跳到主要内容

后端开发大厂面试高频知识点图解(现代C++)

一、后端知识体系总览


二、C++ 内存模型

RAII(资源获取即初始化)

智能指针对比

对比项unique_ptrshared_ptrweak_ptr
所有权独占共享无所有权
拷贝❌ 不可拷贝 只能移动✅ 引用计数+1✅ 不影响引用计数
开销零开销引用计数(原子操作) + 控制块同shared_ptr控制块
循环引用不存在⚠️ 会导致内存泄漏✅ 解决循环引用
使用场景默认首选共享资源观察者/缓存/打破循环

内存常见问题


三、C++ 并发编程

内存序(Memory Order)

生产者-消费者模式(C++实现)

#include <mutex>
#include <condition_variable>
#include <queue>

template<typename T>
class ThreadSafeQueue {
std::queue<T> queue_;
mutable std::mutex mtx_;
std::condition_variable cv_;
public:
void push(T value) {
{
std::lock_guard<std::mutex> lock(mtx_);
queue_.push(std::move(value));
}
cv_.notify_one(); // 通知一个等待的消费者
}

T pop() {
std::unique_lock<std::mutex> lock(mtx_);
cv_.wait(lock, [this] { return !queue_.empty(); }); // 谓词防止虚假唤醒
T value = std::move(queue_.front());
queue_.pop();
return value;
}
};
cpp

std::async 与 std::future


四、现代 C++ 核心特性

移动语义

// 移动语义核心
class MyString {
char* data_;
size_t size_;
public:
// 移动构造函数 —— O(1),只是指针交接
MyString(MyString&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr; // 源对象置空
other.size_ = 0;
}

// 移动赋值运算符
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}
};

// std::move 只是类型转换,不移动任何东西
auto s2 = std::move(s1); // s1 转为右值引用 → 触发移动构造
cpp

完美转发(Perfect Forwarding)

// std::forward 保持参数的值类别(左值/右值)
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
// 左值传入 → 转发为左值
// 右值传入 → 转发为右值
cpp

五、C++ 模板与泛型编程

Concepts(C++20)

// 定义概念
template<typename T>
concept Sortable = requires(T a, T b) {
{ a < b } -> std::convertible_to<bool>;
{ a == b } -> std::convertible_to<bool>;
};

// 使用概念约束模板
template<Sortable T>
void sort(std::vector<T>& vec) {
std::ranges::sort(vec);
}

// 不满足约束 → 编译期友好错误信息(比SFINAE清晰得多)
cpp

CRTP(奇异递归模板模式)

// 静态多态 —— 零虚函数开销
template<typename Derived>
class Base {
public:
void interface() {
static_cast<Derived*>(this)->implementation(); // 编译期派发
}
};

class Impl : public Base<Impl> {
public:
void implementation() { /* 具体实现 */ }
};
cpp

六、消息队列

消息队列核心问题


七、设计模式(C++实现)

单例模式最佳实践(C++)

// ✅ Meyers' Singleton(C++11起线程安全,标准保证局部static只初始化一次)
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // 线程安全,C++11保证
return instance;
}

Singleton(const Singleton&) = delete; // 禁止拷贝
Singleton& operator=(const Singleton&) = delete; // 禁止赋值
Singleton(Singleton&&) = delete; // 禁止移动
Singleton& operator=(Singleton&&) = delete;

private:
Singleton() = default;
~Singleton() = default;
};

// ✅ std::call_once 方式
class Singleton2 {
static std::unique_ptr<Singleton2> instance_;
static std::once_flag flag_;
public:
static Singleton2& getInstance() {
std::call_once(flag_, [] {
instance_.reset(new Singleton2());
});
return *instance_;
}
};
cpp

策略模式(C++ 多种实现)

// 方式1: 经典虚函数(运行时多态)
class SortStrategy {
public:
virtual ~SortStrategy() = default;
virtual void sort(std::vector<int>& data) = 0;
};

// 方式2: std::function(更灵活)
class Sorter {
std::function<void(std::vector<int>&)> strategy_;
public:
void setStrategy(auto&& fn) { strategy_ = std::forward<decltype(fn)>(fn); }
void sort(std::vector<int>& data) { strategy_(data); }
};

