低噪音無環境污染,全球首輛商業氫燃料列車駛入德國

氫燃料電池目前已應用在汽車、公車甚至是列車中,為備受看好的化石燃料替代品,各國也紛紛將氫燃料交通運輸納入未來藍圖,像是全球首輛商業運行氫燃料列車已在德國漢諾威上路,除了為氫燃料列車立下新里程碑,也讓德國離減碳目標更進一步。

該氫燃料列車名為 CORADIA iLINT,由法商阿爾斯通(Alstom)一手開發,於 2016年首次亮相德國柏林 InnoTrans 貿易展,2017 年 3 月更在德國完成首航測試,漢諾威當地鐵路公司 LNVG 於在同年 9 月斥資 8,100 萬歐元訂購 14 輛 CORADIA iLINT。

目前德國漢諾威民眾已經可在下薩克森邦(Lower Saxony)鐵路系統乘坐世界第一批、共 2 輛氫燃料列車,預計 14 輛 CORADIA iLINT 將於 2021 年全面上路,並行駛於庫克斯港、不萊梅港、布雷梅爾弗爾德、布克斯特胡德之間的鐵路線。

CORADIA iLINT 可乘載 300 人,最高時速 140 公里,續航距離與柴油列車相同為 1,000 公里,每組氫燃料槽重達 94 公斤,而雖然氫燃料列車成本較高,但行駛途中只會排出水,沒有排放廢氣與二氧化碳問題,預估可在 10 年左右達成損益兩平。

圖片來源:

該氫燃料列車外觀跟傳統列車相差無幾,如果不是車體外觀滿滿的 H 與 O 化學鍵符號,乍看之下就是一般的藍色列車,但其實其中暗藏玄機,每節車輛頂部都設有氫燃料箱與氧燃料箱,透過燃料電池來產生電力,最後再由車底部的鋰離子電池驅動火車,多餘電力也可儲存起來增加能源使用效率。

該列車還搭載智慧電源管理系統,燃料電池會在列車行駛時穩定供應電力,而列車煞車或是停止時,會立刻停止燃料電池轉換,可節省氫氣消耗量。阿爾斯通開發人員 Jens Sprotte 表示,與傳統柴油火車相比,CORADIA iLINT 噪音降低 60%,乘客只會聽到車輪與風的聲音。

目前德國約有 40% 鐵路未實現電氣化,若是可將 4,000 輛柴油列車全部汰換成氫燃料電池列車,除了能減少 45% 排碳量,還可以免除鐵路電氣化所需的電纜、配電成本。

不過氫燃料列車也有許多挑戰待克服,由於氫燃料技術尚未成熟,能量轉換率還不高、最高時速只能達到每小時 140 公里,且氫氣製程仍無法擺脫化石燃料,純氫氣需要加工才可獲得,阿爾斯通公司表示,計劃之後使用下薩克森邦龐大風力發電系統的電力來製造所需的氫燃料。

德國推行節能減碳與再生能源不遺餘力,計劃在 2030 將再生能源發電比例提升至 65%,而阿爾斯通也有其雄心勃勃目標,望可在在未來 5-20 年間汰換掉德國所有的柴油列車,讓德國鐵路朝零碳邁進。

(首圖來源:。文/DaisyChuang)

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

分佈式事務

分佈式事務

分佈式環境下的事務

要了解分佈式事務,首先要了解分佈式環境

分佈式

如一網站,訪問一個服務A(查詢自己用戶信息), 提供服務A的服務器分別有A1(上海)A2(廣州) A3(新加坡)

同一個服務分佈在三個區域的服務器上,這就是分佈式。你可以訪問 上海的服務器,廣州的或者新加坡的,但是

三個服務器之前通信是有延遲的,所以數據同步需要一定時間

分佈式中的問題

舉例一個分佈式場景

如果用戶Y個人信息 名字為 “南柯一夢” Y改為 “南柯夢”, 同一時間,Y用戶好友查看Y的名字,好友查詢的結果是”南柯一夢” 還是 “南柯夢” 這是分佈式系統常見的問題(數據修改發生在上海,訪問發生在新加坡)。

CAP原則

CAP原則又稱CAP定理,指的是在一個分佈式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。

參考文章
An Illustrated Proof of the CAP Theorem
CAP 定理的含義

以為網絡有延遲和不可測故障,因此分佈式系統是保持服務穩定的常用手段,但是分佈式因為服務機器分佈在不同地點,因此也會有分佈式的特點問題。

分佈式中 一致性 可用性 容災性 是三個指標

Consistency

數據一致性,分佈式環境下,不同地點的服務器,數據庫數據同步一致。

Availability

服務可用性,分佈式環境下,調用服務,都可用

Partition tolerance

分區容錯性,容災能力

分佈式環境多台服務器運行,其中一部分機器故障了,整個系統仍然可以正常運行提供服務

CAP不能同時滿足

必須滿足P

首先分佈式環境,系統需要穩定運行,一台服務器意外斷電,不應該影響系統整體功能正常,另一台或多台服務器還能穩定提供服務,所以分區容錯是必須要滿足。

滿足C

數據一致性,所指的是同一個服務所在不同服務器的數據是同步的。如上改名字的場景 南柯一夢 改為 南柯夢 (在上海的數據庫被修改) 那麼系統要做到滿足數據一致性,必須馬上同步廣州和新加坡的數據庫,這樣才能滿足廣州或者新加坡的訪問者獲得的結果也一致是 “南柯夢” 而不是”南柯一夢”

滿足A

服務可用性,指任何時候訪問服務,都返回結果

A與C是衝突的,上海服務器南柯一夢改為南柯夢后,為了服務可用,此時間訪問新加坡和廣州的服務器,返回的結果應該是南柯一夢(任何時候服務都返回結果) 但是嚴格上講,數據是錯誤的,因為用戶已經改了名字,改為南柯夢,但是數據在上海的才是正確的。

滿足數據一致性必須犧牲服務可用性 或者相反

要達到數據一致性的要求,必須在上海服務器修改數據的同時,同步廣州和新加坡的數據庫,並且在數據同步完成之前,訪問廣州和新加坡的數據庫中這條數據需要等待,返回同步后的結果(一致性)。

失去了服務可用性(這裏服務是等待數據同步完成才返回結果,而不是立刻返回)

因此CAP 要麼 滿足AP (分區服務可用)要麼 CP (分區數據一致)

分佈式中事務

商品購買中的事務

以商品購買生成訂單為例子

網絡上用戶A 購買 一雙鞋子 價格50 付款後生成消費訂單

事務中包含子的服務

這裏簡單設為三個服務,他們是事務相關的

1.商品信息服務

提供商品信息等服務

鞋子 顏色 價格 庫存數量等信息 這裏設 價格price為 50 庫存數 num 9

2.商家賬號收款服務

提供金額收入信息等服務

用戶購買鞋子,需要付款50元到商家賬號

3.用戶消費訂單服務

提供購買消費憑證信息等服務

首先分析用戶購買鞋子,三個服務分別要做什麼

@1 鞋子庫存減1

@2 商家賬號金額增加50

@3 生成 用戶購買鞋子的訂單記錄, 包括數量金額等信息

事務特性

原子性

@1 @2 @3 要麼同時發生,要麼都不發生

一致性

鞋子庫存減少1,收入增加50

隔離性

鞋子庫存減1,後續用戶最多只能購買(9-1=8)雙鞋子

持久性

動作執行成功后,訂單生效,收入新增50生效,庫存減1生效

上述三個服務他們可以在不同的地點,不同機器上部署的,並很常見。

保證數據正確

開啟事務

確定要執行的服務,每個服務的數據庫事務開啟

執行業務

調用庫存減1,轉賬,生成訂單等子服務

提交

業務執行過程中沒有意外,各子服務的數據庫提交事務,生效數據修改

回退

回退,如果服務調用出現了差錯,或者某個子服務執行失敗,可以通過回滾所有數據庫達到數據正確。

補償

某些情況下,某個子服務執行失敗,但是不影響整體業務,也可以提交事務,後續補償機制將失敗的子服務重新執行。

補償機制

個人認為就商品購買而言,補償機制多數情況可以使用且實用。(對強一致要求沒那麼高的情況下)

@1 庫存減1

@2 收入增加50

@ 3生成訂單記錄

如果這次執行的動作, 只有@3失敗,@1 @2成功 說明金額交易,商品庫存業務都沒問題,只是訂單記錄失敗,這是可以提交事務的,訂單錯誤可以生成一條記錄(攜帶商品,金額等信息),發送到MQ消息隊列(或者其他設計)通過消息隊列通知訂單相關服務,補償重新執行生成訂單,達到最終一致性。

分佈式事務控制問題

不同服務在不同區運行

