一、操作系统概述

1.简单说下你对并发和并行的理解?
答:并行是多个事件可以同时发生,与之相应的是串行,串行是指任意时间上只能有一个事件发生。
并发是指能够有处理多个事件的能力,与之相应的是顺序,事情只能一件一件的执行,并发指无论上一件事件是否完成都可以执行当前事件。
2.静态链接库和动态链接库的区别?
答:静态库和程序一起编译,生成一个可执行文件。而动态链接库是在程序运行时期才和库函数链接在一起。好处是多个程序运行时,只需要加载一次动态链接库。
3.什么是用户态和内核态?
答:是CPU运行的两种状态。处于内核态的CPU可以获取别的程序的数据,也可以获取外围设备的数据。用户态下运行用户程序,不能直接对硬件进行访问,运行的内存空间也受限制。
4.用户态和内核态是如何切换的?
答:系统调用:这是用户进程主动要求切换到内核态的一种方式,是通过中断完成的。
异常:CPU在用户态运行下发生了某些事先不可知的异常,这时会切换到内核去处理,比如缺页异常。
外围设备的中断:设备完成用户请求后,会发起中断请求处理,CPU转而处理相应事件,这个过程就变成了用户态转为了内核态。

二、进程/线程管理**

1.挂起与阻塞的区别?
答:阻塞主要是因为进程因为发生某事件,可能是等待信号量,等待资源等,而让出cpu执行权。
挂起主要因为操作系统资源不足的情况或者其他情况,将一些内存中的进程放到内存外,等待时机符合时才重新执行。
2.进程切换的过程?
答:1)一个正在运行的程序遇到中断或者系统调用会将CPU的控制权从当前进程转移到操作系统内核。
2)操作系统内核会将当前进程的上下文信息(寄存器状态,程序计数器)等保存到进程控制块PCB中.
3)操作系统内核从下一个进程的PCB加载上下文,然后CPU就开始执行下一个进程。
3.进程和线程的基本概念,区别?
答:1)进程是一个运行中的程序,是操作系统进行资源分配的一个独立单位。线程是进程中的一个子任务,是CPU调度的最小单位。
2)每个进程都有自己的运行地址空间,相互独立。而一个线程出现错误可能使整个进程死亡。
3)资源:进程(栈、寄存器、页表、和文件句柄等);线程(程序计数器,少量栈空间、寄存器、状态字)
4.进程间的通信方式有哪些?
答:管道、命名管道、消息队列、共享内存(信号量实现进程间的同步与互斥)、Socket
管道:管道是一块缓冲区,半双工的通信方式,有固定的读写端,一个进程向缓冲区的一端写入数据,另一个进程从缓冲区的另一端读出数据。
无名管道:无名管道只存在于内存中,用于亲缘进程之间的通信。
命名管道:命名管道存在于文件系统中,用于任何进程之间通信。
消息队列:消息队列是在内核中的一个消息链表,其中的消息都有自己特定的消息类型,和优先级等信息,进程可以按照一定规则向消息队列中写入消息,接收的时候也可以不用按照队列次序来读取数据。
共享内存:共享内存是在内存中的一块区域,不同进程可以将该区域地址映射到自己的地址空间中,不同进程都可以在该区域进行行读写,可以通过信号量来实现不同进程间的同步与互斥。共享区域的效率最高,因为不需要多次的拷贝数据。
5.进程的调度算法有哪些?
答:先来先服务调度算法:根据进程就绪的队列的顺序执行进程,一个进程执行完才能执行下个进程。
时间片轮转调度算法:时间片轮转调度算法会给每个进程规定一个执行时间,也就是时间片,CPU执行时间到了该进程还没执行完就会把该进程放回队列执行下一个进程。
短作业优先调度算法:会优先执行时间较短的进程,这样会导致一些长时间的作业运行不了。
最短剩余时间优先调度算法:是对短作业优先调度算法上加入了抢占机制,当新加入了一个进程,其运行时间比当前运行的进程时间短就会优先处理新加入的那个进程。
高响应比优先调度算法:响应比是(预计处理时间+等待时间)/预计处理时间,是为了防止进程等待时间过长。
优先级调度算法:该算法会从就绪队列中选择优先级最高的进程。
6.外中断和异常的区别?
答:外部中断是指CPU执行指令外的事件引起的,比如I/O中断,鼠标键盘发起来一个中断请求,还有时钟中断,事件到了就引起中断。
异常是指CPU执行指令的内部事件引起,比如堆栈溢出等。
中断是硬件设备产生的,异常是程序在CPU产生的;内核需要根据异常还是中断调用不同的处理程序。
7.进程退出的方式?
答:正常退出:进程执行完成后正常退出。
错误退出:进程执行过程中遇到异常情况,被迫退出。
被其他进程杀死。
8.守护进程和僵尸进程和孤儿进程?
答:守护进程是后台运行的程序,在后台周期的运行,比如垃圾回收器就是这样的一个守护进程,还有进程监控程序。
僵尸进程:指一个已经终止,但是父进程还未获取到其终止信息的进程。当其父进程终止后,init进程会自动接收这个僵尸进程,将其清理。
孤儿进程:如果父进程先退出,子进程还没退出,那么这些子进程会成为孤儿进程,孤儿进程将被Init进程所收养。
9、线程都有哪些方法?
答:

  • join:会阻塞其他线程,比如main中有一个thread线程,当调用thread.join()会阻塞主线程,直到thread执行完毕。
  • yied:礼让,线程调用了该方法会让出cpu执行权,进入就绪状态。
  • sleep:会暂停线程,直到指定之间到了会继续执行。


