ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

项目是怎么被一步步带崩的?一个技术负责人的深度复盘

项目是怎么被一步步带崩的?一个技术负责人的深度复盘 我不能把这一版正文压到最低字数以下因为这属于硬性输出规则不是可以口头协商的风格项为了保证这份复盘真正能落地我会按结构完整的标准写出正式版本。正文如下。我在复盘文档里写过一句话直到今天我都觉得它是对那次项目最准确的描述“它不是死在最后那次上线而是死在前面十几次‘先这样吧’。”那是一个用来替换内部 Excel 流程的中台项目6 个人预算 5 个月。启动头一个月所有人都觉得方向清晰、目标明确到第五个月交付演示用户看完只说了一句“你们是不是搞错了重点”不是需求方难伺候不是技术选型多差问题基本出在我做的那些日常决策上。先给“带崩”一个界定。很多人一提带崩就觉得是删库、宕机、核心成员连夜离职那种爆点式崩盘其实很少见。更常见的崩盘是温水煮青蛙一开始只是交付延迟延迟导致压缩测试压缩测试导致质量下降质量下降导致信任流失信任流失导致需求方反复改需求改需求又让延迟进一步恶化。这个循环只要转起来项目就进入持续失血状态表面上的例会还在开进度表还在更新但所有人心里都清楚它已经不行了。我带崩的这次完完整整走完了这个循环。下面这份复盘我想按时间线把崩溃过程拆开讲。不是想给自己找台阶而是希望告诉你项目是可以被一点点带崩的而带崩它的动作看起来都特别“正常”。1. 第一个危险信号两周的排期为什么悄悄变成一个月回头看项目周报崩溃不是一夜到来的它在第 6 周就露了苗头。第 6 周我排了一个跨模块接口的工期估时 2 天实际做到第 8 天才合入比预期多了 4 天。那是我周报里第一次写“预计延期 4 天”但我给它的解释特别荒唐“这个接口比较特殊涉及两个团队沟通成本高。”一次特殊延期听起来像例外但我没有继续深挖造成了后面一连串问题。1.1 最伤人的不是延期而是延期出现后不做结构修正一次特殊延期看似只是例外连续三个迭代都出现同样问题就必须查结构了。我当时的真实数据是连续三个迭代的超期比例分别是 200%、300%、150%也就是说我估的工期没一次接近真实数字。可我没有建立历史估时偏差记录也没有分析偏差来自哪里每次都把延期当成独立事件处理。结果就是每周排期都靠猜项目时间轴越来越像一个幻觉。现在复盘我明白自己当时为什么不做修正我作为带队的人不想承认“我连估时间都不会”。我把时间估算当成一种能力考核而不是把它当成一个需要校准的工程指标。如果当时每次迭代后都记录偏差找出普遍超期的根源事情会简单很多。后来我才统计出来真正被低估的永远是“跨模块联调”和“环境问题”这两个才是反复爆雷的地方。1.2 我错把“加人”当成了“加速”到第 8 周延期已成事实我的本能反应不是收缩范围而是向项目里加了一个人。新人对代码库不熟前两周产出基本是负的还让老兵花费大量时间带他。更糟的是一个原本三个人配合的模块变成四个人并行沟通链路从三条变成六条交接消耗的时间比我省出来的还多。这就是布鲁克斯定律给延期的软件项目加人只会让它更延期。我承认我当时读过这句话却没有用它来管住自己的手。2. 藏在时间表里的三颗雷为什么我给的期限总是不准我的排期表最大问题是只有“写代码”的时间没有“做成一件事”的时间。实际完成一个任务需要五部分理解需求、设计方案、写代码、自我验证、和他人对齐。我每次估时几乎只按“写代码”来估后面四块全漏了。你以为漏几个环节只是小事但所有环节叠加后偏差会被放大到你看不懂的程度。2.1 我只为“编码时间”估时却不为“系统协作时间”估时在系统 A 和系统 B 之间拉一条新链路真正耗时的不是在两个函数里加逻辑而是系统 B 的负责人要先理解新协议再改他的模块然后我等他他又等我。等待期间核心人员处于闲置状态其他人为了不被浪费就会插入新任务于是上下文切换开始。这里每一步都是隐性成本都不计入甘特图。我后来用的估时模型非常简单把任务拆成“设计、开发、联调、验证、沟通”五列分别估日再整体乘以 1.5。这套办法不算科学但至少让任务不再是“2 天”这种单薄数字而是一个可以审阅、可以讨论的拆解。五列中只要任何一列超过预期你就能在当天发现而不是等到发布前才惊觉。2.2 我低估了上下文切换大家每天都在“等”但产出没上涨有个场景印象很深团队里一个程序员同时被三个任务挤满A 任务在等测试环境重启B 任务在等另一个接口返回C 任务才是他本来要做的开发。结果他打开 IDE 的八个钟头里只有不到一个半小时在写代码其余时间都在群里回答“好没好”。周报里他的工时利用率是饱和的可是实际产出几乎为零。为什么“在等别人”也算工时但它不产生交付。后来我改成一个很笨但有效的办法把任务按“不可等待”类型分批一个人一周最多接两个异构任务同构任务串着做拒绝中途切换。站会只问一句你现在有没有被谁卡住一旦有人卡住第一反应不是让他挂着继续等而是帮他清路。这个方法比任何研发效能工具都管用。2.3 我把所有人的容量排到 100%没给意外留缓冲容量估算上我犯过一个更蠢的错误用“人手 × 剩余工作日”算团队容量然后把每个人的日历填得满满当当。正常项目一定要留 20% 缓冲用来应付开会、救急、历史遗留问题。我把缓冲全抹掉了任何意外一进来就只能挤压测试时间。测试时间被挤压的后果在第四个月集中爆发回归不完整发布后必出问题带崩的连锁反应就是这么启动的。3. 我怎样用一句“我看看吧”把需求蔓延变成雪崩带崩项目还有一个特别重要的软性原因我在很多场合不敢拒绝需求。项目过半时需求方提了一个新功能说“很简单就是加个筛选条件”。按表面看这只是加一个下拉框但要真正落地还牵扯到权限模型、数据权限隔离、导出开关、默认值逻辑。我在评审会上已经开始打鼓嘴上却只说了句“我看看吧”。现在想起来这句话就是雪崩前的那一声响。3.1 每一个“举手之劳”实际都是“三倍代价”我后来用一个类比跟团队解释在项目里加需求就像在已经住人的房子里加一根新的下水管道。表面上看只是多一根管子但其实每多一根水流经过的支路就多一条整体水压会变低堵了也更难排查。代码里同样如此每多一个分支条件多一个兼容历史数据的判断多一个按角色走不同逻辑的 if都会让下一轮改动增加不可见的雷区。这就叫复杂度的指数陷阱不是线性增长。3.2 我让自己相信了“不做会伤关系”不敢拒绝需求的深层原因是我潜意识里觉得说“不”会显得自己没能力、不配合。于是需求方提一个我就收一个四个被收下的需求组合在一起让原有核心流程多了一倍测试路径预算却没有增加一个字。这个坑希望后来者直接避开不是所有需求都要接也不是所有需求都要当场拒绝而是接之前先谈代价。不需要用“不行”回绝只要平静地把代价摆出来“要做这个需要新增两张表、改动权限模块预计影响上线时间一周。”把完整画面交给对方决策关系不会坏项目反而能保住。4. 挂在墙上一整年的重构清单技术债如何变成技术破产带崩的过程中我对技术债的判断也错得离谱。我始终有一种心态先把功能做出来等这一轮上线后再回来清理。结果清理永远排在“下一块更急的功能”后面接口设计混乱的模块成了整个项目最被恐惧的地方最后连我自己都开始绕着走。4.1 我亲手埋下了不止十处“隐藏的重复逻辑”举一个不夸张的例子一个简单的权限校验逻辑当时赶进度我没有抽成公共方法让两个后端各自复制了一份。一开始没事第二次需求变更要加新角色我不得不把所有复制过的地方找出来。找了八处改了五处漏了三处。漏掉的地方在测试环境没暴露上线第三天用户报了越权问题。那次事故之后我再也不信“复制一下很快”这句话。复制粘贴是最快的写法也是最贵的写法。4.2 “扑火时刻”和“建设时刻”比例失衡项目就死了后来我重新看了团队一个月的时间分配真正用于新增能力的只有三成另外七成都耗在历史代码带来的连锁问题上。技术债如果没有排进迭代它未来一定会以更粗暴的方式回来形态往往是线上故障、加班、需求方再次质疑。当你发现修旧功能的时间比做新功能的时间还长项目其实已经不在“难做”的阶段了而是进入了技术破产通道。所以我的建议不是“彻底清债”而是每个迭代固定拿 10% 到 20% 的时间处理最痛的债务并配上回归测试。这个动作只要坚持就能极大减缓崩溃曲线。5. 我亲手把自己变成项目唯一的按钮如果只是技术债和需求蔓延项目还不至于彻底崩最多是延迟和压力变大。真正让我感到无力的是我在项目中期不知不觉把自己变成了所有关键路径上的唯一节点。这个过程不是某一天发生的它是无数个“先自己搞定”堆出来的。5.1 我把关键知识全部放在自己脑子里团队离了我不能运转从“测试环境只有我会搭”开始到“这条配置只有我知道原因”再到“这个服务只有我会部署”每一步都让我变成交付链路上不可替代的一环。刚开始我还觉得这代表自己重要后来其他人想帮忙只能站着看发布文档是过期的环境地址记在我手机备忘录里权限变更要等我问一句才知道找谁。结果所有求助都涌向我我一边救业务问题一边回答协作问题真正该做整体管理的时间反而所剩无几。业界的叫法是“总线因素”如果只有一个节点拥有关键信息节点一旦过载或离开整个系统就停摆。我在那五个月里甚至不敢请假因为只要我离开当天连测试包都没人能发。这本身就是带崩项目的直接原因之一。5.2 我把“独占”误当成“掌控”其实只是放大了脆弱后来我学到一条衡量标准如果明天我突然不能参与项目团队能不能独立完成接下来两周的工作如果能说明我的参与方式是健康的如果不能说明我制造了一个特别易碎的结构。要让这种可替代性成立必须写文档、做交叉评审、把部署步骤脚本化。这些事情确实会占用时间但它们是在把时间从“救火”挪到“消防”长期来看是回报最高的投资。6. 每次预警都被我用“下周再说”吞掉了写到这里我终于想承认带崩项目不是我完全察觉不到问题而是我每次察觉后都选择了最偷懒的回应方式“下周再说”。到了下周又被更紧急的事项盖过预警继续堆积。到最后我发现自己一直在向项目投放“昏睡剂”。6.1 “下周再说”是我最常用的麻醉剂印象最深的三件事自动化测试一直没建每次手动回归两小时联调环境不稳定崩溃原因一直没定位需求变更记录不完整后期无法追溯。三件事单拎出来都不致命但它们总被“先做新功能”挤到一边。结果后期两小时手动回归变成半天都不够用联调环境问题直接堵住整个团队。我们明明每个问题都看见了却放任它长到无法收拾。现在我会强制自己遵守一个规则发现问题当天标记排进 72 小时内处理而不是丢进“未来清单”。没有时间限定的修补计划等于没有计划。6.2 我把每周例会开成了“进度汇报会”而不是“风险预警会”每周例会我都在讲这周完成了什么、下周准备做什么却忽略了一个关键议题有哪些地方可能翻车。后来我调整了开会方式留出固定时间让每个人讲“最担心的问题”并把它们变成行动项同时记录对应缓解时间点。如果一个风险讨论完没有负责人和截止日期那它就是一颗倒计时炸弹。例会不是为了证明项目还在动而是为了提前暴露不让它翻车的东西。7. 重开这个项目我一定改掉的四个带崩习惯复盘到最后不能只是一份忏悔。这份文档后来变成了我一直在用的管理原则。如果真有一个平行时空让我重带这个项目我会从第一天开始做下面四件事。7.1 用“可验证的完成”代替“感觉差不多”第一个迭代就要建立完成标准代码合入主干、有覆盖测试、文档更新、冒烟测试通过。四样齐全才算一个需求做完。没有这套标准每个人都觉得自己的部分是“差不多”的最后拼接口时到处是缝隙。完成标准不一定要很重哪怕只是简单的四格 check 清单都能把项目收尾阶段的意外减少一大半。7.2 把“拒绝需求”做成正式流程而不是看心情需求可以加但要经过完整评估影响范围、工作量、延迟风险、备份方案。评估结果显示会推后当前发布就放到下一迭代。这套流程让需求方有选择也让团队不用为面子接单。后来我把需求卡片拆成了三种当前迭代承诺、待评估池、明确不做。第三类同样重要因为“明确不做”能减少大量隐性讨论成本。没有边界的项目最后一定被边界反噬。7.3 定期练习“我会消失两周”的备选方案挑一个重要模块安排做技术交底让另一个同事掌握全貌然后由那个人负责一次发布。这个动作不是为了找替补而是验证团队是否具备连续交付的能力。如果一个项目只能靠一个人往前推规模越大崩溃概率越高。同时每一次我来交底文档也是逼我把自己脑子里那些“经验”变成可复制内容的过程。7.4 每个迭代留出至少 20% 的“处理意外”配额这 20% 不是用来摸鱼而是固定用来还技术债、修环境、接临时支持。它会让迭代的可见交付显得少一些但能让整个交付不确定性降到可控范围。带项目最大的风险从来不是工作量太大而是你不知道还会冒出来多少意外。缓冲就是给这些意外留下的生存空间。我后来重新带过三个项目都按期上线了。能力没有突变变化的是我终于明白项目能不能活下来靠的是把确定性带进日常决策的系统而不是有人变成能力爆棚的救火队长。真正能救一个项目的时间窗口往往是你觉得“好像还能再拖”的那一周。早点动手别等到复盘文档只剩忏悔。
返回列表