当前位置: 首页 > news >正文

B站技术岗笔试复盘:前端、运维、后端与移动端核心考点解析

2019年秋招季,我前后投了不少视频社区方向的岗位,B站的笔试是让我印象最深的一批。和其他大厂不同,B站技术岗笔试题没有把前端、运维、后端、移动端放在同一张卷子里硬考,而是按方向分了多套题,第三套流传最广。这套题整体难度中等偏上,但区分度很高——基础题不白送,实战题也不浮空,不少题目直到我后来做项目才真正想明白出题人想问什么。这篇文章是我结合当年考场记录和后来复盘整理的版本,重点不是贴答案,而是把每道题背后的考点链、易错点和面试官视角拆开讲一遍。适合正在准备技术岗校招,或者想查漏补缺的工程师参考。

1. 前端笔试题复盘:基础扎实比炫技更重要

1.1 从一道“事件循环输出顺序”题说起

前端这套题里,最容易被轻视的是第一道代码题:给出一段setTimeout、Promise、async/await混用的代码,要求写出控制台输出顺序。题目本身不绕,但错误率极高。它考察的是JavaScript事件循环的完整链路——宏任务、微任务、同步代码、异步回调的排队规则。

我记忆里那道题大致长这样:

console.log('A'); setTimeout(() => { console.log('B'); }, 0); Promise.resolve().then(() => { console.log('C'); }); async function foo() { console.log('D'); await Promise.resolve(); console.log('E'); } foo(); console.log('F');

我当时是这样推理的:同步代码先执行,所以A、D、F依次输出。Promise.resolve().then()的回调C和await之后的E都属于微任务,按照入队顺序,C会排在E前面;setTimeout的回调B属于宏任务,要等当前宏任务执行完、微任务队列清空后才轮到。所以最终顺序是A、D、F、C、E、B。

多数人错在把await和Promise.then当作同一种排队方式,实际上await后面的代码相当于被Promise.resolve().then()包装,但async函数本身是同步执行的。遇到多级await时,需要一级一级拆开看。你可以把await看作一个"暂停标记",但真正的调度规则还是微任务队列。

这里给一个可复用的检查清单:先把同步代码画完,再标出所有微任务的入队顺序,最后才看宏任务。每次遇见Promise.resolve、async/await、process.nextTick混搭的题,按这个顺序推就不会乱。这道题在2019年并不算偏,但B站把它放在第一题,其实是在筛掉那些"只会用框架、不懂底层调度"的简历。

1.2 经典“防抖节流”手写题:两种实现的边界差异

第三套前端题里有一道手写题:实现一个防抖函数和一个节流函数。很多人背过模板,但题目额外要求"说明两者分别在什么场景使用,并处理this和event对象"。这就在考两个边界:

第一,防抖和节流的核心区别不是"延迟执行",而是"多次触发时如何合并"。防抖是把一段时间内的连续触发合并成一次,适合搜索框输入、窗口resize;节流是保证一段时间内至少触发一次,适合滚动加载、点击提交。写代码时要注意,防抖函数的定时器是否该在等待期间被clear,节流函数的首次触发是立即执行还是延迟执行,都会改变行为。

第二,this和event的处理。如果直接用setTimeout包裹回调,回调里的this会丢失,event对象也可能变成undefined。所以必须保存当前调用上下文:用function关键字而不是箭头函数,在返回的函数里缓存self = this和args = arguments,再传给定时器。有的候选人能写出防抖,但忽略了这条,面试官会追问"如果在Vue模板事件里绑定这个防抖函数会怎样",答不上来就很可惜。

一个不加额外讨论的防抖实现,至少要把上下文和参数传进去:

function debounce(fn, wait) { let timer = null; return function (...args) { const context = this; if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(context, args); }, wait); }; }

节流实现可以用时间戳,也可以用定时器,两者对"第一次触发是否执行"的处理不同。时间戳版第一次立即执行,定时器版第一次延迟执行。场景题里如果面试官问"滚动到底部加载更多,希望停止滚动后不再触发,用哪种",这时候防抖反而不合适,应该用节流加一个是否在滚动中的判断。

1.3 网络与浏览器缓存:考点背后的原理

前端题有一道关于缓存策略的选择题:一个静态资源URL,如何保证用户更新后能及时拿到新版本,同时减少不必要的请求?四个选项涉及Cache-Control、ETag、Last-Modified、Expires。这题表面是HTTP头配置,实际考的是强缓存和协商缓存的配合关系。

