
2024年秋招百度Java工程师第二批笔试这个话题最近在各大技术社区和校招群里被反复讨论。作为经历过不止一轮大厂笔试、也带过很多应届生走完整套校招流程的Java工程师我整理了这份关于百度笔试的详细复盘。这篇内容会围绕大家最关心的几个问题展开笔试题型是什么样的、Java基础到底在考什么、编程题怎么写才能拿分以及那些让无数人当场心态爆炸的环境问题该怎么解决。不管你是刚开始准备校招的应届生还是打算为下一轮招聘提前准备的实习生这篇内容应该都能给你一些真正有用的参考。先说明一点我下面写的不是标准答案而是结合我自己考试经历和帮人复盘总结出来的方法论。每个人的基础不同、优势不同备考策略也要跟着调整。但有些东西是通用的Java的高频考点、算法题的常见套路、在线笔试的避坑方式这些你花时间准备就一定有回报。1. 笔试整体情况与备战思路1.1 笔试形式和题型分布百度校招的技术笔试第一批和第二批在形式上是差不多的。正常情况下试卷分两块一块是选择题包含单选和多选另一块是编程题两到三道不等。整体时长在90分钟到120分钟具体看当年的安排。在线笔试系统会在考试前发送邮件通知里面会写清楚支持的语言和版本这个细节我建议一定提前看清楚。选择题考察的面很杂但Java基础一定占大头。集合框架、并发、JVM内存模型、String相关、异常处理这些几乎每年都会出现。计算机网络会考TCP三次握手、HTTP状态码、DNS解析过程操作系统则是进程调度、死锁、虚拟内存这些经典题。数据库部分重点关注索引、事务隔离级别、SQL语句优化这几块在选择题里出现频率很高。编程题一般是两到三道难度呈梯度上升。第一道往往是简单题双指针、模拟、字符串处理只要思路清晰就能拿下。第二道是中等难度可能涉及贪心、二分、动态规划。第三道属于拉开差距的题目时间不够做不出来非常正常不用自我怀疑。笔试不是一个要求满分的考试它的核心逻辑是筛选。你要做的就是在有限时间内尽可能多拿分把能稳拿的分全部拿到手再去冲难题。很多人栽在时间分配上简单题磨蹭太久难题也没做出来两头空。1.2 备战资料怎么选这个话题我可以直接给你一套组合拳是我自己验证过效率比较高的方式。第一Java基础知识点要系统过一遍这就是大家常说的八股文。网上随手一搜能出来一堆整理好的文档知识点确实全但量也大。我的建议是把它当目录用而不是背诵材料。每个知识点问自己三个问题这是什么为什么这样设计在什么场景下用能答出来说明真理解了答不出来这个点就是你的薄弱项重点补。第二算法刷题要重质量而不是数量。校招时间紧优先刷力扣Hot 100和剑指Offer。刷题的时候别光看题解卡壳十分钟还想不到思路再看题解然后手写一遍。隔天再独立写一遍能写出来才算真正吸收。这样一轮下来比漫无目的地刷三百题有效得多。第三准备一个自己的Java项目。哪怕是课设级别的也完全可以。笔试大题偶尔会有场景设计题比如设计一个秒杀系统、实现一个限流器、写一个短链接服务。有项目经验的人写这种题思路和纯背题的人是不一样的。2. Java基础核心考点拆解2.1 面向对象三特性的考察方式面向对象编程OOP的封装、继承、多态是Java笔试里最基础也最高频的考点。选择题经常考下列哪个体现多态、重载和重写的区别这类问题看着简单但很多人丢分。封装强调的是对象的属性和行为绑定在一起外部只能通过公开接口访问不能直接操作内部状态。考察方式一般是给一段代码让你判断哪个类设计符合封装原则。核心判断标准就一条成员变量有没有用private修饰外部是否只能通过getter/setter方法访问。继承考得最多的是构造器和代码块的执行顺序。父类静态代码块、子类静态代码块、父类实例代码块、父类构造器、子类实例代码块、子类构造器这个顺序几乎年年考。记忆口诀是静态先行父类先于子类。再往深了考会涉及super关键字、方法重写时访问权限不能变窄、抛出的异常不能变宽、返回值类型可以变窄。这些细节在选择题里非常容易设陷阱。多态是重中之重。向上转型、向下转型、instanceof判断、动态绑定和静态绑定都是高频题。做题的时候记住一句话编译看左边运行看右边。变量能调什么方法取决于声明类型方法执行看的是对象实际类型非private、非static方法。重载属于静态绑定编译期确定重写属于动态绑定运行期确定。这个区分是选择题的常客。2.2 集合框架高频考点HashMap、ArrayList与并发容器集合框架在笔试里出现频率高到离谱尤其是HashMap。我甚至见过一张卷子里选择题和编程题都用到了HashMap。HashMap的核心考点把这些吃透基本就稳了底层数据结构JDK 1.8之后是数组链表红黑树。链表长度大于等于8且有元素个数超过64时转红黑树长度降到6时退化为链表。两个阈值不一样是为了防频繁转换。put流程根据key的hash值计算索引该位置为空直接放入非空则遍历链表比较key存在就覆盖不存在就尾插。如果头节点是红黑树节点走树化插入逻辑。扩容机制默认容量16负载因子0.75扩容为原来的两倍元素要重新计算位置。为什么用红黑树链表太长查询退化为O(n)红黑树最坏也是O(log n)。ArrayList和LinkedList的对比也是选择题常客。ArrayList底层是数组查询快增删慢扩容时做整数组拷贝。LinkedList底层是双向链表中间增删快查询慢。刷题时很多人喜欢用LinkedList做队列、做栈但笔试里要注意如果你需要随机访问ArrayList明显更合适。ConcurrentHashMap在并发容器这一块必考。JDK 1.8之后放弃了分段锁改用CAS配合synchronized锁住链表头节点或树根节点读操作不加锁因为Node里的val和next用volatile修饰了。问它为什么比HashTable快答案就是锁粒度更细而且读没有锁。还有一道经典题HashMap为什么线程不安全并发put可能会覆盖数据JDK 1.7头插法在并发扩容时还可能形成环形链表导致死循环。所以并发场景不要直接用HashMap选ConcurrentHashMap。2.3 并发编程与JVM必背知识点并发这块笔试常考的包括synchronized与ReentrantLock的区别、volatile关键字、CAS与原子类、线程池参数。synchronized是JVM层面的锁通过monitor实现代码块结束或异常时自动释放ReentrantLock是JDK提供的锁需要手动lock和unlock建议配合try-finally用。ReentrantLock支持公平锁、可中断锁、多条件队列功能更强。JDK 1.5之后synchronized做了锁升级优化偏向锁、轻量级锁、重量级锁性能差距已经大大缩小。volatile的核心作用有两个保证可见性、禁止指令重排但无法保证原子性。笔试最爱问的就是volatile能不能保证原子性答案是不能。volatile int countcount这种读改写操作不是原子操作并发下依然会丢数据。线程池参数必须背熟corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime空闲线程存活时间、workQueue任务队列、threadFactory线程工厂、handler拒绝策略。执行流程是提交任务后先判断核心线程数是否已满没满就创建核心线程执行满了就放入队列队列满了创建非核心线程线程数到了最大值执行拒绝策略。JVM的考点集中在内存区域和垃圾回收。内存区域常考堆、栈、方法区JDK 8之后是元空间、程序计数器、本地方法栈各自存什么内容、哪些线程共享哪些线程私有。堆是所有线程共享的栈是每个线程私有的。垃圾回收里常考Minor GC和Full GC的触发条件可达性分析算法以及常见垃圾回收器CMS、G1的适用场景和特点。还有一个经典题哪些对象能当GC Roots虚拟机栈引用的对象、方法区静态属性引用的对象、常量池引用的对象、本地方法栈JNI引用的对象。2.4 Java新特性与常见语法细节这几年笔试选择题里Java 8的Lambda表达式和Stream API出现频率明显上升说明出题人也在跟着技术潮流走。Lambda表达式的本质就是一个匿名函数使用前提是函数式接口也就是只有一个抽象方法的接口比如Runnable、Comparator、Consumer。笔试里也出现过方法引用的题比如System.out::println、String::length本质是Lambda的简写形式。方法引用分四种静态方法引用、特定对象的实例方法引用、任意对象的实例方法引用、构造器引用。能识别出来就行。枚举类型是另一个高频考点。enum本质上是一个继承自java.lang.Enum的类枚举常量是这个类的静态final实例。它可以定义字段、方法、构造函数可以implements接口switch语句里可以直接用枚举。有一个常见判断题枚举能不能继承其他类答案是绝对不能因为Java单继承而且它已经隐式继承了Enum类。运算符和表达式看着基础但容易丢分。三个重点要记住第一短路与、短路或的执行规则左边能决定结果时右边不会执行第二三目运算符的类型自动提升问题int和double混用时会提升为double第三位运算左移一位相当于乘2右移一位相当于除2笔试可能会用位运算实现乘除法来考你。数组越界异常ArrayIndexOutOfBoundsException也是笔试编程题里的常见报错后面我会专门讲怎么避免。至于更常见的Java环境变量配置、JDK安装等基础如果你笔试前还没配好环境建议先解决这个前置问题再谈其他。3. 编程题实战从审题到AC的完整流程3.1 笔试算法题的常见题型与套路百度笔试编程题的高频题型我总结下来有几类。第一类是模拟题。给你一套规则让你按规则模拟整个过程。这种题思路不难但实现细节多分支多容易漏。我的习惯是先别急着写代码在纸上把流程捋一遍拆成几个小函数再动手写。边写边想逻辑很容易漏掉边界分支最后debug时间比写代码时间还长不值当。第二类是双指针和滑动窗口。有序数组的两数之和、最长无重复子串、最小覆盖子串都是这一类的经典题。看到连续子数组、区间、窗口这些关键词第一反应就应该是滑动窗口。这类题实现起来不复杂关键在判断场景。第三类是动态规划。背包问题、最长递增子序列、打家劫舍系列。动态规划的核心是状态定义和状态转移方程笔试里我建议先把状态定义写清楚再推转移方程。很多人一上来就写转移方程写一半发现状态定义就是错的全部推翻重来心态很容易崩。第四类是图论基础题。拓扑排序、最短路径Dijkstra、并查集。这类题一般放第三道属于压轴题时间不够可以先跳过不影响前面得分。有人会问排序算法在编程题里还会直接考吗说实话直接让你写排序的题越来越少但排序思想会嵌入到更复杂的题里。并且选择题里经常会出现下面哪一趟排序后的数组可能是快速排序的结果这类题所以对排序过程的状态变化要有清晰的认知。搜索热搜词里冒泡排序和快速排序Java实现的搜索量一直不低说明这是很多人的薄弱点值得专门补一下。3.2 排序算法的Java实现思路冒泡排序代码虽然简单但边界条件很容易写错。正确的写法和一个关键优化点是这样的public void bubbleSort(int[] arr) { for (int i 0; i arr.length - 1; i) { boolean swapped false; for (int j 0; j arr.length - 1 - i; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; swapped true; } } if (!swapped) { break; } } }那个swapped标志位特别重要。如果某一趟循环结束后没有任何交换发生说明数组已经有序直接提前结束。这个是冒泡排序最经典的优化也是选择题考点加了标志位之后最好情况下的时间复杂度是O(n)没加则永远是O(n^2)。快速排序是笔试手撕频率最高的排序没有之一。核心思想是分治选一个基准值把数组分成左边小于等于基准、右边大于等于基准的两部分然后递归处理左右两边。我比较推荐Lomuto分区方案代码写起来不容易出错public void quickSort(int[] arr, int left, int right) { if (left right) return; int pivot partition(arr, left, right); quickSort(arr, left, pivot - 1); quickSort(arr, pivot 1, right); } private int partition(int[] arr, int left, int right) { int pivot arr[right]; int i left; for (int j left; j right; j) { if (arr[j] pivot) { swap(arr, i, j); i; } } swap(arr, i, right); return i; }快速排序的几个关键点要记住最坏时间复杂度是O(n^2)发生在数组已经有序每次选到最大或最小元素作为pivot时优化方式是随机选择pivot或三数取中快速排序是不稳定排序笔试里如果题目不要求手写排序直接用Arrays.sort就可以了。底层是DualPivotQuicksort性能和稳定性都经过大量优化。笔试不是炫技的地方能用现成API解决的事情不要自己造轮子。3.3 边界条件与代码规范如何一次写对编程题最容易失分的不是思路而是一些特别小的地方。我总结几个高频出错点。数组下标越界最常见。凡是代码里出现arr[i 1]、arr[i - 1]、双指针移动都要先想想i和j是不是在有效范围内。循环条件建议写 i n - 1 而不是 i n - 2前者更直观不容易出错。空指针是第二杀手。题目如果没说输入一定非空方法开头一定要判空。还有一个隐藏很深的空指针来源拆箱。int和Integer混合使用Integer为null时自动拆箱抛出NullPointerException这个选择题考过多次很多人挂在上面。整型溢出也容易被忽略。题目没给数据范围时计算涉及乘法或累加就用long别用int。还有一个Integer比较的陷阱-128到127范围内Integer用比较没问题因为这个范围内的值会被缓存超出这个范围比较的是对象引用地址结果可能为false。判等要用equals。这个坑在笔试题里非常容易出成选择题。输入输出的效率也要重视。在线笔试里Java读取数据最快的是BufferedReader其次是Scanner。数据量到一定程度Scanner会有明显延迟极端情况会TLE。平时练习就直接用BufferedReader加StringTokenizer形成习惯BufferedReader br new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st new StringTokenizer(br.readLine()); int n Integer.parseInt(st.nextToken());4. 笔试现场的环境雷区与排查实录4.1 JDK版本不匹配源发行版17需要目标发行版17这个报错是2024年以来很多同学的噩梦原文长这样java: 警告: 源发行版 17 需要目标发行版 17出现这个问题的根本原因是IDE里的项目编译级别和JDK版本不一致。比如说你本地装的是JDK 8但项目编译级别被设成了17编译器就会报这个警告并且拒绝使用当前的JDK来编译。笔试现场遇到这个问题会非常急人。在线笔试系统一般有自带的代码编辑器不需要本地编译但如果你习惯在本地IDE里先调试好再粘贴到系统里这个问题就会卡住你。排查顺序我建议是这样第一步确认本地JDK版本。命令行敲 java -version看清装的是哪个版本。如果装的是JDK 17默认编译级别就是17问题不大。第二步检查IDE的Project Structure设置。在IntelliJ IDEA中是File - Project Structure - Project把SDK和Language Level设成一致版本。第三步检查Maven或Gradle的编译配置。pom.xml里maven-compiler-plugin的source和target要和JDK版本一致。最省心的写法是直接用properties统一指定properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target /properties还有一个细节容易被忽略如果笔试平台只支持Java 8你本地却用了Java 11的语法比如var、Switch表达式、文本块粘贴过去就会编译失败。提前看考试说明确认支持哪个JDK版本本地环境切换到对应版本去练题这是最稳妥的做法。4.2 Lombok与编译器报错另一个高频报错长这样java: You arent using a compiler supported by lombok, so lombok will not work.这个报错一般出现在本地IDE编译阶段。Lombok是通过注解处理器在编译期生成代码的比如Data自动生成getter/setter。如果Lombok版本和JDK版本不兼容它就无法注入编译器就会报这个错。解决办法有几种升级Lombok到最新版本旧版本对JDK 17以上支持不全检查IDE里是否安装了Lombok插件IDEA没有插件时注解不会生效最直接的方案笔试环境如果默认不支持Lombok就不要在笔试编程题里用Data、Builder这些注解我个人的习惯是笔试编程题全程手写普通类不用Lombok。在线笔试的评测系统可能没配注解处理器一个Data注解可能导致整个类编译失败直接零分。手写getter/setter也就几行代码换来的是确定性很值。4.3 内存溢出与输入输出陷阱本地跑得好好的粘贴到在线笔试系统就报内存溢出这个问题很多人都遇到过。报错一般是Exception in thread main java.lang.OutOfMemoryError: Insufficient memory原因通常是两个代码里有无限递归或死循环或者创建了超大数组、不必要的大对象。排查思路很简单先看递归有没有终止条件。快速排序如果基准选得不好在特定数据下递归深度会非常大触发栈溢出。再看数组大小如果题目数据范围是10^5你开个10^9的数组那必然撑爆内存。在线笔试系统一般都会限制内存通常是256M到512M。写代码时要有复杂度意识能用数组就别用HashMap能用int就别用Integer。还有一个容易被忽略的点Scanner读大数据量输入时也会消耗额外内存和时间。数据量大时换成BufferedReader流畅很多。另外如果你在本地用VS Code运行Java时遇到中文乱码这在笔试环境不会出现但会影响本地调试心情。解决方案是把编码统一成UTF-8控制台编码和文件编码保持一致VS Code的settings.json里加上java.debug.settings.consoleEncoding: UTF-8, java.jdt.ls.vmargs: -Dfile.encodingUTF-85. 秋招笔试的独门经验与心态调整5.1 时间分配先易后难学会放弃笔试的编程题难度是渐进的第二题比第一题难第三题最难。很多人的问题不是不会做难题而是把时间全部砸在难题上简单题反而没时间写。我的策略是这样的拿到试卷先快速浏览所有题目用一两分钟判断每道题的难度。然后按顺序写但每题给自己设一个时间上限。简单题最多25分钟中等题最多40分钟难题看完如果10分钟没有思路直接跳过。编程题是按测试用例给分的只过部分用例也能拿部分分数完全不写一定是零分。选择题也一样不要恋战。有些选择题特别绕考的是冷门知识点凭第一感觉选了就过后面有时间再回来检查。任何一道题卡太久都是对其他题目的不尊重。5.2 笔试结束后的复盘笔试结束不等于流程走完。如果你有记题的习惯笔试结束后第一时间把题目复现出来这非常重要。为什么说重要百度第二批笔试和后面批次的题目有很大概率出现相似题型。你认真复盘过一道题下次遇到类似题型就能直接联想到思路节省大量思考时间。很多同学笔试完就把题目抛到脑后下一场又是从头开始这样每次都在重复劳动。复盘的核心不只是把代码抄一遍而是分析三点当时哪里卡住了、正确的做法是什么、如果重写一次要避免什么。把这些记下来形成自己的题库这才是越考越顺的核心逻辑。5.3 心态调整笔试不是终点最后说点实在话。秋招笔试只是整个校招流程中的一环它更像一个初筛器把明显不达标的筛掉而不是把所有考生都难倒。百度这样的公司每年校招收到的简历数以万计笔试通过率本身就不高。一次笔试没过不说明你不行我的建议是别把全部希望押在一场笔试上多投多面增加机会。保持稳定的复习节奏比临时抱佛脚重要得多。每天固定刷几道题过几个知识点周末做一次全真模拟这种细水长流的节奏到了笔试当天状态是稳的。临时狂刷三天大脑一片混乱反而容易在考场上发挥失常。我个人的体会是笔试最大的门槛不是知识量而是熟练度。八股文背熟了、算法题刷顺了、输入输出写熟了笔试的通过率自然会大幅提升。把平时练习当成真正的笔试来对待真正笔试的时候才能像平时练习一样轻松。这份复盘是基于我自己的实战经验和帮人备考过程中积累的总结希望对准备百度Java工程师笔试的同学有帮助。每个人的基础和薄弱点都不一样别照搬任何一份备考计划一定要结合自己的情况去调整。最后祝大家都能拿到心仪的offer。