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

weixin_34253539發表於2018-10-20

圖片來自於 unsplash 上的 rawpixel

重要說明 本文並不會列出在 React 工作面試中會出現的常規問題和問題的完整回答。這篇文章的重點是展示我提出的問題,我在答案中尋找的內容以及為什麼沒有不好的答案。如果你想要一份“最佳面試問題2018”的集合,請檢視 github.com/sudheerj/re…

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

如果你曾經用谷歌搜尋“React 面試問題”(或任何其他“[技術]面試問題”),你可能已經看過無數“十大 React 面試問題”,這些問題要麼已經過時,要麼和“state 和 props 之間有什麼不同”或“什麼是虛擬 dom” 這些問題重複。

知道這些問題的答案不應該是面試官決定是否錄用你的依據。這些知識點都是候選人在日常工作中需要了解,理解和實現的。如果你被問到這樣的問題,要麼是面試你的人沒有技術背景(HR 或“獵頭”),要麼他們認為這是一種形式。

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

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

讓我們相互瞭解對方

在許多情況下,面試將通過 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前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章