신입 백엔드 개발자 · Java · Spring
성진혁
"잘 돌아간다"를 수치와 테스트로 증명합니다
동시성 제어, 데이터 정합성, 실시간 전달 — 백엔드가 조용히 깨지는 지점을 직접 재현하고, 막고, 측정해 왔습니다. 모든 주장에는 실측 수치 또는 테스트 근거가 붙어 있습니다.
프로젝트 — 요청의 여정
- GATEWAY1 / 4
요청이 인증되고, 계량되고, 같은 요청은 두 번 과금되지 않습니다
AI Usage Billing Gateway
2026.05 · 개인재시도가 중복 과금이 되지 않도록 — API Key 발급부터 사용량 계량, 정산 원장까지 돈이 걸린 경계를 검증하는 멀티테넌트 게이트웨이
클라이언트 재시도·네트워크 중복 전송이 그대로 중복 과금으로 이어질 수 있다
→ 체크 150/150 통과 · HTTP 실패 0건 · 중복 계량 0건 (3회 모두)
PG webhook은 재전달·순서 뒤바뀜·위조가 전제 조건이다
→ duplicate delivery가 결제 상태를 두 번 바꾸지 않음을 통합 테스트·k6 branch로 검증
환불·조정이 섞이면 "지금 잔액이 왜 이 값인지"를 추적할 수 없게 된다
→ 환불 흐름 포함 원장 정합성을 Testcontainers 통합 테스트로 검증
- QUEUE → LOCK·TX2 / 4
요청이 대기열을 통과해 좌석 락을 두고 경합합니다
Concert Booking
2026.02 – 2026.05 · 개인100명이 같은 좌석에 몰려도 중복 판매 0건 — 락 전략 3종을 같은 조건에서 실측 비교한 좌석 예약 시스템
동일 좌석에 동시 예매가 몰리면 중복 판매(oversell)가 발생할 수 있다
→ 100 VU 동일 좌석 경합에서 3전략 모두 성공 1건·oversell 0건, p95는 낙관 106ms / Redis 145ms / 비관 215ms
서로 다른 좌석을 예매해도 낙관적 락 성공률이 40%로 무너졌다
→ 분산 예약 성공률 비관 100% vs 낙관 40%를 근거로, 공유 카운터가 있는 모델에서의 전략별 트레이드오프를 문서화
예약 확정 이벤트가 브로커 장애 시 유실될 수 있다
→ Outbox 실패/재시도와 DLT replay를 Testcontainers 통합 테스트로 검증 (OutboxIntegrationTest, KafkaDltReplayIntegrationTest)
측정동일 좌석 100명 경합 oversell0건측정분산 예약 성공률 (비관 vs 낙관)100% vs 40%측정혼합 부하 총 RPS (Redis 락)1,005검증race·멱등·토큰 남용 검증 체크594/594 - STREAM3 / 4
응답이 커밋된 뒤에야 구독자 전원에게 fan-out됩니다
Realtime Chat
2026.02 – 2026.05 · 개인"화면에 보였다"와 "실제 저장됐다"를 구분하는 채팅 — DB 커밋 후에만 브로드캐스트하고, 1,000명 수신 검증에서 유실 0건
채팅방 목록 API가 방 N개당 2N+1회 쿼리를 실행 (방 50개면 101회)
→ k6 200 VU에서 RPS 937 → 1,598 (+70.5%), p95 212.85ms → 149.22ms (−29.9%)
브로드캐스트 후 DB 저장이 실패하면, 화면에는 보였지만 사라지는 메시지가 생긴다
→ 2대 인스턴스 · 1,000명 receiver matrix 3회 반복에서 expected 99,900건 전량 수신 — 유실 0 · 중복 0 · 순서 역전 0
데이터가 쌓이면 조회 경로가 느려질 수 있는데, 어떤 인덱스가 실제로 쓰이는지 모른다
→ 멱등성·멤버 확인은 Index Only Scan, 핵심 쿼리 실행 시간 0.08 – 1.3ms 확인
측정채팅방 목록 RPS937→1,598+70.5%측정p95 응답시간212.85ms→149.22ms−29.9%측정목록 조회 쿼리 수 (방 N개)2N+1회→1회검증1,000명 수신 완전성 (3회 반복)99,900 / 99,900 - DELIVERY4 / 4
응답이 실제 사용자 — 계단 앞에 선 사람 — 에게 도달합니다
My ETA
2026 · 해커톤7인 팀 (기획·리서치 3 · 프로덕트 개발 4) · 15조 피프틴피프틴 · 백엔드 전담 (FastAPI)
교통약자의 실제 보행속도로 도착시간을 다시 계산하는 배리어프리 내비게이션 — 하나금융×SKT Tech4Good 2026 해커톤
지도 앱의 ETA는 표준 보행속도 기준이라 휠체어·노약자에게는 항상 틀린 값이 된다
→ 일반 ETA와 개인화 ETA를 함께 반환하는 경로 API 제공, 경사·보행환경 페널티 반영
엘리베이터·저상버스 정보가 없을 때 "이용 가능"으로 단정하면 사용자를 계단 앞에 데려다 놓는다
→ 실측·시간표·추정·미확인 데이터를 구분해 응답 — 없는 데이터를 지어내지 않는 설계
대중교통을 놓치거나 경로를 이탈하면 기존 안내는 무용지물이 된다
→ 이탈·놓침 감지 시 현재 위치를 새 출발점으로 경로와 ETA 갱신, 위치 요청 지연 복구 처리
200 OK
응답 본문 — 무엇으로 무엇을 했는가
기본기
- 트랜잭션 · 락 — 비관·낙관·Redis 분산 락 3전략을 같은 조건에서 실측 비교하고, 공유 카운터 row의 @Version 충돌로 낙관 성공률이 40%까지 떨어지는 지점을 규명
- DB 인덱스 — 핵심 쿼리를 EXPLAIN ANALYZE로 분석해 인덱스 5개를 설계 — Index Only Scan 확인, 이미 커버되는 인덱스는 추가하지 않음
- JPA · 쿼리 — 채팅방 목록의 2N+1 쿼리를 JPQL 프로젝션 단일 쿼리로 — RPS +70.5%의 주 기여 요인
- 캐시 — Redis Cache Aside에 이벤트별 선택 무효화(방 멤버만·해당 유저만)를 결합해 전체 무효화를 제거
- 멱등성 — 예매·결제·사용량 계량에 Idempotency-Key를 강제 — replay는 같은 결과, 같은 키 다른 본문은 conflict
강점
- Kafka · 이벤트 — Transactional Outbox로 커밋과 발행을 분리하고, DLT 격리 + 수동 replay 복구 경로까지 통합 테스트로 고정
- 실시간 · WebSocket — persist-before-broadcast 파이프라인으로 2대 인스턴스 · 1,000명 수신 검증에서 유실 0건
- 검증 문화 — Testcontainers 실컨테이너 통합 테스트 + k6 시나리오 반복 실행 — 수치 없는 주장은 하지 않음
- Python · FastAPI — 외부 API 5종 어댑터 계층과 개인화 ETA 엔진 — 해커톤 팀 프로젝트 백엔드 전담