App下載

那些巨頭公司的前端面試都喜歡問些什么?

青絲繭 2021-03-06 17:20:05 瀏覽數(shù) (4420)
反饋

在過去的幾年里,我在亞馬遜和雅虎面試過很多專注于前端開發(fā)的 Web 開發(fā)者和軟件工程師,在這篇文章中,我想分享一些面試技巧,幫助候選人為面試做好準(zhǔn)備。

免責(zé)聲明——本文并非旨在列出在前端面試中可能會(huì)被問到的所有問題,但可以將其視為知識(shí)的基線。

通過面試不是件容易的事,作為候選人,通常需要在 45 分鐘的時(shí)間內(nèi)展示自己能做些什么。作為一名面試官,同樣難以在這么短的時(shí)間內(nèi)評(píng)估候選人是否適合。對(duì)于面試來說,并不存在一刀切的方法,面試官問的問題通常會(huì)有一個(gè)范圍,但除此之外,他們可以自行決定要問哪些其他問題。

作為曾經(jīng)的候選人和面試官,我試圖在這篇文章中涵蓋你可能會(huì)在面試中被問到的最重要的前端開發(fā)知識(shí)。

常見的誤解

我見過候選人犯的最大錯(cuò)誤之一就是準(zhǔn)備了一些瑣碎的問題,例如“什么是盒子模型”或者“JavaScript 中的 ?==? 和 ?===? 之間的區(qū)別是什么”。知道這些問題的答案固然是好,但這并不會(huì)告訴面試官來太多有用的信息。

相反,在實(shí)際的面試中,你可能需要使用 JavaScript、CSS 和 HTML 來編寫代碼。在你的面試期間,你可能需要實(shí)現(xiàn) UI、構(gòu)建窗口小部件或使用 Lodash 和 Underscore.js 這樣的庫(kù)編寫常用的實(shí)用程序函數(shù)。例如:

  • 構(gòu)建常見的 Web 應(yīng)用程序的布局和交互,例如類似 Netflix 網(wǎng)站那樣的。
  • 實(shí)現(xiàn)小部件,如日期選擇器、輪播或電子商務(wù)網(wǎng)站購(gòu)物車。
  • 寫一個(gè)類似 ?debounce? 或深度 ?clone? 對(duì)象的函數(shù)。

說到庫(kù),我看到候選人經(jīng)常犯的另一個(gè)錯(cuò)誤是他們需要完全依賴最新的框架來解決面試問題。你可能會(huì)想,如果我可以在生產(chǎn)環(huán)境中使用 jQuery、React、Angular 等,那為什么就不能在面試中使用它們呢?技術(shù)、框架和庫(kù)會(huì)隨著時(shí)間的推移而發(fā)生變化——我更感興趣的是你是否了解前端開發(fā)的底層原理,而不是依賴更高層次的抽象。如果你不能在沒有它們的情況下回答面試問題,我希望你至少可以徹底解釋和推測(cè)這些庫(kù)背后的原理。

總的來說,大部分的面試都涉及實(shí)際的編碼。

JavaScript

你需要了解 JavaScript,而且是徹底地了解。你面試的職位越高,對(duì)語(yǔ)言知識(shí)的要求就越高。以下是你應(yīng)該熟悉的 JavaScript 知識(shí)點(diǎn):

  • 執(zhí)行上下文,尤其是詞法作用域和閉包;
  • 提升、函數(shù)和塊作用域,以及函數(shù)表達(dá)式和聲明;
  • 綁定——特別是 ?call?、?bind?、?apply? 和 ?this?;
  • 對(duì)象原型、構(gòu)造函數(shù)和 ?mixin?;
  • 組合和高階函數(shù);
  • 事件委托和冒泡;
  • 使用 ?typeof?、?instanceof ?和 ?Object.prototype.toString? 進(jìn)行類型轉(zhuǎn)換;
  • 使用回調(diào)、?promise?、?await? 和 ?async? 處理異步調(diào)用;
  • 什么時(shí)候可以使用函數(shù)聲明和表達(dá)式。

DOM

