前端面试题之最全的操作系统面试题!!

PS:在秋招面试的时候,一般到二面的时候都会问一些计算机的基础知识了,不可避免的就是操作系统啦~这里总结常问到的操作系统面试题,有空一定要一整块来钻研呀!

目录

1、进程和线程的区别?

2、协程与线程的区别?

3、并发和并行有什么区别?

4、进程与线程的切换流程?

5.Linux查看进程状态、cpu状态、占用端口的进程号的命令?

6、进程间通信方式有哪些?

7、进程间同步的方式有哪些?

8、线程同步的方式有哪些?

9、 线程的分类?

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

11、为什么进程上下文切换比线程上下文切换代价高?

12、进程调度

13、为什么要使用多线程呢?

14、进程有哪些状态?

1.什么是Swap?

2.什么是上下文切换?

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

4.内部碎片与外部碎片

5.同步和互斥的区别

6.CPU缓存?

7.什么是操作系统OS?

8.什么是系统调用?*

9.常见的几种内存管理机制?*

10.简单描述快表和多级页表?

11.CPU 寻址了解吗?

12.为什么要有虚拟(逻辑)地址空间呢?

13.局部性原理?

14、为什么虚拟地址空间切换会比较耗时?

15、什么是缓冲区溢出?有什么危害?

16、什么是虚拟内存?

17、虚拟内存的实现方式有哪些?

1、什么是分页?

2、什么是分段?

3、 分页和分段有什区别?

4、 什么是交换空间?

5、页面替换算法有哪些?

6、 讲一讲IO多路复用?

7、 硬链接和软链接有什么区别?

8、 中断的处理过程?

9、中断和轮询有什么区别?

10.什么是用户态和内核态?

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

12.Unix 常见的IO模型:

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

14、死锁


1、进程和线程的区别?

调度:进程是资源管理的基本单位,线程是程序执行的基本单位。 切换:线程上下文切换比进程上下文切换要快得多。 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但是可以访问隶属于进程的资源。 系统开销:创建或撤销进程时,系统都要为之分配或回收系统资源,如内存空间,I/O设备等,OS所付出的开销显著大于在创建或撤销线程时的开销,进程切换的开销也远大于线程切换的开销。

2、协程与线程的区别?

线程和进程都是同步机制,而协程是异步机制。 线程是抢占式,而协程是非抢占式的。需要用户释放使用权切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。 协程能保留上一次调用时的状态。

3、并发和并行有什么区别?

并发就是在一段时间内,多个任务都会被处理;但在某一时刻,只有一个任务在执行。单核处理器可以做到并发。比如有两个进程A和B,A运行一个时间片之后,切换到B,B运行一个时间片之后又切换到A。因为切换速度足够快,所以宏观上表现为在一段时间内能同时运行多个程序。 并行就是在同一时刻,有多个任务在执行。这个需要多核处理器才能完成,在微观上就能同时执行多条指令,不同的程序被放到不同的处理器上运行,这个是物理上的多个进程同时进行。

4、进程与线程的切换流程?

进程切换分两步:

1、切换页表以使用新的地址空间,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。

2、切换内核栈和硬件上下文。

对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2步是进程和线程切换都要做的。 因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。

5.Linux查看进程状态、cpu状态、占用端口的进程号的命令?

查看进程状态ps -ef。

查看cpu状态 top。 Cpu(s): 0.1%us 用户空间占用CPU百分比 0.0%sy 内核空间占用CPU百分比 0.0%ni 用户进程空间内改变过优先级的进程占用CPU百分比 99.9%id 空闲CPU百分比

查看占用端口的进程号netstat -an|grep or lsof -i: 80。 查看内存:free -m

VIRT:virtual memory usage 虚拟内存 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等 2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量

RES:resident memory usage 常驻内存 1、进程当前使用的内存大小,但不包括swap out 2、包含其他进程的共享 3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反 4、关于库占用内存的情况,它只统计加载的库文件所占内存大小

SHR:shared memory 共享内存 1、除了自身进程的共享内存,也包括其他进程的共享内存 2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小 3、计算某个进程所占的物理内存大小公式:RES – SHR 4、swap out后,它将会降下来

DATA 1、数据占用的内存。如果top没有显示,按f键可以显示出来。 2、真正的该程序要求的数据空间,是真正在运行中要使用的。

