日產傳退出EV電池生產業務、子公司AES賣中國GSR

朝日新聞22日報導,日產汽車(Nissan)將退出電動車(EV)用電池的生產業務,旗下車用電池生產子公司「Automotive Energy Supply(以下簡稱AES)」將出售給中國投資基金「GSR」,出售額預估為1,000億日圓,雙方預計會在今年夏天達成共識並對外發表。日產在退出EV電池生產業務後,會將資源集中在最先端電池的研發上。

報導指出,鋰離子電池是決定EV競爭力的關鍵,而日系廠商原先是該領域的霸主,不過近年來,南韓、中國廠商呈現顯著成長,加上AES銷售通路有限,因此日產研判擁有EV電池生產業務不具備太多好處。

AES為日產、NEC分別出資51%、49%於2007年設立的公司,主要生產日產電動車Leaf或油電混合車(HV)所需的鋰離子電池。

根據調查公司Techno Systems Research指出,2014年Panasonic車用鋰離子電池全球市佔率高達47%,而2015年雖維持首位、但市佔率萎縮至34%;反觀「其他廠商」市佔率從14%飆增至33%,而在「其他廠商」中、比亞迪(BYD)等中國廠商佔了大多數,LG化學、三星SDI等南韓廠商也在後猛追。

中國對電池市場虎視眈眈,成長最快的電池廠「寧德時代新能源科技股份」(簡稱寧德時代或CATL)已誓言要在2020年底前,使電池產量超越特斯拉(Tesla)、Panasonic合資的「Gigafactory」超大電池廠。

英國金融時報3月5日報導,北京已呼籲企業在2020年底前將車用電池產能拉高一倍,還鼓勵業者前往海外投資。高盛預估,鋰電池將是未來10年的關鍵技術,估計到了2025年市場總值上看400億美元、且主要會由中國主導。

寧德時代行銷主任Neil Yang預測,雖然超越日本、南韓業者並非易事,但預估未來10年內,全球只會剩下10家鋰電池製造商,其中60%的市場會由前三大業者拿下。他也透露寧德時代要將觸角探至全球的野心,聲稱該公司希望跟特斯拉合作,也一直在跟通用汽車(GM)接洽,而福斯(Volkswagen)、BMW則已都是他們的客戶。

寧德時代預計要在2020年將鋰電池總產能拉升至50GWh,而中國整體的鋰電池產能則合計會達121GWh。相較之下,特斯拉則希望在明(2018)年將鋰電池產能拉升至35GWh。每1個GWh的電力,可供應40,000輛電動車、每部行駛100公里所需。中國已在2013年超越南韓成為全世界最大的鋰電池供應國。

(本文內容由MoneyDJ授權使用。圖片出處:public domain CC0)

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

【其他文章推薦】

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

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

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

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

.NET資源泄露與處理方案

.NET雖然擁有強大易用的垃圾回收機制,但並不是因為這樣,你就可以對資源管理放任不管,其實在稍不注意的時候,可能就造成了資源泄露,甚至因此導致系統崩潰,到那時再來排查問題就已經是困難重重。

==========    ==========

一、知識點簡單介紹

常見的資源泄露有:

  • 內存泄漏:非託管資源沒有釋放、非靜態對象註冊了靜態實例。
  • GDI泄露:字體。
  • 句柄泄露:Socket或線程。
  • 用戶對象泄露:移除的對象未釋放。

二、具體實例

1. 內存泄漏

很常見的現象是分不清哪些對象需要釋放,對於控件、Stream等一些非託管資源也只管新增,卻沒有釋放,功能是實現了,卻埋了顆不小的雷。

private void button1_Click(object sender, EventArgs e)
{
    for(int i=0;i<1000;i++)
        this.Controls.Add(new TabPage());
}
private void button1_Click(object sender, EventArgs e)
{
    new Form2.ShowDialog();
}

如果你覺得寫這樣的代碼很Cool,很簡潔,你在項目中也有這麼寫代碼,那你就碰到大麻煩了,你試試在上面Form2中開個大一點的數組來檢查內存,然後運行,按幾下按鈕,你就會發現,內存一直增加,即使你調用了GC也無濟於事。所以,對於此類非託管資源要記住釋放,用完即廢可以採用using關鍵字。

public Form2()
{
    InitializeComponent();
    MyApp.FormChanged += FormChanged;
}

上面這個例子中,MyApp是一個靜態類,如果在實例對象中向這種類裏面註冊了事件,而又沒有取消註冊,這樣也會遇到大麻煩,即使在外部已經記得調用了Form2的Dispose也是沒用的。

解決方案

  • 注意託管資源和非託管資源的釋放區別,非託管資源是需要手動釋放的。
  • ,如上面的ShowDialog問題。(using中還起到了try-catch的作用,避免由於異常未調用Dispose的情況)
  • 使用UnLoad事件或者析構函數,對註冊的全局事件進行取消註冊。
  • 特別注意自定義組件的穩定性更重要,發生問題時影響也更廣。

2. GDI泄露

一般會跟字體相關,例如我曾在Android上用Cocos2d做一個小遊戲時頻繁地切換字體、Dev控件的Font屬性賦值也會有這種現象。

XXX.Font = new Font(...)

解決方案

  • 這個問題我目前是採用字體池來解決,類似線程池的概念,相同Key值取同一個對象。若有更好方案歡迎留言討論

3. 句柄泄露

一般跟Socket和Thread(線程)有關

for(int i=0;i<1000;i++){
    new Thread(()=>{
        Thread.Sleep(1000);
    }).Start();
}

解決方案

  • Socket的場景暫時沒遇到。
  • 線程問題採用線程池相關的輔助類能有效解決,例如ThreadPool、Task、Parallel。

4. 用戶對象泄露

一般跟移除的對象未釋放有關

private void button1_Click(object sender, EventArgs e)
{
    tab.Remove(tabPage);
}

三、最後特別奉送一個內存釋放的大招

[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
/// <summary>    
/// 釋放內存    
/// </summary>    
public static void ClearMemory()
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
    {
        SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
    }
}

調用以上API能讓你的內存一下爆減,是不是很給力,一調用內存就降下來了。But,先別高興太早,這其實是偽釋放,只是暫時解決內存大量泄漏導致系統崩潰的應急處理方案。具體原因參考:,關鍵信息:物理內存轉虛擬內存,涉及磁盤讀寫。好處壞處都貼出來了,是否需要使用請君自己斟酌。

四、總結

實際上由於各個開發人員的水平跟接觸面不同,又沒有經過統一的培訓(各個人對資源釋放的理解與關注度不同,或者寫代碼時就沒考慮內存未被釋放這種問題),發現問題的時候項目往往已經做到了一個階段,系統也比較龐大了,這種時候才發現內存泄露的問題確實是很頭疼的。

  • 資源泄露的場景往往是相互關聯的,發生最多的就是內存泄漏,而除了寫法可能有問題外,也可能是因為句柄泄露或用戶對象泄露引起的。

五、參考資料

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

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

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

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

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

023.掌握Pod-Pod擴容和縮容

一 Pod的擴容和縮容

Kubernetes對Pod的擴縮容操作提供了手動和自動兩種模式,手動模式通過執行kubectl scale命令或通過RESTful API對一個Deployment/RC進行Pod副本數量的設置。自動模式則需要用戶根據某個性能指標或者自定義業務指標,並指定Pod副本數量的範圍,系統將自動在這個範圍內根據性能指標的變化進行調整。

1.1 手動縮容和擴容

  1 [root@uk8s-m-01 study]# vi nginx-deployment.yaml
  2 apiVersion: apps/v1beta1
  3 kind: Deployment
  4 metadata:
  5   name: nginx-deployment
  6 spec:
  7   replicas: 3
  8   template:
  9     metadata:
 10       labels:
 11         app: nginx
 12     spec:
 13       containers:
 14       - name: nginx
 15         image: nginx:1.7.9
 16         ports:
 17         - containerPort: 80
  1 [root@uk8s-m-01 study]# kubectl create -f nginx-deployment.yaml
  2 [root@uk8s-m-01 study]# kubectl scale deployment nginx-deployment --replicas=5	#擴容至5個
  3 [root@uk8s-m-01 study]# kubectl get pods	                                	#查看擴容后的Pod

  1 [root@uk8s-m-01 study]# kubectl scale deployment nginx-deployment --replicas=2	#縮容至2個
  2 [root@uk8s-m-01 study]# kubectl get pods

1.2 自動擴容機制

Kubernetes使用Horizontal Pod Autoscaler(HPA)的控制器實現基於CPU使用率進行自動Pod擴縮容的功能。HPA控制器基於Master的kube-controller-manager服務啟動參數–horizontal-pod-autoscaler-sync-period定義的探測周期(默認值為15s),周期性地監測目標Pod的資源性能指標,並與HPA資源對象中的擴縮容條件進行對比,在滿足條件時對Pod副本數量進行調整。

  • HPA原理

Kubernetes中的某個Metrics Server(Heapster或自定義MetricsServer)持續採集所有Pod副本的指標數據。HPA控制器通過Metrics Server的API(Heapster的API或聚合API)獲取這些數據,基於用戶定義的擴縮容規則進行計算,得到目標Pod副本數量。
當目標Pod副本數量與當前副本數量不同時,HPA控制器就向Pod的副本控制器(Deployment、RC或ReplicaSet)發起scale操作,調整Pod的副本數量,完成擴縮容操作。

  • HPA指標類型

Master的kube-controller-manager服務持續監測目標Pod的某種性能指標,以計算是否需要調整副本數量。目前Kubernetes支持的指標類型如下:
Pod資源使用率:Pod級別的性能指標,通常是一個比率值,例如CPU使用率。
Pod自定義指標:Pod級別的性能指標,通常是一個數值,例如接收的請求數量。
Object自定義指標或外部自定義指標:通常是一個數值,需要容器應用以某種方式提供,例如通過HTTP URL“/metrics”提供,或者使用外部服務提供的指標採集URL。
Metrics Server將採集到的Pod性能指標數據通過聚合API(Aggregated API) 如metrics.k8s.io、 custom.metrics.k8s.io和external.metrics.k8s.io提供給HPA控制器進行查詢。

  • 擴縮容算法

Autoscaler控制器從聚合API獲取到Pod性能指標數據之後,基於下面的算法計算出目標Pod副本數量,與當前運行的Pod副本數量進行對比,決定是否需要進行擴縮容操作:
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

即當前副本數 x(當前指標值/期望的指標值),將結果向上取整。
釋義:以CPU請求數量為例,如果用戶設置的期望指標值為100m,當前實際使用的指標值為200m,則計算得到期望的Pod副本數量應為兩個(200/100=2)。如果設置的期望指標值為50m,計算結果為0.5,則向上取整值為1, 得到目標Pod副本數量應為1個。
注意:當計算結果與1非常接近時,可以設置一個容忍度讓系統不做擴縮容操作。容忍度通過kube-controller-manager服務的啟動參數–horizontalpod-autoscaler-tolerance進行設置,默認值為0.1(即10%),表示基於上述算法得到的結果在[-10%-+10%]區間內,即[0.9-1.1],控制器都不會進行擴縮容操作
也可以將期望指標值(desiredMetricValue)設置為指標的平均值類型,例如targetAverageValue或targetAverageUtilization,此時當前指標值(currentMetricValue) 的算法為所有Pod副本當前指標值的總和除以Pod副本數量得到的平均值。
此外,存在幾種Pod異常的如下情況:

  • Pod正在被刪除(設置了刪除時間戳):將不會計入目標Pod副本數量。
  • Pod的當前指標值無法獲得:本次探測不會將這個Pod納入目標Pod副本數量,後續的探測會被重新納入計算範圍。
  • 如果指標類型是CPU使用率,則對於正在啟動但是還未達到Ready狀態的Pod,也暫時不會納入目標副本數量範圍。

提示:可以通過kubecontroller-manager服務的啟動參數–horizontal-pod-autoscaler-initialreadiness-delay設置首次探測Pod是否Ready的延時時間,默認值為30s。

