1 软件工程

软件开发生命周期:


软件定义时期包括可行性研究详细需求分析过程任务是确定软件开发工程必须完成的总目


具体(步骤)可分成问题定义、可行性研究、需求分析等。


 


软件开发时期:就是软件的设计与实现,可分成计、计、编码、测试等。


软件运行和维护:就是把软件产品移交给用户使用。


  


软件系统的文档


可以分为用户文档系统文档两类,用户文档主要描述系统功能和使用方法,并不关系这些功能是怎样实现的;系统文档描述系统设计、实现和测试等各方面的内容。


软件工程过程


软件工程过程是指为获得软件产品,在软件工具的支持下由软件工程师完成的一系列软件工程 活动,包括以下4 个方面。 ---- PDCA


  • (1)P(Plan)——软件规格说明。规定软件的功能及其运行时的限制。
  • (2)D(Do)——软件开发。开发出满足规格说明的软件。
  • (3)C(Check)——软件确认。确认开发的软件能够满足用户的需求。
  • (4)A(Action)——软件演进。软件在运行过程中不断改进以满足客户新的需求。

定义:软件工程过程是把输入转化为输出的一组彼此相关的资源和活动。


定义支持了软件工程过程的个方面内涵。
第一,软件工程过程是指为获得软件产品,在软件工具支持下由软件工程师完成的一些列软件工程活动。基于这个方面,软件工程过程通常包含4种基本活动:
1. plan——软件规格说明。规定软件的功能及其运行时的限制。
2. do——软件开发。产生满足规格说明的软件。
3. check——软件确认。确认软件能够满足客户提出的要求。
4. action——软件演进。为满足客户的变更要求,软件必须在使用的过程中演进。
事实上,软件工程过程是一个软件开发机构针对某类软件产品为自己规定的工作步骤,它应当是科学的、合理的,否则必将影响软件产品的质量
第二,从软件开发的观点看,它就是使用适当的资源(包括人员、硬软件工具、时间等)为开发软件进行的一组开发活动,在过程结束时将输入(用户要求)转化为输出(软件产品)
所以,<软件工程的过程>是将软件工程的方法和工具综合起来,以达到合理、及时地进行计算机软件开发的目的。软件工程过程应确定方法使用的顺序、要求交付的文档资料、为保证质量和适应变化所需要的管理、软件开发各个阶段完成的任务。


①软件工程包括三个要素:方法、工具和过程。

②软件工程过程中(主要是开发)用到的方法,如结构化方法、面向对象、形式化方法等等

③软件开发过程中的工具,后面有介绍。

④过程主要就是PDCA


软件系统工具


软件系统工具通常可以按软件过程活动将软件工具分为软件开发工具、软件维护工具、软件管理和软件支持工具。


软件 开发 工具:需求分析工具、设计工具、编码与排错工具、测试工具等。


软件 维护 工具:版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工程工具。


软件 管理和 软件 支持 工具项目管理工具、配置管理工具 软件评价工具、软件开发工具的评价和选择



①配置项的管理,这属于管理方面的居多



 


软件设计


软件设计包括四个既独立又相互联系的活动,即数据设计架构(体系结构)设计人机界面(接


口)设计过程设计,这四个活动完成以后就得到了全面的软件设计模型



( 数据设计---架构设计---人机界面设计---过程设计 )===>全面的软件设计模型



1.1 软件过程模型

参考:第五章 软件工程基础知识-博客


瀑布模型(SDLC)



瀑布模型(SDLC):结构化方法中的模型,是结构化的开发,开发流程如同瀑布一般,一步一步的走下去,直到最后完成项目开发,只适用于需求明确或者二次开发(需求稳定),当需求不明确时,最终开发的项目会错误,有很大的缺陷。



原型



原型:与瀑布模型相反,原型针对的就是需求不明确的情况,首先快速构造一个功能模型,演示给用户看,并按用户要求及时修改,中间再通过不断的演示与用户沟通,最终设计出项目,就不会出现与用户要求不符合的情况,采用的是迭代的思想。不适合超大项目开发。



螺旋模型



螺旋模型:是多种模型的混合,针对需求不明确的项目,与原型类似,但是增加了风险分析,这也是其最大的特点。适合大型项目开发四阶段迭代:目标设定、风险分析、开发和有效性验证、评审



增量模型



增量模型:首先开发核心模块功能,而后与用户确认,之后再开发次核心模块的功能,即每次开发一部分功能,并与用户需求确认,最终完成项目开发,优先级最高的服务最先交付。由于并不是从



系统整体角度规划各个模块,因此不利于模块划分难点在于如何将客户需求划分为多个增量与原型不用的是增量模型的每一次增量版本都可作为独立可操作的作品,而原型的构造一般是为了演示。



喷泉模型



喷泉模型:特点是面向对象的模型,而上述其他的模型都是结构化的模型,使用了迭代思想和无间隙开发。



基于构件的开发模型 CBSD



基于构件的开发模型 CBSD:特点是增强了复用性,在系统开发过程中,会构建一个构件库,供其他系统复用,因此可以提高可靠性,节省时间和成本。



形式化方法模型



形式化方法模型:建立在严格数学基础上的一种软件开发方法,主要活动是生成计算机软件形式化的数学规格说明。



敏捷模型



开发宣言:个体和交互 胜过 过程和工具、可以工作的软件 胜过 面面俱到的文档、客户合作 胜过 合同谈判、响应变化 胜过 遵循计划。




十、软件工程基础知识(考点篇)_软件开发


敏捷方法区别于其他方法的两个特点:


  • (1)是“适应性”而非“预设性”。
  • (2)是“面向人的”而非“面向过程的”。

这两点特征是与计划驱动或重型开发方法的主要区别。


敏捷方法的核心思想:


  • (1)敏捷方法是适应型,而非可预测型。拥抱变化,适应变化。
  • (2)敏捷方法是以人为本,而非以过程为本。发挥人的特性。
  • (3)迭代增量式的开发过程。以原型开发思想为基础,采用法代增量式开发,发行版本小型化。

