數據結構:用實例分析ArrayList與LinkedList的讀寫性能_包裝設計

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

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

目錄

  • 背景
  • ArrayList
  • LinkedList
  • 實例分析
    • 1、增加數據
    • 2、插入數據
    • 3、遍曆數據
      • 3.1、LinkedList遍歷改進
  • 總結

背景

ArrayList與LinkedList是Java編程中經常會用到的兩種基本數據結構,在書本上一般會說明以下兩個特點:

  • 對於需要快速隨機訪問元素,應該使用ArrayList。
  • 對於需要快速插入,刪除元素,應該使用LinkedList。

該文通過實際的例子分析這兩種數據的讀寫性能。

ArrayList

ArrayList是實現了基於動態數組的數據結構:

private static final int DEFAULT_CAPACITY = 10;
...
transient Object[] elementData;
...
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

LinkedList

LinkedList是基於鏈表的數據結構。

private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
...    
transient Node<E> first;
transient Node<E> last;
...
private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }

實例分析

  • 通過對兩個數據結構分別增加、插入、遍歷進行讀寫性能分析
1、增加數據
public class ArrayListAndLinkList {
    public final static int COUNT=100000;
    public static void main(String[] args) {

        // ArrayList插入
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        Long start = System.currentTimeMillis();
        System.out.println("ArrayList插入開始時間:" + sdf.format(start));

        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            arrayList.add(i);
        }

        Long end = System.currentTimeMillis();
        System.out.println("ArrayList插入結束時間:" + sdf.format(end));
        System.out.println("ArrayList插入" + (end - start) + "毫秒");


        // LinkedList插入
        start = System.currentTimeMillis();
        System.out.println("LinkedList插入開始時間:" + sdf.format(start));
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < COUNT; i++) {
            linkedList.add(i);
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList插入結束時間:" + sdf.format(end));
        System.out.println("LinkedList插入結束時間" + (end - start) + "毫秒");
     }
}

輸出如下:
兩者寫入的性能相差不大!

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

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

2、插入數據

在原有增加的數據上,在index:100的位置上再插入10萬條數據。

public class ArrayListAndLinkList {
    public final static int COUNT=100000;
    public static void main(String[] args) {

        // ArrayList插入
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        Long start = System.currentTimeMillis();
        System.out.println("ArrayList插入開始時間:" + sdf.format(start));

        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            arrayList.add(i);
        }
        for (int i = 0; i < COUNT; i++) {
            arrayList.add(100,i);
        }

        Long end = System.currentTimeMillis();
        System.out.println("ArrayList插入結束時間:" + sdf.format(end));
        System.out.println("ArrayList插入" + (end - start) + "毫秒");


        // LinkedList插入
        start = System.currentTimeMillis();
        System.out.println("LinkedList插入開始時間:" + sdf.format(start));
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < COUNT; i++) {
            linkedList.add(i);
        }
        for (int i = 0; i < COUNT; i++) {
            linkedList.add(100,i);
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList插入結束時間:" + sdf.format(end));
        System.out.println("LinkedList插入結束時間" + (end - start) + "毫秒");
     }
}

輸出如下:
ArrayList的性能明顯比LinkedList的性能差了很多。

看下原因:
ArrayList的插入源碼:

  public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

ArrayList的插入原理:在index位置上插入后,在index後續的數據上需要做逐一複製。

LinkedList的插入源碼:

public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
 }
 ...
  void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

LinkedList的插入原理:在原來相互鏈接的兩個節點(Node)斷開,把新的結點插入到這兩個節點中間,根本不存在複製這個過程。

3、遍曆數據

在增加和插入的基礎上,利用get方法進行遍歷。

public class ArrayListAndLinkList {
    public final static int COUNT=100000;
    public static void main(String[] args) {

        // ArrayList插入
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        Long start = System.currentTimeMillis();
        System.out.println("ArrayList插入開始時間:" + sdf.format(start));

        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 0; i < COUNT; i++) {
            arrayList.add(i);
        }
        for (int i = 0; i < COUNT; i++) {
            arrayList.add(100,i);
        }

        Long end = System.currentTimeMillis();
        System.out.println("ArrayList插入結束時間:" + sdf.format(end));
        System.out.println("ArrayList插入" + (end - start) + "毫秒");


        // LinkedList插入
        start = System.currentTimeMillis();
        System.out.println("LinkedList插入開始時間:" + sdf.format(start));
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 0; i < COUNT; i++) {
            linkedList.add(i);
        }
        for (int i = 0; i < COUNT; i++) {
            linkedList.add(100,i);
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList插入結束時間:" + sdf.format(end));
        System.out.println("LinkedList插入結束時間" + (end - start) + "毫秒");

        // ArrayList遍歷
        start = System.currentTimeMillis();
        System.out.println("ArrayList遍歷開始時間:" + sdf.format(start));
        for (int i = 0; i < 2*COUNT; i++) {
            arrayList.get(i);
        }
        end = System.currentTimeMillis();
        System.out.println("ArrayList遍歷開始時間:" + sdf.format(end));
        System.out.println("ArrayList遍歷開始時間" + (end - start) + "毫秒");

        // LinkedList遍歷
        start = System.currentTimeMillis();
        System.out.println("LinkedList遍歷開始時間:" + sdf.format(start));
        for (int i = 0; i < 2*COUNT; i++) {
            linkedList.get(i);
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList遍歷開始時間:" + sdf.format(end));
        System.out.println("LinkedList遍歷開始時間" + (end - start) + "毫秒");

    }
}

輸出如下:

兩者的差異巨大:
我們看一下LInkedList的get方法:從頭遍歷或從尾部遍歷結點

public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
 ...
 Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
3.1、LinkedList遍歷改進

我們採用迭代器對LinkedList的遍歷進行改進:

		...
		// LinkedList遍歷
        start = System.currentTimeMillis();
        System.out.println("LinkedList遍歷開始時間:" + sdf.format(start));
        Iterator<Integer> iterator = linkedList.iterator();
        while(iterator.hasNext()){
            iterator.next();
        }
        end = System.currentTimeMillis();
        System.out.println("LinkedList遍歷開始時間:" + sdf.format(end));
        System.out.println("LinkedList遍歷開始時間" + (end - start) + "毫秒");

再看下結果:
兩者的遍歷性能接近。

總結

  • List使用首選ArrayList。對於個別插入刪除非常多的可以使用LinkedList。
  • LinkedList,遍歷建議使用Iterator迭代器,尤其是數據量較大時LinkedList避免使用get遍歷。

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

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

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

從linux源碼看socket的阻塞和非阻塞_台中搬家

※台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

從linux源碼看socket的阻塞和非阻塞

筆者一直覺得如果能知道從應用到框架再到操作系統的每一處代碼,是一件Exciting的事情。
大部分高性能網絡框架採用的是非阻塞模式。筆者這次就從linux源碼的角度來闡述socket阻塞(block)和非阻塞(non_block)的區別。 本文源碼均來自採用Linux-2.6.24內核版本。

一個TCP非阻塞client端簡單的例子

如果我們要產生一個非阻塞的socket,在C語言中如下代碼所示:

// 創建socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
...
// 更改socket為nonblock
fcntl(sock_fd, F_SETFL, fdflags | O_NONBLOCK);
// connect
....
while(1)  {  
    int recvlen = recv(sock_fd, recvbuf, RECV_BUF_SIZE) ; 
    ......
} 
...

