操作系统面试题
操作系统基础
什么是操作系统?
1.操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的程序。
2.操作系统本质上是一个运行在计算机上的软件程序,用于管理计算机硬件和软件资源。
3.操作系统存在屏蔽了硬件层的复杂。
4.操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。
内核态和用户态
在CPU的所有指令中,有些指令是十分危险的,如果错用,将导致系统崩溃,比如清除内存、设置时钟等。如果所有程序都能使用这些指令,那么系统死机的概率将大大增加。所以,CPU将指令分为特权指令和非特权指令,对于危险的指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。
从用户空间到内核空间有以下触发手段:
1.系统调用。用户进程通过系统调用申请使用操作系统提供的服务程序来完成工作。
2.中断。当外围设备完成用户请求后,会向CPU发送中断信号。这时CPU会暂时执行下一条指令(用户态)转而执行该中断信号对应的中断处理程序(内核态)。
3.异常。当CPU在执行运行在用户态下的程序时,发生了某些事先不可预知的异常,这时会触发由当前运行进程切换到处理此异常相关的内核相关程序中,也就转换到了内核态,比如缺页异常。
中断和异常
中断(Interruption)也称外中断,是指来自CPU执行指令外部的事件,通常用于信息输入/输出,如设备发出的I/O结束中断,表示设备输入/输出已经完成。时钟中断,表示一个固定的事件片已到,让处理机处理计时、启动定时运行的任务等。
异常(Exception)也称中断,是指来自CPU执行指令内部的事件,如程序的非法操作码、地址越界、运算溢出、虚存系统的缺页以及专门的陷入指令等引起的事件。异常不能被屏蔽,一旦出现,就应立即处理。故障通常是指由指令执行引起的异常,如非法操作码、缺页故障、除数为运算溢出等。自陷是一种事先安排的“异常”,用于在用户态下调用操作系统内核程序,如条件陷阱指令。终止是指出现了使得CPU无法继续执行的硬件故障,如控制器出错、存储器校验等。

系统调用
根据进程访问资源的特点,我们可以把进程在系统上运行分为两个级别:
1.用户态:用户态运行的进程可以直接读取用户程序的数据。
2.系统态:可以简单的理解系统运行的进程和程序几乎可以访问计算机的任何资源,不受限制。
系统调用按功能大致可以分为下面几类:
1.设备管理:完成设备的请求或释放,以及设备启动等功能。
2.文件管理:完成文件的读、写、创建及删除等功能。
3.进程控制:完成进程的创建、撤销、阻塞及唤醒等功能。
4.进程通信:完成进程之间的消息传递或信号传递等功能
5.内存管理:完成内存的分配、回收以及获取作业占用内存区大小及地址。
进程和线程
进程间的通信方式
1.管道/匿名管道(Pipes):用于具有亲缘关系的父子进程或者兄弟进程之间的通信。
2.消息队列(Message):类似于链表的结构存储信息,存放在内存中并有消息队列标识符标识;它相比于管道,不止能传输字节流,也没有缓冲区大小的限制;消息队列允许一个或多个进程向它写入与读取消息;它实现了消息的随机读取;管道和消息队列的通信数据都是先进先出的原则。
3.内存共享(Shared memory):使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依赖某种同步操作,如互斥锁和信号量等。共享内存的整个通信过程对消息的复制只有两次 用户空间 到 内存 到 用户空间;管道,消息队列则需要四次 用户空间缓冲区 到 内核空间缓存区 到 内存中 内核空间缓冲区 到 用户空间缓存区。
4.信号(Signal):信号是进程通信机制中唯一的异步通知机制。
5.信号量(Semaphores):信号量是一个计数器,用于多进程对共享数据的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程不同线程之间的同步手段。PV操作
6.套接字(Sockets):此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持TCP/IP的网络通信的基本操作单元,可以看作是不同主机之间的进程进行双向通信的端点。简单的说就是通信双方的一种约定,用套接字中的相关函数完成通信过程。套接字也是一种进程间通信机制,与其他机制不同的是,它可以用于不同机器之间的进程通信(套接字=IP地址+端口号)。
协程
协程:协程是微线程,在子程序内部执行,可在子程序内部中断,转而执行别的子程序,在适当的时候再返回回来接着执行。
线程与协程的区别:
(1)协程执行效率高。协程直接操作栈基本没有内核栈切换的开销,所以上下文的切换非常快,切换的开销比线程更小。
(2)协程不需要多线程的锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率比线程高。
(3)一个线程可以有多个协程
为什么协程比线程切换的开销小?
(1)协程执行效率高。协程直接操作栈基本没有内核栈切换的开销,所以上下文的切换非常快,切换开销比线程更小。
(2)协程不需要多线程锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率比线程高。避免了加锁解锁的开销。
进程
进程切换为什么比线程更消耗资源
僵尸进程和孤儿进程
进程之间共享内存的通信方式有什么好处?
采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的缓存。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只需拷贝两次;一次从输入文件到共享内存区,另一次从共享内存区到输出文件。
进程的调度算法有哪些?
IO多路复用
IO 多路复用是一种同步 IO 模型,实现一个线程可以监视多个文件句柄。一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出 cpu。IO 是指网络 IO,多路指多个TCP连接(即 socket 或者 channel),复用指复用一个或几个线程。
意思说一个或一组线程处理多个 TCP 连接。最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程。IO 多路复用的三种实现方式:select、poll、epoll。
锁
乐观锁与悲观锁
一个共享数据加了悲观锁,那线程每次想操作这个数据前都会假设其他线程也可能会操作这个数据,所以每次操作前都会上锁,这样其他线程想操作这个数据拿不到锁只能阻塞了。

