手把手教你如何玩转面试(操作系统) PCB IPC

2019-07-14 11:18发布

手把手教你如何玩转面试(操作系统)

2018年10月18日 15:57:01 Cs_hnu_scw 阅读数:852 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cs_hnu_scw/article/details/79896500

        本篇是讲解关于JavaWeb岗位面试方面的一些对于操作系统知识的整理,当然,不只是需要知道这个方面的内容,还需要掌握其他方面的知识,我都根据自己的经历来进行了整理,方便大家进行系统化的学习,只有多复习多研究,才能对技术有更好的掌握,才能拿到更好的offer。

下面是其他方面的知识点,欢迎大家进行浏览 Java基础:https://blog.csdn.net/Cs_hnu_scw/article/details/79635874 数据结构:https://blog.csdn.net/Cs_hnu_scw/article/details/79896717 Web方向:https://blog.csdn.net/Cs_hnu_scw/article/details/79896165 数据库:https://blog.csdn.net/Cs_hnu_scw/article/details/82900559 计算机网络:https://blog.csdn.net/Cs_hnu_scw/article/details/79896621 其他方面的知识:https://blog.csdn.net/Cs_hnu_scw/article/details/79896876 思维导图github地址:git@github.com:qq496616246/MindMapping.git 或者 https://github.com/qq496616246/MindMapping.git

一:操作系统总览

1:操作系统的组成部分有哪些?

(1)进程管理(Processing management):这里就引出了操作系统中的进程和线程的问题
(2)内存管理(Memory management):这里就引出了对于内存的内容,比如段式,页式,段页式和虚拟内存的内容;
(3)文件系统(File system):
(4)网络通讯(Networking)
(5)安全机制(Security)
(6)用户界面(User interface)
(7)驱动程序(Device drivers)

2:操作系统的特征

(1)并发:同一段时间内多个程序执行(注意区别并发和并行,前者是同一时刻的多个事件,后者是统一时间段内的多个事件)
(2)共享:系统中的资源可以被内存中多个并发执行的进线程共同使用
(3)虚拟:通过时分复用(如分时系统)以及空分复用(如虚拟内存)技术实现把一个物理实体虚拟为多个
(4)异步:系统中的进程是以走走停停的方式执行的,且以一种不可预知的速度推进

3:操作系统的主要功能

(1)处理机管理:处理机分配都是以进程为单位,所以处理机管理也被看做是进程管理。包括进程控制,进程同步,进程通信和进程调度
(2)存储器管理(或者内存管理):内存分配,内存保护,地址映射,内存扩充
(3)设备管理:管理所有外围设备,包括完成用户的IO请求;为用户进程分配IO设备;提高IO设备利用率;提高IO速度;方便IO的使用
(4)文件管理:管理用户文件和系统文件,方便使用同时保证安全性。包括:磁盘存储空间管理,目录管理,文件读写管理以及文件共享和保护
(5)提供用户接口:程序接口(如API)和用户接口(如GUI)  

4:操作系统的主要目标是什么?

答:1)、方便性:操作系统使计算机更易于使用    
2)、有效性:操作系统允许以更有效的方式使用计算机系统资源。    
3)、可扩充性:在操作系统中,允许有效地开发,测试和引进新的系统功能。   
4)、开放性:实现应用程序的可移植性和互操作性,要求具有统一的开放的环境

二:进程和线程相关知识点

1:创建进程的原因有哪些?

(1)系统初始化
(2)执行了从事创建进程的一个系统调用,该系统调用被正在运行的进程所调用。
(3)用户请求创建一个新进程
(4)一个批处理作业的初始化

2:进程的组成部分有哪些?

①程序。作用:描述进程要完成的功能。
②数据集合。作用:程序在执行时所需要的数据和工作区。
③程序控制块。作用:包含进程的描述信息和控制信息。它是进程存在的唯一标志。

3:进程创建的过程

1) 申请空白PCB。为新进程申请获得唯一的数字标识符,并从PCB集合中索取一个空白PCB。
2) 为新进程分配资源。为新进程的程序和数据以及用户栈分配必要的内存空间。显然,此时操作系统必须知道新进程所需要的内存大小。
3) 初始化进程控制块。PCB的初始化包括:
    ①初始化标识信息,将系统分配的标识符和父进程标识符,填入新的PCB中。
    ②初始化处理机状态信息,使程序计数器指向程序的入口地址,使栈指针指向栈顶。
    ③初始化处理机控制信息,将进程的状态设置为就绪状态或静止就绪状态,对于优先级,通常是将它设置为最低优先级,除非用户以显式的方式提出高优先级要求。
4) 将新进程插入就绪队列,如果进程就绪队列能够接纳新进程,便将新进程插入到就绪队列中。

4:进程销毁的原因有哪些?

(1)进程执行完,正常退出。(自愿的)
(2)进程执行过程中,出错退出。(自愿的),比如:试图打开不存在的文件
(3)进程执行过程中,出现严重错误。(非自愿的),比如执行了非法指令,除数是零
(4)被其他进程杀死。(非自愿的)比如,某个进程执行一个系统调用通知操作系统杀死某个其他进程。  

3:进程和程序之间的区别?(进程与线程之间的区别在前面的知识点已经说了)

