数据来源:真实面经整理 | 版本:final


一、公司画像 & 校招节奏

哔哩哔哩(bilibili,B站)成立于,总部上海,是国内最具代表性的年轻世代内容平台。MAU超3.4亿,日均视频播放量超4亿次,员工约1万人。目前纳斯达克+港股双上市,主营业务覆盖视频、直播、游戏、电商。

B站有两个技术特点值得重点关注:第一,后端以Go为主力,C++在音视频处理方向占主导,这决定了你必须至少精通其中一门,两门都会当然更好;第二,弹幕系统是B站的技术名片,全球最复杂的实时弹幕推送技术就在B站,面试官对弹幕相关的系统设计题有天然的热情,这一块必须准备。

文化层面,B站技术团队普遍年轻,二次元氛围浓厚,面试风格比字节轻松,但技术考察深度不打折。不少同学反映B站面试官"问得很细,但不是为了为难你,更像是在讨论问题"。

主要招聘方向:

方向 代表业务 技术侧重
后端开发(Go为主) 弹幕、视频、直播 Go + 微服务,高并发
客户端(Android/iOS) B站App 视频播放器,Kotlin/Swift
音视频工程师 投稿/转码/播放 C++,FFmpeg,编解码
算法工程师 推荐、搜索 Python + C++,召回 + 精排
前端开发 Web/小程序 Vue/React,WebAssembly
数据开发 用户行为分析 Flink/Spark/ClickHouse

校招节奏(参考):

阶段 时间 行动建议
暑期实习转正 实习中做出业绩,争取转正名额
正式网申 jobs.bilibili.com,简历要突出Go/C++项目
笔试 编程题3-4道 + 选择题(语言基础),约90-
技术面试 2-3轮技术面 + 1轮HR面
Offer发放 留意邮件,及时确认

备考时间建议:提前2个月开始,Go语言和弹幕系统设计至少各投入时间,这两个是B站面试的核心差异点。


二、岗位 JD 解析:技术要求拆解

B站JD写得相对简洁,但真实的考察重心从面经数据里看得很清楚。

后端开发(Go方向)

能力维度 JD要求 真实考察重心 备考权重
Go语言 熟悉Go语言 GMP调度/Channel/逃逸分析/GC,每轮必问 ⭐⭐⭐⭐⭐
高并发 高并发系统设计 百万弹幕并发场景,结合业务考 ⭐⭐⭐⭐⭐
弹幕/直播 了解实时系统 弹幕推送完整方案,B站特色题 ⭐⭐⭐⭐⭐
数据库 MySQL/Redis ZSet排行榜、HyperLogLog UV统计 ⭐⭐⭐⭐
消息队列 了解MQ Kafka在弹幕异步处理中的应用 ⭐⭐⭐⭐
算法 数据结构与算法 Medium题为主,链表+LRU高频 ⭐⭐⭐⭐

音视频工程师(C++方向)

能力维度 JD要求 真实考察重心 备考权重
C++语言 精通C++ 智能指针原理,手写实现 ⭐⭐⭐⭐⭐
编解码 音视频基础 H.264/H.265/AV1,I/P/B帧原理 ⭐⭐⭐⭐⭐
FFmpeg 了解FFmpeg 转码流程,命令行使用 ⭐⭐⭐⭐
网络传输 流媒体协议 HLS vs DASH vs RTMP的场景选择 ⭐⭐⭐⭐
内存管理 C++内存管理 RAII,智能指针,手写shared_ptr ⭐⭐⭐⭐⭐

核心差异点:B站面试与其他大厂的不同

两个考点在B站出现频率明显高于其他公司:

Go逃逸分析:其他大厂很少深问,B站几乎每轮都会问。逃逸分析影响性能,B站后端性能要求高,所以这是刚需知识,不是选考内容。

弹幕系统设计:这是B站面试的"必做题"。不是"可能考",是"一定考"。弹幕推送、弹幕存储、弹幕过滤、弹幕同步,这四个方向都要准备。


三、LeetCode 高频题 Top 20(真实面经数据)

B站算法题整体难度:Medium为主,Hard出现概率低于字节,但Medium要做到熟练。Go和C++方向侧重点有差异——Go方向侧重系统设计+基础算法;C++方向会要求手写数据结构(比如自己实现shared_ptr)。