由於網絡協議非常複雜,內核裏面用到了大量的面向對象的技巧,所以我們從創建連接開始,一步一步追述到最後代碼的調用點。

socket的創建

很明顯,內核的第一步應該是通過AF_INET、SOCK_STREAM以及最後一個參數0定位到需要創建一個TCP的socket,如下圖綠線所示:

我們跟蹤源碼調用

socket(AF_INET, SOCK_STREAM, 0)
	|->sys_socket 進入系統調用
		|->sock_create
			|->__sock_create

進一步分析__sock_create的代碼判斷:

const struct net_proto_family *pf;
// RCU(Read-Copy Update)是linux的一種內核同步方法,在此不闡述
// family=INET
pf = rcu_dereference(net_families[family]);
err = pf->create(net, sock, protocol);

由於family是AF_INET協議,注意在操作系統裏面定義了PF_INET等於AF_INET,
內核通過函數指針實現了對pf(net_proto_family)的重載。如下圖所示:

則通過源碼可知,由於是AF_INET(PF_INET),所以net_families[PF_INET].create=inet_create(以後我們都用PF_INET表示),即
pf->create = inet_create;
進一步追溯調用:

inet_create(struct net *net, struct socket *sock, int protocol){
	Sock* sock;
	......
	// 此處是尋找對應協議處理器的過程
lookup_protocol:
	// 迭代尋找protocol==answer->protocol的情況
	list_for_each_rcu(p, &inetsw[sock->type]) answer = list_entry(p, struct inet_protosw, list);

		/* Check the non-wild match. */
		if (protocol == answer->protocol) {
			if (protocol != IPPROTO_IP)
				break;
		}
	......
	// 這邊answer指的是SOCK_STREAM
	sock->ops = answer->ops;
	answer_no_check = answer->no_check;
	// 這邊sk->prot就是answer_prot=>tcp_prot
	sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
	sock_init_data(sock, sk);
	......
}

上面的代碼就是在INET中尋找SOCK_STREAM的過程了
我們再看一下inetsw[SOCK_STREAM]的具體配置:

static struct inet_protosw inetsw_array[] =
{
	{
		.type =       SOCK_STREAM,
		.protocol =   IPPROTO_TCP,
		.prot =       &tcp_prot,
		.ops =        &inet_stream_ops,
		.capability = -1,
		.no_check =   0,
		.flags =      INET_PROTOSW_PERMANENT |
			      INET_PROTOSW_ICSK,
	},
	......
}

這邊也用了重載,AF_INET有TCP、UDP以及Raw三種:

從上述代碼,我們可以清楚的發現sock->ops=&inet_stream_ops;

const struct proto_ops inet_stream_ops = {
	.family		   = PF_INET,
	.owner		   = THIS_MODULE,
	......
	.sendmsg	   = tcp_sendmsg,
	.recvmsg	   = sock_common_recvmsg,
	......
}	

即sock->ops->recvmsg = sock_common_recvmsg;
同時sock->sk->sk_prot = tcp_prot;

我們再看下tcp_prot中的各個函數重載的定義:

struct proto tcp_prot = {
	.name			= "TCP",
	.close			= tcp_close,
	.connect		= tcp_v4_connect,
	.disconnect		= tcp_disconnect,
	.accept			= inet_csk_accept,
	......
	// 我們重點考察tcp的讀
	.recvmsg		= tcp_recvmsg,
	......
}

fcntl控制socket的阻塞\非阻塞狀態

我們用fcntl修改socket的阻塞\非阻塞狀態。
事實上:
fcntl的作用就是將O_NONBLOCK標誌位存儲在sock_fd對應的filp結構的f_lags里,如下圖所示。

fcntl(sock_fd, F_SETFL, fdflags | O_NONBLOCK);
	|->setfl

追蹤setfl代碼:

static int setfl(int fd, struct file * filp, unsigned long arg) {
	......
	filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
	......
}

上圖中,由sock_fd在task_struct(進程結構體)->files_struct->fd_array中找到對應的socket的file描述符,再修改file->flags

在調用socket.recv的時候

我們跟蹤源碼調用:

socket.recv
	|->sys_recv
		|->sys_recvfrom
			|->sock_recvmsg
				|->__sock_recvmsg
					|->sock->ops->recvmsg

由上文可知:
sock->ops->recvmsg = sock_common_recvmsg;

※台中搬家遵守搬運三大原則,讓您的家具不再被破壞!

台中搬家公司推薦超過30年經驗,首選台中大展搬家

sock

值得注意的是,在sock_recmsg中,有對標識O_NONBLOCK的處理

	if (sock->file->f_flags & O_NONBLOCK)
		flags |= MSG_DONTWAIT;

上述代碼中sock關聯的file中獲取其f_flags,如果flags有O_NONBLOCK標識,那麼就設置msg_flags為MSG_DONTWAIT(不等待)。
fcntl與socket就是通過其共同操作File結構關聯起來的。

繼續跟蹤調用

sock_common_recvmsg

int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
			struct msghdr *msg, size_t size, int flags) {
	......
	// 如果flags的MSG_DONTWAIT標識置位,則傳給recvmsg的第5個參數為正,否則為0
	err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
				   flags & ~MSG_DONTWAIT, &addr_len);
	.....				   
}

由上文可知:
sk->sk_prot->recvmsg 其中sk_prot=tcp_prot,即最終調用的是tcp_prot->tcp_recvmsg,
上面的代碼可以看出,如果fcntl(O_NONBLOCK)=>MSG_DONTWAIT置位=>(flags & MSG_DONTWAIT)>0, 再結合tcp_recvmsg的函數簽名,即如果設置了O_NONBLOCK的話,設置給tcp_recvmsg的nonblock參數>0,關係如下圖所示:

最終的調用邏輯tcp_recvmsg

首先我們看下tcp_recvmsg的函數簽名:

int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
		size_t len, int nonblock, int flags, int *addr_len)

顯然我們關注焦點在(int nonblock這個參數上):

int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
		size_t len, int nonblock, int flags, int *addr_len){
	......	
	// copied是指向用戶空間拷貝了多少字節,即讀了多少
	int copied;
	// target指的是期望多少字節
	int target;
	// 等效為timo = nonblock ? 0 : sk->sk_rcvtimeo;
	timeo = sock_rcvtimeo(sk, nonblock);
	......	
	// 如果設置了MSG_WAITALL標識target=需要讀的長度
	// 如果未設置,則為最低低水位值
	target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
	......

	do{
		// 表明讀到數據
		if (copied) {
			// 注意,這邊只要!timeo,即nonblock設置了就會跳出循環
			if (sk->sk_err ||
			    sk->sk_state == TCP_CLOSE ||
			    (sk->sk_shutdown & RCV_SHUTDOWN) ||
			    !timeo ||
			    signal_pending(current) ||
			    (flags & MSG_PEEK))
			break;
		}else{
			// 到這裏,表明沒有讀到任何數據
			// 且nonblock設置了導致timeo=0,則返回-EAGAIN,符合我們的預期
			if (!timeo) {
				copied = -EAGAIN;
				break;
		}
		// 這邊如果堵到了期望的數據,繼續,否則當前進程阻塞在sk_wait_data上
		if (copied >= target) {
			/* Do not sleep, just process backlog. */
			release_sock(sk);
			lock_sock(sk);
		} else
			sk_wait_data(sk, &timeo);
	} while (len > 0);		
	......
	return copied
}

上面的邏輯歸結起來就是:
(1)在設置了nonblock的時候,如果copied>0,則返回讀了多少字節,如果copied=0,則返回-EAGAIN,提示應用重複調用。
(2)如果沒有設置nonblock,如果讀取的數據>=期望,則返回讀取了多少字節。如果沒有則用sk_wait_data將當前進程等待。
如下流程圖所示:

阻塞函數sk_wait_data

sk_wait_data代碼-函數為:

	// 將進程狀態設置為可打斷INTERRUPTIBLE
	prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
	set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
	// 通過調用schedule_timeout讓出CPU,然後進行睡眠
	rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue));
	// 到這裏的時候,有網絡事件或超時事件喚醒了此進程,繼續運行
	clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
	finish_wait(sk->sk_sleep, &wait);