主要敏捷方法:


  • (1)极限编程(XP)。基础和价值观是交流、朴素、反馈和勇气,即任何一个软件项目都可以从4个方面入手进行改善:加强交流:从简单做起:寻求反馈;勇于实事求是。XP 是一种近螺旋式的开发方法,它将复杂的开发过程分解为一个个相对比较简单的小周期:通过积极的交流、反馈以及其他一系列的方法,开发人员和客户可以非常清楚开发进度、变化、待解决的问题和潜在的困难等,并根据实际情况及时地调整开发过程。XP提倡测试先行,为了将以后出现bug的几率降到最低-- 以人为本,近螺旋,测试先行(bug率低下),从交流、朴素(简单)、反馈、勇气四方面入手,
  • (2)水晶系列方法。与XP方法一样,都有以人为中心的理念,但在实践上有所不同。其目的是发展一种提倡“机动性的”方法,包含具有共性的核心元素,每个都含有独特的角色、过程模式、工作产品和实践。-- 以人为本,机动性
  • (3)并列争球法(Scrum)。是一种迭代的增量化过程,把每段时间(如 30天)一次的迭代称为一个“冲刺”(Sprint),并按需求的优先级别来实现产品,多个自组织和自治的小组并行地递增实现产品。-- 迭代增量,冲刺,优先级实现
  • (4)特性驱动开发方法(FDD)。是一个迭代的开发模型。认为有效的软件开发需要3 个要素人、过程和技术。有5个核心过程开发整体对象模型、构造特征列表、计划特征开发、特征设计和特征构建。其中,<计划特征开发>根据构造出的<特征列表>、特征间的依赖关系进行计划,设计出包含<特征设计和特征构建>过程组成的多次选代。-- 迭代,3要素,5过程
统一过程模型(RUP)


RUP 描述了如何有效地利用商业的、可靠的方法开发和部署软件,是一种重量级过程。RUP 类


似一个在线的指导者,它可以为所有方面和层次的程序开发提供指导方针、模版以及事例支持。


RUP 软件开发生命周期是一个二维的软件开发模型,RUP 中有9个核心工作流。


-- 把商业的可靠的方法运用到开发和部署软件上。


这9个核心工作流如下。
  • 业务建模:理解待开发系统所在的机构及其商业运作,确保所有参与人员对待开发系统所在的机构有共同的认识,评估待开发系统对所在机构的影响。
  • 需求:定义系统功能及用户界面,使客户知道系统的功能,使开发人员理解系统的需求,为项目预算及计划提供基础。
  • 分析与设计:把需求分析的结果转化为分析与设计模型。
  • 实现:把设计模型转换为实现结果,对开发的代码做单元测试,将不同实现人员开发的模块集成为可执行系统。
  • 测试:检查各子系统之间的交互、集成,验证所有需求是否均被正确实现,对发现的软件质量上的缺陷进行归档,对软件质量提出改进建议。
  • 部署:打包、分发、安装软件,升级旧系统;培训用户及销售人员,并提供技术支持。
  • 配置与变更管理:跟踪并维护系统开发过程中产生的所有制品的完整性和一致性。
  • 项目管理:为软件开发项目提供计划、人员分配、执行、监控等方面的指导,为风险管理提供框架。
  • 环境:为软件开发机构提供软件开发环境,即提供过程管理和工具的支持。

总结:

业务建模:理解机构及商业运作,让所有人达成共识,评估上系统的影响。

需求:跟以前学的类似。

分析与设计:需求转分析与设计模型

实现:设计模型转结果,单侧,集成等

测试:集测并改进。

部署:部署、培训

配置与变更管理:跟踪并维护制品的完整性和一致性,比如各种配置项,文档等等

项目管理:项目管理方面的

环境:提供开发环境以及过程管理和工具支持等

RUP 把软件开发生命周期划分为多个循环(每个循环是前的9个核心工作流),每个循环生成产品的一个新的版本,每个循环依次
由4 个连续的阶段组成,每个阶段完成确定的任务。这4个阶段如下。---初始-->细化-->构造-->移交
  • ·初始阶段:定义最终产品视图和业务模型,并确定系统范围。
  • ·细化阶段:设计及确定系统的体系结构,制订工作计划及资源要求。
  • ·构造阶段:构造产品并继续演进需求、体系结构、计划直至产品提交。
  • ·移交阶段:把产品提交给用户使用。
RUP 中定义了如下一些核心概念,理解这些概念对于理解 RUP 很有帮助。
  • ·角色:Who 的问题。角色描述某个人或一个小组的行为与职责。RUP预先定义了很多角色,如体系结构师、设计人员、实现人员、测试员和配置管理人员等,并对每一个角色的工作和职责都做了详尽的说明。
  • ·活动:How 的问题。活动是一个有明确目的的独立工作单元。
  • ·制品:What 的问题。制品是活动生成、创建或修改的一段信息。
  • ·工作流:When 的问题。工作流描述了一个有意义的连续的活动序列,每个工作流产生一些有价值的产品,并显示了角色之间的关系。
RUP的特点:3点


  • (1)用例驱动:需求分析、设计、实现和测试等活动都是用例驱动的。
  • (2)以体系结构为中心:包括系统的总体组织和全局控制、通信协议、同步、数据存取、给设计元素分配功能、设计元素的组织、物理分布、系统的伸缩性和性能等。软件的体系结构是一个多维的结构,会采用多个视图来描述。
在典型的4+1视图模型中
  • 分析人员和测试人员关心的是系统的行为,会侧重于用例视图;
  • 最终用户关心的是系统的功能,会侧重于逻辑视图;
  • 程序员关心的是系统的配置、装配等问题,会侧重于实现视图;
  • 系统集成人员关心的是系统的性能、可伸缩性、吞吐率等问题,会侧重于进程视图;
  • 系统工程师关心的是系统的发布、安装、拓扑结构等问题,会侧重于部署视图。

十、软件工程基础知识(考点篇)_软件工程_02


 

总结:

分析、测试------->系统行为----------------------->用例视图

用户---------------->功能----------------------------->逻辑视图

程序员------------->系统配置、装配-------------->实现视图

集成---------------->性能、伸缩性、吞吐率----->进程视图

系统工程师------->发布、安装、拓扑----------->部署视图


  • (3)迭代与增量。把整个项目开发分为多个迭代过程。在每次选代中,只考虑系统的一部分需求,进行分析、设计、实现、测试和部署等过程;每次迭代是在己完成部分的基础上进行的,每次增加一些新的功能实现,以此进行下去,直至最后项目的完成。


1.2 能力成熟度模型


