网易2020校招提前批的前端笔试,算是我当年刷过的校招笔试题里非常有代表性的一场。题型覆盖了计算机基础、JavaScript深挖、CSS布局、浏览器原理,再加两道算法编程题,整体难度在互联网大厂里属于中上。很多人看到"前端"两个字,以为笔试考的都是页面切图、框架API背诵,实际做下来你会发现,网易这种体量的公司,前端笔试的核心是在筛两端:一端是你作为程序员的基本功,另一端是你对前端这个行业的理解深度。用大白话说,就是"能不能把代码写干净、把原理讲清楚、把问题想明白"。
这篇文章不打算去回忆所谓的"原题",那没有意义。我以这次提前批笔试题型为蓝本,聊聊前端校招笔试背后的考察逻辑、高频考点的拆解方式、现场答题的时间分配,以及我自己踩过的坑。不管你是正在准备校招,还是工作几年打算跳槽,这套分析思路基本通用。前端开发面试题年年翻新,但底层的能力模型就那几块,吃透比海量刷题更重要。
1. 笔试整体情况与考核逻辑拆解
1.1 网易提前批笔试到底考什么
先还原一下整体试卷结构。我参加的那场笔试大概分三块:
- 客观题:单选题和不定项选择混合,覆盖计算机网络、数据结构、操作系统基础、JavaScript特性、CSS布局,大概20多道。
- 填空与简答题:这部分不是纯背诵,而是给你一段代码让写输出结果,或者让你手写一个CSS布局方案,再或者让你解释浏览器缓存过程。
- 编程题:两道算法题,一道偏字符串处理,一道偏数组或动态规划,需要在限定时间内通过全部测试用例。
很多人只重视最后的算法题,但我觉得客观题和简答题才是拉开差距的地方。算法题大家刷了LeetCode都能写个大概,但JavaScript细节题很能反映你是不是真的写过代码,还是只是背了面试题。网易的客观题里有一类"输出是什么"的题目,我印象极其深刻,比如事件循环里setTimeout、Promise、async/await的执行顺序,比如this指向在严格模式下的表现,比如闭包中循环变量捕获问题。这类题没有任何商量余地,你理解不深就是会错。
另外值得注意的一点,笔试中出现了不少关于HTTP和浏览器缓存的内容。前端开发做到后面,性能优化是绕不开的坎,而缓存策略是性能优化的地基。网易作为内容型产品为主的公司,页面加载速度和资源命中率直接影响业务指标,所以笔试考这些非常正常。
1.2 为什么笔试要这么设计
我后来跟网易的朋友聊过校招筛选流程,他的一句话点醒了我:校招没有实际项目可以查,笔试是唯一一个能快速、低成本验证候选人基础能力的手段。
大厂校招投递量是上万级的,简历筛选过后依然有几千人进入笔试。如果用纯面试,一天面不了几个人。笔试天然是自动化的筛选器,它筛的不是谁最聪明,而是谁最"稳"。这里的"稳"体现在三方面:
第一,算法能力稳定。不是说你要能写出红黑树,而是能看出来你是不是有清晰的逻辑思维。一个能把二叉树的层次遍历写利索的人,大概率能把复杂业务拆解成小模块。
第二,基础细节扎实。前端技术栈更新非常快,今天Vue、明天React、后天可能又出来一个新框架。笔试只能考相对稳定的底层知识,也就是JavaScript语言特性、CSS核心机制、浏览器工作原理。这些东西十年内不会有根本变化,你掌握得越深,说明你的学习能力越强,而不是只会跟着教程复制代码。
第三,时间分配和抗压能力。笔试时间有限,题量不小,这本身就模拟了工作环境中的deadline。有些人算法题抠太久,导致后面的简答题没时间写;有些人看到一道不会的题心态就崩了,后面全乱套。这种心理素质在笔试里也能被观察出来。
所以,与其抱怨大厂笔试八股文,不如想清楚:它就是在用最低成本找出"基础扎实、逻辑清晰、心态稳定"的候选人。明确了这个逻辑,备考方向就不会跑偏。
2. 核心考点与高频题型解析
2.1 数据结构与算法:笔试的硬骨头
网易前端笔试的算法题,基本锁定在数组、字符串、链表、二叉树、简单动态规划这几类。它不考竞赛级别的难题,但会刻意考察边界条件的处理、时间复杂度的意识,以及代码风格是否整洁。
我当时遇到的一道题,大意是给一个只包含小写字母的字符串,要求找出其中最长无重复字符的子串长度。这个题就是非常经典的滑动窗口,LeetCode原题。但很多人栽在细节上:窗口left指针的更新逻辑写错了,或者没有考虑字符串为空的边界情况。
再比如数组类题目,经常考"排序+去重"、"合并两个有序数组"、"两数之和"这类变形。它们本身不难,难的是你能不能写出O(n)或O(n log n)的方案,而不是三重循环暴力解。笔试判题系统对执行时间是有要求的,暴力解在数据量小的时候能过,一旦测试用例上了规模就直接超时。
我的建议是,刷题别贪多,但每道题至少要会三种角度:暴力解、优化解、最优解。暴力解有什么用?它帮你确认思路,也保证你至少能交一个不超时的版本。优化解是日常工作中最常用的,因为真实项目的代码要兼顾可读性。最优解则是笔试拉分的关键,能体现你对数据结构的理解深度。
2.2 JavaScript和CSS基础:细节决定成败
这部分是整个笔试里最"前端"的部分,也是我建议所有备考者重点复习的模块。JavaScript相关的考点可以整理成一张清单:
- 作用域与闭包,包括循环中var和let的差异
- 原型链与继承,class语法糖背后的原理
- this指向的四条规则,以及箭头函数和普通函数的区别
- 事件循环机制,宏任务和微任务的执行顺序
- 展开运算符和rest参数,也就是前几年很流行的
...arg这类题 - Promise的原理,手写实现一个简易版
这几个点几乎是我面过的所有大厂的必考题。网易笔试特别喜欢用"代码输出题"来考察这些知识点。比如给你一段代码:
for (var i = 0; i < 5; i++) { setTimeout(() => console.log(console.log(i)), 1000) }问你输出什么。如果你不清楚var声明的变量是函数级作用域,循环结束后i已经变成了5,这里就会答错。如果改成let声明,每个迭代块会生成独立的词法环境,输出0到4。这个考点现在依然是前端开发面试题里的常客。
CSS部分则集中在:盒模型的计算方式、BFC是什么以及怎么触发、flex布局的常用属性、position的定位规则、CSS选择器优先级。还有一个高频考点是"让一个元素水平垂直居中你有几种写法",这题看似简单,但每种写法的适用场景和浏览器兼容性都不一样,能写全的人其实不多。
浏览器基础同样重要。浏览器从输入URL到页面渲染完成发生了什么,这个经典问题几乎百分百会考。它考察的是你对网络请求、DNS解析、TCP连接、渲染管线、JavaScript执行阻塞等一整条链路是否清晰。我当时在笔试中遇到了浏览器缓存相关题目,问强缓存和协商缓存的状态码和header字段,这个如果不实际操作过,光靠背是真的容易混淆。
2.3 框架与工程化常识:Vue规范和相关概念
网易前端岗位当时以Vue技术栈为主,所以笔试和后续面试都会涉及Vue。笔试里框架题不会太深,但会考响应式原理的基本理解、组件通信方式、生命周期顺序等。更深的问题,比如"Vue3的Proxy相比Vue2的Object.defineProperty解决了什么问题"这类,笔试偶尔出现,面试基本必问。
工程化方面,前端开发规范在笔试中也开始出现。比如ESLint在团队协作中解决什么问题、prettier和ESLint的区别、模块化规范CommonJS和ESM的差异。这类题目考察的是你有没有真正参与过团队项目,而不是一个人写Demo。我后来在项目里搭建前端开发规范时,会把代码格式化、命名规范、提交检查这些流程固化到CI里,这些经验其实都源于当时笔试带给我的启发。
顺带一提,我在备考期间接触到hzero这类企业级中后台前端框架,它本质上是把大量通用逻辑抽象成一套完整的解决方案。网易这类公司内部也会有类似的自研框架,笔试不会直白地考框架代码,但会通过编程题考察你能否在已有约束下写出清晰、可维护的代码。这和"前端开发skills"最终沉淀为"在复杂工程里写代码的能力"是一个道理。
3. 编程题实战:从读题到AC的完整流程
3.1 拿到题目先做三件事
笔试现场时间紧张,很多人一上来就噼里啪啦写代码,这是最大的忌讳。我总结了一个固定节奏,每次笔试都照着执行:
第一步,读清输入输出格式。有些题目给的输入是数组字符串混合,有些是标准输入多行文本。先确认边界条件,比如输入可能为空、数组元素可能重复、字符串可能包含空格。这些细节往往是判题用例里的隐藏陷阱。
第二步,估算数据规模。题目通常会给出n的范围,比如n <= 10^5。如果是O(n^2)的算法,在这个规模下就是10^10次操作,必然超时。这时候你要立刻锁定目标复杂度,滑动窗口、双指针、哈希表、前缀和、二分这些常见套路往脑海里过一遍,找到匹配的那一个。
第三步,先写测试用例再写代码。很多人不习惯这个习惯,但在笔试中特别有用。先从题目里给的示例入手,手推一遍结果,再补一个边界用例,比如空数组、数组长度为一、全部相同字符。这能帮你提前发现代码里的边界处理漏洞。
这三步大概花5分钟,但能省掉后面改代码的时间。我的经验是,能在45分钟内AC两道编程题的人,基本都用了类似的方法论,而不是靠手速硬写。
3.2 一道典型编程题的完整拆解
我这里拿"最长无重复字符子串"举个例子,说说我是怎么在笔试现场一步步做的。题目给定一个字符串,例如abcabcbb,要求返回最长不含重复字符的子串长度,答案是3,对应abc或bca或cab。
思路是滑动窗口。用两个指针left和right维护窗口边界,用一个Set或者哈希表记录窗口内的字符。right每次向右移动一格,如果遇到重复字符,就把left不断右移,直到窗口内没有重复字符为止。每次移动都更新最大长度。
function lengthOfLongestSubstring(s) { const n = s.length let left = 0 let max = 0 const set = new Set() for (let right = 0; right < n; right++) { while (set.has(s[right])) { set.delete(s[left]) left++ } set.add(s[right]) max = Math.max(max, right - left + 1) } return max }我笔试现场写的和这个基本一致。为什么用Set而不是Map?因为题目只要求去重,不需要记录每个字符的最新位置,Set更简洁。当然用Map记录索引可以进一步优化,让left直接跳到重复字符的下一个位置,复杂度能从近似O(2n)降到严格O(n)。但笔试里的输入规模,Set版本已经足够。
这个例子想说明的核心是,笔试算法题不要求你写出最完美的代码,而是要求你在有限时间内,用最稳妥的思路拿满分。宁可写一个逻辑清晰的O(n)版本,也不要尝试一个自己都不太能讲清楚的优化版本。
3.3 手写代码的边界条件和测试用例
边界条件是我笔试菜鸟期最常翻车的地方。我见过太多人,主逻辑写对了,但有几个边角用例没过,导致整道题AC不了。网易的判题系统是不会告诉你哪个用例挂了的,你只能自己找。
常见的边界情况包括:
- 输入为空或长度为0
- 输入只有一个元素
- 所有元素相同
- 所有元素都不相同
- 数组有负数
- 字符串包含大小写混合或特殊字符
还是用上面的滑动窗口题目举例。当输入为空字符串时,循环不会进入,返回0,正确。当输入为bbbb时,left会不断右移,Set里的元素始终只有b,max始终是1,正确。当输入为au时,两个字符不重复,max更新为2,正确。
我通常会在写完代码后,用这四五类用例在脑海里跑一遍,确认无误再提交。这看似浪费两分钟,实际上能显著提高一次通过率。笔试系统往往有"重新提交"的限制次数,有些公司甚至不看第二次提交的成绩,所以一次通过非常重要。
4. 高频失分点与避坑指南
4.1 客观题里最容易踩的坑
我把网易和另外几家公司笔试中反复出现的"坑"整理成了一张表,每一类都是血泪教训换来的。
| 坑的类型 | 具体场景 | 避坑思路 |
|---|---|---|
| 事件循环顺序 | 混用setTimeout、Promise、async/await,问打印顺序 | 记住微任务先于宏任务,async函数内部await之后的代码是微任务 |
| this指向 | 对象方法里嵌套函数,普通函数this指向window/undefined | 箭头函数不绑定自身this,普通函数调用时this取决于调用位置 |
| 闭包循环变量 | for(var i...)配合setTimeout | var是函数级作用域,改用let或IIFE |
| CSS优先级 | 内联样式、ID、类、标签混用时谁生效 | 内联 > ID > 类 > 标签,!important除外 |
| 类型转换 | 字符串与数字相加、==隐式转换 | 记住+在字符串存在时优先拼接 |
| 原型链 | instanceof判断结果 | 顺着prototype链往上找,构造函数的prototype需要出现在实例的原型链上 |
这里举一个我印象很深的题目。问下面代码输出什么:
console.log([] == ![])大多数人第一反应是"空数组不等于非空数组",选false。实际上,![]先把空数组转成布尔值再取反,得到false。然后[] == false,两边都转成数字比较,空数组转数字是0,false转数字也是0,所以最终结果是true。这道题考察的是JavaScript隐式类型转换的完整链路,任何一个环节没想清楚就会错。
4.2 编程题提交后才发现的问题
笔试现场最痛苦的不是题目不会做,而是提交之后发现因为一个低级错误没通过。根据我自己的经历和周围同学的反馈,编程题最常见的翻车原因有这么几个:
第一,输出格式不对。题目要求输出结果一行一个,你多打了个空格或者把调试用的console.log留在里面,直接判错。有些公司用的是严格比对,多一个空格都是错。所以在提交前,把代码里所有log和临时打印清除。
第二,全局变量污染。如果你在函数外面声明了变量,多个测试用例共享同一个全局变量,第二个用例进来时变量没有被重置,结果就会莫名其妙地错。笔试系统通常对每个测试用例调用一次你的函数,如果你有全局状态,必须记得重置。
第三,数组越界和内存溢出。JavaScript语言本身没这么明显,但如果你用递归解深度很大的树形问题,可能在浏览器环境下直接爆栈。笔试前我专门练过把递归改写成迭代,这个功夫在遇到大数据的树题时非常有用。
第四,排序函数默认行为。JavaScript的sort()不传参数时是按字符串Unicode码排序的,不是按数字大小排序。[1, 2, 10].sort()的结果是[1, 10, 2]。这个坑在真实的业务代码里也经常遇到,笔试现场更是高频失分点。正确的写法是sort((a, b) => a - b)。
4.3 时间分配策略:别让一道题毁掉整张试卷
笔试是有严格时间限制的,我记得网易这场是120分钟。我的策略是:客观题和简答题控制在60分钟内完成,剩下60分钟给两道编程题。第一道编程题30分钟,第二道30分钟。如果第一道20分钟还毫无思路,我会先写一个能过部分用例的暴力解,拿部分分数,然后转向第二道。
这里有个心理层面的问题很多人忽视:一道题卡住时,人会不自觉地想继续死磕,因为"就差一点了"。但笔试不是拼单题满分,而是拼总分。一道题拿到50%的分数,好过空着。而且当你回头再看那道题时,大脑在后台可能会跳出新思路,这种情况我遇到过不止一次。
如果你客观题做太快,比如30分钟就做完,你也别急着交卷。把拿不准的题再逐个验证一遍,尤其是那些"代码输出"题,可以用"代入法"手写JS引擎的执行过程,把作用域链和事件循环的每一步理清楚。这类题真的就是说错就错,但认真推一遍往往能救回来两三分。
5. 备考路线的实际操作建议
5.1 三个月备考时间怎么安排
以我当时为例,我给自己排了三轮复习节奏。第一轮是打基础,大概用一个月。这段时间不刷题,只做两件事:把JavaScript高级程序设计这本书的关键章节重读一遍,理解闭包、原型、异步机制;把CSS的flex和grid系统学一遍,搞清楚BFC、层叠上下文这些概念。很多人觉得基础不考,其实前端开发就是一个基础决定上限的领域,这部分扎实了对后面所有环节都有帮助。
第二轮是刷题期,也是第二个月。我刷的题量不算多,大概每天3道,但每道题都会写清楚解题思路、复杂度分析和边界用例整理。我不推荐一天刷十几道然后过几天忘光,那样效率太低了。我更建议用"按专题刷"的方式,比如这周只刷滑动窗口,下周只刷二叉树。这样你的大脑会对同一类题的套路形成肌肉记忆。
第三轮是模拟期,最后一个月。我没有直接上牛客网做模拟,而是按照笔试的时间要求,每周至少完整模拟两次。手机开飞行模式,电脑只开一个写代码的窗口和题目页面,严格计时,中途不暂停。模拟结束后,我一定会做复盘,把错题分类,统计自己在哪些考点上错得最多,然后有针对地补。
5.2 好用的工具和资料清单
软件和网站方面,我用过这几个,真实体验如下:
- LeetCode或类似的在线判题平台,用来刷算法题,重点标签是"字符串""数组""哈希表""滑动窗口"。
- 牛客网的历年校招笔试真题,可以感受大厂笔试的题型和难度分布,这个不是让你背答案,而是用来练节奏。
- Caniuse,查CSS和JavaScript特性的浏览器兼容性,虽然笔试不直接考,但简答题里提到"这个属性在某个浏览器不兼容"会显得很专业。
- 浏览器DevTools,尤其是Sources和Network面板,用来亲手验证缓存、事件循环和渲染相关的现象。
阅读方面,JavaScript基础部分我推荐《JavaScript高级程序设计》,虽然厚,但值得。CSS部分推荐MDN上的布局章节,比任何书都新。框架部分不用急着啃源码,先把Vue官方文档里"深入理解响应式原理"和"渲染函数"两节读透就够了。如果你想进阶,再去看Vue3的源码解析文章。
一个值得提的方向是前端AI开发。这几年AI辅助编程工具越来越多,我在备考后期也用AI来出题和讲解思路,效率确实高。但我还是建议,AI可以当老师和陪练,不能当替考。校招笔试考察的是你的基本功,这个基本功只能通过自己一行行写代码来打磨,AI给不了你这种肌肉记忆。
5.3 笔试之后的复盘习惯
笔试结束不代表事情结束了。无论你过没过,我都强烈建议做一次完整的复盘。我的复盘分三步:第一步,把考场上没做出来的题目记录下来,尝试在正常状态下重新完成;第二步,把客观题里所有的错题对应的知识点,写进一个错题本;第三步,反思时间分配和心态控制,比如"我是不是在第二道编程题上浪费了太多时间"。
这一步看起来不起眼,但实际上它才是效率提升最大的环节。我后来能连续通过多家公司的笔试,就是因为每一场笔试都在修正自己前面一场的问题。前端开发skills不是天生的,是一轮轮复习和复盘堆出来的。网易提前批笔试那一次,我客观题错了三道,编程题只拿了一道半,整体不算突出,但我认真复盘了两个小时,之后一周内做的每一场模拟都有了质的提升。后来想想,那才是这次笔试给我最大的收获。