面試筆試經驗技巧篇

想找到一份程序員的工做,一點技術都沒有顯然是不行的,可是,只有技術 也是不夠的。前端

面試筆試經驗技巧篇主要針對程序員面試筆試中遇到的 13 個常見 問題進行深度解析,而且結合實際情景,給出了一個較爲合理的參考答案以供讀 者學習與應用,掌握這 13 個問題的解答精髓,對於求職者大有裨益。node

 

經驗技巧 1   如何巧妙地回答面試官的問題?程序員

     所謂「來者不善,善者不來」,程序員面試中,求職者不可避免地須要回答面試官各類 刁鑽、犀利的問題,回答面試官的問題千萬不能簡單地回答「是」或者「不是」,而應該具 體分析「是」或者「不是」的理由。 回答面試官的問題是一門很深刻的學問。面試

    那麼,面對面試官提出的各種問題,如何才能 條理清晰地回答呢?如何才能讓本身的回答不至於撞上槍口呢?如何才能讓本身的回答結 果令面試官滿意呢? 談話是一種藝術,回答問題也是一種藝術,一樣的話,不一樣的回答方式,每每也會產生 出不一樣的效果,甚至是大相徑庭的效果。在此,編者提出如下幾點建議,供讀者參考。算法

    首先 回答問題務必謙虛謹慎。既不能讓面試官以爲本身很自卑,惟惟諾諾,也不能讓面試官以爲 本身清高自負,而應該經過問題的回答表現出本身自信從容、不卑不亢的一面。數據庫

    例如,當面 試官提出「你在項目中起到了什麼做用」的問題時,若是求職者回答:我完成了團隊中最難 的工做,此時就會給面試官一種居功自傲的感受,而若是回答:我完成了文件系統的構建工 做,這個工做被認爲是整個項目中最具備挑戰性的一部份內容,由於它幾乎沒法重用之前的 框架,須要從新設計。這種回答不只不傲慢,反而有理有據,更能打動面試官。編程

    其次,回答面試官的問題時,不要什麼都說,要適當地留有懸念。人通常都有獵奇的心 理,面試官天然也不例外,並且,人們每每對好奇的事情更有興趣、更加偏心,也更加記憶 深入。因此,在回答面試官問題時,切記說關鍵點而非細節,說重點而非和盤托出,經過關 鍵點,吸引面試官的注意力,等待他們繼續「刨根問底」。例如,當面試官對你的簡歷中一 個算法問題有興趣,但願瞭解時,能夠以下回答:我設計的這種查找算法,對於 80%以上的 狀況,均可以將時間複雜度從 O(n)下降到 O(log n),若是您有興趣,我能夠詳細給您分析具 體的細節。後端

   最後,回答問題要條理清晰、簡單明瞭,最好使用「三段式」方式。所謂「三段式」, 有點相似於中學做文中的寫做風格,包括「場景/任務」「行動」和「結果」三部份內容。 以面試官提的問題「你在團隊建設中,遇到的最大挑戰是什麼」爲例,設計模式

   第一步,分析場景 /任務:在我參與的一個 ERP 項目中,咱們團隊一共四我的,除了我之外的其餘三我的中, 兩我的能力很給力,人也比較好相處,但有一我的卻不太好相處,每次咱們小組討論問題 的時候,他都不太愛說話,也不多發言,分配給他的任務也很難完成。數組

   第二步,分析行動: 爲了提升團隊的綜合實力,我決定找個時間和他好好單獨談一談。因而我利用週末時間, 約他一塊兒吃飯,吃飯的時候,順便討論了一下咱們的項目,我詢問了一些項目中他遇到的 問題,經過他的回答,我發現他並不懶,也不糊塗,只是對項目不太瞭解,缺少經驗,缺 乏自信而已,因此愈來愈孤立,愈來愈不肯意討論問題。爲了解決這個問題,我嘗試着把 問題細化到他能夠完成的程度,從而創建起他的自信心。

   第三步,分析結果:他是小組中 水平最弱的人,可是,慢慢地,他的技術變得愈來愈厲害了,也可以按時完成安排給他的 工做了,人也愈來愈自信了,也愈來愈喜歡參與咱們的討論,並發表本身的見解,咱們也 都願意與他一塊兒合做了。「三段式」回答的一個最明顯的好處就是條理清晰,既有描述,也 有結果,有根有據,讓面試官一目瞭然。 回答問題的技巧,是一門大的學問。求職者徹底能夠在平時的生活中加以練習,提升自 己與人溝通的技能,等到面試時,天然就駕輕就熟了。 

