中國喊2060碳排歸零 歐盟外長:應說明如何實現

摘錄自2020年10月24日中央通訊社報導

中國國家主席習近平9月22日在聯合國大會承諾,中國二氧化碳排放將在2030年前達到峰值,2060年前實現碳中和。

歐洲聯盟外長波瑞爾(Josep Borrell)10月22日在個人部落格發表文章,習近平已提出中國2060年前實現碳中和的承諾,加上歐洲正致力氣候外交,這可能是全球應對氣候變遷的重要轉折。他強調,雖然設定一個雄心勃勃的目標很重要,但更重要的是取得成果,而中國迄今尚未詳細說明要如何實現2060年的目標。中國在一帶一路倡議下,其中逾4成投資與能源建設相關,這導致化石燃料發電廠建設增加,這個議題應納入未來歐中對話的議程。

歐盟近年將應對氣候變遷推動為氣候多邊外交行動,歐中領導人今年9月視訊會議時,即強調中國是重要的全球合作夥伴,鼓勵中國加強氣候承諾、盡快啟動國家排放交易體系、設定氣候中和的目標,當時歐盟也強調,中國必須暫停在國外建設燃煤電廠和資助相關建設。

氣候變遷
循環經濟
國際新聞
中國
碳排放
碳中和
氣候外交
一帶一路

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

【其他文章推薦】

※回頭車貨運收費標準

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

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

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

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

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

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

如何拿到阿里P8 Offer-候選人視角談面試

阿里CBU前端團隊招人,不管是serverless、跨端、WEB IDE、工程化、智能化、搭建 還是 直播,在CBU 前端團隊 都能夠找到適合你的技術方向。 感興趣的小夥伴可私信留言,或者加群交流,QQ群(1126560208)

自我介紹

首先簡單自我介紹一下,我叫陳映平,花名叫做小卡,2011年校招進入騰訊,是騰訊課堂B側的前端技術負責人。2015年響應總理的號召,跟朋友一起出來創業,跟前面一位講師的經歷有點像,然後2018年回到騰訊,主要負責NOW直播相關的業務,包括NOW商業化、NOW獨立版等。

今年的三月底,因為家庭的原因來到了杭州,加入了阿里巴巴CBU技術部-前端體驗技術團隊,職級是P8,目前負責的主要是內容跟營銷方向,包括采源寶、淘賣,以及現在風口上的業務,1688電商直播。

接下來分享一下我是如何拿到阿里P8的offer,以及面試過程中的一些思考。分享主要會分為幾個部分。

  • 第一個是整體的面試流程,以及面試過程中的一些內容。
  • 第二個是面試過程中所做的一些準備。
  • 第三個是針對面試過程的一些建議。
  • 第四個是作為前端在進階路上的一些修鍊以及思考。

面試流程

首先我們來看一下面試流程,以及面試過程中可能問到的一些問題。

這裏大概列了一下我當時去面試阿里巴巴的流程,一共分為五面。一面是我的直屬主管,二面是前端團隊的負責人,三面是部門的總經理,四面是跨部門交叉面試,最後一面是部門的HR負責人。

整體的面試流程其實跟前面幾位講師講到的差不多,裏面有一點小小的區別。

第一,就是面試官的層級必須要高於候選人的預估層級,因此從一面開始,所有的面試官都必須是P8或以上。

第二,終面面試官的層級必須大於候選人兩級以上,也就是說終面的面試官需要是P10以上,在阿里內部叫研究員。

最後,就是P7及以上的候選人需要跨BU的交叉面試,來保證面試的公平跟客觀。

接下來我們來看一下面試的內容,具體的面試題目屬於敏感信息,這裏不是很方便透露,就簡單的列舉一下每一輪大概考察了哪一些內容。

首先我們來看一下主管面,他一般會考察你的項目經歷、技術深度,來確認你的基本能力是過關的。

接下來是前端團隊的負責人,一般會看你過往的作品以及個人的一些影響力。比如說有沒有比較成功的項目,對外的一些技術分享,以及一些開源作品等。

然後第三個是部門的總經理跟HRG,一般會看你的項目經驗,你對所從事的業務以及該業務所在行業的一些思考,以及你的人才調性跟匹配度。簡單的說,就是看你是否是部門所需要的人才。

跨BU交叉面試,面試官是隨機的,面的問題跟前面的面試官可能會有一些差異,但整體上是類似的。

可以看到,五輪面試下來,考察的內容其實是各有側重的,當然也有不少重合的地方,這裏簡單概括為四個方面。

第一個是項目經驗與成果,第二個是方案設計與實施細節,第三個是對業務以及行業的一些思考,第四個是人才的調性以及匹配度。我們逐個來拆解一下。

項目經驗與個人成果

首先是項目的經驗與成果。這個比較簡單,主要看的就是你在過去的幾年裡做了什麼項目,取得了什麼成績,有沒有取得一些突破。

不管是技術上的還是業務上的,在取得突破的同時,是否有對外進行沉澱輸出。比如說比如說輸出一套標準化的解決方案,是否在公司組織以及業界具有一定的影響力。

方案設計與實施細節

第二個是方案設計與實施細節。作為一個P8,對架構能力以及技術視野也是有一定的要求的。

這裏同樣是針對項目經驗進行考察,因為架構本身是為場景服務的,不存在脫離場景的架構。你在項目當中是如何進行選型與決策的?我們的簡歷裏面通常呈現的是一個具體的方案,但面試官他更關心的是你在這個方案背後的思考以及決策的過程。

比如說方案主要關心哪些點,是優先保證上線,還是重點保證後續的可維護性。方案是否閉門造車,有沒有跟集團或者業界的方案做對比等。

方案很難做到完美,最後總會存在這樣那樣的問題。這些問題都是面試官他可能挑戰到的。
我們的方案裏面存在的問題,其實很多時候是在有限的資源以及理想的設計之間取得的一些權衡。面試官他其實也有豐富的項目經驗,一般都能夠理解,你只要能夠自圓其說就可以了。最重要的是讓面試官看到你在具體細節背後的一些深入的思考。

行業以及業務的思考

第三個是行業以及業務的一些思考。到了P8,除了在技術上帶頭衝鋒之外,也需要在業務上有更多深入的思考,體現出業務上的決策力跟影響力。

比如說你當前所處的行業現在是什麼情況,是處於上升期呢?還是穩定期?還是已經進入了衰退期?

第二個,團隊業務的現狀。在行業中處於什麼位置?他是領頭羊,還是一個挑戰者?當前有哪些競爭對手?主要面臨哪一些挑戰?要如何破局?

也就是說,你要有更多就是業務以及全局的視角。

人才調性與匹配度

最後是人才的調性跟匹配度。簡單的說,就是看你是不是崗位所需要的人才,你過往的經驗能力跟當前的崗位是否匹配,最後,是否符合阿里的人才觀跟價值觀。

其中有一個非常重要的一點,也是大家經常忽略的一個點,就是個人的預期跟團隊的預期是否匹配。比如說你只是想專心做技術架構,但是崗位想要的其實是一個偏管理的人才,就很有可能會產生預期上的衝突。

這個時候你的落地就會比較困難。哪怕部門最終給你開出來一個比較高的職級,其實也是價值不大的。

面試準備

前面講了面試的整體流程、面試的題目,以及面試過程中主要考查的一些點。接下來講一下我在面試之前做了哪一些準備。主要包含三個部分,其實跟大家差不多。

第一個是了解崗位,第二個是準備簡歷,第三個是準備面試過程中可能問到的一些問題。

首先,了解崗位,主要就是了解這個崗位是做什麼的,他對應聘者有什麼要求,比如說年限,比如說技術棧,比如說項目經驗、部門的大致情況。

第二個準備簡歷,這個大家基本上都有經驗了,主要就是介紹自己的個人專長以及項目經驗,同時針對項目專長跟經驗進行能力的舉證。也就是說,證明你所你說的是真的。

第三個是面試,準備面試的問題。

根據崗位職級的不同,面試的問題跟側重點也不同。通常來說會圍繞技術能力、業務理解、綜合能力三個方面進行展開。

接下來我會簡單講一下這三個步驟,以及大概有哪一些注意事項。

了解崗位

首先是了解崗位的職責要求。很多時候我們看崗位的描述就可以了,一般用人單位會發布一個招聘的JD。如果是部門的情況,可以通過社區或者朋友來進行了解。

比如說,我去面試的時候,對應聘的職級有要求的話,需要重點了解什麼呢?

主要就是了解一下,對應職級對人才的要求,以及能力模型大概是什麼樣子的。

這裏貼一下阿里巴巴對於P8的能力要求。有兩個主要的關鍵特徵點,第一個是領域突破,第二個是業務增值。

怎麼理解這兩個關鍵詞?

領域突破

首先是領域突破,也就是說你需要在自己所擅長的領域裏面,通常是技術,要有所突破。

比如之前在做直播的時候,在技術上通過webassembly+ffmpeg的方式,實現了在web端播放H.265、降低帶寬,並支持更多的視頻編碼。

業務增值

業務增值怎麼理解呢?簡單的說,你需要通過技術突破、系統化數據體系建設等,給業務帶來增量價值。

舉個例子,在做1688直播的時候,項目組當時通過數據分析,發現早上開播的商家比較多,但買家比較少,晚上開播的商家較少,但是買家比較多。

開播的商家跟買家的數量明顯是衝突的,這個時候就可以調整一些運營策略,引導商家在晚上人流多的時候進行開播,提高業務的DAU以及轉化率。

這就是領域突破跟業務增值兩點的簡單闡釋。

能力要求

在崗位特徵之外,下面是三點具體的能力要求。比如說業務理解與實現,技術的沉澱與傳承,團隊的建設與發展等,字比較多,這裏就不一一念出來。

歸結起來其實主要就是三點。

  • 第一個就是具備較強的技術影響力以及業務影響力。
  • 第二個對業務有深入的思考,參与業務決策。
  • 第三個是參与團隊集團的人才建設。

準備簡歷

接下來講一下怎麼準備簡歷。

首先最重要的一點,就是要充分展示自己的能力,以及自己能力跟崗位的匹配度。也就是說告訴面試官,你是他們想要的那一個人。

第二個就是要注意能力舉證的邏輯,最好是数字說話。比如說介紹首屏性能優化,你必須要告訴面試官說你通過哪一些關鍵的手段提升了哪一些性能。在過往的面試中經常會遇到,有些候選人,他在簡歷裏面可能寫了上千字,說他做了什麼事情,但是他最終通過哪一些關鍵的步驟,取得了什麼樣的成果,沒有體現出來。這對看簡歷的面試官來說,也是一個比較頭大的事情。

