《程序员修炼之道》书评

当前位置:首页 > 网络编程 > 编程语言与程序设计 > 程序员修炼之道

出版社:电子工业出版社
出版日期:2005-1
ISBN:9787505397194
作者:Andrew Hunt,David Thomas
页数:333页

花了两天读了,写下了一些笔记与感想,贴出来和大家共享一下

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的名字,不是吗?其实只是指了一个小事情,在你的代码上面留下你的足迹。这一点,在第一个公司的时候就已经养成了习惯,并且保留到现在。虽然现在没有诸如此类的要求,但是我还会继续这么做下去,因为对于自己,对于队友,都是很重要的好习惯,当别人发现有问题时,可以马上过来问我:嘿,为什么会有这个问题。他可以节约自己的时间,我也可以有机会再一次增加自己的经验(参见我之前的感受)。而且留下自己的痕迹,也留下一份责任心,不负责任的人,马上就能被发现。至此,终于把这本书看完了一遍,当然最后的附录和答案没看。对比自己以往接收的,以及所做的,还比较吻合作者描述的注重实效的程序员,值得欣慰。回忆往事,很多习惯源于第一家公司时候经历的一切。有时候我会想,一个程序员的第一份工作,很可能影响了他未来的道路。我还是得感谢在我职业道路上给我醒目灯的第一家公司的同事:老麦。作为同事,师兄,领导,朋友,他无私的给我指明了很多的道路,教了我很多的东西。

关键在执行力

一年后重读这本书,发现其中的多个观点确为做好程序员的一些最基本的道理,没有什么高深之处,关键在于你的执行力,你的团队的执行力怎么样。知易行难。当然,还是力荐这本书。-----------------------------------------------------------------------------------------

从中手到高手

难得一本高手写的书,但有些东西已经过时,比如应该测试先行而不是增加测试。让我特有体会的一些:不要容忍破窗户--软件的质量。DRY--不要重复你自己。正交性--无相互依赖性和解耦性。曳光弹--对于技术未知点或者难点用spike去突破。我等会儿回答你--不要急着回答,留时间给自己估算。纯文本的威力--linux哲学。学习一种编辑器--加速你的工作。代码生成器--消除重复的一种方法。DBC--根据合约设计。异常--将异常用于异常的问题(你无法预计和控制是否会出错的地方)。元数据驱动的应用--将抽象放进代码,细节放进元数据。时间耦合--分析工作流,改善并发性。MVC--三者之间的关系。算法--用O()估算算法的阶。倾听反复出现的疑虑--等你准备好再开始。团队组织--围绕功能,而不是工作职务进行组织(敏捷团队其实本质上做到了这一点,一个story由所有人配合完成)。自动化一切应该自动化的东西。测试状态覆盖,而不是代码覆盖--所有情况,包括边界。管理客户期望--不要没有surprise,而要给他们一点点惊喜。

记了好多笔记,希望以后会用到吧。

在所有的弱点中,最大的弱点就是暴露弱点不要容忍破窗户不要留着破窗户(低劣的设计,错误决策,糟糕的代码)不修,发现一个就修一个,如果没有时间修理,就将代码放入注释,显示“未实现”字样。管理知识资产我们喜欢把程序员所知道的关于计算技术和他们所工作的应用领域的全部事实,以及他们的所有经验视为他们的知识资产(knowledge portfolios)定期投资。就像金融投资一样,你必须定期为你的知识资产投资,即使投资量很小,习惯自身也和总量一样重要。多元化。你知道的不同的事情越多,你就越有价值。作为底线,你需要知道你目前所有的特定技术的各种特性。但不要就此止步,计算技术的面貌变化很快,你掌握的技术越多,你就越能更好的进行调整,赶上变化管理风险。从高风险、可能有高回报,到低风险、低回报,技术存在于这样一条谱带上,把你所有的金钱都投入可能突然崩盘的高风险股票并不是一个好主意;你也不应太保守,错过可能的机会。不要把你所有的技术鸡蛋放在一个篮子里。低买高卖。在新兴的技术流行之前学习它可能就和找到被低估的股票一样困难,但所得到的就和那样的股票带来的收益一样。重新评估和平衡。这是一个非常动荡的行业,你上个月开始研究的热门技术现在也许已像石头一样冰冷。也许你需要重温你有一阵子没有使用的数据库技术,又或许,如果你之前试用过另一种语言,你就会更有可能获得那个新职位。。。总之,定期为你的知识资产投资。什么是获得智力资本,从而为你的资产提供资金的最佳方式呢?有一些建议:每年至少学习一种新语言。不同语言以不同方式解决相同的问题。通过学习若干不同的方法,可以帮助你扩宽你的思维,并避免墨守成规。此外,现在学习许多语言已容易了很多。每季度阅读一本技术书籍。讨论与你当前的项目有关的话题。一旦你养成读书习惯,就一个月读一本书。在你掌握了你正在使用的技术之后,扩宽范围,阅读一些与你的项目无关的书籍。也要阅读非技术书籍。记住计算机是由人使用的,不要忘了等式中人这一边。上课。在本地的学院或大学,或是将要来临的下一次会展上寻找有趣的课程。参加本地用户组织。不要只是去听讲,而要主动参与,于是隔绝对你的职业生涯来说可能是致命的;打听一下你们公司以外的人都在做什么。实验不同的环境。如果你在Windows上工作,就在家玩一玩Unix,如果你只用过makefile和编辑器,就试一试IDE。跟上潮流。订阅商务杂志和其他期刊,选择所涵盖的技术与你当前的项目不同的刊物。上网。信息来源。最后,批判的思考你所读到的和听到的。警惕声称他们的信条提供了唯一答案的狂热者。交流知道你想要说什么了解你的听众选择时机选择风格调整你的交流风格,让其适应你的听众。让文档美观让听众参与我们常常发现,与制作文档的过程相比,我们制作出的文档最后并没有那么重要,如果可能,让你的读者参与文档的早期草稿的制作。获取他们的反馈,并汲取他们的智慧,你将建立良好的工作关系,并很可能在此过程中制作更好的文档。做倾听者回复他人你说什么和你怎么说同样重要注重实效的途径不要重复你自己让复用变得容易消除无关失误之间的影响(正交性)不存在最终决策(可变因素很多)灵活的架构曳光弹用曳光弹找到目标,曳光弹优点:用户能够及早看到能工作的东西开发者构架了一个他们能在其中工作的结构你有了一个集成平台你有了可用于演示的东西你将更能够感觉到工作进展曳光弹告诉你击中的是什么,那不一定总是目标,于是你调整准星,知道完全击中目标为止,这正是要点所在。制作架构原型为了学习而制作原型。许多原型被构造出来,是要为在考虑之下的整个系统建模,与曳光弹不同,在原型系统中,单个模块不需要能行驶特定的功能。事实上,要制作架构原型,你甚至不一定需要进行编码,你可以用便签或索引卡片,在白板上制作原型,你寻求的是了解系统怎样结合成为一个整体,并推迟考虑细节,下面是一些你可以在架构原型中寻求解答的具体问题:主要组件的责任是否得到了良好定义?是否适当?主要组件间的协作是否得到良好定义?耦合是否得以最小化?你能否确定重复的潜在来源?借口定义和各项约定是否可接受?每个模块在执行过程中是否能访问到其所需的数据?是否能在需要时进行访问?根据我们制作原型的经验,最后一项往往会产生最让人惊讶和最有价值的结果领域语言语言的界限就是一个人的世界的界限靠近问题领域编程考虑到大多数应用都会超过预期的使用期限,你可能最好咬紧牙关,先就采用更复杂、可读性更好的语言,最初的努力将在降低支持与维护费用方面得到许多倍的回报。估算估算,以避免发生意外。我们发现,为项目确定进度的唯一途径常常是在相同的项目上获取经验。增量开发是步骤:检查需求、分析风险、设计,实现,集成、想用户确认。于是你完成了初始功能的编码与测试。并将此标记为第一轮增量开发的结束,基于这样的经验,你可以提炼你原来对迭代次数,以及在每次迭代中可以包含的内容的猜想,提炼会变得一次比一次好,对进度表的信心也将随之增长。通过代码对进度表进行迭代。基本工具花时间学习使用这些工具,有一天你将会惊奇的发现,你的手指在键盘上移动,操纵文本,却不用进行有意识的思考,工具将变成你的双手的延伸。纯文本的威力我们搜集需求,将其变为知识,随后又在我们的设计,实现,测试、以及文档中表达这些知识,而且我们相信,持久的存储知识的最佳格式是纯文本。Shell的优势每个木匠都需要好用、坚固、可靠的工作台,用以在加工工件时把工件放置在方便的高度上,工作台成为木工房的中心,随着工件的成型,木匠会一次次回到工作台的近旁。对于操纵文本文件的程序员,工作台就是命令shell。在shell提示下,你可以调用你的全套工具,并使用管道,以这些工具原来的开发者从未想过的方式把它们组合在一起。Shell命令可以被组合进脚本文件中,你可以构建命令序列,是你常做的事情自动化。强力编辑我们认为你最好是精通一种编辑器,并将其用于所有的编辑任务。重要的是精通。源码控制可撤销(undo)与重做(redo)的源码控制系统可提高你的效率。把整个项目置于源码控制系统的保护之下具有一项很大的、隐蔽的好处:你可以进行自动的和可重复的产品构建。(rcs)调试要修正问题,而不是发出指责。Bug是你的过错还是别人的过错,并不是真的很有关系。它仍然是你的问题。调试第一准则:不要恐慌一个脑细胞都不要浪费在”但那不可能发生“的思路上。使数据可视化直截了当的”variable name=data value“(看变量的值)坏变量?检查它们的邻居先快速的查看一下这个坏变量周围的内存。但是,如果没有显而易见的地方让你着手查看,你总是可以依靠好用的老式二分查找。看症状是否出现在代码中的两个远端之一,然后看中间,如果问题出现了,则bug位于起点与中点之间;否则,它就在中点与终点之间。以这种方式,你可以让范围越来越小,直到确定问题所在。不要假定,要证明当你遇到让人吃惊的bug时,除了只是修正它以外,你还需要确定先前为什么没有找出这个故障。考虑你是否需要改进单元测试或其他测试,以让它们有能力找出这个故障。还有,如果bug是一些坏数据的结果,这些数据在造成爆发之前传播通过了若干层面,看一看在这些例程中进行更好的参数检查是否能更早的隔离它。如果一个bug花了很长时间修正,你是否可以做点什么,让下一次修改这个bug更容易。学习一种文本操纵语言如Perl。我们几乎每天都使用文本操纵语言,与我们注意到的其他任何语言相比,本书中的许多想法都可以用这些语言更简单地实现,这些语言使我们能够轻松的编写代码生成器。代码生成器编写能编写代码的代码。被动代码生成器减少敲键次数。它们本质上是参数化模板,根据一组输入生成给定的输出形式。被动代码生成器用途:创建新的源文件在编程语言之间进行一次性转换生成查找表及其他在运行时计算很昂贵的资源主动代码生成器只是一种便利手段。通过其你可以取某项只是的一种表示形式,将其转换为你的应用需要的所有形式,这不是重复,因为衍生出的形式可以用过就扔,并且是由代码生成器按需生成的。让输入格式保持简单,代码生成器就会变得简单。你可以用代码生成器生成几乎任何输出:HTML、XML、纯文本(不一定要生成代码)断言式编程如果它不可能发生,用断言确保它不会发生原型:void assert( int expression )assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。#include <stdio.h>#include <assert.h>#include <stdlib.h>int main( void ){FILE *fp;fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件assert( fp ); //所以这里不会出错fclose( fp );fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败assert( fp ); //所以这里出错fclose( fp ); //程序永远都执行不到这里来return 0;}已放弃使用assert()的原因是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含 #include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:#include <stdio.h>#define NDEBUG#include <assert.h>按合约设计按合约规定编写软件。使用DBC的最大好处也许是它迫使需求与保证的问题走到前台来。何时使用异常我们相信,异常很少应作为程序的正常流程的一部分使用;异常应保留给意外事件,假定某个未被抓住的异常会终止你的程序,问问你自己:“如果我移走所有的异常处理器,这些代码是否仍然能运行?”如果答案是“否”,那么异常也许就正在被用在非异常的情形中。错误处理器是另外一种选择错误处理器是检测到错误时调用的例程,你可以登记一个例程处理特定范畴的错误,处理器会在其中一种错误发生时被调用。怎样配平资源要有始有终。分配资源的例程也应该释放它。对于一次需要一只一个资源的例程,可以对资源分配的基本模式进行扩展,有两个另外的建议:以与资源分配的次序相反的次序解除资源的分配,这样,如果一个资源含有对另一个资源的引用,你就不会造成资源被遗弃。在代码的不同地方分配同一组资源时,总是以相同的次序分配它们,这将降低发生死锁的可能性(如果进程A申请了resource1,并正要申请resource2.而进程B申请了resource2,并试图获得resource1.这两个进程就会永远等待下去)。无论是谁分配的资源,它都应该负责解除该资源的分配。元程序设计再多的天才也无法胜过对细节的专注。动态配置要配置,不要集成。元数据到底是什么?严格的说,元数据是关于数据的数据,最为常见的例子可能是数据库schema或数据词典。元数据是任何对应于应用进行描述的数据——应用该怎样运行,它应该使用什么资源等等。在典型情况下,元数据在运行时,而不是编译时被访问和使用。你每时每刻都在使用元数据——至少你的程序是这样。假定你点击某个选项,隐藏你的web浏览器上的工具栏,浏览器将把该偏好作为元数据存储在某种内部数据库中。元数据的应用我们想要尽可能多的通过元数据配置和驱动应用。我们的目标是以声明方式思考(规定要做什么,而不是怎么做),并创建高度灵活和可适应的程序。商业逻辑于是你让数据库引擎的选择变成了配置选项,并提供了元数据来确定用户界面风格。对于不那么复杂的逻辑,可以使用小型语言加以表达,从而消除在环境变化时重新编译和重新部署的需要。协作式配置操作系统在启动时已经针对硬件进行了配置,而web浏览器会自动用新组件更新自己。没有元数据,你的代码就不可能获得它应用的适应性与灵活性。黑板没看懂。用黑板协调工作流。黑板系统让我们完全解除了我们的对象之间的耦合,并提供了一个“论坛”,知识消费者和生产者可以在那里匿名、异步的交换数据。如你可能会猜想的那样,它还减少了我们必须编写的代码的数量基于计算机的黑板系统最初是在人工智能中应用而发明的。在那样的应用中,要解决的问题大而复杂——语音识别、基于知识的推理系统,等等。现代的分布式类黑板(blackboard-like)系统,比如javaspaces和t spaces,以一种键值对模型为基础;这种模型首先在Linda中得到推广,在其中被称为元祖空间(tuple space)第六章 当你编码时 While you are coding注重实效的程序员批判的思考所有的代码,包括我们自己的。我们不断的在我们的程序和设计中看到改进的余地。在“重构”中,我们将讨论一些即使我们还处在项目中期,也能帮助我们修正现有代码的技术。只要你在制作代码,你就应当记住,有一天你必须对其进行测试,要让代码易于测试,这样你将增加它实际通过测试的可能性。不要靠巧合编程对于你调用的例程,要只依靠记入了文档的行为,如果出于任何原因你无法做到这一点,那就充分的把你的各种假定记入文档。怎样深思熟虑的编程:总是意识到你在做什么。不要盲目的编程,试图构建你不完全理解的应用,或是使用你不熟悉的技术,就是希望自己被巧合误导。按照计划行事。依靠可靠的事物。为你的假定建立文档(“按合约编程”)有助于澄清你头脑中的假定,并且有助于把它们传达给别人。不要只是测试你的代码,还要测试你的假定。不要猜测,要实际尝试它。为你的工作划分优先级。把时间花在重要的方面;很有可能,它们是最难得部分。如果你的基本原则或基础设施不正确,再花哨的铃声和口哨也是没有用的。不要做历史的奴隶,不要让已有的代码支配将来的代码。如果不再适用,所有的代码都可被替换,即使是在一个程序中,也不要让你已经做完的事情约束你下一步要做的事情——准备好进行重构,这一决策可能会影响项目的进度,我们的假定是其影响将小于不进行改动造成的影响。所以下次有什么东西看起来能工作,而你却不知道为什么,要确定它不是巧合。算法速率注重实效的程序员几乎每天都要使用:估计算法使用的资源——时间、处理器、内存。等等一般输入越多,运行时间就越长,或者使用的内存就越多。O()表示法就是时间复杂度。各种算法运行时间:一些常见的O()算法:O(1) 常量型(访问数组元素,简单语句)O(lg(n)) 对数型(二分查找),lg(n)表示法是log2(n)de 简写。O(n) 线性型(顺序查找)O(nlg(n)) 比线性差,但不会差很多(快速排序、堆排序的平均运行时间)O(㎡) 平方律型(选择和插入排序)O(㎥) 平方型(2m*m矩阵相乘)指数型(旅行商问题,集合划分)常识估算:简单循环。如果某个简单循环从1运行到n,那么算法很可能就是O(n)嵌套循环。如果你需要在循环中嵌套另外的循环,那么你的算法就变成了O(m*n),这里的m和n是两个循环的界限,这通常发生在简单的排序算法中。如冒泡排序。二分法。如果你的算法在每次循环时把事物集合一分为二,那么它很可能是对数型O(lg(n))算法,对有序列表的二分查找、遍历二叉树、以及查找机器字中的第一个置位了的位,都可能是O(nln(n)).分而治之。划分其输入,并独立的在两个部分上进行处理,然后再把结果组合起来的算法可能是O(nln(n)),经典例子是快速排序。组合。只要算法考虑事物的排列,其运行时间就有可能失去控制。这是因为排列涉及到阶乘n!,得出5个元素的组合算法所需时间是1,6个元素需要6倍的时间,7个元素需要42倍的时间。估算你的算法的阶你可以通过一些途径处理潜在的问题。如果你有一个O(㎥)算法,设法找到能使其将至O(nln(n))的分而治之的途径。考虑你在代码自身中所做的事情。对于较小的n值,简单的O(n^2)循环的性能可能会比复杂的O(nln(n))算法更好,特别是当O(nlg(n))算法有昂贵的内循环时。如果要获得准确的计时很棘手,就用代码剖析器(code profiler)获得你的算法中的不同步骤的执行次数。并针对输入的规模绘制这些数字。最好的算法对于你的工作并非总是最好的。如果你选择的算法有高昂的设置开销,你也需要注意,对于小输入集,这些设置时间可能会使运行时间相型见拙,并使得算法变得不再适用。易于测试的代码我们需要从一开始就把可测试件(testability)构建进软件中,并且在把各个部分连接在一起之前对每个部分进行彻底的测试。单元测试在隔离状态下对每个模块进行测试,目的是检验其行为,一旦我们在受控的(甚至是人为的)条件下对模块进行了彻底的测试、我们就能够更好的了解模块在广阔的世界上将怎样反应。针对合约进行测试我们喜欢把单元测试视为针对合约的测试,我们想要编写测试用例,确保给定的单元遵守其合约。这将告诉我们两件事:代码是否符合合约,以及合约的含义是否与我那么所认为的儿一样。我们想要通过广泛的测试用例与边界条件,测试模块是否实现了它允诺的功能。为测试而设计当你设计模块,甚或是单个例程时,你应该既设计其合约,也设计测试该合约的代码。通过设计能够通过测试,并履行其合约的代码,你可以仔细的考虑边界条件和其他非如此便不会发现的问题。构建测试窗口我们可以提供模块的内部状态的各种视图,而又不使用调试器。含有跟踪消息的日志文件就是这样一种机制,日志消息的格式应该正规,一致,你也许想要自动解析它们,以推断程序所用的处理时间或逻辑路径,格式糟糕或不一致的诊断信息就像是一堆呕吐物——它们既难以阅读,也无法解析。了解运行中的代码的内部状况的另一种机制是“热键”序列,按下特定的键组合,就会弹出一个诊断控制窗口,显示状态消息等信息,你通常不会想把这样的热键透露给最终用户,但这对于客户服务人员却非常方便。测试文化尽管有着黑客的名声,Perl社群对单元测试和回归测试非常认真。Perl的标准模块安装过程支持回归测试:%make test在这方面Perl自身并无任何神奇之处,Perl使得比较和分析测试结果变得更为容易,以确保顺应性(compliance)——测试被放在特定的地方,并且有着某种预期的输出。测试时技术,但更是文化;不管所用语言是什么,我们都可以让这样的测试文化慢慢浸入项目中。测试你的软件,否则你的用户就得测试。邪恶的向导如果你真的使用向导,却不理解它制作出的所有代码,你就无法理解你自己的应用。你没有能力维护它,而且在调试时会遇到很大的困难。不要使用你不理解的向导代码。他们说,开发者每天都在依赖他们不完全理解的事物——集成电路的量子力学、处理器的中断结构,用于调度进程的算法,系统提供的库里的代码,等等。我们同意。而且如果向导只是开发者可以依赖的一组库调用火标准的操作系统服务,我们队向导的感觉也是一样的。但它们不是,向导生成的代码变成了应用的完整组成部分。向导代码并没有被分解出来,放在整洁的接口后面——它一行一行的与joe编写的功能交织在一起。最后,它不再是向导的代码,而是开始变成joe的代码。没有人应该制作他们不完全理解的代码。解开不可能解开的谜题自由度问题并不在于你是在盒子里面思考,还是在盒子外面思考,而在于找到盒子——确定真正的约束。如果问题是“不可能解决的”这正是你退回一步,问问自己以下问题的时候:有更容易的方法吗?你是在设法解决真正的问题,还是被外围的技术问题转移了注意力?这件事情为什么是一个问题?是什么使它如此难以解决?它必须以这种方式完成吗?它真的必须完成吗?等你准备好有时犹豫的人会得以保全了不起的表演者有一个共同的特征:他们知道何时开始,何时等待。跳水运动员站在高台上,等待完美的时刻起跳。指挥站在乐队前面,手臂举起,直到她感觉到某个瞬间适于开始演奏。倾听反复出现的疑惑——等你准备好再开始当你面对一件任务时,如果你反复感觉到疑虑,或是体验到某种勉强,要注意它。你可能无法准确的指出问题所在,但给它时间,你的疑惑很可能就会结晶成某种更坚实的东西,某种你可以处理的东西。软件开发仍然不是科学,让你的直觉为你的表演做出贡献。是良好的判断,还是拖延当你做出决定,把构建原型当做调查你的不适的一种方法时,一定要记住你为何这样做,你最不想看到的事情就是,你花了几个星期认真的进行开发,然后才想起你一开始知识要写一个原型。规范陷阱编写规范是一项重要职责有些事情“做”胜于“描述”随着规范越来越详细,你得到的回报会递减,甚至会是负回报。你越是把规范当做安乐毯,不让开发者进入可怕的编码世界,进入编码阶段就越困难。不要掉进这样的规范螺旋中:在某个时刻,你需要开始编码!如果你发现你的团队全部包裹在暖和、舒适的规范中,把他们赶出来,考虑构建原型,或是考虑曳光弹开发。圆圈与箭头计算技术从不缺少意图使程序设计更像工程的方法。有一些开发者盲目的追求新方法会一无所获。不要做形式方法的奴隶是否使用形式方法绝对应该。但始终要记住,形式开发方法只是工具箱里的有一种工具。如果在仔细分析之后,你觉得需要使用形式方法,那就采用它——但要记住谁是主人,不要变成方法学的奴隶。注重实效的程序员批判的看待方法学,并从各种方法学中提取精华,融合成每个月都在变得更好的一套工作习惯。这至关重要。你应该不断努力提炼和改善你的开发过程,绝不要把方法学的呆板限制当做你的世界的边界。昂贵的工具比一定能制作出更好的设计形式方法在开发中肯定有其位置。但是,如果你遇到一个项目,其哲学是:“类图就是应用,其余的只是机械的编码”,你知道,你看到的是一个浸满水的项目团队和一个路途遥远的家。第八章 注重实效的项目注重实效的团队不要留破窗户团队作为一个整体,不应该容忍破窗户,团队必须为产品的质量负责。在有些团队方法学中有质量官员——团队会把保证产品质量的责任委派给他。这显然是荒谬的:责任只可能源于全体团队成员都做出自己的贡献。煮青蛙确保每个人都主动的监视环境的变化。对新需求进行持续的度量,团队无需拒绝无法控制的变化——你只需注意到它们正在发生。否则,你就会置身于热水中。交流显然,团队中的开发者必须相互交谈。人们很容易忘记,团队本身也存在于更大的组织中,团队作为实体需要同外界明晰的交流。对外界而言,看上去沉闷寡言的项目团队是最糟糕的团队,它们文档混乱:没有统一的术语。有一个简单的营销诀窍,能帮助团队作为整体与外界交流:创立品牌。当你启动项目是,给它取一个名字,最好是不寻常的名字。它能给你的团队一个用于建设的身份标识,并给外界某种难忘的、可以与你们的工作相关联的东西。不要重复你自己有些团队指定某个成员的担任项目资料管理员,负责协调文档和代码仓库。其他团队成员在查找资料时,可以首先找这个人。通过阅读正在处理的材料,好的资料管理员还能发现正在迫近的重复。当项目太大时,可以指定多人负责各个方面。正交性这里有一个隐含的层级关系——按照对你的授权,你越接近用户,级别就越高。认为项目的各种活动——分析、设计、编码、测试——会孤立地发生,这是一个错误。它们不会孤立地发生。它们是看待同一问题的不同方式,人为的分隔它们会带来许多麻烦。离代码的用户有两、三层远的程序员不大可能注意到他们的工作的应用语境。他们将无法做出有见识的决策。围绕功能,而不是工作职务进行组织我们喜欢按照功能划分团队。把你的人划分成小团队。分别负责最终系统的特定方面的功能。让各团队按照各人的能力,在内部自行进行组织。每个团队都按照他们约定的承诺,对项目中的其他团队负责。承诺的确切内容随项目而变化,团队间的人员分配也是如此。这种分组方式能够极大的减少各个开发者的工作之间的相互影响、缩短时间标度、提高质量、并减少缺陷的数目。但是,只有在项目拥有负责的开发者、以及强有力的项目管理时,这种途径才有效。一个项目至少需要两个“头”——一个主管技术,一个主管行政。自动化自动化是每个项目团队的必要组成部分。为了确保事情得以自动化,指定一个或多个团队成员担任工具构建员,构造和部署项目中的苦差事自动化的工具,让它们制作makefile、shell脚本、编辑器模板,使用程序,等等。知道何时停止绘画要记住,团队是由个体组成的,让每个成员都能以他们自己的方式闪亮。给他们足够的空间、以支持他们,并确保项目的交付能够符合需求。然后,要像“足够好的软件”中画家一样,抵抗不断画下去的诱惑。无处不在的自动化文明通过增加我们不假思索就能完成的重要操作的数目而取得进步无论是构建和发布流程、是书面的代码复查工作、还是其他任何在项目中反复出现的任务,都必须是自动的。我们也许必须在一开始就构建启动器和喷油器,但它们一旦完成、我们从此只需转动钥匙就可以了。一切都要自动化Shell脚本或批处理文件能以相同的次序、反复执行同样的指令。它们能被置于源码的控制之下,你因而也可以检查流程的修改历史。另一个特别受欢迎的自动化工具是cron(或Windows NT上的at)。它允许我们安排无人照管的任务周期性的运行——通常是在午夜。使用cron,我们可以自动安排备份、夜间构建、网站维护、以及其他任何可以无人照管的完成的事情。项目编译我们通常通过makefile编译项目、即使是在使用IDE环境时。使用makefile有若干好处。它是校本化,自动化的流程。我们可以增加挂钩,让其为我们生成代码,并自动运行回归测试。回归测试你还可以让makefile为你运行回归测试,或是针对单个模块,或是针对整个子系统。构建自动化构建是这样一个过程:取一个空目录(和一个已知的编译环境),从头开始构建项目,产生所有你希望产生的,最终交付的东西。在典型情况下,项目构建将包括以下几个步骤:从仓库中签出源码从头开始构建项目,在典型情况下是从顶层的makefile开始,每次构建都会标注某种形式的发布或版本号,或是日期戳。创建可分发映像。这个过程可能需要确定文件所有权和权限,并严格按照发运时所需的格式,产生所有的例子、文档、README文件,以及将随同产品发运的任何东西。运行规定的测试(make test)。如果你没有定期运行测试,你可能会发现,应用因为3个月前做出的代码改动而失败,但愿你有足够的好运气找到它。最终构建我们喜欢使用一个单独的make目标(比如make final),一次完成所有这些参数设置。要记住,如果产品的编译方式与先前的版本不同,你必须针对这个版本再次进行所有测试。鞋匠的孩子我们有制作更好的工具所需的所有原材料,我们有cron,在Windows和Unix平台上,我们都有make,我们还有Perl和其他一些高级脚本语言,可用于快速开发自制的工具、网页生成器、代码生成器、测试装备、等等。让计算机去做重复,庸常的事情——它会做得比我们更好,我们有更重要、更困难的事情要做。无情的测试注重实效的程序员知道,现在就要找到我们的bug,以免以后经受由别人找到我们的bug所带来的羞耻。早测试,常测试,自动测试。bug被发现得越早,进行修补的成本就越低。事实上,好的项目拥有的测试代码可能比产品代码还要多。编写这些测试代码所花的时间是值得的。长远来看,它最后会便宜得多,而你实际上有希望制作出接近零缺陷的产品。此外,你通过了测试将给你高度的自信:一段代码已经“完成”了要到通过全部测试,编码才算完成。单元测试单元测试是对某个模块进行演练的代码。集成测试集成测试说明组成项目的主要子系统能工作,并且能很好的协同。验证和校验一旦你有了可执行的用户界面或原型,你需要回答一个最重要的问题:用户告诉了你他们需要什么,但那是他们需要的吗?没有bug、但回答的问题本身是错误的,这样的系统不会太有用,要注意用户的访问模式、以及这些模式与开发者所用的测试数据的不同。性能测试软件是否能满足现实世界的条件下的性能需求——预期的用户数、连接数、或每秒事物数,它可以伸缩吗?可用性测试它是由真正的用户、在真实的环境条件下进行的。回归测试回归测试把当前测试的输出与先前的值进行对比。我们可以确定我们今天对bug的修正没有破坏昨天可以工作的代码。我们到目前为止提到过的所有测试都可作为回归测试进行,确保我们在开发新代码时没有损失任何领地。对测试进行测试通过“蓄意破坏”测试你的测试测试状态覆盖,而不是代码覆盖。何时进行测试许多项目往往会把测试留到最后一分钟——最后期限马上就要来临时,我们需要比这早得多的开始测试,任何产品代码一旦存在,就需要进行测试。把网收紧一个bug只抓一次一旦测试人员找到了某个bug,这应该是测试人员最后一次发现这个bug。我们必须把时间花在编写新的代码——以及新的bug——上全部都是写注重实效的程序员会把文档当作整个开发过程的完整组成部分加以接受。不进行重复劳动,不浪费时间,并且把文档放在手边——如果可能,就放在代码本身当中,文档的撰写就可以变得更容易。把英语当作有一种编程语言为项目制作的文档基本上有两种;内部文档和外部文档。内部文档包括源码注释、设计与测试文档,等等。外部文档是发布到外界的任何东西,比如用户手册。把文档建在里面,不要拴在外面。代码中的注释代码应该有注释,但太多的注释可能和太少一样糟。注释源码给你了完美的机会,让你去把项目的那些难以描述、容易忘记,却又不能记载在别的任何地方的东西记载下载:工程上的权衡、为何要做出某些决策、放弃了哪些替代方案,等等。下面是不应爱出现在源码注释中的一些内容:文件中的代码导出的函数的列表。有些程序可以为你分析源码,使用它们,列表就保证是最新的。修订历史。就是源码控制系统的用途所在,但是,在注释中包括最后更改日期和更改人的信息可能是有用的。该文件使用的其他文件的列表。使用自动工具可以更准确的确定这些信息。文件名。在源文件里应该出现的最重要的信息之一是作者的姓名——不一定是最后编辑文件的人、而是文件的所有者。使责任和义务与源码联系起来,能够奇迹般的使人保持诚实。可执行文档如果你的文档是作为带有标记(makeup)命令(例如,使用HTML、LaTeX或troff)的纯文档存储的,那么你可以使用像Perl这样的工具自动提取schema,并重新对其进行格式化。标记语言现在许多技术作者使用了DocBook来定义他们的文档,DocBook是一种基于SGML的标记语言,它仔细的标识了文档中的每一个组成成分,通过DSSSL处理器,文档可绘制成任意多种不同格式、Linux文档项目使用了DocBook来以RTF、TEX、info、PostScript和HTML格式发布信息。文档和代码是同一底层模型的不同视图,但视图是唯一应该不同的东西。不要让文档编程二等公民,被排除在项目主要工作流之外。对待文档要像代码一样用心,用户(还有后来的维护者)会为你唱赞歌的。极大的期望在现实中,项目的成功是由它在多大程度上满足了用户的期望来衡量的。温和的超出用户的期望。交流期望用户在一开始就带着想要的东西来到你面前,那可能不完整,不一致,或是在技术上不可能做到。你的部分角色就是要就此进行交流:与你的用户一同工作,以使他们正确的理解你将要交付的产品,并且要在整个开发过程中进行这样的交流。绝不要忘了你的应用要解决的商业问题。额外的一英里给用户的东西要比用户的期望多一点。给系统增加某种面向用户的特性所需的一点额外努力将一次又一次在商誉上带来回报。随着项目的进展,听取你的用户的意见,了解什么特性会使他们真的高兴。你可以相对容易的增加、并让一般用户觉得很好的特性包括:气球式帮助或工具提示帮助快捷键作为用户手册的补充材料的快速参考指南彩色化日志文件分析器自动化安装用于检查系统完整性的工具运行系统的多个版本、以进行培训的能力为他们的机构定制的splash屏幕(交互式软件显示的初始画面——译注)每一项特性都告诉你的用户,开发团队想要开发出了不起的系统,要用于实际的系统。只是要记住,不要因为增加这些新特性而破坏系统。傲慢与偏见注重实效的程序员不会逃避责任。相反,我们乐于接受挑战,乐于使我们的专业知识广为人知。如果我们在负责一项设计,或是一段代码,我们是在做可以引以自豪的工作。在你的作品上签名匿名(尤其是在大型项目中)可能会为邋遢、错误、懒惰和糟糕的代码提供繁殖地。你的签名应该被视为质量的保证。附录两个世界级的程序员专业协会:Association for Computing Machinery(ACM)和IEEE Computer Society,我们建议所有的程序员都加入其中一个,或是两个都加入。期刊IEEE ComputerIEEE SoftwareCommunications of the ACMSIGPLANDr.Dobbs JournalThe Perl JournalSoftware Development Magazine书籍分析与设计:Object_Oriented Software Construction,2nd EditionDesign PatternsAnalysis Patterns团队与项目:The Mythical Man MonthDynamics of Software DevelopmentSurviving Object-Oriented Project:A Manager’s GuideWeb:Slashdot。宣称是“痴迷者的新闻、重要的资料”。Slashdot是Linux社群的网络之家中的一个。除了定期更新Linux新闻之外,该网站还提供关于各种很棒的技术和影响开发者的问题的信息。Cetus Links。关于面向对象话题的数千链接。WiWiWikiWeb。Portland Pattern Repository和模式讨论,这不仅是一个很好的网站,其“对各种想法进行集体编辑”的做法也是一项有趣的试验。

