在過去的幾年里,我在亞馬遜和雅虎面試過很多專注于前端開發(fā)的 Web 開發(fā)者和軟件工程師,在這篇文章中,我想分享一些面試技巧,幫助候選人為面試做好準(zhǔn)備。
免責(zé)聲明——本文并非旨在列出在前端面試中可能會被問到的所有問題,但可以將其視為知識的基線。
通過面試不是件容易的事,作為候選人,通常需要在 45 分鐘的時間內(nèi)展示自己能做些什么。作為一名面試官,同樣難以在這么短的時間內(nèi)評估候選人是否適合。對于面試來說,并不存在一刀切的方法,面試官問的問題通常會有一個范圍,但除此之外,他們可以自行決定要問哪些其他問題。
作為曾經(jīng)的候選人和面試官,我試圖在這篇文章中涵蓋你可能會在面試中被問到的最重要的前端開發(fā)知識。
常見的誤解
我見過候選人犯的最大錯誤之一就是準(zhǔn)備了一些瑣碎的問題,例如“什么是盒子模型”或者“JavaScript 中的 ?==
? 和 ?===
? 之間的區(qū)別是什么”。知道這些問題的答案固然是好,但這并不會告訴面試官來太多有用的信息。
相反,在實際的面試中,你可能需要使用 JavaScript、CSS 和 HTML 來編寫代碼。在你的面試期間,你可能需要實現(xiàn) UI、構(gòu)建窗口小部件或使用 Lodash 和 Underscore.js 這樣的庫編寫常用的實用程序函數(shù)。例如:
- 構(gòu)建常見的 Web 應(yīng)用程序的布局和交互,例如類似 Netflix 網(wǎng)站那樣的。
- 實現(xiàn)小部件,如日期選擇器、輪播或電子商務(wù)網(wǎng)站購物車。
- 寫一個類似 ?
debounce
? 或深度 ?clone
? 對象的函數(shù)。
說到庫,我看到候選人經(jīng)常犯的另一個錯誤是他們需要完全依賴最新的框架來解決面試問題。你可能會想,如果我可以在生產(chǎn)環(huán)境中使用 jQuery、React、Angular 等,那為什么就不能在面試中使用它們呢?技術(shù)、框架和庫會隨著時間的推移而發(fā)生變化——我更感興趣的是你是否了解前端開發(fā)的底層原理,而不是依賴更高層次的抽象。如果你不能在沒有它們的情況下回答面試問題,我希望你至少可以徹底解釋和推測這些庫背后的原理。
總的來說,大部分的面試都涉及實際的編碼。
JavaScript
你需要了解 JavaScript,而且是徹底地了解。你面試的職位越高,對語言知識的要求就越高。以下是你應(yīng)該熟悉的 JavaScript 知識點:
- 執(zhí)行上下文,尤其是詞法作用域和閉包;
- 提升、函數(shù)和塊作用域,以及函數(shù)表達(dá)式和聲明;
- 綁定——特別是 ?
call
?、?bind
?、?apply
? 和 ?this
?; - 對象原型、構(gòu)造函數(shù)和 ?
mixin
?; - 組合和高階函數(shù);
- 事件委托和冒泡;
- 使用 ?
typeof
?、?instanceof
?和 ?Object.prototype.toString
? 進(jìn)行類型轉(zhuǎn)換; - 使用回調(diào)、?
promise
?、?await
? 和 ?async
? 處理異步調(diào)用; - 什么時候可以使用函數(shù)聲明和表達(dá)式。
DOM
知道如何遍歷和操作 DOM 非常重要,對于重度依賴 jQuery 或者開發(fā)了很多 React & Angular 類型應(yīng)用程序的候選人來說,他們可能會在這個問題上栽跟斗。你可能不會每天都直接接觸 DOM,因為我們大多數(shù)人都在使用各種抽象。在不使用第三方庫的情況下,你需要知道如何執(zhí)行以下這些操作:
- 使用 ?
document.querySelector
? 選擇或查找節(jié)點,在舊版瀏覽器中使用 ?document.getElementsByTagName
?; - 上下遍歷——?
Node.parentNode
?、?Node.firstChild
?、?Node.lastChild
? 和 ?Node.childNodes
?; - 左右遍歷——?
Node.previousSibling
?和 ?Node.nextSibling
?; - 操作——在 DOM 樹中添加、刪除、復(fù)制和創(chuàng)建節(jié)點。你應(yīng)該了解如何修改節(jié)點的文本內(nèi)容以及切換、刪除或添加 CSS 類名等操作;
- 性能——當(dāng)有很多節(jié)點時,修改 DOM 的成本會很高,你至少應(yīng)該知道如何使用文檔片段和節(jié)點緩存。
CSS
至少,你應(yīng)該知道如何在頁面上布局元素,如何使用子元素或直接后代選擇器來定位元素,以及什么時候該用類、什么時候該用 ID。
- 布局——安排彼此相鄰的元素的位置,以及如何將元素布置成兩列或三列;
- 響應(yīng)式設(shè)計——根據(jù)瀏覽器寬度大小更改元素的尺寸;
- 自適應(yīng)設(shè)計——根據(jù)特定斷點更改元素的尺寸;
- 特異性——如何計算選擇器的特異性,以及級聯(lián)如何影響屬性;
- 適當(dāng)?shù)拿臻g和類命名。
HTML
知道哪些 HTML 標(biāo)簽最能代表你正在顯示的內(nèi)容以及相關(guān)屬性,應(yīng)該掌握手工知識。
- 語義標(biāo)記;
- 標(biāo)記屬性,例如 ?
disabled
?、?async
?、?defer
? 以及何時使用 ?data-*
?; - 知道如何聲明 ?
doctype
?(大多數(shù)人不是每天都會寫新頁面,所以可能會忘了這個)以及可以使用哪些元標(biāo)簽; - 可訪問性問題,例如,確保輸入復(fù)選框具有更大的響應(yīng)區(qū)域(使用標(biāo)簽“?
for
?”)。另外還有 ?role="button"
?、?role="presentation"
?,等等。
系統(tǒng)設(shè)計
在系統(tǒng)設(shè)計方面,通常涉及 MapReduce、分布式鍵值存儲系統(tǒng)或 CAP 定理等知識。雖然前端工程師日常不需要深入了解如何設(shè)計這類系統(tǒng),但在被要求設(shè)計出常見應(yīng)用程序的前端架構(gòu)時,你也不應(yīng)該感到驚訝。這些問題通常含糊不清,比如“設(shè)計一個像 Pinterest 這樣的網(wǎng)站”或者“如何構(gòu)建購物結(jié)賬服務(wù)?”。以下是需要考慮的知識點:
- 渲染——客戶端渲染(CSR)、服務(wù)器端渲染(SSR)和全局渲染;
- 布局——如果你正在設(shè)計被多個開發(fā)團(tuán)隊使用的系統(tǒng),需要考慮進(jìn)行組件化,以及是否需要開發(fā)團(tuán)隊通過指定標(biāo)記來使用組件;
- 狀態(tài)管理,例如在單向數(shù)據(jù)流或雙向數(shù)據(jù)綁定之間做出選擇。你還應(yīng)該考慮你的設(shè)計是采用被動式還是反應(yīng)式編程模型,以及組件如何相互關(guān)聯(lián),例如是 Foo->Bar 還是 Foo->Bar;
- 異步——你的組件可能需要與服務(wù)器進(jìn)行實時的通信。在設(shè)計時需要考慮使用 XHR 或雙向調(diào)用。如果你的面試官要求你支持舊瀏覽器,那么你需要在隱藏 iFrame、script 標(biāo)簽或 XHR 之間做出選擇。如果沒有,你可以建議使用 websocket,或者使用服務(wù)器發(fā)送事件(SSE),這樣會更好;
- 關(guān)注點分離——Model-View-Controller(MVC)、Model-View-ViewModel(MVVM)和 Model-View-Presenter(MVP)模式;
- 多設(shè)備支持——你的實現(xiàn)是否同時支持 Web、移動 Web 和混合應(yīng)用程序,還是為每一種場景提供單獨的實現(xiàn)?如果你正在構(gòu)建像 Pinterest 這樣的網(wǎng)站,你可能會考慮在 Web 上使用三列,但在移動設(shè)備上只使用一列,你的設(shè)計將如何處理這個問題;
- 資產(chǎn)文件交付——在大型應(yīng)用程序中,獨立團(tuán)隊擁有自己的代碼庫是常有的事。這些不同的代碼庫可能彼此依賴,每個代碼庫通常都有自己的管道來發(fā)布代碼變更。你的設(shè)計需要考慮如何基于依賴項進(jìn)行資產(chǎn)文件的構(gòu)建(代碼拆分)、測試(單元測試和集成測試)和部署。你還需要考慮如何通過 CDN 交付資產(chǎn)文件或者內(nèi)聯(lián)它們來減少網(wǎng)絡(luò)延遲。
Web 性能
除了通用編程最佳實踐之外,你應(yīng)該期望訪問者查看你的代碼或設(shè)計及其性能影響。它曾經(jīng)足以將 CSS 置于文檔的頂部,而 JS 腳本位于頁面底部,但 Web 正在快速移動,你應(yīng)該熟悉這個領(lǐng)域的復(fù)雜性。
- 關(guān)鍵渲染路徑;
- Service Worker;
- 圖像優(yōu)化;
- 延遲加載和捆綁拆分;
- HTTP/2 和服務(wù)器推送的一般含義;
- 何時預(yù)取和預(yù)加載資源;
- 減少瀏覽器回流以及何時將元素提升到 GPU;
- 瀏覽器布局、組合和繪制之間的區(qū)別。
數(shù)據(jù)結(jié)構(gòu)和算法
這個可能有點爭議,但對 Big-O 時間復(fù)雜性和常見運行時間(如 O(N) 和 O(N Log N))有一個基本的了解對你來說不會是壞事。單頁應(yīng)用程序現(xiàn)在非常常見,所以了解內(nèi)存管理等方面的知識是有幫助的。例如,如果你被要求構(gòu)建客戶端拼寫檢查程序,那么了解常見的數(shù)據(jù)結(jié)構(gòu)和算法將會讓你的任務(wù)變得輕松許多。
我不是說你一定需要念一個計算機(jī)學(xué)位,但這個行業(yè)已經(jīng)從構(gòu)建簡單的網(wǎng)頁轉(zhuǎn)移到了計算機(jī)科學(xué)。網(wǎng)上有很多資源可以讓那個你快速掌握基礎(chǔ)知識。
一般的 Web 知識
你需要掌握一些構(gòu)成 Web 的技術(shù)和范式。
- HTTP 請求——GET 和 POST 以及相關(guān)標(biāo)頭,如 Cache-Control、ETag、Status Codes 和 Transfer-Encoding;
- REST 與 RPC;
- 安全性——何時使用 JSONP、COR 和 iFrame。
總結(jié)
對 Web 開發(fā)人員或工程師來說,構(gòu)建 Web 應(yīng)用程序需要掌握大量的知識。不要被知識的深度所限制,而是要保持開放的心態(tài)去學(xué)習(xí)所有復(fù)雜的部分。
除了這里涉及的技術(shù)主題之外,你還需要討論過去參與的項目,描述發(fā)生了哪些有趣的事情以及做出了哪些權(quán)衡。
文章出處 | 前端之巔
想要學(xué)習(xí)更多編程知識請前往 W3Cschool官網(wǎng),隨時隨地學(xué)編程。