操作系统面试必问 50 题!
- 作者
- Name
- 青玉白露
- Github
- @white0dew
- Modified on
- Reading time
- 27 分钟
阅读:.. 评论:..
问题一览
- 什么是操作系统?
- 操作系统主要有哪些功能?
- 常见的操作系统有哪些?
- 什么是用户态和内核态?
- 为什么要有用户态和内核态?只有一个内核态不行么?
- 用户态和内核态是如何切换的?
- 什么是系统调用?
- 系统调用的过程了解吗?
- 什么是进程和线程?
- 进程和线程的区别是什么?
- 有了进程为什么还需要线程?
- 为什么要使用多线程?
- 线程间的同步的方式有哪些?
- PCB 是什么?包含哪些信息?
- 进程有哪几种状态?
- 进程间的通信方式有哪些?
- 进程的调度算法有哪些?
- 什么是僵尸进程和孤儿进程?
- 如何查看是否有僵尸进程?
- 什么是死锁?
- 能列举一个操作系统发生死锁的例子吗?
- 产生死锁的四个必要条件是什么?
- 能写一个模拟产生死锁的代码吗?
- 解决死锁的方法有哪些?
- 什么是内存碎片?
- 常见的内存管理方式有哪些?
- 什么是虚拟内存?有什么用?
- 没有虚拟内存有什么问题?
- 什么是虚拟地址和物理地址?
- 什么是虚拟地址空间和物理地址空间?
- 虚拟地址与物理内存地址是如何映射的?
- 段表有什么用?地址翻译过程是怎样的?
- 通过段号一定要找到对应的段表项吗?得到最终的物理地址后对应的物理内存一定存在吗?
- 分段机制为什么会导致内存外部碎片?
- 页表有什么用?地址翻译过程是怎样的?
- 通过虚拟页号一定要找到对应的物理页号吗?找到了物理页号得到最终的物理地址后对应的物理页一定存在吗?
- 单级页表有什么问题?为什么需要多级页表?
- TLB 有什么用?使用 TLB 之后的地址翻译流程是怎样的?
- 换页机制有什么用?
- 什么是页缺失?
- 常见的页面置换算法有哪些?
- FIFO 页面置换算法性能为何不好?
- 哪一种页面置换算法实际用的比较多?
- 分页机制和分段机制有哪些共同点和区别?
- 局部性原理是什么?
- 文件系统主要做了什么?
- 硬链接和软链接有什么区别?
- 硬链接为什么不能跨文件系统?
- 提高文件系统性能的方式有哪些?
- 常见的磁盘调度算法有哪些?
什么是操作系统?
操作系统是管理计算机硬件和软件资源的系统软件,是计算机系统的核心。
它为用户提供了一个与硬件交互的接口,同时也管理和调度系统资源。
操作系统主要有哪些功能?
操作系统主要提供以下基本功能:
- 进程管理:管理进程、线程,决定哪个进程、线程使用CPU(进程调度)
- 内存管理:决定内存的分配和回收
- 设备管理:为进程与硬件设备之间提供通信能力
- 提供系统调用:作为用户程序与操作系统之间的接口
常见的操作系统有哪些?
常见的操作系统包括:
- Windows
- Linux
- macOS
- Android
- iOS
什么是用户态和内核态?
用户态和内核态是操作系统的两种运行级别:
- 用户态:普通的用户程序运行的模式,权限较低,不能直接访问硬件资源
- 内核态:操作系统内核运行的模式,拥有最高权限,可以直接访问硬件资源
为什么要有用户态和内核态?只有一个内核态不行么?
设置用户态和内核态的主要目的是为了保护系统的安全和稳定性。
如果只有内核态,所有程序都能直接访问硬件和关键资源,可能会导致系统崩溃或被恶意程序利用。
通过区分用户态和内核态,可以限制普通程序的权限,提高系统的安全性和稳定性。
用户态和内核态是如何切换的?
用户态到内核态的切换通常通过系统调用、中断或异常来实现。
当用户程序需要执行特权操作时,会触发从用户态到内核态的切换。
完成操作后,系统会再次切换回用户态。
什么是系统调用?
系统调用是用户程序请求操作系统内核服务的接口。它允许用户程序访问操作系统提供的服务,如文件操作、进程控制等。
系统调用的过程了解吗?
系统调用的基本过程如下:
- 用户程序通过特定的指令(如x86的INT指令)触发系统调用
- CPU切换到内核态
- 操作系统执行相应的系统调用处理程序
- 完成请求的操作
- 返回结果给用户程序
- CPU切换回用户态
什么是进程和线程?
- 进程:是操作系统中的一个执行实体,拥有独立的内存空间和系统资源
- 线程:是进程内的一个执行单元,共享所属进程的内存空间和资源
进程和线程的区别是什么?
上图已经表现了区别,主要区别包括:
- 资源占用:进程是资源分配的基本单位,线程是CPU调度的基本单位
- 内存空间:进程有独立的内存空间,线程共享所属进程的内存空间
- 创建和切换开销:创建和切换进程的开销比线程大
- 通信方式:进程间通信相对复杂,线程间通信较简单
有了进程为什么还需要线程?
线程的引入是为了提高程序的并发性和响应速度。
相比进程,线程的创建和切换开销更小,可以更有效地利用多核处理器,提高系统的并发性能。
为什么要使用多线程?
使用多线程可以:
- 提高程序的并发性
- 更好地利用多核处理器
- 提高程序的响应速度
- 简化程序结构,使得复杂任务的处理更加直观
线程间的同步的方式有哪些?
常见的线程同步方式包括:
- 互斥锁(Mutex)
- 信号量(Semaphore)
- 条件变量(Condition Variable)
- 读写锁(Read-Write Lock)
- 原子操作(Atomic Operations)
PCB是什么?包含哪些信息?
PCB(Process Control Block)是进程控制块,是操作系统用来管理进程的数据结构。
它通常包含以下信息:
- 进程ID
- 进程状态
- 程序计数器
- CPU寄存器
- CPU调度信息
- 内存管理信息
- I/O状态信息
- 账户信息
进程有哪几种状态?
进程通常有以下几种基本状态:
- 创建(New)
- 就绪(Ready)
- 运行(Running)
- 阻塞(Blocked)
- 终止(Terminated)
进程间的通信方式有哪些?
常见的进程间通信方式包括:
- 管道(Pipe)
- 消息队列(Message Queue)
- 共享内存(Shared Memory)
- 信号量(Semaphore)
- 套接字(Socket)
- 信号(Signal)
进程的调度算法有哪些?
常见的进程调度算法包括:
- 先来先服务(FCFS)
- 短作业优先(SJF)
- 优先级调度
- 轮转调度(Round Robin)
- 多级反馈队列调度
什么是僵尸进程和孤儿进程?
- 僵尸进程:子进程结束后,父进程没有及时回收子进程的资源,导致子进程残留在系统中的进程
- 孤儿进程:父进程在子进程结束之前退出,导致子进程成为孤儿,被init进程收养的进程
如何查看是否有僵尸进程?
在Linux系统中,可以使用以下命令查看僵尸进程:
ps aux | grep Z
或
top
然后查看"S"列,如果显示"Z",则表示是僵尸进程。
什么是死锁?
死锁是指两个或多个进程互相等待对方释放资源,导致所有相关进程无法继续执行的状态。
能列举一个操作系统发生死锁的例子吗?
一个典型的死锁例子是"哲学家就餐问题":
五个哲学家坐在圆桌旁,每人之间放着一把叉子。每个哲学家需要两把叉子才能吃饭。
如果每个哲学家都先拿起左边的叉子,然后等待右边的叉子,就会发生死锁。
产生死锁的四个必要条件是什么?
产生死锁的四个必要条件是:
- 互斥条件:资源不能被多个进程同时使用
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求
- 不剥夺条件:进程已获得的资源在未使用完之前不能被强行剥夺
- 循环等待条件:存在一个进程等待队列,形成首尾相接的循环等待资源关系
能写一个模拟产生死锁的代码吗?
以下是一个简单的Java代码示例,模拟两个线程互相等待对方的资源,从而产生死锁:
public class DeadlockExample { public static void main(String[] args) { final Object resource1 = new Object(); final Object resource2 = new Object(); Thread thread1 = new Thread(() -> { synchronized (resource1) { System.out.println("Thread 1: Holding resource 1..."); try { Thread.sleep(100);} catch (InterruptedException e) {} System.out.println("Thread 1: Waiting for resource 2..."); synchronized (resource2) { System.out.println("Thread 1: Holding resource 1 and resource 2..."); } } }); Thread thread2 = new Thread(() -> { synchronized (resource2) { System.out.println("Thread 2: Holding resource 2..."); try { Thread.sleep(100);} catch (InterruptedException e) {} System.out.println("Thread 2: Waiting for resource 1..."); synchronized (resource1) { System.out.println("Thread 2: Holding resource 2 and resource 1..."); } } }); thread1.start(); thread2.start(); } }
解决死锁的方法有哪些?
解决死锁的方法主要有:
- 预防死锁:破坏产生死锁的四个必要条件之一
- 避免死锁:使用银行家算法等方法,在资源分配之前预测是否会导致死锁
- 检测和解除死锁:允许死锁发生,但通过周期性检测并解除死锁状态
- 忽略死锁:适用于发生概率极低且影响不大的情况
什么是内存碎片?
内存碎片是指内存空间中的小块未使用内存,这些小块内存由于太小或分散而难以被有效利用。
主要分为两种:
- 内部碎片:分配给进程的内存块中未被使用的部分
- 外部碎片:已分配的内存块之间的小块空闲空间
常见的内存管理方式有哪些?
常见的内存管理方式包括以下五种:
一、固定分区管理
- 原理:在系统运行前,将内存空间划分为若干个固定大小的分区,每个分区只能装入一道作业。分区的大小可以相等,也可以不等。
- 优点:实现简单,易于管理,不需要复杂的内存分配和回收算法。
- 缺点:内存利用率不高,因为分区大小固定,可能会出现小作业无法装入大分区,而大作业无法装入小分区的情况;缺乏灵活性,不能根据作业的实际需求动态调整分区大小。
二、动态分区管理
- 原理:在系统运行过程中,根据作业的大小动态地划分内存空间。当有新作业进入系统时,系统为其分配一块足够大的内存空间;当作业运行结束后,回收其所占用的内存空间,并将其合并到空闲内存中。
- 优点:提高了内存利用率,能够根据作业的实际需求分配内存空间。
- 缺点:容易产生内存碎片,随着作业的不断进入和退出,内存空间会被分割成许多不连续的小块,降低了内存的可用性;内存分配和回收算法相对复杂,需要耗费一定的时间和系统资源。
三、分页管理
- 原理:将内存空间和程序都划分为大小相等的页面,程序的页面可以离散地存储在内存的不同页面中。通过页表记录程序页面与内存页面的对应关系,实现地址转换。
- 优点:有效地解决了外部碎片问题,提高了内存利用率;便于实现虚拟内存,将程序的一部分页面暂存到外存中,当需要时再调入内存,从而扩大了程序的可用内存空间。
- 缺点:页表的存储和管理需要占用一定的内存空间;地址转换过程增加了系统的开销。
四、分段管理
- 原理:将程序按照逻辑结构划分为若干个段,如代码段、数据段、栈段等。每个段有自己的名字、长度和起始地址。内存分配以段为单位,段可以离散地存储在内存中。通过段表记录段与内存的对应关系,实现地址转换。
- 优点:便于程序的模块化设计和管理,提高了程序的可读性和可维护性;有利于实现共享和保护,不同程序的相同段可以共享,同时可以对不同的段设置不同的访问权限。
- 缺点:同分页管理一样,段表的存储和管理需要占用一定的内存空间;地址转换过程增加了系统的开销;容易产生外部碎片,因为段的大小不固定。
五、段页式管理
- 原理:结合了分段管理和分页管理的优点,将程序先按逻辑结构划分为若干个段,每个段再划分为大小相等的页面。通过段表和页表实现地址转换。
- 优点:既具有分段管理的优点,便于程序的模块化设计和管理,又具有分页管理的优点,有效地解决了外部碎片问题,提高了内存利用率。
- 缺点:地址转换过程更加复杂,需要同时查询段表和页表,增加了系统的开销;段表和页表的存储和管理需要占用更多的内存空间。
什么是虚拟内存?有什么用?
虚拟内存是一种内存管理技术,它为进程提供一个连续的虚拟地址空间,使得进程认为它拥有连续的可用内存。虚拟内存的主要作用包括:
- 扩展物理内存的容量
- 简化内存管理
- 提高内存利用率
- 实现进程间的内存隔离
没有虚拟内存有什么问题?
如果没有虚拟内存,可能会出现以下问题:
- 物理内存容量限制程序的运行
- 内存碎片问题更加严重
- 多进程并发执行时,内存管理更加复杂
- 进程间的内存隔离更难实现,可能导致安全问题
什么是虚拟地址和物理地址?什么是虚拟地址空间和物理地址空间?
- 虚拟地址:程序所使用的内存地址,是一个逻辑概念
- 物理地址:实际的内存硬件中的地址,对应于内存条上的具体位置
- 虚拟地址空间:进程可以使用的虚拟内存地址的集合
- 物理地址空间:实际物理内存中可用的地址的集合
虚拟地址与物理内存地址是如何映射的?
根据提供的内容,虚拟地址到物理地址的映射是通过CPU芯片中的内存管理单元(MMU)完成的。进程持有的虚拟地址会通过MMU的映射关系转换成物理地址,然后再通过物理地址访问内存。
段表有什么用?地址翻译过程是怎样的?
段表用于实现分段内存管理,它记录了每个段的基地址和长度。地址翻译过程大致如下:
- 从虚拟地址中提取段号和段内偏移
- 使用段号在段表中查找对应的段表项
- 检查段内偏移是否越界
- 将段表项中的基地址与段内偏移相加,得到物理地址
通过段号一定要找到对应的段表项吗?得到最终的物理地址后对应的物理内存一定存在吗?
不一定。如果段号无效或段表项不存在,会触发段错误。即使找到了物理地址,对应的物理内存也不一定存在,可能需要触发缺页中断来加载所需的内存页。
分段机制为什么会导致内存外部碎片?
分段机制会导致内存外部碎片,因为不同大小的段被分配和释放后,会在内存中留下不连续的小块空闲空间,这些空间可能太小而无法被有效利用。
页表有什么用?地址翻译过程是怎样的?
页表用于实现分页内存管理,它记录了虚拟页号到物理页号的映射关系。地址翻译过程大致如下:
- 从虚拟地址中提取虚拟页号和页内偏移
- 使用虚拟页号在页表中查找对应的物理页号
- 将物理页号与页内偏移组合,得到物理地址
通过虚拟页号一定要找到对应的物理页号吗?找到了物理页号得到最终的物理地址后对应的物理页一定存在吗?
不一定。如果虚拟页号无效或对应的页表项不存在,会触发缺页中断。
即使找到了物理页号和物理地址,对应的物理页也不一定在内存中。
如果该页面当前不在物理内存中,系统会触发缺页中断,从磁盘将所需页面加载到内存中。
单级页表有什么问题?为什么需要多级页表?
单级页表的主要问题:
- 内存占用大:对于大型地址空间,单级页表可能会占用大量连续内存
- 内存碎片:可能导致大量内存碎片
- 访问效率低:对于大型页表,查找速度可能较慢
多级页表的优势:
- 减少内存占用:只需要为实际使用的地址空间分配页表
- 灵活性:可以更灵活地管理大型地址空间
- 提高访问效率:可以利用缓存机制提高访问速度
TLB有什么用?使用TLB之后的地址翻译流程是怎样的?
TLB (Translation Lookaside Buffer) 的作用:
- 加速虚拟地址到物理地址的转换
- 缓存最近使用的页表项
使用TLB后的地址翻译流程:
- 检查TLB中是否存在虚拟页号对应的条目
- 如果存在(TLB命中),直接获取物理页号
- 如果不存在(TLB未命中),按常规方式查询页表
- 将新查询到的页表项添加到TLB中
- 使用获得的物理页号和页内偏移计算物理地址
换页机制有什么用?
换页机制的作用:
- 实现虚拟内存,使程序可以使用比物理内存更大的地址空间
- 在物理内存不足时,将不常用的页面暂时存储到磁盘上
- 根据需要将页面在内存和磁盘之间进行交换,提高内存利用率
什么是页缺失?
页缺失(Page Fault)是指当程序访问的页面不在物理内存中时发生的情况。
这通常会触发一个中断,操作系统随后会将所需的页面从磁盘加载到内存中。
常见的页面置换算法有哪些?
常见的页面置换算法包括:
- 先进先出(FIFO)算法
- 最近最少使用(LRU)算法
- 最不常用(LFU)算法
- 时钟(Clock)算法
- 最优(OPT)算法(理论算法,实际中难以实现)
一、先进先出(FIFO)算法
- 原理:选择在内存中驻留时间最长的页面进行置换,即最先进入内存的页面最先被换出。可以使用一个队列来记录页面进入内存的顺序,每次需要置换页面时,选择队首的页面进行置换。
- 优点:实现简单,不需要额外的硬件支持。
- 缺点:没有考虑页面的使用频率和未来的访问情况,可能会把经常使用的页面换出,导致性能下降。例如,对于一些循环访问的页面序列,FIFO 算法可能会频繁地进行页面置换。
二、最近最少使用(LRU)算法
- 原理:选择最近最久未使用的页面进行置换。可以使用一个栈或链表来记录页面的使用顺序,每次访问一个页面时,将其移到栈顶或链表头部,表示它是最近使用的页面。当需要置换页面时,选择栈底或链表尾部的页面进行置换。
- 优点:能够较好地反映页面的使用情况,减少频繁换页的情况,提高系统性能。
- 缺点:实现相对复杂,需要额外的硬件支持或软件算法来记录页面的使用顺序。例如,需要使用专门的寄存器或栈来存储页面的访问信息,增加了系统的开销。
三、最不常用(LFU)算法
- 原理:选择在一段时间内使用次数最少的页面进行置换。可以为每个页面设置一个计数器,记录页面的使用次数。当需要置换页面时,选择计数器值最小的页面进行置换。
- 优点:考虑了页面的使用频率,能够保留经常使用的页面,减少换页次数。
- 缺点:计数器的维护需要一定的开销,而且可能会受到页面访问模式的影响。例如,如果一个页面在一段时间内被频繁访问,但之后很长时间都未被访问,它的计数器值可能仍然较高,导致其他更需要被置换的页面无法被换出。
四、时钟(Clock)算法
- 原理:将内存中的页面组织成一个环形链表,类似于时钟的表盘。每个页面有一个访问位(use bit),初始时所有页面的访问位都为 0。当一个页面被访问时,将其访问位设置为 1。当需要置换页面时,从当前指针位置开始,依次检查每个页面的访问位。如果访问位为 0,表示该页面最近未被访问过,就选择这个页面进行置换;如果访问位为 1,表示该页面最近被访问过,就把这个页面的访问位清 0,继续检查下一个页面。
- 优点:实现相对简单,不需要额外的硬件支持。与 FIFO 算法相比,能够减少一些不必要的页面置换。
- 缺点:可能会出现一些不合理的置换情况,例如,一个页面虽然最近被访问过,但如果它在很长一段时间内都不会再被访问,而其他页面虽然最近未被访问过,但在未来可能会被频繁访问,此时时钟算法可能会选择错误的页面进行置换。
五、最优(OPT)算法(理论算法,实际中难以实现)
- 原理:选择在未来最长时间内不会被访问的页面进行置换。这需要预先知道每个页面在未来的访问情况,显然在实际系统中是不可能做到的。
- 优点:如果能够实现,它可以保证系统的性能最优,即换页次数最少。
- 缺点:只具有理论意义,实际中无法实现。通常用于评估其他页面置换算法的性能。
FIFO页面置换算法性能为何不好?
FIFO(先进先出)页面置换算法性能不好的原因:
- 不考虑页面的访问频率,可能会置换出经常使用的页面
- 可能导致Belady异常:增加物理页框数反而增加缺页次数
- 没有考虑页面的局部性原理,不能很好地适应程序的访问模式
哪一种页面置换算法实际用的比较多?
在实际系统中,常用的页面置换算法是时钟(Clock)算法或其变种。
时钟(Clock)页面置换算法又称最近未用(Not Recently Used,NRU)算法,是一种常用的页面置换算法。
一、基本原理
把物理内存中的所有页面组织成一个环形链表,类似于时钟的表盘,表针指向一个页面。页面中有一个访问位(use bit)和一个修改位(dirty bit)。
- 当发生缺页中断时,算法开始遍历这个环形链表,就像时钟的表针在走动。
- 每遇到一个页面,就检查其访问位。如果访问位为 0,表示该页面最近未被访问过,就选择这个页面进行置换;如果访问位为 1,表示该页面最近被访问过,就把这个页面的访问位清 0,继续检查下一个页面。
二、算法流程
- 初始化时,将所有页面放入环形链表中,并设置访问位和修改位。
- 当有新的页面需要调入内存时,如果内存已满,就启动时钟算法进行页面置换。
- 算法从当前指针位置开始,依次检查每个页面的访问位和修改位。如果访问位为 0 且修改位为 0,直接置换该页面;如果访问位为 0 但修改位为 1,就把该页面的访问位清 0,继续检查下一个页面,直到找到一个可置换的页面。
- 如果遍历一圈后仍未找到可置换的页面,就重新开始遍历,直到找到为止。
三、优点
- 实现相对简单,不需要太多复杂的数据结构和计算。
- 性能接近LRU,但实现成本更低
- 避免了FIFO的一些问题,如Belady异常
- 能够较好地平衡页面的使用频率和最近访问时间,在一定程度上提高了内存的利用率。
四、缺点
- 可能会频繁地进行页面置换,尤其是在内存紧张且页面访问模式比较随机的情况下,导致系统性能下降。
- 对于一些特殊的访问模式,如连续访问相同的页面集合,可能会出现不必要的页面置换,降低算法的效率。
分页机制和分段机制有哪些共同点和区别?
共同点:
- 都是内存管理的方法
- 都支持非连续内存分配
- 都需要地址转换机制
区别:
- 单位不同:
- 分页以固定大小的页为单位
- 分段以不同大小的段为单位
- 地址结构:
- 分页地址由页号和页内偏移组成
- 分段地址由段号和段内偏移组成
- 共享和保护:
- 分页难以实现共享和保护
- 分段更容易实现共享和保护
- 碎片问题:
- 分页主要产生内部碎片
- 分段可能产生外部碎片
- 程序员感知:
- 分页对程序员透明
- 分段可以被程序员感知和使用
局部性原理是什么?
局部性原理是指程序在执行时呈现出局部性特征,主要包括:
- 时间局部性:最近被引用的项目可能在不久的将来再次被引用
- 空间局部性:被引用项目附近的项目也可能在不久的将来被引用
- 顺序局部性:程序倾向于顺序执行指令
局部性原理是许多优化技术(如缓存、预取等)的基础。
文件系统主要做了什么?
文件系统主要完成以下任务:
- 管理和组织存储设备上的文件
- 提供文件的创建、读取、写入、删除等操作接口
- 实现文件的命名和目录结构
- 管理存储空间,分配和回收磁盘块
- 提供文件访问控制和安全机制
- 支持文件的备份和恢复
硬链接和软链接有什么区别?
硬链接:
- 与原文件共享同一个inode
- 只能在同一文件系统中创建
- 删除任一链接,文件依然存在
- 不能链接目录
软链接(符号链接):
- 创建一个新的inode,指向原文件路径
- 可以跨文件系统
- 原文件删除后,链接失效
- 可以链接目录
硬链接为什么不能跨文件系统?
硬链接不能跨文件系统的原因:
- 硬链接本质上是同一个文件的多个目录项
- 不同文件系统有独立的inode编号空间
- 跨文件系统无法保证inode编号的唯一性
- 文件系统管理和维护会变得复杂
提高文件系统性能的方式有哪些?
提高文件系统性能的方法包括:
- 使用缓存:如页缓存、inode缓存、目录项缓存
- 预读和预写:预测性地读取或写入数据
- 异步I/O:允许其他操作在I/O等待时继续执行
- 日志文件系统:提高文件系统的可靠性和恢复速度
- 优化文件分配策略:如连续分配、块组等
- 使用更快的存储介质:如SSD
- RAID技术:提高I/O并行度和可靠性
- 文件系统碎片整理
- 合理的目录结构设计
常见的磁盘调度算法有哪些?
常见的磁盘调度算法包括:
- 先来先服务(FCFS):按请求到达的顺序处理
- 最短寻道时间优先(SSTF):选择离当前磁头位置最近的请求
- 扫描算法(SCAN):磁头沿一个方向移动,服务遇到的所有请求,到达一端后改变方向
- 循环扫描算法(C-SCAN):类似SCAN,但只在一个方向上服务请求
- LOOK和C-LOOK:SCAN和C-SCAN的改进版,磁头只移动到最远的请求位置
- N步扫描(N-step SCAN):将请求分成N个子队列,每次扫描处理一个子队列