為什么Java有GC調優而沒聽說過有CLR的GC調優?

前言

在很多的場合我都遇到過一些群友提這樣的一些問題:

  • 為什么Java有GC調優而CLR沒有聽說過有GC調優呢?

  • 到底是Java的JVM GC比較強還是C#使用的.NET CLR的GC比較強呢?
    其實業內已經有幾位大佬的高贊文章和大家分享一下,主要討論JVM和CLR還有GC調優,今天就借用大佬的回答給大家分享一下。

R大的回答

首先給大家介紹一下R大,R大網名叫RednaxelaFX,南京大學畢業巨佬,主攻高級編程語言虛擬機的設計與實現,對于C# .NET CLR有非常深入的研究和了解。先后加入阿里、Oracle、Azul System從事JVM虛擬機開發的工作(HotSpot JVM and Zing JVM)。現在在Databricks從事Spark開發工作。

R大社交主頁

iteye博客:https://www.iteye.com/blog/user/rednaxelafx
知乎主頁:?https://www.zhihu.com/people/rednaxelafx
GitHub:?https://github.com/rednaxelafx

R大回答相關問題摘抄

為什么聽說過 JVM 調優,卻沒聽說過 CLR 調優?

RednaxelaFX的回答 - 知乎?https://www.zhihu.com/question/52900051/answer/132583244

這里R大主要就CLR上幾種調優方式和為什么CLR不需要xmx、xmn等參數給出了原因

因為題主您就是沒聽說過?>_<

假定題主說的是下面三個層面的調優的頭兩種情況:

  1. 對VM的配置參數調優(例如GC參數)

  2. 對應用程序自身的代碼調優

  3. 對VM自身的實現調優

(2)的話無論什么語言什么環境都好,追求性能的人肯定都有在做。Java和.NET都有好用的profiler可以幫助這方面的調查和調優。

有時候參數調優還不夠的地方,也只能自己改自己的應用代碼來解決問題了。請看一個經典案例:

In managed code we trust, our recent battles with the .NET Garbage Collector

(3)的話,CLR還沒開源的時候,也無從調起。倒是有不少人給Mono貢獻改進性能的patch,也算是廣義上“.NET”的VM實現層面調優吧。

在CoreCLR開源后,也有不少人給CoreCLR貢獻各種patch呢,包括“調優”。

.NET碼農們以前時不時會中招的一種地方是程序進入GC的耗時(time-to-GC),也就是從CLR說“我要開始做GC了”到“真正開始做GC”之間的耗時。這里主要開銷來自請求所有應用線程暫停(SuspendEE),這些線程要多久才完成對該請求的響應。聽說過這個過程中會發生“250ms的倍數的等待時間”不?請跳傳送門:

Garbage Collection Thread Suspension Delay (250ms Multiples)

像這種問題就是不進到VM內部做修改的話無法解決的。

(1)的話,其實就算當年CLR還沒開源的時候,CLR也是有調優參數可以配置的呢。

最經典的就是選擇試用Workstation GC(WKS GC)或者Server GC(SVR GC)。見過<gcServer>參數不?

后來可以配置使用Concurrent GC、Background Workstation GC、Background Server GC等。

用戶還可以在代碼里通過 GCSettings.LatencyMode 屬性來影響GC的行為。

看,調優參數列表之一:
Runtime Settings Schema
不過CLR跟HotSpot VM在配置上有一個顯著的區別,就是CLR不需要用戶指定一個“GC堆的最大大小”。這跟CLR的GC堆的基礎設計思路有關系。

HotSpot VM的GC堆一定要使用連續的虛擬地址空間。VM在啟動的時候會一口氣reserve GC所需要的整個地址空間,然后再按需commit。-Xmx會參與到GC堆最大大小的計算中。

CLR的GC堆則是分段式的(segemented),GC堆所用的空間會一個個segment分配,用滿了一個再去分配一個新的;segment不需要在連續的地址空間上。這樣GC堆可以按需自動增長或者縮減,可以一直增長到耗盡虛擬地址空間或者達到配額。

CLR這種分段式GC堆的好處是,在Windows上,特別是32位Windows上,虛擬地址空間中用戶程序可以用的部分是比較零碎的,想要用到盡就不能對“連續的地址空間”有太多要求,這種條件下CLR跑在Windows上就可以充分利用資源。

而且這樣一來,用戶就不用頭疼實現想好要配置多大的堆給CLR用了。反正它需要用多少會自己去增長。這用戶體驗就比絞盡腦汁想個好-Xmx要爽。

