TypeScript 미드레벨 종합 기술면접

TypeScript 미드레벨 (3~7년) 종합 5문항 조회수 98 · 2026-07-28 (화) 03:10:56
1 TypeScript 타입 시스템
Hard

Q. TypeScript의 Covariance(공변성)와 Contravariance(반공변성) 개념을 설명하고, 함수 매개변수가 반공변적이고 반환 타입이 공변적인 이유를 타입 안정성 관점에서 설명해주세요. 또한 strictFunctionTypes 옵션이 이와 어떤 관련이 있는지 설명해주세요.

A. 모범답안

공변성은 타입 A가 B의 서브타입일 때 Container<A>도 Container<B>의 서브타입이 되는 것이고, 반공변성은 그 반대 관계입니다. 함수 매개변수는 반공변적인데, 이는 더 넓은 타입을 받는 함수가 더 좁은 타입을 받는 함수를 대체할 수 있어야 타입 안정성이 보장되기 때문입니다(리스코프 치환 원칙). 반환 타입은 공변적인데, 더 구체적인 타입을 반환하는 함수가 더 일반적인 타입을 반환하는 함수를 안전하게 대체할 수 있기 때문입니다. strictFunctionTypes 옵션을 활성화하면 메서드가 아닌 함수 타입의 매개변수에 대해 올바른 반공변성 검사가 수행되어 더 엄격한 타입 체크가 가능합니다.

핵심 포인트
  • • 공변성과 반공변성의 정의 및 타입 계층 관계
  • • 함수 매개변수의 반공변성이 타입 안정성을 보장하는 원리
  • • strictFunctionTypes 옵션의 역할과 메서드 타입 검사 차이
Follow-up 질문

배열이 공변적이어서 발생할 수 있는 타입 안정성 문제와 readonly 배열이 이를 어떻게 해결하는지 설명해주세요.

2 성능 최적화
Medium

Q. Node.js 애플리케이션에서 V8 엔진의 가비지 컬렉션(GC)이 성능에 미치는 영향을 설명하고, Young Generation과 Old Generation의 차이, 그리고 대용량 데이터 처리 시 메모리 압박을 줄이기 위한 스트림(Stream) 기반 처리 전략을 TypeScript 관점에서 설명해주세요.

A. 모범답안

V8의 가비지 컬렉션은 Young Generation(Scavenger)과 Old Generation(Mark-Sweep-Compact)으로 나뉘며, Young Generation은 빠르게 생성되고 소멸되는 객체를 처리하고 Old Generation은 오래 살아남는 객체를 처리합니다. GC가 실행될 때 애플리케이션이 일시 중지되므로(Stop-the-World) 빈번한 GC는 성능 저하를 일으킵니다. 대용량 파일이나 데이터 처리 시 전체를 메모리에 로드하면 Old Generation으로 승격되어 Major GC를 유발하므로, Node.js의 Readable/Writable Stream을 사용해 청크 단위로 처리하면 메모리 사용량을 일정하게 유지할 수 있습니다. TypeScript에서는 Stream 타입을 제네릭으로 정의하여 타입 안전성을 확보할 수 있습니다.

핵심 포인트
  • • V8 GC의 세대별 메모리 관리 메커니즘
  • • GC가 애플리케이션 성능에 미치는 영향
  • • 스트림 기반 처리로 메모리 압박을 줄이는 전략
Follow-up 질문

Node.js에서 --max-old-space-size 플래그를 조정하는 것이 언제 필요한지, 그리고 메모리 누수를 진단하기 위한 Heap Snapshot 분석 방법을 설명해주세요.

3 시스템 설계
Hard

Q. 이벤트 소싱(Event Sourcing) 패턴의 개념과 장단점을 설명하고, 전통적인 CRUD 방식과 비교하여 어떤 도메인에 적합한지 설명해주세요. 또한 TypeScript로 이벤트 스토어를 구현할 때 이벤트 버전 관리와 스냅샷(Snapshot) 최적화 전략을 설명해주세요.

A. 모범답안

