背景:本科毕业于宇宙工业大学计算机专业,2年前端开发经验,分别就职于广州、深圳的两家小厂各一年。今年 7 月底裸辞回家准备 2 个月,中间大大小小面了十几二十家公司,最终收获了不错的 offer。
前言
7 月底因为我在深圳租的房子刚好到期了,再加上中间有一些工作上以及非工作上不顺心的事情,所以打算直接裸辞回家准备。
同时,在我的职业规划中,我是比较希望能够在职业生涯前期能够进入大厂(不管是不是一线)工作,大厂提供的资源以及大厂本身的业务远远不是小厂能够媲美的,能够加入大厂对我以后的职业规划会有非常多的帮助。同时,如果我今年选择加入一家小厂,同时我仍保留 3 年内加入大厂的想法的话,那我明年就又要再次跳槽,算上今年相当于职业生涯前三年一年一跳,这在 hr 面的时候是一个非常大的减分项。
同时,我再次提醒各位:不到最后时刻,千万不要选择裸辞。因为一旦你选择了裸辞,那么你将失去你的经济来源,短时间内还好,但是一旦经历比较长的面试流程的时候(比如腾讯动辄一个多月的面试流程),整个人的精神压力是非常大的,同时裸辞如果理由不充分的话,在 hr 面的时候也会是一个减分项。
截止到目前为止,我的所有流程大概如下:
- 大厂:
- 深圳shopee(finance):offer;
- 金山办公软件(wps+):offer;
- 猎豹移动:offer;
- 腾讯教育(IM Web):三面挂,但不知道为啥简历还在流程中;
- 字节跳动(深圳飞书):二面挂;
- 富途证券(架构组):三面,被我推了;
- 深圳百度(安全部):hr 面,被我推了;
- 中信信用卡研发中心:三面,被放了飞机,刚好不想去了;
- cvte(ES-Web):一面技术面过了,hr面挂了。
- 小厂:
- 深圳兔展:offer;
- 明源云:offer;
- 铱云科技:offer。
大纲
整篇文章不会列出以上所有我面过的公司的面试题出来,因为面试过程大部分问的问题都紧贴简历上的项目经历,所以很多问的问题并没有普遍参考价值,我会将我在面试中经常遇到的一些问题罗列出来,并给出我心目中认为是比较好的答案供大家参考。
当然,我相信还是有很多人想去看我的完整面试题,我已经统统整理出来,存放在 i-want-offer / FE-Interview-questions[1] 这个仓库里面,里面包含了我在整个准备过程中收集到的一些前端面试知识点,以及我自己经历过的面试题、我身边人经历的面试题或者是我在掘金上看到的有参考价值的面试题,希望能够帮助到各位。
前端八股文
js 基础
- 原型链
- 继承的实现
- 数据类型
- var、const、let 对比
- es next 最新规范
- new 的过程
- this 指向问题
- bind 实现方式
- 闭包
- 事件循环 【超高频】
- 类型判断
- 手写 Promise
其中,关于 js 语法的资料这里不详细赘述,可以去仓库里面找对应的资料。
关于 事件循环(Event Loop) ,大小厂的问法是不同的。
小厂通常会直接让你口述事件循环的机制,这时候比较标准的回答是说出事件循环分为浏览器的事件循环和 node 事件循环,并且分别说出浏览器中的事件循环机制以及 node 事件循环机制。其中加分点在于可以答出 v8 对于 async / await 的优化以及 node 11 版本前后 node 事件循环机制的区别(其实大多数面试官可能自己都不知道,面试题都是网上找的,你说的有道理能把他唬住基本就没问题了)。具体的回答可以参考 事件循环机制满分答案[2] 。
大厂又是另外一种问法,他通常不会直接让你口述事件循环的原理,会给一道面试题给你做,里面包含了宏任务、微任务的各种坑,这种其实更简单,做多了自然就会了。
另外关于 手写 Promise ,目前我没有被小厂问过这个,但是大厂有被问过几次,分别是让我手写 Promise.finally 以及 Promise.all ,实现思路都非常简单,可以参考一下我用 js 实现的 Promise A+[3] 。
前后端通信
作为一个前端工程师,知道那几个基本的知识点足够让你应付初中级别的面试题,但是如果作为一个程序员的角度出发,还是需要丰富自己在这方面的知识。这里不展开讨论,只说面试题。
- 输入 URL 到页面展示 【超高频】
- 跨域 【超高频】
- HTTP 各版本 (通常是由缓存带出来的问题)【高频】
- HTTPS 原理 【高频】
- TCP 三次握手、四次挥手
- TCP 和 UDP 区别
- HTTP 常见状态码
- 鉴权
输入 URL 到页面展示 虽然是一个老生常谈的问题,但是我认为这个问题基本涵盖了整个前端的所有基础知识点,可以回答得非常丰富。建议大家看我的这篇总结:浏览器输入 URL 的全过程[4] ,里面分为了网络篇、解析算法篇、渲染过程篇三个步骤,比较好的讲述了整个过程到底经历了什么。
由这个问题可以带出 缓存、DNS 解析、TCP 连接、HTTP 请求、重排重绘 等等非常多的子问题,如果你掌控的好,甚至可以控制整个面试过程,非常有利于给面试官留下比较好的印象。
跨域 也是另一个非常高频的问题,通常会问你跨域的原因以及解决方案,网上很多答案,这里不做解释。
HTTP 各版本的区别 通常并不会干巴巴的让你回答,在我遇到的所有情况下,通常都是在我答到缓存的时候,面试官会让我停下来解释缓存,这时候回答到一部分 HTTP 各版本中的区别;另外,一部分会在我回答性能优化的时候,答到 HTTP2 的时候会回答。
HTTPS 的问题也是比较简单,问的也通常比较直接,一般会让你直接说原理,然后再让你总结一遍握手过程。偶尔会让你对比一下 HTTP 之间的优缺点。
至于其他问题,可以到仓库里面找答案,也可以网上自己查,都是非常基础的问题。
安全
原本这个问题应该罗列在前后端通信中的,但是这个问题实在是太高频了,几乎每一次面试都有问到,所以我单独罗列出来。
具体的回答可以参考一下我整理的这篇文章:前端安全[5] 。
通常在回答安全问题的时候,需要回答以下几点:
- 有哪些安全问题?
- 解决的办法。
XSS 和 CSRF 是一定要回答上的,剩下的你知道多少答多少,但是别瞎说。一旦你乱说,很容易就会让人觉得你是在背书,没有自己的理解(虽然确实是在背书)。
工程化
这方面通常会从一个项目上入手来说,一般会问一下问题:
- 页面性能优化 【超高频】
- webpack 性能优化
页面性能优化 可以聊的东西其实挺多的,比如通常会从网络、加载这两个角度出发来解决性能问题。网络角度上有可以聊到前面提到的缓存、CDN、HTTP2以及图片格式上面的优化。从加载上来说的话,又可以聊到 webpack 的打包拆包、tree-shaking、懒加载和异步加载、多线程。除了这两个角度以外,还可以从用户体验的角度上来进行优化,比如说骨架屏、动画、虚拟滚动等。
除了这种常规的角度来说,现在我们开发一个 Web 应用通常都会使用框架,每一款框架一般都会有一些配套的性能优化的手段,比如 React 里面的 shouldComponentUpdate、PureComponent、memo 等优化 diff 算法的手段也需要回答。框架的优化问题通常会在你答完性能优化的问题之后跟着问你。
具体可以看下这两篇:
- 性能优化[6]
- React 性能优化[7]
至于 webpack,以我目前的面试经历,问的相对比较少,可以有选择的去关心关注。
框架
框架对于目前现代的 Web 应用开发来说,基本就是必备技能。面试的时候,面试官通常会根据你自己简历上写的技术栈来问,对于大小厂而言,问的方式可能也略有不同。对于小厂来说,如果你恰好技术栈和他们相一致,那么他们问的基本和大厂差不多;如果不相符,那就完全看面试官是否了解你当前的技术栈,了解的话大概会问一些,否则基本不问。对于大厂来说,那基本上是不可能不问的。
由于我的技术栈是 React + Angular,所以我的所有面试经历基本都没有被问到过 Vue 相关的问题(用 Vue 的同学不好意思了)。目前我被问到过的问题主要有:
- Angular 变更检查的原理以及如何进行优化
- React 的 diff 算法工作过程
- Angular、React 的事件机制
- React 中的 setState 是同步还是异步
- React、Angular 的区别(如果你用过 Vue,问的问题会换成 Vue)
- React 中各种组件复用的优劣势(mixin、render props、hoc、hook)
- React 的 Fiber 架构
- 老版本的 React 的某些生命周期被废弃的理由
- React 性能优化
以上的问题都很大概率会被问到。
TypeScript
2020年,ts 基本是一个前端从业者必须掌握的一项技能,一旦你简历上写了有 ts 的开发经验,那么面试基本上都会问一两道有关 ts 的题目。
ts 的一些普通知识在这里不进行赘述,这里挑选一些我在面试中遇到的题目。
另外,对于大小厂而言,他们对 ts 的掌握程度要求是不一样的,对于小厂而言,他们希望来面试的人能够熟练使用 ts 进行业务开发,所以 ts 的概念的熟练程度对他们来说最重要。而对于大厂而言,他们可能更加希望来面试的人能利用 ts 开发一些 ts 的周边工具,所以比较少会直接问 ts 的一些概念,一般都会让你手写一个 ts 的工具函数。
目前我面过的所有小厂,基本都会问 ts 中 type 和 interface 的区别 ,也基本只问这一个问题。除此之外,偶尔还会问到 ts 中如何实现一个函数的重载 ,基本上也是从使用角度出发,考验一个面试人的 ts 的熟练程度。
大厂里面,有两题我是印象比较深刻的:
1.实现一个 ts 的工具函数 GetOnlyFnProps
- type GetOnlyFnKeys<T extends object> = {
- [Key in keyof T]: T[K] extends Function ? K : never
- }
- type GetOnlyFnProps<T extends object> = {
- [K in GetOnlyFnKeys<T>]: T[K]
- }
2.实现一个 ts 的工具函数 UnGenericPromise
- type UnGenericPromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never
项目经历
项目经历千人千面,我的项目经历对于大多数人来说都不太有参考价值。
但是整个面试过程,对于整个项目的讲述其实是可以抽取出来,组合成一套公式来叙述:
- 项目的背景是什么;
- 当前项目的目的是什么;
- 在开发过程中,你的角色是什么;
- 在开发过程中有遇到过什么样的难题;
- 遇到这些问题,你都是如何进行解决的;
- 项目完成之后,取得了哪些成果;
这套公式基本上可以完整地讲清楚你参与的项目的整个过程,也有利于面试官去发掘你项目中的闪光点,便于面试官在你的叙述中找到可以深挖去问你的问题。
同时,在你准备写上简历的项目中,你最好自己能够自己过一遍上面的流程,这样有利于你找到你可能还没有掌握的知识,进行查缺补漏。
算法
我相信大多数人对于大厂面试的恐惧感主要来自于对算法的恐惧,因为在网上流传出来的各种面试题都包含了很多在 leetcode 中难度为 mid 以上的算法题。我本身也是一样,尤其是在我面字节跳动的时候,整个面试过程我都非常紧张,觉得字节的算法题会很难,很可能做不出来。但做完之后,其实也还好,难度基本控制在 leetcode mid 以下的级别,甚至我面的好几家大厂过程中都没有涉及算法。但是,我觉得作为一个程序员,算法水平一定程度上代表着你程序设计的好坏,所以提高自己的算法水平对于开发出高水平 Web 应用是有非常好的帮助的。
我在准备算法的时候,最开始比较盲目的刷 leetcode 的题目,整个过程我觉得进步非常缓慢,很多题目刷了一次两次,第三次再看还是不知道该怎么做。后来我放弃了这种没有目的性的刷题,我开始在网上找一些前端算法中比较常见的题目,我发现了这篇文章:前端算法渣的救赎之路[8] ,里面概括了一些前端面试中常见的题目,还给出了一些算法题型的经典解法,在整个学习过程中,对我的算法提升非常大,同时我也整理出了自己的一些 算法经验[9] 。同时对于基础不是很扎实的人来说,我非常推荐极客大学 9.9 的算法基础训练营,我在看完整个训练营 4 节课后,对基础有了一定的巩固。
做算法的时候我自己有一个窍门:遇到一个问题,先尝试用最暴力的方法进行解决,然后分析出暴力方法会有什么样的问题,然后再去解决遇到的问题。这个方法对于大部分我遇到的算法问题来说,基本上都可以解决问题。
各大厂面试特点
因为今年的特殊原因,所以基本所有公司都会采用远程面试的方式来进行面试。
在我整个面试过程中,其实各大厂的面试风格也是略有不同的,下面我一一细说。
CVTE
据我了解,CVTE 是会有很多轮 hr 面,基本上可以说是每一轮技术面试之后都会有一轮 hr 面来评估你。我当时一面的技术面已经过了,但是一面 hr 面没过,hr 面问的问题也比较尖锐,不过技术面难度还好,基本按照我上面的模版一套组合拳下来也能答出个七七八八。
CVTE 的一面没有涉及到算法题,后续的面试我就不是很清楚了。
中信信用卡中心
一面是前端面的,二面是后端面的,所以只有一面问了前端的知识问题,二面就是单纯打电话聊天,主要是聊了一些开发流程上面的问题,过程非常快非常轻松,全程只有一题算法题,也出现在我上面整理的算法题库里面。
百度
百度的技术面总共有4轮,基础面(同级别员工)+基础面(级别应该比你要一点)+leader面(整个研发部门的技术负责人)+boss面(整个研发部门的总负责人)
百度一面是需要你当场完成一套笔试题,难度的话也一般,基本上面的知识点你都过一遍问题不大,也有一题算法题,是百度的原创题目,但是题型是一样的,问题也不大。前两面都是前端开发面的,没啥难度,涉及到的知识点不局限于前端吧,还包括网络以及开发模式等等问题。
leader面还挺有意思的,当时他们强烈要求我到现场去参与面试,leader 是一个很年轻的小伙,因为不是专职前端,所以问的问题涉及到了整个计算机的所有知识点:数据结构、算法(原创题,一个很简单的递归)、操作系统,以及问你除了 js 以外还掌握什么语言等等,整个过程非常轻松,也非常愉快,大家都有说有笑。
boss 面气氛就比较严肃了,也可能是因为那个会议室空调有点冷的原因。基本上整个面试都是在让我吹水,讲自己的项目经历,以及解决的办法,答题模版也基本可以按照上面的来说,最后也通过了。
富途证券
富途证券是我面试到目前为止,面试时间最长的公司,每一轮面试都基本恰好一个半小时,不知道是不是有硬性规定,所以在面试的时候要预留好时间。
由于富途我只经历了两面,所以整个二面之后是怎样的流程我也不是特别清楚,但是互联网公司大都大同小异。
一面面试官是做前端的,问的非常细,不仅仅需要口述一些前端的基础知识,还会有一些笔试题让你完成,最后还有一道算法题,不过算法题没让我动手写,只是让我说出实现思路就让我过了。
二面面试官似乎是我面试的那个组的开发负责人,所以整个过程没有涉及到任何和前端知识相关的,一开始也是对项目进行吹水,后来之后给了 4 题笔试题,包含算法在内,难度的话大概是 leetcode mid 的水平,做过的话也就还好。
金山软件
金山软件的面试题我觉得比较有水平,全程没有涉及到算法,一面的时候是一些很基本的前端问题,背过的话通过非常轻松。二面的话是有两个面试官,其中一个是整个研发部门前端的leader,一开始可能会先问一些框架上面的知识,看下你对于框架的理解。然后会从实际开发角度出发,给出了几道场景题,让你去设计,非常考验一个人的开发熟练度,更容易能够通过这种方式找到熟练的前端开发。至于三面的话,就是全程在吹水了,还是按照上面项目的吹水公式吹水,整体也非常轻松。
腾讯
腾讯的面试风格和金山特别像,但是他问的基础题会更加复杂一些,不会单纯让你说一些只是要靠背的没啥用的 API,通常会通过一些手撕代码的形式来进行考验。然后每一面都会问你项目的一些情况,问的问题基本也差不多,所以准备一下基本都没啥问题。
但值得注意的一点是,问项目的时候,千万不要被面试官得到主导权,回答的时候一定要自信,千万不要被面试官牵着鼻子走。我在三面的时候,因为是第一次三面,没啥经验,非常紧张,被面试官牵着鼻子走,因为这次面的是 c 端的部门,面试官可能没有理解 c 端和 b 端之间的差异,用 c 端的思维去审视我 b 端的项目,导致整个面试过程我的表现都非常差。所以在面试时,一旦你发现面试官问的问题不太对劲的时候,一定要及时说出来。
字节跳动
字节跳动的问题问的非常细,在我参与的两轮面试中,都是在问一些非常基础的知识,面试的过程也不会很长,大概 45 分钟左右。
一面的时候再做了一番自我介绍之后,给了 5 道笔试题,做完之后再聊一聊别的就过了。
二面的时候简单介绍了一下自己做过的项目,然后主要是围绕着你做的项目中用到的技术进行讨论。他给了我一道场景题,然后让我按照场景中的内容进行实现,最后给了一道应该是原创的算法题。
其实面字节之前我是非常紧张的,我个人对能通过字节的面试一点也不抱希望,但是面完之后,觉得很多时候大家都神话了字节的面试,难度也没有想象中的高。
不过有一说一,我觉得面试我的两位面试官态度都非常好,有一些我答不出来的问题,也会给我提示给我鼓励。虽然我最后二面没有过,但是二面面试官在教我做算法题的思路上给了我一定的帮助,也就是我上面算法总结最后一段话。
总结
其实面试也就那么一回事,被问的多了,自然就能够总结出一套自己的方法论。但是,对于广大程序员同胞来说,大家必须记住面试是面试,工作是工作,面试面的不好的人,工作能力未必比你差。归根到底,大家做了开发这一行,还是技术水平说话,谁的水平高,谁的声音就大,大家不要觉得加入了大厂之后就一辈子安稳,一定要不断提升自己的技术水平。
后记
在我准备面试的过程中,我通过阅读了很多掘金等网上的文章,收获了非常多以前不懂的知识,在这里非常感谢:
- LinDaiDai_霖呆呆[10] 大佬,他写的几篇文章,都让我获益匪浅;
- luciferzero[11] 大佬,他的 前端算法渣的救赎之路[12] 在算法上对我帮助非常大;
- 冴羽[13] 大佬,他的 冴羽的博客[14] 懂得都懂,是我入门之作;
非常感谢以上的所有作者无私的奉献。最后,希望大家都能找到满意的工作。
参考资料
[1]i-want-offer / FE-Interview-questions: https://github.com/i-want-offer/FE-Interview-questions
[2]事件循环机制满分答案: https://github.com/i-want-offer/FE-Interview-questions/blob/master/JS/事件循环.md
[3]Promise A+: https://github.com/LaamGinghong/Promise-A-Plus
[4]浏览器输入 URL 的全过程: https://github.com/i-want-offer/FE-Interview-questions/blob/master/浏览器渲染/浏览器输入URL的全过程.md
[5]前端安全: https://github.com/i-want-offer/FE-Interview-questions/blob/master/安全/前端安全.md
[6]性能优化: https://github.com/i-want-offer/FE-Interview-questions/blob/master/性能优化/性能优化.md
[7]React 性能优化: https://github.com/i-want-offer/FE-Interview-questions/blob/master/性能优化/React性能优化.md
[8]前端算法渣的救赎之路: https://juejin.im/post/6844904175562653710
[9]算法经验: https://github.com/i-want-offer/FE-Interview-questions/tree/master/算法
[10]LinDaiDai_霖呆呆: https://juejin.im/user/360295513463912
[11]luciferzero: https://juejin.im/user/888061128607662/posts
[12]前端算法渣的救赎之路: https://juejin.im/post/6844904175562653710
[13]冴羽: https://juejin.im/user/712139234359182
[14]冴羽的博客: https://github.com/mqyqingfeng/Blog