Unity面试题——C#语言

简介: Unity面试题——C#语言

1. 重载和重写的区别

  1. 所处位置不同 重载在同类中 重写在父子类中
  2. 定义方式不同 重载方法名相同 参数列表不同 重写方法名和参数列表都相同
  3. 调用方式不同 重载使用相同对象以不同参数调用 重写用不同对象以相同参数调用
  4. 多态时机不同 重载时编译时多态 重写是运行时多态

2. 面向对象的三大特点

封装、继承、多态 :

1.继承: 提高代码重用度,增强软件可维护性的重要手段,符合开闭原则。

2.封装: 封装是将数据和行为相结合,通过行为约束代码修改数据的程度,增强数据的安全性,属性 是 C#封装实现的最好体现。

3.多态性: 多态性是指同名的方法在不同环境下,自适应的反应出不同得表现,是方法动态展示的重要手段。

3. 简述值类型和引用类型有什么区别

1.值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的 是堆中存放的地址。

2.值类型存取快,引用类型存取慢。

3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。

4.栈的内存是自动释放的,堆内存是.NET 中会由 GC 来自动释放。

5.值类型继承自 System.ValueType,引用类型继承自 System.Object。

4. 请简述 private,public,protected,internal 的区别

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

private:仅对该类公开

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

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

protected internal:protected + internal

5. C#中所有引用类型的基类是什么

引用类型的基类是 System.Object 值类型的基类是 System.ValueType 同时,值类型也隐式继承自 System.Object

6. 请简述 ArrayList 和 List的主要区别

1.ArrayList 不带泛型 数据类型丢失

2.List 带泛型 数据类型不丢失

3.ArrayList 需要装箱拆箱 List不需要

7. 请简述 GC(垃圾回收)产生的原因,并描述如何避免?

GC 为了避免内存溢出而产生的回收机制

避免:1)减少 new 产生对象的次数

2)使用公用的对象(静态成员)

3)将 String 换为 StringBuilder

8. 请描述 Interface 与抽象类之间的不同

1.接口不是类 不能实例化 抽象类可以间接实例化

2.接口是完全抽象 抽象类为部分抽象

3.接口可以多继承 抽象类是单继承

9. 下列代码在运行中会产生几个临时对象?

其实在 C#中第一行是会出错的(Java 中倒是可行)。应该这样初始化:

string b = new string(new char[]{'a','b','c'});

忽略错误的话:

1."abc"
2.a.ToUpper()
3."123"
4.a.ToUpper()+"123"

10.下列代码在运行中会发生什么问题?如何避免?

会产生运行时错误,因为 foreach 是只读的。不能一边遍历一边修改。

11.请简述关键字 Sealed 用在类声明和函数声明时的作用

类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。

12.反射的实现原理?

可以在加载程序运行时,动态获取和加载程序集,并且可以获取到程序集的信息 反射即在运行期动态获取类、对象、方法、对象数据等的一种重要手段

主要使用的类库:System.Reflection

核心类:

1.Assembly 描述了程序集

2.Type 描述了类这种类型

3.ConstructorInfo 描述了构造函数

4.MethodInfo 描述了所有的方法

5.FieldInfo 描述了类的字段

6.PropertyInfo 描述类的属性

通过以上核心类可在运行时动态获取程序集中的类,并执行类构造产生类对象,动态获取对象的字段 或属性值,更可以动态执行类方法和实例方法等。

13. .Net 与 Mono 的关系?

.Net 是一个语言平台,Mono 为.Net 提供集成开发环境,集成并实现了.NET 的编译器、CLR 和基础类 库,使得.Net 既可以运行在 windows 也可以运行于 linux,Unix,Mac OS 等。

14.在类的构造函数前加上 static 会报什么错?为什么?

构造函数格式为 public+类名如果加上 static 会报错(静态构造函数不能有访问修饰符)

原因:静态构造函数不允许访问修饰符,也不接受任何参数;无论创建多少类型的对象,静态构造函 数只执行一次;运行库创建类实例或者首次访问静态成员之前,运行库调用静态构造函数;静态构造 函数执行先于任何实例级别的构造函数;显然也就无法使用 this 和 base 来调用构造函数。

15.C# String 类型比 stringBuilder 类型的优势是什么?

