자료구조/알고리즘 리드·아키텍트 성능 최적화 면접

자료구조/알고리즘 리드 · 아키텍트 (10년+) 성능 최적화 10문항 조회수 22 · 2026-08-28 (금) 17:42:18
1 메모리 최적화
Hard

Q. 10TB 크기의 로그 파일에서 가장 빈번하게 등장하는 상위 1000개의 IP 주소를 찾아야 합니다. 서버 메모리는 16GB로 제한되어 있습니다. 어떤 알고리즘과 자료구조를 조합하여 이 문제를 해결하시겠습니까? 시간 복잡도와 공간 복잡도 측면에서 설명해주세요.

파일을 여러 번 순회하는 다단계 접근법과 외부 정렬 개념을 고려해보세요.

A. 모범답안

먼저 해시 함수를 사용해 로그 파일을 IP 주소 기준으로 1000개의 작은 파일로 분할합니다(External Hashing). 각 파일은 약 10GB로 메모리에 적재 가능합니다. 각 분할 파일마다 HashMap으로 IP별 빈도를 카운팅하고, Min Heap(크기 1000)을 유지하며 상위 1000개를 추출합니다. 마지막으로 1000개 파일에서 얻은 결과를 병합하여 최종 상위 1000개를 선정합니다. 시간 복잡도는 O(N + K*M*logM)이며(N=전체 레코드, K=파일 수, M=힙 크기), 공간 복잡도는 O(M)로 메모리 제약을 만족합니다. 실무에서는 MapReduce 패러다임으로 분산 처리하여 처리 시간을 단축할 수 있습니다.

핵심 포인트
  • • External Hashing을 통한 파일 분할로 메모리 제약 해결
  • • HashMap과 Min Heap 조합으로 각 파티션의 Top-K 추출
  • • 다단계 병합으로 최종 결과 도출 및 분산 처리 가능성
답변에 넣으면 좋은 키워드
External Hashing Min Heap Top-K MapReduce 공간 복잡도 파티셔닝
실무에서는

대용량 로그 분석, 검색 엔진의 빈도 분석, 이상 탐지 시스템에서 메모리 제약 하의 집계 작업에 활용됩니다.

Follow-up 질문

만약 IP 주소의 분포가 매우 불균등하여 특정 파티션이 메모리를 초과한다면 어떻게 대응하시겠습니까?

2 인덱스 최적화
Hard

Q. 전자상거래 주문 테이블에 5억 건의 레코드가 있습니다. 사용자별 최근 주문 조회 쿼리가 느려져 인덱스 전략을 재설계해야 합니다. user_id, order_date, status 세 컬럼을 사용하는 복합 인덱스의 순서를 어떻게 결정하시겠습니까? 각 순서 조합의 성능 특성과 트레이드오프를 설명해주세요.

카디널리티, 쿼리 패턴, 인덱스 스캔 범위를 종합적으로 고려해야 합니다.

A. 모범답안

쿼리 패턴 분석이 최우선입니다. WHERE user_id = ? ORDER BY order_date DESC 형태라면 (user_id, order_date, status) 순서가 최적입니다. user_id로 먼저 필터링하여 범위를 좁히고, order_date로 정렬되어 있어 추가 정렬 비용이 없으며, status는 커버링 인덱스 효과를 제공합니다. (order_date, user_id) 순서는 날짜 범위 검색 시 유리하지만 사용자별 조회에는 인덱스 스캔 범위가 넓어집니다. 카디널리티가 높은 user_id를 선두에 두면 인덱스 분기가 효율적이고, 파티셔닝과 결합 시 파티션 프루닝 효과도 얻을 수 있습니다. 실제 쿼리 실행 계획과 통계를 확인하여 인덱스 힌트나 파티셔닝 전략을 함께 검토해야 합니다.

핵심 포인트
  • • 쿼리 패턴에 따른 인덱스 컬럼 순서 결정(필터 → 정렬 → 커버링)
  • • 카디널리티와 선택도를 고려한 선두 컬럼 선택
  • • 인덱스 스캔 범위 최소화와 파티셔닝 전략 통합
답변에 넣으면 좋은 키워드
복합 인덱스 카디널리티 커버링 인덱스 인덱스 스캔 파티션 프루닝 실행 계획
실무에서는

대용량 트랜잭션 테이블의 사용자별 조회 성능 개선 시 복합 인덱스 설계가 핵심입니다.

