☰
TME2024校招前端笔试(I)考点解析与备考策略
2026/10/7 11:37:22 网站建设 项目流程

写在前面,这篇不是说“TME笔试答案”的,因为我也拿不到官方题库。但前端校招笔试这东西,出题思路和考察范围其实有很强的规律性,尤其是TME这类体量的公司,笔试(I)通常意味着第一场,后续还会有(II)(III),第一场的题型和难度往往是给整个招聘季定调的。我结合自己这几年的面试经验、带过的应届生反馈,以及网上能搜到的各家大厂前端笔试真题,把TME2024校招前端笔试(I)最可能考的、也最值得提前准备的点,完整拆一遍。

如果你正在准备投递TME或者其他大厂的前端岗,这篇内容就是给你划重点用的。核心会覆盖:笔试的整体考察范围、JavaScript语言基础与手写代码题、Vue/React框架与工程化题目、算法与编程题、以及最后的时间分配和应试策略。每个部分我都会给出可落地的复习思路,不是泛泛而谈。

1. 笔试考察范围全景拆解:TME前端岗到底在筛什么人

先搞清楚一个底层逻辑:笔试不是用来招“最会写代码的人”的,而是用来快速筛掉不合适的人的。TME的校招笔试(I)一般时长90到120分钟,题型通常是“选择题 + 简答题 + 编程题”的组合。题量不算大,但覆盖面很广,目的就是在有限时间内考察你的知识广度和深度。

1.1 从岗位JD反推考点优先级

我让不少准备投TME的同学把招聘官网的JD截图发我看过,前端开发岗的高频要求基本是这几条:

  • 扎实的HTML/CSS/JavaScript基础,理解浏览器渲染原理
  • 熟悉至少一种主流前端框架(Vue或React),有项目实战经验
  • 了解前端工程化、构建工具、性能优化
  • 具备一定的数据结构和算法基础
  • 加分项:有音乐类产品开发经验、熟悉Web Audio API、了解Canvas/SVG

笔试的出题就是围绕这几点展开的。JavaScript基础是绝对的重头戏,大概占30%到40%的分值;框架和工程化占25%到30%;算法编程题占20%到30%;HTML/CSS和网络基础占剩下的10%到15%。这个比例是我根据近几年TME和其他大厂前端笔试题型的平均分布估算的,不是官方数据,但大方向不会错。

1.2 “(I)”背后的信息量

笔试标题里的“(I)”值得琢磨一下。这说明至少有两场笔试,第一场通常面向某一批学校或某一时间段内投递简历的同学。根据往年经验,第一场笔试的难度往往相对友好一些,因为后续还有第二场、第三场,面试官需要通过多场笔试的对比来校准评价标准。但“友好”不等于“简单”,基础题依然会考得很细。

比如有次我帮一个学弟复盘某大厂前端笔试,选择题里考了[1, 2, 3].map(parseInt)的输出结果。这题看着简单,但错误率极高,因为它考的是parseInt接收两个参数、map传给回调函数的三个参数,这两个函数之间的参数错位。这种题就是典型的“知识点你都学过,但组合起来就懵”的考法,TME这类公司特别喜欢出。

1.3 笔试考察的能力模型

我把前端笔试的考察点归纳成一个能力模型,供你对照自测:

能力维度考察形式典型题目分值占比
语言基础选择题、简答题原型链、闭包、事件循环35%
框架与工程化选择题、简答题Vue响应式原理、webpack配置25%
算法与数据结构编程题数组去重、大数相加、递归转迭代25%
网络与浏览器选择题HTTP缓存、跨域、渲染流程10%
HTML/CSS选择题盒模型、Flex布局5%

看完这张表你就该明白:前端笔试不是一个“刷题就能过”的考试,它考的是你对前端知识体系的理解深度。背答案没用,你得真正理解底层原理。

2. JavaScript与手写代码题:基本功的试金石

不管哪家大厂,JavaScript基础都是前端笔试的重头戏。TME的笔试选择题里,JS相关题目的特点是:看起来不难,但每个选项都有陷阱。如果不理解底层原理,很容易凭印象选错。

2.1 高频考点:原型链、闭包、this指向

这三个概念是JS基础题的“三座大山”,TME笔试基本必考。