另一個啟動參數–horizontal-pod-autoscaler-cpuinitialization-period設置首次採集Pod的CPU使用率的延時時間。
當存在缺失指標的Pod時,系統將更保守地重新計算平均值。系統會假設這些Pod在需要縮容(Scale Down) 時消耗了期望指標值的100%,在需要擴容(Scale Up)時消耗了期望指標值的0%,這樣可以抑制潛在的擴縮容操作。
此外,如果存在未達到Ready狀態的Pod,並且系統原本會在不考慮缺失指標或NotReady的Pod情況下進行擴展,則系統仍然會保守地假設這些Pod消耗期望指標值的0%,從而進一步抑制擴容操作。如果在HorizontalPodAutoscaler中設置了多個指標,系統就會對每個指標都執行上面的算法,在全部結果中以期望副本數的最大值為最終結果。如果這些指標中的任意一個都無法轉換為期望的副本數(例如無法獲取指標的值),系統就會跳過擴縮容操作。
最後, 在HPA控制器執行擴縮容操作之前,系統會記錄擴縮容建議信息(Scale Recommendation)。控制器會在操作時間窗口(時間範圍可以配置)中考慮所有的建議信息,並從中選擇得分最高的建議。這個值可通過kube-controller-manager服務的啟動參數–horizontal-podautoscaler-downscale-stabilization-window進行配置,默認值為5min。這個配置可以讓系統更為平滑地進行縮容操作,從而消除短時間內指標值快速波動產生的影響。

1.3 HorizontalPodAutoscaler

Kubernetes將HorizontalPodAutoscaler資源對象提供給用戶來定義擴縮容的規則。
HorizontalPodAutoscaler資源對象處於Kubernetes的API組“autoscaling”中, 目前包括v1和v2兩個版本。 其中autoscaling/v1僅支持基於CPU使用率的自動擴縮容, autoscaling/v2則用於支持基於任意指標的自動擴縮容配置, 包括基於資源使用率、 Pod指標、 其他指標等類型的指標數據。
示例1:基於autoscaling/v1版本的HorizontalPodAutoscaler配置,僅可以設置CPU使用率。

  1 [root@uk8s-m-01 study]# vi php-apache-autoscaling-v1.yaml
  2 apiVersion: autoscaling/v1
  3 kind: HorizontalPodAutoscaler
  4 metadata:
  5   name: php-apache
  6 spec:
  7   scaleTargetRef:
  8     apiVersion: apps/v1
  9     kind: Deployment
 10     name: php-apache
 11   minReplicas: 1
 12   maxReplicas: 10
 13   targetCPUUtilizationPercentage: 50


釋義:
scaleTargetRef:目標作用對象,可以是Deployment、ReplicationController或ReplicaSet。
targetCPUUtilizationPercentage:期望每個Pod的CPU使用率都為50%,該使用率基於Pod設置的CPU Request值進行計算,例如該值為200m,那麼系統將維持Pod的實際CPU使用值為100m。
minReplicas和maxReplicas:Pod副本數量的最小值和最大值,系統將在這個範圍內進行自動擴縮容操作, 並維持每個Pod的CPU使用率為50%。
為了使用autoscaling/v1版本的HorizontalPodAutoscaler,需要預先安裝Heapster組件或Metrics Server,用於採集Pod的CPU使用率。
示例2:基於autoscaling/v2beta2的HorizontalPodAutoscaler配置。

  1 [root@uk8s-m-01 study]# vi php-apache-autoscaling-v2.yaml
  2 apiVersion: autoscaling/v2beta2
  3 kind: HorizontalPodAutoscaler
  4 metadata:
  5   name: php-apache
  6 spec:
  7   scaleTargetRef:
  8     apiVersion: apps/v1
  9     kind: Deployment
 10     name: php-apache
 11   minReplicas: 1
 12   maxReplicas: 10
 13   metrics:
 14   - type: Resource
 15     resource:
 16       name: cpu
 17       target:
 18         type: Utilization
 19         averageUtilization: 50


釋義:
scaleTargetRef:目標作用對象,可以是Deployment、ReplicationController或ReplicaSet。
minReplicas和maxReplicas:Pod副本數量的最小值和最大值,系統將在這個範圍內進行自動擴縮容操作, 並維持每個Pod的CPU使用率為50%。
metrics:目標指標值。在metrics中通過參數type定義指標的類型;通過參數target定義相應的指標目標值,系統將在指標數據達到目標值時(考慮容忍度的區間)觸發擴縮容操作。

  • metrics中的type(指標類型)設置為以下幾種:
    • Resource:基於資源的指標值,可以設置的資源為CPU和內存。
    • Pods:基於Pod的指標,系統將對全部Pod副本的指標值進行平均值計算。
    • Object:基於某種資源對象(如Ingress)的指標或應用系統的任意自定義指標。

Resource類型的指標可以設置CPU和內存。對於CPU使用率,在target參數中設置averageUtilization定義目標平均CPU使用率。對於內存資源,在target參數中設置AverageValue定義目標平均內存使用值。指標數據可以通過API“metrics.k8s.io”進行查詢,要求預先啟動Metrics Server服務。
Pods類型和Object類型都屬於自定義指標類型,指標的數據通常需要搭建自定義Metrics Server和監控工具進行採集和處理。指標數據可以通過API“custom.metrics.k8s.io”進行查詢,要求預先啟動自定義Metrics Server服務。
類型為Pods的指標數據來源於Pod對象本身, 其target指標類型只能使用AverageValue,示例:

  1  metrics:
  2   - type: Pods
  3     pods:
  4       metrics:
  5         name: packets-per-second
  6       target:
  7         type: AverageValue
  8         averageValue: 1k

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

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

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

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

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

《軟件方法(上)》讀書筆記

1、建模

1.1、業務建模之願景

重點1:通俗一點講,一個東西的願景就是:東西最應該賣個誰,對他有什麼好處?

重點2:願景是需求排序的主要依據。

重點3:老大、願景、需求都是基於現狀尋找最值得的改進。改進過後,又是新的現狀了,還是基於現狀尋找最值得的改進。進一步說也可以說,需求只有真假對錯,沒有變化。說需求有變化,那是從一個靜止時間點來看的。

1.1.1、願景




建模之願景

1.2、業務建模之業務用例圖

有了願景,我們知道老大對他所代表的組織的現狀的某些指標不滿意。接下來就可以研究組織,弄清楚到底是組織的哪些環節造成了這些指標比較差,這就是業務建模(Business modeling)的主要內容。

重點1:軟件系統只是組織的一個零件。組織裏面還有很多系統,其中最值錢的是千百年來一直在使用,現在依然是最複雜的系統——人腦系統。

重點2:開發團隊發現需求“容易變化”。根源之一是需求的來路不正,沒有把系統當作一個零件放在組織中來看,靠拍腦袋得出需求,導致得到的系統需求是錯的。

1.2.1、業務角色

① 業務執行者

以某組織為研究對象,在組織之外和組織交互的其他組織(人群或機構)就是該組織的執行者。以一家商業銀行為研究對象,觀察在它邊界之外和它打交道的人群或機構,可以看到儲戶來存錢,企業來貸款,人民銀行要它作監督等等,這些就是該商業銀行的執行者,如下圖所示:




業務執行者(一)

這裏要注意的是,作為觀察者的建模人員本身是一個人腦系統,所以在觀察組織邊界時,直覺上觀察到的不是組織之間的交互,而是組織派出的系統之間的交互,但是一定要把它理解成組織間的交互,因為談論業務執行者時,研究對象是組織,所以外部對應物——業務執行者也應該是組織。例如:以某國稅局為研究對象,可以觀察到企業財務人員到國稅局報稅,但業務執行者不是企業財務人員,而是企業。也許到後來,企業財務人員和國稅系統交互,又或許再後來是企業系統與國稅系統交互,從組織的抽象級別來看,都應該理解為企業和國稅局這兩個機構之間的交互,如下圖所示:




業務執行者(二)

② 業務工人

組織內的人稱為業務工人,例如某商業銀行裏面的營業員。業務工人是可以被替換的人腦零件,它可能被其他業務工人替換,但更有可能被業務實體替換。

③ 業務實體

業務實體是組織中的非人智能系統,例如銀行的ATM、點鈔機、營業系統。

1.2.2、識別業務用例

重點1:業務用例指業務執行者希望通過和所研究組織交互獲得的價值。業務用例是組織的價值,不會因為某個人腦系統或電腦系統的存在或消失而改變,好比如300年前的商業銀行和當前的銀行的業務用例是不變的,因為銀行提供價值的本質沒有改變。所以“這個系統的業務用例是什麼”這樣的說法是錯誤的。

重點1:用好用例,關鍵在於理解“價值”。價值是期望和承諾的平衡點、買賣的平衡點。例如以“醫院”為研究對象,真正的用例是“患者→看病”,而不是“患者→挂號”,患者→挂號”可以是以“挂號室”為研究對象的業務用例(如下圖)。所以做任何事情之前,要搞清楚“邊界”,沒有邊界會很容易盲目“拍腦袋”做一些努力但沒效果的事情。




業務用例識別

1.2.2.1、識別業務用例思路

識別業務用例的思路有兩條:

【從外到內】從業務執行者開始考慮,思考業務執行者和組織交互的目的(主要);

【從內到外】通過觀察組織的內部活動,一直問為什麼,向外推導出組織外部的某個業務執行者(補漏)。




業務用例識別思路

1.2.2.1.1、識別業務用例常犯錯誤

錯誤1 :把業務工人的行為當做業務用例。




錯誤用例識別(1)

錯誤2:業務用例隨待引入系統伸縮。




錯誤用例識別(2)

錯誤3:把害怕遺漏掉的擴展路徑片段提升為業務用例。




錯誤用例識別(3)

錯誤4:管理型業務用例。




錯誤用例識別(4)

總結:錯誤的根源主要源於:建模人員分不清問題和問題的解決方案。

1.3、業務建模之業務序列圖

1.3.1、描述業務流程的手段

本章節主要討論的是業務建模中最繁重的工作——描述業務用例的實現,即業務流程,然後改進它,推導出待引入系統的用例。目前描述業務流程的可選擇手段有文本、活動圖和序列圖,它們的主要區別如下(以財務部“員工→報銷”用例的實現為樣例):

● 文本




文本樣例

文本的缺點是不夠生動,所以在描述業務流程時很少使用文本方式。不過,描述系統用例(即系統需求)的流程時,文本是常用的,因為此時更注重精確,而且還要表達業務規則、性能等目前尚未被UML標準覆蓋的內容。

● 活動圖




活動圖樣例

序列圖是UML圖形描述業務流程的兩種選擇之一。活動圖的前身是流程圖,應該是在建模人員中使用頻率最高的圖形,是隨机械工程領域慢慢引入到計算機領域。不過,隨着編程語言表達能力越來越強,針對簡單的分支或循環邏輯畫圖在很多情況下已經變得沒有必要。

● 序列圖




序列圖樣例

序列圖與活動圖的比較如下:

1)活動圖只關注人,序列圖把人當作系統;

在上一章節中已經提到,現在的業務流程中已經有很多領域邏輯是封裝在業務實體而不是業務工人中,如果忽略非人智能系統,很多重要信息就丟掉了。

2)活動圖表示動作,序列圖強迫思考動作背後的目的;

序列圖可以更加清晰地表述業務工人或業務實體對外的責任,也就是用例的期望值。期望和承諾是用例和對象技術的關鍵思想,使用序列圖來做業務建模,“對象協作以完成用例”的思想就可以統一地慣竊業務建模和系統建模的始終。

3)活動圖“靈活”,序列圖“不靈活”;

不少人認為活動圖勝過序列圖的地方是它靈活,但這靈活是一把雙刃劍。活動圖很靈活,他的控制箭頭可以指向任何地方,就像編碼原始時代的“goto”語句,所以活動圖很容易畫。不過,“很容易畫”的活動圖也比較容易掩蓋建模人員對業務流程認識不足或者業務流程本身存在缺陷的事實。序列圖可通過alt、loop等結構化控製片段來描述業務流程,強迫建模人員用這種方式思考。

1.3.2、業務序列圖要點

1.3.2.1、消息代表責任分配而不是數據流動

序列圖中最重要的要點是消息的含義。A指向B的消息,代表“A請求B做某事”,或者“A調用B做某事的服務”,而“做某事”是B的一個責任。




序列圖消息含義

1.3.2.2、抽象級別是系統之間的協作