該函數調用schedule_timeout進入睡眠,其進一步調用了schedule函數,首先從運行隊列刪除,其次加入到等待隊列,最後調用和體繫結構相關的switch_to宏來完成進程間的切換。
如下圖所示:

阻塞后什麼時候恢復運行呢

情況1:有對應的網絡數據到來

首先我們看下網絡分組到來的內核路徑,網卡發起中斷後調用netif_rx將事件掛入CPU的等待隊列,並喚起軟中斷(soft_irq),再通過linux的軟中斷機制調用net_rx_action,如下圖所示:

注:上圖來自PLKA(<<深入Linux內核架構>>)
緊接着跟蹤next_rx_action

next_rx_action
	|-process_backlog
		......
			|->packet_type->func 在這裏我們考慮ip_rcv
					|->ipprot->handler 在這裏ipprot重載為tcp_protocol
						(handler 即為tcp_v4_rcv)					

緊接着tcp_v4_rcv:

tcp_input.c
tcp_v4_rcv
	|-tcp_v4_do_rcv
		|-tcp_rcv_state_process
			|-tcp_data_queue
				|-sk->sk_data_ready=sock_def_readable
					|-wake_up_interruptible
						|-__wake_up
							|-__wake_up_common

在這裏__wake_up_common將停在當前wait_queue_head_t中的進程喚醒,即狀態改為task_running,等待CFS調度以進行下一步的動作,如下圖所示。

情況2:設定的超時時間到來

在前面調用sk_wait_event中調用了schedule_timeout

fastcall signed long __sched schedule_timeout(signed long timeout) {
	......
	// 設定超時的回掉函數為process_timeout
	setup_timer(&timer, process_timeout, (unsigned long)current);
	__mod_timer(&timer, expire);
	// 這邊讓出CPU
	schedule();
	del_singleshot_timer_sync(&timer);
	timeout = expire - jiffies;
 out:
 	// 返回經過了多長事件
	return timeout < 0 ? 0 : timeout;	
}

process_timeout函數即是將此進程重新喚醒

static void process_timeout(unsigned long __data)
{
	wake_up_process((struct task_struct *)__data);
}

總結

linux內核源代碼博大精深,閱讀其代碼很費周折。希望筆者這篇文章能幫助到閱讀linux網絡協議棧代碼的人。

公眾號

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

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

※台中搬家公司費用怎麼算?

擁有20年純熟搬遷經驗,提供免費估價且流程透明更是5星評價的搬家公司

Volcano火山:容器與批量計算的碰撞_台中搬家公司

※台中搬家公司教你幾個打包小技巧,輕鬆整理裝箱!

還在煩惱搬家費用要多少哪?台中大展搬家線上試算搬家費用,從此不再擔心「物品怎麼計費」、「多少車才能裝完」

【摘要】 Volcano是基於Kubernetes構建的一個通用批量計算系統,它彌補了Kubernetes在“高性能應用”方面的不足,支持TensorFlow、Spark、MindSpore等多個領域框架,幫助用戶通過Kubernetes構建統一的容器平台。

Kubernetes 是當前非常流行的容器編排框架,在其發展早期重點以微服務類應用為主。隨着Kuberentes的用戶越來越多,更多的用戶希望在Kubernetes上運行BigData和AI框架,如Spark、TensorFlow等以構建統一的容器平台。但在Kubernetes運行這些高性能應用時,Kubernetes的默認調度器無法滿足高性能應用的需求,例如:公平調度、優先級、隊列等高級調度功能。由於Kubernetes的默認調度器是基於Pod進行調度,雖然在1.17中引入了調度框架,但仍無法滿足高性能應用對作業級調度的需求。

容器批量計算平台Volcano

針對雲原生場景下的高性能應用場景,華為雲容器團隊推出了Volcano項目。Volcano是基於Kubernetes構建的一個通用批量計算系統,它彌補了Kubernetes在“高性能應用”方面的不足,支持TensorFlow、Spark、MindSpore等多個領域框架,幫助用戶通過Kubernetes構建統一的容器平台。Volcano作為容器調度系統,不僅包括了作業調度,還包含了作業生命周期管理、多集群調度、命令行、數據管理、作業視圖及硬件加速等功能。

而在調度方面,Volcano 又對場景進行了細分、歸類,並提供了相關的方案及算法;同時也為這些功能提供了調度框架,方便用戶對調度器進行擴展。對於分佈式計算或是并行計算來說,根據場景和作業屬性的不同,也可以對其進行細分;在 《并行計算導論》 中將并行計算大致分為三類:

  • 簡單的并行

簡單的并行指多個子任務(tasks)之間沒有通信也不需要同步,可以完全的并行的執行。比較著名的例子應該就屬MapReduce了,它的兩個階段都屬於這種類型:mapper任務在執行時並不會彼此通信同步運行狀態;另一個常見的例子是蒙特·卡羅方法 ,各個子任務在計算隨機數時也無需彼此通信、同步。由於這種并行計算有比較廣泛的應用,例如 數據處理、VatR 等,針對不同的場景也產生了不同的調度框架,例如 Hadoop、DataSynapse 和 Symphony。同時,由於子任務之間無需信息和同步,當其中某幾個計算節點(workers)被驅逐后,雖然作業的執行時間可能會變長,但整個作業仍可以順利完成;而當計算節點增加時,作業的執行時間一般都會縮短。因此,這種作業也常常被稱作 Elastic Job。

  • 複雜的并行

複雜的并行作業指多個子任務 (tasks) 之間需要同步信息來執行複雜的并行算法,單個子任務無法完成部分計算。最近比較有名的例子應該算是 Tensorflow 的 “ps-work模式” 和 ring all-reduce 了,各個子任務之間需要大量的數據交換和信息同步,單獨的子任務無法獨立完成。正是由於作業的這種屬性,對作業調度平台也提出了相應的調度要求,比如 gang-scheduling、作業拓撲等。由於子任務之間需要彼此通信,因此作業在啟動后無法動態擴展子任務,在沒有checkpoint的情況下,任一子任務失敗或驅逐,整個作業都需要重啟,這種作業也常常被稱作 Batch Job,傳統的HPC場景多屬於這種類型的并行作業,針對這種場景的調度平台為 Slurm/PBS/SGE/HTCondor 等。

  • 流水線并行

流水線并行是指作業的多個子任務之間存在依賴關係,但不需要前置任務完全結束后再開始後續的任務;比如 Hadoop 里有相應的研究:在 Map 沒有完全結束的時候就部分開始 Reduce 階段,從而提高任務的并行度,提高整體的運行性能。符合這種場景的應用相對來說比較少,一般都做為性能優化;因此沒有針對這種場景的作業管理平台。需要區分一下工作流與流水線并行,工作流一般指作業之間的依賴關係,而流水線并行一般指作業內部多個任務之間的依賴。由於工作流中的作業差異比較大,很難提前開始後續步驟。