經驗技巧 2  如何回答技術性的問題? 

    程序員面試中,面試官會常常詢問一些技術性的問題,有的問題可能比較簡單,都是歷 年的筆試面試真題,求職者在平時的複習中會常常遇到,應對天然不在話下。但有的題目可 能比較難,來源於 Google、Microsoft 等大企業的題庫或是企業本身爲了招聘須要設計的題 庫,求職者可能歷來沒見過或者歷來都不能完整地、獨立地想到解決方案,而這些題目每每 又是企業比較關注的。 如何可以回答好這些技術性的問題呢?編者建議:會作的必定要拿滿分,不會作的必定 要拿部分分。即對於簡單的題目,求職者要努力作到徹底正確,畢竟這些題目,只要複習得 當,徹底回答正確一點問題都沒有(編者認識的一個朋友聽說把《編程之美》、《編程珠璣》、 《程序員面試筆試寶典》上面的技術性題目與答案全都背得倒背如流了,後來找工做簡直成 了「offer 殺器」,徹底就是一個 Bug,無解了);對於難度比較大的題目,不要驚慌,也不要 懼怕,即便沒法徹底作出來,也要努力思考問題,哪怕是半成品也要寫出來,至少要把本身 的思路表達給面試官,讓面試官知道你的想法,而不是徹底回答不會或者放棄,由於面試官 不少時候除了關注你的獨立思考問題的能力之外,還會關注你技術能力的可塑性,觀察求職 者是否可以在別人的引導下去正確地解決問題,因此,對於你不會的問題,他們頗有可能會 按部就班地啓發你去思考,經過這個過程,讓他們更加了解你。 通常而言,在回答技術性問題時,求職者大可沒必要膽戰心驚,除非是沒學過的新知識, 不然,通常均可以採用如下六個步驟來分析解決。

     (1)敢於提問 面試官提出的問題,有時候可能過於抽象,讓求職者不知所措,或者無從下手,因此, 對於面試中的疑惑,求職者要勇敢地提出來,多向面試官提問,把不明確或二義性的狀況都 問清楚。不用擔憂你的問題會讓面試官煩惱,影響你的面試成績,相反還對面試結果產生積 極影響:一方面,提問可讓面試官知道你在思考,也能夠給面試官一個心思縝密的好印象; 另外一方面,方便後續本身對問題的解答。 例如,面試官提出一個問題:設計一個高效的排序算法。求職者可能丈二和尚摸不到頭 腦,排序對象是鏈表仍是數組?數據類型是整型、浮點型、字符型仍是結構體類型?數據基 本有序仍是雜亂無序?數據量有多大,1000 之內仍是百萬以上個數?此時,求職者大能夠 將本身的疑問提出來,問題清楚了,解決方案也天然就出來了。

     (2)高效設計 對於技術性問題,如何才能打動面試官?完成基本功能是必須的,僅此而已嗎?顯然不 是,完成基本功能頂多只能算及格水平,要想達到優秀水平,至少還應該考慮更多的內容, 以排序算法爲例:時間是否高效?空間是否高效?數據量不大時也許沒有問題,若是是海量 數據呢?是否考慮了相關環節,例如數據的「增刪改查」?是否考慮了代碼的可擴展性、安 全性、完整性以及魯棒性?若是是網站設計,是否考慮了大規模數據訪問的狀況?是否須要 考慮分佈式系統架構?是否考慮了開源框架的使用?

     (3)僞代碼先行 有時候實際代碼會比較複雜,上手就寫頗有可能會漏洞百出、條理混亂,因此,求職者 能夠首先徵求面試官的贊成,在編寫實際代碼前,寫一個僞代碼或者畫好流程圖,這樣作往 往會讓思路更加清晰明瞭。 切記在寫僞代碼前要告訴面試官,他們頗有可能對你產生誤解,認爲你只會紙上談兵, 實際編碼能力卻不行。只有徵得了他們的容許,方可先寫僞代碼。

    (4)控制節奏 若是是算法設計題,面試官都會給求職者一個時間限制用以完成設計,通常爲 20min 左 右。完成得太慢,會給面試官留下能力不行的印象,但完成得太快,若是不能保證百分百正 確,也會給面試官留下毛手毛腳的印象,速度快固然是好事情,但只有速度,沒有質量,速 度快根本不會給面試加分。因此,編者建議,回答問題的節奏最好不要太慢,也不要太快, 若是實在是完成得比較快,也不要急於提交給面試官,最好可以利用剩餘的時間,認真仔細 地檢查一些邊界狀況、異常狀況及極性狀況等,看是否也能知足要求。     (5)規範編碼 回答技術性問題時,多數都是紙上寫代碼,離開了編譯器的幫助,求職者要想讓面試官 對本身的代碼一看即懂,除了字跡要工整,不能眉飛色舞之外,最好是可以嚴格遵循編碼規 範:函數變量命名、換行縮進、語句嵌套和代碼佈局等,同時,代碼設計應該具備完整性, 保證代碼可以完成基本功能、輸入邊界值可以獲得正確地輸出、對各類不合規範的非法輸入 可以作出合理的錯誤處理,不然,寫出的代碼即便無比高效,面試官也不必定看得懂或者看 起來很是費勁,這些對面試成功都是很是不利的。

    (6)精心測試 在軟件界,有一句真理:任何軟件都有 bug。但不能由於如此就縱容本身的代碼, 容許錯誤百出。尤爲是在面試過程當中,實現功能也許並不十分困難,困難的是在有限的 時間內設計出的算法,各類異常是否都獲得了有效的處理,各類邊界值是否都在算法設 計的範圍內。 測試代碼是讓代碼變得完備的高效方式之一,也是一名優秀程序員必備的素質之一。所 以,在編寫代碼前,求職者最好可以瞭解一些基本的測試知識,作 一些基本的單元測試、功 能測試、邊界測試以及異常測試。 在回答技術性問題時,注意在思考問題的時候,千萬別一句話都不說,面試官面試 的時間是有限的,他們但願在有限的時間內儘量地去了解求職者,若是求職者坐在那 裏一句話不說,不只會讓面試官以爲求職者技術水平不行,思考問題能力以及溝通能力 可能都存在問題。 其實,在面試時,求職者每每會存在一種思想誤區,把技術性面試的結果看得過重要了。 面試過程當中的技術性問題,結果當然重要,但也並不是最重要的內容,由於面試官看重的不只 僅是最終的結果,還包括求職者在解決問題的過程當中體現出來的邏輯思惟能力以及分析問題 的能力。因此,求職者在與面試官的博弈中,要適當地提問,經過提問獲取面試官的反饋信 息,並抓住這些有用的信息進行輔助思考,從而博得面試官的歡心,進而提升面試的成功率。 

