백엔드 면접 학습 노트 목차

면접 시나리오·트러블슈팅 — 백엔드 면접 (실제 기출 기반·심화)

지식 질문을 넘어 "이 장애를 어떻게 진단했나요", "이 선택의 트레이드오프는", "경험을 말해 보세요" 로 가는 단골. 정답 암기가 아니라 생각하는 과정·트레이드오프·실무 감각을 본다. 앞의 01~11편을 실전으로 엮는 캡스톤 — 여기서는 단순 정의 대신 실제로 어떤 명령·설정으로 좁혀 가는지를 다룬다.

함정형 단골: ① "느려요"에 추측으로 코드부터 고침 → 측정 없이 가설 검증 X(★) ② OOM = 메모리 부족? → 누수·대량 적재·메타스페이스가 더 흔함 ③ 커넥션 풀 키우면 해결? → DB가 못 받으면 오히려 악화, 점유 시간이 진짜 원인 ④ 데드락은 앱이 멈춤? → InnoDB가 자동 감지·한쪽 롤백(에러 1213)·앱은 재시도하면 됨.


1. 면접 진행 방식·태도 (지식만큼 평가된다)

실제 질문: "모르는 질문이 나오면 어떻게 대처하세요?" · "이 기술을 선택했나요?" (거의 모든 회사 공통)

  • 모르면: "정확히는 모르지만 이렇게 접근하겠습니다"로 사고 과정을 보여라. 아는 척하면 꼬리질문에서 무너진다 — 면접관은 모르는 영역을 다루는 방식을 본다.
  • 항상 트레이드오프로 마무리: "A가 빠르지만 B는 일관성이 좋습니다. 이 상황(읽기 多·약한 일관성 허용)이면 A를 택하겠습니다" — 단정보다 상황별 판단.
  • 되물어라: 설계·장애 질문은 요구사항·규모·제약을 먼저 명확화. "읽기:쓰기 비율? QPS? 일관성 요구? 데이터 규모?"를 묻는 것 자체가 점수다.
  • 수치로 말하라: "빨라졌다"❌ → "p99를 800ms→120ms로"⭕. 측정값이 신뢰를 만든다.

함정: ❌ 자신 없는 주제를 단정적으로 → 꼬리질문 3번이면 들통. 모르는 경계를 솔직히 + 접근법.


2. 트러블슈팅 만능 틀 (★ 모든 장애 질문의 뼈대)

증상 → 가설 → 측정 → 격리 → 수정 → 검증

추측으로 고치지 말고 측정으로 좁힌다. 업계 표준 관찰 방법론과 같은 사고다 — USE(자원별 Utilization·Saturation·Errors, Brendan Gregg)·RED(요청별 Rate·Errors·Duration, Tom Wilkie).

다이어그램 로딩 중…

측정 도구 4종: ① APM·분산 트레이싱(요청이 어느 서비스·어느 스팬에서 시간 소비?) ② 메트릭(Micrometer→Prometheus·Grafana: CPU·힙·풀·QPS·p99) ③ 로그(에러·슬로우쿼리) ④ 덤프(스레드 덤프=어디서 블로킹·힙 덤프=무엇이 메모리 점유).


3. 시나리오 A — "API가 갑자기 느려졌어요" (실전 워크스루)

실제 질문: "특정 API의 응답이 느려졌다는 제보가 왔습니다. 어떻게 원인을 찾나요?" (VSFe·우아한형제들·올리브영 단골)

격리부터: APM 트레이스로 시간이 어디서 소모되는지 본다 — 앱 로직? DB? 외부 API? 큐 대기?

① DB가 범인일 때 — 슬로우 쿼리 로그를 켜고(long_query_time) 느린 쿼리를 잡는다.

EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'PAID';
-- type=ALL(풀스캔)·rows 큼 → 인덱스 누락. (user_id, status) 복합 인덱스 추가

→ 인덱스 추가·커버링 인덱스·쿼리 재작성. (DB 편)

② N+1이 범인일 때 — 한 요청에 쿼리가 수백 개. show_sql이나 p6spy로 쿼리 개수를 본다.

// ❌ 주문 1 + 주문마다 회원 N번 = 1+N
List<Order> orders = orderRepo.findAll();
orders.forEach(o -> o.getMember().getName()); // lazy → 매번 SELECT

// ⭕ fetch join / @EntityGraph / default_batch_fetch_size(IN 절로 묶음)
@Query("select o from Order o join fetch o.member")

→ fetch join·@EntityGraph·spring.jpa.properties.hibernate.default_batch_fetch_size=100. (Spring·JPA 편)

