简介:这份资源是合肥工业大学计算机与信息学院2019~2020学年第二学期软件工程课程A卷试卷原件,面向正在备考软件工程的学生及需要梳理知识框架的复习者,可用于自测理论掌握程度、对照课堂重点查漏补缺。压缩包内共1个docx文件,约25KB,完整收录判断题、选择题、填空题、名词解释与简答题等题型,覆盖需求分析、模块独立性、结构化程序设计、软件测试覆盖、软件维护与迭代模型等核心考点,并附有试卷标准答案页眉信息,便于还原真实考试场景。已有1800人学习下载,说明该卷在同类复习资料中具有一定参考价值。读者可借助原题与答案线索,逐题核对概念理解,重点体会非直接耦合、判定覆盖与条件覆盖、边界值分析法等易混知识点的辨析思路,从而在有限时间内高效完成考前自测与知识串联。
1. 一份能当“错题本”用的软件工程 A 卷:从判断题到 McCabe 环路
期末周翻资料,最怕遇到那种只有题目没有答案、或者答案只写“略”的卷子。这份 2019~2020 学年第二学期的软件工程 A 卷不一样,它把判断题、选择题、填空题、名词解释、简答题、应用题六种题型全带上了,应用题里还完整保留了一道 PDL 求平均值的基本路径测试大题。对正在准备软件工程考试、或者想拿一套真题反向梳理知识框架的人来说,这份试卷原件的价值不在“押题”,而在于它把软件工程从需求、设计、测试到维护的主干知识点用 100 分的题量压了一遍,做完一遍基本能知道自己哪块是空的。
它适合三类人:一是期末复习想找真题练手的学生,二是带课的老师想找一份题型完整的样卷做参考,三是已经工作但软件工程概念有点模糊的开发者,拿它当一次低成本的自测。下面按“先看懂卷子结构、再逐块拆知识点、最后落到那道 18 分大题怎么算”的顺序走,中间会给出可复现的解题步骤和参数,坑也一并标出来。
2. 拆卷子结构:六种题型各自在考什么
拿到一份试卷,先别急着从头做题,先看题型分布。这份卷子的分值结构是判断 10 分、选择 10 分、填空 10 分、名词解释 20 分、简答 20 分、应用 30 分,客观题和主观题基本对半开,应用题独占 30 分,说明命题重心压在“能不能动手画图、能不能算复杂度”上。这个分布本身就值得注意:软件工程不是背概念就能过的课,基本路径测试、软件结构图这类题必须会动手。
2.1 客观题的知识点地图
判断题和选择题加起来 20 分,但覆盖的知识点密度很高。把题干逐条拆开,能整理出一张知识点地图:
| 题号 | 题型 | 考点 | 常见误区 |
|---|---|---|---|
| 判断 1 | 判断 | 需求分析的必要性 | 以为了解目标就能写代码 |
| 判断 2 | 判断 | Brooks 定律 | 加人一定能赶工期 |
| 判断 3 | 判断 | 需求与维护的关系 | 维护是后期才考虑的事 |
| 判断 4 | 判断 | 耦合类型与独立性 | 非直接耦合独立性最强还是最弱 |
| 判断 5 | 判断 | 模块作用范围 | 作用范围是否含自身 |
| 判断 6 | 判断 | 结构化程序的定义 | 单入口单出口是否等于结构化 |
| 判断 7 | 判断 | 单元测试的缺陷发现率 | 80% 这个数字是否准确 |
| 判断 8 | 判断 | 验收测试的实施者 | 最终用户还是开发方 |
| 判断 9 | 判断 | 判定覆盖与条件覆盖 | 两者是否互相包含 |
| 判断 10 | 判断 | 软件重用的定义 | 重用是否要求“不作修改” |
| 选择 1 | 选择 | 生命周期各阶段费用 | 维护费用占比 |
| 选择 2 | 选择 | 过程模型是否迭代 | 瀑布模型是否迭代 |
| 选择 3 | 选择 | 开发失败的主因 | 复杂性还是需求 |
| 选择 4 | 选择 | 总体设计的输出 | 模块结构图还是数据流图 |
| 选择 5 | 选择 | 信息隐蔽与独立性 | 两者关系 |
| 选择 6 | 选择 | 三种基本控制结构 | 顺序、选择、重复 |
| 选择 7 | 选择 | PDL 的含义 | 伪码 |
| 选择 8 | 选择 | 面向对象建模图形 | 包图表示主题划分 |
| 选择 9 | 选择 | 软件成分重用的范围 | 方法标准重用是否算 |
| 选择 10 | 选择 | 测试用例设计方法 | 边界值分析法的识别 |
这张表不是让你背答案,而是让你看清命题人怎么把一个大知识点切成小题。比如“耦合”这个概念,判断题考非直接耦合的独立性,选择题考信息隐蔽与独立性的关系,同一个知识点从两个角度出题。复习时按知识点聚类,比按题号顺序刷效率高得多。
2.2 主观题的分值分配逻辑
名词解释 5 题各 4 分,简答 4 题各 5 分,这两块合计 40 分,是拉开差距的地方。名词解释考的是软件工程、数据字典、需求分析、路径覆盖、UML 五个词,都是课程主干概念,答题时不能只写一句话,4 分意味着至少要给出定义加一个关键特征或作用。简答题四道分别问生命周期阶段划分、RUP 与敏捷过程的比较、软件维护的分类、面向对象方法与结构化方法的比较,后两道明显是“比较型”题目,答题要有对照结构,不能各写各的。
应用题 30 分拆成 4 分、8 分、18 分三档。第一道画 GUI 状态转换图,考的是状态机建模;第二道画生产科和技术科的软件结构图,考的是结构化设计里的模块划分;第三道是整份卷子的压轴,用 PDL 描述的求平均值算法做基本路径测试,要求画程序图、N-S 图、PAD 图,算 McCabe 环路复杂性,求独立路径,再为每条路径设计测试用例。这道题把测试用例设计的完整流程走了一遍,是整份卷子里最值得反复练的题。
3. 基本路径测试实操:把 18 分大题拆成可复现的步骤
基本路径测试是软件工程考试里最容易翻车的题型,因为它同时要求画图、算复杂度、找路径、设计用例,任何一步错后面全错。这道求平均值的 PDL 题一共 13 个标号,逻辑不算复杂,但边界条件多,正好拿来练手。下面按考试要求的四个小问逐步拆。
3.1 先读懂 PDL 在做什么
这段 PDL 的功能是:读入最多 100 个有效数,值域在 minimum 到 maximum 之间,遇到 -999 停止,最后算平均值。关键变量有 value 数组、total.input(输入总数)、total.valid(有效数个数)、sum(有效数之和)、average(平均值)。循环条件是value[i] <> -999 AND total.input < 100,也就是说两个条件同时满足才继续循环,任一不满足就退出。循环体内先累加输入计数,再判断当前值是否在值域内,在则累加有效数和有效个数,然后 i 自增。循环结束后判断有效数个数是否大于 0,大于 0 算平均值,否则平均值置 -999。
理解这段逻辑是画图的前提。很多人直接照着标号画程序图,结果把循环的判定节点画错,根源就是没先读懂AND连接的两个条件在程序图里应该怎么表示。
3.2 画程序图:节点和边的对应关系
程序图(流图)的画法是把每个可执行语句映射成一个节点,控制流映射成有向边。这道题 PDL 已经给了 1 到 13 的标号,画图时直接按标号建节点即可。需要注意几个复合条件:标号 2 和 3 之间是AND关系,标号 5 和 6 之间也是AND关系,在程序图里复合条件要拆成独立的判定节点,否则算出来的环路复杂度会偏小。
按标号建图的基本结构是:1 到 2 是顺序边,2 到 3 是判定的一部分,3 到 4 是循环体入口,4 到 5 顺序,5 到 6 判定,6 到 7 是 THEN 分支,7 到 8 汇合,8 到 9 是 i 自增后回边,9 回到 2 形成循环,9 到 10 是循环出口,10 到 11 判定,11 到 12 是 THEN 分支,12 到 13 汇合,13 结束。
用一段伪代码把节点和边的邻接关系写出来,方便核对:
节点: 1,2,3,4,5,6,7,8,9,10,11,12,13 边: 1 -> 2 2 -> 3 (value[i] <> -999 为真) 2 -> 10 (value[i] <> -999 为假,退出循环) 3 -> 4 (total.input < 100 为真) 3 -> 10 (total.input < 100 为假,退出循环) 4 -> 5 5 -> 6 (value[i] >= minimum 为真) 5 -> 8 (value[i] >= minimum 为假) 6 -> 7 (value[i] <= maximum 为真) 6 -> 8 (value[i] <= maximum 为假) 7 -> 8 8 -> 9 9 -> 2 (回边,继续循环) 10 -> 11 11 -> 12 (total.valid > 0 为真) 11 -> 13 (total.valid > 0 为假) 12 -> 13这段邻接表就是画程序图的依据,也是后面算复杂度和找路径的基础。画 N-S 图和 PAD 图时,结构要和这个邻接关系一致,N-S 图用嵌套的矩形表示顺序、选择、循环,PAD 图用从左到右的树形结构表示,循环用带箭头的框表示。
3.3 算 McCabe 环路复杂性
McCabe 环路复杂性的计算公式有三个,考试里任选一个能算对就行:
- V(G) = E - N + 2,E 是边数,N 是节点数
- V(G) = P + 1,P 是判定节点数
- V(G) = 区域数
用第一个公式核对上面的邻接表:节点数 N = 13,边数 E 数一下,1 到 2 一条,2 分出两条,3 分出两条,4 到 5 一条,5 分出两条,6 分出两条,7 到 8 一条,8 到 9 一条,9 到 2 一条,10 到 11 一条,11 分出两条,12 到 13 一条,合计 E = 17。代入 V(G) = 17 - 13 + 2 = 6。
用第二个公式验证:判定节点是 2、3、5、6、10、11,共 6 个,V(G) = 6 + 1 = 7。两个结果不一致,说明边数或判定节点数有一处数错了。重新核对:标号 2 和 3 是AND连接,在程序图里应该拆成两个判定节点,标号 5 和 6 同理。如果按拆开算,判定节点是 2、3、5、6、10、11 共 6 个,但边数也要相应调整。这里的关键是复合条件的处理方式必须前后一致,要么都拆要么都不拆,不能画图时拆了算复杂度时又合并。
按拆开复合条件的方式重新数:节点 2 和 3 各是一个判定,节点 5 和 6 各是一个判定,加上 10 和 11,判定节点共 6 个,V(G) = 6 + 1 = 7。边数对应调整为 18,V(G) = 18 - 13 + 2 = 7,两个公式对上了。所以这道题的环路复杂性是 7,独立路径也是 7 条。
提示:复合条件拆不拆,直接决定复杂度算出来是 6 还是 7。考试时先确定处理方式,再统一执行,画图、算复杂度、找路径三步用同一套节点划分,否则数字对不上。
3.4 找独立路径并设计测试用例
独立路径的数量等于环路复杂性,7 条路径要覆盖所有边至少一次。找路径的常用方法是基线路径法:先找一条主路径,然后逐个翻转判定节点的分支,每次翻转产生一条新路径。
基线路径走“循环正常执行、值在值域内、有效数大于 0”的主干:
路径1: 1-2-3-4-5-6-7-8-9-2-10-11-12-13这条路径覆盖了循环体执行一次、值在值域内、最后算平均值的情况。接下来逐个翻转:
路径2: 1-2-3-4-5-6-8-9-2-10-11-12-13 (值大于 maximum,跳过累加) 路径3: 1-2-3-4-5-8-9-2-10-11-12-13 (值小于 minimum,跳过累加) 路径4: 1-2-10-11-12-13 (第一个值就是 -999,直接退出) 路径5: 1-2-3-10-11-12-13 (total.input 达到 100 退出) 路径6: 1-2-3-4-5-6-7-8-9-2-10-11-13 (有效数为 0,平均值置 -999) 路径7: 1-2-3-4-5-6-7-8-9-2-3-4-5-6-7-8-9-2-10-11-12-13 (循环执行两次)路径 7 是为了覆盖循环回边至少两次的情况,保证循环体的边被充分覆盖。每条路径对应一组测试用例,设计时要注意输入值的选取:
| 路径 | 输入 value | minimum | maximum | 预期输出 |
|---|---|---|---|---|
| 1 | [5, -999] | 1 | 10 | average=5, valid=1 |
| 2 | [15, -999] | 1 | 10 | average=-999, valid=0 |
| 3 | [0, -999] | 1 | 10 | average=-999, valid=0 |
| 4 | [-999] | 1 | 10 | average=-999, valid=0 |
| 5 | 100 个 5 | 1 | 10 | average=5, valid=100 |
| 6 | [5, -999] 但 minimum > maximum | 10 | 1 | average=-999, valid=0 |
| 7 | [5, 6, -999] | 1 | 10 | average=5.5, valid=2 |
路径 6 的设计要特别注意,要让 total.valid 为 0 但循环正常退出,可以把值域设成 minimum 大于 maximum,这样所有值都不在值域内,valid 保持 0,最后走 ELSE 分支。这个用例是很多人漏掉的,因为它需要构造一个“循环执行了但没有有效数”的场景。
4. 结构化设计与建模题:软件结构图和状态转换图怎么画
应用题前两道虽然分值不如基本路径测试,但它们是结构化设计方法的典型考法,画错了丢分很干脆。这两道题的共同点是都要求“从文字描述里提取模块和关系”,考的是抽象能力,不是画图技巧。
4.1 生产科软件结构图的划分依据
题目给生产科列了四条任务:根据内部合同制定车间月生产计划、根据日报周报调整月计划、以月计划为依据制定产品设计和组装月计划、把组装计划传达到各科并分解为周计划下达车间。画软件结构图的关键是把这四条任务映射成模块,再确定模块间的调用关系。
常见的划分方式是顶层设一个“生产计划管理”控制模块,下面挂三个子模块:月计划制定、月计划调整、组装计划管理。月计划制定接收合同数据,输出月生产计划;月计划调整接收日报周报,对月计划做修正;组装计划管理以月计划为输入,产出产品设计计划和组装计划,再往下分解出“计划传达”和“周计划分解”两个叶子模块。这样划分的依据是数据流:合同和报表是输入,月计划是中间数据,组装计划是输出,模块边界沿着数据流画。
画结构图时要注意扇入扇出不能太大,一般控制在 3 到 5 之间。如果某个模块扇出超过 7,说明抽象层次没拉开,需要再分层。这道题生产科的任务链比较线性,三层结构足够,不需要过度分层。
4.2 技术科结构图与数据流的关系
技术科的任务是根据组装计划做产品结构设计和工艺设计,产出装配图、外购需求计划、自制物料清单和工艺流程图。这里的模块划分要跟着产出物走:结构设计模块产出装配图和物料清单,工艺设计模块产出工艺流程图,外购需求计划可以作为结构设计的一个输出分支。
顶层设“技术设计管理”模块,下挂结构设计和工艺设计两个子模块。结构设计再分出装配图生成和物料清单生成,工艺设计分出工艺流程图生成。外购需求计划从结构设计模块输出到供应科,属于模块间的数据传递,不单独设模块。这样画出来的结构图层次清晰,每个叶子模块对应一个明确的产出物,符合高内聚低耦合的要求。
4.3 GUI 状态转换图的四个状态
第一道应用题要求画 GUI 的状态转换图,场景是一个主菜单、一个带文件打开命令的文件菜单、每个菜单都有退出命令、每次只能打开一个文件。状态转换图的核心是找状态和事件:状态有“主菜单显示”“文件菜单展开”“文件已打开”“程序退出”,事件有“点击主菜单”“点击文件菜单”“点击打开文件”“点击退出”。
从主菜单点文件菜单进入文件菜单展开状态,点打开文件进入文件已打开状态,此时再点文件菜单可以回到文件菜单展开但文件仍打开,点退出从任意状态进入程序退出。每次只能打开一个文件的约束体现在“文件已打开”状态下不能再触发打开事件,或者触发时先关闭当前文件。画图时把这条约束标在转换边上,阅卷时是加分点。
5. 避坑清单:这份卷子最容易做错的五个地方
做完一遍再对答案,发现错的往往不是不会,而是概念边界模糊。下面五条是这份卷子里高频翻车的点,每条按现象、原因、解决写,都是血泪经验堆出来的。
5.1 非直接耦合的独立性判断反了
现象:判断题第 4 题,看到“非直接耦合”就选了独立性最弱,或者犹豫半天选错。原因:把“非直接”理解成“没有直接关系所以耦合弱”,但题目描述的是两个模块之间没有直接关系、联系完全通过主模块控制调用,这恰恰是非直接耦合的定义,而它的独立性是较强的,不是最弱。解决:记住耦合从弱到强的顺序是“非直接耦合 < 数据耦合 < 标记耦合 < 控制耦合 < 外部耦合 < 公共耦合 < 内容耦合”,非直接耦合排最弱端,独立性最强。
5.2 判定覆盖和条件覆盖的包含关系搞混
现象:判断题第 9 题,认为判定覆盖一定包含条件覆盖,或者反过来。原因:两个概念的定义没分清。判定覆盖要求每个判定的真伪分支至少执行一次,条件覆盖要求每个判定中每个条件的真伪至少出现一次。条件覆盖不保证判定结果为真,判定覆盖也不保证每个条件都取到真伪,两者互不包含。解决:记一个反例,判定A AND B,条件覆盖可以取 A 真 B 假、A 假 B 真,两次判定结果都是假,判定覆盖没覆盖到真分支,所以条件覆盖不包含判定覆盖。
5.3 复合条件在程序图里没拆开
现象:算 McCabe 复杂度时用判定节点数加一算出来是 6,用边减节点加二算出来是 7,两个公式对不上。原因:画程序图时把AND连接的复合条件当成了一个判定节点,但算复杂度时又按两个判定数,前后不一致。解决:画图前先定规则,复合条件一律拆成独立判定节点,画图、数边、数判定节点三步用同一套划分,算完用两个公式交叉验证,对不上就回去查边数。
5.4 软件结构图把数据流图直接搬过来
现象:画生产科结构图时,把数据流图里的加工直接当模块画,结果模块之间全是数据流没有调用关系。原因:混淆了数据流图和软件结构图。数据流图描述数据加工和流动,软件结构图描述模块的调用层次,两者转换需要做事务分析和变换分析,不能直接照搬。解决:先找数据流的输入输出边界,输入分支做变换分析,输出分支做事务分析,再按控制层次自上而下分配模块,每个模块给一个动词加名词的名字。
5.5 测试用例只覆盖正常路径
现象:基本路径测试设计用例时,七条路径只设计了正常值和边界值,漏掉了“有效数为 0”和“输入达到 100 上限”这两种异常路径。原因:找独立路径时只盯着循环体内部的分支,忘了循环出口的两个条件也是判定节点。解决:找路径时把每个判定节点的两个分支都列出来,循环条件value[i] <> -999 AND total.input < 100要分别翻转两个子条件,出口判定total.valid > 0的真假都要覆盖,这样路径数才够。
6. 把这份卷子用成复习工具:三步自测法
卷子做完对完答案,如果只是把错题看一遍,过两周还是会错。我一般会把它用成三轮自测,每轮目标不同,最后一轮才落到具体技巧上。
第一轮限时闭卷做,严格按 120 分钟计时,判断题和选择题控制在 20 分钟内,名词解释和简答各 25 分钟,应用题留 50 分钟。这一轮的目的是暴露真实水平,不会的就空着,不要翻书。做完先不对答案,把不确定的题目标记出来,这些标记题比错题更有价值,因为它们反映的是概念模糊而不是完全不会。
第二轮开卷订正,对着教材把每道错题和标记题的知识点找出来,在卷子空白处写一句“这题考的是 X,我错在 Y”。比如判断题第 4 题写“考耦合类型排序,错在把非直接耦合当成最弱”。这一步的关键是写“错因”而不是抄正确答案,抄答案只是搬运,写错因才是加工。
第三轮只做应用题,把基本路径测试那道题重新画一遍程序图、重新算一遍复杂度、重新设计七条路径的用例,然后和第一轮的答案对照。如果两轮的程序图节点划分不一致,说明复合条件的处理规则还没固化,需要回到 3.3 节把拆不拆的规则再确认一遍。软件结构图那道题也是同理,重新画一遍生产科和技术科的结构图,对照模块划分和扇入扇出是否合理。
三轮走完,这份卷子的价值才真正榨干。从那以后我每次拿到一份真题,都强制走一遍“限时做、写错因、重做应用题”这个流程,比刷十套卷子只对答案管用得多。这份软件工程 A 卷的题型完整、应用题有代表性,拿来当这个流程的第一次练习正合适,希望帮到你。
本文还有配套的精品资源,点击获取