程序員,請拒絕無聊的代碼面試!

什麼是「代碼面試」?前端

 

「代碼面試」指全部直接測試候選人的技能,或審查他們編寫的代碼或僞代碼的方法。這些方法包括:程序員

  • 審查代碼片斷,或GitHub的我的頁面;面試

  • 編程測試(Codility等);算法

  • 編程挑戰,或在我的時間裏自由完成的題目;數據庫

  • 現場編程,或結對編程;編程

  • 在白板上實現算法。後端

 

 代碼面試的目的數組

 

這些方法的出現絕非偶然,而是爲了取代那些更差的面試手段,好比:安全

  • 腦筋急轉彎:一架波音747中能裝多少個網球?網絡

  • 咬文嚼字:Java中接口和子類的區別是什麼?

  • 白板編程:至少在這些中不是最差的......

  • 發現式測試:「怎樣檢測鏈表中是否存在環?」

咱們認爲,這一切都是很是愚蠢的面試手段,由於它們沒法反映軟件開發者在平常工做中所需的技能。所以,咱們在面試過程當中,試圖經過代碼面試重現平常的工做。

然而問題在於:這種方法也根本無論用。由於真相是:代碼面試根本不能重現真實的工做。固然,代碼面試能讓候選人展現工做所需的部分技能——但代碼面試的環境和真正的工做環境徹底不一樣。

 

代碼面試的問題

 

代碼面試能減小候選人的數量,但也能拒絕真正優秀的候選人,還能對差的候選人作出虛假的判斷。

代碼測試會佔用面試者和候選人雙方大量的時間。若是能產生效果,也許前者還能夠接受,但後者會致使很難在買方市場上尋找到好的工程師。

因爲隨時更新代碼測試題很困難,結果就致使面試體驗不好。若是候選人對現有的工做滿意,那麼他們根本不會作你的代碼測試題。這些題目也會增長面試的時間,從而延長整個僱傭過程。但這一切都不能增長候選人的數量。

更重要的是,代碼面試並不能很好地模擬真實工做。

