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

C++技术岗面试经验总结

胖咕噜的稞达鸭个人主页 个人专栏: 《数据结构》《C初阶高阶》《Linux系统学习》《算法日记》⛺️技术的杠杆撬动整个世界!1. 右值引用和左值引用的区别左值是我们平常使用的函数对象表达式结束后依旧存在的持久对象右值是表达式结束后就会销毁的临时对象。左值引用T主要用于绑定左值本质是给变量取别名常用于函数传参避免拷贝。右值引用T用于绑定右值主要目的是实现移动语义不复制资源本质上是转移资源的所有权提高性能。在实际使用中右值引用通常会配合std::move使用。需要注意的是std::move本质上只是一个类型转换它将左值转换为右值引用使对象可以被移动但并不会真正移动资源。补充几点关键规则右值引用不能绑定左值但可以通过std::move转换。左值引用不能直接绑定右值但const T可以。右值引用变量本身是左值。右值引用的核心价值是减少拷贝提高性能。1.1 手写 string 类实现构造函数、移动构造和移动赋值#includeiostream#includecstringusingnamespacestd;classMyString{public:// 1. 构造函数MyString(constchar*str){_sizestrlen(str);_datanewchar[_size1];strcpy(_data,str);cout构造函数endl;}// 2. 析构函数~MyString(){delete[]_data;_datanullptr;_size0;cout析构函数endl;}// 3. 拷贝构造MyString(constMyStringother){_sizeother._size;_datanewchar[_size1];strcpy(_data,other._data);cout拷贝构造endl;}// 4. 拷贝赋值MyStringoperator(constMyStringother){cout拷贝赋值endl;if(this!other){delete[]_data;_sizeother._size;_datanewchar[_size1];strcpy(_data,other._data);}return*this;}// 5. 移动构造MyString(MyStringother)noexcept{_dataother._data;_sizeother._size;other._datanullptr;other._size0;cout移动构造endl;}// 6. 移动赋值MyStringoperator(MyStringother)noexcept{cout移动赋值endl;if(this!other){delete[]_data;_dataother._data;_sizeother._size;other._datanullptr;other._size0;}return*this;}voidprint()const{cout(_data?_data:nullptr)endl;}private:char*_data;size_t _size;};2. 智能指针有哪些C11 中主要有三种智能指针unique_ptr独占所有权不允许拷贝shared_ptr共享所有权使用引用计数管理资源weak_ptr弱引用不增加引用计数主要用于解决循环引用问题unique_ptr和shared_ptr区别unique_ptr是独占所有权同一时间只能有一个指针指向资源不能拷贝只能移动。shared_ptr是共享所有权通过引用计数来管理资源多个指针可以指向同一对象。它的引用计数是线程安全的原子操作但是对象本身不是线程安全的。当引用计数为 0 时自动释放资源。为什么要有智能指针在传统的 C 编程中用new申请一块内存空间最后要用delete释放这块内存空间。当我们忘记delete或者delete没有正常执行的时候就会造成内存泄漏。更本质的问题在于C 是手动管理内存的如果程序在执行过程中发生异常、提前返回或者逻辑分支复杂就可能导致delete没有被执行。为了解决这个问题C 引入了RAII机制 和 智能指针通过对象生命周期自动管理资源从而避免内存泄漏。3. 什么是 RAII 机制RAII 通过“对象构造时获取资源对象析构时释放资源”的机制将所有需要手动管理的资源内存、文件、锁等与对象生命周期绑定从而从根源上避免资源泄漏包括异常场景下的泄漏。智能指针满足了 RAII 的设计思路还方便资源的访问。智能指针代管资源模拟指针的行为访问和修改资源。RAII只能管理内存吗RAII不仅用于内存管理还广泛应用于各种资源的管理。例如文件句柄、数据库连接和锁等资源都可以通过RAII进行管理。文件句柄可以通过自定义类或智能指针在对象析构时自动关闭文件。锁使用std::lock_guard或std::unique_lock来自动加锁和解锁避免死锁和忘记释放锁的情况。数据库连接可以使用RAII来确保数据库连接在操作结束后自动关闭避免连接泄漏。4. 智能指针会引发什么问题4.1 循环引用问题shared_ptr采用引用计数的方式管理对象生命周期。正常情况下当引用计数减为0时对象会被自动释放。但是如果两个对象互相持有对方的shared_ptr就会形成循环引用。一旦形成循环引用这两个对象的引用计数都无法降为0最终导致对象不能被释放从而产生内存泄漏。4.2 为什么会发生内存泄漏原因在于shared_ptr会让引用计数加1对象之间互相持有shared_ptr即使外部的shared_ptr已经销毁对象内部仍然彼此引用所以引用计数始终不为0析构函数无法被调用资源也就无法释放4.3 如何解决循环引用问题解决方法就是把其中一边的shared_ptr改成weak_ptr因为weak_ptr是一种弱引用它可以观察shared_ptr管理的对象但是不会增加引用计数也不参与对象生命周期管理这样就可以打破强引用环避免内存泄漏。4.4 weak_ptr 的特点weak_ptr不能直接通过-或*来访问对象。如果想访问资源需要先调用lock()如果对象还存在lock()会返回一个有效的shared_ptr如果对象已经释放lock()返回空对象所以在使用weak_ptr访问资源时一般要先判断lock()的结果是否为空。5. vector 和 list 的应用场景有什么不同5.1 二者的本质区别vector的底层是动态数组list的底层是双向链表因此它们在访问方式、插入删除效率以及内存布局上都不一样。5.2 vector 的特点vector适合以下场景需要高效随机访问经常在尾部插入元素对缓存友好性能较好内存开销相对较小因为vector底层是连续空间所以可以通过下标快速访问元素随机访问效率高。5.3 list 的特点list更适合以下场景频繁在中间位置插入或删除元素不要求随机访问更关注插入删除的灵活性由于list底层是链表所以插入删除时不需要大规模搬移元素但它不能像vector一样高效随机访问同时内存开销也更大。5.4 实际怎么选通常情况下大多数场景优先选择vector因为它的综合性能更好。只有在频繁中间插入和删除时list才更合适。5.5 vector 的扩容机制vector的底层是动态数组它有两个重要概念size当前元素个数capacity当前容量当插入元素时如果size capacity就可以直接插入不会扩容如果size capacity说明空间已经满了这时就会触发扩容5.6 扩容触发条件扩容的本质触发条件是_finish _end_of_storage也就是当前已经没有剩余空间可以继续存放新元素。5.7 vector 扩容时会发生什么扩容一般不会原地进行而是会执行以下步骤重新申请一块更大的连续内存空间将旧空间中的元素拷贝或移动到新空间销毁旧空间中的对象释放旧空间更新内部指针指向新的内存区域5.8 为什么不能原地扩容因为vector要求底层内存必须是连续空间。但操作系统很难保证原有空间后面正好还有一块足够大的连续内存因此大多数情况下只能重新申请一块新的更大空间。5.9 常见扩容策略常见实现中vector会按几何方式扩容例如GCC 通常按2 倍扩容MSVC 通常按1.5 倍扩容这样虽然单次扩容的时间复杂度是O(n)但从均摊分析来看push_back()的均摊时间复杂度仍然是O(1)。5.10 扩容的影响vector一旦扩容会导致原来的迭代器失效原来的指针失效原来的引用失效因为底层地址已经发生了变化。5.11 如何减少扩容带来的性能损失如果提前知道大概需要多少空间可以使用reserve(n)提前预留容量减少扩容次数从而提高性能。6. map 和 unordered_map 的区别map和unordered_map都是 C 中常见的关联容器都可以存储键值对但它们的底层实现和使用场景并不相同。6.1 底层实现不同map底层通常基于红黑树unordered_map底层基于哈希表这决定了它们在查找效率、元素顺序以及使用场景上的差异。6.2 时间复杂度不同map插入O(logn)删除O(logn)查找O(logn)unordered_map插入O(1)摊销删除O(1)摊销查找O(1)摊销所以从平均查找效率来看unordered_map往往更快。6.3 元素顺序不同map中的元素会按照key 有序排列unordered_map中的元素是无序存储如果你需要按键有序遍历那么map更适合。如果你不关心顺序只关心查找速度那么unordered_map更合适。6.4 内存使用不同map由于底层是红黑树每个节点都需要维护树结构信息unordered_map由于底层是哈希表除了元素本身还需要桶数组等额外空间文档里的表述是map由于底层是红黑树内存使用较少unordered_map需要额外空间存储哈希表但在处理大量数据时可能表现更好6.5 场景选择适合用 map 的场景当你需要按 key 有序访问元素顺序遍历键值对范围查询这类场景更适合使用map适合用 unordered_map 的场景当你需要更高的查找效率不关心元素顺序高频键值查找这类场景更适合使用unordered_map7. C 多态是怎么实现的7.1 什么是多态多态的核心含义可以理解为同样的接口调用时表现出不同的行为在 C 中多态主要依赖虚函数来实现。当使用基类指针或者基类引用指向派生类对象时通过这个统一接口调用函数就可能表现出不同子类的不同实现。7.2 多态实现的两个条件多态成立需要满足两个条件被调用的函数必须是虚函数必须通过基类的指针或者引用指向派生类对象只有同时满足这两个条件调用时才会发生动态绑定从而执行子类重写后的函数。7.3 为什么虚函数能实现多态如果父类中的成员函数没有加virtual那么通过基类指针调用函数时会发生静态绑定调用的是基类版本。如果加了virtual并且子类对该函数进行了重写那么通过基类指针调用时会发生动态绑定最终调用的是子类版本。所以虚函数解决的是这样一个问题父类指针 / 父类引用如何正确调用子类自己的实现7.4 为什么基类的析构函数建议写成虚函数这是面试中特别高频的一个追问。如果一个类会被当作基类使用并且你可能会通过基类指针释放派生类对象那么基类析构函数就应该写成虚函数。原因是如果基类析构函数不是虚函数通过基类指针delete派生类对象时只会调用基类析构函数不会调用派生类析构函数如果派生类中自己申请了资源比如堆内存、文件句柄、锁等这些资源就无法被正确释放从而造成资源泄漏而如果基类析构函数是虚函数那么通过基类指针释放对象时会先调用派生类析构再调用基类析构这样对象才能被完整销毁。7.5 本质总结基类析构函数建议写成虚函数本质原因就是保证通过基类指针释放派生类对象时析构过程完整执行避免资源泄漏代码示例智能指针循环引用示例#includeiostream#includememoryusingnamespacestd;structListNode{int_data;shared_ptrListNode_next;shared_ptrListNode_prev;~ListNode(){cout~ListNode()endl;}};intmain(){// 循环引用 -- 内存泄漏shared_ptrListNoden1(newListNode);shared_ptrListNoden2(newListNode);cout初始引用计数:endl;coutn1.use_count() n1.use_count()endl;// 1coutn2.use_count() n2.use_count()endl;// 1n1-_nextn2;n2-_prevn1;cout互相指向后:endl;coutn1.use_count() n1.use_count()endl;// 2coutn2.use_count() n2.use_count()endl;// 2return0;}使用weak_ptr解决循环引用的代码#includeiostream#includememoryusingnamespacestd;structListNode{int_data;shared_ptrListNode_next;weak_ptrListNode_prev;// 改成 weak_ptr~ListNode(){cout~ListNode()endl;}};intmain(){shared_ptrListNoden1(newListNode);shared_ptrListNoden2(newListNode);cout初始引用计数:endl;coutn1.use_count() n1.use_count()endl;// 1coutn2.use_count() n2.use_count()endl;// 1n1-_nextn2;n2-_prevn1;// weak_ptr 绑定 shared_ptr不增加 n1 的计数cout建立关系后:endl;coutn1.use_count() n1.use_count()endl;// 1coutn2.use_count() n2.use_count()endl;// 2return0;}weak_ptr访问资源的方式#includeiostream#includememoryusingnamespacestd;structListNode{int_data;shared_ptrListNode_next;weak_ptrListNode_prev;ListNode(intx):_data(x){}};intmain(){auton1make_sharedListNode(10);auton2make_sharedListNode(20);n1-_nextn2;n2-_prevn1;// weak_ptr 不能直接用 - 或 *// 要先 lock()if(autospn2-_prev.lock()){coutn2 的前驱节点数据: sp-_dataendl;}else{cout前驱节点已经释放endl;}return0;}

