美文网首页
《计算机思维》3:全新的科学。4:工程的复杂

《计算机思维》3:全新的科学。4:工程的复杂

作者: 李成__北京 | 来源:发表于2025-01-14 09:02 被阅读0次

《计算机思维》3:全新的科学

你有没有过这样的想法:现在各个学科都要用到计算机,那为什么还要有一个单独的“计算机系”呢?这是大学在蹭一个浮夸的热点吗?是为了应对市场对程序员的巨大需求吗?不是。

计算机科学系,不是给程序员提供职业培训的地方。计算机科学系是研究计算机的地方。

“计算机科学”是如何发展壮大的,它为什么是一门“科学”。

不要低估天下英雄。不要以为只有像爱因斯坦的广义相对论才算了不起。计算机科学里,也有层出不穷的高妙思想……这是一个想法产生技术,技术刺激想法,想法又产生新想法的故事。

1.自然科学的荣誉感

从外面远处看一个很大的东西,你容易把它当成一个整体;而如果深入其中,你会发现它的各个部分之间存在严重差别。比如外国人在中国以外谈论中国,中国是一个标准化的形象 —— 但是咱们中国人知道,中国的各个地区发展很不平衡,中国很复杂。

大学也是这样。对一般高中生来说名校都很厉害,都是有光环的地方。而真正身处大学里面,它的各个科系其实是有区别的……这里面有个格调问题。教授们常常互相瞧不起,学科之间有个鄙视链。

在所有学科之中,自然科学能给人提供最大的荣誉感 —— 理解自然现象,是最纯粹科研趣味。比如“快速射电暴”这个现象,老百姓对它感兴趣是因为把它当成了外星人发的信号,而在科学家看来,就算它跟外星人没关系,只要它是一个我们尚未理解的自然现象,它就是有意思的 —— 因为这是大自然本身的东西!

反过来说,如果你研究的是某款电动汽车的发动机,你搞了一个什么技术革新,哪怕这项革新有潜力带来巨大的利润,那也对不起,你这个入不了科学家的法眼 —— 因为它不是一个自然现象。你研究的是一个人为的东西。也许在这款电动车的架构之下有这个问题,换一个平台,可能你这个问题就根本不存在。所以这个鄙视原则是 ——

自然的 高于 人为的

那“计算机科学”,是自然的还是人为的呢?

1962年,普渡大学建立了美国第一个计算机科学系,紧接着斯坦福大学也建立了一个。按当今中国的实用主义价值观来说这肯定是好事儿,但是在当时,可是引发了很大的争议。其他系的教授们纷纷声讨,说“计算机科学”算什么学问,何德何能,居然要开山立派成立新系呢?

当然这个灵魂诘问的背后还有一个利益的争夺。成立新系会把其他系的学生、经费和人员编制分流出去,等于是在削弱现有的系。电子工程系的教授完全可以说,我们也可以教计算机课啊?

这就给早期的计算机科学造成了一个重大的选择压力。计算机科学系要竖旗,就不能仅仅是一个培训程序员的地方。计算机科学家必须在企业研发之外,搞出一些有学术味道的东西,得有拿得出手的发现、能提高大学的声望才行。

其实他们不用担心。事实证明,计算机科学里中有太多拿得出手的发现了。

2.从技术到科学

人们研究计算机的初衷,无非是想实现自动化,搞自动计算或者自动控制,解决生产力问题,计算机是一个技术。但是计算机科学一旦成型,它自身的发展就跳出了纯技术的维度。

《计算机思维》这本书列举了计算机科学的各种进步,它的发展可以分为三个方面 ——

初级,是怎么更好地实现自动化,主要解决应用问题;

中级,是研究“计算”这件事儿本身,上升到了类似于自然科学的层面;

高级,则是把计算思维用到其他科学领域中去,是带给人认知的升级。

初级,也就是自动化。

1940年代刚刚发明电子计算机的时候,大家都使用所谓“汇编语言”,是让人说机器的语言 —— 直接把机器指令写在打孔卡上,给计算机读取。这个做法对人的要求实在太高了,费时费力不说,还特别容易出错。那么一个自然的需求就是,能不能让人按照人容易理解的思维写程序,然后把写出来的程序自动翻译成机器语言呢?

