迟钝的编程

从上周一开始,我接到了一个任务,又是把系统里导出来的数据进行统计,输出结果。我用 Ruby 语言编写了一个简单的程序,来处理 Excel 导出的 CSV 文件。由于时间紧急,我没有仔细构思程序应该怎么设计,直接想到什么写什么,最终写出了程序,完成了任务。

之后的几天,我每天开心的用我的小程序来完成任务。尽管我心里想着为它加上直接解析 Excel 的功能,省得我要手动把文件导出成 CSV 格式。不过尝试了一下 parseexcel 包没有成功之后,我暂时就偃旗息鼓了。然后一直到了这周一,领导找到我,说数据不对,我一看果然差的很多,心里一下子紧张起来。然后手动计算,找问题出在哪里。结果发现原来从三天前,信息中心的人不声不响在系统输出的数据表里加了一列,我的程序当然出错了。于是急忙改正。

之后这周三我因为请假,于是就在周二下班后,把当天的结果给弄了出来。我们公司每天下午 4 点就结帐,停止生成新订单了,我觉得到了下班后来弄这个表应该万无一失(过去是次日得出本日的结果)。岂料到了周三下午,领导找到我说数据又不对。我心想怎么回事儿?结果领导指着一个相差比较大的数据给我看。我一看正好有印象,因为我前一天导出数据后,看到这家分部的数据量特别小,只有不到 20 行——这些数据无论如何不能得到领导算出的 80 多的结果。于是我重新导出数据,悲愤的发现原来下班后 1 小时后数据还没有计算完毕,所以发生了这种错误。

然后领导带着我一起手工算了一下,我在这个过程中发现了,原来系统导出的数据有各种各样的坑,一些不适合的数据也被放了进去。另外,我还发现了另外一种情况,也应该被算入结果之中,结果一开始因为它没有出现过,因此我就忽略了它,导致我得到的结果与正确结果有偏差。

于是,从前天下午下班后,我就一个人留在办公室,思考这个问题。因为我的思路还是一开始的那样,所以陷入了一个死胡同中。一开始我是让程序直接模拟我思考的过程,心里怎么想的就让它怎么运行,结果是它完全模拟了一个人类的处理过程。有了不同的情况之后,程序需要判断各种不同的情况,按照这个思路,最简单的方法是程序在读取完一遍数据文件后,再重新读取一遍,用另一种方法来处理数据,最后把两次结果加起来,才得到最终结果。想到这么麻烦,我就感觉一阵绝望——就算我最终写出了程序,我也不敢确保它能正确执行,要调试起来也很麻烦。

到了昨天,我想预期要多次处理数据,不如把这些数据一股脑儿读到内存里去,开始时我觉得这样是一种折衷方法,后来慢慢的发现,这应该是处理问题的正确方法才对。我用两个哈希表,每个元素对应一个列表,来存储从两个视角来分析数据的结果,然后迭代每一个元素对应的列表,进行简单判断,然后就是加法运算计数了,整个解决问题的思路一下子变得如此清晰!

写完了程序之后,我略微反思了一下,其实程序本身没什么复杂的,只是需要把所有的可能情况考虑清楚了,这是最关键的地方。但说来容易,执行起来可不容易。在正常的软件开发中,TDD 是解决这个问题的良药。可我时间紧急,也没有经历来考虑所有可能发生的情况,这其实就给这次开发带来了弯路。另外一个教义,是不要害怕推倒重来。如果我到后来一直坚持一开始的思路,没有变更思路的话,我想就算我最终完成了程序,写的过程应该也非常难受。有趣的是,这样的一个教条,在《人月神话》中已经被提及了。如果正却的开发方法都无法被实行的话,我想最重要的一点,就是要保持冷静,让头脑放空、清晰,是写出正确代码的不二法门。

当然,Ruby 这样的快速开发语言帮了我很大的忙。我想,如果让我自己手工写哈希表,我一定不会这么快的找到解决问题;哪怕是 Java 这样的语言,有自己的数据结构库,使用起迭代来那繁琐的步骤,也很容易把我给绕迷糊了。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据