6、进程间通信方式有哪些?

管道:管道这种通讯方式有两种限制,一是半双工的通信,数据只能单向流动,二是只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 管道可以分为两类:匿名管道和命名管道。匿名管道是单向的,只能在有亲缘关系的进程间通信;命名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。 信号 : 信号是一种比较复杂的通信方式,信号可以在任何时候发给某一进程,而无需知道该进程的状态。 Linux系统中常用信号:

(1)SIGHUP:用户从终端注销,所有已启动进程都将收到该进程。系统缺省状态下对该信号的处理是终止进程。 (2)SIGINT:程序终止信号。程序运行过程中,按Ctrl+C键将产生该信号。 (3)SIGQUIT:程序退出信号。程序运行过程中,按Ctrl+\键将产生该信号。 (4)SIGBUS和SIGSEGV:进程访问非法地址。 (5)SIGFPE:运算中出现致命错误,如除零操作、数据溢出等。 (6)SIGKILL:用户终止进程执行信号。shell下执行kill -9发送该信号。 (7)SIGTERM:结束进程信号。shell下执行kill 进程pid发送该信号。 (8)SIGALRM:定时器信号。 (9)SIGCLD:子进程退出信号。如果其父进程没有忽略该信号也没有处理该信号,则子进程退出后将形成僵尸进程。 信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

消息队列:消息队列是消息的链接表,包括Posix消息队列和System V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

共享内存:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

Socket:与其他通信机制不同的是,它可用于不同机器间的进程通信。

优缺点:

管道:速度慢,容量有限;

Socket:任何进程间都能通讯,但速度慢;

消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题;

信号量:不能传递复杂消息,只能用来同步;

共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存。

7、进程间同步的方式有哪些?

1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

优点:保证在某一时刻只有一个线程能访问数据的简便办法。 缺点:虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。

2、互斥量:为协调共同对一个共享资源的单独访问而设计的。互斥量跟临界区很相似,比临界区复杂,互斥对象只有一个,只有拥有互斥对象的线程才具有访问资源的权限。

优点:使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。 缺点:

互斥量是可以命名的,也就是说它可以跨越进程使用,所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。

通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号量对象可以说是一种资源计数器。

3、信号量:为控制一个具有有限数量用户资源而设计。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。互斥量是信号量的一种特殊情况,当信号量的最大资源数=1就是互斥量了。

优点:适用于对Socket(套接字)程序中线程的同步。 缺点:

信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点;

信号量机制功能强大,但使用时对信号量的操作分散, 而且难以控制,读写和维护都很困难,加重了程序员的编码负担;

核心操作P-V分散在各用户程序的代码中,不易控制和管理,一旦错误,后果严重,且不易发现和纠正。

4、事件: 用来通知线程有一些事件已发生,从而启动后继任务的开始。

8、线程同步的方式有哪些?

1、临界区:当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止,以此达到用原子方式操 作共享资源的目的。

2、事件:事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。

3、互斥量:互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用,但是更节省资源,更有效率。

4、信号量:当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。

区别:

互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说互斥量可以跨越进程使用,但创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量 。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。

互斥量,信号量,事件都可以被跨越进程使用来进行同步数据操作。

9、 线程的分类?

从线程的运行空间来说,分为用户级线程(user-level thread, ULT)和内核级线程(kernel-level, KLT) 内核级线程:这类线程依赖于内核,又称为内核支持的线程或轻量级进程。无论是在用户程序中的线程还是系统进程中的线程,它们的创建、撤销和切换都由内核实现。比如英特尔i5-8250U是4核8线程,这里的线程就是内核级线程 用户级线程:它仅存在于用户级中,这种线程是不依赖于操作系统核心的。应用进程利用线程库来完成其创建和管理,速度比较快,操作系统内核无法感知用户级线程的存在。

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

每个进程中访问临界资源的那段程序称为临界区,一次仅允许一个进程使用的资源称为临界资源。

解决冲突的办法:

如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入,如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待; 进入临界区的进程要在有限时间内退出。 如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

11、为什么进程上下文切换比线程上下文切换代价高?

进程切换分两步:

1.切换页目录以使用新的地址空间。(每一个进程拥有自己独立的内存空间,而线程共享进程的内存空间。)

