1. 程式人生 > >Java面試筆試經驗技巧總結

Java面試筆試經驗技巧總結

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

面試筆試經驗技巧篇主要針對程式設計師面試筆試中遇到的 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 的概率及去工作的可能性等。評估的結果往往具有很強的參 考性,求職者依據評估結果做出的選擇一般也會比較合理。

我有一個微信公眾號,經常會分享一些Java技術相關的乾貨;如果你喜歡我的分享,可以用微信搜尋“Java團長”或者“javatuanzhang”關注。

相關推薦

Java面試筆試經驗技巧總結

想找到一份程式設計師的工作,一點技術都沒有顯然是不行的,但是,只有技術 也是不夠的。面試筆試經驗技巧篇主要針對程式設計師面試筆試中遇到的 13 個常見 問題進行深度解析,並且結合實際情景,給出了一個較為合理的參考答案以供讀 者學習與應用,掌握這 13 個問題的解答精髓,對於求

程式設計師面試筆試經驗技巧

本文為博主年初準備找工作時,在讀完《Java面試筆試寶典》這本書後,加上自身的經歷總結的面經。主要受眾為在校應屆畢業生、剛畢業不舊的小白、想要轉行做開發的小小白,請大神們一笑而過。 希望能對想要找工作的程式設計師們一定啟發。 ==========

畢業菜鳥java面試筆試技巧

面試寶典 寫這篇文章時,本人也是找了兩週的工作,在這段時間幸得兩位大神指點,教了我一些面試技巧,下面就來說說面試那些事: 以下就是面試的一些技巧, 第一點:簡歷最好簡潔明瞭,突出重點,你想想,如果你是人事每天處理上百份簡歷,你頭痛不痛,瀏覽簡歷時肯定不會細看,所以不要繁

【木木與呆呆的專欄】Java程式設計師,專注Java程式設計技術,開發以後臺為主前臺為輔,目前投身Hadoop大資料以及Ranger安全開發,活躍在大資料開源社群,同時推薦多種高效便捷的開發工具,分享自己的各種經驗技巧總結

Java程式設計師,專注Java程式設計技術,開發以後臺為主前臺為輔,目前投身Hadoop大資料以及Ranger安全開發,活躍在大資料開源社群,同時推薦多種高效便捷的開發工具,分享自己的各種經驗技巧總結。...

java面試/筆試題目之多執行緒及鎖 (持續更新中)

前言:這一模組可以參照徐劉根大佬的部落格。 一.執行緒和程序的概念、並行和併發的概念 1.程序:是計算機中的程式關於某資料集合上的一次執行活動,是系統 進行資源分配和排程的基本單位,是作業系統結構的基礎。程式是指令、資料及其組織形式的描述,程序是程式的實體。 2.執行緒:是程式執行流的

java面試/筆試題目之Java常見集合(持續更新中)

宣告:題目大部分來源於Java後端公眾號,有些個人整理,但答案皆為個人整理,僅供參考。 目錄 Java中的集合 List 和 Set 區別 1.Set:集合中的物件不按特定方式排序(針對記憶體地址來說,即非線性),並且沒有重複物件。它的有些實現類能對集合中的物件按特定方式排序。

java面試常考題目總結

幾個月的校招,終於面試可以面不改色,剛開始去面試的時候,每次問問題,以前學的東西都淡忘的差不多了,惡補基礎知識。下面是我總結的一些常考題目。 java和javac的作用:javac 是將java原始檔編譯為class位元組碼檔案,如javac HelloWorld.java。執行javac

java面試筆試冒泡排和快速排序

public static void 冒泡sort(int[] arr) { int[] list = { 1, 0, 2, 9, 4, 6, 3 }; Boolean boo = true; for (int i = 1; i < list.length &&

JAVA面試常問知識總結(一)

try catch finally 的詳細用法: 1 public static int testBasic(){ 2 int i = 1; 3 try{ 4 i++; 5 System.out.printl

JAVA面試常問知識總結(二)

JAVA中的引數傳遞總結先看兩道筆試題: 1 public class Test2 { 2 3 public static void main (String [] args) { 4 StringBuffer a = new StringBuff

JAVA面試常問知識總結(三)——JVM

堆疊(Stack) : 如子彈入彈夾一樣 先進後出佇列(Queue):如排隊過隧道 先進先出ps:java中建立的物件都是放在java堆中的,方法區放置的是類的資訊,又叫靜態區,跟堆一樣,被所有的執行緒共享。方法區包含所有的class和static變數。 2.方法區中包含的都是在整個程式中永遠唯一的元素,如c

java面試筆試知識點----深度瞭解

一、java相關的 1、ArrayList深入瞭解: 三種方式來初始化: (1)預設建構函式,使用初始容量10構造一個空列表(無引數構造)。 elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; (2)帶初始容量引數initialCapac

java面試筆試知識點

一、基礎知識 !!!!!!!!!!!!!!!!!!!①基本概念!!!!!!!!!!!!!!!!!!!! (1)java不存在全域性變數或全域性函式 (2)java程式碼塊初始化順序:父類靜態變數、父類靜態程式碼塊、子類靜態變數、子類靜態程式碼塊、、父類非靜態變數、父類非靜態程式碼塊、父類建構

JAVA面試常問知識總結(四)——集合

先附一張java集合框架圖   下面根據面試中常問的關於集合的問題進行了梳理: Arraylist 與 LinkedList 有什麼不同? 1. 是否保證執行緒安全: ArrayList 和 LinkedList 都是不同步的,也就是不保證執行緒安全; 2. 底

JAVA面試常問知識總結(七)——Spring

如果一個接有2個不同的實現, 如何Autowire某一個指定的實現?   1、通過增加@Qualifier(實現類的名字): @Autowired @Qualifier("GirlStudentImpl") private Student student;   2、也可以通過@R

java面試專題之集合總結

一.集合總結 集合類分為Map和Collection兩大類,各種類之間關係如下: 二.集合和陣列之間的區別 陣列: 1.可以儲存基本資料型別/引用資料型別 基本資料型別存的是值 引用資料型別存的是地址 2.陣列在建立的時候 就會定義儲存的資料型別

JAVA面試常問知識總結(十)——Maven

Maven有哪些優點和缺點? 優點如下: 簡化了專案依賴管理: 易於上手,對於新手可能一個"mvn clean package"命令就可能滿足他的工作 便於專案升級,無論是專案本身升級還是專案使用的依賴升級。 有助於多模組專案的開發,一個模組開發好後,釋出到倉庫,依賴該模組

java-面試筆試寶典書筆記

面向物件 較高開發效率 保證程式的魯棒性 保證程式的高可維護性 (我覺得下面解釋的不怎麼好,待更新) 封裝,對類的資料和方法實行保護,對可信的類可以操作,不可信的類進行資訊隱藏 繼承,層次模型,允許和鼓勵類的重用,子類可以從父類繼承方法和成員變數,可

JAVA面試常問知識總結(十一)——Servlet

Servlet屬於執行緒安全的嗎?   Servlet不是執行緒安全的!    談談轉發和重定向的區別 請求轉發: request.getRequestDispatcher("/king_l2lu.jsp").forward(request,response); 重定向

JAVA面試筆試:Override 和 Overload的區別

1、綜述  Override:重寫; Overload:過載。 這兩者之間的區別在很多Java的面試筆試中都會經常被問到,下面我就捋一下他們的區別。 重寫(Override)也稱覆蓋,它是父類與子類之間多型性的一種表現,而過載(Overload)是一個類中多型性的一種