[譯] 以面試官的角度來看 React 工做面試

圖片來自於 unsplash 上的 rawpixel前端

重要說明 本文並不會列出在 React 工做面試中會出現的常規問題和問題的完整回答。這篇文章的重點是展現我提出的問題,我在答案中尋找的內容以及爲何沒有很差的答案。若是你想要一份「最佳面試問題2018」的集合,請查看 github.com/sudheerj/re…react

個人部分工做職責是執行所謂的「技術面試」,在面試時我會評估申請「React 前端開發」職位的潛在候選人。android

若是你曾經用谷歌搜索「React 面試問題」(或任何其餘「[技術]面試問題」),你可能已經看過無數「十大 React 面試問題」,這些問題要麼已通過時,要麼和「state 和 props 之間有什麼不一樣」或「什麼是虛擬 dom」 這些問題重複。ios

知道這些問題的答案不該該是面試官決定是否錄用你的依據。這些知識點都是候選人在平常工做中須要瞭解,理解和實現的。若是你被問到這樣的問題,要麼是面試你的人沒有技術背景(HR 或「獵頭」),要麼他們認爲這是一種形式。git

面試不該該浪費時間。它應該讓你瞭解候選人的過去經歷,過去的知識和發展機會。候選人應該瞭解您的公司和項目(若是可能),並得出他的表現是否符合你對這個職位候選人的指望的反饋。在求職面試中沒有很差的答案(除非問題嚴格是技術性的)—— 他的答案應該能讓你審視這我的的思考過程。github

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

讓咱們相互瞭解對方

在許多狀況下,面試將經過 Skype 或其餘語音(或語音+視頻)通訊平臺進行。嘗試去了解有可能成爲員工的人是一個讓他們放開本身的好方法。編程

你能告訴我一些你之前的工做,你是如何適應團隊的嗎?你的職責是什麼?

瞭解這我的在他之前的公司作了什麼(若是他被容許分享的話)是一個很好的開始。這給你一些關於他之前工做經驗的基本想法:軟技能(「我是……的惟一開發人員」,「我和個人同事……」,「我管理了一個由 6 名開發人員組成的團隊……」)和硬技能(「 ……咱們建立了一個一百萬人使用的應用程序」,「……我幫助優化了應用程序的渲染時間」,「……建立了不少自動化測試」)。後端

對你來講 React 的主要賣點是什麼。爲何選擇使用 React?

我並不指望你提到 JSX,VDOM 等等。—— 咱們已經能夠經過閱讀 React 主頁上的「特點」導語獲得這些東西。 爲何使用 React?數組

是由於「易上手,難掌握」 的 API(和其它解決方案相比它的確是很是輕量)?好 —— 這麼說的話,意味着你願意學習新事物,而且隨學隨用。

是由於更多的「就業機會」嗎?不錯 —— 你是一個可以適應市場的人,而且在下一個大框架到來的 5 年內不會有任何問題。咱們已經有足夠的 jQuery 開發人員了。

想一想這有點像「電梯遊說」情景(你和你的老闆在電梯裏,而且須要說服他在 20 樓走出電梯門以前使用新技術)。我想知道你是否瞭解 React 能給用戶和開發者帶來什麼好處。

讓咱們開始聊些更有技術性的問題

正如我在一段開頭提到的那樣 —— 我不會問你 VDOM 是什麼。咱們都知道它,但我會問你……

什麼是 JSX 和咱們怎樣在 JavaScript 代碼中書寫它 —— 瀏覽器是如何識別它的?

你知道 —— JSX 只是一種 Facebook 普及的標記語法,受益於 Babel/TSC 這些工具 —— 咱們可以以一種更令賞心悅目的方式書寫 React.createElement 調用。

爲何我會問這個問題?我想知道你是否理解 JSX 的技術原理以及隨之而來的限制:爲何甚至在咱們的代碼並無使用 React 的狀況下,也須要在文件頂部 import React from 'react';爲何組件不能直接返回多個元素。

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

額外加分點:此規則有不少例外。例如:把一個組件賦給 this.component 而且寫 <this.component /> 也會起做用。

