谈谈对软件工程的理解
从换手射击说起
课上讲个人软件过程(PSP)时,Watts Humphrey 换手射击的故事让我记了很久。他服兵役时射击成绩很差,怎么练都没起色,教官观察后建议他改用左手。一个惯用右手的人突然换手,按常理成绩该一落千丈,可他记下每次据枪、瞄准、击发的数据,对着数字改动作,练几次就接近了优秀射手。
我起初当励志故事听。做完第 3 讲的课堂练习才反应过来,它讲的其实是另一件事:工作方式一旦能被记录、被度量,就成了能被控制、被改进的东西。PSP 说的就是这套东西——个人软件过程,它不规定你怎么写代码,而是让你看清自己的时间、缺陷和节奏花在了哪里。换手不神奇,把每次射击拆开看清楚才神奇。
不写过程,问题不现身
做那个校园记账小程序之前,我觉得 PSP 有点像官僚填表。真做起来才发现,它先回答了我最实际的困惑:一个看起来不大的功能为什么吃掉一下午,事后我完全说不清时间花在哪。
四轮迭代里,有两处教训我印象最深。一是日期,我用探针脚本故意输入 2026-9-1,程序不报错,记录也真的进了库,但按月查询匹配的是 2026-09 开头的日期,这条记录在界面上直接消失。代码每行读起来都“对”,只有把脏数据真的跑一遍才看得见这种静默丢失。崩溃是软件在喊疼,不吭声的才危险。
二是金额。数据表里浮点累加冒出了 0.30000000000000004,我把存储换成整数“分”,以为修完了。后来补单元测试,一条用例红了,才发现解析那一路还在用浮点:float("1.005") 实际是 1.00499999,1.005 元会被舍成 1.00 而不是 1.01。存储改对了,入口没改,账面上什么异常都看不出来。修 bug 的终点不是“程序不报错”,而是“错的那处能被证明不再错”。
写完和写对之间隔着一道关
这两处教训有个共同点:都不是“写不出来”,而是“不知道对不对”。人对自己刚写的东西最缺乏怀疑,日志和测试就是给这道关配的仪表盘。
软件工程里那些看着像做给别人看的规矩,做的其实是这件事。编程回答的是“这段代码能不能跑”,工程回答的是“这个程序在需求变了、时间过了、换个人手里还能不能用”。后者要穿过需求、设计、编码、测试、维护的整条线,编码只是很短的一段。
AI 把哪一环换了
用上 AI 编程助手之后,编码被大量草稿化:几百行代码几秒到手,读起来头头是道,跑起来有模有样。我差点就信了,多留了个心眼写探针逐项实测,抓出五处缺陷,一个都不报错。
课程把这种人机协作概括成六步:意图澄清、上下文准备、分阶段生成、验证与验收、迭代修正、沉淀资产。落到我那个小程序上,每一步都摔过跟头。“金额一律以整数分存储,只在输入和显示两个边界换算”这个决策是我定的,AI 执行得利索,可改完我才发现没改全。后来我把这条规则写进项目说明,它成了下一轮迭代的上下文——沉淀资产,就是把这次摔的跟头变成下次的护栏。
最险的一课来自我自己写的测试脚手架。界面测试里写了这么一行:
except TclError: pytest.skip("没有图形界面")
而 Windows 上反复创建 Tk 解释器失败报的也是 TclError,真故障就这么伪装成了“跳过”,屏幕上一片绿,可这台机器图形界面好好的。绿色假象比红色错误危险,它把“还没验证”悄悄换成了“验证通过”,而我还对着全绿的终端松了口气。
我现在的理解
软件工程是一套可以度量的个人过程。它不保证代码是好的,但让每一轮的成果和代价都看得见。人从代码生产者挪到结果验收者的位置,做的还是意图、决策、验证这几件事,只是每轮要更小、更快、更容易回退。
代码可以交给 AI,判断和怀疑得自己留着。规范、测试和版本控制看起来是做给别人看的,做完练习我才真正服气——第一个被它们救的人,是写代码的我。出错的时候,签字的是我。

浙公网安备 33010602011771号