相关文章:

C++技术岗面试经验总结

🎬 胖咕噜的稞达鸭:个人主页🔥 个人专栏: 《数据结构》《C初阶高阶》 《Linux系统学习》 《算法日记》⛺️技术的杠杆,撬动整个世界! 1. 右值引用和左值引用的区别 左值是我们平常使用的函数对象,表达式结束后依旧存在…...

深度解析notion-enhancer组件化架构:从UI扩展到底层实现的设计模式

深度解析notion-enhancer组件化架构:从UI扩展到底层实现的设计模式 【免费下载链接】notion-enhancer An enhancer/customiser for the all-in-one productivity workspace Notion 项目地址: https://gitcode.com/gh_mirrors/no/notion-enhancer Notion作为现…...

AliceSoft游戏文件处理终极指南:从入门到精通的完整解决方案

AliceSoft游戏文件处理终极指南:从入门到精通的完整解决方案 【免费下载链接】alice-tools Tools for extracting/editing files from AliceSoft games. 项目地址: https://gitcode.com/gh_mirrors/al/alice-tools AliceSoft游戏文件处理工具Alice-Tools是一…...

DXVK 2.7.1:Linux游戏图形性能的终极Vulkan转换层深度解析

DXVK 2.7.1:Linux游戏图形性能的终极Vulkan转换层深度解析 【免费下载链接】dxvk Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine 项目地址: https://gitcode.com/gh_mirrors/dx/dxvk DXVK 2.7.1作为基于Vulkan的Direct3D 8/9/10/11转…...