最後一點,就是要謹慎挑選你的簡歷素材。簡而言之就是不要給自己挖坑,寫進簡歷裏面的每一句話,每一個数字都要經得起面試官的挑戰。被問倒的話是其次,千萬不要弄虛作假。因為弄虛作假,不管是在哪個企業裏面,都是紅線,不能觸碰。

準備面試問題

最後一個就是準備面試的問題。我自己也做了挺長時間的面試官,也經常面試別人。所以在面試之前,我通常會進行自我模擬面試,主要問自己以下幾個問題:

  1. 如果我是面試官我會問什麼問題?
  2. 如果我是面試官,我希望聽到什麼樣的回答?
  3. 我的優勢、不足在哪裡,如何揚長避短?

模擬面試的話,需要對崗位的能力模型、崗位的要求、自我的能力特長 以及 產出有比較清晰的認識。如果沒有什麼底的話,建議可以找比較有經驗的朋友幫自己把把關。也可以藉助搜索引擎去網上看一下,需要哪些知識和能力。

面試建議

接下來就是具體的面試過程中的建議。這裡是長者說過的一段話,我自己挺喜歡的,跟大家分享一下。

一個人的命運當然要靠自我的奮鬥,同時也要考慮到歷史的進程。

為什麼這麼說呢?因為面試本身是一個充滿了不確定性的事情。七分看實力,三分看運氣。

面試的不確定性

拋開個人的能力,以及面試的臨場表現,不確定性它主要體現在哪裡呢?

首先是面試官的個人偏好。比如你自己比較擅長vue,面試官它是angular的鐵粉,並且是排他性的鐵粉,大概率你們兩個人是聊不到一塊去的。大概在去年底,社區也發生過這麼個事情。這種情況雖然比較極端,但的確的存在。

其次就是崗位人才的稀缺性。比如說2010年時,隨着iOS以及安卓的流行興起的終端開發浪潮,以及2015年興起的人工智能浪潮。在這個時間點里,這兩個崗位的人才,他是供不應求的,做這塊開發的同學比較容易拿到自己想要的offer以及職級。

最後一個就是面試的時機。比如說現在你去面的這個團隊,他只招P6,但是你自己心目中的理想職級是P7,那就是時機不對,跟你個人能力其實並沒有太大的關係。

最前面提到了,面試三分靠運氣,聽上去有點像撞大運的感覺。但事實上,通過自身硬實力的增加,是可以讓面試的結果變得更加確定的,這裡有幾點小建議。

功夫在日常

第一點,就是功夫在日常,提前規劃、做好積累。如果你事先已經有了換工作的打算,你可以提前了解一下你要面試的崗位,你所要的職級有哪一些硬性要求,提前做好準備。

因為有一些東西是沒辦法臨時抱佛腳的,比如說團隊管理經驗。在過去的幾年時間里,我一直在做團隊管理,還包括一些項目管理的事情。因此在這一方面,我簡歷里是有東西可以寫的,也不怕被面試官問到。

個人品牌建設

第二個,是個人品牌的建設以及影響力的提升。

面試的時間非常有限,通常會在四十五分鐘到一個小時之間。坦白的講,作為一個面試官,他很難在這麼短的時間里對你做出非常全面以及準確的判斷。因為我做過面試官,我也知道這個。因此你需要花非常多的精力,來證明理你的能力能到能夠達到崗位的要求。

個人品牌的建立,以及影響力的建立有什麼好處呢?他會讓你面試的過程變得順利很多。比如說過去的這些年,我基本上每一年都會在社區做一些技術分享,同時也會持續更新我的技術博客。通過這一些,面試官在面試之前就可以對你的個人能力有一個基本的判斷。加上我本身從大公司里出來的buff,以及阿里朋友推薦的背書,在能力舉證這一塊可以省掉非常多的力氣。

保持平常心

最後的一點,就是面試是一個雙向選擇的過程。前面堂主在分享的時候其實也提到了,這個過程,很看緣分跟運氣,要保持平常心。

面試不通過,有可能是你的能力達不到,也有可能是沒有發揮好,需要認真的總結跟反思,制定規劃,進一步提高自己。

但反過來,如果面試通過,當然是一件非常值得開心的事情,但你也要懷着感恩的心,感謝這一路過來幫過自己的朋友,包括自己的面試官。能夠成為面試官,通常他的能力上都有過人之處。這種1v1將近一個小時的面試,是一個非常好的學習探討的過程。你能夠在這個過程中學到非常多的東西。因此要懷着感恩的心。

能力修鍊

接下來,是scott讓我加入的一個技術修鍊的章節。很多同學都覺得,到了P8之後,基本上就只是做做管理的事情,不做編碼了。但事實上不是這樣的。

我們先來看一下,到了P8之後,日常工作是做哪些事情呢?其實主要就三個方面,第一個就是技術管理,第二個項目管理,第三個是團隊管理。

技術管理

技術管理這一塊,因為P8屬於集團的技術中堅力量,他負責的技術域跟業務域會越來越大,很多時候其實並沒有太多精力參与具體的編碼。日常主要做的工作是參与方案的評審,技術架構的設計以及特定領域技術難點的攻堅。

不是說不寫代碼,而是說要站在更高的視角,深入業務輸出合理的方案和設計。簡單的說,就是從原先的自己編碼,變成帶着別人去合理地編碼。

項目管理

第二個是項目管理,做好項目管理主要要做好三個事情。

第一個就是目標管控。當前的項目處於什麼狀況,想要在什麼時候達成什麼目標。

第二個是資源協調。資源總是稀缺的,不管是人力、時間還是經費。按照既定的目標將資源協調到位,也有可能會根據資源的限制,調整實際的項目目標。

最後一個是過程的管控。確保項目按照既定規劃的路線實施,並達到目標,包括進度管理、風險管控以及質量管控等。

團隊管理

最後一個是團隊管理。前面的講師也提到了,主要做四個事情。

第一個是帶人做事。這一個是最基本的要求,就是帶着小夥伴高效、高質量地完成部門、團隊安排的工作。

第二個是看方向。比如說最新的技術趨勢,以及未來的業務走向等。

第三個是定規劃。比如說團隊未來半年、一年的技術規劃,團隊小夥伴的成長規劃等。

第四個是團隊建設。比如說未來團隊的人才梯度劃分、培養計劃、溝通等工作。

團隊管理是一個非常重要的事情,哪怕你現在沒有管理者的頭銜,因為它是在為業務的未來打基礎。

技術修鍊

這裏就簡單的三句話:扎得更深、看得更遠、始終編碼。

首先是扎得更深。也就是說,你在技術領域要有就是更深、更透徹的理解,而不是片面的隨着社區去追星追潮流。

第二個看的更遠。你在技術上、業務上必須有更遠的視角。你要能夠看到技術、業務的遠景,做好規劃。

第三個是始終編碼。現在其實有非常多的技術專家,已經脫離了一線的編碼,他已經沒辦法理解現在越來越複雜的前端研發環境,以及我們的業務變化。阿里內部現在也在推一個親碼活動,所有的P8,甚至P9,每個月都需要提交代碼。也就是要保持對代碼這塊的敏感度。

推薦書籍

接下來推薦一本書,這本書叫做影響力。從職場的角度來看,影響力能夠讓自己的工作開展、目標達成更加順利。其實包括求職也是一樣的,在前面的分享的各個章節裏面,已經反覆反覆提到了影響力這個詞。

影響力的重要性,基本上不用怎麼強調了,如何提高自己的影響力呢?包括技術影響力、團隊影響力、組織影響力,甚至是業界影響力。在這一本書中你都可以找到你想要的答案。

比如說互惠、承諾與一致、權威、短缺、喜好等,整本書的內容還是是比較通俗易懂的,尤其建議剛剛工作一兩年的同學看一下,會有非常大的幫助。

團隊簡介

接下來是關於 CBU技術部-前端體驗團隊 的一點簡單介紹,我是今年三月份加入的體驗技術團隊。

整個團隊現在有六七十人,在集團內部也有比較大的技術影響力。我們致力於鏈接商業與設計,給客戶提供專業的人機交互解決方案。作為B端的業務,我們通常比較低調,但是我們的技術團隊在集團內其實也擁有多個領先的技術產品。比如說像奇美拉搭建系統、JUST研發平台、lighthouse數據分析平台、柯南前端錄製反饋平台等。

我們的團隊技術棧以react、nodejs為主,此外,在serverless、webide、跨端、工程化、智能化、搭建等領域,都有比較多的工程實踐與沉澱。

下面是團隊今年的重點技術方向,主要有下面幾個,下面伐總會對這一塊做進一步的闡釋,這裏就簡單提一下。

加入我們

曬一下我們團隊的照片,這也是我加入CBU體驗技術團隊的一個非常重要的原因。最右邊的就是我們腿長一米八的美女主持人,霸天小姐姐,她也是我們團隊的,現在就坐在我的隔壁,我們每天都有面對面交流的機會。

大家不用太羡慕,只要加入我們團隊,你也可以獲得同樣的機會。這裏的話是幾個二維碼,最右邊的二維碼是我們的團隊跟崗位的介紹,大家感興趣的話可以了解一下。

最左邊是剛剛建的阿里巴巴CBU的技術交流群,大家可以用釘釘掃碼加入。我們已經把我們團隊的技術專家、高級技術專家都拉了進去,大家有什麼技術問題,有什麼困惑都可以掃碼進去交流。

最後,中間是我自己的個人二維碼,現在我們團隊招聘大量的P6跟P7,簡稱海量HC,歡迎加我微信,然後一起交流。加之前最好把自己的博客跟github的地址附錄一下

Q&A

謝謝大家。就是今天的分享主要就到這裏。然後大家看一下大家有什麼問題。

Q:好,小卡。接下來進入提問環節,請問從公司層面來看,騰訊與阿里哪一個更適合上升期的前端工程師發展。

A:這一點的話其實比較難回答,就是片面的比如說究竟是騰訊適合,還是阿里適合。剛好前陣子我跟阿里、騰訊、拼多多的幾位專家還有大佬一起面基,然後我們也探討過同樣的問題,該去什麼樣的公司或團隊,是技術好的,還是說錢多的。

其實答案都不對,重要的是加入成長性比較強的團隊。比如說,我們部門做的是B側的電商,然後風口上的1688電商直播,這個就是屬於公司、部門今年重點布局與規劃的業務,屬於成長性,爆發性比較強的業務。

我們在看應該加入哪個公司、團隊的時候,主要看的是這個部門、業務它的成長性,而不是說是阿里巴巴或者說騰訊哪個更適合。不管是騰訊還是阿里巴巴,在眾多的領域都有它的布局和規劃,也有很多具備成長性的一些業務,大家如果經常在社區逛,其實都會看到。