③ GC(STW)가 범인일 때 — 주기적 지연·p99만 튐. jstat -gcutil <pid> 1000로 GC 빈도·STW 시간, -Xlog:gc*로 로그 확인.

# Full GC가 잦고 STW가 길다 → 힙 부족/누수·잘못된 객체 수명
jstat -gcutil 12345 1000   # FGC(횟수)·FGCT(누적시간) 급증 확인

→ 힙 크기·G1 튜닝·누수 제거. (Java 편)

④ 외부 API가 범인일 때 — 동기 호출이 느려지며 연쇄 지연. → 타임아웃·서킷브레이커·비동기화. (시스템설계 편)

꼬리질문: "측정 도구가 없으면?" → 임시로 구간별 로그(시작/종료 타임스탬프)·스레드 덤프 여러 장으로 어디서 멈춰 있는지. / "느린 쿼리는 빠른데 API가 느리면?" → 커넥션 풀 대기·직렬화·로깅 I/O·GC. / "재현이 안 되면?" → 부하·데이터량·동시성 조건 차이(운영 데이터 규모로 재현).

함정: ❌ 트레이스 없이 "아마 쿼리겠지" 하고 인덱스부터 → 측정이 먼저. 병목이 GC였다면 헛수고.


4. 시나리오 B — "커넥션 풀이 고갈됐어요" (HikariCP)

실제 질문: "갑자기 Connection is not available 에러가 쏟아집니다. 원인과 해결은?" (실무 단골)

증상: HikariPool-1 - Connection is not available, request timed out after 30000ms. HikariCP 기본 풀 크기 10·connectionTimeout 30s — 모든 커넥션이 점유된 채 반납이 안 돼 대기가 타임아웃.

원인은 거의 "점유 시간" — 풀이 작은 게 아니라 오래 쥐고 있는 것:

  • 트랜잭션 안에서 외부 API 호출: 네트워크 대기 동안 DB 커넥션을 쥠 → 동시 요청 몇 개면 고갈.
  • OSIV(Open Session In View, spring.jpa.open-in-view=true 기본값): 영속성 컨텍스트를 뷰 렌더링·응답 직렬화까지 열어둠 → 커넥션을 요청 끝까지 점유.
  • 누수: 커넥션을 명시적으로 닫는 코드에서 예외로 반납 누락. leakDetectionThreshold로 탐지.

해결: ① 트랜잭션 짧게·외부 호출은 트랜잭션 밖으로 ② OSIV off(spring.jpa.open-in-view=false)로 커넥션을 트랜잭션 범위로만 ③ 누수 탐지(spring.datasource.hikari.leak-detection-threshold=5000) ④ 풀 크기는 근거 있게 — HikariCP 권장 pool size = (코어 수 × 2) + 디스크 수 수준에서 측정으로 조정(무작정 키우면 DB 컨텍스트 스위칭·락 경합으로 악화).

꼬리질문: "풀을 100으로 키우면?" → DB가 동시 100을 못 버티면 DB가 병목으로 이동·오히려 악화. / "OSIV를 끄면 부작용은?" → 컨트롤러·뷰에서 lazy 접근 시 LazyInitializationException → 서비스 계층에서 fetch join·DTO로 미리 로딩. / "누수인지 점유인지 구분?" → 점유는 부하 시 고갈·평시 회복, 누수는 시간이 지날수록 가용 커넥션이 단조 감소.

함정: ❌ "풀 크기만 키우면 해결" → 진짜 원인은 점유 시간. 외부 호출·OSIV부터.


5. 시나리오 C — "메모리가 계속 차서 OOM이 납니다"

실제 질문: "OutOfMemoryError가 간헐적으로 발생합니다. 어떻게 분석하나요?" (VSFe·기업 블로그)

증거 확보: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dump터지는 순간의 힙을 떠서, Eclipse MATDominator Tree·Leak Suspects무엇이 힙을 지배하는지 본다.

흔한 누수 패턴:

  • ThreadLocal 미해제: 스레드풀에서 스레드가 재사용되는데 remove()를 안 하면 객체가 계속 매달림(웹 컨테이너 단골).
  • static 컬렉션·무한 캐시: 끝없이 put만 → 크기 제한 캐시(Caffeine maximumSize)·약한 참조.
  • 미해제 자원: 스트림·커넥션·리스너 등록 후 해제 누락.

OOM ≠ 항상 누수: 정상인데 양이 큼(대량 조회를 메모리에 다 적재 → 페이징·스트리밍)·Metaspace OOM(클래스 무한 로딩·동적 프록시)·스레드 과다. 메시지부터 구분: Java heap space vs Metaspace vs unable to create new native thread.

