在IT行业干了整整25年,冒名顶替综合征还在。写一篇叫“资深开发者建议”的文章,我甚至有点犹豫——总有什么东西我不懂,总有什么技术我没用过,总有人比我更懂某个话题。
但25年之后,我觉得可以分享一些想法了。这些是关于怎么工作、怎么造软件、怎么在这个行业待下去的看法。有用的拿走,存疑的质疑,然后按你面前的团队和情况去调整。
需求不清楚,先问,别急着写代码
“活跃客户”到底指什么?谁能批准这个操作?外部服务不可用时应该发生什么?这些问题听起来很基础,尤其当会议室里其他人好像什么都懂的时候。
我宁愿承认自己没搞懂一条业务规则,也不愿围绕自己的理解去造一整个功能。面对一段不熟悉的代码也一样:请人带你过一遍,然后用自己的话复述出来。
现在有了AI,这一步更容易了,但问同事仍然更容易理解一些AI不知道的东西——比如某个业务选择背后的原因。经验应该让人更容易说出“我还不知道”。这一点我到现在还得提醒自己。
开发者需要时间开发
如果主开发还要追每一个依赖、谈范围、向干系人汇报、组织发布,那这些工作就得算进计划里。
在更大的项目上,我会希望有人明确负责协调。这个人可能是项目经理、交付负责人,或者适合该组织的其他角色。小团队里可以是共同责任,但决策仍然需要有主。
工单里写个日期,解决不了一个被阻塞的依赖。得有人去跟另一个团队谈,商定下一步怎么办,并在答案变化时调整计划。
估算一个功能时,要把这些工作算进去。一周排满会议,留给实现的时间就是比一周决策清晰、时间不被打断要少。说实话,我们到现在还在犯“会议过多”这个错,但我希望迟早会变。
不是每个团队都需要同样的会议安排
功能成型期间,跟懂业务流程的人聊几句可能很有用。展示一个能跑的界面,也许能在你再花一周造它之前,就暴露出审批流是错的。
而一个每个人轮流念板上已经能看到的工单的每日站会,就更难说得上有什么必要。
对我来说,有用的会议能解决一个问题、暴露一个依赖,或者产出一个决策。如果一条更新可以写下来、等大家有空时再看,那就试试写下来。如果分歧需要谈,那就谈。
把结果记录在工作所在的地方。一个在电话里做出的决定,如果负责实现的开发者当时不在场,很容易被漏掉。
可读的代码,在有人顶着压力修它时最重要
比起要翻三个文件才能看懂的抽象,我更喜欢命名清晰、流程明显的方法。抽象有它充分的理由,但在加一层之前,我想知道它解决的是哪个问题。
对共享代码也要同样谨慎。两个看起来相似的方法,可能代表的是会各自独立演进的业务规则。把它们放进一个公共库,就制造了一段你得去维护的关系。
等共享行为被理解清楚了,再抽取代码。如果多个应用依赖它,就要考虑兼容性、归属,以及更新怎么到达它们。发布一个包,意味着在原项目之外多了一份责任。
这条建议在我们大量用AI写代码的今天依然成立。不管怎样,写出来的东西都得审一遍,看我们到底能不能读懂、能不能理解。
代码能展示发生了什么,却解释不了为什么必须这样
一条说明“这个文件格式是外部系统要求的”注释是有用的。一条说“下一行给计数器加一”的注释,通常没什么价值。
我想要的是能帮人干活的文档:怎么跑应用、需要哪些配置、怎么执行测试、部署失败时该查什么。把这些说明放在仓库附近,工作流变了就更新。
简短的决策记录也有价值。如果团队否决了队列方案,因为当前工作量不足以支撑运维一个队列,那就把理由记下来,以及什么条件下会重新考虑。
AI可以帮忙起草这些说明。但在把它们当成文档之前,要对照代码和实际环境核对一遍。一份看起来合理却根本没法照着做的安装指南,是留给下一个开发者的又一个麻烦。
一个功能,光在本地跑通还不够
上线之前,我想知道我们怎么识别故障、能对故障做什么。一条有用的日志应该给出足够的上下文来追踪一次操作,同时不暴露凭据或客户数据。一个没有上下文的异常,会让你在好几个不相关的请求里翻找。
测试也要有意识地去设计。如果一个功能在客户之间搬数据,就测那条边界。如果它会发通知,就考虑操作被重复执行时会发生什么。失败场景应该影响测试,而不是在顺利路径通过之后才想起来补。
还要讨论恢复方案。回滚代码,并不能撤销那段代码造成的每一个后果。一次数据库变更,或者一封已经发出去的邮件,都需要单独考虑。
这些问题属于开发阶段,趁你还能改设计的时候,而不是等一场事故逼着你做决定。
有人质疑你的实现,可能会让人不舒服。冒名顶替综合征本来就在场,一条评审意见很容易让人觉得……
热门跟贴