知道如何遍歷和操作 DOM 非常重要,對(duì)于重度依賴 jQuery 或者開發(fā)了很多 React & Angular 類型應(yīng)用程序的候選人來說,他們可能會(huì)在這個(gè)問題上栽跟斗。你可能不會(huì)每天都直接接觸 DOM,因?yàn)槲覀兇蠖鄶?shù)人都在使用各種抽象。在不使用第三方庫(kù)的情況下,你需要知道如何執(zhí)行以下這些操作:

  • 使用 ?document.querySelector? 選擇或查找節(jié)點(diǎn),在舊版瀏覽器中使用 ?document.getElementsByTagName?;
  • 上下遍歷——?Node.parentNode?、?Node.firstChild?、?Node.lastChild? 和 ?Node.childNodes?;
  • 左右遍歷——?Node.previousSibling?和 ?Node.nextSibling?;
  • 操作——在 DOM 樹中添加、刪除、復(fù)制和創(chuàng)建節(jié)點(diǎn)。你應(yīng)該了解如何修改節(jié)點(diǎn)的文本內(nèi)容以及切換、刪除或添加 CSS 類名等操作;
  • 性能——當(dāng)有很多節(jié)點(diǎn)時(shí),修改 DOM 的成本會(huì)很高,你至少應(yīng)該知道如何使用文檔片段和節(jié)點(diǎn)緩存。

CSS

至少,你應(yīng)該知道如何在頁(yè)面上布局元素,如何使用子元素或直接后代選擇器來定位元素,以及什么時(shí)候該用類、什么時(shí)候該用 ID。

  • 布局——安排彼此相鄰的元素的位置,以及如何將元素布置成兩列或三列;
  • 響應(yīng)式設(shè)計(jì)——根據(jù)瀏覽器寬度大小更改元素的尺寸;
  • 自適應(yīng)設(shè)計(jì)——根據(jù)特定斷點(diǎn)更改元素的尺寸;
  • 特異性——如何計(jì)算選擇器的特異性,以及級(jí)聯(lián)如何影響屬性;
  • 適當(dāng)?shù)拿臻g和類命名。

HTML

知道哪些 HTML 標(biāo)簽最能代表你正在顯示的內(nèi)容以及相關(guān)屬性,應(yīng)該掌握手工知識(shí)。

  • 語(yǔ)義標(biāo)記;
  • 標(biāo)記屬性,例如 ?disabled?、?async?、?defer? 以及何時(shí)使用 ?data-*?;
  • 知道如何聲明 ?doctype?(大多數(shù)人不是每天都會(huì)寫新頁(yè)面,所以可能會(huì)忘了這個(gè))以及可以使用哪些元標(biāo)簽;
  • 可訪問性問題,例如,確保輸入復(fù)選框具有更大的響應(yīng)區(qū)域(使用標(biāo)簽“?for?”)。另外還有 ?role="button"?、?role="presentation"?,等等。

系統(tǒng)設(shè)計(jì)

在系統(tǒng)設(shè)計(jì)方面,通常涉及 MapReduce、分布式鍵值存儲(chǔ)系統(tǒng)或 CAP 定理等知識(shí)。雖然前端工程師日常不需要深入了解如何設(shè)計(jì)這類系統(tǒng),但在被要求設(shè)計(jì)出常見應(yīng)用程序的前端架構(gòu)時(shí),你也不應(yīng)該感到驚訝。這些問題通常含糊不清,比如“設(shè)計(jì)一個(gè)像 Pinterest 這樣的網(wǎng)站”或者“如何構(gòu)建購(gòu)物結(jié)賬服務(wù)?”。以下是需要考慮的知識(shí)點(diǎn):

  • 渲染——客戶端渲染(CSR)、服務(wù)器端渲染(SSR)和全局渲染;
  • 布局——如果你正在設(shè)計(jì)被多個(gè)開發(fā)團(tuán)隊(duì)使用的系統(tǒng),需要考慮進(jìn)行組件化,以及是否需要開發(fā)團(tuán)隊(duì)通過指定標(biāo)記來使用組件;
  • 狀態(tài)管理,例如在單向數(shù)據(jù)流或雙向數(shù)據(jù)綁定之間做出選擇。你還應(yīng)該考慮你的設(shè)計(jì)是采用被動(dòng)式還是反應(yīng)式編程模型,以及組件如何相互關(guān)聯(lián),例如是 Foo->Bar 還是 Foo->Bar;
  • 異步——你的組件可能需要與服務(wù)器進(jìn)行實(shí)時(shí)的通信。在設(shè)計(jì)時(shí)需要考慮使用 XHR 或雙向調(diào)用。如果你的面試官要求你支持舊瀏覽器,那么你需要在隱藏 iFrame、script 標(biāo)簽或 XHR 之間做出選擇。如果沒有,你可以建議使用 websocket,或者使用服務(wù)器發(fā)送事件(SSE),這樣會(huì)更好;
  • 關(guān)注點(diǎn)分離——Model-View-Controller(MVC)、Model-View-ViewModel(MVVM)和 Model-View-Presenter(MVP)模式;
  • 多設(shè)備支持——你的實(shí)現(xiàn)是否同時(shí)支持 Web、移動(dòng) Web 和混合應(yīng)用程序,還是為每一種場(chǎng)景提供單獨(dú)的實(shí)現(xiàn)?如果你正在構(gòu)建像 Pinterest 這樣的網(wǎng)站,你可能會(huì)考慮在 Web 上使用三列,但在移動(dòng)設(shè)備上只使用一列,你的設(shè)計(jì)將如何處理這個(gè)問題;
  • 資產(chǎn)文件交付——在大型應(yīng)用程序中,獨(dú)立團(tuán)隊(duì)擁有自己的代碼庫(kù)是常有的事。這些不同的代碼庫(kù)可能彼此依賴,每個(gè)代碼庫(kù)通常都有自己的管道來發(fā)布代碼變更。你的設(shè)計(jì)需要考慮如何基于依賴項(xiàng)進(jìn)行資產(chǎn)文件的構(gòu)建(代碼拆分)、測(cè)試(單元測(cè)試和集成測(cè)試)和部署。你還需要考慮如何通過 CDN 交付資產(chǎn)文件或者內(nèi)聯(lián)它們來減少網(wǎng)絡(luò)延遲。

