为什么我离开了.NET Framework

为什么我离开了.NET Framework2014年1月30日

.NET Framework很好。真的很好。直到它没有。我为什么离开.NET?简而言之,它限制了我们的选择能力(对我来说这是一个巨大的交易),并将我们的注意力转向了感知到的巢穴安全,而不是帮助我们体验在广阔的世界中的所有可能性。 [扣上:这篇帖子实际上变成了一本书......]好的 首先让我先说一下.NET做了很多事情,尽管这些事情大多数都不是来自.NET本身,而是因为.NET社区而来。C-夏普 C#太棒了。我认为这是一种引人注目的语言。来自强大的C背景,我非常喜欢语言的语法,流程和感觉。是的,我会改变一些事情,但总的来说它是一种可靠的语言。有这么大比例的开发人员使用这种语言以及Windows作为操作系统的优势,它是一种很好的语言。ReSharper的 我也喜欢ReSharper。JetBrains的员工都是奇迹工作者。如果没有ReSharper和一些相关工具,我可能不会喜欢C#。BDD和MSpec 我也非常喜欢名为Machine.Specifications(MSpec)的BDD风格的框架。这是一个壮观的测试框架,真正鼓励测试本身的正确语言。在MSpec之前,我的测试很糟糕,真的让我受伤了。 此外,Mspec是我的组织巨大的鼓舞和激励,当我们创建GoConvey --a基于Golang-BDD测试框架。多语言运行时 我认为多语言CLR的概念确实让JVM思考世界。我不了解CLR之前的任何非Java JVM语言,但随着“公共语言运行库”的出现,我的理解是让JVM上的人们移动并最终创建出色的JVM语言,如Scala和Clojure 。如果我错了,请纠正我。此外,CLR让Sun们坐起来注意,因为Java有点陈旧,而且随着Java 8的出现,它现在只是在很多方面迎头赶上。竞争是一件非常好的事情。的NuGet 另一个显而易见的是NuGet。Windows整体而且Windows开发中的软件包管理故事非常糟糕。NuGet解决了很多问题,他们通过大量借用Python和Ruby来做很多事情。还有改进的余地吗?当然。但是我没有感受到NuGet的很多痛苦,除了一些,选择包升级在这里和那里。单 我不能说Mono家伙。他们创造的东西简直令人惊叹。在没有任何官方支持的情况下,尽管潜在的法律问题悬而未决,但他们仍然向前推进并创建了一个令人难以置信的替代官方运行时实现 我已经有几个应用程序在Mono上运行了近一年没有任何问题。生产准备好了吗?这可能取决于您的申请(请参阅下面的“单声道”)CQRS和事件采购 可以说,最好的.NET之一是它是CQRS的发源地和相关技术:事件采购。当然,CQRS + ES本身并不是什么新鲜事。正如Greg Young将告诉你的那样,这是一堆40年的东西重新包装并为我们重新命名。我在大型代码库和CQRS + ES遇到了一些相当严重的问题,当我五年前遇到它时,我的域名完全没有被束缚。CQRS + ES现在是一个命名模式,并且增长是惊人的。这可能是.NET能够与其他开发社区共享的一件事。除此之外,大多数创新都来自外部。坏 有了这些好东西,让我们看看有什么不对,以及为什么我离开了.NET Framework。最令我兴奋的是我最近的开发平台迁移,我可以把很多最好的部分留给我,同时留下不好的东西(如下所示)。视窗 如前所述,在基于网络的服务器软件方面,Windows并不是一个好的参与者。我在Windows中看到的另一个非常大的问题是,传统的Windows开发人员通常只擅长Windows而且在他们的舒适区域之外很快就会迷失方向,而Linux开发人员则不然。计算是SO Windows在内的大很多。开发人员只能在单个操作系统上运行的一个问题是它不可避免地导致Windows的扩散。换句话说,Windows会引发Windows。没有办法打破这个循环。 *另一方面,NIX人通常熟悉多种操作系统(Linux,Unix,OSX,Windows等),操作系统的内部工作方式,各种发行版(基于Debian和Fedora),窗口管理器(小写“ w“),桌面管理器,文件系统,包管理,编译,重新编译,重新打包,命令行”fu“,列表一直在继续。 我的一个小问题是文件系统。NTFS不是唯一的文件系统,对任何给定的任务来说都不是最好的。ZFS,BTRFS,ReiserFS,ext 等都有一些非常酷的属性。我也喜欢能够从BASH创建环回设备或为各种高速/瞬态磁盘操作创建RAM驱动器。这不会发生在Windows中 - 不是没有第三方软件。 在AWS云中,启动Windows框需要10分钟以上。我可以在大约15-20秒内启动一个简单的Linux机器。当谈到云扩展时,能够快速扩展非常重要,因为当扩展很重要时,10-15分钟是永恒的。视觉工作室 我身边的另一个荆棘是Visual Studio。事实上,我需要一个伟大的,'honkin'IDE来做任何真正的开发困扰我。它与Windows一样重要。我有一个Core i7 3770K 3.5GHZ桌面我用16 GB RAM和一个Vertex 4 512 GB SSD构建。它实际上最大化了Windows体验索引,Windows + VS仍然很慢。(是的ReSharper使它变慢,但ReSharper值得。) 现在我开发了一款MacBook Pro,它的CPU功率比我强大的桌面更低,而且事情明显更快,并且在经过一小段学习之后,UX无限好。事实上,我甚至不再使用鼠标 - 我的手总是在键盘或触控板上,我可以向我的计算机做出姿势并实际让它响应 - 与Windows不同。 关于VS的一个很酷的事情是调试器。这是非常方便的看和使用。它经常会在监视窗口中报告错误的值,从而导致更多的调试时间。与此同时,这也是一个很大的负面因素,因为CLR的默认多线程世界使我首先需要一个调试器。没有调试器实际上是一种解放体验,因为它迫使您以不同的方式进行编码。 VS也有这个非常讨厌的习惯,即创建“csproj”和“sln”文件。我恨这些东西。当然,C#必须知道要构建什么以及何时构建。我明白了。在Golang中,引用位于使用import语句的代码中。如果不是.NET版本中的项目文件,我可能已经使用简单的文本编辑器编写了C#,并且语言更流畅。这些文件也有一个非常讨厌的习惯,即在git rebase操作期间创建精彩的合并冲突。 不要让我开始关于换行差异。我无法相信我们今天仍在处理这类事情。如果VS解决方案文件具有Linux行结尾,则不会通过双击加载解决方案,因为VS解决方案文件解析器无法读取它。源控制 幸运的是,我早早跳出了Microsoft Camp进行源代码控制(Visual Source Safe)。在VSS失去我的承诺无数次之后,我在2000年初使用Subversion。然后git来了,我被它迷住了。不幸的是,没有Windows端口 - 这对我来说很典型。最后有人创建了一个端口,我在那里,我没有回头。Git是一把非常锋利的刀,但是当你正确使用它时,它是一个强大而有效的工具。有一次我在一个小工作上使用TFS而且它是一个怪物 - 就像雷蒙德的其他一切一样。它感染了我的项目文件并污染了我的源目录。呸。不,谢谢。任何一天给我命令行git ......或者如果你需要GUI的一点爱情,可能还有SourceTree。单 是的,这是Mono的第二个条目。与Mono一样惊人,它仍然是.NET世界中的二等公民。每当我试图让任何严肃的东西在Mono上运行时,我通常会在实现中遇到错误。幸运的是,我并不觉得下载源代码,发现问题,发出拉取请求,然后在Linux上重新编译。但是我做过这件事的次数比我记得要多。 当然CLR是一个巨大的野兽,并且在非官方实施的不同操作系统上获得相同的行为,这简直就像离开红海一样奇迹...但事实上我必须花费这么多时间来寻找标准库错误让我的代码行为正确是非常难以证明的。 Mono的某些区域也很慢。也许它并不是每个容量都慢,但对我来说,Web服务器是一个关键部分。而且它的速度很慢,最后一个,最后的底部速度很慢 -即使是琐碎的东西。我想好消息是它只能从这里变得更好。我还要提一下,Mono家伙已经忘记了Linux,而不是我可能知道的,所以我不能太批评。IIS 对于太多的应用程序,IIS可能会尝试太多东西。它已经从一个Web服务器变成一个类似于J2EE应用程序容器的应用程序主机。这也是缓慢的一面。我想如果我需要更高的性能,我应该编写自己的Web服务器代码,但我真的很想专注于我的应用程序代码。在Windows上使用公平的Web服务器会很好,但是nginx和其他服务器在生产中不喜欢Windows。 各种基于JVM的实现(如Netty)每秒可轻松执行650K + /请求。IIS以每秒大约50K /请求的速度运行一个简单的CLR“Hello,World!”。应用。(有趣的是,参考基准测试中的人员从TCP套接字创建了一个简单的C#Web服务器,它每秒执行大约120K请求。)关闭情怀 几年前有一场名为ALT.NET的运动。这场运动的全部内容都是在整个更广泛的发展社区中展望自己,并将不同的部分结合在一起。有趣的是,这就是StructureMap,Autofac,NuGet,ASP.NET MVC和许多其他工具的灵感来源。在传统的.NET圈子里,人们对这一运动充满了蔑视和蔑视。我认为这是整个社会的惯性和一般的密切关注的一个巨大证据。(当然,其中一些可能正在消失,因为不同的技术出现,包括Redis,MongoDB等。) 那里有很多很棒的解决方案。假设微软已经命定了The One True Way是荒谬的。如果是这种情况,我们仍然会使用Visual Studio中的可视化设计器将按钮和链接元素拖放到WebForm表面上,我们将按钮连接起来并依靠ASP.NET ViewState来帮助我们隔离可怕的HTTP的“恐怖”。我从我部署的一个代码库中删除了最后一个WebForm的那一天是一个光荣庆祝的日子。从字面上看。 (谁曾经想过“网页控制”是一个好主意?显然我做了因为我喝了Kool-Aid并完全接受它。这让我很难受。我见过2MB + ViewState?) 注意:当我撰写这篇文章时,它最初标题为“为什么我离开.NET”,意味着整个.NET生态系统。标题感觉有点短暂,我将其更新为“为什么我离开.NET框架”。我认为.NET是一个包含所有工具,项目,平台,组织和开发人员组的生态系统。这就是为什么更广泛的.NET社区的某些元素在我的帖子中受到抨击。表演杀手 C,Java和C#中典型的多线程范例强烈鼓励使用锁和互斥锁。锁具有隐藏的成本:它们非常缓慢。使用Disruptor(JVM上的无锁环形缓冲区),您可以轻松处理每秒20M +事件。在.NET上使用规定的“最佳实践”,每秒超过十几个事务被认为是体面到良好的性能,在这一点上,你只需要更大/更好/更多的硬件。事实上,我已经看到第三方客户端库(Rabbit,Couch,Mongo等)在整个代码中都有锁定语句。即使我的代码中没有任何并发,默认和首选方法也使用锁。 无锁,事件驱动的方法可以让您在很大程度上减少硬件和资本支出。大多数应用程序可以轻松地在两台机器上运行,第二台机器只需要冗余和故障转移,以防第一台机器由于硬件相关问题而变得不可用。 另一个方面是调用网络和磁盘子系统的传统方式:同步,阻塞代码。如果您需要多个并发HTTP请求,则需要更多线程。大多数开发人员从未想过要理解的是维护线程所需的1-2MB开销以及上下文切换线程的要求,这可能导致CPU内核花费所有时间来进行上下文切换而不是进行实际工作。所以现在我们在一个应用程序中有数百或数千个线程占用RAM并导致CPU旋转它的轮子。还有更好的方法。 Netty / NIO(JVM),Erlang,Node,Gevent(Python)和Go都鼓励使用基于事件的子系统操作(select / epoll / kqueue)。这意味着CPU可以在等待数据包通过网络进行tx / rx时自由地进行实际工作。由于JVM的成熟,Netty在这项任务中可以说是最快的,但我喜欢Go用Goroutines处理这个问题的方式 - 它简单,优雅,易于推理而没有回调意大利面。SQL Server 作为.NET开发人员,当您开始一个新项目时,您通常会做一些事情(当然是手工): * 创建新的解决方案 * 将其添加到Team Foundation Server * 在IIS中创建相应的网站条目 * 创建一个新的SQL Server数据库 * 将实体框架与解决方案相关联(通常用于2010年之后创建的项目) * 开始设计数据库和ActiveRecord实体。

