【试题实例】 《软件工程》试题 一、从供选择的答案中选出应填入下列叙述中( )内的正确答案。 软件设计中划分程序模块通常遵循的原则是使各模块间的耦合尽可能( A )。三种可能的模块耦合是: ( B ),例如,一个模块直接引用另一个模块中的数据。 ( C ),例如,一个模块把开关量作为参数传送给另一个模块。 ( D ),例如,一个模块通过公共数据结构把数据传送给另一个模块。 其中, ( E )的耦合性最强。 【供选择的答案】 A: ① 强 ② 适中 ③ 弱 B~E: ① 公共耦合 ② 数据耦合 ③ 逻辑耦合 ④ 外部耦合 ⑤ 内容耦合 ⑥ 控制耦合 二、为高质量地开发软件项目,在软件结构设计时必须遵循( A )的原则,( B )建立软件系统的模块结构。并且应根据( C )评价系统模块划分的质量。此外在模块设计时,应从5种基本的( D )出发,利用它们组合成一个模块的程序块结构。 要求每个( E )的结构应是单入口和单出口。 【供选择的答案】 A:① 质量控制 ② 程序优化 ③ 信息隐蔽 ④ 数据共享 ⑤ 模块通信 B:① 自底向上 ② 自顶向下 ③ 衍变的自顶向下 ④ 随机 ⑤ 回归 C:① 数据独立性 ② 程序独立性 ③ 模块独立性 ④ 可修改性 ⑤ 可理解性 D:① 数据结构 ② 处理结构 ③ 功能结构 ④ 成份 ⑤ 控制结构 E:① 程序块 ② 公共块 ③ 数据块 ④ 记录块 ⑤ 通信块 三、从下列叙述中选出5条关于好的程序设计风格的正确叙述。(在对的前面打√) (1) 使用括号以改善表达式的清晰性。 (2) 对递归定义的数据结构不要使用递归过程。 (3) 尽可能对程序代码进行优化。 (4) 不要修补不好的程序, 要重新写。 (5) 不要进行浮点数的相等比较。 (6) 应尽可能多地输出中间结果。 (7) 利用数据类型对数据值进行防范。 (8) 用计数方法而不是用文件结束符或输入序列结束符来判别输入的结束。 (9) 程序中的注释是可有可无的。 (10) 使用有意义的标识符。 四、从下列叙述中选出5条关于软件测试的正确叙述。(在对的前面打√) (1) 为了使得软件容易测试, 应该使用高级的程序设计语言编制程序。 (2) 程序测试是一个程序的执行过程, 目的是为了发现软件中隐藏的错误。 (3) 如果程序中连锁式连接了8个判定(IF)结构, 则程序中总的路径数达28 。 (4) 白盒测试仅与程序的内部结构有关, 完全可以不考虑程序的功能要求。 (5) 为了快速完成集成测试, 采用一次性集成方式是适宜的。 (6) 对一批模块进行测试,发现错误多的模块中残留的错误将比其它的模块少。 (7) 好的测试用例应能证明软件是正确的。 (8) 边界值分析方法是取输入/输出等价类的边界值做为测试用例。 (9) 等价类划分方法考虑了各等价类之间取值的组合情况下可能的结果。 (10) 判定覆盖法可能查不出在判定中逻辑运算符使用有误时产生的错误。 五、从下列叙述中选出5条有利于软件可维护性的正确叙述。(在对的前面打√) (1) 在进行需求分析时需同时考虑如何实现可维护性问题。 (2) 完成测试作业后,为了缩短源程序的长度应删去程序中的注解。 (3) 尽可能在软件生产过程中保证各阶段文档的正确性。 (4) 编程时应尽可能使用全局变量。 (5) 选择时间效率和空间效率尽可能高的算法。 (6) 尽可能利用硬件的特点。 (7) 重视程序结构的设计,使程序具有较好的层次结构。 (8) 使用维护工具或支撑环境。 (9) 在进行概要设计时应加强模块间的联系。 (10) 提高程序的可读性,尽可能使用高级语言编写程序。 (11) 为了加快软件维护作业的进度,应尽可能增加维护人员的数目。 六、下面是一段用赛德尔迭代法求解线性方程组的程序。其中A[n,n] 是方程组的系数矩阵, B[n]是方程组的右端项,X[n] 是方程组的解向量。eps是控制迭代精度的较小实数。imax是控制迭代的最大次数。flag是标志,=0,表示迭代不收敛;=1,表示迭代收敛。 for k := 1 to n do X[k] := 0.0; X[n] := 1.0; for i := 1 to imax do begin flag := 1; for j := 1 to n to begin s := B[j]; for k := 1 to n do begin if j =k then s := s + X[k]; s := s-A[j, k] * X[k] end; if abs(X[j]-s) > (abs(s) + 1.0) * eps then flag := 0; X[j] := s; end; if flag =1 then goto L1; end; L1: (1) 试画出它的结构化的程序流程图。 (2) 将它改为N-S图。 (3) 计算它的McCabe环路复杂性。 七、下面是一趟插入排序的程序, 把R[i+1]插入到R[1..i]的适当位置 R[0] = R[i + 1]; j = i; while ( R[j] > R[0] ) { R[j + 1] = R[j]; j = j -1; } R[j + 1] = R[0]; 用路径覆盖方法为它设计足够的测试用例(while循环次数为0次、1次、2次)。 八、阅读下列关于软件可靠性方面的叙述,回答问题1和问题2。 软件的可靠度可定义为:在假定输入和硬件不发生错误的前提下,对于给定的环境和给定的输入,在指定的时间内能完成规定任务的概率。 某软件中心的评测部为了评估已开发实现的应用软件ASP的可靠性,决定采用软件可靠性的错误播种模型来进行测试和评估。评测部在评估时,作了下列三个假设: (1) 在测试前,单位长度的故障个数ET / IT 为一常数,此常数基本上落在一个固定的范围内。其中IT 为被测程序的长度(即机器指令条数),ET 为被测程序中故障总数。 (2) 失效率正比于软件中剩余的(潜伏的)故障数,平均无故障时间MTTF与单位长度的剩余故障个数成反比,即 MTTF = 1/(K*εr )。其中εr 为单位长度剩余故障个数,K的典型值现取为200。 (3) 测试中发现的错误都得到了及时改正,在测试过程中没有引入新的错误。评测部对ASP软件人为地植入了10个错误,即NS = 10,在开始测试的一小段时间内,发现了160个固有故障,即n = 160,又发现了植入的故障2个,即nS = 2,被测程序ASP的长度(机器指令条数)为105 。 问题1:用故障播种(植入)的数学模型,估算出被测程序ASP的固有故障的个数N的值。如果通过测试一段时间后,发现的固有错误个数为ED = 795时,请估算此程序的平均无故障时间MTTF值。 问题2:若要求把此MTTF再提高4倍,应至少再排除多少个固有错误? 请简要地列出有关计算式。 参考答案 一、答案:A. ③ B. ⑤ C. ⑥ D. ① E. ⑤ 二、答案:A. ③ B. ② C. ③ D. ⑤ E. ① 三、答案:正确的叙述有:(1)、(4)、(5)、(7)、(10) 说明:(1) 利用括号可以明确地规定表达式中各运算符的优先顺序,这样可以提供表达式运算的清晰性,因此是对的。(4) 对于不好的程序,一是程序逻辑混乱以致理解困难,二是隐藏错误多,三是错误定位和修改容易出问题,所以修修补补,越补越糟,不如重新写。(5) 浮点数的运算有其近似性,两个浮点数可能会非常接近但永远不会相等,所以做浮点数的相等比较可能不会有结果。(7) 利用数据类型来检查数据值,这是静态分析的一种手段,叫做类型分析,因此是对的。(10) 使用有意义的标识符,可以提高程序的可读性,因此是对的。 其它的叙述都不对。(2) 对递归定义的数据结构,应当使用递归过程来解决基于这种数据结构的应用问题。(3) 程序代码的优化工作应交给编译器来做,程序设计时应首先考虑程序代码的清晰性、简明性、可读性、正确性、以至于可维护性。(6) 输出中间结果只是在调试程序时才有用,其它时候输出大量中间结果,不但浪费资源,而且给使用者造成麻烦。(8) 从文件输入数据时,应当使用文件结束符来判断输入的结束,使用计数方法判断输入结束不一定是最佳方式。(9) 程序中的注释是必须的,不是可有可无的。 四、答案:正确的叙述有:(1)、(2)、(3)、(4)、(8)。 说明:(1) 使用高级语言编写的程序模块化、结构化程度都比较好,可读性强,容易测试。(2) 程序测试本身应当是一个程序的执行过程,而不是静态的逻辑分析,其目的是发现程序中潜藏的错误。(3) 连锁式分支结构有n个判定,其路径数有2n条,因此当n = 8时程序中总的路径数有28条。(4) 白盒测试基于程序的内部结构设计测试用例,可以不考虑程序的功能要求。(8) 由于在等价类的边界上最容易出错,所以边界值分析方法选取输入∕输出等价类的边界值作为测试用例,可以有效地查错。 不正确的叙述,如(5) 采用一次性集成方式进行模块组装,往往成功的可能性低,而且出现错误时,不容易确定在什么地方出了问题,因此应采用增殖式集成方式,可以把出错的范围局限到少数模块中间。(6) 测试的实践表明,对一批模块进行测试,发现错误多的模块中残留的错误也多,因此必需注意这一现象,弄清哪些模块问题发现得多,对这些模块重点测试。(7) 好的测试用例是能够发现新错误的测试用例,发现不了问题的测试用例就不是好的测试用例,用它们做测试是浪费时间和金钱。(9) 等价类划分法是选择输入等价类的代表值作为测试用例,而因果图法才是考虑了各等价类之间取值的组合情况及可能的结果来设计测试用例的。(10) 语句覆盖法可能查不出在判定中逻辑运算符使用有误时产生的错误。而判定覆盖法则可能查不出在判定中某些条件中关系运算符使用有误时产生的错误。 五、答案:正确的叙述有:(3)、(5)、(7)、(8)、(10) 说明:(3) 尽可能在软件生产过程中保证各阶段文档的正确性,对于保证软件的可靠性、功能性等有相当大的作用,这样可减少用户提出维护请求的可能,即使要更新,工作的难度和工作量也会降低。(5) 选择时间效率和空间效率尽可能高的算法,可以让编程者把注意力集中在提供程序的正确性、可理解性、可修改性、可测试性、可使用性等方面,从而提高可维护性,不必为追求效率而把程序编写得让人看不懂。(7) 如果程序结构设计得较好,层次结构合理,在维护时理解程序和修改程序容易,不易出错。(8) 使用维护工具或支撑环境可以大大降低维护的工作量。(10) 用高级语言编写程序,易读易懂,可以提高可维护性。 不正确的叙述,如(1) 在需求分析时主要考虑软件要“做什么?”这一阶段对可维护性可以提出要求,要达到什么指标,而如何实现可维护性,是在设计和实现阶段考虑的问题。(2) 在程序中加入注释,这是提高程序可读性,从而提高可维护性的重要手段,不能因为测试通过就删去它们。(9) 在软件概要设计时,对产生的程序模块结构的评价方法就是看模块之间的耦合(联系)是否松散。如果联系密切,这样的结构各部分牵连太多,是不好的。(4) 因此在编程时尽可能用参数表,而不应当用全局变量来传送信息。(6) 尽可能利用硬件的特点,这样的程序可移植性很差,自然维护起来就相当困难了。(11) 增加维护人员会降低维护的生产率,有可能对维护进度带来不利的影响。 六、答案:(1) 结构化的程序流程图: (2) N-S图: (3) McCabe环路复杂性度量V(G) = 判定语句个数+1 = 8 七、`画出该程序的流程图: 测试用例设计 循环 次数  输 入 数 据   预 期 结 果  覆 盖 路 径    j R[i-2] R[i-1]  R[i] R[i+1] R[0]  j R[i-2] R[i-1]  R[i] R[i+1] 约束  路 径   0  i  ―  ―  1  2  2  i  ―  ―  1  2 < ①③    i  ―  ―  1  1  1  i  ―  ―  1  1 = ①③   1  i  ―  1  3  2  2 i-1  ―  1  2  3 >< ①②③    i  ―  2  3  2  2 i-1  ―  2  2  3 >= ①②③   2  i  1  3  4  2  2 i-2  1  2  3  4 >>< ①②②③    i  2  3  4  2  2 i-2  2  2  3  4 >>= ①②②③   八、答案: 〖问题1〗利用故障播种(植入)模型,被测程序ASP的固有故障个数N的值为: N = NS * n / nS = 10 * 160 / 2 = 800 (个故障)。 根据Shooman模型: 〖问题2〗把此MTTF再提高4倍,则MTTF = 500,有 得: EC(t) = 799 因此,只要再排除799 - 795 = 4个固有错误,MTTF就可再提高4倍。