是在下輸了,真正土豪的車鑰匙,你根本想象不到有多酷

鑰匙啊,啊,啊,這也太炫酷了開着這樣的車出去溜達透氣(裝X)如此炫酷,還怕妹子不上車嗎然而這些車並不是你想買就能買甚至乎有錢你也買不到貧窮限制的已經不僅僅是我的想象力因為壓根就不是你能想象的高端玩家的思維方式,腦迴路絕對不是平民玩家能夠理解的社會說:“人比人得Die,貨比貨得扔”正所謂沒有對比就沒有傷害相比“貧民”版的無鑰匙啟動系統“貧民”版那差距就是一個詞,天壤之別於“貧民”而言,這差距簡直就是不忍直視,實在有點“凄慘”而我們最常見的“無鑰匙啟動系統”原理便是不用“拿”出鑰匙便能啟動車輛值得一提的是也許

俗話說,有錢不一定會快樂

因為有錢人的快樂

。

。

。

。

。

根本不是你我能夠想象的!!

正所謂窮人玩車富人玩表

是絕對有道理的

因為一隻隨身攜帶的手錶

卻會無時無地烘托着你的身份

但是車也分3 6 9等

如何低調地開車以及優雅地炫富

成為了重中之重

平民玩家

自備一條…精緻的鑰匙

土豪玩家

不僅有一台超跑

而且還有一條酷炫的…鑰匙

啊,啊,啊,這也太炫酷了

開着這樣的車出去溜達透氣(裝X)

如此炫酷,還怕妹子不上車嗎

然而這些車並不是你想買就能買

甚至乎有錢你也買不到

貧窮限制的已經不僅僅是我的想象力

因為壓根就不是你能想象的

高端玩家的思維方式,腦迴路

絕對不是平民玩家能夠理解的

社會說:“人比人得Die,貨比貨得扔”

正所謂沒有對比就沒有傷害

相比“貧民”版的無鑰匙啟動系統

“貧民”版

那差距就是一個詞,天壤之別

於“貧民”而言,這差距

簡直就是不忍直視,實在有點“凄慘”

而我們最常見的“無鑰匙啟動系統”

原理便是不用“拿”出鑰匙便能啟動車輛

值得一提的是

也許人家買車鑰匙

就已經比你的車貴

對於而言

還是好好搬磚算了!

然而

大千世界,一切都有可能

山外有山,車外有車

啟動還得要車鑰匙也沒什麼牛X的

生活當中並不缺少大神!

現在不少車都用互聯網App啟動啦

只要手機在手,輕鬆啟動車輛

那根本都不是事兒

互聯網App版

說了那麼多,認為

其實窮並不是很可怕

可怕的是,窮的那個人是我

不過咧

貧窮雖限制了我們的想象力

但阻擋不了我追求豪車的心

。

。

。

。

。

。

。

。

別再往下拉啦,已經沒有了

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

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

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

15萬買啥車?有轎車有SUV,這2款合資車可以放心買

勁客的優勢在於成熟可靠的動力總成,採用1。5L自然吸氣發動機+CVT無級變速器的搭配能夠帶來非常平順線性的輸出,油門調校靈敏,能夠很好地應付日常市區內行駛,並且也非常省油,可靠性較高。不過其檔次感與配置水平不如哈弗H2。

15萬左右比較推薦的是本田XR-V與豐田卡羅拉,這兩款車目前在市場上都有着不錯的銷量、保值率以及口碑,XR-V在小型SUV市場混得風生水起,靠的就是其成熟的動力系統和越級的空間表現,家用是個非常棒的選擇。而卡羅拉乃全球銷量神車,中庸就是其最大的武器,除了汽油版本外還有雙擎版本可選,擁有非常優秀的燃油經濟性,能夠滿足許許多多的消費者,除了隔音濾振差點,其它方面的表現都非常不錯,乃家用車的不二之選。

一輛是接近中型車的緊湊型車,一輛是標準的中型車,凌渡280DSG豪華版擁有更加豐富的配置,不過因為其比較扁平的設計所以頭部空間表現一般,而君威中型車的身份自然擁有更大的空間以及更高的檔次感,同時全系標配9AT也讓其競爭力進一步上升,採用的1.5T發動機也有着不錯的動力輸出,因此更推薦君威1.5T中配。

510採用的是6擋手動變速器和5擋AMT變速器,假設會開手動擋的話更加推薦手動車型,6個擋位在高速行駛時把轉速壓得更低,能帶來更好的燃油經濟性,同時擁有更高的傳動效率及可靠性,510的手動擋換擋手感不錯,有吸入感並且行程不長,離合器的力度也不沉,沒那麼容易疲勞。而AMT變速器雖然說省去了踩離合器的麻煩,但是其換擋邏輯不清晰,而且頓挫比較嚴重,尤其是在起步階段或者是在堵車狀況下,因此更加推薦510的手動版車型。

兩車都是定位小型SUV,哈弗H2擁有更加親民的售價,更加大氣上檔次的外觀內飾設計,同時配置更加豐富,採用的1.5T發動機+7擋雙離合的搭配,擁有不錯的爆發力,但是雙離合變速器的邏輯有待提高,並且油耗也會偏高。

勁客的優勢在於成熟可靠的動力總成,採用1.5L自然吸氣發動機+CVT無級變速器的搭配能夠帶來非常平順線性的輸出,油門調校靈敏,能夠很好地應付日常市區內行駛,並且也非常省油,可靠性較高。不過其檔次感與配置水平不如哈弗H2。

綜上,假如你預算充足的話,更加建議購買勁客的中配以上車型,而預算不是很足的話,那麼家用選擇H2是一個非常具有性價比的選擇。

2018款飛度新增了運動套件車型,不過在配置方面還是一如既往的寒酸,比較推薦指導價為8.88萬的1.5L CVT潮跑版,在配置上面擁有主/副駕駛座安全氣囊、運動外觀套件、行車電腦显示屏、前霧燈等,類似比較常用的电子車身穩定系統、駐車雷達要到頂配才配備,但是飛度的動力和空間還是非常不錯的,1.5L自吸發動機就能爆發出131匹馬力,日常市區駕駛毫無壓力,加上本田“MM”理念,讓它的空間能夠滿足大多數人的使用需求,市面上大量的改裝件也能讓每位飛度車主把愛車改成獨一無二的樣子。

以上就是本期網友問答欄目的全部內容,假如你也想上牆的話,點擊下方留言留下你的問題並且點個贊,就有機會在下期欄目看見你的身影!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

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

「世界糧食計劃署」獲諾貝爾和平獎 致力解決糧食危機

摘錄自2020年10月11日TVBS新聞網報導