这就是所谓高级编程语言。1957年,Fortran语言被发明了,这是一个科学计算语言,特点是特别容易写公式。1958年,LISP语言出现,这是一个极其强大的符号处理和逻辑运算语言,甚至可以用于人工智能设计。1959年人们又发明了 COBOL 语言,用于商用数据库编程。

然后要方便人们在一台计算机上操作,你就得有账号管理,得安排不同的程序同时运行,那么你就得有操作系统,你就得有系统思维。要想开发出来的软件好用、可靠、容易维护,你就得有工程思维。接下来还有了互联网,你需要网络思维和安全思维。

所有这些自然生长出来的东西都是学问。再进一步,编程*思想*也在演化。传统编程语言是线程式的,程序员思维模式是操控计算机。后来要把软件做得很大的时候,出现了“面向对象”的程序设计。这是不一样的思维模式,程序员想的不再是操控计算机这一台机器,而是“类”和“对象”:每个类和对象就好像是一个小机器一样,是这些虚拟的小机器之间在互动。

那么随着编程语言的发展,同时计算机硬件也在变得越来越快、越来越普及,基础教育界就把编程技能,看得和阅读、写作和数学一样,被认为是人人必备的第四个技能。

但这些还都是比较浅层的计算机科学。

3.从计算自身到“计算宇宙”

计算机科学真正成熟的标志,是“计算机”这个东西,和“计算”这个行为本身,成了研究的对象。

1967年,三个计算机科学家在《科学》杂志上发表了一篇文章,说现在计算机科学已经称得上是一门真正的科学了:就好像动物学研究动物、植物学研究植物一样,计算机科学,研究计算机。

真正的程序员,都认为计算机是有生命的。你得把计算机当做一个独立存在的东西才行,它有自己的脾气,有自己的特性和性格。要想操作好计算机,你得像动物学家理解动物一样,去理解它才行。

这个感觉对外行来说可能有点奇怪。难道计算机不是人类设计制造的吗?怎么人类还不理解计算机呢?但事实就是如此,你能设计它制造它,你可不一定就完全理解它。发明围棋的人并没有完全理解围棋。也许计算机是人类释放出来的一个怪兽!

比如说,如果几个用户同时使用一台计算机,操作系统必须给他们分配计算机CPU时间,那如何分配呢?你在理论上设计得再好,不上机去测试一下就永远不知道结果会是怎么回事儿。你得把计算当成一个生物,在它身上做实验。

与此同时,“计算理论”也在发展。给你一个问题,你能不能估算一下它的难度有多大。计算理论最关心的是,随着问题复杂度上升,计算时间是线性增长呢,还是指数增长?如果是线性增长,我们认为它是一个“简单”问题;如果是指数增长,它就是一个“难的(hard)”问题。

难的问题,计算机就帮不了太多忙。你就得想点别的办法。那么给你一个复杂问题,我们怎么把它算法化,怎么拆解它?解决这个问题的信息结构应该是什么样的?什么样的问题是可计算的,有没有什么问题是不可计算的?

再比如说假设现在有了算法,能不能优化这个算法,来提高运算速度呢?再比如如果让你凭空发明一个编程语言,你应该怎么做呢?

这些问题似乎像是工程上的,但又带有很强烈的数学味道!其实它们本质上是数学问题。现在有很多应用数学家就在专门研究这些问题。

到1990年代,计算机科学的江湖地位就算竖立起来了。人们甚至提出,计算,是在传统的理论和实验这两条路之外,第三条科研道路。但是紧接着的发展超出了计算机科学家的预料……其他学科,开始抢占计算机科学家的地盘。

人们突然意识到,“计算”是个非常基础的逻辑,到处都是计算。生物学家说,DNA就是一个计算系统,DNA复制就是计算操作,生命本来就是一个计算现象!要用计算的眼光来研究生命。

物理学家也可以说,基本粒子的运动就是信息交换啊,物理定律就是计算。

