COP25氣候峰會失敗的關鍵:巴黎協定第六條 嚴格國家訂《聖荷西原則》走自己的路

環境資訊中心記者 姜唯翻譯 林大利審校

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

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

特斯拉要在中國蓋工廠了!將在 2016 年中前完成選址

看來,特斯拉(Tesla)在中國的電動車銷量似乎不如外界先前預期差。特斯拉執行長馬斯克(Elon Musk)日前在香港參加科技論壇前夕受訪表示,特斯拉在中國的營運「相當良好」,將在中國設立工廠,並預計在 2016 年中前完成廠房選址。

雖然在受訪時,馬斯克未透露特斯拉在中國的具體銷售數字,但馬斯克表示,特斯拉在中國的營運狀況目前「相當良好」,似乎不受先前在中國的銷量遠低於預期影響,並表示,要在中國開啟特斯拉電動車製造計畫,正在尋找當地的合作夥伴與工廠,預計在 2016 年中前完成中國工廠選址。   與其他非中國的汽車製造商相同,特斯拉之所以要在中國興建工廠,關鍵的因素便在於要規避中國政府對進口車徵收的進口稅,以減少貨運開銷,讓特斯拉的電動車在中國市場更有競爭力。此外,中國政府鼓勵新能源汽車的發展,也是因素之一。   目前特斯拉在中國 7 個主要城市設有 15 個業務據點、超過 340 個超級充電站及逾 1,600 個充電樁。其中,光是香港就有 42 個超級充電站,使其成為特斯拉在中國快速擴張的充電網路中,充電站密度最高的城市,而特斯拉在香港的銷量也遠高於中國其他城市,2015 年 Model S 銷售量為 2,221 台,占了特斯拉 2015 年在中國所有銷量的 80%。   香港的電動車熱潮也讓馬斯克看見特斯在其中的潛在市場龐大。在 2014 年至 2015 年間,香港的電動車登記數字就飆升了 270%,馬斯克認為,之所以會有如此驚人的成長,歸因於香港政府的「優良政策」,帶動了電動車的銷量。此外,馬斯克透露,Model X 將會在 2016 下半年,隨著特斯拉在香港的新服務中心進軍香港。

(首圖來源: CC BY 2.0)

(本文授權轉載自《》─〈〉)

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

go語言教程之淺談數組和切片的異同

Hello ,各位小夥伴大家好,我是小棧君,上次分享我們講到了Go語言關於項目工程結構的管理,本期的分享我們來講解一下關於go語言的數組和切片的概念、用法和區別。

在go語言的程序開發過程中,我們避免不了數組和切片。關於他們的用法和區別卻使得有的小夥伴感覺困惑。所以小棧君這裏也歸納和總結了關於數組和切片的乾貨幫助小夥伴進行理解。

數組的定義

數組是具有相同唯一類型的一組已編號且長度固定的數據項序列,這種類型可以是任意的原始類型例如整形、字符串或者自定義類型。

相對於去聲明 number0, number1, …, number99 的變量,使用數組形式 numbers[0], numbers[1] …, numbers[99] 更加方便且易於擴展。

數組元素可以通過索引(位置)來讀取(或者修改),索引從 0 開始,第一個元素索引為 0,第二個索引為 1,以此類推。

總體來講的話數組就是同一種類型的固定長度的序列。

在go語言中數組的定義是很簡單的。

如圖所示,我們定義了一個長度為2的數組,在數組定義的過程中,系統已經對這個數組進行了初始化並分配了空間。所以我們如果想要進行賦值可以通過數組名加上下標的方式進行賦值。但是值得注意的一點是我們並不能進行數組的超長處理。這一點有別於java的數組定義,java的定長數組添加值后如果對於超出的值會有自動擴容功能。

但是在go語言中並沒有方法來進行增刪改查值,只有通過下標的方式,所以我們如果進行了越界處理編譯都會進行報錯。所以才入門的小夥伴們需要注意一下哦。數組的下標在數組的合法範圍之外就會出發訪問越界,會有panic出現。所以小棧君也是通過了一個實例給大家說明一下,因為編譯可能會不通過,所以我們巧妙的避開編譯器的編譯進行數組的越界操作說明。

當然需要值得注意的一點是,數組的長度也是數組類型的一部分,因此var a [2]int 和 var b [3] int 是兩個不同的類型。

知識點來了,在go語言中的數組是屬於值類型傳遞,當我們傳遞一個數組到一個方法中,改變副本的值並不會修改到原本數組的值。所以得到的數組還是原來的樣子。

因此如果我們要對數組進行值的修改的話,就只有進行指針操作啦~。

切片的概念

在go語言中數組中長度不可以更改,所以在實際的應用環境中並不是非常實用,所以Go語言衍生出了一種靈活性強和功能更強大的內置類型,即為切片。

與上面所講的數組相比,切片的長度是不固定的,並且切片是可以進行擴容。切片對象非常小,是因為它是只有3個字段的數據結構:一個是指向底層數組的指針,一個是切片的長度,一個是切片的容量。這3個字段,就是Go語言操作底層數組的元數據,有了它們,我們就可以任意的操作切片了。

