Elixir 시니어 기술면접

Elixir 시니어 (7년+) 코딩 · 알고리즘 3문항 조회수 30 · 2026-08-04 (화) 12:33:40
1 동시성 알고리즘
Hard

Q. 수백만 개의 HTTP 요청을 동시에 처리해야 하는 API 게이트웨이를 Elixir로 구현한다고 가정합니다. Rate limiting을 구현할 때 Token Bucket 알고리즘을 GenServer로 구현하는 접근법과, ETS 기반으로 구현하는 접근법의 시간/공간 복잡도를 비교하고, 각각의 트레이드오프를 설명해주세요.

프로세스 간 메시지 전달 비용과 공유 메모리 접근 패턴의 차이를 생각해보세요.

A. 모범답안

GenServer 기반 구현은 단일 프로세스가 모든 요청을 순차 처리하므로 O(1) 시간복잡도지만 메시지 큐 대기로 인한 레이턴시가 발생합니다. 공간복잡도는 O(n)으로 사용자별 상태를 프로세스 상태로 관리합니다. ETS 기반 구현은 동시 읽기/쓰기가 가능해 처리량이 높지만, :ets.update_counter의 원자적 연산을 활용해도 경합 상황에서 재시도 오버헤드가 있습니다. 공간복잡도는 동일하게 O(n)이지만 ETS 테이블의 메모리 오버헤드가 추가됩니다. 수백만 동시 사용자 환경에서는 ETS의 병렬 처리 이점이 크지만, 정확한 rate limiting이 필요하면 GenServer의 순차 처리가 더 안전합니다. 하이브리드 접근으로 사용자를 해시 기반 샤딩해 여러 GenServer로 분산하면 두 장점을 결합할 수 있습니다.

핵심 포인트
  • • GenServer는 순차 처리로 정확성은 높지만 병목 발생 가능
  • • ETS는 동시 접근으로 처리량이 높지만 경합 상황 처리 필요
  • • 샤딩을 통한 하이브리드 접근으로 확장성과 정확성 동시 확보
답변에 넣으면 좋은 키워드
Token Bucket GenServer ETS 원자적 연산 샤딩 메시지 큐 병렬 처리
실무에서는

대규모 API 서비스에서 사용자별 요청 제한을 구현할 때 처리량과 정확성의 균형을 맞추는 아키텍처 결정에 활용됩니다.

Follow-up 질문

만약 분산 환경에서 여러 노드에 걸쳐 global rate limiting을 구현해야 한다면 어떤 접근법을 사용하시겠습니까?

2 분산 시스템 알고리즘
Hard

Q. Elixir 클러스터 환경에서 분산 락(Distributed Lock)을 구현해야 합니다. :global 모듈을 사용하는 방법과 Raft/Paxos 같은 합의 알고리즘 기반 라이브러리를 사용하는 방법의 알고리즘적 차이를 설명하고, 네트워크 파티션 상황에서 각각의 동작 방식과 CAP 이론 관점에서의 트레이드오프를 분석해주세요.

split-brain 시나리오에서 일관성과 가용성 중 무엇을 우선하는지 생각해보세요.

A. 모범답안

:global 모듈은 전체 노드 합의 기반으로 동작하며 네트워크 파티션 발생 시 양쪽 파티션에서 각각 락을 획득할 수 있는 split-brain 문제가 발생합니다. 이는 CAP 이론에서 AP(Availability-Partition tolerance)를 선택한 것으로, 가용성을 우선하지만 일관성을 보장하지 못합니다. Raft 기반 구현은 과반수 쿼럼을 요구하므로 파티션 상황에서 majority를 가진 쪽만 락을 획득할 수 있어 CP(Consistency-Partition tolerance)를 보장합니다. 시간복잡도 측면에서 :global은 O(n) 노드 통신이 필요하고, Raft는 O(log n)의 리더 선출 후 O(1)의 리더 통신으로 더 효율적입니다. 금융 거래처럼 정확성이 중요한 경우 Raft를, 일시적 중복이 허용되는 캐시 갱신 같은 경우 :global을 선택하는 것이 적절합니다.

핵심 포인트
  • • :global은 AP를 선택해 split-brain 문제 발생 가능
  • • Raft/Paxos는 CP를 선택해 과반수 쿼럼으로 일관성 보장
  • • 비즈니스 요구사항에 따라 일관성과 가용성 중 우선순위 결정 필요
답변에 넣으면 좋은 키워드
분산 락 CAP 이론 split-brain Raft 쿼럼 :global 네트워크 파티션
실무에서는

멀티 리전 배포 환경에서 중요한 리소스에 대한 동시 접근을 제어할 때 데이터 일관성을 보장하는 아키텍처 설계에 활용됩니다.

Follow-up 질문

Raft 기반 락 구현에서 리더 노드가 다운되었을 때 락의 안전성을 어떻게 보장할 수 있을까요?

3 스트림 처리 알고리즘
Medium

Q. 대용량 로그 파일(수십 GB)에서 특정 패턴을 찾아 변환 후 저장하는 ETL 파이프라인을 Elixir로 구현할 때, File.read와 File.stream, 그리고 Flow 라이브러리를 각각 사용하는 접근법의 메모리 사용량과 처리 속도를 비교 분석하고, 각 방식의 시간/공간 복잡도를 설명해주세요.

메모리에 전체 데이터를 로드하는 방식과 청크 단위 스트리밍의 차이를 고려하세요.

A. 모범답안

File.read는 전체 파일을 메모리에 로드하므로 공간복잡도가 O(n)이며 파일 크기만큼 메모리를 사용합니다. 수십 GB 파일에서는 메모리 부족으로 실패할 수 있습니다. File.stream은 lazy evaluation으로 청크 단위 처리하므로 공간복잡도가 O(1)(청크 크기)로 메모리 효율적이지만, 단일 프로세스로 순차 처리해 시간복잡도는 O(n)입니다. Flow는 File.stream 위에 병렬 처리를 추가해 여러 코어를 활용하므로, p개 코어 사용 시 이론적으로 O(n/p) 시간복잡도를 달성하며 공간복잡도는 O(p)로 각 워커의 버퍼만 유지합니다. 실무에서는 CPU 바운드 작업(정규식 매칭, 변환)이 많으면 Flow가, IO 바운드 작업이 주를 이루면 File.stream만으로도 충분합니다.

핵심 포인트
  • • File.read는 O(n) 메모리로 대용량 파일에 부적합
  • • File.stream은 O(1) 메모리로 효율적이나 순차 처리
  • • Flow는 병렬 처리로 시간복잡도 개선하되 워커 수만큼 메모리 사용
답변에 넣으면 좋은 키워드
Stream Flow lazy evaluation 백프레셔 병렬 처리 공간복잡도 청크
실무에서는

실시간 로그 분석 시스템에서 메모리 제약 내에서 최대 처리량을 달성하기 위한 파이프라인 설계에 활용됩니다.

Follow-up 질문

Flow를 사용할 때 적절한 partition 수와 window 크기를 결정하는 기준은 무엇인가요?

댓글 0

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

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