經驗技巧 3   如何回答非技術性問題? 

    評價一我的的能力,除了專業能力,還有一些非專業能力,如智力、溝通能力和反應能 力等,因此在 IT 企業招聘過程的筆試面試環節中,並不是全部的筆試內容都是 C/C++、數據 結構與算法及操做系統等專業知識,也包括其餘一些非技術類的知識,如智力題、推理題和 做文題等。技術水平測試能夠考查一個求職者的專業素養,而非技術類測試則更增強調求職 者的綜合素質,包括數學分析能力、反應能力、臨場應變能力、思惟靈活性、文字表達能力 和性格特徵等內容。考查的形式多種多樣,但與公務員考查類似,主要包括行測(佔大多數)、 性格測試(大部分都有)、應用文和開放問題等內容。 每一個人都有本身的答題技巧,答題方式也各不相同,如下是一些相對比較好的答題技巧 (以行測爲例):

      1)合理有效的時間管理。因爲題目的難易不一樣,因此不要對全部題目都「絕對的公 平」、都「一刀切」,要有輕重緩急,最好的作法是不按順序回答。行測中有各類題型,

如數量關係、圖形推理、應用題、資料分析和文字邏輯等,而不一樣的人擅長的題型是不 同樣的,所以應該首先回答本身最擅長的問題。例如,若是對數字比較敏感,那麼就先 答數量關係。

      2)注意時間的把握。因爲題量通常都比較大,能夠先按照總時間/題數來計算每道題的 平均答題時間,如 10s,若是看到某一道題 5s 後還沒思路,則立刻放棄。在作行測題目的時 候,以在最短的時間內拿到最多分爲目標。

      3)平時多關注圖表類題目,培養迅速抓住圖表中各個數字要素間相互邏輯關係的能力。

      4)作題要集中精力,只有集中精力、全神貫注,才能將本身的水平最大限度地發揮        出來。

      5)學會關鍵字查找,經過關鍵字查找,可以提升作題效率。

      6)提升估算能力,有不少時候,估算可以極大地提升作題速度,同時保證正確率。 除了行測之外,一些企業很是相信我的性格對入職匹配的影響,因此都會引入相關的性 格測試題用於測試求職者的性格特性,看其是否適合所投遞的職位。大多數狀況下,只要按 照本身的真實想法選擇就好了,不要弄巧成拙,由於測試是爲了得出正確的結果,因此大多 測試題先後都有相互驗證的題目。若是求職者自做聰明,選擇該職位可能要求的性格選項,則 極可能致使測試先後不符,這樣很容易讓企業發現你是個不誠實的人,從而首先予以篩除。 

