[八股]操作系统常见面试题

操作系统

1.进程和线程的差别?

进程和线程是操作系统中的两个重要概念。

  1. 进程(Process)是系统资源分配的基本单位,一个进程可以包括多个线程。每个进程都拥有独立的地址空间、文件描述符、环境变量等系统资源。进程间通过进程间通信(IPC)进行数据交换和协调。
  2. 线程(Thread)是进程的执行单位,一个进程可以包括多个线程。线程共享进程的地址空间和系统资源,每个线程拥有独立的栈空间和程序计数器。线程间通过共享内存和同步机制(例如互斥锁、条件变量等)进行数据交换和协调。

总的来说,进程和线程的主要差别在于:

  1. 资源开销:每个进程都有独立的地址空间和系统资源,因此进程间的切换开销相对较大,而线程间切换的开销相对较小。
  2. 内存管理:进程之间拥有独立的地址空间,而线程共享进程的地址空间,可以访问同一份数据。
  3. 并发性:由于进程之间拥有独立的资源,因此进程之间的并发性相对较低。而线程之间共享资源,可以更加方便地实现并发。
  4. 可扩展性:由于每个进程拥有独立的资源,因此进程之间相互独立,具有很好的可扩展性。而线程共享进程的资源,因此线程的数量受到了限制,容易出现资源争用的情况。

总的来说,线程的轻量级和高效性使得它们适合于并发编程和资源共享的场景,而进程的独立性和可扩展性使得它们适合于需要隔离和保护的场景。

2.协程和线程的区别

调度方式:线程由操作系统内核进行调度,是抢占式的。当一个线程需要等待某些事件发生时,会主动放弃CPU的控制权,线程调度器会将CPU分配给其他线程。而协程是协作式的,由程序员在代码中显式地指定切换点,协程调度器在切换点进行协程切换。

并发性实现:线程在操作系统内核的帮助下实现并发,一个进程可以包含多个线程并发执行。而协程则通过单线程内部的状态机机制实现并发。协程的并发性依赖于协程调度器的调度,只有当协程主动让出控制权时,才能进行协程切换。

上下文切换开销:线程的上下文切换开销比较大,需要保存线程的堆栈、寄存器等状态。而协程的上下文切换开销比较小,只需要保存少量的状态信息,例如程序计数器和寄存器等。

3.并发和并行的区别

并行就是在同一时刻,有多个任务在执行。这个需要多核处理器才能完成,在微观上就能同时执行多条指令,不同的程序被放到不同的处理器上运行,这个是物理上的多个进程同时进行。

总的来说,并行是在物理上同时执行多个任务,而并发是在逻辑上同时执行多个任务。

4.进程和线程的切换流程

进程和线程都是计算机中的执行单元,但是它们之间的切换流程有所不同。

在操作系统中,进程切换是通过上下文切换来实现的。当一个进程被抢占或者它的时间片到了,操作系统就会保存当前进程的上下文信息(如寄存器的值、程序计数器等等),并加载下一个要执行的进程的上下文信息,然后切换到下一个进程执行。这个过程需要耗费一定的时间和资源,因为需要保存和恢复大量的进程上下文信息。

而线程的切换则比进程切换更加轻量级,因为线程是共享同一个进程的地址空间的。当一个线程被抢占或者它的时间片到了,操作系统只需要保存当前线程的寄存器状态即可,不需要保存整个进程的上下文信息。然后它就可以切换到下一个要执行的线程,重新加载它的寄存器状态,并开始执行它。这个过程比进程切换要快很多,因为只需要保存和恢复少量的线程上下文信息。

需要注意的是,在多核处理器上,进程和线程的切换可以并行进行,因为每个核心可以同时执行一个进程或线程。这可以提高系统的并发能力和吞吐量。

5.为什么虚拟地址空间切换比较费时