業務建模的研究對象是組織,出現在業務序列圖生命線上的對象,其最小顆粒是系統,包括人和非人系統,而系統之間最主要突出的是協作。所以“系統粒度”和“協作”是業務序列圖的關鍵要點,如果記住了這兩個關鍵點,就可以避免了對組織對象抽象的錯誤以及對協作理解的錯誤。




系統內部的組件暴露



表達了過細的交互步驟

以上說的兩種錯誤是把需求和分析的工作流的工作帶入了業務建模。第一樣例圖提到的系統內部的組件,應該在分析和設計工作流中描述;第二樣例圖提到了交互步驟,應該在需求工作流中描述。除了以上兩種抽象級別的錯誤,還有一種是:業務序列圖的內容和業務用例圖差不多,如下所示:




目標組織作為整體出現在業務序列圖中  

1.3.2.3、把時間看作特殊的業務實體

業務序列圖中,我們把時間看作特殊的業務實體。把時間看作上帝造好掛在天上的一個大鐘,向全世界各種系統發送時間消息,這樣,就和後面需要工作流中映射系統用例的時間執行者一致了,同時也幫助理清什麼情況下使用時間執行者的問題。




把時間當作一個系統

值得注意的一點是,時間和定時器不是一個概念,時間是“外系統”,定時器是其他系統用來和時間打交道的“邊界類”。世界上只有一個時間系統,但有無數的定時器。如果建模人員在識別系統用例時說“執行者是定時器”,那就錯了,執行者是時間。




時間和定時器的區別

1.3.2.4、為業務對象分配合適的責任

分配給業務對象的責任必須是該對象有能力承擔的,這需要我們自身必須對理解要十分清晰,畢竟我們自己說話有時候的會含糊。例如“工作人員用Word寫標書”這樣的說法好像可以接受,但如果按照說話的文字不假思索地隨便畫,會很容易導致對象責任分配不準確。




不恰當與不恰當的責任分配對比

1.3.3、現狀業務序列圖

業務序列圖描述的是業務流程,建模需要通過在現狀的業務序列圖基礎上找出改進的要點。如果要把現狀序列圖畫出來,就必須讓自己站在客觀的角度“親臨現場”,“如實”地把所看到的記錄下來,儘力描繪出真實的現狀。但說起來非常簡單,做到卻極其困難。總結到這裏,忽然讓我想起了彼得·德魯克。下面列出一些描述現狀時經常犯的錯誤。

1)錯誤:把想象中的改進當成現狀

很多時候造成這種錯誤,背後的原因很可能是根本沒有深入到組織流程中去做觀察和訪談,對現狀沒有認識,只好想像一個改進后的場景來應付。

2)錯誤:把“現狀”誤解為“純手工”

有的建模人員以為人做的事情才是本質,所以他畫的業務流程中,只有人,沒有非人系統,完全忽略了在技術進步下慢慢可以替代人的這些“業務實體”。

3)錯誤:把“現狀”誤解為“本開發團隊未參与之前”

開發團隊很容易會誤以為當他們開始參与組織流程完善而開發系統的時候當作“現狀”,這就是典型的“技術思維”,很多時候在開發團隊在參与組織流程完善前,組織已經經過了許多次“非系統級”的流程改進,這是站在組織角度去看問題的。

4)錯誤:把“現狀”誤解為“規範”

建模人員在建模業務流程時,照搬組織制定的規範,沒有去觀察實際工作中人們是如何做的,或者即使觀察到了人們實際沒有按照規範做,卻依然按照規範建模。這樣做,得到的業務流程是不真實的,畢竟上有政策,下有對策。

5)錯誤:“我是創新,沒有現狀”

互聯網創業公司的建模人員很容易犯的這個錯誤,動不動就說“我做的是互聯網創新,沒有現狀”,但他們已經忘記了歷史上所有的創新都是站在前輩這些巨人的肩膀之上這個事實。

6)錯誤:“我做產品,沒有現狀”

非定製系統的開發團隊進程拿這句話做接口。A公司的流程和B公司的流程有差異,中國的流程和外國的流程有差異,畫誰的現狀好的?問這個問題的時候,我想是開始開發團隊忘記了“做需求時把產品當項目做”的道理,在第2章節中也提到過“誰比誰更像”的重點。

1.3.4、改進業務序列圖

上面提到的現狀業務序列圖是對組織現狀的客觀描述,而改進業務序列圖是通過信息化手段去思考對業務現狀序列圖的一些改進。通常,信息化給人類的工作和生活帶來的改進有三種模式。

1.3.4.1、改進模式一:物流變成信息流

和信息的光電運輸比起來,用其他手段運輸的物的流轉速度就顯得太慢了,而且運輸成本會隨着距離的增加而明顯增加。如果同類物的不同實例之間可以相互取代,那麼可以提煉物中包含的部分或全部有價值的信息,在需要發生物流的地方,改為通過軟件系統交互信息,需要物的時候再將信息變成物,這樣就可以大大增加流轉速度和降低流轉成本。




物流變成信息流改進

1.3.4.2、改進模式二:改善信息流轉

軟件系統越來越多,而各個軟件系統之間溝通不暢,導致一個人為了達到某個目的可能需要和多個軟件系統打交道,如果把各軟件系統之間的協調工作改為一個軟件系統來完成,人只需要和單個軟件系統打交道,信息的流轉就改進了。




改善信息流轉

1.3.4.3、改進模式三:封裝領域邏輯

在業務流程中,有很多步驟是由人腦來判斷和計算的,領域邏輯封裝在人腦中。相對於計算機,人腦(業務人才)存在成本高,狀態不穩定、會徇私舞弊等問題。如果能夠提煉人腦中封裝的領域邏輯,改為封裝到軟件系統中,用軟件系統代替人腦,業務流程就得到了改進。換句話說,領域邏輯的封裝是對系統“內在”價值的提升,相對於前兩個改進模式有更高的要求和更大的困難。




封裝領域邏輯改進

1.3.4.4、改進思考方式:阿布爾思考法

在軟件開發團隊中,當有人提出新的想法時,經常會被馬上否定“太難了,做不了”,最終得到一個平庸的、毫無競爭力的系統。學會像阿布(俄羅斯大富豪羅曼·阿布拉莫維奇)一樣思考,有助於克服普通人因資源受限而不敢展開想象的思維障礙。阿布思考法分兩步:

1)假設有充足的資源去解決問題,得到一個完美的方案;

2)用手上現有的資源去山寨這個完美的方案。

其實,阿布思考法的核心思想就是,不要閉門造車,要“接地氣”的行動起來,主動去觀察,或主動尋找有用的信息去分析和調研,不要被各種局限被迫讓步。

2、需求

2.1、需求之系統用例圖

在“建模”階段我們研究和思考的對象是組織,從組織的整體性客觀地去發現組織如何可以通過信息化手段去優化流程。有了客觀的整體性分析和改進認知,接下來的“需求”階段需要深入到系統層面去思考了。按正常邏輯,每一步都有“承上啟下”的作用,本章節所研究的系統用例就是通過上一步業務序列圖中所映射出來的。

執行者和用例的概念在業務建模的學習中已經出現過,現在要研究的執行者和用例與業務建模時研究的執行者和用例相比,不同之處是研究對象,之前研究的是組織,現在研究的是系統。

2.1.1、系統執行者要點

系統執行者的定義:在所研究系統外,與該系統發生功能性交互的其他系統。

2.1.1.1、系統是能獨立對外提供服務的整體

封裝了自身的數據和行為,能獨立對外提供服務的東西才能稱為系統。不了解這點,建模人員很容易把“添加一些功能”當作“研發新系統”。




劃分系統用例

2.1.1.2、系統邊界是責任的邊界

系統執行者不是所研究系統的一部分,是該系統邊界外的另一個系統。這裏的系統邊界不是物理的邊界,而是責任的邊界。




錯誤的遙控軟件用例圖    



正確的遙控軟件用例圖

 

2.1.1.3、系統執行者和系統有交互

外系統必須和系統有交互,否則不能算是系統的執行者。如一名旅客來到火車站售票窗口,告訴售票員目的地和車次,售票員使用售票系統幫助旅客購買火車票,這個場景中,和火車票系統交互的是售票員,他是售票系統的執行者。




旅客不是售票系統的執行者

如果火車售票系統現在已經提供了旅客自行購票的接口,例如互聯網購票、售票機等,這種情況下,旅客也是售票系統的執行者。不過“售票員→售票”和“旅客→購票”是兩個不同的用例。

2.1.1.4、交互是功能性交互

上面說的交互還引出一個問題:假設售票員使用鼠標和售票系統交互,按道理,比起銷售員,鼠標里售票系統更近,為什麼不把鼠標作為售票系統的執行者呢?還有,假設售票系統運行在Windows操作系統之上,那麼Windows是不是售票系統的執行者?其實吧,辨別這些問題的要點就是:執行者和系統發生的交互是系統的功能需求。鼠標和操作系統跟售票系統的交互都不是售票系統的核心域概念。售票員和售票系統之間的交互才是,所以售票員才是售票系統的執行者。




售票系統的功能需求

2.1.1.5、系統執行者可以是人或非人系統

系統執行者可以是一個人腦系統,也可以是一個非人智能系統,甚至是一個特別的系統——時間。在軟件業的早期,一個系統的執行者往往全部都是人。隨着時間的推移,系統的執行者中非人執行者所佔的比例越來越多。用例的優勢在於“執行者”和“涉眾”的概念,把演員和觀眾分開。演員(執行者)在台上表演,觀眾(涉眾)在台下看,演員表演什麼是由觀眾的口味決定的,演員可以不是人,但觀眾肯定是人。演員如果是人類,那麼在觀眾席上也會有一個位置,不過在第幾排就不知道了(權重等級)。用例使用“執行者”和“涉眾”代替了原來的“用戶”是一個非常大的突破,建模人員如果過多地關注“用戶”,混淆了真正真正重要的前排“涉眾”的需求,把操作人員當前重要的調研對象(非關鍵人員),那麼花在重要的前排涉眾(關鍵人)身上的時間可能就不夠了。越來越多的系統執行者不是人類,也就是說沒有“用戶”。




從“執行者都是人”到“執行者有一些是人”

 

2.1.1、識別系統執行者

2.1.2.1、從業務序列圖映射系統執行者

如果沒有做業務建模,識別系統執行者只能靠頭腦風暴。例如:什麼人會使用系統來工作?什麼人負責維護系統?系統需要和哪些其他智能系統交互?有沒有定時引發的事件?等等問題。有了業務建模,可以直接從業務序列圖映射即可。業務序列圖上,和所研究系統有實線相連的對象映射為所研究系統的執行者。




業務序列圖:需找租客線索  



從業務序列圖映射得到系統執行者

 

2.1.3、系統用例要點

2.1.3.1、價值的買賣的平衡點

系統用例的定義:系統能夠為執行者提供的、涉眾可以接受的價值。和業務用例相比,研究對象從組織變成了系統,要理解好系統用例,重點依然是之前所強調的買賣平衡點、期望和承諾平衡點。

用例之前的許多需求方法學,把需求定義為思考系統“做什麼”,用例把需求提升到思考系統“賣什麼”的高度。這種思考是非常艱難的,因為它沒有標準答案,只有最佳答案。要得到這個答案,不能靠拍腦袋,必須揣摩涉眾。要得到合適的用例,需要有一顆善於提擦他人的心。




ATM和程序員人腦系統的用例

2.1.3.2、價值不等於可以這樣做

有些人會較真,還是以ATM為例子,有些人會因為“難道ATM放在那裡我就不能登錄一下就離開嗎?我今晚下班就去ATM那裡登錄一下給你看,然後走人。”ATM確實能登錄,但登錄功能並非ATM的賣點,如果以一個“門禁系統”為研究對象,登錄就可以作為它的用例。

還有一種情況,例如科員可以有A和B用例,科長因為比科員的權力大,所以就能擁有科員的用例。用例的執行者只是表明這個用例是為這一類執行者而做的。但不代表系統一定要有權限控制以防止其他的人或電腦系統使用該用例。即時系統確實需要有權限控制,而且角色的劃分和執行者相近,也要把這兩者分開,更不可以因為系統不設權限控制,所以把執行者的名字合併為“用戶”。




用例劃分案例