大家都评价很高,我感觉泛泛

可能现在高质量的书也多,读者的口味也比较叼了。老实说这本书还是不错的,不过在看了《cleaning code》和《卓有成效的程序员》之类的书之后,这本书给我的惊喜不大,而且很多东西讲的有点泛泛。不过还是有一些值得借鉴的东西,值得一看吧。有电子版就爽了。呵呵。

关心你的技艺,思考你的工作

“Someone show loves to program and enjoys being clever about it”——《The Pragmatic Programmer》此句引摘自《程序员修炼之道 - 从小工到专家》,是对“hacker”含义的一种深刻见解,可意译为“热爱编程并享受在其中变得更擅长于编程的人”。作为程序员甚或是更广义的开发者而言,一旦你选择“躬耕”于软件开发领域,就必须从内心热爱这个行当,并且尽可能地赋予这份工作更多的创造性。或者说,像 “工匠”、“雕刻家”那样对待自己的工作,为打造一件让自己和大家都满意甚至惊叹的作品而精雕细琢,争做开发领域的“能工巧匠”。(“工匠”这个词在国外开发界意为丰 富的创造力而备受推崇)在闲谈之前,不得不费点笔墨,“为什么我们需要热情?”。热情是源于兴趣的,没有兴趣自然谈不上热情。如果工作对于你而言不只是为生存所需,而同时让自己的生活充满乐趣,那么我以为这便是热情。如果像《飞行者》那样狂热,那就是偏执狂了……我个人认为对一件事物偏执,很容易让自己忽略了其他事物,比如八小时之外的生活。我想真正能贴上“专业”这个标签的开发者,一定对自己的工作热情,一定会想法设法让它变得有趣,而且生活也会变得充满乐趣。关心你的技艺(Care Aoubt Your Craft)。或许你会觉得灰心,可能是因为自己总是在重复一些譬如业务逻辑之类缺乏创造力的工作或者自己没法让这个过程充满创造性,也可能是别人使用同样的开发工具、处在同样的开发环境中却总是比你来得更高效、更多产,也可能因为你认定自己同样拥有巨大的潜能却好像没办法培养和发挥出来。那么,你跟我一样需要关心自己的技艺,关心自己的技艺为什么总是“徘徊”在进阶之梯的中下层。我想改变目前状况的动力在于,“自己是否渴望自己在做的是一件漂亮作品,而不只是项目”。注重实效的开发者不仅要完成工作,而且要完成得漂亮,也只有实效的开发者才能兼顾二者。假设你是个注重实效的开发者,看看《The Pragmatic Programmer》会以哪些词语描述你,你就可以从这些角度来关心你的技艺:* 早期的采纳者或快速的改编者。你具有技术和技巧上的直觉,你喜爱试验各种事物,给你一样新东西,你很快就可以把握它,并把它与你的知识的其余部分结合在一起。记得,我们团队刚成立的时候,便像facebook那样用起了subversion,而这么简单实践在我以前的团队中甚至一般的开发公司中不会这样常见。(我无意与 facebook相比 :),只是感觉现在无比的受益)。当然,你的自信出自你的经验。* 好奇。你喜欢提问,而且知道如何提问,甚至提问后会立即动手研究。哪怕是一个简单的问题,比如“Facebook用的Subversion到底是什么玩意”?“ 那很漂亮,你用的时候有什么问题吗?”。千万别小看一丁点的问题,每一个问题都可能引发很多的尝试和思考,哪怕是很小的知识点都可能会影响到你今后的某项决策。* 批判的思考者。你不会喜欢赤裸裸地接受“拿来主义”,而从不过问拿来的东西是怎样来的。当同事说“就该这么做”或“只有这个办法”的时候,你不会没有任何调查、没有任何尝试就接受了这些观点。* 有现实感。你会理智地从内因去看待一件事情,设法理解每个问题的内在本质。这种现实主义会给你良好的感知能力:事情有多困难,需要多长时间?让自己了解到某个过程将会有些困难或需要用一点时间才能搞定,这种现实感能够给予你坚持不懈的努力。* 多才多艺。你尽力熟悉广泛的技术和环境(只是熟悉也不错了),并且努力工作,以与各种新发展并肩前行。尽管你现在的工作也许只要求你成为某方面的专才,你却总能够转向新的领域和新的挑战。不应该让自己仅仅局限于特定的技术和领域,还应该努力让自己拥有足够广博的背景和经验,以让你能在特定情况下选择好的方案。你的背景源自对计算机科学的基本原理的理解;而你的经验则来自实际项目,理论与实践的结合会使你强大起来。思考你的工作(Think About Your Work)。每一件事情都有一个开始到结束的过程,每一天都有早上到中午到晚上的过程,每一个人生都有从少年到青年到中年到晚年的演变。我们需要在每件事情开始的时候就“未雨绸缪”地设想将会碰到什么问题,解决问题需要我们现在准备什么;我们每天都需要“朝思暮想”,醒来想想今天需要做什么该怎么做,晚上想想今天做了什么哪里做得不好哪里做得好,再想想明天要做什么做样避免今天犯过的错误怎样做才更好;对于整个人生而言,我们更需要时刻思考自己将来想成为怎样的人,拥有什么,再进一步想想今天的工作是否能促进自己成为那样的人,能否让自己可能拥有自己梦想的东西。因此,对自己做的每一件事情、每一个项目、每一份工作、每一天的努力都多一点的思考和批判,思考自己为什么要这么做、怎样做更好,只是想想,或在日记本上写上几句,或用博客来记录那些点滴。这些思考这些努力可能会在极大的压力之下占据你一些宝贵的时间,但酬劳则是更为活跃地参与你喜爱的工作,掌握的知识范围日增及由此感受到持续进步的欢愉。Oh,关心技艺思考工作的同时,别忘了工作之外你还有能给自己带来更多快乐的关心你的人,还有你的业余兴趣。生活等着你把她变得充满乐趣,需要你的热情和创造力。longlinfeng's Blog:www.longlinfeng.com

关注我的技艺,思考我的工作

在序言中的两条技艺:关注你的技艺,思考你的工作,是全书的基础和我最喜欢的两句话。如果像书名一样,把程序技艺当游戏打怪升级一样,这两句话就是十二字箴言了。想提高自己的编程功力,首先要自己不断思考,把它当做自己的事业。第一章是序言的延续,题目是注重实效的哲学,挺题目就知道是在布道。知识资产和交流两节写的尤其之好。知识资产一节告诉我:要通过各种途径,不断丰富自己的大脑,而交流一节则告诉我:如何把想表达的东西表达清楚(知道自己要说什么),文档、邮件都要严格要求自己。 第二章介绍了全书很重要的一个原则:DRY。不重复自己,甚至可以引申到人生中,如果一件事情你做过了,就不要完全照搬重复,思考改进方案,比如实现自动化。正交性、可撤销性也都是很重要的概念,知识自己软件开发经验还很欠缺,还不能完全领会正交性的美。第三章工具中,文本、版本控制、编辑器、shell都是很常规的工具,没什么可说的,写的很好的一节是调试。书中主要讲的是心理上如何对待调试这个繁琐甚至有时让人抓狂的步骤。首先就是:不要发出指责,要解决问题,其次:不要恐慌。还讲了修正bug的最佳方式是让其再现,数据可视化、跟踪等实用技术,已经bug找到之后的措施:总结、讨论、修正单元测试。第四次讲一些偏执习惯。在让我们接受:代码都不完美之后,这章告诉我们怎么让自己的代码更健壮。合约式编程、早崩溃、断言、异常、配平资源等内容。第五章弯曲还是折断,这章讲的是代码的复用性,如何解耦。自己大型软件方面经验欠缺,也领会很浅。第六章“当我编程时”。靠巧合编程也是书中给我影响很大的一节。这节告诫我们:我们不知道自己的项目会失败,很多情况下是因为根本不知道为什么我们的项目会工作,因此要杜绝靠巧合编程,而要深思熟虑地编程。这点深得我心。一直以为来写程序都是以试错为基础,缺乏分析。还有一些告诫:不要使用不熟悉的技术,为假设建立文档等等。第七章项目开始之前,收货很少。最后一章:注重实效的项目也是很精彩的一章。第一节讲团队,之后有无处不在的自动化、无情的测试、全都是写、期望管理、傲慢与偏见。“全都是写”中有作者关于什么是好的注释的理解,而期望管理则告诉我们,谨慎超出客户的语气,控制客户的期望。总之,这本书是技术布道类的书籍,读完之后可能技术本身不会有什么提升,但我会清楚知道:软件开发领域,美在哪里,我应该朝那个方向去努力,已经我如何做就一定能达到这个方向。书中的很多内容,我现在还没法理解和领会,以后还需要经常拿出来翻翻,常看常新。

正交的好处

我的意见是不要购买其中文版(CS类书有原文版就不要买汉化版)

这本书我有两本,一本是以前购买的中文版。看着郁闷,简直就是在翻译原文的单词。另外一本是英文版,书中很多内容和《UNIX编程艺术》很相似。都是些高人、前辈经验的总结,相当有看头,是我睡前必看书籍之一。但是不建议没有太多编程体验的同学阅之,原因和“嫩不读水浒,少不读三国”的道理一样。

读书笔记 《第二章 注重实效的途径》