一次企业知识库同步系统改造复盘:从全量拉取到增量消息的演进与多级缓存一致性保障

2026 年 4 月 6 日凌晨 3:17,我们收到一条告警:知识库同步服务 CPU 飙升至 98%,同步任务积压超过 12 万条,下游 AI 助手响应延迟突破 8 秒。这不是第一次了——过去三个月,每逢周一早高峰或知识库批量更新后&#xff0…...

如何将Smart AM60电视盒子变身高性能Armbian服务器:完整实战指南

如何将Smart AM60电视盒子变身高性能Armbian服务器:完整实战指南 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s905l…...

Altium Designer 22 实战:用这个隐藏技巧,为DIP插件焊盘穿上‘防烫服’

Altium Designer 22实战:用丝印层为DIP焊盘打造双重防护 手工焊接DIP插件时,烙铁温度过高或操作不当导致绿油层损坏,进而引发短路问题,是硬件工程师经常遇到的痛点。特别是在生产线上,工人为了效率往往将烙铁温度调至最…...

Python3.10开发环境搭建指南:Miniconda镜像简化部署流程

Python3.10开发环境搭建指南:Miniconda镜像简化部署流程 1. 为什么选择Miniconda-Python3.10 Python作为当今最流行的编程语言之一,版本管理一直是开发者面临的挑战。Miniconda-Python3.10镜像提供了一种轻量级解决方案,它能帮你&#xff1…...

