MIL2——模拟面试题
MIL2——模拟面试题
问题
C#
-
请说说你认为 C# 中
==
和Equals
的区别是什么? -
浅拷贝和深拷贝的区别? 可以举例说明
-
下面两种获取10000个数的方式,哪种效率更高?为什么
1
2
3
4
5
6
7
8
9
10List<int> list = new List<int>();
for (int i = 0; i < 10000; i++)
{
list.Add(i);
}
float[] array = new float[10000];
for (int i = 0; i < 10000; i++)
{
array[i] = i;
} -
现在有如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static void Main(string[] args)
{
int i = GetInt();
Console.WriteLine($"第A处 i = {i}");
}
static int GetInt()
{
int i = 10;
try
{
return i;
}
finally
{
i = 11;
Console.WriteLine($"第B处 i = {i}");
}
}- A处和B处谁先打印?
- A、B出打印的i值分别是多少?
-
请问如下代码中,A、B两处 i 的值为多少?
1
2
3
4class Test
{
public int i = 10;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20static void Main(string[] args)
{
Test t = GetObj();
Console.WriteLine($"第A处 i = {t.i}");
}
static Test GetObj()
{
Test t = new Test();
try
{
return t;
}
finally
{
t.i = 11;
Console.WriteLine($"第B处 i = {t.i}");
}
}
Unity
- Unity中当一个细小高速物体撞击另一个较大物体时 会出现什么情况?如何避免?
- 请简述一下Prefab(预制体)的本质是什么?
- Unity是否支持写成多线程程序? 如果支持的话需要注意什么?
- 请简述一下对象池,在游戏开发中我们什么时候会用到它?
- 什么是DrawCall? DrawCall为什么会影响游戏运行效率? 如何减少DrawCall?
答案
C#
-
请说说你认为 C# 中
==
和Equals
的区别是什么?答案:
-
==
是运算符,Equals
是万物之父Object
中的虚方法,子类可重写 -
Equals
一般在子类中重写后用于比较两个对象中内容是否相同 -
==
在没有运算符重载的前提下时,引用类型用于比较地址;值类型用于比较值是否相同 - 运算效率不同,一般
Equals
没有==
效率高,因为一般Equals
比较的内容比==
多
-
-
浅拷贝和深拷贝的区别? 可以举例说明
答案:
- 浅拷贝: 只复制对象的引用地址 两个对象指向同一内存地址,修改其中一个另一个也会随之变化
- 深拷贝: 将对象和值赋值过来,两个对象修改其中任意值都不会影响对方
举例:
比如 引用对象A 和 引用对象B
让 A = B,就是浅拷贝,此时A、B的引用地址相同,改A中内容,B也变
如果想要深拷贝,简单处理就是new
(包括对象中的成员) -
下面两种获取10000个数的方式,哪种效率更高?为什么
1
2
3
4
5
6
7
8
9
10List<int> list = new List<int>();
for (int i = 0; i < 10000; i++)
{
list.Add(i);
}
float[] array = new float[10000];
for (int i = 0; i < 10000; i++)
{
array[i] = i;
}答案:
方式2的效率更高,因为
List
本质是数组,我们通过Add
往List
中添加元素时,会不断的触发扩容,扩容会带来内存和性能上的消耗- 内存方面:每次扩容会产生垃圾,还会造成GC的触发
- 性能方面:每次扩容会进行“搬家”(老数组中内容存入新数组中)
-
现在有如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static void Main(string[] args)
{
int i = GetInt();
Console.WriteLine($"第A处 i = {i}");
}
static int GetInt()
{
int i = 10;
try
{
return i;
}
finally
{
i = 11;
Console.WriteLine($"第B处 i = {i}");
}
}- A处和B处谁先打印?
- A、B出打印的i值分别是多少?
答案:
- B处先打印,A处后打印
- A处
i = 10
,B处i = 11
考点:finally的执行顺序(finally内的代码无论如何都会执行,哪怕是
return
或者throw
),值类型和引用类型的区别 -
请问如下代码中,A、B两处 i 的值为多少?
1
2
3
4class Test
{
public int i = 10;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static void Main(string[] args)
{
Test t = GetObj();
Console.WriteLine($"第A处 i = {t.i}");
}
static Test GetObj()
{
Test t = new Test();
try
{
return t;
}
finally
{
t.i = 11;
Console.WriteLine($"第B处 i = {t.i}");
}
}答案: A、B两处都为11
考点: finally的执行顺序(finally内的代码无论如何都会执行,哪怕是
return
或者throw
),值类型和引用类型的区别
Unity
-
Unity中当一个细小高速物体撞击另一个较大物体时 会出现什么情况?如何避免?
答案:
有可能会直接穿过物体,而不触发碰撞检测
- 我们可以尽量用射线检测来替代细小物体的物理系统碰撞
因为传统的FPS游戏都是通过射线检测加模拟计算来判断伤害的 - 修改
Rigidbody
刚体中的Interpolate
(插值)和CollisionDetection
(碰撞检测)两个参数,来提高碰撞检测的准确性
- 我们可以尽量用射线检测来替代细小物体的物理系统碰撞
-
请简述一下Prefab(预制体)的本质是什么?
答案:
Prefab的本质就是一个YAML配置文件
其中记录了一个GameObject对象上挂载的脚本信息
并且记录了脚本信息中的可配置的属性信息 -
Unity是否支持写成多线程程序? 如果支持的话需要注意什么?
答案:支持
注意:- 只能从主线程访问Unity相关组件、对象以及
UnityEngine
命名空间中的绝大部分内容 - 如果多线程中要和Unity主线程同时修改一些数据
可以通过lock
关键词加锁
- 只能从主线程访问Unity相关组件、对象以及
-
请简述一下对象池,在游戏开发中我们什么时候会用到它?
答案:
- 对象池的主要作用是 避免大量创建对象再释放对象时造成的内存消耗,可以有效降低GC发生的频率。
我们把不用的对象放入对象池中而不是让它直接变为垃圾,下次需要用到对象时再从对象池中获取,
我们通过占用内存来避免更多的内存消耗和GC的发生 - 在游戏中频繁创建对象、实例化对象的地方,都可以用到对象池。
比如前端开发中,游戏中的子弹、伤害字体、特效等等
比如后端开发中线程池等等
- 对象池的主要作用是 避免大量创建对象再释放对象时造成的内存消耗,可以有效降低GC发生的频率。
-
什么是DrawCall? DrawCall为什么会影响游戏运行效率? 如何减少DrawCall?
答案:
-
什么是DrawCall?
每次CPU准备渲染相关数据并通知GPU的过程称为一次DrawCall
-
DrawCall为什么会影响游戏运行效率?
如果DrawCall次数较高,意味着CPU会花费更多的时间准备渲染数据,这会进行更多的计算,进而影响游戏的运行效率
-
如何减少DrawCall?
- 2D和UI层面:打图集,并且注意面板中不同图集图片的层级不要穿插
- 3D模型层面:利用动态批处理和静态批处理,尽量不使用实时光照和实时阴影
等等
-