在 Java 语言中 synchronized 和 ReentrantLock等就是典型的悲观锁,还有一些使用了 synchronized 关键字的容器类如 HashTable 等也是悲观锁的应用。
乐观锁操作数据时不会上锁,在更新的时候会判断一下在此期间是否有其他线程去更新这个数据。

乐观锁可以使用版本号机制和CAS算法实现。在 Java 语言中 java.util.concurrent.atomic包下的原子类就是使用CAS 乐观锁实现的。
独占锁和共享锁
独占锁:是指锁一次只能被一个线程所持有。如果一个线程对数据加上排他锁后,那么其他线程不能再对该数据加任何类型的锁。获得独占锁的线程即能读数据又能修改数据。
JDK中的synchronized和java.util.concurrent(JUC)包中Lock的实现类就是独占锁。
共享锁:是指锁可被多个线程所持有。如果一个线程对数据加上共享锁后,那么其他线程只能对数据再加共享锁,不能加独占锁。获得共享锁的线程只能读数据,不能修改数据。
在 JDK 中 ReentrantReadWriteLock 就是一种共享锁。
互斥锁和读写锁
互斥锁是独占锁的一种常规实现,是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。
互斥锁一次只能一个线程拥有互斥锁,其他线程只有等待。
读写锁是共享锁的一种具体实现。读写锁管理一组锁,一个是只读的锁,一个是写锁。
读锁可以在没有写锁的时候被多个线程同时持有,而写锁是独占的。写锁的优先级要高于读锁,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。
读写锁相比于互斥锁并发程度更高,每次只有一个写线程,但是同时可以有多个线程并发读。
公平锁与非公平锁
公平锁是指多个线程按照申请锁的顺序来获取锁,这里类似排队买票,先来的人先买,后来的人在队尾排着,这是公平的。
非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发环境下,有可能造成优先级翻转,或者饥饿的状态(某个线程一直得不到锁)。
可重入锁
可重入锁又称之为递归锁,是指同一个线程在外层方法获取了锁,在进入内层方法会自动获取锁。

对于Java ReentrantLock而言, 他的名字就可以看出是一个可重入锁。对于Synchronized而言,也是一个可重入锁。
敲黑板:可重入锁的一个好处是可一定程度避免死锁。
自旋锁
自旋锁是指线程在没有获得锁时不是被直接挂起,而是执行一个忙循环,这个忙循环就是所谓的自旋。

自旋锁的目的是为了减少线程被挂起的几率,因为线程的挂起和唤醒也都是耗资源的操作。
如果锁被另一个线程占用的时间比较长,即使自旋了之后当前线程还是会被挂起,忙循环就会变成浪费系统资源的操作,反而降低了整体性能。因此自旋锁是不适应锁占用时间长的并发情况的。
分段锁
分段锁 是一种锁的设计,并不是具体的一种锁。
分段锁设计目的是将锁的粒度进一步细化,当操作不需要更新整个数组的时候,就仅仅针对数组中的一项进行加锁操作。