我当时的回答思路是:文件名加hash,配合Cache-Control: max-age=31536000实现强缓存;当文件名不变时,服务器可以返回ETag做协商缓存;如果业务需要即时更新,最好在版本发布时主动修改引用URL。关键是要明白,强缓存命中时根本不会发请求,协商缓存命中时会发一个带条件的请求但响应体很小。面试官还可能进一步问"为什么ETag优先级高于Last-Modified",因为Last-Modified只能精确到秒,且某些场景下文件内容变了但修改时间没变。

这类题在2019年几乎是前端必考,但B站喜欢在选项里埋坑,比如把"ETag优先级低于Last-Modified"这种说法混进去。复习时要连原理一起记,不能只记"结果"。实际项目里,特别要注意"Cache-Control: no-cache"不是"不缓存",而是"每次都要再验证一次"。如果被字面意思误导,很容易在配置CDN时出错。

2. 运维笔试题复盘:排查思路比命令本身更值钱

2.1 一道系统负载排查题的完整推理链

运维方向第三套题里有一道场景题:线上服务器load average达到20,CPU使用率却只有30%,问可能是什么原因、后续怎么排查。这道题没有标准答案,但考察的是排查链路是否完整。

我拆解的顺序是:先看load average的含义——它是运行队列中可运行线程和不可中断睡眠线程的平均数。CPU使用率低但负载高,说明大量进程在等待I/O。此时不能只盯CPU,要用iostat看磁盘的await和util,用vmstat看b列和wa列;如果是磁盘I/O问题,再用iotop定位是哪个进程在写;如果等待的是网络或者锁,就要结合上下文。如果这些都没有异常,还有一种可能:系统里出现了D状态(不可中断睡眠)的进程,例如NFS挂载超时或内核线程卡住。

这道题想考察的是:你遇到负载异常时,是直接重启,还是能找到"负载高"和"CPU高"的差异点。运维岗的核心价值不是会敲命令,而是有体系化的排查思路。我当时在答题纸上画了一条从现象到根因的决策链,面试官后来反馈说这是加分项。

具体来说,可以按这个顺序写:

  • 先执行uptime确认三个load值的方向。
  • 执行top看排队进程数,按CPU或MEM排序。
  • 执行vmstat 1 5,重点看r(可运行线程)、b(阻塞线程)、wa(I/O等待)三列。
  • 如果b和wa高,用iostat -x 1看磁盘util和await。
  • iotoppidstat定位具体进程。
  • 如果是D状态进程卡死,检查内核日志和挂载点状态。

这个链路看起来简单,但很多人只写到"查看load"就停了。笔试要把判断依据写完整,比如"wa高说明CPU在等磁盘,而不是被计算任务占满"。

2.2 Linux常见命令的隐藏考点:top/ps/netstat

笔试里还专门出了一道选择题,问top输出中load average的三个数值分别代表什么。很多人知道是1分钟、5分钟、15分钟的平均负载,但选项里混入了"三个CPU核数"这种干扰项。类似的还有ps -ef和ps aux的差异,netstat -tunlp和ss -tunlp的使用场景。

这些命令在运维工具箱里是主力,但笔试不会直接问你"如何查看端口占用",而是给一段输出,让你判断哪一列是进程名、哪一列是监听地址。比如netstat输出中的Recv-Q和Send-Q,如果数值持续变大,说明接收队列或发送队列积压,常见原因是应用处理不过来或对端不读数据。这种细节需要平时靠tcpdump抓包观察,光背命令记不牢。

另外,2019年那会儿systemd已经普及,但很多笔试考点还停留在SysVinit时代,比如chkconfig、service。B站当时没有考这些偏门的,反而考了systemctl的常见操作和unit文件依赖关系。复习时最好把新旧两套命令对照着看,别被过时的教程带偏。

针对命令类题目,我的建议是动手搭一套虚拟机环境,把top、ps、netstat、ss、lsof、iostat、vmstat、sar这些命令的典型输出截图打印出来,练习一眼定位关键列。笔试不是让你默写参数,而是给你一个真实输出,让你解释异常点在哪里。

2.3 网络问题定位:从Ping不通开始

运维方向还有一道经典题:用户反馈某个内部系统无法访问,Ping不通,如何一步步排查?这道题几乎是大厂运维笔试的标配,第三套题里它的变体是区分"是网络不通还是服务不通"。

我的排查顺序是:先从本机出发,ping网关确认本机网络是否正常;再ping目标IP,看ICMP是否通;如果IP通但域名不通,查DNS解析;如果IP不通,用traceroute看路径上哪一跳丢包;最后如果网络层全通,再用telnet或nc测目标端口,判断服务是否在监听。笔试答题时不能只写命令,还要写出每一步的判断依据和分支条件,比如ping网关不通时应该检查网卡和路由表。