第二章 注重实效的途径    1. 重复的危害    软件系统中所使用的知识,是会不稳定变化的。比如市场环境的改变,政府决策的变化。  当知识变化的时候,软件系统的基础就出现了错误,这时就需要维护。  维护不应该只存在于软件的发布阶段,而是应该贯穿于开发过程的始终。    如果系统中对同一个知识进行了重复,那将给维护带来无法估计的麻烦。  因此应该避免在多个地方表达同一事物,这就是DRY原则(Don't repeat yourself)。(不管是代码还是文档)    重复的出现有以下几种:    (1)强加的重复:  因为代码结构的约束而不得不出现的重复,有以下几种。    <a>信息的多种表示:  跨越不同子系统使用同一知识结构。可以使用一个生成器,在多种语言的环境下,利用数据库中的元数据来构造出符合条件的结构体。  <b>代码中的注释:  注释应存在于高级结构中,以防止在低级应用中出现注释重复。  <c>文档与代码:  当代码改变后,文档往往没有时间更新。不妨用文档来驱动代码,先更新文档,再根据文档来操作代码。  <d>语言问题:  尤其是在面向对象语言中,会强加很多重复,比如接口及其实现,函数重构等。这种情况只能在编译时,仔细考察头文件和实现文件之间的差异。    (2)无意的重复:  在设计中,由于对象设计不合理,会产生重复:    <a>不同对象类型中,出现重复的属性。(比如:{a,b,c} {a,d,e})  <b>一个对象中,一个属性的改变会使另一个属性也需要改变。(比如:{start,end,length})    对象中的属性,应该使用访问器(get、set)来操作。    (3)无耐性的重复:  开发人员为了节省开发时间,产生的重复。但是往往欲速而不达。    (4)开发者之间的重复:  在开发人员开发自己的独立模块时,很可能生产出一些重复的基本逻辑处理函数。  应鼓励开发者互相进行主动的交流。比如新闻组和论坛。  集中存放实用例程和角本。以便找到可复用的东西。  阅读他人代码和文档,互助复查。      2. 正交性    两个直线相互垂直成为正交。在坐标上表现为,当X值变化时,Y值不变。  也就是说两个或多个事物中一个变化,不会影响到其他。(不依赖性、解耦性)    正交系统的设计就是消除无关事物之间的影响。设计独立、自足的组件。  正交可以提高生产效率、降低风险、便于测试和修改Bug。    团队任务的划分也应该注意正交性。  将基础设施与应用分离。  先按照基础组件(数据库、通信接口、中间件、等)划分子团队。  再根据应用功能和成员能力进行调整,尽量降低子团队之间的偶合性。    设计正交系统:  系统由一系列相互协作的模块组成,每个模块实现不依赖于其他模块的功能。  模块可以被分为很多层,每层提供一级抽象,每层只使用下面一层的抽象。  当一个模块的功能变化时,只需要调整这个模块和它下一层的接口即可。    “对象持久模型”(object persistence scheme)  正交性也体现在:面向方面编程(AOP)    在使用外部工具或库的时候,也应该注意正交,这样可以很容易地更换提供商。  文档也可以使用正交。    正交编码:  <a> 让代码保持解偶:除非必须,不要向外部模块暴露任何事情,也不去依赖外部模块。  <b> 避免使用全局数据。应该把需要的东西显式地传入模块而不是在模块中去访问共享。  <c> 避免编写相似的函数。      3. 可撤销性    不要过于依赖某一个事实,以至于当它改变时已经没有其他的解决办法。  我们在项目初期会做出一些重要决策,随着项目的进展,可选择的余地会越来越小,这些决策变得不能逆转。    一些方法可以帮助我们避免做出不可逆转的决策,DRY原则、解耦、使用元数据等等。  最重要的就是充分预计决策的可能变化,使项目保持灵活。    灵活性:代码、架构、部署、供应商集成。    在设计系统的时候应该注意:  <a> 考虑到单机结构、C-S结构、n层结构的简单转换。  <b> 应该把第三方产品隐藏在定义良好的接口后面。  <c> 注意系统兼容性。      4. 曳光弹    在夜间战争中,射击往往使用曳光弹和子弹交错的形式,一发曳光弹一发子弹。如果明亮的曳光弹打中了目标,那么子弹也就会打中。这种反馈很即时,因为曳光弹处于和子弹同样的环境中,降低了外部影响,并且非常快速地接近目标。    当要构建一个从没有构建过的东西时,基本上已知的东西很少。含糊不清的需求、不熟悉的算法、技术、语言、库。这时候我们需要能在黑暗中发光的代码。    曳光代码是简单功能的试探,通过实现一个和项目相似的简单功能,就可以快速地判断可行性、找出困难。  之后,曳光代码将被扩展、完善,做为最终项目的一部分。  因此,曳光代码需要完整的错误检查、结构、文档、自查。    曳光代码的优点:  <a> 用户可以及早看到实例,并通过直观的对比来纠正需求上的错误。(重新构造曳光代码)  <b> 开发者构建出一个可行的工作结构。  <c> 以曳光代码做为平台,每天的工作结果都可以集成上去,成为一个可用的集成测试原型。  <d> 可以演示。  <e> 非常直观的工作进展情况。    曳光代码不同于原型。  原型可以是一个片面功能的示意,比如用户界面演示,而曳光代码则是一个可用的简单整体架构。  原型制作应该放在曳光代码之前,做为对目标侦察和试探。      5. 原型与便签    原型是为了分析和揭示风险。  原型可以使多种形式的,只要能够准确地表达开发者的理解,并回答一些问题。    对以下工作建议制作原型:  架构、已有系统中的新功能、外部数据的结构或内容、第三方工具组件、性能、用户界面。    原型的价值在于通过它获得的经验教训。  原型应该尽量掩盖细节,把注意力集中在希望获得解答的问题上。    从原型中寻求解答:  主要组件的责任以及主要组件之间的协作关系。  耦合最小化。估计重复的潜在来源。  接口定义、约束关系、数据访问。    原型往往是用过就扔的,并不完整,也不代表任何工作进度。  但原型很容易被人误解,以为工作已经进行了很大一部分,如果需要避免这种误解,最好使用曳光代码。      6. 领域语言    对于一个业务,可以用文字描述。可以用编程语言来实现。也可以定义小型的领域语言并编写解释器,制作专用的代码。    一个项目中会涉及到不同领域,使用不同的领域语言来描述项目,有助于专心解决该领域中的问题,忽略琐碎的细节。    数据语言:  产生某种数据格式供程序使用。比如软件配置文件中特殊的数据格式,只有软件自己定义的解释器才能将其编译为可用的数据结构。    命令语言:  自定义一些命令语句,并构造解释器。比如脚本就是一种命令语言,可以直接执行。    嵌入式语言:  把高级命令语言直接嵌入到程序中。在程序运行的时候,加载不同的外部脚本就可以使程序进行不同的行为,不用重新编译,方便灵活。    这些领域语言的文法大多简单易懂,但真的做到能够运行,却需要花很大力气来做解释的工作。  但是这种努力可以使高级语言更易懂,易于维护,为后期开发带来越来越多的回报。      7. 估算    估算是为了避免发生意外。    估算的准确程度:不同的人对估算结果的准确性的要求有所不同。    估算的方法:  <a> 基本方法:去询问已经做过这件事的人。  <b> 理解提问内容:想要了解问题的范围,再去进行思考。  <c> 建立系统模型:需要一些源数据做为前提,开发一种普遍适用的计算方法。  <d> 把模型分解为组件:考察组件之间的关系,和它们对结果的影响。  <e> 给每个参数制定值:关注于那些对结构影响大的参数,保证尽量正确。  <f> 计算结果:通过调整参数,考量结果是否符合期望。  <g> 用实际结果来验证并改进估算方法。    估算项目进度:  在项目的开始,估算是模糊的。  在开发进行了一部分之后,通过这部分工作的实际情况来进行重新估计。  随着项目的进行,在多次迭代估算之后,估算的结果将趋向于正确。    在被要求估算时,告诉他:“我等会儿回答你。”多花一点时间来思考细节,会得到更好的结果。

我也来说说

这本书我认为是每一个合格的程序员都必须阅读的,里面虽然不教给你具体的方法,但它教给了我们思想以及一些指导性的原则!

看了一半,约10%是比较有用的

看到大家非常推荐于是就买回来阅读,可能是期望太高,可能不知不觉在做了其中的一部分,也可能是里面诸多问题自己的确没有很深感悟。到现在,当我读到一半的时候,我觉得从中学习的东西不多,我会继续读完,深挖掘一下。

六个优点

1. 翻译的质量非常高有点出乎意料之外,一本计算机专业书籍可以被翻译得这么流畅。当然这和本书的题材以及原作者的写作功力也是分不开的。2. 故事中的寓意尤其是在书的前半部分,作者讲的几个故事和事例,都恰如其分地解释了想要叙述的专业知识。石头汤煮青蛙、曳光弹、大楼的破窗户,等等。这些故事给人的印象深刻,同时也就记住那些知识了。3. 没有让人头痛的大段程序非常讨厌一些国内作者使用整页整页的程序(很多时候甚至是不正确的程序),来给书增肥,赚取稿费。与之相反,很多国外的经典计算机书籍都使用尽可能简短的程序,既方便读者阅读,也容易表达重点。尤其本书几乎没有使用代码,少见的一些程序实例也都只使用了基本的语法结构,这就不会给不同领域的程序员造成理解上的障碍。4. 前后呼应作者在阐述的观点,都是互相辅助和佐证的,就像作者在书中提到的一个观点“在正确的基础上做的事情才是正确的。”本书的众多观点初看起来有些杂乱,多亏了作者在文中不断地承前启后,在每个小节最末,更是给出关联的章节,使知识成为一个完整的体系。5. 高效的练习每节最后都给出了一些题目,不但题目出得不错,解答更是值得称赞。在很多解答中,作者并不只给出明确的是非,而是花费笔墨列举一些实际情形,说明在不同的情况下应该有不同的答案。6. 干净的排版目录简明,章节划分清晰、规格一致,内容重点突出,字体美观,恰到好处的留白。一本优秀的专业读物,首先应该是一本制作优秀的读物。

Journeyman是小工吗?不是!

书名:The Pragmatic Programmer: From Journeyman to Master。Master的意思很好理解,那什么是Pragmatic?在本书前言里,作者对Pragmatic Programmer应该具有的品质进行了枚举(care about your craft, Think about your work, Early/fast adopter, inquisitive, critical thinker, realistic, jack of all trades),总之都是很形而上很高的要求。Journeyman在英文里是什么意思? 难道真是指本书中文副标题中的“小工”? 在软件开发领域,什么样的程序员是Journeyman? 是不是一般的代码民工就是journeyman呢?我想大多数读过本书(不管是中文版或英文版)的都没有深入思考过(我第一次读到最近为止也没有)。做软件开发,都喜欢跟建筑行业类比。Kent Beck, GoF的模式思想受到亚历山大的建筑设计思想的启发;架构师在英文里则干脆跟建筑师是同一个单词;Code complete和Programming Pearls里将软件里没有考虑特殊的异常情况比作不了解桥梁附近的涡旋气流的建筑师没有对大桥的安全系数进行冗余设计,等等。是不是出自建筑上的类比,将一般水平的软件开发人员比作建筑行业的小工?这本书译者(或编辑)把journeyman翻译为小工,和把Code Complete翻译成代码大全,都是错误的,目的可能是为了提高书的销量,毕竟把副标题改为“从熟手”到“大师”会吓退不少人,而用从小工到专家则平易近人的多,也更符合中国it浮躁落后的国情。建筑行业的小工我也当过(自家盖房),因为有技术含量的不会,做的是没有技术含量的拌混凝土、筛黄沙、搬砖之类的重体力活,根本不要动脑子,只要听从指挥多流汗就可以了;而具体的架构设计(梁、墙、地基多深、高度、水平度、楼板、钢筋多粗、承重、利用经验对需要多少包水泥黄沙用量进行封底计算以便确定采购量和估算工程费用、工期估算、如何避免雨季对工程的影响,地震活动对水泥标号选择的影响等)则一点也不懂,也不需要懂。英文里的Journeyman到底是不是小工的意思? 在google字典里,Journeyman的意思是:(in the past) a person who was trained to do a particular job and who then worked for sb else (旧时)学徒期满的工匠,出师的学徒工a person who has training and experience in a job but who is only average at it 熟练工;熟手In former times, a journeyman was a worker who had finished learning a trade and who was employed by someone rather than working on his or her own.If you refer to someone as a journeyman, you mean that they have the basic skill which their job requires, but are not very talented or original.显然,小工只能算是学徒期的工人,而不是学徒期满的工匠,journeyman是已经经过培训对工作有一定经验的一般水平的工匠,能完成工作,但是缺乏天分或原创精神。journeyman能盖普通的遮风挡雨的房子,但是让他建造奔向天国的教堂则肯定不行。在“上古卷轴”游戏里里,不同经验等级划分如下:http://www.uesp.net/wiki/oblivion:spells技能熟练等级 技能等级新手(Novice) 0-24学徒(Apprentice) 25-49熟手(Journeyman) 50-75专家(Expert) 76-99大师(Master) 100 而研究所里的职称序列为:研究实习员助理研究员副研究员三级研究员二级研究员一级研究员从上面的序列可以直观的看出,journeyman至少是中级水平的,因为比journeyman高一级的是专家了,应该相当于软件公司的CTO,架构师,首席DBA之类的,或者医院里的专家门诊的主任或副主任医师,那比专家低了一级的应该是技术主管层次的。所以这本书的定位是给有一定项目开发经验的软件开发技术人员。从书后习题答案可以看出,读者需要熟悉Perl,Awk, C++, C, Java, Refactoring, Shell, DBC, RegEx, OO, lex/yacc之类的相关知识,这个要求说高不高,说低也不低,但肯定不是小工的水平了。英文副标题的本意是从熟手到大师,却被翻译成从小工(学徒工)到专家,相当于本意是从副研究员到一级研究员,却被翻译成从助理研究员到三级研究员,硬生生被降了级,难道是译者根据国内it落后现状做的意译?各行业的Journeyman 在游戏里,中级英雄,而不是低级炮灰,不砍人的时候不练功而是发呆,没有必杀技,能砍低级兵,自己也经常挂;在研究所里,通常为副研究员职称,手下有干活的助理研究员研究实习员若干,上百万、上千万的科研项目负责人,做过95,105,863,973,正在做115,享受一定的国家津贴,在国内期刊能通过付版面费发表论文以便将来评研究员职称,没科研经费很高的项目做时不读论文提高内功而是整点几十万的小项目或把以前的项目改个fancy name继续在网上孜孜不倦的申请课题或报奖,但其实数学基础创新能力很差,靠玩弄国外技术概念吃饭,从未(将来也不会)发表sci/ei的论文;在软件公司,项目技术带头大哥,对J2EE或.Net技术体系内的常用框架熟悉,数据库、Web开发熟练,Corba/COM/Web Service, 懂得封装继承多态,会多线程/Socket开发,会用Rose/PowerDesigner;能设计好后让一群代码民工编写模块,没活干的时候不知道提高自己和下属的技术能力读C++ report /CUJ/MSJ /DDJ/SDM,而是上csdn争论java和.Net的前途或者偷菜,只会玩三层架构,其实只是会熟练查MSDN或JavaDoc;在医院, 副主任医师或主管医师,看过很多病人,开药方非常熟练,药方上的密码龙飞凤舞,平均每个病人3分钟,喜用审犯人口气询问病情,热衷于开最新一代光谱抗生素,每月初都能在医院厕所里拿到上万医药代表回扣,平时一般忙着看病人没空研究技术写论文,最多玩玩医院买的数百万的医疗设备弄个技术引进奖,其实只是背熟了药典而已;在建筑行业,盖普通居民住房的包工头,造过很多房子,但是没有资质,只能盖3层以下的房子高了会楼脆脆,有时没活也接些装修的活,纯粹是剥削农民工的包工头,只是对购买黄沙水泥原材料接项目比较熟悉。言而总之,总而言之,翻译成小工是不对的,小工应该是Novice或Apprentice的水平。这本书后面的习题答案非常棒,问题规模都很小,不是很难,但很有启发作用。 本书两位作者都是consultant, 这种人精都有很多行业的20年左右的it项目经验,给开发团队当顾问教练,都是master,书中的tips因此是他们多年的经验总结best-practices。在cba混的运动员看不起郭士强,却不会看不起nba的哈里斯;而有的评价这本书的人小看这本书的作者,岂不是连四肢发达头脑简单的运动员都不如?amazon上有人批评此书“1英里长,但是只有1英尺深”,并推荐Code Complete,殊不知两本书都是BFS类型的,而不是DFS类型的。Code Complete固然很厚很全,但是作者还是在书末推荐了很多书籍杂志,如果够全够深,那他还用的着推荐这些书杂志吗? 虽说治大国若烹小鲜,半部论语就可治天下,但是在软件开发中光靠KISS是不可能的,看看Code Complete末尾的令人望而生畏的参考文献, 他的初中高级推荐书目或作者网站上的程序员职业发展路线Construx Professional Ladder(http://www.construx.com/Page.aspx?hid=952)就知道了。确实,书中每个主题都点到为止, 不够深入;但书中每个主题都可以写一本书, 如DBC, 如Testing, 如Code Generation, 如重构, Use Case, 算法。如果递归深入下去, 那用Code Complete的篇幅也不够。其实The Pragmatic Programmer和Code Complete 2虽然厚薄差别很大,但作者的写作思路都是BFS而不是DFS,对读者进行软件开发的通识教育, 因为具体的DFS工作已经有汗牛充栋的CS书在那里了。经过这种通识教育的人,如果不知道自己去DFS, 那么就只能怪自己了,师傅领进门,修行在个人。书中作者提到的领域都有经典著作, 如DBC和OO可以读Bertrand Meyer的Object-oriented Software Construction 2rd, 重构有Martin Fowler和Kent Beck的Refactoring/Smalltalk Best Priactices,Unit Testing实战有JUnit in Action, JUnit Recipes, 理论性的测试书有Foundations of Software Testing, Code generation可以读Common Lisp, Haskell之类的函数式语言的书中的例子/The art of Unix Programming中的MIni Language和DSL章节/code generation in action,用例有经典的Writing Effective Use Cases,算法书更多,远有Knuth, Bentley, Sedgewick, CLRS的经典,近有Algorithms, Algorithm Design, The Algorithm Design Manual。好书很多,我DFS不过来,所以现在还是个跑龙套的。---------------------------------------------------------------------------------------2009-10-02 更正: 娶了双胞胎姐妹之一的P.J.Plauger在澳大利亚悉尼给学生上软件工程课程时,没有给学生讲授软件分析设计技术、CASE工具和SEI的最新进展.,因为他认识到:  No point in leading students to the mountain top if they haven't learned their way around the foothills adequately. My goal was to make sure they at least knew about all the low-level terrain. They could climb their own hills later, if they chose. Hunt和Thomas应该也是类似想法.大师都是受人以渔的.Meilir Page-Jones(Practical Guide to Structured Systems Design一书作者)将专业技术等级分为7类(http://www.waysys.com/ws_content_al_sse.html),应该比较权威,比游戏里或我臆想的要严谨的多:Stage 1: InnocentA Stage 1 may not have heard of Software-Engineering techniques. Or — more likely nowadays — he may be vaguely aware of their existence but may not see their possible relevance to his situation. Indeed, he may be only dimly aware that there are any software-development problems in his shop. You may find it incredible that Stage 1s could exist in the 1990s, but they do. And the reason stems from the way in which software complexity evolved.Software became insidiously more and more complex in the 1970s and 1980s as users demanded more and more sophisticated systems be installed on the more and more powerful hardware that became available. Yet there was no sharp transition. The earth was not hit by a Complexity Asteroid in 1975 that suddenly made software three orders of magnitude more complex and cast our reptilian development techniques into extinction.I call the way in which software complexity actually increased “Frog in the Pan.” This is because although a frog will jump out of a pan of hot water, a frog that is placed in a pan of cold water and slowly heated will fail to leap forth and will actually boil to death. The temperature gradient is so gradual that there will never be a point at which the frog declares: “Boy, it’s suddenly gotten hot in here! I think I should hop out.” (Before I get into deeper trouble from animal-rights folks, I hasten to add that this analogy is apocryphal. I’ve never tried the experiment and I don’t recommend that you do so either !)Many Stage 1s are experiencing “Frog in the Pan” and are trying to tackle problems of the 1990s with approaches of the 1960s and 1970s, without realizing that the problems they’re facing are the very ones that modern Software-Engineering techniques were created to alleviate.Stage 2: ExposedStage 2s have noticed that the water is getting decidedly warm, if not downright hot. So they are actively seeking Software-Engineering techniques that will get them out of the pan or at least reduce the heat. Stage 2s may survey magazines, confer with colleagues or attend one-day overviews of the techniques. Their interest level is high but their knowledge level is low, being limited to a few terms and definitions and not based on any practical Software-Engineering experience.Stage 3: ApprenticeStage 3s have attended one or two 5-day workshops on Software-Engineering techniques. In these workshops they tackled small but realistic case studies that resembled their own projects in miniature. The case studies provided valuable kinesthetic reinforcement of the formal lecture material and were thus indispensable. However, the case studies’ apparent realism conveyed to the Stage 3 a confidence that is often unwarranted.If a Stage 3 absorbs everything from a seminar, then he is minimally equipped to tackle a true, full-sized project in the corporate jungle. Usually, however, a Stage 3 does not grasp everything or has difficulty scaling the techniques up from a case study to a real project. You could say that most Stage 3s know just enough to be dangerous!Stage 4: PractitionerThe rite of passage to Stage 4 is the use of Software-Engineering techniques on at least one significant project. Achieving “Stage 4-hood” is for many people the most difficult transition of the six transitions between stages. The fledgling Stage 4 is asked to take untried (by him) techniques and apply them to a corporate project with the usual demonic cocktail of politics, deadlines and changing requirements. At the same time, he is attempting to recall what he learned in class and scale up the examples 10- or 100-fold. He continually needs consulting advice, without which he will encounter a series of minor setbacks or major failures. Since many people throw up their hands at this point and revert to their old mediocre but familiar ways, a large proportion of Stage 3s never make it to Stage 4. If an entire project is peopled with Stage 3s, then it’s highly likely that the project itself will fail and the Software-Engineering techniques will be publicly pilloried and then abandoned.Stage 5: JourneymanStage 5s have made it. Their experience of Software-Engineering is “latched” in place and there is little risk of their reverting to the past. In the Stage 5 the Software-Engineering techniques yield for the first time the productivity the marketing folks promised; and on each successive project a Stage 5 further hones his skill and enhances his productivity. A Stage 5 is self-sufficient - more often the source of Software-Engineering advice than its recipient.Stage 6: MasterThe Stage 6 not only is an adept technician, but also possesses a profound methodological foundation. Beyond the “whats” and “hows”, the Stage 6 knows the “whys” of Software Engineering. This depth allows him sometimes to break a surface rule, while adhering to a more fundamental methodological principle. The Stage 6 is a good instructor because his theoretical and practical knowledge give him the wherewithal to tackle difficult student questions.Stage 7: ResearcherThe Stage 7 is concerned with delivering the latest developments in Software Engineering to a wider audience, via books, articles and conference appearances. The Stage 7 looks out for flaws in contemporary Software-Engineering techniques and for consequent ways to improve the techniques. He also scans the horizon for new problems towards whose solution Software Engineering can be extended and generalized. The Stage 7 is at a methodological pinnacle.A couple of our clients measured the length of time from Stages 3 to 5. Depending on the individual person, Stage 3 to Stage 4 took 6 to 18 months (about the length of a project or phase) and Stage 4 to Stage 5 took 18 to 36 months. Never attempt a crucial project solely with Stage 3s and below. Seed each project with Stage 4s and allow access to Stage 5s and 6s if possible. If you don’t have a Stage 5, beg, borrow, steal, buy, kidnap, ... one. External consultants are valuable as a short-term measure. (从这句话就可以看出stage5也就是Journeyman地位之高)Page-Jones眼中的Jurneyman对于公司的作用是这样的:"Stage 5 the Software-Engineering techniques yield for the first time the productivity the marketing folks promised." it项目延期或失败的概率很高, 因此能做到这一点的人水平肯定是很高的。此外,在Software Craftsmanship The New Imperative这本书的第12章和第13章专门用整章的篇幅讨论了Apprentice Developer和Journeymem Developer.

程序员基本素质的培养

如果自己开公司给员工培训的话,朋友的观点是要给程序员培训算法。我认为第一个要讲的就是这本书的内容,第二个就是时间管理。其实在程序员修炼之道里,就有很多关于时间管理的内容,它们是相互补充的。比如程序员的美德——懒惰,就是要提高效率,就是要节约时间。为什么不是培训算法呢?我的理由大概是这样的:1、作为程序员,算法思想应该是基础,算法经验应该是在实践中培养。如果连基本的算法都不懂,他不会通过初面的。2、如果我开公司,应该是做高层应用,这方面,一般是用OO思想来设计,大部分用到的算法都封装好了,要自己写算法的机会不多。更重要的,应该是程序员的效率,包括运用各种自动化和高效的工具。当然,这里的程序员是符合第一点的。3、至于高深的算法,我想我自己更应该先去接受培训。我读这本书的感触很深,收获在目前的公司才显现出来。因为之前的公司没有给我发挥的机会,每天的活就是复制粘贴代码,技术主管也没有给我们展现的机会,公司也没有想做得更好的意图。现在这家公司虽小,但主管给了我很大的空间,我将书中的思想运用到实际开发中,不仅自己收获大,对团队对项目都有很好的影响。算法虽重要,但它只是基础,如果只会基础而没有程序员其它方面的基本素质,还不算一个很好的程序员。《程序员修炼之道:从小工到专家》就是程序员培养基本素质的参考,力荐。http://blog.belltoy.net/read-the-pragmatic-programmer.html另外一篇我写的书评:http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html

每个程序员必看的书

当软件开发渐渐沦为混饭吃的技能,当代码像垃圾一样堆积起来的时候,激情就随之消散了。这本书让我重燃追求软件开发艺术的信心,推荐阅读。

绝对不能只看一遍

对于一个大二的 而且是没什么编程经验 涉猎也不是太广的学生来说 这本书里提到的很多东西都十分的陌生 包括一些语言 一些编译器 很多很多 但是自己却仍然力荐这本书 它让我明白了许多道理 它们不仅适用于软件这个行业 对其他很多行业也非常的适合 鉴于自己的能力 实在不能完全理解书中的每一个点 只好先略读一遍 待到充实了自己 再将其翻出来重读一遍 定能有更大的收获 希望你们也是如此 力荐此书

写作这本书的方式很有意思

这里有作者之一Dave Thomas在敏捷2009大会上关于此书的演讲(http://www.infoq.com/cn/presentations/dt-pragmatic-programmer)这本书的成书过程很有意思。作者非常喜欢program,以至于将这本书的写作当成了软件工程,全书用plain text写成,以soruce code(应该是他们自己发明的领域语言DSL~)的方式组织而成,用他们自己写成的工具build一下后就成了此书,相信他们也以某种版本管理工具对此进行了管理(方便查看版本之间的变化等),并对书中的code进行了单元测试。想像一下他们怎么写书的(借用HTML的格式猜想一下):<Title>程序员修炼之道</Title><Body>shell游戏<Code>/home/Dave/game.sh</Code></Body> Test时会自动测试书中的程序,如:game.sh;Build之后本书便完成了。这真是一个很成功的“项目”:* Automate Everything.* 如果需要,则设计自己的小语言Perl有一个作解释器的包http://search.cpan.org/~dconway/Parse-RecDescent-1.965001/lib/Parse/RecDescent.pm* Fix Broken Windows--Fix small thing,Then big thing will not happen.* Don't repeat yourself(DRY)-- code duplication解决方法: 做成函数,模块,类;采用code generators;采用元程序设计(The art of metaprogramming:http://www.ibm.com/developerworks/linux/library/l-metaprog1.html);采用设计模式(作者觉得采用模式有可能把问题弄复杂);convertions;metaphors;-- Project DuplicationFix by producing procduts; Fix with data-driven designs.* Do one thing better.简单,低耦合。 * Do Nothing Twice.* 代码之前,测试先行。* 选择好的编码工具能有效地提高效率,避免编码中的小错误。

可以说, 这本书改变了我的一生.

我大约是在高二或者高一的时候在学校附近的一个书店里看到的这本书, 只要在这间书店押100元, 就可以在这里借书回去看。《程序员修炼之道》,听这名字就感觉不错。我把它拿回家,封面很深沉,纸张手感很好,排版也更不用说。那个时候我刚开始学C语言,而这本书中的很多内容都让我从一开始养成了一个良好的习惯。说实话,我已经记不清里面到底讲了什么东西了,但是我相信很多东西都已经融入到了我的身体里。包括一个程序员应该有的习惯,怎样边调试边写代码而让你的程序总是正确的,怎样安排时间,当你遇到问题时以一种什么样的心态解决,以及很多很多方法学上的东西,以及很多小技巧。书中也有很多发人深省和给人启发的简短的谚语,所有的这一切都改变了我。或许我前面所说的都是废话,可请你看看下面的链接,这是我在读完那本书不久所做的,我可以说没有这本书对我的影响,我在那个时候就无法做出这样的东西。:-)http://www.robotdiy.com/article.php?sid=193

so so...

看着中文译名,挺吸引人,可惜名不符其实。也就在公司闲瑕之际,前后几次大约半个小时不到翻完了。内容很松散,甚至可说是捕风捉影。事实上,读之前 ,看两位作者的介绍,就给人感觉,Hmm,估计不是真正搞计算机的。。

To be a Pragmatic Programmer

在图书馆偶然翻到这本书,看到序中写着“This book will help you become a better programmer.”就果断带回了,放在床头每天翻一章,一个星期也就看完了。内容比较散,针对每个主题也是点到为止,并不深入,很多建议于我很有用,也有些可能要有些项目经验之后才能体味到。但总体来说,确实是“一本易于阅读——也易于应用——的关于整个编程实践的书。”总结一下书中的内容~What Makes a Pragmatic Programmer?Early adopter/fast adapter.Inquisitive.Critical thinker.Realistic.Jack of all trades.All Pragmatic Programmers share them. They're basic enough to state as Tips:1. Care About Your Craft2. Think! About Your WorkChapter 1. A Pragmatic Philosophy3. Provide Options, Don't Make Lame Excuses4. Don't Live with Broken Windows5. Be a Catalyst for Change6. Remember the Big Picture7. Make Quality a Requirements Issue8. Invest Regularly in Your Knowledge Portfolio (see goals here: http://book.douban.com/annotation/22190513/)9. Critically Analyze What You Read and Hear10. It's Both What You Say and the Way You Say It*是否“Pragmatic”在于你处理问题、寻求解决方案的态度、风格、哲学。一个优秀的,Pragmatic的程序员应该是负责任(3)、不留破窗(4)、瞥见未来变化(5)、适当权衡(6\7)、有广泛的知识和经验(8)、注重交流沟通(9.10)。Pragmatic的编程源于注重实效的思考的哲学。Chapter 2. A Pragmatic Approach11. DRY—Don't Repeat Yourself12. Make It Easy to Reuse13. Eliminate Effects Between Unrelated Things14. There Are No Final Decisions15. Use Tracer Bullets to Find the Target16. Prototype to Learn17. Program Close to the Problem domain18. Estimate to Avoid Surprises19. Iterate the Schedule with the Code*系统开发设计方面的一些技巧和基本原则,如“避免重复”(11)“正交性”(12)“原型与便签”设计(15.16),以及“估算时间”(18)等,于软件领域之外也是公理。Chapter 3. The Basic Tools20. Keep Knowledge in Plain Text21. Use the Power of Command Shells22. Use a Single Editor Well23. Always Use Source Code Control24. Fix the Problem, Not the Blame25. Don't Panic26. "select" Isn't Broken27. Don't Assume It—Prove It28. Learn a Text Manipulation Language29. Write Code That Writes Code*最实用、最为非读不可的一章!!工具放大你的才能。你的工具越好,你越是能更好地掌握他们,你的生产力就越高。 花时间学习使用工具,有一天你会惊奇的发现,你的手指在键盘上移动,却不用有意识的思考。工具将变成你双手的延伸。Chapter 4. Pragmatic Paranoia30. You Can't Write Perfect Software31. Design with Contracts32. Crash Early33. If It Can't Happen, Use Assertions to Ensure That It Won't34. Use Exceptions for Exceptional Problems35. Finish What You Start*不存在完美的软件,我们需要做的不是完美,而是在问题出现之前小心谨慎、未雨绸缪、不让自己陷入无可解救的境地。Pragmatic的程序员将采取防御措施(31)、寻找Bug(32)、主动校验假设(33)、处理异常(34)、动态分配资源(35)。Chapter 5. Bend or Break36. Minimize Coupling Between Modules37. Configure, Don't Integrate38. Put Abstractions in Code Details in Metadata39. Analyze Workflow to Improve Concurrency40. Design Using Services41. Always Design for Concurrency42. Separate Views from Models43. Use Blackboards to Coordinate Workflow*尽一切可能编写宽松、灵活的代码,使代码可以跟上变换的脚步不断向前。这需要代码编写降低耦合度(36.37),使用“元程序设计”减少代码编写和改动(38),还要设计模块(39.42),协调工作流(43)Chapter 6. While You Are Coding44. Don't Program by Coincidence45. Estimate the Order of Your Algorithms46. Test Your Estimates47. Refactor Early, Refactor Often48. Design to Test49. Test Your Software, or Your Users Will50. Don't Use Wizard Code You Don't Understand*编码不是机械的工作(非常非常赞同这个观点,就像非常不喜欢“码农”这个称呼一样)。Pragmatic的程序员批判地思考他们的代码,补靠巧合编程(44),估算算法效率(45.46),及时重构(47),注重测试(48.49)。还有,不要轻信向导~(50)Chapter 7. Before the Project51. Don't Gather Requirements—Dig for Them52. Work with a User to Think Like a User53. Abstractions Live Longer than Details54. Use a Project Glossary55. Don't Think Outside the Box—Find the Box56. Listen to Nagging Doubts—Start When You're Ready57. Some Things Are Better Done than Described58. Don't Be a Slave to Formal Methods59. Expensive Too Do Not Produce Better Designs*项目开始前需求分析的重要性和途径。Chapter 8. Pragmatic Projects60. Organize Around Functionality, Not Job Functions61. Don't Use Manual Procedures62. Test Early. Test Often. Test Automatically.63. Coding Ain't Done 'Til All the Tests Run64. Use Saboteurs to Test Your Testing65. Test State Coverage, Not Code Coverage66. Find Bugs Once67. Treat English as Just Another Programming Language68. Build Documentation In, Don't Bolt It On69. Gently Exceed Your Users' Expectations70. Sign Your Work*从个体哲学转向团队管理的讨论。Pragmatic的团队应该时刻保持一致和可靠(60.61),边开发边测试(62.63.64.65.66),撰写文档(67.68),从项目出资人的角度出发(69),最后,记得签名(70)。附录A有很多丰富的资源:http://book.douban.com/annotation/22192362/书中还有很多锦句,很哲学:http://book.douban.com/annotation/22190425/

作者总结了很多道理和经验

看到了很多共鸣,但是我也承认有些地方还是理解的不是很透彻,这是一本需要看很多遍的书,不同时期看会有不同层面的理解。作者总结了很多道理和经验,但不是教条式的说教,书中有很多例子,还有很多练习题也非常有趣,推荐有一些项目经验的人看看。

实效程序员的修炼之道

这本书得到了国内一些知名, 不知名的圈内人的大力推荐(序1, 2, 3 ...). 不过在我看来也就一般般(难道是自己境界不够? 还是跟我看了不少类似的书有关?), 毕竟是10年前的书了, 虽然里面有一些观念放到现在也不过时, 不过随着日新月异的技术发展, 有些东西在现在来看也有些不合时宜, 而有些东西该有所创新了. 而且有些地方翻译的比较生硬, 看起来怪怪的.不过原著者的兴趣比较有噱头, 一个喜欢木工, 一个玩单引擎飞机

到现在才读这本书是有点迟了

三五年前读的话,收获会更大。但现在读也有一个好处,就是可以看到很多遵从书上的原则而产生出来的实际作品,书中的结论自然得到更好的印证。看起来,好的书的确生命力会长一点

什么是注重实效的程序员?

1. 注重实效的程序员特征:1)早期的采纳者/快速的改编者2)好奇3)批判的思考者4)有现实感5)多才多艺他们处理问题、寻求解决方案时的态度、风格、哲学。他们提出直接的问题去思考,总是设法把问题放在更大的语境中,总是设法注意更大的图景。注意实效的程序员不会坐视他们的项目土崩瓦解。2. 改善(かいぜん),每天为你所拥有的技能而工作,为把新的工具增加到你的技能列表中而工作。3. 在所有弱点中,最大的弱点就是害怕暴露弱点!注意实效的程序员对他或她自己的职业生涯负责,并不害怕承认无知或错误。4. 负责如果你确实同意要为某个结果负责,你就应切实负起责任。当你犯错误、或是判断失误时,诚实地承认它,并设法给出各种选择。不要责备别人或别的东西,或是拼凑借口。不要把所有问题都归咎于供应商、编程语言、管理部门,或是你的同事。5. 破窗户一扇破窗户,只要有那么一段时间不修理,就会渐渐给建筑的居民带来一种废弃感——一种职权部门不关心这座建筑的感觉。于是又一扇窗户破了。人们开始乱扔垃圾。出现了乱涂乱画。严重的结构损坏开始了。不要留着“破窗户”(低劣的设计,错误决策,或是糟糕的代码)不修,发现一个就修一个。如果没有足够的时间进行适当的修理,就用木板把它钉起来。6. 设计出你可以合理要求的东西,好好开发它。一旦完成,就拿给大家看,让他们大吃一惊。然后说“要是我们增加......可能就会更好。”假装那并不重要,坐回椅子上,等着他们要你增加你本来就想要的功能。7. 大多数软件灾难都是从微不足道的小事情开始的,大多数项目的拖延都是一天一天发生的。8. 知识投资的一些建议:1)每年至少学习一种新语言2)每季度阅读一本技术书籍3)也要阅读非技术书籍4)上课5)参加本地用户组织6)试验不同的环境7)跟上潮流8)上网9. 如果你自己找不到答案,就去找出能找到答案的人。不要把问题搁在那里。与他人交谈可以帮助你建立人际网络,而因为在这个过程中找到了其他不相关问题的解决方案,你也许还会让自己大吃一惊。旧有的资产也在不断增长……10. 批判地思考你读到的和听到的,你需要确保你的资产中知识是准确的,并且没有受到供应商或媒体炒作的影响。11. 了解听众1)你想让他们学到什么?2)他们对你讲的什么感兴趣?3)他们有多富有经验?4)他们想要多少细节?5)你想要让谁拥有这些信息?6)你如何促使他们听你说话?12. 做倾听者如果你想要大家听你说话,你必须使用一种方法:听他们说话。鼓励大家通过提问来交谈,或是让他们总结你告诉他们的东西。把会议变成对话,你将能更有效地阐明你的观点。13. 邮件交流1)在你按下“发送”之前进行校对2)检查拼写3)让格式保持简单4)只在你知道对方能阅读rich-text或HTML格式的邮件情况下才使用这些格式。纯文本是通用的。5)设法让引文减至最少6)如果你引用别人的邮件,一定要注明出处,并在正文中进行引用7)不要用言语攻击别人,除非你想让别人也攻击你,并老是纠缠你8)在发送之前检查你的收件人名单9)将你收到的重要文件和你发送的邮件,加以组织并存档14. DRY法则告诉我们,要把低级的知识放在代码中,它属于那里;把注释保留给其他的高级说明。否则,我们就是在重复知识,而每一次改变都意味着既要改变代码,也要改变注释。15. 不要依赖无法控制的事物16. 维持正交性1)让你的代码保持解耦2)避免使用全局数据3)避免编写相似的函数养成不断地批判对待自己的代码的习惯,寻找任何重新进行组织、以改善结构和正交性的机会。这个过程叫做“重构”,它非常重要。17. 修正 bug也是评估整个系统的正交性的好时候。当你遇到问题时,评估修正的局部化程度。18. 要把决策写在沙滩上,而不是把它们刻在石头上。大浪随时可能到来,把它们抹去。19. 曳光弹并非用过就扔的代码,你编写它,是为了保留它。它含有任何一段产品代码都拥有的完整的错误检查、结构、文档,以及自查。曳光开发与项目永不会结束的理念是一致的:总有改动需要完成,总有功能需要增加,这是一个渐进的过程。20. 架构原型中寻求解答的具体问题:1)主要组件的责任是否得到了良好定义?是否适当?2)主要组件间的协作是否得到了良好定义?3)耦合是否得以最小化?4)你能否确定重复的潜在来源?5)接口定义和各项约束是否可接受?6)每个模块在执行过程中是否能访问到其所需的数据?是否能在需要时进行访问?适当地使用原型,可以帮助你在开发周期的早期确定和改正潜在的问题点,在此时改正错误既便宜、又容易——从而为你节省大量时间、金钱,并大大减轻你遭受的痛苦和折磨。21. 估算来自哪里1)理解提问内容2)建立系统的模型3)把模型分解为组件4)给每个参数指定值5)计算答案6)跟踪你的估算能力22. 估算项目进度1)检查需求2)分析风险3) 设计、实现、集成4)向用户确认23. 使用纯文本优点:1)保证不过时2)杠杆作用3)更易于测试缺点:1)与压缩的二进制格式相比,需要更多存储空间2)要解释及处理纯文本文件,计算上的代价可能更昂贵24. 去熟悉shell,你会发现自己生产率迅速提高。25. 选一种编辑器,彻底了解它。并将其用于所有的编辑任务。36. 使用源码控制系统(或范围更宽泛地配置管理系统)追踪你在源码和文档中做出的每一项变动。37. 没人能写出完美的软件,所以调试肯定要占用你大量时间。38. bug是你的过错还是别人的过错,并不是真的很有关系。它仍然是你的问题。39. 如果你目睹bug或见到bug报告时的第一反应是“那不可能”,你就完全错了。一个脑细胞不要浪费在以“但那不可能发生”起头的思路上,因为很明显,那不仅可能,而且已经发生了。40. 在调试时小心“近视”。要抵制只修正你看到的症状的急迫愿望:更有可能的情况是,实际的故障离你正在观察的地方可能还有几步远,并且可能涉及许多其他的相关的事物。要总是设法找出问题的根源,而不只是问题的特定表现。41. 在设法解决任何问题时,你需要搜集所有的相关数据。42. 开始修正bug的最佳途径是让其可再现,毕竟,如果你不能再现它,你又怎么知道自己已经被修正了呢?43. 如果修正这个bug需要很长时间,问问你自己为什么。你是否要以做点什么,让下一次修正这个bug变得更容易?44. 代码生成器有两种主要类型:1)被动代码生成器只运行一次来生成结果,然后就变成了独立的,它与代码生成器分离了。它本质上是参数化模板,根据一组输入生成给定的输出形式,结果一经产生,就变成了项目中有充分资格的源文件。2)主动代码生成 器在每次需要其结果时被使用,结果是用过就扔,它总是能由代码生成器重新生成。它可生成模板,源码控制指示、版权说明及项目中每个新文件的标准注释块。45. 当每个人都确实要对你不利时,偏执就是一个好主意。46. 通过早崩溃、在问题现场找到和诊断问题要容易得多。47. 如果有一个错误,就说明非常、非常糟糕的事情已经发生了。48. 如果传入你的过程的指针决不应该是NULL,那么就检查它!49. 不要用断言代替真正的错误处理,断言检查的是决不应该发生的事情。让断言开着。50. 嵌套的分配1)以与资源分配的次序相反的次序解除资源的分配。这样,如果一个资源含有另一个资源的引用,就不会造成资源被遗弃。2)在代码的不同地方分配同一组资源时,总是以相同的次序分配它们。这将降低发生死锁的可能性。51. 注重实效的程序员谁也不信任,包括我们自己,所以我们觉得,构建代码、对资源确实得到了适当释放进行实际检查,这总是一个好主意。52. 创建灵活代码的一个关键概念是数据模型与该模型的视图的分离。53. 把你的代码组织成最小组织单位(模块),并限制它们之间的交互。如果随后出于折中必须替换某个模块,其他模块仍能够工作。54. 要用元数据描述应用的配置选项:调谐参数、用户偏好、安装目录等等。55. 我们创建的不是组件,而是服务——位于定义良好的、一致的接口之后的独立、开发的对象。56. 批判地思考所有代码,包括我们自己的。我们不断地在我们的程序和设计中看到改进的余地。57. 只要你在制作代码,你就应当记住,有一天你必须对其进行测试。58. 怎样深思熟虑的编程1)总是意识到你在做什么2)不要盲目地编程3)按照计划行事4)依靠可靠的事物5)为你的假定建立文档6)不要只是测试你的代码7)为你的工作划分优先级8)不要做历史的奴隶59. 注重实效的程序员几乎每天都要使用:估计算法使用的资源——时间、处理器、内存等等。60. 常识估算1)简单循环2)嵌套循环3)二分法4)分而治之5)组合61. 无论代码具有下面的哪些特征,你都应该考虑重构:1)重复2)非正交的设计3)过时的知识4)性能62. 重构的建议1)不要试图在重构的同时增加功能2)在开始重构之前,确保你拥有良好的测试3)采取短小、深思熟虑的步骤:把某个字段从一个类移往另一个,把两个类似的方法融合进超类中63. 针对合约进行测试,这将告诉我们两件事:代码是否符合合约,以及合约的含义是否与我们所认为的一样。64. 以下陈述是好的需求:1)只有指定人员才能查看员工档案2)气缸盖的温度不能超过临界值,该值因引擎而异3)编辑器将突显关键词,这些关键词根据正在编辑的文件的类型确定65. 要创建并维护项目词汇表,这是定义项目中使用的专用术语和词汇的地方。项目的所有参与者,从最终用户到支持人员,都应该使用这个词汇表,以确保一致性。66. 编写规范是一项重要职责。67. 注重实效的程序员批判地看待方法学,并从各种方法学中提取精华,融合成每个月都在变得更好的一套工作习惯。68. 一旦我们有了代码,我们就想开始进行测试。69. 怎样测试1)回归测试2)测试数据3)演练GUI系统、4)对测试进行测试5)彻底测试70. 注重实效的程序员会把文档当作整个开发过程的组成部分加以接受。不进行重复劳动,不浪费时间,并且把文档放在手边——如果可能,就放在代码本身当中,文档的撰写就可以变得更容易。71. 不应在源码注释中的一些内容:1)文件中的代码导出的函数的列表2)修订历史3)该文件使用的其他文件的列表4)文件名Tips:1. 关心你的技艺2. 思考,你的工作!3. 提供各种选择,而不是找蹩脚的借口。4. 不要容忍破窗户5. 做变化的催化刘6. 记住大图景7. 使质量成为需求问题8. 定期为你的知识资产投资9. 批判地分析你读到和听到的10. 你说什么和你怎么说同样重要11. 不要重复你自己,DRY(Don't Repeat Yourself)12. 让复用变得容易13. 消除无关事物之间的影响14. 不存在最终决策15. 用曳光弹找到目标16. 为了学习而制作原型17. 靠近问题领域编程18. 估算以避免发生意外19. 通过代码对进度进行迭代20. 使用纯文本保存知识21. 利用命令shell的力量22. 用好一种编辑器23. 总是使用源码控制24. 要修正问题,而不是发出指责25. 不要恐慌(调试第一准则)26. Select 没有问题27. 不要假定,要证明28. 学习一种文本操纵语言29. 编写能编写代码的代码30. 你不可能写出完美的软件31. 通过合约进行设计32. 早崩溃33. 如果它不可能发生,用断言确保它不会发生34. 将异常用于异常的问题35. 要有始有终36. 使模块之间的耦合减至最少37. 要配置,不要集成38. 将抽象放进代码,细节放进元数据39. 分析工作流,以改善并发性40. 用服务进行设计41. 总是为并发进行设计42. 使视图与模型分离43. 用黑板协调工作流44. 不要靠巧合编程45. 估算你的算法阶46. 测试你的估算47. 早重构,常重构48. 为测试而设计49. 测试你的软件,否则你的用户就得测试50. 不要使用你不理解的向导代码51. 不要搜集需求——挖掘它们52. 与用户一同工作,像用户一样思考53. 抽象比细节活得更长久54. 使用项目词汇表55. 不要在盒56. 倾听反复出现的疑虑——等你准备好再开始57. 有些事情“做”胜于“描述”58. 不要做形式方法的奴隶59. 昂贵的工具不一定能制作出更好的设计60. 围绕功能,而不是工作职务进行组织61. 不要使用手工流程62. 早测试,常测试,自动测试63. 要到通过全部测试,编码才算完成64. 通过“蓄意破坏”测试你的测试65. 测试状态覆盖,而不是代码覆盖66. 一个bug只抓一次67. 把英语当作一种编程语言68. 把文档建立在里面,不要拴在外面69. 温和地超出用户的期望70. 在你的作品上签名

前天看完的

近来很忙,不过还是抽时间把这本经典看完了。肯能是目前水平限制,感觉有些收获。但并不觉得裨益很多,不过这本书读起来还是很轻松的。其中收获最大的就是程序文档的可读性,还有领域语言那一章写的挺好。原来对领域语言重要性理解不太深,看完这本书后。才慢慢体会到领域语言的重要性。怪不得那么多老外热衷于研发新的语言,原来是为了解决领域语言的问题。

此书和"卓有成效的程序员"

基本上中心思想是一样的,包括一些内容,如DRY、元数据、自动化等,我先看的《卓》,如果非要说区别就是,《卓》更加生动,让人看完每一章都有跃跃欲试的冲动,而此书的作者似乎刻意不触及实例,不停的用隐喻或避免说的过于实际

有点懵

这书从图书馆慕名借来,满怀欣喜的赏读一番,发现,大部分内容都是泛泛之谈,一些经验只说而已。对于我这种初级的,甚至不能称之为程序员的人来说,还是有点遥远的,好比其中建议,每年都要学习一中新的语言来保持自己思维跟上时代,看的我满头冒汗,心里一阵惭愧,我一种语言还不能说学好呢。不过,其中介绍的一些方法还是很值得我借鉴的。估计能帮我以后少走弯路也说不定。这本书好不好,我是没有资格谈的,应该是比较适合高级程序员来阅读的。

读书笔记 《第八章 注重实效的项目》

第八章 注重实效的项目    1. 注重实效的团队    不要保留破窗户。  主动监视环境的变化。  交流,文档一致,团队的风格。  不要重复,良好的资料管理。  正交性,围绕功能而不是工作职位组织团队。  自动化,自动化办公可以提高效率。      2. 无处不在的自动化    人工流程很难确保一致性和可复制性。  可以借助于shell脚本或批处理来实现自动化。  自动化工具:cron、windows中的“at”      3. 无情的测试    考验那些薄弱的地方。    (1)测试什么?  单元测试、集成测试。  验证和校验(是否符合需求)。  资源耗尽、错误及恢复(内存、CPU、磁盘空间、系统时间、磁盘带宽、网络带宽、调色板、分辨率)  性能测试。  可用性测试。    (2)怎样测试?  回归测试。  测试数据(现实世界数据、合成数据)(大量、边界数据、特定属性)  演练GUI系统(一些自动化测试工具并不能发现一些界面上的bug)  对测试进行测试(用于测试的程序本身也可能存在问题)  彻底测试(测试各种状态的覆盖)    (3)何时测试?  越早测试越好,随时进行测试。      4. 全都是写    如果有可能,把文档放在代码当中,让文档和代码紧密结合。  把代码和文档,视为同一模型的两种视图。    代码的注释要简洁准确。      5. 极大的期望    项目是要以符合用户的期望为基础的,即便是有更强的能力制造一个更高级的产品,也不要太离谱。  可以温和地超出用户的期望,使用户惊喜而不是惊吓。      6. 傲慢与偏见    对自己的作品感到自豪。互相欣赏。

很好的书

书讲得很好,我很少做力荐,但是这本书我认为不错。马维达的翻译其他的我并不清楚,但是这本书我认为不错,没有什么明显的问题,能够翻译到这个样子,就已经非常的不错了。另外,这本书是大家的一些经验总结,我想多看看,多想想是有意义的。

读书笔记 《第一章 注重实效的哲学》

第一章 注重实效的哲学    1. 注重实效:    在思考问题的时候,把它放在更大的语境中,做出明智的决策。    (1)勇于承认无知和错误。  (2)判断风险,在可控的范围内承担责任。  (3)制定应急预案,以防不测。  (4)对一个问题多多思考,提供多种解决方案。并首先说服自己这些方案的可行性。  (5)不要用蹩脚的接口掩饰。      2. 软件的熵    “熵”是某个系统中无序的总量。热力学定律指出,宇宙中的熵倾向于最大化。  当软件中的“无序”增长时,称之为“软件腐烂”(software rot)。    “破窗户理论”:研究者们发现,一扇一直不被修理的破窗口,可以让一栋整洁完整的建筑快速变成一副要被废弃的样子。    不要遗留问题,发现一个解决一个,如果不能及时解决,至少要把代码关掉。以保证有序。  如果容忍“破窗户”的存在,就会降低整体代码的质量,当代码中“破窗户”越来越多,被后续代码覆盖,越来越难以企及,人们就会失去修改它们的信心,从而影响后续开发的质量。      3. 催化    有时候,明确需求,制定项目的计划,并不难,虽然它们必须使用较长的时间。  但是当需要付诸实践的时候,团队中往往意见不一,又会出现很多评估委员会带来干扰。  这时候只要认真做出一个正确的,高效的功能模块,让所有的工作有一个出发点,  那么接下来就像水蒸气凝聚在尘埃上面一样,一朵云很快就会出现了。    用催化的手段,解除团队的迷惘,找到方向。    催化的副作用:  催化虽然找到了出发点,但是不能忘记,要着眼于大的图景。  催化只是帮助项目启动的手段,过于专注于此,很容易偏离方向。不要忽略些许的偏差,积少成多。    所以,在使用催化剂的时候,必须基于客观的决策。      4. 做到足够好    不可能开发出十分完美的产品。    质量、时间、成本上的考量。来自客户、销售人员、公司决策层的意见。  在上述各种压力面前,不要慌张地一味修改和增加、设定不合理的紧迫的时间节点。    系统的范围和质量,是系统需求的重要部分。    如果用户可以早一些使用一个不是很完善的产品(毛边产品),那么他们的一些反馈将会把产品引导向更好的最终方案。  这也就是很多企业安于发布一个他们明知道不完美的产品的原因。    因此,提倡模块化交付使用。      5. 知识资产    程序员所用有的知识,是自身价值的体现。  而由于工作的特殊性,知识很容易变得陈旧,贬值。    因此,为了保持技术水平,知识应该像资产一样投资和管理:  (1)定期投资:不时学习新知识。  (2)多元化:接触多种知识。  (3)风险管理:不要把所有的技术放在同一个篮子里。  (4)低买高卖:新兴技术很可能会流行。  (5)重新评估和平衡:温故知新。    每年至少学习一种新语言。每季度阅读一本技术书籍,也要阅读非技术书籍。  上课,参加本地组织。体验不同环境,跟上潮流。    判断性地思考:批判性地分析所学到的知识,不要盲目跟从。(商业宣传具有蒙蔽性)    (本书推荐语言:smalltalk、Squeak、Eiffel、java)      6. 交流    (1)弄清楚想要说些什么,列出大纲,不断提炼,然后再充实内容。  (2)了解听众的需要、兴趣、能力。  (3)选择时机。  (4)选择形式。有人喜欢电话、有人喜欢面谈、邮件、或打印文档。  (5)美观的书面文档。  (6)让听众参与进来。  (7)做倾听者。  (8)礼貌地回复他人。

典型的炒作

没有什么新鲜的内容 泛泛而谈 翻译也一般 当初买是被csdn的宣传蒙蔽 作为程序员的催眠书 效果不错

内容一般,翻译马马虎虎。适合上厕所的时候阅览。

本书属于技术书(说它算技术书都勉强)中的地摊文学水平,“高大全”、泛泛而谈,不要指望全书能带给你技术上有什么实质性的提升,或者编程想法上的感悟。这两分纯粹是重书的印刷质量。适合上厕所无聊时候解闷儿。看网上评价的天花烂坠又看了看目录,感觉貌似很有很容的样子,就买了一本,书送到时候翻开前面一堆不知道是哪个企业的一些好像是程序员的人写了一些乱七八糟的书评我就估计此书要悲剧。一小时的时间就能粗略的看了此书的1/3,因为此书实在是太没营养和内容了,根本不用思考什么就能快速的阅读,实在都懒得往厕所放了。电子工业出版社的书的要印刷质量还是不错,不过用在这种书上纯属浪费了。书虽然看起来很厚,其实没什么内容,跟排版有直接关系。。本书属于那种说了一大堆貌似很有道理但你看完之后有感觉他好像什么都没说。我实在很不理解这种书如何能获得如此高的评价⋯⋯

不错的书

很高兴看到自己的很多习惯和书里提到的一致,比如测试,自动构建等,可能这些都是敏捷开发的原型吧,还喜欢书里推荐的一些工具,比如emacs。但对于注释那一段表示不赞同,好的代码应该只有很少的注释或者没注释。

曳光弹与原型的区别

看到“曳光弹” 和 “原型与便签”了,好书!回答了自己一直以来在需求建模是否纠结细节问题的很好回答,纠结细节者为“曳(ye 4)光弹” ,而"原型”的目标,不是代码而是与用户交流时的反馈。而“曳光弹”可是交付代码的一部分,而“原型”的代码与交付的产品没有任何关系。下一步:书中详细描述了这两种的使用范围和构建后的使用注意,思考一下这个,然后在反思反思之前的问题再来评论。

做个程序员必须看的书

绝对的好书,做个程序员一定要看下,虽然不能让你成为高手,但是可以让你变得职业一点.觉得现在的社会最缺少的就是职业精神了

菜鸟的指南针

很久以前买的这本书,忘记在哪里看到这部书的推荐了,有大牛很卖力的推荐,于是去买了一本。坦白讲,那个时候自己是完完全全的菜鸟,从大学里出来,除了会编程啥也不懂,这本书在当时真的是指路明灯。书中的道理很浅显,可是对于菜鸟却是至理名言。基本为你勾勒了一个成熟软件程序员专家所需要的所有特性。我自觉地获益颇多,其中很多事情,要么在当时是自己没有想到的,要么是发生了,自己没有注意的等等。给我影响很大。当然,有些自以为是的"大牛"是鄙视这些的,因为看起来不够高深,随便吧,反正它讲的是从小工到专家,我是从小工过来的,那些凭空冒出来的“专家”不看也罢。

力荐程序员修炼之道

这本书是同事推荐让我看的,看了前几章后,发现以前错过了这么好的一本书,遂用了20天时间,利用上班地铁和晚上睡觉前的时间一口气把它看完了。这本书讨论的范围比较广泛,从程序员个人的工作态度,到软件工程,再到项目管理,团队,程序编码都有涉及。我最有感触的是作者讨论的“不要靠巧合编程”,因为当时我的工作中正在为相关的问题而苦恼。本书所介绍的内容虽然没有过多的讨论细节,却有"点化"和让你“顿悟”的功效,如果有一定工作经验的人,应该读起来体会更多。而且书后还列举了丰富的参考和延伸的阅读资源,可以根据作者给出的关于阅读这些资源的建议,继续深入学习所列的资源。的确就像作者所说的,如果他去讨论每个部分的细节,那这本书至少有现在的10倍厚,而且很多细节其他的数据和网络资源已经有详细的描述。顺便说一下,这本书的中译本,个人认为翻译的可以,行文还比较流畅,这是自看过侯捷翻译的C++的书后,我感觉翻译的还行的第二本书。

背景很重要的

完整的看过 ,感觉很不错.可能是背景的原因,感觉如果和 the art of unix programming 结合看的话会更能够理解透这些原则.

本书需要达到一定的高度之后才能看

被推崇的书,这本书是在经历了很多问题之后,读起来有共鸣的感觉的书,本书从学习角度来说,没有很大的实际意义,因为作者已经是在高屋建瓴了,当你能真切感受到作者的思想时,你其实也已经达到了这本书的作者的高度。

千年问题到底是谁的责任

P169" 人们常常因2000年问题指责短视的程序员,他们在大型机的内存比现代的电视遥控器的内存还少的时代拼命节省几个字节。但这并不是那些程序员的错,实际上也不是一个内存使用问题。如果要说,那也是系统分析师和设计师的错。Y2K问题的出现有两个主要原因:没有超出当时的商业实践往前看,以及对DRY原则的违反。 "P170“‘看远些’是要求你预测未来吗?不是。它意味着生成这样的陈述:系统积极的使用DATE抽象。系统将一致,普遍地实现DATE服务,比如看、格式化,存储,以及数学运算。需求将只规定要使用日期。它也许会示意,可以对日期进行某些数学运算。它也许会告诉你,日期将被存储在各种形式的辅助存储器上。这些陈述是关于DATE模块或类的真正的需求。”【popexizhi:自己一直以来都在想这个Y2K问题到底是谁的错误,刚才go了一下发现2038年也是一个类似的问题,不过是一个起源是1960,一个是1970。好吧!我开始没有想到这个是系统分析师和设计师的问题,但是Hunt 和Thomas 说的有道理,无论借口是什么,这两个职位是对未来负责的,不是吗?也许他们都给出过警告,但现在也只是看到这里。随着离散对模拟的广泛使用,这种问题应该在人本身的惰性下只会多不会少了。:)】

