標籤: 台北網站設計

  • 印尼水患災情慘重 雅加達省長遭民眾控告

    摘錄自2020年1月14日中央社報導

    印尼一名律師今天(14日)表示,在暴雨引發洪水及土石流災情,導致數十人喪命、數千人無家可歸後,雅加達省長阿尼斯(AniesBaswedan)因此被這座大城市的居民控告。

    超過200名水患受災民眾昨天在首都雅加達(Jakarta)地方法院提出集體訴訟,尋求總計約430億印尼盾(約新台幣9000萬元)的賠償金。

    這起訴訟指出,阿尼斯未能替雅加達這座大型城市提供合適的預警系統及有效的緊急救難措施,好讓人民的性命及財務損失降到最低。

    雅加達的法務局沒有立即回應置評請求。

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

    【其他文章推薦】

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

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

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

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

  • 富士康杭州投12億,發展新能源汽車租賃業務

    富士康集團總投資12億元,註冊資本1億元,成立杭州浙譽新能源汽車服務有限公司。作為富士康科技集團在杭州開展新能源汽車分時租賃運營的服務主體,專案計畫三年內在杭州地區累計投放5000輛電動汽車。   電動汽車分時租賃是一種城市短途出行方式,在汽車共用的基礎上使用電動汽車進行共用運營,通過會員制的方式以小時計費的新能源電動汽車的租賃服務。其租賃模式就像“租公共自行車一樣”,會員通過網路或手機終端輕鬆實現汽車預定,然後線上下取車實現消費,整個過程全程自助。   該專案是2015年3月富士康集團與杭州市政府簽署全面戰略合作協議後,與杭州進行全面深化合作所邁出的實質性第一步。

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

    【其他文章推薦】

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

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

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

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

  • 二叉搜索樹BST(C語言實現可用)

    二叉搜索樹BST(C語言實現可用)

    1:概述

    搜索樹是一種可以進行插入,搜索,刪除等操作的數據結構,可以用作字典或優先級隊列。二叉搜索樹是最簡單的搜索樹。其左子樹的鍵值<=根節點的鍵值,右子樹的鍵值>=根節點的鍵值。

    如果共有n個元素,那麼每次操作需要的O(log n)的時間.

     

     

     

    常用知識點

    • 滿二叉樹 : 一棵深度為k,且有2^k-1個節點的二叉樹,稱為滿二叉樹。這種樹的特點是每一層上的節點數都是最大節點數。
    • 完全二叉樹 : 而在一棵二叉樹中,除最後一層外,若其餘層都是滿的,並且最後一層要麼是滿的,要麼在右邊缺少連續若干節點,則此二叉樹為完全二叉樹。具有n個節點的完全二叉樹的深度為floor(log2n)+1。深度為k的完全二叉樹,至少有2^(k-1)個恭弘=叶 恭弘子節點,至多有2^k-1個節點。

    2.基本操作

    1. 查找(search)
    2. 插入(insert)
    3. 刪除(remove)

    3:操作原理

      

    查找

    假設查找的值為x,從根節點的值開始比對,如果小於根節點的值,則往左兒子繼續查找,如果大於根節點的值,則往右兒子繼續查找.依次類推.直到當前節點的值等於要查找的值.

     

      以查找數值10為例

    插入

    按照查找的步驟即可找到插入值應該在的位置

     

     

    以插入數值6為例

    刪除:

    有四種情況:

    1: // 當前節點無左節點 ,右字節點7覆蓋5, 

    : 3: // 當前節點無右節點 ,右字節點7覆蓋5, 

     

     : 4: // 刪除節點5的左節點沒有右節點, 只需要8作為3的右節點 ,3節點覆蓋5

     

     

    : 2:  如果以上3中情況都沒有,只需要尋找當前節點的左節點的所有字節點的最大值,用最大值填充5節點 4填充5

     

     

     

     

    5:完整代碼

    #include <stdio.h> 
    #include <stdlib.h>
    struct TNode{
        int data;
        struct TNode *lt;
        struct TNode *rt;    
    };
    struct TNode* insrtTree(struct TNode *t,int key,int i);
    void printTree(struct TNode *root);
    struct TNode* delTree(struct TNode* t,int key);
    int find(struct TNode* t,int key); 
    int arr[1000]={0};
    int main(){
        int n,m;
        int i,t;
        scanf("%d%d",&n,&m); 
        struct TNode *root=NULL;
        for(i=0;i<n;i++){
            scanf("%d",&arr[i]); 
            root=insrtTree(root,arr[i],i);
        }
        //t=arr[m-1];
        
        /*
        if(arr[m-1]==0){
            printf("Right child");
        }else{
            printf("Light child");
        }*/
        root=delTree(root,10);
        printTree(root);
        return 0;
    }
    
    int find(struct TNode* pt,int key){
        if(pt==NULL)return NULL;
        else if(pt->data==key)return 1;
        else if(pt->data>key) return find(pt->lt,key);
        else if(pt->data<key) return find(pt->rt,key);
    }
    // 刪除節點 
    struct TNode* delTree(struct TNode* pt,int key){
        if(pt==NULL)return NULL;
        else if(pt->data>key) pt->lt=delTree(pt->lt,key);//尋找左節點 
        else if(pt->data<key) pt->rt=delTree(pt->rt,key);//尋找右節點
        //  找到節點 處理四種情況  
        else if(pt->lt==NULL){ // 當前節點無左節點 
            struct TNode* curt=pt->rt;
            free(pt);
            return curt;
        }else if(pt->rt==NULL){// 當前節點無右節點 
            struct TNode* curt=pt->lt;
            free(pt);
            return curt;
        }else if(pt->lt->rt==NULL){// 當前節點的左節點無右節點 
            struct TNode* curt=pt->lt;
            curt->rt=pt->rt;
            free(pt);
            return curt;
        }else{ 
        // 以上不滿足就把左兒子的子孫中最大的節點, 即右子樹的右子樹的...右子樹, 
        //提到需要刪除的節點位置
                struct TNode* p;
                for(p=pt->lt;p->rt->rt!=NULL;p=p->rt);
                struct TNode* curt=p->lt;
                p->rt=curt->rt;
                curt->lt=pt->lt;
                curt->rt=pt->rt;
                free(p);
                return curt;
        }
        return pt;
    }
    struct TNode* insrtTree(struct TNode *t,int key,int i){
        if(t==NULL){ //處理第一個節點 以及子節點為NULL情況 
            t=(struct TNode*)malloc(sizeof(struct TNode));
            t->lt=t->rt=NULL;
            t->data=key;
            return t;
        }
        if(t->data>key){// 插入左子樹情況 
             arr[i]=1;
            t->lt=insrtTree(t->lt,key,i);
        }else{         // 插入右子樹情況
            arr[i]=0;
            t->rt=insrtTree(t->rt,key,i);
        }
        return t;
    }
    void printTree(struct TNode *root){
        if(root==NULL)return;
        printf("%d ",root->data);
        printTree(root->lt);
        printTree(root->rt);
    }

     

    說明: 本身學習了 https://blog.csdn.net/li_l_il/article/details/88677927 但是完善了代碼 

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

    【其他文章推薦】

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

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

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

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

  • 數據結構之隊列and棧總結分析

    一、前言:

      數據結構中隊列和棧也是常見的兩個數據結構,隊列和棧在實際使用場景上也是相輔相成的,下面簡單總結一下,如有不對之處,多多指點交流,謝謝。

    二、隊列簡介

      隊列顧名思義就是排隊的意思,根據我們的實際生活不難理解,排隊就是有先後順序,先到先得,其實在程序數據結構中的隊列其效果也是一樣,及先進先出。

         隊列大概有如下一些特性:

         1、操作靈活,在初始化時不需要指定其長度,其長度自動增加(默認長度為32)

            注:在實際使用中,如果事先能夠預估其長度,那麼在初始化時指定長度,可以提高效率

            2、泛型的引入,隊列在定義時可以指定數據類型避免裝箱拆箱操作

         3、存儲數據滿足先進先出原則

           

       c#中有關隊列的幾個常用方法:

      • Count:Count屬性返回隊列中元素個數。
      • Enqueue:Enqueue()方法在隊列一端添加一個元素。
      • Dequeue:Dequeue()方法在隊列的頭部讀取和刪除元素。如果在調用Dequeue()方法時,隊列中不再有元素,就拋出一個InvalidOperationException類型的異常。
      • Peek:Peek()方法從隊列的頭部讀取一個元素,但不刪除它。
      • TrimExcess:TrimExcess()方法重新設置隊列的容量。Dequeue()方法從隊列中刪除元素,但它不會重新設置隊列的容量。要從隊列的頭部去除空元素,應使用TrimExcess()方法。
      • Clear:Clear()方法從隊列中移除所有的元素。
      • ToArray:ToArray()複製隊列到一個新的數組中。

      下面通過隊列來實例模擬消息隊列的實現流程:

     

    using System;
    using System.Collections;
    using System.Collections.Generic;
    
    namespace dataStructureQueueTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("通過Queue來模擬消息隊列的實現");
                QueueTest queueTest = new QueueTest();
    
                while (true)
                {
                    Console.WriteLine("請輸入你操作的類型:1:代表生成一條消息,2:代表消費一條消息");
                    string type = Console.ReadLine();
                    if (type == "1")
                    {
                        Console.WriteLine("請輸入具體消息:");
                        string inforValue = Console.ReadLine();
                        queueTest.InformationProducer(inforValue);
                    }
                    else if (type == "2")
                    {
                        //// 在消費消息的時候,模擬一下,消費成功與消費失敗下次繼續消費的場景
    
                        object inforValue = queueTest.InformationConsumerGet();
                        if (inforValue == null)
                        {
                            Console.WriteLine("當前無可消息可消費");
                        }
                        else
                        {
                            Console.WriteLine("獲取到的消息為:" + inforValue);
    
                            Console.WriteLine("請輸入消息消費結果:1:成功消費消息,2:消息消費失敗");
                            string consumerState = Console.ReadLine();
    
                            ///// 備註:該操作方式線程不安全,在多線程不要直接使用
                            if (consumerState == "1")
                            {
                                queueTest.InformationConsumerDel();
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("操作有誤,請重新選擇");
                    }
                }
            }
        }
    
        /// <summary>
        /// 隊列練習
        /// </summary>
        public class QueueTest
        {
            /// <summary>
            /// 定義一個隊列
            /// </summary>
            public Queue<string> queue = new Queue<string>();
    
            /// <summary>
            /// 生成消息--入隊列
            /// </summary>
            /// <param name="inforValue"></param>
            public void InformationProducer(string inforValue)
            {
                queue.Enqueue(inforValue);
            }
    
            /// <summary>
            /// 消費消息---出隊列--只獲取數據,不刪除數據
            /// </summary>
            /// <returns></returns>
            public object InformationConsumerGet()
            {
                if (queue.Count > 0)
                {
                    return queue.Peek();
                }
    
                return null;
            }
    
            /// <summary>
            /// 消費消息---出隊列---獲取數據的同時刪除數據
            /// </summary>
            /// <returns></returns>
            public string InformationConsumerDel()
            {
                if (queue.Count > 0)
                {
                    return queue.Dequeue();
                }
    
                return null;
            }
        }
    }

     

     

    三、棧簡介

      棧和隊列在使用上很相似,只是棧的數據存儲滿足先進后出原則,棧有如下一些特性:

         1、操作靈活,在初始化時不需要指定其長度,其長度自動增加(默認長度為10)

            注:在實際使用中,如果事先能夠預估其長度,那麼在初始化時指定長度,可以提高效率

            2、泛型的引入,棧在定義時可以指定數據類型避免裝箱拆箱操作

         3、存儲數據滿足先進后出原則

        c#中有關棧的幾個常用方法:

    • Count:Count屬性返回棧中的元素個數。
    • Push:Push()方法在棧頂添加一個元素。
    • Pop:Pop()方法從棧頂刪除一個元素,並返回該元素。如果棧是空的,就拋出一個InvalidOperationException類型的異常。
    • Peek:Peek()方法返回棧頂的元素,但不刪除它。
    • Contains:Contains()方法確定某個元素是否在棧中,如果是,就返回true。

         下面通過一個棧來模擬瀏覽器的回退前進操作的實現

     

    using System;
    using System.Collections.Generic;
    
    namespace dataStructureStackTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                //// 通過棧來模擬瀏覽器回退前進操作
                ////   1、定義兩個棧,分別記錄回退的地址集合,和前進地址集合
                ////   2、在操作具體的回退或者前進操作時
                ////      如果和前一次操作相同,那麼就取出對應隊列的一條數據存儲到另外一個隊列
                Console.WriteLine("本練習模擬瀏覽器的回退前進操作:");
    
                /// 假設瀏覽器已瀏覽了20個網站記錄
                StackTest stackTestBack = new StackTest(20);
                StackTest stackTestGo = new StackTest(20);
                for (int i = 0; i < 20; i++)
                {
                    stackTestBack.PushStack("網站" + (i + 1).ToString());
                }
    
                //// 記錄上一次操作
                string beforOpert = "";
                while (true)
                {
                    Console.WriteLine("");
                    Console.WriteLine("請輸入你操作的類型:1:回退,2:前進");
                    string type = Console.ReadLine();
    
                    if (type == "1")
                    {
                        //// 出棧
                        if (beforOpert == type)
                        {
                            stackTestGo.PushStack(stackTestBack.GetAndDelStack());
                        }
                        string wbeSit = stackTestBack.GetStack();
                        Console.WriteLine("回退到頁面:" + wbeSit);
                        beforOpert = type;
                    }
                    else if (type == "2")
                    {
                        //// 出棧
                        if (beforOpert == type)
                        {
                            stackTestBack.PushStack(stackTestGo.GetAndDelStack());
                        }
                        string wbeSit = stackTestGo.GetStack();
    
                        Console.WriteLine("回退到頁面:" + wbeSit);
                        beforOpert = type;
                    }
                    else
                    {
                        Console.WriteLine("請輸入正確的操作方式!!");
                    }
                }
            }
        }
    
        /// <summary>
        /// 隊列練習
        /// </summary>
        public class StackTest
        {
            /// <summary>
            /// 定義一個棧
            /// </summary>
            public Stack<string> stack;
    
            /// <summary>
            ///無參數構造函數,棧初始化為默認長度
            /// </summary>
            public StackTest()
            {
                stack = new Stack<string>();
            }
    
            /// <summary>
            ///有參數構造函數,棧初始化為指定長度
            ///如果在定義隊列時,如果知道需要存儲的數據長度,那麼最好預估一個長度,並初始化指定的長度
            /// </summary>
            public StackTest(int stackLen)
            {
                stack = stackLen > 0 ? new Stack<string>(stackLen) : new Stack<string>();
            }
    
            /// <summary>
            /// 入棧
            /// </summary>
            /// <param name="inforValue"></param>
            public void PushStack(string inforValue)
            {
                stack.Push(inforValue);
            }
    
            /// <summary>
            /// 出棧(但不刪除)
            /// </summary>
            /// <returns></returns>
            public string GetStack()
            {
                if (stack.Count > 0)
                {
                    return stack.Peek();
                }
    
                return null;
            }
    
            /// <summary>
            /// 出棧(並刪除)
            /// </summary>
            /// <returns></returns>
            public string GetAndDelStack()
            {
                if (stack.Count > 0)
                {
                    return stack.Pop();
                }
    
                return null;
            }
        }
    }

     

    四、使用場景總結

      根據隊列和棧的特點,下面簡單總結一下隊列和棧的一些實際使用場景

       隊列:

        1、異步記錄日誌,此處會涉及到單例模式的使用

        2、消息隊列

        3、業務排隊,比如12306車票購買排隊等候

        4、其他符合先進先出原則的業務操作

       棧:

        1、可回退的操作記錄,比如:瀏覽器的回退操作

        2、計算表達式匹配,比如:計算器表達式計算

        3、其他符合先進后出原則的業務操作

     

    附件:

    關於這一些練習的代碼,上傳到github,有興趣的可以看一下:

     

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

    【其他文章推薦】

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

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

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

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

  • 吉利:到2020年新能源汽車銷量將實現90%以上的占比

    日前,吉利控股集團董事長李書福在接受《中國經營報》記者採訪時表示,以後我們開發的新產品基本是新能源汽車和智慧互聯汽車,傳統汽車就逐漸不生產了。

    此話背後,實際就是吉利於近日提出的“藍色吉利行動”中的重要一環,到2020年,其新能源汽車銷量將實現90%以上的銷量占比。

    具體來說,根據“藍色吉利行動”,吉利新能源將在技術上主打純電動、油電混動、插電式混合動力三種路線,並通過兩大平臺——FE(中高端)與PE(緊湊級)平臺來發展純電動車板塊。

    從以上路徑上看,吉利與其他車企並無二致,但其公佈的“五大承諾”卻足以讓業內熱議——第一,提前全面實現2020年國家第四階段每百公里5.0L的企業平均燃油消耗限值;第二,實現消費者用傳統汽車的購買成本購買插電式混動汽車的夢想;第三,實現到2020年新能源汽車銷量占吉利整體銷量的90%以上;第四,在氫燃料及金屬燃料電池汽車研發方面取得實質性成果;第五,實現新能源技術,智慧化、輕量化技術在行業的領先地位。

    雖然言之鑿鑿,但不得不說的是,90%以上的新能源銷量加上此前吉利發佈的“2020年實現120萬輛”的銷量目標,同年吉利新能源汽車銷量目標竟逾100萬輛。

    對此,吉利控股集團總裁CEO安聰慧表示:“吉利制定這樣的目標並不是為了和其他企業進行對比,而是結合自身發展提出來的。”

    據其介紹,在技術領域,吉利汽車將以與沃爾沃合作打造的CMA中高級車基礎模組架構為核心打造新能源車型,該方面的設計研發工作主要由吉利汽車歐洲研發中心承擔,該中心在瑞典哥德堡已有1200名工程師,中國杭州也有300名工程師,負責架構開發、上車體開發、核心部件開發開發,整車設計、工程製造及新技術的研發。CMA基礎模組架構可以實現電機+發動機等核心部件的批量生產。

    此外,2015年初,吉利與新大洋機電集團成立合資公司並推出知豆電動車,加之此前其子公司上海華普國潤與康迪車業成立的合資公司,署名吉利旗下的新能源車型並不止吉利品牌。雖然,吉利在新能源領域的開疆破土頗有“借力而為”之感,但不論如何,2015年1~11月,在乘聯會統計的自主品牌新能源車銷量占比情況中,吉利節節攀升,的確實現了在自主品牌領域的市占率穩增,也正因如此,加之政策的多重鼓勵,吉利才許下到2020年實現新能源汽車逾百萬的戰略目標。

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

    【其他文章推薦】

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

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

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

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

  • 源碼學習系列之SpringBoot自動配置(篇二)

    源碼學習系列之SpringBoot自動配置(篇二)

    源碼學習系列之SpringBoot自動配置(篇二)之HttpEncodingAutoConfiguration 源碼分析

    繼上一篇博客之後,本博客繼續跟一下SpringBoot的自動配置源碼

    ok,先複習一下上一篇的內容,從前面的學習,我們知道了SpringBoot的自動配置主要是由一個選擇器AutoConfigurationImportSelector,先通過選擇器將自動配置的類加載到Spring容器

    注意點:

    • List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);獲取的候選配置的類名
    • 由SpringFactoriesLoader加載器負責加載配置類名,已經裝載配置類到容器,SpringFactoriesLoader的loadSpringFactories方法讀取自動配置工程的META-INF/spring.factories配置文件,加載配置類的全類名,包裝成Properties對象,然後再加載到容器里
    public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
        /* 將spring.factories的類都裝載到Spring容器*/
         public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
            String factoryClassName = factoryClass.getName();
    
            try {
            //將META-INF/spring.factories文件里配置的屬性都裝載到Enumeration數據結構里
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                ArrayList result = new ArrayList();
                //遍歷獲取屬性,然後再獲取對應的配置類全類名
                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                    String factoryClassNames = properties.getProperty(factoryClassName);
                    result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
                }
    
                return result;
            } catch (IOException var8) {
                throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);
            }
        }
    

    ok,Springboot的自動配置類都在這個包里,源碼很多,所以本博客只是簡單跟一下源碼

    自動配置可以說是SpringBoot框架的一個很重要的功能,其強大的功能就是通過很多配置類實現的,當然這麼多配置,可以參考SpringBoot官方的配置參考:
    https://docs.spring.io/spring-boot/docs/2.1.10.RELEASE/reference/html/common-application-properties.html

    SpringBoot的自動配置類很多,顯然不是每個配置類都生效的,比如你沒引對應的jar,那對應的配置類肯定是不起效的,ok,本博客以HttpEncodingAutoConfiguration自動編碼配置類為實例,記錄一下SpringBoot的自動配置

    先補充一些@Conditional註解的用法:詳情可以參考我上篇博客

    @Conditional派生註解 作用(都是判斷是否符合指定的條件)
    @ConditionalOnJava 系統的java版本是否符合要求
    @ConditionalOnBean 有指定的Bean類
    @ConditionalOnMissingBean 沒有指定的bean類
    @ConditionalOnExpression 符合指定的SpEL表達式
    @ConditionalOnClass 有指定的類
    @ConditionalOnMissingClass 沒有指定的類
    @ConditionalOnSingleCandidate 容器只有一個指定的bean,或者這個bean是首選bean
    @ConditionalOnProperty 指定的property屬性有指定的值
    @ConditionalOnResource 路徑下存在指定的資源
    @ConditionalOnWebApplication 系統環境是web環境
    @ConditionalOnNotWebApplication 系統環境不是web環境
    @ConditionalOnjndi JNDI存在指定的項

    通過上篇博客的學習,我們已經知道了SpringBoot有很多自動配置類,所以本博客拿HttpEncodingAutoConfiguration類來看看

    補充:

    • @Configuration proxyBeanMethods屬性:默認是開啟的,開啟后允許其它配置類調用這個類的@bean方法,詳情參看Spring官方文檔:
    package org.springframework.boot.autoconfigure.web.servlet;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
    import org.springframework.boot.autoconfigure.http.HttpProperties;
    import org.springframework.boot.autoconfigure.http.HttpProperties.Encoding;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.boot.web.server.WebServerFactoryCustomizer;
    import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
    import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.Ordered;
    import org.springframework.web.filter.CharacterEncodingFilter;
    
    @Configuration(
        proxyBeanMethods = false
    )//指定是一個配置列,關了proxyBeanMethods,其它配置類就不能調相應的@bean類
    @EnableConfigurationProperties({HttpProperties.class})//讓使用 @ConfigurationProperties註解的HttpProperties類生效,HttpProperties類通過ConfigurationProperties註解,將屬性配置一個一個加載進來
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )//指定系統環境是Web環境配置才起效,並且指定類型是SERVLET
    @ConditionalOnClass({CharacterEncodingFilter.class})//系統有CharacterEncodingFilter過濾器類,則配置類起效,CharacterEncodingFilter類:SpringMVC中進行亂碼解決的過濾器
    @ConditionalOnProperty(
        prefix = "spring.http.encoding",
        value = {"enabled"},
        matchIfMissing = true
    )//判斷配置文件是否有spring.http.encoding.enabled屬性,如果沒配置,也是默認為true的,因為配置了`matchIfMissing =true`
    public class HttpEncodingAutoConfiguration {
        //創建一個Encoding對象
        private final Encoding properties;
        // 構造函數里通過properties.getEncoding();進行屬性映射,獲取默認的配置
        public HttpEncodingAutoConfiguration(HttpProperties properties) {
            this.properties = properties.getEncoding();
        }
    
        @Bean
        @ConditionalOnMissingBean//如果系統沒有CharacterEncodingFilter類,就執行characterEncodingFilter方法
        public CharacterEncodingFilter characterEncodingFilter() {
            //重新創建一個編碼過濾器
            OrderedCharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
            //設置默認的配置
            filter.setEncoding(this.properties.getCharset().name());
            filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
            filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
            return filter;
        }
    
        @Bean
        public HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
            return new HttpEncodingAutoConfiguration.LocaleCharsetMappingsCustomizer(this.properties);
        }
    
        private static class LocaleCharsetMappingsCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
            private final Encoding properties;
    
            LocaleCharsetMappingsCustomizer(Encoding properties) {
                this.properties = properties;
            }
    
            public void customize(ConfigurableServletWebServerFactory factory) {
                if(this.properties.getMapping() != null) {
                    factory.setLocaleCharsetMappings(this.properties.getMapping());
                }
    
            }
    
            public int getOrder() {
                return 0;
            }
        }
    }
    

    通過對HttpEncodingAutoConfiguration源碼的學習,可以看出,其實主要是用@Conditional及其派生註解,這些註解都是要在特定情況才會起效,起效了,才會將組件加載到Spring容器里

    ok,然後我們怎麼知道哪些配置是起效的?在SpringBoot項目里,是可以通過配置,開啟打印的,可以在application.properties加上debug=true屬性就可以

    控制台打印的Positive matches就表示有效的配置類

    console打印的Negative matches表示不起效的配置類:
    比如我的項目沒有加aop的,aop自動配置類就不起效

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

    【其他文章推薦】

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

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

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

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

  • ES6學習筆記01 — 暫時性死區 ( temporal dead zone )

    參考文檔:   

           

           

    注:文中代碼僅作示意,複製運行時需要適當調整

      
    ES6 規定,如果代碼區塊中存在 let  const 命令聲明的變量,這個區塊對這些變量從一開始就形成了封閉作用域,直到聲明語句完成,這些變量才能被訪問(獲取或設置),否則會報錯ReferenceError。這在語法上稱為“暫時性死區”(英temporal dead zone,簡 TDZ),即代碼塊開始到變量聲明語句完成之間的區域。
      通過 var 聲明的變量擁有變量提升、沒有暫時性死區,作用於函數作用域:

      • 當進入變量的作用域(包圍它的函數),立即為它創建(綁定)存儲空間,立即被初始化並被賦值為 undefined   
      • 當執行到變量的聲明語句時,如果變量定義了值則會被賦值
        (function fn() {  //函數作用域開始
            console.log(temp)  //undefined
            //聲明
            var temp 
            console.log(temp)  //undefined
            //賦值
            temp = 123
            console.log(temp)  //123
        })()
        //在函數作用域外訪問
        console.log(temp)  //ReferenceError: temp is not defined

     

      通過 let 聲明的變量沒有變量提升、擁有暫時性死區,作用於塊級作用域:

      • 當進入變量的作用域(包圍它的語法塊),立即為它創建(綁定)存儲空間,不會立即初始化,也不會被賦值
      • 訪問(獲取或設置)該變量會拋出異常 ReferenceError
      • 當執行到變量的聲明語句時,如果變量定義了值則會被賦值,如果變量沒有定義值,則被賦值為undefined
            {  //函數作用域開始,TDZ開始
                console.log(temp)  //ReferenceError: temp is not defined
                //聲明
                let temp  
                console.log(temp)  //ReferenceError: Cannot access 'temp' before initialization
                //賦值
                temp = 345  //TDZ結束
                console.log(temp)  //345
                //塊級作用域結束
            }
            //在塊級作用域外訪問
            console.log(temp)  //ReferenceError: temp is not defined

     

      通過 const 聲明的常量,需要在定義的時候就賦值,並且之後不能改變,暫時性死區與 let 類似。

            {   //作用域開始,TDZ開始
                console.log(temp)  //ReferenceError: temp is not defined
                //聲明並賦值
                const temp = 789  //TDZ結束
                console.log(temp)  //789 
                //給常量賦值
                temp = 987  //TypeError: Assignment to constant variable
                //作用域結束
            }   
            //在作用域外訪問
            console.log(temp)  //ReferenceError: temp is not defined

     

      
    一句話總結:在塊級作用域中, let  const 聲明的變量、常量在聲明語句執行完成之前不能訪問(包括聲明語句本身)
      另外,容易因為 暫時性死區 而出錯的細節代碼在此不展開舉例,參考文檔中有詳情舉例。  
      附:第一次寫學習筆記,寫隨筆花費的時間比學習相關內容的時間還要長,感覺有點本末倒置,不過以後回頭看應該會覺得有所值得吧!  

      

      

     

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

    【其他文章推薦】

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

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

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

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

  • 電動摺疊腳踏車、滑板車搶攻最後一哩交通需求

    電動摺疊腳踏車、滑板車搶攻最後一哩交通需求

    傳統交通工具汽機車造成許多空氣污染與碳排放,許多廠商認為解決方案是電動車、電動機車,不過,也有人提出另一個想法,那就是何不更充分利用大眾運輸工具,只要解決捷運站到目的地的「最後一哩」交通需求即可鼓勵許多人不用自己開車、騎機車,而願意搭乘捷運。在 CES 2016 上,許多廠商都推出類似概念的產品。

    Cycle Board 推出「街道衝浪者」(Street Surfer)電動滑板三輪車,這輛滑板車的前端有兩輪,連接把手,負責轉向,較大的雙前輪也提供在人行道等不平坦路面上的穩定性,後端有一個小輪,把手可伸縮配合使用者身高,也可收疊起來方便攜帶,把手上除了剎車等基本控制,還可裝上手機。「街道衝浪者」充電一次可行駛 15 到 20 英里(24.1 到 32.2 公里),最高時速 20 英里(32.2 公里)。

    ▲ Street Surfer(Source:) Urban626 則推出 Urb-e 折疊式電動腳踏車,結構像是一把折疊刀,設計師宣稱可快速折疊,實測大約 1 秒鐘可折疊起來,便於帶電車車廂,或是裝進汽車後車廂,骨架以鋁打造,總重 35 英磅(15.876 公斤),時速最高 24 公里,充電 4 小時充飽後,可以行駛 32 公里。   由 Smart Rhino 推出的 Xcooter 同樣是電動折疊式腳踏車,以 X 形狀骨架收合,充電 3 小時可行駛 28 公里,最高時速 80 公里,重量 18 公斤。這些可折疊的電動腳踏車或許是解決捷運站到目的地交通問題的解決方案,不過售價可不便宜,Urb-e 售價 1,500 美元,將近 5 萬元新台幣,Xcooter 預售價 1,499 美元,而 2016 年 4 月正式上市時售價將為 1,799 美元,將近 6 萬元新台幣。

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

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

    【其他文章推薦】

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

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

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

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

  • Ansible之playbook拓展

      一、handlers和notify結合使用觸發條件

      handlers同tasks是屬同級,相當於一個特殊任務列表,這些任務同前文說的tasks里的任務沒有本質的不同,用於當關注的資源發生變化時,才會採取一定的操作。notify此action可用於在每一個play的最後被觸發,這樣可避免多次有改變發生時都執行指定的操作,僅在所有的變化發生完成后一次性地執行指定操作,在notify中列出的操作稱為handler,換句話說當所關注的資源發生變化時notify將調用handlers中定義的操作。其中notify所在任務就是被監控的任務資源變化的任務,notify可以調用多個handlers定義的操作,一個handlers里可以定義很多任務。

    ---
    - hosts: websers
      remote_user: root
    
      tasks:
        - name: create apache group
          group: name=apache gid=80 system=yes
        - name: create apache user
          user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
        - name: install httpd
          yum: name=httpd
        - name: copy config file
          copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
          notify: restart httpd service
    
        - name: start httpd service
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart httpd service
          service: name=httpd state=restarted   
    

      說明:notify后指定的名稱必須要和handlers里的任務名稱相同,如不同handlers所定義的任務將不會執行,相當於沒有notify調用handlers里的任務。

      在某些情況下,我們可能同時需要調用多個handlers,或者需要使用handlers其他handlers,ansible可以很簡單的實現這些功能,如下所示

      1)調用多個handlers

    ---
    - hosts: websers
      remote_user: root
    
      tasks:
        - name: create apache group
          group: name=apache gid=80 system=yes
        - name: create apache user
          user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
        - name: install httpd
          yum: name=httpd
        - name: copy config file
          copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
          notify: 
            - restart httpd service
            - check httpd process
    
        - name: start httpd service
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart httpd service
          service: name=httpd state=restarted
        - name: check httpd process                                                                                      
          shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log
    

      說明:調用多個handlers我們需要在notify中寫成列表的形式,同樣我們被觸發的任務名稱需要同handlers里的被調用的任務名稱完全相同

      2)handlers調用handlers

    ---
    - hosts: websers
      remote_user: root
    
      tasks:
        - name: create apache group
          group: name=apache gid=80 system=yes
        - name: create apache user
          user: name=apache uid=80 group=apache system=yes shell=/sbin/nologin home=/var/www/html 
        - name: install httpd
          yum: name=httpd
        - name: copy config file
          copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
          notify: restart httpd service
    
        - name: start httpd service
          service: name=httpd state=started enabled=yes
    
      handlers:
        - name: restart httpd service
          service: name=httpd state=restarted
          notify: check httpd process                                                                                    
        - name: check httpd process
          shell: /usr/bin/killall -0 httpd &> /tmp/httpd.log
    

      說明:handlers調用handlers,則直接在handlers中使用notify選項就可以。

    在使用handlers我們需要注意一下幾點:

      1)handlers只有在其所在任務被執行時才會被運行,handlers定義的任務它不會像task任務那樣,自動會從上至下依次執行,它只會被notify所在的任務發生狀態改變時才會觸發handlers 的任務執行,如果一個任務中定義了notify調用handlers,但由於條件的判斷等原因,該任務尚未執行,那麼notify調用的handlers同樣也不會執行。

      2)handlers只會在play的末尾運行一次;如果想要在一個playbook的中間運行handlers,則需要使用meta模塊來實現,如:-mate: flush_handlers

      二、playbook中變量的使用

    ansible中變量的命名規範同其他語言或系統中變量命名規則非常類似。變量名以英文大小寫字母開頭,中間可以包含下劃線和数字,ansible變量的來源有很多,具體有以下幾點:

      1)ansible setup模塊,這個模塊可以從遠程主機上獲取很多遠程主機的基本信息,它所返回的所有變量都可以直接調用,有關setup說明請參考本人博客

      2)在/etc/ansible/hosts中定義,此文件是ansible執行名時默認加載的主機清單文件,在裏面除了可定義我們要管理的主機外,我們還可以定義針對單個主機定義單獨的變量,我們把針對單獨某一台主機定義的變量叫做普通變量(也可叫做主機變量);還有一種變量它不是針對單獨一個主機,它針對某一個組裡的所有主機,我們把這種變量叫做公共組變量。主機清單中定義的變量優先級是普通變量高於公共變量。

        2.1)主機變量,可以在主機清單中定義主機時為其添加主機變量以便於在playbook中使用,如下所示

    [websers]
    192.168.0.128 http_port=80 maxRequestsPerChild=808
    192.168.0.218 http_port=81 maxRequestsPerChild=909
    

        2.2)主機組變量,組變量是指定賦予給指定組內所有主機上的在playbook中可使用的變量,如下所示

    [websers]
    192.168.0.128 http_port=80 
    192.168.0.218 http_port=81 
    [websers:vars]
    maxRequestsPerChild=909

      3)通過命令行指定變量(-e指定變量賦值,可以說多個但需要用引號引起或者一個變量用一個-e指定賦值),這種在命令行指定的優先級最高。如下所示

    ansible-playbook -e 'package_name1=httpd package_name2=nginx' test_vars.yml

      4)在playbook中定義變量,最常見的定義變量的方法是使用vars代碼塊,如下所示

    ---
    - hosts: websers
      remote_user: root
      vars:
        - abc: xxx 
        - bcd: aaa  
    

      5)在獨立的變量yml文件中定義,在playbook中使用vars_files代碼塊引用其變量文件,如下所示

    [root@test ~]#cat vars.yml 
    ---
    package_name1: vsftpd
    package_name2: nginx
    [root@test ~]#cat test_vars.yml 
    ---
    - hosts: websers
      remote_user: root
      vars_files:
        - vars.yml
      tasks:
        - name: install package1
          yum: name={{ package_name1 }}
        - name: install package2
          yum: name={{ package_name2 }}
    [root@test ~]#

      6)在role中定義,這個後續說到角色在做解釋

      變量的調用方式:第一種在playbook中使用變量需要用“{{}}”將變量括起來,表示括號里的內容是一個變量,有時用“{{  variable_name }}”才生效;第二種是ansible-playbook -e 選項指定其變量,ansible-playbook -e “hosts=www user=xxxx” test.yml

      在主機清單中定義變量的方法雖然簡單直觀,但是當所需要定義的變量有很多時,並且被多台主機使用時,這種方法顯得非常麻煩,事實上ansible的官方手冊中也不建議我們把變量直接定義到hosts文件中;在執行ansible命令時,ansible會默認會從/etc/ansible/host_vars/和/etc/ansible/group_vars/兩個目錄下讀取變量定義文件,如果/etc/ansible/下沒有以上這兩個目錄,我們可以手動創建,並且可以在這兩個目錄下創建與hosts文件中的主機名或主機組同名的文件來定義變量。比如我們要給192.168.0.218 這個主機定義個變量文件,我們可以在/etc/ansible/host_vars/目錄下創建一個192.168.0.218的空白文件,然後在文件中以ymal語法來定義所需變量即可。如下所示

    [root@test ~]#tail -6 /etc/ansible/hosts 
    ## db-[99:101]-node.example.com
    [websers]
    192.168.0.128 
    192.168.0.218 
    [appsers]
    192.168.0.217
    [root@test ~]#cat /etc/ansible/host_vars/192.168.0.218 
    ---
    file1: abc
    file2: bcd
    [root@test ~]#cat test.yml 
    ---
    - hosts: 192.168.0.218
      remote_user: root
      
      tasks:
        - name: touch file1
          file: name={{ file1 }} state=touch
        - name: toch file2
          file: name={{ file2 }} state=touch
    [root@test ~]#ansible-playbook test.yml 
    
    PLAY [192.168.0.218] ************************************************************************************************
    
    TASK [Gathering Facts] **********************************************************************************************
    ok: [192.168.0.218]
    
    TASK [touch file1] **************************************************************************************************
    changed: [192.168.0.218]
    
    TASK [toch file2] ***************************************************************************************************
    changed: [192.168.0.218]
    
    PLAY RECAP **********************************************************************************************************
    192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   
    
    [root@test ~]#ansible 192.168.0.218 -m shell -a 'ls -l /root'
    192.168.0.218 | SUCCESS | rc=0 >>
    總用量 12
    -rw-r--r--. 1 root   root    0 11月 17 16:49 abc
    -rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
    drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
    drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
    -rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file
    
    [root@test ~]#
    

      說明:可看到我們定義在/etc/ansible/host_vars/下的主機變量文件中的變量生效了。

    同理,我們要想針對某個組的主機定義一些變量,我們只需要在/etc/ansible/group_vars/目錄下創建與主機清單中的主機組同名的文件即可。

      三、使用高階變量

      對於普通變量,例如由ansible命令行設定的,hosts文件中定義的以及playbook中定義的和變量文件中定義的,這些變量都被稱為普通變量或者叫簡單變量,我們可以在playbook中直接用雙大括號加變量名來讀取變量內容;除此以外ansible還有數組變量或者叫做列表變量,如下所示:

    [root@test ~]#cat vars.yml 
    ---
    packages_list:
      - vsftpd
      - nginx
    [root@test ~]#
    

      列表定義完成后我們要使用其中的變量可以列表名加下標的方式去訪問,有點類似shell腳本里的數組的使用,如下所示

    [root@test ~]#cat test.yml 
    ---
    - hosts: 192.168.0.218
      remote_user: root
      
      vars_files:
        - vars.yml
      tasks:
        - name: touch file
          file: name={{ packages_list[0] }} state=touch
        - name: mkdir dir
          file: name={{ packages_list[1] }} state=directory
    [root@test ~]#
    

      說明:我們要使用列表中的第一個元素變量,我們可以寫成vars_list[0],使用第二個變量則下標就是1,依此類推

    [root@test ~]#ansible *218 -m shell -a 'ls -l /root'
    192.168.0.218 | SUCCESS | rc=0 >>
    總用量 12
    -rw-r--r--. 1 root   root    0 11月 17 16:49 abc
    -rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
    drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
    drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
    -rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file
    
    [root@test ~]#ansible-playbook test.yml 
    
    PLAY [192.168.0.218] ************************************************************************************************
    
    TASK [Gathering Facts] **********************************************************************************************
    ok: [192.168.0.218]
    
    TASK [touch file] ***************************************************************************************************
    changed: [192.168.0.218]
    
    TASK [mkdir dir] ****************************************************************************************************
    changed: [192.168.0.218]
    
    PLAY RECAP **********************************************************************************************************
    192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   
    
    [root@test ~]#ansible *218 -m shell -a 'ls -l /root'
    192.168.0.218 | SUCCESS | rc=0 >>
    總用量 16
    -rw-r--r--. 1 root   root    0 11月 17 16:49 abc
    -rw-r--r--. 1 root   root    0 11月 17 16:49 bcd
    drwxr-xr-x. 2 root   root 4096 11月 17 17:23 nginx
    drwxr-xr-x. 2 qiuhom root 4096 11月 11 19:18 scripts
    drwxr-xr-x. 3 qiuhom root 4096 11月 11 19:28 test
    -rw-r--r--. 1 root   root   57 11月 13 19:15 test_cron_file
    -rw-r--r--. 1 root   root    0 11月 17 17:23 vsftpd
    
    [root@test ~]#
    

      說明:可看到我們創建的文件和目錄在目標主機已經生成

    上面的用法是典型的python列表的用法,在python中讀取列表中的元素就是用下標的表示來讀取相應的元素的值。接下我們將介紹另外一種更為複雜的變量,它類似python中的字典概念,但比字典的維度要高,更像是二維字典。ansible內置變量ansible_eth0就是這樣一種,它用來保存遠端主機上面eth0接口的信息,包括ip地址和子網掩碼等。如下所示

    [root@test ~]#cat test.yml     
    ---
    - hosts: 192.168.0.218
      remote_user: root
      
      tasks:
        - debug: var=ansible_eth0 
    [root@test ~]#ansible-playbook test.yml 
    
    PLAY [192.168.0.218] ************************************************************************************************
    
    TASK [Gathering Facts] **********************************************************************************************
    ok: [192.168.0.218]
    
    TASK [debug] ********************************************************************************************************
    ok: [192.168.0.218] => {
        "ansible_eth0": {
            "active": true, 
            "device": "eth0", 
            "features": {
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
                "highdma": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "off [fixed]", 
                "netns_local": "off [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_checksumming": "on", 
                "rx_vlan_filter": "on [fixed]", 
                "rx_vlan_offload": "on [fixed]", 
                "scatter_gather": "on", 
                "tcp_segmentation_offload": "on", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "on", 
                "tx_checksum_ipv4": "off", 
                "tx_checksum_ipv6": "off", 
                "tx_checksum_sctp": "off [fixed]", 
                "tx_checksum_unneeded": "off", 
                "tx_checksumming": "on", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_lockless": "off [fixed]", 
                "tx_scatter_gather": "on", 
                "tx_scatter_gather_fraglist": "off [fixed]", 
                "tx_tcp6_segmentation": "off", 
                "tx_tcp_ecn_segmentation": "off", 
                "tx_tcp_segmentation": "on", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "on [fixed]", 
                "udp_fragmentation_offload": "off [fixed]", 
                "vlan_challenged": "off [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "192.168.0.218", 
                "broadcast": "192.168.0.255", 
                "netmask": "255.255.255.0", 
                "network": "192.168.0.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::20c:29ff:fee8:f67b", 
                    "prefix": "64", 
                    "scope": "link"
                }
            ], 
            "macaddress": "00:0c:29:e8:f6:7b", 
            "module": "e1000", 
            "mtu": 1500, 
            "pciid": "0000:02:01.0", 
            "promisc": false, 
            "speed": 1000, 
            "timestamping": [
                "rx_software", 
                "software"
            ], 
            "type": "ether"
        }
    }
    
    PLAY RECAP **********************************************************************************************************
    192.168.0.218              : ok=2    changed=0    unreachable=0    failed=0   
    
    [root@test ~]#
    

      說明:以上playbook就實現了對ansible_eth0這個變量進行調試並打印,可以看到ansible_eth0是一個相對比較複雜的變量,裡面包含了字典,列表混合一起的一個大字典。

    我們可以看到ansible_eht0裡面包含了很多內容,我們要想讀取其中的IPV4地址,我們可以採用“.”或者下標的方式去訪問,如下所示

    [root@test ~]#cat test.yml 
    ---
    - hosts: 192.168.0.218
      remote_user: root
      
      tasks:
        - name: print ipv4  
          shell: echo {{ ansible_eth0["ipv4"]["address"] }} 
        - name: print mac
          shell: echo  {{ ansible_eth0.macaddress }}
    [root@test ~]#ansible-playbook test.yml -v
    Using /etc/ansible/ansible.cfg as config file
    
    PLAY [192.168.0.218] ************************************************************************************************
    
    TASK [Gathering Facts] **********************************************************************************************
    ok: [192.168.0.218]
    
    TASK [print ipv4] ***************************************************************************************************
    changed: [192.168.0.218] => {"changed": true, "cmd": "echo 192.168.0.218", "delta": "0:00:00.001680", "end": "2019-11-17 18:30:21.926368", "rc": 0, "start": "2019-11-17 18:30:21.924688", "stderr": "", "stderr_lines": [], "stdout": "192.168.0.218", "stdout_lines": ["192.168.0.218"]}
    
    TASK [print mac] ****************************************************************************************************
    changed: [192.168.0.218] => {"changed": true, "cmd": "echo 00:0c:29:e8:f6:7b", "delta": "0:00:00.001746", "end": "2019-11-17 18:30:22.650541", "rc": 0, "start": "2019-11-17 18:30:22.648795", "stderr": "", "stderr_lines": [], "stdout": "00:0c:29:e8:f6:7b", "stdout_lines": ["00:0c:29:e8:f6:7b"]}
    
    PLAY RECAP **********************************************************************************************************
    192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   
    
    [root@test ~]#

      說明:由此可以看出ansible多級變量的調用,使用中括號和點號都是可以的

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

    【其他文章推薦】

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

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

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

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

  • 『嗨威說』算法設計與分析 – PTA 程序存儲問題 / 刪數問題 / 最優合併問題(第四章上機實踐報告)

    『嗨威說』算法設計與分析 – PTA 程序存儲問題 / 刪數問題 / 最優合併問題(第四章上機實踐報告)

    本文索引目錄:

    一、PTA實驗報告題1 : 程序存儲問題

      1.1  實踐題目

      1.2  問題描述

      1.3  算法描述

      1.4  算法時間及空間複雜度分析

    二、PTA實驗報告題2 : 刪數問題

      2.1  實踐題目

      2.2  問題描述

      2.3  算法描述

      2.4  算法時間及空間複雜度分析

    三、PTA實驗報告題3 : 最優合併問題

      3.1  實踐題目

      3.2  問題描述

      3.3  算法描述

      3.4  算法時間及空間複雜度分析

    四、實驗心得體會(實踐收穫及疑惑)

     

     

    一、PTA實驗報告題1 : 程序存儲問題

      1.1  實踐題目:

     

      1.2  問題描述:

          題意是,題干給定磁盤總容量和各個文件的佔用空間,詢問該磁盤最多能裝幾個文件。

     

      1.3  算法描述:

          簽到題,只需要將各個文件從小到大排序,並拿一個變量存儲已佔用的容量總和,進行對比即可得到結果。

    #include<bits/stdc++.h>
    #include<algorithm>
    using namespace std;
    #define MAXLENGTH 1000
    int interger[MAXLENGTH];
    int main()
    {
        int num,length;
        int sum = 0;
        int counter = 0;
        int m = 0;
        cin>>num>>length;
        for(int i=0;i<num;i++){
            cin>>interger[i];
        }
        sort(interger,interger+num);
        while(true){
            if(sum+interger[m]>length||counter==num)
                break;
            sum+=interger[m];
            counter++;
            m++;
        }
        cout<<counter<<endl;
        return 0;
     } 

     

      1.4  算法時間及空間複雜度分析:

         整體算法上看,輸入需要O(n)的時間進行輸入,最快用O(nlogn)的時間複雜度進行排序,使用O(n)的時間進行結果疊加,總時間複雜度為O(nlogn),時間複雜度花費在排序上。

        空間上,只需要一個臨時變量存儲當前佔用容量總和即可。

     

     

    二、PTA實驗報告題2 : 刪數問題

      2.1  實踐題目:

     

      2.2  問題描述:

        第二題題意是指,在給定的数字串以及可刪數個數的條件下,刪數指定k個數,得到的數是最小的。

     

      2.3  算法描述:

        首先,分析題目,刪數問題,可以用一個比較方便的函數,String類的erase函數,這個函數可以刪除字符串內的單個或多個字符,可以比較方便的處理刪數問題。

        第二,我們注意到這道題有個坑點,那就是前導零,我們需要注意100000,刪除1后結果應為0

        第三,確定我們的貪心策略:噹噹前的數,比后一位數大時,刪去當前的數。

        如:樣例178543

        用一個index時刻從頭往後掃,不滿足就后移。

     

         當滿足之後,刪除當前的值。

     

        得到17543,這時將index重新置0,並記錄已刪數+1,直到滿足最大刪數。以此類推,直接輸出string便是結果。

        AC代碼:

    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    #define MAXLENGTH 1005
    int main(){
        int k;
        string a;
        cin>>a>>k;
        int len = a.size();
        while(k>0){
            for(int i = 0;(i<a.size()-1);i++){
                if(a[i]>a[i+1])
                {
                    a.erase(i,1);
                    break;
                }
            }
            k--;
        }
        while(a.size()>1&&a[0]=='0'){
            a.erase(0,1);
        }
        cout<<a<<endl;
        return 0;
    }

     

      2.4  算法時間及空間複雜度分析:

        時間複雜度為O(n^2),即開銷在不斷的刪數和回溯到字符串頭的過程。

        空間複雜度需要一個String字符串長度,因此空間複雜度是O(n)

     

     

    三、PTA實驗報告題3 : 最優合併問題

      3.1  實踐題目:

     

      3.2  問題描述:

        該題目為:題目用 2 路合併算法將這k 個序列合併成一個序列,並且合併 2 個長度分別為m和n的序列需要m+n-1 次比較,輸出某段合併的最大比較次數和最小比較次數。

     

      3.3  算法描述:

        這道題算是哈夫曼算法的一道裸題,很容易解決,只需要使用優秀隊列不斷維護最小值或最大值即可。

        哈夫曼樹:是一顆最優二叉樹。給定n個權值作為n個恭弘=叶 恭弘子的結點,構造一棵二叉樹,若樹的帶權路徑長度達到最小,這棵樹則被稱為哈夫曼樹。

        因此本題根據哈夫曼算法,我們以最小比較次數為例:

     

     

         首先從隊列中選出兩個最小的數進行合併,並在隊列中刪除這兩個數,並將新合成數加入隊列中。

     

     

         再取最小的兩個數再進行合併,以此類推,得到最終的大數如下

        因此最小比較次數為:( 7 – 1 ) + ( 18 – 1 ) + ( 30 – 1 ) =  52,即為所得。最大比較次數也是同理。

       AC代碼如下:

    #include<bits/stdc++.h>
    using namespace std;
    priority_queue<int> Haff;
    priority_queue<int, vector<int>, greater<int> > Haff2;
    int n,ans1,ans2;
    
    int main()
    {
        cin>>n;
        for(int i = 0;i<n;i++)
        {
            int temp;
            cin>>temp;
            Haff.push(temp);
            Haff2.push(temp);
        }
    
        while(1)
        {
            if(Haff.size() == 1)
                break;
            int temp1 = Haff.top();
            Haff.pop();
            int temp2 = Haff.top();
            Haff.pop();
            Haff.push(temp1+temp2);
            ans1 += temp1+temp2-1;
        }
        
        while(1)
        {
            if(Haff2.size() == 1)
                break;
            int temp1 = Haff2.top();
            Haff2.pop();
            int temp2 = Haff2.top();
            Haff2.pop();
            Haff2.push(temp1+temp2);
            ans2 += temp1+temp2-1;
        }
        cout<<ans1<<" "<<ans2;
        return 0;
     } 

     

      3.4  算法時間及空間複雜度分析:

        由分析易知,雖然進行了兩次優先隊列維護,但是總的時間複雜度數量級是不變的,用O(n/2)的時間pop和push合成樹。在優先隊列裏面用紅黑樹對順序進行維護,時間複雜度為O(nlogn),最後將統計的結果輸出,總的時間複雜度為O(nlogn)。

       空間複雜度為兩棵紅黑樹,即T(2n) = O(n)。

     

     

    四、實驗心得體會(實踐收穫及疑惑):

        經過動態規劃的肆虐之後,貪心算法變得稍微容易很多,和三木小哥哥的合作很愉快,能夠很好較快及時的解決三道實踐問題,暫無太多的問題,繼續加油。

     

     

    如有錯誤不當之處,煩請指正。

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

    【其他文章推薦】

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

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

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

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