sammffl

React工作面试——招聘面试官的观点

原文链接: medium.com

Photo by rawpixel via unsplash

重要 本文不是一篇面试问题列表也不会去完整的解答它们。 文章的重点是去展示我提出的问题,我在回答中找什么以及为什么没有不好的回答。 如果你想得到一份“2018年最好的react面试问题”清单,查看 https://github.com/sudheerj/reactjs-interview-questions

我工作的一部分是执行所谓的“技术面试”,在此期间我会评估那些申请React前端开发职位的潜在候选人。

如果你曾用谷歌搜索过“react面试问题”(或者其他“[技术]面试题”) 你可能已经看过无数的“前十名React面试问题”名,这些问题要么过时要么重复相同的问题,例如 “state和props有什么区别”或“什么事虚拟dom”

知道这些问题的答案不应该不应该是面试官决定聘用的基础。 这是候选人在工作中需要去知道、理解和实现的东西。如果你作为候选人被问到这些问题,要么面试官没有技术背景(人事或者猎头)要么他们认为这是例行公事的提问。

面试过程不应该浪费时间。他应该让你了解到候选人过去的经验、过去的学识以及发展机会。候选人应该了解你们的组织和项目(如果可能的话)并获得有关他的表现和你的期望的反馈。在求职面试中应该没有错误的问题(除非问题属于严格意义上的技术问题)—— 回答应该给你提供对一个人的思考过程的洞察力。

本文是从面试人员的角度来写的!

让我们互相了解

在许多情况下,访谈将通过Skype或其他语音(或语音+视频)通信平台进行。 了解潜在的雇佣是一个让他们开放的好方法。

你能告诉我一些你以前的工作,你是如何适应团队的? 你承担了什么责任?

知道这个人在之前的工作中做了什么(如果他可以分享)是一个很好的开始。这让你对他之前的工作经验有了个基本的概念:软技能(“我是个独立开发者……”,“我和我的同事……”,“我管理六个人的团队……”)和硬实力(“……我们创建了一个被100万人使用的应用”,“……我优化了应用的渲染时间”,“创建了一系列的自动化测试”)。

React给你的主要卖点是什么? 你为什么选择使用React?

我不希望你提到JSX、虚拟DOM等等——这些我们都可以通过阅读react主页的features简介了解到。那么_你_为什么使用React?

是不是因为“易于掌握,难以精通”的API(当你将其与其他解决方案进行比较时,它会非常小)?很好 ——比如说,这意味着你愿意学习新东西,并随时学习它们。

是因为“就业机会”吗? 好——你是一个能适应市场的人,并且在下一个大框架到来的5年内不会有任何问题。 我们已经有足够的jQuery开发人员了。

想想这有点像“电梯时刻”情景(你和老板在电梯里,需要说服他在他们20楼出门前使用新技术)。 我不知道你知道React提供什么可以使客户、你还有开发人员受益。

让我们讲跟多技术方面的东西

就像我在一篇公开的文章中提到的那样——我不会问你关于虚拟DOM的问题,我们都知道这个,然而我会问你关于……

什么是JSX以及我们如何在JavaScript代码中编写它——浏览器是怎么识别的?

你知道JSX只是由Facebook推广的符号,要感谢Babel / TSC这样的工具——允许我们用一种更便于识别的方式来写React.createElement调用。

为什么我要问这个问题?我想知道你是否理解JSX的技术方面以及它的所有限制:为什么我们需要在文件的顶部添加import React from 'react',即便在我们的代码里不使用React; 为什么组建不能直接返回多个元素。

奖励问题:为什么JSX中组件名称是以首字母大写开始的? 回答这个只需要提到React识别大写为组建而不是HTML元素就好。

加分:该规则有例外。 例如。 将组件分配给this.component,然后执行<this.component />React也能识别。

您可以在React中声明哪两种主要组件类型,以及何时使用其中一种组件。

有些人会认为这是关于表示和容器组件,但这更多是关于React.Component和函数组件。

一个合适的回答应该提到生命周期函数和组建状态。

既然我们提到了生命周期——你可以带我走完组建状态的完整生命周期吗?以什么顺序调用哪些函数?你会在哪里通过接口请求数据?为什么?

好吧,这个问题有点长,我们把它分成两个小问题。你现在在想“但是你说你不会问生命周期!”。 我没有,我不关心生命周期。 我关心最近几个月生命周期中发生的变化。

如果答案包含componentWillMount,你可以假设此人一直在使用旧版本的React,或者完成了一些过时的教程。这两种情况都会引起一些担忧。 getDerivedStateFromProps是你要找的东西。

加分:提到了在服务端渲染时的差异

关于数据获取的问题也是如此——componentDidMount是你想要听到的那个答案。

奖励问题:为什么是 componentDidMount 而不是 constructor 你想听到的两个原因是:“渲染发生之前,数据不会存在”——尽管不是主要的原因,也向你展示了他了解组建的处理方式; “使用React Fiber中的新异步渲染……” ——有些人是做了功课的。

