System design 一次學會的路線
拆解 Azeem 的 system design 學習路線,整理成可直接照抄的練習模板,讓你從亂猜架構變成有順序地拆題。

Azeem 的 system design 路線,把亂掉的練習順序整理成一套能直接照抄的學習法。
我以前也很討厭 system design。不是因為我不會寫後端,我 CRUD、auth、cache 都碰過,服務也救過幾次;是因為一碰到開放題,我腦袋就空白。你叫我設計 YouTube,我會先講一堆「應該可以用資料庫」這種廢話,講完自己都知道是在撐場面。最煩的是,這東西看起來像面試表演,像在逼你把一堆名詞排成漂亮圖,但我根本不知道自己到底缺的是什麼。
後來我看到這篇 How I Finally Learned System Design (After Feeling Totally Lost),才有點醒過來。它不是在賣神技,也不是叫你背一堆架構名詞。它講的是:你要先有一條學習路線,不然你只是在白板前面裝忙。Azeem 這篇原文沒有提供觀看數或書籤數,所以我不亂報數字;但它提供的不是流量,是一個很實際的拆題順序。Medium、Cloud With Azeem、還有他文中提到的系統設計習慣,才是我覺得值得拆的地方。
別把 system design 當面試戲碼
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
You’ve been building “To-Do” apps and CRUD APIs for three years, and you think you’re a “Senior Engineer.” Then, someone asks you, “How would you design YouTube?” and suddenly you’re sweating through your Patagonia vest.
這句話很毒,但我覺得很準。翻譯一下就是:你平常做的是功能題,一旦題目變成系統題,你就會發現自己其實沒學會怎麼想。以前我以為問題是我不懂分散式系統的術語,後來才知道不是。我是一直用「寫功能」的腦袋在想「設計系統」的題目,當然會卡。

system design 真正考的不是你會不會講 cache、queue、load balancer,而是你能不能先把問題拆成需求、約束、瓶頸,再慢慢往下收斂。你如果一開始就衝去畫架構圖,那通常只是把焦慮畫成方塊而已。
我自己最常犯的錯,是題目一出來就想選技術,像是先決定要不要 Kafka、要不要 microservices、要不要 Redis。這種順序很蠢,因為你還沒搞清楚流量型態、延遲要求、資料一致性,選技術只是自我安慰。
實操寫法很簡單:每次練題先逼自己回答三件事。
- 這個產品的核心動作是什麼?
- 最重要的非功能需求是什麼?
- 最先炸掉的地方會是哪裡?
你先把這三件事講清楚,再談架構,答案就會正常很多。這不是技巧,這是順序問題。
先學名詞,但不要把名詞當答案
很多人卡住,是因為一開始就跑去背詞典:load balancer、cache、queue、shard、CDN。這些字都要懂,沒錯,但懂名字不等於懂用途。你如果只會背定義,最後就會變成那種面試講得很順、追問一來就露餡的人。
Azeem 的路線比較像是先把工具放進情境裡。cache 不是因為它酷,是因為它能減少重複讀取;queue 不是因為它高級,是因為它能把尖峰流量先接住;CDN 不是裝飾,是把靜態內容拉近使用者。也就是說,每個元件都應該對應一個問題,不是對應一個面試關鍵字。
我以前最愛亂用 queue。只要系統慢,我就想「丟 queue 啊」。後來才發現,queue 不是萬靈丹。你如果是熱點資料、讀多寫少、或是索引設計有問題,queue 根本不會救你。它只是把問題延後,不是把問題消掉。
我現在會這樣練:每學一個元件,就寫下三行。
- 它解決什麼問題?
- 它會帶來什麼成本?
- 什麼情況下它反而害你?
例如 cache 會降低延遲,但會有過期資料;queue 能吸收尖峰,但會增加延遲和重試處理;load balancer 能分散流量,但也多了一層路由和監控負擔。你只要一直逼自己回答這三個問題,名詞就不會只是名詞。
先定需求,再決定你要畫什麼架構
我以前很愛先畫「看起來很成熟」的架構。微服務先上、Kafka 先上、服務切一切,感覺很像 senior。後來才知道,這種做法很像先買裝潢再找房子。你還沒弄清楚產品要什麼,就先把系統弄得很複雜,最後只是把維護成本提前買單。

