这是.NET技术面试题系列第一篇,今天主要分享基础概念。1、简述private、protected、public、internal修饰符的访问权限private:私有成员,
这是.NET技术面试题系列第一篇,今天主要分享基础概念。
1、简述 private、 protected、 public、internal 修饰符的访问权限
private : 私有成员, 在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
internal: 当前程序集内可以访问。
2、CTS、CLS、CLR分别作何解释
CTS:Common Type System 通用类型系统。Int32、Int16→int、String→string、Boolean→bool。每种语言都定义了自己的类型,.Net通过CTS提供了公共的类型,然后翻译生成对应的.Net类型。
CLS:Common LanguageSpecification 通用语言规范。不同语言语法的不同。每种语言都有自己的语法,.Net通过CLS提供了公共的语法,然后不同语言翻译生成对应的.Net语法。
CLR:Common LanguageRuntime 公共语言运行时,就是GC、JIT等这些。有不同的CLR,比如服务器CLR、LinuxCLR(Mono)、SilverlightCLR(CoreCLR)。相当于一个发动机,负责执行IL。
3、override与重载(overload)的区别
覆写就是子类中重复定义父类方法,只有virtual和abstract标记的方法(包括泛型)才能被覆写,覆写以override标记;
重载是在同一个类中存在多个方法同名而参数列表不同(包括泛型);方法地址是在编译期已经确定;一般包括方法重载和运算符重载;operator implict可实现一定程度的按返回值重载;
覆写是实现运行时的多态性,而重载实现了编译时的多态性;
4、C#中索引器是否只能根据数字进行索引?是否允许多个索引器参数?
参数的个数和类型都是任意的。索引器的内部本质上就是set_item、get_item方法。
索引可以有多个参数、参数类型任意
索引可以重载。
5、在dotnet中类(class)与结构(struct)的异同?
1、从引用类型和值类型角度区分,内存分配存储地方和垃圾回收方式不一样;
2、class可声明无参构造函数和析构函数;struct则不行;
3、class有继承,有多态、;struct只是支持接口继承,值类型是密封类型,不能被继承;
Class属于引用类型,是分配在内存托管堆上,由GC执行垃圾回收。类是引用传递的。
Struct属于值类型,是分配在内存的堆栈上,线程的堆栈主要由操作系统管理,而不受GC控制,当值类型实例所在方法结束时,其存储单位自动释放,栈的执行率高,但存储容量有限。结构体是按值传递的。
6、堆和栈的区别?
栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中。
堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。
7、New关键词在.NET中作用
1、作为运算符,用于创建对象和调用构造函数,分配内存并初始化;不可重载,若分配内存失败,将引发OutOfMemoryException异常;
2、作为修饰符,用于向基类成员隐藏继承成员;
3、作为约束,用于在泛型声明中约束可能用作类型参数的参数类型。
class Genericer where T:new() { }
8、Using关键词在.Net中作用
1、引入命名空间(是在逻辑上的组织架构,而非实际的物理结构,避免类名冲突的方法;代码中存在调用操作,则编译器才会加载using引入命名空间所在程序集);
2、创建别名(可创建类型别名和程序集别名)usingalias=namespace|type;
3、强制非托管资源清理,编译器自动将using生成try-finally,在finally调用dispose方法;支持初始化多个变量;Dispose只是清理对象封装的非托管资源,而不是释放对象的内存(对象的内存由GC控制);
using(IDisposable fOnt=new Font(),pen=new Pen()){}
9、yield关键字在.Net中作用
yield这个语法糖实现了一个实现IEnumerable接口的类来返回我们需要到IEnumerable类型的数据。当我们需要返回IEnumerable类型的时候,直接yield返回数据就可以了。也不用new一个list,或其他类型。所以yield是一个典型的语法糖。
作用于迭代器块中,用于像枚举器对象提供值或者发出结束信号;
yield return 用于依次返回每个元素;
yield break用于终止迭代;
使用yield return为什么能保证每次循环遍历的时候从前一次停止的地方开始执行呢?
--因为,编译器会生成一个状态机来维护迭代器的状态。
另外使用yield还有一些注意事项:
你不能在具有以下特点的方法中包含 yield return 或 yield break 语句:
匿名方法。
包含不安全的块的方法。
10、Const和readonly区别
Const:生成IL代码,static修饰,只能应用在值类型和string类型,常量值确定于编译时,常量编译后保存于模块的元数据中,无须在托管堆中分配内存;声明是必须初始化,可以定义字段和局部变量;
Readonly:只读字段,可以是任意类型,但是对于引用类型字段,readonly不能限制对该对象实例成员的读写控制;可在构造函数初始化,也就是在在运行时获取值,构造函数初始化是在运行时,只局限于定义字段;推荐使用static readonly
11、特性和属性区别
特性attribute,是一个类,为目标元素提供关联附加信息,并在运行期以反射的方式来获取附加信息;除了自定义的特性,常用特性有:[Flags]、[DllImport]、[Serializable],还有数据层应用的[Required]、[Description]等等;
属性:对私有字段的访问封装;
12、深克隆和浅克隆区别
只有实现了ICloneable接口的类型,才允许其实例被克隆,在Clone方法中通过调用基类MenberwiseClone就可实现浅拷贝;深拷贝实现方法可以在clone里返回New 一个实例对象;
浅拷贝:是指将对象中的所有字段逐字复杂到一个新对象。
对值类型字段只是简单的拷贝一个副本到目标对象,改变目标对象中值类型字段的值不会反映到原始对象中,因为拷贝的是副本;
对引用型字段则是指拷贝他的一个引用到目标对象。改变目标对象中引用类型字段的值它将反映到原始对象中,因为拷贝的是指向堆是上的一个地址;
深拷贝:深拷贝与浅拷贝不同的是对于引用字段的处理,深拷贝将会在新对象中创建一个新的对象和原始对象中对应字段相同(内容相同)的字段,也就是说这个引用和原始对象的引用是不同,我们改变新对象中这个字段的时候是不会影响到原始对象中对应字段的内容。
一般值类型之间的赋值是执行深拷贝,而引用类型的赋值一般执行的是浅拷贝,当然也有例外,如string等。
13、抽象类和接口异同:
相同:
都不能被直接实例化,可以通过继承实现其抽象方法;
都是面向抽象编程的技术基础,通过封装变化来实现实体之间的关系;
不同点:
接口支持多继承;抽象类不能;
接口只能定义抽象规则;抽象类即可以定义规则,还可以提供已实现成员;
接口着重于can-do关系,抽象类偏重于is -a 关系;
抽象类应主要用于关系密切的对象,而接口最合适为不相关的类提供通用功能,尽量将接口设计成功能单一的功能块;
14、C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
C语言,使用函数指针来创建回调函数,使用回调可以把函数回调给程序中的另一个函数。在.NET中,在大部分时间里都没有指针的身影,因为指针被封闭在内部函数当中。可是回调函数却依然存在,它是以委托的方式来完成的。委托可以被视为一个更高级的指针,它不仅仅能把地址指向另一个函数,而且还能传递参数,返回值等多个信息。
委托可以把一个方法作为参数代入另一个方法。
事件(event)可被视作为一种特别的委托,它为委托对象隐式地建立起add_XXX、remove_XXX 两个方法,用作注册与注销事件的处理方法。
15、GC是什么? 为什么要有GC?
什么样的对象被GC认为是垃圾?如何回收?何时回收?回收后,又执行哪些操作?
一个对象成为“垃圾”就表示该对象不被任何其他对象所引用;
垃圾收集器遍历所有对象,通过一定的算法标记查找哪些是可回收的对象;
GC是周期性执行内存清理工作,以下情况出现时GC将会启动:
1、内存不足溢出时,更确切地说是第0代对象充满时;
2、调用GC.Collect方法强制执行垃圾回收;
3、window报告内存不足,CLR将强制执行垃圾回收;
4、CLR卸载appDomain时,GC将所有代龄的对象执行垃圾回收;
GC执行内存清理工作,让程序员专注业务逻辑开发,不用担心内存管理;
不建议调用GC.Collect方法,除非知道有大量对象停止引用;
GC在垃圾回收之后,会出现托管堆的内存碎片,会重新分配内存,压缩托管堆;
GC只能处理托管内存资源的释放,对于非托管资源则不能使用GC进行回收,必须由程序员手工回收,
非托管资源:数据库链接、文件句柄、网络链接、com对象等等,调用Finalize方法(析构函数)和Dispose方法(实现IDisposable接口)清理释放资源;
欢迎大家关注微信号,微信公众号名称:DotNet修炼宝典。 扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)