2023秋招C++八股文

作者:小飞飞  | 来源:3DCV

添加微信:dddvisiona,备注:求职招聘 ,拉你入群。文末附行业细分群。

在2023的秋招中,我参加过多次面试,这些面试都会问到C++的相关知识,C++面试不仅考察理论知识,还会考察解决问题的能力。我将分享我在面试中遇到的一些常见问题,给正在参加秋招的你一些参考。

df372b8c4794bec73c66af3e92a4db9a.jpeg

1.C++新特性

C++的新特性主要在其最新的几个版本中引入,包括C++11、C++14、C++17和C++20。
C++11: 

• 自动类型推断(auto):该关键字允许编译器自动推断变量的类型。

• 范围for循环:这种新的for循环语法使得遍历容器变得更简洁。

• nullptr:引入了新的空指针类型,以替代之前的NULL。 

• 新的智能指针:引入了unique_ptr和shared_ptr,使得内存管理更加安全和方便。 

• 移动语义和右值引用:这使得开发人员可以编写更有效率的代码,尤其是涉及到临时对象的情况。
C++14: 

• 泛型Lambda:C++14添加了对泛型Lambda的支持,使得Lambda可以接受自动类型推断的参数。

• 变量模板:这是模板的一个新形式,可以定义模板常量或者模板全局变量。 

• 二进制字面量:C++14开始支持使用二进制字面量,如:0b1010

C++17:

• 结构化绑定:这允许开发人员在一行代码中声明和初始化多个变量。

• std::optional:这是一个可以包含值或者不包含值的模板类型。 

• std::variant:这是一个安全的联合类型,可以在一组预定义类型中保存值。 

• std::filesystem:这是一个全新的文件系统库,用于操作路径、文件和目录。

这里推荐学习「3D视觉工坊」最新推出的C++从入门到进阶课程:面向三维视觉算法的C++重要模块精讲:从零基础入门到进阶

2.类的实例大小计算

Sizeof(x):返回的是x占的字节数,64位机一个指针(地址)占8个字节,32位机的一个指针占4个字节。
在C++中,类的实例大小计算是一个复杂且关键的过程。以下是一些主要规则:
基本数据类型大小:类的实例大小至少等于其所有非静态成员变量的大小之和。例如,如果一个类有一个 int 成员和一个 double 成员,那么该类的大小至少是 sizeof(int) + sizeof(double)(还没做内存对齐)。这不包括静态成员,因为静态成员不是类的每个实例的一部分,但是在全局范围内只存在一份。

继承:在C++中,如果一个类B继承自另一个类A,那么类B的实例大小至少是 sizeof(A) + sizeof(B中新增的成员)。

对齐规则:C++编译器可能会调整成员的布局以满足硬件的对齐要求,这可能会增加类的大小。例如,如果一个类有一个 char 成员和一个 double 成员,在某些硬件上 double 必须在8字节的边界上对齐,所以编译器可能会在 char 和 double 之间插入7个填充字节。

虚函数:如果一个类有虚函数,那么它的大小至少还包括一个指向虚函数表(vtable)的指针。这个虚函数表在内存中是一个包含函数指针的数组,每个函数指针指向类中的一个虚函数的实现。
空类:在C++中,一个空类的大小不是0,而是1。这是因为每个对象(包括类的实例)在内存中都需要有一个唯一的地址。

3.static关键字

静态全局变量不能被其它文件所用,static最大的可见范围就是本文件。态变量的生命周期是从它们被初始化时开始,直到程序结束时才消亡。因此,如果你尝试使用extern和static修饰同一个变量,编译器会报错。例如,在GCC中,你会得到这样的错误:

error: 'static' and 'extern' are mutually exclusive

在C++17之前,类的静态成员变量需要在类外部定义和初始化。然而,使用inline关键字,你可以在类内部定义和初始化静态成员变量:

class MyClass {
public:
    static inline int count = 0; // Declare, define and initialize static data member
};

4.const关键字