在大多数情况下,这不是正确的编码方式。当然它可能在某些情况下有效,但作为“默认架构”,它不是你想要的。为什么我们在了解问题域之前做出了任何技术选择?这确实将推车放在马前。 Microsoft生态系统鼓励每个人使用SQL Server。从Visual Studio内部或使用SQL Management Studio(及其前身SQL查询分析器)与SQL Server进行交互非常容易。这种以数据库为中心的焦点是被授予的和唯一的方式的一部分。它让你更加迷恋微软。供应商锁定始终对供应商有利。 为什么我们这样开发?为什么我们不考虑应用程序的行为而不是它的存储方式?我的所有项目现在都使用基于JSON的键/值存储。有了这个功能,我可以选择我想要的任何存储引擎,包括SQL Server,Oracle,PostgreSQL,MySQL,Cassandra,CouchDB,CouchBase,Dynamo,SimpleDB,S3,Riak,BerkeleyDB,Firebird,Hypertable,RavenDB,Redis,Tokyo Cabinet / Tyrant ,Azure Blob,文件系统上的纯文本JSON文件等等。突然之间,我们可以根据其优点而不仅仅是熟悉来开始选择存储引擎。 旁白:曾经在AWS RDS上的云中运行SQL Server吗?别。当然它会工作,但一些最简单的事情,如复制不存在。文档中充斥着对AWS RDS中不起作用的SQL Server功能的引用。结论 也许我在软件开发中学到的两个最重要的经验教训是: * 边界和封装的重要性(以各种形式) * 付出代价来获得正确的模型和抽象