有些書中會給出“最佳粒度原則”。例如:一個系統的用例最好控制在XXX個之內,一個用例的基本路徑最好控制在X步到X步之間……這些是沒有根據的。市場需要各種各樣的系統,有功能眾多的,也有功能單一的,也有交付複雜的,應該把屁股坐到涉眾那邊去,揣摩涉眾的心裏,實事求是地寫下來。如果建模人員在粒度問題上激烈爭吵以及糾纏不清,有可能已經犯了錯誤,最常犯的錯誤是把步驟當作用例。




錯誤:把步驟當作用例

2.1.3.3、增刪改查用例的根源是從設計映射需求

有一些用例圖,映入眼帘的用例是四個四個一組的,仔細一看,剛好對應看數據庫的四種操作。相當於把數據庫的各個表名加上新增、刪除、修改、查詢,就得到了用例的名字。有些建模人員確實也知道這個錯誤,但他們學乖了,乾脆把每四個用例合併,改名叫“管理XX”或(“XX管理”),然後新增、刪除、修改、查詢等用例再擴展它,可惜依然是換湯不換藥。




從數據庫視角得到的用例

 

2.1.3.4、從設計映射需求錯誤二:“復用”用例

增刪改查用例實際上就是從設計映射需求,導致“復用”用例的一種情況。在看看以下例子:




“復用”用例錯誤示例——缺陷管理系統

從不同的業務序列圖分別映射得到系統有右邊四個用例,但有的建模人員會動起心思:這些實現起來不都是針對“缺陷”表來“select X X X from缺陷表where X X X”嗎,合併成一個用例“查詢缺陷”多好!於是得到左邊的結果。實際上,右邊這四個用例面對的執行者不同,背後的涉眾利益也有差別。

當然,如果真的像這位建模人員講的,把“數據庫”,買回去就好,想怎麼折騰這信息都可以那不是更加簡單。其實,用例是涉眾願意“購買”的、對系統的一種“用法”,只要涉眾願意“購買”,當然越多越好。講到這裏,就要來說一個需求的基本要點:需求不考慮“復用”,如果考慮“復用”,要警惕自己是不是已經轉換到了設計視角來思考問題。

2.1.3.5、系統用例不存在層次問題

系統用例的研究對象就是某特定系統,不是組織,也不是系統內部的組件。如果存在“層次”上的疑惑,背後的原因是研究對象不知不覺改變了。

像醫院信息系統的用例,有人會畫成如下圖所示,原因可能是前面沒有畫業務用例圖和業務序列圖,所以建模人員頭腦里不知不覺把醫院信息系統的價值和醫院的價值混在一起了。




錯誤的“高層”用例:混淆組織的價值和系統的價值

還有以下的防汛系統用例圖,把系統的願景當成了“高層”用例:




錯誤的“高層”用例:把願景當作用例

以下更為常見的錯誤,為系統的“模塊”或“子系統”畫用例圖:




錯誤:模塊的用例  



用例仍然是系統的用例    



錯誤:子系統的用例

2.1.3.6、用例的命名是動賓結構

用例的命名是動賓結構,例如“取現金”。動詞前面可以加狀語,賓語前面可以加定語,把一句話的主語砍掉,剩下的可以用作用例的名字。

給用例起名時不要使用弱動詞。用例之前的需求技術,可能是以“名詞+動詞”的形式命名系統的功能,例如“發票作廢”,後來要改成用例的動賓結構了,有的建模人員就在前面加一個弱動詞“進行”,就變成了“進行發票作廢”,這個也是不合適的。

如果“名詞+動詞”已經成為行業中的一個術語,也未必要嚴格的動賓結構,例如“成果分析”是某行業的一個術語,也就不必硬要倒過來變成“分析成果”了。

2.1.4、識別系統用例

2.1.4.1、從業務序列圖映射系統用例

其實,只要認真做好業務建模,從業務序列圖上映射系統用例,得到的結果自然就會符合上面說的這些要點。

從業務序列圖中,從外部指向所研究系統的消息,可以映射為該系統的用例。現在我們繼續從“識別系統執行者”的用例中結合執行者和系統用例一起識別。




從業務序列圖上找到從外部指向所研究系統的信息    



從業務序列圖映射得到系統用例

 

在以上業務序列圖中,有一處消息是“外呼人員”指向“線索管理系統”的消息為“提供本人當天名單”,但在以上系統用例圖中,用例名改為了“查看本人當天名單”。因為序列圖上的消息代表“請求某系統做某事”,用例代表“用某系統來做某事”,一定要理解兩種圖的要點,所以有的地方需要調整。

在以上系統用例圖中,有的箭頭是從執行者指向用例,這樣的執行者稱為用例的主執行者,有的箭頭是從用例指向執行者,這樣的執行者稱為用例的輔執行者。主執行者主動發起用例的交互,輔執行者在交互的過程中被動參与進來。

值得注意一下,輔執行者這個概念是被誤用的比較多。最常見的錯誤是把信息的接收者或者將來可能使用信息的人當成輔執行者。另一種輔執行者的誤用剛好相反,把信息的來源當作輔執行者。




錯誤:把可能會用到所生產信息的人當作輔執行者  



錯誤:把提供用例所需要信息的人當作輔執行者

以上錯誤的原因很多是因為前面沒有畫業務序列圖,導致建模人員在畫系統用例圖的時候產生焦慮,總是希望在圖上多放一些信息,以免自己忘記了。一般來說,輔執行者是非人智能系統的情況較多,人腦系統作為輔執行者的情況比較少,所以碰到輔執行者是人的時候,要多留心。




正確:合適的輔執行者(因為辦卡需要用戶輸入密碼)

 

2.2、需求之系統用例規約

用例圖表達了用例的目標,但是對於完整的需求來說,這是遠遠不夠的。用例的背後封裝了不同級別的相關需求,我們需要通過書寫用例規約把這些需求表達出來。用例規約就是以用例為核心來組織需求內容的需求規約。用例規約的各項內容可以通過以下類圖來展示:




用例規約的內容

2.2.1、前置條件和後置條件

用例通過前置條件(precondition)、後置條件(postcondition)以契約的形式表達需求。用例相當於系統的一個承諾:在滿足前置條件時開始,按照裏面的路徑步驟走,系統就能達到後置條件。為了避免掉入“從實現角度看這樣可以那樣也可以”的陷阱,後置條件只需要寫出最想要的那個狀態即可。

● 前置條件:用例開始前,系統需要滿足的約束。

● 後置條件:用例成功結束后,系統需要滿足的約束。

2.2.1.1、前置條件、後置條件必須是系統能檢測的




系統必須能檢測前置、後置條件

以上圖為例,“錄入保單”用例的前置條件是錯誤的。業務代表是否已經把保單交給內勤,系統無法檢測,不能作為前置條件;同樣,“收銀”用例的後置條件也是不對的。顧客是否已經帶着貨物離開商店,系統也無法檢測,不能作為後置條件。

2.2.1.2、前置條件必須是用例開始前系統能檢測的




前置條件必須是用例開始前系統能檢測的

 以上圖所示,儲戶開始取現金的交互前,系統不知道儲戶是誰,要去多少錢,所以無法檢測“儲戶賬戶里有足夠的金額”這個條件。如果把前置條件設置為類似於“存在大於最低限額的現金”這樣的背景條件作為前提條件是可以的。就算很長時間沒人來ATM取現金,這個條件是否成立就擺在那裡。

2.2.1.3、前置後置條件是狀態,不是動作

例如,“經理→批假”的前置條件不能寫“員工提交請假單”,因為是一個動作不是狀態,應改為“存在待審批的請假單”。特別要注意的是,寫成“員工已經提交請假單”很可能也是不對的,因為狀態和導致達到某個狀態的行為不是一一對應的,請假單未必是員工自己提交的,也可以組長負責幫本組人員請假,也可能是從另外的系統批量導入。

如果分不清狀態和行為的區別,建模就會遇到很大的麻煩。後面的建模工作中,還會不斷討論狀態和行為的問題。

2.2.1.4、前置後置條件要用核心域詞彙描述

“系統正常運行”、“網絡連接正常”等放之四海而皆準的約束,和所研究系統沒有特定關係,不需要在前置條件中寫出來,否則會得到一堆沒有任何增值作用的廢話。

後置條件也不能簡單地把用例的名字加上“成功”二字變成“XXX成功”。例如“顧客→下單”的後置條件寫成“顧客已經成功下單”,這不是廢話嗎?更合適的後置條件是“訂單信息已保存”。

2.2.1.5、“已登錄”不應作為前置條件

“已登錄”是一個比較有爭議的情況,以購物網站為研究對象,登錄不是用例。這一點已經在前面的已經學習過,那如何處理登錄?

1)畫法一:把其他用例作為“登錄”的擴展




畫法一:把其他用例作為“登錄”的擴展

 

會員登錄后可以下單,也可以查看以往訂單,還可以退貨……所以上圖這個方法把下單、查看以往訂單畫出登錄的擴展。這是錯的。並不是先做A然後做B或C,B和C就成了A的擴展。

2)畫法二:把“登錄”作為被包含用例




畫法二:把“登錄”作為被包含用例

把“登錄”變成被其他用例包含(Include)的被包含用例(Include Use Case)。這樣做是正確的。登錄用例本來不存在,後來在寫用例規約的時候,發現“下單”、“查看以往訂單”等用例都有以下步驟:




“查看以往訂單”步驟

為了節省書寫用例規約的工作量,考慮把這些形成一個小目標的步驟集合(不是單個步驟)分離出來,作為一個被包含用例單獨編寫規約。這個用例只被其他用例包含,不由主執行者指向。所以,如果按照這個做法的話,“下單”用例規約的步驟里,應該有表示包含“登錄”用例的步驟集合:會員【登錄】。這裏的“登錄”二字加了粗括號表示這是一個被包含用例。它的步驟和約束在另外的地方描述。當然,不喜歡用粗括號可以用下劃線等其他方法以示區分。

3)畫法三:其他用例以“已登錄”作為前置條件




畫法三:其他用例以“已登錄”作為前置條件

有些人覺得畫法二會讓好些用例會出現會員【登錄】,看起來有些礙眼,就想能不能把它提到前置條件里,那就得到了畫法三。把“登錄”作為一個用例,“會員已經登錄”作為其他用例的前置條件。這樣用例的步驟看起來更清爽,但是嚴格來說這也是不對的,“登錄”不能作為購物網站的用例。

以上章節學習過,如果在做需求時考慮復用,可能已經陷入了設計的思維。能夠在多個用例中復用登錄的狀態,這是設計人員的本事,他甚至可以做到10個用例的界面都從一個模板生成,但不能因此就把這10個用例合併成一個。

2.2.2、涉眾利益

前提條件是起點,後置條件是終點,中間的路該怎麼走?這就要由涉眾決定了。也就是我們需要對關鍵人按重要程度排序(從前排到後排)去考慮他們的利益,根據這些利益去梳理正確的需求。以銀行ATM為例子,儲戶在ATM取現金的時,涉及的涉眾利益如如下:

● 儲戶:希望方便;擔心權益受損。

● 銀行負責人:希望安全;希望節約運營成本。

正是這些涉眾利益的交鋒之下,目前我們日常生活中所看到的ATM的用例片段如下:




ATM用例片段

從步驟1有設計約束“通過磁條卡或芯片卡提交賬戶號碼”看,這是為了照顧儲戶“方便”的利益。在銀行角度,雖然儲戶是上帝,為了儲戶更加方便,不用密碼更方便的。但從銀行角度要考慮安全問題,不可能不設置密碼,但為什麼只設置6位而不是8位或者更多呢?這又是“安全”和“方便”交鋒后的妥協……

2.2.2.1、涉眾的來源

1)涉眾來源一:人類執行者

用例的執行者如果是人類,當然是用例的涉眾。執行者如果不是人類,就不是涉眾,因為它沒有利益主張。




考慮人類執行者之後的涉眾

上圖保險系統的“內勤→錄入保單”用例中,內勤是人類,是涉眾,而OA系統不是人類,不是涉眾。

2)涉眾來源二:上游

執行者要使用系統做某個用例,可能會需要一些資源,這些資源的提供者可能就是用例的涉眾。還是以“內勤→錄入保單”為例,保單由業務人員代表提供給內勤。如果內勤喝醉了酒亂錄,信息錯得一塌糊塗,業務代表的利益就被損害了。所以,考慮到上游之後,“內勤→錄入保單”用例的涉眾有內勤和業務代表了。




考慮上游之後的涉眾