第一梯队:必刷(每道至少做3遍)

排名 题目 题号 出现频率 考察方向 B站特色备注
1 反转链表 No.206 ⭐⭐⭐⭐⭐ Go/C++均考 入场券,不会直接淘汰
2 LRU缓存机制 No.146 ⭐⭐⭐⭐⭐ 高频,与弹幕缓存结合 会追问"弹幕池怎么用LRU设计"
3 二叉树层序遍历 No.102 ⭐⭐⭐⭐ 各种变形 考变形题:按层输出/锯齿形
4 无重复字符最长子串 No.3 ⭐⭐⭐⭐ 滑动窗口基础 有时结合字符串处理场景
5 合并K个排序链表 No.23 ⭐⭐⭐⭐ 中高频 考堆的使用,C++方向必刷

第二梯队:高频(至少做2遍)

排名 题目 题号 出现频率 考察方向
6 数组中的第K个最大元素 No.215 ⭐⭐⭐⭐ 堆/快选
7 三数之和 No.15 ⭐⭐⭐⭐ 双指针
8 合并两个有序链表 No.21 ⭐⭐⭐⭐ 链表基础
9 环形链表 No.141 ⭐⭐⭐⭐ 快慢指针
10 二叉树的最近公共祖先 No.236 ⭐⭐⭐ DFS递归
11 合并两个有序数组 No.88 ⭐⭐⭐ 双指针
12 K个一组翻转链表 No.25 ⭐⭐⭐ 链表进阶
13 合并区间 No.56 ⭐⭐⭐ 排序+贪心
14 接雨水 No.42 ⭐⭐⭐ 双指针/单调栈
15 重排链表 No.143 ⭐⭐⭐ 链表综合

第三梯队:中频(至少做1遍)

排名 题目 题号 出现频率 考察方向
16 岛屿数量 No.200 ⭐⭐⭐ BFS/DFS
17 全排列 No.46 ⭐⭐ 回溯
18 最长回文子串 No.5 ⭐⭐ 动态规划/中心扩展
19 滑动窗口最大值 No.239 ⭐⭐ 单调队列
20 编辑距离 No.72 ⭐⭐ DP进阶

刷题规律总结

规律1:链表题是基本盘。反转、合并、环检测、K组翻转,这些链表题出现频率很高,Go和C++两个方向都要刷透。

规律2:LRU要和弹幕场景结合理解。单纯刷LRU不够,面试官会问:"B站弹幕池怎么设计?弹幕量超大怎么分层?" 要能把LRU和实际业务场景接通。

规律3:Hard题不是重点。B站很少出Hard题,Medium刷到熟练远比硬磕Hard题有价值。时间有限的话,第一梯队5题 + 第二梯队10题,优先级高于第三梯队。

规律4:音视频岗有数据流相关题目。如果投音视频工程师,偶尔会考数据流处理相关的题目,比如求数据流中的中位数(No.295),要额外注意。


四、技术面试考点

Go语言专项(后端核心)⭐⭐⭐⭐⭐

GMP调度模型(每轮必问): - G(Goroutine):用户态轻量级线程,初始栈2KB,可增长 - M(Machine):内核线程,M:N模型中的N端 - P(Processor):逻辑处理器,数量由GOMAXPROCS决定,绑定G队列 - 调度时机:channel阻塞、syscall、主动yield(runtime.Gosched())

面试官最爱追问:"P的本地队列满了怎么办?"(答:放入全局队列,其他P可以偷取——work stealing机制)

Channel机制(高频考点): - 向已关闭的channel发送数据 → panic - 从已关闭的channel读取数据 → 返回零值,ok为false - 无缓冲channel:发送和接收必须同时就绪(同步) - 有缓冲channel:缓冲区满时发送阻塞,缓冲区空时接收阻塞

逃逸分析(B站特色高频考点):

这个考点在B站出现频率明显高于其他大厂,因为B站后端对性能要求高,逃逸分析直接影响GC压力。

三种典型逃逸场景: 1. 接口赋值:var i interface{} = x,x会逃逸到堆 2. 返回局部变量指针:函数返回指向局部变量的指针,该变量逃逸 3. slice动态扩容超过栈限制:大对象直接在堆上分配