原型链的考法通常是给出一个对象继承关系,让你判断属性访问的结果,或者问instanceof的判定过程。我建议复习时不要死记结论,而是画一遍原型链的指向关系图:

  • Function.prototype是一个函数对象
  • Object.prototype是原型链的终点
  • func.__proto__ === Function.prototype
  • Function.prototype.__proto__ === Object.prototype

笔试常考的一种变体是:Function instanceof Object和Object instanceof Function都返回什么?答案是true和true,因为Function和Object都是函数,它们的__proto__都指向Function.prototype,而Function.prototype的__proto__指向Object.prototype。搞懂指向关系,这类题就迎刃而解。

闭包的考法集中在两个场景:一个是循环中var和let的区别,另一个是闭包导致的变量共享问题。最经典的例子:

for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i) }, 1000) } // 输出 5 5 5 5 5

如果把var改成let,输出就变成0 1 2 3 4。原因很简单:let有块级作用域,每次循环都创建了一个新的变量绑定;而var是函数作用域,所有setTimeout回调共享同一个i,循环结束后i已经是5。这个题考了作用域、闭包、事件循环三个知识点,性价比非常高。

this指向的考题常见于以下四种调用方式的判断:

function foo() { console.log(this) } foo() // window(非严格模式)/ undefined(严格模式) const obj = { foo } obj.foo() // obj const bar = obj.foo bar() // window / undefined foo.call({a: 1}) // {a: 1}

TME笔试里有一类题特别喜欢考箭头函数和普通函数的this区别。记住一句话:箭头函数没有自己的this,它的this是定义时所在作用域的this。所以obj.foo()如果foo是箭头函数,打印的依然是最外层作用域的this,而不是obj。

2.2 手写题专项:深拷贝、防抖节流、Promise

笔试题里的手写代码题一般出现在简答题或编程题的第一小问,分值不高但很能拉开差距。根据近年的题目风格,以下三个手写题几乎属于必考范围。

深拷贝是一个经典的不能再经典的题。笔试时如果你只写JSON.parse(JSON.stringify(obj)),大概率只能拿一半分,因为面试官期待的是能处理循环引用和特殊类型的实现。我推荐的写法是:

function deepClone(target, map = new WeakMap()) { if (target === null || typeof target !== 'object') { return target } if (target instanceof Date) return new Date(target) if (target instanceof RegExp) return new RegExp(target) if (map.get(target)) return map.get(target) const cloneTarget = new target.constructor() map.set(target, cloneTarget) for (let key in target) { if (target.hasOwnProperty(key)) { cloneTarget[key] = deepClone(target[key], map) } } return cloneTarget }

用WeakMap解决循环引用,用new target.constructor()保留数组和对象的类型,用instanceof处理Date和RegExp。这套写法面试官一看就知道你是真写过深拷贝,不是背的“标准答案”。

防抖节流也是高频手写题。防抖(debounce)的含义是:多次触发事件后,只在最后一次触发的延迟时间结束时执行一次。节流(throttle)的含义是:在固定时间间隔内只执行一次。我习惯用“电梯关门”和“技能冷却”来记忆这两个概念——防抖像电梯,人不断进出就不断重新计时;节流像游戏技能,放完必须等CD。

// 防抖 function debounce(fn, delay) { let timer = null return function(...args) { if (timer) clearTimeout(timer) timer = setTimeout(() => { fn.apply(this, args) }, delay) } } // 节流 function throttle(fn, interval) { let last = 0 return function(...args) { const now = Date.now() if (now - last >= interval) { last = now fn.apply(this, args) } } }

Promise相关手写题在TME笔试里出现的频率也很高,常见的是Promise.all和简易版Promise。Promise.all的实现需要你理解:接收一个可迭代对象,返回一个Promise,全部成功才成功,一个失败就失败。

Promise.myAll = function(promises) { return new Promise((resolve, reject) => { const results = [] let count = 0 if (promises.length === 0) { resolve(results) return } promises.forEach((p, index) => { Promise.resolve(p).then(res => { results[index] = res count++ if (count === promises.length) { resolve(results) } }).catch(reject) }) }) }

2.3 事件循环与异步顺序题:翻车重灾区

TME笔试的JS选择题里,事件循环相关题目是错误率最高的题型之一。这类题综合考察宏任务、微任务、异步回调的执行顺序。

经典真题长这样:

console.log('script start') setTimeout(function() { console.log('timeout 1') }, 0) Promise.resolve().then(function() { console.log('promise 1') }).then(function() { console.log('promise 2') }) console.log('script end')

