09 · 风险点、诚实话术与简历修正(面试前必读)
这篇文档的目的只有一个:让你在字节面试官面前不出现"说了但讲不出、讲了但是假的"的情况。
字节的面试风格是"顺着简历往死里挖",一条你无法展开的描述,就是一个必被击穿的洞。下面第 1 节是必须处理的红牌,第 2 节给出可直接替换的简历文案,第 3 节是"AI 写的吧"的应对,第 4 节是你不能吹的清单,第 5 节是建议真的去补的作业(补完就能多讲 6 个亮点)。
一、🚨 红牌:简历上的"实时直播"在你的仓库里不存在
事实核对
| 你简历写的 | 代码事实 |
|---|---|
| "支持实时直播(Live Streaming)与视频点播(VOD)" | VOD 完整实现;仓库里没有任何直播相关代码——没有 SFU 集成、没有推流密钥校验、没有 RTMP/WHIP 接口、没有拉流播放页 |
| README 里的 live777(Rust SFU) | 只出现在 README.md 的架构图和技术栈表格里,docs/specs/distributed-architecture.md 里你自己写着"仅 README,代码未集成" |
为什么这是最高风险
面试官最可能的第一句追问是:"直播这块你是怎么做的?推流走什么协议?"
- 如果你答"用 live777 做 SFU,OBS 推流" → 下一句追问"live777 和你的服务怎么集成的?鉴权怎么做的?多房间怎么管理?" → 崩。
- 如果你答"直播是我另开的一个服务" → 追问"代码在哪?" → 更崩。字节面试官会看你的 GitHub(你简历里给了链接)。
一旦出现"简历写了但做不出来",整份简历的可信度都会被打折,包括那些你真做得很扎实的部分(很亏)。
三种处理方案(选一个,不要拖)
| 方案 | 做法 | 适用 |
|---|---|---|
| A(推荐) | 删掉"直播"字样,只写点播,把篇幅让给真正有深度的转码/分布式 | 面试就在 1–2 周内 |
| B | 保留但在简历里明确写"点播已落地;直播为 next:计划接入 live777 SFU" | 面试还有 3 周以上,且你真打算做 |
| C | 真的补一个最小直播闭环(见第 5 节作业 9) | 时间充裕、想拿"直播+点播一体化"这个叙事 |
二、可直接替换的简历文案
版式一:纯 VOD(方案 A,推荐)
Vistack 视频点播与分布式转码平台(负责人 / 个人项目) 2025.06 – 2025.10 基于云原生架构的流媒体后端,单二进制按角色拆分为 API / Worker / Transcoder / Auth 四个独立进程。技术栈:Gin + GORM + PostgreSQL + Redis + gRPC + Kafka + etcd + FFmpeg + MinIO + Traefik。 源码:https://github.com/Bin-hy/Vistack
- 多角色微服务拆分:
VISTACK_ROLE单二进制分角色启动,API(HTTP 接入/预签名)、Worker(Kafka 编排/幂等/重试)、Transcoder(gRPC + FFmpeg,仅依赖 MinIO 与 etcd,不持数据库凭证)、Auth(RS256 签发 + JWKS)独立部署、独立扩容。- 分片直传与秒传:MinIO Multipart + 预签名 URL 前端直传(8MB/片、6 并发、浏览器零中转),MD5 整文件哈希实现秒传、
ListObjectParts对比实现断点续传,文件表引用计数 + 双段事务实现安全回收。- DASH 自适应码率:FFmpeg 按源分辨率自动选择 240p–4K 档位(CRF + maxrate 双约束、GOP 与 4 秒切片对齐),产出
manifest.mpd+init/chunk-*.m4s,前端 dash.js ABR 无缝切换。- gRPC 远程转码 + etcd 服务发现:FFmpeg 隔离在独立容器,
ProcessVideo输入输出全走对象存储,无状态可水平扩容;etcd 租约注册 + 自定义 gRPC resolver +round_robin动态发现多副本。- 异步任务可靠性:Kafka 解耦上传与转码,DB 状态机 + Redis 租约 + 事务写入三重幂等;Redis ZSet 延迟队列指数退避重试(上限 8h/7 次)+ 看门狗超时兜底;重试派发器与看门狗用 etcd 领导选举保证全局单例。
- 播放防盗链:manifest 由 API 代理,分片通过 STS 临时凭证(限定
dash/{id}/*只读、30 分钟)+ 前端 SigV4 签名直连 MinIO,带宽与鉴权从 API 卸载。- 高并发实践:Cache-Aside 缓存组件(空值 + 布隆防穿透、singleflight + Redis 锁防击穿、随机 TTL 防雪崩)、Redis Lua 滑动窗口分布式限流(429 +
Retry-After,fail-open)、点赞/收藏/播放量 Lua 原子计数 + 事件队列异步批量落库(幂等)+ ZSet 热门榜单。
版式二:保留直播(方案 B,加一句计划)
在版式一末尾加:
- 演进中:直播模块(基于 live777 Rust SFU 的 WebRTC 分发)处于设计/接入阶段,已完成部署编排与推拉流链路验证,服务端业务集成进行中。
⚠️ 这句话只有在你能回答"live777 的部署、推流地址、SFU 与业务鉴权如何对接"时才能写。
关键修改点说明
| 原简历 | 改后 | 改动理由 |
|---|---|---|
| "三角色微服务架构" | "四角色" | 你实际有 auth 服务,写成四个角色更真实且更亮 |
| "支持直播与点播" | 删 / 或标注演进中 | 见第 1 节 |
| "远程转码隔离…无状态设计支持并发转码水平扩容" | 补上 etcd 注册 + resolver + round_robin 细节 | 这才是技术含量所在 |
| "防盗链:预签名 URL + STS 临时凭证 + JWT" | 说清各用在哪:预签名=上传分片,STS=播放分片,JWT=接口鉴权 | 原写法容易被追问"这三个是并列的吗",答不上就尴尬 |
| (无) | 新增第 5、7 条 | 幂等/重试/领导选举/缓存/限流/计数 是你项目里含金量最高的部分,不写白不写 |
三、被问"这项目是不是 AI 写的 / 你负责到什么程度"
这是 vibecoding 项目必答的一题。不要否认用了 AI,也不要承认自己"只会复制粘贴"。正确的答法是"用 AI 提效 + 我来做设计决策和排障",并且当场用细节证明决策是你做的。
🎤 口述模板:
"这个项目我大量用了 AI 辅助写代码,这点我不回避——它帮我把 CRUD、前端页面、样板代码写得很快。但有三件事是我自己决定的,也是我在这上面花时间最多的地方:
第一是架构取舍。比如要不要把 FFmpeg 拆出去、拆出去之后任务状态机归谁管、transcoder 要不要连数据库——我最后定的是 transcoder 只依赖对象存储、不碰数据库,任务状态只有 worker 一个写入者。
第二是排障。我记得最清楚的有两个:一个是播放时
SignatureDoesNotMatch,最后定位到前端 SigV4 的 CanonicalQuery 没有按 key 排序 + 没处理 SessionToken 的x-amz-security-token;另一个是多副本 worker 起来之后同一批重试任务被投递了两次,我加了 etcd 领导选举才解决。第三是评审自己的代码。我专门写了一份
distributed-architecture.md给自己做架构 review,里面列了 P0 级的正确性缺口,比如 dispatcher 没有选主、worker 没有优雅停机、Kafka 并发是 1,然后按优先级一条条改掉了。所以我的状态是:每一行代码我都读过,架构决策我能解释为什么,性能与故障我能讲清边界。"
🔍 为什么这套话术有效
- "诚实承认 + 三个具体且只有真作者才知道的细节" = 可信。
- 第二点的两个 bug(SigV4 签名、重复投递)是你的杀手牌:AI 不会遇到这两个问题,只有真正在跑系统的人会遇到。
- 第三点引用你仓库里真实存在的
docs/specs/*与distributed-architecture.md——面试官如果打开你的 GitHub,会看到这些文档,形成闭环。
🚨 绝对不要说的三句话
- "这个项目基本都是 AI 写的,我主要负责需求。" → 直接结束。
- "我都懂,你随便问。" → 一旦卡壳,反噬加倍。
- "这个我没参与,是队友做的。" → 你是"负责人",说了就是失职。如果某模块真是别人写的,就提前想清楚你承担了哪一部分(比如"直播模块是与另一位同学协作,我负责 XX"),并且在简历上写清楚分工。
四、🚫 不能吹的清单(附代码事实,防止你临场编错)
| 不要说 | 事实 | 被问到时怎么说 |
|---|---|---|
| "我们做了直播" | 无代码 | 见第 1、3 节 |
| "有 Prometheus 监控/链路追踪" | 只有 zap 日志,仓库里没有 metrics/trace 代码 | "目前只有 zap 结构化日志,指标和 tracing 是我的下一步" |
| "健康检查分了 readiness/liveness 接 K8s 探针" | /health 会 ping DB/MinIO/Redis 但恒返回 200,不区分两种探针 | "health 会探测三个依赖并返回明细,但没有拆 readiness/liveness,探针还没接" |
| "RBAC 细粒度权限" | 表结构齐全(roles/authorities/role_authority/user_authority),但业务代码只用了角色(注册时赋 user 角色),细粒度鉴权中间件没落地 | "RBAC 的表和模型建好了,落地的是角色级,权限点级鉴权还没接中间件" |
| "支持 HLS" | 只产出 DASH | "只做 DASH,HLS 在 spec 里明确列为不做" |
| "有死信队列" | 重试 7 次后静默丢弃 | "没有 DLQ,这是我要补的 P0" |
| "消息投递和 DB 是原子的事务(Outbox)" | 是"先提交事务再发 Kafka,发送失败标 failed + 进重试队列" | "不是 Outbox,靠失败兜底,严格场景应该上 outbox 表" |
| "gRPC 有 mTLS/鉴权" | 明文 + insecure.NewCredentials() | "内网明文,mTLS 在 roadmap 上" |
| "etcd/Kafka/Redis/PG 都是高可用集群" | compose 里全是单节点;EnsureTopic 建的是 1 分区 1 副本 | "本地部署是单节点,生产化要 3 节点 etcd + 3 broker Kafka + 分区提到 8–16" |
| "有压测数据,QPS 多少" | 仓库里没有压测脚本与数据 | 要么现在去压一次拿真数字(强烈建议),要么别说 QPS |
| "转码 4K 只要 X 分钟" | 没有实测数据 | 别说具体耗时,除非你真的测过 |
| "有单测覆盖" | 只有少量单测(cache/ratelimit/danmaku/interaction/web 各一个测试文件) | "核心组件有单测(缓存、限流、弹幕、计数),整体覆盖率不高" |
| "自研分布式锁/自研一致性协议" | 用的是 etcd 官方 concurrency 包 + Redis SETNX + Lua | "基于 etcd 的 session/election 和 Redis 的 SETNX+Lua 实现,没有自研协议" |
原则:**凡是"有/做了"要能指向文件;凡是"没做"要能说出下一步怎么做。**前者证明真实性,后者证明判断力。
五、建议真的去补的作业(按性价比排序,共约 10 小时)
补完这些,你的可讲亮点会增加 6 个以上,而且都是面试官爱问的方向。
| # | 作业 | 工时 | 补完可讲的话术 |
|---|---|---|---|
| 1 | 给 transcode topic 提到 8 分区(改 EnsureTopic 参数或手工 kafka-topics --alter),worker 起 2–3 副本,观察并发转码数变化 | 1 h | "我最开始的瓶颈是 1 分区,4 个 reader 也只有 1 个在消费;提到 8 分区 + 3 副本后并发转码从 1 提到 6,这是我用 kafka-consumer-groups --describe 验证的" |
| 2 | 用 exec.CommandContext + Setpgid 真正杀掉 ffmpeg 进程组 | 1 h | "之前 gRPC 超时只是 worker 侧返回错误,transcoder 里的 ffmpeg 还在跑;改成 context 取消 + 进程组 kill 后,超时能真正回收资源" |
| 3 | 给 /health 拆成 /livez 与 /readyz,K8s 清单里接上探针 | 1 h | "liveness 只看进程,readiness 检查 DB/Redis/MinIO,K8s 就不会因为依赖抖动把健康的 Pod 杀掉" |
| 4 | 加 Prometheus 指标:HTTP 请求数/延迟直方图 + 转码耗时与成功率 + Kafka lag | 2 h | "我加了 /metrics,能看 p95 延迟、转码成功率和消费积压,出问题先看大盘再看日志" |
| 5 | 加 DLQ:重试超 7 次投到 transcode.dlq + 打错误日志 | 1 h | "重试超限不再静默丢弃,而是进死信 topic 供人工重放" |
| 6 | 播放接口补可见性校验:manifest.mpd 与 segments/signature 校验 visibility 与作者身份 | 1 h | "之前只要知道视频 ID 就能看任何视频的切片,属于越权;我补上了可见性校验" |
| 7 | 前端上传失败限次重试(部分分片失败 3 次即中止并提示续传) | 0.5 h | "之前失败会无限重试,我改成有限次 + 提示用户续传" |
| 8 | 压测一次并记录数字:用 hey/wrk 打 /videos/:id/info(缓存命中 vs 关缓存)与上传签名接口 | 2 h | "缓存命中时 p99 是 X ms,关掉缓存是 Y ms,QPS 差 Z 倍" ← 这是最有价值的一句话 |
| 9 | (可选)直播最小闭环:docker 起 live777,OBS 推流,前端加一个 WebRTC 播放页,接进 Traefik | 4 h+ | 可以开始讲直播,但要准备好 SFU/WebRTC 原理问答 |
⚠️ 只做 1、2、6、8 四项(约 5 小时),就已经能把"我知道自己系统的问题并且修了"这个故事讲得非常完整。
六、通用救场话术(临场忘词/被问懵时用)
| 场景 | 话术 |
|---|---|
| 细节记不清 | "这块的数值我要回去看下代码确认,但设计思路是……(讲思路)" |
| 被问到没做的功能 | "这个我没做,但我可以说下如果我来做会怎么设计:……(给方案)" |
| 被问到一个陌生的中间件 | "我没在生产用过它,但我知道它大致解决的是 X 问题,和我在项目里用 Y 的思路类似……" |
| 面试官质疑实现有问题 | "你说得对,这里确实有这个问题(承认),我当时的选择是 A,代价就是你说的 B;如果重做我会用 C。" ← 不要硬辩,认下来并给更好的方案,反而加分 |
| 一段链路讲到一半被带偏 | "我先把这条链路讲完,再回到你刚问的那点,可以吗?" |
| 完全不会 | "这个我不了解,面试结束后我去补。" ← 比编造强一百倍 |
自测清单
- [ ] 已经决定第 1 节的方案 A/B/C,并且简历已经改完
- [ ] 能背出第 3 节的三点式回答(架构取舍 / 排障 / 自我评审)
- [ ] 第 4 节表格逐行读过,确认自己不会说错任何一条
- [ ] 至少完成作业 1、2、6、8(或明确决定不做,且不在面试里提相关能力)
- [ ] 能说出 3 个"只有真做过才知道"的排障细节(SigV4 签名、重复投递、1 分区瓶颈)
- [ ] 准备好一句"这个没做,我会这么做"的模板句
背诵卡
- 直播没代码 → 简历必须去掉,否则整份简历可信度打折。
- 四角色不是三角色(含 auth),主动说出来。
- 预签名管上传、STS 管播放、JWT 管接口,三者别混为一谈。
- AI 辅助写代码可以承认,但要给三个只有真作者知道的排障细节。
- 不能吹:直播、监控、DLQ、Outbox、mTLS、压测 QPS、细粒度 RBAC、HLS、高可用集群。
- 能吹且该吹:四角色拆分、直传秒传续传、DASH 参数、gRPC+etcd、幂等+重试+选主、缓存/限流/计数。
- 认错模板:你说得对 + 我当时的取舍是 + 代价是 + 重做会用。
- 最有价值的一句话是压测对比数字,去测一次。