也就是說,主要看的是業務的成長性以及行業的成長性,公司倒是其次,基本上在大公司你都可以找到一些成長性強的業務和團隊。

比如說我們團隊,歡迎掃碼加入CBU技術交流群,然後一起來探討這個問題。

Q:好的,打下卡。第二個問題,大場對候選人的要求,或者說候選人面試準備,閱讀源碼是否是重要的一項。

A:怎麼說呢?對於有源碼閱讀經驗的同學,其實我們是非常歡迎的,比如說讀過react源碼、vue的源碼、webpack源碼等,我們基本可以判斷,就是這個小夥伴他對這一塊的技術有比較濃厚的興趣,以及比較深入的鑽研。

可能在不同的階段,對人才的要求不是特別一樣。舉個例子,比如說在14年,我當時去面阿里的時候,當時我主要講的是我在工程化以及模塊化的一些積累。當時我的面試官石破當場問了我這個問題,就是有沒有看過某某某的源碼這一塊。

為什麼呢?因為對於P6的同學來說,他更重要的是執行、對方案研究的深入程度,以及標準化方案的輸出。如果你閱讀過源碼,說明你對這塊有比較深入的研究。對於比如說像P7、P8的話,可能對於你的比如說團隊管理能力,你的技術視野等會有更高的要求。

不同的階段它的要求不一樣。但如果你讀過源碼這一塊,我們都是非常歡迎的。

Q:好的,好,還有第三個問題請教小凱,你在前端中是否有遇到過瓶頸期,然後你是怎麼突破的呢?

A:怎麼說呢,就瓶頸期,我分享一下當時我在創業時候的一些經歷跟歷程。我是在15年跟着朋友一起出去創業,然後當時做的是期權做市交易系統。整一個團隊其實做的是金融類的業務,並且是以後台技術為主導的。我當時作為一個前端,其實就孤零零的帶着可能兩三個前端同學,然後就比較孤獨。第二個就是技術上,其實在前端那塊要求並不是特別的高,也沒有太太多人跟我一起交流。

我在創業公司一共待了三年,如果按照當時的那個現狀下去的話,可能我就廢了,也不可能說今年來到阿里拿到P8。我當時是怎麼做的呢?第一個就是始終要關注業界的動態,知道當時最流行的技術趨勢是什麼,我們的業務可能會需要什麼。比如說,我之前提到的Nodejs學習筆記,那一本書就是在創業的那個期間寫出來的。

當時創業其實是非常累、非常辛苦的,可能創過業的同學都知道,我當時寫這本書的時候,基本上都是在晚上,可能十一二點下了班,回家之後,然後在那裡翻源碼,看博客,自己總結輸出。

第二個的話,就是當時團隊的重心是在後台的金融交易系統,前端的東西比較薄。這個時候,其實就是按照像阿里對人才的要求一樣,不要給自己設限,大膽突破自己的邊界。

比如說像當時,我的本職工作是前端,但我還做了非常多的事情,比如說像項目管理、團隊管理的事情。在技術上當時就是在node的那一塊做的相對比較深,我們金融系統裏面的一塊,我把它用nodejs 接過來。

團隊需要我做什麼,我基本就去學什麼。比如說當時做的最雜的時候,前端、php、nodej s,甚至最後連C++、iOS都會去接觸。

遇到瓶頸的時候,可能就是問自己,第一,我想要往哪一方面去發展。第二,當前業務團隊部門、甚至集團需要你去做什麼。

思考這兩個問題之後,基本上你就會得到你想要的答案。

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

【其他文章推薦】

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

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

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

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

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

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

視頻處理之OSD

欲觀原文,請君移步

OSD簡介

OSD,on-screen display的簡稱,即屏幕菜單式調節方式。一般我們按一下Menu鍵后屏幕彈出的显示器各項調節項目信息的矩形菜單,比如調亮度,色調,飽和度等信息,這個显示這個菜單的功能就是視頻行業的OSD。

基於FPGA的OSD設計與實現

1 Xilinx OSD IP功能

  • 支持最多8個layer
  • 背景顏色可編程
  • 位置,大小,顏色,透明度(alpha)可編程
  • 支持RGB和YUV視頻流

2 硬件結構框圖

硬件平台是基於xilinx xc7z035芯片開發的,關鍵模塊框圖如下圖1所示。

  • 一個時序產生模塊Video Timing Controller(在本次實驗中採用1080P標準時序)

  • 首先PL端將視頻流通過VDMA讀出,輸出接口為AXI4-Stream的數據流

  • 然後視頻流進入OSD IP(OSD輸入輸出也是AXI4-Stream接口)

  • 最後OSD輸出數據流與1080P時序同時送入到AXI4-Stream to Video Out模塊,輸出為HDMI接口

下面小編會詳細介紹OSD IP的例化與使用

3 OSD PL端

如果在使用OSD IP過程中出現如下錯誤,請在xilinx官網上申請OSD的License,這裏不再詳述如何申請License。

首先在Block Design中加入Video On Screen Display,打開後會看到如下圖2。

(1) 勾選AXI-Lite Interface:PS端通過AXI-Lite進行配置該IP

(2) Video Format選擇RGB

(3) Layers選擇2

(4) Layer Configuration:LAYER0選擇外部視頻流,也就是實時視頻,LAYER1選擇Internal,PS端可以控制進行圖文疊加

點擊Screen Layout Options,如圖3所示

(1) Background size(選擇背景大小)里寬度輸入1920,高度輸入1080

(2) Background color輸入背景顏色,這裏選擇黑色,可以通過axi-lite來控制

(3) layer0因為選擇的是外部視頻流,所以比如設置為外部視頻流分辨率,輸錯了,可能無法正常使用,小編已經遇到過了,本文使用1920×1080外部視頻流

(4) layer1因為選擇的是內部圖像控制器,所以無所謂設置什麼,可以通過axi-lite控制,所以選擇默認即可

點擊LAYER 1 Options出現圖4界面:因為是內部圖像控制器,所以可以進行一些配置,比如顏色多少,字符數目,比特像素等等,這裏小編選擇的是默認。

配置完OSD IP后,將其AXI-lite掛在總線上即可,然後保存Block Design即可。

注:點開Address Editor,一定要確定該IP被分配地址空間,如果沒有,點擊一下自動分配(小編遇到的問題就是這個ip地址空間在unmap里,導致後續PS端OSD IP無法初始化)。

4 OSD PS端

下面就是常規操作include bitstream導出SDK,其實就是生成hdf文件,硬件信息。然後就launch SDk。如圖4所示,可以看到hdf文件里都有什麼。

新建一個design_top的空工程,如圖5所示,在design_top_bsp下面可以看到system.mss文件,在紅框中找到OSD IP。

點擊import examples,出現如圖6所示,勾選對話框后選擇OK(不會玩IP先整個example)。

打開XosdSelfTestExample.c即可看到該例子程序是怎麼個處理流程(圖7為main函數,圖8為使用流程)小編稱之為PS端IP使用三步法

  • 第一步先進行lookup該IP

  • 第二步就是初始化該IP

  • 第三步就是使用IP

運行一下,結果如圖9所示,可以看到UART會打印OSD成功信息。

OSD 實例

閑話不說,上面經過了OSD example,小編也作為一個PS端初學者來玩一玩。

尷尬的是經常在寫c代碼的時候想着寫begin…end,真是verilog寫習慣了,思想難以改變,原來是花括弧啊{}

初始化模塊如下

在初始化后必須將該模塊進行複位,然後,否則該IP啟動不了。

int OsdInit(int DeviceID)
{
	int Status;
	/* Initialize the OSD instance */
	OsdCfgPtr = XOSD_LookupConfig(DeviceID);
	Status = XOSD_CfgInitialize(&Osd, OsdCfgPtr,OsdCfgPtr->BaseAddress);
	if (Status != XST_SUCCESS)		return 1;
	/* Reset the devices */
	XOSD_Reset(&Osd);
	/* Enable the OSD device and tell it to pick up the register changes	*/
	XOSD_Enable(&Osd);
	XOSD_RegUpdateEnable(&Osd);
	return 0;
}

配置模塊

這裏需要注意的是把BANKIndex輸入為1,否則會進行字符填寫方式就需要改變,不符合操作習慣XOSD_LoadCharacterSetBank(&Osd, Gcindex, 1, (u32 *)Font);

void Graphics_setting(u8 Gcindex,u8 LayerPriority,u32 ColorData[],u32 *TextData)
{
	int width = 1920;
	int height = 1080;
	int LayerAlphaValue = 0xFF;
	int LayerGlobalAlphaEnable = 0;
	XOSD_SetLayerAlpha(&Osd, Gcindex, LayerGlobalAlphaEnable,LayerAlphaValue);
	XOSD_SetLayerPriority(&Osd, Gcindex, LayerPriority);
	XOSD_SetLayerDimension(&Osd, Gcindex, 0, 0, width, height);
	XOSD_EnableLayer(&Osd, Gcindex);
	/* Load color, font and text and set the active banks */
	XOSD_LoadColorLUTBank(&Osd, Gcindex, 0, ColorData);
	//set BankIndex is 1(fit our keyboard)
	XOSD_LoadCharacterSetBank(&Osd, Gcindex, 1, (u32 *)Font);
	XOSD_LoadTextBank(&Osd, Gcindex, 0, (u32 *)TextData);
	XOSD_SetActiveBank(&Osd, Gcindex, 0, 0, 0, 0);
}

圖文疊加模塊

void OsdDrawText(int Gcindex,int x_pos, int y_pos, int color, int string_index, int text_size)
{
	u32 Instruction[XOSD_INS_SIZE];
	u16 ObjType = XOSD_INS_OPCODE_BOXTXT; /* A text string 	XOSD_INS_OPCODE_TXT*/
	u8 ObjSize = (text_size<<4); /* Text Scale factor (1x, 2x, 4x, 8x)	*/
	u16 XStart = x_pos; /* Horizontal start pixel of the text	*/
	u16 YStart = y_pos; /* Vertical start line of the text */
	u16 XEnd = x_pos; /* Horizontal end pixel of the text (not	used) */
	u16 YEnd = y_pos; /* Vertical end line of the text (must be same as YStart) */
	u8 TextIndex = string_index; /* Index of Text String */
	u8 ColorIndex = color; /* Color used to draw text */


	XOSD_CreateInstruction(&Osd, Instruction, Gcindex,ObjType, ObjSize,	XStart, YStart, XEnd, YEnd,TextIndex, ColorIndex);
	XOSD_LoadInstructionList(&Osd, Gcindex, 0, Instruction, 1);
	return;
}

實現結果

前面只給出了兩個圖層,工程退不回去了,目前工程實現的是疊加8個圖層(1個視頻,7個內部圖像控制器)。