如何分析逃逸:

go build -gcflags="-m" main.go

输出中有escapes to heap就是逃逸了。

逃逸的影响:堆上分配需要GC介入,压力大;栈上分配自动回收,性能更好。优化手段:使用sync.Pool复用对象,减少堆分配频率。

面试官高频追问:"你在项目里有没有用逃逸分析优化过性能?"——要有一个具体案例。

GC相关: - Go使用三色标记+写屏障的并发GC - 减少GC压力的方法:减少内存分配次数、使用sync.Pool复用、避免大量小对象

切片底层: - 切片是{ptr, len, cap}三元组 - 多个切片共享底层数组时的修改问题(append可能触发扩容,导致底层数组不再共享)


C++专项(音视频/客户端方向)⭐⭐⭐⭐⭐

智能指针原理(B站特色考点):

B站C++方向对智能指针的考察深度,在国内大厂中属于顶级水平。仅仅知道"unique_ptr独占,shared_ptr共享"是不够的,要能解释底层原理。

unique_ptr: - 独占所有权,不可复制,只可移动(move语义) - 析构时自动释放资源,零开销抽象(和裸指针性能一样)

shared_ptr: - 引用计数机制(内部用原子操作保证线程安全) - 底层有两个指针:一个指向对象,一个指向控制块(control block) - 控制块存储:引用计数、弱引用计数、删除器 - make_shared<T>()只分配一次内存(对象+控制块合并),比shared_ptr<T>(new T())更高效

weak_ptr: - 不增加引用计数,不拥有对象所有权 - 通过lock()获取shared_ptr,如果对象已释放则返回空 - 核心作用:打破循环引用

循环引用经典场景(面试必考):

struct A { shared_ptr<B> b; };
struct B { shared_ptr<A> a; };
// A引用B,B引用A → 引用计数永远不为0 → 内存泄漏
// 解决:把其中一个改为weak_ptr
struct B { weak_ptr<A> a; }; // 不增加引用计数,打破循环

面试官高频追问链: - "shared_ptr线程安全吗?"(答:引用计数操作是线程安全的,但同时读写同一个shared_ptr对象不是线程安全的) - "为什么用weak_ptr能解决循环引用?"(答:weak_ptr不增加引用计数,A的引用计数可以降为0,触发析构)

右值引用与move语义: - std::move:将左值转换为右值引用,不做实际移动,只是类型转换 - 移动构造函数:接管资源所有权,被移动对象置于有效但未指定状态 - 完美转发:std::forward<T>(arg),保持参数的值类别

虚函数与vtable: - 每个含虚函数的类有一个vtable(虚函数表),存放函数指针 - 每个对象有一个vptr(虚指针),指向所在类的vtable - 多继承时有多个vptr,vtable布局更复杂


弹幕系统设计(B站独特考点)⭐⭐⭐⭐⭐

这是B站面试中最有特色的考点,其他公司不会考,但B站几乎必考。完整的弹幕系统方案要从四个维度准备:

维度1:实时弹幕推送 - 用户发弹幕 → 后端接收 → 广播给同一视频的所有在线用户 - 技术选型:WebSocket长连接(比HTTP轮询延迟低、服务器压力小) - 消息广播:同一视频的用户订阅同一个Topic,通过Kafka解耦发送和接收 - 分组策略:按视频ID分组,避免全局广播

维度2:弹幕存储 - 热数据:Redis缓存最近N条弹幕(N = 100~500,按视频播放时间轴存储) - 冷数据:MySQL或Cassandra持久化(Cassandra写入性能更好,适合大量弹幕写入) - 存储设计:以视频ID + 时间戳为主键,支持按时间范围快速查询

维度3:弹幕过滤 - 关键词过滤:DFA算法(确定性有限自动机),构建敏感词树,O(n)时间复杂度 - AI审核:对疑似违规弹幕进入AI审核队列,异步处理 - 用户维度:屏蔽特定用户、屏蔽自定义关键词

维度4:弹幕同步(视频暂停/快进) - 弹幕绑定视频时间轴(PTS,Presentation Timestamp),不是绝对时间 - 用户快进到180s → 拉取180s附近的弹幕缓存 - 暂停 → 停止新弹幕推送,恢复播放 → 重新订阅当前PTS的弹幕流

