(前言) 作为一名.NET技术开发人员,只要基础扎实,完全可以通过不断学习,轻松游走于各个 .NET 应用领域。

(P6)

经验丰富的应聘者,其简历往往只有一页。

 

在受教育经历方面,只需要填写最高层次的受教育经历或培训即可,不要将简历写得像档案一样繁琐。

 

专业经验对于计算机方面的岗位非常重要。

 

(P7) 如果应聘者已经有过工作经验,则一定要给出曾经工作的详细情况,以及完成项目的详细情况,使用人企业迅速判断应聘者的能力。

 

(P8) 如果应聘者有工作经验,用人企业看重的是应聘者曾经工作的具体细节,而不是跳槽次数。所以应聘者不需要列举太多的工作经历。作为IT技术方面的岗位,应聘者应注明自己的技术博客,作为自己技术实力的展示,最后应将自己曾经参与的项目做详细描述。

 

(P9) 应聘者要主动获取有关用人企业的信息,了解企业的性质、规模、业务信息以及企业文化等。

 

(P11) 算法是程序设计的核心之一,高效率的程序必然有良好的算法支持。针对不同问题,算法虽然有多种,但面试中只会包含比较常见的,和工作岗位密切相关的算法题目。

 

(P14) 社会处在高速发展阶段,“物竞天择,适者生存”,凡事“预则立,不预则废”。

 

(P15) 20 - 30 岁年龄段成为职业生涯的黄金期,人生的冲刺阶段。如果个人在这段时期没有做好完善的职业规划,或者没有将其有效地实施,则其发展将颇为坎坷。

 

(P18) 罗马不是一天建成的,要实现自己的职业梦想,必须积累足够的实力和经验。为了完成这些积累,必须选择适合自己的发展平台。

 

(P19)

计算机编程语言技术无所谓好坏,职业规划不应该以编程语言或技术平台为主线进行设计,而应当根据个人所适合的技术应用方向去进行深入的学习和实践,直至成为专家。懂多种技术不如精通某种技术。

 

对于软件行业,编程的技术是核心竞争力。

 

(P23) 类通过构造函数生成对象。

 

(P25) 类是用于描述对象的特征、状态和行为的模板。

 

(P26) 某些时候需要访问私有类成员,可通过 Get 和 Set 访问器读取。

 

(P28) C# 默认的类访问修饰符为 internal

 

(P29) 即使派生类和基类在不同的程序集中,派生类仍可访问基类的protected 修饰符成员。

 

(P31) 属性提供了比较灵活的数据访问方法,编写代码时注意显式声明的 Set 访问符必须比属性修饰符更严格。当 Get 或 Set 访问器没有显式访问修饰符时,其默认访问限制和属性一致。

 

(P33)

sealed 修饰符用于修饰类、实例方法和属性;

 

sealed 修饰符和 abstract 修饰符是相互排斥的,无法共存;

 

sealed 修饰实例方法或属性时,必须和 override 一起使用;

 

(P35)

当类中某些成员不需要创建实例实现,则可将其声明为静态成员;

 

类中没有和对象实例相关的成员,即类体中只有静态成员时,可以声明该类为静态类。静态类无法用“new”创建对象,所以不能编写构造函数,并且该类是密封类(既无法被继承)。

 

声明静态类时,必须保证其内含成员全部为静态成员;

 

(P37)

没有参数的构造函数被称为默认构造函数,如果非静态类的类体中没有声明构造函数,类将自动提供一个默认构造函数,并将类成员初始化为默认值;

 

结构类型 (Struct) 是值类型,不需要显式声明默认构造函数,编译器将自动生成默认构造函数。当用 (new) 运算符实例化时默认构造函数才被调用,并将成员初始化为默认值;

 

静态构造函数在创建实例前或引用静态成员前自动调用,一般用于对静态成员的操作。

 

私有的默认构造函数,可以阻止类在外部创建类的实例。

 

(P39)

函数重载 —— 给函数定义不同的参数个数或不同的参数类型,可以声明不同的同名函数(返回值也可不同);

 

派生类中只有继承的虚方法或抽象方法可以被重写,而静态方法不能被重写;

 

(P40) 派生类所继承的非密封重写方法(即 override 方法)也可以重写,因为该方法是被重写过的。

 

(P43)

接口与抽象类的主要区别:

1. 抽象类只能派生类,而接口可以派生类和结构;

2. 抽象类的派生类可以是抽象类,即使抽象成员在派生类中不一定被完全实现。而接口要求其派生类结构必须完全实现其成员;

3. 抽象类可以包含已经实现的成员,可以包含字段。而接口只包含未实现的成员,不能包含字段,并且接口及所含成员必须为 public 访问级别。

4. 类只能继承一个抽象类,但可以继承(实现)多个接口。

 

(P45)

抽象方法的属性是隐性的 virtual ,所以派生类实现抽象方法或属性必须使用 override 关键字;

 

抽象类的抽象成员不能使用 virtual 或 static 修饰;

 

(P51)

“this”:用于引用类的当前实例;

 

“base”:用于派生类访问基类成员;

 

(P53)

静态成员和实例无关,所以静态成员中不能使用 this 关键字;

 

this 仅限于构造函数和方法成员中使用;

 

base 关键字访问基类的成员时,必须保持基类成员有相应的访问权限;

 

(P53) 索引器可以使客户程序很方便地访问类中集合或数组,访问方法类似于通过索引访问数组,并且索引器向客户程序隐藏了内部的数据结构;

 

(P57) 索引器的访问器不能添加修饰符;

 

(P58)

ASP.NET 在首次执行时进行编译,编译后的程序遇到请求可以直接运行;

 

ASP.NET 还提供了预编译功能,可以在部署网站之前先进行编译,预编译可以改进首次请求网站的性能;

 

ASP.NET 就是网页版的 .NET 应用程序;

 

(P59) ActiveX Data Object (ADO) 是 ASP 内置的组件,其操作的数据源不局限于数据库,还可以是其它数据表,例如 Excel 、文本文件等,即 ODBC 能存取的所有数据源;

 

(P60)

ADO.NET 核心部分是 .NET Data Provider 和 DataSet 对象。 前者被称为数据提供者,后者被称为数据结果集对象。 .NET Data Provider 包括 Connection、 Command、DataReader 和 DataAdapter 这四种对象。

 

使用 ADO.NET 需要引用相应的命名空间,不同的数据库,引用不同的命名空间,但是都需要引用共同的命名空间 Syste.Data;

 

(P61)

.NET 程序集是自我描述的安装单元,程序集是一个逻辑单元,而非一个文件。程序集可以包含元数据的多个文件,也可以是一个 DLL 或 EXE 文件。程序集作为 .NET 可执行程序或 .NET 可执行程序的一部分,包含了程序的文件集合资源文件。

 

程序集分为私有程序集和共享程序集,私有程序集是创建 .NET 项目时默认的,也是比较常用的方式。私有程序集以可执行文件或库的形式提供应用程序,库中的代码只服务于这个应用程序。而共享程序集是一个公共库,服务于系统中所有程序。共享程序集必须安装到 .NET 的指定目录中,而其它被服务的程序不需要知道安装的地址。

 

任何 .NET 程序均于程序集构成,程序集是包含已编译的面向 .NET Framework 代码的逻辑单元。程序集包含描述自身的元数据,这种元数据位于程序集清单中,用于检查版本以及自身的完整性。

 

动态程序集位于内存中,而非存储于文件中。

 

应用程序域是 .NET 中程序的“边界”。相对于进程边界,应用程序域边界范围更小。使用应用程序域可分离组件,并且不会导致类似于进程的性能问题。

 

进程有独立的虚拟内存,以保证进程之间的内存无法互写。

 

一个进程可以容纳多个应用程序域,在没有代理的情况下,不同的应用程序域中的实例和静态成员无法共享,这样做保证了安全性。

 

(P65)

中间语言采用即时编译,也称为 JIT 编译,这种编译方式只编译调用的代码,而不是所有的代码编译过的部分将被存储在内存中,再执行时不需要重复编译。退出程序时,已编译的代码才会被清除。

 

.NET 的 CLR 和 JVM、AVM 是类似的;

 

(P69) .NET Framework 的文件形式主要由公共语言进行时 (CLR) 和 基类库 (BCL) 组成,前者提供进行库环境,而后者提供丰富的类库,适用于全部 .NET 编译语言编写的托管代码调用。

 

(P70) 命名空间只是 .NET 组织各种相关类型的逻辑形式。

 

(P71) C# 的数据类型分为值类型和引用类型,值类型变量包含数据,而引用类型变量只包含数据的内存地址。值类型离开其定义的作用域,将被从内存中清除,而引用类型引用的对象一直存留在托管堆, .NET 收集器自动将其销毁。

 

(P72) 值类型变量作为函数参数传递,只是传递其副本;引用类型变量作为函数参数传递,将传递数据引用,函数体对引用的操作将改变该数据的值。

 

(P73)

CTS 中所有类型都是对象,其共同的基类为 System.Object;

 

CTS 的值类型可分为简单类型、枚举类型和结构类型,而引用类型则分为类类型、数组类型、接口类型和委托类型。并且值类型是密封的,不能派生其它类型,必须继承 System.Value 。相反,引用类型可以继承除 System.Value 以外的任何非封装类型。

 

(P73)

C# 的装箱是创建引用类型变量保存值类型变量值,而拆箱是装箱的逆向操作,即将引用类型的值转换为值类型变量的值。

 

装箱的过程实际是创建了一个新对象,将值类型变量在堆栈的数据值复制到托管堆的新对象上,并由对象类型的变量所引用。拆箱的过程是在堆栈上创建新的值类型的变量,并把托管堆上的对象存储的数据值复制到新的值类型变量。

 

不过在拆箱的过程中,须保证值类型的数据类型和托管堆对应值的数据类型保持一致,否则拆箱过程将产生异常。

 

(P75) 使用 Enum 类的 GetValue()方法,返回 System.Array 类的实例;

 

(P79)

结构可以声明带参数的构造函数,其使用方法和类一致;

 

值类型变量一旦超出作用域即被销毁,而引用类型由内存垃圾处理机制完成收集。

 

(P81)

如果没有修饰符则按值传递参数;

 

“out” —— 表示引用传递参数,但函数必须将其赋值;

 

“params” —— 表示形参为不去定个数的一组实参,这组实参必须具有相同数据类型;

 

“ref” —— 表示按引用传递参数,实参传递前需要赋初始值,但在函数中可以不被赋值;

 

(P84)

实例和静态方法使用参数修饰符无区别;

 

C# 3.0 提供了 var 关键字,用于隐式声明局部变量的数据类型,由编译器根据初始值推测具体的数据类型。

 

(P88) 将值类型加上“?”后缀即可声明这种特殊的可空类型变量,其对应的数据范围是原值类型的底层类型范围加上 null 值;

 

(P90) C# 3.0 提供的扩展方法用于扩展指定类型的功能,而不修改类型内部的代码,并且方法可以单独定义在外部程序集。

 

(P93)

1. 扩展方法所属类必须为静态非泛型类,即扩展方法也是静态方法;

2. 扩展方法的第一个参数为被扩展的类型实例,并且必须使用 this 进行修饰;

3. 扩展方法从第2个参数开始对应被扩展类型实例所传递的参数列表,即扩展类型实例传递的第1个参数对应扩展方法定义的第2个参数,依此类推;

4. 被扩展类型实例可像调用类型内部定义的实例方法一样调用扩展方法。

 

(P95)

C# 3.0 提供的对象构造器,可以非常灵活地初始化对象成员,并且无须定义过多的重载构造桉函数。

 

C# 3.0 可以通过 var 关键字和对象构造器直接定义没有名称(编译器分配名称)的类,同时创建并初始化类成员。匿名类型直接派生于 System.Object 类,并且重写了3个方法,分别为: Equals()方法、GetHashCode()方法和 ToString()方法;

 

(P97)

匿名类型的名称在程序中无法访问;

 

匿名类型在编译后仍然是一个普通的密封类(不可派生其它类),只是名称由编译器分配;

 

(P100)

分部方法可以是静态方法,但必须是隐式的私有方法,并且是无返回值的方法;

 

分部方法只能将方法分为两部分,即声明部分和实现部分;

 

分部方法只用于分部类型,方法的声明部分和实现部分;

 

分部方法可以有 ref 参数,但不能有 out 参数;

 

不允许将委托转换为分部方法;

 

(P103) 用 Viual Studio 2005 / 2008 创建的项目,其属性默认声明了 Debug 和 Trace 等号;

 

(P103)

栈指堆栈,堆指托管堆;

 

堆栈用于存储非实例成员的值类型数据,以及引用类型的变量(用于存储引用类型实例)

 

托管堆用于存储引用类型实例的数据及相关信息;

 

(P104)

堆栈从内存地址高位开始存储数据;

 

托管堆从内存地址低位开始存数数据;

 

(P105)

在常见的 32 位 Windows 操作系统中,单个进程的寻址能力为4GB;

 

Windows 操作系统通过虚拟寻址系统管理数据在内存中存储方式,虚拟寻址将持续的内存地址转化为物理内存的实际地址;

 

操作系统常常将物理内存和虚拟内存配合使用。在程序开发中,只需要将其看做一块连续的内存空间即可;

 

(P106)

生命周期越短的对象(新创建的对象)代数越小,反之代数越大。

 

第2代对象被检查后仍然是第2代,不会继续升级了;

 

垃圾收集器回收时,当前程序进程的所有活动线程将挂起;

 

(P108) GC 类的 WaitForPendingFinalizers() 方法,该方法挂起当前线程直到所有对象被终结,所以一般用在 Collect() 方法之后;

 

(P112)

System.Object 类中析构函数代码如下所示:

protected virtual void Finalize() {}

 

(P113) Dispose() 方法不仅可以清理非托管资源的代码,还可以与其它托管对象通信。因为 Dispose() 是显式调用,所以开发者可以自己把握 Dispose() 方法调用的时机而不需要担心其他托管对象是否已被自动销毁。显式调用 Dispose() 方法可以在非托管资源用完后马上将其清理,相比析构函数更加有效。

 

(P112)

Suppress Finalize() 方法通知垃圾回收器该对象不需要被终结,即避免了垃圾收集器再次调用析构函数;

 

由于结构为值类型,所以无法使用析构函数;

 

重写析构函数不能使用 override 修饰符,而是使用“~类名称()”

 

如果 CLR 检测到对象重写了默认析构函数,将会把对象标记为可终结对象,并把对象的地址引用保存在垃圾收集器管理的终结队列中。在将要发生回收时,将终结队列所指的对象复制到终结对象列表中,第1次回收时调用析构函数,不会删除对象,只有在第2次回收时才真正删除对象;

 

(P120)

没有异常类型参数的 catch 代码块一般很少使用,如果使用时应放在最后;

 

没有参数的 catch 代码块,处理 C# 以外的语言或非托管代码抛出的异常类型;

 

(P121) Data 属性从 System.Exception 类中继承而来的属性,用于存储“名称/值”对;

 

(P123) 在.NET程序的各种异常类型中,基类库所定义的异常由 CLR 创建并抛出异常,这种异常被称为系统级异常,系统级异常共有的基类为 System.SystemException 。为了和系统级异常进行区别,自定义异常类应继承于 System.ApplicationException 类,这种异常被称为应用程序异常;

 

(P127)

“==”运算在子没有重载的情况下,比较的是对象引用;

 

System.Object 类提供了3种方法比较引用类型是否相等,分别为虚拟版本的 Equals()方法、静态 Equals()方法和静态Reference.Equals()方法;

 

System.Object类定义的3种方法都是用于比较两个对象是否指向堆上相同对象,并且比较的是引用地址,如果相等则返回 true;

 

静态的 Reference.Equals()方法接收两个 object 参数,如果两个引用类型引用均为 null 时,结果为 true;

 

用 Reference.Equals()方法比较2个值类型变量毫无意义,结果肯定是 False,即使是2个值相等的变量。因为在 Reference.Equals() 方法比较前,被比较的值类型变量将会被装箱操作,隐性地创建2个不同对象,所以其地址引用也将不同;

 

(P128) 虚拟的 Equals()方法是实例方法,它由实例直接调用并接收一个 object 参数,这个参数同样用于比较引用类型的引用地址是否相等。其派生类一般将其重写为比较对象的状态值,即基于值的引用;

 

(P128)

表示某个值或一组值的任何类都应该重写 Equals()方法。如果类型要实现 IComparable 接口, 则它同样应该重写 Equals() 方法;

 

静态的Equals()方法和虚拟的Equals()方法一样,只是静态调用时接收两个 object 参数,使用时调用实例 Equals()方法。所以当虚拟 Equals()方法被重写为基于值的相等比较时,该方法相当于被重写;

 

未重载“==”运算符的引用类型,“==”运算符用于比较两个引用类型的引用地址,跟引用类型的 Equals()方法一致。所以“==”运算符也被称为第4种判断相等性的方法;

 

(P133)

StreamWriter 对象名称 = new StremWriter(文件路径);

 

StreamReader 对象名称 = new StreamReader(文件路径, 是否追加内容, 字符编码);

 

StreamWriter 类和 StreamReader 类的对象使用后,调用 Close()方法关闭,完成文件数据更新;

 

File 类也提供了静态方法提供类似的功能,如果只需要一次性将字符串写入文件,File 类的静态方法 WriteAllText() 更为简便, WriteAllText() 方法常用的调用方式如以下代码所示:

 

File.WriteAllText(文件路径, 字符串内容, 字符编码);

 

