当前位置: 首页 > news >正文

C++ 面试模拟02

第一部分:基础知识

  1. 什么是拷贝构造函数和赋值运算符?它们之间有什么区别?
  2. 在 C++ 中,const 关键字的作用是什么?有哪些常见用法?
  3. C++ 中的内存管理机制是怎样的?如何避免内存泄漏?
  4. 虚函数(virtual function)的作用是什么?虚函数表(vtable)是如何工作的?

第二部分:面向对象编程

  1. 什么是多态性?C++ 中如何实现运行时多态?
  2. 请解释什么是继承以及继承的优缺点。
  3. C++ 中的“菱形继承”是什么?如何通过虚继承来解决它带来的问题?
  4. 什么是抽象类?抽象类与接口类有何不同?

第三部分:STL(标准模板库)

  1. std::vectorstd::list 有什么区别?它们各自的优点和缺点是什么?
  2. 什么是迭代器?有哪些类型的迭代器?
  3. std::mapstd::unordered_map 的底层实现分别是什么?性能有何差异?
  4. C++ 中的容器适配器有哪些?请举例说明。

第四部分:并发与多线程

  1. C++ 中如何创建线程?有哪些常见的线程管理方式?
  2. 什么是互斥锁(mutex)?如何避免死锁?
  3. 解释一下条件变量(condition variable)的作用,并给出一个简单的使用例子。
  4. 什么是线程局部存储(Thread Local Storage)?在 C++ 中如何使用?

第五部分:C++ 高级特性

  1. 什么是移动语义?C++11 中如何实现移动构造函数与移动赋值运算符?
  2. C++20 中的协程(coroutine)是什么?它们是如何工作的?
  3. 模板元编程(Template Metaprogramming)是什么?在 C++ 中有哪些实际应用?
  4. 什么是 SFINAE?在模板中如何利用 SFINAE 进行类型选择?

第六部分:现场编程

题目:

请你实现一个线程安全的计数器类 ThreadSafeCounter,它支持以下功能:

  • increment():计数器加 1
  • decrement():计数器减 1
  • get():返回当前计数器的值

要求:

  • 使用 std::mutex 保证线程安全。
  • 实现拷贝构造和赋值运算符重载。

答案:

C++知识点/面试问题指南-CSDN博客

第一部分:基础知识

  1. 拷贝构造函数和赋值运算符的区别

    • 拷贝构造函数:当用一个对象初始化另一个新对象时调用,用于对象的创建。
    • 赋值运算符:在已存在对象的基础上,将另一个对象的内容赋值给它。
    • 区别:拷贝构造函数是在对象初始化时调用的,赋值运算符则在对象已经创建后进行赋值。
  2. const 关键字的作用

    • 修饰变量:表示该变量的值不能修改。
    • 修饰指针:区分指针本身是否可变和指向的对象是否可变。
    • 修饰成员函数:表示该成员函数不会修改类的成员变量。
  3. 内存管理

    • C++ 使用动态分配(new/delete)、栈分配以及 RAII(资源获取即初始化)来管理内存。
    • 避免内存泄漏的方法包括使用智能指针(如 std::shared_ptrstd::unique_ptr)。
  4. 虚函数和 vtable

    • 虚函数:用于实现运行时多态,基类中标记为 virtual 的函数可以在派生类中被重写。
    • 虚函数表(vtable):编译器为包含虚函数的类创建一个表,指向虚函数的地址,保证在运行时能够调用正确的函数。

第二部分:面向对象编程

  1. 多态性

    • C++ 中通过虚函数实现运行时多态。基类的虚函数可以在派生类中重写,通过基类指针或引用调用时,动态地选择合适的派生类实现。
  2. 继承

    • 优点:允许代码重用和扩展基类功能。
    • 缺点:不当的使用可能导致强耦合,难以维护。
  3. 菱形继承和虚继承

    • 菱形继承:如果一个类从多个基类继承,而这些基类又继承自同一祖先类,会导致多个基类有相同的祖先成员。
    • 虚继承:通过 virtual 继承,确保继承链中的祖先类只会有一份副本。
  4. 抽象类

    • 抽象类:至少包含一个纯虚函数(= 0 的函数)。不能实例化,只能被继承。
    • 接口类:所有成员函数都为纯虚函数。

第三部分:STL

  1. std::vectorstd::list 区别

    • std::vector:基于动态数组,支持随机访问,插入/删除代价高(中间位置)。
    • std::list:基于双向链表,不支持随机访问,插入/删除较快。
    • 优缺点vector 适合频繁随机访问,list 适合频繁插入/删除。
  2. 迭代器的类型

    • 输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。
  3. std::map vs std::unordered_map

    • std::map:基于红黑树(有序),O(log n) 查找。
    • std::unordered_map:基于哈希表(无序),O(1) 平均查找,但最坏情况 O(n)。
  4. 容器适配器

    • 包括 std::stackstd::queuestd::priority_queue,它们通过封装其他容器(如 dequelist)实现特定的行为。

