.NETFramework基础知识总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

.NETFramework基础知识总结
之前给⼤家总结了java的⾯试⼏次技巧总结,同学们看了觉得还是不错,能够得到⼤家的认可,感觉还是挺不错的。

现在⼜有同学来想⼩编索要.NET⾯试的总结了,好吧。

谁让⼩编这么好呢!以下是.NET⾯试之框架基础知识
1 、术语
⾯试出现频率:从来没⼈问过。

事实上我都不知道怎么问,考背书吗?倒是可以问问知不知道现在.NET最新版本是什么,考察⾯试者是否对新技术⾜够敏感。

重要程度:3/10
需要理解的程度:知道这些缩写(CLR,BCL,FCL,CTS,CLS)各代表什么即可。

1.1 什么是.NET框架?在各个平台版本中,有什么值得强调的更新?
.NET框架是以⼀种采⽤系统虚拟机(即CLR)运⾏的,⾯向CLR的编程平台,以CLR为基础。

.NET的基础类库运⾏于CLR之上(类⽐Java的虚拟机),作为其他各种功能的基⽯。

.NET框架⽀持多种语⾔(C#、F#、、C++、Python等)的开发。

它的前⾝是Windows DNA。

现在.NET框架的扩展性甚⾄超过Java,其的Mono为Mac OS提供了⽀持,Xamarin可媲美安卓开发,可以在任何⼿机上开发。

.NET框架是开源的。

它的代码在。

如果你的commit有幸被接受,即使改动有多么微⼩,也是⽆上的荣耀,你绝对应该把它写到你简历的第⼀⾏,这个成就可以和“为Linux内核优化做过贡献”相⽐,那可⽐曾经在BAT做过⼏年的经历⽜逼多了。

所有.NET⽀持的语⾔编写出来的程序,在⽀持.NET的编译器编译之后,会先产出程序集,其主要内容是IL和元数据。

之后,JIT再将其翻译为机器码。

甲⾻⽂公司的Java EE是.NET平台的竞争对⼿之⼀。

.NET框架现在已经出到了版本4.6.1。

在3.0之前,.NET框架的Web解决⽅案是(Webform & MVC),数据库连接为(⽀持过去的ODBC,OLE等,并⽀持SQL Server和Oracle),Windows Form则作为Windows下的应⽤解决⽅案。

.NET最重⼤的⼀个版本更新是3.0,其中,提出了WCF(统⼀了过去Web服务混乱的形式,形成了⼀个统⼀的格式,并采⽤SOAP),WPF(作为Windows form的增强版)以及WF。

.NET3.5集成了LINQ。

另外Entity Framework取代,它对应VS2008。

.NET4.0提出了任务并⾏库和PLINQ。

.NET 5 (即.NET Core 1.0)在2016年6⽉27⽇推出。

是次推出伴随着 Core (即 6)和Entity Framework 7。

这些产品将⽀持Windows,OS X和Linux三种操作系统。

新版本的.NET项⽬使⽤.json⽂件代替了过去的.xxproj,.sln和.suo⽂件,这符合⽬前的主流,即⽤json代替XML。

新版本的.NET框架要传输给我们的理念是:这是⼀个跨平台的,开源的框架。

⼀切都是依赖注⼊,⼀切都是nuget,开发彻底组件化,能解耦的全都解耦。

Core彻底摆脱了System.Web这个顽疾,在其中,我们甚⾄连MVC都是注⼊进去的。

如果想得到什么组件,要么通过依赖注⼊,要么就使⽤nuget。

永远不要⼿动add reference,⽬前我知道的唯⼀的例外是System.Configuration。

当你和团队其他⼈并⾏开发系统的不同模块时,你们可以⽤nuget互相得到对⽅模块中的⼯程。

Nuget相⽐add reference,更不容易出错,界⾯更友好,且不会轻易陷⼊dll陷阱。

经过.NET牌编译器编译之后的程序集有两种形态:类库(.dll)形态和可执⾏⽂件(.exe)形态。

.NET⾃带了很多类库,统称为FCL。

BCL是FCL的⼀个⼦集。

1.2 基础类库(BCL)
Base Class Library (BCL) 是微软所提出的⼀组标准库,可提供给.NET Framework所有语⾔使⽤。

随着 Windows 以及.NET Framework 的成长,BCL 已近乎成为在.NET上的 Windows API。

mscorlib.dll程序集⼏乎就是基础类库的代名词。

当安装.NET Framework时,所有的基础类库被部署到全局程序集缓存(GAC)。

它的位置⼀般在C:\Windows\assembly。

所以你不需要在你的⼯程中⼿动引⽤任何的基础类库,它们会被⾃动引⽤。

如果你从GAC中删除了mscorlib.dll,你的IDE将变成⼀个什么都不懂的⽩痴。

因为没有mscorlib.dll,意味着没有基础类库,没有整型,字符串,控制台…你什么都做不了。

部分mscorlib.dll包括的命名空间:
System:.NET Framework 类库中最基底的服务,提供应⽤程序域 (Application Domain),数据类型,I/O 以及其他类库的基础。

System.Collections:提供⾮泛型数据结构以及集合对象的⽀持,其中 System.Collections.Generic中包括所有的泛型数据结构。

System.Configuration:提供.NET应⽤程序在配置设置上的⽀持。

System.Data:的组成类库,为数据访问功能的核⼼功能。

System.Drawing:提供.NET的绘图能⼒,包含基本位图处理以及视频与⾊彩处理,打印⽀持也由本名字空间提供,此名字空间包装了⼤多数的 GDI 以及GDI+的API。

System.IO:提供数据流与⽂件读写的⽀持
:.NET中的⽹络功能
System.Reflection:反射
System.Diagnostics:.NET 中提供系统诊断,除错,追踪与运⾏外部进程的能⼒
System.ServiceModel:WCF 的组成类库,于 .NET Framework 3.0 时出现。

System.Text:对⽂字,编码以及正规表达式的⽀持。

System.Threading:线程控制
System.Windows.Forms: Windows Forms 的组成类库,包装了 Win32 ⽤户界⾯,视窗,共⽤控件,以及 Shell 的基础 API,以提供设计 Windows 应⽤程序⽤户界⾯所需的⽀持。

System.Windows:WPF 的组成类库,于 .NET Framework 3.0 时出现。

System.Web: 的组成类库,令⼯程可以和 IIS 服务器交互,XML Web Service 开发的基本⽀持也由本类别提供。

Core中消失(如果你不打算⽤IIS做服务器的容器,则你不需要这个类库)。

System.Xml:XML 解析器
System.Linq,System.Xml.Linq:LINQ 的核⼼类库,System.Linq 是 LINQ to Object,⽽ System.Xml.Linq 则是 LINQ to XML。

然⽽在C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\我们还有⼀个System.dll,这个参考是每次新建⼯程时VS⾃动引⽤的若⼲参考之⼀。

这个程序集中也有⼀个System命名空间,它的内容和mscorlib.dll中的不同。

可以看到,System这个命名空间存在于不⽌⼀个程序集中。

这意味着不同的程序集可以共享⼀个命名空间。

在System.dll中,System类型拥有Uri这个成员,mscorlib.dll中System类型拥有int这个成员(基元类型)。

所以我们可以做个试验,如果我们将⼯程中对System的引⽤去掉,那么我们就不能定义⼀个Uri类型的对象。

但我们仍然可以使⽤int类型,因为它虽然也在System这个类型⾥⾯,但位于mscorlib.dll中。

当你去掉对System的引⽤时,你仅仅去掉了System.dll和⾥⾯的功能,但你没有去掉mscorlib.dll中System类型的功能。

BCL是属于整个.NET框架的,并⾮某种语⾔的⼀个基础类库。

例如,C#的string类型的所有功能和定义来源于mscrolib.dll中的System.String,⽽VB的string类型的功能和定义也来源于相同的地⽅。

基础类库中定义的类型称为基元类型,它也是为.NET框架所有的语⾔共享。

1.3 框架类库(FCL)
作为⼀名.NET程序员,每天都要打交道的就是FCL了(框架类库)。

BCL是FCL的⼀个⼦集。

简单来说FCL除了BCL的那部分,就是我们要引⽤的外部参考。

1.4 CTS(公共类型系统)和CLS(公共语⾔规范)
简单的说,CTS就是说话的语法和规范。

你可以理解为,英语是⼀种语⾔,英语的CTS(⾄少绝⼤⼀部分)就是“实⽤英语语法(张道真)”这本书。

如果C#没了语法,那就没有class,没有接⼝,变成了伪码。

参考资料中的第⼀个链接讲的很好,我就在这⾥总结⼀下吧:
CTS是⼀套语法。

类似“英语语法”。

它规定了⼀套约束,例如英语规定所有的字词都是由26个字母组成的(以及其他很多规则)。

服从这套语法的语⾔都可以被看成是英语的某种⽅⾔,例如中古英语,现代英语都是英语,⽽汉语不符合字词由字母组成,所以它不是英语。

同理所有服从CTS的语⾔,都可以被看
成.NET框架的语⾔。

CTS中定义了类型,允许它有属性,字段,⽅法等。

.NET框架的众多语⾔各⾃实现了CTS的⼀部分功能。

做⼀个不太恰当的类⽐,C#可以被认为是“美国英语”,F#是“英国英语”⽽VB是“印度英语”等。

他们是英语的各种⽅⾔。

他们共享⼀套相同的词汇表,但也各有各的特点。

例如颜⾊在英国英语中的拼写是colour,美国英语则是color。

由于.NET框架的众多语⾔在编译时都要转换为IL,因此IL实现的CTS功能是它们的并集,也就是CTS全部的功能。

你可以理解为,虽然.NET框架语⾔那么多,但⼀编译了之后,就成了⼀种语⾔。

.NET框架的众多语⾔分享CTS的⼀⼩部分功能,这部分功能称为CLS(Common Language Specification,公共语⾔规范)。

这是这些语⾔(的程序集)可以相互使⽤的前提。

如果你创建⼀个新语⾔,其实现了CTS的⼀部分功能,但不包括CLS,那你的语⾔就不能被其他.NET框架的语⾔(的程序集)使⽤。

如果你创建的语⾔甚⾄不符合CTS,例如你在词汇表中加⼊了汉字,那不好意思,你创建的语⾔不能叫英语。

很明显,CLS是CTS的⼀个⼦集,⽽且是最⼩的⼦集。

(最⼩功能集)
1.5 为什么说.NET是平台⽆关的?
.NET程序集可以在⾮微软操作系统如Mac OS,各种版本的Linux,以及iOS和Android移动设备上开发和执⾏。

.NET的平台⽆关性主要体现为:.NET程序集可以在任何的平台上运⾏,不管是Windows,还是Mac,只要这个平台拥有将IL转换为机器码,以及加载其他相关程序集的能⼒(即CLR),⽽任何机器都可以运⾏机器码。

这类似于Java的虚拟机,只要平台装了Java虚拟机,则这个平台就可以运⾏Java程序。

1.6 CLR(公共语⾔运⾏时)
CLR是让程序执⾏所需的外部服务的集合,类似Java需要JVM虚拟机才可以运⾏。

它的核⼼功能(⽐如即时编译,内存管理,程序集加载,安全性,异常处理和线程同步)可由⾯向CLR的所有语⾔使⽤。

例如,CLR允许创建线程,所以⾯向CLR的所有语⾔都能创建线程。

CLR是.NET的运⾏基础,管理.NET程序集的执⾏。

它运⾏于Windows之上,很多功能仅仅是Windows上的⼀个wrapper,例如线程,内存管理等,这些实际上是Windows在管理。

但JIT则是它独有的,如果没有它,就不能把IL变成机器码,计算机也就不认识C#,你也就不能运⾏C#程序。

在开始运⾏.NET程序之前,编译器将代码转换为IL。

IL代码并不能直接运⾏,CLR将真正需要⽤到的程序集导⼊内存,读取元数据,接着为类型开辟内存空间,执⾏所有需要的安全检查,并最终运⾏代码:
CLR找到代码中拥有Main⽅法的类型并且加载这个类型。

CLR中⼀个名为Class loader(类加载程序)的组件负责这项⼯作。

它会从GAC、配置⽂件、程序集元数据中寻找这个类型,然后将它的类型信息加载到内存中的数据结构中。

在Class loader找到并加载完这个类型之后,它的类型信息会被缓存起来,这样就⽆需再次进⾏相同的过程。

当然,如果这个类型引⽤了其他的类型,则会导致⼀连串的程序集加载,这将定义程序代码执⾏的环境(类似Java的JVM)。

注意即使⼯程很⼤,有⼏百个程序集,CLR不会全部加载,只会在真正⽤到该程序集的时候才加载。

验证。

在CLR中,还存在⼀个验证程序(verifier),该验证程序的⼯作是在运⾏时确保代码是类型安全的。

它主要校验两个⽅⾯,⼀个是元数据是正确的,⼀个是IL代码必须是类型安全的,类型的签名必须正确。

这是早期绑定验证,验证在运⾏时之前发⽣。

对于动态类型,此时不做任何检查。

即时编译。

(此时就从编译时过渡到了运⾏时)这⼀步就是将托管的IL代码编译为可以执⾏的机器代码的过程,由CLR的即时编译器(JIT Complier)完成。

即时编译只有在⽅法的第⼀次调⽤时发⽣。

类型加载程序(Class loader)会为每个⽅法插⼊⼀个存根。

在调⽤⽅法时,CLR会检查⽅法的存根,如果存根为空,则执⾏JIT编译过程,并将该⽅法被编译后的本地机器代码地址写⼊到⽅法存根中。

当第⼆次对同⼀⽅法进⾏调⽤时,会再次检查这个存根,如果发现其保存了本地机器代码的地址,则直接跳转到本地机器代码进⾏执⾏,⽆需再次进⾏JIT编译。

JIT编译还会优化本地的代码。

在程序运⾏时,CLR还负责:
异常处理
内存管理与垃圾回收
线程管理(线程池)
托管代码是必须在CLR下执⾏的代码,⽽⾮托管代码则不需要CLR的⽀持就可以运⾏。

CLR本⾝⽤于管理托管代码,因此它是由⾮托管代码编写的,并不是⼀个包含了托管代码的程序集,也不能使⽤IL DASM进⾏查看。

它位于C:\%SystemRoot%\\Framework\版本号下,视安装的机器不同有两个版本,⼀个是⼯作站版本的mscorwks.dll,⼀个是服务器版本的mscorsvr.dll。

wks和svr分别代表workstation和server。

CLR via C#这本书选择通过C#作为视⾓,讨论CLR的各种功能。

通过对这本书的阅读,你会对⼀些实际由CLR进⾏管理的⾏为例如垃圾回收,线程管理有更加深刻的认识。

2. 编译:IL与JIT
⾯试出现频率:低。

不排除部分IL专家会试探性问你⼀些IL命令,但我相信你答不出来他们也不会在意。

学了IL和没学,⼀般⼈看不出来区别,学了IL,也不意味着你就很厉害。

个⼈认为,学IL唯⼀的⽤处就在于证明你看到的书上写的各种结论,或者验证⼀些性能⽅⾯的想法。

重要程度:3/10,常识性了解即可
需要理解的程度:知道IL是中间代码,知道JIT的优点(带缓存的编译),以及它可能会对你的代码进⾏优化。

2.1 什么是IL(CIL)?如何获得IL代码?
在.NET的开发过程中, IL的官⽅术语是MSIL或CIL(Common Intermediate Language,即公共中间语⾔)。

因此,IL,MSIL和CIL指的是同⼀种东西。

当使⽤⽀持.NET的编译器编译之后,⽣成.dll或.exe⽂件。

这⽂件称作.NET程序集,包含IL和元数据。

不同语⾔(例如C#和VB)经过不同编译器(例如C#编译器和VB编译器),编译⼀段功能相似的代码(区别仅仅在于语法),其IL也基本相似。

虽然IL相对C#较为底层,但它仍然是⼀个⼗分⾼级的语⾔。

它并不是汇编语⾔。

可以通过ildasm(在cmd中运⾏)⼯具加载任意的.NET程序集并分析它的内容,包括它所包含的IL代码和元数据。

注意,⾼级语⾔只公开了CLR的所有功能的⼀个⼦集,⽽IL允许开发⼈员访问CLR所有的功能。

2.2 什么是JIT?还有什么其他编译⽅式?何时使⽤到JIT?
即时编译(英语:Just-in-time compilation)是动态编译的⼀种形式,是⼀种提⾼程序运⾏效率的⽅法。

通常,程序有两种运⾏⽅式:静态编译与动态编译。

静态编译的程序在执⾏前全部被翻译为机器码,⽽动态编译执⾏的则是⼀句句,边运⾏边翻译。

即时编译则混合了这⼆者,⼀句句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。

相对于静态编译代码,即时编译的代码可以处理延迟绑定并增强安全性。

CLR的JIT负责将IL编译成机器码。

当程序编译成程序集之后,CLR加载任何需要⽤到的其他程序集,并开始使⽤JIT将CIL编译为机器码。

JIT编译器会在⽅法的⾸次调⽤时,从类型的元数据中查找⽅法,并进⾏检查,例如检查类型是否安全。

如果出现了问题,则触发运⾏时错误。

以后对⽅法的所有调⽤都以本地代码的形式全速运⾏,⽆须重新检查。

2.3 本地代码的优化
CLR的JIT编译器会对本地代码进⾏优化。

例如字符串驻留中对常量字符串相加的优化。

和没有优化相⽐,优化之后的代码将获得更出⾊的性能。

但过度的优化可能会出现问题,在CLR via C#的易失构造中,作者举了⼀个例⼦。

1class Program
2 {
3private static bool s_stopWorker = false;
4static void Main()
5 {
6 Console.WriteLine("Main: letting worker run for 2 seconds");
7 Thread t = new Thread(Worker);
8 t.Start();
9 Thread.Sleep(2000);
10 s_stopWorker = true;
11 Console.WriteLine("Main: waiting for worker to stop");
12 t.Join();
13 }
14
15private static void Worker(object o)
16 {
17int x = 0;
18while (!s_stopWorker)
19 {
20 x++;
21 }
22 Console.WriteLine("Worker: stopped when x = {0}", x);
23 }
24 }
 如果使⽤F5呼叫出Visual Studio的调试模式,则程序会像预期的那样正常运⾏直到结束。

使⽤调试器会造成JIT编译器在Debug模式进⾏编译,它⽣成未优化的代码,⽬的是⽅便你进⾏单步调试。

如果是选择了x86的Release模式进⾏编译:
它将会⽣成被CLR优化的代码。

值得⼀提的是,x86编译器是⼀个更成熟的编译器,执⾏优化⽐x64更⼤胆。

x64不会执⾏上⾯所说的特定的优化。

在再次⽤f6进⾏编译之后,⽤ctrl+F5运⾏程序,程序将会陷⼊⽆限循环。

注意:必须⽤x86+Release编译,然后以⾮调试模式运⾏(即Ctrl+F5),才能看到这个效果。

问题发⽣的原因是,x86的编译优化过度。

它发现变量
s_stopWorker要么为true要么为false。

它还发现这个值在worker⽅法本⾝中从来没有变化。

因此,编译器会⽣成代码检查s_stopWorker,如果s_stopWorker为true,就显⽰“Worker: stopped when x = 0”。

如果s_stopWorker为false编译器就⽣成代码进⼊⼀个⽆限循环,并⼀直递增x。

解决的办法是为s_stopWorker加⼊修饰词volatile。

PDB⽂件包含了可以令调试器在本地⼯作的信息。

可以这么说:有了PDB⽂件,本地的debug才成为可能。

如果你打算发布Release版本,则不需要该⽂件。

使⽤Release模式编译的结果中也不包含PDB⽂件。

例如,你写了⼀个⼩的控制台程序给别⼈⽤,那么你不需要把\bin\debug⾥⾯所有的⽂件都拷贝给别⼈,你只需要程序本⾝,必要的dll和config⽂件即可。

MSDN参考:、及。

相关文档
最新文档