[面試][系統設計]如何設計一個像 Facebook 的社交平台

本文目錄
  1. 大綱
  2. 1. 初探系統設計
  3. 1.1 Junior 跟 Senior 工程師的差異
  4. 1.2 系統設計的題目來源
  5. 1.3 面試官在找的是同事
  6. 2. 如何設計一個像 Facebook 的社交平台
  7. 2.1 縮小問題範圍,確認具體需求
  8. 2.2 先提出一個簡單的解決方案
  9. 2.3 提出可以減少耗能的可行方案
  10. 2.4 從自己擅長的面向切入
  11. 2.5 不要有預設立場
  12. 2.6 主動提出不同設計的優缺點
  13. 3. 衍伸問題
  14. 3.1 你有使用過 Mind Map 跟 Sitemap 嗎?它們的使用時機是?
  15. 筆者碎碎念
  16. 參考資源

擅長嘴砲溝通的人在這個環節有較多優勢。

其實前面 10 幾篇文章的內容都是系統設計的一環,只是問題的方向是從你過往的履歷、技術或是面試公司的需求出發,透過詢問細節來評核你技術的硬實力。

再確認求職者的硬實力過關後,有些面試官會給你一個情境來做系統設計;然後依據你在這道題目上的應對進退,決定要給你 Junior 還是 Senior 的職稱。

如果你面試的職缺是 Tech Lead,這題回答得不好有高機率直接出局。

大綱

  1. 初探系統設計
    • 1.1 Junior 跟 Senior 工程師的差異
    • 1.2 系統設計的題目來源
    • 1.3 面試官在找的是同事
  2. 如何設計一個像 Facebook 的社交平台
    • 2.1 縮小問題範圍,確認具體需求
    • 2.2 先提出一個簡單的解決方案
    • 2.3 提出減少耗能的解決方案
    • 2.4 從自己擅長的面向切入
    • 2.5 不要有預設立場
    • 2.6 主動提出不同設計的優缺點
  3. 衍伸問題
    • 3.1 你有使用過 Mind Map 跟 Sitemap 嗎?它們的使用時機是?

1. 初探系統設計

筆者在第一次遇到系統設計的問題時表現得很差,因為我把它當成一個技術性的問題,所以不停的在輸出自己的想法及觀點,面試完的當下還覺得自己表現的超棒,肯定會拿到 Offer。

果然在兩天後收到 Offer Get 的信件,但核薪結果沒有到達自己的期待;當時我並不了解自己在哪個環節犯了錯,於是向人資詢問主管對我的評價,我收到的評價是:「技術完全沒問題、經驗豐富、自我學習能力高;但在系統架構的設計上能力稍顯不足,主觀思維太多。」

在這之後我才知道面試有「系統設計」這個類型的題目,也明白當時的回答並不是面試官期待的答案。

1.1 Junior 跟 Senior 工程師的差異

Junior 工程師在看到問題後會想直接提出解決方案;而 Senior 工程師則會先釐清問題,從整體架構去思考。

會有這樣的差異是很正常的,因為 Junior 工程師在入職後,往往是接受任務分配的一方,所以他們已經習慣「收到問題 → 解決問題」的作業模式;很少人會去思考為什麼要這樣做、能不能這樣做,以至於可以完成交辦的任務,卻缺乏對整體架構的思維。

而 Senior 工程師除了要寫程式外,有時還要跟 PM 討論需求、規劃系統架構、分配工作給 Junior 工程師、幫 Junior 工程師 Debug;有些工程師討厭做這些事情,因為會耽誤到自己寫程式的時間,但正因為這些事情讓他有更完整的架構思維與溝通能力。


1.2 系統設計的題目來源

雖然系統設計的範圍很廣,但面試官愛考的就大概就是以下幾種:

  • 經典面試題
    很多面試官都是去題庫裡面找題目,我這裡也是建議讀者先熟悉題庫;透過反覆練習題庫,除了掌握基本盤外;在面對沒有接觸過的系統也能做到基本的應對進退。
  • 面試公司的系統
    有些知名企業喜歡向求職者詢問:「如果是你,會如何設計我們公司的系統?」
    這個問題除了考系統設計外,其實也是想知道求職者對面試公司的系統了解有多深。
  • 你履歷上的技能
    像是筆者在履歷上有網頁爬蟲的經歷,面試官就會以此詢問筆者:「如何設計一個網頁爬蟲的系統?」

備註:

每個面試官在意的細節都不一樣;有些題目除了要系統設計外,他還要你提供不同方案的人力資源配置、功能時程預估、所需硬體資源…,要你設計一套可以讓組織運轉的流程。

