Meta 的 system design 面試有非常清晰的出題規律:資料強一致、系統低延遲、功能對齊產品體驗。無論題目表面看似社交、內容分發還是儲存系統,考察核心永遠圍繞三個維度——使用者規模(scale)、一致性策略(consistency tradeoff)、延遲預算(latency)。
這篇文章拆解 Meta 最高頻的三道系統設計題,並給出一套可直接複用的複盤框架。
複盤一道題的正確姿勢
- 定義核心互動:用一句話說清系統的核心使用者操作路徑
- 估算容量:QPS、儲存與延遲預算
- 畫資料流與控制流:write path 和 read path,識別快取、資料庫、訊息系統之間的邊界
- 展開權衡:通過一到兩個 trade-off 深入討論,例如 read-fanout 與 write-fanout 的取捨
高頻題一:News Feed(fanout 與即時性權衡)
Feed 系統是 Meta 的經典高頻題,核心考察 fanout 與即時性的權衡。產品層面,一個使用者發文意味著幾百萬粉絲的 timeline 需要更新;系統層面,這對應一次寫入觸發大量下游資料變動。
push + pull 混合模型
Meta 的設計傳統是 push + pull 混合:
- 高活躍使用者(如名人帳號):寫入時只做輕量 fanout,將貼文存入 global post store;讀取時由 follower 的 newsfeed 服務執行 lazy pull 聚合
- 普通使用者:寫入時直接 fanout 到 follower 的 timeline(write-fanout),讀取時直接命中
def deliver_post(post, author):
save_to_global_store(post)
if author.follower_count > CELEBRITY_THRESHOLD:
# 名人:只入全域庫,讀取時 pull
return "pull"
else:
# 普通使用者:寫時 fanout 到粉絲 timeline
for fan in author.followers:
timeline_cache[fan].push(post.id)
return "push"
加分點:ranker pipeline 解耦
面試中要強調 ranking pipeline 的解耦:一個快速排序模型在 serving 層執行,另一個複雜 ML 模型在離線訓練中更新特徵與權重。展示這一點能體現對 production-scale 系統的理解深度。
高頻題二:Messenger / Chat(訊息一致性與投遞語義)
Chat 題考點集中在訊息一致性與 delivery semantics。Meta 的即時通訊採用 multi-device synchronization model,要求訊息在不同裝置間按時間一致顯示,同時保證「已送達」「已讀」狀態準確。
store-and-forward 處理離線訊息
面試官常追問離線訊息如何處理。核心是 store-and-forward 機制:
- 目標使用者離線時,delivery service 將訊息暫存在 Redis 或持久佇列,並記錄 offset
- 使用者重新上線後,client 從 offset 處繼續拉取,保證不丟不重
def deliver_message(msg, recipient):
if is_online(recipient):
push_to_device(recipient, msg)
else:
# 離線:暫存並記錄 offset
offline_queue[recipient].append(msg)
update_offset(recipient, msg.seq)
def on_reconnect(recipient):
last = get_offset(recipient)
return [m for m in offline_queue[recipient] if m.seq > last]
最後要討論 end-to-end 加密與多裝置金鑰同步,體現對隱私和安全的考量。
高頻題三:秒殺 / 座位預訂(防 double booking 的分散式鎖)
這道題常出現在 Meta 的 infrastructure 或 commerce 團隊面試,考察重點是防止 double booking 的分散式鎖設計。把系統建模為「稀缺資源分配問題」:多個使用者同時請求同一座位/房間,系統必須在高併發下保持唯一性。
reservation token + TTL-based lock
標準思路是 reservation token + TTL 鎖:
- 使用者點擊預訂時,系統生成帶過期時間的 token 寫入 Redis,作為 seat_id 的唯一持有者
- 若確認購買,將鎖升級為持久狀態寫入資料庫;否則 TTL 過期自動釋放
def try_reserve(seat_id, user_id, ttl=120):
# SET NX:只有 key 不存在時才設置,保證唯一持有者
ok = redis.set(f"lock:{seat_id}", user_id, nx=True, ex=ttl)
return bool(ok)
def confirm(seat_id, user_id):
holder = redis.get(f"lock:{seat_id}")
if holder == user_id:
persist_booking(seat_id, user_id) # 升級為持久狀態
return True
return False # 鎖已過期或被他人持有
若面試官追問跨分區一致性,可進一步說明用一致性雜湊分片 seat_id、或引入 Redlock / 單調遞增 fencing token 防止鎖失效後的髒寫。
三維度複盤速查表
| 維度 | News Feed | Chat | 預訂 |
|---|---|---|---|
| Scale | 名人 fanout 放大 | 多裝置同步 | 高併發搶佔 |
| Consistency | 最終一致(timeline) | 順序 + 不丟不重 | 強一致(唯一持有) |
| Latency | 讀路徑毫秒級 | 投遞即時 | 鎖獲取低延遲 |
FAQ
Q1:Meta 系統設計面試最看重什麼? 三個維度:scale(使用者規模)、consistency(一致性取捨)、latency(延遲預算)。面試官不在乎你畫多漂亮的架構圖,而在乎你能否就一兩個關鍵 trade-off 展開有深度的討論。
Q2:News Feed 題該用 push 還是 pull? 混合模型最佳:普通使用者用 write-fanout(push),名人帳號用 read-fanout(pull)避免寫放大。能講清兩者切換的閾值和理由是加分點。
Q3:Chat 題怎麼處理離線訊息? 用 store-and-forward:離線時暫存到 Redis/持久佇列並記錄 offset,使用者上線後從 offset 續拉,保證不丟不重。再補一句多裝置同步和 E2E 加密會更完整。
Q4:秒殺/預訂題如何防止 double booking? reservation token + TTL 鎖:用 Redis SET NX 保證唯一持有者,確認後升級為持久狀態,未確認則 TTL 自動釋放。跨分區可用一致性雜湊分片或 fencing token。
Q5:如何在 45 分鐘內講完一道 Meta 系統設計? 按四步走:一句話定義核心互動 → 估算容量 → 畫 read/write path → 選一兩個 trade-off 深入。時間緊時砍掉次要功能,把深度留給核心權衡。
正在準備 Meta 系統設計?
如果你能列組件但講不深 trade-off,或想在 onsite 前把 News Feed / Chat / 預訂三道高頻題練到能臨場展開,歡迎交流:可提供題型拆解、複盤框架與表達陪練,針對 Meta 設計輪的考察重點客製練習。
聯絡方式
需要面試真題與客製備戰計畫?立刻聯絡微信 Coding0201,獲取真題。
Email: [email protected] Telegram: @OAVOProxy