UNITY
1.Image和RawImage的区别
Imgae比RawImage更消耗性能Image只能使用Sprite属性的图片,但是RawImage什么样的都可以使用Image适合放一些有操作的图片,裁剪平铺旋转什么的,针对Image Type属性RawImage就放单独展示的图片就可以,性能会比Image好很多
2.Resources和AssetBundle使用区别Resources属于内部加载,打包出来后是文件是不存在的,不利于更新Resources会使打包出来程序变大一般内存占用不大、全局使用且变化不大的物体可以用Resources加载 相应的,AssetBundle属于外部加载,方便热更新,打包出来程序也会小很多 扩展:为什么AssetBundle会资源少?刚开始我竟然搞不懂,,查了半天才想起来外部加载啊,,,可以从外部调取啊,就不用放程序里了啊!!!当然就小了
3.协程的用法在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程。
Unity的协程是在每帧结束之后去检测yield的条件是否满足。
1.用来延时
2.用来异步加载等待
3.加载WWW
4.基本就是,控制代码在特定的时机执行。
4.四元数1.控制物体旋转(四元数和向量相乘表示这个向量按照这个四元数进行旋转之后得到的新的向量)2.解决欧拉角万向锁的问题(不懂万向锁的可以去看下这个篇文章:https://blog.csdn.net/fengya1/article/details/50721768)3.四元数可以方便快捷的进行插值运算
5.对渲染管线的理解渲染流水线流程:
1.应用阶段(由CPU负责,输出是渲染所需要的几何信息,即渲染图元)
2.几何阶段(由GPU负责,处理渲染图元,这阶段中最重要的就是把顶点坐标变换屏幕空间中,交给光栅器处理这阶段输出的是屏幕空间中二维顶点坐标、每个顶点对应的深度值、着色等相关信息)
3.光栅化阶段(由GPU,负责这一阶段会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像)细节过程https://zhuanlan.zhihu.com/p/97498781
6.叉乘和点乘的意义叉乘:几何意义:得到一个与这两个向量都垂直的向量,这个向量的模是以两个向量为边的平行四边形的面积在同一平面内, 结果 > 0 表示 B在A的逆时针方向, 结果 <0 表示B在A的顺式针方向, 结果 = 0表示B与A同向应用:计算两个向量方向的点乘:几何意义:可以用来表征或计算两个向量之间的夹角,以及在b向量在a向量方向上的投影两个向量的点乘所得到的是两个向量的余弦值,也就是-1 到1之间,0表示垂直,-1表示相反,1表示相同方向。应用:计算两个向量方向的夹角
7.优化问题场景优化1.遮挡剔除(Occlusion Culling) 不显示被遮挡住的物体2.LOD 根据相机距离远近显示不同精细程度的模型3.大场景可以调节相机可视距离4.小物体可以适当隐藏掉5.使用光照贴图 避免动态实时的进行光照计算,提高效率
UI优化
1.将同一画面图片放到同一图集中
2.图片和文字尽量不要交叉,会产生多余drawcall(相同材质和纹理的UI元素是可以合并的)
3.UI层级尽量不要重叠太多
4.取消勾选不必要的射线检测RaycastTarget
5.将动态的UI元素和静态的UI元素放在不同的Canvas中,减少canvas网格重构频率GC优化
1.字符串使用StringBuilder而不是string,stringBuilder在创建时会自动获取一个容量存储并逐渐扩充,string每一次改变都会创建一个新的对象。
2.访问物体tag的时候尽量使用Gameobject.CompareTag(),因为访问物体的tag属性会在堆上额外的分配空间
3.使用对象池缓存大量创建的物体
4.用for代替foreach,foreach每次迭代产生24字节垃圾内存
8.Addcomponent后哪个生命周期函数会被调用?对于AddComponent添加的脚本,其Awake,Start,OnEnable是在Add的当前帧被调用的,其中Awake,OnEnable与AddComponent处于同一调用链上,Start会在当前帧稍晚一些的时候被调用,Update则是根据Add调用时机决定何时调用:如果Add是在当前帧的Update前调用,那么新脚本的Update也会在当前帧被调用,否则会被延迟到下一帧调用。
9.AssetBundle包加载流程这个每次问我的时候我都很慌,AB包打包不就是在编辑器中写打包代码,然后设置物体包名,打包出来,然后外部加载这几步?但是每次都是面试官问我没了??我查了查也没查到别的啊。。求路过的大佬指点下o(╥﹏╥)o
10.图集打包怎么分类1.按业务功能的预制,寻找依赖,收集所有预制引用的图片,2.如果有多个预制使用了同一张图片,我们就把它扔到common文件夹3.让图集尽量紧凑,没有太多空白,尽量让图集处于2的n次方大小
11.资源加载方式1.Resources2.AssetBundle3.AssetDatabase
12.Unity中协程是如何实现的?首先,请你牢记:协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法 Current 和 MoveNext() ,只有当MoveNext()返回 true时才可以访问 Current,否则会报错。迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。
13.DrawCall和SetPass CallDrawCall:meshes网格绘制应用批处理后的总数。请注意,在多次呈现对象(例如,由像素灯照明的对象),每个在一个单独的渲染结果绘制调用。SetPass Call:渲染改变( passes)次数。每个改变 需要Unity运行时绑定一个新的渲染器(shader),它可能会引入 CPU 开销。
C#
1.数组和List两者效率之间哪个好?数组: 数组在C#中是最早出现的。它在内存中是连续的存储的,所以索引速度很快,而且赋值与修改元素也很简单。可以利用偏移地址访问元素,时间复杂度为O(1);删除时间复杂度为O(n),数组没有添加数据选项。List:基于数组,时间复杂度相同,插入为O(n);不过在数据少量的时候跟数组差不多,数据庞大的时候效率会低于数组。
2.哈希表与字典字典:内部用了Hashtable作为存储结构
- 如果我们试图找到一个不存在的键,它将返回 / 抛出异常。
- 它比哈希表更快,因为没有装箱和拆箱,尤其是值类型。
- 仅公共静态成员是线程安全的。
- 字典是一种通用类型,这意味着我们可以将其与任何数据类型一起使用(创建时,必须同时指定键和值的数据类型)。
- Dictionay 是 Hashtable 的类型安全实现, Keys和Values是强类型的。
- Dictionary遍历输出的顺序,就是加入的顺序
哈希表:
- 如果我们尝试查找不存在的键,则返回 null。
- 它比字典慢,因为它需要装箱和拆箱。
- 哈希表中的所有成员都是线程安全的,
- 哈希表不是通用类型,
- Hashtable 是松散类型的数据结构,我们可以添加任何类型的键和值。
- HashTable是经过优化的,访问下标的对象先散列过,所以内部是无序散列的
3.值类型和引用类型的区别
1.值类型存取快,引用类型存取慢。
2.值类型表示的是数据,引用类型表示的是指向存储在内存堆中的数据的指针和引用。
3.值类型继承自System.ValueType,引用类型继承自System.Object。
4.值类型根据声明位置不同堆和栈中都有可能存储,引用类型分配在堆中。
4.什么是序列化序列化是通过将对象转换为字节流,从而存储对象或将对象传输到内存,数据库或文件的过程。主要用途是保存对象的状态,包括对象的数据,以便能够在需要是重建对象。反向过程称为 反序列化。
5.委托是什么,event关键字有什么用?委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。event关键字的作用,为了限制委托的调用条件,使之只能在外部进行-=、+=操作不能调用,但可以能在类内部调用。
6.继承和组合的区别继承:可以使用现有类的功能,并且在无需重复编写原有类的情况下对原有类进行功能上的扩展。(is-a关系)组合:在新类里面创建原有类的对象,重复利用已有类的功能。(has-a关系)
组 合 关 系 | 继 承 关 系 |
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 | 缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性 |
优点:具有较好的可扩展性 | 缺点:支持扩展,但是往往以增加系统结构的复杂度为代价 |
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象 | 缺点:不支持动态继承。在运行时,子类无法选择不同的父类 |
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口 | 缺点:子类不能改变父类的接口 |
缺点:整体类不能自动获得和局部类同样的接口 | 优点:子类能自动继承父类的接口 |
缺点:创建整体类的对象时,需要创建所有局部类的对象 | 优点:创建子类的对象时,无须创建父类的对象 |
https://www.cnblogs.com/jesselzj/p/4747398.html7
虚方法和抽象方法1)抽象方法是只有方法名称,没有方法体,即没有方法的具体实现,子类必须重写父类抽象方法才能实现具体功能;虚函数有方法名称也也有方法体,但是子类可以覆盖,也可不覆盖。
2)抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化。
3)抽象方法只能在抽象类中声明,虚方法不是。
4)派生类必须重写抽象类中的抽象方法,虚方法则不必要。