关于编程,我的理解
写给某个小朋友看,希望我的一点看法,能有用。欢迎讨论。。
为什么会有编程语言?
计算机史前有过不同的理论,但最后活下来的,只有图灵机一个模型。现在的计算机,都是基于此发展的,跟二战前那个三层楼高的计算机,没啥区别,那个机器一堆开关,人工操作。CPU做的计算也是开关的逻辑计算。所以计算机的语言是01二进制,一开一关,告诉计算机要不要发出电子脉冲。写一个程序全是01数字组成的,对于人来说是mission impossible!所以必须要有编程语言。编程语言就是为了抽象计算机机械原理的一面。
LOAD A ADD B STORE C
实现两个数的加和,这是人类可读的语言,而不是一串01所组成的不可读的机器语言。
抽象是最关键的。所有的编程语言都是为了实现抽象。越是高级的语言,抽象度越高,抽象度越高越好!
机器可以被抽象,CPU可以被抽象,操作系统也可以被抽象。抽象就是使我们可以站在一个更高的角度来思考问题,乃至于思考的只有问题本身,而不必管机械,不必管指令集,不必管操作系统。那么我们的生产力就越高,我们就越有能力做更多的事情。
为什么要学编程?
我觉得文科是不必要学编程的,文科也需要处理一些数据。但是都有用户界面友好的专业软件可以使用。比如金融的eviews(http://www.eviews.com/),要做统计分析,不必要学SAS或R,会用excel或spss就可以了。师夷长技以制夷,能够解决问题是王道。
理科的话,我觉得就有必要学了。每个人都应该有属于自己的工具箱。而编程绝对是powerful tool。
学什么语言?
许多人喜欢问这样的问题,而且多半是这山看着那山高,这问题是没答案的,适合自己的最好。学脚本,不要学编译性的语言。比如C,编译性的语言,唯一的好处是程序运行速度快,但是现在CPU够快了,这个可以忽略。但是编译性语言,要花很多时间在调试上。人力资源才是最宝贵的。编译性语言的另一个好处是可以让你从计算机的角度去思考问题,这回到我所列的第一个问题去看,抽象才是王道。我们不是做系统开发的,不需要知道低层的东西。十年前还在吵着该不该让计算机管理内存,除了老程序员之外,现在已经没人会手工管理内存了,这些东西交给计算机自己搞,我们不需要学。学了也是白学。而且没用。白白耗费人生最精华的时间而已。
每个语言都有自己的特色,像C本来就是为写操作系统设计的,所有的操作系统都是C写的。fortran是为了做数值计算的,现在很多计算的软件如R,都是C和fortran混着写的。像pascal,是一个老师设计给学生用的,好多烦人的规则,但结构化很好,现在看很多计算机的书,里面的代码都是pascal或类pascal的伪代码。每个语言都有自身的优点。优点通常也是缺点。用心学好一个。知识是相通的,一理通,百理明。
我推荐学python,Larry Wall说Perl像洋葱,最大的价值在于裹在它上面的一层又一层。这句话适用于所有语言。.net的精华在于微软找一帮人写了个暴大的类库,java也是,因为sun那帮人写了很好的类库。python现在发展得很好。几乎所有东西都有python的接口,现在如果有人发布个新的C库,没写个python的接口,他都不好意思发布的。还有一点,就是所有语言都打上了设计者的烙印,好处同时也是坏处。像larry wall是个语言学者,他设计的perl就有很多自然语言的特征,这本身是它最大的好处,很灵活,但同时也是它最大的坏处。代码看上去比较乱。而且有很多trick。python的作者说,他要设计一个清晰的语言,让所有人都会写代码,或许某一天,你可以为家里的微波炉写一段控制程序。要清晰,必然就会死板,好处与坏处是一起来的嘛。比如对于程序的缩排都有规定。死板归死板,对于初学者来说,可以养成很好的编程习惯。可以写出结构清晰的代码。
怎么学?
学任何东西都一样,是一个爬坡的过程。不要在半山腰停下来。一停下来就会滚下去。一定要爬到平台期,这时候停下来了,也不会掉下来的。不要急于求成,没什么东西是一下子就掌握的。如果是这样的话,那就没必要学了,因为不值钱。会别人不会的,才显得专业。实验室来了个新生,一来就说要学perl,问他为什么,他说看到实验室有本书,24小时精通perl,我跟他说,幻觉,我用了三年,也没精通。看了一本R for beginner就跟我说,”来吧,出两道题来做吧“,我让他算1万以内有多少个素数,竟然算了半小时,还算错。现在的新生都比较燥。反正别急于求成。慢慢学。最初概念是最重要的。一定要清晰。入门也不难,语言内置支持的几个数据类型弄清楚了。无非就是判断语句,循环,还有函数。基本的语法就这些。学了这个,就可以干很多事情了。可以简单地处理一些文本,处理一些数据,可以让一些重复性的劳作自动化。像我本科的时候,网络认证的程序断线了不会自己重连,每次发现上不了网,我都要去杀了那个进程再重新运行一次。后来我就写了一个脚本干这个事情。就不用再每天做N遍无聊的相同动作。
会处理简单的文本,会处理简单的数据,然后会画点简单的图,就够了。编程语言是我们的工具,我们不是专业的coder。别试图掌握所有的东西,无底洞,学不完的。
再进一步的话,面向对象的概念需要掌握。理解就行。面向对象的实现有三个基本的概念:封装、继承、多态性。封装就是实现类内部对于外部的不可见。一个对象可以看成是对一个具体问题的抽象。里面有自己的数据类型,有操作数据的方法(函数),我们只需要知道它的行为就行,不必要知道它的内部实现细节。对于现实的问题,编程语言内置的数据类型,可能无法满足我们的需要,我们可以自己写数据结构来表征数据,这个实现的关键在于指针,也就是内存中存储数据的地址。指针是所有高级数据结构实现的基础。这种东西费时费力,容易出错。所以说面向对象提高了生产力。因为对象里面定义了表征数据的数据类型,而且还有操作数据的方法,而它的实现是我们所不必关心的。继承就是子类可以拥有父类的方法,这个应该命名搜索空间来实现,调用了方法,但对象里没有定义,便往父类对象里搜索。如此反复直到找到方法为止,找不到会报错。多态性,就是指不同的类可以拥有相同的方法名,这个也是基于命名空间,所有的对象都有自己专属的命名空间,一个封闭的环境。这三个概念我基于自己的理解,解释了一下,我没正经地看过面向对象的书。可能有错。
十几年前,还是软件匮乏的年代,现在应用程序多如牛毛,因为开发的门槛降低了,程序很容易写。很大程程归因于面向对象。就如第一个问题所说的,抽象层次越高,生产力越高。对象就是我们的building block,以前是需要自己造的。现在不需要,有现成的,我们只需要知道怎么砌砖就行了。当年软件开发越来越庞大,遇到了瓶颈。所以出来了面向对象这个东西。把数据抽象了,把操作抽象了。程序员就可以站在更高的层次来思考。
回到第一个问题,还是抽象,面向对象就是更高层次的抽象。基本上我们所能碰到的问题,这个世界都有人遇到过了。会用别人实现的东西,而不是自己重新设计轮子,是很关键的。面向对象被指责的地方是造就了一帮只知其然不知其所以然的低级程序员。这句话是某种层面上讲是对的。但记住我们不是专业的程序员,我们不需要了解内部的细节。我们也不需要自己去实现这些。我们编程是应用层面的。解决我们自己遇到的一些问题而已。我们只需要站在别人的肩膀上。记住第一个问题所说的,越抽象越好!
学到这里就足够了。。20%的知识可以解决80%的问题,剩下的,那80%,你学了,也只能解决,极少遇到的20%的问题而已。如果有需要,再作讨论。
再唠叨一句,不要急于求成,太着急了,学不好,而且容易有挫败感。我学了这么久,也依然只会写一点简单的代码,做一点简单的事情而已。
代码运行出错,或者异常,要思考。想不出来,要google,会找答案,是很关键的能力,找答案的关键在于把问题本身描述清楚。想不懂的,通常是想错方向了,上网找,不要钻牛角尖。
最后送上《料理鼠王》的一句台词,everyone can cook…
编程就像做饭,每个人都能编程!
照着菜谱来就行了。简单的问题很简单。复杂的问题,解决的关键在于把问题分解成简单问题,而分解的关键在于你怎样把子问题的答案粘起来,得出问题的最终答案。
----
写完了,自己看一篇,好虚啊。。嘻嘻,务虚不务实嘛。。
具体问题具体讨论。。