iOS开发进阶iOS精品文章iOS面试

操作系统与编译面试题

2018-03-12  本文已影响102人  果哥爸

主要参考:
《程序员的自我修养》读书总结
编译与链接过程的思考
linux 下动态链接实现原理
研读《程序员的自我修养—链接、装载与库》
程序的静态链接,动态链接和装载

1. 源代码是怎么变成可执行文件的,每一步的作用是什么?(预编译,词法分析,语法分析,语义分析,中间语言生成目标代码生成,汇编,链接)

解答:
源代码变成可执行文件需要经历 4个大步骤:
预处理——>编译——>汇编——>链接

编译流程图.png

引用自:编译与链接过程的思考

1. 预处理:

“预编译器”负责,负责将:

2. 编译

由编译器负责,主要又由词法分析、语法分析、语义分析、优化生成汇编代码五个部分:

3. 汇编

汇编器将汇编语言转换成机器可以执行的语言(完全由01组成).汇编文件经过汇编,变成目标文件,后缀为.o

4.链接
通过调用链接器ld来将多个目标文件以及所依赖的其它库文件链接起来,最后生成可执行文件。

考虑一个.c文件中,用到了另一个.c文件中的变量或函数。在编译这个文件时,我们无法在编译期确定这个变量或函数的地址。只有在把所有目标文件链接起来以后,才能确定。链接器主要负责地址重分配、符号名称绑定和重定位。

2. 应用层、API、运行库、系统调用、操作系统内核之间的关系是什么?

关系图.png

引用自《程序员的自我修养》读书总结

计算机调用结构:

3. 虚拟内存空间是什么,为什么要有虚拟内存空间。

虚拟地址空间:是指应用程序自己认为,自己所处的地址空间。它区别于物理地址空间。后者是真实存在的,比如电脑有一根8G的内存条,物理地址空间就是0~8GbCPUMMU(内存管理单元)负责把虚拟地址转换成物理地址。

引入虚拟地址的好处:

4. 静态链接和动态链接分别表示什么,大概是怎么实现的?

静态链接:

是指链接阶段将多个目标文件和相关的静态库组合在一起形成一个可执行文件。

静态链接包括两个大部分:一是空间和地址的分配;二是符号解析和重定位

扫描所有的输入目标文件,获得他们的各个段的长度、属性和位置,并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来,统一放到一个全局符号表。这样,连接器将能够获得所有输入目标文件的段长度,并且将它们合并,计算出输出文件中各个段合并后的长度与位置,并建立映射关系。

空间和地址分配.png

备注:映射关系就是指可执行文件与进程虚拟地址空间之间的映射。那么,这里程序还没有执行,更不会出现进程,哪里来的进程地址空间呢?此时虚拟存储器便发挥了很大的作用:虽然此时没有进程,但是每个进程的虚拟地址空间的格式都是一致的。所以,为可执行文件的每个段甚至每个符号符号分配地址也就不会有什么错了

符号解析:解析符号就是将每个符号引用与它输入的可重定位目标文件中的符号表中的一个确定的符号定义联系起来。若找不到,则出现编译时错误。

重定位:根据目标文件的重定位入口所修正的指令寻址方式,进行正确的寻址。

动态链接

是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。

动态链接基本分为三步:先是启动动态链接器本身,然后装载所有需要的共享对象,最后重定位和初始化

5. 可执行文件的结构如何?(分为哪些段)

可执行文件的结构.png

(备注:可执行文件中有多个Segment,从装载的角度,我们目前只关心两个“Load”类型的Segment,因为只有它是需要被映射的,其他的诸如“NOTE”、“TLS”、“GNU_STACK”都是在装载时起辅助作用的)

6. 可执行文件是怎么装载进内存的,为什么要分段,分页,页错误是什么?

1). 可执行文件的装载:

-【将CPU指令寄存器设置成可执行文件的入口,启动运行】对动态链接来讲,此时就启动了动态链接器。

2). 为什么要分段、分页

-分段式存储管理就是用户可以把进程按逻辑关系划分为若干个大小不等段,每个段都是从0开始编址,定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相连接,也实现离散分配

