C++岗位求职面试八股文第五篇

C++岗位求职面试八股文系列文章

第一篇:语言基础
第二篇:设计模式
第三篇:数据库
第四篇:计算机网络
第五篇:操作系统
第六篇:LInux
第七篇:数据结构
第八篇:智力题# 前言

[81]delete是如何知道释放内存的大小的?

需要在 new [] 一个对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。

[82]既然有了malloc/free,C++中为什么还需要new/delete呢?直接用malloc/free不好吗?

• malloc/free和new/delete都是用来申请内存和回收内存的。
• 在对非基本数据类型的对象使用的时候,对象创建的时候还需要执行构造函数,销毁的时候要执行析构函数。而malloc/free是库函数,是已经编译的代码,所以不能把构造函数和析构函数的功能强加给malloc/free,所以new/delete是必不可少的。

[83]被free回收的内存是立即返还给操作系统吗?

不是的,被free回收的内存会首先被ptmalloc使用双链表保存起来,当用户下一次申请内存的时候,会尝试从这些内存中寻找合适的返回。这样就避免了频繁的系统调用,占用过多的系统资源。同时ptmalloc也会尝试对小块内存进行合并,避免过多的内存碎片

[84]malloc申请的存储空间能用delete释放吗?


在这里插入图片描述

[85]C++类内定义引用成员

在这里插入图片描述
有3点注意:自定义构造函数,构造函数初始化列表 参数也是引用型

[86]const和define的区别。

定义常量角度:const用于定义常量,带类型;而define用于定义宏,不带类型

起作用的阶段:const生效于编译的阶段(可延迟到运行阶段);define生效于预处理阶段。
占用空间:const定义的常量,在C语言中是存储在内存中、需要额外的内存空间的;define定义的宏,运行时是直接的操作数,并不会存放在内存中。,但是混替换后占用代码段空间
define预处理后,占用代码段空间,const占用数据段空间
起作用的方式: define定义的常量不做类型检查。const有对应的数据类型,是要进行判断的
代码调试的方便程度:const常量可以进行调试的,define是不能进行调试的
是否可以做函数参数:宏定义不能作为参数传递给函数,const常量可以在函数的参数列表中出现

[87]define 和 typedef 的区别

define :宏定义

  1. 只是简单的字符串替换,没有类型检查
  2. 是在编译的预处理阶段起作⽤
  3. 可以⽤来防⽌头⽂件᯿复引⽤,可以使用 #ifdef、#ifndef 等来进行逻辑判断,
  4. 不分配内存,给出的是⽴即数,有多少次使⽤就进⾏多少次替换
    宏不是语句,不在在最后加分号;。
    作用域不同,#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。

typedef :给类型起新名字

  1. 有对应的数据类型,是要进⾏判断的,进行类型检查
  2. 是在编译、运⾏的时候起作⽤
  3. 在静态存储区中分配空间,在程序运⾏过程中内存中只有⼀个拷⻉typedef是语句,要加分号标识结束.而typedef有自己的作用域
    在这里插入图片描述

[88]宏定义和函数有何区别?

• 宏在预处理阶段完成替换,之后被替换的文本参与编译,相当于直接插入了代码,运行时不存在函数调用,执行起来更快;函数调用在运行时需要跳转到具体调用函数。
• 宏定义属于在结构中插入代码,没有返回值;函数调用具有返回值。
• 宏定义参数没有类型,不进行类型检查;函数参数具有类型,需要检查类型。
• 宏定义不要在最后加分号。

[89]变量声明和定义区别?

• 声明仅仅是把变量的声明的位置及类型提供给编译器,并不分配内存空间;定义要在定义的地方为其分配存储空间。
• 相同变量可以在多处声明(外部变量extern),但只能在一处定义

[90]constexpr 和 const

const:常量
constexpr:常量表达式,
constexpr一定是const,反之不是。
顶层const:指针本身是常ᰁ;
底层const:指针所指的对象是常ᰁ;
const 变量的初始化是编译解段,可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化
在这里插入图片描述
最后一个是底层const 带有引用的const,都是底层const
在这里插入图片描述

[91]C++中函数指针和指针函数的区别

定义不同
指针函数本质是一个函数,其返回值为指针。
函数指针本质是一个指针,其指向一个函数。

写法不同
指针函数:int *fun(int x,int y);
函数指针:int (*fun)(int x,int y);

用法不同
在这里插入图片描述

[92]const int *a, int const *a, const int a, int *const a, const int *const a分别是什么,有什么特点。

在这里插入图片描述
1常量
2常量指针:指向可变,值不变
3常量指针
4指针常量:指向不变,值可以变
5都不变

[93]C++和Python的区别

