面试|C# .net 面试题

在开发的过程中,不能只浮于表面,实现功能,而是要不断的积累编程语言的基础知识。

1、.NET是什么?

.net是一个开发者平台,它不仅仅是包含开发环境、技术框架、社区论坛、服务支持等,它还强调了平台的跨语言、跨平台编程的两个特性。

 在.net框架下有很多种语言:C#、Visual Basic、C++/CLI、Eiffel、F#、IronPython、IronRuby、PowerBuilder、Visual COBOL 以及 Windows PowerShell。用其中一种语言编写的类型可以无缝地用在另一种语言编写的应用程序中的互操作性。

CLS:公共语言规范 - Common Language Specification ,CLS从类型、命名、事件、属性、数组等方面对语言进行了共性的定义及规范。

2、简述 private、 protected、 public、internal 修饰符的访问权限

private : 私有成员, 在类的内部才可以访问(只能从其声明上下文中进行访问)。  
protected : 保护成员,该类内部和从该类派生的类中可以访问。 
public : 公共成员,完全公开,没有访问限制。  
internal: 在同一命名空间内可以访问。 

3、委托,事件是不是一种委托?

委托是将一种方法作为参数代入到另一种方法,委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性

事件是一种特殊的委托。  //比如:onclick事件中的参数就是一种方法。

4、.NET中类与结构的异同。

class可以被实例化,属于引用类型,是分配在内存的堆上的。类是引用传递。
struct属于值类型,是分配在内存的栈上的。结构是值传递。
int32、boolean都属于结构。

5、装箱和拆箱

装箱就是隐式的将一个值型转换为引用型对象。

拆箱就是将一个引用型对象转换成任意值型。

比如:
int i=0;
Syste.Object obj=i;
这个过程就是装箱!就是将 i 装箱!
比如:
int i=0;
System.Object obj=i;
int j=(int)obj;
这个过程前2句是将 i 装箱,后一句是将 obj 拆箱!

6、override与重载(overload)的区别。
重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。
重载是面向过程的概念。

override是进行基类中函数的重写,是面向对象的概念。抽象方法,接口,标记为virtual的方法可以被重写(override),实方法不可以

7、如何理解三层架构。
答:三层架构就是将整个业务应用划为:表现层、业务逻辑层、数据访问层。
区分层次的目的即为了“高内聚,低耦合”的思想。
表现层:通俗讲就是展现给用户的界面,即用户在使用一个系统的时候的所见所得。
业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
数据访问层:该层所做事务直接操作数据库,针对数据的增删改查等。
每层之间是一种垂直关系。
三层架构是N层架构的一种,一般来说,层次之间是向下依赖的,下层代码未确定其接口前,上层代码是无法开发的,下层代码接口的变化将使上层的代码一起变化。
优点:分工明确,条理清晰,易于调试,而且具有扩展性。
缺点:增加系统复杂度,增加成本。

8、列举c#语言集合及其特性

一、数组 (数据类型 [ ] 变量名)

数组用于保存固定数量的数据,定长,占用内存少,遍历速度快。

二、动态数组arrylist

ArrayList可以填补数组的不足,进行元素的动态维护。数组的长度是固定的,而ArrayList的容量可以根据需要自动扩充,它的索引会根据程序的扩展而重新分配和调整,动态改变数组的长度,ArrayList是非泛型集合,添加和读取数据有装箱拆箱(存储的时候需要把值类型封装成object类型,取出 来的时候需要再把object类型再转换成值类型),所以会有性能损失。

装箱:如果往ArrayList中存储值类型的数据,在存储的时候需要转换成object类型存 储,由值类型封装成object类型的过程称为装箱。

拆箱:由object类型转换成值类型的过程称为拆箱。

三、列表List
1.定义:List<数据类型>变量名;
2.List集合的赋值:变量名=new List<数据类型>();
3.List集合的初始化器:变量名=new List<数据类型>{元素1,元素2...元素n}
4.添加元素:变量名.Add(要添加的数据);
5.插入元素:变量名.Insert(索引,要插入的数据);
6.删除元素:
变量名.RemoveAt(要删除的索引);
变量名.Remove(数据);
7.修改元素:变量名[索引]=值;