值得一提的是”二次調度”。由於簡單并行的作業一般會有大量的子任務,而且每個子任務所需要的資源相對一致,子任務之間也沒有通信和同步;使得資源的復用率相對比較高,因此二次調度在這種場景下能發揮比較大的作用;Hadoop的YARN,Symphony的EGO都屬於這種類型。但是在面對複雜并行的作業時,二次調度就顯得有也吃力;複雜并行作業一般並沒有太多的子任務,子任務之間還經常需要同時啟動,子任務之間的通信拓撲也可能不同 (e.g. ps/worker, mpi),而且作業與作業之間對資源的需求差異較大,因此導致了資源的復用率較低。

雖然針對兩種不同并行作業類型有不同的作業、資源管理平台,但是根本的目標都是為作業尋找最優的資源;因此,Volcano一直以支持以多種類型的作業為目標進行設計。目前,Volcano可以同時支持 Spark、TensorFlow和MPI等多種類型的作業。

常見調度場景

1.組調度 (Gang-scheduling)

運行批處理作業(如Tensorflow/MPI)時,必須協調作業的所有任務才能一起啟動;否則,將不會啟動任何任務。如果有足夠的資源并行運行作業的所有任務,則該作業將正確執行; 但是,在大多數情況下,尤其是在prem環境中,情況並非如此。在最壞的情況下,由於死鎖,所有作業都掛起。其中每個作業只成功啟動了部分任務,並等待其餘任務啟動。

2.作業級的公平調度 (Job-based Fair-share)

當運行多個彈性作業(如流媒體)時,需要公平地為每個作業分配資源,以滿足多個作業競爭附加資源時的SLA/QoS要求。在最壞的情況下,單個作業可能會啟動大量的pod資源利用率低, 從而阻止其他作業由於資源不足而運行。為了避免分配過小(例如,為每個作業啟動一個Pod),彈性作業可以利用協同調度來定義應該啟動的Pod的最小可用數量。 超過指定的最小可用量的任何pod都將公平地與其他作業共享集群資源。

3.隊列 (Queue)

隊列還廣泛用於共享彈性工作負載和批處理工作負載的資源。隊列的主要目的是:

  • 在不同的“租戶”或資源池之間共享資源
  • 為不同的“租戶”或資源池支持不同的調度策略或算法

