🍅07-C++面试之从代码到可执行程序经历
[TOC]
0 前述
针对于自己在秋招的面试中,对于CPP
部分遇到的问题,其中大部分是以此为起点,你可以基于这些点,将自己对于CPP
学习的知识点,串联起来。无论面试官,问这一类问题中的某个点,你都应该可以将这一个珠子串联到自己的知识链上来讲。这是一种拓展知识的能力。
在此专栏下面个人校招记录:回馈牛客,对CPP
做一个小小的总结。
本部分关于CPP
从代码到可执行程序的4个阶段,以预编译/预处理main.i
-->编译main.s
-->汇编main.o
-->链接 main
的顺序来展开叙述,紧接着给出了链接部分的一些细节,最后分别讨论了静态链接和动态链接的优缺点。
- 下面对应的是之前发布的个人校招其他公司面试总结,希望可以更好的帮到你
这里是CPP
一些面试问题整理
1 预编译/预处理
主要处理源代码文件中的以#
开头的预编译指令。包括
1)将#define
宏定义替换、宏的展开。
2)#if #else #endif
条件编译指令。
3)将注释消除掉。
4)#include
头文件包含指令、特殊符号。预编译所完成的基本上是对源程序的“替代”工作。
经过上述的这些替代,产生一个没有任何替代的输出文件。生成a.i
或a.ii
文件。
2 编译
把预编译之后生成的a.i
或a.ii
文件,去检查代码是否有语法上的错误,并且对代码优化,进行一些列词法分析,语法分析,语义分析及优化后,生成相应的汇编代码文件。输出.s
文件。
3 汇编
把汇编代码转换成机器码,机器可以执行的指令(机器码)。翻译成机器码,输出.o
文件(对应于Windows
平台下)或者.obj
文件。
将编译之后的.s
文件,汇编成可重定位的目标文件.o
文件。
4 链接
将不同的源文件产生的目标文件(可重定位的目标文件和printf.o
等单独编译)进行链接,从而形成一个可执行程序。
静态链接细节
静态链接主要有两步:1)空间与地址分配,分配虚拟地址;2)进行符号解析与重定位。
-
空间与地址分配
linker
将能够获得的所有输入目标文件的段长度,并且将它们合并,计算输出文件中各个段合并后的长度与位置,并建立起映射关系。比如:将各个目标文件
.text
段合并在一起,.data
段合并在一起,并且分配虚拟地址空间。 -
符号解析和重定位
分配好空间后,进行真正的核心操作,进行重定位,主要是伴随着符号解析过程,每个目标文件都可能定义一些符号,也可能引用到定义在其他目标文件的符号。而重定位的过程中,每个重定位的入口都是对一个符号的引用,那么当
linker
需要对某个符号的引用进行重定位时,它就要确定这个符号的目标地址。这时候,linker
就会去查找所有输入目标文件的符号表组成的全局符号表,找到相应的符号进行重定位。比如说我们的
hello world.c
中的main
函数并不知道printf
这个函数的地址,linker
在链接的时候会根据引用到的符号printf
,自动去相应的模块查找printf
的地址,然后将hello world.c
模块中引用到printf
的指令进行重新修正,让它的目标地址成为真正的printf
函数的地址,这个就是链接的基本过程。
链接的分类:静态链接-static
(应加入选项)和动态链接
静态链接优缺点
函数和数据被编译进一个二进制文件,通常以.a
结尾,比如某些封装好的算法就是用.a
提供给对外的API
程序接口被外部调用。在使用静态库的情况下,进行编译链接可执行文件时,linker
从库中复制这些函数和数据,并将它们和应用程序的其它模块组合起来,创建最终的可执行文件。
1)空间浪费:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,会出现同一个目标文件都在内存存在多个副本。
2)更新困难:当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。
3)运行速度快:静态链接的优点就是,无环境依赖,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。
动态链接优缺点
其中共享库就是为了解决上述静态库的前两个问题而设计的,在Linux
系统中通常使用.so
后缀表示;Windows
系统上被称之为DLL
。具有一下特点:
1)动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。加快了编译速度。
2)减少内存占用:共享库,就是即使需要每个程序都依赖同一个库,但是该库也不会像静态链接那样在内存中存在多分,副本,而是这多个程序在执行时共享同一份副本。
3)更新方便:更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一次运行时,更新的新版本目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。
4)性能损耗:因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。
#晒一晒我的offer##我发现了面试通关密码##你的秋招进行到哪一步了##软件开发2023笔面经#这是一个求职总结专栏,求职过程中,牛客里面各位同志,提供了很多面试的信息,对我个人有很大的帮助。这里简单将自己面试记录总结于此。 本人23届校招生,双非硕士,投递岗位嵌入式,控制算法,后台开发均有涉猎,优先级递减。简历累计投递数量:提前批(34)+正式批(128),累计Offer(5+)。