软件工程概论

软件基本概念

  • 概念:软件由一组对象或项目所形成的一个配置,有程序、文档和数据等部分构成。
  • 分类:软件分为应用软件、支撑软件和系统软件。
  • 特征:复杂性、不可见性、易变性、一致性。

软件工程产生的历史根源

  • 大型软件系统开发会经常遇到“焦油坑”
  • 没有银弹
  • 软件危机:计算机软件的开发和维护过程所遇到的一系列严重问题

软件工程概念

(IEEE)软件工程是:将系统性的、规范化的、可定量的方法应用于软件的开发、运行和维护,即将工程化应用到软件上。

  • 范围:软件开发过程(设计、开发、运行、维护);软件开发中应遵循的原则和管理技术;软件开发中所采用的技术和工具
  • 目标:高质量,按时交付,控制成本,满足用户需求

软件开发方法

  • 结构化开发方法SADT
  • 面向对象开发方法OOAD
  • 面向服务的软件开发方法SOSE

软件工程核心思想

软件工程本质

软件系统开发的本质是从现实空间的需求到计算机空间的软件代码之间的映射与转换,映射可分为单步映射和多步映射。

软件工程的本质:用严格的规范和管理手段来缩小偏差,通过牺牲时间来提高质量

  • 概念映射:问题空间的概念与解空间的模型化概念之间的映射
  • 业务逻辑映射:问题空间的处理与解空间处理逻辑之间的映射

软件工程

不同抽象层次之间的映射过程。

  • 需求分析
  • 软件设计
  • 实现
  • 验证/确认

软件工程关注的目标

  • 功能性需求:软件所实现的功能达到它的设计规范和满足用户需求的程度
    • 完备性:软件能够支持用户所需求的全部功能的能力
    • 正确性:软件按照需求正确执行任务的能力
    • 健壮性:在异常情况下能够正常运行的能力,容错能力,恢复能力
    • 可靠性:在给定的时间和条件下,软件能够正常维持其工作而不发生故障的能力
  • 非功能性需求:系统能够完成所期望的工作的性能与质量
    • 效率、可用性、可维护性、可移植性、清晰性、安全性、兼容性、经济性……

软件工程=最佳实践

  • 迭代化开发
  • 需求管理
  • 使用基于构件的体系结构
  • 可视化软件建模
  • 持续质量验证
  • 控制软件变更

软件工程核心概念

概念和形式模型、抽象层次、分治、复用、折中、一致性和完备性、效率、演化

代码评审分析与优化

代码评审的最主要的目的是什么

是确保代码库一直保持健康的状态,代码评审的所有工具和过程都是为了这个目的而构建 的。代码评审会系统化地检查一遍源代码,并希望检查出开发初期未察觉的一些错误,从而提升代码质量。

代码评审的最主要的内容是什么

  • 设计:代码是不是经过精心的设计,并适合我们的系统?
  • 功能性:代码的行为是否和作者的意图保持一致?代码的行为方式对用户是否正常?
  • 命名:开发者是不是选择易于理解的名称给变量、类和方法进行命名?
  • 复杂度:代码能更简单一些吗?在未来,其它开发 者能更容易地理解并使用这些代码吗?
  • 测试:代码是不是正确的,是不是通过了精心设计 的自动测试?
  • 文档:开发者是不是更新了相关的文档?
  • 评论:代码评论是不是足够清晰并有用?
  • 风格:代码是不是采用了标准的编写风格?

使用静态代码分析发现潜在bug所使用的主要技术有哪些

主要技术:缺陷模式匹配、类型推断、模型检查、数据流分析等。

常用Java静态代码分析工具:Checkstyle,FindBugs,PMD

性能分析的目的是什么

  • 性能分析的目的在于:决定程序的哪个部分应该被优化,从而提高程序的速度或者内存使用效率。
  • 性能分析可以由程序的源代码或是可执行文件进行,一般会使用性能分析工具(profiler) 进行。

软件测试

为什么要进行软件测试,软件测试的基本原则有哪些

​ 一款软件开发出来并不能保证其稳定性与毫无漏洞,这就需要进行软件的测试,找出该软件的缺陷,产品的功能是否符合需求,检查软件有没有bug,决定软件是否具有稳定性。

​ 原则:充分注意测试中的聚集现象,测试中发现的80%的错误,可能由程序的20%功能所造成的。对测试结果要有一个确认过程。制定严格的测试计划,排除测试的随意性。注意回归测试的关联性,往往修改一个错误会引起更多错误。妥善保存一切测试过程文档,测试重现往往要靠测试文档。

