操作系统面试总结
操作系统
1. 概念
1.1 计算机系统的层次结构
1.2 什么是操作系统
实现用户与底层的交互,本质上是运行在计算机中的软件,向上管理应用软件,向下管理计算机硬件资源
管理:
- CPU 管理:调度CPU,给时间片的处理机制
- 内存管理:将程序载入内存
- 文件管理:各种文件夹
- 设备管理:声卡、显卡、网卡、摄像头等
1.3 什么叫系统调用
为的是将数据进行隔离,不然内部完全乱套!
用户态:直接读取用户程序的数据
内核态:几乎可以访问计算机的任何资源,不受限制。
系统调用:在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。
1.4 局部性原理
1.5 同步和互斥
互斥:是指在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。一个公共资源同一时刻只能被一个进程或线程使用,多个进程或线程不能同时使用公共资源。
同步:是指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。两个或两个以上的进程或线程在运行过程中协同步调,按预定的先后次序运行。比如 A 任务的运行依赖于 B 任务产生的数据。
1.6 并发、并行、同步、异步
同步:必须一件一件事做,等前一件做完了才能做下一件事。
异步:异步是在等待某个资源的时候继续做自己的事
比如:
同步是指:当程序1调用程序2时,程序1停下不动,直到程序2完成回到程序1来,程序1才继续执行下去。
异步是指:当程序1调用程序2时,程序1径自继续自己的下一个动作,不受程序2的的影响。
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
并发:时分复用,宏观上多任务同时执行,但是实际在微观上是时分复用
并行:真的同时在执行多个任务(多核cpu并行)
1.7 中断
2. 进程和线程
2.1 区别
1. 进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
2. 线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的 实时性,实现进程内部的并发;
3. 一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程而存在;
4. 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈。
2.2 进程的状态
进程状态的改变信息由程序控制块PCB保存
2.3 进程的通信方式
进程是分配系统资源的单位,因此各进程拥有的内存地址空间相互独立,为了保证安全,一个进程不能直接访问另一个进程的地址空间。但是进程之间的信息交换又是必须实现的。为了保证进程间的安全通信,操作系统提供了一些方法
包括:
内存类:共享内存、匿名管道、有名管道
消息类型:信号(Linux)、信号量(进程同步)、消息队列、套接字(网络通信)
① 管道通信:管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据,管道一端的进程顺序的将数据写入缓冲区,另一端的进程则顺序的读出数据。
② 有名管道:名字存在于文件系统中,内容存放在内存中。只要可以访问该路径,就能够彼此通过有名管道相互通信。
③ 信号(Signal)
Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
④ 消息队列
⑤ 共享内存
内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率。
⑥ 信号量
信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。
⑦ 套接字
支持TCP/IP的网络通信的基本操作单元,参考计算机网络
2.4 线程同步的方式
互斥量 Synchronized/Lock:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问
信号量 Semphare:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
事件(信号),Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作
2.5 进程调度算法
3. 内存管理:核心是内存分配
一切需要CPU处理的数据和程序,都需要载入到内存中供CPU读取,所以内存管理负责对对内存的分配和回收。
内存使用:将程序放到内存中,PC指向开始地址。
程序:可以根据不同的功能进行分段,这是符合人类习惯的
逻辑地址:是人为编程中设定的地址,而实际的地址由操作系统分配,实际物理地址 = 基址+ 偏移量
3.1 内存分段管理
将内存进行可变分区,按需分配内存,专门维护一个空闲分区表,已分配分区表。但是分区会产生很多内存碎片,这些碎片没有办法利用,如果实在要用就需要进行内存紧缩,也就是全部重新移动内存中的数据,在内存紧缩的过程中CPU无法被上层使用,所以分段导致效率很低。所以这种分区的内存管理方式不可行。
3.2 内存分页管理
将面包切成一片一片,就不会有面包屑,顶多有些人拿了一片也吃不完,内存浪费的也少。
操作系统不再按段,而是按页分配给段。此时需要维护一个页表,里面存放了页码和对应的逻辑地址。指向时重定向实现逻辑地址与物理地址的转换。
虽然页面越小,内存利用率就越高,但是相应的页表就会非常大。内存要开辟出一块很大的空间存放页表,造成浪费
实际上大部分的逻辑地址是用不上的。参考书籍目录的方式,提出多级页表的方式
多级页表 = 页目录表 + 页表(节),多级页表增加了访问内存的次数,也就是一种用时间换空间的策略。
为了进一步优化多级页表多次访问内存的时间消耗问题,于是提出了快表的概念(快速寄存器),类似于内存里面的高速缓冲寄存器。里面存着了最近使用的页表。可以减少查询的次数。用到的策略是计算机的局部性原理。
1.根据虚拟地址中的页号查快表
2.如果该页在快表中,直接从快表中读取相应的物理地址
3.如果该页不在快表中,就访向内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中
4.当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汯掉快表中的一个页
但实际上分页管理对代码的分段不太友好。程序员希望用段,物理内存希望用页,所以为了集百家之长,又提出了段页式内存管理机制
3.3 段页式内存管理
通过虚拟内存将段表和页表联系起来。
代码段过来了,在虚拟内存上分配一段连续的内存区域给代码段——分段式内存
再将虚拟内存用到的段,映射到实际的分页中,这部分是对用户透明的——分页式内存
3.4 虚拟内存:仓库+店面的模式
3.4.1 换入换出实现大内存
基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的。在程序执行过程中,当所访的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器一一虚拟内存。
3.4.2 页面置换算法
地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断。
4. reference:
感谢以下参考的资料:
进程间通信IPC (InterProcess Communication)
JavaGuide
B站 哈工大操作系统
B站王道考研