“不招人”不是策略,是情绪。这里想聊的不是 HR 政策,而是技术团队里一个很常见的决策:当交付变慢、代码质量波动、线上问题变多时,管理者的第一反应是“以后只招高级工程师,初级工程师进来只会添乱”。这个决定听起来果断,实际上往往解决不了你以为的问题,还会给团队埋下更深的隐患。
1. 核心观点速览:不招初级工程师的真实收益与代价
先说结论:停止招聘 junior 工程师,可能让短期交付质量略有提升,但解决不了“系统设计混乱”“需求链路太长”“代码评审流于形式”等根本问题。更麻烦的是,它会让团队失去人才梯队,导致高级工程师被琐事淹没,三年后出现严重的人才断层。
| 观察维度 | 只招 senior 的预期 | 实际常见结果 |
|---|---|---|
| 交付速度 | 短期提升,复杂任务上手快 | 长期下降,高级工程师被低价值工作占用 |
| 代码质量 | 代码规范度更好 | 代码评审变少,因为 senior 之间互评成本高 |
| 人力成本 | 可控,人少而精 | 不可控,薪资预算大幅上升,招聘周期变长 |
| 团队风险 | 单点能力更强 | 单点故障更严重,一人离职可能带走关键上下文 |
| 人才梯队 | 结构精简 | 断层严重,内部晋升通道消失 |
| 技术氛围 | 减少初级错误 | 失去教学相长,技术分享减少,创新意愿下降 |
| 系统债务 | 复杂逻辑有人维护 | 文档和知识沉淀减少,系统认知集中在少数人脑中 |
把表格里的信息压缩成一句话:不招 junior,是把招聘问题当成了解最方便的操作杠杆,但团队真正的问题往往出在流程、系统复杂度、上下文传递和反馈机制上。
如果团队当前处于“急缺一个能立刻顶上去解决线上问题的工程师”的状态,那么招聘 senior 是合理的。如果团队处于“长期发展、持续交付、需要稳定知识沉淀”的状态,那么完全砍掉 junior 岗位是一个风险很高的决定。
2. 不招 junior 想解决的问题到底是什么
先拆解一下这个决策背后的真实动机。大多数团队宣布“不再招聘初级工程师”时,通常有四个原因。
2.1 初级工程师培养成本高
新人入职后,需要熟悉业务背景、代码结构、部署流程、协作规范。这个过程通常需要 3 到 6 个月才能真正产生稳定产出。如果团队缺少成熟的培训文档和导师机制,新人上手会更慢,而带新人的任务通常落在 team lead 或资深工程师身上,这会让本来就紧张的人力更加紧张。
这个动机成立的前提是:团队有足够的资深成员去带新人。如果团队已经全是 senior,那么新人进来后反而会有更充足的指导资源,培养周期会被显著压缩。因此“培养成本高”只能解释“当前阶段不适合大量招聘 junior”,不能推导出“永远不招 junior”。
2.2 初级工程师容易产生质量问题
刚入职的工程师对测试、代码评审、发布流程都不够敏感,容易写出能运行但难以维护的代码。如果团队没有建立足够的自动化测试防线,新人确实会引入更多线上问题。
但这里有一个被混淆的因果关系:代码质量差的核心原因是缺少强制性的质量门禁,而不是写代码的人叫 junior。一个没有单测覆盖、没有 lint 规则、没有强制 code review 的团队,就算全部换成 senior,质量问题依然会出现,只是出现得慢一点。
2.3 管理成本与沟通成本太高
junior 更需要反馈、更频繁地提问、更需要上下文同步。对管理者来说,这确实增加了沟通成本。但换一个角度看,频繁提问本身就是对系统设计的压力测试。新人的问题常常能暴露出文档缺失、命名混乱、模块边界不清晰的问题。把这些反馈当成噪音,会错过很多改进机会。
2.4 招聘预算和 HC 有限,想用在“刀刃”上
这是最实际的一个动机。团队只有一个 HC,与其招一个还要培养半年的人,不如多花点钱招一个立刻能干活的人。单看这一次决策,没问题。但如果每次都这样选择,团队结构会迅速趋向于“全员资深”,而资深工程师之间做的工作差异会越来越大:有人在做架构设计,有人在写文档,有人在救火。最终团队会发现自己没有足够多的普通执行型工程师来承接重复性工作。
3. 减少 junior 为什么解决不了核心问题
如果用技术类比来解释,停止招聘 junior 不是修复 bug,而是屏蔽错误日志。日志还在,只是你看不到了。
3.1 问题出在系统复杂度,而不是人员等级
当团队发现新人无法快速上手时,第一反应往往是“新人水平不行”。但更可能的原因是系统复杂度高到不合理:一个简单的需求需要改动 5 个服务、经过 3 个消息队列、涉及 2 套数据存储。这种复杂度下,不只是 junior 做不了,新来的 senior 同样需要很长时间才能理解全貌。
不招 junior,团队会陷入“没有新人也就没有人抱怨系统难懂”的假象。所有抱怨都消失了,但系统复杂度不会自动降低。
3.2 问题出在反馈链路,而不是输入质量
软件工程的质量主要靠反馈循环保证:编译、测试、静态检查、评审、灰度发布、线上监控。如果这些反馈链路是完整的,一个中级工程师也能写出高质量代码。如果反馈链路是断裂的,一个高级工程师也可能在错误的抽象上不断叠加错误。
合理的做法是优先补齐 CI/CD、自动化测试、评审规范和监控告警。停止招聘 junior 是把“输入”卡掉,但没有改善“处理过程”。
3.3 问题出在任务拆解能力,而不是执行能力
团队里大量任务并不是需要十年经验的架构设计任务,而是需要精确理解、稳定执行的常规任务。如果团队所有任务都必须由资深角色完成,说明任务拆解做得不够。一个健康的团队,应该能将复杂需求拆成不同难度等级的工单,让不同水平的工程师都能找到适合的切入面。
不招 junior,等于拒绝承认任务可以被拆解,也等于把这些常规任务的成本拉高到资深工程师的时薪水平。
4. 只招 senior 的结构性代价
只招 senior,真正要付出的长期成本往往被严重低估。
4.1 人才梯队断层
团队里如果全是 P6/P7+ 级别的工程师,那么内部晋升空间几乎为零。资深工程师看不到后续梯队,会觉得团队没有成长性;团队也没有足够的基层力量去承接工具链、测试、文档、数据整理这类高重复性工作。等到现有这批 senior 因为家庭、职业规划或个人原因离开时,团队会发现自己根本无人可用。
4.2 知识集中带来的单点故障
senior 之所以是 senior,是因为他们掌握了大量上下文,比如系统为什么这样设计、哪些接口不能动、某个模块的历史包袱在哪里。这些上下文如果只存在于少数人脑中,团队就变得非常脆弱。junior 和 mid-level 工程师的存在,实际上是在倒逼团队把知识显性化:新人要能上手,就必须有文档、有架构图、有标准操作流程。
砍掉 junior,团队会失去知识外溢的动力。文档越来越少,口头沟通越来越多,最终形成一种“这件事只有 A 能解决”的局面。
4.3 成本结构持续恶化
高级工程师的薪资通常是初级的 1.5 到 2 倍以上。如果他们还需要承担本可以由初级工程师完成的重复性工作,从组织投入产出比来看是负优化。同时,高级工程师市场供给少,招聘周期长,团队用人压力会进一步加剧。在预算有限的前提下,一个更合理的选择是用一个 senior 搭配一两个 junior,组成一个能力互补的小组。
4.4 团队氛围和技术创新受损
成熟的团队需要不同层级的碰撞。junior 的提问方式更 naive,也更不受既有假设约束;很多反直觉的优化和创新,恰恰是从“为什么一定要这样做”开始的。当团队全部由资深工程师组成时,讨论往往会变成经验之间的博弈,而不是对问题本身的重新审视。
5. 用工程模型对比不同人才策略
与其在直觉层面争论,不如建立一个简单的可计算模型。下面的 Python 代码是一个简化示例,用来对比“纯 senior 策略”和“混合梯队策略”在总产出上的差异。
# 人才策略对比模拟:纯 senior 策略 vs mixed 策略 # 这里只演示思路,具体数字需要按团队实际情况填写 class Engineer: def __init__(self, level, salary_unit, years_to_invest, mentor_ratio=0.0): self.level = level # "senior" / "junior" self.salary_unit = salary_unit self.years_to_invest = years_to_invest # 需要投入的培养年数 self.mentor_ratio = mentor_ratio # 导师投入时间占比 def effective_output(self, total_weeks): # 简化假设:junior 需要导师部分投入,senior 自带完整产出 if self.level == "senior": return total_weeks * 1.0 else: return total_weeks * 0.4 def simulate(population, weeks=48, cost_per_mentor_per_week=3): total_output = 0 total_cost = 0 for eng in population: total_output += eng.effective_output(weeks) total_cost += eng.salary_unit # 导师投入成本 if eng.level == "junior": total_cost += eng.mentor_ratio * cost_per_mentor_per_week return total_output, total_cost # 示例:5 个 senior all_senior = [Engineer("senior", 10) for _ in range(5)] # 示例:2 个 senior + 3 个 junior mixed = [ Engineer("senior", 10), Engineer("senior", 10), Engineer("junior", 5, years_to_invest=1, mentor_ratio=0.2), Engineer("junior", 5, years_to_invest=1, mentor_ratio=0.2), Engineer("junior", 5, years_to_invest=1, mentor_ratio=0.2), ] output_a, cost_a = simulate(all_senior) output_b, cost_b = simulate(mixed) print(f"纯 senior 策略:总产出 {output_a:.2f},总成本 {cost_a}") print(f"混合梯队策略:总产出 {output_b:.2f},总成本 {cost_b}") print(f"如果 junior 在一年后成长为 mid-level,其后续产出会显著提升")这个模型的核心不是给出精确数字,而是提醒团队:人才策略是有时间维度的。只看当前季度,纯 senior 策略产出高;看两年周期,培养起来的 junior 会逐步贡献更多价值,而且团队对个别成员的依赖度更低。
6. 正确的人才梯队设计:混合策略
一个健康的团队人才结构不应该是“全 junior”或“全 senior”,而是像一套分层缓存系统:资深工程师负责存储长期记忆和复杂计算,初中级工程师负责大量常规请求,并不断积累经验向上流动。
# 团队梯队设计参考(示意配置,按团队规模调整) team_profile: team_size: 10 levels: junior: count: 4 responsibility: ["模块实现", "单元测试", "文档维护", "修复低风险缺陷"] mentorship: "每人配一个 senior 作为 mentor,每周固定 1~2 小时 1:1" promotion_target: "1~2 年内成长为 mid-level" mid: count: 3 responsibility: ["独立交付需求", "牵头小项目", "指导 junior", "参与代码评审"] mentorship: "可作为 junior 的 mentor,同时接受 senior 的架构指导" senior: count: 3 responsibility: ["系统设计", "解决疑难问题", "跨团队协调", "培养 mentor"] mentorship: "负责 mid 和 junior 的成长,减少直接写业务代码的比例"把这条 YAML 转成团队管理的行动,就是三个词:
- 分层:任务按难度拆分,而不是按人头级别分配。
- 带教:senior 的产出里必须包含“指导他人”的部分,否则他只是在写代码,没有形成组织能力。
- 晋升:每个 junior 都应该有一条明确可见的成长路径,而不是进来后自生自灭。
7. 培养 junior 工程师的落地清单
如果团队决定重新开放 junior 招聘,需要有一套可执行的培养机制,否则“招 junior”又会变得一团糟。
7.1 入职第一周:给一个完整的最小任务
新人入职最怕的就是“先看文档熟悉项目”,然后连着一个星期没人管。更好的做法是,入职第一天就给他一个边界清晰、风险较低的真实任务,比如修复一个日志告警、补充一个接口的单元测试、整理一份模块调用关系图。任务本身是否重要不是关键,关键是让他立刻进入“修改代码 -> 跑测试 -> 提交评审 -> 发布验证”的完整链路。
7.2 前三个月:强制代码评审和每日同步
代码评审是 junior 成长最核心的环节。评审不是只点评错误,而是要说明“为什么这样写在项目里会有问题”。每天 15 分钟的站会或 1:1,可以快速暴露新人是否被卡在某一个技术细节上。
# 示例:每周统计代码评审覆盖情况(基于 git 仓库) # 注意:这是一个通用统计思路,实际命令需要按团队代码托管平台调整 git log --since="1 week ago" --pretty=format:"%h %an %s" > commits.txt git log --since="1 week ago" --merges --pretty=format:"%h %an %s" > merges.txt wc -l commits.txt merges.txt从提交数、合并请求数、首个请求合入耗时这些数据里,能大致判断新人是否融入了协作流程。如果长期只有提交没有合入,说明评审链路或权限配置有问题。
7.3 设定明确的晋级标准
junior 的晋升不能只靠“老板觉得他变强了”。建议定义可观察的标准:独立交付了多少个需求、通过了多少次代码评审、是否主动发现问题并修复、是否能给其他人做一次有效的技术分享。
7.4 给 senior 设计带教激励
让资深工程师带新人,不能只靠口头感谢。在绩效考核里要加入“人才发展”维度:培养了谁、产出了什么文档、帮助团队降低了对自己的依赖。否则,带教就会变成一项没有回报的额外负担,senior 自然不愿意做。
8. 接口思维:从“招人”到“建立人才通道”
如果把“招聘”看成一个接口,那么只招 senior 等于把这个接口的并发能力设得非常低,只接受高配请求。更好的做法是建立一条人才流水线:实习生 -> 初级工程师 -> 中级工程师 -> 高级工程师,每一级都有明确的输入、输出和验收标准。
这条通道的价值在于:团队不再依赖外部市场的稀缺人才供给,而是通过内部培养和晋升形成稳定的供给能力。
对 junior 来说,面试进入团队只是第一步,后续的成长机制才是重点。对团队来说,判断标准是:一个 junior 进来后,一年后他是否明显比入职时强,团队是否因为他而沉淀下来了更多文档和工具。如果答案都是否,说明培养机制出了问题,而不是“当初不该招 junior”。
9. 团队健康度与交付性能观察
停止招聘 junior 后,团队表面上变得“稳定”了,但稳定不等于健康。建议用 DORA 四指标和代码评审数据持续观察团队状态,不要只凭感觉做判断。
| 观察指标 | 含义 | 团队变差的信号 |
|---|---|---|
| 部署频率 | 发布的频繁程度 | 发布次数减少,说明复杂度在上升,大家不敢发版 |
| 变更前置时间 | 从代码提交到功能上线的时长 | 前置时间变长,说明测试、评审或环境准备出现瓶颈 |
| 变更失败率 | 发布后导致故障的比例 | 数值上升,说明质量防线失效 |
| 服务恢复时间 | 从故障到恢复的时间 | 时间变长,说明系统可观测性和应急能力不足 |
| 代码评审覆盖率 | 合并请求经过评审的比例 | 超过 30% 的合并没有评审,说明知识传递失效 |
| 文档更新频率 | 设计文档、接口文档、运维手册的更新次数 | 文档长期不更新,说明系统认知开始黑盒化 |
这些指标比“团队里有多少个 senior”更能反映真实问题。如果部署频繁降低、前置时间拉长,不是靠多招几个高级工程师就能解决的,需要审视架构复杂度、测试策略和协作流程。
10. 常见误区与排查方法
把团队中关于招聘和人才管理的常见争论整理成一张排查表,方便对照。
| 常见说法 | 可能存在的误区 | 更稳妥的判断 |
|---|---|---|
| “新人写代码质量太差,不能招” | 没有把质量门禁前置,靠人来保证质量 | 先补自动化测试和评审,再评价新人产出 |
| “培养新人太费时间,不划算” | 只看短期成本,忽略两年后收益 | 为培养机制设上限,比如每个 senior 最多带 1~2 人 |
| “团队现在的任务很简单,不需要新人” | 任务简单是表象,背后是没人做任务拆解 | 如果任务都是简单重复的,说明系统需要抽象和工具化 |
| “只招 senior 可以降低管理成本” | 管理成本转移到上下文维护和招聘成本上 | 统计 senior 在面试、救火、答疑上花费的时间 |
| “没有 budget 培养新人” | 培养不等于烧钱,结构化 review 也能培养 | 把周五技术分享和结对编程纳入固定节奏 |
| “junior 留不住,培养了也是白培养” | 忽略离职原因通常是发展空间不足 | 明确晋升路径比单方面提高薪资更能留人 |
把这些问题提前摆到桌面上讨论,比执行一个“不招 junior”的一刀切决策更有价值。
11. 最佳实践与阶段性建议
如果团队正在犹豫要不要继续招初级工程师,可以参考如下路径。
11.1 先诊断,再关闸
在停止招聘 junior 之前,先回答三个问题:
- 团队当前最严重的瓶颈是人才能力,还是流程和系统复杂度?
- 过去一年离职率最高的环节在哪里?
- 现有 senior 是不是在做初级工作?
如果答案里最多的是“流程问题”和“任务拆解问题”,那就不应该关掉 junior 通道。
11.2 小规模试点
不需要一次性恢复大规模校招。可以招 1 到 2 个 junior,要求团队必须配 mentor、写培训文档、每周 review 进展。三个月后再看效果,用数据决定下一步。
11.3 把培养指标纳入考核
培养新人不是“额外工作”,而是资深工程师的核心职责之一。没有培养指标,senior 就没有动力把知识写下来、讲出来、传下去。团队要学会表扬那些“让团队更不依赖自己”的人,而不是只表扬写代码最多的人。
11.4 定期复盘人才通道
每半年复盘一次:junior 是否按期晋升,mid-level 是否能承担更多设计工作,senior 是否脱离了执行细节。人才通道一旦运转起来,团队对单一外部输入的依赖会明显下降。
最后说一句
不招 junior 本质上是一个非常容易执行的决定,因为只需要修改招聘 JD 就够了。但它只是让团队看起来更精锐,没有解决系统复杂度、质量防线和知识沉淀这些真正的问题。如果你的团队也在犹豫要不要关掉初级岗位,我的建议是:先别急着关阀门,把数据拉出来,看看到底是“人的问题”还是“系统的问题”。大多数时候,答案比你以为的要复杂。