在我们这一次博客,我会将自己整理的课件一些知识点的总结翻译搬运过来。
-
软件构造的多维度视图和质量目标
-
多维软件视图
什么是一个软件?
“软件”的术语最早是Alan Turing提出的
-系统软件与应用软件 -桌面/网络/移动/嵌入式软件
-面向业务/个人的软件 -开源软件与专有软件
用户 应用软件 操作系统 硬件 |
软件系统的组成部分
软件不单单指程序(代码),也不单单指算法+数据结构。
软件 = 程序 + 数据 + 文档;
软件 = 模块(组件)+ 数据/控制流。
多维软件视图总览(翻译表格)
Moment | Period | |||
代码层面 | 组件层面 | 代码层面 | 组件层面 | |
构造阶段 | 源代码, AST, 接口-类-属性-方法 (类图表) | 包,文件, 静态链接, 库,测试用例,构建脚本 (组件图表) | 代码变化 (Code Churm) | 配置项,版本 |
运行阶段 | 代码快照,内存转储 | 包,库,动态链接,配置,数据库,中间件,网络,硬件(部署关系图) | 执行堆栈跟踪,并发多线程 | 多进程、事件日志,分布式进程 |
过程调用图,消息图(序列图) |
1.1构建阶段视图
软件系统的构造阶段视图
构造阶段:idea→需求→设计→编程→可安装/可执行程序包
-代码级视图:源代码——源代码是如何由基本程序块(如函数、类、方法、接口等)逻辑组织的,以及它们之间的依赖关系
-组件级视图:架构——源代码是如何按文件、目录、包、库以及它们之间的依赖关系进行物理组织的
————————————————————————
-时刻视图:源代码和组件在特定时间内是什么样子的
-时段视图:它们如何随时间发展/变化
1.1.1 构建阶段、时刻和代码级视图
源代码是如何由基本程序块(如函数、类、方法、接口等)逻辑组织的,以及它们之间的依赖关系
三种相互关联的形式:
-词汇层面:面向词法的源代码
-语法层面:面向语法的程序结构:如抽象语法树(AST)
-语义层面:面向语义的程序结构:如类图
基于词法的半结构化源代码
源代码是软件开发中最重要的资产。
半结构化:近乎自然语言的风格+遵循特定的编程语法
前者方便程序员进行编程,后者方便编译器。
面向语法的程序结构
抽象语法树(AST)
抽象语法树将半结构化的源代码表示为结构化的树
代码:
转化为树->
面向语义的程序结构
例如,使用类图(UML)来描述接口、类、属性、方法以及它们之间的关系。
通常是基于图形化或正式定义的;
在设计阶段进行建模,然后转换为代码。
它是根据用户需求进行面向对象分析和设计的结果。
语义即为我们的源代码具体想实现什么样的目标,需要我们去构建一种,把我们的源代码同在现实世界的需求联系起来的方法。我们构建一个表达需求,设计思想的图表,之后再通过编程把它转化为代码。
用图形的方式表示类之间的联系、协作的方法等。
-
-
构建阶段、Period和代码级别视图
-
描述随时间发生的“变化”的视图
代码变化:从一个版本到另一个版本向文件中添加、修改或删除的行;
代码变化(Code Churn):
代码变化定义为从一个版本到另一个版本向文件中添加、修改或删除的行。(百度生草器喜欢把它翻译成代码搅动器,我不知道wsm)
上面为从github中察看的代码改动视图;
-
-
构建阶段、时刻和组件级视图
-
源代码被物理组织成文件(files),这些文件进一步按目录(directories)组织;
文件被封装到包(packages)中,并且在逻辑上封装到组件(components)和子系统(sub-system)中。
可重用模块以库(libraries)的形式出现。
库(Library)
这里我不知道能不能翻译为共享库,应该意思和我印象中的共享库是差不多的。
库存储在它们自己的磁盘文件中,在库中收集了一组代码函数,这些函数可以在各种程序中复用。
对开发人员来说他们不总是构建单个的可执行文件,而是将自定义开发的软件和预构建的库连接到单个程序中。
在构建时,库函数可以看作是标准语言的扩展,其使用方式与开发人员编写的函数相同。开发者像使用编程语言中的指令一样使用库中的功能。
System.out.println("Hello World");
类似于使用这样一个函数一样(在java中我们叫方法罢)
库的几种来源:
- 系统预安装的一组操作库,例如文件和网络I/O、GUI、数学库、数据库评估,操作系统提供的库;
- 来自语言SDK,编程语言提供的库;
- 来自第三方来源,第三方公司提供的库;
- 开发者也可以发布他们自己的库,自己积累的库。
静态链接
在静态链接的阶段,库被视为一个由单个对象文件组成的集合。
在构建过程中,当链接器工具确定需要某个函数时,它会从库中提取适当的对象文件,并将其复制到可执行程序中
- 库会被拷贝进入代码形成整体,在执行的时候无需提供库文件。
- 库的对象文件看起来与开发人员自己创建的任何对象文件都相同。
静态链接在构造阶段发生
在链接的最终阶段会将一个可执行程序加载到目标机器上,在最终可执行程序被创建之后,程序和它的库无法分离了。
-
-
构建阶段、Period和组件级视图
-
我们在这里需要了解,各项软件的实体随时间如何变化?
SCI-软件配置项,是指在整个软件生命周期内产生的、需要进行配置管理的各项工作产品,包括文档、程序、数据、标准及规约;
Version-版本;
通过这两个概念我们可以构建出对软件实体随时间变化的模型。
不同的模块会构建出不同版本。
版本控制系统VCS
VCS是一种记录一个或若干文件内容的变化,以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的文本文件,而且可以对任何类型的文件进行版本控制。用的比较多的如svn,git等。
版本控制(Versioning)
软件版本控制是将唯一版本名称或唯一版本号分配给计算机软件的唯一状态的过程。
在给定的版本号类别(主要、次要)中,这些编号通常按递增顺序分配,并与软件中的新的改进相对应。
在细粒度级别(一个更细致的级别)上,版本控制通常用于跟踪增量不同版本的电子信息,无论这些信息是否是计算机软件。
主版本 - 附版本 - 补丁版本
1.2运行阶段视图
软件系统的运行阶段视图
运行阶段
程序在目标机器中运行时是什么样子的,目标机器需要加载到内存中的所有磁盘文件是什么?
在运行时,程序被载入目标机器,然后开始执行;
-代码层面视图:源代码----可执行程序的内存状态是什么样的,程序单元(对象、函数等)如何相互交互?逻辑实体在内存中如何实现?
-组件层面视图:架构 ---- 软件包如何部署到物理环境(操作系统、网络、硬件等)中,它们如何交互?物理的实体在物理硬件环境如何实现?
-时刻视图:程序在特定时刻的行为如何?
逻辑/物理实体在内存/硬件环境中特定时刻的形态如何?
-时段视图:它们随着时间的推移如何表现。
逻辑/实体在内存/硬件环境中的形态随时间如何变化。
可执行程序:原生机器码
程序首先加载到内存中,并且存在多种执行软件的机制,具体取决于加载程序之前进行了多少编译以及程序需要多少操作系统支持。
原生机器码(Native Machine Code)
-将可执行程序完全转换为CPU的原生机器码。
-CPU 只是简单地“跳转”到程序的起始位置,所有的执行都是纯粹使用 CPU 的硬件来执行的。
-在执行时,程序可选择调用操作系统以访问文件和其他系统资源。
-这是执行代码的最快方式,因为程序可以完全访问 CPU 的功能。
动态链接
动态链接方法不会将目标文件复制到可执行映像中; 相反,它会记录成功执行程序所需的库。库文件不会在build阶段被加入可执行软件,仅仅做出标记。
当程序开始运行时,这些库作为单独的实体加载到内存中(根据标记装载库至内存),然后与主程序连接。
动态库是通过连接目标文件构建的磁盘文件。 然后将该库收集到发布包中并安装在目标机器上。 只有这样才能将其加载到机器的内存中。在发布软件时,需要同时把程序所依赖的所有动态库都复制给用户。
所以,在实验提交到GitHub的时候,需要把各种lib都共同提交。
动态链接的优点:
可以升级到更新版本的库(添加功能或修复错误),而无需重新创建可执行程序;
许多操作系统可以通过仅将库的单个副本加载到内存中来优化其内存使用,但与需要相同库的其他程序共享它。
配置和数据文件
任何大型程序都使用外部数据源,例如磁盘上的文件。
程序调用操作系统以请求将数据读入内存:
-屏幕上显示的位图图形图像
-存储为数字化波形的声音
-一组包含在线帮助文本的文档
-包含姓名和地址的数据库
分布式程序
例如,软件系统可能使用客户端/服务器模型,在一台计算机上运行单个服务器程序,而在许多其他计算机上运行大量客户端程序。
在这种情况下,构建系统可以创建两个发布包,假设不同的人将安装服务器程序与客户端程序。
或者,可以使用相同的发布包来安装两个单独的程序。
分布式程序的运行态:需要多个运行程序,分别部署于多个计算机物理环境。
-
-
运行阶段,时刻,代码层面视图
-
代码快照图(Snapshot diagram):关注目标计算机内存中的变量级执行状态。描述程序运行时内存中变量层面的状态
程序的细粒度状态。
Memory dump(内存信息转储)
内存信息转储:硬盘上的文件,其中包含进程内存内容的副本,当进程因某些类型的内部错误或信号而中止时产生。
-调试器可以加载转储文件并显示其中包含的有关正在运行的程序状态的信息。
-信息包括寄存器的内容、调用堆栈和所有其他程序数据(计数器、变量、开关、标志等)。
-它用于分析程序的状态,程序员查看内存缓冲区以查看在失败时正在处理哪些数据项
(6)运行阶段,时段和代码层面视图
UML 中的序列图:程序单元(对象)之间的交互
Execution tracing执行跟踪
跟踪涉及专门使用日志记录来记录有关程序执行的信息,用日志的方式记录程序执行的调用次序
这通常由程序员用于调试目的,并且取决于跟踪日志中包含的信息的类型和详细信息,由经验丰富的管理员或技术支持人员以及由软件监控工具用于诊断软件的常见问题。
(7)运行阶段,时刻和组件层面视图
UML中的部署图
(8)运行时段,时段和组件层面视图
事件日志
系统层面,为系统管理员提供了对诊断和审计有用的信息。
在开发周期中会考虑将记录的不同类别的事件,以及将在事件消息中显示的详细信息。
每类事件都被分配一个唯一的“code”来格式化和输出人类可读的消息。
这有助于本地化并允许系统管理员更容易地获取有关发生问题的信息。