特点:
1.不定长
2.占用内存多
3.遍历速度慢
4.在功能上,数组能实现的所有功能集合都能实现
但集合能实现的功能数组不一定能实现

四、字典Dictionary( TKey , TValue ) 

Dictionary( TKey, TValue) 泛型类提供了从一组键到一组值的映射。字典中的每个添加项都由一个值及其相关联的键组成。通过键来检索值的速度是非常快的。

9、进程与线程的区别?

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位,进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段。

线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

10、string和stringbuilder的区别?

string本身是不可改变的,它只能赋值一次,每一次内容发生改变,都会生成一个新的对象,然后原有的对象引用新的对象,而每一次生成新对象都会对系统性能产生影响,这会降低.NET编译器的工作效率。

而StringBuilder类则不同,每次操作都是对自身对象进行操作,而不是生成新的对象,其所占空间会随着内容的增加而扩充,这样,在做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。

当程序中需要大量的对某个字符串进行操作时,应该考虑应用StringBuilder类处理该字符串,其设计目的就是针对大量string操作的一种改进办法,避免产生太多的临时对象;而当程序中只是对某个字符串进行一次或几次操作时,采用string类即可。

11、属性与字段的区别

属性可以对值的获取和设置进行控制,而字段不能。
一般情况下get读取的值就是set设置的值。
如果只有get,则说明值是只读。
如果只有set,则说明值是只写。
get和set的本质是就是内部方法。

12、如何才能提高代码的效率和性能
可以根据业务流程、业务数据的特点进行优化,比如可以采用缓存、索引等来提高代码的效率和性能。
同时不要进行无意义的代码优化,重点优化系统的性能瓶颈。
按照设计模式去编写代码,彻底的面向对象编程,多用委托事件。
尽量做到方法的每一个实现代码只写一遍。

13、String是值类型还是引用类型?它是如何工作的。
String是引用类型。
String的值是不可变的,当对String类型的对象重新赋值时,这个对象的引用指向就会变成一个新的引用,而原来的那个值并没有改变,只是引用改变了。

14、堆与栈的区别。
栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈中。
堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

15、try{}里有一个return语句,那么紧跟在try后的finally{}里的代码会不会被执行,什么时候被执行。
会执行,如果return后面有一个返回值或者表达式,则会先进行计算,把值暂存起来,然后再执行finally里的代码,无论如何,return总是最后执行

16、属性和字段的区别是什么?
属性可以对值的获取和设置进行控制,而字段不能。
一般情况下get读取的值就是set设置的值。
如果只有get,则说明值是只读。
如果只有set,则说明值是只写。
get和set的本质是就是内部方法。

17、C#的接口和类有什么异同?
不同点:
不能直接实例化接口。
接口不包含方法的实现。
接口可以继承,类只能单继承。
类定义可在不同的源文件之间进行拆分。
相同点:
接口、类和结构都可以从多个接口继承实现。
继承接口的任何非抽象类型都必须实现接口的所有成员。
接口和类都可以包含事件、索引、方法和属性。

18、DataReader和DataSet的异同?
DataReader为在线操作数据, DataReader会一直占用SqlConnection连接,在其获得数据过程中其它操作不可以再使用SqlConnection连接对象。
DataSet为离线操作数据,DataSet会将数据一次性读入内存,然后断开连接,这时其它操作就可以使用SqlConnection连接对象。
由于DataReader一次只读取一行数据,所以占用内存较小。但DataReader为只进且只读的,也就是只能单方向向前读取,如果你想回头去读取上一条数据是不允许的,并且 不允许其修改数据。
由于DataSet一次性读取所有数据,所以比较消耗资源,但也提高了灵活性,在断开数据库连接情况下你可以对数据进行任何增删改查,按照任意的顺序读取数据,并可以将 其写回到数据库。