(1)进程是程序及其数据在计算机的一次运行活动,是一个运行过程,是一个动态的概念。进程的运行实体是程序,离开程序的进程没有存在的意义。而程序是一组有序的指令集合,是一种静态概念。
(2)进程是程序的一次执行过程,它是动态地创建和消亡的,具有一定的生命周期,是暂时存在的;而程序则是一组代码的集合,它是永久存在的,可长期保存。
(3)一个进程可以执行一个或几个程序,一个程序也可以构成多个进程。进程可以创建进程,而程序不能形成新的程序。
(4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。
(5)进程具有并发性,而程序没有;  

4:进程的状态有哪些?

分为三种情况; (1)三种状态: (2)五种状态: (3)七种状态:

6:进程同步的含义和原则

答:多进程虽然提高了系统资源利用率和吞吐量,但是由于进程的异步性可能造成系统的混乱。进程同步的任务就是对多个相关进程在执行顺序上进行协调,使并发执行的多个进程之间可以有效的共享资源和相互合作,保证程序执行的可再现性
同步机制需要遵循的原则: 
1. 空闲让进:当没有进程处于临界区的时候,应该许可其他进程进入临界区的申请 
2. 忙则等待:当前如果有进程处于临界区,如果有其他进程申请进入,则必须等待,保证对临界区的互斥访问 
3. 有限等待:对要求访问临界资源的进程,需要在有限时间呃逆进入临界区,防止出现死等 
4. 让权等待:当进程无法进入临界区的时候,需要释放处理机,边陷入忙等
经典的进程同步问题:生产者-消费者问题;哲学家进餐问题;读者-写者问题   7:孤儿进程和僵死进程是什么?它们各自的危害是什么? (1)孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。 危害:由于父进程已经死亡,系统会帮助父进程回收处理孤儿进程。所以孤儿进程实际上是不占用资源的,因为它终究是被系统回收了。不会像僵尸进程那样占用ID,损害运行系统 (2)僵死进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程 危害:如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。 危害的场景:例如有个进程,它定期的产 生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了

8:进程间的通信方式有哪些(IPC)?

答:进程通信就是指进程间的信息交换,交换信息可以使一个状态,也可以是很多的byte。进程间同步互斥也存在信息的交换,因此也属于是一种IPC,属于是低级通信。该低级通信存在的问题:1)通信的数据量太少;2)通信对用户不透明(数据的传递或者同步互斥都需要程序员实现)

高级通信机制(高级通信的通信细节被OS隐藏,因此使用起来增加方便而且可以传送大量的数据,尤其是管道通信): 
1. 共享内存(最快的方式):相互通信的进程共享某些数据结构或者是存储区,进程之间可以通过这些共享空间进行通信。分为:1)基于共享数据结构的通信,如生产者消费者系统中的有界缓冲区;2)基于共享存储区的通信,可以传输大量数据,通信的进程之间可以像读写普通存储器一样读写共享存储区 
2. 消息传递系统:进程间通信采用的是格式化的消息,可以直接使用OS提供的消息发送或者接受原语进行通信。由于隐藏了通信细节,所以简化了通信程序的复杂性 
3. 管道通信:管道是连接两个一个读进程和一个写进程之间用于实现数据交换的一个共享文件。为了协调管道通信双方,需要管道机制实现如下功能:1)互斥:统一时刻只能有一个进程对管道进行读写;2)同步:当读端发现管道为空的时候需要睡眠等待,直到有数据时候被唤醒,相应的写端也是在管道已满的时候等待直到被唤醒;3)确定对方的存在性:只有同时有读端和写端,管道才有存在意义 4:信号量:进程间通信处理同步互斥的机制。信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。(关键就是通过PV操作) ---------------------------------------------------------------------------------------------------------------------------------------------------------------   知识扩展之信号量与PV操作(非常重要) 原因:为什么需要扩展这个知识点,是有原因的,因为,上面提到了,对于进程之间的通信来说,其中有一个就是通过信号量机制(定义就不多说了),那么为什么信号量能够实现进程之间的通信呢?它里面的工作机制又是如何的?这其实在操作系统中是一个非常重要的知识点(因为这个点在《计算机操作系统》书籍中都有进行很多的描述,并且针对这个问题,提出了很多经典的问题,并且自己在腾讯的时候也是有被问到这个,而且在基于这个问题的时候,其实对于Java的并发编程中都是有利用这个机制的,所以,自己觉得很有必要对这个问题进行阐述一下自己的理解) 大家请点击链接,进入到我的专题中进行阅读:https://blog.csdn.net/cs_hnu_scw/article/details/80204038  -----------------------------------------------------------------------------------------------------------------------------------------------------------

9:进程与线程的区别?

进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位(具有动态、并发、独立、异步的特性,以及就绪、执行、阻塞3种状态;也有5状态或者7状态;资源拥有单位的属性);引入进程是为了使多个程序可以并发的执行,以提高系统的资源利用率和吞吐量。 进程的属性:(1)每个进程拥有唯一标识符和进程控制块,进程控制块记录了进程执行的寄存器和栈等现场状态。
(2)不同的进程可以执行相同的程序,即同一个服务程序被不同的用户调用时,操作系统为它们创建成不同的进程。
(3)在单系统的CPU中,各进程可交替占用CPU;在多CPU的系统中,各进程可同时占用不同的CPU,若各CPU同时为一个进程内的各线程服务则可缩短进程的处理时间。
(4)一个进程被创建后就开始了他的生命周期,直至终止,进程在生命周期内会经历阻塞态、就绪态和运行态等各种状态变化 线程:是比进程更小的可独立运行的基本单位,可以看做是轻量级的进程(具有轻型实体,独立调度分派单位,可并发执行,共享进程资源等属性);引入目的是为了减少程序在并发执行过程中的开销,使OS的并发效率更高。 线程是程序执行流的最小单元,由线程ID、程序计数器、寄存器集合和堆栈组成。
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源。 两者的对比: 
(1)调度: 线程是独立调度的基本单位,进程是资源拥有的基本单位。
在同一进程中,线程的切换不会引起进程切换。在不同进程中进行线程切换,如从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。
(2)拥有资源: 进程是拥有资源的基本单位,而线程不拥有系统资源(也有一点必不可少的资源)。
(3)并发性: 不仅进程间可以并发执行,而且多个线程之间也可以并发执行,提高吞吐量。
(4)系统开销: 由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、IO设备等,因此操作系统所付出的开销远大于创建或撤销进程时的开销。在进行进程切换时,涉及当前执行进程CPU环境的保存及新调度到进程CPU环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。此外,由于同一进程内的多个线程共享进程的地址空间,因此这些线程之间的同步与通信非常容易实现,甚至无需操作系统的干预。
(5)地址空间和其他资源(如打开的文件): 进程的地址空间之间互相独立,同一进程的各线程间共享进程的资源,某进程内的线程对于其他进程不可见。
(6)通信方面: 进程间通信(IPC)需要进程同步和互斥手段的辅助,以保证数据的一致性,而线程间可以直接读/写进程数据段(如全局变量)来进行通信。

