Node.js 미드레벨 프레임워크 심화 면접

Node.js 미드레벨 (3~7년) 프레임워크 5문항 조회수 121 · 2026-05-02 (토) 03:10:52
1 Module System
Medium

Q. Node.js에서 CommonJS(require)와 ES Modules(import)의 동작 방식 차이를 설명하고, 두 모듈 시스템을 하나의 프로젝트에서 함께 사용할 때 발생할 수 있는 문제점과 해결 방법을 설명해주세요.

A. 모범답안

CommonJS는 동기적으로 모듈을 로드하며 런타임에 평가되고, ES Modules는 비동기적으로 로드되며 정적 분석이 가능합니다. CommonJS는 module.exports 객체를 복사하지만, ES Modules는 바인딩을 export하여 live binding을 제공합니다. 혼용 시 문제는 ES Module에서 require를 직접 사용할 수 없고, CommonJS에서 ES Module을 import할 때 await import()를 사용해야 합니다. package.json의 type 필드를 'module'로 설정하거나, .mjs/.cjs 확장자를 사용하여 명시적으로 구분하고, createRequire를 사용하여 ES Module에서 CommonJS를 로드할 수 있습니다.

핵심 포인트
  • • CommonJS는 동기/런타임 평가, ES Modules는 비동기/정적 분석
  • • CommonJS는 값 복사, ES Modules는 live binding
  • • 혼용 시 await import() 또는 createRequire 사용
  • • package.json type 필드와 파일 확장자로 모듈 타입 구분
Follow-up 질문

ES Modules의 Top-level await 기능이 어떻게 동작하며, 이것이 애플리케이션 시작 시간에 미치는 영향과 주의사항은 무엇인가요?

2 Middleware Architecture
Medium

Q. Express.js의 미들웨어 체인 동작 원리를 설명하고, next()를 호출하지 않았을 때와 next(error)를 호출했을 때의 차이점, 그리고 미들웨어 순서가 중요한 이유를 실무 예시와 함께 설명해주세요.

A. 모범답안

Express 미들웨어는 스택 구조로 순차적으로 실행되며, next()를 호출해야 다음 미들웨어로 제어권이 넘어갑니다. next()를 호출하지 않으면 요청이 중단되어 응답을 보내거나 타임아웃이 발생하고, next(error)를 호출하면 일반 미들웨어를 건너뛰고 에러 핸들링 미들웨어로 직접 이동합니다. 미들웨어 순서는 매우 중요한데, 예를 들어 body-parser는 req.body를 파싱하는 미들웨어보다 먼저 와야 하고, 인증 미들웨어는 보호된 라우트보다 먼저 실행되어야 하며, 에러 핸들러는 가장 마지막에 위치해야 모든 에러를 catch할 수 있습니다.

핵심 포인트
  • • 미들웨어는 스택 구조로 순차 실행, next()로 제어권 전달
  • • next() 미호출 시 요청 중단, next(error) 시 에러 핸들러로 이동
  • • 미들웨어 순서가 기능 동작에 직접적 영향
  • • body-parser, 인증, 에러 핸들러 등의 순서 중요
Follow-up 질문

Router 레벨 미들웨어와 Application 레벨 미들웨어의 차이점과 각각의 사용 사례를 설명해주세요.

3 Buffer & Encoding
Hard

Q. Node.js의 Buffer 객체가 필요한 이유와 String과의 차이점을 설명하고, 대용량 바이너리 데이터를 처리할 때 Buffer를 효율적으로 사용하는 방법과 메모리 관리 전략을 설명해주세요.

A. 모범답안

Buffer는 고정 크기의 원시 바이너리 데이터를 다루는 객체로, V8 힙 외부의 메모리를 사용하여 가비지 컬렉션 오버헤드를 줄입니다. String은 UTF-16으로 인코딩되어 메모리 효율이 낮지만, Buffer는 바이트 단위로 직접 접근 가능합니다. 대용량 데이터 처리 시 Buffer.allocUnsafe 대신 Buffer.alloc을 사용하여 보안 이슈를 방지하고, Stream과 함께 사용하여 청크 단위로 처리하며, Buffer Pool을 활용하여 작은 Buffer의 할당 비용을 줄입니다. 또한 Buffer.concat보다는 미리 크기를 계산하여 한 번에 할당하고, 사용 후 명시적으로 참조를 제거하여 메모리를 해제합니다.

