用友秋招前端笔试全解析:考点、真题与备考策略
2026/9/1 14:37:57 网站建设 项目流程

1. 笔试整体概况:先知道卷子长什么样

用友集团2023届秋招前端岗的笔试,整体给我的感觉是四个字:基础为王。整张卷子没有特别偏难怪的算法题,但知识点覆盖非常广,从浏览器原理到Vue底层,从网络协议到工程化配置,几乎把前端校招笔试的常规考点都揉进去了。如果你平时主要靠背面试题、刷LeetCode,可能反而会觉得有些吃力,因为它的很多题是“看起来眼熟,但选项里全是陷阱”。

笔试是在牛客网线上进行的,全程开摄像头,有防切屏监测。时间是90分钟,但实际上题量并不小,选择题有30道左右,外加简答题和两道编程题。我做完之后最大的感受是:时间分配比知识储备更重要,选择题如果纠结太久,后面编程题基本写不完。

这里先给准备投递用友的学弟学妹们一个核心结论:用友的笔试风格偏向ToB企业级应用场景,Vue技术栈占比很高,网络和浏览器知识考察得很细,场景设计题会结合企业级产品(比如大文件上传、权限管理、数据字典)来出题,和互联网大厂那种偏重算法和智力题的路子不太一样。所以复习方向要针对性调整,不能光刷LeetCode。

1.1 笔试流程与时间安排

我当时是在10月中旬收到的笔试通知,点进去之后先是一个身份验证,然后直接进入答题页面。整个流程大概是这样的:

  • 第一部分是单选题,大约20道,涉及HTML/CSS、JavaScript、浏览器、网络、框架基础。
  • 第二部分是多选题,大约10道,难度会比单选明显高,多选少选都不得分,很考验对知识点的精确记忆。
  • 第三部分是简答题,2道场景设计题,要求在文本框中写出思路或关键代码。
  • 第四部分是编程题,2道,一道偏JS手写实现,一道偏工程实践场景。

时间上是90分钟,但我建议大家按“40分钟选择题、20分钟简答、30分钟编程”的节奏来分配。我当时选择题花了差不多50分钟,导致编程题只来得及写一道半,这是比较大的失误。

1.2 题目构成与分值结构

这里我根据记忆整理了一张卷面结构表,方便大家直观了解分值分布:

题型题量分值占比考察重点
单选题约20道30%基础语法、CSS布局、浏览器机制、网络协议
多选题约10道15%JS进阶、框架原理、工程化概念
简答题2道25%场景设计、方案论述、代码思路
编程题2道30%手写实现、业务场景编码

从分值就能看出来,选择题和编程题是拿分的大头,简答题虽然只有两道,但分值不小,而且很考验你平时的项目积累。后面我会逐个模块展开讲。

2. 核心考察点拆解:从真题反推考点

我把自己记得比较清楚的题目做了一次归类和复盘,发现用友笔试考察的核心模块可以分成四大块:计算机网络与浏览器基础、JavaScript语言核心、Vue框架与工程化、业务场景设计。每一块都有一些高频考点和出题风格,下面逐一拆解。

2.1 计算机网络与浏览器基础:考点密集,陷阱最多

这一块是选择题的重灾区,也是我印象最深的部分。用友特别爱考几类题:从输入URL到页面渲染的完整过程、HTTP缓存机制、跨域解决方案、TCP与UDP的区别、浏览器事件循环。这些内容在八股文里都是老面孔,但他们的选项设置很细,不是那种一眼就能看出答案的送分题。

举个例子,有一道题问的是“当用户在地址栏输入一个URL并回车后,以下哪个过程发生在最先的阶段?”选项里有DNS解析、TCP握手、浏览器解析HTML、发送HTTP请求。很多人会直接选DNS解析,但实际上浏览器还要先判断这个输入是关键词还是URL,如果是关键词会走搜索流程,同时浏览器还会检查HSTS列表强制HTTPS。这类细节就是考试想要拉开差距的地方。

HTTP缓存也是必考内容。我当时遇到一道题,给出一个响应头,问哪些情况下浏览器会重新发起请求。这里就必须搞清楚强缓存和协商缓存的区别,Cache-Control的no-cache和no-store分别代表什么含义,以及ETag和Last-Modified的优先级关系。我建议准备笔试时把“HTTP缓存”做成一张流程表,从请求发出到命中缓存的每一步都理清楚,比死记概念有效得多。

跨域问题也考了,而且和实际业务场景结合得很深。用友的企业级产品经常涉及不同域名之间的接口调用,所以跨域是刚需。笔试里考察了CORS的简单请求和非简单请求区分、JSONP的实现原理、以及哪些情况下会触发OPTIONS预检请求。这类题光知道“用代理能解决跨域”是不够的,得能把底层机制讲清楚。

2.2 JavaScript语言核心:闭包、原型链、异步一个都不能少

JS部分的考察整体偏“精读型”,不是简单考你API怎么用,而是考你“为什么这么设计”以及“这段代码运行结果是什么”。题型主要是单选和多选,从作用域、闭包、原型链、this指向到事件循环、Promise、async/await,基本覆盖了面试八股里的所有必背项。

我记得有一道多选题特别典型,考的是闭包和var/let的区别。题目给了一段for循环代码,用var声明循环变量,然后问点击事件输出什么;又问如果换成let会输出什么。这道题的关键在于理解:var声明的变量会挂到全局或者函数作用域上,循环结束后变量保留的是最终值;而let是块级作用域,每次循环都会生成一个新的绑定。如果你只看过面试题但没真正动手写过,这种题很容易选错。

还有一道关于事件循环的题,问的是Promise、setTimeout、async/await混合使用时,打印输出的顺序。这题考察的是宏任务与微任务的执行机制。我的经验是,在笔试前一定要把“执行栈、微任务队列、宏任务队列”这三者的关系画清楚,尤其是async函数中await后面的代码,只有在Promise状态变为resolved之后才会被当作微任务继续执行,这一点特别容易漏。

this指向也是高频考点。用友的题不会直接问“this指向谁”,而是给一个对象方法、一个解构赋值、一个箭头函数的组合代码,让你判断输出。这种题核心就一句话:箭头函数没有自己的this,它的this继承自定义时所在的外层作用域;普通函数的this看调用方式。把这个底层逻辑吃透了,怎么变形的题都能应付。

2.3 Vue框架与工程化:用友的绝对主场

用友集团的企业级产品里,Vue是绝对的主流技术栈,所以笔试里框架部分几乎全是Vue。从Vue2的Object.defineProperty到Vue3的Proxy响应式原理,从虚拟DOM到diff算法优化,从组件通信方式到生命周期执行顺序,都考到了。这套题给我的感受是:他们不考“怎么用Vue写页面”,而是考“Vue内部是怎么工作的”。

有一道题让我印象很深,问的是Vue3的响应式系统和Vue2相比,为什么性能更好。选项里涉及Proxy可以监听对象属性的新增和删除、不需要递归遍历对象、懒收集依赖等。这道题如果你只看过“Vue3用Proxy代替了Object.defineProperty”这句结论,是远远不够的,你得理解两者的本质差别:Object.defineProperty是在初始化时通过遍历对象的key来劫持属性,所以对象新增属性无法被监听;而Proxy代理的是整个对象,不管有没有这个属性,只要对对象做操作,都能被拦截。

组件通信方式也考了,而且是多选题。选项有props/emit、provide/inject、event bus、Vuex/Pinia、$refs、v-model、插槽。这道题本身不难,但它提醒我们:要能把每种通信方式的使用场景和限制说清楚。比如event bus在大型项目中容易造成事件命名冲突和内存泄漏,provide/inject适合跨层级传递但破坏响应式可追溯性,这些优缺点对比一定要提前整理。

工程化方面,考了webpack的loader和plugin区别、vite为什么比webpack快、tree-shaking的工作机制。我印象比较深的一道简答题是关于vite的原理:为什么开发模式下vite冷启动那么快,而webpack开发模式却很慢。答案的核心在于,webpack在启动时要对entry及其依赖进行递归打包,把所有模块编译成bundle后再启动开发服务器;vite则是利用浏览器原生ESModule的能力,服务器按需传输模块,只有真正执行到某个模块时才进行编译。

2.4 业务场景设计题:用友笔试最有辨识度的部分

如果说前面那些考点是“通用前端面试题”,那简答题和部分编程题就是“用友特色”了。用友的服务对象主要是企业客户,所以业务场景题会围绕企业级应用的真实痛点展开,我印象中出现了大文件上传、数据字典管理、数据大屏、微前端改造等方向。

这些题目不是要你写一个完整项目,而是考察你面对一个真实业务问题时,能不能给出一个逻辑清晰、技术选型合理、可落地的方案。比如有一道简答题,大意是“ERP系统中经常需要上传大文件,如果一个文件有2GB,前端怎么设计上传方案?”这道题如果只答“用分片上传”肯定不够,至少要说出分片大小怎么定、并发数怎么控制、断点续传怎么做、进度条怎么实现、服务端怎么合并分片。

还有一道和微前端相关的题,问的是“老系统是jQuery写的,新团队用Vue3,怎么在不让老系统重写的前提下,渐进式接入新功能?”这其实就是企业级转型中非常典型的微前端问题。你要能说出qiankun、single-spa、Module Federation这些方案的优劣势,以及沙箱隔离、样式隔离、公共依赖加载这些关键点。

这类场景题的得分关键在于:不要把题目当八股文来背,而是把自己代入到真实的开发场景里,讲清楚“为什么这么设计”和“遇到问题怎么解决”。

3. 编程题实操复盘:手写实现与场景编码

编程题共两道,一道是纯手写实现,一道是业务场景编码。分值占比30%,如果前面选择题做得慢,编程题很容易写不完。我把两道题都回忆了一下,并复盘了解题思路和完整实现。

3.1 手写Promise.all:不止要会写,还要理解边界情况

第一道编程题是手写Promise.all。说实话,这道题不算难,但它考察的点很细。如果你只是背过Promise.all的用法,没真正实现过,很容易在边界情况上翻车。

Promise.all的核心逻辑是:接收一个可迭代对象(一般是数组),返回一个新的Promise。当所有Promise都成功时,返回一个由各个结果组成的数组,顺序和传入顺序一致;只要有任何一个Promise失败,直接走reject。

以下是标准实现:

function myPromiseAll(promises) { return new Promise((resolve, reject) => { if (!Array.isArray(promises)) { return reject(new TypeError('argument must be an array')); } const results = []; let completedCount = 0; const total = promises.length; if (total === 0) { return resolve([]); } promises.forEach((promise, index) => { Promise.resolve(promise) .then((value) => { results[index] = value; completedCount++; if (completedCount === total) { resolve(results); } }) .catch((error) => { reject(error); }); }); }); }

这里有几个关键点,笔试时即使不要求写代码,面试或简答环节也一定要能讲出来:

  • 使用Promise.resolve(promise)包装,是为了兼容传入非Promise对象的情况。
  • 结果数组的下标必须按传入顺序赋值,不能使用push,否则返回顺序会乱。
  • 只执行一次reject,后面的Promise即使失败也不再处理,这是通过Promise的不可逆状态转换天然保证的。
  • 空数组应该直接resolve一个空数组。

我当时的答题时间不太够,所以只写到了核心逻辑,但没有处理空数组的情况。希望大家吸取我的教训,这类手写题,代码写完一定要检查边界条件,至少在心里跑一遍空数组和带reject的用例。

3.2 大文件分片上传:把场景题变成代码

第二道编程题是一道场景题,题目要求用代码实现大文件分片上传的核心逻辑。题干大概是说:有2GB的文件,前端需要分片上传,要求能断点续传。

这道题虽然以业务场景为背景,但核心还是考手写代码能力。我当时写了三个部分:文件分片、并发控制、上报进度。下面是一个简化的实现示例:

const CHUNK_SIZE = 5 * 1024 * 1024; // 每个分片5MB async function uploadFile(file) { const totalChunks = Math.ceil(file.size / CHUNK_SIZE); let currentChunk = 0; // 先向服务端请求已上传的分片,实现断点续传 const uploadedChunks = await getUploadedChunks(file.name); async function uploadSingleChunk(chunkIndex) { const start = chunkIndex * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, file.size); const chunk = file.slice(start, end); const formData = new FormData(); formData.append('filename', file.name); formData.append('chunkIndex', chunkIndex); formData.append('totalChunks', totalChunks); formData.append('chunk', chunk); try { await axios.post('/api/upload', formData); } catch (error) { // 上传失败,记录重试 throw error; } } // 控制并发,每次最多3个分片同时上传 const concurrency = 3; const queue = []; let index = 0; while (index < totalChunks) { if (queue.length >= concurrency) { await Promise.race(queue); } if (uploadedChunks.includes(index)) { index++; continue; } const task = uploadSingleChunk(index) .then(() => { queue.splice(queue.indexOf(task), 1); currentChunk++; // 上报进度 updateProgress(Math.floor((currentChunk / totalChunks) * 100)); }) .catch(() => { // 重试或者标记失败 }); queue.push(task); index++; } await Promise.all(queue); // 所有分片上传完成,通知服务端合并 const mergeResult = await axios.post('/api/merge', { filename: file.name, totalChunks }); return mergeResult.data; }

这里我用了一个简单的Promise.race来实现并发控制,在实际项目中通常会使用p-limit这类更成熟的并发控制库,但在笔试中,用这种基础写法已经足够了。要注意的是,分片大小和并发数并不是越大越好,要根据网络情况和服务端限制配置,我在实际项目里一般分片设5MB、并发设3到5个,比较稳妥。

3.3 微前端方案梳理:简答题的答题模板

简答题里有一道微前端相关的题目,我把自己的答题思路整理了一下,基本可以当作这类题的模板。

首先,微前端要解决的核心问题是:技术栈异构的多个应用,如何在同一个浏览器页面上协同工作,并且做到独立开发、独立部署。

我在回答时从三个维度展开:

  • 应用隔离策略:JS沙箱隔离,qiankun基于Proxy实现沙箱,让子应用的全局变量和DOM操作不影响主应用;样式隔离,qiankun通过运行时加载和卸载样式表,或者使用CSS Module、CSS-in-JS来避免class名冲突。
  • 主子应用通信:通过自定义事件、全局状态管理(比如SingleSpa的props、qiankun的globalState)来实现主子应用之间的数据同步。
  • 公共依赖管理:使用webpack的externals加上CDN加载,或者使用Module Federation实现共享依赖的运行时加载。

另外要强调:微前端不是银弹,团队如果小于5个人、项目没有多技术栈共存的需求,用微前端只会增加复杂度。我在项目中通常建议团队先用iframe验证需求,真有性能或通用登录问题再考虑qiankun,这句话在笔试里说出来会显得你更有实践经验。

4. 踩坑记录与应试技巧:这些教训希望你提前看到

笔试过程中我踩了不少坑,也有很多事后复盘才想明白的点。这里挑几个最有代表性的写出来,希望对大家有帮助。

4.1 选择题里的常见陷阱

用友的单选题和多选题非常喜欢玩概念辨析。比如CSS部分,有一道题问的是flex布局中flex: 1等价于什么。选项有flex: 1 1 0%flex: 1 0 autoflex: 1 1 autoflex: 1 0 0%。正确答案是flex: 1 1 0%,因为flex: 1其实是flex-grow: 1; flex-shrink: 1; flex-basis: 0%的缩写。这类题如果你只看过flex: 1表示等分,但没有注意flex-basis的默认值,很容易选错。

还有一个多选题,考的是=====的区别以及各种隐式类型转换的结果。比如[1] == 1的结果是什么?null == undefined的结果是什么?NaN === NaN的结果是什么?这些题平时做开发基本用不上精细的转换规则,但笔试就是要考。建议考前把JavaScript的隐式类型转换表过一遍,尤其是对象和原始类型的转换场景。

多选题我还有一个经验:宁可少选也不要乱选。因为多选、错选不得分,不确定的选项千万不要勾。用友的多选没有“部分给分”的机制,少选一个和全错是一样的结果。

4.2 时间分配失误:编程题差点没写完

我前面说了,当时选择题花了将近50分钟,导致编程题时间很紧张。现在复盘,问题出在两道选择题上纠结太久。一道是事件循环的打印顺序题,一道是HTTP缓存的状态码判断。这两道题其实我可以先标记跳过,等做完后面的题再回来看,但我当时非要当场做出来,结果消耗了大量时间。

这里给大家一个很实在的建议:笔试过程中,遇到耗时超过2分钟的题,当场猜一个并标记,先往下走。选择题的分数再高,一道题也就1到2分,编程题一道的分数顶得上十道选择题。把时间花在编程题上,性价比更高。

另外,牛客网的前端编程题是支持JavaScript作答的,不需要处理输入输出,直接写函数体就行。这个机制比ACM模式的题目友好很多,所以大家不要有“编程题很难”的心理负担,本质上就是在一个在线编辑器里完成为一个函数或实现一个小模块。

4.3 环境细节:摄像头和网络一定要提前测试

这件事看起来不太起眼,但真的会出问题。用友的笔试系统要求开摄像头,进入前会自动检测摄像头是否可用、是否有麦克风。如果没有开启权限,会弹窗提示,但此时计时已经开始。

我建议提前一天登录牛客网,测试摄像头、麦克风和浏览器兼容性。最好使用Chrome浏览器,并且安装好最新版本,不要用IE或者某些国产浏览器的兼容模式,在线笔试系统的兼容性普遍是Chrome优先。另外,网络环境要稳妥,如果中途断网,系统会有一定的容忍时间,但频繁断连可能会影响答题状态甚至触发异常记录。我当时就遇到过一次网络波动,还好没造成实质影响,但心理压力确实不小。

5. 用友笔试备考建议:针对性复习路线

到这里,我已经把用友2023届秋招前端岗笔试的题型、考点和注意事项都盘了一遍。最后分享一下如果让我重新准备一次,我会怎么安排复习。

5.1 建立自己的前端八股文笔记

笔试的选择题覆盖面太广,临时抱佛脚效果很差。建议准备一份自己的知识清单,不要直接背网上的面试题合集,而是自己整理一遍,把每个知识点吃透。比如网络部分,我会按“从URL输入到页面渲染”这条主线,把DNS解析、TCP连接、HTTP请求、浏览器渲染、JS执行、资源加载串起来,形成一条完整的链路。

JS部分,我会以“执行机制”为中心,把变量提升、作用域、闭包、this指向、原型链、事件循环、异步编程串成一条线。Vue部分,以“响应式原理”为起点,牵出模板编译、虚拟DOM、diff算法、生命周期、组件通信这整个框架体系。这种主线式整理比零散地背面试题更高效。

5.2 手写实现要练到闭眼能写

用友的编程题出得比较务实,大概率会从Promise相关API、防抖节流、深拷贝、柯里化、大文件上传、并发控制这几个方向里选。建议这些手写题不要只看答案,一定要自己在编辑器里写三到五遍,直到不需要思考就能写出正确代码。

我个人的方法是准备一个“手写题清单”,每天抽半小时到一小时,随机抽取两道题在10分钟内完成。写完之后立刻回看边界条件有没有处理,比如类型判断、空值判断、异常处理。这个过程坚持两周,编程题的通过率会有明显提升。

5.3 结合ToB业务场景准备项目复盘

最后一点也是很多人忽略的:用友是ToB企业服务公司,笔试前一定要花时间了解它的业务形态。用友的产品包括ERP、财务云、人力云、供应链云等,技术底座是很多中大型企业都在用的低代码平台和微服务架构。

在这个背景之下,笔试里的场景题往往和“B端管理系统”强相关。我还记得简答题有考察“数据字典管理”的作用,这其实就是B端系统常见的固定数据项配置功能。如果你在项目里做过类似的模块,可以从“数据库设计、后端接口设计、前端缓存策略、权限控制、使用场景”这几个角度展开说明,这样比单纯的零散回答要完整得多。

所以,备考时不仅要看技术,还要看业务的坑在哪里,想清楚企业级应用相比C端应用的差异在哪里。比如B端系统的用户操作频率低但流程复杂,表单校验、权限链路、数据一致性往往比性能优化更优先;同时系统需要支持多租户隔离和定制化部署,这也是微前端、动态路由、菜单权限这些技术点在企业级应用中如此高频出现的原因。

从笔试本身延展开来说,准备用友秋招前端岗的过程,其实就是一次把前端知识从“会用”提升到“理解原理”的过程。你不需要背一堆花哨的算法模板,但需要把日常开发用到的机制真正吃透。这个投入不管最后拿没拿到offer,对你后续的能力提升都是有帮助的。

我个人在读过那些刷屏的面试题总结、又亲手做完这套题之后,最大的体会是:面试题只能帮你通过面试,真正能让你在面试中脱颖而出、在后续工作中走得更远的,还是你对每个知识点背后“为什么会这样设计”的探索能力。用友的笔试虽然知识点基础,但它恰恰是在筛选那些对前端有系统性理解的人。如果你现在正在准备前端的校招笔试,不妨把用友这套题当作一次自测:先别急着背答案,尝试自己把每一道题背后的原理讲清楚,到面试时你会感谢现在这个认真研究的自己。

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

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

立即咨询