每个进程有自己的页目录和页表,所以每个进程的地址空间映射的物理内存是不一样的。 2.切换内核栈和硬件上下文

内核在创建进程的时候,会为进程创建相应的堆栈。每一个进程都有两个栈,一个用户栈,存在于用户空间;一个内核栈,存在于内核空间。当进程在用户空间运行时,CPU堆栈指针寄存器里面的内容都是用户栈地址,使用用户栈;当进程在内核空间时,CPU堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。 当进程因为中断或者系统调用陷入到内核态时,进程所使用的堆栈也要从用户栈转到内核栈。进程陷入到内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态之后时,在内核态之后的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。 尽管每个进程可以拥有属于自己的地址空间,但是所有进程必须共享CPU寄存器,因此,在恢复一个进程的执行前,内核必须确保每个寄存器装入了挂起进程时的值。 进程恢复执行前必须装入寄存器的那一组数据成为硬件上下文。 对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。

备注:

进程切换与线程切换的最主要区别:进程切换涉及到虚拟地址空间的切换而线程切换则不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用TLB(Translation Lookaside Buffer)来缓存页地址,用来加速页表查找。当进程切换后页表也要进行切换,页表切换后TLB就失效了,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。 通过页表理解进程切换和线程切换开销上的区别 ——

12、进程调度

先来先服务:非抢占式的调度算法,按照请求的顺序进行调度。有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。另外,对I/O密集型进程也不利,因为这种进程每次进行I/O操作之后又得重新排队。

短作业优先:非抢占式的调度算法,按估计运行时间最短的顺序进行调度。长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。

最短剩余时间优先:最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。

时间片轮转:将所有就绪进程按 FCFS 的原则排成一个队列,每次调度时,把 CPU 时间分配给队首进程,该进程可以执行一个时间片。当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送往就绪队列的末尾,同时继续把 CPU 时间分配给队首的进程。

时间片轮转算法的效率和时间片的大小有很大关系:因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。 而如果时间片过长,那么实时性就不能得到保证。

优先级调度:为每个进程分配一个优先级,按优先级进行调度。为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级。

多级反馈队列 在多级队列的基础上,任务可以在队列之间移动,更细致的区分任务。 可以根据“享用”CPU时间多少来移动队列,阻止“饥饿”。 最通用的调度算法,多数OS都使用该方法或其变形,如UNIX、Windows等。

13、为什么要使用多线程呢?

避免阻塞(异步调用) 线程在运行之中,比如遇到磁盘IO、RPC等这些比CPU处理慢得多的操作,就需要阻塞、自旋,这一段时间可以用来运行其它线程的任务,提高效率。 多核处理器 现在的处理器几乎都是多核的,一个单线程程序在运行时只能使用一个处理器核心。

14、进程有哪些状态?

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

运行状态就是进程正在CPU上运行。在单处理机环境下,每一时刻最多只有一个进程处于运行状态。 就绪状态就是说进程已处于准备运行的状态,即进程获得了除CPU之外的一切所需资源,一旦得到CPU即可运行。 阻塞状态就是进程正在等待某一事件而暂停运行,比如等待某资源为可用或等待I/O完成。即使CPU空闲,该进程也不能运行。 运行态→阻塞态:往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的。 阻塞态→就绪态:则是等待的条件已满足,只需分配到处理器后就能运行。 运行态→就绪态:不是由于自身原因,而是由外界原因使运行状态的进程让出处理器,这时候就变成就绪态。例如时间片用完,或有更高优先级的进程来抢占处理器等。 就绪态→运行态:系统按某种策略选中就绪队列中的一个进程占用处理器,此时就变成了运行态。

1.什么是Swap?

从功能上讲,交换分区主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够用而导致oom或者更致命的情况出现。swap空间是磁盘上的一块区域,可以是一个分区,也可以是一个文件,或者是他们的组合。

在Linux上可以使用swapon -s命令查看当前系统上正在使用的交换空间有哪些。

2.什么是上下文切换?

对于单核单线程CPU而言,在某一时刻只能执行一条CPU指令。

上下文切换(Context Switch)是一种将CPU资源从一个线程分配给另一个线程的机制。从用户角度看,计算机能够并行运行多个线程,这恰恰是操作系统通过快速上下文切换造成的结果。在切换的过程中,操作系统需要先存储当前进程的状态(包括内存空间的指针,当前执行完的指令等等),再读入下一个进程的状态,然后执行此进程。

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

