西西河

主题:【原创】乱侃软件工程师的素养 1 -- poorfat

共:💬71 🌺108
全看树展主题 · 分页首页 上页
/ 5
下页 末页
家园 【原创】乱侃软件工程师的素养 1

前言

软件工程师的素养这个问题太大了,鄙人只能就我工作中的所见所闻谈一些感想。这个系列没有什么逻辑次序,想到哪儿写到哪儿,所以就叫“乱侃".

首先谈谈我比较痛恨的某些不良编程习惯。

鄙人作为一个测试工程师,经常需要检测程序员们写的代码。有一次一个程序返回了一个错误,于是我用我的IDE打开那个程序看看这个错误大概会是从哪个地方出现的。于是我就看到了这样一段代码:(以下用伪码表示)

if ( !function_one(...) || !function_two(...) || !function_three(...) )

{

return OMG_WE_FAILED;

}

看到这里我心里已经把这位程序员骂了几遍了。你把三个不同的函数调用都写在一个IF语句里,你叫我怎么知道哪个出错了呢?把这三个函数调用分别写到三个IF语句里难道你会死啊?

有人也许会说,连上调试机debugger一看不就知道了? 不错。 但是你要记住,这个程序将来是要拿去给客户运行的,而客户不一定懂如何调试。 客户只会给你打电话抱怨说你的产品又坏了。假设你的运气好,客户发现错误代码是“OMG_WE_FAILED”,那么你更大的麻烦就来了:究竟是三个函数里的那一个返回了这个错误呢?想去吧,抓破脑皮也想不出的。

如果你把三个函数调用分别放在三个IF语句里,并且分别用不同的错误代码,那么你至少可以知道哪一个函数出错了。而且这也并不增加很多工作量,但却可以减少将来查错的工作量,何乐而不为呢?

所以说,作为一个好的软件工程师,写程序的时候要时刻记得将来这个程序如何检测。程序的可测性(testability)也是很重要的。

作为软件工程师,我们大多数时间不需要写高级深奥的算法。 但是像这样简单的程序也不是随便写写就好了的。如果这也写不好,干脆别吃这碗饭了。

元宝推荐:铁手,
家园 花一个,明显这兄弟没做过单元测试,呵呵。

单元测试要天天讲,呵呵。

家园 【原创】素养 2 - 留下痕迹

另一个和程序可测性相关的问题是,无论你的程序怎么写,一定要记住要想尽办法留下痕迹(trace) ,以便将来可以方便地排查错误。

请看这样一段程序:(以下用伪码表示)

function_one( ... );

function_two( ... );

function_three( ... );

够了,我又要骂人了。这个比上面的例子更糟糕。你连着调用三个函数,却没有作任何检查。 你根本不可能知道会发生什么事情,就连出错了你都不知道。

如果你的程序是一个大项目的一部分,而且已经有了一个标准的日志函数(logging function), 那么你最好不仅要加查错语句,还要加日志语句。

比如像这样:

log("calling function_one ...");

if ( !function_one(...) )

{

log("calling function_one failed.");

return OMG_WE_FAILED_AT_ONE;

}

另两个以此类推。

如果你的项目里已经定义过异常类,那更好了。你可以用try-catch语句, 像这样:

try

{

function_one( ... );

function_two( ... );

function_three( ... );

}

catch (e)

{

log("an exception is caught. "+ e.message);

}

总之,你要想尽一切办法留下痕迹。将来你排查错误的时候,你会明白这些都是值得做的。

家园 不错,有点Code Complete的味道

请继续!

家园 双花双宝

恭喜:你意外获得【西西河通宝】一枚

谢谢:作者意外获得【西西河通宝】一枚

鲜花已经成功送出。

此次送花为【有效送花赞扬,涨乐善、声望】

[返回] [关闭]

家园 C语言这东西是把双刃剑,

对初学者不见得合适。

很怀念那个PASCAL,说句玩笑话,最初的英语写作就是在《数据结构》这门课上练的。

家园 声明几句

Code Complete 这本书我看过一遍,很粗略的通读了一下,没有细看,不过其基本观点我是完全同意的。

我在这里举的所有例子,都是我在实际工作中遇到的。有些例子看似很简单,也许你认为不会有人写这么傻的程序,但是我确确实实遇到了。这些也许是程序员无意之中犯的错误,但经常对产品会是致命的。所以我们不妨经常检查我们的程序。

家园 PASCAL确实很优雅,编程序就象在写文章
家园 胖兄莫要误会