这里有一个容易忽略的点:有些网络策略会禁ICMP,Ping不通不代表TCP不通。所以最后一步一定要测端口,用curl访问HTTP服务也很有用。答完整条链路,面试官才认为你有真实排障经验,而不是背了一堆命令。

网络层排查经常会和DNS混淆。如果内网域名解析超时,Ping域名和Ping IP会呈现完全不同的现象。笔试题目里会故意给出一段nslookup输出,让你判断是DNS服务器问题还是缓存问题。这种题需要理解DNS递归和迭代查询的基本流程,其实不难,但很多人没在真实环境里抓过包,只靠背题很容易掉坑。

3. 后端笔试题复盘:设计能力和细节并重

3.1 一道SQL场景题的索引优化分析

后端这套题里有一道SQL题:给出一张用户订单表和一段慢查询,要求分析如何优化。表结构大概是user_id、order_id、amount、status、create_time,慢查询的WHERE条件是"WHERE user_id = ? AND status = ? ORDER BY create_time DESC",数据量百万级。

我的第一反应是在user_id和status上建立联合索引,但要注意顺序:等值查询的字段放前面,排序字段放最后。所以最合适的索引是(user_id, status, create_time)。为什么不是(status, user_id, create_time)?因为等值条件区分度更高的是user_id,把它放第一位能更快定位到目标用户的数据。如果只建(user_id, create_time)也能满足user_id过滤和排序,但status过滤会在回表后进行,效率不如三列联合索引。

面试题里还问:如果status区分度很低,是否值得放在索引里?实际上联合索引可以覆盖查询,避免回表,即使字段区分度低,只要查询条件固定,放在索引里就有意义。关键是要理解B+树索引的最左前缀原则,以及索引如何同时满足等值过滤和排序需求。我在答题时画了简单的索引结构示意,比直接写"加索引"更有说服力。

这里还可以继续展开:如果查询要按create_time排序,数据库是选择索引排序还是文件排序?当索引前缀列包含create_time时,MySQL可以直接顺序扫描索引取得排序结果,避免filesort。如果条件里status是范围查询,那么索引中create_time就无法参与排序优化了,这时候可能需要考虑把范围查询改成等值,或者在应用层提前过滤。笔试答案里能写出这一层"范围查询会中断排序优化"的细节,就已经超过大多数候选人了。

3.2 JVM与并发:为什么总在问“内存溢出”

后端卷子还考了一道JVM内存溢出场景题:一个Java服务运行几天后响应变慢,堆内存不断增长,Full GC频繁,但老年代回收效果差,可能是什么原因?选项里有内存泄漏、代码中持有大对象、JVM参数设置不当、线程池配置过大等。

这题的考察点不是背JVM结构,而是区分"内存泄漏"和"内存过大"。如果是泄漏,GC后内存仍然持续增长;如果是分配速率过高,通常调整堆大小或对象缓存策略就能缓解。答题时应该给出排查方法:用jmap导出堆dump,用MAT或VisualVM分析对象引用链;同时用jstat看GC日志,观察各代内存变化。笔试作答时写清楚"先查GC日志,再抓堆dump,最后看线程堆栈"这套流程,比单纯写"可能是内存泄漏"要高分数得多。

更具体地说,内存泄漏的常见模式是:静态集合类不断添加对象,但从不移除;或者使用ThreadLocal时没有调用remove,导致线程对象上的Entry无法释放。如果是线程池,每次任务都往ThreadLocal里塞上下文,线程复用后Value仍然被引用,就可能撑爆堆。笔试问到这类题,如果能把"ThreadLocal的内存泄漏"作为例子写出来,面试官会眼前一亮。

并发部分也有一道题:多个线程同时递增一个count,为什么最终结果小于预期?要答出i++不是原子操作、内存可见性、以及使用AtomicInteger或synchronized/Lock解决。这道题虽然基础,但B站会追问"volatile为什么不能解决i++的原子性问题",因为volatile只能保证可见性和有序性,不能保证复合操作的原子性。这个追问能筛掉一大半背面试题的人。

回答这道题时,最好画出两个线程同时读取count为10,然后各自加1,最终写回11的时序。笔试答题纸上画图比较慢,可以用文字描述"read-modify-write"三步的竞态窗口,再说明如何用CAS或加锁消除。

3.3 一道接口幂等性设计题的边界讨论

后端方向还有一道设计题:用户重复提交订单,如何保证接口幂等?这种题在2019年秋招里很常见,但B站给的场景更具体——用户点了两次"支付",后端收到两个相同orderId的请求。