Google的研究發現,優秀的團隊都擁有一項特質,叫作「心理安全」(https://rework.withgoogle.com/blog/five-keys-to-a-successful-google-team/)。只有當團隊的全部人都願意承擔風險、願意身處弱勢時,團隊才能達到最佳狀態。

這跟代碼面試徹底不同。候選人一般會感到焦躁、感到壓力,擔憂一個小錯誤就會丟失這份工做。所以你沒辦法得到候選人的最佳狀態。

更糟糕的是,這些題目會刷掉那些沒有太多自由時間的候選人。經過這些題目只會讓你篩選出那些有空閒時間的人。所以你的候選人會更年輕、更沒有經驗。你還會錯過一些其餘人,如未婚父母或須要照顧家中病人的人。

 

有更好的辦法嗎?

 

雖然說忠言逆耳,可是你必須去和你的候選人談話。你須要去了解他們,須要和他們對話。也許這很難,但從總體來看這種方法更容易。

做爲面試官你必須提升技術力。

 

面試技巧:前提條件

 

代碼面試是空中樓閣,看起來很美好,惟一的缺點是沒法篩選出好的候選人。你須要思考什麼樣的技術力和品質對你的團隊最有價值,而代碼面試只不過是你偷懶的藉口而已。

招聘很難,想作好招聘可能須要掌握一系列的技巧。站長站,可是,有些技巧能夠當即提高你的面試水平:

  • 事先規定你須要的候選人的特徵,該規定須要作到具體、詳細;

  • 詢問候選人一系列固定的問題;

  • 在面試以後、徵求他人意見以前,記下全部面試的反饋;

  • 練習,練習,再練習。

 

不須要代碼的方法

 

不須要寫代碼就能衡量候選人的方法可能有一萬種。我經常使用的三個主要方法能夠覆蓋許多不一樣的技能。在面試過程當中,咱們會談論候選人的經驗,要求他們作一些代碼審查,並與別人合做設計一個系統。

下面我會詳細解釋這個過程。

我試圖經過這些方法找到真正可以勝任技術工做的候選人,而且他們必須能在單純的編程技能以外給團隊帶來價值。一般在一次面試中我能在大約一個小時內覆蓋全部三個部分。我有信心這些信息能讓我找到好的候選人。

深刻挖掘他們的經驗

許多團隊已經這樣作了。他們會在面試一開始花幾分鐘,詢問候選人以前的工做,他們對工做的態度,等等。大多時候這就像隨意談話同樣。

但這是不對的。

記住這是面試。你須要儘量地理解他們構建系統時使用的技術。

爲了作好這一點,你須要在面試開始以前仔細閱讀他們的簡歷。這不是開玩笑,在面試開始以前至少花上10分鐘仔細閱讀(不是略讀)簡歷,若是花30分鐘時間則最好。要從簡歷中儘量多瞭解些他們以前的項目,Google一下看看可否找到他們項目的公開信息。面試時挖掘背景信息所花的時間越少,就越能得到好的效果。

在面試中,要求候選人談談他最近最感興趣的項目。要練習主動的傾聽,要學會參與。僞裝你是他團隊中的一員,或者僞裝大家是在作架構審查。你要努力瞭解他們構建的東西以及構建的方法。這樣作的好處和壞處是什麼?要讓候選人知道,不知道答案無所謂,但重要的是能勾起你的好奇心。

下面是我認爲能得到好的答案的問題:

  • 你在項目中的職責是什麼?這個問題自己並非決定性的。即便在項目中承擔的職責很小,他們也可能很適合大家的團隊。你的候選人也許正是由於沒能得到重要的職責而在尋找新的機會。所以,知道他們過去的職責會頗有幫助。

  • 你從他人那裏得到了什麼幫助?沒法感覺他人的幫助是個極其危險的信號。即便是我的項目,也必定須要別人的幫忙。你確定不想要一個以自我爲中心的同事。

  • 給我介紹下那個功能的工做原理。解釋下數據的來源和去向、存儲方式以及這一切能帶給最終用戶的好處。這個問題的答案足以吸引你的好奇心。

  • 這個項目中最糟糕的技術債務是什麼?好的工程師必須理解他們作出決定時須要付出的代價。問完這個問題,能夠繼續詢問他們怎樣改正這些問題,或者還沒有改正的理由。

  • 有沒有出過生產環境下的bug或服務中斷?測試下他們是否理解bug的緣由,電視劇大全,以及團隊解決bug的方法。他們是否提早預期到了bug?下次怎樣才能避免一樣的問題發生?

這一部分面試能讓你直接瞭解候選人的經驗。作好這一部分還能讓你瞭解他們如何感謝別人或責備別人。你將會了解到他們如何在兩難的工程問題上作出抉擇,他們會與你分享最近的教訓,他們與別人溝通技術的能力應該也很明顯。

若是他們選擇了不太適合的項目,能夠考慮談論其餘項目。所謂不太適合的意思是項目不夠複雜或他們記不清的狀況。

注意,這一步要避免詢問相似於「告訴我你解決過的最難的bug」之類的問題。要求別人回憶系統的某一部分的具體原理會帶來大量的虛假負面判斷。人們不可能擁有他們修復的bug相關的一切知識,這種問題會給面試過程帶來很大壓力。

讓他們審查大家的代碼

這項活動一半是代碼審查一半是角色扮演。你能夠藉此篩選出那些可以提高團隊總體代碼質量並促進辦公室氛圍的人。

下面是代碼審查過程當中須要關注的一些方面:

  • 他們怎樣與代碼的「做者」交流?交流是否有用?是否高效?是否友善?

  • 他們會着重哪些問題?是否能明確表達出他們的疑問?他們是否會當即指出哪些可有可無的問題?

  • 他們是否善於閱讀本身不熟悉的代碼?

這個方法須要提早準備不少東西。你須要找到或編寫一段代碼供候選人審查。你還須要爲你但願候選人找出的問題建立一個優先級列表。不要讓面試管當場出題,必定要事先準備好。

在選擇須要審查的代碼時,不要選擇產品代碼。你的候選人沒有你所擁有的背景知識,這樣作其實是將候選人與你的同事比較,而不是與其餘候選人比較。

努力下降代碼示例中的複雜度。面試的時候,候選人沒有太多時間閱讀代碼,並且極可能他們並無想到會作代碼審查。熱身就要花很長時間。

在代碼中加入一兩個真實的bug,但不要強調找bug。通常來講,代碼審查並非個好的找bug方法,特別是審查者歷來沒有見過代碼的狀況下。能自證的bug(如給須要數組的函數傳遞字符串)最好。在你的優先級列表中,bug的優先級應該是最低的,bug應該是給極其優秀的人的加分項。

最後,代碼應該作一些實際的事情。若是你的公司很出名,那能夠選擇你的產品簡化版本。但若是你須要花大量時間爲候選人提供背景信息的話仍是算了。

最好的選擇要麼是虛構的代碼(也許能夠選擇本文竭力避免的代碼面試中用到的代碼),要麼是開源代碼中的一個拉取請求。

一旦決定了要審查的代碼,你應該期待候選人找出下面這些東西:

  • 過於糟糕的拉取請求的描述或提交信息;

  • 能用但沒法自洽的代碼;

  • 過於複雜的代碼(須要重構的代碼);

  • 混亂的變量或方法名;

  • 過分設計的代碼(即實際上永遠不會用到的功能)。

若是代碼中沒有足夠的問題,就多加一些。

這裏有個潛在的問題,我尚未肯定的答案。這個問題是:你是否應該提早將代碼發給候選人?

若是你這樣作,就又給那些有空閒時間的人以巨大的優點。若是不這樣作,就要面臨增長面試壓力的風險。

我傾向於後者。好的面試官能夠減輕壓力,方法之一就是讓面試者提早知道他們將作代碼審查,你也能夠在審查開始以前介紹你的指望。

共同設計系統

做爲面試官,你最重要的任務之一就是判斷候選人是否能完成要求他們完成的技術工做。好的評價方法應當儘量避免虛假的正面和負面判斷,同時在更普遍的技術水平範圍內區分候選人。

即便是新手也應當能針對問題取得一些進展。最高級的候選人應當能快速找出他們沒法當即解決的問題。

這種方法我從大學時代就開始使用,後來在業界用了二十多年。這種方法很是有效。

這種方法是什麼?

協同設計系統的意思是與你的候選人共同設計一個工具、平臺或項目。不須要寫代碼或僞代碼,只須要討論系統的設計思路和作出的取捨,還要提出這些取捨可能帶來的問題,以及解決問題的方案。

這種方法之因此有效,是由於新手工程師和高級工程師之間的主要區別就是他們能預見到的問題的數量。憑藉經驗能夠造就更強壯的系統設計,也能隨時解決新問題。

怎樣使用這種方法?

首先你的團隊須要選擇一個但願候選人「構建」的項目(全部候選人應當使用同一個項目。長時間這樣作,面試官就能作出更好的評價),本身作一次練習並計時。面試時要讓候選人知道系統設計大概要花多少時間,並告訴他們不可能完成全部設計。他們應當提早了解預期的產出。

花上幾分鐘解釋基本的需求。若是需求沒法用幾句話解釋清楚,那可能不是個好項目。例如,你的項目能夠是構建一個與某個著名的社交媒體平臺類似的東西,好比你無需解釋Instragram的工做原理。

事先提供一切你認爲價值不大的東西。而後詢問候選人他們但願首先構建的部分。而後繼續討論新功能,直到時間用完。

若是候選人很容易就完成了這一切,那麼能夠提升複雜度。若是他們表現得很困難,就下降複雜度。

項目的難度可變,這樣就能深刻了解候選人的技能水平。就像是對候選人水平作二分查找同樣!

選一個項目

這項活動的關鍵就是需求必須易於理解。若是你公司的產品很出名,能夠利用它作爲起點。不然,選一個知名的網站(如Facebook)。項目應當與候選人入職後要作的工做相關。拿咱們來講,咱們有兩個項目,一個用於後端招聘,一個用於前端招聘。

後端項目的主要關注點是流行社交網絡的底層系統。前端項目會提供一些簡化了的產品功能截圖,並詢問候選人如何構建(組件怎麼定義、組件間交互用什麼方法等)。

示例:構建Facebook

首先,咱們會介紹任務。告訴候選人咱們要構建一個相似於Facebook的網站。咱們假設如今這個網站包含了用戶、認證和一些其餘功能。

此時,我會詢問候選人怎樣才能構建最小功能的Facebook。咱們喜歡這個問題,由於這個問題能看出候選人怎樣考慮產品上的需求,也能夠給以後的決策和取捨的討論提供基礎。

此時,我會使用白板記錄下他們的想法。這樣能使我參與其中,保證我以後能理解他們的設計。若是我理解錯了,他們會當即注意到並糾正。

候選人可能會告訴我,最小功能集合包含好友、狀態更新、新聞源,以及點讚的功能。問問他們挑選這個功能列表時的原則。是否漏掉了什麼明顯的功能?是否包含了沒必要要的功能?他們的思考過程比功能列表自己更重要。而後,問問他們打算先作哪一個。假設候選人決定先作「好友」功能。

候選人會有不一樣的想法。一些候選人可能會提出不可行工做的方案,但不該該剝奪他們的機會。最優秀的候選人應該能很快就完成這個階段。

咱們假設候選人告訴我,他要建一個表來保存好友關係。這個表應該包含好友關係的發起人和接收者。

而後繼續挖掘。在Facebook中的好友關係是雙向的。怎樣才能在數據庫中表示?這種表示方法對系統設計有什麼影響?

選擇之一就是不須要作任何特別處理。查找給定用戶的好友時用兩列同時查找。另外一個選擇是在好友數據庫中保存兩份數據,每一個數據表示一個方向。若是這樣作,那麼刪除好友時要同時刪掉兩條數據。討論二者的取捨。

下個話題多是如何處理好友請求。他們可能會選擇在「好友」一欄添加一個「接受」按鈕。他們可能會創建新的表保存好友請求。接下來能夠討論黑名單和垃圾請求等話題。

此時好友的話題基本上說完了,能夠繼續討論下一個功能。隨着新的功能不斷加入系統,討論各個功能之間的交互是件頗有意思的事情。

假如候選人無話可說也不要緊!你能夠提出一種解決方案,問問他們的想法。這種方案的優缺點是什麼?要是他們仍是不理解,能夠試着討論其餘的功能。

這項活動中我最喜歡的地方就是它頗有意思。若是面試官表現很好,候選人也積極參與,那麼最終整個面試過程可能不怎麼像面試,而更像是一次與同事間就新項目進行的談話。

而這正是候選人即將擔任的角色。完美。

 

何時應該用代碼面試?

 

儘管我很不喜歡代碼面試,但有時候也有用:

  • 肯定入門級程序員是否可以編程;

  • 若是你的公司強制進行結對編程,那麼在面試中進行結對編程能夠當作是之後工做的預演;

  • 一個角色須要許多特定的編程技能,而你沒有太多時間去教他們,當你在兩個高級職位名稱之間舉棋不定時尤其如此;

  • 從代碼面試到無代碼面試的轉變過程當中不要忽然轉變,給本身一段轉變的時間,能夠幫你創建無代碼面試的技能。

最後,若是團隊的面試技能欠缺,就須要利用代碼面試。代碼面試的效果不太好,並且也有許多缺點。可是,它很是容易實施。即便是沒有經驗的面試官也能夠很好地處理代碼面試。

若是你正是這樣的人,那麼培養本身的面試能力應該是最優先的——僱傭錯誤的人是最昂貴的錯誤。

 

結論

 

只要一點點練習,你的團隊就能在這種無代碼面試中作得很好。他們能在較短的時間內作出更好的僱傭決策,並且面試也能招來更多的候選人。

我但願這篇文章對你有幫助。若是有問題,請在評論區留言。但願你能在下一次面試中幹掉代碼面試!

相關文章
相關標籤/搜索