系統(tǒng)設(shè)計(jì)面試的萬金油
萬金油: 比喻什么都能做,但什么都不擅長

系統(tǒng)設(shè)計(jì)是面試當(dāng)中的一個(gè)常考點(diǎn),是面試官考察面試者知識(shí)廣度與深度最直接的方式。
許多開發(fā)者在系統(tǒng)設(shè)計(jì)面試中痛苦主要是因?yàn)橄旅嫒齻€(gè)原因
1.系統(tǒng)設(shè)計(jì)面試屬于開放性問題,沒有一個(gè)標(biāo)準(zhǔn)的答案2.缺乏開發(fā)大規(guī)模系統(tǒng)的經(jīng)驗(yàn)3.對(duì)系統(tǒng)設(shè)計(jì)問題沒有準(zhǔn)備
就像代碼面試一樣,那些沒有有意識(shí)地為系統(tǒng)設(shè)計(jì)面試做準(zhǔn)備的求職者,大多表現(xiàn)不佳,尤其是在谷歌、Facebook、亞馬遜、微軟等頂級(jí)公司的面試中。在這些公司中,表現(xiàn)不佳的求職者得到錄用的機(jī)會(huì)非常有限。另一方面,良好的表現(xiàn)總是會(huì)帶來更好的待遇,因?yàn)檫@顯示了候選人處理復(fù)雜系統(tǒng)的能力。
第一步 需求分析
對(duì)我們要解決的問題確切范圍并且提出問題。設(shè)計(jì)類問題大多是開放式的,它們沒有一個(gè)正確的答案,這就是為什么在面試中盡早澄清模棱兩可的問題變得至關(guān)重要?;ㄗ銐驎r(shí)間定義系統(tǒng)最終目標(biāo)的候選人總是有更好的機(jī)會(huì)在面試中取得成功,此外,由于我們只有35-40分鐘的時(shí)間來設(shè)計(jì)一個(gè)大型系統(tǒng),我們應(yīng)該明確我們將重點(diǎn)關(guān)注系統(tǒng)的哪些部分。
讓我們用一個(gè)設(shè)計(jì)類似twitter的服務(wù)來擴(kuò)展這一點(diǎn)。以下是一些設(shè)計(jì)Twitter時(shí)應(yīng)該首先明確的問題。
?用戶能夠發(fā)布推文并關(guān)注其他人嗎??我們應(yīng)該設(shè)計(jì)創(chuàng)建和顯示用戶的時(shí)間軸嗎??推文會(huì)包含照片和視頻嗎??我們是只關(guān)注后端還是也開發(fā)前端??用戶能夠搜索推文嗎??我們需要展示熱門話題嗎??我們需要設(shè)計(jì)新的(或重要的)推文推送通知嗎?
這些問題將會(huì)決定我們的系統(tǒng)最終設(shè)計(jì)會(huì)是什么樣子。
第二步 系統(tǒng)接口定義
定義系統(tǒng)所需要的API,這不僅可以建立系統(tǒng)預(yù)期的確切規(guī)范,而且還可以確保我們沒有弄錯(cuò)任何要求。下面是我們類似Twitter服務(wù)的一些接口示例:
postTweet(user_id, tweet_data, tweet_location, user_location, timestamp, ...)
generateTimeline(user_id, current_time, user_location, ...)
markTweetFavorite(user_id, tweet_id, timestamp, ...)
第三步 規(guī)模估計(jì)
估計(jì)我們要設(shè)計(jì)的系統(tǒng)的規(guī)模,有助于我們以后關(guān)注擴(kuò)展、分區(qū)、負(fù)載平衡和緩存。
?系統(tǒng)的預(yù)期規(guī)模(例如,新推文的數(shù)量,推文的瀏覽數(shù)量,每秒鐘時(shí)間軸的生成數(shù)量,等等)?我們需要多少存儲(chǔ)空間? 如果用戶可以在推特上上傳照片和視頻,我們會(huì)有不同預(yù)期的存儲(chǔ)空間。?我們期望的網(wǎng)絡(luò)帶寬使用量是多少? 這對(duì)于決定我們將如何管理流量和平衡服務(wù)器之間的負(fù)載至關(guān)重要。
第四步 定義數(shù)據(jù)模型
盡早定義數(shù)據(jù)模型將闡明數(shù)據(jù)如何在系統(tǒng)的不同組件之間流動(dòng)。之后,它將指導(dǎo)數(shù)據(jù)分區(qū)和管理。候選人應(yīng)該能夠識(shí)別系統(tǒng)的各種實(shí)體,它們將如何相互作用,以及數(shù)據(jù)管理的不同方面,如存儲(chǔ)、傳輸、加密等。這里有一些我們的Twitter服務(wù)的實(shí)體定義。
User: UserID, Name, Email, DoB, CreationData, LastLogin, etc. Tweet: TweetID, Content, TweetLocation, NumberOfLikes, TimeStamp, etc. UserFollowo: UserdID1, UserID2 FavoriteTweets: UserID, TweetID, TimeStamp
我們應(yīng)該使用哪個(gè)數(shù)據(jù)庫系統(tǒng)? 像Cassandra這樣的NoSQL是否最適合我們的需求,或者我們應(yīng)該使用類似mysql的解決方案? 我們應(yīng)該使用什么樣的塊存儲(chǔ)來存儲(chǔ)照片和視頻?
第五步 高層次設(shè)計(jì)
用5-6個(gè)框圖表示我們系統(tǒng)的核心組件。我們應(yīng)該確定從端到端解決實(shí)際問題所需的足夠多的組件。對(duì)于Twitter,在較高級(jí)別上,我們將需要多個(gè)應(yīng)用程序服務(wù)器來處理所有讀/寫請(qǐng)求,并在它們前面使用負(fù)載均衡器進(jìn)行流量分配。如果我們假設(shè)我們將有更多的讀取流量(與寫入相比),我們可以決定使用單獨(dú)的服務(wù)器來處理這些場景。在后臺(tái),我們需要一個(gè)高效的數(shù)據(jù)庫來存儲(chǔ)所有的tweet并支持大量的讀取。我們還需要一個(gè)分布式文件存儲(chǔ)系統(tǒng)來存儲(chǔ)照片和視頻。
第六步 詳細(xì)設(shè)計(jì)
深入挖掘系統(tǒng)的兩三個(gè)組件,根據(jù)面試官的反饋來確定面試官更關(guān)心系統(tǒng)中哪部分的實(shí)現(xiàn),并且進(jìn)行進(jìn)一步的討論。我們應(yīng)該能夠提出不同的方法,它們的優(yōu)缺點(diǎn),并解釋為什么我們更喜歡一種方法而不是另一種方法。記住,沒有單一的答案,唯一重要的事情是考慮不同選項(xiàng)之間的權(quán)衡,同時(shí)牢記系統(tǒng)約束。
?由于我們將存儲(chǔ)大量的數(shù)據(jù),我們應(yīng)該如何劃分?jǐn)?shù)據(jù)以將其分布到多個(gè)數(shù)據(jù)庫?我們是否應(yīng)該嘗試將一個(gè)用戶的所有數(shù)據(jù)存儲(chǔ)在同一個(gè)數(shù)據(jù)庫中?它會(huì)引起什么問題呢??我們將如何處理推特或關(guān)注很多人的熱門用戶??既然用戶的時(shí)間線將包含最新的(和相關(guān)的)tweets,我們是否應(yīng)該嘗試以一種優(yōu)化的方式存儲(chǔ)我們的數(shù)據(jù),以掃描最新tweets??我們應(yīng)該在哪個(gè)層引入多少緩存來加速呢??哪些組件需要更好的負(fù)載平衡?
第七步 瓶頸問題
嘗試討論盡可能多的瓶頸和不同的方法來緩解它們。
?我們的系統(tǒng)有單點(diǎn)故障嗎? 我們要做什么來減輕它??我們是否有足夠的數(shù)據(jù)副本,以便在失去一些服務(wù)器時(shí)仍能為用戶提供服務(wù)。?類似地,我們是否有足夠多的不同服務(wù)的副本在運(yùn)行,以便一些故障不會(huì)導(dǎo)致整個(gè)系統(tǒng)關(guān)閉。?我們?nèi)绾伪O(jiān)控服務(wù)的表現(xiàn)? 當(dāng)關(guān)鍵組件出現(xiàn)故障或性能下降時(shí),我們是否會(huì)收到警報(bào)。
總結(jié)
總之,面試過程中的有準(zhǔn)備和有組織是系統(tǒng)設(shè)計(jì)面試成功的關(guān)鍵。上述步驟將指導(dǎo)您在設(shè)計(jì)系統(tǒng)時(shí)保持跟蹤并涵蓋系統(tǒng)設(shè)計(jì)的不同方面。
References
[1] 《System Design Interview》: https://book.douban.com/subject/35246417/
