oo-unit4
OO Unit4 Summary
回顾一下第四单元完成的任务:利用UML进行正向建模,并完成一个小型的图书馆管理系统
hw13:实现借阅,预约,预约取书,还书等基本流程
hw14: 实现图书室借阅功能,并增加热门书架与普通书架
hw15:引用用户信用积分限制
一、正向建模与开发
正向建模与开发是一种软件工程方法,主要用于系统设计和实现过程中,特别是在软件开发和硬件设计领域。这种方法从高层次的需求和概念开始,逐步细化和分解,直到实现细节,整个过程类似于从宏观到微观的构建方式。正向建模与开发强调从抽象到具体、从整体到部分的设计思想,有助于确保系统设计的连贯性和完整性,便于团队成员理解整个系统的工作原理。
OO作业是迭代性任务,一个良好的初期架构对于后期作业的顺利完成是十分重要的,本单元中,课程组的初衷是先绘制UML类图等进行正向建模,并据此进行后续开发。对此,我的做法是首先设计整体框架,抽象出主要类例如书架、借还处、预约处等类,将类聚合到一个总体类图书馆中,对不同操作抽象出一些大的方法,得到一开始的粗略图。在图书馆类中针对不同操作抽象方法,调用不同的组成部分调用其内部具体实现方法, ...
BUAA-OS-LAB5
BUAA OS LAB5 实验报告
Thinking
Thinking 5.1
Q:
如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是 一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。
请思考:这么做 这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和IDE磁盘)的操作会 有差异吗?可以从缓存的性质和缓存更新的策略来考虑。
A:
当外部设备更新数据时,Cache中旧的数据可能刚刚缓存,那么完成缓存的这一部分无法完成更新,则会发生错误。
对于串口设备来说,读写更加频繁,信号密集,在相同的时间内发生错误的可能性远高于IDE磁盘。
Thinking 5.2
Q:
查找代码中的相关定义,试回答一个磁盘块中最多能存储多少个文件控制 块?一个目录下最多能有多少个文件?我们的文件系统支持的单个文件最大为多大?
A:
一个文件控制块的大小为256B ,那么一个磁盘块4KB最多存储4KB/256B=16 个文件控制块。
一个目录 = 一个磁盘块全部用来存目录项,又一个目录项32位=4B;则一个目录 4KB ,一个目录中有 4KB/4B=1 ...
BUAA-OO-unit3
OO Unit3 Summary
架构设计梳理:
HW9:
重点架构设计:
第一次作业整体上难度不大,但是需要对jml的实现细节考虑周全,对于一些开销较大的方法需要动态维护以降低时间复杂度,容器尽量使用HashMap等速度较快的。以下列出一些重点方法的实现。
iscircle:
采用朴素bfs加一个visited的map实现去重访问。
queryTripleSum:
采用动态维护,对于添加关系和删除关系,相当于增加或者删除了两人的公共好友数量的三元环。
queryBestAcquaintance:
加入时动态维护最大值,删除时如果删除了最大值重新遍历得到最大值。
getAgeavg/var:
方差和平均数动态维护,注意方差的书写需要考虑整除带来的影响
1return (agesquaresum - 2 * agesum * mean + n * mean * mean) / n;
bug分析和遇到的问题:
第一次测试和舍友对拍了许多测试点,公测功能没出现问题,性能卡了一个点,原因是queryTripleSum一开始采用一种将无向图根据度数转换为有向图的方法,复杂度为O($n\sqrt{ ...
BUAA-OS-LAB4
BUAA OS LAB4 实验报告
Thinking
Thinking 4.1
Q:
思考并回答下面的问题:
•内核在保存现场的时候是如何避免破坏通用寄存器的?
•系统陷入内核调用后可以直接从当时的$a0-$a3参数寄存器中得到用户调用msyscall 留下的信息吗?
•我们是怎么做到让sys开头的函数“认为”我们提供了和用户调用msyscall时同样 的参数的?
•内核处理系统调用的过程对Trapframe做了哪些更改?这种修改对应的用户态的变化是什么?
A:
在 SAVE_ALL 中:
先 move k0,sp,先把通用寄存器的sp复制到$k0 ;
再 sw k0,TF_REG29(sp)、sw $2,TF_REG2(sp):保存现场需要使用$v0作为协寄存器到内存的中转寄存器,写到内存时需要sp ,所以在正式保存协寄存器和通用寄存器前先保存这两个寄存器。
可以。
从用户函数 syscall_*() 到内核函数 sys_*() 时,$a1−$a3 未改变,$a0在handle_sys() 的时候被修改为内核函数的地址,但在内核函数 sys_*() 仅为占位符,不会被用到。同时 ...
BUAA-OO-unit2
OO Unit2 Summary
hw5:
架构设计:
MainClass负责输入,并将对应的Request委派给RequestTable,对应楼座的电梯Elevator通过RequestTable获取请求。这里,我还额外将存储Request的容器封装为一个RequestTable类,这将有利于未来迭代时自由分配指派电梯id。输入线程为主线程,向RequestTable 输入请求,使用线程安全list存储,SafeOutput实现输出安全。
Contorler方法类控制电梯单独行为,获取目标楼层、电梯运动开门等。
生产者:输入线程MainClass
托盘:候乘表RequestTable
消费者:电梯线程Elevator
生产者输入线程获取输入,投放到候乘表RequestTable,消费者电梯线程自己运行,同时扫描RequestTable,找到对应id的乘客后运行。
协作图:
调度:
第一次作业不涉及电梯id的分配,只需考虑单电梯的运行策略。
look算法:
当电梯有乘客时,以乘客中目标楼层距离当前楼层最远的请求为主请求确定目标楼层
当电梯没有乘客时,首先按照原方向,寻找距离 ...
BUAA-OS-LAB3
BUAA OS LAB3 实验报告
Thinking
Thinking 3.1
Q:
请结合MOS中的页目录自映射应用解释代码中e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V 的含义。
A:
UVPT为整个页表起始虚拟地址,e->env_pgdir[PDX(UVPT)为其对应的一级页表项,即为一个二级页表的基地址,PADDR(e->env_pgdir) | PTE_V 为整个页表起始的物理地址,该语句作用为将页目录自身物理地址映射为自身其中的一个一级页表项。
Thinking 3.2
Q:
elf_load_seg以函数指针的形式,接受外部自定义的回调函数 map_page。请你找到与之相关的data这一参数在此处的来源,并思考它的作用。没有这个参数可不可以?为什么?
A:
来源:
在include/elf.h中可以找到typedef int (*elf_mapper_t)(void *data, u_long va, size_t offset, u_int perm, const void ...
BUAA-OS-LAB2
BUAA OS LAB2 实验报告
Thinking
Thinking 2.1
Q:
请根据上述说明,回答问题:在编写的 C 程序中,指针变量中存储的地址 被视为虚拟地址,还是物理地址?MIPS 汇编程序中 lw和sw 指令使用的地址被视为虚 拟地址,还是物理地址?
A:
实际程序中,访存、跳转等指令以及用于取指的PC寄存器中的访存目标地址都是虚拟地址。我们编写的C程序中中指针的值也是虚拟地址。
Thinking 2.2
Q:
•从可重用性的角度,阐述用宏来实现链表的好处。
•查看实验环境中的/usr/include/sys/queue.h,了解其中单向链表与循环链表的实 现,比较它们与本实验中使用的双向链表,分析三者在插入与删除操作上的性能差 异。
A:
宏的的特性就是可重复使用。当这段代码的具体实现需要更改时,只需要改宏这一处就行。宏相比函数由于是字符串的替换,因此不必进行地址的跳转和栈的保存。
在实验环境中,只看到了单向链表、双向链表、单向队列、双向队列、循环队列,感觉循环队列在插入和删除操作方面和循环链表没太大差异,据此进一步分析。
**插入操作:**单向链表插入操作十 ...
BUAA-OS-LAB1
BUAA OS LAB1 实验报告
Thinking
Thinking 1.1
Q:
在阅读附录中的编译链接详解以及本章内容后,尝试分别使用实验环境中 的原生 x86 工具链(gcc、ld、readelf、objdump 等)和 MIPS 交叉编译工具链(带有 mips-linux-gnu- 前缀,如 mips-linux-gnu-gcc、mips-linux-gnu-ld),重复其中的编 译和解析过程,观察相应的结果,并解释其中向objdump传入的参数的含义。
A:
编写程序hello.c
123456#include <stdio.h>int main(){ printf("Hello World!\n"); return 0;}
这里只截取.text部分
x86 .o
123456789101112131415am.o: 文件格式 elf64-x86-64Disassembly of section .text:0000000000000000 <main>: 0: f3 0f ...
BUAA-OO-unit1
OO Unit1 Summary
基于度量的代码分析与迭代过程
注:
CogC是认知复杂度,衡量代码的难以理解的程度,CogC说明代码比较难以理解。
ev(G)是基本复杂度,衡量非结构化程度,ev(G)高意味着难以模块化和维护。
iv(G)是模块设计复杂度,衡量模块的调用关系,iv(G)高意味着模块之间的耦合性高,难以隔离和复用。
v(G)是圈复杂度,衡量结构的复杂程度,v(G)是说明代码难以测试和维护。
hw1
重点思路及迭代过程:
修改项的定义,实现将表达式分为不剩下符号的一个个项
term ---->[+-]{0,2} factor 修改定义实现多余符号匹配
项符号去多余判断符号,累加
因子,累乘,最后结果符号设置为项
原子组和慵懒防止递归爆炸
递归处理表达式因子,正则每次匹配内层,但是有特殊情况如下
((x-1))*((x-1)),判断匹配结果表达式后有*取消计算,防止错误匹配的表达式因子
类图:
PatternString类存储所有需要使用的正则表达式,防止重复声明,Simplify为顶层化简函数,内含有化简表达式、化简项、化简因子 ...
BUAA-OS-LAB0
BUAA OS LAB0 实验报告
Thinking
Thinking 0.1
Q:
• 在前述已初始化的~/learnGit 目录下,创建一个名为 README.txt 的文件。执 行命令git status > Untracked.txt(其中的 > 为输出重定向,我们将在 0.6.3 中 详细介绍)。
• 在README.txt 文件中添加任意文件内容,然后使用 add 命令,再执行命令 git status > Stage.txt。 • 提交README.txt,并在提交说明里写入自己的学号。
• 执行命令cat Untracked.txt 和 cat Stage.txt,对比两次运行的结果,体会 README.txt 两次所处位置的不同。
• 修改README.txt 文件,再执行命令git status > Modified.txt。
• 执行命令cat Modified.txt,观察其结果和第一次执行 add 命令之前的 status 是 否一样,并思考原因。
A:
分别处于未追踪,待提交
commit后处于已提交的状态,status里不可见
...