專欄 | 九章算法前端
網址 | www.jiuzhang.com程序員
與Coding問題不一樣的是,系統設計面試的非結構化性質會讓求職者更難作好準備。很多很優秀的國人candidate算法輪沒問題,code bug free行雲流水,但很是惋惜的敗在設計這一輪,由於得分太低而致使了整個onsite的失敗。即便有一些構建大型系統經驗的程序員也對也不必定能很好的通 過SDI,這主要是由於設計問題的開放性沒有一個標準的答案。web
今天咱們來分享一個** Twitter 軟件工程師**寫的準備系統設計的建議。面試
1.哪些公司考系統設計?算法
對於New Grads 來講,系統設計面試,佔整個面試評估的比例約爲大概是10-30%,多是項目問題/算法問題的follow up,最常常出如今加面環節。有的公司會考覈系統設計,有的公司則不會,須要根據具體公司的面經來定。Amazon、Uber的new grads面試會面到OOD和系統設計,Facebook、Google 的New Grads面試考到系統設計的機率不是很高,主要是算法爲主。建議new grads在算法準備已經比較充分、或者時間比較寬裕的狀況下,着手進行系統設計知識的補充,可展現本身在工業實踐上的知識積累,爲面試加分。sql
而對於Experienced 求職者,基本上80%以上的機率會遇到系統設計面試。建議Experienced 求職者 必定要準備系統設計面試內容。數據庫
2.大公司爲何考系統設計?json
實際工做中用到fancy的算法仍是很是少的,基本上如今市面上作web的公司實現新的feature都是利用client搭積木。可是實現功能A可能有幾個path,問題在於如何把積木搭好,而後讓系統的performace更好,latency更低,scalability, 利於maintainance和 debug,公司更賺錢,這可能須要你做爲開發這個feature的一員作出決定, take ownership。bash
固然,你須要給出最後方案的理由,說服組裏的其餘人都照着你的計劃來實施。作一個成功的產品,不少時候寫代碼一般只佔很小的一部分時間,大多數的時間應該在討論這個產品的requirement和最後站在customer的角度來看產品的功能是否是符合實際,讓用戶喜歡。這裏的customer不只是傳統意義上的付費用戶,也多是一個公司裏面別的team使用你開發工具的人,以及同一個組裏面未來維護你code的同事。沒有任何一個程序員願意維護shitty code。服務器
因此,系統設計這一輪在面試裏面每每佔的比重很大,實際上也是在考察在短期內,你能不能做爲一個feature的owner自圓其說,權衡利弊,給公司給客戶設計一個"能用"的feature。因而,咱們也時常能聽到經典的好比設計一個fb online chat, google calendar之類的題目。
3.系統設計面試是什麼?
系統設計問題已成爲軟件工程面試過程當中的一個標準部分,但SDI超出了測試傳統編碼、技術和分析技能的範圍。系統設計面試的主要目的是讓應聘者有機會展現本身的知識,面試官會測試他們在動態、不可預測的狀況下是如何工做的,以及如何解決一些棘手的問題。
面試中,應聘者將不會遇到能夠運行或編譯的編碼問題,還常常會被問到一些公開的問題,好比設計一個新的、大規模的分佈式系統,好比youtube,另外一個社交平臺,一個URL縮短服務等等...面試官會要求你可以去解決一個開放的問題,相似於若是你是一名軟件工程師,你所要作的規劃和結構的類型是什麼?
4.你要知道,在SDI中,面試官主要考察你的哪些方面?
在SDI過程當中,相當重要的是始終保持開放的通訊線路,面試官會重點考察你是如何處理動態的,開放的工程狀況的。展開來講,你的面試結果是被以下因素所評估決定的:
你儲備的知識:博學實用
你表達思想的能力:和領導談話,與面試官討論高層次的組件、細節、設計利弊以及其餘相關信息的表達能力。
你的運做效率:你是否按照最佳作法步驟工做,例如:
A.需求收集:澄清不明確之處,並肯定系統最終目標,以評估手頭問題或任 務的確切範圍。
B.系統接口定義:肯定和定義任何預期的系統API。
C.系統規模估計:確保您知道系統的範圍。
D.數據模型定義:澄清數據將如何在不一樣的系統組件之間流動,並可以更好地進行數據劃分和管理。
E.高級別設計:肯定從端到端解決SDI問題所需的組件,首先是基礎層次,而後是更深層次。
F.查明和解決瓶頸:肯定如何最有效地減輕其影響。
複製代碼
你的更新和改進能力:一旦你設計了這個系統,你將如何不斷地工做以使它變得更好?
除此之外,你的面試官也可能想看看你是否具有:技能和能力抽象、數據庫、聯網、併發、估計、可用性和可靠性。
5.你要掌握的系統設計面試中最多見的問題?
1.設計TinyURL或bity(URL縮短服務)
2.設計YouTube,Netflix或Twitch(全球視頻流服務)
3.設計Facebook Messenger或WhatsApp(全球聊天服務)
4.設計Quora或Reddit或HackerNews(社交網絡+留言板服務)
5.設計Dropbox或Google Drive或Google Photos(全球文件存儲和共享服務)
6.設計Facebook,Twitter或Instagram(擁有數億用戶的社交媒體服務)
7.設計Uber或Lyft(乘車共享服務)
8.設計Web爬蟲或預先輸入(搜索引擎相關服務)
9. 設計API速率限制器(例如,用於Firebase或Github)
10.設計Yelp或附近的地方/朋友(接近服務器)
複製代碼
6.面試時,你應該去注意哪些問題?
1. 問清楚問題
系統設計面試的核心目標是給候選人一個展現他們知識的機會。沒有絕對正確或錯誤的答案。一個好的系統設計問題一般聽起來很是模糊,緣由是它應該給您一個演示如下內容的機會:
1.你會如何看待問題空間
2.你如何看待瓶頸
3.你能作些什麼來消除這些瓶頸
複製代碼
例如,若是我如今要求你設計Twitter,你會怎麼作?
2.利用你的背景
求職者在面試中容易犯的一個問題:去試圖弄清楚面試官想問什麼,而後迎合他們的反應以知足他們的指望。事實上,這樣反而不利於自我表現,緣由有幾點:
l.每一個人都有本身獨特的背景。在系統設計面試中,這是一個展現本身優點的機會。不要浪費時間去想別人對你的指望。
2.面試官可能會對你的回答點頭,但他們可能知道你只是在虛張聲勢,並無真正考慮問題。
複製代碼
你的經驗和背景可能與下一個候選人大不相同。你把一套價值觀和專業知識帶到桌子上,這是其餘人都作不到的。這就是使你有價值和不可替代的緣由。無論你在哪一個領域,面試官都關心你或者大家能夠把什麼帶到桌子上來。
3. 系統地解決問題
當你在面對一個新系統,或者即將構建一個新系統的時候,你須要注意如下幾點:
l.系統的目標是什麼?
2.誰是系統的用戶?
3.咱們的工做規模是多少?
4.這是一種新/舊的制度嗎?咱們如何處理版本控制?
複製代碼
這一套標準不一樣於前端工程師的那套標準。你能夠嘗試用這些標準在腦海中描繪出一幅圖畫,條理清晰的去完成你的構建和決策過程。
7.你必需要知道的面試中系統設計的關鍵點?
明白了爲何考察系統設計,關鍵點就很容易列出了:
1.產品的requirement是什麼?
不少candidate常犯的錯誤就是拿到題目誇誇其談,羅列概念詞彙。好比我這個系統要有app server,要有load balancer,要用 nosql 數據庫。這實際上是一個本末倒置的思考方向,從技術到功能,而不是從功能到技術。
咱們首先要問本身,爲何要設計這個產品?假設咱們忘掉全部如今的技術,假如咱們是最後這個產品的使用者,咱們須要這個產品具有什麼功能?好比google calendar,咱們要能create personal calendar;咱們要能book time slot,而且time slot要能夠設置不一樣的權限,對不一樣的group顯示不一樣的內容;time slot要能解決event conflict的問題;若是一個用戶能夠create多個canlander,這些calendar可以confict嗎?用戶能夠tag calendar嗎? 怎麼作calendar third party integration?
有了這些想法,剩下的時間就是和麪試官討論其中的一個或者多個功能的實現。討論requirement的過程就是一個交流的過程,你也能夠從交流中獲得面試官的喜愛,而後實現他想要看到的功能。面試開始的頭幾分鐘,其實就是一個頭腦風暴的過程,從點到面,再收回到點。不少candidate缺乏這一個過程,很容易留下communication不足,缺乏detail的印象。
好了,和麪試官討論好具體實現的功能,那麼再描述一個總體的flow。咱們能夠在白板上畫出sequence chart, 什麼是request, 什麼是response。 request裏面有哪些信息?做爲一個client我須要你返回什麼信息?簡而述之,就是把上面的功能討論抽象成一個一個的service。這時候,若是知道如何serialize這些data,好比用json,avro,知道如何在network中對data進行encryption,checksum....這些都是加分點
有了這些,進一步的能夠再談如何儲存這些data,以及這些data之間的關係是什麼樣的,這些API怎麼interact?怎麼樣optimize這些API?再選取世面上的技術就變得理所固然。
2.如何把積木搭好?
有了產品的flow,剩下的就是如何讓performace更好,latency更低,scalability。假設咱們如今產品只有10個用戶,咱們可能只用一臺機器,可是當用戶x 1k後,咱們的瓶頸又在哪裏呢?假設你是這個feature的owner,你可能會遇到哪些問題?好比IO, CPU? 怎麼處理exception?可能咱們一開始爲了快速迭代快糙猛什麼都是sequential,後來須要queuing task,batch write以解決database的IO問題,可能最後再加個Kafka來作streaming,run hadoop 來作offline computation。到這一步咱們可能須要站在稍微高一些的角度來解決user growth pain。這一部分可能須要平時看engineering blog或者視頻對目前的技術作一些學習積累了。
3.take ownership
不少candidate可以提供一個reasonable的solution,可是一般沒有辦法比較不一樣solution的trade off。不少時候面試官更在意的是思考的過程,在不一樣的solution中爲何選A而不選B,或者換句話說,何時選A好, 可是換一個環境之後選B更reasonable? 你有什麼論據來論證你的觀點呢? 好比,咱們要多少的資源存儲那些data,咱們的data center爲何要建在地點A而不是地點B呢?若是須要更新功能,咱們怎麼合理的設置好AB testing? 面試的過程裏面,不會指望 candidate瞭解全部的tech stack,包括面試官在某些方面也必定比你瞭解得少,可是你要始終把此次面試討論的問題當作平常工做中討論的一個部分,事實上,工做的時候也是如此。
遇到一些表現特別出色的candidate,他們有時候具體討論到如何設置service alert以及他們想到實際中可能會出現的一些意外的解決方法,這很是能impress到面試官。Nobody wants to figure out how to handle the accidents in the early morning.
8.其它面試的加分點?
1.利用好白板。 one picture is worth 1000000 words. 善用不一樣顏色的馬克筆,字寫好 。
2.把握面試的主動權,不要讓面試變成Q&A 。
3.瞭解公司的一些open source project或者有名的產品。不瞭解公司來面着幹嗎 ?
4.不要過多 challenge 面試官
5.把抽象的問題具體化站在系統的角度來優化功能。
複製代碼