前車之覆,後車之鑑——開源專案經驗談
前車之覆,後車之鑑
——開源專案經驗談<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
(本文發表於《程式設計師》2005年第2期)
隨著開源文化的日益普及,“參與開源”似乎也變成了一種時尚。一時間,似乎大家都樂於把自己的程式碼拿出來分享了。就在新年前夕,我的一位老朋友、一位向來對開源嗤之以鼻的J2EE架構師竟然也釋出了一個開源的J2EE應用框架(姑且稱之為“X框架”),不得不令我驚歎開源文化的影響力之強大。
可惜開源並非免費的午餐,把原始碼公開就意味著要承受眾目睽睽的審視。僅僅幾天之後,國內幾位資深的
成熟度
開啟X框架在SourceForge的專案站點,我們立刻可以看到:在“Development Status”一欄赫然寫著“5 – Production/Stable”。也就是說,作者認為X框架已經成熟穩定,可以交付使用者使用。那麼,現在對其進行評估便不應該有為時過早之嫌。可是,X框架真的已經做好準備了嗎?
開啟從SourceForge
不需要對開源文化有多麼深刻的瞭解,只要曾經用過一些主流的開源產品,你就應該知道:一個開源軟體至少應該同時提供原始碼釋出包和二進位制釋出包,原始碼包中至少應該有所有必需的依賴庫檔案(或者把依賴庫單獨打包釋出)、完整的單元測試用例(對於Java專案通常是Junit測試套件)、以及執行編譯構建的指令碼(對於
開源必讀:便捷構建 開源軟體應該提供最便捷的構建方式,讓使用者可以只輸入一條命令就完成整個專案的編譯、構建和測試,並得到可執行的二進位制程式。對於Java專案,這通常意味著提供完整的JUnit測試套件和Ant指令碼。你的潛在使用者可能會在一天之內試用所有類似的開源軟體,如果一個軟體需要他用半天時間才能完成構建、而且還無從驗證正確性、無從著手編寫他自己的測試用例,這個軟體很可能在第一時間被扔到牆角。 |
從SourceForge的專案頁面可以看到,X框架的授權協議是Apache License V2.0(APL)。然而在它的釋出包中,筆者沒有看到任何形式的正式授權協議文字。眾所周知,SourceForge的專案描述是可以隨時修改的(X框架本身的授權協議就曾經是GPL),如果釋出包中沒有一份正式的授權協議文字,一旦作者修改了SourceForge的專案描述,使用者又該到哪裡去尋找證據支援自己的合法使用呢?
在X框架的原始碼中,大部分原始檔在開始處加上了APL的授權宣告,但有一部分原始碼很是令人擔心。例如UtilCache這個類,開始處沒有任何授權宣告,而JavaDoc中則這樣宣告作者資訊:
@author<a href="mailto:[email protected]ofbiz.org">David E. Jones</a>
也就是說,這個類的原始碼來自另一個開源專案Ofbiz。值得一提的是,Ofbiz一直是“商業開源”的倡導者,它的授權協議相當嚴格。凡是使用Ofbiz原始碼,必須將它的授權協議一併全文複製。像X框架這樣複製Ofbiz原始碼、卻刪掉了授權協議的行為,實際上已經構成了對Ofbiz的侵權。
另外,作者打包用的壓縮格式是RAR,而這個壓縮格式對於商業使用者是收費的。對於一個希望在商業專案中應用的框架專案來說,選擇這樣一個壓縮格式實在算不得明智。而且筆者在原始碼包中還看到了好幾個.jbx檔案,這是JBuilder的專案描述檔案。把這些JBuilder專用的檔案放在原始碼包中,又怎能讓那些買不起或是不想買JBuilder的使用者放心呢?更何況,出於朋友的關心,筆者還不得不擔心X框架的作者是否會收到Borland公司的律師信呢。
開源必讀:授權先行 在啟動一個開源專案時,第一件大事就是要確定自己的授權協議,並在最醒目的地方用最正式的方式向所有人宣告——當然,在此之前你必須首先了解各種開源授權協議。譬如說,GPL(Linux採用的授權協議)要求在軟體之上的擴充套件和衍生也必須繼承GPL,因此這種協議對軟體的商業化應用很不友好;相反,APL則允許使用者將軟體的擴充套件產物私有化,便於商業應用,卻不利於開發者社群的發展。作為一個開源專案的領導者,對於各種授權協議的利弊是不可不知的。 除了原始碼本身的授權協議之外,軟體需要使用的類庫、IDE、解壓工具等等都需要考慮授權問題。開源絕對不僅僅意味著“免費使用”,開源社群的人們有著更加強烈的版權意識和法律意識。如果你的開源軟體會給使用者帶來潛在的法律麻煩,它離著被拋棄的命運也就不遠了。 |
可以看到,不管從法律的角度還是從釋出形式的角度,X框架都遠夠不上“Production/Stable”的水準——說實在的,以它的成熟度,頂多只能算是一個尚未計劃周全的開源專案。雖然作者在自己的網站上大肆宣傳,但作為一個潛在的使用者,我不得不冷靜地說:即便X框架的技術真的能夠吸引我,但它遠未成熟的專案形態決定了它根本無法在任何有實際意義的專案中運用。要讓商業使用者對它產生興趣,作者需要做的工作還很多。
我剛才說“即便X框架的技術真的能夠吸引我”,這算得上是一個合理的假設嗎?下面,就讓我們進入這個被作者寄予厚望的框架內部,看看它的技術水平吧。
整體架構
在X框架的宣傳頁面上,我們看到了這樣的宣傳詞:
X框架解決了以往J2EE開發存在的諸多問題:EJB難用、J2EE層次複雜、DTO太亂、Struts繞人、快取難做效能低等。X框架是Aop/Ico[注:應為“IoC”,此處疑似筆誤]的實現,優異的快取效能是其優點。
下面是X框架的整體架構圖:
可以看到,在作者推薦的架構中,EJB被作為業務邏輯實現的場所,而POJO被用於實現Façade。這是一個好的技術架構嗎?筆者曾在一篇Blog中這樣評價它[1]:
讓我們先回想一下,使用EJB的理由是什麼?常見的答案有:可分佈的業務物件;宣告性的基礎設施服務(例如事務管理)。那麼,如果在EJB的上面再加上一層POJO的Façade,顯然你不能再使用EJB的基礎設施了,因為完整的業務操作(也就是事務邊界)將位於POJO Façade的方法這裡,所以你必須重新——以宣告性的方式——實現事務管理、安全性管理、remoting、快取等基礎設施服務。換句話說,你失去了 session bean的一半好處。另一方面,“可分佈的業務物件”也不復存在,因為POJO本身是不能——像EJB那樣——分佈的,這樣你又失去了session bean的另一半好處。
繼續回想,使用基於POJO的輕量級架構的理由是什麼?常見的答案有:易於測試;便於移植;“開發-釋出”週期短。而如果僅僅把POJO作為一層Façade,把業務邏輯放在下面的EJB,那麼你仍然無法輕易地測試業務邏輯,移植自然也無從談起了,並且每次修改EJB之後必須忍受漫長的釋出週期。即便是僅僅把EJB作為O/R mapping,而不是業務邏輯的居所,你最多隻能通過DAO封裝獲得比較好的業務可測性,但“修改-釋出”的週期仍然很長,因為仍然有entity bean存在。也就是說,即使是往最好的方面來說,這個架構至少損失了輕量級架構的一半優點。
作為一個總結,X框架即便是在使用得最恰當的情況下,它仍然不具備輕量級架構的全部優點,至少會對小步前進的敏捷開發造成損害(因為EJB的存在),並且沒有Spring框架已經實現的基礎設施(例如事務管理、remoting 等),必須重新發明這些輪子;另一方面,它也不具備EJB的任何優點,EJB的宣告性基礎設施、可分佈業務物件等能力它全都不能利用。因此,可以簡單地總結說,X框架是一個這樣的架構:它結合了EJB和輕量級架構兩者各自的短處,卻拋棄了兩者各自的長處。
在不得不使用EJB的時候,一種常見的架構模式是:用session bean作為Façade,用POJO實現可移植、可測試的業務邏輯。這種模式可以結合EJB和POJO兩者的長處。而X框架推薦的架構模式,雖然乍看起來也是依葫蘆畫瓢,效果卻恰恰相反,正可謂是“取其糟粕、去其精華”。
開源必讀:架構必須正確 在開源軟體的初始階段,功能可以不完善,程式碼可以不漂亮,但架構思路必須是正確的。即使你沒有完美的實現,參與開源的其他人可以幫助你;但如果架構思路有嚴重失誤,誰都幫不了你。從近兩年容器專案的更迭就可以看出端倪:PicoContainer本身只有20個類、數百行程式碼,但它有清晰而優雅的架構,因此有很多人為它貢獻外圍的功能;Avalon容器儘管提供了完備的功能,但架構的落伍迫使Apache基金會只能將其全盤廢棄。 所以如果你有志於啟動一個開源專案(尤其是框架性的專案),務必先把架構思路拿出來給整個社群討論。只要大家都認可你的架構,你就有機會得到很多的幫助;反之,恐怕你就只能得到無盡的嘲諷了。 |
技術細節
既然整體架構已經無甚可取之處,那麼X框架的實現是否又像它所宣稱的那樣,能夠解決諸多問題呢?既然X框架號稱是“AOP/IoC的實現”,我們就選中這兩項技術,看看它們在X框架中的實現和應用情況。
IoC
X框架宣稱自己是一個“基於IoC的應用框架”。按照定義,框架本身就具有“業務程式碼不呼叫框架,框架呼叫業務程式碼”的特性,因此從廣義上來說,所有的框架必然是基於IoC模式的。所以,在框架這裡,“基於IoC”通常是特指“物件依賴關係的管理和組裝基於IoC”,也就是Martin Fowler所說的Dependency Injection模式[2]:由容器統一管理元件的建立和組裝,元件本身不包含依賴查詢的邏輯。那麼,X框架實現IoC的情況又如何呢?
我們很快找到了ContainerWrapper這個介面,其中指定了一個POJO容器核心應該具備的主要功能:
public interface ContainerWrapper {
public void registerChild(String name);
public void register(String name, Class className);
public void register(String name, Class className, Parameter[] parameters);
public void register(String name, Object instance);
public void start();
public void stop();
public Collection getAllInstances();
public Object lookup(String name);
}
在這個介面的預設實現DefaultContainerWrapper中,這些功能被轉發給PicoContainer的對應方法。也就是說,X框架本身並沒有實現元件容器的功能,這部分功能將被轉發給其他的IoC元件容器(例如PicoContainer、Spring或HiveMind等)來實現。在ContainerWrapper介面的註釋中,我們看到了一句頗可玩味的話:
/**
* 封裝了Container,解耦具體應用系統和PicoContainer關係。
瞭解IoC容器的讀者應該知道,在使用PicoContainer或Spring等容器時,絕大多數POJO元件並不需要對容器有任何依賴:它們只需要是最普通的JavaBean,只需要實現自己的業務介面。既然對容器沒有依賴,自然也不需要“解耦”。至於極少數需要獲得生命週期回撥、因此不得不依賴容器的元件,讓它們依賴PicoContainer和依賴X框架難道有什麼區別嗎?更何況,PicoContainer是一個比X框架更成熟、更流行的框架,為什麼使用者應該選擇X框架這麼一個不那麼成熟、不那麼流行的框架夾在中間來“解耦”呢?
不管怎麼說,至少我們可以看到:X框架提供了元件容器的核心功能。那麼,IoC(或者說,Dependency Injection)在X框架中的應用又怎麼樣呢?眾所周知,引入IoC容器的目標就是要消除應用程式中氾濫的工廠(包括Service Locator),由容器統一管理元件的建立和組裝。遺憾的是,不論在框架內部還是在示例應用中,我們仍然看到了大量的工廠和Service Locator。例如作者引以為傲的快取部分,具體的快取策略(即Cache介面的實現物件)就是由CacheFactory負責建立的,並且使用的實現類還是硬編碼在工廠內部:
publicCacheFactory() {
cache = new LRUCache();
也就是說,如果使用者需要改變快取策略,就必須修改CacheFactory的原始碼——請注意,這是一個X框架內部的類,使用者不應該、也沒有能力去修改它。換句話說,使用者實際上根本無法改變快取策略。既然如此,那這個CacheFactory又有什麼用呢?
開源必讀:開放-封閉原則 開源軟體應該遵守開放-封閉原則(Open-Close Principle,OCP):對擴充套件開放,對修改封閉。如果你希望為使用者提供任何靈活性,必須讓使用者以擴充套件(例如派生子類或配置檔案)的方式使用,不能要求(甚至不能允許)使用者修改原始碼。如果一項靈活性必須通過修改原始碼才能獲得,那麼它對於使用者就毫無意義。 |
在示例應用中,我們同樣沒有看到IoC的身影。例如JdbcDAO需要使用資料來源(即DataSource物件),它就在構造子中通過Service Locator主動獲取這個物件:
public JdbcDAO() {
ServiceLocator sl = new ServiceLocator();
dataSource = (DataSource) sl.getDataSource(JNDINames.DATASOURCE);
同樣的情況也出現在JdbcDAO的使用者那裡。也就是說,雖然X框架提供了元件容器的功能,卻沒有(至少是目前沒有)利用它的依賴注入能力,僅僅把它作為一個“大工廠”來使用。這是對IoC容器的一種典型的誤用:用這種方式使用容器,不僅沒有獲得“自動管理依賴關係”的能力,而且也失去了普通Service Locator“強型別檢查”的優點,又是一個“取其糟粕、去其精華”的設計。
開源必讀:瞭解你自己 當你決定要在開源軟體中使用某項技術時,請確定你瞭解它的利弊和用法。如果僅僅為了給自己的軟體貼上“基於xx技術”的標籤而使用一種自己不熟悉的技術,往往只會給你的專案帶來負面的影響。 |
AOP
在X框架的原始碼包中,我們找到了符合AOP-Alliance API的一些攔截器,例如用於實現快取的CacheInterceptor。儘管——毫不意外地——沒有找到如何將這些攔截器織入(weave in)的邏輯或配置檔案,但我們畢竟可以相信:這裡的確有AOP的身影。可是,甫一深入這個“基於AOP的快取機制”內部,筆者卻又發現了更多的問題。
單從CacheInterceptor的實現來看,這是一個最簡單、也最常見的快取攔截器。它攔截所有業務方法的呼叫,並針對每次方法呼叫執行下列邏輯:
IF 需要快取
key = (根據方法簽名生成key);
IF (cache.get(key) == null)
value = (實際呼叫被攔截方法);
cache.put(key, value);
RETURN (cache.get(key));
ELSE
RETURN (實際呼叫被攔截方法);
看上去很好,基於AOP的快取實現就應該這麼做……可是,清除快取的邏輯在哪裡?如果我們把業務方法分為“讀方法”和“寫方法”兩種,那麼這個攔截器實際上只照顧了“讀方法”的情況。而“寫方法”被呼叫時會改變業務物件的狀態,因此必須將其操作的業務物件從快取中清除出去,但這部分邏輯在CacheInterceptor中壓根不見蹤影。如果快取內容不能及時清理的話,使用者從快取中取出的資訊豈不是完全錯誤的嗎?
被驚出一身冷汗之後,筆者好歹還是從幾個Struts action(也就是呼叫POJO Façade的client程式碼)中找到了清除快取的邏輯。原來X框架所謂“基於AOP的快取機制”只實現了一條腿:“把資料放入快取”和“從快取中取資料”的邏輯確實用攔截器實現了,但“如何清除失效資料”的邏輯還得散佈在所有的客戶程式碼中。AOP原本就是為了把快取這類橫切性(crosscutting)的基礎設施邏輯集中到一個模組管理,像X框架的這個快取實現,不僅橫切性的程式碼仍然四下散佈,連快取邏輯的相關性和概念完整性都被打破了,豈不是弄巧成拙麼?
開源必讀:言而有信 如果你在宣傳詞中承諾了一項特性,請務必在你的軟體中完整地實現它。不要僅僅提供一個半吊子的實現,更不要讓你的任何承諾放空。如果你沒有把握做好一件事,就不要承諾它。不僅對於開源軟體,對於任何軟體開發,這都是應該記住的原則。 |
更有趣的是,X框架的作者要求領域模型物件繼承Model基類,並聲稱這是為了快取的需要——事實也的確如此:CacheInterceptor只能處理Model的子物件。但只要對快取部分的實現稍加分析就會發現,這一要求完全是作者憑空加上的:用於快取物件的Cache介面允許放入任何Object;而Model儘管提供了setModified()、setCacheable()等用於管理快取邏輯的方法,卻沒有任何程式碼呼叫它們。換句話說,即便我們修改CacheInterceptor,使其可以快取任何Object,對X框架目前的功能也不會有任何影響。既然如此,又為什麼要給使用者憑空加上這一層限制呢?
退一萬步說,即使我們認為X框架今後會用Model的方法來管理快取邏輯,這個限制仍然是理由不足的。畢竟,目前X框架還僅僅提供了快取這一項基礎設施(infrastructure)而已。如果所有基礎設施都用“繼承一個基類”的套路來實現,當它真正提供企業級應用所需的所有基礎設施時,Model類豈不是要變得碩大無朋?使用者的領域物件豈不是再也無法移植到這個框架之外?況且,“由領域物件判斷自己是否需要快取”的思路本身也是錯誤的:如果不僅要快取領域物件,還要快取String、Integer等簡單物件,該怎麼辦?如果同一個領域物件在不同的方法中需要不同的快取策略,又該怎麼辦?X框架的設計讓領域物件揹負了太多的責任,而這些責任原本應該是通過AOP轉移到aspect中的。在X框架這裡,AOP根本沒有發揮它應有的效用。
開源必讀:避免繫結 開源軟體(尤其是框架類軟體)應該儘量避免對你的使用者造成繫結。能夠在POJO上實現的功能,就不要強迫使用者實現你的介面;能夠通過介面實現的功能,就不要強迫使用者繼承你的基類。尤其是Java語言只允許單根繼承,一旦要求使用者的類繼承框架基類,那麼前者就無法再繼承其他任何基類,這是一種非常嚴重的繫結,不論使用者和框架設計者都應當極力避免。 |
寫在最後
看完這篇多少有些尖刻的批評,恐怕讀者難免要怪責我“不厚道”——畢竟,糟糕的開源軟體堪比恆河沙數,為什麼偏要選中X框架大加撻伐呢?在此,我要給各位讀者、各位有志於開源的程式設計師一個最後、卻是最重要的建議:
開源必讀:切忌好大喜功 開源是一件長期而艱鉅的工作,對於只能用業餘時間參與的我們更是如此。做開源務必腳踏實地,做出產品首先在小圈子裡內部討論,然後逐漸擴大宣傳的圈子。切勿吹大牛、放衛星,把“未來的願景”當作“今天的承諾”來說——因為一旦工作忙起來,誰都不敢保證這個願景到哪天才能實現。 國人還有個愛好:凡事喜歡趕個年節“獻禮”,或是給自己綁上個“民族軟體”的旗號,這更是開源的大忌。凡是做過政府專案的程式設計師,想必都對“國慶獻禮”、“新年獻禮”之類事情煩不勝煩,輪到自己做開源專案時,又何苦把自己套進這個怪圈裡呢?當然,如果你的開源專案原本就是做給某些官老爺看的,那又另當別論。 |
所以,我的這位朋友怕也不能怪我刻薄:要不是他緊趕著拿出個遠未完善的版本“新年獻禮”,要不是他提前放出“AOP/IoC”的衛星,要不是他妄稱這個框架“代表民族軟體水平”,或許我還會誇他的程式碼頗有可看之處呢。有一句大家都熟悉的老話,筆者私以為所有投身開源者頗可借鑑,在此與諸位共勉:
長得醜不是你的錯……
[2]關於IoC模式和Dependency Injection模式,詳見Martin Fowler的《Dependency Injection與模式IoC容器》一文。(中譯本發表於《程式設計師》2004年第3期。
相關推薦
前車之覆,後車之鑑——開源專案經驗談
前車之覆,後車之鑑 ——開源專案經驗談<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> (本文發表於《程式設計師》2005年第2期)隨著開源文化的日益普及,“參
Android Hawk資料庫的原始碼解析,Github開源專案,基於SharedPreferences的的儲存框架
今天看了朋友一個專案用到了Hawk,然後寫了這邊文章 一、瞭解一下概念 Android Hawk資料庫github開源專案 Hawk是一個非常便捷的資料庫.操作資料庫只需一行程式碼,能存任何資料型別. 相信大家應該很熟悉SharedPreferences。它是一種輕量級的儲存簡單配置
貢獻Dubbo生態,阿里開源Nacos專案
阿里巴巴微服務開源專案Nacos於近期釋出v0.5.0版本,該版本主要包括了DNS-basedService Discovery,對Java 11的支援,持續優化Nacos產品使用者體驗,更深度的與Spring Cloud體系的閘道器整合等方面做了演進。 什麼是Nacos Nacos 是阿里
深入淺出:遠離法律風險,必須瞭解開源專案許可證
本文講開源專案的許可證(License)。 現在FOSS(Free Open Souce Software)的專案逐步增多,而且專案引進FOSS專案也越來越多,以提高我們開發的效率,避免重複造輪子。那麼在我們開心享用這些FOSS專案時,感嘆世界真美好,但我們有沒有認真去研讀過它們的許可證呢? 引進FOSS
積極參與開源專案,促進.NET Core生態社群發展
今天早上在微信群裡聊天聊到百度的SDK 已經支援.NET Core, 百度已經在3月份就支援了,想起當時還是我在他們的github上提的issue: https://github.com/Baidu-AIP/dotnet-sdk/issues/3。.NET Core生態社群的發展已經四年多時間,日趨完善,我們
Joint Development 基金會 加入 Linux 基金會,共同推動開源專案標準化
Linux 基金會和 Joint Development 基金會在12月11日聯合宣佈,將 Joint Development 基金會納入到 Linux 基金會之中,以便在專案開源標準化上更輕鬆的進行協作。 Joint Development 基金會是一個非盈利組織,組織
兩年沉澱,我的開源專案已上線!
轉載請註明出處:https://blog.csdn.net/guolin_blog/article/details/84886691 本文同步發表於我的微信公眾號,掃一掃文章底部的二維碼或在微信搜尋 郭霖 即可關注,每個工作日都有文章更新。 今天跟大家談談情懷。
快速開發android,離不開這10個優秀的開源專案
作為一名菜雞Android,時常瞻仰大佬們的開源專案是非常必要的。這裡我為大家收集整理了10個優秀的開源專案,方便我們日常開發中學習! 作者:ListenToCode部落格:https://www.jianshu.com/p/9742ce36b6a8 KnowWeather GitHub
這裡有10個優質Python開源專案,希望對你學習有幫助
導讀:在過去的一個月中,我們對近250個Python開源專案進行了排名,選出了前十。 我們比較了在此期間有新的釋出或是重大發布的專案。Mybridge AI基於多種因素對專案進行排名,以衡量其在專業人員眼中的質量。 開源專案對程式設計師大有裨益。希望你找到一個有意思的專案,讓你有所啟發。
開源專案幾點心得,Java架構必會幾大技術點
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興! Java架構必會幾大技術點關於學習架構,必須會的幾點技術 1. java反射技術 2. xml檔案處理 3. properties屬性檔案處理 4. 執行緒安全
3天200個開源專案,Swift程式語言資料大合集 以及43個優秀的Swift開源專案
Swift 基於C和Objective-C,是供iOS和OS X應用程式設計的全新語言,更加高效、現代、安全,可以提升應用效能,同時降低開發難度。 Swift仍然處於beta測試的階段,會在iOS 8釋出的時一同推出市場,用來取代現有的Objective-C語言。WWDC剛剛結束,在不到24小時的時
【大牛之路】大牛指導,報酬豐厚的開源專案---“谷歌程式設計之夏”
正文 What 這個問題,我們先來看看 Google 官方是怎麼說的:(出自 What is Google Summer of Code?) Google Summer of Code (GSoC) is a global progr
學習Swift,一定不能錯過的10大開源專案
為了指導開發者使用Swift進行開發,蘋果釋出了一系類的技術文件,比如The Swift Programming Language(中文)和Using Swift with Cocoa and Objective-C(中文),同時蘋果也開通了其官方Swift部落格,最
關於Android客戶端,阿里開源的最新專案。
一直以來都是以谷歌為模板,不知道以後的以後會不會以阿里為藍本?本篇純屬為了學習無其他任何的利益價值。 0.Android 容器化框架 Atlas Atlas 是由阿里巴巴移動團隊自研的手機淘寶安卓客戶端容器化框架,以容器化思路解決大規模團隊協作問題,實現並行開發、快速迭代和動態部署,
學習Swift,一定不能錯過的10大開源專案!
Alamofire是一個用Swift編寫的HTTP網路庫,由此前熱門開源專案AFNetworking的的作者mattt開發,可非常簡單地用於非同步網路通訊。 關於何時使用AFNetworking,何時使用Alamofire,可參看作者對兩種情況的分析,不過很好的一點是AFNetworking和Ala
最適合練手的10大機器學習開源專案,趕緊收藏!
本文推薦的10大機器學習開源專案是由Mybridge從250個機器學習開源專案中挑選出來的,Gi
開源專案event-stream被注入惡意程式碼,盜取區塊鏈錢包助記詞
我是今天上午朋友說的時候才發現的這個問題, 這篇推文及其附帶的 GitHub 連結大體是說每週 npm 下載量超過 200 萬的 package 被注入了惡意程式碼,黑客利用該惡意程式碼訪問熱門 JavaScript 庫,目標是 copay(開源比特幣錢包)及其衍生產品的使用者,以此竊取使用
Ant Design 聖誕“彩蛋”炸雷,開源專案為何失控了?
喜慶洋洋的聖誕節,技術圈也十分熱鬧。因為今天開源屆被一個前端 UI 框架的“彩蛋”掀翻天了。 事件起因是螞蟻金服的 Ant Design 框架,開發者別出心裁地在框架程式碼中埋下了一個會在聖誕節當天觸發的“彩蛋”。 如圖中所看到的,本來這應該是一個正常的藍色按
KubeCon + CloudNativeCon 2017 D1: CNCF 新格局與專案更新,新開源容器專案釋出_Kubernetes中文社群
➤ 前言 12月的 KubeCon + CloudNativeCon 北美站與 4 月的 DockerCon 一樣,都在數十年前就作為全美半導體中心的奧斯丁落地。以 Kubernetes 專案為代表的雲原生計算基金會(Cloud Native Computing Foundation,CNCF)就如同一輛列