« 谷歌可以保存搜索历史了 | 返回首页 | 一些琐事 »

数学是一种思考方式

这几天有个读者来来去去给我写了几封 email ,问起我的观点:数学和编程是什么关系?学编程需要多深的数学基础?到底需要掌握哪些数学知识,对编程能力的提高有帮助。

这个还真不好说。

如果说起课堂上我们学到的知识。除了初等代数,在编程中我还真没碰到多少依赖数学技能来解决的问题。当年我学 C 语言的时候很小,甚至不知道数学中函数这个概念,还不一样把 C 语言学完了。虽然过了些年,我才把数学中的函数和程序中的函数联系起来。

做 3d 游戏编程,大学里的线性代数可能还用的到一点。至少得知道矩阵运算吧。但是大部分程序员并不需要接触这些东西。除此之外,如果说程序员必须精通微积分才能编程,那绝对是鬼扯。

如果对用编程的手段解决各种问题感兴趣,或许相关领域的数学知识有些用。比如我时常由于兴趣,做一些数据统计分析工作,这时概率统计的知识就少不了。但是解决问题,编程和数学一样,都只是工具。他们的地位是平等的,并非编程的技能依赖数学技能。

那么,学习数学有用吗?当然有必要。因为数学是一种思考方式,编程需要这样的思考方式。

我有个朋友,十年前认识他的时候,他说他在学佛。有一个问题没弄明白:佛说,不要执着。那么执着于不要执着是不是一种执着。

过了好些年,他还没弄明白这个问题。

学佛怎可以执着于这样的语言逻辑呢?光读佛经是没有用的,道理有时候需要顿悟。数学也如此。

学习数学绝对不是无休止的解题训练,我们需要悟到其中的思考方法。那种逻辑严密的推理,对完美境界的构建。发现理论上的缺陷,并对其分析,重新构作。当然,这个过程,又需要我们做大量的练习,借此领悟其中的道理。

编程也一样,不断的编写代码本身并不能直接提高编程能力。我们需要的是对问题的洞察力,构建系统的能力,理解机器运行时来龙去脉的能力,等等。而这些能力又是在不断编程实践中顿悟出来的。

编程和数学一样,是绝对严谨的。程序有特定的输入,经过特定的流程,一定有特定的输出。对于程序中的 bug ,我们不能抱有神秘论。它们不会没来由的出现,没来由的消逝。这就跟数学证明一样,逻辑或概念的缺陷不会随着时间消失,总等待后人来修补。

另一方面,在数学中,直觉也是很重要的。直觉可以帮助我们快速理解问题,解决问题。对数学了解的越多,数学的直觉就越准。很多数学知识,不需要太多研究学习,靠直觉就可以理解了。程序写多了的人通常也会有这种感觉 :D

只是有时候,数学中有些命题很直观,但是证明过程却非常繁杂。

比如拓扑学中的若当曲线定理:平面上一条简单闭曲线 C 恰好可以把平面分成两个区域,一个是内部,一个是外部。换句话说,平面上的点被分为了两类:在曲线外部的点集 A,和在曲线内部的点集 B 。在同一点集中的任意两点都可以用一条不与 C 相交的曲线相连,而连接一对不属于同一点集的两点的连线必然和 C 相交。

这个定理看起来很直观,显然是对的。但是一般人很难做出严格的数学证明,甚至很难看懂其证明。

现代编程我们经常会遇到类似的东西。尤其在现在系统越来越复杂的情况下,一段很简单的应用程序代码,你可以很显然的知道它能做什么,但是很少有人可以完全解释清楚它是怎样一步步做到的。比如一段很简单的 Windows 程序代码就是这样。只有拥有追根问底的数学精神,才会刨进操作系统底层,去搞明白系统到底怎样工作。这些不是一日之功,甚至不是三五年就够了的。而许多庸庸碌碌的程序员,满足于拖两个控件,粘合一下代码。最终只会感叹,程序只能写到三十岁。要我说,平庸资质如我,三十岁能入门就不错啦。

数学的发展历史中,又包含了许多人无穷的创造力。光靠逻辑推理来一步步解决问题显然是不够的。很多数学问题的解决,都起源于某种直觉,某种创造性构建,甚至把许多表面不相关的东西牵连在一起思考。然后再通过逻辑严密的推导过程来完善它。

例如,费马大定理的最终证明。首先找到了关于费马方程的解所在的费马曲线和椭圆曲线的联系,然后构造出一种特殊的椭圆曲线,当且仅当费马大定理不成立时,该曲线才存在。最后,通过证明这种曲线有一些极端奇怪和不可信的性质,决定了曲线不可能存在,从而反证了费马大定理成立。这之中虽然用到了许多前沿的高深数学理论成果才得以证明,但整个思路框架之巧妙,也是让人佩服之至。

