前言
前不久我被蘑菇街优化了,然后不得不去找工作恰饭呀。
我目前面了五家公司:滴滴、蚂蚁、拼多多、酷家乐、字节跳动,拼多多和酷家乐基本已拿到 offer,蚂蚁二面完了,滴滴和字节即将三面,我先把我已经面过的面经先总结出来,其他的不管过没过,这周内我都会总结出来,希望能给到正在找工作同学的帮助。
在文章里我不仅会列出面试题,还会给到一些答题建议,个人能力有限,也不能保证我回答都正确,如果有错误,希望能纠正我。
酷家乐
酷家乐是我最早面的一家公司,还没被裁的那周二刚好面完,结果周五就被裁了,可能这就是冥冥之中吧。
面试的部门是工具组,是酷家乐最核心的部门,四面面试官跟我说我面的组是工具团队中的最核心组,会涉及到一些图像相关的技术,比如 Tree.js、WebGL 等,所以这个组其实也挺好的,感觉能学到不少技术。
一面(电话面)
你在项目如何优化的
我在简历里面写到了性能优化相关的,所以这个问题。
你做的项目有什么值得说的
基本上就是考察项目的亮点,可以说一些项目难点是如何解决的,或者介绍一些项目中用到的牛逼的技术。
Ts 有什么优势
讲道理所有现在在网上能查到的优势都是得益于静态语言的优势。
type 和 interface 的区别
这是一个高频题,如果考察 TS,这应该是最容易考察的,网上也都能查到相关的资料,但是很可能忽略一个点:type 只是一个类型别名,并不会产生类型。所以其实 type 和 interface 其实不是同一个概念,其实他们俩不应该用来比较的,只是有时候用起来看着类似。
React 事件机制
我觉得需要答的点:
参考资料:一文吃透 React 事件机制原理[1]
React 为什么要用合成事件
事件机制:注册和分发的过程。这里面至少要说出事件注册都是在元素的最顶层
document
节点上。
聊聊 React 的 diff
聊 diff 建议先看看我之前写过的一篇关于虚拟 DOM 的文章:从 React 历史的长河里聊虚拟 DOM 及其价值,有助于理解 diff 的意义。
diff 的细节可以看我之前写的:详解 React 16 的 Diff 策略
React 优化
可以看之前我写的 React 函数式组件性能优化指南,对于类组件也有对应的 API。
怎么理解闭包
基础中的基础,虽然社招考得不多,但是如果连闭包都理解不了,应该会减分不少。闭包由于在规范里没有定义,所以很多人下的定义不一样,理解的角度也不同,但是自己要有一套正确的理解方式,如果按照我的理解 JavaScript 里面所有的函数都是闭包,因为有全局环境,所有的函数都可以访问全局变量。
节流怎么实现的
防抖和节流的代码还是需要会手写的,这也是一个闭包的例子,
原型,class B 继承 class A 翻译成 es5 应该是什么样子
说实话,我觉得这道题其实蛮有水平的,即考察了如何写出一个好的继承方式,也对 new 过程进行了考察,还对考察了对 Class 的理解。
注意的点:
class
是有重载功能的,怎么在子类的构造函数里面调用super
二面(现场面)
react 的基本原理
UI = f(state) ,虚拟 DOM、diff 策略、setState
react 如何做性能优化
这个题也是高频,见一面回答
redux 的重点概念
store、reduce、action、actionCreater、dispatch
聊一聊 React 的生命周期
尽量把 React 15 和 16 的进行对比,然后 16 为什么要准备废除那几个生命周期,以及新增的生命周期可以进行替代。
这个图好好的理解一下
react 生命周期 聊一聊 hooks 怎么处理生命周期
讲道理函数式组件是没有生命周期的,但是如何去模拟类组件的生命周期的作用,都是在
useEffect
里面进行操作的,因为生命周期里面所做的基本都是副作用,放到useEffect
里是最合适的,专门用来处理副作用。笔试题一
const a = { b :3} function foo(obj) { obj.b = 5 return obj } const aa = foo(a) console.log(a.b) console.log(aa.b)
笔试题二:
function Ofo() {} function Bick() { this.name = 'mybick' } var myBick = new Ofo() Ofo.prototype = new Bick() var youbick = new Bick() console.log(myBick.name) console.log(youbick.name)
笔试题三:考察盒子模型和
box-sizing
属性,判断元素的尺寸和颜色。实现一个 fill 函数,不能用循环。
考察递归
用 ES5 实现私有变量
考察闭包的使用
三面(现场面)
简历里面的性能优化是如何做的
减少请求频率、图片压缩、
React.memo
、React.useMemo
class 组件里面如何做性能优化(因为前面我说了用 React.memo 做了性能优化)
shouldComponentUpdate(简称 SCU)。SCU 跟 immutable 强相关,一定要好好理解 react 的 immutable,否则很可能理解不了为什么不能直接去修改 state,然后再去 setState,以及 redux 的 reducer 要返回一个新的对象。
实现一个 Typescript 里的 Pick
type Pick<T, K extends keyof T> = { [P in K]: T[P] }
手写 Promise.all
手写:并发只能 10 个
算法题,怎么判断单链表相交。
很多种方法,我当时说的是最后一个节点如果相同,那么就代表相交。
算法题,怎么找到第一个相交的节点。
同时遍历两个链表到尾部,同时记录两个链表的长度。若两个链表最后的一个节点相同,则两个链表相交。有两个链表的长度后,我们就可以知道哪个链表长,设较长的链表长度为 len1,短的链表长度为 len2。则先让较长的链表向后移动(len1-len2)个长度。然后开始从当前位置同时遍历两个链表,当遍历到的链表的节点相同时,则这个节点就是第一个相交的节点。
这是我刚想到的一种方式,不过当时面试的时候我记得好像更简单,但是想不起来了。
四面(现场面)
你觉得你在公司人缘怎么样
你觉得你为你们小组做了什么贡献
为什么要离职
除了我们公司还投了其他公司吗
薪资和层级有什么要求
如何垂直水平居中
你看过开源库的源码吗?
那你聊聊 React 的源码,把你记得起的讲一讲
我看过 React 的一部分源码的,所以关于 React 源码更新部分的东西,应该基本都能说个大概。
FiberNode 有哪些属性
stadeNode 有什么用?
还有一些技术问题想不起来了
小结
酷家乐面试体验还是不错的,我是一面电话面,面完觉得 OK 之后就叫到公司去现场面试,6 点半下班了就骑车去了酷家乐,七点开始面试,一口气面完了三面,饭都没来得及吃,不过面试官很好给我倒了水。
感觉面试官对我的项目似乎不太敢兴趣,很少问项目的东西,可能由于他们是工具组,连我简历里面组件库相关的也没面,考察基础的比较多,基础考察得比较全面。
但是由于考虑到我之前做的项目复杂性不够,以及工作年限的问题,给到的评级不高,导致薪资也不是特别高,但是已经是这个评级的顶峰了,要是没有更好的 offer 酷家乐还是非常值得去的,特别是工具组。
拼多多
一面
react 16 生命周期有什么改变
componentWillMount
,componentWillReceiveProps
,componentWillUpdate
准备废除,新增了static getDerivedStateFromProps
和getSnapshotBeforeUpdate
我还详细的介绍了为什么要用
getDerivedStateFromProps
来代替即将废除的三个生命周期,主要是 16 版本 render 之前的生命周期可能会被多次执行,具体的可看我的这篇文章:Deep In React 之浅谈 React Fiber 架构(一)详细的介绍一下
getDerivedStateFromProps
你在项目中如何做性能优化的
flex: 0 1 auto;
是什么意思?flex 这个属性常考题,好好把阮老师的那篇 flex 语法篇[2]看完 flex 的面试题基本没问题。
less 的 & 代表什么?
算法题:求最大公共前缀,如
['aaafsd', 'aawwewer', 'aaddfff'] => 'aa'
不能调试,全靠编程素养,只能面试官才能运行。
interface 和 type 的区别
又考了,上面有回答
有用状态管理吗?
我常用的是 redux 和 dva,然后再聊了聊区别已经 redux 的理念
有用 ssr 吗?
没用过
node 熟悉吗?
写得少
二面
class 组件与函数式组件的区别
生命周期、设计理念,感觉这道题比较开发,可以看看 dan 的这篇:函数式组件与类组件有何不同?[3]
css 优先级
important > 内联 > ID 选择器 > 类选择器 > 标签选择器
避免 css 全局污染。
我常用的 css modules
css modules 的原理
生成唯一的类名
有一个 a 标签,如何动态的决定他的样式。
我说了先写几个 css,然后外部传一个前缀的方式。面试官问了都要这样吗?我说可以通过 context 的方式,就不需要每个组件都传了。
import 和 require 导入的区别
高频题,考察 ES6 模块和 CommonJS 模块 的区别。关键点:1. 前者是值的引用,后者是值的拷贝。2.前者编译时输出接口,后者运行时加载。
推荐文章:前端模块化:CommonJS,AMD,CMD,ES6[4]
require 有什么性能问题
好好想想上一个题的区别就能想到了
组件库如何做按需加载
我常用的是
babel-plugin-import
webpack 如何实现动态加载
讲道理 webpack 动态加载就两种方式:
import()
和require.ensure
,不过他们实现原理是相同的。我觉得这道题的重点在于动态的创建 script 标签,以及通过
jsonp
去请求 chunk,推荐的文章是:webpack 是如何实现动态导入的[5]react 里有动态加载的 api 吗?
React.lazy
React.lazy 的原理是啥?
webpack 能动态加载 require 引入的模块吗?
应该是不能的,前面说了,webpack 支持动态导入基本上只能用
import()
和require.ensure
。require 引入的模块 webpack 能做 Tree Shaking 吗?
不能,Tree Shaking 需要静态分析,只有 ES6 的模块才支持。
设计一个 input 组件需要哪些属性。我说了 value 、defaultValue、onChange
value 的类型是什么?
onChange 怎么规定 value 的类型
interface 和 type 的区别
写一个 promise 重试函数,可以设置时间间隔和次数。
function foo(fn, interval, times) {}
常规题,网上有参考答案的。
三面
组件平台有哪些功能?
详细的跟我讨论组件平台的设计,因为他们也想做一个组件平台。
实现一个 redux
实现
createStore
的功能,关键点发布订阅的功能,以及取消订阅的功能。用 ts 实现一个 redux
简单的加上类型,我写的类型没有 redux 源码那么复杂,当时写得比较简单。
小节
一面的时候其实我自己感觉答得不是特别好,连 less 的语法都忘记了,当时面下来感觉要凉了,平时写 样式的时间确实太少了。
很幸运的时候还是给我过了,二面面试官我觉得面得很专业,基本都是从浅入深的考察知识的深度,我感觉答得还可以,因为我是属于那种会的就尽量深一点,暂时不用的就很少花时间,所以我目前知识的广度很有欠缺,对于 node、ssr、移动端、小程序这些方面我的能力都很薄弱,但是面试的时候如果你不熟悉,直接说不熟悉就行,他就不会面了。
我准备面试之前对我自己的要求就是,我会的尽量不会很快就被问倒,所以我重点复习了我擅长的知识。
面下来感觉拼多多也没有想象中那么难,虽然拼多多薪资算行业内高的,不过拼多多在上海,我在杭州,另外就是强制上 6 天班,我比较忌惮这点。考虑到我和女朋友本来就是异地,要是单休,而且节假日也会比正常的少,见面的机会就更少了。
反正选 offer 这种事还是尽量综合考虑吧,团队、薪资、个人生活都应该考虑进去。
最后
我是黑叔,一个爱思考的前端 er,期待你的关注。
亲,点这涨工资