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

傳統交通工具汽機車造成許多空氣污染與碳排放,許多廠商認為解決方案是電動車、電動機車,不過,也有人提出另一個想法,那就是何不更充分利用大眾運輸工具,只要解決捷運站到目的地的「最後一哩」交通需求即可鼓勵許多人不用自己開車、騎機車,而願意搭乘捷運。在 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實驗報告題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網頁設計已成為網頁設計推薦首選

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

BYD:電動車銷量目標連三年翻倍

比亞迪(BYD)董事長兼總裁王傳福在接受中國媒體《財新網》訪談時表示,BYD看好電動車市場的發展,未來三年的銷售目標是逐年倍增,且到2020年時,電動車將取代傳統汽車成為汽車銷售的主力。

去年全球電動車市場火熱,中國市場的銷量提升了三倍,躍升為全球最大電動車市場。BYD的電動車也跟著成長了三倍,產值來到人民幣(下同)220億元。BYD同時發展私家車、電動巴士、電動卡車與電動計程車等產品,屬多角化經營;目前,全球已有160餘座城市看得到BYD電動公車的身影,包含倫敦、阿姆斯特丹、洛杉磯、京都與50多個中國城市。

王傳福指出,特斯拉(Tesla)專注於生產高端私家電動汽車,此一路線與BYD的多角化經營有所不同,因此不會出現直接競爭。此外,BYD會逐步減少傳統汽車的投資比例,未來將逐漸轉為以電動車為主。

王傳福認為,北京政府對電動車的補助確實有助於銷售成長,但中國電動車市場已具一定的規模效應,生產成本會繼續下降。加上民眾對電動車的認同度持續上升,因此即使未來補貼逐漸減少,電動車的銷量也不會受到太大的衝擊。

據統計,BYD的電動車銷售量在2015年12月來到1.09萬輛,月增41.4%。全年銷量6.17萬輛,已超越Nissan、Tesla成為全球電動車銷售冠軍。其中以插電式油電混和車「秦」與「唐」的銷量貢獻最多,達86%;其餘銷量則來自純電動車。

(照片來源:BYD)

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

【其他文章推薦】

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

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

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

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

012.Kubernetes二進制部署worker節點Flannel

一 部署flannel

1.1 安裝flannel


kubernetes 要求集群內各節點(包括 master 節點)能通過 Pod 網段互聯互通。flannel 使用 vxlan 技術為各節點創建一個可以互通的 Pod 網絡,使用的端口為 UDP 8472。




flanneld 第一次啟動時,從 etcd 獲取配置的 Pod 網段信息,為本節點分配一個未使用的地址段,然後創建 flannedl.1 網絡接口(也可能是其它名稱,如 flannel1 等)。




flannel 將分配給自己的 Pod 網段信息寫入 /run/flannel/docker 文件,docker 後續使用這個文件中的環境變量設置 docker0 網橋,從而從這個地址段為本節點的所有 Pod 容器分配 IP。

更多flannel參考:《008.Docker Flannel+Etcd分佈式網絡部署》。

提示:k8smaster01節點已下載相應二進制,可直接分發至node節點。

1.2 分發flannel

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for node_ip in ${NODE_IPS[@]}
  4   do
  5     echo ">>> ${node_ip}"
  6     scp flannel/{flanneld,mk-docker-opts.sh} root@${node_ip}:/opt/k8s/bin/
  7     ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  8   done


1.3 創建flannel證書和密鑰


提示:k8smaster01節點已創建flanneld的CA證書請求文件,可直接分發至node節點。

1.4 分發證書和私鑰

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for node_ip in ${NODE_IPS[@]}
  4   do
  5     echo ">>> ${node_ip}"
  6     ssh root@${node_ip} "mkdir -p /etc/flanneld/cert"
  7     scp flanneld*.pem root@${node_ip}:/etc/flanneld/cert
  8   done


1.5 創建flanneld的systemd


提示:k8smaster01節點已創建創建flanneld的systemd,可直接分發至node節點。

1.6 分發flannel systemd

  1 [root@k8smaster01 ~]# cd /opt/k8s/work
  2 [root@k8smaster01 work]# source /opt/k8s/bin/environment.sh
  3 [root@k8smaster01 work]# for node_ip in ${NODE_IPS[@]}
  4   do
  5     echo ">>> ${node_ip}"
  6     scp flanneld.service root@${node_ip}:/etc/systemd/system/
  7   done


二 啟動並驗證

