程序员修炼之道(转帖)

1我的源码让猫给吃了

不要寻找借口,从自身找原因

2软件的熵

一句话:不以善小而不为,勿以恶小而为之.

从初期就要做好规范,不要因为是poc这样的前提而放松对代码的规范,现在的项目就

有这种问题,初期的时候有人认为(自己也有这种想法)等到以后正式开发的时候再规范

,而往往还未到正式开发,到处出现不规范的东西.加上拷贝粘贴的大法,亡羊补牢都晚

了.这就是所谓破窗户理论.

3石头汤与煮青蛙

两个方面,一还是'软件的熵'当中的含义,喜欢书里面的这段话:'大多数的项目的拖

延都是一天一天发生的,系统一个特性一个特性的偏离其规范.一个又一个的补丁被打

到某段代码上,直到最初的代码一点没有留下'.二是团队的协同合作,这样石头汤也很

鲜美.

4足够好的软件

就是俗话说的一鸟在手胜于二鸟在林.

首先得确保软件可用性,至于亮点,特色,在可用以后才需要考虑.而且还得明确用户需

求(虽然这点始终被强调).大家都知道系统不可能做的完美,但是自己着手开发的时候

总是朝着尽可能完美的方向发展,欺骗自己说,这个功能多么伟大,一定要加上去,那个

功能多么惊天动地,最后反而成为四不像,使项目延期.

在第一次企图做那个todolist的时候,想着把calendar和task两项功能完整的结合,

同时还想着把contact功能也加入,甚至还有msporject的管理功能,但是一切都太多,

以致于设计了少数几个界面以后就陷入了无止境的功能权衡中,因为太多东西又想完美

.所以第一次最终结果是除了最后那个简陋的复杂的界面,什么东西都没有,当然如今代

码也已经不知道是不是被自己删除,能够留在自己硬盘上并且使用的还是那个简简单单

的GeeTask,功能不多,但是的确对我来说,足够好了,如果还有新的功能,添加就是了,不

用一次就做一个大而全的玩意出来.

也想起在上一个公司参与的第一个项目,房地产的预警系统,先前同事通过研究,不知

道从哪里搞到一些其他人做的预警系统,动用高深的所谓经济学景气循环算法来计算,

艰难的实现这些公式.当然我们自己也不知道这个是不是准.后来我负责去给客户实施,

在客户处,得知了惊人的消息:客户需要的足够好的软件其实就是一个新闻发布功能的

东西,因为他们也不懂,是领导的要求---领导当然也是被上层领导要求.这个例子虽然

特殊,但是也说明了一定要及早知道客户心中的足够好的软件是什么.

5你的知识资产

关于学习的一个章节,提到了不少如何学习,把学习知识作为投资一样看待,分析的也

很在理.自认为在这方面还是赶上了书中的要求,不然也不会看到这本书了^_^,学习是

一个过程,不会有立杆见影的效果,当然我们不是政客,不需要立马可见的政绩,那么种

种树又何妨呢?学习也要有实践,把学到的知识找机会就应用起来,起码,自己没用到,也

可以看看别人怎么用嘛.学的多了自然有了自己的判断,前两天不小心点开了jdk源码当

中关于Arrays.sort方法的实现.看到内部的合并排序法却不如《算法导论》中描述的

那么简洁,那么具有可读性,这时候,有了判断了,就不至于傻乎乎的研究它的写法,当然

,jdk里面的mergesort又有一些额外的处理(小数组优化),这个又是可以学习的地方.对

了,这一小节里面还有一段关于如何获得答案的方法,和国内论坛风靡一时的《提问的

智慧》一文有多处相似之处,不知道作者是否参考了本书.

6交流

这个不用说就知道重要了.离开上一家公司最后一个项目就是最好的例子,一开始其

他同事从客户处带回来老系统的截图以及一些需求的说明,然后我们就要按照这些支离

破碎的东西进行开发.我们不是先知,不是某些领导人,可以自由的发挥,于是绞尽脑汁,

开始努力向可以吻合的方向发展,这种日子很不好受,直到我可以与客户联系上以后,直

接的面对面的确认客户的需求(又是需求)才让项目的进展在几天里面比前面一个月都

要好的多.

7重复的危害

有时候是copypaste大法带来的后果,有时候是为了省事,总之,一份功能相同的代码在多处出现,更要命的是,需要修改这部分代码!这个可以毫不客气的说就是灾难,所以在设计,在编码初期就要有良好的规划,尽可能避免重复。实际工作中,发行有时候,尽管想要刻意避免,但是还是会出现。其中一个重要原因在于程序员的偷懒,还有是在于模块的可访问性。尤其是两个模块没有任何公用模块的时候,如何避免重复,或者说人工重复才是问题的关键,即使是build脚本去让两个模块出现相同的东西,也比人为维护两个东西都要好上千万倍。

8正交性

模块耦合,代码耦合,分层分模块,善用设计模式。正交的目标只有一个,让系统富有弹性,可以随需应变。

9可撤销性

