最近看了软件构造的概论,略有思考,便整理了一下
软件构建时:
- 时刻
代码级别:源代码,抽象语法树,内部类属性方法
组件级别:包,源文件,静态链接库,测试用例
- 时期
代码级别:代码变化
组件级别:环境项目
运行时:
- 时刻:
代码级别代码快照、内存dump
组件级别:包,动态链接库、环境、数据库、中介软件、网站、硬件
- 时期:
代码级别:执行轨迹、过程调用图,消息图(序列图)并行和多线程/进程分布式进程
组件级别:时间日志、过程调用图,消息图(序列图)并行和多线程/进程分布式进程
代码级视图:源代码----源代码如何通过基本程序块(如函数,类,方法,接口等)以及它们之间的依赖关系进行逻辑组织
组件级视图:体系结构----源代码如何按文件,目录,包,库以及它们之间的依赖关系进行物理组织
-
Lexical-oriented source code(面向词法)
-
Syntax-oriented program structure: e.g., Abstract Syntax Tree (AST)(面向语
法) -
Semantics-oriented program structure: e.g., Class Diagram (面向语义)
在静态链接中,库是单个对象文件的集合。
运行时:程序在目标机器内运行时的样子是什么,目标机器需要加载到内存中的所有磁盘文件是什么?
-
代码级视图:源代码----可执行程序的内存状态是什么样的,程序单元(对象,函数等)如何相互交互?
-
组件级视图:体系结构----如何将软件包部署到物理环境(操作系统,网络,硬件等)以及它们如何交互?
程序首先被加载到内存中,并且存在几种用于执行软件的机制,这取决于在加载程序之前进行了多少编译以及程序需要多少OS支持。
▪本机代码:(完全转换为CPU能识别的机器码)
- 将完全转换的可执行程序转换为CPU的本机代码。
CPU只是“跳转”到程序的起始位置,所有执行都是纯粹使用CPU的硬件执行的。
-
当它正在执行时,程序可选择调用操作系统来访问文件和其他系统资源。
-
这是执行代码的最快方法,因为程序完全访问CPU的功能。
完整程序解释:运行时系统将整个源代码加载到内存中并对其进行解释(例如BASIC,UNIX shell等)
解释的字节代码:
-
字节代码类似于本机代码,除了CPU不直接理解它们。
程序被编译成字节码形式(如java的类文件) -
它首先将它们转换为本机机器代码或在程序执行时将它们解释。
因此,字节代码环境要求在程序旁边加载一个额外的解释器或编译器。运行时需要由解析器转换成机器码或者解释执行。
即预编译字节码àjava
VM和JIT编译器à机器码àOS
动态链接方法不会将目标文件复制到可执行映像中; 相反,它指出了成功执行程序所需的库。
不会目标文件复制到可执行程序中,而是会标标用到的类库
▪当程序开始运行时,库作为单独的实体加载到内存中,然后与主程序连接。
在运行时,加载用到的库到内存中,然后同主程序链接
▪动态库是通过连接目标文件构建的磁盘文件。 然后将库收集到发行包中并安装在目标计算机上。
只有这样它才能加载到机器的内存中。部署时需要将用到的类库同程序一起部署
类库变化时,不需要重新生成可自行程序,多个运行中程序可共享同一类库,优化内存使用
分布式程序:
例如,软件系统可能使用客户端/服务器模型,其中一台服务器程序在一台计算机上运行,而大量客户机程序在许多其他计算机上运行。
▪在这种情况下,构建系统可以创建两个发布包,因为不同的人将安装服务器程序而不是客户端程序。
▪或者,可以使用相同的发行包来安装两个单独的程序。
日志:每类事件都要分配一个唯一的“代码”来格式化和输出人类可读的消息。这有利于本地化,并使系统管理员能够更容易地获得有关出现问题的信息。
可见, 软件构造是一个比较完整的体系