Follow-up 질문

status 컬럼의 카디널리티가 매우 낮다면(예: 3가지 값만 존재) 인덱스 설계를 어떻게 조정하시겠습니까?

3 동시성 제어
Hard

Q. 초당 50만 건의 쓰기와 200만 건의 읽기가 발생하는 재고 관리 시스템에서 동시성 문제로 재고 부족 상황이 발생하고 있습니다. Lock-based 접근과 Lock-free 자료구조 중 어떤 전략을 선택하시겠습니까? 각 방식의 성능 특성과 일관성 보장 수준을 비교 설명해주세요.

읽기와 쓰기 비율, 경합 수준, CAP 이론 관점에서 접근해보세요.

A. 모범답안

읽기가 쓰기보다 4배 많은 상황에서는 Optimistic Concurrency Control과 Lock-free 자료구조 조합이 유리합니다. CAS(Compare-And-Swap) 연산 기반의 AtomicInteger로 재고를 관리하고, 버전 번호를 활용한 낙관적 락으로 업데이트 충돌을 처리합니다. 비관적 락은 경합이 높을 때 대기 시간이 길어지지만, Lock-free 방식은 retry 오버헤드가 있어도 전체 처리량이 높습니다. 다만 ABA 문제와 메모리 순서 보장을 위해 Memory Barrier를 적절히 사용해야 합니다. 최종 일관성을 허용할 수 있다면 Read Replica와 Write-through Cache를 결합하여 읽기 성능을 더욱 향상시킬 수 있습니다. 재고 정합성이 중요하다면 분산 락(Redis, Zookeeper)과 이벤트 소싱 패턴을 고려합니다.

핵심 포인트
  • • 읽기 중심 워크로드에서 Lock-free 자료구조의 처리량 우위
  • • CAS 연산과 낙관적 락을 통한 동시성 제어
  • • 일관성 요구사항에 따른 분산 락 및 캐싱 전략 선택
답변에 넣으면 좋은 키워드
CAS Lock-free 낙관적 락 ABA 문제 Memory Barrier 최종 일관성
실무에서는

이커머스 플래시세일, 티켓팅 시스템에서 높은 동시성 하의 재고 정합성 보장이 필수입니다.

Follow-up 질문

재고가 음수로 가는 것을 절대 허용할 수 없는 강한 일관성이 필요하다면 아키텍처를 어떻게 변경하시겠습니까?

4 캐시 전략
Medium

Q. 상품 상세 페이지의 응답 시간을 개선하기 위해 다단계 캐싱 전략을 도입하려 합니다. CDN, Redis, Application Cache를 조합할 때 각 레이어의 TTL과 Eviction Policy를 어떻게 설계하시겠습니까? Cache Stampede 문제 해결 방안도 함께 설명해주세요.

데이터 변경 빈도, 캐시 히트율, 동시 요청 처리 관점에서 생각해보세요.

A. 모범답안

CDN은 정적 리소스와 변경이 드문 상품 기본 정보를 1시간 TTL로 캐싱하고, Redis는 실시간성이 필요한 재고/가격 정보를 5분 TTL로 관리합니다. Application Cache는 사용자 세션별 데이터를 LRU로 메모리에 유지합니다. Cache Stampede 방지를 위해 Probabilistic Early Expiration 기법을 적용하여 TTL 만료 전 일정 확률로 미리 갱신하고, Redis의 SETNX를 활용한 Lock 메커니즘으로 동시 갱신 요청을 직렬화합니다. 또한 Stale-While-Revalidate 패턴으로 만료된 캐시를 임시로 제공하면서 백그라운드에서 갱신합니다. 각 레이어별 모니터링을 통해 히트율과 지연시간을 추적하고 TTL을 동적으로 조정합니다.

핵심 포인트
  • • 데이터 특성에 따른 계층별 TTL 차별화
  • • Probabilistic Early Expiration과 분산 락으로 Cache Stampede 방지
  • • Stale-While-Revalidate 패턴으로 가용성과 성능 균형
답변에 넣으면 좋은 키워드
다단계 캐싱 TTL Cache Stampede Probabilistic Early Expiration SETNX Stale-While-Revalidate
실무에서는

대규모 이커머스의 상품 상세 페이지는 다단계 캐싱으로 DB 부하를 90% 이상 줄일 수 있습니다.

Follow-up 질문

