OO_第三单元
测试策略黑箱测试
别称:功能测试、封闭盒测试或基于规格说明的测试
定义:测试人员不需要了解被测试对象的内部逻辑结构、内部特性或源代码,仅关注测试对象的输入和输出,检查测试对象是否按照需求规格说明书的规定正常工作。
理解:进行黑箱测试仅得到输入与输出,设计测试案例时,需要保证覆盖符合规格说明书的所有范围(包含功能、边界等),以及保证输出对应相应的输入要求。
白箱测试
别称:结构测试、透明盒测试或基于代码的测试
定义:测试人员需要了解被测试对象的内部逻辑结构、内部特性和源代码,基于这些内部信息来设计测试用例,以检查测试对象的内部结构和代码是否按预期工作
理解:进行白箱测试可得到输入与输出以及测试对象的源代码,需要了解其内部逻辑结构以及内部特性,故除了进行黑箱测试的相同测试外,还可进行依据上述信息针对性地测试,测试其逻辑结构是否正确的
单元测试
内容:针对软件的最小可测试单元(通常是代码中的一个模块、方法或类)进行测试
特性:每个单元测试间自动,独立运行,可设定条件进行针对测试
编写方法:
完成测试用例的编写,即数据生成
本课程中使用的测试框架为Junit,对不同单元根据JML规格 ...
OO_第二单元
题目概况结合三次作业,模拟多线程实时电梯系统,模拟对象是一个类似北京航空航天大学新主楼的电梯系统,楼座内有多部电梯,电梯可以在楼座内1-11层之间运行。系统从标准输入中读入乘客请求信息(起点层,终点楼层),请求调度器会根据此时电梯运行情况(电梯所在楼层,运行方向等)将乘客请求合理分配给某部电梯,然后被分配请求的电梯会经过上下行,开关门,乘客进入/离开电梯等动作将乘客从起点层运送到终点层。请求的输入通过我们提供的输入接口来定时投放请求,直接调用官方提供的接口即可。
可以采用任何调度策略,即任意时刻,系统选择上下行动,是否在某层开关门,乘客分配给哪部电梯都可以自定义,只要保证在电梯系统运行时间不超过题目要求时间上限的前提下将所有的乘客送至目的地即可。
电梯重置接收到重置指令的电梯需要尽快停靠后完成重置动作,再投入电梯系统运行。为安全起见,电梯重置时内部不可以有乘客,且重置动作**需要时间$T_{reset}=1.2s$。
有两种重置请求:
第一类重置请求仅修改电梯参数,重置参数请求包含需要重置的电梯ID和电梯相关参数(满载人数、移动时间)。程序需要在重置完成后让电梯以新的参数运行,重置 ...
OOpre_总结
架构设计
迭代调整与考虑
按照指导书要求创建Main,Adventurer,Bottle,Equipment,Food等基础类,按照属性的含义以及方法的功能放入不同的类当中,未考虑类与类之间的联系
随着指令的增加,需要更多的类来实现指令,发现类与类之间有许多重复与交叉的部分,可以通过继承与接口的方式来减少代码重写,增强类与类之间的联系
指令的实现若具有一定的复杂性,需要应用设计模式才能更为完善地实现指令,例如单例模式即可构造Store类,实现单一实例并直接访问的类,以及观察者模式,定义一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
补充:主函数可以通过调用命令模式来实现指令,建立抽象指令,具体指令(指令对象),但未能完善。使用junit的心得体会
在使用junit单元测试时,通过输入自己的测试代码,利用Assert语句判断输出是否符合自己预期,检测代码是否正确运行,并可以通过查看类,方法,行,分支覆盖率来查看自行编写的代码是否充分测试。
直接在主函数中输入测试代码学习oopre的心得体会
以正确输出为目的:刚开始接触java语言感到陌生与害怕,并为使用新的编程 ...
OS_挑战性任务-Sigaction
挑战性任务报告
首先想要吐槽一点,由于要求不能对Makefile进行修改,导致不能将自己编写的文件链接入可执行文件当中,导致只能把自己写的函数挤压进已有文件当中,显得有点丑陋
本实验需要实现异步通信Sigaction,仅需关注32个普通信号中的6个信号,按照其信号处理函数或默认处理动作来处理,其余忽略即可。
信号数据存放位置由于考虑到不同进程需要存储自己的信号,便于在从内核态返回用户态时直接查询使用,故放置在进程控制块Env结构体内
信号选择由于指导书要求同一普通信号在进程中最多只存在一个,故只要考虑不同信号间的优先级即可,同时要考虑当前进程正在处理的信号的屏蔽集。( 对于SIGKILL信号,该信号不可被阻塞)
内核态到用户态的准备参考助教在讨论区的建议,需要进程从内核态返回至用户态过程中检查是否有信号进行处理,若有,则处理完后再返回中断位置,这就需要使用重新申请一个栈帧用于当前信号的处理,设置传参等,以及保存进程发生中断时的现场。(一个比较好玩的地方在于当完成信号处理后会调用系统调用syscall_set_trapframe恢复原来的栈帧,这个时候既恢复现场(重新设置cp0_e ...
OS_Lab6
Thinking 6.1
示例代码中,父进程操作管道的写端,子进程操作管道的读端。如果现在想让父进程作为“读者”,代码应当如何修改?
123456789101112131415161718192021222324252627282930313233343536#include <stdlib.h>#include <unistd.h>int fildes[2];char buf[100];int status;int main(){ status = pipe(fildes); if (status == -1) { printf("error\n"); } switch (fork()) { case -1: break; case 0: /* 子进程 - 作为管道的写者 */ close(fildes[0]); /* 关闭不用的读端 */ write(fildes[1], "Hello world\n", 12); /* 向管道中写 ...
OS_Lab5
Thinking 5.1
如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。请思考:这么做这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和 IDE 磁盘)的操作会有差异吗?可以从缓存的性质和缓存更新的策略来考虑。
answer:
缓存Cache是为了提高CPU访问数据的速度,但只有在外部设备进行数据更新或缓存Cache空间不足时,缓存数据才会被写入内存,故在外部设备更新数据时,CPU可能从外设(外部设备对应的内存空间)读入更新前的数据,故引发错误。
串口设备通常是字符设备,按照字节或字符进行数据传输,传输数据的频率高,IDE磁盘是块设备,按块进行数据传输,传输数据的频率低,故前者引发问题的概率大于后者
Thinking 5.2
查找代码中的相关定义,试回答一个磁盘块中最多能存储多少个文件控制块?一个目录下最多能有多少个文件?我们的文件系统支持的单个文件最大为多大?
answer:
宏FILE_STRUCT_SIZE表示文件结构体的大小256B,一个磁盘块的大小为4KB, ...
OS_Lab4
Thinking 4.1
思考并回答下面的问题:
内核在保存现场的时候是如何避免破坏通用寄存器的?
系统陷入内核调用后可以直接从当时的 $a0-$a3参数寄存器中得到用户调用 msyscall留下的信息吗?
我们是怎么做到让 sys 开头的函数“认为”我们提供了和用户调用 msyscall 时同样的参数的?
内核处理系统调用的过程对 Trapframe 做了哪些更改?这种修改对应的用户态的变化是什么?
answer:
内核通过调用宏SAVE_ALL,先保存$sp,$v0两个寄存器,协助将通用寄存器保存在栈空间Trapframe中
可以,因为系统陷入内核调用时,当时的 $a0-$a3参数寄存器并未被修改,可以得到用户调用 msyscall留下的信息。
用户函数syscall_*到内核函数sys_*,$a0-$a3寄存器不会被破坏,也可直接通过内核栈获取
```bashtf->cp0_epc += 4;tf->regs[2] = func(arg1, arg2, arg3, arg4, arg5);
1234567891011121314151617181920212 ...
OS_Lab3
Thinking 3.1
请结合 MOS 中的页目录自映射应用解释代码中 e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V 的含义。
解释:
该代码设置进程控制块e的页目录下虚拟地址UVPT映射到其本身的物理地址,并设置为只读权限。该页目录项所指向的为一个二级页表,但通过地址判断还是一个一级页表,即页目录自身,这就是页目录的自映射。
分析:
读取该虚拟地址PDX(UVPT)[31:22]PDX(UVPT)[31:22]0000_0000_0000_0000的数据,首先读取页目录项(e->env_pgdir[PDX(UVPT)]),得到二级页表的基地址(物理地址)PADDR(e->env_pgdir) | PTE_V,该二级页表与一级页表为同一个页表,所读取的页表项与一开始读取的页目录项相同,为e->env_pgdir[PDX(UVPT)],最终得到数据PADDR(e->env_pgdir) | PTE_V,所得到的页表为页目录本身,即为自映射。
Thinking 3.2
elf_load_ ...