正确答案是script start、script end、promise 1、promise 2、timeout 1。口诀是:同步先执行,微任务先于宏任务,宏任务按注册顺序执行。很多人栽在promise 2和timeout 1的顺序上,因为不清楚单次宏任务执行完后,要把当前微任务队列全部清空,才会执行下一个宏任务。

更变态的考法是在微任务里继续注册微任务,比如:

Promise.resolve().then(() => { console.log('micro 1') Promise.resolve().then(() => console.log('micro 2')) }) setTimeout(() => console.log('macro 1'), 0) // 输出顺序:micro 1,micro 2,macro 1

只要记住“微任务队列是连续清空的”,这类题就不会错。

3. Vue与React框架题:实战能力的第一道门槛

TME的前端技术栈以Vue为主,部分团队用React。笔试的框架题不会考“你用了某个API没有”,而是考你对框架底层机制的理解。这就意味着,如果你简历里写了熟悉Vue,那Vue的响应式原理、生命周期、组件通信这三个点你必须能讲清楚。

3.1 Vue响应式原理:从Vue2到Vue3的进化

Vue相关笔试题目中出现频率最高的,就是响应式原理。Vue2用Object.defineProperty,Vue3用Proxy,两者对比是经典考题。

Vue2的响应式实现思路:

  • 递归遍历data对象的每个属性,用Object.defineProperty拦截get和set
  • 在get中收集依赖(Watcher),在set中通知依赖更新
  • 对于数组,重写push、pop、shift、unshift、splice、sort、reverse七个方法

Vue3的响应式实现思路:

  • 用Proxy代理整个对象,拦截get、set、has、deleteProperty等操作
  • 依赖收集用WeakMap+Map+Set的数据结构
  • 惰性响应式:访问到某个属性时才进行依赖收集

笔试简答题如果问“Vue2和Vue3响应式的区别”,你要答出三个关键点:一个是API层面的差别(Object.definePropertyvsProxy),一个是性能层面的差别(Vue3可以代理整个对象,不需要递归遍历,访问时按需代理),还有一个是能力层面的差别(Vue3可以直接监听属性新增和删除,Vue2需要用Vue.set或者this.$set)。能把这个逻辑捋清楚,基本就能拿满分。

3.2 组件通信与生命周期:小题大考的典型

组件通信的考题形式通常是选择题,给你几个父子组件传参的场景,让你选出正确的写法。复习时掌握这张表就够:

通信类型Vue实现方式React实现方式
父传子propsprops
子传父$emit触发自定义事件回调函数
兄弟通信EventBus / provide-inject状态提升 / Context
跨层级Vuex / PiniaRedux / Zustand

生命周期方面,Vue笔试常考的是“在哪个钩子里发起请求”。标准答案是created或mounted,但TME这类公司会更进一步追问“两者有什么区别”。其实核心区别在于:created时DOM还未挂载,mounted时已挂载;如果请求结果需要操作DOM,放mounted更保险;如果请求结果不依赖DOM,放created可以先发请求节省时间。React那边对应的就是componentDidMount和useEffect。

3.3 工程化与构建工具:笔试里的“隐形考点”

前端工程化很少单独出大题,但选择题里一定会带几道。最常考的是webpack的核心概念和构建优化。

webpack的核心概念包括:entry(入口)、output(出口)、loader(转换器)、plugin(插件)、mode(模式)。笔试喜欢考的是loader和plugin的区别。理解方式很粗暴:loader是处理文件转换的,比如把ES6转成ES5、把Sass转成CSS;plugin是做loader做不了的事的,比如打包前清理目录、压缩代码、注入环境变量。

构建优化相关的考题可能会问:code splitting(代码分割)的原理是什么?tree shaking(摇树优化)依赖什么特性才能生效?前者答“把代码拆成多个chunk,按需加载,减少首屏体积”,后者答“依赖ES6模块的静态结构,在编译阶段就能确定哪些export没有被使用,从而在打包时删除”。

还有一类跟业务场景强相关的工程化题目,比如“音乐App首屏加载慢,你怎么优化”。这种题考察的就不只是构建工具本身了,而是性能优化的整体思路。我之前整理过一个答题框架:资源压缩(Gzip、图片格式)、缓存策略(HTTP缓存、CDN)、代码分割(路由懒加载)、渲染优化(SSR、骨架屏)。用这个框架去答,逻辑清晰,不容易漏点。

