ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

字节跳动前端实习面经:从准备到三面全流程复盘

字节跳动前端实习面经:从准备到三面全流程复盘 2020前端实习面经:字节跳动写这篇面经的时候我刚从字节的实习面试流程里走出来不久。2020年这个时间点前端岗位的竞争已经相当激烈尤其是字节这种体量的公司一个实习岗放出来简历池里各种背景的人都有。我自己的背景不算突出非科班学校普通靠着自学的React和几个小项目撑门面能走到最后拿到offer中间确实有不少值得记录的经验。当时我搜遍了网上能找到的字节面经发现很多人的分享都是零散的“我面了什么题”很少有完整讲清楚“为什么这么面”、“背后在考察什么”的。所以这篇面经我想换个写法把整个面试过程拆开来讲包括每一轮的重点、我踩过的坑、刷题策略、以及面试官各种追问背后的真实意图。如果你正在准备前端实习面试尤其是目标大厂的话这份内容应该能帮你少走不少弯路。先说结论字节的前端面试核心看三件事——基础扎不扎实、编码能力强不强、脑子灵不灵活。框架API背得再熟用处不大手写代码和原理深挖才是重头戏。下面我从整个准备周期开始完整复盘一遍。1. 面试前的准备简历、刷题与心态1.1 简历怎么投、怎么写才能过初筛2020年那会儿投递字节的渠道主要有官网校招、内推、以及牛客网上的各种内推帖。我走的是一条相对有效的路径先在牛客上找到了一名在字节做前端的学长说清自己的情况后要到了内推码。内推在简历筛选阶段确实有优势因为内推人的邮箱会直接收到你的简历如果对方团队缺人、觉得你合适甚至可以帮你内部沟通简历被捞起来看一眼的概率比海投高得多。简历内容这块我当时踩了一个典型误区——把“会点什么”写了一大堆什么Vue、React、小程序、Webpack全堆上去看起来什么都会实际上面试官一眼就看穿是“全而不精”。后来我改成了项目驱动型的写法只放两个项目一个用React做的小型C端应用一个纯JS的编译器玩具。每个项目下面列三点做了什么、用了什么关键技术、解决了什么具体问题。这里有个细节值得说。项目里一定不要只写“用什么技术栈实现了什么功能”面试官更在意的是“你在项目里有没有遇到什么困难怎么解决的”。我在简历里写了一条“用Web Worker优化了长列表渲染时的卡顿问题”这条在后续面试中被追问了至少三轮但每一轮我都能展开说清楚。你在简历上写的每一个技术点都要做好被追问到细节的准备。1.2 刷题范围和学习路线字节的面试算法部分是出了名的硬核实习生也逃不掉。我当时给自己定的刷题策略是LeetCode热题100 剑指Offer 高频手写题核心目标是掌握常见题型的套路而不是追求题量。我前后刷了大概两百多道题不是刷完就扔而是每一道题都做了分类整理数组双指针、链表反转、二叉树遍历、动态规划、字符串处理。分类很重要。因为面试考算法是有套路的面试官很少会出特别偏的题基本都是“你能联想到哪个经典解法”的变体。比如字节喜欢考“最长不重复子串”、“合并两个有序数组”这类题看起来是不同题实际上都是滑动窗口、双指针的思路。你熟悉了套路遇到新题时就能快速判断该往哪个方向试。准备过程中我还额外做了一件事用面试官视角给自己出题对着白板用纸笔画流程讲思路。一开始特别不习惯总是边说边写就乱掉了。后来发现了一个好方法——先给题目做语义拆解再讲清楚复杂度分析然后才开始写代码。养成这个习惯后到真正面试时写代码反而成了最轻松的一环因为前面已经跟面试官对齐了思路写代码只是把想法落地而已。1.3 心态建设被拒绝是正常的这一点我必须专门提一下。我认识不少人被字节挂了之后很长时间缓不过来但其实实习面试的挂率极高也许不是能力问题只是岗位就那两三个HC比你强的人太多了。我在准备时给自己定的心理底线是字节只是目标之一不是唯一去处。这样想之后面试过程反而轻松不少因为不会出现“如果面挂了天就塌了”的焦虑感。还有一个很现实的心态问题是你永远不知道面试官当天是什么状态。有的面试官喜欢揪着框架源码问到底有的面试官则更喜欢考察场景题在不同人手里面试体验会差别很大。如果你的某轮面试感觉特别差不用太在意结果可能会比你想的好。字节的面试官评价体系里沟通能力和学习潜力是占有相当权重的。2. 技术一面从计算机基础到JavaScript原理2.1 一面整体考察什么字节的一面通常以基础为主难度没有想象中那么高但覆盖面很广。我那一面时长约1个小时整体节奏自我介绍5分钟 基础八股文20分钟 手写代码15分钟 项目问答10分钟 反问10分钟。自我介绍是一个很容易被忽视的环节。我一开始准备了一版讲自己多热爱前端的自我介绍后来才发现面试官根本不吃这套。字节的面试官更想听的是你做过什么、擅长什么、想往哪个方向发展最好30秒内讲完别铺垫。我最后定稿的自我介绍口吻是这样的“我是XX主要用React做开发做过两个项目一个是XX一个是XX。对前端工程化比较感兴趣平时会看一些Webpack相关的源码也在尝试写一些小工具。”干净利落把主动权交给面试官。一面最核心的考察点是JavaScript基础这一块如果答不好基本上后面就没戏了。我整理了一下被问到的点和对应的回答思路。2.2 JavaScript基础八股文这些题是必考的先说闭包。面试官一般不会直接问“什么是闭包”而是给你一段代码问你输出什么或者问“闭包在实际开发中有哪些应用场景”。我记得他当时给了一段经典的for循环setTimeout代码问输出结果。这个坑很多人踩过正确答案是打印出一堆N而不是0、1、2。关键在于var声明的变量是函数作用域循环结束时i已经变成了最终值。解法很简单把var改成let或者用立即执行函数包一层形成闭包捕获变量。我在回答的时候没有只给结论而是补充了底层原因每次循环实际上共享了同一个词法环境setTimeout的回调被推入宏任务队列之后函数调用时才去词法环境里查找i而那时i早已变成了退出循环的值。面试官对你的追问是不是能撑住往往就体现在这种“能解释到哪一层”上。接下来是this指向问题。面试官问的不是背书式的“this指向调用者”而是直接抛了几道代码题比如普通函数、箭头函数、对象方法调用时的this分别指向谁。这里最容易出错的点是箭头函数没有自己的this它会捕获定义时所在上下文的this。我记得还有一道bind、call、apply的对比题答完后还要求我手动实现一个bind方法。这个手写题很经典核心是要考虑到绑定时可能有参数柯里化以及new和bind混用时的优先级问题。原型链是每个前端面试都绕不开的。面试官当时问了“创建一个对象有几种方式”然后追着new的原理问了一遍——new的时候到底发生了什么。这个必须答得很完整先创建一个空对象、将这个对象的原型指向构造函数的prototype、将构造函数的this绑定到这个新对象上并执行、最后根据构造函数是否返回对象来决定返回什么。回答完之后又让我手写一个new。最后事件循环。字节一面问事件循环的概率几乎达到了百分百而且问得特别细。除了宏任务和微任务的基本概念面试官还喜欢让你分析一段包含Promise、setTimeout、async/await的代码输出顺序。这个我建议你去把所有边界情况都理一遍尤其是await那行代码它在await之后的代码某种程度上是“微任务中的微任务”输出顺序经常让人意外。多刷几道Event Loop的题这种题其实是有固定套路的。2.3 CSS和浏览器原理注意覆盖面前端面试不只是JavaScriptCSS虽然考察比重不如JS高但基本概念必须掌握。我记得被问到的是flex布局的常见属性、BFC是什么、CSS选择器的优先级如何计算。BFC这个点说来话长。面试官只问了“哪些方式能创建BFC”我答了overflow不为visible、display为inline-block、position为absolute或fixed、float不为none等然后他又问“BFC有什么实际作用”我举了清除浮动、防止margin塌陷的例子。这种问题只要你实际写过页面基本都能说几句但如果只是背概念而没有亲手处理过容易卡壳。浏览器渲染原理也是大热门。从输入URL到页面展示这个过程你最好能完整讲下来DNS解析、TCP连接、HTTP请求、服务器响应、浏览器解析HTML构建DOM树、解析CSS构建CSSOM树、两者合成渲染树、布局、绘制、合成。面试官让我重点解释“重排与重绘的区别”以及“如何减少重排”。这里有个容易忽略的细节访问offsetWidth、offsetHeight这类属性会强制触发同步布局如果你在读写的循环里反复操作就会不断强制重排。所以批量读取、批量写入或者用DocumentFragment做隔离都是实际开发里有效的优化手段。2.4 HTTP与网络基础这块字节问得也比较多特别是HTTP缓存。我在一面被问到强缓存与协商缓存的区别、分别对应的HTTP头有哪些。强缓存是直接走本地缓存不发请求对应的头是Cache-Control和Expires协商缓存是发一次请求通过Last-Modified/If-Modified-Since和ETag/If-None-Match来校验资源是否过期。这里有一个隐藏考点ETag和Last-Modified同时存在时哪个优先级更高答案是ETag因为它的精度更高能解决Last-Modified在一秒内多次修改无法识别的问题。还有一个考法是给你一堆头信息让你判断这个资源会走强缓存还是协商缓存这就涉及Cache-Control不同字段的记忆了比如no-cache是“可以缓存但要先校验”no-store才是“完全不能缓存”这两个经常有人混。2.5 一面手写代码复盘一面手写在面试中占比并不小字节尤其看重这一点。我遇到的手写题是实现一个深拷贝。这题看着简单实际坑特别多。我没有直接上来写代码而是先问面试官“需要拷贝的类型有哪些函数、Date、RegExp这些需要处理吗需要处理循环引用吗”面试官说“你先实现一个基本版本”我于是先写了递归版本处理了普通对象和数组然后主动提出可以处理循环引用用WeakMap解决最后又讲了如何区分数组和对象。这个“先沟通再动手”的习惯我强烈建议你养成。面试官不是看你闷头写而是看你怎么理解需求、怎么拆解问题。如果你能在写代码前用一两句话表明你的思路给面试官留下“这人有工程思维”的印象即使代码里有一点小bug面试评价也不会差。深拷贝的具体实现思路也分享一下先判断当前值是不是对象不是就直接返回是对象的话需要区分普通对象、数组、Date、RegExp等类型然后递归拷贝每个属性。循环引用问题可以通过一个Map或WeakMap来记录已经拷贝过的对象如果再次遇到就直接返回上次拷贝的结果。在实际工作中这种深拷贝虽然用lodash的cloneDeep就够但手写一遍能帮你彻底理解引用的概念。3. 技术二面React原理、项目深入与手写题3.1 二面到底在面什么字节二面和一面最大的区别在于一面是考察你的基础是否扎实二面则开始考察你“是不是真的写过项目”、“对技术有没有自己的理解”。我二面碰到的面试官应该是一个team里的资深前端问的问题更深很多都是React源码层面的。先聊一个常见误解很多人以为只要把React官网文档看了、API背熟了就能应付面试。实际上二面如果深挖React问的是原理实现不是API。比如面试官让我解释“React 16的Fiber架构解决了什么问题”。这个问题如果只看文档你可能知道“是新的协调算法”但如果你不知道老的递归更新会导致主线程长时间被占用、页面掉帧卡顿就没办法把这个问题真的讲透。我当时是从v15和v16的对比讲起的老架构是递归同步更新一旦开始渲染就停不下来组件树一大就容易卡顿。Fiber把更新拆成了一个个小任务每个任务都能被中断然后根据优先级重新调度。React可以在浏览器有空闲的时候通过requestIdleCallback或自己的调度器慢慢执行更新任务保证页面响应不被阻塞。这样讲下来面试官一般就会满意因为他要的不是官网的一句话结论而是你是否理解这个设计背后的动机。3.2 React生命周期与Hooks二面还重点问了React生命周期。Class组件那一套——componentDidMount、componentDidUpdate、componentWillUnmount——虽然现在很多新项目已经不用了但面试时仍然会问建议还是弄清楚整个挂载、更新、卸载的流程。Hooks相关的问题是重头戏。我记得被问到三个方向useEffect的执行时机、useCallback和useMemo的区别、以及“为什么不能在条件语句里写Hooks”。前两个比较基础大家一般都能答上来。第三个是React Hooks设计的核心原理——Hooks是基于链表实现的React在每次渲染时按顺序读取Hook值如果某个Hooks出现在条件语句里可能导致某次渲染的Hook数量与上一次不一致React内部就没法正确地把状态和对应的Hook对应起来所以只能在顶层调用。还有一个经典的追问是“useEffect和useLayoutEffect的区别”。useEffect是异步执行的一般在绘制完成后才触发useLayoutEffect是同步执行的在DOM变更之后、浏览器绘制之前触发。面试官问我“在实际开发中什么场景需要用到useLayoutEffect”我提供了一个读DOM布局属性并做同步操作的例子。因为如果在useEffect里同步读取刚刚渲染的DOM并做样式修改浏览器已经先绘制了一帧用户会看到闪烁而useLayoutEffect在绘制前执行就没有这个闪烁问题。3.3 虚拟DOM与Diff算法每次面React相关岗位虚拟DOM和Diff算法几乎必然被问到。面试官通常不会让你完整讲一遍Diff的实现而是从一个痛点引入为什么需要虚拟DOM直接操作真实DOM不是更直接吗答案核心在于“跨平台能力”和“性能优化”。真实DOM的创建、修改、销毁开销很大虚拟DOM本质上是用一个轻量的JS对象描述UIReact通过对比新旧两个虚拟DOM的差异计算出最小的更新代价再批量操作真实DOM。Diff算法我建议从三个前提讲起它们是React Diff高效的关键1只对同级元素进行Diff如果一个DOM节点在前后两棵树中跨越了层级React不会尝试复用而是直接销毁重建2不同类型的元素产生不同的树比如从div变成spanReact直接卸载原节点不会继续对比子节点3通过key来暗示哪些子元素在不同渲染下是稳定的这也是为什么key一定不能用数组index代替——用index做key当列表中间插入一个元素时React会认为后面的元素类型没变但key变了导致整个列表的大量重渲染。面试官当时给我出了一个具体的列表Diff场景题让我分析为什么用index做key有性能问题。这个场景很典型列表原始是[A, B, C]新列表是[B, A, C]如果你用index做keyReact会认为key为0的节点从A变成了Bkey为1的节点从B变成了A每个节点都复用了错误的组件状态如果你用稳定的唯一ID做keyReact就能识别出A和B只是换了位置通过移动节点而不是重建节点来完成更新。3.4 项目深挖面试官真正想听什么项目深挖是我二面中时间最长的一个环节大概持续了20分钟。面试官拿着简历问得非常细“你说你用SSR优化了首屏加载具体是怎么做的遇到了什么问题怎么排查的”这里我总结出了面试官深挖项目时真正想听的三个层次第一项目是不是你真正参与过的还是只是网上抄的demo第二你在项目里的深度是只写页面还是深入过底层第三你遇到问题时的解决思路是能自己排查还是只会百度。针对这三点准备项目介绍时最好都准备好“遇到什么问题-如何分析-如何解决-最终效果”这样一条完整的故事线。比如我说项目里遇到首屏白屏问题第一反应是排查网络请求发现有一个大JS文件加载过慢。然后通过路由级代码分割把首屏不需要的组件拆出去再配合gzip压缩首屏可交互时间从3.2秒降到了1.5秒。面试官听完了一般会追问“代码分割是怎么做的”这就是React.lazy和Suspense的考点。它重点不是你用了什么API而是你有没有数据意识优化前是多少、优化后是多少。任何优化没有数据支撑面试官都只会当你在讲故事。3.5 二面手写题防抖节流、柯里化与Promise二面也少不了手写代码。我当时被考了三道题难度依次递增实现防抖函数、实现柯里化函数、实现一个符合Promise/A规范的简易Promise。防抖和节流是前端面试的最高频手写题之一没有理由不会。它们两个容易搞混其实区别很简单防抖是指事件触发后n秒内不再触发才执行适合input输入搜索节流是指n秒内最多执行一次适合滚动事件。手写防抖的核心是维护一个timer每次触发时clearTimeout再重新setTimeout手写节流的核心是记录上次执行的时间戳当前时间与上次执行时间之差大于阈值才执行。柯里化手写题考的是对闭包和函数式编程的理解。核心思路是返回一个函数如果传入的参数个数已经达到了原函数的参数个数之和就执行原函数否则继续返回函数收集参数。Promise的手写是最有挑战性的。面试官只要求我实现一个基础版本能处理resolve、reject和then方法即可不需要实现Promise.all这些。但即便是基础版本也有几个关键点构造函数里的resolve和reject需要确保异步调用即使用queueMicrotask或setTimeout模拟微任务、状态只能从pending变为fulfilled或rejected且不可逆转、then方法需要支持链式调用。我当时写的时候在“then返回新Promise”这一步卡了挺久因为你需要处理回调返回值是普通值还是Promise的情况。面试官很耐心还给了提示。最后写完之后他补了一句“你回去把Promise/A完整规范看一遍对你理解异步会很有帮助”。这个建议我后来真的去做了收获很大。3.6 设计模式与工程化二面中还问了一些偏工程化的问题比如“你在项目中有没有用过Webpack的Loader和Plugin它们的区别是什么”。这个问题我建议每个准备面试的人都好好整理一下因为Front-end工程化是大厂实习生一个很重要的加分项。Loader是一个转换器它把A文件变成B文件比如babel-loader把ES6转成ES5Plugin是一个扩展器它在打包的特定时机做额外的事情比如HtmlWebpackPlugin在打包后自动生成HTML文件。简单来说Loader负责“翻译”Plugin负责“干活”。还有一道有意思的场景题设计题“设计一个前端错误监控系统”。我当时的思路是分三层采集层监听window.onerror、unhandledrejection、fetch请求失败等、上报层用sendBeacon或navigator.sendBeacon接口在页面unload时上传错误日志避免用fetch导致日志丢失、分析层服务端聚合错误信息按来源、错误类型、影响用户数排序。这类题没有标准答案主要是看你有没有从0到1搭一个系统的思路。4. 技术三面与HR面:综合考核与软实力4.1 三面更多是综合能力考察到了三面通常是团队负责人或者更资深的技术专家面试考察点已经从“你会不会”变成了“你能走多远”。我的三面整体长度约45分钟没有太多八股文更多是聊技术选型、学习方式、以及对一些开放问题的思考。三面给我印象最深的一道题是“如果让你从0到1搭建一个前端项目你会怎么选型为什么”这道题的特点是没有任何标准答案但很能拉开差距。我从业务场景切入项目是重交互的中后台系统还是偏内容展示的官网这会影响是选React还是Vue、是用SSR还是CSR团队规模会影响要不要引入TypeScript、要不要上Monorepo项目生命周期会影响要不要花时间搭一套完整的CI/CD流程。面试官会在你选型过程中不断追问“你还考虑过哪些方案”、“它们分别有什么优缺点为什么你不选”。这就是在考察你的技术视野和决策能力。还有一个问题是关于性能优化的开放题“你平时是怎么发现和定位前端性能问题的”我的回答思路是先用Lighthouse或Chrome DevTools的Performance面板看核心指标重点关注首次内容绘制FCP、最大内容绘制LCP、累积布局偏移CLS然后结合页面实际情况分析是网络问题、渲染问题还是JS执行问题再针对定位到的问题做专项优化。面试官其实更在意的是你有没有一套可复用的排查方法论而不是你背了多少条优化手段。三面还问了一个关于“遇到技术难题怎么突破”的题。我提到自己经常看国外技术博客和源码并且把自己看懂的源码写成一个模拟实现的项目放到GitHub上。这个回答能体现学习能力和自驱力三面这种层面的面试官非常看重这两点。4.2 HR面与Offer选择HR面相对最轻松但也不能完全放松。字节的HR会问自我介绍、为什么选择字节、对实习时间有没有要求、有没有其他的offer、你觉得自己在面试中表现得怎么样。这里有一个建议HR问你“有没有其他offer”时不要刻意撒谎或隐瞒。如果手里确实有备选offer可以坦诚说“还有另一个在流程中但我个人更偏向字节因为团队技术栈更匹配”。如果手里没有offer就说“目前没有其他offer但在流程中的还有几个”HR完全能理解。切忌为了拉高身价去编造offer一旦被发现会直接失去录用机会。到HR面的时候一般离offer就一步之遥了按照正常流程都会走到这里。HR面结束后过了几天我收到了offer。薪资方面字节的实习薪资在业内属于第一梯队加上房补在同级别公司里很有竞争力。不过我这里不展开数字了因为每年的行情都在变你只需要知道字节实习的薪资福利在行业内是相当能打的就是了。4.3 复盘我自己的面试表现面试结束后我做了一个比较完整的复盘。从一面到三面我在技术上最强的部分是JavaScript基础最弱的部分是网络协议细节。回顾来看如果我能在准备阶段多花些时间在计算机网络特别是TCP/UDP细节上面试过程可能会更从容。复盘过程中我还发现了一个规律面试官最满意我回答的环节往往不是某个八股文背得最流利的时刻而是我主动展示思考过程的时刻。比如我回答深拷贝时主动问需求边界回答项目优化时主动给出数据对比这些都让面试官感觉是在和一个真正有实习经验的人在交流。准备面试不只是背题更是要学会“像一个工程师一样思考和表达”。5. 字节前端面试的高频考点总结与独家建议5.1 高频考点速查表根据我自己的面试经历以及同期朋友们的反馈我整理了一份字节前端实习面试的高频考点速查表。这些考点的重要性和出现频率是我排的可以参考但不需要完全依赖。考点出现频率考察深度备考建议事件循环与异步极高深必须能完全分析Promise/async/setTimeout混合代码的输出顺序闭包与作用域极高中深能解释原理能手写利用闭包的函数this指向极高中熟记各种调用方式下的this指向原型链与继承高深能手写new、Object.create理解class的转译结果React Fiber与生命周期高深理解设计动机能画调度流程图并解释为什么需要中断虚拟DOM与Diff高深理解key的作用、为什么不能用index能手动实现简易DiffHTTP缓存高中强缓存/协商缓存的全流程和所有相关头信息浏览器渲染机制高中重排重绘、合成层、帧概念防抖节流高中能手写并说明适用场景跨域解决方案中中CORS原理、JSONP、反向代理等Webpack原理中深Loader与Plugin区别、打包流程、模块化机制性能优化高开放有数据支撑有排查思路5.2 独家建议如何利用好面经但不过度依赖面经这个东西本质上是一个“题库快照”。你看到的每一篇面经都是某个特定时间点、某个特定面试官、针对某个特定候选人出的题。它很有参考价值但不能当作完整的学习大纲。原因是字节面试的随机性很强不同面试官风格差异极大你按照一份面经准备遇到另一个风格的面试官就容易翻车。我的建议是把面经当成“查漏补缺的清单”而不是“押题宝典”。看到一篇面经先把自己代入如果面试官问我这道题我能完整回答吗能回答到什么深度凡是答不利索的知识点就回去系统学一遍而不是照着面经的答案背。因为字节面试官特别喜欢追问你背答案的话一个“为什么”追问过来就会露馅。另外强烈建议在准备阶段就养成“写博客”或“写笔记”的习惯。面试时被问到“你最近在学什么”时如果你有一个技术博客或GitHub仓库能展示你的学习轨迹会是一个非常强的加分项。哪怕只是每周写一篇短文记录自己学到的知识点也是在向面试官传递“这个人是真的爱技术”的信号。这个习惯不仅在面试中有用对后续的实习转正、正式求职都很有帮助。5.3 最后想说的话面试这件事除了硬实力确实有很大的偶然性。我从开始投递到拿到offer前后经历了简历筛选、三轮技术面、一轮HR面整个周期大约三周。过程中有兴奋有焦虑也有等待结果的煎熬。但回头看最值钱的其实不是offer本身而是被面试逼着系统性梳理了一遍前端知识体系。如果你也在准备字节的前端实习面试我想说的是不要被“字节面试难”吓倒也不要被网上各种神仙面经吓住。那些看起来答得完美无缺的面经很多都有美化成分。面试官想知道的是你当前真实的能力水平以及你有没有成长的潜力。把自己真实会的东西讲清楚、讲深入就已经超过一半的候选人了。如果你面的方向和我不同比如你面的是更偏Node.js或工程化的方向那么考察重点会有所偏移但JavaScript基础和手写代码仍然是必考的。前端这个行业的面试某种程度上就是在考察“基础扎实、思路清晰、手底下能出活”这三件事。你按照这个方向去准备去哪里面试都不会差。
返回列表