當然,切片作為數組的引用,所以切片屬於是引用類型,各位小夥伴可千萬要記住了哦。在切片的使用過程當中,我們可以通過遍曆數組的方式進行對於切片的遍歷,我們也可以內置方法len對數組或切片進行長度的計算。

當然我們也可以對切片的容量進行計算,之前有講過Go語言有豐富的內置庫提供給我們使用,所以我們也可以cap內置函數進行容量的計算。多個切片如果表示同一個數組的片段,它們可以共享數據;因此一個切片和相關數組的其他切片是共享存儲的,相反,不同的數組總是代表不同的存儲。數組實際上是切片的構建塊。

上面的例子小棧君分別用數組和切片進行了測試,我們可以看到數組的容量一旦確定后就無法進行更改,當我們的切片進行初始化,初始的容量是2,此時切片的容量和長度都是2,但是我通過內置的append方法進行了切片的增加。此時的切片的容量和長度都是4。此時我們並不能確定切片內置擴容的機制,但是隱約猜測是倍增。

言歸正傳,為了測試一下切片的擴容機制,所以小棧君又進行了切片的增加,此時,細心的小夥伴應該發現,這次小棧君一次性增加了兩個元素在一個append裏面,因為這是append方法是一個可變長度的傳值。這也是一個小知識點哦。

如果切片的底層數組,沒有足夠的容量時,就會新建一個底層數組,把原來數組的值複製到新底層數組裡,再追加新值,這時候就不會影響原來的底層數組了。

append目前的算法是:容量小於1000個時,總是成倍的增長,一旦容量超過1000個,增長因子設為1.25,也就是說每次會增加25%的容量。

之後我們發現切片的容量和長度發生了變化,如果說上次容量的擴張是4是我們猜測的倍數擴容方式,那麼這次我們就實錘了他的擴容機制就是倍增。而且在Go語言的容量和長度不一樣,所以我們也可以得出結論,就是在 0 <= len(arry) <= cap(slice)。

在我們聲明好切片后我們可以使用new或是make方法對切片進行初始化,當然小棧君也試着嘗試證明切片如果沒有進行初始化是會panic的。結果並沒有出現。因為如果slice沒有初始化,它僅僅相當於一個nil,長度和容量都為0,並不會panic。

小棧君也考慮到可能是因為沒有內置增加方法或是沒有報錯僅僅只是因為我後面利用對Carry數組的切割進行賦值的緣故。所以不甘心又做了一次嘗試,定義好相應的切片后直接使用append方法,結果如下:

我們同樣可以通過上述的例子了解到切片的下標是左閉右開區間,因為我們carry數組的內容如上圖所示, 我們最終得到的結果是IT乾貨棧,下標來講的話是屬於1。所以我們得到的結論和事實是一樣的。對於切片我們也有很多用法,如下圖所示:

下圖是Python中對於切片的操作,並且Python中的數組更為靈活,在後面我為大家分享Python教程的時候會詳細分享哦。

切片的初始化

對於切片的初始化我們可以make方法和new方法

new(T) 為每個新的類型T分配一片內存,初始化為 0 並且返回類型為*T的內存地址:這種方法 返回一個指向類型為 T,值為 0 的地址的指針,它適用於值類型如數組和結構體;它相當於 &T{}。

make(T) 返回一個類型為 T 的初始值,它只適用於3種內建的引用類型:切片、map 和 channel。

拷貝

因為在go語言的數組是屬於值傳遞,之前的方法也證實了這一點,在方法傳遞值的時候系統會進行拷貝一份副本進行傳遞,如果需要改變的值的話就需要使用指針。但是在使用切片處理的時候,因為切片屬於引用傳遞,所以go語言有內置的函數copy方法進行值的拷貝。

上述的一個例子可以綜合說明幾點問題了,最開始我們定義了一個切片並且容量是2,內容是1和2,我們同樣定義了切片b但是並沒有做初始化處理。直接使用copy操作。使用copy操作的時候,小棧君也複製了源碼出來,第一個是我們的數據源,第二個參數傳遞我們的目標源。直接使用的話我們可以從結果看出並沒有成功。

所以接下來小棧君又進行了初始化操作。這裏舉例的目的是提醒各位,在操作切片的時候沒有初始化就相當於nil,最好是進行切片的初始化操作。在早期go語言的版本中,沒有初始化切片會直接報錯。接下來我又進行了再一次的複製操作並且打印出他們的地址和容量、長度。可以看出進行切片的拷貝是不會進行切片的擴容處理。而且他們分別指向了不同的地址說明拷貝成功。

好了,今天的分享就到這啦,如果你喜歡我的分享,麻煩你點擊一個好看或贊,我是小棧君,不定期分享IT乾貨,包括但不限於區塊鏈、大數據、Python、go、等系列專題。希望與你共同成長。我們下期再見啦,拜了個拜~

本文由博客一文多發平台 發布!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

2015年特斯拉共銷售50580輛電動汽車 完成年度銷售計畫

據報導,特斯拉日前宣佈2015年銷售了50580輛電動汽車,完成年度銷售計畫。

特斯拉稱,2015年第四季度Model S電動汽車銷量為17192輛,比上年同期增長75%,環比增長48%。該公司第四季度生產507輛Model X電動汽車,銷售208輛。特斯拉目前計畫每週生產238輛Model X。

特斯拉完成年度銷售計畫相當重要。特斯拉一直在嘗試大幅提高Model S產量,並首次生產Model X。

這是一個頗為困難的任務。特斯拉最初計畫2015年銷售55000輛電動汽車。由於同時生產兩款車型存在不少困難,特斯拉去年8月把銷售目標下調至50000-55000輛,去年11月份再次把銷售目標下調至50000-52000輛。

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

5種常見Bean映射工具的性能比對

本文由 JavaGuide 翻譯自 https://www.baeldung.com/java-performance-mapping-frameworks 。轉載請註明原文地址以及翻譯作者。

1. 介紹

創建由多個層組成的大型 Java 應用程序需要使用多種領域模型,如持久化模型、領域模型或者所謂的 DTO。為不同的應用程序層使用多個模型將要求我們提供 bean 之間的映射方法。手動執行此操作可以快速創建大量樣板代碼並消耗大量時間。幸運的是,Java 有多個對象映射框架。在本教程中,我們將比較最流行的 Java 映射框架的性能。

綜合日常使用情況和相關測試數據,個人感覺 MapStruct、ModelMapper 這兩個 Bean 映射框架是最佳選擇。

2. 常見 Bean 映射框架概覽

2.1. Dozer

Dozer 是一個映射框架,它使用遞歸將數據從一個對象複製到另一個對象。框架不僅能夠在 bean 之間複製屬性,還能夠在不同類型之間自動轉換。

要使用 Dozer 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer</artifactId>
    <version>5.5.1</version>
</dependency>

更多關於 Dozer 的內容可以在官方文檔中找到: http://dozer.sourceforge.net/documentation/gettingstarted.html ,或者你也可以閱讀這篇文章:https://www.baeldung.com/dozer 。

2.2. Orika

Orika 是一個 bean 到 bean 的映射框架,它遞歸地將數據從一個對象複製到另一個對象。

Orika 的工作原理與 Dozer 相似。兩者之間的主要區別是 Orika 使用字節碼生成。這允許以最小的開銷生成更快的映射器。

要使用 Orika 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
    <groupId>ma.glasnost.orika</groupId>
    <artifactId>orika-core</artifactId>
    <version>1.5.2</version>
</dependency>

更多關於 Orika 的內容可以在官方文檔中找到:https://orika-mapper.github.io/orika-docs/,或者你也可以閱讀這篇文章:https://www.baeldung.com/orika-mapping。

2.3. MapStruct

MapStruct 是一個自動生成 bean mapper 類的代碼生成器。MapStruct 還能夠在不同的數據類型之間進行轉換。Github 地址:https://github.com/mapstruct/mapstruct。

要使用 MapStruct 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2.0.Final</version>
</dependency>

更多關於 MapStruct 的內容可以在官方文檔中找到:https://mapstruct.org/,或者你也可以閱讀這篇文章:https://www.baeldung.com/mapstruct。

要使用 MapStruct 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2.0.Final</version>
</dependency>

2.4. ModelMapper

ModelMapper 是一個旨在簡化對象映射的框架,它根據約定確定對象之間的映射方式。它提供了類型安全的和重構安全的 API。

更多關於 ModelMapper 的內容可以在官方文檔中找到:http://modelmapper.org/ 。

要使用 ModelMapper 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
  <groupId>org.modelmapper</groupId>
  <artifactId>modelmapper</artifactId>
  <version>1.1.0</version>
</dependency>

2.5. JMapper

JMapper 是一個映射框架,旨在提供易於使用的、高性能的 Java bean 之間的映射。該框架旨在使用註釋和關係映射應用 DRY 原則。該框架允許不同的配置方式:基於註釋、XML 或基於 api。

更多關於 JMapper 的內容可以在官方文檔中找到:https://github.com/jmapper-framework/jmapper-core/wiki。

要使用 JMapper 框架,我們需要添加這樣的依賴到我們的項目:

<dependency>
    <groupId>com.googlecode.jmapper-framework</groupId>
    <artifactId>jmapper-core</artifactId>
    <version>1.6.0.1</version>
</dependency>

3.測試模型

為了能夠正確地測試映射,我們需要有一個源和目標模型。我們已經創建了兩個測試模型。

第一個是一個只有一個字符串字段的簡單 POJO,它允許我們在更簡單的情況下比較框架,並檢查如果我們使用更複雜的 bean 是否會發生任何變化。

簡單的源模型如下:

public class SourceCode {
    String code;
    // getter and setter
}

它的目標也很相似:

public class DestinationCode {
    String code;
    // getter and setter
}

源 bean 的實際示例如下:

public class SourceOrder {
    private String orderFinishDate;
    private PaymentType paymentType;
    private Discount discount;
    private DeliveryData deliveryData;
    private User orderingUser;
    private List<Product> orderedProducts;
    private Shop offeringShop;
    private int orderId;
    private OrderStatus status;
    private LocalDate orderDate;
    // standard getters and setters
}

目標類如下圖所示:

public class Order {
    private User orderingUser;
    private List<Product> orderedProducts;
    private OrderStatus orderStatus;
    private LocalDate orderDate;
    private LocalDate orderFinishDate;
    private PaymentType paymentType;
    private Discount discount;
    private int shopId;
    private DeliveryData deliveryData;
    private Shop offeringShop;
    // standard getters and setters
}

整個模型結構可以在這裏找到:https://github.com/eugenp/tutorials/tree/master/performance-tests/src/main/java/com/baeldung/performancetests/model/source。

4. 轉換器

為了簡化測試設置的設計,我們創建了如下所示的轉換器接口:

public interface Converter {
    Order convert(SourceOrder sourceOrder);
    DestinationCode convert(SourceCode sourceCode);
}

我們所有的自定義映射器都將實現這個接口。

4.1. OrikaConverter

Orika 支持完整的 API 實現,這大大簡化了 mapper 的創建:

public class OrikaConverter implements Converter{
    private MapperFacade mapperFacade;

    public OrikaConverter() {
        MapperFactory mapperFactory = new DefaultMapperFactory
          .Builder().build();

        mapperFactory.classMap(Order.class, SourceOrder.class)
          .field("orderStatus", "status").byDefault().register();
        mapperFacade = mapperFactory.getMapperFacade();
    }

    @Override
    public Order convert(SourceOrder sourceOrder) {
        return mapperFacade.map(sourceOrder, Order.class);
    }

    @Override
    public DestinationCode convert(SourceCode sourceCode) {
        return mapperFacade.map(sourceCode, DestinationCode.class);
    }
}

4.2. DozerConverter

Dozer 需要 XML 映射文件,有以下幾個部分:

<mappings xmlns="http://dozer.sourceforge.net"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://dozer.sourceforge.net
  http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <mapping>
        <class-a>com.baeldung.performancetests.model.source.SourceOrder</class-a>
        <class-b>com.baeldung.performancetests.model.destination.Order</class-b>
        <field>
            <a>status</a>
            <b>orderStatus</b>
        </field>
    </mapping>
    <mapping>
        <class-a>com.baeldung.performancetests.model.source.SourceCode</class-a>
        <class-b>com.baeldung.performancetests.model.destination.DestinationCode</class-b>
    </mapping>
</mappings>

定義了 XML 映射后,我們可以從代碼中使用它:

public class DozerConverter implements Converter {
    private final Mapper mapper;

    public DozerConverter() {
        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.addMapping(
          DozerConverter.class.getResourceAsStream("/dozer-mapping.xml"));
        this.mapper = mapper;
    }

    @Override
    public Order convert(SourceOrder sourceOrder) {
        return mapper.map(sourceOrder,Order.class);
    }

    @Override
    public DestinationCode convert(SourceCode sourceCode) {
        return mapper.map(sourceCode, DestinationCode.class);
    }
}

4.3. MapStructConverter

Map 結構的定義非常簡單,因為它完全基於代碼生成:

@Mapper
public interface MapStructConverter extends Converter {
    MapStructConverter MAPPER = Mappers.getMapper(MapStructConverter.class);

    @Mapping(source = "status", target = "orderStatus")
    @Override
    Order convert(SourceOrder sourceOrder);

    @Override
    DestinationCode convert(SourceCode sourceCode);
}

4.4. JMapperConverter

JMapperConverter 需要做更多的工作。接口實現后:

public class JMapperConverter implements Converter {
    JMapper realLifeMapper;
    JMapper simpleMapper;

    public JMapperConverter() {
        JMapperAPI api = new JMapperAPI()
          .add(JMapperAPI.mappedClass(Order.class));
        realLifeMapper = new JMapper(Order.class, SourceOrder.class, api);
        JMapperAPI simpleApi = new JMapperAPI()
          .add(JMapperAPI.mappedClass(DestinationCode.class));
        simpleMapper = new JMapper(
          DestinationCode.class, SourceCode.class, simpleApi);
    }

    @Override
    public Order convert(SourceOrder sourceOrder) {
        return (Order) realLifeMapper.getDestination(sourceOrder);
    }

    @Override
    public DestinationCode convert(SourceCode sourceCode) {
        return (DestinationCode) simpleMapper.getDestination(sourceCode);
    }
}

我們還需要向目標類的每個字段添加@JMap註釋。此外,JMapper 不能在 enum 類型之間轉換,它需要我們創建自定義映射函數:

@JMapConversion(from = "paymentType", to = "paymentType")
public PaymentType conversion(com.baeldung.performancetests.model.source.PaymentType type) {
    PaymentType paymentType = null;
    switch(type) {
        case CARD:
            paymentType = PaymentType.CARD;
            break;

        case CASH:
            paymentType = PaymentType.CASH;
            break;

        case TRANSFER:
            paymentType = PaymentType.TRANSFER;
            break;
    }
    return paymentType;
}

4.5. ModelMapperConverter

ModelMapperConverter 只需要提供我們想要映射的類:

public class ModelMapperConverter implements Converter {
    private ModelMapper modelMapper;

    public ModelMapperConverter() {
        modelMapper = new ModelMapper();
    }

    @Override
    public Order convert(SourceOrder sourceOrder) {
       return modelMapper.map(sourceOrder, Order.class);
    }

    @Override
    public DestinationCode convert(SourceCode sourceCode) {
        return modelMapper.map(sourceCode, DestinationCode.class);
    }
}

5. 簡單的模型測試

對於性能測試,我們可以使用 Java Microbenchmark Harness,關於如何使用它的更多信息可以在 這篇文章:https://www.baeldung.com/java-microbenchmark-harness 中找到。

我們為每個轉換器創建了一個單獨的基準測試,並將基準測試模式指定為 Mode.All。

5.1. 平均時間

對於平均運行時間,JMH 返回以下結果(越少越好):

這個基準測試清楚地表明,MapStruct 和 JMapper 都有最佳的平均工作時間。

5.2. 吞吐量

在這種模式下,基準測試返回每秒的操作數。我們收到以下結果(越多越好):

在吞吐量模式中,MapStruct 是測試框架中最快的,JMapper 緊隨其後。

5.3. SingleShotTime

這種模式允許測量單個操作從開始到結束的時間。基準給出了以下結果(越少越好):

這裏,我們看到 JMapper 返回的結果比 MapStruct 好得多。

5.4. 採樣時間

這種模式允許對每個操作的時間進行採樣。三個不同百分位數的結果如下:

所有的基準測試都表明,根據場景的不同,MapStruct 和 JMapper 都是不錯的選擇,儘管 MapStruct 對 SingleShotTime 給出的結果要差得多。

6. 真實模型測試

對於性能測試,我們可以使用 Java Microbenchmark Harness,關於如何使用它的更多信息可以在 這篇文章:https://www.baeldung.com/java-microbenchmark-harness 中找到。

我們為每個轉換器創建了一個單獨的基準測試,並將基準測試模式指定為 Mode.All。

6.1. 平均時間

JMH 返回以下平均運行時間結果(越少越好):

該基準清楚地表明,MapStruct 和 JMapper 均具有最佳的平均工作時間。

6.2. 吞吐量

在這種模式下,基準測試返回每秒的操作數。我們收到以下結果(越多越好):

在吞吐量模式中,MapStruct 是測試框架中最快的,JMapper 緊隨其後。

6.3. SingleShotTime

這種模式允許測量單個操作從開始到結束的時間。基準給出了以下結果(越少越好):

6.4. 採樣時間

這種模式允許對每個操作的時間進行採樣。三個不同百分位數的結果如下:

儘管簡單示例和實際示例的確切結果明顯不同,但是它們的趨勢相同。在哪種算法最快和哪種算法最慢方面,兩個示例都給出了相似的結果。

6.5. 結論

根據我們在本節中執行的真實模型測試,我們可以看出,最佳性能顯然屬於 MapStruct。在相同的測試中,我們看到 Dozer 始終位於結果表的底部。

7. 總結

在這篇文章中,我們已經進行了五個流行的 Java Bean 映射框架性能測試:ModelMapper MapStruct Orika ,Dozer, JMapper。

示例代碼地址:https://github.com/eugenp/tutorials/tree/master/performance-tests。

開源項目推薦

作者的其他開源項目推薦:

  1. :【Java學習+面試指南】 一份涵蓋大部分Java程序員所需要掌握的核心知識。
  2. : 適合新手入門以及有經驗的開發人員查閱的 Spring Boot 教程(業餘時間維護中,歡迎一起維護)。
  3. : 我覺得技術人員應該有的一些好習慣!
  4. :從零入門 !Spring Security With JWT(含權限驗證)後端部分代碼。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

台日合作電動車「日台之翼」 日本參賽奪佳績

  南臺科技大學與日本姊妹校三重大學跨國跨校合作,組團參加日本鈴鹿賽道所舉辦的「2015 Ene-1 GP SUZUKA」新世代能源車競賽,「日台之翼」以 25 分 03 秒636成績在全部 89 個參賽隊伍中勇奪第 10 名,在所有參賽的大專隊伍中則名列第 2,由於兩校聯合組隊,無法參加專科以上學校組別,因而歸屬一般組(社會組)中排名第 6,以第一年參賽隊伍而言,成績表現十分亮眼。   其競賽方式是以 40 顆市售 3 號電池為電源的電動車競速賽,行駛於鈴鹿賽車道 3 圈,並以總時間長短決定勝負。南臺科大校長戴謙表示,此次競賽用車「日台之翼」為日本三重大學電機系師生組裝車輛,南臺科大提供車輛測試與行駛數據分析,並由台灣大魯閣集團贊助車體與車輛零件,攜手合作完成。   有鑑於南臺科大機械系已有 20 年長期製作車輛如太陽能車、方程式賽車、燃料電池車、環保電車等技術與經驗,日本三重大學決定與南臺科大攜手合作,製作電動車共同參賽。     (圖片來源:)

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

