.NET的前世今生与将来

笔者注

谨以此文纪念我敬重的2016年9月17日去世的 装配脑袋 逝世两周年

让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败。最终能成文是因为我给自己承诺必须赶在 装配脑袋 逝世两周年前发表。愿天堂没有bug,活着的开发人员珍惜写好每一行代码的机会。

前言

.NET正式诞生了16年了,目前是微软技术栈的主要开发平台。笔者有幸在2002年在生产环境使用.NET 1.0 beta,一直到现在.NET Core 2.1,见证了.NET从最开始蹒跚学步的婴儿,到现在在各大领域大放异彩的巨人。

在过去的10多年中,开始那些年,.NET被质疑、误解,一些开技术人员觉得.NET就是Java的复制品,没有什么值得学习和使用的,而且,一些反微软阵营的技术人员,为了反对而反对。正是由于这些偏见,至今,一些公司仍然不愿意使用.NET,即便.NET从第一天开始就已经提交到ECMA标准和使用Rotor开放了代码和免费使用。

本文试图给大家展示一个完整的.NET历史、现状、生态圈,希望在.NET拥抱开源界的时候,业界也能拥抱.NET,更多技术人员参与到.NET的大家庭中来。

现在,让我们一起回顾一下.NET过去10多年的发展吧。

.NET技术栈

如果你想对.NET的整个技术栈有全面的理解和并希望深入研究,可以看笔者的爆栈下面的.NET技术栈: http://overflowstack.github.io/
 

误解