經驗技巧 4   如何回答快速估算類問題? 

     有些大企業的面試官,總喜歡使一些「陰招」「損招」,出一些快速估算類問題,對他們 而言,這些問題只是手段,不是目的,可以獲得一個滿意的結果當然是他們所須要的,但更 重要的是經過這些題目他們能夠考查求職者的快速反應能力以及邏輯思惟能力。因爲求職者 平時準備的時候可能對此類問題有所遺漏,一時很難想起解決的方案。

     並且,這些題目乍一 看確實是毫無頭緒,無從下手,徹底就是坑求職者的,其實求職者只要從惶恐不安中冷靜下 來,稍加分析,也就那麼回事。由於此類題目比較靈活,屬於開放性試題,通常沒有標準答 案,只要弄清楚了回答要點,分析合理到位,具備說服力,可以自圓其說,就是正確答案, 一點都不困難。

     例如,面試官可能會問這樣一個問題:「請你估算一下一家商場在促銷時一天的營業 額?」,求職者又不是統計局官員,如何可以得出一個準確的數據呢?求職者家又不是開商 場的,如何可以得出一個準確的數據呢?即便求職者是商場的大當家,也不可能弄得清清楚 楚明明白白吧? 難道此題就無解了嗎?其實否則,本題只要可以分析出一個概數就好了,不必定要精確 數據,而分析概數的前提就是作出各類假設。

     以該問題爲例,能夠嘗試從如下思路入手:從 商場規模、商鋪規模入手,經過每平方米的租金,估算出商場的日租金,再根據商鋪的成本 構成,獲得全商場日均交易額,再考慮促銷時的銷售額與平時銷售額的倍數關係,乘以倍數, 便可獲得促銷時一天的營業額。具體而言,包括如下估計數值:

        1)以一家較大規模商場爲例,商場通常按 6 層計算,每層大約長 100m,寬 100m,合 計 60000m2的面積。

        2)商鋪規模佔商場規模的一半左右,合計 30000m2。

        3)商鋪租金約爲 40 元/ m2,估算出年租金爲 40×30000×365=4.38 億。

        4)對商戶而言,租金通常佔銷售額 20%左右,則年銷售額爲 4.38 億×5=21.9 億。計算 平均日銷售額爲 21.9 億/365=600 萬。

        5)促銷時的日銷售額通常是平時的 10 倍,因此大約爲 600 萬*10=6000 萬。

    此類題目涉及面比較廣,例如:估算一下北京小吃店的數量?估算一下中國在過去一年方便麪的市場銷售額是多少?估算一下長江的水的質量?估算一下一個行進在小雨中的人 5min 內身上淋到的雨的質量?估算一下東方明珠電視塔的質量?估算一下中國去年一年一 共用掉了多少塊尿布?估算一下杭州的輪胎數量?但通常都是即興發揮,不是哪道題記住答 案就能夠應付得了的。遇到此類問題,一步步抽絲剝繭,纔是解決之道。 

 

