LG Chem 開發新技術 電動車充電後可行駛 500 公里

電動車續航力有望加倍,南韓電池巨擘 LG Chem 宣布開發出新技術,電動車充電一次可行駛 400 至 500 公里,預計不久後就能量產。   韓國先驅報(Korea Herald)1 日報導,目前一般電動車充電後僅能行駛不到 200 公里。LG Chem 副會長兼執行長朴鎮洙表示,已研發出新技術,電動車行駛里程能增至 400至 500 公里。他說,產品不久就能投產,但拒絕透露更多細節。   LG Chem 砸錢投入開發,宣稱 2018 年研發費用將由當前的 6,000 億韓圜,提高到 9,000 億韓圜;未來 3 年研發人員也將增至 4,100 人。  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

深入理解JVM(③)虛擬機的類加載過程

前言

上一篇我們介紹到一個類的生命周期大概分7個階段:加載、驗證、準備、解析、初始化、使用、卸載。並且也介紹了類的加載時機,下面我們將介紹一下虛擬機中類的加載的全過程。主要是類生命周期的,加載、驗證、準備、解析和初始化這五個階段所執行的具體動作。

加載

類加載過程的第一個階段就是加載,在加載階段,Java虛擬機需要完成以下三件事情:

1. 通過一個類的全限定名來獲取定義此類的二進制字節流。
2. 將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。
3. 在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口。
《Java虛擬機規範》對這三點要求其實並不是特別具體,這樣留給虛擬機實現和Java應用的靈活度都是相當大的。僅第一條,獲取二進制字節流,並沒有有指出從哪裡獲取,如何獲取。這樣就已經能被我們的Java開發人員玩出各種花樣了。
例如:

  • 從ZIP包中讀取(JAR、EAR、WAR)。
  • 從網絡中獲取(Web Applet)。
  • 運行時計算生成,最典型的就是動態代理技術,在java.lang.reflect.Proxy中,就是用了ProxyGenerator.generateProxyClass()來為特定接口生成形式為“$Proxy”的代理類的二進制字節流。
  • 由其他文件生成(JSP)。
  • 從數據庫中讀取。
  • 從加密文件中獲取(防止被反編譯獲取源碼)。
  • …….. …..

相對於類加載的其他階段,非數組類型的加載階段是開發人員可控性最強的階段。加載階段即可以使用Java虛擬機里內置的引導類加載器完成,也可以由用戶自定義的類加載器去完成。

驗證

驗證這一階段的目的是確保Class文件的字節流中包含的信息符合《Java虛擬機規則》的全部約束要求,保證這些信息被當作代碼運行后不會危害虛擬機自身安全。
驗證階段大致上會完成下面四個階段的檢驗動作:
文件格式驗證、元數據驗證、字節碼驗證和複合引用驗證

文件格式驗證

這是驗證的第一個階段,主要是驗證字節流是否符合Class文件格式的規範,並且能被當前版本的虛擬機處理。
這一階段的驗證點有:

  • 是否以魔數0xCAFEBABE開頭。
  • 主、次版本號是否在當前Java虛擬機接受範圍之內。
  • 常量池的常量中是否有不被支持的常量類型。
  • 指向常量的各種索引值是否有指向不錯在的常量或不符合類的常量。

這個階段的驗證是基於二進制字節流進行的,只有通過了這個階段的驗證之後,這段字節流才被允許進入Java虛擬機內存的方法區中進行存儲,後面的階段都是基於方法區的存儲結構進行的,不會再直接讀取、操作字節流了。

元數據驗證

第二階段是對字節碼描述的信息進行語義分析,以保證其描述的信息符合《Java虛擬機規則》的要求,這個階段主要有以下一些驗證點:

  • 當前類是否有父類(除java.lang.Object外,所有類都應當有父類)。
  • 當前類的父類是否繼承了不允許被繼承的類(被final修飾的類)。
  • 如果當前類非抽象類,是否實現了父類或接口要求實現的所有方法。
  • 類中的字段、方法是否與父類產生矛盾。
字節碼驗證

第三階段是整個驗證過程最複雜的一個階段,主要目的是通過數據流分析和孔劉分析,確定程序語義是合法的、符合邏輯的。
為了保證被校驗的方法在運行時不會做出危害虛擬機的安全的行為,主要做了如下一些校驗:

  • 保證任意時刻操作棧的數據類型與指令代碼序列都能配合工作,例如不會出現類似於“在操作放置了一個int類型數據,使用時卻按long類型來加載如本地變量表中”這樣的情況。
  • 保證任何跳轉指令都不會跳轉到方法體以外的字節碼指令上。
  • 保證方法體中的類型轉換總是有效的。例如:一個子類對象賦值給父類數據類型,這是安全的,但是把父類對象賦值為子類數據類型,獲取賦值給另外一個毫無關係的數據類型,則是不合法的。
  • … …

如果一個類型中有方法體的字節碼沒有通過字節碼驗證,那它肯定是有問題的;但如果一個方法體通過了字節碼驗證,也仍然不能保證它一定就是安全的。因為字節碼驗證也是在程序中進行的,即不能通過程序準確地檢查出程序是否能在有限時間之內結束運行。

符號引用驗證

最後一個階段的校驗行為發生在虛擬機將符號引用轉化為直接引用的時候,這個轉化動作將在連接的第三個階段——解析階段發生。
本階段通常需要校驗下列內容:

  • 符號引用中通過字符串描述的全限定名是否能找到對應的類。
  • 在指定類中是否存在符合方法的字段描述符及簡單名稱所描述的方法和字段。
  • 符合引用中的類、字段、方法的可訪問性,是否可被當前類訪問。

驗證階段對於虛擬機的類加載機制來說,是一個非常重要的、但卻不是必須要執行的階段,因為如果程序運行的全部代碼都已經被反覆使用和驗證過,在生成環境的實施階段就可以考慮使用-Xverify:none參數來關閉大部分的類驗證措施,來縮短類加載的時間。

