第一部分

1. 请简述值类型与引用类型的区别

1. 值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的是堆中存放的地址。 
2. 值类型存取快,引用类型存取慢。
3. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。
4. 栈的内存是自动释放的,堆内存是 .NET 中会由 GC 来自动释放。 
5. 值类型继承自 System.ValueType, 引用类型继承自 System.Object 。

2.C# 中所有引用类型的基类是什么

System.Object

3. 请简述 ArrayList 和 List<Int> 的主要区别

ArrayList,存在类型不安全问题,和装箱拆箱性能问题;
类型不安全:ArrayList会把所有数据当做Object类型来处理,所以允许操作不同类型的数据;所以在运行时,可能会报类型不匹配的错误;
装箱拆箱:例如需要将int-->object,object-->int;过程消耗性能;

 List<Int>:List是ArrayList的等效类;
因为泛型避免了编译时输入不同类型;
List将所有内容存储在T类数组中,没有装箱,但是数组是在堆上分配的。
所以避免了类型不安全和装箱拆箱问题;

4. 请简述 GC (垃圾回收)产生的原因,并描述如何避免?

原因:GC 回收堆上的内存 
避免: 1 )减少 new 产生对象的次数
      2 )使用公用的对象(静态成员) 
      3 )将 String换为 StringBuilder

5. 请描述 Interface 与 abstract类之间的不同

一个类继承了某个抽象类表示它“是什么”,实现了某个接口表示它“有什么功能”或者“会做什么事”。
比如:燕子(具体类)是鸟(抽象类),会飞(接口)。C#中不支持多继承,即燕子只能是鸟,不会是其他东西了;
但可以有多个功能,做很多事,比如会飞(IFly),会吃(IEat)。

1.接口可以多继承,抽象类不可以多继承;
2.接口只能定义方法,而抽象类还实现方法;
3.接口可以作用于值类型和引用类型,而抽象类只能作用于引用类型;

7.关键字

virtual 关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写
           虚拟成员的实现可由派生类中的替代成员更改。
 const 关键字来声明某个常量字段或常量局部变量
 abstract 修饰符来指示某个类仅用作其他类的基类,而不用于自行进行实例化
 event 关键字用于声明发布服务器类中的事件。
 extern 修饰符用于声明在外部实现的方法。 
 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 
         在这种情况下,还必须将方法声明为 static,如下面的示例所示:
        [DllImport("avifil32.dll")]
        private static extern void AVIFileInit();

8. 请简述关键字 Sealed 和 final 的区别

sealed 修饰符可以应用于类、实例方法和属性。
   sealed修饰符应用于方法或属性时,必须始终与override一起使用;在派生类中不可以被重写;
   用于类时,该类被称为密封类,密封类不能被继承;
   结构是隐式密封的,因此它们不能被继承。

   final修饰符来限定变量、字段、方法和类。
   用于变量时,该变量只能赋值一次,不可修改;
   用于方法时,该方法不能被重写或隐藏;
   用于类时,该类不能被继承。
   接口的成员是不能使用该关键字的,道理和不能在abstract类使用final一样。

9. 请简述 private , public , protected , internal 的区别

private : 私有成员, 在类的内部才可以访问。
protected: 保护成员,该类内部和继承类中可以访问。
internal:在同一命名空间内可以访问。
public: 公共成员,完全公开,没有访问限制。命名空间外也可以访问。

10. 反射的实现原理?

审查元数据并收集关于它的类型信息的能力。
实现原理:在运行时根据程序集及其中的类型得到元数据。
在程序运行时,动态获取 程序集, 类型(class,interface)和类型的成员信息(方法,字段,属性等)。
在程序运行时,动态创建 类型实例, 以及调用和方法 动态创建出来的 类型实例的成员。
反射的应用:框架(Spring .net/ .Net MVC等)
在程序运行时,动态获取 程序集

11. .Net 与 Mono 的关系?

.net 是微软2001年  Windows下的开发平台
 Mono 是Xamarin公司是对.net跨平台开源的实现,不再局限于Windows,还可以Linux、Unix、Mac OS X、iOS、Android;Unity游戏开发也从Mono 中出现。
2014年,微软在.net基础上开发了.net core ,对.net跨平台开源的实现;
2016年,微软收购Mono
2020年,发布.net 5,不断发展的.net core,跨平台的不断完善。

12. 简述 Unity3D 支持的作为脚本的语言的名称

C#、javascript

13.Unity3D 是否支持写成多线程程序?如果支持的话需要注意什么?

仅能从主线程中访问  Unity3D 的组件,对象和  Unity3D 系统调用 ;
支持:如果同时你要处理很多事情或者与  Unity 的对象互动小可以用  thread, 否则使用 coroutine 。 
注意:  C# 中有  lock 这个关键字  , 以确保只有一个线程可以在特定时间内访问特定的对象;

