道家思想"/>
CS中的道家思想
一、“夫亦将知止,知止可以不殆。”
以下是一段计算斐波那契数列前n项和的简单递归算法:
那我们小学二年级就学过的,在递归结构中,那条语句最重要啊?
对滴,就是这句,递归终止条件语句!若没有递归终止条件语句,程序运行时将陷入无往之境,全然不知前路该当何去何从,是故“夫亦将知止,知止可以不殆”。
二、“天下万物生于有,有生于无。”
在香农的《信息论》中有这样一个概念,叫“信息熵”,它表述了在某一套语言系统中,所采用的符号们传达信息的效率,以下是关乎于它的一个计算公式:
其中H(X)是信息熵,也就是信息量(对,基本就是“信息量”仨字的字面意思)。而p(xi)则表示第i个符号出现的概率。
那有了这个公式后,假如某一语言系统中只有“0”一个符号,那显然在这个语言系统中,每种符号的出现概率只能为1,代回公式,因为log1=0,所以很容易可以算出H(X)= 0,也就是说该语言系统无法传达任何信息。
但如果我们再在这个语言系统中添加一个符号“1”,并假设“0”和“1”两种符号出现的概率各为50%,代回公式,H(X)=-(0.5log0.5 + 0.5log0.5) = -(0.5*(-1)+0.5*(-1))=1,也就是说这回这个语言系统中的每个符号可以传达1bit的信息。而若有无穷无尽的01,这个语言系统就已然可以传达无穷无尽的信息。
正所谓:“天下万物生于有,有生于无。”
三、“故物或损之而益,或益之而损。”
在计算机科学领域,在可能的一些能被奉为“圣经”的书籍中有一本较为重要的,英文首字母缩写叫“CSAPP”,中文名叫《深入理解计算机系统》,这本书开篇不久讲到了一个公式,该公式常年盘踞在斯坦福、MIT这等学校在这门课期末考试中填空题第一空的位置,这个公式叫“Amdahl定律”,长这样:
我们知道,计算机的存储系统有着具备层次性的体系结构,可以简单分为硬盘、内存以及寄存器。其中寄存器存取速度最快,内存次之,硬盘最慢,相应的,寄存器的成本最高,内存次之,硬盘则最为廉价,除此之外,寄存器、内存与硬盘中各自存储的数据可以简单地说它们又依次远离CPU的核心的算术逻辑运算单元。
那为何要采取这样的设计?就是要尽量用更少的价格提供给用户相对更快的速度。
当然可以全用寄存器来执行数据存取,整体运行时较从前会更快一些,但相应的,成本会飞涨,那作为一件产品、一件商品,这种设计方案就叫“得不偿失”。
以上这种可能略极端,但也恰恰说明若要优化计算机系统,一定要将整个计算机系统作为由不同层级的部分所构成的整体来考量,而“Amdahl定律”就是告诉我们某一部分的性能提升后,其对整体性能提升带来的改变能有几何的,结合预估成本,统筹地看,才能知道何为当下最佳的优化策略。那之所以这一定律常年预定了许多名校这门课考试的填空题第一题的位置,按照一些教授的解释,就是希望学生们能记住计算机科学中所体现的这种整体化思维与“大局观”,有时略微牺牲掉一些暂不必要的部分,把省出的力气放在其它部分上,可能会换取更好的结果;有时过分钻于某一点,也许最后那个部分取得了提升,却终换得满盘皆输。
虽然可能有失偏颇,但我觉得在某一角度上,这也合乎于这句:“故物或损之而益,或益之而损。”
四、“大直若屈,大巧若拙。”
对于下面这样的一个迷宫,想必大家几乎一眼就能看出它的走法了:
但如果换成这样的一个迷宫呢:
若还是照之前那般只是盯着看,我们自己可能都不确定自己到底能不能盯出答案。
那可以采取一种什么样的方法,至少可以保证我们在有限的时间内,一定能走出这个迷宫?
其实很简单,就是从入口进去,每逢路口都只往右拐(或只往左拐),并在路口处对你将走向的那条支路做上标记,一旦遇到死路就退回上一个路口,选择之前走过的岔路的旁边一条没走过的岔路再次向前,依次类推,终能走通。
采用以上的办法,可以保证在有限的时间内一定能走通迷宫。并且,除此之外,再无别的方法可以确保有效地在有限时间内能走通迷宫。而当迷宫复杂到一定程度,采用这种看似最笨的办法来走迷宫会绝对快于“干瞪眼”的办法。
正所谓“大直若屈,大巧若拙。”
五、“为之于未有,治之于未乱。”
翻开一本面向基础的讲一门计算机语言的书,一般都会在比较靠前的部分讲到不要用类似a1、b1、x这种没有意义的名字命名变量,像这样:
因为这会使得你和它之间很快就彼此疏离,因而走向形同陌路,最终变得互相厌恶,它厌恶你不懂它,你厌恶它不讲道理、毫无逻辑,还净无理取闹。
好吧,正经一点,其实是这样会影响程序的可读性(这段代码究竟在做什么?x1、xx和xxx代表什么?fido又是什么意思?),未来代码量变庞大后,这里留下的隐患会使得调试变得相当困难。
所以要尽量采用可读的、易记的和恰如其分的名字来命名变量。像这样:
虽然多打了几个字母,但所换来的程序可读性的提升,至少可以使得在后续调试过程中,不会因为不懂变量含义而抓耳挠腮了。
除此之外,面向对象开发的出现以及以之为基础生出的一些开发模式本质上也是为使代码结构更为清晰,可读性更强,因而程序扩展起来也就更为容易,而要做到这一点,做好“抽象”便是重中之重。
在不了解抽象方法时,如果你需要把字体设为粗体,你或许会写出下面的语句,这里用到了一个按位or运算符和一个16进制常量0x02:
如果你够幸运的话,也可能代码会比上面这样要干净些。但使用拼凑方法的话,你能得到的最好结果也就是写成这样:
或者是这样:
就修改字体大小而言,这些做法都存在一个限制,即要求调用方代码直接控制数据成员,这无疑限制了currentFont的使用。
如果这么编写程序的话,程序中的很多地方就会充斥着类似的代码。
但如若能够做好抽象,你会写出下面这条语句:
这条语句的可读性是完胜上面那几种的。同时,它会使得无需再在程序内部到处传递数据,以致程序结构变得混乱,还会让你可以像在现实世界中那样操作实体,而不用在底层实现上操作它,提高效率。
但若想做到这一点,你需要先花时间做好需求分析,其包括程序抽象结构的设计,而花时间去做这些并非实际编码工作的事,其能够取得的成效是显著的。
正所谓“为之于未有,治之于未乱。”
欢迎关注我的微博或微信公众号“嘉法编译器”
更多推荐
CS中的道家思想
发布评论