虚拟地址空间切换通常是指进程间切换或者用户态和内核态切换时,由于需要保存和恢复进程或者内核上下文而产生的开销。具体原因如下:

  1. 上下文切换:当一个进程被调度器挂起,系统会保存该进程的上下文(包括寄存器、程序计数器、栈指针等),并切换到另一个进程。当再次切换回该进程时,系统需要恢复之前保存的上下文,这个过程需要耗费一定时间。
  2. TLB刷新:虚拟地址空间切换时,进程的虚拟地址空间映射关系也需要重新建立,这就需要刷新翻译后备缓冲器(Translation Lookaside Buffer,TLB)中的内容。因为TLB中存储了虚拟地址与物理地址的映射关系,而不同进程或者内核态和用户态之间的虚拟地址映射关系不同,所以切换时需要刷新TLB,这也会产生一定的开销。
  3. 虚拟内存机制:虚拟地址空间切换时,由于进程的虚拟地址空间中包含了页表等虚拟内存管理机制的数据结构,所以切换时需要刷新这些数据结构,并进行相关的操作。这也会导致一定的开销。

综上所述,虚拟地址空间切换需要进行上下文切换、TLB刷新和虚拟内存机制的切换等多种操作,因此会产生一定的开销,导致切换比较费时。

6.进程间通信方式有哪些

进程间通信(IPC)是指不同进程之间进行数据传递、共享和协作的方式。常见的进程间通信方式包括:

  1. 管道(Pipe):管道是一种半双工的通信方式,一般由两个进程使用。一个进程将数据写入管道,另一个进程则从管道中读取数据。
  2. 命名管道(Named Pipe):与管道不同,命名管道有一个名字,它们可以用于不同进程之间的通信,也可以用于同一进程内的不同线程之间的通信。
  3. 信号(Signal):信号是一种异步通信方式,进程可以向另一个进程发送信号,当另一个进程接收到信号时,它可以采取相应的行动。
  4. 共享内存(Shared Memory):共享内存允许多个进程访问同一块内存,从而实现进程间的数据共享。不过需要协调各个进程的读写操作,避免数据混乱。
  5. 消息队列(Message Queue):消息队列是一种消息传递机制,允许不同进程之间传递指定类型的消息。
  6. 信号量(Semaphore):信号量是一种计数器,用于同步多个进程的访问共享资源。当一个进程访问共享资源时,它必须先获得信号量,然后释放信号量以允许其他进程访问该资源。
  7. 套接字(Socket):套接字是一种网络编程方式,可以用于在不同主机上的进程之间进行通信。套接字可以实现不同进程之间的数据传输和共享。

优缺点

  • 管道:速度慢,容量有限;
  • Socket:任何进程间都能通讯,但速度慢;
  • 消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题;
  • 信号量:不能传递复杂消息,只能用来同步;
  • 共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。

7.进程间同步的方式

进程间同步是指为了保证多个进程之间按照特定顺序执行而采取的措施,主要是通过互斥和同步机制来避免进程之间的冲突和竞争。

常见的进程间同步方式包括:

  1. 互斥锁(Mutex):互斥锁是一种最常见的同步机制,它可以保证在任意时刻只有一个进程访问临界资源,其他进程必须等待互斥锁被释放才能访问该资源。
  2. 信号量(Semaphore):信号量是一种计数器,用于控制多个进程之间对共享资源的访问,可以实现进程之间的同步和互斥操作。
  3. 条件变量(Condition Variable):条件变量用于在多个进程之间进行通信,当共享资源不满足条件时,该进程可以等待在条件变量上,直到满足条件后再执行。
  4. 读写锁(Read-Write Lock):读写锁是一种特殊的互斥锁,它可以同时允许多个进程读取共享资源,但只允许一个进程写入共享资源。
  5. 屏障(Barrier):屏障用于在多个进程之间进行同步操作,当所有进程都到达屏障时,它们可以一起执行后续操作。
  6. 事件(Event):事件是一种同步机制,可以用于多个进程之间的通信和同步,当一个进程发生事件时,其他进程可以接收到该事件并进行相应的操作。

8.线程同步的方式

同上1-5

  1. 原子操作(Atomic Operation):原子操作是一种线程安全的操作,可以保证多个线程对共享资源的访问是原子的,即不会发生竞争和冲突

