2017前端笔试题剖析:从JavaScript闭包到浏览器原理
2026/9/5 4:31:17 网站建设 项目流程

2017年秋招那会儿,前端岗位的笔试题还没有现在这么“卷算法”,但也不是随便背背八股文就能过。4399作为国内老牌游戏平台,它的前端笔试试卷在当年算是比较典型的“大而全”风格:既有基础语言题,也有浏览器原理,还会塞几道逻辑题和编程题。我印象很深的是,做这套卷子时最大的感受是“好像都见过,但一落笔就犹豫”,这正是考察基本功扎实程度的典型出法。

这套试卷适合两类人参考:一类是准备校招的应届生,想了解2017年前后端分离逐步普及阶段,企业到底在面试者身上找什么;另一类是工作一两年的前端,想回头校验自己有没有把JavaScript、网络协议这些底层概念真正理解透。本文不会泄露真实试题,但会把当年这类试卷常见的出题方向、典型题型和答题思路完整拆一遍,帮你建立一套应对“大而全笔试卷”的方法论。

1. 整体考察方向与命题思路

1.1 2017年前端岗位的时代背景与技能要求

2017年的前端生态,和现在有个很大的区别:Vue 2 刚大规模流行,React 16 才发布不久,Webpack 3 还是主流,HTTP/2 普及率有限,TypeScript 在企业里还没有成为默认选择。这意味着当时的笔试不会考“useMemo过期问题”或“Vue3响应式原理”,而是把重心放在更稳定的语言基础、浏览器机制和编码能力上。

4399这类游戏公司的前端工程师,日常要面对大量运营活动页、官网、游戏预约页、数据后台,这些页面共同的特点是:流量峰值高、兼容性要求苛刻、开发周期短。所以笔试图通过几个方面来筛选人:第一,JavaScript语言功底深不深,因为运营页离不开DOM操作、事件绑定和数据渲染;第二,是否理解浏览器加载与性能优化的基本常识,因为活动页上线后动辄百万级PV,加载慢会直接影响转化率;第三,有没有基本的逻辑拆解能力,因为写活动页经常要处理复杂的交互时序和倒计时逻辑。

理解了这些背景,再去看笔试试卷,就不会觉得题目是零散的,而是有一根线在串:考察你能否成为一个“能直接上手干活、上线后不出大事故”的前端工程师。

1.2 4399笔试试卷的模块设计与考察权重

从我当年参加校招和后来帮学弟学妹改简历、模拟笔试的经验来看,2017年这类游戏公司前端试卷的模块构成大致是:

  • 计算机基础与网络(约20%):TCP三次握手、HTTP状态码、缓存策略、跨域方案,偶尔会有DNS解析过程。
  • HTML/CSS(约20%):语义化标签、盒模型、BFC、浮动清除、居中方案、CSS选择器优先级、兼容性 hack。
  • JavaScript(约30%):变量提升、闭包、原型链、this指向、事件循环、作用域、数组方法、手写防抖节流。
  • 编程题/算法(约20%):手写函数、数组去重、排序、简单递归、字符串处理,难度大概在LeetCode简单到中等之间。
  • 逻辑题与开放题(约10%):比如“10个瓶子9瓶毒药1瓶解药”这类经典题,或者“前端页面加载太慢,你会怎么排查”。

这个权重关系说明:JavaScript是绝对核心,网络和CSS次之,算法仅考察基础编码能力,不追求竞赛级难度。所以备考的重点应该放在JS语言本质和网络原理,而不是盲目刷高难度算法题。

2. 核心知识点拆解与答题要点

2.1 JavaScript:闭包、原型链与异步

先说闭包。笔试中闭包的典型考法是“输出结果”或“写一个防抖函数”。闭包的考点有两个:一是理解函数作用域链的保持机制,二是清楚闭包带来的内存开销。答题时不要只背“函数内访问外部变量”这层皮,要把执行上下文、作用域链、变量对象的关系讲清楚。

原型链同样是重灾区。常见题是画出var a = {}的原型链、判断a.__proto__ === Object.prototype的结果,或者手写一个new。很多人在原型链上栽跟头,是因为没有把constructor__proto__prototype三者区分开。我的建议是画图,把Function.prototypeObject.prototype的关系在纸上画一遍,笔试时就算记不牢也能推导出来。

异步这块,2017年的考点顺序一般是:setTimeoutPromise的输出顺序、事件循环的宏任务与微任务、回调地狱怎么解决。现在大家张口就来async/await,但那时候经常考的是一串setTimeout 0Promise.resolve().then的排列组合。做这类题时记住一条主线:同步代码先执行,清空微任务队列,再取一个宏任务执行,执行完继续清空微任务。按这个规则一步步推,基本不会错。

2.2 浏览器与网络:从输入URL到页面显示