百万并发弹幕的处理: - 垂直拆分:按视频ID分片,热门视频单独部署WebSocket服务节点 - 水平扩展:无状态的WebSocket服务,通过一致性哈希路由 - 消峰:Kafka作为缓冲层,消费端异步写入存储

高频追问:"弹幕的实时性和一致性如何平衡?"(答:弹幕不需要强一致性,最终一致性即可。优先保证实时性,允许极小概率的弹幕乱序或短暂延迟)


数据库专项(通用方向)⭐⭐⭐⭐

Redis高级数据结构(B站常考): - ZSet实现热门视频排行榜:ZADD rank 播放量 视频ID,ZREVRANGE rank 0 9取Top10 - HyperLogLog统计视频UV:PFADD uv_视频ID 用户ID,PFCOUNT uv_视频ID - 为什么用HyperLogLog?误差率约0.81%,内存只需12KB,而Set存储千万UV需要几百MB - Bitmap统计用户签到:每个bit代表一天,一年只需46字节

MySQL分库分表: - 视频稿件表按uid分库(根据用户ID取模) - 弹幕表按视频ID分表(同一视频的弹幕在同一分片) - 跨分片查询问题:避免跨库JOIN,用业务层聚合

Kafka在弹幕场景的应用: - Topic:一个视频对应一个或多个Partition - 弹幕写入:生产者发布弹幕消息 → 消费者异步写入存储 → 广播给在线用户 - 保证顺序:同一视频的弹幕发到同一Partition,单Partition内消息有序


音视频基础(音视频岗)⭐⭐⭐⭐⭐

编解码基础: - H.264/AVC:最广泛支持,压缩效率均衡,硬件解码支持好 - H.265/HEVC:同质量比H.264节省约50%带宽,但编码复杂度更高 - AV1:开源免版税,压缩效率优于H.265,B站正在推进AV1转码 - I/P/B帧:I帧完整关键帧(最大)、P帧参考前帧(中)、B帧双向参考(最小)

流媒体协议选择: - RTMP:低延迟(约1-3秒),适合直播推流,但需Flash支持(已淘汰) - HLS:延迟高(10-30秒),基于HTTP分片,兼容性好,适合点播 - DASH:类似HLS,支持ABR(自适应码率),Netflix主推 - WebRTC:超低延迟(<500ms),适合连麦等实时场景

低延迟直播优化: - 减小切片时长(HLS从10s降到2s) - 使用CMAF格式提升兼容性 - CDN边缘节点就近加速


五、面经规律总结

面试风格画像

B站面试有一个明显特点:技术深度 + 业务场景结合。面试官不会单纯考"手写快排",而是会把算法题和业务场景接起来——"你实现了LRU,那B站弹幕池怎么设计?"这种追问方式在B站很典型。

面试氛围相对轻松,面试官普遍年轻(很多是应届生带届生),喜欢技术讨论而不是考试式审问。但不要误判——轻松的氛围不等于低要求,追问会追到底层原理。

高概率追问链

智能指针追问链(C++方向几乎必问):

shared_ptr是什么?
→ 追问:引用计数是如何实现线程安全的?(原子操作)
→ 追问:循环引用具体怎么发生?(A→B→A,引用计数永远≥1)
→ 追问:weak_ptr为什么不增加引用计数?(只记录弱引用计数,不阻止对象析构)
→ 追问:能手写一个简化版shared_ptr吗?(控制块+引用计数+析构逻辑)

Go逃逸追问链(Go方向高频):

什么是逃逸分析?
→ 追问:举3个会逃逸的典型场景?
→ 追问:怎么查看代码里哪些变量逃逸了?(go build -gcflags="-m")
→ 追问:逃逸对性能有什么影响?如何优化?(sync.Pool,减少堆分配)
→ 追问:你项目里有没有因为逃逸问题导致的性能问题?怎么排查的?

弹幕系统追问链(每家公司都会问的设计题,B站会追得更深):

弹幕系统怎么设计?
→ 追问:百万并发弹幕怎么处理?(分片+WebSocket集群+Kafka消峰)
→ 追问:弹幕的实时性和一致性如何平衡?(最终一致性,优先实时性)
→ 追问:用户快进时怎么加载弹幕?(按PTS时间轴拉取缓存)
→ 追问:弹幕存储怎么设计分层?(Redis热数据 + Cassandra冷数据)

