你剛剛拿到了夢寐以求公司的 onsite 面試。招募協調員把當天的行程寄給你,掃過清單一行行往下看時你還挺有信心,直到你的目光落在這一場——系統設計面試。
系統設計面試常常令人感到畏懼。題目可能模糊到像「設計知名產品 X」。題意曖昧、範圍寬得不合理。你會感到疲憊是可以理解的。畢竟,誰能在短短一小時內,設計出一個原本由數百甚至數千名工程師打造出來的熱門產品?
好消息是,沒有人期待你做到那種事。真實世界的系統設計極其複雜。例如 Google 搜尋看似簡單,但支撐這份簡單的技術量卻令人嘆為觀止。既然沒有人期待你在一小時內設計出真實世界的系統,那系統設計面試的意義在哪?
系統設計面試模擬的是真實世界的問題解決場景:兩位同事針對一個曖昧的問題協作,並提出能達成目標的解法。問題是開放式的,沒有完美答案。最終的設計成果其實沒有你在設計過程中投入的努力那麼重要。 這給了你一個機會展示你的設計能力、為自己的設計選擇辯護,並以建設性的方式回應回饋。
我們換個視角,想想看當面試官走進會議室見你時,她腦中在想什麼。面試官的首要目標是準確評估你的能力。她最不想要的,就是因為這場面試進行得不順利、訊號不足,而給出無法定論的評估。那麼,面試官在系統設計面試中究竟想看到什麼?
許多人以為系統設計面試只關乎技術設計能力,其實遠不止於此。一場有效的系統設計面試會給出強烈訊號,反映受試者:
- 協作能力
- 抗壓表現
- 建設性處理模糊情境的能力
提出好問題的能力同樣是關鍵技能,許多面試官會特別觀察這一點。
優秀的面試官也會留意警訊(red flag)。過度設計(over-engineering)是許多工程師的通病——他們沉迷於設計純粹度而忽略 tradeoff,往往沒意識到過度設計系統的累積成本,許多公司就為這份無知付出了高昂代價。你絕對不想在系統設計面試中表現出這種傾向。其他警訊還包括思考狹隘、固執己見等。
在本章中,我們會分享一些有用的技巧,並介紹一個簡單而有效的框架,用來解決系統設計面試題。
一套有效的系統設計面試 4 步驟流程#
每場系統設計面試都不一樣。一場精彩的系統設計面試是開放式的,並沒有放諸四海皆準的解法。然而,有些步驟與共通要點是每場系統設計面試都該涵蓋的。
步驟 1 — 理解問題並確立設計範圍#
「老虎為什麼吼叫?」
教室後排有隻手刷地舉起來。
「Jimmy,請說?」老師回應。
「因為牠肚子餓!」
「非常好,Jimmy。」
從小到大,Jimmy 一直是班上第一個搶答的學生。每當老師發問,總有那麼一個小孩,無論他到底知不知道答案,都喜歡搶著回答——那就是 Jimmy。
Jimmy 是個王牌學生。他以「快速知道所有答案」為傲,考試時常常第一個寫完,是老師心目中各種學科競賽的首選。
不要當 Jimmy。
在系統設計面試中,沒思考就快速給出答案不會讓你加分。在尚未透徹理解需求之前就回答,是巨大的警訊,因為這場面試不是常識搶答賽,沒有所謂的正確答案。
所以,不要急著跳進來給解法。慢下來。深入思考,並透過提問來釐清需求與假設。這一點極其重要。
身為工程師,我們喜歡解難題、喜歡直接跳到最終設計;但這種做法很容易讓你設計出錯的系統。工程師最重要的技能之一,就是問對問題、做出適當的假設、收集建構系統所需的所有資訊。所以,不要害怕發問。
當你提出問題時,面試官要嘛直接回答,要嘛要求你自行做出假設。如果是後者,請把你的假設寫在白板或紙上,之後可能會用到。
該問哪些問題?問題的目的在於釐清確切需求。下面是一份能幫你起步的問題清單:
- 我們要打造哪些具體功能?
- 產品有多少使用者?
- 公司預期擴展速度有多快?3 個月、6 個月、1 年後預期的規模分別是多少?
- 公司的技術堆疊是什麼?有哪些現成服務可以利用以簡化設計?
範例#
如果你被要求設計一個 News Feed 系統,你會想透過提問來釐清需求。你和面試官的對話可能像下面這樣:
應徵者:這是行動 App、Web App,還是兩者都有?
面試官:兩者都有。
應徵者:產品最重要的功能是哪些?
面試官:能發文、以及看到朋友的 News Feed。
應徵者:News Feed 是按時間反序排列,還是有特定排序規則?特定排序規則的意思是每篇貼文有不同權重,例如來自親密好友的貼文比來自社團的貼文更重要。
面試官:為了簡化問題,假設 feed 是按時間反序排列。
應徵者:一個使用者最多可以有幾個朋友?
面試官:5000。
應徵者:流量規模是多少?
面試官:1,000 萬日活躍使用者(DAU)。
應徵者:feed 可以包含圖片、影片,或只能放純文字?
面試官:可以包含媒體檔案,包括圖片與影片。
以上是你可以拋給面試官的範例問題。重點是理解需求並釐清模糊之處。
步驟 2 — 提出高層設計並取得認可#
在這個步驟中,我們的目標是發展出一個高層設計,並與面試官就此達成共識。在這個過程中與面試官協作會是個好主意。
- 提出設計的初步藍圖,並徵求回饋。把面試官當隊友、一起合作。許多優秀的面試官喜歡一邊聊一邊參與。
- 在白板或紙上畫出帶有關鍵元件的方塊圖,可能包含客戶端(行動/Web)、API、Web 伺服器、資料儲存、Cache、CDN、Message Queue 等。
- 做 back-of-the-envelope 估算來評估你的藍圖是否符合規模限制。把思路說出來。在動手算之前,先和面試官確認是否有必要做這項估算。
如果可能的話,挑幾個具體場景跑一遍。這能幫你把高層設計收斂得更清楚,也很可能讓你發現尚未考慮到的邊界案例。
我們在這個步驟需要包含 API 端點與資料庫 schema 嗎?這要看題目。對於「設計 Google 搜尋引擎」這種大型題目來說,這些細節稍嫌過低層;但對於「設計多人撲克遊戲後端」這類題目來說,就很合適。請與面試官討論。
範例#
讓我們以「設計一個 News Feed 系統」為例,來示範如何切入高層設計。在此你不需要真的理解這個系統如何運作,所有細節會在「Design A News Feed System」一章中說明。
從高層來看,設計分為兩大流程:feed 發佈與 News Feed 建構。
- Feed publishing:使用者發佈貼文時,對應資料會被寫入快取/資料庫,並把貼文擴散到朋友的 News Feed 中。
- Newsfeed building:News Feed 是透過彙整朋友們的貼文,並按時間反序排列建構而成。
圖 1 與圖 2 分別呈現 feed 發佈與 News Feed 建構流程的高層設計。