常用的软件测试模型有哪些,分析一下各自的优缺点

模型 优点 缺点
传统瀑布模型 强调需求设计的作用;前一阶段完成后只需关注后续阶段;为项目提供按阶段划分的检查点,里程碑清晰。 线性研发过程难以适应需求的频繁变化;项目周期后段才可看到成果,用户要到末期才能看到开发结果,增加了开发的风险;强制的里程碑,对于开发过程中出现的变化,适应能力较差;文档工作量较大,测试在项目的后期,文档的开发带来很大的工作量。
V模型 以“编码”为黄金分割线,将整个过程分为开发和测试,并且开发和测试之间是串行的关系。 将测试放在整个开发的最后阶段,没有让测试尽早介入开发,没有在需求阶段就进入测试。
W模型 测试与开发并行,让测试尽早介入开发环节,使测试尽早发现问题今早解决。 虽然开发与测试并行了,但是在整个开发阶段,仍然是串行的,上一阶段未完全完成无法进入下一阶段,不支持敏捷模式的开发。
X模型 解决交接和频繁集成周期的问题。
H模型 测试是一个完全独立的模型,所以可以和其他的流程交叉地进行,便于尽早执行测试。

软件测试过程及其相关活动

  • 开发者测试:单元测试,集成测试(软件设计文档),确认测试(软件需求文档),系统测试(其他系统元素,用户手册),性能测试(非功能性需求)。
  • 客户测试:验收测试,安装测试
  • 用户测试:试用测试

单元测试,集成测试,确认测试,系统测试,验收测试基本内容

  • 单元测试:对软件基本组成单元进行的测试,有时也称“组件测试”。单元测试一般由编写该单元代码的开发人员执行,该人员负责设计和运行一系列的测试以确保该单元符合需求。
  • 集成测试:在单元测试的基础上,将所有模块按照总体设计的要求组装成为子系统或系统进行测试的接口。
  • 确认测试:检查软件能否按合同要求进行工作,即是否满足软件需求说明书中的确认标准。
  • 系统测试:将已经集成好的软件系统作为一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其他元素结合在一起,在实际运行环境下进行的一系列测试。
  • 验收测试:验收测试是以用户为主的测试,一般使用用户环境中的实际数据进行测试。在测试过程中,除了考虑软件的功能和性能外,还应对软件的兼容性、可维护性、错误的恢复功能等进行确认。

黑盒测试白盒测试的异同

黑盒测试 白盒测试
只利用规格说明标识测试用例 只利用程序源代码标识测试用例
如果程序实现了未描述的行为,功能测试无法意识到 如果已描述的行为未能实现,结构性测试无法意识到
冗余度大,可能会有漏洞 具有覆盖率指标

软件设计与软件架构概论

什么是软件设计,软件设计在SE中所处哪个位置

软件设计为问题域的外部可见行为的规约增添实际的计算机系统实现所需的细节,包括关于人机交互、任务管理和数据管理的细节。

软件需求分析→需求规格说明→软件设计→软件文档→软件编码

软件设计的主要内容

架构,人机界面和通讯接口,数据结构,算法。

微服务架构的基本标准有哪些

  • 分布式服务组成的系统
  • 按照业务而不是技术来划分组织
  • 做有生命的产品而不是仅仅针对项目
  • 强服务个体和弱通信
  • 自动化运维
  • 高度容错性
  • 快速演化和迭代

软件架构的核心概念

image-20200708183129945.png

软件架构的核心思想有哪些

  • 异步:层与层之间通过异步调用提升吞吐量
  • 分层:各层次职责单一,提升可维护性
  • 缓存:层与层之间通过缓存提高存取效率
  • 分布式:各层内通过分布式提升性能

SaaS(软件即服务)与云端软件部署

B/S与三层C/S结构的区别

  • C/S:表现层仍部署在客户端(表示层,功能层,数据层)
  • B/S:客户端除浏览器外无任何程序需要部署(表现层,应用层,数据层)

C/S+B/S混合模式遵循的原则是什么

  • 内外有别:企业内部通过局域网直接访问数据库服务器,企业外部通过Internet访问Web服务器
  • 查改有别原则:不管用户处于企业内外什么位置(局域网或Internet),凡是需要对数据进行更新操作的,都需要使用C/S结构;如果只是执行一般的查询与浏览操作,则使用B/S结构