能力成熟度模型 CMM


软件组织化阶段的描述,随着软件组织定义、实施、测量、控制和改进其软件过程,软件组织


的能力经过这些阶段逐步提高。针对软件研制和测试阶段。分为如下五个级别:




十、软件工程基础知识(考点篇)_软件开发_03



能力成熟度模型集成CMMI


是若干过程模型的综合和改进,不仅仅软件,而是支持多个工程学科和领域的、系统的、一致的


过程改进框架,能适应现代工程的特点和需要,能提高过程的质量和工作效率。


CMMI两种表示方法:


(1)阶段式模型:类似于 CMM,它关注组织的成熟度,五个成熟度模型如下:


十、软件工程基础知识(考点篇)_软件开发_04


其中2-5级对应的过程域如下图所示:



十、软件工程基础知识(考点篇)_迭代_05


2.连续式模型:关注每个过程域的能力,一个组织对不同的过程域可以达到不同的过程域能力等


级。


总结:

初始:成功全靠个人英雄级别;

可重复(已管理):有了基本的过程管理和项目进度及费用的跟踪,能重复类似的;

已定义:在管理和工程2方面的过程已经文档化标准化,成为某个组织行业的标准了

已管理级(定量管理):从定性到定量了,对过程有了详细的度量标准。

优化级:持续优化更新。



1.3 逆向工程


软件复用是将已有软件的各种有关知识用于建立新的软件,以缩减软件开发和维护的花费。软件复用是提高软件生产力和质量的一种重要技术。早期的软件复用主要是代码级复用,被复用的知识专指程序,后来扩大到包括领域知识、开发经验、设计决定、体系结构、需求、设计、代码和文档等一切有关方面。


逆向工程:软件的逆向工程是分析程序,力图在比源代码 更高抽象层次 建立程序的表示过程,逆向工程 设计的恢复过程 。逆向工程的四个级别:


  • 实现级:包括程序的抽象语法树、符号表、过程的设计表示。
  • 结构级:包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图、程序和数据结构
  • 功能级:包括反映程序段功能及程序段之间关系的信息,例如数据和控制流模型
  • 领域级:包括反映程序分量或程序诸实体与应用领域概念之间对应关系的信息,例如 E-R模型

其中,领域级 抽象级别 最高, 完备性 最低,实现级抽象级别最低,完备性最高



与逆向工程相关的概念有重构、设计恢复、再工程正向工程



(1)重构是指在同一抽象级别上转换系统描述形式---相同抽象级别,换种描述


(2)设计恢复是指借助工具从已有程序中抽象出有关数据设计、总体结构设计和过程设计等方面的信息---从 程序中恢复当时的设计


(3)再工程是指在逆向工程所获得信息的基础上修改或重构已有的系统,产生系统的一个新版本。再工程是对现有系统的重新开发过程包括逆向工程、新需求的考虑过程和正向工程三个步骤。它不仅能从已存在的程序中重新获得设计信息,而且还能使用这些信息来重构现有系统,以改进它的综合质量。在利用再工程重构现有系统的同时,一般会增加新的需求,包括增加新的功能和改善系统的性能。 --- 先逆向工程,然后根据获得的设计信息,并增加新的需求,重构


(4)正向工程是指不仅从现有系统中恢复设计信息,而且使用该信息去改变或重构现有系统,以改善其整体质量。 --- 恢复设计信息,然后用这些设计再去重构现有系统,改善质量



2 需求工程

2.1 软件需求


软件需求 是指用户对系统在功能、行为、性能、设计约束等方面的期望。是指用户解决问题或达到目标所需的条件或能力,是系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或能力以及反映这些条件或能力的文档说明。




分为需求开发和需求管理两大过程,如下所示:图很重要



十、软件工程基础知识(考点篇)_迭代_06


获取-->分析-->定义(SRS)-->验证-->基线-->变更控制-->版本控制-->需求跟踪-->需求状态跟踪


|-------------需求开发-----------------|<---支持---|------------------------需求管理----------------------------|




需求的层次

  • 业务需求:反映企业或客户对系统高层次的目标要求,通常来自项目投资人、客户、市场营销部门或产品策划部门。通过业务需求可以确定项目视图和范围
  • 用户需求:描述的是用户的具体目标,或用户要求系统必须能完成的任务。即描述了用户能使用系统来做什么。通常采取用户访谈问卷调查等方式,用户使用的场景进行整理,从而建立用户需求。
  • 系统需求:从系统的角度来说明软件的需求,包括功能需求、非功能需求设计约束等。
  1. 功能需求:也称为行为需求,规定了开发人员必须在系统中实现的软件功能,用户利用这些功能来完成任务,满足业务需要。
  2. 非功能需求:指系统必须具备的属性或品质,又可以细分为软件质量属性(如可维护性、可靠性、效率等)和其他非功能需求
  3. 设计约束:也称为限制条件或补充规约,通常是对系统的一些约束说明,例如必须采用国有自主知识产权的数据库系统,必须运行在 UNIX操作系统之下等。



2.2 需求获取


是一个确定和理解不同的项目干系人的需求和约束的过程


常见的需求获取法包括:

  • (1)用户访谈:1对1-3,有代表性的用户。其形式包括结构化和非结构化两种。
  • (2)问卷调查:用户多,无法一一访谈。
  • (3)采样:从种群中系统地选出有代表性的样本集的过程。样本数量=0.25*(可信度因子/错误率)2
  • (4)情节串联板:一系列图片,通过这些图片来讲故事。
  • (5)联合需求计划(JRP):通过联合各个关键用户代表、系统分析师、开发团队代表一起,通过有组织的会议来讨论需求。
  • (6)需求记录技术:任务卡片、场景说明、用户故事、Volere白卡。

总结:

用户访谈要求比较高,自己得懂才行,而且记录比较困难(因为聊嘛);问卷调查要求也比较高,因为设计问卷也得懂的多,联合需求计划JRP是拉一批人开会,


2.3 需求分析


一个好的需求应该具有无二义性、完整性、一致性、可测试性、确定性、可跟踪性、正确性、必要性等特性。 必要的、确定、完整、正确、(前后)一致,无二义,可测试可跟踪。


 


因此,需要分析人员把杂乱无章的用户要求和期望转化为用户需求,这就是需求分析的工作。


需求分析的任务


