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  ?

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

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

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

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

RocketMQ ACL使用指南

目錄

@(本節目錄)

1、什麼是ACL?

ACL是access control list的簡稱,俗稱訪問控制列表。訪問控制,基本上會涉及到用戶、資源、權限、角色等概念,那在RocketMQ中上述會對應哪些對象呢?

  • 用戶
    用戶是訪問控制的基礎要素,也不難理解,RocketMQ ACL必然也會引入用戶的概念,即支持用戶名、密碼。
  • 資源
    資源,需要保護的對象,在RocketMQ中,消息發送涉及的Topic、消息消費涉及的消費組,應該進行保護,故可以抽象成資源。
  • 權限
    針對資源,能進行的操作,
  • 角色
    RocketMQ中,只定義兩種角色:是否是管理員。

另外,RocketMQ還支持按照客戶端IP進行白名單設置。

2、ACL基本流程圖

在講解如何使用ACL之前,我們先簡單看一下RocketMQ ACL的請求流程:

對於上述具體的實現,將在後續文章中重點講解,本文的目的只是希望給讀者一個大概的了解。

3、如何配置ACL

3.1 acl配置文件

acl默認的配置文件名:plain_acl.yml,需要放在${ROCKETMQ_HOME}/store/config目錄下。下面對其配置項一一介紹。

3.1.1 globalWhiteRemoteAddresses

全局白名單,其類型為數組,即支持多個配置。其支持的配置格式如下:

  • 空
    表示不設置白名單,該條規則默認返回false。
  • “*”
    表示全部匹配,該條規則直接返回true,將會阻斷其他規則的判斷,請慎重使用。
  • 192.168.0.{100,101}
    多地址配置模式,ip地址的最後一組,使用{},大括號中多個ip地址,用英文逗號(,)隔開。
  • 192.168.1.100,192.168.2.100
    直接使用,分隔,配置多個ip地址。
  • 192.168..或192.168.100-200.10-20
    每個IP段使用 “*” 或”-“表示範圍。

3.1.2 accounts

配置用戶信息,該類型為數組類型。擁有accessKey、secretKey、whiteRemoteAddress、admin、defaultTopicPerm、defaultGroupPerm、topicPerms、groupPerms子元素。

3.1.2.1 accessKey

登錄用戶名,長度必須大於6個字符。

3.1.2.2 secretKey

登錄密碼。長度必須大於6個字符。

3.1.2.3 whiteRemoteAddress

用戶級別的IP地址白名單。其類型為一個字符串,其配置規則與globalWhiteRemoteAddresses,但只能配置一條規則。

3.1.2.4 admin

boolean類型,設置是否是admin。如下權限只有admin=true時才有權限執行。

  • UPDATE_AND_CREATE_TOPIC
    更新或創建主題。
  • UPDATE_BROKER_CONFIG
    更新Broker配置。
  • DELETE_TOPIC_IN_BROKER
    刪除主題。
  • UPDATE_AND_CREATE_SUBSCRIPTIONGROUP
    更新或創建訂閱組信息。
  • DELETE_SUBSCRIPTIONGROUP
    刪除訂閱組信息。
3.1.2.5 defaultTopicPerm

默認topic權限。該值默認為DENY(拒絕)。

3.1.2.6 defaultGroupPerm

默認消費組權限,該值默認為DENY(拒絕),建議值為SUB。

3.1.2.7 topicPerms

設置topic的權限。其類型為數組,其可選擇值在下節介紹。

3.1.2.8 groupPerms

設置消費組的權限。其類型為數組,其可選擇值在下節介紹。可以為每一消費組配置不一樣的權限。

3.2 RocketMQ ACL權限可選值

  • DENY
    拒絕。
  • PUB
    擁有發送權限。
  • SUB
    擁有訂閱權限。

3.3、權限驗證流程

上面定義了全局白名單、用戶級別的白名單,用戶級別的權限,為了更好的配置ACL權限規則,下面給出權限匹配邏輯。

4、使用示例

4.1 Broker端安裝

首先,需要在broker.conf文件中,增加參數aclEnable=true。並拷貝distribution/conf/plain_acl.yml文件到${ROCKETMQ_HOME}/conf目錄。