4. 编程题与算法题:笔试中的分水岭

编程题是TME笔试(I)里单题分值最高的部分,通常有两到三道,难度从“基础”到“中等偏上”不等。算法题考察的不是竞赛级别的算法能力,而是基本的数据结构运用和编码能力。但别小看它,每年栽在编程题上的人不比栽在选择题上的少。

4.1 高频算法题类型:字符串、数组、递归

根据近年大厂前端笔试题的统计,前端岗位的算法题集中在三类:字符串处理、数组操作、递归与动态规划。TME的编程题由于业务偏向音乐播放器,还可能出现跟播放列表、搜索推荐相关的题目背景,但核心算法依然是通用类型。

字符串处理的代表题是“大数相加”。给定两个字符串形式的非负整数num1和num2,计算它们的和并以字符串形式返回。这题的考点有两个:一是不能用BigInt偷懒,二是要考虑进位边界。

function addStrings(num1, num2) { let i = num1.length - 1 let j = num2.length - 1 let carry = 0 let res = [] while (i >= 0 || j >= 0 || carry) { const n1 = i >= 0 ? Number(num1[i]) : 0 const n2 = j >= 0 ? Number(num2[j]) : 0 const sum = n1 + n2 + carry res.unshift(sum % 10) carry = Math.floor(sum / 10) i-- j-- } return res.join('') }

数组操作的经典题是“数组扁平化并去重排序”。这道题如果写递归,代码是:

function flatten(arr) { return arr.reduce((pre, cur) => { return pre.concat(Array.isArray(cur) ? flatten(cur) : cur) }, []) }

如果要求用非递归实现,可以借助栈:

function flattenByStack(arr) { const stack = [...arr] const result = [] while (stack.length) { const item = stack.shift() if (Array.isArray(item)) { stack.unshift(...item) } else { result.push(item) } } return result }

递归与动态规划在TME笔试中出现的代表题是“爬楼梯”变体:一次可以爬1步或2步,爬上n阶台阶有多少种方式。核心是f(n) = f(n-1) + f(n-2),用滚动数组优化空间复杂度,笔试时写出递推式不算完,还得把环结构写出来。但更常见的是升级版——带成本的爬楼梯,或者跳台阶时不能连续跳2步,这些变体考的是你能不能举一反三。

4.2 编程题如何拿满分:边界条件与时间复杂度的双重要求

编程题评分通常是“部分用例通过给部分分”,所以目标不是“AC全对”,而是“尽量多过用例”。根据我帮人复盘笔试的经验,以下三个步骤可以帮助你稳定拿分。

第一步,先写暴力解,确保不空题。即使时间复杂度差一点,过了基础用例就能拿不少分。第二步,再考虑优化。如果暴力解超时,再想优化方案。第三步也是很多人忽略的:写代码前先列测试用例,特别是边界用例。比如数组为空、字符串超长、数值为0、递归深度大等场景。

举个例子,题目要求“实现一个函数,输入一个字符串,输出字符出现次数最多的字符”。如果你直接写一个对象统计然后遍历,基本用例都能过。但如果题目追加了“如果出现次数相同,输出最早出现的字符”,很多人没注意到“最早”这个条件,在比较时用了严格大于而不是大于等于,就会挂掉一半用例。

4.3 笔试环境与代码调试技巧

TME的笔试一般在牛客网或者赛码网进行,这两个平台的前端编程题环境都支持JavaScript和Node.js。有几点需要提前适应:

  • 编程题的输入输出用readline处理,而不是浏览器环境里的prompt。很多第一次参加笔试的人会在这里浪费很多时间。
  • 牛客网默认的JS模板是V8引擎的,用readline读取输入行后,print或console.log输出结果。
  • 题目的“运行”按钮只验证示例用例,真正提交后在后台会有很多隐藏用例,所以测试时多造几组特殊数据。

一个实用的调试技巧:如果你不确定当前环境是否支持某个API,在代码开头先输出该API的类型,比如console.log(typeof Promise)看环境里Promise是否可用。这虽然看起来傻,但在陌生的在线OJ环境里很管用。

5. 实战应试策略:时间分配与做题顺序

笔试不仅考知识储备,也考应试策略。时间分配不合理,很可能导致后面的编程题没时间写。我根据TME笔试(I)常见的“选择题60分钟 + 简答题20分钟 + 编程题40分钟”结构,整理了一套比较稳妥的时间分配方案。