在 Java 语言中 CurrentHashMap 底层就用了分段锁,使用Segment,就可以进行并发使用了。
锁升级
JDK1.6 为了提升性能减少获得锁和释放锁所带来的消耗,引入了4种锁的状态:无锁、偏向锁、轻量级锁和重量级锁,它会随着多线程的竞争情况逐渐升级,但不能降级。
无锁
无锁状态其实就是上面讲的乐观锁,这里不再赘述。
偏向锁
Java偏向锁(Biased Locking)是指它会偏向于第一个访问锁的线程,如果在运行过程中,只有一个线程访问加锁的资源,不存在多线程竞争的情况,那么线程是不需要重复获取锁的,这种情况下,就会给线程加一个偏向锁。
偏向锁的实现是通过控制对象Mark Word的标志位来实现的,如果当前是可偏向状态,需要进一步判断对象头存储的线程 ID 是否与当前线程 ID 一致,如果一致直接进入。
轻量级锁
当线程竞争变得比较激烈时,偏向锁就会升级为轻量级锁,轻量级锁认为虽然竞争是存在的,但是理想情况下竞争的程度很低,通过自旋方式等待上一个线程释放锁。
重量级锁
如果线程并发进一步加剧,线程的自旋超过了一定次数,或者一个线程持有锁,一个线程在自旋,又来了第三个线程访问时(反正就是竞争继续加大了),轻量级锁就会膨胀为重量级锁,重量级锁会使除了此时拥有锁的线程以外的线程都阻塞。
升级到重量级锁其实就是互斥锁了,一个线程拿到锁,其余线程都会处于阻塞等待状态。
在 Java 中,synchronized 关键字内部实现原理就是锁升级的过程:无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁。。
锁粗化就是将多个同步块的数量减少,并将单个同步块的作用范围扩大,本质上就是将多次上锁、解锁的请求合并为一次同步请求。
锁消除是指虚拟机编译器在运行时检测到了共享数据没有竞争的锁,从而将这些锁进行消除。
什么情况下会产生死锁?
死锁处理策略
(1)死锁预防。设置某些限制条件,破坏产生死锁的4个必要条件之一或几个。
(2)死锁避免。死锁避免同样属于事先预防策略,但并不是事先采取某种限制措施破坏死锁的必要条件,而是在资源动态分配过程中,防止系统进入不安全状态,以避免发生死锁。这种方法所施加的限制较弱,可以获得较好的系统性能。1.系统安全状态,允许进程动态地申请资源,但系统在进行资源分配前,应先计算此次分配的安全性。若此次分配不会导致系统进入不安全状态,则允许分配;否则等待。2.银行家算法,进程运行前先声明对各种资源的最大需求量,当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过进程声明的最大需求量。已经拥有的+需要的 <= 还剩可分配的
(3)死锁的检测以及解除。无须采取任何限制性措施,允许进程在运行过程中发生死锁。通过系统的检测机构以及及时检测出死锁的发生,然后采取某种措施解除死锁。

死锁与饥饿的区别
1.进入饥饿状态的进程可以只有一个,而因循环等待条件而进入死锁状态的进程至少有2个
2.发生饥饿的进程的状态可能是就绪态(长期得不到处理机),也可能是阻塞态(长期得不到IO设备),而发生死锁的进程的状态则必定是阻塞态。
操作系统的地址有几种
物理地址:
在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单位给唯一一个的存储器地址,成为物理地址,又称为实际地址或绝对地址。
缓存溢出
缓存溢出是指输入到一个缓冲区或者数据保存区域的数据量超过了其容量,从而导致覆盖了其他区域数据的情况。
攻击者造成并利用这种情况使系统崩溃或者通过特质的代码来控制系统。
被覆盖的区域可能存在其他程序的变量、参数、类似于返回地址或指向前一个栈帧的指针等程序控制流数据,缓冲区可以位于堆、栈或者进程的数据段。
内存和缓存的区别
内存和缓存时计算机不同的组成部件。
内存:内存也被称为内存储器,其作用时用于暂时存放CPU的运算数据,以及与硬盘等外部存储交换的数据。只要计算机在运行中,CPU就会把需要进行运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。
缓存:CPU芯片面积和成本的因素影响,决定了缓存都很小。现在一般的缓存不过几M,CPU缓存的运行频率极高,一般是和处理器同频运作,工作效率远远大于系统内存和硬盘。实际工作时,CPU往往需要重复读取同样的数据块,而缓存容量的增大,可以大幅提升CPU内部读取数据的命中频率,而不用再到内存或者硬盘上寻找,以此提高系统性能。
硬链接和软链接
区别:
(1)软连接可以为文件和目录创建链接;硬链接只能为文件创建链接;
(2)软连接可以跨文件系统;硬链接必须是同一个文件系统
(3)硬链接因为只是文件的一个别名,所以不重复占用内存;软链接因为只是一个访问文件的快捷方式文件,文件只包含快捷指向信息,所以占用内存很小;
(4)软链接的文件权限和源文件可以不一样;硬链接文件权限是一样的,因为他们本来就是一个文件的不同名称而已。
1.不同点:源文件删除,硬链接的文件不受影响,软链接文件失效
2.相同点:源文件更改,硬链接的文件和软链接的文件同时变化

浙公网安备 33010602011771号