準備

準備階段是正式為類中定義的變量分配內存並設置類變量的初始值的階段,這些變量所使用的內存都應當在方法區中進行分配,需要注意的是,這裏所說的方法區只是一個概念上的區域,在JDK7以及之前HotpSpot用永久代實現方法區,這個概念是正確的,但是在JDK8以及之後,類變量會隨着Class對象一起存放在Java堆中,這個時候類變量存在於方法區就僅僅是一個概念了。
在準備階段有兩點需要着重強調
1、在準備階段進行內存分配的僅包括類變量,而不包括實例變量,實例變量將會在對象實例化時隨着對象一起分配在Java堆中。
2、這裏所說的為類變量設置初始值,“通常情況”下是數據類的零值。
例如一個類變量定義為:

public static int value = 666;

那變量在準備階段過後的初始值為0而不為666,因為這個時候還未開始執行任何Java方法,而把value賦值為666的putstatic指令是程序被編譯后,存放於類構造器 ()方法之中,所以把value賦值為666的動作要到類的初始化階段才會被執行。

但是如果類字段的屬性表中存在ConstantValue屬性,那在準備階段變量值就會被初始化為ConstantValue屬性所指定的初始值,例如:

public static final int value = 666;

在編譯時Javac將會為value生成ConstantValue屬性,在準備階段虛擬機就會根據ConstantValue的設置將value賦值為666。

解析

解析階段是Java虛擬機將常量池內的符號引用替換為直接引用的過程,符號引用在Class文件中它以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等類型的常量出現。
先來解釋一下什麼是符號引用和直接引用。

  • 符號引用:符號引用以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。
  • 直接引用:直接引用是可以直接指向目標的指針、相對偏移量或者是一個能間接定位到目標的句柄。

解析動作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調用點限定這7類符號引用進行,分別對應於常量池的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info、CONSTANT_MehodType_info、CONSTANT_MethodHandle_info、CONSTANT_Dynamic_info和CONSTANT_InvokeDynamic_info
這8種常量類型。

初始化

初始化階段是類加載過程的最後一個步驟,之前介紹的幾個類加載的動作里,出了在加載階段用戶應用程序可以通過自定義類加載器的方式局部參与外,其餘動作都完全由Java虛擬機來主導控制。
簡單的來說,初始化階段就是執行類構造器<clinit>()方法的過程。那麼<clinit>()是如何執行的呢?

  • <clinit>()方法是由編譯器自動收集類中所有變量的複製動作和靜態語句塊(stataic{}塊)中的語句合併產生的,編譯器收集的順序是由語句在源文件中出現的的順序決定的,靜態語句塊中只能訪問到定義在靜態語句塊之前的變量,定義在它之後的變量,在前面的靜態語句塊可以賦值,但是不能訪問。
    例如:
  • <clinit>()方法與類的構造函數不同,它不需要顯式地調用父類構造器,Java虛擬機會保證在子類 ()方法執行前,父類 ()方法以及執行完畢。
  • 由於父類的<clinit>()方法先執行,即父類中定義的靜態語句塊要優先於子類的變量賦值操作。
    如下代碼運行結果會是 4
    父類
public class FatherClass {

    public static int fatherObject = 3;

    static {
        fatherObject = 4;
    }
}

子類

public class SonClass extends FatherClass{

    public static int sonObject = fatherObject;

}

測試

@Test
public void testClassLoad(){
    System.out.println(SonClass.sonObject);
}

運行結果

4
  • <clinit>()方法對於類或接口來說並不是必需的。
  • 接口中不能使用靜態語句塊,但仍然有變量初始化的賦值操作,因此接口與類一樣都會生成<clinit>()方法。
  • Java虛擬機必須保證一個類的<clinit>()方法在多線程環境中被正確地加鎖同步,若同時多個線程區初始化一個類,那麼只會有其中一個線程去執行這個類的<clinit>()方法,其他線程都需要阻塞等待,直到活動線程執行完畢<clinit>()方法。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

解讀兩會後新能源汽車盛況——第五屆中國國際新能源汽車論壇5月在滬召開

近些年,環保問題的凸顯,阻礙了傳統能源汽車快速前進的腳步,多地以環境保護的緣由實行限購限行等措施,而在此非常時期,新能源汽車的崛起和發展就越來越受到各方的關注。《穹頂之下》讓業界積極關注解決霧霾的辦法。工業燒煤與汽車尾氣排放是造成城市霧霾現象的主因,新能源替代煤炭與石油是保證中國可持續發展的主要措施,因此新能源汽車需要得到推廣也成為業界共識。

恰逢此時,新能源汽車技術日趨成熟,新能源汽車的崛起和發展已經受到越來越多的人關注,”兩會”期間,新能源汽車的發展成為代表們熱議的話題。新能源汽車的發展能否借助”兩會”的東風,走上快車道。

在連續四屆精彩紛呈的新能源汽車論壇和一屆亞太鋰電池峰會的基礎上,由希邁商務諮詢主辦,上海交大密西根學院、工信部賽迪顧問大力支持,並得到了亞太電動車協會陳清泉院士傾情指導的“第五屆中國國際新能源汽車論壇2015”將於2015年5月18日至19日在上海隆重召開。屆時將有三百位行業領導出席本次論壇。

部分已確認參會的公司如下:

工業和資訊化部中國電子資訊產業發展研究院、上海新能源汽車推進辦、比亞迪戴姆勒、特斯拉、樂視超級汽車(中國)有限公司、富豪汽車、通用汽車中國、上汽集團、中科力帆、江鈴汽車、揚州亞星客車股份有限公司、長城新能源、上海大眾聯合、中國電力企業聯合會、艾爾維、NEC、綠嘀汽車租賃(北京)有限公司、泰國國家石油公司、ATL、飛思卡爾、東莞振華新能源等等。