你真的會寫單測嗎?TDD初體驗

前言:

  昨天讀到了一篇文章,講的是TDD,即Test-Driven Development,測試驅動開發。大體意思是,它要求在編寫某個功能的代碼之前先編寫測試代碼,然後只編寫使測試通過的功能代碼,通過測試來推動整個開發的進行。這有助於編寫簡潔可用和高質量的代碼,並加速開發過程。

  初讀之時,瞬間感受到了震撼,感覺和自己之前的開發流程全都不一樣,之前是由始至終,而這種思想確實以終為始。後來一查這種思想早在前幾年甚至前幾十年就被提出了,進而被廣泛運用到了敏捷開發中。看來是自己孤落寡聞了,於是我準備將這種思想用到今後的開發中,要做的第一件事,就是溫習如何寫用例。

為什麼是溫習?

  早在實習的時候,我們研發組就有寫用例的習慣,但是隨着開發逐漸熟悉,這種習慣不知不覺就被丟棄了,有頁面的點點點,沒頁面的看邏輯。相信有很多人也像我一樣,不知不覺就把這項技能丟棄了,接下來就讓我們一起,去重新撿起這項技能。

工具選擇

Junit

對於一個Java開發工程師來說,一提到寫單測,我們最先想到的,一定是Junit。下面是maven坐標

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>

用Junit我們可以快速的,簡潔的用註解進行單元測試。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:conf/core/*.xml")
public class ObjTest {

  @Test
  public void testFunc(){
     //todo test          
  }
}

這裏要注意的是@ContextConfiguration註解中的路徑是Spring配置文件的位置。測試的方法必須是public的,且沒有返回值。

mockito

mockito是一個用於模擬對象的工具,我認為他也是測試工作中必不可少的一部分,詳細的介紹我推薦可以看一下:

人生苦短,我用Mockito 

比較不錯的入門案例,它的maven坐標地址為:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
</dependency>

Mock這種測試方法, 對比傳統的Junit測試,有如下好處:

    1. 不用每次測試的是時候,都初始化Spring容器,採用Mock的方式模擬對象,效率高
    2. 對象間的依賴關係,可以用Mock去表達,同時,我們不關心的部分,我們都可以用Mock的方式代替(比如對象A引用對象B的某某方法,但是我們不關係對象B方法實現,只想藉助方法,這個時候就可以Mock)
    3. 可以應對複雜的測試環境,比如方法調用順序、方法調用次數等等。

以下是Mock的一個小案例:

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
    /**
     * mock對象
     */
    @Mock
    List<String> mockedList;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testMock() {
        // mock對象行為
        Mockito.when(mockedList.get(0)).thenReturn("one");
        Assert.assertEquals("one", mockedList.get(0));
        // 僅僅是mock了對象的行為,實際上列表還是空的
        Assert.assertEquals(0, mockedList.size());

        //驗證mock對象的get方法被調用過,且調用時的參數是0
        Mockito.verify(mockedList).get(0);
    }
}

這裡在使用@Mock的時候,必須事先調用MockitoAnnotations.initMocks(this),且使用@RunWith(MockitoJUnitRunner.class)

Jacoco

JaCoCo是一個開源的覆蓋率工具,支持多種覆蓋率的統計,其中包括:

    1. 行覆蓋率:度量被測程序的每行代碼是否被執行,判斷標準行中是否至少有一個指令被執行。
    2. 類覆蓋率:度量計算class類文件是否被執行。
    3. 分支覆蓋率:度量if和switch語句的分支覆蓋情況,計算一個方法裏面的總分支數,確定執行和不執行的 分支數量。
    4. 方法覆蓋率:度量被測程序的方法執行情況,是否執行取決於方法中是否有至少一個指令被執行。
    5. 指令覆蓋:計數單元是單個java二進制代碼指令,指令覆蓋率提供了代碼是否被執行的信息,度量完全 獨立源碼格式。
    6. 圈複雜度:在(線性)組合中,計算在一個方法裏面所有可能路徑的最小數目,缺失的複雜度同樣表示測 試案例沒有完全覆蓋到這個模塊。

下面是它的maven坐標:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
</dependency>

接下來我們用maven插件的方式,對jacoco進行配置

