小言_互联网的博客

Unity C# 面试重知识点

383人阅读  评论(0)

string和StringBuilder

***:stringstring 对象时恒定不变的,改变对象时需要分配新的存储空间 StringBuilder是直接再内存中改变他的值
String是字符串常量。
StringBuffer是字符串变量 ,线程安全。
StringBuilder是字符串变量,线程不安全。
String类型是个不可变的对象,当每次对String进行改变时都需要生成一个新的String对象,然后将指针指向一个新的对象,如果在一个循环里面,不断的改变一个对象,就要不断的生成新的对象,所以效率很低,建议在不断更改String对象的地方不要使用String类型。


Garbage Collector(垃圾收集器)


Heap(堆)内存经过回收、压缩之后,可以继续采用前面的heap内存分配方法,当内存达到一定程度,GC会自动进行垃圾的回收


AssetBundle


而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的
用AssetBundle.Load(同Resources.Load) 会从AssetBundle的内存镜像里读取并创建一个Asset对象
通过bundle的形式:即将资源打成 AssetBundle包 放在服务器或本地磁盘,然后使用WWW模块get 下来,然后从这个bundle中load某个object。
Resources的方式需要把所有资源全部打入安装包,这对游戏的分包发布(微端)和版本升级(patch)是不利的


动画


主要有 关节动画、骨骼动画、(关键帧动画(单一网格模型动画))。
关节动画:把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活,Quake2中使用这种动画;
骨骼动画,广泛应用的动画方式,集成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,(有关节相连,可做相对运动)),皮肤作为单一网格蒙在骨骼之外,决定角色的外观;
(关键帧动画(单一网格模型动画))由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,角色动画较真实


着色器Shader

是基于Lighting光照和materical材质结构的
实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的光照lighting,贴图Texture,材质Materical,颜色color等组合作用,然后输出。
Shader是一种基于Lighting(光照信息)以及Material configuration(材质的构造),包含了针对每个像素的颜色是如何渲染的算法的脚本,会涉及到比较多数学的计算。


表面着色器(fixed function shader)的抽象层次比较高,它可以轻松地以简洁方式实现复杂着色。表面着色器可同时在前向渲染及延迟渲染模式下正常工作。
顶点片段着色器(vertex shader)可以非常灵活地实现需要的效果,但是需要编写更多的代码,并且很难与Unity的渲染管线完美集成。
片段着色器(又叫固定功能管线着色器(Fragment Interpolation))可以作为前两种着色器的备用选择,当硬件无法运行那些酷炫Shader的时,还可以通过固定功能管线着色器来绘制出一些基本的内容。


堆和栈的区别


1、栈区(stack)— 由编译器自动分配释放,是一段连续的存储空间 ,存放函数的参数,局部变量的"值"等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放,不是一段连续的存储空。一般存放"引用类型",间, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表


值类型和引用类型的区别


***值类型:***(如 char、int 和 float)、枚举类型和结构类型。
引用类型: 包括类 (Class) 类型、接口类型、委托类型和数组类型。


数据存储


PlayerPrefs
Unity自带的临时存储函数
PlayerPrefs.setInt(), PlayerPrefs.getInt()
PlayerPrefs.setString() PlayerPrefs.getString()
PlayerPrefs.setFloat() PlayerPrefs.getFloat()

***List<>和ArrayList<>***都继承了IList接口,List是一个接口,而ArrayList是一个类,它实现了List接口。
List list=new List()这种写法是错误的,而ArrayList就可以被构造
而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
List<>泛型集合
List:需要声明类型 ,例如 list,所以是类型安全 的,省掉了装箱与拆箱 的过程,效率比ArrayList高 ,System.Collections命名空间
例1:List students=new List();//<>里面的Student是自己写的一个类
例2:List list = new List() { “name1”,“name2”};
//增 students.Add(T t);
//删 move(int index); stucents.Remove(T t);
//改 students[]=//修改的数据
//查或者改 遍历集合类似于遍历数组 ArrayList students=new ArrayList(); Student stu=students[0] as Student;