這些功能可以通過層次隊列進一步擴展,在層次隊列中,項目被賦予額外的優先級,這將允許它們比隊列中的其他項目“跳轉”。在kube批處理中,隊列被實現為集群範圍的CRD。 這允許將在不同命名空間中創建的作業放置在共享隊列中。隊列資源根據其隊列配置(kube batch#590)按比例劃分。當前不支持分層隊列,但正在進行開發。

集群應該能夠在不減慢任何操作的情況下處理隊列中的大量作業。其他的HPC系統可以處理成百上千個作業的隊列,並隨着時間的推移緩慢地處理它們。如何與庫伯內特斯達成這樣的行為是一個懸而未決的問題。支持跨越多個集群的隊列可能也很有用,在這種情況下,這是一個關於數據應該放在哪裡以及etcd是否適合存儲隊列中的所有作業或pod的問題。

4.面向用戶的, 跨隊列的公平調度 (Namespace-based fair-share Cross Queue)

在隊列中,每個作業在調度循環期間有幾乎相等的調度機會,這意味着擁有更多作業的用戶有更大的機會安排他們的作業,這對其他用戶不公平。 例如,有一個隊列包含少量資源,有10個pod屬於UserA,1000個pod屬於UserB。在這種情況下,UserA的pod被綁定到節點的概率較小。

為了平衡同一隊列中用戶之間的資源使用,需要更細粒度的策略。考慮到Kubernetes中的多用戶模型,使用名稱空間來區分不同的用戶, 每個命名空間都將配置一個權重,作為控制其資源使用優先級的手段。

※推薦台中搬家公司優質服務,可到府估價

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

5.基於時間的公平調度 (Fairness over time)

對於批處理工作負載,通常不要求在某個時間點公平地分配資源,而是要求在長期內公平地分配資源。例如,如果有用戶提交大作業,則允許用戶(或特定隊列)在一定時間內使用整個集群的一半, 這是可以接受的,但在下一輪調度(可能是作業完成后數小時)中,應懲罰此用戶(或隊列)而不是其他用戶(或隊列)。在 HTCondor 中可以看到如何實現這種行為的好例子。

6.面向作業的優先級調度 (Job-based priority)

Pod優先級/搶佔在1.14版本中被中斷,它有助於確保高優先級的pod在低優先級的pod之前綁定。不過,在job/podgroup級別的優先級上仍有一些工作要做,例如高優先級job/podgroup應該嘗試以較低優先級搶佔整個job/podgroup,而不是從不同job/podgroup搶佔幾個pod。

7.搶佔 (Preemption & Reclaim)

通過公平分享來支持借貸模型,一些作業/隊列在空閑時會過度使用資源。但是,如果有任何進一步的資源請求,資源“所有者”將“收回”。 資源可以在隊列或作業之間共享:回收用於隊列之間的資源平衡,搶佔用於作業之間的資源平衡。

8.預留與回填 (Reservation & Backfill)

當一個請求大量資源的“巨大”作業提交給kubernetes時,當有許多小作業在管道中時,該作業可能會餓死,並最終根據當前的調度策略/算法被殺死。為了避免飢餓, 應該有條件地為作業保留資源,例如超時。當資源被保留時,它們可能會處於空閑和未使用狀態。為了提高資源利用率,調度程序將有條件地將“較小”作業回填到那些保留資源中。 保留和回填都是根據插件的反饋觸發的:volcano調度器提供了幾個回調接口,供開發人員或用戶決定哪些作業應該被填充或保留。

Volcano 調度框架

Volcano調度器通過作業級的調度和多種插件機制來支持多種作業;Volcano的插件機制有效的支撐了針對不同場景算法的落地,從早期的gang-scheduling/co-scheduling,到後來各個級別的公平調度。下圖展示了Volcano調度器的總體架構:

Cache 緩存了集群中Node和Pod信息,並根據PodGroup的信息重新構建 Job (PodGroup) 和 Task (Pod) 的關係。由於在分佈式系統中很難保證信息的同步,因此調度器經常以某一時間點的集群快照進行調度;並保證每個調度周期的決定是一致的。在每個調度周期中,Volcano 通過以下幾個步驟派發作業:

  • 在每個調度周期都會創建一個Session對象,用來存儲當前調度周期的所需的數據,例如,Cache 的一個快照。當前的調度器中僅創建了一個Session,並由一個調度線程執行;後續將會根據需要創建多個Session,併為每個Session分配一個線程進行調度;並由Cache來解決調度衝突。
  • 在每個調度周期中,會按順序執行 OpenSession, 配置的多個動作(action)和CloseSession。在 OpenSession中用戶可以註冊自定義的插件,例如gang、 drf,這些插件為action提供了相應算法;多個action根據配置順序執行,調用註冊的插件進行調度;最後,CloseSession負責清理中間數據。

(1) action是第一級插件,定義了調度周期內需要的各個動作;默認提供 enqueue、allocate、 preempt和backfill四個action。以allocate為例,它定義了調度中資源分配過程:根據 plugin 的 JobOrderFn 對作業進行排序,根據NodeOrderFn對節點進行排序,檢測節點上的資源是否滿足,滿足作業的分配要求(JobReady)后提交分配決定。由於action也是基於插件機制,因此用戶可以重新定義自己的分配動作,例如 基於圖的調度算法firmament。

(2) plugin是第二級插件,定義了action需要的各個算法;以drf插件為例,為了根據dominant resource進行作業排序,drf插件實現了 JobOrderFn函數。JobOrderFn函數根據 drf 計算每個作業的share值,share值較低代表當前作業分配的資源較少,因此會為其優先分配資源;drf插件還實現了EventHandler回調函數,當作業被分配或搶佔資源后,調度器會通知drf插件來更新share值。

  • Cache 不僅提供了集群的快照,同時還提供了調度器與kube-apiserver的交互接口,調度器與kube-apiserver之間的通信也都通過Cache來完成,例如 Bind。
  • 同時,為了支持上面這些場景,Volcano的調度器還增加了多個Pod狀態以提高調度的性能:
  • Pending: 當Pod被創建后就處於Pending狀態,等待調度器對其進行調度;調度的主要目的也是為這些Pending的Pod尋找最優的資源
  • Allocated: 當Pod被分配空閑資源,但是還沒有向kube-apiserver發送調度決策時,Pod處於Allocated狀態。 Allocated狀態僅存在於調度周期內部,用於記錄Pod和資源分配情況。當作業滿足啟動條件時 (e.g. 滿足minMember),會向kube-apiserver提交調度決策。如果本輪調度周期內無法提交調度決策,由狀態會回滾為Pending狀態。
  • Pipelined: 該狀態與Allocated狀態相似,區別在於處於該狀態的Pod分配到的資源為正在被釋放的資源 (Releasing)。該狀態主要用於等待被搶佔的資源釋放。該狀態是調度周期中的狀態,不會更新到kube-apiserver以減少通信,節省kube-apiserver的qps。
  • Binding: 當作業滿足啟動條件時,調度器會向kube-apiserver提交調度決策,在kube-apiserver返回最終狀態之前,Pod一直處於Binding狀態。該狀態也保存在調度器的Cache之中,因此跨調度周期有效。
  • Bound: 當作業的調度決策在kube-apiserver確認后,該Pod即為Bound狀態。
  • Releasing: Pod等待被刪除時即為Releasing狀態。
  • Running, Failed, Succeeded, Unknown: 與Pod的現有含義一致。

狀態之間根據不同的操作進行轉換,見下圖。

Pod的這些狀態為調度器提供了更多優化的可能。例如,當進行Pod驅逐時,驅逐在Binding和Bound狀態的Pod要比較驅逐Running狀態的Pod的代價要小 (思考:還有其它狀態的Pod可以驅逐嗎?);並且狀態都是記錄在Volcano調度內部,減少了與kube-apiserver的通信。但目前Volcano調度器僅使用了狀態的部分功能,比如現在的preemption/reclaim僅會驅逐Running狀態下的Pod;這主要是由於分佈式系統中很難做到完全的狀態同步,在驅逐Binding和Bound狀態的Pod會有很多的狀態競爭。

Volcano調度實現

Volcano調度器在支持上面這些主要場景時,分別使用了action和plugin兩級插件。總體來講,帶有動作屬性的功能,一般需要引入 action 插件;帶有選擇 (包括排序) 屬性的功能,一般使用 plugin 插件。因此,這些常見場景中,fair-sharing、queue、co-scheduling都通過plugin機制來實現:都帶有選擇屬性,比如“哪些作業應該被優先調度”;而preemption、reclaim、backfill、reserve 則通過 action 機制來實現:都帶有動作屬性,比如“作業A 搶佔 作業B”。這裏需要注意的是,action 與 plugin 一定是一同工作的;fair-sharing 這些 plugin 是藉助 allocate 發展作用,而 preemption 在創建新的 action 后,同樣需要 plugin 來選擇哪些作業應該被搶佔。這裏通過job-based fairness (DRF) 和 preempt 兩個功能的實現來介紹action 和 plugin 兩種插件機制的使用,其它功能類似:

  • Job-based Fairness (DRF): 目前的公平調度是基於DRF,並通過 plugin 插件來實現。在 OpenSession 中會先計算每個作業的 dominant resource和每個作業share的初始值;然後註冊 JobOrderFn回調函數,JobOrderFn 中接收兩個作業對象,並根據對像的 dominant resource 的 share值對作業進行排序;同時註冊EventHandler, 當Pod被分配或搶佔資源時,drf根據相應的作業及資源信息動態更新share值。

其它插件的實現方案也基本相似,在OpenSession中註冊相應的回調,例如 JobOrderFn, TaskOrderFn,調度器會根據回調函數的結果決定如何分配資源,並通過EventHandler來更新插件內的調度數。

  • Preemption: preempt是在allocate之後的一個action,它會為“高”優先級的Pending作業選取一個或多個“低”優先級的作業進行驅逐。由於搶佔的動作與分配的動作不一致,因此新創建了preempt action來處理相應的邏輯;同時,在選取高低優先級的作業時,preempt action還是依賴相應的plugin插件來實現。其它動作插件的實現方式也類似,即根據需要創建整體的流程;將帶有選擇屬性的問題轉換為算法插件。

6月4日晚20:00-21:00,Volcano/kube-batch 創始人在線授課,不僅傳授Volcano架構原理,還告訴你更多應用落地場景,戳鏈接免費觀看。

點擊關注,第一時間了解華為雲新鮮技術~

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

※推薦台中搬家公司優質服務,可到府估價

台中搬鋼琴,台中金庫搬運,中部廢棄物處理,南投縣搬家公司,好幫手搬家,西屯區搬家

7.5-15萬不買日系車 上班族首選車型顏值高有格調!_網頁設計公司

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

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。

內飾運動感沒有那麼強烈,整體比較中規中矩,不過,配色上沒有那麼沉悶。福克斯有1。0T 1。5T 1。6L三種動力車型選擇,三種車型配置相差並不算太大,都標配了ESp,剎車輔助,牽引力控制等的配置,每一款動力的車型低配和次低配舒適性的配置稍少了一些,但對於日常使用而言,影響並不大。

如今路上的車輛越來越多,塞車,找不到停車位,已經是習以為常的時。因為這樣,現在不少人會選擇“體型”較小的車型,這樣在路上行駛或者在塞車擠位的時候都比較輕鬆。對於一般的上班族而言,下面這些車型就適合。

上汽大眾-pOLO

指導價:7.59-14.69萬

pOLO的外觀大家也再熟悉不過了,大眾臉配上小“體型”,有一種別樣的規矩感。內飾造型同樣是大眾風,但鋼琴烤漆高亮度面板和鍍鉻飾條,稍微的提升了些檔次感,布局也以實用為主。

pOLO有1.4L,1.6L以及1.4T車型選擇,對於一般用車,1.4T車型的選擇性較低。1.4L車型除了頂配之外都沒有配備ESp,剎車輔助,牽引力控制,這方便比較不就到,舒適配置表現中下,畢竟是8萬的大眾車。1.6L車型低配和次低配車型安全配置較低,舒適性配置比1.4L車型多了幾個,例如,電動天窗,定速巡航等,頂配和次頂配車型有配備ESp,剎車輔助,牽引力控制,舒適性配置也比較齊全。另外,1.4L車型的自動風尚型可以選裝ESp,剎車輔助,牽引力控制。

長安福特-福克斯

指導價:9.98-16.58萬

馬丁臉有較強烈的視覺感,整體的設計運動型較強,對於喜歡有點激情的上班族來說,很適合。內飾運動感沒有那麼強烈,整體比較中規中矩,不過,配色上沒有那麼沉悶。

福克斯有1.0T 1.5T 1.6L三種動力車型選擇,

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

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

三種車型配置相差並不算太大,都標配了ESp,剎車輔助,牽引力控制等的配置,每一款動力的車型低配和次低配舒適性的配置稍少了一些,但對於日常使用而言,影響並不大。中配車型配置比較齊全,日常使用很足夠,例如,電動天窗,多功能方向盤,后駐車雷達等都有配備。而頂配車型還配備了併線輔助,車道偏離系統,但價格較貴,日常使用,選擇中低配車型就足夠了。

東風標緻-標緻308S

指導價:11.27-17.97萬

不一樣的風情,這是308S給人的第一眼感覺,濃濃的法系味道。內飾顯得比較簡約,但做工依然保持了法系的精緻,看起很有質感,物理按鍵被替代成了觸碰式的,這對操作的實用性有一定的減少。

308S有1.2T 1.6L 1.6T三種動力車型車選擇,1.2T和1.6L的頂配車型配置較為齊全一些,但有些奇怪的是,全系都有配備ESp,剎車輔助,上坡輔助,就是沒有配備牽引力控制,頂配有配備全景天窗但是全系都沒有電動天窗,這算是法系的獨特的風格?中低配車型雖然配置較少,但對於日常使用也還是足夠的,只要你對配置要求不高的話。1.6T車型整體配置算得上齊全,有配備牽引力控制,但還是沒有電動天窗,其他舒適性配置算得上豐富,不過價格就貴了不少,不太推薦。

總結:斯文派的pOLO,激情派的福克斯,時尚派的標誌308S,三種不同風格之選。在價格上,pOLO算上優惠,最低配裸車價可以去到6萬多,而福克斯和308S價格稍微貴一些,但配置上會好很多。總體而言,福克斯各方面比較均衡,價格不高也不低,配置也一樣,對於現在人選車的“理念”而言,比較適合。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

選擇SUV的N個理由,說中你了嗎?_如何寫文案

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

銷售文案是什麼?A文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

6%的人表示準備買SUV,這麼高的數據比例其實不驚人,確實在近幾年的汽車市場中,SUV持續火爆,自主品牌也厚積薄發,像哈弗H6,榮威RX5,吉利博越,寶駿560等等。那麼問題來了,廠家如此重本地研發SUV,加上越來越多消費者買SUV,究竟為的是什麼。

在某網站上曾看過一個數據調查,

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

擁有後台管理系統的網站,將擁有強大的資料管理與更新功能,幫助您隨時新增網站的內容並節省網站開發的成本。

其中有一個問題是“你會買一輛SUV么?”,在回答中有90.6%的人表示準備買SUV,這麼高的數據比例其實不驚人,確實在近幾年的汽車市場中,SUV持續火爆,自主品牌也厚積薄發,像哈弗H6,榮威RX5,吉利博越,寶駿560等等。那麼問題來了,廠家如此重本地研發SUV,加上越來越多消費者買SUV,究竟為的是什麼?

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

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

什麼是銷售文案服務?A就是幫你撰寫適合的廣告文案。當您需要販售商品、宣傳活動、建立個人品牌,撰寫廣告文案都是必須的工作。

瑞虎3x 4G看點揭秘 打造中國最強智能語音行車系統_網頁設計公司

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

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

頂級互聯支撐 瑞虎3x讓年輕人越玩越high基於Cloudrive2。0系統的支持,瑞虎3x成為同級別中最具玩味的入門級小型SUV,也是同級唯一擁有4G互聯的車型,加上動感的造型、出色的操控,讓年輕人越玩越high。造型上,瑞虎3x採用了奇瑞最新的Life in motion(生•動)設計語言,一體式前格柵大燈組、16寸和17寸超大鋁合金輪轂、C字型光影尾燈,讓年輕人玩的更炫。

奇瑞進入戰略2.0后提出了產品年輕化的品牌核心理念,相繼推出的艾瑞澤5和瑞虎7均實現了產品年輕化。如今奇瑞戰略2.0后的第三款車型瑞虎3x已經進入了上市的“倒計時”,定位於“4G智趣SUV”的瑞虎3x憑藉什麼讓年輕人為之瘋狂?11月7日,奇瑞聯合科大訊飛在安徽合肥舉辦一場“4G智趣SUV 瑞虎3x Cloudrive2.0智雲互聯行車系統玩轉派對”活動,現場展示了其智能語音系統的奧秘。

不惜成本 打造中國最強智能語音行車系統

之所以稱之為“4G智趣SUV”,瑞虎3x離不開強大的互聯繫統的支持。為了實現產品的全面年輕化和智能化,奇瑞很早就與科大訊飛合作,強強聯合開發了Cloudrive系統,並不斷進化升級,不惜成本的為消費者打造更智能更便捷的互聯體驗。

據悉,瑞虎3x上的移動4G wifi信號極強,並可以為多達10部移動終端提供4G網絡熱點,在任何地點都能實現最快的瀏覽速度,為用戶提供了更好的上網體驗。此外,瑞虎3x還擁有全球最強語音系統,其採用科大訊飛雙麥語音降噪模塊,具備雲+端語音識別,極大增強了語音識別的成功率,並支持數十種方言,使車載語音不再是“小白”。

界面方面,瑞虎3x的Cloudrive2.0系統搭載了8英寸觸控大屏,分辨率達到1080p高清級別,UI界面也做到了極簡設計,並有聖誕版、春節版、搶紅包版等等多種個性桌面,讓每個車主都有自己的個性主題。

此外 通過專屬手機App,

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

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

用戶可隨時隨地獲取車輛信息,查詢違章等,該系統還支持免費在線升級,可以隨時享受最新的智能體驗。可以說瑞虎3x搭載的這套新系統無論是語音交互的融會貫通,還是娛樂導航極簡的交互和UI設計,都具有業內突出的表現,功能和性能都達到國內智能語音系統的最高水準。

頂級互聯支撐 瑞虎3x讓年輕人越玩越high

基於Cloudrive2.0系統的支持,瑞虎3x成為同級別中最具玩味的入門級小型SUV,也是同級唯一擁有4G互聯的車型,加上動感的造型、出色的操控,讓年輕人越玩越high。

造型上,瑞虎3x採用了奇瑞最新的Life in motion(生•動)設計語言,一體式前格柵大燈組、16寸和17寸超大鋁合金輪轂、C字型光影尾燈,讓年輕人玩的更炫。

動力方面,瑞虎3x採用了1.5+5MT和1.5+4AT全新動力組合,為年輕人提供了肆意玩樂的動力與操控、這台1.5L發動機最大功率高達106馬力,同時瑞虎3x還採用了蓮花調校基礎上的精準調校底盤,以及186mm的超強通過性,帶來了完美的操控樂趣。

此外,瑞虎3x在奇瑞技術2.0強大的依託下,還具備超越同級的品質保障。配置上,瑞虎3x不光有Cloudrive2.0智雲互聯行車系統,還有雙色皮織混搭座椅、真皮多功能方向盤、電動天窗,ESC电子穩定系統、HHC坡道輔助控制、倒車雷達+動態輔助倒車影像和TpMS胎壓監測等舒適和安全裝備,讓小車不再低廉,也讓所有喜愛瑞虎3x的年輕人玩的起。

奇瑞進入戰略2.0后一直強調品牌年輕化,並用實際行動證明其新產品的確深諳年輕消費者的用車需求,深深的抓住了目標消費群體,因此才有艾瑞澤5和瑞虎7的大賣。如今,為玩樂而生的瑞虎3x即將到來,它將是那些追求新鮮、個性,並以玩樂為主的年輕人的最佳之選,瑞虎3x將於11月15日在北京、成都、長沙三地聯動上市,讓我們一起期待這一時刻。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※想知道最厲害的網頁設計公司嚨底家"!

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

上汽MG名爵全新SUV定名 名爵 ZS將於廣州車展亮相_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

其中,16T發動機採用小排量缸內中置直噴渦輪增壓等國際最先進技術,排量僅1。0L,最大功率卻高達125馬力,峰值扭矩170牛•米,動力性能優於1。6L自然吸氣發動機,實現同級最強的性能表現,又能兼顧超低油耗。1。5L發動機最大功率120馬力,峰值扭矩達到150牛•米。

11月9日,上汽乘用車宣布,MG名爵旗下全新緊湊型互聯網SUV定名“名爵ZS”,同時還發布了官圖。據了解,名爵ZS將於11月18日在廣州車展全球首發。

名爵ZS

名爵ZS名字本身就寓意了年輕一代。字母Z代表年輕人熱情、活潑的個性標籤,“Z一代”的年輕人,呼吸着互聯網的空氣,

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

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

既能秒懂國際大事,又能玩轉最新互聯應用。作為聚焦年輕人的互聯網SUV,名爵ZS詮釋了年輕一代專屬、真實的生活態度,是他們追求潮流、綻放個性的平台,將成為年輕人的SUV首選。

名爵ZS將搭載上汽“世界級”藍芯動力科技16T和1.5L發動機。其中,16T發動機採用小排量缸內中置直噴渦輪增壓等國際最先進技術,排量僅1.0L,最大功率卻高達125馬力,峰值扭矩170牛•米,動力性能優於1.6L自然吸氣發動機,實現同級最強的性能表現,又能兼顧超低油耗;1.5L發動機最大功率120馬力,峰值扭矩達到150牛•米。

MG名爵始終致力於為年輕人打造純粹的駕控樂趣。名爵ZS融合了國際范兒的全新設計語言、智能互聯繫統以及領先動力科技,是一輛滿足年輕人潮流、時尚、個性需求的互聯網汽車。榮威RX5爆款在前,名爵ZS緊隨其後,有望再次引爆SUV市場。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

兩位70歲老人花了十個月拉票 只為成為這台車的主人!_貨運

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

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

艾森豪威爾(Eisenhower)總統是出了名的汽車發燒友。1953年,艾森豪威爾駕駛着一款首批量產的凱迪拉克Eldorado車型在其總統就職典禮上精彩亮相。凱迪拉克Eldorado是汽車設計史上的典範,佔有極其重要的地位,它首創的弧形擋風玻璃作為一個標誌性的汽車設計理念,很快就被其他量產新車型所效仿。

縱觀歷史,凱迪拉克品牌長久以來都承載着美國總統專屬座駕的使命。憑藉全面的安全配置和時尚高貴的設計風格,凱迪拉克一直都備受歷屆美國總統的青睞,讓我們一起來回顧一下凱迪拉克十大經典車型與美國總統之間的不解淵源。

美國總統伍德羅·威爾遜(Woodrow Wilson)乘站在1919款凱迪拉克Type57,這是一款七座轎車,同時也標志著首位美國總統踏上了異國土地。

1919年,在美國慶祝“一戰”勝利的大型巡遊活動上,當時的總統伍德羅·威爾遜(Woodrow Wilson)就乘坐了一輛1916年款的凱迪拉克Series 53穿越波士頓大街。搭載首次大規模量產的V8發動機的凱迪拉克車型之所以在歐洲戰爭期間大受歡迎,正是憑藉發動機無與倫比的強勁動力以及經久耐用的穩定性能。

美國總統卡爾文·柯立芝(Calvin Coolidg)在其任職末期的座駕是1928年款的凱迪拉克341 Town車型。凱迪拉克341系列於1928年問世,此款車型搭載光滑雙拼面曲軸V8發動機,輸出功率67千瓦。此外,該款車型還採用了3速手動變速箱和可傾斜的前照燈。1928年款凱迪拉克完美融合了精緻典雅的工藝性和藝術感,成為了美國總統的專屬座駕。

珍珠港事件后,美國總統富蘭克林·羅斯福(Franklin D. Roosevelt)選擇了裝備有重裝甲的1928年款凱迪拉克Town 車型,該車原為美國黑幫頭目阿爾·卡彭(Al Capone)所有。

1938年,通用汽車將兩輛凱迪拉克敞篷車交付給美國政府,分別命名為“Queen Mary”和“Queen Elizabeth”。這兩款車是以當時的兩大游輪命名的,它們的車長約為6.5米,重達3.5噸,兩車均配有一個小型武器裝備箱、雙向無線電裝置及重型發電機。憑藉其出色的穩定性及耐用性,這兩款座駕曾先後服務於三位美國總統:富蘭克林·羅斯福(Franklin D. Roosevelt)、哈利·杜魯門(Harry S. Truman)和德懷特·艾森豪威爾(Dwight D. Eisenhower)。

美國總統哈利·杜魯門(Harry S. Truman)在白宮前乘坐1947年款凱迪拉克轎車。

艾森豪威爾(Eisenhower)總統是出了名的汽車發燒友。1953年,

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

艾森豪威爾駕駛着一款首批量產的凱迪拉克Eldorado車型在其總統就職典禮上精彩亮相。凱迪拉克Eldorado是汽車設計史上的典範,佔有極其重要的地位,它首創的弧形擋風玻璃作為一個標誌性的汽車設計理念,很快就被其他量產新車型所效仿。

1956年,凱迪拉克“Queen Mary II”與“Queen Elizabeth II”敞篷轎車取代了其上一代車型,不但為艾森豪威爾總統服務,並繼續服務於約翰·肯尼迪(John F. Kennedy)和林頓·約翰遜(Lyndon B. Johnson)兩任總統。這兩輛車於1968年正式退役。

1983年款的凱迪拉克Fleetwood和凱迪拉克Fleetwood Brougham成為里根總統(Ronald W. Reagan)的專用座駕。人們曾猜測1993年由好萊塢巨星伊斯特伍德(Clint Eastwood)出演的《火線狙擊》電影中使用的是凱迪拉克Fleetwood總統座駕“真身”,但實際上,電影中使用的只是一款精心打造的複製品,並不是總統當時乘坐的那款車。出於安全考慮,總統座駕向來只作為公務用車出勤。

1993年,凱迪拉克車型成為克林頓(William J. Clinton)總統的座駕,一個全新的時代由此開啟。在此之前,總統座駕通常都是在量產車型的基礎上改裝而來。但1993年款的凱迪拉克Brougham總統系列車型是由凱迪拉克品牌通過絕對安全的程序,特別設計、研發和製造而成的,以確保總統用車的私密性及安全性,這樣的慣例一直延續到現在。

1983年款的凱迪拉克Fleetwood豪華轎車現存放於加州西米穀市的里根圖書館內, 1993年款凱迪拉克Fleetwood Brougham則存放於阿肯色州小石城的克林頓總統中心。

美國總統奧巴馬的凱迪拉克新座駕於2009年1月20日在奧巴馬總統的就職遊行時已正式亮相。該車沿用了總統專機的命名規則,被稱為“凱迪拉克一號”,它融合了凱迪拉克量產車標誌性的設計和先進的技術,同時兼具總統座駕的獨特性能。這台車的技術參數僅被少數通用汽車設計團隊的成員所知,它最顯著的特點在於擁有比前輩更加挺拔的姿態,在外觀上極易辨識。

隨着2016美國大選結果的揭曉,將服務新任美國總統的全新一代的凱迪拉克總統專屬座駕也已經研發完畢。在2017年1月的美國總統就職典禮上,全新的“凱迪拉克一號”將與第四十五任美國總統一起,開始全新的歷史征程。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

一段車禍視頻血的教訓告訴你為什麼必須遠離大貨車!_網頁設計公司

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

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

)無視大貨車,強塞的後果這一段事故中右邊的白色小車不單單違規,實線變道,還無視左後側的大貨車,結果就車頭都沒了。要知道,像這種“拖頭”,撞小車,和你捏爛一塊豆腐是差不多感覺的,不痛不癢,並且就這麼短的距離,突然的硬“插”,大貨車司機能反應過來,車本身也反應不過來。