我们提到过从接口获取数据——如何在重新安装组件时确保不重新获取数据?

我们假设“缓存失效”不存在。这严格意义上不是react相关的问题,但如果答案仅限于React,那也很好——也许他们已经使用GraphQL处理那些对你来说繁重的工作?

我问这个问题,看看候选人是否理解在应用程序中不耦合UI和其他层的想法。 可以提到React结构外部的API。

你如何解释“状态提升”的概念?

好吧,我确实问了些典型的react问题,这个问题很关键,它可以让你给候选人一些喘息的空间。

回答范围从“它允许你在兄弟组件中传递数据”到更好的“它使你拥有更具重用性的纯展示组件”。Redux在这里可能会被提到, 但也可能是件坏事,因为这意味着候选人可能只是跟随这社区的意见而没有理解为什么他们需要Redux。

奖励问题:你将如何跨越多个深度级别传递数据,而不是将其从组件传递给组件? 自从React16.3以来,Context已经成为主流——Context曾经存在过,但文档是缺失的(也可能是故意的)。能够解释context如何工作(同时展示function-as-child模式的知识)是加分的。

如果在这里提到了Redux / MobX它也是好的。

React生态系统

开发React应用程序是该过程的一部分 ——还有更多内容:调试,测试和记录。

你是怎么在React代码中调试一个问题的;你用的是什么工具?你是怎么调查组件不重新渲染的原因?

每个人都应该熟悉基础的工具像linter (eslint, jslint) 和调试工具(React Developer Tools)。

使用RDT通过检查组件状态/属性是否正确设置来调试问题是一个很好的答案,提到使用开发者工具设置断点也是一个很好的答案。

你用什么测试工具编写单元/ E2E测试? 什么是快照测试,它有什么好处?

在大多数情况下,测试是“必要之恶”,但这些是我们需要的东西。这有很多好的回答: karma, mocha, jasmin, jest, cypres, selenium, enzyme, react-test-library等等。最糟糕的是候选人回答 “在上家公司我们不做单元测试,只有人工测试”。

快照测试部分还取决于您在项目中使用的内容; 如果你觉得它没有益处,不要问它。 但是如果你这样做,可以对UI层进行快速简便的回归测试(生成的HTML + CSS)。

小小的代码挑战

在可能的情况下,我也会做一些小代码挑战,这些挑战应该花费不到一两分钟来解决/解释,例如:


/** * What is wrong with this example, and how would you go  
* about fixing or improving the component? 
*/ 
class App extends React.Component {  
  constructor(props) {
    super(props);
    this.state = {
      name: this.props.name || 'Anonymous'
    }
  }    
  render() {
    return (
      <p>Hello {this.state.name}</p>
    );  
  }
}

有多种方法可以解决它:删除状态并使用属性,实现getDerivedStateFromProps或(最好)更改为函数组件。

/**
 * Can you explain the differences between all those ways
 * of passing function to a component?
 *
 * What happens when you click each of the buttons?
 */
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事件循环。

/**
 * What's the issue with this component. Why?
 * How would you go about fixing it?
 */
class App extends React.Component {
state = { search: '' }
handleChange = event => {
/**
     * This is a simple implementation of a "debounce" function,
     * which will queue an expression to be called in 250ms and
     * cancel any pending queued expressions. This way we can 
     * delay the call 250ms after the user has stoped typing.
     */
    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毫秒更新状态,然后呈现字符串“搜索:……”。

这里的问题是event是React中的SyntheticEvent,如果与它的交互被延迟(例如通过setTimeout),它将被清除,.target.value引用将不再有效。

加分:候选人能够解释为什么会这样。

我们完成了技术问题。

这应该足以让你对候选人的技术技能有所了解。 你还有一些时间可以留给更多开放式问题。

在你过去的项目中遇到的最大的问题是什么;你最大的成就是什么?

这就回到了最初的问题—— 回答真的是因人而异,因职位而异了。一位初级开发人员会说他最大的问题是在一个复杂的过程中被抛出的问题,但他们能够征服它。寻找更高级职位的人将解释他们如何优化应用程序性能,并且可以带领团队的人通过进行结对编程来解释他们如何提高速度。

如果你有无限的时间预算并且可以修复/改进/改变你上一个项目中的一件事,它会是什么?为什么?

另一个开放式问题,答案取决于你在候选人中寻找什么。 他们会尝试用MobX取代Redux吗? 改进测试设置? 写出更好的文档?

反转表格和反馈

现在是角色互换的时候了。 你可能对候选人的技能和成长潜力有一个坚实的想法。 让他问问题——这不仅可以让他更多地了解公司和产品,他们提出的问题可能会给你一些关于他们想要成长的方向的指示。

Carl Vitullo写了一些很好的文章,主题是问你的潜在雇主有哪些问题,我推荐你去看一下——准备好回答他们,或者说由于NDA要求你不能按照步骤进行: