第一周C#学习/200道测试题分析

第一周C#学习/200道测试题分析

.NET、C#和ASP.NET三者之间的区别

  1. .NET是微软公司下的一个跨语言开发平台,.NET核心就是.NET Framwork(.NET框架)是.NET程序开发和运行的环境,在这个平台下可以用不同的语言进行开发。
  2. .NET Core是一个新的开源并且跨平台的用来构建可以所有操作系统(包括Windows, Mac, and Linux)上面运行的应用的的框架。
  3. C#是一个.NET平台下的一个程序设计语言,仅仅是一个语言。是运行在.net CLR(公共语言进行时)上的,用于创建应用程序的高级语言。
  4. 第一周C#学习/200道测试题分析

名词解释类:

类、对象、方法和属性详解

  1. 对象:现实世界中的实体(世间万物皆对象)
  2. 类:具有相似属性和方法的对象的集合
  3. 面向对象程序设计的特点:封装 继承 多态
  4. 对象的三要素:属性(对象是什么)、方法(对象能做什么)、事件(对象如何响应)

函数签名:

就是把函数方法体去掉以后剩下的东西(返回值、参数、调用方式等) ,可以明确区分函数的不同。

※ 基本值类型、默认值及后缀

  1. bool System.Boolean 4Byte 32bit布尔型变量 逻辑值,true或者false,默认值为false
  2. byte System.Byte 1Byte 8bit无符号整数无符号的字节,所存储的值的范围是0~255,默认值为0
  3. char System.Char 2Byte 16bit 无符号Unicode字符,默认值为’\0’
  4. decimal System.Decimal16Byte 128bit十进制数不遵守四舍五入规则的十进制数,28个有效数字,通常用于财务方面的计算,默认值为0.0m
  5. double System.Double 8Byte 64bit双精度的浮点类型,默认值为0.0d
  6. float System.Single 4Byte 32bit单精度的浮点类型,默认值为0.0f
  7. int System.Int32 4Byte 32bit有符号整数,默认值为0
  8. object System.Object 指向类实例的引用,默认值为null
  9. string System.String 指向字符串对象的引用,默认值为null
  10. 第一周C#学习/200道测试题分析

浮点数精度损失:

所有的浮点型变量都存在精度损失的问题。
float32位,8位表示指数,23位表示尾数;int纯32位存储。另一方面,2^23 = 8388608,一共七位,绝对能保证的为6位,float的精度为6~7位有效数字

※ 类型转换:

第一周C#学习/200道测试题分析

  1. 隐式转换:对于内置数值类型,如果要存储的值无需截断或四舍五入即可适应变量,则可以进行隐式转换。 对于整型类型,这意味着源类型的范围是目标类型范围的正确子集。
  2. 显示转换(强制转换): 强制转换是显式告知编译器你打算进行转换且你知道可能会发生数据丢失的一种方式。 若要执行强制转换,请在要转换的值或变量前面的括号中指定要强制转换到的类型。a = (类型名)b;
  3. 引用类型之间的强制转换操作不会更改基础对象的运行时类型;它只更改用作对该对象引用的值的类型。
  4. 子类强转父类:实际上依然是子类,调用父类中定义的方法和变量;如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;
  5. C#数据类型及其转换/封箱拆箱
  6. C#-子类和父类之间的转换/里氏转换原则
  7. SOLID 原则

类型术语:

  1. 强/弱类型:强类型指一旦变量被指定某类型,如果不经过强制转换,不会再有变动。弱类型相反,同一变量可赋予不同类型的值。但注意C#中与JS中的var类型的不同。
  2. 静态/动态类型语言:静态是编译期间做检查数据类型的语言;动态是运行期间做检查数据类型的语言;
  3. 深拷贝/浅拷贝(只针对Object和Array):深拷贝会创造一模一样的对象,不共享内存,互不影响;浅拷贝会复制指向某对象的指针而非对象本身,共享内存,相互影响。
    形参和实参:
  4. 形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。
  5. 实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
  6. 形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

※ 实例变量、类变量与局部变量:

  1. 实例变量:也叫对象变量、类成员变量;从属于类由类生成对象时,才分配存储空间,各对象间的实例变量互不干扰,能通过对象的引用来访问实例变量。
  2. 类变量:也叫静态变量,是一种比较特殊的实例变量,用static关键字修饰;一个类的静态变量,所有由这类生成的对象都共用这个类变量,类装载时就分配存储空间。与类绑定,不再受实例影响。
  3. 局部变量:方法中或者某局部块中声明定义的变量或方法的参数被称为局部变量,他们只存在于创建他们的block里({}之间)无法在block外进行任何操作,如读取、赋值。

※ 引用类型和值类型:

  1. 值类型(Value types):
    • 基础数据类型(string类型除外):包括整型、浮点型、十进制型、布尔型。
    • 结构类型:就是 struct 型
    • 枚举类型:就是 enum 型
    a. 值类型变量可以直接分配给一个值。
    b. 内存存储:值类型和指针总是放在它们被声明的地方。
  2. 引用类型(Reference types):
    • 有六种:class(类)、interface(接口)、delegate(委托)、object(通用对象)、string(字符串)、数组(即便有元素为值类型,如int[ ])
    a. 引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。
    b. 内存存储:引用类型保存在托管堆上,但在托管栈上会生成一个指向这个堆的指针引用。
  3. 特点:所有值类型的数据都无法为null的,声明后必须赋以初值;引用类型才允许为null。
  4. 内存分配——静态存储区 栈 堆
  5. C#中的值类型和引用类型
  6. 第一周C#学习/200道测试题分析

其中的class1为引用类型,其中整型a为值类型,但跟随实例存储在堆中。

※ 拆箱与封箱(影响性能)

简单来说:
• 封箱就是将值类型转换为引用类型。
• 拆箱就是将引用类型转换为值类型。
本质上说:
• 封箱是在值类型转换为引用类型对象时,将值类型字段拷贝到托管堆上发生的内存分配(与引用类型内存分配以及对数据操作是一模一样的)。
• 拆箱把托管堆上值类型数据传递到托管栈。

※ 重载和重写:

重载体现了多态性:
• 多态是指子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。多态这种特性也需要编程语言提供特殊的语法机制来实现,比如继承、接口类、duck-typing。多态可以提高代码的扩展性和复用性,是很多设计模式、设计原则、编程技巧的代码实现基础。

  1. 重载(Overloading):是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。
    • 多态性:调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性的体现。
    • 条件:1.必须在同一个类中2.方法名必须相同3.参数列表不能相同。
  2. 重写(Override):相当于覆盖。
    • 条件:1. 在不同的类中 2. 发生方法重写的两个方法返回值,方法名,参数列表必须完全一致 3. 子类抛出的异常不能超过父类相应的方法抛出的异常 4. 子类方法的访问级别不能低于父类相应方法的访问级别(public,package,protected, private)5.方法体不同
    • 要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是 virtual、abstract 或 override 的。

※ 继承:

• 继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
<访问修饰符> class <基类> {…}
class <派生类> : <基类>{…}
• 当我们调用子类构造方法时,系统会首先调用父类的构造方法,然后再调用子类构造方法。 调用的方式有两种:
• 隐式调用父类构造方法,没有指定调用父类哪个构造方法时,会调用父类无参构造方法。
• 通过 base 关键字显式调用父类构造方法。

特殊符号表达式类:

字符串中的{ }:

与c++取地址概念相同,从0开始。后面的参数用逗号隔开。

  1. Console.WriteLine("{0}",a) ;
  2. Console.WriteLine($"{a}");

Lambda表达式()=>:

  1. 代替委托实例,=>为声明运算符; 若要创建 Lambda 表达式,需要在 Lambda 运算符左侧指定输入参数(如果有),然后在另一侧输入表达式或语句块。
  2. 表达式Lambda:(input-parameters) => expression
  3. 语句Lambda:(input-parameters) => { }
  4. 任何 Lambda 表达式都可以转换为委托类型。 Lambda 表达式可以转换的委托类型由其参数和返回值的类型定义。
  5. 第一周C#学习/200道测试题分析

委托(Delegate):

  1. 委托使得可以将方法当作另一个方法的参数来进行传递。所有的委托(Delegate)都派生自 System.Delegate 类,类似于 C的函数指针。
  2. 委托的实现包括4个条件:
    a. 声明委托类型,且必须有个方法包含了要执行的代码。
    b. 必须创建一个委托实例。
    c. 必须调用委托实例。
  3. 委托对象可使用 “+” 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。

※ 事件、EventHandler:

• 在C#中的事件基于委托模型。委托模型遵守观察者设计模式,使订阅者(接收或处理事件的类)能够向提供方(发送或引发事件的类)注册并接收相关通知。
• EventHandler即事件委托,表示用于处理不具有事件数据的事件的方法。字面上理解就是一个事件处理器,将一个事件与处理事件的方法联系起来的一种机制。
• 【C#】EventHandler委托详解

关键字类:

Xunit中Assert的API:

第一周C#学习/200道测试题分析

this & base:

  1. this关键字:
    a. 引用类的当前实例。
    b. 注意:静态成员方法中不能使用this关键字,this关键字只能在实例构造函数、实例方法或实例访问器中使用
  2. base关键字:
    a. 用于从派生类中访问基类的成员;
    b. 指定创建派生类实例时调用基类构造函数;
    c. 调用基类上已被重写的方法。
    d. 注意:静态成员方法中不能使用base关键字,base关键字只能在实例构造函数、实例方法或实例访问器中使用
  3. base和this访问的都是类的实例,也就是对象,而静态成员只能由类来访问,不能由对象来访问。

ApendLine:

将默认的行终止符加到字符串结尾。----->\r\n

  1. \r回车,从最老的打字机引入的概念,表示回到本行的开始位置;
  2. \n换行,同样来自打印技术的术语,表示跳转到下一行。
  3. \r\n连用,表示跳到下一行,并且返回到下一行的起始位置
  4. \t 一个占位符,表式空格

Equal/==:

• Equal比较地址内容。
• ==比较值内容。
• ===
• Object.ReferenceEquals(obj1,obj2)它是比较的是内存地址是否相等
诸如String、Date等类对equals方法进行了重写的话,所以比较的是所指向的对象的内容。。

Set&Get方法:

面向对象的基本原则:封装(Encapsulation)、多态(Polymorphism)、继承(Inheritance)。
这里体现了封装的特性:
• 封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式来访问内部信息或者数据。它需要编程语言提供权限访问
• 。控制语法来支持,例如 Java 中的 private、protected、public 关键字。
• 封装特性存在的意义,一方面是保护数据不被随意修改,提高代码的可维护性;另一方面是仅暴露有限的必要接口
第一周C#学习/200道测试题分析

当实例化第一个“person”这个类时,系统在分配内存空间时对name属性直接分配内存,之后对name属性的操作也是直接操作内存中name属性所在的这个块;
而当实例化第二个“人”类型时,系统会先分配一个叫name的private私有的内存空间(此处的name对于类的内部使用,Name对于外部操作使用,要有所区分),之后的读与写的操作都是通过Name这个public的类似于指针的东西来关联name进行,以此达到封装的目的,并且通过get和set关键字也可以控制可读还是可写。

Set:

包含不重复元素的集合称为“集(set)”。.NET Framework包含两个集HashSet和SortedSet,它们都实现ISet接口。HashSet集包含不重复元素的无序列表,SortedSet集包含不重复元素的有序列表。

List:

• SortedList :代表了一系列按照键来排序的键/值对,这些键值对可以通过键和索引来访问。

IEnumerator 迭代器:

• 最初,枚举数定位在集合中第一个元素的前面。 在读取 Current的值之前,必须调用 MoveNext 方法将枚举器前移到集合的第一个元素;否则,Current 未定义。
• 在调用 Current 或 MoveNext 之前,Reset 返回同一对象。 MoveNext 将 Current 设置为下一个元素。
• 如果 MoveNext 越过集合的末尾,则枚举器将定位到集合中的最后一个元素之后,MoveNext 返回 false。 当枚举器位于此位置时,对 MoveNext 的后续调用也将返回 false。 如果最后一个调用 MoveNext 返回 false,则 Current 未定义。
• 若要再次将 Current 设置为集合的第一个元素,可以调用 Reset(如果已实现),后跟 MoveNext。 如果未实现 Reset,则必须创建新的枚举器实例以返回到集合的第一个元素。

Enum枚举:

enums枚举是值类型,数据直接存储在栈中,而不是使用引用和真实数据的隔离方式来存储。
yield上下文关联词:
• 用来实现迭代器的功能:yield return;yield break;

Using:

• using 语句(using(){}):定义一个范围,在此范围的末尾将释放对象。using 语句中使用的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。Dispose方法是using语句必需执行的(在结束时),必要时可通过重写达到预期结果。
• using 指令为命名空间创建别名,或导入在其他命名空间中定义的类型。
• using static 指令导入单个类的成员。
Type.FullName Property:
• 获取该类型的完全限定名称,包括其命名空间,但不包括程序集。
• 当确定到类中某方法时,命名空间.父类名.子类名+方法名

Nullable可空类型:

  1. nullable 类型(可空类型):可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。是一个轻量级的值类型。
  2. 基本类型+? : 单问号用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是 NullAble 类型的。
  3. ?? : 双问号 可用于判断一个变量在为 null 时返回一个指定的值。

String、StringBuilder、字符串常量池:

C# String与StringBuilder
C#和.NET中的字符串
StringBuilder Class API

LINQ查询操作:

Linq查询有两种形式的语法:查询语法和方法语法:
31. 查询语法:使用查询表达式的形式,类似SQL语句( var value00 = from item in array1 select item;)
32. 方法语法:使用方法调用的形式(value00 = array1.Select(item => item);)

Exception类:

IndexOutOfRangeException(数组越界错误);InvalidOperationException(无效操作错误,包含许多);InvalidCastException(无效映射错误);DivideByZeroException(除0错误);OverflowException(超出类型取值范围错误)

进制转换/运算符:

  1. 算术运算符
  2. &:二进制与运算;|:二进制或运算;^:二进制异或运算;~:二进制补码运算(反转);<</>>:二进制左移/右移;
  3. &&:与运算;||:或运算;!:非运算;
  4. 0xff:为C语言中十六进制转化为二进制的前缀表示方法,看后面的两位对应的数字。
  5. ?? 运算符:左不为空则返回该值,若空则计算右,若不为空则返回该值。若无,返回null;
  6. 补码、反码:
    a. 反码的表示方法是:
    • 正数的反码是其本身
    • 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
    b. 补码的表示方法是:
    • 正数的补码就是其本身
    • 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
  7. 二进制非运算~:非运算就是原数二进制的补码,再反码,再回原码的过程。
    第一周C#学习/200道测试题分析