安恒信息 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++工程能力.

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

相关推荐

03-09 20:07
已编辑
门头沟学院 Web前端
📍面试公司:杭州安恒信息🕐面试时间:3.3💻面试岗位:前端❓面试问题:一面:50+min两个项目问了很久。。。1.如果说现在已经写好了文档,但后端接口还没写好,前端部分你怎么完成?2.你做过什么优化吗,说出来你知道的优化方案?3.你用过什么&nbsp;AI&nbsp;写代码吗?4.你项目的&nbsp;vibe&nbsp;coding&nbsp;率能达到多少?5.说说&nbsp;mpc&nbsp;和&nbsp;skills?6.了解&nbsp;rules?7.有没有用&nbsp;AI&nbsp;做过好玩的小东西?8.Vue2&nbsp;和&nbsp;Vue3&nbsp;的区别9.组件通信10.v-if&nbsp;和&nbsp;v-show&nbsp;区别11.v-for&nbsp;渲染中,为什么要有&nbsp;key&nbsp;这个东西?12.reactive&nbsp;和&nbsp;ref&nbsp;的区别,存复杂对象用什么?13.reactive&nbsp;用在数组上的时候有坑,你知道吗?14.Git&nbsp;了解吗,项目有没有做权限控制?15.如果遇到&nbsp;Git&nbsp;冲突,怎么办?16.merge&nbsp;和&nbsp;rebase&nbsp;的区别知道吗?17.Webpack&nbsp;和&nbsp;Vite&nbsp;对比18.TS&nbsp;的泛型19.TS&nbsp;有什么优势,为什么用在项目中?20.我现在有一个&nbsp;interface,里面存了&nbsp;id、name、grade、content,我只想&nbsp;id&nbsp;变为必填项,其它选填,该怎么做?21.为什么学前端,有没有什么规划?二面:40min1.做完这个项目最大的收获是什么?....项目相关2.&nbsp;js&nbsp;为什么是单线程的?3.浏览器是多进程的还是单进程的,为什么要设计成多进程?4.假如你工作中,你和同事开发同一个功能,你同事的代码写的不规范,不够好,你怎么劝你的同事放弃它的代码?5.如果产品经理现在提了一个需求,复杂且要难实现,你怎么去跟产品经理沟通?6.你了解&nbsp;AI&nbsp;相关的东西吗,幻觉,提示词之类的?7.最近有没有做过&nbsp;ai&nbsp;相关的小项目,或者了解最新的&nbsp;ai&nbsp;相关的知识?8.你来公司实习,想得到什么收获?三面:30+min1.学校、生活、日常问题2.问项目,要看项目展示3.算法题,复原IP地址(只给了一串数字,忘了ipv4地址格式了,没做出来4.职业规划🙌面试感想:一面体验很好,面试官会引导。越往后面越恶心,三面面试官语气不是很好。
Ice124:补一句,算法题是面试官现场搜的,我在那等了好几分钟
发面经攒人品
点赞 评论 收藏
分享
牛客96569358...:跟我问的一样,这是一个无转正日常实习生该有的难度吗
查看17道真题和解析
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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