C++和Linux面试好题
南山烟雨珠江潮推荐的题目:
1、什么是copy on write?C++中如何利用RAII和智能指针实现一个COW的字符串类?Linux中fork()的COW机制是如何影响C++程序内存使用和性能的?
2、在你所选用的编译器(例如gcc)中,虚函数表的内存布局是怎样的?在Linux下,如何通过gdb调试器或直接解析二进制文件(使用objdump或readelf)来验证一个C++类的内存布局?
3、零拷贝(Zero-Copy)是什么?Linux中sendfile()等系统调用如何实现零拷贝?在C++网络编程中,如何利用这些系统调用(例如,在传输文件时)来提升性能?与使用传统的read/write方式相比,需要注意什么?
4、linux中的信号(Signal)是什么?用在程序中一般处理哪些信号?如何优雅地处理SIGTERM和SIGINT信号来实现服务的平滑安全地退出?
5、请描述Linux进程的地址空间布局。另外,new char[1]可能会分配多少内存?
6、什么是守护进程?需要先后调用哪些系统调用才能让一个进程成为一个地道的守护进程?(这个当然不需要背下来,能说出其中几个即可)。
7、如何发现程序中的CPU热点(Hotspot)?你使用过哪个/些性能剖析(profiling)工具?介绍一下其使用方法。
8、在Linux中如何发现程序中的内存泄漏和非法内存访问?你一般是怎么做的?请举例说明如何使用Valgrind的memcheck工具来检测C++程序中的内存错误,以及如何让Valgrind更好地理解STL和智能指针?
9、什么是文件描述符?它的最大值由什么决定?如何修改?如果遇到“Too many open files”错误,如何排查和解决?如何利用RAII思想设计文件描述符的封装类,以避免泄漏?
10、你写过多线程的程序吗?用的是linux中的pthread api还是C++中的std::thread相关的api?两者有何区别和联系?如果你写的一个程序a正在运行,你怀疑它发生了死锁,在不杀死这个进程的情况下,你如何确认它是否死锁?
11、select,poll,epoll,其中哪些是同步api、哪些是异步api?你在linux中使用过异步api吗?在C++中是如何封装的(使用libevent、libuv、asio还是自己封装的)?(你选择的方案)采用的是reactor还是proactor?它们有何区别?你对比过两者的性能差异吗?
12、使用共享内存(Shared Memory)在Linux上进行进程间通信时,能否直接在其中创建C++对象(如std::string,std::vector)?会有什么潜在风险和陷阱?(例如,静态变量、虚函数表指针、内部指针等问题)。如何安全地实现?
13、现代C++协程(Coroutines)是协作式调度的。当一个C++协程在Linux上通过co_await挂起时,底层的执行线程(pthread)在做什么?这与你所理解的epoll事件循环有何相似与不同之处?协程如何与现有的基于epoll的Reactor网络库集成?
14、在C++代码中,一个系统调用(如read,write)失败返回-1时,你是如何处理这个错误的?是检查errno并抛出异常,还是返回错误码?两者分别有什么优劣?
xiaokang:什么样的问题是好问题?
1、内存管理问题 坏问题:“new和malloc有什么区别?” 好问题:“假设你在开发一个高频交易系统,发现频繁的内存分配成为了性能瓶颈,你会如何解决?”
初级回答:使用内存池 中级回答:设计分级内存池,不同大小的对象使用不同策略 高级回答:考虑内存对齐、cache友好、NUMA感知的设计
2、并发编程问题 坏问题:“什么是死锁?如何避免?” 好问题:“如果让你**实现一个线程池,你会考虑哪些问题?**请画出你的设计。”
评估维度:
基础设计:任务队列 + 工作线程
线程安全:锁的使用,条件变量
性能优化:任务窃取,动态扩容
异常安全:资源管理,优雅关闭
可配置性:线程数量,队列大小
3、好问题的设计原则 从项目经验入手
万能开场:“介绍一下你做过的最有挑战性的C++项目。”
为什么选择这个技术栈?
遇到了什么技术难点?
如何进行性能优化的?
如果重新设计,会有什么改进?
4、好问题的设计原则 递进式深入
Level 1:基本实现 “如何实现一个简单的智能指针?”
Level 2:异常安全 “如何处理构造函数中的异常?”
Level 3:性能优化 “如何避免不必要的引用计数操作?”
Level 4:高级特性 “如何处理循环引用问题?”
5、好问题的设计原则 场景化问题
“你正在开发一个游戏服务器,需要管理10万个玩家对象,如何设计内存管理策略?”
对象池设计
内存布局优化
cache友好的数据结构
垃圾回收策略
4、开放式讨论
例如:“在什么情况下你会选择C++而不是其他语言?”
对技术栈的理解深度
技术选型的思考能力
实际项目经验
学习和适应能力
程序喵大人 常见C和C++问题推荐
https://lb3fn675fh.feishu.cn/docx/VUjdd8uCdoufThxHEOzcQQaonCh
C语言
const的作用有哪些,谈一谈你对const的理解?
描述char*、const char*、char* const、const char* const的区别?
指针常量和常量指针有什么区别?
static的作用是什么,什么情况下用到static?
全局变量与局部变量的区别?
宏定义的作用是什么?
内存对齐的概念?为什么会有内存对齐?
inline 内联函数的特点有哪些?它的优缺点是什么?
如何避免野指针?
如何计算结构体长度?
sizeof和strlen有什么区别?
知道条件变量吗?条件变量为什么要和锁配合使用?
如何用C 实现 C++ 的面向对象特性(封装、继承、多态)
memcpy怎么实现让它效率更高?
typedef和define有什么区别?
extern有什么作用,extern C有什么作用?
C++基础知识面试题
C语言和C++有什么区别?
struct和class有什么区别?
extern “C"的作用?
了解RAII吗?介绍一下?RAII可是C++很重要的一个特性。
函数重载和覆盖有什么区别?
谈一谈你对多态的理解,运行时多态的实现原理是什么?
对虚函数机制的理解,单继承、多继承、虚继承条件下虚函数表的结构
如果虚函数是有效的,那为什么不把所有函数设为虚函数?
构造函数可以是虚函数吗?析构函数可以是虚函数吗?
基类的析构函数可以调用虚函数吗?基类的构造函数可以调用虚函数吗?
什么场景需要用到纯虚函数?纯虚函数的作用是什么?
指针和引用有什么区别?什么情况下用指针,什么情况下用引用?
new和malloc有什么区别?
malloc的内存可以用delete释放吗?
malloc出来20字节内存,为什么free不需要传入20呢,不会产生内存泄漏吗?
new[]和delete[]一定要配对使用吗?为什么?
类的大小怎么计算?
volatile关键字的作用
如何实现一个线程池?说一下基本思路即可!
了解各种强制类型转换的原理及使用吗?说说?
C++11新特性
了解auto和decltype吗?
谈一谈你对左值和右值的了解,了解左值引用和右值引用吗?
了解移动语义和完美转发吗?
enum 和 enum class有什么区别?
了解列表初始化吗?
对C++11的智能指针了解多少,可以自己实现一个智能指针吗?
平时会用到function、bind、lambda吗,都什么场景下会用到?
对C++11的mutex和RAII lock有过了解吗?
一般什么情况下会出现内存泄漏?出现内存泄漏如何调试?
unique_ptr如何转换的所有权?
谈一谈你对面向对象的理解
什么场景下使用继承方式,什么场景下使用组合?
STL系列
C++直接使用数组好还是使用std::array好?std::array是怎么实现的?
std::vector最大的特点是什么?它的内部是怎么实现的?resize和reserve的区别是什么?clear是怎么实现的?
deque的底层数据结构是什么?它的内部是怎么实现的?
map和unordered_map有什么区别?分别在什么场景下使用?
list的使用场景?std::find可以传入list对应的迭代器吗?
string的常用函数
设计模式
分别写出饿汉和懒汉线程安全的单例模式
说出观察者模式类关系和优点
说出代理模式类关系和优点
说出工厂模式概念和优点
说出构造者模式概念
说出适配器模式概念
操作系统
进程和线程的区别?
操作系统是怎么进行进程管理的?
操作系统是如何做到进程阻塞的?
进程之间的通信方式有哪些?
线程是如何实现的?
线程之间私有和共享的资源有哪些?
一般应用程序内存空间的堆和栈的区别是什么?
进程虚拟空间是怎么布局的?
虚拟内存是如何映射到物理内存的?了解分页内存管理吗?
什么是上下文切换,操作系统是怎么做的上下文切换?
什么是大端字节,什么是小端字节?如何转换字节序?
产生死锁的必要条件有哪些?如何避免死锁?
信号和信号量的区别是什么?
锁的性能开销,锁的实现原理?
编译原理
gcc hello.c 这行命令具体的执行过程,内部究竟做了什么?
程序一定会从main函数开始运行吗?
如何确定某个函数有被编译输出?
动态链接库和静态链接库的区别是什么?
秦物智联推荐题目
1、什么是类型安全,c++中如何能够做到类型安全。
2、C++的4种cast作用和使用方法,注意的问题。
3、STL容器常用哪几种,哪些是有序的,哪些是无序的。
4、Vector容器的概念和作用
5、三种设计模式,工厂模式或者观察者模式讲一下。
6、智能指针有几种?
7、单例模式,好处/坏处?
8、解释一下观察者模式
9、工厂模式概念
10、stl常用的容器有哪些
11、list容器底层是怎么实现的
12、vector和list的区别,分别在哪些场景使用
13、类和结构体的区别
14、单例模式,工厂模式,代理模式的特点及应用场景
15、new/delete和malloc/free区别
16、map的特性,如何确认map中是否存在key值,map如何遍历
17、指针和引用的区别
18、智能指针介绍
19、指针和引用的区别
20、三大特性
21、虚函数怎样具体实现的
22、stl最常用容器
23、map的底层拿什么实现的
24、static修饰类成员函数的时候可以调用类内的私有成员吗
25、构造函数可以是虚函数吗?
26、讲解一下多态的实现
27、C和c++区别
28、重写与重载
29、单例模式,工厂模式,代理模式和观察者模式的特点及应用场景
30、c++中用哪些容器存储哪些数据
31、c++内存管理
32、智能指针shared——ptr
33、STL标准模板库容器有哪些
34、vector和list分别使用什么场景
35、stl标准模板库有哪些,描述下优缺点
36、深和浅拷贝概念
37、左值和右值引用的问题
38、消息队列通信方式
39、c++中使用消息队列实现线程之间的通信
40、c++利用stl中的queue封装消息队列类如何实现
41、消息队列类中是否实现register方法进程任务注册,
是否使用
是否使用lambda表达式。
42、常用设计模式简介
anchor推荐题目
c++的class的大小由哪些因素决定?(能把这个问题答全非常牛,这是当初一个阿里面试官出给我的,当初我只面个实习生,回答的一塌糊涂)
什么是多态,什么是虚函数,虚函数是怎么实现的?
析构函数可以是虚函数吗,为什么?然后接着问,什么情况下析构函数必须是虚函数。
RAII是什么?这个名词不会也无所谓,可以引出一个更具体的例子,shared_ptr的实现,shared_ptr一定是不会导致内存泄露吗?
new/delete和malloc/free有什么区别和联系
错误处理有几种方法,为什么有些场合要禁用exception?(如果一个错误处理方法都说不出来,甚至引导之后都没有听说过什么是错误处理,直接扣三分之一的分甚至更多)
一个和c相关的问题,毕竟这俩语言分不开,什么是野指针,有哪些野指针?
什么是悬垂引用?这个答不上来也不为难,加分题。
一个多少和语言无关的问题,你平常怎么调试代码,你能想到多少方法?(这题想到的越多分越高)
vitamind3
-
C++创建一个类,默认应当实现几个函数?
-
拷贝构造函数应当实现几个?怎样正确实现使用右值引用的拷贝构造函数?
-
怎样正确的重载实现new和delete?
-
public,protected,private继承有何区别?对friend访问有何影响?
-
STL里各种智能指针的区别和应用场景。
纯C、嵌入式相关
请解释一下C语言中的指针和数组的区别,并给出一个实际应用的例子。
谈谈你对C语言内存管理的理解,包括动态内存分配(如malloc, free)的使用注意事项。
C语言中的结构体(struct)和联合体(union)有何不同?在什么场景下你会选择使用它们?
SPI驱动遇到的问题
sensor驱动了解吗
介绍一个你平时遇到的异常卡死问题
如何有网络工具抓包分析网络问题
音频框架是否了解
如何进行内核裁剪
- volatile是否可以修饰const
- 可以,
volatile const用于描述那些在程序运行过程中其值可能被外部因素(如硬件或并发线程)改变,但又不允许程序修改的变量。
- 如何快速一行代码操作硬件寄存器
- 使用位带操作或直接对寄存器地址进行读写,例如:
*(volatile uint32_t *)(0x40021000 + 0x04) |= (1 << 3);
- 如何最快比较两组寄存器里有多少位不同
- 使用异或运算,然后计算结果中的1的个数,可以使用位计数指令如
popcnt。
- 如何降低功耗
- 关闭未使用的外设,使用低功耗模式,优化代码减少处理器空闲等待。
- 什么时候会用到do{}while(0)
- 构造宏时确保代码块的正确性,防止意外的分号导致宏展开错误。
- GPIO有几种状态
- 输入、输出、高阻态、上拉、下拉等。
- 如何用软件处理硬件管脚抖动
- 使用软件延时滤波或状态机检测稳定状态。
- 如何高效处理中断
- 设置中断优先级,避免中断嵌套,最小化中断服务例程的执行时间。
- delay和sleep的区别
delay通常阻塞当前执行流,sleep可能涉及系统调用,让出CPU。
- 中断时可否睡眠
- 不推荐,中断应尽快返回,不应做长时间操作。
- 如何设计RAM和flash的验证工具
- 使用CRC校验和、MD5哈希或其他完整性检查算法。
- 如何合理高效静态分配内存
- 根据最大需求预分配,使用内存池减少碎片。
- 如何跟踪内存泄漏
- 使用动态内存管理库提供的统计功能或专门的内存泄漏检测工具。
- 如何实现一个ring buffer以及用途
- 实现循环指针和头尾指针,用于缓冲区,用于数据流处理和通信。
- DMA和FIFO的区别
- DMA用于数据传输,FIFO是一种存储结构,DMA可以利用FIFO作为缓冲。
- 如何做到统一API对接不同外设驱动
- 设计抽象层,提供通用接口。
- 如何合理设计flash分区表
- 考虑应用需求、更新策略、磨损均衡和冗余。
- 正常非掉电重启是否要释放内存
- 重启前释放资源有助于系统的稳定性和初始化。
- 正常掉电关机流程是否要释放内存
- 同上,但要考虑持久性数据的保存。
- 非掉电异常如何处理
- 异常处理程序捕获异常,记录错误,尝试恢复或重启。
- 如何实现异常后的dump
- 记录关键寄存器和内存状态,保存在非易失存储中。
- 非正常掉电如何保护
- 使用UPS或电池备份,存储关键数据到非易失存储。
- 如何设计一个简单的profiling工具
- 记录函数调用时间和次数,分析性能瓶颈。
- 低功耗深睡眠如何唤醒后继续之前工作
- 保存状态到非易失存储,唤醒后恢复状态。
- RTOS不能断点和打印的时候如何调试
- 使用硬件调试器或日志记录和故障注入测试。
- 什么是交叉编译
- 在一个平台上生成另一个平台可执行代码的编译过程。
- 如何保证makefile的增量编译
- 使用依赖关系和文件时间戳。
- 如何用一套代码支持不同硬件
- 使用抽象层和条件编译。
- 如何用一版软件支持不同硬件
- 设计模块化架构,硬件无关接口。
- 不同代码编译后的存放区域有何不同
- 代码段、数据段、BSS段,根据类型和属性存放。
- release和debug编译的区别
- Release优化代码,Debug包含调试信息和符号。
- ARM多核之间有多少通讯机制及优缺点
- 共享内存、消息传递、中断,各有适用场景和效率差异。
- 两个线程之间不同锁的区别是什么
- 互斥锁、读写锁、自旋锁,适用于不同同步需求。
- 如何理解收益边界
- 性能提升与成本、复杂度之间的权衡点。
- 介绍一下自己关于代码优化的经验
- 分析热点,先考虑算法和数据结构,再进行微调。
- 关于代码移植有什么经验分享
- 尽早识别硬件特异性代码,使用标准库和接口,保持良好的编码规范