然而,时至今日,软件开发不管怎么自动化,总是有一些例外,需要程序员去手工处理。这些例外情况,通常无关乎高精尖,而是些很普通的问题。在八年以前,我还没有接触知识表示和人工智能的时候,这个问题一直在脑中挥之不去。2003年,偶然接触到cyc项目,这又一次彻底颠覆了我的想法,因为这个cyc刚好能作一些看起来很简单,却又非要人工才能处理的事情,而且这些事情并不像看上去那么简单,一个简单的推理常常要调用成千上万条断言。当然cyc并不是一个真正的常识处理系统,它固然是十余年积累的成果,也有很多闪光的思想,但是局限性也很明显。不管怎样,它为我开启了一个全新的视野。人工智能是个很大的领域,其中有很多天才的创见,要理解它的全部内涵,是件艰巨漫长的工作。然而,有一件事情从开始的时候就能得出结论,那就是,如果计算机真的具有了与人类相当的智能,那么必然就不再需要人来为它编程序,那个时候,就是程序员这个职业寿终正寝的时候,当然,整个软件产业也将不复存在。所以,程序员以及软件产业的生存,其实就寄托于那些为数越来越少的,必须人来处理的“例外”情况。
我们现在就来关注这些例外情况,因为它们是如此重要,将会决定各位程序员以及产业的命运。
软件是什么呢?计算机发展的早期历史上是没有软件的概念的,那时候只有程序,每个用户就是他自己的程序员,编写程序满足他自己的需求。这个时候的程序员,不需要需求调研,不需要划分工作阶段,总之一句话,想怎么干就怎么干,他们也不会考虑复用,因为程序只是他们个人想法的表达,没有想法的时候想也没用,一旦有了想法,两下就写出来了,即使需要借鉴以前的想法,从脑子里调出来比从故纸堆翻出来也快捷得多。也许软件与程序的不同就在于此,软件是做给别人用的,程序是写给自己用的。软件是伴随着不会编程的“业余”用户的产生而出现的。开发软件与写程序第一个不同的地方就是要做需求调研,不管做多简单的软件,都要调研。有的时候,程序员看似没有做,其实是他和用户已经很熟悉,用户的需求早已经都记在脑子里了。用户有需求就表明用户有一些需要计算的问题,这些问题可以由计算机做,当然也可以由人来做,事实上computer最早指的是拿着纸笔或者计算尺工作的计算员们。如果由人来完成计算,用户通常需要告诉计算员计算的公式和流程,然后提供初始数据,如果这位计算员经验丰富的话,有时候不必如此罗嗦,只需要告诉他算什么题目就可以了,计算员自己知道公式和流程,或者即使当时不知道,也可以自己找资料学习。使用计算机就享受不到如此的便利了,计算机不会自己学习查资料,即使硬盘里存有以往的计算程序,它也不会自己去使用,一定要人手工调出来运行。人与计算机的根本差别不在于处理信息的能力,而在于处理信息的主观能动性。
自从引入了客户,引入了需求,软件开发开始变得复杂了,最早的客户还比较好应付,他们都是懂一些计算机技术的人,那时候完全不懂的人根本不会想到用计算机做事情。最初的需求都很具体,输入什么,做哪种计算,结果怎么输出,都讲得清清楚楚,所以最初搞需求分析的人都画数据流图,只要数据流清楚了,软件就确定了,今天的程序员就没这么幸运了,工作流程、访问权限、用户体验等等,撞得满头都是包,如果光盯着数据流图的话,什么也做不出来。那时候的分析员和设计师基本上是同一个人,因为没有什么好设计的,就是把功能分解一下,列张表1234写出来,再往后稍微复杂一些,所谓结构化方法,也就是功能多了一些,列表不好使改用层次树。今天的设计师,最惨的时候UML14种图全都画遍,可能也还有没描述清楚的地方。
软件出现之后,因为商业的驱动,很快就泡沫一般膨胀起来,各位今天目睹了各种泡沫之后,大概会总结出来一条规律,凡是泡沫一定没有好结果。软件一旦开始膨胀,所需的人工自然不断地加倍,于是以IBM为代表(IBM确实养了不少杰出的科学家,但是养了更多猪头,当科学家和猪头一起研究问题的时候,通常猪头不会变成科学家,而科学家却会变成猪头),采用了工业时代提高效率的不二法则--增加人手,扩大规模,精细分工,流水作业,至于结果嘛,各位学过软件工程第一课的话,恐怕就知道他们的事迹了。
扯IBM的糗事看似和我们的主题没多少关系,其实当中有着深刻的联系。我们前面所说的那些可以自动处理的部分,他们用人工都做得很完美,而在那些例外的地方,却几乎无例外地犯错误。那么,例外到底是什么呢?为何总是挥之不去呢?要解决这个问题,我们就需要从更深层次挖掘软件的本质。不管怎么说,软件的核心功能就是计算,那么计算是什么呢?今天互联网上充斥着各种各样的计算,仅仅用数学来概括是不足以涵盖其外延的。在数字系统之外,也存在各种各样的计算,比如模拟计算机的计算,军事上的兵棋推演,商业上的决策方法等等。如果要概括所有这些计算共同的特征,就只有三点:第一,都有一组初始的数据,代表着某个现实的或者抽象的系统在某一时刻的状态;第二,都有一组理论或者公式(或者二者兼具),规定了各个数据如何相互作用;第三,经过计算的过程,最终都得到另一组数据,描述系统在另一时刻可能的状态。如果把第一、第二两条中的要素加在一起,称之为一个模型的话,计算就相当于模型的一次推演。模型推演是人脑最基本的思维方法,人类发明计算机来分担思考的负担,因此计算机当然必须能够担负这样的计算工作。然而计算机并不懂得什么是模型,只是一个执行程序的机器,因此必须由人来将模型程序化,软件简单地说就是程序化了的模型。面向对象的方法其实就是一种模型表示法,而近年更有人提出模型驱动的开发,这都与软件的模型性质密不可分。
仅仅认识到软件具有模型的性质还不够,首先,模型本身是复杂的,虽然所有的模型都可以用一组规律加一组数据来概括,但是实际做过系统的人,特别是做行业系统的人都知道,行业知识本身就是复杂的,相互之间常常有说不清道不明的关系,如果不是自己真正理解了这些知识,仅仅以书本和专家言语为基础,做一些表面(形式化)的推理,是几乎一定会出错的。其次,初始数据也不是简单的,今天的系统,数据来源多种多样,精度、可信度各不相同,非结构化的数据常常见到,单是把这些数据转换到适合模型推演的形式,就要费九牛二虎之力。第三,模型代码化本身也不是件轻松的工作,今天的计算环境空前复杂,各种平台,各种支撑系统都要考虑,今天的架构师要掌握的知识比以往任何时候都多。最后,软件虽然以模型为核心,但绝不仅仅是模型,为了让模型进行有用的工作,各种辅助系统也必不可少。
(未完待续)
https://blog.sciencenet.cn/blog-533026-428644.html
上一篇:
信息幽灵下一篇:
消灭程序员需要百年吗?(下)