讨论:写程序到底需不需要懂数学?

数学系所学的数学,跟一般人所会用到的数学不太一样。研究所顺利考上的向往已久的资工所,成为名符其实的本科系学生,本以为可以不用再玩数学了,但我发现我错了,是不用再玩那些抽久的高等数学没错,但线性代数、机率统计、离散数学等...用了更多的数学,我想不出来有哪门资工研究所的课没用到数学的。写程序需要数学吗?  
写程序到底需不需要懂数学?

piggy | 08 Jun, 2007 17:26

数学对于程序设计师来说到底重不重要?!类似这样标题的讨论,在网络上已经不知道被讨论多少次了。前两天又在老同事小白的blog上看到了他的看法。以前正方总是喜欢拿算法与效率来表明数学很重要的立场,反方或是最近普遍的观点是要依照需求。两方都没错,我也有一点小心得跟大家分享。

先来谈谈「数学」在大家的心中是长什么样子。我大学时念的是辅大应数,会选应数的原因是一、我的分数上不了资工,二、应数又跟纯数不一样,是比较偏计算机应用的(事实上不是这么回事),应数的全名是应用数学。三、高中时一位要好且计算机很强的同学也是念辅大应数,所以我就这样进了数学系。在一般人眼中是个很硬的科系,那几年全校1/2的名单中,数学系就占了一半。数学系所学的数学,跟一般人所会用到的数学不太一样。除了几门工科必备的微积分、线性代数、机率统计外,剩下的都是高深且抽象的数学理论,像是高等微积分、高等代数、几何学(不是三角形、正方形那种简单几何)、拓扑学等。这几门课程跟本像天书一样,非常的抽象(无法画在直角坐标系上),我能毕业也算是一种奇迹啊~~我真怀疑我那学念到博士班的同学们,他们的脑袋是不是跟我长得不一样。

研究所顺利考上的向往已久的资工所,成为名符其实的本科系学生,本以为可以不用再玩数学了,但我发现我错了,是不用再玩那些抽久的高等数学没错,但线性代数、机率统计、离散数学等…用了更多的数学,我想不出来有哪门资工研究所的课没用到数学的。而且你最后的硕士论文要写出来,数学更是不能少的。你以为玩网络不需要数学?大错特错,里面一堆机率统计的东西。电机需要数学吗?当然需要!最基本的傅利叶转换就够搞死你了,所有工科的系所都逃不了数学的魔掌。就算你到了管理学院,会计系要数学、经济系要数学、连心理系有些领域也需要数学。虽然所需要的数学不尽相同,但都在数学的领域里。我开始后悔当年没把数学念好,博士班念到一半念不下去了,其中一个原因是我数学太烂了。

写程序需要数学吗?要看程序的目的?那我们就像讨论一个简单的程序,算出1加到100的总和。

完全以程序结果为导向的人,或是训练有素的程序女/男工,甚至有时连我都会很直觉的写出这样的程序:

int sum = 0;

for (int i=1; i<=100; i++)

sum += i;

上面这个程序片段还算很容易让人一眼就看懂,可是我们明明国中时就学过了这种数列级数的算法了,怎么还会写出上面这么笨的程序呢?

int sum = ((1 + 100) * (100 - 1 + 1)) / 2;或更精简的

int sum = (101 * 100) >> 2;

这个例子已经被说烂了,我们来来看另一个例子,计算1加到10000,奇数和偶数的总和。用循环的话,一样很直觉得就写出来了:

int oddSum = 0;

int evenSum = 0;

for (int i=1; i<=10000; i++)

{

if (i % 2 == 0)

evenSum += i;

else

oddSum += i;

}很简单的程序吧!可是我们稍稍的用我们有12年(国小到高中)的数学背景想一下,你可以写出更精简的程序:

int sum = (10001 * 10000) >> 2;

int evenSum = 5001 * 5000;

int oddSum = sum - evenSum;什么?看不懂?!sum应该知道怎么算出来吧?就刚刚第一个例子是1加到100,现在改加到10000而已。evenSum呢?简单的推理一下,1到10000之间的偶数总和是是2+4+6+...+10000,把它们全部除以2的话会变成1+2+3+...+5000,所以1到10000偶数的总和不就是1加到5000的两倍吗?

1加到5000是:

(5001 * 5000) >> 2两倍就不用除那个2了,所以不就是上面那个算式了吗!

那1到10000奇数的总和不就是全部的总和减掉偶数的总合吗!稍微动一下脑袋,可以让你的程序变得很有效率。怕别人看不懂?是不会加个批注在程序代码里面喔!

相信聪明的你,很容易就可以分析出来这两个例子的两种写法,在效能上迶多大的差异,但这不是我在这里想要表答数学是如何如何增加效率的。我想要表答的是,我们明明辛苦了12年,学了一堆的数学,为什么我们要放弃这样的基本训练?我们笑美国人的数学不好,请问你又用了多少的数学来帮助你的生活和你的工作?学了又不用,那不如从小学开始就分科系好了,不喜欢数学、怕数学的,就选完全用不到数学的科系。