此方法编写较为简单,功能和 StreamWriter 对象类似,可以用 File 类的静态方法 ReadAllText()的常用调用方式读取,如以下代码所示:

 

File.ReadAllText(文件路径, 字符编码);

 

字符编码是将字节和字符的格式转换规范;

 

UTF-8 编码 是国际文本信息交换的主要方法,它可以支持世界上的所有语言,在实际应用中为了使文件使用更广泛,建议采用 UTF-8 编码;

 

(P136) File 类有部分独特的成员,提供更简便的文件操作;

 

(P138) 复制文件则可以直接使用 File 类的 Copy()静态方法:

File.Copy(原文件路径, 目标路径 + Path.GetFileName(原文件路径), 是否覆盖);

 

(P140) System.IO 命名空间提供了 FileSystemWatcher 类,用于监视(观察)所指定的目录下文件及子目录的变化;

 

(P141) FileSystemWatcher 类可以监视本地计算机、网络驱动器或远程计算机上的文件;

 

(P144) 异常处理语句结构是大型程序中容易遗漏的部分,读者应保持添加异常处理的习惯;

 

(P146)

// Ienumerable 接口的成员

IEnumerator GetEnumerator();

 

// IEnumerator 接口的成员

bool MoveNext();

object Current {get;}

void Reset();

 

(P147)

迭代器方法只需要在类型中直接定义一个类似的 GetEnumerator()方法,使用 foreach 语句遍历集合,并用 yield return 返回每个子项;

 

迭代器方法不需要显式实现2个接口。实际上 IEnumerable 接口和 IEnumerator 接口被迭代器方法隐藏实现,使用时不需要关心如何实现。

 

(P151)

需要对集合类型的子项按指定的键值排序,可以用实现System.IComparable 接口的 CompareTo()方法完成;

 

如果集合类型的子项是自定义类型的对象,必须在自定义中实现 System.IComprable 接口的 CompareTo()方法,才能完成排序的功能;

 

(P152)

使用“.”运算符连接接口名称和所需要实现的方法名称,以显式方式实现接口方法,可以有效地避免方法重名等问题。

 

如果集合类型的子项需要比较多个键值(相对于对象的多个属性或其他值),就需要定义一个实现 System.Collections.IComparer 接口 Compare()方法的辅助类;

 

利用 Sort()方法的重载版本,可以根据不同情况,灵活地对数组子项进行不同键值的排序;

 

IComparable 接口的命名空间是 System ,而 IComparer 接口命名空间是 System.Collections;

 

(P157)

Array 类在 System命名空间下, ArrayList 在 Syste.Collections 命名空间下;

 

使用默认构造函数创建的 ArrayList 类对象默认初始值容量为16;

 

ArrayList 类还提供了 ToArray()方法,用于将 ArrayList 内容转换为 object 类型的数组并返回;

 

(P165)

class MyClass<T>

{

    T 字段名称;

    T 属性名称 {get; set;}

    T 方法名称 (T 参数列表) }

 

(P168) System.Collections 命名空间下的集合类型在 System.Collections.Generic 命名空间有相应的泛型版本;

 

(P171) “default”关键字在泛型代码中用于设置类型占位符的默认值: 变量 = default(T);

 

(P181) “delegate”关键字定义时,临时定义了一个派生于 System.MulticastDelegate 类的密封类,这个类与基类 System.Delegate 均同为委托提供必要的基础成员;

 

(P183) 多点委托的委托类型必须保证相同。另外,多点委托所引用的多个方法都有返回值的情况下,只有最后被调用的方法才有返回值;

 

(P184) “+=”运算符和“-=”运算符被重载,编译时这2个运算符分别转换为调用 Delegate 类的 Combine()静态方法和 Remove()静态方法;

 

(P186)

必须理解事件和委托的联系,才能掌握事件机制的本质;

 

事件就是当对象或类(发布者)状态发生改变时,对象或类发出信息通知订阅者,发布者也被称为“事件源”;

 

(P187) 事件实质上是一种特殊的委托,通过多点委托的方法被多个方法订阅;

 

(P189)

匿名方法的方法体代码直接和委托对象关联,不需要指定委托对象名称;

 

实际编译时,匿名方法的名称由编译器自动分配;

 

(P192)

Lambda 表达式将 delegate 也隐藏了:(参数列表) => ;

 

.NET 的应用程序体系分为以下4个层次:程序集(Adembly)、模块(Module)、类型(Class)和类型成员(Member),反射技术可以在程序运行时获取这4个层次的元数据信息;

 

应用程序域是程序集层次上的更大的容器,一个应用程序域可以装载多个程序集;

 

(P201)

“Load()” —— 用于加载当前程序集位于相同目录下的外部程序集;

 

“LoadFrom()” —— 用于加载其它目录中的程序集;

 

(P203)

mscorlib 程序集包括了 .NET 大部分的基类库, CLR 运行时自动加载;

 

Assembly 类的 LoadFrom 方法需要传递外部程序集的完整路径;

 

(P204) 读取 AppDomain 类的 CurrentDomain 属性,可返回当前应用程序域,调用当前应用程序域的 GetAssemblies 方法,可获取所包含程序集的集合;

 

(P221) 进程包括多个应用程序域,而应用程序域可以加载多个程序集;

 

(P225)

如果需要异步调用委托对象所指向的方法,必须显式地调用 BeginiInvoke()方法,如果需要返回值则调用 EndInvoke()方法;

 

BeginInvoke()方法返回一个 IsAsyncResult 类型的对象而调用 EndInvoke()方法需要这个IAsyncResult 类型对象作为参数;

 

(P231) 默认情况下,手动创建的线程都是前台线程,而线程池中的线程只能是后台线程。只有前台线程全部结束,应用程序域才能被卸载(程序才能关闭)。前台线程全部结束后,后台线程即使没有完成工作,也会被忽略,并自动结束;

 

(P236)

lock(this) {需要同步的代码块;}

Monitor.Enter(this)

try

finally {Monitor.Exit(this);}

 

(P248)

自定义一个类类型,当该类型被标记了[Serializable]特性后,其对象即可被序列化;

 

(P249) XmlSerializer 类的构造函数需要传递参数,当只需要实现一个独立对象时,传递该对象所属类的 Type 对象类型即可,当该对象依赖于其它对象时,需要将其它对象所属类的 Type 对象类型作为数组传递;

 

(P264) this.控件对象.事件名称 + new EventHandler(事件处理方法名称);

 

(P268)

Application.Exit() 是退出整个应用程序;

 

this.Close() 是关闭指定的当前窗体;

 

(P268)

GDI+ 绘制功能的核心是 System.Drawing.Graphics 类,可以通过作为绘图区域窗体的 Paint 事件处理方法获取 Graphics 类对象,访问该方法所接接收的第2个参数的 Graphics 属性即可;

 

(P273)

SqlConnection 连接字符串 —— Server = 服务器名称; Database = 数据库名称; User ID = 用户名; Password = 密码;

 

OleDbConnection 连接字符串 —— Provider = SQLOLEDB; Data Source = 服务器名称; Initial Catalog = 数据库名称; User ID = 用户名; Password = 密码;

 

OdbcConnection 连接字符串 —— Driver = {SQL Server}; Server = 服务器名称; Database = 数据库名称; (或者) DSN = DSN 名称;

 

OracleConnection 连接字符串 —— Data Source = Oracle 8i; UserID = 用户名; Pwd = 密码;

 

(P274) 池化机制对“名称/值”对间的空格十分敏感;

 

(P283) 如果没有数据可操作,那么只能使用调用命令对象的 ExecuteReader 方法,返回一个数据读取器(DataReader 对象)。因为ExecuteNonQuery()与 ExecuteScalar()在没有数据调用时,就会出现“对象没有实例化”的错误,所以在判断是否有数据时,应该调用数据读取器的 Read()方法来检验;

 

(P284) DataReader 对象只能配合命令对象使用,而且 DataReader 对象在操作时连接对象营保持打开状态;

 

(P285) 数据读取器的 Read()方法可以检测是否还有下一条数据,有则返回true,没有则返回 false 。相应地, NextResult()方法可以检测是否还有下一个表的结果集,有则返回 true ,并且数据读取器将返回下一个结果集的数据,没有则返回 false;

 

(P293) DataReader 只能向前读取数据,每次读取一条记录(内存中瞬间只保存一条记录),读取完成后不能进行任何数据操作;

 

(P296) 由于 CommandBuilder 会使程序性能下降,因此应该避免大数据量批量更新,为了提高性能,应该使用存储过程;

 

(P310) 当字段名、表名和数据库名作为变量时,只能采用动态 SQL 语句方式,使用 exec() 或者 exec sp_exexutesql 执行;

 

(P317) UPDATE 事务先执行一个 DELETE 操作,再执行一个 INSERT 操作,执行过的行首先被转移到 deleted 表,让新行同时添加到激活触发器的表中和 inserted 表中;

 

(P319) 指定 GROUP BY 时, GROUP BY 表达式必须与选择列表的表达式严格匹配,即选择列表中任何非聚合表达式的每个字段名(列)必须包含在 GROUP BY 列表中;

 

(P335) 在 TCP/IP 协议中,HTTP 协议即(超文本传输协议)位于 TCP/IP 协议的应用层,主要用于传输网页文件;

 

(P338) AutoEventWireup 属性设置为 true 时,服务器端的事件将自动绑定。如果开发者需要某个事件的处理方法使用自定义名称,则只需设置 AutoEventWireuo 属性为 false ;

 

(P344) 页面类的 Server 属性可返回 System.Web.HttpServer.Utility 类的对象。简称其为 Server 对象(严格说应该是 Http Server Utility 对象)。

 

(P349)

“Web 服务器控件” —— 该控件运行于服务器端,根据代码执行结果生成一个或者多个 HTML 控件,而不是直接描述 HTML 控件;

 

Web服务器控件的事件处理在服务器端,并且状态可以保存到 ViewState (试图状态)中。

 

(P350) 用户控件实现了完全的类化,并最大程度封装了代码块,使代码维护更加方便,也提高了数据的安全性;

 

(P359)

FileUpload 控件的 PostedFile 属性可返回 HttpPostedFile 对象;

 

ASP.NET 的 Web 应用程序默认将上传文件限制于 4MB 以下, 如果需要修改这个限制,可以在 Web.Config 配置文件中修改 HttpRuntime 配置元素的 MaxRequestLength 属性值(单位为千字节)即可。当用户上传的文件大小超过了该属性值,上传将失败,并且页面内容为“此程序无法显示网页”的页面;

 

(P360) form 元素会自动提交到自身页面上。如果没有指定 method 属性,它会默认地设置为 “Post”。如果用户没有指定 name 和 id 属性,ASP.NET 会自动地给予分配;

 

(P361) 每个控件的 ID 属性被保存到 ViewState 中;

 

(P362) 在 *.aspx 页面中,如果 form 元素的 runat 属性值为“server”,则该页面所生成的 HTML 页面具备了 ViewState 功能;

 

(P364) ViewState 只在页面内有效,不能跨页面使用;

 

(P372) 使用非进程内方法存储 Session 值应确保 HttpSessionState 对象内的自定义类型是可序列化的,即类型被标记了[Serializable]特性;

 

(P382) mode 属性值为“On” 时代表始终显示自定义(友好的)信息,如果没有设置 DefaultRedirect 属性,用户将看到一般的错误信息,而 mode 属性值为“Remote Only”时代表只对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息;

 

(P385) ASP.NET 应用程序下每个子目录都可以有继承于根目录配置文件的 Web.Config 文件, 但一个应用程序只能有一个身份验证登录页面。即以上代码中 <forms> 子节点 loginUrl 属性所指的页面。如果在子目录的 Web.Config 文件中出现了 <authentication> 节点的配置,程序将出错,除非将此目录配置为虚拟目录进行访问;

 

(P390)