參考鏈接

百度網盤源碼以及參考文檔鏈接如下

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

※回頭車貨運收費標準

Python 圖像處理 OpenCV (6):圖像的閾值處理

前文傳送門:

「Python 圖像處理 OpenCV (1):入門」

「Python 圖像處理 OpenCV (2):像素處理與 Numpy 操作以及 Matplotlib 显示圖像」

「Python 圖像處理 OpenCV (3):圖像屬性、圖像感興趣 ROI 區域及通道處理」

「Python 圖像處理 OpenCV (4):圖像算數運算以及修改顏色空間」

「Python 圖像處理 OpenCV (5):圖像的幾何變換」

圖像的閾值

看到這個詞可能大家都很懵,為啥在圖像處理裏面還會有閾值。

圖像的閾值處理用大白話講就是將圖像轉化為二值圖像(黑白圖),目的是用來提取圖像中的目標物體,將背景和噪聲區分開(可以近似的認為除了目標全是噪聲)。

通常會設定一個閾值 T ,通過 T 將圖像的像素劃分為兩類:大於 T 的像素群和小於 T 的像素群。

首先可以先將圖像轉化為灰度圖像,因為在灰度圖像中,每個像素都只有一個灰度值用來表示當前像素的亮度。

接下來二值化處理可以將圖像中的像素劃分為兩類顏色,一種是大於閾值 T 的,另一種是小於閾值 T 的。

比如最常見的二值圖像:

當灰度值小於閾值 T 的時候,可以將其像素設置為 0 ,表示為黑色。

當灰度值大於閾值 T 的時候,可以將其像素設置為 255 ,表示為白色。

在 OpenCV 中,為我們提供了閾值函數 threshold() 來幫助我們實現二值圖像的處理。

函數如下:

retval, dst = threshold(src, thresh, maxval, type, dst=None)
  • retval: 閾值
  • dst: 處理后的圖像
  • src: 原圖像
  • thresh: 閾值
  • maxval: 最大值
  • type: 處理類型

常用的 5 中處理類型如下:

  • cv.THRESH_BINARY: 二值處理
  • cv.THRESH_BINARY_INV: 反二值處理
  • cv.THRESH_TRUNC: 截斷閾值化
  • cv.THRESH_TOZERO: 閾值化為 0
  • cv.THRESH_TOZERO_INV: 反閾值化為 0

接下來這幾種處理類型有啥不同,我們一個一個來看。

二值處理

這種二值處理方式最開始需要選定一個閾值 T ,從 0 ~ 255 之間,我這裏選擇出於中間的那個數 127 。

接下來的處理規則就是這樣的:

  • 大於等於 127 的像素點的灰度值設定為最大值,也就是 255 白色
  • 小於 127 的像素點的灰度值設定為 0 ,也就是黑色

接下來開始寫代碼,看我們的馬里奧同學(不知道你們還記不記得我們的馬里奧同學):

import cv2 as cv

src = cv.imread("maliao.jpg")

# BGR 圖像轉灰度
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 二值圖像處理
r, b = cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY)

# 显示圖像
cv.imshow("src", src)
cv.imshow("result", b)

# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

反二值處理

這種方式和上面的二值處理非常相似,只是把處理規則給反了一下:

  • 大於等於 127 的像素點的灰度值設定為 0 ,也就是白色
  • 小於 127 的像素點的灰度值設定為最大值,也就是 255 白色

完整代碼如下:

import cv2 as cv

src = cv.imread("maliao.jpg")

# BGR 圖像轉灰度
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 二值圖像處理
r, b = cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY_INV)

# 显示圖像
cv.imshow("src", src)
cv.imshow("result", b)

# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

從圖像上可以看到,顏色和上面的二值圖像正好相反,大部分的位置都變成了白色。

截斷閾值化

這種方法還是需要先選定一個閾值 T ,圖像中大於該閾值的像素點被設定為該閾值,小於該閾值的保持不變。

完整代碼如下:

import cv2 as cv

src = cv.imread("maliao.jpg")

# BGR 圖像轉灰度
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 二值圖像處理
r, b = cv.threshold(gray_img, 127, 255, cv.THRESH_TRUNC)

# 显示圖像
cv.imshow("src", src)
cv.imshow("result", b)

# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

這種方式實際上是把圖片比較亮的像素處理成為閾值,其他部分保持不變。

閾值化為 0

這種方式還是需要先選定一個閾值 T ,將小於 T 的像素點設置為 0 黑色,其他的保持不變。

完整代碼如下:

import cv2 as cv

src = cv.imread("maliao.jpg")

# BGR 圖像轉灰度
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 二值圖像處理
r, b = cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO)

# 显示圖像
cv.imshow("src", src)
cv.imshow("result", b)

# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

這個方法是亮的部分不改,把比較暗的部分修改為 0 。

反閾值化為 0

這個和前面的反二值圖像很像,同樣是反閾值化為 0 ,將大於等於 T 的像素點變為 0 ,其餘保持不變。

完整代碼如下:

import cv2 as cv

src = cv.imread("maliao.jpg")

# BGR 圖像轉灰度
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 二值圖像處理
r, b = cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO_INV)

# 显示圖像
cv.imshow("src", src)
cv.imshow("result", b)

# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()

這個方法是暗的部分不改,把比較亮的部分修改為 0 。

全家福

接下來還是給這幾種閾值處理后的圖像來個全家福,讓大家能有一個直觀的感受,代碼我也給出來,如下:

import cv2 as cv
import matplotlib.pyplot as plt

# 讀取圖像
img=cv.imread('maliao.jpg')
lenna_img = cv.cvtColor(img,cv.COLOR_BGR2RGB)
gray_img=cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 閾值化處理
ret1, thresh1=cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY)
ret2, thresh2=cv.threshold(gray_img, 127, 255, cv.THRESH_BINARY_INV)
ret3, thresh3=cv.threshold(gray_img, 127, 255, cv.THRESH_TRUNC)
ret4, thresh4=cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO)
ret5, thresh5=cv.threshold(gray_img, 127, 255, cv.THRESH_TOZERO_INV)

# 显示結果
titles = ['Gray Img','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [gray_img, thresh1, thresh2, thresh3, thresh4, thresh5]

# matplotlib 繪圖
for i in range(6):
   plt.subplot(2, 3, i+1), plt.imshow(images[i],'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])

plt.show()

示例代碼

如果有需要獲取源碼的同學可以在公眾號回復「OpenCV」進行獲取。

參考

https://blog.csdn.net/Eastmount/article/details/83548652

http://www.woshicver.com/

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

【其他文章推薦】

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

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

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

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

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

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

※回頭車貨運收費標準

一名優秀的程序員應該向誰提問

這兩年來,向我提問的人真的可以稱得上是不計其數了。哎呀,一不小心又用了個成語,裝逼在無形當中啊。雖然有點誇張,但說真的不算少了,請摸着良心問問,你是不是就問過?

但我特別討厭一種行為,就是用手機拍電腦屏幕的照片來提問。為什麼這麼說呢?請你立刻現在馬上拿起手機自己拍張照試試。如果相機不給力,屏幕像素又低,我的天吶,看這種照片上的代碼真的是痛苦啊!

鑒於此,我在群里三番五次提醒過,請用截屏,不要用手機拍照!但隔三差五還是有人這樣照干不誤,我很生氣,真的。

你提問,肯定想要得到回答,對吧?如果你用心,那回答的人也就會用心,即便是你的問題石沉大海了,那也是對自己的一種負責任啊。

在提問題的時候,你應該做好充分的準備:

  • 用足夠多的細節來描述問題發生的場景,你想得到什麼樣的答案?
  • 在求助之前,你做了哪些努力?研究過了嗎?得到了一些線索嗎?

那可能有些人會不服氣,拋下一句狠話:“你這大佬也太不負責任了吧?我就是沒有找到答案才過來找你的啊?我努力了呀?”

冷靜一下哈,提個問題你脾氣這麼大,這麼焦躁,怎麼可能得到答案,對不對?

讓你做準備不是我在逃避責任,而是在教你,教會你自己怎麼解決問題。就拿我來說吧,我已經很少向別人提問題了,除了那隻橡皮鴨。

有生以來,我遇到最痛苦的一個問題就是“可學上往”(寫錯別字,我是認真的),真的,當時我問遍了所有我能問的群,我能問的人,因為這個問題很無解,你了解的。

在向別人求助之前,可行的解決方案就是去問度娘,對吧,但度娘又怎麼會告訴答案呢。有些好心的同行會扔一句“VVPPNN”,然後我就搜啊搜——搜不到答案。

大概折騰了兩周的時間,還是青銅時代群里的一位小夥伴告訴了我答案。由於最近風聲緊,我就不提了。不過,我需要坦誠一句,我“可學上往”純粹是為了寫技術文章用(偶爾 1024 下,不騙你),因為有時候,一些知識點,我自己還沒有掌握,必須得先學習一下,然後才能輸出給讀者。

但度娘有時候給的答案,真的是讓你懷疑人生,那些狗屁不是的帖子它的搜索結果里全都有。但骨骼這方面做得真的是不錯,有一說一。

(這篇文章寫了不少錯別字,不要怪我,我也是被逼的,忍耐一下,看不懂的地方就 YY 一下)

為什麼我很少提問題了呢?

  • 我碰到了一個問題;
  • 我自己研究了一會,沒找到答案;
  • 我決定還是骨骼吧;
  • 我把關鍵詞扔在搜索框里,答案好像還沒找到;
  • 我看了很多帖子,好像答案完全不着邊;
  • 我把問題重新梳理了一遍,準備找技術比我還好的朋友提問;
  • 10 分鐘過去后,我寫下了一百個字,感覺問題已經描述得很清楚了,在好友列表裡準備找朋友了;
  • 突然,我發現好像我搜索的關鍵詞不太對,於是我就換了一個,又換了一個,抱着試一試的心態,結果真的找到了想要的答案。

不知道你有沒有遇到這樣的情況?反正我真的是經歷了無數次。有時候,答案找不到,我都着急得想捶爆鍵盤了,甚至狠狠地在桌子上捶了一拳,疼痛的感覺讓我冷靜下來。

於是我想到了那隻橡皮鴨,我在心裏對它說:“為什麼這台服務器上的首頁打開時間需要一分多鍾,而另外一台服務器上只需要不到三秒鐘?”

“那你有沒有對比兩台服務器有什麼不同嗎?”橡皮鴨開口回答道。

“比對了呀,完全一樣啊,代碼一樣,只是說參數不一樣,war 包也一樣,都用的 Tomcat 啊。”我憤憤不平地說。

“操作系統一樣嗎?”橡皮鴨耐心地開導着我。

“不太一樣,一台是 Windows Server,一台是 CentOS。”我回答道。

“那你有沒有想過把 Windows Server 那台也換成是 CentOS?”橡皮鴨依然很冷靜。

“不會吧,就因為操作系統不同,首頁打開速度差別就會這麼大?”

“你試試唄,把環境備份下,反正現在切換一下操作系統又不麻煩。”

“好的,聽你的,橡皮鴨。”

一個小時后,神奇的事情發生了,原來問題真的是因為 Windows Server 啊!果然不如 Linux 靠譜啊!

以上就是三年前我真實經歷過的,當時有一台遺留的 Windows Server,我就沒想着把操作系統換成是 Linux 的,然後同樣的 war 包放上去后,首頁打開速度超慢,我嘗試過對首頁加上緩存,減少 JavaScript、CSS 文件的大小,對它們進行壓縮,甚至減少了從後台獲取數據的量,但所有的嘗試都於事無補。

最後,真的是橡皮鴨幫助到了我。當你把自己完全投入到一種假想當中,去問一個透徹而詳盡的問題時,答案真的會悄無聲息地找上門來。

大多數情況下,並不是因為我們的知識庫儲備不足,而是我們尋找問題的方向發生了偏離,一旦我們意識到了這種錯誤,問題也就不再是問題。

當然了,當你嘗盡一切辦法,仍然找不到答案的話,找大牛、找朋友、找同事、找社群,不要臉地提問吧,別怕自己受到打擊,別怕問題無人解答,你要做的是,把問題梳理得越來越清晰,也許答案就在你那裡。

如果覺得文章對你有點幫助,請微信搜索「 沉默王二 」第一時間閱讀。回復關鍵字「簡歷」更有一份技術大佬整理的優質簡歷模板,助你一臂之力。

本文已收錄 GitHub,傳送門~ ,裏面更有大廠面試完整考點,歡迎 Star。

我是沉默王二,一枚有顏值卻靠才華苟且的程序員。關注即可提升學習效率,別忘了三連啊,點贊、收藏、留言,我不挑,嘻嘻

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

【其他文章推薦】

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

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

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

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

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

※回頭車貨運收費標準

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

一篇文章快速搞懂 Atomic(原子整數/CAS/ABA/原子引用/原子數組/LongAdder)

前言

相信大部分開發人員,或多或少都看過或寫過併發編程的代碼。併發關鍵字除了Synchronized,還有另一大分支Atomic。如果大家沒聽過沒用過先看基礎篇,如果聽過用過,請滑至底部看進階篇,深入源碼分析。

提出問題:int線程安全嗎?

看過Synchronized相關文章的小夥伴應該知道其是不安全的,再次用代碼應驗下其不安全性:

public class testInt {
    static int number = 0;

    public static void main(String[] args) throws Exception {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000; i++) {
                    number = number+1;
                }
            }
        };

        Thread t1 = new Thread(runnable);
        t1.start();
        Thread t2 = new Thread(runnable);
        t2.start();

        t1.join();
        t2.join();
        System.out.println("number:" + number);
    }
}

 

 