經驗技巧 5  如何回答算法設計問題? 

    程序員面試中的不少算法設計問題,都是歷年來各家企業的「炒現飯」,無論求職者以 前對算法知識學習得是否紮實,理解得是否深刻,只要面試前買本《程序員面試筆試寶典》 (編者早前編寫的一本書,由機械工業出版社出版),學習上一段時間,牢記於心,應付此類 題目徹底沒有問題,但遺憾的是,不少世界級知名企業也深知這一點,若是純粹是出一些毫 無技術含量的題目,對於考前「突擊手」而言,可能會佔盡便宜,但對於那些技術好的人而 言是很是不公平的。因此,爲了把優秀的求職者與通常的求職者可以更好地區分開來,他們 會年年推陳出新,愈來愈傾向於出一些有技術含量的「新」題,這些題目以及答案,再也不是 之前的陳穀子爛芝麻了,而是通過精心設計的好題。

    在程序員面試中,算法的地位就如同是 GRE 或托福考試在出國留學中的地位同樣,必 須但不是最重要的,它只是衆多考覈方面中的一個而已,不必定就能決定求職者的生死。雖 然如此,但並不是說就不用去準備算法知識了,由於算法知識回答得好,必然會成爲面試的加 分項,對於求職成功,百利而無一害。那麼如何應對此類題目呢?很顯然,編者不可能將此 類題目都在《程序員面試筆試寶典》中一一解答,一來因爲內容衆多,篇幅有限,二來也沒 必要,今年考過了,之後通常就不會再考了,否則仍是沒有區分度。編者覺得,靠死記硬背 確定是行不通的,解答此類算法設計問題,須要求職者具備紮實的基本功以及良好的運用能 力,編者沒法左右求職者的我的基本功以及運用能力,由於這些能力須要求職者「十年磨一 劍」地苦學,但編者能夠提供一些比較好的答題方法和解題思路,以供求職者在面試時應對 此類算法設計問題。「授之以魚不如授之以漁」,豈不是更好?

     (1)概括法 此方法經過寫出問題的一些特定的例子,分析總結其中通常的規律。具體而言就是經過 列舉少許的特殊狀況,通過分析,最後找出通常的關係。例如,某人有一對兔子飼養在圍牆 中,若是它們每月生一對兔子,且新生的兔子在第二個月後也是每月生一對兔子,問一 年後圍牆中共有多少對兔子。 使用概括法解答此題,首先想到的就是第一個月有多少對兔子,第一個月的時候,最初 的一對兔子生下一對兔子,此時圍牆內共有兩對兔子。第二個月還是最初的一對兔子生下一 對兔子,共有 3 對兔子。到第三個月除最初的兔子新生一對兔子外,第一個月生的兔子也開 始生兔子,所以共有 5 對兔子。經過舉例,能夠看出,從第二個月開始,每個月兔子總數 都是前兩個月兔子總數之和,Un+1=Un+Un1,一年後,圍牆中的兔子總數爲 377 對。 此種方法比較抽象,也不可能對全部的狀況進行列舉,因此,得出的結論只是一種猜想, 還須要進行證實。

     (2)類似法 正如編者「年年歲歲花類似,歲歲年年仍單身」同樣,此方法考慮解決問題的算法是相 似的。若是面試官提出的問題與求職者之前用某個算法解決過的問題類似,此時此刻就能夠 舉一反三,嘗試改進原有算法來解決這個新問題。而一般狀況下,此種方法都會比較奏效。

 例如,實現字符串的逆序打印,也許求職者歷來就沒遇到過此問題,但將字符串逆序確定 在求職準備的過程當中是見過的。將字符串逆序的算法稍加處理,便可實現字符串的逆序打印。

 (3)簡化法 

此方法首先將問題簡單化,例如改變一下數據類型、空間大小等,而後嘗試着將簡化後 的問題解決,一旦有了一個算法或者思路能夠解決這個被「閹割過」的問題,再將問題還原, 嘗試着用此類方法解決原有問題。 例如,在海量日誌數據中提取出某日訪問 xxx 網站次數最多的那個 IP。很顯然,因爲 數據量巨大,直接進行排序不可行,但若是數據規模不大時,採用直接排序不失爲一種好的 解決方法。那麼如何將問題規模縮小呢?因而想到了Hash法,Hash每每能夠縮小問題規模, 而後在「閹割過」的數據裏面使用常規排序算法便可找出此問題的答案。

     (4)遞歸法 爲了下降問題的複雜度,不少時候都會將問題逐層分解,最後歸結爲一些最簡單的問題, 這就是遞歸。此種方法,首先要可以解決最基本的狀況,而後以此爲基礎,解決接下來的問題。 例如,在尋求全排列的時候,可能會感受無從下手,但仔細推敲,會發現後一種排列組 合每每是在前一種排列組合的基礎上進行的從新排列,只要知道了前一種排列組合的各種組 合狀況,只需將最後一個元素插入到前面各類組合的排列裏面,就實現了目標:即先截去字 符串 s[1…n]中的最後一個字母,生成全部 s[1…n1]的全排列,而後再將最後一個字母插入 到每個可插入的位置。

     (5)分治法 任何一個能夠用計算機求解的問題所需的計算時間都與其規模有關。問題的規模越小, 越容易直接求解,解題所需的計算時間也越少。而分治法正是充分考慮到這一內容,將一個 難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。分治 法通常包含如下三個步驟:

          1)將問題的實例劃分爲幾個較小的實例,最好具備相等的規模。

          2)對這些較小的實例求解,而最多見的方法通常是遞歸。

          3)若是有必要,合併這些較小問題的解,以獲得原始問題的解。 分治法是程序員面試常考的算法之一,通常適用於二分查找、大整數相乘、求最大子數 組和、找出僞幣、金塊問題、矩陣乘法、殘缺棋盤、歸併排序、快速排序、距離最近的點對、 導線與開關等。

    (6)Hash 法 不少面試筆試題目,都要求求職者給出的算法儘量高效。什麼樣的算法是高效的?一 般而言,時間複雜度越低的算法越高效。而要想達到時間複雜度的高效,不少時候就必須在 空間上有所犧牲,用空間來換時間。而用空間換時間最有效的方式就是 Hash 法、大數組和 位圖法。固然,此類方法並不是包治百病,有時,面試官也會對空間大小進行限制,那麼此時, 求職者只能再去思考其餘的方法了。 其實,凡是涉及大規模數據處理的算法設計中,Hash 法就是最好的方法之一。

   (7)輪詢法 在設計每道面試筆試題時,每每會有一個載體,這個載體即是數據結構,例如數組、鏈 表、二叉樹或圖等,當載體肯定後,可用的算法天然而然地就會暴露出來。可問題是不少時 候並不肯定這個載體是什麼。當沒法肯定這個載體時,通常也就很難想到合適的方法了。 編者建議,此時,求職者能夠採用最原始的思考問題的方法——輪詢法,在腦海中輪詢 各類可能的數據結構與算法,常考的數據結構與算法一共就那麼幾種(見表 1),即便不完 全同樣,也是由此衍生出來的或者類似的,總有一款適合考題的。 

                                                                                                    表 1  最常考的數據結構與算法知識點 