大貨車盲區多,這是眾所周知的,不單單是行人要注意,行車中更要注意。老司機常說,看見大貨車,不要跟隨,不要並排,不要硬塞,不要走前頭。

老司機這樣的警示並不是沒有道理,首先大家先來看看大貨車盲區,可以說除了駕駛位前方,基本都是盲區,請看下圖。

別看大貨車的駕駛位高,但其實盲區很多,並且由於一些大貨車的“拖箱”很長,還會有“內輪差”,也就是轉彎的時候,車廂和車頭的路徑是不一樣的,車廂會佔據向轉彎方向的那邊。

文字的東西,相信大家也看不少了,那麼這次直接讓大家來個視覺上感受,更直觀感受為什麼總是強調遠離大貨車。

(視頻建議在WiFi狀態下觀看,土豪請隨意!)

無視大貨車,強塞的後果

這一段事故中右邊的白色小車不單單違規,實線變道,還無視左後側的大貨車,

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

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

結果就車頭都沒了。要知道,像這種“拖頭”,撞小車,和你捏爛一塊豆腐是差不多感覺的,不痛不癢,並且就這麼短的距離,突然的硬“插”,大貨車司機能反應過來,車本身也反應不過來。

在接下來的這一段事故中,同樣是不顧左後側的大貨車,而此時正是處於大貨車的盲區,強“插”的結果就是,被大貨車強行推着走了幾百米,直到小車被甩出去了,這就是為什麼說小車面對大貨車犹如一塊豆腐。

