内容将会持续更新,有错误的地方欢迎指正,谢谢!
拥有更好的学习体验 —— 不断努力,不断进步,不断探索 |
助力快速掌握 面试题 为面试者节省宝贵的学习时间,避免困惑! |
文章目录
- 一、进程、线程、协程的区别?
- 二、material和sharematerial的区别?
- 三、Unity 实现2D游戏有几种方式?
- 四、LOD是什么,优缺点是什么?
- 五、MipMap是什么,作用是什么?
- 六、请简述GC(垃圾回收)产生的原因,并描述如何避免?
- 1、垃圾回收触发
- 2、垃圾回收的过程
- 3、GC操作带来的问题
- 4、堆上变量存储过程
- 5、GC优化
- 七、简述Quaternion四元数的作用,四元数的优缺点?
- 八、动态加载资源的方式?它们之家的区别?
- 九、静态批处理和动态批处理区别?
- 1、绘制原理
- 2、什么是批处理
- 3、动态批处理
- 4、静态批处理
一、进程、线程、协程的区别?
- 进程:
进程是程序资源管理的最小单位,每个进程都有独立的内存空间,进程之间的运行是相互独立的。
- 进程是操作系统进行资源分配和管理的基本单位。
- 每个进程都有独立的内存空间、文件描述符和其他资源。
- 进程之间相互独立运行,拥有自己的地址空间。
- 进程是程序资源管理的最小单位。
- 线程:
线程是进程的执行单元,同一进程中的多个线程是共享内存和资源的,线程是可以并发的。
同一时间可以执行多个线程,开辟线程的开销很大,但多线程能够更有效的利用计算机资源,在性能上线程要优于线程,线程适合多任务同时处理,线程不能操作Unity的很多方法和组件。
- 线程是进程中的执行流程,是任务调度和系统执行的最小单位。
- 同一进程中的多个线程共享进程的内存和资源。
- 线程之间的切换开销较小,因为它们共享相同的地址空间。
- 线程可以并发执行,但需要注意同步问题。
- 协程:
协程是在主线程运行的同时开启的另一段逻辑处理,来协助当前程序的执行,协程适合对某任务进行分时处理,协程是由程序员在代码里面显示调度的。
- 协程是一种用户态的轻量级线程,完全由程序控制。
- 协程不是由操作系统内核管理,而是由应用程序控制。
- 协程能保留上一次调用时的状态,每次过程重入时,相当于进入上一次调用的状态。
- 协程通常用于异步编程和高效的并发处理。
线程和协程的主要不同就在于多线程程序可以运行多个线程,而协同程序是通过协作来完成,在任一时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要的时才会挂起,协程很像多线程但不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足。
二、material和sharematerial的区别?
- shareMaterial表示共享材质,修改shareMaterial材质将会改变所有使用了这个材质的的物体的外观,并且也会改变存储在工程里的材质设置。
- material是材质的实例,修改材质仅会影响物体的材质。
- 每次引用renderer.matetial时会生成一个新的material在内存中,销毁物体时需要手动销毁材质。
三、Unity 实现2D游戏有几种方式?
- 使用UGUI
- 相机投影模式设为正交模式
- 使用Unity的2D模式
- 使用2D插件(NGUI)
四、LOD是什么,优缺点是什么?
LOD是常用的游戏优化技术,它按照模型的位置和重要程度决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。
LOD是多层次细节,在游戏场景中根据摄像机与模型的距离来决定显示哪一个模型,一般距离近的时候显示高精度多细节模型,距离远的时候显示低精度低细节的模型。
优点: 减少顶点数,面数,提高渲染效率。
缺点: 增加CPU计算 、内存占用率高(有多个不同的精度的模型)。
五、MipMap是什么,作用是什么?
MipMap是多级渐远纹理技术,就是贴图会被处理成一系列的更小的图像,形成一个图像金字塔,每一层都是对上一层的的降采样的的结果。当相机离物体近的时候就适当替换成较大的纹理(纹理质量好,模糊感较少),当相机离物体远的时候就可以使用较小的纹理(纹理质量稍差,模糊感较强)
优点: 当物体远离时,无需高精度纹理展示时,则替换低精度纹理,降低了显存带宽,较少渲染。
缺点: MipMap是一些列的图片组成的文件,内存占用率高,典型的利用空间换取时间的办法。
六、请简述GC(垃圾回收)产生的原因,并描述如何避免?
1、垃圾回收触发
- 在堆内存上进行内存分配操作而内存不够的时候都会触发垃圾回收来利用闲置的内存。
- GC会自动的触发,不同平台运行的频率不一样。
- GC可以强制被执行。
2、垃圾回收的过程
- GC会检查堆内存上的每个储存变量。
- 对每个变量会检查其引用是否处于激活状态。
- 如果变量的引用不在处于激活状态,则会被标记可回收。
- 被标记的变量会被移除,其所占有的内存会被会被回收到堆内存上。
3、GC操作带来的问题
- GC操作会需要大量的时间来运行,如果堆内存上有大量的变量或者引用需要检查,则检查的操作会十分缓慢,这就使得游戏运行缓慢。
- GC操作可能会在关键时候运行,使得游戏帧率下降。
- GC操作会导致堆内存的碎片化,当内存被回收到堆内存上的时候,有可能使得堆内存被分割成碎片化单元,堆内存碎片化会使游戏占用的内存越来越大,并且GC操作会更加频繁的发生。
4、堆上变量存储过程
- Unity检查是否有足够闲置的内存单元用来存储数据,如果有则分配对应大小的内存单元。
- 如果没有足够的存储单元,Unity会触发垃圾回收来释放不再被使用的堆内存,这一步是缓慢的,如果垃圾回收后有足够的大小的存储单元则进行内存分配。
- 如果垃圾回收后没有足够的内存单元,则Unity会扩展堆内存的大小,这步操作很缓慢,然后分配对应大小的内存单元给变量。
5、GC优化
- 使用对象池,可以避免大量对象的创建。
- 使用StringBuilder替代string,String为不可变字符串,对于执行大量字符串操作的过程,会分配大量空间,显著降低性能,而StringBuilder是一个可变字符串,可以通过追加、移除、替换或插入字符来修改。
- 减少装箱操作,装箱和拆箱过程需要进行大量的计算,装箱时需要创建一个全新的对象,需要进行内存的分配。
- Struct中不要有引用类型变量,struct是值类型,而如果struct中有引用类型的变量,GC会检查整个struct。
- 不要在频繁调用的函数中反复进行堆内存分配。
七、简述Quaternion四元数的作用,四元数的优缺点?
Quaternion用来储蓄和表示对象的旋转角度 高阶复数 Q = w + xi + yj + z*k
Quaternion计算紧凑高效,不受万向节锁的困扰,并且可以很方便的进行球面插值
-
作用
- 存储旋转方向:Quaternion类用于存储游戏对象的三维方向,以及描述从一个方向到另一个方向的相对旋转。
- 避免万向锁问题:与欧拉角不同,四元数可以避免万向锁问题,使得在不同的坐标系下都能正确地表示旋转。
- 平滑插值:在动画和相机跟随等场景中,四元数提供更平滑的旋转插值。
-
优点
- 避免万向锁问题:四元数不受万向锁的困扰,提供更平滑的旋转。
- 保持一致性:在不同的坐标系下都能保持一致性。
- 紧凑高效:用四个数表示,节省内存。
-
缺点
- 计算复杂:与欧拉角相比,四元数的计算较复杂。
- 不易理解:不太直观地表示旋转。
八、动态加载资源的方式?它们之家的区别?
-
Resource.Load
加载的资源必须放在Resources文件夹下,游戏打包时,Resources文件夹下文件会被全部压缩打包并进行加密,并且Resource文件夹的目标不存在,只能通过Resources.Load进行加载。 -
UnityWebRequest
既可以加载本地的资源也可以从服务端下载资源,从本地加载资源时需要将资源放在StreamingAssets文件夹下,该文件夹下资源打包时不会被压缩和加密。 -
AssetBundle.LoadFromFile
用于加载本地的AssetBundle,一般用于更新资源的加载。 -
Addressable.LoadAssetAsync
这是Unity引入的新的资源管理系统,可以实现更高级的资源加载和管理。通过Addressable Assets System,可以将资源进行标记和分组,并且支持动态加载、远程加载、版本管理等功能。相较于传统的资源加载方式,这种方式更加灵活和智能。
九、静态批处理和动态批处理区别?
1、绘制原理
为了将物体绘制到屏幕上,引擎必须向图像API发送一个DrawCall指令,每一次发送DrawCall指令的过程为一个渲染批次(Batch)。
这个过程分为两大部分:
- 设置渲染状态: 对于加载到游戏中的资源和对象等,CPU需要计算其顶点相关矩阵,渲染所用贴图、材质、shader、灯光等。
- 调用DrawCall: CPU主要工作就是设置这些物体的渲染状态后调用DrawCall,从而造成CPU开销,简单来说就是CPU向GPU发送指令并由GPU绘制。
2、什么是批处理
因为每一次发送DrawCall指令都会造成CPU的性能开销,而CPU的处理速度比GPU慢,所以可以将绘制的压力移交给GPU。
Unity可以将一些物体进行合并从而用一次Drawcall来渲染它们,这一操作称为批处理,批处理能够得到更好的渲染性能。
例如渲染一千个三角形,如果把它们按一千个单独的网格进行渲染则需要请求1000次DrawCall,而如果直接渲染一个包含了一千个三角形的网格则只需要请求1次DrawCall,这样减轻了CPU的开销在性能上会有很大的提升。
3、动态批处理
动态批处理的原理是每一帧把可以进行批处理的模型网格合并,再把合并后的模型数据传给GPU,然后使用同一个材质对其渲染。
除了实现方便,动态批处理的另一个好处是经过批处理的物体仍然可以移动,这是因为由于处理每帧时,Unity都会重新合并一次网格。
虽然动态批处理不需要我们进行任何额外的工作但只有满足条件的模型和材质才可以被动态批处理
- 必须使用相同的材质(相同材质的物体之间差别只在于顶点数据不同,可以将顶点数据合并在一起,在一起发送给GPU)。
- 动态批处理仅会应用于总共包含不超过 900 个顶点属性且不超过 300 个顶点的网格。
- 即使游戏对象基本相同,使用不同材质实例也会导致游戏对象不能一起接受批处理。
- 有多个Pass通道的shader会中断批处理。有时需要使用额外的Pass来为模型添加更多的效果,但这样一来模型就不会被动态批处理了。
4、静态批处理
静态批处理的实现原理是,只在运行的开始阶段,把需要进行静态批处理的模型合并到一个新的网格结构中。
这意味着这些模型不可以在运行时刻被移动,但由于它只需要进行一次合并操作因此比动态批处理更加高效,但静态批处理的缺点是需要占用更多的内存来存储合并后的几何结构。
每一次跌倒都是一次成长 每一次努力都是一次进步 |
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!