首页 > 编程语言 >c++面试八股文(大公司通用)

c++面试八股文(大公司通用)

时间:2024-09-13 17:25:53浏览次数:9  
标签:std 八股文 函数 回答 内存 C++ 面试 c++ 指针

在C++面试中,常见的问题通常会围绕C++的基础知识、数据结构与算法、系统设计、编程技巧、以及实际应用中的场景。以下是华为C++面试中常见的“八股文”问题及其简要回答思路。

1. C++语言基础

  • C++中const的用法有哪些? 回答

    • 常量变量const int a = 10;
    • 指针常量const int* p;(指向常量的指针),int* const p;(指针本身是常量)
    • 成员函数常量void func() const; 保证成员函数不能修改类中的数据成员。
    • 常量引用:用于引用常量对象。
  • C++中构造函数和析构函数的执行顺序? 回答

    • 构造函数按继承层次从基类到派生类执行,析构函数相反,从派生类到基类。
    • 成员对象的构造顺序按照声明顺序执行,析构顺序相反。
  • C++中this指针的作用是什么? 回答

    • this是指向当前对象的指针,在类的非静态成员函数中隐式传递,用于访问类的成员。
  • C++中的深拷贝与浅拷贝区别? 回答

    • 浅拷贝:拷贝对象的所有字段,指针仍指向同一块内存。
    • 深拷贝:拷贝指针指向的内存,即创建新内存并复制内容,避免多对象共用同一内存。

2. 面向对象编程

  • C++的多态性是如何实现的? 回答

    • 多态通过虚函数实现。基类定义虚函数,派生类重写该虚函数。通过基类指针或引用调用派生类的实现。
    • 虚函数通过虚函数表(vtable)和虚指针(vptr)实现动态绑定。
  • 什么是虚析构函数,为什么需要它? 回答

    • 虚析构函数确保通过基类指针删除派生类对象时,派生类的析构函数能够被正确调用,防止内存泄漏。
  • 接口类和抽象类的区别是什么? 回答

    • 接口类:所有成员函数都是纯虚函数,用来定义接口,通常没有数据成员。
    • 抽象类:包含至少一个纯虚函数,但可以有普通函数或成员变量。

3. C++内存管理

  • C++中内存分配方式有哪些? 回答

    • 栈内存:函数内部定义的局部变量,自动分配和释放。
    • 堆内存:使用new/delete进行动态分配和释放。
    • 全局/静态内存:全局变量和静态变量,程序开始时分配,结束时释放。
    • 常量存储区:存放常量数据。
  • 智能指针的作用和类型? 回答

    • 作用:自动管理堆内存,防止内存泄漏。
    • 类型
      • std::unique_ptr:独占所有权。
      • std::shared_ptr:共享所有权,引用计数机制。
      • std::weak_ptr:弱引用,不影响引用计数,防止循环引用。
  • C++中的RAII机制是什么? 回答

    • 资源获取即初始化,利用对象的构造函数获取资源,在析构函数中释放资源,确保资源安全管理。典型应用是智能指针的自动内存管理。

4. STL(标准模板库)

  • STL中的常见容器有哪些?其特点是什么? 回答

    • vector:动态数组,支持随机访问,内存是连续的。
    • list:双向链表,支持高效插入和删除,内存不连续。
    • map:基于红黑树实现的有序键值对,支持O(log n)时间复杂度的查找。
    • unordered_map:基于哈希表实现的无序键值对,查找速度接近O(1)。
    • deque:双端队列,支持头尾高效插入删除。
  • 如何选择合适的STL容器? 回答

    • 如果需要随机访问,选择vector
    • 如果插入删除操作频繁且顺序不重要,选择list
    • 如果需要键值对且要求有序,选择map
    • 如果键值对不要求有序,选择unordered_map
    • 如果需要双端操作,选择deque
  • STL中迭代器失效问题是什么?如何避免? 回答

    • 在使用vectorlist等容器时,元素的插入或删除可能会使得指向这些元素的迭代器失效。
    • 解决办法:在vector中避免在迭代过程中添加或删除元素;或者通过list这样的链表容器来减少迭代器失效。

5. 多线程编程

6. 算法与数据结构

