什么叫软件
软件是计算机系统中与硬件相互依存的另一部分,它是包括程序,数据及其相关文档的完整集合
什么叫软件危机?软件危机包含哪两点?软件危机产生的原因是什么
软件危机主要指在计算机软件开发与维护过程中所遇到的一系列严重的问题。包括两点:
- 如何开发软件,以满足软件日益增长的需求
- 如何维护数量不断膨胀的已有软件。
软件开发和维护中存在许多的严重问题,一方面和软件本身的特点有关,另一方面也和软件开发与维护的方法不正确有关。具体表现如下:
- 软件是逻辑部件而不是物理部件
- 软件的规模越来越大,复杂性越来越大
- 轻视需求分析的重要性,轻视软件维护的错误观点和方法
什么叫软件工程
采用工程的概念、原理、技术、方法来开发与维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来
两种软件工程方法学开发软件时要建立哪些模型
传统方法学和面向对象方法学
瀑布模型(需求稳定,而且可以预先指定)
原型模型(需求模糊而且可能随时变化)
增量模型(分析员先做出需求分析和概要设计,用户参与逐步完善)
螺旋模型(将瀑布模型与原型化模型结合起来,并加入了风险分析)
软件过程模型
软件过程模型分为五大类:
- 管理过程模型。
- 瀑布模型(又称为生命周期模型)
- 增量过程模型:增量模型、RAD模型
- 烟花过程模型:原型开发模型、螺旋模型、协同开发模型
- 专用过程模型:包括基于构件的开发模型,形式化方法模型,面向方法的软件开发模型
什么是软件生命周期
一个软件从定义、开发、使用和维护,直至被废弃,要经历一个漫长的时期,通常把软件经历的这个漫长时期称为一个生命周期
软件生命周期有哪几个阶段和步骤
三个阶段:定义、开发、维护
八个步骤:问题定义、可行性研究、需求分析;总体设计、详细设计、编码与单元测试、综合测试、运行维护
软件设计两个阶段是什么
总体设计阶段和详细设计阶段
总体设计阶段的两个阶段是什么
总体设计包括系统设计(划分出组成系统的程序、文件、数据库、人工过程和文档等物理元素)和结构设计(确定系统中每个程序是由哪些模块组成的,以及这些模块相互间的关系,不涉及模块内部算法流程)
软件和硬件的区别是什么
软件是一种逻辑部件,而不是具体的物理部件。软件在开发、生产、使用、维护等方面与硬件相比有明显差异。
软件是开发,硬件是制造。
软件是自定的,硬件是组装的。
软件不会磨损,硬件存在磨损问题。
软件需求分析的任务是什么
需求分析的任务是确定系统必须完成哪些工作,也就是对目标系统提出完整、准确、清晰、具体的要求。
一般来说包含下述方面:
- 确定对系统的综合要求(主要有:功能需求、性能需求、运行需求、将来可能提出的需求)
- 分析系统的数据需求
- 导出系统的逻辑模型:数据流图、实体-联系图、状态转换图、数据字典、算法流程
- 修正系统开发计划
瀑布模型与原型模型分别适用于开发那些软件
瀑布模型适用于需求文档,而且可以预先指定的大型系统工程项目。
原型模型适用于需求模糊或者随时间变化的中小型项目
数据流图的作用是什么?如何画
数据流图是以特定的图形符号描述系统逻辑模型的工具。
它从数据传送和加工的角度抽象的描述信息在系统中的流动和数据处理的过程。
它是开发人员与用户之间交流信息的通信工具。
画法
- 先找出数据源点和汇点。他们是外部实体,由他们确定系统与外界的接口。
- 找出外部实体的输出数据流和输入数据流。画出顶层数据流图。
- 从顶层加工出发,逐步细化,画出所需子图。
- 分析系统的主要处理功能。把每一个处理功能作为一个加工,并且确定他们之间的数据流入,流出关系,画出第一层数据流图。
- 对流图中每个加工进行细化,画出所需子图,直到加工不需再分解为止。
- 按照前面给出的原则检查和修改每一层数据流图和子图。
什么叫数据字典?如何写数据字典?
数据字典是描述数据流图中数据的信息的集合(描述内容包括:数据流图、状态转换图、数据字典ER图中的数据信息(数据流、数据存储、外部实体)、控制信息(事件),不包括处理。
如何写
顺序:即以确定的次序链接两个或多个分量。如:A+B
选择:即从两个或多个可能的元素中选取一个。如:[A|B]
重复:即把指定的分量重复零次或多次。如:1{A}5
可选:即一个分量可有可无
软件设计的原则有哪些?
模块化、抽象化与逐步求精、信息隐藏与局部化、模块独立
内聚与耦合有哪些,如何定义,如何区分
耦合衡量不同模块之间互相依赖的紧密程度
内聚衡量一个模块内部各个元素彼此结合的紧密程度
详细设计阶段用到的图形工具有哪些
程序流图PFD
盒图NS图
问题分析图PAD
判定树
软件工程的启发式规则有哪些
-
当模块过大时就应该分解它。一般按功能分解到成为一个小的功能单一的模块为止。一般一个模块内包含的语句在30-50条较好。
分解后不应降低模块的独立性
-
深度、宽度、扇入、扇出都应该适当。好的设计通常是顶层扇出比较高。中层扇出比较少。底层扇入到公共的使用模块中去。
模块的独立性是贯穿始终的标准,不能为了其他目标而违背独立性标准
-
对于任何一个内部存在判断调用的模块,它的判断作用的范围应该是其控制范围的一个子集。存在判断调用的模块,所在的层次不要与哪些属于判断作用范围的模块所在的层次相隔太远----越近越好
-
力争降低模块接口的复杂程度。模块接口的复杂是软件发生错误的一个主要原因。应该仔细设计模块接口,使得信息传递简单并且和模块的功能一致。接口复杂或不一致,是紧耦合或低内聚的征兆,应该重新分析这个模块的独立性
-
设计单入口单出口的模块,防止出现内容耦合
-
模块功能应该可预测----模块是黑盒子,输入相同则输出相同,其内部数据结构和接口受到限制。模块的功能应该能够预测,但也要防止模块功能过分局限。过分局限将导致模块灵活性太差,会出现使用现场的修改。
模块的控制域和作用域分别指什么?
控制域:本身及其所有下级模块
作用域:受该模块内一个判定影响的所有模块的集合
模块的扇入、扇出、深度、宽度分别是什么意思?
深度表示软件结构中控制的层数–粗略的标志一个系统的大小和复杂程度
宽度是软件结构统一层次上的模块总数的最大值–宽度越大系统越复杂
模块的扇出指的是一个模块拥有的直属下级模块的个数,一般扇出数在7以内,平均为3-4
模块的扇入是指一个模块的直接上级模块的个数
软件测试的目的是什么?
软件测试时为了发现错误无而执行程序的过程
测试时程序的执行过程,目的在于发现错误;
软件测试中需要数据,即为测试而精心设计的测试用例,利用测试用例去运行程序,帮助发现程序错误;
一个好的测试用例在于能发现至今未发现的错误;
一个成功的测试是发现至今未发现错误的测试;
软件测试绝对不是要证明程序的正确性,也证明不了程序的正确性;
单元测试有哪些内容
将每一个模块作为一个独立的测试单元,保证每个模块作为一个单元能正确运行
单元测试主要针对模块的以下五个基本特征进行测试:
- 模块接口
- 局部数据结构
- 重要的执行路径
- 错误处理
- 边界条件
什么是集成测试?非渐增式和渐增式有什么区别?渐增式如何组装模块?
将模块组合起来成为一个完整的系统对其进行测试叫做集成测试。
不论是子系统测试还是系统测试,都兼有检测和组装两重含义,通常称为集成测试。
非渐增式是将模块先进性单元测试然后组装在一起进行测试。
渐增式是逐个将未测试的模块组装到已经测试过的模块上去进行集成测试。每加入一个就测一次。
非渐增式需要桩模块、驱动模块,非渐增式开始可以并行测试、渐增式可以及时发现接口错误、非渐增式很难发现接口错误、渐增式开始不能并行测试、渐增式测试比较彻底
什么是确认测试?该阶段有哪些工作?
按照需求规格说明书中的确定指标对系统进行功能和性能的测试。
该阶段进行明确测试(按照需求规格说明书用黑盒法进行测试),软件配置测试(文档的完整性,发现遗漏错误及时补充和修改)
什么叫流图?如何画流图?流图的环形复杂度如何计算?
流图是抽象化的程序流图,突出表现控制流。
符号○代表流图的一个节点,表示一个或多个无分支语句。
箭头为边,表示控制流的方向。
在分支结构中,分支的汇聚处应有个汇聚节点。每一条边必须终止于一个节点。如果判断中的条件表达式是由一个或多个逻辑运算符连接的复合表达式,则需要改为一系列只有单个条件的嵌套的判断。
根据程序内单条件分支数或循环个数来度量环形复杂度即程序的复杂度。
环形复杂度即程序的复杂度
白盒测试与黑盒测试有哪些测试方法?如何对具体问题进行测试?
白盒测试对程序模块所有执行路径至少执行一次;对所有的逻辑判定,取真与取假白盒测试两种情况都至少测试一次;白盒测试也叫逻辑覆盖法,包括:语句覆盖,判定覆盖,条件覆盖
黑盒测试发现程序错误,必须在所有可能的输入条件和输出条件中确定测试数据,来检查程序是否能够产生正确的输出。
黑盒测试有等价类法和边界值分析法
软件测试步骤有哪些?每个测试阶段的测试依据是什么?分别由谁来测试?
步骤 测试内容 时间
单元测试:将每一个模块作为一个独立测试单元,保证每个模块作为一个单元能够正确运行。(编码阶段)
子系统测试:将经过单元测试的模块放在一起形成一个子系统来测试,以测试模块间的接口正确性作为主要任务。(集成测试阶段)
系统测试:将经过测试的子系统装配成一个完整的系统进行测试,检验系统是否确实能实现需求规格说明书中的功能,以及系统的动态特征是否符合预定要求。阶段系统测试是指整个计算机系统的测试,可与系统的安装和验收想结合进行(集合测试阶段)
验收测试:在用户参与下,把软件系统作为单一的实体进行测试,使软件系统能满足用户的需要。测试内容与系统测试基本相同(验收阶段)
平行测试:新旧两个系统同时运行进行比较,避免风险的同时给用户对新系统一段熟悉的时间(运行阶段)
什么叫维护?维护的类型有哪些?
软件维护就是在软件已经交付使用之后,为了改正错误或满足新的需要而修改软件的过程。
软件维护类型有:
- 改正性维护:对程序使用期间发现的程序错误进行诊断和改正的过程;占17-21%
- 适应性维护:配合变化了的环境进行修改软件的活动;占18-25%
- 完善性维护:满足用户在使用过程中提出增加新的功能或修改已有功能的建议而进行的改进工作;占50-66%
- 预防性维护:为了改善未来的可维护性或可靠性而修改软件的工作;占4%
UML中活动图、状态图、顺序图都分别描述的什么?
活动图强调的是从活动到活动的控制流,是一种表述过程基理、业务过程以及工作流的技术。活动图它可以用来对业务过程、工作流建模,也可以对用例实现甚至是程序实现来建模
状态机图常用来描述业务或软件系统中的对象在外部事件的作用下,对象的状态从一种状态到另一种状态的控制流
顺序图描述的是对象之间的消息发送关系,而不是类之间的关系
UML中的事物有哪些?
结构事物:UML中的名词,它是模型的静态部分,描述概念或物理元素
行为事物:UML中的动词,它是模型中的动态部分,是一种跨越空间、时间的行为。
分组事物:UML中的容器,用来组织模型,使模型更加结构化。
注释事物:UML中的解释部分,和代码中的注释语句一样,是用来描述模型的。
面向对象的基本概念类、对象、封装、继承等定义是什么?
类是具有相同属性和服务的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分
对象是系统中描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和这组属性进行操作的一组服务组成,是类的一个实例
封装是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐藏对象的内部细节
继承性:如果一个类A继承自另一个类B,就把这个A称为B的子类,而把B称为A的父类。继承使得相似对象可以共享程序代码和数据结构,大大减少程序中的冗余信息;继承可以把已有的一般性的类具体化来提高软件的可重用性。
多态性是指父类中定义的属性或服务被子类继承后,可以具有不同的数据类型或表现出不同的可重用性。
用例图的作用是什么?
用例图是外部参与者能观察到的系统功能的模型图。由一组用例、参与者及它们之间的关系组成。
主要用于对系统、子系统或类的功能行为进行建模。
参与者是系统交互的外部实体。
可以使人也可以是其他系统。
用例是从用户的角度描述系统的行为,它将系统的功能描述成一系列事件,这些时间最终对参与者产生可观察结果。
UML中的关系有哪些?
依赖,实现,泛化,关联,聚合,组合
请解释面向对象的范例如何比结构化范例更有优势?
- 结构化范例有限成功的原因在于结构化技术不是面向行动的,也不是面向数据的,但不是两者都有的,与此相反,面向对象的范式认为数据和动作同等重要。查看对象的简单方法是一个统一的软件组件,它既包含数据,也包含操作数据的操作。
- 在维护期间,实现细节对某个对象是局部的。面向对象的范式使维护变得更快、更容易,引入回归错误的机会大大减少。
- 面向对象的泛型使开发更容易。产品的对象与其在现实世界的对应关系,促进了软件的更好开发
- 精心设计的对象是独立的单位。对象由数据和数据上执行的操作组成。如果对对象的数据执行的所有操作都包含在该对象中,那么该对象可以被视为一个概念上的独立的实体。产品中的任何东西都可以在对象本身中找到,这是一种独立的额外形式,称为封装。在设计良好的对象中,信息隐藏确保实现细节隐藏于对象之外的所有内容。唯一允许的通讯形式是向对象发送消息以进行特定的动作。行动的执行方式完全由客体本身负责。
- 使用结构化范式构建的产品本质上是一个单元。这就是为什么结构化范式在应用于大型产品时不太成功的原因之一。与此相反,正确的地使用面向对象的范式,生成的产品由一些较小的、基本独立的单元组成。面向对象的范例降低了软件产品的复杂程度,从而简化了开发和维护。
- 面向对象泛型促进重用。因为对象是一个独立的实体,所可以在将来的产品中使用它们。这种对象的重用减少了开发和维护的时间和成本。
- 当使用面向对象分析时,对象从一开始就进入生命周期。在分析阶段提取对象,在设计阶段设计,并在是现阶段进行编码,因此,面向对象泛型是一种集成方法;从一个阶段的转换到另一个阶段的转换要比结构化范例更平滑,从而减少开发过程中的故障数量。
任何有用的产品几乎都肯定要在维修阶段进行维修,请解释为什么维护是必要的。
- 第一个原因是要纠正错误,无论是规格错误、设计错误、编码故障、文档错误,还是任何其他类型的错误。这就是所谓的维修。令人惊讶的是,对69个组织的研究表明,维护程序员只花了17.5%的时间进行纠正维护。
- 他们的大部分时间,60.5%,花在维护第二型、完善性维护。在这里,对代码进行修改以提高产品的有效性。例如,客户可能希望添加额外的功能,或者要求修改产品,使其运行的更快。提高了产品的可维护性的另一个例子是完善性维护。
- 改变产品的第三个原因就是适应性维护,产品的变化对产品运行环境的变化做出反应。例如:如果产品被移植到一个新的编译器、操作系统或者硬件上,几乎肯定要进行修改。随着税法的每一次修改,准备纳税申报的产品都必须相应的修改。客户机不要求自适应维护,相反,它是外部强加给客户机的。研究表明,18%的软件维护在本质上是自适应的。
- 其余4%的维修时间用于其他类型的维修,而不属于其他三类
请列出三个关于良好编码风格的建议,并简要解释一下。
- 使用一致且有意义的变量名。程序员应该给哪些不仅对程序员有意义的变量命名。在软件工程背景下,术语“有意义”意味着“从未来的维护程序员的角度来看”有意义。同时,变量名的一致性也是同样重要的。变量名的组件的排序应该是一致的。变量的名称应该包含类型信息。
- 自我记录的代码是非常罕见的。通常的情况是程序员在编写代码模块时会欣赏代码的每一个细微差别。每个模块都必须有开场白注释。内联注释应该插入代码中,以帮助维护程序员理解代码。
- 参数的使用,很少有真正的常量,也就是说,变量的值永远不会改变。所有表观常数都应作为参数处理。如果某个值因任何原因而发生变化,那么可以快速有效的实现此更改。
- 提高可读性的代码布局,不止一条语句出现在一行上,即使许多编程语言允许多于一个语句。缩进也许是提高可读性的最重要技术。另一个有用的帮助是空行。方法应该使用空行分隔。此外,经常使用空行打破大的代码块也是有帮助的。额外的空白使代码更容易阅读。
- 嵌套if语句,尝试使用丁格尔条件而不是嵌套的if语句。如果语句太深会导致难以读取代码。
请列出自上而下实施的优缺点和自底向上实现的优缺点
自上而下 | 自下而上 |
---|---|
优点:1.错误隔离 2.主要的设计缺陷很早出现 | 优点:错误隔离;潜在可重用模块较早测试 |
缺点:潜在的可重用模块没有充分测试 | 缺点:主要的设计故障被检测到较晚 |
什么是三明治集成?优点是什么?
由于无论是自顶向下还是自底向上即成都不适合所有工作,解决方案是将他们分区。
逻辑构件被自顶向下的集成,所有主要的设计故障都可以及早的捕获。操作构件集成在一起。他们因此而获得了全面的测试,通过防御性编程构件调用屏蔽,因此可以重复使用在其他产品的信心。当所有工件都被适当集成时,两组工件之间的接口将逐一测试。
优点:错误隔离。主要设计故障出现早。潜在的可重用代码工件经过充分测试。
------------------- |
| 优点:1.错误隔离 2.主要的设计缺陷很早出现 | 优点:错误隔离;潜在可重用模块较早测试 |
| 缺点:潜在的可重用模块没有充分测试 | 缺点:主要的设计故障被检测到较晚 |
什么是三明治集成?优点是什么?
由于无论是自顶向下还是自底向上即成都不适合所有工作,解决方案是将他们分区。
逻辑构件被自顶向下的集成,所有主要的设计故障都可以及早的捕获。操作构件集成在一起。他们因此而获得了全面的测试,通过防御性编程构件调用屏蔽,因此可以重复使用在其他产品的信心。当所有工件都被适当集成时,两组工件之间的接口将逐一测试。
优点:错误隔离。主要设计故障出现早。潜在的可重用代码工件经过充分测试。