10 压力面 · 简历修正 · 保命话术
这篇是"防守篇"。前几篇教你怎么把项目讲好,这一篇教你在被打的时候不崩。 分成四块:① 简历已投出去怎么补救 → ② 十类压力问题与标准答法 → ③ 答不上来时的三条保命话术 → ④ 反问与收尾。
一、简历已经投出去了,MySQL 怎么办?(最高优先级)
【现实判断】
简历上写的"Express5 + Mysql"是硬错误——代码是 PostgreSQL 17。这不是"表述不严谨",是事实错误。但它不是诚信问题,因为:
- 项目早期(2026-04-23 至 05-13)确实短暂用过 MySQL(
mysql2依赖 +USE_DB_AUTH开关,只覆盖账号侧存储); - 5 月 13 日有一个提交整体切换到
pg,因为需要部分唯一索引、JSONB 深扫、plpgsql 触发器这些 PG 能力; - 但
README.md和ARCH.md从切换前就没更新过,仓库里还留着 MySQL 的建表化石(backend/sql/init_users.sql里的AUTO_INCREMENT)。简历大概率是从 README 抄的。
【三条应对路线,按场景选】
路线 A:面试前能改简历(最优) 直接按 03-简历四条主线拆解.md 末尾的修改版替换。不用解释,改了就完事。
路线 B:简历已投、面试中被问到(推荐说法)
【口述】 我主动更正一处:简历上写的是 MySQL,实际现在用的是 PostgreSQL 17。 项目最早(四月底)确实跑在 MySQL 上,但五月中旬我们做了一次整体切换——原因是这个系统需要三样 MySQL 给不了的能力:部分唯一索引(用来实现"同一任务最多一条活跃积分冻结")、JSONB 深扫(用来判断一个文件是否还被十几张业务表引用)、以及 plpgsql 触发器(把文件生命周期约束下沉到数据库)。切换是在一个提交里完成的,同时补上了数据库迁移体系。 简历没改是因为我写的时候参考了项目 README,而那份 README 停留在切换之前——这是我的疏漏,不是我们有双重数据库。代码里现在只有
pg一个驱动,没有mysql2。
【备注讲解】 这个说法的四个要点:① 主动更正(不遮)② 给出真实的历史原因(不是编的)③ 给出切换的技术理由(显专业)④ 主动说明错误来源(README 过期)并给出可验证的事实(只有 pg 驱动)。 绝对不要说"MySQL 和 PostgreSQL 差不多所以写错了"——那会让人觉得你不懂两者的差异。反过来说清"为什么要 PG",这题就从减分变成了加分。
路线 C:面试官压根没问不要主动提。 但如果聊到数据库设计,一定要用 PostgreSQL 的术语(部分唯一索引、FOR UPDATE、ON CONFLICT、advisory lock、JSONB),自然地把事实覆盖掉。
二、其他三处需要修正的表述(一句话版)
| 简历原话 | 一句话修正 | 展开在哪里 |
|---|---|---|
| "引用计数保护" | "准确说是引用存在性判定——代码里的 refCount 只用于参考图数量;文件保护用的是跨 12+ 张表的 oss_key_in_use() + 触发器 + 唯一约束 + 30 天延迟删除" | 06 Q21 / 09 故事 5 |
| "Docker Compose 一键部署" | "应用没有容器化:PG 和 Redis 用 compose 起,应用是 pm2 跑 tsx + nginx 反代 + 自研发布脚本" | 08 / 03 ④ |
| "6+ 供应商" | "历史接入过 6 家,当前新任务只走腾讯云 VOD,老实现保留是为了在途任务能轮询" | 05 Q1 |
统一原则:主动更正 + 给原因 + 给可验证的事实。三句话以内说完,不要反复道歉。
三、十类压力问题与标准答法
压力类型 1:质疑项目是不是 AI 写的
【面试官可能在试探什么】 你到底有没有自己的判断力。
【口述】 是 AI 深度参与的,我们团队重度使用 AI 编程,很多实现是模型先起草我再改。 但有两件事是我自己把住的: 第一是设计决策。比如"轮询必须加 2 小时硬超时"、"冻结记录要用部分唯一索引"、"恢复逻辑在启动时必须强制覆盖 active job、周期巡检时必须跳过"——这些判断模型给不出来,因为它是从踩坑里长出来的。仓库里那些写了很长注释解释"为什么这么改"的地方,基本都是事故之后我补的。 第二是验证责任。关键的、改错就直接造成资损或误封的逻辑,我都抽成纯函数单独测——比如身份判定
decideIdentity、轮询超时isPollTimedOut、限流的窗口判定、支付轮询的decidePollAction(它的注释直接写着"改错会直接造成资损")。后端现在有 349 个测试文件。 我不会说"每一行都是我手写的",但这个系统的可靠性设计是我的。
【追问 1】"那你具体讲一个 AI 写错了、你改对的例子。"
支付轮询的判定逻辑。原来"本地订单过期就关单"是写在一起的,我把它抽成纯函数
decidePollAction的时候发现一个资损风险:本地过期不等于上游未支付——服务宕机期间用户完全可能已经付款、只是回调没进来。所以我把规则改成"上游确认未付、且本地也过期"才算关单,而且用严格大于:恰好到期的瞬间再等一轮——宁可多等,也不误关已付款的单。这种"往代价小的那一侧偏"的判断,AI 起草的版本里是没有的。
【追问 2】"你怎么保证 AI 写的代码质量?"
三条:① 关键路径抽纯函数 + 单测;② 大改动先在测试环境跑 + 冒烟脚本(我们有一批
smoke-*和verify-*脚本);③ 对"静默失败"零容忍——我会专门检查那些catch {}空吞的地方,因为异步系统里静默失败比抛错危险得多。
压力类型 2:追问量化指标("QPS 多少""P99 多久""多少用户")
【为什么这是压力题】 他想看你会不会编数字。
【口述】 我没有可信的线上指标,所以我不编数字——我们连 metrics 体系都没有,没有 Prometheus、没有链路追踪,告警靠日志关键词和定时巡检。我能给的只有代码和日志里能验证的量级。 但我可以讲清怎么设计评估:如果要做容量评估,我会先埋三个指标——① 队列深度与等待时长(BullMQ 的 job 数 + 从入队到被处理的延迟),② 端到端 P50/P99(从下单到成片的墙钟时间,并且按生成方式分桶,因为 15 秒单段和 30 秒分段完全是两个量级),③ 上游调用成功率与失败归因分布。 已经有一个可用于容量判断的事实:
PixelCountTooSmall在生产日志里出现 1348 次,是第二名的 70 倍——说明我们最大的损耗不是模型能力,是素材预处理。
【备注讲解】 这个答法的价值在于:承认没有 → 立刻给出"我会怎么建" → 再补一个真实可验证的量级事实。最后那句 1348 次非常关键,它证明你看过真实日志,不是空口说"我们会建指标"。
压力类型 3:质疑设计("为什么不用 Kafka?""为什么不用 xfade?""为什么不用 STS?")
【通用三段式】
① 承认这个选择不是唯一的 → ② 给出当初的具体约束(量级、语义、成本、时间) → ③ 说清什么时候该换
例:为什么不用 Kafka / RabbitMQ?
三个理由:量级上我们的任务是"每天几千到几万条长耗时任务",不是百万级日志流,用 Kafka 是拿最重的基础设施解决最轻的问题;语义上我们要的是延迟任务(2 秒后、30 秒后再轮询一次)和固定 jobId 去重,这两件事在 BullMQ 里是一等公民,在 Kafka 里要靠时间轮自建、在 RabbitMQ 里要靠 TTL + 死信队列拼;运维上我们本来就用 Redis 做缓存、限流、分布式锁,不引入第二个中间件。 什么时候该换:如果任务的吞吐涨到 Redis 单实例扛不住、或者需要多消费者组各自独立消费(比如同一批任务既要给生成用、也要给数据分析用),那时候 Kafka 的模型才对。
例:拼接为什么不用 xfade 转场?
我们的设计是硬切。因为段间连贯性已经靠"上一段尾帧当下一段首帧"锚定了画面,加了转场反而会把衔接糊掉——而且转场要额外编码,成本和风险都不划算。当然如果将来要做"刻意区分章节"的长视频,转场是有意义的。
例:上传直传为什么不用 STS 临时凭证?
这是个真问题,我们没有做。 现在是把 POST policy 签名 + 永久 AK 的 ID 发给浏览器,配上一个 public-read 的桶。正确的做法是 STS 临时凭证 + 私有桶 + 最小权限,这样凭证会过期、权限可收窄。没做的原因是没有专用的 RAM 角色和 STS 接入工作,属于已知的安全欠账。
【备注讲解】 第三例的答法最重要:对真欠账,直接承认 + 说清正确做法,不要试图辩护。
压力类型 4:"这个功能是你做的吗?"(挖作者归属)
【为什么是压力题】 他在验证你有没有把团队成果说成自己的。
【口述】 我先把边界说清楚,免得后面越讲越虚。这个仓库是团队协作的,2500 多个提交、8 位以上作者。 我主导的是:任务崩溃恢复与巡检、视频任务提交 Worker 和轮询队列、积分冻结/结算/退款的核心实现(
credit_holds表那条迁移是我写的)、微信支付客户端和微信扫码登录、限流与身份解析、OSS 生命周期、以及前端从巨型 App.tsx 拆成 page + hook 架构。 我参与但主作者是同事的:脚本库一键生成的分段生产 Worker、模型目录与定价清单、视频编辑器的编排。 这几块我能讲清设计和我从恢复侧看到的问题,但我会明确说"这部分不是我写的"。
【备注讲解】 这段说出来会显著提升可信度。面试官最怕的是"讲得很流畅、一问细节就露馅",而主动划界的人反而让他在你负责的部分上更愿意相信你。具体的归属清单在 01-项目口述介绍-多版本.md 第一节。
压力类型 5:"如果线上出故障你怎么排查?"(考察真实经验)
【推荐用 09 里的故事 1 或 2 正面回答】,然后在收尾处主动交底:
排查路径我一般是三步:① 先看现象是"一个任务坏了"还是"一类任务坏了"(前者查单条任务的
task_events审计表,后者查巡检日志和失败归因分布);② 看权威状态在哪一层断的(是供应商没返回、还是我们没收到、还是收到了但没写库);③ 看有没有并发对手(同一条链路的两个执行者互相覆盖,是我们出过最多的一类问题)。 但我必须说:我们目前的可观测性是很弱的——日志是console.log加[ALERT]前缀约定,没有 request id、没有结构化日志、没有 APM,pm2 日志积累了 1.8G 没有轮转,客服排查靠 grep。如果重来一次,我会第一件把日志结构化 + 加 request id + 接入错误聚合。
压力类型 6:"这个方法为什么这么写?"(挑一行代码问意图)
【应对模板】
先答"它防的是什么"(几乎每个非平凡写法背后都有一次事故)→ 再说"不这么写会怎样" → 最后说"代价是什么"。
例:为什么 taskRecovery 里那么长一串 if (generateMode === ...) continue;?
它防的是误杀内存自管的任务。这些任务在
video_tasks里只有一行占位行,长得跟正常任务一样,但状态在进程内存或者另一套队列里。落到通用分支会有四种后果:被标失败并清零积分、拿内部占位 taskId 去查供应商报错、用不在注册表里的 provider 抛异常被吞掉导致永久悬挂、以及最贵的——拿空 prompt 去调模型烧钱出一条废片。 代价是:这串分支靠注释维持清单,新增一种生成方式很容易漏一处,这是技术债。正确做法是给这类任务一个显式的类型字段。
压力类型 7:"你觉得这个项目最大的问题是什么?"
【别答技术细节,答层次】
架构上最大的问题是"权威状态分散"。 一部分任务状态在数据库里,一部分在进程内存里(长视频、批量复刻),一部分在 Redis 里(分段的段状态),还有一部分的收尾判断原先依赖用户浏览器是否还开着页面。我们这两年的大部分事故——68 小时悬挂、积分永久冻结、误重排烧钱——都是这个分散的直接结果。 我们的应对是把"判断权"往服务端收:加巡检、加对账、把前端轮询从"收尾触发者"降级为"展示者"。但根上的解法是状态外置:让所有长任务的状态都落在一张表里、用统一的执行模型,这样恢复逻辑就不用靠九条 if 分支去猜。 工程上最大的问题是"没有强制执行通道":我们有 349 个测试文件,听起来不少,但 CI 只有一个后端单测 job、而且因为账户欠费八月初起其实没在跑,
pre-pushhook 也因为core.hooksPath没设置实际没安装。测试资产不缺,缺的是卡口。
【备注讲解】 这个答法的高明处:分"架构"和"工程"两层说,每层都给一个统一根因(权威状态分散 / 缺强制通道),而不是罗列零散缺点。有统一根因的判断,才是架构师级别的判断。
压力类型 8:"如果现在给你两周,你做什么?"
【考察优先级判断】
三件事,按顺序: 第一,数据库备份 + PITR。 现在没有任何自动备份,而这张库是积分和支付的账本——单卷丢失等于账本不可恢复。这不是优化,这是唯一一个"出事就无法挽回"的风险点。 第二,把 CI 修起来。 现在 CI 因为账户欠费停摆、hook 也没装,等于所有质量纪律都是口头的。 第三,消灭"已扣款未建任务"那个追不回的窗口。 现在
/generate链路是"先扣减 + 事后补冻结日志",两件事不在一个事务里;进程在最坏的时刻被杀,这笔钱只能靠对账发现。把主流链路迁移到真冻结的事务语义,这是补一个敞着的资金口子。 剩下的(metrics、支付退款、上游对账、动态路由恢复)都是明确的、但不紧急的。
【备注讲解】 排序逻辑要能自洽:"不可挽回的" > "让纪律可执行的" > "敞着的口子" > "明确但不紧急的"。这个优先级框架本身比具体答案更值钱。
压力类型 9:"你怎么验证你改对了?"
三层: ① 纯函数单测。凡是"改错就直接造成资损或误封"的逻辑,我都抽成纯函数——身份判定、轮询超时、限流窗口、支付轮询判定,都有测试。 ② 数据断言。资金和文件这类有不变式的系统,我写了 SQL 层面的断言测试,比如双账本"赠送 + 充值 = 总额"、全站收尾函数必须显式钉死超分模板(有一条冻结断言守着,漏钉会静默回落到全局默认)。 ③ 冒烟脚本 + 生产巡检。改动上生产后,靠巡检和对账观察——这类系统的验证终点不是测试通过,是账对得上。
压力类型 10:"讲一个你失败/判断错的例子"
【必须真答,不能绕】 用 09 里的故事 4:
有一个"2.6 秒的演示视频被当成待编辑原片"的问题,我们犯了四次。前三次我都是打补丁——在出问题的那个分支加一个判断。每次修完都"好了",然后换一个场景又炸。 第四次(用户按 30 秒收费、拿到 2.6 秒的片子)我才意识到:根因不是某个判断错了,而是"素材角色判定"这件事散落在多个分支里——每修一处,别处还会漏。所以第四次我把它收敛成一张角色白名单,判定只在一处。 我从中得到的教训是:当一个 bug 以"同类不同款"的形态反复出现时,不要修那一处,要去找"这个判断散落在几个地方"。现在我判断技术债的第一条标准就是这个——同一个业务判断出现在两个以上的地方,就是债。
四、答不上来时的三条保命话术
这三条要背到脱口而出。
- 真不会的细节
"这一层我没做到源码级。我知道的边界是 X,回去我会先看 Y。" —— 绝不硬编。 面试官顺着往下问一层你就崩了,而且"编"这件事本身比"不会"严重得多。
- 效果/数字类
"我没有可信的基线,所以不编数字——但我可以说清怎么设计评估、瓶颈在哪。" —— 然后立刻转到你能讲的东西(比如"1348 次是第二名的 70 倍"这类真实日志量级)。
- 质疑 AI 生成类
"是 AI 辅助。我把住的是设计决策和验证责任——比如轮询超时、部分唯一索引、恢复逻辑的启动/周期差异,这些是从踩坑里长出来的判断。" —— 见本节压力类型 1。
【附加:被问到一个完全没准备的技术点时】
"这块我没做过,但我可以从第一性原理推一下:如果是我做,我会先确认 X,然后考虑 Y 的取舍……" —— 推演能力本身也是被考察的。字节面试官经常故意问超纲题,看的是思维过程而不是答案。
五、反问清单(按含金量排序)
第一梯队(结合他们的业务,显示你懂这条链路)
- "你们的 AI 视频链路里,单条成片的 P99 延迟大概是什么量级?瓶颈主要在模型侧,还是在后处理/拼接这一侧?"
- "长耗时的异步生成任务,你们是自研任务编排还是用现有队列?失败任务的额度/积分回滚,是怎么保证不重不漏的?"
- "团队做 AI 视频,是更偏模型能力接入,还是更偏工程编排与交付质量?"
第二梯队(了解岗位与团队) 4. "如果我进来,前三个月你们最希望我补上的是哪一块?" 5. "团队现在在可靠性和可观测性上投入多少?有没有专门的稳定性负责人?" 6. "这个方向接下来半年最重要的一个技术判断是什么?"
不要问:加班强度、能不能用 AI 写代码、薪资福利(留给 HR 面)、"你们用什么技术栈"(JD 上写着)。
六、开场 30 秒与收尾 30 秒(背下来)
开场(自我介绍里嵌项目)
我是 XX,做后端为主。最近一年主要在做鲨堂 AI这个电商视频生成平台——它本质上是个调度器:自己不生产视频,而是把几十种生成方式编排到多个外部 AI 供应商上,所以我的工作核心是三件事:任务别丢、状态别乱、钱别错。 我特别想聊的是异步任务的一致性——这块我踩的坑最多,也想听听你们是怎么做的。
收尾(把话题交回去,留好印象)
这个项目我复盘下来,做得比较实的是异步任务的一致性和资金对账,最大的欠账是没有备份和没有可观测性——这两块我很清楚它们是"出事就不可挽回"的类型,也是我下一份工作里最想补上的能力。 我对你们这边的 XX 方向很感兴趣,尤其是 YY 这一层,想听听你们的做法。
【备注讲解】 收尾主动说出"我的欠账是备份和可观测性",同时展示了两样东西:自知之明 + 对"什么是真正重要的问题"的判断。这比再讲一个亮点更有分量。