不管是從安全性,穩定性,還是服務粒度細化方便維護等多因素考慮,都是很有必要讓不同的服務分開在不同服務區運行。

單體數據庫的事務不被支持,購買商品到生成訂單所有操作加起來算一個事務,涉及的數據在不同一服務(不同的數據庫),並且同一個服務可能運行在多台服務器上。

數據庫開啟事務針對的是單台服務器,多個服務多個數據庫,並不支持數據庫的事務,需要額外設計處理數據一致性問題(或者最終一致性)

同一個服務運行在多個區

不同服務不在一個服務器,同樣的,分佈式為穩定性可用而生,因此,一個服務大多有在多個區的服務器上運行,開啟事務的時候,如何保證事務開啟提交等事務相關命令每次發送到同一個區的同一個服務器,也是一定要考慮的問題。

分佈式事務處理方式

如上所述分佈式服務代表多個數據庫,不支持數據庫的事務,

如何保證事務中涉及的數據庫數據修改都提交生效或者都回滾。

建立控制中心

控制中心在執行業務時,統一發送開始事務的命令給三個服務,返回狀態

狀態沒問題執行數據修改,

都沒問題就發送給三個服務,提交事務,否在回滾事務

消息機制事務

MQ消息隊列,達到控制事務正確目的,項目中kafka聽的比較多,可在高併發環境下穩定運行,可以通過消息機制發送事務處理結果到子服務,子服務收到消息,通過分析消息內容,做出對應的操作,達到事務一致性或者最終一致性等目的
思考圖:

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

【其他文章推薦】

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

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

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

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

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

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

MySQL多版本併發控制機制(MVCC)-源碼淺析

MySQL多版本併發控制機制(MVCC)-源碼淺析

前言

作為一個數據庫愛好者,自己動手寫過簡單的SQL解析器以及存儲引擎,但感覺還是不夠過癮。<<事務處理-概念與技術>>誠然講的非常透徹,但只能提綱挈領,不能讓你玩轉某個真正的數據庫。感謝cmake,能夠讓我在mac上用xcode去debug MySQL,從而能去領略它的各種實現細節。
筆者一直對數據庫的隔離性很好奇,此篇博客就是我debug MySQL過程中的偶有所得。
(注:本文的MySQL採用的是MySQL-5.6.35版本)

MVCC(多版本併發控制機制)

隔離性也可以被稱作併發控制、可串行化等。談到併發控制首先想到的就是鎖,MySQL通過使用兩階段鎖的方式實現了更新的可串行化,同時為了加速查詢性能,採用了MVCC(Multi Version Concurrency Control)的機制,使得不用鎖也可以獲取一致性的版本。

Repeatable Read

MySQL的通過MVCC以及(Next-Key Lock)實現了可重複讀(Repeatable Read),其思想(MVCC)就是記錄數據的版本變遷,通過精巧的選擇不同數據的版本從而能夠對用戶呈現一致的結果。如下圖所示:

上圖中,(A=50|B=50)的初始版本為1。
1.事務t1在select A時候看到的版本為1,即A=50
2.事務t2對A和B的修改將版本升級為2,即A=0,B=100
3.事務t1再此select B的時候看到的版本還是1, 即B=50
這樣就隔離了版本的影響,A+B始終為100。

Read Commit

而如果不通過版本控制機制,而是讀到最近提交的結果的話,則隔離級別是read commit,如下圖所示:

在這種情況下,就需要使用鎖機制(例如select for update)將此A,B記錄鎖住,從而獲得正確的一致結果,如下圖所示:

MVCC的優勢

當我們要對一些數據做一些只讀操作來檢查一致性,例如檢查賬務是否對齊的操作時候,並不希望加上對性能損耗很大的鎖。這時候MVCC的一致性版本就有很大的優勢了。

MVCC(實現機制)

本節就開始談談MVCC的實現機制,注意MVCC僅僅在純select時有效(不包括select for update,lock in share mode等加鎖操作,以及update\insert等)。

select運行棧

首先我們追蹤一下一條普通的查詢sql在mysql源碼中的運行過程,sql為(select * from test);

其運行棧為:

handle_one_connection  MySQL的網絡模型是one request one thread
 |-do_handle_one_connection
	|-do_command
		|-dispatch_command
			|-mysql_parse	解析SQL
				|-mysql_execute_command
					|-execute_sqlcom_select	執行select語句
						|-handle_select
							...一堆parse join 等的操作,當前並不關心
							|-*tab->read_record.read_record 讀取記錄

由於mysql默認隔離級別是repeatable_read(RR),所以read_record重載為
rr_sequential(當前我們並不關心select通過index掃描出row之後再通過condition過濾的過程)。繼續追蹤:

read_record
 |-rr_sequential
	|-ha_rnd_next
		|-ha_innobase::rnd_next 這邊就已經到了innodb引擎了
			|-general_fetch
				|-row_search_for_mysql
					|-lock_clust_rec_cons_read_sees 這邊就是判斷並選擇版本的地方

讓我們看下該函數內部:

bool lock_clust_rec_cons_read_sees(const rec_t* rec /*由innodb掃描出來的一行*/,....){
	...
	// 從當前掃描的行中獲取其最後修改的版本trx_id(事務id)
	trx_id = row_get_rec_trx_id(rec, index, offsets);
	// 通過參數(一致性快照視圖和事務id)決定看到的行快照
	return(read_view_sees_trx_id(view, trx_id));
}

read_view的創建過程

我們先關注一致性視圖的創建過程,我們先看下read_view結構:

struct read_view_t{
	// 由於是逆序排列,所以low/up有所顛倒
	// 能看到當前行版本的高水位標識,>= low_limit_id皆不能看見
	trx_id_t	low_limit_id;
	// 能看到當前行版本的低水位標識,< up_limit_id皆能看見
	trx_id_t	up_limit_id;
	// 當前活躍事務(即未提交的事務)的數量
	ulint		n_trx_ids;
	// 以逆序排列的當前獲取活躍事務id的數組
	// 其up_limit_id<tx_id<low_limit_id
	trx_id_t*	trx_ids;	
	// 創建當前視圖的事務id
	trx_id_t	creator_trx_id;
	// 事務系統中的一致性視圖鏈表
	UT_LIST_NODE_T(read_view_t) view_list;
};

然後通過debug,發現創建read_view結構也是在上述的rr_sequential中操作的,繼續跟蹤調用棧:

rr_sequential
 |-ha_rnd_next
 	|-rnd_next
 		|-index_first 在start_of_scan為true時候走當前分支index_first
 			|-index_read
 				|-row_search_for_mysql
 					|-trx_assign_read_view

我們看下row_search_for_mysql里的一個分支:

row_search_for_mysql:
// 這邊只有select不加鎖模式的時候才會創建一致性視圖
else if (prebuilt->select_lock_type == LOCK_NONE) {		// 創建一致性視圖
		trx_assign_read_view(trx);
		prebuilt->sql_stat_start = FALSE;
}

上面的註釋就是select for update(in share model)不會走MVCC的原因。讓我們進一步分析trx_assign_read_view函數:

trx_assign_read_view
 |-read_view_open_now
 	|-read_view_open_now_low

好了,終於到了創建read_view的主要階段,主要過程如下圖所示:

代碼過程為:

static read_view_t* read_view_open_now_low(trx_id_t	cr_trx_id,mem_heap_t*	heap)
{
	read_view_t*	view;
	// 當前事務系統中max_trx_id(即尚未被分配的trx_id)設置為low_limit_no
	view->low_limit_no = trx_sys->max_trx_id;
	view->low_limit_id = view->low_limit_no;
	// CreateView構造函數,會將非當前事務和已經在內存中提交的事務給剔除,即判斷條件為
	// trx->id != m_view->creator_trx_id&& !trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)的
	// 才加入當前視圖列表
	ut_list_map(trx_sys->rw_trx_list, &trx_t::trx_list, CreateView(view));
	if (view->n_trx_ids > 0) {
		// 將當前事務系統中的最小id設置為up_limit_id,因為是逆序排列
		view->up_limit_id = view->trx_ids[view->n_trx_ids - 1];
	} else {
		// 如果當前沒有非當前事務之外的活躍事務,則設置為low_limit_id
		view->up_limit_id = view->low_limit_id;
	}
	// 忽略purge事務,purge時,當前事務id是0
	if (cr_trx_id > 0) {
		read_view_add(view);
	}
	// 返回一致性視圖
	return(view);
}

行版本可見性:

由上面的lock_clust_rec_cons_read_sees可知,行版本可見性由read_view_sees_trx_id函數判斷:

/*********************************************************************//**
Checks if a read view sees the specified transaction.
@return	true if sees */
UNIV_INLINE
bool
read_view_sees_trx_id(
/*==================*/
	const read_view_t*	view,	/*!< in: read view */
	trx_id_t		trx_id)	/*!< in: trx id */
{
	if (trx_id < view->up_limit_id) {

		return(true);
	} else if (trx_id >= view->low_limit_id) {

		return(false);
	} else {
		ulint	lower = 0;
		ulint	upper = view->n_trx_ids - 1;

		ut_a(view->n_trx_ids > 0);

		do {
			ulint		mid	= (lower + upper) >> 1;
			trx_id_t	mid_id	= view->trx_ids[mid];

			if (mid_id == trx_id) {
				return(FALSE);
			} else if (mid_id < trx_id) {
				if (mid > 0) {
					upper = mid - 1;
				} else {
					break;
				}
			} else {
				lower = mid + 1;
			}
		} while (lower <= upper);
	}

	return(true);
}

其實上述函數就是一個二分法,read_view其實保存的是當前活躍事務的所有事務id,如果當前行版本對應修改的事務id不在當前活躍事務裏面的話,就返回true,表示當前版本可見,否則就是不可見,如下圖所示。

接上述lock_clust_rec_cons_read_sees的返回:

if (UNIV_LIKELY(srv_force_recovery < 5)
			    && !lock_clust_rec_cons_read_sees(
				    rec, index, offsets, trx->read_view)){
	// 當前處理的是當前版本不可見的情況
	// 通過undolog來返回到一致的可見版本
	err = row_sel_build_prev_vers_for_mysql(
					trx->read_view, clust_index,
					prebuilt, rec, &offsets, &heap,
					&old_vers, &mtr);			    
} else{
	// 可見,然後返回
}

undolog搜索可見版本的過程

我們現在考察一下row_sel_build_prev_vers_for_mysql函數:

row_sel_build_prev_vers_for_mysql
 |-row_vers_build_for_consistent_read

主要是調用了row_ver_build_for_consistent_read方法返回可見版本:

dberr_t row_vers_build_for_consistent_read(...)
{
	......
	for(;;){
		err = trx_undo_prev_version_build(rec, mtr,version,index,*offsets, heap,&prev_version);
		......
		trx_id = row_get_rec_trx_id(prev_version, index, *offsets);
		// 如果當前row版本符合一致性視圖,則返回
		if (read_view_sees_trx_id(view, trx_id)) {
			......
			break;
		}
		// 如果當前row版本不符合,則繼續回溯上一個版本(回到for循環的地方)
		version = prev_version;
	}
	......
}

整個過程如下圖所示:

至於undolog怎麼恢復出對應版本的row記錄就又是一個複雜的過程了,由於篇幅原因,在此略過不表。

read_view創建時機再討論

在創建一致性視圖的row_search_for_mysql的代碼中

// 只有非鎖模式的select才創建一致性視圖
else if (prebuilt->select_lock_type == LOCK_NONE) {		// 創建一致性視圖
		trx_assign_read_view(trx);
		prebuilt->sql_stat_start = FALSE;
}

trx_assign_read_view中由這麼一段代碼

// 一致性視圖在一個事務只創建一次
if (!trx->read_view) {
		trx->read_view = read_view_open_now(
			trx->id, trx->global_read_view_heap);
		trx->global_read_view = trx->read_view;
	}

所以綜合這兩段代碼,即在一個事務中,只有第一次運行select(不加鎖)的時候才會創建一致性視圖,如下圖所示:

筆者構造了此種場景模擬過,確實如此。

MVCC和鎖的同時作用導致的一些現象

MySQL是通過MVCC和二階段鎖(2PL)來兼顧性能和一致性的,但是由於MySQL僅僅在select時候才創建一致性視圖,而在update等加鎖操作的時候並不做如此操作,所以就會產生一些詭異的現象。如下圖所示:

如果理解了update不走一致性視圖(read_view),而select走一致性視圖(read_view),就可以很好解釋這個現象。
如下圖所示:

總結

MySQL為了兼顧性能和ACID使用了大量複雜的機制,2PL(兩階段鎖)和MVCC就是其實現的典型。幸好可以通過xcode等IDE進行方便的debug,這樣就可以非常精確加便捷的追蹤其各種機制的實現。希望這篇文章能夠幫助到喜歡研究MySQL源碼的讀者們。

公眾號

關注筆者公眾號,獲取更多乾貨文章:

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

印度學者:中國築壩正破壞喜馬拉雅生態

摘錄自2018年8月27日中央社報導

印度新德里政策研究中心戰略研究教授切拉尼(Brahma Chellaney)表示,喜馬拉雅生態系統日漸脆弱,雖然在這一地區大規模資源濫採的國家都應受到譴責,「但沒有一個國家像中國,對喜馬拉雅造成如此嚴重的破壞」。

切拉尼撰文寫道,亞洲的未來與喜馬拉雅山的關係緊密,但人類卻大規模建設水壩且肆無忌憚地開採資源,破壞當地生態系統,其中中國透過築壩改造天然河流,卻有愈來愈多工程引水項目集中在國外,而非內部河流。以喜馬拉雅冰川地區來說,目前中國造壩已覆蓋近3/4的青藏高原。

針對中國行徑,切拉尼還指出2點,一是中國想在青藏高原乾旱的北部和西北部製造人造雨,外界擔心此舉會吸走喜馬拉雅其他地區(西藏的降雨集中地)的水分;另一是中國大肆開發礦產資源,如開發銅礦的行動已汙染藏族的Pemako(隱藏的蓮花地)地區。

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

【其他文章推薦】

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

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

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

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

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

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

考量經濟 梅克爾反對歐盟拉高減碳目標

摘錄自2018年8月27日中央社報導

德國總理梅克爾今天(27日)表示,世界各地極端天候頻傳,充分證明氣候變遷已是事實。不過她反對為保護氣候拉高減少溫室氣體排放門檻,指此舉沒太大意義。

路透社報導,北半球今夏的炙熱高溫,引發外界憂心氣候變遷的現象正加速發生,歐洲數十個國家都呼籲,減少溫室氣體排放量的速度,應要比原訂目標更快。

歐洲聯盟(EU)執委會主管氣候行動與能源事務執委卡尼特(Miguel Arias Canete)呼籲將2030年之前溫室氣體減量目標,從40%提高至45%。

但梅克爾(Angela Merkel)表示,加速減少有害的二氧化碳排放量恐適得其反,況且歐洲各國此際對達成原訂目標都很吃力,再要拉高門檻沒有道理。

她說:「我對這些新提議尤其不怎麼高興。我認為應先堅守既定目標。我不認為一直設定新目標有任何意義。」

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

如果你對自己有要求 | “回顧,再出發”——記2020軟工提問回顧與個人總結

回顧,再出發

項目 內容
這個作業屬於哪個課程 2020春季計算機學院軟件工程(羅傑 任建)
這個作業的要求在哪裡 提問回顧與個人總結
我在這個課程的目標是 完成一次完整的軟件開發經歷
並以博客的方式記錄開發過程的心得
掌握團隊協作的技巧
做出一個優秀的、持久的、具有實際意義的產品
這個作業在哪個具體方面幫助我實現目標 為自己一學期的努力畫上句號
對下一個階段的展望

作業要求:

  • 鏈接到以前提問題的博客
  • 請嘗試對自己曾經提出的問題進行解答,並闡明,是如何通過看書,實踐,或者討論弄清楚的。
  • 是否原來的問題還不明白?如果有,請分析。
  • 是否產生了新的問題?如果有,請提出。
  • 軟件工程這門學問有很多 “知識點”, 這門課強調 “做中學” – 在實踐中學習知識點。
    • 請問你們在項目的 需求/設計/實現/測試/發布/維護階段(一共6 個階段)中都學到了什麼“知識點”,每個階段只要說明一個知識點即可。
  • 結合自己在個人項目/結對編程/團隊項目的經歷,談談自己的理解或心得。

​ 2020年3月3日下午16:48,在博客園發表了本學期軟件工程的第零篇博客——停下來,回頭看 ——記2020BUAA軟工第一次作業-熱身! ,1萬5千字的長文收穫了1256次閱讀和6個評論,其中ScalersTalk作者Scalers專門註冊了博客園在我的評論下方留言回復2500字,令我備受鼓舞,還有鄒欣老師和寶玉老師的建議我牢記在心,mio4學長的經驗之談也對我很大啟發。懷着對所有閱讀過我的文章和評論我的文章的人的感激,踏上了軟件工程的學習道路。

