```html
📅 更新日期:2023-10-27 | 🌐 域名:www.kaoacca.cn | 📧 联系我们:contact@kaoacca.cn

C C++面试大全

深耕底层原理,解析内存奥秘,掌握并发编程。为您打造从入门到精通的 C C++面试大全 知识体系,助您斩获大厂Offer。

【壹】C/C++ 语言核心基础解析

基础不牢,地动山摇。在 C C++面试大全 中,基础题往往决定了面试官对你的第一印象。

指针与引用

指针是C语言的灵魂,也是C++面试的重灾区。面试官常问:const char p 与 char const p 的区别?引用在底层是如何实现的(通常是指针常量)?空指针与野指针的区别及防御性编程策略。

内存管理

栈(Stack)与堆(Heap)的区别是必考题。栈由编译器自动分配释放,存放局部变量;堆由程序员手动管理(malloc/free 或 new/delete)。重点考察内存泄漏的检测(Valgrind)、内存碎片问题以及智能指针(unique_ptr, shared_ptr)的底层引用计数机制。

关键字奥秘

static、volatile、extern、register 四大关键字的深度解析。static修饰局部变量(改变生命周期)、全局变量(改变作用域)和函数(改变连接属性)的不同效果。volatile防止编译器优化,常用于多线程共享变量或寄存器映射。

预处理与编译

从源码到可执行文件的四个阶段:预处理(宏展开、头文件包含)、编译(语法检查、生成汇编)、汇编(生成目标文件)、链接(符号解析、重定位)。理解 #include 与 #define 的本质区别。

【贰】面向对象与STL源码剖析

深入理解C++面向对象特性及标准模板库的实现细节,是区分初级与高级工程师的关键。

面向对象特性
STL容器与算法
内存模型与虚函数

封装、继承与多态

多态是C++的核心。实现多态的条件:基类指针/引用、虚函数重写、派生类对象赋值给基类。虚函数表(vptr/vtable)机制是面试高频考点。编译器如何在运行时通过虚函数表找到正确的函数地址?

  • 虚析构函数:当基类指针指向派生类对象并删除时,若析构函数非虚,会导致派生类资源未释放(内存泄漏)。
  • 纯虚函数:定义接口,包含纯虚函数的类为抽象类,不能实例化。
  • 访问控制:public, protected, private 在继承中的变化规则。

STL 六大组件

STL(Standard Template Library)由容器、算法、迭代器、仿函数、适配器、空间配置器组成。

容器类型 底层数据结构 特点与应用场景
vector 动态数组 随机访问快,尾部插入快,中间插入/删除慢。最常用容器。
list 双向链表 任意位置插入/删除快,随机访问慢。内存不连续。
map 红黑树 (RB-Tree) 有序键值对,查找/插入/删除均为 O(log N)。线程不安全。
unordered_map 哈希表 (Hash Table) 无序键值对,平均查找 O(1)。处理冲突策略(链地址法)。

虚函数表与内存布局

理解类的内存布局对于解决内存对齐、指针偏移问题至关重要。

// 示例:虚函数表指针的位置
class Base {
    virtual void func1() {}
    virtual void func2() {}
    int a;
};
class Derived : public Base {
    virtual void func3() {}
    int b;
};
/
内存布局示意:
Base: [vptr] [a]
Derived: [vptr(Base)] [a] [b]
注意:Derived的vptr指向Derived的虚函数表,但func1/func2仍共享Base的逻辑(若未重写)。
/

【叁】Linux系统编程与并发

服务器端开发离不开Linux环境。进程、线程、IO多路复用是后端开发的基石。

进程与线程

进程是资源分配的最小单位,线程是CPU调度的最小单位。进程间通信(IPC)方式:管道、消息队列、共享内存、信号量、套接字。线程间共享堆和全局数据,但拥有独立的栈。线程同步机制:互斥锁、条件变量、读写锁、自旋锁。

IO 模型

阻塞IO、非阻塞IO、IO多路复用(select/poll/epoll)、信号驱动IO、异步IO。重点掌握 epoll 的LT(水平触发)与ET(边缘触发)模式区别,以及epoll为何比select高效(O(1)获取就绪fd,无最大连接数限制)。

网络编程

TCP与UDP的区别。TCP三次握手与四次挥手的过程及状态转换(TIME_WAIT, CLOSE_WAIT产生的原因)。粘包/拆包问题及其解决方案(长度字段、分隔符)。

【肆】C/C++ 开发者成长路径

从初学者到架构师,每一步都需扎实积累。

阶段一:语言基础 (0-1年)

熟练掌握C语言语法,理解指针、数组、结构体、内存布局。掌握基本的调试技巧(GDB)。能够编写简单的Linux命令行工具。

阶段二:C++进阶 (1-3年)

深入理解面向对象编程,掌握STL常用容器及算法。学习C++11/14/17新特性(智能指针、Lambda、移动语义)。理解编译链接过程。

阶段三:系统与网络 (3-5年)

深入Linux系统编程,掌握多线程并发编程模型(Reactor/Proactor)。熟悉网络协议栈,能够编写高性能网络服务器。了解数据库原理。

阶段四:架构与优化 (5年+)

系统架构设计能力,性能调优(CPU/内存/IO瓶颈分析)。分布式系统基础,中间件开发。代码规范与团队管理。

【伍】网友最关心的 10 个高频面试题

基于全网搜索数据筛选,这些是 C C++面试大全 中被提问频率最高的问题。

1. 简述 C 和 C++ 的主要区别?

C是面向过程的编程语言,强调函数和数据结构分离;C++是面向对象的编程语言,支持封装、继承、多态。C++在C的基础上增加了类、模板、异常处理、STL等特性,且C++代码通常能兼容C代码(需 extern "C" 处理命名修饰)。


2. malloc/free 和 new/delete 的区别?

① malloc/free 是C语言库函数,new/delete 是C++操作符。② malloc 只分配内存,不调用构造函数;new 分配内存并调用构造函数初始化。③ new/delete 返回特定类型指针,无需强制类型转换;malloc 返回 void。④ new/delete 可被重载,malloc/free 不可。


3. 什么是内存泄漏?如何检测和避免?

内存泄漏指动态分配的堆内存在使用后未释放,导致程序可用内存逐渐减少。检测方法:Valgrind (Memcheck), AddressSanitizer (ASan), CRT Debug Heap。避免方法:使用智能指针 (unique_ptr/shared_ptr) 管理资源,遵循RAII(资源获取即初始化)原则,确保异常安全。


4. 解释一下 C++ 中的虚函数表 (vtable)?

虚函数表是C++实现动态多态的机制。每个包含虚函数的类都有一个虚函数表,表中存放该类的虚函数地址。每个对象包含一个虚表指针 (vptr),指向类的虚函数表。调用虚函数时,通过 vptr 找到 vtable,再找到具体函数地址,实现运行时绑定。


5. TCP 和 UDP 的主要区别?

① TCP面向连接,UDP无连接。② TCP可靠传输(确认、重传、流量控制),UDP不可靠。③ TCP面向字节流,UDP面向报文。④ TCP头部开销大(20字节),UDP小(8字节)。⑤ TCP速度慢于UDP。⑥ TCP支持广播/组播(较少用),UDP支持。


6. 什么是死锁?产生条件及解决方法?

死锁指两个或多个进程无限等待对方持有的资源。四个必要条件:互斥、占有并等待、非抢占、循环等待。解决方法:破坏其中一个条件。常用策略:资源有序分配法、银行家算法、超时机制、锁降级。


7. vector 扩容机制是怎样的?

vector 底层是动态数组。当容量不足时,vector 会申请一块更大的连续内存(通常是原大小的 1.5倍 或 2倍),将原数据拷贝/移动到新内存,释放旧内存,并更新内部指针。注意:扩容会导致原有迭代器失效。


8. 智能指针 unique_ptr 和 shared_ptr 的区别?

unique_ptr 独占所管理的对象,不可复制,可移动。shared_ptr 共享所管理的对象,使用引用计数,当计数为0时释放对象。shared_ptr 存在循环引用问题,需用 weak_ptr 解决。


9. 什么是右值引用和移动语义?

右值引用 (T&&) 绑定到右值(临时对象)。移动语义通过 std::move 将左值强制转换为右值引用,从而避免深拷贝,直接转移资源所有权(如指针、文件描述符),大幅提升性能。


10. 如何在 Linux 下调试 C++ 程序?

主要工具:GDB(断点、单步、查看变量、核心转储分析)、Valgrind(内存泄漏检测)、AddressSanitizer(编译选项 -fsanitize=address)、Strace(系统调用跟踪)、Ltrace(库调用跟踪)。

```
斌知网
蜀ICP备2026017620号-5