<plugin>
     <groupId>org.jacoco</groupId>
      <artifactId>jacoco-maven-plugin</artifactId>
       <version>0.8.3</version>
       <configuration>
            <includes>
               <include>com/**/*</include>
            </includes>
            <!-- rules裏面指定覆蓋規則 -->
            <rules>
            <rule implementation="org.jacoco.maven.RuleConfiguration">
               <element>BUNDLE</element>
               <limits>  
               <!-- 指定方法覆蓋到50% -->
               <limit implementation="org.jacoco.report.check.Limit">
                   <counter>METHOD</counter>
                   <value>COVEREDRATIO</value>
                   <minimum>0.50</minimum>
                </limit>
                <!-- 指定分支覆蓋到50% -->
                <limit implementation="org.jacoco.report.check.Limit">
                    <counter>BRANCH</counter>
                    <value>COVEREDRATIO</value>
                    <minimum>0.50</minimum>
                 </limit>
                 <!-- 指定類覆蓋到100%,不能遺失任何類 -->
                 <limit implementation="org.jacoco.report.check.Limit">
                    <counter>CLASS</counter>
                    <value>MISSEDCOUNT</value>
                    <maximum>0</maximum>
                  </limit>
                  </limits>
              </rule>
              </rules>
         </configuration>
         <executions>
             <execution>
                <id>pre-test</id>
                  <goals>
                       <goal>prepare-agent</goal>
                   </goals>
             </execution>
             <execution>
                   <id>post-test</id>
                   <phase>test</phase>
                   <goals>
                       <goal>report</goal>
                   </goals>
             </execution>
       </executions>
  </plugin>

  這裏值得注意的是<include>com/**/*</include>指的是class文件的位置。做完這些以後,我們就可以生成報表了。因為我們是用maven插件的方式進行配置的,所以如果我們使用idea進行開發的時候,就可以看到右側maven一欄中出現了jacoco插件

 最常用的就是這兩個,一個是檢查配置是否正確,第二個是用來將exec文件,生成index.html用來進行觀察覆蓋率。

我們先執行maven中的test指令,這時,我們在target中就可以看到一個jacoco.exec文件。

有了這個jacoco.exec文件,就可以使用jacoco的report方法,來生成文件。

 右鍵index.html文件,選擇Reveal in Finder(Mac),windows也是類似,打開文件磁盤的位置。

 可以看到,由於這個項目之前沒有幾個單測,所以覆蓋率特別低。點開之後,就可以看到具體的代碼,非常的方便。

 最後今天配置jacoco的時候,踩了2個坑:

1 用idea進行開發的同學。使用jacoco的時候,不要勾選這個按鈕,它會跳過你測試階段的代碼執行,進而不會生成jacoco.exec文件。

 

 2 保證自己測試代碼沒有錯誤(尤其是項目中,由於代碼更新,測試用例沒有更新,導致的測試不可用)

這裏的現象是雖然可以生成jacoco.exec 文件,而且可以report成文檔,但是打開之後發現,代碼覆蓋率都是0。

最後:

希望大家都可以保持寫測試用例的好習慣,謝謝

 

 

 

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

環保署 7 月起 補助汰換二行車機車新購電動二輪車

為加速淘汰二行程機車並推廣電動二輪車,環保署 23 日預告訂定「淘汰二行程機車及新購電動二輪車補助辦法」。環保署表示,民眾汰換二行程機車並新購電動機車目前補助 3,000 元,未來將加碼補助,其中汰換二行程機車並新購重型電動機車,環保署加上經濟部總計補助 20,400 元,汰換二行程機車並新購輕型、小輕型電動機車總共補助 15,000 元。   環保署表示,二行程機車相較於四行程機車,碳氫化合物排放量約為 18 倍,一氧化碳排放量約為 2 倍,污染嚴重,因此於 2004 年實施機車第四期排放標準時,加嚴二行程機車的標準,促使國內不再生產銷售二行程機車,依據交通部車輛登記資料統計,截至今年 4 月底止,二行程機車仍有約 200 萬輛。   「淘汰二行程機車及新購電動二輪車補助辦法」中電動二輪車包括電動機車、電動自行車及電動輔助自行車等都有補助,民眾淘汰二行程機車並新購上述的電動二輪車,皆有補助,預計新補助辦法在 7 月 15 日開始推動,但環保署強調,若民眾只汰換二行車機車而沒有新購電動機車,環保署僅補助 1,500 元。

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

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

Jmeter與壓測相關概念

相關概念

RT(response time)

什麼是RT? RT就是指系統在接收到請求和做出相應這段時間跨度

但是值得一提的是RT的值越高,並不真的就能說明我們的系統的吞吐量就很高, 比如說,如果存在數據在網絡中傳輸時出現了丟包的現象,傳輸的數據少了,速度就會增加, 但是這是事故,不是說我們的系統吞吐量高

此外,對不同的系統來說衡量的標準也不一樣,對一個遊戲軟件來說,響應時間也就是常說的延遲. 在100ms以內,遊戲體驗感會很好,飆升到幾秒鐘,乾脆就不要玩了, 但是對一個編譯系統來說,編譯一套源代碼可能好幾十分鐘,人們也願意等

java應用程序中的GC也會導致系統的總體RT飆升

Throughput 吞吐量