10:为什么有进程还需要有线程?

(1)能够更好的利用相同地址空间的资源。因为,不同的进程是拥有不同的地址空间的,那它们就不能利用某个进程中的地址空间的资源了。
(2)进程的创建和销毁,消耗的资源大,而线程的创建和销毁,消耗的资源较小,可以更好的减少资源的浪费。
(3)线程可以进行并行执行,这对于有大量的IO处理时,可以提高执行的速度。 11:进程控制块(PCB)的相关知识-------这个对于进程是相当重要的部分 含义:
(1)Process Control Block 又称为 进程描述符进程属性
(2)是操作系统用于管理控制进程的一个专门的数据结构
(3)记录进程的各种属性,描述进程的动态变化过程
PCB包含的信息:
 第一部分:进程描述信息
(1)进程标识符(Process ID),唯一。通常是一个整数
(2)进程名。通常基于可执行文件名,不唯一
(3)用户标识符(user ID)
(4)集成组关系
 第二部分:进程控制信息
(1)当前的状态
(2)优先级(priority)
(3)代码执行入口地址
(4)程序的磁盘地址
(5)运行统计信息(执行时间,页面调度)
(6)进程间同步和通信
(7)进程的队列指针
(8)进程的信息队列指针
 第三部分:拥有的资源和使用情况
(1)虚拟地址空间状况
(2)打开文件列表
 第四部分:CPU现场信息
(1)寄存器值(通用寄存器、程序计数器PC、程序状态字PSW、栈指针)
(2)指向该进程页表的指针 12:进程的切换 含义:进程切换指从正在运行的进程中收回处理器,让待运行进程来占有处理器运行。实质上就是被中断运行进程与待运行进程的上下文切换
进程切换引起模式切换:进程切换必须在操作系统内核模式下完成,这就需要模式切换。模式切换又称处理器切换,即用户模式和内核模式的互相切换。
进程切换的工作过程(详细版):
1、(中断/异常等触发)正向模式切换并压入PSW/PC 。 (Program Status Word 程序状态字。program counter 程序计数器。指向下一条要执行的指令)
2、保存被中断进程的现场信息。
3、处理具体中断、异常。
4、把被中断进程的系统堆栈指针SP值保存到PCB。(Stack Pointer 栈指针。Process Control Block 进程控制块。)
5、调整被中断进程的PCB信息,如进程状态)。
6、把被中断进程的PCB加入相关队列。
7、选择下一个占用CPU运行的进程。
8、修改被选中进程的PCB信息,如进程状态。
9、设置被选中进程的地址空间,恢复存储管理信息。
10、恢复被选中进程的SP值到处理器寄存器SP。
11、恢复被选中进程的现场信息进入处理器。
12、(中断返回指令触发)逆向模式转换并弹出PSW/PC。
进程切换的工程过程(粗略版)
1、保存处理机的上下文,包括程序计数器PC、处理机状态字PS、其他寄存器
2、修改当前运行进程的PCB内容,包括将进程状态从运行态改成其他状态(等待状态/就绪状态)
3、选择另一个进程(按照调度算法)
4、修改被调度进程的PCB内容,包括把其他状态改变到运行态
5、恢复被选现场(上一次切换出处理机时)的处理机现场,按原保护的程序计数器值重置程序计数器PC,运行新选进程
进程切换发生的时机:
进程切换一定发生在中断/异常/系统调用处理过程中,常见的有以下情况:
1、阻塞式系统调用、虚拟地址异常。
导致被中断进程进入等待态。
2、时间片中断、I/O中断后发现更改优先级进程。
导致被中断进程进入就绪态。
3、终止用系统调用、不能继续执行的异常。
导致被中断进程进入终止态。
注意要点:不是所有的中断/异常就会引起进程切换,有可能会发生,执行完中断/异常后,继续恢复当前进程继续执行。 13:进程发生调度的情况 1、当进程主动放弃处理机时:原来的进程主动放弃了处理机,选择申请‘调度’来选择另外的合适进程
(1)正在执行的进程执行完毕:操作系统在处理“进程结束”系统调用后影请求重新调度
(2)正在执行的进程出I/O请求:当操作系统内核驱动启动外设I/O后,在I/O请求没有完成前要讲进程变成阻塞状态,应该请求重新调度
(3)正在执行的进程要等待其他进程或系统发出的时间时:如等待另一个进程通讯数据,这时操作系统应将现运行进程挂到等待队列,并且请求重新调度
(4)正在执行的进程暂时得不到所要的系统资源:如要求独占资源却被其他进程占用,这时等待的进程应阻塞到等待队列上,并且请求重新调度
2、当有新进程就绪时:为了支持可剥夺的调度方式,这时要申请‘调度’才能剥夺老进程
(1)当中断处理程序处理完中断,如I/O中断引起某个阻塞进程变成就绪状态时,应申请重新调度
(2)当进程释放独占资源,引起其他等待该资源进程从阻塞状态进入就绪状态时,应该申请重新调度
(3)当某进程发“发送消息”系统调用,导致等待该消息的进程就绪时
(4)其他任何原因引起有进程从其他状态变成就绪状态,如进程被中级调度选中时
3、为了支持可剥夺的调度方式,即使没有新就绪进程,为了让所有就绪进程轮流占用处理机,也可选择申请‘调度’
(1)当时钟中断发生,时钟中断处理程序调用有关时间片的处理程序,发现正运行进程的时间片到,应请求重新调度,以便让其他进程占用处理机
(2)在按进程优先级进行调度的操作系统中,任何原因引起进程的优先级发生变化时,应请求重新调度。如进程通过系统调用自愿改变优先级时或系统处理时钟中断时,根据各进程等待处理机的时间长短而调整进程的优先级