编程也是如此,我们首先需要对各种编程方法,编程语言的特性得心应手;而后,编程绝对不是简单的堆砌代码,它需要我们巧妙的构建系统,在合适的地方用合适的方式来解决问题。最终还需要让每个部分都严格正确。

最后,对于那位朋友的问题,我只能给出我的个人建议。学习编程的确需要学习数学。但学习数学,不必列出书目,一本本去啃那些枯燥的教科书。只需要从数学史读起,弄清人类是怎样一步步理解数学的,学习其中的思想,最后用自己的兴趣去研究其中感到有趣的部分。

Comments

恩,同感。数学是一种工具,也是一种思维模式,但如果有谁说一个人拿过诺贝尔编程奖就一定拿过诺贝尔数学奖,那绝对是扯蛋。数学是用来培养逻辑思维能力的,这种能力在编程中也十分需要

一直在想的还没答案的问题终于有答案了,真好

佛把一切执着都放下了,但唯独对于人生的思考是执着的。

俺以前是学数学的,只可惜没学好。

谢谢!

好文章,把数学在编程中所起的主要作用娓娓道出。

看了下面的某位仁兄的留言,分清做工程和做理论?不敢苟同

就我做项目做工程的时候,大量的数学应用是我们原来不可想象的。在工厂里和工人交流做了之后,就感觉,不仅仅停留在设计界面和设计数据库方面。仅仅是用户端和数据存储端。而中间的逻辑,不用数学分析去做,很难。不仅仅是UML画画图的事情。

数学?我以前就在思考,数学到底给我带来了什么?

我爸爸说,数学是一切理论和应用科学的基础。我一直都记在心里。

后来感觉到,学习数学可谓给我带来了一种训练,可能是逻辑思维的训练,或者其他的训练,谁知道呢。

但学了数学,和没有学,就是两个概念的思维。

有一本书叫做《身边的数学》,英文版,介绍了我们平时用到数学的地方。会发现其实数学无处不在。

我和我原来的朋友在讨论中,他说,我们中国人搞数学的,都是在证明什么什么,而没有发现认识新的数学理念。

陈景润先生是我们所敬仰的先辈,但是他也仅仅停留在“证明”哥德巴赫猜想的阶段。也仅仅是解题。其实,也与他那个时代的背景有关。

数学应用在编程上的地方那就太多了,其实本来我们用的就是Computer。而离散数学本来就是程序员应该学的一种基础。

现在我的工作就是写程序帮我的同事分析股票还有期货行情,他们证明好的一个个数学模型拿过来都要实现为程序。本身就是数学应用的体现。

我在做纺织项目的时候,一个流程的设计搞不明白,我们原来的经理乐呵呵的过来了,说有什么问题,我说这个流程实在理顺不清楚,他看了看说,这不就是一个统计学的应用吗?之后我跟他学了点统计学,把流程很容易的理顺了。我很惊叹于分析之后的程序设计,利用各种手段,而数学会在其中占很大比重。不跟他学,我根本不理解流程与统计学还有关系。

后来还跟他学了些数学方面的模式分类,有关概率和统筹方面的,比如抽样这种在工厂里Qc保证。这个模式不是我们OO编程方面所提到的“模式”,是数学范畴的模式。之后他建议我看《组合数学》这本书。

我在编写游戏的那段时间就不用提数学的作用了,这方面云风是同行。

Knuth先生组织编纂了《具体数学》这本书。作为计算机算法的基础。

编程上数学理论及其应用的方面太多了。学了自然会有用到地方。

有些数学理论,学了没有坏处,为什么不学?华罗庚先生的书很好,可以看看。

虽然我在文章中并没有写“常理”二字,但这里也没有必要玩文字游戏。

说说自己的理解:如果以“常理”来指代文章所提到的句子的话,我认为数学上的“常理”和物理上的“常理”是两类事物。

物理探究的我们所处世界的“真实”,数学只是找出“真实”的工具,其本身并不能证明真假。

高斯当年想通过测量三座山峰形成的三角形的内角和是否等于 180 度,来试图发现欧式几何和非欧几何哪个更能真实的描述我们所处的世界。但他同时也明白,无论结果如何,不同的几何在数学上都是同时成立的。

不太认同云风所说的
"做 3d 游戏编程,大学里的线性代数可能还用的到一点。至少得知道矩阵运算吧。但是大部分程序员并不需要接触这些东西。除此之外,如果说程序员必须精通微积分才能编程,那绝对是鬼扯。"

