首先附一张大图
将系统性的、规范化的、可定量的方法应用于软件的开发、运行与维护中,即将工程化方法应用于软件;
对上述方法进行研究;
瀑布模型
增量过程模型(需求基本不变)
增量模型
迭代运用瀑布模型
RAD(快速应用开发)
并行使用瀑布模型
演化过程模型(需求经常变动)
快速原型开发
与用户交互最多。
其原型可能会被抛弃,而增量模型的每次迭代的系统都不可被破坏
螺旋模型
是一种风险驱动过程模型。
开发时间长。
4P:People、Project、Product、Process
项目管理-4P
People
Product
需求分析
软件设计
软件实现
软件测试
软件运维
每个阶段都用对应文档
Process
Project
原则:W5HH
Why
What
Who
When
Where
How
How much
要素
如何记忆?
一个项目,首先要看你的完成进度,然后看你的工作,然后看已经投入的资源(成本),最后肯定要看项目的结果如何
项目估算-2总8小
基本估算方式
分段估算
从宏观到微观,随着项目推进,不断分段估算
参数估计
根据过往大量历史数据,预测
专家估计
专家经验预测
高级估算方式
LOC(代码行技术)
a为乐观值,b为悲观值,m为可能值(均值代码量),u为单位代码的成本,v为平均生产率,PM为总工作量(人/月)则
LOC = (a + 4m + b) / 6
C(Cost) = u * LOC
PM = LOC / v
功能点
FP=UFC×[0.65+0.01×∑Fi]
COCOMO
A工作量调整因子,Size规模,B规模调整因子
PM = A * Size ^ B
故事点
用例点
标准用例 = (基本流+扩展流+2×业务规则)/10
生产率 = 6工作日/单位用例
工作量 = 6×总标准用例
机器学习
进度安排-7步法
如何记忆?
首先,我们最终会得到一张任务图
为了得到这张任务图,我们需要得到所有任务节点,因此,首先得划分任务。
划分完任务后,我们需要构建整个任务图,因此,我们需要构建任务网络,接着,根据任务网络,我们要能够为每个任务分配时间,完了之后,接着确定资源,确定完资源后,我们需要人干活了,因此要确定责任,安排完人后,我们需要给他们指标,因此每个任务我们都应该确定结果,确定结果后,我们还应该制定一个里程碑,用以鼓舞士气。
因此,进度安排的流程便很清晰了:
划分任务
任务网络
时间分配
资源分配
责任确定
结果确定
里程碑确定
Step1:划分任务
工作分配采用40-20-40原则
40:分析和设计
20:编码
40:测试与维护
Step2:任务网络
Step3:时间分配
计算最早开始时间与结束时间
计算最晚开始时间与结束时间
计算关键路径
确定任务开始时间与结束时间
绘制甘特图
Step4:资源分配
Step5:责任确定(人员确定)
Step6:结果确定
Step7:里程碑确定
风险评估-4点
风险识别
头脑风暴、专家判断
风险评估
风险表
要素:
风险及风险类型
风险发生的概率
风险产生的后果
风险缓解策略
应对计划
风险控制
软件需求
需求定义
以一种清晰、简洁、一致且无二义性的方式,描述用户对目标软件系统在功能、行为、性能、设计约束等方面的期望, 是在开发过程中对系统的约束
需求分类
功能性需求
业务需求:即一个系统的目标
用户需求:用户对于该系统的功能需求
系统需求:根据用户需求定义系统需求
如何记忆?
首先你手中有一个业务,比方说你想成为最大的电商平台,这就是你的业务需求,为了成为最大的电商平台,你需要调研用户希望电商平台是什么样子,他们更喜欢什么样式的电商平台,这就是用户需求,综合用户需求,你明白了你要的平台应该如何设计,它应该有什么功能?这便是系统需求
非功能性需求
非功能需求
业务规则
对某些功能的可执行性或内部执行逻辑的一些限定条件。
外部接口需求
如何与外部系统进行交接,例如:
软件接口需求
硬件接口需求
通信接口需求
设计约束
限制了开发人员设计和构建系统时的选择范围。
需求工程
如何记忆?
首先要获取需求,即做一些基本的调研。其次要对需求进行分析与建模,例如一些UML图。然后要将前面的步骤做一个完整的规格说明,以便于大家理解。最后,要对需求进行验证,以便发现问题,解决问题。
需求获取
座谈会、面对面访谈、问卷、头脑风暴等
需求分析与建模
需求规格说明
需求验证
需求获取-7步法
7个步骤:
学习/了解背景知识;
与高层人士聊天,了解业务需求;
与客户或底层人士聊天,了解用户需求;
整合需求报告,继续步骤1~3;
需求分类与组织;
优先级排序与解决;
最终需求清单,与客户进行确认;
如何记忆?
主要记忆5~7点,前4点逻辑很简单。那么,我们从第5条开始。
得到了几乎没有错误的需求报告之后,我们自然应该对这些需求进行归类,这也是需求分类与组织,其次,为了决定先做什么需求、后做什么需求,我们还应该对需求的优先级进行排序,最后,我们要形成一个完整的需求清单,递交给用户确认,然后就可以开始下一个阶段了。
需求建模-3方法
基于场景的建模方法
用户故事
一个用户故事
Card
-作为一个<角色>,我希望<活动>,以便于<效益>
Conversation
-用户需求列表
Confirmation
-通过验收测试确认需求已经完成
UML用例图
用例图中除了包括用例图,每个用例还应该包含详细的用例说明,这些用例说明一般由:目标、基本事件流、拓展事件流组成。
注意点:
实心箭头代表Case继承(泛化)关系
空心箭头代表Actor继承(泛化)关系
无心箭头(->)代表通讯关联
泳道图(活动图)
注意点:
实心圆形是起始点
环形是终止点
基于类的建模方法(暂无)
基于模式的建模方法(暂无)
包含
功能性需求
非功能需求
性能
约束条件
外部接口(用户接口UI)
特征
基本
高级
软件工程开发方法
传统方法和面向对象方法的本质区别
前者:功能+数据
后者:对象+消息
传统方法-2方法
功能分解法
层层进行功能分解。
优点:简单、易启动
缺点:
模块间具有依赖性,难以检测错误
难以适应需求变化
局部错误将影响全局(牵一发而动全身)
结构化方法-6种
缺点:
需求的变化/需求自身的错误
系统结构的崩溃
存在上述问题的核心原因:
结构化方法是面向数据流与功能分解的方法,可是它们时刻会变
数据流图DFD
数据字典DD
结构化语言
判定表或判定树
实体转化图E-R
信息建模法
实体:矩形
关系:菱形
属性:圆形
状态转化图
面向对象开发方法
基本概念:
类
对象
消息
多态(重载方法)
继承
软件设计
特征-3要素
如何记忆?
对于目标而言,即要完成用户的需求(设计完不成用户的需求,我只能给他0分)
对于形态而言,要可读、易理解、可操作(开发者要对着这份设计文档看的,要是不可读,那还开发什么?)
对于内容而言,当然要写出一份囊括整个软件的面向实现的文档了
目标
设计必须是实现所有包含在分析模型中的明确需求、以及客户期望的所有隐含需求。
形态
对开发、测试和维护人员来说,设计必须是可读的、可理解的、可操作的指南
内容
设计必须提供软件的全貌,从实现的角度去说明功能、数据、行为等各个方面。
原则-5原则
封装性
复用性
抽象
层次化
应用层、网络层、链路层、物理层
模块化
基本要素-3要素
软件体系结构 = 构件 + 连接件 + 约束条件
构件-4特点
如何记忆?
把构件理解为一种控件(安卓控件),安卓控件你希望有什么特点?
首先它得是可配置的吧,比如你想要修改颜色;其次它是可复用的吧,不然你怎么才能反复用这个控件呢?如何来理解可替换呢?我们以安卓点击事件为例,安卓每个控件实际上都有点击事件,我们完全可以替换该控件的点击事件为我们自定义的点击事件;最后,他得是可分离的吧,也就是说我们直接引入某个包就能直接使用,不想用了把包删掉就好。
连接件-3示例
连接各个构件,是构件间的桥梁
约束条件
例如一些层次结构上的约束,上层不能访问下层之类的,有点类似强制访问协议
体系结构风格(软件架构)-5架构
数据流风格(DFD)
以数据为中心风格
如何记忆?
Windows注册表
面向对象风格
返回/调用风格(类似功能分解法)
层次结构风格
C/S
Client
Server
三层C/S架构
Client
Businesses
Server
B/S
Browser
UI
应用层(Business)
Server
C/S+B/S
公司内部C/S,外部B/S
CRC卡片分拣法
CRC
C:Class(确定类)
R:Responsibility(确定责任、确定方法)
C:Collaboration(确定类之间的关联)
DFD结构化方法
要素
层次性
顶层:从0标号,不得出现数据存储
0层:从1标号
1层:从x.1标号
……
要求-7/3
基本要求-7要求
不好评估的原则-3原则
状态图
状态的抽象
例如人的一生,我们可以分为
出生、青年、中年、老年、死亡
每个阶段都是对年龄的一个抽象
状态图建模
要素-3要素
状态种类-4类
组合状态
OR关系
同时只能执行一个
AND关系
可以并列执行
历史状态(记忆)
状态活动
do
entry
exit
include
状态迁移
三个部分
src:源状态
dst:目标状态
转移条件: 事件名称[警戒条件]/动作
顺序图(时序图)
要素-4要素
对象(object)
生命线(LifeLine)
激活态(Active)
消息(Message)-4/1
基础类消息-4
应用类消息-1
组合片段-4种
程序员应该做到……-至少3点
编写自文档化代码
善于运用程序模板
善于写有意义的注释
良好的函数编写习惯
短小
更短小
只执行自己应该做的事,别做多了
代码审查-3种模式
如何记忆?
桌面检查:一个程序员
代码走查:设计或编程人员组成小组
代码审查:编程或测试人员组成小组,以会议形式进行审查
桌面检查
由一个程序员人工阅读代码,通过对源程序代 码的分析和检验来发现程序中的错误。
代码走查
设计或编程人员组成一个走查小组,通过阅读一段文档或代码并进行提问和讨论,发现可能存在的问题。
代码审查
若干编程人员和测试人员组成一个审查小组,以会议形式通过阅读、讨论和争议对程序进行静态分析。
代码重构-5种
如何记忆发散式变化和散弹式修改?
发散式变化:一个类处理多个类的职责,一 VS 多,类似思维导图的发散式分支……
散弹式变化:多个类处理一个类的职责,多 VS 一,散弹多发子弹打中同一个人……
重复的代码
过长的函数
发散式变化
在一个类种要处理三种不同的事务,抽象三个类
散弹式修改
抽象类,封装需要多次修改的函数
数据泥团
多个类都用了同一个变量,将变量抽出
基本概念
缺陷类型术语-4个
如何记忆各个概念?
错误:人为导致的错误
接下来三个,我们联合记忆:
缺陷 导致 故障
故障 演变 失效
错误
人为操作错误
缺陷
系统本身的设计缺陷
故障
系统的一种不期望出现的状态
失效
软件运行时产生的一种不希望或不可接受的外部行为结果
概念
测试是使用人工和自动手段来运行或检测某个系统的过程,其目的在于检验系统是否满足规定的需求 或 弄清预期结果与实际结果之间的差别。
软件测试的特点-2点
缺陷的集群性
80/20原则:80%的软件错误存在于20%的代码行中
杀虫剂悖论
用同样的测试用例多次重复进行测试,最后将不再能够发现新的缺陷。
测试团队-4种
测试经理
建立和完善测试流程以及部门管理体制,审核测试项目并分配资源,监控和协调各项目的测试工作,负责与其他部门的协调和沟通工作。
测试组长
制定测试项目计划(包括人员、进度、软硬件环境和流程等),实施软件测试,跟踪和报告计划执行情况,负责测试用例质量,管理测试小组并提供技术指导。
测试工程师
理解软件产品的要求,对其进行测试以便发现软件中的错误,验证软件是否满足规格说明所描述的需求,编写相应的测试方案和测试用例。
测试工具工程师
编写软件测试工具,并利用所编写的测试工具对软件进行测试, 或者为测试工程师开发测试工具。
策略
测试对象-3个
如何记忆?
不管是需求分析阶段还是软件设计阶段抑或是软件实现阶段,我们都应该对各自的输出结果进行测试审查,它们对应的产出分别是:SRS、SDS以及CODE。
测试过程-4个
如何记忆?
一个很简单的方式,也是我们每个人做任何事之前要做的步骤:计划、准备、执行、报告。
计划阶段:首先需要有测试对象,我们才能有计划地对其进行测试,因此需要输入软件计划、软件规格说明、软件设计说明;
准备阶段:有了计划,当然是开始准备呗;
执行阶段:怎么测试?当然是通过对源码进行测试了,因此需要输入代码;
报告阶段:并不是说实验做完就完了,你还得写实验报告;
计划
输入:项目计划、SRS、SDS
输出:测试计划
准备
测试用例、工具等准备
执行
输入:经过审查或修改后的代码
输出:经过测试修正后的代码
报告
输出:测试报告
测试类型-4种
测试对象角度
单元测试
测试中最小的单元,通常由程序员自己编写
通常由两部分构成:
驱动模块:模拟父模块
桩模块:模拟子模块
集成测试-2个
一次性集成测试
每个模块分别进行单元测试,然后整体测试。
优点:
效率高
人力少
测试用例少
简单、易行
缺点:
难以进行错误定位和修正
会遗漏很多错误
新旧错误混杂
增量型集成测试
自底向上
优点:可以不再用到桩模块
缺点:在系统完成开发前都无法运用
自顶向下
缺点:需要用到大量桩模块
优点:可以迅速测试,有利于稳定军心
系统测试-4个
验收测试
回归测试
技术角度
黑盒测试
又称功能测试,它将测试对象看做一个黑盒子,完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。
白盒测试
又称结构测试,它把测试对象看做一个透明的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。
程序执行角度
静态测试
通过人工分析或程序正确性证明的方式来确认程序正确性。
动态测试
通过动态分析和程序测试等方法来检查程序执行状态,以确认程序是否有问题。
人工干预角度
测试用例-4条
测试用例是为特定的目的而设计的一组测试输入、执行条件和预期的结果。
概述
结构化测试;逻辑驱动测试
方案-2种
逻辑覆盖型-5种
语句覆盖
覆盖每一条语句
判定(分支)覆盖
A and B = T
A and B = F
条件覆盖
A = T, B = T
A = F, B = F
判定-条件覆盖
A and B = T
A and B = F
A = T, B = T
A = F, B = F
条件组合覆盖
A = T, B = T
A = T, B = F
A = F, B = T
A = F, B = F
控制结构型
基本路径测试-4个步骤
Step1:绘制控制流图
Step2:求取圈复杂度
V为圈复杂度,E为边数量,N为节点数量,P为区域数,M为分支节点个数
V = P
V = E - N + 2
V = M + 1
Step3:求解独立路径
本次路径必须包含之前出现的路径种没有的路径
Step4:编写测试用例
循环结构测试-4种类型
简单循环测试
按照如下顺序进行:
0次
1次
……
n-1次
n次
n+1次
嵌套循环测试
从内向外,外层保证最小循环次数,测试层与简单循环测试一致,内层取典型值
串接循环测试
两种情况:
简单串接:分别使用简单循环测试
复杂串接:运用嵌套循环测试
不规则循环测试
无法测试,需要转换结构
概述
功能化测试;任何程序都可看做将输入定义域取值映射到输出值域的函数
方案
等价类测试
原则
分而不交
各等价类无交集
合而不变
各等价类合起来没有超过输入定义域
类内等价
等价类中的元素应该等价
类型
测试用例设计
覆盖尽可能多的有效等价类
仅覆盖一个无效等价类
等价类陷阱
原始输入域改变
例如:后一日问题
针对从1800年到2050年之间的任意一个日期,计算出其下一天的 日期;
年:[1800~2050]
月:[1~12]
日:[1~31](并不是所有月份都有31、30)
这里,日的取值将原问题的输入域扩大了
无效等价类的采用单缺陷原则
等价类设计的两种方式
根据输入域
严格区分有效域与无效域
根据输出域
仅需要确定有效域,不存在无效域
边界值测试
场景法测试
通过运用场景来对系统的功能点或者业务流程进行描述
重要点:
基本流
备选流
概述
敏捷开发是一种基于更紧密的团队协作、能够有效应对快速变化需求、快速交付高质量软件的迭代和增量的新型软件开发方法。
主要方法是:
XP(极限编程):偏重于实践
Scrum:偏重于管理
Scrum(乱挤)
框架
将整个过程分为更小的迭代,每个迭代周期称为一个冲刺(Sprint),每次迭代就是一个小的瀑布模型
团队角色
Scrum Master
激励、辅助作用
Team
团队成员,自组织地完成开发任务
Product Owner
项目持有者,定义开发目标以及需要实现的特性和优先级
团队组织
民主式结构
优点:有利于技术难关的突破
缺点:遇到分歧难以解决
全功能整体团队
角色交叉,基于技能而非岗位组队
Scrum制品与活动
Scrum制品
产品订单Product Backlog
客户角度,产品功能列表
迭代订单Sprint Backlog
开发技术角度,迭代开发任务
可工作软件
活动
迭代规划会议
时间:每次冲刺(Sprint)开始前
内容:需求分析、设计
每日站立会议
时间:每天
成员:Team
内容:彼此明确工作及进度
迭代评审会议
Scrum团队在会议中向最终用户展示工作成果,团队成员希望得到反馈, 并以之创建或变更Backlog条目。
迭代总结会议
时间:迭代完成时
敏捷规划与可视化管理
Scrum规划
发布规划
发布规划
迭代规划
仅针对一次迭代的规划
可视化管理
项目交付工作-3个
项目实施
是将软件系统部署到客户方的计算机系统上,协助客户准备基础数据,使软件系统顺利上线运行
客户培训
在系统安装完成、基础数据准备齐全之后,应该组织客户培训,使其掌握对软件系统的使用和操作。
验收
客户对系统进行验收测试
演化法则-Lehman法则-5个
如何记忆后3者?
首先程序演化法则就是说软件遵循一般的统计意义上的发展规律;其次呢,组织稳定守恒就是说大家在一起开发的时候,每天做的工作、会议(例如Scrum的每日站立会议)等活动是基本不变的;最后,熟悉程度守恒是说大家对这个软件的熟悉程度都不会发生太大变化,即软件的功能一般不会随着软件的发展发生太大的变化
软件持续变化
复杂性递增(看看知乎吧)
程序演化法则
程序演化服从统计上的确定趋势(先好,后差)
组织稳定守恒
编程项目总体活动统计上不变
熟悉程度守恒
整个系统的功能不会发生很大的变化
软件维护
维护类型-3个
影响因素-4个
团队稳定性
原团队可能会解散,维护任务可能落在非原团队的人上,需要花时间理解
合同责任
开发人员一般不会签订维护合同
人员技术水平
领域知识欠缺
程序年龄与结构
程序结构越发混乱
软件再工程-5步
Step1:源代码转化
Step2:逆向工程
逆向工程是以复原软件的规格说明和设计为目标的软件分析过程
Step3:程序结构改善
Step4:程序模块化
Step5:数据再工程