1.1 什么是软件
1.1.1 软件的定义和作用
什么是软件呢?现在,被普遍接受的软件的定义是:软件(software)是在通用计算机硬件之上面向特定应用目标实现的解决方案。它是计算机系统中与硬件(hardware)相互依存的另一部分,包括程序(program)、相关数据(data)及说明文档(document)。为了更好地理解软件的概念,将软件和硬件等其他人工产品相区分是非常重要的。软件是逻辑的而不是物理的产品。因此,软件具有与硬件完全不同的特征。
(1)软件开发不同于硬件设计
与硬件设计相比,软件更依赖于开发人员的业务素质、智力,以及人员的组织、合作和管理。对硬件而言,设计成本往往只占整个产品成本的一小部分,而软件开发占整个产品成本的大部分,这意味着软件开发项目不能像硬件设计项目那样来管理。
(2)软件生产不同于硬件制造
硬件设计完成后就可投入批量制造,制造是一个复杂的过程,其间仍可能引入质量问题;软件成为产品之后,其制造只是简单的复制而已,软件的仓储和运输也非常简单。因此,软件产品必须要成为第一,一旦落后,市场就会被领先的产品以零成本的复制所占领。
(3)软件维护不同于硬件维修
硬件在运行初期有较高的故障率(主要来源于设计或制造的缺陷),在缺陷修正后的一段时间中,故障率会降到一个较低和稳定的水平上。随着时间的推移,故障率将再次升高,这是因为硬件会受到磨损,达到一定程度后就只能报废。软件是逻辑的而不是物理的,虽然不会磨损和老化,但在使用过程中的维护却比硬件复杂得多,在维护过程中还可能产生新的错误。软件在运营时需要持续的维护和版本更新,这也正是软件产业隶属于服务业而不是制造业的主要原因。
当前,软件作为信息技术产业的核心与灵魂,正发挥着巨大的使能作用和渗透辐射作用。所有新的信息技术应用、平台和服务模式,均离不开软件技术作为基础支撑。更为重要的是,在数字经济时代,软件技术已经成为企业的核心竞争力,不仅引领着信息技术产业的变革,在汽车、能源、制造、零售等众多传统领域中存在的比重和重要性也在不断加大,在支持这些传统领域产业结构升级换代甚至颠覆式创新的过程中起到核心关键作用,并进一步加速重构了全球分工体系和竞争格局。作为新一轮科技革命和产业变革的标志,德国的“工业4.0”和美国的“工业互联网”,以及我国的“制造强国战略”,均将信息和软件技术作为发展重点。无所不在的软件,正在走出信息世界的范畴,开始深度渗透到物理世界,在支撑人类社会运行和人类文明进步中发挥重要的“基础设施”作用,甚至开始扮演着重新定义整个世界图景的重要角色。
1.1.2 软件的发展历史
从世界上第一台计算机ENIAC在美国诞生到现在的70多年时间里,软件作为人类智力活动的逻辑产品,经历着与其他行业不同的快速发展。作为信息技术的核心,软件技术呈现从“工具”和“平台”到“引领”的转变。与此同时,软件的产品形态和商业模式也在不断演进,先后经历了大型机和小型机时代的硬件附属阶段、PC时代的独立软件产品阶段、“互联网+”时代的“软件即服务”阶段,以及数字经济时代的“软件定义”阶段[1]。
(1)硬件附属阶段
在计算机诞生后的相当长一段时期内,实际上并没有“软件”的概念,计算机是通过用机器语言和汇编语言编写程序直接操作硬件来运行的。到20世纪60年代初,在高级程序设计语言出现后,软件才从硬件中分离出来,成为相对独立的制品。但是,在这个大型机和小型机时代,硬件占据绝对主体的地位,软件仅仅作为计算机硬件的附属物而存在,没有独立的商业形态,软件的代码通常是向使用者开放的,便于用户自己进行修改与优化。
(2)独立软件产品阶段
进入20世纪70年代的PC时代后,出现了软件许可证(license)的概念,卖软件的许可证成为一种新型的商业模式,软件作为一个独立的产品销售,软件代码成为核心竞争力而不再对使用者开放。标志性的成功案例就是微软的Windows操作系统。在这个时期,软件逐渐颠覆了传统计算机产业“硬件为王”的格局,开始成为IT产业的主导者。软件开始正式成为一个独立产业,在各个行业、领域不断普及,催生了人类历史上信息化的第一波浪潮,即以单机应用为主要特征的数字化阶段(信息化1.0)。
(3)“软件即服务”阶段
20世纪90年代中期开始,随着互联网的快速发展普及,软件从单机计算环境向网络计算环境延伸,带来了信息化的第二波浪潮,即以网络在线应用为主要特征的网络化阶段(信息化2.0)。软件的形态发生了重大的变化,“软件即服务”(software as a service)开始成为一种非常重要的网络化软件交付形态和使用方式。不同于传统面向单机的拷贝形态,“软件即服务”使得人们不必再拥有软件产品,而是通过互联网在任何时间、任何地点、任何设备上,直接与软件提供者进行连接并按需获取和使用软件的功能。
(4)“软件定义”阶段
当前,软件正在融入支撑整个人类经济社会运行的基础设施中,对传统物理世界基础设施和社会经济基础设施进行重塑与重构,通过软件定义的方式赋予其新的能力和灵活性,成为促进生产方式升级、生产关系变革、产业升级、新兴产业和价值链的诞生与发展的重要引擎。
1.1.3 挑战与问题
软件与工业控制、制造、科学计算、数值计算、物联网等各领域不断加强融合,正引领并促进这些领域的高速发展。为了满足各个领域的相关要求,软件对应呈现出许多新的特征,从而导致软件开发与维护面临新的挑战:
1)软件复杂性挑战。今天的软件常常是网络应用,涉及多种硬件、多种操作系统、多种编程语言,逻辑复杂,同时面临层出不穷的新技术。
2)软件大规模挑战。软件规模不断扩大,一个宇宙飞船的软件系统源程序代码可多达2000万行,鸿蒙操作系统的研发人数超过2万。
3)软件高质量挑战。随着软件应用在越来越多的关键领域中,软件的质量要求也越来越高,例如高安全性、高可靠性、高性能、高易用性、可配制的功能和流程等。
4)不确定性挑战。乌卡(VUCA)时代下,软件项目面临需求和技术的易变性、不确定性、复杂性和模糊性的挑战,应用环境从静态、封闭、可控逐步变为动态、开放、难控。
5)进度和敏捷开发的挑战。几乎所有软件项目的进度要求都很紧,常常需求还没有确定,交付日期却已经定了,进度预估不足是常态。这就要求敏捷开发,快速适应需求变化。
6)遗留系统(legacy system)的挑战。随着软件的不断开发和应用,存在着大量的遗留系统需要集成和复用。这些系统是早年采用旧的技术开发而成的,目前一部分仍能有效运行,一部分需要升级改造,还有一部分虽然被淘汰,但仍包含大量可复用的资产。
7)分散团队的协同挑战。全球软件开发由于能充分利用各地的资源,被越来越多的组织所接受,特别是跨国组织和集团。地理位置分散的开发团队,协同合作需要克服时间、文化等差异造成的沟通障碍。
我们所面临的新挑战不止上述这些。这些挑战导致了软件项目的成功率和质量一直偏低。根据Standish Group发布的chaos报告[2],软件项目的成功率低于40%,超过60%的项目由于进度延期、超出预算、不符合客户的需求、质量低劣等原因而在不同程度上失败。由于软件质量低劣导致的故障,也给我们的生活和工作带来了巨大的损失。例如,2018年印尼狮航一架波音737 MAX 8客机途中坠落,189人罹难,失事原因为软件设计缺陷,飞机的迎角传感器“数据错误”触发“防失速”自动操作,导致机头不断下压,最终坠海。
为什么软件开发表现得如此不成熟呢?分析其根源,主要有两个方面的原因:
● 与软件本身的特点有关。软件是无形的逻辑实体,具有高度的复杂性,不仅难以理解和描述,而且难以开发、度量和控制,使得软件开发过程中处处充满着风险。
● 与软件开发和维护的方法、过程、管理、规范和工具不正确有关。Parnas教授曾说过,虽然我们已经提出了不少好的技术和方法,例如迭代式交付(1988)、测量(1977)、风险管理计划(1981)、变更控制委员会(1979),等等,“它们早就在这里多年了,但是没有被适当使用”。当前软件实践常常是,面对进度压力,软件工程师没有计划他们的工作,匆匆地走过需求、设计和编码,软件开发直到测试前仅仅是忽略质量的技术。这些实践引入了大量的缺陷,即使是有经验的工程师也会每7~10行代码就引入一个缺陷,中等规模的系统平均存在着上千个缺陷。大多数缺陷必须靠测试发现,这通常要花去开发时间的一倍时间。目前大多数的工作方式还像30年前一样。
如何才能解决这些问题,提高软件开发和维护的效率与质量?这正是软件工程所研究和实践的。