注:之前我們介紹過:一名靠譜的JavaScript程序員應(yīng)備的素質(zhì)骡和,從程序員的角度提出要去學(xué)習(xí)哪些知識,下面這篇文章從面試官的角度介紹到面試時可能會問到的一些問題嚎杨。
我在Twitter和Stripe的一部分工作內(nèi)容是面試前端工程師袒炉。其實關(guān)于面試你可能很有自己的一套,這里我想跟你們分享一下我常用的方法付材。
不過我想先給你們一個忠告朦拖,招聘是一件非常艱巨的任務(wù),在45分鐘內(nèi)指出一名侯選人是否合適是你需要完成的任務(wù)厌衔。不過面試的最大問題是每個人都會想著去雇傭他們自己璧帝,任何通過我面試的人想法大都跟我差不多(注:因為你總會問你自己關(guān)心和知道的問題),這其實不是一件好事富寿。因此我之前的決定都有很大碰運氣的成分睬隶。不過,這也是一個良好的開端作喘。
最理想的情況下是侯選人有一個全面的Github“簡歷”理疙,這樣我們可以同時通過他們的開源項目了解他們。我經(jīng)常會瀏覽他們的代碼然后針對一些特定的代碼設(shè)計問一些問題泞坦。如果侯選人有非常好的開源項目記錄窖贤,接下來的面試會直接去檢驗他們的團(tuán)隊協(xié)作精神。否則,我不得不去問他們一些代碼方面的問題了赃梧。
我的面試非常有實踐性滤蝠,全部是寫代碼。沒有抽象和理論上的東西(注:作者是個行業(yè)派)授嘀,其他的面試官很可能會問這些問題物咳,但是我認(rèn)為他們前端編程的能力是值得商榷的。我問的問題大多看上去非常簡單蹄皱,但是每組問題都能讓我考查侯選人某一方面JavaScript的知識览闰。
第一部分:Object Prototypes (對象原型)
剛開始很簡單。我會讓侯選人去定義一個方法巷折,傳入一個string類型的參數(shù)压鉴,然后將string的每個字符間加個空格返回,例如:
spacify('hello world') // => 'h e l l o w o r l d'
盡管這個問題似乎非常簡單锻拘,其實這是一個很好的開始油吭,尤其是對于那些未經(jīng)過電話面試的侯選人——他們很多人聲稱精通JavaScript,但通常連一個簡單的方法都不會寫署拟。
下面是正確答案婉宰,有時侯選人可能會用一個循環(huán),這也是一種可接受的答案推穷。
function spacify(str) { return str.split('').join(' '); }
接下來心包,我會問侯選人,如何把這個方法放入String對象上面缨恒,例如:
'hello world'.spacify();
問這個問題可以讓我考察侯選人是否對function prototypes(方法原型)有一個基本的理解谴咸。這個問題會經(jīng)常引起一些有意思的討論:直接在對象的原型(prototypes)上添加方法是否安全,尤其是在Object對象上骗露。最后的答案可能會像這樣:
String.prototype.spacify = function(){ return this.split('').join(' '); };
到這兒,我通常會讓侯選人解釋一下函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別血巍。
第二部分:參數(shù) arguments
下一步我會問一些簡單的問題去考察侯選人是否理解參數(shù)(arguments)對象萧锉。我會讓他們定義一個未定義的log方法作為開始。
log('hello world')
我會讓侯選人去定義log述寡,然后它可以代理console.log的方法柿隙。正確的答案是下面幾行代碼,其實更好的侯選人會直接使用apply.
function log(msg) { console.log(msg); }
他們一旦寫好了鲫凶,我就會說我要改變我調(diào)用log的方式禀崖,傳入多個參數(shù)。我會強調(diào)我傳入?yún)?shù)的個數(shù)是不定的螟炫,可不止兩個波附。這里我舉了一個傳兩個參數(shù)的例子。
log('hello', 'world');
希望你的侯選人可以直接使用apply。有時人他們可能會把apply和call搞混了掸屡,不過你可以提醒他們讓他們微調(diào)一下封寞。傳入console的上下文也非常重要。
function log(){ console.log.apply(console, arguments); };
接下來我會讓侯選人給每一個log消息添加一個"(app)"的前輟仅财,比如:
'(app) hello world'
現(xiàn)在可能有點麻煩了狈究。好的侯選人知道arugments是一個偽數(shù)組,然后會將他轉(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); };
第三部分:上下文
下一組問題是考察侯選人對上下文和this的理解。我先定義了下面一個例子碎罚。注意count屬性不是只讀取當(dāng)前下下文的宁改。
var User = { count: 1, getCount: function() { return this.count; } };
我又寫了下面幾行,然后問侯選人log輸出的會是什么魂莫。
console.log(User.getCount()); var func = User.getCount; console.log(func());
這種情況下还蹲,正確的答案是1和undefined。你會很吃驚耙考,因為有很多人被這種最基礎(chǔ)的上下文問題絆倒谜喊。func是在winodw的上下文中被執(zhí)行的,所以會訪問不到count屬性倦始。我向侯選人解釋了這點斗遏,然后問他們怎么樣保證User總是能訪問到func的上下文,即返回正即的值:1
正確的答案是使用Function.prototype.bind鞋邑,例如:
var func = User.getCount.bind(User); console.log(func());
接下來我通常會說這個方法對老版本的瀏覽器不起作用诵次,然后讓侯選人去解決這個問題。很多弱一些的侯選人在這個問題上犯難了枚碗,但是對于你來說雇傭一個理解apply和call的侯選人非常重要逾一。
Function.prototype.bind = Function.prototype.bind || function(context){ var self = this; return function(){ return self.apply(context, arguments); }; }
第四部分:彈出窗口(Overlay library)
面試的最后一部分,我會讓侯選人做一些實踐肮雨,通過做一個‘彈出窗口’的庫遵堵。我發(fā)現(xiàn)這個非常有用,它可以全面地展示一名前端工程師的技能:HTML,CSS和JavaScript怨规。如果侯選人通過了前面的面試陌宿,我會馬上讓他們回答這個問題。
實施方案是由侯選人自己決定的波丰,但是我也希望他們能通過以下幾點來實現(xiàn):
在遮罩中最好使用position中的fixed代替absolute屬性壳坪,這樣即使在滾動的時侯,也能始終讓遮罩始蓋住整個窗口掰烟。當(dāng)侯選人忽略時我會提示他們這一點爽蝴,并讓他們解釋fixed和absolute定位的區(qū)別沐批。
.overlay { position: fixed; left: 0; right: 0; bottom: 0; top: 0; background: rgba(0,0,0,.8); }
他們?nèi)绾巫尷锩娴膬?nèi)容居中也是需要考察的一點。一些侯選人會選擇CSS和絕對定位霜瘪,如果內(nèi)容有固定的寬珠插、高這是可行的。否則就要使用JavaScript.
.overlay article { position: absolute; left: 50%; top: 50%; margin: -200px 0 0 -200px; width: 400px; height: 400px; }
我也會讓侯選人確保當(dāng)遮罩被點擊時要自動關(guān)閉颖对,這會很好地考查事件冒泡機(jī)制的機(jī)會捻撑。通常侯選人會在overlay上面直接綁定一個點擊關(guān)閉的方法。
$('.overlay').click(closeOverlay);
這是個方法缤底,不過直到你認(rèn)識到點擊窗口里面的東西也會關(guān)閉overlay的時侯——這明顯是個BUG顾患。解決方法是檢查事件的觸發(fā)對象和綁定對象是否一致,從而確定事件不是從子元素里面冒上來的个唧,就像這樣:
$('.overlay').click(function(e){ if (e.target == e.currentTarget) closeOverlay(); });
其他方面
當(dāng)然這些問題只能覆蓋前端一點點的知識的江解,還有很多其他的方面你有可能會問到,像性能徙歼,HTML5 API, AMD和CommonJS模塊模型犁河,構(gòu)造函數(shù)(constructors),類型和盒子模型(box model)魄梯。根據(jù)侯選人的情況桨螺,我經(jīng)常會隨機(jī)提些問題。
看起是一個和善的面試官酿秸,大部分面試官灭翔,都只會這么問,說一下this 說一下原型 說一下繼承 辣苏,肝箱,完全要自己總結(jié),根據(jù)你的總結(jié)稀蟋,面試官再進(jìn)一步問到總結(jié)中的漏洞