在 React 中你能夠聲明的兩種主要組件類型是什麼以及使用時怎樣在二者間選擇?

一些人會認爲這道題是關於展現組件和容器組件的,但其實是關於 React.Component 和函數組件。

恰當的回答應該說起生命週期函數和組件狀態。

因爲咱們提到了生命週期 —— 你能跟我講一遍掛載狀態組件的生命週期嗎?哪些函數按何種順序被調用?你會把向 API 的數據請求放在哪裏執行?爲何?

好,這個問題有點長。請隨意把它分紅兩個小問題。你如今會想「但你說你不會問關於生命週期的內容啊!」。我不會問,我不關心生命週期。我關心的實際上是最近幾個月生命週期發生的變化。

若是回答包含 componentWillMount,你能夠假設此人一直在使用舊版本的 React,或者學了一些過期的教程。兩種狀況都會引發一些擔心。getDerivedStateFromProps 纔是你在尋找的答案。

額外加分點:提到在服務端上處理方式不一樣。

關於數據獲取的問題也是如此 —— componentDidMount 是你想要/聽到的之一。

加分題:爲何用 componentDidMount 而不是 constructor
你但願聽到的兩個緣由會是:「在渲染髮生以前數據不會存在」 —— 雖然不是主要緣由,但它向您顯示該人員瞭解組件的處理方式; 「在 React Fiber 中使用新的異步渲染……」 —— 有人一直在努力學習。

咱們剛纔提到經過 API 獲取數據 —— 你是如何保證在組件從新掛載以後不會從新獲取數據?

咱們假設不存在「緩存失效」。這個點和 React 關聯性並不大,不過若是回答限制在 React 範圍內,也是不錯的 一 也許他使用的 GraphQL 的方法對你來講過於繁重?

我問這個問題的目的,是考察候選人是否理解在應用中 UI 須要與其餘層解耦的理念。能夠說起一個 React 架構外部的 API。

你能解釋下「狀態提高」理念嗎?

好,我確實問了一些典型的 React 問題。不過這一個是相當重要的,容許你給候選人一些放鬆空間。

首選答案是「它容許你在兄弟組件間傳遞數據」或「它容許你擁有更多純展現組件,更易複用」。在這裏也許會提到 Redux,不過這可能也是一件壞事,由於它表示候選人只是跟隨社區推薦的任何東西,而不理解他爲何須要它。

加分題:若是不能在組件間傳遞數據,你怎樣給多級組件傳遞數據? 自從 React 16.3 開始,Context 已經成爲主流 —— 它以前就已經存在了,不過文檔是缺失的(有意爲之)。若是能在解釋出 Context 的工做方式(同時能表現出知道 function-as-child 模式)會是加分項。

若是這裏能提到 Redux 或 MobX 也很好。

React 生態

開發 React 應用只是流程的一部分 —— 還有更多的要作:調試、測試和文檔。

你是怎樣調試 React 代碼問題的,你用哪些工具?你會怎樣調查組件沒有從新渲染的問題?

每一個人都應該熟悉像 linter(eslint,jslint)和調試工具(React Developer Tools)這些基本工具。

使用 RDT 來調試問題並經過檢查組件 state/props 是否正確是一個不錯的答案,若是能提到用 Developer Tools 來打斷點也是很好的回答。

你用過哪些測試工具來寫 unit/E2E 測試?快照測試是什麼及它的好處?

在大多數狀況下測試是「不可避免的麻煩」,但它們又是咱們所須要的。有不少優秀的答案:karma、mocha、jasmin、jest、cypres、selenium、enzyme、react-test-library 等等。最糟糕的事是候選人回答「上一家公司咱們不作單元測試,只有人工測試」。

快照測試部分的回答依賴於你的項目裏用了什麼;若是你以爲它不是頗有用就不要問及。可是若是以爲有用 —— 答案就是「用於 HTML + CSS 生成的 UI 層的便捷迴歸測試」。

小型的代碼挑戰