多年前我讨厌“模特”这个词。每个人都会抛弃它,这是一个如此重载的术语,很难理解它的含义以及为什么它很重要。在这一点上,我只会说模型是你试图封装的现实的狭隘代表。也许最简单的例子是全球的墨卡托投影。擅长一件事:导航。如果你将它用于其他任何东西,它就不会毫无价值。如果您不专注于为正确的模型付出代价并将业务现实封装起来,那么任何数量的技术都无法为您节省成本。 我使用.NET的最大优点是One True Way可以让您远离理想模型,并使您更加关注实现细节和技术默认值。这种关注导致技术实施渗透并感染模型,最终导致模型衰减和恶化,因为它无法适应不断变化的业务需求。当这种情况发生时,开发人员在从一种新技术转向另一种新技术时会挣扎和踢,就像吸毒成瘾者一样,希望下一件大事可以治愈他们的疾病。 技术本身并不是灵丹妙药,相反,它取决于权衡和选择。只有正确理解业务行为并将其封装到格式良好,易于理解的模型中,才能将技术堆栈保留在其所属的位置 - 作为实现细节。 这就是我离开.NET Framework的原因,因为它一直在重申自己,并希望不仅仅是它:实现细节。

乔纳森奥利弗 阅读此作者的更多帖子。 犹他州,美国 https://blog.jonathanoliver.com/ 分享这个帖子


作者:spike

分类: Net

创作时间:2023-06-25

更新时间:2024-12-08

联系方式放在中括号之中例如[[email protected]],回复评论在开头加上标号例如:#1