const 关键字用于声明一个常量,也就是说,这个变量的值一旦设定,就不能更改。因此,const 变量必须在声明时就初始化.如果 const 是一个类的成员变量,那么它必须在构造函数的初始化列表中初始化:

class MyClass {
public:
    const int a;
    MyClass(int value) : a(value) {}
};

当const关键字出现在星号 * 前面它是在声明一个指针,该指针指向的内容是不能修改的。不能通过这个指针来改变它所指向的值,但是可以改变这个指针本身所指向的地址。在星号后面则反之。

5.左值和右值

在C++中,"左值"和"右值"是两种不同类型的表达式。这两个术语源于它们在赋值表达式中可能出现的位置,左值通常出现在赋值操作符的左边,而右值通常出现在赋值操作符的右边。然而,这只是最初的定义,现代C++中对这两个概念的定义已经有所扩展和深化.
左值(Lvalue):左值是一个可以定位到存储空间的表达式,这个存储空间有一个可观察的地址。左值可以出现在赋值操作符的左边或右边。例如,如果我们有一个变量a,那么表达式a就是左值,因为a具有明确的内存位置:

int a = 10; // 'a' is an lvalue
a = 20; // 'a' is on the left side of assignment operator
int b = a; // 'a' is also an lvalue when it is on the right side of assignment operator

右值(Rvalue):右值是一个不与特定内存位置关联的表达式。它们是临时的,不能具有可观察的地址。右值主要包括:• 字面量(例如:10, 20.5, 'a') • 返回值为非引用类型的函数的结果 • 二元运算符或一元运算符的计算结果

int y = x + 2; // '(x + 2)' is an rvalue
int z = foo(); // if foo() is a function returning non-reference type, then 'foo()' is an rvalue

在C++11及后续版本中,右值引用和移动语义的引入使得右值的概念更加复杂。C++11引入的右值引用允许我们修改右值,并对临时对象进行优化,这在大型对象或资源所有权传递的情况下,可以显著提高性能.

6.struct和class

在 C++ 中,struct和class基本上是相同的;它们都可以包含数据成员和成员函数,也都可以用于继承和多态。但是,它们在默认访问级别和默认继承方式上有些微妙的差别。
•struct的默认成员访问级别是public。也就是说,如果你不明确指定一个struct的成员是public、protected还是private,那么它默认就是public。
•class的默认成员访问级别是private。也就是说,如果你不明确指定一个class的成员是public、protected还是private,那么它默认就是private。
•如果你在继承一个struct时不明确指定是public、protected还是private继承,那么它默认就是public继承。
•如果你在继承一个class时不明确指定是public、protected还是private继承,那么它默认就是private继承

7.指针和引用的区别是什么

在C++中,指针和引用都是用于存储另一个对象的地址或别名的变量类型。但是,它们之间存在一些关键的区别。
1.基本定义:指针是一个变量,其值为另一个变量的地址,而引用则是一个已存在变量的别名
2.空值:指针可以为空,而引用在创建时必须被初始化,并且不能改变引用到的对象。
3.更改指向:指针的指向可以在其生命周期中改变,即它可以指向另一个对象。而引用一旦创建,就不能更改引用到的对象。
4.使用方式:使用指针访问其指向的对象时,必须使用解引用运算符( * )。而使用引用时,可以像使用普通变量一样直接访问。
5.指针的指针与引用的引用:C++允许指针的指针,但是不允许引用的引用。

8.delete和delete[]的区别

在C++中,delete和delete[]用于释放动态分配的内存,但它们的用途是有区别的:
• delete 用于删除通过 new 单独创建的单一对象。
• delete[] 用于删除通过 new[] 创建的对象数组。这两者的区别在于 delete 只能用于销毁单一对象,而 delete[] 可以销毁整个对象数组。如果在对象数组上使用 delete 或在单一对象上使用 delete[],那么可能会导致未定义的行为。

int* p = new int;
delete p;
// 对于对象数组的创建和删除
int* arr = new int[10];
delete[] arr;

9.进程和线程有什么区别

