以面試官的角度來(lái)看 React 工作面試

image

圖片來(lái)自于 unsplash 上的 rawpixel

重要說(shuō)明 本文并不會(huì)列出在 React 工作面試中會(huì)出現(xiàn)的常規(guī)問(wèn)題和問(wèn)題的完整回答。這篇文章的重點(diǎn)是展示我提出的問(wèn)題,我在答案中尋找的內(nèi)容以及為什么沒(méi)有不好的答案。如果你想要一份“最佳面試問(wèn)題2018”的集合,請(qǐng)查看 https://github.com/sudheerj/reactjs-interview-questions

我的部分工作職責(zé)是執(zhí)行所謂的“技術(shù)面試”,在面試時(shí)我會(huì)評(píng)估申請(qǐng)“React 前端開發(fā)”職位的潛在候選人。

如果你曾經(jīng)用谷歌搜索“React 面試問(wèn)題”(或任何其他“[技術(shù)]面試問(wèn)題”),你可能已經(jīng)看過(guò)無(wú)數(shù)“十大 React 面試問(wèn)題”,這些問(wèn)題要么已經(jīng)過(guò)時(shí),要么和“state 和 props 之間有什么不同”或“什么是虛擬 dom” 這些問(wèn)題重復(fù)。

知道這些問(wèn)題的答案不應(yīng)該是面試官?zèng)Q定是否錄用你的依據(jù)。這些知識(shí)點(diǎn)都是候選人在日常工作中需要了解,理解和實(shí)現(xiàn)的。如果你被問(wèn)到這樣的問(wèn)題,要么是面試你的人沒(méi)有技術(shù)背景(HR 或“獵頭”),要么他們認(rèn)為這是一種形式。

面試不應(yīng)該浪費(fèi)時(shí)間。它應(yīng)該讓你了解候選人的過(guò)去經(jīng)歷,過(guò)去的知識(shí)和發(fā)展機(jī)會(huì)。候選人應(yīng)該了解您的公司和項(xiàng)目(如果可能),并得出他的表現(xiàn)是否符合你對(duì)這個(gè)職位候選人的期望的反饋。在求職面試中沒(méi)有不好的答案(除非問(wèn)題嚴(yán)格是技術(shù)性的)—— 他的答案應(yīng)該能讓你審視這個(gè)人的思考過(guò)程。

本篇文章以面試官的視角所寫!

讓我們相互了解對(duì)方

在許多情況下,面試將通過(guò) Skype 或其他語(yǔ)音(或語(yǔ)音+視頻)通信平臺(tái)進(jìn)行。嘗試去了解有可能成為員工的人是一個(gè)讓他們放開自己的好方法。

你能告訴我一些你以前的工作,你是如何適應(yīng)團(tuán)隊(duì)的嗎?你的職責(zé)是什么?

了解這個(gè)人在他以前的公司做了什么(如果他被允許分享的話)是一個(gè)很好的開始。這給你一些關(guān)于他以前工作經(jīng)驗(yàn)的基本想法:軟技能(“我是……的唯一開發(fā)人員”,“我和我的同事……”,“我管理了一個(gè)由 6 名開發(fā)人員組成的團(tuán)隊(duì)……”)和硬技能(“ ……我們創(chuàng)建了一個(gè)一百萬(wàn)人使用的應(yīng)用程序”,“……我?guī)椭鷥?yōu)化了應(yīng)用程序的渲染時(shí)間”,“……創(chuàng)建了很多自動(dòng)化測(cè)試”)。

對(duì)你來(lái)說(shuō) React 的主要賣點(diǎn)是什么。為什么你選擇使用 React?

我并不期望你提到 JSX,VDOM 等等。—— 我們已經(jīng)可以通過(guò)閱讀 React 主頁(yè)上的“特色”導(dǎo)語(yǔ)得到這些東西。你 為什么使用 React?

是因?yàn)椤耙咨鲜郑y掌握” 的 API(和其它解決方案相比它的確是非常輕量)?好 —— 這么說(shuō)的話,意味著你愿意學(xué)習(xí)新事物,并且隨學(xué)隨用。

是因?yàn)楦嗟摹熬蜆I(yè)機(jī)會(huì)”嗎?不錯(cuò) —— 你是一個(gè)能夠適應(yīng)市場(chǎng)的人,并且在下一個(gè)大框架到來(lái)的 5 年內(nèi)不會(huì)有任何問(wèn)題。我們已經(jīng)有足夠的 jQuery 開發(fā)人員了。

想想這有點(diǎn)像“電梯游說(shuō)”情景(你和你的老板在電梯里,并且需要說(shuō)服他在 20 樓走出電梯門之前使用新技術(shù))。我想知道你是否了解 React 能給用戶和開發(fā)者帶來(lái)什么好處。

讓我們開始聊些更有技術(shù)性的問(wèn)題

正如我在一段開頭提到的那樣 —— 我不會(huì)問(wèn)你 VDOM 是什么。我們都知道它,但我會(huì)問(wèn)你……

什么是 JSX 和我們?cè)鯓釉?JavaScript 代碼中書寫它 —— 瀏覽器是如何識(shí)別它的?

你知道 —— JSX 只是一種 Facebook 普及的標(biāo)記語(yǔ)法,受益于 Babel/TSC 這些工具 —— 我們能夠以一種更令賞心悅目的方式書寫 React.createElement 調(diào)用。

為什么我會(huì)問(wèn)這個(gè)問(wèn)題?我想知道你是否理解 JSX 的技術(shù)原理以及隨之而來(lái)的限制:為什么甚至在我們的代碼并沒(méi)有使用 React 的情況下,也需要在文件頂部 import React from 'react';為什么組件不能直接返回多個(gè)元素。

加分題:為什么 JSX 中的組件名要以大寫字母開頭?
能回答出 React 如何知道要渲染的是組件還是 HTML 元素就夠了。

額外加分點(diǎn):此規(guī)則有很多例外。例如:把一個(gè)組件賦給 this.component 并且寫 <this.component /> 也會(huì)起作用。

在 React 中你可以聲明的兩種主要組件類型是什么以及使用時(shí)怎樣在兩者間選擇?

一些人會(huì)認(rèn)為這道題是關(guān)于展示組件和容器組件的,但實(shí)際上是關(guān)于 React.Component 和函數(shù)組件。

恰當(dāng)?shù)幕卮饝?yīng)該提及生命周期函數(shù)和組件狀態(tài)。

由于我們提到了生命周期 —— 你能跟我講一遍掛載狀態(tài)組件的生命周期嗎?哪些函數(shù)按何種順序被調(diào)用?你會(huì)把向 API 的數(shù)據(jù)請(qǐng)求放在哪里執(zhí)行?為什么?

好,這個(gè)問(wèn)題有點(diǎn)長(zhǎng)。請(qǐng)隨意把它分成兩個(gè)小問(wèn)題。你現(xiàn)在會(huì)想“但你說(shuō)你不會(huì)問(wèn)關(guān)于生命周期的內(nèi)容啊!”。我不會(huì)問(wèn),我不關(guān)心生命周期。我關(guān)心的其實(shí)是最近幾個(gè)月生命周期發(fā)生的變化。

如果回答包含 componentWillMount,你可以假設(shè)此人一直在使用舊版本的 React,或者學(xué)了一些過(guò)時(shí)的教程。兩種情況都會(huì)引起一些擔(dān)憂。getDerivedStateFromProps 才是你在尋找的答案。

額外加分點(diǎn):提到在服務(wù)端上處理方式不同。

關(guān)于數(shù)據(jù)獲取的問(wèn)題也是如此 ——?componentDidMount 是你想要/聽到的之一。

加分題:為什么用 componentDidMount 而不是 constructor
你希望聽到的兩個(gè)原因會(huì)是:“在渲染發(fā)生之前數(shù)據(jù)不會(huì)存在” —— 雖然不是主要原因,但它向您顯示該人員了解組件的處理方式; “在 React Fiber 中使用新的異步渲染……” —— 有人一直在努力學(xué)習(xí)。

我們剛才提到通過(guò) API 獲取數(shù)據(jù) —— 你是如何保證在組件重新掛載之后不會(huì)重新獲取數(shù)據(jù)?

我們假設(shè)不存在“緩存失效”。這個(gè)點(diǎn)和 React 關(guān)聯(lián)性并不大,不過(guò)如果回答限制在 React 范圍內(nèi),也是不錯(cuò)的 一 也許他使用的 GraphQL 的方法對(duì)你來(lái)說(shuō)過(guò)于繁重?

我問(wèn)這個(gè)問(wèn)題的目的,是考察候選人是否理解在應(yīng)用中 UI 需要與其他層解耦的理念。可以提及一個(gè) React 架構(gòu)外部的 API。

你能解釋下“狀態(tài)提升”理念嗎?

好,我確實(shí)問(wèn)了一些典型的 React 問(wèn)題。不過(guò)這一個(gè)是至關(guān)重要的,允許你給候選人一些放松空間。

首選答案是“它允許你在兄弟組件間傳遞數(shù)據(jù)”或“它允許你擁有更多純展示組件,更易復(fù)用”。在這里也許會(huì)提到 Redux,不過(guò)這可能也是一件壞事,因?yàn)樗硎竞蜻x人只是跟隨社區(qū)推薦的任何東西,而不理解他為什么需要它。

加分題:如果不能在組件間傳遞數(shù)據(jù),你怎樣給多級(jí)組件傳遞數(shù)據(jù)? 自從 React 16.3 開始,Context 已經(jīng)成為主流 —— 它之前就已經(jīng)存在了,不過(guò)文檔是缺失的(有意為之)。如果能在解釋出 Context 的工作方式(同時(shí)能表現(xiàn)出知道 function-as-child 模式)會(huì)是加分項(xiàng)。

如果這里能提到 Redux 或 MobX 也很好。

React 生態(tài)

開發(fā) React 應(yīng)用只是流程的一部分 —— 還有更多的要做:調(diào)試、測(cè)試和文檔。

你是怎樣調(diào)試 React 代碼問(wèn)題的,你用哪些工具?你會(huì)怎樣調(diào)查組件沒(méi)有重新渲染的問(wèn)題?

每個(gè)人都應(yīng)該熟悉像 linter(eslint,jslint)和調(diào)試工具(React Developer Tools)這些基本工具。

使用 RDT 來(lái)調(diào)試問(wèn)題并通過(guò)檢查組件 state/props 是否正確是一個(gè)不錯(cuò)的答案,如果能提到用 Developer Tools 來(lái)打斷點(diǎn)也是很好的回答。

你用過(guò)哪些測(cè)試工具來(lái)寫 unit/E2E 測(cè)試?快照測(cè)試是什么及它的好處?

在大多數(shù)情況下測(cè)試是“不可避免的麻煩”,但它們又是我們所需要的。有很多優(yōu)秀的答案:karma、mocha、jasmin、jest、cypres、selenium、enzyme、react-test-library 等等。最糟糕的事是候選人回答“上一家公司我們不做單元測(cè)試,只有人工測(cè)試”。

快照測(cè)試部分的回答依賴于你的項(xiàng)目里用了什么;如果你覺得它不是很有用就不要問(wèn)及。但是如果覺得有用 —— 答案就是“用于 HTML + CSS 生成的 UI 層的便捷回歸測(cè)試”。

小型的代碼挑戰(zhàn)

如果有可能,我也會(huì)讓候選人來(lái)做一些小型的代碼挑戰(zhàn),解決/解釋它們不應(yīng)該花費(fèi)超過(guò)一兩分鐘,例如:

/**
* 這個(gè)例子有什么問(wèn)題,要如何修改或改進(jìn)這個(gè)組件?
*/

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: this.props.name || 'Anonymous'
    }
  }

  render() {
    return (
      <p>Hello {this.state.name}</p>
    );
  }
}

有很多方式來(lái)解決它:移除 state 并使用 props,實(shí)現(xiàn) getDerivedStateFromProps 或者更好的方式是把該組件變?yōu)楹瘮?shù)組件。

/**
 * 這幾個(gè)向組件傳遞函數(shù)的方式,你能解釋它們的不同嗎?
 *
 * 當(dāng)你點(diǎn)擊每個(gè)按鈕會(huì)發(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比較多。如果候選人回答正確緊接著問(wèn)“為什么?”。為什么 click 2 這會(huì)以這種方式運(yùn)行?

這個(gè)不是 React 問(wèn)題,如果有人的回答以“因?yàn)樵?React 中……”開始,這說(shuō)明他們沒(méi)有真正理解 JS 事件循環(huán)機(jī)制。

/**
 * 這個(gè)組件有什么問(wèn)題。為什么?要如何解決呢?
 */