broker.conf的配置文件如下:

brokerClusterName = DefaultCluster
brokerName = broker-b
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
listenPort=10915
storePathRootDir=E:/SH2019/tmp/rocketmq_home/rocketmq4.5MB/store
storePathCommitLog=E:/SH2019/tmp/rocketmq_home/rocketmq4.5MB/store/commitlog
namesrvAddr=127.0.0.1:9876
autoCreateTopicEnable=false
aclEnable=true

plain_acl.yml文件內容如下:

globalWhiteRemoteAddresses:

accounts:
- accessKey: RocketMQ
  secretKey: 12345678
  whiteRemoteAddress:
  admin: false
  defaultTopicPerm: DENY
  defaultGroupPerm: SUB
  topicPerms:
  - TopicTest=PUB
  groupPerms:
  # the group should convert to retry topic
  - oms_consumer_group=DENY

- accessKey: admin
  secretKey: 12345678
  whiteRemoteAddress:
  # if it is admin, it could access all resources
  admin: true

從上面的配置可知,用戶RocketMQ只能發送TopicTest的消息,其他topic無權限發送;拒絕oms_consumer_group消費組的消息消費,其他消費組默認可消費。

4.2 消息發送端示例

public class AclProducer {
    public static void main(String[] args) throws MQClientException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name", getAclRPCHook());
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        for (int i = 0; i < 1; i++) {
            try {
                Message msg = new Message("TopicTest3" ,"TagA" , ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
                SendResult sendResult = producer.send(msg);
                System.out.printf("%s%n", sendResult);
            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        producer.shutdown();
    }

    static RPCHook getAclRPCHook() {
        return new AclClientRPCHook(new SessionCredentials("rocketmq","12345678"));
    }
}

運行效果如圖所示:

4.3 消息消費端示例

public class AclConsumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4", getAclRPCHook(),new AllocateMessageQueueAveragely());
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        consumer.subscribe("TopicTest", "*");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                ConsumeConcurrentlyContext context) {
                System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        System.out.printf("Consumer Started.%n");
    }

    static RPCHook getAclRPCHook() {
        return new AclClientRPCHook(new SessionCredentials("rocketmq","12345678"));
    }
}

發現並不沒有消費消息,符合預期。

關於RocketMQ ACL的使用就介紹到這裏了,下一篇將介紹RocketMQ ACL實現原理。

推薦閱讀:
1、

2、

3、

4、

作者介紹:
丁威,《RocketMQ技術內幕》作者,RocketMQ 社區佈道師,公眾號: 維護者,目前已陸續發表源碼分析Java集合、Java 併發包(JUC)、Netty、Mycat、Dubbo、RocketMQ、Mybatis等源碼專欄。

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

【其他文章推薦】

※為什麼 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  ?

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

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

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

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

福特新專利:電動車可分拆出單輪車騎行

傳統內燃機引擎汽車的引擎得透過傳動系統將動力傳到輪子,純電動車的馬達則往往直接連結在輪子上,如果把輪子連同馬達一起拆下來,是不是能當「風火輪」呢?你或許覺得這個想法超級異想天開,不過福特汽車卻剛申請通過一項這樣的專利。

這項專利名稱為「可與汽車結合的自力推進單輪車」,其實就是從電動車上拔下一個輪子來,使用方式是這樣的,當車主將電動車停妥後,下車來,在左後輪處放下一個腳架,之後就能拆下左後輪,馬達系統內附在輪框之中,將電力與資料傳輸數據纜線拆離電動車本體,從後車箱中取出把手椅座組,放在輪子上,接上電力與數據纜線,就成了一輛單輪車。

(Source:)   這輛單輪車顯然與賽格威等產品一樣會自動平衡,使用這種雙重交通工具,可以把車停在停車場後,騎著風火輪到汽車不便停靠的地方,似乎也還蠻方便,此外,由於電動車少了個輪子,歹徒就算成功開鎖偷車也開不走,大概是額外的好處。不過,反過來說,要是把風火輪給騎丟了,電動車成了三輪車,也是哪兒都去不了,這可就糗大了。   無論如何,這項專利還在紙面階段,就看福特會不會真的把它實現吧。

(首圖來源: CC BY 2.0)    (本文授權轉載自《》─〈〉)

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