還有像這種,不管是大貨車還是小貨車,超載對於他們來說,在平常不過了。就像視頻中的這段,由於轉彎加上暴風,由於超載,貨物堆積較高,貨車承受不住,直接被吹翻,如果此時右側的小車是並排的狀態,那必然成為“受害者”。

總結:現在大多數人的認知,只要大貨車有“參与”的事故,多數都會認為責任在於大貨車,在看了上方的視頻后,還會這樣想么,雖然有一些仍然是大貨車本身的責任,但是主要是個机械,任何時候都會有可能出現故障,大貨車車和小車不同,小車失控想要控制下來簡單的多,而大貨車失控,基本是控制不到的了。所以,在剛出駕校的時候,為什麼老司機總是要提醒遠離大貨車,就是這個原因。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

1.3T動力強?比速新SUV/MPV預售價僅6.19-8.6萬_租車

※超省錢租車方案

商務出差、學生出遊、旅遊渡假、臨時用車!GO 神州租賃有限公司!合法經營、合法連鎖、合法租賃小客車!

總結:外觀上也算是比較高顏值,原創度方面值得表揚,豐富的配置和良好的空間表現,綜合實力還是比較強的,未來的路充滿挑戰啊。比速M3預售價:6。19-8。39萬比速M3主要針對的是嚮往舒適安逸生活的家庭消費群體而打造的,外觀上更有精緻感,車身線條簡潔舒暢,誇張的X造型中網採用大面積鍍鉻裝飾,給人很霸氣的感覺,辨識度很高,B、C、D柱也是採用黑色設計,懸浮車頂非常時尚。