​ 2020年3月8日臨晨2點56分,發出了軟件工程這門課正式的第一篇博客——初窺構建之法——記2020BUAA軟工個人博客作業 ,這片博客中都是在閱讀完鄒欣老師的《構建之法》后,對書中存疑的地方提出的問題,並加入自己的思考和理解。這片博客收穫了594次閱讀9條評論,有其他學校的軟件工程老師,還有仰慕已久的SivilTaram學長在我的博客下留言。最令我沒有想到的是,負責鄒欣老師的《構建之法》和吳軍博士的《浪潮之巔》出版的周筠老師聯繫了我,加了我的微信,帶我走進了大神們的世界,周筠老師的群聊中有吳軍博士,有輪子哥,還有各行各業的優秀人士,看着他們在群里的討論愈發能夠感受到自己所學和認識的狹隘,除了自己的學習之外,還需要更多的與優秀的人的交流,在交流中增長自己的眼界。為了完成這篇博客,我將《構建之法》每一個章節都進行了閱讀,書中還有很多博客的鏈接我也大多點開來看,對於提出的問題也事先在網上做了充分的調查和搜尋,給出了自己的理解和嘗試性的解答。雖然一周的閱讀時間很短,但是這個過程真的十分漫長,看完《構建之法》感覺自己在理論上已經開始嘗試着從軟件工程的思維去思考問題。特別是對PM的章節,除了書之外還搜索了很多地方關於Program Manager和Product Manager的區別,並嘗試着將自己代入體驗。

​ 2020年3月10日下午18:59,發布了“深度評測官”——記2020BUAA軟工軟件案例分析作業,對候選素材中最難啃的OCR識別表單的開源工作進行了測評,做第一個吃螃蟹的人,後面總結了經驗推廣開來,陸續也出現了幾篇OCR的測評,收穫了1754次閱讀,成為了後面團隊開發時的產品介紹。在這次作業中,開始體會軟件之間的差異,開發軟件需要側重什麼,什麼樣的軟件是一款優秀的軟件。

​ 2020年03月21日,我和我的組員拼裝成了一個團隊,並給我們的團隊發布了第一篇博客——“介紹一下自己吧”——記2020BUAA軟工團隊介紹和採訪:

我們是 BUAA軟軟軟件工程小隊 ,簡稱 軟軟軟,但是大家也可以看到我們的博客的 TITLE 是 HARD_CORE_SE,指的是 “硬核的軟件工程” ,軟軟軟其實是希望我們遇到硬核的軟件工程也可以 化硬為軟,直面困難,在我們的眼裡沒有 硬核 二字,一切困難在團隊面前都是紙老虎!
雖然我們都沒有大型的工程經驗,是一直拼裝起來的軍隊,但是我們相信通過我們團隊的配合一定能夠在軟件工程這門課中發揮出色,不只是取得成績,而且能做出像樣的、能流傳的、實用的項目出來。

​ 雖然當時我們還沒有選好題目,但是我們核心的目標已經確定——做出像樣的、能流傳的、實用的項目出來。

​ 2020年4月1日,我們團隊發布了項目選擇博客——“媽媽再也不用擔心我忘交作業了!”——記2020BUAA軟工團隊項目選擇,結合本學期的疫情分析了同學們的痛點,決定開發一款幫助同學規劃提醒日程的Web應用,而我作為想出這個點子的人,對這個應用有什麼頁面,有什麼功能,能夠實現什麼最為清楚,因此成為了團隊的負責人。

​ 2020年5月5日,修復完所有的Bug、走過不知道多少次流程,我們確定首次公開發布我們的產品——DDLKiller,一款專門面向北航本科生設計的日程提醒助手,並在朋友圈,班級微信群,QQ群等小範圍內進行推廣:

​ 從後台統計數據來看,發布第一天註冊用戶達到77人,第二天達到148人,僅僅使用两天的時間就已經超額完成預期的100人,並且從反饋來看,同學們對這一款簡潔美觀、功能強大的日程管理助手非常滿意,並且积極給我們提供反饋意見,幫助我們在Beta階段做的更好。

​ 第一次發布說實話是非常忐忑的,我們熬了無數個夜晚,開了無數的視頻會議,做了無數次測試的軟件,突然開放給大家,不知道大家是喜愛,還是無感,我們當天晚上守在後台,看着註冊登錄的日誌,看着註冊的人數一個一個往上漲,一個一個開始新建事項,使用我們的功能,守到過了午夜1點仍然沒有異常,我們的心才放了下來,大家相互鼓勵,洗洗睡了。

​ 2020年6月2日,又經過一輪的迭代,我們發布了Beta版本的DDLKiller,雖然是6月2日發布,但是用戶們早已體驗過新的功能,結合很多人性化的新功能進行二次推廣,用戶量達到240人,相比Alpha階段增長90人。後來經過最後一次項目展示答辯,我們的軟件工程這門課程,結束了。

​ 但DDLKiller還沒有結束,就像我們UltraSoft – Beta – Postmortem事後分析中所說的:

BUAA – UltraSoft – 軟軟軟小組 2020春大三下學期的軟件工程, 全劇終。

但我們DDLKiller的故事還在繼續,不要走開,馬上回來

​ 我們還留了兩個功能沒有實現,我們感受到了大家對客戶端和小程序的呼聲,我們希望在自己的大學生涯中,甚至在未來的生活中,依然繼續使用這款我們親手打磨,親手建設的產品,說實在的,我們還挺不捨得的。雖然在專業人士的眼中看來這個實現非常簡單,可能一個前端大神两天就能做完的事情,一個後端大神一天就能寫完的東西,我們卻花了整整一個學期。

​ 可是,我們在這個學期裏面不是學習的如何寫前端,如何使用Vue,不是學習如何寫後端,如何使用Django,我們團隊的賬號發表了39篇博客,技術博客都是在我們的個人賬號中發表,這說明什麼,團隊博客中所記錄的,是實實在在的軟件工程。那一篇篇設計與規劃、Scurm Meeting、發布說明、測試報告、項目展示、事後分析,是DDLKiller像一個新生兒一樣,成長的記錄。

​ 我們學會了團隊成員之間如何高效合作,我們學會了如何使用Github、Gitee管理團隊項目,我們學會了使用MockPlus設計產品原型,我們學會了如何權衡需求和實際。確實專業的工程師照着我們的網站實現一個是很快,但是他可能很難做到從0到1的過程。他沒有進行痛點的分析,他不知道用戶真正需要什麼,他沒有一個需求和實際使用之間的權衡,他的開發確實了團隊協作的樂趣。

​ 說實話剛開始團隊開發的時候我還是不習慣多人協作,覺得一個人做完了事就可以省去交流的時間,後來我才發現不是我不會開發,是我不會交流。我們團隊後期自研創新的交流方式非常高效,一個石墨文檔把鍋和坑明確到人,每個人不需要問自己需要干什麼,還可以干什麼;一天十幾個小時在線的騰訊會議,有問題直接進來說,語音來的總比打字快,共享屏幕來的總比截圖直接。大家高效交流之後整個難度就下來了,只要說好了誰負責開發什麼模塊,最晚什麼時候需要驗收,還有不懂的我們共享屏幕聊,幾乎不會產生歧義或者推鍋的情況出現。作為一個PM我的體會最深:在Alpha階段的前期由於缺乏有效的溝通,PM和組員都很累,每個人都有點不清楚自己要干什麼,我知道大家要干什麼卻不能很好布置下去,每天群里的提問和回答帶來的卻只有效率的低下,我也想着自己一個人做好就算了,要那麼多人干什麼,但也發現自己越是想全部做完做好越是什麼都做不完做不好。這是一段非常難忘的經歷,是軟件工程這門課提供給我的,給了我一個在步入社會前體驗社會毒打的經歷,幸好是在課內體會到的,不至於“死”得太慘。

​ 回首望去,覺得這學期很長,也不知道是不是疫情在家的緣故,還是無窮無盡的騰訊會議的緣故,雖然只過了3個月,但是感覺自己做了很多事情一樣。3個月後再看自己的第一篇博文,確實有了些不一樣的體會。

回答自己

​ 在初窺構建之法——記2020BUAA軟工個人博客作業中,我提出了七個小問題,其實在當時已經回答的差不多了,但現在有了一定的軟件工程經驗之後,又有了一點小的看法。

問題一:是否真的沒有銀彈

​ “把重點放在質量上,生產力將隨之而來”,這是Jones的觀點。基於這個觀點我當時提出了這樣的觀點:

我之所以對銀彈是否存在持有懷疑態度是因為在大環境下,有一些本可以提高的生產力沒有提高,還有很多團隊會出現文檔與實現分離的情況,出現進度卡在某一個人負責的環節的情況,這些情況都是我們會在後續的團隊編程中可能會遇到的,所以我覺得現在就應該思考,如何在團隊中破除沒有銀彈的詛咒,提升團隊的整體水平和能力。