我今天不是要大家在写程序是时钻研那种算法、功式等,去计较那些在现在动不动在2GHZ, 3GHZ,双核心、四核心之下,所省下的那微小的效率。而是你的态度!你宁愿多打一些code,也不愿动一下脑筋,如果你的态度是这样子的话,那也是活得下去啦,不过你的水平就不过如此而已。

你会反驳说,需要用到算法、要讲求效率时,我再去研究一下就好了,干嘛说的很严重似的。今天我们一时兴起,要去爬阳明山,没问题啊,那种程度的山,只要双脚健全走得动的人都能爬。如果换成现在流行的登山步道呢?这需要一点点体力才行。如果你要去爬台湾百岳呢?合欢山的东峰算是最简单的吧?开车到山脚下,穿个好一点的鞋子、好一点的衣服、多一点的体力,也还不是太大的问题。那爬玉山呢?虽然现在爬玉山已经很方便了,连行李都可以请人帮你背,但平常没有一些训练,要爬上去不是那么容易的事。你要站在世界的最高点,去挑战圣母峰,那全世界没几个人办得到,而且办到的人事前可是经过了严格的训练。

你想把自己摆在什么位置?你想要成就到什么样的高度?如果你只想在小小的台湾,在二、三流的公司里,打打项目游击战,赚个还算可以的薪水,那的确,你不怎么需要数学,连软件工程的理论也不太需要,最重要的唬弄客户的技术纯熟就可以了。去年去了101的37楼面试后,我才知道我了不起只爬到阿里山而已,要登上MountainView这座山,我必需十倍努力才行。而这个努力不是我在面试前,看看什么教战手册、写写网络上的考古题我就能够通过的,而是必需把一些数学的训练熟到变成很自然的反应才行。简单的问你就好了啦,上面那个用循环写的1加到10000的那个例子,如果10000改用n的话,那需要多少时间,用大O(big O)来表示。如果你不能很快的推论出是O(n)的话,那你的履历连投都不要投,在37楼问的问题比这难多了,而且你没几分钟的时间可以作答。去年那次,是我第二次后悔当初没把数学学好。

为什么Google会这么重视算法和效率?应该说世界级的大公司都重视,Yahoo、微软、YouTube…,因为你写的程序不是给几十个人、几百个人用而已。而是同一时间有几百万,甚至上千万人使用。一个人慢0.1秒好了,一百万人就10万秒,超过一天耶。浏览一个网页,慢个几秒钟你都不能忍受了,更何况是一天。你说能不计较算法和效率吗?!

你想过什么样的生活是你自己决定的,但你想要当个世界级的软件工程师的话,把学数学就当作是一种修行吧!不要怕没地方用,因为你时时刻刻都可以用到它。当你的修行到了某个程度,要挑战高山,就比别人容易多了。

好好好,不想深入就算了,但你不觉得放弃12年的数学训练很可惜吗?至少花点脑筋用一下嘛~~,大家都多少用一点,软件的水平就会慢慢提升了,你说是吗?

时间: 2024-10-27 13:30:49

讨论:写程序到底需不需要懂数学?的相关文章

你写程序再牛,也未必懂我写的文章!

[导语]如果你觉得这篇文章是喊口号,那你就错了.前面写的很多文章,其实都是一步步写上来的,内容上有连贯性,但分章阅读也影响不大.很多内容谈到心,心强大,无坚不摧.心态.视野.格局等等,这些东西说再多,对不同的人,效果也不一样,其原因是心有不同. 一.大道甚夷,其人好径 这句话来自老子<道德经>,老子要表达的真正意思,肯定不是我写的这篇文章理解的那样,我说的只是最肤浅的'望文生义'.老子说的大道,其实是体道.悟 道.行道的正确方向.意思是说人们体道,然后悟道,然后行道,这个通向道的路其实很平坦,

讨论:程序员高手和菜鸟的区别是什么?

随着做软件的时间越来越长,我发现,做软件越来越难.难在哪?难在怎么做出一个好的软件.好的软件标准是什么?两个词,好用,好看!程序员的最大价值在于做出好用又好看的软件的能力.因此,我觉得程序员的价值绝对不在于技术本身,而在于做出好用且好看软件的能力.这是一个开放性的话题,每一个人都是菜鸟过来的,我希望和祝愿每一个技术人员都能尽快成为高手,也希望更多老鸟来分享经验.在这篇文章,我将根据自己的经验来分享,期望能给人有更多的有帮助的信息.在这里,我只想从技术角度来分析,技术不一定和收入相关联的. 1 命

讨论:程序员高手和菜鸟的区别是什么? - 道法自然