如果是处理字符串的话,用 string 中的方法每次都需要创建一个新的字符串对象并且分配新的内存地 址,而 stringBuilder 是在原来的内存里对字符串进行修改,所以在字符串处理 方面还是建议用 stringBuilder 这样比较节约内存。但是 string 类的方法和功能仍然还是比 stringBuilder 类要强。

string 类由于具有不可变性(即对一个 string 对象进行任何更改时,其实都是创建另外一个 string 类的 对象),所以当需要频繁的对一个 string 类对象进行更改的时候,建议使用 StringBuilder 类, StringBuilder 类的原理是首先在内存中开辟一定大小的内存空间,当对此 StringBuilder 类对象进行更改 时, 如果内存空间大小不够, 会对此内存空间进行扩充,而不是重新创建一个对象,这样如果对一个 字符串对象进行频繁操作的时候,不会造成过多的内存浪费,其实本质上并没有很大区别,都是用来 存储和操作字符串的,唯一的区别就在于性能上。String 主要用于公共 API,通用性好、用途广泛、读取性能高、占用内存小。 StringBuilder 主要用于拼接 String,修改性能好。 不过现在的编译器已经把 String 的 + 操作优化成 StringBuilder 了, 所以一般用 String 就可以了 String 是不可变的,所以天然线程同步。 StringBuilder 可变,非线程同步。

16.C# 函数 Func(string a, string b)用 Lambda 表达式怎么写?

(a,b) => {};

17.数列 1,1,2,3,5,8,13...第 n 位数是多少?用 C#递归算法实现

public int CountNumber(int num) {
if (num == 1 || num == 2) {
return 1;
} else { return CountNumber(num -1) + CountNumber(num-2);
}
}

18.冒泡排序(手写代码)

public static void BubblingSort(int[]array) {
for (int i = 0; i < array.Length; i++){
for (int j = array.Length - 1; j > 0; j--){
if (array[j] < array[i]) {
int temp = array[j];
array[j] = array[j-1];
array[j - 1] = temp;
} } } }

19.C#中有哪些常用的容器类,各有什么特点。

List,HashTable,Dictionary,Stack,Queue

List:索引泛型容器 访问速度快 修改速度慢

HashTable/Dictionary:散列表格式 查询效率高 空间占用较大

Stack:后进先出

Queue: 先进先出

20.C#中常规容器和泛型容器有什么区别,哪种效率高?

不带泛型的容器需要装箱和拆箱操作 速度慢 所以泛型容器效率更高 数据类型更安全

21.有哪些常见的数值类?

简单值类型--包括 整数类型、实数类型、字符类型、布尔类型

复合值类型--包括 结构类型、枚举类型

22.C#中委托和接口有什么区别?各用在什么场合?

接口(interface)是约束类应该具备的功能集合,约束了类应该具备的功能,使类从千变万化的具体 逻辑中解脱出来,便于类的管理和扩展,同时又合理解决了类的单继承问题。

C#中的委托是约束方法集合的一个类,可以便捷的使用委托对这个方法集合进行操作。

在以下情况中使用接口:

1.无法使用继承的场合

2.完全抽象的场合

3.多人协作的场合 以上等等

在以下情况中使用委托:多用于事件处理中

23.C#中 unsafe 关键字是用来做什么的?什么场合下使用?

非托管代码才需要这个关键字 一般用在带指针操作的场合

24.C#中 ref 和 out 关键字有什么区别?

ref 修饰参数,表示进行引用传递,out 修饰参数也表示进行引用传递,但传递的引用只为带回返回值 ref 又进又出 out 不进只出

25.For,foreach,Enumerator.MoveNext 的使用,与内存消耗情况

for 循环可以通过索引依次进行遍历,foreach 和 Enumerator.MoveNext 通过迭代的方式进行遍历。内存 消耗上本质上并没有太大的区别。但是在 Unity 中的 Update 中,一般不推荐使用 foreach 因为会遗留 内存垃圾。

26.函数中多次使用 string 的+=处理,会产生大量内存垃圾(垃圾碎片),有

什么好的方法可以解决。

通过 StringBuilder 那进行 append,这样可以减少内存垃圾

27.当需要频繁创建使用某个对象时,有什么好的程序设计方案来节省内存?

设计单例模式进行创建对象或者使用对象池

28.JIT 和 AOT 区别

Just-In-Time - 实时编译

执行慢 安装快 占空间小一点

Ahead-Of-Time - 预先编译

执行快 安装慢 占内存占外存大29.给定一个存放参数的数组,重新排列数组