读书笔记 《第六章 当你编码时》

第六章 当你编码时    1. 靠巧合编程  有些情况下,程序只是由于一些偶然因素才运行得不错。这些程序没有在更极限的边界情况、或是一个新的环境、一个新的扩展下接收考验,甚至没有经过程序员自己的仔细斟酌,这是危险的。    一些约定上的误解、不规范的测试、文档中隐含的动作,都使程序成为一个巧合的短暂成功。    一些有效编码的建议:  <a> 时刻意识到在做什么。  <b> 不要盲目编程。要按照计划行事。  <c> 依靠可靠的事物,为所有的假定建立文档。  <d> 设定工作的优先级,注重难点和基础。  <e> 不要让已有的代码支配将来的代码,勇于改变。      2. 算法的速率  通常一个应用中输入的规模会影响到算法的效果。输入越多,越是消耗资源。但是多数时候这种关系并不是线性的。    O()表示法  O(n*n)表示随着输入数量的增长,运算消耗将会成平方增长。  当n不断变大时,O()中一些低阶项可以忽略,比如 O(n*n/2+3n) 和 O(n*n) 等价。    O()表示法只能表示一种输入量和运算成本之间的关系,并不能表达实际运算速度的优劣,可能O(n*n)比O(n)还要快。    常用模型:  <a> 简单循环:O(n)  <b> 嵌套循环:O(n*n)  <c> 二分法(比如二叉树搜索):O(lg(n))  <d> 分而治之(把输入分成两部分,分别处理后再合并在一起,比如快速排序):O(nln(n))  <e> 组合(考察事物的可能组合方式):阶乘,失去规律控制。    如果应用的输入是取决于外部输入的,那么即便是简单的循环,都应该仔细考虑使用的资源。嵌套循环更加如此。设法找到低阶的算法来替代高阶的算法。    如果应用的输入是可控的,低阶算法不一定优于高阶算法,尤其是当低阶算法中有耗费资源的内循环时。  因此对估算的测试十分重要,牢记要注重实效。      3. 重构  与建筑相比,软件更像是园艺,更加有机,富于变化。    当代码出现了一下问题,就需要重构:  <a> 重复。  <b> 非正交的设计。  <c> 过时的知识。  <d> 性能。    时间压力并不应阻止重构,花在修补问题上的功夫将远远超出重构的工作量。  重构要及早进行、经常进行。    重构也是一项需要慎重、深思熟虑进行的活动,只有在对项目有了更深的理解、知识基础或需求发生了变化时,重构才更有意义。    重构时应该注意:  <a> 不要在重构的同时增加功能。  <b> 重构前后进行良好地测试,保证重构结果的正确。  <c> 小改动,深思熟虑。不要把程序撕毁。  <d> 修改所有相关依赖的部分。      4. 易于测试的代码  软件应该被模块化,且在集成前,每个模块都应该可以被单独测试质量。    单元测试:在隔离状态下,对每个模块进行测试。单元测试的辅助设施代码可继续用于系统集成测试。  单元测试的代码应该放在一个与测试对象临近的位置。这样单元测试的代码可以做为例子来说明模块的用法。也方便构建回归测试。    针对合约进行测试:根据合约编写测试用例,确保单元遵守其合约。    测试程序应该有以下功能:  <a> 指定设置和清理。  <b> 选择个别或所有测试方法。  <c> 分析输出的正确性。  <d> 标准化的故障报告。    软件发布之后,可以通过日志、定义热键、诊断控制窗口等方法,来在实际应用环境中进行测试。      5. 邪恶的向导    供应商提供的各种编程向导虽然十分快速,但是它屏蔽了太多细节,以至于一旦出现问题,很难入手解决。    使用向导,要理解向导产生的代码。因为向导产生的代码并不是模块化的,它们和我们自己的代码混杂在一起。