比速T3

預售價:7.49-8.69萬元

比速T3的整體外觀設計走的是時尚風格,進氣格柵與大燈採用整體式設計,視覺效果出色,再加上鍍鉻飾條的點綴與中央“BISU”車標巧妙的融合,營造了飛翼式的造型特點,黑色運動包圍與車頂行李架很有SUV的范。

而側面A柱、B柱和C柱都採用了黑色的設計,營造出懸浮式車頂的炫酷效果,雙五輻式輪圈,硬朗的尾燈線條,雙邊雙出的排氣管,運動感十足。

內飾部分依然透露着很潮流的氣息,黑棕雙色搭配的內飾很顯檔次,多處採用銀色飾條飾板,凸顯年輕的風格,懸浮式的中控屏設計是一大亮點,據說,比速T3還全系標配車身穩定系統、四輪碟剎、倒車雷達、中控大屏、倒車影像等使用功能。

比速T3的長寬高分別為4350/1825/1685mm,軸距為2565mm,與哈弗H2、瑞風S3等競爭對手相比稍微佔優,雙縫線皮質座椅質感出色,前後排空間表現還算良好,

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

有別於一般網頁架設公司,除了模組化的架站軟體,我們的營業主軸還包含:資料庫程式開發、網站建置、網頁設計、電子商務專案開發、系統整合、APP設計建置、專業網路行銷。

儲物格空間比較實用。

動力方面,比速T3全系標配1.3T發動機,最大功率133馬力,與之匹配的5擋手動變速器,相信不會讓我們失望。

總結:外觀上也算是比較高顏值,原創度方面值得表揚,豐富的配置和良好的空間表現,綜合實力還是比較強的,未來的路充滿挑戰啊。

比速M3

預售價:6.19-8.39萬

比速M3主要針對的是嚮往舒適安逸生活的家庭消費群體而打造的,外觀上更有精緻感,車身線條簡潔舒暢,誇張的X造型中網採用大面積鍍鉻裝飾,給人很霸氣的感覺,辨識度很高,B、C、D柱也是採用黑色設計,懸浮車頂非常時尚。

內飾整體造型設計還是挺跟得上潮流的,仿木飾板的加入提升了不少豪華感,雖說這個價位來說塑料面板在所難免,但是邊緣仿縫線的設計增添了很多精緻感,頂配車型一塊10英寸的中控屏是一大亮點,支持手機互聯、導航等主流功能。

其長*寬*高為4760*1810*1751mm,軸距達到2800mm,和寶駿730等競品相比很有優勢,門板還有擋把兩側都包裹了皮革、絨布等軟性材質,觸感很好,即使是第三排空間也很舒適。

在動力系統部分,將提供了1.5L自然吸氣發動機,最大功率114馬力,後期還會有1.5T渦輪增壓發動機和CVT變速器,而傳動部分,將搭載5擋手動變速器。

總結:在高手如雲的自主品牌MpV市場里,會與有寶駿730、風行S500等車型廝殺,相信在車內空間、配置方面有優勢的比速M3會得到用戶的肯定。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

日本、大陸,發現這些先進的國家已經早就讓電動車優先上路,而且先進國家空氣品質相當好,電動車節能減碳可以減少空污