答题时要分场景:如果请求是同步的,可以在业务入口用Redis SETNX设置一个"处理中"的key,并带上超时时间;如果请求走MQ,可以基于消息ID做去重表;如果是对账系统,可以用数据库唯一索引兜底。重点是说明分布式环境下"检查再插入"存在竞态,必须用带原子性的操作,比如Redis的setnx,或者DB唯一约束。同时要考虑幂等键的失效时间、重试机制、接口返回的语义是否一致。

我当时额外补充了"最终一致性"的思路:即使某个请求超时,前端显示失败,后端通过回调或定时对账最终完成订单,这也能保证不重复扣款。踩坑时要注意,光靠前端按钮置灰不叫幂等,因为恶意请求或重试工具可以绕过前端。笔试里把这类边界写清楚,面试官会觉得你有真实项目的复杂度意识。

还有一个容易被忽略的点:幂等不只是一次请求只生效一次,还包括"重复请求返回的结果应该和第一次一致"。比如支付成功接口,第一次返回成功,第二次重复请求时如果返回"订单已完成"而不是"成功",对客户端来说语义不同,可能导致前端重复发起轮询。所以设计幂等key时,通常会把请求参数+来源标识一起hash,保证同一来源的重复请求能被识别。

4. 移动端笔试题复盘:性能优化和适配是主旋律

4.1 一道“卡顿优化”场景题的回答框架

移动端这套题里有一道典型的性能优化题:一个视频列表页滑动卡顿,如何定位和优化?答案不外乎布局层、渲染层、数据层、内存层,但B站把场景限定在"Android端RecyclerView(或iOS端UICollectionView)列表,每项有封面图、标题栏和滚动播放的预览视频"。

我的分析框架是:先用Systrace(Android)或Instrument(iOS)查看主线程耗时,确认是掉帧还是丢帧;再看布局复杂度,减少嵌套、合并层级;检查图片加载是否用了合适的采样率,避免大图直接加载到内存;列表复用时是否在onBindViewHolder里做了耗时操作,比如频繁创建对象

http://www.cnnetsun.cn/news/4320483.html

相关文章:

  • 《妃梦千年》第38章-归途之择
  • C 语言学习笔记(六)
  • 福瑞兽剧预告片制作全流程解析:从兽设建模到渲染合成
  • 【计算机毕业设计】基于深度学习的智能交通流量预测 Web 系统
  • 《易学・姤䷫|道影子新解 044》
  • 游戏NPC接入大语言模型为何难?从确定性、实时性到成本解析
  • QCA7000/7005 SPI驱动开发指南:MCU与电力线通信芯片的通信实现
  • GFS-VL:融合3D VLM稠密知识与少样本校准的点云分割
  • AI蜂群逃逸与多智能体系统安全:沙箱防护实践指南
  • 从单片机到ROS2:机器人嵌入式物联网自学路线全攻略
  • 从零训练二次元角色LoRA:Stable Diffusion角色一致性实战全流程
  • 八电HOLOLIVE vs 八门P5X:WS练习局触发轴与资源节奏拆解
  • Hypermesh 2024前处理实战:网格划分、质量检查与节点显示问题
  • ESP8266 与 ESP-01S 到底是什么?从 Wi-Fi SoC 到串口联网模块,新手一篇快速看懂
  • Luckysheet集成实践:从zip解压到Excel转JSON的全流程指南
  • LVGL 9.0移植到STM32F746G-DISCO与性能基准测试实战
  • 用 Scrapy 爬取百家姓与姓氏源流数据:多源采集、数据清洗与结构化存储实战
  • 直播录像处理实战:FFmpeg转码切片与批量归档全流程
  • 266美元+四个AI模型,一天打造AI小镇应用:开源项目实战
  • 阿里编程题4星刷题体验:从算法建模到树状数组的实战解析
  • 【设计模式精讲】5.工厂方法(Factory Method)
  • S7-1200 MODBUS轮询库V15:多从站通信高效封装方案
  • YOLOv8农田作物倒伏识别系统:从环境搭建到部署实战解析
  • 2026 Agentic AI 智能体:让 AI 从“聊天“走向“自己干活“(MonkeyCode 实战)
  • OpenRouter 排障指南:API 网关原理、常见报错与 Claude Code 接入
  • 基于LSTM+CNN的光伏发电功率预测系统实战解析
  • Claude Code控制机械臂:从仿真到真机的安全实践
  • 专业的AI基座机构
  • 从字幕到Anki卡片:构建英语学习自动化流水线
  • 90%新手都踩的Python环境坑!版本冲突彻底解决指南 |数智码力