【面经】腾讯U3d面试面经 帧同步方向(总)

近期拿到了一个腾讯的offer,记录一下面试过程。

我找的内推,面试的流程如下:

上传内推简历,接着马上被HR转到项目组里面,一个小时左右面试官电话过来约面,接着电话面,然后去科兴面,最后HR面,OFFER到手。

总的来说腾讯的面试流程还是挺简洁的,听说有人面了很多很多面,我没有遇到这种情况,不过最后给offer时间间隔太久了,一周半才确认。

 

两轮技术面试都是在问帧同步相关的问题,所以就一起写了,也是对帧同步做一个总结吧。(PS:其实我简历很多其他方向也很希望面试官能问到啊...)

由于时间比较久了 所以面试的问题可能不是特别准确。

PS。A并不是我面试的时候说的,因为并不可能在面试的情况下说出那么完善的逻辑,而是回来复盘之后,才想起来然后整理出来的。

Q:帧同步如何解决不同步的问题?

A:https://blog.csdn.net/nxshow/article/details/88382085

Q:帧同步怎么做到流畅的战斗?

A:

首先,定义一下流畅的战斗,流畅的战斗并不是代表着游戏的帧数一定要多高多高,而是说游戏的帧数在某一个帧数范围内小规模的变动,例如稳定在30帧这样。

对于单机游戏来说,如果要保证稳定在30帧,每一帧的逻辑、渲染等耗时不能高于33MS,所以需要小心的规划每一个函数的使用,采用分帧执行、算法优化等手段优化卡顿点。

而对于帧同步来说,不仅仅需要完成单机游戏的优化、还要针对网络波动进行针对的优化。我们知道,网络传输无法保证每一次传输的延迟都是一定的,有时候10MS就能完成一次传输,有时候1000MS才能完成一次传输,那么客户端如何保证网络传输不稳定的情况下,逻辑帧的运行还是相对稳定的呢?下面是给到的两种解决方案。

  1. 收到逻辑帧消息之后,不立即去播放,而是存着,播放使用固定的延迟进行播放,表现上就是玩家每次进行操作的时候,并不是马上生效的,而是有一小段固定延迟,这样网络在我们设置的延迟内波动的话,玩家是感受不出来卡顿的。但是缺点也很明显,每一个玩家都会有一段延迟。
  2. 另外一个处理方式就是,逻辑和表现进行分离,表现帧由玩家和逻辑帧进行驱动,逻辑帧卡顿并不影响表现帧,表现帧由玩家进行控制播放,一旦收到了新的逻辑帧,立即去做校验,如果说表现帧的播放轨迹和逻辑帧有出入,立即进行纠正。如果说新的逻辑帧并没有和表现帧有差异,但是表现帧相对逻辑帧差距很大,例如逻辑帧才到100帧,表现帧就已经到了200帧,这时候就对输入进行限制,比如移动速度放慢等操作。等待逻辑帧追上表现帧。对于其他玩家,采用AI预测的方式进行预测,一旦预测结果与新收到的逻辑帧不一致,就立即回退;同时,随着逻辑帧和表现帧的差距越来越大,相应的减缓预测的效果,最终停止预测。如果说逻辑帧突然来了一大波,应该适当的进行加速播放逻辑帧,尽量去追上表现帧。

Q:帧同步环境下如何做网络流量优化?

A:网络流量的优化,实际上就是网络包大小、数量的优化;首先,尽量去减小发送的数据,合理的规划每一个byte的作用,数量上尽量去合并同一批发送的数据包,减小由于包头造成的流量损失。

Q: 如何解决UDP丢包问题?

A:

首先明确一点,丢包问题是不可能解决的,在TCP和UDP下都会存在丢包的情况,那么为什么TCP号称是可靠的传输协议呢?这是由于TCP处理了丢包的情况,而UDP是无连接的,每次发出一个数据包之后就不管了,所以丢包的情况是需要我们自己去处理的。

首先,丢包是不可避免的,但是我们应该尽量去避免代码逻辑造成的丢包,还有就是完善丢包重传机制。

代码逻辑造成的丢包,具体来说,是以下几点:

  1. 发送端发送的数据堆积导致的丢包,也就是发送缓存被填满了导致的丢包,处理方式就是,控制发送频率,避免同时发送过多、过大的数据包。
  2. 数据包过大导致的丢包,internet协议规定的MTU大小为576,也就是目前最差的路由器支持的最小包大小就是576,如果大于这个数字,路由器就有可能对数据包进行分包,这样就一个包变成了两个包,两个包只要有其中一个包丢掉了,就代表这个数据包丢了,所以我们要严格控制数据包的大小,去掉UDP包头20个字节的大小,我们可用的还有556,我们程序中定义为512,只要超过这个数字,就会强制进行分包发送,接收方接收到数据包的时候,再进行重组。
  3. 接收端卡顿导致的丢包,接收端运行卡顿,导致数据包到接受端的时候Recv函数并没有在执行,处理方式就是使用多线程去执行Recv函数,这个线程里面只处理Recv,然后将接收到的数据缓存起来。

 

但是就算这样处理了之后,由于网络问题导致的丢包是没法解决的,所以我们必然要建立可靠的UDP传输。也就是实现丢包重传机制。

  1. 给每一个包规定一个自增的唯一序号,通过ACK确认双方发送到了那个数据包。
  2. 合理设置RTO(重传超时时间),TCP貌似是2*RTO, KCP采用的是1.5*RTO。

然后这里面试官追问,如果说这个包丢了,你一定要等到确认丢包之后重传吗?

答案是不会,格斗游戏既然使用了帧同步,就是要求实时性能,所以在重传机制上,还做了冗余发送的机制,就是在发送当前帧的时候,把前面几帧的数据一起合并起来发过去,相当于这几个消息中,只要收到了其中一个消息,就能流畅的播下去。

Q:如何保证在UDP环境下接收逻辑顺序一致性?

A:针对每一个数据包进行编号,后发的数据包如果先到了客户端,就存着,直到接收到的数据包是顺序的,才发生到逻辑层进行顺序处理

Q:如何实现帧同步环境下的断线重连?

A:

因为UDP是无连接的,所以断线只能通过上次收到的消息时间超时了多久进行判断,断线之后客户端逻辑帧停止,表现帧停止预测。

重连就比较麻烦了,重连回来之后,将逻辑帧、状态帧拉回来,服务器一次性将断线之后的消息发给客户端,客户端加速播放。

但是如果断线时间比较久,重连回来之后,消息数据量非常大,需要播放的帧数很多,有没有优化方法呢?有的,帧同步因为逻辑是在客户端运算的,所以帧同步的作弊也比较容易,我们通常会采用专门的验证服务器去验证,这个服务器同样接收客户端的操作指令,运行战斗逻辑,所以我们断线时间比较久的话,可以去验证服取到最新的现场数据,再发送现场数据到最新的逻辑帧给客户端,即可实现快速重连

Q:怎么去做战斗预测?

A:

Q:在帧同步的环境下怎么防止作弊的情况?

A:

Q:帧同步和状态同步的区别?为什么我们游戏要用到帧同步?

A:

帧同步和状态同步都不是新东西,很早以前就有了,以前由于网络问题,帧同步只存在于局域网游戏中。帧同步的逻辑放在客户端,服务器只管转发;状态同步的逻辑放在服务端,客户端只管表现。由于帧同步逻辑是客户端计算的,所以帧同步的每一个客户端都要知道场上的所有信息,才能正确的进行计算。而状态同步的逻辑都在服务端,所以状态同步不需要每一个客户端都知道所有的信息,只需要知道这个客户端所关心的信息就可以了。

因此状态同步更适合MMORPG这样的同步客户端数量较多,信息较为复杂的情况;而帧同步更适合MOBA这样的,客户端数量固定,更关注实时性的情况。

为什么我们游戏需要用到帧同步?我们游戏是一个格斗类型的游戏,对于打击感、实时性要求较高,而且参与战斗的只有两个客户端,战斗的场景非常简单,是一个典型的适合使用帧同步的场景。如果我们使用的是状态同步,每一个客户端在同一帧的表现不一致,就非常难调打击感,那么对于格斗游戏来说,没有打击感这个游戏就没有了灵魂。还有一点,帧同步的逻辑都在客户端,所以如果需要新增加战斗机制,只需要在客户端修改就可以了,不需要像状态同步那样,服务端增加计算逻辑,客户端增加表现逻辑。开发上非常简单,逻辑上也非常清晰。

 

除开帧同步 还少量的问了一些其他问题

Q:ETC压缩算法原理

A:

Q:大地图下的地图加载方式?

A:

Q:MMORPG游戏中多人、多时装渲染优化方案?

A:

 

问题不止这些,不过面试时间有点久,有些问题已经忘了,这里先做一个记录,后面有空再把回答补上

你可能感兴趣的:(Unity3D,面试经验)