數 據 結 構                                                                                                  算    法                                                                                     概    念 


 

鏈表                                                                                                廣度(深度)優先搜索                                                                         位操做 


 

數組                                                                                                              遞歸                                                                                      設計模式 


 

二叉樹                                                                                                       二分查找                                                                              內存管理(堆、棧等) 


 

樹                                                                                                排序(歸併排序、快速排序等)  


 

堆(大頂堆、小頂堆)                                                                樹的插入/刪除/查找/遍歷等  


 

棧                                                                                                                   圖論  


 

隊列                                                                                                               Hash 法  


 

向量                                                                                                               分治法  


 

Hash 表                                                                                                         動態規劃  


 

此種方法看似笨拙,其實實用,只要求職者對常見的數據結構與算法爛熟於心,一點都 沒有問題。 爲了更好地理解這些方法,求職者能夠在平時的準備過程當中,應用此類方法去答題,作 得多了,天然對各類方法也就熟能生巧了,面試的時候,再遇到此類問題,也就可以收放自 如了。固然,千萬不要相信有着張無忌般的運氣,可以在一晚上之間練成乾坤大挪移這一絕世 神功,稱霸武林,算法設計功力的練就是平時一點一滴的付出和思惟的磨練。方法與技巧也 許只是給面試打了一針「雞血」、喂一口「大補丸」,不會讓本身變得從容自信,真正的功力 仍是須要一個長期的積累過程的。 