【其他文章推薦】

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

※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!

Google 新專利:無人駕駛車可預測前車行為

Google 日前為其自動駕駛汽車提交了一項新的專利申請,該技術能檢測和追蹤道路上其他車輛的刹車和指示燈狀態,從而避免出現追尾等事故。

通過前置攝像頭,這種技術能讓Google無人駕駛汽車預判其他汽車的運動狀態。同時,車載電腦會檢測汽車燈的亮度變化,從而判斷司機是否打開指示燈。

從電腦的角度講,Google將通過一套演算法來識別攝像頭中圖像的圖元,分析其顏色,以確定裡面是否有脈衝。如果有脈衝,這套演算法將判斷司機可能如何操作指示燈,然後將資訊回饋給中央系統。

如果這樣的專利技術最終能發展成為行業標準,將擁有廣泛的應用潛力。Google在專利申請檔中稱,前面的車輛可以是汽車、卡車、摩托車或公車。

雖然如此,由於Google已經獲得了大量自動駕駛汽車相關專利,新申請的這項技術最終能否被實際應用到其自動駕駛汽車中尚不得而知。

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

【其他文章推薦】

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

※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!

你真的會寫單測嗎?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  ?

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

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

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

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

TensorFlow2.0(10):加載自定義圖片數據集到Dataset

 

前面的博客中我們說過,在加載數據和預處理數據時使用tf.data.Dataset對象將極大將我們從建模前的數據清理工作中釋放出來,那麼,怎麼將自定義的數據集加載為DataSet對象呢?這對很多新手來說都是一個難題,因為絕大多數案例教學都是以mnist數據集作為例子講述如何將數據加載到Dataset中,而英文資料對這方面的介紹隱藏得有點深。本文就來捋一捋如何加載自定義的圖片數據集實現圖片分類,後續將繼續介紹如何加載自定義的text、mongodb等數據。

 

如果你已有數據集,那麼,請將所有數據存放在同一目錄下,然後將不同類別的圖片分門別類地存放在不同的子目錄下,目錄樹如下所示:

$ tree flower_photos -L 1

flower_photos
├── daisy
├── dandelion
├── LICENSE.txt
├── roses
├── sunflowers
└── tulips

 

所有的數據都存放在flower_photos目錄下,每一個子目錄(daisy、dandelion等等)存放的都是一個類別的圖片。如果你已有自己的數據集,那就按上面的結構來存放,如果沒有,想操作學習一下,你可以通過下面代碼下載上述圖片數據集:

In [ ]:

import tensorflow as tf
import pathlib
data_root_orig = tf.keras.utils.get_file(origin='https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
                                         fname='flower_photos', untar=True)
data_root = pathlib.Path(data_root_orig)
print(data_root)  # 打印出數據集所在目錄

 

下載好后,建議將整個flower_photos目錄移動到項目根目錄下。

In [1]:

import tensorflow as tf
import random
import pathlib
data_path = pathlib.Path('./data/flower_photos')
all_image_paths = list(data_path.glob('*/*'))  
all_image_paths = [str(path) for path in all_image_paths]  # 所有圖片路徑的列表
random.shuffle(all_image_paths)  # 打散

image_count = len(all_image_paths)
image_count

Out[1]:

3670

 

查看一下前5張:

In [2]:

all_image_paths[:5]

Out[2]:

['data/flower_photos/sunflowers/9448615838_04078d09bf_n.jpg',
 'data/flower_photos/roses/15222804561_0fde5eb4ae_n.jpg',
 'data/flower_photos/daisy/18622672908_eab6dc9140_n.jpg',
 'data/flower_photos/roses/459042023_6273adc312_n.jpg',
 'data/flower_photos/roses/16149016979_23ef42b642_m.jpg']

 

讀取圖片的同時,我們也不能忘記圖片與標籤的對應,要創建一個對應的列表來存放圖片標籤,不過,這裏所說的標籤不是daisy、dandelion這些具體分類名,而是整型的索引,畢竟在建模的時候y值一般都是整型數據,所以要創建一個字典來建立分類名與標籤的對應關係:

In [3]:

label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
label_names

Out[3]:

