ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

360前端客观题复盘:JavaScript与浏览器核心考点解析

360前端客观题复盘:JavaScript与浏览器核心考点解析 终于有人把这份题拿出来聊了。我2018年春招的时候也做过360这套Web前端开发工程师的客观题当时做完感觉“选择题而已不至于太难”考完对答案才发现真正拉差距的根本不是会不会而是对一些基础细节有没有形成条件反射式的准确判断。那会儿Vue 2.5刚火起来、React 16刚出Fiber、Webpack 4还在beta跟现在的前端生态比很多东西已经变了但一套高质量的客观题之所以值得反复看是因为它考的不是“最新API背没背”而是“底层原理有没有搞透”。哪怕放到现在这套题里涉及的JavaScript核心机制、浏览器渲染、网络协议、安全策略依然是前端面试绕不开的硬底子。我先把结论放在前面这套客观题合集对准备校招、跳槽、甚至是刚入行想自检基础的前端开发都有很强的复盘点价值。它覆盖的知识面非常宽但考得并不浅很多题表面在问“选哪个”实际上是在问“为什么”。这篇文章我就按自己做题时的复盘逻辑把当时的考点拆开揉碎讲一遍也顺手聊一聊哪些题目放在今天依然有效哪些已经需要结合新特性重新理解。1. 为什么值得回头啃一套2018年的老题1.1 那个年代的前端生态坐标先做个时间定位。2018年初的前端ES6已经全面普及但ES Modules在浏览器端的原生支持还不算好TypeScript还没有成为大厂的默认选项Vue和React两大框架进入白热化竞争阶段Angular在国内的声量已经明显下滑。构建工具方面Webpack 3是主流Webpack 4刚出很多团队还在踩跨域、热更新、tree-shaking的坑。小程序刚亮相不久前端岗位的招聘要求里开始出现“有小程序开发经验优先”。这个时间节点意味着什么它意味着当时的笔试客观题既不会考太新的东西也不会停留在最老的前端写法上。jQuery还有一些题但已经不多了ES6的let/const、解构赋值、Promise、箭头函数一定是重头CSS3动画和flex布局也是必不可少。整体命题思路可以概括为“在经典知识基础上考查候选人有没有跟上时代更新的能力”。放到今天回头看这些题里的“时代背景”已经淡化了但底层的语言机制、浏览器原理、网络协议并没有过时。比如事件循环、原型链、闭包、HTTP缓存这些在2025年的面试题里依然反复出现。所以啃老题的价值不是押题而是通过这些经典的考查维度搭建一套完整的前端知识框架。1.2 客观题不等于送分题很多同学一看“客观题”三个字就觉得是考察记忆力的背一背就过了。实际上大厂的笔试客观题恰恰是最能筛选出“有没有真正写过代码”的题型。我举个典型的例子一道关于Array.prototype.sort的题目如果你只是背过“sort会改变原数组”那考场上遇到“[10, 9, 8].sort()的结果是什么”很容易想当然地选[8, 9, 10]。但正确答案是[10, 8, 9]因为默认排序顺序是把元素转为字符串后按Unicode码点排序的。这种题目写过代码的人不一定会特别注意但至少不会毫无防备而完全靠做题背答案的人基本一道题就暴露了。360这套题的设计逻辑我认为就是沿着这种思路走的。它不太会问你“Vue的生命周期有哪些”这种纯背诵题而是会换一个场景比如“在created里修改数据视图会不会更新”、“父子组件的mounted执行顺序”这种需要在真实开发中观察过的细节。这类题的区分度极高懂就是懂不懂就是只能蒙。所以我建议大家刷这类题的时候不要只盯着正确率而是把每道题都当成一个引子选对了能不能给旁边的人讲清楚为什么选错了是知识盲区还是理解偏差把每道题的问题都问到底才是做真题的正确姿势。2. JavaScript客观题原型链、闭包与异步时序的核心战场2.1 原型链看似基础实则最容易出错JavaScript的客观题里原型链是绝对的高频考点。那会儿的题一般不会直接让你默写原型链的图而是会通过某段代码的执行结果来考查。比如function Person() {} Person.prototype.say function() { return hello; }; var p new Person(); console.log(p.say()); console.log(p.constructor Person); console.log(p instanceof Person);这道题的三个输出分别是什么hello、true、true看起来很简单。但360这种级别的笔试很可能把问题再变一下问p.hasOwnProperty(say)的值。如果对hasOwnProperty和原型链查找机制理解不透很容易把“p能调用say方法”和“p拥有say属性”混为一谈。前者的答案还需要多读几遍因为[10, 9, 8].sort()这个例子因为默认字典序排序结果是[10, 8, 9]但很多人心里预期是[8, 9, 10]这跟sort的默认行为有关。还有一个高频陷阱点构造函数显式返回对象的情况。function Foo() { this.name foo; return { name: bar }; } var f new Foo(); console.log(f.name);这题的结果是bar。原理是构造函数如果显式返回一个对象那么new出来的实例会被这个对象覆盖只有当返回值是原始类型时才会被忽略并返回this。很多人在项目里几乎没有写过“构造函数返回对象”这种写法所以遇到这种题就懵了。但它考的是对new操作符执行过程的完整理解——创建一个新对象、把原型关联到构造函数的prototype、执行构造函数内部逻辑、根据返回类型决定最终结果任何一个环节不理解都可能选错。2.2 闭包从经典循环坑到垃圾回收的变体闭包的客观题360肯定不会缺席。经典的循环题大概是这样的for (var i 0; i 3; i) { setTimeout(function() { console.log(i); }, 0); }输出是3 3 3而不是0 1 2这个相信现在很多同学已经烂熟于心了。但笔试的难度在于它可能会换一个变体for (var i 0; i 3; i) { (function(j) { setTimeout(function() { console.log(j); }, 0); })(i); }这样输出就是0 1 2原因是用了IIFE把每次循环的i值传入了新函数作用域。更进阶一点的考法是把var换成letfor (let i 0; i 3; i) { setTimeout(function() { console.log(i); }, 0); }输出是0 1 2。let在每次循环迭代中都会创建一个新的绑定这跟var的“函数作用域只有一个变量”有本质区别。这道题哪怕放在现在也是经典中的经典因为它考的不仅是语法差异更是对作用域机制的理解。笔试里闭包还常和垃圾回收挂钩。比如问“返回一个引用了外部数组的闭包函数外部数组什么时候被回收”。答案是只要闭包函数还被引用它引用的外部变量就不会被回收。这个知识点如果在真实项目里优化性能时没踩过内存泄漏的坑光靠背概念很容易在变体题上翻车。我记得当时有一道题给了一段返回函数的代码然后问“改变外部变量后再调用闭包函数输出是什么”——考的就是闭包保存的是变量的引用而不是值。这比直接问“闭包是什么”要高明得多。2.3 事件循环与异步顺序区分度的分水岭如果说原型链和闭包是基础分那么事件循环相关的题目就是拉开差距的地方。2018年的时候Promise已经普及但async/await还没那么泛滥所以题目更喜欢考Promise和setTimeout的组合。一个经典的输出顺序题console.log(A); setTimeout(function() { console.log(B); }, 0); Promise.resolve().then(function() { console.log(C); }); console.log(D);正确顺序是A D C B。原理是同步代码先执行完然后微任务队列Promise的then回调优先于宏任务队列setTimeout回调执行。这道题放在今天依然适用但现在的考题可能会加入async/await比如async function test() { console.log(1); await console.log(2); console.log(3); } test(); console.log(4);输出是1 2 4 3。原因是await后面的代码会被包装成微任务执行所以console.log(3)会在同步代码全部执行完之后才执行。这里有个容易混淆的点await console.log(2)中的console.log(2)是同步执行的await的等待行为只影响后续代码。我当时做这类题的经验是先脑子里面跑一遍“同步代码 → 微任务 → 宏任务”的流水线再一道一道对答案。不用急着看解析自己能把顺序推出来才算真正掌握了事件循环的调度逻辑。3. 浏览器与网络基础缓存、渲染与安全一个都不能少3.1 HTTP缓存一次请求中间的判断链路浏览器相关的客观题里HTTP缓存的高频程度超出很多人想象。360的题里也出现了因为它直接关系到Web性能优化。缓存的关键在于对几个头字段的理解Cache-Control、Expires、ETag、Last-Modified。我建议大家把这几个字段按“请求前”和“请求后”两个阶段拆开理解请求前强缓存阶段浏览器先检查Cache-Control里的max-age如果资源没过期直接用本地缓存不发请求。Expires是HTTP/1.0时代的字段指定的是一个绝对时间容易被本地时间干扰所以现代应用基本都用Cache-Control的相对时间。请求后协商缓存阶段如果强缓存失效了浏览器会带上If-None-Match对应服务端的ETag和If-Modified-Since对应服务端的Last-Modified去问服务器资源有没有变。服务端返回304表示没变浏览器可以继续用本地缓存返回200的话说明资源变了直接替换。笔试题目喜欢考查的点是ETag和Last-Modified的优先级、no-cache和no-store的区别、304状态码的含义。这里最容易被绕晕的是no-cache。它的意思并不是“不缓存”而是“使用缓存前必须先和服务端确认”也就是强制走协商缓存而no-store才是真正的不允许缓存。如果把它们比作生活中的场景max-age3600就像是“这一小时内我直接用手头的信息不用再打电话问你”no-cache则是“每次我都要打电话问你一句‘之前那个信息还能用吗’你说能用我才用”no-store是“你给我的信息我转头就扔下次再要就重新给我发一份。”3.2 渲染过程从输入URL到页面呈现的关键环节渲染原理也是前端笔试必考的经典。题目可能问“在浏览器地址栏输入URL并回车中间发生了什么”这种题其实在客观题里通常会被拆成若干个选择题比如“HTML解析过程中遇到script标签会怎样”、“重排和重绘的区别是什么”。这里有个很重要的知识点JavaScript的下载和执行会阻塞HTML解析。所以一个不讲性能的页面如果把一个大型script标签放在head里那么页面白屏时间会被明显拉长。这也是为什么业界一直强调“把脚本放在body底部”或者使用defer/async属性。那年的题目大概率会问这两者的区别defer脚本会并行下载但会等待HTML解析完成后再按顺序执行。async脚本也是并行下载但下载完就立即执行不保证执行顺序。进一步深挖浏览器解析HTML时遇到link relstylesheetCSS不会阻塞DOM解析但会阻塞渲染因为渲染需要CSSOM和DOM合并成渲染树。这部分很多客观题会结合“CSS放在头部、JS放在尾部”的最佳实践来出题考查你能否把实践和原理对应起来。渲染过程中的重排和重绘也是高频考点。重排reflow是当DOM的几何属性发生变化时浏览器需要重新计算元素的尺寸和位置重绘repaint是样式变化不影响布局时浏览器只需要重新绘制元素。直观来说修改width、height、margin、display都会触发重排修改color、background-color、visibility则只触发重绘。而transform为什么常被用来做动画因为它可以触发GPU合成不一定会引起重排和重绘。这个知识点在当时的性能优化题里是得分点今天也依然是前端优化的基本素养。3.3 XSS与CSRF安全题里最常见的两类基础功360本身就是安全公司笔试里考Web安全可以说是“主场作战”所以这部分题目一般不会太浅。最常见的两道题是跨站脚本攻击和跨站请求伪造虽然名字容易混淆但攻击思路完全不同。XSS的核心问题是“用户输入的内容被当成代码执行了”。比如一个评论区用户输入了scriptalert(xss)/script如果前端直接把这段内容插入到页面里脚本就会执行。防御手段主要有三种对输入做过滤、对输出做编码、使用CSP策略限制脚本来源。客观题里还会考一个点textContent和innerHTML的区别前者安全后者如果插入用户内容就会触发XSS。CSRF的核心思路是“借用用户的登录凭证发起恶意请求”。比如你在A网站是登录状态攻击者在B网站放了一个自动提交的表单请求A网站的转账接口浏览器会自动带上你的Cookie服务器以为是你主动发起的操作。防御手段包括校验Referer字段、使用CSRF Token、设置SameSiteCookie等。客观题比较喜欢考“哪个请求会携带Cookie”以及“为什么CSRF Token能防住攻击”。安全这块的题建议不要死记硬背最好能动手写一小段demo复现一下XSS和CSRF的攻击链路。一旦理解了攻击链路选择题基本不用猜因为你知道那个环节“如果没有任何防护就会出事”。4. CSS与HTML看似送分的客观题其实藏着不少失分点4.1 盒模型与BFC绕不开的基础之一CSS的客观题从盒模型开始是惯例。标准盒模型里width指的是内容区content的宽度padding和border在宽度之外而IE盒模型也叫怪异盒模型对应box-sizing: border-box;里width指的是内容区加padding加border的总宽度。题目如果给一个width: 200px; padding: 20px; border: 1px solid #000;的div问标准盒模型下元素实际占用的宽度那就是200 20*2 1*2 242px。如果在border-box下那实际宽度就是200px内容区会被压缩成200 - 40 - 2 158px。这种题只要理解了计算规则就不会错但考场上时间紧很多人会忽略“border也要算进去”这个细节。BFC块级格式化上下文通常不会单独出一道大题而是穿插在“如何解决外边距塌陷”“如何清除浮动”这类题里。BFC的考点其实很集中它是页面上的一个独立渲染区域内部元素的布局和外部的元素互不影响。触发BFC的条件包括overflow值不为visible比如hidden、float不为none、display为inline-block或flex、position为absolute或fixed。我当时复习BFC的时候总结了一句话只要遇到“父子元素的margin合并”或者“父元素高度塌陷”这种问题第一个想到的思路就是给父元素创建一个BFC。客观题大概率会给你几个候选CSS属性问哪个能解决浮动塌陷这时候只要记得“overflow: hidden可以触发BFC”就能拿分。4.2 CSS居中方案与选择器优先级居中问题是CSS里最容易出选择题的因为方案太多了不同场景用哪个本身就值得考。比如一个div水平居中最简单的margin: 0 auto;要求元素有确定宽度如果是flex容器justify-content: center;就够了。垂直居中方案更多line-height只能处理单行文本、display: table-cell vertical-align: middle可以处理任意内容、绝对定位加transform: translate(-50%, -50%)是经典方案、flex的align-items: center是最省事的。客观题会给出一个场景比如“父元素高度不确定子元素需要水平垂直居中”然后给四个选项让你选可行方案。如果你只会背诵“flex可以居中”而没有考虑浏览器兼容性可能会选错。2018年的语境下flex已经足够安全但有些老项目里可能会考查position transform的兼容性更好。选择器优先级也几乎是必考。规则很简单!important 内联样式 ID选择器 类选择器/属性选择器/伪类 元素选择器/伪元素。但数字计算容易在长选择器链上出错。比如#app .content .item是1, 0, 2而.content .item .active是0, 0, 3前者优先级更高。注意这里不是十进制加法也不是“ID多就一定赢”而是按位比较从左到右ID选择器数量多的赢相同再比较类选择器数量再相同才比较元素选择器数量。很多人在这种地方丢分不是不知道优先级而是比较方式搞错了。4.3 HTML语义化与DOM操作的隐藏考点HTML部分的客观题大概率会考语义化标签的选用比如header、nav、article、section、aside、footer分别应该用在什么场景。这类题不难但要注意别选错section不是“通用的容器标签”如果只是想包一层div做样式应该用div而不是section因为section带有“文档中的独立部分”这层语义。标题往深了说语义化对SEO和无障碍访问都有影响这个答题的时候可以作为辅助判断依据。DOM操作的客观题也不少比如“document.getElementById返回的是什么”。这个问题有两个坑一是某些浏览器会把name为指定值的元素也返回二是该方法的返回值在绝大多数标准场景下是一个元素对象而不是数组或集合。而document.querySelectorAll返回的是静态的NodeList不是HTMLCollection也不是数组所以不能直接调用map方法。这个问题常和“getElementsByTagName返回的是动态集合”放在一起考用来判断你分不清“静态”和“动态”的区别。我复习DOM这块的经验是一定要区分几个容易混淆的集合类型HTMLCollection是动态的NodeList不一定是动态的querySelectorAll返回的是静态快照。一旦出题人把getElementsByClassName和querySelectorAll放在同一个题里对这两个概念的理解就直接决定对错。5. 框架、工程化与算法那个年份的取舍与风向5.1 Vue与React的常见选择题点位2018年笔试里的框架题已经占了不少比重。Vue的题爱考响应式原理和生命周期React的题爱考setState和虚拟DOM。Vue 2的响应式原理是基于Object.defineProperty的它会遍历data对象中的每个属性把每个属性都转成getter/setter。因此Vue 2中给对象新增一个属性比如this.obj.newKey 1是不会触发视图更新的。正确姿势是用Vue.set或者this.$set。这个考点在当年的笔试题里出现频率很高因为很多初学者就是在这里踩坑。放在今天的语境里Vue 3改用Proxy之后已经没有这个问题了但如果这套题考的是Vue 2答案还是老一套。生命周期顺序也是个经典考点。Vue 2的父子组件生命周期顺序父beforeCreate→ 父created→ 父beforeMount→ 子beforeCreate→ 子created→ 子beforeMount→ 子mounted→ 父mounted。一句话总结就是“父组件先创建但子组件先挂载”。这个结论如果没实际调试过单靠背很难稳定记住因为它的顺序不是直觉能推出来的。既然这套题里出现过刷题的时候最好自己写个demo把每个钩子的输出打一遍建立直观记忆。React的题在2018年已经会考Fiber了但不会太深常见的还是setState的异步批量更新。连续调用三次setState(count count 1)最终count只会加3而且如果用的是函数式更新就不会出现覆盖问题。这个知识点在笔试题里常以“下面哪种写法能保证状态正确累加”的形式出现区分度在于你知不知道setState在合成事件和生命周期里是异步批量的而在原生事件和setTimeout里是同步的。5.2 工程化与Webpack客观题考到哪一层工程化方向的客观题主要是围绕Webpack来出。2018年最常见的考法是问你Webpack的loader和plugin有什么区别。loader负责对模块的源代码进行转换比如把ES6转成ES5、把Sass编译成CSS、把图片转成base64plugin则处理更大范围的任务比如代码压缩、资源管理、环境变量注入。一句话loader是“转换器”plugin是“扩展器”。还有一个高频考点是source map。题目可能会问“生产环境应该使用哪种source map”或者“eval-source-map和source-map有什么区别”。当年很多同学的误区是“上线也开source map”这其实会暴露源码。原则上生产环境可以用nosources-source-map这种不带源码内容的类型或者干脆关闭只在测试环境开启。这类题的背后其实是工程化素养考的不是API而是你有没有真正部署过项目。5.3 算法与数据结构客观题里的复杂度计算前端笔试的算法部分客观题一般不会太难但会考复杂度。比如问“冒泡排序在最坏情况下的时间复杂度是多少”答案是O(n²)问“在有序数组中二分查找的时间复杂度”答案是O(log n)。还有些题会结合数据结构选型频繁在数组头部插入元素应该用哪种结构这里有个容易混淆的点数组在头部插入是O(n)的因为需要移动后面的所有元素而链表在头部插入是O(1)的只需要改指针。但如果题目说的是“数组的push操作”那在JavaScript里一般是O(1)因为是在尾部追加但也可能触发扩容。笔试的客观题很少会考虑扩容这种细节但如果你能说出“均摊O(1)”在主观题环节会很加分。栈和队列的考点更直白JS数组的push和pop实现的是栈push和shift实现的是队列但shift是O(n)操作性能差。有一种常见考法是“用两个栈实现一个队列”这题如果以选择题出现多半不是让你写代码而是问“进队和出队的平均时间复杂度”。答案是入队O(1)、出队均摊O(1)因为每次出队时如果辅助栈为空才需要把主栈的元素全部弹过去一次。6. 做真题的正确姿势从对答案到建立知识网络6.1 复盘时把每道题拆成知识图谱我刷360这套题的时候除了对答案还会把每道题背后涉及的知识点拆出来画成一张自己的知识图谱。比如一道“HTTP缓存”的选择题我会沿着它延伸出强缓存和协商缓存的区别、Cache-Control有哪些常用指令、ETag和Last-Modified谁优先、304状态码什么时候出现、刷新页面和首次访问的缓存策略有什么不同。这样一道题就变成了一组知识点的入口比单独背十道题效率高得多。这种拆解式的复盘可以把零散的知识点串成网。比如从“事件循环”出发可以连到宏任务、微任务、Promise、async/await、DOM事件回调、requestAnimationFrame从“浏览器渲染”出发可以连到CSSOM、重排、重绘、合成层、性能优化。知识一旦成网考试时遇到没见过的题也不会慌因为你会用已有的知识去推理。6.2 错题档案不要只看正确答案错题整理是备考里最枯燥但最有价值的环节。我自己的习惯是不仅要记录正确答案和解析更要把“我当时为什么选错”写下来。如果是知识盲区就去补对应章节如果是看题不仔细比如漏看了“选出错误的一项”那就要提醒自己考试时先圈出题干的限定词。另一个可以尝试的方法是“假装自己是出题人”。做完一道题后想一想如果我要在这道题的基础上变一个条件应该怎么变比如原题是“把var换成let后输出是什么”那我可以继续想如果把setTimeout改成Promise呢把循环次数从3改成5呢这种“变题训练”能帮你在考场上应对陌生感因为出题人翻来覆去就是那几个考点换的只是外表。6.3 客观题的临场时间分配客观题虽然每道题占用的时间短但整套题做下来时间管理依然重要。我的策略是第一遍把会做的题直接选掉不会的题标记出来先跳过第二遍回头处理标记的题优先做那些“排除两个选项后可以蒙”的题最后如果还有时间再集中精力算复杂度或者读代码输出题。对于完全不会的题也不要直接乱蒙。排除法在技术客观题里特别有用因为很多时候错误选项的错误点很明显比如“ES6不支持箭头函数”“flex布局一定是两列”这种绝对化表述基本可以直接排除。你可以把不确定性从四选一降到二选一这样蒙对的概率就翻倍了。这套题刷完之后我个人最大的体会是客观题最大的价值不是拿那一两分的对错而是通过它把那些你以为自己懂、其实经不起推敲的知识点全部暴露出来。每次做错一道题我都会逼自己去把对应章节重新翻一遍然后自己给自己讲一遍。这个过程比刷十套新题都管用。如果你也是准备春招的应届生或者工作两三年想系统查漏补缺建议把这套题放下“考过就扔”的偏见静下心来把每道题背后的原理抠一遍你不会后悔的。
返回列表