【33】C++岗位求职面试八股文第三十三篇(操作系统)

系列文章目录

第一篇:语言基础

第二篇:设计模式

第三篇:数据库

第四篇:计算机网络

第五篇:操作系统

第六篇:LInux

第七篇:数据结构

第八篇:智力题

[61] 一个线程占多大内存?

一个linux的线程大概占8M内存。

[62]UTF-8编码占几个字节:中文3英文1数字1

一个中文字符等于三个字节,一个中文标点符号占三个字节;一个英文字符等于一个字节,一个英文标点占一个字节;一个数字符号等于一个字节。

[63]“linux的默认编码是“UTF-8”

命令:locale磁盘utf8,内存unicode

[64]服务器正在创建线程时候能够处理新来的连接吗

可以,一个进程用来创建线程,主进程用来处理新的连接诶

[65]什么是页表,为什么要有?

页表是虚拟内存的概念。操作系统虚拟内存到物理内存的映射表,就被称为页表。不可能每一个虚拟内存的 Byte 都对应到物理内存的地址。这张表将大得真正的物理地址也放不下,于是操作系统引入了页(Page)的概念。进行分页,每页4kb,这样可以减小虚拟内存页对应物理内存页的映射表大小。

⻚表的作⽤:是内存⾮连续分区分配的基础,实现从逻辑地址转化成物理地址⻚表实际上就是进程的虚存空间与系统中的物理存储空间的⼀个映射关系在⻚式管理中,⻚表的作⽤是实现从⻚号到物理块号的地址映射,存储⻚表的作⽤是记录内存 ⻚⾯的分配情况

[66]虚拟内存到物理内存的寻址⽅式

CPU通过虚拟地址来访问主存,访问内存使⽤的物理地址,MMU通过将虚拟地址进⾏翻译, 转化为物理地址,然后再⽤这个物理地址去访问内存数据。

[67]简述操作系统中的缺页中断

1.缺页异常:malloc和mmap函数在分配内存时只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,引发缺页中断。

2.缺页中断:缺页异常后将产生一个缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。

缺页中断与一般中断区别:(1)在指令执行期间产生和处理缺页中断信号,另一个是某一指令执行完(2)一条指令在执行期间,可能产生多次缺页中断(3)缺页中断返回的是执行产生中断的一条指令,而一般中断返回的是执行下一条指令。(因为一般中断是在执行完此条指令才中断,所以返回的是下一条中断·)(因为缺页中断是在执行此条指令过程中中断,所以返回的是此条中断·)

[68]什么时候会由用户态陷入内核态?

用户空间:(1)代码段.text:存放程序执行代码的一块内存区域。只读,代码段的头部还会包含一些只读的常数变量。(2)数据段.data:存放程序中已初始化的全局变量和静态变量的一块内存区域。(3)BSS 段.bss:存放程序中未初始化的全局变量和静态变量的一块内存区域。(4)可执行程序在运行时又会多出两个区域:堆区和栈区。堆区:动态申请内存用。堆从低地址向高地址增长。栈区:存储局部变量、函数参数值。栈从高地址向低地址增长。是一块连续的空间。(5)最后还有一个文件映射区,位于堆和栈之间。内核空间:DMA区、常规区、高位区。

  1. 什么时候进入内核态:共有三种方式:a、系统调用。b、异常。c、设备中断。其中,系统调用是主动的,另外两种是被动的。

为什么要用虚拟内存:因为早期的内存分配方法存在以下问题:(1)进程地址空间不隔离。会导致数据被随意修改。(2)内存使用效率低。(3)程序运行的地址不确定。操作系统随机为进程分配内存空间,所以程序运行的地址是不确定的。

使用虚拟内存的好处:(1)扩大地址空间。每个进程独占一个4G空间,虽然真实物理内存没那么多。(2)内存保护:防止不同进程对物理内存的争夺和践踏,可以对特定内存地址提供写保护,防止恶意篡改。(3)可以实现内存共享,方便进程通信。(4)可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。使用虚拟内存的缺点:(1)虚拟内存需要额外构建数据结构,占用空间。(2)虚拟地址到物理地址的转换,增加了执行时间。(3)页面换入换出耗时(4)一页如果只有一部分数据,浪费内存。

