米哈游 服务器开发方向 C++ 一面 面经

1. 协程和线程的本质区别是什么?协程的调度是由谁控制的?

线程由操作系统内核调度,切换需要陷入内核态,开销大(保存/恢复寄存器、栈、上下文)。协程是用户态的轻量级执行单元,调度由程序自身控制(协作式),切换只需保存少量寄存器,无系统调用开销。协程共享线程栈,适合高并发 IO 密集型场景,如游戏服务器的大量连接处理。

2. epoll 的 LT 和 ET 模式有什么区别?ET 模式下如何避免数据丢失?

LT(水平触发):只要 fd 可读/可写就持续通知,未处理完下次还会触发,使用简单但效率略低。ET(边缘触发):只在状态变化时触发一次,必须一次性把数据读完,否则不再通知。ET 下避免丢失的做法:将 fd 设为非阻塞,循环 read 直到返回 EAGAIN/EWOULDBLOCK 为止。

3. Reactor 和 Proactor 模式有什么区别?游戏服务器一般用哪种?

Reactor 是同步非阻塞模型,事件就绪后由应用层自己去读写数据(如 epoll + 非阻塞 IO)。Proactor 是异步模型,内核完成 IO 后才通知应用层(如 Windows IOCP)。游戏服务器在 Linux 上通常用 Reactor 模式,配合线程池处理业务逻辑,典型实现如 muduo、libevent。

4. TCP 四次挥手中,为什么 TIME_WAIT 状态需要等待 2MSL?

MSL 是报文最大生存时间。等待 2MSL 有两个原因:① 确保最后一个 ACK 能到达对端,若对端没收到会重发 FIN,2MSL 内能收到并重传 ACK;② 让本次连接的所有报文在网络中消亡,防止旧连接的延迟报文被新连接误收。

5. TCP 的滑动窗口和拥塞控制有什么关系?拥塞控制的四个阶段是什么?

滑动窗口是流量控制机制,由接收方通告窗口大小限制发送速率。拥塞控制是发送方根据网络状况自适应调整发送量,实际发送量 = min(拥塞窗口, 接收窗口)。四个阶段:① 慢启动:cwnd 指数增长;② 拥塞避免:cwnd 线性增长;③ 快重传:收到 3 个重复 ACK 立即重传;④ 快恢复:ssthresh = cwnd/2,cwnd = ssthresh 后进入拥塞避免。

6. UDP 如何实现可靠传输?说说 KCP 的核心思路。

UDP 本身不可靠,要实现可靠传输需在应用层加:序列号、ACK 确认、超时重传、滑动窗口、乱序重排。KCP 的核心思路:以带宽换延迟,取消 Nagle 算法,降低 RTO 计算的保守程度(1.5x 而非 2x),支持选择性重传(SACK),减少不必要的等待,适合游戏实时对战场景。

7. std::movestd::forward 的区别是什么?

std::move 无条件将左值转为右值引用,触发移动语义,转移资源所有权,避免深拷贝。std::forward 是完美转发,保留参数的原始值类别(左值还是右值),用于模板函数中将参数原封不动地传递给下一层,避免多余拷贝。本质上两者都只是 static_cast,不产生任何运行时代码。

8. 虚函数表(vtable)的布局是怎样的?多继承时 vtable 有几张?

每个含虚函数的类有一张 vtable,存放虚函数指针数组。对象内存开头存放 vptr 指向该表。单继承时子类复用父类 vtable 并覆盖重写的槽位。多继承时每个有虚函数的基类对应一张 vtable,子类对象内存中有多个 vptr,调用不同基类的虚函数时使用对应的 vptr,存在 thunk 调整 this 指针偏移。

9. weak_ptr 解决了什么问题?它是如何判断对象是否还活着的?

weak_ptr 解决 shared_ptr 循环引用导致内存泄漏的问题(如 A 持有 B 的 shared_ptr,B 持有 A 的 shared_ptr,引用计数永远不为 0)。weak_ptr 不增加强引用计数,通过控制块中的弱引用计数跟踪。判断对象是否存活:调用 lock() 尝试提升为 shared_ptr,若强引用计数已为 0 则返回空指针。

10. 内存池的设计思路是什么?游戏服务器为什么需要内存池?

内存池预先向系统申请一大块内存,按固定大小或分级管理,分配时直接从池中取,释放时归还到池而非还给系统。游戏服务器需要内存池的原因:① 频繁 new/delete 导致内存碎片;② 系统调用开销大,影响帧率和延迟;③ 内存池分配/释放是 O(1),且局部性好,缓存命中率高。常见实现:固定块内存池、tcmalloc、jemalloc。

11. std:: 和 在游戏服务器中如何选择?

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

C++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论
总结的很好呢
点赞 回复 分享
发布于 04-02 22:33 北京

相关推荐