这书名译的,不是一般的烂,可内容不错.

于代码大全,的角度和表达方式有所不同,推荐给不同思维方式的朋友,用不同的思维方式去看看,程序员一样要注重编程心理学啊.呵呵.

每个程序员都需要好好读读

觉得每个程序员都应该读一读这本书,实在是够经典。以这种厚度,写出这么深的道理,又能够处处结合实践,真不容易。   逐页读来,常常有拍案而起的冲动,曾经摔过的那些跟头,原来已经有人摔过了,并且总结出了经验教训,给出了解决之道!   只是如果自己没摔过,怕不容易能找到共鸣。

不要不懂装懂

这本书翻译很好。当然,由于文化背景的原因,有些东西,本来很流畅可读的,译成中文,就不那么生动了,这也是事实。不过,不能怪译者,目前的水平已经难能可贵了。前人早已说过,Poetry is what gets lost in translation.(Frost?)注意,我是此书出版社的竞争者,完全没有必要不好说好的。书的内容其实很深刻,也很精彩,只是有些章节、原则没有展开讲而已,但是如果你细细琢磨,所获必多。有人说什么作者不是搞计算机的,简直是笑话。估计人家编写的代码比你读过的都多得多。我接触过的程序员中,自己明明是井底之蛙,却以为已经老子如何如何的,不在少数。此书中的知识涉及之广,远在《代码大全》之上(Steve McConnell关注的是构建,也就是源码的实现以及最相关的东西),说什么此书很快就读完了,没什么东西之类的人,要么是你还需要学习如何读好书,要么就是你甚至还没有到书中的journeyman(书中译为小工,可以再斟酌)的层次。

那些成长付出的代价

在你走向任何人,告诉他们为何某事做不到、为何耽搁、为何出问题之前,先停下来,听一听你心里的声音。与你的显示器上的橡皮鸭子交谈,或是与猫交谈。你的辩解听起来合理、还是愚蠢?在你老板听来又是怎样?http://wenku.baidu.com/view/6a9cbf22482fb4daa58d4bc2.html

绝对是程序员的必读之书

绝对是程序员的必读之书,从小工到专家,受益匪浅。。涵盖的主题从个人责任、职业发展,知道用于使代码保持灵活、并且易于改编和复用的各种架构技术,利用许多富有娱乐性的奇闻轶事、有思想性的例子及有趣的类比,全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。

读书笔记 《第五章 弯曲或折断》

第五章 弯曲或折断    本章旨在探讨,怎样生产出灵活、柔软的程序。    1. 解耦与得墨忒(tei)耳法则    在使用对象内部的某个属性时,不要用贯穿的方法去直接读取,应该使用一个包装过的读取函数。    得墨忒耳法则规定,某个对象中的任何方法内部,都应该只调用以下内容:  <a> 它自身。  <b> 传入该方法的任何参数,但不包括参数对象的属性。  <c> 方法内部创建的任何对象。  <d> 任何直接持有的组件对象,比如局部变量。    虽然使用这种方法,可以有助于减少错误,便于维护,但是要编写大量的包装方法,产生额外的运行时代价。  因此很多时候都需要在设计时平衡正反两方面的影响。  反规范化:违反规范化原则,以换取速度。      2. 元程序设计    使用元数据进行动态配置:  程序在运行时读取本地配置信息对自身的行为进行控制,而不要在编译时定义程序的动作。  元数据用于描述应用程序的配置选项(如使用.ini文件对程序进行初始化)。    元数据驱动:  代码中提供抽象的功能,元数据中定义程序的运行细节。(即代码中定义程序能做什么,元数据中定义程序怎么做。)  <a> 迫使开发者进行解耦。  <b> 迫使开发者推迟细节处理,专注于健壮、抽象的结构设计。  <c> 不用重新编译,通过元数据就可以定制功能。    商业逻辑:  商业政策和规则更有可能发生变化,需要一种灵活的格式进行维护。  使用元数据、小型语言、专家系统,都可以用于定义商业逻辑。      3. 时间耦合    程序运行中,有两个重要的时间概念:并发和次序。  在项目的设计阶段,人们的设计往往是线性的,先做这个,后做那个。  我们应该容许并发,考虑解除任何时间或次序上的依赖。  这样有助于减少项目开发过程中的任何时间依赖:工作流、架构、设计、部署。    (1)工作流:  借助UML活动流图,找出什么可以在同一时间发生,什么必须以严格的次序进行。    (2)用服务进行设计:  把功能理解为一个个独立的服务,这些服务位于定义良好、一致的接口后面,并发地处理事物逻辑。    (3)为并发进行设计:  对任何全局或静态变量加以保护,使其免予并发访问。  设计更整洁的接口,以便于并发调用。    (4)部署:  一旦架构具有了并发的特性,那么部署就可以更加灵活多变了。      4. 模型、视图、事件驱动    把程序划分成模块,明确责任,有助于开发和维护,减少错误。  模块之间的数据同步也需要进行严格的范围控制。    (1)事件:  使用事件,使对象之间的耦合尽量减少。  事件触发者不需要了解接收者的情况,多个接收者互补干扰地处理各自的事务。    (2)发布和订阅:  发布/订阅协议可以准确的把事件发送给需要的对象。  订阅方先向发布方注册,发布方一旦产生事件,就会按照名单来通知订阅者。    (3)MVC模式:  <a> 数据模型:资源信息的数据格式。  <b> 视图:数据的显示表现(图表、文字表格)。  <c> 控制器:控制数据在视图中的显示逻辑(排序、缩放、等),并向模型提供新数据。既向模型,也向视图发布事件。    利用事件驱动,我们可以把数据模型和视图,数据模型和控制器分离开来,从而实现更强大的灵活性。但是视图和控制器是具有耦合特性的。    (4)模型──查看器网络  在视图的上层再构建一个查看器,查看器可以有多种形式:报告脚本、视频字幕、动态网页等。  查看器是抽象的,模型与查看器之间都用事件驱动。  这样一个模型可以有多个视图和查看器,一个查看器也可以对应多个模型。    虽然事件驱动可以解除一些耦合,但是监听者和事件发布者之间还是必须有一些相互了解,比如公共接口的定义。      5. 黑板    黑板系统完全解除了对象之间的耦合,提供一个“论坛”,知识消费者和生产者进行匿名、异步的交换数据。    分布式类黑板系统:JavaSpaces和 T Spaces。  以键值对模型为基础(元组空间)。    这种系统可以在黑板上存储Java对象。通过字段匹配、子类型匹配进行查找。也可以订阅事件通知。    黑板系统的基本特性:  <a> 查找并获取数据对象。  <b> 公布数据对象。  <c> 取出并移除数据对象。  <d> 当有制定数据对象写入时,通知订阅者。    黑板系统的优点是,所有使用者与黑板之间,有单一、一致的接口。  在很多应用中,各项工作的前后顺序可能不固定,就会出现许多种工作流。用黑板可以协调工作流,忽略前后顺序。

态度、观念、习惯,程序员的养成