會議結構

  上午 下午
大會第一天

“智”造時代政策預測、製造趨勢及試點城市推廣情況

工信部、科技部、交通部、發改委及地方政府的政策支持
下一代電動汽車產品及商業模式
國內外整車商新能源新動向

新能源汽車電機及控制系統

新能源汽車開發特點及供應配套要求
動力總成電氣化
變速器和電驅動的開發技術與實踐

大會第二天

基礎設施引領商業新模式

充電基礎設施建設的市場分析
能源互聯網電動汽車項目
實現高效、智慧、規範的網路化建設與運營

新能源汽車市場新常態

樂視——重新定義汽車
谷歌更酷的下一步:無人駕駛
無線充電技術新突破
車身輕量化

微型電動車市場准入

政策准入前景
市場格局變化
電池技術路線選擇

動力電池突破之路

動力電池未來商業模式、技術路線探索
燃料電池及材料研發
智慧電池以及電動車動力管理系統

      整車廠商-電池企業對接洽談會

據悉,中國國際新能源汽車論壇將吸引來自國內外主流參會企業和嘉賓,預計將達到300人左右。相對規模與檔次都名列亞洲前茅,學習促進行業發展,業主相互技藝分享,充分享受資源平臺,創造最大企業價值。

連絡人:Hill ZENG(曾先生)
電話:+86-21-6045 1760
傳真:+86-21-6047 5887
郵箱:
唯一報名官方網址:

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

為在中國實現國產 特斯拉將與重慶車企合作電動車?

昨(17)日, 重慶整車製造企業力帆集團在其微信公眾號上稱特斯拉汽車公司的投資及政府關係總監肯•摩根一行於3月16日造訪了力帆集團,並與力帆高層就電動車領域的充電站建設、電池、投入與使用成本等話題進行了深入交流。   據力帆集團高層介紹,肯•摩根對力帆純電動汽車底盤換電池技術十分感興趣。力帆純電動汽車底盤換電池技術已於去年4月獲得了國家發明專利,該技術對換電池過程實現了全智慧控制,換電池時間可控制在3分鐘以內。   此外,肯•摩根還造訪了長安新能源汽車。有知情人士透露,長安也是特斯拉的潛在合作夥伴。長安汽車之前計畫斥資180億元人民幣投入到研發、技術、供應、運營四個領域,2015至2025年將分三個階段推出共計34款新能源產品,其中純電動車佔多數。   特斯拉CEO埃隆•馬斯克此前不止一次稱特斯拉會在2-3年內在中國達到國產。有業內人士表示,此次特斯拉來渝探營,將有可能促進重慶車企與特斯拉聯手,打造純電動汽車。 

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

增長率為76% 全球電動車市場達74萬輛車

德國Baden-Württemberg省的太陽能和氫能研究中心(ZSW)日前發佈的一份報告透露,全球電動汽車市場目前已達74萬輛車,其中幾乎有一半(32萬)註冊於2014年。基於電動車約為76%的增長率,去年汽車電池供應商的收益為20億歐元。   其中,美國市場增長69%,本土道路上的電動汽車數量增至29萬輛,占全球的三分之一。而中國是世界上第三最強大的電動車市場,2014年增加了約5萬4千輛,增長了120%,全國道路上接近有10萬輛電動車,僅次於擁有11萬電動車(2014年45%的速度增長)的日本。   該德國中心發現,這三個主要國家的扶持政策説明加速電動汽車的採用。在中國,例如,國產電動車是被補貼的,對終端消費者來講比較便宜。而德國相反,沒有市場激勵機制,從而只有11700新車註冊。   此外,該報告還發現,日產的Leaf是最流行的電動車品牌,創下了自2010年以來15萬的全球註冊記錄。第二是通用汽車公司的雪佛蘭Volt,全球註冊75000輛,第三為6萬註冊量的豐田Prius。而特斯拉S型已售出5萬輛,遙遙領先15000輛的寶馬的i3,事實上,i3才在市場上超過12個月,因此在這麼短時間內已具有這樣的市場份額,是令人印象深刻的。   2012年和2014年之間新車註冊數量每年增加兩倍。“如果近幾年的勢頭依然不減,在短短幾個月的時間裡,全球電動車的數量將超過百萬。”ZSW電化學能源技術事業部主任Werner Tillmetz表示。 

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

使用Apache Hudi構建大規模、事務性數據湖

一個近期由Hudi PMC & Uber Senior Engineering Manager Nishith Agarwal分享的Talk

關於Nishith Agarwal更詳細的介紹,主要從事數據方面的工作,包括攝取標準化,數據湖原語等。

什麼是數據湖?數據湖是一個集中式的存儲,允許以任意規模存儲結構化和非結構化數據。你可以存儲原始數據,而不需要先轉化為結構化的數據,基於數據湖之上可以運行多種類型的分析,如dashboard、大數據處理的可視化、實時分析、機器學習等。

接着看看對於構建PB級數據湖有哪些關鍵的要求

第一個要求:增量攝取(CDC)

企業中高價值的數據往往存儲在OLTP中,例如下圖中,users表包含用戶ID,國家/地區,修改時間和其他詳細信息,但OLTP系統並未針對大批量分析進行優化,因此可能需要引入數據湖。同時一些企業採用備份在線數據庫的方式,並將其存儲到數據湖中的方法來攝取數據,但這種方式無法擴展,同時它給上游數據庫增加了沉重的負擔,也導致數據重寫的浪費,因此需要一種增量攝取數據的方法。

第二個要求:Log Event去重