几乎所有公司笔试都会考查“输入URL到页面显示经历了什么”。这道题虽然没有标准答案,但得分点非常明确:DNS解析、TCP连接、HTTP请求、服务器响应、浏览器解析HTML构建DOM树、合并CSS构建CSSOM、执行JS、布局绘制。你答得越有条理,说明你对前端性能优化的理解越深。

2017年还特别爱考浏览器缓存。需要区分强缓存与协商缓存,Cache-ControlExpires的优先级,Last-ModifiedETag的关系。答题时建议画一个简单的决策流程图:先看是否有强缓存命中,命中则直接用;未命中则带上缓存标识请求服务器,由服务器判断返回200还是304。把流程写清楚,比死记字段更有效。

跨域也是必考项。CORS、JSONP、postMessage、document.domain、代理服务器,这些方案要能说出原理、适用场景和缺点。特别注意JSONP只能发GET请求,而且要动态创建script标签再移除,这些细节最容易拿分也最容易丢分。

2.3 HTML/CSS:布局、盒模型与兼容性

布局方面,2017年笔试还没有像现在这样疯狂考Flex和Grid,但一定会考“未知高度垂直居中”和“两栏自适应布局”。大部分人会答flex,但如果能补充position + transformtable-cell等多种方案,并且说明各自的兼容性,就能明显拉开差距。

盒模型要理解content-boxborder-box的区别,以及如何通过box-sizing统一。浮动清除是经典老题,要能写出clearfix的完整写法,并且解释为什么用overflow: hidden能触发BFC。BFC考的是概念,常见的触发条件必须背熟:float不为nonepositionabsolute/fixeddisplayinline-block/table-cell/flexoverflow不为visible

选择器优先级计算题也常出现。记住规则:行内样式 > ID选择器 > 类/属性/伪类 > 元素/伪元素,!important最高。遇到a:hover这种不难,但组合选择器时要逐级数权重,不要凭感觉。

2.4 算法与逻辑题:基础编码与思维考察

4399这类公司的算法题,不会让你啃红黑树,但会考“手写数组去重”“字符串反转”“括号匹配”“斐波那契数列”这类基础题目。关键在于用标准、高效的写法完成,并且能分析时间复杂度。我当年遇到的是“统计一个字符串中每个字符出现的次数”,这题现在看很基础,但在笔试时间紧张时,有人会用for循环嵌套,有人会想到用对象key来计数,也能看出基础差距。

逻辑题虽然分值不高,但往往是压轴题,用来拉开区分度。常见的有“药瓶问题”“过桥问题”“抛硬币概率”等。做逻辑题先不要慌,把条件列成表格,用穷举或反向推理的方式去试。有时候写出思路和假设过程也会给分,千万不要空着。

3. 典型真题回忆与详细解析

3.1 这道作用域与闭包题,90%的人能蒙对但讲不清

我印象很深的一道题是:

for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 100); }

问输出结果是什么。答案当然是输出5个5,但卷子还会追问“如何让它输出0 1 2 3 4”。这一问就筛掉了很多只会背答案的人。

常规解法是用IIFE传参:

for (var i = 0; i < 5; i++) { (function (j) { setTimeout(function () { console.log(j); }, 100); })(i); }

也可以用let声明块级变量,但在2017年部分旧浏览器不兼容,所以笔试时最好两种都写,并解释区别:var没有块级作用域,循环结束后i变成5;let每次迭代都会绑定新的变量;IIFE则是通过函数参数形成独立作用域,保存了每次循环的副本。

这道题背后真正考察的是“闭包捕获的是变量本身还是变量的值”。很多人回答“收藏了i的值”,这个说法不准确。闭包捕获的是变量的引用,当循环结束时所有定时器回调都引用同一个i,所以看到的是最终值。除非你把值作为参数传递,才能把当前值固定下来。

3.2 一道综合布局题:左右固定,中间自适应

这种题在2017年几乎是必考,现在虽然看着“老”,但用来考察CSS功底非常有效。题目一般是这样:左右两个盒子宽度固定200px,中间盒子自适应填满剩余宽度,要求中间盒子优先渲染。

最优方案是用flex布局:

<article class="container"> <section class="center">中间内容</section> <aside class="left">左</aside> <aside class="right">右</aside> </article>
.container { display: flex; } .center { flex: 1; order: -1; } .left, .right { flex: 0 0 200px; }

通过order: -1让中间盒子在HTML里虽然是第一个,但显示顺序正确。除了flex,还要能写出圣杯布局和双飞翼布局方案的要点。圣杯布局利用负margin和相对定位,双飞翼布局在中间盒子里嵌套一层再设置margin,两者都是为了解决中间优先渲染的问题。

答题时不要只贴代码,要写清楚优缺点:flex最简洁,但需要考虑IE9及以下兼容性;圣杯布局的负margin容易让初学者懵;双飞翼布局更直观但多了一层DOM。能说出这些,面试官会认为你真的用过,而不是背下来的。

3.3 手写“Promise串行执行”

这道题在当时算是进阶考点,现在已经成了基础。题目一般会给一个返回Promise的函数数组,要求串行执行并保留结果。