记得四年前刚开始工作时从公司拿到的第一本书,就是这本《程序员修炼之道》(英文版),作为新入职员工study group的学习材料,当时在senior engineer带领下和其他同事一起学习了这本书。虽然之前就听说这是一本好书,当时看的时候也只是觉得讲的都有道理,但这些是很自然的啊,干吗花这么大的篇幅说来说去?所以只是囫囵吞枣地翻过也就扔在一边了。之后也看过很多类似的书籍,《程序员修炼之道》也一直是公司新人的必备学习材料,而我却一直没再重拾这本书仔细读一遍,直到最近周筠老师发给我中文电子版,才又从书架上翻出当年的英文版,对照着中文电子版仔细读了一遍。此次重读,感受颇多,也颇能理解为何公司一直选用此书作为新人教材。这本书里虽只包含了很多看似粗浅朴素的道理,实则是若干经验的心血总结。比如谁都知道不要对自己家的破窗户置之不理,可实际中听到太多的妥协:这个代码已经这样了,只能继续在上面贴上丑陋的workaround,这其实是一种对责任的推卸和对未来的不负责。当然现实是不完美的,有时救火队员也不得不放下破窗户而迁就其他,但作为一个pragmatic程序员,保持追求完美的心态还是很有必要的,正因为这个心态,我们才会去追求代码的优美、设计、实现的正交、DRY(Dont' Repeat Yourself)原则……关于DRY,我想说,不但don't repeat yourself,也don't report others,我们看到太多重复造轮子的故事,正如书中提到“鞋匠的孩子没鞋穿”,作为一个pragmatic程序员,合理地使用工具、库,以及自己积累的开发的轮子,会让自己的productivity不断提升。这让我想起公司里一个让人崇拜的“牛”,大家一直想把产品进程内cache做成多进程共享,正在大家讨论该怎么做的时候,“牛”人用短短几天时间已经完成了,众人再次对他又崇拜了一把。“牛”其实是备有很多现成代码的,完成这个功能只是把之前积累的封装良好的模块重用就可以了。书中推崇的另外一个方法:曳光弹。自己之前用prototype,一直犹豫于代码是否需要重用。其实原则上prototype的代码应该是抛弃型的,但有时候前期做的一些工作是为了确定方案、构建框架,而这些也是作为后期工作的基础。事实上,在项目前期值得仔细考虑的究竟是采用prototype还是曳光弹,取决于它们的适用场景(对于产品开发,曳光弹的应用场景可能相对会更多一些)。当然,对于书中提到的对知识资产的管理(知识投资)、沟通和交流的重要性等,我想这就不单单对于程序员适用了,任何一个要想有所作为的人,这些方面的重要性都毋庸多说了。而对于自动化和文本处理等方面的经验,也是很多书中都提到的经验之谈(《Unix编程艺术》、《卓有成效的程序员》等)。最后,说一下这本书的译者马维达,我最早是在学校时读过他翻译的ACE文档及相关资料,收益颇多,ACE可谓网络编程技术的集大成者,而这本《程序员修炼之道》则可谓编程的集大成者,从项目管理、软件架构和设计、代码编写和测试,各方面在此书中都有精到的阐述。此书的翻译质量应该说比较准确,基本真实地表达了原书的意思,但正因直译,有些语句可能在理解上会有一些难度(比如P146,“只要对于那些被耦合在一起的模块而言,这是众所周知的和可以接受的,你的设计就没有问题。”),不过细读这本书,这些有所晦涩的内容还是能理解的。当然,译者还是可以适当加些“译注”,让读者更容易理解,内容更顺畅的(比如书中直接用古鲁来翻译Guru,如果加上解释可能会更好;又比如Law of Demeter,原书没有解释得太清楚,如果多加些解释可能会更便于理解)。感谢周筠老师让我有机会重温这本优秀的书籍,为了完成作业,也为了让自己的认识提升。

《程序员修炼之道》书评、感受及快速参考

一、书评:值得一年读一次二、对46条建议的个人感受三、快速参考列表一、书评:值得一年读一次-------------------------------------------------------------------------------------在《代码大全》的“赞誉”中,有个叫John Robbins的同学认为《代码大全》应该每年都被读一遍。我觉得这样的建议,对于本书也同样适用。本书的很多观点与论述都是基于作者多年的经验与实践,而这种东西,是很难轻易写在书上让你理解的,更不要说获取了。只有自己亲身的经历或者体会后,才能完全读懂这本书背后的哲学,才能把那一个个的点串成一条线。 而经验是逐步积累起来的,所以,每年阅读一次都可以给你新的体会,除非,你已经完全明白了。就我而言,读下来感觉是:1. 读懂了,而且我们就是这么做的。如“shell游戏”,“源码控制”,“源程序设计”。。。2. 读懂了,但由于某些原因我们没完全那么做的。“按合约设计”,“重构”。。。3. 读懂了,但以前没意识到的。“强力编辑”,”等你准备好“。。。4. 没读懂,如”黑板“。。。当然,还包括那些我不知道的”我不知道“的内容。所以,一年后再读一遍对我肯定还是有好处的。关于翻译,感觉有太多的直译:1. guru,mantra这些专有名词的直译倒还可以接受(但是不是缺乏一个译注?或者干脆不要译);2. Demeter法则的翻译相当唐突!!!而同样有个Liskov法则,却保留了英文表示~~~3. 一些英文里的习语,或者特定于文化的用法,直译过来很是困惑,如“吃鱼”,”国王的人马“等,最好是译者能理解后以译注的方式说明一下。(当然,这个对译者要求较高,直接读英文版并不能解决这个问题)但总的来讲,对核心内容阅读影响不大。二、对46条建议的个人感受------------------------------------------------------------------------------------第1章 注重实效的哲学---------------------------1 我的源码让猫给吃了责任感与勇气,要为自己行为后果负责,勇于承认自己的弱点与过错,而不是寻找无聊的借口。2 软件的熵“熵”是某个系统中”无序“的总量,那么“软件的熵”就是软件系统中无序的总量,根据”破窗户“原理,如果你容忍了软件中一个设计或者代码的瑕疵,软件的熵必然会迅速增长,直至“软件腐烂”。一个和“破窗户”类似的故事是:一个小旅馆中的卫生间老是被旅客弄得又脏又乱,于是老板娘想了个办法,先把卫生间打扫的干干净净,然后再在台盆上插上一支花,显的十分干净与温馨,旅客们都不忍心破坏这么美好的环境,从今以后,该旅馆的卫生间总是干干净净的。给你的代码这种别人不忍心破坏的环境。3 石头汤与煮青蛙石头汤:即使你不掌握任何资源,只要你有一个好的想法,你也能成就一件事,或者一番事业。煮青蛙:项目在不知不觉中失去了控制,却没有人察觉到 --- 没有大局观! 记的公司的Niu曾经说过:既要埋头做事,又要抬头看路。很朴实,却也很精辟。4 足够好的软件在软件的质量,需求及资源(人员与时间)中作权衡时,我们一般认为质量是不可妥协的一个元素,把这三个因素作为三角形的三个顶点,为了保证三角形面积不变,当需求增加时,我们必须增加人手或时间;当时间或者人员减少时,我们也必须减少需求。但这里告诉我们,把软件的质量作为需求的一部分,因为需求是来自用户的,对于质量的要求自然也是用户说了算,如果用户基于市场,或者期限的考虑,可以接受有一些”毛边“的软件,你也别傻愣着。追求完美是个不错的理念,但要知道何时止步:那就是用户觉得足够好。况且,及早接触用户,可以给你十分宝贵的反馈。5 你的知识资产像投资金融资产一样投资知识。养成自己的学习方法与技巧,建立自己的知识管理体系。6 交流!交流的重要性不言而喻,如果你经常与他人,尤其是其他组的人打交道的话,这个感受会更加深。我想理解交流的目的很重要:交流不是为了表达你自己,不是为了说服他人,也不是为了指责与推脱,而是为了比较和谐的把事情解决。所以你要懂得倾听,要有耐心,要有礼貌,表达要清晰,态度要明确~~~第2章 注重实效的途径----------------------------7 重复的危害重复的危害在于维护的负担。DRY原则首先在于拒绝重复;其次在于鼓励可复用性。总是在一些代码中看到好几份PI常量、ASSERT宏的定义,这种重复是相当低级、不负责任的,为什么不在用之前先搜索一下呢? 就好像你在论坛提问前,先要搜索一下是否该问题已经问过一样。8 正交性不知道为什么造这么一个名词出来,在我看来,这就是独立性,内聚性,就是尽可能的减少组件间的相互依赖。9 可撤消性就是抽象性,想在D3D和OpenGL中切换,想在Oracle和SQL Server切替换?用自己的接口封装其基本概念!10 曳光弹迭代开发,并通过不断的反馈进行调整。最近在实施的Scrum,其实是同样概念的开发方法。11 原型与便笺原型是为了探索,为了验证。原型比较适用于研究型的项目,而曳光弹,则比较适用于方案比较明朗的项目。原型是用完就扔的代码,这里你可以忽略所有规范,为的只是最快的建立验证系统的原型。其实,在曳光弹方法中,对于一些局部的任务,也可以采用原型方法来验证。12 领域语言什么是领域语言,我的感觉就是比以编程语言更加直接、高级的方式来实现功能。我的经验中,用过一些:1. 通过一个xml文件来配置系统的UI,系统实现了一个解析器会在运行时解析该文件创建UI2. 用一个perl脚本把一个reg文件解析为一个头文件,然后编译进代码中,该解析过程会在prebuild时间中调用3. 其实,我觉得通过系统API完成的工作,也算是领域语言。13 估算其实,生活中,工作中到处都是估算。你去买个菜大概要多少时间,做个晚饭要多少时间,洗个澡要多少时间~~~~ 完成这个模块的分离要多少时间。 估算需要知道:要完成什么,怎么完成,怎样才算完成。书中有个观点感同身受:你估算的单位会对解读造成影响。(秒?分?。。。还是年)。要提高估算的能力,关键在于多估算,多反馈。这样有两个好处:1. 每次根据你的估算与实际花费,找出差异,你的考虑会越来越全面。2. 估过的项目多了,很多时候你就可以依靠之前的经验了。第3章 基本工具-------------------14 纯文本的威力纯文本是跨平台,跨时间(不会过时)的最佳、最简单的表示法,而且易于理解与对比。有一个常见的误解,就是觉得二进制比文本表示要安全,其实这只是更加晦涩难懂而已,要说安全,加密才是正解。程序源代码、资源文件、html、xml、注册表文件等等,用的都是纯文本,如果你要设计一个自己的文件格式、优先考虑纯文本,除非你有存储空间与效率上的考虑。15 shell游戏虽然Windows下的shell不如*nix的强大,但是对于自动化一些日常的操作已经足够了,比如我们经常会用一些bat文件来自动化配置。尤其是,当你配合shell命令和Perl这种超强的文本处理语言,你会觉得如鱼得水。 这两年的代码重构工作中,领教了不少Perl + Shell的威力!16 强力编辑用熟用精一种编辑器,的确是相当好的建议。工欲善其事,必先利其器。平时在windows下N++用的比较多一些,最近考虑切换使用一种更强大、跨平台的工具,比如Emacs或者Vi。 其实这个道理可以说的更宽泛一些,对于经常在IDE中工作的人,精通其工作的IDE,如VS就相当有用了,其效率的提升应该是成倍的。17 源码控制这个年代,相信只要是写软件的,肯定都用了SCM,我们公司用的是Perforce,很多开源项目用SVN、Mercury、或者git之类的,而CVS有逐渐没落之势。“源码让猫吃了“的情形,只发生在我大学写的程序中~~~18 调试关于调试的方法论介绍,扩展阅读可以是这本书《Debugging》:http://book.douban.com/subject/3228993/。里面“橡皮鸭”这个故事可以作为一个提醒点来提醒自己:在请教别人之前,先把问题向橡皮鸭解释一遍。其实很多时候,当你把问题理顺了,答案也就自然有了。 有过这样的经历吧:当你向同事说完你的问题后,你马上意识到了该如何解决~~~~而此时可能对方那是还没明白你在问什么 --- 这就是橡皮鸭的作用。19 文本操纵操纵文本时一种乐趣。这种乐趣是我在发现了perl以及正则表达式的强大后才体会到的。我运行shell命令然后用perl解析其输出;我可以在几分钟内解析30000多个源文件并以一种复杂的方式修改代码。那时,你会觉得自己很强大~~~很难想象,没有perl和正则表达式的日子,我是怎么过来的。20 代码生成器这其实是特殊的文本操纵,目标在于自动化工作与避免重复。Wizard其实就是一种代码生成器,Doxygen也算是一种,虽然其生成的是代码的文档。在工作中,我们做过根据一个原始的reg文件,产生一个头文件,以编译到代码中。第4章 注重实效的偏执-----------------------------21 按合约设计在写函数的时候,入口处assert输入参数,出口处返回该调用是否成功是最基本的。只是我们没有比较正式的将其称为前条件、后条件并注释出来。当然,也会在入口,出口处检查某个状态是否成立,这应该就是这里指的“不变项”。我想,明确这些概念,可以让我们在写代码的时候有比较清晰的思路来保证函数的规范性。实现一个函数的时候先思考一下,它的合约是什么呢~~~22 死程序不说谎当程序中有致命错误时,直接crash会是比较好的选择。因为这样是以最明确的方式报告了错误,便于修正。如果试图掩盖这种错误,虽然程序还是运行着,却有着潜在的危险。比如C++中两次迭代的异常会导致程序crash,如果你试图在析构函数中吞下第二个异常,其实是掩盖了错误,而不是解决了问题。与其苟延残喘的活着,不如给他痛痛快快的来一刀吧!23 断言式编程这是防御式编程的重要组成部分,如果你觉得“不可能”发生,那就用断言确保它不会发生。当然,注意这里是“不可能”发生,很多初学者很容易认为在失败的时候就assert,比如流程:为打开一个文件,如果不存在,则先创建它。那么在第一步打开文件失败时,很多人会错误的使用一个assert,而其实,这是“可能”的情况。24 何时使用异常对于错误处理的方式,异常处理比返回值判断的好处在于:减少了条件判断;把错误处理的代码集中到了一起。但是我们工作中用的最多的,还是返回值处理。在异常处理中,一个很重要的措施是保证异常抛出时,资源能被正确的释放掉,在C++中,我们可以用RAII,而在C#,或者Java中,我们可以利用finally语句。25 怎样配平资源关于资源管理的章节几个原则吧:1. 谁分配谁释放2. 先分配的后释放 --- 以防后分配的对先分配的有引用3. 在代码不同的地方以相同次序分配资源 --- 避免死锁第5章 弯曲,或折断-------------------------26 解耦与得墨忒耳法则迪米特法则(Law of Demeter),意译的话是”最少知识原则“。这里采用如此奇怪的音译显得很唐突。解耦包含逻辑解耦与物理解耦,其实关键就是一个:最少知识原则。能不知道的就尽量别知道,能不依赖的就尽量别依赖。当你写代码是发现需要再include一个头文件时:三思。27 元程序设计基础点讲,就是不要硬编码;提升点讲,就是指软件的配置信息,尽量保存在在注册表中,或者配置文件中,可以动态配置再提升点,就是软件设计中我们要封装变化,比如封装在接口之后,但如果可行,封装到代码之外才是最灵活的。28 时间耦合主要讲并发,要考虑并发,就要考虑:1. 单个操作是否足够独立2. 多个操作是否可以并行。不要只考虑程序中并发,看看你的工作中,你们团队中工作流程的并发要求。29 它只是视图MVC模式,我觉得是观察者模式的一种特殊情况。通过接口实现了具体类之间的解耦,并实现了发布/订阅的工作模式。这个大家应该都很熟悉的。30 黑板是更进一步的解耦,连Item29中需要的共同接口都解掉了。但没怎么看明白~~~第6章 当你编码时----------------------31 靠巧合编程知其然,知其所以然;能工作,要知道为何能工作;会失败,要知道为何会失败。不要靠巧合去七拼八凑。32 算法速率用大O表示法来分析算法的效率。培养一种直觉,对一些常见的算法,一看流程就能说出其大O表示,如冒泡排序O(n^2),遍历O(n)。里面提供的一张图挺不错的:http://www.flickr.com/photos/dbger/4488865262/33 重构我并不同意很多书中宣称的一定要重构,以及他们的理由。重构始终是一种艺术,你要在理想与现实之间做出一个权衡。《重构》那本书介绍了许多重构的方法。但其实我们更需要的是一个比较可靠、高效的重构器,至少C++方面做的还不够好,VS本身未提供多少,而VA插件的重构功能相当有限。34 易于测试的代码易于测试的代码会有非常简洁的接口,非常明确的约定,从而也有更好的质量。这是从比较细节的,代码的角度来看的。而从软件角度来看,就应该提供完善的log机制与诊断功能,这样才能在客户环境下精确的定位错误。35 邪恶的向导如果你只是为了编写一个测试程序,你可以不理解想到产生的代码;但是如果你需要基于向导创建一个软件,理解向导产生的代码就显得十分必要了。我想这也是为什么《深入浅出MFC》如此风行的原因吧,大家其实都意识到这个问题了。第7章 在项目开始之前---------------------------36 需求之坑试图在想在项目初期弄清需求其实是不太可能的,因为那时即使是用户,也不清楚所有的需求,因为用户对需求的理解也是一个循序渐进的过程。我比较认同Scrum中的做法,逐步迭代,让用户参与整个的过程,给出反馈,这其实也是帮用户弄清了其需求。了解用户为何要做某件事情的原因,而不是其目前做这件事情的方式。因为其可能一开始就错了,因为你可能有更好的方式 --- 你才是提供方法的那个人。 同理,在你帮助别人解决问题时,也要记得挖掘其根源,而不要跟着其方式往下走,因为他有可能从一开始就错了。37 解开不可能解开的谜题Think out of the box。转换一下思路,很有可能就会柳暗花明。38 等你准备好我们似乎很容易走在两个极端。有的时候我们太激进,还没想好就开始coding了;而有的时候却爱拖延,迟迟不肯动手,总觉得还没准备好。自己属于哪种情况,问问内心其实很容易判断,关键是如何克服自己去正确的做事。39 规范陷阱有些规范描述起来相当复杂,但做起来却十分简单。让PD费劲的在spec上写下来,再让开发费劲的去理解,实在是一种浪费。这也是在Scrum中引入User Story好处:通过交流就能解决的问题,就不要费劲去写什么spec了。毕竟,spec不是目的,只是一种手段。40 圆圈与箭头没有过时的方法,也没有最优的流程,关键是看你如何摸索出一套适合你们项目于团队的流程。光追求某种先进的方法,只是流于表而疏于本。again,流程不是目的,只是一种手段。第8章 注重实效的项目---------------------------41 注重实效的团队注重实效的方法适用于个人,同样适用于团队:不要留破窗户;温水煮青蛙;交流;不要重复你自己;正交性;自动化。 其中,对于项目团队的组织,以功能划分最佳,这样才具有较好的正交性。开发归开发,QA归QA,PD归PD,然后必然频繁的跨团队交流,我们公司目前正从这种方式慢慢转向Scrum团队:QA, 开发,PD同属一组,交流的效率能得到很大的提高。42 无处不在的自动化这方面,我有两条信条:1. 机器能做的事情,人就不要做2. 凡是有固定规律的事情,都可以被自动化。软件开发中的很多过程都能被自动化,我认为自动化繁琐的工作有两个好处:一个机器做的快而好,而且可重复;二是将繁琐的手工工作转化成编写自动化的程序,容易产生成就感。43 无情的测试关于测试的相当不错的论述。自动化测试基础之上发现的bug,要为其添加case,不停的”把网收紧“。但其中对于测试先行(TDD)没有特别的介绍,事实上,TDD是被认为是相当可行的一种编程方法学。44 全都是写写注释、写文档。。。关键点还是在于:1. 不要重复2. 自动化比如你需要某个DLL中的函数导出列表,不要自己维护一份(不要重复),而是写个工具从DLL中提取出来(自动化)。45 极大的期望知道用户的“期望”,不要无法达到,也不要超出太多。”温柔的超出用户的期望“或许是最好的策略。人的承受力是有个range的,不要太低,也不要太高~~~ 呃,或者,物极必反吧。46 傲慢与偏见 Sign You Work!!!让别人知道这是你的作品:荣辱与共!这会催生一种自豪感与责任感。如果你不敢在代码中签上你的名字,问问自己的内心:为什么?三、快速参考列表------------------------------------------------------------------------------------1.关心你的技艺Care About Your Craft如果你不在乎能否漂亮地开发出软件,你又为何要耗费生命去开发软件呢?2.思考!你的工作Think! About Your Work关掉自动驾驶仪,接管操作。不断地批评和评估你的工作。3.提供各种选择,不要找蹩脚的借口Provide Options, Don't Make Lame Excuses要提供各种选择,而不是借口。不要说事情做不到;说明能够做什么。4.不要容忍破窗户Don't Live with Broken Windows当你看到糟糕的设计、错误的决策和糟糕的代码时,修正他们。5.做变化的催化剂Be a Catalyst for Change你不能强迫人们改变。相反,要向他们展示未来可能会怎样,并帮助他们参与对未来的创造。6.记住大图景Remember the Big Picture不要太过专注于细节,以致忘了查看你周围正在发生什么。7.使质量成为需求问题Make Quality a Requirements Issue让你的用户参与确定项目真正的需求。8.定期为你的知识资产投资Invest Regularly in Your Konwledge Portfolio让学习成为习惯9.批判的分析你读到的和听到的Critically Analyze What You Read and Hear不要被供应商、媒体炒作、或教条左右。要依照你自己的看法和你的项目的情况去对信息进行分析。10.你说什么和你怎么说同样重要It's Both What You Say and the Way You Say It如果你不能有效地向他人传递你的了不起的想法,这些想法就毫无用处。11.不要重复你自己DRY -- Don't Repeat Yourself系统中的每一项知识都必须具有单一、无歧异、权威的表示。12.让复用变得容易Make It Easy to Reuse如果复用很容易,人们就会去复用。创造一个支持复用的环境。13.消除无关事务之间的影响Eliminate Effects Between Unrelated Things设计自足、独立、并具有单一、良好定义的目的的组件。14.不存在最终决策There Are No Final Decisions没有决策是浇铸在石头上的。相反,要把每项决策都视为写在沙滩上的,并为变化作好计划。15.用曳光弹找到目标Use Tracer Bullets to Find the Target曳光弹能通过试验各种事物并检查他们离目标有多远来让你追踪目标。16.为了学习而制作原型Prototype to Learn原型制作是一种学习经验。其价值并不在于所产生的代码,而在于所学到的经验教训。17.靠近问题领域编程Program Close to the Problem domain用你的用户的语言进行设计和编码。18.估算,以避免发生意外Estimate to Avoid Surprises在着手之前先进行估算。你将提前发现潜在的问题。19.通过代码对进度表进行迭代Iterate the Schedule with the Code用你在进行实现时获得的经验提炼项目的时间标度。20.以纯文本保存知识Keep Knowledge in Plain Text纯文本不会过时。它能够帮助你有效利用你的工作,并简化调试和测试。21.利用命令shell的力量Use the Power of Command Shells当图形用户界面无能为力时使用shell22.用好一种编辑器Use a Single Editor Well编辑器应该是你的手的延伸;确保你的编辑器是可配置、可扩展和可编程的。23.总是使用源码控制Always Use Source Code Control源码控制是你的工作时间的机器——你能够回到过去。24.要修正问题,而不是发出指责Fix the Problem, Not the BlameBug是你的过错还是别人的过错,并不是真的很有关系——他仍然是你的问题,他仍然需要修正。25.调试时不要恐慌Don’t Panic When Debuging做一次深呼吸,思考什么可能是bug的原因。26.“Select”没有问题“Select” Isn’t Broken在OS或编译器、甚至或是第三方产品或库中很少发现bug。Bug很可能在应用中。27.不要假定,要证明Don’t Assume It-Prove It在实际环境中——使用真正的数据和边界条件——证明你的假定。28.学习一种文本操纵语言Learn a Text Manipulation Language你们每天的很大一部分时间处理文本,为什么不让计算机替你完成部分工作呢?29.编写能写代码的代码Write Code That Writes Code代码生成器能提高你的生产效率,并有助于避免重复。30.你不可能写出完美的软件You Can’t Write Perfect Software软件不可能完美。保护你的代码和用户,使它(他)们免于能够预见的错误。31.通过合约进行设计Design with Contracts使用合约建立文档,并检查代码所做的事情正好是他声明要做的。32.早崩溃Crash Early死程序造成的危害通常比有问题的程序要小的多。33.用断言避免不可能发生的事情Use Assertions to Prevent the Impossisble断言验证你的各种假定。在一个不确定的世界里,用断言保护你的代码。34.将异常用于异常问题Use Exceptions for Exceptional Problems异常可能会遭受经典的意大利面条式代码的所有可读性和可维护性问题的折磨。将异常保留给异常的事物。35.要有始有终Finish What You Start只要可能,分配某资源的例程或对象也应该负责解除其分配。36.将模块之间的耦合减至最少Minimize Coupling Between Modules通过编写“羞怯的”代码并应用得墨忒耳法则来避免耦合。37.要配置,不要集成Configure, Don’t Integrate要将应用的各种技术选择实现为配置选项,而不是通过集成或工程方法实现。38.将抽象放进代码,细节放进元数据Put Abstractions in Code, Details in Metadata为一般情况编程,将细节放在被编译的代码库之外。39.分析工作流,以改善并发性Analyze Workflow to Improve Concurrency利用你的用户的工作流中的并发性。40.用服务进行设计Design Using Services根据服务——独立的、在良好定义、一致的接口之后的并发对象——进行设计。41.总是为并发进行设计Always Design for Concurrency容许并发,你将会设计出更整洁、具有更少假定的接口。42.视图与模型分离Separate Views form Models要根据模型和视图设计你的应用,从而以低廉的代码获取灵活性。43.用黑板协调工作流Use Blackboards to Coordinate Workflow用黑板协调完成不同的事实和因素,同时又使各参与方保持独立和隔离。44.不要靠巧合编程Don’t Program by Coincidence只依靠可靠的事物。注意偶发的复杂性,不要把幸运的巧合与有目的的计划混为一谈。45.估计你的算法的阶Estimate the Order of Your Algorithms在你编写代码之前,先大致估算事情需要多长时间46.测试你的估计Test your Estimates对算法的数学分析并不会告诉你每一件事情。在你的代码的目标环境中测定他的速度。47.早重构,常重构Refactor Early, Refactor Often就和你会在花园里除草、并重新布置一样,在需要时对代码进行重写、重做和重新架构。要铲除问题的根源。48.为测试而设计Design to Test在你还没有编写代码时就还是思考测试问题。49.测试你的软件,否则你的用户就得测试Test Your Software, or Your Users Will无情地测试。不要让你的用户为你查找bug。50.不要使用你不理解的向导代码Don’t Use Wizard Code You Don’t Understand向导代码可以生成大量代码。在你把它们合并进你的项目之前,确保你理解全部这些代码。51.不要搜集需求——挖掘它们Don’t Gather Requirements – Dig for Them需求很少存在于表面上。它们深深地埋藏在层层假定、误解和政治手段下面。52.与用户一同工作,像用户一样思考Work with a User to Think Like a User要了解系统实际上将如何被使用,这是最好的方法。53.抽象比细节活得更长久Abstractions Live Longer than Details“投资”于抽象,而不是现实。抽象能在来自不同的现实和新技术的变化的“攻击”之下存活下去。54.使用项目词汇表Use a Project Glossary创建并维护项目中使用的专用术语和词汇的单一信息源。55.不要在盒子外面思考——要找到盒子Don’t Think Outside the Box – Find the Box在遇到不可能解决的问题时,要确定真正的约束。问问你自己:“它必须以这种方式完成吗?它真的必须完成吗?”56.等你准备好在开始Start When You’re Ready你的一生都在积累经验。不要忽视反复出现的疑虑。57.对有些事情“做”胜于“描述”Some Things are Better Done than Described不要掉进规范的旋涡——在某个时刻,你需要开始编码。58.不要做形式方法的奴隶Don’t Be a Slave to Formal Methods如果你没有把某项技术放进你的开发实践和能力的语境中,不要盲目地采用它。59.昂贵的工具不一定能制作出更好的设计Costly Tools Don’t produce Better Designs小心供应商的炒作,行业教条、以及价格标签的诱惑。要根据工具的价值判断它们。60.围绕功能组织团队Organize Teams Around Functionality不要把设计师与编码员分开,也不要把测试员与数据建模员分开。按照你构建代码的方式构建团队。61.不要使用手工流程Don’t Use Manual ProceduresShell脚本或批文件会一次次地以同一顺序执行同样的指令。62.早测试,常测试,自动测试Test Early. Test Often. Test Automatically与呆在书架上的测试计划相比,每次构建时运行的测试要有效的多。63.要通过全部测试,编码才算完成Coding didn’t Done Until All the Tests Run就是这样。64.通过“蓄意破坏”测试你的测试Use Saboteurs to Test Your Testing在单独的软件副本上故意引用bug,以检验测试能够抓住它们。65.测试状态覆盖,而不是代码覆盖Test State Coverage, Not Code Coverage确定并测试重要的程序状态。只是测试代码行是不够的。66.一个bug只抓一次Find Bugs Once一旦测试员找到一个bug,这应该是测试员最后一次找到它。此后自动测试应该对应其进行检查。67.英语就是一种编程语言English is Just a Programming Language像你编写代码一样编写文档:遵守DIY原则、使用原数据、MVC、自动生成,等等。68.把文档建在里面,不要拴在外面Build Documentation In, Don’t Bolt It On与代码分离的文档不太可能被修整和更新。69. 温和地超出用户的期望Gently Exceed Your Users’ Expectations要理解你的用户的期望,然后给他们的东西要多那么一点。70.在你的作品上签名Sign Your Work过去时代的手工艺人为能在他们的作品上签名而自豪。一夜应该如此。检查清单71.要学习的语言厌倦了C、C++和JAVA?试试CLOS、Dylan、Eiffel、Objective C、Prolog、Smalltalk或TOM。他们每一种都有不同的能力和不同的“风味”。用其中的一种或多种语言在家里开发一个小项目。72.WISDOM离合诗What do you want them to learn? 你想让他们学到什么?What is their interest in what you’ve got to say? 他们对你讲的什么感兴趣?How sophisticated are they? 他们有多富有经验?How much detail do they want? 他们想要多少细节?Whom do you want to own the information? 你想要让谁拥有这些信息?How can you Motivate them to listen to you? 你如何使他们听你说话?73.怎样维持正交性设计独立、良好定义的组建。使你的代码保持解藕避免使用全局数据重构相似的函数74.应制作原型的事物构架已有系统的新功能外部数据的结构或内容第三方工具或组建性能问题用户界面设计75.架构问题责任是否得到了良好定义?写作是否得到了良好定义?耦合是否得以最小化?你能否确定潜在的重复?接口定义和各项约束是否可以接受?模块能否在需要时访问所需数据?76.调试检查清单正在报告的问题是底层bug的直接结果,还是只是症状?Bug真的在编译器里?在OS里?或者是在你的代码里?如果你向同事详细解释这个问题,你会说什么?如果可以代码通过了单元测试,测试是否足够完整?如果你用该数据单元测试,会发生什么?造成这个bug的条件是否存在于系统的其他任何地方?77.函数的得墨忒耳法则某个对象的方法应该值调用属于以下情形的方法:它自身传入的任何参数它创建的对象组件对象78.怎样深思熟虑地编程总是意识到你在做什么不要盲目地编程按照计划行事依靠可靠的事物为你的假定建立文档不要只是测试你的代码,还要测试你的假定为你的工作划分优先级不要做历史的奴隶79.何时进行重构你发现了对DRY原则的违反你发现事物可以更为正交你的知识扩展了需求演变了你需要改善性能80.劈开戈尔迪斯结在解决不可能解决的问题时,问问自己:有更容易的方法吗?我是在解决正确的问题吗?这件事情为什么是一个问题?是什么使它如此难以解决?它必须以这种方式完成吗?它真的必须完成吗?81.测试的各个方面单元测试集成测试验证和校验资源耗尽、错误及恢复性能测试可用性测试对测试自身进行测试

中文版勘误:88页,21节“按合约设计”

今天下午重读此节中文版,感到了一个认识上的冲突:断言失败到底是bug(缺陷),还是不一定是bug(缺陷)?正确的理解当然是,断言失败是bug(不是error),是需要修改源码,并重新编译发布的。中文版88页原文把概念完全说反了,刚好手上有英文版,比对发现是翻译错误。希望对新手,和喜爱这边书的朋友们,在读到此处时能消解困扰。本人也是很喜欢此书中文版。中文版原文:不管发生什么,不要误以为没能履行合约是bug。它不是某种决不应该发生的事情,这也就是为什么前条件不应被用于完成像用户输入验证这样的任务的原因。英文版原文:What ever happens,make no mistake that failure to live up to the contract is a bug. It is not something that should ever happen, which is why preconditions should not be used to perform things such as user-input validation.更正后:不管发生什么,不要弄错了(注1):没能履行合约是bug。它是决不应该发生的事情(注2),……。注1:在中文里,“不要误以为”,其实和“不要以为”是一个意思,“误”只修饰动词“以为”,并没有改变“以为”。注2:此处译者把ever看成了never。

程序员内功辅导手册

记得第一次接触内功心法之类的书籍是在大三时候。有一天逛学校后边的华储计算机书店,恰好碰到《The Art of UNIX Programming》促销,于是随便买来,在厕所看完了。现在想想,当时并不能看懂其中大多数的东西,但还是被大师的风范所感染。比如现在每次给新员工培训时候都会提一下的K.I.S.S,比如不要重复发明轮子…… 都是从这本书里第一次接触到的。后来陆陆续续读了《The Productive Programmer》、《Becoming A Technical Leader》、《Programming Pearls》以及这本《The Pragmatic Programmer》。随着自己工作中写更多的代码,碰到更多工程上、沟通上、项目管理上的问题,越发觉得大师们的精髓思想是那么的有穿透力。他们从大量实践中积累出的经验,源于生活高于生活的见解,直接或间接的影响着我。使我成为一个更会编码、更会沟通、更有实效的人。而这本书,我感觉是其中最贴近程序员本身日常工作,最实用,最好用的一本书。作者不但在项目管理,软件架构和设计,代码编写和测试方便都有精到的见解,更难能可贵的是能把这些见解用平实和幽默的语言写出来。我感觉里面对任何一个主题的探讨都恰到好处,不会浅尝辄止的隔靴搔痒,也不会像很多书一样,铺很多代码在上面占用篇幅。作者更多的是结合自己的丰富经验,精到滴给出自己的建议,恰好能点出程序员容易调入的陷阱,给出提升的套路和心法。书中的练习题也颇有点意思,虽然不难,但足够启发读者深入思考。还有不时出现的tips,极其精炼,又极其到位。将其中任意几条用来改善自己的工作,相信对于一个初级或者中级的程序员来说都是不小的收获。我随便摘抄几个:DRY - Don't Repeat Yourself.不要重复你自己语言的界限就是一个人的世界的界限。Always Use Source Code Control总是使用源码控制Don't Assume it - Prove It不要假定,要证明Write Code That Writes Code编写能编写代码的代码Test Early, Test Often. Test Automatically.早测试,常测试,自动测试Gently Exceed Your User's Expectations温和地超出用户期望国外的大师级程序员不但有一股Geek风,有一些还透着很多黑客文化,甚至还神乎其神地和中国古典文化,禅,道,老子,孔子,墨子等等扯上关系。比如《编程之道》《编程之禅》等等。但这类书不知道是不是翻译的原因,总归有点晦涩难懂,且和大多数的中国程序员的经历还是有很大的差别,读起来不是那么有共鸣。但是这本书显然不是这一类,虽然观点高屋建瓴,作者却总能找到平实和幽默的例子来讲述,读起来亲切和周到,让人不时会心一笑,非常愉悦。听说这本书也是"趋势科技"等公司的新人必须读物,我却觉得无论新人来是老手,读来都会颇有收获。郑重推荐。

感觉自己水平不够

这本书应该也算是名著了,大一时看的,看的是中文版,感觉不到有多大的启发,没有给我什么帮助,我甚至没有完全看完就丢在一边了。可能是水平和经验不够无法领悟其精髓,看前言里的话,似乎我得等自己水平有所提升以后找机会重读一遍。

道理浅显,可是中文翻译的真烂

英文不行,没办法,只能费劲巴活的找到这本书的中文电子版下了看看看完了发现书里的道理和经验讲得都很浅显,很实用,但是看的途中觉得有些翻译实在是拗口和蹩脚。。好点的技术文咋都是英文的,啥时候我们的前辈大牛们也能用中文写两本,让老毛子们去翻译翻译

每个刚毕业的做程序员的都应该读一下

很多东西,都会让你有开窍的感觉.好的习惯,对于程序员来说至关重要,而这本书,介绍了培养好的习惯的方向.

于我心有戚戚焉

本书原版书名为《The Pragmatic Programmer》,翻译过来就是讲求实效的程序员,这本书的内容也正是如此,阐述了如何成为一名卓有成效的程序员。中文名翻译为《程序员修炼之道》很恰当形象,因为本书可以看成是一本Pragmatic 程序员哲学书籍。这是一本读来让我感觉“于我心有戚戚焉”的书籍。虽然我不能认同书中的所有观点,但每条都能让我有所共鸣、感悟和思考。在我看来,这本书应该是每隔一段时间就拿出来重新阅读,重新在旁白处写上理解。这是一本经典书籍,值得反复阅读。篇首几位国内知名程序员写的推荐序也很不错!

经典中的经典

听说中文版翻译得不好,还好我读的是英文版。书中基本没有实际的代码示例,只有一些零碎的观点,但作者的很多建议值得仔细体会。市面上大多数编程书籍大多是讲解一些具体的实例,但此书不是一本谈论实际问题的书籍,而是一本类似于职业生涯规划的书。

靠谱的程序员都是相似的

<<The Pragmatic Programmer>>中文版的书名被译作《程序员修炼之道》,这倒和原书的副标题“From Journeyman to Master”有些贴切,按照书中的指点修炼,不说变为大师,成为一个“靠谱”的程序员应该问题不大。<<The Pragmatic Programmer>>出版于1999年,距今已有接近10年,可惜自己最近才完整看了一遍。读之前觉得认为可能会比较虚,会和不少讲软件工程和管理的书类似,讲一些大而空的问题,一些看起来绝对正确而又没什么用的废话。没想到读了开头就再也放不下了,觉得作者真是“太有才了”,随便摘录几条(有些是自己的体会):1、DRY Don't Repeat Yourself 同样的信息应该只在一处出现,不然会给以后的维护带来无穷无尽的烦恼。2、对待bug的态度有些开发人员,遇到bug,总先要辩解一下,“不可能”“不会吧”“我怎么没发现”“你操作有问题吧”,就是不想承认。有的人则是出了问题先怀疑操作系统、怀疑库函数、怀疑编译器、怀疑硬盘、怀疑网络,就是不怀疑自己写的代码有问题。当然不排除系统可能会有问题,可是这比买彩票中500万的概率还要小,还是先从自己的代码找原因吧。3、Don't Assume It —-- Prove It经常遇到这种情况,开发人员遇到了一个bug,查了一下,觉得可能是这个原因,好,马上修改代码,提交,Done!其实有很多时候bug根本没有被修正,首先要做的是重现bug,重现的步骤越简单越好,修改完再用同样的步骤,看bug是否不再出现,否则你怎么知道bug已经被fix了呢。4、Crash Early Crash, Don't Trash. 早死早托生。尽早暴露问题,而不是搞的一团糟。(这一点要辩证去看)5、Don't Program by Coincidence代码为什么正常工作?不知道!反正写了那么多,看起来是工作正常的。很多时候如果我们说不清楚,那是说明自己还没有完全理解这个问题,代码也只是幸运的运行起来了,深层的bug隐藏在里面,只是还没有暴露出来,总有一天会以更具破坏性的方式去爆发,“出来混,总是要还的”。开发人员也常有侥幸心里,有时候自己测试也遇到了问题,可是不好重现,大多数情况下又是正常的,就会想“在客户哪儿应该不会出问题”6、Ruthless Testing --- 无情测试“Extreme Programming”也有类似的口号“continuous integration and relentless testing”。“多数开发人员憎恨测试。他们倾向于小心翼翼地测试,知道代码哪儿会出问题,就下意识避开” 很多问题,只要稍微用心去测,就会测出来,而不至于到用户那儿再暴露出来。这一点也是我们需要加强的,建立测试的环境和机制,让问题尽早暴露出来。另外还有好多Tips,比如“每年学习一门编程语言,每月读一本技术书籍”“功能正交性”“破窗理论”“代码即文档”学好一门计算机编程语言真的不值得过分骄傲,可悲的是,我们往往一门编程语言也没有学习好就在简历上写着精通XX编程。为什么有的程序员,工作十年了还不开窍,仍然写不出高质量的程序,以至于哀叹程序员是吃青春饭,过了三十岁就不知道何去何从。为什么有的程序员,勤勤恳恳,却事倍功半,写出来的程序仍然七疮八孔,bug众多?想了解更多吗? 那就去读这本书吧 :) ~~