9.线程的分类

根据线程的特性和使用方式,可以将线程分为以下几种类型:

  1. 用户线程:用户线程是由应用程序创建和管理的线程,它们运行在用户空间中,不受操作系统直接控制,需要应用程序自己实现线程的调度和同步。
  2. 内核线程:内核线程是由操作系统创建和管理的线程,它们运行在内核空间中,可以受到操作系统的直接控制,由操作系统进行线程调度和同步。
  3. 守护线程:守护线程是在后台运行的线程,它们通常被用于执行一些周期性或长时间运行的任务,如垃圾回收、日志记录等。
  4. 实时线程:实时线程是指需要满足实时性要求的线程,它们需要在特定的时间内完成任务,不能受到其他线程或操作系统的干扰。
  5. 线程池线程:线程池线程是一种预先创建好的线程,可以重复利用,避免了线程创建和销毁的开销,提高了系统的性能。

根据线程之间的关系,线程还可以分为以下两种类型:

  1. 主线程:主线程是指应用程序启动时创建的第一个线程,它负责程序的初始化和资源的分配,通常是其他线程的父线程。
  2. 子线程:子线程是由主线程或其他线程创建的线程,它们通常用于执行一些独立的任务,可以与其他线程并行运行。

10.什么是临界区,如何解决冲突

临界区是指程序中访问共享资源的代码段,这些代码段需要保证在同一时间内只有一个线程能够访问,否则就会引发竞争和冲突。

为了解决多个线程访问临界区时的冲突问题,需要采取同步机制来保证线程的顺序执行,常见的解决冲突的方法包括:

  1. 互斥锁(Mutex):互斥锁是一种最常见的同步机制,它可以保证在任意时刻只有一个线程访问临界资源,其他线程必须等待互斥锁被释放才能访问该资源。
  2. 信号量(Semaphore):信号量是一种计数器,用于控制多个线程之间对共享资源的访问,可以实现线程之间的同步和互斥操作。
  3. 条件变量(Condition Variable):条件变量用于在多个线程之间进行通信,当共享资源不满足条件时,该线程可以等待在条件变量上,直到满足条件后再执行。
  4. 原子操作(Atomic Operation):原子操作是一种线程安全的操作,可以保证多个线程对共享资源的访问是原子的,即不会发生竞争和冲突。

11.什么是死锁?死锁产生的条件?

什么是死锁

在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。

死锁产生的四个必要条件:(有一个条件不成立,则不会产生死锁)

  • 互斥条件:一个资源一次只能被一个进程使用
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放
  • 不剥夺条件:进程获得的资源,在未完全使用完之前,不能强行剥夺
  • 循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系

为了避免和解决死锁问题,常见的方法包括:

  1. 避免死锁:在设计和实现程序时,需要避免发生死锁的情况,尽可能减少资源的占用和请求、避免循环等待等。
  2. 检测死锁:在程序运行时,可以通过死锁检测算法来检测是否发生了死锁,如果发现死锁,则采取相应的措施进行解除。
  3. 预防死锁:通过引入超时机制、优先级机制、资源分配策略等方法,预防死锁的发生,使系统具有更好的健壮性和稳定性。
  4. 解除死锁:当发生死锁时,需要采取相应的措施进行解除,常见的方法包括撤销进程、回滚事务、剥夺资源等。

12.进程调度策略

进程调度策略是指操作系统为了提高系统的性能和效率,在多个进程之间进行选择和分配CPU时间片的方法和规则。常见的进程调度策略包括:

  1. 先来先服务调度(FCFS):按照进程的到达顺序进行调度,即越早到达的进程越先获得CPU时间片。适用于CPU繁忙和无阻塞的场景,但容易导致“饥饿”现象。
  2. 短作业优先调度(SJF):按照进程的执行时间进行调度,即执行时间短的进程优先获得CPU时间片。适用于多个短作业同时到达的场景,但无法处理长作业。
  3. 优先级调度:按照进程的优先级进行调度,即优先级高的进程优先获得CPU时间片。可以根据应用场景设置不同的进程优先级,但容易出现“优先级反转”现象。
  4. 时间片轮转调度(RR):将CPU时间分成若干个时间片,每个进程轮流获得一个时间片进行执行。适用于多个进程竞争CPU资源的场景,但需要合理设置时间片大小。
  5. 多级反馈队列调度:将就绪队列分成多个队列,每个队列的时间片大小不同,优先级也不同,进程会根据自己的执行情况被分配到不同的队列。适用于多个长短不一的作业同时存在的场景,但调度复杂度较高。
  6. 最短剩余时间优先:最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。