2.1 啟動flannel

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for node_ip in ${NODE_IPS[@]}
  3   do
  4     echo ">>> ${node_ip}"
  5     ssh root@${node_ip} "systemctl daemon-reload && systemctl enable flanneld && systemctl restart flanneld"
  6   done


2.2 檢查flannel啟動

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for node_ip in ${NODE_IPS[@]}
  3   do
  4     echo ">>> ${node_ip}"
  5     ssh root@${node_ip} "systemctl status flanneld|grep Active"
  6   done



2.3 檢查pod網段信息

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# etcdctl \
  3   --endpoints=${ETCD_ENDPOINTS} \
  4   --ca-file=/etc/kubernetes/cert/ca.pem \
  5   --cert-file=/etc/flanneld/cert/flanneld.pem \
  6   --key-file=/etc/flanneld/cert/flanneld-key.pem \
  7   get ${FLANNEL_ETCD_PREFIX}/config			#查看集群 Pod 網段(/16)



  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# etcdctl \
  3   --endpoints=${ETCD_ENDPOINTS} \
  4   --ca-file=/etc/kubernetes/cert/ca.pem \
  5   --cert-file=/etc/flanneld/cert/flanneld.pem \
  6   --key-file=/etc/flanneld/cert/flanneld-key.pem \
  7   ls ${FLANNEL_ETCD_PREFIX}/subnets			#查看已分配的 Pod 子網段列表(/24)
  8 [root@k8smaster01 ~]# etcdctl \
  9   --endpoints=${ETCD_ENDPOINTS} \
 10   --ca-file=/etc/kubernetes/cert/ca.pem \
 11   --cert-file=/etc/flanneld/cert/flanneld.pem \
 12   --key-file=/etc/flanneld/cert/flanneld-key.pem \
 13   get ${FLANNEL_ETCD_PREFIX}/subnets/172.30.8.0-21	#查看某一 Pod 網段對應的節點 IP 和 flannel 接口地址




解釋:

172.30.8.0/21 被分配給節點 k8snode02 (172.24.8.75);

VtepMAC 為 k8snode02 節點的 flannel.1 網卡 MAC 地址。

2.4 檢查flannel網絡信息

  1 [root@k8snode02 ~]# ip addr show



解釋:flannel.1 網卡的地址為分配的 Pod 子網段的第一個 IP(.0),且是 /32 的地址。

[root@k8smaster01 ~]# ip route show |grep flannel.1

172.30.8.0/21 via 172.30.8.0 dev flannel.1 onlink

172.30.128.0/21 via 172.30.128.0 dev flannel.1 onlink

172.30.208.0/21 via 172.30.208.0 dev flannel.1 onlink

172.30.216.0/21 via 172.30.216.0 dev flannel.1 onlink

解釋:

到其它節點 Pod 網段請求都被轉發到 flannel.1 網卡;

flanneld 根據 etcd 中子網段的信息,如 ${FLANNEL_ETCD_PREFIX}/subnets/172.30.32.0-21 ,來決定進請求發送給哪個節點的互聯 IP。

2.5 驗證各節點flannel


在各節點上部署 flannel 后,檢查是否創建了 flannel 接口(名稱可能為 flannel0、flannel.0、flannel.1 等):

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for all_ip in ${ALL_IPS[@]}
  3   do
  4     echo ">>> ${all_ip}"
  5     ssh ${all_ip} "/usr/sbin/ip addr show flannel.1|grep -w inet"
  6   done



輸出:








在各節點上 ping 所有 flannel 接口 IP,確保能通:

  1 [root@k8smaster01 ~]# source /opt/k8s/bin/environment.sh
  2 [root@k8smaster01 ~]# for all_ip in ${ALL_IPS[@]}
  3   do
  4     echo ">>> ${all_ip}"
  5     ssh ${all_ip} "ping -c 1 172.30.8.0"
  6     ssh ${all_ip} "ping -c 1 172.30.32.0"
  7     ssh ${all_ip} "ping -c 1 172.30.128.0"
  8     ssh ${all_ip} "ping -c 1 172.30.208.0"
  9     ssh ${all_ip} "ping -c 1 172.30.216.0"
 10   done


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

【其他文章推薦】

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

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

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

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

打破再生能源迷思 日本宮古島上的太陽能板超百搭

文:宋瑞文(加州能源特約撰述)

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

【其他文章推薦】

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

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

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

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

分析亞馬遜、澳洲、印尼大火 重點不在碳排放 而是地點與強度

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

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