第四部分:并发与多线程

  1. 线程的创建

    • 使用 std::thread 创建线程:
std::thread t([] { std::cout << "Thread is running"; });
t.join();  // 等待线程结束
  • 互斥锁(mutex)与死锁

    • 互斥锁std::mutex 用于保护共享资源避免数据竞争。通过 std::lock_guardstd::unique_lock 自动管理锁。
    • 避免死锁:使用相同顺序加锁,或者使用 std::lock() 同时加锁多个资源。
  • 条件变量

    • 用于线程间同步,等待特定条件:
std::condition_variable cv;
std::mutex mtx;
bool ready = false;
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [&ready] { return ready; });

线程局部存储

  • 使用 thread_local 关键字为每个线程定义独立的存储空间:
thread_local int x = 0;  // 每个线程都有自己独立的 x 变量

第五部分:C++ 高级特性

  1. 移动语义

    • 移动语义通过 移动构造函数移动赋值运算符 避免不必要的深拷贝,使用 std::move 来将对象转化为右值引用,从而实现资源的转移而不是复制。
  2. C++20 协程

    • 协程通过 co_awaitco_yieldco_return 实现协程的控制流,用来处理异步任务和生成器。
    • 使用例:
std::future<int> asyncAdd(int a, int b) {co_return a + b;
}
  • 模板元编程

    • 通过模板递归和模板特化实现编译期计算。常见应用包括类型萃取(type traits)和元函数。
  • SFINAE

    • 在模板中,"Substitution Failure Is Not An Error" 规则允许在匹配失败时尝试其他模板。常用于限制模板特化。
template<typename T>
std::enable_if_t<std::is_integral<T>::value, T> add(T a, T b) { return a + b; }

第六部分:现场编程

#include <iostream>
#include <mutex>class ThreadSafeCounter {
private:int counter;std::mutex mtx;public:ThreadSafeCounter() : counter(0) {}// 增加计数void increment() {std::lock_guard<std::mutex> lock(mtx);++counter;}// 减少计数void decrement() {std::lock_guard<std::mutex> lock(mtx);--counter;}// 获取当前计数int get() const {std::lock_guard<std::mutex> lock(mtx);return counter;}// 拷贝构造函数ThreadSafeCounter(const ThreadSafeCounter& other) {std::lock_guard<std::mutex> lock(other.mtx);counter = other.counter;}// 赋值运算符ThreadSafeCounter& operator=(const ThreadSafeCounter& other) {if (this != &other) {std::lock_guard<std::mutex> lockThis(mtx);std::lock_guard<std::mutex> lockOther(other.mtx);counter = other.counter;}return *this;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【AI创作组】Matlab中进行符号计算
  • 【目标检测】隐翅虫数据集386张VOC+YOLO
  • 【ArcGIS微课1000例】0122:经纬网、方里网、参考格网绘制案例教程
  • UE4_后期处理七—仿红外线成像效果
  • MIME 类型
  • Ubuntu环境切换到服务器某个用户后source等命令和Tab快捷补全都用不了了,提示没找到,但root用户可以
  • java并发编程笔记 之 线程和进程
  • Unity 的Event的Use()方法
  • 太速科技-383-基于kintex UltraScale XCKU060的双路QSFP+光纤PCIe 卡
  • Java后端中的复杂查询优化:索引设计与SQL调优的结合
  • 个人计算机与网络的安全
  • 【JavaScript】LeetCode:51-55
  • Vue实战教程:手动封装一个全局可自定义图标提示组件
  • 企业如何高效应对多类型知识产权事务的复杂挑战?
  • Vue中集中常见的布局方式
  • 2017-08-04 前端日报
  • Akka系列(七):Actor持久化之Akka persistence
  • Android 架构优化~MVP 架构改造
  • Angular 4.x 动态创建组件
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • JavaWeb(学习笔记二)
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Mocha测试初探
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • 跨域
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 前端_面试
  • 入口文件开始,分析Vue源码实现
  • 手机端车牌号码键盘的vue组件
  • 算法-插入排序
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 网络应用优化——时延与带宽
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​低代码平台的核心价值与优势
  • #git 撤消对文件的更改
  • #Linux(make工具和makefile文件以及makefile语法)
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (~_~)
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (zhuan) 一些RL的文献(及笔记)
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (三)Kafka离线安装 - ZooKeeper开机自启
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)人的集合论——移山之道
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .config、Kconfig、***_defconfig之间的关系和工作原理
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET Core 中插件式开发实现
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @RequestParam详解
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码