声明:本文某些内容摘自互联网,仅作学习之用!若无意侵犯你的权利,本人将在24小时内删除!
1.类的三大特性:封装、继承、多态。
2.类和结构的区别:
a) 一个是值类型(结构),一个是引用类型(类),结构struct在传递的时候如果没有指定ref,则传递的是内存中的一分副本,而class则是传递对他的引用。
b) 类在堆中,结构在栈中,类传递的是类在堆中的地址,而结构是在栈中另复制了一个传递,你改变传递过来的结构不会影响原结构。而类是引用,共用一块内存,会改变堆中类的内容。
c) 对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类 Object 继承。
3.new关键字的作用:
a) 作为运算符用来创建一个对象和调用构造函数。
b) 作为修饰符。
c) 用于在泛型声明中约束可能用作类型参数的参数的类型。
new作为修饰符的作用,在用作修饰符时,new关键字可以在派生类中隐藏基类的方法,也就说在使用派生类的方法是调用的方法是New关键字新定义出来的方法,而不是基类的方法。在不使用New关键字来隐藏基类方法也是可以的,编译器会出现一个警告,提示如果有意去隐藏基类的方法,请使用New关键字修饰。
4.override和overload区别:
Item | Override重写(覆盖) | Overload重载 |
位置 | 存在于继承关系的类中 | 存在于同一类中 |
方法名 | 相同 | 相同 |
参数列表 | 相同 | 必须不同 |
返回值 | 相同 | 可以不 |
5.值类型和引用类型的区别:
声明一个值类型变量,编译器会在栈上分配一个空间,这个空间对应着该值类型变量,空间里存储的就是该变量的值。引用类型的实例分配在堆上,新建一个引用类型实例,得到的变量值对应的是该实例的内存分配地址。值类型的值是存放在堆栈中的,改变其值,不改变变量原有的值,而引用类型的值是存放在栈中的,其引用的地址是存放在堆栈中的,改变其值也就改变了变量原有的值。值类型不允许包含null值,然而可空类型可以将null赋值给值类型l。
Item | 值类型 | 引用类型 |
内存分配地点 | 分配在栈中 | 分配在堆中 |
效率 | 效率高,不需要地址转换 | 效率低,需要进行地址转换 |
内存回收 | 使用完后,立即回收 | 使用完后,不是立即回收,等待GC回收 |
赋值操作 | 进行复制,创建一个同值新对象 | 只是对原有对象的引用 |
函数参数与返回值 | 是对象的复制 | 是原有对象的引用,并不产生新的对象 |
类型扩展 | 不易扩展 | 容易扩展,方便与类型扩展 |
6.死锁的必要条件?如何避免?
1) 互斥条件:一个资源每次只能被一个进程使用。
2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁排除的方法:
1)、撤消陷于死锁的全部进程;
2)、逐个撤消陷于死锁的进程,直到死锁不存在;
3)、从陷于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失。
4)、从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态
7.base、this关键字的含义?
1)base 关键字用于从派生类中访问基类的成员:
调用基类上已被其他方法重写的方法。
指定创建派生类实例时应调用的基类构造函数。
基类访问只能在构造函数、实例方法或实例属性访问器中进行。
2)this 关键字引用类的当前实例。 new class()
以下是 this 的常用用途:
限定被相似的名称隐藏的成员 public new
将对象作为参数传递到其他方法
声明索引器。
8.抽象类和接口的异同?
1)抽象类:抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。
2)接口是引用类型的,和抽象类的相似之处有三点:
a、不能实例化;
b、包含未实现的方法声明;
c、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
d、接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。
3)区别:
a、抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
b、一个类一次可以实现若干个接口,但是只能扩展一个父类;
c、接口可以用于支持回调,而继承并不具备这个特点;
d、抽象类不能被密封;
e、抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的。
f、抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现;
g、好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染;
h、尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。
i、如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。
9.静态成员和非静态成员:
1)类的成员要么是静态的,要么是动态的,如果将类的某个成员声明为static,则该成员是静态成员;
2)类的静态成员是属于类所有,不必产生类的实例就可以访问它,就是只用类名就可以访问;
3)静态成员为类的所有实例所共享,无论这个类创建了多少个实例,一个静态成员在内存中只占有一块区域;
4)类的非静态成员属于类的实例所有,每创建一个类的实例,都在内存中为非静态成员开辟了一块区域;
5)静态方法只能访问类例的静态
10.静态类:
它们仅包含静态成员。
它们不能被实例化。
它们是密封的。
它们不能包含实例构造函数(C# 编程指南)。
因此创建静态类与创建仅包含静态成员和私有构造函数的类大致一样。私有构造函数阻止类被实例化。
使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员。编译器将保证不会创建此类的实利。
静态类是密封的,因此不可被继承。静态类不能包含构造函数,但仍可声明静态构造函数以分配初始值或设置某个静态状态。
11.collection和collections的区别:
Collection是集合类的上级接口,Collections是针对集合类的一个帮助类,它提供一系列静态方法来实现对各种集合的搜索,排序,线程安全化操作。
12.堆和栈的区别:
Heap是堆,空间是由手动操作分配和释放的,它的存储区很大的自由存储区。
Stack是栈,是由是操作系统自动分配和释放的,栈上的空间是有限的。程序在编译期间变量和函数分配内存都是在栈上进行的,且在运行时函数调用时的参数的传递也是在栈上进行的。
13.readonly 关键字与 const 关键字:
const 字段只能在该字段的声明中初始化。
readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。
const 字段是编译时常数,而 readonly 字段可用于运行时常数。
const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明。
const 对于引用类型的常数,可能的值只能是 string 和 null。readonly可以是任何类型
14.进程和线程:
进程是比线程大的程序运行单元,都是由操作系统所体会的系统运行单元,一个程序中至少要有一个进程,有一个进程中,至少要有一个线程,线程的划分尺度要比进程要小,进程拥有独立的内存单元,线程是共享内存,从而极大的提高了程序的运行效率同一个进程中的多个线程可以并发执行。
15.什么叫应用程序域?什么是托管代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
应用程序域:就是为安全性,可靠性,隔离性,和版本控制,及卸载程序提供的隔离边界。它通常由运行库宿主创建,应用程序域提供了一个更安全,用途更广的处理单元。
托管代码:使用CLR编译语言编辑器开发编写的代码就叫托管代码。
装箱和拆箱:是把值类型转换为引用类型的过程,是隐式的,相反的过程就是拆箱,是显式的。
CTS是公共类型系统,CLS是公共语言规范,CLR公共语言运行库。
强类型系统:每个变量和对象都必须具有申明类型。
16.c#中类的默认访问修饰符,是private还是internal?
默认是internal :
C#用多种修饰符来表达类的不同性质。根据其保护级C#的类有五种不同的限制修饰符:
public可以被任意存取;
protected只可以被本类和其继承子类存取;
internal只可以被本组合体(Assembly)内所有的类存取,组合体是C#语言中类被组合后的逻辑单位和物理单位,其编译后的文件扩展名往往是“.DLL”或“.EXE”。
protected internal唯一的一种组合限制修饰符,它只可以被本组合体内所有的类和这些类的继承子类所存取。
private只可以被本类所存取。
如果不是嵌套的类,命名空间或编译单元内的类只有public和internal两种修饰。
new修饰符只能用于嵌套的类,表示对继承父类同名类型的隐藏。
abstract用来修饰抽象类,表示该类只能作为父类被用于继承,而不能进行对象实例化。抽象类可以包含抽象的成员,但这并非必须。abstract不能和new同时用。下面是抽象类用法的伪码:
abstract class A
{
public abstract void F();
}
abstract class B: A
{
public void G() {}
}
class C: B
{
public override void F()
{
//方法F的实现
}
}
抽象类A内含一个抽象方法F(),它不能被实例化。类B继承自类A,其内包含了一个实例方法G(),但并没有实现抽象方法F(),所以仍然必须声明为抽象类。类C继承自类B,实现类抽象方法F(),于是可以进行对象实例化。
sealed用来修饰类为密封类,阻止该类被继承。同时对一个类作abstract和sealed的修饰是没有意义的,也是被禁止的。
17.c# 类的public private internal protected的区别:
public 修饰的类,可以在整个系统的任意地方调用,是完全公开的;
private 相反的,只能在类内部调用.任何实例,无法调用private调用;
internal 仅为同项目(这里的项目是只单独的项目,而不是整个解决方案)调用,或者说同一命名空间内调用;
protected 自己及自己的子类可以调用
18.error和exception
Error和Exception都继承自Throwable,他们下列不同处:
Exceptions
1.可以是 可被控制(checked) 或 不可控制的(unchecked)
2.表示一个由程序员导致的错误
3.应该在应用程序级被处理
Errors
1.总是 不可控制的(unchecked)
2.经常用来用于表示系统错误或低层资源的错误
3.如何可能的话,应该在系统级被捕捉