[69]虚拟地址到物理地址怎么映射的?

操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表。页表中的每一项都记录了这个页的基地址

页表中,每个条目由4个字节组成,每页4kb大小页目录索引、页表索引、页内偏移页表地址 页地址 物理地址

[70]堆栈溢出是什么,会怎么样?

堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界。常指调用堆栈溢出,本质上一种数据结构的满溢情况。堆栈溢出可以理解为两个方面:堆溢出和栈溢出。

堆溢出:比如不断的new 一个对象,一直创建新的对象,而不进行释放,最终导致内存不足。将会报错:OutOfMemory Error。

栈溢出:一次函数调用中,栈中将被依次压入:参数,返回地址等,而方法如果递归比较深或进去死循环,就会导致栈溢出。将会报错:StackOverflow Error。

[71]Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)

链接Linux进程状态:R (TASK_RUNNING),可执行状态。Linux进程状态:S (TASK_INTERRUPTIBLE),可中断的睡眠状态Linux进程状态:D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。

[72]进程五个状态

[73]操作系统中malloc的实现原理

malloc底层实现:当开辟的空间小于 128K 时,调用 brk()函数;当开辟的空间大于 128K 时,调用mmap()。

Malloc在虚拟内存的堆中分配一块大小,但是并没有映射到物理内存,使用时产生缺页异常,触发缺页中断,操作系统内核再从物理内存匹配一块地址进行映射。

malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲快。采用隐式链表将所有空闲块,每一个空闲块记录了一个未分配的、连续的内存地址。

[74]32位系统能访问4GB以上的内存吗

正常情况下是不可以的。32位正好是2的32次方,正好是4G,所以大于4G就没办法表示了,而在32位的系统中,因其它原因还需要占用一部分空间,所以内存只能识别3G多。但是使用PAE技术就可以实现 32位系统能访问4GB以上的内存。PAE技术将地址扩展到了36位,这样,系统就能够容纳2^36=64GB的内存。

32位操作系统针对的32位的CPU设计。CPU的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推

普通家用版32位操作系统最大支持4GB内存,但是实际不可能完全用到4G的内存,一般在3.2g到3.5G左右,这是内存的总量,而应用程序只能使用2GB内存左右。

[75]并发和并行

1.并发:对于单个CPU,在一个时刻只有一个进程在运行,但是线程的切换时间则减少到纳秒数量级,多个任务不停来回快速切换。2.并行:对于多个CPU,多个进程同时运行。3.区别。通俗来讲,它们虽然都说是"多个进程同时运行",但是它们的"同时"不是一个概念。并行的"同时"是同一时刻可以多个任务在运行(处于running),并发的"同时"是经过不同线程快速切换,使得看上去多个任务同时都在运行的现象

多进程:操作系统中同时运行的多个程序。多线程:在同一个进程中同时运行的多个任务

[76]守护进程、僵尸进程和孤儿进程

守护进程:指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,周期性地执行某种任务。Linux的大多数服务器就是用守护进程的方式实现的,如web服务器进程http等

孤儿进程如果父进程先退出,子进程还没退出,那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)。一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

僵尸进程:如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸进程。这些信息至少包括进程ID,进程的终止状态,以及该进程使用的CPU时间(指的是在pcb块中的进程信息),所以当终止子进程的父进程调用wait或waitpid时就可以得到这些信息。如果一个进程终止,而该进程有子进程处于僵尸状态,那么它的所有僵尸子进程的父进程ID将被重置为1(init进程)。继承这些子进程的init进程将清理它们(也就是说init进程将wait它们,从而去除它们的僵尸状态)。

[77]如何避免僵尸进程?(存在于内核空间中的pcb控制信息)

1.通过signal(SIGCHLD, SIG_IGN)通知内核对子进程的结束不关心,由内核回收。2.父进程调用wait/waitpid等函数等待子进程结束,如果尚无子进程退出wait会导致父进程阻塞。waitpid可以通过传递WNOHANG使父进程不阻塞立即返回。

[78]说说进程、线程、协程是什么,区别是什么?

