大厂常见面试题----C++篇(1)

1.C++内存分布?

(1)栈区

由编译器自动分配释放,存储函数的参数值,局部变量值等,其操作方法类似于数据结构中的栈。
程序自动向操作系统申请分配以及回收,速度快,使用方便,但是程序员无法控制,如果分配失败,抛出栈溢出错误

注意:const局部变量也存储在栈区,栈区向地址减少的方向增长;
系统为变量在栈上申请内存后,CPU需要不断地判断变量是否已结束使用的生命周期,如果生命周期结束,系统就会释放这个变量申请的栈内存,这样一来随着在栈上申请的变量增多,会对cpu 造成额外的 消耗

(2)堆区

一般由程序员申请和释放,与数据结构中的堆没有任何关系,分配方式类似于链表。

程序员向操作系统申请一段内存,当系统收到程序的申请时,会遍历一个记录空间内存节点的链表,找到第一个空间大于或等于所申请空间的堆节点,将该空闲节点从链表中删除,并将该节点的空间分配给程序,如果链表中空闲节点的空间大于申请空间的大小,系统会自动将对于的部分放入空闲链表中,故容易造成内存的碎片化,分配速度较慢,地址不连续。

注意:程序员申请的内存必须由程序员负责释放,否则会导致内存泄漏,堆得增长方向与内存地址的增长方向相同,因此堆区上申请空间理论上是没有大小限制的,但是受安装内存条的大小和系统以及其他程序的占用,不是无限大的 程序员申请在堆上的内存,是由程序员自己管理的,不像栈上的变量一样,需要消耗CPU资源判断变量的生命周期,所以不会对CPU造成额外的消耗,这也是程序员申请堆上内存的优点。

(3)全局/静态区

全局变量和静态变量是存储在一起的,在程序编译时分配

(4)文字常量区

存储常量字符串

(5)程序代码区

存储函数体(类的成员函数,全局函数)的二进制代码

2.虚函数索引机制底层?

虚函数是依赖一张虚函数表(vtable),由编译器生成并存放在某处,程序运行时会将该地址存放在对象中。在真正调用的时候会先通过存储在对象中的虚函数表的地址,寻找真正的调用成员函数的地址。

这也知道了为什么虚函数机制会带来更多的开销,当触发虚函数时,首先要取得存储在对象中的虚函数地址,这里需要一次内存寻址,然后通过该地址取得真正要调用的函数的地址,这里又是一次内存寻址,之后才开始进行真正的函数调用。因此我们不能过分的依赖虚函数机制,在类型明确的情况下更适合于直接调用。

3.Vector和list的区别?

(1)

list是由双向链表实现的,内存空间是不连续的;优点是插入和删除的效率较高,只需要在插入的地方更改指针的指向即可,不用移动数据;缺点是list查询效率较低,时间复杂度为O(n)

(2)

vector拥有一段连续的内存空间,并且起始地址不变;优点是便于随机访问,时间复杂度为O(1);缺点是因为内存空间是连续的,所以在插入和删除操作时,会造成内存块的拷贝,时间复杂度为O(n);

4.构造函数为什么不能用virtual?

虚表根据实例生成,构造函数之前未生成虚表不能使用virtual

5.右值引用?

定义右值引用需要&&;右值引用一定不能初始化,只能用右值初始化,右值引用的目的是为了延长初始化对象的生命周期,对于左值,其生命周期与其作用域有关,没有必要去延长;右值引用还可以用于传参数;右值引用主要是为了使用std::move函数,这个函数是实现对象的移动,std::swap是复制拷贝,但是移动不是对象的复制,可以大大降低内存的消耗

template <typename T>
typename remove_reference<T>::type&& move(T&& param)
{
    using ReturnType = typename remove_reference<T>::type&&;

    return static_cast<ReturnType>(param);
}

6.右值引用的场景?

