Java/Spring 백엔드에서 발생할 수 있는 문제를 직접 재현하고, SQL·실행 계획·로그·테스트 결과를 바탕으로 원인과 해결 과정을 학습하는 프로젝트입니다. 기능 구현 자체보다 문제를 예상하고 관찰한 뒤, 해결 방법을 적용하고 같은 조건에서 다시 확인하는 과정에 집중합니다.
문제 상황
→ 예상
→ 재현
→ 로그 / SQL / 실행 계획 / 서버 상태 관찰
→ 원인 분석
→ 관련 CS 학습
→ 해결 후보 비교
→ 적용
→ 동일 조건 재검증
→ 선택 기준 정리
Problem
→ Prediction
→ Reproduction
→ Observation
→ Analysis
→ CS
→ Solution
→ Verification
→ Selection Criteria
문제를 예상하고 재현한 뒤 실제 증거를 바탕으로 분석하고, 해결 방법을 적용해 같은 조건에서 다시 확인합니다.
| Day | 실험 | 핵심 개념 | 상태 |
|---|---|---|---|
| 01 | JPA N+1 재현과 조회 방식별 SQL 비교 | LAZY, Fetch Join, EntityGraph | ✅ 완료 |
| 02 | 복합 인덱스 컬럼 순서와 실행계획 비교 | B+Tree, Cardinality, Selectivity, Query Planner | ✅ 완료 |
| 03 | 100만 건 Offset vs Cursor Pagination | Index, B+Tree, Query Plan | 예정 |
| 04 | JPA 쿼리 수와 실제 조회 비용 비교 | Batch Fetch, Projection, Heap | 예정 |
| 05 | 애플리케이션 검증과 DB Constraint | UNIQUE, MVCC, Transaction | 예정 |
| 06 | Lost Update 동시성 문제 재현 | Race Condition, Critical Section, Isolation Level | 예정 |
| 07 | 낙관적 락·비관적 락·Atomic UPDATE 비교 | Lock, Version, CAS, Retry | 예정 |
| 08 | Deadlock 재현과 Lock Ordering | Deadlock, DB Lock, Lock Ordering | 예정 |
| 09 | 외부 API 지연과 서버 자원 추적 | Thread, Blocking I/O, Timeout | 예정 |
| 10 | Retry Storm과 Backoff·Jitter | Retry, Backoff, Jitter | 예정 |
| 11 | HTTP 재시도와 Idempotency Key | HTTP, UNIQUE, Idempotency | 예정 |
| 12 | DB·Local Cache·Redis 비교 | Cache Aside, Locality, Consistency | 예정 |
| 13 | Testcontainers·GitHub Actions·n8n 기반 회귀 검증 자동화 | Test Isolation, CI, Automation | 예정 |
| 14 | k6 기반 부하 테스트와 성능 임계값 검증 | Load Test, Throughput, p95/p99 | 예정 |
| 15 | OpenAPI·Swagger·GitHub 기반 협업 개발 흐름 | API Contract, Pull Request, CI Check | 예정 |
완료된 Day만 상세 문서에 연결합니다. 재현 조건, 코드, SQL, 실행 계획, 로그, 측정 결과와 재현 방법은 각 Day README에서 관리합니다.
| Day | 블로그 |
|---|---|
| 01 | JPA 연관관계 조회에서 발생한 N+1 문제 재현과 해결 과정 |
| 02 | 복합 인덱스는 왜 컬럼 순서에 따라 달라질까? PostgreSQL 실행계획으로 확인하기 |
| 03 | 예정 |
| 04 | 예정 |
| 05 | 예정 |
| 06 | 예정 |
| 07 | 예정 |
| 08 | 예정 |
| 09 | 예정 |
| 10 | 예정 |
| 11 | 예정 |
| 12 | 예정 |
| 13 | 예정 |
| 14 | 예정 |
| 15 | 예정 |
GitHub에는 재현 조건, Fixture, 실제 코드, SQL·실행 계획, 서버·DB 로그, 테스트, 측정값과 재현 명령을 남깁니다. 블로그에는 문제 상황, 예상과 실제 결과의 차이, 원인, 관련 CS, 해결 후보와 선택 과정, 제약과 배운 점을 기록합니다.
실제로 도입한 기술만 기록하며, 계획 단계의 기술은 미리 추가하지 않습니다.
비밀번호는 저장소에 기록하지 않고 환경 변수로 전달합니다.
export DB_USERNAME=backend_lab
export DB_PASSWORD='choose-a-local-password'
export MYSQL_ROOT_PASSWORD='choose-a-different-root-password'
export MYSQL_PORT=3307
export DB_URL='jdbc:mysql://localhost:3307/backend_lab'
docker compose up -d
./gradlew clean build
./gradlew bootRunDay별 API와 실험 실행 명령은 각 Day README에서 관리합니다.
spring-backend-lab/
├── src/
├── docs/
│ └── experiments/
│ ├── day01-jpa-n-plus-one/
│ └── day02-composite-index/
├── build.gradle
├── compose.day02.yaml
├── compose.yaml
└── README.md
아직 시작하지 않은 Day의 폴더는 만들지 않으며, 실제 실험을 시작할 때 docs/experiments/dayXX-topic/ 아래에 추가합니다.
GitHub에 포함하는 자료:
- 실제 구현 코드와 테스트 코드
- Fixture, SQL, 실행 계획과 Hibernate·DB warning
- 실험 검증 로그, 실제 측정 결과와 Day별 README
GitHub에서 제외하는 자료:
.env, 실제 비밀번호, Secret·Token과 사용자 개인 경로- 전체 서버 로그와 테스트용 민감 정보
- 블로그 원고, 개인 메모와 캡처 이미지
블로그 자료는 로컬 blog/에 보관하며 Git에서 제외합니다.