7. 系统设计与实际应用

  • 如何在C++中创建和管理线程? 回答

    • 使用C++11的std::thread类创建线程。
    • 线程函数可以是普通函数、成员函数或lambda表达式。
    • 使用join()来等待线程结束,或detach()将其分离。
    std::thread t1([]{ std::cout << "Hello from thread"; });
    t1.join();  // 等待线程结束
    

  • 如何保证多线程的安全性? 回答

    • 使用std::mutex互斥锁保护共享资源,避免数据竞争。
    • 使用std::lock_guardstd::unique_lock自动管理锁的生命周期,减少手动加锁和解锁的出错机会。
  • C++中的死锁是什么?如何避免? 回答

    • 死锁是指两个或多个线程互相等待对方释放资源,从而导致程序无法继续执行。
    • 避免方法
      1. 以固定顺序锁定多个资源。
      2. 使用std::try_lock避免阻塞。
      3. 尽量减少锁的粒度和持有时间。
  • 如何实现链表的逆序? 回答: 使用三个指针遍历链表,逐个反转指针方向:

    ListNode* reverseList(ListNode* head)
    {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr != nullptr)
        {
            ListNode* nextTemp = curr->next;
            curr->next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }
    

  • 如何判断一个链表是否有环? 回答

    • 使用快慢指针(Tortoise and Hare算法)。快指针一次移动两步,慢指针一次一步,如果链表有环,两个指针最终会相遇。
  • 常见排序算法及其时间复杂度? 回答

    • 冒泡排序:O(n^2),交换相邻元素。
    • 选择排序:O(n^2),每次选最小元素放到前面。
    • 插入排序:O(n^2),逐个插入到有序序列中。
    • 快速排序:O(n log n),基于分治法,通过选择基准元素分区。
    • 归并排序:O(n log n),基于分治法,递归地分割和合并。
  • 如何设计一个线程安全的单例模式? 回答: 使用C++11之后的std::call_once或静态局部变量:

    class Singleton
    {
    public:
        static Singleton& getInstance()
        {
            static Singleton instance;
            return instance;
        }
    private:
        Singleton() {}
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
    };
    

    如何实现生产者-消费者模型? 回答: 使用std::mutexstd::condition_variable来协调生产者和消费者的工作,确保线程安全。

    std::queue<int> buffer;
    std::mutex mtx;
    std::condition_variable cv;
    
    void producer()
    {
        std::unique_lock<std::mutex> lock(mtx);
        buffer.push(1);
        cv.notify_one();  // 通知消费者
    }
    
    void consumer()
    {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !buffer.empty(); });
        int item = buffer.front();
        buffer.pop();
    }
    

    8. 常见陷阱与优化

  • C++中的对象切割是什么? 回答

    • 对象切割发生在当子类对象通过基类传递或赋值时,子类特有的部分被切割掉,只剩下基类的部分。
    • 解决方法是使用指针或引用来传递对象,避免拷贝。
  • C++中的空指针异常如何避免? 回答

    • 在访问指针前检查指针是否为nullptr
    • 使用智能指针自动管理内存,避免手动释放未初始化或已释放的指针。

标签:std,八股文,函数,回答,内存,C++,面试,c++,指针
From: https://blog.csdn.net/scm06111/article/details/142216069

相关文章

  • 《C++编程规范》六、构造、析构与复制
    目录第47条以同样的顺序定义和初始化成员变量使用这些函数之所以需要小心,其中一个原因是几乎一半的情况下编译器都会为我们生成代码。另一个原因是,C++默认时总是将类当作类似于值的类型,但是实际上并非所有的类型都类似于值(见第32条)。知道何时应该显式地编写(或者禁止)这些特殊......
  • ros 自定义消息(图像+标志位+位姿)python和c++发布和接受
      编译 脚本 v3_gaosi_img_pose_flag.sh#!/bin/bash#外部给与执行权限#sudochmod+xrun_ros_nodes.sh#定义ROS安装路径#安装时候添加到系统路径了不需要每次都sourceROS_SETUP="/opt/ros/noetic/setup.bash"#定义工作目录路径自己的工程没有加到系......
  • 吊打面试官!从多维度理解架构
    大家好,我是汤师爷~在工作当中,我们经常会听到以下说法:产品负责人说,现在的业务架构太复杂,需要仔细梳理下。技术领导说,这个项目很复杂,需要做下系统架构方案评审。研发经理说,这次秒杀活动访问量非常大,需要用到高并发架构方案。一线研发说,互联网大厂都会用到微服务架构,我要学学微......
  • 面试-运行环境-网页渲染
    网页加载过程网页是如何加载并渲染出来的从输入url到渲染出页面的整个过程(经典题来了)资源有哪些形式加载的大致过程请求啥就是返回啥,图片、音频都有可能。请求的是页面则返回HTML代码。渲染过程-①RenderTree:渲染树,每个节点挂了很多CSS属性,这样就能渲染......
  • Java面试随手记3
    一、面试题总结31、mysql中char和varchar的区别?特性charvarchar存储方式定长,长度不足时填充空格可变长,按实际长度存储存储效率固定空间,浪费内存根据实际长度动态分配性能较高,适合固定长度数据稍低,适合不定长度数据适用场景固定长度的字符串不定长度的字符串空格处理自动去......
  • 面试-JS Web API - 存储
    cookieHTML5存储(localStorage和sessionStorage)cookiecookie本身用于浏览器和server通讯的,被借用到本地存储来。可以用document.cookie来修改。同一个变量会覆盖,不同变量会追加。localStorage和sessionStorage//保存数据到localStoragelocalStorage.getItem('a......
  • 面试004
    1、自动化测试框架具体如何实现介绍整体技术名词:框架使用到了pytest、allure、jsonpath等技术实现框架搭建框架底层执行逻辑:根据执行选项读取测试用例信息Pytest插件用于读取测试用例信息并根据需要动态生成测试用例。最终按照编写的测试用例流程模板,执行用例具体执行......
  • C++--模板
    1泛型编程如何将Swap实现乘成一个通用的交换函数voidSwap(int&left,int&right){inttemp=left;left=right;right=temp;}voidSwap(double&left,double&right){doubletemp=left;left=right;right=temp;}voidSwap......
  • 面试-JS Web API-Linux命令
    关键Linux命令虽然前端开发者不需要掌握Linux的所有命令,但以下基本的命令对日常工作是非常有用的:文件和目录管理ls:列出当前目录下的文件和文件夹。lsls-l#显示详细信息ls-a#显示隐藏文件cd:切换目录。cd/path/to/directorycd..#返回上一级目录pwd:显......
  • 面试官:线程池遇到未处理的异常会崩溃吗?
    首先,这个问题考察的是你对线程池execute方法和submit方法的理解,在Java线程池的使用中,我们可以通过execute方法或submit方法给线程池添加任务,但如果线程池中的程序在执行时,遇到了未处理的异常会怎么呢?接下来我们一起来看。1.execute方法execute方法用于提交一个不需要......