打个比方,比如说你去听课,带了一个纸质笔记本做笔记。笔记本有100张纸,课程有语文、数学、英语三门,对于这个笔记本的使用,为了便于以后复习方便,你可以有两种选择。

  • 第一种是,你从本子的第一张纸开始用,并且事先在本子上做划分:第2张第30张纸记语文笔记,第31到60张纸记数学笔记,第61到100张纸记英语笔记,最后在第一张纸做个列表,记录着三门笔记各自的范围。这就是分段管理第一张纸段表
  • 第二种是,你从第二张纸开始做笔记,各种课的笔记是连在一起的:第2张纸是数学,第3张是语文,第4张英语……最后呢,你在第一张纸做了一个目录,记录着语文笔记在第3、7、14、15张纸……,数学笔记第2、6、8、9、11……英语笔记在第4、5、12……。这就是分页管理第一张纸叫页表。你要复习哪一门课,就到页表里查寻相关的纸的编号,然后翻到那一页去复习

3)页错误是什么
页错误又叫页缺失,在引入分页机制的操作系统中,一个进程的代码和数据被放置在一个虚拟的地址空间中,地址空间按固定长度划分为好多页。同时,物理内存也按固定长度划分为好多帧,因为物理内存小硬盘空间大,为了在内存里放置更多的进程,操作系统的设计者决定把页映射内存帧或硬盘的虚拟内存文件中。
进程的可视范围是它自己的地址空间,它并不知道某一页映射到内存里还是硬盘上,进程只管自己运行。当进程需要访问某一页时,操作系统通过查看分页表,得知被请求的页在内存里还是硬盘里。若在内存里,则进行地址翻译;若在硬盘里,则发生页缺失。操作系统立即阻塞该进程,将硬盘里对应的页换入内存,然后使该进程就绪(可以继续运行)。

7. 进程的内存格局是怎样的?(堆、栈、全局/静态区,代码区,常量区)

进程的内存格局.png

8. 堆和栈的区别,函数调用和栈的关系

1)堆和栈的区别:

a.申请方式:
-: 由系统自动分配, 例如,在函数中声明一个局部变量 int b; 系统自动在栈中为b开辟空间 。

注意:p1和p2本身是在栈中的

b.申请后系统的响应:

c.申请大小限制:
栈:在Windows下,是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意
思是栈顶的地址栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小2M(也有
的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将
提示overflow。因此,能从获得的空间较小。

堆:是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储
空闲内存地址的,自然是不连续的,而链表遍历方向是由低地址高地址堆的大小
受限于计算机系统中有效的虚拟内存。由此可见,获得的空间比较灵活,也比较大。

d.申请效率比较:

e. 存储内容

f. 存取效率:

总结堆和栈的区别可以用如下的比喻:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就 走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自 由度小
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由 度大

9. 进程和线程的区别

关联:

区别:

10.异步和同步,串行,并发,并行的区别

同步.png

详见:帮你快速理解同步 ,异步,并发/并行,串行

11. 多并发任务,仅多线程能加快速度么(不能,会变慢,有线程切换的开销)

多并发任务中,CPU只有一个,因此分配给进程的CPU资源是一定的,多线程只不过是轮流抢占CPU资源而已,并不会真正提高处理速度,并且由于线程之间的切换需要一定的开销,因此也会浪费一定的切换时间,这会导致一个任务采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。但多线程的作用主要在于提高了并发数量,比如http请求,如果是单线程,一次只能接收一个请求,多线程则可以同时接收多个请求。

12. 多个线程之间可以共享那些数据

13. 进程之间如何通信

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。

IPC的方式通常有管道(包括无名管道和命名管道)消息队列信号量信号消息队列共享内存套接字( socket )远程过程调用:RPC等。其中 套接字( socket )远程过程调用:RPC支持不同主机上的两个进程IPC

image.png
数据只需复制两次:一次从输入文件共享内存区,另一次从共享内存区输出文件
然而其他IPC形式(管道、FIFO、消息队列)则需要四次复制:
image.png
另外,默认情况下通过fork派生的子进程并不与其父进程共享内存区。

RPC是用于从一个系统(客户主机)上某个程序调用另一个系统上(服务器主机)某个函数的一种方法。

它的调用进程被调用进程可在不同主机上执行,客户和服务器运行在不同主机上,而且过程调用中涉及网络I/O,对于程序员是透明的。

另外,RPC也可用于同一主机上的客户和服务器之间,因此也可认为是另一种形式的消息传递。

详见:进程间通信方式

14. 介绍几种锁,他们的用途和区别

上一篇下一篇

猜你喜欢

热点阅读