Skip to content

Latest commit

 

History

History
152 lines (100 loc) · 7.67 KB

OS.md

File metadata and controls

152 lines (100 loc) · 7.67 KB

操作系统面试常见问题

本文档记录了常见的操作系统面试问题,特地记录下来用于临时抱佛脚

死锁

1. 什么是死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

2. 死锁的产生条件

  1. 互斥:一个资源一次只能被一个进程占用;
  2. 请求与保持:一个进程请求资源不被允许时,也不会放弃已占有的资源;
  3. 不可占用:资源不可被抢占;
  4. 循环等待:进程之间形成头尾相连的互相等待情况。

3. 死锁解除的方法

  1. 预防死锁 -- 针对死锁产生的四种条件
    1. 将独享资源变为共享资源
    2. 一次性把所有所需资源分配给某个进程
    3. 资源可抢占
    4. 给资源编号,只能按序取用
  2. 避免死锁 -- 银行家算法

银行家算法:事先计算,如果将资源按一定顺序分配给某个进程后,能够使进程结束,释放资源(不会产生死锁),则分配;否则不分配

  1. 检测死锁
  2. 解除死锁

4. 互斥锁,自旋锁,读写锁,悲观锁,乐观锁 详情参考

  1. 乐观锁 Vs 悲观锁

    1. 乐观锁认为,多个线程共享资源时很少会更改共享资源,所以先分配,工作完成后再看资源是否被更改,如果被更改则放弃此次操作;
    2. 悲观锁认为,线程会更改共享资源,所以每次只能让一个线程占用资源。
  2. 互斥锁 Vs 自旋锁

    1. 互斥锁认为,当A占用资源,B想要访问资源时,加锁失败,此时B会释放CPU,进行 线程的上下文切换 (时间开销大)
    2. 自旋锁认为,当A占用资源,B想要访问资源时,加锁失败,B不会释放CPU,而是进入 忙等待,不用切换上下文
  3. 读写锁:在执行“读”操作时,可以多个线程共享资源;当执行“写”操作时,将只能允许一个线程访问资源


内存管理

1. 堆和栈

  1. 栈是由编译器自动分配和释放,存放函数的参数和局部变量的值,它的访问速度较快。栈上数据的释放是随着出栈自动销毁了。栈的生长方向向下,内存地址由高到低。

  2. 堆是程序运行时显式申请和释放的内存空间,程序结束后由操作系统回收,容易产生内存碎片。堆的空间比较灵活,可以不连续,通常比栈要大。堆的生长方向向上,内存地址由低到高。

2. 块、页、段、段页式内存

  1. 块式存储:将内存分成多个块,每次有数据要调入,直接分给它一整个块,管理简单,但空间利用率极低;
  2. 页式存储:将内存分为多个页,页<块,通过页表查询;
  3. 段式存储:将内存分为多个段,段<<块,虽然更加细粒度,但是一段数据可能要分布在多个段上,非常费尽;
  4. 段页式存储:先将内存分为多个段,再在段的基础上划分多个页。此时每查询一个数据要访问三次内存。

3. 虚拟内存

用于扩充内存的。 它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。


进程 & 线程

1. 进程 Vs 线程

从根本上来说,进程是操作系统分配资源的基本单位,线程是操作系统任务调度的基本单位

  • 进程的切换需要涉及到资源的调动,非常低效,但是转换线程不需要涉及资源调动,效率高;
  • 进程内可以有多个线程,这些线程共享进程的资源;而各个进程间又是相互独立的;
  • 进程崩溃,不会对其他线程有害;线程崩溃,整个进程都要完蛋,所以会影响其他线程;

2. 信号量与PV操作

信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于 进程间同步。为了获得共享资源,进程需要执行下列操作:

(1)创建一个信号量:这要求调用者指定初始值,对于二值信号量来说,它通常是1,也可是0;

(2)等待一个信号量:该操作会测试这个信号量的值,如果小于0,就阻塞。也称为P操作;

(3)挂出一个信号量:该操作将信号量的值加1,也称为V操作。

  • 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。信号量通常为0/1。
  • 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。

3. 进程调度

  1. 非抢占:一个任务在处理时,只有等待其完成,才能进行下一步,用于批处理
  2. 抢占:一个任务在处理时,其他进程可能可以打断其执行
    1. FIFO
    2. 最短作业优先 -- 会造成饥饿(即一个进程可能长时间得不到资源)
    3. 时间片轮转
    4. 优先级 -- 会造成饥饿
    5. 最高响应比 -- 响应比=响应事件/处理时间 (即越快能处理完+等了很久的可以先执行)

4. 用户态和内核态

  • 用户态的程序只能访问用户空间的资源,执行非特权指令,对于特权指令要通过系统调用的方式进行。

用户态就是提供应用程序运行的空间,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用

  • 运行在内核态的进程控制着操作系统内核程序和计算机的硬件资源,可以执行特权指令和非特权指令。

5. 用户态→内核态

  1. 系统调用:本身就是中断,只不过是软中断
  2. 异常
  3. 硬件中断

6. 进程的状态

进程有三种状态:就绪、执行、阻塞

就绪态是“完事具备,只欠CPU”,阻塞态是除了CPU以外还缺其他资源

三态.png

7. 上下文切换

上下文切换就是将当前执行的任务转换到下一个任务的过程。在该过程中,还需要保存上一个任务的状态。

进程的上下文切换会涉及内存资源的调度,而线程的上下文切换不会改变内存资源。

8. 并发 & 并行

并行:多个进程在多个处理器上同时执行,在宏观和微观上都是同时执行的;

并发:一个处理器一次只能处理一个进程,即在微观上,是串行的;但是由于进程切换迅速,在宏观上看,一个处理器同时处理多个进程,即并行的。

9. 进程通信

  1. 管道(Pipe)
    1. 半双工
    2. 缓冲区类似于循环队列,空间有限
    3. 管道是没有ID标识的(针对匿名管道,后面推出有名管道FIFO后解决该问题)
    4. 保存在内存中
  2. 消息队列
    1. 类似于链表构成的队列
    2. 有特定标识符
    3. 保存在内核中
  3. 信号量(semaphore)
    1. PV操作
  4. 共享内存
  5. socket
    1. 可以让不在同一台计算机但通过网络连接计算机上的进程进行通信
    2. 套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
  6. 信号(Signal)
    1. 中断系统就是使用信号机制,由某个进程发出,在到达接收方前阻塞,直到接收方可以接受为止,接收方接受后,保护断点和上下文,进行转换