​ 我們團隊的生產力就有一個拐點,從一開始的效率低下到後來的慢慢摸索再到後來形成體系之後組員們心照不宣。是否真的沒有銀彈?我們組可能找到了自我協作的方式,充分將每個人的能力在其崗位上發揮,做到了效率的最大化和能力發揮的最大程度,整體生產力得到了提高,是否一定程度上找到了銀彈?

​ 其實大家都在尋找屬於自己的“銀彈”,我看到每個小組都有自己組內的成熟的管理機制和協作方法,大部分是Github的Issue和Pull Request,還有一個Github的看板,還有一些在線文檔。並沒有說Github上面使用的管理方式就比石墨文檔更有技術,我們團隊覺得上Github的速度太慢,石墨文檔就能很好的解決我們的問題,也可以定位到人,還有具體的任務細節:

Beta階段開發明顯更加得心應手一些,外加Gitee上面的清晰的Issue和Pull Requests:

無論是對內的石墨文檔還是對外的Gitee,都對我們的實際開發極大提高了生產力。

問題二:如何選擇合適的團隊模式

當時鄒欣老師給到我的回答是:

想請教老師和助教,業餘劇團模式的具體形式能夠結合助教的經歷或是老師的觀察給一個更加清晰的講述嗎?

就是大家可以選擇各種角色來扮演, 在下一個項目中,又可以有全新的分配方式。
你們就是用‘業餘’ 時間來開發的, 比較適合這樣的模式。

​ 在實際的開發中,我們確實也是業餘劇團的模式,大家先分好了大方向,前端和後端,然後分配一個模塊的任務吧,如日曆視圖、課程視圖等,如數據庫、爬蟲等,在實際的開發中,主體上不太發生改變,在細分的任務上比較靈活自由。特別是在Alpha發布之後,項目已經成型,大家已經不再限制於模塊的開發,細化到功能的開發,比如要實現一個快速創建的功能,可以在日曆中,也可以在日程列表中,兩個都進行添加。甚至前端的同學可以來優化一下後端的代碼,後端的同學學習一下前端的實現,都是“互通有無”的。

問題三:每日例會的效果如何?

在這個問題下面我當時又提出了一個問題:

敏捷開始是否是一個偽命題?

當時找到了Vczh輪子哥的回答:

敏捷不是一群開發者對着甲方的第一版需求猛做幾天,而是在做的過程中始終和甲方進行有效的、不間斷的溝通,來幫助甲方更加清晰地認清自己的需求,也幫助整個團隊確定一個當前的完成進度,也就是一個迭代中的需求分析和驗收

​ 經過兩輪的迭代和20餘次的Scrum Meeting,感受到了一些敏捷開發的意義:雖然我們沒有甲方,但是我們自己就是自己的甲方,我們不斷反省和思考着自己需要什麼功能,自己不需要什麼功能,認清自己的需求,掌握團隊的進度,不斷驗收。

​ 每日例會一開始是拒絕的,我們在Alpha階段還弄錯了例會的時間,導致缺少兩篇,覺得這些東西在Github上都有,為什麼還要記錄呢?後來其實發現每日例會重要並不在於記錄,其一在於每日隱隱地督促着每一個成員,“今晚要彙報,自己做了什麼?”;其二在例會,一個常規的,團隊的固定“節目”,有例會才像是一個成熟的團隊而不是一個個散兵,在例會中大家可以找到歸屬感,大家可以有問題在例會中大膽提出來,有什麼想法提出來大家一起實現,有什麼功能其實沒有什麼用大膽刪去,例會還是一個平台,提供給大家自由說話、表達意見和想法的平台,在例會中每個人都有說話的權利,每個人的話都能被所有人所聽見,這是我理解的每日例會的意義。至於效果,見仁見智吧,我們團隊的例會效果我還是比較滿意的,大家都有準時參与,都敢說,都是為了我們DDLKiller更好的發展去說。

問題四:為什麼除了微軟很少見到Program Manager

​ 當時我其實沒有找到這個問題合適的答案,也是遺留了下來,自己作為這個學期軟軟軟團隊的PM,無論是Product Manager也好還是Program Manager也好,談一下自己的看法。

​ 很多地方都在吐槽產品經理,說產品經理不管需求是否能夠實現,產品經理是程序員的天敵諸如此類,無非就是在說產品經理不動技術,只懂調研和分析需求。作為我們團隊的PM,我也參与了調研,我也確定了產品的需求,但我也在我的崗位——後端、部署、測試上工作,所以當我有新的需求的時候,作為一名程序員,我也會要麼憑藉自己的經驗對需求的實現難度進行預估,要麼根據已經實現了的功能對需求進行預估。比如臨時加入一個消息中心,我其實也是從前端小白到了解了一點前端的知識,我知道這個功能並不麻煩,前後接口一設置分別實現就行了,所以大膽的安排了下去這個臨時的任務,我得力的組員也很快完成了,經過我的連接和測試,一天內用我們的“業餘”時間就上線了這個功能,提供了極大的便捷。

​ 至於為什麼除了微軟很少見到Program Manager,希望我能夠親身去微軟和其他公司體驗一下吧。

問題五:對於小團隊而言小強地獄是否可行?

​ “小強地獄”聽着特別可怕,但其實在我們的實際開發中沒有太多遇到,首先是代碼總量不大,經過幾次定位就可以找到問題所在;其次是我們保證了合併進入主分支錢經過“充分”的測試,這裏的充分之所以打上引號是因為100%的充分並不存在,就像我們的同步課程中心的爬蟲核心功能,在我們團隊的幾個人的賬戶上測試都沒有出現問題,結果小範圍的內測立刻炸鍋,趕忙修復然後加大內測的範圍,在幾輪的測試都無誤之後我們才正式上線功能,這也是為什麼我們發布比較晚的原因。

​ 我們團隊也並沒有測試這個職位,大家前端和後端自己先測試自己的代碼,然後連接的時候再測試連接的代碼,不需要不參与開發的人去讀代碼,只要提供充分的測試樣例就行了。小團隊連開發都人數有些不夠,在項目的尾期設置專門進行覆蓋性測試的測試人員即可,這種開發方式在我們的項目中並沒有出現什麼大礙,所以小強地獄這種東西,只是一個提出來的權衡feature和bug的模式,每個團隊可以根據自己的實際情況進行調整。

問題六:迷思之六:技術的創新是關鍵?

​ 我們的項目有創新嗎?可以說有:我們使用郵件給用戶進行提醒,只要有網就能收到提醒;也可以說沒有,有一部分的用戶是被我們的美觀的界面吸引過來的,可能並沒有使用郵件的功能,而且其實我們的產品有類型的原型——Microsoft的ToDo。但是我們創新性地將同學們的所需以一個更好的形式呈現了出來,進行了高度集成再展現的過程,這也不失為一種創新。

​ 我們在開發的時候想過創新嗎?說實話我沒有。用戶在使用到這樣一款產品的時候會主動想到有什麼創新嗎?可能也沒有。無論是開發者還是使用者,大家都在關注一樣東西——是否解決痛點。我們可能從來沒有想過郵件提醒是一種創新,靈感來源於博客園的作業提醒,我們想的是如何解決用戶沒有在日程的DDL前被提醒的痛點,郵件只是解決這個痛點的一個可行方式罷了。

​ 我不是在否認創新的重要性,只是在說有的軟件可能目的不在於創新,也能夠贏得大家的喜愛。新鮮感固然是好東西,但是新鮮感不能持久,當新鮮感褪去,用戶是否還會對我們的產品滿意?是否會選擇其他更具有新鮮感的東西?這些是根據用戶的需求是否被解決所決定的,也是一個產品的核心部分,真正被考量的部分。

問題七:最難的問題——排座次

​ 當時提出這個問題時,還是太嫩了,其實排座次在實際執行起來是整個開發中最簡單的事情,就像鄒欣老師說的,有的人想得60分有的人想得90分,根據大家的Pull Requests和實現的功能的工作量就可以看出來。我們團隊的成員大家都非常积極,甚至主動找我領取任務,所以在最後的打分大家都差不多;其他組比如NAG2020就可以看到,其中有一名成員就是想拿60分的,兩個階段的貢獻分都是最低,代碼貢獻也是最少,自然就給了最少的分數。

​ 使用Gitee、Github等項目管理軟件之後,每個人的积極程度、活躍程度、項目的貢獻量都一目瞭然,所以排座次的問題,客觀公平公正得到了解決。

新的問題

​ 疫情之下,我們體驗到了全新的軟件工程,可能我們是唯一一屆在線上開展軟件工程這門課的學生,我們線上開會,線上協作,線上發布,線上展示。Work From Home 成了疫情中主流的工作方式。之前看到Vue的開發團隊就是分佈在世界的各個角落,線上交流和協作維護,他們已經形成了一種十分成熟的WFH的工作方式。