<% %> 是服务器端的输出指令,包含输出到页面的程序代码;

 

<%# %> 是数据绑定表达式语法;

posted @ 2011-12-18 16:58 Richard-Tian 阅读(214) 评论(0) 编辑

 

程序员要朝“内”和向“外”两个方面扩展自己的知识和技能:

内 —— 指的是编写代码的基本功、数据结构思想、设计模式等。

“修内”四要素:

1. 深刻理解面向对象编程思想;

2. 精通C#编程语言特点;

3. 熟悉设计模式的23种模式,理解各个模式UML图

4. 了解软件工程过程,掌握数据结构的概念和技术;

 

外 —— 指的是新技术的热情、知识的广度、注重扩展性等。

“修外”五要素:

1. 对新技术的理解和远见;

2. 通过项目的实践熟悉 DB 设计、SQL Server 或 Oracle 技术;

3. 清晰理解代码实现方式、范例、以及.NET相关接口;

4. 理解 Web 2.0 理念、Blog/Wiki/RSS 架构、SOA 理念、软件测试,了解网络和其它操作系统;

5. 知道如何面对英语面试;

 

(P15) 工资 —— 一定要问清楚是税前还是税后,这点不用多说。另外,还要问清楚,发多少个月。很多单位有年底双薪,还有一些单位会发14-16个月不等。

 

(P15)

“五险一金” —— 养老保险、医疗保险、失业保险、人身意外伤害保险、生育保险。“一金”指的是住房公积金。

 

有的单位公积金比例上得非常高,所以你工资扣得也很多,那意味着公司交的钱更多,而一旦买房时,这些钱都是你自己的。所以,这部分收入不能忽视。

 

有些单位还会向你提供补充医疗保险、补充养老保险、补充意外保险、住房无息贷款或经济适用房等,也要问清楚。

 

(P16) 关于加班,国家有规定:如果周六、周日加班的话,可以获得正常工资2倍的加班费;如果是五一、十一这样法定的假日加班的话,可以获得正常工资3倍的加班费。

 

(P29) 事情都是人做出来的,关键是人。

 

(P30) 正确的做法是和那些比你强的人打交道,看他们是怎么想的、怎么做的,学习他们,然后最终提升自己的能力才是最重要的。

 

(P35) 语言有“无类型”、“弱类型”和“强类型”3种:

1. “无类型” —— 不检查,甚至不区分指令和数据;

2. “弱类型” —— 检查很弱,仅能严格地分指令和数据;

3. “强类型” —— 严格地在编译期进行检查;

 

(P36) GAC —— Global Assembly Cache (全局应用程序集缓存),它解决了几个程序共享某一个程序集的问题。

 

(P37)

 

值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。

 

引用类型的对象总是在进程堆中分配(动态分配)。

 

引用类型和值类型都继承自 System.Object 类,不同的是,几乎所有的引用类型都直接从 System.Object 继承,而值类型则继承其子类,即直接继承 System.ValueType 。

 

(P38) 所有的值类型都是密封的,所以无法派生出新的值类型。

 

(P39) 引用类型可以包含 Null 值, 值类型不能。

 

(P40)

引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。

 

值类型(不支持多态)适合存储C#应用程序的数据,而引用类型(支持多态)应该用于定义应用程序的行为。

 

(P43) 装箱就是将值类型转换为引用类型的过程,并从栈中搬到堆中。而拆箱就是把引用类型转换为值类型。

 

(P45) DateTime 为 Struct 类型。

 

(P47)

关键字 const (静态常量):

1. 在编译期间解析的常量;

2. 必须在声明同时就初始化;

3. 既可用来修饰类中的成员,也可修饰函数体内的局部变量;

 

关键字 static readonly (静态常量):

1. 在运行期间解析的常量;

2. 既可以在声明时初始化,也可以在构造器中初始化;

3. 只可以用于修饰类中的成员;

 

(P51)

问: 定制的异常类应该继承哪个类? 应包含哪些构造函数?

答: 定制的异常类应从 Application.Exception 派生。按照约定,异常名应以 Exception 结尾, 应包含 Exception 基类定义的3个公共构造函数:

1. 默认的无参构造函数;

2. 带一个字符串参数(通常是消息)的构造函数;

3. 带一个字符串参数和一个 Exception 对象参数的构造函数;

 

(P60)

“==”判断符号左右两个 Object 是否指向统一内存地址;

 

“Equals()”判断两个 Object 是否一样 (所有成员值一样);

 

(P63)

在.NET Framework 中,由3种序列化机制:二进制、XML和简单地向访问协议(SOAP),它们的优缺点如下:

1. 二进制序列化的最大优点是: 类型数据可以准确地表示出来。因为二进制序列化对象的公有和私有成员,所以在反序列化的时候可以忠诚地重建出该对象的状态;

2. XML 只序列化对象的公有属性和字段。在 XML 序列化时,私有字段和其它实例化对象就失去了;

3. XML 和 SOAP 是开放标准,具有很好的移植性;

 

(P72) Random r = new Random(unchekced(int)DateTime.Now.Ticks));

 

(P73)

过程式编程语言为: 程序 = 算法 + 数据;

面向对象编程语言为: 程序 = 对象 + 消息;

 

(P76) 抽象类或者包含私有构造函数的类都不能实例化。

 

(P79) internal protected 的语意应该是 “internal || protected”

 

(P80) 栈的访问速度比堆要快,但栈的资源有限。

 

(P88) 虚函数的目的就在于实现多态性。

 

(P92) 如果没有写静态构造函数,而类中包含带有初始值设定的静态成员,那么编译器会自动生成默认的静态构造函数。

 

(P95)

“覆盖 (Override)” —— 指子类重新定义父类的虚函数的做法;

 

“重载 (Overload)” —— 指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同);

 

重载只是一种语言特性,与多态无关,与面向对象也无关;

 

封装可以隐藏实现细节,使得代码模块化;

继承可以扩展已存在的代码模块(类);

它们的目的都是为了 —— 代码重用

 