5.1 做题顺序:先做编程题还是先做选择题

我的建议是:先快速做完选择题中送分的基础题,然后直接跳到编程题,最后再回头啃选择填空里的难题。原因是编程题的分值密度更高,一道编程题可能顶五六道选择题,而且编程题需要更长的思考时间,放在后面容易因为时间压力导致思路混乱。

具体节奏可以这样安排:

  • 前10分钟:快速浏览全部题目,标注出送分题和难题
  • 接下来15分钟:做完简单的选择题(能一眼看出答案的)
  • 再花35到40分钟:做编程题,每道题先保证写出暴力解,再尝试优化
  • 剩余时间:回头攻选择填空里的难题,能做就做,不能做就凭经验猜

选择题的猜题也有技巧。前端笔试的选项通常是四个,如果一道题你完全不会,可以先排除掉明显不合理的选项,再结合“出题人喜欢设置的陷阱”来判断。比如问“以下哪项不属于Vue的构成部分”,答案通常是那个你没见过的选项;问“以下哪个API不是ES6新增的”,答案是那个ES5就有的Object.create。

5.2 常见失分点与避坑经验

每年校招笔试,我陆续收集了不少同学回传的题目反馈,总结出几个常见的失分点,你复习的时候要特别留意。

第一个失分点:选择题里的代码题只看不运行。有些选择题给出一段代码让你判断输出,很多人只看了一遍就直接选了。正确做法是:能运行的题,在脑子里像机器一样逐行运行一遍。尤其是循环嵌套、递归调用、原型链查找这类代码,只看不run特别容易掉坑。

第二个失分点:简答题写得太短。简答题的要求通常是“简述XXX的原理”,建议写成“定义 + 关键点 + 例子”三段式。比如问Vue的虚拟DOM是什么,不要只回答“一种用JS对象描述真实DOM结构的技术”,要加上“通过diff算法比较新旧vnode差异,最小化真实DOM操作”和实际场景的例子。写得越完整,得分越稳。

第三个失分点:编程题不写注释、变量命名混乱。笔试平台的评分可能有人工审核环节,代码可读性会影响主观分。合理使用nums、target、index等语义化命名,在关键逻辑处加中文注释,会给人留下好印象。

5.3 笔试前一周的冲刺复习清单

如果你距离笔试还有一周左右,按下面的清单准备,性价比最高:

复习模块具体内容建议用时
JS核心概念原型链、闭包、this、事件循环、Promise2天
手写代码专项深拷贝、防抖节流、Promise.all、数组去重、函数柯里化1天
框架原理Vue响应式、生命周期、组件通信、Vue3新特性1天
工程化与网络webpack核心概念、HTTP缓存、跨域方案、HTTPS握手1天
算法刷题LeetCode热题100中的简单、中等题,重点是字符串、数组、链表的题目2天

复习时多写代码、少看视频。看懂了不代表能写出来,笔试考的是手写能力。建议每天抽出至少两个小时,在牛客网的在线编程环境里练题,提前适应笔试平台的输入输出模式。

5.4 心态管理与临场应变

笔试心态这件事很玄,但确实会影响发挥。我见过一些人,编程题第一道没写出来,心态崩了,后面本来会的题也没做对。应对方法是:遇到卡壳超过10分钟的题,先跳过,做后面的。笔试不要求满分,只要通过线就行。一般笔试通过线在60分左右,所以哪怕有一两道题不会,也不影响大局。

还可以准备一个自己的“代码模板库”,在笔试前十分钟把这些模板默写在草稿纸上(如果允许),或者记在心里。比如快速幂、二分查找、树的遍历(递归版和迭代版)、并查集这类经典的算法模板,考到就直接套,不需要现场重新推理。

最后,笔试结束后记得复盘。不管考得如何,把题目回忆一遍,尤其是自己做错的题和没写出来的题。TME这类公司的笔试通常不止一场,第一场挂了还有可能收到第二场的邀请,或者后续批次还有机会。复盘就是把经验留给下一轮,不要因为一次失利就放弃整个招聘季。

坦白说,前端笔试考察的内容就那么些,难的是在有限时间内把你会的都写出来。我见过不少基础扎实但笔试翻车的同学,问题基本都出在时间分配和临场心态上。拿到真题之后好好练手,把这篇提到的考点过一遍,通过笔试不会太难。

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

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

立即咨询