Sass软件的基本特征,与传统B/S的本质区别是什么

本质上属于B/S结构,对B/S的扩展:

  • 通过web来管理和使用软件
  • 软件被集中式的部署与管理,统一升级和维护
  • 单实例,多租户

本质区别:多租户共享Server和软件实例

SaaS软件具体划分为哪几个层次,每个层次分别有什么作用

  • 表示层:接收用户输入的数据与指令,展示数据的处理结果;本身并不维护数据也不包含业务逻辑
  • 控制层:统一维护一组对象;根据表示层发来的指令调度这些对象的行为;除了调度之外,本身也可能包含业务逻辑;亦可直接访问DB
  • 逻辑层:对象(数据+业务逻辑)
  • 持久化层:数据的持久存储

SaaS软件基本架构是MVC,M、V、C分别有什么作用

  • 模型M:封装业务逻辑/数据,将数据变化通知视图
  • 视图V:显示用户界面,将用户行为传递给控制器
  • 控制器C:将用户行为映射到模型的更新上,选择需要显示的视图

基本架构风格

软件架构风格划分为哪几个层次

  • 代码模式:编码时的套路,一些技巧,是最低层次的套路,只能影响某一方法或类中的一些细节
  • 设计模式:解决了一般性的设计问题,影响一个模块内部,是中等层次的重用策略
  • 架构模式:是高层层次的重用策略,实现定义好一些子系统,层,指定他们的责任,并给出把他们组织在一起的法则和指南

C/S+B/S混合模式遵循的原则

内外有别原则:

  • 企业内部用户通过局域网直接访问数据库服务器
    • C/S结构,交互性增强,数据查询与修改响应速度高
  • 企业外部用户通过Internet访问Web服务器/应用服务器
    • B/S结构,用户不直接访问数据,数据安全

查改有别原则:

  • 不管用户处于企业内外什么位置,凡是需要对数据进行更新操作的都要使用C/S结构
  • 如果只是执行一般的查询与浏览操作则使用B/S结构

事件系统的基本构成与实现策略

image-20200709085846109.png

分离的交互:事件发布者不会意识到事件订阅者的存在

多对多通信:采用发布/订阅消息传递,一个特定事件可以影响多个订阅者

基于事件的触发器:控制流由接收者确定

异步:通过事件消息传递支持异步操作

事件风格实现策略:

  • 选择广播式:有目的广播,只发送给那些已经注册过的订阅者
  • 观察者模式:发布-订阅模式

软件需求与需求获取

软件需求有哪些作用

  • 充分理解现实中的业务问题,并作为软件设计的基础
  • 为软件项目的成本、时间、风险估计提供准确的依据
  • 减少开发工作量,避免将时间与资源浪费在设计与实现错误的需求上
  • 通过提供需求文档和需求基线,来有效的管理系统演化与变更
  • 作为顾客与开发团队之间正式合同的一部分
  • 为最终的验收测试提供标准和依据

不同层次的软件需求

image-20200709091920149.png

产生不合格需求的原因有哪些

  • 无用户参与
  • 用户需求不断增加
  • 模棱两可的需求
  • 不必要的特性
  • 过于精简的规格说明
  • 忽略了用户分类
  • 不准确的计划

用户故事与用例建模

什么事用户故事,由哪些内容构成

  • 卡片:简要的文本陈述
  • 交谈:用户如何与系统交互
  • 确认:如何验证和测试

好的用户故事应具备的特征

  • Independent:尽可能独立
  • Negotiable:可讨论的
  • Valuable:对用户/客户有价值的,以用户可理解的语言书写,是系统的特性而非开发任务
  • Estimable:其工作量可以估计
  • Small:小
  • Testable:可测试的,可验证的

面向对象软件开发方法中的用例有哪些特征

  • 行为序列:一个用例由一组可产生某些特定结果的行为构成,这些行为是不可再分解的
  • 系统执行:系统为外部角色提供服务
  • 可观测到的,有价值的结果:用例必须对用户产生价值
  • 特定的角色:某人,某台设备,某外部系统等,能够触发某些行为

用例模型的元素构成

  • 参与者:存在于被定义系统外部并与该系统发生交互的人或其他系统,代表系统的使用者或使用环境
  • 用例
  • 通讯关联:用于表示参与者和用例之间的对应关系。表示参与者使用了系统中的那些服务(用例),系统所提供的服务(用例)是被哪些参与者使用的