什麼是吐吞量呢? 百度百科: 廣義的吞吐量是: 單位時間內成功的傳輸數據的數量, 在我們進行壓力測試得出的結果中, 可以將吞吐量理解成系統在單位時間內成功處理的請求的數量

一個系統的吞吐量和request對CPU的消耗,外部的接口以及IO等因素緊密相關,

比如一個web應用代碼寫的再漂亮,但是每次請求都會去查詢數據庫,併發數上來后,數據庫就會佔用大量的CPU負載,系統的IO飆升,甚至可能導致其他軟件不得不等待mysql先執行完才能搶到CPU的時間分片. 系統的瓶頸積壓到mysql這裏,這個web應用的吞吐量一定不會很高

此外,一般我們都是這樣描述吞吐量: 在併發數為xxx時,系統的吐吞量為yyy

併發用戶數

它指的是系統可以承載的, 可以同時正常使用網站的用戶數量, 這個指標似乎看起來可以比吞吐量更加直觀反應系統的性能, 但是往往系統中的用戶又有不同的行為, 比如未註冊的, 在線的, 同時發送請求的等等, 簡而言之, 可以考慮用在線的用戶和同時發送請求的用戶數作為性能指標, 把在線的用戶當成性能指標更直觀, 把同時發送請求的用戶數量當成性能指標更準確

QPS (query per seconds)

每秒的查詢率, 用來權衡服務器在規定的時間內處理的流量數

計算公式: QPS = req / sec , 即平均每秒的請求量

TPS (transition per seconds)

TPS (transaction per second)代表每秒執行的事務數量,可基於測試周期內完成的事務數量計算得出。例如,用戶每分鐘執行6個事務,TPS為6 / 60s = 0.10 TPS。同時我們會知道事務的響應時間(或節拍),以此例,60秒完成6個事務也同時代表每個事務的響應時間或節拍為10秒

PV和UV

PV訪問量 (Page View) 每打開一次頁面或者刷新一次頁面 pv+1, 它反應的的網站的頁面被訪問的次數

UV訪問數(Unique Visitor) 即, 獨立訪客的訪問數, 換句話就是一台電腦算一個訪客,

  • 通過QPS估算PV

公式1 : pv = QPS*3600*6

公式2: pv = QPS*3600*8

  • 根據QPS,PV估算服務器的數量

服務器的數量= 每天的總PV / 單台服務器的PV

原理: 每天80%的訪問集中在了當前的20%的時間段, 這20%的時間就叫做峰值時間

峰值時間段 QPS = 總pv數*0.8 / 每天的秒數*0.2

Jmeter

jmeter能做什麼?

Jmeter也是apache的頂級項目, 通過jmeter我們可以測試靜態和動態資源,web動態應用程序的性能, 還可以用來模擬服務器,服務器中,網絡或者對象上的高負載, 測試他們的強度,以及不同負載下的總體性能

使用環境: Windows

使用的思路: 在jmeter提供的可視化頁面中,添加一個一個的指定的模塊. 對我們的web項目中指定的接口進行壓力測試,當然它不僅僅使用於發送http請求測試web項目的資源接口

添加什麼模塊呢?

  • 線程組: 也就是啟動多少條線程對系統壓測, 線程是否併發的啟動
  • http的默認參數: 比如protocol host port 等等
  • 添加請求的參數/請求體/cookie等信息
  • 添加監聽器來显示壓測結果

實例:

添加線程組,每輪同時啟動1000條線程對系統進行壓測,重複1輪

添加默認使用的請求參數, 這個默認的請求參數並不要求強制添加,只是為了以後在具體的某個http請求壓測模塊不寫請求參數時,使用這裏面的默認參數

配置信息如下:

添加一個sample, 這個sample其實就是http請求, 一個具體的http請求, 用大白話說 ,我們想壓測系統中的登錄方法,就添加一個登錄sample, 想壓測系統中拉取個人信息的方法, 就添加一個 個人信息sample

sample詳細配置

可以看到上圖中我們可以添加request Param request body, 上傳文件, 甚至可以添加一個模塊添加請求的cookie模塊

添加Listenner, 選擇聚合報告 ,開始壓測得到下面的結果,我們關注圖中的吞吐量

支持使用配置文件中的數據當成壓測的參數, 使用場景: 通過這個配置文件的配置,我們可以模擬出多用戶併發訪問系統的場景,下面配置中的每一行都是一個用戶的信息,jmeter會自動讀取這個配置文件中的每一行,使用這裏面的信息進行壓力測試,直到達到了用戶指定的請求量才結束

編寫配置文件

導入配置文件

使用配置文件,詳細的配置細節我都標在了圖片中

發送請求

使用環境: linux

第一步: 在window上錄好 XXX.jmx 文件

第二步: 啟動

sh jmeter.sh -n -t XXX.jmx -l result.jtl

第三步:將result.jtl導回到window上的jmeter中在可視化頁面中查看結果

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

美西岸漁場重新開放 拖網漁船罕見獲環團肯定

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

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

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!