还是系统的可变性,是否可以快速应付其中一些改变而快速改变。通常我们用面向接口的方式来做到这些。在前人的基础上,我们有corba,com,ejb,webservice,odbc,jdbc等等让我们快速应变的基石,但是总有一些依赖我们自己的东西,接口,接口!

10曳光弹

很炫的名字,可惜就是在讲poc,ProveofConcept,的确很有用。

11原型与便笺

原型,没别的,常用的东西。

12领域语言

不同语言有不同的优势,关键在于扬长避短,合理运用,有时候组合起来事半功倍。

13估算

开始前做好计划,过程中最终计划,磨刀不误砍柴工。

14纯文本的威力

很多时候纯文本的简单让事情更容易。

15Shell游戏

程序员必须掌握命令行,即使在windows下面。

16强力编辑

知道vi好,但是只会那么几个简单的命令,而且,通常我总是在windows下面工作,所以通常用crack的UltraEdit。不少实用的功能,加速编辑。倒是IDE的快捷键记住了不少,在实际工作中,发挥了很大的作用。

书上提到仍有不少人使用windowsnotepad写代码,我虽然不至于此,但倒是习惯使用它来写文章,记录东西,然而就在刚才,发现手工输入的东西都会出现几个黑色的黑框,可见一定要选择足够好的编辑器才行,何况,windowsnotepad只能撤销一次,而且你也不会知道撤销的到底是你那次的输入。

17源码控制

凡是工作过的程序员,没有不用源码控制工具的吧?只是选择有所不同。

18调试

读书的时候学习编程,觉得和其他人最不一样的地方在于两点,一是自己思考程序的流程,写下代码之前,知道代码将要(预期)执行的顺序逻辑,二是会调试代码,出现错误时不像一般人完全不知道该如何是好,而是去调试来寻找出错的原因。我相信,现在还是有不少工作了的程序员,不习惯去调试,他们期待的是自己的代码都是一次编写就能正确无误的执行,如果不行,那么别人大概可以帮忙解决。

一直以来,一直觉得,一个程序员的经验丰富情况很大程度依赖于他遇到的bug并解决的数量,所以一个人代码写的越多,解决的问题越多,那么他下次遇到问题时就越容易很快的定位。所以,有时候遇到问题并且成功的选择另外一个方案绕过去以后,不妨回头再看看原来到底为什么不行,毕竟下次也许你又要遇到,而且,更重要的是,可能到时候不能选择其他的方案。

19文本操纵

这一节没理解它真正的含义,表面看来是讲可以使用程序来读取操作文本的信息,来加快工作效率,但是到底指什么呢?不明白。不过倒是在工作上,多次嫌手工执行一些转换数据库工作麻烦,而写一些简短的工具来做批处理,效果也很不错。

20代码生成器

经常用,很好用。

21按合约设计

以前也看过类似的文章,当时还把它贴到公司的wiki上面,并且自从那以后一直坚持契约的方式编程。长久一来,我一直认为这是行之有效的方式,每个人把注意力放到自己的代码中,对他人的代码只作检查,不做包容,如果,对方的屁股没擦干净,一脚踹出去比请进来帮他擦更让人能够觉得舒畅,而且,也能防止有些家伙习惯性的先把屁股伸进来。

至于断言,以前学习VC6的时候因为其对程序的终止而不那么喜欢,而并非每次都写JUnit也让自己并非常用。

22死程序不说谎

代码总是忠实的执行程序员的指令。一切程序员的错误最终将反映到代码上面来,在代码中随时做好踹别人屁股,甚至踹自己屁股的准备,因为崩溃比继续错误的运行更有好处。

23断言式编程

就是断言,同21节中的内容。

24何时使用异常

因为在用java所以一直在和异常打交道,系统的,别人写的或者是自己写的。异常的处理可以说是所有java应用中最普遍的东西。配合上面3节,合理使用,让异常发挥最大的效用。

25怎样配平资源

记住并切实的执行一个原则:打开的资源一定要关闭,这个资源可以是文件,内存,io或者其他。虽然有些语言比如java有GC来管理内存,但是却管理不了文件,c的野指针问题,也都是因为只顾申请却不记得释放导致。还是前面的老话,屁股要自己擦干净,擦不干净当然会把裤子弄脏,脏了裤子是小,臭味熏了别人是大。

26解耦与得墨忒耳法则

没明白得墨忒耳法则的具体确切内容,不过减少耦合总是不错的。

27元程序设计

很多东西都应该以配置文件的形式来处理,这样的好处显而易见:修改这部分内容无需重新编译代码。而今,我又有一些新的体会:配置可能会带来配置满天飞的灾难,所以一定要清晰易懂的配置。

28时间耦合

工作流的东西,到现在还没有去瞅过,管他呢,用的到时再说吧。

29它只是视图

mvc常用的不行的东西,发布/订阅,这个也是在设计、编码过程中自然而然想要使用的玩意。

30黑板

是指多系统共用数据吗?看着有点像,不确定。

31靠巧合编程

编写代码的方式是知道要做什么,然后写代码。所以要清楚的知道自己的代码每一步都做了些什么。对于很多程序来说,通常情况下,它是正确的,而某些情况下它却不正常了,那么这就可以归属于靠巧合编程。程序的错误,很多时候在于对边界条件的判断。