随着做软件的时间越来越长,我发现,做软件越来越难.难在哪?难在怎么做出一个好的软件.好的软件标准是什么?两个词,好用,好看!程序员的最大价值在于做出好用又好看的软件的能力.因此,我觉得程序员的价值绝对不在于技术本身,而在于做出好用且好看软件的能力.这是一个开放性的话题,每一个人都是菜鸟过来的,我希望和祝愿每一个技术人员都能尽快成为高手,也希望更多老鸟来分享经验.在这篇文章,我将根据自己的经验来分享,期望能给人有更多的有帮助的信息.在这里,我只想从技术角度来分析,技术不一定和收入相关联的. 1 命

用CIL写程序:写个函数做加法

前言: 上一篇文章小匹夫为CIL正名的篇幅比较多,反而忽略了写那篇文章初衷--即通过写CIL代码来熟悉它,了解它.那么既然有上一篇文章做基础(炮灰),想必各位对CIL的存在也就释然了,兴许也燃起了一点探索它,掌握它的欲望.那么小匹夫就继续扯一扯CIL,接下来的几篇文章也都以上一篇文章中的那个CIL实现的Hello Wolrd程序为基础,继续通过写CIL代码实现一些功能的方式来和各位探讨交流,同时也加深自己对CIL的掌握和印象. 人生就是做加法 "我的肩上搭着她得衣裳,我嗅着她留在衣服上的体香..

用CIL写程序:这个叫“慕容小匹夫”的类

前文回顾: <用CIL写程序:你好,沃尔德> <用CIL写程序:写个函数做加法> 前言: 今天是乙未羊年的第一天,小匹夫先在这里给各位看官拜个年了.不知道各位看官是否和匹夫一样,摸键盘的手都已经有点生疏了呢?所以,为了不忘却程序猿的使命,不冷落程序猿最好的伙伴--键盘.匹夫决定来写<用CIL写程序>的最新一篇文章.可是写什么主题呢?之前匹夫也介绍过CIL其实也是面向对象的,所以寻思着大过年的,不如就写一个类,一个用来抽象化小匹夫的类吧,既可以介绍下小匹夫,小匹夫也可以借

菜鸟谈算法和数学对写程序的影响

首先声明,本人在数学和算法上没什么造诣,只是发表一下自己的观点吧,最近一段时间在学习算法.引用一下我大学的时候的一位老师(刘伟)的一篇文章,这是他在CSDN上的一篇文章,他也一直是我人生中的偶像.http://blog.csdn.net/lovelion/article/details/1350127 因为自己进公司的以来,一直从事的是C#和JAVA方面的开发,而且框架都是调用公司的框架,所以一直感觉数学在编程当中不起到什么作用.PS:不是数学的作用不大,而是自己确实对这方便很菜,所以才会有这么

[讨论帖] 程序员如何赚外快?

昨天的一篇文章一个程序员如何快速赚到一百万?引起了大家的热门讨论,现在另开一个贴,讨论一下如何赚钱. -------------------------- 挣外快需要的是大量的业余时间和强大的意志,如果你是个每天工作十几个小时天天累得像狗一样的话,那不是太容易. 我自己的情况 在三线城市,工作说不上忙,和公司领导(前公司和现公司)关系不错,加上能力也被他们认可.他们有人有资源,所以偶尔有单都会叫上我.单的大小看情况,刚开始的时候两三千的单也接,现在基本没 10k 都不谈了,没什么意思.这算是被动

用CIL写程序:从“call vs callvirt”看方法调用

前文回顾:<用CIL写程序系列> 前言: 最近的时间都奉献给了加班,距离上一篇文章也有半个多月了.不过在上一篇文章<用CIL写程序:定义一个叫“慕容小匹夫”的类>中,匹夫和各位看官一起用CIL语言定义了一个类,并且在实例化之后给各位拜了大年.但是那篇文章中,匹夫还是留下了一个小坑,那就是关于调用方法时,CIL究竟应该使用call呢还是应该使用callvirt呢?看上去是一个很肤浅的问题,哪个能让程序跑起来哪个就是好的嘛.不是有一句话:白猫黑猫,抓到耗子就是好猫嘛.不过其实这并不是一

019写程序在一棵二叉树中找到两个结点的最近共同祖先(keep it up)

写程序在一棵二叉树中找到两个结点的最近共同祖先. 分两种情况来讨论这个题: 第一种情况结点中没有指向父结点的指针 第二种情况接种有指向父节点的指针 我们先看第一种情况,结点中没有指向父结点的指针. 我们可以采用暴力搜索每一个结点,如果这个结点的子树中 有已知的两个结点,那我们就继续沿着左右子树找,如果左子树 能找到,我们就继续沿着左子树找,如果有子树能找到,我们就 沿着右子树找,不存在两个子树都能够找到. 代码: struct TreeNode {<pre name="code"