2020年諾貝爾和平獎,得主是「世界糧食計劃署」,這個隸屬聯合國組織,負責解救饑荒,是全球規模最大的人道救援團體之一;只是今年全球陸續出現疫情、天災和戰亂,聯合國秘書長古特瑞斯就說全球貧窮人口在30年內第一次增加,全球糧食安全正備受考驗。

2020年諾貝爾和平獎,給了聯合國旗下的世界糧食計劃署,挪威諾貝爾委員會指出,世糧署致力對抗飢餓問題,也為改善戰亂地區的和平做出貢獻。

只是今年不僅碰上百年大疫情,更是極端天災、蝗蟲肆虐的一年,糧食供應面臨前所未有的危機,聯合國警告,今年恐怕會有上億人餓死。

大陸長江流域,今年暴雨洪水災情不斷,讓「魚米之鄉」的南方農田泡水,小麥欠收1000萬噸,影響大陸4成人口主食。美國從今年8月以來,西岸野火延燒超過500萬英畝土地,相當於燒掉75個台北市,規模空前。

挪威諾貝爾委員會主席瑞斯.安德森:「促使我們今年選擇,讓世糧署獲獎的因素之一,是因為飢餓人口正在升高,和戰爭與衝突有關的飢餓在增加。」

循環經濟
國際新聞
聯合國
世界糧食計劃署
諾貝爾和平獎

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

【其他文章推薦】

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

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

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

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

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

※超省錢租車方案

中國特供不能買?14萬起這幾款SUV比途觀、漢蘭達更值!

98萬將空間玩到了極致本田聞名於世的除了讓人津津樂道的性能與紅頭髮動機之外,對於車內空間的營造有着極為深度的造詣也是鍾愛本田品牌的家用車車主們非常欣賞的一點品牌特性。而這一點在冠道上被發揮得淋漓盡致。當所有主機廠都在用相似的尺寸做7座SUV的時候,冠道依舊是以5座布局應對市場競爭,而也正是這5座的座椅布局讓它成為了合資品牌中型SUV陣列里後排空間鮮有對手的存在,寬敞的後排甚至可以用誇張來形容,這對於後排有着執念的中國消費者來說,冠道的乘坐空間是非常具有誘惑力的存在。

提到“中國特供”,似乎很多人對這個字眼都頗有微詞;很大一部分原因都是因為中國汽車消費市場上銷量高的車型有不少的身份是“中國特供”,而某些車型,由於技術平台較老的緣故讓部分消費者將它們扣上了一些“高價低能”的帽子。

其實特供車型是每一個成型的汽車消費市場中都存在的一個現象;例如日本的K-car,小尺寸低排量的設定與方盒子的造型,便是為了日本那寸土寸金的地方量身打造的代步工具。

又例如美國的皮卡和大尺寸、大排量的SUV以及轎車,廣袤的美利堅平原土地上的牧場主們更需要一款能載貨的車型為自己的畜牧事業運輸物料,加之他們的汽車文化發展就是讓多缸數大排量的車型唱着主調,所以美系車自然成了“大尺寸”的汽車代名詞。

所以不同品牌的特供車不過是主機廠為了可以更好的開拓一方水土,鞏固自己品牌效應的一種商業手段,其實某種情況上看,做好一款特供車並不簡單,畢竟需要花大量的時間進行市場調研和消費需求的考究,才可以做出一款能幫助主機廠在某個特定的市場環境下能帶來豐厚利潤的車型。

近年來中國市場上的特供新車越來越多,而以下這些中國特供的SUV可以說是每一台都非常值得推薦的車型,它們在不同的產品定位下保持了品牌在各自擅長領域中的優勢,極大程度的滿足了中國消費者的用車需求。

寶馬X1

指導售價:28.38-43.90萬

空間與品牌信仰為它贏得了市場

寶馬X1現如今的銷量能有個平均月銷量6000輛以上的水平,豪華品牌緊湊型SUV有這個數據已經相當不錯,而且現款的X1比奧迪Q3賣得要更好,也側面印證了它的市場效應已經成型,消費者對於這款UKL前置前驅平台下的SUV已經有了極大的包容度。

起初,UKL這三個字母幾乎讓寶馬成為了眾矢之的,認為寶馬標的汽車就不應該出現前置前驅這種喪失操控源泉的驅動形式,但其實大多數人對於寶馬的定義或許更多的是停留在寶馬的品牌效應上,其次,UKL前驅平台的寶馬X1不僅做出了比老款X1更大的尺寸,更挖掘出了相當寬敞的後排空間,讓X1的形象更接近一個買菜家用的角色定位,對於大多數人來說,這樣的寶馬X1其實更實在。

馬自達CX-4

指導售價:14.08-21.58萬

年輕人的需求得以很好的滿足

嚴格意義上說,CX-4應該是一款中國首發的SUV;這款運動風格濃郁的跨界車型讓它看上去並不像傳統意義上的SUV那般厚重,靈動的造型和飄逸的魂動設計線條讓它在年輕人心目中有着極高的認同度。

在產品力層面,CX-4保持了馬自達品牌一貫出色的操控性,雖然空間並不是強項,但是作為一般年輕家庭來說空間實用性已然足夠,而且在市場終端显示出了一個接受度非常高的售價,這讓想要購買一款高顏值SUV的年輕人看到了希望,也讓不少在轎車與SUV中找不到平衡點的消費者們有了一個十分合適的折中選擇。

冠道

指導售價:22.00-32.98萬

將空間玩到了極致

本田聞名於世的除了讓人津津樂道的性能與紅頭髮動機之外,對於車內空間的營造有着極為深度的造詣也是鍾愛本田品牌的家用車車主們非常欣賞的一點品牌特性;而這一點在冠道上被發揮得淋漓盡致。

當所有主機廠都在用相似的尺寸做7座SUV的時候,冠道依舊是以5座布局應對市場競爭,而也正是這5座的座椅布局讓它成為了合資品牌中型SUV陣列里後排空間鮮有對手的存在,寬敞的後排甚至可以用誇張來形容,這對於後排有着執念的中國消費者來說,冠道的乘坐空間是非常具有誘惑力的存在。

昂科威

指導售價:21.99-31.99萬

將豪華融進了平民層次

二十來萬要買合資SUV買出豪華質感?除了昂科威之外可能能叫得上號的車型並不多,別克品牌近年來在內飾檔次感的提升工程上可謂是下足了功夫,而昂科威這款誕生於中國返銷至美國的SUV更是如此,內飾氛圍無論是在設計或是用料層面都在同價位車型中處於上乘水準,並且擁有主動降噪技術以進一步提升昂科威在行駛狀況下的高檔質感。