您写的真是不错的。

不过,您工作的地方算是对开发人员很宽容的了,还有宽裕时间让人做Code Review。小弟我入行超过十年,只见过一家公司这么做。

家园 有点像英语写作时的维多利亚时代的老古董

优雅,缓慢,表现力丰富而细腻,还带着对已经过去的好时光的眷恋,以及一股扑鼻而来的霉味儿。

家园 我也跟个最近遇到的错误

DateTime yesterday = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day - 1);

这个错误躲过了两个测试的围剿,终于在某月1日爆发了。

家园 哈哈,熊仔曾弄过一个藏了半年的bug

1-9月份都没问题,10-12月份就挂了。哈哈

家园 驴兄真是一针见血啊,呵呵。
家园 【原创】素养 (3) 永远不要许诺你完不成的任务

很多人说过这个问题了,但我还是要再次强调这一点。因为还经常能看到有人犯类似的错误。 切记,永远不要许诺你完不成的任务。

说一件真事儿。大学的时候我们学软件工程课。全班分成几个组,合作完成几个编程的项目。一个小组大约5到6个人,每个人负责写一个项目的一个模块,然后整合在一起作总体测试。 我的小组里有一位公认的编程高手,我们决定把一块主要模块分给他做。每星期小组开会交流各自的进度。每次他都说没问题。其实他其他课程很忙,没有足够的时间可以花在这个模块上。学期临近结束的时候,其他小组成员都完成了各自分配的模块,就他还一点没动。 我们问他有什么困难,我们其他组员可以抽时间帮他。他拒绝了,说保证按时完成任务。 然后就是期末考试,大家忙得一塌糊涂,没人过问这事儿。等到项目要上交的前一天晚上,他赶到机房,写了一通宵的程序,终于把他的模块做完。 然后我们几个做总体调试,发现一大堆错误。改了几个主要的错误,后来小的错误就没改。 卡在预定时间匆匆上交了。

毕业以后,我没再和他联系。想必他一定在某个IT公司高就。祝愿他不会再犯同样的错误。

几年来我一直想这件事情对我们教训是什么。我认为,教训就是: 永远不要许诺你完不成的任务。

然后还有一个推论: 如果你发现你完不成任务了,要尽早通知其他相关人员,并且立刻寻求帮助。死撑是没有用的。再强的程序高手也有玩不转的时候。

家园 【原创】素养 (4) 不要假设人人都能看懂你写的文档

这个系列基本上写的都是我在工作中遇到的另我痛恨的事情。所以免不了我要骂人。这个贴继续开骂。

我曾经接手过一个测试文档,其中有一条测试案例是这样写的:(大意)

“ 请确认某某功能是好的。(verify function XYZ works.)”

诸位,如果你被分派去执行这条测试案例,你会不会骂人?我是涵养很好的人,所以我只是默默地在心里把文档作者骂了几遍。然后我虚心地向作者请教以下几个问题:

1 - 到底什么叫做“是好的”? 你到底要我达到什么测试目的?

2 - 我应该执行什么步骤来测试该功能?

3 - 什么情况下我可以认定该项测试成功了?

4 - 什么情况下我可以认定该项测试失败了?(由于众所周知的原因,你最好保证3 和4是互斥的, 否则我还要继续踢你屁股)

5 - 如果测试失败了,我应该向谁举报?由谁负责订正错误?

以上都是一些最最基本的测试问题。这些问题不搞清楚,没有人可以执行测试的。写这个测试案例的人一定已经有丰富的执行该测试的经验了。所以他一看这些字眼就知道该怎么做。 可是其他人不一定是这方面的专家。 所以你如果想要其他同事能够顺利执行你写的测试案例,你最好花点功夫,把你的文档写清楚。不要假设人人都能看懂你写的文档。

一个完整的测试案例,不仅要有以上提到的几条,还至少要有以下几点:

- 执行该项测试的人员需要哪些预备知识?背景知识?

- 前期准备工作有哪些?

- 测试环境是什么?如何认定测试环境是有效的?如果测试环境不正确,那么你得到的测试结果就是无效的,无论是成功了,还是失败了。

- 需要哪些硬件电脑?

- 需要哪些软件工具?

总之写文档的时候,一定要把问题的来龙去脉都搞清楚了,别人才有可能看得懂。 记住,文档是要让别人看懂的, 不是用来卖弄你的水平的。

全看树展主题 · 分页首页 上页
/ 5
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河