每日做面经-25.11.16

1.weak_ptr解决lambda捕获this导致循环引用

📌 2. Lambda 表达式中的 weak_ptr 解决方案

❌ 问题:Lambda 捕获 this 导致循环引用

复制代码
class MyClass {
public:
    void start() {
        // 错误:捕获 this 会导致循环引用
        timer_.async_wait([this](auto...) {
            // 处理逻辑
        });
    }
private:
    boost::asio::steady_timer timer_;
};

✅ 正确方案:用 weak_ptr 代替 this

复制代码
class MyClass {
public:
    void start() {
        // 创建 weak_ptr 用于安全捕获
        auto self = std::weak_ptr<MyClass>(shared_from_this());
        timer_.async_wait([self](auto...) {
            if (auto ptr = self.lock()) {
                // 安全访问 ptr
            }
        });
    }
private:
    boost::asio::steady_timer timer_;
};

💡 为什么有效
weak_ptr::lock() 返回 shared_ptr,如果对象已销毁则返回空指针,避免访问已释放内存。

2.线程,进程创建方法

Linux 创建进程/线程

🐳 创建进程

复制代码
pid_t pid = fork(); // 复制当前进程
if (pid == 0) {
    // 子进程
} else {
    // 父进程
}

🐤 创建线程

复制代码
pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);

💻 C++ 创建线程

复制代码
#include <thread>
void thread_func() { /* ... */ }
std::thread t(thread_func);
t.join(); // 等待线程结束

💡 为什么 C++ 用 std::thread

跨平台、RAII 安全(自动管理线程生命周期)。

3.TCP socket 编程流程

📡 服务端:

复制代码
int sock = socket(AF_INET, SOCK_STREAM, 0);
bind(sock, ...);
listen(sock, 5);
int conn = accept(sock, ...);
recv(conn, ...);
send(conn, ...);
close(conn);
close(sock);

📡 客户端:

复制代码
int sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, ...);
send(sock, ...);
recv(sock, ...);
close(sock);

💡 关键点

  • 服务端:bindlistenaccept
  • 客户端:connect → 通信

4.weak_ptr除了循环引用,还解决了哪些问题。

  1. 资源存在性检测 (最实用的功能!) weak_ptr能让你在访问对象前先检查一下:"嘿,这个对象还在吗?"这通过expired()方法实现。比如在事件系统中,你可以在触发回调前先检查对象是否还活着,避免访问已经销毁的对象。

  2. 避免悬空指针 (C++开发者最头疼的问题之一) 通过lock()方法,weak_ptr能安全地转换成shared_ptr,如果对象已经销毁,lock()会返回空指针。这样就能避免"使用已释放内存"的未定义行为,就像给你的代码加了个安全气囊。

  3. 提供非拥有式观察机制(这才是weak_ptr的精髓!) 它不增加引用计数,只是"安静地观察"对象状态,不会影响对象的生命周期。这在很多场景下特别有用:

    • 缓存系统:缓存对象引用但不阻止对象被销毁
    • 观察者模式:主题可以弱引用观察者,避免观察者与主题间的循环引用
    • 树形结构:子节点弱引用父节点,避免父子节点相互持有导致的内存泄漏

5.gcc编译的时候,可执行程序崩溃了,应该怎么查找崩溃的原因? 编译成功,但是运行时崩溃了?

  1. 看错误信息

    • Linux:Segmentation fault (core dumped)Bus error
    • Windows:0xC0000005 (访问违规) 或 0xC0000279 (未知错误)
  2. 获取更多信息

    • Linux:dmesg -T | tail 看内核日志
    • Windows:查看"事件查看器"中的应用程序错误

🔍 排查步骤(从易到难)

✅ 第一步:检查编译警告(90%的问题都藏在这里!)

复制代码
gcc -Wall -Wextra -Werror your_program.c -o your_program
  • -Wall:显示所有警告
  • -Wextra:显示额外警告
  • -Werror:把警告当错误处理

💡 知识库[7]提到,很多崩溃其实是"函数没有return"导致的,编译器会警告但不会报错,加上-Werror就能提前发现。

🧪 第二步:用GDB调试(最直接有效的方法!)