這種做法的壞處…怎能沒有壞處呢。壞處也有若干。其中一個就是在這樣的堆上實現的分代式GC的write barrier效率會比HotSpot那種用連續地址空間的要差一些。而且segmented heap實現起來也稍微復雜一些。

CLR 相比 JVM有哪些先進之處?

CLR 相比 JVM有哪些先進之處?- RednaxelaFX的回答 - 知乎 https://www.zhihu.com/question/39400401/answer/81293750

這里R大主要介紹了下CLR和JVM的不同,和下面hez大佬的回答可以對應起來

雖然只寫了一半但還是先發出來免得坑掉。后面邊討論邊更新吧…

這個問題原文是:

CLR 相比 JVM有哪些先進之處?

留下備份。

首先這個問題按其原樣無法回答,因為CLR與JVM不是可比較的對象。

CLR(Common Language Runtime)是CLI(Common Language Infrastructure)規范中的VES(Virtual Execution System)的一種具體實現,而“JVM”不指定實現的話只能說是一種抽象的規范。

適合比較的對象是:

  • 規范層面:CLI vs JVM

  • 實現層面:CLR / Mono 等 vs HotSpot VM / J9 VM / JRockit VM 等

從規范層面看的話,CLI規范

ECMA-335

當前最新的版本是2012年出的第6版。我沒太跟進新的CLI規范所以不確定這個版本的CLI與哪個版本的.NET Framework里的CLR對應。

JVM規范

The Java? Virtual Machine Specification

當前最新的版本則是2015年出的Java SE 8版。

在規范層面上,當前的CLI完勝當前的JVM。

《Virtual Machines: Versatile Platforms for Systems and Processes》

一書中有一章專門對比介紹了CLI與JVM的設計,值得一讀。

JVM規范由Sun最初的JVM實現(后來稱為Classic VM)抽象而來,然后幾乎沒有大的改動。后來的更新主要添加了Class文件對泛型信息的有限記錄、注解(annotation)支持、字節碼校驗器的更新(split verifier / type checking verifier)、invokedynamic及MethodHandle支持、default method支持等。

最初的JVM規范雖然也提到它“可以支持多種語言”,但主要目的還是支持Java一種語言的執行,直到Java 7添加了JSR 292(invokedynamic與MethodHandle)后才有了專門為Java以外的語言設計的功能。

CLI由.NET最初的CLR實現抽象而來,然后與CLR一起逐漸進化。它出現的時間畢竟比JVM規范晚許多,而且一開始就以支持多種語言、多種范型的執行與互操作為設計目的,自然設計得更完善。對歷史有興趣的同學可以搜搜“Project 7”看。

Interviewer: I've heard that there was a project where Microsoft started to inte...

Don Syme: That's a small part of the sequence. The visional design of the .NET platform was very much expected to be a multi-language platform from the start. Right back in 1998, just in fact as our research group in programming languages started at Microsoft and I joined the team and then other 10 of us joined the team, we were approached by a guy called James Plamondon, who started the project called Project 7, which was about getting 7 academic and 7 industrial programming languages on each side to target the .NET common language runtime and really check out if it was good enough, to see if design changes could be made early on in the design process of .NET to make sure it was good enough for a range of programming languages.

Project 7的參與方嘗試了將許多種語言移植到CLR上,包括C、Pascal、Cobol (Fujitsu)、Fortran (Salford)、Haskell、Standard ML、Eiffel、Active Oberon for .NET (ETH)、Gardens Point Component Pascal (QUT)等等。

后來還有更進一步的“Project 7+”。

Technical Overview of the Common Language Runtime

要追尋CLR更早的黑歷史就不得不提微軟的Visual J++。請跳傳送門:

微軟當年的 J++ 究竟是什么?為什么 Sun 要告它?- RednaxelaFX 的回答

下面先列舉一些點提醒我回頭更新…

Assembly vs Class文件

  • 常量池以stream的方式存在

  • 可以有strong name

