软考软件设计师UML关系与面向对象原则高频考点解析
简介:本资源是面向软考中级软件设计师考生的系统性知识点精要整理文档,聚焦考试高频核心内容,助力考生高效梳理知识脉络、突破重点难点。文档为单个31.83MB的Word文件(.docx),结构清晰、排版规范,涵盖面向对象设计全体系:从类、对象、继承、多态、封装等基本概念,到单一职责、开闭、里氏替换等7大设计原则;从创建型、结构型、行为型三大设计模式分类,到UML类图、用例图、关系建模及树与二叉树、AVL树、排序算法、线性表等数据结构要点。目录层级分明,含详细子节编号与关键词提炼,如“UML关系(2)”“平衡二叉树”“串的存储结构”等,便于按需速查与考前冲刺。目前已有894人学习下载,是备考阶段不可或缺的结构化笔记型参考资料。
1. 软考中级软件设计师:不背UML关系图,90%的人在“继承 vs 组合”上直接丢分
软考中级软件设计师不是考你会不会写代码,而是考你能不能用标准语言把设计逻辑“说清楚、画准确、判对错”。去年真题里一道4分简答题:“请指出类图中A与B之间是泛化、关联、聚合还是组合关系,并说明判断依据”,全卷平均得分仅1.3分——不是知识点没学,是根本没练过“看图判关系”的肌肉记忆。这份Fyh软考笔记最狠的落地价值,就是把UML六类关系(泛化、实现、关联、聚合、组合、依赖)全部拆成可验证的判断条件:比如“带空心菱形+实线箭头”必须同时满足“整体销毁时部分是否必然销毁”+“是否有明确的整体-部分语义”两个硬条件,缺一不可。它专治那种“概念都懂,一做题就选错”的玄学失分。适合两类人:一是刷过两轮题但选择题正确率卡在65%上不去的;二是总在下午案例题“画类图/改用例图”环节被扣3分以上的——因为这里不考创意,只考你是否把国标《GB/T 22239—2019》里定义的图形语义刻进了本能。
2. 面向对象设计7大原则:高频考点:开闭原则与里氏替换的嵌套陷阱与答题模板
2.1 开闭原则:不是“能加新类就行”,而是“改旧代码=踩雷区”
开闭原则(OCP)在软考中从不单独出题,一定和里氏替换原则(LSP)或依赖倒置原则(DIP)捆绑出现。典型场景:题干给出一段使用继承的代码,要求“修改以符合开闭原则”。很多考生直接加个子类就交卷,结果零分。为什么?因为OCP的核心约束是对修改关闭——你新加的子类如果导致父类方法签名变更、或迫使原有调用方修改逻辑,就违反了OCP。正确解法必须满足两个动作:① 抽离可变行为为抽象接口(如PaymentStrategy);② 新增实现类(如AlipayStrategy)且不改动任何已有类的源码。真题示例:
某支付模块原只有
CashPayment类,现需支持微信支付。现有代码中OrderService.process()直接newCashPayment()。请重构以符合开闭原则。
标准答题结构:
- 指问题:当前
OrderService硬编码CashPayment,新增支付方式需修改process()方法,违反“对修改关闭”; - 给方案:定义
PaymentInterface接口,CashPayment和WechatPayment均实现该接口;OrderService依赖该接口,通过构造函数注入具体策略; - 证闭环:后续增加
ApplePayStrategy只需新增实现类,OrderService和CashPayment代码零修改。
提示:所有涉及“新增功能不改旧代码”的题,答案里必须出现“接口/抽象类”“依赖注入”“运行时多态”三个关键词,缺一不可。
2.2 里氏替换原则:考试最爱挖坑的“看似合理实则违法”场景
LSP常与OCP形成连环套题。关键陷阱在于:子类重写父类方法时,不能加强前置条件,也不能削弱后置条件。真题高频错误选项举例:
- 错误:“
Bird.fly()抛出UnsupportedOperationException,Eagle重写后正常飞行” → 违反LSP(父类承诺可飞,子类却可能崩); - 正确:“
Shape.area()返回double,Circle.area()返回精确值,Square.area()也返回精确值” → 符合(后置条件未削弱)。
面试官最想听的是你能否识别“契约破坏”。答题时必须引用LSP原文:“子类型必须能够替换掉它们的父类型”,然后紧扣方法契约分析:输入范围是否收窄?输出精度是否降低?异常类型是否增多?
2.3 依赖倒置原则:别再说“面向接口编程”,要说出“谁依赖谁、为什么不能反过来”
DIP在下午案例题中必考,但90%考生答成空话。正确答案必须包含三层:
①现状问题:高层模块(如ReportGenerator)直接依赖低层模块(如MySQLConnection),导致换数据库需改所有业务类;
②改造动作:定义DBConnectionInterface,MySQLConnection和PostgreSQLConnection实现它;ReportGenerator只依赖该接口;
③验证依据:符合DIP“抽象不应依赖细节,细节应依赖抽象”,且使ReportGenerator可测试(可用Mock实现)。
注意:若题干出现“Spring框架”“IOC容器”,答案中必须点明“通过配置文件或注解声明依赖关系,运行时由容器注入具体实现”。
3. UML关系辨析:高频考点:聚合与组合的生死线判断法
3.1 聚合 vs 组合:考试只认两个铁律,不看UML图例美观度
UML中空心菱形(聚合)和实心菱形(组合)的区别,绝非“看起来更紧密就是组合”。软考真题严格按国家标准《GB/T 22239—2019》执行,只认两个客观判据:
- 生命周期绑定:组合关系中,整体销毁时部分必须销毁(如
Car销毁→Engine必须销毁);聚合关系中,部分可独立存在(如Department销毁→Employee可转去其他部门); - 语义强弱:组合强调“强拥有”(
House与Room),聚合强调“弱拥有”(University与Professor)。
真题示例:
类图中
Order与OrderItem间为实心菱形连线。问:是否为组合关系?说明理由。
满分答案:
是组合关系。理由:①OrderItem的生命周期完全依附于Order,当Order被删除时,其所有OrderItem必须同步删除;② 业务语义上,OrderItem不能脱离Order独立存在(无订单的订单项无意义),符合组合的“强拥有”定义。
3.2 关联与依赖:箭头方向决定一切,但必须结合代码证据
关联(实线)与依赖(虚线+箭头)的区分,关键看耦合深度:
- 关联:类A持有类B的实例变量(
class A { private B b; }),二者长期存在; - 依赖:类A仅在某个方法中使用类B(
void method() { B b = new B(); }),临时借用。
易错点:看到“A.method(B b)”就判依赖——错!若该方法是构造函数参数且赋值给成员变量,则属关联。必须看变量是否成为类的状态一部分。
3.3 易错题:UML关系四大失分点(必须死记)
以下四类题,近3年真题错误率超75%,务必对照自查:
| 错在哪 | 为什么错 | 怎么答对 |
|---|---|---|
| 把“继承”画成“依赖” | 仅因子类用了父类方法,就误判为依赖;忽略继承的本质是“is-a”语义 | 看类名:Dog继承Animal是泛化;Report调用Logger.log()是依赖。UML中泛化必须用空心三角箭头,且箭头指向父类 |
| 混淆“聚合”与“关联” | 认为“有整体-部分就是聚合”,忽略聚合必须可分离(如Car与Wheel可拆卸) | 查生命周期:若部分可被多个整体共享(Teacher可教多个Class),则是关联;若部分只能属于一个整体且可分离,才是聚合 |
| 将“实现接口”画成“依赖” | 接口是契约,实现类必须100%满足,比依赖强得多 | UML中实现必须用虚线+空心三角箭头,且箭头指向接口(与泛化方向相反) |
| 忽略“多重性”标注 | 题干明确“一个订单对应多个商品”,类图中却未标1..*,直接扣2分 | 所有涉及数量关系的题,答案中必须写出具体多重性(如0..1、1..*、*),并说明业务含义 |
提示:所有UML关系题,答案必须包含“图形符号+文字标注+业务语义”三要素,缺一不可。
4. 数据结构与算法:高频考点:平衡二叉树AVL的旋转操作与时间复杂度陷阱
4.1 AVL树插入后的四种旋转:不是背口诀,而是画“失衡节点三兄弟”
AVL树旋转是软考必考计算题,但考生常因记混LL/LR/RL/RR而翻车。血泪经验:放弃口诀,直接画失衡节点及其左右子树的高度差分布。核心逻辑:
- 失衡发生在某节点N,其左子树高度 - 右子树高度 = 2 或 -2;
- 若N左子树更高(差为2),看N的左子节点L:
- 若L的左子树更高 → LL型 → 右旋N;
- 若L的右子树更高 → LR型 → 先左旋L,再右旋N;
- 右子树更高同理。
真题示例:
初始AVL树为
[10,5,15,3,7],插入2后,请画出调整后的树,并说明旋转类型。
解题步骤:
- 插入
2后,路径10→5→3→2,节点3失衡(左高2); 3的左子节点2无右子树 → 属LL型;- 对
3右旋:2升为根,3变2右子,2原右子(空)挂3左; - 更新高度,验证平衡。
4.2 二分查找的边界陷阱:考试只考“while (left <= right)”的致命细节
二分查找代码题必考边界处理。真题常给一段有bug的代码,要求指出错误并修正。高频错误:
- 错误1:
while (left < right)→ 漏掉单元素数组(left==right时退出); - 错误2:
mid = (left + right) / 2→ 整数溢出(Java/C++中left+right可能超int); - 错误3:
left = mid或right = mid→ 无限循环(因mid可能等于left/right)。
标准答案模板:
public int binarySearch(int[] arr, int target) { int left = 0, right = arr.length - 1; // 边界:right必须是length-1 while (left <= right) { // 必须<=,覆盖单元素 int mid = left + (right - left) / 2; // 防溢出 if (arr[mid] == target) return mid; else if (arr[mid] < target) left = mid + 1; // +1避免死循环 else right = mid - 1; // -1避免死循环 } return -1; }注意:所有二分题答案中,必须强调“
left = mid + 1”和“right = mid - 1”的+1/-1动作,这是防死循环的铁律。
4.3 排序算法对比表:考试只认“最好/最坏/平均时间+稳定性+原地性”
软考排序题从不考代码,只考特性对比。必须掌握下表核心参数(近5年真题100%覆盖):
| 算法 | 最好时间 | 最坏时间 | 平均时间 | 稳定性 | 原地排序 | 适用场景 |
|---|---|---|---|---|---|---|
| 冒泡 | O(n) | O(n²) | O(n²) | 稳定 | 是 | 小数据、教学演示 |
| 快速 | O(n log n) | O(n²) | O(n log n) | 不稳定 | 是 | 大数据、内存充足 |
| 归并 | O(n log n) | O(n log n) | O(n log n) | 稳定 | 否(需O(n)空间) | 大数据、需稳定 |
| 堆排 | O(n log n) | O(n log n) | O(n log n) | 不稳定 | 是 | 内存受限、实时系统 |
| 直接插入 | O(n) | O(n²) | O(n²) | 稳定 | 是 | 小数据、基本有序 |
提示:若题干出现“外部排序”“磁盘IO”,答案必须点明“归并排序可扩展为多路归并,减少IO次数”。
5. 软件工程模型与测试:高频考点:V模型与螺旋模型的本质差异与适用场景
5.1 V模型:不是“测试阶段在开发后”,而是“每个开发阶段有唯一对应测试阶段”
V模型常被误解为“瀑布模型+测试”,实则其灵魂在于双向映射:需求分析→验收测试,概要设计→系统测试,详细设计→集成测试,编码→单元测试。真题陷阱:给出一个“先编码再写设计文档”的流程,问是否符合V模型——答案必为否,因V模型强制设计文档在编码前完成,且每份设计文档必须有对应测试用例。
答题关键句:
“V模型要求测试活动与开发活动严格并行定义:概要设计文档必须包含系统测试方案,详细设计文档必须包含集成测试用例,编码完成前单元测试脚本已编写完毕。”
5.2 螺旋模型:考试只考“风险驱动”和“迭代次数”,不考图形
螺旋模型在软考中唯一考点是:每次迭代必须包含四个象限——制定计划、风险分析、开发实施、客户评估。真题常给一个项目背景(如“开发航天器控制软件,安全风险极高”),问为何选用螺旋模型。满分答案必须含两点:
① “可针对高风险环节(如实时性验证)在早期迭代中专项分析,避免后期返工”;
② “客户每轮评估后可调整需求,适应需求不确定性高的场景”。
注意:若题干出现“CMMI”“过程改进”,答案中必须关联“螺旋模型天然支持CMMI的持续改进思想”。
5.3 McCabe圈复杂度:计算公式必须带括号,否则扣分
McCabe复杂度(V(G))计算是送分题,但格式错误直接丢分。公式必须写为:
V(G) = E - N + 2P
其中E为边数,N为节点数,P为连通分量数(通常为1)。
真题示例:给出一个含3个if、1个while的流程图,要求计算V(G)。
标准步骤:
- 数判定节点数(if/while/for等):3+1=4;
- 套公式:V(G) = 判定节点数 + 1 = 4 + 1 = 5;
- 或画控制流图:E=12, N=8, P=1 → V(G)=12-8+2=6(需按图计算,此处仅为示意)。
提示:所有计算题答案必须写出完整公式及代入过程,只写结果不得分。
5.4 易错题:软件测试四大失分点(阅卷人一眼扫出)
| 错在哪 | 为什么错 | 怎么答对 |
|---|---|---|
| 混淆“黑盒”与“白盒”测试目标 | 认为黑盒测内部逻辑,白盒测功能 → 完全颠倒 | 黑盒:基于需求规格说明书,验证功能是否符合用户预期;白盒:基于代码结构,验证路径/分支/条件覆盖 |
| 误判“单元测试”执行者 | 写“由测试工程师执行” → 错!单元测试必须由开发人员编写并执行 | 标准答案:“单元测试由开发人员在编码完成后立即执行,测试对象是单个函数或类” |
| 忽略“回归测试”触发条件 | 只写“修改代码后”,漏掉“环境变更”“数据变更”等场景 | 必须列出三类触发条件:① 功能修改;② 缺陷修复;③ 运行环境或配置变更 |
| 将“α测试”等同于“用户验收测试” | α测试是开发方组织的内部用户测试,UAT是客户主导的正式验收 | 答案中必须强调“α测试在开发场所进行,UAT在客户现场进行” |
6. 答题技巧:从“写满”到“踩点得分”的三步压缩法
软考中级下午题是典型的“踩点给分”,而非“写得越多越好”。我带过的学员里,最惨的是写了两页纸却只得3分——因为全在描述背景,没命中任何一个得分关键词。后来我逼自己总结出“三步压缩法”,现在每次模拟考前都强制走一遍:
6.1 第一步:题干关键词提取(15秒内完成)
拿到题先划三类词:
- 主体词:如“UML类图”“AVL树”“V模型”——锁定考点模块;
- 动作词:如“指出”“说明”“计算”“画出”——决定答题形式(文字/公式/图形);
- 限定词:如“必须”“不得”“至少”“简述”——框定答案长度和深度。
例如题干:“请指出类图中A与B的关系,并说明判断依据(不超过100字)”,立刻知道:① 答案必须是“组合”这类名词;② 依据必须含“生命周期”和“语义”;③ 超过100字直接扣分。
6.2 第二步:得分点预埋(30秒内列提纲)
根据历年真题统计,每道4分题平均有3个得分点。以“解释开闭原则”为例:
- 得分点1:定义(对修改关闭,对扩展开放);
- 得分点2:违反后果(修改旧代码引发连锁错误);
- 得分点3:实现手段(抽象接口+多态注入)。
强迫自己用铅笔在草稿纸写“1.定义 2.后果 3.手段”,确保三点不遗漏。曾有个学员漏写“后果”,明明方案全对,只拿2分。
6.3 第三步:答案压缩(严格计时)
所有文字题答案必须控制在题干要求字数的90%以内。我的压缩口诀:
- 删连接词:去掉“因此”“所以”“由此可见”;
- 缩术语:用“OCP”代替“开闭原则”,但首次出现必须写全称;
- 去举例:除非题干要求“举例说明”,否则例子一律删。
真题验证:某年“简述敏捷开发特征”,标准答案68字,我学员写120字,因含两个冗余例子,被扣1分。
从那以后我每次模考,都强制自己用手机秒表计时:15秒划词、30秒列点、剩余时间写答案。哪怕最后5秒没写完,也停笔——因为多写的字大概率是废话。希望帮到你。
本文还有配套的精品资源,点击获取