
这套试卷虽然标题写着2019年秋招但你现在拿来看一点都不过时。B站那几年技术体系扩张得很快前端、后端、运维、移动端四个方向共用一套题考察的恰恰是一个技术人最底层、最不容易过时的东西。我前阵子完整过了一遍这套题又拉着团队里几个不同方向的同学一起聊了聊发现里面的思路和坑放到现在2026年准备大厂校招依然很有参考价值。今天就把这套卷子的拆解过程和考点分析记录下来给准备技术岗面试的朋友一份参考。1. 试卷整体设计与思路拆解1.1 四个方向共用一套题背后的考察逻辑先看这套题的结构。前端、运维、后端、移动端四个岗位共用一套笔试题这在现在的招聘里已经不多见了大部分公司都是分方向出卷。但B站当时这么设计是有意为之的。核心逻辑是校招进来的新人不管岗位是什么首先得是一个合格的技术人。也就是说通用技术素养的权重远高于具体框架和工具的熟练度。这套题里的公共部分基本都在考察三件事计算机基础网络、操作系统、数据结构、逻辑思维和问题排查的思路、以及对技术深度的好奇程度。我自己的体会是这种出题思路特别适合用来筛掉“背题族”。你框架API背得再熟如果没有真正理解底层原理遇到稍微绕一点的场景题就会露馅。所以你在准备这类试卷时不要只盯着自己岗位的方向去准备公共基础部分反而是拉开差距的关键。1.2 2019年的技术生态决定了哪些考点会成为重点把时间拉回到2019年你就能理解为什么这套题会考那些内容了。那一年互联网行业正处在前后端分离全面普及的节点Vue 2.x是前端绝对的主流Spring Boot在后端领域已经完成了对传统SSH体系的替代Docker和容器化理念开始大规模落地移动端则处在Android 9/10的适配期性能优化和崩溃治理是各大厂的重点。B站的业务形态很特殊它的核心场景是弹幕、视频播放和直播互动。这些场景对实时性要求极高对网络请求的稳定性要求也很高。所以你去看这套卷子里涉及到的考题方向——网络协议、并发处理、内存管理、性能优化——几乎都是围绕这些业务场景展开的。这一点和纯电商、纯社交产品的笔试题有明显的区别出题人明显是带着业务视角在出题的。1.3 这套卷子对现在准备面试的人有什么参考价值有人可能会问2019年的题现在2026年了还有参考价值吗我的观点是价值反而更高了。原因很简单这套题侧重的基础能力恰恰是现在很多浮躁的面试者最欠缺的。现在的技术生态比2019年复杂得多微服务、Serverless、AI辅助编程、跨端框架层出不穷。但你去面试大厂面试官最看重的依然是你能不能把一条HTTP请求从输入URL到页面渲染的完整链路讲清楚你能不能定位一个CPU飙高的问题你能不能设计一个高可用的服务架构这些问题的底层逻辑在这套2019年的题里都有涉及。另外一个很实在的参考价值是它可以帮助你建立一个完整的知识图谱自查清单。你在过这套题的时候一旦发现自己某个考点完全没听过或者只能说出名词说不出原理那就是你的知识盲区赶紧去补。这个价值不亚于刷题本身。2. 前端方向考点精讲与实操要点2.1 JavaScript语言基础闭包、原型链与this指向前端部分的题目里JavaScript语言基础占了很大的比重。这不是B站的偏好而是所有大厂前端笔试的共同特征。JS的核心机制——原型链、闭包、事件循环、this指向——这几样东西基本每年必考形式可能变化但内核不变。我举个例子。闭包这个知识点常规考法是问你输出什么但B站这套题里更倾向于让你写一个防抖函数debounce并且要求在实现过程中体现出对闭包的理解。这其实是更高明的一种考法从“认识闭包”上升到“运用闭包解决实际问题”。function debounce(fn, delay) { let timer null; return function(...args) { if (timer) clearTimeout(timer); timer setTimeout(() { fn.apply(this, args); }, delay); }; }这个实现里有几个关键点值得注意第一timer变量利用了闭包的特性在多次调用之间保持状态第二fn.apply(this, args)确保回调函数里this指向正确第三clearTimeout和setTimeout的组合实现了“最后一次调用生效”的效果。这三个点每一个都是面试官看你能不能拿到高分的分水岭——很多人能写出防抖但能讲清楚为什么要用apply来修正this的就不多了。再比如原型链我的建议是不要死记硬背而是去理解Object.prototype、Function.prototype和实例之间到底是怎么关联起来的。你可以在浏览器控制台里手动敲几段代码用__proto__沿着链条往上爬看看每一步拿到的是什么。这个动作看起来简单但比你看十篇文章都管用。踩过的坑是很多人知道arr.__proto__ Array.prototype但问到Array.prototype.__proto__ Object.prototype就懵了这一层关系理不清后面讲“继承”全是糊涂账。2.2 浏览器与网络从输入URL到页面渲染的完整链路这套题里有一道典型的综合题用户在浏览器输入 www.bilibili.com 并回车请描述从输入到页面展示的完整过程。这道题在2019年的面试圈里已经是“烂大街”的题型了但B站的出题人加了一个限定请重点描述浏览器解析HTML、CSS、JavaScript的执行顺序以及DOM树和CSSOM树是如何合成渲染树的。这个限定条件一加考察层次就完全不一样了。大多数人能背出DNS解析、TCP握手、HTTP请求、服务器响应这几步但一到浏览器内部渲染机制就含糊了。我当时让团队里一个刚入职的前端新人写这道题他写得最薄弱的部分恰恰就是渲染流程。这是普遍现象。我来梳理一遍我认为标准的答案框架DNS解析浏览器缓存 → 系统缓存 → 路由器缓存 → 根域名服务器层层递归拿到IP。TCP连接三次握手建立连接如果是HTTPS还需要TLS握手协商加密参数。发送HTTP请求携带请求头、Cookie等服务器处理完返回响应报文。浏览器解析HTML边解析边构建DOM树遇到script标签会阻塞解析这里要提到defer和async的区别。解析CSS构建CSSOM树CSS的解析不会阻塞DOM树的构建但会阻塞渲染。合成渲染树DOM树和CSSOM树合并成渲染树然后经过布局Layout、绘制Paint、合成Composite三个步骤。2019年的时候我还建议补充一下GPU加速和层合成的内容放到现在你还可以再延伸一下如果页面里有content-visibility: auto这样的CSS属性渲染过程会发生什么变化。这就是一个从“死记硬背”到“活学活用”的升级路径。2.3 框架考察Vue响应式原理的底层拆解2019年秋招的时代背景Vue正处于2.x的成熟期。B站前端团队的早期版本也有不少Vue的技术栈试卷里出现Vue响应式原理的题目可以说是一点都不意外。这道题的标准问法是Vue 2.x中当你修改一个data中的属性时视图是如何自动更新的请结合源码描述依赖收集和派发更新的过程。我建议的回答思路是这样的Vue 2.x的核心是Object.defineProperty。在初始化data时Vue会遍历data中的所有属性通过Object.defineProperty把每个属性转换成getter/setter。在getter中会进行依赖收集把当前的Watcher添加到Dep依赖收集器中在setter中会触发Dep的notify方法通知所有依赖这个属性的Watcher执行更新从而驱动视图变化。这里面有几个细节值得展开为什么Vue 2.x无法检测到对象新增属性的变化因为新增的属性没有经过Object.defineProperty的处理不是响应式的。解决方法是Vue.set或this.$set。为什么数组用索引直接修改不会触发更新因为Object.defineProperty无法拦截数组索引操作所以Vue重写了数组的7个方法push、pop、shift、unshift、splice、sort、reverse来实现响应式。异步更新队列是怎么回事当触发setter时Vue不会立即更新DOM而是把Watcher推入一个队列中通过nextTick在下一个tick统一更新。这是性能优化的关键设计。如果你是现在准备面试我建议你再往深处补一层Vue 3的Proxy实现方案和2.x有什么本质区别Proxy可以直接代理整个对象不需要逐个属性defineProperty所以能够解决新增对象属性和数组索引修改的问题。这个对比能体现出你对技术演进的思考深度面试官通常会比较认可。2.4 性能优化首屏加载与缓存策略前端部分还有一个实操性很强的考点性能优化。B站的业务特性决定了它对首屏加载速度的要求非常高视频站点如果首屏等太久用户直接就走了。所以这套题里问了如果B站首页首屏加载过慢你会从哪些方向排查和优化我梳理一下答辩时可以给出的方向每一个都是可以直接落地的第一资源体积优化。JavaScript和CSS文件要压缩混淆图片要按需加载和懒加载视频封面可以使用WebP格式而不是传统JPEG体积直接可以减少30%左右。第二缓存策略。HTTP缓存分为强缓存Cache-Control、Expires和协商缓存ETag、Last-Modified。静态资源比如JS、CSS、图片这些文件名带hash的可以设置长时间的强缓存因为内容变了文件名就会变不会出现缓存不失效的问题。HTML文件设置协商缓存保证每次请求都能确认是否新鲜。第三渲染路径优化。CSS放在head里避免FOUC无样式内容闪烁JavaScript用defer或async避免阻塞渲染关键CSS可以内联减少关键渲染路径的长度。第四网络层面的优化。接入CDN把静态资源分发到离用户最近的节点开启HTTP/2实现多路复用避免队头阻塞域名拆分减少请求并发限制的影响。我在实际项目里遇到过一个真实案例一个视频详情页首屏要加载1.2MB的JavaScript导致白屏时间超过3秒。后来做了路由级代码分割同时把一些第三方库改成按需引入首屏JS压到了300KB以下白屏时间降到了1秒以内。这就是性能优化实战的典型收益。3. 后端方向考点精讲与实操要点3.1 Java基础与并发编程的考察深度后端方向的内容Java占了半壁江山。2019年的B站后端主流技术栈就是Java Spring生态所以这套题里Java基础、并发编程、JVM这一类内容考得非常扎实。并发编程是我认为这套题里最有区分度的一块。它考的不是synchronized和Lock的API用法而是让你在一个多线程环境下分析一段代码是否存在线程安全问题以及如何修复。这种题能考出一个人的并发基本功是否扎实。举一种典型场景一个计数器多个线程同时对其进行自增操作。public class Counter { private int count 0; public void increment() { count; } public int getCount() { return count; } }这段代码显然是线程不安全的。count不是原子操作它包含“读取-修改-写入”三步在多线程环境下两个线程可能同时读取到同一个值然后各自加1写回导致结果比期望值小。解决思路有几种你要能说出每种方案的优劣和适用场景使用synchronized关键字修饰increment方法简单直接但锁粒度较大。使用AtomicInteger基于CAS比较并交换实现无锁并发适合计数器这种竞争不激烈的场景。使用LongAdderJDK 8引入在高并发下性能优于AtomicInteger因为它在内部进行了分段累加。我个人建议回答时能体现一层进阶思考synchronized在JDK 1.6之后经历了锁升级过程偏向锁 → 轻量级锁 → 重量级锁所以不要再说synchronized是“重量级锁”这种过时的说法了。能谈到这一层面试官对你的评价会明显提升。3.2 Spring核心思想IOC与AOP的通俗理解Spring相关的题目是后端笔试的必考项。最经典的一题就是请用自己的话解释一下什么是IOC控制反转和AOP面向切面编程并且说明它们在项目里的实际应用场景。很多初学者把IOC理解成“把对象交给Spring管理”这个说法没错但太浅了。我自己的理解方式是不用IOC的代码对象之间的依赖关系是在代码里写死的。比如A类里要使用B类就直接new B()。一旦B的构造函数变了或者需要加一层代理A类代码就得跟着改。用IOC之后对象的创建和依赖注入统一由容器管理A类只需要声明“我需要一个B类型的依赖”容器会在合适的时机把B实例注入进来。核心收益是解耦开发者在写业务代码时不需要关心依赖是怎么组装起来的。AOP的应用场景我建议你准备三个经典案例这三个覆盖了90%的面试需求日志记录通过切面统一记录接口的入参、出参、耗时不需要在每个方法里手动写日志代码。事务管理Spring声明式事务的本质就是AOP通过Transactional注解声明事务边界AOP代理在方法执行前后自动完成开启事务、提交或回滚。权限校验通过切面拦截请求检查当前用户是否有权限执行某个操作与业务逻辑解耦。我在工作中还遇到过用AOP做接口幂等性校验的案例。原理就是在方法执行前通过切面检查请求中携带的唯一标识如果相同标识的请求在短时间内来过就拦截掉。这种写法既优雅又实用是AOP比较高级的运用方式。3.3 MySQL索引与事务隔离级别后端笔试中数据库的考察权重历来很高。这套题里有两道题我认为值得展开一道是索引失效的场景分析一道是事务隔离级别的理解。先看索引失效。常见的索引失效场景包括对索引列使用了函数或计算比如WHERE YEAR(create_time) 2023。隐式类型转换比如索引列是varchar类型查询时传入了int类型的值MySQL会做类型转换导致索引失效。使用LIKE模糊查询且通配符在开头比如LIKE %keyword。使用OR连接多个条件且其中一个条件没有索引。联合索引没有遵循最左前缀原则。解释一下为什么函数会导致索引失效。B树索引是按照索引列的值进行排序存储的如果你对索引列执行了函数操作那么原始值和函数值之间的排序关系就完全不一样了MySQL无法利用原有的索引结构进行快速查找只能退化成全表扫描。理解这个原理比死记硬背几条规则更有效——不只是“知道会失效”而是“知道为什么会失效”。再看事务隔离级别。MySQL的InnoDB引擎支持四种隔离级别读未提交Read Uncommitted、读已提交Read Committed、可重复读Repeatable Read、串行化Serializable。在这套题的场景设定里你可以结合B站的实际业务来回答。B站的核心业务场景里有一个典型的可重复读需求用户在查看视频详情时视频的封面、标题、UP主信息、播放量、弹幕数等数据是在一个页面上同时展示的。如果这些数据来自多个查询而这多个查询之间又出现了其他事务的提交那么用户在刷新页面时可能会看到某个字段是旧值另一个字段已经变成新值的情况。可重复读隔离级别保证了在当前事务内的多次查询结果是一致的这正好满足了这种展示型业务的需求。MySQL默认的隔离级别就是可重复读这一点也经常被拿来当作一道附加题为什么MySQL选择可重复读作为默认隔离级别而Oracle选择的是读已提交答案要落到主从复制上在MySQL早期版本中statement-based的日志方式在读已提交级别下主从复制的数据一致性可能会有问题可重复读级别下binlog的写入顺序可以保证主从一致。这个历史原因能答出来的同学基本上数据库方面就是加分项了。3.4 Redis的使用场景与缓存一致性Redis在后端笔试中几乎是必考的。B站这套题里的Redis部分没有问那种“Redis有哪些数据结构”的送分题而是直接给了业务场景视频的播放量计数、热门排行榜、弹幕的实时展示这些场景用Redis怎么做本质上考察的是你能不能根据业务特点选择合适的数据结构和策略。播放量计数短时间内的播放量可以先用Redis的INCR命令做原子自增然后定期批量更新到数据库。这样可以避免高并发下直接操作数据库导致压力过大。热门排行榜使用有序集合ZSet以视频ID为member以播放量或综合热度为score。ZSet天然支持按score排序取Top N榜单直接用ZREVRANGE命令即可性能极高。弹幕的实时展示可以使用Redis的发布订阅Pub/Sub机制或者使用Stream类型把实时弹幕分发给在线用户。不过弹幕系统发展到后期普遍会引入WebSocket 消息队列来做Redis在这里更多承担的是中间缓存层的角色。缓存一致性问题我认为是最值得展开讲的。经典的场景是视频的播放量数据缓存里存了一份数据库里也存了一份如果用户播放视频导致缓存更新但数据库更新失败两边数据就不一致了。业界常见的方案包括先更新数据库再删除缓存的Cache Aside模式以及延迟双删策略即先删缓存、更新数据库、延迟几百毫秒再删一次缓存。2019年的时候这些方案还是面试中的进阶内容能答出Cache Aside模式的细节就已经很出色了。放到现在你还可以补充一个更高级的思路基于Binlog的异步更新方案通过订阅数据库的Binlog变更在数据变更后异步刷新缓存。不过这个方案引入了额外的基础设施复杂度一般在强一致需求不高的场景下才推荐使用。4. 运维方向考点精讲与实操要点4.1 Linux基础与常用命令的实战理解运维部分的笔试题Linux的内容必考。但B站这套题里的Linux题目不是简单的“如何查看文件内容”这种初级题而是直接给你一个线上故障场景让你用命令去排查。我印象最深的一道题是服务器CPU使用率持续100%你怎么找出是什么进程导致的完整的排查路径如下用top命令查看系统整体的CPU占用情况找到CPU占用率最高的进程PID。用top -H -p PID查看该进程内部所有线程的CPU占用情况定位到具体是哪个线程在消耗CPU。如果进程是Java应用需要找到线程ID转换成十六进制printf %x 线程ID。用jstack PID thread_dump.txt导出线程快照然后在dump文件中搜索步骤3转换出的十六进制线程ID。在线程快照中定位到对应的线程栈信息找到具体的代码行号这通常就是问题的根源。这套排查路径放到今天依然是JVM应用CPU飙高问题排查的标准流程。我建议每个做运维或后端的同学都亲手在测试环境模拟一遍这个流程。方法很简单写一个死循环的Java程序然后在服务器上跑起来按照上面的步骤一步步走一遍。做过一次之后你对这个排查流程的理解深度会远超只看文章的效果。另外Linux这块还有一些送分题但你容易丢分的点。比如curl -I和curl -v的区别-I只发送HEAD请求获取响应头信息-v会输出完整的请求和响应过程包括DNS解析、TCP握手、TLS协商的详细日志。排查网络问题用-v的次数远多于-I这两个参数的区别虽然基础但用得好不好直接体现工程经验。4.2 网络排查思路与工具效率对比运维方向最核心的竞争力是网络问题的排查能力。这套题里有一道开放题用户反馈B站视频加载很慢你如何一步步排查我推荐的排查路径是分层排查法第一层先确认是不是客户端的问题。让用户切换网络环境如果Wi-Fi慢但4G/5G正常那问题大概率出在用户所在网络的运营商链路或路由器配置上。这一步的沟通成本最低但往往能先排除一半的干扰项。第二层服务端全链路检查。用ping确认服务器是否可达看延迟和丢包率用traceroute或mtr察看经过的每一跳路由定位是哪一段链路延迟偏高用dig检查DNS解析是否正常解析耗时多少是否返回了离用户最近的CDN节点。第三层应用层指标检查。查看服务器的CPU、内存、带宽占用情况查看Web服务器的访问日志确认视频文件请求是否命中了CDN缓存查看数据库和缓存的慢查询日志和命中率检查消息队列是否堆积。我把这个思路用表格整理一下方便对照使用排查层级核心问题常用工具/命令关键指标客户端用户网络环境是否正常切换网络、浏览器开发者工具资源加载耗时、失败请求数网络链路DNS解析是否正常dig、nslookup解析耗时、返回IP是否合理网络链路路由转发是否异常ping、mtr每跳延迟、丢包率服务端基础设施资源是否充足top、free、df -hCPU使用率、内存余量、磁盘IO服务端应用性能是否达标日志分析、APM工具接口响应时间、错误率、GC频率服务端依赖组件是否健康Redis info、MySQL慢查询日志命中率、慢查询数量、连接数实际工作中你会发现大部分“视频加载慢”的case最后都能在第三层找到根因。但如果你跳过前两层直接查应用日志很可能会在错误的方向上浪费大量时间。4.3 容器化与CI/CD的笔试题解析2019年是Docker容器化逐渐成为运维标配的年份这套题的运维部分也涉及了容器化的内容。有一道题是请对比Docker和传统虚拟机的区别并说明Docker在部署流程中的优势。这道题看似基础但想答出深度需要抓住几个关键点传统虚拟机通过Hypervisor虚拟化硬件每个虚拟机都有独立的操作系统内核资源隔离性好但启动慢、开销大。Docker容器则共享宿主机的操作系统内核通过Namespace做资源隔离通过Cgroups做资源限制启动速度是秒级的资源占用远小于虚拟机。Docker在部署流程中的核心优势我总结为三个词标准化、版本化、快速交付。标准化体现在镜像上。开发环境、测试环境、生产环境都使用同一个镜像启动容器彻底告别了“在我机器上能跑”的问题。版本化体现在镜像Tag上。每次发版都构建一个新的镜像并打上版本号一旦线上出问题回滚到上一个Tag的镜像就行做到了秒级回滚。快速交付体现在流水线自动化上。开发代码提交后自动触发构建、测试、镜像构建、推送镜像、部署到服务器的完整流程。这就是CI/CD的雏形。放到2026年再回头看当年这道题的底层逻辑依然没有变只是工具链从Docker延伸到了Kubernetes。如果你现在准备面试可以在回答完Docker的基础内容后主动延伸一下Docker解决的是“单机上的标准化交付”而Kubernetes解决的是“分布式环境下的编排调度”。这两个层次的区别能体现出你对容器化技术演进有全局认知。5. 移动端方向考点精讲与实操要点5.1 Android生命周期与内存管理机制移动端的笔试题Android平台的内容是主力。B站在2019年时的移动端业务主要包括B站App、哔哩哔哩漫画等这些App的共同特点是功能复杂、页面多、有大量图片和视频相关内容。所以这套题的移动端部分生命周期和内存管理自然成了考察重点。Android的Activity生命周期属于基础中的基础但B站这套题的出题方式很巧妙它没有直接让你默写生命周期方法而是给你一个具体的场景——正在播放视频时来电Activity的生命周期会发生怎样的变化这个场景考察的是你能不能把生命周期方法放到真实业务中理解来电时Activity先执行onPause()此时App不可交互但在前台可见区域可能还有残留。电话接通后Activity执行onStop()App完全不可见。电话挂断后Activity执行onRestart()→onStart()→onResume()恢复到可交互状态。在onPause()中应该做的事情是暂停视频播放、暂停弹幕滚动、释放不必要的资源。因为onPause()执行时间极短不适合做耗时操作这也是开发者最容易踩坑的地方——很多人习惯在onPause()里保存数据但如果数据量大可能会导致掉帧卡顿。内存管理这块最常被问的就是内存泄漏。B站App里有大量图片资源的加载和销毁如果处理不当最容易出现的就是Bitmap导致的内存泄漏。典型的场景是Activity已经销毁了但Bitmap对象还被某个静态变量持有引用导致Activity无法被GC回收内存越用越多最终OOM崩溃。排查内存泄漏的工具我用过的最经典组合是Android Studio自带的Memory Profiler加上LeakCanary。LeakCanary这个库可以自动检测内存泄漏定位到泄漏发生的引用链。我建议准备Android面试的同学自己写一个存在内存泄漏的Demo然后用LeakCanary把泄漏链分析一遍加深印象。这个实操经历在面试中讲出来比单纯说“我知道内存泄漏”要有说服力得多。5.2 网络层优化与弱网环境适配B站的业务场景中移动端用户经常在地铁、电梯、地下车库等弱网环境下刷视频。网络层的优化对用户体验至关重要。这套题里有一道相关的场景题如果一个用户的网络从Wi-Fi切换到4G网络App的网络连接有哪些潜在风险你如何应对这个问题考察的是移动网络切换时的连接稳定性处理。核心风险点是网络切换会导致IP地址变化正在进行的TCP连接会断掉如果App内已有请求正在执行可能会失败。应对方案包括在网络切换监听器ConnectivityManager的NetworkCallback中检测到网络变化后立即取消当前所有未完成的请求使用新的网络通道重新发起请求。针对关键接口如视频续播、弹幕重连设计自动重试机制重试时加入指数退避策略避免网络恢复瞬间所有客户端同时重试导致服务器被打垮。为视频播放器设置网络缓冲区策略在弱网环境下自动降低视频清晰度保证画面流畅优先于画质清晰。另外Android 7.0之后App的多网络支持能力也是考点。你可以补充如何通过NetworkCallback监听特定网络的可用性以及如何针对不同的网络类型设置不同的DNS解析策略。这些细节能让面试官感受到你确实做过移动网络优化相关的实践而不是在背资料。5.3 性能优化核心能力启动速度与流畅度优化移动端笔试的最后一类重点题型是性能优化。B站的App场景很典型启动时要加载首页推荐流、检查更新、拉取配置中心数据、建立长连接等如果这些任务全部在主线程上执行启动过程会卡顿明显。启动速度优化的核心思路是“异步化与延后化”。我梳理一下常规的优化手段用异步线程池处理初始化任务。把启动时的初始化任务分类哪些是必须在主线程执行的如onCreate中的基础UI初始化哪些是可以异步的哪些是可以延后到首页渲染完成后再执行的。用启动器框架如阿里开源的Alpha启动器管理初始化任务的依赖关系并行执行无依赖的任务让关键任务优先完成。用Trace工具分析启动耗时。Android Studio自带的CPU Profiler可以生成启动过程的Trace文件你能直观地看到每个方法占用了多少时间哪些耗时操作可以挪位。流畅度优化的核心指标是帧率FPS。掉帧的原因通常是主线程做了耗时操作导致系统无法在16.6ms内完成一帧的绘制。定位方法是用Systrace或Perfetto查看主线程的执行情况找到占用时间过长的方法。常见的原因包括布局过度绘制、主线程IO操作、频繁创建对象导致GC卡顿等。我建议大家在准备这个话题的时候不只是看资料而是真的打开自己的App或者任意一个开源项目用CPU Profiler和Systrace实际做一次性能分析把发现的性能瓶颈记录成文档。有了这样的实操记录笔试和面试中你再聊性能优化底气完全不一样。6. 常见问题与排查技巧实录6.1 笔试中最容易丢分的三个低级错误我拿这套题让团队几个校招生做了一遍整理出三个最常见的丢分点这里分享出来你复习时一定要避免。第一不写过程直接给结果。很多技术题的计算结果本身只占很少的分数真正占分的是你如何推理、如何拿公式、如何考虑边界条件。比如让你估算一个接口的QPS上限光给一个数字没有任何意义你要把计算过程写清楚平均响应时间是多少、线程池配置是什么、数据库连接池有多少个、每个请求占用多少资源这些推理过程才是面试官真正想看的。第二背答案但不理解原理。这个在框架题上表现得最明显。比如问Vue的nextTick实现原理很多人能背出“在下次DOM更新循环结束后执行延迟回调”但一问到“底层是用MutationObserver还是Promise实现的”就答不上来。这种“知其然不知其所以然”的状态在笔试的追问环节非常容易被识破。第三遇到不会的题直接空着。笔试不是高考不会的题也可以写思路、写伪代码哪怕只写出“我打算用分治的思路来解决”都能拿到一点过程分。空着不仅丢分面试官还会认为你缺乏解决未知问题的勇气。正确做法是把已知条件列出来把能想到的解决方向写出来哪怕最后的实现是错的也能体现你的思考过程。6.2 如何规划笔试答题时间这套题是四个方向共用一套题量不小。时间分配不合理很容易出现会做的题目来不及做完的情况。我的建议是按照“先易后难、分段检查”的策略来分配时间。第一步拿到试卷后先用2分钟快速浏览全部题目按照“必做/可选/难题”三个等级把题目分类。必做题是那些你有把握拿高分的难题是那些你可能会但需要花时间的难题的优先级放在最后。第二步先做必答题控制在总时间的50%以内。这些题是你最有信心的尽量拿到满分。做完之后立刻检查一遍确认没有因为粗心丢失分数。第三步做可选但有点把握的题控制在总时间的30%。遇到卡壳的地方如果超过5分钟想不出来先跳过做完后面的再回头想。第四步最后剩余时间处理难题和检查。这时候千万不要钻牛角尖难题能写多少写多少核心是过程中要体现思路。6.3 从笔试到面试的准备建议笔试只是第一关它的意义除了筛选还在于暴露你的知识盲区让你在面试前有方向地补齐短板。我建议你笔试之后立刻做三件事。第一件复盘每一道错题。不要把错题归因为“我粗心了”而要深挖到底是哪个知识点不熟悉导致的错误。如果是网络相关的题错了就把HTTP/TCP相关的知识从头过一遍如果是数据库的题错了就把索引和事务重新学一遍。我在这套题的复盘过程中发现很多人丢分最多的其实是公共基础部分而不是自己岗位方向的内容这个结论你可以参考复习时不要把公共部分漏掉。第二件针对薄弱点做小项目练手。比如在复习后端岗位的Redis部分时可以动手写一个基于Redis的排行榜服务不用很复杂只要能跑通核心逻辑就行。这个项目经历既能加深你对知识点的理解也能成为面试时展示的素材。第三件整理你自己的“面试小抄”。把容易混淆的点、常考的公式、常用的命令记录下来。这个东西不是用来作弊的而是作为一个知识索引在面试前快速过一遍能有效缓解紧张情绪。我自己的经验是面试前看一眼这些浓缩的要点比临时翻厚书管用得多。7. 应对这套题的长期学习路线7.1 基础不牢地动山摇计算机基础的优先级说到这我忍不住再强调一下计算机基础的重要性。你往后看所有的校招笔试题不管公司是哪个行业的不管岗位是前端还是后端计算机基础都是第一道门槛。计算机网络、操作系统、数据结构与算法这三门课就是技术面试的地基。B站这套题中的网络题、并发题、性能优化题全部可以追溯到这三门课里的底层知识。比如前端的渲染流程底层是浏览器的工作原理后端的并发编程底层是操作系统对线程的调度运维的网络排查底层是TCP/IP协议栈的运作机制。我建议的路线是先花一整块时间系统学一遍计算机网络不用纠结于每一个细节但要建立完整的知识框架。然后学操作系统重点理解进程和线程、内存管理、文件系统三块。数据结构与算法则需要持续性地刷题保持手感。这个顺序是符合实际应用场景的依赖关系的。7.2 动手实操有很多人准备了三四个月知识点背得滚瓜烂熟笔试和面试成绩却不理想。原因往往是缺少实操经验导致遇到需要动手的场景题就无从下手。针对B站这套题涉及的各个方向我建议你至少亲手完成以下这些实操项目做过的和不做过的面试表现差距会非常明显写一个完整的HTTP服务器支持静态文件托管和简单的路由分发。这个项目能帮你把TCP连接、HTTP报文、请求处理全链路串起来。用Docker容器化部署一个前后端分离的应用配置好MySQL和Redis依赖并写一个基础的docker-compose文件。这个项目覆盖了运维最核心的技能点。在Android模拟器上设置弱网环境可以通过模拟器自带的网络限速功能然后观察一个视频App在弱网下的表现记录并优化其中的问题。这些项目本身不复杂但你亲手做过之后笔试中遇到相关的场景题你对“这需要解决什么问题”“能采取什么手段”的理解会直接跃升一个档次。这是任何“速成宝典”都给不了的。7.3 从一套题到一类题的迁移能力这套题做完了你可能会想B站的题已经刷完了接下来干什么我的回答是不要继续刷题而是学会迁移。技术笔试的题型是高度相似的你真正要掌握的不是这套题本身而是这套题背后的一整套考察逻辑。你会看到前端问的URL渲染流程和后端问的HTTP请求处理底层是同一套网络知识体系运维问的Docker原理和移动端问的内存管理逻辑背后都是操作系统和资源管理的思想。当你刷完一套题应该形成这样的习惯把每道题归类到知识体系中标注出它考察了哪个基础知识点然后在脑海中检查这个知识点有没有在其他题目中出现过有没有可能在其他岗位的考察中换个形式出现。用这样的方式一套题可以变成十套题的复习效果。我个人在实际操作中的体会是2019年的这套笔试题放到今天来看价值不在于题目本身而在于它帮你划定了知识边界。离这套题的时代已经过去好几年了但那些基础的东西仍然是技术面试中不会过时的压舱石。按照这条路线扎实走下来你收获的不仅是一份笔试通过的通知更是一个能应对未来各种技术变化的地基。