將豪華融進二三十萬級別車型,這一舉措無疑是成功的,昂科威上市以後便獲得了非常可觀的銷量數據,敦實厚重的外觀設計符合大多數人對於家用SUV的認知,而實際使用體驗越級的檔次感又能讓消費者感受到相對優越的用車氛圍,也正是昂科威出色的產品力體現,所以它一直處於十分值得推薦購買的SUV名錄里。

大指揮官

指導售價:27.98-40.98萬

極大程度上滿足了國人喜好

大指揮官剛剛上市,從理性角度上說,並不應該這麼快就下定論它是一款值得推薦的車型,但是它呈現出來的市場決心非常明顯,上市之前便已經放出“我便是為中國市場而來”的消息,直擊漢蘭達,銳界,途昂的細分定位。

大指揮官的產品力幾乎滿足了國人對於一款35萬左右能買到的合資SUV應該呈現出來的產品力該有的認知:接近5米的車長,魁梧的身軀,平實近人的外觀設計,7座的布局,以及幾乎全面的配置水平,這些都符合一个中國家庭用戶對於中型SUV的嚴苛需求,起碼從產品力上看,大指揮官交出的答卷絕對值高分。

結語:就普通消費者而言,一輛車是否特供並不是衡量這輛車好與壞的標準;而是要看綜合產品力的體現是否符合它所特供的市場環境;中國汽車市場對於SUV的空間與配置需求看得更重,而對動力、操控等机械品質的要求所佔比重則要低於前者。

以上車型除了馬自達CX-4是一款更講究操控性能的SUV以外,其餘車型幾乎都是將空間與配置放在了車型研發時的首位,從關注度和銷量上看,這些車型無疑是成功的代表;所以特供車不值得買嗎?我看未必。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

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

7萬塊就能買到的合資家轎,還是自動擋,這3款車靠譜嗎?

由圖表數據我們可以看出賽歐的後排座墊比較長,因而支持性及舒適性會好過其他兩車。瑞納則是中規中矩,表現還不錯。汽車當然不止滿足自己的駕駛慾望,還要考慮家人的乘坐體驗,在看來,這三輛車在空間的表現上是合格的。

不知道你是否有這樣一種感覺,“如果我有一輛車,那麼我將得到整個世界。”雖然是自我感覺良好,但不可否認的是擁有一輛車真的帶給我們很多的便利,至少讓我們打破距離的阻礙,去到我們想去的地方。有了車,自信心是爆棚的,就看到過一個沉默寡言的人買車之後整天開着他那輛奧拓在小區裏面晃來晃去。

買車的好處多,但是在動輒10萬以上的汽車市場面前,不少人看了一眼自己的存摺,默默地把它放回原處;仍然有一部分迫切買車但是預算不夠的人把目光放在了10萬以下的汽車市場,那麼一起跟來看看這幾款比較多人選擇的低價位合資車是否值得選擇。

辣評:很多選擇瑞納的車主不僅是因為瑞納有着超低的價格(乞丐版裸車5萬左右),比較重要的一點是它有着耐看的顏值,車頭微微向下傾斜,呈一個低趴的狀態,外觀上有着超出這個價位的設計。畢竟價格擺在那裡,瑞納的內飾塑料感比較強,但是看上去不會顯得老氣,以簡約的風格為主。“皮薄”是很多人對瑞納的質疑,這個價位日韓車確實沒有國產車用料讓人放心,想說的是任何時候都要遵守交通規則,沒有任何車是絕對安全的。

辣評:賽歐也是中國人的老朋友了,現在街上還看到兩廂版的賽歐,小巧可愛。我們今天要介紹的是三廂版的賽歐,外觀上雪佛蘭家族的辨識度挺高的。內飾同樣的簡潔,比較奇葩的一點是賽歐的車窗升降按鍵設置在了中控下的位置,使用起來不是那麼方便。不過相對於其較低的價格及油耗,這點小瑕疵也就算不得什麼了吧。

辣評:近幾年威馳的銷量和口碑都還不錯,如果你有8萬的預算的話推薦買威馳,除了外觀沒有其他兩車好看外,威馳全系都標配了車身穩定系統,安全性能有了不小的提升,加之日系車是省油的典範,威馳在油耗上不會讓人失望。

雖然價格低,但是在乘坐空間上比較符合心意。三車在乘坐空間上差異並不是很大,只不過威馳後排頭部空間上會有劣勢,還好威馳後排中間地板是全平的,對於坐中間的人來說絕對是福音;由圖表數據我們可以看出賽歐的後排座墊比較長,因而支持性及舒適性會好過其他兩車;瑞納則是中規中矩,表現還不錯。汽車當然不止滿足自己的駕駛慾望,還要考慮家人的乘坐體驗,在看來,這三輛車在空間的表現上是合格的。

7萬左右的價格入手一輛合資車,對於配置就不要抱有太大的期望了,不過一些安全配置必須得有。威馳比較有誠意,全系都標配了車身穩定系統,CVT銳行版上坡輔助、剎車輔助這些功能都有;同樣的價位,賽歐已經可以買到頂配版本-幸福天窗版了,雖然沒有配置車身穩定系統,但是前排側氣囊讓人放心;就7萬這個價格來說,瑞納同樣可以上頂配了,盤式后制動器比另外兩車都要有誠意,同樣帶有前排側氣囊,車身穩定系統,總算在安全配置上扳回一城。

油耗一直是車主比較擔心的問題,一輛車油耗低的話,在日常養車中能夠省下一大筆錢。三車的平均油耗都在7L/100Km左右,當然不同路況會有不同的油耗,跑高速的話油耗會更低。

除了配置和油耗令人滿意之外,這三輛車低廉的價格是讓很多預算不多的人心動的主要原因。賽歐的價格已經下探到了4.7萬左右,瑞納的價格已經低的不能再低了,所以目前沒有優惠,就連銷售勢頭良好的威馳都有一萬左右的優惠,可見這個價位競爭的激烈,對於想買車人士來說是個好消息。

一直沒有提到動力是因為認為在這個價位,絕大多數車子在動力上表現都不怎麼樣,滿足家用足以,起碼高速超車是可以做到的。如果你迫切地希望擁有一輛車,在預算不是很多的情況下,這些車都可以在考慮的範圍內,況且7萬左右的價格就可以提自動擋車型,操控難度下降了不少。特別是對於新手司機,人生中第一輛車用來磨鍊一下自己的駕駛技術,無疑是很好的選擇。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

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

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

有的帥爆有的超級靠譜,買這3款不到20萬的SUV,大家都說好

