NET面试--C#基础
1、面向对象的三大特征?
继承,多态,封装
2、值类型和引用类型的区别?
值类型:存在栈中,读取快
引用类型:存在堆中,内存
3、C#接口和类有什么异同?
接口与类不同点:
- 不能直接实例化接口
- 接口不包含方法的实现
- 接口、类和结构可以从多个接口继承
- 但是C#只支持单继承:类只能从一个基类继承实现
接口与类相同点:
- 接口、类和结构可以从多个接口继承
- 接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员
- 接口可以包含事件、索引器、方法和属性
- 一个类可以实现多个接口
4、抽象类和接口区别
相同:
- 都可以被继承
- 都不能被实例化
- 都可以包含方法声明
- 派生类必须实现未实现的方法
区 别:
- 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
- 抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。
- 接口可以被多重实现,抽象类只能被单一继承
- 抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中
- 抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定,因此反映的是事物的外部特性
- 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法
- 接口可以用于支持回调,而继承并不具备这个特点
- 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
5、泛型的优点和缺点
优点:
- 类型安全
- 减少拆箱和装箱,提升性能
- 二进制重用
- 消除强制类型转换
缺点: - 增加了对象的复杂度
- 反射耗性能
6、反射的优点和缺点
优点:
- 反射提高了程序的灵活性和扩展性。
- 降低耦合性,提高自适应能力。
- 它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
缺点:
- 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
- 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
用途:
- 它允许在运行时查看特性(attribute)信息。
- 它允许审查集合中的各种类型,以及实例化这些类型。
- 它允许延迟绑定的方法和属性(property)。
- 它允许在运行时创建新类型,然后使用这些类型执行一些任务。
7、谈谈委托
在CLR运行时,委托DoSth实际上就一个类,该类有一个参数类型为方法的构造函数,并且提供了一个Invoke实例方法,用来触发委托的执行。
- 委托DoSth定义了方法的参数和返回类型
- 通过委托DoSth的构造函数,可以把符合定义的方法赋值给委托
- 调用委托的实例方法Invoke执行了方法
8、C#中索引器的实现过程,是否只能根据数字进行索引
索引器允许类或结构的实例就像数组一样进行索引。索引器形态类似于,不同之处在于它们的取值函数采用参数。
索引器的参数可以采用任何类型,不过int是最为合理的类型。
9、如何理解.net的垃圾回收机制
NET Framework 的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来回收它们占用的内存
10、C#可否对内存进行直接的操作?
C#是可以对内存进行直接操作的,虽然很少用到指针,但是C#是可以使用指针的,在用的时候需要在前边加unsafe,,在.net中使用了垃圾回收机制(GC)功能,它替代了程序员,不过在C#中不可以直接使用finalize方法,而是在析构函数中调用基类的finalize()方法
11、new做了那些操作
- 声明引用
- 使用new关键字创建类的对象并对其初始化
- 将引用指向类的对象
12、C#中property与attribute的区别,他们各有什么用处,这种机制好处在哪里?
- 对于Property来说,和直接使用成员变量相比,好处很多,比如,可以在赋值或读取值前进行数据校验,可以很容易提供触发事件的方法等等。当然也可以提供只读或只写的属性。
- 而Attributes的引入,使得我们在设计方法,属性,事件等的时候,可以加入我们的一些信息或约束。使得我们编程更加方便。
13、为什么要用委托
委托使得一个方法可以作为另一个方法的参数进行传递,这就是委托最大的作用。
14、类与结构类
- 结构类声明字段不能给初始值
- 隐式的无参数的构造函数在结构中无论如何都是存在的,所以程序员不能手动的为结构添加1个无参数的构造函数.
- 创建结构体对象可以不使用new关键字
- 结构体不能从另外1个结构或者类继承,但是可以实现接口.
- 结构体是值类型 类是引用类型.
15、 String和StringBuilder
- String声明之后在内存中大小是不可修改的,
- StringBuilder可以自由扩展大小(String分配在栈区,StringBuilder分配在堆区)
16、C#有那些集合,各有什么优缺点
Array
- Array:在内存上是连续分配的(可定义长度,也可不定义长度),Array中的元素类型要一样。
- Array通过坐标(索引)访问,读取、修改快—增删慢
ArrayList
- 不定长度的,连续分配的
List
- 也是Array,内存上都是连续摆放的;不定长;泛型,保证类型安全,避免装箱拆箱(都是统一的类型)
LinkedList
- 双向链表 元素不连续分配,每个元素都有记录前后节点。
Queue
- 队列,就是链表 先进先出
Stack:
- 栈 也是链表, 先进后出 先产生的数据最后使用
HashSet:
- hash分布,元素间没关系(不用记录前后节点),动态增加.
SortedSet:
- 排序集合 去重+排序.SortedSet也可以做交差并补.
Hashtable:
- 拿着key计算一个内存地址,然后放入key-value。长度不定,可以动态增加。放入的都是object类型,所以避免不了装箱拆箱。
Dictionary:
- 相当于泛型版本的HashTable.因为数据基于泛型,减少了装箱拆箱的消耗.
SortedDictionary:
- 排序字典,依据key进行排序.因为要排序,所以增删改慢,多了一个排序
SortedList:
- 也是key,value形式,自动排序.不能重复添加,key重复会报错
ConcurrentQueue 线程安全版本的Queue
ConcurrentStack 线程安全版本的Stack
ConcurrentBag (List集合是非线程安全的)ConcurrentBag线程安全版本的对象集合
ConcurrentDictionary 线程安全版本的Dictionary
BlockingCollection 线程安全集合