发布时间:2026/8/29 22:18:02
大厂前端实习笔试攻略:JavaScript闭包、事件循环与布局方案全解析 2018年春天投小米前端实习生岗位的时候我还在学校啃JavaScript红宝书。当时做完笔试最大的感受就是题目覆盖面很广但几乎每道题都能在“前端开发skills”的底层能力里找到出处——语言基本功、异步机制、布局方案、工程化意识一个都没落下。这套题放到今天依然有很强的参考价值不是因为它多难而是因为它把“一个合格实习生该有的前端基础”考得很透彻。如果你正在准备前端实习或校招尤其是目标定在大厂的同学这篇内容非常值得看完。我会把当时笔试题背后的考察逻辑、典型题型、完整解题思路和踩坑经验全部拆开讲一遍不讲虚的直接对着题目来。1. 笔试背后的技术栈与考察逻辑1.1 大厂实习笔试到底想筛选什么很多人误以为实习笔试考的是“背得多不多”其实恰恰相反。大厂招实习生看的不是你会多少框架而是你在这个行业里有没有“干活的底子”。前端开发skills这个词听起来虚落到笔试里其实非常具体变量作用域清不清楚、类型转换会不会踩坑、异步回调能不能理顺、布局方案是不是只知道一种。小米这套笔试题以及同时期其他大厂的卷子有个共同特点不追新不炫技。它不会考你某个框架API的冷门参数而是把最基础、最能反映编码习惯的知识点翻来覆去地考。比如typeof的返回值、和的区别、let和var在循环里的表现——这些看起来简单但恰恰是很多简历上写着“精通JavaScript”的同学栽跟头的地方。实话说笔试筛人的核心逻辑就一条基本功决定上限工具决定下限。框架不会可以入职再学但作用域、闭包、事件循环这些如果不过关后续接需求、查bug会非常痛苦。所以笔试题的分布逻辑基本是按“语言基础 - 异步机制 - 布局能力 - 框架理解 - 工程意识”这条线铺开的。1.2 2018年前后的主流技术栈决定了考点范围看笔试题不能脱离时代背景。2018年前端技术栈处在一个比较关键的节点Vue 2.5 和 React 16 是绝对主流ES6 已经普及Webpack 4 刚出来HTTP/2 已经开始落地。这意味着笔试考点的选项池是比较明确的。JavaScript 基础部分ES6 的语法几乎是必考项包括let/const、箭头函数、解构赋值、模板字符串、rest 参数与展开运算符还记得热搜词里的“前端开发 函数 ...arg”吗这个点在笔试里出现的频率极高。异步部分Promise 已经取代回调成为主流问法async/await也已经开始进入题目。CSS 部分flex 布局已经普及grid虽然存在但还不是考试重点经典的盒子模型、BFC、双栏三栏布局仍然是主力题型。框架部分Vue 的生命周期、组件通信、v-if和v-show的区别是高频考点React 则是 state 和 props、生命周期函数。工程化方向Webpack 的核心概念entry、output、loader、plugin会被考到但不会深入细节HTTP 相关的基础状态码、跨域、缓存也在考察范围内因为这直接关系到前后端协作能力。1.3 从相关热词里嗅到的考点线索如果你仔细看当时技术圈的热搜词会发现很多词其实都在疯狂暗示考点。“前端开发规范vue”指向的是编码规范和框架理解“trea 开发 前端后端”和“hzero前端开发”说明笔试已经不只看纯前端前后端协作的基础知识比如跨域、接口联调、HTTP 状态码也会以选择题或简答题的形式出现。“前端开发 函数 ...arg”更直接rest 参数和展开运算符的用法、arguments对象的转换、函数式编程里的参数处理都是实打实的出题点。我当时复习的时候有个习惯把热词当成题目线索顺着关键词去延伸知识树。这个方法在后来的笔试里帮了大忙——很多看起来很偏的题其实都能在热词背后找到对应的知识点。所以下面我会顺着这条线索把核心题型一个一个拆开。2. 笔试题型拆解五个必刷的经典考点2.1 JavaScript 基础类型判断、作用域、闭包、this 指向JavaScript 基础部分是整个笔试的大头占比通常在 40% 左右。出题方式一般是选择题 代码输出题。选择题喜欢考typeof的返回值、instanceof的判断逻辑、null和undefined的区别、隐式类型转换的坑。代码输出题则集中在作用域、闭包和this的绑定规则上。先看类型判断。typeof有一个著名的坑typeof null object这是历史遗留问题。typeof function(){} function则是一个容易忽略的点因为函数也是一个对象。数组的判断推荐用Array.isArray()instanceof在跨 iframe 场景下会失效。这些细节在选择题里出现的概率非常高如果只看书不写代码很容易在这里丢分。作用域和闭包是必考中的必考。经典的for循环 setTimeout输出题几乎所有大厂笔试都出现过。考的不是你会不会写setTimeout而是你知不知道var没有块级作用域、函数作用域和词法作用域到底怎么工作。this的指向问题同样高频——普通函数调用、作为对象方法调用、call/apply/bind修改指向、箭头函数不绑定this这四种情况必须做到一眼能分辨。2.2 ES6 新特性let/const、解构、rest 参数与展开运算符ES6 在 2018 年的笔试里已经不是“新特性”而是“默认语法”了。出题重点集中在几个方向上let/const和var的区别尤其临时性死区、解构赋值的各种写法、rest 参数与展开运算符的使用场景。...arg这个语法糖几乎是笔试常客。rest 参数用于收集剩余参数返回一个真数组展开运算符则用于展开可迭代对象。有个经典陷阱题[...arguments]和Array.prototype.slice.call(arguments)有什么区别答案功能上等价但写法上arguments本身不是数组[...arguments]依赖可迭代协议在旧环境下可能不兼容。这种题考的就是你写代码时是否知道边界。箭头函数也是高频考点。箭头函数没有自己的this、不能用作构造函数、没有arguments对象可以用 rest 参数替代。笔试爱考的组合题是箭头函数里再嵌套箭头函数this指向谁答案是始终指向外层作用域的this不会因为调用方式变化而改变。2.3 异步与事件循环Promise、setTimeout、微任务与宏任务异步这块属于“看着简单一写就错”的重灾区。出题形式基本是给一段代码问输出顺序比如setTimeout和Promise.then混在一起让你猜打印顺序。核心知识点是事件循环Event Loop。JavaScript 是单线程的代码在执行时会先跑完同步代码然后处理微任务队列Promise.then、MutationObserver再取宏任务setTimeout、setInterval、事件回调执行。一个宏任务执行完后会清空微任务队列然后继续取下一个宏任务。如果你不理解这个循环机制基本上只要出现三个以上的异步任务就必错。比较典型的一道题setTimeout回调、Promise.resolve().then回调、普通console.log一起出现输出顺序永远是同步代码 - 微任务 - 宏任务。这个顺序不只笔试考实际开发里写异步逻辑时如果没概念很容易出现 bug 找不到原因。2.4 CSS 布局盒模型、居中方案、双栏三栏布局、flexCSS 部分的考察相对直白不会绕弯子但知识点密度很大。盒模型是必考的标准盒模型content-box和 IE 盒模型border-box的区别、box-sizing的作用这是基础中的基础。居中方案也是高频题。水平居中、垂直居中、水平垂直居中每种至少要知道两三种写法。flex 出现后居中变得非常容易但笔试可能会要求你“不用 flex 实现居中”考察你对 margin、定位、table 布局等老方案的理解。双栏和三栏布局同样如此flex 能轻松实现但 float margin、绝对定位、grid 这些方案也要能写出来。BFC块级格式化上下文也是出题点通常和“清除浮动”“外边距塌陷”绑在一起考。你要知道什么事情会触发 BFCoverflow 非 visible、float、position 为 absolute/fixed、display 为 inline-block/flex/grid以及 BFC 能解决什么问题。2.5 框架与工程化Vue 生命周期、组件通信、Webpack 基础框架部分对实习生的要求不太高主要是基础概念和生命周期理解。Vue 的话8 个生命周期钩子必须背下来created和mounted的区别要能用一句话说清楚一个是数据可用但 DOM 未挂载一个是 DOM 已挂载。v-if和v-show的区别一个操作 DOM 节点一个操作 display 属性也是高频题。组件通信是 Vue 笔试的核心。父传子用 props子传父用$emit兄弟组件通过事件总线或者 Vuex跨层级用 provide/inject。笔试喜欢出一个场景题A 组件嵌套 B 组件嵌套 C 组件C 要通知 A 更新数据问有哪些方案。答题的时候列出事件总线、Vuex 两种方案并说明各自适用场景基本能拿满分。工程化方向Webpack 的四大概念entry、output、loader、plugin是送分题loader 和 plugin 的区别要能说清楚loader 转换文件plugin 做打包之外的扩展。HMR热模块替换、source map 的作用也是常见选择题。3. 典型真题现场解题代码与思路完整记录3.1 作用域与闭包for 循环 setTimeout 输出题题目几乎长这样for (var i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); }问输出什么如何修改才能输出 0、1、2、3、4第一问答案输出五次 5。原因在于var声明变量没有块级作用域setTimeout的回调函数在 1 秒后执行时循环早已结束i已经变成 5所有回调共享同一个变量所以打印的都是 5。第二问有至少三种改法。第一种最简单把var换成letfor (let i 0; i 5; i) { setTimeout(function() { console.log(i); }, 1000); }let每次循环都会创建一个新的绑定回调捕获的是每次迭代独立的i输出正确。第二种是用闭包传参for (var i 0; i 5; i) { (function(j) { setTimeout(function() { console.log(j); }, 1000); })(i); }通过立即执行函数把i作为参数传入每次迭代的值被固化到函数作用域里。第三种是利用setTimeout的第三个参数for (var i 0; i 5; i) { setTimeout(function(j) { console.log(j); }, 1000, i); }第三种很多人不知道能写出来会加分。这道题考察的其实是“变量作用域 异步回调 闭包捕获”三个知识点一次考全性价比极高属于“一定要拿分”的题。3.2 手写防抖函数timer 细节与 this 绑定手写题里出现频率最高的就是防抖和节流。题目一般会说实现一个debounce函数要求事件触发后 delay 毫秒执行期间重复触发则重新计时并且保证this指向正确、参数正确传递。一个完整的实现function debounce(fn, delay) { let timer null; return function() { const context this; const args arguments; clearTimeout(timer); timer setTimeout(function() { fn.apply(context, args); }, delay); }; }这里有几个关键点必须注意。第一返回的函数必须是普通函数而不是箭头函数因为需要访问动态的this如果外层用箭头函数this会被绑定到定义时的作用域。第二fn.apply(context, args)里的context和args必须在闭包里保存下来否则执行时this和参数都丢了。第三clearTimeout放在每次触发时确保上次的定时器被清掉这是防抖的核心逻辑。扩展题还会让你写节流throttle区别在于防抖是“最后一次触发有效”节流是“固定时间间隔内只能执行一次”。笔试如果出了防抖十有八九会追问题节流的区别建议两个都提前准备好。3.3 事件循环输出题Promise、setTimeout 与微任务题目一般长这样setTimeout(function() { console.log(a); }, 0); Promise.resolve().then(function() { console.log(b); }); console.log(c);问输出顺序。答案是c-b-a。整个执行流程是这样的同步代码先执行输出csetTimeout的回调进入宏任务队列Promise.then的回调进入微任务队列同步任务执行完毕后事件循环先清空微任务队列输出b然后再取宏任务队列的第一个任务输出a。如果把题目再复杂化加一个async/awaitasync function test() { console.log(1); await Promise.resolve(); console.log(2); } console.log(3); test(); console.log(4);输出顺序是3-1-4-2。await后面的代码相当于.then的逻辑进入微任务队列所以2在4之后打印。这个点很容易错很多人以为await是同步阻塞其实它是“让出线程”的语法糖。3.4 手写深拷贝处理数组、Date、循环引用深拷贝是手写题的常客难点不是写出来而是写得完整。一个初级版本的深拷贝很容易但一个能处理数组、Date、RegExp、Symbol key、循环引用的版本才能真正体现代码功底。我来写一个笔试能用的版本function deepClone(obj, map new WeakMap()) { if (obj null || typeof obj ! object) { return obj; } if (obj instanceof Date) { return new Date(obj); } if (obj instanceof RegExp) { return new RegExp(obj); } if (map.has(obj)) { return map.get(obj); } const clone Array.isArray(obj) ? [] : {}; map.set(obj, clone); Reflect.ownKeys(obj).forEach(key { clone[key] deepClone(obj[key], map); }); return clone; }关键点有三个。第一基本类型直接返回不用递归。第二Date 和 RegExp 要特殊处理用构造函数创建一个新对象不能直接复制引用。第三循环引用问题——用WeakMap保存已克隆的对象如果再次遇到直接返回缓存的结果否则深拷贝会无限递归导致栈溢出。Reflect.ownKeys可以拿到包括 Symbol 在内的所有自有属性比Object.keys更完整。函数一般不需要深拷贝直接引用即可所以typeof obj ! object的判断会把函数直接过滤掉这是合理的。3.5 CSS 双栏布局三种实现方案对比CSS 手写题一般会考双栏或三栏布局要求是“左侧固定宽度右侧自适应”。这种题最简单的答案是用 flex.container { display: flex; } .left { width: 200px; flex-shrink: 0; } .right { flex: 1; }但笔试通常会加一句“不能用 flex”这时候要准备 fallback 方案。经典的 float margin 方案.container { overflow: hidden; } .left { float: left; width: 200px; } .right { margin-left: 200px; }overflow: hidden触发了 BFC能清除浮动带来的高度塌陷问题。还有一种绝对定位方案父容器position: relative左侧position: absolute; left: 0; width: 200px右侧margin-left: 200px。这个方案需要注意父容器要设置padding-left或 overflow 处理否则右侧内容可能会被左侧遮挡。三栏布局中间自适应左右固定最常用的是圣杯布局和双飞翼布局现在用 flex 也可以轻松实现.container { display: flex; } .left { width: 200px; } .center { flex: 1; order: 2; } .right { width: 200px; }能写出一种方案并解释为什么这样能生效基本就能拿分。重点不是背代码而是说清楚“左侧浮动后脱离文档流右侧的 margin-left 把它让开的宽度补回来”这层逻辑。4. 笔试实战中的踩坑与避坑清单4.1 时间分配策略先拿送分题再啃硬骨头小米这套笔试题我记得总时长是一个半小时左右题量不算小。我在实际答题时踩过最大的坑是前面选择题纠结太久导致最后的编程题时间不够。复盘下来时间分配应该遵循“先易后难先拿分再说”的原则。选择题里确实有几道题是有争议的、选项模棱两可的遇到这种题最多停留 3 分钟选一个最合理的答案后立刻跳过不要恋战。编程题反而值得留足时间——因为代码题是按点给分的写出基本思路和关键代码就能拿一半以上的分性价比远高于选择题。我当时大概花了 45 分钟做选择题剩下 45 分钟写编程题实际体验是选择题应该压缩到 30 分钟编程题尽量留到 60 分钟。手写题还有个技巧如果实在写不完整先写函数签名和注释把思路框架搭出来再往里面填实现。阅卷人看的是代码能力和思路空白的卷面是零分写了框架和核心逻辑至少能拿到过程分。4.2 代码书写习惯决定了印象分笔试阅卷很多时候不是机器判卷而是后端或者前端团队的人在看。代码的整洁程度会直接影响印象分。我见过一些同学代码逻辑是对的但命名全是a、b、c缩进乱七八糟函数也没有注释——这种答案即使对了也容易扣分。好的笔试代码应该做到变量命名用语义化的英文比如debounceTimer、resultList、isFirstRender函数名和注释说明函数的作用边界条件写在代码前面关键逻辑加一行注释解释“为什么这么写”。比如深拷贝里的map.has(obj)如果不加注释阅卷人可能会疑惑但如果你写一行“避免循环引用导致栈溢出”印象分会完全不同。还有一个小细节代码缩进统一用两个空格还是四个空格不重要但必须保持一致。千万不要混用 tab 和空格这在显示上会错乱极影响观感。如果你是手写代码现场笔试可能要写在纸上宁可写慢一点也要保证每个字符清晰可辨认。4.3 高频陷阱速查表我把笔试里最容易踩的坑整理成一个速查表考前扫一遍能避开大部分失分点。考点典型陷阱正确思路typeof null返回 object这是 JS 的历史遗留 bug选择题必记 和 0 为 true严格相等不转换类型var 循环闭包输出全是最后一个值let/IIFE/setTimeout 第三参this 指向方法解构后调用 this 丢失箭头函数或 bind 绑定Promise 顺序Promise.then 早于 setTimeout微任务先于宏任务箭头函数没有 arguments、不能 new用 rest 参数替代 argumentsArray.isArrayinstanceof 跨 iframe 失效用 Array.isArray 最稳妥box-sizingpadding 撑大盒子border-box 保布局稳定v-if vs v-show切换频繁用 v-if 卡顿高频切换用 v-show深拷贝循环引用递归栈溢出WeakMap 缓存已克隆对象这十四个坑涵盖了选择题和编程题的大部分失分点。你不需要背下来但做模拟题的时候如果发现自己在这几个点上反复出错就说明基础还需要补。5. 复盘与面试衔接笔试里的每一道题都是面试素材5.1 笔试结束后怎么复盘效率最高很多人笔试结束后就扔了这是最可惜的。笔试是一份非常精准的能力画像哪块薄弱一清二楚。我当时的做法是考完趁记忆还新鲜把每道题按“确定对的”“蒙对的”“完全不会的”三类归档。“蒙对”的题目尤其值得复盘——它意味着你其实不会只是运气好。归档之后针对“完全不会”的部分回到书里和文档里补缺口。比如我当时在事件循环那类题上错得最多所以花了整个周末把所有 Promise、async/await、setTimeout 组合输出题都刷了一遍直到每一种排列组合都能秒答。面试的时候面试官问异步相关的问题我回答得特别轻松因为笔试已经把盲区标出来了。这个复盘习惯还有一个好处它让你知道自己语言描述的表达逻辑在哪里断掉了。很多题你脑子里知道答案但写不出来说明你对知识的掌握还停留在“认识”阶段没有达到“熟练应用”阶段。笔试是检验你“会不会”复盘是帮你搞清楚“为什么不会”。5.2 把笔试题转化为面试表达素材笔试的代码题几乎都是面试时的好素材。比如你笔试里写了防抖函数面试官问你“你在项目里用过防抖吗”你就可以把笔试题里实现拿出来结合项目场景说一遍。这个衔接非常顺畅——因为笔试题本来就是经过筛选的经典场景面试官也熟悉你提到它不会显得突兀。我建议准备一个“笔试错题集”每个错题后面写两行一行是正确答案一行是你当时的错误原因。面试前翻一遍比临时刷题有用得多。我自己在二面的时候被问到“你能讲一下事件循环吗”我直接拿出笔试中做错的那道 Promise 输出题作为引子从错误推导出正确理解面试官印象很深。另外一个很实用的小技巧笔试结束后把每道编程题的代码重新在自己的编辑器里跑一遍确保能正常运行。这个动作的意义不只是验证答案更是让你的手感和思路保持在线。面试写代码的时候很多时候你的肌肉记忆比大脑思考更快平时写得越流畅面试表现越稳定。

