校招考点全解析——C++软件与嵌入式软件篇(蒋豆芽的秋招之旅)专刊正式上线了!!!
本专栏介绍
-
本专栏适合于C/C++已经入门的学生或人士,有一定的编程基础。
-
本专栏适合于互联网C++软件开发、嵌入式软件求职的学生或人士。
- 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。
- 针对于基础不太好的同学,建议学习本人专刊文章《蒋豆芽的秋招打怪之旅》,网址:https://www.nowcoder.com/tutorial/10078/index,该专刊文章对每一个知识点进行了详细解析。
-
本专栏特点:
本专栏囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构、数据库等一系列知识点,总结出了高频面试考点(附有答案)共计309道,事半功倍,为大家春秋招助力。
-
本专栏内容分为七章:共计309道高频面试题(附有答案)
-
蒋豆芽的秋招打怪之旅——啊C啊C我爱你
-
蒋豆芽的秋招打怪之旅——C++说爱你不容易
-
蒋豆芽的秋招打怪之旅——操作系统,揭开钢琴的盖子
-
蒋豆芽的秋招打怪之旅——说说计算机网络的那些事
-
蒋豆芽的秋招打怪之旅——嵌入式基础知识(仅适合嵌入式求职的同学)
- 蒋豆芽的秋招打怪之旅——算法与数据结构
- 蒋豆芽的秋招打怪之旅——数据库(仅适合C++软件开发求职的同学)
-
- 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
-
请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。
快走入蒋豆芽的世界来吧,和蒋豆芽一起开启春秋招打怪之旅!!!
作者介绍
湖南大学(985)硕士研究生(1%保研),国家奖学金、省优秀研究生称号获得者。校招面试过数十家公司,经验丰富,获得过华为、京东、顺丰科技等公司offer。个人面试经历写作为专刊文章,目前为牛客网专刊作者。擅长机器学习、C++后台开发、嵌入式软件开发。非科班研究生,立志进入互联网领域,最后通过自己的努力拿到大公司的offer,将自己的经历写入了《蒋豆芽的秋招打怪之旅》故事中,和大家分享春秋招的酸甜苦辣。
部分题目展示
-
说说数组和指针的区别
-
概念:
(1)数组:数组是用于储存多个相同类型数据的集合。 数组名是首元素的地址。
(2)指针:指针相当于一个变量,但是它和不同变量不一样,它存放的是其它变量在内存中的地址。指针名指向了内存的首地址。
-
区别:
(1)赋值:同类型指针变量可以相互赋值;数组不行,只能一个一个元素的赋值或拷贝
(2)存储方式:
数组:数组在内存中是连续存放的,开辟一块连续的内存空间。数组是根据数组的下进行访问的,数组的存储空间,不是在静态区就是在栈上。
指针:指针很灵活,它可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内存。由于指针本身就是一个变量,再加上它所存放的也是变量,所以指针的存储空间不能确定。
(3)求sizeof:
数组所占存储空间的内存大小:sizeof(数组名)/sizeof(数据类型)
在32位平台下,无论指针的类型是什么,sizeof(指针名)都是4,在64位平台下,无论指针的类型是什么,sizeof(指针名)都是8。
(4)初始化://数组 int a[5] = {0}; char b[]={"Hello"}; //按字符串初始化,大小为6. char c[]={'H','e','l','l','o','\0'}; //按字符初始化 int* arr = new int[n]; //创建一维数组 //指针 //指向对象的指针 int p=new int(0) ; delete p; //指向数组的指针 int p=new int[n]; delete[] p; //指向类的指针: class p=new class; delete p;
-
-
数组指针与指针数组的区别
数组指针是一个指针变量,指向了一个二维数组;指针数组是一个数组,只不过数组的元素存储的是指针变量。
-
指针函数与函数指针的区别
(1)定义不同 指针函数本质是一个函数,其返回值为指针。 函数指针本质是一个指针,其指向一个函数。
(2)写法不同
指针函数:int *fun(int x,int y); 函数指针:int (*fun)(int x,int y);
(3)用法不同
指针函数返回一个指针。 函数指针使用过程中指向一个函数。通常用于函数回调的应用场景
-
请说说内存分布模型
从低地址到高地址,一个程序由代码段、数据段、 BSS 段组成。
-
数据段:存放程序中已初始化的全局变量和静态变量的一块内存区域。
-
代码段:存放程序执行代码的一块内存区域。只读,代码段的头部还会包含一些只读的常数变量。
-
BSS 段:存放程序中未初始化的全局变量和静态变量的一块内存区域。
-
可执行程序在运行时又会多出两个区域:堆区和栈区。
堆区:动态申请内存用。堆从低地址向高地址增长。
栈区:存储局部变量、函数参数值。栈从高地址向低地址增长。是一块连续的空间。
-
最后还有一个文件映射区,位于堆和栈之间。
-
-
堆和栈的区别
-
堆栈空间分配不同。栈由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等,栈有着很高的效率;堆一般由程序员分配释放,堆的效率比栈要低的多。
-
堆栈缓存方式不同。栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放;堆则是存放在二级缓存中,速度要慢些。
-
堆栈数据结构不同。堆类似数组结构;栈类似栈结构,先进后出。
-
空间大小: 栈的空间大小并不大,一般最多为2M,超过之后会报Overflow错误。堆的空间非常大,最大可到达4G,可操作的空间非常大。
-
能否产生碎片: 栈的操作与数据结构中的栈用法是类似的。‘后进先出’的原则,以至于不可能有一个空的内存块从栈被弹出。因为在它弹出之前,在它上面的后进栈的数据已经被弹出。它是严格按照栈的规则来执行。但是堆是通过new/malloc随机申请的空间,频繁的调用它们,则会产生大量的内存碎片。这是不可避免地。
-
-
请你说说野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
野指针不同于空指针,空指针是指一个指针的值为null,而野指针的值并不为null,野指针会指向一段实际的内存,只是它指向哪里我们并不知情,或者是它所指向的内存空间已经被释放,所以在实际使用的过程中,我们并不能通过指针判空去识别一个指针是否为野指针。
-
请你说说内存泄露
简单地说就是申请了一块内存空间,使用完毕后没有释放掉。
(1)new和malloc申请资源使用后,没有用delete和free释放;
(2)子类继承父类时,父类析构函数不是虚函数。
(3)Windows句柄资源使用后没有释放。
有以下几种避免方法:
第一:良好的编码习惯,使用了内存分配的函数,一旦使用完毕,要记得使用其相应的函数释放掉。
第二:将分配的内存的指针以链表的形式自行管理,使用完毕之后从链表中删除,程序结束时可检查改链表。
第三:使用智能指针。
第四:一些常见的工具插件,如ccmalloc、Dmalloc、Leaky、Valgrind等等。
-
堆内存申请需要注意什么?
(1)不要错误地返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡。
(2)不要返回了常量区的内存空间。因为常量字符串,存放在代码段的常量区,生命期内恒定不变,只读不可修改。
(3)通过传入一级指针不能解决,因为函数内部的指针将指向新的内存地址。
解决办法:
(1)使用二级指针
(2)通过指针函数解决,返回新申请的内存空间的地址。
-
请你说说内存碎片
内存碎片通常分为内部碎片和外部碎片:
(1)内部碎片是由于采用固定大小的内存分区,当一个进程不能完全使用分给它的固定内存区域时就产生了内部碎片,通常内部碎片难以完全避免;
(2)外部碎片是由于某些未分配的连续内存区域太小,以至于不能满足任意进程的内存分配请求,从而不能被进程利用的内存区域。再比如堆内存的频繁申请释放,也容易产生外部碎片。
解决方法:
(1)段页式管理
(2)内存池
-
请你说说malloc内存管理原理
当开辟的空间小于 128K 时,调用 brk()函数;
当开辟的空间大于 128K 时,调用mmap()。
malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲快。采用隐式链表将所有空闲块,每一个空闲块记录了一个未分配的、连续的内存地址。
-
什么是内存池
内存池也是一种对象池,我们在使用内存对象之前,先申请分配一定数量的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。当不需要此内存时,重新将此内存放入预分配的内存块中,以待下次利用。这样合理的分配回收内存使得内存分配效率得到提升。
-
说说new和malloc的区别,各自底层实现原理
-
new是操作符,而malloc是函数。
-
new在调用的时候先分配内存,在调用构造函数,释放的时候调用析构函数;而malloc没有构造函数和析构函数。
-
malloc需要给定申请内存的大小,返回的指针需要强转;new会调用构造函数,不用指定内存的大小,返回指针不用强转。、
-
new可以被重载;malloc不行
-
new分配内存更直接和安全。
-
new发生错误抛出异常,malloc返回null
-
-
说说使用指针需要注意什么?
-
定义指针时,先初始化为NULL。
-
用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
-
不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
-
避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作
-
动态内存的申请与释放必须配对,防止内存泄漏
-
用free或delete释放了内存之后,立即将指针设置为NULL,防止“野指针”
-
-
初始化为0的全局变量在bss还是data
BSS段通常是指用来存放程序中未初始化的或者初始化为0的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0。
全部评论
(10) 回帖