物理地址就是内存中真正的地址,它就相当于是你家的门牌号,你家就肯定有这个门牌号,具有唯一性。不管哪种地址,最终都会映射为物理地址。

在实模式下,段基址 + 段内偏移经过地址加法器的处理,经过地址总线传输,最终也会转换为物理地址。

但是在保护模式下,段基址 + 段内偏移被称为线性地址,不过此时的段基址不能称为真正的地址,而是会被称作为一个选择子的东西,选择子就是个索引,相当于数组的下标,通过这个索引能够在 GDT 中找到相应的段描述符,段描述符记录了段的起始、段的大小等信息,这样便得到了基地址。如果此时没有开启内存分页功能,那么这个线性地址可以直接当做物理地址来使用,直接访问内存。如果开启了分页功能,那么这个线性地址又多了一个名字,这个名字就是虚拟地址。

不论在实模式还是保护模式下,段内偏移地址都叫做有效地址。有效抵制也是逻辑地址。

线性地址可以看作是虚拟地址,虚拟地址不是真正的物理地址,但是虚拟地址会最终被映射为物理地址。下面是虚拟地址 -> 物理地址的映射。

4.内部碎片与外部碎片

在内存管理中,内部碎片是已经被分配出去的的内存空间大于请求所需的内存空间。

外部碎片是指还没有分配出去,但是由于大小太小而无法分配给申请空间的新进程的内存空间空闲块。

页式虚拟存储系统存在内部碎片;段式虚拟存储系统,存在外部碎片

为了有效的利用内存,使内存产生更少的碎片,要对内存分页,内存以页为单位来使用,最后一页往往装不满,于是形成了内部碎片。

为了共享要分段,在段的换入换出时形成外部碎片,比如5K的段换出后,有一个4k的段进来放到原来5k的地方,于是形成1k的外部碎片。

5.同步和互斥的区别

同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

6.CPU缓存?

What: CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。 Why: 缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾。当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。 How: 命中: 缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。 分级: 按照数据读取顺序和与CPU结合的紧密程度,CPU缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。

7.什么是操作系统OS?

操作系统本质上是在硬件上运行的软件系统,用于管理计算机硬件与软件资源的程序。 它可以的简单的分为两个部分,外壳和内核。外壳负责与用户进行交互,内核负责与硬件进行交互。

8.什么是系统调用?*

我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能咋办呢?那就需要系统调用了!

也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。

这些系统调用按功能大致可分为如下几类:

设备管理。完成设备的请求或释放,以及设备启动等功能。 文件管理。完成文件的读、写、创建及删除等功能。 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。 进程通信。完成进程之间的消息传递或信号传递等功能。 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。

9.常见的几种内存管理机制?*

简单分为连续分配管理方式和非连续分配管理方式这两种。连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如 块式管理 。同样地,非连续分配管理方式允许一个程序使用的内存分布在离散或者说不相邻的内存中,常见的如页式管理 和 段式管理。

块式管理 : 远古时代的计算机操系统的内存管理方式。将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片。 页式管理 :把主存分为大小相等且固定的一页一页的形式,页较小,相对相比于块式管理的划分力度更大,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址。 段式管理 : 页式管理虽然提高了内存利用率,但是页式管理其中的页实际并无任何实际意义。 段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多 。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。 段页式管理:段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。 分页机制和分段机制的共同点和区别? 共同点 : 分页机制和分段机制都是为了提高内存利用率,较少内存碎片。 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的。 区别 : 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序。 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需要。

10.简单描述快表和多级页表?

在分页内存管理中,很重要的两点是:

虚拟地址(逻辑地址)到物理地址的转换要快。 解决虚拟地址空间大,页表也会很大的问题。 为了提高内存的空间性能,提出了多级页表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。

快表(TLB): 也叫旁路转换缓冲或者页表缓冲,可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的 Cache,它的作用与页表相似。如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。

多级页表: 引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。给进程分配的内存空间很大的话,对应页表也很大。于是就要建立多级页表,把高层页表(相对级别比较高的)放在内存,靠这个高层页表找底层页表,再在底层页表里找到对应的实页号。部分底层页表在内存,另外的一些就被塞在磁盘,被高层页表点名之后,才调入内存。

