基础
什么是操作系统
操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机的基石。
操作系统本质上是一个运行在计算机上的软件程序 ,用于管理计算机硬件和软件资源。
从资源管理的角度来看,操作系统有 6 大功能:
- 进程和线程的管理:进程的创建、撤销、阻塞、唤醒,进程间的通信等。
- 存储管理:内存的分配和管理、外存(磁盘等)的分配和管理等。
- 文件管理:文件的读、写、创建及删除等。
- 设备管理:完成设备(输入输出设备和外部存储设备等)的请求或释放,以及设备启动等功能。
- 网络管理:操作系统负责管理计算机网络的使用。网络是计算机系统中连接不同计算机的方式,操作系统需要管理计算机网络的配置、连接、通信和安全等,以提供高效可靠的网络服务。
- 安全管理:用户的身份认证、访问控制、文件加密等,以防止非法用户对系统资源的访问和操作
用户态和内核态的区别
根据进程访问资源的特点,我们可以把进程在系统上的运行分为两个级别:
- 用户态(user mode) : 用户态运行的进程可以直接读取用户程序的数据。处于用户态的 CPU 只能受限的访问内存,并且不允许访问外围设备
- 系统态(kernel mode) : 系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。
具有用户态和内核态主要是为了保证计算机系统的安全性、稳定性和性能
什么是系统调用
系统调用是应用程序与操作系统之间进行交互的一种方式,通过系统调用,应用程序可以访问操作系统底层资源例如文件、设备、网络等。
运行在用户态的程序,调用操作系统提供的系统态级别的功能或资源,需要用到系统调用
系统调用按功能大致可分为如下几类:
- 设备管理。完成设备的请求或释放,以及设备启动等功能。
- 文件管理。完成文件的读、写、创建及删除等功能。
- 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
- 进程通信。完成进程之间的消息传递或信号传递等功能。
- 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
用户态和内核态是如何切换的
用户态切换到内核态的 3 种方式:
- 系统调用(Trap):用户态进程 主动 要求切换到内核态的一种方式,主要是为了使用内核态才能做的事情比如读取磁盘资源。
- 中断(Interrupt):当外围设备完成用户请求的操作后,会向 CPU 发出相应的中断信号,如果先前执行的指令是用户态下的程序,就会由用户态到内核态的切换。比如硬盘读写操作完成
- 异常(Exception):当 CPU 在执行运行在用户态下的程序时,发生了异常,会转到了内核态处理异常,比如缺页异常。
系统调用的过程是什么
- 用户态的程序发起系统调用,因为系统调用中涉及一些特权指令,用户态程序权限不足,因此会中断执行,也就是 Trap(Trap 是一种中断)。
- 发生中断后,当前 CPU 执行的程序会中断,跳转到中断处理程序。内核程序开始执行,也就是开始处理系统调用。
- 内核处理完成后,主动触发 Trap,这样会再次发生中断,切换回用户态工作。
并发与并行的区别
- 并发:指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行。(时间片轮转)
- 并行:指在同一时刻,有多条指令在多个处理器上同时执行。
并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在
最关键点是:是否是 同时 执行。
同步和异步的区别
- 同步 : 发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。
- 异步 :调用在发出之后,不用等待返回结果,该调用直接返回。
阻塞和非阻塞的区别
- 阻塞:是指调用结果返回前,当前线程会被挂起,即阻塞。(sleep)
- 非阻塞:是指即使调用结果没返回,也不会阻塞当前线程。(轮询)
进程和线程
线程、进程、协程是什么
进程:进程是系统进行资源分配的基本单位,进程就是运行起来的可执行程序。
线程:线程是程序执行的最基本的单位,是轻量级的进程,多个线程可以在同一个进程中同时执行,并且共享进程的资源比如内存空间、文件句柄、网络连接等。
协程:是一种特殊类型的子程序或函数,允许在同一个线程中进行多个流程(或称为协作任务)之间的切换和调度,实现高效的非阻塞并发操作。用户自己控制切换的时机,不再需要陷入系统的内核态
进程和线程的区别
- 资源:进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问进程的资源。
- 包含关系:线程是进程划分成的更小的运行单位,一个进程在其执行的过程中可以产生多个线程。
- 独立性:各进程基本上是独立的,而同一进程中的线程极有可能会相互影响。
- 开销:线程执行开销小,但不利于资源的管理和保护;而进程正相反
- 通信:线程间可以通过直接读写同一进程的数据进行通信,但是进程通信需要借助一些复杂的方法。
线程间的同步的方式有哪些
线程同步是两个或多个共享关键资源的线程的并发执行。
- **互斥锁(Mutex)**:只有拥有互斥对象的线程才有访问公共资源的权限。(synchronized、Lock)
- 读写锁(Read-Write Lock):允许多个线程同时读取共享资源,但只有一个线程可以对共享资源进行写操作。
- **信号量(Semaphore)**:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
- 屏障(Barrier):屏障是一种同步原语,用于等待多个线程到达某个点再一起继续执行。(CyclicBarrier)
- 事件(Event) : Wait/Notify:通过通知操作的方式来保持多线程同步
PCB 是什么
PCB(Process Control Block) 即进程控制块,是操作系统中用来管理和跟踪进程的数据结构,操作系统会根据这些信息来管理和调度进程。
PCB 主要包含下面几部分的内容:
- 进程的描述信息,包括进程的名称、标识符等等;
- 进程的调度信息,包括进程阻塞原因、进程状态(就绪、运行、阻塞等)、进程优先级等;
- 进程对资源的需求情况,包括 CPU 时间、内存空间、I/O 设备等等。
- 处理机的状态信息,包括通用寄存器、指令计数器、程序状态字 PSW、用户栈指针
PCB使得多道程序环境下,使得程序可以并发执行
进程切换的流程
- 当前进程的时间片用完或者发生了阻塞等等原因,触发进程切换。
- 操作系统保存当前进程的上下文信息。包括寄存器的值、程序计数器(PC)等。这些信息可以通过保存在进程控制块(PCB)中。
- 根据调度算法,选择一个新的就绪状态(Ready)的进程来执行。
- 加载被选中进程的上下文信息。将PCB中保存的上下文信息恢复到相应的寄存器和PC等。
- 进程切换完成后,操作系统将控制权交给新选中的进程,开始执行它的指令。
进程有哪几种状态
有创建状态、就绪状态、运行状态、阻塞状态、结束状态。
- 其中只有就绪状态和运行状态能互相转化,当进程为就绪态时,等待 CPU 分配时间片,得到时间片后就进入 运行状态
- 运行状态在使用完 CPU 时间片后,又重回就绪态。
- 阻塞状态是进程在运行状态时,需要等待某个资源比如打印机资源,而进入一个挂起的状态,等资源拿到后会回到就绪状态,等待 CPU 时间片。
进程间的通信方式有哪些
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。
无名管道
- 用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。
命名管道
- 与无名管道不同,命名管道可以在无关的进程之间交换数据
- 有名管道严格遵循先进先出FIFO
- 有名管道以磁盘文件的方式存在
消息队列
- 消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符 ID 来标识;
- 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除;
- 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
信号量
- 信号量(semaphore)是一个计数器。通过对信号量进行P操作(申请资源)和V操作(释放资源)来协调资源的访问,避免竞态条件的发生。
- 基于操作系统的 PV 操作,程序对信号量的操作都是原子操作
- 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数;
共享内存
- 多个进程可以访问同一块物理内存区域,通过读写这块共享内存来实现数据的共享。这种方式高效快速,但需要进行进程间同步和互斥操作,以防止数据竞争。
套接字(Sockets)
- 主要用于在客户端和服务器之间通过网络进行通信。可以在不同主机上的进程之间进行通信
RPC
- 远程过程调用(RPC,Remote Procedure Call):RPC允许一个进程调用另一个进程中的过程或函数,并获取返回值。
进程的调度算法有哪些
先到先服务调度算法(FCFS,First Come, First Served)
**短作业优先的调度算法(SJF,Shortest Job First)
时间片轮转调度算法(RR,Round-Robin) : 每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
多级反馈队列调度算法(MFQ,Multi-level Feedback Queue):
多级:表示有多个队列,每个队列优先级从高到低,同时优先级越高时间片越短。
反馈:表示如果有新的进程加入优先级高的队列时,立即停止当前正在运行的进程,转而去运行优先级高的队列
进程在不同优先级的队列间迁移,首先调度优先级高的队列中的进程,只有优先级高的队列为空时才去调度优先级低的队列中的进程;对于同一个队列中的进程,按照时间片轮转的方式进行调度,如果一定时间片后依然未能完成,则进入优先级低的队列等待。
优先级调度算法(Priority):为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。
守护进程、僵尸进程和孤儿进程是什么
守护进程
指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,周期性地执行某种任务。Linux的大多数服务器就是用守护进程的方式实现的,如web服务器进程http等
孤儿进程
一个父进程退出,而它的子进程还在运行,这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
僵尸进程
如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸进程
设置僵尸进程的目的是维护子进程的信息,当终止子进程的父进程调用wait或waitpid时就可以得到这些信息
死锁
什么是死锁
多个进程/线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于进程/线程被无限期地阻塞,因此程序不可能正常终止。
死锁的四个必要条件
- 互斥:资源必须处于非共享模式,即一次只有一个进程可以使用。
- 请求和保持:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
- 不可剥夺:资源不可剥夺。只能在持有资源的进程完成任务后,该资源才会被释放。
- 循环等待:有一组等待进程
{P0, P1,..., Pn},P0等待的资源被P1占有,P1等待的资源被P2占有,……,Pn-1等待的资源被Pn占有,Pn等待的资源被P0占有。
解决死锁的方法有哪些
预防:采用某种策略,限制并发进程对资源的请求,从而使得死锁的必要条件在系统执行的任何时间上都不满足。
- 破坏互斥条件:一次性分配所有资源
- 破坏请保持条件:只要有一个资源得不到分配,也不给这个进程分配其他的资源:
- 破坏不可剥夺条件:当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源;
- 破坏循环等待条件:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反。
避免:允许系统中同时存在四个必要条件 ,只要掌握并发进程中与每个进程有关的资源动态申请情况,根据资源的使用情况提前做出预测 ,仍然可以避免死锁
银行家算法:当一个进程申请使用资源的时候,通过 试探 分配给该进程资源,然后通过 安全性算法 判断分配后系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待,若能够进入到安全的状态,则就 真的分配资源给该进程。
检测:系统 定时地运行一个 “死锁检测” 的程序,判断系统内是否出现死锁,如果检测到系统发生了死锁,再采取措施去解除它。
进程-资源分配图:描述进程和资源申请及分配关系的一种有向图,可用于检测系统是否处于死锁状态。
解除:与检测相配套的一种措施,用于将进程从死锁状态下解脱出来。
- 资源剥夺:挂起某些死锁进程,并抢占它的资源
- 撤销进程:强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源
- 进程回退:让一个或多个进程回退到足以避免死锁的地步。
内存管理
内存管理是干什么的
- 内存的分配与回收:对进程所需的内存进行分配和释放
- 地址转换:将程序中的虚拟地址转换成内存中的物理地址。
- 内存扩充:当系统没有足够的内存时,利用虚拟内存技术或自动覆盖技术,从逻辑上扩充内存。
- 内存映射:将一个文件直接映射到进程的进程空间中,这样可以通过内存指针用读写内存的办法直接存取文件内容,速度更快。
- 内存安全:保证进程之间使用内存互不干扰,避免一些恶意程序通过修改内存来破坏系统的安全性。
什么是内存碎片
- 内部内存碎片:已经分配给进程使用但未被使用的内存。
- 外部内存碎片:并未分配给进程但又太小导致无法使用的内存。这些内存碎片不能满足任意进程所需要的内存分配请求
什么是虚拟地址(逻辑地址)和物理地址
物理地址:它是地址转换的最终地址,进程在运行时执行指令和访问数据最后都要通过物理地址从主存中存取,是内存单元真正的地址。
逻辑地址:是指计算机用户看到的地址。编程时的指针值,数组在逻辑地址上是连续的,在物理地址上并不连续,操作系统通过地址映射,将逻辑地址映射成连续的。(CPU 芯片中的一个重要组件 MMU,地址转换)
MMU 将虚拟地址翻译为物理地址的主要机制有两种: 分段机制 和 分页机制 。
常见的内存管理方式有哪些
- 连续内存管理:为一个程序分配一个连续的内存空间,内存利用率一般不高。
- 非连续内存管理:允许一个程序使用的内存分布在不相邻的内存中,相对更加灵活一些。
连续内存管理
块式管理:块式管理会将内存分为几个固定大小的块,每个块中只包含一个进程。
伙伴系统算法:将内存按 2 的幂次划分(每一块内存大小都是 2 的幂次比如 2^6=64 KB),并将相邻的内存块组合成一对伙伴(必须是相邻的才是伙伴)。
当进行内存分配时,伙伴系统会尝试找到大小最合适的内存块。如果找到的内存块过大,就将其一分为二,分成两个大小相等的伙伴块。如果还是大的话,就继续切分,直到到达合适的大小为止。
非连续内存管理
- 段式管理:以段(—段连续的物理内存)的形式管理/分配物理内存。应用程序的虚拟地址空间被分为大小不等的段,段是有实际意义的,每个段定义了一组逻辑信息
- 页式管理:把物理内存分为连续等长的物理页,应用程序的虚拟地址空间划也被分为连续等长的虚拟页
- 段页式管理机制:结合了段式管理和页式管理的一种内存管理机制,把物理内存先分成若干段,每个段又继续分成若干大小相等的页。
介绍一下分页机制
分页机制 把主存(物理内存)分为连续等长的物理页(一般是4或8字节),应用程序的虚拟地址空间划也被分为连续等长的虚拟页。现代操作系统广泛采用分页机制。
在分页机制下,应用程序虚拟地址空间中的任意虚拟页可以被映射到物理内存中的任意物理页上,因此可以实现物理内存资源的离散分配。
分页机制按照固定页大小分配物理内存,使得物理内存资源易于管理,可有效避免分段机制中外部内存碎片的问题。
页表有什么用?地址翻译过程是怎样的?
分页管理通过 页表(Page Table) 映射虚拟地址和物理地址。
分页机制下的虚拟地址由两部分组成:
- 页号:通过虚拟页号可以从页表中取出对应的物理页号;
- 页内偏移量:物理页起始地址+页内偏移量=物理内存地址。
页表中还存有诸如访问标志(标识该页面有没有被访问过)、脏数据标识位等信息。
具体的地址翻译过程:
- MMU 首先解析得到虚拟地址中的虚拟页号;
- 通过虚拟页号去该应用程序的页表中取出对应的物理页号(找到对应的页表项);
- 用该物理页号对应的物理页起始地址(物理地址)加上虚拟地址中的页内偏移量得到最终的物理地址。
多级页表是什么,作用是什么
多级页表就是,存放下一个页表地址的页表
目的是避免把全部页表一直放在内存中占用过多空间。
多级页表属于时间换空间的典型场景。利用增加页表查询的次数减少页表占用的空间。
快表是什么,使用快表之后的地址转换流程
为了提高虚拟地址到物理地址的转换速度,操作系统在 页表方案 基础之上引入了 快表(TLB) 来加速虚拟地址到物理地址的转换。可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分。作为页表的 Cache,它的作用与页表相似,但是提高了访问速率。
由于采用页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。
使用快表之后的地址转换流程是这样的:
- 根据虚拟地址中的页号查快表;
- 如果该页在快表中,直接从快表中读取相应的物理地址;
- 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;
- 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。
分页与分段的区别是什么
- 段是信息的逻辑单位,是为了满足程序对内存空间的逻辑需求而设计的,通常根据程序中数据和代码的逻辑结构来划分。页是信息的物理单位,是为了管理内存的方便而划分的
- 段的大小不固定,有它所完成的功能决定;页大大小固定,由系统决定;
- 段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制。
- 页有内部碎片,无外部碎片;段有外部碎片,无内部碎片
虚拟内存
虚拟内存是什么
虚拟内存(Virtual Memory) :本质上来说它只是逻辑存在的,是一个假想出来的内存空间,主要作用是作为进程访问主存(物理内存)的桥梁并简化内存管理。
通过 虚拟内存 可以让程序拥有超过系统物理内存大小的可用内存空间。虚拟内存为每个进程提供了一个私有的地址空间,每个进程拥有一片连续完整的内存空间
虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,并且 把内存扩展到硬盘空间。
虚拟内存的作用是什么
- 隔离进程:物理内存通过虚拟地址空间访问,虚拟地址空间与进程一一对应。进程之间彼此隔离,一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。
- 提高内存使用安全性:控制进程对物理内存的访问,隔离不同进程的访问权限,提高系统的安全性。
- 提升物理内存利用率:有了虚拟地址空间后,操作系统只需要将进程当前正在使用的部分数据或指令加载入物理内存。
- 提供更大的可使用内存空间:可以让程序拥有超过系统物理内存大小的可用内存空间。当物理内存不够用时,可以利用磁盘充当物理内存。
- 简化内存管理:进程都有一个一致且私有的虚拟地址空间,程序员不用和真正的物理内存打交道,而是借助虚拟地址空间访问物理内存,从而简化了内存管理。
虚拟内存的技术实现方式
虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。
- 请求分页存储管理 :建立在分页管理之上,在作业开始运行之前,仅装入当前要执行的部分段即可运行。发现要访问的页面不在内存,缺页中断,调入内存
- 请求分段存储管理 :建立在分段存储管理之上,如同请求分页储存管理方式一样。
- 请求段页式存储管理
请求分页与分页存储管理有何不同
请求分页存储管理建立在分页管理之上。
他们的根本区别是:是否将程序所需的全部地址空间都装入主存
页面置换算法有哪些
地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断 。
缺页中断 就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问。 在这个时候,被内存映射的文件实际上成了一个分页交换文件。
- OPT(最佳页面置换算法) :选未来最远将使用的页淘汰,是一种最优的方案
- FIFO(先进先出页面置换算法) : 淘汰最先进入内存的页面
- LRU(最近最久未使用页面置换算法) :选择最近最久未使用的页面予以淘汰
- LFU (最少使用页面置换算法) : 选择在之前使用最少的页面作为淘汰页。
文件系统
文件系统主要做了什么
- 存储管理:将文件数据存储到物理存储介质中,并且管理空间分配。
- 文件管理:文件的创建、删除、移动、重命名、压缩、加密、共享等等。
- 目录管理:目录的创建、删除、移动、重命名等等。
- 文件访问控制:管理不同用户或进程对文件的访问权限,保证文件的安全性和保密性。
常见的磁盘调度算法有哪些
- 先来先服务算法(FCFS):按照请求到达磁盘调度器的顺序进行处理,先到达的请求的先被服务。
- 最短寻道时间优先算法(SSTF):优先选择距离当前磁头位置最近的请求进行服务。
- 扫描算法(SCAN):也被称为电梯(Elevator)算法。磁头沿着一个方向扫描磁盘,如果经过的磁道有请求就处理,直到到达磁盘的边界,然后改变移动方向,依此往复。
- 循环扫描算法(C-SCAN):SCAN 算法的变体,只在磁盘的一侧进行扫描,并且只按照一个方向扫描,直到到达磁盘边界,然后回到磁盘起点,重新开始循环。
Linux 常用命令有哪些
目录/文件:
cd usr:切换到该目录下 usr 目录ls:显示目录中的文件和子目录的列表mkdir [选项] 目录名:创建新目录(增)。pwd:显示当前工作目录的路径。rmdir [选项] 目录名:删除空目录(删)rm [选项] 文件或目录名:删除文件/目录(删)。cp [选项] 源文件/目录 目标文件/目录:复制文件或目录(移)。mv [选项] 源文件/目录 目标文件/目录:移动文件或目录(移),也可以用于重命名文件或目录。touch [选项] 文件名..:创建新文件或更新已存在文件(增)cat 文件名:文件的查看(查) 。vim 文件名:修改文件的内容(改)。tar -zcvf 打包压缩后的文件名 要打包压缩的文件:打包并压缩文件- z:调用 gzip 压缩命令进行压缩
- c:打包文件
- v:显示运行过程
- f:指定文件名
tar [-xvf] 压缩文件:解压文件-
x:解压
-
网络:
ping [选项] 目标主机:测试与目标主机的网络连接。ifconfig或ip:用于查看系统的网络接口信息,包括网络接口的 IP 地址、MAC 地址、状态等。
进程::
ps:用于显示当前运行的进程状态。ps aux:显示所有用户的所有进程。ps -p <PID>:显示与指定PID相关的进程信息,包括进程的状态、CPU占用、内存占用、启动时间等。
top:动态实时显示进程的系统资源占用情况和进程信息。(CPU、内存、进程)htop:类似于top命令,但提供了更加交互式和直观的界面,支持鼠标操作。kill:向进程发送信号,通常用于终止或操作进程。常用选项有:kill <PID>:终止指定进程ID的进程。kill - 9 <PID>:强行终止killall <进程名>:终止指定名称的所有进程。
pgrep:根据进程名或其它条件来查找进程的PID。netstat -tuln | grep <端口号>:列出正在监听的端口,并通过grep过滤出包含指定端口号的行。-t选项表示TCP协议,-u选项表示UDP协议,-l选项表示仅显示监听状态的端口,-n选项表示以数字形式显示端口号。