ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

2024小米秋招前端笔试复盘:题型、考点、编程题与避坑指南

2024小米秋招前端笔试复盘:题型、考点、编程题与避坑指南 2024年小米秋招前端岗第二批笔试我是在9月下旬收到通知的。和第一批比起来第二批的节奏明显快了不少——上午收到邮件第二天晚上就考。当时心里其实有点打鼓因为“第二批”本身就释放了一个信号第一批笔试筛掉了一波人剩下的坑位已经在收缩后面的每一轮竞争都会更现实。但换个角度想小米的笔试相比某些大厂动辄4道hard题的场面还是温和不少题型覆盖面广考的是基本功和代码落地能力只要复习方向对这一关是可以稳过的。这篇文章我把整场笔试从题型结构、考点分布、编程题复盘到避坑经验完整拆一遍给后面要投小米或者其他中大型互联网公司前端岗的朋友做个参考。文章里所有真题都是我凭记忆还原的版本可能和原题有出入但考点和解题思路是实打实的。1. 笔试整体流程与题型分布先说说整体的考试形式和流程这部分会影响你后续的复习策略和考试当天的状态。小米2024届秋招用的是赛码网平台前端岗第二批次笔试安排在晚上19:00-20:30总共90分钟。登录之后会有身份核验需要打开摄像头并且考试期间不能切出浏览器页面切屏超过一定次数会被系统记录严重的话直接判作弊。这个我在后面避坑部分会详细讲。整场笔试卷面结构是这样的题型题量分值占比建议用时单选题10题30分15分钟多选题5题20分10分钟编程题2题30分40分钟前端设计/简答题1题20分20分钟从分值分布能看出来小米前端笔试不是纯算法导向。编程题占30分剩下70分都是围绕前端基础知识和工程实践能力展开的这个比例和腾讯、字节那种算法占半壁江山的风格不太一样更偏向考察一个候选人能不能直接上手做业务。选择题部分覆盖的知识面比较广包括JavaScript语言特性、CSS布局、浏览器渲染机制、网络协议、Vue/React框架原理等。多选题是这里面比较吓人的部分——少选不得分、多选也不得分非常严格所以遇到不确定的选项千万别乱选。编程题是两道难度大致在LeetCode中等偏下水平。一道偏数据结构和动态规划一道偏字符串处理。不涉及特别冷门的算法但要求你在赛码网这个没有本地IDE辅助的环境里用纯手写的方式把代码完整跑通。这个后面我单独开一节详细复盘。最后一道前端设计题是拉分项。题目会给你一个具体业务场景让你设计一个组件或功能模块要写清楚设计思路、技术选型、边界情况处理。这部分考察的不是你背了多少八股文而是你有没有真正做过东西、有没有踩过坑。这一套卷子整体感受下来时间够用但不算宽裕难点不在题有多难而在“面太宽”。如果复习只盯着框架源码或者只刷算法很容易在选择题和多选题上翻车。2. 核心考点拆解这些知识点被反复点名我复盘整张卷子把考点归成了五大类。每一类都是前端面试的高频区但小米这批笔试有几个出题角度很刁钻值得单独拎出来说说。2.1 JavaScript语言特性不只是八股文JS部分是单选题和多选题的重头戏但小米的考法不是那种“闭包输出什么”的入门题而是会在原型链、this指向、事件循环这几个经典考点上再套一层。我记得有一道单选题是这样的function Foo() { this.name foo; } Foo.prototype.getName function() { return this.name; }; const obj { name: bar }; const fn Foo.prototype.getName; console.log(fn());这道题考察的是方法单独调用时this到底指向谁。答案是undefined而不是bar因为fn()是普通函数调用在非严格模式下this指向window严格模式下指向undefined。很多人看到obj.name bar就直接选了bar但实际上这个对象根本没有参与调用链。这种考法就是典型的“你懂原型链但不会灵活运用”就会翻车。还有一道关于Promise和事件循环的题console.log(script start); setTimeout(() { console.log(timeout); }, 0); Promise.resolve().then(() { console.log(promise1); }).then(() { console.log(promise2); }); console.log(script end);这道题考的是宏任务和微任务的执行顺序答案是script start → script end → promise1 → promise2 → timeout。如果你对“微任务在宏任务之前执行”理解得不够透彻很容易把timeout排到promise前面。这道题其实是送分题但考场上紧张状态下容易手滑。JS这边我的建议是不要只背结论一定要把“为什么”搞清楚。比如事件循环你要理解为什么微任务优先于宏任务——因为微任务队列会在当前宏任务执行结束后、下一个宏任务开始前被清空。你只有在源码层面理解了这套机制遇到变种题才不会慌。2.2 CSS布局与样式细节看着简单坑不少CSS考了两道选择题和一道多选题涉及BFC、Flex布局、层叠上下文题目本身不算难但出题角度比较“实际”。有一道题是给你一个Flex容器的代码问你子元素在容器宽度不足时怎么表现div styledisplay: flex; width: 300px; div styleflex: 1 1 200px;A/div div styleflex: 1 1 200px;B/div div styleflex: 1 1 200px;C/div /div正确理解是三个子元素的flex-basis都是200px总和600px大于容器宽度300px所以会按照flex-shrink的比例进行压缩三个子元素最终各占100px因为shrink默认是1且三者比例相同。如果你不清楚flex缩写中1 1 200px分别代表flex-grow、flex-shrink和flex-basis这道题就很容易选错成“三个元素各200px然后溢出”。另外一道多选题考的是“哪些属性会创建层叠上下文”选项包括opacity小于1、transform非none、position为fixed、z-index不为auto。前三个都是对的但很多人会漏掉position: fixed这一项因为它在CSS2.1时代是不创建层叠上下文的但是CSS3之后规范改了fixed定位的元素会创建层叠上下文。这种题就是吃你知识是不是最新的。CSS这块复习策略很明确Flex和Grid的基本布局必须滚瓜烂熟BFC和层叠上下文要理解触发条件和实际作用移动端适配的rem/vw方案要能说清楚原理。2.3 浏览器与网络渲染机制是重点浏览器这边考了事件循环的浏览器端实现、页面渲染流程、HTTP缓存机制。有一道题是问你“在地址栏输入URL后发生了什么”虽然这是经典面试题但小米把它做成了选择题里的一个选项陷阱。更值得一说的是HTTP缓存那道多选题它考的是Cache-Control的no-cache和no-store有什么区别。很多人会望文生义觉得no-cache就是不缓存no-store就是也不缓存。实际上no-cache的意思是“可以缓存但每次使用前必须向服务器验证”而no-store才是“完全不允许缓存”。这是一个在实战中特别容易踩坑的点小米在这次笔试里直接用一道多选题考了出来。网络层的知识点前端面试常考的就是缓存、HTTPS握手、CDN加速原理、TCP三次握手这些。我的建议是缓存这块一定要把强缓存和协商缓存的完整流程背下来包括Cache-Control、ETag、Last-Modified之间的优先级关系。2.4 Vue/React框架原理二选一但都要会基本概念小米前端岗的框架考察以Vue为主但也涉及React的基础概念。我印象最深的一道题是考察Vue3的响应式原理题目问的是在Vue3中ref和reactive的底层实现区别是什么。答案是ref基于reactive实现通过给对象创建一个带有value属性的响应式对象来包装原始值而reactive使用Proxy直接代理对象。如果你只学过Vue2的Object.defineProperty这道题基本只能蒙。另外有一道React的题是关于useEffect的依赖数组行为考的是“依赖项是引用类型时如何避免重复执行”。这个点其实很多工作一两年的前端都容易忽略——useEffect的对比是浅比较如果你在依赖数组里传了一个每次渲染都重新创建的对象那么effect会在每次渲染后都执行。框架这块我的建议是至少要有一个主线框架是精通的。如果你说你会Vue那Vue3的响应式原理、虚拟DOM和diff算法、computed和watch的区别、组件通信方式这四块是必须能默写的程度。2.5 前端工程化与性能优化考察实际落地能力多选和简答题里都有工程化相关的内容。选择题考了一道webpack的loader和plugin区别简答题则直接问了“如何优化首屏加载速度”。优化首屏这个问题属于面试高频题但小米的批改标准显然不是让你列一堆方案就完事而是要看你说得是否具体。你光说“使用CDN、代码分割、懒加载”这些词是不够的要能说清楚具体的实现方式和预期效果。比如代码分割你要说用import()动态导入配合webpack的splitChunks把公共依赖抽离懒加载要说路由级别的懒加载方案图片要说明使用WebP格式、添加loadinglazy等。性能优化这块的知识点其实就是平时的积累没有太多捷径。但如果你时间紧优先把雅虎35条军规里的核心条目看一遍再结合一到两个你实际项目的优化案例基本上就够了。3. 编程题真题复盘两道题一个套路编程题是整个笔试里最硬核的部分没有伪代码、没有提示就是纯手搓代码。我把能回忆起来的两道题还原在这里并给出完整的解题思路和AC代码。3.1 第一题最长连续递增子序列原题是这么描述的给定一个未排序的整数数组找出最长连续递增子序列的长度要求时间复杂度O(n)。举个例子输入: [1, 3, 5, 4, 2, 3, 4] 输出: 3 解释: 最长连续递增子序列是 [2, 3, 4]长度为3注意这题的关键是“连续”也就是说子序列在原数组中必须是挨在一起的不是经典的LIS问题。它其实是一道贪心题思路非常简单维护一个计数器count从下标1开始遍历数组如果nums[i] nums[i - 1]计数器加1否则计数器重置为1。同时用maxLen记录历史最大值。function findLengthOfLCIS(nums) { if (nums.length 0) return 0; let maxLen 1; let count 1; for (let i 1; i nums.length; i) { if (nums[i] nums[i - 1]) { count; } else { count 1; } maxLen Math.max(maxLen, count); } return maxLen; }时间复杂度O(n)空间复杂度O(1)。这是这轮笔试里最简单的一道题属于送分题。但我在考场上一开始其实犹豫了一下因为前面选择题里也出现了一道“最长递增子序列”相关的考点我下意识以为编程题也会考LIS差点按动态规划去写了。后来仔细审题才发现是“连续”的变种。这里也给后来者提个醒笔试编程题的第一件事永远是“审题”尤其是区分“连续”和“非连续”这决定了你的解法是完全不同的量级。如果题目要求时间复杂度O(n)那么出题人大概率是想要贪心或双指针动态规划一般是O(n²)或O(nlogn)提前就在题目条件上给你筛掉了。3.2 第二题字符串解码第二题稍微有点含金量题目的原型是LeetCode 394题“字符串解码”但不完全是原题。我记忆中的版本是给定一个经过编码的字符串格式为k[encoded_string]表示方括号内的字符串重复k次。要求输出解码后的字符串。可以假设k是正整数输入字符串总是有效的嵌套的情况可能存在。示例输入: 3[a2[c]] 输出: accaccacc这道题是典型的栈应用场景。解法思路是遍历字符串遇到数字就解析出完整的数字注意可能不止一位遇到[就入栈遇到]就出栈并拼接字符串。我当时写的解法是用两个栈一个存字符串、一个存数字边遍历边处理function decodeString(s) { let stack []; let num 0; let currentStr ; for (let ch of s) { if (!isNaN(ch)) { num num * 10 Number(ch); } else if (ch [) { stack.push({ str: currentStr, count: num }); currentStr ; num 0; } else if (ch ]) { let { str, count } stack.pop(); currentStr str currentStr.repeat(count); } else { currentStr ch; } } return currentStr; }这个解法的关键点是在遇到[时把当前的字符串和当前累计的数字打包存进栈里然后清空currentStr和num。在遇到]时弹栈并把弹出来的字符串拼接在currentStr前面这样就能正确处理嵌套结构。举个例子走一遍3[a2[c]]遍历到3时num变成3遇到[把{str: , count: 3}入栈遇到acurrentStr变成a遇到2num变成2遇到[把{str: a, count: 2}入栈遇到ccurrentStr变成c遇到]弹出{str: a, count: 2}currentStr变为a c.repeat(2)也就是acc再遇到]弹出{str: , count: 3}currentStr变为 acc.repeat(3)最终得到accaccacc。这道题的难度在于处理嵌套但如果你对栈的使用足够熟练10分钟内可以写完并测试通过。我做完这道题之后大概还剩15分钟左右正好用于检查和写下一道设计题。3.3 赛码网环境下的代码提交技巧这里必须单独说一个经验赛码网的编程题环境没有本地IDE那么友好没有代码补全、没有语法高亮、不能实时调试。你只有提交运行之后才能看到“通过率”和“错误样例”的提示。所以在赛码网写代码要养成几个习惯第一写完代码后一定要在代码里手动补一个测试用例。你不能像在本地IDE里那样console.log调试但可以在提交前自己在脑子里模拟几组输入输出。比如上面那道字符串解码我就在纸面上手算了一遍3[a2[c]]的推导过程。第二边界情况一定要处理。数组题要检查空数组字符串题要检查空字符串和字符全是数字的情况。赛码网不会因为边界情况给你额外提示只会显示“通过率50%”你很难定位是哪里错了。第三输入输出格式。赛码网前端岗可以用JavaScript提交但输入输出需要自己封装。题目通常会给你一个readline()读取输入、print()输出的函数不要自己去写process.stdin那一套。严格按题目给的示例代码来写就行格式错了编译都过不了。4. 前端设计题如何答好“设计一个组件”这类题编程题之外最后一题是前端设计题。这是我整场笔试里最有感触的一部分因为这种题没有标准答案但又最能看出一个人的实际水平。题目大概是“请设计并实现一个支持大文件上传的组件要求支持断点续传。请写出你的设计思路、核心代码逻辑以及需要考虑的边界情况。”这种题本质上是在考工程能力不是考八股文。它的隐含要求是你有没有真正做过上传功能知不知道大文件上传会遇到什么问题。我的解题思路是这样的首先明确问题背景。为什么要断点续传因为大文件上传网络波动可能导致中断重新上传整个文件成本太高所以要把文件切片按片上传记录上传进度断网后从断点继续传。然后设计整体方案我按四个模块来拆文件切片使用File对象的slice方法把文件切成固定大小的块比如每片5MB。用FileReader或者arrayBuffer读取每个切片的内容。实际项目中文件大、切片多的情况下还要控制并发数避免一次发太多请求导致浏览器崩溃。上传队列与进度管理用一个数组维护所有切片的上传状态待上传、上传中、已完成、失败。每上传完一个切片记录它的索引。上传进度可以通过(已完成切片数 / 总切片数) * 100%计算。这一步其实引出了第二个考点前端如何计算文件MD5值通常会使用spark-md5这个库但它对超大文件会有卡顿问题所以最好结合Worker来处理。断点续传上传过程中断后重新开始上传时先向服务端发送一个请求查询该文件已经上传了哪些切片。这个查询需要用到文件的唯一标识——也就是文件的MD5值。服务端返回已存在的切片索引列表前端只上传缺失的部分。这就是断点续传的核心逻辑。边界情况比如文件上传过程中用户取消再次选择同一个文件时如何从断点恢复比如服务端返回错误时某个切片一直失败是无限重试还是跳过比如并发数限制、超时处理等。我当时没有写完整的实现代码因为时间不够但我画了一个清晰的流程图并给出了核心的伪代码// 核心逻辑伪代码 async function uploadFile(file) { const fileMd5 await calculateMD5(file); // 计算文件指纹 const chunkSize 5 * 1024 * 1024; // 5MB一片 const chunks Math.ceil(file.size / chunkSize); // 先检查服务端已上传的切片 const uploadedChunks await axios.get(/upload/status?md5${fileMd5}); const tasks []; for (let i 0; i chunks; i) { if (uploadedChunks.includes(i)) continue; // 已上传的跳过 const start i * chunkSize; const chunk file.slice(start, start chunkSize); const formData new FormData(); formData.append(chunk, chunk); formData.append(index, i); formData.append(md5, fileMd5); tasks.push(axios.post(/upload/chunk, formData)); } // 控制并发比如每次最多5个 await runWithConcurrency(tasks, 5); // 所有切片上传完成后通知服务端合并 await axios.post(/upload/merge, { md5: fileMd5, name: file.name }); }为什么我要在这里给出这么详细的代码因为面试官看的是你能不能把一个工程问题拆解成可执行的方案而不是光靠嘴说“我用过断点续传”。你写出来的伪代码越接近可运行的真实代码就越能证明你是真的做过而不是背过方案。关于设计题我总结一个经验这种题一定要“先结构后细节”。先把方案的大框架写出来再填充细节。不要在第一步就陷入“slice方法怎么传参”“并发怎么控制”这样的细节里那样会显得你没有全局观。我当时是先列了四个模块再写核心代码最后补充边界情况整体思路特别清晰。5. 考场上容易踩的坑我亲身经历过和听说过的这一节聊点更贴近实战的东西。很多技术不错的人笔试翻车不是输在知识储备上而是输在考试细节上。我把自己踩过、以及身边同学踩过的坑整理在这里。5.1 切屏警告和摄像头问题小米这次笔试用的是赛码网进系统的时候会让你开启摄像头权限并拍照验证。考试过程中系统会监测你是否切出了浏览器窗口。我有同学在考试期间因为电脑弹窗广告切了一下屏幕被系统警告了一次虽然不是马上取消成绩但心里会很慌影响后续答题状态。这里有两件事很重要。一是考试前把电脑上所有弹窗软件、聊天软件、输入法的自动更新全部关掉特别是类似浏览器弹广告那种最稳妥的方式是开一个干净的用户账户考试。二是提前确认摄像头能不能用多准备一个外接摄像头备用。有些人的笔记本摄像头权限没开进考场的时候调试了半天白白浪费了答题时间。5.2 时间分配别在一道题上死磕我给自己定的时间预算特别严格选择题15分钟多选10分钟编程题40分钟设计题20分钟剩下5分钟检查。实际考下来选择题和多选题各用了12分钟编程题两题一共用了27分钟最后设计题写了25分钟时间刚好够用。但有些人容易犯一个错误在编程题上死磕。如果一道题解了20分钟还没思路就要果断做下一题。因为编程题是客观题要么AC要么没分你在一道题上耗40分钟即使解出来了也可能因为没时间做设计题而丢掉那把20分。而设计题你只要写了思路、给出了合理的方案至少能拿一半以上的分。这个性价比差距太大了。5.3 多选题的“少选”陷阱我说过小米多选是“少选多选都不得分”这和很多考试“少选得一半分”的规则不一样。所以这套卷子的多选题其实是“宁缺毋滥”的但这里的“缺”不是叫你不选而是提醒你不要猜。你只选有把握的选项哪怕只选一项不会被扣分只是不得分。但如果选了一项错的整题0分。所以对于不确定的选项果断不选。我当时有一道多选题没把握就只选了两项最终结果不知道对错但至少我没有因为猜错而丢掉那些我确定能拿到的分。5.4 读题不认真连续和非连续差的是整个解法前面编程题复盘时我已经提过“连续递增子序列”这个问题。其实这反映了笔试里最常见的失分原因——审题不清。选择题里有一些概念题出题人会在题目中间藏“陷阱词”比如“不属于”“错误的是”“最不可能的是”。这类词很容易在快速读题时被忽略。我的习惯是看题先看问题带着问题去读题干。尤其是选择题先看“选正确的还是选错误的”再读题能有效避免因为惯性思维而选反。5.5 网络环境断网等于白考这个是我一个同学的惨痛教训。他考试当天在宿舍网络是校园网平时挺稳结果考试中途路由器重启了一次断网接近3分钟。虽然赛码网偶尔会断线重连但他那3分钟正好卡在一道编程题即将完成提交的点上代码没保存心态直接崩了。建议考试前强制把手机热点准备好一旦主网络断连30秒内切换热点。另外每做完一题立刻保存或提交不要攒到最后一次性提交。6. 不同基础的人怎么准备小米这种笔试笔试复盘做得再好对还没考的人来说最有价值的还是“该怎么准备”这件事。我按基础水平分了三类你可以根据自己的实际情况对号入座。6.1 基础扎实的资深开发者查漏补缺刷手感如果你日常工作在写业务代码对Vue/React的底层原理有一定理解项目里做过组件封装那你的重点不是从头学而是查漏补缺和刷手感。这个阶段我建议你把重心放在三件事上一是手写高频面试题包括防抖节流、深拷贝、Promise.all、数组扁平化、instanceof的原理实现这些题目虽然不一定会原封不动地出现在编程题里但它们的核心思路会以各种变体出现。二是刷LeetCode热题100题中的数组、字符串、链表相关题目重点练习使用JavaScript刷题的感觉尤其是双指针和栈这两个高频套路。三是整理两个你最有自信的项目亮点比如性能优化、工程化配置、复杂组件设计这些是设计题的素材库。6.2 基础薄弱的应届生先过八股文再刷题如果你对事件循环、原型链、闭包这些概念还停留在“听说过但说不清”的程度那你的策略要调整先把八股文过一遍再做真题。为什么是“先八股文后刷题”因为小米这套笔试题的选择题占比高达50分而这50分几乎全部是八股文。你连flex: 1 1 200px三个值分别代表什么都不清楚编程题做得再6也很难及格。八股文的复习范围就锁定我上面讲的五个模块JS核心、CSS布局、浏览器机制、框架原理、前端工程化。八股文过了之后再来刷题。应届生刷题不需要追求很难的题目把LeetCode的简单和中等题刷到50道左右就够了。重点是掌握常见的解题思路哈希表、双指针、栈、队列、动态规划入门、字符串处理。这六类套路基本覆盖了前端笔试编程题的所有出题方向。6.3 跨专业或转行选手抓大放小目标明确如果你是非科班或转行时间又紧我的建议是战略性放弃某些分值低但投入大的考点。比如多选题里的某些冷门CSS属性、React源码级别的原理分析这些可以直接跳过。你要把有限的精力全押在性价比最高的三块JavaScript核心语法闭包、原型、异步、CSS常见的布局方案Flex、Grid、居中、BFC、以及一道必会的算法模板数组遍历和字符串处理。这三块学扎实了你至少能拿到卷面60%的分数过笔试线问题不大。关键还是心态。小米这批笔试是“第二批”题量看起来多但整体难度真的没有到劝退的程度。相比某些大厂动辄出的hard级别动态规划题小米的题更朴实地考察你有没有掌握前端工程师日常需要的基本功。正常准备、正常发挥是很有希望通过的。我自己在复习的时候有一个很深的体会前端笔试的题目八股文和算法题的占比大概是一半一半但很多人花在算法题上的时间是八股文的五倍。这个投入产出比其实是失衡的。对前端岗来说基础知识扎实远比会做几道hard题要重要。笔试筛的是“能不能干活”的底线而不是“算法有多强”的天花板。希望后面准备小米或者其他大厂笔试的朋友能把精力放在真正能帮你拿到offer的考点上。
返回列表