比較正常的順序,是先把需求收乾淨。這個系統是偏讀還是偏寫?使用者是全球分布還是單區域?資料一致性是硬需求還是可以延遲?即時性到底要到秒級、毫秒級,還是幾分鐘都行?這些問題的答案,會直接決定你該不該用快取、該不該分區、該不該做非同步處理。
我很喜歡 Azeem 這篇的地方,就是它沒有把 system design 說成神秘儀式。它其實是在教你怎麼收斂問題。你如果不先定義問題,每個架構看起來都差不多合理;你一旦把限制條件講清楚,很多選項會自己消失。
實操時,我建議固定用同一個流程,不要每次 freestyle。
- 先問清楚需求。
- 做粗略流量估算。
- 找出核心資料模型和 API。
- 畫出主要資料流。
- 找瓶頸。
- 最後才加 cache、async、partition。
這個順序看起來笨,但很有效。因為它逼你先思考問題,再思考解法。
估算不是考數學,是防止你自己亂講
很多人討厭 capacity estimation,因為他們以為那是在比誰算得準。其實不是。它只是讓你不要胡說八道。你如果假設流量很小,設計就會看起來很漂亮;但只要題目一補上規模,整個架構就會像紙糊的一樣。
估算的作用,是幫你看見壓力會落在哪裡。是資料庫先爆?還是頻寬先爆?是單台服務撐不住?還是 storage 成本先炸?這些問題不需要精準到小數點,你只需要大概合理。system design 裡面,可信的量級比精準的數字重要太多。
我以前會跳過這一步,因為我覺得麻煩。結果就是我畫出來的東西很順眼,直到有人問我「每秒多少 request?」我才發現整個設計根本沒算過。那種尷尬我不想再來一次。
實操寫法是準備幾個固定錨點,然後用粗算就好。
- 日活使用者數
- 每人每天請求數
- 平均 payload 大小
- 尖峰倍數
再把這些轉成 QPS、儲存量、頻寬和記憶體壓力。你不用算得像財務報表,你只要知道壓力會往哪邊跑。只要你能說出「這裡會熱」、「這裡會慢」、「這裡會貴」,你的答案就比一堆空話有用。
真正的答案通常是取捨,不是標準配方
這是我最想吐槽的一點:很多人以為好的 system design 有標準答案。沒有。大部分時候,你其實是在選代價。多一層 cache,延遲會降,但一致性麻煩;多做副本,可靠性會上去,但同步成本變高;切成 microservices,邊界可能更清楚,但部署、監控、除錯都更煩。
所以當面試官問你「為什麼這樣設計」時,真正要講的不是你用了哪些元件,而是你為什麼接受這些代價。Azeem 的文章雖然不是在列一張工具清單,但它很明顯在推你往這個方向走:從背答案,改成理解選擇。
我遇過太多人一開口就說「我們用 microservices」。這句話常常只是想讓自己看起來成熟。問題是,microservices 不是免費午餐,它會帶來網路延遲、觀測性、部署協調、失敗模式,還有一堆你原本不用處理的麻煩。很多時候,先用 monolith 反而比較合理。
實操時,每次你加一個元件,就強迫自己補一句代價說明。
- 加 cache,就要說快取失效怎麼辦。
- 加 queue,就要說重試和 dead-letter 怎麼處理。
- 切服務,就要說邊界為什麼值得那個複雜度。
這個習慣很重要,因為它會把你從「畫圖的人」拉回「做決策的人」。
不要亂刷題,先把一種題型練到不陌生
我以前學 system design 的方式很爛,就是一直換題目。今天 YouTube,明天 Uber,後天 Twitter,結果腦袋塞滿一堆彼此不相干的片段。看起來很努力,實際上很散。
比較有效的方法,是先挑少數幾種常見題型,反覆練到你看到題目不會慌。像 URL shortener、rate limiter、chat system、file storage、news feed,這些題型各自會逼你碰到不同問題:讀寫比例、fanout、即時性、一致性、儲存、快取、失敗處理。你不是在背答案,你是在熟悉結構。
Azeem 的「from scratch」不是叫你從零知識開始,而是叫你建立一條梯子。先從小系統開始,再往上加複雜度。這樣你才會知道每一塊元件是怎麼互相影響的,不然你只是在聽別人講一個很完整的故事,自己還是不會做。
我自己最有感的是 chat system。以前我只會說「訊息存在資料庫,再推送出去」,講得很乾。後來我才發現,offline delivery、訊息順序、重送、ack、同步狀態,全部都會影響設計。你只要把一個題型練熟,下一題就不會那麼像黑盒子。
實操寫法:每週只做一題完整設計,然後寫成固定格式。
- 需求
- 估算
- 資料模型
- API
- 主流程
- 瓶頸
- 取捨
你不用每題都追求完美,你只要一直重複同一套思考順序,腦袋就會慢慢長出肌肉記憶。
可抄的模板
# system design 練習模板(可直接複製)
## 1. 問題定義
- 這個產品在解決什麼問題?
- 誰會用?
- 核心使用流程是什麼?
## 2. 需求
### 功能需求
-
-
-
### 非功能需求
- 延遲目標:
- 可用性目標:
- 一致性要求:
- 擴充性假設:
## 3. 粗略估算
- 日活:
- 每人每天請求數:
- QPS:
- 讀寫比:
- 每筆資料大小:
- 尖峰倍數:
## 4. 核心資料
- 使用者
- 主要物件
- 中介事件
- 狀態 / session / log
## 5. API 草稿
- POST /...
- GET /...
- PUT /...
- DELETE /...
## 6. 高層架構
- Client
- Load balancer / API gateway
- App service
- Cache
- Database
- Queue / stream
- Object storage / CDN
## 7. 資料流
1. Request 進來
2. 驗證與授權
3. 讀 cache 或 DB
4. 寫入 durable store
5. 必要時丟 async work
6. 回應使用者
## 8. 瓶頸
- 最先會爆的是什麼?
- 哪裡會熱點?
- 哪裡最貴?
## 9. 取捨
- 為什麼選這個 DB?
- 為什麼 cache 放這裡?
- 為什麼這段用 async?
- 為什麼現在還不切 microservices?
## 10. 失敗處理
- Retry
- Timeout
- Dead-letter queue
- Replication
- Backup
## 11. 擴充計畫
- 加 cache
- 加 replica
- Partition data
- Offload static content
- 真的需要時再拆服務
## 12. 最後總結
- 一句話設計摘要
- 最大取捨
- 最大風險
- 下一步改善這段就是我想直接塞給自己的版本。它不會讓 system design 瞬間變簡單,但它會讓你至少知道自己現在在幹嘛,不會一題還沒開始就先亂。
這篇內容的原始來源是 Azeem 的 Medium 文章,我拆的是他的學習順序和觀念;上面的模板、段落重排、實作清單,都是我整理後做成可直接抄的版本。你如果要看原文脈絡,從這個 URL 進去就行。