正文
比如张君宝与昆仑三绝何足道在少林寺的那场经典之战中,张君宝能够“以少林拳中最平淡无奇的拳招,化解了最繁复的敌招”,始终不落下风,所恃者不过内力之浑厚尔。另外的著名战例还包括少林寺小和尚虚竹VS.吐蕃国师鸠摩智以及聚贤庄萧峰VS.玄难。内力达到登峰造极空前绝后的第一高手莫过于少林寺的扫地僧。也许风清扬是一个例外,好在我们讨论的是一般规律,所以就顾不得他了。计算机编程所特有的思维(Thinking)就是程序员的”内力“,思维能力不济,功能再强大的编程语言也无用武之地。所以,我在这里特别强调程序员的思维艺术。
程序员的思维有一个专业术语,叫做计算思维(Computational Thinking)。计算思维是按照计算机科学的基本概念和方法,用来理解需求、设计系统、实现编程、解决问题的思维方法。简而言之,计算思维就是程序员或计算机科学家是如何思考的。当然,计算机科学的理论知识如数理逻辑、离散数学、数据结构、算法以及面向对象是计算思维的必要条件。计算思维有一系列的智力工具,不能一一尽述,仅列举关键的几项如下:
抽象思维(abstract thought)
。给定一个问题,抽象就是去掉纷繁芜杂的与计算无关的部分,用规约(Reduction)的方法还原到问题的本质。所谓本质即把原来的问题转换为一个或几个可以使用计算机描述并解决的问题,进一步讲也就是转换为在算法上可计算的(algorithmically computable)一个或几个问题,更准确更理论化更上档次的描述是转换为邱奇-图灵论题(TChurch-Turing thesis)可计算的可数个问题。图灵机(Turing Machine)和λ演算(Lambda calculus)本身就是对可计算性(Computability)的漂亮的抽象,可以作为抽象思维的经典案例来揣摩学习。一般在实际工作中,常常需要把问题的实体对象根据需求表示为各种数据结构如树、堆、栈等,而业务逻辑(Business Logic)过程表示为各种算法如排序和查找等。
表示(Presentation)是解决问题的第一步,也是关键的一步。在程序员的实践中,我们都有很深的体会,一旦问题被准确的无歧义表示出来了,解决方案就烘云托月般地呈现出来了。这就是“数据即代码,代码即数据”的道理。抽象思维也广泛用于数学家的工作。面对一个困难的问题,数学家们常从两个方向开展研究。
一方面,从特殊情况入手,推广到更一般的情况;另一方面,将一个一般问题具体化成几种特殊情况。两个方向的结果最终汇聚在一起,就找到了问题的答案。我想这可能是论语中“我叩其两端而竭焉”的一个最好注解。而从特殊到一般就是不断抽象的过程。我们用一个具体的例子加以说明,有一个著名的六度分隔理论(Six Degrees of Separation)讲的是世界上任意两个人都可以通过最多另外6个人相互认识,如果要验证这一理论,怎么做呢?
我们可以借助一个图(graph)来表示人与人之间的关系,每个人用图中的一个节点表示,如果A和B认识,那么在代表他们的节点之间有一条边连接。那么现在的问题就转换为检查这个图的直径是否大于6。考虑到世界人口众多,且有生老病死,图的规模必然超大,并且是动态的不断变化的,算出它的直径仍需要更多的简化。这里就到此为止了。
逻辑推理(Reasoning)
。逻辑推理对于程序员的重要性不言而喻。与其说逻辑推理用于程序新功能的开发,毋宁说更多的应用在程序调试修改BUG的过程中。程序调试有点类似于Sherlock Holmes侦破案件的过程。和Dr. Wason比较起来,Holmes的推理优于常人的地方有两点:第一,在观察现场或听取来访者叙述时,他能够得到更多的的数据,尤其是一些别人容易忽略的关键的细节,这得益于他对犯罪领域知识的丰富积累,知道什么才是更重要的数据;第二,根据得到的数据,他能够联想到更多的可能的结论,这得益于他大量的案例储存。有了这两点,就能够通过一环套一环的推理链逐渐缩小侦察范围,最终认清犯罪事实。