Node.js 시니어 종합 기술면접

Node.js 시니어 (7년+) 종합 5문항 조회수 95 · 2026-06-29 (월) 03:11:07
1 성능 최적화
Hard

Q. Node.js 애플리케이션에서 클러스터 모드로 여러 워커 프로세스를 실행할 때, 마스터 프로세스가 들어오는 연결을 워커들에게 분배하는 방식(Round-Robin vs Shared Socket)을 설명하고, 각 방식의 장단점을 비교해주세요. 또한 특정 세션을 동일한 워커로 라우팅해야 하는 Sticky Session이 필요한 경우 어떻게 구현하시겠습니까?

A. 모범답안

Node.js 클러스터는 두 가지 로드 밸런싱 방식을 제공합니다. Round-Robin 방식은 마스터가 연결을 받아 순차적으로 워커에게 분배하며, OS별 편차 없이 균등 분배가 가능하지만 마스터가 병목이 될 수 있습니다. Shared Socket 방식은 모든 워커가 같은 포트를 공유하며 OS 커널이 분배를 담당해 오버헤드가 적지만, OS에 따라 불균등 분배가 발생할 수 있습니다. Sticky Session은 nginx의 ip_hash나 HAProxy의 source 옵션을 사용하거나, 애플리케이션 레벨에서 Redis 기반 세션 저장소를 활용하여 모든 워커가 세션을 공유하도록 구현할 수 있습니다.

핵심 포인트
  • • Round-Robin: 마스터가 연결을 순차 분배, 균등하지만 마스터 병목 가능
  • • Shared Socket: OS 커널이 분배, 오버헤드 적지만 불균등 가능성
  • • Sticky Session: 외부 로드밸런서 설정 또는 Redis 세션 공유로 구현
  • • Windows는 기본적으로 Round-Robin, Linux는 Shared Socket 사용
Follow-up 질문

PM2나 다른 프로세스 매니저를 사용할 때 클러스터 모드 대비 어떤 추가 기능을 활용할 수 있으며, 무중단 배포(Zero-Downtime Deployment)는 어떻게 구현하시겠습니까?

2 데이터베이스 아키텍처
Hard

Q. 대규모 트래픽을 처리하는 Node.js 애플리케이션에서 데이터베이스 연결 풀(Connection Pool)의 크기를 결정하는 전략을 설명해주세요. 특히 PostgreSQL에서 권장하는 공식(connections = ((core_count * 2) + effective_spindle_count))의 의미와, Node.js의 비동기 특성을 고려할 때 연결 풀 크기 설정 시 주의해야 할 사항을 설명해주세요.

A. 모범답안

데이터베이스 연결 풀 크기는 CPU 코어 수와 디스크 특성을 기반으로 설정하는데, PostgreSQL 공식은 CPU 병렬 처리 능력과 디스크 I/O 동시성을 고려합니다. 하지만 Node.js는 비동기 I/O 모델로 단일 스레드가 많은 요청을 처리하므로, 전통적인 멀티스레드 애플리케이션보다 적은 연결로도 높은 처리량을 달성할 수 있습니다. 과도한 연결 풀은 DB 서버의 컨텍스트 스위칭과 메모리 오버헤드를 증가시키므로, 실제 동시 쿼리 수를 모니터링하고 점진적으로 증가시키며 최적값을 찾아야 합니다. 일반적으로 워커 프로세스당 10-20개 연결로 시작하여 병목 지점을 분석하며 조정하는 것이 좋습니다.

핵심 포인트
  • • 전통 공식은 멀티스레드 환경 기준, Node.js는 비동기 특성상 더 적은 연결로 효율적
  • • 과도한 연결은 DB 서버의 컨텍스트 스위칭과 메모리 낭비 유발
  • • 실제 동시 쿼리 수 모니터링하여 점진적 조정 필요
  • • 연결 획득 대기 시간, 쿼리 실행 시간, DB CPU 사용률을 종합 분석
Follow-up 질문

Read Replica를 활용하는 환경에서 마스터와 레플리카 간 복제 지연(Replication Lag)이 발생할 때, 애플리케이션 레벨에서 데이터 정합성을 보장하기 위한 전략은 무엇이 있을까요?

3 보안 아키텍처
Hard

Q. Node.js 애플리케이션에서 SQL Injection, NoSQL Injection, Command Injection 등 다양한 인젝션 공격의 차이점과 각각의 방어 방법을 설명해주세요. 특히 ORM/ODM을 사용하더라도 인젝션 공격에 취약할 수 있는 경우와, 사용자 입력 검증 시 화이트리스트 방식과 블랙리스트 방식 중 어느 것을 선택해야 하는지 근거와 함께 설명해주세요.

A. 모범답안

SQL Injection은 쿼리 문자열에 악의적인 SQL을 삽입하는 공격으로 Prepared Statement나 ORM의 파라미터 바인딩으로 방어합니다. NoSQL Injection은 MongoDB 등에서 객체 형태로 쿼리 연산자($where, $gt 등)를 주입하는 공격으로, 입력값의 타입 검증과 쿼리 객체 생성 시 연산자 필터링이 필요합니다. Command Injection은 child_process 등에서 시스템 명령어를 실행할 때 발생하므로, shell 옵션을 false로 설정하고 인수를 배열로 전달해야 합니다. ORM 사용 시에도 raw 쿼리나 동적 필드명 사용 시 취약할 수 있으며, 입력 검증은 허용된 값만 통과시키는 화이트리스트 방식이 우회 공격을 원천 차단할 수 있어 안전합니다.

