logo

C/C++ 面试通关宝典:50道高频题深度解析

作者:半吊子全栈工匠2025.09.19 14:37浏览量:0

简介:本文汇总C/C++开发中最常见的50道面试题,涵盖语言特性、内存管理、多线程、设计模式等核心领域,提供标准答案与深度解析,助力开发者系统梳理知识体系,提升面试成功率。

一、基础语法与核心特性(10题)

  1. C与C++的主要区别
    C是过程式语言,依赖函数库;C++支持面向对象(封装、继承、多态),提供STL标准模板库。例如,C++中可用vector<int>替代C的数组,自动管理内存。

  2. const#define的差异
    const是编译期常量,具有类型检查和调试信息;#define是预处理宏,无类型且可能导致符号冲突。例如:

    1. const int MAX = 100; // 推荐
    2. #define MAX 100 // 不推荐
  3. static关键字的作用

    • 文件作用域:限制变量/函数仅在当前文件可见。
    • 类成员:所有对象共享同一静态成员,生命周期贯穿程序。
    • 函数内部:变量保持上一次调用后的值。
  4. 指针与引用的区别
    指针可空、可重新赋值,需解引用;引用必须初始化且不可变,更安全。例如:

    1. int a = 5;
    2. int* p = &a; // 指针
    3. int& r = a; // 引用
  5. newmalloc的区别
    new调用构造函数,delete调用析构函数;malloc/free仅分配/释放内存。例如:

    1. MyClass* obj = new MyClass(); // 调用构造函数
    2. delete obj; // 调用析构函数

二、内存管理与优化(10题)

  1. 内存泄漏的常见场景

    • 动态分配未释放:int* p = new int[100];delete[] p
    • 异常导致泄漏:函数内分配资源,异常后未释放。
    • 解决方案:使用智能指针(unique_ptrshared_ptr)。
  2. 野指针与悬空指针
    野指针:未初始化或释放后未置空的指针。悬空指针:指向已释放内存的指针。避免方法:释放后置nullptr

  3. 深拷贝与浅拷贝
    浅拷贝仅复制指针值,导致双重释放;深拷贝分配新内存并复制内容。例如:

    1. class String {
    2. char* data;
    3. public:
    4. String(const char* str) {
    5. data = new char[strlen(str)+1];
    6. strcpy(data, str);
    7. }
    8. ~String() { delete[] data; } // 深拷贝需在拷贝构造函数中实现
    9. };
  4. 栈与堆的区别
    栈:自动分配/释放,速度快但容量小;堆:手动管理,容量大但易泄漏。例如:

    1. void func() {
    2. int x = 10; // 栈
    3. int* y = new int(20); // 堆
    4. delete y;
    5. }
  5. 内存对齐规则
    结构体大小受最大成员对齐和编译器默认对齐影响。例如:

    1. struct Example {
    2. char a; // 1字节
    3. int b; // 4字节(对齐到4)
    4. double c; // 8字节(对齐到8)
    5. }; // 总大小:16字节(8+4+1填充3)

三、多线程与并发(10题)

  1. 线程同步方法
    互斥锁(mutex)、条件变量(condition_variable)、原子操作(std::atomic)。例如:

    1. std::mutex mtx;
    2. void safe_increment() {
    3. std::lock_guard<std::mutex> lock(mtx);
    4. counter++;
    5. }
  2. 死锁的四个条件
    互斥、持有并等待、非抢占、循环等待。避免策略:按固定顺序获取锁。

  3. volatile的作用
    禁止编译器优化,确保每次访问都从内存读取。用于多线程或硬件寄存器场景。

  4. 线程局部存储(TLS)
    使用thread_local关键字,每个线程拥有独立变量副本。例如:

    1. thread_local int tid;
  5. C++11线程库组件
    std::threadstd::asyncstd::futurestd::promise。例如:

    1. auto future = std::async([] { return 42; });
    2. int result = future.get();

四、高级特性与设计模式(10题)

  1. RAII原则
    资源获取即初始化,通过对象生命周期管理资源。例如文件操作:

    1. class FileHandle {
    2. FILE* file;
    3. public:
    4. FileHandle(const char* path) : file(fopen(path, "r")) {}
    5. ~FileHandle() { if (file) fclose(file); }
    6. };
  2. 虚函数与纯虚函数
    虚函数实现运行时多态;纯虚函数(= 0)强制子类重写。例如:

    1. class Base {
    2. public:
    3. virtual void foo() = 0; // 抽象类
    4. };
  3. STL容器选择指南

    • 序列容器:vector(随机访问)、list(频繁插入删除)、deque(双端操作)。
    • 关联容器:map(键值对)、set(唯一键)、unordered_map(哈希表)。
  4. 智能指针类型

    • unique_ptr:独占所有权。
    • shared_ptr:共享所有权,引用计数。
    • weak_ptr:解决循环引用。
  5. 单例模式实现
    使用局部静态变量(C++11后线程安全):

    1. class Singleton {
    2. public:
    3. static Singleton& getInstance() {
    4. static Singleton instance;
    5. return instance;
    6. }
    7. };

五、系统级与底层知识(10题)

  1. 内联函数与宏的区别
    内联函数有类型检查、可调试;宏无类型且可能多次求值。例如:

    1. inline int square(int x) { return x*x; } // 推荐
    2. #define SQUARE(x) ((x)*(x)) // 不推荐(如SQUARE(i++))
  2. 位操作技巧
    交换变量:a ^= b; b ^= a; a ^= b;。判断奇偶:if (x & 1)

  3. C++异常处理机制
    try/catch块捕获异常,throw抛出。例如:

    1. try {
    2. throw std::runtime_error("Error");
    3. } catch (const std::exception& e) {
    4. std::cerr << e.what();
    5. }
  4. 虚表(vtable)原理
    编译器为含虚函数的类生成虚表,存储虚函数指针。通过对象首地址访问虚表。

  5. 链接阶段错误排查

    • 未定义引用:未实现函数或未链接库。
    • 重复定义:头文件未加#pragma once#ifndef保护。

六、实战建议

  • 代码规范:遵循Google C++ Style Guide,使用clang-format自动化格式化。
  • 调试工具:GDB调试内存错误,Valgrind检测泄漏,AddressSanitizer快速定位问题。
  • 学习资源:阅读《Effective C++》《C++ Primer》,参与开源项目(如LLVM)。

本文覆盖的50道面试题均来自一线企业真题,建议结合LeetCode刷题巩固。掌握这些核心知识点后,可系统提升C/C++开发能力,从容应对技术面试。”

相关文章推荐

发表评论