甚至有人提出,整个宇宙就是一台计算机 —— 我们很有可能是生活在一个计算机模拟之中。这个思想其实缺乏足够的证据支持。

但是现在想想,如果没有计算机科学,人们再怎么想,也很难想象宇宙是一台计算机 —— 你根本就不会有这个概念!

所以说,计算机科学绝不仅仅是解决自动化问题的学问,它还有计算机和计算理论自身的学问,它还给我们提供了一个非常不一样的观察世界的眼光。

你是不是体会到了一点学术的魅力。一门科学就好像有生命一样,它不但要发展壮大,而且要在不同的维度上发展壮大。计算机科学就好像一棵树,它不但越长越高枝繁叶茂,而且在成长的过程中这棵树本身还在脱胎换骨,你过段时间一看树的材质都和以前不一样了。然后这棵树还影响了别人的认知,让人反思到底什么叫做“树”,甚至怀疑自己和整个世界就是一棵树……

还可以把计算机科学跟那些幻想小说里的魔法和修仙的世界做个类比。这门学问的发展,就如同一个人刚出道的时候被人看不起,但是他有很多奇遇,今天学个大招明天升级一项技能,然后过了几十年换了筋骨,再过几百年居然成仙升天了 —— 同时他还带给我们一个全新的世界观……只不过,真实世界里学问的奥妙,比魔法世界那一套更复杂也更精彩。

看修计算机这个事儿,一点都不比修仙低级。

《计算机思维》4:工程的复杂

一个特别厉害的技能,叫做“软件工程”。可以说是工程管理和综合治理手段的极限。希望你能体会一下如何治理最复杂的系统。

可能你是一个产品经理,主导开发过一款APP。可能你是个企业家,管理一个几万人的大工厂。可能你是个土木工程师,设计过一座跨海大桥。你非常厉害,中国有很多这样的厉害人物。中国是手机 APP 开发大国,中国有很多超大型企业,中国有全世界最长的跨海大桥 ——可是为什么中国就没有属于自己的计算机操作系统呢?为啥国产芯片不行呢?

因为那些事儿,跟现代软件工程相比,还只能算是简单的事儿。

程序员、CEO、计算机科学家,如果是拍一个超级英雄电影的话,这些人都可以是前台的英雄人物。但是躲在幕后操纵世界的,则将是一位、或者几位,软件工程大师。有句话叫“在计算机科学里,软件工程这一部分,对计算机科学家来说太难了。”

不了解软件工程,就不知道什么叫“大”,什么叫“复杂”。

1.小和大

编程是个非常适合自学成才的项目。很多人不是科班出身,自学编程技术,也容易找到一个程序员的职位,甚至还可以自己开发一个小软件。

但仅限于*小*软件。比如你可以自己写一个电子邮件客户端程序,或者写一个视频编辑工具。可是如果要开发一个超大型软件,其中涉及到的学问,可就不是自学所能达到的了,那是需要在重大项目的实践中去领悟和提高的。自学也许可以让你成为一个优秀的侠客,而伟大的将帅,则只能用千万士兵的鲜血铸就。

这里面的关键是一个尺度问题。大,是不一样的。

计算机刚刚出来的时候,程序员都是身上有修士气质的手艺人。编程者经常是孤独的,能说天书一样的语言,想法高深莫测,写出来的代码仿佛有一种暴力美学,他们的眼睛跟显示器一起在黑暗中闪闪发光。编程,是一项神秘的技能。

那时候的程序都是完全自由的 —— 计算机很贵,而程序不要钱。程序员们就好像十九世纪的艺术家一样,偶尔弄个俱乐部或者小作坊,彼此欣赏。

不过这个艺术时代并没有持续多长时间,程序员们很快就陷入了极度的悲观情绪之中。因为……错误。

写代码太容易出错了!代码越写越长,出错的频率不成比例地增加。可能你今天费了很大力气好不容易运行通过了,过了几天、遇到一个没想到的情况,发现还有一个隐藏的错误。有个程序员甚至说,他意识到,也许他的余生,都要在纠正自己的错误中度过……

程序员们终于明白,他们需要工程师思维。