11.CPU 寻址了解吗?

CPU 需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件。

CPU要寻址的时候,就会将虚拟地址告知给MMU,然后MMU在快表TLB中查询真实的物理地址,如果没有命中,还要去到磁盘中寻找,如下图所示:

12.为什么要有虚拟(逻辑)地址空间呢?

避免多个程序之间的物理地址冲突:主要是因为,如果程序直接写入物理地址的话,就需要使用得到该物理地址,而如果该物理地址已经被占用了,就会发生冲突。所以使用虚拟地址映射到物理地址,可以避免物理地址的冲突。 屏蔽底层内存访问:用户程序可以访问任意内存,寻址内存的每个字节,这样就很容易(有意或者无意)破坏操作系统,造成操作系统崩溃。 程序可以使用一系列相邻的虚拟地址来访问内存中不相邻的物理地址。

13.局部性原理?

局部性原理是虚拟内存技术的基础,正是因为程序运行具有局部性原理,才可以只装入部分程序到内存就开始运行。

局部性原理的主要内容就是:

时间局部性 :如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。 空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。

14、为什么虚拟地址空间切换会比较耗时?

进程都有自己的虚拟地址空间,把虚拟地址转换为物理地址需要查找页表,页表查找是一个很慢的过程,因此通常使用Cache来缓存常用的地址映射,这样可以加速页表查找,这个Cache就是TLB(translation Lookaside Buffer,TLB本质上就是一个Cache,是用来加速页表查找的)。 由于每个进程都有自己的虚拟地址空间,那么显然每个进程都有自己的页表,那么当进程切换后页表也要进行切换,页表切换后TLB就失效了,Cache失效导致命中率降低,那么虚拟地址转换为物理地址就会变慢,表现出来的就是程序运行会变慢,而线程切换则不会导致TLB失效,因为线程无需切换地址空间,因此我们通常说线程切换要比较进程切换块,原因就在这里。

15、什么是缓冲区溢出?有什么危害?

缓冲区溢出是指当计算机向缓冲区填充数据时超出了缓冲区本身的容量,溢出的数据覆盖在合法数据上。

危害有以下两点:

程序崩溃,导致拒绝额服务 跳转并且执行一段恶意代码 造成缓冲区溢出的主要原因是程序中没有仔细检查用户输入。

16、什么是虚拟内存?

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

17、虚拟内存的实现方式有哪些?

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

1、什么是分页?

把内存空间划分为大小相等且固定的块,作为主存的基本单位。因为程序数据存储在不同的页面中,而页面又离散的分布在内存中,因此需要一个页表来记录映射关系,以实现从页号到物理块号的映射。

访问分页系统中内存数据需要两次的内存访问 (一次是从内存中访问页表,从中找到指定的物理块号,加上页内偏移得到实际物理地址;第二次就是根据第一次得到的物理地址访问内存取出数据)。

2、什么是分段?

分页是为了提高内存利用率,而分段是为了满足程序员在编写代码的时候的一些逻辑需求(比如数据共享,数据保护,动态链接等)。

分段内存管理当中,地址是二维的,一维是段号,二维是段内地址;其中每个段的长度是不一样的,而且每个段内部都是从0开始编址的。由于分段管理中,每个段内部是连续内存分配,但是段和段之间是离散分配的,因此也存在一个逻辑地址到物理地址的映射关系,相应的就是段表机制。

3、 分页和分段有什区别?

分页对程序员是透明的,但是分段需要程序员显式划分每个段。 分页的地址空间是一维地址空间,分段是二维的。 页的大小不可变,段的大小可以动态改变。 分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。

4、 什么是交换空间?

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

用途:

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

5、页面替换算法有哪些?

在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断从而将该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘对换区中来腾出空间。