13.进程有哪些状态

进程一共有5种状态,分别是创建、就绪、运行(执行)、终止、阻塞。

进程五种状态转换图

  • 运行状态就是进程正在CPU上运行。在单处理机环境下,每一时刻最多只有一个进程处于运行状态。
  • 就绪状态就是说进程已处于准备运行的状态,即进程获得了除CPU之外的一切所需资源,一旦得到CPU即可运行。
  • 阻塞状态就是进程正在等待某一事件而暂停运行,比如等待某资源为可用或等待I/O完成。即使CPU空闲,该进程也不能运行。

14.什么是分页

在操作系统中,分页是一种虚拟内存管理机制,用于将进程的逻辑地址空间划分为固定大小的页,这些页通常是连续的内存块。分页机制将进程的虚拟地址空间映射到物理内存中的物理地址空间,从而使得进程能够访问物理内存中的数据。

具体来说,当进程访问一个虚拟地址时,操作系统会根据页表将该虚拟地址转换为物理地址。如果该页不在内存中,操作系统会将其从磁盘中读取到内存中,并更新页表以反映该页的新位置。如果内存已经满了,操作系统可能会使用页面置换算法来决定将哪些页置换出去,以便为新的页腾出空间。

分页机制可以有效地管理进程的内存使用,避免了内存碎片问题,并且可以在多个进程之间共享内存页,从而提高了系统的效率。

15.什么是分段

分段(segmentation)是一种内存管理技术,其中进程的内存空间被划分为不同的段,每个段都具有自己的基址和大小。这些段通常是代码段、数据段、堆栈段等。

分段技术的主要目的是允许进程的不同部分可以独立地增长,而不会相互干扰。这样,代码段可以保持不变,数据段可以在程序运行时动态增长,而堆栈段可以用于存储函数的局部变量和函数调用的参数。

分段还可以用于实现虚拟内存,其中操作系统将进程的虚拟地址映射到物理内存中的实际地址。这允许进程访问超出其物理内存限制的内存区域,并且可以实现内存保护和共享等功能。

需要注意的是,分段技术需要硬件和操作系统的支持,因此不是所有的计算机系统都支持分段技术。

16.分页和分段的区别

分页是将一个进程的逻辑地址空间分成若干大小相等的部分,每一部分称作页面。

分段是一组逻辑信息的集合,即一个作业中相对独立的部分。

分页和分段的主要区别是:

① 页是信息的物理单位,段是信息的逻辑单位;

② 页的大小是由系统固定的,段的长度因段而异,由用户决定;

③ 分页的作业地址空间是一维的,分段的作业地址空间是二维的。

17.什么是交换空间?

操作系统把物理内存(physical RAM)分成一块一块的小内存,每一块内存被称为页(page)。当内存资源不足时,Linux把某些页的内容转移至硬盘上的一块空间上,以释放内存空间。硬盘上的那块空间叫做交换空间(swap space),而这一过程被称为交换(swapping)。物理内存和交换空间的总容量就是虚拟内存的可用容量。

用途:

  • 物理内存不足时一些不常用的页可以被交换出去,腾给系统。
  • 程序启动时很多内存页被用来初始化,之后便不再需要,可以交换出去。

