这个问题应该从机器语言是怎么工作说起的。
在计算机的太古宙时代,在制造一台计算机之前,首先要做的是为它建造一座能够容纳它的大房子。然后还要配接上水电资源,因为它运行起来就要耗费半座城市的电能,散热也得跟上。
而能够操纵这样的由电子管组成的怪兽的人,则是看起来低调神秘的科学怪人,他们在一卷纸带上打上不规则的孔,送入机器,然后等着这台怪兽一阵轰鸣之后在纸带上输出结果。
而这样的机器也仅能进行算术运算,那些穿孔纸带组成的神秘符号,就是机器语言。
下面看一段机器语言的代码吧:
A10010
8B160210 01D0 A10410
要是有谁一眼就能说出它的功能,那么请接受我双膝跪地顶礼膜拜。如果看不明白,也没关系,后面语言越高级越容易看明白。
上面的每一条语句就是CPU可执行的一条指令。CPU常被比喻成计算机的大脑,因为指令的计算最终是由它来完成的。
而指令通常包括运算和赋值,往往单条指令的动作都是简单的,只做一件事情。我们通过把多条指令按顺序排列让CPU执行,以此来实现复杂的逻辑。
可想而知,如果要这样写代码,人类还怎么进步?于是科学家们就做了一下改进,让代码好懂了些,这就有了汇编语言。
将上面机器的代码翻译成汇编语言:
mov AX, X
mov DX, Y add AX, DX
mov Z, AX
在这里我们可以看到,神秘的字母和数字组合转化成了有意义的单词和字母了。学过汇编语言的同学们自不必说,没学过的也可以大略猜测到,mov应该就是move的缩写,是搬运、赋值;add就更好理解,加法。
而汇编的特点是它虽然比机器语言更好理解了些,但它和机器语言也是逐条对应的。要想实现复杂的逻辑控制,写出来的代码仍然很不好理解。
科学家们再一次对编程语言进行了改进,而这一次则是飞跃。
诞生于1957年的Fortran,以及1960年左右发布的COBOL,被认为是最早的计算机实用编程高级语言。它们相对于汇编语言的改进在于,语句不再和机器指令对应,而是更接近自然语言。
所以高级语言中的“高级”二字,并不是说新的编程语言有多么先进,而是说它们在系统中处于更高一级的抽象。高级语言的代码更适合于人类编写与阅读了。
例如前述的机器语言和汇编语言代码,如果用Fortran语言写出来,就是这样:
Z = X + Y
怎么样?即使不懂编程,也能看出来是什么意思吧,这类似一个数学算式了。当然,在计算机语句里,这是一条赋值语句,和数学语境中的等式还是有所不同的。
而高级语言需要通过编译器,将文本符号翻译成机器可以执行的指令集。编译的过程一般分为四个过程,分别是预处理、编译、汇编、链接,最后得到可执行文件。
可以使用近似于自然语言的方式写程序,这显然有助于编程技术的推广,也推动了计算机的普及和软件的快速发展。
可是编程的效率提高之后,另一个问题也随之而来。那就是代码缺少规范,只要能实现功能,大家可以随心所欲地写代码。尤其是对goto语句的滥用,导致代码混杂扭曲,因此这样的代码也被称为“面条式代码”。
当软件需求进一步膨胀时,这样的编程效率又跟不上发展了。由此在20世60年代爆发了软件危机。1968年北约在联邦德国的国际学术会议上正式提出了这个名词。
软件危机的意思就是说,大家照这样去写代码,那么再过几十年,全人类都去当程序员也生产不出实际需要的软件来。确实有点危言耸听,但我们知道现在并没有出现那么骇人的景象,这都要感谢科学家们在编程思想上的进步。
同样是在1968年,荷兰计算机科学家Dijkstra在写给ACM通讯的一封信中,声明应该在程序中废除goto语句,只需要使用三种基本结构就可以完成所有的程序功能。
这封信就是著名的“GoTo letter”,由这封信开始掀起了结构化编程的浪潮,Dijkstra也因为他在计算机技术上的卓越贡献,在1972年获得了图灵奖。
Dijkstra老爷子
Dijkstra提出的三种基本程序结构,分别是顺序、选择、循环。
顺序 就是从第一条语句开始,直到执行至最后一条语句结束,中间每一条语句都要被执行到。
选择 则是根据条件判断,程序决定执行相应的语句。
循环 则是判断条件,重复执行语句。
上世纪七十年代,诞生于贝尔实验室的C语言是最知名的结构化编程语言。同时C语言也是使用最广泛的编程语言。
时至今日,得益于物联网的快速发展,在IOT技术栈中占有重要地位的C语言,又在TIOBE编程语言排行榜上大放异彩。对于一门存在了四十多年的编程语言来说,这不能不说是一个奇迹。
C语言因其简洁的语法,同时具备对系统底层的操作能力,成为编写操作系统及底层服务的最佳选择。
软件危机终究还是没有爆发,人类也从单机时代进入了互联网时代。人们又需要开发起来更快、还要更好用的编程语言了。
面向对象编程的英文是Object Oriented Programming,下文中简称其为OOP。一般来说,支持OOP的语言都包含三个特性,即封装、继承和多态。
其实最早的面向对象编程语言是Simula 67,它诞生于1967年。在当时,OOP所要求的三个特性,Simula 67就都具备了。
所以面向对象技术还真不是我们遇到危机时才发明出来的,而是早已存在,但在60年代时太过超前而并没有被普及开来。
直到互联网和PC兴起,快速产品化的要求催使人们去寻找更适合的方法。语法像自然语言已经远远不够了,编程语言最好还能符合人类的自然思维过程,而OOP包含的三个基本特性,正好满足了这个要求。
如今我们在学习面向对象编程语言时,老师都会通过现实世界打比方。例如定义一个类就相当于画好了一张汽车的设计图,所有的细节都隐藏在私有方法中,对外只公开操作方法,包括启动和停止等。
通过类,就能派生出一个实例,也就是一辆实际可以开的车。你调用公开的方法就能开车上路了,而且不用关心它内部是如何运作的。你只要能把奥迪开起来,那么宝马你也能开。
JAVA、C#、php等语言正是在这样的背景下兴起,它们上手简单,一名新人经过短期培训就能上岗工作。这降低了软件开发的门槛,也让互联网企业具备了快速拓展业务的能力。
C++语言在早期因其包罗万象的特点,曾被大神Linus痛批。但在C++ 11发布之后,C++被注入了许多现代编程语言的元素,也被称为Morden C++。如今C++已经大量应用在游戏引擎、人工智能、大数据等领域的基础组件构建中。
当进入移动互联网时代之后,编程语言发展更加快速,但都会具备面向对象的三个基本特性。
在终端,苹果公司推出的编程语言就有Objective C、Swift。以谷歌为主导的Android平台则使用java、C/C++、Kotlin。
编程语言不断推陈出新,但只要是支持OOP特性的,对程序员来说就可以快速上手工作。这可能也是中国在移动互联网时代拥有诸多优秀企业和应用的原因吧。
纵观编程语言的发展,可以清晰地观察到,它是朝着对人越来越友好的方向的。从便于识别,到易于阅读,再到符合自然思维习惯。
编程语言前进的每一步,都是为了让人在使用这种工具时,能够更有效率地实现功能,达成目标。在一个阶段被满足之后,快速兴起的需求又会推动编程语言走向下一个时代。
可以推测,基于人工智能技术的辅助,编程技术将不再需要经过大量专业学习才能掌握。任何人只要具备逻辑表达的能力,就能生产出符合自己需要的软件产品。
这样的设想在现在看来可能是太美好了一些,因为有科学家认为完全不需要人工干预就不太可能,因为机器无法处理所有的细节。
我也很好奇,在未来编程语言会是什么样呢?