考慮分析大規模時間序列數據的場景,這些事件被寫入數據管道,並且數量非常大,可達數十億,每秒可達百萬的量。但流中可能有重複項,可能是由於至少一次(atleast-once)保證,數據管道或客戶端失敗重試處理等發送了重複的事件,如果不對日誌流進行重複處理,則對這些數據集進行的分析會有正確性問題。下圖是一個示例日誌事件流,其中事件ID為唯一鍵,帶有事件時間和其他有效負載。

第三個要求:存儲管理(自動管理DFS上文件)

我們已經了解了如何攝取數據,那麼如何管理數據的存儲以擴展整個生態系統呢?其中小文件是個大問題,它們會導致查詢引擎的開銷並增加文件系統元數據的壓力。而如果寫入較大的文件,則可能導致攝取延遲增加。一種常見的策略是先攝取小文件,然後再進行合併,這種方法沒有標準,並且在某些情況下是非原子行為,會導致一致性問題。無論如何,當我們寫小文件並且在合併這些文件之前,查詢性能都會受到影響。

第四個要求:事務寫(ACID能力)

傳統數據湖在數據寫入時的事務性方面做得不太好,但隨着越來越多的業務關鍵處理流程移至數據湖,情況也在發生變化,我們需要一種機制來原子地發布一批數據,即僅保存有效數據,部分失敗必須回滾而不會損壞已有數據集。同時查詢的結果必須是可重複的,查詢端看不到任何部分提取的數據,任何提交的數據都必須可靠地寫入。Hudi提供了強大的ACID能力。

第五個要求:更快地派生/ETL數據(增量處理)

僅僅能快速攝取數據還不夠,我們還需要具有計算派生數據的能力,沒有這個能力,數據工程師通常會繞過原始表來構建其派生/ETL並最終破壞整個體繫結構。下面示例中,我們看到原始付款表(貨幣未標準化)和發生貨幣轉換的派生表。

擴展此類數據管道時很有挑戰,如僅對變更進行計算,或者基於窗口的Join的挑戰。對基礎數據集進行大規模重新處理不太可能,這會浪費計算資源。需要在數據湖上進行抽象以支持對上游表中已更改的行(數據)進行智能計算。

第六個要求:法律合規/數據刪除(更新&刪除)

近年來隨着新的數據保護法規生效,對數據保留有了嚴格的規定,需要刪除原始記錄,修複數據的正確性等,當需要在PB級數據湖中高效執行合規性時非常困難,如同大海撈針一般,需要高效的刪除,如進行索引,對掃描進行優化,將刪除記錄有效地傳播到下游表的機制。

要求回顧(匯總)

  • 支持增量數據庫變更日誌攝取。
  • 從日誌事件中刪除所有重複項。
  • Data Lake必須為其數據集提供有效的存儲管理
  • 支持事務寫入
  • 必須提供嚴格的SLA,以確保原始表和派生表的數據新鮮度
  • 任何數據合規性需求都需要得到有效的支持
  • 支持唯一鍵約束
  • 有效處理遲到的數據

有沒有能滿足上面所有需求的系統呢?接下來我們引入Apache Hudi,HUDI代表Hadoop Upserts Deletes and Incrementals。從高層次講,HUDI允許消費數據庫和kafa事件中的變更事件,也可以增量消費其他HUDI數據集中的變更事件,並將其提取到存儲在Hadoop兼容,如HDFS和雲存儲中。在讀取方面,它提供3種不同的視圖:增量視圖,快照視圖和實時視圖。

HUDI支持2種存儲格式:“寫時複製”和“讀時合併”。

首先來看看寫時複製。如下圖所示,HUDI管理了數據集,並嘗試將一批數據寫入數據湖,HUDI維護稱為“提交時間軸(commit timeline)”的內容,以跟蹤HUDI管理的數據集上發生的操作/更改,它在提交時間軸上標記了一個“inflight”文件,表示操作已開始,HUDI會寫2個parquet文件,然後將“inflight”文件標記為已完成,這從原子上使該新數據寫入HUDI管理的數據集中,並可用於查詢。正如我們提到的,RO視圖優化查詢性能,並提供parquet的基本原始列存性能,無需增加任何額外成本。
現在假設需要更新另一批數據,HUDI在提交時間軸上標記了一個“inflight”文件,並開始合併這些更新並重寫Parquet File1。此時,由於提交仍在進行中,因此用戶看不到正在寫入任何這些更新(這就是我們稱為“快照隔離”)。最終以原子方式發布提交后,就可以查詢版本為C2的新合併的parquet文件。

COW已經在Uber投入運行多年,大多數數據集都位於COW存儲類型上。

儘管COW服務於我們的大多數用例,但仍有一些因素值得我們關注。以Uber的行程表為例,可以想象這可能是一個很大的表,它在旅程的整個生命周期中獲取大量更新。每隔30分鐘,我們就會獲得一組新旅行以及對舊旅行的一些更新,在Hive上的旅行數據是按天劃分分區的,因此新旅行最終會在最新分區中寫入新文件,而某些更新會在舊分區中寫入文件。使用COW,我們只能重寫那些更新所涉及的文件,並且能夠高效地更新。由於COW最終會重寫某些文件,因此可以像合併和重寫該數據一樣快。在該用例中通常大於15分鐘。再來看另外一種情況,由於某些業務用例(例如GDPR),必須更新大量歷史行程,這些更新涉及過去幾個月數據,從而導致很高的寫入延遲,並一遍又一遍地重寫大量數據,寫放大也會導致大量的IO。若為工作負載分配的資源不足,可能就會嚴重損害攝取延遲。

在真實場景中,會將ETL鏈接在一起來構建數據管道,問題會變得更加複雜。

對問題進行總結如下:在COW中,太多的更新(尤其是雜亂的跨分區/文件)會嚴重影響提取延遲(由於作業運行時間較長且無法追趕上入流量),同時還會引起巨大的寫放大,從而影響HDFS(相同文件的48個版本+過多的IO)。合併更新和重寫parquet文件會限制我們的數據的新鮮度,因為完成此類工作需要時間 = (重寫parquet文件所花費的時間*parquet文件的數量)/(并行性)。

