這禮拜繼續讀 <System Design Interview- An insider’s guide> 第三章。
Chapter 3: 系統設計面試的框架
這章要介紹的是,如何進行一個系統設計面試。這章應該是讀到目前為止讓我最有感的一章了吧。
首先,他提到了一個重要的問題:「為什麼公司要考系統設計?」
考系統設計的原因,不是因為公司想要找到一個可以設計出 Google 搜尋引擎的完美工程師,或是一個十分精通於設計的人才。相反的,一場成功的系統設計面試可以探測到面試者的很多面向:面試者可否有效的與面試官針對某個問題進行合作,提出一個可行的解決方案?在這其中,可以觀察到面試者的協作能力、溝通能力、承受壓力的能力、以建設性方法解決問題的能力。另外,還可以看看面試者是否有透露什麼危險的訊號:是否過度設計、展現固執的個性、或是狹隘的思維?
因此,這章旨在提供一個簡單有效的框架,讓我們可以訓練自己做一個有效的問題解決者。以下,作者提出了四個步驟,並假設本次我們面對到的題目是「設計一個 news feed system」。
第一步驟:瞭解問題,並確立設計的範圍
當拿到一個問題後,切記不要馬上提出自己的答案。必須先在心裡好好思考題目的目的、釐清條件,並彙整資訊。
主要有兩個問題可以詢問。可以再針對這兩個問題的回覆,做更多細節上的詢問:
- 系統的核心功能有什麼?
- 系統的規模大小?
如果是 news feed system, 可以先詢問產品最主要的功能為何,假設回覆是「發文」,接著便可以接著詢問發文的排列順序、是否僅包含文字或允許多媒體內容、read-write ratio、consistency requirement等等。接著再針對系統規模大小詢問,比如一天流量,然後接著可以詢問使用者最多的朋友數量等等。
第二步驟:提出高階設計,並取得認可
接著,便是利用以上取得的資訊、做出初步設計的階段了。
首先可以先用一個 box diagram,畫出主要 entity 以及其關聯。主要 entity 可能有:client side, web server, db, cache, CDN, message queue 等等。也可以註記主要的 api 有哪些。
關於粗略估算的部分,作者有提到需針對提出的假說做一點估算,但讀書會的當周講者認為不太需要。我認為如果僅僅是要考驗面試者針對系統功能的規劃思路,或許估算的部分相較於決定哪些功能的使用與否確實看起來比較 minor 一點。
最後,就是使用一個具體的功能/範例,示範一下你的系統會如何運作。
這期間必須將面試官視為是你的 partner, 與他討論每一個環節,盡量取的他的回饋。
如果是 news feed system, 可以針對「發布個人動態」去畫一個 diagram, 說明從 client side開始,如何經過 load balancer, 抵達 post service, 然後存取 post cache, post database 等等。
第三步驟:深入設計
第三步驟是一個比較 tricky 的環節。當你已經釐清需求、畫好藍圖之後,面試官可以延伸問你很多問題。諸如以下(內容為讀書會講者所整理):
-
high level design: 製作 on demand new feed 的 trade-off 為何
-
技術細節:how to get friend list by graph database?
-
潛在效能問題:what if the fan-out service in new feed system cannot process new post fast enough?
-
envelop estimation (算數學環節):how many RAMs are needed for caching all news feed?
-
新需求的討論:what will happen if we need to edit page? delete page? how to do fraud detection?
第四步驟:彙整總結
這裡要特別注意的是,要留給自己 wrap up 你的方案的時間,不要花太多時間在細節、或是被面試官不小心帶走節奏。如果還有餘裕與時間,可以再額外討論的點有:
-
系統可能的瓶頸?
-
可能出錯的狀況?
-
可以觀察哪些衡量指標?
Conclusion
系統面試環節既是考驗你對不同技術的理解,也考驗你如何在有限的時間之內,流暢地提出一個問題的解方。最主要的 takeaway 如下:
- 沒有正確的答案、也沒有最好的答案,只有最適合的答案。不要背答案,盡量針對每一個問題去想一個合適的解決方法。
- 把面試官當成你的隊友,跟他討論、溝通,切記不要一個人悶頭思考。時常取得面試官的 feedback。
- 當卡住的時候,勇於跟面試官要求提示。
- 永不放棄。