进程和线程是操作系统中两个基本概念,它们在资源分配、运行方式以及使用场景等方面有一些重要的区别:
1.资源分配:进程是操作系统分配资源的基本单位,比如CPU时间、内存空间等。每个进程有自己的地址空间,这个地址空间包含了程序代码、全局变量、堆、栈等。而线程是进程的一部分,是CPU调度的基本单位。一个进程可以包含多个线程,这些线程共享进程的地址空间和其他资源。
2.运行方式:每个进程都有自己的独立执行路径,并且进程间的运行互不影响。但是在同一个进程中的线程,它们的执行可以被彼此影响。线程之间可以通过共享数据和通信来协调行为。
3.创建开销:创建或销毁一个进程的开销通常比创建或销毁一个线程的开销要大,因为操作系统需要分配或回收更多的资源。线程的创建和销毁只涉及到一些寄存器、栈和线程元数据的分配,因此开销较小。
4.切换开销:进程间切换的开销也大于线程间切换的开销。进程切换需要更多的时间和资源,因为每次切换都需要改变整个地址空间。而线程切换更快,因为同一进程中的线程共享相同的地址空间。
5.通信方式:进程间通信(IPC,Inter-Process Communication)需要使用特殊的操作系统API,如管道、消息队列、共享内存等。而线程间通信更容易,因为它们共享相同的内存,可以直接访问彼此的堆和全局变量。

10.C++程序的处理过程

预处理阶段:写好的⾼级语⾔的程序⽂本⽐如hello.c,预处理器根据#开头的命令,修改原始的程序,如#include将把系统中的头⽂件插⼊到程序⽂本中,生成以.i结尾的⽂件。
编译阶段:编译器将hello.i⽂件翻译成⽂本⽂件hello.s,这个是汇编语⾔程序。⾼级语⾔是源程序。汇编语⾔程序是以标准的⽂本格式确切描述⼀条低级机器语⾔指令。不同的⾼级语⾔翻译的汇编语⾔相同。
汇编阶段:汇编器将hello.s翻译成机器语⾔指令。把这些指令打包成可⾦定位⽬标程序,即.o⽂件。hello.o是⼀个⼆进制⽂件,它的字节码是机器语⾔指令,不再是字符。前⾯两个阶段都还有字符。
链接阶段:⽐如hello程序调⽤printf程序,它是每个C编译器都会提供的标准库C的函数。这个函数存在于⼀个名叫printf.o的单独编译好的⽬标⽂件中,这个⽂件将以某种⽅式合并到hello.o中。链接器就负责这种合并。得到的是可执⾏⽬标⽂件。

—END—

高效学习3D视觉三部曲

第一步 加入行业交流群,保持技术的先进性

目前工坊已经建立了3D视觉方向多个社群,包括SLAM、工业3D视觉、自动驾驶方向,细分群包括:

[工业方向]三维点云、结构光、机械臂、缺陷检测、三维测量、TOF、相机标定、综合群;

[SLAM方向]多传感器融合、ORB-SLAM、激光SLAM、机器人导航、RTK|GPS|UWB等传感器交流群、SLAM综合讨论群;

[自动驾驶方向]深度估计、Transformer、毫米波|激光雷达|视觉摄像头传感器讨论群、多传感器标定、自动驾驶综合群等。

[三维重建方向]NeRF、colmap、OpenMVS、MVSNet等。

[无人机方向]四旋翼建模、无人机飞控等。

除了这些,还有求职、硬件选型、视觉产品落地等交流群。

大家可以添加小助理微信: dddvisiona,备注:加群+方向+学校|公司, 小助理会拉你入群。

a569fc13c55355fa2db1142de4fdeae1.jpeg
添加小助理微信:cv3d007, 拉你入群
第二步 加入知识星球,问题及时得到解答
3.1 「3D视觉从入门到精通」技术星球

针对3D视觉领域的视频课程(三维重建、三维点云、结构光、手眼标定、相机标定、激光/视觉SLAM、自动驾驶等)、源码分享、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答等进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业、项目对接为一体的铁杆粉丝聚集区,6000+星球成员为创造更好的AI世界共同进步,知识星球入口:「3D视觉从入门到精通」