(1)绘制系统上下文范围关系图


(2)创建用户界面原型


(3)分析需求可行性


(4)确定需求优先级


(5)为需求建立模型


(6)创建数据字典


(7)使用QFD(质量功能部署)




总结:

分析过程:


1. 绘制系统上下文范围关系图:定义系统与外部实体间的界限和接口,确定需求范围

2. 创建用户界面原型:帮助用户理解系统

3. 分析需求的可行性:经济、技术、法律、用户使用

4. 确定需求的优先级:制订系统研发的迭代计划

5. 为需求建立模型:帮助系统分析师理解系统,为软件设计提供系统的逻辑视图。

6. 创建数据字典:对系统中所有的数据项进行详细说明和定义

7. 使用QFD将产品的特性、属性和对用户的重要性联系起来




分析结果---下面的

1. 功能模型:数据流图DFD,描述系统的功能组成。

2. 行为模型:状态转换图STD,描述系统的状态和引起状态转换的事件。

3. 数据模型:实体联系图E-R,描述系统中各个实体之间的关系。

4. 数据字典:确保数据在系统中的完整性和一致性。




结构化的需求分析


结构化特点:自顶向下,逐步分解,面向数据。


三大模型:功能模型(数据流图DFD)、行为模型(状态转换图STD)、数据模型(E-R图)以及数据字典。



十、软件工程基础知识(考点篇)_软件工程_07


数据流图DFD


基本图形元素:外部实体、加工、数据存储、数据流


十、软件工程基础知识(考点篇)_迭代_08


1)数据流:由一组固定成分的数据组成,表示数据的流向。


在 DFD 中,数据流的流向可以有以下几种:


  • 从一个加工流向另一个加工;从加工流向数据存储(写);
  • 从数据存储流向加工();从外部实体流向加工(输入);
  • 加工流向外部实体(输出)。

2)加工:描述了输入数据流到输出数据流之间的变换,也就是输入数据流经过什么处理后变成了输出数据流。数据流图中常见的三种错误如图所示:


加工 3.1.2 有输入但是没有输出,称之为“黑洞”。--只有输入


加工 3.1.3 有输出但没有输入。称之为“奇迹”。--只有输出


加工 3.1.1 中输入不足以产生输出,我们称之为“灰洞”(--输入不足以产生输出)。这有几种可能的原因:①一个错误的命名过程;②错误命名的输入或输出;③不完全的事实灰洞是最常见的错误,也是最使人为难的错误。一旦数据流图交给了程序员,到一个加工的输入数据流必须足以产生输出数据流。


 


十、软件工程基础知识(考点篇)_软件开发_09


3)数据存储:用来存储数据。在软件系统中还常常要把某些信息保存下来以供以后使用。


4)外部实体(外部主体):是指存在于软件系统之外的人员或组织,它指出系统所需数据的发源


地(源)和系统所产生的数据的归宿地(宿)。


分层数据流图:


十、软件工程基础知识(考点篇)_软件开发_10


数据字典 DD


数据流图描述了系统的分解,但没有对图中各成分进行说明。数据字典就是为数据流图中的每个


数据流、文件、加工,以及组成数据流或文件的数据项做出说明。


数据字典有以下4 类条目:数据流、数据项、数据存储和基本加工


十、软件工程基础知识(考点篇)_软件工程_11


加工逻辑也称为“小说明”。常用的加工逻辑描述方法有结构化语言、判定表和判定树3 种。


2.4 需求定义

软件需求规格说明书 SRS


是需求开发活动的产物,编制该文档的目的是使项目干系人与开发团队对系统的初始规定有一个共同的理解,使之成为整个开发工作的基础。SRS是软件开发过程中最重要的文档之一,对于任何规模和性质的软件项目都不应该缺少。


需求定义方法


(1)严格定义也称为预先定义,需求的严格定义建立在以下的基本假设之上:所有需求都能够被预先定义开发人员与用户之间能够准确而清晰地交流。采用图形(或文字)可以充分体现最终系统。


 


(2)原型方法,迭代的循环型开发方式,需要注意的问题:并非所有的需求都能在系统开发前被准确地说明。项目干系人之间通常都存在交流上的困难,原型提供了克该服困难的一个手段。


特点: 需要实际的、可供用户参与的系统模型。有合适的系统开发环境。反复是完全需要和值得提倡的,需求一旦确定,就应遵从严格的方法。



2.5 需求验证


也称为需求确认,目的是与用户一起确认需求无误,对需求规格说明书 SRS 进行评审和测试,包


括两个步骤:


需求评审正式评审和非正式评审。


需求测试设计概念测试用例


需求验证通过后,要请用户签字确认,作为验收标准之一,此时,这个需求规格说明书就是需求基线,不可以再随意更新,如果需要更改必须走需求变更流程


2.6 需求管理

定义需求基线


通过了评审的需求说明书就是需求基线,下次如果需要变更需求,就需要按照流程来一步步进行。


需求的流程及状态如下图所示:



十、软件工程基础知识(考点篇)_软件开发_12



需求变更和风险


主要关心需求变更过程中的需求风险管理,带有风险的做法有:无足够用户参与、忽略了用户分


类、用户需求的不断增加、模棱两可的需求、不必要的特性、过于精简的 SRS、不准确的估算。


  


变更产生的原因: 外部环境 的变化、 需求和设计 做的 不够完整 、 新技术 的出现、 公司机构重组 造成业务流程的变化。


  


变更控制委员会 CCB:也称为配置控制委员会,其任务时对建议的配置项变更做出评价、审批,以及监督已经批准变更的实施。


需求跟踪:


双向跟踪,两个层次 ,如下图所示:


十、软件工程基础知识(考点篇)_软件开发_13


正向跟踪 表示用户原始需求是否都实现了反向跟踪表示软件实现的是否都是用户要求的,不多


不少,可以用原始需求和用例表格(需求跟踪矩阵)来表示:


若原始需求和用例有对应,则在对应栏打对号,若某行都没有对号,表明原始需求未实现,正向跟踪发现问题;若某列都没有对号,表明有多余功能用例,软件实现了多余功能,反向跟踪发现问题。


总结:

正向跟踪:是否都实现了;反向跟踪:是否多实现了;需求跟踪矩阵:行是需求-列是用例。


3 系统设计

先进行系统的流程设计,然后进行系统设计,最后界面设计。

