MIL20——模拟面试题

  1. C# 类中的函数是否占用内存空间?
  2. C# 中的函数是何时被加载到内存中的呢?
  3. C# 函数中一般会声明一些临时变量,当函数被加载内存中后,所占的内存空间是否包含函数中的这些临时变量?
  4. C# 中委托的本质是什么?它是如何存储函数的?
  5. C# 中事件的本质是什么?

Unity

  1. Unity 在发布 Android 平台项目时,在加载 Application.streamingAssetsPath​ 中文件时我们应该注意什么?
  2. Unity 中安卓主流的纹理压缩格式 ETC 和 ETC2 的主要区别是什么?
  3. Android 平台常用压缩格式 ETC 不支持透明通道,那我们的半透明纹理应该如何处理?
  4. Unity 中针对 IOS 平台我们使用的主流纹理压缩格式是什么?
  5. 请问为什么延迟渲染路径能够优化有大量光源的场景渲染

答案

C#

  1. C# 类中的函数是否占用内存空间?

    占用,但是它不再我们通常说的堆栈中,而是存储在内存中的文本段(Text Segment),它是存储可执行程序的代码的内存段

  2. C# 中的函数是何时被加载到内存中的呢?

    CLR(公共语言运行时)会按需加载程序集和其中的类型和成员,程序执行到需要调用某个类的函数时,
    CLR 会负责将该函数的 IL 代码编译成本机代码,并将其加载到 Text Segment 中,
    一旦函数的代码被加载到内存中,它通常会一直存在于内存中,直到程序退出

    运行可执行文件后的流程:

    image

  3. C# 函数中一般会声明一些临时变量,当函数被加载内存中后,所占的内存空间是否包含函数中的这些临时变量?

    不会包含。函数中的临时变量,不管是值类型还是引用类型都是在函数执行期间动态分配的。
    这些临时变量会在堆栈中进行内存分配,栈上的内存由 CLR 动态管理,用完会被销毁,堆上的内存有 GC 垃圾回收机制统一进行管理

  4. C# 中委托的本质是什么?它是如何存储函数的?

    委托的本质是一个类,当我们声明一个委托时,相当于声明了一个类。
    它会默认继承 System.MulticastDelegate​ 类(多播委托类) 而这个 System.MulticastDelegate​ 类,又继承 Delegate​ 类(委托类)
    这些父类当中的一些方法,就是当我们对委托进行操作时真正会调用的内容,

    image

    image

    通过这些父类中的方法我们其实可以简单推测出,委托中存储函数的本质:
    是通过一个委托类对象来存储对象的引用或者静态类的类型,然后再记录一个函数的名字。
    但是实际上,在内部会根据这些信息定位到:

    1. 函数的引用(函数的内存地址)
    2. 函数所在对象的引用(如果是实例方法),而当我们进行 +=​ 操作时,其实 C# 内部会调用父类中的 Combine​ 结合方法,
      在底层帮助我们声明一个新的委托对象来记录对应函数的相关信息
  5. C# 中事件的本质是什么?

    通过对委托的理解,来帮助我们理解事件将会变得比较容易,
    我们在使用事件的时候往往是在类中声明成员变量时,当我们声明一个事件时,本质就是对委托进行私有访问限制的封装
    事件的本质其实就是委托 ,只不过系统会对 event​ 字段修饰的委托在编译时进行一些特殊处理,这些特殊处理包括:

    1. 生成一个私有的委托变量
    2. 添加两个事件访问器(用于在外部 +=​ 和 -=​)
    3. 禁止外部类对事件进行一些操作

Unity

  1. Unity 在发布 Android 平台项目时,在加载 Application.streamingAssetsPath​ 中文件时我们应该注意什么?

    无法使用 File​ 中相关 API 进行加载,只能使用 Unity 中 WWW​、UnityWebRequest​、AssetBundle​ 相关 API 进行加载

  2. Unity 中安卓主流的纹理压缩格式 ETC 和 ETC2 的主要区别是什么?

    1. 透明通道

      • ETC 不支持透明通道
      • ETC2 支持透明通道
    2. 压缩效率

      • ETC2 相对 ETC 在相同压缩比下图像质量更好
    3. 支持设备

      • ETC 基本支持所有 Android 设备,ETC2不支持低端设备

    目前 ETC2 在逐渐取代 ETC

  3. Android 平台常用压缩格式 ETC 不支持透明通道,那我们的半透明纹理应该如何处理?

    将纹理的透明通道分离,1 张存 RGB,1 张存 A,
    利用自定义 Shader 将其组合使用,ETC 的内存占用相对 RGBA32 会降低为之前的 1/4,效率也会提升
    因此即使分成 2 张图,内存占用也会减少到之前的 1/2

  4. Unity 中针对 IOS 平台我们使用的主流纹理压缩格式是什么?

    1. PVRTC:最主流最常用,支持所有 IOS 设备
    2. ASTC(如果设备支持,推荐使用)和 ETC2,iPhone 5s 及以上型号的 iPhone 手机,iPad Air 及以上型号的 iPad 平板电脑

    他们都支持透明通道,因此我们无需进行额外处理

  5. 请问为什么延迟渲染路径能够优化有大量光源的场景渲染

    因为延迟渲染路径利用了 G 缓存来存储最终可见的片元信息,
    当我们真正进行光照计算时,只会计算 G 缓冲区中存储的各片元信息,这会减少很多不必要的光照计算