3)涉眾來源三:下游

執行者使用系統做某個用例,產生的後果會影響到其他人。這些受影響的人也是涉眾。還是以“內勤→錄入保單”為例,如果系統做得不好,沒有檢測內勤錄保單時是否填了必填項就放了過去,後面負責審核的經理工作量增加了。還有,OA系統雖然不是該用例的涉眾,但假如保險系統不停地向OA系統發送垃圾數據包,導致OA癱瘓,那麼OA系統維護人員的工作量就增加了。所以,OA系統維護人員也是下游的涉眾。考慮下游之後,“內勤→錄入保單”用例的涉眾如下圖所示:




考慮下游之後的涉眾

 

4)涉眾來源四:信息的主人

用例會用到一些信息,這些信息會涉及某些人,雖然這些人也許並不知道這個系統的存在,但他們是用例的涉眾。還是以“內勤→錄入保單”為例,保單的信息涉及被保人,投保人和受益人,如果信息出錯或泄露,這些人就會遭殃,所以他們是涉眾。因為這類涉眾可能和系統沒什麼接口,比較容易被忽略,所以要特別需要注意。




考慮信息的主人之後的涉眾

其實,前面的業務建模對識別涉眾起到了非常大的幫助,如果做需求前做了業務建模,會更加了解一件事情的前因後果,大多數涉眾都能夠從業務序列圖中看出來。如下圖所示:




業務建模可以幫助尋找涉眾

 

2.2.2.2、尋找涉眾利益

查理·芒格說過:說服別人要訴諸利益,而非訴諸理性。所以要學會思考涉眾的利益點是一門非常大的學問。尋找涉眾利益時,要“親兄弟,明算賬”,把不同涉眾各自關注的利益體現出來,而不是寫成一模一樣的。家裡兩夫妻對同一件事情都還有不同立場,更不用說一個組織裏面形形色色的涉眾了。例如,司機開車進廠裝化肥,工作人員通過地磅系統操縱地磅給車稱重。針對這件事,不同的涉眾可謂是“各懷鬼胎”:

● 化肥公司老闆——擔心公司內部人員貪污;

● 地磅操作員——希望操作簡便;擔心承擔責任;擔心繫統壞掉影響工作量;

● 倉管人員——擔心稱不準導致無謂的返工裝包;

● 買主——擔心進去時稱得輕了,出來時稱得重了,導致給少了化肥;

● 司機——擔心等候時間太長導致每天拉貨次數減少;

即使有些利益有時不方便白紙黑字寫出來共享,但至少建模人員要心知肚明,不能一團和氣了事。建模人員要仔細觀察和揣摩涉眾的痛苦,才能找到真正的涉眾利益,否則寫出來的“涉眾利益”往往很蒼白。例如以下例子:

● 護士——擔心出錯

這都是正確的無用廢話,誰都擔心出錯,但為什麼還是出錯?仔細調研過之後寫出來就生動多了:

● 護士——擔心自己的藥理學知識記錯,對藥物名稱相近的藥物計算錯劑量,導致給葯錯誤;

2.2.2.3、善於積累涉眾利益

需求是不斷變化的,我想這都是共識了,新系統肯定在功能或性能上和舊系統有所不同,否則還做什麼新系統呢。但是,背後的涉眾利益要穩定得多。看看之前ATM的例子出現的涉眾利益:

儲戶——希望方便;擔心權益受損;

銀行負責人——希望安全;希望節約運營成本;

其實這些涉眾利益不止適用於ATM,也適用於清朝的錢莊櫃檯、現在的銀行櫃檯、網上銀行和手機銀行。換句話說,越本質越穩定。

2.2.3、基本路徑

一個用例會有多個場景,其中有一個場景描述了最成功的情況,執行者和系統的交互非常順利,一路綠燈直抵用例的後置條件。這個場景稱為基本路徑。用例把基本路徑分離出來,目的是凸顯用例的核心價值。還是以ATM為例,發生在ATM上的場景有很多:

1)張三來了,插卡,輸入密碼,輸入金額,順順利利取到錢,高興地走了;

2李四來了,插卡,輸密碼,密碼錯,在輸,再錯,再輸,卡被吞掉了;

3王五來了,插卡,輸密碼,輸金額,今天取得太多不能取了……

以上三個場景,只有場景(1)是銀行在大街上擺放一台ATM的初衷。雖然場景(2)和(3)是難以避免,但場景(1)出現得越多越好,這是涉眾對ATM的期望。

書寫路徑步驟的時候需要注意以下一些要點。這些要點有重疊的地方,如果違反了其中一個要點,很可能會違反另外的要點。

2.2.3.1、按照交互四步曲書寫

執行者和系統按回合交互,直到達成目的。需要的回合數是不定的,可能一個回合足夠,也可能需要多個回合。一個回合中的步驟分為四類:請求、驗證、改變、回應。如下圖所示:




交互四步曲

在一個回合中,請求是必須的,同時還需要其他三類步驟中的至少一類。看看以下例子,可以看到,第一個回合只需要請求和響應,第二個回合則四類步驟都有。




回合制的交互示例

當時間作為主執行者而且不需要和其他輔執行者交互的用例中,可能會出現不需要回應的情況,而且只有一個回合,如下所示:




回合制的交互示例

在書寫步驟時要注意以下一些形式上的問題:

1)對於時間為主執行者的用例,回合中的請求步驟不寫“時間告知時間周期到了”,而是寫“當到達時間周期時”。

2)驗證步驟不寫“是否”。例如以上例子中,第4步寫“系統驗證註冊信息充分”,不寫“系統驗證註冊信息是否充分”,目的是要表達“充分”是基本路徑期望的驗證結果。

3)系統和輔執行者之間的交互可以看作是一種回應步驟,寫成“系統請求輔助執行者做某事”,例如“系統請求郵件列表系統群發郵件”。

2.2.3.2、只寫系統能感知和承諾的內容

看看以下例子:

……

4、系統反饋應收總金額

5、顧客付款

6、收銀員提交付款方式和金額

7、系統計算找零金額

8、系統反饋找零金額,打印收據

9、收銀員找零

……

顧客付款和收銀員找零是系統無法感知和承諾的。如果寫在步驟里,會讓人產生誤解:只要用了本系統,顧客就會乖乖付款,收銀員會乖乖找零——也許顧客忘記付款和收銀員忘記找零正式商場要解決的一個頭痛問題。

2.2.3.3、使用主動語句理清責任

把動作的責任人放在主語的位置,看看以下兩句話:

1)伊布從瓦倫西亞處得到傳球,舒梅切爾撲救伊布的射門。

2瓦倫西亞傳球,伊布射門,舒梅切爾撲救。

雖然上面一句比較文藝,但下面一句把責任理得更清晰。用例步驟也是如此:

系統從會員處獲得用戶名和密碼(錯)

會員提交用戶名和密碼(對)

用戶名和密碼被驗證(錯)

系統驗證用戶名和密碼(對)

會員要是不提交,就不要怪系統沒有動靜;會員要是提交了,系統不動彈,那就要怪系統了。做到規規矩矩說話,把責任理清楚,其實不容易。再列舉一些常見的“胡說八道”,如下所示:




規矩用詞

2.2.3.4、主語只能是主執行者或系統

寫需求,就是要把系統當作一個黑箱,描述它對外提供的功能以及功能附帶的質量需求。系統如何構造,不屬於需求描述的範圍,除非是涉眾強加的設計約束。所以步驟里不能出現“執行者請求前端系統做某事,前端系統請求後端系統做某事”“執行者請求客戶端做某事,客戶端請求服務端做某事”“執行者請求A子系統做某事,A子系統請求B子系統做某事”,就算這個系統最終的組成是分解成很多個部分,分佈在一百多個國家運行,需求里也只有兩個字:系統。前面已經學習過了,系統邊界是責任邊界,而非物理邊界,如下所示:




需求把系統看作是黑箱

 

2.2.3.5、使用核心域術語描述

路徑步驟應該使用核心域的術語來描述,也就是說,要說“人話”。以下以一個零件採購系統為研究對象,比較以下兩句話,哪一句是“人話”,哪一句是“鳥語”?

1)系統建立連接,打開連接,執行SQL語句,從“零件”表查詢……

2系統根據查詢條件搜索零件

其實,一眼就能看出,第一句是“鳥語”,第二句是“人話”了。不同職能多少會有主觀意識,做Java開發的覺得自己做的才是技術,需求屬於業務。但需求人員卻覺得自己做的也是技術,他們所研究的客戶才是業務。但客戶覺得自己做的才是技術……,這咋看起來有點像一個鄙視鏈。其實,大家做的都是“技術”,這是領域不同而已。應該用“核心域”和“非核心域”來代替“業務”和“技術”。

如果所研究系統是一個關係數據庫的腳本工具,核心域是關係數據庫領域,上面提到的“系統建立連接,打開連接,執行SQL語句”就成了合適的需求。

2.2.3.6、不要涉及界面細節

很多人寫需求的時候,會把界面的細節帶進來,例如:

● 會員從下拉框中選擇類別

● 會員從文本框中輸入查詢條件

● 會員單擊“確定”按鈕

這些界面細節很可能不是需求,更多是設計方案,背後可能隱藏更多的真正需求,也許是可用性需求“操作次數不超過5次”。但畢竟我們面對的客戶各種各樣的喜好都有,可能有些前排涉眾明確要求“一定要用下拉框”,那麼“下拉框”也是需求,但依然不能寫“會員從下拉框框中選擇類別”。因為這裏涉及兩類需求,她們的穩定性和變化趨勢不同,應該分開描述:

● 會員選擇類別(這是步驟)

● 通過下拉框來實現(這是設計約束)

用例的需求組織方式是分層的,從用例的路徑、步驟、約束,穩定性會越來越低,如下所示:




用例規約的需求層級

把需求分層級了,穩定和不穩定的需求就分開了,更有利於了解事情的核心本質。平時遇到的大部分“需求變更”發生在補充約束級別,例如輸入會員信息時加個微信字段(字段列表變了),調整結賬時的打折規則(業務規則變了)。級別越高的需求,內容越穩定。

很多時候做需求會把看得見和需求混為一談,真正的需求不見得是顯而易見的。需求判斷的標準不是涉眾是否看得見,而是涉眾是否在意。第一章已經學習過,需求和設計不是一一對應的,而是多對多的。

2.2.3.7、不要涉及交互細節

在步驟中,除了避免描述頁面細節,還要避免描述交互細節。例如有人會這樣寫:

● 會員每輸入賬戶名稱的一個字符

● 系統在界面中驗證當前輸入信息合法

寫的人有他的道理:系統不是等待提交后才驗證輸入信息是否合法,而是隨時驗證立即反饋,這樣使用戶體驗更好。其實,這隻是交互設計的一些技能。忍不住要在需求規約里描述界面和交互的細節,背後的原因和忍不住要思考內部代碼如何實現的原因是一樣的,都是對自己的設計技能沒有信心,害怕“現在想到了如果不忘記記下來以後就忘記了”。這些都是人性的弱點。

用例的步驟應該把焦點放在系統必須接收什麼輸入、系統必須輸出什麼信息以及系統必須做什麼處理這三個重點上,加上字段列表、業務規則、可用性需求等約束,足以表達各種需求。

關於用例的交互怎麼寫,是一個比較頭疼的問題。即使不涉及交互設計細節的問題,也免不了混進交互設計的成分,例如,為什麼要分兩個回合而不是一個回合?實際上涉眾更希望一個回合就能達到用例的目標。所以,建議觀點是在用例規約中把路徑步驟刪掉,只保留輸入輸出、涉眾利益和補充約束,交互的路徑步驟由交互設計人員決定。

2.2.3.8、需求是“不這樣不行”

許多需求人員之所以在需求崗位上,並不是因為他掌握了該掌握的需求技能,可能只是因為他工作年限足夠長該換到需求崗位了——和許多年齡到了就上崗的夫妻和父母相似。這樣的需求人員硬着頭皮做需求時,最常用的一招就是托着腦袋想“這個東西是什麼樣子”,然後畫一個界面原型拿去和涉眾確認。一旦涉眾說“差不多就這樣吧”,就把這個界面原型作為需求交給分析設計人員。在這一點上,互聯網公司的產品經理表現得尤為明顯。如果僥倖成功,就拚命鼓吹“原型大法好”,因為他只會這個。

