지원자 입장으로 면접을 본 경험은 많지만, 면접관 자리에 앉는 건 다른 일이다. 최근 2~3년차 백엔드 개발자 채용에 면접관으로 참여하면서, 지원자의 이력서에 적힌 기술 스택을 기준으로 질문 세트를 미리 준비했다. 이 글은 그 세트를 특정 지원자를 식별할 수 없게 일반화해서 정리한 것이다.
같은 연차 백엔드 채용을 준비하는 면접관에게도, 반대로 면접을 앞둔 개발자에게도 쓸모가 있을 것이다.
준비하면서 잡은 원칙
- “무엇을 썼는가”가 아니라 “왜 그걸 골랐는가”를 묻는다. 기술 이름은 이력서에 있다. 면접에서 확인할 건 선택의 근거다.
- 각 질문에 꼬리 질문을 하나 이상 붙인다. 첫 답은 외운 것일 수 있다. 두 번째 답에서 깊이가 드러난다.
- 실제 장애 하나를 끝까지 파고든다. 여러 주제를 얕게 훑는 것보다, 한 사건을 원인·대응·재발 방지까지 따라가는 게 훨씬 많은 걸 보여준다.
- 답변에서 볼 포인트를 미리 적어둔다. 그래야 면접 중에 “잘 모르겠다”는 인상 대신 구체적인 기준으로 평가할 수 있다.
1. 메시지 큐 — RabbitMQ
Q. 왜 RabbitMQ였나? Kafka나 Redis Pub/Sub이 아닌 이유는?
- 볼 포인트: 메시지 순서 보장, 소비자 ACK, 재처리, 처리량 요구 중 무엇을 기준으로 골랐는지. “팀에서 쓰고 있어서”도 솔직한 답이면 괜찮다. 그 다음 “그럼 지금 다시 고른다면?”을 묻는다.
Q. 컨슈머가 메시지 처리 중 예외가 나면 어떻게 되도록 설계했나?
- 꼬리: nack 후 requeue를 했나? 무한 재시도는 어떻게 막았나? DLQ(Dead Letter Queue)를 뒀나?
- 볼 포인트: 재시도 횟수 제한, 지수 백오프, 최종 실패 메시지의 행방을 설명할 수 있는지.
Q. 메시지가 중복 소비될 수 있는 상황을 설명하고, 어떻게 대응했나?
- 볼 포인트: at-least-once 전달을 이해하고 있는지, 멱등성 키를 어디에 뒀는지.
2. 실시간 통신 — WebSocket
Q. 채팅 서버를 여러 인스턴스로 띄웠을 때, A 인스턴스에 붙은 사용자가 B 인스턴스에 붙은 사용자에게 메시지를 보내려면?
- 볼 포인트: 세션이 인스턴스에 종속된다는 걸 이해하는지, Redis Pub/Sub이나 메시지 브로커로 인스턴스 간 브로드캐스트를 하는 구조를 설명하는지.
Q. WebSocket 연결이 끊겼을 때 클라이언트와 서버 각각 어떻게 처리했나?
- 꼬리: 재연결 시 놓친 메시지는? heartbeat 주기는 어떻게 정했나?
Q. STOMP를 썼다면, 순수 WebSocket 대신 STOMP를 얹은 이유는?
3. 데이터 접근 — JPA / QueryDSL
Q. 연관된 엔티티가 있는 데이터를 삭제할 때 어떤 순서와 방식으로 처리했나?
- 이건 실제로 지원자의 프로젝트에 “삭제 흐름 재설계” 이력이 있어서 준비한 질문이다. 꼬리: cascade를 썼나, 직접 삭제했나? soft delete와 hard delete 중 무엇을 골랐고 이유는? 대량 삭제 시 영속성 컨텍스트 메모리 문제는?
- 볼 포인트: 삭제가 단순
delete()호출이 아니라 참조 무결성·이력 보존·성능이 얽힌 설계 문제라는 걸 인식하는지.
Q. N+1 문제를 실제로 만난 적 있나? 어떻게 발견했고 어떻게 고쳤나?
- 꼬리: fetch join과
@BatchSize,@EntityGraph의 차이. fetch join에 페이징을 걸면 어떻게 되나?
Q. QueryDSL을 도입한 이유와, 도입 후 불편했던 점은?
- 볼 포인트: 동적 쿼리·타입 안정성이라는 교과서 답 뒤에, Q클래스 생성·빌드 설정·복잡한 서브쿼리 같은 실제 마찰을 말하는지.
4. 캐시 — Redis
Q. Redis를 어떤 용도로 썼나? (캐시 / 세션 / 락 / Pub/Sub / 큐)
- 용도별로 다른 꼬리 질문이 나간다.
Q. 캐시를 썼다면, 캐시 무효화 전략은? DB와 캐시가 어긋나는 상황은 어떻게 막았나?
- 볼 포인트: TTL만 믿는지, 쓰기 시점 무효화를 하는지, Cache-Aside와 Write-Through 차이를 설명하는지.
Q. Redis가 죽으면 서비스는 어떻게 되나?
- 볼 포인트: 캐시 미스로 DB에 부하가 몰리는 상황(캐시 스탬피드)을 상상해봤는지, 장애 격리를 생각해봤는지.
5. 게이트웨이 — Spring Cloud Gateway
Q. 게이트웨이를 별도로 둔 이유는? Nginx로 못 하는 게 뭐였나?
- 볼 포인트: 인증·라우팅·필터를 Java 코드로 다루고 싶었던 실제 이유가 있는지.
Q. 게이트웨이에서 인증을 처리했다면, 인증 실패 응답은 게이트웨이가 내리나 각 서비스가 내리나? 각 서비스는 게이트웨이를 신뢰하나?
- 꼬리: 내부 서비스가 게이트웨이를 거치지 않고 직접 호출당하는 걸 어떻게 막았나?
Q. Spring Cloud Gateway는 WebFlux 기반이다. 필터 안에서 블로킹 호출을 하면 어떻게 되나?
6. 배치 처리
Q. 배치가 중간에 실패하면 어디서부터 다시 시작하나?
- 볼 포인트: 청크 단위 커밋, 재시작 시 이미 처리된 항목 스킵, 멱등성.
Q. 처리 대상이 100배로 늘면 지금 구조에서 어디가 먼저 병목이 되나?
- 볼 포인트: 자기 코드의 한계를 스스로 말할 수 있는지. 이건 어떤 주제에서든 좋은 질문이다.
Q. 비동기 재시도를 직접 구현했다면, 어떤 구조로?
- 지원자 이력에 비동기 재시도 구현이 있어서 넣은 질문이다. 꼬리: 재시도 상태는 어디에 저장했나? 서버가 재시작되면 진행 중이던 재시도는? 재시도 간격은 고정인가 증가인가?
7. 도메인 특화 — 한국어 NLP (TextRank)
지원자가 상담 시스템에서 키워드 추출에 TextRank를 썼다고 해서 준비한 영역이다.
Q. TextRank가 문서에서 키워드를 뽑는 원리를 한 문장으로 설명하면?
- 볼 포인트: 그래프·공기(co-occurrence)·PageRank 유사 반복이라는 골격을 말하는지.
Q. 한국어에서 형태소 분석기 선택이 결과에 어떤 영향을 줬나? 어떤 분석기를 썼고 왜?
Q. 추출된 키워드 품질은 어떻게 평가했나?
- 볼 포인트: 정답 셋이 없는 문제에서 평가 기준을 어떻게 세웠는지.
8. 장애 경험 — 한 사건을 끝까지
여기서 가장 많은 시간을 쓴다. 지원자의 프로젝트에 “게시글 생성 직후 조회가 실패하던 문제”가 있어서 그걸 따라갔다.
Q. 그 문제를 처음 인지한 경로는? (모니터링 / 사용자 제보 / 우연) Q. 재현은 됐나? 안 됐다면 어떻게 좁혔나? Q. 원인이 무엇이었나?
- 이 유형의 증상은 트랜잭션 커밋 전 조회, 리플리카 지연, 캐시 선반영, 비동기 인덱싱 지연 등 후보가 많다. 지원자가 후보를 나열하고 소거한 과정을 말하는지 본다. Q. 임시 조치와 근본 조치는 무엇이었나? 둘이 달랐나? Q. 같은 문제가 다시 나지 않게 무엇을 바꿨나?
한 사건을 이렇게 따라가면 기술 이해도, 문제 해결 방식, 팀 안에서의 역할, 사후 처리 태도가 한 번에 보인다.
면접 후 정리하면서 느낀 것
- 질문을 미리 준비하니 면접 중에 “다음에 뭘 묻지”가 아니라 “이 답에서 뭘 더 파지”에 집중할 수 있었다.
- 답변에서 볼 포인트를 적어두지 않으면 인상 평가로 흐른다. 적어두면 지원자 간 비교가 가능해진다.
- 가장 좋은 답은 “정답”이 아니라 “그때는 이렇게 했는데 지금 보면 이 부분은 다르게 할 것 같다” 였다. 자기 코드를 비판할 수 있는 사람은 성장한다.