상품 정보가 갑자기 변경되었을 때 모든 캐시 레이어를 즉시 무효화해야 한다면 어떤 전략을 사용하시겠습니까?

5 검색 최적화
Hard

Q. 1억 개의 문서를 대상으로 전문 검색(Full-text Search) 성능을 최적화해야 합니다. Inverted Index 구조에서 AND/OR 복합 쿼리 처리 시 성능을 높이기 위한 자료구조와 알고리즘을 설명하고, Skip List와 Bitmap Index의 활용 시나리오를 비교해주세요.

포스팅 리스트 병합 전략과 문서 빈도에 따른 최적화를 고려하세요.

A. 모범답안

Inverted Index의 포스팅 리스트는 정렬된 문서 ID 배열로 유지하며, AND 연산 시 가장 짧은 리스트를 기준으로 다른 리스트들과 병합합니다. Skip List를 사용하면 O(n) 순차 탐색을 O(log n)으로 개선하여 긴 포스팅 리스트를 건너뛸 수 있습니다. OR 연산은 Priority Queue를 사용한 K-way Merge로 처리합니다. 고빈도 용어(stopwords)는 Bitmap Index로 변환하여 비트 연산으로 빠르게 교집합/합집합을 계산합니다. 저빈도 용어는 압축된 포스팅 리스트로 유지하여 공간 효율성을 높입니다. WAND(Weak AND) 알고리즘을 적용하면 상위 K개 결과만 필요할 때 조기 종료로 성능을 크게 향상시킬 수 있습니다. 샤딩 전략으로 문서를 분산 저장하고 병렬 검색 후 결과를 병합합니다.

핵심 포인트
  • • Skip List로 포스팅 리스트 탐색 최적화 및 병합 전략
  • • Bitmap Index를 활용한 고빈도 용어의 비트 연산 처리
  • • WAND 알고리즘과 샤딩으로 Top-K 검색 성능 향상
답변에 넣으면 좋은 키워드
Inverted Index Skip List Bitmap Index WAND 포스팅 리스트 K-way Merge
실무에서는

검색 엔진, 로그 분석 플랫폼에서 수억 건의 문서를 밀리초 단위로 검색하는 핵심 기술입니다.

Follow-up 질문

실시간으로 문서가 추가/삭제되는 환경에서 인덱스 일관성을 유지하면서 검색 성능을 보장하려면 어떤 전략을 사용하시겠습니까?

6 네트워크 최적화
Medium

Q. 마이크로서비스 간 통신에서 latency가 평균 100ms인데 P99는 2초에 달합니다. 서킷 브레이커와 타임아웃 설정은 되어 있지만 여전히 긴 꼬리 지연(tail latency)이 발생합니다. Connection Pool 크기, Keep-Alive 설정, Hedged Request 패턴 관점에서 최적화 방안을 제시해주세요.

네트워크 레벨의 재사용과 요청 복제 전략을 함께 고려하세요.

A. 모범답안

먼저 Connection Pool 크기를 모니터링하여 대기 시간이 발생하는지 확인하고, 피크 트래픽의 1.5배로 설정합니다. HTTP Keep-Alive를 활성화하고 idle timeout을 60초로 설정하여 연결 재사용률을 높입니다. TCP_NODELAY 옵션으로 Nagle 알고리즘을 비활성화하여 작은 패킷의 지연을 줄입니다. Hedged Request 패턴을 도입하여 P95 지연시간 후 동일 요청을 다른 인스턴스로 병렬 전송하고 먼저 응답한 결과를 사용합니다. Adaptive Timeout을 구현하여 최근 응답 시간의 P99 기준으로 타임아웃을 동적 조정합니다. gRPC의 경우 Multiplexing을 활용하고, HTTP/2의 Stream Priority를 설정하여 중요한 요청의 우선순위를 높입니다.

핵심 포인트
  • • Connection Pool과 Keep-Alive 최적화로 연결 오버헤드 감소
  • • Hedged Request로 긴 꼬리 지연 완화
  • • Adaptive Timeout과 프로토콜 레벨 최적화
답변에 넣으면 좋은 키워드
Connection Pool Keep-Alive Hedged Request Tail Latency Adaptive Timeout HTTP/2
실무에서는

MSA 환경에서 서비스 간 통신 최적화는 전체 시스템 응답 시간의 핵심 요소입니다.

Follow-up 질문

Hedged Request가 백엔드 서버 부하를 증가시킨다면 어떻게 균형을 맞추시겠습니까?