3.1处理流程设计

◆流程表示工具


程序流程图(Program Flow Diagram,PFD)用一些图框表示各种操作,它独立于任何一种程序设计语言,比较直观、清晰,易于学习掌握。任何复杂的程序流程图都应该由顺序、选择和循环结构组合或嵌套而成。


IPO图:是流程描述工具,用来描述构成软件系统的每个模块的输入、输出和数据加工


  


N-S 图:容易表示嵌套和层次关系,并具有强烈的结构化特征。但是当问题很复杂时,N-S 图可能很大,因此不适合于复杂程序的设计。


  


问题分析图(PAD)是一种支持结构化程序设计的图形工具。PAD具有清晰的逻辑结构、标准化的图形等优点,更重要的是,它引导设计人员使用结构化程序设计方法,从而提高程序的质量



N-S图(盒图),IPO图,PAD图



十、软件工程基础知识(考点篇)_迭代_14





◆业务流程重组 BPR


BPR是对企业的业务流程进行根本性的再思考和彻底性的再设计,从而获得可以用诸如成本、质量、服务和速度等方面的业绩来衡量的显著性的成就。BPR 设计原则、系统规划和步骤如下图所示:



十、软件工程基础知识(考点篇)_软件工程_15




总结:

基本原则:流程为中心,团队管理(以人为本)、客户导向。----重要

设计规划:战略->流程->数据->功能->系统

实现步骤:启动->计划->建团队->分析流程->重新设计流程->实施->持续改进->重新开始



◆业务流程管理 BPM


BPM 是一种以规范化的构造端到端的卓越业务流程为中心以持续的提高组织业务绩效为目的的系统化方法。


BPM与 BPR 管理思想最根本的不同就在于流程管理并不要求对所有的流程进行再造。构造卓越的业务流程并不是流程再造,而是根据现有流程的具体情况,对流程进行规范化的设计。


流程管理包含三个层面:规范流程、优化流程和再造流程。--先规范,在优化,再造





3.2 系统设计


系统设计主要目的:为系统制定蓝图,在各种技术和实施方法中权衡利弊,精心设计,合理地使用各种资源,最终勾画出新系统的详细设计方法


 


系统设计方法结构化设计方法,面向对象设计方法。


 


系统设计的主要内容计、计。


 


概要设计基本任务:又称为系统总体结构设计,是将系统的功能需求分配给软件模块,确定每个模块的功能和调用关系,形成软件的模块结构图,即系统结构图。


 


详细设计的基本任务:模块内详细算法设计、模块内数据结构设计、数据库的物理设计、其他设计(代码、输入/输出格式、用户界面)、编写详细设计说明书、评审。



总结:

系统设计的目的是为系统制定蓝图,勾画出详细设计方法,需要采用一系列方法,比如结构化的,面向对象的等方法来实现;其实内容主要就是概设和详设。



系统设计基本原理

  • 抽象化;
  • 自顶而下,逐步求精;
  • 信息隐蔽;
  • 模块独立(高内聚,低耦合)。
  • 系统设计原则
  • 保持模块的大小适中;
  • 尽可能减少调用的深度;
  • 多扇入,少扇出;-- 多让别人调用,少调用别人,功能尽量通用
  • 单入口,单出口;
  • 模块的作用域应该在模块之内;
  • 功能应该是可预测的。

 




内聚程度从低到高如下表所示:



十、软件工程基础知识(考点篇)_软件开发_16



总结:

偶然内聚:偶然性的;

逻辑内聚:这就是逻辑功能相似, 根据参数决定执行哪个

时间内聚:把这些模块组合在一起 同时执行;

过程内聚:一个模块能完成多个任务,但是必须按照 指定顺序执行, 是一个过程

通信内聚:在 同一个数据结构上操作, 输入输出相同

顺序内聚:类似管道过滤器; 顺序执行,输入为输出

功能内聚:这个是一个有机整体,共同作用缺一不可。



耦合程度从低到高如下所示:


十、软件工程基础知识(考点篇)_迭代_17


总结:

无直接:相当于偶然;

数据:类似值传递;

标记:传递数据结构了,比如list

控制:类似逻辑内聚, 根据传递的控制变量来执行哪一功能

外部:模块 通过软件之外的环境联合

公共:通过 公共数据结构/环境相互作用

内容:模块内部联系,通过非正常入口转入另一模块内


系统结构图(SC)


系统结构图(SC)又称为模块结构图,它是软件计阶段的工具,反映系统的功能实现和模块之间的联系与通信,包括各模块之间的层次结构,即反映了系统的总体结构


 


详细设计的表示工具


详细设计的表示工具有图形工具、表格工具语言工具


其中图形工具有业务流图、程序流程图、PAD 图、NS流程图


详细设计的表示图形工具
程序流程图


程序流程图又称为程序框图,是使用最广泛然的一种描述程序逻辑结构的工具。它用方框表示一个处理步骤菱形表示一个逻辑条件箭头表示控制流向。其优点是:结构清晰,易于理解,易于修 改。缺点是:只能描述执行过程而不能描述有关的数据


 


NS 流程图


NS 流程图,也称为盒图,是一种强制使用结构化构造的图示工具,也称为方框图。其具有以下特点:功能域明确、不可能任意转移控制、很容易确定局部和全局数据的作用域、很容易表示嵌套关


系及模板的层次关系。


 


PAD 图


PAD 图是一种改进的图形描述方式,可以用来取代程序流程图,相比程序流程图更直观,结构更清晰。最大的优点是能够反映和描述自顶向下的历史和过程。PAD 提供了 5 种基本控制结构的图 示,并允许递归使用。



3.3 人机界面设计


人机界面设计的三大原则:置于用户控制之下、减用户的记忆负担、保持界面一致性。


 


  • 置于用户的控制之下以不强迫用户进入不必要的或不希望的动作的方式来定义交互方式;
  • 提供灵活的交互;
  • 允许用户交互可以被中断和取消;
  • 当技能级别增加时可以使交互流水化并允许定制交互;
  • 使用户隔离内部技术细节;
  • 设计应允许用户和出现在屏幕上的对象直接交互。
  • 减少用户的记忆负担减少对短期记忆的要求;
  • 建立有意义的缺省;
  • 定义直觉性的捷径;
  • 界面的视觉布局应该基于真实世界的隐喻;
  • 以不断进展的方式揭示信息。
  • 保持界面的一致性允许用户将当前任务放入有意义的语境在应用系列内保持一致性如过去的交互模型已建立起了用户期望,除非有迫不得已的理由,不要去改变它。