經驗技巧 6   如何回答系統設計題? 

     應屆生在面試的時候,偶爾也會遇到一些系統設計題,而這些題目每每只是測試一下求 職者的知識面,或者測試求職者對系統架構方面的瞭解,通常不會涉及具體的編碼工做。雖 然如此,對於此類問題,不少人仍是感受難以應對,也不知道從何提及。

     如何應對此類題目呢?在正式介紹基礎知識以前,首先羅列幾個常見的系統設計相關的 面試筆試題,以下所示:

        1)設計一個 DNS 的 Cache 結構,要求可以知足每秒 5000 次以上的查詢,知足 IP 數據 的快速插入,查詢的速度要快(題目還給出了一系列的數據,好比站點數總共爲 5000 萬、 IP 地址有 1000 萬等)。

        2)有 N 臺機器,M 個文件,文件能夠以任意方式存放到任意機器上,文件可任意分割 成若干塊。假設這 N 臺機器的宕機率小於 1/3,想在宕機時能夠從其餘未宕機的機器中完整 導出這 M 個文件,求最好的存放與分割策略。

        3)假設有三十臺服務器,每臺服務器上面都存有上百億條數據(有可能重複),如何找出這 三十臺機器中,根據某關鍵字,重複出現次數最多的前100條?要求使用Hadoop來實現。

        4)設計一個系統,要求寫速度儘量快,並說明設計原理。

        5)設計一個高併發系統,說明架構和關鍵技術要點。

        6)有 25T 的 log(query->queryinfo),log 在不斷地增加,設計一個方案,給出一個 query 能快速返回 queryinfo。 以上全部問題中凡是不涉及高併發的,基本能夠採用 Google 的三個技術解決,即 GFS、 MapReduce 和 Bigtable,這三個技術被稱爲「Google 三駕馬車」,Google 只公開了論文而未 開源代碼,開源界對此很是有興趣,仿照這三篇論文實現了一系列軟件,如 Hadoop、HBase、 HDFS 及 Cassandra 等。 在 Google 這些技術還未出現以前,企業界在設計大規模分佈式系統時,採用的架構往 往是 database+sharding+cache,如今不少公司(好比 taobao、weibo.com)仍採用這種架構。 在這種架構中,仍有不少問題值得去探討。如採用什麼數據庫,是 SQL 界的 MySQL 仍是 NoSQL 界的 Redis/TFS,二者有何優劣?採用什麼方式 sharding(數據分片),是水平 分片仍是垂直分片?據網上資料顯示,weibo.com 和 taobao 圖片存儲中曾採用的架構是 Redis/MySQL/TFS+sharding+cache,該架構解釋以下:前端 cache 是爲了提升響應速度,後 端數據庫則用於數據永久存儲,防止數據丟失,而 sharding 是爲了在多臺機器間分攤負載。 最前端由大塊大塊的 cache 組成,要保證至少 99%(該數據在 weibo.com 架構中的是本身猜 的,而 taobao 圖片存儲模塊是真實的)的訪問數據落在 cache 中,這樣能夠保證用戶訪問速 度,減小後端數據庫的壓力。此外,爲了保證前端 cache 中的數據與後端數據庫中的數據一 致,須要有一箇中間件異步更新(爲何使用異步?理由簡單:同步代價過高。異步有缺點, 如何彌補?)數據,這個有些人可能比較清楚,新浪有個開源軟件叫 Memcachedb(整合 了 Berkeley DB 和 Memcached),正是完成此功能。另外,爲了分攤負載壓力和海量數據, 會將用戶微博信息通過分片後存放到不一樣節點上(稱爲「Sharding」)。

      這種架構優勢很是明顯:簡單,在數據量和用戶量較小的時候徹底能夠勝任。但缺點是 擴展性和容錯性太差,維護成本很是高,尤爲是數據量和用戶量暴增以後,系統不能經過簡 單地增長機器解決該問題。 鑑於此,新的架構應運而生。新的架構仍然採用 Google 公司的架構模式與設計思想, 如下將分別就此內容進行分析。

     GFS 是一個可擴展的分佈式文件系統,用於大型的、分佈式的、對大量數據進行訪問的 應用。它運行於廉價的普通硬件上,提供容錯功能。如今開源界有 HDFS(Hadoop Distributed File System),該文件系統雖然彌補了數據庫+sharding 的不少缺點,但自身仍存在一些問題,

     好比:因爲採用 master/slave 架構,所以存在單點故障問題;元數據信息所有存放在 master 端的內存中,於是不適合存儲小文件,或者說若是存儲大量小文件,那麼存儲的總數據量不 會太大。 MapReduce 是針對分佈式並行計算的一套編程模型。其最大的優勢是:編程接口簡單, 自動備份(數據默認狀況下會自動備三份),自動容錯和隱藏跨機器間的通訊。在Hadoop中, MapReduce 做爲分佈計算框架,而 HDFS 做爲底層的分佈式存儲系統,但 MapReduce 不是 與HDFS耦合在一塊兒的,徹底能夠使用本身的分佈式文件系統替換掉HDFS。當前MapReduce 有不少開源實現,如 Java 實現 Hadoop MapReduce,C++實現 Sector/sphere 等,甚至有些數 據庫廠商將 MapReduce 集成到數據庫中了。

     BigTable 俗稱「大表」,是用來存儲結構化數據的,編者以爲,BigTable 在開源界最火 爆,其開源實現最多,包括 HBase、Cassandra 和 levelDB 等,使用也很是普遍。 除了 Google 的這「三駕馬車」之外,還有其餘一些技術可供學習與使用: Dynamo:亞馬遜的 key-value 模式的存儲平臺,可用性和擴展性都很好,採用 DHT (Distributed Hash Table)對數據分片,解決單點故障問題,在 Cassandra 中,也借鑑了該技 術,在 BT 和電驢這兩種下載引擎中,也採用了相似算法。 虛擬節點技術:該技術經常使用於分佈式數據分片中。具體應用場景是:有一大塊數據(可 能 TB 級或者 PB 級),需按照某個字段(key)分片存儲到幾十(或者更多)臺機器上,同時 想盡可能負載均衡且容易擴展。傳統的作法是:Hash(key) mod N,這種方法最大的缺點是不容易 擴展,即增長或者減小機器均會致使數據所有重分佈,代價太大。因而新技術誕生了,其中一 種是上面提到的 DHT,如今已經被不少大型系統採用,還有一種是對「Hash(key) mod N」的 改進:假設要將數據分佈到 20 臺機器上,傳統作法是Hash(key) mod 20,而改進後,N 取值要 遠大於 20,好比是20000000,而後採用額外一張表記錄每一個節點存儲的 key的模值,好比: node1:0~1000000 node2:1000001~2000000 …

      這樣,當添加一個新的節點時,只需將每一個節點上部分數據移動給新節點,同時修改一 下該表便可。 Thrift:Thrift 是一個跨語言的 RPC 框架,分別解釋「RPC」和「跨語言」以下:RPC 是遠程過程調用,其使用方式與調用一個普通函數同樣,但執行體發生在遠程機器上;跨語 言是指不一樣語言之間進行通訊,好比 C/S 架構中,Server 端採用 C++編寫,Client 端採用 PHP 編寫,怎樣讓二者之間通訊,Thrift 是一種很好的方式。 本篇最前面的幾道題都可以映射到以上幾個系統的某個模塊中,如:

           1)關於高併發系統設計,主要有如下幾個關鍵技術點:緩存、索引、數據分片及鎖粒 度儘量小。

           2)題目 2 涉及如今通用的分佈式文件系統的副本存放策略。通常是將大文件切分紅小 的 block(如 64MB)後,以 block 爲單位存放三份到不一樣的節點上,這三份數據的位置需根 據網絡拓撲結構配置,通常而言,若是不考慮跨數據中心,能夠這樣存放:兩個副本存放在 同一個機架的不一樣節點上,而另一個副本存放在另外一個機架上,這樣從效率和可靠性上, 都是最優的(這個 Google 公佈的文檔中有專門的證實,有興趣的可參閱一下)。若是考慮跨 數據中心,可將兩份存在一個數據中心的不一樣機架上,另外一份放到另外一個數據中心。

           3)題目 4 涉及 BigTable 的模型。主要思想是將隨機寫轉化爲順序寫,進而大大提升寫 速度。具體是:因爲磁盤物理結構的獨特設計,其併發的隨機寫(主要是由於磁盤尋道時間 長)很是慢,考慮到這一點,在 BigTable 模型中,首先會將併發寫的大批數據放到一個內存 表(稱爲「memtable」)中,當該表大到必定程度後,會順序寫到一個磁盤表(稱爲「SSTable」) 中,這種寫是順序寫,效率極高。此時可能有讀者問,隨機讀可不能夠這樣優化?答案是: 看狀況。一般而言,若是讀併發度不高,則不能夠這麼作,由於若是將多個讀從新排列組合 後再執行,系統的響應時間太慢,用戶可能接受不了,而若是讀併發度極高,也許能夠採用 相似機制。 