14:进程/任务之间的调度算法

答:基本调度算法: 
1. 先来先服务调度算法FCFS:既可以作为作业调度算法也可以作为进程调度算法;按作业或者进程到达的先后顺序依次调度;因此对于长作业比较有利; 
2. 短作业优先调度算法SJ(P)F:作业调度算法,算法从就绪队列中选择估计时间最短的作业进行处理,直到得出结果或者无法继续执行;缺点:不利于长作业;未考虑作业的重要性;运行时间是预估的,并不靠谱 
3. 高优先权优先调度算法HPF:既可以作为作业调度也可以作为进程调度算法;调度作业时,从就绪队列中选择优先级最高的作业进行处理;由于涉及到了优先级,因此可以分为抢占式和非抢占式;而且优先级的确定也可以分为静态优先级(事先根据进程类型,进程对资源的需求,用户要求等方面确定一个固定值);动态优先级(随进程的推进或者等待时间而增加或者减少) 
4. 高相应比算法HRN:响应比=(等待时间+要求服务时间)/要求服务时间; 
5. 时间片轮转调度RR:按到达的先后对进程放入队列中,然后给队首进程分配CPU时间片,时间片用完之后计时器发出中断,暂停当前进程并将其放到队列尾部,循环 
6. 多级反馈队列调度算法:目前公认较好的调度算法;设置多个就绪队列并为每个队列设置不同的优先级,第一个队列优先级最高,其余依次递减。优先级越高的队列分配的时间片越短,进程到达之后按FCFS放入第一个队列,如果调度执行后没有完成,那么放到第二个队列尾部等待调度,如果第二次调度仍然没有完成,放入第三队列尾部…。只有当前一个队列为空的时候才会去调度下一个队列的进程。
实时调度算法: 
1. 最早截止时间优先调度算法EDF:算法根据任务的开始截止时间确定优先级,截止时间越早,优先级越高。算法维护一个实时就绪队列,最早截止时间的任务排在最前面;可以用于抢占式调度也可以用于非抢占式调度; 
2. 最低松弛度优先调度算法LLF:松弛度=(必须完成时间-本身运行时间-当前时间);算法根据任务的松弛度确定任务的优先级,松弛度代表了任务的紧急程度,任务的紧急程度越高,被赋予的优先级越高

15:调度算法的目标?

(1)保证进程调度的尽量公平 
(2)保持系统的所有部分尽可能忙碌

16:资源分为什么?多线程之间共享和独享的资源分别是什么?

答:资源分为共享资源和独享资源; 共享的资源有:
a. 堆  由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)
b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
c. 静态变量虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
d. 文件等公用资源  这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。
独享的资源有:
a. 栈 栈是独享的
b. 寄存器  这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC 对于进程的一系列流程,最好心里要有一个过程,这样的话,对于整个进程的认识就会比较的完善,而没有必要去死记硬背那些知识点,所以推荐一篇文章:大家可以根据流程并结合我的知识点来进行完善。----->>>>>>进程管理知识点梳理

三:死锁的相关知识

1:死锁的必要条件和处理方法

定义:死锁是指多个进程在运行过程中,因为争夺资源而造成的一种僵局,如果没有外力推进,处于僵局中的进程就无法继续执行。
死锁原因: 
1. 竞争资源:请求同一有限资源的进程数多于可用资源数 
2. 进程推进顺序非法:进程执行中,请求和释放资源顺序不合理,如资源等待链
死锁产生的必要条件: 
1. 互斥条件:进程对所分配的资源进行排他性的使用 
2. 请求和保持条件:进程被阻塞的时候并不释放锁申请到的资源 
3. 不可剥夺条件:进程对于已经申请到的资源在使用完成之前不可以被剥夺 
4. 环路等待条件:发生死锁的时候存在的一个 进程-资源 环形等待链
死锁处理: 
1. 预防死锁:
破坏产生死锁的4个必要条件中的一个或者多个;实现起来比较简单,但是如果限制过于严格会降低系统资源利用率以及吞吐量 
2. 避免死锁:在资源的动态分配中,防止系统进入不安全状态(可能产生死锁的状态)-如银行家算法 
3. 检测死锁:允许系统运行过程中产生死锁,在死锁发生之后,采用一定的算法进行检测,并确定与死锁相关的资源和进程,采取相关方法清除检测到的死锁。实现难度大 
4. 解除死锁:与死锁检测配合,将系统从死锁中解脱出来(撤销进程或者剥夺资源)。对检测到的和死锁相关的进程以及资源,通过撤销或者挂起的方式,释放一些资源并将其分配给处于阻塞状态的进程,使其转变为就绪态。实现难度大
死锁定理:S为死锁状态的充分条件是,当且仅当S的资源分配图是不能完全简化的。

