前端春招面经:字节网易美团三厂offer实战复盘

前端春招面经:字节网易美团三厂offer实战复盘 2019年春招那阵子我前前后后折腾了差不多两个月最后拿到了字节跳动、网易、美团三家的前端offer。这篇面经一直想写但总想着再沉淀一下、再复盘一下结果就拖到了现在。当时准备面试的时候我把网上能找到的2019春招前端面经几乎翻了个遍一边看一边整理自己的知识盲区说实话帮助很大。所以现在轮到自己了也想把这些东西如实记录下来给准备走前端这条路的朋友做个参照。这不是一篇只罗列面试题的流水账。我会把每一轮的考察逻辑、我当时怎么答的、事后复盘哪里没答好、以及三家公司风格上的差异都聊一遍。如果你正在准备前端面试或者打算在接下来几个月投简历这篇内容应该能帮你把准备重心放对。1. 春节前后的准备阶段在开始聊面试题之前先把准备阶段的事情说清楚。我的原则是面经是查漏补缺用的不是临时抱佛脚用的。所以春节前我花了大概三周把知识体系过了一遍春节后才开始集中刷题和投简历。1.1 核心知识板块怎么梳理我身边有不少朋友准备面试的时候容易慌今天看框架、明天看算法、后天又觉得CSS不太行结果哪块都没吃透。我的做法是先列一个知识地图把前端面试会涉及的板块全部列出来然后逐个击破。以我当时的划分主要分成了这几块JavaScript语言基础原型链、闭包、作用域、this指向、事件循环、ES6新特性浏览器和网络渲染原理、回流重绘、HTTP缓存、HTTPS握手、跨域方案CSS和布局盒模型、flex、grid、BFC、居中方案、响应式框架Vue的响应式原理、vdom和diff、生命周期React的fiber、hooks、setState机制工程化webpack打包流程、loader和plugin区别、代码分割、性能优化算法和数据结构数组/字符串操作、链表、二叉树、排序、动态规划入门项目复盘简历上每个项目都能讲清楚技术选型、难点、优化指标这个清单看着挺多但每一块其实都有对应的经典问题。我当时是给自己定了个目标每个板块至少要能脱稿讲出三个核心知识点并且能现场手写一段代码不然不算过关。1.2 简历和项目准备的坑简历这件事我踩过一个大坑。最初我把自己参与过的所有项目都写上去了觉得项目多显得厉害结果面试官一深挖就问穿了。后来我把简历精简到两个项目一个偏重业务、一个偏重技术深度每个项目都提前准备了如下问题这个项目解决的核心问题是什么为什么要用你选的那个方案你在里面负责哪些模块最有技术含量的部分是哪里有没有做过性能优化具体数据是多少如果重新做一遍哪里会改成什么方案这些问题如果没有提前想清楚面试现场很容易卡壳。尤其第二个问题面试官几乎是必问的。我记得我在准备项目复盘的时候把自己写过的代码重新翻了一遍把一些当时模糊的决策点全部想明白了后来面试时被问到项目细节基本都能接住。1.3 刷题策略和时间安排刷题这件事我的策略是先分类、再限时、最后复盘。分类的意思是不要今天刷一道链表、明天刷一道动态规划而是按专题集中刷比如这一周全是二叉树下一周全是动态规划这样知识迁移效率高。我给自己定的节奏是工作日每天保证2小时1小时算法题 1小时基础知识背诵和手写。周末半天做一次完整的模拟面试自己给自己出题然后对着镜子讲或者录音下来听。这个方法挺推荐的因为很多知识点你觉得会了但真让你口头表达出来你会发现说话逻辑是乱的。基础知识的背诵不是死记硬背而是要把每个知识点背后的为什么想清楚。比如事件循环你不能只背微任务先于宏任务你得理解为什么要有微任务、哪些api会进入微任务、浏览器和Node的事件循环有什么区别。面试官只要顺着你的回答追问两三句你是真懂还是背的立马就能试出来。2. 字节跳动四轮面试全记录字节跳动是我春招面的第一家也是整体流程最长、考察最全面的一家。我投的是北京的前端岗位从一面到offer大概用了两周时间中间每轮面试间隔大概2-3天。整体感觉是字节非常看重基础功底和代码能力问题不绕弯子上来就是硬核问题。2.1 面试流程回顾字节的流程是一共四轮前三轮是技术面最后一轮是HR面。一面主要聊基础JavaScript、CSS、网络都会涉及中间穿插手写代码。面试官让我做自我介绍的时候我就简单说了一下学校、实习经历和主要技术栈大概一分钟左右。然后他就开始问问题了。二面会深挖项目和框架原理同时会有一道中等难度的算法题。这一轮明显感觉到面试官更关注你思考问题的过程而不是答案本身。三面是综合面除了技术问题之外还会问一些开放性的场景设计题比如如果让你从零设计一个前端监控系统你会怎么设计考察的是你的知识广度和系统设计能力。HR面就相对轻松了聊的主要是职业规划、为什么选择字节、对加班的看法、目前的offer情况之类的问题。2.2 高频题目深度解析我按记忆把字节面试中比较有代表性的题目列出来然后说下我当时是怎么答的以及哪些地方值得注意。第一道是手写Promise.all。这道题我建议所有准备前端面试的人都应该重点准备。Promise.all的核心逻辑是接收一个promise数组返回一个新的promise所有promise都成功则返回结果数组任何一个失败则reject。我在实现的时候先用一个计数器记录已完成的数量然后用一个数组按顺序存结果。这里有个细节要注意结果数组的顺序要和传入的promise顺序一致不能因为哪个先resolve就放在前面。我当时把这个点讲出来了面试官明显比较认可。第二道是事件循环相关的题。面试官给了一段代码问输出顺序。大概是console.log(script start) setTimeout(() { console.log(setTimeout) }, 0) Promise.resolve().then(() { console.log(promise1) }).then(() { console.log(promise2) }) console.log(script end)输出顺序是script start、script end、promise1、promise2、setTimeout。这道题我答得比较快因为准备的时候专门把微任务和宏任务的执行顺序捋过一遍。这里要特别注意Promise的then回调属于微任务会在当前宏任务结束前执行而setTimeout属于宏任务要等本轮所有微任务执行完之后才会执行。第三道是算法题反转链表。这道题有两个解法迭代和递归我建议两个都掌握。我当时先讲了思路说用三个指针pre、cur、next来迭代处理然后把代码写出来了。面试官又追问了递归写法我也写了一遍。这类经典题的要点是先说自己用什么方法、时间复杂度是多少再动手写这样显得思路清晰。2.3 字节面试避坑心得字节的面试强度和节奏是真的快一面就可能直接上算法题而且手写代码的时候面试官会盯着你写。我总结了几个心得手写代码之前一定先讲思路。哪怕思路很简单也要说清楚既能让面试官知道你在想什么也能给自己理清逻辑。最怕的是闷头就写写到一半发现思路错了那就很难圆回来了。遇到不会的题千万不要直接说不会。我当时的做法是先把自己能想到的切入点说出来哪怕这些点不一定对。比如问我一个没接触过的api我就说这个api我不太熟悉但根据命名我猜它大概是做什么用的我平时处理类似需求的时候会用xxx方案。面试官一般不会因为你不会一道题就否定你反而会看你面对未知问题时有没有解决思路。字节的算法题难度整体是中等偏上的如果平时没有刷题习惯会吃大亏。我建议至少把leetcode上链表、二叉树、字符串处理、动态规划入门这四类题刷够50道再去。刷题真的没有捷径唯手熟尔。不过也不要盲目追求数量每道题做完之后要总结思路下次遇到类似的能反应过来才行。3. 网易面试最温和但也最抠细节网易这边体验很好整体流程走下来给人的感觉是面试官非常耐心不太会打断你说话问的问题也比较体系化。网易的面试只有两面技术面加一轮HR面效率挺高的。3.1 面试流程回顾网易一面是远程视频面的面试官先问了一些项目相关的问题然后沿着我提到的技术点往下深挖。比如我在项目里提到了做过首屏加载优化他就顺着问你是怎么定位性能瓶颈的用了哪些手段效果怎么样每个问题都问得很细。二面更偏向原理Vue响应式原理、虚拟DOM、diff算法都有涉及。还问了一些工程化相关的问题比如webpack打包流程、如何做项目构建优化。HR面主要聊了期望薪资、base地点偏好、手上的其他offer情况以及有没有考研的打算。整体氛围比较轻松。3.2 高频题目深度解析网易面试比较有代表性的题目第一个是Vue响应式原理。我在2019年那阵子Vue 2.x还是主流所以这道题的标准回答是围绕Object.defineProperty展开的数据被observe之后每个属性都有一个Dep依赖收集器组件渲染时会把对应的Watcher收集进来数据更新时触发setterDep通知所有Watcher去更新。这里我额外提了一句Object.defineProperty无法监听新增属性所以Vue 2提供了Vue.set来解决这个问题面试官觉得这个点提到位了。第二个是HTTP缓存机制。这道题值得把每一个细节都搞清楚。强缓存是通过Expires和Cache-Control实现的Expires是HTTP/1.0的东西有客户端时间不准的问题所以HTTP/1.1引入了Cache-Control用max-age来做相对时间。协商缓存有两种验证方式一种是Last-Modified配合If-Modified-Since另一种是ETag配合If-None-Match。我当时把这些对比着讲了一遍还说了为什么有了Last-Modified还要有ETag因为Last-Modified最小粒度是秒同一秒内多次修改文件是没法感知的。第三个是实现深拷贝。这道题我踩过坑所以多说一句。很多人在面试时写深拷贝就直接用JSON.parse(JSON.stringify())但面试官一定会追问这个方法有什么问题当时就问了我说它没法处理undefined、函数、Symbol而且循环引用会直接报错。然后面试官让我写一个能处理循环引用的深拷贝。我的思路是用WeakMap记录已经拷贝过的对象如果碰到相同的引用就直接返回复制过的对象。这样既能解决循环引用的问题也可以复用已经拷贝的对象。3.3 网易面试避坑心得网易的面试官很喜欢顺着你的回答一路追问所以你在回答每个问题之前要想清楚自己说的每句话会不会被追问。这个很考验对知识掌握的完整度。我建议在准备阶段每复习一个知识点都要自己问自己如果我是面试官我会顺着这个知识点追问什么然后把可能的追问问题也准备一遍。另外网易面试明显对项目的完整度要求比较高。我建议简历上每个项目都要有明确的背景-方案-数据结构。背景是为什么要做这件事方案是你的技术选型和具体实现数据是做完之后的效果比如页面加载时间从多少降到多少、线上问题减少了多少。数据不需要多华丽但一定要真实因为面试官真的会追问数据是怎么测出来的。4. 美团三轮面下来最看工程落地美团这边同样也是三轮技术面加一轮HR面。整体感觉是美团的面试官非常务实问题基本都是围绕真实业务场景展开的不太喜欢问八股文式的概念题更看重你能不能解决实际问题。4.1 面试流程回顾美团一面也是先过基础但和字节不一样美团的基础题更多是穿插在场景里问的。比如它不会直接问跨域有哪些方案而是问如果你们项目前后端分离接口跨域了你会怎么处理需要你结合实际场景来回答。二面偏向工程化问了很多webpack配置和优化相关的问题还让设计一个前端通用组件库的架构方案。三面是leader面聊得比较深包含系统设计题、团队协作经验、遇到技术难题时的处理方式等。4.2 高频题目深度解析美团让我印象最深的一道题是如何设计一个前端通用组件库。这道题开放性很强考察的是你的架构能力。我当时从四个层面来回答组件层、样式层、工具层、文档和示例代码。组件层要明确组件之间的层级关系和通信方式样式层要考虑主题定制能力我提了CSS变量和BEM命名规范工具层包含表单校验、请求封装等公共能力文档层要支持组件展示、API说明和在线调试。回答完这些之后面试官又追问了组件库的版本发布策略和兼容性处理我就说了用semver语义化版本、按需加载要考虑babel-plugin-import这种方案。第二个是webpack构建优化。美团比较关注优化所以我答的时候专门提了三个方向一是通过happyPack或thread-loader开启多线程构建把耗时的loader处理并行化二是用DllPlugin把不常变动的第三方库预先打包从而减少二次构建时间三是合理配置splitChunks做代码分割把公共模块单独抽出来避免重复打包、减少首屏加载JS体积。另外我还提了一句优化之前一定要先做构建耗时分析用speed-measure-webpack-plugin定位真正的瓶颈不要盲目优化。第三个是ES6模块和CommonJS的区别。这道题看起来基础但美团问得挺细。我说CommonJS是运行时加载因为require是在代码执行到那一步才去加载模块的ES Module是编译时加载import语句会被提升到文件顶部所以可以做静态分析和tree shaking。此外ES Module的export是引用拷贝而CommonJS的module.exports是值拷贝。最后还提了一句ES Module是严格模式下运行的所以顶层this是undefined而CommonJS环境下模块顶层的this指向module.exports。4.3 美团面试避坑心得美团的场景题比重很大所以你在准备的时候不能只背概念还要能把概念落到真实场景里。我建议平时多留个心眼想想自己做过的项目里哪些地方用到了某个技术点如果面试官问起来能不能用自己项目的例子来说明白。比如你简历里写了用webpack做过构建优化那就要把当时的配置项、优化前后的时间对比都准备好。另外美团对工程化这块的考察比另外两家更细。如果你对webpack还停留在会配脚手架的阶段建议把webpack的核心概念系统过一遍入口、输出、loader、plugin、devServer、source map、tree shaking、scope hoisting这些都要能说清楚。特别是loader和plugin的区别要弄清楚loader是让webpack能处理非JS文件plugin则是用来扩展webpack自身功能两者定位完全不同。5. 三家公司横向对比与复盘三家公司面完之后我花了很长时间做复盘。面试是一个双向选择的过程不仅是公司在评估你你也要通过面试过程判断这家公司适不适合自己。5.1 面试风格与考察侧重点对比我把三家的差异整理成了一个表格方便对照看公司考察侧重点算法题难度项目追问深度流程节奏字节跳动基础功底、代码能力中等偏上中等快四面两周走完网易原理理解、项目完整度中等深逐层追问适中两面HR美团场景设计、工程落地中等中等偏上稳三轮HR字节推荐算法基础扎实、喜欢硬核题目的候选人网易更适合能沉下心把原理讲透、项目细节扎实的人美团则偏爱有工程sense、能解决实际问题的工程师。这些特点没有高下之分关键看你自己是什么类型的选手。5.2 常见问题速查与避坑清单根据整个春招周期里我自己和身边同学的面试情况我整理了一个高频问题速查表大家准备的时候可以对照着自查分类常见问题回答要点JS基础手写new、bind、call/apply注意new要创建新对象、修改原型、绑定thisJS基础事件循环输出顺序题先宏任务再微任务的细粒度逻辑框架Vue父子组件生命周期顺序父created、子created、子mounted、父mounted框架React setState同步还是异步合成事件中是异步原生事件和定时器里是同步网络输入URL到页面渲染全过程从DNS、TCP、HTTP到渲染树分阶段说网络HTTPS握手过程证书验证、密钥交换、加密通信三步CSS水平垂直居中方案至少说出flex、positiontransform、grid三种工程化webpack构建流程从入口解析依赖图、loader处理、plugin介入、输出性能首屏加载优化方案代码分割、路由懒加载、图片压缩、资源预加载5.3 关于心态、谈offer和选择的个人建议面试过程中心态起伏是很正常的。我记得面字节三面之前我一度紧张得睡不着因为前面每一轮都聊得不错反而怕最后搞砸。后来我想明白了一个道理面试就是一次技术交流对面坐的面试官也是从你这个阶段过来的答不上来不丢人不懂装懂才丢人。抱着这种心态之后后面几场面试反而越聊越放松。关于offer选择我自己的经验是不要只盯着薪资。我当时对比了三家的技术栈、业务方向、团队氛围和地理位置最后选了最适合自己职业规划的那家。薪资固然重要但第一份工作更关键的是能不能让你在技术上快速增长有没有靠谱的导师带你业务是不是有足够的成长空间。这些因素你可以在面试过程中去感受也可以在HR面的时候直接问清楚。聊聊这套准备方法能不能复用现在回头再看2019年春招这段经历我个人最大的感受是面试准备的本质不是背题而是搭建一个完整的知识网络。你会发现很多题目表面上看是独立的但实际上都指向同一个底层能力比如手写Promise是在考察你对异步流程的控制能力事件循环输出题考察的是你对JS运行时机制的理解HTTP缓存则是在考察你对浏览器资源加载过程的认识。这些能力是相通的。所以如果你想复现这套方法我建议不要只盯着题库刷而是先花时间把我在第一节列的知识地图过一遍确保每个板块都能讲出核心原理然后再结合面经去验证自己的掌握程度。面经的价值在于告诉你某家公司喜欢考什么方向的题让你有的放矢地补强但如果你本身基础不牢看再多面经也是空中楼阁。最后再分享一个小技巧每次面试结束后当天晚上就把所有能回忆起来的题目记录下来然后逐题标注自己答得好不好、缺漏在哪里。这个复盘习惯坚持下来你会发现第二场面试比第一场明显更稳。我整个春招大概整理了四十多道题目每一道都写了解题思路和当时的回答版本这才是这套面经整理下来最值钱的东西。