随便聊聊 [Unity3D]蓝港面试题
1. 请简述值类型与引用类型的区别
答
- 内存存储位置:值类型的数据直接存储在内存栈中,而引用类型的数据存储在内存堆中,内存单元存放的是堆中数据的地址。
- 存取速度:值类型的存取速度较快,引用类型的存取速度相对较慢。
- 数据表示:值类型表示实际的数据,引用类型表示指向存储在内存堆中数据的指针或引用。
- 内存释放方式:栈的内存会自动释放,堆内存则由.NET的垃圾回收器(GC)自动释放。
- 继承关系:值类型继承自
System.ValueType,引用类型继承自System.Object。
2. C#中所有引用类型的基类是什么
答
引用类型的基类是System.Object,值类型的基类是System.ValueType。同时,值类型也隐式继承自System.Object。
3. 请简述ArrayList和List的主要区别
答
- 类型安全性:
ArrayList存在不安全类型的问题,它会把所有插入其中的数据都当作Object来处理。 - 装箱拆箱操作:使用
ArrayList时会涉及装箱拆箱操作,这比较费时。 - 类型本质:
List<Int>是泛型接口,ArrayList是实现了该接口的类,可以被实例化。
4. 请简述GC(垃圾回收)产生的原因,并描述如何避免
答
GC的主要作用是回收堆上不再使用的内存。为了减少GC的触发,可以采取以下措施:
- 减少对象创建:减少使用
new关键字创建对象的次数。 - 使用公用对象:使用静态成员作为公用的对象。
- 字符串处理:将
String替换为StringBuilder,避免频繁的字符串拼接操作。
5. 请描述Interface与抽象类之间的不同
答
- 方法定义:抽象类中可能已经有一些方法的具体定义,而接口只能定义各个方法的签名,不能包含具体的实现代码。
- 继承与实现:类可以继承抽象类,当父类已经有实际功能的方法时,子类可以直接引用该方法,也可以选择重写。而实现接口时,必须实现接口中所有的方法,不能遗漏。
6. 下列代码在运行中会产生几个临时对象
答
在C#中,第一行代码可能会出错(在Java中倒是可行)。正确的初始化方式需要按照C#的语法规则进行。
7. 下列代码在运行中会发生什么问题?如何避免
答
代码会产生运行时错误,因为foreach是只读的,不能一边遍历一边修改集合中的元素。避免方法是使用for循环或者其他可修改集合的遍历方式。
8. 请简述关键字Sealed用在类声明和函数声明时的作用
答
- 类声明:当
Sealed用于类声明时,可防止其他类继承此类。 - 方法声明:当
Sealed用于方法声明时,可防止派生类重写此方法。
9. 请简述private,public,protected,internal的区别
答
- public:对任何类和成员都公开,无限制访问。
- private:仅对该类内部公开,外部类无法访问。
- protected:对该类及其派生类公开。
- internal:只能在包含该类的程序集中访问该类。
- protected internal:具有
protected和internal的双重访问权限。
10. 反射的实现原理
答
反射是指审查元数据并收集关于它的类型信息的能力。简单来说,就是获取程序集中的属性和方法。实现步骤如下:
- 导入
using System.Reflection;命名空间。 - 使用
Assembly.Load("程序集")加载程序集,返回类型是一个Assembly对象。 - 通过
foreach (Type type in assembly.GetTypes())遍历程序集中的所有类型,获取类的名称。 - 使用
assembly.GetType("程序集.类名")获取当前类的类型。 - 使用
Activator.CreateInstance(type)创建此类型的实例。 - 使用
type.GetMethod("方法名")获取当前方法。 - 使用
mInfo.Invoke(null, 方法参数)调用方法。
11..Net与Mono的关系
答
Mono官网主页:Mono是一个软件平台,旨在让开发者轻松创建跨平台应用程序。它由Xamarin赞助,是基于C#和公共语言运行时(CLR)的ECMA标准,对Microsoft的.NET Framework的开源实现。
Mono是.NET的一个开源跨平台工具,类似于Java虚拟机。Java本身不是跨平台语言,但运行在虚拟机上就能实现跨平台。.NET只能在Windows下运行,而Mono可以在Linux、Unix、Mac OS等多种操作系统上运行。
12. 简述Unity3D支持的作为脚本的语言的名称
答
Unity的脚本语言基于Mono的.NET平台运行,可以使用.NET库,这为XML、数据库、正则表达式等问题提供了很好的解决方案。Unity里的脚本都会经过编译,运行速度较快。支持的脚本语言有:
- JavaScript:和网页中常用的JavaScript不同,它编译后的运行速度很快,语法方面也有不少区别。
- C#:是一种广泛使用的强类型编程语言。
- Boo:可以看作是Python语言的变种,融合了Ruby和C#的特性,是静态类型语言。
13. Unity3D是否支持写成多线程程序?如果支持的话需要注意什么
答
仅能从主线程中访问Unity3D的组件、对象和系统调用。Unity3D支持多线程编程,如果同时要处理很多事情或者与Unity的对象互动较少,可以使用thread;否则,建议使用coroutine。
需要注意的是,C#中有lock关键字,可确保只有一个线程可以在特定时间内访问特定的对象。
14. Unity3D的协程和C#线程之间的区别是什么
答
- 运行机制:多线程程序可以同时运行多个线程,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起。
- 访问限制:除主线程之外的线程无法访问Unity3D的对象、组件和方法。
- Unity特性:Unity3D没有严格意义上的多线程概念,但提供了
StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)等后台加载场景的方法。StartCoroutine之所以叫协同程序,是因为在其函数体里处理代码时,利用yield语句等待执行结果,期间不影响主程序的继续执行,可以协同工作。而LoadLevelAsync允许在后台加载新资源和场景,利用协同可以在前台用loading条或动画提示玩家游戏未卡死,同时后台协同处理加载事宜。
15. U3D中用于记录节点空间几何信息的组件名称,及其父类名称
答
用于记录节点空间几何信息的组件是Transform,其父类是Component。
16. 简述四元数的作用,四元数对欧拉角的优点
答
四元数主要用于表示旋转。相对欧拉角,它具有以下优点:
- 增量旋转:能进行增量旋转。
- 避免万向锁:可以避免欧拉角中存在的万向锁问题。
- 表达方式:给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)。
17. 向量的点乘、叉乘以及归一化的意义
答
- 点乘:描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影。
- 叉乘:得到的向量垂直于原来的两个向量。
- 归一化:用于只关心方向,不关心大小的情况。
18. 矩阵相乘的意义及注意点
答
矩阵相乘用于表示线性变换,如旋转、缩放、投影、平移、仿射等。需要注意矩阵的蠕变问题,即误差的积累。
19. 为何大家都在移动设备上寻求U3D原生GUI的替代方案
答
U3D原生GUI存在一些问题,如不美观、OnGUI方法耗费时间、使用不方便等,因此大家会寻求替代方案。
20. 请简述如何在不同分辨率下保持UI的一致性
答
NGUI很好地解决了这一问题,其原理是计算出屏幕的宽高比与原来预设的屏幕分辨率的对比值,然后修改摄像机的size,以实现屏幕分辨率的自适应性。
21. 为什么dynamic font在unicode环境下优于static font
答
Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。使用动态字体时,Unity将不会预先生成一个包含所有字体字符的纹理。当需要支持亚洲语言或者较大的字体时,若使用静态字体,字体的纹理将非常大,而动态字体则能避免这个问题。
22. Render的作用?描述MeshRender和SkinnedMeshRender的关系与不同
答
Render的作用是使对象显示在屏幕上。MeshRender用于渲染静态网格,而SkinnedMeshRender用于渲染带有骨骼动画的网格,它们都继承自Renderer类。
23. 简述SkinnedMesh的实现原理
答
暂未详细阐述。
24. 在场景中放置多个Camera并同时处于活动状态会发生什么
答
游戏界面可以看到多个摄像机画面的混合效果。
25. Prefab的作用?如何在移动环境的设备下恰当地使用它
答
Prefab在实例化时使用,主要用于经常会用到的物体,其属性方便修改。在移动环境的设备下,应合理使用Prefab,避免不必要的资源浪费。
26. 如何销毁一个UnityEngine.Object及其子类
答
使用Destroy方法销毁UnityEngine.Object及其子类。
27. 为什么Unity3D中会发生在组件上出现数据丢失的情况
答
组件上绑定的对象被删除时,会导致组件上出现数据丢失的情况。
28. 如何安全的在不同工程间安全地迁移asset数据?三种方法
答
- 将
Assets目录和Library目录一起迁移。 - 导出包。
- 使用Unity自带的
assets Server功能。
29. MeshCollider和其他Collider的一个主要不同点
答
MeshCollider具有Convex属性,这是它与其他Collider的一个主要不同点。
30. 当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免
答
可能会出现穿透现象,即碰撞检测失败。可以通过调整碰撞体的参数、提高物理模拟的精度等方法来避免。
31. OnEnable、Awake、Start运行时的发生顺序?哪些可能在同一个对象周期中反复的发生
答
运行顺序为Awake -> OnEnable -> Start。OnEnable在同一对象周期中可以反复发生。
32. 请简述OnBecameVisible及OnBecameInvisible的发生时机,以及这一对回调函数的意义
答
当物体的可见状态切换时,会触发OnBecameVisible和OnBecameInvisible回调函数。这一对回调函数可用于只需要在物体可见时才进行的计算,以提高性能。
33. Unity3D如何获知场景中需要加载的数据
答
可以使用Resource.Load和AssetBundle来获取场景中需要加载的数据。
34. MeshRender中material和sharedmaterial的区别
答
修改sharedMaterial将改变所有使用这个材质的物体的外观,并且也会改变存储在工程里的材质设置。不推荐直接修改由sharedMaterial返回的材质。如果想修改渲染器的材质,建议使用material。