LRU + 业务追问链:

手写LRU
→ 追问:B站弹幕池怎么用LRU设计?(LRU淘汰冷弹幕,保留热弹幕段)
→ 追问:如果弹幕量超大,单个LRU扛不住怎么办?(分片LRU,按视频ID分片)
→ 追问:LRU的时间复杂度是多少?能优化吗?(O(1),哈希表+双向链表)

笔试特点

  • 题型:编程题3-4道 + 选择题(Go/C++基础知识,音视频岗有音视频相关选择题)
  • 难度:编程题Medium为主,Hard偶尔出现
  • 时间:90-
  • 特点:Go语言基础选择题可能考channel、goroutine、接口等,C++方向可能考指针、虚函数等
  • 策略:先把编程题全做完,选择题利用剩余时间完成,不确定的题目猜默认最直观的答案

不同岗位的差异

岗位 算法题权重 系统设计权重 语言专项权重 备注
后端(Go) ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐(Go专项) 弹幕设计必考
音视频(C++) ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐(C++专项+音视频) 编解码必考
算法工程师 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐(Python为主) 推荐系统必考
客户端(Android/iOS) ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐(Kotlin/Swift) 视频播放器优化考察
前端 ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐(JS/TS+Vue) WebAssembly了解加分

校招节奏

整体策略

B站备考有一个核心原则:Go/C++语言专项和弹幕系统设计要早投入,不能靠临时抱佛脚。这两个方向的考察深度决定了你必须有深度理解,而不是表面背诵。

如果只有,优先级排序是:语言专项(Go或C++)> 弹幕系统设计 > 算法题(链表+LRU) > 数据库 > 其他。

详细计划

阶段 时间 重点任务 每日用时
Phase 1:C++智能指针 unique_ptr/shared_ptr/weak_ptr原理;手写简化版shared_ptr(含引用计数);循环引用问题画图演示 2-
Phase 2:Go语言专项 GMP调度模型;Channel各种情况;逃逸分析3种场景+查看工具;GC机制;sync.Pool使用 2-
Phase 3:数据库+Redis ZSet排行榜设计;HyperLogLog UV统计原理和适用场景;MySQL分库分表策略;Kafka基础
Phase 4:弹幕系统设计 实时推送(WebSocket+Kafka);存储分层(Redis+Cassandra);过滤方案;快进时弹幕同步;百万并发处理
Phase 5:算法专项 LRU手写(Go+C++两个版本);链表全系列(反转/合并/环/K组翻转);滑动窗口;堆应用
Phase 6:冲刺 音视频基础补充(针对音视频岗);看最新B站面经;整理项目中弹幕/视频相关点;模拟面试

最低备考标准(上场前必须达到)

  • [ ] 智能指针循环引用问题能画图演示(A→B→A的引用计数问题,以及weak_ptr如何打破)
  • [ ] Go逃逸分析能举出3种典型逃逸场景,知道如何用命令查看
  • [ ] 弹幕实时推送完整方案能讲清楚(WebSocket + Kafka + Redis热存储 + 冷存储三层架构)
  • [ ] LRU缓存能在内手写(Go或C++均可,HashMap + 双向链表)
  • [ ] HyperLogLog用于视频UV统计的理由能解释(误差率约0.81%可接受,内存从几百MB降到12KB)
  • [ ] 至少熟练掌握第一梯队5道题,能在内写出clean code

各岗位备考调整

投后端(Go方向):Phase 2 Go语言专项延长到(),弹幕系统设计是重中之重,不可压缩。

投音视频(C++方向):Phase 1 C++专项延长到(),Phase 6 冲刺时重点补充H.264/H.265/FFmpeg知识,能说清楚转码流程。

投算法工程师:Phase 5 算法专项延长到(),增加推荐系统基础:召回+排序的基本架构,CTR预估的常见模型。

一句话建议

B站面试最大的坑是只刷题不准备弹幕系统设计,然后被追问得哑口无言。弹幕设计不是加分题,是必答题。里,至少花时间把弹幕系统的完整方案推演3遍,每遍都从"用户点击发送"到"其他用户看到弹幕"全链路走一遍,直到能流畅讲出来为止。