4 测试基础知识

4.1 测试基础

测试原则

  • 应尽早并不断的进行测试;-- 尽早不断测试
  • 测试工作应该避免由元开发软件的人或小组承担;--避嫌
  • 在设计测试方案时,不仅要确定输入数据,而且要根据系统功能确定预期的输出结果;-- 根据功能输出确定
  • 既包含有效、合理的测试用例,也包含不合理、失效的用例;-- 用例广,有效无效的都要有
  • 检验程序是否做了该做的事,且是否做了不该做的事;-- 做了该做的,不做不该做的
  • 严格按照测试计划进行;-- 有测试计划的,按照计划执行
  • 妥善保存测试计划和测试用例;-- 妥善保管测试计划和用例
  • 测试用例可以重复使用或追加测试。-- 测试用例可重复用并追加

测试类型分为两大类:


动态测试


程序运行时测试。


  • 黑盒测试法:功能性测试,不了解软件代码结构,根据功能设计用例,测试软件功能。
  • 白盒测试法:结构性测试,明确代码流程,根据代码逻辑设计用例,进行用例覆盖。
  • 灰盒测试法:即既有黑盒,也有白盒。

静态测试


程序静止时,即对代码进行人工审查。


  • 桌前检查:程序员检查自己编写的程序,在程序编译后,单元测试前-- 单测前自查
  • 代码审查:由若干个程序员和测试人员组成评审小组,通过召开程序评审会来进行审查。-- 别的程序员和测试员会议评审
  • 代码走查:也是采用开会来对代码进行审查,但并非简单的检查代码,而是由测试人员提供测试用例,让程序员扮演计算机的角色,手动运行测试用例,检查代码逻辑。-- 也是开会不过,测试员给用例,程序员充当电脑,测试


4.2 测试阶段


(1)单元测试:也称为模块测试,测试的对象是可独立编译或汇编的程序模块、软件构件OO软件中的类(统称为模块),测试依据是软件详细设计说明书。


  


(2)集成测试:目的是检查模块之间,以及模块和已集成的软件之间的接口关系,并验证已集成的软件是否符合设计要求。测试依据是软件概要设计文档。


  


(3)确认测试:主要用于验证软件的功能、性能和其他特性是否与用户需求一致。根据用户的参与程度,通常包括以下类型:


  • 内部确认测试:主要由软件开发组织内部按照 SRS进行测试
  • Alpha测试用户开发环境下进行测试。
  • Beta 测试用户实际使用环境下进行测试,通过改测试后,产品才能交付用户。
  • 验收测试:针对 SRS,在交付前以用户为主进行的测试其测试对象为完整的、集成的计算机系统。验收测试的目的是,在真实的用户工作环境下,检验软件系统是否满足开发技术合同或SRS。验收测试的结论用户确定是否接收该软件的主要依据。除应满足一般测试的准入条件外,在进行验收测试之前,应确认被测软件系统已通过系统测试。

(4)系统测试:测试对象是完整的、集成的计算机系统;测试的目的是在真实系统工作环境下,验证完成的软件配置项能否和系统正确连接,并满足系统/子系统设计文档和软件开发合同规定的要


求。测试依据是用户需求或开发合同。


主要内容包括功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、安装与反安装测试等,其中,最重要的工作是进行功能测试与性能测试。功能测试主要采用黑盒测试方法;性能测试


主要指标有响应时间、吞吐量、并发用户数和资源利用率等。


 


(5)配置项测试:测试对象是软件配置项,测试目的是检验软件配置项与 SRS 的一致性。测试的依据是SRS。在此之间,应确认被测软件配置项已通过单元测试和集成测试。


  


(6)回归测试:测试目的是测试软件变更之后,变更部分的正确性和对变更需求的符合性,以及软件原有的、正确的功能、性能和其他规定的要求的不损害性。


 


其他测试


(1)AB 测试是为 Web 或 App 界面或流程制作两个或多个版本,在同一时间维度,分别让组成成分相同(相似)的访客群组(目标人群)随机的访问这些版本,收集各群组的用户体验数据和业务数据,最后分析、评估出最好版本,正式采用。


 


(2)Web 测试是软件测试的一部分,是针对 Web 应用的一类测试。由于 Web 应用与用户直接相关,又通常需要承受长时间的大量操作,因此 Web 项目的功能和性能都必须经过可靠的验证。


 


(3)链接测试。链接是 Web 应用系统的一个主要特征,它是在页面之间切换和指导用户去一些未知地址页面的主要手段。链接测试可分为3个方面。首先,测试所有链接是否按指示那样确实链接到了该链接的页面;其次,测试所链接的页面是否存在;最后,保证 Web 应用系统上没有孤立的页面。


(4)表单测试。当用户通过表单提交信息的时候,都希望表单能正常工作。如果使用表单来进行在线注册,要确保提交按钮能正常工作,当注册完成后应返回注册成功的消息。如果使用表单收集配送信息,应确保程序能够正确处理这些数据,最后能让用户收到信息。


总结:

单侧-->集测-->系测-->确认(内测-->Alpha-->beta-->验收),补充的配置项的测试、变更修改的回归测试,以及针对app和web的AB测试,针对web的web测试、链接测试、表单测试。


4.3测试用例设计


黑盒测试用例 :将程序看做一个黑盒子,只知道输入输出,不知道内部代码,由此设计出测试用例,分为下面几类


  • 等价类划分:把所有的数据按照某种特性进行归类,而后在每类的数据里选取一个即可。等价类测试用例的设计原则:设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止;计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。-- 用例分类,每类中选一个即可,新用例设计原则:1).尽可能多的覆盖情况2).只覆盖一种情况
  • 边界值划分:将每类的边界值作为测试用例,边界值一般为范围的两端值以及在此范围之外的与此范围间隔最小的两个值,如年龄范围为0-150,边界值为0,150,-1,151四个。-- 边界值
  • 错误推测:没有固定的方法,凭经验而言,来推测有可能产生问题的地方,作为测试用例进行测试。--经验推测
  • 因果图:由一个结果来反推原因的方法,具体结果具体分析,没有固定方法。-- 结果反推