​ 試想,在WFH是否會成為未來的發展方向?特別是對於程序員而言,WFH其實可以在不影響開發的前提下能節省很多的時間,如通勤等等,很多大公司已經或者開始嘗試WFH,包括美國的巨頭Google、Facebook、Twitter等等,請問老師和助教覺得,本學期的WFH與之前學期的線下軟工有什麼區別,有意料之外的提高嗎?

“做中學”

需求階段

學會取捨:衝刺只有兩周,而且我們是業餘開發,所以不可能將所有的功能都實現,甚至在Alpha階段我們僅有的反饋中有一項是希望在課程列表中加入測試模塊,這個想法在Beta設計與規劃前是列入到了Todo List中的,然而在Beta設計與計劃實際的權衡中我們將其丟棄了,替換為了課程的通知,因為通知使用的更多,幾乎每門課都有,而測試只有少量的一兩門課有。

設計階段

顏值即正義:一款顏值高的產品不一定是最好的但一定是最吸引用戶的,我們的Web程序也是因高顏值吸引了不少用戶,大家對於課程中心陳舊的排版感到視覺疲勞的時候看到我們的產品會眼前一亮從而想要體驗,這是在推廣階段特別重要的一點。

實現階段

考慮可擴展性、注意代碼風格:以我負責的後端爬蟲來說,從開始時的只爬取課程作業和課程資源到迭代中加入爬取課程通知再到期末季中爬取考試日程安排,這幾樣東西應該做到合理歸類與分離,以免造成代碼太過臃腫接手的人難以及時上手。

測試階段

回歸測試和覆蓋測試的重要性:在發布新功能時,要一併考慮到舊有功能是否正常運行,我們在迭代中就遇到這樣的問題,比如在Beta階段我們支持了重複日程的提醒,向日程中加入了字段 repeat,然而我們只測試了常規的添加日程,沒有考慮下方的快速添加日程和模板添加日程,導致發布之後出現內部錯誤,檢查日誌才發現錯誤所在然後緊急修復。如果每個新功能在發布的時候都能夠有回歸測試則可以避免這一問題。

發布階段

漸進式發布:當一個應用的新功能準備發布的時候,會進行一些測試,比如灰度測試,即選取一小部分用戶可以體驗到該功能,其他用戶維持原來的功能不變,以查看新功能的運行效果和用戶反饋意見,在我們的開發中,我們有多台主機可以進行訪問,所以會先使用其他主機的ip訪問使用“內測版本”的DDLKiller,然後過一段時間再發布。在Alpha的正式發布前我們也做了小範圍的內測,讓一些自己的舍友和朋友先使用,看看有沒有問題,還有么改進的地方,確實內測找出了一些問題,幫助我們在正式發布的時候減少很多事情。

維護階段

文檔文檔文檔:經驗教訓是有心東西一定要以文字的形式在文檔中呈現,首先是提高了團隊內部的溝通效率,大家不用反覆詢問可以直接查閱文檔,其次是積少成多,為後面接手的同學做充足的準備。特別是前後端分離的團隊開發,只要文檔維護得好,直接事半功倍,反之事倍功半。

理解、心得

​ 個人項目->結對項目->團隊項目,是一個課程組有意設計的一個遞進的關係,在這一點上我覺得羅老師和任老師班級的軟工做的最好,相比於歐陽老師班級的個人項目直接到團隊項目,我們中間有一個過渡期,很多人其實在過渡期的時候就知道自己想要干什麼了,大致可以分為前端和後端了,這樣一來在團隊中的項目分工也簡便了很多。

​ 在個人項目中,我們實現了一個求交點的程序,沒有頁面显示,只有命令行的交互;在結對項目中,我們加大了求解交點的難度,同時用圖形化的界面將交點的位置呈現在了眼前;在兩個衝刺,前後兩個月的團隊項目中,我們分工更加細緻,實現了一個軟件。一步步走來,感覺越來越難了,但是也越來越簡單了。難在項目確實更大,從技術上來說難度確實增大了;簡單在我們不是一個人在戰鬥了,我們身邊從沒有人到一個人再到一群人,集體的力量是不容小覷的,每個人都有自己擅長的部分,這一點感觸特別深。在團隊中,一個人花了很久不能解決的事情,丟出來大家都积極主動伸出援手,一起將困難啃下來;在這個學期學習是在很累的時候,也是我們團隊的成員陪伴着我,在此感謝陪我熬夜最多的Kkkk,有時候大家就算不需要說話,只要會議室裏面有人,心靈就能得到慰藉——“我背後還有一個團隊”。

​ 在團隊項目中,我既是PM又是後端開發,還負責部署,這個工作可能比有的團隊PM只負責文書麻煩一些,但也暴露出來了一人多職的缺點。由於Alpha階段對時間的理解錯誤外加新項目開發難度大,導致Scrum Meeting有一兩次開會了但是沒有及時記錄導致會議紀要缺失的情況,還有就是寫完代碼之後沒時間寫文字了於是產生拖延,這一部分應該專人來記錄會好一些。在團隊項目階段確實學習到了很多新知識,無論是Django開發還是NGINX部署,都需要啃官方文檔,特別是NGINX和Uwsgi的兩個官方文檔還有不清楚的地方需要自己解決,在五一的五天假期連肝五天才總算把前後端連接和服務器部署徹底啃下來,終於在五一假期的尾聲進行小面積的推廣。這也讓我對網絡與系統這一方面產生了興趣,在暑假期間我會嘗試涉獵一些分佈式和網絡編程相關的內容,如果感興趣的話希望有機會往這方面發展下去。若是因軟件工程這門課能夠找到我自己的真實興趣所在,也是太值得了。

​ 作為PM,特別感謝我的軟軟軟團隊的隊友們,包括Alpha階段結束之後轉走的Dz,一樣非常感謝。是你們一起幫助我完成了我的一個想法,讓他不再是一個想法,成為了一個真正能夠使用,大家都可以使用,甚至受到好評的一款軟件。其實DDLKiller是我實在找不到一款可以提醒我日程的軟件下的“被迫選擇”,想要一款DDLKiller這個念頭在我剛開學的時候就有了,當時和舍友嘗試了Tower協作也不好用,嘗試了Microsoft的Todo也不好用,自己又開發不了,但是居然在團隊開發中被我們做出來了,和我預想的完全一致,甚至某些功能超出預期。是你們讓我第一次體會到想法到實現的喜悅,第一次切身體會到代碼的魅力,第一次感受到團隊的強大,體會到1+1+1+1+1+1+1>7。DDLKiller就是我的軟軟軟團隊的孩子,離不開每一個人的付出。

​ 我們在第一篇自我介紹中說到:

雖然我們都沒有大型的工程經驗,是一直拼裝起來的軍隊,但是我們相信通過我們團隊的配合一定能夠在軟件工程這門課中發揮出色,不只是取得成績,而且能做出像樣的、能流傳的、實用的項目出來。

​ 至少在我自己看來,我們已經成功了。

最後想說的

​ 大概的都說的七七八八了,若是要用幾個詞語總結這學期的軟件工程課程的話:

魔幻、刺激、充實、欣慰

​ 在每次的個人作業前面老師都讓我們寫下這門課程的目標,我寫的是:

完成一次完整的軟件開發經歷
並以博客的方式記錄開發過程的心得
掌握團隊協作的技巧
做出一個優秀的、持久的、具有實際意義的產品

​ 現在看來,我都已經做到了:

  • 一次完整的軟件開發經歷:從使用MockPlus畫出草圖,到真正用網址就能訪問

  • 博客團隊的開發:39篇團隊博客就在BUAA軟軟軟件工程小隊中

  • 團隊協作的技巧:我們甚至自研了石墨文檔+騰訊會議的創新性協作方式

  • 優秀的、持久的、具有實際意義的產品:DDLKiller——懂你的日程管家

    從UltraSoft – Beta – Postmortem事後分析中摘取一段話出來:

如果下一年有學弟學妹問我:軟件工程哪個老師的課好?

我會如實回答:如果你對自己有要求,如果你想這個學期不碌碌無為,如果你想學期結束收穫滿滿,如果你想逼自己一把,選擇羅傑、任健老師的班級吧。過程會很痛苦,你會看到別人都在玩的時候你在寫博客,你會看到別人開發的時候你在寫博客,你會看到別人只開發一次就結束的時候你在寫博客,你在開例會,你在Beta階段開發,但是當你的博客得到了老師的認可,得到了助教的讚賞,得到了《構建之法》作者鄒欣老師的點評,得到了輪子哥Vczh對你的提問的親自回復,得到了《持續行動》《刻意學習》作者Scalers為你特地開賬號的留言,你會感覺,這一切都值了。