18.物理地址、逻辑地址、有效地址、线性地址、虚拟地址的区别?

  1. 物理地址(Physical Address):物理地址是计算机主存储器中每个存储单元的唯一标识符,通常由硬件生成。物理地址是实际的内存地址,它指向实际存储数据的物理位置。
  2. 逻辑地址(Logical Address):逻辑地址也称为虚拟地址,它是在进程中使用的地址,由进程生成。逻辑地址与物理地址不同,它是相对地址,它指向的是虚拟内存中的地址,而不是物理内存中的地址。逻辑地址是由程序员使用的地址。
  3. 有效地址(Effective Address):**有效地址是指在程序中运算后得到的地址。**例如,在访问数组元素时,程序员给出的地址是逻辑地址,但是在运算时,这个地址需要加上数组的偏移量才能得到实际访问的物理地址,这个实际的地址就是有效地址。
  4. 线性地址(Linear Address):线性地址是指逻辑地址经过段式地址转换(Segmentation)后得到的地址。在使用分段技术管理内存时,逻辑地址空间被划分为若干个段,每个段有自己的段基址和长度。在访问内存时,逻辑地址需要通过段表进行转换,得到线性地址。线性地址是逻辑地址经过地址转换后得到的地址,它是对实际内存地址的抽象。
  5. 虚拟地址(Virtual Address):虚拟地址与逻辑地址类似,它是进程中使用的地址,由进程生成。虚拟地址是指在使用虚拟内存技术时,进程中使用的地址,它是相对地址,而不是实际的物理地址。在使用虚拟内存时,进程访问的是虚拟地址,操作系统将虚拟地址映射到物理地址空间中的实际地址,这样进程就可以访问实际的物理内存了。虚拟地址可以大于物理地址空间的大小,因此它允许进程访问超出物理内存空间的数据,从而实现了更大的内存空间和更好的内存管理。

19.页面替换算法有哪些

  1. 最佳(OPT)页面替换算法:选择在未来最长时间内不再被使用的页面进行替换。这个算法在理论上可以保证最小化页面缺失率,但是实际上由于无法准确预测未来的内存需求,所以实际应用较少。
  2. 先进先出(FIFO)页面替换算法:选择最早被装入内存的页面进行替换,这个算法是最简单的页面替换算法,但是可能会产生Belady异常,即当分配的页面数增加时,页面缺失率反而会增加。
  3. 最近最少使用(LRU)页面替换算法:选择最近最少使用的页面进行替换。这个算法比FIFO更加精细,但是实现起来比较复杂,需要维护页面的访问历史记录。
  4. 时钟(Clock)页面替换算法:也称为二次机会算法,是对FIFO算法的改进。时钟算法使用一个类似于时钟的数据结构来维护页面的访问历史,当页面被访问时,它的标志位被设置为1,当需要替换页面时,算法从当前位置开始扫描,如果当前页面的标志位为1,则将它的标志位置为0并继续扫描,直到找到一个标志位为0的页面进行替换。
  5. 最近未使用(NRU)页面替换算法:将页面分为4个类别,根据页面的访问情况来动态调整页面的类别。在替换页面时,先选择未使用过的页面进行替换,如果没有未使用过的页面,则选择最久未被使用的页面进行替换。
  6. 工作集(Working Set)页面替换算法:为每个进程定义一个工作集,即当前进程正在使用的一组页面。当内存不足时,选择一个进程并替换该进程工作集中最久未被使用的页面,这个算法适合于系统中有多个进程并且进程的页面访问具有较强的局部性特征的情况。

20.什么是缓冲区溢出?有什么危害?

缓冲区溢出(Buffer Overflow)是指在向缓冲区写入数据时,超过了缓冲区本身的容量,导致数据溢出到相邻的内存区域中,从而可能破坏了程序的运行和系统的安全。

缓冲区溢出可能导致以下危害:

  1. 程序崩溃:缓冲区溢出可能导致程序崩溃或死锁,因为它可能会覆盖到程序的控制信息或关键数据,从而使程序无法正常运行。
  2. 数据损坏:缓冲区溢出可能会破坏程序的数据,例如文件或数据库中存储的数据,这可能会导致数据的不一致或丢失。
  3. 安全漏洞:缓冲区溢出是许多安全漏洞的主要原因之一。攻击者可以利用缓冲区溢出漏洞来执行恶意代码,例如在计算机系统中安装后门程序、窃取敏感信息或控制系统。
  4. 提权攻击:攻击者可以利用缓冲区溢出漏洞来获取系统特权,从而使其可以对系统进行更广泛的攻击和控制。