白盒测试用例 :知道程序的代码逻辑,按照程序的代码语句,来设计覆盖代码分支的测试用例,覆盖级别从低至高分为下面几种:


  • (1)语句覆盖 SC:逻辑代码中的所有语句都要被执行一遍,覆盖层级最低,因为执行了所有的语句,不代表执行了所有的条件判断。-- 代码语句都执行一遍,但是有可能条件执行不充分
  • (2)判定覆盖 DC:逻辑代码中的所有判断语句的条件的真假分支都要覆盖一次。-- 判断语句真假执行一遍,但是联合条件的每个条件没执行


十、软件工程基础知识(考点篇)_迭代_18



  • (3)条件覆盖CC:针对每一个判断条件内的每一个独立条件都要执行一遍真和假。-- 这里是补充的判定覆盖的,不管是否联合条件,每个单独的判断真假执行一遍
  • (4)条件判定组合覆盖CDC:同时满足判定覆盖和条件覆盖。-- 把判定覆盖和条件覆盖组合



十、软件工程基础知识(考点篇)_软件工程_19



  • (5)路径覆盖:逻辑代码中的所有可行路径都覆盖了,覆盖层级最高。-- 所有可行的路径都走


十、软件工程基础知识(考点篇)_软件工程_20



4.4 调试


测试是发现错误,调试是找出错误的代码和原因。


调试需要确定错误的准确位置;确定问题的原因并设法改正; 改正后要进行回归测试。


调试的方法

  • 蛮力法:又称为穷举法或枚举法,穷举出所有可能的方法一一尝试。
  • 回溯法:又称为试探法,按选优条件向前搜索,以达到目标,当发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
  • 演绎法:是由一般到特殊的推理方法,与“归纳法”相反,从一般性的前提出发。得出具体陈述或个别结论的过程。
  • 归纳法是由特殊到一般的推理方法,从测试所暴露的问题出发,收集所有正确或不正确的数据,分析它们之间的关系,提出假想的错误原因,用这些数据来证明或反驳,从而查出错误所在。

软件度量


软件的两种属性:外部属性指面向管理者和用户的属性可直接测量,一般为性能指标内部属 性指软件产品本身的的属性,如可靠性等,只能间接测量


 


McCabe度量法:又称为环路复杂度,假设有向图中有向边数为m,节点数为n,则此有向图的环路复杂度为m-n+2.


注意 m和 n 代表的含义不能混淆,可以用一个最简单的环路来做特殊值记忆此公式,另外,针对一个程序流程图,每一个分支边(连线)就是一条有向边,每一条语句(语句框)就是一个顶点。


此外,推荐使用另一种简单的计算公式:环路复杂度=判定节点个数+1.



边数和节点数(方框)


复杂度 = 边数 - 节点数 +2。




试题理解:

十、软件工程基础知识(考点篇)_迭代_21



先找开始和结束,然后找从开始到结束有几条路径。



十、软件工程基础知识(考点篇)_迭代_22




顶点数,包换开始和结束


十、软件工程基础知识(考点篇)_软件工程_23


边数


十、软件工程基础知识(考点篇)_迭代_24


13 - 11 + 2 = 4,所以环路复杂度是4。




5 系统运行与维护

5.1 系统转换


遗留系统是指任何基本上不能进行修改和演化以满足新的变化了的业务需求的信息系统,它通常


具有以下特点:


  • (1)系统完成企业中许多重要的业务管理工作仍然不能完全满足要求。一般实现业务处理电子化及部分企业管理功能,很少涉及经营决策
  • (2)系统在性能上已经落后,采用的技术已经过时。例如,多采用主机/终端形式或小型机系统,软件使用汇编语言或第三代程序设计语言的早期版本开发,使用文件系统而不是数据库。
  • (3)通常是大型的软件系统融入企业的业务运作和决策管理机制之中,维护工作十分困难
  • (4)没有使用现代信息系统建设方法进行管理和开发,现在基本上已经没有文档,很难理解


十、软件工程基础知识(考点篇)_迭代_25




从技术水平和业务价值,两方面入手:

两头的:高水平高价值的,改造一下;低水平低价值的扔了;

中间的:高水平低价值集成;低水平高价值的继承。




系统转换是指新系统开发完毕,投入运行,取代现有系统的过程,需要考虑多方面的问题,以实现与老系统的交接,有以下三种转换计划:

  • 直接转换:现有系统被新系统直接取代了,风险很大适用于新系统不复杂,或者现有系统已经不能使用的情况。优点是节省成本
  • 并行转换:新系统和系统并行工作一段时间,新系统经过试运行后再取代,若新系统在试运行过程中有问题,也不影响现有系统的运行,风险极小,在试运行过程中还可以比较新老系统的性能,适用于大型系统。缺点是耗费人力和时间资源难以控制两个系统间的数据转换
  • 分段转换:分期分批逐步转换,是直接和并行转换的集合,将大型系统分为多个子系统,依次试运行每个子系统,成熟一个子系统,就转换一个子系统。同样适用于大型项目,只是更耗时,而且现有系统和新系统间混合使用,需要协调好接口等问题。

数据转换与迁移:将数据从旧数据库迁移到新数据库中。要在新系统中尽可能的保存旧系统中合理的数据结构,才能降低迁移的难度。


也有三种方法:系统切换前通过工具迁移、系统切换前采用手工录入、系统切换后通过新系统生成


5.2 系统维护概述


系统的可维护性可以定义为维护人员理解、改正、改动和改进这个软件的难易程度,其评价指标


如下:


  • (1)易分析性。软件产品诊断软件中的缺陷或失效原因或识别待修改部分的能力。
  • (2)易改变性。软件产品使指定的修改可以被实现的能力,实现包括编码、设计和文档的更改。
  • (3)稳定性。软件产品避免由于软件修改而造成意外结果的能力。
  • (4)易测试性。软件产品使已修改软件能被确认的能力。
  • (5)维护性的依从性。软件产品遵循与维护性相关的标准或约定的能力。

总结:好不好分析、好不好改、改后稳定不、好不好测试、遵循相关标准不