​ 慶幸當初的自己沒有聽到負面的評論就退縮,堅持選擇了羅老師和任老師的班級,做出了像樣的東西。我確實心裏吐槽過博客,用心寫真的很累,每次博客能花上3~5個小時,每次都是動輒上萬字,但是確實寫完之後獲得了有意義的評論和建議心裏特別舒服,讓我受寵若驚的是第一次的Scalers為我註冊博客園賬號留言7500字,讓我感覺到自己的博客沒有白費。自己也是北航面向對象課程的助教,也能夠一定程度上理解老師和助教的良苦用心,很多東西學生在做的時候是會不理解甚至罵出聲的,但是做完之後又是另一種感受了,老師和助教只能委屈成為暫時的惡人,逼着同學去思考,逼着去寫下文字,逼着做看不到短期利益的事情,等待着一切都結束時候的理解。

​ 軟件工程這門課雖然結束了,但我們的軟件開發依然在繼續,回顧,為的是更好的出發。

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

【其他文章推薦】

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

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

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

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

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

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

聚甘新

ZooKeeper使用入門

ZooKeeper簡介

ZooKeeper是一個分佈式的,開源的分佈式應用程序協調服務,是Hadoop的子項目之一。它是一個為分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。

安裝ZooKeeper

操作系統要求

操作系統 客戶端 服務端 原生客戶端 附加組件
GNU/Linux 開發/生產 開發/生產 開發/生產 開發/生產
Solaris 開發/生產 開發/生產 不支持 不支持
FreeBSD 開發/生產 開發/生產 不支持 不支持
Windows 開發/生產 開發/生產 不支持 不支持
Mac OS X 開發 開發 不支持 不支持

軟件要求

Java 8及Java 11以上版本(Java 9和10不支持)

硬件要求

此硬件資源為官網推薦的配置,實際開發過程中不需要這麼大,筆者測試1核1G內存20G硬盤的虛擬機即可運行。

  • 2核
  • 2G內存
  • 80G硬盤

下載安裝並進行單點配置

  1. 下載頁面地址:https://zookeeper.apache.org/releases.html
  2. 官網只提供tar.gz格式的壓縮包,windows下載后按照zip之類的解壓方式可能會導致解壓后的包無法使用,筆者使用Git帶的命令行執行linux的解壓命令解壓后使用,如果沒有安裝Git則建議使用虛擬機安裝Linux使用。以下是正確解壓和錯誤解壓后的對比。

  1. 解壓后的ZooKeeper默認是無法執行的,需要進行配置,將 apache-zookeeper-3.6.1/conf/zoo_sample.cfg複製一份並重命名為zoo.cfg,沒什麼特殊需要裡邊的配置項默認即可,筆者因為是在windows下使用,所以將datadir修改了。配置文件項說明如下:
配置項 說明
tickTime ZooKeeper使用的時間,單位毫秒,一般用於心跳檢測,而ZooKeeper中的最小session超時時間是此項的兩倍
dataDir 保留內存數據庫快照的地址,如果不單獨指定,事務日誌也會記錄在此
clientPort 服務端監聽的端口號
initLimit 集群中的follower服務器與leader服務器之間初始連接時的最大心跳數
syncLimit 集群中follower服務器與leader服務器之間通訊時的最大心跳數
  1. 配置完成后即可在bin目錄下執行對應的文件啟動了,Windows下為zkServer.bat,Linux下為zkServer.sh

ZooKeeper應用

通過zkCli進行使用

  1. ZooKeeper啟動后,可以通過bin目錄下自帶的客戶端進行訪問,Windows下為zkCli.bat,Linux下為zkCli.sh
  2. 啟動時默認連接localhost:2181,如果有需要連接遠程或其他端口的情況,可以如下添加參數:
zkCli.sh -server IP:Port
  1. 進入客戶端后執行help(此處是一個隨意的指令,只要不是zkCli支持的操作都可以)可查看其支持的操作,關於所有操作的介紹請參考官方頁面:https://zookeeper.apache.org/doc/current/zookeeperCLI.html

  2. 常用操作介紹:

  • 查看節點信息,節點路徑不能以“/”結尾
ls /
ls /zookeeper
  • 創建一個節點
create /test
create /test/testa
  • 查看節點狀態
stat /test
stat /test/testa
  • 刪除節點
# 刪除單個空節點
delete /test/testa
delete /test

# 級聯刪除
deleteall /test

*退出客戶端

quit

通過ZooKeeper客戶端使用

因為筆者的第一開發語言是Java,這裏以Java為例。常用的ZooKeeper Java客戶端用zkclient和Apache Curator兩種。zkclient是github上的一個開源項目,該項目在2018年10月2日後停止更新;Apache Curator是Apache基金會的開源項目,目前持續更新,推薦使用。常用的分佈式RPC框架DUBBO也在2019年1月份推出的2.7.0版本中將默認的ZooKeeper客戶端由zkclient切換為Apache Curator,此文中的示例也使用Apache Curator。

  1. 創建一個Maven項目,然後在pom.xml中引用Apache Curator,以下是筆者的文件內容,除了Apache Curator外添加了測試使用的junit並設置了編譯使用的java版本。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>apache-curator</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.3.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.6.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  1. 之後在src\test\java\目錄創建com\aotian\curator\test\Tester.java,文件基本框架如下,主要是創建一個空的測試類
public class Tester {

    @Test
    public void testCurator() {
      
    }

}
  1. 接下來就是使用Apache Curator提供的API對ZooKeeper進行訪問了。首先介紹下常用的API
  • 創建客戶端
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
curatorFramework.start();
  • 檢查節點是否存在,存在的話返回Stat對象,不存在則返回null
curatorFramework.checkExists().forPath("/localhost/aotian");
  • 創建節點,forPath第二個參數可以指定節點內容,不設置時創建空節點
curatorFramework.create().creatingParentContainersIfNeeded().forPath("/localhost/aotian", message.getBytes());
  • 設置節點內容,僅適用於已存在的節點,否則會報錯
curatorFramework.setData().forPath("/localhost/aotian", message.getBytes());
  • 獲取節點信息,以下代碼錶示將獲取的節點信息保存到result對象。
Stat result = new Stat();
curatorFramework.getData().storingStatIn(result).forPath("/localhost/aotian");
  • 獲取節點內容
byte[] results = curatorFramework.getData().forPath("/localhost/aotian");
  1. 完整示例如下,結尾添加了線程睡眠的代碼,可以在睡眠時間內通過zkCli查看服務端中的內容。
    @Test
    public void testCurator() {
        // 創建客戶端
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
        curatorFramework.start();
        // 定義節點內容
        String message = "testCurator";
        try {
            // 判斷節點是否存在不存在則創建,存在則設置指定值
            Stat a = curatorFramework.checkExists().forPath("/localhost/aotian");
            if (a == null){
                curatorFramework.create()
                        .creatingParentContainersIfNeeded()
                        .forPath("/localhost/aotian", message.getBytes());
            }else{
                curatorFramework.setData().forPath("/localhost/aotian", message.getBytes());
            }

            // 獲取節點信息
            Stat result = new Stat();
            curatorFramework.getData().storingStatIn(result).forPath("/localhost/aotian");
            System.out.println(result.getCtime());

            // 獲取節點內容
            byte[] results = curatorFramework.getData().forPath("/localhost/aoitan");
            System.out.println(new String(results));

            // 線程睡10S,這段時間內可以通過客戶端查看節點內的信息,結束后只能查看到空節點
            Thread.sleep(100000);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            curatorFramework.close();
        }
    }

ZooKeeper集群搭建

ZooKeeper集群中包含兩種角色:Leader和Follower,因為ZooKeeper集群是半數節以上節點正常時才會正常提供服務,所以一般ZooKeeper集群中節點數量均為奇數。我們按照最小數量算,準備三台zookeeper服務器。

  1. 分別按照本文一開始的單機配置配置好三個ZooKeeper服務。個人聯繫或可以在同一台機器上部署三個ZooKeeper,只要解決端口衝突問題即可,實際生產過程中務必使用三台機器進行搭建,否則一旦機器出問題則整個集群癱瘓。
  2. 準備好三台ZooKeeper服務器之後我們準備開始集群的配置,首先我們需要規劃好ZooKeeper的ID,然後在datadir屬性對應的目錄下創建一個myid文件。然後在文件內寫上當前服務對應的ID,筆者規劃的是0、1、2,所以我需要添加的配置文件如下:
IP地址 文件路徑 文件內容
192.168.142.7 /tmp/zookeeper/myid 0
192.168.142.8 /tmp/zookeeper/myid 1
192.168.142.9 /tmp/zookeeper/myid 2

datadir屬性默認在/tmp目錄下,此目錄會被定期清理掉,生產環境不要使用。

3、配置完以上文件后,需要配置之前的zoo.cfg,在最後添加以下內容,其中server.*對應myid文件中的ID號,192.168.142.7是IP地址,2888是ZooKeeper集群的通訊端口,3888是集群選取Leader使用的端口。

