1.面试对象以及使用的技术栈
这次面试的是一个广州某知名外包公司在汇丰驻场开发的一个项目组,技术栈React,本着试水的心态去面试,查漏补缺。
2.面试过程
-
自我介绍(英文+中文):
由于是汇丰项目不得不使用英文自我介绍,简单介绍完之后,就开始用中文水自己熟悉React那些东西
-
技术面:
面试的是一位汇丰项目的大姐姐,整个过程轻松愉悦,当作技术交流就好了 - setState是异步还是同步的为什么? 假如触发一个setState,可以立马触发console.log输出改变后的值吗? - A: 看起来即是异步也是同步,一般执行完setState以后,再console.log,打印的还是修改前的值,若需要修改后立马查看修改的值,需要在setState的参数中加入一个回调函数(至于这里为什么是异步我没答上来)。调用多个this.setState的时候是把state进行覆盖。当把setState放到 setTimeout 的时候,因为setTimeout是一个队列任务,并没有先去执行,具体可查阅Eventloop的有关文章。先执行主进程代码块,等主进程执行完了, isBatchingUpdates 又变为了 false ,导致最后去执行队列里的 setState 时候走的是和原生事件一样的分支,所以表现就会和原生事件一样,可以同步拿到最新的state的值。 - React中每个生命周期分别用过来做什么 - A: 1. CompentWillMount,组件初始化,react17版本将弃 2. ComponentDidMonut,组件挂载时用来请求数据,设置state的值,绑定事件监听,绑定定时器 3. ComponentWillUnmonut,组件卸载时用初始化组件,或者取消事件监听,取消定时器 4. getDefaultProps,初始化props 5. getInitState,初始化state 6. shouldComponentUpdate,通过对比上一个props和当前props进行对比,进行逻辑判断是否需要重新渲染,false则不重新渲染,否则重新渲染 7. render ,解析this.props以及this.state,将Jsx型的vdom(虚拟DOM)渲染成对象类型的vdom - diff算法的实现? - A: 1. (tree diff)对树分层比较,两棵树 只对同一层次节点 进行比较。如果该节点不存在时,则该节点及其子节点会被完全删除,不会再进一步比较。只需遍历一次,就能完成整棵DOM树的比较。 2. (component diff)react对不同组件的比较,如果是同一类型两个组件会按层级比较判断虚拟dom的位置,如果虚拟dom并没有发生变化,用户可以通过shouldCompontUpdate来判断是否判断计算。不同类型的组件将一个将要发生变化的组件标记为dirty component,从而替换整个组件的所有结点。 3. (element diff) 对同一级的节点进行删除,移动,插入,但针对节点有key的情况进行移动,则不需要对比原位置进行删除再重新创建 (ps:具体diff深入还得百度看,此处只摘抄了重点)
- 现在公司项目用的版本是react多少?有用过React Hooks吗?
- A:
1. react 16.8
2. 有用过,大概就是使用了useState以及useEffect,useContext了解过。
- 但当前的公司项目并没有这个需求使用到useContext,useContext创建后,子孙后代的组件都能使用里面的属性。
- useState的用法就是相当于传统react中state值得初始化,以及一个触发setState得函数的一个结合,一般在hooks中开始定义,例如:const [sample,setSample] = useState('test'),其中的意义相当于给sample一个初始值名为test,后续需要通过setSample()该函数去覆盖sample的值。
- useEffect的用法相当于传统react中的componetDidMount,基本上钩子中的请求都在useEffect中发送,其中useEffect中接受两个参数,一个需要执行的函数,以及一个数组,数组的作用相当于一个监听里面值得变化,如果变化则useEffect将重新执行内部的第一个参数便是那个执行函数,有点类似mobx中autorun。其中如果考虑组件卸载后,只需要在useEffect中的执行函数内重新return一个函数。
- 为什么react中的组件需要大写?
- A:
因为在react中书写的jsx需要通过babel进行解析转化为React的生成节点的方法=>React.createElement(当前结点,props,子节点),但createElement的方法会判断是否大写区分是html的标签,如果是小写,createElement中的第一个参数为字符串,大写则为一个变量。
- class中的constructor中的super()不写是否会报错?如果不写constructor是否也会报错?
- A:
1. ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错
2. 一个类中必须要有constructor构造函数,但如果没有显示定义,一个默认的构造函数则会被默认添加,所以不会报错。
- 如何使用flex实现一个居中?
display:flex
justify-content:center
align-items: center
- 熟悉es6吗?如何定义一个5个长度的数组,然后对其补空为长度10的数组?
A: (当初没答上,但是当初用原生js比较繁琐的方法解决)es6方法实现思路,首先定义一个长度为十的类数组,再通过Array.from的方法,把类数组转化为数组。
var array = {0:'1',1:'2',2:'3',length:10}
Array.from(array)//["1", "2", "3", undefined, undefined, undefined, undefined, undefined, undefined, undefined]
3.面试总结
最后向面试官寻求一些建议,虽说是外包岗位,但由于面试我的是汇丰这边,所以或多或少很问框架最深层的原理,setState更新state看似一个很简单的过程,其中包含的深入原理特别复杂,面试官也建议我继续关注react框架的底层的原理以及其源码,不过这次面试算是第一次遇到有点水准的外包岗面试,很值得记录一下。