class App extends React.Component {

state = { search: '' }

handleChange = event => {

/**
     * 這是“防抖”函數(shù)的簡(jiǎn)單實(shí)現(xiàn),它會(huì)以隊(duì)列的方式在 250 ms 內(nèi)調(diào)用
     * 表達(dá)式并取消所有掛起的隊(duì)列表達(dá)式。以這種方式我們可以在用戶停止輸
     * 入時(shí)延遲 250 ms 來(lái)調(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ù)中并沒(méi)有錯(cuò)誤。那么應(yīng)用會(huì)按期望方式運(yùn)行嗎?它會(huì)在用戶停止輸入的 250 ms 之后更新并且渲染字符串“Search for: …”嗎?

這里的問(wèn)題是在 React 中 event 是一個(gè) SyntheticEvent,如果和它的交互被延遲了(例如:通過(guò) setTimeout),事件會(huì)被清除并且 .target.value 引用不會(huì)再有效。

額外加分點(diǎn):候選人要能解釋出為什么。

技術(shù)問(wèn)題環(huán)節(jié)完畢

這應(yīng)該足夠你了解候選人的技能了。不過(guò)你還要為開放問(wèn)答留一些時(shí)間。

你在過(guò)去的項(xiàng)目里遇到的最大問(wèn)題是什么?你最大的成就?

這就回到第一個(gè)問(wèn)題了 —— 答案可能因開發(fā)人員以及職位而異。初級(jí)開發(fā)人員會(huì)說(shuō)他最大的問(wèn)題是在一個(gè)復(fù)雜的過(guò)程中報(bào)錯(cuò),但他可以征服它。尋找更高級(jí)職位的人將解釋他如何優(yōu)化應(yīng)用程序性能,而帶領(lǐng)團(tuán)隊(duì)的人會(huì)解釋他如何通過(guò)結(jié)對(duì)編程提高速度。

如果你有無(wú)限的時(shí)間預(yù)算并讓你解決/提升/改變你最后一個(gè)項(xiàng)目里的一項(xiàng)東西,你會(huì)選什么,以及為什么選它?

而別的開放問(wèn)題則要看你要在候選人身上尋找什么。他會(huì)嘗試用 MobX 替換 Redux 嗎?改進(jìn)測(cè)試設(shè)置?寫出更好的文檔?

對(duì)調(diào)表格和反饋

現(xiàn)在是時(shí)候改變角色了。你可能已經(jīng)對(duì)候選人的技能和成長(zhǎng)潛力有了充分的了解。讓他問(wèn)些問(wèn)題 —— 這不僅可以讓他更多地了解公司和產(chǎn)品,他問(wèn)的問(wèn)題可能會(huì)給你一些關(guān)于他想要成長(zhǎng)方向的指示。

Carl Vitullo 寫過(guò)一些關(guān)于要問(wèn)你的潛在雇主的問(wèn)題的好文章,我會(huì)推薦給你 —— 準(zhǔn)備好回答他們,除非因?yàn)楸C軈f(xié)議或別的需要讓你不能問(wèn)某些特定問(wèn)題:

  • 入職和工作場(chǎng)所

  • 發(fā)展和緊急情況

  • 成長(zhǎng)

給予反饋

如果候選人在某些問(wèn)題上表現(xiàn)不佳或者回答錯(cuò)誤(或者與你預(yù)期不同)—— 這時(shí)你可能希望澄清這些問(wèn)題。不要讓它聽起來(lái)像是在青睞此人,只要解釋你注意到的問(wèn)題 —— 提供解決方案和一些他可以用來(lái)改善自己的資源。

如果招聘過(guò)程的其余部分取決于您,請(qǐng)告訴他們您將在 X 天內(nèi)回復(fù)他們,如果沒(méi)有,請(qǐng)告訴他們你們公司的某個(gè)人會(huì)這樣做。如果您知道該過(guò)程需要超過(guò) 2-3 天,請(qǐng)告訴他們。現(xiàn)在 IT 是一個(gè)很大的市場(chǎng),候選人可能已經(jīng)進(jìn)行了多次面試 —— 他可能會(huì)接受另一個(gè) offer 而不會(huì)等你的反饋。

不要輕視候選人 —— 這其實(shí)是人們?cè)谏缃幻襟w上經(jīng)常抱怨的。

本篇文章中表達(dá)的是我自己的觀點(diǎn),不能代表我過(guò)去或現(xiàn)任雇主,客戶或合作者的意見。

如果發(fā)現(xiàn)譯文存在錯(cuò)誤或其他需要改進(jìn)的地方,歡迎到 掘金翻譯計(jì)劃 對(duì)譯文進(jìn)行修改并 PR,也可獲得相應(yīng)獎(jiǎng)勵(lì)積分。文章開頭的 本文永久鏈接 即為本文在 GitHub 上的 MarkDown 鏈接。

原文https://mp.weixin.qq.com/s?__biz=MzU3ODQ0MDY4MQ==&mid=2247484154&idx=1&sn=d462194d24c58eec9a49dc8b7fd52a0f&chksm=fd741e7cca03976a7c82b02474deb63c77d614356340953b1e2dcc20b4abef1bab2ec74dd51f&scene=21#wechat_redirect

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,155評(píng)論 25 708
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,897評(píng)論 2 59
  • 標(biāo)簽:工作 環(huán)境探索 人無(wú)遠(yuǎn)慮必有近憂 這句話是前人經(jīng)過(guò)無(wú)數(shù)次嘗試后總結(jié)出來(lái)的至理名言,放在現(xiàn)代社會(huì)也有很強(qiáng)的指...
    digman閱讀 298評(píng)論 0 0
  • 鳳九近來(lái)心情很好,今日尤甚。剛剛長(zhǎng)勵(lì)神秘兮兮地來(lái)告訴她,就在方才,少陽(yáng)君擇好了喜服的布料,已經(jīng)一同送去衣官那處。他...
    西西惟亞閱讀 4,265評(píng)論 4 59