5L兩款自然吸氣發動機,匹配的是SKYAMC-drive6AT變速箱,換擋快速,而且動力輸出比較線性,動力跟腳,運動感強。而指南者搭載的1。4T和2。4L兩款發動機,其中1。4T車型使用了Mutil-air技術,可以精確把控節氣門開關角度與時間,進而保證動力的輸出性,另外還加持四驅技術,可應對不時之需。

現今市面上琳琅滿目的SUV車型,不僅性格多種多樣,連用途也是不盡相同,操控運動、日常家用、越野叢林,只要你敢想,就有SUV可以滿足你。

今天,就為此刻在閱覽這篇文章的你,各推薦一款車型,滿足你的三個小願望!

馬自達CX-4的外觀採用了魂動設計理念,整個車身扁平化,線條流暢動感看起來非常舒服,運動氣息十足,由車燈延伸至鍍鉻進氣格柵處形成的翼式形態和車標形成相互呼應,非常的有格調;

指南者車身線條較為硬朗,七孔式進氣格柵非常地有張力,整個造型時尚當中富含陽剛硬朗之氣;

V-motion設計形態下的奇駿,車身線條凌厲,不僅層次感展現得非常好,還很有視覺衝擊力,進氣格柵側的鍍鉻飾條也異常吸睛。

馬自達CX-4的內飾採用了既時尚又有科技感的懸浮式中控屏幕,整個內飾就是馬自達家族風格,無論是用料還是做工,手感都非常的不錯,高配車型座椅還採用了意大利進口的皮質材料,舒適感非常好。指南者的內飾偏向於硬漢形象但又不失年輕人的個性,內飾線條和布局都較為簡潔,沒有什麼花哨和特別之處,主要還是以實用性為主。奇駿的內飾延續了外觀的V-motion設計風格,特色性很足,簡單當中透露出了清爽,細膩的做工用料,靈動飄逸的線條也帶來不錯的觸感體驗和視覺享受。

空間上礙於三款車都是緊湊型SUV,比起中型的SUV來說小了不少,但還是夠用,170cm的測試者坐進後排腿部空間仍有兩拳+盈餘,寬敞度還是不錯的。而主打運動和操控的CX-4也沒有因為車身的設計大幅度壓縮空間,乘坐空間仍然比較可觀,就是後排頭部空間要稍微局促了些。

此次推薦的都是銷量較多的車型,其中馬自達推薦車型CX-4的指導價為15.28萬,像LED大燈、主動安全配置等各方面的配置都還行,綜合性價比不錯,就是舒適性欠佳,對於預算充足的車主們可選擇中高配車型。至於指南者和奇駿選擇的就都是中高配車型,电子設備、配置要齊全很多,滿足日常需要是沒有問題的。

動力方面CX-4搭載2.0L和2.5L兩款自然吸氣發動機,匹配的是SKYAMC-drive6AT變速箱,換擋快速,而且動力輸出比較線性,動力跟腳,運動感強;而指南者搭載的1.4T和2.4L兩款發動機,其中1.4T車型使用了Mutil-air技術,可以精確把控節氣門開關角度與時間,進而保證動力的輸出性,另外還加持四驅技術,可應對不時之需;奇駿搭載的是2.0L和2.5L發動機,除了低配車型使用的是6MT變速箱,其餘車型用的都是模擬7擋CVT變速箱,其中2.0L發動機採用了缸內直噴技術,動力輸出比較線性,在低扭矩時也並不乏力。

結語:

總的來說,三款車的性格區別還是比較明顯的,CX-4偏向於操控和運動;而指南者就有點兼具越野性和家用,適合想偶爾出去叢林山地撒撒歡又可家用的朋友;至於奇駿嘛,就更適合城市通行,畢竟家用屬性爆棚。若要推薦車型,就推薦馬自達CX-42018款 2.0L自動兩驅藍天活力版、廣汽菲克Jeep指南者2017款 200T 自動家享版以及東風日產奇駿2017款 2.0L CVT舒適版。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

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

※超省錢租車方案

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

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

這款月銷2萬輛的自主精品SUV,車主們是如何評價的?

再來看它的動力表現,搭載的是最大馬力為156ps的1。5T渦輪增壓發動機,匹配6MT或6AT變速箱,低扭表現良好,跑起來給人的感覺是比較輕快的,特別是來自愛信的6AT變速箱換擋平順、邏輯清晰。值得表揚的還有它對於底盤的調校繼承了長安一貫的好功底,有一種不錯的緊緻感,在保證一定舒適性的同時能兼顧到支撐性,方向盤的力度也適中。

在競爭異常激烈的緊湊型SUV陣營中,有一款國產SUV自上市以來銷量就一路攀升,現今的銷量能保持每月1-2萬輛的好成績。

那麼它到底有哪些吸引消費者的魔力呢?各位已經購車的車主們又是怎麼評價的?想知道答案的話就繼續往下看吧:

對於外觀的評分,我認為車主打得並不低,長安CS55的前臉造型看起來比較敦實、有力量感,扁平的前進氣格柵與前大燈採用了一體化設計,格柵使用粗體的“CNANGAN”字樣辨識度很高。車身側麵線條比例協調,B、D柱採用隱藏式設計,讓車頂有一種懸浮的效果,但側面被不少人說看到路虎的影子。

總之外觀見仁見智,我們接着說內飾:

有值得點贊的方面,比如中控台的按鍵布局比較規整,紅黑線條的搭配凸顯運動感,但是用料中規中矩,而且車內異味也略大。同時那塊8英寸的中控屏的設計被吐槽有點雪佛蘭旗下車型的影子。

作為一款家用SUV,空間是消費者比較注重的方面,而長安CS55在這方面的表現還是不負眾望的:

身高為178cm的體驗者在駕駛座上調整好座椅可獲得4指的頭部空間,來到後排頭部空間剩餘3指、腿部空間超過兩拳,並且中央地板隆起度不大,可以給中間乘客提供還算不錯的舒適性,另外後備廂的容量一般但車內儲物格的儲物能力絕對會給你驚喜,日常家用基本是不用擔心的。

再來看它的動力表現,搭載的是最大馬力為156ps的1.5T渦輪增壓發動機,匹配6MT或6AT變速箱,低扭表現良好,跑起來給人的感覺是比較輕快的,特別是來自愛信的6AT變速箱換擋平順、邏輯清晰。

值得表揚的還有它對於底盤的調校繼承了長安一貫的好功底,有一種不錯的緊緻感,在保證一定舒適性的同時能兼顧到支撐性,方向盤的力度也適中。但是美中不足的是發動機的噪音有點大,而且油耗也不是特別理想,畢竟1.5噸的車重擺在那。

它的主要競品車型有同樣大賣的自主緊湊型SUV傳祺GS4:

結語:綜合來看,空間大、動力足是長安CS55能獲得廣大車主滿意的關鍵特點,同時底盤有韌性、操控性還算不錯也能討得車主的歡喜。當然車無完車,內飾與油耗方面還有待提升的空間,不過這份成績已經是屬於自主品牌緊湊型SUV里偏上等水平了,你怎麼看呢?歡迎留言告訴我們喲!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

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

※超省錢租車方案

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

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

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

開這款四門轎車,想不被關注都難,奔馳寶馬都得繞道

並不是誰都能觸手可及瑪莎拉蒂Ghibli是特別的它的發展並不存在“延續”曾經的它是跑車雙門兩座跑車和雙門四座跑車分別都是它的前身可是今天的它不再是一款跑車它僅僅是在不同的歷史階段扮演不同的角色它有着一顆3。0T V6的心臟最大馬力350pS最大扭矩500N·m匹配8AT變速箱如果以跑車,甚至超跑的水準去衡量它的動力這還是嫩了一點4門5座的三廂設計讓它顯得更居家儘管它帶有跑車的基

拉風的外觀

奢華的內飾

澎湃的動力

精準的操控

具備這些因素的一定是超跑?

不!也有可能是瑪莎拉蒂Ghibli

極具藝術感的外觀造型

分分鐘能讓你在鬧市中成為焦點

內飾設計舒適、豪華

還有各種真皮面料、高檔木飾等配飾供你選裝

就連車漆顏色、輪轂、剎車卡鉗、音響等配置都可以選配

讓你打造出獨一無二的專屬座駕

正因為它是如此獨特

彷彿時刻都在訴說“生人勿近”

畢竟它的身價

……

並不是誰都能觸手可及

瑪莎拉蒂Ghibli是特別的

它的發展並不存在“延續”

曾經的它是跑車

雙門兩座跑車和雙門四座跑車分別都是它的前身

可是今天的它不再是一款跑車

它僅僅是在不同的歷史階段扮演不同的角色

它有着一顆3.0T V6的心臟

最大馬力350pS

最大扭矩500N·m

匹配8AT變速箱

如果以跑車,甚至超跑的水準去衡量它的動力

這還是嫩了一點

4門5座的三廂設計讓它顯得更居家

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

【其他文章推薦】

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

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

※回頭車貨運收費標準

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

※超省錢租車方案

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

這3台不到20萬的中型車,讓開邁騰的年輕人羡慕到想賣車

阿特茲,雖然是一大堆的優點,但都是針對駕駛者而設計的,因此乘客的乘坐體驗就一般了,加上在風噪胎躁方面的控制不是很好,整體的乘坐質感並不高,如果是想給家人更多的舒適體驗,那還是再考慮考慮吧。蒙迪歐,綜合實力很平均,然而在這個價位購車的朋友們多多少少會考慮到油耗這個問題,雖然蒙迪歐的動力數據很好,但在強大動力的加持下,油耗的表現確實是偏高。

今天,跟大家嘮嘮幾款打着運動旗號的中型車,它們分別是:阿特茲,蒙迪歐以及思鉑睿,一看到這幾款車,大家都知道,這些車都有一個通病,就是銷量不高~

其中,蒙迪歐在2017的全年的銷量為:112158台,阿特茲則是:53493台,思鉑睿最少,才19277台,換個說法,這三款車每個月的銷量都是不會破萬的,它們的小眾程度可見一般。

三車外觀如何?

阿特茲自不必說,採用了“魂動”設計語言的它不負“ATENZA”這個寓意為萬眾矚目的稱號。

蒙迪歐,大多朋友戲稱為“小馬丁”的存在,當然,此馬丁非天才DJ Martin Garrix,而是汽車界的紳士-阿斯頓·馬丁,雖然嚴謹的說,它們沒什麼關係,但是蒙迪歐的運動外觀卻是不爭的事實。

思鉑睿,低矮的車身,兇悍的前進氣格柵,這都是它為了區別於傳統舒適性中型車的外觀而設計的。

既然是主打運動,那麼動力是必不可少的較量了

通過三台車的動力系統對比,蒙迪歐在總體上比其它兩款車的動力更加好,畢竟渦輪增壓在這裏佔得便宜不小,但是論起操控,號稱東瀛寶馬的馬自達是三車之中最好的,而屬於買發動機送車殼的本田思鉑睿在這三款車中,發動機與變速箱的匹配程度是最高的。

那麼,運動型車能家用嗎?

在這之前,給大家看看三車的後排空間數據,大家就明白是咋回事了。

阿特茲空間數據

蒙迪歐空間數據

思鉑睿空間數據

通過對比看出,其實三款車型均為中型轎車,在空間方面也不要過於擔心,就算再不濟也是足夠正常使用。

三車的配置上,哪個更優?

給大家帶來的是三款車在相近價位的配置對比,通過對比看出阿特茲的配置更加豐富一點,也更加符合國人買車時“配置豐富”的需求,所以阿特茲在配置對比方面優勢不小。

說了這麼多,這些車都沒有缺點嗎?

當然不是,為你一一道來。

阿特茲,雖然是一大堆的優點,但都是針對駕駛者而設計的,因此乘客的乘坐體驗就一般了,加上在風噪胎躁方面的控制不是很好,整體的乘坐質感並不高,如果是想給家人更多的舒適體驗,那還是再考慮考慮吧。

蒙迪歐,綜合實力很平均,然而在這個價位購車的朋友們多多少少會考慮到油耗這個問題,雖然蒙迪歐的動力數據很好,但在強大動力的加持下,油耗的表現確實是偏高。

思鉑睿,說句老實話,它的裝配水平在這麼多的車之中只能算是一般,而且車內各處的異響也不少,但好在整體的行駛質感做得不錯,在保證一定運動格調的情況下還能兼顧到家庭所需。

對於這三款車型而言,其實取捨也很簡單,假如你是一名極致的操控愛好者,那麼阿特茲絕對可以滿足到你,而針對於蒙迪歐和思鉑睿而言,雖然同樣定位在運動型中級車上,但是它們依然保持着很不錯的舒適性能兼顧到家庭所需,更適合那些以家庭出行為主但又對操控有所要求的朋友。

那麼這幾款車,哪個配置的最值得入手呢?阿特茲,選擇2.5L藍天運動版性價比是最高的,在保證足夠的動力的前提下配置也足夠我們日常所需;而蒙迪歐則可以考慮到1.5T的時尚型,動力能滿足日常所需而且在配置上也能滿足需求;最後輪到思鉑睿,雖然2.4L版本更值得推薦,而且已經自帶了原來的SI運動包圍,但據消息稱2.4L版本已經開始停產,而作為主銷車型的實則為2.0L的低排量版本以及混動版本,而更推薦考慮混動版本。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

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