步驟 3 — 設計深入探討#
到了這個階段,你和面試官應該已經達成下列共識:
- 對整體目標與功能範圍取得共識
- 已勾勒出整體設計的高層藍圖
- 從面試官那裡取得對高層設計的回饋
- 根據她的回饋對深入探討的方向有了初步想法
你應該與面試官一起識別並排序架構中的元件優先順序。值得強調的是,每場面試都不一樣。有時面試官會釋放出她偏好聚焦在高層設計的訊號;有時,特別是 senior 等級的面試,討論可能會聚焦在系統的效能特性,例如瓶頸與資源估算。但大多數情況下,面試官會希望你深入挖掘某些系統元件的細節。
舉例來說:
- 對 URL 短網址服務來說,深入探討把長 URL 轉成短 URL 的 hash 函式設計就是個有趣的方向。
- 對聊天系統來說,如何降低延遲、如何支援上線/離線狀態,是兩個值得深入的有趣主題。
時間管理至關重要,因為你很容易陷入一些無法展現你能力的瑣碎細節中。你必須帶著訊號上場、展示給面試官看。盡量別陷入不必要的細節。例如,在系統設計面試中詳細討論 Facebook feed 排名所用的 EdgeRank 演算法就不太理想,因為這會花掉寶貴時間,又無法證明你設計可擴展系統的能力。
範例#
到此為止,我們已經討論了 News Feed 系統的高層設計,面試官也對你的方案感到滿意。接下來,我們會深入探討兩個最重要的場景:
- Feed 發佈
- News Feed 取得
圖 3 與圖 4 展示了這兩個場景的詳細設計,會在「Design A News Feed System」一章詳細說明。


步驟 4 — 收尾#
在這個最後的步驟,面試官可能會問你幾個延伸問題,或是讓你自由地討論其他補充重點。以下是幾個可以延伸的方向:
- 面試官可能希望你指出系統的瓶頸並討論可能的改善方向。永遠不要說你的設計已經完美、無可改善——一定還有可以改進的地方。這是展現你批判思考能力、留下良好最終印象的好機會。
- 為面試官回顧一下你的設計也會很有幫助,尤其當你提出過好幾種方案時更是如此。在漫長的面試之後,幫面試官刷新一下記憶會很有用。
- 錯誤情境(伺服器故障、網路中斷等)是值得討論的有趣主題。
- 維運議題也值得一提:你如何監控指標與錯誤日誌?系統如何 rollout?
- 如何應對下一個規模級別也是個有趣的主題。例如,若你目前的設計支援 100 萬使用者,要支援 1,000 萬使用者需要做哪些變更?
- 提出若有更多時間還想做的其他改進。
在收尾時,我們列出該做與不該做的事項摘要。
該做#
- 永遠要請求釐清需求。不要假設你的假設一定正確。
- 理解問題的需求。
- 沒有所謂正確或最佳的答案。為一間年輕新創設計的解法,會與為一間擁有數百萬使用者的成熟公司設計的解法不同。請務必先理解需求。
- 讓面試官知道你在想什麼。與你的面試官溝通。
- 如果可能,提出多種方案。
- 一旦你和面試官就藍圖達成共識,就深入探討每個元件,並從最關鍵的元件開始設計。
- 把想法丟給面試官討論。優秀的面試官會像隊友一樣與你協作。
- 永不放棄。
不該做#
- 不要對典型面試題毫無準備。
- 不要在尚未釐清需求與假設前就跳進解法。
- 不要一開始就在單一元件上花太多細節,先給高層設計再逐步往下挖。
- 卡住時,不要猶豫,請求提示。
- 再強調一次,要溝通。不要默不作聲地思考。
- 不要以為你給出設計後面試就結束了。在面試官說結束之前,你都還沒結束。盡早並頻繁地請求回饋。
各步驟的時間分配#
系統設計面試題通常範圍很廣,45 分鐘或一小時根本不足以涵蓋整體設計。時間管理至關重要。每個步驟該花多少時間?以下是 45 分鐘面試的粗略時間分配建議。
請記住這只是粗略估計,實際分配會依問題範圍與面試官的需求而定。
- 步驟 1 理解問題並確立設計範圍:3 - 10 分鐘
- 步驟 2 提出高層設計並取得認可:10 - 15 分鐘
- 步驟 3 設計深入探討:10 - 25 分鐘
- 步驟 4 收尾:3 - 5 分鐘