软考中级 软件设计师 上午考试内容笔记(个人向)Part.2
软考上午考试内容
4. 法律法规与标准化知识
-
知识产权
- 即“智慧财产权”,可简单分为:工业产权 和 著作权;
- 设计的法律法规包含:
- 著作权法;
- 计算机软件保护条例;
- 商标法;
- 专利法;
其中,对保护期限、知识产权人确定和侵权判断考得比较多;
-
- 公民作品:使用权和报获得报酬权是作者终身及死后50年;
- 单位作品:使用权和报获得报酬权是首次发表后50年;
- 公民软件产品:获益和传播权利是作者终身及死后50年;
- 单位软件产品:获益和传播权利是首次发表后50年;
- 注册商标:有效期10年,期满后6个月内必须续注,注册人死亡或者倒闭1年后未转移即可注销;
- 发明专利权:自申请日后20年;
- 实用新型和外观设计专利:自申请日后10年;
商业秘密:不确定保护期限,不过一旦公开公众即可使用;
- 对于单位知识产权人的认定:
- 作品
- 利用单位条件创作的,并由单位承担责任:除署名权外一切归单位;
- 有合同约定,著作权归单位的:除署名权外一切归单位;
- 其他情况:作者享有著作权,单位有权在业务范围内优先使用;
- 软件
- 本职工作内明确规定开发的:单位享有著作权;
- 从事本职工作活动产生的结果:单位享有著作权;
- 利用单位条件开发,并由单位承担责任的:单位享有著作权;
- 其他情况:作者享有著作权,单位有权在业务范围内优先使用;
- 专利权
- 本职工作内作出的发明创造:单位享有专利权;
- 履行本单位交付的本职工作以外的任务而作出的发明创造:单位享有著作权;
- 离职、退休、工作调动后1年内,理论上与原单位工作有关的:单位享有著作权;
- 其他情况:作者享有著作权,单位有权在业务范围内优先使用;
- 作品软件
- 委托创作
- 有合同约定,著作权归委托方的:著作权归委托方;
- 合同中未约定著作权归属的:著作权归创作方;
- 合作开发
- 只进行组织、提供咨询意见、物质条件或者其他辅助工作的:著作权归创作方;
- 共同创作的:著作权共同享有,按照人头比例分配,成果可分割的,可分开申请;
- 委托创作
- 商标
- 原则上谁先申请谁拥有;
- 同时申请的,需要提供证据,根据谁先使用决定谁拥有该权利;
- 无法提供证据的,协商归属,甚至协商无效时可以使用抽签的方式,但必须要把权利的归属确定下来;
- 专利
- 基本和上边一致,且不允许同时驳回双方的专利申请;
- 作品
-
侵权判定
- 《著作权法》规定: 中国公民、法人或者其他组织的作品,不论是否发表,都享有著作权。 中国公民、法人或者其他组织的作品,不论是否发表,都享有著作权。 中国公民、法人或者其他组织的作品,不论是否发表,都享有著作权。
- 但是比较奇葩的是,开发软件所用的思想、处理过程、操作方法或者数字概念不受保护;
- 著作权法不适用的情形:
- 法律、法规;
- 国家机关的决议、决定、命令和其他具有立法、司法、行政性质的文件以及其官方正式译文;
- 时事新闻;
- 历法、通用数表、通用表格和公式;
- ……
- 尤其注意,不管什么情况,修改和保证作品原状的权利都在创作者手中,所以未经他人允许,歪曲和篡改他人作品的,都属于侵权;
-
标准化
- 国际标准
- ISO(
国际标准化组织
)、IEC(国际电气委员会
);
- ISO(
- 国家标准
GB
:中国标准;ANSI
:美国标准;JIS
:日本标准;
- 区域标准
CEN
:欧洲标准(欧盟
);
- 行业标准
GJB
:中国军用标准;IEEE
:美国IEEE标准;MIT-S
:美国军用标准;
- 地区标准;
- 企业标准;
- 项目标准;
- 国际标准
-
标准的编号
- 国外、国际标准代号:标准代号 + 专业类号 + 顺序号 + 年代号;
- 国内:
- 强制性标准代号为GB;
- 推荐行标准代号为GB/T;
- 指导性标准代号为GB/Z;
- 实物标准代号为GSB;
- 行业标准代号:汉字拼音大写字母构成;
- 地区标准代号:DB加上省级行政区划代码的前两位
- 企业标准代号:Q加企业代号;
5. 程序设计
-
编译 & 解释;
- 编译步骤:
- 词法分析:检查关键字、标识符是否出错;
- 语法分析:对源程序的结构进行分析(
表达式、语句、程序
); - 语义分析:进行类型分析和检查,保证生成正确的目标代码;
- 中间代码生成;
- 代码优化:在转化成目标代码前的变更,目的是使目标代码更为高效;
- 目标代码的生成(中间代码 → \rightarrow →绝对指令代码/可重定向指令代码/汇编指令代码);
- 文法
- 一个形式文法是一个有序的四元组
G
=
(
V
,
T
,
S
,
P
)
G = (V,T,S,P)
G=(V,T,S,P) ,其中:
- V V V 是一个非终结符集合,其中 V ≠ ∅ V \neq \emptyset V=∅,可理解为占位符;
- T T T 是一个终结符集合,其中 T ≠ ∅ T \neq \emptyset T=∅,是语言的组成部分,是最终结果;
- S S S 是一个起始符,且 S ∈ V S \in V S∈V,是语言的开始符号;
- P P P 是一个产生式集合,其中 P ≠ ∅ P \neq \emptyset P=∅,且 P P P 的每个产生式都是 V ∪ T ∪ S → V ∪ T ∪ S V \cup T \cup S \rightarrow V \cup T \cup S V∪T∪S→V∪T∪S 的形式,即用终结符替代非终结符的规则;
- 文法的分级: 短语文法( 0 型) → 上下文有关文法( 1 型) → 上下文无关文法( 2 型) → 正规文法( 3 型) 短语文法(0型)\rightarrow上下文有关文法(1型)\rightarrow上下文无关文法(2型)\rightarrow正规文法(3型) 短语文法(0型)→上下文有关文法(1型)→上下文无关文法(2型)→正规文法(3型)
- 【重点】:文法-语法推导树
- 对于
G
=
(
V
,
T
,
S
,
P
)
G = (V,T,S,P)
G=(V,T,S,P)来说,一颗语法树应具有以下特征:
- 每个节点都有一个标记,标记属于V;
- 根节点的标识是S;
- 若一个节点至少有一个子孙节点,并且自身标记为A,则A肯定属于V;
- 构造方法:
观察可供选择的选项,先确定第一个终止符,接着确定第二个,从左到右以此类推,最后转换出要求的终止符串;
- 对于
G
=
(
V
,
T
,
S
,
P
)
G = (V,T,S,P)
G=(V,T,S,P)来说,一颗语法树应具有以下特征:
- 【重点】:有限自动机
- 在状态转换图中:
- 双圆代表终点;
- D F A = ( { S , A , B , C , f } , { 1 , 0 } , δ , S , { f } ) DFA = (\{S,A,B,C,f\},\{1,0\},\delta,S,\{f\}) DFA=({S,A,B,C,f},{1,0},δ,S,{f}) ,其中最前面的集合是图中出现的节点集合,第二个集合是选择路径的条件集合,第三个字母是执行的规则,S代表起始状态,f代表终止状态;
- δ ( S , 1 ) = A \delta(S,1) = A δ(S,1)=A 代表从S出发的根据条件"1"指向A的线条;
- 在正规式中:
- 形如
(
a
∣
b
)
∗
(a|b)^*
(a∣b)∗的式子,其中
*
代表从0开始到 ∞ \infin ∞,而 a ∣ b a|b a∣b代表一直到无穷的字符串可以取a也可以取b,综上所述, ( a ∣ b ) ∗ = { t 1 t 2 . . . ∣ t i ∈ { a , b } , i ∈ [ 0 , + ∞ ) } (a|b)^* = \{t_1t_2... | t_i \in \{a,b\} ,i \in [0,+\infin)\} (a∣b)∗={t1t2...∣ti∈{a,b},i∈[0,+∞)} - 同理,对于 ( a b ) ∗ ( b a ) ∗ (ab)^*(ba)^* (ab)∗(ba)∗来说,则是 { t 1 t 2 . . . t i t i + 1 . . . t j ∣ t i = a b , t j = b a , i , j ∈ [ 0 , + ∞ ) } \{t_1t_2...t_it_{i+1}...t_j | t_i = ab ,t_j = ba, i,j \in [0,+\infin)\} {t1t2...titi+1...tj∣ti=ab,tj=ba,i,j∈[0,+∞)}
- 形如
(
a
∣
b
)
∗
(a|b)^*
(a∣b)∗的式子,其中
- 在状态转换图中:
- 表达式(
配合二叉树使用
):表示前缀、后缀、中缀表达式,具体方法是:- ( + a b ) (+ab) (+ab):根左右,前缀;
- ( a + b ) (a+b) (a+b):左根右,中缀;
- ( a b + ) (ab+) (ab+):左右根,后缀;
在做题目的时候,没说的话默认中缀表达式;
- 一个形式文法是一个有序的四元组
G
=
(
V
,
T
,
S
,
P
)
G = (V,T,S,P)
G=(V,T,S,P) ,其中:
- 编译步骤:
-
传值和传址(
引用
)- 传值:形参取实参的数值,形参的改变不影响实参的值发生改变;
- 传址:形参取实参的地址,形参的改变会改变实参的值;
6. 软件工程基础知识
-
软件生成周期
-
软件能力成熟度模型(
CMM
)- 从成熟度低到高,可以分成5个级别:
初始级(无序)、可重复级(“工业化”)、已定义级(文档化,标准化)、已管理级(定量控制)、优化级(改进优化) 初始级(无序)、可重复级(“工业化”)、已定义级(文档化,标准化)、已管理级(定量控制)、优化级(改进优化) 初始级(无序)、可重复级(“工业化”)、已定义级(文档化,标准化)、已管理级(定量控制)、优化级(改进优化) - 在
CMM
基础上,发展出了CMMI
。其在CMM
的基础上,更新了解释:- 阶梯型模型 初始的(过程不可预测 / 缺乏控制)、已管理的(过程为项目服务)、已定义的(过程为组织服务)、定量管理的(过程度量控制)优化的(于过程中改进) 初始的(过程不可预测/缺乏控制)、已管理的(过程为项目服务)、已定义的(过程为组织服务)、定量管理的(过程度量控制)优化的(于过程中改进) 初始的(过程不可预测/缺乏控制)、已管理的(过程为项目服务)、已定义的(过程为组织服务)、定量管理的(过程度量控制)优化的(于过程中改进)
- 连续性模型
- 更关注每个过程域的能力,
CL
代表Capability Level
; -
- CL0(不完整级):过程域的一个或多个目标没有被满足,过程执行不完整或不一致。
- CL1(已执行级):过程通过转换可识别的输入工作产品,产生可识别的输出工作产品,实现了过程域的特定目标。
- CL2(已管理级):过程作为已管理的过程被制度化,有计划、监控和控制。
- CL3(已定义级):过程作为已定义的过程被制度化,遵循组织的标准过程,并且有过程资产和度量。
- CL4(量化管理级):过程作为量化管理的过程被制度化,使用统计和定量技术来控制和改进过程。
- CL5(优化级):过程作为优化的过程被制度化,专注于持续改进过程性能,使用量化反馈和创新。
- 更关注每个过程域的能力,
- 从成熟度低到高,可以分成5个级别:
-
统一过程(
UP
)模型-
统一过程模型(
UPM
)是CMM
的改进版本; -
主张:用例和风险驱动,以架构为中心,迭代并且增量;
-
其核心概念是:
-
【迭代开发】:软件开发被分为多个迭代周期,每个迭代周期都会产生一个可执行的、测试的软件版本。每个迭代都是在前一个迭代的基础上进行改进和扩展。
-
【增量交付】:在每个迭代周期中,开发团队会集中精力完成软件的一部分功能,这些功能被设计为可以独立交付的增量。随着迭代的进行,软件的功能逐渐完善(
渐进式部署 + 灰度测试
)。 -
【角色分配】:统一过程定义了一系列角色,每个角色都有特定的职责和活动。这些角色包括业务分析师、软件架构师、程序员、测试人员等。
-
【工件产出】:在软件开发过程中,会产生一系列的工件,如需求文档、设计文档、代码、测试用例等。这些工件是软件开发过程中的重要产出。
-
【纪律性】:统一过程强调纪律性,即遵循一定的规则和流程来管理软件开发过程,以确保软件质量和开发效率;
-
-
由UML方法和工具支持;
-
其一般包括四个阶段:
-
初始阶段(
Inception
):在这个阶段,确定项目的范围、目标和愿景,识别关键的业务需求,评估项目的可行性,并制定初步的项目计划。 -
细化阶段(
Elaboration
):在这个阶段,进一步细化需求,设计软件的架构,制定更详细的开发计划,并开始开发软件的核心功能。 -
构建阶段(
Construction
):这是软件开发的主要阶段,开发团队集中精力编写代码,进行单元测试,集成各个模块,并进行系统测试。 -
移交阶段(
Transition
):在这个阶段,软件准备交付给用户。进行最终的测试,确保软件满足所有需求,然后部署到生产环境中。
-
-
6.1 软件开发模型
- 瀑布模型(
Waterfall
)
- 演化模型(
Evolutionary
)- 将开发过程分为多个迭代周期,每个周期都会产生一个可工作的软件版本。每个迭代都会增加新功能或改进现有功能;
- 将开发过程分为多个迭代周期,每个周期都会产生一个可工作的软件版本。每个迭代都会增加新功能或改进现有功能;
- 增量模型(
Incremental
)- 融合了瀑布模型和原型,该模型采用随日程时间的进展而交错的线性序列,每一个线性序列产生软件的一个可发布的“增量”;
- 最大的特点是引进了增量包的概念(
OTA
);
- 螺旋模型(
Spiral
)- 增加了风险分析;
- 喷泉模型 (
Fountain
)- 主要面向对象开发,具有迭代和无间隙特性;
- 以用户需求为动力,以对象为驱动;
- 基于构件的开发模型
- 本质还是演化模型,只是以迭代方式构建软件时,采用预先打包的软件开发应用系统;
6.2 结构化方法
重中之重是:数据流图;
- 由结构化分析、结构化设计、结构化程序设计/结构化实现构成;
- 是一种面向数据流开发的方法;
- 总的指导思想是:自上而下,逐层分解;
- 其基本原则是功能的分解与抽象;
- 结构化分析的原理是分解与抽象;
6.2.1 系统设计原理
系统设计基本原理
- 抽象;
- 模块化;
- 信息隐蔽(
封装
);- 模块独立(
高内聚、低耦合
)耦合指模块间的联系紧密程度,耦合程度越高,模块间的独立性就越差;内聚是指模块内部各元素之间联系的紧密程度,内聚程度越低,则模块的独立性越差;
-
耦合分类
耦合类型 描述 非直接耦合 两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的 数据耦合 一组模块借助参数表传递简单数据 标记耦合 一组模块通过参数表传递记录信息(数据结构) 控制耦合 模块之间传递的信息中包含用于控制模块内部逻辑的信息 外部耦合 一组模块都访问同一全局简单变量,而且不是通过参数表传递该全局变量的信息 公共耦合 多个模块都访问同一个公共数据环境 内容耦合 一个模块直接访问另一个模块的内部数据;一个模块不通过正常入口转到另一个模块的内部;两个模块有一部分程序代码重叠;一个模块有多个入口 -
内聚分类
内聚类型 描述 功能内聚 完成一个单一功能,各个部分协同工作,缺一不可 顺序内聚 处理元素相关,而且必须顺序执行 通信内聚 所有处理元素集中在一个数据结构的区域上 过程内聚 处理元素相关,而且必须按特定的次序执行 瞬时内聚(时间内聚) 所包含的任务必须在同一时间间隔内执行 逻辑内聚 完成逻辑上相关的一组任务 偶然内聚(巧合内聚) 完成一组没有关系或松散关系的任务 -
模块是组成系统的基本单位,它的特点是可以组合、分解和更改。系统中任何一个处理功能都可以看成一个模块。根据模块功能具体化程度的不同,可以分为:【逻辑模块】和【物理模块】;
-
一个模块要具有以下4个要素:
- 输出和输入;
- 处理功能;
- 内部数据;
- 程序代码;
6.2.2 数据流图
- 又称数据流程图,是一种便于用户理解,分析系统数据流程的图形工具;
- 精确地在逻辑上描述了系统的功能、输入、输出和数据存储;
- 数据字典
-
数据流图描述了系统的分解,但没有对图中各成分进行说明。作为补充,数据字典对数据流图中的微末部分做出了说明;
-
数据字典有4类条目:
- 数据流条目;
- 数据存储条目;
- 加工条目;
- 数据项条目;
字典管理主要是指把字典条目按照某种格式组织后存储在字典中,并允许进行CRUD;
-
符号 含义 举例说明 = 被定义为 + 与 x=a+b,表示x由a和b组成 [ , ] 或 [ | ] 或 x=[a, b],x=[a {…} 重复 x={a},表示x由0个或多个a组成 (…) 可选 x=(a),表示a可在x中出现,也可以不出现 -
元素 说明 图元 数据流 由一组固定成分的数据组成,表示数据的流向。每个数据流通常有一个合适的名词,反映数据流的含义 箭头 加工 加工描述了输入数据流到输出数据流之间的变换,也就是输入数据流做了什么处理后变成了输出数据流 圆角矩形、圆形 数据存储 (文件) 用来表示暂时存储的数据,每个文件都有名字。流向文件的数据流表示写文件,流出的表示读文 件 右开口长方形 外部实体 指存在于软件系统外的人员或组织 长方形
-
- 数据流图的分层
- 从上到下,分别是顶层图、零层图、一层图、……,每一层都存在和外部实体之间的交互(
做题的关键
); - 若分层数据流图中的某张图的某个加工可以由另一张图来进行分解,则称前者为父图,后者为子图,且每张子图只能对应一张父图;
- 从上到下,分别是顶层图、零层图、一层图、……,每一层都存在和外部实体之间的交互(
- 数据流图的编号
- 顶层图和零层图都只有一张,前者不用编号,后者的加工需要编号;
- 子图号就是父图中被分解的加工号;
- 画数据流图的注意事项:
- 画数据流而不是画控制流;
- 输出数据流的名称不与输入数据流相同;
- 允许一条加工有多条数据流向另一个加工,也允许一个加工有两条相同的输出数据流流向两个不同的加工;
- 保持父图和子图的平衡,保持子图内的平衡(
用来解题找缺失的数据流效果非常好
); - 保持数据守恒;
- 每次加工都必须既有输入数据流也有输出数据流;
- 在整个数据流图中,对于每个数据存储(
临时存储
),都必须既有读数据流也有写数据流,但在某张具体的子图中,可以只有读或者只有写;
6.3 Jackson方法
- 面向数据结构,数据结构驱动,由输出/输入数据结构分析其对应性,推导出相应的程序结构,从而给出具体实现的软件描述;
- 特别适用于输入输出结构明确的中小型系统;
- 主要将软件的开发过程分成两种:
- 结构化分析;
- 结构化设计;
- 具体实现方式如下:
- 分析并确定输入数据和输出数据的逻辑结构,并用Jackson图来表示这些数据结构。
- 找出输入数据结构和输出数据结构中有对应关系的数据单元。
- 从描绘数据结构的Jackson图导出描绘程序结构的Jackson图。
- 为每对有对应关系的数据单元,按照它们在数据结构图中的层次在程序结构图的相应层次画一个处理框。
- 根据输入数据结构中剩余的每个数据单元所处的层次,在程序结构图的相应层次分别为它们画上对应的处理框。
- 列出所有操作和条件(包括分支条件和循环结束条件),并且把它们分配到程序结构图的适当位置。
- 用伪码表示程序。Jackson方法中使用的伪码和Jackson图是完全对应的。
6.4 原型化方法
- 走一步看一步;
6.5 面向对象开发方法
- 包含:面向对象分析、面向对象设计、面向对象实现;
- 面向对象的标准语言是UML(
Uniform Modeling Language,统一建模语言
)【这是极为重要的考点】;
6.5.1 UML建模
- “UML”全称为:Unified Modeling Language,统一建模语言;
- 有四种关系:
- 【依赖】:一个事物的发生会影响到另一个事物,另一个事物就对原事物产生依赖;
- 【关联】:描述了对象之间的联系即关系链。它一般体现在两种:
- 聚合:整体与部分间的结构关系;
- 组合:整体与部分之间的关系,比聚合更强,又叫强聚合(
添加了结构以外的关系
);
- 【泛化】:在我看来是一种继承或者说迭代,即特殊寓于一般之中。子元素的对象可以取代父元素的对象。用这种方法,事实上说,子元素继承或者说共享了父元素的结构和行为;
- 【实现】:是类元之间的语义关系,一个类元制定了另一个类元保证执行的契约。其常见于两种情况:
- 接口与实现接口的类/构件之间;
- 在用例和实现他们的协作之间(
具体类与抽象类
);
- 使用UML主要考查各种视图 ,常见的有结构视图和动态视图两种。再细分的话有类图、用例、状态图、构件图、活动图、顺序图;
6.5.1.1 类图
- 主要考察三个方面:
- 填类名、方法名、属性名;
- 填多重度;
- 填类间关系;
分成几部分依次叙述:
- 类、方法、属性
- 使用形如
- 使用形如
- 多重度
-
1
1
1 :一个集合中的一个对象对应另一个集合中一个对象(
例如一本书对应一个借书人
); -
0..
∗
0..*
0..∗ :一个集合的一个对象对应一个集合的0个或者多个对象(
例如一个借书人可能借了很多本书也可能没借书
); - 1.. ∗ 1..* 1..∗ :一个集合的对象对应一个集合的1个或者多个对象;
- ∗ * ∗ :一个集合中的一个对象对应另一个集合中的多个对象;
值得注意的是,这种多重度关系是相互的,即
你对她纯爱,她对你海王是有可能的
; -
1
1
1 :一个集合中的一个对象对应另一个集合中一个对象(
- 填写关系【背】
- 综合来看,A → \rightarrow → B,即A实现了B,B是A抽象的体现;
6.5.1.2 用例图
- 展示了一组用例、参与者(
一般画成小人
)以及两者之间的关系; - 通常包含用例、参与者、扩展关系(
<<include>>
)、包含关系(<<extend>>
); - 两个事务的实现是并联的,填
<<extend>>
;是串联的(前者为后者提供数据来源或者条件
),填<<include>>
;
6.5.1.3 顺序图 & 协作图
- 前者强调消息时间序列的交互图,后者强调接收和发送消息的对象的结构组织;
-
- 顺序图的执行方向是从上到下;
- 主要的挖空地点是箭头上方所表示的消息传递,考试会把消息名挖掉进行混淆;
- ":xxx"代表对象,虚线是类的生命线(存活时间),箭头由前者指向后者,长条圆角矩形代表执行的事务(活动条),短的圆角矩形代表接受消息返回的事务
6.5.1.4 活动图
- 形如这种:
6.5.1.5 状态图
- 展示了一个状态机。其关注系统的动态视图,对于接口、类和协作的行为建模尤为重要;
- 强调对象行为的时间顺序;
- 形如:
6.5.1.6 通信图
- 强调收发消息,强调参加交互的组织;
- 它有几个特点:
- 有路径;
- 有顺序号;
- 将参加交互的对象作为图的顶点;
- 将连接这些对象的链(
chain
)表示为图的弧; -
- 对象间有链、消息箭头、消息内容(顺序号、方法/传值);
:xxx
表示对象xxx;
6.5.1.7 构件图
- 表示了构件之间的组织和依赖的关系;
- 专注于系统的静态实现;
-
- 提供接口:
--C
; - 构建:长方形;
- 依赖:
--
+ 名称; - 接受接口:
--O
;
- 提供接口:
6.6 敏捷开发方法
- 目的是:尽可能早地持续交付有价值的部分给客户让其满意;
- 极限编程(
XP
);
6.7 系统设计
- 采用了结构化方法的结构化设计;
- 模块独立、高内聚、低耦合和低复杂度;
6.8 系统测试
- 以下介绍相关的测试方法:
黑盒测试之所以被称之为“黑盒”,是因为对于测试人员来说,他们不了解也不需要了解软件内部的结构和代码实现,程序对他们就像是黑盒子一样,只能看到输入和输出。测试人员是从用户角度,验证软件的功能是否符合用户的需求;
白盒测试则不然。它通常由开发人员进行,需要了解软件的内部逻辑和外部信息才能进行测试,测试目的也变成验证软件内部的逻辑或者路径是否正确; - 测试阶段包括:
- 单元测试(
测试某个模块,一般使用白盒
); - 集成测试;
- 确认测试;
- 系统测试;
- 单元测试(
6.9 软件开发项目管理
-
Gantt图
- 以日历为基准,描述项目任务的进度;
- 水平条的表示:
- 首尾:开始时间和结束时间;
- 长度:持续时间;
- 同一时段同时存在多条:任务的并发;
-
PERT图
- 有向图,使用箭头表示任务,节点代表事件;
- 箭头长度代表完成任务的时长;
- 箭头指向节点代表流入节点的任务结束;
- 一个事件/节点都有一个事件号和出现该事件的最早时刻和最迟时刻,由此可以计算出一个松弛时间(
不影响整个工期的前提下,完成该任务有多少机动余地
); - 只有流入节点的所有任务都结束,节点代表的事件才会出现,流出节点的任务才可以开始;
- PERT图能够反映任务之间的关系以及决定是否如期完成整个工程的关键路径,但不能反映任务之间的并行关系;
- 如何求一个事件的最晚开始时间:
- 根据开始时间逐步确定直至找到结束事件的结束时间(
也是最早开始时间和最晚开始时间
); - 由结束事件的时间沿着路径倒推结点,直至找到要求的结点;
- 通过减去沿途的所有任务时间观察得出目标结点的最晚开始时间;
- 根据开始时间逐步确定直至找到结束事件的结束时间(
- 有向图,使用箭头表示任务,节点代表事件;
-
风险管理
-
软件质量模型
- 由三个层次构成: 质量特性、质量子特性、度量指标 质量特性、质量子特性、度量指标 质量特性、质量子特性、度量指标
- 质量特性 & 质量子特性
根据ISO 9126标准,软件质量特性可以分为六个主要类别,每个类别下又包含若干子特性。
-
功能性(Functionality):
- 适合性(Suitability):软件是否提供了满足用户需求的功能。
- 准确性(Accuracy):软件提供的功能是否正确无误。
- 互操作性(Interoperability):软件与其他系统或软件交互的能力。
- 安全性(Security):软件保护信息和数据的能力。
- 依从性(Functionality Compliance):软件是否符合相关标准和规范。
-
可靠性(Reliability):
- 成熟性(Maturity):软件防止内部错误导致失效的能力。
- 容错性(Fault Tolerance):软件在出现故障时的自我处理能力。
- 易恢复性(Recoverability):软件在失效后恢复原有功能的能力。
- 依从性(Reliability Compliance):软件是否遵循相关可靠性标准。
-
易用性(Usability):
- 易理解性(Understandability):软件信息是否清晰易懂。
- 易学性(Learnability):用户学习使用软件的难易程度。
- 易操作性(Operability):用户操作软件的便捷性。
- 吸引性(Attractiveness):软件吸引用户的能力。
- 易用性的依从性(Usability Compliance):软件是否符合易用性标准。
-
效率(Efficiency):
- 时间特性(Time Behavior):软件执行任务所需的时间。
- 资源利用性(Resource Utilization):软件运行时对资源的使用效率。
- 效率依从性(Efficiency Compliance):软件是否符合效率标准。
-
维护性(Maintainability):
- 易分析性(Analyzability):诊断和分析软件问题的难易程度。
- 易改变性(Modifiability):软件进行修改的容易程度。
- 稳定性(Stability):修改软件时不影响其他功能的难易程度。
- 易测试性(Testability):软件修改后进行测试的容易程度。
- 依从性(Maintainability Compliance):软件是否符合维护性标准。
-
可移植性(Portability):
- 适应性(Adaptability):软件适应不同环境的能力。
- 易安装性(Installability):软件安装的难易程度。
- 共存性(Co-existence):软件与其他软件共享资源的能力。
- 易替换性(Replaceability):软件被其他软件替代的容易程度。
- 依从性(Portability Compliance):软件是否符合可移植性标准。
-
6.9.1 软件度量
- 这里介绍McCabe度量法,它又叫环路度量;
- 环路度量认为程序的复杂性取决于控制的复杂性(
循环、选择造成的环路
); - 环路度量越大,程序越复杂。环路度量在强连通有向图G中,由图论可得: V ( G ) = m − n + 2 V(G) = m - n + 2 V(G)=m−n+2其中m是图中弧/边的个数,n是图中结点的个数;
6.9.2 面向对象技术
- 面向对象 = 对象 + 分类 + 继承 + 通过消息的通信 面向对象 = 对象 + 分类 + 继承 + 通过消息的通信 面向对象=对象+分类+继承+通过消息的通信
- 其中包括:
- 对象
- 运行的实体;
- 既包含属性/数据,又包含方法/行为/操作数据的函数;
- 与其说是对象,不如说是程序模板;
- 一个对象由:对象名、属性(数据)、操作(方法)组成;
- 消息
- 对象间进行通信的一种构造(
代表着一组包含特定格式的信息
); - 对象 1 → 消息 对象 2 对象1\overset{\text{消息}}\rightarrow 对象2 对象1→消息对象2,对象2对消息进行解释并予以响应,这称为消息传递;
- 发送对象的对象不需要知道接收对象如何对请求予以相应;
- 对象间进行通信的一种构造(
- 类
- 定义了一组大体上相似的对象;
- 类是在对象之上的抽象,对象是类的具体化,是类的实例;
- 继承
- 是父类和子类之间共享数据和方法的机制;
- 一个父类可以有多个子类,但一个子类只能继承自一个父类;
- 多态
- 不同对象接收到同一消息后产生不同结果,这一现象被称为多态;
- 泛化 = 多态 , 实现 = 继承;
- 简单来说是同一操作作用于不同的对象,会有不同的解释;
- 对象
6.9.2.1 设计原则
- 单一职责原则
- 要设计目的单一的类;
- 开放-封闭原则
- 对扩展开放,对修改关闭(
股权警告
);
- 对扩展开放,对修改关闭(
- 里氏替换原则(
Liskov substitution principle
)- 子类可以替换父类;
- 依赖倒置原则
- 针对接口编程,而不是针对实现编程;
- 要依赖于抽象,而不是具体实现;
- 接口隔离原则
- 宁愿使用多个专门的接口也比使用单一的总接口要好;
- 组合复用原则
- 要尽量少用继承,要尽量使用组合;
Q:什么是组合,为什么是组合?
A:组合就是在一个对象中嵌套另一个对象作为对象成员来使用。组合非常有利于代码的复用,且关系可以动态变化,一个对象中可以包含多个不同的子对象,从而实现更为复杂的组合变化。更重要的是继承使用的太多的话,对象间的耦合程度过高,代码会变得臃肿混乱,容易一处修改就使得代码陷入bug和混乱; - 迪米特原则(
Demeter Principle
)- 一个对象应当对其他对象尽可能少的“了解”;
- 也就是,不同函数之间应避免直接访问到彼此的内部信息,需要使用的时候直接调用就好了;
6.9.2.2 设计模式的概念和分类
- 只关注软件系统的设计,与具体的实现语言无关(
软考可选择c++或者java
); - 设计模式一般会有4个要素:
- 模式名称;
- 问题;
- 解决方案;
- 效果;
- 设计模式的分类(
23种
):
- 常考的有: 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者 工厂方法、抽象工厂、构建器、适配器、装饰、命令、中介者、观察者
-
- 创建型模式
- 抽象了实例化过程;
- 关注对象的创建过程,将对象的创建与使用分离,提供了了一个灵活的方式来创建对象,而无需指定具体的类;
- 结构型模式(
常考选择题
)- 描述如何组合类和对象以获得更大的结构;
- 采用继承机制来组合接口或者实现;
- 行为型模式
- 不仅描述对象或类的模式,还描述它们之间的通信模式;
- 关注对象之间的交互和职责分配、对象之间的交互方式;
-
- 行为类模式使用继承机制在类间分派行为;
-
- 行为对象模式使用对象复合
- 为什么要使用行为型模式:
1. 提高代码复用性: 通过封装变化的部分,减少重复代码;
2. 增强代码可维护性: 将复杂的逻辑拆分成更小的、可管理的单元
- 创建型模式
6.9.2.2.1 工厂方法模式(factory_method
)
- 在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型,本质是将子类的实例化给推迟了;
- 它建议使用特殊的工厂方法代替对于对象构造函数的直接调用(
如:new
),直接调用改在工厂方法中进行。这允许你在子类中重写工厂方法, 从而改变其创建产品的类型;仅当这些产品具有共同的基类或者接口时, 子类才能返回不同类型的产品, 同时基类中的工厂方法还应将其返回类型声明为这一共有接口;
- 【要素】:共同接口的创建方法,子类方法多态;
- 举例:
- 模式结构:
6.9.2.2.2 抽象工厂模式(abstract factory
)
- 是在工厂方法基础上的升级,应对的是某一类对象下的所有子类,而不是某一个子类(
某一个子类是工厂方法
); - 例如对于椅子、沙发、餐桌等家具来说,按照设计风格的不同可以分为中式、日式、维多利亚式、北欧式。现在我们想生产一些家具,但是要求每一批生产的都是一种生产风格。此时,就可以声明抽象工厂(一个包含了批次中所有产品构造方法的接口),如
F
u
r
n
i
t
u
r
e
F
a
c
t
o
r
y
{
+
c
r
e
a
t
e
C
h
a
i
r
(
)
,
+
c
r
e
a
t
e
S
o
f
a
(
)
,
+
c
r
e
a
t
e
T
a
b
l
e
(
)
}
FurnitureFactory\{+createChair(), +createSofa(), +createTable()\}
FurnitureFactory{+createChair(),+createSofa(),+createTable()},这些方法必须返回抽象的产品类(
即Chair、Sofa、Table
)。在这以后,应对不同设计风格的生产要求,可以通过接口创建特定类型的“工厂”对象,在这些“工厂”对象中对构造方法进行重写,如由FurnitureFactory
创建ChineseFurnitureFactory
来生产ChineseChair
、ChineseSofa
、ChineseTable
。 - 模式的结构:
6.9.2.2.3 构造器模式/生成器模式(builder
)
- 允许你使用相同的创建代码分步骤创建不同类型和形式的复杂对象;
- 生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。生成器能够让你能够分步骤创建复杂对象。 生成器不允许其他对象访问正在创建中的产品;
- 例如你要建造一间房子,需要建造墙壁、房门、管道、地板、天花板。这时候你有三种思路:
- 第一种是创建一个房子的基类(
BaseEntity
)储存一定的参数,并在其基础上进行实现或者泛化。但如果后来者要对房子添加一些基类中没有出现过的修改,出现了基类中没有的参数,构造函数也要变动,则需要修改基类,这样会使开发非常复杂; - 第二类是在基类中创建一个涵盖所有参数的超级构造函数,但这样会造成严重的资源浪费。大多数情况下,超级构造函数的参数都没有用,故调用起来非常复杂;
- 最后一种也就是额外创建一个构造器,将对象的构造过程拆分成一组“步骤”,如
buildWall()创建墙壁
、buildDoor()创建房门
、buildTube()创建管道
等。每次创建对象,只需要通过构造器对象选择性地调用特定的对象执行,按顺序一次性完成相应步骤即可。当创建不同形式的产品时,一些构造步骤可能需要不同的实现(参数不同
),则需要对应创建不同产品的构造器(如Builder1
和Builder2
);
- 第一种是创建一个房子的基类(
- 模式的结构:
在有需要的情况下,可以进一步将用于创建产品的一系列生成器步骤调用抽取成为单独的主管类(
Director
)。主管类可定义创建步骤的执行顺序, 而生成器则提供这些步骤的实现,或者说主管类构造了使用生成器接口的对象。事实上,对于客户端代码来说, 主管类完全隐藏了产品构造细节。 客户端只需要将一个生成器与主管类关联, 然后使用主管类来构造产品, 就能从生成器处获得构造结果了;
6.9.2.2.4 原型模式(Prototype
)
- 针对不想复制品依赖类或者只知道要复制对象的部分接口不知道全貌的情况(
即:从外部复制对象并非总是可行
); - 原型模式将克隆过程委派给被克隆的实际对象。 模式为所有支持克隆的对象声明了一个通用接口, 该接口让你能够克隆对象, 同时又无需将代码和对象所属类耦合。 通常情况下, 这样的接口中仅包含一个克隆方法。克隆方法会创建一个当前类的对象, 然后将原始对象所有的成员变量值复制到新建的类中(
你甚至可以复制私有成员变量, 因为绝大部分编程语言都允许对象访问其同类对象的私有成员变量
); - 支持克隆的对象即为原型。 当你的对象有几十个成员变量和几百种类型时, 对其进行克隆甚至可以代替子类的构造(
方法是:创建一系列不同类型的对象并不同的方式对其进行配置。 如果所需对象与预先配置的对象相同, 那么你只需克隆原型即可, 无需新建一个对象
);
事实上,这类复制与其说是克隆,不如说是有丝分裂,所有“遗传物质”(
属性、方法
)都和原型一摸一样;
- 其模式结构是:
6.9.2.2.5 单例模式(Singleton
)(问题非常多
)
- 确保【1】一个类只有一个实例, 并【2】提供一个访问该实例的全局节点。但这违反了单一职责原则;
实际上,只解决了上文描述中的其中一个的东西,都被称为单例。单例在现在非常常用;
- 实现方法:
- 在类中添加一个私有静态成员变量用于保存单例实例;
- 创建静态方法,在首次被调用时创建一个新对象, 并将其存储在静态成员变量中。 此后该方法每次被调用时都返回该实例(
延迟初始化
); - 将类的构造函数设为私有(
只有一个实例
)。 类的静态方法仍能调用构造函数, 但是其他对象不能调用; - 检查客户端代码, 将对单例的构造函数的调用替换为对其静态方法的调用;
6.9.2.2.6 适配器模式(Adapter
)
- 类似于……
- 适配器是一个特殊的对象, 能够转换对象接口, 使其能与其他对象进行交互(
调整格式、属性等
); - 模式通过封装对象将复杂的转换过程隐藏于幕后,被封装的对象甚至察觉不到适配器的存在;
- 例如:
- 模式的结构是:
6.9.2.2.7 责任链模式(Chain of Responsibility
)
- 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者;
- 详细内容见于此处;
6.9.2.2.8 命令模式(Command
)
优秀的软件设计通常会将关注点进行分离, 而这往往会导致软件的分层(
网络层、Mybatis_plus后端
);
- 将请求封装为一个对象,从而可用不同的请求对客户进行参数化,同时将请求排队或者记录请求日志,支持可撤销的操作;
- 一个 GUI 对象传递一些参数来调用一个业务逻辑对象, 这个过程通常被描述为一个对象发送请求给另一个对象。命令模式建议 GUI 对象不直接提交这些请求。 你应该将请求的所有细节 (例如调用的对象、 方法名称和参数列表) 抽取出来组成命令类, 该类中仅包含一个用于触发请求的方法。命令对象负责连接不同的 GUI 和业务逻辑对象(
类似于视图和数据库
)。 此后, GUI 对象无需了解业务逻辑对象是否获得了请求, 也无需了解其对请求进行处理的方式。 只需要GUI对象触发命令即可, 命令对象会自行处理所有细节工作。; - 让所有命令实现相同的接口。 该接口通常只有一个没有任何参数的执行方法, 让你能在不和具体命令类耦合的情况下使用同一请求发送者执行不同命令;
有一个问题,由于接口的方法不含有任何参数,当需要接受请求的参数时,需要另寻他招:使用数据对命令进行预先配置, 或者让其能够自行获取数据(
用属性或者对象接收并调用而不是传参
); - 其模式类似于:
6.9.2.2.9 观察者模式(Observer
)
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新;
6.9.2.2.10 状态模式(State
)
- 将状态变成类;
- 允许一个对象在其内部状态改变时改变它的行为;
6.9.2.2.11 策略模式(Strategy
)
- 最常见的就是:定义一系列的算法,把它们一个个封装起来,并且使他们可以相互替换。此时算法独立于使用它的用户而变化;
- 本质还是【多方案切换】这一套;
6.9.2.3 语言选择
- 建议还是使用Java,因为没有多继承,没有指针;
原文地址:https://blog.csdn.net/ozawacai/article/details/143653426
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!