程序員面試什麼最重要?
程序員面試一直是社區樂於討論的熱門話題。我本身從06年實習以來,前後經歷了4家軟件公司,所有是外企,其中有世界500強的通訊企業,有從事期權期貨交易的歐洲中等規模的金融公司,也有爲大型汽車製造商開發Android智能汽車的新興公司。跨入IT行業以來,我在求職過程當中經歷過屢次面試,最近兩年也有過屢次面試別人的經驗。我感受如今到了對這個問題發表本身見解的時候,這篇文章是我站在面試官角度對於程序員面試問題的一個階段性反思和經驗總結。前端
目標
相信和很多朋友同樣,有了幾年工做經驗成爲Senior後就開始了面試別人的經歷。我在最初這個階段只是按照本身的想象把」找到基礎好的程序員「,」找到算法能力優秀的程序員「,」找到有Android開發經驗的程序員「等做爲面試的目標。可是,實際的經歷告訴我,尤爲是按「基礎好」,「算法好」這些目標招到的人最終效果並很差。好比,有的面試者基礎知識和算法掌握狀況不錯,進程、線程、內存等概念清晰,基本的Hash,二叉樹,快速排序等數據結構和算法也比較熟悉,可是進公司後在實際工做中表現得很糟糕。後來,我才發現原來是個人面試目標出了問題,我原先的面試方法更像是大學的算法或操做系統期末考試,按照這種方法讓許多並不合適的人經過了面試,同時也可能錯過了許多合適的人。程序員
後來,個人反思是,從公司的角度講,面試的根本目的是找到"可以幹好工做"的人,而「高學歷」,「算法好」,「基礎好」,「有經驗」這些都是表象而不是根本,它們並不能直接和「工做好」劃等號。面試
方法
目標明確了,但接下來的問題是假設面試者是一個黑盒系統,「工做好」不是直接可觀測變量,你所能直接觀測的變量是基礎、算法、經驗、學歷、性格、談吐、年齡等等。因此,實際上,你只能從「基礎好」,「算法好」等能夠直接觀測的量去推測「工做好」的機率,這就是一個在「X好「條件下"工做好「的條件機率問題:P(工做好 | X好)。算法
根據這個模型,面試所應該考察哪些方面就很明顯了,那就是選擇那種最具備區分性的方面來考察。好比,考察面試者的體型特徵沒有太大意義,由於P(工做好|高),P(工做好|矮),P(工做好|胖),P(工做好|瘦)的機率都差很少;因此,體型特徵不具備區分性,這不是面試所應該關注的內容。數據庫
面試官應當結合職位的要求明確哪些因素具備比較好的區分性。好比,若是要招一名技術門檻比較高的3D遊戲引擎開發工程師,面試者A具備3D遊戲引擎開發的經驗,可是在基礎知識和算法面試方面表現通常;面試者B相反,基礎知識和算法面試表現很好,但沒有遊戲開發經驗,而你只能選擇其一。你選誰呢?其實,這就是兩個條件機率問題P(工做好|經驗好,基礎通常,算法通常)和P(工做好|沒經驗,基礎好,算法好)。這個問題就留給面試官來判斷了,就我我的而言,對於技術門檻較高須要技術積累的職位,經驗更加說明問題,所以,我更傾向於面試者A。編程
下面,我再結合本身的經驗談談對面試中常見方面的見解。後端
算法
算法是Google和MS等大公司面試所重點考察的內容。我我的很喜歡算法,曾經參加ACM/ICPC拿過北京賽區的13名。可是,就我的經驗來看,我所接觸過的絕大多數開發職位而言,算法都不適合做爲考察面試者優劣的主要因素。對於普通的非算法性開發職位,考察面試者的算法就至關於考察他打乒乓球好很差同樣,與目標「工做好」的相關性過低。就我我的的經驗來看,差很少P(工做好|算法好)=50%,也就是算法面試沒有太大的區分性。服務器
甚至,還有一種很很差的狀況特別多地出如今算法好的面試者身上,我稱之爲「只磨刀,不砍柴」。什麼意思呢?有類人只對什麼A*算法,異步編程,JVM類加載機制這種純技術問題感興趣,對實現用戶需求毫無興趣。這類人看起來有必定的技術能力,可是對公司來說貢獻十分有限,甚至不如技術通常但認真負責的人。因此,一旦遇到面試者算法好,我就特別留意考察會不會是這種「只磨刀,不砍柴」的人。數據結構
另外,雖然我我的不瞭解Google和MS,但我對於其特別重視考察算法能力的面試策略是持懷疑態度的。即便在這樣的世界級大公司,算法雖然重要,但能夠想象在項目實施過程所遇到的各類各樣問題中,算法問題絕大多數時候不會是主要瓶頸,沒有到那種須要每一個人都是算法高手的狀況。實際上,絕大多數項目真正難點並非一兩個算法瓶頸,甚至也不是單點的技術瓶頸,而是系統性的組織、協調、設計、開發問題,有大量的看起來不是那麼有技術含量的髒活累活,也有許多問題是因爲信息不足,並非技術能力強就能克服這些困難。一個團隊最好優點互補,有人算法強,有人業務分析能力強,有人擅長後端服務,有人擅長前端界面,有人聰明,有人踏實,這是最好的。若是按照「算法好」的單一標準選材,一定會把許多優秀的人才拒之門外。
補充:在更多地瞭解了Google和Facebook等一流公司的面試細節以後,我對這個問題的認識有了必定的改變,實際上這些公司在面試過程當中並不徹底強調技巧性很強的算法,而是更加註重編碼(Coding)能力,只是在進行編碼測試的過程當中每每是經過一些簡單算法題來進行的。我對於這種面試方法愈來愈欣賞,而且也做爲了咱們公司面試過程當中的重點環節,由於編碼能力的測試是十分必要的,它有着知識性問題沒法取代的做用,若是一個面試者連「判斷一個字符串是不是另外一個字符串的子串」這樣的題目都沒法正確並快速地實現,那麼基本上能夠直接排除了。我這裏所強調的是沒必要考察高難度的算法問題,並不是不重視編碼能力測試,請讀者不要誤解。
基礎
基礎面試是指考察諸如指針使用、進程線程概念等基礎知識的面試,十分相似於大學期末考試題。我曾經覺得基礎面試十分重要,可是如今不這麼看了。在工做中基礎的確是重要的,可是在面試過程當中,它必須具備區分性纔有意義,也就是說P(工做好|基礎好)的機率要高,那麼考察指針使用,進程線程區別這樣的基礎題目纔有它的意義。個人實際經驗是,基礎面試並不具備很好的區分性,和算法同樣, 差很少P(工做好|基礎好) = 50%。同時,基礎面試是最容易準備的,中國人有長期的應試教育經驗,要準備幾個把玩指針題目太容易了。
我曾經遇到過這樣的面試者,他的C語言基礎和編譯、連接等原理掌握得很是好,給我留下了深入的印象,我給的面試結論是:知識面不寬,只會C語言,但基礎很紮實,建議錄用。後來的事情證實了那個結論的前半部分是對的,可是」建議錄用「錯了。他在實際工做中表現得一塌糊塗,不理解需求,不理解總體架構;同時,上班時間不是花在項目上,而是花在閱讀諸如《程序員的自我修養》之類的書籍上。最後,這位同事因爲長期「不出活」離開了公司。
基礎不是不重要,而是「基礎好」不足以說明面試者能幹好工做,由於基礎是屬於局部性知識,而實際工做須要綜合性能力,兩者有天壤之別。C語言、操做系統能考高分,可是不會寫程序的人在大學咱們還見得少嗎? 軟件開發就像蓋房子,綜合能力是設計和搭骨架,基礎知識是碼磚。張小龍原先Foxmail是Delphi開發的,他它不懂C#,你若是要招聘一個開發.NET Email客戶端的人,你考察他對CLR掌握得好很差有意義嗎? 讓張小龍來開發一個C#版的Foxmail真的會有困難嗎? 你招一個精通C#但沒有Email客戶端開發經驗的人來真的比張小龍靠譜嗎?
我說基礎知識不重要,和古人說的「不積窪步無以致千里」是否是矛盾呢?不矛盾!「窪步」與「千里」是一種可累加關係,但再多的「基礎知識」都累加不成「綜合能力」。學習軟件開發要像持續集成同樣,一開始就是一個完整的系統,雖然規模不大,問題不少,但它麻雀雖小五臟俱全,從小系統到大系統,從簡單系統到複雜系統逐步演化。
因此,基礎好自己不足以說明太多的問題,必須進一步考察綜合能力。對於基礎面試表現很差的面試者,若是時間容許也要進一步考察,有的面試者實際上是有能力的,只是沒有進行充分的準備。最理想的狀態固然是基礎和綜合能力俱佳,若不能兼顧,應當綜合能力優先。
經驗
這裏所說的經驗不是經過工做了多少年來衡量的,而主要是指面試者的經歷,好比,是否完整地實現過一個軟件,或做爲主要開發者完成過一個項目。經驗的重要性在於它能說明一我的的綜合能力。從項目的性質、規模和難度,面試官就能夠大體判斷出面試者的綜合能力。若是一個面試者一直在大公司負責一個小模塊的開發維護,那麼基本能夠判斷他不具有獨立或做爲主要開發者承擔一個項目的能力,只適合在另外一家大公司作相似的事情。對於門檻較高須要長期技術積累的職位,相關經驗更顯得尤其重要,好比,Linux內核開發,JVM開發,遊戲引擎開發,數據庫實現,高級UX等。對於這類職位,沒有經驗的面試者即便綜合素質不錯也是須要長時間的學習和積累才能勝任。因此,基本上若是肯定了你的職位屬於此類,那麼相關經驗毫無疑問應該成爲首選因素,換句話說,P(工做好 | 相關經驗好)的機率是很是高的。
經過項目經驗判斷面試者的優劣比經過基礎和算法測試更加靠譜,因此,面試過程當中面試官應該花比較多的時間聽面試者介紹項目經驗,並進行深刻地探討交流,瞭解面試者的知識面、思惟能力、表達能力等。同時,能夠結合項目提一些基礎知識和算法的問題,好比,若是面試者作過C++相關的項目,那就能夠問他如何進行內存管理?是否熟悉智能指針?若是面試者的回答不能使人滿意,那麼就基本上能夠判斷他的項目作得不是很好。
要注意的是,經驗也是一個多維度的事物。好比,C++股票交易中間件系統,這就涉及(C++,中間件,股票) 3個維度。假如面試者A作過C++股票交易客戶端,面試者B作過C的股票交易中間件。從語言角度看,A最匹配,從項目性質看,B最匹配,你如何選擇?這就是在多個維度中,哪一個維度更重要的問題,就這個例子而言,我我的更傾向於B,由於我認爲中間件開發經驗是主要矛盾,而從C切換到C++並非問題。因此,面試官須要判斷哪種經驗是主要的,而哪種經驗是次要的。好比,咱們招聘Android應用開發,這個職位的Android技術門檻並不高,它的真正難點在於作出好的用戶體驗(UX)。因此,若是一個面試者沒有Android的經驗咱們是能夠接受的,可是我但願他在UX方面有經驗,至少作過其餘平臺的移動應用開發。
性格
如今,我來談我認爲最重要的因素:性格。這多是許多初爲面試官的朋友所不可思議的,怎麼會是性格最重要呢?說實話,當我意識到這一點時,我本身也很驚訝!說白了,仍是 P(工做好|性格好)的機率最高啊。個人實際經驗是,若是一我的的性格好,他能把工做作好的可能性是最高的,性格好遠比基礎好、算法好要靠譜。
一我的若是技術上有缺陷,經驗上有不足,但性格好,在團隊中是很容易由其餘人來補位的,他本身也很容易逐漸補起來;相反,若是一我的的性格很差,全部的技術優點經驗優點都發揮不出來,甚至還會起到負做用,並且性格缺點很難改變。我一直談到實際工做所須要的是綜合性的能力,這種綜合能力的發揮中性格是相當重要的。項目中不止會遇到技術問題,要涉及溝通、協調,不一樣的人不一樣的部門既有合做又有磨擦,如何處理這些事情都須要一個良好的性格。能夠說,在開發團隊裏讓你不同凡響的不是你從哪一個學校畢業,也不是你過去的經驗,而是你的性格。
固然,性格是一個複雜的東西,它包含了不少的方面,並不是全部方面都是程序員面試所須要關注的。個人經驗是能夠重點考察這些方面:
1) 態度積極仍是消極。有的面試者在談吐中就會天然給你一種積極上進的感受,或者你能夠在他的經歷中發現他積極的因素,這些都不是太難看出來的。相反,有的面試者你能明顯感受到他的消極情緒。積極性在工做中是十分重要的,積極的人能給團隊帶來朝氣,也更易於合做。基本上,若是肯定面試者屬於態度積極的,他經過我這一關的可能性就會大大增長;相反,若是肯定屬於態度消極的,即便技術能力不錯我也會十分謹慎。
2) IQ。個人經驗是,整體來看,聰明的人在工做中的表現更爲優秀。在面試中要考察一我的是否聰明並不必定要像Google和MS那樣找些專門測試IQ的智力題,其實,你只須要看他討論問題是否是頗有邏輯性,思考和說話是否是反應敏捷就能夠作出大體的判斷。另外,眼睛是人心靈的窗戶,一我的聰明與否,眼睛是會說話的。不過,聰明也不徹底是優勢,好比,當公司或項目遇到困難時,每每是聰明人先跑掉了,堅守的每每是IQ通常的人。
3) 語言表達能力。語言表達能力也是程序員十分重要的一項素質,它關係到項目中的溝通是否順暢。面試官能夠看看面試者可否用簡明的語言介紹清楚曾經作過的項目,可否抓住要點,可否考慮到聽者的相關背景。通常來說,語言表達能力強的人綜合能力都不會太差。
4) 是否具備用戶意識。有人說程序員是作研發的,哪來什麼用戶?只有銷售、市場人員纔會和用戶打交道。其實,這是完徹底全的錯誤認識。你寫一個模塊,甚至一個API,只要有別人用,他就是你的用戶。有的程序員設計一個模塊或是一個軟件老是習慣於從使用者的角度來考慮,儘可能地方便使用者,這就是一種良好的用戶意識。具備良好的用戶意識的人更能考慮別人的感覺和總體的須要,而不是單純地從本身和局部來思考問題。當面試者談及過去的項目經驗時,面試官能夠經常站在用戶的角度對其進行提問,從這個過程當中觀察其是否具備良好的用戶意識。
5) 如何應對質疑和壓力。面試官應該對面試者的回答以及以往項目進行合理的質疑,看看他如何應對。曾經有一位面試者談到作遊戲登陸服務器的經歷,我就問:「若是登陸服務器掛了,怎麼辦呢」?他說原先雖然沒有考慮這個問題,可是能夠怎麼怎麼改進。其實,你們都理解項目中有各類不完美,這裏面緣由不少,只要面對質疑和壓力能從容應對努力往好的方向思考解決就能夠了,不須要掩飾缺陷,更不該該有情緒。我遇到過有的面試者,一旦你對其項目提出質疑,他立刻產生反抗情緒,或不高興,或不認可有問題,這很容易一會兒看出來他在工做中容不得質疑和批評,這種人要想合做就很困難。
6) 個性特色。許多面試者喜歡在簡歷上寫「精通C++/Linux「,這些字眼看得人麻木,若是有人寫」喜歡C++/Linux「,我就會有一種眼前一亮的感受。「精通」是沒有感情色彩的敘述,而「喜歡」包含了面試者的個性,我更願意看到面試者的個性。我相信對某樣東西真正的熱情遠比你當前對它的掌握程度更爲重要。其實,N年的經歷告訴咱們,同一個班的同窗,同一個項目組的同事,雖然天天所學的知識,所接觸的工做都是相同的,但其實每一個人的成績和表現差別是十分明顯的。那麼,到底本質的差別是什麼呢?其實,就是每一個人的個性。是個性使得有的人業餘時間去打球,有的人業餘時間去看書,有的人喜歡Linux,有的人喜歡Mac。一我的在團隊中扮演的角色也和他的個性有很大的關係。面試官應該引導面試者展示本身的個性,並判斷其是否有益於團隊。
總結
最後總結起來,個人經驗是: 1) 面試官的目標是找到」工做好「的人,必定要圍繞這個目標來進行面試,若是把面試當成了算法或操做系統期末考試這就走入了誤區;2) 面試過程是經過學歷、性格、基礎、經驗、算法等能夠測試的因素去綜合判斷面試者「工做好」的機率;3) 在各類因素中,性格 > 經驗 > 基礎 > 算法。性格是最重要的,若是性格很差,全部技術能力都會大打折扣,並且技術缺陷容易彌補,性格缺陷很難改變;經驗體現了一我的的綜合能力,你能夠從面試者過去的經歷中判斷他能從事哪一種工做,不能從事哪一種工做;基礎和算法則主要起到輔助參考的做用,基礎好的程序員通常適應性比較強,學新技術更快,可是切忌單純從基礎來判斷一我的的能力。