server.0=192.168.142.7:2888:3888
server.1=192.168.142.8:2888:3888
server.2=192.168.142.9:2888:3888

4、最後檢查防火牆是否開放了2181、2888、3888端口,確認開放后啟動ZooKeeper即可。通過執行zkServer.sh status命令可以查看當前機器的狀態。

[root@centos-server-01 bin]# ./zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/apache-zookeeper-3.6.0/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

[root@centos-server-02 bin]# ./zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/apache-zookeeper-3.6.0/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

聚甘新

Tesla 推出半掛電動卡車和新款 Roadster 超跑,性能爆表但量產能力依然受存疑

  2017 年 11 月 16 日電動車製造商 Tesla 在洛杉磯進行產品發表會,推出了首款半掛電動卡車,這款卡車在空載的狀況下 0 到 100 公里加速僅需 5 秒,續航達到了驚人的 800 公里,整體設計科技感十足,還加入自動輔助駕駛功能,可適應簡單路況的高速公路行駛需求,2019 年量產。在此次發表會上 Elon Musk 還給電動超跑的愛好者帶來了一個驚喜,Tesla 新款 Roadster 發表,這車款從時速 0 到 100 公里加速僅需要 1.9 秒,續航達到了 1,000 公里,預期在 2020 年上市。   Tesla 的電動卡車經過半年多的預熱宣傳終於在 11 月 16 日的發表會上亮相,該公司 CEO Elon Musk 乘坐全新的 Tesla 半掛卡車出場,全球最知名的電動車製造商開始進軍運輸市場。 Tesla 半掛電動卡車的性能非常驚人,在空載的狀況下 0 到每小時 100 公里加速僅需要 5 秒,相當於性能出眾的轎車水準,其他同類的卡車 0 到每小時 100 公里加速大概需要 15 秒,Tesla 的卡車即使在滿載 36 噸貨物的狀況下加速到每小時 100 公里也只需要 20 秒,最高時速可達到每小時104公里。   電動卡車需要面臨的最大挑戰就是續航,運輸貨物往往需要遠距離的行程,Tesla 電動卡車採用了 4 個獨立電機,單次充電可在高速公路路況下行駛約 800 公里,Tesla 為電動卡車打造了專用超級充電站 Megacharger,充電 30 分鐘就可行駛 650 公里,可應對 6-7 個小時的行程。  

  Tesla 半掛電動卡車的設計極具未來感,駕駛空間位於卡車前部中央的位置,空間較大,司機可完全站立,另外還配有有可拆卸的乘客座位。操控系統的設計延續了 Tesla Model 系列電動車的風格,採用了多個大尺寸觸控螢幕,用於顯示導航和車況資料。   為了提升電動卡車的安全性,在電池的部分採用了特殊的安全設計,電池位置較低降低了卡車的重點,同時擋風玻璃可有效地減少撞擊的衝擊力,車身上的鏡頭可實現 360 度的路況監控,一旦出現緊急狀況可向司機發出警告,必要時自動輔助駕駛系統可自動剎車。  

  雖然這款卡車上沒有配上無人駕駛功能,但應用到 Model S 上的自動駕駛升級後推廣到了卡車上,在高速公路等簡單路況下,自動駕駛系統可實現車道保持和變換,加速和停車等功能,降低司機在開車時的工作強度,提升行駛的安全性。   Tesla 電動卡車的目標市場主要是中短途運輸市場,每公里運輸成本大約是其他燃油卡車的 80%,由於安全性提升,運輸公司在車輛維護和保險方面的支出會相應減少。這款產品將在 2019 年量產,售價暫沒有公開。  
Roadster 再現,性能續航力爆表   此次發表會上 Elon Musk 還帶來了一款之前沒有任何消息曝光的新品──新款 Roadster 電動超跑,這是 Tesla 有史以來速度最快的電動車,從時速 0 到 100 公里加速僅需要 1.9 秒,幾乎超越了市面上其他昂貴的超級跑車,最高時速達到了每小時 400 公里,採用了 200kWh 的電池,單次充電續航達到了驚人的 1,000 公里,這款產品預期在 2020 年上市,售價為 20 萬美元起,第一批 1,000 台售價為 25 萬美元。  

  無論 Tesla 的半掛卡車還是新款超跑,在產品性能和外觀設計上都獲得了好評,但擺著這家電動車製造商面前的難題並沒有解決,產能問題使得 Tesla Model 3 還有 50 萬台訂單沒有交車,這兩款至少需要等到 2020 年才開始量產交付的新車會讓消費者等到什麼時候呢?   為了提升產能,Tesla 每一季需要投入 10 億美元建廠。傳統汽車製造商在新車推出之前,一般需要對產能進行長期的規畫,工廠建設、生產線配置和產能提升都需要時間,一般從工廠建設到生產線量產需要 3 年時間,同時製造商還需要面非常大的資金壓力,Tesla 應對這一問題的辦法就是提前 3 年時間發表產品,再進行工廠的建設和產品量產,Elon Musk 在產能提升方面也表現了極強的信心,Tesla的製造工廠自動化程度較高,能夠在一定程度上加快產能提升的速度。   一般汽車製造商的新品提升產能的時間週期大約是 6 個月,Tesla 在 2017 年第三季僅生產了 260 台 Model 3,產能不到預期的一成,這意味著 Tesla 面臨了更大的麻煩,有媒體報導 Tesla 的製造商機器人數量不足,僅有 150 台組裝機器人,部分生產線仍需要手工配裝,雖然 Tesla 否認的這一消息,作為車輛製造產業的新創公司,Tesla 的供應商管理、製造流程控制等方面確實存在缺陷。   (合作媒體:。首圖來源:Tesla)  

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

【其他文章推薦】

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

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

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

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

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

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

聚甘新

殼牌與IONITY聯手,歐洲據點大增、EV充電5分鐘搞定

  Thomson Reuters 27日報導,荷蘭皇家殼牌(Royal Dutch Shell plc)宣布與IONITY GmbH結盟、2019年將在歐洲(包括比利時、英國、法國、荷蘭、奧地利、捷克、匈牙利、波蘭、斯洛伐克和斯洛維尼亞)高速公路80個據點設置超高速電動車(EV)充電站。殼牌零售部門主管Istvan Kapitany表示,如果加上德國境內預計要增設的20座,兩年內殼牌在歐洲高速公路的加油站將有四分之一會提供高速充電服務。   殼牌指出,350 kW的充電功率搭配IONITY技術可讓EV充電時間縮短至5~8分鐘,遠比一般的數小時充電時間還要快。依據殼牌最樂觀的估算,全球EV車隊占整體車隊比重將從目前的1%成長至2025年底的10%,全球原油日需求量將因而縮減80萬桶。殼牌競爭對手BP 8月表示正與電動車製造商洽談合作案、預計在旗下加油站內將設置充電樁。根據歐洲替代燃料瞭望台的統計,2014~2017年期間歐洲EV充電樁成長將近三倍、逼近12萬大關。   英國金融時報報導,殼牌在全球各地擁有4萬座加油站、平均每天服務3千萬名客戶。殼牌將安裝的IONITY充電樁功率為350 kW、遠大於業界目前的標準規格(50kW)。IONITY成立於2016年,股東包括福特、BMW、戴姆勒、Volkswagen。   (本文內容由授權使用。首圖來源:public domain CC0)  

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

【其他文章推薦】

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

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

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

※回頭車貨運收費標準

聚甘新

Uber在英推出電動車隊,BYD、Nissan響應

新式交通運輸公司Uber在英國倫敦發表了全球首支電動車車隊,並由中國比亞迪(BYD)、日商Nissan響應,分別提供E6和LEAF組成一支50輛電動車的車隊。這支車隊在8月31日正式上路,可有效減少當地空污;若反應良好,還會拓展到其他英國城市。

倫敦市長Sadiq Khan曾承諾要將倫敦市轉型為全球最環保的城市,並積極採用低碳排放車款、設置電動車充電站。今年三月,由BYD和英國ADL聯手研發的五輛電動雙層巴士正式在倫敦上路,是全球首個電動雙層巴士車隊。

另一方面,Uber也曾在南非、葡萄牙測試驗動車專案,並推出Uber Green實驗性服務。Uber車隊也曾採用Toyota Prius油電混和車,藉此降低行駛時的碳排放量。

英國Uber總經理Jo Bertram表示,Uber希望能建立一個節能減碳的共乘交通模式,與Nissan、BYD的合作代表這個決心,也將是個起點。目前,英國的Uber大約有六成是油電混和車款,倫敦市對於電動車的接受度相對較高。

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

【其他文章推薦】

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

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

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

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

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

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

聚甘新