2022届秋招Java后端高频知识点汇总⑨--操作系统
1. IO模型
①BIO(blocking IO)
阻塞IO,即在读写数据的过程中会发生阻塞现象。
当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,操作系统就会将数据从内核空间拷贝到用户空间,并返回结果给用户线程,用户线程才解除阻塞状态。
(因为我们的用户程序只能获取用户空间的内存,无法直接获取内核空间的内存)
典型的阻塞IO模型的例子为:
data = socket.read();
如果数据没有就绪,就会一直阻塞在read方法。
②NIO(nonblocking IO)
当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时(数据未准备就绪),它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。所以事实上,在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。
但是对于非阻塞IO就有一个非常严重的问题,在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高,因此一般情况下很少使用while循环这种方式来读取数据。
③AIO (异步IO Asynchronous IO)
【异步IO模型才是最理想的IO模型】
在异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其它的事。
而另一方面,从内核的角度,当它收到一个asynchronous read之后,它会立刻返回,说明read请求已经成功发起了,因此不会对用户线程产生任何阻塞。
然后,内核会等待数据准备完成,再将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。
当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了。
(也就说用户线程完全不需要关心实际的整个IO操作是如何进行的,只需要先发起一个请求。)
也就说在异步IO模型中,IO操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用IO函数进行具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作已经完成,不需要再在用户线程中调用IO函数进行实际的读写操作。
④IO多路复用(IO multiplexing)
在多路复用IO模型中,会有一个线程不断去轮询多个socket的状态,只有当socket真正有读写事件时,才真正调用实际的IO读写操作。
因为在多路复用IO模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线 程和 进程,并且只有在真正有socket读写事件进行时,才会使用IO资源,所以它大大减少了资源占用。
⑤信号驱动IO(signal driven IO)
在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作。
2. 进程有哪几种状态
进程大致分为5个状态
①创建状态(new):进程正在被创建,尚未到就绪状态。
②就绪状态(ready):进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。
③运⾏状态(running) :进程正在处理器上上运⾏(单核 CPU 下任意时刻只有⼀个进程处于运⾏状态)。
④阻塞状态(waiting) :⼜称为等待状态,进程正在等待某⼀事件⽽暂停运⾏如等待某资源为可⽤或等待 IO 操作完成。即使处理器空闲,该进程也不能运⾏。
3. 进程间通信方式
⼤概有 7 种常⻅的进程间的通信⽅式
①管道/匿名管道(Pipes) :⽤于具有亲缘关系的⽗⼦进程间或者兄弟进程之间的通信。
②有名管道(Names Pipes) : 匿名管道由于没有名字,只能⽤于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘⽂件的⽅式存在,可以实现本机任意两个进程通信。
③信号(Signal) :信号是⼀种⽐较复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣;
④消息队列(Message Queuing) :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(⽆名管道:只存在于内存中的⽂件;命名管道:存在于实际的磁盘介质或者⽂件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除⼀个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不⼀定要以先进先出的次序读取,也可以按消息的类型读取.⽐ FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载⽆格式字 节流以及缓冲区⼤⼩受限等缺。
⑤信号量(Semaphores) :信号量是⼀个计数器,⽤于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信⽅式主要⽤于解决与同步相关的问题并避免竞争条件。
⑥共享内存(Shared memory) :使得多个进程可以访问同⼀块内存空间,不同进程可以及时看到对⽅进程中对共享内存中数据的更新。这种⽅式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有⽤的进程间通信⽅式。
4. 进程的调度算法
为了确定⾸先执⾏哪个进程以及最后执⾏哪个进程以实现最⼤ CPU 利⽤率,计算机科学家已经定义了⼀些算法,它们是:
①先到先服务(FCFS)调度算法 : 从就绪队列中选择⼀个最先进⼊该队列的进程为之分配资源,使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤ CPU 时再重新调度。
②短作业优先(SJF)的调度算法 : 从就绪队列中选出⼀个估计运⾏时间最短的进程为之分配资源,使它⽴即执⾏并⼀直执⾏到完成或发⽣某事件⽽被阻塞放弃占⽤ CPU 时再重新调度。
③时间⽚轮转调度算法 : 时间⽚轮转调度是⼀种最古⽼,最简单,最公平且使⽤最⼴的算法,⼜称 RR(Round robin)调度。每个进程被分配⼀个时间段,称作它的时间⽚,即该进程允许运⾏的时间。
④多级反馈队列调度算法 :前⾯介绍的⼏种进程调度的算法都有⼀定的局限性。如短进程优先的调度算法,仅照顾了短进程⽽忽略了⻓进程 。多级反馈队列调度算法既能使⾼优先级的作业得到响应⼜能使短作业(进程)迅速完成。因⽽它是⽬前被公认的⼀种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
5. 常见的几种内存管理机制
内存管理机制简单分为连续分配管理⽅式和⾮连续分配管理⽅式这两种。
连续分配管理⽅式是指为⼀个⽤户程序分配⼀个连续的内存空间,常⻅的如块式管理 。
⾮连续分配管理⽅式允许⼀个程序使⽤的内存分布在离散或者说不相邻的内存中,常⻅的如⻚式管理和段式管理。
①块式管理 : 远古时代的计算机操系统的内存管理⽅式。将内存分为⼏个固定⼤⼩的块,每个块中只包含⼀个进程。如果程序运⾏需要内存的话,操作系统就分配给它⼀块,如果程序运⾏只需要很⼩的空间的话,分配的这块内存很⼤⼀部分⼏乎被浪费了。这些在每个块中未被利⽤的空间,我们称之为碎⽚。
②⻚式管理 :把主存分为⼤⼩相等且固定的⼀⻚⼀⻚的形式,⻚较⼩,相对相⽐于块式管理的划分⼒度更⼤,提⾼了内存利⽤率,减少了碎⽚。⻚式管理通过⻚表对应逻辑地址和物理地址。
③段式管理 : ⻚式管理虽然提⾼了内存利⽤率,但是⻚式管理其中的⻚实际并⽆任何实际意义。段式管理把主存分为⼀段段的,每⼀段的空间⼜要⽐⼀⻚的空间⼩很多 。但是,最重要的是段是有实际意义的,每个段定义了⼀组逻辑信息,例如,有主程序段 MAIN、⼦程序段 X、数据段 D及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。
6. 虚拟地址和物理地址
虚拟地址,就是就是一种逻辑意义上的地址,而当我们想要访问这个虚拟地址时,是需要转换到物理地址才能够真实的访问到。
7. 什么是虚拟内存
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
虚拟内存也叫虚拟存储器,基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其余部分留在外存,就可以启动程序执行。
8. 什么是共享内存
共享内存是进程间通信的一种方式。
共享内存允许两个不相关的进程访问同一个逻辑内存,共享内存是两个正在运行的进程之间共享和传递数据的一种非常有效的方式。
不同进程之间共享的内存通常为同一段物理内存。
进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。
9. 页面置换算法
程序在运行时,在请求分页系统中,每当所要访问的页面不在内存时,便产生一个缺页中断,需要将所缺的页调入内存。
如果内存中有空闲块,则分配一个块,将要调入的页装入该块,并修改页表中的相应页表项。
但内存已无空闲空间时,就需要从内存中淘汰某页,而选择淘汰哪个页面的算法就是页面置换算法。
①最佳置换算法(OPT)
最佳置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。
但是由于人们目前无法预知进程在内存下的若干页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。
最佳置换算法可以用来评价其它算法。
②先进先出页面置换算法(FIFO)
优先淘汰最早进入内存的页面,即在内存中驻留时间最久的页面。
该算法实现:把调入内存的页面根据先后次序链接成队列,设置一个指针总指向最早的页面。
但该算法与进程实际运行时的规律不适应,因为在进程中,有的页面经常被访问。
③最近最久未使用置换算法(LRU)
选择最近最长时间未访问过的页面予以淘汰,
它认为过去一段时间未访问过的页面,在最近的将来可能也不会被访问。
该算法为每个页面设置一个访问字段,来记录页面自上次访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
④时钟置换算法(CLOCK)
时间置换算法是给每一帧关联一个附加位,称为使用位。当某一页首次装入主存时,该帧的使用位设置位1;当该页随后再被访问到时,它的使用位也被置为1。
10. 调度算法
1.先来先服务调度算法(FCFS)
从就绪的队列中选择最先进入该队列的进程进行处理。
2.短作业优先调度算法(SJF)
从就绪队列中选择一个估计运行时间最短的进程进行处理。
3.优先级调度算法
从就绪队列中选择优先级最高的进程进行处理。
4.高响应比优先调度算法
先计算队列中每个作业的等待时间和估计运行时间的比值作为响应比,从中选出响应比最高的作业运行。
5.时间片轮转调度算法
按照先来先服务的原则执行队列中的进程,但是只能运行一个时间片,然后再重新排队,等候再次运行。
6.多级反馈队列调度算法
多级反馈队列调度算法是时间片轮转调度算法和优先级调度算法的,通过动态调度调整整个进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。
#高频知识点汇总##Java##学习路径#