现在业界/一些开发人员对.NET这个平台有诸多误解,他们的想法可以概括如下:
  • .NET是封闭的
    • 实际上,.NET从第一天开始便把标准提交到ECMA,并且利用Rotor 开放了源代码(详见这里),感谢RednaxelaFX的指正
  • .NET只能在Windows平台上跑
    • .NET 2004年开始就能在Linux上面跑了(Mono,详见后面内容)
  • .NET带来的费用高
    • .NET是开源的,可以在多平台跑,没有费用可言
  • .NET性能低
    • .NET(相关开发语言如C#)的性能在多个性能测试平台上是领先的(详见后面内容)
  • .NET是微软的
    • 这是典型的为了反而反,类似的幼稚行为是在微软最近收购了GitHub后,一些开发人员马上迁移到GitLab上,然而他们可能不知道:
      • GitLab是在微软Azure托管的(不过他们最近迁移到Google Cloud了)
      • GItLab之前发生过因为主数据库PostgreSQL备份/恢复出错导致了客户数据丢失的问题
 

前世

Windows 32

在2000年前,在微软平台上做开发,一般用的Windows 32 API,主要有以下几种开发方案:
  • Visual C++
    • 通用解决方案,可以是桌面应用(如MFC),也可以是C/S应用
  • Visual BASIC
    • 快速应用开发(RAD)的一种,一般做图形界面(GUI)应用
    • 组件一般采用ActiveX(COM),利用注册表做接口管理
    • 提醒:VB在.NET没有缺席
  • Delphi
    • 另外一种RAD,兼顾了VB的组件化和VC++的很好的底层API交互支持
    • Anders Hejlsberg是这个产品的首席架构师(提醒,他是.NET的核心人物之一,看下面内容)
 
做Win 32开发,会面对一个问题:版本控制,因为接口改变了,但因为发布管理不统一,导致了不同版本互相覆盖,调用错乱,这就是饱受诟病的.DLL地狱(Windows类库一般用.DLL做后缀):
  • 标准Win32 DLL:要么随意放到Windows System32目录,要么Program Files (x86)目录
  • ActiveX DLL:虽然统一用注册表做版本信息管理,但是因为发布的时候版本没定义好,导致使用regsvr32.exe注册的时候可能会把上一个版本覆盖
 
做Web开发,当年微软提供了ASP(Active Server Pages),使用VBScript做服务器端脚本,利用ActiveX做实际业务交互,譬如ADODB做数据库存储,但是这个解决方案在内存处理、安全方面都存在诸多问题。
 
 

前期

背景

诞生

微软剑桥研究院的技术人员,在1998年开始研究下一代的开发技术,他们的思维很超前,去年他们发了一篇文章,介绍这个项目的发展史,上面的图片,清晰可见一些.NET的特性,还有一些还没有被实现。

.NET这个开发平台,学习多个开发平台的特性,譬如Java,把开发语言Java等(笔者注:别的Java平台语言下面提及)编译成中间语言(IL),运行时JIT。不过.NET更进一步,支持本地化编译。

2002年,微软正式对外发布了.NET 1.0。

最近,Oracle宣称.NET的主要对手Java的安装量超过20亿,笔者还没有找到.NET安装量的官方数字。

.NET的名字

相信很多人会问,为什么会取.NET这个名字?适逢当年2000-2002年互联网大潮,微软打算推出一个适应互联网需求的开发平台,所以干脆用了.NET这个名字。当时很多公司开发的产品都加了.NET后缀,甚至公司域名都采用了.NET而不是.COM。
 

.NET特性

首先,.NET是一个开发平台,从1.0开始支持GUI(WinForm)、CUI(控制台)、Windows Service、Remoting等等Windows平台的开发,也支持ASP.NET (WebForm)开发web系统,所以从最开始,.NET就支持多平台开发。可以说.NET从第一天开始便是为了互联网而生的。

.NET编译生产的文件叫程序集Assembly,就是代码物理的集合,命名空间用来逻辑归类代码。

 

语言 vs 平台

有一些同学把语言和平台搞混了,譬如他们会说.NET是一种语言。让我们来捋一下关系吧:
  • 平台:.NET
    • 语言:C#,F#,VB.NET,等等
  • 平台:JVM
    • 语言:Java、Scala、Clojure,等等
 
有趣的是,现在流行的开发平台大多采用了类似的编译、运行、调优机制:
  1. 编译成中间语言(IL)
  2. 运行时即使编译成machine code(JIT,后述)
  3. 有办法改变JIT的行为(调优)
  4. 有办法预编译成machine code

言归正传,.NET平台上最主流的3种开发语言分别是C#、VB.NET和F#。

Pascal之父、Delphi首席架构师Anders Hejlsberg,当年还在Borland,被微软CEO Bill Gates重金邀请加盟微软,主导开发.NET平台上的全新开发语言,这就有了现在.NET平台上最流行的开发语言C# ,取义C++的++ ,即(C++)++,合在一起就是4个+,碰巧和音符的C♯一样,所以读作C sharp,不是C井,谢谢。因为这个升C的字符比较难敲,所以,一般用数字3上面的那个#符合代替(对,♯和#不是同一个字符)。C#是目前全球最流行的开发语言之一。

如果你想深入了解C#,可以参考Jon Skeet编写的《C# in depth》,JK很奇怪,他是在Stack Overflow上是排名第一的回答者,C#专家,然而,他却是在Google工作的(潜伏的卧底?)。

笔者对BASIC有着非常深厚的感情,第一次接触这个语言是1992/1993年的时候,后来用了GWBASIC、TrueBASIC、TurboBASIC、QBASIC、QuickBASIC、Visual BASIC (1.0版本还是DOS下的,用的ASCII字符拼接成图形界面)。

如果你用Visual BASIC 5/6,相信不会对VB.NET太陌生,尽管VB.NET用起来有点别扭。VB.NET表面上是微软照顾老VB用户在.NET平台上的实现,但这个语言实在太别扭。在VB 11.0之前,它是尽量和C#高度交互的,很多语言特性都尽量“兼容”,但是11.0之后,开发团队决定和C#分道扬镳,各自演进。

说起VB.NET,相信一些开发人员还记得@装配脑袋,他从老VB开始就是忠实用户,在博客、技术会议中和大家分享各自VB.NET/编译器技术和心得,他两年前不幸因病去世,愿天堂没有bug。

VC++一直以开发高性能著称程序,在.NET世界,VC++.NET,可以和.NET程序集交互,当然,你仍然可以选择写不基于.NET的代码。不过,如果你用,NET的话,为什么不直接用C#?除了VC++.NET,微软还有C++/CLI这个专门设计来和.NETA交互的兼容C++的语言,用来开发.NET托管代码。

如果你需要高性能、喜欢函数式编程,那么F#这个函数式的开发语言会比较适合你,它天生以高性能并行计算著称。可能你还已经猜到,F#里的F代表Functional函数式。

微软当年雄心勃勃,希望把.NET打造为大一统的开发平台,当年Java如日中天,微软自然不会放过这个机会:难道还有直接把对手的支持者拉拢过来的而扩大市场更好的办法吗?此消彼长,道理大家都懂。所以微软推出了J#。不过这个项目有点尴尬,最开始是想和Java进行交互,利用Java成熟的平台组件,后来项目没有被维护了,但是,.NET 4.5之前,想要自己读写zip文件,.NET框架内置的类库中,只有J#有一个类库,否则只能用第三方的方案。

J#出师未捷身先死,长使英雄泪满襟。然而这并没有阻止.NET的雄心。大家知道JVM是一个运行平台,在这基础上,有各种语言,Java是老大哥,Scala有取而代之的趋势,最近Google因为不满Oracle拿Java版权大棒乱挥舞,近年大力扶植JetBrains的Kotlin。同样,.NET平台上,也有多种语言,除了上述的几种,还有Fantom、Visual COBOL、ClojureCLR等。

为了和动态语言交互,.NET引入了 Dynamic Language Runtime (DLR),这样,各自动态语言就可以和.NET互相调用,而这个平台下的语言一般有一个前缀:Iron。当年出现了IronPython、IronRuby、IronScheme等项目。然而,这个项目没有被维护了。或许Iron是因为这个名字起得比较晦气,都“打铁”了。

 
 

核心特性

每种语言/开发平台都有自己的看家本领:语言特性(面向对象 vs 函数式、强类型 vs 动态类型、并行计算等等)、生态圈(开放、大量的第三方库/扩展支持)等等。

.NET的运行时Common Language Runtime(CLR)是.NET的核心,负责程序的解释和运行。.NET程序启动的时候,会经过多达50步才正式开始跑你写的第一行代码,中间是各种元数据的查找、分析等。如果程序是第一次执行,CLR会把要执行的代码路径进行JIT(即时编译),这个过程会有各种优化,举个例子:冷代码(如异常处理逻辑)会相对热代码(正常逻辑)执行较慢,这就是为什么如果过度使用异常来做控制,会有性能瓶颈。

如果你想对CLR进入深入的了解,可以参考传奇开发人员Jeffrey Richter编写的《CLR via C#》,他是经典开发书籍《Windows via C/C++ 》的作者。

.NET大量封装Win 32 API,这叫InterOperability(InterOp)。如果你需要调用第三方甚至自己编写的Windows 32,可以通过这个实现。

还记得DLL地狱吗?.NET的程序集经过SN(强命名)签名后,可以通过gacutil注册到Global Assembly Cache(GAC),这样任何一个程序可以直接调用。因为它通过程序集名称(assembly name)来区分每个程序集的唯一性,所以不会出现不同版本的程序集互相覆盖的问题。

C/C++,没有第三方的库,你需要手工控制内存的调用和回收,好处是按需调用,省内存,高效,然而对开发人员有较高要求,所以一般使用第三方的解决方案。Java和.NET,都有自己的
Garbage Collection (GC)。.NET GC分3个阶段,不同阶段针对对象的不同生命周期。如果你希望深入研究GC,可以参考下面的"高性能"部分。

不同于现在各种基于Google Chromium二次打包的浏览器壳,除了完整版,.NET还包括多个不同的兄弟框架,譬如.NET Execution Environment (DNX)、Compact Framework (CF)用于移动设备、Microsoft Framework (MF)用于嵌入式设备。

 

开发

Visual Studio是最受微软技术开发人员欢迎的IDE,你可以通过它使用上述各种语言开发、调试、测试、发布各种应用。或许你不知道,Visual Studio作为通用的IDE,被其它产品借用,譬如微软SQL Server的管理工具SQL Server Management Studio (SSMS)就是基于Visual Studio的,所以大部分快捷键和功能是一致的。

刚开始的时候微软推出的.NET针对自家Windows桌面开发推出了Windows Form(WinForm)这个开发方案。出发点是想把所有界面元素OO化,通过事件驱动,底层还是Win32那套消息机制,GDI+渲染。不过默认的渲染效果有审美疲劳,所以有些应用采用了国内比较流行的皮肤做法,通过owner draw实现自主的渲染,摆脱了单一的UX体验。

不喜欢WinForm的事件模型?不喜欢自己实现双向绑定?不喜欢WinForm太传统的Win32 GUI元素?那么,WPF应该会是你的选择。它使用XAML作为界面语言,DirectX渲染,逻辑代码可以选择C#或者VB.NET。之所以使用XAML(XML格式),是为了把界面描述标准化,这是iOS、Android和Xamarin的标准做法。

.NET的推出是为了应对互联网时代,必不可少的,需要提供网站开发方案。微软把当年的基于ActiveX + VBScript的服务器端开发解决方案ASP(Active Server Pages)升级,成为了ASP.NET。WebForm的设计思想是复制WinForm,但是封装得不好,导致用户被迫强行做各种js和css hack,尤其是它复制WinForm的事件模型,导致各自不必要的Postback,而且页面有着极其臃肿的ViewState来维护当前的状态,所以很多时候页面加载耗时甚长,久等不见内容。当然你可以用UpdatePanel做异步ajax更新提升用户体验。

 
WebForm设计缺陷包括但不仅限于:
  • 早年的封装没有考虑各个浏览器的兼容性,开发者必须做各种js/css hack
  • 表格postback设计导致不理想的用户体验
  • 使用ViewState做当前页面的状态保持,但这个ViewState是写入到页面的,默认是写入到文件前面部分,但页面数据量多的时候(如使用DataGrid),这个ViewState会相当大,导致页面加载缓慢,虽然有办法把ViewState放到页面后面部分,让加载看起来快点,但是根本问题没有解决。而且ViewState会出现各种损坏的情况导致功能无法使用
  • 容易导致开发人员把界面、业务逻辑和数据存储都放到同一个文件里面,难以维护和做单元测试
  • 慢,慢,慢,重要的事情要说三遍
 
为了解决在饱受诟病的WebForm中出现的各种问题,微软推出了 ASP.NET MVC,这是对当年市场上日渐流行的Web设计方式Model View Controller的回应,这个产品后来开源了。 ASP.NET MVC的设计思想是好的,把界面、业务逻辑、数据模型等分离,这样不同角色的人员可以独立进行开发,互不干扰。
 
ASP.NET MVC自带几种渲染器:
  • ASP.NET WebPages就是ASPNET WebForm (不要用)
  • ASP.NET Razor 就是.cshtml/.vbhtml文件的渲染器 (还是不要用)

你可能会问,那到底用什么做页面渲染?简单来说:不要在服务器端做渲染,因为所有界面渲染都不应该是服务器的事情,现在用户的浏览器渲染能力很强,这种事情完全应该留给客户的机器去做,这样服务器的压力会大减。服务器应该做的事情只是接受请求,根据业务逻辑处理数据、读取/存储数据。

所以,页面渲染,应该选择成熟Web前端MVC方案,譬如AngularJS、React等。

网络开发,除了网站,还有一些不可见的后台服务。Web Services是跟随ASP.NET 1.0推出的,协议基于XML,现在使用这个技术的产品比较少了。后来微软推出了大一统的WCF(Windows Communication Foundation)平台,是相对较新的一套Web服务解决方案,支持多种传输协议和安全机制,但配置繁琐。

ASP.NET Web API是ASP.NET MVC的一个组件,提供构建RESTful API的方案,目前比较多产品使用。

大家还记得Java Applet吗?当年Flash大行其道,但其问题太多,安全问题、CPU占用问题、稳定性等等。为了对抗如日中天的Flash,微软推出了Silverlight。Silverlight的性能不亚于Flash,而且比隔三差五要打安全补丁的Flash安全很多,但是两者都无法摆脱基于ActiveX插件的问题,即便预先安装,也常有版本兼容问题导致无法在浏览器加载,而且默认那套银灰色的界面确实有审美问题。

 
Silverlight的著名的应用:
  • 当年奥运会MSNBC的网络直播采用Silverlight解决方案
  • 微软的本地虚拟机管理平台Windows Controller,用的就是Silverlight
  • 微软云平台Azure,早期版本,使用了Silverlight做界面
 

不过和Flash抵挡不了技术发展的洪流一样,Silverlight也被迫退出了市场。对了,Flash在中国还是奇葩地存在,由某个流氓公司特供中国版,切记不要使用。

一个成熟的开发平台,单纯有好的语言、基础库还是不足够的。当年为了方便开发人员,微软提供了一整套的常用功能框架,叫Enterprise Library,包括功能如读写配置、数据访问、日志、缓存等,而这个项目的前身是Best Practice Application Blocks,就是类似广大开发爱好者常常自己搞的工具库。

大家还记得ActiveX年代的ADODB吗?在.NET世界,我们有升级版:ADO.NET。通过ADO.NET,你可以访问各大数据库系统。大部分数据库系统是支持多线程的,所以需要读写数据的时候:

  • 当你单线程读写数据的时候,已经用了command.Prepare(),甚至在允许表锁定的情况下用了connection.BeginTransaction()还是觉得慢,那么,
  • 可以用多线程,这里可以Parallel下的方法,一般多线程下会快带来几倍的性能提升,如果你还是觉得慢,那么,
  • 使用bulk copy。一般大型数据库系统都提供这个,譬如SQL Server提供SqlBulkCopy(本质上是BULK INSERT),譬如PostgreSQL提供的COPY命令
 
 

随着技术的发展,面向对象进入数据存储和访问领域。譬如数据访问,这些解决方案叫O/RM,对象关系映射。在Java领域著名的Hibernate被移植到.NET成了NHibernate,Dapper也是一个不错的轻量级的选择。微软也推出了自己的Entity Framework,后来并开源了。

不过不管是Code First、Model  First还是Database First,这些OO化的O/RM,因为对象化这个过程,性能损耗不可避免,而且,不同的解决方案要么解决不了延迟加载,要么做不好缓存,或者动态生成的SQL效率低下。如果你需要绝对的高性能,还是应该手工写SQL,并且封装到存储过程,这样业务逻辑不需要在每次执行的时候都在客户端/服务器不断传输。想象一下,即便某业务逻辑执行速度很快,但数量巨大,譬如一天100万次,当这个业务逻辑很复杂,譬如100K,那么一天光是这些SQL的网络流量起码是100GB,如果如果是封装成SP,那么,可能就是100MB。

同时,使用这些O/RM,一般会遇到对具体某种RDBMS的特性支持不好的情况,需要使用底层SQL直接调用操作,这样O/RM就无法直接切换到别的数据库系统了。

NoSQL蓬勃发展,在传统关系型数据库系统中被常规化的数据(一条数据会被存储到不同的字段甚至不同的表),现在作为一个json文件(字符串)被存储到各种类型的NoSQL中。NoSQL优势是快速的读写,因为避免了多表关联的可能,一次读取,一次写入。但是真因为这样,绝大部分NoSQL无法做跨表(集合)的关联,因此一般的做法是用定时任务生成目标数据,这种解决方案有2个问题:数据非实时和冗余的空间占用,同时,json文件本身的所有属性是键值对,所以空间占用远逊于RDBMS。

市面上不乏基于.NET的NoSQL,部分还是开源的,笔者觉得最好的一个是开源的STSDb,独创的Waterfall索引比传统的b+树要跟高性能。

大量业务系统都需要用到工作流。WF(Windows Workflow)是微软额外推出的基于.NET的工作流系统,不过这个方案配置起来有点罗嗦。

 

生态圈

 

从别的成熟平台中移植著名的项目是业界惯常的做法。一些著名/优秀的项目被移植到.NET,譬如Java世界的hibernate (nhibernate)、junit (nunit)、iText  (iTextSharp)、Quartz (Quartz.net)、Lucence (Lucence.net)、Log4j (log4net)。

一个开放平台的成熟,离不开社区的支持。开源/代码托管网站,早期的有SourceForge.net、CodeProject等,后来微软自己推出了自己的GotDotNet,后来变成了CodePlex.com,然而几个月前这个项目已经停止运转,大部分项目都被作者各自迁移到GitHub。

.NET框架和C#从第一天开始,就作为ECMA标准公开了源代码,这为后来的Mono和跨平台打下了坚实的基础。几年前,微软把.NET完全开源了,包括编译器、框架、类库等等。

著名的Linux GUI解决方案GNOME之父Miguel de Icaza,创建了Mono项目,让.NET真正跨平台,在Linux、MacOS下运行。Mono项目同时带来了SharpDevelop这个IDE,后来又被移植到别的平台上成为了MonoDevelop。

Mono项目近年被Ubuntu拥抱,跟随标准发布预装。

 

今生

.NET的发展脚步没有停下来,它不断进化,现在,.NET已经在各大平台扎根。

最近的15年周年纪念活动,Anders Hejlsberg被Channel 9邀请参与活动,并讲述了他对C#的看法,他表示:“我也没想到C#能如此兴盛。”

如果说.NET平台是心脏,那么,语言就是骨络。目前.NET平台上3大主流开发语言有各自的演进路线。C#作为先锋在新特性上不断快速进化,譬如LINQ/Lambda、async/await并行计算等,当然动态特性也是值得提及的。如果一个东西走起来像鸭子,叫起来像鸭子,它可能不是一只鸭子而是被鸭子带坏了的鹦鹉。如果你想知道C#的各种技术内幕,可以看Matt Warren的技术博客,他是C#语言委员会的成员之一,这个委员会决定每个版本的新特性。

Roslyn作为新一代的编译工具,使用C#编写,终于实现了.NET的自举,这是一个语言成熟的标志。

开发工具

不仅仅是各种语言跨平台,微软的开发工具也能跨平台。Windows上最佳开发IDE Visual Studio现在不仅仅在Windows上跑,微软推出的兄弟Visual Studio Code还支持Linux和MacOS,还有Visual Studio For Mac。

相信做过开发的同学都对各种第三方依赖组件的引入、维护都很烦恼,NPM、webpack、Chocolatey、Maven Repository等都是著名的包管理解决方案,微软效仿之,推出了NuGet。本质上NuGet包和Office系列的文件类似,都是zip文件,里面有一些元信息和实际文件。通过Visual Studio的项目Package菜单你可以直接生成NuGet包。早期的NuGet不允许直接下载包,非常恼人,必须通过客户端如Visual Studio,现在允许了。

如果你想架设自己的NuGet包管理平台,可以使用ProGet。

 

案例

或许你会想,.NET到底有什么优秀的案例?

如果你做Web开发,相信你听过甚至用过OWIN项目,它包括了SignalR、Nancy、Katana等项目。如果你用过IoC,你应该听过甚至用过Windsor,它是Castle项目的一员,包括了ActiveRecord、MonoRail等。相信你用过stackoverflow?它以及众多兄弟网站,都属于StackExchange,而这些所有网站都是基于ASP.NET的。微软自家一些产品也是完全或者部分使用.NET实现的,譬如BizTalk、Blend等。

如果你想了解更多的优秀.NET解决方案,可以看这个非常详细的列表:https://github.com/Microsoft/dotnet/blob/master/dotnet-developer-projects.md

了解或者开发过云应用吗?业界领先的公有云提供商微软Azure,这个平台大部分技术都是基于.NET的。对了,Bing搜索引擎也是。

Unity是流行的2D/3D游戏开发平台,其脚本系统主要是Mono,它刚刚对外宣布支持最新版版本Mono。另外一个游戏引擎Godot,也是使用Mono作为脚本引擎。

有些技术牛人,利用.NET打造自己的开源的操作系统。譬如比较早期的Cosmos OS ( https://www.gocosmos.org/ ),还有近期的FlingOS( http://www.flingos.co.uk/ )。由此可见.NET作为一个开发平台的能力和潜力。

为了实现跨CPU平台(x86和ARM等),微软为 Windows带来了UWP,开发者可以使用多种开发语言(.NET家族的,甚至HTML/WinJS)开发Windows平台应用,界面语言是XAML,这些应用不仅仅可以在Intel的x86平台下跑,还可以在ARM上跑。大家还记得Windows Phone和Surface吗?

跨平台

之前说过Mono这个跨平台开发解决方案,在支持Linux/MacOS的基础上,它继续进化,衍生出Xamarin项目,实现了对主流手机系统苹果iOS、Google Android、微软WP甚至三星Tizen的支持。

2016年微软收购了Xamarin,整合到Visual Studio里,并且将其开源,创始人Miguel de Icaza成为微软的Distinguished Engineer。

DotNet Anywhere (DNA)是另外一套跨平台解决方案:https://github.com/chrisdunelm/DotNetAnywhere

2016年,微软为了大一统.NET平台标准,推出了.NET Standard,可以把这个看成一个协议,而不是具体实现。具体实现是.NET完整版 4.x、.NET Core 2.x、Xamarin等。

.NET完整版4.x现在统治Windows平台,Xamarin复制移动平台,而.NET Core则主打跨平台,如Linux、MacOS、Docker、嵌入式设备、IoT等,譬如已经有Raspberry Pi等设备在运行.NET Core。或许你不知道,Docker For Windows是用.NET编写的。

.NET Core做法和.NET完整版在API层面基本上一直和兼容,区别在于,.NET完整版是依赖本地GAC安装/本地目录的.NET程序集,而.NET Core是依赖NuGet包,所有基础类库都是NuGet包,而这些包不像老版本的node.js那样都安装到本地目录,而是集中安装到本机的NuGet库里。

和.NET Core匹配的有ASP.NET Core,允许开发人员开发在Linux等平台跑的Web系统。

.NET开发初期,大量借鉴Java这个平台的优点,近年,Java作为平台和作为语言,分别复制了,NET和C#的一些特性。JavaScript的一些新特性直接复制了C#的特性。

 
 

高性能

业界做性能测试的时候,一般会用这句话:“不服跑个分!”。网上有各种性能评测文章/比较网站,最近看过一个完整,各种语言互相比较,其中.NET和Java的结果差异不大,11个比较项目中,.NET 6 : 5 Java。

.NET为了提高性能,通过如下几个不同状态下方式:

  • 语言:支持Parallel等并行计算
  • 编译:编译器会做各种优化,譬如代码内联,像常量和枚举等,会直接把实际值复制到调用方
  • JIT:除了根据代码访问路径进行动态即使编译之外,还可以使用更可控的Profile Guided JIT
  • 本地化:可以使用多种方式进行本地化编译,譬如ngen命令行和C# Native
  • LLVM:有一个开源项目,叫SharpLang,使用LLVM作为基础对C#代码进行编译。R大指出还有 https://github.com/dotnet/llilc 这个项目
 
以上是语言/框架层面的优化,如果做了上述的事情后仍然对性能不满意,那么你可以:
  • 优化算法,有可能带来数十倍的性能提升
  • 重构设计和实现,原来的设计可能是错的,也可能是现在有更好的解决办法,重构/重新实现可以改善性能
  • .NET运行时的调优
    • 如果你使用多线程(包括Parallel),那么你可以修改一下ThreadPool的MinThreads数量
    • 如果你调用HttpClient/HttpWebRequest等网络方法,那么,你可以修改一下ServicePointManager的DefaultConcurrentConnectionLimit,因为微软为了遵循古老的HTTP规则,对同一个网站最多只允许2个并发连接
    • 修改GC为Server模式
 
如果你还需要更高效的解决方案,可以考虑Map Reduce分布式计算,所谓的分而治之

如果你想深入研究如何编写高性能的.NET程序,可以参考Ben Watson编写的《Writing High-Performance .NET Code》这本书。

如果你还是不满足于性能表现,可以使用GPU加速,目前比较成熟的解决方案是AleaGPU,对C#的支持非常友好。

将来

Web前端开发技术日新月异,但同时也存在各种脏乱差的情况(笔者会另外撰文详细述说)。近来各大浏览器加入了对Web Assembly的支持,Web Assembly允许开发人员用如C++等语言实现逻辑,然后编译成二进制的Web Assembly。

最近,微软宣布ASP.NET项目引入了Blazor项目(取义Browser + Razor),这个项目是基于DotNet Anywhere的,允许开发人员用.NET + Razor实现前端功能。

在Windows平台上(x86和ARM),你可以使用.NET设计UWP应用,但其它平台上,你不能用.NET做带界面的应用。最近对外公布的AvaloniaUI,允许大家使用UWP类似的技术在Linux和MacOS上实现桌面应用,这个项目的名字看出来和当年的Avalon项目的关系了吗?

现在技术界喜欢搞cross play,譬如Windows 10下自带了Linux子系统,SQL Server也可以在Linux上跑,JavaScript可以通过node.js写服务器端代码,.NET也可以写Web Assembly做前端。

.NET发展16年,为业界带来各种新技术的同时,也给人类的发展做出了重大贡献,它会继续和老对手Java等一起齐头并进,互相追赶和促进。

 

谨以此文纪念我敬重于于2016年9月17日去世的 装配脑袋 逝世两周年。

 

如果你看到这里,那告诉你一个消息:世界那么大,我想去看看。再次上路,去追求心中的理想。

 

爆栈网

爆栈网Kayow.com融合了我10多年来的经验、心得、吸取的教训,频繁地发表高质量的技术文章:  http://kayow.com

 

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本人书面同意。本人保留一切追究的权利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
爆栈 系统开发技术栈、Web前端开发技术栈、数据库技术栈、.NET技术栈! http://overflowstack.github.i o   本地化 English: https://github.com/unruledboy/WebFrontEndStack/ 中文博客: http://www.cnblogs.com/unruledboy/p/WebFrontEndStack.html Español: https://github.com/unruledboy/WebFrontEndStack/blob/master/README.es-es.md   Web前端技术栈 比较全面的浏览器、平台、类库、框架、工具等。   自行生成预览图    准备环境 您应该安装Visual Studio 2010 。 安装 nodejs. 安装 Phantomjs. 安装 Python 2.7. npm install 如果出现错误,您可以检查 [phantomjs-node] 的依赖(https://github.com/sgentle/phantomjs-node/wiki), node-gyp.   运行命令 npm start 运行服务并直接打开主html文件。 npm run build 生成预览图。   选项   -h, --help                           Display this message.   -p, --port number                    (Default: 3000) Set the port what express listening.   -ues, --update_existed_stargazers    (Default: false) Update project's stargazers including existed.   --phantomjs                          The task to generate the image.   --readme                             The task to update readme.   --updatestargazers                   The task to update the count of the stargazers.   为什么? 大家是否想过: Web前端开发究竟包含哪些技术呢? 我所掌握的技术这个子集,在Web前端技术大系这个超集里面占的比例是多少呢? 我究竟还没有掌握多少Web前端技术呢? 面试的时候会考哪些技术呢? 那么,Web前端开发是否也应该有这样的技术栈概览图呢?搜索了很久,没有找到一个符合我要求的“较为全面”地表述Web前端技术大系的图表。所以我们自行设计了这个Web前端技术栈。 这个图表里的分类未必准确,相关技术也难免会有遗漏,欢迎大家指点以便不断改进。 Web前端技术实在太繁多限于篇幅,,这里没有罗列一些技术。 您可以点击下面链接查看交互式预览图(用鼠标移动/缩放/点击节点打开相关网站): https://rawgit.com/unruledboy/WebFrontEndStack/master/ux/WebFrontEndStack.htm?locale=zh-cn   Web前端技术栈 Web前端开发技术栈 Electron [GitHub] NW.js [GitHub] PhoneGap / Cordova [GitHub] MUI [GitHub] React Native [GitHub] Ionic [GitHub] CoffeeScript [GitHub] TypeScript [GitHub] ClojureScript [GitHub] JSX (Facebook) Sandbox XSS CORS SEO Responsiveness CDN Normalize [GitHub] Reset Handlebars [GitHub] Haml [GitHub] Slim [GitHub] Jade [GitHub] Ejs Spacebars mustache [GitHub] babel [GitHub] LESS Sass(SCSS) Stylus LESS [GitHub] Hat [GitHub] Compass [GitHub] Bourbon [GitHub] Gumby [GitHub] nib [GitHub] 基础库 模块化 框架 UI框架 WebSocket 数据可视化 WebGL CSS3 动画 流程控制 函数式编程 手机 UI 框架 jQuery [GitHub] Prototype [GitHub] Zepto [GitHub] MooTool [GitHub] umd [GitHub] RequireJS [GitHub] webpack [GitHub] browserify [GitHub] ES6 Module CommonJS AMD UMD AngularJS [GitHub] Backbone [GitHub] Knockout [GitHub] Ember [GitHub] React [GitHub] polymer [GitHub] Deft.js [GitHub] Vue [GitHub] Riot [GitHub] Bootstrap [GitHub] Semantic UI [GitHub] Foundation [GitHub] Material UI [GitHub] WinJS [GitHub] Pure [GitHub] Amaze UI [GitHub] Socket.io [GitHub] web-socket-js [GitHub] D3 [GitHub] Echarts [GitHub] HighCharts [GitHub] Vis.js [GitHub] Flot [GitHub] Three.js [GitHub] Babylon.js [GitHub] Pixi.js [GitHub] Animate.css [GitHub] bounce.js [GitHub] Effeckt.css [GitHub] move.js [GitHub] Bluebird [GitHub] q [GitHub] when.js [GitHub] yield await Promise Generator ES6 ES7 async [GitHub] co [GitHub] Promise bacon.js [GitHub] immutable.js [GitHub] ramda [GitHub] underscore.js [GitHub] lodash [GitHub] ReactiveX [GitHub] jQuery Mobile [GitHub] Jo [GitHub] Dojo Mobile Lungo [GitHub] 工具 在线工具 QUnit [GitHub] Jasmine [GitHub] Mocha [GitHub] Selenium [GitHub] WebDriverIO [GitHub] Protractor Chai [GitHub] Sinon.JS [GitHub] Karma [GitHub] nodeunit [GitHub] tape [GitHub] nightmare [GitHub] Sauce Labs Browser Stack Browser Shots Browserling Browser Sandbox Cross Browser Testing Browsera SortSite npm [GitHub] Bower [GitHub] JSLint [GitHub] JSHint [GitHub] jscs [GitHub] Closure Linter Node.js [GitHub] Phantom.js [GitHub] SpiderMonkey Developer Tools Firebug [GitHub] Grunt [GitHub] Gulp [GitHub] Brunch [GitHub] Yeoman Broccoli [GitHub] 精简 编译 合并 混淆 图像优化 单元测试 Sublime Text WebStorm Atom [GitHub] Vim Emacs Brackets [GitHub] Light Table [GitHub] Visual Studio Visual Studio Code [GitHub] Dreamweaver ;-) FrontPage / SharePoint Designer ;-) Cookie Local Cache Session Storage Local Storage Components Resources Extensions Plugins Images Icons Fonts Audios Videos JScript (IE8- / ASP) Chakra (IE9 / Edge) V8 (Chrome / Opera / Nodejs / MongoDB) [GitHub] SpiderMonkey (Firefox) Nitro (Safari) Trident (IE) Blink / prev. WebKit (Chrome) Gecko (Firefox) WebKit (Safari) Blink / prev. Presto (Opera) EdgeHTML (Edge) HTML JavaScript CSS DOM Element Attribute Prototype Scope Closure JSON (JavaSript Object Notation) AJAX (Asynchronous JavaScript and XML) Selector Priority Specificity Box Model W3C HTML CSS XHTML XML HTML (HyperText Markup Language) CSS (Cascading Style Sheets) JavaScript HTTP/1.1 HTTP/2 WebSocket 链接 会话 授权 请求 响应 压缩 打包 服务器端推送 Internet Explorer Chrome Firefox Safari Opera Edge Netscape ;-) 浏览器 协议 Web三剑客 标准 核心概念 渲染引擎 脚本引擎 运行时 编辑器 编译任务 编译工具 调试 基础工具 质量控制 包管理 测试 库 / 框架 CSS 预处理器 未来标准 模板引擎 统一化 最佳实践 安全 中间语言 移动应用开发 桌面应用开发   标签:爆栈网  技术栈

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值