多态是为了实现另一个目的 —— 接口重用;

 

“接口是公司最有价值的资源。设计接口比用一堆类来实现这个接口更费时间,而且接口需要耗费更昂贵的人力的时间”。

 

继承的为重用代码而存在的理由已经越来越薄弱,因为“组合”可以很好地取代继承的扩展现有的代码的功能,而且“组合”的表现更好(至少可以防止“类爆炸”)。继承的存在很大程度上是作为“多态”的基础,而非扩展现有代码的方式。

 

(P99)

接口:

—— 从广义上说,凡是一个类提供给外部使用的部分都可以被称为接口。广义接口的真正意义是在类的继承中体现多态的功能,这种接口又被称为抽象类接口。

 

—— 从狭义上说,接口是指特定的函数集合,一般是用 Interface 声明的,它表示一个方法集合,这个集合被称为一个命名接口。

 

从上述认识来看,接口实际上是结合着多态而来的,它的最大的任务就是实现多态,而多态又是面向对象最精华的理论。掌握了多态,也就掌握了面向对象的精髓。但掌握多态必须先理解和掌握接口,只有充分理解接口的定义,才能更好地应用多态。

 

(P104)

在C#中,new 关键字可用作运算符、修饰符或约束。

 

new 修饰符和 override 修饰符不可同时用在一个成员上,因为这两个修饰符在含义上相互排斥。

 

(P108) 如果想调用子类的 new 方法,用子类的句柄(绝对不能用基类句柄)来调用。

 

(P110) 在构造函数中,通过 this 可以调用同一 class 中别的构造函数。

 

(P112)

子类被构造时一定会先调用父类的构造函数,但可以用 base 关键字选择调用哪个构造函数。

 

决定调用哪一个,但不能哪个都不调用(至少选一个)。如果不指定的话,一般会调用无参数的构造函数,因为这是一个类的默认的构造函数。

 

(P113) 抽象类允许包含抽象成员,但这不是必需的(可以允许一个抽象类中没有任何抽象成员),抽象类中可以有非抽象方法。

 

(P116) 接口中的接口成员可以是方法、属性、事件和索引器。

 

(P188) abstract 修饰符不可以和 static、virtual 和 sealed 修饰符一起使用,但是可以和 override 修饰符一起使用。

 

(P123) 显式为接口的方法指定 public 修饰符是非法的。

 

(P127) 委托在编译的时候确定会编译成类。

 

(P128) 委托是一个类,它定义了方法的类型,使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,使得程序具有更好的可扩展性。

 

(P131) 声明一个事件类似于声明一个进行了封装的委托类型的变量。

 

(P145)

1. NLR : 前序遍历 (Preorder Traversal) —— 访问结点的操作发生在遍历其左右子树之前,即根左右;

2. LNR : 中序遍历 (Inorder Traversal) —— 访问结点的操作发生在遍历其左右子树之间,即左根右;

3. LRN : 后序遍历 (Postorder Traversal) —— 访问结点的操作发生在遍历其左右子树之后,即左右根;

 

(P146)

“满二叉树” —— 对于所有结点都达到最大的二叉树;

“完全二叉树” —— 叶子结点仅在层次最大的两层出现,对于任意一结点,左子树高度只等于右子树高度或者右子树高度加一;

 

(P153) System.Text.Encoding.Default.GetBytes(strTmp).Length —— 里面的 Default 属性,在默认情况下,英文字母用一个字节表示,汉字用双字节表示。

 

(P160)

在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则这种排序方法是不稳定的。

 

稳定的排序 ——

排序名称: 气泡排序 (Bubble Sort)

时间复杂度: 最差、平均都是 O(n2);最好是 O(n)

空间复杂度: 1

 

排序名称: 鸡尾酒排序 (Cocktail Sort) (双向的冒泡排序)

时间复杂度: 最差、平均都是 O(n2);最好是 O(n)

空间复杂度: 1

 

排序名称: 插入排序 (Insertion Sort)

时间复杂度: 最差、平均都是 O(n2); 最好是 O(n)

空间复杂度:1

 

排序名称: 归并排序 (Merge Sort)

时间复杂度: 最差、平均、最好都是 O(nlogn)

空间复杂度: O(n)

 

排序名称: 桶排序 (Bucket Sort)

时间复杂度: 最差、平均、最好都是 O(n)

空间复杂度: O(k)

 

排序名称: 基数排序 (Radix Sort)

时间复杂度: 最差、平均、最好都是 O(dn) (d是常数)

空间复杂度: O(n)

 

排序名称: 二叉树排序 (Binary Tree Sort)

时间复杂度: 最差、平均、最好都是 O(nlogn)

空间复杂度: O(n)

 

排序名称: 图书馆排序 (Library Sort)

时间复杂度: 最差、平均、最好都是 O(nlogn)

空间复杂度: (L+&)n

 

不稳定的排序 ——

排序名称: 选择排序 (Selection Sort)

时间复杂度: 最差、平均都是 O(n2)

空间复杂度: 1

 

排序名称: 希尔排序 (Shell Sort)

时间复杂度: 最差、平均、最好都是 O(nlogn)

空间复杂度: 1

 

排序名称: 堆排序 (Heap Sort)

时间复杂度: 最差、平均、最好都是 O(nlogn)

空间复杂度: 1

 

排序名称: 快速排序 (Quick Sort)

时间复杂度: 平均是 O(nlogn); 最坏的情况下是 O(n2)

空间复杂度: O(logn)

(P165) 应用交换排序基本思想的主要排序方法有: 冒泡排序和快速排序。

 

(P183) 作为设计者,应该拥抱变化、利用变化,而不是逃避变化。

 

(P192)

MVC (Model / View / Controller) 模式是一种使用的较多的设计模式。 MVC 包括了类对象: Model 是应用对象;View是它在屏幕上的表示; Controller 定义用户见面对用户输入的响应方式。

 

1. 模型 (Model):是应用程序的主体部分,模型表示业务数据,或者业务逻辑;

 