如何完整解决Bilibili API风控限制?开发者高效应对指南

如何完整解决Bilibili API风控限制?开发者高效应对指南 【免费下载链接】bilibili-api 哔哩哔哩常用API调用。支持视频、番剧、用户、频道、音频等功能。原仓库地址:https://github.com/MoyuScript/bilibili-api 项目地址: https://gitcode.com/gh_mir…...

Qwen3-VL-8B分步部署教程:vLLM服务+proxy_server+chat.html独立启动详解

Qwen3-VL-8B分步部署教程:vLLM服务proxy_serverchat.html独立启动详解 1. 项目概述 今天给大家分享一个完整的AI聊天系统部署方案,基于Qwen3-VL-8B大语言模型,包含前端界面、反向代理服务器和vLLM推理后端。这个系统采用模块化设计&#xf…...

STM32F0实战:基于HAL库开发【4.6】

21.2 USB模块STM32F0072VBT6微控制器片内集成有符合USB2.0全速设备技术规范要求的USB模块,通过该模块可以实现与PC主机的USB通信连接,进一步拓展将该系列微控制器的应用范围。21.2.1 USB模块的结构STM32F072VBT6微控制器片内集成的USB模块,可…...

12年不上班,我靠什么支撑到现在

我已经12年没去上过班了,14年从学校辞职出来后,就没再给人打过工。虽然我不上班,但身边人都觉得我很会赚钱,觉得我很幸运,也觉得我很有勇气。 其实,并不是我多勇敢,是因为早在2014年&#xff0c…...

C语言字符串必知:末尾有个隐藏的\0,新手易踩坑

C语言字符串 在C语言程序设计体系当中,字符串属于处理文本信息的核心载体,其设计逻辑跟底层实现深深地展现了C语言贴近硬件兼具高效灵活的语言特性,和一部分高级语言不一样,C语言并没有设置独立的字符串数据类型,而是经…...

告别联网烦恼:uv离线安装科学计算包的3种实战姿势(NumPy/TensorFlow实测)

数据科学家必备:三种高效离线安装Python科学计算包的终极方案 实验室的服务器突然断网了,而你的TensorFlow模型训练正进行到关键时刻——这种场景对数据科学家来说简直是噩梦。别担心,离线安装Python包并非无解难题。本文将带你掌握三种经过实…...

揭秘书匠策AI:论文写作的未来式导航助手 —— 你的毕业论文智囊团

在学术的浩瀚海洋中,每一位即将扬帆远航的毕业生都面临着同样的挑战——如何撰写一篇高质量、有深度的毕业论文?这不仅仅是对知识的综合运用,更是对思维逻辑、创新能力的全面考验。幸运的是,随着人工智能技术的飞速发展&#xff0…...

Cursor Pro功能优化工具:提升AI编程体验的开源解决方案

Cursor Pro功能优化工具:提升AI编程体验的开源解决方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your tr…...

编程新手学编程,先学C语言还是C++?学姐告诉你答案