※回頭車貨運收費標準

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

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

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

深度解密 Go 語言之 sync.map

工作中,經常會碰到併發讀寫 map 而造成 panic 的情況,為什麼在併發讀寫的時候,會 panic 呢?因為在併發讀寫的情況下,map 里的數據會被寫亂,之後就是 Garbage in, garbage out,還不如直接 panic 了。

目錄

  • 是什麼
  • 有什麼用
  • 如何使用
  • 源碼分析
    • 數據結構
    • Store
    • Load
    • Delete
    • LoadOrStore
    • Range
  • 其他
  • 總結
  • 參考資料

是什麼

Go 語言原生 map 並不是線程安全的,對它進行併發讀寫操作的時候,需要加鎖。而 sync.map 則是一種併發安全的 map,在 Go 1.9 引入。

sync.map 是線程安全的,讀取,插入,刪除也都保持着常數級的時間複雜度。
sync.map 的零值是有效的,並且零值是一個空的 map。在第一次使用之後,不允許被拷貝。

有什麼用

一般情況下解決併發讀寫 map 的思路是加一把大鎖,或者把一個 map 分成若干個小 map,對 key 進行哈希,只操作相應的小 map。前者鎖的粒度比較大,影響效率;後者實現起來比較複雜,容易出錯。

而使用 sync.map 之後,對 map 的讀寫,不需要加鎖。並且它通過空間換時間的方式,使用 read 和 dirty 兩個 map 來進行讀寫分離,降低鎖時間來提高效率。

如何使用

使用非常簡單,和普通 map 相比,僅遍歷的方式略有區別:

package main

import (
	"fmt"
	"sync"
)

func main()  {
	var m sync.Map
	// 1. 寫入
	m.Store("qcrao", 18)
	m.Store("stefno", 20)

	// 2. 讀取
	age, _ := m.Load("qcrao")
	fmt.Println(age.(int))

	// 3. 遍歷
	m.Range(func(key, value interface{}) bool {
		name := key.(string)
		age := value.(int)
		fmt.Println(name, age)
		return true
	})

	// 4. 刪除
	m.Delete("qcrao")
	age, ok := m.Load("qcrao")
	fmt.Println(age, ok)

	// 5. 讀取或寫入
	m.LoadOrStore("stefno", 100)
	age, _ = m.Load("stefno")
	fmt.Println(age)
}

第 1 步,寫入兩個 k-v 對;

第 2 步,使用 Load 方法讀取其中的一個 key;

第 3 步,遍歷所有的 k-v 對,並打印出來;

第 4 步,刪除其中的一個 key,再讀這個 key,得到的就是 nil;

第 5 步,使用 LoadOrStore,嘗試讀取或寫入 “Stefno”,因為這個 key 已經存在,因此寫入不成功,並且讀出原值。

程序輸出:

18
stefno 20
qcrao 18
<nil> false
20

sync.map 適用於讀多寫少的場景。對於寫多的場景,會導致 read map 緩存失效,需要加鎖,導致衝突變多;而且由於未命中 read map 次數過多,導致 dirty map 提升為 read map,這是一個 O(N) 的操作,會進一步降低性能。

源碼分析

數據結構

先來看下 map 的數據結構。去掉大段的註釋后:

type Map struct {
	mu Mutex
	read atomic.Value // readOnly
	dirty map[interface{}]*entry
	misses int
}

互斥量 mu 保護 read 和 dirty。

read 是 atomic.Value 類型,可以併發地讀。但如果需要更新 read,則需要加鎖保護。對於 read 中存儲的 entry 字段,可能會被併發地 CAS 更新。但是如果要更新一個之前已被刪除的 entry,則需要先將其狀態從 expunged 改為 nil,再拷貝到 dirty 中,然後再更新。

dirty 是一個非線程安全的原始 map。包含新寫入的 key,並且包含 read 中的所有未被刪除的 key。這樣,可以快速地將 dirty 提升為 read 對外提供服務。如果 dirty 為 nil,那麼下一次寫入時,會新建一個新的 dirty,這個初始的 dirty 是 read 的一個拷貝,但除掉了其中已被刪除的 key。

每當從 read 中讀取失敗,都會將 misses 的計數值加 1,當加到一定閾值以後,需要將 dirty 提升為 read,以期減少 miss 的情形。

read map 和 dirty map 的存儲方式是不一致的。
前者使用 atomic.Value,後者只是單純的使用 map。
原因是 read map 使用 lock free 操作,必須保證 load/store 的原子性;而 dirty map 的 load+store 操作是由 lock(就是 mu)來保護的。

真正存儲 key/value 的是 read 和 dirty 字段。read 使用 atomic.Value,這是 lock-free 的基礎,保證 load/store 的原子性。dirty 則直接用了一個原始的 map,對於它的 load/store 操作需要加鎖。

read 字段里實際上是存儲的是:

// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {
	m       map[interface{}]*entry
	amended bool // true if the dirty map contains some key not in m.
}

注意到 read 和 dirty 里存儲的東西都包含 entry,來看一下:

type entry struct {
	p unsafe.Pointer // *interface{}
}

很簡單,它是一個指針,指向 value。看來,read 和 dirty 各自維護一套 key,key 指向的都是同一個 value。也就是說,只要修改了這個 entry,對 read 和 dirty 都是可見的。這個指針的狀態有三種:

當 p == nil 時,說明這個鍵值對已被刪除,並且 m.dirty == nil,或 m.dirty[k] 指向該 entry。

當 p == expunged 時,說明這條鍵值對已被刪除,並且 m.dirty != nil,且 m.dirty 中沒有這個 key。

其他情況,p 指向一個正常的值,表示實際 interface{} 的地址,並且被記錄在 m.read.m[key] 中。如果這時 m.dirty 不為 nil,那麼它也被記錄在 m.dirty[key] 中。兩者實際上指向的是同一個值。

當刪除 key 時,並不實際刪除。一個 entry 可以通過原子地(CAS 操作)設置 p 為 nil 被刪除。如果之後創建 m.dirty,nil 又會被原子地設置為 expunged,且不會拷貝到 dirty 中。

如果 p 不為 expunged,和 entry 相關聯的這個 value 可以被原子地更新;如果 p == expunged,那麼僅當它初次被設置到 m.dirty 之後,才可以被更新。

整體用一張圖來表示:

Store

先來看 expunged:

var expunged = unsafe.Pointer(new(interface{}))

它是一個指向任意類型的指針,用來標記從 dirty map 中刪除的 entry。

