🧑💻 안녕하세요. 끈기있고 노력하는 개발자 윤준필 입니다.
학부 4학년 때 Web application을 개발하는 전공강의를 들으며 처음 웹 개발에 흥미를 느끼게 되었고,
졸업 후 지금까지 백엔드 개발 부트캠프, 개인 및 팀 프로젝트 등의 참여를 통해 꾸준히 웹 개발학습을 이어가고 있습니다.
사람들과 협업하여 프로젝트 진행하는 것과 개발 시 발생하는 문제를 해결하는 것에 흥미를 느낍니다.
🏫 학력 및 교육
- 부산동성고등학교 졸업 (~16.02)
- 상명대학교 서울캠퍼스 컴퓨터과학과 중퇴 (~20.02)
- 서울과학기술대학교 산업정보시스템공학과 졸업 (~23.08)
- Techit 멋쟁이사자처럼 백엔드 부트캠프 5기 수료 (~23.09)
🪪 자격증 및 어학
- SQLD 취득 (21.06)
- Toeic Speaking IM3 취득 (23.01)
- 정보처리기사 취득 (24.06)
🛠️ 기술스택
- JAVA
- Springboot
- AWS EC2, AWS RDS
- MySQL
- Github(협업), Github-actions(CI/CD)
📁 프로젝트
1. 코딩퀴즈, 생성형 AI 기반 코딩퀴즈 제공 서비스 [팀 프로젝트]
프로젝트 기간 : 2024.04 – 2024.06 (진행중)
프로젝트 설명
- OPENAI API 를 기반으로 코딩문제를 생성 후 유저에게 퀴즈게임 형식으로 제공하는 서비스입니다.
- 유저 점수에 따라 랭킹정보를 얻을 수 있으며,문제마다 질문, 답변을 할 수있는 게시판이 구현되어 있습니다.
- 날짜, 유형, 틀린문제 별 문제 필터링 기능을 통해 복습할 수 있습니다.
- iOS app과 백엔드 REST API 서버를 연결하여 구현하였습니다.
시스템 버전
- Springboot : 3.2
- JAVA : 17
- MySQL : 8.3
시스템 아키텍처
프로젝트 ERD
내가 프로젝트에 사용한 SKILL
- BACKEND : Spring JPA, QueryDsl, Oauth2.0, Scheduler, Swagger
- DB : Redis, MySQL
- DEPLOY : AWS EC2, AWS RDS, NGINX, Docker
맡은 업무
- 퀴즈게임 메인로직 구현
- 유저가 제출한 정답이 오답일 경우 유저 객체 내 틀린 퀴즈 List에 추가, 정답일 경우 Redis 내에 당일점수가 갱신되도록 구현했습니다.
- 게임시작 요청 시 유저의 당일 참여가능 횟수를 확인하고 차감 및 예외상황 등을 처리하는 기능을 구현했습니다.
- 유저 점수 저장 REDIS 서버 연동
- REDIS 서버 내 데이터를 HASH 자료형을 사용하였으며 Key 값은 유저 인덱스값, HashKey 값은 점수, 참여가능 횟수 그리고 리프레쉬 토큰값을 지정하였습니다.
- 점수 업데이트 Scheduler 구현
- 특정 시간마다 Redis 내에 저장된 당일 점수를 일괄적으로 로컬DB에 업데이트 시키는 Scheduler와, 자정시간에 유저의 참여가능 필드값을 초기화 시키는 Scheduler를 구현했습니다.
- 지난 퀴즈 조건에 따른 검색기능 구현
- 틀린, 유형별, 날짜별 등의 조건과 Cursor값을 Query Parameter값으로 받아와 이에 알맞는 퀴즈 List를 반환시키는 검색 기능을 구현했습니다. QueryDsl을 통해 쿼리 메서드를 작성했습니다.
- 퀴즈에 대한 질문 게시판 및 댓글 관련 CRUD 기능 구현
- 퀴즈마다 질문 게시판을 생성하고, 해당 게시판에서 퀴즈에대한 질의응답을 진행할 수 있도록 개발했습니다.
- 유저 엔티티 Soft Delete 적용
- 유저 정보 삭제 시 DB에 물리적 삭제가 아닌 논리적 삭제로 변경하여 유지보수성을 높였습니다.
- Swagger API 사용한 REST API 문서화
- REST API 백엔드 서버에서 제공하는 각각의 End-Point에 대한 설명을 Swagger API를 통해 작성해 iOS로 프론트개발을 맡은 팀원과의 소통을 원활하게 진행할 수 있었습니다.
- AWS 활용한 서버배포
- NGINX 리버스 프록시를 통해 로드밸런싱 환경을 구축했습니다. Docker 컨테이너 3개에 각각 포트번호를 부여 후 Springboot 어플리케이션을 띄워 NGINX 포트로 요청시 각 포트로 일정하게 트래픽을 분산시켜 서버의 안정성을 높였습니다.
2. 전국 병원 검색 및 평가 서비스 [개인 프로젝트]
프로젝트 기간 : 2024.01 – 2024.02
프로젝트 설명
- 공공데이터포털의 전국 병원 정보 12만 데이터를 기반으로 개발한 검색 & 평가 서비스입니다.
- 검색창에 지역, 병원형태, 이름 등의 조건을 설정해 검색 시 관련 병원 리스트를 페이지 형태로 확인할 수 있습니다.
- 병원을 선택하면 해당 병원 관련 상세정보를 확인할 수 있으며, 텍스트 및 점수 리뷰를 작성할 수 있습니다.
시스템 버전
- Springboot : 2.7
- JAVA : 11
- MySQL : 8.3
프로젝트 ERD
내가 프로젝트에 사용한 SKILL
- BACKEND : Spring JPA, QueryDsl, Spring AOP, Caffeine Cache, Scheduler
- DB : MySQL
- TEST : nGrinder
맡은 업무
- 병원 검색기능 구현
- QueryDsl 적용 : 기존에는 JPQL로 Query 메소드를 작성하였으나, 데이터 호출 테스트 시 런타임 에러의 원인를 잡는데 시간이 오래 걸려 QueryDsl을 적용하였고 컴파일 시점에서 잘못 작성한 코드를 처리할 수 있었습니다.
- Query 실행 결과 Cache 처리 : 병원 데이터 호출 시 latency는 1000ms 으로 길게 나왔고, 검색 결과 List를 Cache 처리하여 이후 요청 시 latency를 15-20ms로 올려 조회성능이 약 200배 개선될 수 있었습니다.
- 병원 엔티티 관련 CRUD 기능 구현
- 조회수 Update Scheduler 도입 : 기존에는 특정 index의 병원 정보 조회 요청 시 DB에서 조회수가 증가되도록 구현하였으나, 매 요청마다 Update Query를 실행하는 것을 줄이기 위해 조회수 증가값을 Cache에 저장 후, Scheduler를 통해 일괄적으로 Update 하도록 구현하였습니다.
- 성능 테스트 도입
- Ngrinder를 통한 성능 테스트 : 서버로 많은 요청이 왔을 때의 상황을 알아보기 위해 Ngrinder를 사용했습니다. 이를 사용하기 위해 Springboot, Java 버전을 2.7 과 11로 다운그레이드 하였고, 테스트 스크립트 작성을 통해 다양한 상황에서의 성능 테스트를 진행할 수 있었습니다.
- 댓글 엔티티 관련 CRUD 기능 구현
- 댓글 생성/조회/수정/삭제 기능을 구현했습니다.
3. 공모자들, 공모주 정보 제공 커뮤니티 서비스 [팀 프로젝트]
프로젝트 기간 : 2023.08 – 2023.09
프로젝트 설명
- 공모주 정보들을 여러 사이트에서 크롤링하여 수집하고, 공모주 청약일과 마감일을 달력 형태로 사용자에게 제공합니다.
- 공모주를 선택하면 해당 공모주 관련 뉴스와 상세정보를 확인할 수 있으며, 공모주 별 채팅방을 이용할 수 있습니다.
- 유저인증 방식으로 JWT 인증방식을 선택하였습니다.
시스템 버전
- Springboot : 3.1
- Java : 17
- MySql : 8.3
시스템 아키텍쳐
프로젝트 ERD
내가 프로젝트에서 사용한 SKILL
- FRONTEND : Thymeleaf
- BACKEND : Spring JPA, Spring Security, Oauth2.0, JWT, JavaMail
- DB : Redis, MySQL
- DEPLOY : AWS EC2, AWS RDS, Docker
맡은 업무
- 유저 엔티티 관련 CRUD 기능 구현 ( 회원가입, 로그인/로그아웃, 소셜 로그인, 비밀번호 찾기, 정보 수정 등 )
- 로그인, 로그아웃 : Spring Security 기반으로 개발. 로그인 성공 시 토큰을 생성하여 쿠키형태로 클라이언트에게 전송, 로그아웃 시 토큰 소멸되도록 구현했습니다.
- 소셜 로그인 : Spring Security, Oauth2.0 기반 개발. 카카오, 네이버 인증서버로 요청을 통해 Oauth2User 객체에 담긴 정보를 유저 엔티티로 변환해 DB 저장하도록 구현했습니다.
- JWT 기반 유저 인증/인가 기능 구현
- Token Filter : 로그인 시 발급된 JWT를 파싱 후, 토큰필터를 통해 유효성을 확인하고 SecurityContextHolder에 인증정보를 담아 필터를 거치도록 구현했습니다. 구현과정에서 예외처리할 상황이 많아 시간이 걸렸지만 여러번의 테스트를 통해 성공적으로 구현했습니다.
- REDIS 캐시서버 도입 : 처음에는 Refresh 토큰을 엔티티로 저장 후 DB로 조회 했으나, 휘발성 데이터인 토큰을 Redis에 저장하여 토큰을 key:value 형태로 보관했고, 유저의 요청시 Redis를 조회 함으로써 DB의 부하를 줄이고자 했습니다.
- CustomException 구현
- 서비스 내에서 발생하는 예외상황을 Enum형태의 ErrorCode를 정의했습니다. HttpStatus 코드와 예외상황을 설명하는 메세지가 포함되어 있으며, CustomException 발생 시 Handler를 통해 ErrorCode를 전송하는 식으로 구현하였습니다.
- AWS 이용한 서비스 배포
- ec2 인스턴스에 Spring boot 서버와 Redis 서버를 docker를 통해 컨테이너로 관리하였고, 데이터베이스를 Amazon RDS 인스턴스에 띄워 관리하였습니다.