7 메모리 관리
Hard

Q. Java 애플리케이션에서 Old Generation GC가 30초씩 발생하여 서비스가 멈춥니다. Heap Dump 분석 결과 대용량 HashMap이 원인으로 확인되었습니다. GC 튜닝과 자료구조 재설계 관점에서 어떻게 문제를 해결하시겠습니까? Off-heap 메모리 활용 방안도 함께 설명해주세요.

객체 생명주기와 메모리 배치 전략을 고려하세요.

A. 모범답안

먼저 G1GC의 Region 크기와 Heap 비율을 조정하여 Humongous Object 할당을 줄입니다. 대용량 HashMap을 Caffeine이나 Chronicle Map 같은 Off-heap 캐시로 전환하여 GC 대상에서 제외시킵니다. 데이터를 Weak Reference나 Soft Reference로 래핑하여 메모리 부족 시 자동 회수되도록 합니다. 객체 풀링을 도입하여 반복적으로 생성되는 객체의 할당 비용을 줄이고, Primitive 타입 특화 컬렉션(Trove, FastUtil)으로 Boxing 오버헤드를 제거합니다. 데이터가 시계열 특성이 있다면 시간 기반 파티셔닝으로 Old Generation 진입을 지연시킵니다. Shenandoah나 ZGC 같은 Low-latency GC로 전환을 검토하고, JVM 옵션으로 GC 로그를 상세히 수집하여 지속적으로 모니터링합니다.

핵심 포인트
  • • Off-heap 메모리로 대용량 데이터를 GC 대상에서 제외
  • • Primitive 특화 컬렉션과 객체 풀링으로 할당 압력 감소
  • • Low-latency GC 도입과 지속적인 모니터링
답변에 넣으면 좋은 키워드
Off-heap G1GC Humongous Object Weak Reference Chronicle Map ZGC
실무에서는

대용량 캐시를 사용하는 실시간 서비스에서 GC 튜닝은 안정적인 응답 시간 보장의 핵심입니다.

Follow-up 질문

Off-heap 메모리 사용 시 메모리 누수를 어떻게 탐지하고 관리하시겠습니까?

8 부하 분산
Hard

Q. 특정 사용자의 요청이 집중되어 일부 서버에만 부하가 몰리는 Hot Spot 문제가 발생했습니다. Consistent Hashing을 사용 중인데도 불균형이 심합니다. Virtual Node 개수 조정, Bounded Load 알고리즘, Request Hedging 중 어떤 전략을 선택하시겠습니까? 각각의 트레이드오프를 설명해주세요.

데이터 분포 특성과 실시간 부하 상태를 함께 고려해야 합니다.

A. 모범답안

먼저 Virtual Node 개수를 128에서 512로 증가시켜 해시 링의 분포를 균등하게 만듭니다. 하지만 이것만으로는 Hot Key 문제를 해결할 수 없으므로 Bounded Load 알고리즘을 도입합니다. 각 서버의 현재 부하를 추적하여 평균 부하의 1.25배를 초과하면 다음 서버로 라우팅합니다. Power of Two Choices 전략을 결합하여 두 개의 후보 서버 중 부하가 낮은 쪽을 선택합니다. Hot Key는 클라이언트 사이드에서 Local Cache로 처리하거나, 서버에서 Key Splitting 기법으로 여러 복제본을 만들어 부하를 분산시킵니다. Request Hedging은 읽기 전용 워크로드에만 제한적으로 적용하여 쓰기 중복을 방지합니다. 실시간 메트릭 기반의 Adaptive Load Balancing으로 동적으로 가중치를 조정합니다.

핵심 포인트
  • • Virtual Node 증가와 Bounded Load로 균등 분산 보장
  • • Power of Two Choices와 Hot Key 처리 전략 조합
  • • 실시간 메트릭 기반 동적 부하 분산
답변에 넣으면 좋은 키워드
Consistent Hashing Virtual Node Bounded Load Power of Two Choices Hot Key Adaptive Load Balancing
실무에서는

분산 캐시, 샤딩된 데이터베이스에서 Hot Spot 문제는 전체 시스템 성능 저하의 주요 원인입니다.

Follow-up 질문

서버를 추가하거나 제거할 때 최소한의 데이터 이동으로 리밸런싱하려면 어떤 전략을 사용하시겠습니까?

9 압축 알고리즘
Medium

