Node.js 미드레벨 기술면접

Node.js 미드레벨 (3~7년) 종합 5문항 조회수 59 · 2026-07-21 (화) 19:10:54
1 캐싱 전략
Medium

Q. Node.js 애플리케이션에서 Cache-Aside 패턴과 Write-Through 패턴의 차이점을 설명하고, 각 패턴의 장단점과 적합한 사용 사례를 설명해주세요. 또한 캐시 일관성 문제를 해결하기 위한 전략도 포함해주세요.

A. 모범답안

Cache-Aside는 애플리케이션이 캐시를 먼저 확인하고 없으면 DB에서 조회 후 캐시에 저장하는 패턴으로, 읽기 위주 작업에 적합하며 캐시 장애 시에도 서비스가 가능합니다. Write-Through는 데이터 쓰기 시 캐시와 DB에 동시에 저장하는 패턴으로, 데이터 일관성이 높지만 쓰기 지연이 발생합니다. Cache-Aside는 구현이 간단하지만 초기 조회 시 지연이 있고, Write-Through는 항상 최신 데이터를 보장하지만 불필요한 캐시 저장이 발생할 수 있습니다. 캐시 일관성을 위해 TTL 설정, 이벤트 기반 캐시 무효화, 버전 관리 등의 전략을 사용할 수 있습니다.

핵심 포인트
  • • Cache-Aside는 Lazy Loading 방식으로 읽기 최적화
  • • Write-Through는 쓰기 시점에 캐시 갱신으로 일관성 보장
  • • TTL과 이벤트 기반 무효화로 캐시 일관성 관리
  • • 사용 패턴에 따른 적절한 캐싱 전략 선택
Follow-up 질문

Write-Behind(Write-Back) 패턴은 언제 사용하며, 이 패턴의 위험성과 이를 완화하는 방법은 무엇인가요?

2 테스트 전략
Medium

Q. Node.js 애플리케이션에서 외부 API 호출을 포함한 서비스 로직을 테스트할 때 Mock, Stub, Spy의 차이점을 설명하고, 각각을 사용하는 적절한 상황과 Jest 또는 Sinon을 활용한 구현 전략을 설명해주세요.

A. 모범답안

Mock은 객체의 전체 동작을 가짜로 대체하고 호출 여부와 파라미터를 검증하는 데 사용하며, 주로 의존성 전체를 대체할 때 적합합니다. Stub은 특정 함수의 반환값만 미리 정의하여 테스트 시나리오를 제어하는 데 사용하며, 외부 API 응답을 시뮬레이션할 때 유용합니다. Spy는 실제 함수를 그대로 실행하면서 호출 정보만 기록하여, 함수가 올바르게 호출되었는지 검증할 때 사용합니다. Jest에서는 jest.fn()으로 Mock을, jest.spyOn()으로 Spy를 구현하며, Stub은 mockReturnValue()나 mockResolvedValue()로 구현할 수 있습니다.

핵심 포인트
  • • Mock은 전체 객체 대체 및 상호작용 검증
  • • Stub은 반환값 제어로 테스트 시나리오 구성
  • • Spy는 실제 동작 유지하며 호출 정보 추적
  • • 테스트 목적에 따라 적절한 테스트 더블 선택
Follow-up 질문

통합 테스트에서 실제 데이터베이스 대신 인메모리 DB를 사용하는 것과 Mock을 사용하는 것의 장단점을 비교해주세요.

3 에러 핸들링
Hard

Q. Node.js에서 Unhandled Promise Rejection과 Uncaught Exception의 차이점을 설명하고, 각각을 처리하는 방법과 process.on('unhandledRejection')과 process.on('uncaughtException') 이벤트 핸들러를 사용할 때의 주의사항 및 프로덕션 환경에서의 모니터링 전략을 설명해주세요.

A. 모범답안

Unhandled Promise Rejection은 Promise가 reject되었지만 catch 핸들러가 없을 때 발생하며, Uncaught Exception은 동기 코드에서 try-catch로 처리되지 않은 에러가 발생할 때 나타납니다. process.on('unhandledRejection')으로 처리되지 않은 Promise 에러를 잡을 수 있지만, 근본적으로는 모든 Promise에 적절한 에러 핸들링을 추가해야 합니다. process.on('uncaughtException')은 애플리케이션이 불안정한 상태가 되므로 로그를 남기고 graceful shutdown을 수행해야 하며, 절대 계속 실행해서는 안 됩니다. 프로덕션에서는 Sentry나 DataDog 같은 APM 도구로 이러한 에러를 모니터링하고, PM2나 Kubernetes의 자동 재시작 기능을 활용해야 합니다.

