標籤: iphone維修

  • 上次被目擊是1913年!消失百年「沃茲考氏變色龍」現蹤

    摘錄自2020年11月1日自由時報報導

    這真的是百年一見!科學家在非洲島國馬達加斯加西北部,發現難為世人所見的變色龍「沃茲考氏變色龍」(Voeltzkow’s chameleon),上一次這種變色龍被目擊的紀錄,是在100多年前。

    馬達加斯加和德國的研究人員10月30日宣佈這項發現,他們2018年在馬達加斯加西北部探察時,發現了幾隻活「沃茲考氏變色龍」。巴伐利亞自然歷史陳列館(ZSM)的科學家,在期刊「蠑螈」(Salamandra)發表的報告說,基因分析確認,這些物種是拉波德氏變色龍(Labord’s chameleon)的近親。

    上一次發現沃茲考氏變色龍是在1913年,而且,之前也從未有關於雌性「沃茲考氏變色龍」的紀錄。研究人員說,雄性的沃茲考氏變色龍外觀為綠色,相比之下,母變色龍就繽紛得多。研究人員相信,這兩種變色龍都只在雨季生活:孵化、迅速成長、與競爭者較勁,然後交配、死亡,這些過程都在短短幾個月內完成。ZSM爬蟲和兩棲動物典藏研究員格勞(Frank Glaw)說,「這些動物基本上是脊椎動物中的浮游類」。現今大規模森林砍伐正威脅牠們的棲地。

    生物多樣性
    國際新聞
    變色龍
    瀕危物種

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

    【其他文章推薦】

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

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

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

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

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

  • 有德系有美系,這幾款大7座SUV比漢蘭達還牛得多

    有德系有美系,這幾款大7座SUV比漢蘭達還牛得多

    98-63。98萬細心的朋友可能會發現,探險者的外觀設計有幾分“路虎車”的影子,如果你真的有這樣的直覺,那就對了,探險者的確和“路虎”之間有點不為人知的故事,感興趣的話可以上網找找哦。超大的尺寸仍然是這個級別車型的亮點,外觀大氣是無可厚非的,探險者車身上的設計即帶有都市的時尚感,亦有硬派的越野風,這也是路虎車的風格。

    要說大七座SUV,我想不少人第一時間就想到漢蘭達,但是對於大眾粉來說,第一時間想到的或許是大眾的途昂。途昂作為一款比途觀L 定位更高的SUV,售價區間為30.89-51.89萬,比起漢蘭達23.98-42.28萬的售價,雖然重疊度很高,但也能明顯看出途昂的定位要高於漢蘭達。

    如果宏觀市面上的所有合資中大型SUV,途昂可是說是定價非常低的一款,以至於它沒有多少直接的競爭對手,這也是他能在最近一年時間里月銷量能到達1萬輛左右的原因之一,那實際上到底在這個價位還有誰能與之匹敵?我們把終端優惠的價格也考慮進去,發現豐田的普拉多和福特的探險者似乎也很吸引人,對比一波看看。

    上汽大眾-途昂

    指導價:30.89-51.89萬

    很多人第一眼看到途昂的時候可能都會以為是途觀L再加長后的SUV,因為他們套用的是同一套設計語言,呈現的效果很一致。途昂除了尺寸更大了,其實也有其他明顯的區別,就是途昂前後翼子板的腰線呈隆起的形狀,使其整體看起來更霸氣。當時話說回來,其實大眾車最終還是講究由簡潔的設計營造高級感,所以其實這款途昂的外觀也就一般般吧,不太高級,只是比較霸氣而已。

    一汽豐田-普拉多

    指導價:46.48-63.68萬

    普拉多的外觀造型可是說是整個SUV界最獨居一格的,在如今的SUV設計風格都以精緻化、年輕化的方向靠攏的環境下,普拉多依舊以“粗曠”的設計營造出硬派的風格,最獨特的當然是“兇悍”的前臉,還有就是滿身肌肉感的車身,雖然沒有什麼平直硬朗的線條,但整體車身外觀也彰顯出很強的力量感。

    福特(進口)-探險者

    指導價:44.98-63.98萬

    細心的朋友可能會發現,探險者的外觀設計有幾分“路虎車”的影子,如果你真的有這樣的直覺,那就對了,探險者的確和“路虎”之間有點不為人知的故事,感興趣的話可以上網找找哦。超大的尺寸仍然是這個級別車型的亮點,外觀大氣是無可厚非的,探險者車身上的設計即帶有都市的時尚感,亦有硬派的越野風,這也是路虎車的風格。

    尺寸對比

    尺寸方面,三車的長度很接近,探險者的車寬最寬;普拉多的車高最高;而途昂的軸距是最長的,而且比另外兩部車都要長不少,長軸距的車型更利於車內空間的布置,不過由於三輛車都已經達到了中大型SUV級別,而且都是7座車型,所以空間方面其實不必多慮。

    內飾對比

    雖然三輛車都不是豪華品牌,但是從售價來看,三輛車都超越了普通品牌的水平,所以內飾方面也絕對不能落伍。途昂的內飾還是很“大眾”,滿滿的家族氣息,只不過比起其他大眾車型,橫向面積更舒展,而且用料也更高級。普拉多的內飾一直都飽受好評,坐進車內后很容易就被其舒適性所征服,軟材質應用到位。但探險者的內飾設計就比較中庸,這也是福特車的特點,設計一向以來都比較平淡,不過用料方面還是很厚道。

    動力對比

    途昂的動力配備,由於選擇比較多,而且還應用了2.0T低功率發動機,以此將其門檻拉得很低,186匹馬力,這麼大的車,其實還是有點勉強吧。普拉多則全系搭載3.5L自然吸氣發動機,配備6AT的變速箱,這套動力總成無論是在鋪裝路面的日常駕駛,還是在一般的越野道路都可以說游刃有餘吧。而探險者的最低動力是2.3T的渦輪增壓發動機,276匹,是肯定夠用的,這個無需擔心。

    總結

    從以上對比就可以看出,其實途昂的起步價能這麼低,主要還是入門車型搭載了一款功率比較一般的發動機。但是我們綜合各方面表現,特別是配置方面(由於途昂配置領先很多,所以這次沒作對比),途昂還是很有優勢的,所以結論是,大七座SUV,途昂非常值得推薦。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

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

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

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

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

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

  • 【Flutter實戰】圖片組件及四大案例

    【Flutter實戰】圖片組件及四大案例

    老孟導讀:大家好,這是【Flutter實戰】系列文章的第三篇,這一篇講解圖片組件,Image有很多高級用法,希望對您有所幫助。

    圖片組件是Flutter基礎組件之一,和文本組件一樣必不可少。圖片組件包含Image和Icon兩個組件,本質上Icon不屬於圖片組件,但其外形效果上類似於圖片。

    在項目中建議優先使用Icon組件,Icon本質上是一種字體,只不過显示的不是文字,而是圖標,而Image組件先通過圖片解碼器將圖片解碼,所以Icon有如下優點:

    • 通常情況下,圖標比圖片體積更小,顯著的減少App包體積。
    • 圖標不會出現失真或者模糊的現象,例如將20×20的圖片,渲染在200×200的屏幕上,圖片會失真或模糊,而圖標是矢量圖,不會失真,就像字體一樣。
    • 多個圖標可以存放在一個文件中,方便管理。
    • 全平台通用。

    Image

    Image組件用於显示圖片,圖片的來源可以是網絡、項目中圖片或者設備上的圖片。

    加載網絡圖片:

    Image.network(
      'http://pic1.win4000.com/pic/c/cf/cdc983699c.jpg',
    )
    

    加載項目中圖片:

    首先將圖片拷貝到項目中,通常情況下,拷貝到assets/images/目錄下,assets/images/目錄為手動創建,新建的項目默認是沒有此目錄的。

    設置pubspec.yaml配置文件:

    assets:
      - assets/images/
    

    或者指定具體圖片的名稱:

    assets:
      - assets/images/aa.jpg
    

    通常情況下,使用第一種方式,因為圖片會有很多張,增加一張就這裏配置一個太麻煩。

    注意:assets前面的空格問題,極容易引發編譯異常,正確格式如下:

    加載圖片:

    Image.asset('assets/images/aa.jpg')
    

    加載設備上的圖片:

    要加載設備(手機)上的圖片首先需要獲取設備圖片的路徑,由於不同平台的路徑不同,因此路徑的獲取必須依靠原生支持,如果了解原生(Android和iOS)開發,可以直接使用MethodChannel獲取路徑,如果不懂原生(Android和iOS)開發,可以使用第三方插件獲取路徑,這裏推薦官方的path_provider

    加載設備上的圖片:

    Image.file(File('path'))
    

    設置圖片的大小:

    Image.asset('assets/images/aa.jpg',width: 100,height: 200,),
    

    當Image的大小和圖片大小不匹配時,需要設置填充模式fit,設置組件大小為150×150,

    Container(
      color: Colors.red.withOpacity(.3),
      child: Image.asset('assets/images/aa.jpg',width: 150,height: 150),
    )
    

    看到,圖片左右兩邊有空白區域(淺紅色填充的區域),如果想要圖片充滿整個區域,設置如下:

    Container(
      color: Colors.red.withOpacity(.3),
      child: Image.asset('assets/images/aa.jpg',width: 150,height: 150,fit: BoxFit.fill,),
    )
    

    雖然圖片充滿整個區域,但圖片變形了,使圖片等比拉伸,直到兩邊都充滿區域:

    Container(
      color: Colors.red.withOpacity(.3),
      child: Image.asset('assets/images/aa.jpg',width: 150,height: 150,fit: BoxFit.cover,),
    )
    

    此時,圖片未變形且兩邊都充滿區域,不過圖片被裁減了一部分。

    fit參數就是設置填充方式,其值介紹如下:

    • fill:完全填充,寬高比可能會變。
    • contain:等比拉伸,直到一邊填充滿。
    • cover:等比拉伸,直到2邊都填充滿,此時一邊可能超出範圍。
    • fitWidth:等比拉伸,寬填充滿。
    • fitHeight:等比拉伸,高填充滿。
    • none:當組件比圖片小時,不拉伸,超出範圍截取。
    • scaleDown:當組件比圖片小時,圖片等比縮小,效果和contain一樣。

    BoxFit.none的裁減和alignment相關,默認居中,

    Image.asset(
      'assets/images/aa.jpg',
      width: 150,
      height: 150,
      fit: BoxFit.none,
      alignment: Alignment.centerRight,
    ),
    

    左邊為原圖。

    設置對齊方式:

    Container(
      color: Colors.red.withOpacity(.3),
      child: Image.asset(
        'assets/images/aa.jpg',
        width: 150,
        height: 150,
        alignment: Alignment.centerLeft,
      ),
    ),
    

    colorcolorBlendMode用於將顏色和圖片進行顏色混合,colorBlendMode表示混合模式,下面介紹的混合模式比較多,瀏覽一遍即可,此屬性可以用於簡單的濾鏡效果。

    • clear:清楚源圖像和目標圖像。
    • color:獲取源圖像的色相和飽和度以及目標圖像的光度。
    • colorBurn:將目標的倒數除以源,然後將結果倒數。
    • colorDodge:將目標除以源的倒數。
    • darken:通過從每個顏色通道中選擇最小值來合成源圖像和目標圖像。
    • difference:從每個通道的較大值中減去較小的值。合成黑色沒有效果。合成白色會使另一張圖像的顏色反轉。
    • dst:僅繪製目標圖像。
    • dstATop:將目標圖像合成到源圖像上,但僅在與源圖像重疊的位置合成。
    • dstIn:显示目標圖像,但僅显示兩個圖像重疊的位置。不渲染源圖像,僅將其視為蒙版。源的顏色通道將被忽略,只有不透明度才起作用。
    • dstOut:显示目標圖像,但僅显示兩個圖像不重疊的位置。不渲染源圖像,僅將其視為蒙版。源的顏色通道將被忽略,只有不透明度才起作用。
    • dstOver:將源圖像合成到目標圖像下。
    • exclusion:從兩個圖像的總和中減去兩個圖像的乘積的兩倍。
    • hardLight:調整源圖像和目標圖像的成分以使其適合源圖像之後,將它們相乘。
    • hue:獲取源圖像的色相,以及目標圖像的飽和度和光度。
    • lighten:通過從每個顏色通道中選擇最大值來合成源圖像和目標圖像。
    • luminosity:獲取源圖像的亮度,以及目標圖像的色相和飽和度。
    • modulate:將源圖像和目標圖像的顏色分量相乘。
    • multiply:將源圖像和目標圖像的分量相乘,包括alpha通道。
    • overlay:調整源圖像和目標圖像的分量以使其適合目標后,將它們相乘。
    • plus:對源圖像和目標圖像的組成部分求和。
    • saturation:獲取源圖像的飽和度以及目標圖像的色相和亮度。
    • screen:將源圖像和目標圖像的分量的逆值相乘,然後對結果求逆。
    • softLight:對於低於0.5的源值使用colorDodge,對於高於0.5的源值使用colorBurn。
    • src:放置目標圖像,僅繪製源圖像。
    • srcATop:將源圖像合成到目標圖像上,但僅在與目標圖像重疊的位置合成。
    • srcIn:显示源圖像,但僅显示兩個圖像重疊的位置。目標圖像未渲染,僅被視為蒙版。目標的顏色通道將被忽略,只有不透明度才起作用。
    • srcOut:显示源圖像,但僅显示兩個圖像不重疊的位置。
    • srcOver:將源圖像合成到目標圖像上。
    • xor:將按位異或運算符應用於源圖像和目標圖像。

    是不是感覺看了和沒看差不多,看了也看不懂。正常,估計只有學過視覺算法的才能看懂吧,直接看下各個屬性的效果吧:

    repeat表示當組件有空餘位置時,將會重複显示圖片

    Image.asset(
      'assets/images/aa.jpg',
      width: double.infinity,
      height: 150,
      repeat: ImageRepeat.repeatX,
    )
    

    重複的模式有:

    • repeat:x,y方向都充滿。
    • repeatX:x方向充滿。
    • repeatY:y方向充滿。
    • noRepeat:不重複。

    matchTextDirection設置為true時,圖片的繪製方向為TextDirection設置的方向,其父組件必須為Directionality

    Directionality(
        textDirection: TextDirection.rtl,
        child: Image.asset(
          'assets/images/logo.png',
          height: 150,
          matchTextDirection: true,
        )),
    

    左邊為原圖,效果是左右鏡像。

    filterQuality表示繪製圖像的質量,從高到低為:high->medium->low->none。越高效果越好,越平滑,當然性能損耗越大,默認是low,如果發現圖片有鋸齒,可以設置此參數。

    當加載圖片的時候回調frameBuilder,當此參數為null時,此控件將會在圖片加載完成后显示,未加載完成時显示空白,尤其在加載網絡圖片時會更明顯。因此此參數可以用於處理圖片加載時显示佔位圖片和加載圖片的過渡效果,比如淡入淡出效果。

    下面的案例是淡入淡出效果:

    Image.network(
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
      frameBuilder: (BuildContext context, Widget child, int frame,
          bool wasSynchronouslyLoaded) {
        if (wasSynchronouslyLoaded) {
          return child;
        }
        return AnimatedOpacity(
          child: child,
          opacity: frame == null ? 0 : 1,
          duration: const Duration(seconds: 2),
          curve: Curves.easeOut,
        );
      },
    )
    

    loadingBuilder參數比frameBuilder控制的力度更細,可以獲取圖片加載的進度,下面的案例显示了加載進度條:

    Image.network(
        'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
        loadingBuilder: (BuildContext context, Widget child,
            ImageChunkEvent loadingProgress) {
      if (loadingProgress == null) {
        return child;
      }
      return Center(
        child: CircularProgressIndicator(
          value: loadingProgress.expectedTotalBytes != null
              ? loadingProgress.cumulativeBytesLoaded /
                  loadingProgress.expectedTotalBytes
              : null,
        ),
      );
    })
    

    centerSlice用於.9圖,.9圖用於拉伸圖片的特定區域,centerSlice設置的區域(Rect)就是拉伸的區域。.9圖通常用於控件大小、寬高比不固定的場景,比如聊天背景圖片等。

    Container(
        width: 250,
        height: 300,
        decoration: BoxDecoration(
            image: DecorationImage(
                centerSlice: Rect.fromLTWH(20, 20, 10, 10),
                image: AssetImage(
                  'assets/images/abc.jpg',
                ),
                fit: BoxFit.fill))),
    

    上面為原圖,下面為拉伸的圖片。

    在使用時大概率會出現如下異常:

    這是由於圖片比組件的尺寸大,如果使用centerSlice屬性,圖片必須比組件的尺寸小,一般情況下,.9圖的尺寸都非常小。

    Icon

    Icon是圖標組件,Icon不具有交互屬性,如果想要交互,可以使用IconButton。

    Icon(Icons.add),
    

    設置圖標的大小和顏色:

    Icon(
      Icons.add,
      size: 40,
      color: Colors.red,
    )
    

    上面的黑色為默認大小和顏色。

    Icons.add是系統提供的圖標,創建Flutter項目的時候,pubspec.yaml中默認有如下配置:

    所有的圖標在Icons中已經定義,可以直接在源代碼中查看,也可以到官網查看所有圖標。

    所有圖標效果如下:

    案例

    聊天背景(.9圖實現)

    Container(
      width: 200,
      padding: EdgeInsets.only(left: 8,top: 8,right: 20,bottom: 8),
      decoration: BoxDecoration(
          image: DecorationImage(
              centerSlice: Rect.fromLTWH(20, 20, 1, 1),
              image: AssetImage(
                'assets/images/chat.png',
              ),
              fit: BoxFit.fill)),
      child: Text('老孟,專註分享Flutter技術和應用實戰。'
          '老孟,專註分享Flutter技術和應用實戰。'
          '老孟,專註分享Flutter技術和應用實戰。',),
    )
    

    背景圖片大小是57×80:

    右側三角已經不在中間了,如果想讓其一直保持居中,修改拉伸區域:

    centerSlice: Rect.fromLTWH(20, 10, 1, 60),
    

    圓形帶邊框的頭像

    Container(
      width: 100,
      height: 100,
      padding: EdgeInsets.all(3),
      decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.blue),
      child: Container(
        decoration: BoxDecoration(
            shape: BoxShape.circle,
            image: DecorationImage(
                image: AssetImage('assets/images/aa.jpg'), fit: BoxFit.cover)),
      ),
    )
    

    圖片佔位符:

    Image.network(
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
      height: 150,
      width: 150,
      fit: BoxFit.cover,
      frameBuilder: (
        BuildContext context,
        Widget child,
        int frame,
        bool wasSynchronouslyLoaded,
      ) {
        if (frame == null) {
          return Image.asset(
            'assets/images/place.png',
            height: 150,
            width: 150,
            fit: BoxFit.cover,
          );
        }
        return child;
      },
    )
    

    添加自己的圖標庫

    如果系統提供的圖標沒有我們想要的圖標,這時需要引入第三方庫的圖標,下面以阿里巴巴的圖標庫為例。

    打開阿里巴巴的圖標官網,找到自己想要的圖標后,將鼠標放置到圖標上,加入購物車:

    點擊右上角的購物車,然後點擊添加至項目:

    如果沒有添加過項目,需要創建一個新項目:

    創建好后加入此項目,跳轉到我的項目頁面,點擊下載:

    解壓下載的文件,解壓出來的文件有好幾個,如下圖:

    選擇iconfont.ttf文件拷貝到 Flutter 項目的assets/fonts目錄下,assets/fonts目錄默認是沒有的,需要手動創建,在pubspec.yaml設置如下:

    千萬注意紅框內開頭的空格問題,否則編譯不通過,family後面跟的字符串最好有意義,後面用圖標的時候需要用到。

    用法如下:

    Icon(IconData(0xe613,fontFamily: 'appIconFonts')
    

    0xe613在下載圖標時已經標註,將&#替換為0,如下圖:

    fontFamily是在pubspec.yaml中設置的family屬性,第三方的圖標和系統圖標一樣,可以設置其顏色和大小。

    交流

    老孟Flutter博客地址(330個控件用法):http://laomengit.com

    歡迎加入Flutter交流群(微信:laomengit)、關注公眾號【老孟Flutter】:

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

    【其他文章推薦】

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

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

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

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

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

  • EnergyTrend微信新服務“太陽能價格評析” 立即關注!

    EnergyTrend微信新服務“太陽能價格評析” 立即關注!

    EnergyTrend微信(簡中版)
    只要在微信關注我們

    EnergyTrend專業的分析師將直接告訴您
    最即時的太陽能市場價格微評論

    讓您一機在手隨時隨地輕鬆掌握太陽能市場最新動態

    [加入關注]
    1.微信→朋友→新增朋友→掃描QR Code→將右側QR Code置於方框內→關注
    2.微信→朋友→新增朋友→查找官方帳戶→輸入”集邦新能源網”→關注

     

     

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

    【其他文章推薦】

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

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

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

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

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

  • 空拍機驚嚇小熊可避免 論文提出技術與倫理建議:預警為要

    環境資訊中心記者 鄭雅云報導

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

    【其他文章推薦】

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

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

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

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

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

  • Gogoro 宣布與新北市政府合作擴充電池交換站,擴充大台北充電網路

    Gogoro 宣布與新北市政府合作擴充電池交換站,擴充大台北充電網路

    Gogoro 致力於電池交換型式的供電系統,提供比傳統機車更為綠能的選擇。13 日 Gogoro 宣布與新北市政府合作建置電池交換站,加上上個月台北市年底前建置的千座電池交換站,大台北地區將逐漸追上加油站數量。

    Gogoro 在新北市於明年第一季前預計完成建置 20 座電池交換站、兩座太陽能電池交換站,建置範圍涵蓋三重區、三峽區、中和區、汐止區、板橋區、林口區、新店區、新莊區、樹林區、蘆洲區等新北都會區域。

    Gogoro 營運副總潘璟倫表示:「目前雙北市平均每月電池交換次數高達近 28 萬次,為全台灣使用率最高的地區。為了加速提供車主的能源需求,Gogoro 不斷積極的佈建電池交換站以及尋找適合的地點,這次非常感謝新北市政府給予機會讓我們建置足夠的電池換電站提供消費者使用,希望透過這樣的合作持續帶動電動機車的發展。」

    Gogoro 在台北市電池交換站已經超越傳統加油站的數量,而與台北市政府合作的 1,000 座電池交換站將拉大差距。本月在大台北地區新開台北天母忠誠、新北新店民權兩家門市。大台北地區將共有 35 家銷售服務據點同時提供完整的服務,完善台北地區服務網路。

    配合開學季,Gogoro 也於 9/15 – 10/14 推試騎送限量「All Pass 文具組」,只要消費者到門市體驗試乘,即可獲得此試騎好禮。

    (合作媒體:。首圖來源:)

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

    【其他文章推薦】

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

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

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

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

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

  • 一時技癢,擼了個動態線程池,源碼放Github了

    一時技癢,擼了個動態線程池,源碼放Github了

    闡述背景

    線程池在日常工作中用的還挺多,當需要異步,批量處理一些任務的時候我們會定義一個線程池來處理。

    在使用線程池的過程中有一些問題,下面簡單介紹下之前遇到的一些問題。

    場景一:實現一些批量處理數據的功能,剛開始線程池的核心線程數設的比較小,然後想調整下,只能改完后重啟應用。

    場景二:有一個任務處理的應用,會接收 MQ 的消息進行任務的處理,線程池的隊列也允許緩存一定數量的任務。當任務處理的很慢的時候,想看看到底有多少沒有處理完不是很方便。當時為了快速方便,就直接啟動了一個線程去循環打印線程池隊列的大小。

    正好之前在我公眾號有轉發過美團的一篇線程池應用的文章(https://mp.weixin.qq.com/s/tIWAocevZThfbrfWoJGa9w),覺得他們的思路非常好,就是沒有開放源碼,所以自己就抽時間在我的開源項目 Kitty 中增加了一個動態線程池的組件,支持了 Cat 監控,動態變更核心參數,任務堆積告警等。今天就給大家分享一下實現的方式。

    項目源代碼地址:https://github.com/yinjihuan/kitty

    使用方式

    添加依賴

    依賴線程池的組件,目前 Kitty 未發布,需要自己下載源碼 install 本地或者私有倉庫。

    <dependency>
        <groupId>com.cxytiandi</groupId>
        <artifactId>kitty-spring-cloud-starter-dynamic-thread-pool</artifactId>
    </dependency>
    

    添加配置

    然後在 Nacos 配置線程池的信息,我的這個整合了 Nacos。推薦一個應用創建一個單獨的線程池配置文件,比如我們這個叫 dataId 為 kitty-cloud-thread-pool.properties,group 為 BIZ_GROUP。

    內容如下:

    kitty.threadpools.nacosDataId=kitty-cloud-thread-pool.properties
    kitty.threadpools.nacosGroup=BIZ_GROUP
    kitty.threadpools.accessToken=ae6eb1e9e6964d686d2f2e8127d0ce5b31097ba23deee6e4f833bc0a77d5b71d
    kitty.threadpools.secret=SEC6ec6e31d1aa1bdb2f7fd5eb5934504ce09b65f6bdc398d00ba73a9857372de00
    kitty.threadpools.owner=尹吉歡
    kitty.threadpools.executors[0].threadPoolName=TestThreadPoolExecutor
    kitty.threadpools.executors[0].corePoolSize=4
    kitty.threadpools.executors[0].maximumPoolSize=4
    kitty.threadpools.executors[0].queueCapacity=5
    kitty.threadpools.executors[0].queueCapacityThreshold=5
    kitty.threadpools.executors[1].threadPoolName=TestThreadPoolExecutor2
    kitty.threadpools.executors[1].corePoolSize=2
    kitty.threadpools.executors[1].maximumPoolSize=4
    

    nacosDataId,nacosGroup

    監聽配置修改的時候需要知道監聽哪個 DataId,值就是當前配置的 DataId。

    accessToken,secret

    釘釘機器人的驗證信息,用於告警。

    owner

    這個應用的負責人,告警的消息中會显示。

    threadPoolName

    線程池的名稱,使用的時候需要關注。

    剩下的配置就不一一介紹了,跟線程池內部的參數一致,還有一些可以查看源碼得知。

    注入使用

    @Autowired
    private DynamicThreadPoolManager dynamicThreadPoolManager;
    dynamicThreadPoolManager.getThreadPoolExecutor("TestThreadPoolExecutor").execute(() -> {
        log.info("線程池的使用");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, "getArticle");
    

    通過 DynamicThreadPoolManager 的 getThreadPoolExecutor 方法獲取線程池對象,然後傳入 Runnable,Callable 等。第二個參數是這個任務的名稱,之所以要擴展一個參數是因為如果任務沒有標識,那麼無法區分任務。

    這個線程池組件默認集成了 Cat 打點,設置了名稱可以在 Cat 上查看這個任務相關的監控數據。

    擴展功能

    任務執行情況監控

    在 Cat 的 Transaction 報表中會以線程池的名稱為類型显示。

    詳情中會以任務的名稱显示。

    核心參數動態修改

    核心參數目前只支持 corePoolSize,maximumPoolSize,queueCapacity(隊列類型為 LinkedBlockingDeque 才可以修改),rejectedExecutionType,keepAliveTime,unit 這些參數的修改。

    一般 corePoolSize,maximumPoolSize,queueCapacity 是最常要動態改變的。

    需要改動的話直接在 Nacos 中將對應的配置值修改即可,客戶端會監聽配置的修改,然後同步修改先線程池的參數。

    隊列容量告警

    queueCapacityThreshold 是隊列容量告警的閥值,如果隊列中的任務數量超過了 queueCapacityThreshold 就會告警。

    拒絕次數告警

    當隊列容量滿了后,新進來的任務會根據用戶設置的拒絕策略去選擇對應的處理方式。如果是採用 AbortPolicy 策略,也會進行告警。相當於消費者已經超負荷了。

    線程池運行情況

    底層對接了 Cat,所以將線程的運行數據上報給了 Cat。我們可以在 Cat 中查看這些信息。

    如果你想在自己的平台去展示,我這邊暴露了/actuator/thread-pool 端點,你可以自行拉取數據。

    {
    	threadPools: [{
    		threadPoolName: "TestThreadPoolExecutor",
    		activeCount: 0,
    		keepAliveTime: 0,
    		largestPoolSize: 4,
    		fair: false,
    		queueCapacity: 5,
    		queueCapacityThreshold: 2,
    		rejectCount: 0,
    		waitTaskCount: 0,
    		taskCount: 5,
    		unit: "MILLISECONDS",
    		rejectedExecutionType: "AbortPolicy",
    		corePoolSize: 4,
    		queueType: "LinkedBlockingQueue",
    		completedTaskCount: 5,
    		maximumPoolSize: 4
    	}, {
    		threadPoolName: "TestThreadPoolExecutor2",
    		activeCount: 0,
    		keepAliveTime: 0,
    		largestPoolSize: 0,
    		fair: false,
    		queueCapacity: 2147483647,
    		queueCapacityThreshold: 2147483647,
    		rejectCount: 0,
    		waitTaskCount: 0,
    		taskCount: 0,
    		unit: "MILLISECONDS",
    		rejectedExecutionType: "AbortPolicy",
    		corePoolSize: 2,
    		queueType: "LinkedBlockingQueue",
    		completedTaskCount: 0,
    		maximumPoolSize: 4
    	}]
    }
    

    自定義拒絕策略

    平時我們使用代碼創建線程池可以自定義拒絕策略,在構造線程池對象的時候傳入即可。這裏由於創建線程池都被封裝好了,我們只能在 Nacos 配置拒絕策略的名稱來使用對應的策略。默認是可以配置 JDK 自帶的 CallerRunsPolicy,AbortPolicy,DiscardPolicy,DiscardOldestPolicy 這四種。

    如果你想自定義的話也是支持的,定義方式跟以前一樣,如下:

    @Slf4j
    public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            log.info("進來了。。。。。。。。。");
        }
    }
    

    要讓這個策略生效的話使用的是 SPI 的方式,需要在 resources 下面創建一個 META-INF 的文件夾,然後創建一個 services 的文件夾,再創建一個 java.util.concurrent.RejectedExecutionHandler 的文件,內容為你定義的類全路徑。

    自定義告警方式

    默認是內部集成了釘釘機器人的告警方式,如果你不想用也可以將其關閉。或者將告警信息對接到你的監控平台去。

    如果沒有告警平台也可以在項目中實現新的告警方式,比如短信等。

    只需要實現 ThreadPoolAlarmNotify 這個類即可。

    /**
     * 自定義短信告警通知
     *
     * @作者 尹吉歡
     * @個人微信 jihuan900
     * @微信公眾號 猿天地
     * @GitHub https://github.com/yinjihuan
     * @作者介紹 http://cxytiandi.com/about
     * @時間 2020-05-27 22:26
     */
    @Slf4j
    @Component
    public class ThreadPoolSmsAlarmNotify implements ThreadPoolAlarmNotify {
        @Override
        public void alarmNotify(AlarmMessage alarmMessage) {
            log.info(alarmMessage.toString());
        }
    }
    

    代碼實現

    具體的就不講的很細了,源碼在https://github.com/yinjihuan/kitty/tree/master/kitty-dynamic-thread-pool,大家自己去看,並不複雜。

    創建線程池

    根據配置創建線程池,ThreadPoolExecutor 是自定義的,因為需要做 Cat 埋點。

    /**
     * 創建線程池
     * @param threadPoolProperties
     */
    private void createThreadPoolExecutor(DynamicThreadPoolProperties threadPoolProperties) {
        threadPoolProperties.getExecutors().forEach(executor -> {
            KittyThreadPoolExecutor threadPoolExecutor = new KittyThreadPoolExecutor(
                    executor.getCorePoolSize(),
                    executor.getMaximumPoolSize(),
                    executor.getKeepAliveTime(),
                    executor.getUnit(),
                    getBlockingQueue(executor.getQueueType(), executor.getQueueCapacity(), executor.isFair()),
                    new KittyThreadFactory(executor.getThreadPoolName()),
                    getRejectedExecutionHandler(executor.getRejectedExecutionType(), executor.getThreadPoolName()), executor.getThreadPoolName());
            threadPoolExecutorMap.put(executor.getThreadPoolName(), threadPoolExecutor);
        });
    }
    

    刷新線程池

    首先需要監聽 Nacos 的修改。

    /**
     * 監聽配置修改,spring-cloud-alibaba 2.1.0版本不支持@NacosConfigListener的監聽
     */
    public void initConfigUpdateListener(DynamicThreadPoolProperties dynamicThreadPoolProperties) {
        ConfigService configService = nacosConfigProperties.configServiceInstance();
        try {
            configService.addListener(dynamicThreadPoolProperties.getNacosDataId(), dynamicThreadPoolProperties.getNacosGroup(), new AbstractListener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    new Thread(() -> refreshThreadPoolExecutor()).start();
                    log.info("線程池配置有變化,刷新完成");
                }
            });
        } catch (NacosException e) {
            log.error("Nacos配置監聽異常", e);
        }
    }
    

    然後再刷新線程池的參數信息,由於監聽事件觸發的時候,這個時候配置其實還沒刷新,所以我就等待了 1 秒鐘,讓配置完成刷新然後直接從配置類取值。

    雖然有點挫還是可以用,其實更好的方式是解析 receiveConfigInfo 那個 configInfo,configInfo 就是改變之後的整個配置內容。因為不太好解析成屬性文件,就沒做,後面再改吧。

    /**
     * 刷新線程池
     */
    private void refreshThreadPoolExecutor() {
        try {
            // 等待配置刷新完成
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        dynamicThreadPoolProperties.getExecutors().forEach(executor -> {
            ThreadPoolExecutor threadPoolExecutor = threadPoolExecutorMap.get(executor.getThreadPoolName());
            threadPoolExecutor.setCorePoolSize(executor.getCorePoolSize());
            threadPoolExecutor.setMaximumPoolSize(executor.getMaximumPoolSize());
            threadPoolExecutor.setKeepAliveTime(executor.getKeepAliveTime(), executor.getUnit());
            threadPoolExecutor.setRejectedExecutionHandler(getRejectedExecutionHandler(executor.getRejectedExecutionType(), executor.getThreadPoolName()));
            BlockingQueue<Runnable> queue = threadPoolExecutor.getQueue();
            if (queue instanceof ResizableCapacityLinkedBlockIngQueue) {
                ((ResizableCapacityLinkedBlockIngQueue<Runnable>) queue).setCapacity(executor.getQueueCapacity());
            }
        });
    }
    

    其他的刷新都是線程池自帶的,需要注意的是線程池隊列大小的刷新,目前只支持 LinkedBlockingQueue 隊列,由於 LinkedBlockingQueue 的大小是不允許修改的,所以按照美團那篇文章提供的思路,自定義了一個可以修改的隊列,其實就是把 LinkedBlockingQueue 的代碼複製了一份,改一下就可以。

    往 Cat 上報運行信息

    往 Cat 的 Heartbeat 報表上傳數據的代碼如下,主要還是 Cat 本身提供了擴展的能力。只需要定時去調用下面的方式上報數據即可。

    public void registerStatusExtension(ThreadPoolProperties prop, KittyThreadPoolExecutor executor) {
        StatusExtensionRegister.getInstance().register(new StatusExtension() {
            @Override
            public String getId() {
                return "thread.pool.info." + prop.getThreadPoolName();
            }
            @Override
            public String getDescription() {
                return "線程池監控";
            }
            @Override
            public Map<String, String> getProperties() {
                AtomicLong rejectCount = getRejectCount(prop.getThreadPoolName());
                Map<String, String> pool = new HashMap<>();
                pool.put("activeCount", String.valueOf(executor.getActiveCount()));
                pool.put("completedTaskCount", String.valueOf(executor.getCompletedTaskCount()));
                pool.put("largestPoolSize", String.valueOf(executor.getLargestPoolSize()));
                pool.put("taskCount", String.valueOf(executor.getTaskCount()));
                pool.put("rejectCount", String.valueOf(rejectCount == null ? 0 : rejectCount.get()));
                pool.put("waitTaskCount", String.valueOf(executor.getQueue().size()));
                return pool;
            }
        });
    }
    

    定義線程池端點

    通過自定義端點來暴露線程池的配置和運行的情況,可以讓外部的監控系統拉取數據做對應的處理。

    @Endpoint(id = "thread-pool")
    public class ThreadPoolEndpoint {
        @Autowired
        private DynamicThreadPoolManager dynamicThreadPoolManager;
        @Autowired
        private DynamicThreadPoolProperties dynamicThreadPoolProperties;
        @ReadOperation
        public Map<String, Object> threadPools() {
            Map<String, Object> data = new HashMap<>();
            List<Map> threadPools = new ArrayList<>();
            dynamicThreadPoolProperties.getExecutors().forEach(prop -> {
                KittyThreadPoolExecutor executor = dynamicThreadPoolManager.getThreadPoolExecutor(prop.getThreadPoolName());
                AtomicLong rejectCount = dynamicThreadPoolManager.getRejectCount(prop.getThreadPoolName());
                Map<String, Object> pool = new HashMap<>();
                Map config = JSONObject.parseObject(JSONObject.toJSONString(prop), Map.class);
                pool.putAll(config);
                pool.put("activeCount", executor.getActiveCount());
                pool.put("completedTaskCount", executor.getCompletedTaskCount());
                pool.put("largestPoolSize", executor.getLargestPoolSize());
                pool.put("taskCount", executor.getTaskCount());
                pool.put("rejectCount", rejectCount == null ? 0 : rejectCount.get());
                pool.put("waitTaskCount", executor.getQueue().size());
                threadPools.add(pool);
            });
            data.put("threadPools", threadPools);
            return data;
        }
    }
    

    Cat 監控線程池中線程的執行時間

    本來是將監控放在 KittyThreadPoolExecutor 的 execute,submit 方法里的。後面測試下來發現有問題,數據在 Cat 上確實有了,但是執行時間都是 1 毫秒,也就是沒生效。

    不說想必大家也知道,因為線程是後面單獨去執行的,所以再添加任務的地方埋點沒任務意義。

    後面還是想到了一個辦法來實現埋點的功能,就是利用線程池提供的 beforeExecute 和 afterExecute 兩個方法,在線程執行之前和執行之後都會觸發這兩個方法。

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        String threadName = Thread.currentThread().getName();
        Transaction transaction = Cat.newTransaction(threadPoolName, runnableNameMap.get(r.getClass().getSimpleName()));
        transactionMap.put(threadName, transaction);
        super.beforeExecute(t, r);
    }
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        String threadName = Thread.currentThread().getName();
        Transaction transaction = transactionMap.get(threadName);
        transaction.setStatus(Message.SUCCESS);
        if (t != null) {
            Cat.logError(t);
            transaction.setStatus(t);
        }
        transaction.complete();
        transactionMap.remove(threadName);
    }
    

    後面的代碼大家自己去看就行了,本文到這裏就結束了。如果感覺本文還不錯的記得轉發下哦!

    多謝多謝。

    最後感謝美團技術團隊的那篇文章,雖然沒有分享源碼,但是思路什麼的和應用場景都講的很明白。

    感興趣的 Star 下唄:https://github.com/yinjihuan/kitty

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

    【其他文章推薦】

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

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

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

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

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

  • 載不動聖誕老人 瑞典夏季乾旱 部分馴鹿餓死

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

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

    【其他文章推薦】

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

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

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

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

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

  • Python 為什麼推薦蛇形命名法?

    Python 為什麼推薦蛇形命名法?

    關於變量的命名,這又是一個容易引發程序員論戰的話題。如何命名才能更具有可讀性、易寫性與明義性呢?眾說紛紜。

    本期“Python為什麼”欄目,我們將聚焦於變量命名中的連接方式,來切入這塊是非之地,想要回答的問題是——Python 為什麼要推薦蛇形命名法?

    首先一點,對於單個字符或者單詞 (例如:a、A、PYTHON、Cat),當它們被用作變量名時,大致有全小寫、全大寫和首字母大寫這幾種情況。編程語言中出現這些情況時,它們基本上跟英語的表達習慣是相同的。

    但是,編程語言為了令變量名表達出更豐富的含義,通常需要使用多個單詞或符號。 英語習慣使用空格來間隔開單詞,然而這種用法在編程語言中會帶來一些麻煩,所以程序員們就創造出了另外的方法:

    • 蛇形命名法(snake case)
    • 駝峰命名法(camel case)
    • 匈牙利命名法(HN case)
    • 帕斯卡命名法(Pascal case)
    • 脊柱命名法(spinal case)
    • 自由命名法(studly caps)
    • 駝峰蛇形命名法

    總體而言,這些命名法都是要克服單詞間的空格,從而把不同單詞串連起來, 最終達到創造出一種新的“單詞”的效果。

    我畫了一張思維導圖,大略區分了這幾種命名法:

    如果按照受眾量與知名程度排名,毫無疑問排前兩位的是駝峰命名法和蛇形命名法。

    我們可以簡單比較一下它們的優缺點:

    • 可讀性:蛇形命名法用下劃線拉大詞距,更清楚易讀;駝峰命名法的變量名緊湊,節省行寬
    • 易寫性:駝峰命名法以大小寫為區分,不引入額外的標識符;蛇形命名法統一小寫,輸入相對方便
    • 明義性:對於某些縮寫成的專有名詞,例如 HTTP、RGB、DNS等等,一般習慣全用大寫表示,但是如果嚴格遵循這兩種命名法的話,須得只留首字母大寫或者全小寫,這樣對原意都會造成一些“破壞”,有時候甚至讓人感覺到彆扭。如果保留全大寫,IDE 可能識別不準,反而會出現波浪提示

    由此可見,它們各有優缺點,但哪一方都不具有壓倒性。我個人稍微偏好於蛇形命名法,但是在需要用駝峰命名的時候(比如寫 Java 時),也能無障礙切換。

    需要指出的是,Python 也推薦使用駝峰式命名,那是在類名、Type 變量、異常 exception 名這些情況。而在包名、模塊名、方法名和普通變量名 等情況,則是推薦用蛇形命名(lower_case_with_underscores)。

    那麼,為什麼 Python 會推薦用蛇形命名法呢?

    最大的原因是歷史原因。 蛇形命名方式起源於 1960 年代,那時它甚至還沒有特定的名稱。Python 從 C 語言中借鑒過來后,給它起名為“lower_case_with_underscores”,即帶下劃線的小寫命名。

    直到 21 世紀初的幾年,在 Intel 和 Ruby 社區中,才有人開始以“snake_case”即蛇形命名來稱呼它。

    現今有不少編程語言在某些場景下會推薦使用蛇形命名法,而 Python 則是其中最早這麼做的之一,並且是使用場景最多的語言之一。

    維基百科上統計了一份清單,可以看出 Python 對它的偏好:

    其次,還有一個比較重要的原因,那就是 Python 對下劃線“_”的獨特偏愛。

    比如類似於 _xx、__xx、xx_、__xx__ 等等的寫法就隨處可見,甚至還有孤零零一個下劃線 _ 作為變量的特殊情況。這樣看來,下劃線作為單詞間的連接,恰恰是這種傳統習慣的一部分。

    最後,我還看到過一種解釋:因為 Python 是蟒蛇啊,理所當然是用蛇形命名……

    對於這三個解釋,你們是如何感想的呢?對於蛇形命名法,大家是喜歡還是不喜歡呢?歡迎留言交流。

    寫在最後:本文屬於“Python為什麼”系列(Python貓出品),該系列主要關注 Python 的語法、設計和發展等話題,以一個個“為什麼”式的問題為切入點,試着展現 Python 的迷人魅力。部分話題會推出視頻版,請在 B 站收看,觀看地址:視頻地址

    公眾號【Python貓】, 本號連載優質的系列文章,有Python為什麼系列、喵星哲學貓系列、Python進階系列、好書推薦系列、技術寫作、優質英文推薦與翻譯等等,歡迎關注哦。

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

    【其他文章推薦】

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

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

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

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

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

    聚甘新

  • 福斯拼2025年躍居電動車龍頭、砸500億歐元採購電池

    福斯拼2025年躍居電動車龍頭、砸500億歐元採購電池

      福斯集團(Volkswagen Group)11月18日宣布,2018~2022年期間旗下核心品牌將在全球投資228億歐元、當中有140億歐元將會投入德國地區工廠。位於德國茲威考(Zwickau)的工廠將獲得10億歐元的挹注、藉此轉型為純電動車生產線。   福斯預估2025年旗下電動車產量至少可達100萬輛。採用MEB(Modular Electric Drive Kit)模組化電動車平台技術的電動車續航力將介於400~600公里之間。首款搭載MEB的Volkswagen I.D.預計在2020年發表、當年產量預估將達10萬輛。   福斯集團11月17日宣布,2018~2022年期間集團將投入340億歐元在電動移動、自主駕駛、新型移動服務以及數位化等領域。福斯9月宣布,2030年底以前旗下所有車款都將具備電動驅動選項。   福斯執行長Matthias Muller表示,上述投資將為集團在2025年躍居全球最大電動車廠商奠定基礎。Muller提到,未來數年整個汽車業將面臨根本性的變化。 為了滿足對電池產能的巨大需求,福斯集團已啟動了旨在建立長期戰略合作夥伴關係的全球(包括中國在內)招標程序、金額預估將超過500億歐元。   福斯集團預期巴西、中國、俄羅斯以及北美將會是未來數年的主要成長來源。   福斯汽車公司(中國)11月16日宣布,從現在到2025年這段期間公司與合資企業夥伴將投資逾100億歐元在電動移動工業化領域。   Thomson Reuters報導,英國財政部19日表示,財長Philip Hammond將在11月22日公布的政府預算書當中宣布提供總額達1.0億英鎊的電動車購買補助金。   (本文內容由授權使用。首圖來源:pixabay)  

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

    【其他文章推薦】

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

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

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

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

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

    聚甘新