导航

转《UNIX编程艺术》读书心得

Posted on 2015-12-23 08:42  MaHaLo  阅读(1670)  评论(0编辑  收藏  举报

花了一段时间看完了《UNIX编程艺术》,但不是看得特别仔细,尤其是后面作者通过对工具的讲解来阐述其设计思想,因为很多工具能未曾接触过,难免就会产生一些乏味的感觉。其实就像译者姜宏在译序里说的一样,本书并不是什么UNIX编程手册,而是对UNIX历史上众多成功经验和失败教训的一个总结。而且在读这本书的过程中,你会发现很多地方并没有什么绝对的对与错,我想这也是作者ESR的意图之一,让读者自己去思考,才能从中掌握一些技巧。相对来说,阅读这类描述编程思想的书籍比阅读充满代码的指导类书籍要困难一些,但也要有趣一些。比如,开篇的第一部分就是在着重介绍UNIX的哲学、文化,通过17条原则来阐述其大意,最后却一言以蔽之——“KISS(Kepp it sample,stupid!)“。

UNIX从1969年诞生至今,经历了无数的兴衰没落,但仍然能毅力不倒。如果UNIX仅仅是作为一个操作系统所存在,我想它并不能坚持至今,至少对于今天的普通用户来说,还是更习惯于Windows这类带有GUI、拥有华丽界面的操作系统,支撑其发展的就是它的设计思想。在作者眼中UNIX就是世界上最好的操作系统,因为其设计的简洁性、透明性时其他操作系统无法比拟的。

不要重复造轮子

我觉得这是很多程序员挂在嘴边的一句话,UNIX推动了开源事业的发展,也给我们带了了很多轮子。以前在博客园看过一篇文章《到底是否应该重复造轮子》,作者最后说道“99%的人都不应该重复造轮子,只有1%的人应该去做这件事,因为只有1%甚至更少的人,造轮子造出了未来,而剩下的,都成为了这少数人的绿叶,衬托着他们的光芒,对于剩下的这批人来说,这些轮子造的意义并不大,至少对他们自己来说,花费的时间与得到的成长不成正比。”。我个人的观点认为,作为新一代的程序员,我们踩在无数巨人的肩膀上,我们的确不应该去重复造轮子,但我们需要知道怎么去造轮子,懂得这个轮子背后的实现原理,这样你在遇到新问题的适合至少知道怎样去解决。而且对于新手程序员来说,“只管使用、不管原理”这样的想法也不利于自身的成长。其次,我们也要选择一个合适的轮子,不然你还不如自己造一个。

简洁的是最好的

UNIX哲学基础中有一条简洁原则——设计要简洁,复杂度能低则低。在UNIX系统中的工具就是最好的例子,它们只做一件事情,但通过管道将他们连在一起却能完成许多复杂的工作,当然UNIX的“文本化协议”息息相关。如果单从设计角度来说的话,简洁就是一个程序的功能要尽可能的单一,不要想着我做的这个程序能胜任所有工作,到头来才发现连一个简单的工作都完成不了,还经常出现BUG。另外,程序员在技术上的虚荣心也是导致程序复杂度无限提升的原因,为了展现自己的技术实力,他们经常使用复杂的算法去完成简单的功能,最后出了问题连自己也解决不了。这种本可以避免的错误就是在浪费我们的时间,我们应该把时间投入到新问题中,而不是为这样的旧错误擦屁股,所以,为了世界和平(程序员会做出什么事,连自己都不知道)请降低你的代码复杂度,记住难于理解、维护和扩展的代码就是复杂的代码。计算机编程的本质就是控制复杂度, Kepp it sample,stupid!

过早的局部优化实际上会妨碍全局优化,先制作原型,再精雕细琢,优化之前先确保能用

我很赞同这句话所表达的观点。优化是一个长期的过程,而且在你的程序都不能正常运行的情况下就去进行局部优化,除非你有足够的信息和技术,否则你就是在作死,因为你永远不知道你的优化会导致什么新的问题,还没学会走你就想跑了~

“极限编程”宗师Kent Beck说过“先求运行,再求正确,最后求快”,在电脑硬件极速膨胀的今天,对于大多数程序员(还有少数人属于特殊领域)来说真的没有必要为了节省一点运行时间去进行过早的优化,当你的程序能正确运行的时候,你自然会发现哪些地方需要进行优化。上周用Nodejs重写Global Configuration API的时候就运用了一下这个思想,我认为这样做的好处在于你的优化更具有针对性,而不是自以为这个地方就该优化一下。即便是在过程中产生了新的BUG,我们也能更快、更好的解决掉,同时也印证了另外一个观点——最好的优化工具就是Delete键。

模块不宜过小,也不能过大

要编制复杂软件而又不至于一败涂地的唯一的方法就是降低其整体复杂度——用清晰的接口把若干个简单的模块组合成一个复杂的软件。如此一来,多数问题就只会局限于某个局部,那么还有希望对局部进行改进而不至于牵动全身。模块作为其中重要的组成部分,扮演者重用的角色,模块过大或过小都会产生更多的BUG,那么怎样才能算是一个适合的模块呢?模块划分常常是程序设计中最难的一部分,可以把模块看成是一个小程序,就像UNIX系统中的小工具一样,他们的职责应该简单、单一,各个模块之间通过接口相互协作,我觉得一个模块可以被替换而不会影响整体的运行就是最合适的。当然,具体的划分还是需要根据具体的情况作出调整。

这里我想到另外一个观点——宽进严出,我觉得这同样也使用于模块设计,因为你不能保证其他模块或者用户的输入是严格按照你的要求来做的,但是你应该保证你的输出是严格一致的,不会经常发生变化(这里的变化通常是指数据结构的改变),这样才能与其他模块更好的协作。

代码是活代码、睡代码还是死代码?

“活代码”是指在你的周围存在一个非常活跃的开发社区,“睡代码”之所以睡着,经常是因为对作者而言,维护代码的痛苦超过了代码本身的效用,而“死代码”则是睡得太久,重新实现一段等价的代码更容易。(摘抄自书中原话)

提供机制,而非策略

个人理解的就是机制是做什么,策略是怎么做,这样的好处就是使用“机制”的用户可以根据自己的需要使用自己的“策略”来实现其中的细节,而且这样很容易更换“策略”而不会影响“机制”。其实这就是接口的工作,以前在学校学习三层架构的时候每一层都有一个接口层,比如,数据访问层有一个接口层定制了需要提供的功能(做什么),而具体的实现可以根据不同的场景而改变,SQL Server可以用SQL Server的访问层、Oracle可以用Oracle的访问层(怎么做),你底层的更换并不会影响到上一层。

总结

最初以为书本中会有许多示例代码,到头来才发现除了文字还是文字,阅读过程中难免会感觉枯燥,其实仔细想想,如果你真的能静下心来好好思考一下,你肯定会有更多的收获。对于这些思想性的东西,并不是一朝一夕就能掌握的,我觉得更多的是要结合实际项目进行练习,这样才能更好的把这些思想融会贯通。其实,作者所说的“UNIX是世界上最好的操作系统”,就我个人而言我还是更喜欢使用Windows(也许是习惯了图形化界面),因为我觉得UNIX的学习成本有点高,虽然我觉得在终端中使用命令很酷(尤其是使用yum安装软件的时候),但对于不熟悉的人来说效率真的不高。

BTW:读一遍真的不够