
Unity客户端面试里网络这一块的比例不算特别高但几乎每轮都会碰见。尤其是初级岗位不会一上来就问分布式架构、拥塞控制那些深水区反而喜欢从最基础的TCP/UDP、HTTP/HTTPS、Socket、客户端收发消息流程这些点入手一层层往下问。这篇面经就是给准备Unity客户端岗位的初级开发者准备的把网络方向常考的东西、答题思路以及我自己参与面试时见过的典型翻车现场一起梳理一遍。先说清楚一个事情初级岗位的网络面试考的不是你要能独立写出一套网络库而是考察你有没有“网络意识”。什么叫网络意识就是你写一个登录功能不只是调一个接口而是清楚这条消息从客户端出发经过了哪些层到服务端后怎么被处理返回时又走了什么链路出了问题你大概知道往哪个方向排查。这个意识比背多少协议细节都重要。1. 网络面试到底在考什么先搞懂出题人的意图1.1 初级岗位的网络能力模型很多人在准备阶段容易走偏一上来就死磕TCP的拥塞控制算法、TCP BBR、QUIC协议这些进阶内容结果面试官问了个“Unity里怎么发一个HTTP请求”反而答得支支吾吾。初级岗位的网络能力模型其实可以拆成三层第一层是协议基础包括TCP/UDP的区别、三次握手四次挥手、HTTP/HTTPS的基本语义、Socket概念。这是面试的“入场券”不需要你背到RFC级别但核心机制必须说清楚。第二层是Unity引擎内的网络API使用经验比如UnityWebRequest、AsyncOperation、协程和回调、JsonUtility等。对应届生或者经验浅的候选人面试官最想确认的是你真的在项目里用过这些API而不是只看了教程。第三层是游戏特有的网络概念比如状态同步、帧同步、断线重连、消息协议设计。这一层初级岗位不会问得太深但至少你要能说出“帧同步和状态同步有什么区别”这种级别的内容。所以建议按这个顺序去准备先把协议基础打牢再整理自己做过的Unity网络功能最后了解一下游戏同步的基本概念。别反过来。1.2 面试官的考察路径与常见套路我自己参与面试时问网络相关问题通常有一个固定路径先问一个宽泛的比如“客户端和服务端通信底层有哪些方式”然后根据你的回答沿着某个点往下追。你要是主动提到TCP我就会顺势问“TCP为什么可靠”你要是提到“用了HTTP”我就会问“HTTP和TCP是什么关系”。整个过程很像剥洋葱一层一层往里钻。这种方式让你很难靠背题过关。因为同一个问题只要你换个项目背景、换个数据量答案就可能不一样。比如“如果玩家点击攻击客户端怎么把这个消息发给其他玩家”你光说“发个UDP不就行了”是不够的面试官会追问丢包怎么办要不要服务器校验其他玩家是收到原始输入还是收到结算结果所以这块的准备重点不是去背一份标准答案列表而是把网络的知识织成一张网知道协议之间的关系知道每一个机制解决的是什么问题知道在Unity里写代码时有哪些坑。下面我会按这个思路把常考的内容一块一块拆开讲。2. 必须吃透的基础协议TCP/UDP/HTTP/HTTPS2.1 TCP三次握手与四次挥手不只是背状态三次握手几乎是必考题这个没什么争议。但很多人的回答停留在“客户端发SYN服务器回SYNACK客户端再回ACK”这个层面能把这个说清楚其实已经可以及格了。问题是面试官通常会加一句“为什么需要三次两次不行吗”这个问题才是真正的分水岭。两次握手最大的问题在于客户端第一次发的SYN报文如果因为网络延迟被卡了很久客户端超时重传服务器收到重传的SYN后回了SYNACK这时候旧的SYN又到了服务器服务器会再回一个SYNACK认为连接建立了。如果只是两次握手服务器就会为这条“死连接”资源白白等着。而三次握手因为客户端收到SYNACK后还需要再回一次ACK服务器只有在收到这个ACK后才算建立连接旧的那个SYNACK没有对应ACK服务器就知道这个连接不用建立了。用生活化的例子讲两次握手就像你给对方发了一条微信“今晚吃饭吗”对方回了“好”你以为约上了但可能你的消息其实发了两遍第一遍是延迟了很久才到的旧消息对方回的是那个旧消息你以为他答应的是你现在这顿实际上他已经吃完了。三次握手等于对方回“好”之后你还得再确认一下“好的那就今晚”对方看到这个确认才真正去订位。四次挥手也比很多人以为的要复杂。主动关闭方发FIN被动方回ACK然后被动方进入CLOSE_WAIT状态这时候被动方还可以继续发数据发完后再发FIN主动方回ACK最后主动方进入TIME_WAIT状态等待2MSL。面试里容易漏掉的点是被动方的ACK和FIN是分开的不能合并成一次。原因是TCP是全双工的两个方向的数据通道要分别关闭。就好比两个人打电话一个人说“我说完了你还有要说的吗”对方说“知道了”但对方可能还有话要说等他说完了才会说“我也说完了”。如果不区分这两个方向就可能把对方还没说完的话给掐断。TIME_WAIT这个状态也值得主动提一句它能保证最后一个ACK如果丢了被动方重发FIN时主动方还能响应同时让旧连接的延迟报文在网络中消失不至于干扰新连接。在Unity客户端里TIME_WAIT一般不是问题但如果你用同一端口频繁重连偶尔会遇到端口被占用的报错这背后就是TIME_WAIT在起作用。2.2 TCP的可靠性机制不是一句话就能带过的面试官问“TCP为什么比UDP可靠”你要是只答“TCP有重传机制”分数不会高。一个更好的回答结构是把可靠性拆成几个机制来讲一是确认应答与序号。TCP把数据切成一个个报文段每个字节都有序号接收方收到后会回ACK确认。发送方如果在规定时间内没收到ACK就会认为报文丢了或者出错触发重传。这是可靠性的地基。二是超时重传与快速重传。超时重传是等到超时时间到了还没收到ACK就重发快速重传是接收方收到乱序数据时会立刻重复发送对缺失数据的ACK发送方连续收到三个相同ACK后不等超时立刻重传。三是流量控制。接收方在自己的窗口字段里告诉发送方“我还能接收多少数据”发送方据此调整发送速率避免把接收方缓冲区撑爆。这个在面试里可以说得稍微细一点滑动窗口是接收方和发送方各自维护的一个区间窗口大小会动态变化。四是拥塞控制。虽然初级岗位不太会深挖但提一句“TCP会根据网络拥塞状态调整发送速率有慢启动、拥塞避免、快重传、快恢复几个阶段”就足够了。注意别把流量控制和拥塞控制搞混流量控制是端到端的解决“接收方来不及处理”的问题拥塞控制是全局的解决“网络中间设备处理不过来”的问题。要特别提醒的是TCP的可靠性是“传输层”的可靠不等于“应用层”的可靠。面试官经常在后面加一个问题“所以客户端发了条登录消息就一定能登录成功吗”答案是不能。因为TCP只能保证消息正确到达对端的内核缓冲区不保证对端应用层一定处理成功。如果服务端进程崩了、数据库写失败了、或者服务器返回了“密码错误”TCP层面看起来依然“可靠”。这就要在应用层再做一层ack和超时重试。2.3 UDP与TCP怎么选游戏里的真实场景TCP和UDP的选择问题是初级岗位的高频题也是能看出候选人有没有项目经验的地方。TCP适合对完整性要求高、实时性要求低的场景。登录注册、商城购买、背包数据、排行榜、活动配置这些都不会用UDP因为丢了任何一条数据都是事故。比如你买了一件装备这条消息丢了玩家会直接炸毛。UDP适合对实时性要求高、允许少量丢失的场景。比如玩家位置同步、技能释放、子弹轨迹、操作指令这类高频信息。这里要纠正一个很多人常犯的错误UDP并不代表“一定会丢包”而是“丢了也不负责”。在同一个局域网里UDP丢包率其实很低但在公网跨地域环境下丢包和乱序就明显了。如果你面试时能主动说出下面这句话会很加分“网络协议的选择不是非黑即白的实际项目里经常是TCP和UDP混用甚至会在UDP之上自己实现一套可靠机制比如给消息编号、加ack、做重传和排序这就是常说的可靠UDP。”不同品类游戏的选型也不一样。MMORPG里的移动同步早期很多用TCP但因为TCP的队头阻塞问题在弱网环境下体验会很差所以后来很多游戏改用UDP或者KCP这类基于UDP的可靠协议。FPS和MOBA对延迟极其敏感基本都会走UDP。卡牌、SLG、休闲游戏如果实时性要求不高直接用TCP甚至HTTP就够了。回答的时候结合具体游戏类型去说会显得你是有思考的。2.4 HTTP/HTTPS与Unity侧的常见使用HTTP在Unity客户端开发里主要用来做非实时通信登录、注册、拉取公告、上传战绩、获取活动配置等。Unity里最常用的类是UnityWebRequest它比老的WWW类功能更全可以处理Get、Post、Put、Delete等请求还支持下载文件、上传表单、设置请求头。面试官如果问HTTP和TCP的关系你要能说清楚HTTP是应用层协议它依赖TCP作为传输层。也就是建立连接、可靠传输这些事是TCP干的HTTP只是规定了“请求和响应的格式”。打个比方TCP是高速公路和货车HTTP是货车上贴的快递单规定了从哪寄、寄给谁、里面装了什么类型的东西。状态码这一块也建议记熟几个常见的200表示成功201表示创建成功400表示客户端请求参数错误401表示未认证403表示无权限404表示资源不存在500表示服务器内部错误502表示网关错误。UnityWebRequest里经常会出现一个现象请求明明返回了500但Unity那边没有抛异常只是isDone变成true需要通过responseCode去判断。这个细节很多人踩过坑可以拿去面试里当自己的经验讲。HTTPS多了一层SSL/TLS加密面试里问到概率不小。核心机制是客户端先拿到服务器的证书用CA公钥验证证书合法性然后通过非对称加密协商出一个对称加密密钥后续通信全部用这个对称密钥加密。这个过程叫TLS握手。在Unity里如果你用UnityWebRequest发HTTPS请求证书校验失败时会直接报错Android平台上还经常遇到证书信任问题解决办法一般是让服务器配上完整证书链或者把用到的公钥证书打进客户端。3. Unity客户端网络编程的实操要点3.1 从Socket到上层业务网络层怎么做分层面试时如果聊到“你在项目里怎么用Socket”一个能让面试官点头的回答是我平时不会在业务代码里直接写Socket而是把网络层拆成几层来做。这个回答能体现你的工程意识。常见分层大概是这样的连接层负责Socket的创建、连接、断开、重连以及心跳包的发送。协议编解码层负责把业务数据结构序列化成字节流或者把收到的字节流解析成业务消息。消息派发层根据消息ID把不同的消息分发给对应的业务处理模块。业务逻辑层UI、角色控制、玩法逻辑等只关心“收到了一个消息”不关心消息是怎么从网络到达的。这样分层的好处是业务层不用关心网络细节网络层也不用关心业务逻辑。假如你要从TcpClient换成一个自定义网络库只要协议编解码和派发的接口不变业务层代码一行都不用改。用C#写一个最简的TCP客户端其实代码量不大TcpClient client new TcpClient(); await client.ConnectAsync(ip, port); NetworkStream stream client.GetStream(); byte[] data Encoding.UTF8.GetBytes(hello); await stream.WriteAsync(data, 0, data.Length); byte[] buffer new byte[1024]; int n await stream.ReadAsync(buffer, 0, buffer.Length); Debug.Log(Encoding.UTF8.GetString(buffer, 0, n));这段代码虽然能跑但如果项目里直接这么写会被打得很惨。因为接收数据不一定是“发一次收一次”的整齐对应可能你读到的数据里包含了半条消息、两条消息、甚至半条消息加一条完整消息。这就引出了网络编程里最经典的话题粘包和拆包。3.2 粘包拆包问题与消息协议设计粘包拆包问题初级面试里出现的频率其实很高。为了防止背题建议先理解它的成因。TCP是流式协议它底层不关心你发了几次数据只按照接收方的缓冲区大小把字节流切割后往上送。所以可能出现你两次调用Write分别发送了“你好”和“世界”服务端一次Read读到的却是“你好世界”这叫粘包。也可能你一次调用Write发送了一长串数据服务端分两次Read才读完这叫拆包或者说半包。解决思路通常是“在消息前面加长度头”每个消息规定一个格式前4个字节用int表示正文长度后面是正文。接收方先读4个字节知道正文有多长再接着读对应长度的字节就能精确切出一条完整消息。不够了就继续存着等下一次再读。// 发送消息先把长度写入头部再拼接正文 byte[] body Encoding.UTF8.GetBytes(jsonString); byte[] sendBuffer new byte[body.Length 4]; byte[] lenBytes BitConverter.GetBytes(body.Length); Buffer.BlockCopy(lenBytes, 0, sendBuffer, 0, 4); Buffer.BlockCopy(body, 0, sendBuffer, 4, body.Length); stream.Write(sendBuffer, 0, sendBuffer.Length);接收端用一个临时缓冲区把每次Read到的数据追加进去然后循环检查如果缓冲区长度大于4就读出头部长度如果缓冲区长度还够一个完整消息就按长度切出来交给消息派发层。这里有个很容易忽略的细节字节序。C#的BitConverter在Windows上默认是小端序而很多服务端协议或者通信中间件默认使用大端序网络字节序。如果两边没对齐解析出来的长度会变成一个超大数字或者负数直接导致断线。所以在设计协议时一定要约定好字节序。Unity里想省事可以这样写int length System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));再进一步序列化方案怎么选最简单的可以用JSON可读性好但字节数多、性能差性能敏感的业务一般用protobuf之类的二进制序列化方案。在面试里这点可以主动提一句“我在项目里用的是protobuf配合消息ID做分发派发层用一个字典注册消息处理函数。”这样就把协议编解码、序列化、消息分发全部串起来了。3.3 主线程与网络线程Unity的线程模型这一块是Unity面试里很有特色的考点因为其他不少客户端端技术面试不太会这么强调线程。Unity的API基本只能在主线程调用而网络收包天然是异步的要么在子线程里阻塞读要么在回调里收。如果你直接在子线程里收到消息后去操作GameObject轻则报错“get_gameObject can only be called from the main thread”重则偶发性崩溃特别难排查。一个标准做法是收包线程只负责把收到的消息解析成消息对象然后塞进一个线程安全的队列主线程在Update里每帧从队列里取消息再分发给业务逻辑处理。ConcurrentQueueBaseMessage messageQueue new ConcurrentQueueBaseMessage(); // 子线程接收 void OnMessageReceived(BaseMessage msg) { messageQueue.Enqueue(msg); } // 主线程每帧处理 void Update() { while (messageQueue.TryDequeue(out BaseMessage msg)) { Dispatch(msg); } }C#的ConcurrentQueue内部有锁但在这种低频率出队操作下性能足够。如果你对性能有更高要求也可以自己实现环形缓冲或者双缓冲队列但初级岗位能说出“用ConcurrentQueue暂存主线程消费”这个方案已经足够了。关于“网络操作放子线程还是主线程”的问题也常被问到。记住一个结论阻塞式网络操作尤其是同步Read不要放主线程否则一旦网络卡住或服务端不返回整个游戏直接卡死异步API如UnityWebRequest、async/await封装在主线程用没问题因为底层不会阻塞调用线程。3.4 Unity常用网络方案选型面试里经常会被问“Unity项目里做网络通信一般有哪些方案”这时候你可以列一个对比表展示自己对生态的熟悉程度方案协议/类型适合场景优点缺点UnityWebRequestHTTP/HTTPS登录、配置、资源下载官方支持API简单支持协程/async不适合高频实时通信原生TcpClient/UdpClientTCP/UDP自研网络层灵活可控性能好无额外依赖要自己处理粘包、分包、重连、心跳WebSocket基于TCP的全双工WebGL、微信小游戏、实时对战浏览器/小游戏端唯一便捷的长连接方案基于TCP弱网延迟比纯UDP高MirrorTCP/UDP封装中小型多人游戏原型开源、社区大、上手快深度定制有门槛Photon上层PUN/Quantum快速上线的小游戏服务端现成不用自己部署商用收费控制力弱Netcode for GameObjectsUnity官方网络库官方生态项目和Unity集成好支持状态同步相对较新资料少定制需要一定能力这里有个经验之谈如果你只是做面试准备不一定真的要精通所有方案但是要能说清楚它们之间的大致定位。比如“WebGL平台没有原生TCP Socket只能用WebSocket或者HTTP轮询”这句话本身就能体现你对平台差异的认知。再比如“小游戏平台和普通App的网络环境不一样需要专门考虑并发限制和域名白名单”这些都是实际项目里会踩的坑。大厂为什么倾向于自研网络层从工程角度讲Control是原因之一自研协议可以针对自家游戏的同步模式做定制优化可以做弱网模拟、流量统计、灰度降级第三方方案一旦出问题你只能等社区修或者自己魔改成本反而更高。初级候选人如果能点到这一层说明你不是只停留在用API的层面。4. 状态同步与帧同步游戏网络的两条路线4.1 状态同步客户端上报操作服务器广播状态状态同步是目前网络游戏最主流的同步方式尤其是大型多人游戏。它的核心思路是服务器是权威的客户端不直接决定游戏世界里的最终状态。客户端做的事情是把操作指令发给服务器服务器运行完整的游戏逻辑计算出最新的游戏状态然后把状态广播给所有相关客户端。举个例子玩家A按了一下前进键客户端不会立刻把自己的坐标改成“往前走了1米”而是把“按下前进键”这条指令发给服务器。服务器用自己的逻辑算出A的新位置然后告诉所有客户端A现在在(10, 20, 30)这个点。其他客户端收到后在本地把这个玩家移动到目标点。这里有个客户端要做的重要事情插值和预测。如果没有插值服务器以10Hz的频率下发位置快照其他玩家看到的动作就会一卡一卡的插值就是让本地显示的位置平滑地向目标位置靠近。预测则是客户端在收到服务器状态之前先用自己的逻辑模拟一下操作结果让本机玩家操作时不觉得有延迟等服务器权威状态到达后再做校正。在面试里你不需要把预测和校正的算法细节背下来但能说出“服务器权威客户端做插值和预测”这个思路就够了这已经超过了多数初级候选人的水平。4.2 帧同步所有客户端跑同一个剧本帧同步的思路和状态同步差别很大。它不要求服务器每个时刻都广播全量状态而是把游戏逻辑统一切成帧服务器只管收集所有客户端的操作指令然后把这些指令按顺序广播给所有人。每个客户端收到指令后在自己的机器上跑一遍完全相同的游戏逻辑得到完全相同的游戏画面推进。帧同步的成立前提是“确定性”。什么意思就是同样的输入在不同机器上用同样的代码和浮点运算必须得到完全一样的结果。这里面有个坑不同CPU、不同架构的浮点运算精度可能有细微差别所以帧同步项目一般会用定点数代替浮点数或者规定某些运算必须保证跨平台一致。帧同步常见的应用类型是格斗游戏、RTS、以及一些强对抗性的派对游戏。这类游戏玩家数量不多但每个玩家对操作反馈的要求极高手势级别的延迟差异都会被感知。帧同步因为客户端不用等服务器逻辑算完所以延迟更低但代价是客户端一旦数据被篡改画面就完全不可信所以通常还需要服务器对关键操作做校验。4.3 对比表与初级岗位怎么答对比项状态同步帧同步服务器负担高服务器要跑逻辑且频繁广播状态低服务器主要转发输入指令客户端网络流量较大频繁接收状态快照较小只接收输入指令但需要更密的帧数据防作弊能力强服务器权威弱客户端容易改本地输入断线恢复容易重新拉取状态即可较难需要可靠地同步帧进度代表性品类MMO、MOBA、大世界格斗、RTS、弹幕、多人ACT初级岗位如果被问到“你们游戏项目用了什么同步方案”回答的时候不要急着抛名词先说是哪类玩法、玩家数量多少人、延迟要求多高。比如你可以说“我之前参与的是一个4人合作的轻竞技游戏因为玩家少、操作反馈要求高我们选了帧同步方案客户端跑确定性逻辑服务器只做指令转发和可靠排序。”然后如果面试官感兴趣再展开讲里面遇到的问题。这里特别提醒不要把自己没做过的项目说得天花乱坠。面试官一句话就能识破“你这个同步的浮点数精度问题你们当时怎么解决”答不上来反而更尴尬。不如承认“这部分是我初步了解的我项目里更多是HTTP请求和消息收发但我在学习帧同步的过程中理解了确定性和输入指令广播的概念。”这种诚实的态度其实加分。5. 高频面试题与答题思路实录5.1 高频问题与参考答案要点把常见的网络面试题整理成一张表每题都按“回答主线加分点”的格式给参考思路。问题回答主线加分项TCP和UDP的区别TCP可靠、有序、面向连接、字节流UDP不可靠但快速、无连接、报文独立结合游戏场景说哪里用TCP哪里用UDP三次握手过程SYN→SYNACK→ACK解释为什么不能两次握手TCP怎么保证可靠序号、ACK、超时重传、滑动窗口、拥塞控制补充“可靠不等于应用层可靠”什么是粘包拆包TCP是流协议消息没有边界给出消息头加length的解决方案提到大小端Unity里怎么发HTTP请求UnityWebRequest 协程/async提到responseCode、证书问题、超时处理Socket和WebSocket的区别Socket是传输层概念WebSocket是应用层协议基于TCP提到WebGL小游戏用WebSocket的原因心跳包的作用保活连接、探测死连接、配合超时断开说明心跳间隔和服务器踢线机制的关系断线重连怎么做检测断开→指数退避重试→恢复后重新登录/同步状态提到要处理消息幂等状态同步和帧同步区别服务器权威广播状态 vs 广播输入指令提到服务器负担、客户端预测客户端怎么接收TCP数据子线程阻塞读取→队列→主线程消费强调不能子线程直接操作Unity API如何设计消息ID和派发消息ID对应处理函数反序列化后分发提到protobuf或JSON登录流程消息怎么保证不丢TCP保证传输应用层需要自己ack和超时重试提到登录状态机和幂等处理UDP怎么实现可靠消息序号、ack、重传、去重、排序提到KCP这类现成方案游戏中网络延迟高怎么办插值、预测、延迟补偿结合具体玩法说明取舍大端小端问题协议约定字节序统一转换举例说明不统一会导致长度字段解析失败HTTP长连接和短连接默认短连接Keep-Alive可复用说明WebSocket用来解决频繁请求的开销5.2 追问与深挖如何展示自己的思考深度能背下上面的回答主线只能保证“不丢分”想要“加分”需要在回答中带出你自己的思考痕迹。这里我举一个典型的追问场景。面试官问“TCP为什么可靠”你答了确认应答和重传。他继续问“那UDP能做到可靠吗”如果你直接说“不能”就掉进坑里了。正确的思路是UDP本身不做传输层的可靠性保证但应用层可以实现一套可靠性机制给它加上序号、ack、超时重传、拥塞控制这就是可靠UDPKCP就是典型代表。这个回答展示的是你已经理解了可靠性的本质不是UDP“不能”而是TCP把这套机制放在了系统内核里UDP则需要你自己建。再比如你提到项目里用了protobuf面试官可能会问“为什么不用JSON”这时候你可以说项目中有的消息比较高频每秒钟几十条JSON的字符串解析开销和字节体积会占掉不少带宽和CPUprotobuf是二进制编码字段按编号紧凑排列体积小、解析快。但如果只是登录请求这种低频消息JSON完全够用甚至更便于调试。这样回答面试官看到的是你在“工程权衡”而不是“背书”。面试里还有一个高频追问套路“如果玩家在游戏里卡了一下然后突然恢复你会怎么设计”初级岗位常见的错误答法是“重连就行”。稍微好一点的答法是先做消息缓存网络恢复后把断线期间的操作补发过去服务端再判断这些操作是否还有效无效就要求客户端同步最新状态。再深一层还要考虑玩家在断线期间其实已经死掉了那么其他客户端看到这个玩家时会怎么处理。不用把方案讲得多完美重点是让面试官看到你在思考边界情况而网络编程大部分坑都出在边界情况里。6. 面试中容易翻车的细节与避坑经验6.1 常见翻车点以下几个问题是我在实际面试场景里经常听到的“致命回答”单独拎出来说说。第一把“HTTP”和“TCP”对立。有人会答“我们用的不是TCP是HTTP”这是概念混乱。HTTP是跑在TCP之上的应用层协议你用了HTTP本质上也用了TCP。正确说法是“我们项目的实时通信用了TCP自定义协议非实时请求用了HTTP。”第二聊到可靠UDP就慌。只要你说出“用UDP做实时同步”面试官极大概率会追问“那丢包怎么办”。如果完全没准备会当场卡壳。建议提前准备一个简短回答客户端给每个UDP包编上序号接收方发现序号跳变就要求重传收到重复包就丢弃同时按序号缓冲乱序包到期后按顺序抛给上层。能把这四句话说清楚就已经很能打了。第三对“心跳包”的理解停留在“保活连接”这四个字。可以再往深一层说心跳包有两个作用一是让网络中间设备不要因为空闲断开连接二是让服务器能快速发现客户端已经离线从而触发清理逻辑。心跳的间隔要权衡太频繁浪费带宽太慢则死连接清理不及时。很多项目会做三级心跳比如客户端每隔一段时间发一次心跳连续N次没收到服务端回复就尝试重连重连失败才真正判定断线。第四说“子线程里直接操作Unity对象”这在上述3.3里已经强调过。如果遇到这种情况可以坦白“我知道不能跨线程操作所以我的网络回调里只把数据放到队列主线程Update里再处理。”这个回答一出来面试官基本不会再在这个点上纠缠。第五对数字不敏感。面试官问“你们同步频率是多少”“心跳多久一次”如果支支吾吾或者给出一个离谱的数字会显得项目经验不实。哪怕不是自己在真实项目里配置的也要知道常见量级服务器状态同步一般是10~30Hz帧同步一般是每帧发送指令心跳常见的是3~10秒一次。回答时加上“这个数值要根据真实网络环境压测调整”就很完整了。6.2 如何准备网络方向的面试我给实操建议如果你是零基础或者项目里网络部分写得很少建议用一到两周时间按下面这条路走一遍比刷一百道题都管用。先做一个最简TCP客户端和服务端。本地起一个监听端口Unity客户端连上去发一条自定义协议的消息服务端收到后原样返回客户端再解析并显示在屏幕上。这个过程中你会真实遇到粘包、字节序、收到半包不知道怎么处理的问题把这些记录下来。然后做一个HTTP请求到公开接口的Demo用UnityWebRequest发Get和Post分别处理成功、超时、404、500这几种情况。重点观察responseCode、error、isDone之间的区别。再用抓包工具看一下HTTP请求的报文格式看看请求头、请求体、响应状态行长什么样。最后做一个“断线重连”的小功能客户端每秒检查一次连接状态断开后尝试重连重连成功后把断线期间缓存的消息队列补发出去。这个功能能覆盖掉大部分初级网络面试的知识点包括心跳、超时、状态机、消息队列。准备过程中可以顺手把每个问题的答案写在自己的笔记里用“我要去给别人讲明白”的标准去组织语言。面试的时候不要怕被问到不懂的词哪怕答不上来也要尽量拆题“这个点我目前接触不深但我理解它是解决XXX问题的我的项目里暂时用的是YYY方案。”这种回答哪怕不完美也比沉默或者胡编强得多。我自己带新人的时候经常说一句话网络这块知识面试前突击两天能应付题目但真正想做好客户端一定要自己写过一遍才懂。希望这篇面经能帮你把网络这部分的复习范围圈清楚少走点弯路。