// 方式3: 模板参数策略(编译期多态,零开销)
template<typename Strategy>
class Sorter3 {
public:
void sort(std::vector<int>& data) { Strategy::sort(data); }
};
cpp

八、认证授权

JWT 结构

Header: {"alg": "HS256", "typ": "JWT"}  -- Base64编码
Payload: {"sub": "1234", "name": "John", "exp": 1735689600} -- Base64编码
Signature: HMACSHA256(base64(header) + "." + base64(payload), secret)

三部分用 . 连接: xxxxx.yyyyy.zzzzz
C++库: jwt-cpp / libjwt

OAuth2.0 四种授权方式

方式场景安全性
授权码模式Web应用(最常用最安全)⭐⭐⭐⭐⭐
简化模式纯前端SPA应用⭐⭐⭐
密码模式高度信任的第一方应用⭐⭐
客户端凭证模式服务间调用(无用户参与)⭐⭐⭐⭐

九、Docker & Kubernetes

K8s 核心架构

C++ 多阶段 Dockerfile 示例

# 构建阶段
FROM gcc:13 AS builder
WORKDIR /app
COPY . .
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build

# 运行阶段(最小镜像)
FROM debian:bookworm-slim
COPY --from=builder /app/build/server /usr/local/bin/
EXPOSE 8080
CMD ["server"]
dockerfile

十、RESTful API 设计

规范说明示例
资源名词复数URL表示资源,不用动词/api/v1/users
HTTP方法表示操作GET/POST/PUT/DELETEGET /users/123
版本号放在URL或Header/api/v1/
状态码语义化200/201/204/400/401/403/404/500-
分页page/size 或 cursor?page=1&size=20
过滤/排序query参数?status=active&sort=-created
错误格式统一code + message + details{"code":40001,"msg":"参数错误"}

C++ Web 框架对比

框架特点性能
Drogon全功能、非阻塞IO、ORM、WebSocket⭐⭐⭐⭐⭐
oat++零拷贝、协程、Swagger集成⭐⭐⭐⭐⭐
Crow类Flask简洁API、Header-only⭐⭐⭐⭐
Cinatra国产、C++20协程⭐⭐⭐⭐
Pistache轻量REST框架⭐⭐⭐
Boost.Beast底层HTTP/WebSocket库⭐⭐⭐⭐⭐

十一、C++ 编译与构建


十二、高频面试题速查

问题答案要点
智能指针有哪些?区别?unique_ptr独占零开销;shared_ptr引用计数共享;weak_ptr弱引用解决循环引用
移动语义是什么?转移资源所有权而非拷贝,std::move将左值转为右值引用,触发移动构造/赋值
左值和右值的区别?左值有地址可取地址;右值是临时值。C++11: 右值引用&&延长临时对象生命周期
virtual析构函数何时需要?基类指针删除派生类对象时必须;否则派生类资源泄漏(未定义行为)
虚函数表(vtable)原理?每个有虚函数的类有一个vtable;对象含vptr指向vtable;虚函数调用通过vptr间接跳转
什么是RAII?资源获取即初始化,构造获取析构释放,利用栈对象生命周期自动管理资源
std::move实际做了什么?只是static_cast为右值引用,本身不移动任何东西,让编译器选择移动构造/赋值
如何避免内存泄漏?智能指针 + RAII;valgrind/ASan检测;避免裸new/delete
const和constexpr区别?const运行期常量(也可编译期);constexpr保证编译期求值(C++11函数/C++14扩展)
模板特化 vs 重载?函数优先用重载(更直观);类模板用特化/偏特化
Kafka如何保证消息不丢?acks=all + 同步刷盘 + ISR + 手动提交offset
如何设计一个秒杀系统?前端限流→Nginx→网关限流→Redis扣库存→MQ异步下单→DB
接口幂等性如何实现?Token机制 / 唯一ID + 数据库唯一键 / Redis SetNX / 状态机
请作者喝奶茶:
Alipay IconQR Code
Alipay IconQR Code
本文遵循 CC CC 4.0 BY-SA 版权协议, 转载请标明出处
Loading Comments...