若是有可能,我也會讓候選人來作一些小型的代碼挑戰,解決/解釋它們不該該花費超過一兩分鐘,例如:

/**
* 這個例子有什麼問題,要如何修改或改進這個組件?
*/

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,實現 getDerivedStateFromProps 或者更好的方式是把該組件變爲函數組件。

/**
 * 這幾個向組件傳遞函數的方式,你能解釋它們的不一樣嗎?
 *
 * 當你點擊每一個按鈕會發生什麼?
 */

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>
        <button onClick={this.handleClick1}>click 2</button>
        <button onClick={this.handleClick2}>click 3</button>
        <button onClick={this.handleClick3}>click 4</button>
      </div>
    );
  }
}
複製代碼

這道題要稍微費點功夫,由於代碼比較多。若是候選人回答正確緊接着問「爲何?」。爲何 click 2 這會以這種方式運行?

這個不是 React 問題,若是有人的回答以「由於在 React 中……」開始,這說明他們沒有真正理解 JS 事件循環機制。

/**
 * 這個組件有什麼問題。爲何?要如何解決呢?
 */

class App extends React.Component {

state = { search: '' }

handleChange = event => {

/**
     * 這是「防抖」函數的簡單實現,它會以隊列的方式在 250 ms 內調用
     * 表達式並取消全部掛起的隊列表達式。以這種方式咱們能夠在用戶中止輸
     * 入時延遲 250 ms 來調用表達式。
     */
    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>
    )
  }
}
複製代碼

好,這道題就須要一些解釋了。在防抖函數中並無錯誤。那麼應用會定期望方式運行嗎?它會在用戶中止輸入的 250 ms 以後更新而且渲染字符串「Search for: …」嗎?

這裏的問題是在 React 中 event 是一個 SyntheticEvent,若是和它的交互被延遲了(例如:經過 setTimeout),事件會被清除而且 .target.value 引用不會再有效。

額外加分點:候選人要能解釋出爲何。

技術問題環節完畢

這應該足夠你瞭解候選人的技能了。不過你還要爲開放問答留一些時間。

你在過去的項目裏遇到的最大問題是什麼?你最大的成就?

這就回到第一個問題了 —— 答案可能因開發人員以及職位而異。初級開發人員會說他最大的問題是在一個複雜的過程當中報錯,但他能夠征服它。尋找更高級職位的人將解釋他如何優化應用程序性能,而帶領團隊的人會解釋他如何經過結對編程提升速度。

若是你有無限的時間預算並讓你解決/提高/改變你最後一個項目裏的一項東西,你會選什麼,以及爲何選它?

而別的開放問題則要看你要在候選人身上尋找什麼。他會嘗試用 MobX 替換 Redux 嗎?改進測試設置?寫出更好的文檔?

對調錶格和反饋

如今是時候改變角色了。你可能已經對候選人的技能和成長潛力有了充分的瞭解。讓他問些問題 —— 這不只可讓他更多地瞭解公司和產品,他問的問題可能會給你一些關於他想要成長方向的指示。

Carl Vitullo 寫過一些關於要問你的潛在僱主的問題的好文章,我會推薦給你 —— 準備好回答他們,除非由於保密協議或別的須要讓你不能問某些特定問題:

給予反饋

若是候選人在某些問題上表現不佳或者回答錯誤(或者與你預期不一樣)—— 這時你可能但願澄清這些問題。不要讓它聽起來像是在青睞此人,只要解釋你注意到的問題 —— 提供解決方案和一些他能夠用來改善本身的資源。

若是招聘過程的其他部分取決於您,請告訴他們您將在 X 天內回覆他們,若是沒有,請告訴他們大家公司的某我的會這樣作。若是您知道該過程須要超過 2-3 天,請告訴他們。如今 IT 是一個很大的市場,候選人可能已經進行了屢次面試 —— 他可能會接受另外一個 offer 而不會等你的反饋。

不要輕視候選人 —— 這實際上是人們在社交媒體上常常抱怨的。

本篇文章中表達的是我本身的觀點,不能表明我過去或現任僱主,客戶或合做者的意見。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索