如何面試一個前端開發者?
我在Twitter和Stripe這兩家公司工作期間會負責一些前端開發者的面試。在面試過程中我們有很大的決定權,這裡和大家一起分享一些我設計的不同型別的面試問題。
首先,我要警告各位的就是: 招人很難!尤其是要在45分鐘之內判斷一個人是否適合崗位更是一項高難度的工作。 面試存在的問題就是大家都想招到像一個像自己一樣的人。 每個通過我面試的人的思維方式可能都和我比較相似, 但這樣肯定是不對的。 正因如此, 其實目前為止我做的每一個決定都有一部分運氣成分。 但是我想這種方式會是個很好的開始。
理想情況下,應聘者應該有一份比較完整的GitHub‘簡歷’, 這樣我們可以一起來回顧他們參與的開源專案。 通常我會先瀏覽他們的程式碼,然後針對某一個具體的程式碼設計問他們一些問題。 如果應聘者在這一部分表現非常優秀,就可以直接進入團隊社交能力的考察部分。否則的話我會讓他們做一些程式設計題目。
我面試的時候是非常注重實踐的, 整個面試過程幾乎全都是在寫程式碼。 我不會問一些比較抽象的或者演算法相關的問題。其他的面試官如果願意的話可以考察這些方面, 但我覺得這些知識未必是一個前端開發者所必需的。我問的問題看起來比較簡單,但實際上每一類問題都可以讓我洞悉應聘者在JavaScript的某一方面的知識。
應聘者可以使用自己的膝上型電腦也可以用我的,但在我這裡是不會用白板的。他們也可以使用任何適合自己的編輯器,但我通常直接用Chrome的控制檯來檢查的應聘者的程式輸出結果。
第一部分:物件原型
我們先從簡單的來。實現一個spacify函式:接受一個字串作為引數,然後把這個字串的每個字元都用空格隔開後返回。例如:
spacify('hello world') // => 'h e l l o w o r l d'
雖然這個問題看起來非常容易,但結果卻證明從這個問題問起是很合適的,尤其是對於一些電話面試者,他們聲稱瞭解JavaScript,卻連一個完整的函式都不會寫。下面是這個題目的正確答案,有的應聘者通過迴圈來實現也是可以的。
function spacify(str) { return str.split('').join(' '); }
接下來這個問題是讓應聘者直接為String物件增加spacify的函式,像這樣:
'hello world'.spacify();
通過這個問題我可以瞭解到應聘者對於函式原型基礎知識的掌握情況。另外這個問題經常會引發另外一個有趣的討論:直接在prototypes上尤其是在Object的prototypes上定義屬性的風險。
最終的答案類似下面的程式碼:
String.prototype.spacify = function(){ return this.split('').join(' '); };
這時候我還會讓應聘者解釋函式表示式(expression)和函式宣告(declaration)的區別。
第二部分:引數
接下來我會問一些簡單的問題,這些問題可以幫我瞭解到應聘者對引數物件的理解程度。
首先,呼叫一個尚未定義的log函式:
log('hello world')
然後我讓應聘者去實現log函式:接受一個string引數然後直接傳給console.log(),正確答案就在下面,但有些比較優秀的應聘者會直接使用apply函式來實現。
function log(msg){ console.log(msg); }
完成上一步後我會修改呼叫log的方式:傳遞多個引數。告訴應聘者我希望log函式不止接收一個數字作為引數,它應該可以接受任意個數字作為引數。同時我也提醒他們cosole.log()本身就可以接收多個引數。
log('hello', 'world');
理想情況下應聘者應當直接使用apply來實現這個功能。但有時他們會混淆apply和call的二者的區別,這時你可以給他們一些提示。另外將console作為上下文引數這一點也很重要。
function log(){ console.log.apply(console, arguments); };
然後我會讓要求在每一條日誌訊息前加上“(app)”的字首,例如:
'(app) hello world'
現在,問題就有點棘手了。能力強些的應聘者應當知道arguments是一個偽陣列,在使用它之前得先把它轉換成標準陣列。通常我們用Array.prototype.slice就可以實現這一點,像下面這樣:
function log(){ var args = Array.prototype.slice.call(arguments); args.unshift('(app)'); console.log.apply(console, args); };
第三部分:上下文
下面的這一組面試題可以考察應聘者對於JavaScript中context和this的理解。我先給出下面的定義,注意,count的屬性是從當前的上下文中讀取的。
var User = { count: 1, getCount: function() { return this.count; } };
然後我會讓應聘者寫出下面程式碼的輸出結果:
console.log(User.getCount()); var func = User.getCount; console.log(func());
這個題目正確的答案是1和undefined。令人吃驚的是有很多人會在這種關於上下文的基礎知識上犯錯。func函式被呼叫時,它的上下文是windows,而windows是沒有count屬性的。我把這些都和應聘者做了解釋,然後我問他如何才能保證func函式始終都能以User作為上下文被呼叫,這樣它就能正確執行從而返回1。
正確的答案是使用Function.prototype.bind,例如:
var func = User.getCount.bind(User); console.log(func());
通常我會告訴應聘者有一些老的瀏覽器是不支援bind函式的,然後讓他們自己來寫一個函式來模擬。有一些基礎差的應聘者並不認可這一點,但對我來講每一個被僱傭的應聘者對apply和call都應該有比較深入的理解,這一點很重要!
Function.prototype.bind = Function.prototype.bind || function(context){ var self = this; return function(){ return self.apply(context, arguments); }; }
如果應聘者像上面那樣實現了bind並且還判斷了當前瀏覽器是否已經支援bind函式,那麼應聘者可以得到額外的加分。
此時,如果應聘表現的很出色,我會讓他們去實現currying引數。
第四部分:Overlay庫
面試的最後這一部分裡,我會讓應聘者做一些更加實際的事情,通常是去實現一個‘overlay’的庫。這很方式很管用,它涉及到了整個前端開發所用到的技術:HTML、CSS 和JavaScript。如果應聘者在前面幾個環節表現優秀,我會盡早的開始這一部分的問題。
具體的實現因人而異,但是這裡幾個關鍵點需要注意!
對於overlay covers,最好使用 position: fixed 而不是 position: absolute,這樣即使視窗滾動的時候也可以保證層鋪滿整個視窗。如果應聘者沒有注意到這一點我會提示他們,然後問他們這兩者的區別。
.overlay { position: fixed; left: 0; right: 0; bottom: 0; top: 0; background: rgba(0,0,0,.8); }
從把內容放置到層的中心位置的方式也可以為面試官提供一些資訊。有些應聘者可能會使用CSS和絕對位置,但這樣的前提是內容必須是固定寬度和長度的。另外的應聘者也可能會選擇用JavaScript來定位。
.overlay article { position: absolute; left: 50%; top: 50%; margin: -200px 0 0 -200px; width: 400px; height: 400px; }
我還會要求他們實現單擊關閉層的功能,然後就可以順勢討論下幾種不同型別的事件傳播機制。大多數應聘者會直接為層設定一個事件監聽器。
$('.overlay').click(closeOverlay);
看著是對的,但很快你就會發現在這個層的子元素上單擊也會關閉層,這明顯不是我們預期的效果。解決方法是先檢查事件的targets來確保不是一個傳播事件,像這樣:
$('.overlay').click(function(e){ if (e.target == e.currentTarget) closeOverlay(); });
其它
其實這些問題只覆蓋了前端知識的很小一部分,面試的時候你可以問很多其他方面的問題,例如效能、HTML5 APIs, AMD vs CommonJS modules、 建構函式、資料型別以及盒模型等。我經常會根據應聘者的興趣來搭配不同型別的問題。
此外我推薦大家到前端開發者面試題集錦和JavaScript花園去尋找一些靈感!
相關文章
- 前端開發面試題前端面試題
- web前端開發面試題分享Web前端面試題
- 初級前端開發面試總結前端面試
- 一個web前端開發者學習Flutter 的歷程(一)Web前端Flutter
- 中高階前端開發高頻面試題前端面試題
- 深圳XX機器人前端開發面試機器人前端面試
- 高階前端開發者必會的34道Vue面試題系列(二)前端Vue面試題
- 高階前端開發者必會的34道Vue面試題解析(三)前端Vue面試題
- 如何完成一個有效的面試面試
- 如何成為一個出色的敏捷開發者?敏捷
- 面試題:如何設計一個高併發系統?面試題
- 開發多年HashMap原理不知道,Java開發者面試如何系統複習HashMapJava面試
- 如何打造一個令人愉悅的前端開發環境(一)前端開發環境
- 最全前端開發面試問題及答案整理前端面試
- 乾貨 | 作為前端開發者如何邁向獨立開發者前端
- java面試題大合集(開發者必看)Java面試題
- 資料庫面試題(開發者必看)資料庫面試題
- Go 開發者面試突破:50 道高頻面試題及解答Go面試題
- 一個NB的web前端開發者,是怎麼學習的?Web前端
- 2019web前端開發全新面試題庫 二Web前端面試題
- 2018年前端開發校招面試總結前端面試
- iOS高階開發者面試必過技巧iOS面試
- JavaScript面試的完美指南(開發者視角)JavaScript面試
- java面試題總結(開發者必備)Java面試題
- Web前端JQuery面試題(一)Web前端jQuery面試題
- 敏捷個人-做好一個開發者敏捷
- iOS開發者的一些前端感悟iOS前端
- 測試開發之前端篇-瀏覽器開發者工具使用(TODO)前端瀏覽器
- 如何使用前端技術開發一個桌面跨端應用前端跨端
- 前端開發者如何用腦圖快速上手linux前端Linux
- Web前端開發必看的100道大廠面試題Web前端面試題
- 常見的前端開發CSS 面試題及回答策略前端CSS面試題
- 常見的前端開發:Javascript 面試題及回答策略前端JavaScript面試題
- 北京某某某某科技前端開發面試前端面試
- 一個 Handler 面試題引發的血案!!!面試題
- 記一個面試題引發的思考面試題
- 【前端 · 面試 】TCP 總結(一)—— 概述前端面試TCP
- [前端 · 面試 ]TCP 總結(一)—— 概述前端面試TCP
- 拿到大廠前端offer的前端開發是怎麼回答面試題的前端面試題