操作系统面经整理

操作系统

1.虚拟内存的几种映射技术?
(1)页式管理
-就是将内存分为固定大小的页,这个是由操作系统控制的,对于用户而言是透明的,未用户提供一维地址空间供用户查询,页内偏移是硬件处理的。
-优点:没有外部碎片,内部碎片不会超过页的大小。
-缺点:可能会在处理一个程序的过程中或者一条指令的时候频繁的发生缺页中断,从而产生抖动。
(2)页式管理
-就是将内存按照一定的逻辑进行划分。
-优点:段的逻辑独立性易于编译,管理和修改,便于多道程序共享;段长可以根据需求动态变化;
-缺点:主存空间分配的时候比较麻烦,容易出现碎片。
(3)段页式存储的管理方式
-分段和分页各有优点,分页能有效利用内存,分段更好满足用户需要。段页式就是将二者的优点合并,用户程序划分成段并赋予段名,之后每一段再划分成页,地址为:段号,段内页号,页内地址。
-优点:综合了以上的优点
-缺点:访问一次需要多次访问内存;
2.什么是系统调用?
(1)首先需要了解的概念就是用户态和内核态,用户态就是当前用户可以读取用户程序的资源,内核态则是可以使用计算机的所有资源。
(2)如果我们的计算机运行在用户态同时想要使用系统态级别的功能,就需要使用系统调用了。
-设备管理:设备的请求和释放;
-文件管理:完成文件的读和写;
-进程通信:进程之间的消息传递;
-进程控制:进程的创建和撤销;
-内存管理:完成内存的分配和回收;
3.线程的同步方式?
(1)互斥量Mutex,就是同一时刻只有一个线程能访问资源。
(2)信号量:控制在同一时刻访问资源的线程数量。
(3)事件:通过通知操作来保持多线程同步,方便的实现线程优先级的比较操作。
4.解决死锁的方式?
(1)预防
-一次性将所有需要的资源都请求得到。
-层次性分配,一个进程获得当前资源之后才能请求更高级别的资源。
(2)避免
-在资源分配之前去检测,看看究竟有没有可能造成死锁。
(3)检测:判断有无环;
(4)解除:撤销发生死锁的进程。
5.操作系统读写磁盘,影响读写的效率的因素有哪些?
寻道时延,旋转时延,实际数据的读取和写入时间。
6.什么是进程地址空间?
(1)进程的地址空间是随着进程创建而分配的,进程小时了他也就没有了,其实也是一种对于物理内存的一种映射。
(2)其中包括
-堆;-栈;-环境变量;-代码;初始化/未初始化数据;-字符串常量等。
7.说一下页面置换算法?
(1)OPT:就是调出以后都不会再使用的页,这种一般是不太可能实现的,所以一般是衡量其他算法的尺度。
(2)FIFO:先进先出。
(3)LRU:最近最久未使用。
(4)LFU:最少页面置换算法。
8.线程切换需要保存哪些上下文?
(1)堆栈指针
(2)程序计数器
(3)线程id
(4)线程状态等
9.进程切换的过程?
(1)首先保存当前进程的状态,寄存器信息等。
(2)更新当前进程对应的PCB里面的信息。
(3)将其加入PCB的队列。
(4)之后取出来一个PCB执行其对应的进程。
10.负载均衡策略?
(1)轮循:将请求依次分发到服务器的后端,对于每个后端来说,都接受相同数目的请求(但是比如我们想让一台强大的机器接受多的请求就不满足了)。
(2)加强轮循:就是为每一个增加一个权值,根据权值大小的不同来确定到哪台机器,同样的,无法自动调节。
(3)采用Hash算法:就是根据ip和url来计算,这样会把相同的请求路由到一台机器上。(一台宕机就gg)
(4)随机random:就用算法实现,但是不适合对命中率有要求的。
(5)一致性哈希(可以进行简单的算法研究):就是搞出来一个环(MD5算法得到其中所有的值,即0-264这么多个点。比如我们有三个后台,就将这么多个点除以三,之后当我们来了请求的时候,就看落在哪个区间之内,就选用哪个点。
(6)一致性哈希改进:对于每台服务器,我们搞出来1000个点和他对应,这样就相当于减少了增加和减少服务器的不均衡状况。
(7)最小连接数:维护每台服务器的最小连接,看看谁的连接少,就把当前的请求分发给谁。这样的操作会增加资源消耗,单独的服务器或者表结构来进行查询。
(8)加权最小连接数:就是在最小连接数的基础之上进行加权
11.简单说一下socket通信的阻塞和等待?
(1)首先,假设我们有三个进程都在内存中轮番执行,这个时候,进程A想要创建一个socket对象来接受网络上的数据。
(2)创建之后,这个socket对象就会交由文件系统管理,同时其缓冲区中也并无数据,处于等待状态(阻塞住了),这个进程的引用挂于socket对象的等待列表中。
(3)CPU在这个时候就轮番执行B,C进程而不再管A进程。
(4)当缓冲区有数据了,就唤醒,并加入工作队列,继续执行。(注意:如何知道网络数据对应哪个进程?Ip和端口号,每一个socket对应一个端口,这里面系统要维护一个表,端口号和socket对象之间的对应关系)
12.后续出现了IO多路复用,那么这个模型是什么样的?
(1)相当于一个数组结构,数据里面存放所有的Socket对象,我们的进程A可以监控所有的socket对象,其实就是将其挂在所有的socket对象的等待队列后面。
(2)调用select方法的时候就是遍历这个数组,看看哪个socket里面的缓冲区不为空,有不为空的就唤醒A进程继续执行就完事了。
(3)缺点(每次调用select都需要遍历整个数组,删除的时候也需要遍历整个数组,很是麻烦,增加开销,程序被唤醒之后,还需要知道哪个socket里面带数据,所以还需要遍历一遍),其实是调用select的时候进行扫描一遍。
(4)默认只能监听1024个socket。
select 实现多路复用的方式是,将已连接的 Socket 都放到一个文件描述符集合,然后调用 select 函数将文件描述符集合拷贝到内核里,让内核来检查是否有网络事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将此 Socket 标记为可读或可写, 接着再把整个文件描述符集合拷贝回用户态里,然后用户态还需要再通过遍历的方法找到可读或可写的 Socket,然后再对其处理。
所以,对于 select 这种方式,需要进行 2 次「遍历」文件描述符集合,一次是在内核态里,一个次是在用户态里 ,而且还会发生 2 次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。
13.说一下几种常见的IO模型?
(1)同步阻塞IO:当我们发起请求的时候,在内核读取数据不会马上返回,而是需要等待数据接收完毕之后或者是发生错误的时候返回,这样就会导致当前进程一直在阻塞。
(2)同步非阻塞IO:当我们发其请求的时候,会先行查看数据有没有准备好,准备好了的话直接返回;没准备好就返回错误,相当于用户都能收到立即返回,不断的进行请求,直到获取了结果。
(3)IO多路复用:当我们的系统处于一个高并发的情况下,那么对于每一个io操作都会阻塞一个进程而言,就会出现资源消耗过大的情况,这样就需要我们进行一个线程监控多个socket减少资源的浪费。
epoll通过三个函数解决poll和select方法的缺陷。
-epoll_create: 创建一个epoll文件描述符集合,同时底层创建一个红黑树和就绪链表,红黑树存储所监控的文件描述符的节点数据,就绪链表存储就绪的文件描述符的节点数据。
-epoll_ctl: 用于添加新的描述符,首先判断红黑树中是否存在,如果不存在,插入数据,并告知内核注册回调函数(当文件描述就绪时通过网卡驱动触发),数据就绪后将事件添加到就绪队列中。
-epoll_wait: 检查链表,并将数据拷贝到用户空间(两者维护的是片共享内存),最后清空链表。其中epoll的工作方式分为LT、ET。
注意:epoll是线程安全的,但是当一个线程调用epollwait,而另一个线程用epollctl向同一个epoll_fd添加一个监测fd后,epollwait有可能被改fd的读/写事件唤醒。
(4)信号驱动IO:首先用户进行通过系统调用在内核安装一个信号处理函数,该系统调用会立刻返回,不会阻塞,数据准备就绪的时候,内核会为这个进程准备一个信号,用户进程就可以读取数据导内存。
(5)异步IO:内核收到之后会立即返回,之后去做这个事情,做完了就向程序发送一个signal信号,表示自己干完了。
14.epoll的lt和et模式?
(1)lt称为水平触发,当我们发现有事件完成通知应用程序的时候,应用程序可以不进行处理这个事件,下次再调用epoll_wait的时候,还会将这个事件发送给应用程序。
(2)et称为边缘触发,当有事件完成通知应用程序的时候,应用程序必须进行处理,要是不处理的话,下次就不通知了。
15.单核的CPU运行会存在线程安全问题吗?
一样会有的,因为单核CPU也无法保证CPU在什么时候切换线程,举例就是i++操作,我们无法保证什么时候切换线程就无法保证结果的正确性。
16.进程间的通信方式?
(1)管道:管道一边顺序写入数据,另一边顺序读出数据。属于内核中的一块缓存区,通信方式效率低,不适合进程间的频繁交换数据。
(2)消息队列:你来一个,我用一个这种,内核中的消息链表。通信不及时,不适合叫大数据传输(内核态和用户态数据的相互拷贝),可以频繁的交换数据类型,可以自定义数据类型。
(3)共享内存:两个进程的虚拟内存映射到一块物理内存中,一个进程写入,另一个马上就能看到。(共享内存的几种实现方式)
(4)信号量:实际就是解决共享内存的问题,P操作信号量-1,如果值大于等于0,就可用;之后释放资源的时候就是V操作,信号量+1,值大于等于0就唤醒其余的进程。
(5)信号:例如linux中的crtl+c就是强行结束当前进程,释放信号去和进程间通信。
(6)Socket:套接字通信。使得可以将信息不光跨进程,还可以在网络之间传输。
17.进程创建的过程?
(1)申请空白的PCB。
(2)为新的进程申请资源。
(3)初始化PCB。
(4)将新进程加入就绪队列。
18.fork和exec的区别?
(1)fork相当于创建当前进程的子进程,和当前进程公用一个数据区,里面什么东西都是一样的;但是当子进程开始执行的时候,就会慢慢和父进程剥离开,数据开始隔离。
(2)exec相当于再同一块进程内存中使用新的程序代替调用exec 的那个进程,新进程会保持原来的进程的进程号不变。
19.什么是写时复制技术(copyOnWrite)?
copyOnWrite技术的思路是通过写时复制的方式来来解决并发的问题,采用一种读写分离的思想,这样在读的时候,可以并发读,提高效率。具体的方式,是并发读,然后写入前,先复制一份,然后在复制的那一份数据中,写入需要的数据,然后替换掉原来的引用,那么就写成功了。需要注意的是,copyOnWrite只能保证最终一致性,不能实时更新。
20.什么是PCB?
进程创建得时候随之创建得一个常驻内存得东西,任意时刻可以存取,进程结束得时候可以删除。
(1)进程得描述信息:进程标识符;用户标识符。
(2)进程得控制和管理信息:进程当前状态;进程优先级等等。
(3)资源分配清单:有关地址或者内存地址得分配信息。
(4)处理机相关信息:各种寄存器内部存储的值,进程切换之后重新执行得时候能找到状态之类得。
PCB得组织方式可以有链式和索引式,按照进程得状态形成链表或者是将同一个状态得进程对应得PCB创建一张索引表存放。
21.什么是IO多路复用?
(1)sellect和poll:
select 实现多路复用的方式是,将已连接的 Socket 都放到一个文件描述符集合,然后调用 select 函数将文件描述符集合拷贝到内核里,让内核来检查是否有网络事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将此 Socket 标记为可读或可写, 接着再把整个文件描述符集合拷贝回用户态里,然后用户态还需要再通过遍历的方法找到可读或可写的 Socket,然后再对其处理。
所以,对于 select 这种方式,需要进行 2 次「遍历」文件描述符集合,一次是在内核态里,一个次是在用户态里 ,而且还会发生 2 次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。
select 使用固定长度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,在 Linux 系统中,由内核中的 FD_SETSIZE 限制, 默认最大值为 1024,只能监听 0~1023 的文件描述符。
poll 不再用 BitsMap 来存储所关注的文件描述符,取而代之用动态数组,以链表形式来组织,突破了 select 的文件描述符个数限制,当然还会受到系统文件描述符限制。
但是 poll 和 select 并没有太大的本质区别,都是使用「线性结构」存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。
(2)epoll
epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删查一般时间复杂度是 O(logn),通过对这棵黑红树进行操作,这样就不需要像 select/poll 每次操作时都传入整个 socket 集合,只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。
epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。
https://www.zhihu.com/question/32163005
22.系统调用都有什么东西?
(1)进程控制:fork创建子进程,exit终止进程。
(2)文件操作:open,read,write,close,create
(3)系统:sysinfo,获取系统信息
23.什么是伪共享?
计算机为了节省访问内存的时间,会设置多级缓存,只有上一级缓存未命中的时候才会去考虑去访问下一级缓存;在这种情况下,缓存是以缓存行去存放的。如果两个CPU要访问的数据在同一个缓存行里面同时这两个数据是有关系的,那么就是共享。假设CPUA要访问张三,CPUB要访问李四,虽然张三李四毫无关系,但是他们存放在一个缓存行里面,这种就是伪共享,浪费时间,还没啥卵用。
24.如何避免伪共享?
(1)让不同线程操作的不同对象存在于不同的缓存行,就缓存行进行填充就行了,假设一共64bit,前8位存正常的东西,后56位存没用的就可以了。
(2)强制按照缓存行对齐。
25.什么是僵尸进程?
(1)当我们由父进程创建子进程之后,子进程执行完了任务把必要资源释放了,但是还留下一定的信息去保证父进程能够找到它,这样的进程就是僵尸进程,僵尸进程一旦多了,会使我们创建进程创建不了;
(2)可以删除僵尸进程kill CHLD 父进程号
26.什么是孤儿进程?
父进程创建子进程之后,父进程终止了,这时候子进程就会被systemd收容,这种进程都称为孤儿进程,init会清理。
27.共享内存的几种实现方式?
(1)基于物理的实现方式(XSI):通过申请一个共享内存并返回一个key值,其他进程可以通过key找到这块共享内存;调用shmat方法可以通过key找到这块共享内从并挂载到当前的地址空间。
(2)基于文件映射实现的共享内存(mmap):进程将一个普通文件映射到每个进程的地址空间中,对映射区的改写会被写回到文件当中。
28.线程和进程的区别?
(1)进程;一般进程和应用程序一一对象,每个进程对应一个端口号,进程是资源分配的最小单位,一个进程可以包含若干个线程。
(2)线程:系统分配处理器时间的最小单位(基本单元),程序执行的最小单位。
29.进程调度算法有哪些?
(1)先来先服务;
(2)短进程优先;
(3)优先级调度算法;
(4)时间片轮转算法;
(5)多级反馈队列调度算法,优先级由高到低得队列,只有优先级高的队列中得进程执行完成才能到低得。
30.什么是协程?
(1)协程是运行在线程上面得一个东西,其在线程得基础之上采用分时复用得方式运行。
(2)协程得切换在用户态不在内核态,所以代价小很多。
31.什么是中断?
中断就是某些意外情况需要主机干预,机器能够自动停止程序进入新的程序,中断也是用户态到核心态的唯一途径。
(1)外中断/中断:中断发生的时候,处理机先处理好当前的东西,再去处理别的。比如IO。
(2)内中断(异常):程序错误,软件异常。
32.Linux如何设置后台进程?
(1)nohup:屏蔽hup信号,中断会在exit的时候退出去。
(2)Setid:也可以设置,原理就是将其父进程设置成1systemd,这样就父进程不g这个进程一直不会g。
33.僵尸进程于孤儿进程?
(1)僵尸进程:子进程在执行完成之后会留下来pid等关键信息,供其他的进程查询的时候使用,这种就叫做僵尸进程,kill CHLD 父进程id
(2)孤儿进程:父进程先于子进程g了,子进程就都会被挂到systemd上面。
34.什么是用户态,什么是内核态?
(1)用户态:只能访问受限的内存,且不允许访问外围设备,占用CPU的能力被剥夺,CPU的资源可以被其他线程获取。
(2)内核态:CPU可以访问内存的所有数据,包括外围设备,硬盘,同时CPU也可以将自己从一个程序切换成另一个程序
-系统调用,异常和中断会使程序由用户态转换为内核态。
为了安全,要是没有这个化分,程序就可以随随便便的访问所有的资源,这样就导致了如果将不适合的程序写到了错误的内存中,就会直接爆炸。
35.BIO和NIO?
(1)就是同步阻塞模型和同步非阻塞模型。
(2)NIO通过选择器来进行监视多个Socket,这样当我们想查看究竟有没有通信事件的时候,没有就去干别的事情,不会再这等。
36.Linux的常用命令?
(1)ll列表查看;ls直接查看
(2)mkdir创建文件;rm删除文件;rm-rf删除
(3)mv修改名字;cp复制文件
(4)touch创建文件
(5)vi就是修改,insert就是改,之后esc完了:wq
(6)cat看最后一屏,less分页查看
(7)tar -zxvf解压;tar -zcvf压缩
(8)su切换用户;sudo临时使用root用户。
(9)ps -ef 查看所有运行得进程
37.进程间的通信方式?
(1)管道匿名通信:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程之间流动,一般是父子进程。
-父进程创建管道,子进程
-父进程关闭读,子进程关闭写,之后父进程塞数据,子进程读数据。
(2)高级通信管道:将另一个程序当作一个新的进程在当前进程里面启动(类似于他的子进程)。
(3)有名管道通信:允许没有亲缘得进程进行通信。
(4)消息队列通信:克服了只能传递无格式字节流得问题。
(5)信号量通信:就是多个进程访问临界区资源。
(6)共享内存:配合信号量。
(7)信号机制
(8)Socket
38.什么是外部碎片?什么是内部碎片?
(1)外部碎片就是没有分配的,但是拥有的存储空间有限,无法在进行分配(1,2,3号空间,1,2,3分配了,之后2释放了,剩余这样一块空间,但问题是再来的数据都比这块大,无法分配)。
(2)内部碎片就是已经分配的,但是用不了,就是1,2,3号空间,最小的分配单位就是块空间,我们分了2.5块空间的东西,把三块都占用了,第三块里面剩下的一半也用不了了。
(3)MySQL可能是因为索引使用UUID产生碎片
39.什么是虚拟内存?
(1)他将主存看成一个存储在磁盘空间上的地址空间的高速缓存,主存中只保存活动区域,根据需要在主存和磁盘之间移动数据。他为进程提供了一致的空间管理,简化了内存管理,保护了每个进程的地址空间不被其他的进程破坏。
(2)当我们在缓存中读取数据的时候,如果有的话,就直接去区虚拟地址引用,之后用磁盘里的数据;要是没命中的话,出发缺页,就去磁盘中替换,
40.未命中的执行流程?
(1)首先用户会发出一个虚拟地址,这个虚拟地址会通过MMU(专门翻译的东西)产生一个物理地址,并向主存中请求这个物理地址。
(2)主存这个时候就返回这个物理地址,但是物理地址对应的有效控制位是0,也就是不存在,MMU出发了一次异常。
(3)缺页处理程序确定物理内存中的牺牲页,之后将其换出磁盘。
(4)调入新的页面,更新PTE。
(5)CPU重新发出地址,找到了,之后完成数据请求。
41.单核CPU使用多线程的时候,会提升速度吗?
(1)如果是IO密集型,那么我们每个线程会等待线程操作,这样就会节省时间,相当于只是耗费了一个线程上下文切换的时间。
(2)如果是计算密集型,切换了线程也只是一个CPU在干活,那么都一样的,还会浪费一个线程上下文切换的时间。
42.什么是信号驱动IO?
就是预先告知内核,当某个文件描述符即将发生事件的时候让内核发送一个信号通知进程。系统需要注册信号处理函数,启动了信号处理驱动IO之后,就可以继续执行程序了,数据准备好了之后内核发送一个信号给用户进程,之后用户进程调用recvfrom函数,这种模型在内核等待期间是不会阻塞的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值