当前位置: 华文星空 > 知识

如何给一个外行人解释:世界上第一个程序是如何写出来并让它按规定运行?

2016-11-01知识

一堆土怎么盖出高楼大厦的?其实是一个道理,两个字,工程。

完成一项大的工作,有三个步骤:

  1. 找到一个可行的理论,这是科学的范畴,也是最困难的一步
  2. 将理论的可行性转化为实践的可行性,这是技术的范畴,同样需要天才和灵感
  3. 用这个可行的方法重复一千遍,在这个过程中找到最有效率的执行方案,然后再重复更多次来做出更复杂的应用,这是工程

工程是看上去最神奇最宏伟的一步,但其实是最不复杂的一步,毕竟路都铺好了,工程师们通常要做的只有:

  1. 创造出更合理的工具来提高工作效率
  2. 发明出更合理的分工来提高工作效率
  3. 总结出更容易学会的经验来提高工作效率

它无非是对于这件事,要如何把更多的人力投上去、让这些人力发挥最大效率、从而在最短时间内完成工作的问题,跟前两步来说,根本没有什么困难的。就像研究力学原理最困难,发明大楼的设计方法其次,而设计出大楼并没有那么难,照着图纸施工更是搬砖的活了。

对于计算机科学也是这样的。提出存储程序原理的冯诺依曼是天才,提出可计算理论的图灵是天才,发明出晶体管的肖克利是天才,发明锁存器、DRAM、总线、操作系统原理、编译原理、C语言……这些天才的名字我甚至没法一一叫出,我们这些工程师只是在前人种下的大树下,用前人发明好的方法重复着自己的工作,同时尝试着做出一点点微小的贡献而已。


计算机能进行计算,首先归功于非线性元件的发现,这个开端还不是半导体晶体管,而是继电器、电子管等等。在这之前人们已经可以用电阻分压进行一些计算了,但是很幼稚,得到的结果也不准确;而经过这些元件的研究,人们发现我们可以将信息表示为数字信号,用0-1的二进制来进行运算,这样就可以通过电路得到精确的结果,这很快就表现出了对手摇计算机的领先。某些电路可以让一个输入信号变成它的相反的值,0变成1,1变成0;某些电路可以让两个输入信号变成与或者或的关系,与也就是00、01、10都变成0,而11变成1,或则是00变成0,而01、10、11都变成1。布尔代数这个工具告诉我们,以上的逻辑加在一起就足够表达所有可能的逻辑了,包括加减乘除在内,于是我们可以用二进制进行运算。


曾经对计算机来说,所谓「编程」,指的是把线路板上可变的线路重新插接起来,让它们连接成可以工作的电路;甚至于debug,指的是有虫子飞进线路里被电死了,造成了短路,需要人去把它们取出来,所以叫做de-bug,bug就是虫子的意思。后来冯诺依曼提出了存储程序的概念,我们不是用插线,而是用存储在电子元件中的程序来控制线路之间的连接,这样就大大提高了我们重新布线的效率;而这样的机器能完成怎样的任务,这个问题则由另一名天才图灵解决了:简单来说,能完成任何任务。这样人类就有了第一台通用电子计算机ENIAC,一个庞然大物。虽然不知道细节,但它大概是从穿孔卡片之类的外设中读入第一个程序的。穿孔卡片的历史就远比计算机要早了,甚至可以上溯到十八世纪;IBM最早也是靠它发家的。为了存储数据,ENIAC甚至用了一个水银槽,把电转换成声波,让声波沿着水银槽传播来实现延迟,从而暂存数据。不管怎么说它的确是可以工作的。


程序是如何替代线路来运算的呢?其实并没有什么神秘的。我们看继电器,它通电的时候,就导通一条线路,关闭的时候则断开;如果我们将所有的可能的连接上都连上线,就可以用继电器来控制这些线是通还是断,也就相当于控制了电路。更好的一点是,我们运算的结果可以反过来修改存储的状态,于是这个运算可以按照我们设计的步骤连续不断地运作下去,大大扩展了计算机可以进行的任务种类。


如果你想知道第一个程序如何运行的,大概到这里就结束了;但是离office还远。


电子管计算机不管是价格还是寿命都有大问题,后来人类发明了晶体管,然后是集成电路,它大大降低了计算机的尺寸和成本,于是小型机甚至个人PC变为可能。再后来,计算机越来越廉价,也就有越来越多的人用得起,为了让所有人都能用得上,IBM、贝尔实验室等机构就联合起来想要开发一个叫做multics的操作系统。


操作系统是什么呢?以前的计算机一次只运行一个程序,它接受指定好的输入,完成指定的工作,打印到纸带输出,然后就停机。但现在的计算机计算能力很强,仅仅一条纸带的输入速度已经满足不了它了,为了提高效率,它必须能同时输入多道数据,运行多个任务,从而提高效率。对于以前的计算机来说,计算,然后决定读取数据,然后等待数据读进来,这时候计算机完全停转等待着穿孔卡片(纸带),这是对计算机的浪费;而有操作系统了之后,计算机会在等待数据输入的时候,切换到其他计算任务上,直到读取完成之后再切换回来进行原来的任务,这样就让输入输出(IO)与计算进行了重叠。


然而这个计划悲惨地失败了,大概是因为当时的人们还没有充分认识到,软件的开发是一项独立于硬件的工程,直到认清这件事的时候已经晚了,贝尔实验室和IBM都因为开发延迟而退出了这项计划。但通过这个大项目,人们认清了几件事:

  1. 软件开发的复杂度超过了人们的想象,必须用正确的方法来进行;这个正确的方法叫做模块化。将软件的功能拆分成小的模块,这样人们才能有效地协同起来共同工作;否则仅仅投入人力是不够的。
  2. 工具的重要性。要高效率的开发软件,我们需要高级语言而不是汇编。

后来,multics的遗迹上,两个爱玩游戏的工程师为了玩游戏,从遗弃的代码中开发出了Unix,顺便发明了C语言。

从这以后,软件工程的路上一片坦途。没过多久,也有了我们熟知的DOS和Windows。


这之后的故事就简单了,就像我最早说的,我们工程师只是在铺好的路上重复劳动,再一点点改进原来的方法,从DOS到Windows,从16位到32位,从文本模式到图形模式,从实模式到保护模式,我们的工具每天都在进步,但我们做的事情其实与几十年前没有多大区别。就像是搭积木,我们每个人都学会了怎么搭上自己的一块,最终我们搭出了庞然大物,但这其实并没有什么可稀奇的。