主要参考于这个博主https://blog.csdn.net/justloveyou_的一些文章,并根据自己的面试经验做了相关的补充。
操作系统
操作系统
操作系统的作用
- 存储管理:存储的分配与回收(为进程分配存储空间)、存储的保护(防止进程间互相干扰)、地址映射(进程的逻辑地址映射到物理地址)、存储扩充(覆盖、交换、虚拟存储)。
- 处理机调度:归结为对进程的管理,进程调度、进程控制、进程同步、进程通讯。
- 设备管理:缓冲管理、设备分配和回收、设备处理、设备独立性。
- 文件管理:文件存储空间管理、目录管理、文件读写和存取控制
- 用户接口:提供程序接口或者用户接口
操作系统的特点
- 虚拟:一个物理实体映射为多个逻辑对应物,分为空分复用(虚拟内存)和时分复用(分时系统)。
- 共享:资源可供内存中多个并发执行的进程共同使用。
- 并发:多个事件在同一时间间隔内发生。
- 异步:独立、不可预知的速度向前推进。
进程与线程
进程的特点
- 动态性
- 并发
- 独立
- 异步:独立
- 结构:实体(程序段,数据段,PCB)
线程上下文切换
巧妙地利用了时间片轮转的方式, CPU 给每个任务都服务一定的时间,然后把当前任务的状态保存 下来,在加载下一任务的状态后,继续服务下一任务,任务的状态保存及再加载, 这段过程就叫做 上下文切换。时间片轮转的方式使多个任务在同一颗 CPU 上执行变成了可能。
上下文:是指某一时间点 CPU 寄存器和程序计数器的内容。
PCB------“切换桢”:上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行切换,上下文切换过程中的信息是保存在进程控制块(PCB, process control block)中的。PCB 还经常被称 作“切换桢”(switchframe)。信息会一直保存到 CPU 的内存中,直到他们被再次使用。
上下文切换的活动:
1. 挂起一个进程,将这个进程在 CPU 中的状态(上下文)存储于内存中的某处。
2. 在内存中检索下一个进程的上下文并将其在 CPU 的寄存器中恢复。
3. 跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行),以恢复该进程在程序中。
守护、僵尸、孤儿进程的概念
- 守护进程:运行在后台的一种特殊进程,独立于控制终端并周期性地执行某些任务。
- 僵尸进程:如果一个进程已经终止了,但是其父进程还没有获取其状态,那么这个进程就称之为僵尸进程.僵尸进程还会消耗一定的系统资源,并且还保留一些概要信息供父进程查询子进程的状态可以提供父进程想要的信息.一旦父进程得到想要的信息,僵尸进程就会结束。//一个进程 使用fork创建 子进程,若子进程退出,而父进程没有wait/waitpid获取子进程的状态信息,那么子进程的进程描述符仍保存在系统中,这样的进程称为僵尸进程。
- 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,这些子进程称为孤儿进程。(孤儿进程将由 init 进程收养并对它们完成状态收集工作)
程序与进程的区别
- 静态概念;动态概念。
- 不可以并发;可以并发。
- 进程是竞争计算机系统资源的基本单位,而程序不会竞争计算机系统资源。
- 不同的进程可以包含同一程序。
进程与线程的区别
- 进程是对运行时程序的封装,是资源分配的基本单位,实现了操作系统的并发;线程是进程的子任务,是CPU调度的基本单位,实现了进程内的并发。
- 一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程存在。
- 进程在执行过程中拥有独立的内存单元和地址空间,而多个线程共享进程的内存。
- 进程都有独立的代码和数据空间(程序上下文),进程之间的切换会有比较大的开销,线程是轻量级进程,同一类线程共享代码和数据空间,都有自己的运行栈和程序计数器,线程之间切换的开销小。
- 一个进程死掉不会对其他进程造成影响,一个线程死掉,会导致线程占有的资源永远无法释放,从而影响其他线程的正常工作,
什么是协程
协程是属于线程的,没有线程的上下文切换消耗。协程的调度切换是用户(程序员)手动切换的,因此更加灵活,因此又叫用户空间线程.
进程之间通信的几种方式
- 管道(特殊的文件,有固定的读端和写端,存在内存中):具有亲缘关系的父子进程间的通信。
- 命名管道:允许无亲缘关系进程间的通信。
- 消息队列(消息的链接表,存放在内核中):消息的链接表,客服了信号量有限的缺点,一个读,一个写
- 共享内存(存储区):需要依靠同步操作。
- 信号量(计数器):进程之间或者同一进程的不同线程之间同步和互斥的手段。
- 信号:通知进程某个事件已经发生。
- 套接字:可用作网络中不同机器之间的进程间的通信
线程之间通信的几种方式
- 锁机制:互斥锁、条件变量、读写锁
- 信号量机制
- 信号机制
- 共享内存
线程同步的方式
- 临界区:任意时刻只允许一个线程对共享资源进行访问。只能同步同一进程的线程之间
- 互斥量:只有拥有互斥对象的线程才有访问公共资源的权限,互斥对象只有一个。实现跨进程同步。
- 信号量:允许多个线程在同一时刻访问同一资源,但限制了访问的最大线程数目。跨进程同步,但不能用于分布式操作系统,因为必须有公共内存。
- 信号:通知进程某个事件已经发生。跨进程同步。
进程同步的方法
- 原子操作
- 信号量机制
- 自旋锁
- 管程
- 会合
- 分布式系统
进程有几种状态
- 就绪:
- 运行
- 阻塞
线程的状态
- 新建
- 就绪
- 运行
- 阻塞
- 等待
- 限时等待
- 结束
死锁
死锁产生的条件
死锁是指每个进程持有某种资源而又等待其他进程释放它们现在保持的资源,在未改变这种状态之前都不能向前推进。
- 循环等待:若干进程之间形成一种头尾相接的环形等待资源关系
- 部分占有:一个进程必须占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有;
- 不可剥夺:进程不能被抢占,即资源只能被进程在完成任务后自愿释放
- 互斥:至少有一个资源必须属于非共享模式,即一次只能被一个进程使用;
预防死锁
只要确保死锁发生的四个必要条件中至少有一个不成立。
- 打破互斥条件:允许进程同时访问某些资源。
- 打破占有并等待条件:可以实行资源预先分配策略,进程在运行前一次性向系统申请它所需要的全部资源。
- 打破非抢占条件:允许进程强行从占有者哪里夺取某些资源。
- 打破循环等待条件:实行资源有序分配策略。
避免死锁
动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。
银行家算法。
检测死锁
资源分配图
解除死锁
- 撤销进程
- 剥夺资源
- 进程回退
处理器管理
进程调度策略
- 先来先服务(FIFS)
- 短作业优先
- 时间片轮转(针对进程)
- 优先级调度
- 多级队列(针对进程)
- 多级反馈队列(针对进程)
- 高响应比(只针对作业):响应比=(等待时间+要求服务时间)/要求服务
内存管理
分页和分段的区别
- 将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。没有内碎片但会产生外碎片。
- 将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧。没有外碎片但是会产生内碎片。
虚拟内存
并不是所有的页都必须在内存中才能运行程序。对于进程而言,逻辑上似乎有很大的内存空间,实际上其中一部分对应物理内存上的一块(称为帧,通常页和帧大小相等),还有一些没加载在内存中的对应在硬盘上
页面置换算法
- 最佳置换算法
- 先进先出(FIFO)
- 最近最少使用法(LRU)
- 最少使用(LFU)
- 最近未使用法(NRU)
- 时钟算法
颠簸/抖动现象
刚换出的页面马上又要换入内存;刚换入的页面马上就要换出内存;
程序执行的过程
- 编译:编译程序将源代码编译成若干个目标模块;
- 链接:将编译之后的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块。
- 装入:由装入程序将装入模块装入内存中运行。
动态链接和静态链接
静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时。
物理地址与逻辑地址
- 逻辑地址:编译后每个目标模块都是从0开始编号的(相对/逻辑地址),链接成一个完整的可执行目标文件时,也是对各模块构成统一的逻辑地址空间。
- 物理地址:内存中物理单元的集合;装入程序装入内存中,通过地址转换将逻辑地址转换成物理地址,成为重定位。
I/O管理
中断和轮询
1,轮询——效率低,等待时间很长,CPU利用率不高。它定时对各种设备轮流询问一遍有无处理要求。轮流询问之后,有要求的,则加以处理。能处理的输入输出设备的数量也是有一定限度的
2,中断——容易遗漏一些问题,CPU利用率高。程序中断通常简称中断,是指CPU在正常运行程序的过程中,由于预先安排或发生了各种随机的内部或外部事件,使CPU中断正在运行的程序,而转到为响应的服务程序去处理。
中断类型
- 硬件故障中断:硬件异常或者故障
- 程序性中断:程序执行错误:溢出、地址错等
- 外部中断:外部设备请求引起的中断,时钟中断、控制台中断
- 输入输出中断:外设或通道操作
I/O模型
1,阻塞IO:用户线程阻塞。
最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用 户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除 block 状态。
2,非阻塞IO/NIO:
当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦内核中的数据准备 好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。 所以事实上,在非阻塞 IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞 IO不会交出 CPU,而会一直占用 CPU。
3,多路复用IO模型(阻塞IO):
Java NIO 实际上就是多路复用 IO。在多路复用 IO模型中,会有一个线程(内核线程)不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真正调用实际的 IO 读写操作。
用select, poll, epoll监听多个io对象,当io对象有变化(有数据)的时候就通知用户进程。
4,信号驱动IO模型:
当用户线程发起一个 IO 请求操作,会给对应的 socket 注册一个信号函数,然后用户线程会继续执行,不阻塞,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用 IO 读写操作来进行实际的 IO 请求操作。
5,异步IO模型:
当用户线程发起 read 操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它受到一个 asynchronous read 之后, 它会立刻返回,说明 read 请求已经成功发起了,因此不会对用户线程产生任何 block。然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它 read 操作完成了。也就说用户线程完全不需要实际的整个 IO 操作是如何 进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示 IO 操作已经完成,可以直接 去使用数据了。
- BIO(阻塞IO):阻塞IO和非阻塞IO的区别在于发起IO请求是否阻塞
- NIO(非阻塞IO):
- AIO(异步IO):同步IO和异步IO的区别就在于处理IO请求是否阻塞
JAVA NIO
三大核心部分:Channel,Buffer,Selector
传统 IO 基于字节流和字符流进行操作,而 NIO 基于 Channel 和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区 中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开, 数据到达)。因此,单个线程可以监听多个数据通道。
- select方法:不断轮询去监听的socket,socket个数有限制,一般为1024个;
- poll实现方法:采用轮询方式监听,只不过没有个数限制;
- epoll实现方法:并不是采用轮询方式去监听了,而是当socket有变化时通过回调的方式主动告知用户进程。
NIO 和传统 IO 之间第一个最大的区别是,IO 是面向流的,NIO 是面向缓冲区的。
IO与NIO的区别
- IO是面向流的,NIO是面向缓冲的
- IO是阻塞的,NIO是非阻塞的
- IO是单线程的,NIO通过选择器来模拟多线程(一个线程 Thread 使用一个选择器 Selector 通过轮询的方式去监听多个通道 Channel 上的事件,从而让一个线程就可以处理多个事件。)
Select,poll,epoll的区别
- Select:On,无差别轮询,对socket进行线性扫描
- Poll:On,没有最大连接数的限制,基于链表存储;
- Epoll:O1,虽然连接数有上限,但是很大,只有活跃的socket才会主动调用callback。
磁盘调度
对于磁盘,访问时间包括两个主要部分:
- 寻道时间:是磁臂移动磁头到包含目标扇区的柱面的时间;
- 旋转延迟:是磁盘旋转目标扇区到磁头下的额外时间;
- 先来先服务:简单,时间长
- 最短寻道时间:平均寻道长度会大大减少,缺点是距离初始磁头较远的服务长期得不到处理,产生“饥饿”现象。
- 扫描算法(电梯调度算法):先向内扫描,再向外扫描。
- 循环扫描算法:磁头单向移动。扫描方向一致。
- N-STEP扫描:多个队列
- FSCAN:两个队列
Linux
Linux中常用到的命令
显示文件目录命令ls 如ls
改变当前目录命令cd 如cd /home
建立子目录mkdir 如mkdir xiong
删除子目录命令rmdir 如rmdir /mnt/cdrom
删除文件命令rm 如rm /ucdos.bat
文件复制命令cp 如cp /ucdos /fox
获取帮助信息命令man 如man ls
显示文件的内容less 如less mwm.lx
Linux文件属性有哪些
第一个字段的第一位是文件类型标识符:-表示普通文件;c表示字符设备(character);b表示块设备(block);d表示目录(directory);l表示链接文件(link);
后面第一个三个连续的短横是用户权限位(User),第二个三个连续短横是组权限位(Group),第三个三个连续短横是其他权限位(Other)。
每个权限位有三个权限,r(读权限,4),w(写权限,2),x(执行权限,1)。
权限的设定可以用chmod命令
chmod u+rw aaa(给用户权限位设置读写权限,其权限表示为:- rw- --- ---)
chmod g+r aaa(给组设置权限为可读,其权限表示为:- --- r-- ---)
chmod ugo+rw aaa(给用户,组,其它用户或组设置权限为读写,权限表示为:- rw- rw- rw-)
chmod u-x aaa(去掉用户可执行权限,权限表示为:- rw- rwx rwx)
如果要给aaa赋予制定权限- rwx r-x r-x,命令为:
chmod u=rwx,go=rx aaa