JavaScript 시니어 CS 기초 기술면접
새 면접Q. B-Tree와 B+Tree의 구조적 차이를 설명하고, 데이터베이스 인덱스에서 B+Tree가 선호되는 이유를 설명해주세요. 또한 JavaScript로 대용량 데이터를 다룰 때 메모리 효율적인 인덱싱 구조를 설계한다면 어떤 자료구조를 선택하고 어떻게 구현할지 제시해주세요.
B-Tree는 모든 노드에 데이터를 저장하지만, B+Tree는 리프 노드에만 데이터를 저장하고 내부 노드는 인덱스만 가집니다. B+Tree는 리프 노드가 연결 리스트로 연결되어 있어 범위 검색(range query)에 유리하고, 내부 노드가 더 많은 키를 저장할 수 있어 트리 높이가 낮아져 디스크 I/O가 감소합니다. JavaScript에서는 대용량 데이터 처리 시 IndexedDB의 B+Tree 인덱스를 활용하거나, 메모리 제약이 있다면 Skip List나 Trie 구조를 고려할 수 있으며, 페이지네이션과 lazy loading을 결합한 가상화 전략을 사용해야 합니다.
- • B+Tree는 리프 노드에만 데이터 저장, 내부 노드는 인덱스만 보유
- • 리프 노드 간 연결 리스트 구조로 범위 검색 성능 우수
- • 디스크 기반 DB에서 캐시 효율성과 순차 접근 성능이 뛰어남
- • JavaScript에서는 IndexedDB 활용 또는 Skip List 같은 대안 고려
만약 실시간으로 데이터가 계속 추가되는 로그 시스템을 JavaScript로 구현한다면, LSM-Tree(Log-Structured Merge-Tree) 같은 쓰기 최적화 자료구조를 어떻게 적용할 수 있을까요?
Q. 동적 계획법(Dynamic Programming)과 메모이제이션(Memoization)의 차이를 설명하고, JavaScript의 클로저와 WeakMap을 활용한 메모이제이션 구현 시 메모리 누수를 방지하는 전략을 제시해주세요. 또한 대규모 재귀 연산에서 콜스택 오버플로우를 방지하기 위한 trampolining 기법도 함께 설명해주세요.
동적 계획법은 bottom-up 방식으로 작은 문제부터 해결하여 테이블을 채우는 반면, 메모이제이션은 top-down 방식으로 필요한 경우에만 계산하고 캐싱합니다. JavaScript에서 WeakMap을 사용하면 객체 키가 더 이상 참조되지 않을 때 자동으로 가비지 컬렉션되어 메모리 누수를 방지할 수 있습니다. Trampolining은 재귀 함수를 반복문으로 변환하여 thunk를 반환하고, 외부 루프에서 실행함으로써 콜스택을 평탄화하는 기법입니다. 대규모 시스템에서는 LRU 캐시를 구현하여 메모리 사용량을 제한하고, 필요시 Worker Thread로 연산을 분산할 수 있습니다.
- • DP는 bottom-up 테이블 방식, 메모이제이션은 top-down 캐싱 방식
- • WeakMap 사용으로 참조가 없어진 캐시 자동 정리
- • Trampolining으로 재귀를 반복문으로 변환하여 스택 오버플로우 방지
- • LRU 캐시와 Worker Thread 활용으로 대규모 연산 최적화
피보나치 수열 계산을 메모이제이션으로 최적화할 때, 수백만 번의 호출이 발생하는 상황에서 캐시 크기를 제한하고 LRU 정책을 적용하는 구현 전략을 설명해주세요.
Q. HTTP/1.1, HTTP/2, HTTP/3(QUIC)의 핵심 차이점을 설명하고, 각 프로토콜에서 발생하는 성능 병목 현상(Head-of-Line Blocking, TCP 3-way handshake 등)과 해결 방식을 비교해주세요. 또한 Node.js 서버에서 HTTP/2를 도입할 때 고려해야 할 Server Push, Multiplexing의 실무적 장단점과 최적화 전략을 제시해주세요.
HTTP/1.1은 연결당 하나의 요청만 처리하여 HOL blocking이 발생하고, HTTP/2는 멀티플렉싱으로 하나의 TCP 연결에서 여러 스트림을 병렬 처리하지만 TCP 레벨의 HOL blocking은 여전히 존재합니다. HTTP/3는 UDP 기반 QUIC 프로토콜을 사용하여 스트림 독립성을 보장하고 0-RTT 연결로 지연을 줄입니다. Node.js에서 HTTP/2 Server Push는 클라이언트가 요청하기 전에 리소스를 전송할 수 있지만, 캐시 상태를 모르면 불필요한 데이터 전송이 발생할 수 있어 신중한 사용이 필요하며, 멀티플렉싱은 우선순위 설정과 흐름 제어를 통해 최적화해야 합니다.
- • HTTP/2는 멀티플렉싱으로 연결 재사용, 하지만 TCP HOL blocking 존재
- • HTTP/3(QUIC)는 UDP 기반으로 스트림 독립성과 0-RTT 연결 제공
- • Server Push는 캐시 상태 미인지로 인한 낭비 가능성 있음
- • 우선순위 설정과 흐름 제어로 멀티플렉싱 성능 최적화 필요
대규모 CDN 환경에서 HTTP/3 도입 시 UDP 패킷 손실률이 높은 모바일 네트워크 환경에서의 성능 저하를 어떻게 모니터링하고 대응할 수 있을까요?
Q. 프로세스와 스레드의 차이를 메모리 구조 관점에서 설명하고, 컨텍스트 스위칭(Context Switching) 비용이 프로세스와 스레드에서 어떻게 다른지 설명해주세요. 또한 Node.js의 단일 스레드 모델에서 libuv의 스레드 풀이 어떻게 동작하며, 스레드 풀 크기(UV_THREADPOOL_SIZE)를 조정할 때 고려해야 할 시스템 리소스와 성능 트레이드오프를 제시해주세요.
프로세스는 독립적인 메모리 공간(code, data, heap, stack)을 가지지만, 스레드는 같은 프로세스 내에서 code, data, heap을 공유하고 stack만 독립적으로 가집니다. 컨텍스트 스위칭 시 프로세스는 메모리 맵, 페이지 테이블 등을 교체해야 하지만, 스레드는 레지스터와 스택만 교체하면 되어 훨씬 빠릅니다. Node.js의 libuv 스레드 풀은 기본 4개 스레드로 파일 I/O, DNS 조회, crypto 등 블로킹 작업을 처리하며, UV_THREADPOOL_SIZE를 늘리면 동시 처리량은 증가하지만 CPU 코어 수를 초과하면 컨텍스트 스위칭 오버헤드가 증가하고, 메모리 사용량도 증가하므로 CPU 코어 수와 작업 특성을 고려한 벤치마킹이 필요합니다.
- • 프로세스는 독립 메모리, 스레드는 메모리 공유로 컨텍스트 스위칭 비용 차이
- • 스레드 전환은 레지스터/스택만 교체, 프로세스는 메모리 맵 전체 교체
- • libuv 스레드 풀은 블로킹 작업 처리, 기본 4개 스레드
- • 스레드 풀 크기는 CPU 코어 수와 작업 특성 고려하여 벤치마킹 후 결정
CPU 바운드 작업이 많은 Node.js 애플리케이션에서 Worker Threads와 libuv 스레드 풀의 역할 분담을 어떻게 설계하고, 각각의 적절한 크기를 결정하는 기준을 제시해주세요.
Q. 데이터베이스 트랜잭션의 ACID 속성을 각각 설명하고, 분산 시스템에서 CAP 정리(Consistency, Availability, Partition Tolerance)와의 관계를 설명해주세요. 또한 Node.js에서 PostgreSQL과 MongoDB를 함께 사용하는 폴리글랏 퍼시스턴스 아키텍처에서 트랜잭션 일관성을 보장하기 위한 Saga 패턴과 2PC(Two-Phase Commit)의 차이점 및 각각의 적용 시나리오를 제시해주세요.
ACID는 Atomicity(원자성), Consistency(일관성), Isolation(격리성), Durability(지속성)을 의미하며, CAP 정리에서는 분산 시스템이 일관성, 가용성, 분할 내성 중 최대 2개만 만족할 수 있다고 합니다. 2PC는 코디네이터가 모든 참여자에게 prepare와 commit을 순차적으로 요청하여 강한 일관성을 보장하지만, 블로킹 프로토콜이라 코디네이터 장애 시 전체 시스템이 대기 상태가 될 수 있습니다. Saga 패턴은 각 서비스가 로컬 트랜잭션을 실행하고 실패 시 보상 트랜잭션으로 롤백하는 방식으로 최종 일관성(eventual consistency)을 제공하며, 분산 마이크로서비스 환경에서 더 적합합니다. PostgreSQL과 MongoDB를 함께 사용할 때는 Saga 패턴으로 각 DB의 로컬 트랜잭션을 관리하고, 이벤트 소싱이나 메시지 큐를 통해 보상 로직을 구현하는 것이 실용적입니다.
- • ACID는 단일 DB 트랜잭션 보장, CAP는 분산 시스템 트레이드오프
- • 2PC는 강한 일관성 제공하지만 블로킹 프로토콜로 가용성 저하
- • Saga 패턴은 보상 트랜잭션으로 최종 일관성 제공, 마이크로서비스에 적합
- • 폴리글랏 환경에서는 Saga + 이벤트 소싱/메시지 큐 조합 권장
주문-결제-재고 시스템에서 Saga 패턴을 적용할 때 Orchestration 방식과 Choreography 방식의 차이를 설명하고, 각각 어떤 상황에서 선택해야 하는지 제시해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!