['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

In [4]:

label_to_index = dict((name, index) for index, name in enumerate(label_names))
label_to_index

Out[4]:

{'daisy': 0, 'dandelion': 1, 'roses': 2, 'sunflowers': 3, 'tulips': 4}

In [5]:

all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_image_paths]

In [6]:

for image, label in zip(all_image_paths[:5], all_image_labels[:5]):
    print(image, ' --->  ', label)

 

data/flower_photos/sunflowers/9448615838_04078d09bf_n.jpg  --->   3
data/flower_photos/roses/15222804561_0fde5eb4ae_n.jpg  --->   2
data/flower_photos/daisy/18622672908_eab6dc9140_n.jpg  --->   0
data/flower_photos/roses/459042023_6273adc312_n.jpg  --->   2
data/flower_photos/roses/16149016979_23ef42b642_m.jpg  --->   2

 

好了,現在我們可以創建一個Dataset了:

In [7]:

ds = tf.data.Dataset.from_tensor_slices((all_image_paths, all_image_labels))

 

不過,這個ds可不是我們想要的,畢竟,裏面的元素只是圖片路徑,所以我們要進一步處理。這個處理包含讀取圖片、重新設置圖片大小、歸一化、轉換類型等操作,我們將這些操作統統定義到一個方法里:

In [8]:

def load_and_preprocess_from_path_label(path, label):
    image = tf.io.read_file(path)  # 讀取圖片
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [192, 192])  # 原始圖片大小為(266, 320, 3),重設為(192, 192)
    image /= 255.0  # 歸一化到[0,1]範圍
    return image, label

In [9]:

image_label_ds  = ds.map(load_and_preprocess_from_path_label)

In [10]:

image_label_ds 

Out[10]:

<MapDataset shapes: ((192, 192, 3), ()), types: (tf.float32, tf.int32)>

 

這時候,其實就已經將自定義的圖片數據集加載到了Dataset對象中,不過,我們還能秀,可以繼續shuffle隨機打散、分割成batch、數據repeat操作。這些操作有幾點需要注意:
(1)先shuffle、repeat、batch三種操作順序有講究:

  • 在repeat之後shuffle,會在epoch之間數據隨機(當有些數據出現兩次的時候,其他數據還沒有出現過)
  • 在batch之後shuffle,會打亂batch的順序,但是不會在batch之間打亂數據。

(2)shuffle操作時,buffer_size越大,打亂效果越好,但消耗內存越大,可能造成延遲。

 

推薦通過使用 tf.data.Dataset.apply 方法和融合過的 tf.data.experimental.shuffle_and_repeat 函數來執行這些操作:

In [12]:

ds = image_label_ds.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=image_count))
BATCH_SIZE = 32
ds = ds.batch(BATCH_SIZE)

 

好了,至此,本文內容其實就結束了,因為已經將自定義的圖片數據集加載到了Dataset中。

下面的內容作為擴展閱讀。

 

擴展

 

上面的方法是簡單的在每次epoch迭代中單獨讀取每個文件,在本地使用 CPU 訓練時這個方法是可行的,但是可能不足以進行GPU訓練並且完全不適合任何形式的分佈式訓練。

 

可以使用tf.data.Dataset.cache在epoch迭代過程間緩存計算結果。這能極大提升程序效率,特別是當內存能容納全部數據時。

在被預處理之後(解碼和調整大小),圖片就被緩存了:

In [13]:

ds = image_label_ds.cache()  # 緩存
ds = ds.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=image_count))

 

使用內存緩存的一個缺點是必須在每次運行時重建緩存,這使得每次啟動數據集時有相同的啟動延遲。如果內存不夠容納數據,使用一個緩存文件:

In [14]:

ds = image_label_ds.cache(filename='./cache.tf-data')
ds = ds.apply(tf.data.experimental.shuffle_and_repeat(buffer_size=image_count))

 

參考

 

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

【其他文章推薦】

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

※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!

從監控異常發現網絡安全

前言

  最近在前端異常監控系統中,發現一些異常信息,從中做了一些分析,得到一些體會,因此作文。

