C++ 面经(1)

首要注意:平心静气!!!

 

技术面试注意事项:

1、不着急作答,稍微停顿一下,整理自己的思路,尽量不要语无伦次。

2、对于简单一些的问题,尽量不要照本宣科,找准问题回答的角度,争取简单问题回答得比较有亮点。

3、对于相对复杂的问题,或者比较难以阐述的问题,需要多思考一些时间,如果是现场面试,最好用纸笔边画边讲。如果是电话面试,需要多和面试官沟通,不要自顾自的滔滔不绝的讲。

4、对于面试中,被提问到自己不知道的内容,例如区块链等等,至少说点与自己相关的东西的,不要仅仅只说不知道。

5、还有什么问题,例如:我将来在公司能接触到什么技术,我需要作出什么转型,请面试官能不能对我的面试做一下点评,提一些宝贵的经验,我后续复盘可以针对性的提高一下。

 

C++相关问题:

 

1、C++ this指针是干什么用的?

  (1)一个类型定义的很多对象,一般都具有各自的成员变量,但是它们共享一套成员方法。之后在这一套成员方法中,如果存在与成员变量同名的变量,就需要靠this指针进行区分

      速记: 某个类型  --》  很多对象 --》 私有成员变量  --》 共享成员方法  --》 this指针操作的是此时此刻需要调用对象的成员。


 

2、C++ 的 new 和 delete,什么时候用new[] 申请, 可以用 delete 释放

  • (1)new 和 delete 本质上是运算法重载,也就是 operator new 和 operator delete, 当我们在 new[] 时 相应的也会有 delete []ptr 出现。delete 的作用可以概括成两点:1、调用析构函数 2、 释放内存
  • (2)如果是自定义类型,而且提供了析构函数,那么在 new[] 一个新变量时,就一定需要用到delete []ptr 与其匹配 (例如是一个数组内存,delete 就会将数组中的每一个对象进行析构,调用析构 函数时,会传入每一个对象的起始地址

 


 

3、C++ static 关键字的作用

  • (1)从面向过程角度出发, static可以修饰全局变量、函数、局部变量。

    ①普通的全局变量或者函数,在别的文件中,加上 extern 关键字,都可以使用,但是一旦在自己的文件中把全局变量或者函数加上 static 修饰,那么在别的文件中将无法使用。深入剖析来说,当全局变量或者函数被static修饰后,在符号表中它们的作用于就从globe编程了local。

    ②static如果修饰局部变量,这个变量就将被记录到 .data 或者 .bss端,前者是变量初始化所记录的位置,后者是变量未初始化记录的位置,一定是静态变量!同时需要注意,static 局部变量在整个过程中只会被初始化一次,它的声明周期会比函数或是类更长。

                                                                                                        

 

  • (2)从面向对象的角度出发,static可以修饰成员变量,成员方法,一旦用static修饰了前述,那么成员变量或方法将从对象所私有的变为对象公有的,它们均不会产生this指针了。

 


 

3、C++ 的继承(可以说一些优点)

  • (1)一般用来描述类与类之间的关系,类和类之间除了继承还具有组合关系,继承:a kind of,组合:a part of,继承能够使得代码的复用更加简便高效
  • (2)通过继承,在基类中可以给所有派生类保留统一的纯虚函数接口,等待派生类进行重写,通过使用多态,可以使得基类指针访问不同派生类对象的同名覆盖方法。

    ①虚函数:虚函数一般是用virtual修饰的函数,虚函数的主要特点概括为8个字:类似接口,实现多态

       当我们想子类 b 实例化一个父类对象 a 时,如果父类子类包含同名函数 fun ,在不加 virtual 的情况下,调用该方法时是进行的a.fun() 操作,如果加virtual 则是进行 b.fun()操作

    ②纯虚函数:一般以这种形式存在: virtual <类型><函数名>(<参数表>)=0; 纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。

 


4、C++ 的继承多态, 空间配置器, vector 和 list的区别, map 和 多重map的区别

  • 多态:静(编译时期)多态:函数重载和模板。   动(运行时期)多态:虚函数 指针/引用派生类对象
  • 空间配置器allocator:给容器使用的,主要作用是把内存开辟和对象构造区分开来,把内存释放和对象析构区分开来
  • vecotr和list的区别:数组和链表的区别,vector随机访问多(优先队列的实现基于vecotr),list适用于频繁增加删除
  • map和multimap:map不允许有重复key值,数据是以[key-value]形式存储,底层实现是红黑树,multimap允许key值重复

  红黑树性质:

    ①

    ②


 

4、C++ 如何防止内存泄漏? 以及智能指针详述。

内存泄漏:一般是指分配的堆内存(没有名字,智能用指针来指向)没有释放,之后也没有机会进行释放了。

例如:

  int* p = new int[1000]

  if(xxx){

    return;

  }

  delete []p;

智能指针:智能指针利用的就是栈上的对象一旦出了它的作用域就自动析构该指针,可以在其析构函数中就把资源进行释放。官方性的总结有以下两个特点:

                                                                                          

 

    ① 不需要显式地释放资源。 

    ② 采用这种方式,对象所需的资源在其生命期内始终保持有效

    ③ 智能指针会延申出几个问题:

        1)带引用和不带引用计数的智能之间有什么区别?

        2)带引用计数的智能指针有什么好处?是否线程安全?带引用计数的指针指针分强智能指针和弱智能指针,它们是依据什么区分的,什么情况下使用,以及交叉引用问题                             怎么解决?

        3)使用不带引用计数的智能指针时推荐使用哪个,为什么?

 

    智能指针具有如下类型(不带引用计数:auto_ptr/scoped_ptr/unique_ptr  带引用计数:shared_ptr/weak_ptr):

    ① auto_ptr:  98版的智能指针,原对象一旦拷贝给新对象时,原对象就会被置为nullptr,但是一旦再使用原来的对象的话,由于原来对象为nullptr,就会导致程序的崩溃,所以一般不                  会用到这个版本比较老的智能指针。

    ②unique_ptr:属于C++11,它直接会将指针的拷贝构造函数和赋值函数禁用,防止有指针间相关联的情况。