包括但不限于:
• Python是一种脚本语言,是解释执行的,而C++是编译语言,是需要编译后在特定平台运行的。python可以很方便的跨平台,但是效率没有C++高。
• Python使用缩进来区分不同的代码块,C++使用花括号来区分
• C++中需要事先定义变量的类型,而Python不需要,Python的基本数据类型只有数字,布尔值,字符串,列表,元组等等
• Python的库函数比C++的多,调用起来很方便
• C++执行效率高,编程难(开发效率低);python执行效率低,编程简单(开发效率快;

python是一种解释语言。python的工作方式是,首先在安装python软件包的位置创建一个虚拟机。然后将写好的python代码保存到.py文件中。然后再通过Cpython,将python代码编译为python虚拟机的字节码。

• Python 与 C ++ 重要的区别之一是内存管理。Python 提供了被称为「垃圾收集器」的自动内存管理机制,不允许直接进行内存处理操作。但在 C++ 里则没有这样的机制,并且所有内存管理操作都需要自行处理。

• 解释型语言是指使用专门的解释器对源程序进行逐行解释成特定平台的机器码并立即执行的语言。解释型语言通常不会进行整体的编译和链接处理,解释型语言相当于把编译型语言中的编译和解释过程混合在一起同时完成。

[94]使用指针需要注意什么?

初始化置NULL 申请内存后判空 指针释放后置NULL

定义指针时,先初始化为NULL。
用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作
动态内存的申请与释放必须配对,防止内存泄漏
用free或delete释放了内存之后,立即将指针设置为NULL,防止“野指针”

[95]C++有几种传值方式,之间的区别是什么?

值传递:形参即使在函数体内值发生变化,也不会影响实参的值;
引用传递:形参在函数体内值发生变化,会影响实参的值;
指针传递:在指针指向没有发生改变的前提下,形参在函数体内值发生变化,会影响实参的值;

值传递用于对象时,整个对象会拷贝一个副本,这样效率低;而引用传递用于对象时,不发生拷贝行为,只是绑定对象,更高效;指针传递同理,但不如引用传递安全。

[96]堆和栈的区别

堆栈空间分配不同。栈:程序运行时由编译器自动分配 ,存放函数的参数值,局部变量的值等;程序结束时由编译器自动释放,(编译器通过汇编指令决定分配的方式,但是具体的分配时间当然是运行时的)
堆一般由程序员分配释放。

堆栈缓存方式不同。栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放;堆则是存放在二级缓存中,速度要慢些。

堆栈数据结构不同。堆类似数组结构;栈类似栈结构,先进后出。

局部变量的内存空间分配是在程序运行时进行的,不初始化。
静态变量和全局变量会在编译时就进行内存的分配,初始化。

[97]C++的内存管理

内存分配方式:
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。

堆,就是那些由new分配的内存块,一般一个new就要对应一个delete。

自由存储区,就是那些由new等分配的内存块,和堆是十分相似的,

全局/静态存储区,全局变量和静态变量被分配到同一块内存中

常量存储区,这是一块比较特殊的存储区,里面存放的是常量,不允许修改

[98]常见的内存错误及其对策

未分配 未初始化 越界 未释放 释放仍使用
内存错误:
(1)内存分配未成功,却使用了它。
(2)内存分配虽然成功,但是尚未初始化就引用它。
(3)内存分配成功并且已经初始化,但操作越过了内存的边界。
(4)忘记了释放内存,造成内存泄露。
(5)释放了内存却继续使用它。
对策:
(1)定义指针时,先初始化为NULL。
(2)用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
(3)不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
(4)避免数字或指针的下标越界,特别要当心发生“多1”或者“少1”操作
(5)动态内存的申请与释放必须配对,防止内存泄漏
(6)用free或delete释放了内存之后,立即将指针设置为NULL,防止“野指针”
(7)使用智能指针。

[99]内存泄露及解决办法

什么是内存泄露?
简单地说就是申请了一块内存空间,使用完毕后没有释放掉。(1)new和malloc申请资源使用后,没有用delete和free释放;(2)子类继承父类时,子类有数据开辟到堆区,父类析构函数不是虚函数。(3)Windows句柄资源使用后没有释放。

怎么检测?
第一:良好的编码习惯,使用了内存分配的函数,一旦使用完毕,要记得使用其相应的函数释放掉。
• 计数法:使用new或者malloc时,让该数+1,delete或free时,该数-1,程序执行完打印这个计数,如果不为0则表示存在内存泄露
• 一定要将基类的析构函数声明为虚函数
• 对象数组的释放一定要用delete []
• 有new就有delete,有malloc就有free,保证它们一定成对出现

第二:将分配的内存的指针以链表的形式自行管理,使用完毕之后从链表中删除,程序结束时可检查改链表。

第三:使用智能指针。

第四:一些常见的工具插件,如CRT(windows)、Valgrind(linux)等等。

[100]避免死锁(Deadlock)算法

银行家算法(Banker’s Algorithm)
当一个进程申请使用资源的时候,银行家算法通过先 试探 分配给该进程资源,然后通过安全性算法判断分配后的系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待。

链接
在这里插入图片描述

[续]C++岗位求职面试八股文第六篇

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT与Fintech

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值