目录
C面试题
1、描述⼀下gcc的编译过程?
gcc编译过程分为4个阶段:预处理、编译、汇编、链接。
预处理:头⽂件包含、宏替换、条件编译、删除注释
编译:主要进⾏词法、语法、语义分析等,检查⽆误后将预处理好的⽂件编译成汇编⽂件。
汇编:将汇编⽂件转换成 ⼆进制⽬标⽂件
链接:将项⽬中的各个⼆进制⽂件+所需的库+启动代码链接成可执⾏⽂件
2、内存的最⼩存储单位以及内存的最⼩计量单位分别是?
内存的最⼩存储单位为 ⼆进制位, 内存的最⼩计量单位 字节
3、#include<> 与#include ""的区别?
include<>到系统指定⽬录寻找头⽂件,#include ""先到项⽬所在⽬录寻找头⽂件,如果没有找再到系 统指定的⽬录下寻找
4、描述⼀下变量的命名规则
变量名有字⺟、数值、下划线组成,但不能以数值开头
5、变量的声明与定义有啥区别?
声明变量 不需要 建⽴存储空间, 变量的定义需要建⽴存储空间
6、谈谈c语⾔中有符号和⽆符号的区别?
有符号:数据的最⾼位为符号位,0表示正数,1表示负数 ⽆符号:数据的最⾼位不是符号位,⽽是数据的⼀部分
7、谈谈计算机中补码的意义
统⼀了零的编码
将符号位与其他位统⼀处理
将减法运算转换成加法运算
8、谈谈数组的特点
同⼀个数组所有的成员都是相同的数据类型,同时所有的成员在内存中的地址是连续的
9、数组的分类
数组的分类主要是:静态数组、动态数组两类。
静态数组:类似int arr[5];在程序运⾏就确定了数组的⼤⼩,运⾏过程不能更改数组的⼤⼩。
动态数组:主要是在堆区申请的空间,数组的⼤⼩是在程序运⾏过程中确定,可以更改数组的⼤⼩。
10、描述⼀下⼀维数组的不初始化、部分初始化、完全初 始化的不同点
不初始化:如果是局部数组 数组元素的内容随机 如果是全局数组,数组的元素内容为0
部分初始化:未被初始化的部分⾃动补0
完全初始化:如果⼀个数组全部初始化 可以省略元素的个数 数组的⼤⼩由初始化的个数确定
11、谈谈数组名作为类型、作为地址、对数组名取地址的 区别?
数组名作为类型:代表的是整个数组的⼤⼩
数组名作为地址:代表的是数组⾸元素的地址
对数组名取地址:代表的是数组的⾸地址
12、谈谈你对⼆维数组在物理上以及逻辑上的数组维度理解
⼆维数组在逻辑上是⼆维的,在物理上是⼀维的
13、描述⼀下函数的定义与函数的声明的区别
函数定义:是指对函数功能的确⽴,包括指定函数名、函数类型、形参及其类型、函数体等,它是⼀个 完整的、独⽴的函数单位。函数的定义就算函数的具体实现
函数的声明:是把函数的名字、函数类型以及形参的个数、类型和顺序(注意,不包括函数体)通知编译 系统,以便在对包含函数调⽤的语句进⾏编译时,据此对其进⾏对照检查(例如函数名是否正确,实参 与形参的类型和个数是否⼀致),函数的声明就算告诉系统存在这个函数,一般在调用的时候使用
14、描述⼀下指针与指针变量的区别
指针:没存中每⼀个字节都会分配⼀个32位或64位的编号,这个编号就是地址, ⽽指针就是内存单元的 编号。
指针变量:本质是变量 只是该变量存放的是空间的地址编号
15、描述⼀下32位或64位平台下指针的⼤⼩
32位平台:任意类型的指针⼤⼩为4字节
64位平台:任意类型的指针⼤⼩为8字节
16、描述⼀下指针数组的概念
指针数组本质是数组,只是数组的每个元素是⼀个指针(地址)
17、描述⼀下普通局部变量、普通全局变量、静态局部变 量、静态全局变量的区别
普通局部变量: 存在栈区、不初始化内容随机、只在定义所在的复合语句中有效、符合语句结束变量空间释放
普通全局变量 存在全局区、不初始化内容为0、进程结束空间才被释放,能被当前源⽂件或其他源⽂件使⽤,只是其 他源⽂件使⽤的时候,记得使⽤extern修饰
静态局部变量: 存在全局区、不初始化内容为0、整个进程结束空间才被释放,只能在定义所在的复合语句中有效
静态全局变量 存在全局区、不初始化内容为0、整个进程结束空间才被释放,只能被当前源⽂件使⽤
18、描述⼀下内存分区
程序在运⾏前:分为代码区、BSS段(未初始化数据区)、data段(初始化数据区)
程序在运⾏后:堆区、栈区、全局区(静态区)、⽂字常量区、代码区
19、在使⽤realloc给已分配的堆区空间追加空间时需要注意啥?
记得⽤指针变量保存realloc的返回值
20、结构体与共⽤体的区别是啥
结构体中的成员拥有独⽴的空间,共⽤体的成员共享同⼀块空间,但是每个共⽤体成员能访问共⽤区的 空间⼤⼩是由成员⾃身的类型决定
21、谈谈⽂件的分类
⽂件分为⼆进制和⽂本⽂件
⼆进制⽂件基于值编码,需要根据具体的应⽤才能知道某个值具体的含义
⽂本⽂件基于字符编码,⼀个字节⼀个意思,可以通过记事本打开
22、⽂件缓冲区刷新⽅式有⼏种
⾏刷新、满刷新、强制刷新、关闭刷新
23、哪些情况下会出现野指针
指针变量未初始化、指针释放后未为置空、指针操作超越变量作⽤域
24、如何理解指针作为函数参数的输⼊和输出特性
输⼊特性:主调函数分配空间 背调函数使⽤该空间
输出特性:被调⽤分配空间 主调函数使⽤该空间
25、如何理解结构体的浅拷⻉与深拷⻉
当结构体中有指针成员的时候容易出现浅拷⻉与深拷⻉的问题。 浅拷⻉就是,两个结构体变量的指针成员指向同⼀块堆区空间,在各个结构体变量释放的时候会出现多 次释放同⼀段堆区空间 深拷⻉就是,让两个结构体变量的指针成员分别指向不同的堆区空间,只是空间内容拷⻉⼀份,这样在 各个结构体变量释放的时候就不会出现多次释放同⼀段堆区空间的问题
26、描述⼀下结构体对⻬规则
1. 数组成员对⻬规则。第⼀个数组成员应该放在offset为0的地⽅,以后每个数组成员应该放在offset 为min(当前成员的⼤⼩,#pargama pack(n))整数倍的地⽅开始(⽐如int在32位机器为4字 节,#pargama pack(2),那么从2的倍数地⽅开始存储)。 2. 结构体总的⼤⼩,也就是sizeof的结果,必须是min(结构体内部最⼤成员,#pargama pack(n)) 的整数倍,不⾜要补⻬。 3. 结构体做为成员的对⻬规则。如果⼀个结构体B⾥嵌套另⼀个结构体A,还是以最⼤成员类型的⼤⼩ 对⻬,但是结构体A的起点为A内部最⼤成员的整数倍的地⽅。(struct B⾥存有struct A,A⾥有 char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对⻬规则仍 满⾜原则1、原则2。
27、啥叫宏函数以及作⽤
在项⽬中,经常把⼀些短⼩⽽⼜频繁使⽤的函数写成宏函数,这是由于宏函数没有普通函数参数压栈、 跳转、返回等的开销,可以调⾼程序的效率。 宏通过使⽤参数,可以创建外形和作⽤都与函数类似地类 函数宏(function-like macro). 宏的参数也⽤圆括号括起来,来保证宏函数的完整性。
Linux系统编程
1、shell是什么
Shell 是“命令解释器”(⼈和内核打交道的翻译) Shell 作⽤:对⽤户输⼊到终端的命令进⾏解析,调⽤ 对应的执⾏程序
2、常⻅的 shell 及查看 shell 的⽅法
unix默认的shell为sh linux默认的shell为bash
查看shell的⽅法:cat /etc/shells 或 echo $SHELL
3、简单描述⼀下linux下的⽬录结构
/bin 存放系统可执⾏程序(⼤部分系统命令) /sbin 存放 root ⽤户的系统可执⾏程序 /boot 存放内核 和启动程序的相关⽂件 /lib 库⽬录,存放系统最基本的动态库 /media 默认挂载设备媒体的⽬录,例如 U 盘、光驱 /mut 推荐挂载设备媒体的⽬录 /usr ⽤于存放庞⼤⽽复杂的⽬录(unix system resource,⽤ 于安装软件的⽬录) /proc 系统内存的映射(随着系统的运⾏,时⻓变化的) /ect 系统软件的启动和配 置⽬录 /dev ⽤于存放设备⽂件 /home 家⽬录,所⽤⽤户的根⽬录(当前⽤户的根⽬录是 /home/user)
4、linux下的权限分为哪3个组
⽤户权限、同组⽤户权限、其他⽤户权限
5、linux下⽂件的类型
普通⽂件 d ⽬录⽂件 c 字符设备⽂件 b 块设备⽂件 l (软)连接⽂件 p 管道⽂件 s 本地套接字
6、描述⼀下软连接和硬链接的区别