进程:程序是指令、数据及其组织形式的描述,而进程则是程序的运行实例,包括程序计数器、寄存器和变量的当前值。线程:微进程,一个进程里更小粒度的执行单元。一个进程里包含多个线程并发执行任务。协程:协程是微线程,在子程序内部执行,本质⽤户空间下的线程,拥有⾃⼰的寄存器上下⽂和栈;可在子程序内部中断,转而执行别的子程序,在适当的时候再返回来接着执行。线程与进程的区别:(1)一个线程从属于一个进程;一个进程可以包含多个线程。(2一个进程挂掉,不会影响其他进程。(3)进程是操作系统资源分配和调度的最小单位;线程CPU调度的最小单位。(4)进程系统开销显著大于线程开销;线程需要的系统资源更少。(5)进程在执行时拥有独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展段;但每个线程拥有自己的栈段和寄存器组。(6)进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈,线程切换时只需要切换硬件上下文和内核栈。(7)通信方式不一样。(8)进程适应于多核、多机分布;线程适用于多核

“多个线程共享同一个地址的内存地址,但是他有自己独立的线程空间。如果挂掉的线程在临死之前,修改了内存地址,导致地址失效或异常,那么他死后,其他线程去访问被他所修改的地址时,进程会崩溃。如果说挂掉的线程活着的时候,压根儿不会修改内存数据或地址,只是单纯的做些体力活。那么他死后,不会影响到当前进程

线程与协程的区别:协程无锁、执行效率高,基本不需要切换内核(1)协程执行效率极高。协程直接操作栈基本没有内核切换的开销,所以上下文的切换非常快,切换开销比线程更小。(2)协程不需要多线程的锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率比线程高。(3)一个线程可以有多个协程,处理大量IO时候性能较好。

[79]为什么引入协程?

(1) 节省 CPU避免系统内核级的线程频繁切换,造成的 CPU 资源浪费。⽽协程是⽤户态的线程,⽤户可以 ⾃⾏控制协程的创建于销毁,极⼤程度避免了系统级线程上下⽂切换造成的资源浪费。 (2)节约内存在 64 位的 Linux 中,⼀个线程需要分配 8MB 栈内存和 64MB 堆内存,系统内存的制约⽆法开启更多线程实现⾼并发。⽽在协程编程模式下,可以轻松有⼗⼏万协程,这是线程⽆法⽐拟的。(3)稳定性前⾯提到线程之间通过内存来共享数据,这也导致了⼀个问题,任何⼀个线程出错时,进程中的所有线程都会跟着⼀起崩溃。(4)开发效率协程因为存在于一个线程中,所以不存在写变量的冲突(非抢占式),没有锁机制。所以执行的效率比线程高很多,而协程只有三个寄存器的值修改,只涉及到简单的现场保存和恢复

线程要比进程更加轻量,创建一个线程要比创建一个进程快10 ~ 100倍,在切换的时候,由于进程是系统的多任务,涉及到从用户态切换到内核态,进程的切换会带来大量的内存开销导致缺页中断,需要读取硬盘并加载到内存中;线程需要调用操作系统内核,涉及到从用户态切换到内核态,多个寄存器的刷新操作;而协程只有三个寄存器的值修改,只涉及到简单的现场保存和恢复

[80]线程池是如何实现的

链接链接

[续]C++岗位求职面试八股文第三十四篇(操作系统)

更多关于算法题解、软件开发面经、机器学习算法面经、各企业面试问题记录,关注Fintech砖,持续更新中。https://www.nowcoder.com/users/873777317

企业面试记录专栏https://www.nowcoder.com/creation/manager/columnDetail/0YBWnm

机器学习面经专栏https://www.nowcoder.com/creation/manager/columnDetail/j8nNy0

软件开发面经专栏https://www.nowcoder.com/creation/manager/columnDetail/0aXKaM

更多校园招聘常见面试问题(开发、算法、编程题目)参见CSDN博客:http://t.csdn.cn/V4qbH

欢迎关注、收藏、点赞后进行问题咨询及秋招建议

#晒一晒我的offer##牛客解忧铺##牛客在线求职答疑中心##我的实习求职记录##软件开发薪资爆料#
软件开发八股面经 文章被收录于专栏

包含C++、操作系统、数据库、计算机组成、计算机网络、设计模式、操作系统、牛客网服务器项目、综合智力题等

全部评论

相关推荐

3 16 评论
分享
牛客网
牛客企业服务