标题：软件危机
概述
软件危机泛指在计算机软件的开发和维护过程中所遇到的一系列严重问题。[1]
发展历史
软件危机（software crisis），20 世纪60年代以前，计算机刚刚投入实际使用，软件设计往往只是为了一个特定的应用而在指定的计算机上设计和编制，采用密切依赖于计算机的机器代码或汇编语言，软件的规模比较小，文档资料通常也不存在，很少使用系统化的开发方法，设计软件往往等同于编制程序，基本上是个人设计、个人使用、个人操作、自给自足的私人化的软件生产方式。
60年代中期，大容量、高速度计算机的出现，使计算机的应用范围迅速扩大，软件开发急剧增长。高级语言开始出现；操作系统的发展引起了计算机应用方式的变化；大量数据处理导致第一代数据库管理系统的诞生。软件系统的规模越来越大，复杂程度越来越高，软件可靠性问题也越来越突出。原来的个人设计、个人使用的方式不再能满足要求，迫切需要改变软件生产方式，提高软件生产率，软件危机开始爆发 。
1968 年北大西洋公约 组织 的计算机 科学家在联邦德国召开国际会议，第一次讨论软件危机问题，并正式提出“软件工程”一词，从此一门新兴的工程学科——软件工程学——为研究和克服软件危机应运而生。
主要表现
软件危机主要表现在：
① 软件开发费用和进度失控。费用超支、进度拖延的情况屡屡发生。有时为了赶进度或压成本不得不采取一些权宜之计，这样又往往严重损害了软件产品的质量。
②软件的可靠性差。尽管耗费了大量的人力物力，而系统的正确性却越来越难以保证，出错率大大增加，由于软件错误而造成的损失十分惊人。
③生产出来的软件难以维护。很多程序缺乏相应的文档资料，程序中的错误难以定位，难以改正，有时改正了已有的错误又引入新的错误。随着软件的社会拥有量越来越大，维护占用了大量人力、物力和财力。进入80年代以来，尽管软件工程研究与实践取得了可喜的成就，软件技术水平有了长足的进展，但是软件生产水平依然远远落后于硬件生产水平的发展速度。
④用户对“已完成”的系统不满意现象经常发生。一方面，许多用户在软件开发的初期不能准确完整的向开发人员表达他们的需求；另一方面，软件开发人员常常在对用户需求还没有正确全面认识的情况下，就急于编写程序。[1]
软件危机不仅没有消失，还有加剧之势。主要表现在：
①软件成本在计算机系统总成本中所占的比例居高不下，且逐年上升。由于微电子学技术的进步和硬件生产自动化程度不断提高，硬件成本逐年下降，性能和产量迅速提高。然而软件开发需要大量人力，软件成本随着软件规模和数量的剧增而持续上升。从美、日两国的统计数字表明，1985年度软件成本大约占总成本的90%。
②软件开发生产率提高的速度远远跟不上计算机应用迅速普及深入的需要，软件产品供不应求的状况使得人类不能充分利用现代计算机硬件所能提供的巨大潜力。
危机原因
软件工程研究结果表明 ，软件危机的原因主要有两方面：
与软件本身的特点有关
软件不同于硬件，它是计算机系统中的逻辑部件而不是物理部件；软件样品即是产品，试制过程也就是生产过程；软件不会因使用时间过长而“老化”或“用坏”；软件具有可运行的行为特性，在写出程序代码并在计算机上试运行之前，软件开发过程的进展情况较难衡量，软件质量也较难评价，因此管理和控制软件开发过程十分困难；软件质量不是根据大量制造的相同实体的质量来度量，而是与每一个组成部分的不同实体的质量紧密相关，因此，在运行时所出现的软件错误几乎都是在开发时期就存在而一直未被发现的，改正这类错误通常意味着改正或修改原来的设计，这就在客观上使得软件维护远比硬件维护困难；软件是一种信息产品，具有可延展性，属于柔性生产，与通用性强的硬件相比，软件更具有多样化的特点，更加接近人们的应用问题。
随着计算机应用领域的扩大，99%的软件应用需求已不再是定义良好的数值计算问题，而是难以精确描述且富于变化的非数值型应用问题。因此，当人们的应用需求变化发展的时候，往往要求通过改变软件来使计算机系统满足新的需求，维护用户业务的延续性。
来自于软件开发人员的弱点
其一，软件产品是人的思维结果，因此软件生产水平最终在相当程度上取决于软件人员的教育、训练和经验的积累；
其二，对于大型软件往往需要许多人合作开发，甚至要求软件开发人员深入应用领域的问题研究，这样就需要在用户与软件人员之间以及软件开发人员之间相互通讯，在此过程中难免发生理解的差异，从而导致后续错误的设计或实现，而要消除这些误解和错误往往需要付出巨大的代价；
其三，由于计算机技术和应用发展迅速，知识更新周期加快，软件开发人员经常处在变化之中，不仅需要适应硬件更新的变化，而且还要涉及日益扩大的应用领域问题研究；软件开发人员所进行的每一项软件开发几乎都必须调整自身的知识结构以适应新的问题求解的需要，而这种调整是人所固有的学习行为，难以用工具来代替。
软件生产的这种知识密集和人力密集的特点是造成软件危机的根源所在。
从软件开发危机的种种表现和软件开发作为逻辑产品的特殊性可以发现软件开发危机的原因： 
（1）用户需求不明确
在软件开发过程中，用户需求不明确问题主要体现在四个方面：
在软件开发出来之前，用户自己也不清楚软件开发的具体需求；
用户对软件开发需求的描述不精确，可能有遗漏、有二义性、甚至有错误；
在软件开发过程中，用户还提出修改软件开发功能、界面、支撑环境等方面的要求；
软件开发人员对用户需求的理解与用户本来愿望有差异。
（2）缺乏正确的理论指导
缺乏有力的方法学和工具方面的支持。由于软件开发不同于大多数其他工业产品，其开发过程是复杂的逻辑思维过程，其产品极大程度地依赖于开发人员高度的智力投入。由于过分地依靠程序设计人员在软件开发过程中的技巧和创造性，加剧软件开发产品的个性化，也是发生软件开发危机的一个重要原因。 
（3）软件开发规模越来越大
随着软件开发应用范围的增广，软件开发规模愈来愈大。大型软件开发项目需要组织一定的人力共同完成，而多数管理人员缺乏开发大型软件开发系统的经验，而多数软件开发人员又缺乏管理方面的经验。各类人员的信息交流不及时、不准确、有时还会产生误解。软件开发项目开发人员不能有效地、独立自主地处理大型软件开发的全部关系和各个分支，因此容易产生疏漏和错误。
（4）软件开发复杂度越来越高
软件开发不仅仅是在规模上快速地发展扩大，而且其复杂性也急剧地增加。软件开发产品的特殊性和人类智力的局限性，导致人们无力处理“复杂问题”。所谓“复杂问题”的概念是相对的，一旦人们采用先进的组织形式、开发方法和工具提高了软件开发效率和能力，新的、更大的、更复杂的问题又摆在人们的面前。
解决途径
软件工程诞生于60年代末期，它作为一个新兴的工程学科，主要研究软件生产的客观规律性，建立与系统化软件生产有关的概念、原则、方法、技术和工具，指导和支持软件系统的生产活动，以期达到降低软件生产成本 、改进软件产品质量、提高软件生产率水平的目标。软件工程学从硬件工程和其他人类工程中吸收了许多成功的经验，明确提出了软件生命周期的模型，发展了许多软件开发与维护阶段适用的技术和方法，并应用于软件工程实践，取得良好的效果。
在软件开发过程中人们开始研制和使用软件工具，用以辅助进行软件项目管理与技术生产，人们还将软件生命周期各阶段使用的软件工具有机地集合成为一个整体，形成能够连续支持软件开发与维护全过程的集成化软件支援环境，以期从管理和技术两方面解决软件危机问题。
此外，人工智能与软件工程的结合成为80年代末期活跃的研究领域。基于程序变换、自动生成和可重用软件等软件新技术研究也已取得一定的进展，把程序设计自动化的进程向前推进一步。在软件工程理论的指导下，发达国家已经建立起较为完备的软件工业化生产体系，形成了强大的软件生产能力 。软件标准化与可重用性得到了工业界的高度重视，在避免重用劳动，缓解软件危机方面起到了重要作用。
相关因素
硬件生产率大幅提高
如今，计算机的发展已进入一个新的历史阶段；硬件产品已系列化、标准化，"即插即用"。硬件产品的生产可以采用最高精尖的现代化工具和手段、自动成批生产。生产效率几百万倍的提高。生产能力过剩。
软件生产随规模增大复杂度增大
以美国宇航局的软件系统为例：
1963年 水星计划系统 200万条指令
1967年 双子星座计划系统 400万条指令
1973年 阿波罗计划系统 1000万条指令
1979年 哥伦比亚航天飞机系统 4000万条指令
假设1个人一年生产一万条有效指令，那么是否4000人生产一年，或400人生产10年就能完成任务呢？答案是否定的。一万条指令的复杂度决不仅仅是100条指令复杂度的100倍。
软件生产率很低
伴随计算机的普及，整个社会对计算机应用的需求越来越大。
但软件的生产却还沿用"手工作坊"的生产方式，人工编程生产。生产效率仅提高了几倍。
生产能力极其低下。
硬、软件供需失衡
社会大量需求，生产成本高，生产过程控制复杂，生产效率低等等因素构成软件生产的恶性循环。由此产生"软件危机"。
矛盾引发危机
软件危机是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。
为了研究、解决软件危机，诞生了一门新兴学科--软件工程学。它把软件作为工程对象，从技术措施和组织管理两个方面来研究、解决软件危机。
具体体现
1. 软件开发进度难以预测
拖延工期几个月甚至几年的现象并不罕见，这种现象降低了软件开发组织的信誉。以丹佛新国际机场为例:
该机场规模是曼哈顿机场的两倍，宽为希思机场的10倍，可以全天侯同时起降三架喷气式客机；投资1.93亿美元建立了一个地下行李传送系统，总长21英里，有4，000台遥控车，可按不同线路在20家不同的航空公司柜台、登机门和行李领取处之间发送和传递行李；支持该系统的是5，000个电子眼、400台无线电接受机、56台条形码扫描仪和100台计算机。按原定计划要在1993年万圣节前启用，但一直到1994年6月，机场的计划者还无法预测行李系统何时能达到可使机场开放的稳定程度。
2. 软件开发成本难以控制
投资一再追加，令人难于置信。往往是实际成本比预算成本高出一个数量级。
而为了赶进度和节约成本所采取的一些权宜之计又往往损害了软件产品的质量，从而不可避免地会引起用户的不满。
3. 用户对产品功能难以满足
开发人员和用户之间很难沟通、矛盾很难统一。往往是软件开发人员不能真正了解用户的需求，而用户又不了解计算机求解问题的模式和能力，双方无法用共同熟悉的语言进行交流和描述。
在双方互不充分了解的情况下，就仓促上阵设计系统、匆忙着手编写程序，这种"闭门造车"的开发方式必然导致最终的产品不符合用户的实际需要。
4. 软件产品质量无法保证
系统中的错误难以消除。软件是逻辑产品，质量问题很难以统一的标准度量，因而造成质量控制困难。
软件产品并不是没有错误，而是盲目检测很难发现错误，而隐藏下来的错误往往是造成重大事故的隐患。
5. 软件产品难以维护
软件产品本质上是开发人员的代码化的逻辑思维活动，他人难以替代。除非是开发者本人，否则很难及时检测、排除系统故障。
为使系统适应新的硬件环境，或根据用户的需要在原系统中增加一些新的功能，又有可能增加系统中的错误。 
6. 软件缺少适当的文档资料
文档资料是软件必不可少的重要组成部分。
实际上，软件的文档资料是开发组织和用户的之间权利和义务的合同书，是系统管理者、总体设计者向开发人员下达的任务书，是系统维护人员的技术指导手册，是用户的操作说明书。
缺乏必要的文档资料或者文档资料不合格，将给软件开发和维护带来许多严重的困难和问题。最典型失败系统的例子是：
IBM公司开发OS/360系统，共有4000多个模块，约100万条指令，投入5000人年，耗资数亿美元，结果还是延期交付。在交付使用后的系统中仍发现大量（2000个以上）的错误。 
1968年在德国召开的NATO（North Atlantic Treaty Organization ,北大西洋公约组织）会议上首次提出了“软件工程”概念，希望用工程化的原则和方法来克服软件危机