運行結果:

在上面的例子中,我們定義一個初始值為0的靜態變量number,再新建並運行兩個線程讓其各執行10萬次的自增操作,如果他是線程安全的,應該兩個線程執行后結果為20萬,但是我們發現最終的結果是小於20萬的,即說明他是不安全的。

在之前Synchronized那篇文章中說過,可以在number=number+1這句代碼上下加Synchronized關鍵字實現線程安全。但是其對資源的開銷較大,所以我們今天再看下另外一種實現線程安全的方法Atomic。

Atomic基礎篇分界線

原子整數(基礎類型)

整體介紹

Atomic是jdk提供的一系列包的總稱,這個大家族包括原子整數(AtomicInteger,AtomicLong,AtomicBoolean),原子引用(AtomicReference,AtomicStampedReference,AtomicMarkableReference),原子數組(AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray),更新器(AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater)。

AtomicInteger

AtomicInteger,AtomicBoolean,AtomicLong三者功能類似,咱就以AtomicInteger為主分析原子類。

先看下有哪些API,及其他們具體啥功能:

public class testInt {

    public static void main(String[] args) {
        //定義AtomicInteger類型的變量,值為1
        AtomicInteger i = new AtomicInteger(1);
        //incrementAndGet方法先新增1再返回,所以打印2,此時i為2
        System.out.println(i.incrementAndGet());
        //getAndIncrement方法先返回值再新增1,所以打印2,此時i為3
        System.out.println(i.getAndIncrement());
        //get方法返回當前i值,所以打印3,此時i為3
        System.out.println(i.get());
        //參數為正數即新增,getAndAdd方法先返回值再新增666,所以打印3,此時i為669
        System.out.println(i.getAndAdd(666));
        //參數為負數即減去,getAndAdd方法先返回值再減去1,所以打印669,此時i為668
        System.out.println(i.getAndAdd(-1));
        //參數為正數即新增,addAndGet方法先新增666再返回值,所以打印1334,此時i為1334
        System.out.println(i.addAndGet(666));
        //參數為負數即減去,addAndGet方法先減去-1再返回值,所以打印1333,此時i為1333
        System.out.println(i.addAndGet(-1));
        //getAndUpdate方法IntUnaryOperator參數是一個箭頭函數,後面可以寫任何操作,所以打印1333,此時i為13331
        System.out.println(i.getAndUpdate(x -> (x * 10 + 1)));
        //最終打印i為13331
        System.out.println(i.get());
    }
} 

 

 

執行結果:

對上述int類型的例子改進

public class testInt {
    //1.定義初始值為0的AtomicInteger類型變量number
    static AtomicInteger number = new AtomicInteger(0);

    public static void main(String[] args) throws Exception {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000; i++) {
                    //2.調用incrementAndGet方法,實現加1操作
                    number.incrementAndGet();
                }
            }
        };

        Thread t1 = new Thread(runnable);
        t1.start();
        Thread t2 = new Thread(runnable);
        t2.start();

        t1.join();
        t2.join();
        System.out.println("number:" + number.get());
    }
}

 

 

我們可以看到運行結果是正確的20萬,說明AtomicInteger的確保證了線程安全性,即在多線程的過程中,運行結果還是正確的。但是這存在一個ABA問題,下面將原子引用的時候再說,先立個flag。

源碼分析

我們以incrementAndGet方法為例,看下底層是如何實現的,AtomicInteger類中的incrementAndGet方法調用了Unsafe類的getAndAddInt方法。

public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

 

我們看下getAndAddInt方法,裏面有個循環,直接值為compareAndSwapInt返回值為true,才結束循環。這裏就不得不提CAS,這就是多線程安全性問題的解決方法。

public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
}

 

CAS

線程1和線程2同事獲取了主內存變量值0,線程1加1並寫入主內存,現在主內存變量值1,線程2也加2並嘗試寫入主內存,這個時候是不能寫入主內存的,因為會覆蓋掉線程1的操作,具體過程如下圖。

CAS是在線程2嘗試寫入內存的時候,通過比較並設置(CompareAndSet)發現現在主內存當前值為1,和他剛開始讀取的值0不一樣,所以他會放棄本次修改,重新讀取主內存的最新值,然後再重試下線程2的具體邏輯操作,再次嘗試寫入主內存。如果這時候線程1,再次對主內存進行了修改,線程2發現現在主內存的值又和預期不一樣,所以將放棄本次修改,再次讀取主內存最新值,再次重試並嘗試寫入主內存。我們可以發現這是一個重複比較的過程,即直到和預期初始值一樣,才會寫入主內存,否則將一直讀取重試的循環。這就是上面for循環的意義。

CAS的實現實際上利用了CPU指令來實現的,如果操作系統不支持CAS,還是會加鎖的,如果操作系統支持CAS,則使用原子性的CPU指令。

原子引用

在日常使用中,我們不止對上述基本類型進行原子操作,而是需要對一些複雜類型進行原子操作,所以需要AtomicReference。

不安全實現

先看不安全的BigDecimal類型:

public class testReference {
    static BigDecimal number = BigDecimal.ZERO;

    public static void main(String[] args) throws Exception {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                   number=number.add(BigDecimal.ONE);
                }
            }
        };

        Thread t1 = new Thread(runnable);
        t1.start();

        Thread t2 = new Thread(runnable);
        t2.start();

        t1.join();
        t2.join();

        System.out.println(number);
    }
} 

 

 

運行結果如下圖,我們可以看到兩個線程,自循環1000次加1操作,最終結果應該是2000,可是結果小於2000。

安全實現-使用CAS

public class testReference {
    //定義AtomicReference類型BigDecimal變量
    static AtomicReference<BigDecimal> number = new AtomicReference<BigDecimal>(BigDecimal.ZERO);

    public static void main(String[] args) throws Exception {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    //手動寫循環+CAS判斷
                    while(true){
                        BigDecimal pre=number.get();
                        BigDecimal next=number.get().add(BigDecimal.ONE);
                      if(number.compareAndSet(pre,next))  {
                          break;
                      }
                    }
                }
            }
        };

        Thread t1 = new Thread(runnable);
        t1.start();

        Thread t2 = new Thread(runnable);
        t2.start();

        t1.join();
        t2.join();

        System.out.println(number.get());

    }
}

 

 

運行結果如下:

ABA問題及解決

在上面CAS過程中,是通過值比較來知曉是不是能夠更新成功,那如果線程1先加1再減1,這樣主內存還是原來的值,即線程2還是可以更新成功的。但是這樣邏輯錯了,線程1已經發生了修改,線程2不能直接更新成功。

代碼:

public class testInt {

    static AtomicInteger number = new AtomicInteger(0);

    public static void main(String[] args) throws Exception {


        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int a = number.get();
                System.out.println("開始number:" + a);
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(number.compareAndSet(a, a++));


            }
        });
        t1.start();
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("開始增加操作");
                int a = number.incrementAndGet();
                System.out.println("當前number:" + a);
                int b = number.decrementAndGet();
                System.out.println("當前number:" + b);
            }
        });
        t2.start();

        t1.join();
        t2.join();
    }
} 

 

 

我們看線程2對其進行了一系列操作,但是最後打印了還是true,表示可以更新成功的。這顯然不對。

那我們可以使用AtomicStampedReference,為其添加一個版本號。線程1在剛開始讀取主內存的時候,獲取到值為0,版本為1,線程2也獲取到這兩個值,線程1進行加1,減1的操作的時候,版本各加1,現在主內存的值為0,版本為2,而線程2還拿着預計值為0,版本為1的數據嘗試寫入主內存,這個時候因版本不同而更新失敗。具體我們用代碼試下:

public class testInt {