Web 性能

除了通用編程最佳實(shí)踐之外,你應(yīng)該期望訪問者查看你的代碼或設(shè)計(jì)及其性能影響。它曾經(jīng)足以將 CSS 置于文檔的頂部,而 JS 腳本位于頁(yè)面底部,但 Web 正在快速移動(dòng),你應(yīng)該熟悉這個(gè)領(lǐng)域的復(fù)雜性。

  • 關(guān)鍵渲染路徑;
  • Service Worker;
  • 圖像優(yōu)化;
  • 延遲加載和捆綁拆分;
  • HTTP/2 和服務(wù)器推送的一般含義;
  • 何時(shí)預(yù)取和預(yù)加載資源;
  • 減少瀏覽器回流以及何時(shí)將元素提升到 GPU;
  • 瀏覽器布局、組合和繪制之間的區(qū)別。

數(shù)據(jù)結(jié)構(gòu)和算法

這個(gè)可能有點(diǎn)爭(zhēng)議,但對(duì) Big-O 時(shí)間復(fù)雜性和常見運(yùn)行時(shí)間(如 O(N) 和 O(N Log N))有一個(gè)基本的了解對(duì)你來說不會(huì)是壞事。單頁(yè)應(yīng)用程序現(xiàn)在非常常見,所以了解內(nèi)存管理等方面的知識(shí)是有幫助的。例如,如果你被要求構(gòu)建客戶端拼寫檢查程序,那么了解常見的數(shù)據(jù)結(jié)構(gòu)和算法將會(huì)讓你的任務(wù)變得輕松許多。

我不是說你一定需要念一個(gè)計(jì)算機(jī)學(xué)位,但這個(gè)行業(yè)已經(jīng)從構(gòu)建簡(jiǎn)單的網(wǎng)頁(yè)轉(zhuǎn)移到了計(jì)算機(jī)科學(xué)。網(wǎng)上有很多資源可以讓那個(gè)你快速掌握基礎(chǔ)知識(shí)。

一般的 Web 知識(shí)

你需要掌握一些構(gòu)成 Web 的技術(shù)和范式。

  • HTTP 請(qǐng)求——GET 和 POST 以及相關(guān)標(biāo)頭,如 Cache-Control、ETag、Status Codes 和 Transfer-Encoding;
  • REST 與 RPC;
  • 安全性——何時(shí)使用 JSONP、COR 和 iFrame。

總結(jié)

對(duì) Web 開發(fā)人員或工程師來說,構(gòu)建 Web 應(yīng)用程序需要掌握大量的知識(shí)。不要被知識(shí)的深度所限制,而是要保持開放的心態(tài)去學(xué)習(xí)所有復(fù)雜的部分。

除了這里涉及的技術(shù)主題之外,你還需要討論過去參與的項(xiàng)目,描述發(fā)生了哪些有趣的事情以及做出了哪些權(quán)衡。

文章出處 | 前端之巔

想要學(xué)習(xí)更多編程知識(shí)請(qǐng)前往 W3Cschool官網(wǎng),隨時(shí)隨地學(xué)編程。


3 人點(diǎn)贊