發現異常

  某天早上打開監控系統發現,當天凌晨1點過測試環境有2個前端上報的異常,報錯的原因都是由於沒有獲取到 url 中的參數,比如正常的地址應該是 www.xx.com?a=1&b=2, 但是實際訪問的是 www.xx.com%3Fa%3D1%26b%3D2。 很明顯路徑被 encode 了,導致程序沒有拿到參數。

  2個異常的訪問路徑是不一樣的,並且以上2個地址  decode 之後再訪問,能夠正常打開頁面,參數全部都是正確的。 這些訪問的 url 是我們在做跳轉的時候,入口配置的,我們的邏輯中不會 encode,這個地方非常讓人疑惑,為什麼會出現這樣的請求,猜測很可能是人為修改了再訪問的。 後來把參數獲取出來,去查詢一些信息,發現這條請求是都來自於我們的測試同學的賬戶,但是私下詢問過,1點過同事根本什麼都沒有做。 也排除了有其他人用他手機訪問的情況。 再對參數里的信息做查詢,發現這2個參數對應的數據是在2個多月前,我們項目測試階段的數據,這就更奇怪了,2個月前的版本我們已經沒有再測試了,同事也很久沒有訪問過這幾個入口。 是不是有人在刷我們的頁面,但為什麼幾個參數都是如此精確,都是正確的。 

  一定有其他人在訪問。因為各方面情況看起來都很不正常:

    1. 凌晨1點過訪問的

    2. 訪問路徑被 encode 了

    3. 數據是測試同事的,他自己卻沒有訪問過。

    4. 訪問的地址的數據都是2個月前生成的,如果有三方黑客獲取到了訪問記錄之後,延遲到最近批量訪問也符合行為邏輯

 

  再看看上報的其他異常信息,更奇怪了,瀏覽器的版本無從得知,User-Agent 只有 Go-http-client/1.1 , 怎麼看都像是爬蟲腳本在做請求。 說到爬蟲,爬蟲一般會針對已知的接口進行數據拉取,以獲取他人的信息; 又或者不停的遍歷不同的路徑,查找可訪問的路由(隱藏的後門),路徑遍歷很容易發現,如果有日誌的話,就能看到很多 404, 大量的訪問一些奇怪的路徑。 那我們遇到的,是前期通過某種方式攔截到我們的網頁請求,收集起來,到一定時間再去訪問,這種方式叫做:重放攻擊。

  我們在服務器又查詢了 IP 等一些相關的信息,發現有幾個 IP 時不時的在做這樣的訪問攻擊,而且也看得出對方很謹慎,沒有同時做大批量的請求。 又發現了更多的異常行為,首先比如一個 www.x.com/page 的頁面路徑,它使用 post 方法去請求了一次。 

  所有的異常數據,被訪問的路徑都是測試環境的地址,使用的 http,而我們的正式環境使用的 https,對方似乎並沒有能力獲取到 https 的請求。 通過查詢這幾個 IP 在正式環境訪問,又發現了一條記錄,而剛好這條記錄的訪問地址沒有 https(因為有時候,我們的開發自己可能會手動把 https 改成 http 去訪問)。  到目前的結論是黑客方的監聽是和我們的項目環境沒有關係的,只是因為我們正式環境使用了 https 他才沒有獲取到。

  最初以為只是一個同事的手機被監聽了,但是因為又出現了另一個同事的請求,所以覺得爬蟲在路由器層攔截的概率更大,而且剛好這兩個同事有一個用的是安卓,有一個用的是蘋果,所以看起來所有的設備都有命中的可能。 但是如果是公司路由器的問題,那為什麼目前為止就只發現了兩個同事的訪問被爬取了,這些網頁其他同事也都訪問過,而且頻率也不低。 對方的策略具體是什麼,到底在哪裡攔截的,我有點束手無策了。 而後詢問過另一個同事後,得知對方大概是在20多天前訪問的,爬蟲訪問的記錄全部集中在這幾天。 種種跡象表明確實是前期收集了一段時間,這两天才開始出來集中訪問的。

  前面通過查詢 IP,發現爬蟲的服務器都在國內,但是對方也可能隱藏掉了真實 IP 。 如果對方的行為對公司造成了傷害,也許可以進一步去查對方服務器歸屬人。 但是因為從對方訪問量和攻擊程序來說,對我們幾乎沒有傷害。 甚至能感覺到對方不是定向要攻擊我們。 看起來更像是對方的程序遊離在互聯網上,收集到了什麼,就干點什麼的意思。

 

