“千里之堤,毁于蚁穴”,很多软件问题并不是由重大的缺陷引起的,反而是一些很细小的问题造成的。下面罗列近期软件开发过程中,我遇到的几个程序编写的细节问题案例。
案例一:
某软件版本要实现从本地配置的目录中扫描出文件并进行处理的功能,只有满足特定前缀的文件才能被扫描出来。文件的前缀在配置文件中进行手动配置。在测试的过程中,我们发现在目录中有很多满足配置前缀的文件,但一个都没有被扫描出来。
问题到底出在哪里呢?为了查找问题原因,我们在代码中添加了很多的调试日志,最后发现读入的前缀配置值后面多了一个“*”。我们又查看了配置文件,发现在手动添加配置值的时候,在前缀的后面加了一个“*”,当作通配符使用。但程序并不需要加通配符,只要将前缀写上就可以了。
假设配置项Prefix表示前缀,那么修改之前的示例如下:
Prefix=prefix*
修改之后的示例如下:
Prefix=prefix
一个小小的“*”,就使得整个程序的功能异常,能说细节不重要吗?
案例二:
某软件版本要从配置文件中读取路径值来拼装文件的存放位置。在测试的过程中,程序出现异常,打印出的日志显示文件路径不存在。我们查看了本地的磁盘,该路径是存在的。那为什么程序找不到这个路径呢?
程序中的路径来源于两个部分,一部分是配置文件中某个配置项(假设为FilePath)的值,另一部分是程序自身生成的。为了查找问题原因,我们同样在代码中添加了详细的调试日志,发现最后拼装出的路径多了一条斜杠,形如“D:\zhou\mail\\wang”。
查看相关代码和配置项,原来在配置项的后面已经添加了一条斜杠,而在程序最后拼装路径的时候,又在中间添加了一条斜杠。即在“D:\zhou\mail\”和“wang”之间添加了“\”。如此处理,程序能够找到这个“奇怪”的路径才怪了!
案例三:
在查看某软件版本生成的日志的过程中,发现有一条日志打印出的变量值非常的奇怪。查找该条日志对应的代码,形式如下:
WriteLog(Log_Info, "Name=%d, Age=%d", Name, Age);
该条日志要打印出变量Name和Age的值,但在定义变量的时候,Name是字符型数组,而Age是整型。但代码“Name=%d, Age=%d”所示,两个变量都以整型(%d)的形式来打印,能够正常吗?正确的形式是“Name=%s, Age=%d”。
这个问题基本不会影响程序的正常流程,因为它是出现在日志当中的。但我们也不能置之不理,细节问题不处理好,积累起来就会出现大的问题。
案例四:
在运行某软件版本数据库脚本(sql文件)的时候,老是报语法错误。查看对应的SQL语句,发现在初始化某一字符型变量的时候,使用了如下语句:
select @namestr = "Zhou"
大家也许注意到了,在SQL语法中,字符串是用单引号来标志的,而不是双引号。这个语法是与C语言有区别的。但很多开发人员熟悉了C语言的那一套语法规则,于是在数据库脚本中,也用双引号在初始化字符型变量。
正确的SQL语句如下:
select @namestr = 'Zhou'
以上四个案例,相信可能很多人都遇到过。那么,我们如何避免以上细节问题的出现呢?
第一,在编写程序的时候,我们一定要全神贯注。我看很多人喜欢把手机放在手边,时不时地低头看一下,也不知道每天为什么总有那么多消息。这样做会导致精力的分散,写出来的程序自然不会让人很放心,出现bug也是很正常的了。
第二,在写完程序之后,我们一定要多检查几遍,不要认为功能正常就没问题了。大家不要嫌麻烦,尽量把每一行代码都看一下,以发现一些容易被忽略的问题。“小心驶得万年船”,只有我们认真对待每一行程序,程序才会“对得起”我们。
第三,在写好程序之后,不要急着提交,让同事对代码进行走查。代码走查也是同行评审的一种,其目的是提高代码的质量。一个人的视野有限,很多问题都发现不了。也许你没有发现的问题,同事一眼就看到了。软件的质量是要靠大家共同努力来提高的。
细节决定成败,这个道理在软件开发中也是成立的。只有不断地实践、不断地总结,我们才能够提高代码的质量,让细节问题无处藏身。
(本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)