圖片來自于 unsplash 上的 rawpixel
重要說明 本文并不會列出在 React 工作面試中會出現(xiàn)的常規(guī)問題和問題的完整回答。這篇文章的重點(diǎn)是展示我提出的問題,我在答案中尋找的內(nèi)容以及為什么沒有不好的答案。如果你想要一份“最佳面試問題2018”的集合搞挣,請查看 https://github.com/sudheerj/reactjs-interview-questions
我的部分工作職責(zé)是執(zhí)行所謂的“技術(shù)面試”,在面試時我會評估申請“React 前端開發(fā)”職位的潛在候選人。
如果你曾經(jīng)用谷歌搜索“React 面試問題”(或任何其他“[技術(shù)]面試問題”)以政,你可能已經(jīng)看過無數(shù)“十大 React 面試問題”,這些問題要么已經(jīng)過時伴找,要么和“state 和 props 之間有什么不同”或“什么是虛擬 dom” 這些問題重復(fù)盈蛮。
知道這些問題的答案不應(yīng)該是面試官決定是否錄用你的依據(jù)。這些知識點(diǎn)都是候選人在日常工作中需要了解技矮,理解和實(shí)現(xiàn)的抖誉。如果你被問到這樣的問題,要么是面試你的人沒有技術(shù)背景(HR 或“獵頭”)衰倦,要么他們認(rèn)為這是一種形式袒炉。
面試不應(yīng)該浪費(fèi)時間。它應(yīng)該讓你了解候選人的過去經(jīng)歷樊零,過去的知識和發(fā)展機(jī)會我磁。候選人應(yīng)該了解您的公司和項(xiàng)目(如果可能),并得出他的表現(xiàn)是否符合你對這個職位候選人的期望的反饋驻襟。在求職面試中沒有不好的答案(除非問題嚴(yán)格是技術(shù)性的)—— 他的答案應(yīng)該能讓你審視這個人的思考過程夺艰。
本篇文章以面試官的視角所寫!
讓我們相互了解對方
在許多情況下沉衣,面試將通過 Skype 或其他語音(或語音+視頻)通信平臺進(jìn)行郁副。嘗試去了解有可能成為員工的人是一個讓他們放開自己的好方法。
你能告訴我一些你以前的工作厢蒜,你是如何適應(yīng)團(tuán)隊(duì)的嗎霞势?你的職責(zé)是什么?
了解這個人在他以前的公司做了什么(如果他被允許分享的話)是一個很好的開始斑鸦。這給你一些關(guān)于他以前工作經(jīng)驗(yàn)的基本想法:軟技能(“我是……的唯一開發(fā)人員”愕贡,“我和我的同事……”,“我管理了一個由 6 名開發(fā)人員組成的團(tuán)隊(duì)……”)和硬技能(“ ……我們創(chuàng)建了一個一百萬人使用的應(yīng)用程序”巷屿,“……我?guī)椭鷥?yōu)化了應(yīng)用程序的渲染時間”固以,“……創(chuàng)建了很多自動化測試”)。
對你來說 React 的主要賣點(diǎn)是什么。為什么你選擇使用 React憨琳?
我并不期望你提到 JSX诫钓,VDOM 等等「菝—— 我們已經(jīng)可以通過閱讀 React 主頁上的“特色”導(dǎo)語得到這些東西菌湃。你 為什么使用 React?
是因?yàn)椤耙咨鲜直槁裕y掌握” 的 API(和其它解決方案相比它的確是非常輕量)惧所?好 —— 這么說的話,意味著你愿意學(xué)習(xí)新事物绪杏,并且隨學(xué)隨用下愈。
是因?yàn)楦嗟摹熬蜆I(yè)機(jī)會”嗎?不錯 —— 你是一個能夠適應(yīng)市場的人蕾久,并且在下一個大框架到來的 5 年內(nèi)不會有任何問題势似。我們已經(jīng)有足夠的 jQuery 開發(fā)人員了。
想想這有點(diǎn)像“電梯游說”情景(你和你的老板在電梯里僧著,并且需要說服他在 20 樓走出電梯門之前使用新技術(shù))履因。我想知道你是否了解 React 能給用戶和開發(fā)者帶來什么好處。
讓我們開始聊些更有技術(shù)性的問題
正如我在一段開頭提到的那樣 —— 我不會問你 VDOM 是什么霹抛。我們都知道它搓逾,但我會問你……
什么是 JSX 和我們怎樣在 JavaScript 代碼中書寫它 —— 瀏覽器是如何識別它的卷谈?
你知道 —— JSX 只是一種 Facebook 普及的標(biāo)記語法杯拐,受益于 Babel/TSC 這些工具 —— 我們能夠以一種更令賞心悅目的方式書寫 React.createElement
調(diào)用。
為什么我會問這個問題世蔗?我想知道你是否理解 JSX 的技術(shù)原理以及隨之而來的限制:為什么甚至在我們的代碼并沒有使用 React
的情況下端逼,也需要在文件頂部 import React from 'react'
;為什么組件不能直接返回多個元素污淋。
加分題:為什么 JSX 中的組件名要以大寫字母開頭顶滩?
能回答出 React 如何知道要渲染的是組件還是 HTML 元素就夠了。
額外加分點(diǎn):此規(guī)則有很多例外寸爆。例如:把一個組件賦給 this.component
并且寫 <this.component />
也會起作用礁鲁。
在 React 中你可以聲明的兩種主要組件類型是什么以及使用時怎樣在兩者間選擇?
一些人會認(rèn)為這道題是關(guān)于展示組件和容器組件的赁豆,但實(shí)際上是關(guān)于 React.Component
和函數(shù)組件仅醇。
恰當(dāng)?shù)幕卮饝?yīng)該提及生命周期函數(shù)和組件狀態(tài)。
由于我們提到了生命周期 —— 你能跟我講一遍掛載狀態(tài)組件的生命周期嗎魔种?哪些函數(shù)按何種順序被調(diào)用析二?你會把向 API 的數(shù)據(jù)請求放在哪里執(zhí)行?為什么?
好叶摄,這個問題有點(diǎn)長属韧。請隨意把它分成兩個小問題。你現(xiàn)在會想“但你說你不會問關(guān)于生命周期的內(nèi)容案蛳拧宵喂!”。我不會問会傲,我不關(guān)心生命周期樊破。我關(guān)心的其實(shí)是最近幾個月生命周期發(fā)生的變化。
如果回答包含 componentWillMount
唆铐,你可以假設(shè)此人一直在使用舊版本的 React哲戚,或者學(xué)了一些過時的教程。兩種情況都會引起一些擔(dān)憂艾岂。getDerivedStateFromProps
才是你在尋找的答案顺少。
額外加分點(diǎn):提到在服務(wù)端上處理方式不同。
關(guān)于數(shù)據(jù)獲取的問題也是如此 ——?componentDidMount
是你想要/聽到的之一王浴。
加分題:為什么用 componentDidMount
而不是 constructor
脆炎?
你希望聽到的兩個原因會是:“在渲染發(fā)生之前數(shù)據(jù)不會存在” —— 雖然不是主要原因,但它向您顯示該人員了解組件的處理方式; “在 React Fiber 中使用新的異步渲染……” —— 有人一直在努力學(xué)習(xí)氓辣。
我們剛才提到通過 API 獲取數(shù)據(jù) —— 你是如何保證在組件重新掛載之后不會重新獲取數(shù)據(jù)秒裕?
我們假設(shè)不存在“緩存失效”。這個點(diǎn)和 React 關(guān)聯(lián)性并不大钞啸,不過如果回答限制在 React 范圍內(nèi)几蜻,也是不錯的 一 也許他使用的 GraphQL 的方法對你來說過于繁重?
我問這個問題的目的体斩,是考察候選人是否理解在應(yīng)用中 UI 需要與其他層解耦的理念梭稚。可以提及一個 React 架構(gòu)外部的 API絮吵。
你能解釋下“狀態(tài)提升”理念嗎弧烤?
好,我確實(shí)問了一些典型的 React 問題蹬敲。不過這一個是至關(guān)重要的暇昂,允許你給候選人一些放松空間。
首選答案是“它允許你在兄弟組件間傳遞數(shù)據(jù)”或“它允許你擁有更多純展示組件伴嗡,更易復(fù)用”急波。在這里也許會提到 Redux,不過這可能也是一件壞事闹究,因?yàn)樗硎竞蜻x人只是跟隨社區(qū)推薦的任何東西幔崖,而不理解他為什么需要它。
加分題:如果不能在組件間傳遞數(shù)據(jù),你怎樣給多級組件傳遞數(shù)據(jù)赏寇? 自從 React 16.3 開始吉嫩,Context 已經(jīng)成為主流 —— 它之前就已經(jīng)存在了,不過文檔是缺失的(有意為之)嗅定。如果能在解釋出 Context 的工作方式(同時能表現(xiàn)出知道 function-as-child 模式)會是加分項(xiàng)自娩。
如果這里能提到 Redux 或 MobX 也很好。
React 生態(tài)
開發(fā) React 應(yīng)用只是流程的一部分 —— 還有更多的要做:調(diào)試渠退、測試和文檔忙迁。
你是怎樣調(diào)試 React 代碼問題的,你用哪些工具碎乃?你會怎樣調(diào)查組件沒有重新渲染的問題姊扔?
每個人都應(yīng)該熟悉像 linter(eslint,jslint)和調(diào)試工具(React Developer Tools)這些基本工具梅誓。
使用 RDT 來調(diào)試問題并通過檢查組件 state/props 是否正確是一個不錯的答案恰梢,如果能提到用 Developer Tools 來打斷點(diǎn)也是很好的回答。
你用過哪些測試工具來寫 unit/E2E 測試梗掰?快照測試是什么及它的好處嵌言?
在大多數(shù)情況下測試是“不可避免的麻煩”,但它們又是我們所需要的及穗。有很多優(yōu)秀的答案:karma摧茴、mocha、jasmin埂陆、jest苛白、cypres、selenium猜惋、enzyme丸氛、react-test-library 等等。最糟糕的事是候選人回答“上一家公司我們不做單元測試著摔,只有人工測試”。
快照測試部分的回答依賴于你的項(xiàng)目里用了什么定续;如果你覺得它不是很有用就不要問及谍咆。但是如果覺得有用 —— 答案就是“用于 HTML + CSS 生成的 UI 層的便捷回歸測試”。
小型的代碼挑戰(zhàn)
如果有可能私股,我也會讓候選人來做一些小型的代碼挑戰(zhàn)摹察,解決/解釋它們不應(yīng)該花費(fèi)超過一兩分鐘,例如:
/**
* 這個例子有什么問題倡鲸,要如何修改或改進(jìn)這個組件供嚎?
*/
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: this.props.name || 'Anonymous'
}
}
render() {
return (
<p>Hello {this.state.name}</p>
);
}
}
有很多方式來解決它:移除 state 并使用 props,實(shí)現(xiàn) getDerivedStateFromProps
或者更好的方式是把該組件變?yōu)楹瘮?shù)組件。
/**
* 這幾個向組件傳遞函數(shù)的方式克滴,你能解釋它們的不同嗎逼争?
*
* 當(dāng)你點(diǎn)擊每個按鈕會發(fā)生什么?
*/
class App extends React.Component {
constructor() {
super();
this.name = 'MyComponent';
this.handleClick2 = this.handleClick1.bind(this);
}
handleClick1() {
alert(this.name);
}
handleClick3 = () => alert(this.name);
render() {
return (
<div>
<button onClick={this.handleClick1()}>click 1</button> //MyComponent剛開始就只執(zhí)行
<button onClick={this.handleClick1}>click 2</button>//空
<button onClick={this.handleClick2}>click 3</button>//MyComponent
<button onClick={this.handleClick3}>click 4</button>//MyComponent
</div>
);
}
}
這道題要稍微費(fèi)點(diǎn)功夫劝赔,因?yàn)榇a比較多誓焦。如果候選人回答正確緊接著問“為什么?”着帽。為什么 click 2
這會以這種方式運(yùn)行杂伟?
這個不是 React 問題,如果有人的回答以“因?yàn)樵?React 中……”開始仍翰,這說明他們沒有真正理解 JS 事件循環(huán)機(jī)制赫粥。
/**
* 這個組件有什么問題。為什么予借?要如何解決呢傅是?
*/
class App extends React.Component {
state = { search: '' }
handleChange = event => {
/**
* 這是“防抖”函數(shù)的簡單實(shí)現(xiàn),它會以隊(duì)列的方式在 250 ms 內(nèi)調(diào)用
* 表達(dá)式并取消所有掛起的隊(duì)列表達(dá)式蕾羊。以這種方式我們可以在用戶停止輸
* 入時延遲 250 ms 來調(diào)用表達(dá)式喧笔。
*/
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.setState({
search: event.target.value
})
}, 250);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
{this.state.search ? <p>Search for: {this.state.search}</p> : null}
</div>
)
}
}
好,這道題就需要一些解釋了龟再。在防抖函數(shù)中并沒有錯誤书闸。那么應(yīng)用會按期望方式運(yùn)行嗎?它會在用戶停止輸入的 250 ms 之后更新并且渲染字符串“Search for: …”嗎利凑?
這里的問題是在 React 中 event
是一個 SyntheticEvent
浆劲,如果和它的交互被延遲了(例如:通過 setTimeout
),事件會被清除并且 .target.value
引用不會再有效哀澈。
額外加分點(diǎn):候選人要能解釋出為什么牌借。
技術(shù)問題環(huán)節(jié)完畢
這應(yīng)該足夠你了解候選人的技能了。不過你還要為開放問答留一些時間割按。
你在過去的項(xiàng)目里遇到的最大問題是什么膨报?你最大的成就?
這就回到第一個問題了 —— 答案可能因開發(fā)人員以及職位而異适荣。初級開發(fā)人員會說他最大的問題是在一個復(fù)雜的過程中報錯现柠,但他可以征服它。尋找更高級職位的人將解釋他如何優(yōu)化應(yīng)用程序性能弛矛,而帶領(lǐng)團(tuán)隊(duì)的人會解釋他如何通過結(jié)對編程提高速度够吩。
如果你有無限的時間預(yù)算并讓你解決/提升/改變你最后一個項(xiàng)目里的一項(xiàng)東西,你會選什么丈氓,以及為什么選它周循?
而別的開放問題則要看你要在候選人身上尋找什么强法。他會嘗試用 MobX 替換 Redux 嗎?改進(jìn)測試設(shè)置湾笛?寫出更好的文檔饮怯?
對調(diào)表格和反饋
現(xiàn)在是時候改變角色了。你可能已經(jīng)對候選人的技能和成長潛力有了充分的了解迄本。讓他問些問題 —— 這不僅可以讓他更多地了解公司和產(chǎn)品硕淑,他問的問題可能會給你一些關(guān)于他想要成長方向的指示。
Carl Vitullo 寫過一些關(guān)于要問你的潛在雇主的問題的好文章嘉赎,我會推薦給你 —— 準(zhǔn)備好回答他們置媳,除非因?yàn)楸C軈f(xié)議或別的需要讓你不能問某些特定問題:
入職和工作場所
發(fā)展和緊急情況
成長
給予反饋
如果候選人在某些問題上表現(xiàn)不佳或者回答錯誤(或者與你預(yù)期不同)—— 這時你可能希望澄清這些問題。不要讓它聽起來像是在青睞此人公条,只要解釋你注意到的問題 —— 提供解決方案和一些他可以用來改善自己的資源拇囊。
如果招聘過程的其余部分取決于您,請告訴他們您將在 X 天內(nèi)回復(fù)他們靶橱,如果沒有寥袭,請告訴他們你們公司的某個人會這樣做。如果您知道該過程需要超過 2-3 天关霸,請告訴他們〈疲現(xiàn)在 IT 是一個很大的市場,候選人可能已經(jīng)進(jìn)行了多次面試 —— 他可能會接受另一個 offer 而不會等你的反饋队寇。
不要輕視候選人 —— 這其實(shí)是人們在社交媒體上經(jīng)常抱怨的膘掰。
本篇文章中表達(dá)的是我自己的觀點(diǎn),不能代表我過去或現(xiàn)任雇主佳遣,客戶或合作者的意見识埋。
如果發(fā)現(xiàn)譯文存在錯誤或其他需要改進(jìn)的地方,歡迎到 掘金翻譯計(jì)劃 對譯文進(jìn)行修改并 PR零渐,也可獲得相應(yīng)獎勵積分窒舟。文章開頭的 本文永久鏈接 即為本文在 GitHub 上的 MarkDown 鏈接。