이벤트 소싱은 상태 변경을 직접 저장하는 대신 상태를 변경시킨 이벤트들을 순서대로 저장하는 패턴으로, 완전한 감사 추적(Audit Trail)과 시간 여행(Time Travel) 디버깅이 가능합니다. 장점은 데이터 변경 이력의 완전한 보존, 이벤트 재생을 통한 다양한 뷰 생성, 도메인 이벤트의 명시적 표현이고, 단점은 이벤트 스키마 변경 관리의 복잡성과 쿼리 성능 문제입니다. 금융 거래, 주문 처리, 협업 도구 등 이력 추적이 중요한 도메인에 적합합니다. TypeScript 구현 시 이벤트 타입을 유니온 타입으로 정의하고 버전 필드를 포함시키며, 이벤트가 많아지면 주기적으로 현재 상태의 스냅샷을 저장하여 재생 성능을 최적화합니다.

핵심 포인트
  • • 이벤트 소싱의 개념과 CRUD 방식과의 차이점
  • • 장단점 및 적합한 도메인 시나리오
  • • 이벤트 버전 관리와 스냅샷 최적화 전략
Follow-up 질문

CQRS(Command Query Responsibility Segregation) 패턴과 이벤트 소싱을 함께 사용할 때의 시너지 효과와 Read Model 동기화 전략을 설명해주세요.

4 트러블슈팅
Medium

Q. TypeScript 프로젝트에서 순환 의존성(Circular Dependency) 문제가 발생하는 원인과 런타임 에러로 이어지는 과정을 설명하고, 이를 탐지하고 해결하기 위한 방법들(import 순서 조정, 배럴 파일 문제, 의존성 역전 원칙 등)을 실무 관점에서 설명해주세요.

A. 모범답안

순환 의존성은 모듈 A가 B를 import하고 B가 다시 A를 import할 때 발생하며, CommonJS에서는 부분적으로 초기화된 모듈이 반환되어 undefined 참조 에러가 발생할 수 있습니다. ES Module에서는 호이스팅으로 일부 완화되지만 여전히 문제가 될 수 있습니다. 탐지 방법으로는 madge, dpdm 같은 도구를 사용하거나 ESLint의 import/no-cycle 규칙을 활성화할 수 있습니다. 해결 방법은 공통 의존성을 별도 모듈로 추출하기, 배럴 파일(index.ts)에서 재export하는 구조 피하기, 의존성 역전 원칙(DIP)을 적용해 인터페이스에 의존하도록 리팩토링하기, 지연 import(동적 import)를 사용하는 것 등이 있습니다.

핵심 포인트
  • • 순환 의존성이 런타임 에러로 이어지는 메커니즘
  • • 탐지 도구 및 정적 분석 방법
  • • 의존성 역전 원칙 등 구조적 해결 방법
Follow-up 질문

NestJS나 Angular 같은 프레임워크에서 의존성 주입(DI) 컨테이너가 순환 의존성 문제를 어떻게 해결하는지 설명해주세요.

5 코드 리뷰
Medium

Q. TypeScript에서 타입 가드(Type Guard)를 구현하는 여러 방법(typeof, instanceof, in 연산자, 사용자 정의 타입 가드)을 설명하고, 각각의 사용 사례와 한계점을 설명해주세요. 특히 사용자 정의 타입 가드에서 is 키워드의 역할과 잘못 구현했을 때 발생할 수 있는 타입 안정성 문제를 설명해주세요.

A. 모범답안

typeof는 원시 타입 검사에, instanceof는 클래스 인스턴스 검사에, in 연산자는 객체의 속성 존재 여부 검사에 사용됩니다. 사용자 정의 타입 가드는 'parameterName is Type' 형태로 정의하며, 복잡한 조건이나 API 응답 검증에 유용합니다. is 키워드는 함수가 true를 반환할 때 해당 매개변수의 타입을 좁혀주는 역할을 하지만, 런타임 검증 로직이 불완전하면 컴파일러는 타입이 보장된 것으로 믿지만 실제로는 다른 타입이 들어올 수 있어 런타임 에러가 발생합니다. 따라서 타입 가드 내부에서 모든 필수 속성을 철저히 검증해야 하며, zod나 io-ts 같은 런타임 검증 라이브러리를 사용하면 더 안전합니다.

핵심 포인트
  • • 타입 가드의 종류별 사용 사례와 한계
  • • 사용자 정의 타입 가드의 is 키워드 역할
  • • 불완전한 타입 가드 구현이 초래하는 타입 안정성 문제
Follow-up 질문

discriminated union 패턴을 사용한 타입 좁히기와 exhaustive check를 통해 모든 케이스를 처리했는지 컴파일 타임에 검증하는 방법을 설명해주세요.

댓글 0

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

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