zoukankan      html  css  js  c++  java
  • 操作系统面试常见

    那么什么称为僵尸进程呢?

    即子进程先于父进程退出后,子进程的PCB需要其父进程释放,但是父进程并没有释放子进程的PCB,这样的子进程就称为僵尸进程,僵尸进程实际上是一个已经死掉的进程。

    孤儿进程

    一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

    子进程死亡需要父进程来处理,那么意味着正常的进程应该是子进程先于父进程死亡。当父进程先于子进程死亡时,子进程死亡时没父进程处理,这个死亡的子进程就是孤儿进程。

    但孤儿进程与僵尸进程不同的是,由于父进程已经死亡,系统会帮助父进程回收处理孤儿进程。所以孤儿进程实际上是不占用资源的,因为它终究是被系统回收了。不会像僵尸进程那样占用ID,损害运行系统。

    作业调度:

    先来先服务

    短作业优先

    优先级调度算法 高响应比优先调度算法

    轮转调度算法RR

    多级优先队列调度算法

    最低松弛度调度算法 : 必须完成时间-本身运行时间-当前时间

    避免死锁:

    银行家算法 利用 可利用资源向了 最大需求矩阵 分配矩阵 和 需求矩阵

     

    程序编译后进行链接的方式:

    1.静态链接 一次将所需模块全部链接完成

    2.装入时动态链接 边装入内存边链接

    3.运行时动态链接,其他模块不提前装入内存,需要的时候再去调用

    软链接和硬链接

    https://www.jianshu.com/p/dde6a01c4094

    硬链接是指针,所有的硬链接都是指向同一个磁盘块。 删除一个指针不会真正删除文件,只有把所有的指针都删除才会真正删除文件。 软连接是另外一种类型的文件,保存的是它指向文件的全路径, 访问时会替换成绝对路径

    内存分配:

    但以理按需分配 分为系统区和用户去

    固定分区分配

    动态分区分配:根据进程需要动态分配

    1. 首次适应FF算法 找第一个能装下的

    2. 循环首次适应算法 找满足的最小块

    3. 最佳适应 找正合适的

    4. 最坏适应 在空闲链中找内存块最大的

    基于索引的分配;

    1. 快速适应算法

    2. 伙伴系统

    3. 哈希算法

    内存的内外零头

    在存储管理中,内零头是指分配给作业的存储空间中未被利用的部分,外零头是指系统中无法利用的小存储块。 在固定式分区分配中,为将一个用户作业装入内存,内存分配程序从系统分区表中找出一个能满足作业要求的空闲分区分配给作业,由于一个作业的大小并不一定与分区大小相等,因此,分区中有一部分存储空间浪费掉了。由此可知,固定式分区分配中存在内零头。 在可变式分区分配中,为把一个作业装入内存,应按照一定的分配算法从系统中找出一个能满足作业需求的空闲分区分配给作业,如果这个空闲分区的容量比作业申请的空间容量要大,则将该分区一分为二,一部分分配给作业,剩下的部分仍然留作系统的空闲分区。由此可知,可变式分区分配中存在外零头。 在页式虚拟存储系统中,用户作业的地址空间被划分成若干大小相等的页面,存储空间也分成也页大小相等的物理块,但一般情况下,作业的大小不可能都是物理块大小的整数倍,因此作业的最后一页中仍有部分空间被浪费掉了。由此可知,页式虚拟存储系统中存在内零头。

    在段式虚拟存储系统中,作业的地址空间由若干个逻辑分段组成,每段分配一个连续的内存区,但各段之间不要求连续,其内存的分配方式类似于动态分区分配。由此可知,段式虚拟存储系统中存在外零头。

    内存分段和分页的区别

    分页分段的内存管理

    https://www.cnblogs.com/felixfang/p/3420462.html

    分段和分页其实都是一种对地址的划分或者映射的方式。

    两者的区别主要有以下几点:

    a)页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要(也是对用户透明的)。段是信息的逻辑单位,它含有一组其意义相对完整的信息(比如数据段、代码段和堆栈段等)。分段的目的是为了能更好的满足用户的需要(用户也是可以使用的)。

    b)页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。

    c)分页的作业地址空间是一维的,即单一的线性空间,程序员只须利用一个记忆符(线性地址的16进制表示),即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名(比如数据段、代码段和堆栈段等),又需给出段内地址。

    d)页和段都有存储保护机制。但存取权限不同:段有读、写和执行三种权限;而页只有读和写两种权限。

    页面调度算法(或者说是虚拟内存的实现)

    虚拟内存使得应用程序认为它拥有连续的可用内存,这样一来,就在逻辑层面上扩大了内存容量。但是实际上,只是把比较常用的内存片段取出来了而已,还有部分资源是放在磁盘存储器上的。需要的时候再进行数据交换。

    调度方式有,分页式,段式,段页式。比较流行方式是段页式,他结合了前两者的优点,以页为单位替换,以段为单位使用。

    常见的替换替换算法有4种,随机算法,先进先出算法,LRU算法,最优算法。 比较常使用的是LRU算法,他在redis里也有使用,当redis的内存满了的时候就是使用LRU算法替换掉旧内存。

    因为虚拟存储技术,进程运行中需要的页面不在内存中 需要进行换入换出

    1. 最佳置换算法x 这只是用来衡量算法好坏的

    2. 先进先出置换算法FIFO

    3. 最少使用算法LFU

    4. 最近最久未使用LRU

    5. Clock置换算法

    image-20200411180929001

    image-20200411181017130

    乐观锁和悲观锁 1.乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将比较-替换这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。

    2.悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了

    synchronized是悲观锁,属于抢占式,会引起其他线程阻塞。

    volatile提供多线程共享变量可见性和禁止指令重排序优化

    CAS是基于冲突检测的乐观锁(非阻塞)

    • SELECT ... LOCK In SHARE MODE;

    • SELECT ... FOR UPDATE;

    进程调度算法

    1.先来先服务调度算法。

    2.短作业(进程)优先调度算法。

    3.优先权调度算法。

    4.高响应比优先调度算法。

     

    磁盘调度算法

    例:假定某磁盘共有200个柱面,编号为0-199,如果在为访问143号柱面的请求者服务后,当前正在为访问125号柱面的请求服务,同时有若干请求者在等待服务,它们每次要访问的柱面号为 86,147,91,177,94,150,102,175,130

    1、先来先服务算法(FCFS)First Come First Service

    这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。

    先来先服务 (125)86.147.91.177.94.150.102.175.130

    2、最短寻道时间优先算法(SSTF) Shortest Seek Time First

    该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。

    最短寻道时间优先(125)130.147.150.175.177.102.94.91.86

    3、扫描算法(SCAN)电梯调度

    扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。

    电梯调度(125)102.94.91.86.130.147.150.175.177

    4、循环扫描算法(CSCAN)

    循环扫描算法是对扫描算法的改进。如果对磁道的访问请求是均匀分布的,当磁头到达磁盘的一端,并反向运动时落在磁头之后的访问请求相对较少。这是由于这些磁道刚被处理,而磁盘另一端的请求密度相当高,且这些访问请求等待的时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。

    循环扫描 (125)130.147.150.175.177.86.91.94.102

    在Linux下产生新的进程的系统调用就是fork函数,

    五种I/O模型:

    1、阻塞I/O(read/write)

    2、非阻塞I/O(如recvfrom,进程会反复调用recvfron)

    3、I/O复用(select/poll)

    4、信号驱动I/O(发送信号调用信号处理函数)

    5、异步I/O:

    后台进程又称守护进程

    后台程序基本上不和用户交互,优先级别稍低

    前台的程序和用户交互,需要较高的响应速度,优先级别稍高

    LINUX后台进程也叫守护进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件

    前台进程就是用户使用的有控制终端的进程

    进程间通信

      管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用进程间的亲缘关系通常是指父子进程关系。

      命名管道(named pipe/FIFO):命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

      信号量(semophonre):信号量是一个计数器,可以用来控制多个进程队共享资源的访问。它常作为一个锁机制,防止某进程在访问共享资源时,其他进程也访问此资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

      消息队列(message queue):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

      信号(sinal):信号是一种比较复杂的通信方式,用于通知接受进程某个事件已经发生。

      共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的ipc通信方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往和其他通信方式如信号量,配合使用来实现进程间的同步和通信。

      套接字(socket):套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备间的进程通信。

      全双工管道:共享内存、信号量、消息队列、管道和命名管道只适用于本地进程间通信,套接字和全双工管道可用于远程通信,因此可用于网络编程。

      

    锁机制:包括互斥锁、条件变量、读写锁

        互斥锁:提供了以排他方式防止数据结构被并发修改的方法。

        读写锁:允许多个线程同时共享数据,而对写操作是互斥的。

        条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

      信号量机制(Semaphore):包括无名进程信号量和命名线程信号量

      信号机制(Signal):类似进程间的信号处理

    3.简述产生死锁的必要条件

    产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3)不剥夺条件:进程已获得的资源,在末使用完之前不能强行剥夺。 4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

     

    5.请描述多级反馈队列调度算法的调度机制

    1、进程在进入待调度的队列等待时,首先进入优先级最高的Q1等待。  

    2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。例如:Q1,Q2,Q3三个队列,只有在Q1中没有进程等待时才去调度Q2,同理,只有Q1,Q2都为空时才会去调度Q3。  

    3、对于同一个队列中的各个进程,按照时间片轮转法调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列,直至完成。  

    4、在低优先级的队列中的进程在运行时,又有新到达的作业,那么在运行完这个时间片后,CPU马上分配给新到达的作业(抢占式)。  

     

    2.进程有哪几种基本状态?简要描述进程基本状态之间转换的典型原因

    就绪 执行 阻塞

    img

    image-20200407150030045

     

  • 相关阅读:
    HDU 1863 畅通工程(Kruskal)
    HDU 1879 继续畅通工程(Kruskra)
    HDU 1102 Constructing Roads(Kruskal)
    POJ 3150 Cellular Automaton(矩阵快速幂)
    POJ 3070 Fibonacci(矩阵快速幂)
    ZOJ 1648 Circuit Board(计算几何)
    ZOJ 3498 Javabeans
    ZOJ 3490 String Successor(模拟)
    Java实现 LeetCode 749 隔离病毒(DFS嵌套)
    Java实现 LeetCode 749 隔离病毒(DFS嵌套)
  • 原文地址:https://www.cnblogs.com/handso/p/13729489.html
Copyright © 2011-2022 走看看