基于猫佬wuduan Twomian面试的思考

基于猫佬wuduan Twomian面试的思考
最新回答
听海的哭泣ぃ

2023-07-11 21:17:06

为什么在游戏开发中需要使用到Lua?
  • 热更新支持:Lua作为脚本语言,可动态加载和修改代码,无需重新编译整个项目,尤其适合移动端(如iOS限制代码动态下发)。Mono虽支持热更新,但仅能生成32位包,不符合谷歌64位要求,而IL2CPP(Unity主流方案)需配合Lua实现灵活更新。
  • 跨平台兼容性:Lua轻量且独立于平台,与C#(Unity主语言)互补,避免直接依赖平台特定的编译工具链。
  • 性能与开发效率平衡:Lua执行效率接近原生代码,且语法简洁,适合快速迭代游戏逻辑(如活动系统、AI行为),减少C#的冗长代码。
C#方法参数中的ref和out关键字的作用是什么?
  • 按地址传递参数:两者均通过引用传递参数,允许方法修改调用方的变量值。
  • 初始化差异

    ref:需调用前显式初始化变量(如int x = 0; Method(ref x);)。

    out:无需初始化,但方法内必须赋值(如Method(out int y);),常用于返回多个值(但元组更现代)。

Native内存和Managed内存间的区别
  • 管理方式

    Native Memory:由开发者手动分配/释放(如C++的malloc/free),易内存泄漏。

    Managed Memory:由CLR(如Unity的Mono/IL2CPP)自动垃圾回收(GC),开发者无需直接干预。

  • 性能

    Native内存直接操作硬件,效率高但风险大。

    Managed内存因GC暂停(STW)可能引发卡顿,但安全性高。

  • 用途

    Native:高性能需求(如图形渲染、物理引擎)。

    Managed:游戏逻辑、数据管理(如角色属性、任务系统)。

Unity的垃圾回收算法的特点
  • 分代回收:Unity采用分代GC,将对象分为三代(0代新对象、1代短期存活、2代长期存活),优先回收高频创建的短期对象,减少STW时间。
  • 增量式GC:Unity 2018+引入增量式GC,将回收任务分帧执行,避免单帧卡顿,但总耗时可能增加。
  • 局限性:无法回收Native内存,需手动管理(如Destroy对象后调用Resources.UnloadUnusedAssets)。
在ScrollView中裁剪Item上的粒子特效
  1. Visible Mask设置

    粒子组件启用Visible Mask并设为InsideMask。

    添加空物体,挂载SpriteMask组件覆盖列表区域,调整Order in Layer控制渲染顺序。

  2. Shader裁剪

    传递列表的V4向量(如屏幕坐标)至Shader,用clip()函数丢弃区域外粒子。

  3. Mask组件(不推荐)

    直接使用Unity的Mask组件,但可能引发性能问题(如额外Draw Call)。

前向渲染和延迟渲染的区别
  • 流程差异

    前向渲染:每个光源对每个物体逐个渲染,光源数量多时性能下降(O(n*m),n物体,m光源)。

    延迟渲染:先渲染几何信息(G-Buffer),再在屏幕空间合并光照,光源数量影响小(O(n+m))。

  • 适用场景

    前向:光源少、移动端(兼容性更好)。

    延迟:复杂光照、PC/主机端(需支持MRT)。

实现可靠UDP的考虑角度
  • 顺序保证:为数据包添加序列号,接收方按序重组。
  • 丢包重传:设置超时重传机制(如Go-Back-N或Selective Repeat)。
  • 拥塞控制:动态调整发送速率(如基于RTT和丢包率)。
  • 校验和:验证数据完整性,丢弃损坏包。
网络同步的了解
  • 状态同步:服务器定期广播全量状态(如MOBA游戏),客户端直接渲染,但带宽消耗大。
  • 帧同步:客户端仅接收输入指令,本地模拟运行(如RTS游戏),需严格确定性逻辑。
  • 插值/预测:客户端本地预测移动,服务器校正偏差(如FPS游戏),平衡实时性与流畅性。
Git和SVN的区别
  • 分布式 vs 集中式

    Git:每个开发者拥有完整仓库副本,支持离线提交。

    SVN:依赖中央服务器,需联网操作。

  • 分支管理

    Git:分支创建/切换快(指针操作),合并冲突处理更灵活。

    SVN:分支为服务器路径拷贝,操作较重。

  • 性能

    Git:基于哈希的存储,克隆大型仓库慢但后续操作快。

    SVN:线性历史,简单场景下可能更快。

Git切换分支快的原因
  • 指针操作:分支本质是指向提交(commit)的指针,切换分支仅需移动指针,无需复制文件。
  • 全量数据存储:每个commit保存项目完整快照,应用指定commit到工作区时直接复制文件,无需diff计算差异。
维护前1000名玩家排行榜的方案
  • 数据结构选择

    有序集合(Sorted Set):Redis的ZSET,按分数排序,支持高效范围查询(如ZREVRANGE rank 0 999)。

    跳表/B+树:自实现时可选,支持O(log n)插入/查询。

  • 分片与缓存

    按玩家ID分片存储,避免单节点瓶颈。

    定期缓存前1000名至内存,减少数据库查询。

基于分治思想的排序算法
  • 快速排序:选基准值分区,递归排序子数组。
  • 归并排序:分治为子序列,合并有序结果。
适合UI跳转/返回管理的数据结构
  • 栈(Stack):先进后出(LIFO),符合UI层级返回逻辑(如Android返回栈)。
寻路算法
  • A*:启发式搜索,适合静态地图(如网格寻路)。
  • Dijkstra:无启发式,保证最短路径但效率低。
  • NavMesh:Unity导航网格,动态避障优化。
  • JPS(Jump Point Search):网格地图优化,跳过冗余节点。