21.什么是虚拟内存?

虚拟内存就是说,让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。虚拟内存使用部分加载的技术,让一个进程或者资源的某些页面加载进内存,从而能够加载更多的进程,甚至能加载比内存大的进程,这样看起来好像内存变大了,这部分内存其实包含了磁盘或者硬盘,并且就叫做虚拟内存。

22. 虚拟内存的实现方式有哪些?

虚拟内存中,允许将一个作业分多次调入内存。釆用连续分配方式时,会使相当一部分内存空间都处于暂时或永久的空闲状态,造成内存资源的严重浪费,而且也无法从逻辑上扩大内存容量。因此,虚拟内存的实需要建立在离散分配的内存管理方式的基础上。虚拟内存的实现有以下三种方式:

  • 请求分页存储管理。
  • 请求分段存储管理。
  • 请求段页式存储管理。

23.讲一讲IO多路复用

在 I/O 多路复用中,一个进程可以同时监听多个文件描述符(File Descriptor),并等待任何一个文件描述符上的 I/O 事件(如读就绪、写就绪等)。当任何一个文件描述符上出现 I/O 事件时,进程就可以对该文件描述符进行操作。这种方式可以避免阻塞式 I/O(Blocking I/O)中的轮询,从而提高程序的效率。

常见的 I/O 多路复用机制有以下几种:

  1. select():最初的 I/O 多路复用技术,支持监听的文件描述符数量有限。
  2. poll():类似于 select(),但支持的文件描述符数量更多。
  3. epoll():Linux 特有的 I/O 多路复用机制,性能更好,支持的文件描述符数量没有限制。

在使用 I/O 多路复用时,程序需要调用相应的系统函数进行监听,并在事件发生时对相应的文件描述符进行操作。因此,相对于传统的阻塞式 I/O 和非阻塞式 I/O,I/O 多路复用需要进行更多的编程工作,但可以获得更好的性能和可扩展性。

24.硬链接和软链接有什么区别?

硬链接和软链接都是用于创建文件或目录之间的链接。它们的主要区别在于它们创建链接的方式和它们链接的文件或目录之间的关系。

硬链接是在文件系统中创建一个新的目录项,该目录项指向同一个物理文件。简而言之,它们是指向同一个文件的不同名字,但是它们在文件系统中的位置不同,因此当一个硬链接被删除时,该文件并不会被删除,因为其他硬链接仍然存在,仍然指向该文件。

相反,软链接是一种特殊的文件类型,它创建了一个指向另一个文件或目录的符号链接。软链接是一个指向实际文件或目录的快捷方式,因此当原始文件或目录被删除时,软链接将不再指向有效的文件或目录。此外,软链接可以跨越不同的文件系统和网络协议,因为它们只是指向目标文件或目录的路径名。

因此,硬链接和软链接之间的主要区别是硬链接是指向同一物理文件的不同名字,而软链接则是指向另一个文件或目录的符号链接。

25. 中断的处理过程?

  1. 保护现场:将当前执行程序的相关数据保存在寄存器中,然后入栈。
  2. 开中断:以便执行中断时能响应较高级别的中断请求。
  3. 中断处理
  4. 关中断:保证恢复现场时不被新中断打扰
  5. 恢复现场:从堆栈中按序取出程序数据,恢复中断前的执行状态。

26. 中断和轮询有什么区别?

中断和轮询之间的主要区别在于它们处理I/O操作的方式。中断是一种异步的机制,设备可以在需要处理数据时通知CPU,从而有效地降低CPU的占用率。相反,轮询是一种同步的机制,需要CPU不断地检查设备状态,浪费大量的CPU时间。

27.什么是用户态和内核态

用户态和内核态是操作系统中的两种不同的运行模式,用于区分操作系统内核代码的执行状态和普通用户进程的执行状态。