void SortArray(Array arr){Array.Sort(arr);}

30.Foreach 循环迭代时,若把其中的某个元素删除,程序报错,怎么找到那

个元素?以及具体怎么处理这种情况?(注:Try.....Catch 捕捉异常,发送

信息不可行)

foreach 不能进行元素的删除,因为迭代器会锁定迭代的集合,解决方法:记录找到索引或者 key 值, 迭代结束后再进行删除。

31.GameObject a=new GameObject() GameObject b=a 实例化出来了 A,

将 A 赋给 B,现在将 B 删除,问 A 还存在吗?

存在,b 删除只是将它在栈中的内存删除,而 A 对象本身是在堆中,所以 A 还存在

32.你拥有 A 块钱,一瓶水 B 块钱,每瓶水可以得到一个瓶盖,每 C 个瓶盖

可以换一瓶水请写出函数求解上面题目,上面题目 ABC 为参数

public static int Buy(int a,int b,int c) {
return a/b + ForCap(c,a/b);
}
public static int ForCap(int c,int d) {
if (d<c) {
return 0;
} else {
return d/c + ForCap(c,d/c + d%c);
}}

33.有一排开关,第一个人把所有的开关打开,第二个人按 2 的倍数的开关,

第三个人按 3 的倍数的开关,以此类推,现在又 n 个开关,k 个人,写函

数求最后等两者的开关,输入参数 n 和 k

static void Main(string[] args) {
int n = int.Parse(Console.ReadLine()); int k = int.Parse(Console.ReadLine());
Function(100,100);
}
static void Function(int n, int k) {
int i, j = 0;
bool[] a = new bool[1000]; //初始 false:关灯,true:开灯
for (i = 1; i <= k; i++) //k 个人
for (j = 1; j <= n; j++) //n 个灯
if (j % i == 0)
a[j] = !a[j]; //取反,false 变 true,原来开变关,关变开
for (i = 1; i <= n; i++) //最后输出 a[i]的值就可以了
if (a[i]) //灯亮着
Console.WriteLine(i);
}

34.数制转换,将任意整数转换成 8 进制形式

static void Main(string[] args) {
int n;
n =int.Parse(Console.ReadLine());
Console.WriteLine("输入的 10 进制为:{0}",n);
Console.Write("转换为 8 进制数为: ");
d2o(n);
}
static void d2o(int n) {
if (n > 7) {
d2o(n / 8);
}
Console.Write(n%8);
}

35.找出 200 以内的素数。

static void Main(string[] args) {
int count = 0;
for (int i = 1; i < 200; i++) { //外层循环:要判断的数
for (int j = 2; j <=i; j++){
if (i % j == 0&& i!=j) {
break;
}
if (j == i ) { //结束的条件:最后一个数还没有被整除
count++;
Console.WriteLine(i);
} }
}
Console.WriteLine(count);
}

36.打印杨辉三角形

public static void YHSJ(){
int [][]a= new int[7][] ;
a[0] = new int[1]; //a[0][0]=1;
a[1] = new int[2] ;
for (int i = 0; i < 7; i++) {
a[i] = new int[i+1] ;
a[i][0] =1;
a[i][i]=1;
if(i>1) { //求出中间的数据
for(int j=1;j<i; j++){
a[i][j]= a[i-1][j-1]+a[i-1][j];
}
}
}
for (int i=0; i<a.Length; i++) {
for (int k = 0; k < a.Length-1-i; k++) {
Console.Write("");
}
for(int j=0;j<a[i].Length; j++ ) {
Console.Write(a[i][j] + "");
}
Console.WriteLine();
}
}

37.中国有句俗话“三天打鱼两天晒网”,某人从 2000 年 1 月 1 日起开始

“三天打鱼两天晒网”,问这个人在今后的某天中“打鱼”还是”晒网”

public static void Compute(){
Console.WriteLine ((DateTime.Now - DateTime.Parse("2000-01-01")).Days%5<3?"打鱼":"晒网");

}38.假设当前市场价一只鸡 10 元,一只鸭 12 元 5 角。请写一个函数

ShowPrice,输入参数分别为鸡和鸭的个数(非负整型),功能为显示出总

价钱,精确到分。例如调用 ShowPrice(5,10)后输出 175.00。请注意程

序的可读性和易于维护性。