핵심 포인트
  • • SQL Injection: Prepared Statement, 파라미터 바인딩 사용
  • • NoSQL Injection: 타입 검증, 쿼리 연산자 필터링, Object.create(null) 활용
  • • Command Injection: shell 옵션 비활성화, 인수 배열 전달
  • • 화이트리스트 방식이 블랙리스트보다 안전 - 알려지지 않은 공격 패턴 차단
Follow-up 질문

OWASP Top 10에서 Insecure Deserialization 취약점이 Node.js 환경에서 어떻게 발생할 수 있으며, JSON.parse 외에 직렬화 라이브러리를 사용할 때 주의해야 할 보안 사항은 무엇인가요?

4 메시징 시스템
Hard

Q. Node.js 기반 이벤트 드리븐 아키텍처에서 메시지 큐(RabbitMQ, Kafka 등)를 도입할 때 At-Most-Once, At-Least-Once, Exactly-Once 전송 보장 수준의 차이를 설명하고, 각 수준을 구현하기 위한 전략을 설명해주세요. 특히 Exactly-Once 시맨틱을 구현할 때 멱등성(Idempotency) 보장이 왜 중요한지 설명해주세요.

A. 모범답안

At-Most-Once는 메시지를 한 번만 전송하고 확인 없이 삭제하여 손실 가능성이 있지만 중복은 없습니다. At-Least-Once는 메시지 처리 확인(ACK) 후 삭제하여 손실은 방지하지만 재전송으로 중복 가능성이 있습니다. Exactly-Once는 메시지가 정확히 한 번만 처리되도록 보장하는데, 분산 환경에서는 네트워크 장애나 프로세스 재시작으로 완벽한 구현이 어렵습니다. 따라서 At-Least-Once 전송에 애플리케이션 레벨에서 멱등성을 보장하여 중복 처리를 허용하되 결과는 동일하게 만드는 방식이 현실적입니다. 멱등성은 고유 메시지 ID를 DB에 저장하거나, 자연스럽게 멱등한 연산(SET 연산, 절대값 업데이트 등)을 사용하여 구현합니다.

핵심 포인트
  • • At-Most-Once: 손실 가능, 중복 없음 / At-Least-Once: 손실 없음, 중복 가능
  • • Exactly-Once: 이론적 보장, 실무에서는 At-Least-Once + 멱등성으로 구현
  • • 멱등성: 동일 메시지 여러 번 처리해도 결과 동일하게 설계
  • • 메시지 ID 기반 중복 제거 테이블, 트랜잭션 아웃박스 패턴 활용
Follow-up 질문

Kafka의 파티션 리밸런싱 중에 메시지 처리 순서가 보장되지 않을 수 있는데, 순서 보장이 중요한 이벤트 스트림을 처리할 때 어떤 전략을 사용하시겠습니까?

5 모니터링 및 관찰성
Medium

Q. 프로덕션 환경의 Node.js 애플리케이션에서 관찰성(Observability)을 확보하기 위한 세 가지 핵심 요소인 Metrics, Logs, Traces의 역할과 차이점을 설명하고, 각각을 수집하고 분석하기 위한 도구와 전략을 제시해주세요. 특히 분산 트레이싱에서 Trace ID와 Span ID의 개념과, 마이크로서비스 간 컨텍스트 전파(Context Propagation) 방법을 설명해주세요.

A. 모범답안

Metrics는 시스템의 정량적 지표(CPU, 메모리, 요청 수, 응답 시간 등)를 시계열로 수집하여 전체적인 건강도를 파악하는 데 사용하며, Prometheus나 Datadog으로 수집합니다. Logs는 개별 이벤트의 상세 정보를 기록하여 문제의 원인을 분석하는 데 사용하며, ELK Stack이나 Loki로 중앙화합니다. Traces는 요청이 여러 서비스를 거치는 전체 경로를 추적하여 병목 지점을 식별하는 데 사용하며, Jaeger나 Zipkin으로 시각화합니다. 분산 트레이싱에서 Trace ID는 전체 요청 흐름을 식별하고, Span ID는 각 서비스 내 작업 단위를 식별하며, HTTP 헤더나 메시지 메타데이터를 통해 서비스 간 컨텍스트를 전파합니다.

핵심 포인트
  • • Metrics: 시계열 수치 데이터, 시스템 전체 건강도 모니터링
  • • Logs: 이벤트 상세 기록, 문제 원인 분석 및 디버깅
  • • Traces: 분산 요청 경로 추적, 병목 지점 식별
  • • Trace ID로 전체 요청 추적, Span ID로 개별 작업 식별, HTTP 헤더로 컨텍스트 전파
Follow-up 질문

고부하 상황에서 모든 요청을 트레이싱하면 오버헤드가 크므로 샘플링을 적용해야 하는데, Head-based Sampling과 Tail-based Sampling의 차이와 각각의 장단점을 설명해주세요.

댓글 0

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

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