JavaScript 미드레벨 기술면접

JavaScript 미드레벨 (3~7년) 코딩 · 알고리즘 5문항 조회수 44 · 2026-07-11 (토) 19:11:09
1 비동기 프로그래밍
Medium

Q. JavaScript에서 async 함수 내부에서 발생한 동기 에러와 비동기 에러의 처리 방식을 설명하고, top-level await가 모듈 시스템에 미치는 영향과 실무에서 사용할 때 주의해야 할 점을 설명해주세요.

A. 모범답안

async 함수 내부의 동기 에러는 함수 실행 시점에 즉시 발생하지만 자동으로 rejected Promise로 래핑되어 반환됩니다. 비동기 에러는 await 키워드를 통해 Promise rejection을 동기 코드처럼 try-catch로 처리할 수 있습니다. top-level await는 ES2022에서 도입된 기능으로 모듈의 최상위 레벨에서 await를 사용할 수 있게 하며, 해당 모듈을 import하는 모든 모듈이 await가 완료될 때까지 대기하게 됩니다. 이는 모듈 로딩 순서와 초기화 타이밍에 영향을 주므로, 장시간 소요되는 작업에 사용하면 애플리케이션 시작 시간이 지연될 수 있습니다. 실무에서는 설정 파일 로드나 DB 연결 같은 필수 초기화 작업에만 제한적으로 사용하고, 에러 발생 시 모듈 로드 자체가 실패한다는 점을 고려해야 합니다.

핵심 포인트
  • • async 함수는 모든 에러를 rejected Promise로 변환
  • • top-level await는 모듈 로딩을 블로킹하여 의존성 체인 전체에 영향
  • • 초기화 시간 지연과 에러 처리 전략 고려 필요
  • • CommonJS와의 호환성 문제 존재
Follow-up 질문

여러 모듈에서 top-level await를 사용할 때 순환 의존성 문제가 발생할 수 있는 시나리오와 이를 방지하는 방법을 설명해주세요.

2 성능 최적화
Hard

Q. Web Worker를 사용하여 메인 스레드의 블로킹을 방지하는 패턴을 설명하고, Worker와 메인 스레드 간 데이터 전송 시 Structured Clone Algorithm의 제약사항과 Transferable Objects를 사용한 최적화 방법, 그리고 SharedArrayBuffer를 활용한 메모리 공유 방식의 장단점을 설명해주세요.

A. 모범답안

Web Worker는 별도의 스레드에서 JavaScript를 실행하여 CPU 집약적 작업을 메인 스레드와 분리할 수 있습니다. postMessage를 통한 데이터 전송은 Structured Clone Algorithm을 사용하는데, 함수, DOM 노드, Symbol 등은 복제할 수 없고 데이터 크기가 클수록 직렬화 비용이 증가합니다. Transferable Objects(ArrayBuffer, MessagePort 등)는 소유권을 이전하는 방식으로 복사 없이 빠르게 전송되지만 원본 스레드에서는 더 이상 접근할 수 없습니다. SharedArrayBuffer는 여러 스레드가 동일한 메모리 영역을 공유하여 복사 비용을 없애지만, Atomics API를 통한 동기화가 필요하고 race condition 위험이 있으며 보안 요구사항(COOP/COEP 헤더)이 엄격합니다. 실무에서는 이미지 처리, 대용량 데이터 파싱, 암호화 작업 등에 Worker를 활용하며, 데이터 크기와 전송 빈도를 고려해 적절한 전송 방식을 선택해야 합니다.

핵심 포인트
  • • Structured Clone은 직렬화 비용이 있고 특정 타입 제약 존재
  • • Transferable Objects는 zero-copy 전송이지만 소유권 이전
  • • SharedArrayBuffer는 동기화 복잡성과 보안 제약 존재
  • • 작업 특성에 따라 적절한 데이터 전송 방식 선택 필요
Follow-up 질문

Worker Pool 패턴을 구현할 때 Worker 인스턴스 수를 결정하는 기준과 작업 큐 관리 전략을 설명해주세요.

3 함수형 프로그래밍
Medium

Q. JavaScript에서 Transducer 패턴의 개념과 동작 원리를 설명하고, map과 filter를 체이닝할 때 발생하는 중간 배열 생성 문제를 Transducer로 어떻게 해결할 수 있는지 설명해주세요. 또한 reduce를 활용한 Transducer 구현 시 성능 이점과 실무 적용 시나리오를 제시해주세요.

A. 모범답안

Transducer는 함수형 프로그래밍에서 컬렉션 변환 로직을 조합 가능한 형태로 추상화한 패턴으로, reducing 함수를 다른 reducing 함수로 변환하는 고차 함수입니다. 일반적인 map, filter 체이닝은 각 단계마다 중간 배열을 생성하여 메모리와 성능 비용이 발생하지만, Transducer는 모든 변환을 단일 reduce 패스로 합성하여 중간 배열 없이 한 번의 순회로 처리합니다. 예를 들어 대용량 데이터를 여러 단계로 필터링하고 변환할 때 각 요소가 모든 변환을 거쳐 바로 결과에 추가되므로 메모리 효율이 높습니다. 실무에서는 스트림 처리, 대용량 로그 분석, ETL 파이프라인 등에서 유용하며, RxJS나 Ramda 같은 라이브러리에서 이 개념을 활용합니다. 다만 코드 복잡도가 증가하므로 성능이 실제로 문제가 되는 경우에만 적용하는 것이 좋습니다.