在COW中,我們實際上並沒有太大的parquet文件,因為即使只有一行更新也可能要重寫整個文件,因為Hudi會選擇寫入小於預期大小的文件。

MergeOnRead將所有這些更新分組到一個文件中,然後在稍後的時刻創建一個新版本。對於重更新的表,重寫大文件會導致開銷變大。

如何解決上述寫放大問題呢?除了將更新合併並重寫parquet文件之外,我們將更新寫入增量文件中,這可以幫助我們降低攝取延遲並獲得更好的新鮮度。

將更新寫入增量文件將需要在讀取端做額外的工作以便能夠讀取增量文件中記錄,這意味着我們需要構建更智能,更智能的讀取端。

首先來看看寫時複製。如下圖所示,HUDI管理了數據集,並嘗試將一批數據寫入數據湖,HUDI維護稱為“提交時間軸(commit timeline)”的內容,以跟蹤HUDI管理的數據集上發生的操作/更改,它在提交時間軸上標記了一個“inflight”文件,表示操作已開始,HUDI會寫2個parquet文件,然後將“inflight”文件標記為已完成,這從原子上使該新數據寫入HUDI管理的數據集中,並可用於查詢。正如我們提到的,RO視圖優化查詢性能,並提供parquet的基本原始列存性能,無需增加任何額外成本。

現在需要進行第二次更新,與合併和重寫新的parquet文件(如在COW中一樣)不同,這些更新被寫到與基礎parquet文件對應的增量文件中。RO視圖繼續查詢parquet文件(過時的數據),而RealTime View(Snapshot query)會合併了parquet中的數據和增量文件中的更新,以提供最新數據的視圖。可以看到,MOR是在查詢執行時間與較低攝取延遲之間的一個權衡。

那麼,為什麼我們要異步運行壓縮?我們實現了MERGE_ON_READ來提高數據攝取速度,我們希望儘快攝取較新的數據。而合併更新和創建列式文件是Hudi數據攝取的主要耗時部分。

因此我們引入了異步Compaction步驟,該步驟可以與數據攝取同時運行,減少數據攝取延遲。

Hudi將事務引入到了大規模數據處理中,實際上,我們是最早這樣做的系統之一,最近,它已通過其他項目的類似方法獲得了社區認可。

Hudi支持多行多分區的原子性提交,Hudi維護一個特殊的文件夾.hoodie,在該文件夾中記錄以單調遞增的時間戳表示的操作,Hudi使用此文件夾以原子方式公開已提交的操作;發生的部分故障會透明地回滾,並且不會影響讀者和後面的寫入;Hudi使用MVCC模型將讀取與併發攝取和壓縮隔離開來;Hudi提交協議和DFS存儲保證了數據的持久寫入。

下面介紹Hudi在Uber的使用情況

Hudi管理了超過150PB數據湖,超過10000張表,每天攝入5000億條記錄。

接着看看Hudi如何替代分析架構。利用Hudi的upsert原語,可以在攝取到數據湖中時實現<5分鐘的新鮮度,並且能繼續獲得列式數據的原始性能(parquet格式),同時使用Hudi還可以獲得實時視圖,以5-10分鐘的延遲提供dashboard,此外HUDI支持的增量視圖有助於長尾效應對數據集的突變。

為方便用戶能快速使用Hudi,Hudi提供了一些開箱即用的工具,如HoodieDeltaStreamer,在Uber內部,HoodieDeltaStreamer用來對全球網絡進行近實時分析,可用來消費DFS/Kafka中的數據。

除了DeltaStreamer,Hudi還集成了Spark Datasource,也提供了開箱即用的能力,基於Spark,可以快速構建ETL管道,同時也可無縫使用Hudi + PySpark。

接着介紹更高級的原語和特性。

如何從損壞的數據中恢復?例如線上由於bug導致寫入了不正確的數據,或者上游系統將某一列的值標記為null,Hudi也可以很好的處理上述場景,可以將表恢復到最近的一次正確時間,如Hudi提供的savepoint就可以將不同的commit保存起來,用於後續恢復,注意MoR表暫時不支持savepoint;Hudi還提供了文件的版本號,即可以保存多個版本的文件,這對於CoW和MoR表都適用,但是會佔用一些存儲空間。

Hudi還提供便於增量ETL的高級特性,通過Spark/Spark便可以輕鬆增量拉取Hudi表的變更。

除了增量拉取,Hudi也提供了時間旅行特性,同樣通過Spark/Hive便可以輕鬆查詢指定版本的數據,其中對於Hive查詢中指定hoodie.table_name.consume.end.timestamp也馬上會得到支持。

下面看看對於線上的Hudi Spark作業如何調優。

下面列舉了幾個調優手段,設置Kryo序列化器,使用Shuffle Service,利用開源的profiler來進行內存調優,當然Hudi也提供了Hudi生產環境的調優配置,可參考【調優 | Apache Hudi應用調優指南】

下面介紹社區正在進行的工作,敬請期待。

即將發布的0.6.0版本,將企業中存量的parquet表高效導入Hudi中,與傳統通過Spark讀取Parquet表然後再寫入Hudi方案相比,佔用的資源和耗時都將大幅降低。以及對於查詢計劃的O(1)時間複雜度的處理,新增列索引及統一元數據管理以消除對DFS的文件list操作。

還有一些值得關注的特性,比如支持行級別的索引,該功能將極大降低upsert的延遲;異步數據clustering以優化存儲和查詢性能;支持Presto對MoR表的快照查詢;Hudi集成Flink,通過Flink可將數據寫入Hudi數據湖。

整個分享就介紹到這裏,歡迎觀看。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

特斯拉歐洲首座工廠落腳柏林 業界關注

