**
第一部分:面试题 越甲天下
**
1.假设有八枚硬币,其中有一枚是假币,质量轻于其他七枚,给你一台天平,请问至少要多少次可以得到假币,并说明方法。
答:2次
将8枚硬币分为3份,分别为3,3,2 ,比较3,3的两堆 如果一样重,则说明假币在 2的这堆里面,再比较2枚硬币,轻的则为假币,如果 不一样重,则说明假币在轻的一方,从中再挑出2枚硬币,如果一样重,则另一枚则为假币,不一样重,则轻的那一枚为假币
2. 现有一个RGB颜色值,RGB三个分量分别为r=128,g=20,b=100,请将r g b三个变量写一个表达式,求出一个color值(转换为十六进制记法)
Byte r=128 g=20,b=100
3. C#中怎么使用引用,引用传递和值传递有什么区别
使用ref和out关键字传递,引用传递是传递地址,修改会改变原有的值, 值传递只传递值的副本。不会对原有的值进行改变。
4. 有这样一个字符串:“100|500;300|20;6|200;800|30”,每个分号隔开一组参数,总共4组,每组以|分割,请将这个字符串拆分并转换为key-value模式存储。
string s = "100|500;300|20;6|200;800|30";
Dictionary<string, string> d1 = new Dictionary<string, string>();
string[] s1 = s.Split(';');
string[] s2;
for (int i = 0; i < s1.Length; i++)
{
s2 = s1[i].Split('|');
d1.Add(s2[0], s2[1]);
}
5. 简述泛型的优点,并列举一个实际应用场景
性能优化,类型安全,List和ArrayList相比较多了一个泛型约束,如果直接用ArrayList会将数据转化为Object再存储进去,使用的时候就多了一个装箱的操作,对性能消耗很大, 泛型在使用时就需要声明好类型。
6. Dictionary,list,SortedSet的区别及应用场景
dictionary是通过哈希表存储键值对的,可以通过键来访问值,比较适合用于频繁访问数据的时候,列表是通过数组来进行存储的,可以通过下标进行访问,比较适合用来存储相同类型数据。排序列表也是存储的键值对,不同的是它会根据键进行排序。在数据基本有序的情况下比较适用。
7.abstract,static,interface,where,virtual的区别。
abstract:抽象,修饰类或者方法,修饰类表示该类不可被实例化,抽象方法只能存在于抽象类中,抽象方法不能有具体方法。
static:静态的,声明属于类型本身而不是属于特定对象的静态成员
interface:声明为接口类型,即类或者构造必须声明的合同
where:基类类型约束
virtual:修饰方法属性等,使其可在派生类中被重写
8. 实现一个枚举,获取枚举的整型值及本身的字符串
public enum color
{
red = 34,
blue = 288,
yellow
}
Debug.Log((int)color.red);
Debug.Log(color.yellow);
9. 实现一个玩家对象的等级属性,并阐述属性的作用
10. 什么是多态,什么是虚函数,列举其应用场景
同样的操作作用于不同的对象,产生不同的效果,就是多态,虚函数表示父类方法使用virtual关键字修饰,继承该类的方法可以重写该方法。
11. 什么是不定参数,请实现一个带有不定参数的方法,并阐述其作用
void testMethod(params int[] values)
{
for (int i = 0; i < values.Length; i++)
{
Debug.Log(values[i]);
}
}
使用关键字params 输出该参数列表
12. 什么是协程,并谐剧应用场景
是一个特殊的函数,程序运行时暂停自身并且提交一个唤醒的条件,直到条件完成,就会继续运行。会在lateupdate之后执行。
应用场景:计时器,打字机效果,异步加载资源
13. 请实现一个基础的事件管理器,用于注册,删除,添加事件
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
public class EventmanagerA
{
//事件的存储方式,事件的添加 事件的移除(指定的某个事件) 移除所有事件
private static EventmanagerA _instance;
public static EventmanagerA instance
{
get
{
if (_instance == null)
{
_instance = new EventmanagerA();
}
return _instance;
}
}
public delegate void onactionhandler(object p);
public Dictionary<int, List<onactionhandler>> dic = new Dictionary<int, List<onactionhandler>>();
public void addeventlistener(int key, onactionhandler handler)
{
if (dic.ContainsKey(key))
{
dic[key].Add(handler);
}
List<onactionhandler> list = new List<onactionhandler>();
list.Add(handler);
dic.Add(key, list);
}
public void removeeventlistner(int key, onactionhandler handler)
{
if (dic.ContainsKey(key))
{
List<onactionhandler> list = dic[key];
list.Remove(handler);
if (list.Count > 0)
{
dic.Remove(key);
}
}
}
public void Dispatch(int key, object p)
{
if (dic.ContainsKey(key))
{
List<onactionhandler> list = dic[key];
if (list.Count > 0 && list != null)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i] != null)
{
list[i](p);
};
}
}
}
}
public void Dispatch(int key)
{
Dispatch(key, null);
}
}
14. 简述unity为什么能够实现跨平台特征。
主要使用了一种叫CIL的代码指令集,
**
第二部分:大梦龙图笔试题
**
1.简单描述prefab的用处和环境
预制体,通常是会被重复创建使用的同一对象,如子弹等。类似于一个模板,批量生成同类型的克隆体
2.简单描述AssetBundle的作用
热更新时使用assetbundle压缩资源从服务器进行更新传输。
打包压缩资源,减小安装包大小。
3.解释一下vertex shader 和pixel shader
定点着色器 和像素着色器 vertexshader 是改变物体模型外形的,由于模型是由点构成的,因此改变点就是改变外形
当模型顶点变换完之后,是需要填充颜色的,这些填充算法是针对屏幕上的每个像素的
4.通过脚本来删除一个GameObject
Destroy(gameobject)
DestroyImmediate(gameobject)
5.unity3d脚本从唤醒到销毁有一套比较完整的生命周期,请列出系统自带的几个重要的方法。
Awake onenable start fixedupdate update lateupdate ondisable ondestroy
6.如何计算vector3的长度
vector3.mangitude
7.vector3.normalize有什么意思,如何计算这个值
单位向量 长度为1
8.Application.datapath;Application.streamingassetspath;application.persistentdatapath在安卓和ios平台下,分别对应的位置是什么
Platform: UNITY_ANDROID
Application.dataPath: /data/app/com.Company.ProductName-1.apk
Application.streamingAssetsPath: jar:file:///data/app/com.Company.ProductName-1.apk!/assets
Application.persistentDataPath: data/com.Company.ProductName/files
Platform: UNITY_IOS
Application.dataPath: ProductName.app/Data
Application.streamingAssetsPath: ProductName.app/Data/Raw
Application.persistentDataPath: /Documents
9.不使用foreach如何遍历一个字典
var enumerator = dic.GetEnumerator();
while (enumerator.MoveNext())
{
Debug.Log(enumerator.Current.Key+":"+enumerator.Current.Value);
}
10.Animator的状态机有哪些类型的参数
Float int bool trigger
11.如何控制多个相机的显示顺序
摄像机的Depth参数控制
12.如何执行一个协程,如何停止一个协程
startcoroutine() stopcoroutine()
实现一个简单的计时器
float time = 0f;
public Text hourtext;
public Text minutetext;
public Text secondtext;
int hour;
int min;
int second;
// Use this for initialization
void Awake()
{
StartCoroutine(timecau());
}
IEnumerator timecau()
{
while (true)
{
time = time + Time.deltaTime;
hour = (int)time / 3600;
min = (int)time / 60;
second = (int)time % 60;
TimeTrans(hour, min, second);
print(time);
yield return null;
}
}
void TimeTrans(int hour, int min, int second)
{
hourtext.text = hour.ToString();
minutetext.text = min.ToString();
secondtext.text = second.ToString();
}
13.请指出下面代码的错误
using unityEngine
using system.collection
public class Test:MonoBehaviour{
void start(){
transform.position.x =10
}
}
因为position是vector3,vector3是结构体的类型的,这相当于对他的副本赋值,就算赋值也没有意义。
14.补全下面的update函数,让这个gameobject以speed的速度向target移动,当与target的距离小于等于1时停止
public Vector3 target;
public float speed;
private void Update()
{
}
if (Vector3.Distance(target, transform.position) > 1f)
{
transform.position = Vector3.MoveTowards(transform.position, target, speed);
}
**
第三部分:杂项
**
1.transform的localPosition 和position的区别
一个是相对于世界原点为中心 一个是相对于父节点为中心
2.如何销毁一个基类为UnityEngine.Object的实例
Destroy()方法
DestroyImmediate()方法
3.写出几个U3D脚本自带函数的执行顺序
Awake()->OnEnable()->Start()->fixedupdate()->update()->lateupdate()->OnGui()->OnDisable()->OnDestroy()
4.Unity动态加载资源有哪些接口,有什么区别?
答:
1.resource.load(),加载Resources 的目录中的资源
2.www(可以加在任意处的资源(服务器)已被弃用)
3.unitywebrequest (www的升级版本,)
4.AssetDatebase.load(只能加载assets目录下的资源,只能用于editor)
5.assetbundle(只能加载ab资源,当前设备允许访问的路径都可以)
加载资源,同步和异步的特点
同步:管理方便,资源准备好可以及时返回,缺点,没有异步快
异步:加载资源快,与主线程无关,缺点:调用比较麻烦,最好的方法是使用回调
5.什么是协同程序,与C#的线程有什么区别?
答:协同程序:在主线程运行的同时开启一段逻辑处理,来协助当前的程序执行。
协程避免了无意义的调度,由此可以提高性能,需要自己调度自己的协程,失去了标准线程对cpu使用的能力例如单核情况下,有ab两个线程需要处理,那么先a再切换到b
协程常用于多任务的同时处理,线程多用于单任务时的分时处理。
6.unity3d中的drawcall有几种合并方式?
答:
7.简单描述c#中关键字abstarct,virtual override 和sealed的含义
答:
Abstract:抽象,修饰类表示该类为抽象类,不可被实例化,具体派生类必须覆盖基类的抽象方法。修饰方法,表示该方法为抽象方法,不能实现该方法,只包含声明。
Virtual:虚方法,修饰方法,表示该方法可以被重写
Override:修饰方法,表示重写
Overload:重载
Sealed:修饰方法,表示该方法仅该类可访问,修饰类表示该类不可被继承。
8.抽象类和接口的区别
答:
相同点:
都不能被实例化,都可以被继承
都可以包含方法声明
派生类必须实现未实现的方法
区别:1.抽象类可以定义字段,属性,方法实现。接口可以实现方法,事件,属性,索引器,但不能定义字段。
2.抽象类是一个不完整的类,需要进一步实现(继承,并实现方法)。接口是一个行为规范,可以直接继承引用
3,接口可以被多重实现,抽象类只能被单一继承。
4.抽象类更多的定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类间
5.抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性,接口是为了满足外部调用而定义的一个功能约定,因此反映的事物的外部特性。
6.接口基本不具备继承的特性,仅仅能够调用而已。
7.接口可以用于支持回调,而继承并不具备这个特点。
8.抽象类中实现具体方法默认为虚的,而实现接口的类中的接口方法却默认为非虚,当然也可以声明为虚。
9如果抽象类中实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口方法
8.以下代码片段有什么问题
Int[] a = new int[128];
foreach(int aa in a){
Foreach(int bb in a){
Foreach(int cc in a){
cc=0;
}}}
答:foreach取值是只读的,不能给元素赋值。
Public class test: MonoBehaviour{
Void start(){
Transform.position.x =10;
}
}
答:上述代码是没有意义的 因为transform.position 返回值是vector3 vector3的类型是结构体,transform.position.x只是他的副本,并不能真真修改到他的值。所以不能赋值。
9.arrylist 和list的区别?
答:arrylist相比较list是一种非类型安全的,在装箱和拆箱操作过程中可能遇到数据类型不匹配造成一些性能损耗
10.以下哪些是值类型,哪些是引用类型
Object class enum struct bool int string float interface delegate
答:object class interface string delegate 是引用类型 其他是值类型 所有的类型都指向object 值类型继承valuetype
10.请指出下面代码中,哪些地方会发生装箱或者拆箱
Int a =10; object obj =a; obj =100; int b =(int)obj; Type type = b.GetType()
String str = b.ToString() Console.Write(obj) Console.Write(b);
答:object obj =a 装箱obj =100装箱 int b = (int)obj 拆箱 Type type = b.GetType()装箱
string str = b.ToString(); 虽然ToString()是object的方法,但int已经对它进行了重写,并且值类型都是密封的,所以将会直接调用int的ToString()方法;
而最后两句:Console.Write()共有18个重载的方法,其中有Console.Write(object value)及Console.Write(int value)两个重载方法,所以不会产生装箱。
11.列举2个以上你熟悉的C#容器(List,Dictionary等),描述其适用场景,并简述其底层数据结构。
在这里插入代码片
12.c#中struct 和class的区别,作为参数是有何优劣?Unity中常见的struct类型有哪些?
答: struct 是值类型, 他的引用对象在栈上,引用对象时,会取他的副本,不会改变本身,class是引用类型,对象在堆内存上,会使用他的引用, struct的话 空间较小,访问速度快,class 空间较大,访问速度慢,结构适合表示一个轻量级对象。
Unity中常见的结构体 有 vector3 vector2 vector4 Rect Color Color32 Bounds Touch
13.ref参数和out参数是什么?有什么区别?
答:使用ref参数需要在 使用前先声明初始化 ,将值类型作为引用类型传递
使用out参数不需要在使用前初始化,但需要在传递过程(方法)中对其赋值,也是将值类型作为引用类型传递。
14.heap与stack有何区别?
答:堆内存是用来存储引用类型的也可以存储值类型,栈是用来存储值类型的,栈有自动清理功能,堆则是需要使用GC清理, 当我们使用引用类型时,我们在和指向引用类型的指针打交道,而不是引用类型本身。当我们使用值类型时,我们就是在和值类型本身打交道。
15.如何在list中删除多个数据,在dictionary中呢?
答:RemoveAll 使用tolist 将dictionary转化为list进行操作
16.匿名委托是什么?什么是闭包?
答:匿名委托:委托的一种简单化声明方式,通过delegate 关键字声明
闭包:闭包是一个包含了上下文环境的匿名函数,匿名函数内可以使用上层作用域的变量。
17.C#中什么是反射?反射的实现原理?
答:反射指程序可以访问、检测和修改它本身状态或行为的一种能力。
18.数据序列化的方式有哪些?简述实现序列化的原理与用途?
xml ,json
19.求下面二叉树的前序遍历,中序遍历的输出结果。
答:给定了二叉树的任何一种遍历序列,都无法唯一确定相应的二叉树。但是如果知道了二叉树的中序遍历序列和任意的另一种遍历序列,就可以唯一地确定二叉树。
前序遍历:6 4 2 3 5 1 7 根左右
中序遍历:3 2 4 6 1 5 7 左根右
后序遍历:3 2 4 1 7 5 6 左右根
20.平时使用过哪些设计模式?有何作用与缺陷?
答:单例模式 观察者模式 工厂模式
21. MVC模式的理解?
MVC:使用数据-控制显示分离的工作方式,目的使代码结构清晰化
M 数据层; 提供两种函数接口:操作。 获取数据, 并可以发送更新消息
V 视图层 接受消息并控制界面显示,跳转效果等。
C 实现必要逻辑
22.MonoBehaviour的函数执行顺序?
答:Awake start onenable fixedupdate update lateupdate ongui ondisable ondestroy
23.向量的点乘,叉乘以及归一化的意义?
答:点乘:一条边在另一条边上的投影乘以另一条边的长度
叉乘:求向量在平面的法向量
归一化的意义:计算时我们无需考虑具体的模长带来的影响,只考虑向量的方向
24.简述四元数的作用,四元数对欧拉角的优点?
答:四元数用于表示旋转,相对于欧拉角
1.能进行增量旋转
2.避免万向锁
3.给定方位的表达有两种,互为负(欧拉角有无数种表达方式)
25.什么是prefab,有什么用处?
答:预制体 类似声明了一种模板,是一种可以被重复使用的对象,使用该物体创建的对象都是被克隆的,修改预制体对象,可以同步修改所有使用该预制体创建出来的对象。
26.UGUI的常用类有哪些,常用的优化方式有哪些?
答:
Button Slider Text Image Toggle ScrollBar InputField Canvas EventSystem
优化方式:
1.检查空image
2.优化九宫格 Image
3.检查Mask组件
4.检查错误透明材质
5.错误的UI设置
https://www.cnblogs.com/lan-yt/p/9470157.html
27.怎么样在UGUI上显示模型,特效?
答:使用RenderTexture渲染在RawImage后显示在UI上。
28.怎么样在UGUI上实现无限滑动列表?
答:
29.简单描述一下使用过的热更新,实现原理与流程?
答:tolua,访问服务器 比对本地的files.txt文件 的md5值 如果一样则不会进行更新 ,加载本地资源,如果不一样 会把服务器上的ab文件加载到本地,并且更新files.txt文本 加载下载下来的文件。
30.简单介绍一下之前使用的资源加载管理策略?有何优化方向?
31.MeshRender中material与sharedmaterial的区别?
答:Material:只会改变当前对象的材质设置
Sharedmaterial:共享的,改变这个设置,所有用到这个材质的都会被改变
32.什么是LOD,MipMap?
答:LOD Level of Detail,多层次细节,添加LOD Group 目的是让一个物体距离不同的时候渲染不同的资源,但是会加大内存。 针对模型资源
MiniMap:类似LOD,对象离摄像机越远的时候像素越低,越模糊 针对纹理资源
33.什么是DrawCall?如何降低Drawcall?
答:
34.TextureType选项分别选为“Texture”和“Sprite”有什么区别?
1.texture用在rawimage组件上 sprite用在image组件上
2.Texture没有图集的概念,sprite 有图集的概念
3.Texture 比较节省资源,但是他每一张texture 就是一次drawcall,而一个sprite的图集只会产生一个drawcall,但是比较耗费内存
4.Texture不可以直接拖入3d或者2d场景中,用于3d模型贴图,再由GPU把模型渲染出来。Sprite则可以在3d场景中直接作为对象,会自动添加一个spriterender组件。
5.图片过大,不适合图集的时候用texture ,图片使用频率不高,例如登录加载闪屏
6.图片修改麻烦的时候也可以用texture
35.在使用UGUI时遇到过什么问题?如何解决的?
答:粒子特效无法显示在UI上层
1.一开始尝试去看渲染层级,然后发现不是这个问题,查到选择的渲染模式不支持粒子显示,然后就换到了相机模式,添加了一个2d摄像机 赋值上去 就发现粒子特效显示在上层了
36.请简述GC产生的原因,并描述如何避免?
答:
1.Garbage Collection,在堆内存上进行内存分配操作而内存不足的时候都会触发垃圾回收来利用闲置的内存
2.GC会自动的触发,不同平台运行频率不一样
3.GC可以被强制执行 GC.Collect()
大量的GC操作会使运行的游戏变得卡顿,减少GC得方式主要有几种:
1.减少GC的运行次数
2.减少单次GC的运行时间
3.将GC的运行时间延迟,避免在关键的时候触发,比如可以再场景加载的时候调用GC
避免的方法:
1.缓存,需要重复使用的对象 在函数外部声明变量
2.不要在频繁调用的函数中反复进行堆内存分配
3.清除链表 链表需要重新设置时使用clear
4.对象池,避免重复创建对象,产生大量的对象。
5.尽量少使用string 改为使用stringbuilder
6.移除游戏中的Debug.log()函数
7.注意使用UNity中自带的函数
8.减少装箱操作
9.协程操作的使用,如果yield带有参数返回,会造成不必要的内存垃圾
10.Foreach循环 5.5以前每次foreach迭代会在堆内存上昌盛一个system.Object对象来实现迭代操作。
11.减少函数的引用
12.重构代码减少GC的影响
37.Shader 的光照模式有哪些?什么是渲染管道?
答:1.环境光Ambient 2.自发光Emissive 3.漫反射diffuse 4.高光反射 Specular
渲染管道:主要分为:应用程序阶段、顶点处理、面处理、光栅化、像素处理
38.在物体发生碰撞的整个过程中,有几个阶段,分别列出对应的函数?
答:istrigger为false时 oncollisionenter oncollisionstay oncollisionexit
Istrigger为true时 ontriggerenter ontriggerstay ontriggerexit
39.平时有哪些提升自己的方式?
答:浏览别人的博客,自己动手 穿插在各个技术类群之间,看大佬们讨论学术问题。购买了一些完整项目,自行研究。
40.简述Unity对资源的内存管理机制
41.简述TCP建立连接与断开连接的握手流程
TCP建立连接的三次握手:
1.首先主机A通过向主机B发送一个含有同步序列号的标志位的数据段,向主机B请求连接,通过这个数据段,告诉主机B向主机B建立连接,并且需要用哪个序列号作为回应。
2.主机B收到主机A的请求,用一个带有确认应答(ACK)和同步序列号(SYN)的数据段响应主机A,目的是告诉主机A已经收到请求,可以连接数据了,你要用哪个序列号作为起始数据来回应我。
3.主机A收到B的回复,再发送一个确认请求。已经收到回复,要开始传输数据了。
断开连接的四次断开:
1.当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求
2.主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1
3.由B端再提出反方向的关闭请求,将FIN置1
4.主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束。
42.简述UI资源的管理方法
43.简述UI系统优化方法
44.你所知道的有哪些排序方式,选一种排序方式描述具体的算法思路
答:冒泡排序 选择排序 插入排序 归并排序 快速排序 希尔排序 堆排序
快速排序 ,主要思想是二分法, 选取首位为基准值,中心思想是从前往后遍历,小于基准值的会被放到基准值的左边,大于基准值的会被放在右边,返回基准值的位置然后再度遍历。直到传入的值的相等或者前面的大于后面的就排列好了。
45.C#中数组, ArrayList 和List 三者的区别?
数组是连续的内存块存储结构,声明的时候定义长度,定义同种类型数据,插入删除时比较麻烦。需要对所有的元素进行位置改动,赋值和修改元素比较简单,取值也快。
Arraylist 是集合的一种,可以放任何类型,不受限制,但是他取用时可能会存在大量的装箱拆箱操作,比较耗费性能,不安全类型。
List泛型也是用来存储同种类型的数据,但是他的长度不受限,增加移除数据方便,也不存在装箱拆箱的操作。
46.C#中string、stringbuilder 的异同
String:每次修改string 类型的字符串 都要重新生成一块内存区域存储一个string对象,比较浪费内存
Stringbuilder:stringbuilder 对象每次修改会在原基础上进行字符改动。 stringbuilder线程不安全
stringBuffer和stringBuilder是一样的,后者速度比前者快,但是前者是线程安全的,适合在多线程下使用,后者是线程非安全的,比较适合在单线程下使用。
47.C#中的委托是什么?事件是不是一种委托
答:委托:将方法当做参数使用 关键字delegate
是 event
48.什么是反射?C#中怎么调用外部动态链接库?
答:
49.简述AssetBundle的加载过程与注意事项。
答:
50.简述自定义模型的实现原理并说明如何在Untiy中自定义模型。
答:
51.UnityShader中用的是什么语言?UnityShader中Lighting,culling ,ztest,zwrite,fog,alphaTest,blend,offset,colorMask 分别代表什么意思?
52.写一个生产者消费者的伪代码?
假设缓冲区大小为10,生产者、消费者若干。只要缓冲区池未满,生产者便可以将消息送入缓冲区池,只要缓冲区池未空,消费者便可以从缓冲区中取走一个消息。
items代表缓冲区可使用的资源数,space代表缓冲区可用资源数
mutex表示互斥锁
buf[10]代表缓冲区,内容类型为item
in、out代表第一个资源和最后一个资源(i即in最早产生的资源)
var items=0,sapce=10,mutex=1;
var in=0,out=0;
item buf[10]={NULL};
producer{
while(true){
P(space);//等待缓冲区有空闲位置,在使用PV操作时,条件变量需要在互斥锁之前
P(mutex);//保证在product时不会有其他进程访问缓冲区
//product
buf.push(item,in); //将新资源放到buf[in]位置
in=(in+1)%10;
V(mutex);
V(items);
}
}
consumer{
while(true){
P(items); //等待缓冲区有资源可以使用
P(mutex); //保证在consume时不会有其他线程访问缓冲区
//consume
buf.pop(out); //将buf[out]位置的资源取走
out=(out+1)%10;
V(mutex);
V(space);
}
}
53.请用C#实现一个打乱扑克的算法
答:
static void Suffle()
{
int[] poke = new int[54];
for (int i = 0; i < poke.Length; i++)
{
poke[i] = i + 1;
}
int temp = 0;//用来存储取出来的值
int target = 0;//获取随机值
Random random = new Random();
for (int i = 0; i < poke.Length; i++)
{
target = random.Next(0, poke.Length);
temp = poke[i];
poke[i] = poke[target];
poke[target] = temp;
}
for (int i = 0; i < poke.Length; i++)
{
Console.WriteLine(i + ":" + poke[i]);
}
}
54.写一个Lua的“类” ,并实现类A,B 其中类B继承类A,提供new方法, 实现A,B类,并都实现类方法funName 打印对应类名
答:
--首先用lua实现类
Class = {x=1,y=1}
Class.__index = Class
function Class:New(x, y)
local t={}
setmetatable(t,Class)
t.x = x
t.y = y
return t
end
function Class:Add()
self.x = self.x + 1
self.y = self.y + 1
end
function Class:Log()
print("基类的x:"..self.x.."基类的y:"..self.y)
end
--实现继承
SubClass = {z=2}
setmetatable(SubClass,Class)
SubClass.__index = SubClass
function SubClass:New(x,y,z)
local t = {}
t = Class:New(x, y)
setmetatable(t, SubClass)
t.z = z
return t
end
function SubClass:Add() --重载
print("基类被覆盖了")
end
--实现多态
local tempa = Class:New(3,3)
tempa:Log()
tempa:Add()
tempa = SubClass:New(2,2,2)
tempa:Log()
tempa:Add()
55.内存的分配方式?
答:堆栈 和堆 托管堆
56.#include<file.h> 与#include “file.h”的区别?
答:
#include<file.h> 直接在标准库里查找file.h
#include "file.h" 编译器在源文件所在的目录(当前路径)中搜索file.h,如果找不到再从库里查找
57.面向对象的三个基本特征,并简单叙述
继承:建立一个新的派生类,可以继承父类的方法或属性,也可以扩展自己想要的内容。
封装:把客观的事物封装成抽象的类。
多态:同个基类的派生类实现有不同实现方式。
58.请填写,bool B float f 指针变量ptr 与 “零值”做等值比较的if 语句
If(B) if(!B)
Float f
const EPSINON=0.00001;
If(f=EPSINON)
if(ptr==NULL)
if(ptr!=NULL)
59.请计算以下结构的大小
Struct s1
{
Short d;
Int a;
Short b;
}a1
Struct s2 {
Short d;
Short b;
Int a;
}a2;
Siezof(a1):
Sizeof(a2):
12
8
61.下面代码如有问题,请指出修改
Void test2()
{
Char string[10],str1[10]
For(i=0;i<10;i++){
Str[1] =’a’;
}
Strcpy(string,st1);
}
在这里插入代码片
62.下面代码有什么问题,如果可以改进请修改
#define CALL_WITH_MAX(a,b) function((a)>(b) ?(a):(b))
Int a =5, b =0;
CALL_WITH_MAX(++a,b+10)
在这里插入代码片
63.下面两种写法比较其利弊,并说明有什么问题,可以怎么改进
Class R{…};
ConstR&funcA(int param1,int param2)
{
R r = new R(param1 , param2)
Return r;
}
R&funcB(int param1 , int param2){
R r = R(param1, param2)
Return r;
}
64.实现一个单例 写单例末班并写出使用例子。
Public class Singleton<T> :Monobehaviour where T: Singleton<T>{
public static T Instance { get; private set; }
private void Awake()
{
if (Instance == null)
{
Instance = (T)this;
DontDestroyOnLoad(Instance);
}
else
{
Destroy(gameObject);
}
}
void test(){debug.log(11)}
}
public calss testSingleton : Singleton<testSingleton>{
void start(){
testSingleton.Instance.test();
}
}
65.任意方法实现以下结构体的稳定排序,全部字段都考虑进去顺序自定义(尽量使用STL,如需要可往结构体加方法,容器自选vector,set map list 等任意 一种)
Struct player
{
String name;
Int level;
}
在这里插入代码片
66.一个学生的信息是:姓名,学号,性别,年龄等信息,用vector ,把这些学生信息组织起来,在此vector中删除学生年龄 age =10 的学生信息 (用STL代码实现)
在这里插入代码片
67.1.写个动物的基类,猫跟狗继承基类,重写基类的方法
public class Animal
{
public int age;
public string name;
public Animal() { }
public Animal(string name, int age)
{
this.age = age;
this.name = name;
}
public virtual void eat()
{
Debug.Log("正在吃东西");
}
public void Catch(string name)
{
Debug.Log(name+"在抓东西");
}
}
public class Cat : Animal
{
public Cat() { }
public Cat(string name, int age) : base(name, age)
{
}
public void eat(string name)
{
Debug.Log(name + "吃东西");
}
}
public class Dog : Animal
{
//public Cat() { }
public Dog(){}
public Dog(string name, int age) : base(name, age)
{
}
public override void eat()
{
Debug.Log("吃东西aa");
}
}
68.for(int i= 4;i>=1;i–){
print("")
for(int j = 1; j< 4 - i; j++){
print("")
}
print("\n")
}
输出的结果
*
*
**
***
69.猫捉老鼠的观察者模式
public class Cat:MonoBehaviour
{
public Action catCatch;
public string name;
public Cat(string name)
{
this.name = name;
}
public void Catch()
{
Debug.Log(name+"开始抓人");
if (catCatch != null)
{
catCatch();
}
}
}
public class Mouse:MonoBehaviour
{
public string name;
public Mouse(string name,Cat cat)
{
this.name = name;
cat.catCatch += RunAway;
}
private void RunAway()
{
Debug.Log(name+"正在逃跑");
}
}
70.实现一个任意一个排序算法除了 冒泡 我用lua写的快排
71.实现一个链表, 我用的是lua
72.十进制转换成二进制的算法
void GetTwo(int n)
{
int i;
int[] arr = new int[10];
for (i = 0; n > 0; i++)
{
arr[i] = n % 2;
n = n / 2;
}
for (i = i - 1; i >= 0; i--) {
Debug.Log(arr[i]);
}
}
74.lua实现斐波那锲数列
function getn(n)
if n==1 or n ==2 then
return 1
else
return getn(n-1)+getn(n-2)
end
end
75.C#的栈溢出 的实例
在这里插入代码片
76.__index __newindex rawget rawset的区别
__index:元方法 检索元表内是否含有某元素的值
__newindex:当对于一个表中不存在的索引赋值时会调用此元表中的方法
Rawget:直接获取元表中的某个值,不存在返回nil,并不调用__index方法
Rawset:往元表中添加值,不调用__newindex方法
78.重载和重写的区别
重载 表示 同方法名 参数列表和返回值列表不同
重写使用关键字override 参数列表和返回值方法名都相同
79.任意语言实现观察者模式(这个是说你熟悉的设计模式 我说 单例工厂 观察者)
观察者模式
**
一面:
**
1.C#的GC是什么?Lua的GC又是什么?
,
C#:垃圾回收机制,程序员只需要申请内存,而不需要关注内存的释放;GC会在适当的时候将已经中止生命周期的内存给释放掉;相比C/C++等简化了应用层的开发的复杂度,同时也降低了内存泄漏的风险。
Lua:通过特定算法的GC机制实现自动内存管理,因此程序员不需要关心对象的内存分配问题;不再使用的对象时,除了将引用的变量设为nil,不需要主动释放对象;Lua的GC不断运行去收集不再被Lua程序访问的对象。
2.协程是什么?和线程的区别是?你来实现会怎么做?
协程:即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态;
线程:多线程是阻塞式的,每个IO都必须开启一个新的线程,但是对于多个CPU的系统应该使用Thread,尤其是有大量数据运算的时刻,但是IO密集型就不适合;而且Thread中不能操作Unity的很多方法和Component;
进程、线程和协程:一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间运行。
void Start()
{
StartCoroutine(A());
}
IEnumerator A()
{
print(“Hello World!”);
yield return null;
}
3.工厂模式?
分类:简单工厂模式、工厂方法模式、抽象工厂模式,它们都属于设计模式中的创建型模式;
功能:用工厂方法代替new的操作,把对象的实例化部分抽取出来,目的是降低系统中代码耦合度,并且增强了系统的扩展性。
4.MVC?
是一种框架,是模型-视图-控制器的缩写,是一种软件设计典范;用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑;
优点:重用性高、生命周期成本低、部署快、可维护性高、有利于软件工程化管理;
缺点:没有明确的定义、不适合中小型规模的应用程序、增加系统结构和实现的复杂性、视图与控制器之间连接过于紧密、视图对模型数据的访问效率低、一般高级的界面工具或构造器不支持模式。
5.手写一个快排。
在这里插入代码片
6.Lua如何实现面向对象?
**使用空table模拟一个类。**
7.Lua元表是什么?有什么作用?
https://blog.csdn.net/banruoju/article/details/73730632
概念:本身就是一个table,最具体点说,就是用来存放元方法的table;
作用:修改一个值的行为(更确切地说,这是元方法的能力),需要注意的是,这种修改会覆盖掉原本该值可能存在的相应的预定义行为。
8.简单说一下UGUI的Canvas三种模式。
Screen Space-Overlay
Screen Space-Camera
World Space
第一种:Screen Space-Overlay(屏幕空间,覆盖模式)
第二种:Screen Space-Camera(屏幕空间,摄影机模式)
第三种:World-Space(世界空间模式)
1.Screen SpaceOverlay(屏幕空间覆盖模式)的画布会填满整个屏幕空间,并将画布下面的所有的UI元素置于屏幕的最上层
2.Screen Space-Camera画布也是填满整个屏幕空间,如果屏幕尺寸改变,画布也会自动改变尺寸来匹配屏幕。所不同的是,在该模式下,画布会被放置到摄影机前方。在这种渲染模式下,画布看起来绘制在一个与摄影机固定距离的平面上。所有的UI元素都由该摄影机渲染,因此摄影机的设置会影响到UI画面。
3.World Space即世界控件模式。在此模式下,画布被视为与场景中其他普通游戏对象性质相同的类似于一张面片(Plane)的游戏物体。画布的尺寸可以通过RectTransform所有的UI元素可能位于普通3D物体的前面或者后面显示。当UI为场景的一部分时,可以使用这个模式
9.Dictionary的插入时间复杂度?
在这里插入代码片
10.平衡二叉树的插入时间复杂度?
在这里插入代码片
12.Update、LateUpdate、和FixedUpdate的区别是什么?LateUpdate和FixedUpdate一般用于什么?为什么?
update:每帧执行时,调用次方法
fixedupdate:相对来说,固定帧执行,一般用于物理运动
lateupdate:在所有的update之后执行,一般用于摄像机的跟随主角视角,避免出现摄像机拍摄卡顿的效果。
13.装箱和拆箱是什么?为什么存在?
装箱:值类型转引用类型;
拆箱:引用类型转值类型;
为什么存在:C#被设计成完全面向对象的语言;对于CPU来说,处理一个完整的对象,需要很多的指令,对于内存来说,又需要很多的内存;如果连整数都是对象,那么效率自然很低,于是C#使用了一种机制,使得这些基本类型在一般的编程中被当做非对象的简单类型处理,在另一些场合,又允许被视作一个对象,这种机制就是装箱和拆箱。
装箱后的对象看上去和一个对象一样,拥有方法,可以被当作Object处理,拆箱后的变量,看上去又如同C语言中的那些变量、结构体一样,可以直接参与运算和处理。**
14.值类型和引用类型的区别?
值类型:在栈中分配空间,由系统自动开辟空间,自动释放;值类型相互赋值后,对两个变量的任何操作都不会相互影响,因为他们各自都有独立的存储空间,操作的是不同的数据;
引用类型:在栈中存储地址,在堆中存储数据和分配空间,需要用new手动开辟空间,自动释放;引用类型互相赋值后,他们共用一个空间的数据,会相互影响。
15.闭包是什么?C#如何实现闭包?
```csharp
闭包:内层函数可以引用外层函数的变量,即使外层函数执行已经终止,该变量的值并非创建时的值,而是在父函数范围内的最终值
如何实现:
Action bibao()
{
int a = 10;
return delegate ()
{
Debug.Log(a);
};
}
二面:
**1.100层的楼,2个鸡蛋,如何最快测出哪层楼扔鸡蛋不会碎?时间复杂度是多少?平均时间复杂度又是多少?
2.粒子特效如何显示在同一个Canvas下两个不同UI之间?
4.求一个int数组最大和的连续子序列。
5.如何判定一个点在弧形内?
6.仅仅只靠锚点和Canvas的渲染模式就能完美自适应吗?如何解决?
7.Lua中的UserData是什么?
8.Lua中的iparis与paris的区别是?
ipairs:会从下标为1开始查找,如果断开连续则停止遍历
pairs:遍历除nil外的所有元素
9.刘海屏如何做自适应?
10.老版本的Unity的GC是怎么样的?
11.Lua的闭包是如何实现的?**
lua中的闭包:子函数可以引用父函数中的局部变量,称之为闭包
function bibao()
local a =10
return function()
a =a +1
return a
end
1. U3D中用于记录节点空间几何信息的组件名称以及其父类的名称
Transform,Component
2. 简述prefab的用处
预置是一种资源类型——存储在项目视图中的一种可重复使用的游戏对象。预置可以多次放入到多个场景中。当你添加一个预置到场景中,就创建了它的一个实例。所有的预置实例链接到原始预置,基本上是它的克隆。不管你的项目存在多少实例,当你对预置进行任何更改,你将看到这些更改将应用于所有实例。
3. 请描述游戏动画有哪几种
关节动画、骨骼动画、单一网格模型动画(关键帧动画)
4. C#中的排序方式有哪些?请写出其中的一个从大到小的排序
选择排序,冒泡排序,快速排序,插入排序,希尔排序,归并排序
public static class QuickSort
{
public static void QuickSort(int[] arr, int low, int high)
{
int temp;
int i = low;
int j = high;
if (i < j)
{
temp = arr[i];
while (i < j && arr[j] >= temp) --j;
if (i < j)
{
arr[i] = arr[j];
++i;
}
while (i < j && arr[i] <= temp) ++i;
if (i < j)
{
arr[j] = arr[i];
–j;
}
}
QuickSort(arr, low, i - 1);
QuickSort(arr, i + 1, high);
}
5. Unity摄像机有几种工作方式,分别是什么?
两种,透视摄像机perspective,正交摄像机Orthographic
6. 将图片的TextureType选项分别选择“Texture”,”Sprite”有什么区别
Sprite作为UI精灵使用,Texture作用模型贴图使用
7. 使用unity3d实现2d游戏的方式有几种?请列举
1.使用本身的GUI
2.把摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴
3.使用2d插件,如:2DToolKit
8. Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期,请列举系统自带的几个重要的方法,如果脚本挂载的对象隐藏了的话生命周期是否会执行;
Awake():唤醒事件,游戏一开始运行就执行,只执行一次。
OnEnable():启用事件,只执行一次。当脚本组件被启用的时候执行一次。
Start():开始事件,执行一次。
FixedUpdate():固定更新事件,执行N次,0.02秒执行一次。所有物理组件相关的更新都在这个事件中处理。
Update():更新事件,执行N次,每帧执行一次。
LateUpdate():稍后更新事件,执行N次,在 Update() 事件执行完毕后再执行。
OnGUI():GUI渲染事件,执行N次,执行的次数是 Update() 事件的两倍。
OnDisable():禁用事件,执行一次。在 OnDestroy() 事件前执行。或者当该脚本组件被“禁用”后,也会触发该事件。
OnDestroy():销毁事件,执行一次。当脚本所挂载的游戏物体被销毁时执行。
不会执行
9. 如何优化内存?
1.压缩自带类库;
2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉;
3.释放AssetBundle占用的资源;
4.降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
5.使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。
6.代码中少产生临时变量
10. Unity提供了用于保存和读取数据的类(PlayerPrefs)请列举保存和读取整型数据的函数
PlayerPrefs.SetInt() ,PlayerPrefs.GetInt()
11. 射线检测的碰撞原理是什么?(请写个伪代码发射一条射线进行射线检测)
射线检测是由一个点向一个方向发射的一条线,在发射轨迹中与其他物体发生碰撞时,它将停止发射。
RayCastHit hit;
Ray ray = new Ray(transform.position,transform.forward);
If(Physic.RayCast(ray,out hit)){
Print(“碰撞检测成功”);
}
12. 请将一个二维数组元素行变列,列变行转90度
public static int[,] Change(int[,] arr)
{
int[,] brr = new int[arr.GetLength(1),arr.GetLength(0)];
for (int i = 0;i<arr.GetLength(0);i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
brr[j,i] = arr[i,j];
}
}
return brr;
}
13. 鼠标实现在场景中拖动物体(伪代码)
private void onm ouseDrag()
{
Vector3 a = transform.position - Camera.main.transform.position;
float b = Vector3.Dot(a, Camera.main.transform.forward);
transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, b));
}
工作中内存泄漏有没有遇见过?怎么跟踪内存泄漏的?你是怎么处理的?
按钮多次点击,生成图标对象并未回收 UWA GOT检测内存 unity中ctrl+7调用profiler跟踪内存
gc什么时候产生的?怎么处理
说说你是怎么性能优化的(我不知道问的是哪方面还是全部)
1.使用光照贴图
2.合批
3.合并网格
4.UGUI动静分离
5.打包图集
你会不会C++,C#和C++的区别
指针
lua热更实现的原理
C#这种编译型语言的修改需要重新编译生成一个Dll(动态链接库),而在手机端是无法进行编译的。所以每次更新需要重新下载一个安装包,这样玩家游戏体验很差。而用lua这门语言由于他的语言特性可以跨平台运行,只要手机端有一个lua虚拟机就可以直接运行lua代码。将修改后的代码直接加载进游戏就可以替代需要更新的部分。
对象池是什么,你项目中哪里使用过对象池?
对象池是一个保存需要频繁创建和销毁的游戏物体的工具。对象池将原本需要被销毁的游戏对象保存下来,在需要使用时候再取出来使用,这样减少了实例化物体所耗费的性能。比如子弹,下拉列表的重复利
冰川网络面试题
一、请回答下述基础相关问题
1、什么是泛型,泛型和传统类型的Boxing/Unboxing有什么区别,写一个泛型类C使其继承于Cbase
2、OnEnable、Awake、Start执行的先后顺序
3、请简述反射的用途,写一段代码动态加载一个程序集,从该程序集获取类型T,从类型T获得名为Create的静态方法,调用该静态方法
二、请回答下述资源相关的问题
4、Prefab的作用,如何获取prefab实例化出来的GameObject的预置类型,prefabInstance,ModelPrefabInstance等预置类型有什么不同
5、资源如何同构AssetBundle打包和加载
6、AssetDatabase.LoadAssetAtPath和Resource.Load分别适用于什么场合
三、请回答下述几何相关的问题
7、正交摄像机和透视摄像机的区别,第一人称摄像机Fov变化会产生怎样的摄像机效果
8、给定屏幕一个点(x,y)如何进行对场景中的GameObject进行射线拾取
9、拖尾效果中的带子采用Bezier曲线/Catmull-rom曲线的差异
四、请回答下述渲染相关的问题
10、HDR中动态范围压缩和Tone Mapping 原理
11、MeshRender和SkinnedMeshRender的关系与不同
12、写一段代码从上述Render获取材质并切换shade,并获取该Shader中某uniform constant值,每帧修改该constant值产生uv动画实现装备上流动的流光效果
13、发现贴图如何进行烘焙(Bake)
五、请回答下述动画相关的问题
14、IK和FK动画的区别
15、骨骼蒙皮的原理
16、Animator如何切换状态,Avatar的Generic和Humanoid分别适用于那些类型的Mesh
六、请回答下述碰撞相关的问题
17、Collider有哪几种类型,Convex用于哪类Collider,如何从MeshFilter的顶点数据计算特征向量进而得到OBB/胶囊
18、穿透和非穿透的碰撞检测的实现上有什么区别
19、举例说明如何检测某个技能中的子弹击中来人的哪个位置
七、请回答下述物理相关的问题
20、RigidBody的用途,Kinematic的RigidBody和普通的RigidBody的区别
21、如何计算RigidBody间反弹的弹力大小,该弹力大小和包围盒大小以及Mass之间的关系,并举例说明对场景进行破坏时如何给RigidBody施力或赋予冲量
22、披风等如何使用柔布系统实现
八、请回答下述协程相关的问题
23、协程的用途,协程和线程有什么区别
24、yield关键字什么时候适用,yield break/yield return 有什么区别
25、写一段代码说明协程在异步资源加载时如何和WWW组件使用
九、请回答下述性能有关的问题
26、Deep Profile和普通 Profile采集的分析数据有什么区别
27、如何对人物模型进行LOD,如何合并几个网格生成CombineMesh
28、对前向渲染和延迟渲染性能影响较大的因素分别有哪些
十、请结合你对ugui/ngui/Scaleform等认识回答下述ui相关的问题
29、如何让一个按钮响应用户的Touch操作,并添加对应的Touch事件处理代码
30、如何实现按钮的渐变缩放动画,请写一句语句实现该功能
31、如何生成图集,如何制作一个带关键帧动画的精灵
c#部分面试题:
1.简述 private、 protected、 public、internal 修饰符的访问权限。
private:只能在类的内部访问
Public:对类没有限制级别
Protected:只能在类的内部以及继承该类的类中访问
Internal:同一程序集都可以访问
2.override与重载的区别
Override:重写父类方法,参数列表和返回值类型必须与父类相同
重载:同类中方法名相同参数列表和返回列表不同
3.面向对象的特性?
抽象 继承 封装 多态
4.启动一个线程是用run()还是start()
Start()方法
5.接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可
继承实体类(concrete class)?
可以,可以,可以
6.构造函数是否可以被override?
不可以,重写是发生在继承上的,针对于方法名相同,子类和父类的构造函数名称是不同的
7.是否可以继承string类?
不可以,string类被sealed关键字修饰,不可被继承
8.Switch是否能作用在byte上,或者long上,或者string上?
可以作用在byte,string上,不能作用在long上面
9.当整数a赋值给一个object对象时,整数a将会被?
装箱
10.Public static const int A=1;这段代码有错误么?为什么?
const 修饰表示常量,不可被修改
static 修饰的变量表示静态字段,是可以被修改的,不能同时修饰同个变量
11.委托声明的关键字是?
delegate
12.结构和类的区别?
结构是值类型
类是引用类型
13.实现一个快速排序算法
14.描述一下C#中索引器的实现过程,是否只能根据数字进行索引。
定义索引 访问修饰符 数据类型 this[索引类型 index]{} ,主要作用是可以让类像数组一样来操作取值。
不是 索引类型可以是任意类型
15.什么是受管制的代码
unsafe,不经过clr运行
17.String s=new string(“xyz”);创建了几个string object?
2个 newstring xyz 为1个 指向s为1个
18.string 和stringbuilder 的区别
string 声明的字符串每次修改时都需要重新开辟一块空间来存储
stringbuilder则是在同个作用域上修改
19.什么是虚函数,什么是抽象函数
虚函数:virtual 关键字修饰的函数,父类函数需要被重写时可用次关键字修饰
抽象函数:abstract 关键字修饰的函数,表达该函数在被继承时一定要被实现
20.你都认识哪些数据结构?请举例说明这些数据结构的区别以及应用的场景?
链表
栈
队列
Lua笔试题
1.Lua基本数据类型有哪些,请列举?
number userdate function boolean table nil thread string
2.pairs 和 ipairs区别
pairs:遍历非nil外的所有元素
ipairs:从下标为1开始遍历表中的数组,如果断续则不再继续遍历。
3.lua怎么实现继承?
实现类
class ={x=1,y=2}
class.__index =class
function class:New(x,y)
local o={}
setmetatable(o,class)
o.x =x
o.y =y
return o
end
class : prints()
print(x..":".y)
end
实现继承
subclass = {z=2}
subclass.__index = subclass
setmetatable(subclass,class)
function subclass.New(x,y,z)
local o ={}
o = class:new(x,y)
setmetable(o,subclass)
o.z = z
return o
end
4.dofile 和require 的区别是什么?请指出相同点 和不同点
require 在加载一个文件时,会先在package.loaded里面查找该模块是否存在,如果存在,直接返回模块,如果不存在,则加载模块文件
dofile :读入代码文件并执行编译,每调用dofile一次,就会重新编译执行一次。
相同点,都会执行代码,require只执行一次,dofile每次调用都会执行一次
loadfile:将整个模块文件当成一个函数返回,但是不执行
5.5.Lua函数调用中“.”XXX.func()号和“:”xxx:func()有什么区别?
. 的需要加self .还可以用来表示类方法 类方法是静态的方法
:则表示默认传入self,不需要再加。:可以用来表示成员方法 ,是依附于对象的方法。
6.Lua编程中:
Local test=text1 … text2 …text3… text4
和
Local test=string.format(“%s%s%s%s”,text1,text2,text3,text4)
这两种写法哪个好?为什么?
.. ..连接字符串比string.format的速度更快,更节能 ..的连接原理为concat函数,不过使用多少次.. 他都只会执行一次 string.format 里面会有较多的循环执行。
7.Lua中如何判断一个表中的数据是否有序?
8.简述Lua中如何模拟类的概念实现,并说明元方法__index 和__newindex的作用
通过表的元方法,模拟实现类的行为特性
__index:元表中可以通过该元方法绑定一个函数或者表,表中没有找到对应索引时会调用元表绑定的函数或者在绑定的表中查找该索引的对应的值
__newindex:元表绑定该方法,当表对中不存在的索引赋值时,会调用该元方法,该元方法可绑定函数或者一个表。
9.现有变量t,通过执行’t={l,2}'初始化,当执行’t[‘a’]=some string here.时,简要描述变 量t相关内存变化情况。
10.简述Lua中闭包的作用,并使用闭包实现一个计数器 counter,要求每次调用counter(),输 出数字速增,写出关键歩骤即可。
让需要保存的数据一直保存在内存中,不会被GC清除
function bibao()
local count =0
return function()
count = count +1
return count
end
end
11.Unity如何实现热更?
使用热更框架,tolua xlua ulua等
12.做过热更新?有接触过ToLua吗? ToLua与XLua的区别?
xlua主要代码是c#写的,考虑需要用到热更新的地方采用lua编写,有可能需要热更新的代码前打上hotfix标签,lua脚本获取到对应的c#类,然后进行修改
tolua框架的思想是主逻辑都由lua代码编写,热更的时候直接进行修改就行了。
13.求下面二叉树的前序遍历,中序遍历的输出结果
前序遍历:根左右 6423517
中序遍历:左根右3246157
后序遍历:左右根3241756
已知中序遍历以及前序/后序遍历可以还原树
14.选择你熟悉的一门语言,或者使用伪代码,实现以下功能:
一个矩形Rectangle,包含左上角坐标(x1,y1),右下角坐标(x2,y2),width,height(宽,高)四个属性
(1)Bool intersect(Rectangle b)判断是否与矩形b相交
(2)Bool contains(Rectangle b)判断矩形b是否被包含在当前矩形中
可选:
(3)Rectangle Rotate(p,angle)将矩形按照点p旋转angle角度,并返回旋转后的矩形
15.求最大值的例子
function GetMax(t)
for k,v in ipairs(t) do
if max==nil then
max = v
end
if max<v then
max = v
end
end
return max
end
16.实现数字n的几次方
function GetN(t,n)
local sum
if(n==1) then
sum = t
else
sum = GetN(t,n-1)*t
end
return sum
end
17.实现阶乘
使用循环
function Getjc(n)
i =1
if n<1 then
return 1
else
repeat
i =n*i
n =n -1
until n==0
end
return i
end
递归
function GetJiecheng(n)
local sum
if n==1 then
sum =1
else
sum = GetJiecheng(n-1)*n
end
return sum
end
18.实现斐波那契数列
function GetN(n)
if n==1 or n==2 then
return 1
else
return GetN(n-1)+GetN(n-2)
end
end
19.输出三角形的形状
a=5
for i = 1, a, 1 do
for j = 1, a - i, 1 do
io.write(' ')
end
for k = 1, 2 * i - 1, 1 do
io.write(k)
end
print()
end
20.9*9乘法表
function GetNineNine()
for i =1,9,1 do
for j =1,i,1 do
io.write(i.."*"..j.."="..i*j)
io.write(' ')
end
print()
end
end
21.求平年闰年
function GetLunOrPing(t)
if(t%4==0 and t%400==0) then
print(t.."是闰年")
else
print("平年")
end
end
22.判断第一个整数是否是第二个整数的倍数
function Getzhengshu(t1,t2)
if(t1%t2==0) then
print("是倍数")
end
end
23.已知年份和月份,求这个月的天数
function GetDay(t,n)
local runyear={31,29,31,30,31,30,31,31,30,31,30,31}
local pingyear ={31,28,31,30,31,30,31,31,30,31,30,31}
local tempyear
if(t%4==0 and t%400==0) then
tempyear = runyear
else
tempyear = pingyear
end
for i,v in pairs(tempyear) do
if i==n then
print(v)
end
end
end
24.求1-100的奇数的和
function GetSumA()
local i =1
local sum = 0
while(true) do
if(i<100) then
sum = sum+i
i = i+2
else
break
end
end
print(sum)
end
25.使用while循环求式子2+22+222+2222+22222的和。p=p*10+2;
function GetSumB()
local i = 2
local sum =0
local count=0
while(true) do
sum = sum +i
i = i*10 +2
count =count+1
if(count>4) then
break
end
end
print(sum)
end
26.请编程验证一下“角谷猜想”:对任意的自然数,若是奇数,就对它乘以3加1;若是偶数就对它除以2;这样得到一个新数,再按上述奇数、偶数的计算规则进行计算,一直进行下去,最终将得到1。
function GetNew(t)
while(true) do
if t==1 then
print(t)
break
end
if t%2==0 then
t =t/2
else
t=t*3+1
end
end
end
27.dofile 和require的作用是什么?请指出相同点和不同点
require 会先在package.loaded里面查找是否存在该模块,如果存在,则直接返回,不存在,则再加载模块,他只会执行一次
dofile 读入文件并执行编译只要运行一次 就会重新执行一次
28.有以下代码片段保存在文件test.lua中;
…
local list ={{0}=1,2,3,4,nil,6}
For k,v in pairs(list) do print(v) end
For k,v in ipairs(list) do print(v) end
…
执行require ”test”后会输出什么?
会报错,没有{0}=1这种写法
29.简述Lua中如何模拟“类”的概念实现,并说明元方法_index 与_newindex的作用;
利用表的元方法来实现类的行为属性
class ={}
class.__index =class
class:New()
local o ={}
setmetatable(o,class)
return o
end
__index:从表中查找某个不存在的索引时会调用__index方法,__index可以执行一个函数或者绑定一个表,从该表中检索索引并返回
__newindex:从表中赋值不存在的字段,如果赋值的索引不存在则回调用__newindex元方法,__index可以执行一个函数,或者绑定一个表
30.Lua调试中,有哪些常用的函数?如何把函数的调用堆栈打印出来?
debug.traceback()
31.Lua编程中,有哪些可以提升性能的做法?
1.使用局部变量
2.
12.什么是短连接,什么是长连接?
长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持(不发生RST包和四次挥手)。
短连接, 通信双方需要发送数据包的时候,就建立tcp连接,数据传输完成后,就断开连接。
13.你用过哪些插件,请概述一下你的项目哪里用到,为什么用?
dotween:实现动画效果
easytouch:用来模拟虚拟摇杆的,实现人物在屏幕上移动释放技能等。
ngui:ui设计都是用ngui的。
14.Unity在移动设备上的一些优化资源的方法?
.使用assetbundle,实现资源分离和共享,将内存控制到200m之内,同时也可以实现资源的在线更新
2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右
3.只使用一盏动态光,不是用阴影,不使用光照探头
粒子系统是cpu上的大头
4.剪裁粒子系统
5.合并同时出现的粒子系统
6.自己实现轻量级的粒子系统
animator也是一个效率奇差的地方
7.把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下
8.animator出视野不更新
9.删除无意义的animator
10.animator的初始化很耗时(粒子上能不能尽量不用animator)
11.除主角外都不要跟骨骼运动apply root motion
12.绝对禁止掉那些不带刚体带包围盒的物体(static collider )运动
NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下
13每帧递归的计算finalalpha改为只有初始化和变动时计算
14去掉法线计算
15不要每帧计算viewsize 和windowsize
16filldrawcall时构建顶点缓存使用array.copy
17.代码剪裁:使用strip level ,使用.net2.0 subset
18.尽量减少smooth group
19.给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具
15.什么是drawCall?DrawCall高了会有什么影响?如何降低?
每次引擎准备数据并通知到GPU的过程称为一次drawcall
影响帧率
降低
使用lod,mipmap
静态批处理
动态批处理
合并网格单元
使用了纹理图集和共享材质的,可以用sharedmaterial代替material
16.unity中创建一个物体可以通过哪些方式?
1.GameObject go= new GameObject()
2.GameObject go
GameObject.Instantiate(go)
3.GameObject.CreatePrimitive(PrimitiveType.Cube)
17.GameObject跟Component分别是什么?他们之间有什么关系?
游戏对象,组件
组件是挂载在游戏对象上的。每个对象都默认包含一个transform组件
18.描述Transform跟RectTransform之间的联系和区别
rectTransform继承于transform ,rectTransform主要针对UI的,Transform主要针对非UI的
19.Unity中的Asset是什么?列出5中以上你熟知的Asset类型?
资源
贴图
模型
动作
音频文件
纹理贴图
材质
预制体
shader