JavaScript 미드레벨 CS 기초 면접
새 면접Q. 해시 테이블의 충돌(Collision) 해결 방법인 체이닝(Chaining)과 개방 주소법(Open Addressing)의 동작 원리를 각각 설명하고, 각 방식의 장단점을 메모리 사용량과 캐시 지역성(Cache Locality) 관점에서 비교해주세요. 또한 JavaScript의 Map이나 Object가 내부적으로 어떤 방식을 사용하는지 알고 있다면 설명해주세요.
체이닝은 연결 리스트를 사용하고, 개방 주소법은 다른 빈 슬롯을 찾는 방식입니다. 메모리 할당 패턴과 CPU 캐시 효율성을 생각해보세요.
체이닝은 충돌 발생 시 같은 해시 값을 가진 요소들을 연결 리스트로 관리하는 방식으로, 구현이 간단하고 해시 테이블의 로드 팩터가 1을 초과해도 동작하지만 추가 메모리가 필요하고 포인터 참조로 인해 캐시 지역성이 낮습니다. 개방 주소법은 충돌 시 선형 탐사, 이차 탐사, 이중 해싱 등으로 다음 빈 슬롯을 찾는 방식으로, 메모리를 연속적으로 사용해 캐시 효율이 높지만 로드 팩터가 높아지면 성능이 급격히 저하되고 삭제 연산이 복잡합니다. JavaScript의 V8 엔진은 Object의 경우 히든 클래스와 인라인 캐싱을 사용하며, Map은 해시 테이블 기반이지만 구체적인 충돌 해결 방식은 엔진 구현에 따라 다릅니다. 실무에서는 데이터 크기와 접근 패턴에 따라 적절한 자료구조를 선택해야 하며, 빈번한 삽입/삭제가 있다면 체이닝이, 읽기 위주라면 개방 주소법이 유리할 수 있습니다.
- • 체이닝은 연결 리스트로 충돌 관리, 개방 주소법은 다른 빈 슬롯 탐색
- • 체이닝은 메모리 오버헤드가 있지만 로드 팩터 제약이 적음
- • 개방 주소법은 캐시 지역성이 높지만 로드 팩터에 민감함
- • V8 엔진의 구현 방식은 최적화 전략에 따라 다름
대용량 데이터 캐싱 시스템이나 인메모리 데이터베이스에서 적절한 해시 테이블 구현 방식을 선택하는 것이 성능에 직접적인 영향을 미칩니다.
로드 팩터가 0.75를 초과하면 해시 테이블을 리사이징하는 것이 일반적인데, 리사이징 과정에서 발생하는 성능 문제를 어떻게 완화할 수 있을까요?
Q. TCP의 흐름 제어(Flow Control)와 혼잡 제어(Congestion Control)의 차이점을 설명하고, 각각이 해결하려는 문제와 사용하는 메커니즘을 비교해주세요. 또한 TCP의 슬라이딩 윈도우(Sliding Window) 프로토콜이 어떻게 동작하는지 설명하고, 실무에서 Node.js 서버의 TCP 소켓 옵션을 튜닝할 때 고려해야 할 사항을 제시해주세요.
흐름 제어는 수신자 중심, 혼잡 제어는 네트워크 중심 문제입니다. 윈도우 크기 조정 방식의 차이를 생각해보세요.
흐름 제어는 송신자가 수신자의 처리 능력을 초과하여 데이터를 보내지 않도록 하는 메커니즘으로, 수신자가 광고하는 윈도우 크기(rwnd)를 통해 조절됩니다. 혼잡 제어는 네트워크의 혼잡 상태를 감지하고 전송률을 조정하여 패킷 손실을 방지하는 메커니즘으로, Slow Start, Congestion Avoidance, Fast Retransmit, Fast Recovery 등의 알고리즘을 사용하며 혼잡 윈도우(cwnd)로 제어됩니다. 슬라이딩 윈도우는 ACK를 받지 않고도 여러 패킷을 연속으로 전송할 수 있게 하여 파이프라이닝을 구현하며, 실제 전송 가능한 데이터양은 rwnd와 cwnd 중 작은 값으로 결정됩니다. Node.js에서는 SO_RCVBUF, SO_SNDBUF 같은 소켓 버퍼 크기, TCP_NODELAY(Nagle 알고리즘 비활성화), keepalive 설정 등을 조정할 수 있으며, 특히 고대역폭-고지연 네트워크에서는 윈도우 스케일링 옵션이 중요합니다.
- • 흐름 제어는 수신자 버퍼 오버플로 방지, 혼잡 제어는 네트워크 혼잡 방지
- • 흐름 제어는 rwnd 사용, 혼잡 제어는 cwnd와 알고리즘 조합 사용
- • 슬라이딩 윈도우는 ACK 대기 없이 연속 전송을 가능하게 함
- • 실무에서는 네트워크 환경에 맞춰 소켓 옵션 튜닝 필요
실시간 스트리밍 서비스나 대용량 파일 전송 API에서 TCP 파라미터를 적절히 조정하면 처리량과 지연시간을 크게 개선할 수 있습니다.
HTTP/2나 HTTP/3에서는 TCP의 Head-of-Line Blocking 문제를 어떻게 해결하려고 했으며, 특히 HTTP/3가 QUIC 프로토콜을 사용하는 이유는 무엇인가요?
Q. 대규모 로그 데이터에서 상위 K개의 빈도수가 높은 항목을 찾는 문제(Top K Frequent Elements)를 해결하는 여러 알고리즘 접근법을 비교 설명해주세요. 특히 HashMap + Heap 방식과 QuickSelect 기반 방식의 시간복잡도와 공간복잡도를 분석하고, 데이터가 메모리에 모두 들어가지 않는 스트리밍 환경에서는 어떤 근사 알고리즘(Count-Min Sketch, Lossy Counting 등)을 사용할 수 있는지 설명해주세요.
정확한 해를 구하는 방법과 메모리 제약이 있을 때의 근사 해법을 구분해서 생각해보세요. 힙의 크기를 K로 유지하는 것이 핵심입니다.
HashMap + Min Heap 방식은 먼저 모든 요소의 빈도수를 HashMap으로 계산(O(N))한 후, 크기 K인 Min Heap을 유지하며 빈도수가 높은 K개를 선택하는 방식으로 시간복잡도 O(N + M log K), 공간복잡도 O(M + K)입니다(N은 전체 요소 수, M은 유니크 요소 수). QuickSelect 기반 방식은 빈도수 배열을 만든 후 Partition 알고리즘으로 K번째 요소를 찾는 방식으로 평균 O(N + M), 최악 O(N + M²)의 시간복잡도를 가지며 추가 정렬이 필요 없습니다. 스트리밍 환경에서는 Count-Min Sketch가 해시 함수 배열과 카운터 행렬로 빈도를 근사 추정하며 O(1) 업데이트와 O(log 1/δ) 공간을 사용하고, Lossy Counting은 에러 파라미터 ε를 기반으로 빈도가 낮은 항목을 주기적으로 제거하여 메모리를 절약합니다. 실무에서는 정확도 요구사항과 메모리 제약에 따라 적절한 알고리즘을 선택해야 하며, 실시간 분석 대시보드에서는 근사 알고리즘이 필수적입니다.
- • HashMap + Min Heap은 O(N log K)로 정확한 Top K 추출 가능
- • QuickSelect는 평균적으로 더 빠르지만 최악의 경우 성능 저하
- • 스트리밍 환경에서는 Count-Min Sketch, Lossy Counting 같은 근사 알고리즘 필요
- • 정확도와 메모리 트레이드오프 고려 필수
실시간 로그 분석 시스템, 검색어 자동완성, 실시간 트렌드 분석 등에서 제한된 메모리로 빈도수 높은 항목을 빠르게 찾아야 할 때 사용됩니다.
실시간 트렌딩 토픽을 찾는 시스템에서 시간 윈도우(예: 최근 1시간)를 적용하려면 알고리즘을 어떻게 수정해야 할까요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!