速查表 (Quick Reference)
面試預設選擇
| 決策點 | 預設選擇 | 替代條件 |
|---|---|---|
| 架構模型 | Client-Server | 音視訊通話 → P2P(WebRTC) |
| Client 類型 | Thick Client(SPA/App)+ REST | — |
| CAP 取捨 | AP(可用性優先) | 銀行/庫存/訂票 → CP |
| 擴展策略 | 先垂直,再水平 | 流量持續高 / 需高可用 → 水平 |
| 傳輸層 | TCP | 低延遲 + 可丟包 + 無瀏覽器 → UDP |
| API 範式 | REST | 靈活查詢 → GraphQL;內部高效 → gRPC |
| 即時推送 | SSE | 雙向 → WebSocket;P2P音視訊 → WebRTC |
| LB 類型 | L7 | WebSocket → L4 |
| LB 演算法 | Round Robin | 持久連線 → Least Connections |
| 故障處理 | 重試 + 指數退避 + 抖動 | 持續失敗 → 熔斷器 |
| 分片 routing | Consistent Hashing + vNodes | 固定 shard 數 → hash % N |
| 通用索引 | B-Tree / B+Tree | 等值 → Hash;寫多 → LSM |
| 地理索引 | R-Tree(SQL)/ Geohash(NoSQL) | Uber 鄰近 → H3;地圖切片 → S2 |
| 全文檢索 | Inverted Index(Elasticsearch) | 小規模 → PostgreSQL FTS |
| 隔離等級 | Read Committed | 多次讀同 row 一致 → Repeatable Read;金融 → Serializable |
| 超賣防護 | 原子 UPDATE / SELECT FOR UPDATE |
不要 提升到 Serializable |
| 跨服務交易 | Saga + 補償 | (罕見)強一致需求 → 2PC |
| Shard Key | Hash + Consistent Hashing | 多租戶 SaaS → Range |
| Sharding 時機 | 50TiB / 10k TPS / uncached read 需求 | < 1TB / < 1k TPS 不要分片 |
| Replication | Single-Leader + Semi-Sync | 多 DC → Multi-Leader;高可用寫入 → Leaderless |
| Read-After-Write | 從 primary 讀自己改的 | 追蹤 LSN(不要用時鐘) |
| 快取模式 | Cache-Aside + LRU + TTL | 寫密集 → Write-Behind;靜態媒體 → CDN |
| 快取失效 | 寫入時 delete cache |
不一致敏感 → 短 TTL + 接受最終一致 |
網路層次 → 網路層次與請求流程
| 層 | 協定 | 功能 |
|---|---|---|
| L3 網路層 | IP | 路由、定址 |
| L4 傳輸層 | TCP, UDP, QUIC | 端到端通訊、可靠性 |
| L7 應用層 | HTTP, DNS, WS, WebRTC | 應用程式通訊 |
Web 請求流程:DNS 解析 → TCP 三次握手 → HTTP 請求 → 伺服器處理 → HTTP 回應 → TCP 四次揮手
TCP vs UDP → 傳輸層協定 TCP vs UDP
| 特性 | TCP | UDP |
|---|---|---|
| 連線 | 面向連線 | 無連線 |
| 可靠性 | 保證交付 | 盡力而為 |
| 標頭 | 20–60 bytes | 8 bytes |
| 場景 | 幾乎所有情況(預設) | 串流、遊戲、VoIP |
瀏覽器只能透過 WebRTC 使用 UDP。
HTTP 方法與狀態碼 → HTTP 與 HTTPS
| 方法 | 語義 | 冪等 |
|---|---|---|
| GET | 取得 | ✅ |
| POST | 建立 | ❌ |
| PUT | 完整更新 | ✅ |
| PATCH | 部分更新 | ❌ |
| DELETE | 刪除 | ✅ |
| 碼 | 含義 |
|---|---|
| 200 / 201 | 成功 / 建立成功 |
| 301 / 302 | 永久 / 暫時重定向 |
| 401 / 403 | 未驗證 / 無授權 |
| 404 / 429 | 不存在 / 頻率過高 |
| 500 / 502 | 伺服器錯誤 / 閘道錯誤 |
API 範式 → API 範式比較、API 設計決策框架
| 範式 | 格式 | 場景 |
|---|---|---|
| REST | JSON | 外部 API(預設) |
| GraphQL | JSON | 前端靈活查詢、多團隊重疊資料 |
| gRPC | Protocol Buffers | 內部微服務(吞吐量 ~10x) |
策略:內部 gRPC + 外部 REST
決策樹:
External or Internal?
├── Internal ────────────► RPC / gRPC
└── External
└── Over/Under-fetching concern?
├── Yes ─────► GraphQL
└── No ─────► REST
即時通訊 → 即時通訊協定
| 協定 | 方向 | 底層 | 場景 |
|---|---|---|---|
| SSE | Server → Client | HTTP/TCP | 通知、事件推送 |
| WebSocket | 雙向 | TCP | 聊天、遊戲 |
| WebRTC | P2P | UDP | 音視訊通話 |
決策:SSE 夠嗎?→ 需要雙向?→ WebSocket → 需要 P2P 音視訊?→ WebRTC
負載平衡 → 負載平衡
| 類型 | 層級 | 路由依據 | 場景 |
|---|---|---|---|
| 客戶端 LB | — | 客戶端查詢 registry | 內部微服務、gRPC |
| L4 LB | 傳輸層 | IP/Port | WebSocket(必選) |
| L7 LB | 應用層 | URL/Header/Cookie | HTTP 流量(預設) |
演算法:無狀態 → Round Robin;長連線 → Least Connections;Session 持久 → IP Hash
降低延遲:靜態內容 → CDN;地理相關資料 → 區域分片
故障處理模式 → 故障處理模式
| 模式 | 解決 | 關鍵字 |
|---|---|---|
| 重試 + 指數退避 + 抖動 | 暫時故障 | exponential backoff + jitter |
| 冪等性 / 冪等鍵 | 重試副作用 | idempotency key |
| 熔斷器 | 級聯故障 | Closed → Open → Half-Open |
熔斷器狀態機:
Closed ──失敗超閾值──► Open ──逾時到期──► Half-Open
▲ │
└──────── 測試成功 ──────────────────────┘
測試失敗 → 回到 Open
Client-Server Architecture → 主從架構
| 角色 | 職責 |
|---|---|
| Client | UI、收集輸入、發請求、展示回應 |
| Server | 驗證授權、商業邏輯、讀寫 DB、回傳結果 |
Thin Client(SSR)vs Thick Client(SPA/App)— 現代預設 Thick + REST
C/S vs P2P — 音視訊通話才考慮 P2P
CAP Theorem → CAP 定理
| 組合 | 保證 | 犧牲 | 場景 |
|---|---|---|---|
| CP | 一致性 + 分區容忍 | 可用性 | 銀行、庫存、訂票 |
| AP | 可用性 + 分區容忍 | 一致性 | 社群動態、DNS、購物車 |
| CA | — | — | 現實中不存在 |
決策:「暫時不一致會造成嚴重後果嗎?」→ 是 → CP;否 → AP(預設)
Scalability → 可擴展性
| 策略 | 做法 | 上限 | 複雜度 | 適合時機 |
|---|---|---|---|---|
| Vertical Scaling | 升級單機規格 | 有物理限制 | 低 | 短期快速解法 |
| Horizontal Scaling | 增加機器 + LB | 理論無限 | 高 | 長期大規模成長 |
順序:先垂直,碰到上限或需高可用時再水平
水平擴展挑戰:Session 狀態、資料一致性(→ CAP)、LB SPOF
REST 要點 → REST 架構風格
| 動詞 | 冪等 | 用途 |
|---|---|---|
| GET | ✅ | 讀取 |
| POST | ❌ | 建立 |
| PUT | ✅ | 完整更新 |
| PATCH | 依設計(通常 ❌) | 局部更新 |
| DELETE | ✅ | 刪除 |
狀態碼:401(未認證)vs 403(無權限);201 Created(建立成功,搭 Location header)
參數:Path(指向資源)/ Query(篩選)/ Body(POST/PUT/PATCH 結構化資料)
反模式:POST /updateUser、GET /deleteUser、GET 帶 body
GraphQL 要點 → GraphQL 查詢語言
| 操作 | 對應 |
|---|---|
| Query | 讀取 |
| Mutation | 修改 |
| Subscription | 即時推送(通常 WebSocket) |
核心問題:
- N+1:batch resolver 用 DataLoader 合成
IN (...) - Cache 難:POST + 單一 endpoint → 用 persisted queries 取回 CDN cache
- 惡意查詢:用 query complexity / depth limit
gRPC 要點 → RPC 與 gRPC
- Protobuf 二進位序列化 → ~10x JSON 吞吐量
- IDL(.proto) 定義介面,生成跨語言 stub
- HTTP/2 → 四種模式:unary / server stream / client stream / bidirectional
- 相容規則:新欄位用新 tag、刪除欄位
reserved、不改型別 - 陷阱:面試不要過早跳 gRPC;瀏覽器需 gRPC-Web
API Security → API 安全
AuthN vs AuthZ:「你是誰」vs「你能做什麼」
| 方式 | 類型 | 典型場景 |
|---|---|---|
| API Key | AuthN | 內部 / 低敏感 API |
| JWT | AuthN | 公開 App 身份驗證 |
| OAuth 2.0 | AuthZ | 第三方授權 |
| mTLS | AuthN | 內部微服務(雙向) |
| RBAC | AuthZ | 公司內部管理(角色) |
| ABAC | AuthZ | 金融 / 政府(屬性) |
| Scope | AuthZ | OAuth token 粒度控制 |
- JWT 放
Authorization: Bearer <token> - Access token 短期 + Refresh token
- 不要把敏感資料放 JWT payload(只有 base64,非加密)
Consistent Hashing → 一致性雜湊
核心問題:hash(key) % N 在 N 變動時會搬走幾乎所有 key。
解法:
- Hash Ring:節點與 key 映射到圓環,順時針找第一個節點
- Virtual Nodes:每節點多個位置 → 分佈均勻 + 可按硬體能力分配
搬遷量:hash % N → O(K);Consistent Hashing → O(K/N)。
觸發場景:Distributed Cache sharding、Cassandra/DynamoDB routing、Sticky Sessions、Rate Limiting、CDN edge routing。
索引結構決策 → 資料庫索引概論
| 需求 | 首選索引 |
|---|---|
| 通用查詢 / 範圍 / 排序 | B-Tree / B+Tree(預設) |
| 純等值查詢 | Hash Index(O(1)) |
| 寫多 / 時序 / log ingest | LSM Tree(Cassandra、RocksDB) |
| 地理鄰近搜尋 | Geohash / R-Tree / H3 / S2 |
| 全文關鍵字檢索 | Inverted Index(Elasticsearch/Lucene) |
B-Tree 要點 → B-Tree 索引
- 平衡多叉樹,葉節點距離相等
- B+Tree:只葉節點存資料 + 葉節點間 linked list → 範圍查詢更快
- InnoDB / PostgreSQL / MongoDB 都用 B+Tree 或近似變體
LSM Tree 要點 → LSM Tree
寫入:WAL → MemTable(SkipList)→ SSTable flush → Compaction
- 把隨機寫變順序寫 → 寫入吞吐極高
- 查詢用 Bloom Filter 跳過 SSTable
- 代價:寫放大 + 讀取可能多層
Hash Index 要點 → 雜湊索引
hash(key) → bucket→ O(1) 等值查詢- 碰撞處理:Chaining or Open Addressing
- 不支援範圍、排序、前綴
Geospatial 要點 → 地理空間索引
| 技術 | 特色 |
|---|---|
| Geohash | 2D→1D 字串,用 B-Tree 前綴 |
| Quadtree | 固定切 4 等份(遊戲、GIS 可視化) |
| R-Tree | 彈性可重疊 MBR(SQL 空間索引標準) |
| S2 | 地球→立方體→4 邊形 cell(地圖切片) |
| H3 | 地球→二十面體→6 邊形 cell(Uber 鄰近搜尋) |
Inverted Index 要點 → 倒排索引
- Term Dictionary + Posting List
- Posting 含 Doc ID、TF、positions(phrase query 用)
- 應用:Elasticsearch、Lucene、PostgreSQL FTS、MySQL FULLTEXT
Database Transactions → 資料庫交易
ACID:Atomicity / Consistency / Isolation / Durability
四種隔離等級
| 隔離等級 | Dirty | Non-repeat | Phantom | 預設於 |
|---|---|---|---|---|
| Read Uncommitted | ✅ | ✅ | ✅ | 幾乎不用 |
| Read Committed | ❌ | ✅ | ✅ | PostgreSQL |
| Repeatable Read | ❌ | ❌ | ✅ | MySQL InnoDB |
| Serializable | ❌ | ❌ | ❌ | 金融 |
並發異常與解法
- Dirty Read:讀到未 commit 資料
- Non-repeatable Read:同 row 值變了
- Phantom Read:範圍查詢 row 數變了
- Lost Update(重要!):兩交易同時改 → 後寫覆蓋前寫
- 解:Optimistic Locking(version 欄位)或 Pessimistic Locking(
SELECT FOR UPDATE)
- 解:Optimistic Locking(version 欄位)或 Pessimistic Locking(
- 超賣本質是 Lost Update:原子
UPDATE qty = qty - 1 WHERE qty > 0即可,不要動隔離等級
分散式交易
- 2PC:強一致但脆弱(coordinator 崩潰會卡死)
- Saga:本地交易 + 補償,現代微服務主流
ACID 的 C 是「商業 constraint」,CAP 的 C 是「副本同步」。完全不同。
Sharding → 資料分片
Shard Key 三條件
- 高基數(cardinality)
- 均勻分佈
- 契合查詢模式
三種策略
| 策略 | 優點 | 缺點 |
|---|---|---|
| Range | 支援範圍查詢 | 容易熱點(如 created_at) |
| Hash(預設) | 分佈均勻 | 擴容大搬資料 → 用 Consistent Hashing |
| Directory | 靈活 | SPOF + 多一次 lookup |
三大挑戰
| 挑戰 | 解法 |
|---|---|
| Celebrity Hot Spot | 隔離到專屬 shard / 複合 key hash(uid+date) |
| 跨 shard 查詢 | 快取 / 反正規化 / 背景預計算 |
| 跨 shard 一致性 | 設計成同用戶資料同 shard → 避免 / Saga / 接受最終一致 |
1TB 以下、< 10k TPS 寫入幾乎都不需要分片。先 index → cache → replica → 升級硬體 → 才談 sharding。
Replication → 資料複寫
三大架構
| 架構 | 適用 | 主要挑戰 |
|---|---|---|
| Single-Leader | 大多數讀取密集應用 | Replication Lag、Failover |
| Multi-Leader | 多 DC、離線編輯 | 寫入衝突 |
| Leaderless | 高可用寫入、最終一致 | Quorum 一致性、版本合併 |
Replication Lag 三大不一致
| 問題 | 解法 |
|---|---|
| Read-After-Write | 自己改的從 primary 讀 / 追蹤 LSN(不要用時鐘) |
| Monotonic Read | 同用戶總是讀同一 replica(hash(user_id) 路由) |
| Consistent Prefix | 有因果關係的寫入放同一 partition / version vector |
Failover 三大坑
- 非同步資料遺失 → 半同步 + 選資料最新的 follower
- Split Brain → STONITH / Fencing Token / Raft consensus
- Timeout 拿捏(太長復原慢、太短誤觸發)
Quorum(Leaderless)
公式:w + r > n → 讀寫節點必有重疊。
常見 n=3, w=2, r=2(容忍 1 個失效)。
Sloppy Quorum + Hinted Handoff:寫到「非家節點」暫存,網路恢復後送回家 → AP 配置。
Caching → 快取機制
快取位置(latency 由低到高)
In-Process(ns) < Redis 同區(< 1ms) < CDN(20–40ms)
四種模式
| 模式 | 寫入 | 適用 |
|---|---|---|
| Cache-Aside(預設) | App 寫 DB → delete cache | 通用 |
| Write-Through | App 寫 cache → cache 同步寫 DB | 讀必新鮮 |
| Write-Behind | App 寫 cache → 背景非同步寫 DB | 高寫吞吐、可丟資料 |
| Read-Through | Cache 自己 miss 後查 DB | CDN 本質 |
淘汰策略
LRU 預設(90% 工作負載適合)+ TTL 防過時。LFU 適合長期熱門,FIFO 幾乎不用。
三大陷阱
| 問題 | 最有效解 |
|---|---|
| Cache Stampede | Request Coalescing(Single Flight) |
| Cache Consistency | 寫入時 delete + 適度 TTL |
| Hot Key | 複製到多節點(TTL 錯開)+ in-process 備援 |
面試五步驟
- 確認瓶頸 → 2. 決定快取什麼 → 3. 選架構(預設 Cache-Aside)→ 4. 淘汰策略(LRU+TTL)→ 5. 說缺點(失效 / 故障 / Stampede)
Numbers to Know → 系統設計關鍵數字
核心量級
| 元件 | 關鍵指標 | Scale Trigger |
|---|---|---|
| Cache(Redis) | < 1ms、100k+ ops/sec、1TB 上限 | hit < 80% / latency > 1ms |
| Database | 50k TPS 讀 / 10–20k TPS 寫 / 64TiB | 50TiB / 10k TPS 寫 / uncached < 5ms |
| App Server | 100k+ 連線 / 8–64 核 / 64–512GB | CPU > 70% / 頻寬 ≈ 20Gbps |
| Kafka Broker | 1M msg/sec / 1–5ms / 50TB / 週月保存 | 800k msg/sec / 200k partition |
Latency 量級直覺
memory ≪ disk ≪ network
- Memory(in-process):ns
- Memory(Redis 同區):< 1ms
- Disk(DB cached):1–5ms
- Disk(DB uncached):5–30ms
- Network(跨區):10–100ms+
過早 sharding 是頭號錯誤 —— < 1TB / < 1k TPS 通常不需要。