我在Twitter和Stripe的一部分工作內(nèi)容是面試前端工程師。其實(shí)關(guān)于面試你可能很有自己的一套,這里我想跟你們分享一下我常用的方法。
不過(guò)我想先給你們一個(gè)忠告,招聘是一件非常艱巨的任務(wù),在45分鐘內(nèi)指出一名侯選人是否合適是你需要完成的任務(wù)。不過(guò)面試的最大問(wèn)題是每個(gè)人都會(huì)想著去雇傭他們自己,任何通過(guò)我面試的人想法大都跟我差不多(注:因?yàn)槟憧倳?huì)問(wèn)你自己關(guān)心和知道的問(wèn)題),這其實(shí)不是一件好事。因此我之前的決定都有很大碰運(yùn)氣的成分。不過(guò),這也是一個(gè)良好的開(kāi)端。
最理想的情況下是侯選人有一個(gè)全面的Github“簡(jiǎn)歷”,這樣我們可以同時(shí)通過(guò)他們的開(kāi)源項(xiàng)目了解他們。我經(jīng)常會(huì)瀏覽他們的代碼然后針對(duì)一些特定的代碼設(shè)計(jì)問(wèn)一些問(wèn)題。如果侯選人有非常好的開(kāi)源項(xiàng)目記錄,接下來(lái)的面試會(huì)直接去檢驗(yàn)他們的團(tuán)隊(duì)協(xié)作精神。否則,我不得不去問(wèn)他們一些代碼方面的問(wèn)題了。
我的面試非常有實(shí)踐性,全部是寫(xiě)代碼。沒(méi)有抽象和理論上的東西(注:作者是個(gè)行業(yè)派),其他的面試官很可能會(huì)問(wèn)這些問(wèn)題,但是我認(rèn)為他們前端編程的能力是值得商榷的。我問(wèn)的問(wèn)題大多看上去非常簡(jiǎn)單,但是每組問(wèn)題都能讓我考查侯選人某一方面JavaScript的知識(shí)。
第一部分:Object Prototypes (對(duì)象原型)
剛開(kāi)始很簡(jiǎn)單。我會(huì)讓侯選人去定義一個(gè)方法,傳入一個(gè)string類(lèi)型的參數(shù),然后將string的每個(gè)字符間加個(gè)空格返回,例如:
spacify(‘hello world’) // =》 ‘h e l l o w o r l d’
盡管這個(gè)問(wèn)題似乎非常簡(jiǎn)單,其實(shí)這是一個(gè)很好的開(kāi)始,尤其是對(duì)于那些未經(jīng)過(guò)電話(huà)面試的侯選人——他們很多人聲稱(chēng)精通JavaScript,但通常連一個(gè)簡(jiǎn)單的方法都不會(huì)寫(xiě)。
下面是正確答案,有時(shí)侯選人可能會(huì)用一個(gè)循環(huán),這也是一種可接受的答案。
function spacify(str) {
return str.split(‘’).join(‘ ’);
}
接下來(lái),我會(huì)問(wèn)侯選人,如何把這個(gè)方法放入String對(duì)象上面,例如:
‘hello world’.spacify();
問(wèn)這個(gè)問(wèn)題可以讓我考察侯選人是否對(duì)function prototypes(方法原型)有一個(gè)基本的理解。這個(gè)問(wèn)題會(huì)經(jīng)常引起一些有意思的討論:直接在對(duì)象的原型(prototypes)上添加方法是否安全,尤其是在Object對(duì)象上。最后的答案可能會(huì)像這樣:
String.prototype.spacify = function(){
return this.split(‘’).join(‘ ’);
};
到這兒,我通常會(huì)讓侯選人解釋一下函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別。
第二部分:參數(shù) arguments
下一步我會(huì)問(wèn)一些簡(jiǎn)單的問(wèn)題去考察侯選人是否理解參數(shù)(arguments)對(duì)象。我會(huì)讓他們定義一個(gè)未定義的log方法作為開(kāi)始。
log(‘hello world’)
我會(huì)讓侯選人去定義log,然后它可以代理console.log的方法。正確的答案是下面幾行代碼,其實(shí)更好的侯選人會(huì)直接使用apply.
function log(msg){
console.log(msg);
}
他們一旦寫(xiě)好了,我就會(huì)說(shuō)我要改變我調(diào)用log的方式,傳入多個(gè)參數(shù)。我會(huì)強(qiáng)調(diào)我傳入?yún)?shù)的個(gè)數(shù)是不定的,可不止兩個(gè)。這里我舉了一個(gè)傳兩個(gè)參數(shù)的例子。
log(‘hello’, ‘world’);
希望你的侯選人可以直接使用apply。有時(shí)人他們可能會(huì)把a(bǔ)pply和call搞混了,不過(guò)你可以提醒他們讓他們微調(diào)一下。傳入console的上下文也非常重要。
function log(){
console.log.apply(console, arguments);
};
接下來(lái)我會(huì)讓侯選人給每一個(gè)log消息添加一個(gè)“(app)”的前輟,比如:
‘(app) hello world’
現(xiàn)在可能有點(diǎn)麻煩了。好的侯選人知道arugments是一個(gè)偽數(shù)組,然后會(huì)將他轉(zhuǎn)化成為標(biāo)準(zhǔn)數(shù)組。通常方法是使用Array.prototype.slice,像這樣:
function log(){
var args = Array.prototype.slice.call(arguments);
args.unshift(‘(app)’);
console.log.apply(console, args);
};
第三部分:上下文
下一組問(wèn)題是考察侯選人對(duì)上下文和this的理解。我先定義了下面一個(gè)例子。注意count屬性不是只讀取當(dāng)前下下文的。
var User = {
count: 1,
getCount: function() {
return this.count;
}
};
我又寫(xiě)了下面幾行,然后問(wèn)侯選人log輸出的會(huì)是什么。
console.log(User.getCount());
var func = User.getCount;
console.log(func());
這種情況下,正確的答案是1和undefined。你會(huì)很吃驚,因?yàn)橛泻芏嗳吮贿@種最基礎(chǔ)的上下文問(wèn)題絆倒。func是在winodw的上下文中被執(zhí)行的,所以會(huì)訪(fǎng)問(wèn)不到count屬性。我向侯選人解釋了這點(diǎn),然后問(wèn)他們?cè)趺礃颖WCUser總是能訪(fǎng)問(wèn)到func的上下文,即返回正即的值:1
正確的答案是使用Function.prototype.bind,例如:
var func = User.getCount.bind(User);
console.log(func());
接下來(lái)我通常會(huì)說(shuō)這個(gè)方法對(duì)老版本的瀏覽器不起作用,然后讓侯選人去解決這個(gè)問(wèn)題。很多弱一些的侯選人在這個(gè)問(wèn)題上犯難了,但是對(duì)于你來(lái)說(shuō)雇傭一個(gè)理解apply和call的侯選人非常重要。
Function.prototype.bind = Function.prototype.bind || function(context){
var self = this;
return function(){
return self.apply(context, arguments);
};
}
第四部分:彈出窗口(Overlay library)
面試的最后一部分,我會(huì)讓侯選人做一些實(shí)踐,通過(guò)做一個(gè)‘彈出窗口’的庫(kù)。我發(fā)現(xiàn)這個(gè)非常有用,它可以全面地展示一名前端工程師的技能:HTML,CSS和JavaScript。如果侯選人通過(guò)了前面的面試,我會(huì)馬上讓他們回答這個(gè)問(wèn)題。
實(shí)施方案是由侯選人自己決定的,但是我也希望他們能通過(guò)以下幾點(diǎn)來(lái)實(shí)現(xiàn):
在遮罩中最好使用position中的fixed代替absolute屬性,這樣即使在滾動(dòng)的時(shí)侯,也能始終讓遮罩始蓋住整個(gè)窗口。當(dāng)侯選人忽略時(shí)我會(huì)提示他們這一點(diǎn),并讓他們解釋fixed和absolute定位的區(qū)別。
.overlay {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: rgba(0,0,0,.8);
}
他們?nèi)绾巫尷锩娴膬?nèi)容居中也是需要考察的一點(diǎn)。一些侯選人會(huì)選擇CSS和絕對(duì)定位,如果內(nèi)容有固定的寬、高這是可行的。否則就要使用JavaScript.
.overlay article {
position: absolute;
left: 50%;
top: 50%;
margin: -200px 0 0 -200px;
width: 400px;
height: 400px;
}
我也會(huì)讓侯選人確保當(dāng)遮罩被點(diǎn)擊時(shí)要自動(dòng)關(guān)閉,這會(huì)很好地考查事件冒泡機(jī)制的機(jī)會(huì)。通常侯選人會(huì)在overlay上面直接綁定一個(gè)點(diǎn)擊關(guān)閉的方法。
$(‘.overlay’).click(closeOverlay);
這是個(gè)方法,不過(guò)直到你認(rèn)識(shí)到點(diǎn)擊窗口里面的東西也會(huì)關(guān)閉overlay的時(shí)侯——這明顯是個(gè)BUG。解決方法是檢查事件的觸發(fā)對(duì)象和綁定對(duì)象是否一致,從而確定事件不是從子元素里面冒上來(lái)的,就像這樣:
$(‘.overlay’).click(function(e){
if (e.target == e.currentTarget)
closeOverlay();
});
其他方面
當(dāng)然這些問(wèn)題只能覆蓋前端一點(diǎn)點(diǎn)的知識(shí)的,還有很多其他的方面你有可能會(huì)問(wèn)到,像性能,HTML5 API, AMD和CommonJS模塊模型,構(gòu)造函數(shù)(constructors),類(lèi)型和盒子模型(box model)。根據(jù)侯選人的情況,我經(jīng)常會(huì)隨機(jī)提些問(wèn)題。
-
工程師
+關(guān)注
關(guān)注
59文章
1570瀏覽量
68531 -
前端
+關(guān)注
關(guān)注
1文章
192瀏覽量
17757
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論