一面已通过。1.介绍实习时的主要工作2.本科时是否做过服务端相关项目3.Java垃圾回收机制4.会存在内存碎片化之类的问题吗5.Java Spring的Bean的生命周期是什么样子的6.介绍Java多线程7.轻量级锁自旋失败,转换为重量级锁的过程是什么样子的8.如果要设计一个高并发的订单号生成器,要求全局唯一且可以递增,应该怎么设计9.能介绍一下上下文工程和Harness工程的区别吗10.上下文summary的策略是什么样子的11.怎么去缓解内容被压缩导致结果失真的问题12.RAG文档的分片策略是怎么样子的13.假设召回的一个片段不足以解决问题,怎么优化14.对于更深入的场景,比如文档有语义或组织关系,召回的片段可能指向别的文档,怎么优化15.了解过 Agentic search 吗16.React 和 Plan Execute模式的区别17.如果是比较复杂的场景,既需要 Plan Execute,又需要 React 及时感知进度或外界信息并做反馈调整,这种场景需要怎么设计18.项目是否拿到上线后的测试数据19.假设项目需要升级,需要定位到具体出问题的代码,怎么做20.假设没有堆栈报错,怎么做21.现在需要做成通用平台或工具,给所有业务使用,怎么设计这样一套工具22.怎么把人在排查问题中积累的经验给到系统23.大模型的工具调用能力是什么24.MCP和Skill的区别是什么25.介绍CNN和Transformer的区别26.为什么位置编码能够体现句子中分词的关系27.为什么说模型有上下文限制28.像 Cloude 这种模型,上下文窗口可能只有 200K,并不大,为什么不做得更大一些呢29.模型的参数量是什么时候定的30.为什么提供这么多不同参数量的模型31.像模型上层的 SFT、Lora 这些微调,之前有做过吗32.RL和SFT的区别33.RL的数据源从哪里来34.鸿蒙的 ARKTS 你觉得和安卓有什么区别35.它的整个应用的启动链路是怎么样的反问:岗位具体情况。答:岗位的核心课题是如何用 AI 赋能整个产品线,打造 Agent 能力,不再局限于前端、客户端或服务端某一个领域,希望具备全栈相关的能力。
点赞 评论 收藏
分享
03-31 00:30
已编辑
门头沟学院 golang
无手撕,被面试官暴打一小时,第一次被拷打 go 相关的内容,被拷打得我想找个地缝钻进去,😭我是菜🐶,我的腾讯面试之旅结束了 qwq。1. go routine 是啥怎么调度的。2. 如果 gmp 中 p 的分配是怎么分配的(go语言 runtime系统进行内存管理,调度器还有系统调度封装)3.向一个 nil channel发送读取消息会怎么样?4.向一个close的channel接发消息会有什么结果?5.slice是引用还是还是拷贝(我最开始很干脆地说是引用,结果面试官一副匪夷所思的语气:你确定?我就跟他说是拷贝,被戏耍麻了😭,只能怪自己基础不牢)6.内存逃逸是什么,简单介绍一下。7.接口的底层实现,接口的类型。8.闭包求输出:funcs := []func(){}for i := 0; i < 3; i++ {funcs = append(funcs, func() {fmt.Println(i)})}for _, f := range funcs {f()}其实这个答案根据 go 的不同版本,输出结果不同。在 1.22 之前,输出是三个 3, 因为循环内的 i 实际上地址是指向同一处的。但是在 1.22 及之后,结果是 0, 1, 2, 如果这个时候你打印一些 i 的地址,你会发现地址是不相同的。因为 go 在 1.22 更新了 for 循环(包括 range)的方式,循环内的临时变量 i 和 range 中取出的数据都是完全独立的一份拷贝,而且指向的地址不相同!9.Go GC 机制讲解一下,什么是写屏障,如果没有写屏障,可能会有什么情况?10.让我们来聊聊你的项目吧,来看看你的项目,啊哈!~达人探店项目,高并发店铺点评博客项目",介绍一下你的项目,你如何实现异步秒杀的?如何防止超卖,如何实现一人一单,如何使用分布式锁,lua 脚本是怎么写的?怎么实现消息不丢失的?压测怎么做的?有没有使用过阿波罗普罗米修斯宙斯哈迪斯盖亚(已晕qwq)等压测工具,有没有压测过你的各个缓节的时间,你的性能瓶颈在哪里?Redis 如果 set 数据量较大的情况下如何进行大 key 值拆分,你的 Redis 是单机还是主从?你的 kafka 有几个节点,划分了几个 partition?有几个消费者节点,你的项目有几个服务?11. 有什么经常用的 AI coding 的工具?有 Agent 开发相关的经历吗?哦?你还了解过 Agent 开发? MCP、RAG#@$*^~你能展开讲讲吗?12. 反问:请教之前空接口,受教了。给了本菜🐕一点建议:go 的基础太不牢了,作为主要的开发语言来说是不够格的。期间面试官一直没开视频,但我隐隐听到他在偷笑
点赞 评论 收藏
分享
评论
3
10
分享

创作者周榜

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