分類: 3C資訊

  • 積極拓電動車市場,Hyundai推EV車用平台

    積極拓電動車市場,Hyundai推EV車用平台

     

    特斯拉(Tesla)電動車成功引領話題,各大車廠跟紛紛仿效,搶攻此一市場。原本力推燃料電池車的韓國車廠–現代汽車(Hyundai Motor),眼看市場風向轉變,也宣布要研發該公司首款電動車專屬的車用平台(car platform)。

    路透社30日報導,車用平台意指外觀不同的汽車共享相通的設計、工程、生產流程,以及主要零件等,能夠壓低研發成本。現代汽車之前力推燃料電池車,如今轉攻電池車,突顯投資人施壓,要求該公司積極進軍新市場。

    現代汽車的電動車平台,電池將位於汽車底部,以便容納大容量電池,並讓車內空間最大化。現代-起亞環保車主管Lee Ki-sang說,電動車平台初期投資費用高,但是他們必須替未來做準備。分析師說現代別無選擇,必須追隨特斯拉、通用汽車、Daimler AG旗下的賓士(Mercedes-Benz),打造單獨的電動車平台,才能留在此一市場。

    Hi Investment & Securities分析師Ko Tae-bong表示,單獨平台初始時可能會造成虧損,但是現代若不研發長程電動車將落後對手,例如300、500、600公里車款。

    電動車大廠特斯拉(Tesla Inc.)要價35,000美元的平價車種「Model 3」預計2017年稍晚就能開賣,摩根士丹利(通稱大摩)認為,這款電動車的安全度會是一般車輛的10倍之多,發生死亡車禍的機率有望比其他車種低90%。

    MarketWatch、Business Insider等外電報導,大摩分析師Adam Jonas 23日發表研究報告指出,特斯拉為每台車安裝超級電腦後,車子安全性提升至其他車輛兩倍已經不夠看,他相信Model 3的安全度會是其他車輛的十倍之多,這會讓死亡車禍的發生機會降低90%。

    Jonas認為,缺少特斯拉駕車輔助科技的二手車價值將因而猛掉,未來甚至會被禁止上路。特斯拉蒐集資料的能力超群,還能將先進的安全輔助技術應用到電動車,還未推出類似科技的傳統車廠,競爭力堪虞。

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

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

    【其他文章推薦】

    ※超省錢租車方案

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

    ※回頭車貨運收費標準

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

    FB行銷專家,教你從零開始的技巧

  • 博弈論——兩人取子遊戲與威佐夫博弈,隱藏在背後的黃金分割

    博弈論——兩人取子遊戲與威佐夫博弈,隱藏在背後的黃金分割

    本文始發於個人公眾號:TechFlow,原創不易,求個關注

    今天是算法和數據結構專題第25篇文章,我們繼續博弈論專題。

    在上一篇文章當中我們了解了最簡單的巴什博奕,今天我們來看看另一個經典的博弈模型——威佐夫博弈。博弈論和機器學習有些類似,數學家們針對場景進行建模,設計出了幾個經典模型。然後我們在面臨具體問題的時候,對問題進行深入分析,尋找最合適的模型應用來解決它。

    石子問題

    我們來看一道經典的例題,有兩堆石子,有兩個絕頂聰明的人在玩一個遊戲。每次每個人可以從其中一堆石子當中取走任意數量的石子,或者是從兩堆當中同時取走相同數量的石子。無法取石子的人落敗,請問,在告知兩堆石子數量的情況下,這兩個人當中哪一方會獲勝?

    我們簡單分析一下,會發現一些局面是先手必敗的。比如說(0, 0),再比如(1, 2)。我們簡單分析一下(1, 2),先手有4種策略,首先他可以取走第一堆,那麼後手可以取完第二堆,顯然後手獲勝。他也可以在第二堆當中取1個,這時剩下(1, 1),後手會同時取完,同樣是後手獲勝。第三種是他取走第二堆,後手可以取完第一堆,後手獲勝。第四種是他在第一堆和第二堆當中同時取走一個,這時第二堆剩下一個,後手勝。

    那麼,這些必敗的狀態之間有什麼規律呢?我們怎麼找到這個規律,並且找到解呢?

    分析

    我們可以枚舉幾個必敗的狀態:(0, 0), (1, 2), (3, 5), (4, 7)…

    我們觀察一下這些狀態,可以找到兩條規律。我們假設從小到大排的第k個必敗狀態是(x, y),並且x < y。我們可以發現y = x + k。也就是說必敗狀態兩個數的差值是遞增的,這也說明了每一個必敗狀態的差值都各不相同。

    其實這是很容易證明的,我們用反證法,假設(a, a+k), (b, b+k)都是必敗狀態,並且a < b。那麼先手在面臨(b, b+k)的時候,只需要在兩堆當中同時取走b-a個石子,那麼給後手的局面就是(a, a+k)。對於後手來說,這是一個必敗的局面,這就和(b, b+k)先手必敗矛盾,所以不存在兩個必敗局面的差值相等

    我們也可以作圖分析,我們把兩堆石子的數量看成是坐標軸上的一個點。所以遊戲就變成了:棋盤上有一個點,每次每個人可以將它向下、向左或者向左下移動若干個格子,不能移動的人輸。終止節點顯然是原點,一步就能移動到原點的點顯然是必勝點,假設我們給這些所有必勝點都染色的話,剩下的的沒當中橫縱坐標和最小的點就是下一個必敗點。因為它不論如何移動,都會給對手留下一個必勝點。

    我們根據上面的邏輯把必敗點都染色,可以得到下面這張圖:

    從這張圖可以看出,必敗點之間不能通過一次移動得到,換句話說可以一次移動到必敗點的點都是必勝點,從圖上可以看出,除了必敗點的之外的點都是必勝點,並且每一個自然數都必然只會被包含在一個必敗狀態當中。

    到這裏,我們距離解法已經很接近了,現在剩下的問題是,我們如何根據x和y的取值快速判斷它們是否構成一個必敗局面呢?也就是說我們能不能找出一個通項公式,對於第k個必敗局面,它的坐標是(\(x_k, y_k\))呢?

    求解

    為了寫出通項公式,我們需要引入Betty定理

    設a和b是兩個正無理數,並且\(\frac{1}{a} + \frac{1}{b} = 1\)

    記P={[\(a_n\)], \(n \in N^+\)}, Q={[\(b_n\)], \(n \in N^+\)},則\(P \cap Q = \varnothing\)\(P\cup Q = N^+\)

    證明

    \(P\cap Q = \varnothing\)

    反證,我們假設存在\(k \in P\)並且\(k \in Q\),即存在正整數n, m滿足 k < an, bm < k+1。

    也就是:\(\frac{n}{k} > \frac{1}{a} > \frac{n}{k+1}, \frac{m}{k} > \frac{1}{b} > \frac{m}{k+1}\)兩個式子相加可以得到:\(\frac{m+n}{k} > 1 > \frac{m+n}{k}\)

    \(k < n+m < k+ 1\),這與n,m,k都是正整數矛盾

    \(P \cup Q = N^+\)

    反證,假設存在\(k \notin P\)\(k \notin Q\),即存在正整數n,m滿足\(an < k < a(n+1)-1, bm < k < b(m+1)-1\)

    即:\(\frac{n}{k} < \frac{1}{a} < \frac{n+1}{k+1}, \frac{m}{k} < \frac{1}{b} < \frac{m+1}{k+1}\)

    相加,可以得到:\(\frac{m+n}{k} < 1 < \frac{n+m+2}{k+1}\)

    即:n + m < k < n + m + 1,這與n,m,k均為正整數矛盾

    我們花了這麼大力氣來證明Betty定理就是為了用的,因為我們發現必敗狀態的通項和Betty定理序列很像。我們不妨假設存在這樣的a, b同時滿足Betty定理與必敗狀態的性質:

    \[[an] + n = [bn], \frac{1}{a} + \frac{1}{b} = 1 \]

    \[[an] + n = [an + n] = [(a+1)n] = [bn] \]

    代入可以得到:

    \[\frac{1}{a} + \frac{1}{a+1} = 1 \]

    解這個方程,可以得到\(a = \frac{1 + \sqrt{5}}{2}\approx 1.618\),熟悉數學的同學相信一下就看出來了,這個數是黃金分割的比例,這是巧合嗎,還是藏着更深的道理呢?

    至少,求出了a之後,我們就可以非常簡單地判斷必敗狀態了:

    import math
    def lose_or_win(a, b):
        if a > b:
            a, b = b, a
        
        k = b - a
        # 根據差值k求出第k個必敗狀態,判斷是否相等
        return not (int(k * (math.sqrt(5)+1) / 2)) == a
    

    總結

    和之前介紹的巴什博奕相比,威佐夫博弈的推導過程要複雜得多,但是雖然推導過程依然複雜,但是仍然擋不住最後實現的代碼非常簡單。

    另外,在推導的過程當中,我們用到了Betty定理,這個定理的推導和證明雖然不難,但是如果不是數學專業的同學,可能大概率都沒有接觸過。這其實體現了博弈論本身和數學的關係是非常緊密的。一個看起來非常簡單的問題,引申出了一系列眼花繚亂的推導和證明,怎麼樣,大家看得還過癮嗎?

    今天的文章到這裏就結束了,如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

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

    【其他文章推薦】

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

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

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

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

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

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

  • Task.Result跟 Task.GetAwaiter.GetResult()相同嗎?怎麼選?

    前幾天在用線程池執行一些任務時運到一種情形,就是回調方法中使用到了異步方法,但是回調方法貌似不支持async await的寫法。這時候我應該如何處理呢?是使用Task.Result來獲取返回結果,還是使用GetAwaiter.GetResult()呢?本文就來探討下吧。

    作者:依樂祝

    原文地址:https://www.cnblogs.com/yilezhu/p/13168337.html

    這裏先上我這種場景的偽代碼:

    ThreadPool.QueueUserWorkItem(ExcuteScanProcess, node);
    

    ExcuteScanProcess這個回調方法中

    private void ExcuteScanProcess(object state)
    {
        ……其他處理……
        repository.UpdateAsync(node).ConfigureAwait(false).GetAwaiter().GetResult();
        ……其他處理……
    }
    

    如上圖所示repository.UpdateAsync(node)屬於一部方法,這時候我想要等待它異步執行完成之後再執行後續的邏輯。這時候我有兩種選擇,是直接

    repository.UpdateAsync(node).ConfigureAwait(false).GetAwaiter().GetResult();
    

    好呢,還是

    repository.UpdateAsync(node).ConfigureAwait(false).Result;
    

    好呢?

    為此我查找了相關的資料,對它倆的區別做一個簡單的總結:

    其實這兩個使用方式是差不多的。不過,還是有一點小小的區別的:如果任務失敗,Task.GetAwaiter().GetResult()會直接拋出異常,而Task.Result則會把異常包裝在AggregateException中。從這個角度說Task.GetAwaiter().GetResult()要優於Task.Result。畢竟它少了異常的包裝操作,即直接拋出異常,而不是把異常包裝在AggregateException中。

    下面的引言解釋了為什麼Task.Result不僅僅包含Task.GetAwaiter().GetResult()(由於“非常高的兼容性”)的異常傳播行為。

    如前所述,我們有一個非常高的兼容性標準,因此我們避免了改動。因此,Task.Wait保留了始終包裝的原始行為。但是,您可能會發現自己處在某些高級情況下,這些情況下您想要的行為類似於所採用的同步阻塞Task.Wait,但是您希望將原始異常展開而不是傳播,而不是將其封裝在AggregateException中。為此,您可以直接定位任務的等待者。當您編寫“ await task;”時,編譯器Task.GetAwaiter()會將其轉換為方法的用法,這將返回具有GetResult()方法的實例。當用於有故障的任務時,GetResult()將傳播原始異常(這是“ await task;” 如何獲得其行為)。因此,您可以使用“task.GetAwaiter().GetResult()如果您想直接調用此傳播邏輯。

    https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/

    GetResult”實際上表示“檢查任務是否有錯誤”

    通常,我會儘力避免對異步任務進行同步阻塞。但是,在少數情況下,我確實違反了該準則。在那些罕見的情況下,我的首選方法是GetAwaiter().GetResult()因為它保留任務異常,而不是將它們包裝在中AggregateException

    總結

    通過上述內容的闡述,因此在那些必須對異步任務進行同步阻塞的場景中,我選擇使用GetAwaiter().GetResult()

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

    【其他文章推薦】

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

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

    ※台北網頁設計公司全省服務真心推薦

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

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

  • 這一次搞懂Spring Web零xml配置原理以及父子容器關係

    這一次搞懂Spring Web零xml配置原理以及父子容器關係

    前言

    在使用Spring和SpringMVC的老版本進行開發時,我們需要配置很多的xml文件,非常的繁瑣,總是讓用戶自行選擇配置也是非常不好的。基於約定大於配置的規定,Spring提供了很多註解幫助我們簡化了大量的xml配置;但是在使用SpringMVC時,我們還會使用到WEB-INF/web.xml,但實際上我們是完全可以使用Java類來取代xml配置的,這也是後來SpringBoott的實現原理。本篇就來看看Spring是如何實現完全的零XML配置。

    正文

    先來看一下原始的web.xml配置:

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          <!--加載spring配置-->
          classpath:spring.xml
        </param-value>
      </context-param>
      <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>ServicePlatform.root</param-value>
      </context-param>
    
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        <!--<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>-->
      </listener>
    
      <servlet>
        <servlet-name>spring-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <!--springmvc的配置文件-->
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring-dispatcher.xml</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>spring-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
    

    這裏各個配置的作用簡單說下,context-param是加載我們主的sping.xml配置,比如一些bean的配置和開啟註解掃描等;listener是配置監聽器,Tomcat啟動會觸發監聽器調用;servlet則是配置我們自定義的Servlet實現,比如DispatcherServlet。還有其它很多配置就不一一說明了,在這裏主要看到記住context-paramservlet配置,這是SpringIOC父子容器的體現。在之前的I文章中講過IOC容器是以父子關係組織的,但估計大部分人都不能理解,除了看到複雜的繼承體系,並沒有看到父容器作用的體現,稍後來分析。
    了解了配置,我們就需要思考如何替換掉這些繁瑣的配置。實際上Tomcat提供了一個規範,有一個ServletContainerInitializer接口:

    public interface ServletContainerInitializer {
        void onStartup(Set<Class<?>> var1, ServletContext var2) throws ServletException;
    }
    

    Tomcat啟動時會調用該接口實現類的onStartup方法,這個方法有兩個參數,第二個不用說,主要是第一個參數什麼?從哪裡來?另外我們自定義的實現類又怎麼讓Tomcat調用呢?
    首先解答最後一個問題,這裏也是利用SPI來實現的,因此我們實現了該接口后,還需要在META-INF.services下配置。其次,這裏傳入的第一個參數也是我們自定義的擴展接口的實現類,我們可以通過我們自定義的接口實現很多需要在啟動時做的事,比如加載Servlet,但是Tomcat又是怎麼知道我們自定義的接口是哪個呢?這就需要用到@HandlesTypes註解,該註解就是標註在ServletContainerInitializer的實現類上,其值就是我們擴展的接口,這樣Tomcat就知道需要傳入哪個接口實現類到這個onStartup方法了。來看一個簡單的實現:

    @HandlesTypes(LoadServlet.class)
    public class MyServletContainerInitializer implements ServletContainerInitializer {
        @Override
        public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
            Iterator var4;
            if (set != null) {
                var4 = set.iterator();
                while (var4.hasNext()) {
                    Class<?> clazz = (Class<?>) var4.next();
                    if (!clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers()) && LoadServlet.class.isAssignableFrom(clazz)) {
                        try {
                            ((LoadServlet) clazz.newInstance()).loadOnstarp(servletContext);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    
    public interface LoadServlet {
    
        void loadOnstarp(ServletContext servletContext);
    }
    
    public class LoadServletImpl implements LoadServlet {
        @Override
        public void loadOnstarp(ServletContext servletContext) {
            ServletRegistration.Dynamic initServlet = servletContext.addServlet("initServlet", "org.springframework.web.servlet.DispatcherServlet");
            initServlet.setLoadOnStartup(1);
            initServlet.addMapping("/init");
    	}
    }
    

    這就是Tomcat給我們提供的規範,通過這個規範我們就能實現Spring的零xml配置啟動,直接來看Spring是如何做的。
    根據上面所說我們可以在spring-web工程下找到META-INF/services/javax.servlet.ServletContainerInitializer配置:

    @HandlesTypes(WebApplicationInitializer.class)
    public class SpringServletContainerInitializer implements ServletContainerInitializer {
    	@Override
    	public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
    			throws ServletException {
    
    		List<WebApplicationInitializer> initializers = new LinkedList<>();
    
    		if (webAppInitializerClasses != null) {
    			for (Class<?> waiClass : webAppInitializerClasses) {
    				// Be defensive: Some servlet containers provide us with invalid classes,
    				// no matter what @HandlesTypes says...
    				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
    						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
    					try {
    						initializers.add((WebApplicationInitializer)
    								ReflectionUtils.accessibleConstructor(waiClass).newInstance());
    					}
    					catch (Throwable ex) {
    						throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
    					}
    				}
    			}
    		}
    
    		if (initializers.isEmpty()) {
    			servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
    			return;
    		}
    
    		servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
    		AnnotationAwareOrderComparator.sort(initializers);
    		for (WebApplicationInitializer initializer : initializers) {
    			initializer.onStartup(servletContext);
    		}
    	}
    
    }
    
    

    核心的實現就是WebApplicationInitializer,先看看其繼承體系

    AbstractReactiveWebInitializer不用管,主要看另外一邊,但是都是抽象類,也就是說真的實例也是由我們自己實現,但需要我們實現什麼呢?我們一般直接繼承AbstractAnnotationConfigDispatcherServletInitializer類,有四個抽象方法需要我們實現:

        //父容器
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[]{SpringContainer.class};
        }
    
        //SpringMVC配置子容器
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[]{MvcContainer.class};
        }
    
        //獲取DispatcherServlet的映射信息
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
    	// filter配置
        @Override
        protected Filter[] getServletFilters() {
            MyFilter myFilter = new MyFilter();
            CorsFilter corsFilter = new CorsFilter();
            return new Filter[]{myFilter,corsFilter};
        }
    

    這裏主要注意getRootConfigClassesgetServletConfigClasses方法,分別加載父、子容器:

    @ComponentScan(value = "com.dark",excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
    })
    public class SpringContainer {
    }
    
    @ComponentScan(value = "com.dark",includeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
    },useDefaultFilters = false)
    public class MvcContainer {
    }
    

    看到這兩個類上的註解應該不陌生了吧,父容器掃描裝載了所有不帶@Controller註解的類,子容器則相反,但需要對象時首先從當前容器中找,如果沒有則從父容器中獲取,為什麼要這麼設計呢?直接放到一個容器中不行么?先思考下, 稍後解答。
    回到onStartup方法中,直接回調用到AbstractDispatcherServletInitializer類:

    	public void onStartup(ServletContext servletContext) throws ServletException {
    		super.onStartup(servletContext);
    		//註冊DispatcherServlet
    		registerDispatcherServlet(servletContext);
    	}
    

    先是調用父類:

    	public void onStartup(ServletContext servletContext) throws ServletException {
    		registerContextLoaderListener(servletContext);
    	}
    
    	protected void registerContextLoaderListener(ServletContext servletContext) {
    
    		//創建spring上下文,註冊了SpringContainer
    		WebApplicationContext rootAppContext = createRootApplicationContext();
    		if (rootAppContext != null) {
    			//創建監聽器
    			ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
    			listener.setContextInitializers(getRootApplicationContextInitializers());
    			servletContext.addListener(listener);
    		}
    	}
    

    然後調用createRootApplicationContext創建父容器:

    	protected WebApplicationContext createRootApplicationContext() {
    		Class<?>[] configClasses = getRootConfigClasses();
    		if (!ObjectUtils.isEmpty(configClasses)) {
    			AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    			context.register(configClasses);
    			return context;
    		}
    		else {
    			return null;
    		}
    	}
    

    可以看到就是創建了一個AnnotationConfigWebApplicationContext對象,並將我們的配置類SpringContainer註冊了進去。接着創建Tomcat啟動加載監聽器ContextLoaderListener,該監聽器有一個contextInitialized方法,會在Tomcat啟動時調用。

    	public void contextInitialized(ServletContextEvent event) {
    		initWebApplicationContext(event.getServletContext());
    	}
    
    	 */
    	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    		long startTime = System.currentTimeMillis();
    		try {
    			// Store context in local instance variable, to guarantee that
    			// it is available on ServletContext shutdown.
    			if (this.context == null) {
    				this.context = createWebApplicationContext(servletContext);
    			}
    			if (this.context instanceof ConfigurableWebApplicationContext) {
    				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
    				if (!cwac.isActive()) {
    					// The context has not yet been refreshed -> provide services such as
    					// setting the parent context, setting the application context id, etc
    					if (cwac.getParent() == null) {
    						// The context instance was injected without an explicit parent ->
    						// determine parent for root web application context, if any.
    						ApplicationContext parent = loadParentContext(servletContext);
    						cwac.setParent(parent);
    					}
    					configureAndRefreshWebApplicationContext(cwac, servletContext);
    				}
    			}
    			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
    
    			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
    			if (ccl == ContextLoader.class.getClassLoader()) {
    				currentContext = this.context;
    			}
    			else if (ccl != null) {
    				currentContextPerThread.put(ccl, this.context);
    			}
    
    			return this.context;
    		}
    	}
    

    可以看到就是去初始化容器,這個和之前分析xml解析是一樣的,主要注意這裏封裝了ServletContext對象,並將父容器設置到了該對象中。
    父容器創建完成后自然就是子容器的創建,來到registerDispatcherServlet方法:

    	protected void registerDispatcherServlet(ServletContext servletContext) {
    		String servletName = getServletName();
    		Assert.hasLength(servletName, "getServletName() must not return null or empty");
    
    		//創建springmvc的上下文,註冊了MvcContainer類
    		WebApplicationContext servletAppContext = createServletApplicationContext();
    		Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");
    
    		//創建DispatcherServlet
    		FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
    		Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
    		dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
    
    		ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
    		if (registration == null) {
    			throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
    					"Check if there is another servlet registered under the same name.");
    		}
    
    		/*
    		* 如果該元素的值為負數或者沒有設置,則容器會當Servlet被請求時再加載。
    			如果值為正整數或者0時,表示容器在應用啟動時就加載並初始化這個servlet,
    			值越小,servlet的優先級越高,就越先被加載
    		* */
    		registration.setLoadOnStartup(1);
    		registration.addMapping(getServletMappings());
    		registration.setAsyncSupported(isAsyncSupported());
    
    		Filter[] filters = getServletFilters();
    		if (!ObjectUtils.isEmpty(filters)) {
    			for (Filter filter : filters) {
    				registerServletFilter(servletContext, filter);
    			}
    		}
    
    		customizeRegistration(registration);
    	}
    
    	protected WebApplicationContext createServletApplicationContext() {
    		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    		Class<?>[] configClasses = getServletConfigClasses();
    		if (!ObjectUtils.isEmpty(configClasses)) {
    			context.register(configClasses);
    		}
    		return context;
    	}
    
    

    這裏也是創建了一個AnnotationConfigWebApplicationContext對象,不同的只是這裏註冊的配置類就是我們的Servlet配置了。然後創建了DispatcherServlet對象,並將上下文對象設置了進去。看到這你可能會疑惑,既然父子容器創建的都是相同類的對象,何來的父子容器之說?別急,這個在初始化該上文時就明白了。但是這裏的初始化入口在哪呢?沒有看到任何監聽器的創建和調用。實際上這裏的上下文對象初始化是在Servlet初始化時實現的,即init方法,直接來到HttpServletBeaninit方法(分析SpringMVC源碼時講過):

    	public final void init() throws ServletException {
    		...省略
    		
    		// Let subclasses do whatever initialization they like.
    		initServletBean();
    	}
    
    	protected final void initServletBean() throws ServletException {
    		try {
    			this.webApplicationContext = initWebApplicationContext();
    			initFrameworkServlet();
    		}
    	}
    
    	protected WebApplicationContext initWebApplicationContext() {
    		//這裡會從servletContext中獲取到父容器,就是通過監聽器加載的容器
    		WebApplicationContext rootContext =
    				WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    		WebApplicationContext wac = null;
    
    		if (this.webApplicationContext != null) {
    			// A context instance was injected at construction time -> use it
    			wac = this.webApplicationContext;
    			if (wac instanceof ConfigurableWebApplicationContext) {
    				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
    				if (!cwac.isActive()) {
    					if (cwac.getParent() == null) {
    						cwac.setParent(rootContext);
    					}
    					//容器加載
    					configureAndRefreshWebApplicationContext(cwac);
    				}
    			}
    		}
    		if (wac == null) {
    			wac = findWebApplicationContext();
    		}
    		if (wac == null) {
    			wac = createWebApplicationContext(rootContext);
    		}
    
    		if (!this.refreshEventReceived) {
    			synchronized (this.onRefreshMonitor) {
    				onRefresh(wac);
    			}
    		}
    
    		if (this.publishContext) {
    			// Publish the context as a servlet context attribute.
    			String attrName = getServletContextAttributeName();
    			getServletContext().setAttribute(attrName, wac);
    		}
    
    		return wac;
    	}
    

    看到這裏想你也應該明白了,首先從ServletContext中拿到父容器,然後設置到當前容器的parent中,實現了父子容器的組織,而這樣設計好處我想也是很清楚的,子容器目前裝載的都是MVC的配置和Bean,簡單點說就是Controller,父容器中都是Service,Controller是依賴於Service的,如果不構建這樣的層級關係並優先實例化父容器,你怎麼實現Controller層的依賴注入成功呢?

    總結

    本篇結合之前的文章,分析了SpringMVC零XML配置的實現原理,也補充了之前未分析到父子容器關係,讓我們能從細節上更加全面的理解SpringIOC的實現原理,相信看完本篇對於SpringBoot的實現你也會有自己的想法。

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

    【其他文章推薦】

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

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

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

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

    ※回頭車貨運收費標準

  • mysql大表在不停機的情況下增加字段該怎麼處理

    mysql大表在不停機的情況下增加字段該怎麼處理

    MySQL中給一張千萬甚至更大量級的表添加字段一直是比較頭疼的問題,遇到此情況通常該如果處理?本文通過常見的三種場景進行案例說明。

    1、 環境準備

    數據庫版本: 5.7.25-28(Percona 分支)

    服務器配置:  3台centos 7虛擬機,配置均為2CPU  2G內存

    數據庫架構: 1主2從的MHA架構(為了方便主從切換場景的演示,如開啟GTID,則兩節點即可),關於MHA搭建可參考此文 MySQL高可用之MHA集群部署

    準備測試表:  創建一張2kw記錄的表,快速創建的方法可以參考快速創建連續數

    本次對存儲過程稍作修改,多添加幾個字段,存儲過程如下:

    DELIMITER $$
    CREATE  PROCEDURE `sp_createNum`(cnt INT )
    BEGIN
        DECLARE i INT  DEFAULT 1;
        DROP TABLE  if exists  tb_add_columns;
        CREATE TABLE if not exists tb_add_columns(id int primary key,col1 int,col2 varchar(32));
        INSERT INTO tb_add_columns(id,col1,col2) SELECT i  as id ,i%7 as col1,md5(i) as col2;
        
        WHILE i < cnt DO
          BEGIN
            INSERT INTO tb_add_columns(id,col1,col2) SELECT id + i   as id ,( id + i) %7 as col1,md5( id + i) as col2  FROM tb_add_columns WHERE id <=cnt - i ;
            SET i = i*2;
          END;
        END WHILE;
    END$$
    DELIMITER ;

    調用存儲過程,完成測試表及測試數據的創建。

    mysql> call sp_createNum(20000000);

     2.  直接添加字段

    使用場景: 在系統不繁忙或者該表訪問不多的情況下,如符合ONLINE DDL的情況下,可以直接添加。

    模擬場景: 創建一個測試腳本,每10s訪問該表隨機一條記錄,然後給該表添加字段

    訪問腳本如下

    #!/bin/bash
    # gjc
    
    for i in  {1..1000000000}                    # 訪問次數1000000000,按需調整即可
    do
        id=$RANDOM                          #生成隨機數    
        mysql -uroot -p'123456' --socket=/data/mysql3306/tmp/mysql.sock  -e "select  a.*,now() from  testdb.tb_add_columns a where id = "$id     # 訪問數據
        sleep 10                            #  暫停10s
    done

    運行腳本

    sh  test.sh

     給表添加字段

    mysql> alter table  testdb.tb_add_columns add col3 int;

      此時,訪問正常。

     附ONLINE DDL的場景如下,建議DBA們必須弄清楚

    (圖片轉載於https://blog.csdn.net/finalkof1983/article/details/88355314)

     

     (圖片轉載於https://blog.csdn.net/finalkof1983/article/details/88355314)

    3.   使用工具在線添加

    雖然Online DDL添加字段時,表依舊可以讀寫,但是生產環境使用場景中對大表操作使用最多的還是使用工具pt-osc或gh-ost添加。

    本文主要介紹 pt-osc(pt-online-schema-change) 來添加字段,該命令是Percona Toolkit工具中的使用頻率最高的一種

    關於Percona Toolkit的安裝及主要使用可以參考  五分鐘學會Percona Toolkit 安裝及使用

    添加字段

    root@mha1 ~]# pt-online-schema-change --alter "ADD COLUMN  col4  int" h=localhost,P=3306,p=123456,u=root,D=testdb,t=tb_add_columns,S=/data/mysql3306/tmp/mysql.sock  --charset=utf8mb4 --execute

    主要過程如下:

    1> Cannot connect to A=utf8mb4,P=3306,S=/data/mysql3306/tmp/mysql.sock,h=192.168.28.132,p=...,u=root
    1> Cannot connect to A=utf8mb4,P=3306,S=/data/mysql3306/tmp/mysql.sock,h=192.168.28.131,p=...,u=root
    No slaves found.  See --recursion-method if host mha1 has slaves.  #  因為使用的是socket方式連接數據庫 且未配置root遠程連接賬號,所以會有此提示
    
    # A software update is available:
    Operation, tries, wait:
      analyze_table, 10, 1                                     
      copy_rows, 10, 0.25                                       
      create_triggers, 10, 1                      
      drop_triggers, 10, 1
      swap_tables, 10, 1
      update_foreign_keys, 10, 1
    Altering `testdb`.`tb_add_columns`...
    Creating new table...                                     #  創建中間表,表名為"_原表名_new"
    Created new table testdb._tb_add_columns_new OK.           
    Altering new table...                                     #  修改表,也就是在新表上添加字段,因新表無數據,因此很快加完
    Altered `testdb`.`_tb_add_columns_new` OK.                  
    2020-06-20T12:23:43 Creating triggers...                  #  創建觸發器,用於在原表拷貝到新表的過程中原表有數據的變動(新增、修改、刪除)時,也會自動同步至新表中
    2020-06-20T12:23:43 Created triggers OK.
    2020-06-20T12:23:43 Copying approximately 19920500 rows... # 拷貝數據,數據庫量是統計信息里的,不準確
    Copying `testdb`.`tb_add_columns`:  11% 03:50 remain       #  分批拷貝數據(根據表的size切分每批拷貝多少數據),拷貝過程中可以用show processlist看到對應的sql
    Copying `testdb`.`tb_add_columns`:  22% 03:22 remain
    Copying `testdb`.`tb_add_columns`:  32% 03:10 remain
    Copying `testdb`.`tb_add_columns`:  42% 02:45 remain
    Copying `testdb`.`tb_add_columns`:  51% 02:21 remain
    Copying `testdb`.`tb_add_columns`:  62% 01:48 remain
    Copying `testdb`.`tb_add_columns`:  72% 01:21 remain
    Copying `testdb`.`tb_add_columns`:  81% 00:53 remain
    Copying `testdb`.`tb_add_columns`:  91% 00:24 remain
    2020-06-20T12:28:40 Copied rows OK.                       # 拷貝數據完成
    2020-06-20T12:28:40 Analyzing new table...                # 優化新表
    2020-06-20T12:28:40 Swapping tables...                    # 交換表名,將原表改為"_原表名_old",然後把新表表名改為原表名
    2020-06-20T12:28:41 Swapped original and new tables OK.    
    2020-06-20T12:28:41 Dropping old table...                 #  刪除舊錶(也可以添加參數不刪除舊錶)
    2020-06-20T12:28:41 Dropped old table `testdb`.`_tb_add_columns_old` OK.
    2020-06-20T12:28:41 Dropping triggers...                  # 刪除觸發器
    2020-06-20T12:28:41 Dropped triggers OK.
    Successfully altered `testdb`.`tb_add_columns`.            # 完成

    修改過程中,讀寫均不受影響,大家可以寫個程序包含讀寫的

    注:  無論是直接添加字段還是用pt-osc添加字段,首先都得拿到該表的元數據鎖,然後才能添加(包括pt-osc在創建觸發器和最後交換表名時都涉及),因此,如果一張表是熱表,讀寫特別頻繁或者添加時被其他會話佔用,則無法添加。

    例如: 鎖住一條記錄

    用pt-osc添加字段,會發現一直卡在創建觸發器那一步

     此時查看對應的SQL正在等待獲取元數據鎖

    換成直接添加也一樣,例如

     當達到鎖等待后將會報錯放棄添加字段

    mysql> alter table  testdb.tb_add_columns add col5 int;
    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    對於此情況,需等待系統不繁忙情況下添加,或者使用後續的在從庫創建再進行主從切換

    4  先在從庫修改,再進行主從切換

    使用場景: 如果遇到上例中一張表數據量大且是熱表(讀寫特別頻繁),則可以考慮先在從庫添加,再進行主從切換,切換后再將其他幾個節點上添加字段。

    先在從庫添加(本文在備選節點添加)

    mysql> alter table  testdb.tb_add_columns add col5 int;
    Query OK, 0 rows affected (1 min 1.91 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    進行主從切換

    使用MHA腳本進行在線切換

    masterha_master_switch  --conf=/etc/masterha/app1.conf --master_state=alive  --orig_master_is_new_slave --new_master_host=192.168.28.131  --new_master_port=3306

    切換完成后再對其他節點添加字段

    /* 原主庫上添加192.168.28.128  */
    mysql>  alter table  testdb.tb_add_columns add col5 int;
    Query OK, 0 rows affected (1 min 8.36 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    /* 另一個從庫上添加192.168.28.132  */
    mysql>  alter table  testdb.tb_add_columns add col5 int;
    Query OK, 0 rows affected (1 min 8.64 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    這樣就完成了字段添加。

    5.  小結

    生產環境MySQL添加或修改字段主要通過如下三種方式進行,實際使用中還有很多注意事項,大家要多多總結。

    • 直接添加

    如果該表讀寫不頻繁,數據量較小(通常1G以內或百萬以內),直接添加即可(可以了解一下online ddl的知識)

    •  使用pt_osc添加

    如果表較大 但是讀寫不是太大,且想盡量不影響原表的讀寫,可以用percona tools進行添加,相當於新建一張添加了字段的新表,再降原表的數據複製到新表中,複製歷史數據期間的數據也會同步至新表,最後刪除原表,將新表重命名為原表表名,實現字段添加

    •  先在從庫添加 再進行主從切換

    如果一張表數據量大且是熱表(讀寫特別頻繁),則可以考慮先在從庫添加,再進行主從切換,切換后再將其他幾個節點上添加字段

     

     

     

     

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 流產、死胎層出不窮 南蘇丹隱匿石油業環境報告 犧牲者至今未受保障

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

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

    【其他文章推薦】

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

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

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

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

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

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

  • 2017中國國際新能源汽車產業博覽會

    展會城市:
    深圳、上海
    展會開始日期:
    深圳:2017/6/16
    上海:2017/8/23
    展會結束日期:
    深圳:2017/6/18
    上海:2017/8/25

    2017新能源汽車產業博覽會將於2017年6月16-18日,8月23-25日分別在深圳會展中心及上海新國際博覽中心舉行,本屆展會預計累計展示面積達7萬平米,展商超過800家,專業觀眾超過6萬人次,全產業鏈展示實現無縫對接。

    展會以展覽展示及技術交流為主題,組委會將重點邀請新能源汽車生產企業及核心三電(電池、電機、電控)企業參與。新能源汽車領域包括:比亞迪、北汽、上汽、宇通、金龍、青年客車、福田、中通、東風、力帆等;電池領域包括:國軒、寧德時代、力神、沃特瑪、邁科等;電機電控領域包括:寶馬、中國南車、大洋電機、中科三環、上海大郡、上海電驅動、浙江尤奈特、深圳大地和、大連機電、東風機電、南洋機電、精進電動等。

    振威展覽【股票代碼:834316】是中國規模最大的民營展覽公司,深耕行業20年,于北京、天津、廣州、西安、成都、新疆分別設有全資子公司。每年承接20多個大型政府展會,累積了豐富的政府資源和關係網絡。為打通新能源汽車產業各大環節的壁壘,振威展覽聯合中國土木工程學會城市公共交通學會、廣東省充電設施協會、充電設施線上網,共同打造中國新能源汽車產業第一展。

    主辦方積累了豐富的資源,本屆展會得到了上海市經信委、江蘇省經信委、浙江省經信委、武漢市經信委、廣州市經信委等政府部門的高度關注與大力支持。此外,展會還將重點邀請各地公交集團、旅遊公司、計程車運營公司、汽車租賃企業、大型物流公司、市政環衛公司等組團參觀交流,迅速實現供需對接。

    兩地展會同期均舉辦2017振威新能源汽車產業峰會,峰會圍繞當前最熱門話題展開討論。如何更好的實現市場驅動,如何提高整個產業的核心競爭力,都是需要我們共同思考的問題。為此,組委會將邀請來自新能源汽車產業各個領域的知名專家學者、領軍企業高層與政府代表、協會代表,共同探討新形勢下如何更好的提升市場化水準,如何提升企業核心競爭力、深化全產業鏈的交流與合作,實現共贏的局面。

    參展範圍

    新能源汽車

    純電動車:純電動客車、純電動城市物流車、純電動乘用車、純電動環衛車等;
    混合動力車:混合動力轎車、插電混合動力大巴等;
    其他:氫燃料電池汽車、增程式電動車等;

    新能源汽車核心零部件及配套

    動力集成:電動機、整車控制器、功率轉換器、傳動裝置、電池組、BMS、啟停電源、移動車載充電器、充電樁等;
    解決方案:整車設計、輕量化底盤、變速動力系統、直驅動力系統等;
    配套產品:磁性材料、連接器、飛輪、超級電容、相關新材料、相關檢測設備等。

    聯繫方式:
    廣州振威國際展覽有限公司
    電話:+86 20 8395 3286
    手機(微信):+86 135 3358 3989
    聯絡人:黃俊鵬
    E-mail:Johnny@zhenweiexpo.com

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

    【其他文章推薦】

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

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

    ※台北網頁設計公司全省服務真心推薦

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

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

  • 南京金龍加碼純電動物流車 四款新品將在振威新能源汽車展亮相

    南京金龍加碼純電動物流車 四款新品將在振威新能源汽車展亮相

    近年來,在電子商務快速發展的強勢需求拉動下,中國電商物流繼續保持快速增長。在環境壓力較大的當下,物流行業推行新能源汽車也成了改善環境,治理霧霾的一個重要手段。

    在新能源物流車形勢一片大好的情況下,新能源客車產品在細分市場銷量第二把交椅的南京金龍自然也不會錯過這一片藍海。據瞭解,南京金龍將於2017上海國際新能源汽車產業博覽會上推出四款新品純電動物流車。展會由振威展覽股份、中國土木工程學會城市公共交通學會、廣東省新能源汽車產業協會、廣東省充電設施協會及充電設施線上網聯合舉辦,將於2017年8月23-25日在上海新國際博覽中心舉行。

    據瞭解,本次南京金龍四款純電動物流車型分別為開沃D07、開沃D09、開沃D10和開沃D11。此四款物流車涵蓋3.9-5.9米的中小型物流車,且秉承其一貫的強勁續航能力,滿載續航均在220-260公里,是名副其實的續航之王。其中開沃D07為微型純電動物流車,主要用於城市內的快遞派送。作為“最後一公里”快遞配送專家,其載貨空間達3.4立方米,載貨量可達600KG,完美滿足市網點到客戶的快遞配送。開沃D09、D10為輕型純電動物流車,載貨空間分別在6立方米和8立方米,載重分別為750kg和1000kg,主要用作城市間的物流配送“貨的”。

    開沃D7純電動物流車

    去年,南京金龍就推出了素有“快遞王”之稱的開沃E7,“物流王”開沃D11,早已以其380公里左右的高續航、1.55噸的高載重、12.3個立方的高容量等特點,4小時繞北京五環三圈贏得了新能源物流車界的良好口碑。D11作為城市大空間長續航的物流王更是經受市場考驗超過3年、以好品質得到客戶認可和擁護的車型,輕鬆勝任城市間的物流運輸。

    3月1日,工信部官網正式公佈了《新能源汽車推廣應用推薦車型目錄(2017年第2批)》主要車型及參數。此次發佈的目錄涉及新能源乘用車、新能源客車及新能源專用車共有40家企業201款車型進入目錄。其中,南京金龍開沃牌NJL5040XXYBEV1純電動廂式運輸車入圍本次目錄。

    資料顯示,2016年純電動物流車產量達5.78萬輛,且2017年剛開始,工信部就給電動物流車行業一個驚喜。首批新能源汽車推薦目錄發佈,以電動物流車為代表的專用車型共有36款,占總比19%。“新能源物流車正成為新能源商用車發展的一大亮點。”全國乘聯會秘書長崔東樹也指出,新能源物流車使用費用低,維(護)修簡單,從國家政策的扶持以及城市空氣污染的角度來看,新能源物流車急劇增長是必然的,也是長期的發展趨勢。

    據不完全統計,北京、上海、廣東、天津等37省市出臺的新能源汽車政策裡都有提及純電動物流車的相關政策。隨著政策的明朗,行業逐漸趨於理性,純電動物流車市場迎來健康發展,其也將迎來真正的發展元年。業界普遍認為,2017年電動物流車行業預計將實現10萬輛左右的銷量,同比增速超過100%。

    南京金龍市場負責人表示,本次展會的召開是一個很好的契機,南京金龍開沃純電動物流車憑藉靈活多變的空間及穩定的滿負荷續航里程,將極大地改變我國新能源物流車產業發展格局。未來,南京金龍憑藉產品技術優勢,不斷開拓物流、快遞行業需求,為全面實現“零排放物流”的行業大計而持續努力。

    組委會聯繫方式:+86 20-83953286
    連絡人:黃俊鵬
    官方微信公眾號:nevechina

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

    【其他文章推薦】

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

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

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

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

    ※回頭車貨運收費標準

  • Gogoro擴點台中南投屏東,全台將有360個換電站

    Gogoro擴點台中南投屏東,全台將有360個換電站

    徹底改寫電動機車市場銷售紀錄的新創公司Gogoro,在短短兩年內已突破20,000 輛的銷售數字,並建置了300 多個電池交換站,充分展現了積極搶攻市場版圖的超高效率與決心。Gogoro 13 日宣布,將在4 月底開始投入在台中海線的3 個城鎮以及屏東地區首座換電站的設置;5 月底前則將進入南投。

    Gogoro 能源服務副總經理潘璟倫表示,Gogoro 在第一季的布站目標主要著力在高雄及台南地區,共於該區新增了19 個換電站。第二季,則會強化在六都以外的建置計畫,除預計在屏東市、東港、南投市、草屯、員林等地設置首座換電站外,也會在清水,沙鹿,大甲與鹿港4 個城鎮分別設置換電站以串連、打通台中彰化的海線。Gogoro 最南端的換電站,也預期在第二季末於東港設立。這些都是依據大數據分析的結果所進行的計畫,後續,大家也可以很快地可以看到在不同的區域,看到GoStation 電池交換站。

    在六都地區,Gogoro 仍以「一公里一座換電站」為能源網路目標,從北台灣一路往南延伸,透過與加油站、捷運站、學校、便利商店、賣場等單位異業結盟,合作布點的方式,積極擴大台灣綠色生活圈。

    依照Gogoro 第二季的計畫,6 月底前,全台將會有360 個換電站。這讓Gogoro 更貼近其將在2017 年底完成西岸走廊串連,讓基隆到屏東的西部都會區得以北南縱走,暢騎無阻的承諾。

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

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

    【其他文章推薦】

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

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

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

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

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

    ※超省錢租車方案

  • 鋰電池原料暴漲,電動車產業受影響

    鋰電池原料暴漲,電動車產業受影響

    鋰電池關鍵材料鈷、鋰價格暴漲,令電池乃至電動車製造商成本控制面臨極大壓力。

    鈷的國際報價四月中旬來到每磅27.5美元,寫下八年新高記錄。從2017年初以來,鈷價累計漲幅達90%,對照一年之前,更是跳增2.5倍。根據主要交易機構官員表示,鈷的身價節節升高,主因需求看漲,市場預先囤貨所致。(日經新聞)

    另外,鋰價近兩年翻升約三倍,電池製造商的成本上漲壓力可以想見,這將進一步轉嫁至電動車製造商身上。據估計,鈷約佔電池製造成本的兩成。

    特斯拉大眾化電動車Model 3預計在今年稍晚量產,目前特斯拉已收到40萬輛預購訂單。除了特斯拉之外,日產新一代Leaf電動車也即將上市,這些均為鈷與鋰等電池材料提供炒作題材。

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

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

    【其他文章推薦】

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

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

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

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

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

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