公司动态

2020百度前端笔试题复盘:考点拆解与答题策略

📅 2026/8/29 23:36:21
2020百度前端笔试题复盘:考点拆解与答题策略
每年到了七八月总有一批准备秋招的学弟学妹来问我百度Web前端工程师的笔试卷到底考什么我翻出2020年校招第一批笔试题认认真真看了几遍发现哪怕放到现在这套卷子的考点设计依然很能打覆盖面之广、区分度之高放在今天依然能筛掉大部分“只背API不读源码”的候选人。所以这篇文章不打算按题型罗列一遍就完事而是把这份卷子拆开揉碎从出题逻辑、核心考点、答题思路到考后复盘完整过一遍。无论你是准备2025届校招还是想测试自己前端基础扎不扎实这份复盘都值得花二十分钟看完。校招笔试卷和平时刷的面试题集有个本质区别它没有面试官在对面引导你必须在有限时间内通过纸面答案完成对你的判断。这意味着出题人必须在每个考点上都设计出“能区分会不会”的关卡而不是“听过名词就能蒙对”的选择题。2020年百度前端第一批卷子在这点上做得相当典型我结合当时的做题记录和后来参与校招评审的经验把这个过程完整还原出来。1. 2020年百度第一批前端卷的整体结构与出题逻辑1.1 一份典型的百度前端笔试卷长什么样先说整体观感。百度2020校招Web前端工程师笔试卷第一批的时间一般是60分钟左右题量控制在“认真做能做完、但不认真一定做不完”的水平。题型大致分为四块单选/多选选择题、简答/手写代码题、在线编程题、设计题。选择题覆盖的领域在我印象里包括HTML、CSS、JavaScript、浏览器原理、网络协议、前端工程化偶尔还会出现一两道数据结构相关的题。手写代码题通常是一道到两道纯JavaScript手写比如实现防抖节流、手写深拷贝、模拟Promise的某个方法。在线编程题两道左右基本是LeetCode中等难度偏下的水平但这不代表容易——限时和输入输出处理会让很多人在本地IDE里写得飞起、到了在线编辑器就卡壳。最后一题设计题很关键通常给出一个需求场景让你描述方案或者画结构这是拉开差距的地方。很多人拿到卷子第一反应是“题目不难”第二反应是“选项全认识但不确定”。这种感觉其实正是出题人想要的。以原型链为例题目不会问“什么是原型链”而是给你一段代码让你判断obj.hasOwnProperty(x)的返回值再让你判断obj.__proto__ Object.prototype是真的还是假的。如果你对原型链的理解停留在“对象可以通过__proto__找到父级”这个层面碰到这种组合判断就容易翻车。所以选择题考的不是记忆是你在平时写代码时有没有形成精准的概念模型。1.2 出题人到底在筛什么人百度前端团队在2020年那个时间点主要技术栈是React Vue并行、小程序也在大量落地团队需要的人是“能马上参与业务、又愿意往底层钻”的候选人。那么一套60分钟笔试卷如何筛出这种人答案是三句话基础题筛掉没系统学过的人编程题筛掉只会调用不会实现的人设计题筛掉只关注页面不关注工程的人。举个实际的例子基础题里一定会有一道关于事件循环的输出顺序题。这种题如果你平时只写过业务代码从来没关心过setTimeout和Promise.then的回调谁先执行基本会做错。而如果你能拿笔画出宏任务队列和微任务队列的演进过程这道题就是送分题。它要筛的就是“有没有把知识体系搭起来”的人。和面试题集不同笔试卷没有追问和解释的机会所以答案必须写得足够严谨。比如手写防抖函数阅卷标准看起来是“能输出一个函数”但实际评分时会检查this指向对不对、timer有没有越界、第一次调用的immediate参数有没有处理。这些细节恰恰是判断你是否真正理解防抖原理的抓手也是我在复盘时感受最深的一点。2. 基础选择题里的高频考点从语言陷阱到浏览器原理2.1 JavaScript的“送分题”其实都是陷阱题百度的笔试卷里JavaScript语言基础的比重一直不低。综合2020年批次的题目来看this指向、闭包、作用域提升、原型链是肯定跑不掉的。以this为例有个技巧是所有题目通用的先判断调用方式再判断调用位置。是普通函数调用、对象方法调用、new调用、还是箭头函数定义时捕获每次只要先把这四类分清楚所谓this指向难题就垮了一半。再看闭包。笔试很少直接让你“解释闭包”而是给你一个for循环里放setTimeout的经典代码问你输出什么以及怎么改才能输出 0 到 4。这道题其实在考两件事闭包导致变量共享以及let的块级作用域如何解决这个问题。更深一层的问法是“用var怎么改成var也能正确输出”这就逼着你想到用IIFE形成独立作用域。类似的考点还包括变量提升和函数提升的优先级——比如一段代码中先写var foo 3再写function foo(){}问你打印什么。这种题只靠死记硬背容易错真正理解解析器的工作方式就不会丢分。原型链的题在2020年卷子里也出现过。比较有代表性的考法是Function.__proto__是什么、Object.__proto__是什么。很多人到这里开始晕。其实记住一条结论就够了Function和Object的函数构造器都指向Function.prototype而Function.prototype本身又是一个对象对象又来自Object.prototype。如果选项里出现Function instanceof Object是true这类判断很多被绕晕的人就会犹豫。出题人很清楚90%的前端开发平时不会用到这层知识笔试就是要用这种反直觉的题把“背了几个月面经”和“真理解了原型链”区分开。2.2 浏览器机制与网络协议别看轻这两块前端笔试会出现URL输入到页面展示的完整链路题。它考的不是某一个小点而是你能否把DNS解析、TCP连接、HTTP请求、浏览器解析HTML、构建DOM树、生成CSSOM、布局、绘制这一整条链路串起来。2020年的百度卷里这种题以选择题形式出现居多但选项设计得非常有迷惑性比如会把“TCP建立连接属于浏览器进程”和“渲染进程负责网络请求”混在一起要你判断正误。我建议备考时不要只记结论要自己画一遍链路图。画的过程中你会想清楚这么几个问题浏览器进程和渲染进程之间的通信方式是什么document对象在哪个线程解析图片的onload事件是等到图片字节全下载完还是等解码完成。这些一旦理解到位比背十次“输入URL到页面展示”的步骤清单都有用。网络协议在笔试卷里一般占两三道题重点在HTTP缓存、HTTPS握手、TCP和UDP的区别、HTTP版本演进。其中HTTP缓存几乎是必考因为它直接关系到前端性能优化。常见考法是给一组响应头问你某次请求是走强缓存还是协商缓存。做这类题要抓住一个核心强缓存命中时根本不发起网络请求协商缓存一定要发请求给服务器确认再决定是否可以用本地缓存。Cache-Control和Expires同时出现谁优先ETag和Last-Modified哪个更精确这些都要形成条件反射。2.3 CSS与渲染盒模型、BFC、布局方案的底层逻辑CSS在笔试卷的占比没有JavaScript高但几乎每套卷子都会固定两到三题。2020年第一批卷子里出现过CSS盒模型的计算以及display: flex实现常见的三栏布局。盒模型这种题基本是送分项——你只要记得标准盒模型中width只包含内容区而在IE怪异盒模型中width包含了content padding border题目就能做对。但容易错的是box-sizing: border-box加百分比宽度的组合题要细心地把padding和border从总宽度里减掉再算。BFC是前端笔试的一道“经典老题”。考法通常是问触发BFC的方式有哪些以及BFC能解决什么问题。标准答案不外乎overflow: hidden、display: flow-root、浮动、绝对定位、display: inline-block等解决的是外边距折叠、浮动元素父容器高度塌陷、以及防止元素覆盖浮动元素的问题。但多数人不知道的是BFC是一个独立的渲染区域它内部的元素布局不会影响外部。理解到这个层面答题时就能用自己的话组织出区分度。布局题在2020年的卷子里以“给一个场景用flex实现”为主比如实现上下固定中间自适应的经典后台布局或者垂直水平居中。这类题除了写出display: flex、justify-content: center、align-items: center之外还要注意容器和子项在flex-direction为column时主轴方向的变化。忘了换轴整个布局就是错的。3. 手写代码题这些最常抽到的“功底题”怎么答才不丢分3.1 手写防抖与节流关键在细节笔试的手写题里防抖和节流是出现频率最高的两个。2020年百度的第一批卷子就抽到了防抖。题目一般不会说“要实现一个防抖函数”而是给一个搜索框频繁输入请求接口的场景要求写一个函数避免每次按键都发请求。答案的关键点有三个定时器存储、this绑定、参数透传。一个能拿高分的防抖函数大概是这样的function debounce(fn, delay 500, immediate false) { let timer null; let isInvoked false; return function (...args) { const context this; if (timer) clearTimeout(timer); if (immediate !isInvoked) { fn.apply(context, args); isInvoked true; return; } timer setTimeout(() { fn.apply(context, args); isInvoked false; timer null; }, delay); }; }这里有几个细节很容易被阅卷扣分。第一setTimeout回调里不使用this而是把外层this先保存到context变量这样fn.apply(context, args)才能把事件源正确传进业务函数。第二timer需要先clearTimeout再重新赋值否则连续触发时定时器会累积。第三immediate参数处理的是“第一次立即执行”的需求这在很多业务场景中比单纯延迟更实用。如果只写四行代码完事大概率只会拿到一半分。节流的思路类似但没有防抖考得频繁。常用的实现有“时间戳版”和“定时器版”前者保证首次立即执行后者保证最后一次也能触发。笔试如果让你手写节流建议把两种实现都写出来再解释一遍适用场景差异这会让阅卷人觉得你有完整的设计判断而不仅仅是会背模板。3.2 手写深拷贝边界条件比API记忆更重要深拷贝是另一道高频手写题。2020年百度的卷子也涉及了。很多人的第一反应是JSON.parse(JSON.stringify(obj))但题目如果问你“这个方案有什么缺陷”你得能说出三到四个点undefined、函数、Symbol会被忽略Date会被转成字符串RegExp会变成空对象循环引用会直接报错。真正应试时一个足够好的深拷贝实现至少要处理这些边界情况function deepClone(target, hash new WeakMap()) { if (target null || typeof target ! object) return target; if (target instanceof Date) return new Date(target); if (target instanceof RegExp) return new RegExp(target.source, target.flags); if (hash.has(target)) return hash.get(target); const result Array.isArray(target) ? [] : {}; hash.set(target, result); Object.keys(target).forEach(key { result[key] deepClone(target[key], hash); }); return result; }这里用WeakMap而不是普通对象来存储已经克隆过的引用核心原因是循环引用场景下如果不用一个全局记录表克隆函数就会无限递归。WeakMap的key是弱引用可以防止内存泄漏同时它在语义上也是“对象到对象”的映射很适合这个场景。对于Date和RegExp分别用源值构造新实例保证克隆后的对象不是同一引用。这个版本虽然代码也不多但它体现的是对边界条件的完整思考而不是只会写基础递归。3.3 手写数组扁平化、去重与乱序笔试中的“工具箱题目”这一类的核心考点是ES6方法和使用陷阱。数组扁平化可以从递归出发再进阶到用flat(Infinity)。但阅卷人更希望看到的是“你会用递归处理任意层级”而不是只会调用一个API。所以备考时至少要把递归版本、reduce版本、generator版本各写一遍才算真正掌握了。数组去重最常见的答案是new Set(arr)但题目如果问“对象数组怎么去重”就得扩展成“根据某个key去重”或者“深比较去重”。这在笔试中是以简答形式出现容易被忽略。另外随机打乱数组这道题经常出现在选择题里常见的错误答案是arr.sort(() Math.random() - 0.5)。这个写法虽然能让数组乱序但并不是均匀随机而且在不同浏览器引擎下的表现不一致。正确做法是Fisher-Yates洗牌算法从后往前遍历每轮随机选一个前置索引交换这才是计算复杂度稳定的做法。笔试中能写出Fisher-Yates会让阅卷人对你的算法功底有额外好感。4. 在线编程题从二分到动态规划这些在2020卷子里的真容4.1 编程题的环境与输入输出比算法更容易丢分很多人的认知是在线编程题就是LeetCode原题评测。但实际上校招笔试的在线编程环境往往和LeetCode不一样尤其是输入输出格式。LeetCode是核心代码模式函数签名已经给好了你只要实现函数体而校招笔试有时用的是ACM风格的模式需要自己处理多行输入自己解析字符串。2020年百度用的是牛客/赛码这类平台有的题目是核心代码模式有的需要你readline逐行读数据。如果你不熟悉readline的用法光是读取输入就能耗掉十分钟。我的建议是提前准备一份Node.js下的输入输出模板。核心代码模式就简单一些读入数组、解析字符串这些操作在函数内部完成。还有一个小细节JavaScript的sort默认按字典序排序不是数值排序。如果你在一个返回最大数的题目里直接arr.sort()然后取最后一项很可能会拿到错误答案。这种错误在本地测试一小段数据时看不出来换成大数据量就完全不对。4.2 一道典型题目的完整拆解用最省内存的方式找出一段连续子数组的最大和这类题目在2020年的卷子里出现过原题描述通常围绕“给定一个整数数组找出一个具有最大和的连续子数组至少包含一个元素返回其最大和”。看起来很简单但解法层次非常分明。暴力解法是两重循环枚举所有起点和终点再求和时间复杂度O(n^2)。这个复杂度在数组长度超过1000时就会明显变慢而笔试中的用例常常会放到几万甚至几十万的长度必然会超时。更好的解法是动态规划递推式是dp[i] max(nums[i], dp[i-1] nums[i])代表以第i个元素结尾的连续子数组的最大和。最终答案就是整个dp数组的最大值。空间还可以继续优化。因为dp[i]只和dp[i-1]及nums[i]相关所以不需要开一个和原数组等长的dp数组只需要一个变量存“上一项的最大和”一个变量存“全局最大和”即可。这就是经典的Kadane算法时间复杂度O(n)空间复杂度O(1)。考试时写到这一步哪怕对题目场景的描述不够漂亮判题也是全通过。4.3 边界条件和常见坑位空数组、负整数、溢出上面这道题有三个边界条件非常值得留意数组长度为1、数组全是负数、数组元素值非常大。数组全是负数时暴力解容易出错——很多人会写“当前和小于0则直接重置”但如果数组全为负重置后等于永远取不到任何元素。正确做法是至少保证子数组包含一个元素Kadane算法本身也天然满足这个条件。另一个容易踩的坑是初始化全局最大值时用0当数组全为负数时返回0这明显是错的。应该初始化为-Infinity或者直接取nums[0]。至于溢出JavaScript的Number类型在超出Number.MAX_SAFE_INTEGER时会出现精度丢失。如果题目明确说数值范围很大比如超过2^53用BigInt是更稳的选择。不过校招笔试题一般不会这么极端知道这个注意事项就够了。5. 设计题才见真功夫组件设计和技术方案怎么答出区分度5.1 组件设计题比如让你设计一个可扩展的Modal框2020年百度第一批卷子中有设计题的设置考察形式通常是给出一个业务场景让你设计一个组件的API和状态结构。这类题没有唯一答案但从阅卷角度高分答案一定有完整的设计流程。以Modal为例我的答题顺序是以下四步。第一步列出核心需求显隐控制、标题与内容插槽、底部按钮定制、遮罩层点击关闭、关闭回调。第二步设计propsvisible控制显隐、title传标题、footer传底部内容、width控制宽度、destroyOnClose等。第三步设计事件onClose由父组件监听并负责修改visible这符合单向数据流的React哲学也让组件保持受控。第四步扩展性支持通过children传入任意内容支持footer{null}隐藏底部支持transition配置动画。这里最关键的得分点是你能说出受控组件和非受控组件的区别并且明确这个Modal是受控的还是非受控的。受控组件意味着外部通过visible控制Modal的开合组件内部不维护自己的开合状态非受控的Modal可以通过defaultVisible配合组件内部状态自己关。大多数高质量UI库的Modal都是受控组件因为用户点关闭按钮时你到底是想让它关还是想填一份表单校验再关只有使用者知道。这是设计判断不是API背诵。5.2 技术方案设计题一个前端监控系统的答题框架还有一种设计题不考组件直接抛一个较大场景比如“如何设计一个前端错误监控系统”。这种题看起来虚无缥缈但答题是有框架的按“采集、上报、聚合、告警、分析”五步走基本能拿到三分之二以上的分数。采集侧要覆盖三类错误window.onerror捕获运行时错误和资源加载错误unhandledrejection捕获Promise异常console.error捕获手动记录。资源加载错误有个细节window.onerror的第三个参数target如果落在img或script元素上表示这个资源加载失败需要单独判断。上报侧需要考虑批量合并不一次性发几百条请求而是把多条错误信息攒到一个数组里到达一定数量或一定时间后统一通过navigator.sendBeacon发送。sendBeacon的优点是页面卸载时请求也能送达不会因为页面关闭而丢失。聚合侧是按错误堆栈的指纹信息去重同一个报错在服务端只记录一条并统计出现次数。告警侧的阈值可以根据PV和错误率动态设置。分析侧就是根据sourcemap还原压缩前的代码位置这是前端团队做质量治理非常依赖的能力。这样答出来阅卷人会看到你思考的是完整链路而不是只点了几个孤立的技术名词。笔试中设计题的核心要求不是给出最优解而是展示你拆解问题的方式足够职业化。5.3 性能优化类的设计题首屏渲染提速怎么答另一类高频设计题是“你会怎么优化一个页面的首屏速度”。2020年的卷子里就有类似的开放性问题。我的答题框架是三个维度资源体积、加载链路、渲染路径。资源体积从压缩JavaScript/CSS/图片开始再考虑Tree Shaking、去掉冗余依赖、按需加载。加载链路重点是HTTP缓存、CDN预热、dns-prefetch、preload和prefetch的区别以及HTTP/2多路复用和HTTP/3的QUIC。渲染路径重点是减少首屏需要请求的CSS和JS数量把非关键脚本拆成异步或者延迟加载让首屏HTML能尽快解析出DOM和CSSOM。还有一手叫首屏直出/SSR适合对SEO和首屏时间都非常敏感的场景。答题时最好给出可量化验收方式优化前用Performance面板记录LCP和FCP优化后对比同一指标。能说出“性能优化不是靠感觉靠埋点数据判断收益”这句话已经比80%的候选人有工程意识。6. 考后复盘与备考清单这些非技术分最容易丢6.1 机试环境的坑IDE、输入输出、浏览器不兼容2020年校招的机试环境普遍是牛客或赛码这类平台自带一个Online Editor可以切语言但不能装插件。我自己的体验是自动补全几乎没有Emmet也不生效平时在VSCode里写习惯了的人到这种编辑环境会突然觉得自己不会写代码了。所以备考时最后两周一定要用平台自带的在线编辑器做几次全真模拟哪怕题目简单也要训练手感和读题速度。另外要注意平台对不同浏览器的兼容性。现场笔试前检查浏览器版本尽量避免用旧版浏览器的兼容模式否则代码运行时报错会很耽误时间。还有一点容易被忽略系统允许切到本地IDE调试但前提是你得在本地也搭好相同的输入输出框架否则切来切去反而浪费时间。6.2 时间分配别再为一道多选纠结十分钟笔试最忌讳的是一道题耗时过长。选择题每道尽量控制在一分钟上下如果你在一道多选上卡住先标记出来做完整套再回头。手写代码题每题控制在五到八分钟在线编程题一题十分钟设计题留出十到十五分钟。大厂笔试题量不是让你从容做完全部的时间本身就是筛选条件之一所以“在固定时间内把会做的做对、不会做的果断跳过”也是一种能力。我见过太多考生在选择题和一道偏难的编程题上死磕结果设计题只写了两行。如果你拿到的试卷结构和2020年这批类似设计题的分数权重往往不低于一道编程题放弃它极其不划算。6.3 一个靠谱的备考复习计划结合这份卷子覆盖的考点我建议按知识领域做一个复习表按你自己的薄弱程度调整时间分配知识领域核心考点建议复习时间占比JavaScript语言机制原型链、this、闭包、作用域、事件循环、深拷贝25%浏览器与网络渲染流程、回流重绘、HTTP缓存、HTTPS15%CSS与布局盒模型、BFC、flex/grid、移动端适配10%框架与工程化Vue/React响应式或虚拟DOM原理、Webpack构建流程15%数据结构和算法数组、字符串、栈、队列、二分、动态规划20%设计题与业务场景组件API设计、性能优化方案、监控系统10%在线环境练习牛客/赛码平台全真模拟、输入输出处理5%给三个实操建议第一所有手写题必须用纸笔或者记事本练不要一上来就交给编辑器补全校招笔试不给你补全的机会。第二编程题复习以分类刷题为主按数组、字符串、链表、二分、动态规划、回溯这几类逐类突破而不是随机刷一题换一类。第三设计题不要只看别人的答案逼自己写一份完整方案发给自己看十天后回看能不能看懂、能不能挑出逻辑漏洞如果看不懂说明当初写得太含糊。结语的一点个人体会回过头看2020年百度这批笔试卷比市面上很多所谓“大厂真题集”更有参考价值因为它考的每一道题都不是孤立的面试题而是前端工作日常的抽象提炼。防抖节流对应的是搜索框输入深拷贝对应的是状态管理中的数据传递编程题对应的是接口数据的处理逻辑设计题对应的是真实业务需求。只要你在平时写代码时多问一句“这个语法为什么这样写”“这个方案还有什么边界没处理”面对这套卷子就不会慌。最后分享一个我备考时用的小技巧每道题做完后不管对不对都在旁边写一句话解释自己答题的思路。这个习惯让我在复盘时能快速定位薄弱点。你们也可以试试。