用户态指的是进程运行时的一种状态,此时进程只能访问自己的内存空间和资源,不能直接访问操作系统内核代码和系统硬件资源,必须通过系统调用等方式向内核发出请求,由内核代表进程完成操作。

内核态指的是操作系统内核代码运行时的一种状态,此时内核可以访问所有系统资源,包括进程的内存空间和资源。当进程需要执行操作系统提供的一些特权操作时,如修改系统参数、进行设备驱动等,需要通过系统调用进入内核态,由内核完成相应的操作

用户态和内核态的切换是由操作系统内核控制的。当进程需要进行特权操作时,例如读写磁盘、网络通信等,需要进入内核态执行,此时操作系统会将进程的状态从用户态切换到内核态;操作完成后,再将进程的状态切换回用户态,继续执行。

用户态和内核态的切换涉及到CPU的模式切换,因此是有一定开销的,频繁的切换会影响系统的性能。因此,操作系统的设计中需要合理控制用户态和内核态的切换次数,避免无意义的切换和系统性能的浪费。

28.用户态和内核态是如何切换的

内核态和用户态之间的切换由操作系统内核完成,切换过程通常涉及以下步骤:

  1. 应用程序发出系统调用请求。
  2. CPU将当前应用程序的状态保存到内存中,包括程序计数器(PC)和寄存器等。
  3. CPU将控制权转移到操作系统内核,从用户态切换到内核态。
  4. 操作系统内核在内核态中执行系统调用。
  5. 操作系统内核将结果返回给应用程序。
  6. CPU将应用程序的状态从内存中恢复,包括程序计数器和寄存器等。
  7. CPU将控制权转移回应用程序,从内核态切换回用户态。

总之,当应用程序需要访问受限的资源时,它必须通过系统调用从用户态切换到内核态,并在内核态中执行相关操作,然后返回结果并切换回用户态。这个切换过程由操作系统内核完成。

29.在Unix中,常见的IO模型

阻塞IO(Blocking IO):当一个进程执行IO操作时,该进程会一直阻塞,直到IO操作完成为止。这种模型通常会导致CPU资源的浪费,因为进程可能会一直等待IO操作完成而无法执行其他任务。

非阻塞IO(Non-blocking IO):当一个进程执行IO操作时,如果IO操作不能立即完成,进程会立即返回并继续执行其他任务,而不会一直等待IO操作完成。这种模型需要不断轮询IO操作是否完成,也可能会导致CPU资源的浪费。

IO复用(IO Multiplexing):通过select、poll、epoll等系统调用,将多个IO操作绑定到一个进程中,并等待任何一个IO操作完成。当有IO操作完成时,进程会被唤醒,从而处理已经完成的IO操作。这种模型能够处理多个IO操作,而且不会浪费CPU资源。

信号驱动IO(Signal-driven IO):当一个IO操作完成时,内核会向进程发送一个信号,通知该进程已经完成了一个IO操作。该进程可以在信号处理函数中处理该IO操作。这种模型需要额外的信号处理代码,但能够避免轮询IO操作的浪费。

异步IO(Asynchronous IO):当一个IO操作被发起时,进程可以继续执行其他任务,而不需要等待IO操作完成。当IO操作完成后,内核会向进程发送一个通知,告诉该进程IO操作已经完成。这种模型可以极大地提高IO操作的效率,但实现较为复杂。

30.select、poll 和 epoll 之间的区别?

select、poll、epoll都是IO多路复用的机制,用于实现高效的事件驱动IO。

它们的主要区别如下:

  1. select和poll采用轮询的方式,而epoll采用回调的方式,当IO事件发生时会调用回调函数。
  2. select和poll的处理能力受到文件描述符数量限制,而epoll则没有这个限制。
  3. select和poll需要遍历整个文件描述符集合,而epoll只需要遍历发生变化的文件描述符集合。
  4. select和poll每次调用都需要将文件描述符集合从用户空间拷贝到内核空间,而epoll只需要拷贝一次。
  5. select和poll支持的事件类型有限,只能检测普通文件、管道和套接字,而epoll支持的事件类型更加丰富,包括文件、管道、套接字、定时器等。