꼬리질문: "힙 덤프 없이 운영 중 분석?" → jmap -histo:live <pid>로 인스턴스 수 상위 클래스·jcmd GC.class_histogram. / "GC가 도는데 왜 OOM?" → 회수 가능한 게 없음(전부 도달 가능 = 누수) 또는 회수보다 적재가 빠름. / "재현이 안 됨?" → 운영 트래픽·데이터량·장시간 가동(누수는 시간 누적).

함정: ❌ "힙만 늘리면 됨" → 누수면 터지는 시점만 미룸. 근본 원인(도달 가능한 쓰레기)을 끊어야.


6. 시나리오 D — "DB 데드락 / 간헐적 데이터 꼬임"

실제 질문: "데드락이 가끔 발생합니다. 원인과 대응은?" · "동시에 같은 행을 갱신할 때 값이 꼬입니다." (DB·동시성 단골)

데드락: 두 트랜잭션이 락을 엇갈린 순서로 잡아 서로 대기. InnoDB는 자동 감지해서 비용이 적은 쪽을 롤백(에러 1213 Deadlock found) — 앱이 멈추지 않는다. 원인은 SHOW ENGINE INNODB STATUSLATEST DETECTED DEADLOCK로 확인.

  • 해결: ① 여러 자원을 항상 같은 순서로 락 ② 트랜잭션을 짧게(락 보유 시간↓) ③ 데드락은 정상 발생할 수 있으니 재시도 로직(1213 → 지수 백오프 재시도) ④ 격리수준·인덱스 정비(범위 락 줄이기).