放下书中的理论才是Pragmatic

这本书看过一段时间了,一直觉得很可惜的是标题被翻译成程序员修炼之道,这个标题本身抛弃了全书pragmatic的灵魂,而这样的说法太过神话本身就不够pragmatic。想起这个词是前几天看到电影Intouchables,里面好像两次提到 Pragmatic这个词,一次是Driss不愿意把Philippe塞进面包车而指着旁边一辆玛莎拉蒂说这个怎么样,Philippe说不适合,他需要 to be pragmatic,Driss调侃笑了笑“Pragmatic?”还是拉着Philippe钻进玛莎拉蒂飙车去了;第二次是Driss找工作,简历上对 自己的评价只有一个词——Pragmatic。在Webster字典上pragmatic的定义是“dealing with the problems that exist in a specific situation in a reasonable and logical way instead of depending on ideas and theories”,差不多就是实用主义、实效的意思,我觉得这是对做工程最有帮助的词汇和思维方式,放下一切理论,从实际情况出发,发展出合理有效的方 法才会是工程实践本身。熟记书中的理论没有错,研究各种设计模式绝对有帮助,但是在实际应用的时候还是需要放下理论,需要在实践和理论之间找到 tradeoff,这才是pragmatic的关键。反过来说,评价一个软件架构、一套软件过程实施方案、一系列协同开发制度关键点还是在于他是否适合你,是否满足阶段性需求,而不是他的名气和理论价值,这才是pragmatic。PS:最近晚上在玩Diablo III,形式上跟2代差别很大,然而最大的乐趣体现在根据所拥有的装备不断的调整技能的组合搭配去build你的人物,到论坛上就发现大家的build差别还是有一些的,思路也不一样,我觉得这充分体现了游戏设计人员的设计思路,单纯去copy别人的技能搭配可能完全不适合你的装备,绝对的pragmatic,呵呵。有一系列的暴雪解密视频以及各个patch的变化过程会发现,原有的技能、符文等系统被放弃也是有原因的,就是为了保证乐趣的同时保证策略的简单,所以最后的Diablo III没有了2代复杂的技能加点、符文宝石系统,现在有的宝石镶嵌还是可逆的,更加保证了玩家在组合上的自由和随心所欲。

程序员自我提升阶段的首选书籍

其实两年之前(那是我还在上大三)就曾在书店里看到这本书,当时可能是被书名所蛊惑吧,看到"修炼之道"这四个字就感觉这本书书名太唬,拿起来翻了翻也没看到什么有关"修炼"的实质内容,于是就将它搁置了。两年的时间里,实习和工作让我积攒起了一定的代码量和项目经验,同时在这段时间里,我阅读了很多书籍,以弥补大学里不努力学习的过失。后来再次在书店看到了这本书,才发现书中的不少内容和我这两年的一些感触产生了共鸣,于是将其买下,仔细的阅读了一遍。这本书的翻译还是很不错的,个别的字眼可能比较晦涩(比如“古鲁”或是“曼特拉”之类的怪词),不过不影响整体的阅读,关键的词汇以及语句译者给出了原文,这一点是很不错的。一般来说,刚刚接触编程的人,更倾向于从具体的程序代码学习编程的理念,而不是从程序设计理论书籍去理解编程的概念。就像学习英语,在刚开始的时候,最重要的是扩大自己的阅读量和词汇量,而不是“钻研”各种奇淫技巧。所以,计算机编程的入门书籍里都包含了大量的示例代码片段,初学者通过模仿这些代码,在心里逐步建立起一个属于自己的程序设计模型。这是程序设计的第一个阶段,也就是入门阶段。在编写了一定量的代码,对编程有了一定的了解之后。逐渐的,我们开始对自己的编写的程序,以及程序设计进行反思:程序为什么要这么设计?以什么方式可以编写出更好的程序?如何在编写程序时少走不必要的弯路?这时我们最需要的,不再局限于某种语言的语法或者是xxAPI的使用方法,而是面对实际问题需要的灵活的处理方案,亦或是去理解被前辈所认可的相对正确的软件设计方法。在这时,我们处于程序员的第二个阶段,也就是自我提升阶段。当然我们也可以通过自己的摸索,逐步找到上面问题的答案,然而这样会付出很大的代价。阅读相关的书籍,可以令我们少走不必要的弯路,加快我们水平的提升速度。事实上这样的书籍并不多。The Pragmatic Programmer(以下简称TPP)这本书,就是在自我提升阶段,值得反复阅读的绝好的书籍。这本书里面涉及到了在软件开发中的方方面面:从正确的理解需求到灵活的设计实现,从估算/提升程序的运行效率到提升软件的开发效率,从程序员的自身修养到与他人交流时的tips。这本书用非常短小的篇幅,覆盖了非常大的范围(事实上,这是我看过的覆盖面最广的有关程序员技术的书籍)。传统的计算机书籍一般采用自下而上,由浅至深,循序渐进的方法来讲述计算机理论。而TPP这本书的组织结构显的比较松散,章节之间相对独立,这使得“随机阅读”成为可能:你可以随便的翻到某一章直接阅读,而有联系的章节均在每一节末尾给出。每一节里面都有一两个起到概括全文作用的Tips,这些Tips都是前辈经验的结晶,需要被牢记。和代码大全2里的Checklist相类似,TPP把全书出现的70个Tips整合到一起,放在了书末尾,以便查阅。然而,由于篇幅所限,TPP在介绍程序设计的理念及原则时,都是"点到为止",也就是说,TPP只提供了一个通往成为注重实效的程序员的前进方向,而具体的细节,则需要你在工作中,或者进一步阅读相关书籍来把握。因此我在这里提供一些值得阅读的后续书籍:编写程序:程序设计实践(The practise of programming)从各个方面,讲述了如何编写正确、优美的程序交流:人性的弱点,这个... 不用多说了吧,和编程无关,但是程序员应该读读它,毕竟我们不只和计算机打交道算法速率和估算:编程珠玑(Programming pearls)是介绍编写实用高效算法和正确程序的最好的书籍生产效率:卓有成效的程序员(The productive programmer)里提供了很多实用的小工具,以及提升编程效率的具体途径。软件构建:代码大全2(Code complete 2nd edition),超级经典的软件构建过程全书,从下至上介绍了软件构建过程中的大量使用技巧和细节。重构:重构-改善既有代码的设计(Refactoring- refactoring improving the design of existing code)阐述了重构的理念,并提供了大量的重构技巧。编程规范:.Net设计规范(Framework Design Guidelines)一书以微软.Net Framework开发团队的视角,提供了大量.Net编程的实用规约(Convention)下面是对本书翻译的一点小建议:古鲁这个词在英文中是Guru,这个词汇来源于印度,意为宗教领袖,后来被引申为计算机领域的大师。个人认为在这里音译Guru显得很诡异,翻译成"大师"显得更为合适。(Head First 设计模式一书也是这么翻译的)曼特拉这个词在英文中是Mantra,这个词汇同样源于印度,意为教义。译者同样使用了音译,个人认为翻译成"信条"更为合适接下来是对电子工业出版社的一些建议:个人感觉自从07年下半年到现在,电子工业出版社就没再引进过很好的国外计算机图书了,希望电工社能注意到这一点。希望电工社可以引进下面这两本书:http://www.amazon.com/Computer-Systems-Programmers-Perspective-2nd/dp/0136108040深入理解计算机系统第二版,此书就不用多介绍了吧,的最好的计算机系统导论教材。http://www.amazon.com/Programming-Language-Pragmatics-Third-Michael/dp/0123745144程序设计语言-实践之路第三版,此书的第一版和第二版都是电工社出版的,我看过第二版,无论是翻译质量还是内容都很不错,希望可以尽快引进第三版(如果可能,希望还是裘宗燕老师翻译)http://www.amazon.com/Programming-Principles-Practice-Using-C/dp/0321543726/Programming: Principles and Practice Using C++ ,C++之父编写,我看过的最好的程序设计入门书籍,同时也是我看过的最好的C++入门书籍

主观偏见