总的来说,epoll相对于select和poll来说,在处理大量连接时,性能更加优异。但在连接数较少时,三者的性能差距并不是很明显。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 前端八股面试题pdf是一个常见的前端面试准备资料。它通常包含了一系列前端开发的基础知识、技能及常见问题,用于考察面试者对前端开发的理解和应用能力。 该pdf的内容大致分为以下几个方面:HTML、CSS、JavaScript、框架和工具、网络及性能优化、跨平台兼容性等。 在HTML部分,面试题可能包含HTML基础语法、常用标签以及语义化、表单提交和验证等内容。 在CSS方面,题目可能涵盖盒模型、选择器、伪类、Flexbox、Grid布局等常用技巧和性能优化方法。 在JavaScript部分,题目可能关注变量声明、作用域、闭包、原型链、事件绑定、异步编程等基本概念和实际应用。 在框架和工具方面,题目可能涉及React、Vue等主流前端框架的使用和相关的组件化、虚拟DOM等特性。同时,常见的工具和包管理器如Webpack、Babel等也可能成为考察的内容。 网络及性能优化方面,题目可能探讨HTTP协议、缓存、CDN、异步加载等相关知识。 最后,跨平台兼容性也是一个重要的领域,题目可能包含对不同浏览器、设备或响应式设计的适配和兼容。 解答这些面试题有助于巩固并拓宽前端开发知识,培养解决实际问题的能力。同时,阅读和理解该pdf能够更好地为前端开发工作做好准备,提高面试成功的机会。 ### 回答2: 前端八股面试题PDF是一个非常有用的资源,对于准备前端面试的人来说特别有帮助。这个PDF包含了许多常见的前端面试题目,通常会涵盖HTML、CSS、JavaScript、框架和库、网络和性能优化等方面的知识。 在一个前端面试中,面试官可能会问一些基础的HTML问题,比如语义化标签的作用、HTML5新特性等。对于CSS方面的问题,他们可能会问一些关于盒模型、浮动、定位和响应式设计的题目。至于JavaScript,常见的问题包括原型链、闭包、异步和事件处理等。对于框架和库的问题,可以有关于React、Vue、Angular等的问题。另外,网络和性能优化方面的问题也是很常见的。 回答这些问题时,我们需要结合自己的实际经验和知识进行回答。可以通过提供适当的例子和解释来展示自己对知识的理解和应用能力。此外,还可以结合自己的项目经验和学习成果来回答,展示自己的实际操作能力。 总之,前端八股面试题PDF是一个非常有用的资源,通过仔细准备和回答这些问题,我们可以更好地展示自己的前端技能和知识,提高自己在前端面试中的竞争力。 ### 回答3: 前端八股面试题PDF是一份辅助求职者准备前端开发职位面试的材料。这份PDF通常包含了常见的前端八股面试题目和答案范例。 在前端开发职位面试中,八股文是指一些常见的基础知识问题。这些问题涵盖了HTML、CSS、JavaScript等前端开发的基础内容。通过这些问题,面试官可以了解求职者的基础知识水平,判断其是否具备这个职位的入门能力。 使用前端八股面试题PDF可以帮助求职者系统地复习和准备前端开发面试。通过看题目,思考和回答问题,并参考PDF中给出的答案范例,求职者可以更好地掌握前端开发的基础知识,提高应对面试问题的能力。 当然,单纯依赖八股面试题PDF是远远不够的。求职者还需要通过实际的项目经验和实践来加深理解和运用前端开发的知识。只有在实际中学以致用,并不断提升自己的技术水平,才能在面试中更好地展现自己的能力。 最后,我建议求职者在准备面试时,要综合考虑各方面的知识和技能。八股面试题PDF只是一种辅助工具,真正的关键在于求职者是否理解并能应用所学的知识,以及能否通过实践项目展示自己的实际能力。通过全面的准备和努力,求职者可以更好地面对前端开发职位的面试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值