// Store sets the value for a key.
func (m *Map) Store(key, value interface{}) {
	// 如果 read map 中存在該 key  則嘗試直接更改(由於修改的是 entry 內部的 pointer,因此 dirty map 也可見)
	read, _ := m.read.Load().(readOnly)
	if e, ok := read.m[key]; ok && e.tryStore(&value) {
		return
	}

	m.mu.Lock()
	read, _ = m.read.Load().(readOnly)
	if e, ok := read.m[key]; ok {
		if e.unexpungeLocked() {
			// 如果 read map 中存在該 key,但 p == expunged,則說明 m.dirty != nil 並且 m.dirty 中不存在該 key 值 此時:
			//    a. 將 p 的狀態由 expunged  更改為 nil
			//    b. dirty map 插入 key
			m.dirty[key] = e
		}
		// 更新 entry.p = value (read map 和 dirty map 指向同一個 entry)
		e.storeLocked(&value)
	} else if e, ok := m.dirty[key]; ok {
		// 如果 read map 中不存在該 key,但 dirty map 中存在該 key,直接寫入更新 entry(read map 中仍然沒有這個 key)
		e.storeLocked(&value)
	} else {
		// 如果 read map 和 dirty map 中都不存在該 key,則:
		//	  a. 如果 dirty map 為空,則需要創建 dirty map,並從 read map 中拷貝未刪除的元素到新創建的 dirty map
		//    b. 更新 amended 字段,標識 dirty map 中存在 read map 中沒有的 key
		//    c. 將 kv 寫入 dirty map 中,read 不變
		if !read.amended {
		    // 到這裏就意味着,當前的 key 是第一次被加到 dirty map 中。
			// store 之前先判斷一下 dirty map 是否為空,如果為空,就把 read map 淺拷貝一次。
			m.dirtyLocked()
			m.read.Store(readOnly{m: read.m, amended: true})
		}
		// 寫入新 key,在 dirty 中存儲 value
		m.dirty[key] = newEntry(value)
	}
	m.mu.Unlock()
}

整體流程:

  1. 如果在 read 里能夠找到待存儲的 key,並且對應的 entry 的 p 值不為 expunged,也就是沒被刪除時,直接更新對應的 entry 即可。
  2. 第一步沒有成功:要麼 read 中沒有這個 key,要麼 key 被標記為刪除。則先加鎖,再進行後續的操作。
  3. 再次在 read 中查找是否存在這個 key,也就是 double check 一下,這也是 lock-free 編程里的常見套路。如果 read 中存在該 key,但 p == expunged,說明 m.dirty != nil 並且 m.dirty 中不存在該 key 值 此時: a. 將 p 的狀態由 expunged 更改為 nil;b. dirty map 插入 key。然後,直接更新對應的 value。
  4. 如果 read 中沒有此 key,那就查看 dirty 中是否有此 key,如果有,則直接更新對應的 value,這時 read 中還是沒有此 key。
  5. 最後一步,如果 read 和 dirty 中都不存在該 key,則:a. 如果 dirty 為空,則需要創建 dirty,並從 read 中拷貝未被刪除的元素;b. 更新 amended 字段,標識 dirty map 中存在 read map 中沒有的 key;c. 將 k-v 寫入 dirty map 中,read.m 不變。最後,更新此 key 對應的 value。

再來看一些子函數:

// 如果 entry 沒被刪,tryStore 存儲值到 entry 中。如果 p == expunged,即 entry 被刪,那麼返回 false。
func (e *entry) tryStore(i *interface{}) bool {
	for {
		p := atomic.LoadPointer(&e.p)
		if p == expunged {
			return false
		}
		if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) {
			return true
		}
	}
}

tryStore 在 Store 函數最開始的時候就會調用,是比較常見的 for 循環加 CAS 操作,嘗試更新 entry,讓 p 指向新的值。

unexpungeLocked 函數確保了 entry 沒有被標記成已被清除:

// unexpungeLocked 函數確保了 entry 沒有被標記成已被清除。
// 如果 entry 先前被清除過了,那麼在 mutex 解鎖之前,它一定要被加入到 dirty map 中
func (e *entry) unexpungeLocked() (wasExpunged bool) {
	return atomic.CompareAndSwapPointer(&e.p, expunged, nil)
}

Load

func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
	read, _ := m.read.Load().(readOnly)
	e, ok := read.m[key]
	// 如果沒在 read 中找到,並且 amended 為 true,即 dirty 中存在 read 中沒有的 key
	if !ok && read.amended {
		m.mu.Lock() // dirty map 不是線程安全的,所以需要加上互斥鎖
		// double check。避免在上鎖的過程中 dirty map 提升為 read map。
		read, _ = m.read.Load().(readOnly)
		e, ok = read.m[key]
		// 仍然沒有在 read 中找到這個 key,並且 amended 為 true
		if !ok && read.amended {
			e, ok = m.dirty[key] // 從 dirty 中找
			// 不管 dirty 中有沒有找到,都要"記一筆",因為在 dirty 提升為 read 之前,都會進入這條路徑
			m.missLocked()
		}
		m.mu.Unlock()
	}
	if !ok { // 如果沒找到,返回空,false
		return nil, false
	}
	return e.load()
}

處理路徑分為 fast path 和 slow path,整體流程如下:

  1. 首先是 fast path,直接在 read 中找,如果找到了直接調用 entry 的 load 方法,取出其中的值。
  2. 如果 read 中沒有這個 key,且 amended 為 fase,說明 dirty 為空,那直接返回 空和 false。
  3. 如果 read 中沒有這個 key,且 amended 為 true,說明 dirty 中可能存在我們要找的 key。當然要先上鎖,再嘗試去 dirty 中查找。在這之前,仍然有一個 double check 的操作。若還是沒有在 read 中找到,那麼就從 dirty 中找。不管 dirty 中有沒有找到,都要”記一筆”,因為在 dirty 被提升為 read 之前,都會進入這條路徑

這裏主要看下 missLocked 的函數的實現:

func (m *Map) missLocked() {
	m.misses++
	if m.misses < len(m.dirty) {
		return
	}
	// dirty map 晉陞
	m.read.Store(readOnly{m: m.dirty})
	m.dirty = nil
	m.misses = 0
}

直接將 misses 的值加 1,表示一次未命中,如果 misses 值小於 m.dirty 的長度,就直接返回。否則,將 m.dirty 晉陞為 read,並清空 dirty,清空 misses 計數值。這樣,之前一段時間新加入的 key 都會進入到 read 中,從而能夠提升 read 的命中率。

再來看下 entry 的 load 方法:

func (e *entry) load() (value interface{}, ok bool) {
	p := atomic.LoadPointer(&e.p)
	if p == nil || p == expunged {
		return nil, false
	}
	return *(*interface{})(p), true
}

對於 nil 和 expunged 狀態的 entry,直接返回 ok=false;否則,將 p 轉成 interface{} 返回。

