목차5개 항목
출처와 참고
ByteByteGo의 System Design 101 가이드 「10 Key Data Structures We Use Every Day」, 「Algorithms for System Design Interviews」, 「The 9 Algorithms That Dominate Our World」, 「How to Avoid Crawling Duplicate URLs at Google Scale?」를 바탕으로 재구성한 노트다. 블룸 필터의 거짓 음성이 없는 이유와 거짓 양성률 식은 fru1tworld/cs-basic 모의 면접 질문 목록의 「자료구조」 질문이 묻는 개념으로 보강했다.
알고리즘 공부는 구현에 치우치기 쉽다. 시스템을 설계할 때는 「이 알고리즘이 실제 시스템의 어느 문제를 푸는가」를 아는 것이 구현 세부보다 중요하다. 그래서 자료구조와 알고리즘을 쓰임새 중심으로 묶어 본다.
일상 속 자료구조
| 자료구조 | 쓰이는 곳 | 왜 그것인가 |
|---|---|---|
| 리스트 | SNS 피드 | 순서대로 이어 붙이고 훑는다 |
| 배열 | 수학 연산, 이미지 픽셀 | 인덱스로 즉시 접근, 메모리에 연속 배치 |
| 스택 | 편집기의 실행 취소·다시 실행 | 마지막에 한 것을 먼저 되돌린다(스택) |
| 큐 | 프린터 작업, 게임의 사용자 입력 전송 | 들어온 순서대로 처리한다(큐와 덱) |
| 해시 테이블 | 캐시 시스템 | 키로 평균 O(1) 조회 |
| 힙 | 작업 스케줄링 | 우선순위가 가장 높은 것을 빨리 꺼낸다(힙과 우선순위 큐) |
| 트리 | HTML 문서(DOM), AI의 결정 트리 | 계층 구조를 표현한다(트리와 이진 탐색 트리) |
| 접미사 트리 | 문서 안 문자열 검색 | 모든 접미사를 미리 색인해 부분 문자열을 빠르게 찾는다 |
| 그래프 | 친구 관계, 길 찾기 | 관계와 연결을 표현한다(그래프의 기본) |
| R-트리 | 가까운 장소 찾기 | 공간을 겹치는 사각형으로 나눠 위치 범위 질의를 빠르게 한다 |
| 버텍스 버퍼 | GPU 렌더링 | 정점 데이터를 GPU 메모리에 한 번에 보낸다 |
기초 자료구조의 구현은 기초 자료구조에 있다.
시스템 설계에 자주 나오는 알고리즘
| 알고리즘·자료구조 | 푸는 문제 | 쓰이는 곳 |
|---|---|---|
| 일관된 해싱(Consistent Hashing) | 노드가 늘거나 줄 때 다시 옮길 키를 최소화한다 | 분산 캐시, 샤딩, 로드 밸런서(데이터베이스 샤딩) |
| 지오해시(Geohash)·쿼드트리(Quadtree) | 2차원 위치를 인덱싱해 "근처에 무엇이 있나"를 빨리 답한다 | 주변 가게 찾기, 차량 호출 |
| 블룸 필터(Bloom Filter) | 원소가 집합에 "확실히 없다"를 적은 메모리로 판정한다 | 크롤러의 중복 URL, DB의 불필요한 디스크 읽기 줄이기 |
| HyperLogLog | 고유 원소 개수를 아주 적은 메모리로 근사한다 | 고유 방문자 수 집계(Redis) |
| Count-Min Sketch | 스트림에서 원소별 빈도를 근사한다 | 실시간 인기 검색어, 상위 K개 |
| 토큰 버킷·누출 버킷 | 요청 속도를 제한한다 | API 속도 제한(rate limiting) |
| 트라이(Trie) | 접두사로 문자열을 찾는다 | 검색어 자동 완성(기초 자료구조) |
| 머클 트리(Merkle Tree) | 두 데이터 집합에서 다른 부분만 빨리 찾는다 | 복제본 동기화, Git, 블록체인 |
| Raft·Paxos | 여러 노드가 하나의 값에 합의한다 | 리더 선출, 분산 설정 저장소(etcd, ZooKeeper) |
| 운영 변환(OT)·CRDT | 동시에 일어난 편집을 충돌 없이 합친다 | 공동 문서 편집 |
| 증분 동기화(rsync) | 바뀐 블록만 보내 파일을 맞춘다 | 파일 동기화·백업 |
이 중 일관된 해싱, 블룸 필터, 지오해시·쿼드트리처럼 여러 설계 문제에 반복해서 나오는 것을 먼저 이해한다. 합의 알고리즘이나 CRDT는 선임 수준에서 원리를 알아 두면 된다.
블룸 필터: 중복 URL 걸러 내기
웹 크롤러는 수십억 개의 URL 중 이미 본 것을 다시 넣지 않아야 한다. 선택지는 셋이다.
| 방법 | 장점 | 단점 |
|---|---|---|
| 메모리의 집합(Set) | 빠르고 정확하다 | URL 전체를 저장해 메모리가 감당이 안 된다 |
| DB에 저장하고 조회 | 정확하다 | 조회마다 DB 부하가 크다 |
| 블룸 필터 | 비트 배열만 써서 메모리가 매우 적고 빠르다 | 가끔 "있다"고 잘못 답한다 |
flowchart LR
M["비트 배열(크기 m)<br>0 0 0 0 0 0 0 0 0 0 0 0"]
subgraph ADD["추가"]
U1["url1"] --> H1["해시 A, B, C"] --> P1["위치 1, 5, 9를 1로"]
U2["url2"] --> H2["해시 A, B, C"] --> P2["위치 3, 5, 11을 1로<br>(5는 겹친다)"]
end
subgraph GET["조회"]
U3["url3"] --> H3["해시 A, B, C"] --> P3["위치 1, 3, 5"] -- "세 칸 모두 1" --> R3["#quot;아마 있다#quot;<br>실제로는 없다(거짓 양성)"]
U4["url4"] --> P4["위치 2, 5, 9"] -- "2가 0" --> R4["#quot;확실히 없다#quot;"]
end- 거짓 음성은 없고 거짓 양성만 있다. 비트는 0에서 1로 세우기만 하고 되돌리지 않으므로, 한 번 넣은 원소의 k칸은 언제까지나 1이다. 그래서 "없다"(어느 한 칸이 0)는 답은 항상 맞다. 반대로 "있다"는 다른 원소들이 세운 비트가 우연히 k칸을 모두 덮었을 때도 나오므로 틀릴 수 있다. 크롤러가 새 URL을 가끔 놓치는 것은 감수할 수 있으므로 잘 맞는다.
- 거짓 양성률은 비트 배열 크기 m, 해시 함수 개수 k, 넣은 원소 수 n으로 정해진다. 근사식은 p ≈ (1 - e^(-kn/m))^k이고, 가장 낮아지는 k는 (m/n)·ln 2다. 이때 원소당 약 9.6비트면 1%, 14.4비트면 0.1%다. 원소가 기대보다 많이 들어오면 비율이 급격히 나빠지므로 기대 원소 수에 맞춰 크기를 미리 잡는다.
- 해시 함수는 고르게 퍼지고 빨라야 한다. 암호 해시 대신 MurmurHash, xxHash 같은 비암호 해시를 쓴다.
- 기본 블룸 필터는 원소를 지울 수 없다. 지우려고 비트를 0으로 되돌리면 그 비트를 함께 쓰던 다른 원소가 "없다"로 나와 거짓 음성이 생긴다. 삭제가 필요하면 칸마다 비트 대신 카운터를 두는 카운팅 블룸 필터나 쿠쿠 필터를 쓴다.
크롤러 전체 설계에서 블룸 필터가 놓이는 자리는 대규모 웹 크롤러 설계에 있다.
세상을 움직이는 아홉 가지 알고리즘
검색 엔진, SNS, Wi-Fi, 휴대폰, 위성까지 일상 기술 밑에는 다음 알고리즘이 있다.
| 알고리즘 | 하는 일 | 쓰이는 곳 |
|---|---|---|
| 정렬 | 데이터를 순서대로 놓는다 | 검색 결과, 데이터베이스, 거의 모든 곳(병합 정렬과 퀵 정렬) |
| 다익스트라 | 그래프에서 최단 경로를 찾는다 | 지도 길 찾기, 네트워크 라우팅(다익스트라 최단 경로) |
| 트랜스포머 | 어텐션으로 시퀀스의 관계를 학습한다 | 대규모 언어 모델, 번역 |
| 링크 분석(PageRank) | 링크 구조로 페이지의 중요도를 매긴다 | 검색 순위 |
| RSA | 공개키로 암호화하고 개인키로 푼다 | HTTPS 키 교환·서명(인코딩·암호화·해시) |
| 정수 인수분해 | 큰 수를 소인수로 나눈다. 어렵다는 사실 자체가 RSA의 안전 근거다 | 암호학 |
| 합성곱 신경망(CNN) | 이미지의 지역 패턴을 학습한다 | 이미지 인식, 얼굴 인식 |
| 허프만 부호화 | 자주 나오는 기호에 짧은 부호를 준다 | 압축(ZIP, JPEG, PNG의 일부 단계) |
| 보안 해시(SHA) | 임의 데이터를 고정 길이 지문으로 만든다 | 무결성 검사, 디지털 서명, Git, 블록체인 |
정리
- 자료구조는 쓰임새로 기억한다. 실행 취소는 스택, 캐시는 해시 테이블, 스케줄링은 힙, 위치 검색은 R-트리다.
- 대규모 시스템의 단골 알고리즘은 일관된 해싱, 지오해시·쿼드트리, 블룸 필터, 근사 집계(HyperLogLog, Count-Min Sketch), 속도 제한, 머클 트리, 합의다.
- 블룸 필터는 "확실히 없다"를 싸게 판정한다. 거짓 양성을 감수할 수 있는 곳에 쓴다.
- 설계에서는 구현보다 어떤 문제를 어떤 대가로 푸는지를 설명할 수 있어야 한다.
관련 노트: 기초 자료구조, 대규모 웹 크롤러 설계, 데이터베이스 샤딩, 시스템 설계의 선택지와 흔한 문제의 해법, 빅오 표기법과 시간 복잡도, 데이터 압축: 무손실과 손실, 실시간 트렌딩과 Top-K 집계
원본 기록5
- 원문 (새 창) bytebytego.com/guides/10-key-data-structures-we-use-every-day
- 원문 (새 창) bytebytego.com/guides/algorithms-you-should-know-before-taking-system-design-interviews
- 원문 (새 창) bytebytego.com/guides/the-9-algorithms-that-dominate-our-world
- 원문 (새 창) bytebytego.com/guides/how-to-avoid-crawling-duplicate-urls-at-google-scale
- GitHub 원문 (새 창) github.com/fru1tworld/cs-basic/blob/main/interview/cs/ds.md