int main(){
    unique_ptr<int> ptr1(new int);
    unique_ptr<int> ptr2(ptr1);           // 错误,无法调用其拷贝构造
    unique_ptr<int> ptr3(new int);
    ptr3 = ptr2;  // 错误,无法调用其赋值函数  

    return 0
}

 

    ③shared_ptr:属于C++11,其允许多个智能指针指向同一个资源快,并且能够保证共享的资源只会被释放一次,这个要和auto_ptr作区别关联记忆。

      shared_ptr具有如下特点:

        1) shared_ptr在内部会维护一个计数引用,用来记录该份资源被几个对象共享。

        2)当一个shared_ptr对象被销毁时,析构函数内部就会将该技术引用减1

        3)如果引用计数为0,则表示自己是最后一个使用该资源的shared_ptr对象,必须释放该资源。

        4)如果引用计数不为0,表示还有其他对象在使用,该资源不能被释放,否则将变为野指针。

        5)如果是在多线程上修改shared_ptr时,就会出现计数指针不稳定的情况,这时候就要考虑加锁

int main(){
    shared_ptr<int> ptr1(new int(2));
    cout << ptr1.get() << endl;
    shared_ptr<int> ptr2 = ptr1;
    cout << ptr2.get() << endl;
    cout << ptr1.get() << endl;    

    return 0;
}

 

 

6、什么是右值引用。

1)右值引用的概念有些读者可能会感到陌生,其实他和C++98/03中的左值引用有些类似,例如,在c++98/03中的左值引用是这样的:

 1 int i = 0;

2 int& j = i; 

这里的int&是对左值进行绑定(但是int&却不能绑定右值),相应的,对右值进行绑定的引用就是右值引用,他的语法是这样的A&&,通过双引号来表示绑定类型为A的右值。通过&&我们就可以很方便的绑定右值了,比如我们可以这样绑定一个右值:

 1 int&& i = 0; 

这里我们绑定了一个右值0,关于右值的概念会在后面介绍。右值引用是C++11中新增加的一个很重要的特性,他主是要用来解决C++98/03中遇到的两个问题,第一个问题就是临时对象非必要的昂贵的拷贝操作,第二个问题是在模板函数中如何按照参数的实际类型进行转发。通过引入右值引用,很好的解决了这两个问题,改进了程序性能。


具体参考博客:https://blog.csdn.net/CHEN6329986/article/details/124710942

posted @ 2022-06-07 23:09  炫迈吃到爽  阅读(30)  评论(0编辑  收藏  举报