清晰的思路

  只有思路清晰,應(yīng)聘者才有可能在面試過程中解決復(fù)雜的問題。有時面試官會有意出一些比較復(fù)雜的問題,以考查能否在短時間內(nèi)形成清晰的思路并解決問題。對于確實很復(fù)雜的問題,面試官甚至不期待應(yīng)聘者能在面試不到一個小時的時間里給出完整的答案,他更看重的可能還是應(yīng)聘者是否有清晰的思路。面試官通常不會喜歡應(yīng)聘者在沒有形成清晰思路之前草率地開始寫代碼,結(jié)果寫出來的代碼容易邏輯混亂、錯誤百出。

  應(yīng)聘者可以用幾個簡單的方法幫助自己形成清晰的思路。

  首先是舉幾個簡單的具體例子讓自己理解問題。當一眼看不出問題中隱藏的規(guī)律時,可以試著用1~2個具體的例子模擬操作的過程,這樣說不定能通過具體的例子找到抽象的規(guī)律。

  其次可以試著用圖形表示抽象的數(shù)據(jù)結(jié)構(gòu)。像分析與鏈表、二叉樹相關(guān)的題目時,可以畫出它們的結(jié)構(gòu)圖來簡化題目。

  后可以試著把復(fù)雜的問題分解成若干個簡單的子問題,再一一解決。很多基于遞歸的思路,包括分治法和動態(tài)規(guī)劃法,都是把復(fù)雜的問題分解成一個或者多個簡單的子問題。

  比如把二叉搜索樹轉(zhuǎn)化排序的雙向鏈表這個問題很復(fù)雜。碰到這個問題,不妨先畫出1~2個具體的二叉搜索樹及其對應(yīng)的排序雙向鏈表,直觀地感受二叉搜索樹和排序的雙向鏈表有哪些聯(lián)系。如果一下子找不出轉(zhuǎn)換的規(guī)律,可以把整個二叉樹看出三部分:根結(jié)點、左子樹和右子樹。當遞歸地把轉(zhuǎn)換左右子樹這兩個子問題解決之后,再把轉(zhuǎn)換左右子樹得到的鏈表和根結(jié)點鏈接起來,整個問題也解決了。

  優(yōu)化代碼的能力

  的程序員對時間和空間的消耗錙銖必較,他們很有激情不斷優(yōu)化自己的代碼。當面試官出的題目有多種解法時,通常他會期待應(yīng)聘者終能夠找到優(yōu)解。這要求應(yīng)聘者在面試官提示還有更好的解法時,不能放棄思考,而應(yīng)該努力尋找在時間消耗或者空間消耗上可以優(yōu)化的地方。

  要想優(yōu)化時間或者空間效率,首先要知道如何分析效率。即使是同一個算法,用不同方法實現(xiàn)的效率可能也會大不相同,要能夠分析出算法及其代碼實現(xiàn)的效率。例如求斐波那契數(shù)列,很多人喜歡用遞歸公式f(n)=f(n-1)+f(n-2)求解。如果分析它的遞歸調(diào)用樹,會發(fā)現(xiàn)有大量的計算是重復(fù)的,時間效率是以n的指數(shù)增加。但如果先求f(1)、f(2),再根據(jù)f(1)和f(2)求出f(3),接下來根據(jù)f(2)、f(3)求出f(4),并以此類推用一個循環(huán)求出f(n),這種計算方法的時間效率只有O(n),比前面遞歸的方法要好很多。

  要想優(yōu)化代碼的效率,還要熟知各種數(shù)據(jù)結(jié)構(gòu)的優(yōu)缺點,并能選擇合適的數(shù)據(jù)結(jié)構(gòu)解決問題。我們在數(shù)組中根據(jù)下標可以用O(1)完成查找。數(shù)組的這個特征可以用來實現(xiàn)簡單的哈希表解決很多面試題,比如在字符串中找到第一個只出現(xiàn)一次的字符。再比如為了找出n個數(shù)字中小的k個數(shù),需要一個數(shù)據(jù)容器來存儲k個數(shù)字。在這個數(shù)據(jù)容器中,我們希望能夠快速地找到大值并且能快速地替換其中的數(shù)字。經(jīng)過權(quán)衡,我們發(fā)現(xiàn)二叉樹比如大堆或者紅黑樹都是實現(xiàn)這個數(shù)據(jù)容器的理想選擇。

  要想優(yōu)化代碼的效率,也要熟練掌握常用的算法。面試中常用的算法是查找和排序。如果從頭到尾順序掃描一個數(shù)組,需要O(n)時間才能完成查找操作。但如果數(shù)組是排序的,應(yīng)用二分查找算法能把時間復(fù)雜度降低到O(logn)。排序算法除了能夠給數(shù)組排序之外,還能用來解決其他問題。比如快速排序算法中的Partition函數(shù)能夠用來在n個數(shù)里查找第k大的數(shù)字,從而可以用O(n)的時間在數(shù)組中找到出現(xiàn)次數(shù)超過數(shù)組長度一半的數(shù)字。如果面試題是一個求大值或者小值的題目,則可以嘗試用動態(tài)規(guī)劃法或者貪婪算法,比如用動態(tài)規(guī)劃法求出數(shù)組中連續(xù)子數(shù)組的大和。

  的綜合能力

  在面試過程中,應(yīng)聘者除了展示自己的編程能力和技術(shù)功底之外,還需要展示自己的軟技能,諸如溝通能力和學習能力。隨著軟件系統(tǒng)的規(guī)模越來越大,軟件開發(fā)已經(jīng)告別了單打獨斗的年代,程序員與他人的溝通變得越來越重要。在面試過程中,面試官會觀察應(yīng)聘者在介紹項目經(jīng)驗或者算法思路時是否觀點明確、邏輯清晰,并以此判斷他溝通能力的強弱。另外,面試官也會從應(yīng)聘者說話的神態(tài)和語氣來判斷他是否有團隊合作的意識。通常面試官不會喜歡高傲或者輕視合作者的人。

  IT行業(yè)知識更新很快,因此程序員只有具備很好的學習能力才能跟上知識更替的步伐。通常面試官有兩種辦法考查應(yīng)聘者的學習能力。第一種方法是詢問應(yīng)聘者近在看什么書、從中學到了哪些新技術(shù)。面試官可以用這個問題了解應(yīng)聘者的學習愿望和學習能力。第二種方法是拋出一個新概念,接下來他會觀察應(yīng)聘者能不能在較短時間內(nèi)理解這個新概念并解決相關(guān)的問題。比如面試官要求應(yīng)聘者計算第1500個丑數(shù)。很多人都沒有聽說過丑數(shù)這個概念。這時面試官會觀察應(yīng)聘者面對丑數(shù)這個新概念,能不能經(jīng)過提問、思考、再提問的過程,終找出丑數(shù)的規(guī)律從而找到解決方案。