摘錄自2019年11月13日中央社報導

特斯拉執行長馬斯克(Elon Musk)12日在柏林接受全國最大報「畫報」(Bild)集團頒獎時意外宣布,歐洲第一座超級電池廠將落腳在柏林地區。

柏林在地的「每日鏡報」(Der Tagesspiegel)報導,知情人士指出,特斯拉超級電池廠(Gigafactory)的預定地在柏林東南郊的工業區,鄰近即將在明年秋天啟用的新機場,行政區屬布蘭登堡邦(Brandenburg)。這座廠的規模相當於特斯拉目前在上海興建的新廠,預計2021年年底完工啟用,可望創造7000個工作機會。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

特斯拉拼了:中國車主貸款購車3年後可享50%回購

4月13日,特斯拉宣佈在中國推出保值承諾服務:在車主貸款購車三年後,如有車輛回購需求,特斯拉在經過條件審核後會以約50%的購入價格回購車主的Model S。這項服務此前已在北美、歐洲市場推出。而特斯拉則是目前唯一在中國推出保值回購服務的豪華汽車品牌。

  首先,車主須貸款購買Model S,貸款額度不少於車輛購入價的60%,且期數在36個月以上;其次,車主在三年內的行駛里程需少於6萬公里,超出部分將按照3.25元人民幣(下同)/公里扣除保值價格。已交車或全款購買的客戶都無法享受到這一服務,而已交付的車輛由於款項進賬等原因,也不再享受該服務。    另外,如果車輛在使用過程中發生意外損壞,回購服務也能進行。特斯拉將會對損耗車輛進行檢測,如果客戶是在特斯拉授權的維修店裡面進行維修,將有一本詳細的說明手冊,根據損耗程度相應的折價。

  無論購買P85D或是其他任一版本的Model S車型,回購的價格等於基礎車型價格的50%加上特定車型超過基礎車型價格部分的43%。基礎車價就是以購車當時最低版本和配置的車型來定。4月9號之前,特斯拉官方訂購平臺上的最基礎車型是Model S 60,就以60版本的價格計算。4月9日以後推出了70D,不再有60,則以70D版本價格計算。例如,客戶花100萬購買一輛特斯拉model S P85D車型,三年後可享有70D車價的50%+選裝配件(超過70D車價)的43%的回購資金,即可得47.795萬元。   車主在提車時即會獲得特斯拉出具的保值承諾服務函,並明確回購價格。符合上述條件的Model S車主,在辦理貸款購車後的第37個月期間內,可以作出如下選擇:留下Model S繼續使用;或者以保值價格把Model S賣給特斯拉。」留」或者」賣」的決策只能在貸款三年後的第一個月內作出,逾時則無法享受保值回購服務。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

電動車進駐大樓,ChargePoint 推出公寓大樓用電動車充電座

在美國,許多人都擁有寬敞的車庫,買了電動車就在車庫中設置充電座,然而若是市區中的大樓住戶,只能停在大樓地下室密密麻麻的停車格,買電動車可就麻煩了。電動車充電座製造商 ChargePoint 看見了這個問題,計劃推出公寓大樓用電動車充電座,解除大樓住戶購買電動車的障礙。    
  《富比世》報導,當特斯拉 Model S 電動車上市時,Gogoro 創辦人陸學森原本想要擁有一輛,但是第一個問題是在台灣沒有上市,就算進口一輛,台灣的住處大樓沒有獨立車庫,無法安裝幫 Model S 電動車充電的充電座,若非要開 Model S 電動車,只能在公司裝設充電座在公司充電,但這樣一來,週末就無法開出去兜風,豈不是大煞風景,最後陸學森在女友說服下,還是打退堂鼓。   這個困擾,其實也是各國所有大樓住戶的困擾,雖然以美國來說,如加州等地區路上設有充電站,不過電動車車主總是想要在家把電充飽飽才開出門,以免半路沒電,據美國能源部統計,80% 電動車都是在家充電,要是在家不能充電,購買電動車的意願就會降低,ChargePoint  執行長帕斯奎‧羅曼諾(Pasquale Romano)表示,除了少數例外,住大樓的人通常不買電動車,正是因為如此。   那要如何改善這個情況?羅曼諾認為,過去為了讓少數電動車主能在大樓停車場充電,大樓業主得全數自掏腰包在停車場設置充電座,投資風險很高,因此意願低落,但大樓業主如果並不用負擔充電座的設置費用,像大樓附設的投幣式自助洗衣機一樣,由業者來設置機器,這樣就成了。      
可吸引高收入使用者   2015 年 4 月,ChargePoint 宣布推出大樓專用的充電座系統,大樓業主不用負擔設置費用,這部分完全由 ChargePoint  吸收,大樓業主只需要為充電座連接電力即可,ChargePoint 會向用戶收取每月 39.99 美元的月費,電費部分則由住戶直接交給大樓業主,如果有電動車的住戶搬走了,ChargePoint 可以暫時關閉住戶所屬停車格的充電座,直到下一位有電動車的住戶入住才重新啟動,這樣一來,大樓業主的風險可說降到極低,勢必能提高安裝充電座的意願。   對大樓來說,提供停車場充電座設施,可吸引電動車車主,讓大樓更快租出,電動車車主又通常是高收入、高社經地位的良好住戶,對大樓有額外幫助;而對 ChargePoint 來說,能打進大樓這片處女地,是開拓新市場的絕佳機會,估計至 2020 年,美國將有 230 萬電動車主,其中有 10% 將會住在大樓內,這種合作方式對大樓與 ChargePoint 可說是雙贏局面。   想出免費贈送充電座商業模式的也不只 ChargePoint,曾經推出低價「開源碼」充電座的新創事業 EMotorWerks,2014 年推出特別活動,免費贈送原本售價 299 美元的 JuiceBox 充電座,條件是用戶要有可用的 Wi-Fi,讓充電座能將資訊傳給 EMotorWerks,以及用戶同意可由 EMotorWerks 來調整充電速度。    
 

    用戶只需要在行動裝置的專屬 App 上,告訴 EMotorWerks 何時要用車要充飽電力,EMotorWerks 會根據電力的離峰尖峰情況,自動調整充電速度,盡可能讓電力都在離峰時充電。在加州,尖峰電價可能高出平均電價 30 倍以上,避開尖峰時段充電可以為用戶節省大量電費;另一方面,也相當於為電網平衡離尖峰電力需求,如夜間風力發電過剩,可加速充電把多餘的電力用掉,尖峰時暫停充電,緩和尖峰負載。   EMotorWerks 未來的營收可望來自為用戶節省電費的服務、為電網調節平衡的服務,以及出售所收集的數據,為此,免費贈送充電座也划算。   EMotorWerks 的點子,也可能為 ChargePoint 採用,ChargePoint 充電座也可能成為大樓業主調節電力負載與電費支出的利器。無論如何,在充電座業者的推波助瀾下,電動車的充電障礙,將漸漸減輕。     本文全文授權轉載自《科技新報》─〈〉

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