做 3D游戏编程的连计算机图形学都不熟悉的话 最多只能算一个coder
计算机图形学的基础就是 解析几何
微积分 和 线性代数..
比如:直线Brasenham算法就是解微分方程..

反证过程中以是否违反“常理”作为反证依据似乎有些不妥,要不量子论岂不早就被反证了?

关键还是看做工程还是做科研,
将来的编程模式会进一步拉近两者的关系,

我觉得云风写那么多文章,对于绝大部分读者而言。就这篇最有价值。

真的,希望云风以及别人不要就此抬杠。

佛经里的“执着”不是指“执着”某件事物,它指的是世间万物的本质是不断变化的,生死的轮回,快乐得失的轮回,世上一切的一切都是在变化中存在的。呵呵!所以你那个朋友理解的“执着”本身就是字面游戏。
我到现在连《心经》都没记清楚,还是很惭愧!不过,我相信如果真遇到天灾人祸,光念观音菩萨还是不够的,那也只是心里安慰。

数学修养重于知识,就好比算法修养一样,做JAVA或者.NET的应用大多不需要什么算法知识,但个人认为算法修养是必备的.

好文,很就没有看计算机的书了,都在看其他方面的书

非常认同此文。

一个人的直觉的确不是从天上掉下来的,而是日积月累而来的。

用直觉提出问题,用逻辑解决问题。

@2楼

...那是最基本的逻辑啊...A => B <-> ~B => ~A

当然 如果A<=>B 那么~A <=> ~B

充要条件哟,不是充分条件。什么是充要条件?

如果你不在家是你女朋友在家的充要条件的话,推论很寒:你一出门(去女朋友的家?),你女朋友就会等在家里(此为充分条件);而你回家了,你的女朋友一定在外游荡(去你家了?)。(此为必要条件)

笨~刚刚把“该曲线才存在”看成了“该曲线存在”。

"当且仅当费马大定理不成立时,该曲线才存在。最后,通过证明这种曲线有一些极端奇怪和不可信的性质,决定了曲线不可能存在,从而反证了费马大定理成立。"
这段话貌似有问题……

费马大定理不成立是曲线存在的充分必要条件……但是,反过来不能够说曲线不存在是费马大定理成立的充分条件……

就好像,如果我不在家,我女朋友一定会在家;但是我女朋友不在家,并不代表偶在家。

奥文!

好文

工作上有些方面的开发需要很扎实的数学功底.比如,舌脉象仪这个产品在设计实现数字信号处理算法和图形分析算法上.

抽空看一下你推荐的<什么是数学>,是本好书.

BTW,同感,真正的程序员不用担忧30岁以后做什么.

对,不断的编写代码本身并不能直接提高编程能力.学数学让人喜欢刨根问底.

做研究,写算法的,跟做具体应用的,分工不同,侧重点不同。

我觉得计算机软件发展到今天,关于计算机软件本身各个方面都研究的趋于成熟了,比如操作系统,图形界面,软件工程。可以预见随着硬件的不断升级,编译开发语言工具的不断升级,软件开发的自动化在将来不是不可能的事情。
计算机科学发展的推动还是取决于不同的应用而这其中不可少的会大量利用数学工具。比如数据库,海量数据的算法,数据压缩(有损压缩中的多数算法),信号处理(FFT变换等),计算机语言的进一步发展(可能需要用到数理逻辑)和计算机游戏(3D的物理模型,接近真实图像的算法),都是建立在高等数学工具上的。当然在今天一个纯粹的工程师可能不需要太多的数学可以搞定国内很多低端的开发应用。但如果想进一步发展,做真正的研究开发工作,深厚的数学背景肯定非常重要。
简单的例子就是,The art of computer programming的作者Donald Knuth, 就是纯粹的数学出身的大师。而且查看他书中的代码,简单,精致,巧妙决不逊于当代Michael Abrash或John Carmack在游戏应用中的各种代码优化技巧。
科学+工程的大牛可能是当今最缺乏的吧。当然,我只能仰望这样的大牛了。希望中国也能出这样的大师。

一直在思考类似的问题,却不知道如何表述,看完此文才知原来如此,呵呵。

受益良多,好文!

比如说,做CAD软件的,就会用到一些几何方面的数学。。。

我觉得读书真的是一件好事,数学的也好,人文的也好,编程的也好,自己最近也买了两本大部头的<<深入解析Windows操作系统>>和<<代码大全>>,现在在看第一本,但是发现读的热情没以前那么强了。。。

Post a comment

非这个主题相关的留言请到:留言本