핵심 포인트
  • • Unhandled Rejection은 비동기, Uncaught Exception은 동기 에러
  • • uncaughtException 발생 시 프로세스 재시작 필수
  • • 모든 비동기 코드에 명시적 에러 핸들링 구현
  • • APM 도구와 프로세스 매니저로 에러 모니터링 및 복구
Follow-up 질문

Domain 모듈이 deprecated된 이유와 이를 대체하는 현대적인 에러 처리 방법은 무엇인가요?

4 성능 최적화
Hard

Q. Node.js 애플리케이션에서 N+1 쿼리 문제가 무엇인지 설명하고, Sequelize나 TypeORM 같은 ORM을 사용할 때 이 문제가 발생하는 구체적인 상황과 DataLoader 패턴을 활용한 해결 방법, 그리고 eager loading과 lazy loading의 트레이드오프를 설명해주세요.

A. 모범답안

N+1 쿼리 문제는 부모 엔티티 N개를 조회한 후 각각의 연관 엔티티를 개별적으로 조회하여 총 N+1번의 쿼리가 발생하는 성능 문제입니다. ORM에서 관계 데이터를 lazy loading으로 접근할 때 흔히 발생하며, 예를 들어 사용자 목록을 조회한 후 각 사용자의 게시글을 순회하며 접근하면 발생합니다. DataLoader는 동일한 이벤트 루프 내의 요청을 배치로 모아 한 번에 처리하여 이 문제를 해결하며, 특히 GraphQL에서 유용합니다. Eager loading(include, join 사용)은 초기 쿼리에서 모든 데이터를 가져와 N+1을 방지하지만 불필요한 데이터까지 로드할 수 있고, lazy loading은 필요할 때만 조회하지만 N+1 위험이 있어 사용 패턴에 따라 선택해야 합니다.

핵심 포인트
  • • N+1은 반복문 내 개별 쿼리 실행으로 발생
  • • DataLoader로 배치 처리 및 캐싱 구현
  • • Eager loading으로 JOIN 쿼리 한 번에 처리
  • • 필요한 데이터만 조회하는 전략적 쿼리 설계
Follow-up 질문

GraphQL Resolver에서 N+1 문제를 진단하는 방법과 실제 프로덕션에서 쿼리 성능을 모니터링하는 도구는 무엇이 있나요?

5 아키텍처 패턴
Medium

Q. Node.js에서 CQRS(Command Query Responsibility Segregation) 패턴의 개념을 설명하고, 이 패턴이 해결하는 문제와 Event Sourcing과의 관계, 그리고 실제 구현 시 고려해야 할 점과 적합한 사용 사례를 설명해주세요.

A. 모범답안

CQRS는 데이터 변경(Command)과 조회(Query)의 책임을 분리하는 패턴으로, 각각 다른 모델과 데이터베이스를 사용할 수 있습니다. 복잡한 도메인에서 읽기와 쓰기 요구사항이 다를 때 유용하며, 읽기 모델을 비정규화하여 조회 성능을 최적화하고 쓰기 모델은 비즈니스 로직에 집중할 수 있습니다. Event Sourcing과 함께 사용하면 모든 상태 변경을 이벤트로 저장하고 이를 통해 읽기 모델을 구성할 수 있어 시너지가 있습니다. 구현 시 데이터 동기화 지연(Eventual Consistency), 복잡도 증가, 인프라 비용 증가를 고려해야 하며, 높은 읽기/쓰기 비율 차이가 있거나 복잡한 조회 요구사항이 있는 시스템에 적합합니다.

핵심 포인트
  • • Command와 Query 모델 분리로 각각 최적화
  • • 읽기 모델 비정규화로 조회 성능 향상
  • • Event Sourcing으로 이벤트 기반 상태 관리
  • • 복잡도와 일관성 트레이드오프 고려 필요
Follow-up 질문

CQRS를 적용한 시스템에서 Command 실행 후 즉시 Query로 조회했을 때 데이터가 반영되지 않는 문제를 사용자 경험 측면에서 어떻게 처리할 수 있나요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!