安全問題

  再來說說安全性問題,我們常常在訪問 url 的時候,帶上一些參數,比如在 app 中,內嵌一些 h5,h5 的參數中需要帶上一些識別身份的 token。 如果說、我們沒有使用 https,黑客在中間層監聽了我們的請求,就能獲取到我們的數據,甚至對方萬一得到了 token,還能獲取更多我們的隱私信息。 這就給重放攻擊提供了安全漏洞。

  那麼防禦重放攻擊,有什麼辦法呢? 常用的辦法有兩種

  (1)加隨機數保障只被使用一次,但是需要額外空間存儲歷史使用過的值;

  (2)加時間戳,不用額外保存信息,但是需要同步時間,但同步時間並不能達到各種情況下的準確。 總之大概方向就是需要一個參數,來判斷是否失效。

 

為什麼 https 保障安全

  網上文章很多,這裏就不做一一解釋了,簡單說兩點,https 利用非對稱加密和對稱加密、保障數據安全;利用数字證書做雙向身份校驗、保障不被釣魚。

 

抓包工具為什麼能抓取 https

  以前知道抓包工具通過一定配置就能抓取到 https 請求,這樣一想,那 https 是不是就不安全啊,抓包工具都能攔截到。 首先我們需要先了解它的原理,才能做下一步分析。 

 

  抓包工具抓取 https 的原理是利用抓包工具做中間代理人,和客戶端建立信任連接以後,再代客戶端去向服務端發送和接受請求,達到中間商的效果,這樣抓包工具既能看到數據,客戶端也能正常使用。

以下是抓包工具抓取 https 的流程(拷貝的他人的總結,也不知道最初是誰寫的,因為網上太多同樣的了,作者勿怪,無法署名)

  1. 客戶端向服務器發起HTTPS請求

  2. Charles攔截客戶端的請求,偽裝成客戶端向服務器進行請求

  3. 服務器向“客戶端”(實際上是Charles)返回服務器的CA證書

  4. Charles攔截服務器的響應,獲取服務器證書公鑰,然後自己製作一張證書,將服務器證書替換后發送給客戶端。(這一步,Charles拿到了服務器證書的公鑰)

  5. 客戶端接收到“服務器”(實際上是Charles)的證書後,生成一個對稱密鑰,用Charles的公鑰加密,發送給“服務器”(Charles)

  6. Charles攔截客戶端的響應,用自己的私鑰解密對稱密鑰,然後用服務器證書公鑰加密,發送給服務器。(這一步,Charles拿到了對稱密鑰)

  7. 服務器用自己的私鑰解密對稱密鑰,向“客戶端”(Charles)發送響應

  8. Charles攔截服務器的響應,替換成自己的證書後發送給客戶端

  9. 至此,連接建立,Charles拿到了 服務器證書的公鑰 和 客戶端與服務器協商的對稱密鑰,之後就可以解密或者修改加密的報文了

 

  所以前提是客戶端需要選擇信任並安裝 Charles 的證書,否則抓包工具也無法攔截 https,在互聯網上大部分惡意腳本程序,想要抓取用戶數據,也大都是和抓包工具一樣的工作原理,所以 https 還是比較安全的。

 

未使用 https ?

  記得以前公司還沒使用 https 的時候,可能大家都經歷過噁心的流量劫持,我們自己在線上環境使用都挺正常的,時不時其他地區的同事會告訴我們說,頁面上漂浮了一個按鈕,點開就跑到其他地方去了。 甚至說有些注入的代碼有問題,導致我們的界面也出現了問題,當時各種研究后,最後的辦法就是上 https, 到現在就再也不用擔心這個問題了。 現在一些瀏覽器訪問非 https 的頁面,都會提示不安全,平時也看得到一些他人的網站都還是沒用 https,進去就會報警告。 也如我們發現的重放攻擊,這些安全問題確實存在於網絡中,甚至無人能避免,所以沒用 https 的站點,還是快點升級吧!

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

【其他文章推薦】

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

※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!

環保署 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  ?

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

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

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

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

四部委,九大行業組織首次攜手新能源汽車展