系统维护包括硬件维护、软件维护和数据维护,其中软件维护类型如下:

  • 正确性维护:发现了 bug 而进行的修改。
  • 适应性维护:由于外部环境发生了改变,被动进行的对软件的修改和升级。
  • 完善性维护:基于用户主动对软件提出更多的需求,修改软件,增加更多的功能,使其比之前的软件功能、性能更高,更加完善。
  • 预防性维护:对未来可能发生的 bug进行预防性的修改。

总结:正确性是bug修改,适应性是环境变了适应,完善性是用户提变更,预防性是未来可能的bug。



6 净室软件工程


净室软件工程是一种应用数学与统计学理论以经济的方式生产高质量软件的工程技术,力图通过严格的工程化的软件过程达到开发中的零缺陷或接近零缺陷。净室方法不是先制作一个产品,再去消


除缺陷,而是要求在规约和设计中消除错误,然后以“净”的方式制作,可以降低软件开发中的风险,以合理的成本开发出高质量的软件。


  


在净室软件工程背后的哲学是:通过在第1次正确地书写代码增量,并在测试前验证它们的正确性来避免对成本很高的错误消除过程的依赖。它的过程模型是在代码增量积聚到系统的过程的同时,进行代码增量的统计质量验证。它甚至提倡开发者不需要进行单元测试而是进行正确性验证和统计质量控制


  


净室软件工程(CSE)的理论基础主要是函数理论和抽样理论。


  


净室软件工程应用技术手段:

  1. 统计过程控制下的增量式开发
  2. 基于函数的规范与设计。
  3. 正确性验证。CSE 的核心
  4. 统计测试和软件认证。

净室软件工程在使用过程的一些缺点:


(1)CSE 太理论化,需要更多的数学知识。其正确性验证的步骤比较困难且比较耗时


(2)CSE 开发小组不进行传统的模块测试,这是不现实的。


(3)CSE 也会带有传统软件工程的一些弊端


7 基于构件的软件工程CBSE


基于构件的软件工程(CBSE)是一种基于分布对象技术、强调通过可复用构件设计与构造软件系统的软件复用途径。CBSE 体现了“ 购买而不是重新构造 ”的哲学,将软件开发的重点从程序编写转移到了基于己有构件的组装,以更快地构造系统,减轻用来支持和升级大型系统所需要的维护负担,


从而降低软件开发的费用。



总结:就是搞一个构件库,有的开发有的购买,然后用这些构件来组装系统。



用于CBSE 的构件应该具备以下特征。

  • (1)可组装性:对于可组装的构件,所有外部交互必须通过公开定义的接口进行。同时它还必须对自身信息的外部访问。
  • (2)可部署性:软件必须是自包含的,必须能作为一个独立实体在提供其构件模型实现的构件平台上运行。构件总是二进制形式,无须在部署前编译
  • (3)文档化:构件必须是完全文档化的,用户根据文档来判断构件是否满足需求。
  • (4)独立性构件应该是独立的,应该可以在无其他特殊构件的情况下进行组装和部署,如确实需要其他构件提供服务,则应显示声明。
  • (5)标准化构件标准化意味着在CBSE 过程中使用的构件必须符合某种标准化的构件模型。

构件模型定义了构件实现、文档化以及开发的标准,其包含的模型要素为:


(1)接口。构件通过构件接口来定义,构件模型规定如何定义构件接口以及在接口定义中应该包含的要素,如操作名、参数以及异常等。


(2)使用信息。为使构件远程分布和访问,必须给构件一个特定的、全局唯一的名字或句柄


构件元数据是构件本身相关的数据,比如构件的接口和属性信息。


(3)部署构件模型包括一个规格说明,指出应该如何打包构件使其部署成为一个独立的可执行实体。部署信息中包含有关包中内容的信息和它的二进制构成的信息。


构件模型提供了一组被构件使用的通用服务,这种服务包括以下两种。

  • ·平台服务,允许构件在分布式环境下通信和互操作。
  • ·支持服务,这是很多构件需要的共性服务。例,构件都需要的身份认证服务。

中间件实现共性的构件服务,并提供这些服务的接口。


CBSE 过程


是支持基于构件组装的软件开发过程。


过程中的6个主要活动:

  • 系统需求概览 -- 看看用户的需求是啥
  • 识别候选构件 -- 根据需求来找适应的差不多的构件
  • 根据发现的构件修改需求 -- 根据找到的构件匹配一下,有些不完全匹配的适当的修改需求(当然得达到用户的目的)
  • 体系结构设计 -- 还是离不开架构设计,不过这个时候要考虑构件库的因素
  • 构件定制与适配 -- 能有的构件就用,没有的或不匹配的就开发或者修改构件
  • 组装构件创建系统。-- 组装系统

CBSE 过程与传统软件开发过程不同点:

  • (1)CBSE 早期需要完整的需求以便尽可能多地识别出可复用的构件
  • (2)在过程早期阶段根据可利用的构件来细化和修改需求。如果可利用的构件不能满足用户需求,就应该考虑由复用构件支持的相关需求。
  • (3)在系统体系结构设计完成后,会有一个进一步的对构件搜索及设计精化的活动。可能需要为某些构件寻找备用构件,或者修改构件以适合功能和架构的要求。
  • (4)开发就是将己经找到的构件集成在一起的组装过程。

构件组装


是指构件相互直接集成或是用专门编写的“胶水代码”将它们整合在一起来创造一个系统或另一个构件的过程。常见的组装构件有以下3 种组装方式。


1.顺序组装。通过按顺序调用己经存在的构件,可以用两个已经存在的构件来创造一个新的构件。如上一个构件输出作为下一个构件的输入。


2.层次组装。这种情况发生在一个构件直接调用自另一个构件所提供的服务时。被调用的构件为调用的构件提供所需的服务。二者之间接口匹配兼容。


3.叠加组装。这种情况发生在两个或两个以上构件放在一起来创建一个新构件的时候。这个新构件合并了原构件的功能,从而对外提供了新的接口。外部应用可以通过新接口来调用原有构件的接口,而原有构件不互相依赖,也不互相调用。这种组装类型适合于构件是程序单元或者构件是服务


的情况。


构件组装的三种不兼容问题(通过编写适配器解决):


(1)参数不兼容。接口每一侧的操作有相同的名字,但参数类型或参数个数不相同。


(2)操作不兼容。提供接口和请求接口的操作名不同。


(3)操作不完备。一个构件的提供接口是另一个构件请求接口的一个子集或者相反