一起玩轉微服務(14)——單元測試

作為一名java開發者,相信你或多或少的接觸過單元測試,對於測試來講它是一門能夠區分專業開發人員與業餘開發人員的重要學科,這篇文章將對java中最常見的一個單元測試框架junit進行一個梳理和講解。

為什麼需要單元測試

在平時的開發當中,一個項目往往包含了大量的方法,可能有成千上萬個。如何去保證這些方法產生的結果是我們想要的呢?當然了,最容易想到的一個方式,就是我們通過System.out來輸出我們的結果,看看是不是滿足我們的需求,但是項目中這些成千上萬個方法,我們總不能在每一個方法中都去輸出一遍嘛。這也太枯燥了。這時候用我們的單元測試框架junit就可以很好地解決這個問題。

junit如何解決這個問題的呢?答案在於內部提供了一個斷言機制,他能夠將我們預期的結果和實際的結果進行比對,判斷出是否滿足我們的期望。

預備工作

junit4是一個單元測試框架,既然是框架,這也就意味着jdk並沒有為我們提供api,因此在這裏我們就需要導入相關的依賴。

junit4是一個單元測試框架,既然是框架,這也就意味着jdk並沒有為我們提供api,因此在這裏我們就需要導入相關的依賴。

這裏的版本是4.12。當然還有最新的版本。你可以手動選擇。這裏選用的是4的版本。

案例

這裏我們要測試的功能超級簡單,就是加減乘除法的驗證。

然後我們看看如何使用junit去測試。

以上就是我們的單元測試,需要遵循一下規則:

  • •每一個測試方法上使用@Test進行修飾
  • •每一個測試方法必須使用public void 進行修飾
  • •每一個測試方法不能攜帶參數
  • •測試代碼和源代碼在兩個不同的項目路徑下
  • •測試類的包應該和被測試類保持一致
  • •測試單元中的每個方法必須可以獨立測試

以上的6條規則,是在使用單元測試的必須項,當然junit也建議我們在每一個測試方法名加上test前綴,表明這是一個測試方法。

assertEquals是一個斷言的規則,裏面有兩個參數,第一個參數表明我們預期的值,第二個參數表示實際運行的值。

我們運行一下測試類,就會運行每一個測試方法,我們也可以運行某一個,只需要在相應的測試方法上面右鍵運行即可。如果運行成功編輯器的控制台不會出現錯誤信息,如果有就會出現failure等信息。

運行流程

在上面的每一個測試方法中,代碼是相當簡單的,就一句話。現在我們分析一下這個測試的流程是什麼:

在上面的代碼中,我們使用了兩個測試方法,還有junit運行整個流程方法。我們可以運行一下,就會出現下面的運行結果:

從上面的結果我們來畫一張流程圖就知道了:

如果我們使用過SSM等其他的一些框架,經常會在before中添加打開數據庫等預處理的代碼,也會在after中添加關閉流等相關代碼。

註解

對於@Test,裏面有很多參數供我們去選擇。我們來認識一下

  • •@Test(expected=XX.class) 這個參數表示我們期望會出現什麼異常,比如說在除法中,我們1/0會出現ArithmeticException異常,那這裏@Test(expected=ArithmeticException.class)。在測試這個除法時候依然能夠通過。
  • •@Test(timeout=毫秒 ) 這個參數表示如果測試方法在指定的timeout內沒有完成,就會強制停止。
  • •@Ignore 這個註解其實基本上不用,他的意思是所修飾的測試方法會被測試運行器忽略。•@RunWith 更改測試運行器。

測試套件

如果我們的項目中如果有成千上萬個方法,那此時也要有成千上萬個測試方法嘛?如果這樣junit使用起來還不如System.out呢,現在我們認識一下測試嵌套的方法,他的作用是我們把測試類封裝起來,也就是把測試類嵌套起來,只需要運行測試套件,就能運行所有的測試類了。

下面我們使用測試套件,把這些測試類嵌套在一起。

 

 

 

參數化設置

什麼是參數化設置呢?在一開始的代碼中我們看到,測試加法的時候是1+1,不過我們如果要測試多組數據怎麼辦?總不能一個一個輸入,然後運行測試吧。這時候我們可以把我們需要測試的數據先配置好。

這時候再去測試,只需要去選擇相應的值即可,避免了我們一個一個手動輸入。

spring boot + junit

通過spring suite tools新建工程

 

 

1. Controller

@RestController
@RequestMapping
public class BookController {
    @RequestMapping("/books")
    public String book() {
        System.out.println("controller");
        return "book";
    }
}

Test1 引入Spring上下文,但不啟動tomcat