2013、2014年第一屆和第二屆節能與新能源汽車成果展聚集了一汽集團、東風集團、上汽集團、北汽集團、長安集團、一汽大眾、上海大眾、上海通用、富豪汽車、一汽豐田、廣汽豐田、豐田中國、廣汽本田、北京現代、吉利汽車、華晨汽車、比亞迪汽車、江淮汽車、長城汽車、吉奧汽車、宇通客車、安凱客車等國內外主流車企紛紛集體參展,展品涵蓋乘用車、商用車、改裝車、專用車和零部件,集中展示了近年來在節能汽車、環保汽車、新能源汽車領域取得的最新成果。

2015十月,以“選擇•行動——未來從現在開始”為主題的2015(第三屆)節能與新能源汽車產業發展規劃成果展覽會(以下簡稱2015節能與新能源汽車成果展)將要在北京國家會議中心舉辦。

6月10日下午,“2015節能與新能源汽車產業發展成果彙報及展示會”新聞發佈會在北京隆重召開。從發佈會上獲悉,中國工業和信息化部將會同財政部、科技部、發展改革委等部門於今年10月共同在北京舉辦“2015年節能與新能源汽車產業發展成果彙報及展示會”,全面宣傳展示我國節能與新能源汽車發展取得的豐碩成果。中國汽車工業協會副秘書長葉盛基、中國貿促會機械行業分會副會長周衛東向各界通報了成果彙報及展示會的籌備情況。

成果展由會議和展會兩大部分構成

2015年節能與新能源汽車產業發展成果彙報及展示會主要由會議和展會兩大部分構成。

會議方面主要包括節能與新能源汽車發展成果彙報會、節能與新能源汽車技術研討會、電動汽車國際標準研討會、新能源汽車專利成果研討會和示範城市經驗交流會等內容。展會包括中國國際汽車新能源及技術應用展覽會、節能與新能源汽車發展情況回顧、節能與能源汽車發展前景展望以及節能與新能源汽車產業發展規劃成果展覽會

2015節能與新能源汽車成果展將分設整車展區、關鍵零部件展區、充電設施展區和試點城市展區,在重點展示25個創新工程項目研究成果基礎上,全面展示節能與新能源汽車產業發展的最新成果。今年展會參展企業覆蓋領域更廣,代表性更強,將全面展示目前國際節能與新能源汽車領域的產品和技術。電池、電機、電控等關鍵零部件企業,以及配套設施企業也將攜最新技術和產品參展。

互動體驗和趣味活動

本屆節能與新能源汽車成果展的亮點,除了以往產品和技術的靜態展示外,展會同期還將舉辦“尊享體驗”試乘試駕活動、全國高校汽車科技文化節、節能與新能源汽車寶貝嘉年華和BLUE-AUTO金秋惠享購車節等互動體驗和趣味活動。

尊享體驗”試乘試駕,將由參展車企提供數十輛節能與新能源車型給體驗者,讓現場觀眾可以親身體驗節能與新能源汽車的“好開”、“安全”、“省錢”、“環保”和“智慧”等優點,同時展示各車型優秀的動力性和經濟性。同期互動體驗和趣味活動不僅為參展企業提供了更多車輛性能表現的空間,也為觀眾帶來更加豐富多彩的觀展體驗。

2015年節能與新能源汽車產業發展成果彙報及展示會

時間:2015年10月21-24日
地點:北京•國家會議中心

組織機構:
主辦單位:工業和信息化部、財政部、科技部、發展改革委
協辦單位:中國汽車工業協會、 中國汽車技術研究中心、中國汽車工程學會、中國汽車工程研究院股份有限公司、中國電工技術學會、中國國際貿易促進委員會機械行業分會、中國國際貿易促進委員會汽車行業分會、汽車知識雜誌社、寰球時代汽車投資管理(北京)有限公司等單位。
承辦單位:北京中汽四方會展有限公司等。
合作單位:北京盛大超越國際展覽有限公司

展會諮詢:
連絡人:嶽巍                               
手  機:+86 135 5286 5285                           
電  話: +86 10 6329 0215                   
傳  真: +86 10 5141 8155
E-mail:

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

【其他文章推薦】

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

※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!