如果沒有一定的實務基礎,面對這些延伸的問題基本沒有招架之力。


1.3 面試官在找的是同事

問題走向完全看面試官的喜好,因為沒有固定的解答,所以回答是否被接受也是看你跟面試官頻率是否契合。

今天面試官要找的是同事,在確認技術過關後;他想透過這個關卡更進一步了解求職者:

  • 是否具備分析問題的能力。
  • 會經過討論再做出設計,而不是一開始就有許多預設立場。
  • 能夠清晰闡述自己的策略。
  • 溝通時雙方在同一個頻率,不會出現雞同鴨講的狀況。
  • 能評估自己提出方案的優缺點,並提出可行的優化方案。

與其說是考試,更像是同事間在討論一個議題;有時也會遇到你認為自己的方案沒問題,但面試官就是覺得不可行的狀況;此時你可以先了解面試官顧慮的點,可能真的有自己忽略的細節。

有時面試官的技術能力未必高於求職者,也許你提出的方案更好,但因為已經超過面試官知識範圍所以不被採納;此時並不建議堅持己見,你可以說:「也許有我忽略的細節,您的考慮應該是對的。」然後轉移到下一個話題。

如果你遇到一個自己完全不熟悉的領域,連回答的頭緒都沒有,請跟面試官討論你想解決的問題,並說明為什麼會卡住,千萬不要不懂裝懂瞎掰答案;多跟面試官互相分享彼此的想法,面試官自己也很清楚求職者是不可能在短時間內給出完美的答案,面對自己不熟悉的議題,就算有不會知識也是很正常的。

  • 系統設計不只是單純的考試,而是評估你在工作上會如何討論問題。
  • 雙方有來有往聊得越開心,就算你的回答有犯錯也容易被忽略。

會錄取的求職者未必技術能力最好,但絕對是在面試過程中溝通流暢的。


2. 如何設計一個像 Facebook 的社交平台

2.1 縮小問題範圍,確認具體需求

大部分主管在交代事情時,只會給一個方向,並不會把細節說清楚;所以面試官也是想透過這個問題來了解在未來交辦工作時,你會如何面對。

  • 縮小問題範圍
    Facebook 是一個經歷十幾年改版、無數菁英灌注青春與熱血的系統,它所提供的服務實在是太多了,所以要先確認問題回答的方向,比如說:「Facebook 有提供蠻多種服務的,像是發文動態、Messager、廣告系統;我們要先從哪一塊來做討論?」

  • 不要急著提出解決方案
    當年筆者沒搞清楚狀況,把它當成高流量架構設計的問題;直接丟出一堆像是 Load Balance、Repliaction、DB Sharding…的技術方案;我當時說的很開心,但回答的內容完全偏離了面試官想要了解的方向。

    使用什麼技術可以等需求確定後再討論,如果一開始在分析問題時就走偏了,那後面再多的努力也沒有用。


2.2 先提出一個簡單的解決方案

假設面試官把問題縮小到打造一個 Messager 的系統,那核心功能就非常明確;此時你只要簡單敘述設計概念就好;不要急著說出使用 Node.js + Socket.io + MongoDB 這些工具來打造系統。

  • 簡述基礎解決方案
    我們會需要一個聊天伺服器來處理訊息間的溝通,當用戶發送訊息時,訊息會先傳送到伺服器並儲存;如果接收方在線上就直接傳送訊息給他,如果不在線就透過推播通知。
    在 UI 介面上,使用者發送訊息成功時會有時間戳記;當接收方點開訊息時也會有已讀的標記。

通常考題都會涵蓋「前端、後端、資料庫」的設計;這樣面試官才能依照自己在意的點深入詢問。


2.3 提出可以減少耗能的可行方案

資源永遠是有限的,更高的硬體規格代表更多的預算,此時就需要 trade-off(權衡)。

接著讓我們從資源消耗的角度來探討 Messager 這個系統中,好友上線顯示綠燈的功能要如何設計。

最簡單的做法是當用戶一上線,就向所有好友發送上線通知;但這個設計在系統成長到百萬用戶,且特定時段上線的活躍用戶數量高達 30 萬時,這種發送通知的方法對資源的消耗極大。

  • 有什麼方式可以減輕資源消耗?
    很多人打開 Messager 只是簡單回覆訊息就關掉,所以系統其實沒必要爲剛上線的用戶立刻發送通知;我會建議把發送上線通知的策略改為顯示活躍用戶,可能要在線 5 分鐘以上再發送通知;透過減少請求的次數來降低對系統資源的消耗。

2.4 從自己擅長的面向切入