當需求人員問問題時都是“這樣可以嗎”,相當於:

● 需求人員:界面這樣布局可以嗎?

● 涉    眾:(好用就行,我又不會做界面,問我可不可以我當然說可以了)可以。

● 需求人員:代碼這樣寫可以嗎?

● 涉    眾:(好用就行,我又不會寫代碼,問我可不可以我當然說可以了)可以。

如果問的問題改為“不這樣可以嗎?”,像下面這樣:

● 需求人員:界面不這樣布局可以嗎?

● 涉    眾:不可以,這是政府的規定,你們不要自己亂髮揮啊!

● 需求人員:代碼不這樣寫可以嗎?

● 涉    眾:不可以,這段代碼是我小舅子寫的,一定要這樣,否則不給錢。

這時,界面和代碼就成為了需求,當然,只是補充約束級別的需求。說到這裏,我們歸納出需求的判斷標準:需求是“不這樣不行”,而不是“這樣也行”。

2.2.4、擴展路徑

基本路徑上的每個步驟都有可能發生很多意外,其實某些意外是系統要負責處理的,處理意外的路徑就是擴展路徑。因為一個步驟上出現的意外及其處理可能有多種,所以同一步驟上的擴展路徑可能有多條。




擴展路徑和步驟

對於擴展路徑及其步驟的標號,本書採用的是Cockburn推薦的方法。擴展路徑的標號方法是在擴展步驟的数字序號後面加上字符序號,例如2a表示步驟2的第a條擴展路徑,2b表示步驟2的第b條擴展路徑。擴展路徑條件的最後加上冒號,接下來是該擴展路徑的步驟,標號方法是在擴展路徑編號後面加上数字序號,例如2a1。也就是說,步驟的編號以数字結尾,擴展路徑編號以字母結尾。如果多重擴展,那就繼續按此形式標註。還是以之前ATM“儲戶→取現金”用例為例。該用例規約加上擴展路徑之後如下所示:

基本路徑:

1. 儲戶提交賬戶號碼

2. 系統驗證賬戶號碼合法

3. 系統提示輸入密碼

4. 儲戶輸入密碼

5. 系統驗證密碼合法、正確

6. 系統提示輸入取現金額

7. 儲戶輸入取現金額

8. 系統驗證取現金額合法

9. 系統記錄取現信息,更新賬戶餘額

……

2a. 賬戶號碼不合法:

         2a1.系統反饋賬戶號碼不合法

         2a2.返回1

5a. 密碼不合法:

         5a1.返回3

5b. 密碼合法但不正確:

         5b1.系統驗證當日取款累計輸錯密碼次數不超過3

                   5b1a.當日取款累計輸錯密碼次數超過3次:

                            5b1a1.系統關閉賬戶

                            5b1a2.用例結束

         5b2.系統反饋密碼不正確

         5b3.返回3

8a. 取現金額不合法:

         8a1.返回6

有一點需要注意,和輔執行者交互的步驟很有可能會出現擴展。例如:

4. 系統請求短信平台發布信息

……

擴展

……

4a. 短信平台無響應:

         4a1.系統反饋短信平台無響應

……

但,如果系統不需要從外部系統那裡得到任何結果,這個外系統就不是輔執行者,所以它出現故障會不會導致擴展的討論是沒有意義的。例如:

5. 系統向經理的电子郵箱通知有新的待審批申請

除了以上步驟之外,從其他步驟產生擴展路徑一定要非常謹慎,否則容易讓不屬於需求的內容混進用例規約中。特別要注意下面幾點。

1)能感知和要處理的意外才是擴展

2)設計技能不足導致的錯誤不是擴展

3)不引起交互行為變化的選擇不是擴展

4)界面跳轉不是擴展

2.2.5、補充約束

路徑步驟里描述的需求是不完整的。例如:

用例名:發布講座消息

……

1. 工作人員輸入講座信息,請求發布

2. 系統驗證講座信息充分

3. 系統生成發布內容

4. 系統請求短信平台發布消息

5. 系統保存講座信息和發布情況

6. 系統反饋信息已經保存併發布

……

步驟1中的“講座信息”包括哪些內容?需要添加字段列表。步驟2中“充分”指什麼,需要添加業務規則。從步驟1到步驟6有沒有速度上的要求?需要質量需求。

如果補充約束的內容只和單個用例相關,可以直接放在該用例的規約中;如果補充約束適用於多個用例,可以單獨集中到另外的地方,從用例規約引用。

補充約束前面的編號不代表順序,而是表示該約束綁定的步驟編號,如果某條補充約束不是針對某一步驟,而是針對多個步驟甚至整個用例,前面的編號可以是“*”,如下所示:

5. 發布情況=發布時間+工作人員

補充約束的類型可用類圖表示:




用例的補充約束

2.2.5.1、字段列表

字段列表用來描述步驟里某個領域概念的細節。例如上面“發布講座消息”用例的步驟中,步驟1、3、5都需要分別添加字段列表。

字段列表可以用自然語言表達,例如:

字段列表

1. 講座信息包括:舉辦時間、地點、專家信息、主題、簡介。專家信息包括:姓名、單位、頭銜。

也可以用符號表達,例如:

字段列表

1. 講座信息=舉辦時間+地點+專家+主題+簡介

1. 專家=姓名+單位+頭銜

表示的符號可以採用過去數據字典常用的符號。例如:“+”表示數據序列,“()”表示可選項,“{}”表示多個,“[|||]”表示可能的取值。例如:

註冊信息=公司名+聯繫人+電話+{聯繫地址}

聯繫地=州+城市+街道+(郵編)

保存信息=註冊信息+註冊時間

客房狀態=[空閑|已預定|佔用|維修中]

很多時候,做需求會把設計的細節帶上,例如“電話號碼varchar(255)”或把數據模型圖附上,這是不準確的。數據模型是設計,設計應該來源於需求,而非空想一個設計,然後把他當成需求。

2.2.5.2、業務規則

業務規則描述步驟中系統運算的一些規則,例如上面“發布講座消息”用例的步驟2中的“充分”沒有說清楚,需要添加業務規則,例如:

業務規則:

2. 必須有的項包括:時間、地點、專家、主題

其實,主要涉眾能理解,行業上適用的任何方式(例如數學、物理公式)都可以用來表達業務規則。描述業務規則時要注意:業務規則不等於實現算法。因為業務規則也是一種需求,也是從涉眾的角度看“不這樣不行”的。例如,研究一款為盲人或殘疾人而做的語音輸入軟件,用例規約有如下片段:

3. 系統將語音輸入翻譯為文字

業務規則

3. 採用XX識別算法

這樣的業務規則可能是有問題的,如果前排是盲人或殘疾人,他們是不懂什麼叫“XX算法”,也不在意你是否用了這個算法,他們在意的需求是:“背景噪音強度為XX的情況下,識別率應該在XX以上”。當然也不排除前排涉眾是有意推廣某廠家的識別技術,那麼“採用XX識別算法”也可以成為需求。

2.2.5.3、質量需求

系統滿足功能需求,說明系統能把事情做正確。在做正確的基礎上,系統還需要在做的過程中滿足一些指標,這些指標就是質量需求,也被稱為“非功能需求”。

1)可用性

可用性需求是對人類執行者和系統之間交互質量的度量。如果系統僅能正確達到用例目標,但交互太頻繁,人類執行者是不喜歡用的。在表達可用性需求時,僅僅說“系統容易使用”是不行的。這是無法量化的目標,合適的可用性需求應該是可以度量的,例如:




可用性度量

2)性能

性能包括速度、容量、能力等,例如:

① 系統應在0.5秒之內拍攝超速車的照片(速度)

② 應允許1000個執行者同時使用此用例(容量)

③ 在標準工作負荷下,系統的CPU佔用率應少於50%(能力)

在尋找質量需求時,性能類型的質量需求往往是最多的。

3)可靠性

可靠性表示系統的安全性和完整性,通常用平均無故障時間(MTBF,Mean Time Between Failures)和平均修復時間(MTTR, Mean Time To Repair)表示。可靠性需求往往不是針對單個用例,而是針對整個系統,可以在所有用例規約的最後,單獨用小篇幅描述。

4)可支持性

可支持性表示系統升級和修復的能力。例如:

① 95%的緊急錯誤應能在30個工作時內修復

② 在修復故障時,未修復的相關缺陷平均數應小於0.5

③ 升級新版本時,應保存所有系統設置和個人設置

和可靠性一樣,可支持性需求往往不是針對單個用例,而是針對整個系統,可以在所有用例規約的最後,單獨用小篇幅描述。

以上介紹了質量需求的種類,很多時候質量需求不用可以去尋找,按照前面說過的“不這樣行嗎”的標準,把混入需求的設計刪掉,然後問為什麼,背後往往隱含的就是質量需求,如下所示:




質量需求

2.2.5.4、設計約束

設計約束是在實現系統時必須要遵守的一些約束,包括界面樣式、報表格式、平台、語言等。

設計約束既不是功能需求,也不是質量需求。例如,“用Oracle數據庫保存數據”,其實用DB2也可以滿足同樣的功能需求和質量需求,但必須要用Oracle,因為客戶已經採購了許多Oracle數據庫軟件,如果不用,成本就會增加。

設計約束是需求的一種,也一樣要從涉眾的視角描述。在很多需求規約中,不少來自開發人員視角的設計偽裝成設計約束,混進了需求的隊伍。例如“系統應採用三層架構方式搭建”,涉眾並不了解“三層”好在哪裡,為什麼不是四層、五層等,然後問“為什麼”,背後的真正需求可能還是性能需求。

需求是問題,設計是解決方案,二者的穩定性不同。

 

2.3、需求啟發

2.3.1、需求啟發要點

需求人員要能夠像獵人一樣,用銳利的眼睛發現隱藏在叢林中的獵物,像偵探一樣,用縝密的思維判斷出偽裝成好人的兇手。但需求人員會有許多的障礙:如

1)需求的一個啟發障礙是知識的詛咒,意思是:一旦知道某個東西,就很難相像不知道它會是什麼樣子;

2)知識的詛咒在需求啟發中體現為溝通的困難;

3)需求啟發的另一個障礙是做和定義的不同;

但理解了以下兩個要點,有助於克服需求啟發中的障礙:

1)和涉眾交流的形式應該採用視圖,而不是模型;

2)和涉眾交流的內容應該聚焦涉眾利益,而不是需求;

2.3.2、需求啟發手段




需求啟發手段

2.3.3、需求人員的素質培養




需求人員的素質

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

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

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

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

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

(三十五)golang–面向對象之多態

多態:變量具有多種形態,可以用統一的接口來調用不同的實現。

接口體現多態特徵:

(1)多態參數:之前所講的Usb接口案例,既可以接受手機變量,也可以接受相機變量,就體現了usb接口的多態;

(2)多態數組:

package main

import (
    "fmt"
)

type usb interface {
    start()
    stop()
}

type phone struct {
    name string
}

func (p phone) start() {
    fmt.Println(p.name, "手機開始工作")
}

func (p phone) stop() {
    fmt.Println(p.name, "手機停止工作")
}

type camera struct {
    name string
}

func (c camera) start() {
    fmt.Println(c.name, "相機開始工作")
}

func (c camera) stop() {
    fmt.Println(c.name, "相機停止工作")
}

type computer struct {
}

func (co computer) working(usb usb) {
    usb.start()
    usb.stop()
}

func main() {
    var usbArr [3]usb
    usbArr[0] = phone{"小米"}
    usbArr[1] = phone{"vivo"}
    usbArr[2] = camera{"尼康"}
    fmt.Println(usbArr)
    for i := 0; i < len(usbArr); i++ {
        usbArr[i].start()
        usbArr[i].stop()
    }
}

我們以前講到,數組是只能存儲同一種類型的數據,利用多態數組,就可以存儲不同的類型了;

如何將一個接口變量賦值給一個自定義類型的變量?使用類型斷言

類型斷言:由於接口是一般類型,不知道具體類型,如果要轉成具體類型,就需要使用類型斷言;要保持原來空接口指向的數據類型和斷言的數據類型一致;

為了避免輸出panic報錯,可以進行斷言判斷;

類型斷言實踐一:

我們給phone中加入一個方法call(),在調用usb變量時,usb.call(),肯定是不對的,因為usb可能是phone,也可能是camera,而camera是沒有這個函數的,因此,在調用的時候用類型斷言。

