標籤: 銷售文案

  • 【Spring註解驅動開發】使用InitializingBean和DisposableBean來管理bean的生命周期,你真的了解嗎?

    寫在前面

    在《【Spring註解驅動開發】如何使用@Bean註解指定初始化和銷毀的方法?看這一篇就夠了!!》一文中,我們講述了如何使用@Bean註解來指定bean初始化和銷毀的方法。具體的用法就是在@Bean註解中使用init-method屬性和destroy-method屬性來指定初始化方法和銷毀方法。除此之外,Spring中是否還提供了其他的方式來對bean實例進行初始化和銷毀呢?

    項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

    InitializingBean接口

    1.InitializingBean接口概述

    Spring中提供了一個InitializingBean接口,InitializingBean接口為bean提供了屬性初始化后的處理方法,它只包括afterPropertiesSet方法,凡是繼承該接口的類,在bean的屬性初始化后都會執行該方法。InitializingBean接口的源碼如下所示。

    package org.springframework.beans.factory;
    public interface InitializingBean {
    	void afterPropertiesSet() throws Exception;
    }
    

    根據InitializingBean接口中提供的afterPropertiesSet()方法的名字可以推斷出:afterPropertiesSet()方法是在屬性賦好值之後調用的。那到底是不是這樣呢?我們來分析下afterPropertiesSet()方法的調用時機。

    2.何時調用InitializingBean接口?

    我們定位到Spring中的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory類下的invokeInitMethods()方法中,來查看Spring加載bean的方法。

    題外話:不要問我為什麼會是這個invokeInitMethods()方法,如果你和我一樣對Spring的源碼非常熟悉的話,你也會知道是這個invokeInitMethods()方法,哈哈哈哈!所以,小夥伴們不要只顧着使用Spring,還是要多看看Spring的源碼啊!Spring框架中使用了大量優秀的設計模型,其代碼的編寫規範和嚴謹程度也是業界開源框架中數一數二的,非常值得閱讀。

    我們來到AbstractAutowireCapableBeanFactory類下的invokeInitMethods()方法,如下所示。

    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    	//判斷該bean是否實現了實現了InitializingBean接口,如果實現了InitializingBean接口,則調用bean的afterPropertiesSet方法
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        //調用afterPropertiesSet()方法
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //調用afterPropertiesSet()方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }
    
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
                //通過反射的方式調用init-method
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
    

    分析上述代碼后,我們可以初步得出如下信息:

    • Spring為bean提供了兩種初始化bean的方式,實現InitializingBean接口,實現afterPropertiesSet方法,或者在配置文件和@Bean註解中通過init-method指定,兩種方式可以同時使用。
    • 實現InitializingBean接口是直接調用afterPropertiesSet()方法,比通過反射調用init-method指定的方法效率相對來說要高點。但是init-method方式消除了對Spring的依賴。
    • 如果調用afterPropertiesSet方法時出錯,則不調用init-method指定的方法。

    也就是說Spring為bean提供了兩種初始化的方式,第一種實現InitializingBean接口,實現afterPropertiesSet方法,第二種配置文件或@Bean註解中通過init-method指定,兩種方式可以同時使用,同時使用先調用afterPropertiesSet方法,后執行init-method指定的方法。

    DisposableBean接口

    1.DisposableBean接口概述

    實現org.springframework.beans.factory.DisposableBean接口的bean在銷毀前,Spring將會調用DisposableBean接口的destroy()方法。我們先來看下DisposableBean接口的源碼,如下所示。

    package org.springframework.beans.factory;
    public interface DisposableBean {
    	void destroy() throws Exception;
    }
    

    可以看到,在DisposableBean接口中只定義了一個destroy()方法。

    在Bean生命周期結束前調用destory()方法做一些收尾工作,亦可以使用destory-method。前者與Spring耦合高,使用類型強轉.方法名(),效率高。後者耦合低,使用反射,效率相對低

    2.DisposableBean接口注意事項

    多例bean的生命周期不歸Spring容器來管理,這裏的DisposableBean中的方法是由Spring容器來調用的,所以如果一個多例實現了DisposableBean是沒有啥意義的,因為相應的方法根本不會被調用,當然在XML配置文件中指定了destroy方法,也是沒有意義的。所以,在多實例bean情況下,Spring不會自動調用bean的銷毀方法。

    單實例bean案例

    創建一個Animal的類實現InitializingBean和DisposableBean接口,代碼如下:

    package io.mykit.spring.plugins.register.bean;
    
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Component;
    /**
     * @author binghe
     * @version 1.0.0
     * @description 測試InitializingBean接口和DisposableBean接口
     */
    public class Animal implements InitializingBean, DisposableBean {
        public Animal(){
            System.out.println("執行了Animal類的無參數構造方法");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("執行了Animal類的初始化方法。。。。。");
    
        }
        @Override
        public void destroy() throws Exception {
            System.out.println("執行了Animal類的銷毀方法。。。。。");
    
        }
    }
    

    接下來,我們新建一個AnimalConfig類,並將Animal通過@Bean註解的方式註冊到Spring容器中,如下所示。

    package io.mykit.spring.plugins.register.config;
    
    import io.mykit.spring.plugins.register.bean.Animal;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    /**
     * @author binghe
     * @version 1.0.0
     * @description AnimalConfig
     */
    @Configuration
    @ComponentScan("io.mykit.spring.plugins.register.bean")
    public class AnimalConfig {
        @Bean
        public Animal animal(){
            return new Animal();
        }
    }
    

    接下來,我們在BeanLifeCircleTest類中新增testBeanLifeCircle02()方法來進行測試,如下所示。

    @Test
    public void testBeanLifeCircle02(){
        //創建IOC容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnimalConfig.class);
        System.out.println("IOC容器創建完成...");
        //關閉IOC容器
        context.close();
    }
    

    運行BeanLifeCircleTest類中的testBeanLifeCircle02()方法,輸出的結果信息如下所示。

    執行了Animal類的無參數構造方法
    執行了Animal類的初始化方法。。。。。
    IOC容器創建完成...
    執行了Animal類的銷毀方法。。。。。
    

    從輸出的結果信息可以看出:單實例bean下,IOC容器創建完成后,會自動調用bean的初始化方法;而在容器銷毀前,會自動調用bean的銷毀方法。

    多實例bean案例

    多實例bean的案例代碼基本與單實例bean的案例代碼相同,只不過在AnimalConfig類中,我們在animal()方法上添加了@Scope(“prototype”)註解,如下所示。

    package io.mykit.spring.plugins.register.config;
    import io.mykit.spring.plugins.register.bean.Animal;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Scope;
    /**
     * @author binghe
     * @version 1.0.0
     * @description AnimalConfig
     */
    @Configuration
    @ComponentScan("io.mykit.spring.plugins.register.bean")
    public class AnimalConfig {
        @Bean
        @Scope("prototype")
        public Animal animal(){
            return new Animal();
        }
    }
    

    接下來,我們在BeanLifeCircleTest類中新增testBeanLifeCircle03()方法來進行測試,如下所示。

    @Test
    public void testBeanLifeCircle03(){
        //創建IOC容器
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnimalConfig.class);
        System.out.println("IOC容器創建完成...");
        System.out.println("-------");
        //調用時創建對象
        Object bean = ctx.getBean("animal");
        System.out.println("-------");
        //調用時創建對象
        Object bean1 = ctx.getBean("animal");
        System.out.println("-------");
        //關閉IOC容器
        ctx.close();
    }
    

    運行BeanLifeCircleTest類中的testBeanLifeCircle03()方法,輸出的結果信息如下所示。

    IOC容器創建完成...
    -------
    執行了Animal類的無參數構造方法
    執行了Animal類的初始化方法。。。。。
    -------
    執行了Animal類的無參數構造方法
    執行了Animal類的初始化方法。。。。。
    -------
    

    從輸出的結果信息中可以看出:在多實例bean情況下,Spring不會自動調用bean的銷毀方法。

    好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!

    項目工程源碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation

    寫在最後

    如果覺得文章對你有點幫助,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回復“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。

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

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

    ※教你寫出一流的銷售文案?

    FB行銷專家,教你從零開始的技巧

  • 三文搞懂學會Docker容器技術(上)

    三文搞懂學會Docker容器技術(上)

    1,Docker簡介

      1.1 Docker是什麼?

    Docker官網: https://www.docker.com/

    Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從Apache2.0協議開源。
    Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後發布到任何流行的 Linux 機器上,也可以實現虛擬化。
    容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
    Docker 從 17.03 版本之後分為 CE(Community Edition: 社區版) 和 EE(Enterprise Edition: 企業版),我們用社區版就可以了。

      1.2 Docker架構原理?

     

    Docker三要素,鏡像,容器,倉庫

    1.鏡像

    Docker 鏡像(Image)就是一個只讀的模板,它可以是一個可運行軟件(tomcat,mysql),也可以是一個系統(centos)。鏡像可以用來創建 Docker 容器,一個鏡像可以創建很多容器。

    2.容器

    Docker 利用容器(Container)獨立運行的一個或一組應用。容器是用鏡像創建的運行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。可以把容器看做是一個簡易版的 Linux 環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。容器的定義和鏡像幾乎一模一樣,也是一堆層的統一視角,唯一區別在於容器的最上面那一層是可讀可寫的。

    3.倉庫

    倉庫(Repository)是集中存放鏡像文件的場所,類似GitHub存放項目代碼一樣,只不過Docker Hub是由來存鏡像(image)的。倉庫(Repository)和倉庫註冊服務器(Registry)是有區別的。倉庫註冊服務器上往往存放着多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的標籤(tag,類似版本號)。

    倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。

    最大的公開倉庫是 Docker Hub(https://hub.docker.com/),存放了數量龐大的鏡像供用戶下載。國內的公開倉庫包括阿里雲 、網易雲 等。

     

    容器與鏡像的關係類似於面向對象編程中的對象與類。

    Docker 面向對象
    容器 對象
    鏡像

      1.3 Docker有什麼用?

        1,簡化環境搭建,提高開發生命周期效率;

        2,大大簡化運維工作量;

        3,微服務利器;

      1.4 Docker容器與虛擬機區別?

    Docker是一種輕量級的虛擬化技術,比傳統的虛擬機性能更好。

    下圖是虛擬機的體繫結構:

     

    • server – 表示真實電腦。
    • Host OS – 真實電腦的操作系統,例如:Windows,Linux
    • Hypervisor – 虛擬機平台,模擬硬件,如VMWare,VirtualBox
    • Guest OS – 虛擬機平台上安裝的操作系統,例如CentOS Linux
    • App – 虛擬機操作系統上的應用,例如nginx

     

    下圖是Docker的體繫結構:

    • server – 表示真實電腦。
    • Host OS – 真實電腦的操作系統,例如:Windows,Linux
    • Docker Engine – 新一代虛擬化技術,不需要包含單獨的操作系統。
    • App – 所有的應用程序現在都作為Docker容器運行。

     

    這種體繫結構的明顯優勢是,不需要為虛擬機操作系統提供硬件模擬。所有應用程序都作為Docker容器工作,性能更好。

      Docker容器 虛擬機(VM)
    操作系統 與宿主機共享OS 宿主機OS上運行宿主機OS
    存儲大小 鏡像小,便於存儲與傳輸 鏡像龐大(vmdk等)
    運行性能 幾乎無額外性能損失 操作系統額外的cpu、內存消耗
    移植性 輕便、靈活、適用於Linux 笨重、與虛擬化技術耦合度高
    硬件親和性  面向軟件開發者 面向硬件運維者

     

    Docker優點:輕量級,速度快,運行應用隔離,方便維護…

    2,Docker安裝

      2.1 Docker版本介紹

    Docker從1.13版本之後採用時間線的方式作為版本號,分為社區版CE和企業版EE。

    社區版是免費提供給個人開發者和小型團體使用的,企業版會提供額外的收費服務,比如經過官方測試認證過的基礎設施、容器、插件等。

    社區版按照stable和edge兩種方式發布,每個季度更新stable版本,如17.06,17.09;每個月份更新edge版本,如17.09,17.10。

    我們平時用社區版就足夠了。所以我們安裝社區版;

      2.2 Docker安裝官方文檔

    我們主要參考:https://docs.docker.com/install/linux/docker-ce/centos/  來安裝;

      2.3 工具準備

    前置課程:Centos課程  http://www.java1234.com/javaxuexiluxiantu.html

    打包下載: http://pan.baidu.com/s/1i55jJAt

    虛擬機 VMware

    centos7安裝下虛擬機VM上;

    連接工具 才用 FinalShell  官方地址:http://www.hostbuf.com/

      2.4 Docker安裝步驟

    我們切換到root用戶

    1、Docker 要求 CentOS 系統的內核版本高於 3.10 ,查看本頁面的前提條件來驗證你的CentOS 版本是否支持 Docker 。

    通過 uname -r 命令查看你當前的內核版本

     $ uname -r

    2、使用 root 權限登錄 Centos。確保 yum 包更新到最新。

    $ yum update

    3、卸載舊版本(如果安裝過舊版本的話)

    $ yum remove docker  docker-common docker-selinux docker-engine

    4、安裝需要的軟件包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的

    $ yum install -y yum-utils device-mapper-persistent-data lvm2

    5、設置yum源

    $ yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo

    6,安裝最新版本的Docker

    $ yum install docker-ce docker-ce-cli containerd.io

    7,啟動Docker並設置開機啟動

    $ systemctl start docker

    $ systemctl enable docker

    8,驗證Docker

    $ docker version

     

    說明安裝OK;

    9,Docker HelloWorld測試;

    $ docker run hello-world

     

    因為本地沒有這個鏡像,所以從遠程官方倉庫去拉取,下載;

    然後我們再執行一次;

     

    OK了

      2.5 Docker配置阿里雲鏡像倉庫

    Docker默認遠程倉庫是 https://hub.docker.com/

    比如我們下載一個大點的東西,龜速

     

    由於是國外主機,類似Maven倉庫,慢得一腿,經常延遲,破損;

    所以我們一般都是配置國內鏡像,比如阿里雲,網易雲等;推薦阿里雲,穩定點;

    配置步驟如下:

    1,登錄進入阿里雲鏡像服務中心,獲取鏡像地址

    進入阿里雲容器鏡像服務地址:點這裏快速進入

    使用你的淘寶賬號密碼登錄

     

    這裏我們獲取鏡像地址;

    2,在/etc/docker目錄下找到在daemon.json文件(沒有就新建),將下面內容寫入

    {

     “registry-mirrors”: [“https://xxxxxxx.mirror.aliyuncs.com”]

    }

    3,重啟daemon

    systemctl daemon-reload

    4,重啟docker服務

    systemctl restart docker

    5,測試

    由於速度太快,截圖都難;

     

    3,HelloWorld運行原理

    運行  docker run hello-world

    本地倉庫未能找到該鏡像,然後去遠程倉庫尋找以及下載該鏡像;

    然後我們再執行該命令:

    出來了 Hellowold。我們具體來分析下 執行原理和過程;

    從左到右 client客戶端,Docker運行主機,遠程倉庫;

    docker build ,pull,run分別是 構建,拉取,運行命令,後面再細講;

    中間Docker主機里有 Docker daemon主運行線程,以及Containers容器,容器里可以運行很多實例,(實例是從右側Images鏡像實例化出來的)Images是存儲再本地的鏡像文件,比如 Redis,Tomat這些鏡像文件;

    右側是Registry鏡像倉庫,默認遠程鏡像倉庫 https://hub.docker.com/  不過是國外主機,下載很慢,不穩定,所以我們後面要配置成阿里雲倉庫鏡像地址,穩定快捷;

    執行 docker run hello-world的過程看如下圖例:

     

     

     

    4,Docker基本命令

       4.1 啟動Docker

               systemctl start docker

      4.2 停止Docker

             systemctl stop docker

      4.3 重啟Docker

           systemctl restart docker

      4.4 開機啟動Docker

         systemctl enable docker

      4.5 查看Docker概要信息

       docker info

      4.6 查看Docker幫助文檔

       docker –help

      4.7 查看Docker版本信息

         docker version

    5,Docker鏡像

      5.1 docker images 列出本機所有鏡像

     

    REPOSITORY 鏡像的倉庫源
    TAG 鏡像的標籤(版本)同一個倉庫有多個TAG的鏡像,多個版本;我們用REPOSITORY:TAG來定義不同的鏡像;
    IMAGE ID 鏡像ID,鏡像的唯一標識
    CREATE 鏡像創建時間
    SIZE 鏡像大小

    OPTIONS 可選參數:

    -a 显示所有鏡像(包括中間層)
    q 只显示鏡像ID
    -qa 可以組合
    –digests 显示鏡像的摘要信息
    –no-trunc 显示完整的鏡像信息 

     

      5.2 docker search 搜索鏡像

    和 https://hub.docker.com/ 這裏的搜索效果一樣;

    OPTIONS可選參數:

    –no-trunc 显示完整的鏡像描述
    -s 列出收藏數不小於指定值的鏡像
    –automated 只列出Docker Hub自動構建類型的鏡像

     

     

     

      5.3 docker pull 下載鏡像

    docker pull 鏡像名稱:[TAG]

    注意:不加TAG,默認下載最新版本latest

      5.4 docker rmi 刪除鏡像

    1,刪除單個:docker rmi 鏡像名稱:[TAG]

    如果不寫TAG,默認刪除最新版本latest

    有鏡像生成的容器再運行時候,會報錯,刪除失敗;

    我們需要加 -f 強制刪除

    2,刪除多個:docker rmi -f 鏡像名稱1:[TAG] 鏡像名稱2:[TAG]

    中間空格隔開

    3,刪除全部:docker rmi -f $(docker images -qa)

     

     

    ——————————————————————————————————————————

    作者: java1234_小鋒

    出處:https://www.cnblogs.com/java688/p/13132444.html

    版權:本站使用「CC BY 4.0」創作共享協議,轉載請在文章明顯位置註明作者及出處。

    ——————————————————————————————————————————

     

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

    【其他文章推薦】

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

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

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

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

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

    ※教你寫出一流的銷售文案?

  • 區塊鏈系列教程之:比特幣中的網絡和區塊鏈

    區塊鏈系列教程之:比特幣中的網絡和區塊鏈

    目錄

    • 簡介
    • 比特幣的網絡
      • 網絡發現與同步
    • SPV節點
      • 區塊鏈頭
      • Merkle Tree
    • 比特幣中的區塊鏈
      • 區塊標識符
    • 創世區塊
    • 總結

    簡介

    比特幣的底層就是區塊鏈技術,區塊鏈也是因為比特幣而廣為人知的。和其他的區塊鏈技術相比,比特幣的區塊鏈有什麼特徵呢?作為去區塊鏈的鼻祖,又有什麼與眾不同的特性呢?快來跟我們一起看看吧。

    比特幣的網絡

    比特幣使用的是P2P(peer-to-peer)網絡,此P2P非彼P2P,這裡是點對點的網絡架構,而不是人對人的借錢模式。

    P2P是指位於同一網絡中的每台計算機都彼此對等,各個節點共同提供網絡服務,不存在任何“特殊”節點。每個網絡節點以“扁平(flat)”的拓撲結構相互連通。在P2P網絡中不存在任何服務端(server)、中央化的服務、以及層級結構。

    傳統的網絡結構是client-server的模式,所有的client都是和server交互獲取信息, 只要server掛掉了,client也就沒有用了。

    而在P2P網絡中,沒有server的概念,每個節點可以作為一個server。對比起來P2P網絡在穩定性方面要比C-S架構的系統要穩定得多。

    網絡發現與同步

    既然是P2P網絡,那麼問題來了,這個P2P網絡是怎麼建立起來的呢?節點之間是怎麼發現的呢?

    有做過P2P下載的同學應該都聽說過種子的概念,這個種子裏面保存了其他活躍的節點的地址。通過下載種子就可以連接對應的節點。

    而每個節點又保存了最近連接或者活躍的節點,這樣就形成了龐大的P2P網絡。

    同樣的,比特幣的P2P網絡也是這樣的。

    新節點是如何發現網絡中的對等節點的呢?雖然比特幣網絡中沒有特殊節點,但是客戶端會維持一個列表,那裡列出了那些長期穩定運行的節點。這樣的節點被稱為“種子節點(seed nodes)”

    節點必須持續進行兩項工作:在失去已有連接時發現新節點,並在其他節點啟動時為其提供幫助。

    SPV節點

    我們之前介紹了,在比特幣的世界里既沒有賬戶,也沒有餘額,只有分散到區塊鏈里的UTXO(Unspent Transaction Outputs)。

    那麼如果想要驗證交易的話,需要從歷史的交易中查找所有的和該交易有關的交易,從而進行完整,全面的驗證。

    這樣做的問題就是,如果下載所有的歷史記錄,那麼需要上百G的硬盤空間,這對於手機或者其他輕量級的客戶端是無法想象的。

    於是SPV出現了。SPV的全稱是Simplified payment verification,叫做簡單認證支付。

    SPV保存的不是整個區塊鏈,而是區塊鏈的頭部,因為每個區塊鏈頭只有80字節,所以即使把所有的區塊頭都下載保存起來也不會很大。

    區塊鏈頭

    區塊頭由三組區塊元數據組成。首先是一組引用父區塊哈希值的數據,這組元數據用於將該區塊與區塊鏈中前一區塊相連接。

    第二組元數據,即難度、時間戳和nonce,與挖礦競爭相關。

    第三組元數據是merkle樹根(一種用來有效地總結區塊中所有交易的數據結構)。

    Nonce、難度目標和時間戳會用於挖礦過程,Merkle根用來索引和組織該區塊所有的交易信息。

    上圖是一個區塊鏈頭組成的鏈。

    Merkle Tree

    Merkle Tree,是一種樹(數據結構中所說的樹),網上大都稱為Merkle Hash Tree,這是因為 它所構造的Merkle Tree的所有節點都是Hash值。Merkle Tree具有以下特點:

    1. 它是一種樹,可以是二叉樹,也可以多叉樹,無論是幾叉樹,它都具有樹結構的所有特點;

    2. Merkle樹的恭弘=叶 恭弘子節點上的value,是由你指定的,這主要看你的設計了,如Merkle Hash Tree會將數據的Hash值作為恭弘=叶 恭弘子節點的值;

    3. 非恭弘=叶 恭弘子節點的value是根據它下面所有的恭弘=叶 恭弘子節點值,然後按照一定的算法計算而得出的。如Merkle Hash Tree的非恭弘=叶 恭弘子節點value的計算方法是將該節點的所有子節點進行組合,然後對組合結果進行hash計算所得出的hash value。

    有了Merkle Tree,我們只需要知道和要驗證的交易相關的其他Merkle Tree中的信息,就可以計算出整個Merkle Tree的值,這樣就可以直接使用頭部信息進行驗證了。這就是SPV的原理。

    比特幣中的區塊鏈

    區塊鏈是由包含交易信息的區塊從後向前有序鏈接起來的數據結構。它可以被存儲為flat file(一種包含沒有相對關係記錄的文件),或是存儲在一個簡單數據庫中。

    比特幣核心客戶端使用Google的LevelDB數據庫存儲區塊鏈元數據。

    它由一個包含元數據的區塊頭和緊跟其後的構成區塊主體的一長串交易組成。區塊頭是80字節,而平均每個交易至少是250字節,而且平均每個區塊至少包含超過500個交易。

    區塊標識符

    那怎麼表示一個區塊呢?我們使用區塊標誌符。

    區塊主標識符是它的加密哈希值,一個通過SHA256算法對區塊頭進行二次哈希計算而得到的数字指紋。產生的32字節哈希值被稱為區塊哈希值,但是更準確的名稱是:區塊頭哈希值,因為只有區塊頭被用於計算。

    第二種識別區塊的方式是通過該區塊在區塊鏈中的位置,即“區塊高度(block height)”。第一個區塊,其區塊高度為0
    和區塊哈希值不同的是,區塊高度並不是唯一的標識符。雖然一個單一的區塊總是會有一個明確的、固定的區塊高度,但反過來卻並不成立,一個區塊高度並不總是識別一個單一的區塊。兩個或兩個以上的區塊可能有相同的區塊高度,在區塊鏈里爭奪同一位置。

    創世區塊

    區塊鏈里的第一個區塊創建於2009年,被稱為創世區塊。它是區塊鏈裏面所有區塊的共同祖先,這意味着你從任一區塊,循鏈向後回溯,最終都將到達創世區塊。

    因為創世區塊被編入到比特幣客戶端軟件里,所以每一個節點都始於至少包含一個區塊的區塊鏈,這能確保創世區塊不會被改變。每一個節點都“知道”創世區塊的哈希值、結構、被創建的時間和裏面的一個交易。因此,每個節點都把該區塊作為區塊鏈的首區塊,從而構建了一個安全的、可信的區塊鏈的根。

    創世區塊的哈希值為:
    0000000000 19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

    創世區塊包含一個隱藏的信息。在其Coinbase交易的輸入中包含這樣一句話“The Times 03/Jan/2009 Chancellor on brink of second bailout forbanks.”這句話是泰晤士報當天的頭版文章標題,引用這句話,既是對該區塊產生時間的說明,也可視為半開玩笑地提醒人們一個獨立的貨幣制度的重要性,同時告訴人們隨着比特幣的發展,一場前所未有的世界性貨幣革命將要發生。該消息是由比特幣的創立者中本聰嵌入創世區塊中。

    coinbase的值是:04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73

    解碼方法如下:

    在python shell下:

    “04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73”.decode(‘hex’)

    輸出:

    ‘\x04\xff\xff\x00\x1d\x01\x04EThe Times 03/Jan/2009 Chancellor on brink of second bailout for banks’

    總結

    本文介紹了比特幣的網絡和比特幣中的區塊鏈的相關概念,希望大家能夠喜歡。

    本文作者:flydean程序那些事

    本文鏈接:http://www.flydean.com/bitcoin-blockchain-network/

    本文來源:flydean的博客

    歡迎關注我的公眾號:程序那些事,更多精彩等着您!

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

    【其他文章推薦】

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

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

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

  • 「半雞半鴨」:考古發現最古老禽類化石

    摘錄自2020年3月28日大紀元報導

    考古學家發現一隻禽類生物的頭骨和腿骨化石,經檢驗發現它生活在距今約6,680萬~6,670萬年前,是至今全球發現的最古老的鳥類化石。

    這份近期發表在《自然》(Nature)期刊上的研究公布了這一發現。研究者之一劍橋大學的古生物學家菲爾德(Daniel Field)說:「這是我們至今發現的最早存在的鳥類的證據。」

    恐龍大約在距今6,600萬年前滅絕,因此這隻生物生活在僅比那個時間點早一點的時期。在此之前,科學家找到的最早的鳥類化石大約生活在距今6,650萬年前。新發現的化石比這個更早一些。

    研究人員估計這隻鳥的體重為400克左右,只有現在的水鳥——鳧的一半大。「我們認為它的臉看起來有點像現代的雞,但是頭骨的後面看起來又更像現在的鴨子。」菲爾德說。一起發現的還有它的腿骨化石,看起來它有著兩條細長的腿,說明它是生活在岸邊的一種禽類。

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

    【其他文章推薦】

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

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

    ※別再煩惱如何寫文案,掌握八大原則!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

    FB行銷專家,教你從零開始的技巧

  • 幫居民生計找出路 坦尚尼亞社區林業 改善盜伐有成

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

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

    【其他文章推薦】

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

    ※別再煩惱如何寫文案,掌握八大原則!

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

    ※超省錢租車方案

    ※教你寫出一流的銷售文案?

    網頁設計最專業,超強功能平台可客製化

  • 地球暖化冰河融解 北極新發現5座島嶼

    摘錄自2019年10月23日民視新聞報導

    俄羅斯研究人員23日表示,他們在北極偏遠地區發現了5座新島,目前還沒有命名研究人員是在法蘭士約瑟夫地群島,發現這5座新島嶼。島嶼原本為冰河覆蓋,因為冰河融化的關係,才被人發現。從無人機空拍畫面可以看到島嶼上有北極熊和海象等動物居住。

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

    【其他文章推薦】

    ※教你寫出一流的銷售文案?

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

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 一種失去飛翔能力的鳥 使科學家重拾對環境的希望

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

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

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

    ※教你寫出一流的銷售文案?

    FB行銷專家,教你從零開始的技巧

  • 熱浪席捲 澳洲全國均溫40.9度創新高

    摘錄自2019年12月18日中央社報導

    澳17日出現有紀錄以來最熱的一天,氣象局測到全國平均氣溫高達攝氏40.9度(華氏105.6度)。先前澳洲高溫紀錄為2013年1月時創下的攝氏40.3度。

    在近日野火肆虐澳洲東岸,又有熱浪席捲各地,氣候狀況更形惡劣的情況下,高溫紀錄預料很快就會再寫新高。

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

    【其他文章推薦】

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

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

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

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

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

    ※教你寫出一流的銷售文案?

  • 捨電動車 韓國現代氫動力貨卡將上市 目標零碳排征服瑞士高山

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

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

    【其他文章推薦】

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

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

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

  • 研究:為躲避赤道高溫 海洋生物逐漸往極地方向移動

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

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

    【其他文章推薦】

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

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

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

    南投搬家公司費用需注意的眉眉角角,別等搬了再說!

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

    ※教你寫出一流的銷售文案?