開發一個應用並非一件難事,可是對應用的總體架構有一個深刻的瞭解確實是一件了不得的事。通常,系統設計面試題都會放在最後來考察 candidata 的更高 level 的水平。面試
系統設計可讓面試官更充分的瞭解 candidata 的全方面的水平。涉及到操做系統、網絡、模塊化、設計模式、分佈式等等系列的問題。面試官只要抓住一點感興趣的點,就能夠很快的瞭解 candidata 在這個領域的瞭解和深度。數據庫
一、首先,系統設計面試考你什麼?設計模式
答:考你對問題的分析,trade off,考你對一項技術的瞭解程度。promise
二、怎麼樣回答才比較好?微信
答:最理想的狀況是——基本題目給出來,你就可以知道這個系統的大概結構會是怎麼樣的,全部的考點分佈在哪裏。網絡
三、如何去作才能達到回答得比較好的狀況?架構
答:你得看過這些結構而且知道它全部的 tradeoff,知道它用到的全部技術等等,現場憑藉經驗想是隻有大牛才能作的活。咱們通常人仍是老老實實的學習現有的系統吧。分佈式
四、如何知道考點在哪裏?模塊化
答:想一想若是你是面試官你會問什麼?在看其餘人設計的結構的時候帶着問題去看,設想哪裏你能夠提出什麼樣的問題,這樣慢慢的你就會有體會了。
例如:系統設計要用到 message queue,大半會提到 kafka。這個時候你得知道面試官會問 kafka 什麼?他八成會問到用 kafka 有什麼問題。那麼有什麼問題呢? kafka 只保證了 at least one time delivery。因此你最好給每一個 message 加 sequence number 來防止 duplictes(是的我知道 kafka 後來 promise 了 exact one time delivery 的 feature,不過沒人用)性能
相似這樣,你得在面試官問出來以前就知道問題是啥。這是能夠作的到的。只要你老是帶着問題去看。
通常系統設計面試題的解法分爲四個步驟:
Step1:
明確需求和規範。這個是最重要的,確保你的目標清晰明確,保證接下來的任務可以分解和實施,可以確保實現你的目標。
Step2:
描繪出高層次的設計。在這個階段還沒必要去仔細描繪具體的實施細節。只須要將幾個大的模塊給肯定好,規劃出他們之間的交互就能夠了。
Step3:
評估和計算。針對不一樣用戶數量級別,不一樣性能需求的條件,來肯定後面的機器硬件配置及數量等支撐條件。
其中,系統設計有主要的三個話題:分別是 交互、存儲和 CAP 均衡。
交互:即網絡交互,是採用可靠但慢的 TCP,仍是採用不可靠可是快速的 UDP。HTTP 是在應用層,而且基於 TCP 協議。
存儲:設計到關係型數據庫,內存數據庫和分佈式數據庫等等概念。不少問題也不僅是隻能依靠某一個數據可來解決的。只要設計合理,能夠知足條件就行。
CAP均衡:根據 CAP 定理,在 consistency,availability 和 partition tolerance 上只能達到一張 trade off。那麼,看什麼,或者說學習什麼會讓你知道考點在哪裏呢?我以前跟着 Justin 老師學了 SDE 的課程,這套課程學完後,SDE 上岸須要掌握的題型基本均可以刷通關。
如何作呢?下面舉一個例子來詳細的說一下:好比說如今要設計一個 hash
第一步和第二步:
我要首先問問 requirement:
我:多少資料須要進 cache?面試官:30TB
我:expected QPS?面試官:10M
我:eviction strategy?面試官:LRU
我:Access pattern?面試官:Write Back(有空的話 Write through,Write around、write back 都要知道什麼意思,利弊等等)
我:Latency 重要嗎?面試官:cache的用途就是下降 latency
我:C or A:A(什麼是 CAP?)
第三步:
須要我本身手動簡單計算一些問題。須要多少臺機器,大概須要用什麼,storage (並非說多麼精確,可是也不要離譜)
下面是計算流程:
假設咱們如今要用 72GB RAM 4 core 的 machine
那總共以存儲 data 來講須要 30TB/72GB = 420臺
這樣的話每臺的 QPS = 10M/420 = 23000,即便全部 core 都用了,每一個 core 要處理 6000QPS
表明說 1/6000 = 167 us 搭配上面那個 Link 可知道即便是 ram sequentially read 1MB 要 250M,因此咱們若是用這個 size 的 machine 會沒法負荷
改變主意 假設如今用 16GB RAM 4 core 的 machine
30TB/16GB = 1875 臺,QPS per CPU = 10M/1875/4 = 1400 QPS = 700 us per queries。這個數字負擔小多了。
總結一下,上面的流程大概是:
先用 data constrain 算出要幾臺機器->再用 traffic constrain 算看看這樣的配置合不合理->這樣作完你就知道你的 system 是須要猛一點的機器少臺一點仍是差一點的機器多臺一點。
第四步:
畫出大致架構
見 Notes for Harvard CS75 Web Development Lecture 9 Scalability(解答系統設計中的 scale 的問題)述
第五步:
scale:
這時候小 system 畫完了,若是要 scale 的話須要什麼東西,不外乎就是 load balancer,DB 就是可能要 master-slave 或是 multi-master 這種東西
至於怎麼 fault tolerance 呢?常見的處理就是 replication,就是同樣的資料存不少地方,假設有 P 個 replication。
由於每次寫和讀都寫進/讀出這 P 個地方很是花時間,那咱們該怎麼辦呢?
假設寫的時候,只要有 W 個 replication confirm update 我就 return to user
假設讀的時候,只要有 R 個 replication 給我一個同樣的 value,我就 return 這個 value 給 user
depends on design 的 use case(這就是爲何 use case 很重要的緣由)你要看 read 跟write 哪個 operation 能夠承受高一些的 latency
若是要求 read 很快 write 能夠慢一點不要緊,那就能夠設 R=1,W=P,反之能夠設 R=P,W=1
總之,只要 R+W > N 那這 database 就是 strong consistent!若是真的要求高速度的話就必須犧牲 consistent,那 R+W 就會 < P(weak consistent)
最重要的並且並無多少人提到的,請看各個大公司的 engineer blog,是很是很是重要的。
那麼爲何要看 blog?
blog 提到的系統就是如今在生產環境的系統
blog 會提到各類 tradeoff 以及作這種設計的緣由
好的 blog 會給出各類相詳細的細節,甚至源代碼(固然你不須要閱讀源碼這麼深刻)
blog 提到的系統很容易拿來觸類旁通
舉例:[https://eng.uber.com/cherami/]
請仔細閱讀這一篇文章。若是讀懂了而且在讀的過程當中不停的問本身考點,那麼這一篇文章能夠解決不下10個不一樣的 system design 問題:如何設計一個 job queue?如何保證 job 必定執行?deadleatter 如何去設計(uber blog 裏還有單獨一篇講這個),如何設計一個分佈式爬蟲?等等問題
那麼哪裏有好的 blog?
uber、airbnb 的我都看得不少。我時間少,你能夠把大公司得都看了。
深刻看了 10 來篇高質量得就以爲融會貫通了。
但願能對你們有所幫助。
文章篇幅有限,若是你們但願更加深刻的瞭解,歡迎你們加個人微信號 L13509543893,註明來意+簡歷便可。