@RunWith(SpringRunner.class)
@SpringBootTest  //引入Spring上下文 -> 上下文中的 bean 可用,自動注入
public class BookControllerTest {
    
    @Autowired
    private BookController bookController;  //自動注入
    
    @Test
    public void testControllerExists() {
        Assert.assertNotNull(bookController);
    }
    
}

Test2 引入Spring上下文,且啟動Tomcat 模擬生產環境,接收Http請求

package com.cloud.skyme;

import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.junit4.SpringRunner;

/** * @author zhangfeng * web單元測試 * */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class Chapter0302junitApplicationTests {
	
	@LocalServerPort
    private int port;
	
	@Autowired
	private TestRestTemplate restTemplate;
    
    @Test
    public void testControllerExists() {
    	Assert.assertEquals(this.restTemplate.getForObject("http://localhost:" + port + "/books", String.class), "book");
    }

}

@RunWith(SpringRunner.class),讓測試運行於Spring測試環境,此註釋在org.springframework.test.annotation包中提供。
@SpringBootTest指定Sspring Bboot程序的測試引導入口。
TestRestTemplate是用於測試rest接口的模板類。
運行單元測試,測試上面邊構建的Wweb地址,可以看到輸出的測試結果與期望的結果相同.

運行單元測試,得到與期望相同的結果。

    
javascript    44行

13:31:03.722 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate] 13:31:03.739 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)] 13:31:03.801 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.cloud.skyme.Chapter0302junitApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper] 13:31:03.830 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.cloud.skyme.Chapter0302junitApplicationTests], using SpringBootContextLoader 13:31:03.837 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.cloud.skyme.Chapter0302junitApplicationTests]: class path resource [com/cloud/skyme/Chapter0302junitApplicationTests-context.xml] does not exist 13:31:03.838 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.cloud.skyme.Chapter0302junitApplicationTests]: class path resource [com/cloud/skyme/Chapter0302junitApplicationTestsContext.groovy] does not exist 13:31:03.838 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.cloud.skyme.Chapter0302junitApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}.
13:31:03.839 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.cloud.skyme.Chapter0302junitApplicationTests]: Chapter0302junitApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration. 13:31:03.918 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.cloud.skyme.Chapter0302junitApplicationTests] 13:31:04.070 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [C:\java\workspace\microservice\chapter0302junit\target\classes\com\cloud\skyme\Chapter0302junitApplication.class] 13:31:04.073 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.cloud.skyme.Chapter0302junitApplication for test class com.cloud.skyme.Chapter0302junitApplicationTests 13:31:04.225 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.cloud.skyme.Chapter0302junitApplicationTests]: using defaults. 13:31:04.226 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener] 13:31:04.243 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource] 13:31:04.244 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute] 13:31:04.244 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@7133da86, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@3232a28a, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@73e22a3d, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@47faa49c, org.springframework.test.context.support.DirtiesContextTestExecutionListener@28f2a10f, org.springframework.test.context.event.EventPublishingTestExecutionListener@f736069, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@6da21078, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@7fee8714, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@4229bb3f, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@56cdfb3b, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@2b91004a, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@20ccf40b] 13:31:04.250 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@6cd28fa7 testClass = Chapter0302junitApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@614ca7df testClass = Chapter0302junitApplicationTests, locations = '{}', classes = '{class com.cloud.skyme.Chapter0302junitApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@3b07a0d6, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@14d3bc22, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@45b9a632, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@5e316c74, org.springframework.boot.test.context.SpringBootTestArgs@1], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> false]], class annotated with @DirtiesContext [false] with mode [null]. 13:31:04.267 [main] DEBUG org.springframework.test.context.support.DependencyInjectionTestExecutionListener - Performing dependency injection for test context [[DefaultTestContext@6cd28fa7 testClass = Chapter0302junitApplicationTests, testInstance = com.cloud.skyme.Chapter0302junitApplicationTests@31fa1761, testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@614ca7df testClass = Chapter0302junitApplicationTests, locations = '{}', classes = '{class com.cloud.skyme.Chapter0302junitApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@3b07a0d6, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@14d3bc22, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@45b9a632, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@5e316c74, org.springframework.boot.test.context.SpringBootTestArgs@1], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> false]]].
13:31:04.306 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.3.1.RELEASE) 2020-06-28 13:31:04.940 INFO 8376 --- [ main] c.c.s.Chapter0302junitApplicationTests : Starting Chapter0302junitApplicationTests on WIN-55FHBQI56BD with PID 8376 (started by Administrator in C:\java\workspace\microservice\chapter0302junit) 2020-06-28 13:31:04.942 INFO 8376 --- [ main] c.c.s.Chapter0302junitApplicationTests : No active profile set, falling back to default profiles: default 2020-06-28 13:31:09.134 INFO 8376 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 0 (http) 2020-06-28 13:31:09.160 INFO 8376 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2020-06-28 13:31:09.161 INFO 8376 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.36] 2020-06-28 13:31:09.372 INFO 8376 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2020-06-28 13:31:09.372 INFO 8376 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4316 ms 2020-06-28 13:31:10.029 INFO 8376 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-06-28 13:31:10.655 INFO 8376 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 59724 (http) with context path '' 2020-06-28 13:31:10.673 INFO 8376 --- [ main] c.c.s.Chapter0302junitApplicationTests : Started Chapter0302junitApplicationTests in 6.362 seconds (JVM running for 8.218) 2020-06-28 13:31:11.423 INFO 8376 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2020-06-28 13:31:11.423 INFO 8376 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2020-06-28 13:31:11.461 INFO 8376 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 37 ms controller 2020-06-28 13:31:13.497 INFO 8376 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'

 

 這樣,一個web應用從構建到單元測試就都已經完成了,可見,構建一個Spring Web MVC的應用就是如此簡單。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心