扎實(shí)的基礎(chǔ)知識(shí)、高質(zhì)量的代碼、清晰的思路、優(yōu)化代碼的能力、的綜合能力是編程技術(shù)面試的五大要點(diǎn)。

  找工作一直是一個(gè)熱門話題。要想找到心儀的工作,難免需要經(jīng)過(guò)多輪面試。編程面試是程序員面試過(guò)程中為重要的一個(gè)環(huán)節(jié)。如果能在編程面試的環(huán)節(jié)充分展示自己的能力,那么拿到中意的Offer是水到渠成的事情。

  我先后在歐特克、微軟和思科等公司任軟件工程師,多次接受他人的面試,同時(shí)也面試過(guò)很多人。總結(jié)面試與被面試的經(jīng)驗(yàn),我發(fā)現(xiàn)盡管面試官的背景、性格各不相同,但都關(guān)注應(yīng)聘者五種素質(zhì):扎實(shí)的基礎(chǔ)知識(shí);能寫高質(zhì)量的代碼;分析問(wèn)題時(shí)思路清晰;能優(yōu)化時(shí)間效率和空間效率;具備包括學(xué)習(xí)能力、溝通能力、發(fā)散思維能力等在內(nèi)的綜合能力。

  扎實(shí)的基礎(chǔ)知識(shí)

  扎實(shí)的基本功是成為程序員的前提條件,因此面試官首要關(guān)注應(yīng)聘者的素質(zhì)即是否具備扎實(shí)的基礎(chǔ)。通;竟υ诰幊堂嬖嚟h(huán)節(jié)體現(xiàn)在兩個(gè)方面:一是編程語(yǔ)言,二是數(shù)據(jù)結(jié)構(gòu)和算法。

  每個(gè)程序員至少要熟練掌握1~2門編程語(yǔ)言。面試官?gòu)膽?yīng)聘者在面試過(guò)程中寫的代碼以及跟進(jìn)的提問(wèn)中,能看出他編程語(yǔ)言掌握的熟練程度。以大部分公司面試要求的C++為例,如果函數(shù)需要傳入一個(gè)指針,面試官可能會(huì)問(wèn)是否需要為該指針加上const,把const加在指針不同的位置有什么區(qū)別;如果寫的函數(shù)需要傳入的參數(shù)是一個(gè)復(fù)雜類型的實(shí)例,面試官可能會(huì)問(wèn)傳入值參數(shù)或者引用參數(shù)有什么區(qū)別,什么時(shí)候需要為傳入的引用參數(shù)加上const。

  數(shù)據(jù)結(jié)構(gòu)通常是編程面試過(guò)程中考查的重點(diǎn)。在參加面試之前,應(yīng)聘者需要熟練掌握鏈表、樹、棧、隊(duì)列以及哈希表等數(shù)據(jù)結(jié)構(gòu)以及它們的操作。如果我們留心各大公司的面試題,會(huì)發(fā)現(xiàn)鏈表和二叉樹相關(guān)的問(wèn)題是很多面試官喜歡問(wèn)的問(wèn)題。這方面的問(wèn)題看似簡(jiǎn)單,但真正掌握也很不容易,特別適合在短短幾十分鐘的面試時(shí)間內(nèi)檢驗(yàn)應(yīng)聘者的基本功。如果應(yīng)聘者事先對(duì)鏈表的插入和刪除結(jié)點(diǎn)了如指掌,對(duì)二叉樹的各種遍歷方法的循環(huán)和遞歸寫法都爛熟于胸,那么真正到了面試時(shí)也游刃有余了。

  大部分公司對(duì)算法的要求都只是考查查找和排序。應(yīng)聘者可以在了解各種查找和排序算法的基礎(chǔ)上,重點(diǎn)掌握二分查找、歸并排序和快速排序,因?yàn)楹芏嗝嬖囶}都只是這些算法的變體而已。比如把排序好的數(shù)組的前面若干個(gè)數(shù)字移到數(shù)組的后面,然后問(wèn)怎樣在這個(gè)數(shù)組之中找到小的數(shù)字。這道題其本質(zhì)是考查二分查找。少數(shù)對(duì)算法很重視的公司比如谷歌或者百度,還會(huì)要求應(yīng)聘者熟練掌握動(dòng)態(tài)規(guī)劃和貪婪算法。如果對(duì)這種類型的公司感興趣,那么應(yīng)聘者在參加面試之前應(yīng)該加強(qiáng)對(duì)相關(guān)算法題目的練習(xí)。

  高質(zhì)量的代碼

  只有注重質(zhì)量的程序員,才能寫出魯棒穩(wěn)定的大型軟件。在面試過(guò)程中,面試官總會(huì)格外關(guān)注邊界條件、特殊輸入等看似細(xì)枝末節(jié)但實(shí)質(zhì)至關(guān)重要的地方,以此來(lái)分析應(yīng)聘者是否注重代碼質(zhì)量。很多時(shí)候,面試官發(fā)現(xiàn)應(yīng)聘者寫出來(lái)的代碼只能完成基本的功能,一旦輸入特殊的邊界條件參數(shù)會(huì)錯(cuò)誤百出甚至程序崩潰。

  舉個(gè)很多應(yīng)聘者都被問(wèn)過(guò)的一個(gè)問(wèn)題:寫一個(gè)函數(shù),把字符串轉(zhuǎn)化成整數(shù)。這道題看似很簡(jiǎn)單,絕大部分計(jì)算機(jī)專業(yè)的畢業(yè)生都能用十行以內(nèi)的代碼實(shí)現(xiàn)基本的功能。可是在實(shí)際面試過(guò)程中,十個(gè)應(yīng)聘者中只有一個(gè)人能通過(guò)這道題的面試,因?yàn)榻^大部分應(yīng)聘者不能全面考慮到各種特殊輸入,比如輸入的字符串含中有非數(shù)字的符號(hào)、在字符串的開頭有正負(fù)號(hào)、字符串中有正負(fù)號(hào)但其位置不是在字符串的開頭。

  除此之外,面試官還希望應(yīng)聘者能考慮的邊界條件包括2147483647(0×7FFFFFFF,int能表示的大正整數(shù))和-2147483648(0×80000000,int能表示的小負(fù)整數(shù))。

  除了邊界條件和特殊輸入考慮不足之外,面試官還有一個(gè)不能容忍的錯(cuò)誤是程序崩潰。面試時(shí)很多應(yīng)聘者都會(huì)忘記對(duì)空指針做特殊處理而導(dǎo)致程序崩潰。如果面試時(shí)遇到鏈表、二叉樹相關(guān)的題目,應(yīng)聘者一定要特別小心。因?yàn)檫@兩種題目對(duì)應(yīng)的代碼里通常會(huì)有大量的指針操作,如果考慮不周到,有可能對(duì)空指針進(jìn)行操作而使程序崩潰。

  比如這樣一道題:輸入一個(gè)鏈表的頭指針和一個(gè)無(wú)符號(hào)整數(shù)k,輸出該鏈表的倒數(shù)第k個(gè)結(jié)點(diǎn)。這個(gè)題目很多人都能想到用兩個(gè)指針來(lái)解決:第一個(gè)指針先在鏈表上移動(dòng)k-1步,同時(shí)讓第一個(gè)指針和第二個(gè)指針在鏈表上移動(dòng)。當(dāng)?shù)谝粋(gè)指針移動(dòng)到尾指針時(shí),第二個(gè)指針指向的是倒數(shù)第k個(gè)結(jié)點(diǎn)。然而不是每個(gè)應(yīng)聘者都能根據(jù)正確思路寫出完整的代碼。不少應(yīng)聘者會(huì)忽略兩種可能:一是輸入的鏈表頭指針有可能是空指針;二是鏈表上結(jié)點(diǎn)的數(shù)目有可能少于k個(gè)。忽略這兩點(diǎn)的代碼都存在崩潰的可能,從而很難獲得面試官的青睞。

  要想寫出魯棒的高質(zhì)量代碼,需要在動(dòng)手寫代碼之前想好測(cè)試用例。在寫代碼之前,先要想好各種邊界條件和特殊輸入作為測(cè)試用例。當(dāng)代碼寫好之后,自己在心里用之前想好的測(cè)試用例來(lái)檢驗(yàn)自己寫出的代碼,這樣能在面試官之前發(fā)現(xiàn)并解決問(wèn)題。以求鏈表的倒數(shù)第k個(gè)結(jié)點(diǎn)為例,如果事先想到了輸入頭指針為空指針和鏈表上的結(jié)點(diǎn)總數(shù)少于k這兩個(gè)測(cè)試用例,并且在寫好代碼之后在心里模擬代碼的運(yùn)行過(guò)程,確保能夠通過(guò)這兩個(gè)測(cè)試用例的測(cè)試,那么這輪面試必然是能夠通過(guò)的。