2. 视图 (View): 是应用程序中用户界面相关的部分,是用户看到并与之交互的界面;

 

3. 控制器 (Controller):工作就是根据用户输入控制用户界面数据显示和更新 Model 对象的状态;

 

(P201)

类与类之间存在以下关系:

1. 泛化 (Generalization)

2. 关联 (Association)

3. 依赖 (Dependency)

4. 聚合 (Aggregation)

 

泛化 —— 指类与类之间的继承关系、接口与接口之间的继承关系或类对接口的实现关系;

 

依赖 —— 指对两个相对独立的对象,当一个对象负责构成另一个对象的实例,或者依赖另一个度喜爱那个的服务时,这两个对象之间主要体现为依赖关系;

 

关联 —— 指对于两个相对独立对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间为关联关系;

 

聚合 —— 指当对象 A 被加入到对象 B 中,成为对象 B 的组成部分时,对象 B 和 对象 A 之间为聚合关系;

 

聚合是关联关系的一种,是较强的关联关系,强调的是整体与部分之间的关系;

 

关联与聚合的区别:

1.

关联关系所涉及的两个对象是处在同一个层次上的;

聚合关系所涉及的两个对象是处于不平等的层次上,一个代表整体、一个代表部分;

 

2. 对于具有聚合关系的两个对象,整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期,当整体消失,部分也就随之消失;

 

(P222)

一个进程至少包含一个线程;

 

当一个程序开始运行时,它就是一个进程。进程包括运行中的程序和程序所使用到的内存和系统资源;

 

(P227)

作业调度算法:

1. 先来先服务;

2. 轮转法;

3. 多级反馈队列算法;

4. 优先级法;

5. 最短作业优先法;

6. 最高响应比优先法;

 

进程调度算法:

1. 先进先出算法;

2. 最短 CPU 运行期优先调度算法;

3. 轮转法;

4. 多级反馈队列;

 

(P228)

“sleep()” —— 是使线程停止一段时间的方法。在 sleep 时间间隔期满后,线程不一定立即恢复运行。

 

“wait()” —— 是线程交互时,如果线程对一个同步对象 X 发出一个 wait 的调用,该线程会暂停执行,被调用对象进入等待状态,知道被唤醒或等待时间到。

 

(P238)

“存储过程” —— 是用户定义的一系列 SQL 语句的集合,涉及特定表或其它对象的任务,用户可以调用存储过程;

 

“函数” —— 通常是数据库已定义的方法,它接受参数并返回某种类型的值,并且不涉及特定用户表;

 

“事务” —— 作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有4个属性,成为 ACID (原子性、一致性、隔离性和持久性) 属性, 只有这样才能成为一个事务;

 

(P275)

“单项绑定” —— <%# Eval("username") %>

“双向绑定” —— <%# Bind("title") %>

 

(P276) 在数据绑定控件的 EditItemTemplate 或 InsertItemTemplate 中要使用 Bind 函数。

 

(P278)

ASP.NET 页面在触发各个子控件的事件之后,会递归调用控件的 OnPreRender , 然后递归地将控件的 ViewState 序列化成一个字符串,最后递归调用控件的 Render 输出结果。

 

在 DataBind 的事件中,ItemCreated 和 ItemDataBind 是尤为重要并且经常要用到的两个事件。

 

ItemCreated 事件在 DataGrid 创建表格时触发。

 

ItemDataBound 事件在数据绑定到相应的行后触发。

 

(P283) Session 在服务器和客户端各保留一个副本,关闭浏览器与否与 Session 是否存在没有任何关系。

 

(P284) Session 机制可能需要借助于 Cookie 机制来达到保存表示的目的,但实际上还有其它选择。

 

(P285)

“Application” —— 是公共的,所有人都能看到;

 

“Session” —— 是私有的,每个客户端都存在一个不同的 Session 生存期;

 

“Cookie” —— 是保存在本机的文件,记录短小的信息,除非 Cookie 过期,否则会一直存在;

 

“ViewState” —— 类似于 ASP 中的 Hidden 控件,用来记录页面中控件的状态,主要在页面间传递信息时用;

 

“Cache” —— 是缓存,用来记录已经执行过的一些数据,比如读取数据库目的是加速显示,减少服务器的负担,过期时间也是可以自己设定的;

 

(P288) XML 注释 : <!-- -->

 

(P288)

ASP.NET页面之间传递参数:

1. URL 链接地址传递 —— QueryString

2. Post 方式 —— Request.Form["***"]

3. Session 传递

4. Application 传递

5. Server.Transfer 传递

 

(P290)

GET 请求:

1. 利用一个问号“?”代表 URL 地址的结尾数据参数的开端;

2. 后面的参数每一个数据参数以 “名称 = 值”的形式出现;

3. 参数与参数之间利用一个连接符“&”来区分;

 

(P291)

防盗链:

1. 检查Refer;

2. 为资源文件添加数据签名;

3. Session验证;

 

(P288) XML Web Service 与 .NET Remoting

1.

名称: XML Web Service

容易操作: 容易

跨平台: 是

充分利用 .NET Framework 功能:不充分

精确传递数据格式: 不精确

支持状态: Stateless

对象作业模式: 无

支持通信协议: HTTP

执行效率: 低

 

2.

名称: .NET Remoting

容易操作: 较难

跨平台: 否

充分利用 .NET Framework 功能:充分

精确传递数据格式: 精确

支持状态: Stateful 或 Stateless

对象作业模式: 丰富(单次呼叫、单一对象、前端启用)

支持通信协议: HTTP、TCP(可扩充)

执行效率: 高

 

(P304)

“Finalize()” —— 用于隐式释放资源;

“Dispose()” —— 用于显式释放资源;

 

(P311) 在面试面前,面试者应对应聘公司有所了解。比如公司的规模、业务、未来发展等。对公司文化理解是否深刻,是你超出其他应聘者的一个亮点。

 

(P366) 知识是用来用的,不是用来当摆饰唬人的。