CS-Notes 笔记的笔记
附上 cs-Note的链接
概念篇
计算机操作系统
进程与线程
- 进程是资源分配的基本单位以及系统调度的单位,线程是独立调度的基本单位
- 进程控制块(PCB) :描述进程的基本信息和运行状态
- 创建或撤销线程的时候,系统都要回收资源,开销很大。但是创建或销毁进程时开销较小。另外,进程切换需要执行进程CPU环境的保存以及新调度进程CPU环境的设置,而线程切换时只需要保存和设置少量寄存器的内容
- 线程状态:
- 就绪
- 运行
- 等待/阻塞
进程同步
同步与互斥
- 同步:由于合作产生的直接制约关系,使得进程有一定的先后执行关系
- 互斥:多个进程只有一个进程能进入临界区
信号量与互斥量
- 信号量是限制同时进入临界区的线程数量的整形变量,可以进行PV操作。当信号量的值为 1 时,则成为了 互斥量。
进程通信
- 同步与通信:通过进程通信才可以更好地完成进程的同步
管道
- 匿名管道
- 只限制于父子进程以及兄弟进程中使用
- 只支持半双工通信。(在使用读管道时,就不能写;在使用时,两个文件描述符需要关闭一个)
- 命名管道
- 可以在父子进程外使用
消息队列
- 相对于FIFO(命名管道),有以下优点
- 可以根据消息类型选择性进行接收
- 独立于读写进程,不需要读写进程自己处理同步
信号量
共享内存
- 将 同一个文件加载到内存,将内存地址 映射到各个进程的地址空间,从而实现多进程对一各内存块的访问。注意:需要师兄信号量来控制内存的读写。
套接字(SOCKET)
- 可以跨机器进行通信
内存管理
分页
- 将内存分为固定大小的页面,需要经过 **内存管理单元(MMU)**将逻辑地址映射到物理地址。
- 特点:无外碎片-即页面与页面之间没有空间,但是存在内碎片(即页面之内有空余的空间)
分段
- 分段的产生,可以解决一些问题:
- 安全性和共享内存:相同类型的类型在同一个段,可以限制对其的操作
- 溢出保护:因为段是有范围的,可以识别是否访问段外的地址
- 减少重新编译代价:因为不同类型的数据放在不同的段,因此其中一个段改变,就不需要所有的段都重新编译
分页与分段
- 分页对程序员是透明的,但是分段是程序员可以感知到的。分段是将类似 常量段,代码段,堆栈段等放在不同的虚拟空间以免出现数据段之间因数据动态增长出现相互覆盖的情况。
- 分页的逻辑地址是一维地址,分段的是二维地址。所谓的n维则是需要进行n次转换才能获得真正的物理地址。
文件系统
inode
- 因为
inode
对应的目录不会储存子文件的文件名,因此需要重命名子文件、删除文件、新增文件其实都是对目录的操作,而不是对文件本身的操作,故进行重命名文件操作需要拥有目录的写权限,而不是该文件的写操作。
数据流重定向
1 | 代码 | 运算符 |
---|---|---|
标准输入 (stdin) | 0 | < 或 << |
标准输出 (stdout) | 1 | > 或 >> |
标准错误输出 (stderr) | 2 | 2> 或 2>> |
>> 表示追加在原文件 |
孤儿进程
父进程已经退出,但是子进程还在运行的进程。会由init
进程(进程号为 1)将他们回收
僵尸进程
由于父进程没有调用子进程的wait()
或waitpid()
,因为子进程退出后进程描述符不会被释放,导致有限的进程描述符被长久占用而不能产生新的进程。解决办法是:将父进程杀死,子进程就会变成孤儿进程从而被回收。
HTTP
HTTP/1.0
- 缺点:默认关闭
Keep-Alive
导致每次请求都需要经过TCP三次握手,成为短链接。
HTTP/1.1
- 默认开启
Keep-Alive
,但是还是存在不能并发的问题,如果需要并发则必须要建立新的连接 - 支持流水线,即无需等待response的到来即可再次request
- 头部重复但却没有进行压缩
HTTP/2.0
增加了几个优化
- 多路复用: 可以使用一个TCP连接实现并发传输
- 二进制帧: 通过给每各帧进行编号,就可以实现并发有序了。
- 压缩头部: 由于头部信息基本不变,可以只传变化的头部,同时使用压缩算法如果
Huffman
编码进行压缩。 - 服务器推送: 当请求主页 html 时,同时返回 关联的 css以及 js文件。从而减少客户端的请求,直接从缓存中取出。
额外参考链接:
面向对象思想
设计原则(S.O.L.I.D)
单一责任原则
- 一个类只负责一件事情。当这个类需要做的事情太多,则需要分解。
开放封闭原则
- 对扩展开放,对修改关闭
- 经典设计模式是 装饰者模式
里氏替换原则
- 子类对象必须能够替代所有的父类对象
接口分离原则
- 不应该强迫客户依赖于他们不用的方法
- 所以比起使用多个专门的接口,使用单一的总接口要好
依赖倒置
高层模块不应该依赖于具体低层模块,两者都应该依赖于抽象模块
抽象不依赖细节,细节应该依赖于抽象
其他设计原则
迪米特法则
最少知识原则,一个对象应该对其他对象有尽可能少的了解,并不和陌生人说话
合成复用原则
组合优于继承
共同封闭原则
一起修改的类,应该组合在一起(同一个包里)。并不希望修改应用程序里的代码遍布很多包,而是在同一个包里。
稳定抽象原则
最稳定的包应该是最抽象的包,不稳定的包应该是具体的包
稳定依赖原则
包的依赖关系应该是向稳定方向依赖的,就是说自身依赖的包要比自身更加稳定
数据库系统原理
事务的ACID
A-原子性(Atomicity)
事务视为最小不可分割单元,一个事务的提交要么全部提交,要么全部失败。可以通过回滚日志来实现
C-一致性(Consistency)
数据库在执行事务前后都保持一致的状态,在一致性的状态下,所有事务对同一个数据的读取结果都是相同的。
I-隔离性(Isolation)
一个事务所作的修改在最终提交以前,对其他事务是不可见的。
D-持久性(Duration)
算法篇
进度调度算法
1. 批处理系统
目的是保证吞吐量以及周转时间最短(从提交到终止的时间)
- 先来先服务(FCFS)
- 特点:有利于长作业
- 缺点:不利于短作业,因为短作业需要执行的时间很短,但是却需要等很久。
- 短作业优先(SJF)
- 特点:短作业优先
- 缺点:会导致长作业饿死
- 最短剩余时间优先(SRTN)
- 特点:当一个新作业到达时,将其整个运行时间与当前进程的剩余时间作比较,较短的进程获得调度
2. 交互式系统
目的是快速地对用户的交互进行响应。
- 时间片轮转
- 特点:将所有就绪的进程按 FCFS 的原则排队,每个进程轮流获得资源,其占用资源的时间相等
- 缺点:如果时间片过长,实时性无法得到保证。如果时间片过短,则会在浪费很多时间在进程切换上。
- 优先级调度
- 特点:根据优先级高低进行调度
- 缺点:可能会让优先级低的进程获取不到调度
- 多级反馈队列
- 特点:设置多个队列,每个队列获得的时间片长短不一样,队列获得时间片越多,优先级越低(可以当成其数学期望是一样的)。融合了时间片轮转调度算法以及优先级调度算法。可以实现 将 本来是用时间片调度算法切换100次的作业,切换次数减少至 7次(1,2,4,8,16,32,64)
- 特点:设置多个队列,每个队列获得的时间片长短不一样,队列获得时间片越多,优先级越低(可以当成其数学期望是一样的)。融合了时间片轮转调度算法以及优先级调度算法。可以实现 将 本来是用时间片调度算法切换100次的作业,切换次数减少至 7次(1,2,4,8,16,32,64)
死锁解决方式
鸵鸟策略
直接忽略
死锁检测
-
资源的数量都只有一个的情况下:
- 检查资源分配有向图是否存在环来判断是否死锁。
下图的方框代表资源,圆圈代表进程,箭头指向为资源分配情况
-
资源数量不仅是一个的情况下:
- 算法详情:
- 算法详情:
死锁预防
- 死锁必要条件
- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
破坏办法:只有一个进程能真正能获取到进程。如 假脱机打印机技术。
- 占有和等待:已经得到了某个资源的进程可以再请求新的资源。
破坏方法:进程需要一次性 获取所有资源
- 资源不可以抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
破坏办法:优先级高或权限高的进程可以直接抢夺资源
- 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
破坏办法:给资源统一编号,只能按编号顺序来请求资源。如,要获取编号为 n+1的资源就必须先拿到编号为 n 的资源。
死锁避免
- 每个资源分配决策前,要检测本次资源分配是否会让系统进入不安全的状态,即可能会产生死锁
- 死锁避免的算法与 死锁检测 算法相似。也称为银行家算法。
- 特点:这种解决方式较为严格,因为就算系统进入不安全的状态,如果没按某种调度顺序执行进程,就有可能没产生死锁。
页面置换算法
最佳算法(OPT)
- 实现:所选择的被换出的页面将是最长时间不被访问的
- 缺点:没有人可以预知未来,所以CPU不知道未来会加载那些页面
最近最久未使用(LRU)
- 实现:维护一个页面使用记录的链表,每次使用调用某一个页面后将页面放在表尾,这样位于表头的页面将是最久未被使用的页面。
- 缺点:每次调用都得调整链表,代价高
最近未使用
- 实现:每个页面有两个状态位:R(read) 与 M(modified) ,当页面被读以及被修改相应置 1;R位会被定时清零。当缺页时,优先换出 类编号最小的 页面。编号如下:
R = 0, M = 0
R = 0, M = 1
R = 1, M = 0
R = 1, M = 1
- 思想:换出一个被修改的脏页面比换出一个被频繁使用的干净页面要好。
先进先出(FIFO)
- 实现:先进来的页面优先换出
- 缺点:程序的局部性原理说明,程序执行一段指令(访问一个页面),不久的将来也会执行这段指令(访问这个页面),所以这样会导致缺页率增加。
第二次机会算法
- 实现:设置 R 标志位,当被访问时置 1。当需要置换页面时,从页面链表表头搜索,当一个R位为0,则立即换出;当一个R位为 1,则置 0 并挪到链表表尾。
- 特点:表头表示最老的页面(不一定最老就得被换出去),表尾表示最年轻的页面
- 缺点:跟最近最久未使用缺点类似,每次都得调整表头以及表尾。
时钟算法
- 实现:跟第二次机会算法类似,不过把链表变为循环链表,就不需要挪动链表了。
磁盘调度算法
先来先服务(FCFS)
最短寻道时间优先(SSTF)
- 特点:优先调度在当前磁头所在磁道距离最近的磁道。
- 缺点:容易出现磁头两端的请求出现饥饿
电梯算法(SCAN)
- 实现:总是沿着一个方向处理请求,直到这个方向不会再有请求则改变运行方向。