身为一名编程方面的新手,大家都会遭遇的一个疑问是:是要先去学习C语言,还是要先去学习C?有些同学会认为倘若我先着手学习C,之后再回过头来学习C语言,这样是不是会更为简便?毕竟,升级…...

终极暗黑破坏神2存档编辑器:免费开源的d2s文件修改完整指南

终极暗黑破坏神2存档编辑器:免费开源的d2s文件修改完整指南 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾经因为暗黑破坏神2中的角色培养方向错误而感到沮丧?或者因为装备获取过于依赖运气而想…...

突破压缩技术边界:7-Zip ZS多算法融合解决方案全解析

突破压缩技术边界:7-Zip ZS多算法融合解决方案全解析 【免费下载链接】7-Zip-zstd 7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard 项目地址: https://gitcode.com/gh_mirrors/7z/7-Zip-zstd 在数据爆炸的时代,文件…...

Windows 10/11 安卓应用安装器:APK Installer 完整使用指南

Windows 10/11 安卓应用安装器:APK Installer 完整使用指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 还在为无法在Windows电脑上运行安卓应用而烦恼吗…...

5分钟解锁百度网盘SVIP下载特权:Mac用户的终极加速指南

5分钟解锁百度网盘SVIP下载特权:Mac用户的终极加速指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 你是否曾为百度网盘在Mac上的龟速下…...

unrpa架构深度解析:RPA文件格式逆向工程与高性能解包技术实现

unrpa架构深度解析:RPA文件格式逆向工程与高性能解包技术实现 【免费下载链接】unrpa A program to extract files from the RPA archive format. 项目地址: https://gitcode.com/gh_mirrors/un/unrpa 在游戏开发与逆向工程领域,RPA(R…...

告别背包焦虑:TQVaultAE如何彻底改变《泰坦之旅》装备管理体验

告别背包焦虑:TQVaultAE如何彻底改变《泰坦之旅》装备管理体验 【免费下载链接】TQVaultAE Extra bank space for Titan Quest Anniversary Edition 项目地址: https://gitcode.com/gh_mirrors/tq/TQVaultAE 对于《泰坦之旅》玩家来说,最令人沮丧…...

[Java 算法] 动态规划(4)

练习一 : 最长递增子序列 300. 最长递增子序列 - 力扣(LeetCode) class Solution {public int lengthOfLIS(int[] nums) {int n nums.length;int[] dp new int[n];// 初始化:每个元素至少是长度为1的子序列Arrays.fill(dp, 1);int maxLen …...

霜儿-汉服-造相Z-Turbo入门必看:从零启动到生成高清古风人像全流程

霜儿-汉服-造相Z-Turbo入门必看:从零启动到生成高清古风人像全流程 想亲手生成一张充满诗意的古风汉服人像吗?比如,一位身着月白霜花刺绣汉服的少女,在江南庭院的白梅树下,气质清冷,宛如从画中走来。这听起…...

Word一打字就删除后面的文字

按下FN和esc,事esc变亮后,按下insert即可...

Phi-3-mini-4k-instruct本地部署实战:Ollama让AI推理像聊天一样简单

Phi-3-mini-4k-instruct本地部署实战:Ollama让AI推理像聊天一样简单 1. 模型简介 Phi-3-Mini-4K-Instruct是微软推出的轻量级开源语言模型,仅有38亿参数却展现出惊人的推理能力。这个模型特别适合在本地设备上运行,不需要昂贵的GPU就能获得…...

三场正交相位场统一论2.0——宇宙底层规律与星际航行的终极答案

前言:打破百年物理枷锁,回归宇宙本质逻辑从麦克斯韦完成电磁力的初步统一,到特斯拉触摸到反重力的技术边缘,从爱因斯坦构建时空弯曲的引力假说,到张祥前提出空间螺旋统一场模型,人类为破解宇宙四大力统一的…...

Obsidian: 图片管理插件-Local Images Plus与Paste Image Rename的进阶配置指南

1. 为什么需要图片管理插件 如果你经常用Obsidian写笔记,肯定遇到过这样的烦恼:从网页复制粘贴的图片默认存放在系统剪贴板,关闭笔记后图片就消失了;或者随手粘贴的图片文件名杂乱无章,过段时间根本分不清是哪篇笔记的…...

ens33网络接口DOWN状态诊断与修复:从基础命令到Netplan配置

1. 为什么ens33接口会突然DOWN掉? 最近在调试Ubuntu虚拟机时,突然发现网络连接断了。用ip addr一看,ens33接口的状态赫然显示着"DOWN"。这种情况在虚拟化环境中其实很常见,我遇到过不下十次。通常表现为:虚拟…...