FEATURED · 精选文章

B站校招后端笔试卷全解析:Java/MySQL/Redis/算法考点与答题技巧

发布时间 / 2026/8/31 5:32:06
来源 / 创域科博编辑部
栏目 / 资讯中心
B站校招后端笔试卷全解析:Java/MySQL/Redis/算法考点与答题技巧 校招后端笔试说白了就是一场“八股文算法设计题”的综合体检。哔哩哔哩2020校园招聘后端笔试卷一这套题我最近带着几个准备秋招的学弟完整过了一遍感触挺深——它不像某些厂上来就甩一堆偏题怪题而是非常典型地考察“后端基本功”Java基础、Spring容器、MySQL事务、Redis缓存、并发编程、经典算法最后还有一道系统设计。这套题的风格和当前主流互联网公司的校招笔试题高度一致非常适合作为后端岗位求职者检验自身水平的标尺。如果你正处于后端学习路线的中间阶段或者正在疯狂刷后端面试题准备校招这篇文章值得认真看完。我会把这份笔试卷的核心考点逐层拆开补充常见追问、易错点以及我当时给学弟讲题时反复强调的排查思路和答题技巧。看完你不仅能“会做题”更能理解题目背后面试官真正想考察的能力点。1. 笔试卷整体脉络B站后端笔试在考什么1.1 从题目结构看B站的用人偏好先说结论这份试卷的难度属于中等偏上但区分度极高。它没有像某些大厂一样考超纲的底层汇编或者复杂的数学推导而是把重心放在“后端开发日常真正会用到的技术深度”上。整套试卷大致可以分为四块选择题涵盖Java、操作系统、网络、数据库、编程题手写算法、SQL题MySQL实战、以及一道开放性的系统设计题。从题目分布能明显看出B站作为一家以视频业务为核心的互联网公司对后端工程师的期望是基础扎实、能写高质量代码、对数据库和缓存有深入理解、具备一定的架构思维。这种出题思路其实代表了国内绝大多数中大型互联网公司校招笔试的主流方向。所以说这份试卷对准备后端岗位的同学来说参考价值非常大不只是为了“刷题”更是为了梳理自己的知识体系。1.2 知识点权重分析与备考优先级我把试卷涉及的核心知识点做了一张权重表方便你安排复习优先级。知识模块考察形式占比估算优先级Java基础与JVM选择题20%高Spring框架选择题10%高MySQL与索引事务选择题SQL题20%高Redis选择题10%高操作系统与网络选择题15%中算法与数据结构编程题15%高系统设计问答题10%中从这张表能看出想要在这套笔试卷上拿高分MySQL和算法是两个绝对不能失分的板块。尤其是SQL题看起来简单但往往藏了索引失效、隐式转换、分组排序这些细节坑。这些细节也正是面试官区分“背过八股”和“真正写过业务代码”的关键。2. Java核心考点复盘不只是背八股2.1 集合类与并发容器Fail-Fast机制的前因后果这套选择题里Java集合类相关的题目出了好几道其中最值得展开说的是ArrayList的Fail-Fast机制。题目大致是这样的在遍历ArrayList的过程中如果另一个线程同时对它进行了结构性修改比如add或remove会发生什么标准答案是抛ConcurrentModificationException。但面试官不会满足于这个答案他在后续面试环节一定会追问具体是哪个方法抛出的为什么HashMap也有同样的问题CopyOnWriteArrayList是怎么解决的这里你要理解到源码层面。ArrayList内部维护了一个modCount字段每次结构性修改都会自增。迭代器初始化时会将当前的modCount赋值给expectedModCount每次调用next()方法时都会检查这两个值是否相等如果不相等就抛出异常。这就是“快速失败”的含义——它不保证一定检测到并发修改而是在绝大多数情况下能够及时发现并报错。至于CopyOnWriteArrayList它的设计思路是“写时复制”每次修改操作都会复制底层数组修改在新数组上进行读写分离。因为写操作不会影响读操作的底层数组所以迭代器遍历时根本不需要检查modCount自然也就不会抛ConcurrentModificationException。代价是写操作开销很大适合读多写少的场景。2.2 JVM内存区域与GC回收机制试卷里有一道关于JVM内存区域的题目问的是以下哪个区域不会发生OutOfMemoryError选项包括堆、虚拟机栈、方法区、程序计数器。答案是程序计数器。它是JVM中唯一不会发生OOM的区域因为它所占用的内存空间很小且生命周期跟随线程。这道题本身不难但非常典型它考察的是你对JVM运行时数据区的完整理解。我建议你复习JVM时把这个知识点和垃圾回收机制串联起来记忆。比如Minor GC发生在新生代使用复制算法Major GC/Full GC涉及老年代使用标记-清除或标记-整理算法。为什么新生代用复制算法因为新生代对象“朝生夕死”的比例高复制算法只需要复制少量存活对象效率高。为什么老年代用标记-整理因为老年代对象存活率高如果还用复制算法会有大量复制开销且没有额外空间做分配担保。理解这些“为什么”比死记结论重要得多。面试官问GC相关问题时真正想听的是你能否根据对象存活特征推导出算法选型而不是单纯背出三种算法的定义。2.3 多线程与锁synchronized和ReentrantLock怎么选并发编程的题目在这份试卷中出现了两次一次是问synchronized和ReentrantLock的区别另一次是问volatile关键字的作用。关于volatile很多人只记住“可见性”和“禁止指令重排”但容易忽略一个关键点volatile不能保证原子性。所以它适合修饰状态标记位不适合做计数器。题目中的经典陷阱是多个线程同时对volatile int count执行count最终结果是否一定是线程安全的答案是否定的因为count不是一个原子操作它包含读取、加一、写回三个步骤。至于锁的选择我的建议是能不用锁就不用锁必须用锁时优先考虑synchronized。因为synchronized在JDK 6之后引入了偏向锁、轻量级锁的优化在竞争不激烈的情况下性能并不比ReentrantLock差而且使用更简单不容易出错。ReentrantLock的优势在于可中断、可设置超时时间、支持公平锁、支持多个条件变量。比如你需要实现“最多等待3秒获取锁获取不到就执行降级逻辑”这样的需求就应该用ReentrantLock的tryLock(timeout, unit)这不是synchronized能直接做到的。3. Spring核心机制IOC与AOP的底层逻辑3.1 Bean的生命周期与循环依赖Spring相关的选择题占了不少比例其中有一道关于Bean作用域的题singleton和prototype的区别。这属于基础中的基础但B站把它和线程安全结合起来考单例Bean是否存在线程安全问题答案是存在。因为单例Bean在整个容器中只有一个实例如果它内部持有可变状态比如一个HashMap成员变量那么并发请求下就会出现数据竞争。解决办法有两种一是把可变状态放在方法内部用局部变量隔离二是使用ThreadLocal保存线程私有数据。更深入的考点是Spring如何解决循环依赖。比如A依赖BB依赖A两个都是单例BeanSpring为什么能正常创建这里涉及三级缓存第一级缓存存放完整的Bean第二级缓存存放早期暴露的Bean还未完成属性填充第三级缓存存放ObjectFactory用于生成代理对象的工厂。核心思路是A创建时发现需要B于是先把A的早期引用暴露到三级缓存再去创建BB创建时发现需要A直接从缓存中拿到A的早期引用完成注入B创建完成后A再从缓存中拿到完整的B完成注入。这个机制理解起来有点绕我建议你用画图的方式捋一遍流程面试时如果能把这个三级缓存讲清楚绝对是个加分项。3.2 Spring事务传播行为与失效场景关于事务的题目这张试卷集中在MySQL部分但有一道是纯Spring事务的事务的传播行为REQUIRED和REQUIRES_NEW有什么区别REQUIRED是默认传播行为如果当前没有事务就新建一个事务如果当前已经存在事务就加入到当前事务中。REQUIRES_NEW则是不管当前有没有事务都新建一个独立的事务外层事务的回滚不会影响到内层事务的提交。这里最经典的一个场景是你有一个方法A加了Transactional它方法内部调用了另一个方法B也加了TransactionalB抛出异常后A捕获了这个异常并继续执行请问事务最终是提交还是回滚很多新手会答错。答案取决于B的传播行为。如果B是REQUIRED那么B加入了A的事务B抛出的异常即使被A捕获事务也会被标记为rollback-only最终A提交时会抛出UnexpectedRollbackException。如果B是REQUIRES_NEWB会独立提交或回滚A捕获异常后可以正常提交。这个细节就是面试官区分你有没有真正写过事务代码的试金石。另外补充一个高频易错点Transactional默认只在运行时异常RuntimeException下回滚受检异常Exception的子类默认不回滚。如果你希望受检异常也触发回滚需要显式声明rollbackFor Exception.class。4. MySQL与Redis后端存储的两驾马车4.1 SQL题实战索引失效的N种场景这套试卷的SQL题很有代表性它给出了一张用户表一张订单表要求查询“最近一个月内下单次数超过5次的用户信息”。如果你直接写WHERE order_time DATE_SUB(NOW(), INTERVAL 1 MONTH) GROUP BY user_id HAVING COUNT(*) 5大概率能跑出正确结果但这并不是考察重点。这道题的隐藏考点在索引。如果你在order_time字段上有索引那么条件order_time DATE_SUB(NOW(), INTERVAL 1 MONTH)是能走索引的因为DATE_SUB的计算发生在等号右边不影响字段本身的索引匹配。但如果把条件改成DATE_SUB(NOW(), INTERVAL 1 MONTH) order_time虽然语义相同优化器也有可能正确处理但更安全的写法是保证字段独立出现在比较运算符的一侧不对字段做函数运算。举几个经典的索引失效场景对索引列使用函数比如WHERE YEAR(create_time) 2020索引失效。隐式类型转换比如WHERE phone 12345678901而phone字段是varchar类型索引失效。模糊匹配以通配符开头比如WHERE name LIKE %张索引失效WHERE name LIKE 张%则可以走索引。使用OR连接非索引列比如WHERE id 1 OR name 张三如果name没有索引整个查询可能全表扫描。做SQL题时我养成了一个习惯先看表的索引设计再写SQL。很多同学倒在这道题上不是因为不会写SQL而是根本没想到要分析索引。4.2 事务隔离级别与MVCC实现原理关于MySQL事务的考察B站问到了REPEATABLE READ级别下是否解决了幻读问题。答案是InnoDB在REPEATABLE READ隔离级别下通过MVCC解决了快照读的幻读但当前读仍然可能产生幻读。为了帮你彻底搞清楚这个知识点我用一个生活化的例子解释MVCC。想象一个多人协作的共享文档每个人打开文档时看到的都是自己打开那个瞬间的版本之后别人怎么改都不影响你当前看到的页面。只有当你主动点击“刷新”按钮时页面才会更新到最新版本。这个“打开瞬间的版本”就是快照读而“刷新按钮”就是当前读。在InnoDB中每行记录都有隐藏字段DB_TRX_ID最后修改事务ID和DB_ROLL_PTR回滚指针配合undo log实现多版本链。REPEATABLE READ下事务第一次执行SELECT时生成read view后续SELECT都基于这个read view判断可见性因此同一事务多次查询结果一致。但如果你使用SELECT ... FOR UPDATE或INSERT/UPDATE/DELETE这类当前读操作它会读取最新已提交版本此时如果其他事务插入了满足条件的新记录就会出现幻读。彻底解决幻读需要加间隙锁Gap Lock或Next-Key Lock这也是InnoDB在REPEATABLE READ下能部分解决幻读的关键机制。4.3 Redis缓存三大问题穿透、击穿、雪崩Redis相关的题目B站考察了缓存穿透和缓存雪崩。这两个概念很容易混淆我遇到过不少工作了两年的人都没能讲清楚。缓存穿透是指查询一个不存在的数据缓存和数据库中都没有导致每次请求都直接打到数据库。正常流程是先查缓存缓存没有则查数据库数据库也没有则返回空。但如果有人恶意构造大量不存在的ID请求缓存永远不会有数据数据库压力会剧增。解决方案有三种一是对空值也做缓存设置较短的过期时间二是使用布隆过滤器在缓存之前加一层过滤三是参数校验拒绝明显非法的ID。缓存雪崩是指大量缓存同时失效导致所有请求瞬间涌向数据库。解决方案的核心思路是“错峰过期”在设置缓存过期时间时加一个随机值比如base random(0, 300)秒避免大量key在同一时间过期。第二道防线是使用多级缓存比如本地缓存加分布式缓存即使Redis挂了本地缓存还能扛住一部分流量。缓存击穿和雪崩的区别在于击穿是单个热点key过期高并发下大量请求同时访问这个key发现缓存过期后全部打到数据库雪崩是大批量key同时过期。击穿的解决方案是互斥锁只允许一个请求去数据库加载数据其他请求等待并直接读取缓存。5. 算法题精讲手写代码的边界意识5.1 高频题归并排序的链表版本这套试卷的手写算法题里有一道链表排序题。要求时间复杂度O(n log n)空间复杂度O(1)这就排除了用数组辅助排序的方案直接指向“链表归并排序”。链表归并排序的核心是三个步骤找到链表的中点将链表拆成两半。这里有一个经典技巧快慢指针。慢指针每次走一步快指针每次走两步快指针到达链表尾部时慢指针正好在中点。递归排序左右两半。合并两个有序链表返回新头节点。看似不难但实际手写时容易在“找中点”时出错。特别要注意的是链表长度为偶数时中点有两个你可能需要“左中点”而不是“右中点”否则归并时会出现无限递归或漏节点的问题。我习惯的写法是初始化时slow指向headfast指向head.next这样slow最终会停在左中点。如果fast也指向head那么slow会停在右中点可能引发问题。另一个常见错误是拆分后忘记将左半段的尾部置为null。如果不断开链接合并时可能会形成环导致程序死循环。这种边界意识是面试官非常看重的代码素养。5.2 必考题反转链表的迭代与递归反转链表几乎是每套后端笔试卷的必考题B站也不例外。虽然题目简单但考察的是你能不能写出两种解法并解释它们各自的空间复杂度。迭代法的时间复杂度是O(n)空间复杂度是O(1)只需要三个指针prev、curr、next每次迭代完成指针反转。递归法的代码更简洁但空间复杂度是O(n)因为递归调用栈会占用额外空间。递归法的核心是先反转以head.next为头节点的子链表然后让head.next.next指向head最后让head.next指向空。这里我给你的建议是面试时先写迭代法因为不容易出错且空间更优写完后再主动补充递归法展示你思路的全面性。千万别一上来就写递归写不出来卡在那边会非常尴尬。另外反转链表还有一个变体——反转链表的第m到第n个节点。笔试如果时间充裕可以顺手把变体也写一遍它的关键在于保存m位置前驱和n位置后继处理边界时要注意头节点可能被反转的情况通常需要借助虚拟头节点dummy来简化逻辑。6. 系统设计题解析从“会做题”到“会设计”6.1 短视频Feed流推送系统的核心架构这套试卷的最后一题是设计一个类似B站动态页的Feed流系统。这类题目在校招笔试题中越来越常见它考察的不是你的架构经验而是你能否将基本组件缓存、消息队列、数据库组合成一个可用的方案。我的解题思路分三步走第一步明确需求边界。Feed流系统的核心操作只有两个用户发布动态、用户拉取关注列表的最新动态。这里要主动向面试官确认是推模式还是拉模式或者推拉结合关注关系是否有上限动态的排序依据是时间还是热度把需求问清楚再动手设计比一上来就画架构图专业得多。第二步选定核心组件。推模式写扩散适合粉丝量少的场景发布者写一条动态系统实时推送给所有在线粉丝的收件箱拉模式读扩散适合大V场景粉丝发起请求时再去关注列表各自拉取最新动态。B站这种平台既有普通UP主也有千万粉大UP主必须采用推拉结合的模式普通用户用推模式大V用拉模式同时用消息队列异步处理推送任务。第三步补充存储与缓存设计。Feed内容存MySQL或TiDB热数据放Redis收件箱使用Redis的List或ZSet结构ZSet的score可以用发布时间戳方便按时间拉取。为了防止缓存穿透每个用户的收件箱列表需要提前初始化并设置合理的过期和淘汰策略。整个设计不需要多么高大上但一定要自圆其说把每个组件为什么这么选讲清楚。6.2 系统设计题的答题框架与表达技巧很多同学拿到系统设计题就懵不是因为不懂技术而是不知道怎么组织答案。我总结了一个适合校招阶段的答题框架分享给你功能需求列出核心功能和非核心功能。非功能需求估算QPS、数据量、可用性目标。数据模型设计定义核心表结构和存储选型。核心流程时序用文字描述一次完整请求的调用链。缓存与性能优化明确哪些数据需要缓存缓存策略是什么。容灾与降级方案接口超时怎么办缓存挂了怎么办扩展性思考如果数据量变成100倍你这个方案哪些点会先扛不住用这个框架答题即使你设计得不是最优方案面试官也能清楚看到你的思考路径。我见过很多同学在系统设计题上“会做但说不清”这非常吃亏。表达能力在后端工程师的晋升中占的比重超乎想象笔试阶段只是第一步后续的面试环节会更加放大这一点。7. 备考方法与避坑指南7.1 为什么刷题很多却收效甚微我知道很多同学在准备后端笔试时会陷入一个“刷题陷阱”每天刷大量LeetCode和八股文但一遇到B站这种综合性笔试卷还是容易抓瞎。原因在于后端笔试题不是一个一个孤立的知识点而是多个知识点交织在一起的综合体。比如一道SQL题可能同时考察索引、聚合函数、子查询和分组排序一道Java选择题可能同时涉及集合类、并发和JVM。所以我更推荐“以题带点”的复习方式每做一道题把该题涉及的所有知识点都展开复习一遍并顺手整理成笔记。比如做到Spring循环依赖这道题就不要只背三级缓存而是顺手把Bean生命周期、AOP代理、Lazy注解都过一遍。这样看似刷题量少了但每道题的价值翻了数倍。7.2 针对B站这套高频考点的高效准备路径结合这套试卷的考点分布我总结了一条针对性的复习路径按优先级排序“Java集合类源码阅读”重点看ArrayList、HashMap、ConcurrentHashMap的源码理解底层数据结构与扩容机制。“MySQL索引与事务”使用EXPLAIN分析SQL执行计划亲手验证各种索引失效场景。“Redis核心数据结构与缓存策略”不只要看八股更要动手用Redis执行命令观察ZSet的排序行为和内存编码。“Spring IOC与事务原理”结合源码看BeanFactory的创建流程理解Transactional的底层代理机制。“高频算法模板”链表归并排序、反转链表、LRU缓存、快速排序、二分查找变体做到条件反射级别。还有一点值得提醒这套试卷虽然叫“2020校园招聘”但它的考点在今天依然是主流这反映出一个现实——后端基础知识的迭代速度远没有框架快。把基础打牢比追逐每一个新框架都更值得投入时间。7.3 笔试中的时间分配建议B站这套笔试卷的题量不小如果每道选择题都纠结太久编程题基本上没时间做完。我当时的建议是选择题每道控制在1-2分钟内遇到不会的先标记跳过SQL题控制在10-15分钟两道算法题各留20分钟系统设计题留30分钟。整体节奏是“先保正确率再争取完成度”。如果最后系统设计题时间不够优先把功能需求、数据模型和核心流程写清楚能拿一半以上的分。这也是面试官阅卷时的主要关注点。8. 写在最后从笔试卷反推能力模型这套哔哩哔哩2020校园招聘后端笔试卷一虽然已经过去几年但它的出题思路和能力考察模型并没有过时。我反复带人刷这套题感触最深的一点是它真正想筛选的不是“背了多少知识点”的人而是“能不能用这些知识解决实际业务问题”的人。比如SQL题不会直接告诉你“这里有个索引失效”而是让你自己在写查询时主动考虑性能在设计Feed流系统时考察你是否具备从零构建一个可用系统的全局观。如果你正在准备后端岗位的校招不妨以这套试卷为镜对照检查你自己的知识盲区。做完之后不要急着对答案先把每道题的考点和解题思路用自己的语言复述一遍如果能做到“给别人讲明白”那这个知识点才算真正属于你。我在带学弟的过程中反复强调一个方法把做错的题整理成一个“错误原因清单”写清楚“为什么错”“正确思路是什么”“同类题还有哪些变体”。下次复习时只看这个清单效率远高于重新刷一遍题。最后再分享一个我自己踩过的坑做笔试题时一定要看清题目要求的输入输出格式尤其是算法题是“标准输入输出”还是“实现一个函数”。B站这套试卷就有一道算法题要求实现函数签名结果有同学按Scanner标准输入写了半天最后编译不通过白白丢分。另外笔试前最好提前熟悉在线编程平台的编辑器操作有些平台的自动补全很弱平时用惯IDE的话需要提前适应手写代码的节奏。笔试拼的不只是知识储备还有临场状态和细节把控力这两点往往决定了你能不能从“会做”变成“做得完”。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