1我的源码让猫给吃了
不要寻找借口,从自身找原因
2 软件的熵
一句话:不以善小而不为,勿以恶小而为之.
从初期就要做好规范,不要因为是poc这样的前提而放松对代码的规范,现在的项目就
有这种问题,初期的时候有人认为(自己也有这种想法)等到以后正式开发的时候再规范
,而往往还未到正式开发,到处出现不规范的东西.加上拷贝粘贴的大法,亡羊补牢都晚
了.这就是所谓破窗户理论.
3 石头汤与煮青蛙
两个方面,一还是'软件的熵'当中的含义,喜欢书里面的这段话:'大多数的项目的拖
延都是一天一天发生的,系统一个特性一个特性的偏离其规范.一个又一个的补丁被打
到某段代码上,直到最初的代码一点没有留下'. 二是团队的协同合作,这样石头汤也很
鲜美.
4足够好的软件
就是俗话说的一鸟在手胜于二鸟在林.
首先得确保软件可用性,至于亮点,特色,在可用以后才需要考虑.而且还得明确用户需
求(虽然这点始终被强调).大家都知道系统不可能做的完美,但是自己着手开发的时候
总是朝着尽可能完美的方向发展,欺骗自己说,这个功能多么伟大,一定要加上去,那个
功能多么惊天动地,最后反而成为四不像,使项目延期.
在第一次企图做那个todo list的时候,想着把calendar和task两项功能完整的结合,
同时还想着把contact功能也加入,甚至还有ms porject的管理功能,但是一切都太多,
以致于设计了少数几个界面以后就陷入了无止境的功能权衡中,因为太多东西又想完美
.所以第一次最终结果是除了最后那个简陋的复杂的界面,什么东西都没有,当然如今代
码也已经不知道是不是被自己删除,能够留在自己硬盘上并且使用的还是那个简简单单
的GeeTask,功能不多,但是的确对我来说,足够好了,如果还有新的功能,添加就是了,不
用一次就做一个大而全的玩意出来.
也想起在上一个公司参与的第一个项目,房地产的预警系统,先前同事通过研究,不知
道从哪里搞到一些其他人做的预警系统,动用高深的所谓经济学景气循环算法来计算,
艰难的实现这些公式.当然我们自己也不知道这个是不是准.后来我负责去给客户实施,
在客户处,得知了惊人的消息:客户需要的足够好的软件其实就是一个新闻发布功能的
东西,因为他们也不懂,是领导的要求---领导当然也是被上层领导要求.这个例子虽然
特殊,但是也说明了一定要及早知道客户心中的足够好的软件是什么.
5 你的知识资产
关于学习的一个章节,提到了不少如何学习,把学习知识作为投资一样看待,分析的也
很在理.自认为在这方面还是赶上了书中的要求,不然也不会看到这本书了^_^,学习是
一个过程,不会有立杆见影的效果,当然我们不是政客,不需要立马可见的政绩,那么种
种树又何妨呢?学习也要有实践,把学到的知识找机会就应用起来,起码,自己没用到,也
可以看看别人怎么用嘛.学的多了自然有了自己的判断,前两天不小心点开了jdk源码当
中关于Arrays.sort方法的实现.看到内部的合并排序法却不如《算法导论》中描述的
那么简洁,那么具有可读性,这时候,有了判断了,就不至于傻乎乎的研究它的写法,当然
,jdk里面的mergesort又有一些额外的处理(小数组优化),这个又是可以学习的地方.对
了,这一小节里面还有一段关于如何获得答案的方法,和国内论坛风靡一时的《提问的
智慧》一文有多处相似之处,不知道作者是否参考了本书.
6 交流
这个不用说就知道重要了.离开上一家公司最后一个项目就是最好的例子,一开始其
他同事从客户处带回来老系统的截图以及一些需求的说明,然后我们就要按照这些支离
破碎的东西进行开发.我们不是先知,不是某些领导人,可以自由的发挥,于是绞尽脑汁,
开始努力向可以吻合的方向发展,这种日子很不好受,直到我可以与客户联系上以后,直
接的面对面的确认客户的需求(又是需求) 才让项目的进展在几天里面比前面一个月都
要好的多.
7 重复的危害
有时候是copy paste大法带来的后果,有时候是为了省事,总之,一份功能相同的代码在多处出现,更要命的是,需要修改这部分代码!这个可以毫不客气的说就是灾难,所以在设计,在编码初期就要有良好的规划,尽可能避免重复。实际工作中,发行有时候,尽管想要刻意避免,但是还是会出现。其中一个重要原因在于程序员的偷懒,还有是在于模块的可访问性。尤其是两个模块没有任何公用模块的时候,如何避免重复,或者说人工重复才是问题的关键,即使是build脚本去让两个模块出现相同的东西,也比人为维护两个东西都要好上千万倍。
8 正交性
模块耦合,代码耦合,分层分模块,善用设计模式。正交的目标只有一个,让系统富有弹性,可以随需应变。
9 可撤销性
还是系统的可变性,是否可以快速应付其中一些改变而快速改变。通常我们用面向接口的方式来做到这些。在前人的基础上,我们有corba ,com,ejb,webservice,odbc,jdbc等等让我们快速应变的基石,但是总有一些依赖我们自己的东西,接口,接口!
10 曳光弹
很炫的名字,可惜就是在讲poc,Prove of Concept ,的确很有用。
11 原型与便笺
原型,没别的,常用的东西。
12 领域语言
不同语言有不同的优势,关键在于扬长避短,合理运用,有时候组合起来事半功倍。
13 估算
开始前做好计划,过程中最终计划,磨刀不误砍柴工。
14 纯文本的威力
很多时候纯文本的简单让事情更容易。
15 Shell游戏
程序员必须掌握命令行,即使在windows下面。
16 强力编辑
知道vi好,但是只会那么几个简单的命令,而且,通常我总是在windows下面工作,所以通常用crack的UltraEdit。不少实用的功能,加速编辑。倒是IDE的快捷键记住了不少,在实际工作中,发挥了很大的作用。
书上提到仍有不少人使用windows notepad写代码,我虽然不至于此,但倒是习惯使用它来写文章,记录东西,然而就在刚才,发现手工输入的东西都会出现几个黑色的黑框,可见一定要选择足够好的编辑器才行,何况,windows notepad只能撤销一次,而且你也不会知道撤销的到底是你那次的输入。
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的名字,不是吗?其实只是指了一个小事情,在你的代码上面留下你的足迹。这一点,在第一个公司的时候就已经养成了习惯,并且保留到现在。虽然现在没有诸如此类的要求,但是我还会继续这么做下去,因为对于自己,对于队友,都是很重要的好习惯,当别人发现有问题时,可以马上过来问我:嘿,为什么会有这个问题。他可以节约自己的时间,我也可以有机会再一次增加自己的经验(参见我之前的感受)。而且留下自己的痕迹,也留下一份责任心,不负责任的人,马上就能被发现。
至此,终于把这本书看完了一遍,当然最后的附录和答案没看。对比自己以往接收的,以及所做的,还比较吻合作者描述的注重实效的程序员,值得欣慰。回忆往事,很多习惯源于第一家公司时候经历的一切。有时候我会想,一个程序员的第一份工作,很可能影响了他未来的道路。
我还是得感谢在我职业道路上给我醒目灯的第一家公司的同事:老麦。作为同事,师兄,领导,朋友,他无私的给我指明了很多的道路,教了我很多的东西。