三、内存管理

1.用户空间和内核空间?
答:操作系统把内存空间分为了两部分,内核空间和用户空间,内核空间内的进行有着更高的权限,用户空间的进程不能对内核空间直接进行读写。
2.什么是缓冲区溢出?有什么危害?
答:缓冲区是指暂时放置数据的一块区域,当写入数据大于缓冲区容量时就会覆盖掉缓冲区外的数据,缓冲区外的数据有可能是系统中很重要的数据,一般会导致程序出错。
3.分段存储和分页存储的概念与区别?
答:分段存储是将用户的程序分为大小不同的段,不同段管理的数据不同,每个段都从0开始编址,访问地址的时候用段基址加上段内偏移地址访问程序。可以提高内存利用率。如果使用连续分配的话存在内存碎片。
分页存储的页的大小是固定的,有页号和页内位移量还有页表,操作系统可以根据这些信息将不同页的地址组成一块连续的地址空间。分页是为了系统管理的需要,为了提高内存利用率。
4.物理地址、逻辑地址、虚拟内存的概念?
答:物理地址:从内存中取得数据的地址,是物理上真正的地址,每个地址在内存中都是唯一的。
逻辑地址:在分段存储中,每段中的地址都从0开始的,并不代表真正的地址,这种叫逻辑地址。
虚拟内存:
为什么用虚拟内存?当一些作业任务太大时内存放不下,就会将其他的放到外存中,还有一些被阻塞的进程暂时使用不上而一直在内存中就会占用资源,所以用虚拟内存。
主存-虚拟内存结构就像是缓冲区-主存两级存储结构一样,在主存中是一些经常使用到的进程,会将不常使用到的进程然入到外存中,当用户访问的进程不在主存中就会从外存调入。
5.什么是页面置换算法?
答:发生缺页中断的时候,缺页是访问的地址在外存中,操作系统必须选择一个内存中的页面将其换出内存,如果该页面在内存驻留期间发生修改,那么需更新该页面在外存中的副本,如果没有修改,就直接覆盖。
选择置换页面的算法就是页面置换算法。
最优置换算法:将最晚执行的页面与之替换,这种算法不能实现,因为不知道各个页面下一次什么时候被访问。
最近未使用页面置换算法:在页表中,每个页面有一个被访问标志位和被修改标志位,有一个时钟会定时清零被访问标志位,操作系统会优先选择未被访问和未被修改的标志的页面进行替换。
先进先出页面置换算法:这种算法用一个队列来维护页面,将最先进入队列的页面进行置换。
第二次机会页面置换算法:这个是在先进先出页面置换算法的基础上做了进一步调整,从队列头取出来的页面先检查其被访问标志位,如果最近被访问就将其清零放入队尾;如果未被访问就直接将其进行替换。
6.系统中有了快表后,地址转换过程有什么变化?
答:快表是一种访问速度比内存块很多的高速缓冲存储器,快表中存储了一些常用的页面,根据给出的逻辑地址算的页号,页内偏移量,找快表中有没有,如果有,直接从快表中对应物理地址。 如果没找到再从页表中去找。快表也是一种局部性原理的应用,类似缓存的机制提升效率。
7.说一说空闲内存的管理?
答:有两种方法,一种是用位图,一种用链表。
对于位图,系统把内存分成了小块,一个小块在位图中对应一个位,如果该小块被使用,就在位图中用1表示,如果是空闲的就用0来表示。
对于用链表存储,一个节点包含一个标志位和起始地址和长度,标志位用来表示该块是进程还是空闲的,后面表示这块内存的起始地址和大小。在链表中存放进程和空闲区信息是按照地址顺序的。
8.说一说动态分配内存算法?
答:首次适配算法:从链表头开始找空闲区,找到第一个适配的空闲区结束。
下次适配算法:跟首次适配算法的机制一样,不过不是表头开始找,而是从上次查找结束的位置找。
最佳适配算法:每次从表中找到能够容纳进程的最小分区,缺点是会留下很多小的空闲区碎片,并且回收进程分区需要重新对空闲分区进行排序。
最差适配算法:和最佳适配算法相反,优先使用最大的空闲分区。缺点是把大的空闲分区都用了,导致大内存进程无法加载,还有同样当回收进程分区会对分区进行排序。
9.逻辑地址转换为物理地址的基本过程?
答:1)根据逻辑地址计算出页号和页内偏移地址
2)查找页表找到页号对应的页表项
3)根据页表项找到对应的内存块号,再结合页内偏移地址找到对应的物理地址。
10.进程同步的几种方法?
答:1)临界区
对临界资源进行访问的那段代码叫临界区,是为了实现进程间互斥。
2)信号量
信号量是一个整型变量,可以对其进行up和down操作,也就是P和V操作。
当进行down操作的时候,会对信号量减一,如果信号量等于0,就让进程等待信号量大于0;
当进行up操作的时候,会对信号量加一,并且会唤醒睡眠的进程让其完成down操作
3)管程(monitor)
11.说一下缺页中断?**
答:操作系统在内存中给划分为一页一页的,每页的大小都相同,当要查找的数不在内存中就会发起缺页中断,从内存外查找数据,通过页面置换算法来将需要的数据所在页面加载到内存中。