工程师思维和科学家思维至少有三个重大区别。

第一,科学家是寻找事物的规律,而工程师是去设计一个东西。科学家只要觉得这个规律有意思就可以发表,而工程师得负责任。他得确保这个东西不但要有用,而且还得安全不出事,还得考虑成本,讲究可行性,让人用得上还用得起才行。

第二是对知识的态度。科学家面对知识,是把自己当成一个没有利益攸关的旁观者,感觉看懂了、能总结出规律就行。而工程师,则是参与者。他不能仅仅“懂”这个知识,他是要拿来用的。

第三是对模型的使用。科学家喜欢简化的模型,能抓住实质就行 —— 爱因斯坦有句名言说“什么东西都要越简单越好,要简单到不能再简单为止”。而工程师必须考虑所有的细节,“魔鬼在细节中”是工程师的座右铭。

要把写程序上升到工程的高度,跟以前那种兴趣爱好式的编程可就完全不同了。更进一步,软件工程和传统的工程也不一样。

比如你要修个桥,工程过程中哪里犯个小错误,通常也就是小错误 —— 最多也就是让大桥的质量降级。这座大桥总共有15个桥墩,其中第五个桥墩有个地方没建好,这座桥大致上还能用。但软件就不一样了,程序中的一个小错误很可能就会导致整个系统的崩溃。

这是为啥呢?因为软件不但各处的关联非常密集,而且是个“活”的东西。比如发射火箭,软件是要控制火箭做动作的!哪个动作不对,火箭立即失控。

所以软件不但是个工程,而且比传统工程难得多。那怎么应对这种复杂呢?

2.小思维

早期的软件开发者想出了很多工程化的办法,起到了一定的效果。比如以前都是用汇编语言,后来发明了高级编程语言,程序员就不容易出错……当然,这时候也不需要程序员个个都有修士的气质了。

最重要的一个方法,是把常用、好用的代码*封装*起来,重复使用。如果这段代码总是被用到,已经被大家测试过很多次了,证明没有毛病,那就不要再改来改去搞定制了,应该把它封装成一个“库函数”。库函数具有标准化的输入和输出,程序员下次再用的时候只需要照顾好输入输出,而不必关心函数内部是什么情形 —— 这就能大大降低出错的概率和提高编程的效率。

封装这个思想可以用在软件的各个方面。数据结构、面向对象的编程、文件系统,这些都是封装和分层。这一层的编程不用考虑底下一层的逻辑。

操作系统的内核也是一个类似的智慧。操作系统把最常用的操作计算机的动作,都事先在内核中预备好,而内核经过千锤百炼,不容易出错。等到别人写应用软件的时候,用到相关的动作,就只要调用内核就行,而不必自己直接操作计算机。这就相当于把专业的事儿交给专业的人,也就不那么容易出错了。

所有这些思想都要求对软件开发有个宏观的设计,而不只是吭哧吭哧写代码。然后你还得考虑多个人一起开发一个软件的情形,比如最起码得有个版本控制之类。

到这一步,软件业才算正式成了一个行业。在上世纪五十年代,就已经有公司专门开发软件卖钱。

……可惜这些还远远不够。

软件业从一开始就不是一个做事漂亮的行业。项目总是在延期。好不容易交付了,软件卖出去之后又总是被人发现各种毛病和错误。客户不满意,可是如果真要搞什么售后服务,到现场去给人解决问题,那几乎就是不可完成的任务……而且还有黑客攻击、还有计算机病毒!

一个笑话,说一个软件工程师嘲笑一个汽车工程师,说“如果汽车行业像计算机行业一样发展,现在汽车应该一毛钱一辆。”但是汽车工程师不以为然,说“可是谁会要一辆动不动就抛锚的汽车呢?”

而早期的软件公司,对此只有两个不是办法的办法。一个办法是尽量去找那些经验丰富、头脑聪明的高水平程序员……一个办法是销售软件的时候干脆附带一个免责声明:如果因为这个软件的毛病给您造成了损失,我们概不负责。

社会对计算机的美好幻想被打破了,软件行业陷入了危机。

3.大思维