学习3D视觉核心技术,扫描查看,3天内无条件退款 db18c0caed8dd6d355d40aa634237c52.jpeg
高质量教程资料、答疑解惑、助你高效解决问题
3.2 3D视觉岗求职星球

本星球:3D视觉岗求职星球 依托于公众号「3D视觉工坊」和「计算机视觉工坊」、「3DCV」,旨在发布3D视觉项目、3D视觉产品、3D视觉算法招聘信息,具体内容主要包括:

  • 收集汇总并发布3D视觉领域优秀企业的最新招聘信息。

  • 发布项目需求,包括2D、3D视觉、深度学习、VSLAM,自动驾驶、三维重建、结构光、机械臂位姿估计与抓取、光场重建、无人机、AR/VR等。

  • 分享3D视觉算法岗的秋招、春招准备攻略,心得体会,内推机会、实习机会等,涉及计算机视觉、SLAM、深度学习、自动驾驶、大数据等方向。

  • 星球内含有多家企业HR及猎头提供就业机会。群主和嘉宾既有21届/22届/23届参与招聘拿到算法offer(含有海康威视、阿里、美团、华为等大厂offer)。

  • 发布3D视觉行业新科技产品,触及行业新动向。

23515f9fe18f127bdf72d02371f00e6f.jpeg
扫码加入,3D视觉岗求职星球,简历投起来
第三步 系统学习3D视觉,对模块知识体系,深刻理解并运行

如果大家对3D视觉某一个细分方向想系统学习[从理论、代码到实战],推荐3D视觉精品课程学习网址:www.3dcver.com

科研论文写作:

[1]国内首个面向三维视觉的科研方法与学术论文写作教程

基础课程:

[1]面向三维视觉算法的C++重要模块精讲:从零基础入门到进阶

[2]面向三维视觉的Linux嵌入式系统教程[理论+代码+实战]

[3]如何学习相机模型与标定?(代码+实战)

[4]ROS2从入门到精通:理论与实战

[5]彻底理解dToF雷达系统设计[理论+代码+实战]

工业3D视觉方向课程:

[1](第二期)从零搭建一套结构光3D重建系统[理论+源码+实践]

[2]保姆级线结构光(单目&双目)三维重建系统教程

[3]机械臂抓取从入门到实战课程(理论+源码)

[4]三维点云处理:算法与实战汇总

[5]彻底搞懂基于Open3D的点云处理教程!

[6]3D视觉缺陷检测教程:理论与实战!

SLAM方向课程:

[1]深度剖析面向机器人领域的3D激光SLAM技术原理、代码与实战

[2]彻底剖析激光-视觉-IMU-GPS融合SLAM算法:理论推导、代码讲解和实战

[3](第二期)彻底搞懂基于LOAM框架的3D激光SLAM:源码剖析到算法优化

[4]彻底搞懂视觉-惯性SLAM:VINS-Fusion原理精讲与源码剖析

[5]彻底剖析室内、室外激光SLAM关键算法和实战(cartographer+LOAM+LIO-SAM)

[6](第二期)ORB-SLAM3理论讲解与代码精析

视觉三维重建:

[1]彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进

[2]基于深度学习的三维重建MVSNet系列 [论文+源码+应用+科研]

自动驾驶方向课程:

[1] 深度剖析面向自动驾驶领域的车载传感器空间同步(标定)

[2] 国内首个面向自动驾驶目标检测领域的Transformer原理与实战课程

[3]单目深度估计方法:算法梳理与代码实现

[4]面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)

[5]如何将深度学习模型部署到实际工程中?(分类+检测+分割)

无人机:

[1] 零基础入门四旋翼建模与控制(MATLAB仿真)[理论+实战]

最后

1、3D视觉文章投稿作者招募

2、3D视觉课程(自动驾驶、SLAM和工业3D视觉)主讲老师招募

3、顶会论文分享与3D视觉传感器行业直播邀请

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值