操作系统面试题-6
常考面试题
简述GDB常见的调试命令,什么是条件断点,多进程下如何调试。⭐⭐⭐⭐
GDB调试:gdb调试的是可执行文件,在gcc编译时加入 -g ,告诉gcc在编译时加入调试信息,这样gdb才能调试这个被编译的文件 gcc -g tesst.c -o test
GDB命令格式:
quit:退出gdb,结束调试
list:查看程序源代码
list 5,10:显示5到10行的代码
list test.c:5, 10: 显示源文件5到10行的代码,在调试多个文件时使用
list get_sum: 显示get_sum函数周围的代码
list test,c get_sum: 显示源文件get_sum函数周围的代码,在调试多个文件时使用
reverse-search:字符串用来从当前行向前查找第一个匹配的字符串
run:程序开始执行
help list/all:查看帮助信息
break:设置断点
break 7:在第七行设置断点
break get_sum:以函数名设置断点
break 行号或者函数名 if 条件:以条件表达式设置断点
watch 条件表达式:条件表达式发生改变时程序就会停下来
next:继续执行下一条语句 ,会把函数当作一条语句执行
step:继续执行下一条语句,会跟踪进入函数,一次一条的执行函数内的代码
条件断点:break if 条件 以条件表达式设置断点
多进程下如何调试:用set follow-fork-mode child 调试子进程
或者set follow-fork-mode parent 调试父进程
说说进程调度算法有哪些?⭐⭐⭐⭐⭐
- 先来先服务调度算法
- 短作业(进程)优先调度算法
- 高优先级优先调度算法
- 时间片轮转法
- 多级反馈队列调度算法
简述LRU算法及其实现方式。⭐⭐⭐⭐⭐
LRU算法:LRU算法用于缓存淘汰。思路是将缓存中最近最少使用的对象删除掉
实现方式:利用链表和hashmap。
当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。
在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样一来在链表尾部的节点就是最近最久未访问的数据项。
代码实现
我们给出C++的具体实现,代码一看就懂了。
class LRUCache { list<pair<int, int>> cache;//创建双向链表 unordered_map<int, list<pair<int, int>>::iterator> map;//创建哈希表 int cap; public: LRUCache(int capacity) { cap = capacity; } int get(int key) { if (map.count(key) > 0){ auto temp = *map[key]; cache.erase(map[key]); map.erase(key); cache.push_front(temp);//把该节点移到链表头部 map[key] = cache.begin();//映射头部 return temp.second; } return -1; } void put(int key, int value) { if (map.count(key) > 0){ cache.erase(map[key]); map.erase(key); } else if (cap == cache.size()){//若缓存满了,则把链表最后一个节点删除 auto temp = cache.back(); map.erase(temp.first); cache.pop_back(); } cache.push_front(pair<int, int>(key, value));//新建一个节点,放到链表头部 map[key] = cache.begin();//映射头部 } }; /** Your LRUCache object will be instantiated and called as such: LRUCache* obj = new LRUCache(capacity); int param_1 = obj->get(key); obj->put(key,value); */
什么是页表,为什么要有?⭐⭐⭐⭐⭐
页表是虚拟内存的概念。操作系统虚拟内存到物理内存的映射表,就被称为页表。
原因:不可能每一个虚拟内存的 Byte 都对应到物理内存的地址。这张表将大得真正的物理地址也放不下,于是操作系统引入了页(Page)的概念。进行分页,这样可以减小虚拟内存页对应物理内存页的映射表大小。
我们举个形象的例子,就如同一本书,如果把整个书给摊开,那占地面积太大了,所以书才要分页,节约空间。
简述操作系统中的缺页中断。⭐⭐⭐⭐⭐
缺页异常:malloc和mmap函数在分配内存时只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,引发缺页中断。
缺页中断:缺页异常后将产生一个缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。
简述一下虚拟内存和物理内存,为什么要用虚拟内存,好处是什么?⭐⭐⭐⭐⭐
物理内存:物理内存有四个层次,分别是寄存器、高速缓存、主存、磁盘。
寄存器:速度最快、量少、价格贵。
高速缓存:次之。
主存:再次之。
磁盘:速度最慢、量多、价格便宜。
操作系统会对物理内存进行管理,有一个部分称为内存管理器(memory manager),它的主要工作是有效的管理内存,记录哪些内存是正在使用的,在进程需要时分配内存以及在进程完成时回收内存。
虚拟内存:操作系统为每一个进程分配一个独立的地址空间,却是虚拟内存。虚拟内存与物理内存存在映射关系,通过页表寻址完成虚拟地址和物理地址的转换。
为什么要用虚拟内存:因为早期的内存分配方法存在以下问题:
(1)进程地址空间不隔离。会导致数据被随意修改。
(2)内存使用效率低。
(3)程序运行的地址不确定。操作系统随机为进程分配内存空间,所以程序运行的地址是不确定的。
使用虚拟内存的好处:
(1)扩大地址空间。每个进程独占一个4G空间,虽然真实物理内存没那么多。
(2)内存保护:防止不同进程对物理内存的争夺和践踏,可以对特定内存地址提供写保护,防止恶意篡改。
(3)可以实现内存共享,方便进程通信。
(4)可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。
使用虚拟内存的缺点:
(1)虚拟内存需要额外构建
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
<p> - 本专刊适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专刊适合于互联网C++软件开发、嵌入式软件求职的学生或人士。 - 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构等一系列知识点的讲解,并且最后总结出了高频面试考点(附有答案)共近400道,知识点讲解全面。不仅如此,教程还讲解了简历制作、笔试面试准备、面试技巧等内容。 </p> <p> <br /> </p>