간헐적 데이터 꼬임 = 경쟁 조건: 읽고-수정-쓰기(check-then-act)가 원자적이지 않음. → 비관락(SELECT … FOR UPDATE낙관락(@Version·충돌 시 재시도)·원자 연산(UPDATE … SET stock=stock-1 WHERE stock>0)·격리수준 상향. (DB·시스템설계 편)

앱(JVM) 데드락도 같은 틀: jstack <pid>(또는 kill -3)로 "Found one Java-level deadlock" 블록 — 어느 스레드가 어느 모니터를 잡고 무엇을 기다리는지.

꼬리질문: "데드락을 0으로?" → 완전 제거보다 확률↓ + 재시도가 현실적. / "낙관 vs 비관 선택?" → 충돌 드물면 낙관(락 비용↓)·잦으면 비관/원자 연산. / "재시도가 위험한 연산은?" → 비멱등(중복 결제) → 멱등키 먼저.

함정: ❌ "데드락 = 서버 멈춤" → InnoDB가 한쪽 롤백·앱은 재시도면 됨. 진짜 문제는 락 순서·긴 트랜잭션.


7. 시스템 설계 인터뷰 — 접근 틀 (작은 예라도 을 보여라)

실제 질문: "URL 단축기를 설계해 보세요." · "선착순 쿠폰을 설계한다면?" (분산 심화는 11편, 여기선 접근 순서)

: 요구사항 명확화 → 용량 산정 → API·데이터 모델 → 고수준 구성 → 병목·확장 → 트레이드오프. 바로 그리지 말고 되묻기부터.

미니 워크스루 — URL 단축기 용량 산정 (숫자로 규모 감각을 보여주는 게 핵심):

  • 가정: 쓰기 1억 URL/월 ≈ 40 writes/s, 읽기:쓰기 = 100:1 → 4,000 reads/s.
  • 키 길이: Base62 7자리 = 62⁷ ≈ 3.5조 → 수년 충분. 저장 5년 ≈ 60억 row.
  • 설계: 읽기가 압도적 → 캐시(핫 URL)+읽기 복제·리다이렉트는 영구면 301(브라우저 캐시·집계 손실) vs 추적 필요면 302.
  • 병목: 키 생성 충돌(카운터/Snowflake)·핫키(캐시)·읽기 폭주(CDN·복제).

되묻기 체크리스트: 규모(QPS·저장량)·읽기:쓰기 비율·일관성 요구·지연 허용·가용성 목표·트래픽 패턴(피크/핫키). (구체 분산 기법 = 11편: 복제·샤딩·CAP·Saga·서킷브레이커.)

함정: ❌ 요구사항 안 묻고 바로 박스 그리기 → 과·과소 설계. 먼저 규모를 정의.


8. 경험·인성(behavioral) — STAR로 구조화

실제 질문: "가장 어려웠던 기술 문제는?" · "성능을 개선한 경험은?" · "협업 중 갈등 경험은?"

STAR: Situation(상황·맥락) → Task(내 과제) → Action(내가 한 구체 행동) → Result(수치 결과).

  • 예: "결제 API p99가 800ms로 SLA를 못 맞춤(S) → 원인 규명·개선 담당(T) → APM으로 N+1 발견, fetch join + Redis 캐시 + 커넥션 풀 점유 분리(A) → p99 800ms→120ms·DB CPU 70%→35%(R)."
  • 기술 선택은 왜 그것을·대안은·트레이드오프는까지. 실패·배움도 성장 관점으로 솔직히("재시도를 멱등 없이 넣어 중복 결제 → 멱등키로 수정, 이후 비멱등 연산을 먼저 점검하는 습관").

함정: ❌ "우리 팀이/우리가" 일색 → 면접관은 당신의 Action을 본다. 내가 한 것을 명확히.


흔한 오답·함정 정리

  • 측정 없이 코드부터 고침 → 증상→가설→측정→격리가 먼저(병목을 틀리면 헛수고).
  • 커넥션 풀만 키우면 해결 → 진짜 원인은 점유 시간(외부 호출·OSIV). DB가 못 받으면 악화.
  • OOM = 메모리 부족 → 누수(도달 가능한 쓰레기)·대량 적재·Metaspace가 더 흔함.
  • 데드락 = 서버 멈춤 → InnoDB 자동 감지·한쪽 롤백(1213)·재시도로 처리.
  • 시스템 설계는 바로 그린다 → 요구사항·규모 되묻기가 먼저.
  • 모르는 걸 아는 척 → 꼬리질문에 붕괴. 접근법·솔직함이 점수.

한국 면접 단골 종합 Q&A (답변 골격)

질문핵심 접근
API 느림 진단?APM 구간 격리 → 슬로우쿼리/N+1/GC/외부지연 → 가설 검증
커넥션 풀 고갈?점유 시간(외부호출·OSIV)·누수 → 짧게·분리·OSIV off
OOM 분석?힙 덤프 + MAT dominator → ThreadLocal·무한캐시·대량적재 구분
데드락?INNODB STATUS·락 순서 통일·짧게·재시도(1213)
동시성 꼬임?경쟁 조건 → 비관/낙관락·원자 연산·격리수준
트래픽 10배?캐시·복제·비동기·샤딩·CDN — 병목부터(11편)
시스템 설계?요구사항→용량→API/모델→병목→트레이드오프
어려웠던 경험?STAR + 수치 + 트레이드오프
모르는 질문?접근 과정 제시·솔직·되묻기

꼬리질문 대비 (상 난이도)

  • "측정 도구가 없는 환경이면?" → 구간 로그·스레드 덤프 다중 샷·jstat/jmap/jstack 같은 JDK 내장으로.
  • "그 캐시·DB·큐가 죽으면?" → 폴백(DB 직접)·스탬피드 대비·소비자 멱등·서킷브레이커(8·9·10·11편).
  • "그 선택의 단점은?" → 모든 선택엔 비용이 있다 — 단점을 먼저 인지하고 왜 감수하는지.
  • "더 큰 규모면 뭐가 먼저 깨지나?" → 단일 DB 쓰기·동기 호출 연쇄·캐시 미스·핫 파티션.
  • "장애를 어떻게 예방?" → 부하 테스트·SLO/알람·서킷브레이커·점진 배포·관찰성(메트릭·트레이싱).

한 줄 요약 — 면접은 지식 + 생각 과정·트레이드오프·실무 감각. 트러블슈팅은 증상→가설→측정→격리→수정→검증(추측 말고 측정: APM·메트릭·로그·덤프). 단골 장애 — 느림(구간 격리→슬로우쿼리/N+1/GC)·커넥션 고갈(점유 시간·OSIV)·OOM(힙 덤프→누수/적재)·데드락(INNODB STATUS·재시도)·동시성(락·원자 연산) — 은 앞 편의 원인·해결로 푼다. 시스템 설계는 요구사항→용량→설계→병목→트레이드오프 틀로 되묻기 먼저. 경험은 STAR + 수치. 모르면 접근법을 보여라.

(출처 — 한국 면접 기출·교차검증 2026-06: VSFe/Tech-Interview·gyoogle — tech-interview-for-developer·WeareSoft/tech-interview · 기업 기술블로그(우아한형제들·올리브영 트러블슈팅 사례) · 도구·동작 1차자료: HikariCP About Pool Sizing·[Spring Boot OSIV 문서]·MySQL InnoDB Deadlock Detection·USE Method(Brendan Gregg)·System Design Interview(Alex Xu)·Release It!(Nygard) — 앞 01~11편(각 1차자료 검증) 종합·교차검증.)

시스템 설계·분산 — CAP·복제·샤딩·Saga·서킷브레이커채용공고 실전 면접 질문 — 90문항·모범답안(기출·1차검증)