經驗技巧 7   如何解決求職中的時間衝突問題? 

      對於求職者而言,求職季就是一個趕場季,一天少則幾家、十幾家企業入校招聘,多則 幾十家、上百家企業招兵買馬,企業多,選擇項天然也多,這當然是一件好事情,但因爲招 聘企業實在是太多,天然而然會致使另一個問題的發生:同一天企業扎堆,且都是本身心 儀或欣賞的大牛企業的現象。若是不可以提早掌握企業的宣講時間、地點,是很容易遲到或 錯過的。但有時候即便掌握了宣講時間、筆試和麪試時間,仍是有可能錯過,爲何呢?時 間衝突,人不可能具備分身術,也不可能同一時間作兩件不一樣的事情,因此,不少時候就必 須有所取捨了。 到底該如何取捨呢?該如何應對這種時間衝突的問題呢?在此,編者將本身的一些想法 和經驗分享出來,以供讀者參考:

        1)若是多家心儀企業的校園宣講時間發生衝突(前提是隻宣講,不筆試,不然請看後面 的建議),此時最好的解決方法是和同窗或朋友商量好,各去一家,而後你們進行信息共享。

        2)若是多家心儀企業的筆試時間發生衝突,此時只能選擇其一,畢竟企業的筆試時間 都是考慮到了成百上千人的安排,須要提早安排考場、考務人員和閱卷人員等,不可能爲了 某一我的而輕易改變。因此,最好選擇本身更有興趣的企業參加筆試。

       3)若是多家心儀企業的面試時間發生衝突,不要輕易放棄。對於面試官而言,面試任 何人都是同樣的,由於面試官誰都不認識,而面試時間也是靈活性比較大的,通常能夠經過 電話協商。求職者能夠與相關工做人員(通常是企業的 HR)進行溝通,以某種理由(例如學 校的事宜、導師的事宜或家庭的事宜等,前提是必須可以說服人,不要給出的理由連本身都說服不了)讓其調整時間,通常都能協調下來。但爲了保證協調的成功率,通常要接到面試通知 後第一時間聯繫相關工做人員變動時間,這樣他們協調起來也更方便。

       正如世界上沒有可以包治百病的藥物同樣,以上這些建議在應用時,不少狀況下也作不 到全盤兼顧,當必須進行多選一的時候,求職者就要對此進行評估了,評估的項目能夠包括: 對企業的中意程度、得到 offer 的機率及去工做的可能性等。評估的結果每每具備很強的參 考性,求職者依據評估結果作出的選擇通常也會比較合理。 

相關文章
相關標籤/搜索