Q. 로그 수집 시스템에서 네트워크 전송량을 줄이기 위해 압축을 도입하려 합니다. Gzip, Snappy, LZ4, Zstandard 중에서 선택해야 하는데, 압축률과 CPU 사용량의 트레이드오프를 어떻게 평가하시겠습니까? 실시간 스트리밍과 배치 처리 시나리오를 구분하여 설명해주세요.

압축 속도, 압축률, CPU 오버헤드를 시나리오별로 우선순위를 정하세요.

A. 모범답안

실시간 스트리밍에서는 지연시간이 중요하므로 LZ4나 Snappy를 선택합니다. LZ4는 압축 속도가 500MB/s 이상으로 CPU 오버헤드가 낮고 압축률은 2~3배 수준입니다. 배치 처리에서는 네트워크 비용 절감이 우선이므로 Zstandard나 Gzip을 사용하여 5~10배 압축률을 달성합니다. Kafka 같은 메시지 큐에서는 Producer에서 압축하고 Consumer에서 해제하는데, Snappy가 CPU와 압축률의 균형이 좋아 많이 사용됩니다. 로그 데이터의 반복 패턴이 많다면 Dictionary 기반 압축인 Zstandard가 유리하며, 사전 학습을 통해 압축률을 더욱 높일 수 있습니다. 벤치마크로 실제 데이터 샘플의 압축률, 처리량, CPU 사용률을 측정하여 비용 모델을 수립합니다.

핵심 포인트
  • • 실시간 처리는 LZ4/Snappy로 지연시간 최소화
  • • 배치 처리는 Zstandard/Gzip으로 압축률 극대화
  • • 실제 데이터 기반 벤치마크로 비용 모델 수립
답변에 넣으면 좋은 키워드
LZ4 Snappy Zstandard 압축률 지연시간 Dictionary 압축
실무에서는

대규모 로그 수집 시스템에서 압축은 네트워크와 스토리지 비용을 50% 이상 절감할 수 있습니다.

Follow-up 질문

압축된 로그 파일을 직접 검색해야 한다면 어떤 인덱싱 전략을 사용하시겠습니까?

10 배치 처리 최적화
Hard

Q. 매일 밤 1TB의 데이터를 처리하는 배치 작업이 6시간에서 12시간으로 늘어나 다음 날 서비스 시작 전에 완료되지 않습니다. 데이터 증가율은 월 20%입니다. 병렬 처리, 증분 처리, 알고리즘 최적화 관점에서 장기적인 확장 전략을 수립해주세요.

단순 리소스 증설이 아닌 구조적 개선 방안을 고려하세요.

A. 모범답안

먼저 전체 스캔을 증분 처리로 전환하여 변경된 데이터만 처리합니다. Change Data Capture나 타임스탬프 기반 파티셔닝으로 처리 대상을 90% 줄일 수 있습니다. 데이터를 독립적인 청크로 분할하고 Spark나 Flink로 병렬 처리하여 선형 확장성을 확보합니다. 알고리즘 복잡도를 개선하여 O(N²)를 O(N log N)으로 줄이고, 불필요한 조인과 집계를 제거합니다. Columnar Storage(Parquet, ORC)로 전환하여 필요한 컬럼만 읽어 I/O를 70% 감소시킵니다. Predicate Pushdown과 Partition Pruning으로 스캔 범위를 최소화합니다. 중간 결과를 Materialized View로 저장하여 재계산을 방지하고, Lambda Architecture로 실시간 레이어와 배치 레이어를 분리하여 부하를 분산합니다. 처리 시간을 모니터링하여 임계값 도달 시 자동으로 리소스를 스케일 아웃합니다.

핵심 포인트
  • • 증분 처리와 CDC로 처리 대상 데이터 최소화
  • • 병렬 처리와 Columnar Storage로 I/O 최적화
  • • 알고리즘 개선과 Lambda Architecture로 구조적 확장성 확보
답변에 넣으면 좋은 키워드
증분 처리 CDC Columnar Storage Predicate Pushdown Lambda Architecture Materialized View
실무에서는

데이터 웨어하우스의 ETL 작업에서 증분 처리와 병렬화는 처리 시간을 10배 이상 단축시킬 수 있습니다.

Follow-up 질문

배치 작업 중 일부가 실패했을 때 전체를 재실행하지 않고 실패 지점부터 재개하려면 어떤 설계가 필요합니까?

댓글 0

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

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