【其他文章推薦】

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

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

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

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

奔馳計畫發力純電動汽車市場 推出電動車家族

據英國路透社報導,新一代奔馳E級車型實現半自動駕駛,將于底特律車展亮相,奔馳還計畫發力純電動汽車市場,推出電動車家族,與特斯拉一爭高下。

據悉,新一代奔馳E級車型有望通過升級軟體拓展自動駕駛領域,不僅將能夠在劃定高速公路路段和堵車路段完成更長距離的自動駕駛,還將延長“脫手操作”時間。此外,該車型具備駕駛員協助工具,包括系統自動匹配法定限速、高速公路駕駛導航和自動規避導航。

同時,韋伯表示,奔馳母公司戴勒姆集團正計畫生產新系列純電動豪華轎車。他表示,奔馳計畫增產電動汽車,以彌補插電式混合動力版轎車的不足,但電動汽車的結構設計將不僅僅限於轎車,而是“盡可能靈活”地適於豪華車型不同版本的發展,全新純電動汽車的時代即將到來。而純電動汽車的大量發售,將使奔馳需要更多的電池工廠。

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

【其他文章推薦】

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

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

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

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

大型網站的演化之路——讀《大型網站技術架構》

大型網站的演化之路——讀《大型網站技術架構》
____

author:姚毛毛的博客 & 妖生

01 大型網站or軟件有什麼特點?

高併發、大流量,微信都日活10億了
7×24的高可用,俗稱的4個9(99.99%)
海量數據的存儲與管理
全國甚至全球的用戶分佈,複雜網絡
安全環境很差
需求變更頻繁,需要快速迭代

最後,是漸進式的發展。
所有大型網站都是從一個小網站發展起來的。
好的網站與複雜的架構都是演化來的,而不是一開始就設計好的。
當年才出發的時候,誰也想不到微信可以日活十億,最初的時候肯定也沒有成千上萬的服務器集群對不對。

02 最初與第一次的演化之路:應用與數據的分離

我們最初的小型網站是什麼樣的?
從邏輯上看,一個應用服務、一個數據庫;從物理上看,一台服務器就搞定了。
在用戶量增多后,我們開始需要將應用跟數據庫分離。

那應用跟數據庫所需要的服務器配置是一樣的嗎?
當然是NO。
應用需要處理更多的業務邏輯,所以需要好一點多一點的CPU。
數據庫則要快速檢索磁盤跟放置數據緩存,因此需要快一點的磁盤和大一點的內存。

當然,所有演進的目的都是想更高、更快、更強。只是有時候沒法做到面面俱到,需要取捨。

03 第二次演進:緩存優化

恭喜你,網站優化了一次,體驗變好了,用戶也開始增多了,可是煩惱的又來了。
用戶的增多,帶來的數據庫壓力也大了,怎麼辦?

在IT行業甚至所有現實模型中都存在一個顛撲不破的真理,即二八原則。
在網站訪問上也是如此,80%的業務訪問總是集中在20%的數據上。
淘寶買東西就翻前面那麼一點,淘寶已經為我們找好了信用好、成交量高的賣家;百度一下也就是翻前面那兩三頁,甚至一頁里的前幾條(如果沒有廣告的話);微博熱搜吃瓜也就看前十吧,後面的你會一個個點過去嗎?

那麼,把這20%的數據緩存起來,是不是就可以減少數據庫的訪問壓力,提高網站訪問性能了?
YES。

那麼,怎麼緩存呢?
我們通常使用的緩存方案有兩種,即應用服務器上的本地緩存,和獨立的分佈式緩存。

有什麼優缺點?
本地緩存速度快些,但是受限於應用服務器的內存,且會導致與應用爭用的情況。
獨立的分佈式緩存可以使用集群,速度稍慢,但也很快,基本只有網絡IO的消耗;但是缺點就一個字:貴。因為需要購買獨立的緩存服務器。
所以在現實中,有時候,我們有時並不會購買獨立的緩存服務器,而是放在大內存的應用或數據庫服務器上,設置好閾值,共用內存。

04 第三次演進:應用集群與數據庫的集群和讀寫分離

哇,用了緩存后,訪問數據好快啊。
可是用戶又增多了,應用支撐不過來了怎麼辦?真是幸福的煩惱啊。
單台數據庫是不是有宕機的危險啊?

唉,集群唄。花錢就完事了。

應用集群、數據庫集群。

這也是我們當今的軟件架構中最常用的部署方案。