最优算法在当前页面中置换最后要访问的页面。不幸的是,没有办法来判定哪个页面是最后一个要访问的,因此实际上该算法不能使用。然而,它可以作为衡量其他算法的标准。 NRU 算法根据 R 位和 M 位的状态将页面分为四类。从编号最小的类别中随机选择一个页面。NRU 算法易于实现,但是性能不是很好。存在更好的算法。 FIFO 会跟踪页面加载进入内存中的顺序,并把页面放入一个链表中。有可能删除存在时间最长但是还在使用的页面,因此这个算法也不是一个很好的选择。 第二次机会算法是对 FIFO 的一个修改,它会在删除页面之前检查这个页面是否仍在使用。如果页面正在使用,就会进行保留。这个改进大大提高了性能。 时钟 算法是第二次机会算法的另外一种实现形式,时钟算法和第二次算法的性能差不多,但是会花费更少的时间来执行算法。 LRU 算法是一个非常优秀的算法,但是没有特殊的硬件(TLB)很难实现。如果没有硬件,就不能使用 LRU 算法。 NFU 算法是一种近似于 LRU 的算法,它的性能不是非常好。 老化 算法是一种更接近 LRU 算法的实现,并且可以更好的实现,因此是一个很好的选择 最后两种算法都使用了工作集算法。工作集算法提供了合理的性能开销,但是它的实现比较复杂。WSClock 是另外一种变体,它不仅能够提供良好的性能,而且可以高效地实现。 最好的算法是老化算法和WSClock算法。他们分别是基于 LRU 和工作集算法。他们都具有良好的性能并且能够被有效的实现。还存在其他一些好的算法,但实际上这两个可能是最重要的。

6、 讲一讲IO多路复用?

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:

当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。 当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。 如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。 如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。 与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

7、 硬链接和软链接有什么区别?

硬链接就是在目录下创建一个条目,记录着文件名与 inode 编号,这个 inode 就是源文件的 inode。删除任意一个条目,文件还是存在,只要引用数量不为 0。但是硬链接有限制,它不能跨越文件系统,也不能对目录进行链接。 符号链接文件保存着源文件所在的绝对路径,在读取时会定位到源文件上,可以理解为 Windows 的快捷方式。当源文件被删除了,链接文件就打不开了。因为记录的是路径,所以可以为目录建立符号链接。

8、 中断的处理过程?

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

9、中断和轮询有什么区别?

轮询:CPU对特定设备轮流询问。中断:通过特定事件提醒CPU。 轮询:效率低等待时间长,CPU利用率不高。中断:容易遗漏问题,CPU利用率不高。

10.什么是用户态和内核态?

用户态和系统态是操作系统的两种运行状态:

内核态:内核态运行的程序可以访问计算机的任何数据和资源,不受限制,包括外围设备,比如网卡、硬盘等。处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况。 用户态:用户态运行的程序只能受限地访问内存,只能直接读取用户程序的数据,并且不允许访问外围设备,用户态下的 CPU 不允许独占,也就是说 CPU 能够被其他程序获取。 将操作系统的运行状态分为用户态和内核态,主要是为了对访问能力进行限制,防止随意进行一些比较危险的操作导致系统的崩溃,比如设置时钟、内存清理,这些都需要在内核态下完成 。

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

所有的用户进程都是运行在用户态的,但是我们上面也说了,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有 系统调用,而能够执行系统调用的就只有 操作系统。

一般用户态 -> 内核态的转换我们都称之为 trap 进内核,也被称之为 陷阱指令(trap instruction)。

他们的工作流程如下:

首先用户程序会调用 glibc 库,glibc 是一个标准库,同时也是一套核心库,库中定义了很多关键 API。 glibc 库知道针对不同体系结构调用系统调用的正确方法,它会根据体系结构应用程序的二进制接口设置用户进程传递的参数,来准备系统调用。 然后,glibc 库调用软件中断指令(SWI) ,这个指令通过更新 CPSR 寄存器将模式改为超级用户模式,然后跳转到地址 0x08 处。 到目前为止,整个过程仍处于用户态下,在执行 SWI 指令后,允许进程执行内核代码,MMU 现在允许内核虚拟内存访问 从地址 0x08 开始,进程执行加载并跳转到中断处理程序,这个程序就是 ARM 中的 vector_swi()。 在 vector_swi() 处,从 SWI 指令中提取系统调用号 SCNO,然后使用 SCNO 作为系统调用表 sys_call_table 的索引,调转到系统调用函数。 执行系统调用完成后,将还原用户模式寄存器,然后再以用户模式执行。

12.Unix 常见的IO模型:

对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说,当一个read操作发生时,它会经历两个阶段:

