MIL5——模拟面试题

问题

C#

  1. 以下代码,谁的效率更高?为什么?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //代码1:
    List<int> list = new List<int>();
    for (int i = 0; i < 50; i++)
    {
    list.Add(i);
    }
    //代码2:
    List<int> list2 = new List<int>(50);
    for (int i = 0; i < 50; i++)
    {
    list2.Add(i);
    }
  2. 数组和链表的区别是什么?

  3. C# 中的 Action​ 和 Func​ 是什么?Unity 中的 UnityAction​ 是什么?他们有什么区别?

  4. 请问最终的打印结果是什么?

    1
    2
    3
    4
    5
    6
    public struct Record
    {
    public int id;
    public string name;
    public int[] children;
    }
    1
    2
    3
    4
    5
    6
    public void DoSomething(Record record)
    {
    record.id = 6;
    record.name = "Bob";
    record.children[0] = 7;
    }
    1
    2
    3
    4
    5
    var record = new Record();
    record.name = "Alice";
    record.children = new int[] { 1, 2, 3 };
    DoSomething(record);
    Debug.Log(string.Format("{0}-{1}-{2}", record.id, record.name, record.children[0]));
  5. 网络游戏开发中,网络传输数据的基本流程是什么?

Unity

  1. 两个四元数相乘有什么作用?四元数乘以向量有什么作用?

  2. 图中的小球是否被渲染了?是否会产生DrawCall?

    image

  3. 在没有使用遮挡剔除的情况下,图中A和B都是默认标准材质,图中的小球最终是否会被渲染,是否会产生DrawCall

    image

  4. 如果不考虑IOS平台,只在Windows和Android平台上发布游戏,如何在不使用第三方热更新方案的前提下实现热更新功能

  5. Unity中如何调试排查Android上运行的项目问题

答案

  1. 以下代码,谁的效率更高?为什么?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //代码1:
    List<int> list = new List<int>();
    for (int i = 0; i < 50; i++)
    {
    list.Add(i);
    }
    //代码2:
    List<int> list2 = new List<int>(50);
    for (int i = 0; i < 50; i++)
    {
    list2.Add(i);
    }

    答案:

    代码2的效率更高,因为 List​ 的本质是数组,
    在初始化时,如果不默认为其指明分配多少容量,它会不断扩容,扩容会带来效率的降低和垃圾的产生

    • 效率的降低:从旧数组到新数组的搬家
    • 垃圾的产生:每次扩容时,旧数组就变成了垃圾
  2. 数组和链表的区别是什么?

    答案:

    1. 存储结构不同

      • 数组是顺序存储结构,在内存中是连续存储的
      • 链表是链式存储结构,在内存中是非连续存储的
    2. 访问效率不同

      • 数组由于是顺序存储,通过下标访问,访问效率高
      • 链表由于是非连续存储,我们想要获取其中某一元素,需要从头或尾遍历,效率低
    3. 插入、删除效率不同

      • 数组由于是顺序存储,在插入和删除时,需要整体移动数组中的大部分元素,效率低
      • 链表由于是链式存储,在插入和删除时,效率高
    4. 越界问题

      • 数组由于是顺序存储,声明时容量是固定的,如果不处理扩容逻辑,存在越界风险
      • 链表由于是链式存储,无越界风险
  3. C# 中的 Action​ 和 Func​ 是什么?Unity 中的 UnityAction​ 是什么?他们有什么区别?

    答案:
    Action​ 和 Func​ 是 System​ 命名空间下 C#为我们提供的两个写好的委托

    • Action​ 本身是一个无参无返回值的委托,对应的 Action<>​ 泛型委托支持最多16个参数
    • Func​ 本身是一个无参有返回值的委托,对应的 Func<>​ 泛型委托支持最多16个参数,并且有返回值

    UnityAction​ 是 UnityEngine.Events​ 命名空间下,Unity为我们提供的写好的委托
    UnityAction​ 本身是一个无参无返回值的委托,对应的 UnityAction<>​ 泛型委托支持最多4个参数

  4. 请问最终的打印结果是什么?

    1
    2
    3
    4
    5
    6
    public struct Record
    {
    public int id;
    public string name;
    public int[] children;
    }
    1
    2
    3
    4
    5
    6
    public void DoSomething(Record record)
    {
    record.id = 6;
    record.name = "Bob";
    record.children[0] = 7;
    }
    1
    2
    3
    4
    5
    var record = new Record();
    record.name = "Alice";
    record.children = new int[] { 1, 2, 3 };
    DoSomething(record);
    Debug.Log(string.Format("{0}-{1}-{2}", record.id, record.name, record.children[0]));

    答案:0-Alice-7

    考点:

    1. 值和引用的区别
    2. 特殊引用类型 string
    3. 结构体中的引用成员
  5. 网络游戏开发中,网络传输数据的基本流程是什么?

    答案:

    客户端将自定义类对象数据序列化为2进制数据发送给服务端
    服务端将收到的2进制数据反序列化为对应的类对象进行逻辑处理
    如果是服务端发送给客户端的消息也是同理

Unity

  1. 两个四元数相乘有什么作用?四元数乘以向量有什么作用?

    • 四元数相乘:角度叠加
    • 四元数乘以向量:向量旋转
  2. 图中的小球是否被渲染了?是否会产生DrawCall?

    image

    答案:

    最终不会被渲染,标准材质存在深度测试,小球在立方体后方,不会通过深度测试,所以不会被渲染
    会产生DrawCall,既然都深度测试了,那么肯定是存在DrawCall的
    深度测试发生在片元着色器处理之后,GPU会对每个片元执行深度测试来决定遮挡关系,决定是否被渲染

  3. 在没有使用遮挡剔除的情况下,图中A和B都是默认标准材质,图中的小球最终是否会被渲染,是否会产生DrawCall

    image

  4. 如果不考虑IOS平台,只在Windows和Android平台上发布游戏,如何在不使用第三方热更新方案的前提下实现热更新功能

    答案:C#的反射
    可以通过热更DLL文件的形式,加载程序集(dll)
    利用反射执行热更DLL包中的逻辑

  5. Unity中如何调试排查Android上运行的项目问题

    答案:

    1. 如果需要进行断点调试

      通过数据线链接运行项目的Android设备,发布时开启了

      • Development Build 开发模式构建
      • Autoconnect Profiler 自动连接分析器
      • Script Debuggins 脚本调试
      • Wait For Managed Debugger 等待托管调试器

      等选项

      然后只需要Build and Run既可以,利用Unity的Profiler 性能剖析器窗口排查性能问题,并且还可以进行断点调试

    2. 如果只是获取一些打印调试信息

      可以利用Unity2019.4及其以上版本提供的Android Logcat工具获取信息
      Unity2019.4以下的版本,可以使用Android的ADB(安卓调试桥)工具

    3. 如果需要获取设备输入信息
      可以利用Unity Remote来测试移动设备的输入相关逻辑