一.简答题
1.简述c#中的所有访问修饰符及访问权限?
(1)public:给类,及所有类成员使用
可访问范围:当前类自身 所有的子类 同一程序集其他类通过实例化也可以访问 其他程序集中的类也可以实例化访问
(2)protected:给类,内嵌类的所有成员使用
可访问范围:当前类自身 所有的子类可以访问 同一程序集其他类不可以访问 其他程序集中可以通过继承也可以访问
(3)internal:给类,内嵌类的所有成员使用
可访问范围:当前类自身 同一程序集的其他类可以通过实例化访问 同一程序集中的子类也可以访问 其他程序集中不管是不是子类都无法访问
(4)private:给类,及所有类成员使用
可访问范围:当前类自身 所有类成员的默认访问修饰符
(5)internal protected:给类,及内嵌类的所有成员使用
可访问范围:当前类自身 同一程序集的其他类可以通过实例化进行访问 所有子类可以访问 其他程序集中可以通过继承进行访问,但实例化不行
2.简单介绍方法重载和重写?
重写:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。
重载:一个类中的方法与另一个方法同名,但是参数表不同,这种方法称之为重载方法。
3.方法中的ref参数和out参数的用法是什么?
(1)ref引用传参:
①使用ref引用参数时,必须在方法的声明和调用中都使用ref修饰符
②实参必须是变量,在用作实参前必须被赋值,如果是引用类型变量,可以赋值为一个引用或者null值
(2)out输出参数:
①在方法体结束前,必须对out参数进行赋值;
②遇到方法中的形参是out类型,则在调用方法的时候同样实参也必须带有out参数;
③在调用out类型参数的方法时,需准备一个相同类型的变量接受out的结果,并且必须带有关键字;
4.简单介绍数组和集合的区别?
①数组用于保存固定数量的数据,定长,占用内存少,遍历速度快;
②集合保存的数据数量,可以在程序的执行过程中,不断发生变化,不定长,占用内存多,遍历速度慢;
③在功能上,数组能实现的所有功能,集合都能实现;反之,集合能实现的某些功能,数组难以实现
5.简单介绍c#中的两个特殊函数?
①构造函数:又叫构造方法, 当创建类的新对象时执行,构造函数的名称与类的名称完全相同,无返回值类型,可以重载
②析构函数:是实现销毁一个类的实例的方法成员,当类的对象超出范围时执行,无返回值,也不带任何参数,用于在结束程序(比如关闭文件、释放内存等)之前释放资源
6.简单介绍static静态的用法和特性?
static意思是静态,可以修饰类、字段、属性、方法,但不能用于索引器、析构函数或类以外的类型。
标记为static的就不用创建实例对象调用了,可以通过类名直接点出来
三种用法:
①static可以修饰变量,这个变量只能是成员变量,不能是局部的,称为静态函数
static int a=1;
②Static可以修饰类,使类成为静态类。这样在此类中只能定义静态的方法和静态的变量。
③static可以修饰方法,在方法(函数)前用static修饰,表示此方法为所在类或所在自定义类所有,而不是这个类的实例所有,这个方法称为静态方法:
特性:
只会在编译时分配空间,程序真正执行时,是不会重新分配空间的.
值能变,但是其指向地址不会变
用static声明了的变量不会被GC(辣鸡回收机制)所回收.
7.c#中的委托是什么?事件是不是委托?
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递
事件是一种消息机制,它是一种特殊的委托。
8.请简述c#中类(class)和结构(struct)的异同?
异:(1)类型不同:类是引用类型,在堆上分配地址;
结构是值类型,在栈上分配地址;
(2)继承性不同:类:是完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承
结构:不能从另外一个结构或者类继承,本身也不能被继承(但能够继承接口,方法和类继承接口一样),虽然结构没有明确的用sealed声明,但却是隐式的sealed
(3)内部结构不同:类: 有默认的构造函数和析构函数 可以使用 abstract 和 sealed 有protected 修饰符 必须使用new 初始化
结构: 没有默认的构造函数,但是可以添加构造函数 没有析构函数 没有 abstract 和 sealed(因为不能继承) 不能有protected 修饰符 可以不使用new 初始化,在结构中初始化实例字段是错误的
同:基类型都是对象(object)
9.介绍c#中string和StringBuilder的用法?
String类有不可改变性,每次执行字符操作时,都会创建一个新的String对象。
StringBuilder 类解决了对字符串进行重复修改的过程中创建大量对象的问题。初始化一个StringBuilder 之后,它会自动申请一个默认的StringBuilder 容量(默认值是16),这个容量是由Capacity来控制的.并且允许,我们根据需要来控制Capacity的大小,也可以通过Length来获取或设置StringBuilder 的长度.
10.什么是抽象函数(abstract)?什么是虚拟函数(virtual)?两者有何区别?
抽象函数:是只有定义、没有实际方法体的函数,它只能在抽象函数中出现
虚拟函数:有自己的函数体,已经提供了函数实现,但是允许在子类中重写或覆盖。
区别:
①虚拟函数必须有实现部分,抽象函数必须重写
②抽象函数只能在抽象类中声明,虚拟函数不是。
③抽象函数必须在派生类中重写,虚拟函数不必。
④无法创建abstract类的实例,只能被继承无法实例化
⑤虚拟函数可以实现多态,而抽象函数不行
11.c#中接口和类有什么异同?
不同点:
不能直接实例化接口。
接口不包含方法的实现。
接口可以多继承,类只能单继承。
类定义可以在不同的源文件之间进行拆分。
相同点:
接口、类都可以从多个接口继承。
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
接口和类都可以包含事件、索引器、属性。
12.进程和线程的区别是什么?
(进程是系统进行资源分配的基本单位,有独立的内存地址空间;
线程是CPU调度的基本单位,没有单独地址空间,有独立的栈,局部变量,寄存器, 程序计数器等。
线程属于进程,不能独立执行。每个进程至少要有一个线程,成为主线程)
二者的区别:
①调度
线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
②并发性
进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
③拥有资源
进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
④系统开销
在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
13.请详述c#中的继承问题?
①子承父业:子类会继承父类的属性,构造,行为
②父类具有的,子类不一定具有,子类具有的,父类也不一定具有
当父类只有带参构造,子类自动会要有带参构造
③C#不支持多重继承,但是可以多重接口继承
④关键字this:当前类自己,base:代表当前类的亲父类
⑤实例化过程(对象创建过程,先调用的最终父类的构造函数然后依次往下调用当前类)
⑥析构过程(对象销毁的过程,从自己开始销毁直到最终父类)
14.简述break,continue,return三者的区别?
return:跳出当前循环,直到代码块结束
break:只跳出当前循环,执行代码之后的代码
continue:只跳出当前本次循环,执行下一次循环
15.简述Socket通信TCP协议的三次握手的作用?
三次握手是为了验证服务器与浏览器之间两者的收,发功能是否正常。
①第一次握手保证客户端能够具有发送数据的能力
②第二次握手保证服务端能接收到数据,保证服务端能够发送数据的能力
③第三次握手保证客户端能够接收到数据
16. 简述建立Socket通信的服务端,客户端的步骤?
服务器端:
第一步:创建一个用于监听连接的Socket对像;
第二步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第三步:用socket对像的Bind()方法绑定EndPoint;
第四步:用socket对像的Listen()方法开始监听;
第五步:接收到客户端的连接,用socket对像的Accept()方法创建一个新的用于和客户端进行通信的socket对像;
第六步:通信结束后一定记得关闭socket;
客户端:
第一步:建立一个Socket对像;
第二步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第三步:用socket对像的Connect()方法以上面建立的EndPoint对像做为参数,向服务器发出连接请求;
第四步:如果连接成功,就用socket对像的Send()方法向服务器发送信息;
第五步:用socket对像的Receive()方法接受服务器发来的信息 ;
第六步:通信结束后一定记得关闭socket;
二.算法
1.使用递归算法计算斐波那契数列
static void Main(string[] args)
{
Console.WriteLine("请输入你想要计算的斐波那数列:");
int i = int.Parse(Console.ReadLine());
int result = Getres(i);
Console.WriteLine("计算出{0}位的斐波那数列为{1}",i,result);
Console.ReadLine();
}
static int Getres(int i)
{
int res = 0;
if (i==1)
{
res = 0;
}
else if (i==2)
{
res = 1;
}
else
{
res = Getres(i - 1) + Getres(i - 2);
}
return res;
}
2.在1-20这20个数中求出7个不重复的随机数
static void Main(string[] args)
{
int[] num = new int[7];
Random r = new Random();
for (int i = 0; i < num.Length; i++)
{
num[i] = r.Next(1,21);
if (i>0)
{
for (int j = 0; j < i; j++)
{
if (num[i]==num[j])
{
i--;
}
}
}
}
for (int i = 0; i < num.Length; i++)
{
Console.Write(num[i]+" ");
}
Console.WriteLine();