用友秋招前端笔试全复盘:考点分布与避坑指南
2026/9/1 13:22:51 网站建设 项目流程

2023年秋招我投了用友集团的前端岗,笔试考完出来最大的感受是:范围广,但深度不算变态,重点考的是“有没有认真做过项目、有没有啃过基础”,而不是背多少偏题怪题。这篇文章就把我那次笔试的完整复盘整理出来,包括题型分布、各模块考点、高频题目回忆、解题思路,以及我在复习和考试过程中踩过的坑。无论你是准备投用友,还是想参考一下国内大厂前端校招的笔试水平,这篇都能给你一个比较清晰的坐标。

先说结论:用友前端笔试从题型到难度,在国内企业服务类公司里属于比较典型的一套。它不像头部C端互联网大厂那样动辄四道Hard算法题压场,也不像小公司那样只考八股文背诵,而是选择题、编程题、简答题混合,综合考察前端基础、工程化经验、计算机基础和业务理解能力。这种结构对项目经历比较扎实、但算法刷题量一般的同学反而比较友好。

1. 用友秋招前端笔试整体拆解:站在出题人的角度想问题

1.1 考试形式和题目结构的复盘

我参加的那场笔试是统一的在线测评,全程双机位摄像头监考,网页端答题,总分和时间我记得是90分钟。整体题量在四五十道左右,其中选择题占大头,后面跟两道编程题,中间或者最后夹杂几道简答/手写题目。不同的批次可能略有差异,但大方向是一致的。

时间分配是我觉得最需要提前心理建设的一点。90分钟里塞四五十道选择题加两道编程题,如果每道选择题都纠结太久,编程题很可能会写不完。我当时策略是:选择题平均每题控制在1分钟上下,遇到超过两分钟还没头绪的选项先标记跳过,等编程题写完再回来补。这个策略帮我稳住了后面的编程题,实际效果很好。

题型分布大概长这样:

模块题量占比主要考察方向
前端基础(JS/CSS/HTML)约35%-40%原型链、闭包、事件循环、布局、选择器优先级
浏览器与网络约15%-20%缓存、跨域、渲染机制、HTTP状态码
框架与工程化约20%-25%Vue/React原理、组件通信、打包工具、微前端
数据结构与算法约2道编程题以常见算法题和业务场景模拟题为主
计算机基础约10%网络协议、基础数据结构、操作系统常识
开放/素质题少量项目经历、场景设计、职业规划

1.2 用友这家公司对前端的独特要求

用友是做企业服务软件的,产品线涵盖了大型企业的ERP、财务、人力、供应链等系统,这几年也在大力推YonBIP这类云平台。这类B端公司的前端开发和C端产品的思路差异很大,在笔试里会有很明显的映射。

C端产品前端关注的是性能指标、首屏体验、跨端适配、数据埋点这些;而B端企业服务前端更看重组件化能力、表单中台、权限控制、复杂表格、可视化大屏、低代码/配置化页面搭建,以及微前端这类可以支持大型系统拆分的架构方案。笔试里大量出现组件设计、状态管理、前端工程化相关题目,就是这个原因。

所以如果你准备投递用友这类企业服务公司,复习的侧重点应该是:背熟Vue/React的底层原理、吃透组件通信和状态管理的各种方案、对微前端有基本的认知,同时把前端工程化里的分包、构建优化、环境配置这些理解到位。至于那些炫技型CSS动效、WebGL可视化之类的深挖题,反而考得很少。

2. 核心考点拆解:JS基础、CSS与浏览器机制

2.1 JS基础:原型链、事件循环、闭包三件套

JS基础这部分的题目,说白了就是前端面试八股文里最经典的那几类。但用友的题有一个特点:它不太直接问你“什么是闭包”,而是给你一段代码,让你判断输出结果,或者让你补充一段代码,来实现某种效果。这种考法其实比背概念更有区分度。

我记得有一道题是考察事件循环和Promise执行顺序的,类似这种结构:

console.log('start'); setTimeout(() => { console.log('timeout'); }, 0); Promise.resolve().then(() => { console.log('promise1'); }).then(() => { console.log('promise2'); }); console.log('end');

答案是start -> end -> promise1 -> promise2 -> timeout。这道题表面看是在考宏任务和微任务的执行顺序,但如果你能准确说出来“微任务队列会在当前宏任务末尾清空,而Promise的then的回调会进入微任务队列”这个底层机制,这类题就不容易错。我当时复习时是把任务队列相关的机制完整梳理了一遍,包括process.nextTickasync/await在微任务中的处理,后来看到类似题目基本能秒出答案。

原型链相关的题也考了,核心就是原型链查找机制。比如实现一个instanceof的手写版本,代码不复杂,但要求你理解原型和原型链的关系。还有一类常考的是new操作符执行过程中发生了什么,以及手写一个new的模拟实现,这里有一个关键点很多人会漏,就是构造函数如果返回了一个对象,那么new表达式的值是这个对象,而不是this

闭包题的出题方式也值得说一下。用友考了一道结合循环和异步的经典闭包陷阱题,问的是用var声明循环变量时,点击某个元素输出什么,以及如何修复它。这个题目之所以高频,是因为它同时考察了闭包、作用域、事件处理机制和异步延迟执行,一道题能卡掉一部分基础不牢的人。

2.2 CSS与布局:经典布局题是送分题也是必考题

CSS部分用友考得不难,核心集中在三块:布局、选择器优先级、盒子模型与BFC。其中布局题基本是必考的,常见的就是两栏和三栏布局。我当时遇到的是要求实现一个左侧固定宽度、右侧自适应的两栏布局,并且要求右侧内容区高度与左侧一致。

这种题有至少四种解法:float + marginflex布局、grid布局、绝对定位加left偏移。我建议至少掌握前两种,因为面试官可能会追问:flex和float在实现这种布局时有什么本质区别?flex有没有兼容性问题?在某些老版本浏览器里,flex处理方案不如float稳定,但在现代浏览器里它是最推荐的常规做法。

BFC(块级格式化上下文)是另一类高频题。它通常不会直接考名词解释,而是给你一个场景,比如“子元素设置了margin-top,结果父元素跟着一起位移了,怎么解决”,本质考的就是如何触发BFC。常用的触发条件包括:设置overflowhidden/autodisplay: flexdisplay: inline-blockposition: absolute/fixed等。这道题的排查思路其实在实际项目里也很有用,遇到margin穿透或者浮动塌陷的问题,第一时间就该想起BFC。

2.3 浏览器机制:缓存、跨域、渲染流程是重头戏

浏览器相关的考点里,HTTP缓存机制是用友非常喜欢考的。它通常给出几个字段:Cache-ControlExpiresETagLast-Modified,然后问你浏览器缓存的判断顺序,以及强缓存和协商缓存的区别。复习的时候我建议把整个缓存链路整理成一张流程图:浏览器发起请求,先检查强缓存命中没有,命中就直接用本地缓存,没命中就发请求,服务器通过ETagLast-Modified判断协商缓存,返回304或200。

跨域问题也是必考项。用友的题考了JSONP的原理、CORS的配置方式,以及postMessage在前端跨域通信里的使用场景。这里有一个特别注意点:JSONP只能支持GET请求,因为它的底层原理是动态创建<script>标签加载外部脚本,而script标签的加载天然不受同源策略限制。这个细节很容易被忽略,但答出来会显得你对跨域方案的边界条件理解得很清楚。

浏览器渲染机制那道题是让我印象比较深的,它给了一段HTML和CSS,问回流和重绘分别发生在哪些步骤。这里有一个很重要的点:display: nonevisibility: hidden对回流重绘的影响是不同的。前者会元素从渲染树中移除,触发回流和重绘;后者只改变元素的可见性,元素仍然占据空间,所以只触发重绘。实际项目里做性能优化,尽量用visibility替代display的切换,或者用transform动画替代top/left位移动画,都是为了减少回流次数。

3. 框架与工程化:Vue主导下的组件化和架构思维

3.1 Vue 2/3核心机制:响应式原理是绕不开的题眼

用友的前端技术栈以Vue为主,尤其在很多老项目里Vue 2的存量非常大,但新项目已经普遍转向Vue 3了。所以笔试题目里Vue 2和Vue 3的内容都会涉及,尤其是响应式原理的对比。

关于这个考点,我当时整理的核心差异是这样的:Vue 2通过Object.defineProperty对数据进行劫持,只能拦截对象属性的读取和修改,无法监听新增属性和数组索引的变化,所以才有Vue.set$set这样的API来补充。Vue 3改用Proxy代理整个对象,天然支持新增属性和索引访问的拦截,同时配合Reflect保证原生的捕获器行为不出现偏差,这也是Vue 3弱化$set的根本原因。

下面是一个简化的响应式实现思路,主要用来理解核心机制:

// Vue 3响应式核心的思路简化版 function reactive(obj) { return new Proxy(obj, { get(target, key, receiver) { // 依赖收集:读取时记录谁在用这个值 track(target, key); return Reflect.get(target, key, receiver); }, set(target, key, value, receiver) { const result = Reflect.set(target, key, value, receiver); // 依赖触发:值变化了,通知所有用这个值的地方更新 trigger(target, key); return result; } }); }

笔试考到这种题,一般不会让你手写完整源码,但会让你判断“给一个对象新增属性后,页面数据是否会更新”,以及解释原因。懂了ProxyObject.defineProperty的差异,这类题就很稳。

3.2 组件通信与状态管理:一道场景题串起所有方案

用友笔试里有一道场景设计题:在一个后台管理系统中,有一个父组件管理用户列表,子组件负责展示用户详情,兄弟组件负责筛选用户条件,问有哪些组件通信方案,各自的适用场景是什么。这种题就是考察你对组件通信全貌的掌握程度。

常见的组件通信方式我整理了一个表格:

通信场景推荐方案适用说明
父子组件props/$emit(Vue 2)或defineProps/defineEmits(Vue 3)结构清晰,适合单向数据流
父子组件深层嵌套provide/inject适合祖先组件向所有后代组件提供数据
兄弟组件/跨级组件事件总线(Vue 2)/mitt(Vue 3)适合简单场景,组件数量少时使用
全局状态Vuex / Pinia适合管理登录状态、权限信息、全局配置等
跨应用postMessageCustomEvent适合微前端架构下不同子应用通信

我当时在回答这道题的时候,额外提到了一个经验:不要动不动就把所有通信都用全局状态管理来做,很多只需要父子组件传值的场景用props+emit就够了。全局状态管理引入后,如果滥用,项目里会出现一堆“状态不知道从哪里来、在哪里被修改”的问题,定位bug的成本会直线上升。在企业级B端项目里,状态管理的核心作用是管理全局性的、跨组件的关键状态,而不是替代组件通信。

3.3 前端工程化:打包优化、微前端、低代码平台

工程化这块的题量明显比一般的C端公司笔试要多。用友毕竟是做企业级平台的,它非常关心你有没有真正负责过一个大型前端项目的构建和维护。

构建优化是必问的。问题一般是“你的项目首屏加载太慢,如何排查和优化”。标准答案大概包括:路由懒加载、UI组件库按需引入、第三方库拆包、启用CDN缓存、图片压缩、开启gzip压缩、代码分割等等。但如果只是背这些点,大概率只能拿基础分。我建议准备一两个实际用过的优化案例,比如我把某个大型表单页的包体从1.5MB优化到了400KB,具体是怎么做按需引入的,优化后首屏时间从3秒降到了1.5秒。这种有数据支撑的回答,在面试环节会更占优势。

微前端也是用友这类多系统集成型公司比较喜欢的考点。笔试里会以选择题形式考察:多个前端应用如何实现统一登录、如何共享公共组件、子应用之间如何通信。这背后其实是一套完整的微前端架构,包括主应用和子应用的注册机制、路由匹配规则、沙箱隔离策略,以及公共依赖的上层抽取。如果之前没接触过微前端,建议至少把single-spaqiankun的核心概念过一遍,理解它们是怎么做应用加载和JS沙箱隔离的。还有今年连续火起来的module federation方案,它比qiankun更轻量,是另一条值得了解的路线。

低代码/配置化平台这个方向,在笔试里不一定会出大题,但选择题里会带一点“表单配置化渲染”的内容。毕竟用友的产品线里有大量表单和列表页面,如果能实现配置化生成,开发效率会高很多。我建议复习时了解一下动态表单和JSON Schema驱动的页面渲染方案,对这类题会很有帮助。

4. 算法与手写编程题:高频题型与考场上的解法策略

4.1 两道编程题的复盘:数据结构题和业务场景题的组合

用友笔试的两道编程题,一道偏数据结构算法,一道偏业务场景模拟,难度大概是LeetCode中等偏下。这是我印象比较深的一个组合。

第一道题我遇到的是“数组中第K个最大元素”。这题正常情况下用最小堆维护大小为K的堆,堆顶就是答案;或者直接用快速选择算法平均O(n)解决。我当时用JavaScript手写了快速选择,因为JavaScript本身没有内置堆结构,如果临时实现一个堆反而容易出错。这里提一个考场小技巧:如果你对快速选择理解得不够透彻,直接用sort排序然后倒序取第K个也是能过的,虽然时间复杂度差一些,但在笔试数据的规模下通常没问题。考试的目标是拿分,不是炫技。

第二道题是偏业务的模拟题:给定一组员工数据(包含姓名、部门、薪资),要求按部门分组,并在每个部门内按薪资降序排列,输出每个部门薪资最高的员工信息。这道题本质就是考察数组API的熟练度和对象操作的严谨性,用Array.prototype.reduce做分组,再用sort排序,逻辑清晰。

不过这个题里有一个坑,就是排序的稳定性。JavaScript的Array.prototype.sort在V8引擎中是稳定排序,但如果你依赖“原顺序”来作为次级排序条件,建议在比较函数里显式写好,不要赌默认行为。另外,边界情况——比如空数组、所有薪资相同、部门字段缺失——也要考虑进去。我在写的时候额外加了数据过滤和空值判断,这种细节在业务场景模拟题里往往是加分项。

4.2 手写题:防抖节流、Promise.all、深拷贝

除了编程题,简答或手写题部分出现了三件套:防抖节流、Promise.all、深拷贝。这三道题属于前端手写题的常青树,基本每个认真准备过前端面试的人都会背,但背和写对是两回事。

防抖节流这道题,关键点是理解两者的区别。防抖是在事件触发后等待一段时间再执行,如果在这段时间内再次触发,就重新计时;节流是保证在一段时间内只执行一次。业务上典型场景:搜索框输入用防抖,页面滚动或窗口resize用节流。下面是我当时手写的版本:

// 防抖:多次触发只执行最后一次 function debounce(fn, delay = 300) { let timer = null; return function (...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); timer = null; }, delay); }; } // 节流:一段时间内只执行一次 function throttle(fn, interval = 300) { let last = 0; return function (...args) { const now = Date.now(); if (now - last >= interval) { last = now; fn.apply(this, args); } }; }

这里有一个细节:很多人在手写防抖节流的时候忽略了this指向的处理。如果不做fn.apply(this, args),在对象方法里调用时this会丢失。笔试题如果考察到“能否正确处理this指向”,这里就是切分水平的地方。

Promise.all手写题的核心是并发处理与错误处理。关键点有三个:返回一个Promise、所有输入Promise都成功才resolve且结果顺序要跟输入顺序一致、任意一个失败就直接reject。实现的时候,要用一个计数器记录已完成的数量,而不是用数组的length,否则数组中间的空位会导致误判。

深拷贝这道题看似基础,但很多人在处理循环引用时翻车。常规做法是用WeakMap记录已经拷贝过的对象,遇到重复引用时直接返回已有的拷贝,避免无限递归。还需要区分数组、普通对象、Date、RegExp等常见类型。如果只是用JSON.parse(JSON.stringify(obj)),遇到undefinedfunctionSymbol、循环引用都会出问题,所以在笔试里这道题其实是在考察边界意识。

4.3 算法复习的侧重点:高频题型比刷题量更重要

如果你时间有限,我强烈建议算法复习围绕这几类展开:数组和字符串操作、哈希表应用、双指针、链表、二叉树基础遍历、动态规划入门、排序算法复杂度。用友这类公司更看重你“会用数据结构和算法解决实际问题”,而不是出竞赛级别的题目。

另外,刷题的时候尽量用JavaScript写,不要用Python或Java刷完就跑了。因为很多公司的笔试系统里主语言是JavaScript,你用其他语言写熟了,到实际笔试时再切换到JS手写,会有明显的生疏感。我当时就有这个教训,前期刷题用Python特别顺手,一到JS手写就卡壳,后来强制自己所有题都用JS写两遍,才慢慢适应。

5. 计算机基础与开放类题目:容易被忽视的得分项

5.1 网络基础:TCP、HTTP状态码和HTTPS握手

计算机基础部分,用友考得不算深,但覆盖了不少网络协议的知识点。TCP的三次握手和四次挥手是常客,HTTP状态码也有涉及。这些题目本身不复杂,但我发现很多前端同学在这块是短板,因为平时写业务代码根本接触不到底层网络细节。

HTTP状态码建议把常见分类记住:1xx是信息性状态码,2xx表示成功,3xx表示重定向,4xx是客户端错误,5xx是服务端错误。其中容易混淆的几个是:301永久重定向和302临时重定向,304协商缓存命中,403禁止访问和404未找到的区别,以及502和504的逻辑差异。这些选择题里会出现,而且在实际项目联调接口时也经常用得上。

HTTPS握手流程这道题,考察点在对称加密和非对称加密如何配合。简单理解就是:先用非对称加密协商出一个临时对称密钥,之后通信都用对称加密,兼顾了安全性和性能。如果你能把这个逻辑讲清楚,分数基本就拿到了。

5.2 数据结构与操作系统边缘考点

数据结构部分没有考复杂算法,主要是对栈、队列、二叉树这些基础概念的理解。比如栈的“后进先出”特性如何应用到函数调用栈和浏览器的“前进后退”功能,队列的“先进先出”特性如何应用于任务队列。这类题目只要你大学课程没白学,基本能答对。

操作系统部分考了进程和线程的区别,以及进程间通信的基本方式。这题对于前端同学来说可能有点偏,但如果你了解浏览器的多进程架构,答这类题其实不难。浏览器的每个标签页本质是一个进程,渲染、GPU、网络等线程在进程内各司其职,这个知识架构本身就是对进程线程关系最好的实践理解。

5.3 行为面题目:项目经历的呈现方式

笔试里的开放题一般会让你写一两段关于项目经历的内容。问法大概是“简述一个你最熟悉的项目,遇到的最大难点是什么,如何解决的”。这道题看似随便写写就能过,但它实际上是筛选人的关键题之一。因为笔试环节没有面试官追问,你写的每一段话就是你这轮印象的全部来源。

我的建议是使用STAR原则来组织:情境(Situation)说明项目背景,任务(Task)说明你的职责,行动(Action)说清楚你具体做了什么技术选型和方案落地,结果(Result)给出量化指标。比如“重构了三个核心表单页面,通过封装通用表单组件和配置化方案,将同类页面的开发周期从3天缩短到1天”。这种表述在面试官眼里会非常有说服力,因为它的核心是“你有能力把复杂问题简化成可复用的方案”,这恰恰是企业级B端场景最需要的能力。

6. 经验复盘:复习路线、考场策略与避坑指南

6.1 复习时间线与核心资料

如果从零开始准备这类B端公司前端笔试,我建议至少留出四周时间。第一周用来梳理前端基础八股文,包括JS、CSS、浏览器机制,把自己最薄弱的模块先过一遍;第二周集中刷框架题和工程化题,Vue全家桶的底层原理要吃透;第三周算法和手写题为主,力扣按标签刷,每天保证三到五题;第四周进入模拟笔试状态,找整套前端笔试题练手,训练时间分配和手写代码的稳定性。

资料方面,前端八股文汇总、力扣热题100、Vue官方文档和源码解析文章是我认为性价比最高的三项。如果时间很紧,宁可少刷一些偏题怪题,也要把高频基础题反复做熟,毕竟笔试里基础题的占比远大于困难题。

6.2 考场上最容易踩的坑

第一个坑是时间分配失衡。选择题里总有那么两三道比较偏,容易让你较劲。我的做法是:标记跳过,绝不恋战。两道编程题的分值远高于几道选择题,编程题写不出来,选择题答得再好也是白搭。

第二个坑是代码细节。在线笔试的代码编辑器一般不会给你完整的自动补全,手写代码时语法错误很容易出。所以平时练习时尽量少依赖IDE的自动补全,尤其是在写sort的比较函数、reduce的累加器和各种API的参数顺序时,一个简单的拼写错误就会导致整个程序跑不通。

第三个坑是审题不清。业务场景模拟题往往藏着一两个边界条件,比如空值处理、排序稳定性、重复元素去重。很多同学题目看了一半就开始写,写完才发现漏了要求,返回去改又浪费时间。我建议先花两三分钟把题目彻底读透,把输入输出的边界列出来,再动手写代码。

6.3 给下一届同学的建议:用友笔试之后还有面试

笔试只是第一关,通过了之后还有一至两轮技术面和一轮HR面。技术面会围绕笔试里的薄弱点和项目经历展开追问,比如你在笔试里写了“深拷贝”,面试官就可能让你现场写一遍,并追问循环引用怎么处理、Symbol属性要不要拷贝。所以笔试里出现过的题目,考完之后一定要复盘,把它变成自己能讲清楚的知识点,否则面试时被追问答不上来,反而暴露短板。

HR面则更看重你的职业规划、稳定性、团队协作能力和对用友业务的了解程度。面试前建议花点时间上官网看一下用友的核心产品线,了解它是做企业服务软件的公司,明白这类公司的业务流程和技术形态,面试时能聊出一些自己的理解,会和其他候选人拉开差距。

我个人在复盘这场笔试时最大的体会是:这场笔试并没有故意刁难人,它考察的每一项能力——JS基础、框架原理、工程化经验、算法的基本套路、项目中的问题解决能力——都是日常前端工作中真实会用到的东西。只要在校招季之前踏踏实实把基础打牢,把项目经历真正做完做深,通过这场笔试并没有想象中那么玄乎。希望这篇复盘能帮你在准备过程中少走一些弯路。

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

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

立即咨询