复制代码
gdb ./your_program
(gdb) run
# 程序崩溃后
(gdb) backtrace  # 查看调用栈
(gdb) print variable_name  # 查看变量值
(gdb) list  # 查看崩溃附近的代码

💡 知识库[9]提到,GDB是排查运行时崩溃的神器,能精确找到崩溃位置。

🧪 第三步:内存错误检测(Valgrind)

复制代码
valgrind --tool=memcheck --leak-check=full ./your_program

Valgrind会报告:

  • 无效的内存访问(如野指针)
  • 内存泄漏
  • 数组越界

💡 知识库[8]提到,90%的运行时崩溃都是内存问题,Valgrind能帮你精准定位。

🔍 第四步:检查常见崩溃原因

崩溃类型 常见原因 解决方法
段错误 空指针解引用、数组越界、使用已释放内存 检查指针初始化、添加边界检查、释放后置空
未定义引用 链接时缺少库 添加-l库名,如-lm链接数学库
优化导致崩溃 编译优化选项问题 尝试-O0编译,排除优化问题
依赖库问题 DLL/动态库缺失或版本不匹配 检查ldd(Linux)或依赖库安装

💡 知识库[5]提到,我曾经遇到过一个-O3优化导致的崩溃,用-fno-tree-loop-vectorize就解决了。

🧪 第五步:简化问题(快速定位)

  1. 写个最小可复现代码(最小测试用例)
  2. 逐步添加代码,定位问题点
  3. printf在关键位置输出,确认执行流程

💡 知识库[3]提到,C语言"代码正确却无法运行"的常见原因,很多都是因为编译检查的局限性,需要运行时验证。

🌟 实用技巧

  1. 在关键位置加日志

    复制代码
    std::cout << "Before malloc: " << ptr << std::endl;
    ptr = malloc(100);
    std::cout << "After malloc: " << ptr << std::endl;
  2. 检查编译器版本

    复制代码
    gcc --version
    • 知识库[11]提到,不同版本GCC对代码处理可能不同
  3. 检查系统环境

    • Linux:ldd ./your_program 查看依赖库
    • Windows:确保安装了VC++运行库

6.http的get和post有什么区别吗?

GET是"只读小能手",适合"查资料";POST是"提交小能手",适合"交作业"。

特性 GET POST 通俗解释
数据位置 URL后面(?key=value) 请求体中 GET:参数在地址栏,谁都能看到 POST:参数藏在"信封"里,只有服务器能看
数据长度 受限(2KB~8KB) 无限制 GET:只能写"小纸条" POST:能寄"大包裹"
安全性 低(参数暴露在URL) 较高(参数在Body) GET:像在公开场合说密码 POST:像在私密房间说密码(但还是要HTTPS加密!)
幂等性 幂等(多次请求结果相同) 非幂等(可能重复创建资源) GET:刷新页面,结果一样 POST:刷新支付页面,可能多扣钱
缓存 可缓存 不可缓存 GET:浏览器会记住,下次直接用 POST:每次都要重新提交
书签 可保存为书签 不可保存为书签 GET:能收藏喜欢的搜索结果 POST:不能收藏"提交按钮"
TCP包数量 1个 2个(有时) GET:一次搞定 POST:先问"能发吗?",再发内容
适用场景 查询、获取数据 提交数据、创建资源 GET:搜索"手机",看商品详情 POST:登录、注册、提交订单
相关推荐
菜鸟-012 小时前
上位机---QT
开发语言·qt
她说彩礼65万2 小时前
C# Lambda 表达式
开发语言·c#
Bug快跑-12 小时前
Java、C# 和 C++ 并发编程的深度比较与应用场景
java·开发语言·前端
2501_941111462 小时前
高性能计算集群部署
开发语言·c++·算法
普通网友2 小时前
模板编译期机器学习
开发语言·c++·算法
普通网友2 小时前
C++与机器学习框架
开发语言·c++·算法
普通网友2 小时前
C++安全编程指南
开发语言·c++·算法
学困昇2 小时前
C++11中的右值引用和移动语义
开发语言·c++
有梦想的攻城狮2 小时前
初识Rust语言
java·开发语言·rust