软件工程的问题不是你每年能培养多少高水平程序员的问题,而是复杂性问题。

小软件和大软件的根本区别在于尺度。以前一个小软件只有几千行代码,现在一个大软件要有几百万行代码。以前的软件是给一个人用,现在是多个用户共同使用一个软件。更重要的一点是,以前的软件是一个人或者几个人开发的,现在则是大型团队一起开发。

计算机思想家弗瑞德里克·布鲁克斯(Fred Brooks),曾经在上世纪六十年代末率领IBM公司300人的团队开发操作系统。他做完这件事之后很有感触,为此专门写了一本书,叫《人月神话》。

布鲁克斯提出两个感慨。

第一个感慨是,1个人干12个月的活,绝对不是12个人在1个月内能干完的。项目用的程序员越多,平均每个人出活的速度就越慢。所以你规划项目的时候不要算什么“人月”。

第二个感慨是,你这个团队做出来的软件的结构,往往和你这个团队的人员组织管理结构高度相似。所以软件工程不但要管项目,还要管人。

布鲁克斯这本书出来,人们才充分认识到软件工程的难度。现代软件工程要求,软件产品必须达到下面这五个目标,称之为“DRUSS” ——

Dependable,可信赖,让顾客真能指望上你这个软件;

Reliable,得可靠,不能总出毛病;

Usable,软件是给人用的,得让人能够上手;

Safe,用的时候不能出安全事故;

Secure,它得不容易被黑客攻击才行。

现代主流操作系统,包括 Windows, Mac 和 Linux,各自都有接近一亿行代码,而且大致实现了这五个方面的要求。而即便是这三个可以说是最成熟的软件系统,其中仍然还有大量的毛病。

那怎么才能获得这种大型软件工程的能力呢?前面说的办法都还是小软件思维,剩下的,就只有一些经验之谈,而没有什么特别系统的行动指南了。

比如说,在系统安全方面,软件开发的首要原则是默认不给用户授权。如果非要授权用户接触一个什么东西,就必须得有显性的授权;每个程序进程只能拥有最有限的授权,等等。软件工程就是由这些原则、工作中遇到的规律、前辈传下来的经验组成的。

技术进步能解决一定的问题,比如更多的分层封装,搞虚拟机,客户端和服务器,高级编程语言,交互式开发环境,可视化的控制和数据流,更好的操作系统等等……但是技术解决不了所有的问题。

1987 年的时候,布鲁克斯写了一篇文章叫《没有银弹》,又提出一个洞见:软件工程的根本问题,是人的问题。主导软件开发的这个人,必须得能够理解高度复杂的东西才行。

写程序是永远在更新的技术,软件分为很多层,会出现各种毛病,你得确保产品满足 DRUSS 五方面的要求,你得操很多的心……你得能驾驭复杂。

*

像这样的人才,都是绝对的帅才。这就好比带兵打仗,你不用说指挥十万人打仗,你能把十万人安全带到战场,不哗变、不闹事、都能吃饱饭就不错了。

布鲁克斯有句名言是这么说的 ——

“好的判断来自经验,而经验来自坏的判断。”(Good judgement comes from experience, and experience comes from bad judgement.)

正所谓一将功成万骨枯,驾驭大型软件工程的能力,只能通过大型软件工程培养出来。

有些创新能力难复制 —— 因为它是长出来的。中国有很多软件开发者,但是缺少操作系统这种级别的大型软件开发积累。有几代程序员试炼出来的库函数吗?有 Windows 3.1,Windows 95 的种子吗?有前辈开发者总结出来的原则、规律和教训吗?有自己的标准和规范吗?软件每天都在更新,但软件工程的背后,是一棵经年累月长出来的大树。

美国要封锁华为公司,而华为在搞自己的手机操作系统。在软件工程上另起炉灶是一个几乎不可想象的任务,但是如果真有那样的机会,那就是现在。

倒要让美国人看看,中国公司有没有驾驭复杂的能力。

相关文章

网友评论

      本文标题:《计算机思维》3:全新的科学。4:工程的复杂

      本文链接:https://www.haomeiwen.com/subject/afxbyjtx.html