$news_paage$

  知識遷移能力是一種特殊的學習能力。如果我們能夠把已經(jīng)掌握的知識遷移到其他領(lǐng)域,那么學習新技術(shù)或者解決新問題會變得容易。面試官經(jīng)常會先問一個簡單的問題,再問一個很復(fù)雜但和前面的簡單問題相關(guān)的問題。這時面試官期待應(yīng)聘者能夠從簡單問題中得到啟示,從而找到解決復(fù)雜問題的竅門。比如面試官先要求應(yīng)聘者寫一個函數(shù)求斐波那契數(shù)列,再問一個青蛙跳臺階的問題:一只青蛙一次可以跳上1級臺階,也可以跳上2級臺階,請問這只青蛙跳上n級的臺階總共有多少種跳法?應(yīng)聘者如果具有較強的知識遷移能力,能分析出青蛙跳臺階問題實質(zhì)上只是斐波那契數(shù)列的一個應(yīng)用。

  還有不少面試官喜歡考查應(yīng)聘者的抽象建模能力和發(fā)散思維能力。面試官從日常生活中提煉出問題,比如如何判斷5張撲克牌是不是順子,考查應(yīng)聘者能不能把問題抽象出來用合理的數(shù)據(jù)結(jié)構(gòu)表示,并找到其中的規(guī)律解決這個問題。面試官也可以限制應(yīng)聘者不得使用常規(guī)方法,這要求應(yīng)聘者具備創(chuàng)新精神,能夠打開思路從多角度去分析、解決問題。比如面試官要求應(yīng)聘者不用加減乘除四則運算實現(xiàn)兩個整數(shù)的加法。此時面試官期待應(yīng)聘者能夠打開思路,用位運算實現(xiàn)整數(shù)的加法。

  小結(jié)

  我們可以用下圖來總結(jié)出應(yīng)聘者需要具備的素質(zhì)。

  從上圖可以看出,應(yīng)聘者在面試之前需要做足準備,對編程語言、數(shù)據(jù)結(jié)構(gòu)和算法等基礎(chǔ)知識有全面的了解。面試時如果碰到簡單的問題應(yīng)聘者一定要注重細節(jié)寫出完整、魯棒的代碼。如果碰到復(fù)雜的問題應(yīng)聘者可以通過畫圖、舉具體例子分析和分解復(fù)雜問題等方法先理清思路再動手編程。除此之外,應(yīng)聘者還應(yīng)該不斷優(yōu)化時間效率和空間效率,力求找到優(yōu)的解法。在面試過程中,應(yīng)聘者還應(yīng)該主動提問弄清楚題目的要求,表現(xiàn)自己的溝通能力。當面試官前后問的兩個問題有相關(guān)性時,盡量把解決前面問題的思路遷移到后面的問題中去,展示自己良好的學習能力。如果能做到這么幾點,那么應(yīng)聘者順利通過面試獲得心儀的職位將是瓜熟蒂落的事情。