解法有很多种,最简单的用Array.prototype.reduce

function runPromiseInSequence(array, value) { return array.reduce( (promiseChain, currentFunction) => promiseChain.then(currentFunction), Promise.resolve(value) ); }

也可以写递归版本:

function runPromiseInSequence(array, value) { if (array.length === 0) return Promise.resolve(value); return array[0](value).then((res) => runPromiseInSequence(array.slice(1), res) ); }

这道题的考点不只是“能不能写出代码”,还考察你是否理解Promise的链式调用和异步控制流。很多人会下意识用for循环加await,但当时的考纲可能不允许用async/await(ES2017刚发布,部分环境不满足)。所以笔试试卷更希望你用手写then的方式控制异步顺序。如果时间允许,把reduce原理展开讲一遍,会让面试官印象更深。

4. 笔试中的常见失分点与实战技巧

4.1 时间分配与做题顺序

2017年这套试卷的做题时间一般是90分钟到120分钟,题量约30到40道。很多人失败在时间分配上:在前面的选择题里反复纠结,导致后面编程题没时间写。

我建议拿到卷子先花2分钟浏览全卷,标注出“会做但不确定”的题。做题顺序按“先熟后生”:先把有把握的填空、选择、简答做掉,保证基础分拿到;再做中等难度的代码题;最后留至少30分钟给两到三道编程题和逻辑题。编程题哪怕只写出核心思路,也要把思路写在旁边,阅卷人通常会看你的解题方向,整个空白和写出伪码得分完全不同。

4.2 易错概念盘点

有些概念看起来简单,但每次命中率都奇高。

第一,=====的比较规则。null == undefined是true,NaN == NaN是false,0 == false是true。这些要牢牢记住,答题时最好写出“建议用严格等于”的结论。

第二,typeof null返回objecttypeof function(){}返回function。这种坑题经常夹在选择题里。

第三,[] == false的结果是true,因为数组会先转成字符串"",再转成数字0。这种隐式转换题需要理清规则:对象转原始值会调用valueOftoString

第四,CSS中margin合并问题。垂直方向上相邻兄弟元素的margin会合并,取较大值。父元素和第一个子元素的margin也会合并,除非父元素触发BFC或设置padding/border。很多人在这类题上被绕晕,关键是要记住“margin合并只发生在垂直方向,并且只有块级元素”。

把易错点整理成一张表,考前快速过一遍,比无效刷题更有用。

4.3 简答题怎么答才容易拿高分

简答题最忌只写一句结论。比如问“什么是BFC”,如果只写“块级格式化上下文”,等于没写。高分答法应该包含三部分:定义、触发条件、应用场景。

以“什么是跨域”为例,你可以这样写:

跨域是浏览器的一种安全限制,指协议、域名、端口任一不同时,浏览器会阻止Ajax请求读取响应。常见的解决方式有CORS(服务端设置Access-Control-Allow-Origin)、JSONP(利用script标签不受同源限制)、正向代理(开发环境通过Proxy把请求转发到目标地址)。实际项目中,我们团队用Vue开发时会配置webpack-dev-server的proxy,生产环境由Nginx配置转发,尽量避免在前端写死跨域请求。

这样一段话不仅回答了定义,还体现了工程经验。阅卷人很容易从简答题看出应试者是真做过项目,还是只背了概念。所以简答题要当作“小论文”来答,尽量带上业务场景、选型理由和踩过的坑。

5. 从笔试到面试:这些知识点还会怎么追问

笔试结束只是第一步,很多题目会在面试中被二次深挖。比如笔试里考了“点击按钮延迟3秒输出当前索引”,面试就会追问“如果用闭包解决了,那么闭包会不会造成内存泄漏,怎么避免”;笔试里考了“两栏布局”,面试就会让你现场打开编辑器,换个需求做三栏瀑布流。

我建议在复盘试卷时,对每道错题都做三层延伸:第一层,正确答案是什么;第二层,为什么我之前会错;第三层,面试官如果抓住这个知识点,还能问出哪些变体。比如bind得掌握和callapply的区别,还要能手写一个bind。再比如事件循环,要能解释requestAnimationFramesetTimeout在不同场景下的优先级差异。

另外,笔试中涉及的算法题,虽然难度不大,但也要会分析时空复杂度。面试官可能不问“你怎么实现去重”,而问“你的算法时间复杂度是多少,有没有优化方案”。这时候如果你能说出用Set是O(n),而用filter + indexOf是O(n²),会显得很有深度。

最后一点建议:做笔试复盘时,不要只收集题目和答案,而要把每道题对应的知识点写进自己的知识图谱里。2017年的前端笔试和现在相比,只是技术栈变了,面试官考察的内核没变:你是否真的理解了语言的运行机制,遇到问题是否有清晰的排查思路,写代码时有没有良好的工程意识。这套方法放在今天,依然能帮你顺利通过大部分公司的前端笔试。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询