핵심 포인트
  • • Transducer는 reducing 함수를 변환하는 고차 함수
  • • 중간 배열 생성 없이 단일 패스로 여러 변환 수행
  • • 메모리 효율과 성능 향상, 특히 대용량 데이터 처리에 유리
  • • 코드 복잡도 증가로 필요성 판단 중요
Follow-up 질문

Lazy Evaluation과 Transducer의 차이점을 설명하고, JavaScript에서 Generator를 활용한 Lazy Evaluation 구현 방법을 비교해주세요.

4 모듈 시스템
Hard

Q. JavaScript의 CommonJS와 ES Modules의 근본적인 차이점을 로딩 방식, 순환 참조 처리, Tree Shaking 지원 측면에서 비교 설명하고, Node.js에서 두 모듈 시스템을 혼용할 때 발생할 수 있는 문제점과 해결 방법을 제시해주세요. 또한 dynamic import의 활용 사례와 주의사항을 설명해주세요.

A. 모범답안

CommonJS는 동기적으로 모듈을 로드하고 실행 시점에 require를 평가하는 반면, ES Modules는 정적 분석이 가능한 선언적 문법으로 파싱 단계에서 의존성을 파악하고 비동기로 로드합니다. 순환 참조 시 CommonJS는 불완전한 exports 객체를 반환하여 undefined 문제가 발생할 수 있지만, ESM은 live binding으로 나중에 초기화된 값도 참조할 수 있습니다. ESM은 정적 구조 덕분에 Tree Shaking이 가능하지만 CommonJS는 런타임에 결정되어 불가능합니다. Node.js에서 혼용 시 .mjs/.cjs 확장자나 package.json의 type 필드로 구분하며, CommonJS에서 ESM을 import하려면 dynamic import를 사용해야 합니다. dynamic import는 코드 스플리팅, 조건부 로딩, 플러그인 시스템에 유용하지만 Promise를 반환하므로 에러 처리와 로딩 상태 관리가 필요하고, 번들러 설정에 따라 청크 분리 전략을 고려해야 합니다.

핵심 포인트
  • • CommonJS는 동기/동적, ESM은 비동기/정적 분석 가능
  • • 순환 참조 처리 방식과 live binding 차이
  • • ESM만 Tree Shaking 지원으로 번들 크기 최적화 가능
  • • Node.js 혼용 시 확장자와 type 필드로 구분, dynamic import 활용
Follow-up 질문

Webpack이나 Vite 같은 번들러에서 ESM과 CommonJS 모듈을 함께 번들링할 때 발생하는 interop 문제와 __esModule 플래그의 역할을 설명해주세요.

5 디자인 패턴
Medium

Q. JavaScript에서 Mixin 패턴과 Decorator 패턴의 차이점을 설명하고, 각각을 구현하는 방법과 실무에서의 활용 사례를 제시해주세요. 또한 TypeScript의 Decorator와 JavaScript Decorator Proposal(Stage 3)의 차이점과 실제 프로젝트 적용 시 고려사항을 설명해주세요.

A. 모범답안

Mixin은 여러 객체의 기능을 조합하여 새로운 객체를 만드는 패턴으로 Object.assign이나 스프레드 연산자로 구현하며, 다중 상속과 유사한 효과를 냅니다. Decorator는 기존 객체나 함수의 동작을 래핑하여 확장하는 패턴으로, 원본을 수정하지 않고 기능을 추가합니다. Mixin은 로깅, 이벤트 처리 같은 공통 기능을 여러 클래스에 주입할 때 유용하고, Decorator는 권한 검사, 캐싱, 성능 측정 같은 횡단 관심사를 처리할 때 적합합니다. TypeScript Decorator는 실험적 기능으로 --experimentalDecorators 플래그가 필요하고 메타데이터 리플렉션을 지원하지만, JavaScript Stage 3 Decorator는 표준화 과정에 있으며 문법과 동작이 다릅니다. 실무에서는 프레임워크 지원 여부, 빌드 도구 호환성, 팀의 이해도를 고려하여 도입해야 하며, 과도한 사용은 코드 복잡도를 높일 수 있어 명확한 사용 가이드라인이 필요합니다.

핵심 포인트
  • • Mixin은 기능 조합, Decorator는 동작 래핑
  • • Mixin은 다중 기능 주입, Decorator는 횡단 관심사 처리에 적합
  • • TypeScript와 JavaScript Decorator 제안의 문법 및 동작 차이
  • • 표준화 진행 상황과 도구 지원 확인 필요
Follow-up 질문

JavaScript Proxy를 활용하여 런타임 Decorator 패턴을 구현할 때의 장점과, 클래스 데코레이터와의 성능 비교를 설명해주세요.

댓글 0

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

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