软考笔记 - 案例分析
系统规划
主题内容:
- 系统规划
- 费用的成本类型
- 成本效益分析计算
例题考点:
- 软件项目的可行性分析概念
- 经济可行性:项目的建设成本、运行成本和项目建成后可能的经济收益
- 技术可行性:信息系统需要实现的功能和性能,以及技术能力约束
- 法律可行性:从政策、法律、道德、制度等社会因素来论证信息系统建设的现实性
- 用户使用可行性:从信息系统用户的角度来评估系统的可行性,与企业现行制度是否结合,是否方便员工使用
- 开发成本和运营成本、有形收益和无形收益之间的辨析
- 净现值计算相关(注意记得加上开发成本)
- 静态投资回收期:不折现的情况下,考虑收益与投资相同的年份
- 动态投资回收期:折现计算收益与投资相同的年份
- 投资收益率:折现总收益/折现总投资,年均收益率 = 总收益率 / 运营年数
需求工程
主要在需求获取和需求分析上面。
需求获取
- 抽样调查计算样本大小:$\alpha \times (可信度系数 / 1 - 可信度)^2$
- 用户访谈
- 准备访谈:确定访谈目的、访谈用户、详细的访谈问题(开放式、封闭式)、制定访谈安排、学习领域知识
- 访谈过程:限制时间、寻找异常错误情况、深入细节、做好记录
- 访谈后续:吸收理解记录访谈信息、错过的问题先记录下次再访谈
- 问卷调查
- 确定问题及其类型(开发+封闭),注意使用“用户的语言”编写
- 缺点:未见面,难以获得隐性信息;不重视;不了解进一步的细节;
- 提升问卷返还率:解释问卷的目的、哪些人必须写、领导督促、合理设计问卷、奖品或奖励
- 联合需求计划(JRP):议程、时间安排、会议纪要、避免专业术语、解决冲突、会议要有间歇、尽量取得一致意见、遵守规则
结构化需求分析
数据字典将功能模型、数据模型和行为模型联系在一起。
- 功能模型:数据流图(一般从0层开始)
- 数据模型:实体联系图
- 行为模型:状态转换图
数据流图
强调系统中的数据流动,由数据流,外部实体,加工,数据存储四个部分组成。
- 父图与子图之间的平衡:细化之后,外部实体与系统之间的数据流不改变
- 子图内部的平衡:加工前后数据有进有出,错误实例:
- 黑洞:一个加工只有输入数据流而没有输出数据流
- 奇迹:一个加工只有输出数据流而没有输入数据流
- 灰洞:一个加工的输入数据流不能通过加工产生输出数据流
好的数据流图三原则:
- 复杂性最小化:把信息划分为小的且相对独立的一大批字集。详细信息可以往下一层,与其它模块的关联可以往上一层。
- 接口最小化:也是复杂性最小化的一种具体体现。各元素之间的接口或连接数应该最小化。
- 数据流一致性:即上文所说的数据流图平衡
活动图(带泳道)
活动图的关键就在于它的活动都是“谓语”,表示一种动作。也可以说是一种特殊的状态图。
活动图分泳道,分清是由哪些角色完成活动。
用例图
用例图描述一组用例、参与者及他们之间的关系。由用户角度描述系统的功能,参与者(用户、组织、外部系统、时间)是外部触发因素,用例是功能单元。
用例建模的流程:
- 识别参与者(必须)
- 合井需求获得用例(必须)
- 细化用例描述,用例规约(必须):一个复杂的表格,记载了用例名称、ID、说明、前置条件、后置条件、参与角色、基本事件流、其他事件流、异常事件流等。
- 调整用例模型(可选)
用例关系包括:包含关系、扩展关系、泛化关系。
- 包含关系:其中这个提取出来的公共用例称为抽象用例,而把原始用例称为基本用例或基础用例。当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示它们。(查询和外借都包含登录)
- 扩展关系:如果一个用例明显地混合了两种或两种以上的不同场景,即根据情況可能发生多种分支,则可以将这个用例分为一个基本用例和一个或多个扩展用例,这样使描述可能更加清晰。
- 泛化关系:当多个用例共同拥有一种类似的结构和行为的时候,可以将它们的共性抽象成为父用例,其他的用例作为泛化关系中的子用例。在用例的泛化关系中,子用例是父用例的一种特殊形式,子用例继承了父用例所有的结构、行为和关系。
包含vs泛化:是否体现了父子关系
采用UML分析用户需求时,用例UC1可以出现在用例UC2出现的任何位置,那么UC1 和UC2 之间的关系是(泛化)。
解题思路:该题涉及面向对象的分析,子类是可以替换父类的。就此题而言,UC1应该是UC2的子类。
类图
- 类名、方法名、属性名
- 多重度
- 关系
多重度
- 1:表示一个集合中的一个对象对应另一个集合中一个对象。
- 0..*:表示一个集合中的一个对象对应另一个集合中的0个或多个对象。
- 1..:表示一个集合中的一个对象对应另一个集合中的一个或多个对象。
关系
- 依赖关系:一个事物发生变化影响另一个事物。
- 泛化关系:特殊、一般关系。
- 关联关系:描述了一组链,链是对象之间的连接。
- 聚合关系:整体与部分生命周期不同。
- 组合关系:整体与部分生命周期相同。
- 实现关系:接口与类之问的关系。
顺序图
顺序图强调对象之间消息发送的顺序,同时显示对象之间的交互。
通信图
强调对象之间存在的消息收发关系,而不突出这些消息的发送时间顺序。
状态图
用于展现此类对象所具有的可能状态,以及某些事件发生时状态转移情况。
定时图
展示交互过程中的真实时间信息,具体描述对象状态变化的时间点以及维持特定状态的时间段。
构件图和包图
构件图描述一个封装的类和它的接口、端口,以及由内嵌的构件和连接件构成的内部结构。构件图是类图的变体。
包图,包的图标像是一个带标签的文件夹,包的基本思想是把共同工作的元素放到一个文件夹中。
部署图
描述软件构件与物理节点之间的部署位置以及之间的通讯协议配置等等。
Web系统设计
主要是Web开发涉及技术的综合应用。高性能、高可用、可维护、应变、安全等。
影响web性能的三个主要因素与相关对策(建立对应的缓存池):
- 数据库的连接与销毁。可以采用数据池的方式缓存数据库连接,实现数据库连接复用,提高系统的数据访问效率。
- 构件或中间件的加载与卸载。可以采用分布式对象池的方式缓存创建开销大的对象,实现对象复用,用以提高效率。
- 线程的创建与销毁。可以采用线程池的方式缓存己经创建的线程,提高系统的反应速度。
负载均衡
负载均衡在应用层和传输层都可以实现。
- 应用层负载均衡
- 基于特定软件的负载均衡(HTTP重定向):实现简单,性能差
- 反向代理的负载均衡:部署简单,代理服务器可能成为性能瓶颈
- 传输层负载均衡
- 基于DNS的负载均衡:效率高于HTTP重定向,但是应用服务器故障不能及时通知DNS,且DNS负载均衡控制权在域名服务商处
- 基于NAT的负载均衡:一个外部IP映射为多个内部IP,动态转换。技术成熟,一般在网关位置,可以通过硬件实现。四层交换机一般采用了这个技术。
负载均衡算法
负载均衡算法主要分为静态和动态两类。静态算法不考虑系统当前的负载,而动态算法是考虑当前系统的负载的。
静态负载均衡算法
- 轮转算法:轮流将服务请求(任务) 调度给不同的节点(即:服务器)。
- 加权轮转算法:考虑不同节点处理能力的差异。
- 源地址哈希散列算法:根据请求的源lP地址,作为散列键从静态分配的散列表找出对应的节点。
- 目标地址哈希教列算法:根据请求目标P做散列找出对应节点。
- 随机算法:随机分配,简单,但不可控。
动态负载均衡算法
- 最小连接数算法:新请求分配给当前活动请求数量最少的节点,每个节点处理能力相同的情况下。
- 加权最小连接数算法:考虑节点处理能力不同,按最小连接数分配。
- 加权百分比算法:考虑了节点的利用率、硬盘速率、进程个数等,使用利用率来表现剩余处理能力。
硬件负载均衡:F5;软件负载均衡:LVS、Nginx、HAproxy
Session共享机制
- 客户端携带session的cookie
- 服务器之间同步session
- 服务器将session存入共享的redis
无状态服务是对单次请求处理,不依赖其他请求。处理请求的所有信息,要么都包含在请求里,要么可以从外部获取到。
有状态服务,它的自身会保存一些数据,先后请求有关联。
ORM与持久化
面向对象的映射关系
- 类——数据库表
- 对象——记录
- 属性——字段
比较维度 | Hibernate | Mybatis |
---|---|---|
特点 | 强大,复杂,间接 | 小巧,简单,直接 |
SQL相关性 | 无关 | 有关 |
可移植性, 与SQL相关性 紧密联系 | 好 | 差 |
复杂多表关联 | 不支持 | 支持 |
数据库读写分离
主从数据库结构:一主多从,多主多从。主库做写操作,从库做读操作。通过日志同步。
- 主库(Master)更新数据完成前,將操作写binlog日志文件。
- 从库(Salve)打开/0线程气主库连接,做binlog dumpprocess, 井将串件写入中继日志。
- 从库执行中继日志事件,保持与主库一致。
主从复制的策略:基于SQL语句的复制、基于行的复制、混合模式复制。
用缓存降低数据库IO
- 读取,检查key,若有直接返回;没有就查数据库,并更新缓存
- 写入,先写数据库,再更新对应的缓存
以上是最简单直接的同步方案。初次之外,还有通过中间件采用异步队列方式同步,通过数据库插件完成数据同步和利用触发器进行缓存同步。
比较维度 | MemCache | Redis |
---|---|---|
数据类型 | 简单kv类型 | 丰富的数据结构 |
持久性 | 不支持 | 支持 |
分布式存储 | 客户端哈希分片 一致性哈希 | 多种方式,主从、 Sentinel哨兵、Cluster等 |
多线程 | 支持 | 6.0以上支持 |
内存管理 | 有 | 没有 |
事务支持 | 不支持 | 有限支持 |
容灾 | 不支持 | 支持 |
Redis相关
Redis存储与切片
Redis集群切片的常见方式:
- 客户端分片:在客户端通过key的hash值对应到不同的服务器
- 中间件实现分片:在应用软件和redis中间,通过中间件来实现服务到后台redis节点的路由分派
- 客户端服务端协作分片:即redis cluster模式,客户端采用一致性hash,服务端提供错误节点的slot重定向
范围分片:按照数据ID分类
哈希分片:对key进行哈希运算分片
一致性哈希分片:汤羽讲的一个环上的那种哈希,有效地解决了重新分配节点带来的问题
分布式存储方案:主从模式、哨兵模式、集群模式
- 主从:一主多从,故障时手动切换
- 哨兵:有哨兵的一主多从,主节点故障自动选择新的主节点
- 集群:分节点对等集群,分slots,不同slots的信息存储到不同的节点
Redis数据类型
类型 | 特点 | 示例 |
---|---|---|
String | 存储二进制任何数据,最大512MB | 缓存、计数、共享session |
Hash | 一个Key对应一个HashMap,针对一组数据 | 存储、读取、修改用户属性 |
List | 双向链表、有序,增删快、查询慢 | 消息队列,文章列表, 记录前N个最新的登陆ID |
Set | 键值对无序,唯一 增删查改都是O(1),支持交并差 | 去重,共同爱好,标签 |
Sorted Set | 键值对有序,唯一,自带按权重排序效果 | 排行榜 |
Redis缓存与持久化
缓存技术的淘汰机制:不淘汰(默认)、设置过期时间的键空间、全键空间。
- 不淘汰:默认策略,内存不足则报警
- 设置过期时间的:volatile-random,随机移除;volatile-lru,优先移除最近未使用;volatile-ttl,优先移除ttl最小的
- 全键空间:allkeys-random,allkeys-lru
Redis持久化有两种方式:
- RDB:传统数据库中的快照方式,指定时间时间间隔存储快照。全量备份,数据还原速度快,保存间隔时间长,数据安全性低,(相同数据量)数据体积相对小
- AOF:传统数据库中的日志方式,增量存储数据更改的指令。增量备份,数据还原速度慢,保存时间间隔短,数据安全性高,(相同数据量)数据体积相对大
在RDB状况下,save操作会阻塞。
Redis常见问题
- 缓存雪崩:Redis缓存在短时间内大量失效,导致数据库IO突然大量增加,导致数据库崩溃。可以通过锁或队列保证数据库IO在可以承受的范围;为key设置不同的失效时间,避免在同一时间缓存大量失效;设置二级缓存,有时间限制的缓存+无时间限制的缓存,减少对数据库的访问。
- 缓存穿透:查询结果为空,则一般情况下缓存里面不存。那么我们可以在缓存结果为空的情况下,直接设置默认值放到缓存。也可以通过设置布隆过滤器来降低对数据库的压力,它可以拦截掉一个一定不存在的数据。
- 缓存预热:系统上线后,直接将缓存先加到缓存系统中。可以通过上线时直接模拟访问、(数据量不大时)项目启动自动加载和定时刷新缓存来实现缓存预热。
- 缓存更新:除Redis自带的缓存失效策略,还有定时清理过期缓存、先判断用户请求的数据缓存是否过期,过期直接更新缓存的方案。
- 缓存降级:在系统出现问题时,保留核心系统可用,减少缓存对系统资源的占用。
XML与JSON
XML的优点:格式统一,符合标准;容易与其它系统进行远程交互,数据共享比较方便。
XML的缺点:文件庞大、格式复杂;服务器与客户端都需要大量的代码来解析XML。
JSON的优点:数据格式简单、易读写、格式都是压缩的、占用带宽小;易于解析,JavaScript通过 eval()
进行JSON读取,其他语言也支持;简化客户端和服务器端的代码开发量,易于维护。
JSON的缺点:推广较晚,不如XML使用广泛。
RESTful
只使用HTTP和XML进行基于Web通信的技术,可以降低开发的复杂性,提高系统的可伸缩性。
- 网络上的所有事物都被抽象为资源。
- 每个资源对应一个唯一的资源标识。
- 通过通用的连接件接口对资源进行操作。
- 对资源的各种操作不会改变资源标识。
- 所有的操作都是无状态的。
响应式设计
响应式WEB设计是一种网络页面设计布局,其理念是:集中创建页面的图片排版大小,可以智能地根据用户行为以及使用的设备环境进行相对应的布局。
- 采用流式布局和弹性化设计:相对单位和百分比。
- 响应式图片:按照比例缩放图片,在小设备上降低图片自身的分辨率。
数据库设计
数据库的性能、数据一致性和安全问题是数据库设计中最重要的三个问题。
提升查询效率,降低添加、修改、删除效率。采用B树,B+树等。
对象-关系映射
O/R映射是指将关系数据库中的关系型数据与面向对象编程语言中类型系统定义的数据进行格式转换。好处如下:
- 可以将业务逻辑与数据逻辑分离;
- 可以使得开发人员采用面向对象的方式访问底层关系型数据库;
- 能够做到上层应用与底层的具体数据库无关,两者解耦合。
反规范化
优点:连接操作少、检索快、统计快,查表少,索引快
缺点:数据冗余,插入、更新等操作开销大,数据不一致(触发器数据同步/应用程序数据同步),更新和插入代码困难
- 增加派生性冗余列:单价 * 数量 = 总价,增加总价,减少计算
- 增加冗余列:姓名和学号都在成绩
- 重新组表:最直接的反规范化
- 分割表:按照地区水平分割
分区分表分库
- 分区:一般DBMS直接提供,一个表分成多个物理文件,逻辑上一张表
- 分表:分成了两个或多个有意义上的独立表格,逻辑上是两张表
- 分库:根据业务情况分成多个库
分表和分区都针对数据表、都使用了分布式存储、都提升了查询效率、都降低了数据库的IO压力。
数据库常见的分区方式:范围分区(人为按照ID分区),哈希分区,列表分区(人为按照非连续字段分区,如全国的省份)
分区的优点:分区之后可以存储更多的数据,清理数据更方便,更精准的查询数据,跨区多个磁盘查询更高效,涉及聚合函数查询也容易进行数据的合并(逻辑上是一个表)
分布式数据库
分布式数据库在原有的集中式数据库上,额外增加了全局DBMS来管理。全局DBMS由全局外模式、全局概念模式、分片模式和分布模式这四个部分组成。
分布透明性:分片透明、位置透明,以及局部数据模型透明(逻辑透明)。分不分片,用户感受不到;数据存放的位置,用户不用管;用户不用关心局部数据模型。分片也分为水平分片和垂直分片,即按记录和按字段的分片,也有混合分片。
NoSQL
关系数据库:面向通用领域。
NoSQL的几个特点:特定应用领域、海量、非结构化、高并发、弱事务性、向外扩展
常见的几个NoSQL:键值Redis、列存储HBase、文档MongoDB、图数据库Neo4J
联邦数据库系统
联邦数据库系统的特征:分布、异构、自治、透明。联邦数据库对数据库等文件做集成,并对外提供统一的借口。
分为紧耦合和松耦合两大类。
数据库性能优化小结
集中式数据库优化
- 硬件系统(CPU,内存,硬盘,网络等)
- 系统软件(进程优先级,CPU使用权等)
- 数据库设计
- 表与视图(物化视图)
- 索引:利于查询,不利于修改
- SQL优化:以不相干子查询代替相干子查询
- 应用软件:数据库连接池
分布式数据库优化:降低通信代价。有全局查询树转换、多副本策略、查询树分解、半连接与直接连接。
数据库迁移的七步
- 待迁移数据源的详细说明,包括数据的存放方式、数据量和数据的时间跨度。
- 建立新旧系统数据库的数据字典,对现有系统的历史数据进行质量分析,以及新旧系统数据结构的差异分析。
- 新旧系统代码数据的差异分析。
- 建立新旧系统数据库表的映射关系,对无法映射字段的处理方法。
- 开发或购买、部署ETL工具。
- 编写数据转换的测试计划和校验程序。
- 制定数据转换的应急措施。
云数据库的特点
云数据库是指被优化或部署到一个虚拟计算环境中的数据库,具有按需付费、按需扩展、高可用性以及存储整合等能力。
云数据库的特点有:实例创建快速、支持只读实例、读写分离、故障自动切换、数据备份、Binlog备份、SQL审计、访问白名单、监控与消息通知等。
大数据
4V:Volume、Velocity、Variety、Value。
大数据偏向于深度分析,如关联分析、回归分析等。需要以集群平台做硬件支撑。
面向对象的系统开发
面向对象分析方法是将面向对象思想应用于系统分析过程,以用例描述作为输入,基于对象完成业务问题的理解、业务过程分析和建模。面向对象系统开发过程中,按照对象所承担的职责不同,可以将对象分为:
- 实体对象:表示业务域的事实数据并需要持久化存储的对象类型;
- 控制对象:表示业务系统中应用逻辑和业务规则的对象类型;
- 接口对象:表示用户与系统之间交互方式的对象类型。
筛选对象的原则:
- 去除相同含义的对象;
- 去除不属于系统范围内的对象;
- 去除没有特定独立行为的对象;
- 去除含义解释不清楚的对象;
- 去除属于另一个对象属性或行为的对象。
并发程序设计模式
模式 | 分解方式 |
---|---|
任务级井行模式 | 任务分解 |
分治模式 | 任务分解或数据分解 |
几何分解模式 | 数据分解 |
流水线模式 | 数据流分解 |
波峰模式 | 数据流分解 |