软件讲座
蒋炎岩老师:模型
模型:软件系统中的小小世界
计算机系统是状态机,软件也是状态机
- 真实系统的状态机过于庞大,只有化简(仅仅关注一个侧面)才能理解
如何用模型指导软件测试
软件测试实质:搞破坏
思路
小世界假设:软件bug只需要关注软件系统的一小部分即可触发,而描述bug发生实际上只需要少量信息
小世界建模:建模系统发生的关键事件,将软件测试问题变成一个搜索问题
- 操作系统对于进程,文件的抽象本质上上世纪七十年代到当今其实基本没有变化
小世界建模:建模基础系统和演化带来的特性
例如船,从帆船到航母,实际上破坏船体都会带来相似的结果,可以用相同的思想去测试,即对于测试航母,先建模一个帆船的模型,针对帆船进行测试
在操作系统内核中,可以建立一个基础的UNIX的文件系统模型,以插件的形式将现代操作系统的功能加入,对该种基础模型进行测试,一般也可以测试出来内核的问题
对于编译器:
- 程序=框架+语句
- 框架确定了控制流
- 语句确定了数据流和含义
模型:程序合成
软件的动态更新,就像是一台不会停止运行的服务器就可以运行
目标:能不能调试代码不需要重新编译(这里是编译原理的东西吗?),就不需要停止软件运行
思路:将对函数的调用改为对函数指针的调用
难题:代码改一行,数据全变样,即会导致之前数据的迁移异常
动态更新:对象状态转换,比如原本是数组,通过一个函数更新为链表的存储方式
期望:自动生成对象状态操作历史
例如对数组到链表的转换,可以生成一个序列备份这样就可以复原,
感觉挺好,但是软件复杂度上升然后就顶不住了
答案:在项目本身中
在复杂的软件项目中构造一个模型,将一个完整的项目进行拆分,拆分成小的模型和片段,将其中可以替换的部分进行更新,最后再进行一个合成,完成一个动态更新
模型:计算机系统的构造和解释
关于《操作系统》这一门课,就可以为计算机系统进行建模,所有软件都是状态机,对状态机就能进行一个模拟
为计算机硬件建模
将精简为计算机软件提供的核心机制通过C函数实现多处理器硬件的抽象,这样写操作系统不再需要汇编
为操作系统建模
从应用角度,操作系统就可以视为一组API,进行建模之后,也可以了解操作系统的实现正确性和编译器的编译正确性
总结:化繁为简”
对于无法搞懂的复杂系统,就建模成简单系统,搞清楚小的模型的原理,然后再映射回去
模型:更小的系统,更小的状态空间
- 系统=行为的总和
- 模型便于暂时忽略复杂性,化繁为简
蒋炎岩老师:安卓应用跨设备迁移
相同应用在不同设备之间会出现问题(如最简单的计算器会在屏幕尺寸不同时出现不同的显示界面)
一台机器的测试用例如果能通过但是在别的设备上可以使用,更复杂应用如word的包基本相同,但是在手机上和平板上面界面是很不一样的
软件工程中的搜索问题
软件自动化:
- 生成测试用例
- 生成代码
- 生成时间
解决方式:使用贪心方法找到相同操作的映射
搜索+剪枝
应用向更小屏幕的迁移
如手机应用向穿戴设备(手表等)迁移,将原有的移动应用界面“映射”到智能手表上(其中还要能够选出来需要的功能)
软工vs系统
- 应用:人类需求在信息世界的投影
- 系统:硬件上构建的服务系统
ai属于连接软件与系统之间的桥梁
数据库发展
预测:
智能化作用逐步加大
影响数据库发展的因素
- 软件计数
- 数据模型
- 硬件
- 计算模式
- 架构演进
- 新型应用
计算机内存管理(论文读)
[原创] 每个程序员都应该知道的内存知识 (带你走读Ulrich Drepper的经典论文)_哔哩哔哩_bilibili
重点:3,4,6章
视频1:
cpu访问速度与内存访问速度出现显著差距(CPU速度与SRAM速度显著下降,而DRAM速度提升不高,SSD相对于磁盘提升了一部分速度)
提升方法:
- 利用cpu缓存
- 改进ram架构设计
- 内存控制设计
- DMA
最初系统包括南北桥系统(北桥包含RAM内存控制器,南桥包含PCIE和USB,SATA)
演进时改进成为了一种将cpu集成的设计
当今使用SDRAM(一种DRAM,但是可以同步时钟信号)行列选通都是低电平有效
关于预充电与激活:不同芯片在行选中与下一行选中之间有时间间隔,会在其中进行准备
视频2:
存储结构:寄存器到SRAM到DRAM
冯诺依曼架构实际上使用得不太多
L1指令缓存与数据缓存是分开的,在二级缓存开始就是分开的
cpu缓存:
缓存不命中原因:
- 一开始缓存中没有任何数据(预热区间)
- 缓存容量不够用
- 发生访问冲突(如修改缓存数据时也需要同步修改主存数据)
cpu缓存具体实现:
- 全相连缓存
缓存是以行的形式存储
- 直接映射缓存
硬件实现容易
缓存容量越大,命中概率越高
写回缓存
写回:缓存数据修改会打上“脏数据”标记,在一段时间后写回主存(延时策略)
缓存替换策略:选择替换的方式,最常使用LRU(计组部分的知识)
cpu设计中有很多访问预测的部分(减少流水线停止导致的时间开销,也就是苏老师做的用ai自行判断内存访问部分)
访问时序部分:
视频3:
第四章:虚拟内存
虚拟内存映射(操作系统部分):每个程序实际上都会自动分配一定的虚拟内存,但是物理内存不足,会出现内存越界情况
如果内存中有足够一个程序(进程)运行的内存总量(总量是2G,但是是在物理地址上不连续)就没办法运行新的进程
不同进程之间由于可能占用相同的物理内存,导致改写内存呢使得相应地址的数据是“脏数据”
虚拟内存属于一种抽象。
在虚拟地址情况下,使用物理内存方式发生变化,可以灵活映射
计算机任何问题都可以通过加一层来解决
例:没有虚拟内存时候只能连续地进行映射,加上虚拟内存,如实际连续物理地址不足会映射到其它空余地方(如硬盘也行),这样进程不会崩溃
通过映射可以自由决定映射位置,即使进程使用的是同样的虚拟地址,但映射算法会映射到不同的物理地址上(哈希表解决冲突),如果几个程序需要使用同一内存,操作系统就会映射到同一个物理地址保证使用数据相同
映射是在硬件级别来做(MMU,内存管理单元),在CPU内核和内存之间
LAZY ALLOCATION:内核使用一种推迟分配内存的方式,当用户申请一块内存,操作系统(硬件)不一定马上分配这一块内存(为了优化性能),实际使用中申请一块内存,接下来使用的机会会其实很少(在链接,装载,一些库函数中也会使用到)
页:
- 页是一个内存大小单元
TLB:包含映射的东西,正常在虚拟地址上通过TLB映射到物理地址
使用Directory索引来查找在具体哪一页,完整页表放在主存中,即访问内存时可能会访问两次内存(间址寻址)
采用方法:使用硬件(TLB),TLB分为指令部分与数据部分(来加快速度),本质类似CACHE
增加TLB方法:
- 单个页变大(4k改2M,命中概率增大)
- 再增加一级TLB缓存
视频4:
很多内置库函数如new,malloc其实都是设计内存管理
大公司都在开发自己的内存分配器(如谷歌脸书等等)
行与列访问具有不同效率
TLB优化:尽量减少内存使用,