32算法速率

就目前来说,项目已经很少需要精确到一个具体算法的速度,但是在比较广义的范围内,减少不必要的计算,提高整体运算速度,还是会是系统看起来更好。本节提到的算法复杂度,在很多书中都被提及,但是我从一开始就忽略了这部分的学习,所以,通常情况下,总是不知道一个算法的具体复杂的(总是忘记某些重要的结论,比如递归算法的复杂度计算公式),所以这个一定要补上来。

33重构

没什么好说的。

34易于测试的代码

测试,保障代码质量,没什么好说的。

35邪恶的向导

为了节约时间,出现了各种向导工具,同时也让不明就里的人失去了了解细节的机会,因而,懒惰的人更不会去理会向导做了什么事情,这就是邪恶的原因所在。

36需求之坑

终于到了需求的部分,可是有没什么好说的了。

37解开不可能解开的迷题

有时候问题的解决需要跳出常规的思维。或者简单一点,用另外一种方法,而不是钻牛角尖。

38等你准备好

不打无准备的仗。没什么好说的。

39规范陷阱

不要等万事具备才开始,因为不可能万事具备,用户总是在变。

40圆圈与箭头

工具是拿来帮助加快开发,而不是束缚开发的。各种各样眼花缭乱的UML,其实只是为了能够清晰描述设计者的思想。当我还是高中生的时候,老师在课堂上面讲述着流程图这种工具,当时甚至5、6年以后我都没听说过uml,但是觉得流程图就是那么的实用。如今,已经很少见到有谁在使用流程图来描述。也许和设计的关注点不同有关,但是当自己在使用uml进行设计时,却又十分的想使用流程图,可惜,像rose之类的工具都没有,也不知道uml是否定义。viso倒貌似有,可是还没用过。前不久找了一个开源的digramdesinger的工具,在这方面倒做的不错。

41注重实效的团队

项目开发就脱不开团队,个人的项目除了兴趣爱好,还没听说过。团队重要性不言而喻,以往的经历告诉我一个合理的团队让人觉得有归属感,反之,就容易萌生去意。一起喝着可乐,听着破喇叭放出的音乐,并且加着班的团队在多年以后的记忆里面显得那么的美。

42无处不在的自动化

程序的目的之一就是让原本繁琐复杂的重复劳动自动化的处理,而软件开发过程中也一样需要自动化。我一直坚信别人说过的一句话:凡是有人参与的过程,肯定会产生错误。所以,我也一直坚持能让机器去做的事情就交给机器,以减少人的参与,减少错误的发生几率。在过去,我尝试了多次为某些任务编写简单的程序来自动化处理,虽然,我的计划上,没有写一个程序这样的描述,但是,写程序自动处理更好,更有效,最重要的是,还能再次重复预设的动作。此外其他的自动化工具也是很值得推荐,比如自动化测试,代码生成器。

43无情的测试

测试是为了保障代码的质量。所以越是仔细,全面的测试,越是有助于系统的健壮,不负责任的程序员或者测试,总是拿着可以正常运行的数据来进行着测试。有条件还是需要专职的测试,合格的测试,而不是那种连代码都看不懂的刚毕业的小姑娘。

44全都是写

文档和注释。自认为注释方面还过得去,但是有些情况下还是会忽略注释而后期弥补,这一点需要改正。至于文档倒是需要好好努力的,这样能显的更“专业”,能更好的记录代码的情况。

45极大的期望

达到客户的期望,才是软件真正的成功。这一点,其实又涉及到“万恶的”需求。刚刚经历了一段做完的曳光弹被客户枪毙的事情。其实这一切,如果能从一开始就得到客户的期望,就不会如此的糟糕。而事实却是客户的期望,客户的需求却并非可以得到。虽说这不是好的软件工程的典型,但是至少,我们现在知道了什么是客户期望的。

46傲慢与偏激

很cool的名字,不是吗?其实只是指了一个小事情,在你的代码上面留下你的足迹。这一点,在第一个公司的时候就已经养成了习惯,并且保留到现在。虽然现在没有诸如此类的要求,但是我还会继续这么做下去,因为对于自己,对于队友,都是很重要的好习惯,当别人发现有问题时,可以马上过来问我:嘿,为什么会有这个问题。他可以节约自己的时间,我也可以有机会再一次增加自己的经验(参见我之前的感受)。而且留下自己的痕迹,也留下一份责任心,不负责任的人,马上就能被发现。

至此,终于把这本书看完了一遍,当然最后的附录和答案没看。对比自己以往接收的,以及所做的,还比较吻合作者描述的注重实效的程序员,值得欣慰。回忆往事,很多习惯源于第一家公司时候经历的一切。有时候我会想,一个程序员的第一份工作,很可能影响了他未来的道路。

我还是得感谢在我职业道路上给我醒目灯的第一家公司的同事:老麦。作为同事,师兄,领导,朋友,他无私的给我指明了很多的道路,教了我很多的东西。

相关推荐