19、简述ADO.NET中的五个主要对象。
Connection:主要是开启程序和数据库之间的连接。没有利用连接对象将数据库打开,是无法从数据库中取得数据的。Close和Dispose的区别,Close以后还可以Open,Dispose以后则不能再用。
Command:主要可以用来对数据库发出一些指令,例如可以对数据库下达查询、新增、修改、删除数据等指令,以及调用存在数据库中的存储过程等。这个对象是架构在Connection 对象上,也就是Command 对象是透过连接到数据源。
DataAdapter:主要是在数据源以及DataSet 之间执行数据传输的工作,它可以透过Command 对象下达命令后,并将取得的数据放入DataSet 对象中。这个对象是架构在Command对象上,并提供了许多配合DataSet 使用的功能。
DataSet:这个对象可以视为一个暂存区(Cache),可以把从数据库中所查询到的数据保留起来,甚至可以将整个数据库显示出来,DataSet是放在内存中的。DataSet 的能力不只是可以储存多个Table 而已,还可以透过DataAdapter对象取得一些例如主键等的数据表结构,并可以记录数据表间的关联。DataSet 对象可以说是ADO.NET 中重量级的对象,这个对象架构在DataAdapter对象上,本身不具备和数据源沟通的能力;也就是说我们是将DataAdapter对象当做DataSet 对象以及数据源间传输数据的桥梁。DataSet包含若干DataTable、DataTableTable包含若干DataRow。
DataReader:当我们只需要循序的读取数据而不需要其它操作时,可以使用DataReader 对象。DataReader对象只是一次一笔向下循序的读取数据源中的数据,这些数据是存在数据库服务器中的,而不是一次性加载到程序的内存中的,只能(通过游标)读取当前行的数据,而且这些数据是只读的,并不允许作其它的操作。因为DataReader 在读取数据的时候限制了每次只读取一笔,而且只能只读,所以使用起来不但节省资源而且效率很好。使用DataReader 对象除了效率较好之外,因为不用把数据全部传回,故可以降低网络的负载。
ADO.NET 使用Connection 对象来连接数据库,使用Command 或DataAdapter对象来执行SQL语句,并将执行的结果返回给DataReader 或 DataAdapter ,然后再使用取得的DataReader 或DataAdapter 对象操作数据结果。

20、请简述面向对象的多态的特性及意义
简单来说,多态是具有表现多种形态的能力特征,在OO中是指,语言根据对象的类型的不同,以不同的方式处理。
特别是重载方法和继承类这种形式的能力。
多态被认为是面向对象语言的必备特性。
面向对象的语言使用虚方法表达多态。
这意味着派生类可以有和父类具有同样签名的方法,并且父类可以调用派生类的方法。
在C#中,必须使用virtual关键字才能使方法被父类调用。

21、写一个冒泡排序(从小到大)。
int[] myInts = { 11, 22, 33, 44, 55 ,66};
int temp = 0;
int count = 0;
for (int i = 1; i <= myInts.Length - 1; i++)
{
//bool 是否需要排序 = false;
for (int j = myInts.Length - 1; j >= i; j--)
{
if (myInts[j] < myInts[j - 1])
{
temp = myInts[j];
myInts[j] = myInts[j - 1];
myInts[j - 1] = temp;
}
count++;
}
}

22、ref和out

①out:输出参数,方法中的out参数在方法结束时,需要准备一个相同类型的变量接受out的结果,并且必须带out关键字。

②遇到方法中形参是out类型,则在调用方法的时候实参也必须带有out关键字。

③ref:引用传参,使用前要进行初始化,传进方法中的参数,如果在方法内发生改变,那么这个参数变量将会永久性发生改变。


23、说出B/S和C/S的区别

①体积:C/S胖客户端,B/S瘦客户端

②效率:C/S本地运行,B/S服务器端运行

③网络:C/S依赖不强,B/S必须依赖网络

④用户:C/S体验更好,B/S其次

你可能感兴趣的:(C#)