面試筆試經驗技巧篇


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

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

 

經驗技巧 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 的概率及去工作的可能性等。評估的結果往往具有很強的參 考性,求職者依據評估結果做出的選擇一般也會比較合理。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM