拓冰建站拓冰建站
首页 / 资讯中心 / 正文

2023用友秋招Java岗笔试真题解析:考点拆解与备考攻略

每年秋招季Java岗的笔试题都绕不开几个大厂的固定套路用友集团的这套卷子算是比较典型的代表题量适中、难度梯度明显、既考基础又考工程实践。整个笔试内容覆盖了Java基础语法、集合框架、JVM与并发、Spring生态以及算法手写几乎把校招Java岗需要掌握的核心知识点全部过了一遍。这篇文章我就结合2023年用友集团秋招Java岗笔试的真实题型和考察重点逐块拆解考点背后的原理和答题思路既是复盘也是给后面备考的同学一份比较完整的参考。先说下这套卷子适合谁看正在准备Java后端校招的应届生、想系统梳理Java基础知识的初级开发者以及打算跳槽但想先摸摸底的在职工程师。即使你不投用友这套知识框架也是国内中大厂Java校招的通用标尺吃透它能省下大量盲目刷题的时间。1. 用友秋招Java笔试的整体结构与备考定位1.1 笔试形式与时间安排用友2023秋招Java岗的笔试采用的是在线笔试平台大部分技术岗统一安排在一个时间段内完成通常持续90到120分钟。题型结构比较稳定选择题单选多选占大头最后附2到3道编程题。选择题侧重Java基础、集合、并发、JVM和Spring框架编程题以数据结构与算法为主偶尔会出现一道与业务场景结合的设计类代码题。时间分配是很多人的痛点。我见过不少同学前面的选择题反复纠结结果最后编程题只剩十几分钟连暴力解法都没写完。我的建议是选择题每道控制在1分钟内拿不准的先标记跳过编程题至少留出40分钟。因为编程题往往是按测试用例给分的哪怕只过一部分用例也比空着强。1.2 考点分布与性价比分析从这套卷子可以看出用友的考点分布和互联网大厂略有区别更偏向企业级应用开发所涉及的Java核心能力而不是纯粹的数据结构和算法竞赛。个人统计下来大致比例如下考点模块大致占比复习性价比Java基础语法与面向对象20%高拿分快集合框架15%高高频考点集中JVM与内存模型15%中高理解后不容易忘多线程与并发15%中高面试也必考Spring/Spring Boot框架10%中需要理解设计思想算法与数据结构20%高编程题直接决定上限其他网络、数据库、Linux等5%视剩余时间取舍这里想多说一句很多人复习时爱钻研偏题怪题结果基础题却丢分非常可惜。用友这套卷子的选择题难度并不算高很多是概念辨析和代码结果判断题换句话说基础扎实的同学拿高分很容易基础不牢靠的同学就算刷了大量难题也会在简单题上翻车。2. 面向对象与Java语法基础最容易被忽视的送分题2.1 面向对象三大特性的考察角度用友笔试里面向对象的题目不会直接问“什么是封装”而是通过代码片段让你判断输出结果或者让你识别代码违反了哪些设计原则。比如典型的多态考题父类引用指向子类对象调用一个父子类都有的实例方法输出的到底是父类还是子类的结果。这类题考察的是动态绑定机制关键在于理解“编译看左边运行看右边”。重载与重写的区别也是选择题常客。我印象很深的一道题是给定几个方法签名问哪些构成合法重载哪些是重复定义。很多人会把返回值类型不同当作重载的充分条件这是错的——重载只要求参数列表不同返回值类型不参与方法签名。如果把这道题想明白了类似变体题都不会出错。继承中的构造方法调用顺序也经常出现。考察点在于子类构造前必须先调用父类构造如果父类没有无参构造子类必须显式用super调用。这个知识点还会连带考察静态代码块、实例代码块和构造方法的执行顺序。我建议把这个顺序背下来父类静态块子类静态块父类实例块父类构造子类实例块子类构造。2.2 枚举、泛型、Lambda与异常处理这些语法细节在选择和编程题里都有体现。枚举在笔试中通常考察其本质——它本质上是一个继承了java.lang.Enum的final类所以枚举不能继承其他类但可以实现接口。用友这道题里给了一个带构造器和抽象方法的枚举问编译是否通过实际上是在考枚举能不能定义抽象方法。答案是能因为枚举可以定义抽象方法由每个枚举常量分别实现。泛型则爱考类型擦除。比如问List 和List 在运行时是不是同一个类型答案是同一个因为泛型信息在编译期就被擦除了。还有泛型上下限通配符的题目比如List? extends Number和List? super Integer分别能往里面添加什么类型。前者不能添加任何元素除了null后者可以添加Integer及其子类。这个知识点光背结论容易忘理解“生产者extends消费者super”的PECS原则之后答题会稳很多。Lambda表达式相关的题目经常会和函数式接口绑在一起。题目会问下面哪个接口可以用Lambda表达式实现答案必须同时满足两个条件接口只有一个抽象方法即函数式接口且接口上有FunctionalInterface注解或者虽然没有注解但只有一个抽象方法。Runnable、Comparator、Callable都是常见的函数式接口而Comparator因为还有equals等Object方法但equals是Object的public方法不算抽象方法所以它依然是个函数式接口可以写Lambda。异常处理考察的点比较集中受检异常和非受检异常的区分、try-catch-finally的执行顺序、try-with-resources的关闭顺序。有一个容易错的点如果catch和finally里都有return那么finally里的return会覆盖catch里的return。还有如果 finally 里抛出了新异常它会覆盖原始异常。这些看似边缘的细节恰恰是用友这种笔试喜欢挖坑的地方。3. 集合框架存储结构与源码级别的判断力3.1 HashMap的底层实现与扩容机制HashMap是用友Java笔试几乎必考的内容也是Java集合框架里最值得花时间深挖的一个点。它不仅考你背下来的结论还会通过代码题和场景判断题来考察你对底层实现的理解程度。核心知识点包括HashMap底层是数组链表红黑树的结构。当链表长度超过8且数组长度大于等于64时链表会树化成红黑树当红黑树节点数小于6时会退化成链表。这里有个容易被反问的细节为什么转红的阈值是8因为遵循泊松分布在负载因子0.75的情况下链表长度达到8的概率已经极低约千万分之一用8作为阈值是时间和空间的权衡结果。扩容机制也常考。HashMap初始容量是16负载因子默认0.75也就是说当元素个数超过16*0.7512时会触发扩容容量翻倍到32。jdk1.7是头插法并发扩容时可能出现循环链表jdk1.8改成尾插法避免了这个问题但HashMap依然不是线程安全的并发场景得用ConcurrentHashMap。笔试的选择题就爱考“以下哪些说法正确”上面任何一个细节没掌握都可能丢分。再提一个容易忽略的点HashMap允许key为nullkey为null时存放在table[0]位置。而Hashtable和ConcurrentHashMap都不允许key为null。很多人知道这个结论但不知道为什么本质上是因为ConcurrentHashMap在并发环境下无法区分“没有这个key”和“key对应的value为null”这两种情况所以干脆禁止null。3.2 ArrayList与LinkedList的适用场景这个考点看起来简单但用友真题里出现了结合源码的变体。题目问以下哪个操作在LinkedList上比ArrayList更快很多人条件反射地选“插入”但忽略了“指定位置的插入”其实两者都需要遍历ArrayList虽然插入是数组拷贝但定位是O(1)LinkedList插入虽然只是改指针但定位是O(n)。准确的说法是LinkedList在头部插入和删除更快ArrayList在尾部插入和随机访问更快。还有一个常考的点ArrayList扩容。初始容量10添加元素超过容量时扩容为原来的1.5倍int newCapacity oldCapacity (oldCapacity 1)。这里有个面试官也爱问的细节为什么不是2倍而是1.5倍因为1.5倍的扩容更节省内存扩容次数也相对可控是空间和时间的一个折中。笔试里可能直接问“ArrayList扩容后的容量是多少”注意是1.5倍不是2倍。3.3 Comparable与Comparator的辨析用友的选择题里出现过这样一道题对一个对象数组排序对象实现了Comparable接口问排序结果。这类题考察的是两种比较器的使用场景Comparable是自然排序定义在实体类内部只能有一个实现Comparator是定制排序定义在类外部可以定义多个。用Comparator.comparing可以链式组合多个排序条件比如先按年龄排序再按姓名排序。这里顺便提一下热词里出现了快速排序java实现和冒泡排序java这说明排序算法也是笔试和面试的共同重点。用Collections.sort或者Arrays.sort时底层其实会根据数据类型和规模选择不同的排序算法比如对象数组用TimSort基本类型数组用DualPivotQuickSort。了解这些能帮你回答“为什么Arrays.sort比你自己写的快排还快”这类进阶题。4. JVM与并发笔试中拉开差距的硬骨头4.1 JVM内存区域与垃圾回收JVM这块是Java笔试的深水区也是用友这套卷子中选择题难度较高的部分。考察内容分为两大块内存区域划分和垃圾回收机制。内存区域的题目通常以代码题形式出现给一段代码问里面创建的对象分别分配在哪个区域。核心结论是绝大部分对象分配在堆上但通过逃逸分析如果对象不会逃逸出方法可能被分配在栈上栈上分配这是JIT的优化手段。线程共享的区域是堆和方法区在HotSpot中方法区以元空间Metaspace实现jdk1.8之后字符串常量池移到了堆中线程私有的区域是虚拟机栈、本地方法栈和程序计数器。垃圾回收的重点在于判断对象是否可回收。引用计数法有循环引用问题所以HotSpot用的是可达性分析算法从GC Roots出发遍历不可达的对象才会被回收。哪些对象可以作为GC Roots虚拟机栈中引用的对象、方法区中静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象以及被synchronized持有的对象。笔试容易挖坑的点是两个对象相互引用但都和GC Roots断开问能不能被回收。答案是可以因为可达性分析不受循环引用影响。垃圾收集器的题目一般会问CMS和G1的区别。G1是分Region的收集器把堆划分为多个大小相等的Region维护一个优先列表每次根据允许的停顿时间选择回收收益最大的Region实现了可预测的停顿时间。而CMS是标记-清除算法会产生内存碎片。这里有一道经典面试题G1是分代收集器吗答案是G1保留了年轻代和老年代的概念但物理上不再连续仍然是分代收集器。4.2 类加载机制与双亲委派类加载机制这块笔试常考双亲委派模型。题目形式一般是给出一个类的加载过程问某个步骤发生在哪个阶段或者问“打破双亲委派的应用场景有哪些”。核心流程是一个类加载器收到加载请求后先不自己加载而是委托给父类加载器一直往上委托到Bootstrap ClassLoader父类加载器无法加载时才向下返回。打破双亲委派的经典场景是Tomcat的WebAppClassLoader因为每个Web应用需要加载自己版本的同名类所以它先自己加载加载不到才委托父类。还有一个经典案例是JDBC的DriverManager它用了线程上下文类加载器来加载数据库驱动这也属于打破双亲委派的一种。笔试里如果问“你觉得双亲委派模型有什么缺点”回答就是“父类加载器无法加载子类加载器路径下的类”这个答案比单纯背流程更得分。4.3 线程池的核心参数与执行流程线程池是并发部分的重头戏用友笔试对这块的考察非常具体会直接给出七个参数问某个场景下线程池的行为。核心参数要能背得滚瓜烂熟corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime线程存活时间、unit时间单位、workQueue任务队列、threadFactory线程工厂、handler拒绝策略。执行流程是这样的提交任务时如果当前线程数小于corePoolSize创建新线程执行如果大于等于corePoolSize加入阻塞队列如果队列满了且线程数小于maximumPoolSize创建新线程执行如果线程数已经达到maximumPoolSize执行拒绝策略。拒绝策略有四种AbortPolicy直接抛异常、CallerRunsPolicy调用者线程执行、DiscardPolicy直接丢弃、DiscardOldestPolicy丢弃队列中等待最久的任务。笔试容易考的一个场景是线程池的corePoolSize2maximumPoolSize5队列容量3一次性提交8个任务问最终有多少个任务在同时执行。答案是5个因为第6个及以上任务会进队列队列容量3第9个才会触发拒绝策略。这类题只要理解了流程基本就是送分题。4.4 synchronized、volatile与Lock并发的另一个高频考点是synchronized和volatile的区别。synchronized保证原子性、可见性和有序性volatile只保证可见性和有序性不保证原子性。笔试里常见的代码题是多个线程对volatile修饰的int变量执行i操作问最终结果是不是一定是10000。答案是不是因为i不是原子操作volatile无法保证复合操作的原子性。这里要注意区分——volatile保证的是每次读取都从主内存读但读-改-写三步之间依然可能被其他线程打断。synchronized在jdk1.6之后引入了锁升级机制无锁、偏向锁、轻量级锁、重量级锁。这个升级过程是单向的只能从低到高不能降级。轻量级锁通过CAS来获取锁竞争激烈时会膨胀为重量级锁重量级锁依赖操作系统的监视器锁monitor实现涉及用户态和内核态切换性能相对较差。AQS是ReentrantLock的基础核心是一个volatile的state变量和一个CLH双向队列。这套体系理解了并发选择题基本全覆盖。5. Spring生态与工程实践考点脱离纯语言层面的考察5.1 Spring IoC与AOP的理解深度用友毕竟是以企业级应用为核心业务的公司Spring框架的考察自然不可少。IoC和AOP是Spring的两大核心选择题通常在概念辨析和运行机制两个层面出题。IoC控制反转这一块除了要知道“容器负责创建和管理对象”之外还要能说清楚Bean的生命周期实例化、属性填充、初始化InitializingBean接口、PostConstruct注解、init-method、使用、销毁。笔试里有一道常见的排序题一个Bean的构造方法、PostConstruct方法、InitializingBean.afterPropertiesSet方法和init-method的执行顺序是什么。正确的顺序是构造方法 - PostConstruct - afterPropertiesSet - init-method。这个顺序很多人记不清其实是按照Spring处理这些回调的先后阶段来记忆的先属性填充完成后再执行自定义初始化回调。AOP的考察重点是动态代理的两种实现方式JDK动态代理和CGLIB代理。默认情况下如果目标类实现了接口Spring用JDK动态代理如果没有实现接口用CGLIB。但如果配置了proxyTargetClasstrue则强制用CGLIB。Spring Boot 2.x之后AOP默认使用CGLIB代理即使类实现了接口。这个知识点在选择题里经常以“以下关于Spring AOP说法正确的是”出现最容易挖坑的就是代理方式的选择。5.2 Spring Boot自动配置的本质Spring Boot的自动配置是近年笔试的热门考点。核心注解是EnableAutoConfiguration它通过Import导入AutoConfigurationImportSelector这个Selector会扫描所有jar包中META-INF/spring.factories文件里配置的自动配置类。每个自动配置类通常带有ConditionalOnClass、ConditionalOnProperty等条件注解只有满足条件时才会生效。笔试常考的一个变体是问某个自动配置类在什么条件下会生效。比如DataSourceAutoConfiguration只有当classpath下存在javax.sql.DataSource并且没有用户自定义的DataSource Bean时才生效。这就是“约定优于配置”的体现。我在实际做项目时也用到了这个原理自己写一个starter通过spring.factories暴露自动配置类实现中间件的零配置接入。理解自动配置机制后遇到“为什么我引入了依赖但没有生效”这类问题排查思路会清晰很多。5.3 Maven、Git与环境变量等工具链细节热词里出现了很多关于Java环境配置、java环境变量配置的搜索说明不少同学在笔试前连本地的Java开发环境都没完全搞定这其实是很吃亏的。用友的笔试虽然是线上完成但如果本地没有安装JDK、没有配置好JAVA_HOME你在练习编程题时会遇到各种莫名其妙的问题比如命令行编译直接报“javac不是内部或外部命令”。关于环境变量JAVA_HOME要指向JDK的安装目录PATH里要加上%JAVA_HOME%\binCLASSPATH一般不需要手动设置了。热词里还有一个具体报错java: 警告: 源发行版 17 需要目标发行版 17这个error在实际开发中经常遇到原因是本机JDK版本和项目编译版本不一致。解决办法是在pom.xml或者build.gradle中统一source和target的版本或者在IDEA的Settings - Build Tools - Maven - Runner里把JRE版本调成一致。笔试不会直接考这种报错但如果你是提前在本地练题时遇到了能自己解决也是一种工程能力。Maven的考察点主要是依赖管理机制坐标groupId、artifactId、version、依赖传递、依赖冲突解决就近原则、第一声明优先、scope的含义compile、provided、runtime、test、system。Git主要考分支操作和回退命令比如git reset和git revert的区别。这些都是日常开发中反复用到的东西笔试里出现也不意外。6. 算法题与手写代码性价比最高的冲刺点6.1 冒泡排序与快速排序的手写能力用友笔试的编程题不会故意为难人但基础的排序算法必须能手写出来。热词里冒泡排序java和快速排序java实现搜索量很高说明这是很多人的薄弱点。以我个人的经验来看突击复习算法时与其背一堆花哨的算法模板不如把几个经典算法练到肌肉记忆的程度因为笔试场景下手写代码本身就容易紧张熟悉度不够基本上写不对。冒泡排序是最基础的排序算法虽然实际开发中几乎用不到但笔试中可能作为编程题的基础步骤出现。手写时注意两点一是每轮比较后最大的数会沉到末尾二是优化点——如果某轮没有发生交换说明已经有序可以提前退出。快速排序的写法有递归版和迭代版。我推荐掌握递归版因为它代码更清晰不容易写错。快排的关键是partition函数选基准pivot、从右向左找比基准小的、从左向右找比基准大的、交换最后把基准放到正确位置。这里有一个很多人容易忽略的细节如果pivot选择的是最左边的元素那么必须先从右边开始扫描否则会覆盖pivot的正确位置。这个细节一旦写错整个排序结果都会乱掉。6.2 高频算法模板链表反转、二分查找与字符串处理算法题里链表的题出现频率极高。反转链表是最基础的有迭代和递归两种写法。迭代写法的核心是三个指针prev、curr、next每次把curr.next指向prev然后整体后移。递归写法更简洁但理解门槛稍高核心思想是假设后面的链表已经反转只需要调整当前节点的指针。建议两种都练熟因为笔试场景下如果时间充足可以用迭代写如果对递归有信心递归写起来更漂亮。二分查找也是高频考点。用友的编程题出现过在有序数组中查找目标值左右边界的变体。这里的关键在于边界条件的处理while循环是left right还是left right缩边界时mid1还是mid。我总结了一个简单可靠的模板public int binarySearch(int[] nums, int target) { int left 0, right nums.length - 1; while (left right) { int mid left (right - left) / 2; if (nums[mid] target) { return mid; } else if (nums[mid] target) { left mid 1; } else { right mid - 1; } } return -1; }注意mid的写法用left (right - left) / 2而不是(left right) / 2因为后者在left和right都很大的时候可能溢出。这类细节在笔试阅卷时虽然不会逐一检查但写成这样本身就体现了你的代码素养。字符串处理题通常考察StringBuilder的使用和双指针技巧。热词里出现的java中数组越界异常在算法题中也非常常见——比如字符串转字符数组之后遍历下标没有控制好就会抛ArrayIndexOutOfBoundsException。我建议在写循环时养成一个习惯凡是涉及到数组或字符串索引先确认边界条件再写循环体。6.3 刷题策略与临场答题习惯笔试编程题和面试手撕代码最大的区别在于没有人和你互动你只能靠自己。这就要求你在刷题时养成“一气呵成”的习惯。我推荐按专题刷题先数组、字符串、链表再二叉树、动态规划最后再练习一些常见的贪心和回溯问题。每个专题刷10到15道题不求数量多但每道题都要完全理解并能独立写出来。临场答题时有一个很实用的技巧先读题目确认输入输出格式然后先在草稿纸上写几个测试用例推演一遍思路再开始写代码。写完代码后一定要自己手动过一遍测试用例包括边界情况。这个步骤很多人会跳过结果上了考场才发现代码有逻辑漏洞白白丢分。笔试判题通常只看最终通过率不会在意你调试过程写了什么所以确保提交前代码能跑通大部分用例才是最重要的。7. 复盘与备考建议踩过的坑和亲测有效的路线7.1 备考时间线与节奏安排现在回头看我踩过最大的坑就是一开始没有制定系统性的复习计划而是东一榔头西一棒子地刷题导致前面学后面忘。如果你还有2到3个月的准备时间我建议把复习分成三个阶段第一阶段2-4周系统性过Java基础。以《Java核心技术卷I》或者高质量的基础视频为教材把面向对象、集合、异常、泛型、IO、反射这些基础内容吃透。每个知识点都要动手写代码验证不要只停留在“能看懂”的层面。这个阶段结束后你应该能达到“看到一个类名就能说出它的常用方法和底层结构”的程度。第二阶段2-3周集中突破JVM、并发和Spring。这三个模块是笔试中难度最高、分值最重的部分。建议搭配《深入理解Java虚拟机》和《Java并发编程的艺术》这两本书的关键章节来学习。Spring部分可以配合官方文档和实际项目演示来理解不用背源码但要能说出核心设计思想。第三阶段2-3周刷题和模拟笔试。每天固定做2到3道算法题保持手感。每周至少做一次完整的模拟笔试限定时间检验自己的各模块正确率。模拟笔试的结果能帮你精准定位薄弱点然后进行针对性补强。7.2 现场答题的注意事项笔试当天的发挥往往比平时的积累更重要。有几个细节我想特别提醒第一在线笔试平台最好提前半小时进入检查摄像头、浏览器、网络连接。千万不要因为网络卡顿导致交卷失败这种低级失误每年都有人犯。第二选择题中遇到不会的题不要死磕先标记最后有时间再回头想。特别是多选题选错一个可能就全扣分不确定的选项宁可不选。我见过很多人对多选的规则不熟悉结果多选了一个错误选项导致整题零分非常可惜。第三编程题一定要先确认输入输出格式。有些题目的输入是一个数组有些是多行输入有些需要处理到文件尾这些细节一旦搞错代码逻辑再正确也无法通过测试用例。我通常的习惯是先用简单的输入样例手动模拟一遍代码运行确认输入输出匹配再提交。第四编程题的命名和注释不需要太复杂但至少要做到变量名可读。虽然笔试判题不看你代码风格但万一做题中途思路混乱清晰的变量名能帮你更快理清逻辑。7.3 个人体会最后分享一点我自己的体会吧关于“八股文”这个被很多人诟病的东西。热词里频繁出现java八股文、java面试必备八股文确实国内校招笔试面试对基础概念的记忆要求很高。但我越来越觉得八股文本身不是坏事关键是背诵的方式要正确——不是死记硬背答案而是背“为什么”。比如你背“HashMap线程不安全”同时要知道它为什么不安全并发put可能导致数据覆盖、jdk1.7还有扩容死循环问题这样面试时被追问才有底气。笔试也一样理解了原理之后考题再怎么变形你都能识别出它考的就是那个核心知识点。用友这套笔试题整体难度在秋招Java岗里属于中等偏上不搞竞赛级算法也不出偏门知识但对基本功的要求非常扎实。如果你能把这篇文章里梳理的考点全部掌握不说拿满分至少拿到面试通知是绰绰有余的。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门