    static AtomicStampedReference<Integer> number = new AtomicStampedReference<Integer>(0, 0);

    public static void main(String[] args) throws Exception {


        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int a = number.getReference();
                int s = number.getStamp();
                System.out.println("開始number:" + a + ",stamp:" + s);
                try {
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(number.compareAndSet(a, a + 1, s, s + 1));


            }
        });
        t1.start();
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("開始增加操作");
                int a = number.getReference();
                int s = number.getStamp();
                number.compareAndSet(a, a + 1, s, s + 1);
                System.out.println("當前number:" + a + ",stamp:" + (s + 1));
                a = number.getReference();
                s = number.getStamp();
                number.compareAndSet(a, a - 1, s, s + 1);
                System.out.println("當前number:" + a + ",stamp:" + (s+1));
            }
        });
        t2.start();

        t1.join();
        t2.join();
    }
} 

 

我們可以看到每次操作都會更新stamp(版本號),在最後對比的時候不僅比較值,還比較版本號,所以是不能更新成功的,false.

原子數組

AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray三者類似,所以以AtomicIntegerArray為例,我們可以將下面AtomicIntegerArray看做是AtomicInteger類型的數組,其底層很類似,就不詳細寫了。

AtomicIntegerArray  array = new AtomicIntegerArray(10);
array.getAndIncrement(0);   // 將第0個元素原子地增加1

 

AtomicInteger[]  array = new AtomicInteger[10];
array[0].getAndIncrement();  // 將第0個元素原子地增加1

 

字段更新器和原子累加器比較簡單,這裏就不說了。 

Atomic進階篇分界線

LongAdder源碼分析

LongAdder使用

LongAdder是jdk1.8之後新加的,那為什麼要加他?這個問題,下面將回答,我們先看下如何使用。

public class testLongAdder {
    public static void main(String[] args) throws Exception {
        LongAdder number = new LongAdder();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 10000; j++) {
                    number.add(1L);
                }
            }
        };
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("number:" + number);
    }
}

 

我們可以看到LongAdder的使用和AtomicLong大致相同,使用兩個線程Thread1,Thread2對number值各進行一萬次的自增操作,最後的number是正確的兩萬。

與Atomic的對比優勢

那問題來了,既然AtomicLong能夠完成對多線程下的number進行線程安全的操作,那為什麼還要LongAdder?我們先來段代碼比較下,兩個在結果都是正確的前提下,性能方面的差距。

public class testLongAdder {
    public static void main(String[] args) {
       //1個線程,進行100萬次自增操作
        test1(1,1000000);
      //10個線程,進行100萬次自增操作
        test1(10,1000000);
     //100個線程,進行100萬次自增操作
        test1(100,1000000);
    }

    static void test1(int threadCount,int times){
        long startTime=System.currentTimeMillis();
        AtomicLong number1=new AtomicLong();
        List<Thread> threads1=new ArrayList<>();
        for(int i=0;i<threadCount;i++) {
            threads1.add(new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < times; j++) {
                        number1.incrementAndGet();
                    }
                }
            }));
        }
        threads1.forEach(thread -> thread.start());
        threads1.forEach(thread ->{
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } );

        long endTime=System.currentTimeMillis();
        System.out.println("AtomicLong:"+number1+",time:"+(endTime-startTime));

        LongAdder number2=new LongAdder();
        List<Thread> threads2=new ArrayList<>();
        for(int i=0;i<threadCount;i++) {
            threads2.add(new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < times; j++) {
                        number2.add(1);
                    }
                }
            }));
        }
        threads2.forEach(thread -> thread.start());
        threads2.forEach(thread ->{
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } );

        System.out.println("LongAdder:"+number2+",time:"+(System.currentTimeMillis()-endTime));

    }
} 

 

上述代碼對比了1個線程,10個線程,100個線程在進行100百次自增操作后,AtomicLong和LongAdder所花費的時間。通過打印語句,我們發現在最終number1和number2都正確的基礎上,LongAdder花費的時間比AtomicLong少了一個量級。

源碼分析

那為什麼會導致這種情況,我們就要從源碼層面分析。AtomicLong為什麼效率低?因為如果線程數量一多,尤其在高併發的情況下,比如有100個線程同時想要對對象進行操作,肯定只有一個線程會獲取到鎖,其他99個線程可能空轉,一直循環知道線程釋放鎖。如果該線程操作完畢釋放了鎖,其他99個線程再次競爭,也只有一個線程獲取鎖,另外98個線程還是空轉,直到鎖被釋放。這樣CAS操作會浪費大量資源在空轉上,從而使得AtomicLong在線程數越來越多的情況下越來越慢。

AtomicLong是多個線程對同一個value值進行操作,導致多個線程自旋次數太多,性能降低。而LongAdder在無競爭的情況,跟AtomicLong一樣,對同一個base進行操作,當出現競爭關係時則是採用化整為零的做法,從空間換時間,用一個數組cells,將一個value拆分進這個數組cells。多個線程需要同時對value進行操作時候,可以對線程id進行hash得到hash值,再根據hash值映射到這個數組cells的某個下標,再對該下標所對應的值進行自增操作。當所有線程操作完畢,將數組cells的所有值和無競爭值base都加起來作為最終結果。

我們先看下LongAdder裏面的字段,發現其裏面沒有,主要是在其繼承的Stripped64類中,有下面四個主要變量。

 /** CPU數量,即cells數組的最大長度*/
    static final int NCPU = Runtime.getRuntime().availableProcessors();

    /**
     *cells數組,為2的冪,2,4,8,16.....,方便以後位運算
     */
    transient volatile Cell[] cells;

    /**
     * 基值,主要用於沒有競爭的情況,通過CAS更新。
     */
    transient volatile long base;

    /**
     * 調整單元格大小(擴容),創建單元格時使用的鎖。
     */
    transient volatile int cellsBusy;

 

 

下面是add方法開始。

 public void add(long x) {
        //as:cells數組的引用
        //b:base的基礎值
        //v:期望值
        //m:cells數組大小
        //a:當前數組命中的單元
        Cell[] as; long b, v; int m; Cell a;
        //as不為空(cells已經初始化過,說明之前有其他線程對初始化)或者CAS操作不成功(線程間出現競爭)
        if ((as = cells) != null || !casBase(b = base, b + x)) {
        //初始化uncontented,true表示未競爭(因為有兩個情況,這裏先初始化,後面對其修改,就能區分這兩種情況)
        boolean uncontended = true;
        //as等於null(cells未初始化)
        //或者線程id哈希出來的下標所對應的值為空(cell等於空),getProbe() & m功能是獲取下標,底層邏輯是位運算
        //或者更新失敗為false,即發生競爭,取非就為ture
        if (as == null || (m = as.length - 1) < 0 ||
                (a = as[getProbe() & m]) == null ||
                !(uncontended = a.cas(v = a.value, v + x)))
        //進入到if裏面,說明更新case失敗,或者更新某個cell也失敗了,或者cell為空,或者cells為空
                longAccumulate(x, null, uncontended);
        }
    }

 

從LongAdder調用Stripped64的longAccumulate方法,主要是初始化cellscells的擴容多個線程同時命中一個cell的競爭操作。

final void longAccumulate(long x, LongBinaryOperator fn,
                              boolean wasUncontended) {
        //x:add的值,fn:為null,wasUncontended:是否發生競爭,true為發生競爭,false為不發生競爭
        int h;//線程的hash值
        //如果該線程為0,即第一次進來,所以ThreadLocalRandom強制初始化線程id,再對其hash
        if ((h = getProbe()) == 0) {
            ThreadLocalRandom.current(); 
            h = getProbe();
            wasUncontended = true;
        }
        //擴容意向,為false肯定不擴容,為true可能擴容
        boolean collide = false; 
        //死循環               
        for (;;) {
            //as:cells數組的引用
            //a:當前線程命中的cell
            //n:cells的長度
            //v:當前線程命中的cell所擁有的value值
            Cell[] as; Cell a; int n; long v;
            //cells不為空
            if ((as = cells) != null && (n = as.length) > 0) {
                //當前線程命中的cell為空,下面邏輯是新增cell
                if ((a = as[(n - 1) & h]) == null) {
                    if (cellsBusy == 0) {       // Try to attach new Cell
                        Cell r = new Cell(x);   // Optimistically create
                        if (cellsBusy == 0 && casCellsBusy()) {
                            boolean created = false;
                            try {               // Recheck under lock
                                Cell[] rs; int m, j;
                                if ((rs = cells) != null &&
                                    (m = rs.length) > 0 &&
                                    rs[j = (m - 1) & h] == null) {
                                    rs[j] = r;
                                    created = true;
                                }
                            } finally {
                                cellsBusy = 0;
                            }
                            if (created)
                                break;
                            continue;           // Slot is now non-empty
                        }
                    }
                    collide = false;
                }
                //發生競爭
                else if (!wasUncontended)       // CAS already known to fail
                    wasUncontended = true;      // Continue after rehash
                //沒有競爭,嘗試修改當前線程對應的cell值,成功跳出循環
                else if (a.cas(v = a.value, ((fn == null) ? v + x :
                                             fn.applyAsLong(v, x))))
                    break;
                //如果n大於CPU最大數量,不可擴容
                else if (n >= NCPU || cells != as)
                    collide = false;            // At max size or stale
                else if (!collide)
                    collide = true;
                //獲取到了鎖,進行擴容,為2的冪,
                else if (cellsBusy == 0 && casCellsBusy()) {
                    try {
                        if (cells == as) {      // Expand table unless stale
                            Cell[] rs = new Cell[n << 1];//左移一位運算符,數量加倍
                            for (int i = 0; i < n; ++i)
                                rs[i] = as[i];
                            cells = rs;
                        }
                    } finally {
                        cellsBusy = 0;
                    }
                    collide = false;
                    continue;                   // Retry with expanded table
                }
                h = advanceProbe(h);
            }
            //cells等於空,並且獲取到鎖,開始初始化工作,創建結束釋放鎖,繼續循環
            else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
                boolean init = false;
                try {                           // Initialize table
                    if (cells == as) {
                        Cell[] rs = new Cell[2];
                        rs[h & 1] = new Cell(x);
                        cells = rs;
                        init = true;
                    }
                } finally {
                    cellsBusy = 0;
                }
                if (init)
                    break;
            }
            else if (casBase(v = base, ((fn == null) ? v + x :
                                        fn.applyAsLong(v, x))))
                break;                          // Fall back on using base
        }
    }

 

 

結語

結束了,撒花。這篇主要說了Atomic的一些使用,包括Atomic原子類(AtomicInteger,AtomicLong,AtomicBoolean),Atomic原子引用(AtomicReference,AtomicStampedReference),以及1.8之後LongAdder的優勢,源碼分析。過程還穿插了一些CAS,ABA問題引入和解決方式。

 