List list =new List(T是指的List中元素的类型)
for(int i=0;i<list.count;i++)
{
list[i]
}
这个是直接用下标操作,用Foreach有时候会更方便一些
foreach中可以用来取下标值:
List list = new List() { “name1”,“name2”};
foreach(string s in list)
{
int i=list.indexof(s);//i就是下标
}

ArrayList<> 非泛型集合
ArrayList只有一个参数Value值,没有Key值,命名空间System.Collections.Generic
所有加入的数据均为object,使用需要装箱与拆箱,存储的数据来动态扩充的,不需要指定大小
缺点:因为加入为object类型,需要装箱与拆箱,所以效率低。并且不安全
例:ArrayList list = new ArrayList();
//新增数据 list.Add(“abc”); list.Add(123);
//修改数据 list[0] = 345;
//移除数据 list.RemoveAt(0);
ArrayList list = new ArrayList();
//for遍历
for (int i = 0; i < list.Count; i++)
{
SE se = (SE)list[i];
Console.WriteLine(se.Name);
}
//foreach遍历
foreach (Object obj in list)
{
SE se = (SE)list[i];
Console.WriteLine(se.Name);
}

Direction<> 字典类型 泛型 不需要拆装箱
Add将指定的键和值添加到字典中。
Clear 从 Dictionary中移除所有的键和值。
ContainsKey确定 Dictionary是否包含指定的键。
ContainsValue确定 Dictionary是否包含特定值
Remove从 Dictionary中移除所指定的键的值。
System.Collections.Generic(程序集)
从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成
//遍历Values
1、创建及初始化
   Dictionary<int, string> myDictionary = new Dictionary<int, string>();
2、添加元素
   myDictionary.Add(“C#”,0);
   myDictionary.Add(“C++”,1);
   myDictionary.Add(“C”,2);
   myDictionary.Add(“VB”,2);
3、查找元素By Key
  if(myDictionary.ContainsKey(“C#”))
  {
    Console.WriteLine(“Key:{0},Value:{1}”, “C#”, myDictionary[“C#”]);
  }
4.遍历元素 By KeyValuePair
  foreach (KeyValuePair<string, int> kvp in myDictionary)
  {
    Console.WriteLine(“Key = {0}, Value = {1}”,kvp.Key, kvp.Value);
  }
5、仅遍历键 By Keys 属性
  Dictionary<string, int>.KeyCollection keyCol = myDictionary.Keys;
  foreach (string key in keyCol/string key in myDictionary.Keys/)
  {
    Console.WriteLine(“Key = {0}”, key);
  }
6、仅遍历值By Valus属性
  Dictionary<string, int>.ValueCollection valueCol = myDictionary.Values;
  foreach (int value in valueCol)
  {
    Console.WriteLine(“Value = {0}”, value);
  }
7.移除指定的键值By Remove方法
  myDictionary.Remove(“C#”);
  if (myDictionary.ContainsKey(“C#”))
  {
    Console.WriteLine(“Key:{0},Value:{1}”, “C#”, myDictionary[“C#”]);
  }
  else
  {
    Console.WriteLine(“不存在 Key : C#”);
}
foreach (SE se in list.Values)
{
//遍历时不需要类型转换
Console.WriteLine(se);
}
//同时遍历
foreach (KeyValuePair<string, SE> en in list)
{
Console.WriteLine(en.Key);
Console.WriteLine(en.Value.Name);
}
//KeyValuePair<TKey,TValue>是一个泛型结构

Hashtable 哈希表类型
Hashtable list = new Hashtable();

//Hashtable不能用索引访问,所以遍历一个Hashtable只能用foreache()方法

//遍历Key
foreach (Object obj in list.Keys)
{
Console.WriteLine((string)obj);
}
//遍历Value
foreach (Object obj in list.Values)
{
SE se = (SE)obj;
Console.WriteLine(se.Name);
}
//同时遍历,DictionaryEntry一个结构
foreach (DictionaryEntry en in list)
{
Console.WriteLine(se.Keys);
COnsole.WriteLine(((SE)en.Value).Name);
}


转载:https://blog.csdn.net/qq_42838904/article/details/102488169
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场