标题：软件项目风险管理
总体介绍
如果对项目进行风险管理，就可以最大限度的减少风险的发生。但是，目前国内的软件企业不太关心软件项目的风险管理，结果造成软件项目经常性的延期、超过预算，甚至失败。成功的项目管理一般都对项目风险进行了良好的管理。因此任何一个系统开发项目都应将风险管理作为软件项目管理的重要内容。
在项目风险管理中，存在多种风险管理方法与工具，软件项目管理只有找出最适合自己的方法与工具并应用到风险管理中，才能尽量减少软件项目风险，促进项目的成功。
软件项目的风险管理是软件项目管理的重要内容。在进行软件项目风险管理时，要辩识风险，评估它们出现的概率及产生的影响，然后建立一个规划来管理风险。风险管理的主要目标是预防风险。本文探讨了风险管理的主要内容和方法，介绍了风险管理的经典理论，比较了几种主流的风险管理策略和模型。
引言
近几年来软件开发技术、工具都有了很大的进步，但是软件项目开发超时、超支、甚至不能满足用户需求而根本没有得到实际使用的情况仍然比比皆是。软件项目开发和管理中一直存在着种种不确定性，严重影响着项目的顺利完成和提交。但这些软件风险并未得到充分的重视和系统的研究。直到20世纪80年代，Boehm比较详细地对软件开发中的风险进行了论述，并提出软件风险管理的方法。Boehm认为，软件风险管理指的是“试图以一种可行的原则和实践，规范化地控制影响项目成功的风险”，其目的是“辨识、描述和消除风险因素，以免它们威胁软件的成功运作”。
在此基础上，业界对软件风险管理的研究开始慢慢丰富起来，理论上对风险进行了一些分类，提出了风险管理的思路；实践上也出现了一些定量管理风险的方法和风险管理的软件工具。虽然业界对风险管理表现了极大的兴趣，做出了不少努力，但似乎很少开发项目的组织真正积极地在软件开发过程中使用风险管理的方法。1995年IWSED（International Workshop on Software Engineering Data）会议做出的调查显示：风险管理技术没有得到广泛应用的原因并不是大家不相信这种技术的实效性，而是对风险管理的技术和实践缺乏了解。因此，我们认为很有必要对风险管理进行研究。
软件项目风险管理概念
软件开发中的风险是指软件开发过程中及软件产品本身可能造成的伤害或损失。风险关注未来的事情，这意味着，风险涉及选择及选择本身包含的不确定性，软件开发过程及软件产品都要面临各种决策的选择。风险是介于确定性和不确定性之间的状态，是处于无知和完整知识之间的状态。另一方面，风险将涉及思想、观念、行为、地点等因素的改变。
当在软件工程领域考虑风险时，我们要关注以下的问题：什么样的风险会导致软件项目的彻底失败；用户需求、开发技术、目标计算机以及所有其他与项目有关的因素的改变将会对按时交付和总体成功产生什么影响；对于采用何种方法和工具，需要多少人员参与工作的问题，我们如何选择和决策；软件质量要达到什么程度才是“足够的”。当没有办法消除风险，甚至连试图降低该风险也存在疑问时，这些风险就是真正的风险了。在我们能够标识出软件项目中的真正风险之前，识别出所有对管理者和开发者而言均为明显的风险是很重要的。
风险管理在项目管理中占有非常重要的地位。首先，有效的风险管理可以提高项目的成功率。其次，风险管理可以增加团队的健壮性。与团队成员一起进行风险分析可以让大家对困难有充分估计，对各种意外有心理准备，大大提高组员的信心，从而稳定队伍。第三，有效的风险管理可以帮助项目经理抓住工作重点，将主要精力集中于重大风险，将工作方式从被动救火转变为主动防范。
被动风险策略是针对可能发生的风险来监督项目，直到它们变成真正的问题时，才会拨出资源来处理它们。更普遍的是，软件项目组对风险不闻不问，直到发生了错误才赶紧采取行动，试图迅速地纠正错误。这种管理模式常常被称为“救火模式”。当补救的努力失败后，项目就处在真正的危机之中了。
对于风险管理的一个更聪明的策略是主动式的。主动策略早在技术工作开始之前就已经启动了。标识出潜在的风险，评估它们出现的概率及产生的影响，对风险按重要性进行排序，然后，软件项目组建立一个计划来管理风险。主动策略中的风险管理，其主要目标是预防风险。但是，因为不是所有的风险都能够预防，所以，项目组必须建立一个应付意外事件的计划，使其在必要时能够以可控的及有效的方式做出反应m任何一个系统开发项目都应将风险管理作为软件项目管理的重要内容。
在进行软件项目风险管理时，要标识出潜在的风险，评估它们出现的概率及产生的影响，并按重要性加以排序，然后建立一个规划来管理风险。风险管理的主要目标是预防风险，但不是所有的风险都能够预防。所以必须建立一个意外事件计划，使其在必要时能以可控的和有效的方式做出反应。风险管理目标的实现包含三个要素。首先，必须在项目计划书中写下如何进行风险管理；第二，项目预算必须包含解决风险所需的经费，如果没有经费，就无法达到风险管理的目标；第三，评估风险时，风险的影响也必须纳入项目规划中。
风险管理涉及的主要过程包括：风险识别，风险量化，风险应对计划制定和风险监控，如图1所示[1][3]。风险识别在项目的开始时就要进行，并在项目执行中不断进行。就是说，在项目的整个生命周期内，风险识别是一个连续的过程。
风险识别：风险识别包括确定风险的来源，风险产生的条件，描述其风险特征和确定哪些风险事件有可能影响本项目。风险识别不是一次就可以完成的事，应当在项目的自始至终定期进行。
风险量化：涉及对风险及风险的相互作用的评估，是衡量风险概率和风险对项目目标影响程度的过程。风险量化的基本内容是确定那些事件需要制定应对措施。。
风险应对计划制定：针对风险量化的结果，为降低项目风险的负面效应制定风险应对策略和技术手段的过程。风险应对计划依据风险管理计划、风险排序、风险认知等依据，得出风险应对计划、剩余风险、次要风险以及为其它过程提供得依据。
风险监控：涉及整个项目管理过程中的风险进行应对。该过程的输出包括应对风险的纠正措施以及风险管理计划的更新。
每个步骤所使用的工具和方法详见表1：
风险管理步骤 所使用的工具、方法 
风险识别 头脑风暴法、面谈、Delphi法、核对表、SWOT技术 
风险量化 风险因子计算、PERT估计、决策树分析、风险模拟 
风险应对计划制定 回避、转移、缓和、接受 
风险监控 核对表、定期项目评估、挣值分析
软件项目中的风险
软件项目的风险无非体现在以下四个方面：需求、技术、成本和进度。IＴ项目开发中常见的风险有如下几类：需求风险①需求已经成为项目基准,但需求还在继续变化;②需求定义欠佳,而进一步的定义会扩展项目范畴;③添加额外的需求;④产品定义含混的部分比预期需要更多的时间;⑤在做需求中客户参与不够;⑥缺少有效的需求变化管理过程。计划编制风险①计划、资源和产品定义全凭客户或上层领导口头指令,并且不完全一致;②计划是优化的,是"最佳状态",但计划不现实,只能算是"期望状态";③计划基于使用特定的小组成员,而那个特定的小组成员其实指望不上;④产品规模(代码行数、功能点、与前一产品规模的百分比)比估计的要大;⑤完成目标日期提前,但没有相应地调整产品范围或可用资源;⑥涉足不熟悉的产品领域,花费在设计和实现上的时间比预期的要多。组织和管理风险①仅由管理层或市场人员进行技术决策,导致计划进度缓慢,计划时间延长;②低效的项目组结构降低生产率;③管理层审查 决策的周期比预期的时间长;④预算削减,打乱项目计划;⑤管理层作出了打击项目组织积极性的决定;⑥缺乏必要的规范,导至工作失误与重复工作;⑦非技术的第三方的工作(预算批准、设备采购批准、法律方面的审查、安全保证等)时间比预期的延长。人员风险①作为先决条件的任务(如培训及其他项目)不能按时完成;②开发人员和管理层之间关系不佳,导致决策缓慢,影响全局;③缺乏激励措施,士气低下,降低了生产能力;④某些人员需要更多的时间适应还不熟悉的软件工具和环境;⑤项目后期加入新的开发人员,需进行培训并逐渐与现有成员沟通,从而使现有成员的工作效率降低;⑥由于项目组成员之间发生冲突,导致沟通不畅、设计欠佳、接口出现错误和额外的重复工作;⑦不适应工作的成员没有调离项目组,影响了项目组其他成员的积极性;⑧没有找到项目急需的具有特定技能的人。开发环境风险①设施未及时到位;②设施虽到位,但不配套,如没有电话、网线、办公用品等;③设施拥挤、杂乱或者破损;④开发工具未及时到位;⑤开发工具不如期望的那样有效,开发人员需要时间创建工作环境或者切换新的工具;⑥新的开发工具的学习期比预期的长,内容繁多。客户风险①客户对于最后交付的产品不满意,要求重新设计和重做;②客户的意见未被采纳,造成产品最终无法满足用户要求,因而必须重做;③客户对规划、原型和规格的审核 决策周期比预期的要长;④客户没有或不能参与规划、原型和规格阶段的审核,导致需求不稳定和产品生产周期的变更;⑤客户答复的时间(如回答或澄清与需求相关问题的时间)比预期长;⑥客户提供的组件质量欠佳,导致额外的测试、设计和集成工作,以及额外的客户关系管理工作。产品风险①矫正质量低下的不可接受的产品,需要比预期更多的测试、设计和实现工作;②开发额外的不需要的功能(镀金),延长了计划进度;③严格要求与现有系统兼容,需要进行比预期更多的测试、设计和实现工作;④要求与其他系统或不受本项目组控制的系统相连,导致无法预料的设计、实现和测试工作;⑤在不熟悉或未经检验的软件和硬件环境中运行所产生的未预料到的问题;⑥开发一种全新的模块将比预期花费更长的时间;⑦依赖正在开发中的技术将延长计划进度。设计和实现风险①设计质量低下,导致重复设计;②一些必要的功能无法使用现有的代码和库实现,开发人员必须使用新的库或者自行开发新的功能;③代码和库质量低下,导致需要进行额外的测试,修正错误,或重新制作;④过高估计了增强型工具对计划进度的节省量;⑤分别开发的模块无法有效集成,需要重新设计或制作。过程风险①大量的纸面工作导致进程比预期的慢;②前期的质量保证行为不真实,导致后期的重复工作;③太不正规(缺乏对软件开发策略和标准的遵循),导致沟通不足,质量欠佳,甚至需重新开发;④过于正规(教条地坚持软件开发策略和标准),导致过多耗时于无用的工作;⑤向管理层撰写进程报告占用开发人员的时间比预期的多;⑥风险管理粗心,导致未能发现重大的项目风险。
风险辨识
识别风险是系统化地识别已知的和可预测的风险，在可能时避免这些风险，且当必要时控制这些风险。根据风险内容，我们可以将风险分为：
(1)产品规模风险：与软件的总体规模相关的风险。
(2)商业影响风险：商业风险影响到软件开发的生存能力。商业风险包含的五个主要的风险是：
l 市场风险：开发了一个没有人真正需要的优秀产品或系统；
l 策略风险：开发的产品不符合公司的整体商业策略；
l 销售风险：开发了一个销售部门不知道如何去卖的产品；
l 管理风险：由于重点的转移或人员的变动而失去了高级管理层的支持的风险；
l 预算风险：没有得到预算或人力上的保证。
(3)客户特性风险：与客户的素质以及开发者和客户沟通能力相关的风险。
(4)过程定义风险：与软件过程定义相关的风险。
(5)开发环境风险：与开发工具的可用性及质量相关的风险。
(6)技术风险：技术风险是指在设计、实现、接口、验证、维护、规约的二义性、技术的不确定性、陈旧的技术等方面存在的风险。技术风险威胁到软件开发的质量及交付的时间，如果技术风险变成现实，则开发工作可能变得很困难或根本不可能。
(7)人员数目及经验带来的风险：与参与工作的软件工程师的总体技术水平及项目经验相关的风险。
在进行具体的软件项目风险识别时，可以根据实际情况对风险分类。但简单的分类并不是总行的通的，某些风险根本无法预测。在这里，我们介绍一下美国空军软件项目风险管理手册中指出的如何识别软件风险。这种识别方法要求项目管理者根据项目实际情况标识影响软件风险因素的风险驱动因子，这些因素包括以下几个方面。
(1)性能风险：产品能够满足需求和符合使用目的的不确定程度。
(2)成本风险：项目预算能够被维持的不确定的程度。
(3)支持风险：软件易于纠错、适应及增强的不确定的程度。
(4)进度风险：项目进度能够被维持且产品能按时交付的不确定的程度。
每一个风险驱动因子对风险因素的影响均可分为四个影响类别——可忽略的、轻微的、严重的及灾难性的。
风险分析
在进行了风险辨识后，我们就要进行风险估算，风险估算从以下几个方面评估风险清单中的每一个风险：
(1)建立一个尺度，以反映风险发生的可能性；
(2)描述风险的后果；
(3)估算风险对项目及产品的影响；
(4)标注风险预测的整体精确度，以免产生误解。
对辨识出的风险进行进一步的确认后分析风险，即假设某一风险出现后，分析是否有其他风险出现，或是假设这一风险不出现，分析它将会产生什么情况，然后确定主要风险出现最坏情况后，如何将此风险的影响降低到最小，同时确定主要风险出现的个数及时间。进行风险分析时，最重要的是量化不确定性的程度和每个风险可能造成损失的程度。为了实现这点，必须考虑风险的不同类型。识别风险的一个方法是建立风险清单，清单上列举出在任何时候可能碰到的风险最重要的是要对清单的内容随时进行维护，更新风险清单，并向所有的成员公开，应鼓励项目团队的每个成员勇于发现问题并提出警告。建立风险清单的一个办法是将风险输入缺陷追踪系统中，建立风险追踪工具，缺失追踪系统一般能将风险项目标示为已解决或尚待处理状态，也能指定解决问题的项目团队成员，并安排处理顺序。风险清单给项目管理提供了一种简单的风险预测技术，下表事一个风险清单的例子：
风险 类别 概率 影响 
资金将会流失 商业风险 40% 1 
技术达不到预期效果 技术风险 30% 1 
人员流动频繁 人员风险 60% 3 
在风险清单中，风险的概率值可以由项目组成员个别估算，然后加权平均，得到一个有代表性的值。也可以通过先做个别估算而后求出一个有代表性的值来完成。对风险产生的影响可以对影响评估的因素进行分析。
一旦完成了风险清单的内容，就要根据概率进行排序，高发生率、高影响的风险放在上方，依次类推。项目管理者对排序进行研究，并划分重要和次重要的风险，对次重要的风险再进行一次评估并排序。对重要的风险要进行管理。从管理的角度来考虑，风险的影响及概率是起着不同作用的，一个具有高影响且发生概率很低的风险因素不应该花太多的管理时间，而高影响且发生率从中到高的风险以及低影响且高概率的风险，应该首先列入管理考虑之中。
在这里，我们需要强调的是如何评估风险的影响，如果风险真的发生了，它所产生的后果会对三个因素产生影响：风险的性质、范围及时间。风险的性质是指当风险发生时可能产生的问题。风险的范围是指风险的严重性及其整体分布情况。风险的时间是指主要考虑何时能够感到风险及持续多长时间。可以利用风险清单进行分析，并在项目进展过程中迭代使用。项目组应该定期复查风险清单，评估每一个风险，以确定新的情况是否引起风险的概率及影响发生改变。这个活动可能会添加新的风险，删除一些不再有影响的风险，并改变风险的相对位置。
风险评估的对策
在风险评估过程中，我们可以采取以下的步骤：
(1)定义项目的风险参考水平值。要使风险评估发生作用，就要定义一个风险参考水平值，对于大多数项目而言，通过对性能、成本、支持及进度等因素的分析，可以找出风险的参考水平值，对于性能下降、成本超支、支持困难或进度延迟（或者这四种的组合）等情况，超过这一参考水平值项目就会被终止。
(2)建立每一组（风险、风险发生的概率、风险产生的影响）与每一个参考水平值的关系。
(3)预测一组临界点以定义项目终止区域，该区域由一条曲线或不确定区域界定。
(4)预测什么样的风险组合会影响参考水平值。
风险驾驭
风险驾驭包括对策指定、风险缓解、风险监控、风险跟踪等内容。
所有风险分析活动都只有一个目的——辅助项目组建立处理风险的策略。如果软件项目组对于风险采取主动的方法，则避免永远是最好的策略。这可以通过建立一个风险缓解计划来达到即制定对策。
对不同的风险项要建立不同的风险驾驭和监控的策略比。如对于开发人员离职的风险项目开始时应作好人员流动的准备采取一些措施确保人员一旦离开时项目仍能继续；制定文档标准并建立一种机制保证文档及时产生；对每个关键性技术岗位要培养后备人员。对于技术风险，可以采用的策略有，对采用的关键技术进行分析，避免软件在生命周期中很快落后；在项目开发过程中保持对风险因素相关信息的收集工作，减少对合作公司的依赖尤其是对延续性强的项目应该尽可能地吸收合作公司的技术并变为自己的技术，避免因为可能发生的与合作公司合作的终止带来的影响和风险降低投入成本。
一个有效的策略必须考虑风险避免、风险监控和风险管理及意外事件计划这样三个问题。风险的策略管理可以包含在软件项目计划中，或者风险管理步骤也可以组成一个独立的风险缓解、监控和管理计划（RMMM计划）。RMMM计划将所有风险分析工作文档化，并且由项目管理者作为整个项目计划的一部分来使用，RMMM计划的大纲主要包括：主要风险，风险管理者，项目风险清单，风险缓解的一般策略、特定步骤，监控的因素和方法，意外事件和特殊考虑的风险管理等。一旦建立了RMMM计划，我们就开始了风险缓解及监控，风险缓解是一种避免问题的活动，风险监控则是跟踪项目的活动。它有三个主要目的：评估一个被预测的风险是否真的发生了；保证为风险而定义的缓解步骤被正确地实施；收集能够用于未来的风险分析信息。
软件开发是高风险的活动。如果项目采取积极风险管理的方式，就可以避免或降低许多风险，而这些风险如果没有处理好，就可能使项目陷入瘫痪中。因此在软件项目管理中还要进行风险跟踪。对辨识后的风险在系统开发过程中进行跟踪管理，确定还会有哪些变化，以便及时修正计划。具体内容包括：
(1)实施对重要风险的跟踪；
(2)每月对风险进行一次跟踪；
(3)风险跟踪应与项目管理中的整体跟踪管理相一致；
(4)风险项目应随着时间的不同而相应地变化。
通过风险跟踪，进一步对风险进行管理，从而保证项目计划的如期完成。
经典风险管理理论
Boehm模型Boehm用公式RE=P(UO)*L(UO)对风险进行定义，其中RE表示风险或者风险所造成的影响，P(UO)表示令人不满意的结果所发生的概率，L(UO)表示糟糕的结果会产生的破坏性的程度。在风险管理步骤上，Boehm基本沿袭了传统的项目风险管理理论，指出风险管理由风险评估和风险控制两大部分组成，风险评估又可分为识别、分析、设置优先级3个子步骤，风险控制则包括制定管理计划、解决和监督风险3步。
Boehm思想的核心是10大风险因素列表，其中包括人员短缺、不合理的进度安排和预算、不断的需求变动等。针对每个风险因素，Boehm都给出了一系列的风险管理策略。在实际操作时，以10大风险列表为依据，总结当前项目具体的风险因素，评估后进行计划和实施，在下一次定期召开的会议上再对这10大风险因素的解决情况进行总结，产生新的10大风险因素表，依此类推。
10大风险列表的思想可以将管理层的注意力有效地集中在高风险、高权重、严重影响项目成功的关键因素上，而不需要考虑众多的低优先级的细节问题。而且，这个列表是通过对美国几个大型航空或国防系统软件项目的深入调查，编辑整理而成的，因此有一定的普遍性和实际性。但是它只是基于对风险因素集合的归纳，尚未有文章论述其具体的理论基础、原始数据及其归纳方法。另外，Boehm也没有清晰明确地说明风险管理模型到底要捕获哪些软件风险的特殊方面，因为列举的风险因素会随着多个风险管理方法而变动，同时也互相影响。这就意味着风险列表需要改进和扩充，管理步骤也需要优化。
虽然其理论存在一些不足，但Boehm毕竟可以说是软件项目风险管理的开山鼻祖。在其之后，更多的组织和个人开始了对风险管理的研究，软件项目风险管理的重要性日益得到认同。CRM模型SEI（Software Engineering Institution）作为世界上著名的旨在改善软件工程管理实践的组织，也对风险管理投入了大量的热情。SEI提出了持续风险管理管理模型CRM（Continuous Risk Management）。
SEI的风险管理原则是：不断地评估可能造成恶劣后果的因素；决定最迫切需要处理的风险；实现控制风险的策略；评测并确保风险策略实施的有效性。
CRM模型要求在项目生命期的所有阶段都关注风险识别和管理，它将风险管理划分为5个步骤：风险识别、分析、计划、跟踪、控制。框架显示了应用CRM的基础活动及其之间的交互关系，强调了这是一个在项目开发过程中反复持续进行的活动序列。每个风险因素一般都需要按顺序经过这些活动，但是对不同风险因素开展的不同活动可以是并发的或者交替的。Leavitt模型SEI和Boehm的模型都以风险管理的过程为主体，研究每个步骤所需的参考信息及其操作。而Aalborg大学提出的思路则是以Leavitt模型为基础，着重从导致软件开发风险的不同角度出发探讨风险管理。
1964年提出的Leavitt模型将形成各种系统的组织划分为4个有趣的组成部分：任务、结构、角色和技术。这4个组成部分和软件开发的各因素很好地对应起来：角色覆盖了所有的项目参与者，例如软件用户、项目经理和设计人员等；结构表示项目组织和其他制度上的安排；技术则包括开发工具、方法、硬件软件平台；任务描述了项目的目标和预期结果。Leavitt模型的关键思路是：模型的各个组成部分是密切相关的，一个组成部分的变化会影响其他的组成部分，如果一个组成部分的状态和其他的状态不一致，就会造成比较严重的后果，并可能降低整个系统的性能。
将这个模型和软件风险的概念相对应，即一个系统开发过程中任何Leavitt组成成分的修改都会产生一些问题，甚至导致软件修改的失败。根据Leavitt模型，任何导致风险发生的因素都可以归结为模型中的组成部分，例如技术及其可行性；或者归结为组成部分之间的联系，例如程序开发人员使用某一技术的能力。因此，使用Leavitt模型从4个方面分别识别和分析软件项目的风险是极有条理性和比较全面的。在进行软件项目管理时，可以采用不同的方法对不同的方面进行风险管理。
Leavitt模型实际上是提出一个框架，可以更加广泛和系统地将软件风险的相关信息组织起来。Leavitt理论的设计方法和实现研究已经广泛应用于信息系统中，它所考虑的都是软件风险管理中十分重要的环节，而且简单、定义良好、适用于分析风险管理步骤。
总结
总之，在软件项目开发过程中，当对软件的期望很高时，一般都会进行项目风险分析、预测、评估、管理及监控等风险管理。通过风险管理可以使项目进程更加平稳，可以获得很高的跟踪和控制项目的能力，并且可以增强项目组成员对项目如期完成的信心。风险管理是项目管理中很重要的管理活动，有效的实施软件风险管理是软件项目开发工作顺利完成的保证。