CIL(Common Intermediate Language) / MSIL vs Java字節碼

  • CIL不僅有二進制形式的規范,而且還有標準的文本形式語法;Java字節碼只有二進制形式的規范

  • 局部變量區里無論什么類型的值都使用1個slot,而JVM則是long和double用相鄰的2個slot

  • 異常處理支持filter

  • 支持具現化泛型(reified generics)

    • OpenJDK: Valhalla

  • 泛型支持聲明點協變/逆變(declaration-site variance)

    • Java語言層面的泛型則是支持使用點協變/逆變(use-site variance)

  • 支持無符號整數類型(unsigned)

  • 支持用戶自定義值類型(value type)

    • OpenJDK: Valhalla

  • 支持對用戶自定義值類型指定顯式內存布局,可以模擬C的struct和union以便互操作(StructLayout)

    • OpenJDK: Panama

  • 支持檢查溢出的算術運算(checked arithmetic)

  • 支持有保證的尾調用(tail call)

  • 支持unsafe verifiable代碼

  • 支持輕量代碼生成(LCG,Lightweight Code Generation)

  • 支持委托類型(Delegate / MulticastDelegate)

  • CLI Delegate的single cast版本與Java 7的MethodHandle有相似之處

  • 支持方便的P/Invoke和Reverse P/Invoke

    • OpenJDK: Panama

  • 不支持自定義類加載器(custom class loader)。JVM上過于靈活的ClassLoader簡直是頭疼的要命,不支持這個簡直好。

CLI里藏的私貨:Assembly采用PE(Portable Executable)格式。PE是Windows上原生的可執行文件格式。

CLR與Windows的整合

  • Windows Loader可以直接識別.NET Assembly并啟動CLR來執行程序。

  • Windows對GAC(Global Assembly Cache)有文件系統層面的特殊處理,“Fusion”。

  • 與COM有良好的互操作能力。畢竟CLR原本就是希望設計成下一代COM,原本還用過COR這個名字(COM Object Runtime)。

  • 分塊式GC堆(Chunked GC Heap),可以自動擴張和收縮GC堆的大小,并且在Windows這種地址空間比較破碎的環境中可以有效的利用地址空間里的空隙。對應的,JRockit在Windows上則是用filler object來利用空隙。

  • GC堆分為多個空間,特別是高頻堆/低頻堆(high-frequency heap / low-frequency heap)的劃分很有趣。

  • GC支持固定住對象(Object Pinning)

  • GC提供API讓應用程序可以指定native對象的內存壓力,以便GC與native協調工作(System.GC.AddMemoryPressure Method (Int64))

  • 支持Windows的結構化異常處理(SEH)。

CLR 與 一些JVM實現之間有對應物的

  • CLR:DAC / SOS擴展;HotSpot VM:Serviceability Agent;J9 VM:DTFJ / jdmpview

  • CLR:CAS(Code Access Security)與 JVM的沙箱

hez大佬的回答

再來給大家介紹一下hez2010大佬,今年剛從中山大學畢業,對于C++、.NET、C#、Rust等平臺語言都有深入的研究,經常在博客園看文章的小伙伴應該早就看過hez佬的博文。他是.NET Runtime開源項目的持續貢獻者、Microsoft Student Partner、可以說年少有為。

hez大佬的社交主頁

個人博客:https://hez2010.com/
博客園:https://www.cnblogs.com/hez2010/
知乎:https://www.zhihu.com/people/hez2010
GitHub:https://github.com/hez2010

hez大佬回答相關問題摘抄

.NET Core已經開源好幾年了, 為什么不像JVM那樣很多人研究和調優其GC算法?

hez2010的回答 - 知乎?https://www.zhihu.com/question/365482363/answer/2389471084

這和虛擬機(這里指 JVM 和 CoreCLR)本身的特性有關系,由于基礎設施的不同造成開發人員解決問題的取向不同。

當開發者遇到 GC 導致的問題時:

Java 開發者選擇調優 GC,例如設置堆大小、調整各代和 region 的預算等等,最終使得“滿足 GC 觸發的條件”變得不那么容易滿足來緩解這個問題,代價自然是內存占用更高,畢竟只要內存是無限的那就不需要 GC,同理只要 GC 對堆大小容忍度夠高不去回收或者少回收,自然就能減輕 GC 帶來的問題。因此開發者需要根據自身的 workload 來調配這些參數,最終達到一個既不會占用大的離譜甚至導致 OOM 錯誤,又不會導致頻繁 GC 的平衡點。

而 .NET 開發者則會選擇優化自己的代碼,既然熱路徑中對象在托管堆內存上大量分配造成了頻繁的 GC 導致出了性能問題,那干脆不用 class,轉而去用 struct、stackalloc、fixed buffer、NativeMemory、Span 甚至指針,小對象什么的全都在棧上分配,用完自動隨著棧的銷毀而銷毀,甚至 JIT 可以直接把小值類型對象優化到寄存器里面,連內存分配都不需要;堆內存也不需要 GC 托管堆了,直接用 NativeMemory 自己分配自己回收管理,全程完全不需要 GC 介入。這么做的指導思想很簡單,既然是 GC 導致的問題,那么直接從源頭解決:不分配托管堆內存就不需要 GC。

由于 CoreCLR 從一開始就是支持值類型、指針和非托管堆的,因此有能力的開發者可以在需要低延時的場景中(例如游戲)選擇局部自行管理內存從而無需 GC;而其他大多數情況下 GC 并不會導致問題,因此這些時候開發者也可以充分利用 GC 帶來的便利提升開發效率。

而 JVM 并沒有這樣的設施,因此開發者需要將解決問題的方法聚焦到如何讓 GC 適應自己的 workload 上,通過調優一系列的參數來緩解因為 GC 導致的問題,再有就是通過 JVM 團隊改進 GC 的算法來盡可能讓 GC 暫停線程的時間變短。

另外,這也使得 JVM 和 CoreCLR 的工作重心完全不同,在 CoreCLR 上一個軟實時 GC(ZGC)的重要性遠遠沒有 JVM 上來的高,因此優先級就會變低。在 JVM 上 ZGC 是理所當然的重要,而在 CoreCLR 上卻并不是,相反,.NET 工作重心則聚焦在改進 struct 相關的底層代碼編寫體驗上:例如允許棧對象(ref struct)持有其他棧對象的引用(ref field),允許 ref struct 作泛型參數和約束,允許在棧上分配任何對象,以及棧對象生命周期的管理等等。

不過最近 CoreCLR 的 GC 團隊也逐漸開始有興趣實現軟實時 GC 以改進游戲等低延時場景的開發體驗(注意我說的是開發體驗,因為讓 GC 全盤管理堆內存可以很大程度上提升開發效率并避免內存安全問題,只是單純要求低延時甚至 0 延時的話現在完全可以通過繞開 GC 做到),這也是建立在其他高優先級工作(例如 region 改造和 DPAD 等)基本都完成的基礎上才輪到的。

至于某些極端情況,例如要求可預測的性能、絕對 0 GC 延時的,唯一辦法只有繞開 GC,這種情況即使 ZGC 也無法對應。

更新:

補充一下,.NET 的 GC 是可以直接替換實現的,通過設置環境變量 DOTNET_GCName 指向你按照接口自己實現的 GC 的路徑,就能做到替換掉自帶的 GC:

https://docs.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#standalone-gcdocs.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#standalone-gc

所以要是真的對自帶 GC 不滿的話,可以考慮自己寫 GC 來用。

總結

兩位大佬回答的比較好,基本原因給說的比較明白了,在我看來兩者的比較如下:

  • 從大多數人所認為“調優”選項來說,其實.NET CLR GC也是有調優選項的,只是因為CLR的GC默認使用了Segment方式來組織內存,會動態的申請和歸還內存空間,所以不需要像JVM一些GC一樣去人為的設置-xmx-xmn-xms這些選項。

  • 現在的.NET的GC和JVM上的GC(指G1)其實是平分秋色,因為都是為高吞吐量設計的分代并行GC,在高吞吐量下都有著不錯的表現,當然各自也有優化空間。

  • 受制于JVM平臺沒有自定義值類型、stackalloc、NativeMemory、Span和指針等特性,.NET這邊能無分配或者棧上分配地方JVM上需要堆分配。所以JVM平臺上的GC壓力會比CLR上的壓力更大一些(雖然有逃逸分析、標量替換等等JIT輔助技術,但是沒有原生那么快)。

  • JVM平臺開源的比較早,所以它的GC有非常多的選擇,雖然造成初學者面臨很多調優和選擇的問題,但是GC的豐富性這一點是.NET平臺上所缺失的。

  • JVM平臺上有單獨低延時的C4和ZGC。目前.NET平臺上沒有單獨低延時GC實現,.NET平臺這邊低延時第一是調整GCMode為GCLatencyMode.SustainedLowLatency,另外通過值類型、ref、棧上分配、非托管操作還有在關鍵路徑暫時關閉GC等方式來實現低延時。

GC算法從提出到現在歷經了幾十年的時間,筆者也關注了一些近年的論文,其實總得來說在馮諾依曼架構體系下,GC垃圾回收算法已經沒有顛覆性的變化。