package main

import (
    "fmt"
)

type usb interface {
    start()
    stop()
}

type phone struct {
    name string
}

func (p phone) start() {
    fmt.Println(p.name, "手機開始工作")
}

func (p phone) call() {
    fmt.Println(p.name,"手機在打電話")
}

func (p phone) stop() {
    fmt.Println(p.name, "手機停止工作")
}

type camera struct {
    name string
}

func (c camera) start() {
    fmt.Println(c.name, "相機開始工作")
}

func (c camera) stop() {
    fmt.Println(c.name, "相機停止工作")
}

type computer struct {
}

func (co computer) working(usb usb) {
    usb.start()
    //如果usb還指向phone的結構體變量,則還需要調用call方法
    if phone, ok := usb.(phone); ok { phone.call() }
    usb.stop()
}

func main() {
    var usbArr [3]usb
    usbArr[0] = phone{"小米"}
    usbArr[1] = phone{"vivo"}
    usbArr[2] = camera{"尼康"}
    var com computer
    fmt.Println(usbArr)
    for i := 0; i < len(usbArr); i++ {
        com.working(usbArr[i])
    }
}

類型斷言實踐2:循環判斷輸入參數的類型

package main

import (
    "fmt"
)

type student struct {
    name string
}

func typeJudge(items ...interface{}) {
    for index, x := range items {
        switch x.(type) {
        case bool:
            fmt.Printf("第%v個參數是bool類型,值是%v\n", index, x)
        case int, int32, int64:
            fmt.Printf("第%v個參數是整數類型,值是%v\n", index, x)
        case float32:
            fmt.Printf("第%v個參數是float32類型,值是%v\n", index, x)
        case float64:
            fmt.Printf("第%v個參數是float64類型,值是%v\n", index, x)
        case string:
            fmt.Printf("第%v個參數是string類型,值是%v\n", index, x)
        case student:
            fmt.Printf("第%v個參數是student類型,值是%v\n", index, x)
        case *student:
            fmt.Printf("第%v個參數是*student類型,值是%v\n", index, x)
        default:
            fmt.Printf("第%v個參數類型不確定,值是%v\n", index, x)
        }
    }
}

func main() {
    var n1 float32 = 1.1
    var n2 float64 = 1.2
    var n3 int32 = 1
    var name string = "tom"
    var n5 bool = true

    stu1 := student{"jack"}
    stu2 := &student{"bob"}

    typeJudge(n1, n2, n3, name, n5, stu1, stu2)
}

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

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

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

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

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

MySQL 5.7 – 通過 BINLOG 恢複數據

日常開發,運維中,經常會出現誤刪數據的情況。誤刪數據的類型大致可分為以下幾類:

  • 使用 delete 誤刪行
  • 使用 drop table 或 truncate table 誤刪表
  • 使用 drop database 語句誤刪數據庫
  • 使用 rm 命令誤刪整個 MySQL 實例。

不同的情況,都會有其優先的解決方案:

  • 針對誤刪行,可以通過 Flashback 工具將數據恢復
  • 針對誤刪表或庫,一般採用通過 BINLOG 將數據恢復。
  • 而對於誤刪 MySQL 實例,則需要我們搭建 HA 的 MySQL 集群,並保證我們的數據跨機房,跨城市保存。

本篇主要討論的內容是誤刪表或者庫,會先介紹有關 BINLOG 的操作命令,然後會對誤刪表的這種情況進行實際的模擬。

BINLOG 常見操作命令

BINLOG 的查詢方式一般分為兩種,一種是進入 MySQL 控制台進行查詢,另一種是通過 MySQL 提供的工具 mysqlbinlog 進行查詢,兩者的不同會在下面介紹。

通過 MySQL Cli 查詢 BINLOG 信息

在 cli 中,常見的命令如下:

# 查詢 BINLOG 格式
show VARIABLES like 'binlog_format';

# 查詢 BINLOG 位置
show VARIABLES like 'datadir';

# 查詢當前數據庫中 BINLOG 名稱及大小
show binary logs;

# 查看 master 正在寫入的 BINLOG 信息
show master status\G;

# 通過 offset 查看 BINLOG 信息
show BINLOG events in 'mysql-bin.000034' limit 9000,  10;

# 通過 position 查看 binlog 信息
show BINLOG events in 'mysql-bin.000034' from 1742635 limit 10;

使用 show BINLOG events 的問題:

  • 使用該命令時,如果當前 binlog 文件很大,而且沒有指定 limit,會引發對資源的過度消耗。因為 MySQL 客戶端需要將 binlog 的全部內容處理,返回並显示出來。為了防止這種情況,mysqlbinlog 工具是一個很好的選擇。

通過 mysqlbinlog 查詢 BINLOG 信息

在介紹 mysqlbinlog 工具使用前,先來看下 BINLOG 文件的內容:

# 查詢 BINLOG 的信息
mysqlbinlog  --no-defaults mysql-bin.000034 | less
# at 141
#100309  9:28:36 server id 123  end_log_pos 245
  Query thread_id=3350  exec_time=11  error_code=0
  • at 表示 offset 或者說事件開始的起始位置
  • 100309 9:28:36 server id 123 表示 server 123 開始執行事件的日期
  • end_log_pos 245 表示事件的結束位置 + 1,或者說是下一個事件的起始位置。
  • exec_time 表示在 master 上花費的時間,在 salve 上,記錄的時間是從 Master 記錄開始,一直到 Slave 結束完成所花費的時間。
  • rror_code=0 表示沒有錯誤發生。

在大致了解 binlog 的內容后,mysqlbinlog 的用途有哪些?:

  • mysqlbinlog 可以作為代替 cli 讀取 binlog 的工具。
  • mysqlbinlog 可以將執行過的 SQL 語句輸出,用於數據的恢復或備份。

查詢 BINLOG 日誌:

# 查詢規定時候后發生的 BINLOG 日誌
mysqlbinlog --no-defaults --base64-output=decode-rows -v  --start-datetime  "2019-11-22 14:00:00" --database sync_test  mysql-bin.000034 | less

導出 BINLOG 日誌,用於分析和排查 sql 語句:

mysqlbinlog --no-defaults --base64-output=decode-rows -v  --start-datetime  "2019-11-22 14:00:00" --database sync_test  mysql-bin.000034 > /home/mysql_backup/binlog_raw.sql

導入 BINLOG 日誌

# 通過 BINLOG 進行恢復。
mysqlbinlog --start-position=1038 --stop-position=1164 --database=db_name  mysql-bin.000034 | mysql  -u cisco -p db_name

# 通過 BINLOG 導出的 sql 進行恢復。
mysql -u cisco -p db_name < binlog_raw.sql.sql

mysqlbinlog 的常用參數:

  • --database 僅僅列出配置的數據庫信息
  • --no-defaults 讀取沒有選項的文件, 指定的原因是由於 mysqlbinlog 無法識別 BINLOG 中的 default-character-set=utf8 指令
  • --offset 跳過 log 中 N 個條目
  • --verbose 將日誌信息重建為原始的 SQL 陳述。
    • -v 僅僅解釋行信息
    • -vv 不但解釋行信息,還將 SQL 列類型的註釋信息也解析出來
  • --start-datetime 显示從指定的時間或之後的時間的事件。
    • 接收 DATETIME 或者 TIMESTRAMP 格式。
  • --base64-output=decode-rows 將 BINLOG 語句中事件以 base-64 的編碼显示,對一些二進制的內容進行屏蔽。
    • AUTO 默認參數,自動显示 BINLOG 中的必要的語句
    • NEVER 不會显示任何的 BINLOG 語句,如果遇到必須显示的 BINLOG 語言,則會報錯退出。
    • DECODE-ROWS 显示通過 -v 显示出來的 SQL 信息,過濾到一些 BINLOG 二進制數據。

MySQL Cli 和 mysqlbinlog 工具之間的比較

如果想知道當前 MySQL 中正在寫入的 BINLOG 的名稱,大小等基本信息時,可以通過 Cli 相關的命令來查詢。

但想查詢,定位,恢復 BINLOG 中具體的數據時,要通過 mysqlbinlog 工具,因為相較於 Cli 來說,mysqlbinlog 提供了 --start-datetime--stop-position 等這樣更為豐富的參數供我們選擇。這時 Cli 中 SHOW BINLOG EVENTS 的簡要語法就變得相形見絀了。

使用 BINLOG 恢複數據

恢復的大致流程如下:

  1. 會創建數據庫和表,並插入數據。
  2. 誤刪一條數據。
  3. 繼續插入數據。
  4. 誤刪表。
  5. 最後將原來以及之後插入的數據進行恢復。

準備數據

準備數據庫,表及數據:

# 創建臨時數據庫
CREATE DATABASE IF NOT EXISTS test_binlog default charset utf8 COLLATE utf8_general_ci; 


