Unity常用面试问题

Unity面试高频问题解析

GC针对的谁

new对象的时候,产生新对象
产生新对象:装箱,使用linq表达式的委托,new,字符串,使用委托的时候创建了新对象会产生gc,如果缓存了全局这个委托,则不会

GC是发生在什么时候

主动调collect接口以及内存分配不足的时候

如何避免gc

别new对象

GC的过程,为什么耗时

每一次GC会经历以下过程,堆上的对象越多,对象的引用越多,意味着GC所做的工作越多
1:GC会检查堆上所有的对象
2:GC会检查所有这些对象的引用是否仍在作用域
3:每个不在作用域的对象都会被标记为待删除
4:GC删除每个待删除的垃圾对象

渐进式gc,unity2019的分代垃圾收集功能

移动端的优化

GC,UGUI合批,网格重建,跨语言调用,IO,预制体加载大小(特效动态加载),ab包分类

卡牌鱼眼列表的实现

利用Horizontal Layout Group的控制自己缩放特性和item的缩放来修改content大小,监听鼠标事件

全面屏手机为什么可以自适应,自适应是怎么处理的

水滴屏:
修改父节点的anchorMin,跳过水滴

safeAreaRect.offsetMin = Vector2.zero;
safeAreaRect.offsetMax = Vector2.zero;
var resolution = canvas.pixelRect.size;
var offsetX = resolution.x - safeArea.width;
var offsetY = resolution.y - safeArea.height;
safeAreaRect.anchorMin = new Vector2(offsetX / resolution.x, offsetY / resolution.y);
safeAreaRect.anchorMax = new Vector2((resolution.x-offsetX)/ resolution.x, (resolution.y-offsetY)/ resolution.y);

有一个按钮点击了没有反应为什么 pc和手机上

raycast没勾选,被别人挡住了

c#的字典是什么实现的

Hash算法

无限列表的实现,格子划完超过1之后的做法,不需要每个设置数据,进去的一行设置位置就行了。滑到下面去怎么跟index变化进行对应

建个字典用数据索引和transform缓存

大地图划的很快,或者一下子缩小会不会看到一个图片没有加载出来或者一个空的地方

用九宫格加载和精确度低的图片解决

相机裁剪的流程

在这里插入图片描述
到裁剪空间后gpu删除不在-1,1,0,1范围内的点,部分内的切割, UnityObjectToClipPos
直接裁剪空间判断x,yz是否在-w,w之中

为什么函数出来后值类型离开后会自动释放

因为值类型是复制的,出栈后栈顶指针收缩复用那片区域,引用是在堆里面

stringbuilder实现

字符数组

texture导入的设置重要的设置

可读可写,类型,大小,压缩格式,minmap是否开启(开了增加内存,不开分辨率过高增加渲染压力,显存过大,传递数据drawcall更多)

头顶UI的优化技巧

1.使用3D做法,避免坐标转换,可以使用job放在其他线程处理旋转缩放,位置,缺点canvasgroup,以及布局组件之类的不好使用
2.判断视野范围内才更新
3.超过一定距离卸载,跟相机的距离
4.根据距离远近分帧更新
5.需要时更新,怪物移动以及相机更新
6.加载的时候分帧加载,避免同一帧创建多个
https://zhuanlan.zhihu.com/p/25670078
头顶文字合批 用srpbatch

TCP和UDP

tcp:按序到达,实时性没udp强,要连接才能发送,双向通信
udp:无法保证顺序,单向通信

大世界地图里面地形合并是动态合批还是静态合批

动态合批

大世界地图里面地形合并怎么合并的</

### Unity GC 垃圾回收机制面试问题解析 #### 1. Unity中GC的基本工作流程是什么? Unity使用的垃圾回收机制基于.NET运行时(CLR),其基本流程包括标记和压缩两个阶段。在标记阶段,GC会检查堆上的所有对象,并标记所有不可达的对象为待回收。随后进入压缩阶段,GC会整理内存碎片,移动幸存的对象到连续的内存区域,并更新所有根的引用以指向新的内存位置。这一过程会暂停所有线程,确保回收的准确性[^2]。 #### 2. Unity中GC的分代回收机制是如何工作的? Unity的GC采用分代回收策略,将对象分为三代:第0代、第1代和第2代。新创建的对象属于第0代。当第0代内存达到阈值时,GC会回收第0代中的不可达对象,幸存的对象升级为第1代。当第1代内存达到阈值时,GC会同时回收第0代和第1代对象,幸存的第1代对象升级为第2代。第2代对象是长期存活的对象,只有在内存不足时才会触发完整的GC回收[^2]。 #### 3. 为什么频繁的GC会影响Unity游戏性能? 由于GC在标记和压缩阶段会暂停所有线程(Stop-The-World机制),频繁的垃圾回收会导致帧率下降,影响游戏的流畅性。此外,堆上的对象越多,对象之间的引用关系越复杂,GC需要处理的数据量越大,导致回收时间增加,进而加剧性能问题[^1]。 #### 4. 在Unity中如何优化GC的性能? - **避免频繁创建和销毁对象**:使用对象池(Object Pool)技术重用对象,减少GC的触发频率。 - **减少堆内存分配**:避免在Update等高频函数中分配临时对象,例如字符串拼接、LINQ查询等。 - **及时释放引用**:当对象不再使用时,将其引用置为`null`,以便GC能够识别为垃圾对象[^3]。 - **使用结构体代替类**:对于小型数据结构,优先使用结构体(值类型),避免堆内存分配。 - **避免循环引用**:使用弱引用(WeakReference)打破循环引用,防止对象无法被回收[^3]。 #### 5. Unity中GC的触发条件有哪些? - **显式调用**:使用`System.GC.Collect()`强制触发GC,但不推荐频繁使用。 - **内存分配达到阈值**:当第0代对象的内存使用超过预算时,自动触发GC。 - **资源加载或卸载**:加载或卸载资源(如AssetBundle)时可能触发GC。 - **脚本编译**:在Editor中修改脚本并重新编译时,会触发GC以清理旧的类型信息。 #### 6. Unity中有哪些常见的GC优化技巧? - **字符串拼接优化**:避免使用`+`操作符拼接字符串,推荐使用`StringBuilder`减少临时字符串对象的创建。 - **协程与IEnumerator优化**:避免在协程中频繁使用`yield return new WaitForSeconds()`,可以使用共享的协程或自定义计时器。 - **匿名函数与闭包**:避免在频繁调用的函数中使用匿名函数或闭包,因为它们可能隐式捕获变量并延长对象生命周期。 - **使用Unity内置的容器类**:如`Unity.Collections`包中的`NativeArray`、`NativeList`等,它们在C# Job System中避免了GC分配。 #### 7. Unity中如何检测GC的性能影响? - **使用Unity Profiler**:通过Unity的Profiler工具监控`GC Alloc`指标,查看每帧的内存分配情况。 - **日志输出**:在Editor中启用`UnityEditorInternal.InternalEditorUtility.GetTotalAllocatedMemorySize()`等API,跟踪内存使用。 - **性能分析工具**:结合VisualVM、dotTrace等第三方工具分析C#堆内存的分配与回收情况。 ```csharp // 示例:使用StringBuilder优化字符串拼接 using System.Text; public class GCExample : MonoBehaviour { private StringBuilder sb = new StringBuilder(); void Update() { sb.Clear(); sb.Append("Frame: "); sb.Append(Time.frameCount); Debug.Log(sb.ToString()); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustEasyCode

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值