14.Unity3D 的协程和 C# 线程之间的区别是什么?

最大的不同就是Unity3D中的协程是运行在主线程上的,它相当于把主线程切分成细小的片段,同一时间只能有一个协程处于执行状态。
而C# 则可以在同一时刻执行多个线程。
而且协程可以通过迭代器获取yield return回来的值

15.U3D 中用于记录节点空间几何信息的组件名称,及其父类名称

Transform;component;

16. 简述四元数的作用,四元数对欧拉角的优点?

用于旋转物体
相对欧拉角的优点: 
1 )能进行增量旋转 
2 )避免万向锁 
3 )给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)

17. 向量的点乘、叉乘以及归一化的意义?

点乘:求一个向量在另一个向量上的投影,也相当与求向量相似度,相似度越大,值也越大;
叉乘:求两个向量构成平面的法向量,法向量的长度为两个向量构成平行四边形的面积;
归一化:用在之关系向量关系,不关心向量大小时;

18. 矩阵相乘的意义及注意点

用于表示线性变换:旋转、缩放、投影、平移、仿射 
注意矩阵的蠕变:误差的积累

19. 为何大家都在移动设备上寻求 U3D 原生 GUI 的替代方案

不美观, OnGUI 很耗费时间,使用不方便   , DrawCall

20. 请简述如何在不同分辨率下保持 UI 的一致性

NGUI   很好的解决了这一点,屏幕分辨率的自适应性,原理就是计算出屏幕的宽高比跟原来的预设的屏幕分辨率求出一个对比值,然后修改摄像机的 size 。

21. 为什么 dynamic font 在 unicode 环境下优于 static font

Unicode   是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。 
使用动态字体时, Unity 将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。

22.Render 的作用?描述 MeshRender 和 SkinnedMeshRender 的关系与不同

Render的作用:使物体出现在屏幕上。
MeshRender:网格渲染器,通过MeshFilter拿到网格形状,并进行渲染。
SkinnedMeshRender:蒙皮网格渲染,比MeshRender多了一个蒙皮,用于骨骼蒙皮动画渲染;

23. 简述 SkinnedMesh 的实现原理

Skinned Mesh中文一般称作骨骼蒙皮动画,正如其名,这种动画中包含骨骼(Bone)和蒙皮(Skinned Mesh)两个部分;
动画数据记录时间和骨骼的运动信息
而骨骼运动,通过skin info(包含 Mesh 顶点的本地坐标、世界坐标、影响该顶点的骨骼数目和骨骼指针、骨骼影响该顶点的权重信息)来控制蒙皮运动;

24. 在场景中放置多个 Camera 并同时处于活动状态会发生什么?

游戏界面可以看到很多摄像机的混合

25.Prefab 的作用?如何在移动环境的设备下恰当地使用它?

Prefab 在实例化的时候用到,主要用于经常会用到的物体,属性方便修改

26. 如何销毁一个 UnityEngine.Object 及其子类

使用Destroy销毁后仍然可以输出游戏物体,使用DestroyImmediate销毁后输出null
原因是DestroyImmediate是立即销毁(让GameObject置为Null),立即释放资源,做这个操作的时候,会消耗很多时间的,影响主线程运行
Destroy是异步销毁,是在当前帧结束后才会真正的销毁物体(让GameObject置为Null),一般在下一帧销毁,不会影响主线程的运行

27. 为什么 Unity3D 中会发生在组件上出现数据丢失的情况?

组件上绑定的对象被删除了

28. 如何安全的在不同工程间安全地迁移 asset 数据?三种方法

1.将 Assets 目录和 Library 目录一起迁移
2.导出包
3.用 unity 自带的 assets Server 功能

29.MeshCollider 和其他 Collider 的一个主要不同点?

Meshcollider 再快也是基于 V3 顶点 ~~ 建议还是用 boxcollider ,  boxcollider 本身是基于算法,没有面的概念。

30. 当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免?

穿透(碰撞检测失败)
碰撞体变大,  FixedUpdate,  代码限制

31.OnEnable 、 Awake 、 Start 运行时的发生顺序?哪些可能在同一个对象周期中反复的发生?

Awake ——》OnEnable——》Start
OnEnable

32. 请简述 OnBecameVisible 及 OnBecameInvisible 的发生时机,以及这一对回调函数的意义?

当物体是否可见切换之时。可以用于只需要在物体可见时才进行的计算。

33.Unity3D 如何获知场景中需要加载的数据?

Resources.Load();
AssetBundle.Load();
AssetDataBase.LoadAssetAtPath<T>();

34.MeshRender 中 material 和 sharedmaterial 的区别?

修改 sharedMaterial 将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。 
不推荐修改由 sharedMaterial 返回的材质。如果你想修改渲染器的材质,使用 material替代。