《代码之外:程序员重启人生》· 第02篇
上一世,他替所有人承诺了三周上线。
这一世,他决定让每一个人都看见:这个“不可能完成的排期”,到底是谁定的。
周一上午十点。
会议室里坐了十二个人。
产品、研发、测试、项目经理、业务负责人,还有两个林川以前只在组织架构里见过的领导。
投影仪上打开着一份需求文档。
标题很大:
会员增长系统二期建设方案。
项目经理站在屏幕旁边,语气很有信心。
“这个项目是本季度的重点任务,业务希望三周后上线。”
他说到这里,停了一下,看向研发团队。
“整体需求不算复杂,主要是在现有系统上增加几项能力。大家今天把方案和排期定下来,下午就正式启动。”
林川坐在会议桌末端。
面前放着电脑,屏幕上是一份刚刚收到的需求文档。
他只看了前五页,就知道这场会议会发生什么。
上一世,就是在这间会议室里。
就是同一个时间。
就是同一句话。
三周后上线。
那一次,他只用了不到二十分钟就看完了整份文档。
然后得出了一个结论:
做不完。
但他没有直接说。
因为当时的他认为,技术人员不能一上来就否定业务需求。
要体现担当。
要积极配合。
要先想办法,不要先讲困难。
后来项目经理问他:
“技术上应该没问题吧?”
全场都看着他。
他犹豫了几秒,回答:
“如果需求不再调整,大家加加班,应该可以。”
就是这句话,把整个研发团队推进了一个持续三周的深坑。
接下来的二十一天里:
需求改了六次。
原型改了四版。
第三方接口直到上线前五天才提供。
测试环境晚了一周。
业务规则每天都有新解释。
最终,项目延期九天。
复盘会上,所有过程都被压缩成了一句话:
研发前期评估不充分,对需求复杂度判断不足。
这一世,林川重新坐在这里。
项目经理刚好讲到:
“这个项目虽然时间紧,但我相信大家有能力克服困难。”
林川低头看了一眼时间。
十点零七分。
距离上一世他说出那句“应该可以”,还有十三分钟。
一、需求文档写了三十页,却没有一个人真正说清需求
产品经理开始介绍功能。
“二期主要包括用户分层、权益匹配、活动推荐、优惠券自动发放、效果分析几个模块。”
业务负责人补充:
“这次最重要的是灵活。后续业务有什么新玩法,都能快速配置,不要每次都重新开发。”
产品经理点开下一页。
页面上画着一个很完整的系统架构图。
从用户标签,到规则引擎,再到推荐策略、优惠券中心和数据分析。
箭头很多。
模块也很多。
看起来几乎没有遗漏。
项目经理问:
“技术这边有没有问题?”
会议室安静了两秒。
后端组另一个同事低头看电脑。
前端负责人翻着原型。
测试负责人皱着眉,没有开口。
林川知道大家都看出了问题。
但谁也不想第一个站出来。
因为这是重点项目。
业务领导在场。
项目经理已经公开表态“三周上线”。
这时候提出问题,很容易被理解为不积极、不担当,甚至是故意给项目设置障碍。
上一世的林川也这么想。
所以他选择了先把事情接下来,再慢慢解决。
但他后来才明白:
评审会上没有说清的问题,不会消失。
它们只会被延期到开发阶段,以需求变更、返工、加班和事故的形式重新出现。
林川抬起手。
“我有几个问题需要确认。”
项目经理看了他一眼。
“你说。”
林川没有先讨论能不能做。
他打开需求文档,从第一条开始问。
“用户分层规则由谁配置?”
产品经理回答:
“业务人员配置。”
“具体通过哪些条件组合?”
“年龄、地区、消费情况、活跃度这些,后续也可能增加。”
“条件之间支持与、或、嵌套吗?”
产品经理停顿了一下。
“最好都支持。”
“嵌套层级有没有限制?”
“这个还没考虑。”
林川继续问:
“权益匹配冲突时按什么规则处理?比如同一个用户同时命中三个活动,是叠加发放,还是优先级覆盖?”
业务负责人说:
“原则上不能重复发,但具体要看活动。”
“那么不同活动的互斥规则由谁配置?”
“也做成灵活配置吧。”
“优惠券发放失败是否重试?重复发放如何判断?活动规则修改后,已经进入执行队列的用户按旧规则还是新规则处理?”
会议室逐渐安静下来。
产品经理原本翻页的手停住了。
业务负责人皱起眉。
“这些属于技术实现细节吧?”
林川摇了摇头。
“不是技术细节,是业务规则。技术可以按照规则实现,但不能替业务决定用户应该拿哪张券。”
业务负责人没有立刻回答。
林川接着问:
“效果分析需要实时还是次日更新?”
“最好实时。”
“实时到什么程度?一分钟、五分钟,还是操作后立即显示?”
“当然越快越好。”
“目前交易数据同步到分析库平均有二十分钟延迟。如果要求五分钟以内,需要调整现有数据链路,这不在当前需求范围里。”
业务负责人看向项目经理。
“这个之前没人告诉我们。”
项目经理看向产品经理。
产品经理又看向林川。
林川没有接这个眼神。
他只是把刚才的问题逐条记录在屏幕上的表格里。
不到十分钟,待确认项已经有十七条。
原本看起来非常完整的三十页需求文档,此时像一栋只画了外立面、却没有水电和承重结构的房子。
二、“你先评估一个时间”,是程序员最容易接下的陷阱
项目经理显然不想让会议继续陷入细节。
他打断了讨论。
“这些问题可以后续再确认。我们今天先把大体排期定下来。”
随后,他看向林川。
“按照现在的功能范围,三周能不能完成?”
上一世,这句话让林川陷入了一个错误的思考方式。
他开始在脑子里快速计算:
两天搭框架。
五天做规则引擎。
三天对接优惠券。
三天开发管理页面。
剩下时间联调和测试。
如果周末加班。
如果接口按时提供。
如果需求不再修改。
如果所有人都不出问题。
似乎勉强可以。
程序员很容易做这种理想状态下的估算。
因为写代码时,我们习惯假设输入明确、依赖可用、环境稳定。
可项目排期不是算法题。
它不是问你:
在所有条件完美的情况下,最快多久能写完?
它真正问的是:
在当前信息不完整、资源有限、需求可能变化的情况下,你愿不愿意对某个日期负责?
上一世的林川没有看懂这个区别。
这一世,他没有直接给时间。
他反问:
“这个排期是指开发完成,还是正式上线?”
项目经理愣了一下。
“当然是正式上线。”
“是否包含需求确认、技术设计、开发、联调、测试、业务验收和上线准备?”
“包含。”
“上线后需要灰度吗?”
“需要。”
“灰度观察多久?”
“这个到时候再看。”
林川点了点头。
“那现在还不能给出三周能上线的结论。”
项目经理的脸色有些变化。
“你先做一个初步评估,不需要特别精确。”
林川说:
“初步评估也需要基于明确假设。否则这个数字后面很容易变成研发承诺。”
会议室里的气氛突然变得有些微妙。
所有人都听懂了这句话。
项目经理笑了一下。
“没人说让你一个人承担,项目是大家一起做的。”
林川也笑了。
“既然是大家一起承担,那我们就把各方前置条件和责任一起写进排期。”
他说完,把自己的电脑投到了大屏幕上。
上面是一张简单的表格。
| 阶段 | 前置条件 | 责任人 | 预计时间 |
|---|---|---|---|
| 需求确认 | 业务规则全部确认 | 产品、业务 | 待确认 |
| 技术设计 | 需求基线冻结 | 研发 | 3个工作日 |
| 核心开发 | 第三方接口文档齐备 | 研发 | 10—12个工作日 |
| 联调测试 | 测试环境可用 | 研发、测试 | 5个工作日 |
| 业务验收 | 验收标准明确 | 业务 | 3个工作日 |
| 灰度上线 | 无阻塞问题 | 全体 | 2个工作日 |
林川指着第一行。
“现在需求规则没有确认,第三方接口也没有提供,验收标准还没定义。”
“基于当前信息,我只能评估研发净开发时间,无法承诺正式上线时间。”
项目经理问:
“那研发净开发需要多久?”
“需求冻结以后,十五到十七个工作日。”
业务负责人立刻皱眉。
“那不是超过三周了吗?”
“是。”
“能不能压缩?”
“可以。”
林川回答得很快。
会议室里的几个人同时抬头。
项目经理似乎松了一口气。
“怎么压缩?”
林川切换到下一页。
“有三个方案。”
三、这一次,他不再只说“做不了”
大多数程序员面对不合理排期时,常见的反应有两种。
第一种是直接说:
做不了。
第二种是硬着头皮说:
我们尽量。
第一种容易被认为不配合。
第二种则会把风险全部留给自己。
真正有效的方式,不是替决策者说“行”或“不行”。
而是把可选方案、代价和风险同时摆出来。
林川在屏幕上列出三个方案。
方案一:三周上线核心版
保留:
基础用户分层
固定规则匹配
单一优惠券发放
次日效果统计
暂不支持:
复杂规则嵌套
多活动冲突处理
实时分析
灵活策略配置
风险最低,可以在需求本周冻结的前提下推进。
方案二:三周上线完整版
需要:
增加两名后端开发
一名前端全程投入
测试提前介入
第三方接口两天内提供
需求不得再发生范围变化
即使满足以上条件,仍存在联调和质量风险。
方案三:五周上线完整版
按照正常研发流程推进。
保留完整设计、测试和灰度时间,整体风险可控。
林川说完,看向业务负责人。
“如果上线日期不能调整,建议选择方案一。”
“如果功能范围不能调整,建议选择方案三。”
“如果日期和范围都不能调整,就需要增加资源,并接受更高的线上风险。”
会议室安静了几秒。
没有人再问“为什么不能既要又要”。
因为林川已经把那句话翻译成了明确成本。
业务负责人看着屏幕。
“三周核心版,后续再补完整功能,会不会影响后面的扩展?”
“只要我们提前保留规则扩展接口,不会影响整体方向。但首期不要一次性实现所有配置能力。”
产品经理问:
“那业务后面想加新规则怎么办?”
“进入下一期迭代。”
“但领导希望一次到位。”
林川看向坐在最前面的业务领导。
“技术上可以一次到位,但一次到位意味着上线时间至少五周。需要请业务确认,当前最重要的是上线速度,还是完整能力。”
这句话说完,决定权终于回到了真正应该做决定的人手里。
业务领导沉默片刻。
“先上核心版。”
项目经理立刻说道:
“那就按核心版三周推进。”
林川没有马上答应。
他补充:
“需要明确三个前提。”
“第一,本周三之前确认并冻结核心版需求。”
“第二,第三方优惠券接口最晚本周五提供。”
“第三,如果核心版范围发生变化,排期同步调整。”
项目经理点头。
“可以。”
林川问:
“这些结论是否写进会议纪要?”
项目经理脸上的笑容停了一瞬。
随后说道:
“当然。”
林川低下头,保存了表格。
上一世,那个模糊的“三周上线”是他一个人背下来的。
这一世,三周依然没有改变。
但范围、条件、责任和风险全部写清楚了。
表面上看,他只是多问了几个问题。
实际上,他改变了整个项目的责任结构。
四、会议结束前,真正的博弈才刚刚开始
需求评审持续了两个小时。
会议快结束时,项目经理进行总结。
“今天整体结论是,项目按照三周上线推进。研发这边由林川牵头,大家全力配合。”
林川听到这里,立刻抬起头。
上一世也是这样。
“由林川牵头。”
听起来像重视,实际上意味着:
排期是项目经理定的。
需求是产品和业务提出的。
资源由各部门掌握。
最后结果却由林川负责。
这是典型的责任下沉。
林川问:
“我确认一下,牵头具体是指哪部分?”
项目经理说:
“整体技术推进,包括方案、开发、联调以及风险协调。”
“跨部门资源也由我协调吗?”
“你先推动,有问题再找我。”
上一世,林川听到这里会默认接受。
这一世,他继续问:
“如果第三方接口延期,我有权调整项目上线时间吗?”
“这个需要大家一起决定。”
“如果需求范围增加,我有权拒绝加入当前版本吗?”
“也要具体讨论。”
“如果测试资源不足,我可以直接调整测试人员安排吗?”
项目经理皱起眉。
“人员安排当然由测试负责人决定。”
林川点头。
“那我可以负责技术方案和研发交付,但整体项目排期、跨部门资源和范围变更,需要由项目经理负责。”
会议室里有人低下头,似乎在忍笑。
项目经理沉默两秒。
“这是当然的。”
林川说:
“好,那请会议纪要里写成:林川负责技术方案及研发交付,项目经理负责整体进度、资源协调及范围管理。”
这一次,项目经理没有立刻回答。
业务领导抬头看了他一眼。
“这样写比较清楚。”
项目经理只能点头。
“可以。”
林川没有胜利者的得意。
他只是安静地在自己的笔记中写下一句话:
责任必须和权限绑定。
上一世,他承担了整体结果,却没有任何整体权限。
需求变更,他不能拒绝。
资源不到位,他无法调配。
接口延期,他只能等待。
最后项目延期,却要解释自己为什么没有做好项目管理。
这种事情在职场里并不少见。
一个人被要求“对结果负责”,听起来像是获得了信任。
但如果没有对应的决策权、资源权和范围控制权,这种负责往往只是:
提前指定背锅的人。
五、下午三点,需求果然开始变了
会议结束不到三个小时。
产品经理在群里发来一条消息:
业务刚补充了一个需求,希望首期支持会员等级自动升降,应该不复杂,麻烦研发一起加进去。
群里没人回复。
林川打开需求说明。
所谓“会员等级自动升降”,涉及:
消费金额计算
有效期
退款扣减
跨月统计
等级保留
降级保护
人工调整
历史数据迁移
这不是一个小功能。
而是一套独立规则系统。
上一世,面对这种消息,林川通常会先在心里骂一句,然后回复:
收到,我评估一下。
评估完发现工作量很大,又担心显得不配合。
最后往往会变成:
我们尽量加进去。
这一次,他没有立即讨论技术方案。
他先回复:
该需求不在今天评审确认的核心版范围内,初步判断会影响现有排期。我先补充工作量和影响分析,之后请项目经理组织确认是否加入当前版本。
十分钟后,他发出评估结果:
新增会员等级自动升降预计增加5—7个工作日开发量,并涉及历史数据处理和规则确认。
可选方案:
保持三周上线,等级功能进入下一期;
加入当前版本,上线时间顺延一周;
增加一名后端开发,但仍需业务在两天内确认完整规则。
请确认方案后调整版本范围及排期。
产品经理私聊他:
这个没必要搞得这么正式吧?以前类似的小需求不都是直接加吗?
林川看着这句话,想起上一世无数个“顺便”。
顺便增加一个字段。
顺便补一个查询条件。
顺便支持一下导出。
顺便把规则做成可配置。
最后,一个原本三天的功能,变成了三周还做不完的系统。
他回复:
小改动可以直接处理,但涉及范围和排期变化的需求需要公开确认。这样后续业务、产品和研发对上线内容的理解是一致的。
产品经理没有再回复。
半小时后,项目经理在群里说:
会员等级功能放到下一期,本期范围不变。
事情就这样结束了。
没有争吵。
没有得罪人。
也没有通宵加班。
林川第一次发现:
当你把变更成本说清楚以后,很多所谓“必须马上做”的需求,会自动失去紧迫性。
不是业务突然变得讲道理。
而是过去每一次需求变更的成本,都被研发人员默默吞掉了。
当吞掉成本的人不再沉默,决策才会恢复真实。
六、项目进行到第二周,所有人都在等待他失败
林川的变化很快引起了注意。
有人觉得他专业。
也有人觉得他变得难沟通了。
午饭时,前端同事半开玩笑地说:
“你最近怎么什么都要留记录?开始防着大家了?”
林川回答:
“不是防谁,是防止大家记忆不一样。”
对方笑了笑。
“你这人现在说话一套一套的。”
林川没有解释。
他知道,在一个长期依赖模糊协作的团队里,开始明确边界的人,往往最先被认为不合群。
因为过去很多人的轻松,建立在另一个人的模糊承担之上。
你突然不再兜底。
他们感受到的不是规则变清晰了,而是你没有以前好用了。
项目进入第二周,第三方接口仍然没有提供。
上一世,这个问题拖到上线前五天。
林川每天都在私聊催促,却没有公开同步。
后来联调延期,大家只记得研发没有按时完成。
这一世,接口超过约定时间的当天上午,他就在项目群更新了风险:
第三方优惠券接口原计划本周五提供,目前尚未收到。该接口是联调前置条件,如今天无法提供,联调及上线时间将按实际延迟天数顺延。请项目经理协助确认最新交付时间。
第三方负责人很快回复:
我们还在内部测试,预计下周二提供。
项目经理私聊林川:
群里不用直接说上线顺延,会给业务造成压力。你们先并行开发,后面想办法追回来。
林川看着这句话,太熟悉了。
“先并行开发。”
“后面追回来。”
翻译一下就是:
外部依赖延期,不调整总排期。
损失的时间,研发通过加班补回来。
上一世,他接受了。
这一世,他回复:
我们已经基于模拟数据并行开发,但真实接口联调和异常验证无法提前完成。可以继续维持目标日期,但需要把接口延期列为项目风险,最终上线时间根据联调结果确认。
项目经理问:
你一定要这么较真吗?
林川想了一会儿。
回道:
我不是在争责任,是在确保项目计划基于真实条件。
对方没有再回复。
下午,项目周报中多了一条:
风险:第三方接口延期,可能影响联调时间。负责人:项目经理协调。
林川看到这句话时,心里没有多大波动。
他只是知道,这一次,风险终于去了它应该去的地方。
七、上线前一天,没有人再问他为什么没早点说
第三周周四。
第三方接口完成联调。
测试发现两个阻塞问题。
如果按照上一世的节奏,团队会连夜修复,第二天强行上线。
一旦上线出问题,研发再负责救火。
项目经理在群里问:
问题今晚能不能解决?明天的上线计划尽量不要动。
林川回复:
第一个问题今晚可以修复。第二个涉及第三方重复发券,需要双方联合验证。
当前建议:
周五修复并完成回归,周一上线;
保持周五上线,但关闭自动发券功能,待验证通过后再开启。
不建议在重复发券风险未确认的情况下全量上线。
业务负责人问:
重复发券概率高吗?
“目前测试十次出现两次。”
“影响是什么?”
“同一用户可能获得多张优惠券,涉及营销成本和客诉。”
业务负责人很快做出决定:
周一上线,先保证稳定。
没有人说研发延期。
没有人说林川不担当。
因为从项目第一天开始,所有范围、前置条件、依赖和风险都在公开记录中。
大家清楚地知道项目为什么走到今天。
周一上午,核心版顺利上线。
没有通宵。
没有事故。
也没有人在复盘会上寻找责任人。
业务领导在项目总结会上说:
“这次虽然时间紧,但范围控制和风险管理做得不错。后续项目可以复用这套方式。”
项目经理坐在旁边,表情有些复杂。
会议结束后,他找到林川。
“这次项目做得不错。”
林川说:
“是团队配合得好。”
项目经理看着他。
“你和以前不太一样了。”
“哪里不一样?”
“以前你只负责把东西做出来。现在你开始推动别人把该做的事情做完了。”
林川笑了笑。
上一世,负责人说他缺少影响力。
那时他以为,影响力是多开会、多说话、多表现自己。
现在他才明白:
真正的影响力不是替所有人承担。
而是让问题、责任、成本和选择都回到正确的位置。
八、程序员真正要评估的,不只是开发时间
项目结束后,林川整理了这次项目的记录。
他在最后写下四句话。
第一句:
不明确的需求,不直接承诺排期。
第二句:
排期必须同时包含范围、前置条件和责任人。
第三句:
任何范围变更,都要重新评估时间与资源。
第四句:
没有对应权限,不承担整体结果。
这些话看起来很简单。
但上一世,他用了五年才真正理解。
程序员经常被要求评估一个功能需要多久。
我们会分析代码量、接口数量、数据库结构和技术难度。
但真正决定项目能否按时完成的,往往不是这些。
而是:
需求什么时候冻结
外部依赖什么时候到位
谁负责做业务决策
资源是否真实投入
变更能不能受到控制
风险发生后由谁做取舍
如果这些问题没有答案,再精确的开发评估,也只是一个看起来专业的猜测。
会议室里最危险的一句话,不是:
这个需求很难。
而是:
大家先按这个时间推进,有问题后面再说。
因为“后面再说”的问题,最后通常都会在上线前找到一个具体的人。
上一世,那个人是林川。
这一世,不会再是了。
写在最后
很多程序员不是不会评估工作量。
而是不敢把真实评估说出来。
担心显得不积极。
担心被认为能力不够。
担心领导觉得自己只会讲困难。
于是,我们给出一个建立在完美条件下的时间。
然后再用加班、透支和个人兜底,去填补现实与假设之间的差距。
可真正专业的评估,从来不是报出一个让所有人都满意的日期。
而是让决策者清楚地知道:
要这个时间,需要放弃什么。
要这个范围,需要增加什么。
要同时满足所有目标,需要承担什么风险。
程序员不是项目里的许愿池。
不能每个人投进一个需求,最后就自动出现一个按时上线的系统。
林川的第二次人生还在继续。
下一次,他将回到那次项目总结会。
上一世,核心代码是他写的,线上问题是他解决的。
最后站在台上领取表扬的人,却不是他。
这一世,他不准备抢任何人的功劳。
他只是不会再允许别人,把他的工作从故事里删除。
本篇留一句话
一个没有范围、条件和责任人的排期,不是计划,只是一张等待研发签字的欠条。