笔者注
谨以此文纪念我敬重的 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 标准从第一天开始就已经开源和免费使用.
本文试图给大家展示一个完整的. NET 历史, 现状, 生态圈, 希望在. NET 拥抱开源界的时候, 业界也能拥抱. NET, 更多技术人员参与到. NET 的大家庭中来.
现在, 让我们一起回顾一下. NET 过去 10 多年的发展吧.
.NET 技术栈
如果你想对. NET 的整个技术栈有全面的理解和并希望深入研究, 可以看笔者的爆栈下面的. NET 技术栈: http://overflowstack.github.io/
误解
现在业界 / 一些开发人员对. NET 这个平台有诸多误解, 他们的想法可以概括如下:
.NET 是封闭的
实际上,.NET 从第一天开始便开源了(详见后面内容)
.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, 等等
有趣的是, 现在流行的开发平台大多采用了类似的编译, 运行, 调优机制:
编译成中间语言(IL)
运行时即使编译成 machine code(JIT, 后述)
有办法改变 JIT 的行为(调优)
有办法预编译成 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 http://asp.net/ MVC, 这是对当年市场上日渐流行的 Web 设计方式 Model View Controller 的回应, 这个产品后来开源了. ASP.NET http://asp.net/ MVC 的设计思想是好的, 把界面, 业务逻辑, 数据模型等分离, 这样不同角色的人员可以独立进行开发, 互不干扰.
ASP.NET http://asp.net/ MVC 自带几种渲染器:
ASP.NET http://asp.net/ WebPages 就是 ASPNET WebForm (不要用)
ASP.NET http://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# 代码进行编译
以上是语言 / 框架层面的优化, 如果做了上述的事情后仍然对性能不满意, 那么你可以:
优化算法, 有可能带来数十倍的性能提升
重构设计和实现, 原来的设计可能是错的, 也可能是现在有更好的解决办法, 重构 / 重新实现可以改善性能
.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/
版权所有
所有文章内容版权所有, 任何形式的转发 / 使用都必须先征得本人书面同意. 本人保留一切追究的权利.
来源: https://www.cnblogs.com/unruledboy/p/net_past_present_future.html