[译] 以面试官的角度来看 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前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