在這個算力沒有指數級增長的時代,各個語言的GC算法都開始趨同(C# Java Js Go等等),在沒有更創新性的GC算法出來之前,從源頭上避免分配和Rust語言那樣的RAII管理內存可能是各個語言后面都會走的路。

如果大家想了解更多GC相關的知識,可以看下方的文章鏈接和推薦的書。

https://www.cnblogs.com/InCerry/p/dotnet-gc-workflow-1.html
https://www.cnblogs.com/InCerry/p/maoni-mem-doc.html
https://www.cnblogs.com/InCerry/p/put-a-dpad-on-that-gc.html

9bac057c414d3a2611a3863269e6f05f.png

9a511668a643d09932f45baf8cb18d97.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284308.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284308.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284308.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu16.04 - 安裝RabbitVCS,linux下的TortoiseSVN!!!

RabbitVCS 官網&#xff1a;http://rabbitvcs.org/ 1&#xff0c;添加PPA源。在shell里面執行下面命令&#xff1a; sudo add-apt-repository ppa:rabbitvcs/ppa 這個命令執行完畢后&#xff0c;查看執行結果看是否密鑰導入成功&#xff0c;成功截圖&#xff1a; 如果導入密鑰失…

8 種最坑的SQL錯誤用法

1、LIMIT 語句 2、隱式轉換 3、關聯更新、刪除 4、混合排序 5、EXISTS語句 6、條件下推 7、提前縮小范圍 8、中間結果集下推 總結 sql語句的執行順序&#xff1a; FROM <left_table>ON <join_condition><join_type>JOIN <right_table>WHERE &…

Vue根據菜單json數據動態按需加載路由Vue-router

每個菜單項對應一個頁面組件&#xff0c;根據菜單項動態按需加載路由 路由配置的正確寫法&#xff1a; /*router/index.js*/ import Vue from vue import Router from vue-router import url from ./url import store from ../storeVue.use(Router)const router new Router({/…

【ArcGIS微課1000例】0047:制圖表達(2)---河流漸變效果的實現

當我們在ArcMap中加載河流數據時,得到的效果往往如圖所示,僅僅是表示河流位置的線要素,既無法真實地反映河流的實際情況,同時在出圖的時候也遠沒有任何美化效果。 文章目錄 1.創建制圖表達2.添加幾何效果3.使用制圖規則4.使用制圖表達屬性覆蓋警告:這些操作會對您的數據庫…

操作系統思考 第二章 進程

第二章 進程 作者&#xff1a;Allen B. Downey 原文&#xff1a;Chapter 2 Processes 譯者&#xff1a;飛龍 協議&#xff1a;CC BY-NC-SA 4.0 2.1 抽象和虛擬化 在我們談論進程之前&#xff0c;我打算先定義幾個東西&#xff1a; 抽象&#xff08;Abstraction&#xff09;&…

1 句代碼,搞定 ASP.NET Core 綁定多個源到同一個類

問題有群友希望將路由中的信息綁定到一個Dto對象中&#xff1a;public class DDDDDto {[FromRoute(Name "collectionId")]public Guid collectionId { get; set; }[BindProperty(Name "relativeUrl")]public string relativeUrl { get; set; } }這樣就不用…

redux中間件的用法

1.定義 中間件就是一個函數&#xff0c;對store.dispatch方法進行了改造&#xff0c;在發出 Action 和執行 Reducer 這兩步之間&#xff0c;添加了其他功能。 2.舉例 日志中間件 import { applyMiddleware, createStore } from redux; import createLogger from redux-logger; …

設置git自動補全功能(windows版本)

目錄 下載 Git 的源代碼 在目錄中 git/contrib/completion/ 中找到 git-completion.bash 文件 將 git-completion.bash 文件改名為 .git-completion.bash 找到本機git安裝目錄 將.git-completion.bash文件復制到git安裝目錄下的etc文件夾 打開同目錄下的 bash.bashrc 文件&…

用Vue搭建一個應用盒子(二):datetime-picker

接著上次的進度&#xff0c;我們已經實現了一個todo-list。它已經具備了基本的功能&#xff0c;可以新建、編輯、刪除任務。但是美中不足的是&#xff0c;它的時間設定上只能通過輸入一段字符串來設定&#xff0c;很不社會。我們應該完成的效果是一個time-picker&#xff0c;日…

ArcGIS實驗教程——實驗四十八:ArcGIS制圖表達入門及案例教程

文章目錄 1. 制圖表達的概念1.1 什么是地圖表達1.2 使用制圖表達改善要素外觀1.3 制圖表達的優點2. 使用制圖表達2.1 創建制圖表達2.2 使用制圖表達來符號化圖層2.3 使用制圖表達規則3. 地圖表達實戰案例1.創建制圖表達2.添加幾何效果3.使用制圖規則4.使用制圖表達屬性覆蓋1. 制…

PAT (Advanced Level) 1070. Mooncake (25)

簡單貪心。先買性價比高的。 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<string> #include<algorithm> using namespace std;doub…

[轉]Java 18 還未用上,Java 19 最新兩大特性曝光

鐵打的 Java&#xff0c;流水的版本。 不久前&#xff0c;Java 18 才正式發布&#xff0c;遵循 Oracle 六個月發一版本的頻率&#xff0c;Java 19 將在今年 9 月出爐。這不&#xff0c;還沒等眾多開發者用上 Java 18&#xff0c;關于 Java 19 最新的兩個目標功能就被披露了出…

文本生成器(bzoj 1030)

Description JSOI交給隊員ZYX一個任務&#xff0c;編制一個稱之為“文本生成器”的電腦軟件&#xff1a;該軟件的使用者是一些低幼人群&#xff0c;他們現在使用的是GW文本生成器v6版。該軟件可以隨機生成一些文章―――總是生成一篇長度固定且完全隨機的文章—— 也就是說&…

C# 值類型和引用類型講解

要了解值類型和引用類型&#xff0c;我們首先要知道堆和棧的區別&#xff1a;① 棧是編譯期間就分配好的內存空間&#xff0c;因此你的代碼中必須就棧的大小有明確的定義&#xff1b;堆是程序運行期間動態分配的內存空間&#xff0c;你可以根據程序的運行情況確定要分配的堆內存…

【ArcGIS微課1000例】0048:制圖表達(3)---水立方效果實現

本文講解ArcGIS中水立方效果的實現過程(制圖表達案例)。 文章目錄 一、效果展示二、制作步驟1. 創建數據庫及要素數據集2. 創建范圍3. 創建隨機點4. 創建泰森多邊形5. 創建制圖表達一、效果展示 基于制圖表達的思想,可以容易實現多種形式的水立方效果,例如: 怎么實現的呢…

Java中this與super的區別

2019獨角獸企業重金招聘Python工程師標準>>> this與super關鍵字在java中構造函數中的應用&#xff1a; ** super()函數 ** super()函數在子類構造函數中調用父類的構造函數時使用&#xff0c;而且必須要在構造函數的第一行&#xff0c;例如&#xff1a; class Ani…

EF選擇Mysql數據源

EF添加ADO.NET實體模型處直接選擇Mysql數據源 最近想到EF是連接多數據庫的orm框架&#xff0c;于是就想測試下。查了一堆網上資料后&#xff0c;測試連接mysql成功。步驟如下&#xff1a; 1、在你項目Model層中nuget安裝MySql.Data.Entity 如果沒安裝這個provider 就進行下面的…

JIRA簡介及基本概念

目錄 第一章 JIRA簡介 1.1 什么是JIRA 1.2 JIRA的主要功能 1.3 JIRA的主要特點 1.3.1 JIRA的優點 1.3.2 JIRA的缺點 1.4 相關版本 第二章 JIRA的基本概念 2.1 JIRA 中涉及的角色 2.1.1 管理人員 2.1.2 項目管理者 2.1.3 開發人員 2.1.4 測試人員 2.2 問題 2.2.1…

CodeChef Chef and Churu [分塊]

題意&#xff1a; 單點修改$a$ 詢問$a$的區間和$f$的區間和 原來普通計算機是這道題改編的吧... 對$f$分塊&#xff0c;預處理$c[i][j]$為塊i中$a_j$出現幾次&#xff0c;$O(NH(N))$&#xff0c;只要每個塊差分加上然后掃一遍就行了不用樹狀數組之類的 修改&#xff0c;整塊直接…

SkiaSharp 之 WPF 自繪 拖曳小球(案例版)

感謝各位大佬和粉絲的厚愛和關心( 催更)&#xff0c;我會再接再厲的&#xff0c;其實這也是督促自己的一種方式&#xff0c;非常感謝。剛寫了一篇萬字長文&#xff0c;自己也休養生息(低調發育)了一段時間&#xff0c;接下來來幾個小案例。拖曳小球WPF的拖曳效果&#xff0c;基…