欢迎来到光光的奇妙冒险,我是你们的煎饼光子老师。
今天是我们的第五期笔试面试题总结。
C#部分:
1、以上代码,谁的效率更高?为什么?
答案:
代码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、请问最终的打印结果是什么?
答案:
0-Alice-7
string类型只要赋值就会生成新的地址,这一点使得它虽然是引用类型,但在实际使用中却很像值类型;
而数组是引用类型,在new时才会产生新地址
此处使用ref关键字传入Record,得到的结果才是“6-Bob-7”
考点:
1.值和引用的区别
2.特殊引用类型string
3.结构体中的引用成员
5、网络游戏开发中,网络传输数据的基本流程是什么?
答案:
客户端将自定义类对象数据序列化为2进制数据发送给服务端
服务端将收到的2进制数据反序列化为对应的类对象进行逻辑处理
如果是服务端发送给客户端的消息也是同理
Unity部分:
1、两个四元数相乘有什么作用?四元数乘以向量有什么作用?
四元数相乘:角度叠加
四元数乘以向量:向量旋转
2、图中的小球是否被渲染了?是否会产生DrawCall?
答案:
不会被渲染,不会产生DrawCall
Unity本身有摄像机视锥体剔除,也就是不会显示完全位于视锥体之外的游戏对象
那么小球就不会进行渲染,也不会提交数据给GPU,也就不会产生DrawCall
3、在没有使用遮挡剔除的情况下,图中A和B都是默认标准材质,图中的小球最终是否会被渲染,是否会产生DrawCall
答案:
最终不会被渲染,标准材质存在深度测试,小球在立方体后方,不会通过深度测试,所以不会被渲染
会产生DrawCall,既然都深度测试了,那么肯定是存在DrawCall的
深度测试发生在片元着色器处理之后,GPU会对每个片元执行深度测试来决定遮挡关系,决定是否被渲染
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来测试移动设备的输入相关逻辑