미리보기
기본 정보
- iOS, Android 대학교 열람실 알람 서비스를 출시하여 실제 사용자 약 650명에게 서비스를 제공하고 있습니다. - 대학교 강의 리뷰 서비스를 출시하여 실제 사용자 약 40명에게 서비스를 제공하고 있습니다. 개발자이기 전에 서비스를 만드는 사람으로서, 사용자들에게 진정한 가치를 전달하는 서비스를 만드는 사람입니다. 학교 학생들이 강의 선택 시 겪는 고민과 열람실 이용 중 불편함을 해결하기 위해 강의 리뷰 서비스와 열람실 남은 시간 알람 시스템을 직접 설계하고 구현했습니다. 기술의 장단점을 파악하고, 그에 따른 적절한 활용을 중요하게 생각하며, 단순한 기능 구현을 넘어서 원리와 배경을 이해하려고 노력합니다. 또한, 배운 것을 문서화하여 공유하고, 이를 통해 지식을 깊게 이해하고 전달하는 데 큰 보람을 느낍니다. 현재 개인 기술 블로그를 운영하며, 지속적으로 지식을 나누고 있습니다.
기술 스택
Java, JPA, MySQL, Spring Boot, Spring
프로젝트
홍익대학교 열람실 이용 시간 알람 시스템
홍익열공이
2024.09. ~ 진행 중
홍익대학교 학생들이 열람실에서 겪는 페인포인트를 정확히 타겟하여 앱으로 솔루션을 제시하고 이를 통해 학교 시스템에 기여하는 것을 목표로 달려가는 서비스입니다. IOS, AOS, Github
#Java #SpringBoot #Spring Data JPA #MySQL
이벤트 기반 회원가입 알림 시스템 구현 및 트랜잭션 롤백 문제 해결
회원가입이 완료되면 디스코드 웹훅을 통해 알림을 보내는 기능을 구현했습니다.
하지만 회원가입과 웹훅 알림이 하나의 트랜잭션에 묶여 있어 다음과 같은 문제가 발생했습니다.
외부 API 의존성 문제
디스코드 서버의 rate-limit 예외 발생 시 회원가입까지 롤백됨
다수의 사용자가 동시에 가입할 경우 API 응답 지연 및 커넥션 타임아웃 발생
결합도 문제 및 확장성 부족
웹훅 알림과 회원가입 로직이 강하게 결합되어 있어 테스트 코드 작성 어려움
향후 알림 방식 추가시 확장성이 부족
고려한 개발 요소
트랜잭션 분리: 회원가입과 알림 로직을 별도 트랜잭션으로 실행
새로운 커넥션 할당으로 인해 데드락 발생
Async (비동기 처리) 도입
순서 보장이 어려움
트랜잭션 롤백 시 후속 작업이 실행될 위험 존재
해결 과정
TransactionEventListener 활용
트랜잭션이 성공적으로 커밋된 후 이벤트를 발생시켜 웹훅 알림 전송
순서 보장이 가능하며, 추후 확장도 용이
서비스 간 결합도를 낮춰 유지보수성과 테스트 용이성 개선
학과별 랭킹 시스템 구현 및 쿼리 실행 속도 90%이상 단축
사용자의 주별 학습 기록을 조회하는 쿼리를 실행하는 과정에서, 불필요한 조인과 비효율적인 인덱스 사용으로 인해 성능 문제가 발생했습니다.
불필요한 조인으로 인한 성능 저하
유저와 공부시간 기록을 조회하는 과정에서 모든 사용자에 대해 개별적으로 인덱스 조회 수행
함수 호출 (YEARWEEK)로 인한 인덱스 미활용
MySQL YEARWEEK 함수는 인덱스가 적용되지 않음
인덱스를 활용하지 못하고, 매번 모든 row에 해당 조건을 평가해야 하는 비효율적인 방식
쿼리 실행 성능 저하
공부시간 테이블에 대해 유저수 약 20,000번 인덱스 스캔 수행
결과적으로 전체 조회 시간 3.11s 소요
고려한 개발 요소 및 해결 과정
쿼리 구조 변경: YEARWEEK 함수 사용 대신 범위 조건 사용하여 인덱스를 활용할 수 있도록 개선
YEARWEEK = 202503 -> 날짜 범위 조건(BETWEEN)으로 변경
BETWEEN start_time >= '2025-01-13' AND start_time < '2025-01-20'
인덱스 최적화
Index Range Scan을 활용할 수 있게 인덱스 생성
쿼리 실행 성능 개선
기존 실행 시간: 3.11s -> 최적화 후: 343ms
Index Range Scan을 통해 인덱스 기반으로 한 번의 스캔으로 필요한 데이터만 검색
방송통신대학교 강의 리뷰 사이트
Knouk
2024.08. ~ 2024.09.
Knouk(사이트)는 방송통신대학교의 강의평가를 한눈에 쉽게 살펴볼 수 있는 웹사이트입니다. Github
테스트 계정 ID: test, PWD: 123
#Java #SpringBoot #Spring Data JPA #MySQL
사용자 중심 시스템 기획 및 개발
학생들이 수강신청 시 시즌에 카톡방에 올라오는 강의 추천, 강의 후기를 많이 물어보는 일이 잦아 강의를 선택하는 데 도움이 될 수 있는 강의 리뷰 사이트를 기획하여 서비스를 제공하였습니다.
강의 정렬 및 리뷰 개수 표시 기능 구현
유저가 최신 리뷰 순으로 강의를 쉽게 찾을 수 있도록 강의를 최신 리뷰 순으로 정렬하고, 강의에 대한 리뷰 개수를 표시하는 기능을 추가했습니다.
Swagger 커스텀 활용 및 오픈소스 기여 링크
API 문서화를 위해 Swagger를 커스텀하여 사용하며, 관련 오픈소스에 기여했습니다.
실시간 매칭 및 채팅 시스템
Chatty
2023.12. ~ 2024.04.
실시간 매칭 시스템으로 상대방과 매칭하여 채팅할 수 있는 서비스입니다. Github
#Java #SpringBoot #Spring Data JPA #MySQL #Redis #WebSocket
No-Offset 페이징 도입하여 응답 시간 40% 개선 링크
문제 상황
Paging을 사용했을 때, 뒷 페이지로 갈 수록 접근 속도가 늘어나고 불필요한 COUNT 쿼리 발생으로 응답 속도에 지연이 발생했습니다.
해결 과정
불필요한 COUNT 쿼리, 페이지마다 접근 속도에 차이가 생기지 않게 No-Offset 방식을 도입하였고, 응답 시간 40% 개선하였습니다.
N+1 문제 해결로 응답 시간 60% 개선 링크
문제 상황
게시글 목록을 조회할 때, 해당 객체가 가지고 있는 연관관계 댓글, 좋아요, 유저 등을 조회하게 되면서 N번의 추가적인 쿼리가 발생했습니다.
해결 과정
ManyToOne에 대해서는 Fetch Join을 OneToMany에 대해서는 전역적인 batch size를 설정함으로써 N + 1 문제를 해결하였습니다.
대규모 데이터 조회 성능 개선
문제 상황
게시글을 조회하였을 때, 연관관계인 좋아요의 개수를 테이블 풀스캔으로 수십만 개의 데이터를 메모리에 로드하는 비효율로 성능 저하가 발생하였습니다.
해결 과정
테이블 풀스캔 문제를 해결하기 위해 좋아요 개수를 따로 조회할 수 있게 COUNT 쿼리를 추가하였고 응답 시간 96% 개선하였습니다. 링크
문제 상황
좋아요 순으로 게시글 목록을 조회할 때 Join, Group by, COUNT(), 대용량 데이터 정렬로 인하여 게시글 목록 조회 시, 2초가 넘는 응답 시간이 발생하였습니다.
해결 과정
쿼리 플랜을 분석하여 Join, Group By, COUNT 연산을 최적화할 수 있는 반정규화를 적용하였고, Sort 연산을 생략하기 위해 인덱스를 활용하여 조회 성능 97% 향상하였습니다. 링크
댓글 작성과 알람 발송 트랜잭션 분리 링크
문제 상황
댓글을 작성했을 때 알림이 발송되는 상황에서 댓글과 알림 로직이 하나의 트랜잭션 안에서 처리되어 알림에 문제가 발생하였을 때, 댓글 저장도 롤백되어버리는 문제가 발생하였습니다.
해결 과정
트랜잭션 전파 옵션 REQUIRES_NEW 설정으로 도메인 로직과 서비스 로직을 분리하여 해결하였습니다.
실시간 매칭 시스템 동시성 문제 해결 링크
문제 상황
1:1 실시간 매칭 시스템에 한 유저가 다른 사용자와 매칭을 기다리는 중, 여러 사용자가 동시에 접근하였을 때, 한 명이 여러명과 동시에 매칭이 되는 문제가 발생하였습니다.
해결 과정
단일 인스턴스인 상황이기 때문에 synchronized를 활용하여 동시성 문제를 해결하였습니다.
방송통신대학교 커뮤니티 사이트
WiseSea
2023.07. ~ 2023.08.
방송통신대학교 학생들을 위한 커뮤니티 사이트 Github
#Java #SpringBoot #Spring Data JPA #MySQL #Qureydsl
게시글 좋아요 동시성 이슈 해결 링크
문제 상황
좋아요를 동시에 여러 번 요청하면 DB에 중복 저장, 좋아요 개수가 음수로 넘어가는 문제가 발생하였습니다.
해결 과정
비관적 락은 성능에 큰 문제가 발생하기 때문에 낙관적 락을 사용하여 동시성 문제 해결하였습니다.
데드락 방지 및 성능 최적화 링크
문제 상황
락을 사용해도 외래키 잠금 전파로 인하여 동시에 요청이 올 때 데드락이 발생하였습니다.
해결 과정
락을 사용하지 않고 유니크 제약 조건을 추가하여 중복 저장 방지 및 데드락 문제 해결하였습니다.
중고 거래 사이트
Market
2023.07. ~ 2023.08.
당근마켓 기능을 클론코딩한 마켓 API 서버 Github
#Java #SpringBoot #Spring Data JPA #MySQL #WebSocket
사용자 중심 서비스 개선
당근마켓 웹 버전의 사용자 경험을 분석하고, 사용자에게 필요한 기능을 고민하며 웹 애플리케이션의 편의성을 개선.
STOMP 기반 WebSocket 통신 구현
Spring WebSocket을 이용해 실시간 채팅 기능을 구현하여 사용자 간 실시간 상호작용을 제공.
위치 기반 검색 기능 구현
MySQL의 ST_Distance_Sphere 함수를 활용하여 사용자의 위치를 기준으로 근처의 중고 거래 글을 검색할 수 있는 기능을 구현.
커뮤니티 사이트
마쉴랭
2023.01. ~ 2023.04.
술, 안주, 사는 애기를 자유롭게 할 수 있는 커뮤니티 사이트 Github
#Java #SpringBoot #Spring Data JPA #MySQL
JWT 토큰 저장 방식 고민 및 구현 링크
JWT 토큰의 저장소 방식에 대해 고민하고, 보안 이슈를 고려하여 최종적으로 쿠키 저장 방식을 선택하였습니다.
XSS 공격 시나리오 구현 및 분석 링크
XSS 공격을 직접 구현하여 JWT 토큰을 로컬 스토리지에 저장할 때 발생할 수 있는 보안 문제를 분석하였습니다.
CSRF 공격 시나리오 구현 및 분석 링크
CSRF 공격을 직접 구현하여 JWT 토큰을 쿠키에 저장할 때 발생할 수 있는 보안 문제를 분석하였습니다.
포트폴리오
URL
교육
방송통신대학교
대학교(학사) | 컴퓨터과학과
2023.03. ~ 현재 | 재학 중
대외활동
2023년 총장배 소프트웨어경진대회 동상 수상
소프트웨어경진대회
방송통신대학교 학생들을 위한 커뮤니티 사이트를 제작하였습니다.
자격증
SQLD
SQL개발자 | 한국데이터산업진흥원
2024.09.