等待数据准备就绪 (Waiting for the data to be ready) 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process) 正式因为这两个阶段,linux系统产生了下面五种网络模式的方案:

阻塞式IO模型(blocking IO model) 非阻塞式IO模型(noblocking IO model) IO复用式IO模型(IO multiplexing model) 信号驱动式IO模型(signal-driven IO model) 异步IO式IO模型(asynchronous IO model) 对于这几种 IO 模型的详细说明,可以参考这篇文章:2021-Java后端工程师必会知识点-(操作系统) - 掘金

其中,IO多路复用模型指的是:使用单个进程同时处理多个网络连接IO,他的原理就是select、poll、epoll 不断轮询所负责的所有 socket,当某个socket有数据到达了,就通知用户进程。该模型的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

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

(1)select:时间复杂度 O(n)

select 仅仅知道有 I/O 事件发生,但并不知道是哪几个流,所以只能无差别轮询所有流,找出能读出数据或者写入数据的流,并对其进行操作。所以 select 具有 O(n) 的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。

(2)poll:时间复杂度 O(n)

poll 本质上和 select 没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个 fd 对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的。

(3)epoll:时间复杂度 O(1)

epoll 可以理解为 event poll,不同于忙轮询和无差别轮询,epoll 会把哪个流发生了怎样的 I/O 事件通知我们。所以说 epoll 实际上是事件驱动(每个事件关联上 fd)的。

select,poll,epoll 都是 IO 多路复用的机制。I/O 多路复用就是通过一种机制监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),就通知程序进行相应的读写操作。但 select,poll,epoll 本质上都是同步 I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步 I/O 则无需自己负责进行读写,异步 I/O 的实现会负责把数据从内核拷贝到用户空间。

14、死锁

死锁是指两个或两个以上的进程,在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在相互等待的进程称为死锁进程。

1.死锁:如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁。 2.产生死锁的必要条件:同时具有四个必要条件,只要其一不满足,就不会发生死锁。 <1:互斥条件:临界资源,只能别一个进程占用。 <2:请求和保持条件:正在占有资源,并且还提出新的资源请求,得不到心得请求时,也不释放自己原有的资源。 <3:不可抢占资源 <4:循环等待条件。 3.处理方法:a、预防死锁:限制条件,破坏死锁四个必要条件中的一个或几个。 b、避免死锁:在资源的动态分配过程中,用某种方法防止系统进入不安全的状态(试分配),防止死锁。 c、检测死锁:检测及时发现死锁,采取适当措施。 d、解除死锁:撤销进程,或回收资源等。 <1、预防死锁:主要是破坏后三个条件: (1)破坏请求和保持条件:a、第一种协议:规定,所有进程在运行之前,必须一次性的申请其在整个运行过程中所需要的全部资源,-----------一次分配,不允许动态申请。----只要有一总资源不能满足,就不分配任何资源 缺点:资源严重浪费:分配而不使用。 进程容易发生饥饿现象,进程迟迟不能开始:长时间等待。(啥时候能全部分给我) b、第二种协议:允许一个进程只获得运行初期所需的资源,便开始运行,运行过程中在逐步释放已分配资源,然后再请求新的资源。 (2)破坏不可抢占条件:协议规定:当一个已经保持了某些不可抢占资源的进程,提出新的资源请求二不能得到满足时,他必须释放已经保持的所有资源,待以后需要时在重新申请。 (3)破坏循环等待条件:对系统所有资源类型进行线性排序,并赋予不同的序号。 注:每个进程必须按照序号递增的顺序请求资源,若请求到一些序号较高的资源,还想请求序号低的资源,则必须释放所有具有相同和更高序号的资源后,才能申请序号低的资源。 <2、避免死锁:在资源的动态分配过程中,用某种方法防止系统进入不安全的状态(试分配),防止死锁。 (1)系统安全状态:允许进程动态申请资源,但资源进行分配之前先计算安全性。 (2)安全状态例子:

进程| 最大需求| 已分配 | 可用 p1| 10 |5 |3 p2| 4 |2 | p3| 9 |2 | 安全推进的进程序列: p2---》p1---》p3 注:当有进程请求一个可用资源时,系统需对该进程的请求进行计算(试分配),若将资源分配给 进程后系统仍处于安全状态,才将该资源分配给进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值