핵심 포인트
  • • Buffer는 V8 힙 외부 메모리 사용으로 GC 오버헤드 감소
  • • 바이너리 데이터 직접 처리, String보다 메모리 효율적
  • • Stream과 함께 청크 단위 처리로 메모리 사용 최소화
  • • Buffer Pool 활용 및 사전 크기 계산으로 성능 최적화
Follow-up 질문

Buffer.allocUnsafe를 사용했을 때 발생할 수 있는 보안 문제는 무엇이며, 어떤 상황에서 안전하게 사용할 수 있나요?

4 Child Process & IPC
Hard

Q. Node.js의 child_process 모듈에서 spawn, exec, fork의 차이점을 설명하고, 각각의 적합한 사용 사례와 부모-자식 프로세스 간 통신(IPC) 방법을 설명해주세요.

A. 모범답안

spawn은 스트림 기반으로 대용량 데이터를 처리하며 명령어와 인자를 분리하여 쉘을 거치지 않아 안전합니다. exec은 쉘을 통해 명령을 실행하고 버퍼에 결과를 모아 콜백으로 반환하여 작은 출력에 적합하지만 쉘 인젝션 위험이 있습니다. fork는 새로운 Node.js 프로세스를 생성하며 내장 IPC 채널을 제공하여 메시지 기반 통신이 가능합니다. spawn은 대용량 로그 처리나 파일 변환에, exec은 간단한 시스템 명령 실행에, fork는 CPU 집약적 작업의 분산 처리에 적합합니다. IPC는 fork의 경우 send/on('message')로 구조화된 데이터를 주고받고, spawn/exec은 stdio 스트림을 통해 통신합니다.

핵심 포인트
  • • spawn은 스트림 기반, exec은 버퍼 기반, fork는 Node.js 프로세스 전용
  • • spawn이 가장 안전하고 대용량 처리에 적합
  • • fork는 내장 IPC 채널로 메시지 통신 지원
  • • exec은 쉘 인젝션 위험이 있어 신뢰할 수 없는 입력에 부적합
Follow-up 질문

child_process로 생성한 프로세스가 좀비 프로세스가 되는 상황과 이를 방지하는 방법을 설명해주세요.

5 HTTP/HTTPS Server
Medium

Q. Node.js의 http 모듈로 직접 서버를 구성할 때와 Express 같은 프레임워크를 사용할 때의 차이점을 설명하고, Keep-Alive 연결 관리와 Connection Timeout 설정이 서버 성능에 미치는 영향을 설명해주세요.

A. 모범답안

http 모듈은 로우 레벨 API로 라우팅, 미들웨어, 파싱 등을 직접 구현해야 하지만 오버헤드가 적고 세밀한 제어가 가능합니다. Express는 라우팅, 미들웨어 체인, 에러 핸들링을 추상화하여 개발 생산성이 높지만 약간의 성능 오버헤드가 있습니다. Keep-Alive는 TCP 연결을 재사용하여 핸드셰이크 오버헤드를 줄이고 성능을 향상시키지만, 과도한 Keep-Alive 타임아웃은 소켓을 오래 점유하여 동시 연결 수를 제한할 수 있습니다. server.keepAliveTimeout과 server.headersTimeout을 적절히 설정하여 Slow Loris 공격을 방지하고, 로드밸런서의 타임아웃보다 길게 설정하여 연결이 조기 종료되지 않도록 합니다.

핵심 포인트
  • • http 모듈은 저수준 제어 가능, Express는 추상화로 생산성 향상
  • • Keep-Alive로 TCP 연결 재사용하여 성능 개선
  • • 과도한 타임아웃은 소켓 점유로 동시 연결 제한
  • • keepAliveTimeout과 headersTimeout 설정으로 보안과 성능 균형
Follow-up 질문

Node.js 서버에서 HTTP/2를 사용할 때의 장점과 구현 시 주의사항은 무엇인가요?

댓글 0

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

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