# 創建臨時表
CREATE TABLE `sync_test` (`id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


# 添加數據
insert into sync_test (id, name) values (null, 'xiaoa');
insert into sync_test (id, name) values (null, 'xiaob');
insert into sync_test (id, name) values (null, 'xiaoc');

# 查看添加的數據
select * from sync_test;

刪除表或者數據

誤刪操作:

# 刪除 name=xiaob 的數據
delete from sync_test where id=3

# 插入幾條數據
insert into sync_test (id, name) values (null, 'xiaod');
insert into sync_test (id, name) values (null, 'xiaoe');
insert into sync_test (id, name) values (null, 'xiaof');

# 刪除表
DROP TABLE sync_test;

數據的恢復

在執行數據恢復前,如果操作的是生產環境,會有如下的建議:

  • 使用 flush logs 命令,替換當前主庫中正在使用的 binlog 文件,好處如下:
    • 可將誤刪操作,定位在一個 BINLOG 文件中,便於之后的數據分析和恢復。
    • 避免操作正在被使用的 BINLOG 文件,防止發生意外情況。
  • 數據的恢復不要在生產庫中執行,先在臨時庫恢復,確認無誤后,再倒回生產庫。防止對數據的二次傷害。

通常來說,恢復主要有兩個步驟:

  1. 在臨時庫中,恢復定期執行的全量備份數據。
  2. 然後基於全量備份的數據點,通過 BINLOG 來恢復誤操作和正常的數據。

使用 BINLOG 做數據恢復前:

# 查看正在使用的 Binlog 文件
show master status\G;
# 显示結果是: mysql-bin.000034

# 執行 flush logs 操作,生成新的 BINLOG
flush logs;

# 查看正在使用的 Binlog 文件
show master status\G;
# 結果是:mysql-bin.000035

確定恢複數據的步驟:

這裏主要是有兩條誤刪的操作,數據行的誤刪和表的誤刪。有兩種方式進行恢復。

  • 方式一:首先恢復到刪除表操作之前的位置,然後再單獨恢復誤刪的數據行。
  • 方式二:首先恢復到誤刪數據行的之前的位置,然後跳過誤刪事件再恢複數據表操作之前的位置。

這裏採用方式一的方案進行演示,由於是演示,就不額外找一個臨時庫進行全量恢復了,直接進行操作。

查詢創建表的事件位置和刪除表的事件位置

#  根據時間確定位置信息
mysqlbinlog --no-defaults --base64-output=decode-rows -v  --start-datetime  "2019-11-22 14:00:00" --database test_binlog  mysql-bin.000034 | less

創建表的開始位置:

刪除表的結束位置:

插入 name=’xiaob’ 的位置:

# 根據位置導出 SQL 文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v --start-position "2508132" --stop-position "2511004" --database test_binlog  mysql-bin.000034 > /home/mysql_backup/test_binlog_step1.sql
 
 
mysqlbinlog --no-defaults --base64-output=decode-rows -v --start-position "2508813" --stop-position "2509187" --database test_binlog  mysql-bin.000034 > /home/mysql_backup/test_binlog_step2.sql
 

# 使用 mysql 進行恢復
mysql -u cisco -p < /home/mysql_backup/test_binlog_step1.sql
mysql -u cisco -p < /home/mysql_backup/test_binlog_step2.sql

MySQL 5.7 中無論是否打開 GTID 的配置,在每次事務開啟時,都首先會出 GTID 的一個事務,用於并行複製。所以在確定導出開始事務位置時,要算上這個事件。

在使用 –stop-position 導出時,會導出在指定位置的前一個事件,所以這裏要推后一個事務。

對於 DML 的語句,主要結束位置要算上 COMMIT 的位置。

總結

在文章開始時,我們熟悉了操作 BINLOG 的兩種方式 CLI 和 mysqlbinlog 工具,接着介紹了其間的區別和使用場景,對於一些大型的 BINLOG 文件,使用 mysqlbinlog 會更加的方便和效率。並對 mysqlbinlog 的一些常見參數進行了介紹。

接着通過使用 mysqlbinlog 實際模擬了數據恢復的過程,並在恢複數據時,提出了一些需要注意的事項,比如 flush logs 等。

最後在恢複數據時,要注意 start-positionend-position 的一些小細節,來保證找到合適的位置。

參考

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

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

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

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

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

馬斯克遇程咬金,第一台電動卡車不姓特斯拉

馬斯克近日才剛在推特上表示,近期將推出全電動的半掛式卡車,令市場相當的看好,然而如今第一個達成創舉的廠商,卻不是特斯拉。

特斯拉將在9 月發表載貨用的全電動半掛卡車(Tesla Semi)原型,雖然業界一直在質疑其負載及續航力,不過若成功的話也等於是對市場投下一個震撼彈。畢竟相較汽柴油車的引擎,電動車的維護成本較低,假如電池成本也持續降低,在配合環保法規的情況下,相當的有市場。

不過如今一家原本專做柴油及天然氣發動機的龍頭廠商康明斯(Cummins)推出了相當於第7 級重型卡車的電動車,其配備了先進的140 kWh 的電池組,並預計將於2019 年開始交付給客戶。這台卡車被命名為AEOS,應該是取意於希臘神話中替太陽神阿波羅拉車的火焰飛馬。

 

AEOS in motion: Raw footage of our first fully electric heavy duty demonstration Urban Hauler Tractor.

— Cummins Inc. (@Cummins)

 

且Cummins 也能僅提供動力系統總成,將可應用於電動巴士等其他車型。電動巴士製造商 Proterra 的總裁Ryan Popple 指出,這是相當令人震驚的消息,是邁向完全電氣化交通的一大步,隨著各國正積極修訂法規鼓勵電動車,目前這方面的市場相當大,巴士及校車等訂單幾乎滿載。

據Cummins 表示,這輛電動卡車動力總成與一般柴油車相當,可牽引4,4000 磅的重量,近20 噸,單次充電可行駛約100 英里,並可加掛額外的電池組將行程擴展到300 英里,還可安裝太陽能電池板,還有再生制軔(Regenerative brake)及低阻力輪胎的研發將可望進一步提昇其行駛距離。目前的充電站設計,將可在1 小時內充滿,而Cummins 的目標是希望,能夠在2020 年以前,將充電時間縮短到20 分鐘。

不過Cummins 的執行長Thomas Linebarger 也坦言,依目前電池科技的進展,第7 級重型卡車的應用已是極限,第8 級的重型拖車目前仍遙遙無期。所以也將推出同型的高效率柴油引擎及混合動力車款。儘管有所突破,但目前電動系統仍較適用於商用卡車,Cummins 一舉超越特斯拉也同樣宣示了將進軍此市場的意圖。

當然特斯拉就算被搶得頭籌,也不代表無法反擊,據之前透露的消息,其產品可能將定位於行程達200-300 英里的運輸範圍,性能可能比AEOS 還強。但Cummins 此舉或許更大意義在於強調,他們這些傳統龍頭,儘管受到挑戰,仍有相當強的底蘊,在不同動力系統的研發上,有超乎市場想像的潛力。

(合作媒體:。圖片出處:)

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

【其他文章推薦】

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

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

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

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

首發!Apache Flink乾貨合集打包好了,速來下載

  最近的一份市場調查報告显示,Apache Flink 是 2018 年開源大數據生態中發展“最快”的引擎,和 2017 年相比增長了 125% 。為了讓大家更為全面地了解 Flink,我們製作了一本电子乾貨合集:《不僅僅是流計算:Apache Flink 實踐》,融合了 Apache Flink 在國內各大頂級互聯網公司的大規模實踐,希望對大家有所幫助。

  在這本合集里,你可以了解到:

  Flink 如何為整個阿里集團平穩度過雙十一立下汗馬功勞?

  如何為滿足滴滴極為複雜的業務需求提供簡單直觀的 API 支持?

  如何在字節跳動逐步取代原有的 JStorm 引擎,成為公司內部流式數據處理的唯一標準?

《不僅僅是流計算:Apache Flink 實踐》目錄一覽

  下載地址:

  https://102.alibaba.com/downloadFile.do?file=1543409877893%2fApache+Flink.pdf

  Apache Flink 已經被業界公認是最好的流計算引擎。然而 Flink 的計算能力不僅僅局限於做流處理。Apache Flink 的定位是一套兼具流、批、機器學習等多種計算功能的大數據引擎。在最近的一段時間,Flink 在批處理以及機器學習等諸多大數據場景都有長足的突破。此次專刊,旨在對 Flink 在大數據智能計算方面做一些簡要的介紹。後續我們還將發布更多關於 Flink 在新場景的應用乾貨。

  下面,我們邀請阿里資深技術專家、Apache Flink Committer 王紹翾老師(花名“大沙”),帶領大家走進 Flink 的世界。

  在全面介紹 Flink 的新進展之前,我先來介紹一些大數據和人工智能計算的背景。大數據計算的種類非常多,比較典型的,且被大規模使用的主要是 3 種類型:

  • 批計算

  • 流計算

  • 交互式分析計算

  批計算的特點是要計算的數據量比較大,但是往往對延遲不是特別敏感。流計算對延遲的要求非常高,這些作業的查詢 query 往往是固定的。因此流計算作業往往需要提前調度起來,一旦數據到來就可以做快速的處理,節省了調度的開銷。

  最後一種是交互式分析,這種類型的大數據計算的特點是用戶的查詢 query 是不固定的,這些 query 往往是由用戶隨機的發出的。雖然查詢不固定,在這種場景下,用戶對查詢的返回時間是有一定的要求的,這個時間介於批處理和流處理之間,越快越好,最好能做到秒級。

  人工智能計算的種類很多,但是整體架構大多和上圖所描述的類似。一個常見的 ML pipeline 通常涉及一系列的數據預處理、特徵提取和轉換、模型訓練以及驗證。如果驗證后的效果符合預期,就可以將模型推到線上服務。如果不符合預期,算法工程師就需要調整算法模型或者參數,然後再做一次模型的訓練和驗證,直到對結果滿意后,再將訓練好的模型推上線服務。整個計算過程可以是對一個確定大小的數據按照批計算模式計算,也可以接入實時數據按照流計算模式進行計算。上面這個 pipeline 是人工智能計算最基礎的流程,如果算法工程師對數據以及業務特點非常熟悉,他們就能設計出合理的算法模型和參數。但是往往更常見的情況是,算法工程師需要分析工具幫助他們理解數據。只有在很好地理解了數據特點之後,才能提取出更有用的特徵,設計出更好的模型。因此,如下圖所示,做好人工智能計算,不可或缺的一部分就是交互式分析。有了交互式分析,算法工程師可以對數據做各種 ad-hoc query,從而幫助他們更好地理解數據。

  綜上所述,可以看出人工智能計算和大數據計算是密不可分的。雖然人工智能計算變得越來越炙手可熱,人們越來越多的提及人工智能而不是大數據,但是我們不能忘記,人工智能計算的基礎是大數據計算,沒有大數據計算提供算力和功能,人工智能計算只能停留在紙上談兵的階段。接下來,我把基於大數據計算的人工智能計算簡稱為“大數據智能計算”。

  大數據和 AI 全景–2018(來源:http://mattturck.com/bigdata2018/)

  那麼怎麼來搭建一套大數據智能計算系統呢?http://mattturck.com 收集了所有大數據和 AI 的軟件和平台。上面提到的每一種大數據計算場景都有好幾種軟件的選擇,調研和選型這些軟件本身就是一項巨大的工程。即使最後為每一套場景都選型了一種軟件,那麼後期的開發迭代和運維也難做到高效。因為每一套軟件都需要專門的開發和運維團隊負責,無論是在人力還是機器資源上都不能橫向打通,勢必會造成浪費。

  因此,阿里巴巴一直在思考是否可能有一套計算引擎解決如上的所有問題。經過仔細的選型,我們選擇了 Apache Flink,並圍繞着 Flink 在打造一款通用計算引擎。Flink 已經被業界公認是最好的流計算引擎。

  它所具有的低延遲、高吞吐、保障 Exactly-once 的計算模式,使得它具有金融級的大數據處理能力。在批處理方面,基於流式的 flow 來處理批數據有着潛在的優勢和擴展性。阿里巴巴利用 Flink 的天然特性,做了若干批計算方面的優化,使得 Flink 也成為了一款性能卓越的批計算引擎。在人工智能和交互式分析方面,我們也在逐步地完善 Flink 的易用性,生態,以及性能。另外,不得不提的是,Flink 的流處理架構還天然的適合於正在快速崛起的本質更像流計算的 IoT 的場景。

  Flink 的社區和生態一直在壯大。在流計算和批計算等場景慢慢使用 Flink 成為主流的同時,我們期望設計和推廣出更多更完善的批流融合的場景。所有對 Lamda 架構有訴求的應用應該都可以用 Flink 完美的解決。早期的 Lamda 架構的設計也許很快會成為歷史。

  在易用性和生態方面,我們一方面幫助 Flink 社區在 tableAPI,Python,以及 ML 等諸多領域發力,持續提升用戶做 Data science 和 AI 計算的體驗。另一方面,我們也在努力完善 Flink 和其他開源軟件的融合,包括 Hive,以及 Notebook(Zeppelin, Jupyter)等等。這些諸多的努力,都是為了最終實現我們“一套引擎完美解決大數據智能計算”的初衷。Apache Flink 自 2014 年開源至今也才 4 年,我們期待更多的企業和開發者們和我們一起參與到 Apache Flink 的社區和生態建設中來,共同把它打造成為全球最一流的開源大數據引擎。

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

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

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

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

印度政府年內擬發布新電動車政策,車廠提前動起來

印度政府為對抗空污,矢言2030年全國只賣電動車,促使車廠卯起勁來加速開發電動車。

電動車因電池成本極高而造價昂貴,加上缺乏充電站,普及化面臨重重困難。儘管如此,印度政府仍不畏挑戰,決心走這條困難但正確的路。據路透社報導,某印度政府官員表示正在草擬新政策,當中包含推動電動車的藍圖,預計將在今年底發布。

在政策引導下,印度國內外車廠已經全面動起來。報導指出,韓國現代汽車正與供應商就電動車所需零件進行討論。另外,印度車廠Ashok Leyland去年推出電動巴士後,還與新創企業SUN Mobility結盟,將齊力研發車用電池交換技術。

鄰近印度的中國政府現也意識到電動車時代來臨,據新華社9日報導,中國工信部副部長辛國斌透露已啟動相關研究,正在研擬傳統內燃機汽車退場的時間表。

(本文內容由授權使用。圖片出處:pexels CC0)

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

【其他文章推薦】

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

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

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

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

Gogoro增資三億美元,引進高爾創投、新加坡淡馬錫

台灣電動機車商Gogoro(睿能創意)電池交換技術獲國際認同,新一輪C系列三億美元募資,成功吸引到美國前副總統高爾的世代投資管理公司(Generation Investment Management)參與。

Gogoro電動機車從2015年開賣至今,已賣出超過3.4萬部,包含法國電力公司昂吉集團(Engie)、日本住友(Sumitomo),以及新加坡淡馬錫投資公司(Temasek)等,現在都是新加入的投資者。

據金融時報報導,新募資金多數將用於擴張電池交換網路,以及開發相關後端系統科技,Gogoro計畫以人工智能來即時監控交換站電池使用狀況,以及電價波動。

Gogoro創辦人陸學森受訪時表示,前兩代電動機車是出於必要的產物,目的在證明其電池與充電系統的可行性,Gogoro自認比較像能源公司多過機車製造商。陸學森透露已與國外其它車廠洽談合作計畫,將把技術向國際推廣。

(本文內容由授權使用。圖片出處:Gogoro 官網)  

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

【其他文章推薦】

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

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

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

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