2:说说进程的饥饿和死锁的区别?

它们两者都是进程与进程之间存在的两种资源竞争的状态: 死锁:如果一个进程集合中的每个进程都在等待只能由该组进程中的其他进程才能引发的事件,那么,该组进程是死锁的。 饥饿:主要就是指存在某些进程永远得不到服务的机会。比如多个文件进行请求打印机设备分配打印机问题。如果首先分配给小文件,那么大文件可能永远得不到打印。对于这问题,比较好的解决方法就是通过先来先服务方式。

四:存储管理的相关知识

1:虚拟存储器出现的原因以及其主要的思想?

出现的原因:遇到程序太大,以至于内存容纳不下,而必须进行分段进行载入内存
基本思想:程序,数据和堆栈的总大小可能超过可用的物理内存的大小。由操作系统把程序当前使用的那部分保留在主存中,而把其他的部分保存在磁盘上。这样就实现用小的内存大小来运行大的程序。

2:物理地址和虚拟地址分别指什么?

物理地址:就是内存中实际存在的地址,也就是我们电脑中内存条中所表示的地址。 虚拟地址:被分成虚拟页号(高位)和偏移量(低位)是一种虚拟化的地址,是由程序产生的地址。虚拟地址与物理地址不是一一对应关系,它们之间存在映射关系。而转换就是通过MMU(其中MMU(内存管理单元):作用为把虚拟地址映射为物理内存地址)来进行。 参考这篇博文可以理解:https://blog.csdn.net/patkritlee/article/details/52176765  

3:什么叫做虚拟内存?虚拟存储器的特征是什么?

如果存在一个程序,所需内存空间超过了计算机可以提供的实际内存,那么由于该程序无法装入内存所以也就无法运行。单纯的增加物理内存只能解决一部分问题,但是仍然会出现无法装入单个或者无法同时装入多个程序的问题。但是可以从逻辑的角度扩充内存容量,即可解决上述两种问题,所以出现了虚拟内存;
虚拟存储器定义:就是具有请求调入功能和置换功能,可以从逻辑上对内存容量加以扩充的一种存储器系统。虚拟存储器都是建立在离散内存管理的基础上。
虚拟存储器的特征: 
1. 多次性:一个作业可以分多次被调入内存。多次性是虚拟存储特有的属性 
2. 对换性:作业运行过程中存在换进换出的过程(换出暂时不用的数据换入需要的数据) 
3. 虚拟性:虚拟性体现在其从逻辑上扩充了内存的容量(可以运行实际内存需求比物理内存大的应用程序)。虚拟性是虚拟存储器的最重要特征也是其最终目标。虚拟性建立在多次性和对换性的基础上行,多次性和对换性又建立在离散分配的基础上 4:页表是什么?页表的表项有哪些结构?页面的抖动和颠簸又是指什么? 页表:把虚拟地址映射到页帧。(每个进程都有自己的页表,因为每个进程都有自己的虚拟空间)
页表的结构:(1)高速缓存禁止位:标识是否被缓存
(2)访问位:标识是否被访问,主要是作用于页面置换
(3)修改位:为了记录页面的使用状况,用于标识是否被修改过
(4)保护位:指出一个页面允许什么类型的访问
(5)"在/不在"位:标识是否处于内存中,如果不在,就需要从磁盘进行载入内存
(6)页帧号
页面抖动:刚刚换出的页面可能又被接下来访问。
页面颠簸:每执行几条程序语句,就会发生页面失效(缺页)的情况。

5:页面置换算法有哪些?

(1)最佳置换算法:只具有理论意义的算法,用来评价其他页面置换算法。置换策略是将当前页面中在未来最长时间内不会被访问的页置换出去。
(2)先进先出置换算法:简单粗暴的一种置换算法,没有考虑页面访问频率信息。每次淘汰最早调入的页面
(3)最近最久未使用算法LRU:算法赋予每个页面一个访问字段,用来记录上次页面被访问到现在所经历的时间t,每次置换的时候把t值最大的页面置换出去(实现方面可以采用寄存器或者栈的方式实现)
(4)时钟算法clock(也被称为是最近未使用算法NRU):页面设置一个访问为,并将页面链接为一个环形队列,页面被访问的时候访问位设置为1。页面置换的时候,如果当前指针所指页面访问为为0,那么置换,否则将其置为0,循环直到遇到一个访问为位0的页面
(5)改进型Clock算法:在Clock算法的基础上添加一个修改位,替换时根究访问位和修改位综合判断。优先替换访问为何修改位都是0的页面,其次是访问位为0修改位为1的页面。
(6)最少使用算法LFU:设置寄存器记录页面被访问次数,每次置换的时候置换当前访问次数最少的。存在问题是该访问寄存器并不能真正反映当前页面访问次数,因为访问速度比较快,所以在更新寄存器的时间间隔内访问1次和访问100次都是一样的。另外,LFU和LRU是很类似的,支持硬件也是一样的,但是区分两者的关键在于一个以时间为标准,一个以次数为标准(例如对于寄存器 pa 001111 和pb 111000,两个页面,如果采用LRU,那么被淘汰的是pa,如果采用LFU那么被淘汰的是pb)。
(7)页面缓冲算法PBA:置换的时候,页面无论是否被修改过,都不被置换到磁盘,而是先暂留在内存中的页面链表(已修改页面链表和未修改页面链表,也可以不区分)里面,当其再次被访问的时候可以直接从这些链表中取出而不必进行磁盘IO,当链表中已修改也难数目达到一定数量之后,进行依次写磁盘操作(相当于将多次IO合并为一次) 6:操作系统在什么情况下会做调页有关的工作? (1)进程创建:操心系统要确定程序和数据最初的大小,并为它们创建一个页表。
(2)进程执行:必须为新进程重置MMU(内存管理单位)和刷新TLB(快表),以清除以前进程所留下的痕迹。
(3)页面失效:操作系统必须通过读硬件寄存器来确定哪个虚拟地址造成页面失效,并且通过计算磁盘哪个页面需要被换入。
(4)进程销毁:操作系统必须释放进程的页表,页面和页面在磁盘所占有的空间。