通過負責均衡調度器(nginx、F5等),可以將用戶請求通過輪詢或者IP指定的方式,分發到應用服務器集群中的任意一台服務器上,緩解應用壓力。
而數據庫以Oracle為例,則是可以在生產服務器上安裝RAC版本,而應用可以通過訪問數據庫的VIP(Virtual IP),或者JDBC集群訪問的方式訪問數據庫。
但是在網站的應用開發中,則一般選擇mysql的較多。雖然淘寶早期也是使用了Oracle,但是後期也轉mysql了。
至於為什麼?
呵呵,一個字,貴。兩個字,很貴。三個字,太貴了。

集群的好處有兩個:1、緩解服務壓力;2、高可用,其中一台壞了,另一台還可以繼續使用,給你恢復服務的機會。

一般軟件演化到這裏就完事了。

但是網站有個不一樣的地方,很多時候,都是讀多寫少。
點贊的、吃瓜的比上場評論的少很多對吧?

而讀多的情況雖然通過緩存配置消化了一部分,但還是有一部分讀操作(緩存未命中、緩存過期)和全部的寫操作會訪問數據庫。
所以在你的用戶量又迅猛增加到一定規模時,又是數據庫成為了我們的瓶頸。

目前大部分數據庫都是支持主從熱備功能的,主數據庫通過主從複製機制將數據更新同步到從數據庫。
此時我們的應用就可以建設專門的讀、寫數據庫的訪問模塊,使數據庫讀寫分離對應用透明。

有時我們甚至會將專門的查詢模塊剝離出來,成為另一個子系統。

05 不算演進的第四次演進:CDN與反向代理

為什麼要做CDN?
移動、電信、聯通……,華東、華南、西南、西北……,網絡環境複雜,每個地區訪問網站的速度都不太一樣。
CDN跟反向代理是加速訪問的一種手段,它們的基本原理都是緩存。
區別是CDN部署在網絡廠商的機房,反向代理是部署在網站機房。
CDN跟反向的目的都是儘早返回數據給用戶。

06 三國演義式的第五次演進:分佈式演進、業務的拆分與合併

分佈式數據庫是一種最後手段,只有在單表數據非常龐大的時候才使用。
很多網站和軟件根本用不到這一步,分佈式數據庫會帶來更麻煩的複雜性。
網站更常用的手段是拆分業務,拆分不同的業務應用,拆分不同的業務庫,部署在不同的物理服務器上。

這一招,在圍棋上,叫分治。在三國里,叫合久必分。

以商城網站為例,可以將首頁、店鋪、訂單、賣家、買家拆分不同的產品線,這其中不同的產品線又可以拆分多個應用,分歸不同的業務團隊管理。

應用之間可以通過首頁超鏈接建立關係,也可以通過消息隊列進行數據分發,當然,最多的還是訪問同一個數據存儲系統,來構成一個完整的系統。

這叫微服務。

隨着業務拆分越來越小,應用越來越複雜,其中又出現了一些可以共用的服務。如用戶管理、商品管理,那麼就可以將這些共用的業務提取出來,獨立部署。
用現在流行的話來說,叫業務中台。

在技術上,大家又造了各種各樣的輪子,解決的問題其實有很多共性。例如文件、圖片的處理、數據的存儲與搜索系統。
技術中台也有了。

在數據上,大家的系統因為拆分的愈來愈零碎,存儲到了不同的數據庫中,又形成了一個個數據孤島。把這些打通,做成數據倉庫,分析用戶畫像豈不美哉?優惠券推送、大數據殺熟了解一下。
而在技術上,隨着數據越來越多,數據存儲和檢索的技術需求也越來越高。所以我們又會引用一些非關係型的技術如NoSQL、搜索引擎等等。
最後,數據中台也有了。

所謂分久必合,新三國成型了。

歡迎關注我的公眾號:姚毛毛的博客

這裡有我的編程生涯感悟與總結,有Java、Linux、Oracle、mysql的相關技術,有工作中進行的架構設計實踐和讀書理論,有JVM、Linux、數據庫的性能調優,有……

有技術,有情懷,有溫度

歡迎關注我:姚毛毛& 妖生

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

【其他文章推薦】

※專營大陸空運台灣貨物推薦

台灣空運大陸一條龍服務

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

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

劇毒農藥賺很大 一年賣數十億美元 愈窮國家用愈兇

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

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

【其他文章推薦】

※專營大陸空運台灣貨物推薦

台灣空運大陸一條龍服務

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

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