用例建模的基本过程

  • 识别并描述参与者
  • 识别用例,给出简要描述
  • 识别参与者与角色之间的通讯关联
  • 给出每一个用例的详细描述
  • 细化用例模型

面向对象基本概念

面向对象的软件工程

  • 面向对象分析OOA:分析和理解问题域,找出描述问题域和系统责任所需的类及对象,分析它们的内部构成和外部关系,建立OOA 模型
  • 面向对象设计OOD:将OOA 模型直接变成OOD模型,并且补充与一些实现有关的部分,如人机界面、数据存储、任务管理等
  • 面向对象编程OOP:用一种面向对象的编程语言将OOD模型中的各个成分编写成程序,由于从OOA→OOD→OOP实现了无缝连接和平滑过渡,因此提高了开发工作的效率和质量

面向对象基本概念

  • 对象
    • 对象Object:用来描述客观事物的实体,是构成系统的一个基本单位,由一组属性以及作用在这组属性的操作构成
    • 属性Attribute:描述对象静态特性的数据项
    • 操作Operation:描述对象动态性的一个动作
  • 类:具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述
  • 消息:一个对象向其他对象发出的请求,一般包含提供服务的对象标识、服务标识、输入信息和应答信息等信息
  • 封装:把对象的属性和操作结合成一个独立的单元,并尽可能对外界隐藏对象内部实现细节
  • 接口:描述了一个类的一组外部可用的属性和服务(操作)集
  • 继承:之类可以自动拥有父类的全部属性和操作
    • 单一继承
    • 多重继承
    • 抽象类:把一些类组织起来,提供一些公共的行为,但不能使用这个类的实例(即从该类中派生出具体的对象),而仅仅使用其子类的实例。称不能建立实例的类为抽象类
  • 多态:在父类中定义的属性或服务被子类继承后,可以具有不同的数据类型或表现出不同的行为。同一操作用于不同对象上可以有不同的解释,并产生不同的执行结果

对象之间的关系

  • 分类结构:继承/泛化:一般与特殊的关系
  • 组成结构:
    • 组合:部分与整体的关系,彼此不可分
    • 聚合:部分与整体的关系,但彼此可分
  • 实例连接:关联:对象之间的长期静态联系
  • 消息连接:依赖:对象之间动态的,临时的通信联系

强度:继承>>组合>>聚合>>关联>>依赖

  • 接口连接:实现关系:是泛化关系和依赖关系的结合,通常用以描述一个接口和实现它们的类之间的关系

面向对象分析与设计

系统设计

  • 包图:逻辑设计
  • 部署图:物理设计

对象设计

  • 类图
  • 状态图
  • 时序图
  • 关系数据库设计方案
  • 用户界面设计方案

面向NFR(非功能性需求)的软件架构设计

面向对象五大设计原则

  • 单一责任原则SRP:一个类一个责任,不应有多于一个的原因使得一个类发生变化
  • 开放封闭原则OCP:对扩展性的开放,对修改的封闭
  • Liskov替换原则LSP:子类型必须能够替换其基类型
  • 接口隔离原则ISP:客户端不应依赖于它们不需要的方法,客户端应依赖稳定的接口
  • 依赖倒置原则DIP:抽象模块不依赖于具体模块,具体应依赖于抽象

抽象:LSP,DIP,OCP

分离:SRP,ISP

模块化设计原则

模块化设计目标:高内聚,低耦合

模块内部聚合度:某一模块内部包含的各功能之间相互关联的紧密程度

模块之间耦合度:多个模块之间相互关联的紧密程度

耦合是影响软件复杂程度和设计质量的重要因素,应建立模块间耦合度尽可能松散的系统

软件架构基本模式

  • 分层:C/S、B/S、多层,数据、计算与显示的分离(MVC)
    • 各负其责,分工明确
    • 牺牲了效率,提高了可维护性
  • 异步:事件,消息
    • 请求之后继续执行,后续等待结果
    • 性能(吞吐量)提高,但是实时性变差
  • 缓存:页面缓存、数据缓存、消息缓存
    • 预取
    • 提高了效率,牺牲了准确性
  • 并发(分布式):集群、负载均衡、分布式数据库
    • 多个模块共同处理请求
    • 提高了吞吐量,可靠性,降低了响应时间,但需考虑同步等复杂问题