參考資料

Java多線程進階(十七)—— J.U.C之atomic框架:LongAdder

CAS原理

Java 8 Performance Improvements: LongAdder vs AtomicLong

AtomicInteger深入理解

原子操作類AtomicInteger詳解

玩轉Java併發工具,精通JUC,成為併發多面手

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

【其他文章推薦】

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

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

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

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

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

※回頭車貨運收費標準

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

奇駿 途觀都被逼至絕路!這新款SUV顏值操控同級無敵?

內飾上也是進行了重新設計,用料也更為厚道,相當於原來的中庸內飾設計,現款設計無疑更為時尚。加入懸浮式中控屏幕以及改變了空調出風口的形狀。儀錶盤依然是三錶盤式設計,中規中矩,若是可以能把轉速表放在中央相信能贏得更多馬粉的喜歡。

前言

馬自達的車型對於很多消費者來說就像是夢中情人的存在,非常喜歡但可能因為價格、實用性等問題最後卻是選擇其他的車型。而在今年剛剛開幕的洛杉磯車展上,馬自達給我們帶來了最新的CX-5,那麼它有着什麼樣的改變?是否能讓人突破理性果斷將其開回家?

2017款CX-5使用的依然是馬自達近年來力推的魂動設計,所以它看起來還是給到我們比較熟悉的感覺,但是相對於現款的設計,無疑是更為激進動感,在顏值方面再次領跑整個緊湊型SUV。

大燈方面變得更為凌厲,而且尺寸也相對小了。進氣格柵面積更大,並且從原本有着的鍍鉻裝飾變成了現在的黑色網狀格柵,更像是一輛性能車,一改現款的儒雅氣質,突顯了自己的凌厲氣質。

大燈光源上始終使用的是氙氣大燈,不過LED日間行車燈效果佳,造型漂亮。

得益短后懸的設計,2017款CX-5看起來更為緊湊。除此以外,馬自達還增大了A柱的角度帶來了更佳的視野,降低了重心以及更寬的輪距以求有着更為優秀的操控表現,所以最佳操控緊湊型SUV的地位CX-5是再次坐實了。

大尺寸輪轂配合短前後懸的設計使得新CX-5車身更為緊湊,車頭前吻是整車中最為性感的部分。

家族化設計使得CX-5在尾部沒有太多的新意,但總歸是更為動感,上方的擾流板相當個性。

內飾上也是進行了重新設計,用料也更為厚道,相當於原來的中庸內飾設計,現款設計無疑更為時尚。加入懸浮式中控屏幕以及改變了空調出風口的形狀。

儀錶盤依然是三錶盤式設計,中規中矩,若是可以能把轉速表放在中央相信能贏得更多馬粉的喜歡。

在空間表現上將於現款持平,所以空間和競爭對手相比還是處於劣勢,不過加入了傾角可調節式的後排座椅,後排還是可以坐得比較舒適的。

寬大的座椅是佔據空間的大戶,但是這樣乘坐舒適度,尤其是長途時就有着很大的保證。

動力方面將維持現款的2.0L以及2.5L創馳藍天發動機,配搭的是6AT變速箱,油耗表現優秀。

價格方面相信將維持現款的17-25萬區間,據悉2017款將在下一年引進國產,這款全新的CX-5在外觀內飾上以及操控上有了一定的提升 ,相對於其他車企的改款來說這相當的厚道,不過在國人重視的空間方面馬自達始終沒能交出一份滿意的結果。對此,你願意為這“夢中情人”埋單嗎?還是覺得“可遠觀而不可褻玩焉”?本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

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

這款轎車標配ESP起價只有5萬多 10月份還賣了1.6萬台!

所以小編這次就是要給大家說說艾5哪款車的性價比最高。下面兩個圖表分別是手動擋車型和自動擋車型。其中艾5標配主/副駕駛座安全氣囊、ESp、上坡輔助、后視鏡電動調節。所以如果預算不充足,即使最低配的艾5,也是可以入手的。

自主SUV異常火爆是眾所周知的,但是自主轎車在和合資轎車的對抗中一直出於劣勢,所以不少人都唱衰自主轎車。

但是事情總會有轉機的,只要廠家拿出有誠意的作品,銷量一定不會差的。比如奇瑞艾瑞澤5(本文簡稱艾5),這款起步價只有5.89萬的緊湊型轎車,要保證顏值和空間的情況下,竟然全系標配了ESp,正是因為如此厚道的配置,所以艾5的10月份銷量為16504輛。表現非常好。

艾5在今年3月18日上市,指導價為5.89-9.79萬,上市之後就取得了很大的反響,之所以引起巨大的關注,一是因為艾5的的原創性很高,在細節方面都突出了年輕化的設計理念。車頭造型飽滿,中網樣式類似“滿天星”,這樣的設計也使前格柵的層次感較為豐富。

二是因為艾5的配置確實不低。艾5的車身尺寸為4572*1825*1482mm,軸距為2670mm,標準的緊湊型轎車,不小的軸距極大的保證了車內空間。同時配置很高,即使是最低配,也是標配了ESp,從這一點可以看出這個企業還是挺實在的。

正是因為企業的“實在”,所以才得到了消費者的認可。但是當消費者去選擇艾5的時候,會發現密密麻麻一堆車型看起來就頭疼。所以小編這次就是要給大家說說艾5哪款車的性價比最高。下面兩個圖表分別是手動擋車型和自動擋車型。

其中艾5標配主/副駕駛座安全氣囊、ESp、上坡輔助、后視鏡電動調節。所以如果預算不充足,即使最低配的艾5,也是可以入手的。

通過圖表可以發現,撇開手動擋最低配和自動擋高配,其餘的手動擋和自動擋都是相互對應的,價格差了8000元,但是其它配置一樣的,所以相當於8000買個一台CVT變速箱,所以我們就以手動擋車型為例子進行分析。

通過上圖我們發現,雖然低配的性價比不低,但是和次低配領潮版比起來,性價比還是沒有領潮版高。

領潮版、智效領動版、領銳版相比起來,首先排除智效領動版,性價比最低。雖然領銳版售價已經接近7萬,但是多出的配置還是比較實用的。所以領銳版也有一定的性價比。

對於再高級別的領跑版和領臻版,無非就是多個氣囊、GpS,不過價格已經過高,對於艾5這款主打性價比的車子,顯然是不會受歡迎的。不過如果資金充足的話也可以選擇手動或者自動領臻版,安全配置比較豐富。

對於售價高達9.79萬的頂配車型-自動領尊版,更多的是為了提升品牌形象,幾乎完全沒有性價比。

綜上所述,領潮版的性價比最高了,其次是領銳版,同時最低配的手動領尚版性價比也不錯。其它車型的性價比不是很高。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

※回頭車貨運收費標準

廣州現場精彩不斷 奧德賽主場熱力開局

“全能MpV”奧德賽具備了魔方式的空間變換組合,可以根據不同場合的需求自由切換:除了可以乘坐7人的正常模式以外,還可以放倒部分第三排座椅,變為“休閑模式”或“超長模式”,更能將後排完全收起放平,變為“超大模式”。

在個人色彩越來越濃的今天

我們在職場上八面玲瓏,進退自如

但一轉身,面對與最親近的家人溝通

卻往往不知該如何應對……

11月的廣州依舊“熱情”高漲,而這份熱情也同樣延續到了11月12日在廣州舉辦的奧德賽非凡品鑒會活動現場。作為繼上海、北京之後又一場有別傳統的非凡品鑒會,坐鎮主場的奧德賽此番同樣延續了熱播綜藝《飯局的誘惑》節目熱潮,誠邀兩位金牌辯手現場與大家分享傳授說話之道,在欣賞奧德賽非凡魅力的同時,現場觀眾更是得到了智、情、局三商的全方位提升。

事實上,《飯局的誘惑》作為奧德賽與綜藝大咖馬東聯手打造的一檔綜藝節目,節目中高智商高情商的語言對壘令觀眾朋友大呼過癮。同樣的,以雙商詮釋自我產品特點的奧德賽在節目中頻繁亮相,更是成為嘉賓主持話梗里的經典“橋段”。也正因此,在非凡品鑒會上,奧德賽同樣將“說話的藝術”搬到了現場,在全方位展示自身產品實力的同時,更是將智、情、局三商的精髓應用到了日常生活之中。

延續高雙商開局 ,奧德賽掌控生活格局

Talk show環節,一如在前兩站中,“金牌辯手”們教會了大家如何應付生活中的各種尷尬,廣州站品鑒會上,馬薇薇與黃執中同樣為大家準備了新鮮的生活話題。

現場,金句女王馬薇薇首先與大家分享了如何在家庭生活中以“分”為貴,即在家庭關係中分清是“男權”還是“平權”為主;分清楚想要從原生家庭得到什麼就必須失去什麼;分清楚在自己組建的新家庭里是願意當主人還是當“孩子”。把握家庭話語權,例如馬薇薇提及在平權家庭中,面對出行問題時則必須共同承擔,在帶上自己父母的同時更要照顧到對方的父母。也正因此,像奧德賽這樣至少能夠容下6個人的車才是出行的必需品。

而事實上,作為一款7座MpV車型,奧德賽擁有2+2+3的座椅布局,在日常出行中,與一家三口的需求完美匹配,可以盡享第二排航空座椅的舒適體驗。即便是再帶上雙方父母,奧德賽的座位和空間也是綽綽有餘。這便是奧德賽對於家庭出行更為全面的考慮,也足以凸顯出其高情商的一面。

對於家庭生活的妥善處理,在網絡上一向以“情感專家”著稱的黃執中更是以男性視角深入剖析,教會大家如何利用情商照顧到身邊的每一個人。在談話中,黃執中提出:在遇到問題時不應關注事件本身,而是當事人雙方感覺的問題;在討論問題時不應站在對立面,而是轉換方式,一同面對問題;最終即便問題解決,也應該從對方得失心出發給予一定的安慰,讓對方知道她的委屈你能懂。簡而言之,黃執中用超高的情商詮釋了面對尷尬處境時如何照顧全局,細緻巧妙的處理也贏得了在場觀眾的掌聲。

正如黃執中說的那樣,奧德賽對於“掌控全局”也同樣非常在行。“全能MpV”奧德賽具備了魔方式的空間變換組合,可以根據不同場合的需求自由切換:除了可以乘坐7人的正常模式以外,還可以放倒部分第三排座椅,變為“休閑模式”或“超長模式”,更能將後排完全收起放平,變為“超大模式”。無論是全家外出的座位需要,亦或是商務接待需要的車內空間,奧德賽都能輕鬆掌控。

