Unity3D面试题

原作者:胤醚貔貅
链接:https://www.jianshu.com/p/55bb80edfd83 原文点击这里跳转
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
搬运虽易,但整理不易,点个赞支持一下呗!~

1. [C#语言基础]请简述拆箱和装箱

答:
装箱操作:
值类型隐式转换为object类型或由此值类型实现的任何接口类型的过程。

1.在堆中开辟内存空间。

2.将值类型的数据复制到堆中。

3.返回堆中新分配对象的地址。

拆箱操作:

object类型显示转换为值类型或从接口类型到实现该接口值类型的过程。

1.判断给定类型是否是装箱时的类型。

2.返回已装箱实例中属于原值类型字段的地址。

2. [.NET(C#)] attribute,property,markup,tap翻译。

答:
attribute翻译成特性,用来标识类,方法 。

property翻译为属性,性质用于存取类的字段 。

markup翻译成标记。

tag翻译成标签。

3. [.NET(C#)] 程序集的重要特性。

答:程序集的一个重要特性是它们包含的元数据描述了对应代码中定义的类型和方法。

4. [.NET(C#)] ref与out关键字。

答:ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。

5. [.NET(C#)] new 关键字用法。

答:

  1. new 运算符 :用于创建对象和调用构造函数。

  2. new 修饰符 :用于向基类成员隐藏继承成员。

  3. new 约束 :用于在泛型声明中约束可能用作类型参数的参数的类型。

6. [.NET(C#)] C#中,string str = null 与 string str = “”,说明区别。

答:string str = “” 初始化对象分配空间。

string str = null 表示一个空引用,没有占用空间。//实际情况是,string为null时依然为"",但该题常考。

7. [.NET(C#)]什么是序列化?

答:序列化是将对象状态转换为可保持或传输的格式的过程。 与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

8. [.NET(C#)] sealed 修饰符有什么特点。

答:

  1. sealed 修饰符可以应用于类、实例方法和属性。密封类不能被继承。密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed 修饰符必须始终与 override一起使用。

  2. 将密封类用作基类或将 abstract 修饰符与密封类一起使用是错误的。

  3. 结构是隐式密封的;因此它们不能被继承。

9. [.NET(C#)] 详述.NET里class和struct的异同。

答:

相同点:

  1. 语法类似。

不同点:

  1. class是引用类型,继承自System.Object类; struct是值类型,继承自System.ValueType类,因此不具多态性。但是注意,System.ValueType是个引用类型。

  2. 从职能观点来看,class表现为行为; 而struct常用于存储数据。

  3. class支持继承,可以继承自类和接口; 而struct没有继承性,struct不能从class继承,也不能作为class的基类,但struct支持接口继承。

  4. 实例化时,class要使用new关键字; 而struct可以不使用new关键字,struct在声明时就进行了初始化过程,所有的成员变量均默认为0或null。

10. [.NET(C#)]如何选择结构还是类。

答:1) 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些。

  1. 结构表示如点、矩形和颜色这样的轻量对象。例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。

  2. 在表现抽象和多级别的对象层次时,类是最好的选择。

  3. 大多数情况下该类型只是一些数据时,结构时最佳的选择。

11. [.NET(C#)]抽象类(abstract class)和接口(interface)的区别。

答:

抽象类:

  1. 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法。

  2. 抽象类不能被实例化。

  3. 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类。

  4. 具体派生类必须覆盖基类的抽象方法。

  5. 抽象派生类可以覆盖基类的抽象方法,也可以不覆盖。如果不覆盖,则其具体派生类必须覆盖它们。

接口:

  1. 接口不能被实例化。

  2. 接口只能包含方法声明。

  3. 接口的成员包括方法、属性、索引器、事件。

  4. 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员。

  5. 接口中的所有成员默认为public,因此接口中不能有private修饰符。

  6. 派生类必须实现接口的所有成员。

  7. 一个类可以直接实现多个接口,接口之间用逗号隔开。

  8. 一个接口可以有多个父接口,实现该接口的类必须实现所有父接口中的所有成员。

抽象类和接口的异同:
相同点:

  1. 都可以被继承。

  2. 都不能被实例化。

  3. 都可以包含方法声明。

  4. 派生类必须实现未实现的方法。

区 别:

  1. 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。

  2. 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”。

  3. 接口可以被多重实现,抽象类只能被单一继承。

  4. 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中。

  5. 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性。

  6. 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法。

  7. 接口可以用于支持回调,而继承并不具备这个特点。

  8. 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的。

  9. 如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

12. [.NET(C#)]什么叫应用程序域?

答:

  1. 操作系统和运行库环境通常会在应用程序间提供某种形式的隔离。

  2. 应用程序域为安全性、可靠性、版本控制以及卸载程序集提供了隔离边界。

  3. 应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小。

13. [.NET(C#)]什么是强类型?

答:为所有变量指定数据类型称为“强类型”。C#是强类型语言。

14. [.NET(C#)]托管代码。

答:使用基于公共语言运行库的语言编译器开发的代码称为托管代码;托管代码具有许多优点,例如:跨语言集成、跨语言异常处理、增强的安全性、版本控制和部署支持、简化的组件交互模型、调试和分析服务等。

15. [.NET(C#)]什么是CTS?

答:CTS:通用系统类型 Common Type System。所有.NET语言共享这一类型系统,实现它们之间无缝的互操作。该方案还提供了语言之间的继承性。

16. [.NET(C#)]什么是CLR?

答:CLR:公共语言运行库 Common Language Runtime。是一个运行时环境,它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必要的分离。

17. [.NET(C#)]什么是CLS?

答:CLS:公共语言规范 Common Language Specification。可以保证C#组件与其他语言组件间的互操作性。

18. [.NET(C#)]什么是委托?

答:

  1. 委托是一种引用方法的类型。

  2. 委托类似于 C++ 函数指针,但它是类型安全的。

  3. 委托允许将方法作为参数进行传递。

  4. 委托可用于定义回调方法。

19. [.NET(C#)]活动目录的作用。

答:

  1. Active Directory存储了有关网络对象的信息,并且让管理员和用户能够轻松地查找和使用这些信息。

  2. Active Directory使用了一种结构化的数据存储方式,并以此作为基础对目录信息进行合乎逻辑的分层组织。

20. [.NET(C#)]在.NET中,配件的意思。

答:程序集(中间语言,源数据,资源,装配清单)。

21. [.NET(C#)]值类型和引用类型的区别。

答:

  1. 值类型通常被分配在栈上,它的变量直接包含变量的实例,使用效率比较高。

  2. 引用类型分配在托管堆上,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例。

  3. 一个是值COPY,一个是地址COPY。

  4. 内存回收:值类型使用完后,立即回收;引用类型使用完后,不是立即回收,等待GC回收。

22. [.NET(C#)].NET中的垃圾回收机制。

答:.NET Framework 的垃圾回收器管理应用程序的内存分配和释放。
每次使用 new运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来回收它们占用的内存。

23. [.NET(C#)]什么是索引器?如何使用索引器?

答:索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。可以用任意类型索引

  1. 索引器使得对象可按照与数组相似的方法进行索引。

  2. get 访问器返回值。set 访问器分配值。

  3. this 关键字用于定义索引器。

  4. value 关键字用于定义由 set 索引器分配的值。

  5. 索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。

  6. 索引器可被重载。

  7. 索引器可以有多个形参,例如当访问二维数组时。

24. [.NET(C#)]进程和线程的区别。

答:

  1. 进程是系统进行资源分配和调度的单位。

  2. 线程是CPU调度和分派的单位。

  3. 一个进程可以有多个线程,这些线程共享这个进程的资源。

25. [.NET(C#)]启动一个线程是用run()还是start()?

答:启动一个线程是调用start()方法,导致操作系统将当前实例的状态更改为ThreadState.Running。

26. [.NET(C#)]构造器Constructor是否可被override(重写)?

答:构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overloade

27. [.NET(C#)]静态成员和抽象类

答:静态成员override、virtual 或 abstract。

抽象类不能是密封的sealed或静态的static。

28. [.NET(C#)]在C#中using和new这两个关键字有什么意义。

答:
using 关键字有两个主要用途:

  1. 作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。

  2. 作为语句,用于定义一个范围,在此范围的末尾将释放对象。

new 关键字:新建实例或者隐藏父类方法

29. [.NET(C#)].NET的错误处理机制。

答:.NET错误处理机制采用try->catch->finally结构。 throw发生错误时,层层上抛,直到找到匹配的catch为止。

30. [.NET(C#)]error和exception有什么区别。

答:
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出,不可能指望程序能处理这样的情况。

exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

31. [.NET(C#)]UDP连接和TCP连接的异同。

答:

  1. TCP(Transmission Control Protocol)传输控制协议:一种面向连接的、可靠的、基于字节流的运输层通信协议,三次握手。

  2. UDP(User Datagram Protocol)用户数据报协议:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点。缺点是易丢失数据包。

32. [.NET(C#)]System.String 和System.StringBuilder有什么区别?

答:

  1. System.String是不可变的字符串。

  2. System.StringBuilder存放了一个可变的字符串,并提供一些对这个字符串修改的方法。

  3. String类在执行字符串拼接的操作上,用“+”会产生新的对象,占用内存。

  4. StringBuilder类只是修改字符串的内容,不建立新的对象。

33. [.NET(C#)]const和readonly有什么区别?

答:

  1. const 字段只能在该字段的声明中初始化。

  2. const 字段不允许在常数声明中使用 static 修饰符。

  3. readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。

  4. 另外,const 字段是编译时常数,而 readonly 字段可用于运行时常数。

34. [.NET(C#)]C#中的委托是什么?事件是不是一种委托?

答:

  1. 委托可以把一个方法作为参数代入另一个方法。

  2. 委托可以理解为指向一个函数的引用。

  3. 事件是一种特殊的委托。

35. [.NET(C#)]什么是受管制的代码?

答:在类型或成员的声明中使用 unsafe 修饰符。因此,类型或成员的整个正文范围均被视为不安全上下文,无法由 CLR 进行验证的代码。

36. [.NET(C#)]面向对象语言三大特性。

答:封装、继承、多态。

37. [.NET(C#)]能用foreach遍历访问的对象需要实现什么接口或声明什么方法的类型。

答:声明IEnumerable接口或实现GetEnumerator()方法。

38. [.NET(C#)]接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

答:接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。

39. [.NET(C#)]是否可以继承String类?

答:String类是sealed类故不可以继承。

40. [.NET(C#)]数组有没有length()这个方法? String有没有length()这个方法?

答:数组、String类都没有Length()方法,它们只有Length属性

41. [.NET(C#)]成员变量和成员函数前加static的作用。

答:即使没有创建类的实例,也可以调用该类中的静态方法、字段、属性或事件。如果创建了该类的任何实例,不能使用实例来访问静态成员。静态成员通常用于表示不会随对象状态而变化的数据或计算。

42. [.NET(C#)]什么是虚函数?什么是抽象函数?

答:1) 虚函数:没有实现的,可由子类继承并重写的函数。

  1. 抽象函数:规定其非虚子类必须实现的函数,必须被重写。

43. [.NET(C#)]C#中的三元运算符是?

答:? 和 : (问号和冒号)格式如下:ndition ? first_expression : second_expression

44. [.NET(C#)]当整数a赋值给一个object对象时,整数a将会被?

答:装箱。

45. [.NET(C#)]委托声明的关键字是?

答:delegate

46. [.NET(C#)]在.Net中所有可序列化的类都被标记为?

答:[Serializable]

47. [.NET(C#)]利用operator声明且仅声明了==,有什么错误么?

答:要同时修改Equale和GetHash() ? 重载了"==" 就必须重载 “!=”。

48. [智力题] 62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动?

答:62移动成2的6次方,2^6。

49. [.NET(C#)]C#可否对内存进行直接的操作?

答:可以使用指针。也就是非安全代码,就是不在 CLR 完全控制下执行的代码,它有可能会导致一些问题,因此他们必须用 “unsafe” 进行表明。

50. [.NET(C#)] &和&&的区别。

&是位运算符,表示按位与运算。

&&是逻辑运算符,表示逻辑与(and)

51. [.NET(C#)]重载的方法是否可以改变返回值的类型?

可以。

52. [.NET(C#)]如何把一个Array复制到ArrayList里?

  1. 实现1

    string[] s ={ “111”, “22222” };

    ArrayList list = new ArrayList();

    list.AddRange(s);

  2. 实现2

    string[] s ={ “111”, “22222” };

    ArrayList list = new ArrayList(s);

53. [.NET(C#)]什么是强名?

强名是由程序集的标识加上公钥和数字签名组成的,其中,程序集的标识包括简单文本名称、版本号和区域性信息(如果提供的话)。它使用对应的私钥从程序集文件中生成。(程序集文件包含程序集清单,其中包含组成程序集的所有文件的名称和哈希。)

54. [.NET(C#)]C#中几种循环的方法,并指出他们的不同:

  1. for:使用于确定次数的循环。

  2. foreach:使用于遍历的元素是只读的。//Unity中此处是个坑,建议不要用foreach

  3. while:次数不确定,条件随机变化。

  4. do…while:次数不确定,条件随机变化,但至少要保证能被执行一次。

55. [.NET(C#)]请简述一下用Socket进行同步通讯编程的详细步骤

  1. 在应用程序和远程设备中使用协议和网络地址初始化套接字。

  2. 在应用程序中通过指定端口和地址建立监听。

  3. 远程设备发出连接请求。

  4. 应用程序接受连接产生通信scoket。

  5. 应用程序和远程设备开始通讯(在通讯中应用程序将挂起直到通讯结束)。

  6. 通讯结束,关闭应用程序和远程设备的Socket回收资源。

56. [.NET(C#)] try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

答:会执行,在return前执行

57. [.NET(C#)] 写出程序的输出结果:

(我尽力挽救还原代码了,将就着看 跳过也行…)

public classA
{
	public virtual void Fun1(int i)
	{
		Console.WriteLine(i);
	}
	
	public void Fun2(classA a)
	{
		a.Fun1(1);
		Fun1(5);
	}
}

public classB : A
{
	public override void Fun1(int i)
	{
		base.Fun1(i + 1);
	}
}
public static void Main()
{
	classB b = new classB();
	classA a = new classA();

	a.Fun2(b);
	b.Fun2(a);
}


答案:
2
5
1
6

58. [.NET(C#)]求以下表达式的值,写出您想到的一种或几种实现方法:1 - 2 + 3 - 4 +…+ m

(找到规律就好办了,奇数加,偶数减,又是抢救代码的一天…原文排版真滴不行)
答案:

public static void Main()
{
	intinput = int.Parse(Console.ReadLine());
	intsum = 0;
	for(inti =0; i <= input; i++)
	{
		if((i % 2) == 1)
		{
			sum += i;
		}
		else
		{
			sum = sum - i;
		}
	}
	Console.WriteLine(sum);
}

59. [.NET(C#)]两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

答:不对,有相同的hash code。

60. [.NET(C#)] swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

答案:可以作用在byte和long上,也可以作用在string上。

61. [.NET(C#)] short s1 = 1; s1 = s1 + 1;有什么错?short s1 = 1; s1 += 1;有什么错?

答:

  1. short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能隐式转化为short型。可修改为s1 =(short)(s1 + 1) 。

  2. short s1 = 1; s1 += 1正确。

62. [.NET(C#)] 字符串处理问题

题目: 需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个。
答案:
string inputStr = " xx xx “;
inputStr = Regex.Replace( inputStr.Trim(), @”/s+", " " );

63. [.NET(C#)]下面这段代码输出什么?为什么?

int i = 5;
int j = 5;
if Object.ReferenceEquals(i, j))
{
	Console.WriteLine("Equal");
}
else
{
	Console.WriteLine("Not Equal");
}

答案:Not Equal。因为比较的是对象

64. [.NET(C#)] public static const int A=1;这段代码有错误么?是什么?

答:const不能用static修饰。

65. [.NET(C#)]下面的代码中有什么错误吗?

class A
{
	public virtual void F()
	{
		Console.WriteLine("A.F");
	}
}

abstract class B : A
{
	public abstract override void F();//abstract与override关键字可以同时使用
}

(考查:abstract与override关键字可以同时使用)
答案: 没有错误!可以通过编译器。
注意: 网上有资料说abstract与override关键字不可以同时使用,这种说法是错误的 !

66. [.NET(C#)] 以下是一些C#中的枚举型的定义,其中错误的用法有?

A. public enum var1{ Mike = 100, Nike = 102, Jike }

B. public enum var1{ Mike = “1”, Nike, Jike }

C. public enum var1{ Mike=-1 , Nike, Jike }

D. public enum var1{ Mike , Nike , Jike }

答案 B

70. [C#语言基础]简述string与StringBuilder相比的优点。

答:
string的字符串为常量不可修改。

  1. 可以满足字符串常量池的需要。即对于创建相同文本时,string为同一对象。

  2. 允许string对象缓存HashCode。字符串不变形保证了hash码的唯一性。

  3. 安全性,string被许多的类库用来当做参数。

StringBuilder实际是一个char类型的集合,完成了组装拼接等工作。
String更适合做程序的参数,StringBuilder用于做String类型的组装。

71. [C#语言基础]C#StringBuilder类型比string类型的优势是什么?

答:
StringBuilder的优势在于拼接字符串。
//String的优势在于对字符串做一些处理,在使用过程中看具体的需求。

72. [C#语言基础]编写程序判断整数46234的每位相加和。

答:

int number = 46234;
string strNumber = number.ToString();
int length = strNumber.Length;

//方法1:
int result=0;
for (int i = 0; i < length; i++)
{
	result += number % 10;
	number /= 10;
}
//方法2:
for (int i = 0; i < length; i++)
{
	result += number / (int)Math.Pow(10, i) % 10;
}
//方法3:
for (int i = 0; i < strNumber.Length; i++)
{
	result += int.Parse(strNumber[i].ToString());
}

74. [C#语言基础] [值类型引用类型] 以下代码输出结果是什么?原因是什么?

object o1 = 1;
object o2 = o1;
o1 = 2;
Console.WriteLine(o2);

答:1;原因:o1将数据1在堆中引用赋值给o2,而后又将引用指向数据2,故o2仍指向数据1的引用。

75. [C#语言基础]请写出定义方法的语法。

答:
[访问修饰符][可选修饰符] 返回类型 方法名称(参数列表)
{
方法体;
return 结果;
}

76. [C#语言基础]请简述string字符串不可变性的原因?

答:

在很多语言当中如Java\C#中字符串string被设计成具有不可变性的。从系统优化方面考虑这样的设计好处主要由三点。

首先,它允许在一个字符串上执行各种操作,而不实际地更改字符串。

字符串不可变,还因为这在操作或访问一个字符串时不会发成线程同步问题。

除此之外,CLR可通过一个String对象共享多个完全一致的String内容。这样能减少系统中的字符串数量,者正是字符串留用技术的目的。

1.字符串常量池的需要。字符串常量池是内存堆中一个特殊的存储区域,当创建一个string对象时,假设此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。

2.允许string对象缓存HashCode。字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存,这是一种性能优化手段,因为这不必每次都去计算新的哈希码。

3.安全性。string被许多的类库用来当做参数,例如网络连接URL,文件路径Path,还有反射机制所需要的String参数等,假若string可变的,将会引起各种安全隐患。

综上,string不可变的原因包括设计考虑,效率优化问题,以及安全性三大方面。

另:在C++中string类型是可变的。

77. [C#语言基础]请简述方法重载OverLoad?

答:方法名称相同,但参数列表不同称为方法重载。用于在不同条件下解决同一类型的问题。
注意:单单返回值不同不能称之为重载!

80. [C#语言基础]在类的构造函数前加上static会报什么错?为什么?

答:
静态函数没有访问修饰符,其他C#代码从来不调用它,但在加载类时,总是由.NET运行库调用它,所以像public或private这样的访问修饰符就没有任何意义。
出于同样原因,静态构造函数不能带任何参数,一个类也只能有一个静态构造函数。静态构造函数只能访问类的静态成员,不能访问类的实例成员。

也就是说只加static不会报错,加了static再加了别的就会报错。

81. [C#语言基础]C#函数Func(string a,string b)用Lambda表达式怎么写?

答:(a,b)=>{}

注:该题有两种错误可能:

一种是方法没有些返回值即Func(string a,string b)为 void Func(string a,string b)此时,Lambda表达式可写作(a,b)=>{}

一种是Func为Func此时Lambda可写作a=>b//a,b为string类型

82. [C#语言基础]数列1,1,2,3,5,8,13…第n为数是多少?用C#递归算法实现。答:

public static int Fibonacci(int num)//Fibonacci
{
	return (num == 0 || num == 1) ? 1 : (Fibonacci(num-2)+Fibonacci(num-1));
}

注:计算斐波那契数列依据数列定义来建立方法是不推荐的写法。因为此时计算第n位的数的时间复杂度为O((3/2)n)。相比较而言,利用循环可以将时间复杂度缩小到O(n)该方法较为实用,而且实现简单,在没有特殊要求的情况下属于建议的写法。另一种优化的写法可以将时间复杂度优化到O(logn),实现代码较复杂,且隐含的时间常数较大。但适合面试者展示其知识面和代码实现的能力。

写法二:

public long Fibonacci2(int num)
{
	int result[2] = {0, 1};
	if(num < 2)
	return result[num];
	
	long fibOne = 1;
	long fibTwo = 0;
	long fibN = 0;
	for(int i = 2;i <= num; i++)
	{
		fibN = fibOne + fibTwo;
		fibTwo = fibOne;
		fibOne = fibN;
	}
	return fibN;
}

83. [C#语言基础]请简述值类型和引用类型的区别。

答:
从概念上区分,值类型时直接存储其值,而引用类型是存储对值的引用。
实际中,对于值类型的对象,初始化一个实例,该实例代表的是其内部存储的数据本身。而引用类型的对象,初始化一个实例,该实例代表的是其初始化数据在内存当中的引用。

值类型隐式继承自System.ValueType.该类为抽象类,只能序列化,不能被显式继承。

值类型:枚举,结构

引用类型:数组,委托,类,接口

84. [C#语言基础]请简述ArrayList和List<>的主要区别

答:
ArrayList是非泛型列表,存储数据是把所有的数据都当成object类型数据,存在装箱问题,取出来使用的时候存在拆箱问题,装箱拆箱会使性能变差,而且存在数据安全问题,但是优点在于可以让值类型和引用类型相互转换。

List是泛型列表,在使用的时候才会去定义数据类型,泛型避免了拆装箱的问题,存入读取熟读较快,类型也更安全。

85. [C#语言基础]请简述GC(垃圾回收)产生的原因,并描述如何避免?

解析:首先,这道题的描述是不严谨的,GC作为CLR的一种机制是由系统调用的,只要运行与CLR上的托管代码GC的工作本身是不可避免的。

但是抛开这些细节不谈,我可以在这里写把我认为这道题可能涉及到的东西写一下。

如果只把GC理解成一种可以自动释放内存的方式,使程序员省去了手动释放内存的烦恼,或试图引用已释放的内存空间的错误,这无疑是片面的,虽然这的确是GC非常重要的功能。但GC的作用远不如此。

GC的产生是与CLR堆内存特殊的分配方式有关的。CLR要求所有的资源都从托管堆分配,托管堆有一个指针NextObjPtr它的初始为保留地址空间的基地址。NextObjPtr指向下一个对象在堆中的分配位置。每当添加一个对象,NextObjPtr指针的值就会加上对象占据的字节数。这样做有两个好处:

首先,在许多应用程序中,差不多同时分配的对象彼此间有较强的联系,而且经常差不多在同一时间访问。在垃圾回收环境中,如果对象在内存中连续分配,会由于引用的本地性而获得性能上的提升。具体地说,这意味着进程的工作集小于非托管环境中运行相似的应用程序。

另一方面,这意味着代码使用的对象可以全部驻留在CPU的缓存中,加快CPU对这些对象的访问速度。

但托管堆具有这些好处,是因为它做了一个相当大胆的假设,地址的空间和存储是无限的。那么如何让它由假设变为可实现的,这就是GC垃圾回收的工作。

GC的垃圾回收算法是基于世代法和启发式算法的。

世代法是指将堆分为0代,1代,2代。每当0代的堆满时就触发一次垃圾回收。当第0代的的内存并没被释放,就会被提升到1代,如果1代在被回收时仍然保留的内存,就会被提升到2代。这样压缩空间的的方法保证了堆内存的连续性,增加了访问对象的速度。而启发式算法是指在基于应用程序对新建对象的模式,进行启发式的对第1代,第2代堆进行释放,或扩大第0代的堆空间。

建议只有在以下两种情况下才调用Dispose或Close:确定必须清理资源;或者确定可以安全地调用Dispose或Close,并希望将对象从中介列表中删除,禁止对象提升(到另一代)从而提高性能。

那么避免因为GC过程而影响性能的编程方法如下:

因为GC的目标引用地址都是存在栈上的,所以尽量不要用太深的栈,比如递归。

合理的使用new避免不必要的对象新建次数。

不要一次性大量申请内存。

对运行时string对象尽量不要使用+来构建,而要用StringBuilder

86. [C#语言基础]请描述Interface接口与abstract抽象类之间的不同。

答:

语法不同:

1.抽象类中可以有字段,接口没有。

2.抽象类中可以有实现成员,接口只能包含抽象成员。

3.抽象类中所有成员修饰符都可以使用,接口中所有的成员都是对外的,所以不需要修饰符修饰。

用法不同:

1.抽象类是概念的抽象,接口关注与行为。

2.抽象类的子类与父类的关系是泛化关系,耦合度较高,而实现类和接口之间是实现关系,耦合度比泛化低。

3.一个类只能继承自一个类,但是可以实现多个接口。

87. [C#语言基础]下列代码在运行时会产生几个临时对象?

string a="abc";//1个对象
a=(a.ToUpper()+"123").Substring(0,2);

答:
三个临时对象

注:
string a=“abc”;//1个对象
a=(a.ToUpper()+“123”).Substring(0,2);
a.ToUpper()//1个临时对象
“123”//1个临时对象
a.ToUpper()+“123”//1临时个对象

.Substring(0,2)//1个对象由于它将引用赋给了a所以它不是临时对象
在语句运行时结束后不存在引用的对象。

88. [C#语言基础]下列代码在运行中会发生什么问题?如何避免?

List Is = new List(new int[]{1,2,3,4,5});
foreach(int item in Is)
{
	Console.WriteLine(item * item);
	Is.Remove(item);
}

答:会产生运行时错误,抛出一个InvalidOperationException异常,因为foreach是只读的。不能一边遍历一边修改。 使用foreach时候不要对内容进行修改。

89. [C#语言基础]请简述关键字Sealed用在类声明和函数(方法)声明时的作用?

答:sealed访问修饰符用于类时,表示该类不能被继承;对于方法表示不能重写该方法。当应用于方法或属性时,sealed 修饰符必须始终与 override 一起使用。

若要确定是否密封类、方法或属性,通常应考虑以下两点:

  1. 派生类利用自定义类的功能所获得的可能好处。
  2. 派生类在修改类之后导致其无法正常工作或按预期工作的可能性。

90. [C#语言基础]请简述private,public,protected,internal的区别?

答:
public:对任何类和成员都公开,无限制访问

private:仅对该类公开

protected:对该类和其他派生类公开

internal:只能在包含该类的程序集中访问该类

91. [C#语言基础]反射的实现原理?

答:审查元数据并收集关于它的类型信息的能力。

注:
公共语言运行时程序管理应用程序域,应用程序域构成具有相同应用程序范围的对象周围定义的边界。 此管理包括将每个程序集加载到相应的应用程序域中和控制每个程序集内的类型层次结构的内存布局。

程序集包含模块、模块包含类型,而类型包含成员。 反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

Reflection,中文翻译为反射。

这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:

Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。

Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。

MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。

诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。

92. [C#语言基础].NET与Mono的关系?

答:MONO是.NET的一个开源跨平台工具。.NET只能在Windows下运行,Mono可以实现跨平台,可以运行与Linux,Unix,Mac OS等。

93. [面对对象]请说出4中面向对象的设计原则,并分别简述它们的含义。

答:
1)单一职责原则:一个类,最好只做一件事,只有一个引起它的变化。

2)开放-封闭原则:对于扩展是开放的,对于更改是封闭的。

3)里氏替换原则:子类必须能够替换其基类。

4)依赖倒置原则:设计应该依赖于抽象而不是具体实现。

A.高层模块不应该依赖底层模块,两个都应该依赖抽象。

B.抽象不应该依赖细节,细节应该依赖抽象(要对抽象编程,不要对实现编程。)

5)接口隔离原则:使用多个小的专门的接口而不要使用一个大的总接口。

6)迪米特法则:如果两个类不彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

7)合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用类继承。

94. [C#语言基础]Hashtable是无序的吗?

答:电脑没有绝对的无序,hashtable是通过哈希码让开发者感觉无序。
注:这里的无序是指集合的添加顺序与其输出顺序无关。Hashtable是通过哈希码或哈希函数,对其内部元素进行排列的,所以其元素的添加顺序与其输出顺序无关。

95. [设计模式]请描述你所了解的设计模式,并说明在你的项目中哪里使用过?

答:
单例: 对象池,游戏管理器, 抽象工厂

状态:有限状态机,

桥接:有限状态机

策略:AI自动行为操控中每种操控算法的独例

注:扩展补充。

创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。

96. [数据结构]说出你所了解的数据结构,并说明它们的特点。

答:

  1. 列表
    特点:有序,内存空间连续,读取速度快,大小可变,通过位置索引取元素.
    缺点:输入,删除的速度慢
    类库已实现:List、ArrayList

  2. 字典:
    特点:键值对的集合,通过键查找值,查找方便,无序
    类库已实现:Dictionary、Hashtable

  3. :
    特点:后进前出 LIFO(Last In First Out)
    支持操作:入栈,出栈,读栈顶,
    类库已实现:Stack、Stack

  4. 队列:
    特点:前进前出 FIFO(First In First Out)
    支持操作:入队,出队,读队首
    类库已实现:Queue、Queue

  5. 链表:
    特点:节点内存空间不连续,插入,删除速度快,读取速度慢.
    类库已实现:LinkedList

  6. 数组
    特点:内存空间连续,长度固定,读取速度快
    类库已实现:Array


  7. 特点:可以将对象组织为层次结构,
    实现:可使用设计模式中的组合模式实现树结构

97. [C#语言基础]Override 与 Overload的区别。

答:
Override:是指方法的重写,C#中可重写abstract、vritual 、override三类方法,重写是子类重写父类的以上三种方法,是动态绑定的,调用速度比方法隐藏慢,但灵活性好,重写本质是对方法表的修改

Overload:是指方法的重载,一个类中的多个同名方法,参数列表不同,主要指参数个数或类型不同,重载的目的是为了让实现相似功能的方法用一个名称表示,方便程序员编写和理解代码。可读性好。

重写和重载都是多态的一种体现

98. [C#语言基础]对比数组与集合。

答:
数组:长度固定,大小不变,存储空间连续,读取速度快,插入,删除速度慢。
集合:长度不定,大小可变,存储空间可能不连续,适合存放不确定数量的数据。

99. [C#语言基础]假如有一个Person类,包含姓名,年龄字段,如对Person数组按年龄升序排列,也可以按姓名升序排列,将来可以会有更多的排序方式,你该怎么实现,说出思路。

答:

方法一:实现IComparer, 使用Array.Sort(Array, IComparer )

方法二:使用OrderBy或OrderByDescending 方法加Lambda表达式

如:arr = arr.OrderBy(p=>p.age).ToArray();

Uinty笔试题

100. [UI]NGUI Button怎样接受用户点击并调用函数,具体方法名称是什么?

答: 在按钮上绑定一个带有OnClick事件List;

EventDelegate();

EventDelegate(Callback call);//void Callback()

EventDelegate(MonoBehaviour target,string methodName)

[Unity] Unity在PC端播放视频注意的问题是什么?

答:必须安装QuickTime播放器,不支持FLV视频格式。

102. [Unity]PC端播放视频是与哪一个类有关?

答:MovieTexture。

103. [Unity]通过Unity持久化存储PlayerPrefs,如何实现存储以及获取一个整数数据。

答:
存储:PlayerPrefs.SetInt(“MyKey”, 1);
获取:int myKey = PlayerPrefs.GetInt(“MyKey”);

104. [Unity]通过Unity持久化存储PlayerPrefs,如何删除数据。

答:
PlayerPrefs.DeleteKey(“MyKey”);
PlayerPrefs.DeleteAll();

105. [Unity]一个角色要用到unity中寻路系统,应该添加哪个组件?

答:NavMeshAgent。

106. [Unity]NavMeshObstacle组件的作用?

答:寻路网格动态碰撞组件,用于运动的物体阻碍寻路物体效果。

107. [Unity]射线中RaycastHit代表什么?

答:射线碰到的碰撞信息

108. [Unity]通过什么可以区分射线碰到的游戏对象?

答:通过LayerMask(层的遮罩),RaycastHit返回的碰撞的标签。

109. [动画系统]角色的AnimationType中(Generic,Legacy ,Humanoid),哪个动画样式可应用在Mecanim动画系统。

答:Generic Humanoid类人样式。

110. [动画系统]Unity支持几种动画?

  1. 关键帧动画
  2. 默认骨骼动画(人型)
  3. CAT

搬运虽易,但整理不易,点个赞支持一下呗!~

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值