安恒信息 C++开发 一面

1. 自我介绍

2. 既然你在项目中管理了大量内存,讲讲 std::unique_ptr 自定义删除器(Deleter)的用法和场景?

解答: 智能指针不仅可以管理内存,还能管理文件描述符(fd)、Socket连接或各种硬件资源。为了防止资源泄漏,可以给 unique_ptr 传入自定义删除器。相比于 shared_ptr 在运行时通过类型擦除调用删除器,unique_ptr 的删除器类型是模板参数的一部分,在编译期绑定,几乎没有额外开销。

#include <memory>
#include <unistd.h>

struct FdDeleter {
    void operator()(int* fd) const {
        if (fd && *fd >= 0) {
            close(*fd);
            delete fd;
        }
    }
};
// 使用:
std::unique_ptr<int, FdDeleter> safe_fd(new int(socket(...)));

3.计算机网络中,如果对端机器处理极慢,导致 TCP 接收窗口降为 0,会发生什么?如何恢复?

这就是 TCP 零窗口(Zero Window) 问题。当服务端的应用层(如你的消费者进程)由于阻塞未调用 read,导致系统接收缓冲区满时,会向客户端发送 Window=0 的 ACK 包。此时客户端的发送方会停止发送数据。为了避免死锁(即服务端后来有了窗口,但更新窗口的包丢了),客户端会启动一个零窗口探测定时器(Zero Window Probe),周期性地发送只包含 1 字节数据的探测包,强制服务端响应当前的真实窗口大小,直到窗口恢复后继续发送。

4. 介绍一下你简历上这两个项目中觉得更有挑战的一个?

5. 项目中网络通信没自己写,而是用的 muduo 库?那你介绍一下你在其他项目实现的 epoll 服务器?

我实现的 epoll 服务器是一个典型的 Reactor 模型(One Loop Per Thread)。

  1. 主线程运行 main Reactor,只负责监听监听套接字(listenfd),当有新连接进入时,触发 epoll_in 事件,调用 accept 获取新连接。
  2. 然后通过轮询或 Hash 算法,将这个新连接的 fd 分发给后端的 Thread Pool 中的某个 sub Reactor。
  3. sub Reactor 将该 fd 注册到自己的 epoll 实例中,专门负责处理这个连接后续的读写、数据解析和业务逻辑。

6. 你的 epoll 服务器没有使用第三方库进行序列化?那你介绍一下自定义的通信协议?

由于没有使用 Protobuf,我采用的是 TLV (Type-Length-Value) 格式的二进制自定义协议,这样能有效解决 TCP 粘包和半包问题。在 Socket 接收端,我会设定一个固定大小的 Header(比如 4 字节的 Package Length + 2 字节的 MSG_TYPE)。每次 read 时,先读满 Header 长度以解析出 Body 的大小;然后继续在缓冲区中等待,直到接收到的字节数等于 Body Length,才认为拼接出了一个完整的数据包,进而反序列化并抛给业务层。

7. 你的网络库是对 muduo 进行了二次封装?为什么把 connect 封装成 channel?

是的。在 muduo 的设计哲学中,Channel 是对文件描述符(fd)及其关心的 epoll 事件(如 EPOLLIN, EPOLLOUT)的直接封装。将由 connect 建立的 socket fd 封装为 channel 的好处是:彻底分离了底层 IO 事件与上层业务逻辑。Channel 内部保存了各种事件的回调函数(读、写、错误、关闭)。当 epoll 返回活跃事件时,直接根据触发的 Channel 执行其预设的回调,满足了高内聚、低耦合的非阻塞异步编程需求。

8. 再说一下日志系统,你采用的是双缓冲设计是吧,具体怎么设计的?

双缓冲(Double Buffering)主要是为了避免前端业务线程的打日志操作被磁盘 IO 阻塞。

  1. 准备两个 Buffer(A 和 B)。前端工作线程将日志追加到内存 Buffer A 中(只需加轻量级自旋锁或无锁队列,极快)。
  2. 后台专门有一个落盘线程。当 Buffer A 写满或到达定时器的刷新时间时,前后台快速交换(Swap) Buffer A 和 Buffer B 的指针。
  3. 交换后,前端继续将新日志写到 Buff

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论
这项目,看起来像小比特啊
点赞 回复 分享
发布于 昨天 21:27 安徽

相关推荐

最喜欢秋天的火龙果很...:第一份工作一定要往大的去,工资低点没事。后面换工作会更好找,即使你去小公司,你也不可能不会换工作的。所以找大的去
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务