情景演繹扣人心弦,奧德賽解碼非凡亮點

與傳統品鑒會相比,非凡品鑒會的現場可謂處處不同。除了引人入勝的talk show環節,現場講師對產品的解讀也是別具一格。通過場景的植入與話題的點撥,講師從“撥、移、躺、藏、開”多角度深入,為現場觀眾生動解碼了奧德賽的非凡體驗點。

以“移”為例,在講解過程中,講師通過實際的例子為大家詮釋了奧德賽超低車門踏板設計的用意。原來,在設計之初,考慮到一些身着裙裝的女性能夠方便上下車,同時也照顧到老人小孩的乘坐便利,奧德賽在保證通過性的同時,將油箱做的更扁平,合理化配置的前提下,為乘客提供了最佳的上下車高度。奧德賽用高智商和高情商的雙商完美解決了問題。

亦動亦靜,全方位感受奧德賽非凡一面

靜態展示體驗部分,現場的一輛“特殊”展車令不少人眼前一亮。作為企業社會化責任的一部分,同時也作為車系派生車型的進一步完善,奧德賽福祉車的亮相無疑是場上的另一大看點。通過遙控二排可升降旋轉座椅,短短十幾秒內,行動不便的乘客無需自己挪動便可輕鬆實現上下車動作,方便之餘也再次體現出奧德賽全方位人性化的設計理念。

當然,除了靜態展示部分,品鑒會又怎少的了試駕環節。不同與上海站與北京站的路況,廣州站的試駕路線採用了“直線”加“調頭”的模式。試駕時,體驗者不僅能夠感受到“黃金動力組合”下奧德賽CVT無級變速箱的平順加速動力,同時,在調頭部分中更可感受奧德賽同級最小轉彎半徑的優勢。這樣的專項試駕也令不少體驗者印象深刻。

除了靜態展示和試乘試駕部分外,主辦方還為親臨現場體驗的來賓準備了奧德賽全能生活非凡禮遇。豐盛的現金禮遇和置換福利表現也令不少來賓現場簽訂購車意向。奧德賽的高局商則恰恰體現在此。

從職場到生活,從同事相處到家庭關係,奧德賽攜多位名嘴辯手與大家分享了職場人生中的說話之道,用一個個生動有趣的例子完美詮釋了高智商高情商的人生格局。創新、趣味、智慧、尊享,這就是奧德賽非凡品鑒會留給在場所有人的印象。而下一站深圳,活動即將迎來收官站,屆時,名嘴嘉賓又將有哪些辛辣犀利的話題與大家分享,奧德賽與你一同見證非凡本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

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

※回頭車貨運收費標準

城市SUV就不能越野?這些20萬級的SUV不僅能家用還能出去野!

98-22。98萬元水平對置發動機、左右對稱四驅系統,這都是斯巴魯強有力的武器,一直以來只能通過進口途徑購買的斯巴魯汽車給人感覺都是售價不便宜。而事實上斯巴魯有一款最低售價低於二十萬的SUV,那就是斯巴魯XV。對了,斯巴魯車配件都是進口的,所以維修保養的成本會相對高一點。

叫獸之前發過一篇文章說硬派SUV在操控、舒適性、動力調校等方面的表現導致其不適合城市的駕駛。然而事實上像叫獸這種從山裡走出來的孩子,雖然平時在城市裡混,但過年過節還是必須開車回家才夠意思的,不然買車有什麼意義?對吧。所以一輛既能在城市輕鬆駕駛,跑爛路的時候又有較好通過性的SUV,就最適合叫獸了。眼看着要年底了,叫獸跟你們分享一下這樣的車有哪些吧。

東風日產-奇駿

指導價:18.18-26.78萬元

硬朗平直的車身,優秀的四驅系統,同級別幾乎最好的通過性,這是上一代奇駿給叫獸留下的印象。而在售的這一代奇駿,雖然外觀進行了脫胎換骨的變化,變得更加接近時尚的城市SUV了,但其優秀的越野性能還是得以保留。

外觀方面,奇駿對比同級別的對手在尺寸方面有一定的優勢,所以觀感上奇駿會顯得高大,配合上稍帶有肌肉感的線條,奇駿的外觀還是頗具霸氣的,實際上奇駿的定位只是緊湊型SUV。

奇駿的內飾採用懷抱式的設計,線條流暢柔和,十分有親和力。日產車的內飾做工在日系車裡面算是做得優秀的一個了,尤其是奇駿這種有輕度越野需求的車,做工差的話異響就會特別明顯。還有一個就是奇駿的中控屏比較小,沒有導航,但有全景影像,比較實用。

奇駿最便宜的四驅車型為2.0L的智享版,算上優惠的話,落地價估計也就二十萬出頭,性價比還是蠻突出的。最大馬力為150ps,搭載CVT變速箱,動力輸出線性,低扭有力,該發動機的日常行駛很輕快。

奇駿的前後橋有開放式差速器,能夠鎖止打滑的車輪,所以該車是有能力通過交叉軸的,同時奇駿的車身剛度不錯,最小離地間隙為210mm,接近角為17°,底盤質感沉穩,濾震效果好。綜合這些數據和表現,奇駿應對輕度的越野還是綽綽有餘的。

廣汽三菱-歐藍德

指導價:15.98-22.38萬元

三菱歐藍德之前都是以進口車的身份活躍在國內市場,二十來萬的價格,三菱的血統,進口的品質,進口版歐藍德的口碑一直不錯。而直到今年,姍姍來遲的合資歐藍德終於和我們見面,合資的歐藍德原汁原味的保留了進口歐藍德的設計,不同的是價格更加優惠了

廣汽三菱歐藍德的造型和進口版車型是高度一致的,車頭造型比進口版的舊款要開揚和順眼不少,寬大的格柵十分霸氣,只是鍍鉻的裝飾稍微偏多了。側面的造型十分修長,因為歐藍德有着4695mm的車身長度,至於車尾則比車頭要低調很多,圓潤的造型有點像旅行車的車尾。

內飾造型的變化也不大,還是熟悉的日系居家風格,最明顯的變化是中控大屏從7英寸換成了8英寸,但這個大屏比新勁炫上面那一塊真的要和諧很多,不會太突兀。配置方面有防碰撞預警和ACC,還是挺實用的。

動力方面,只有最低配採用2.0L的發動機,其餘三個配置均為2.4L+CVT的四驅車型,最大馬力192ps,認為如果買歐藍德不買四驅版本,那還不如買一台XRV了。2.4L版本的歐藍德低扭表現出色,起步有力,動力輸出平順,但畢竟車重擺在那,歐藍德不能給你很強烈的加速快感。

歐藍德採用一套適時四驅系統,有三種驅動模式供駕駛者選擇,實際測試中,交叉軸、單前輪着地的三開放式滑輪組都可以通過,只是电子系統的反應還是有點慢。歐藍德的整體越野能力值得肯定,畢竟他主要還是一輛城市SUV啊。

斯巴魯-斯巴魯XV

指導價:18.98-22.98萬元

水平對置發動機、左右對稱四驅系統,這都是斯巴魯強有力的武器,一直以來只能通過進口途徑購買的斯巴魯汽車給人感覺都是售價不便宜。而事實上斯巴魯有一款最低售價低於二十萬的SUV,那就是斯巴魯XV。對了,斯巴魯車配件都是進口的,所以維修保養的成本會相對高一點。

叫獸覺得斯巴魯XV的外觀對比常見的SUV來說稍顯另類,車身造型扁平,長度比同級對手要短,車身重心也比較低,整體的造型更加接近於跨界車。

內飾方面,斯巴魯XV的採用對稱式的布局,內飾材料主要為塑料,做工很好,接縫緊密而均勻,但新款在內飾上的變化依然不大。讓叫獸欣慰的是在配置方面,斯巴魯XV有不少的提升,如胎壓監測、發動機啟停、空調溫度分區控制等等。不過話又說回來,這些配置,自主品牌十來萬的車早就有配備了。

動力方面,斯巴魯XV搭載了2.0L的水平對置4缸發動機,最大馬力150ps,變速箱則為CVT。和大部分的日系車一樣,斯巴魯XV的動力表現並不算积極,雖然起步輕快,但後段的動力儲備明顯不足,而且CVT變速箱又不適合急加速,所以斯巴魯XV只適合安安分分的駕駛。

斯巴魯XV搭載全時四驅系統,由於水平對置發動機重心低,所以XV的行駛穩定性很好。但重心低不代表通過性差,220mm的最低離地間隙讓XV能夠輕鬆應對爛路。左右對稱四驅系統能根據行駛狀況調整前後軸的扭力分配,這就讓斯巴魯XV比普通的城市SUV擁有有更強的脫困能力了。

廣汽菲克Jeep-自由光

指導價:20.98-31.58萬元

在Jeep還是只能進口的時代,想要二十來萬買一台軸距2705mm的Jeep中型SUV那幾乎就是天方夜譚。但現在不同了,合資國產後的自由光定價親民了不少,想體驗一下Jeep的中型SUV,自由光是最佳選擇了。

國產自由光的外觀和進口自由光的外觀差別不大,第一眼看的時候甚至會覺得有點怪,但時間長了之後就會發現其實自由光的外觀設計還是挺有意思的。七孔造型的中網辨識度好高,細條狀造型的頭燈也很有時尚感,自由光的外觀設計很大膽,越看越有味道。

內飾方面,對稱式的布局,維持了進口版上的設計,實質上自由光的內飾帶有一點歐洲車的風格,簡單而有檔次感。至於用料方面又體現了美系車的大方,不會吝嗇皮質材料的使用。座椅也和美系大沙發一樣,填充厚實,舒適性出色。

自由光有2.0L和2.4L兩種排量,變速箱均為ZF的9AT,最大馬力分別是155ps和175ps,叫獸認為想體驗更加接近Jeep的駕駛感受,2.4L專業版以上帶有適時四驅系統的車型會更加合適。可惜由於車重較大,175ps的馬力也僅能夠用,市區的行駛十分溫和舒適,沒什麼爆發力可言。

廣汽菲克Jeep-自由光搭載的是入門的Active Drive I四驅系統,有不錯的燃油經濟性,四驅西東也能適當的根據路況來分配各車輪的動力。所以整體來說自由光還是有能力應對一些泥濘道路或者打滑不是十分嚴重的脫困。

總結:雖說現在國家的經濟發展相當繁榮,但路況不好的小縣城或者農村還是不在小數。購買SUV除了是因為其相對霸氣的外形以外,更好的通過性和越野性能才是最能體現它實用的地方。又是年近歲晚的時候,相信不少人都盤算着怎樣回家過年,不知道今年你們有沒有考慮開上一輛四驅SUV回去?本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

※回頭車貨運收費標準

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