相关新闻

2026/8/29 22:18:02

Godot 3D 模型材质切换指南:3 步实现完整换装与状态替换

Godot 3D 模型材质切换指南:3 步实现完整换装与状态替换 【免费下载链接】godot Godot Engine – Multi-platform 2D and 3D game engine 项目地址: https://gitcode.com/GitHub_Trending/go/godot 角色一踏进雨里,身上的衣服要立刻变成湿身材质&…

2026/8/29 22:18:02

mermaid 完整解析:一段文本变成 SVG 图的 5 站旅程

mermaid 完整解析:一段文本变成 SVG 图的 5 站旅程 【免费下载链接】mermaid Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid 在一个 …

2026/8/29 22:28:26

Pygame贪吃蛇游戏开发:从零搭建静态界面与网格化设计

1. 项目概述:为什么从界面开始?很多朋友学编程,第一个想做的游戏就是贪吃蛇。它规则简单,逻辑清晰,是理解游戏循环、事件处理和图形绘制的绝佳入门项目。但不少教程一上来就讲蛇的移动、食物的生成,把一堆代…

2026/8/29 22:28:26

测试转大模型:把学习路径落到证据

聊《大模型岗位变了,测试工程师该补的还是算法吗?》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要去年我带的一个大模型项目上线那天,测试的同学说"Demo 能跑通&#x…