在提出基礎的解決方案後,題目就會往細節發展,此時你可以主動向面試官確認一些系統需求,假設你擅長大流量高併發的議題,你就故意問面試官:「這個系統在設計上要考量到大流量以及高併發的問題嗎?」

主動引導面試官將話題轉向自己擅長的領域是很重要的;但如果面試官對這個議題沒有興趣,千萬不要自顧自的一直講。

如果你對某個領域不擅長就不要挖坑給自己跳,假如你主動提及資料庫相關問題,面試官可能就因為你履歷上有 MySQL 跟 PostgreSQL 的經驗,而詢問你兩者的優缺點及使用時機,如果你答不出來反而會被扣分。


2.5 不要有預設立場

Messager 系統除了傳送訊息這個基礎功能外,還有建立聊天群組、回覆特定訊息、移除訊息、對訊息傳送表情符號…等眾多功能。

如果你打算在這些功能上開闢戰場,請先詢問面試官是否需要這些功能;而不是沒有經過溝通,自己覺得理所當然就直接開始設計。

經驗分享

在系統開發上,如果你要做的功能在需求規格以外,一定要先跟 PM 溝通;你認為必要的功能對客戶來說可能根本不需要,甚至系統有可能因為多出來的功能而產生無法預期的 Bug;千萬不要自作聰明。


2.6 主動提出不同設計的優缺點

如果面試官把話題帶到 DB Sharding 上面,比如:「隨著用戶成長,儲存用戶的 Table 資料量太大,效率越來越低,有什麼解決方案嗎?」

筆者會用下面的角度來回答:

考慮到用戶數量會持續成長,為了減輕資料庫的負擔,我會將這個 Table 切分到多個資料庫來分散壓力,這邊提供兩種切分策略:

  • Range-based partitioning
    第一種是挑選一個合適的欄位作為切分條件,像是以用戶的「年齡」做為切分條件;不過使用這種方式可能會造成不均勻的 Server load,因為每個年齡段的用戶數量不同。

  • Hash partitioning
    為了解決 Server load 不均勻的問題,第二種方案則是挑選一個欄位用 Hash Function 計算出一個值,用這個值來決定資料要放到哪個資料庫。

    可以採用 Consistent Hashing 讓資料均勻分布在不同 DB;這個方案在 DB 數量有增減時,也能盡量避免原有的 Key 被重新分配。

系統設計沒有標準答案,如果你有能力提出多種解決方案,並能說出各自的利弊是非常加分的。


3. 衍伸問題

3.1 你有使用過 Mind Map 跟 Sitemap 嗎?它們的使用時機是?

考點:設計系統架構時的輔助工具

  • Mind-Map
    在專案做需求訪談時,我會先透過 Mind Map 來幫助發想與記錄想法,透過這張圖即使開會偏離重點也可以快速拉回;在會後我會透過它向同事說明需求的關聯性、以及一些功能的限制條件,讓他們快速理解這個專案的目標。
  • Sitemap
    在需求明確後,我會用 Sitemap 規劃系統架構,設計頁面之間的關聯性與階層,完成流程上的模擬;並檢視規劃是否有下列問題:
    • 如果需要 SEO 的頁面被埋得太深就要重新規劃,避免 Google 爬蟲不到。

    • 檢查是否有規劃不良導致的孤兒網頁。

      孤兒網頁:系統沒有連結可以抵達的網頁。


筆者碎碎念

即使經驗豐富,面對一個從未思考過的問題,也很難提出合適的設計;這邊建議讀者可以透過以下方式,有意識地培養自己系統設計的能力:

  • 上網找題庫,吸收他人在系統設計上的經驗。
  • 找 Mentor 做模擬面試,熟悉答題方向。
  • 在閒暇時思考知名的系統是如何設計出來的(ex:Youtube、Google、Twitter…)。

感謝大家的閱讀,如果喜歡我的文章可以訂閱接收通知;如果有幫助到你,按Like可以讓我更有寫文的動力,我們明天見~

參考資源

  1. 系統設計面試 6 個技巧|我面 Google 前的準備方法
  2. 軟體工程師系統設計面試準備指南
  3. 系統設計面試(第一部分)
  4. donnemartin/system-design-primer
  5. 從 Sitemap 的應用,談 SEO 的學習


參考資源(圖 1)

在許多人的幫助下,本系列文章已成功出版,除了添加新的篇章,更完善了每個案例的應對進退;如果對現在的職涯感到迷茫,也許這本書能帶給你不一樣的觀點~

天瓏書局: https://www.tenlong.com.tw/products/9786263334571

Talk

留言討論

留言載入中…