7:页面失效的处理过程?

(1)硬件陷入内核,在堆栈中保存程序计数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。
(2)启动一个汇编代码例保存通用寄存器和其他易失的信息,以免被操作系统破坏。这个例程将操作系统作为一个过程调用。
(3)当操作系统发现一个页面失效时,试图查找需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计算器,取出这条指令,用软件分析这条指令,看看它在页面失效时正在做什么。
(4)一旦知道了发生页面失效的虚拟地址,操作系统检测这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效而没有保护错误发生,系统则检查是否有空闲页帧。如果没有空闲页帧,执行页面置换算法寻找一个被淘汰的页面。
(5)如果选择的页帧“脏”了,安排将该页面写会磁盘,并发生一次上下文切换,挂起产生页面失效的进程,让其他进程运行直至磁盘传输结束。无论如何,该页帧被标记为忙,以免因为其他原因而被占用。
(6)一旦页帧“干净”了后(无论是理科还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其载入。该页面被载入后,产生页面失效的进程仍然被挂起,并且如果有可运行的用户进程,则另一个用户进程运行。
(7)当磁盘中断发生,表面该页面已经装入时,页表也已更新以反映它的位置,页帧也标记为通常的状态。
(8)恢复发生页面失效指令以前的状态,程序计数器重新指向这条指令。
(9)调度页面失效进程,操作系统返回调用它的汇编语言例程。
(10)该例程恢复寄存器和其他状态信息,回到用户空间继续执行,就好像页面失效没有发生过一样。

8:内存管理方式

答:内存管理方式出现的原因:由于连续内存分配方式(单一连续分配,固定分区分配,动态分区分配,动态重定位分区分配)导致的内存利用率偏低以及内存碎片的问题,进而引出离散的内存分配方式。离散内存分配可以从OS的内存管理角度引出页式(离散分配的基本单位是页)管理,也可以从程序编制角度引出段式(离散分配的基本单位是段)管理。 (1)页式 基本分页存储管理中不具备页面置换功能(即没有实现虚拟内存的功能),因此需要整个程序的所有页面都装入内存之后才可以运行。因为程序数据存储在不同的页面中,而页面又离散的分布在内存中,因此需要一个页表来记录逻辑地址和实际存储地址之间的映射关系,以实现从页号到物理块号的映射。由于页表也是存储在内存中的,因此和不适用分页管理的存储方式相比,访问分页系统中内存数据需要两次的内存访问(一次是从内存中访问页表,从中找到指定的物理块号,加上页内偏移得到实际物理地址;第二次就是根据第一次得到的物理地址访问内存取出数据)。 
为了减少两次访问内存导致的效率影响,分页管理中引入了快表(或者联想寄存器)机制,包含快表机制的内存管理中,当要访问内存数据的时候,首先将页号在快表中查询,如果查找到说明要访问的页表项在快表中,那么直接从快表中读取相应的物理块号;如果没有找到,那么访问内存中的页表,从页表中得到物理地址,同时将页表中的该映射表项添加到快表中(可能存在快表换出算法)。 
在某些计算机中如果内存的逻辑地址很大,将会导致程序的页表项会很多,而页表在内存中是连续存放的,所以相应的就需要较大的连续内存空间。为了解决这个问题,可以采用两级页表或者多级页表的方法,其中外层页表一次性调入内存且连续存放,内层页表离散存放。相应的访问内存页表的时候需要一次地址变换,访问逻辑地址对应的物理地址的时候也需要一次地址变换,而且一共需要访问内存3次才可以读取一次数据。 (2)段式 分页是为了提高内存利用率,而分段是为了满足程序员在编写代码的时候的一些逻辑需求(比如数据共享,数据保护,动态链接等)。 
分段内存管理当中,地址是二维的,一维是段号,一维是段内地址;其中每个段的长度是不一样的,而且每个段内部都是从0开始编址的。由于分段管理中,每个段内部是连续内存分配,但是段和段之间是离散分配的,因此也存在一个逻辑地址到物理地址的映射关系,相应的就是段表机制。段表中的每一个表项记录了该段在内存中的起始地址和该段的长度。段表可以放在内存中也可以放在寄存器中。 
访问内存的时候根据段号和段表项的长度计算当前访问段在段表中的位置,然后访问段表,得到该段的物理地址,根据该物理地址以及段内偏移量就可以得到需要访问的内存。由于也是两次内存访问,所以分段管理中同样引入了联想寄存器。
分段和分页的对比: 
(1)对程序员的透明性:分页透明,但是分段需要程序员显示划分每个段。
(2)地址空间的维度:分页是一维地址空间,分段是二维的。
(3)大小是否可以改变:页的大小不可变,段的大小可以动态改变。
(4)出现的原因:分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。 (3)段页式: 先将用户程序分为若干个段,然后再把每个段分成若干个页,并且为每一个段赋予一个段名称。这样在段页式管理中,一个内存地址就由段号,段内页号以及页内地址三个部分组成。  段页式内存访问:系统中设置了一个段表寄存器,存放段表的起始地址和段表的长度。地址变换时,根据给定的段号(还需要将段号和寄存器中的段表长度进行比较防止越界)以及寄存器中的段表起始地址,就可以得到该段对应的段表项,从段表项中得到该段对应的页表的起始地址,然后利用逻辑地址中的段内页号从页表中找到页表项,从该页表项中的物理块地址以及逻辑地址中的页内地址拼接出物理地址,最后用这个物理地址访问得到所需数据。由于访问一个数据需要三次内存访问,所以段页式管理中也引入了高速缓冲寄存器。

9:页式管理,段式管理以及段页式管理各自的地址结构是什么?

(1)页式:页号+页内偏移量
(2)段式:段号+段内偏移量 (3)段页式:段号+页号+偏移量 10:页式管理,段式管理以及段页式管理各自的地址转换流程是怎样?  

五:输入/输出相关知识

1:常见的I/O设备有哪些?并且I/O设备的分类主要是哪几种?

2:磁盘读取数据为什么要先缓存到内部的缓冲区,而不是直接存储在主存? (1)通过进行内部缓冲,磁盘控制器可以在开始传送之前进行检验和。如果检验和是错误的,那么就表明错误的信号将被发出并且不会进行传送。
(2)一旦磁盘传送开始,从磁盘读出的数据是以固定速率到达的,不论控制器是否准备好接受数据。如果控制器要将数据直接写入内存,则它必须为要传送的每个字取得系统总线的控制。此时,如果其他设备使用总线而导致总线忙,则控制器就必须等待。

3:I/O软件的层次是哪几种?

(1)中断处理程序:中断处理发生的过程(见自己的博客)
(2)设备驱动程序
(3)与设备无关的操作系统软件:基本功能是执行对所有设备公共的I/O功能,并且向用户层软件提供一个统一的接口。
    其接口又分为:1:设备驱动程序的统一接口
  2:缓冲
  3:错误报告
  4:分配与释放专用设备
  5:提供与设备无关的块大小
(4)用户级I/O软件

4:CPU的工作状态有什么?

大多数计算机系统将CPU执行状态分为目态与管态。CPU的状态属于程序状态字PSW的一位。CPU交替执行操作系统程序和用户程序。
管态又叫特权态,系统态或核心态。CPU在管态下可以执行指令系统的全集。通常,操作系统在管态下运行。 
目态又叫常态或用户态。机器处于目态时,程序只能执行非特权指令。用户程序只能在目态下运行,如果用户程序在目态下执行特权指令,硬件将发生中断,由操作系统获得控制,特权指令执行被禁止,这样可以防止用户程序有意或无意的破坏系统。 
从目态转换为管态的唯一途径是中断。 
从管态到目态可以通过修改程序状态字来实现,这将伴随这由操作系统程序到用户程序的转换。 5:机械硬盘的工作原理 硬盘的构造: (1)机械手臂(Boom)
(2)磁头(Head)
(3)转轴(Spindle)
(4)盘片(Platter)组成,在实际应用中又将盘片分成了磁道(Track),扇区(Sector)和柱面(Cylinder) 工作方式:       现代硬盘寻道都是采用CHS(Cylinder Head Sector)的方式,硬盘读取数据时,读写磁头沿径向移动,移到要读取的扇区所在磁道的上方,这段时间称为寻道时间(seek time)。因读写磁头的起始位置与目标位置之间的距离不同,寻道时间也不同。目前硬盘一般为2到30毫秒,平均约为9毫秒。磁头到达指定磁道后,然后通过盘片的旋转,使得要读取的扇区转到读写磁头的下方,这段时间称为旋转延迟时间(rotational latencytime)。 磁盘调度算法: (1)先来先服务算法(FCFS)
这种算法将对磁盘的IO请求进行排队,按照先后顺序依次调度磁头。这种算法的特点是简单,合理,但没有减少寻道时间
(2)最短寻道时间算法(SSFT)
这种算法优先执行所需读写的磁道离当前磁头最近的请求。这保证了平均寻道时间的最短,但缺点显而易见:离当前磁头比较远的寻道请求有可能一直得不到执行,这也就是所谓的“饥饿现象”。
(3)扫描算法(SCAN)
这种算法在磁头的移动方向上选择离当前磁头所在磁道最近的请求作为下一次服务对象,这种改进有效避免了饥饿现象,并且减少了寻道时间。但缺点依然存在,那就是不利于最远一端的磁道访问请求。
(4)循环扫描算法(CSCAN)
也就是俗称的电梯算法,这种算法是对最短寻道时间算法的改进。这种算法就像电梯一样,只能从1楼上到15楼,然后再从15楼下到1楼。这种算法的磁头调度也是如此,磁头只能从最里磁道到磁盘最外层磁道。然后再由最外层磁道移动到最里层磁道,磁头是单向移动的,在此基础上,才执行和最短寻道时间算法一样的,离当前磁头最近的寻道请求。这种算法改善了SCAN算法,消除了对两端磁道请求的不公平。 磁盘优化的策略: (1)对于磁盘读取来说,大部分的时间都是花在寻到时间上面,所以通过寻道策略可以进行一定的优化;
(2)可以利用局部性特点:所谓的局部性原理分为时间和空间上的。由于程序是顺序执行的,因此当前数据段附近的数据有可能在接下来的时间被访问到。这就是所谓的空间局部性。而程序中还存在着循环,因此当前被访问的数据有可能在短时间内被再次访问,这就是所谓的时间局部性原理。
     提前读(Read-Ahead)
提前读也被称为预读。根据磁盘原理我们不难看出,在磁盘读取数据的过程中,真正读取数据的时间只占了很小一部分,而大部分时间花在了旋转延迟和寻道时间上,因此根据空间局部性原理,每次读取数据的时间不仅仅读取所需要的数据,还将所请求数据附近的数据进行读取。
      延迟写(Delayed write)
同样,根据时间局部性原理,最近被访问的数据有可能再次被访问,因此当数据更改之后不马上写回磁盘,而是继续放在内存中,以备接下来的请求读取或者修改,是减少磁盘IO的另一个有效手段。

6:说说我们在系统进行开启的时候,做的哪些工作?

当电源打开时,BIOS最先运行,然后它读入主引导记录并跳转到主引导记录。然后这一引导程序进行检查以了解哪个分区是活动的。引导扇区包含一个小的程序,它在根目录中搜索某个程序(或者是操作系统或者是一个更大的启动程序装载器)。该程序被装入内存并执行。

7:输入输出设备中的盘有哪些类型?

(1)磁盘
(2)RAID(廉价磁盘冗余阵列)
(3)CD-ROM(光盘)
(4)可刻录的CD
(5)可重写CD
(6)DVD(数字通用光盘)

8:中断处理程序的过程?

(1)保存没有被中断硬件保存的所有寄存器(包括PSW)
(2)为中断服务过程设置上下文,可能包括设置TLB,MMU和页表
(3)为中断服务过程设置堆栈
(4)应答中断控制器,如果不存在集中的中断控制器,则再次开发中断。
(5)将寄存器从它们被保存的地方(可能是某个堆栈)复制到进程表中。
(6)运行中断服务过程,从发出中断的设备控制器的寄存器中提取消息。
(7)选择下一次运行哪个进程,如果中断导致某个被阻塞的高优先级进程变为就绪,则可能选择它现在就运行。
(8)为下一次运行的进程设置MMU上下文,也许还需要设置某个TLB。
(9)装入新进程的寄存器,包括PSW
(10)开始运行新进程。

六:文件系统的相关知识

1:常见的文件系统有哪些?

答:其实对于这个问题的话,我是从两个方面进行回答的,因为随着现在的技术的发展的话,出现传统的文件系统和分布式系统,所以,回答的时候,可以说一下这两种类型的不同的系统。可以参考下面这两篇文章: https://blog.csdn.net/yjxsdzx/article/details/77918889 https://blog.csdn.net/xyw591238/article/details/51441282 2:文件存取方式有哪些? (1)顺序存取:从开始顺序读取文件的全部字节和记录,但不能跳过某一些内容,也不能不按顺序读取;
(2)随机存取(现在都采用这种):以任何次序读取其中字节或记录
3:文件操作有哪些? 4:说说对于文件目录的理解? 4:说说对于文件描述符的理解 文件描述符定义:       文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3。POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号码,因此,在网络通信过程中稍不注意就有可能造成串话。       在linux进程中,默认有三个文件是打开的:标准输入(stdin)0,标准输出(stdout)1,错误输出(stderr)2,其0,1,2对应的物理设备分别是键盘,显示器,显示器;因此,函数 scanf() 使用 stdin,而函数 printf() 使用 stdout。 文件描述符的结构关系:        由图可以理解到,在我们进程的进程控制块即PCB中有一个结构体指针file,它指向了一个files_struct结构体,这个结构体内保存着一个指针数组,其每个元素都是一个指针,这个指针就是打开文件的指针,而我们所谓的文件描述符就是这些指针的下标,所以只要拿着文件描述符就可以找到对应的文件。 文件描述符的生命周期: (1)创建file对象
(2)根据IO对象的类型注册各个操作函数(注册file_operations)
(3)将file对象的指针注册到进程描述符的files数组里的fd下标处
(4)read、write等等IO操作
(5)调用close(fd)释放file对象 总结:文件描述符(file_struct)是操作系统用来管理文件的数据结构,当我们创建一个进程时,会创建文件描述符表,进程控制块PCB中的fs指针指向文件描述符表,当我们创建文件时,会为指向该文件的指针FILE*关联一个文件描述符并添加在文件描述符表中。在文件描述符表中fd相当于数组的索引,FILE*相当于数组的内容吗,指向一个文件结构体。

七:操作系统相关方面知识

1:时钟周期,机器周期(CPU周期),指令周期各自的含义是什么?

指令周期 :取出并执行一条指令的时间。 
机器周期 :又称CPU周期,CPU访问一次内存所花的时间较长,因此用从内存读取一条指令字的最短时间来定义。
时钟周期:通常称为节拍脉冲或T周期。处理操作的最基本单位,即CPU主频。 三者的关系:指令周期通常用若干个机器周期表示,而机器周期又包含若干个时钟周期

2:说说Linux系统中,用得比较多的命令以及作用。

(1)ls ----显示当前目录下的文件
(2)cd XXX ----进入XXX目录
(3)mc XXX     ----移动XXX目录
(4)cp XXX     ----复制文件
(5)find       ----查找相应需求的内容
(6)grep ----分析一行信息
(7)rm XXX ----删除文件或者目录
(8)ps ----显示某个时间点的进程状态信息
(9)kill ----杀死进程
(10)top ----动态显示CPU信息
(11)tar ----压缩文件
(12)cat ----查看文件
(13)chmod ----修改文件权限
(14)vim ----使用vim编辑器
(15)netstat ----查看网络 3:      这并不是终点,而是我刚刚的开始,我会一直不断结合自己的情况,将知识点进行更新,欢迎大家进行关注和阅读!!!