当一个类拥有一个资源(普通指针进行管理),那么拷贝成员函数就必须拷贝这个资源,但是拷贝资源会导致一些额外的开销。但是这种拷贝情况并不是必须的,可以通过定义移动构造函数和移动赋值运算符就可以避免这个问题。而移动成员的参数就必须是一个右值引用类型。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些常见C++大厂面试题及其解答: 1. 什么是多态?如何实现多态? 多态是指同一种操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。在C++中,实现多态有两种方式:虚函数和模板。 - 虚函数 在基类中定义虚函数,派生类可以重写该虚函数。当用基类指针或引用调用该虚函数时,实际调用的是派生类中的函数。这种方式称为动态多态。 - 模板 模板是一种编译期多态性,允许类型参数化。通过模板可以实现函数或类的通用性,同时保持代码的安全性和可读性。这种方式称为静态多态。 2. 什么是智能指针?如何使用智能指针? 智能指针是一种封装了指针的对象,可以自动管理内存,避免内存泄漏和空指针引用等问题。C++11中提供了三种智能指针:unique_ptr、shared_ptr和weak_ptr。 - unique_ptr unique_ptr是独占式智能指针,用于管理一个对象的内存。它不能被复制,只能通过移动语义转移所有权。当unique_ptr超出作用域或被显式删除时,它所管理的对象会被自动销毁。 - shared_ptr shared_ptr是共享式智能指针,多个shared_ptr可以共享同一个对象的内存,当最后一个shared_ptr被销毁时,才会释放内存。通过控制块来记录当前有多少个shared_ptr指向同一个对象。 - weak_ptr weak_ptr是弱引用智能指针,它可以用于解决shared_ptr的循环引用问题。weak_ptr不拥有对象的所有权,只是提供了一种安全的访问方式。 使用智能指针时需要注意避免循环引用和空指针引用等问题。 3. 什么是虚函数?虚函数有什么作用? 虚函数是一种动态绑定的函数,用于实现多态。在基类中定义虚函数,在派生类中可以重写该虚函数。当用基类指针或引用调用该虚函数时,实际调用的是派生类中的函数。 虚函数的作用在于实现多态,使得程序可以在运行时根据对象的实际类型来调用适当的函数。这样可以提高代码的灵活性和可扩展性。 4. 什么是纯虚函数?如何使用纯虚函数? 纯虚函数是一种没有实现的虚函数,在基类中定义纯虚函数,派生类必须重写该函数才能使用。纯虚函数用于定义接口,让派生类来实现具体的功能。 定义纯虚函数可以在函数声明后加上`=0`,如下所示: ```cpp virtual void func() = 0; ``` 使用纯虚函数可以强制规定派生类必须实现某些函数,从而实现多态和接口声明的功能。 5. 什么是模板?如何使用模板? 模板是一种泛型编程技术,通过参数化类型和函数来实现通用性。模板可以实现函数或类的通用性,同时保持代码的安全性和可读性。 在C++中,定义模板可以使用关键字template和typename或class。模板可以有多个参数,可以是类型参数或非类型参数。 模板的使用可以通过实例化来完成,即在模板名后加上具体的类型或值。例如: ```cpp template<typename T> void func(T arg) { ... } func<int>(5); ``` 6. 什么是STL?STL中包含哪些容器?如何使用STL容器? STL是标准模板库的缩写,是C++中的一个重要库,提供了一系列容器、算法和迭代器等工具,用于简化程序开发。 STL中包含以下容器: - 序列式容器:vector、list、deque、array、forward_list - 关联式容器:set、map、multiset、multimap、unordered_set、unordered_map、unordered_multiset、unordered_multimap - 容器适配器:stack、queue、priority_queue 使用STL容器可以通过头文件`<container>`和`<algorithm>`来实现。例如: ```cpp #include <vector> #include <algorithm> using namespace std; vector<int> vec = {1, 2, 3, 4, 5}; sort(vec.begin(), vec.end()); ``` 7. 什么是RAII?如何使用RAII? RAII是资源获取即初始化的缩写,是一种C++编程技术,用于自动管理资源的生命周期。RAII的核心思想是:在对象的构造函数中获取资源,在对象的析构函数中释放资源。 使用RAII可以避免资源泄漏和空指针引用等问题,提高代码的可读性和可靠性。一般情况下,RAII可以通过智能指针、文件句柄、锁等方式来实现。 例如,使用智能指针实现RAII可以如下所示: ```cpp class MyObj { public: MyObj() { ... } ~MyObj() { ... } }; void func() { unique_ptr<MyObj> ptr(new MyObj()); // ... } ``` 当`func()`函数执行完毕时,`ptr`指向的对象会被自动销毁,从而释放资源。 以上是一些常见C++大厂面试题及其解答,希望对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值