春天,早晨下车后步行一段路,西侧年轻的学生走入城市,东侧小道下开出新花,老太太上香山,我赶着修bug,现在淡然了,寄身于电子世界的bug和自然万物一样,缘起缘灭,于我相无挂碍。

1. 背景

  • 现象

回放多种设备的历史数据,在高倍速和跳转时有2种数据的时间戳不同步。自从原作者毕业后搁置至今。

  • 目标

5个工作日完成。

2. 过程

2.1. 第1阶段

  • 看代码框架,Dot绘图汇总,打印放手边。耗时8小时。
  • 看代码中跳转逻辑,牵扯到不同数据文件的切换,搭建错误现象的依赖环境和复现。耗时8小时。
  • 精读关键代码,比对现象和代码的联系,发现一些奇奇怪怪、不符直觉的代码和现象,比如设备规格不同,导致文件的长度不同,更易偏差。耗时16小时。
  • 解决一处异常崩溃,加入检测时间戳不同步及对齐功能,标记并清理频繁跳转时的历史数据。耗时16小时。

计划时间内支持主动对齐、提高稳定性,频繁跳转在开发环境中达到可用状态。

2.2. 第2阶段

由于同一个GUI展现了多种数据,测试发现很多新问题,其中一部分是老版本的遗留,但被上述bug遮掩,另一部分是第1阶段的修改促使关联模块出现”排他性“,于是局部摩擦变为世界大战:

  • 更多种设备数据的不同步。
  • 频繁操作后死循环、死锁、崩溃。
  • 停止、播放结尾、中途切换信号文件时状态错误。
  • 不响应API请求。
  • 但凡和某种设备数据有关的功能,一并异常。
  • 单机操作尚可,并发出异常。

后续再投入22个开发工作日,外加数十小时的加班,以及一位优秀小伙伴的持续帮助下,才算告一段落。

3. 感受

每天面对失控的代码,小到无符号和有符号的混用、全局变量漫游、冗余锁、几百行的大函数,大到冗余IO、内存泄露、二分法死循环、状态混乱、高耦合、全局变量被多线程覆盖、线程不安全。

这时候主要矛盾已经从做什么和怎么做,变成如何不受广泛关注后进度会议衍生焦虑的干扰,保持镇定,持续做正确的事,这一点出乎意料地触及开发心理学。

4. 分享

4.1. 不明确维护软件的步骤就无法估算

如果你不熟悉这个急待修复的软件,第一个困难是估算工时,因为一旦延期就是集体负担,甚至恐慌,成为一段不如意的经历,反而阻碍过程。

《开源软件的故障处理》中做过一些讨论,维护既有软件和开源软件一样,最大的障碍是不熟悉以及尚未解决的问题通常有其难处,可以把过程分为7个步骤:

开源软件的故障处理

建议分为2块分别估算,第1部分是完成上图中再现、什么是对、定位、理解意图,对问题有了大致的认识,再去估算后面步骤。可惜往往还会出现明显的误差,因为对于不熟悉的东西,影响范围又大,不动手始终缺少细节的考量,保守点做好2倍工时的准备,并不难堪,因为你竟然有勇气直面真相,如实评估后团队才能做出真实计划、调整资源,掌控后续的战斗序列。此刻切忌好听的,我穿越晚明,许诺二年平辽,最后的损失还是崇祯来兜底,除了缓解一时的紧张情绪,没有什么正向意义。

推广开来,越是不明朗的事务,越要落实方法和步骤。

4.2. 细节是魔鬼:说来容易做来难

PPT开发和口头开发,都是面向人类的语言理解系统,突出容易理解的共识概念,开发软件要在计算机中使用编程语言构建、组装一棵棵细节逻辑树,同时兼顾计算机环境和用户的边界约束,多如牛毛的细节决策实现软件六性,优秀和良好、良好和普通的迥异千差万别。

维护软件意味着你要评估前人代码中逻辑树的意图、完成度和不足,做扩充、裁减、嫁接、重写,还要不影响其他子树,当代码高耦合、难读时,非常考验耐心、手艺和心力。

好比给一辆高速前进的汽车更换刹车片,说起来只有一句话:“在没有踩下刹车的时候更换刹车片”,你觉得做起来有哪些困难?

4.3. 书柜乱了,每次找东西都很慢

你有个大书柜,每次到货随手塞进去,有一天找《三大师谈〈红楼梦〉》花费10分钟,下次找《设计原本》还是10分钟,因为缺少索引。

软件也一样,幸福的代码易于理解、少有低级错误,甚至自身就是文档,不幸的代码就是混乱的书柜,代码中每个分支、循环和赋值语句、异步处理、约束条件,都是逻辑决策,不论什么原因,如果你对这些决策没有形成洞察,每次分析都要无聊地重读。这就是为什么代码可读性、设计文档是维护成本的关隘。

4.4. bug足够多,负负得正

跳转功能没有清理过期数据是一个bug,但却保障各项数据存在某种程度的一致性,当我短暂享受正确清理的喜悦,一杯茶的功夫又发现数据一致性崩塌,与下图神似。

负负得正

4.5. 设计缺席

ToB、ToG有客户关系,ToC有流量经济,无论哪种在长周期里真正胜出的产品都因为设计良好,团队开发往往人多、模块多、相互依赖,所以需要初步的整体设计和开发时的补充设计,来避免考虑不全、不深、沟通折损,缺少深度思考和依赖调试的软件往往只在当前条件下表现良好,当外部或内部变化时失控。

4.6. 复盘

解决完了理应享受胜利的喜悦,但也要警惕好了伤疤忘了痛,为什么会制造这些问题?如何避免?这些是你们团队的底层性格,如果不复盘只是徒增回忆,没有提高,还会再犯。