这是一本为程序员写的书,是一本好书。好书应该由好程序员来读,如果你不是好程序员,或者,不想成为一名好程序员,有趣的事很多,就别在这儿浪费精力了。好程序员需要优秀的思想,这是本书第一部分主要阐述的内容。Andy和David采用调侃、隐喻等方式,讲述了现实情景中,一名好程序员应该具备的思维方式、价值观以及习惯。好程序员是需要精当的方法。这一部分介绍了一些方法,原则,或者我们可以称作“元(meta)”方法的东西。它们均来自于作者实际工作和具体实践,很生动、具体。有时你只有经过反复思考、实践,再思考之后方才能有所感悟。好程序员需要顺手的工具。程序员或开发者并不是赤手空拳的。就像作者在书的开始部分所讲“你或许感觉到同事似乎在使用一些工具,从而使他们比你效率更高”。实际上,我们并不缺少工具,问题是我们往往不知该使用哪些,在哪种情况下使用。如果你经常有这类问题,这一部分就是你的参考答案。好程序员需要最佳的实践。Dave和Andy花费了5个章节,几乎占据了整本书一半以上篇幅,详细阐述了程序员在日常工作中经常可能遇到的具体问题,并且提供了相应的指导、建议和解决方案。 完整地覆盖了程序设计、代码实现以及项目管理等有关实践的重要事项。另外,关于阅读方法,我不同意原作者可从任意章节开始阅读的建议。虽然现代认知科学一再证明,学习是一个多样化的,充满个性的过程,每一名学习者都可以按照自己的喜好,安排相应的学习方式。但这都有一个基本假设:没有上下文关联的语境问题;与此相反,在本书中,这个基本假设是不存在的。所以,对于本书,正确的阅读方式应该是按顺序阅读前三个章节,后面的章节你尽可自由。上述建议完全出自个人实际体会,主观且真实。最后,借用Kent Beck在《解析极限编程》一书中的话与大家共勉:“再全面的园艺书也无法使你成为园艺师。首先你必须从事园艺工作,其次要加入园艺者团队,然后教授别人园艺。那时你就是园艺师了”。P.S. 作为引进翻译类书籍,翻译质量当然需要关注。这一点, 图灵刘江已经给出评价(http://www.douban.com/review/1209369/),我非常认同。在此就不废话了。

读书笔记 《第四章 注重实效的偏执》

第四章 注重实效的偏执    不可能写出完美的软件,因此程序员应该针对自己的错误进行防卫性编码。    1. 按合约设计  坦率是交流过程中最好的解决办法,用合约规定双方的权力和义务。    按合约设计(DBC):  用文档记载并约定软件模块的权力与责任,确保程序的正确。    一个程序业务例程的约定包括以下方面:  <a> 前提条件:执行例程之前必须满足的条件。  <b> 后条件:例程完成后,世界的状态。  <c> 不变项:在例程执行前后,保持不变的事物。    合约中应该保持“羞怯”,尽量缩小输入和输出的数量以及范围。    对父类规定了合约之后,继承父类的子类可以有自己的合约,但至少要遵循父类的合约。  这样用户在使用子类的时候,才能感到它是父类的一种。      使用DBC的好处是,它明确了需求和约束,让程序员知道应该是什么样子,不允许是什么样子。    一些编程语言具有内置DBC支持,这样就可以用“断言”让编辑器帮助检查合约。  但是断言不能被继承,runtime系统和库的设计也不支持合约。  <a> Eiffel 和 Sather 可以自动在编译器和runtime系统中检查前提条件和后条件。  <b> C 和 C++ 可以使用Nana,用调试器在运行时监控断言。  <c> Java 可以使用 iContract ,读取注释,生成包含断言逻辑的源文件。  但是像<b><c>两种预处理实现断言的方式,可能会使项目集成变得杂乱。    断言的判断,是在调用者调用例程之后,进入例程之前,在后台进行测试的,这样就可以在出现问题之前,阻止例程的错误运行。    不变项的用法:  <a> 循环不变项:循环中经常出现计数错误,用循环不变项来确定循环的最终目标,并且每次循环都应符合这个目标。  <b> 语义不变项:定义一种在任何情况下都不可违反的需求。注意那些反复变化的政策性约定不属于语义不变项。      2. 死程序不说慌    尽早地检测问题,尽早地让程序崩溃。  例如在Java中,一个runtime中的异常发生时,RuntimeExcepton如果没有被捕捉,将渗透到程序的顶部,并留下痕迹。    当程序中发现有不应发生的事情发生之后,程序应该尽早地报警崩溃,因为如果没有及时报告,这个异常的后果可能会在之后引发“不可能的错误”。      3. 断言式编程    在编码的过程中,不要坚信某些事情是不可能发生的,就不去处理。应该用断言来确保这些事情不会发生。    例如在C++中,用于判断布尔的assert宏:  void writeString(char *string){   assert(string != NULL);   ...  }  注意在编译时,断言可能不会被执行,因此不要把必须执行的代码写在断言中。    断言只是一种异常情况的预防,不要用断言代替异常处理代码。  应该让断言失败,抛出异常,以便在某处做资源的释放等处理。    虽然断言是在检查那些“绝不会发生”的事情,但是在软件经过了测试并发布之后,断言也应该开着。    注意不要在使用断言时,引发新的危险代码。      4. 何时使用异常    引入断言的一个副作用是,当需要进行断言的事物太多,很容易让代码变得丑陋。  这就需要使用异常处理,可以对一整段内容进行异常处理,替代多个断言,使代码简洁。      5. 怎样配平资源    对于资源,要有始有终。  分配资源的例程要负责结束该资源。  按照分配资源顺序相反的顺序来结束资源。  在代码的不同地方分配一组资源时,总是用相同的顺序来分配它们。    配平资源的方法在不同程序语言中有所不同。  当一个资源生成后,如果有多个途径来释放(比如可以在正常流程后释放,也可以在异常捕获后释放),可能会在维护时带来问题。    当一个子结构创建的资源从属于一个顶层结构时,在配平时有以下选择:  <a> 顶层结构负责释放包含的子结构。  <b> 只解除顶层结构的分配。  <c> 如果包含子结构,拒绝解除自身的分配。    检查配平:  为资源编写包装,用包装检查资源的状态,比如在包装里加入计数器。

修炼

同样的信息应该只在一处出现。在所有的弱点中,最大的弱点就是害怕暴露弱点。如果你自己找不到答案,就去找出能找到答案的人。批判地分析你读到的和听到的。你说什么和你怎么说同样重要。不要依赖于你无法控制的事物属性。要让你的代码学会“摇滚”:可以“摇”就“摇”,必须“滚”就“滚”。语言的界限就是一个人世界的界限。要修正问题,而不是发出指责。编写能编写代码的代码。如果它不可能发生,用断言确保它不会发生。海森堡虫子:调试改变了被调试系统的行为。将抽象放进代码,细节放进元数据。最好的并非总是最好的。不要使用你不理解的向导代码。完美,不是在没有什么需要增加,而是在没有什么需要去掉时达到的。不要搜集需求,挖掘它们。倾听反复出现的疑虑——等你准备好再开始。对有些事情“做”胜于“描述”。不要做形式方法的奴隶。昂贵的工具不一定能制作出更好的设计。早测试,常测试,自动测试。任何形式的文档都只是快照。温和地超出用户的期望。

再读《程序员修炼之道》

以前读过一次《程序员修炼之道》,现在又开始重读。这是一本值得推荐的好书,书中针对初级程序员给出了很多实用的建议。第一章的“我的源代码让猫吃了”,提出了注重实效的程序员应该是一个有担当的人。如果问题是由于自己的原因造成的,那么就应该承认错误,并且要想办法解决它。后面的内容也是偏向实践操作的。

程序员的必修课

觉得每个程序员都应该读一读这本书,实在是够经典。以这种厚度,写出这么深的道理,又能够处处结合实践,真不容易。逐页读来,常常有拍案而起的冲动,曾经摔过的那些跟头,原来已经有人摔过了,并且总结出了经验教训,给出了解决之道!只是如果自己没摔过,怕不容易能找到共鸣。

个人进阶经典读物

不同于《高效程序员的45个习惯》,这部《程序员修炼之道》注重的是个人,而前者更注重的是团队。就像书名所说,这是一本为程序员修炼指明道路的书,但绝不意味着它适合纯新手,我想适合阅读此书的人应该具备一定的基础。这本书应该在阅读《高》之前阅读。在《高》中,我们可以发现很多词汇解释很简略,甚至是一笔带过。在《高》中,作者的知识是建立在读者已经对其有一定了解的基础上。那么这部《程》就是阅读《高》之前的“基础”书。书中用了一定篇幅讲解了许多概念和知识,包括原型系统,代码生成器,按合约设计以及详细的介绍了测试单元等等。我们可以发现这些无不在《高》中出现,实际上《高》的厚度很薄的原因就在于此,他认为这些概念你已经了解,也许是默认你读过了《程》。事实上,我觉得这是一本很经典的书。我们可以发现身边很多人,他们拼命的去完成任务目标,而不去思考有些时候有些事情为什么这样做,有没有更好的方法来实现。当然,最终他们获得了丰富的经验,但是回过头来会发现,这种经验只是局限于任务本身,并没有获得什么共通的东西,最后这种经验仅仅化身为简历上浓墨重彩的一项。那么什么是“共通的东西”?我觉得是个人技巧和素养的积累。具体举例来说,也许我在进行某个任务期间,学会了如何写出“正交性”的代码,而在今后任何任务中,我都可以使用这种“正交性”,而且越写越好。也许你会说,“正交性”学学就会写了,但是我觉得,这是一个人编程素养的修炼,需要经过一段时间的积累才能有所展现,就如同融会贯通了一样,自然而然的就会那样思考和编写代码。所以,关键在于你是否有这种意识去增加这种技巧,培养这种素质。这就需要我们在进行任务的同时,不断停下来思考为什么这样,能不能那样。上面说了一大段,其实我要说的是,书中很多技巧都能够提供给你编程素养修炼的指引。比如正交性、自动化、单元测试这些,看似我们很少了解或使用的技巧和知识,却是程序员进阶的利器。这本书也只是一种指引,能不能够有所收获还需要自己不断尝试。我相信读过此书并实践此书,一定是一个良好的开端。我的另一篇关于《高效程序员的45个习惯》的书评:http://book.douban.com/review/6246158/

读书笔记 《第三章 基本工具》

第三章 基本工具    1. 纯文本的威力    用纯文本保存知识,这样可以方便地在各种环境下使用和管理。    威力:  <a> 不会过时:即使使用纯文本数据的应用已经不存在了,这些数据仍可以被其他的应用使用。  <b> 杠杆作用:每一种计算机工具都可以处理纯文本。(Unix系统更是纯文本成功的范例)  <c> 容易测试:很方便修改纯文本的输入,纯文本的输出结果也易于分析。    缺点:  需要较大空间。  解析处理的时候花费更大的计算机资源代价。  容易暴露系统数据内容给用户。    纯文本是最通行无阻的数据标准。      2. 使用shell    shell是程序员的工作台,在shell上操作各种工具。    虽然目前大多数应用都是基于GUI界面来进行的,但是GUI的缺点也显而易见:  GUI所提供的功能,受到设计者想法的局限。  而shell可以通过用户使用不同命令的组合,来实现功能组合定制。    例如在本地文件条件搜索的时候,shell命令就非常简洁快速。    UWIN:windows下的unix开发环境。      3. 强力编辑    精通一种编辑器,用它来处理所有文本,而不要使用很多编辑器去处理不同文本。  学习编辑器的快捷特性和功能特点,找到最适合自己工作的编辑器。    所使用的编辑器的特性,和熟练程度,将直接影响到生产效率。  某些编辑器不仅能智能地控制文本格式、用颜色区分内容,更可以定义模板。      4. 源码控制    源码控制能跟踪源码和文档中的每一项变化,提供多级撤销和版本恢复功能。  如(SVN)      5. 调试    专注于修正问题,而不是发出指责。  放松下来,不要恐慌。  bug报告的准确性很难保证,留意不要被bug报告误导。为了明确情况,最好和测试者直接交流。  重现业务中的bug,使过程数据可视化,跟踪调试。  必须要能够明确地解释出所检查的每行代码。  bug往往混迹与我们编写的代码、第三方库、运行环境的模糊地带,不要急于归咎于第三方或系统。      6. 代码生成器    当我们总是要在不同的语境中编写功能相同的代码时,应该编写一个代码生成器来替我们完成重复的工作。    (1)被动代码生成器  参数话模板,根据一组输入生成给定的输出形式。  可以用于:创建新的源文件、生成制式注释、在编程语言之间进行一次性转换、生成计算时间昂贵的查找表或其他资源。    (2)主动代码生成器  就像在“防止重复”的原则中提到的一样,主动代码生成器用于把源数据转化为适用于当前代码环境的结构。  生成的代码是可以随意抛弃的。    让输入的数据格式保持简单,可以简化代码生成器的构造。

程序员推荐都需要看一下

 绝对的好书,做个程序员一定要看下,虽然不能让你成为高手,但是可以让你变得职业一点.觉得现在的社会最缺少的就是职业精神了。看了这个书籍之后,收获非常大。看了这个书籍之后,收获非常大。看了这个书籍之后,收获非常大。

关注职业生涯的程序员的思考

前几年,书店最多的是XXX编程语言书,XXX分析与设计,很多都是学校的教科书。而关于程序员真正实践的书不多(貌似就CC,编程珠矶,程序设计实践几本)。最近几年,这样的书慢慢多了。这本相比其它书个人感觉更关注职业生涯的发展。书中的第一个tip就是 Think, about your work,而后面的Don't panic也是说在紧急情况下如何处理工作的。大多tip都是需要有相关的经验才能体会。总体感觉,这本书还是比较深的,而书中关于实践的操作方案说得也相对精炼(demeter那条说得非常好,够清晰明了),对于初入行的人来说,还是很要花点时间读的。

感觉比较奇怪

感觉从第三章往后就不是一个人写的了,不知道是不是我理解的不好,感觉比较奇怪感觉从第三章往后就不是一个人写的了,不知道是不是我理解的不好,感觉比较奇怪感觉从第三章往后就不是一个人写的了,不知道是不是我理解的不好,感觉比较奇怪

断言,异常和错误返回的区别

原书的P97-P103 中#23 断言式编程 # 24何时使用异常关于断言,pope在代码中就没有怎么用过,只是在看别人的coding时见过,也没太留意过;置于异常倒是一个很热的话题,pope一直在纠结异常应该处理多少的问题。来说说#23,#24吧!#23 Hunt 和Thomas给出的结论是“如果它不可能发生,用断言确保它不会发生(If it can't happen, use assertions to ensure that it won't)”与异常和错误的边界是:不用断言代替 程序的错误处理”在提出为什么使用断言的eg中,给出的是“啃咬电缆的老鼠,因为玩游戏而耗尽的内存,和填满了日志的硬盘”,和吞讨论时,我们感觉Hunt和Thomas的意思其实说的是硬件资源层的问题,作为上层应用的软件开发者,我们是在逻辑基础上working的,而行业分工中,这样的问题本来是硬件工程师要保证给我们的内容,但是真实运行环境中,我们这些默认的保证可能因为其他鼠祸机灾而被破坏,so 我们要用到断言,这个是现实环境的why;另一方面,在开发过程中,断言的意义是验证自己划分funciton的基础是否正确,ok,就这样了。#24 异常与程序传统错误的界限,原文如下:“异常应保留给意外事件,”----------------------未完待续,周末加班,回头继续写---------------------

读完了!

读完了,确实很实际!很多都是很现实的问题,也讲述了一个大型的网络公司,软件公司的一些怪异事情!最主要的是给给出了很多自己的想法,一些人事招聘的观念!给大家都是一个很好的释疑!特备是给在学习期间的同仁的一些建议,真的很好!

从小工到专家

仅仅这本书是不会让你从小工成为专家的。书的内容并没有它的书名那么有诱惑性。另外,我宁可相信书名里的“道”指道路的道,而不是Tao。想成为专家,得沿着这条道路继续走下去。整本书浏览下来,留在我印象里的东西并不多。也许是文化的差异,也许是翻译的问题,我一直对老外说的类似“我的代码被猫吃了”之类的话感到别扭,觉得有点扭捏作态。这本书无疑覆盖了很多很多内容:设计的原则,代码的组织,开发方法,测试,重构,设计模式,与人的沟通,文档,需求分析(把我现在这一刻能回想起来的东西都罗列一遍)。除了在沟通和需求分析两部分吸引了我的一些注意力之外,其它的地方大都是蜻蜓点水。当然,这两部分也没有深入。300页的小册子,覆盖这么多东西,当然只是把一些原则、概念点出来。这本书有意义的地方应该是一种意识,一个成为专家的起点。所以,现在回来看这里已有的书评,很同意这句话:每个刚毕业的做程序员的都应该读一下。

读后感

这是一本写理论的书,并不是写实际操作的书。印象深刻的一点就是“解耦合(decoupling)”一下几点是作者十分强调的:1. DRY - Don't repeat yourself. 2. Decoupling. 解耦合3. Be responsible. 对自己的工作负责,对代码负责4. Be good at tools. 善用工具5. Don't program by coincidence. 不要用巧合编程,不要臆断某些逻辑   Theoretical knowledge > Practical ability.

英文版的很好

英文版的写的很好,老少皆宜,童叟无欺。中文翻译的好不好不知道。译者的水准和责任感还是挺好的,我看过他翻译的ACE的书。建议去看原版的,比较准确

没有想象的好,不够吸引人!

我对这本书的评价一般,原因很简单,我都没能坚持看完,虽然普遍评价很高,但是我只相信自己的大脑做出的判断:一般,还是一般,可看可不看~ (如果我哪天看完了,我回重新评论一下,但是得等)我不向任何人推荐这本书,当然,不推荐您也可以看!

读书笔记 《第七章 在项目开始之前》

第七章 在项目开始之前    1. 需求之坑    (1)挖掘需求  需求往往隐藏在更深的层面,而且很难用文字表述清楚。  商业政策不应被硬性地写入需求,它们经常改变。  比如:“只有人事部们才能查看员工档案”,这是一个政策描述;  “只有授权用户才能查看员工档案”,这是一个需求描述。    需求应该着眼于用户做某件事情的原因,而不是做事情的方式。  “成为用户”,能更深入地了解需求。    (2)需求文档  系统的对外接口,对于用户来说更加重要,仔细考察用户的使用习惯。  UML用例图:用于捕获工作流。    (3)防止过度  需求文档应保持精确,但不要太过具体。    (4)使用抽象的描述,可以更好地适应未来的发展。  (5)防止细微地,渐进式的需求膨胀。  (6)维护一个项目词汇表。      2. 解开不可能解开的迷题    关键是确定真正的约束,在这些约束中寻找突破。某些约束是绝对的,某些约束是主观片面的。  找出约束,也就确认了自由度。  列出所有可能的途径,哪怕是看似愚蠢的,分析每一种方法。  对约束划分优先级,从最严格的约束开始考虑。      3. 等你准备好    当感到疑虑时,要停下来注视它。  培养判断能力和直觉。  当觉得无法入手时,构造一些原型,寻找灵感。      4. 规范陷阱    程序规范就是把需求规约到程序员能够接管的程度,消除岐义。  但是规范并不能捕获系统中的所有细节,这涉及到各人的理解差异和书面文字的表述局限。  随着规范越来越详细,从中得到的回报也越来越低。    把需求搜集、设计、实现视为同一个过程,在实现中让需求更明确,而不要把每个步骤孤立进行。      5. 圆圈与箭头    有各种开发方法,及其众多的追随者。  形式技术和方法有七优点,但是不要盲目采用。而且要注意它们的一些缺陷:  <a> 多采用图文结合来捕获需求,但是这种复杂的技术对于用户是很难理解的。  <b> 鼓励专门化:把工作严格区分,影响交流,浪费工作资源。  <c> 有些方法会影响程序本身的灵活性。    不要迷信某一种形式方法,从各种方法中汲取经验,形成自己的工作方式。

程序人生

为什么豆瓣不能书评电子书的周刊???这简直不科学。。@阿北找个空把笔记留在这里好了 知乎周刊·程序人生 (知乎)- 您在位置 #154-155的标注 | 添加于 2014年12月19日星期五 下午12:21:51不乏有人上大学之前对编程一窍不通,学计算机只是因为计算机「热门」而已。如同包办的婚姻,没有一丝爱情,最后以编程为业,只是因为也不会做别的什么了。==========知乎周刊·程序人生 (知乎)- 您在位置 #187-187的标注 | 添加于 2014年12月19日星期五 下午12:24:09但是编程,算是物美价廉地去满足你创造欲的一种方式:一台还算 ok 的电脑足以。==========知乎周刊·程序人生 (知乎)- 您在位置 #193-200的标注 | 添加于 2014年12月19日星期五 下午12:26:14学会如何查找帮助:这是学习一个新语言的第一步,一般别人要我教一个语言,我一定告诉 TA 先学会如何用这个语言系统的帮助,这就好比学会如何用字典。每种人类语言都有字典,而且形态类似,但是计算机语言的帮助系统形态各异,比如统计语言 R,是在命令行里面输入「?+你要查询的内容」完成,而 Visual Studio 大部分通过 MSDN,iOS 编程通过 Apple Developer Center 等等。因此你要先找好帮助在哪,怎么用。如果帮助看不懂,就买本入门的书籍,慢慢开始看。等你能写程序了,就会慢慢用上帮助。我自己的经验是,就算一个程序员对于一个语言系统再熟悉,写一个新的 project 的时候,还是有不熟悉的函数、库、接口需要查看帮助系统,因此早早学会怎么查帮助,会对你长期帮助很大。当然,实在不行,就身边找个大牛,随时请教,没有比这更靠谱的了。==========知乎周刊·程序人生 (知乎)- 您在位置 #222-222的标注 | 添加于 2014年12月19日星期五 下午12:28:28代码要比写代码==========知乎周刊·程序人生 (知乎)- 您在位置 #222-222的标注 | 添加于 2014年12月19日星期五 下午12:28:46看代码要比写代码难很多倍。==========知乎周刊·程序人生 (知乎)- 您在位置 #229-230的标注 | 添加于 2014年12月19日星期五 下午12:30:16Facebook 喜欢雇佣所谓的 「full stack programmer」,就是一个人从设计,到交互,到 html,css,javascript, server,sql, 架构和数据统计都能做。成为 full stack programmer 最好的方式就是不断做个人项目==========知乎周刊·程序人生 (知乎)- 您在位置 #275-277的标注 | 添加于 2014年12月19日星期五 下午12:34:30全栈工程师不是为了工作本身,是为了方便实现自己的梦。 作为一个标准的全栈工程师来答下,全栈工程师不是培养出来的,是逼出来的。==========知乎周刊·程序人生 (知乎)- 您在位置 #295-297的标注 | 添加于 2014年12月19日星期五 下午12:36:44如果不是创业,我的价值可能也就是个 2w 多工资的架构师或者技术经理,这个价格远远对不起我这 13 年的付出。一个真正的全栈工程师,目标只有一个:创业。==========知乎周刊·程序人生 (知乎)- 您在位置 #462-464的标注 | 添加于 2014年12月19日星期五 下午12:46:58你要知道,这个世界上有那么一类人,他们永远保持着自私的心态。无论什么时候,他们都在为自己的利益做打算。当你说你在银行工作,他们第一个想法是你能不能给搞到贷款或者办张没有额度限制的信用卡。当你说你在医院工作,他们第一个想法是能不能去看病不排队或者在医院拿点药品送他。==========知乎周刊·程序人生 (知乎)- 您在位置 #593-594的标注 | 添加于 2014年12月20日星期六 下午11:58:54所谓选择最好的入门语言可能是一个伪问题,而真正的问题是当你选择了其中一门语言后,如何选择合适的学习方法。==========知乎周刊·程序人生 (知乎)- 您在位置 #615-618的标注 | 添加于 2014年12月21日星期日 上午12:05:12以下想说说关于学习曲线的问题,初学者最大的障碍可能就是遇到问题得不到解答。不过,如今的学习条件跟当年互联网不发达的时候相比已经好得多了,有这么多优秀的问答网站,学习资源,百科全书可供使用,比如: 1. 知乎 2. stackoverflow 3. wikipedia 4. 美国一流大学的开放式课程==========知乎周刊·程序人生 (知乎)- 您在位置 #620-623的标注 | 添加于 2014年12月21日星期日 上午12:06:55部分语言的优秀的入门教材 : C: C Programming Language JAVA: Java Programming Language, Stanford's the programming methodology C++: C++ How to Program Python: Dive into Python, Learn Python the Hard Way,A Byte of Python==========知乎周刊·程序人生 (知乎)- 您在位置 #624-626的标注 | 添加于 2014年12月21日星期日 上午12:07:04比较适合新手的在线测评网站: USACO Euler Project TopCoder==========知乎周刊·程序人生 (知乎)- 您在位置 #630-630的标注 | 添加于 2014年12月21日星期日 上午12:07:29happy coding!==========知乎周刊·程序人生 (知乎)- 您在位置 #652-653的标注 | 添加于 2014年12月21日星期日 上午12:09:08关于 C 语言书籍推荐,以及学习建议,我都写到这里来了:学习 C 语言基本思路与参考书籍 - 林建入的软件设计之路 - 知乎专栏 | http://zhuanlan.zhihu.com/linjr/19694823==========知乎周刊·程序人生 (知乎)- 您在位置 #710-711的标注 | 添加于 2014年12月21日星期日 上午12:12:20为了发掘那可能存在的一两个数学家,把一代孩子的数学教育拔高到一个变态的标准,这你们都知道。音乐也一样。==========知乎周刊·程序人生 (知乎)- 您在位置 #777-779的标注 | 添加于 2014年12月21日星期日 上午12:17:12如何一边写代码一边跟女友聊天? 张恺进 你需要注意不要一不小心在对话框里打个//,然后写出自己的心里话。

阅读第一遍的感受

花了大概有8,9个晚上,历时2周时间指导思想不错:比如:煮青蛙那一章,可以放大为生活的真理。翻译我觉得不是很流畅,虽然有人说很好了,我自己翻译的资料更烂,但是我还是想说,真的很拗口,读起来确实很费劲。好书是好书,但是,所有的中文短句总结,我都记不住,倒是把部分原文英文的给记住了。

做项目修炼之道

都说这书很好,机缘巧合我跟利未借了这本书。我想从这本书找找有没有适合美术的修炼之道。读的过程中,我发现的确有,而且老外归纳总结的很有条理。分享如下:关于个人的修炼1、保持技术直觉,喜爱尝试并接受新事物2、保持好奇心,喜欢提问3、批判的思考者,不要盲从4、要理解问题的内在本质5、熟悉广泛的技术并了解你所处的时代和环境6、说什么和怎么说同样重要7、不要重复自己8、关心你掌握的技术9、思考你从事的工作10、提供多种解决方案,不要找借口11、充满热情,影响别人12、关注全局,做好细节13、定期为你的知识资产投资,保持学习的习惯14、等你准备好再开始15、在你的作品上签名关于项目研发和管理的修炼1、当你发现糟糕的设计时,马上修正它们2、让用户参与确定项目真正的需求3、让复用变的容易4、消除无关事物之间的影响5、不存在最终决策6、为了学习制作原型(类似在造车之前会做一个1:1的模型车)7、学习估算工作量8、用好一种编辑器(专精一种绘画软件)9、解决问题,而不是指责10、不要假定,要证明11、你不可能写出完美的软件(没有完美的画)12、为并发进行设计13、像用户一样思考14、围绕功能组建团队15、一个bug只抓一次16、温和的超出用户期望

程序员修炼之道

 网易、趋势科技等公司新员工技术培训首选用书 云风、邹飞、霍炬、徐宥、赵钟秋写书评联袂推荐《程序员修炼之道》 十周年纪念版重印上市,原书作者亲自作序推荐

china-pub近期免费赠书活动大汇总

http://www.china-pub.com/STATIC07/1106/jsj_zengshu_110616.asp1、china-pub新浪微博免费赠书(5本)#china-pub赠书#共5册,《云计算核心技术剖析》《云计算(第二版)》《Linux内核设计与实现(原书第3版)》《黑客与画家:硅谷创业之父Paul Graham文集》《MongoDB权威指南》关注本人转发本微博,即有机会获得赠书1册,随机抽取5名幸运者。活动时间:06.10—06.20日。china-pub新浪微博:@china-pub网上书店2、china-pub豆瓣免费赠书(20本)活动地址:http://www.douban.com/group/topic/20425927/谁说天下没有免费的午餐?!您尽情的侃,china-pub尽情的送!不需其他,只要您侃的精彩,即有超值畅销书赠送。【好书推荐】总有那么一些书,您想谈谈评评……【职场杂谈】钱不是问题,问题是……(总有一些经验,您觉得值得分享)【神侃战场】关于IT行业、人生、爱情……(总有一些话,如鲠在喉不吐不快)【关于china-pub】您对十年老网站china-pub有什么建议与意见呢?活动规则1、关注本豆瓣china-pub(http://www.douban.com/people/chinapub/),加入本小组china-pub网上书店(http://www.douban.com/group/chinapub/);2、在本小组对应的上述4个板块(好书推荐、职场杂谈、神侃战场、关于china-pub)中任一板块发言,参与讨论的人,侃的精彩(侃的精彩就行哦)即有机会获得超值赠书1册;3、赠书数量20册,最终获得赠书的20名幸运者(侃的最精彩的20人)可以在china-pub网站上任选1册赠书,每人限1册(原版书、按需印刷、套装书、缺货书除外)。(共20册赠书);4、活动时间:2011.06.13—2011.07.10日;5、本活动最终解释权归china-pub所有。

好的地方很多,但是也有不足的地方

不知道是翻译的原因,还是作者本身的原因,或者是看这本书本来就需要足够的功底。这本书给我的感觉是逻辑性不强。说下序的部分,开头一句就是“本书将帮助你成为更好的程序员”,然后我的头脑里面马上就想到:接下来作者是从哪几个方面或者是怎么来谈成为更好的程序员。可作者话题一转,说编程是一种技艺,编程是艰难的工作,看了好几遍都没弄懂作者要表达个什么意思。每一章的开头部分,是这一章的概述,作者也的确是这么干的。但让我找不到本章讲述的内容之间的联系,比如说第一章,注重实效的哲学,这里有六个小节:源码让猫给吃了、软件的熵、石头烫与煮青蛙、足够好的软件、你的只是资产、交流;在这章的开头部分的描述中,没有讲述他们之间的联系,感觉很分散;而且就算是后面的详细内容也没有很好的从一个小节流畅的过度到下一个小节。看完之后,肯定会想,这些小节到底跟注重实效的哲学之间是什么关系,为什么是这样子的关系!个人觉得,虽然在这些小的方面,有我不理解的部分,但是整本书还是让我学到很多的东西,值得推荐!

领悟程序员的哲学

在大学的时候,编程是我的兴趣,也是当时我给自己定位的职业方向。当我在图书馆看到这本《程序员修炼之道》的时候,直觉告诉我应该看看这本书,或许对我的成长有帮助。读完之后更加肯定了自己的直觉是对的。当时我虽然没有实际项目的开发经验,不能一时领悟其意,但我明白,这本书中总结的原则和方法对我来说是极为宝贵的,于是买了一本放在床头。参加工作后,随着编程经验的积累,我越来越能体会到这本书中的观点。每次重读书中的章节,我都会有新的收获;再结合自己的每次经历,都能与之共鸣——这是对我影响最深的一本书,也是我向朋友和同事推荐次数最多的一本书。有趣的是,书前Kevin Ruland的评论说:这是我唯一不会出借的一本书。究竟是一本什么样的书会让大师如此爱不释手?这本书所涉及的内容很广,涵盖了程序员成长过程中和软件开发过程中要注意的地方。从程序员的个体哲学到编码过程中的各个环节,再到团队的项目管理;从程序员要如何扩充知识,如何思考问题,如何利用有效的工具打造个人的工作环境,到项目启动之前如何建立一些基本准则,如何分析、设计、编写、测试、重构,如何实现自动化,甚至是项目团队中提高实效的原则。书中的内容全都来自经验的总结,倡导编程中正确的观念和良好的习惯,而这正是优秀的程序员必须拥有的良好素质。书中讲述的原则源于实践,高于实践,它们蕴涵着前辈们的智慧。随着知识的扩展、编程体验的增加,对这本书中的内容的理解也会愈加深刻。反过来,对前辈菁华的吸收,有助于我们提高编程水平,开发出更好的产品。我深信这不是一本只要读一遍的书。这些原则看似简单,但细细品味一番,却是大哲大道,环环相扣,要理解透彻并不容易。例如,提示44告诉我们“不要靠巧合编程”,这道理看起来好像很简单,但我发现实际工作中还是很容易就犯这个错的。细想一下Bug列表中的问题,其中大多数问题不正是由于作了不正确的假设,或者是想当然造成的吗?要是一开始就有了深思熟虑,经过了合理的设计,完整有效地进行了测试,应该大部分都可以避免吧。而思考、设计、测试又紧扣书中其他章节。曾经和朋友讨论关于员工培训的事。如果给程序员做培训,我首选的材料就是这本《程序员修炼之道》。--注:这是应博文视点周老师的邀请,为这本书的再版写的书评。希望更多的程序员朋友能够读一读这本书。http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html另外一篇我写的书评:http://blog.belltoy.net/read-the-pragmatic-programmer.html

程序员应有的基本素质

这本书是在倡导正确的观念和好的习惯, 但是并不会详细教你怎样做. 在我看来,里面说的其实是程序员应有的基本素质,只不过现在合格的程序员并不多。所以, 这本书值得一看, 不过也是翻过一遍就够了. 章节比较简短, 相互关系不紧密, 而且也有比较多的reference信息, 很适合抽空阅读一小段。

又一本好书被糟蹋了

翻译得太烂, 书名译得极其恶俗这本书本来很好的, 每个程序员都应该读强烈建议买影印版 http://www.douban.com/subject/1119873/或者原版

一本值得多次阅读的书籍

最近时间比较多,抽了4天时间读完了程序与经典书籍《程序员修炼之道》,结论是,这是一本适合多次阅读的书籍。这是一本讲程序员内功的书籍,涵盖了设计一个的产品各个点,包括:设计,编码,测试,管理,文档等等,书中始终围绕的一个中心就是:注重实效的程序员应该如何做。我选了一些有意思的内容分享给大家。1. 领域语言让我想起了《代码的未来》中提到的DSL(Domain Specific Language),在我们工作中会经历各种DSL,在我们需要的时候,我们可以自己来书写DSL。2. 如果出现了Bug,记住:死程序不会说谎:我是做测试出生,当时提交 Bug 到程序员那边,经常会被回应:怎么可能会有这个问题?现在我自己做程序员了,我发现我依然没有跳出这个怪圈,要时刻提醒自己死程序不会说谎。3. 断言式编程:如果它不可能发生,用断言确保它不会发生。里面举了两个例子来让我们对断言反思,很有意思:(1)1752年9约只有19天,为使日历同步而进行的。 (2)非欧几何中,三角形的内角和不等于180°,想一想投影在球面上的三角形?4. 元数据使用元数据来解耦,要配置,不要集成。5. 考虑并发:软件设计的适时候,我们要考虑并发的情况,以提高效率。6. 不要靠巧合编程:不要试,要证明;这又是很多人学习新技术的通病,我们不但要知其然,而且要知其所以然。7. 算法:1).估算你的算法。测试你的估算; 2.最高效的算法并非总是最好的。8. 重构:早重构,常重构。书里关于重构的内容讲得比较少,但是重构的方向已经给我们指明,使用重构这个武器,我们可以战胜两个敌人:提前超详细设计和烂代码。9. 需求:与用户一同工作,像用户一样思考。里面举了一个需求之坑,也很有意思:“只有员工的上级和人事部门才可以查看员工的档案” “只有得到授权的用户可以访问员工档案”哪个才是我们真正的需求?维护词汇表,Use a project glossary 来让我们高效沟通吧。10. 测试:早测试,常测试,自动测试:编一点,测一点。要到通过全部测试,编码才算完成。通过“蓄意破坏”测试你的测试。测试状态覆盖,而不是代码覆盖。为新bug编写新的测试;11. 文档:代码中的注释应该讨论为何做某事,它的目标和目的。让不同形式的文档内容保持一致:文档和代码是同一底层模型的不同视图。对待文档要像对待代码一样用心。12. 责任:代码署名,代码所有人,责任。我们的目的是:多年以后,当我们的孙子看到我们编写的代码的时候,他的眼里也会闪过一丝骄傲。13. 注重实效的团队:(1) 不要留破窗户:最勤勉的开发者如果被派到不在乎质量的团队里,会发现自己很难保持修正琐碎问题所需的热情。(2) 注重检测环境的变化;(3) 交流:一个方法给自己的项目团队创建一个名字和LOGO来增加归属感。(4) 不要重复,重复代码,重复功能等等。(5) 按照功能划分团队。而不是按工作职务来划分组织。(6) 自动化:效率最大化。(7) 制作完美软件的时候,要知道何时停止绘画?14. 最终结论:注重实效的程序员应该不断学习!果然是这个样子。15. 本书结尾推荐的书籍:经典好书,不要错过。分析与设计:Object-Oriented Software Construction 2nd EditionDesign PatternsAnalysis Patterns团队与项目:The Mythical Man Month.Dynamics of Software DevelopmentSurviving Object-Oriented Projects: A Manager’s Guide具体环境:Unix:Advanced Programming in the Unix EnvironmentUnix Network Programming


 程序员修炼之道下载 精选章节试读


 

外国儿童文学,篆刻,百科,生物科学,科普,初中通用,育儿亲子,美容护肤PDF图书下载,。 零度图书网 

零度图书网 @ 2024