static void ShowPrice(int num_chicken, int num_duck) {
float totalPrice = 0.00f;
float price_chicken = 10f;
float price_duck = 12.5f;
totalPrice = num_chicken * price_chicken + num_duck * price_duck;
Console.WriteLine("总价钱为:{0:0.00}", totalPrice);
}

39.请写一个函数,用于返回 n!(阶乘)结果末尾连续 0 的个数,如

GetZeroCount(5)返回 1,因为 5!

= 120,末尾连续 1 个 0

static void ShowPrice(int num_chicken, int num_duck) {
float totalPrice = 0.00f;
float price_chicken = 10f;
float price_duck = 12.5f;
totalPrice = num_chicken * price_chicken + num_duck * price_duck;
Console.WriteLine("总价钱为:{0:0.00}", totalPrice);
}
目录
相关文章
|
9小时前
|
存储 安全 Java
C#语言特点及基础
C#语言特点及基础
|
9小时前
|
前端开发 Java C#
java/C#语言开发的医疗信息系统11套源码
java/C#语言开发的医疗信息系统11套源码
27 1
|
9小时前
|
算法 C# 数据库
【干货】一份10万字免费的C#/.NET/.NET Core面试宝典
C#/.NET/.NET Core相关技术常见面试题汇总,不仅仅为了面试而学习,更多的是查漏补缺、扩充知识面和大家共同学习进步。该知识库主要由自己平时学习实践总结、网上优秀文章资料收集(这一部分会标注来源)和社区小伙伴提供三部分组成。该份基础面试宝典完全免费,发布两年来收获了广大.NET小伙伴的好评,我会持续更新和改进,欢迎关注我的公众号【追逐时光者】第一时间获取最新更新的面试题内容。
|
9小时前
|
SQL 数据库 C#
C# .NET面试系列十一:数据库SQL查询(附建表语句)
#### 第1题 用一条 SQL 语句 查询出每门课都大于80 分的学生姓名 建表语句: ```sql create table tableA ( name varchar(10), kecheng varchar(10), fenshu int(11) ) DEFAULT CHARSET = 'utf8'; ``` 插入数据 ```sql insert into tableA values ('张三', '语文', 81); insert into tableA values ('张三', '数学', 75); insert into tableA values ('李四',
75 2
C# .NET面试系列十一:数据库SQL查询(附建表语句)
|
9小时前
|
开发框架 算法 搜索推荐
C# .NET面试系列九:常见的算法
#### 1. 求质数 ```c# // 判断一个数是否为质数的方法 public static bool IsPrime(int number) { if (number < 2) { return false; } for (int i = 2; i <= Math.Sqrt(number); i++) { if (number % i == 0) { return false; } } return true; } class Progr
64 1
|
9小时前
|
并行计算 安全 Java
C# .NET面试系列四:多线程
<h2>多线程 #### 1. 根据线程安全的相关知识,分析以下代码,当调用 test 方法时 i > 10 时是否会引起死锁? 并简要说明理由。 ```c# public void test(int i) { lock(this) { if (i > 10) { i--; test(i); } } } ``` 在给定的代码中,不会发生死锁。死锁通常是由于两个或多个线程互相等待对方释放锁而无法继续执行的情况。在这个代码中,只有一个线程持有锁,且没有其他线程参与,因此不
116 3
|
9小时前
|
安全 Go 开发者
Golang深入浅出之-Go语言并发编程面试:Goroutine简介与创建
【4月更文挑战第22天】Go语言的Goroutine是其并发模型的核心,是一种轻量级线程,能低成本创建和销毁,支持并发和并行执行。创建Goroutine使用`go`关键字,如`go sayHello(&quot;Alice&quot;)`。常见问题包括忘记使用`go`关键字、不正确处理通道同步和关闭、以及Goroutine泄漏。解决方法包括确保使用`go`启动函数、在发送完数据后关闭通道、设置Goroutine退出条件。理解并掌握这些能帮助开发者编写高效、安全的并发程序。
23 1
|
9小时前
|
Java C# 开发工具
开发语言漫谈-C#
C#的#,字面上的意思就是++++
|
9小时前
|
图形学
【Unity C#_菜单Window开发系列_Inspector Component UnityEditor开发】
【Unity C#_菜单Window开发系列_Inspector Component UnityEditor开发】
|
9小时前
|
存储 开发框架 .NET
C# 面试题及答案整理,最新面试题
C# 面试题及答案整理,最新面试题
51 0