2026/8/29 22:18:02

大厂前端实习笔试攻略:JavaScript闭包、事件循环与布局方案全解析

2018年春天投小米前端实习生岗位的时候,我还在学校啃JavaScript红宝书。当时做完笔试,最大的感受就是:题目覆盖面很广,但几乎每道题都能在“前端开发skills”的底层能力里找到出处——语言基本功、异步机制、布局方案、工程化意识…

2026/8/29 21:30:11

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/28 16:16:21

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/28 16:16:22

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/29 0:01:10

etc目录下的profile.d文件目录设置环境变量和全局脚本shell

一、设置环境变量etc目录下的profile.d文件目录 /etc/profile.d1、编写 vi test.sh文件内容# jdk变量 export ZHK_HOME/root export PATH$PATH:$ZHK_HOME/test # 可以取出来ZHK_HOME变量给ZZZ_HOME赋值 export ZZZ_HOME${ZHK_HOME}/test2、刷新 执行source /etc/profile 命令使…

2026/8/29 0:01:10

【JavaScript】内存管理-垃圾回收机制-内存泄露

内存管理 C 语言这样的底层语言一般都有底层的内存管理接口,比如 malloc()和free()。 而 JavaScript 是在创建变量(对象,字符串等)时自动进行了分配内存,并且在不使用它们时“自动”释放。释放的过程称为垃圾回收。 整…

2026/8/29 0:01:10

Labgrid-MCP:为嵌入式硬件实验室接入AI Agent操控能力

Labgrid-MCP 的目标是把 MCP(Model Context Protocol)能力延伸到真实嵌入式硬件实验室:AI Agent 通过一个标准化的 MCP Server,就能查看目标板状态、控制上电断电、复位开发板、读取串口日志,甚至执行镜像刷写。对于经…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…