Delete

// Delete deletes the value for a key.
func (m *Map) Delete(key interface{}) {
	read, _ := m.read.Load().(readOnly)
	e, ok := read.m[key]
	// 如果 read 中沒有這個 key,且 dirty map 不為空
	if !ok && read.amended {
		m.mu.Lock()
		read, _ = m.read.Load().(readOnly)
		e, ok = read.m[key]
		if !ok && read.amended {
			delete(m.dirty, key) // 直接從 dirty 中刪除這個 key
		}
		m.mu.Unlock()
	}
	if ok {
		e.delete() // 如果在 read 中找到了這個 key,將 p 置為 nil
	}
}

可以看到,基本套路還是和 Load,Store 類似,都是先從 read 里查是否有這個 key,如果有則執行 entry.delete 方法,將 p 置為 nil,這樣 read 和 dirty 都能看到這個變化。

如果沒在 read 中找到這個 key,並且 dirty 不為空,那麼就要操作 dirty 了,操作之前,還是要先上鎖。然後進行 double check,如果仍然沒有在 read 里找到此 key,則從 dirty 中刪掉這個 key。但不是真正地從 dirty 中刪除,而是更新 entry 的狀態。

來看下 entry.delete 方法:

func (e *entry) delete() (hadValue bool) {
	for {
		p := atomic.LoadPointer(&e.p)
		if p == nil || p == expunged {
			return false
		}
		if atomic.CompareAndSwapPointer(&e.p, p, nil) {
			return true
		}
	}
}

它真正做的事情是將正常狀態(指向一個 interface{})的 p 設置成 nil。沒有設置成 expunged 的原因是,當 p 為 expunged 時,表示它已經不在 dirty 中了。這是 p 的狀態機決定的,在 tryExpungeLocked 函數中,會將 nil 原子地設置成 expunged。

tryExpungeLocked 是在新創建 dirty 時調用的,會將已被刪除的 entry.p 從 nil 改成 expunged,這個 entry 就不會寫入 dirty 了。

func (e *entry) tryExpungeLocked() (isExpunged bool) {
	p := atomic.LoadPointer(&e.p)
	for p == nil {
		// 如果原來是 nil,說明原 key 已被刪除,則將其轉為 expunged。
		if atomic.CompareAndSwapPointer(&e.p, nil, expunged) {
			return true
		}
		p = atomic.LoadPointer(&e.p)
	}
	return p == expunged
}

注意到如果 key 同時存在於 read 和 dirty 中時,刪除只是做了一個標記,將 p 置為 nil;而如果僅在 dirty 中含有這個 key 時,會直接刪除這個 key。原因在於,若兩者都存在這個 key,僅做標記刪除,可以在下次查找這個 key 時,命中 read,提升效率。若只有在 dirty 中存在時,read 起不到“緩存”的作用,直接刪除。

LoadOrStore

這個函數結合了 Load 和 Store 的功能,如果 map 中存在這個 key,那麼返回這個 key 對應的 value;否則,將 key-value 存入 map。這在需要先執行 Load 查看某個 key 是否存在,之後再更新此 key 對應的 value 時很有效,因為 LoadOrStore 可以併發執行。

具體的過程不再一一分析了,可參考 Load 和 Store 的源碼分析。

Range

Range 的參數是一個函數:

f func(key, value interface{}) bool

由使用者提供實現,Range 將遍歷調用時刻 map 中的所有 k-v 對,將它們傳給 f 函數,如果 f 返回 false,將停止遍歷。

func (m *Map) Range(f func(key, value interface{}) bool) {
	read, _ := m.read.Load().(readOnly)
	if read.amended {
		m.mu.Lock()
		read, _ = m.read.Load().(readOnly)
		if read.amended {
			read = readOnly{m: m.dirty}
			m.read.Store(read)
			m.dirty = nil
			m.misses = 0
		}
		m.mu.Unlock()
	}

	for k, e := range read.m {
		v, ok := e.load()
		if !ok {
			continue
		}
		if !f(k, v) {
			break
		}
	}
}

當 amended 為 true 時,說明 dirty 中含有 read 中沒有的 key,因為 Range 會遍歷所有的 key,是一個 O(n) 操作。將 dirty 提升為 read,會將開銷分攤開來,所以這裏直接就提升了。

之後,遍歷 read,取出 entry 中的值,調用 f(k, v)。

其他

關於為何 sync.map 沒有 Len 方法,參考資料里給出了 issue,bcmills 認為對於併發的數據結構和非併發的數據結構並不一定要有相同的方法。例如,map 有 Len 方法,sync.map 卻不一定要有。就像 sync.map 有 LoadOrStore 方法,map 就沒有一樣。

有些實現增加了一個計數器,並原子地增加或減少它,以此來表示 sync.map 中元素的個數。但 bcmills 提出這會引入競爭:atomic 並不是 contention-free 的,它只是把競爭下沉到了 CPU 層級。這會給其他不需要 Len 方法的場景帶來負擔。

總結

  1. sync.map 是線程安全的,讀取,插入,刪除也都保持着常數級的時間複雜度。

  2. 通過讀寫分離,降低鎖時間來提高效率,適用於讀多寫少的場景。

  3. Range 操作需要提供一個函數,參數是 k,v,返回值是一個布爾值:f func(key, value interface{}) bool。

  4. 調用 Load 或 LoadOrStore 函數時,如果在 read 中沒有找到 key,則會將 misses 值原子地增加 1,當 misses 增加到和 dirty 的長度相等時,會將 dirty 提升為 read。以期減少“讀 miss”。

  5. 新寫入的 key 會保存到 dirty 中,如果這時 dirty 為 nil,就會先新創建一個 dirty,並將 read 中未被刪除的元素拷貝到 dirty。

  6. 當 dirty 為 nil 的時候,read 就代表 map 所有的數據;當 dirty 不為 nil 的時候,dirty 才代表 map 所有的數據。

參考資料

【德志大佬-設計併發安全的 map】https://halfrost.com/go_map_chapter_one/

【德志大佬-設計併發安全的 map】https://halfrost.com/go_map_chapter_two/

【關於 sync.map 為什麼沒有 len 方法的 issue】https://github.com/golang/go/issues/20680

【芮神增加了 len 方法】http://xiaorui.cc/archives/4972

【圖解 map 操作】https://wudaijun.com/2018/02/go-sync-map-implement/

【從一道面試題開始】https://segmentfault.com/a/1190000018657984

【源碼分析】https://zhuanlan.zhihu.com/p/44585993

【行文通暢,流程圖清晰】https://juejin.im/post/5d36a7cbf265da1bb47da444

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

【其他文章推薦】

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

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

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

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

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

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