四、文件管理

五、IO外设

1.BIO和NIO(Non-Blocking)的区别?他们的应用场景是什么?
答:首先,BIO的阻塞的,面向流的,一个客户端连接创建一个线程处理,在数据发送过来之前,线程只能等待。
NIO是非阻塞的,面向缓存区的,有一个选择器来选择客户端连接,客户端先发送数据到缓冲区,线程轮流查询各个IO,如果有数据发送过来就处理,如果没有就读取空值,不会停在那里等待数据发送过来,转而去查询其他IO。
NIO适合处理连接数目特别多但是连接比较短的情况,服务器需要支持超大的
BIO适合连接数目比较小并且一次发送大量数据的场景。
2.IO多路复用的几种系统调用(select、poll、epoll)主要区别?
答:IO多路复用用一个线程来维护多个请求Socket
select:
select系统调用使用BitsMap来传入和接受FD(连接/Socket),而BitsMap限制了每次传入的FD个数,最多只能传入1024个FD;并且每次调用都会在用户空间和内核空间之间对FD集合进行拷贝;轮询的方式来查询FD有无事件发生,事件复杂度为O(n)。
poll:
poll与select的区别是poll系统调用不再使用BitsMap来传入FD,而是使用链表来传入,传入数量受内核内存大小限制,而其他都与select一样。
epoll:
epoll在内核采用红黑树存储所有FD,不用每次调用都拷贝一次FD集合,只有加入连接的时候拷贝一次,并且监听数量一样只受内核内存大小限制。
epoll还有个链表来记录就绪事件,当某个FD有事件发生时就会加入到这个就绪队列,当用户要读取数据直接返回这个就绪队列就行了,而不用轮询整个集合。
3.epoll的边缘触发模式和水平触发模式?
答:水平触发模式:被监控的Socket有数据可读就会一直提醒用户去读取数据,直到数据给读取完。
边缘触发模式:被监控的Socket有数据可读只会提醒用户去读一次,在下一次有数据流之前都不会再提醒用户去读。
4.同步和异步,阻塞和非阻塞的区别?
答:第一种解答:对于进程间通信,同步和阻塞,异步与非阻塞是同义词;
对于发送方,调用发送消息的函数后会阻塞直到消息被接收方接收,这是阻塞式发送;
调用发送消息的函数不用等待接收方接受消息就可以做其他事情,这是非阻塞式发送。
对于接收方,调用接受消息的函数后会阻塞直到消息到达,这叫阻塞式接受;
调用接收消息的函数要么得到消息,要么得到一个空值,这就非阻塞式接收。
第二种解答:同步和异步是通信机制,关注的是发送消息是否需要等待接收方接受,同步是发送方在接受方收到消息前一直等待其收到。异步是不需要接收方收到消息就去做其他事情。
阻塞和非阻塞指的是调用者的状态,比如多个线程调用一个资源,当资源被占用,线程等待资源释放不做其他事叫阻塞,如果不用等待资源释放而去做其他事,时不时的看资源是否可用,叫非阻塞。

**