0%

面试精选

操作系统

操作系统是控制应用程序执行的程序,是应用程序和计算机硬件间的接口

  • 方便:操作系统使计算机更易于使用
  • 有效:操作系统允许以更有效地方式使用计算机系统资源
  • 扩展能力:在构造操作系统时,应允许在不妨碍服务的前提下,有效地开发、测试和引入新的系统功能

进程和线程

Q: 区别?
  • 「进程」 是操作系统资源分配的基本单位
  • 「线程」 是任务调度和执行的基本单位

在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。

包含关系:只有一个线程的进程可以看做是单进程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

以上参考

分时系统、多任务

Q: 五状态模型?
  • 「运行态」 进程正在执行
  • 「就绪态」 进程做好了准备,只要有机会就开始执行
  • 「阻塞/等待态」 进程在某些事件发生前不能执行,如 I/O 操作完成
  • 「新建态」 刚刚创建的进程,操作系统还未把它加入可执行进程组,它通常是进程控制块已经创建但还未加载到内存中的新进程
  • 「退出态」 操作系统从可执行进程组中释放出的进程,要么它自己已停止,要么它因某种原因被取消
Q: 并发技术?
  • 「原子操作」 一个函数或动作由一个或多个指令的序列实现,对外不可见
  • 「临界区」 一段代码,在这段代码中进程将访问共享资源,当另外一个进程已在这段代码中运行时,这个进程就不能在这段代码中执行
  • 「互斥」 当一个进程在临界区访问共享资源时,其他进程不能进入该临界区访问任何共享资源的情形
  • 「死锁」 两个或两个以上的进程因每个进程都在等待其他进程做完某些事情而不能继续执行的情形
  • 「活锁」 两个或两个以上的进程为响应其他进程中的变化而持续改变自己的状态但不能做有用的工作的情形
  • 「竞争条件」 多个线程或进程在读写一个共享数据时,结果依赖于它们执行的相对时间的情形
  • 「饥饿」 一个可运行的进程尽管能继续执行,但被调度程序无限期地忽视,而不能被调度执行的情形

一文看懂临界区、互斥锁、同步锁、临界区、信号量、自旋锁等名词

在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有资源或仅仅占有一点必须资源)。但对于某些资源来说,其在同一时间只能被一个进程所占用。这些一次只能被一个进程所占用的资源就是所谓的临界资源。

对于临界资源的访问,必须是互斥进行。也就是当临界资源被占用时,另一个申请临界资源的进程会被阻塞,直到其所申请的临界资源被释放。而进程内访问临界资源的代码被成为临界区。

  • 「信号量」 把互斥锁推广到”N”的空间,同时允许有N个线程进入临界区的锁叫“信号量”。互斥量和信号量的实现都依赖TSL指令保证“检查-占锁”动作的原子性。

  • 「信号量」 用于进程间传递信号的一个整数值。在信号量上只可进行三种操作:初始化,递减和增加,这三种操作都是原子操作。递减阻塞进程,递增解除进程阻塞。

  • 「二元信号量」 只取 0 和 1 的信号量

  • 「管程」 把互斥量交给程序员使用太危险,有些编程语言实现了“管程”的特性,从编译器的层面保证了临界区的互斥,比如Java的synchronized关键字。

  • 「管程」 是由一种程序设计语言结构,它提供的功能与信号量相同,但更易于控制。

  • 「事件」 对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。

Q: 互斥锁?自旋锁?

对于互斥锁来说,如果一个线程已经锁定了一个互斥锁,第二个线程又试图去获得这个互斥锁,则第二个线程将被挂起(即休眠,不占用 CPU 资源)。

在计算机系统中,频繁的挂起和切换线程,也是有成本的。自旋锁就是解决这个问题的。

自旋锁,指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

容易看出,当资源等待的时间较长,用互斥锁让线程休眠,会消耗更少的资源。当资源等待的时间较短时,使用自旋锁将减少线程的切换,获得更高的性能。

Q: 重入锁?不可重入锁?

可重入锁(ReetrantLock),也叫做递归锁,指的是在同一线程内,外层函数获得锁之后,内层递归函数仍然可以获取到该锁。换一种说法:同一个线程再次进入同步代码时,可以使用自己已获取到的锁。

使用可重入锁时,在同一线程中多次获取锁,不会导致死锁。使用不可重入锁,则会导致死锁发生。

参考

Q: 死锁的条件?
  • 「互斥」 一次只有一个进程可以使用一个资源。其他进程不能访问已分配给其他进程的资源。
  • 「占有且等待」 当一个进程等待其他进程时,继续占有已分配的资源
  • 「不可抢占」 不能强行抢占进程已占有的资源
  • 「循环等待」 存在一个闭合的进程链,每个进程至少占有此链中下一个进程所需的一个资源
Q: 进程间通信?
  • 「管道」 命名管道和匿名管道,只有具有“血缘”关系的进程才可共享匿名管道,而不相关的进程只能共享命名管道
  • 「消息」 是有类型的一段文本。每个进程都有一个与之相关联的消息队列,其功能类似于信箱
  • 「共享内存」 是 UNIX 所提供的进程间通信手段中速度最快的一种。虚存中由多个进程共享的一个公共内存块。