最多10萬元 選國產SUV還是合資家用轎車_貨運

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

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

朗逸較簡單內飾這東西跟價格絕對是成正比的,雖然這兩個車價格差不多,但是由於GS是自主品牌,所以內飾絕對要比朗逸“豪華”一個檔次。尺寸和空間基本處在一個檔次視覺上朗逸稍微大一點,但是真的坐進去了會發現其實都差不多,可能朗逸確實大那麼一點點。

如今十萬級別的車子日漸成為大多數消費者的主流選擇,所以今天我們就選取了目前比較熱的兩款車,帝豪GS和大眾朗逸做對比,看看誰的性價比更高。

為了對比的公平,我們就選取了帝豪GS的頂配車型-運動版 1.3T 自動臻尚型,指導價為10.88萬。朗逸為1.6L 自動風尚版,指導價為12.19萬元(優惠下來和帝豪GS價格相近)。為了方便閱讀下文帝豪GS簡稱為GS。之所以選擇朗逸和GS對比,是因為後台有很多讀者經常糾結這兩個車怎麼選擇,所以今天就統一給大家做個介紹。

外觀

GS的更具設計感;朗逸更中庸

因為帝豪GS是吉利精品2.0時代的最新產品,所以外觀設計上緊跟時代的步伐,看起來非常時尚動感。朗逸則是更多的採用大眾中庸化的設計,整體上並沒有太大的特色。不過,有很多消費者就是很喜歡朗逸的外觀設計。

內飾

GS更精緻;朗逸較簡單

內飾這東西跟價格絕對是成正比的,雖然這兩個車價格差不多,但是由於GS是自主品牌,所以內飾絕對要比朗逸“豪華”一個檔次。

尺寸和空間

基本處在一個檔次

視覺上朗逸稍微大一點,但是真的坐進去了會發現其實都差不多,可能朗逸確實大那麼一點點。

配置

毫無懸念GS完勝,

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

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

不管舒適性配置還是安全配置GS都“吊打”朗逸

動力系統

GS雙離合不太靠譜;朗逸動力系統較老但是穩定耐操

雖然帝豪1.3T發動機是最新研發的,性能還是比較先進的,但是雙離合變速箱遭到了不少消費者的吐槽。朗逸的動力系統雖然沒有什麼亮點,但是質量確實非常好。

由於朗逸車子較輕,再加上調教的很好,所以朗逸的百公里油耗約為7.5L,GS則比較高,約為9L。對於駕駛感受來說,由於朗逸屬於老舊平台的產物,所以駕駛感受很一般,帝豪GS由於調教的很不錯,駕駛起來會給你不小的驚喜。

其實這兩台車子硬件比起來肯定是GS完勝,但是軟實力也就是品牌知名度來看,GS顯然差距還很大。雖然GS外觀好看,還是大家喜歡的SUV車型,但是大家還是更傾向於選擇朗逸。畢竟,大家覺得,朗逸的質量,要比GS好太多。

其實我們並不是十分推薦GS的雙離合車型,本文只是為了方便做對比,因為只有最貴的GS才和1.6L 自動風尚版的朗逸價格差不多。所以我們更推薦GS的手動擋車型,質量更可靠,最值得推薦。如果真的喜歡雙離合,那麼小編還是更推薦大眾的雙離合。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※回頭車貨運收費標準

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

光便宜還不夠 這些10幾萬的家用車還能賺些買菜錢_網頁設計公司

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

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

如果這些政策真的落實這類打車軟件很有可能成為最新的相親軟件就像網上說過的一個梗本地戶口、價格不便宜的新車、還有本地牌照滿足這些條件估計都有車有房比普通的交友平台更牛逼。下班也要出去做網約司機了。說了這麼多,究竟什麼車才適合跑滴滴。

我們沒車一族的出行方式基本就是靠走、或者踩個自行車、乘坐公共交通工具、部分地區短途還能坐摩托車、土豪一點就去坐計程車。從Uber進入中國以及和滴滴出行一起相互大肆燒錢開始,我們終於找到了一個舒服、價格便宜的出行方式,也讓有車一族找到了一個月入破萬的工作。

還記得那時全民皆滴滴的時代

人們出行叫網約車

不僅隨傳隨到、關鍵是便宜

再也不用碰到那些讓人厭惡的出租車!

對於很多駕駛員來說

終於擁有一個月入破萬的工作

還記得網約車剛興起的時候

做幾個月新買的車就回本了

每天做幾單就有巨額獎勵

也讓不少人辭掉了原本的工作

紛紛投入了網約車的行列

作為一個開放的平台,各位車主只需要身份證、駕駛證、行駛證就能完成註冊,投入到偉大的網約車行列,也正是因為手續如此簡單,也造就了網約車行列出現一些混亂的狀況,也存在一些比較極端的負面新聞。

下面我們來扒一扒你打滴滴遇過的奇葩事情…

王小姐:我曾經叫了一輛滴滴,然後來的竟然是一檯面包車!麵包車!而且還有很大一股異味!

楊先生:叫了滴滴,看着App,盯着地圖上的小汽車離自己越來越近了,然後趕時間的我馬上就能上車了….後來司機開過了,結果司機越開越遠,最後又兜了很大一個圈子轉回來!!!我勒個去!

好日子總會到頭的

網約車車存在已經嚴重影響到計程車行業

為了保障利益

終極BOSS受不了壓力要出手了!

《網約車徵求意見稿》

已經從北上廣深這幾個一線城市出台

用最簡單的話術總結這個意見稿

車、牌、人三方面都作出明確規定!

在尺寸上

北、深、上三大城市軸距要求≥2.7米

新能源車軸距≥2.65米

廣州長寬高分別大於4.6米、1.7米、1.42米

在排量上

北、上、深≥2.0L或1.8T;上海沒要求

在年限上

廣州要求1年內准新車

深圳要求2年內車型

北京、上海並沒要求

總結下來最嚴格的還是廣州

另外網約車要求是本地牌照

北京需要搖號

上海:拍牌均價88359元(10月)

廣州:拍牌均價19614元(9月)

深圳:拍牌均價39729元(9月)

在駕駛員方面

北、上兩城需要本地戶口

深圳需要有居住證

廣州並沒要求(這是一個包容的城市)

看起來要滿足這一些條件真不容易…

如果這些政策真的落實

這類打車軟件很有可能成為

最新的相親軟件

就像網上說過的一個梗

本地戶口、價格不便宜的新車、還有本地牌照

滿足這些條件估計都有車有房

比普通的交友平台更牛逼!

下班也要出去做網約司機了!

說了這麼多,究竟什麼車才適合跑滴滴?

要跑滴滴首先要滿足以下幾個條件!

中級車以上(價格還不能太高)

動力在2.0L或1.8T以上

車子省油、保養便宜、而且耐用

最後當然要空間大

1日系选手

凱美瑞

車身尺寸:4850*1825*1480mm

軸距:2775mm

符合車型:全系

售價:18.48-32.98萬

點評:在看來,滴滴的法規上,日系車佔優!先趴一趴日系車的優點,空間大、省油、保養便宜、而且還耐操,用來做網約車還真是合適,而這一次所說的豐田凱美瑞全系車型均已滿足各項條件,這裏更推薦選擇雙擎車型,雖然是2.5L的排量但是油耗才5-7L左右的表現就已經能獨領風騷,更不用說2.0L車型本身的表現了。照這麼說雅閣也是個不錯的選擇囖?其實不然,針對網約車來說,凱美瑞的後排舒適度是在雅閣之上的,

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

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

自己搭車也會選擇凱美瑞。

2德系选手

帕薩特

車身尺寸:4872*1834*1484mm

軸距:2803mm

符合車型:1.8T以上車型

售價:22.29-33.29萬

點評:帕薩特可以說是在德系品牌中能夠達標而且價格是最便宜的一個車型,在空間、動力、排量、尺寸方面均已經滿足要求,雖然帕薩特有一個比較大的優惠幅度,但是1.8T以上的車型辦下來也要20多萬,專門拿來做網約車就真的比較浪費了,而且德系車保養並不便宜,另外還存在一定程度的燒機油情況,拿來做網約車,未免投入太大了。

3美系选手

邁銳寶XL

車身尺寸:4923*1854*1477mm

軸距:2829mm

符合車型:2.5L版本

售價:21.99-24.99萬

點評:外觀帥氣、空間大、配置高是邁銳寶XL主要賣點之一,只是用來做網約車就必須選擇2.5L的版本,在油耗方面會偏高,而且後期投入比較大,除了這一款車型,你也可以選擇2.0L的君威或者2.0T的蒙迪歐,但是百公里油耗隨便都能超過10L的車型來說,拿來做網約車加油加到怕啊。

4國產选手

博瑞

車身尺寸:4956*1861*1513mm

軸距:2850mm

符合車型:全系

售價:11.98-22.98萬

點評:實際上博瑞也是為數不多能夠參与到網約車序列的車型之一,首先就是國產的中型車並不多,其中就博瑞賣得不錯,雖然博瑞的油耗也是百公里油耗超過10L的貨,但關鍵是車型起售價比其他車型便宜,雖然博瑞的小毛病還是有不少,但三大件的大問題還算得上過關,拿來做網約車也是可以的。

總結:

就如所說,這一次網約車的規定就像給日系車量身定做那般,做網約車最關鍵的是什麼?認為關鍵就是要省油!另外就是要售價便宜的,所以真的要狠下心來做網約車,跟偏向於選擇凱美瑞這一類的日系中型車。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

這四款SUV上個月賣的最好 只要不到15萬 是不是真的那麼好?_租車

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

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

98-15。38萬TOp 3長安CS75售價:9。28-15。88萬TOp 4寶駿560售價:6。98-9。48萬【總結】如今國內SUV市場的火爆可謂是無人不知,而這當中自主品牌的崛起也讓我們為之欣慰,哈弗H6在競爭激烈的15萬級別SUV市場更是創下了5。3萬的銷量神話,15萬這個價格分水嶺既能選擇以上這些優秀的SUV也能選擇性能平庸的合資品牌轎車,具體怎麼選還得看你們怎麼選擇,但在看來上述的自主品牌的車輛他們在擁有不輸合資車的駕乘質感的同時價格還更有優勢,各位同學在選車是不防多留意他們一下。

9月的SUV熱銷榜單出爐了,

※超省錢租車方案

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

毫無疑問SUV市場依舊保持火熱。而在眾多的熱銷SUV前十名中,自主品牌脫穎而出包攬了緊湊級SUV銷量的前三名。

【總結】如今國內SUV市場的火爆可謂是無人不知,而這當中自主品牌的崛起也讓我們為之欣慰,哈弗H6在競爭激烈的15萬級別SUV市場更是創下了5.3萬的銷量神話,15萬這個價格分水嶺既能選擇以上這些優秀的SUV也能選擇性能平庸的合資品牌轎車,具體怎麼選還得看你們怎麼選擇,但在看來上述的自主品牌的車輛他們在擁有不輸合資車的駕乘質感的同時價格還更有優勢,各位同學在選車是不防多留意他們一下。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

這些十幾萬的車換個殼賣貴3萬 偏偏大家都買貴的 你呢?_包裝設計

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

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

98-18。98萬元斯柯達-明銳指導價:9。98-17。99萬元大眾-速騰指導價:13。18-21。88萬元總結科雷嘉和逍客,會選擇科雷嘉,因為它有更加高的顏值,內飾設計富含科技感,各方面的用料做工都要比逍客更好,價格可能是唯一需要考慮的地方。

孿生兄弟大家一定聽過,那麼汽車界的孿生兄弟你又知道多少呢?事先聲明一下,想要表達的不是路虎極光和陸風X7,更加不是保時捷MACAN和眾泰SR9。

要講的是真正意義上的孿生兄弟,它們的底子一樣,但是樣子不同,

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

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

各項的調校也不盡相同,最重要的是售價也不相同。

指導價:16.38-21.98萬元

指導價:13.98-18.98萬元

指導價:9.98-17.99萬元

指導價:13.18-21.88萬元

科雷嘉和逍客,會選擇科雷嘉,因為它有更加高的顏值,內飾設計富含科技感,各方面的用料做工都要比逍客更好,價格可能是唯一需要考慮的地方。

明銳和速騰,會選擇明銳,最大的決定因素是掀背式的尾廂,然後就是內飾的設計,速騰的內飾已經看膩了,再去看看明銳的內飾,有新鮮感。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

本年度試過最深刻的SUV竟是一台國產車_台中搬家

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

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

路虎SVR作為一輛極其暴力的性能SUV,其5。0L V8發動機能爆發出550馬力的動力,而且輸出非常直接,只要你深踩油門,車子馬上就會發出炸裂整條街的聲浪,其暢快的感覺絕對讓你上癮。吉利近年推出的車型風評都非常不錯,博瑞被稱為最美中國車,而最美中國SUV則落到了博越身上。

上一期我們為大家送上了年度印象最深刻的性能車盤點,今天就為大家送上年度印象最深刻的SUV盤點。

奔馳GLA A45 AMG是一台性能SUV,同級對手就是已經在國外上市的RS Q3。可能不少人會覺得GLA A45 AMG就是一輛加高了的A45 AMG,開起來並無太多不同。實際上底盤高度加高了之後除了通過性提高了之外,整輛GLA A45 AMG的身板還是很硬挺的,過彎的時候你還是能很明顯感覺到它性能SUV的屬性,同時超過380馬力的動力輸出也能讓你享受一下推背感,當你遇到一些非鋪裝路面時,又能直接開過去,這種逆天的設定還真是有點吸引人呢。

Model X是特斯拉首款SUV,Model X p90D在狂暴模式下百公里加速僅為3.4秒,也是把特斯拉的超強加速能力繼承了下來。除此之後,其鷹翼式車門,可電動控制開關的車門,提供五座和七座車型,

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

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

加上一個回頭率極高的外觀,Model X絕對適合一些喜歡獨特又能接受新事物的車主。

雖然車底有一個大電機,增加了不少車重,但也讓Model X的重心壓低了,行駛過程的穩定性也提高了不少,對於想偶爾激烈駕駛一下的朋友來說,Model X也是能應付得到的。

路虎SVR作為一輛極其暴力的性能SUV,其5.0L V8發動機能爆發出550馬力的動力,而且輸出非常直接,只要你深踩油門,車子馬上就會發出炸裂整條街的聲浪,其暢快的感覺絕對讓你上癮。

吉利近年推出的車型風評都非常不錯,博瑞被稱為最美中國車,而最美中國SUV則落到了博越身上。博越的設計風格越趨成熟,加上2.0L/1.8T發動機和6AT變速箱的動力單元,其匹配程度非常不錯,果然自主品牌還是得在變速箱上下功夫。

而博越的行駛質感也對得起這個價位,雖然操控上來說不會太理想,但是作為SUV,博越還是提供了不錯的舒適性,如果平常有照顧家人的需要,那麼博越是值得考慮的一款自主SUV。

好了這期盤點就到這了,請期待下一期家用車盤點。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

質信中國造 探秘吉利博越寶雞生產基地_台中搬家公司

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

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

博越整體造型融合了中國文化元素與國際時尚潮流,外觀動感精緻,內飾典雅輕奢。博越搭載了2。0L自然吸氣和1。8TD兩款發動機,與之匹配的是6擋手動和澳大利亞DSI6速手自一體變速器,實現了動力與操控的完美結合。再根據中國路況和SUV特性進行深度的調教優化,博越兼顧安全性和駕馭樂趣。

10月29日,“質信中國造 吉利博越品質之旅”活動在吉利汽車寶雞基地舉行。作為吉利汽車進入精品3.0時代的全新生產基地,寶雞基地是吉利汽車按照高標準規劃設計打造的世界一流現代化汽車工廠。寶雞基地採用了國際一流的生產設備,各車間均投入全球領先的專業機器人,建成衝壓、焊裝、塗裝、總裝全自動化的國際一流生產線,實現了全領域智能製造。寶雞基地的製造工藝不僅處於國內領先水平,同時也達到了全球一流的世界級工廠水準,成為中國汽車製造業的標杆型工廠。

圖:吉利汽車寶雞製造基地

高標準規劃建設 打造世界一流的現代化工廠

寶雞基地根據吉利集團發展戰略部署,遵循高起點規劃、高標準設計,按照世界一流現代化汽車工廠要求進行建設,也是吉利汽車響應國家“一帶一路”,“西部大開發”政策的具體體現。寶雞基地項目總投資72億元人民幣,佔地1344畝,建設用地1164畝,一次性建成包括衝壓、焊裝、塗裝、總裝的整車四大主要工藝用房,以及與之配套的聯合動力站、油化庫、試車跑道、成品車停放區、管理中心、生活配套區等各項輔助設施,形成雙班年產20萬台整車的生產規模。

圖:五序衝壓

衝壓車間,擁有兩條達到世界先進水平的全自動化生產線,A線為2400噸打頭的五序衝壓連線,用於生產外覆蓋件;B線為日本網野公司生產的四序壓機,用於生產內板件和深拉延件。衝壓車間整線全封閉設計,噪音低於85分貝;採用德國SMT獨立清洗、塗油機,可以實現最高精度5um的油膜厚度控制,達到高效清洗;兩條生產線均採用ABB直線七軸機器人搬運,最高可達14SpM,實現整線自動化;一鍵換模技術更是達到世界領先水準。

圖:車身總拼線

焊裝車間,作為引領吉利集團邁向工業4.0的首創工廠,從建設之初貫徹實施自動化、智能化、模塊化、柔性化等先進理念,力圖打造吉利的標杆工廠。全線擁有128台焊裝領域頂尖的意大利柯馬、瑞典ABB機器人,可以完成包括車身總成、地板總成、側圍總成等七大總成的全自動化生產,實現了低能耗、高強度車身以及高品質的製造目標。

圖:色漆噴塗

塗裝車間,率先在吉利集團採用水性免中塗工藝,在保證車身防腐性能和油漆外觀質量的同時,減少VOC排放50%,降低能耗30%,是目前世界塗裝領域最先進的工藝。無論是在車身底部的UBC噴塗,還是色漆、清漆的噴塗,甚至到噴塗過程中的門蓋的開啟與關閉均採用塗裝行業全球最先進的39台德國杜爾機器人來實現。

圖:車門分裝線

總裝車間,由電裝、內裝,底盤1、底盤2,外裝、複合線等6條裝配線銜接而成的主線,包括前懸、后懸、輪胎、儀錶台、前端模塊、車門、頂棚等7條分裝線以及整車檢測線組成。主線與分裝線全部採用低噪音的摩擦輸送方式,大幅度降低了車間噪音。整車檢測線採用國際先進的3D激光技術四輪定位台、多功能轉轂試驗台、前大燈檢測設備,可滿足不同車型的高品質檢測需求。

圖:OK線

除了先進的四大工藝車間,

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

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

寶雞基地的生產管控也達到了世界領先水平,採用整線生產監控、一鍵換模、光學對中等先進技術,具備全自動化生產水平。寶雞基地堅持“零缺陷”生產管理體系,採用主客觀雙向檢驗方法,通過人工與機器的雙重檢查,把控產品合格度。嚴謹的生產管控力度離不開吉利汽車“造每個人的精品車”發展理念,從技術、工藝、零部件供應和檢測等方面,全方位確保每一輛博越產品的精品品質。

圖:四輪定位

南北工廠齊發力 產能釋放嚴把品質關

博越是吉利汽車歷時三年半時間打造的智能互聯精品SUV,集好看、好開、好智能於一身。博越整體造型融合了中國文化元素與國際時尚潮流,外觀動感精緻,內飾典雅輕奢。博越搭載了2.0L自然吸氣和1.8TD兩款發動機,與之匹配的是6擋手動和澳大利亞DSI6速手自一體變速器,實現了動力與操控的完美結合。再根據中國路況和SUV特性進行深度的調教優化,博越兼顧安全性和駕馭樂趣。

值得一提的是,博越搭載了諸多具有前瞻性的智能配置,如城市預碰撞安全系統、ACC智能自適應巡航、360°隨動3D全景影像、pM2.5空氣凈化器、“你好博越”智能語音交互系統等,在智能安全、智能駕馭、智能舒適和智能互聯方面,引領同級SUV車型,樹立了中國SUV市場新標杆。尤其是博越首創“安全識別圈”概念,從駕駛安全感到主動安全,再到被動安全,全面打造智能駕駛安全體系。

圖:媒體参觀生產線

憑藉卓越的產品性能,博越上市即熱銷。截止到10月底,博越累計銷量達7萬台;累計訂單量突破15萬台,熱銷態勢仍在繼續。在2016年度C-NCAp第三批安全碰撞結果中,博越依靠完善的被動安全系統榮獲58.2分的優異成績,刷新了2015版C-NCAp標準實施以來SUV碰撞的記錄。此外,博越榮獲2016TTA自主品牌年度自主車型和安全品質獎兩項殊榮,併入圍2017中國年度車前三強等多項大獎。連續被權威機構認證,無疑是博越精品品質的最好證明。

圖:跑道試車

在以博越為代表的精品SUV帶動下,吉利汽車2016年前三季度實現45.9萬輛的銷量成績,同比增長29%。在此基礎上,吉利汽車第二次上調全年銷量目標至70萬輛,展現出了強大的自信心。寶雞基地的投產,將承擔起博越90%的產能,達到月產1.6萬輛的規模。加上春曉工廠,博越月產能將實現2萬輛。南北工廠齊發力,將最大程度上緩解博越的產能壓力,縮短用戶的提車周期,助力博越銷量再上新台階。

吉利汽車集團副總裁、汽車銷售公司總經理林傑表示:“博越作為吉利汽車精品車發展戰略首款SUV產品,擔負着吉利汽車品牌向上,銷量突破的任務。事實也證明,在吉利汽車嚴把品質關的前提下,吉利汽車全線產品齊頭並進,SUV與轎車實現了均衡發展。在寶雞基地的順利投產下,博越的產能問題也將得到緩解,用戶的提車周期也將最大限度的縮短,但我們並不會因此放鬆對產品品質的把控。吉利汽車將堅持以市場和消費者需求為導向,不斷為消費者打造高品質、高技術、高附加值的產品,努力提升品牌影響力,引領中國汽車製造業向專業化、精品化、國際化方向轉型。”本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

Redis詳解(十三)—— Redis布隆過濾器_網頁設計公司

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

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

  本篇博客我們主要介紹如何用Redis實現布隆過濾器,但是在介紹布隆過濾器之前,我們首先介紹一下,為啥要使用布隆過濾器。

1、布隆過濾器使用場景

  比如有如下幾個需求:

  ①、原本有10億個號碼,現在又來了10萬個號碼,要快速準確判斷這10萬個號碼是否在10億個號碼庫中?

  解決辦法一:將10億個號碼存入數據庫中,進行數據庫查詢,準確性有了,但是速度會比較慢。

  解決辦法二:將10億號碼放入內存中,比如Redis緩存中,這裏我們算一下佔用內存大小:10億*8字節=8GB,通過內存查詢,準確性和速度都有了,但是大約8gb的內存空間,挺浪費內存空間的。

  ②、接觸過爬蟲的,應該有這麼一個需求,需要爬蟲的網站千千萬萬,對於一個新的網站url,我們如何判斷這個url我們是否已經爬過了?

  解決辦法還是上面的兩種,很顯然,都不太好。

  ③、同理還有垃圾郵箱的過濾。

  那麼對於類似這種,大數據量集合,如何準確快速的判斷某個數據是否在大數據量集合中,並且不佔用內存,布隆過濾器應運而生了。

2、布隆過濾器簡介

  帶着上面的幾個疑問,我們來看看到底什麼是布隆過濾器。

  布隆過濾器:一種數據結構,是由一串很長的二進制向量組成,可以將其看成一個二進制數組。既然是二進制,那麼裏面存放的不是0,就是1,但是初始默認值都是0。

  如下所示:

  

  ①、添加數據

  介紹概念的時候,我們說可以將布隆過濾器看成一個容器,那麼如何向布隆過濾器中添加一個數據呢?

  如下圖所示:當要向布隆過濾器中添加一個元素key時,我們通過多個hash函數,算出一個值,然後將這個值所在的方格置為1。

  比如,下圖hash1(key)=1,那麼在第2個格子將0變為1(數組是從0開始計數的),hash2(key)=7,那麼將第8個格子置位1,依次類推。

  

 

  ②、判斷數據是否存在?

  知道了如何向布隆過濾器中添加一個數據,那麼新來一個數據,我們如何判斷其是否存在於這個布隆過濾器中呢?

  很簡單,我們只需要將這個新的數據通過上面自定義的幾個哈希函數,分別算出各個值,然後看其對應的地方是否都是1,如果存在一個不是1的情況,那麼我們可以說,該新數據一定不存在於這個布隆過濾器中。

  反過來說,如果通過哈希函數算出來的值,對應的地方都是1,那麼我們能夠肯定的得出:這個數據一定存在於這個布隆過濾器中嗎?

  答案是否定的,因為多個不同的數據通過hash函數算出來的結果是會有重複的,所以會存在某個位置是別的數據通過hash函數置為的1。

  我們可以得到一個結論:布隆過濾器可以判斷某個數據一定不存在,但是無法判斷一定存在

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

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

  ③、布隆過濾器優缺點

  優點:優點很明顯,二進制組成的數組,佔用內存極少,並且插入和查詢速度都足夠快。

  缺點:隨着數據的增加,誤判率會增加;還有無法判斷數據一定存在;另外還有一個重要缺點,無法刪除數據。

3、Redis實現布隆過濾器

①、bitmaps

  我們知道計算機是以二進制位作為底層存儲的基礎單位,一個字節等於8位。

  比如“big”字符串是由三個字符組成的,這三個字符對應的ASCII碼分為是98、105、103,對應的二進制存儲如下:

  

 

 

  在Redis中,Bitmaps 提供了一套命令用來操作類似上面字符串中的每一個位。

  一、設置值

setbit key offset value

  

 

   我們知道”b”的二進製表示為0110 0010,我們將第7位(從0開始)設置為1,那0110 0011 表示的就是字符“c”,所以最後的字符 “big”變成了“cig”。

  二、獲取值

gitbit key offset

  

   三、獲取位圖指定範圍值為1的個數

bitcount key [start end]

  如果不指定,那就是獲取全部值為1的個數。

  注意:start和end指定的是字節的個數,而不是位數組下標。

  

②、Redisson

  Redis 實現布隆過濾器的底層就是通過 bitmap 這種數據結構,至於如何實現,這裏就不重複造輪子了,介紹業界比較好用的一個客戶端工具——Redisson。

  Redisson 是用於在 Java 程序中操作 Redis 的庫,利用Redisson 我們可以在程序中輕鬆地使用 Redis。

  下面我們就通過 Redisson 來構造布隆過濾器。

 1 package com.ys.rediscluster.bloomfilter.redisson;
 2 
 3 import org.redisson.Redisson;
 4 import org.redisson.api.RBloomFilter;
 5 import org.redisson.api.RedissonClient;
 6 import org.redisson.config.Config;
 7 
 8 public class RedissonBloomFilter {
 9 
10     public static void main(String[] args) {
11         Config config = new Config();
12         config.useSingleServer().setAddress("redis://192.168.14.104:6379");
13         config.useSingleServer().setPassword("123");
14         //構造Redisson
15         RedissonClient redisson = Redisson.create(config);
16 
17         RBloomFilter<String> bloomFilter = redisson.getBloomFilter("phoneList");
18         //初始化布隆過濾器:預計元素為100000000L,誤差率為3%
19         bloomFilter.tryInit(100000000L,0.03);
20         //將號碼10086插入到布隆過濾器中
21         bloomFilter.add("10086");
22 
23         //判斷下面號碼是否在布隆過濾器中
24         System.out.println(bloomFilter.contains("123456"));//false
25         System.out.println(bloomFilter.contains("10086"));//true
26     }
27 }

  這是單節點的Redis實現方式,如果數據量比較大,期望的誤差率又很低,那單節點所提供的內存是無法滿足的,這時候可以使用分佈式布隆過濾器,同樣也可以用 Redisson 來實現,這裏我就不做代碼演示了,大家有興趣可以試試。

4、guava 工具

  最後提一下不用Redis如何來實現布隆過濾器。

  guava 工具包相信大家都用過,這是谷歌公司提供的,裏面也提供了布隆過濾器的實現。

 1 package com.ys.rediscluster.bloomfilter;
 2 
 3 import com.google.common.base.Charsets;
 4 import com.google.common.hash.BloomFilter;
 5 import com.google.common.hash.Funnel;
 6 import com.google.common.hash.Funnels;
 7 
 8 public class GuavaBloomFilter {
 9     public static void main(String[] args) {
10         BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),100000,0.01);
11 
12         bloomFilter.put("10086");
13 
14         System.out.println(bloomFilter.mightContain("123456"));
15         System.out.println(bloomFilter.mightContain("10086"));
16     }
17 }

 

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

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

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

一本正經的聊數據結構(7):哈弗曼編碼_如何寫文案

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

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

前文傳送門:

「一本正經的聊數據結構(1):時間複雜度」

「一本正經的聊數據結構(2):數組與向量」

「一本正經的聊數據結構(3):棧和隊列」

「一本正經的聊數據結構(4):樹」

「一本正經的聊數據結構(5):二叉樹的存儲結構與遍歷」

「一本正經的聊數據結構(6):最優二叉樹 —— 哈夫曼樹」

引言

在上一期,我們介紹了什麼是哈夫曼樹以及哈夫曼樹的構建過程,本期我們接着介紹哈夫曼樹的用途。

字符編碼壓縮

哈夫曼樹的應用很廣,哈夫曼編碼就是其在電訊通信中的應用之一。廣泛地用於數據文件壓縮的十分有效的編碼方法,其壓縮率通常在 20% ~ 90% 之間。

在電訊通信業務中,通常用二進制編碼來表示字母或其他字符,並用這樣的編碼來表示字符序列。

在計算機當中,因為計算機不是人,不能識別圖像、聲音、視頻等內容,對於計算機來講,它只能認識二進制的 0 和 1 ,在数字电子電路中,邏輯門的實現直接應用了二進制,因此現代的計算機和依賴計算機的設備里都用到二進制。

我們在計算機上看到的一切的圖像、聲音、視頻等內容,都是由二進制的方式進行存儲的。

簡單來講,我們把信息轉化為二進制的過程可以稱之為編碼,在計算機的世界里,編碼有很多種格式,比如我們常見的: ASCII 、 Unicode 、 GBK 、 GB2312 、 GB18030 、 UTF-8 、 UTF-16 等等。

編碼方式從長度上來分大致可以分為兩個大類:

  • 定長編碼:定長僅表明段與段之間長度相同,但沒說明是多長。
  • 變長編碼:變長就是段與段之間的長度不相同,同樣也不定義具體有多長。

在最初的設計中, ASCII 編碼就是採用的定長編碼的方案,使用定長一字節來表示一個字符。

舉個栗子,假如我們對 「hello」 進行編碼,使用定長編碼,為了方便,採用了十進制,主要是因為我懶,原理與二進制是一樣的。

字符 編碼
h 00
e 01
l 02
o 03

假設我們現在有個文件,內容是 00000001 ,假如定長 2 位(這裏的位指十進制的位)是唯一的編碼方案,用它去解碼,就會得到 「hhhe」 (可以對比上面的編碼, 00 代表 h ,所以前 6 個 0 轉化成 3 個 h ,後面的 01 則轉化成 e )。

但是,如果定長 2 位不是唯一的編碼方案呢?如上圖中的定長 4 位方案,如果我們誤用定長 4 位去解碼,結果就只能得到「he」( 0000 轉化為 h , 0001 轉化為 e )

隨着時代的發展,不僅老美要對他們的英文進行編碼,我們中國人也要對漢字進行編碼,而早期的 ASCII 碼的方案只有一個字節,對我們漢字而言是遠遠不夠的,所以在我們的漢字編碼方案 GB2312 中,漢字是使用兩個字節來表示的(這也是迫不得已的事,一字節壓根不夠用) 。

再多說一句,實際上我們的 GB2312 是一種變長的編碼方案,主要是為了兼容一個字節的 ASCII 碼。

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

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

隨着計算機在全世界的推廣,各種編碼方案都出來了,彼此之間的轉換也帶來了諸多的問題。採用某種統一的標準就勢在必行了,於是乎天上一聲霹靂, Unicode 粉墨登場!

不過 Unicode 對於只需要使用到一個字節的 ASCII 碼來講,讓他們使用 Unicode ,多少還是不是很願意的。

比如 「he」 兩個字符,用 ASCII 只需要保存成 6865 ( 16 進制),現在則成了 00680065 ,前面多的那兩個 0 (用作站位) ,基本上可以說是毫無意義,用 Unicode 編碼的文本,原來可能只有 1KB 大小,現在要變成 2KB ,體積成倍的往上漲。

最終, Unicode 編碼方案逐漸演化成了變長的 UTF-8 編碼方案,並且 UTF-8 是可以和 ASCII 碼進行兼容。

UTF-8 因為能兼容 ASCII 而受到廣泛歡迎,但在保存中文方面,要用 3 個字節,有的甚至要 4 個字節,所以在保存中文方面效率並不算太好,與此相對, GB2312 , GBK 之類用兩字節保存中文字符效率上會高,同時它們也都兼容 ASCII ,所以在中英混合的情況下還是比 UTF-8 要好,但在國際化方面及可擴展空間上則不如 UTF-8 了。

所以如果有進軍國際的想法,那麼最好還是使用 UTF-8 編碼。

哈弗曼編碼

哈弗曼編碼是一種不定長的編碼方式,是由麻省理工學院的哈夫曼博所發明,這種編碼方式實現了兩個重要目標:

  • 任何一個字符編碼,都不是其他字符編碼的前綴。

  • 信息編碼的總長度最小。

乾巴巴的,還是接着舉例子:

如果我們對 「ABACCDA」 進行編碼,假設 A, B, C, D 的編碼分別為 00, 01,10, 11。

那麼 「ABACCDA」 編碼后的結果是 「00010010101100」 (共 14 位),我們解碼的時候只需要每兩位進行拆分,就可以恢復編碼前的信息了。

那我們如果用哈弗曼編碼的方式進行編碼呢?

第一件事情是要確定每個字母的權值(出現頻率), 「ABACCDA」 這個字符串中 A, B, C, D 的權值(出現的頻率)分別為 0.43, 0.14, 0.29, 0.14 。

有了權值,我們可以構造一個哈弗曼樹了,感興趣的同學可以自己畫一下,下面這個是我畫的:

編碼的結果就顯而易見了: A:0, C:10, B:110, D:111 。

剛才那個 「ABACCDA」 編碼后的結果就是 「0110010101110」 (共 13 位)。

上面我們知道了哈夫曼編碼如何編碼,那麼我們拿到了一個經過哈弗曼編碼后的代碼,如何進行譯碼工作呢?

首先還是要知道每個字母的權重是多少,然後畫出來這個哈弗曼樹,接下來,就可以對照着這個哈弗曼樹進行譯碼工作了。

在譯碼的過程中,若編碼是 「0」 ,則向左走。若編碼是 「1」 ,則向右走,一旦到達恭弘=叶 恭弘子結點,則譯出一個字符。然後不停的重複,直到這個編碼的結束,就是我們需要的原內容了。

參考

https://www.cnblogs.com/wkfvawl/p/9783271.html

https://my.oschina.net/goldenshaw/blog/307708

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

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

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

重學 Java 設計模式:實戰適配器模式_網頁設計公司

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

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

作者:小傅哥
博客:https://bugstack.cn

沉澱、分享、成長,讓自己和他人都能有所收穫!

一、前言

擦屁屁紙80%的面積都是保護手的!

工作到3年左右很大一部分程序員都想提升自己的技術棧,開始嘗試去閱讀一些源碼,例如SpringMybaitsDubbo等,但讀着讀着發現越來越難懂,一會從這過來一會跑到那去。甚至懷疑自己技術太差,慢慢也就不願意再觸碰這部分知識。

而這主要的原因是一個框架隨着時間的發展,它的複雜程度是越來越高的,從最開始只有一個非常核心的點到最後開枝散恭弘=叶 恭弘。這就像你自己開發的業務代碼或者某個組件一樣,最開始的那部分核心代碼也許只能佔到20%,而其他大部分代碼都是為了保證核心流程能正常運行的。所以這也是你讀源碼費勁的一部分原因。

框架中用到了設計模式嗎?

框架中不僅用到設計模式還用了很多,而且有些時候根本不是一個模式的單獨使用,而是多種設計模式的綜合運用。與大部分小夥伴平時開發的CRUD可就不一樣了,如果都是if語句從上到下,也就算得不上什麼框架了。就像你到Spring的源碼中搜關鍵字Adapter,就會出現很多實現類,例如;UserCredentialsDataSourceAdapter。而這種設計模式就是我們本文要介紹的適配器模式。

適配器在生活里隨處可見

如果提到在日常生活中就很多適配器的存在你會想到什麼?在沒有看後文之前可以先思考下。

二、開發環境

  1. JDK 1.8
  2. Idea + Maven
  3. 涉及工程三個,可以通過關注公眾號bugstack蟲洞棧,回復源碼下載獲取(打開獲取的鏈接,找到序號18)
工程 描述
itstack-demo-design-6-00 場景模擬工程;模擬多個MQ消息體
itstack-demo-design-6-01 使用一坨代碼實現業務需求
itstack-demo-design-6-02 通過設計模式優化改造代碼,產生對比性從而學習

三、適配器模式介紹

適配器模式的主要作用就是把原本不兼容的接口,通過適配修改做到統一。使得用戶方便使用,就像我們提到的萬能充、數據線、MAC筆記本的轉換頭、出國旅遊買個插座等等,他們都是為了適配各種不同的,做的兼容。。

除了我們生活中出現的各種適配的場景,那麼在業務開發中呢?

在業務開發中我們會經常的需要做不同接口的兼容,尤其是中台服務,中台需要把各個業務線的各種類型服務做統一包裝,再對外提供接口進行使用。而這在我們平常的開發中也是非常常見的。

四、案例場景模擬

隨着公司的業務的不斷髮展,當基礎的系統逐步成型以後。業務運營就需要開始做用戶的拉新和促活,從而保障DAU的增速以及最終ROI轉換。

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

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

而這時候就會需要做一些營銷系統,大部分常見的都是裂變、拉客,例如;你邀請一個用戶開戶、或者邀請一個用戶下單,那麼平台就會給你返利,多邀多得。同時隨着拉新的量越來越多開始設置每月下單都會給首單獎勵,等等,各種營銷場景。

那麼這個時候做這樣一個系統就會接收各種各樣的MQ消息或者接口,如果一個個的去開發,就會耗費很大的成本,同時對於後期的拓展也有一定的難度。此時就會希望有一個系統可以配置一下就把外部的MQ接入進行,這些MQ就像上面提到的可能是一些註冊開戶消息、商品下單消息等等。

而適配器的思想方式也恰恰可以運用到這裏,並且我想強調一下,適配器不只是可以適配接口往往還可以適配一些屬性信息。

1. 場景模擬工程

itstack-demo-design-6-00
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                ├── mq
                │   ├── create_account.java
                │   ├── OrderMq.java
                │   └── POPOrderDelivered.java
                └── service
                    ├── OrderServicejava
                    └── POPOrderService.java
  • 這裏模擬了三個不同類型的MQ消息,而在消息體中都有一些必要的字段,比如;用戶ID、時間、業務ID,但是每個MQ的字段屬性並不一樣。就像用戶ID在不同的MQ里也有不同的字段:uId、userId等。
  • 同時還提供了兩個不同類型的接口,一個用於查詢內部訂單訂單下單數量,一個用於查詢第三方是否首單。
  • 後面會把這些不同類型的MQ和接口做適配兼容。

2. 場景簡述

1.1 註冊開戶MQ

public class create_account {

    private String number;      // 開戶編號
    private String address;     // 開戶地
    private Date accountDate;   // 開戶時間
    private String desc;        // 開戶描述

    // ... get/set     
}

1.2 內部訂單MQ

public class OrderMq {

    private String uid;           // 用戶ID
    private String sku;           // 商品
    private String orderId;       // 訂單ID
    private Date createOrderTime; // 下單時間     

    // ... get/set      
}

1.3 第三方訂單MQ

public class POPOrderDelivered {

    private String uId;     // 用戶ID
    private String orderId; // 訂單號
    private Date orderTime; // 下單時間
    private Date sku;       // 商品
    private Date skuName;   // 商品名稱
    private BigDecimal decimal; // 金額

    // ... get/set      
}

1.4 查詢用戶內部下單數量接口

public class OrderService {

    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);

    public long queryUserOrderCount(String userId){
        logger.info("自營商家,查詢用戶的訂單是否為首單:{}", userId);
        return 10L;
    }

}

1.5 查詢用戶第三方下單首單接口

public class POPOrderService {

    private Logger logger = LoggerFactory.getLogger(POPOrderService.class);

    public boolean isFirstOrder(String uId) {
        logger.info("POP商家,查詢用戶的訂單是否為首單:{}", uId);
        return true;
    }

}
  • 以上這幾項就是不同的MQ以及不同的接口的一個體現,後面我們將使用這樣的MQ消息和接口,給它們做相應的適配。

五、用一坨坨代碼實現

其實大部分時候接MQ消息都是創建一個類用於消費,通過轉換他的MQ消息屬性給自己的方法。

我們接下來也是先體現一下這種方式的實現模擬,但是這樣的實現有一個很大的問題就是,當MQ消息越來越多后,甚至幾十幾百以後,你作為中台要怎麼優化呢?

1. 工程結構

itstack-demo-design-6-01
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                └── create_accountMqService.java
                └── OrderMqService.java
                └── POPOrderDeliveredService.java
  • 目前需要接收三個MQ消息,所有就有了三個對應的類,和我們平時的代碼幾乎一樣。如果你的MQ量不多,這樣的寫法也沒什麼問題,但是隨着數量的增加,就需要考慮用一些設計模式來解決。

2. Mq接收消息實現

public class create_accountMqService {

    public void onMessage(String message) {

        create_account mq = JSON.parseObject(message, create_account.class);

        mq.getNumber();
        mq.getAccountDate();

        // ... 處理自己的業務
    }

}
  • 三組MQ的消息都是一樣模擬使用,就不一一展示了。可以獲取源碼後學習。

六、適配器模式重構代碼

接下來使用適配器模式來進行代碼優化,也算是一次很小的重構。

適配器模式要解決的主要問題就是多種差異化類型的接口做統一輸出,這在我們學習工廠方法模式中也有所提到不同種類的獎品處理,其實那也是適配器的應用。

在本文中我們還會再另外體現出一個多種MQ接收,使用MQ的場景。來把不同類型的消息做統一的處理,便於減少後續對MQ接收。

在這裏如果你之前沒要開發過接收MQ消息,可能聽上去會有些不理解這樣的場景。對此,我個人建議先了解下MQ。另外就算不了解也沒關係,不會影響對思路的體會。

再者,本文所展示的MQ兼容的核心部分,也就是處理適配不同的類型字段。而如果我們接收MQ后,在配置不同的消費類時,如果不希望一個個開發類,那麼可以使用代理類的方式進行處理。

1. 工程結構

itstack-demo-design-6-02
└── src
    └── main
        └── java
            └── org.itstack.demo.design
                ├── impl
                │   ├── InsideOrderService.java
                │   └── POPOrderAdapterServiceImpl.java
                ├── MQAdapter,java
                ├── OrderAdapterService,java
                └── RebateInfo,java

適配器模型結構

  • 這裏包括了兩個類型的適配;接口適配、MQ適配。之所以不只是模擬接口適配,因為很多時候大家都很常見了,所以把適配的思想換一下到MQ消息體上,增加大家多設計模式的認知。
  • 先是做MQ適配,接收各種各樣的MQ消息。當業務發展的很快,需要對下單用戶首單才給獎勵,在這樣的場景下再增加對接口的適配操作。

2. 代碼實現(MQ消息適配)

2.1 統一的MQ消息體

public class RebateInfo {

    private String userId;  // 用戶ID
    private String bizId;   // 業務ID
    private Date bizTime;   // 業務時間
    private String desc;    // 業務描述
    
    // ... get/set
}
  • MQ消息中會有多種多樣的類型屬性,雖然他們都有同樣的值提供給使用方,但是如果都這樣接入那麼當MQ消息特別多時候就會很麻煩。
  • 所以在這個案例中我們定義了通用的MQ消息體,後續把所有接入進來的消息進行統一的處理。

2.2 MQ消息體適配類

public class MQAdapter {

    public static RebateInfo filter(String strJson, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return filter(JSON.parseObject(strJson, Map.class), link);
    }

    public static RebateInfo filter(Map obj, Map<String, String> link) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        RebateInfo rebateInfo = new RebateInfo();
        for (String key : link.keySet()) {
            Object val = obj.get(link.get(key));
            RebateInfo.class.getMethod("set" + key.substring(0, 1).toUpperCase() + key.substring(1), String.class).invoke(rebateInfo, val.toString());
        }
        return rebateInfo;
    }

}
  • 這個類里的方法非常重要,主要用於把不同類型MQ種的各種屬性,映射成我們需要的屬性並返回。就像一個屬性中有用戶ID;uId,映射到我們需要的;userId,做統一處理。
  • 而在這個處理過程中需要把映射管理傳遞給Map<String, String> link,也就是準確的描述了,當前MQ中某個屬性名稱,映射為我們的某個屬性名稱。
  • 最終因為我們接收到的mq消息基本都是json格式,可以轉換為MAP結構。最後使用反射調用的方式給我們的類型賦值。

2.3 測試適配類

2.3.1 編寫單元測試類
@Test
public void test_MQAdapter() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    create_account create_account = new create_account();
    create_account.setNumber("100001");
    create_account.setAddress("河北省.廊坊市.廣陽區.大學里職業技術學院");
    create_account.setAccountDate(new Date());
    create_account.setDesc("在校開戶");          

    HashMap<String, String> link01 = new HashMap<String, String>();
    link01.put("userId", "number");
    link01.put("bizId", "number");
    link01.put("bizTime", "accountDate");
    link01.put("desc", "desc");
    RebateInfo rebateInfo01 = MQAdapter.filter(create_account.toString(), link01);
    System.out.println("mq.create_account(適配前)" + create_account.toString());
    System.out.println("mq.create_account(適配后)" + JSON.toJSONString(rebateInfo01));

    System.out.println("");

    OrderMq orderMq = new OrderMq();
    orderMq.setUid("100001");
    orderMq.setSku("10928092093111123");
    orderMq.setOrderId("100000890193847111");
    orderMq.setCreateOrderTime(new Date()); 

    HashMap<String, String> link02 = new HashMap<String, String>();
    link02.put("userId", "uid");
    link02.put("bizId", "orderId");
    link02.put("bizTime", "createOrderTime");
    RebateInfo rebateInfo02 = MQAdapter.filter(orderMq.toString(), link02);

    System.out.println("mq.orderMq(適配前)" + orderMq.toString());
    System.out.println("mq.orderMq(適配后)" + JSON.toJSONString(rebateInfo02));
}
  • 在這裏我們分別模擬傳入了兩個不同的MQ消息,並設置字段的映射關係。
  • 等真的業務場景開發中,就可以配這種映射配置關係交給配置文件或者數據庫後台配置,減少編碼。
2.3.2 測試結果
mq.create_account(適配前){"accountDate":1591024816000,"address":"河北省.廊坊市.廣陽區.大學里職業技術學院","desc":"在校開戶","number":"100001"}
mq.create_account(適配后){"bizId":"100001","bizTime":1591077840669,"desc":"在校開戶","userId":"100001"}

mq.orderMq(適配前){"createOrderTime":1591024816000,"orderId":"100000890193847111","sku":"10928092093111123","uid":"100001"}
mq.orderMq(適配后){"bizId":"100000890193847111","bizTime":1591077840669,"userId":"100001"}

Process finished with exit code 0
  • 從上面可以看到,同樣的字段值在做了適配前後分別有統一的字段屬性,進行處理。這樣業務開發中也就非常簡單了。
  • 另外有一個非常重要的地方,在實際業務開發中,除了反射的使用外,還可以加入代理類把映射的配置交給它。這樣就可以不需要每一個mq都手動創建類了。

3. 代碼實現(接口使用適配)

就像我們前面提到隨着業務的發展,營銷活動本身要修改,不能只是接了MQ就發獎勵。因為此時已經拉新的越來越多了,需要做一些限制。

因為增加了只有首單用戶才給獎勵,也就是你一年或者新人或者一個月的第一單才給你獎勵,而不是你之前每一次下單都給獎勵。

那麼就需要對此種方式進行限制,而此時MQ中並沒有判斷首單的屬性。只能通過接口進行查詢,而拿到的接口如下;

接口 描述
org.itstack.demo.design.service.OrderService.queryUserOrderCount(String userId) 出參long,查詢訂單數量
org.itstack.demo.design.service.OrderService.POPOrderService.isFirstOrder(String uId) 出參boolean,判斷是否首單
  • 兩個接口的判斷邏輯和使用方式都不同,不同的接口提供方,也有不同的出參。一個是直接判斷是否首單,另外一個需要根據訂單數量判斷。
  • 因此這裏需要使用到適配器的模式來實現,當然如果你去編寫if語句也是可以實現的,但是我們經常會提到這樣的代碼很難維護。

3.1 定義統一適配接口

public interface OrderAdapterService {

    boolean isFirst(String uId);

}
  • 後面的實現類都需要完成此接口,並把具體的邏輯包裝到指定的類中,滿足單一職責。

3.2 分別實現兩個不同的接口

內部商品接口

public class InsideOrderService implements OrderAdapterService {

    private OrderService orderService = new OrderService();

    public boolean isFirst(String uId) {
        return orderService.queryUserOrderCount(uId) <= 1;
    }

}

第三方商品接口

public class POPOrderAdapterServiceImpl implements OrderAdapterService {

    private POPOrderService popOrderService = new POPOrderService();

    public boolean isFirst(String uId) {
        return popOrderService.isFirstOrder(uId);
    }

}
  • 在這兩個接口中都實現了各自的判斷方式,尤其像是提供訂單數量的接口,需要自己判斷當前接到mq時訂單數量是否<= 1,以此判斷是否為首單。

3.3 測試適配類

3.3.1 編寫單元測試類
@Test
public void test_itfAdapter() {
    OrderAdapterService popOrderAdapterService = new POPOrderAdapterServiceImpl();
    System.out.println("判斷首單,接口適配(POP):" + popOrderAdapterService.isFirst("100001"));   

    OrderAdapterService insideOrderService = new InsideOrderService();
    System.out.println("判斷首單,接口適配(自營):" + insideOrderService.isFirst("100001"));
}
3.3.2 測試結果
23:25:47.076 [main] INFO  o.i.d.design.service.POPOrderService - POP商家,查詢用戶的訂單是否為首單:100001
判斷首單,接口適配(POP):true
23:25:47.079 [main] INFO  o.i.d.design.service.POPOrderService - 自營商家,查詢用戶的訂單是否為首單:100001
判斷首單,接口適配(自營):false

Process finished with exit code 0
  • 從測試結果上來看,此時已經的接口已經做了統一的包裝,外部使用時候就不需要關心內部的具體邏輯了。而且在調用的時候只需要傳入統一的參數即可,這樣就滿足了適配的作用。

七、總結

  • 從上文可以看到不使用適配器模式這些功能同樣可以實現,但是使用了適配器模式就可以讓代碼:乾淨整潔易於維護、減少大量重複的判斷和使用、讓代碼更加易於維護和拓展。
  • 尤其是我們對MQ這樣的多種消息體中不同屬性同類的值,進行適配再加上代理類,就可以使用簡單的配置方式接入對方提供的MQ消息,而不需要大量重複的開發。非常利於拓展。
  • 設計模式的學習學習過程可能會在一些章節中涉及到其他設計模式的體現,只不過不會重點講解,避免喧賓奪主。但在實際的使用中,往往很多設計模式是綜合使用的,並不會單一出現。

八、推薦閱讀

  • 1. 重學 Java 設計模式:實戰工廠方法模式(多種類型商品發獎場景)
  • 2. 重學 Java 設計模式:實戰抽象工廠模式(替換Redis雙集群升級場景)
  • 3. 重學 Java 設計模式:實戰建造者模式(裝修物料組合套餐選配場景)
  • 4. 重學 Java 設計模式:實戰原型模式(多套試每人題目和答案亂序場景)
  • 5. 重學 Java 設計模式:實戰單例模式(Effective Java 作者推薦枚舉單例模式)

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

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

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

吐血整理全網最全的單例模式_網頁設計

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

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

前言

之前文章已經說過了設計模式的七大原則,即接口屏蔽原則,開閉原則,依賴倒轉原則,迪米特原則,里氏替換原則,單一職責原則,合成復用原則,不明白的,可以移至萬字總結之設計模式七大原則(https://www.cnblogs.com/chenchen0618/p/12434603.html)。從今天開始我們就要學習一些常見的設計模式,方便我們以後看源碼使用,當然,也可以指導我們平常的編碼任務。

我們常見的設計模式主要有23種,分為3種類型,咱也不全說,只寫重要的幾個把。

創建型:單例模式,工廠模式,原型模式

結構型:適配器模式,裝飾模式,代理模式

行為型:模板模式,觀察者模式,狀態模式,責任鏈模式

單例模式的概念和作用

概念

系統中只需要一個全局的實例,比如一些工具類,Converter,SqlSession等。

為什麼要用單例模式?

  • 只有一個全局的實例,減少了內存開支,特別是某個對象需要頻繁的創建和銷毀的時候,而創建和銷毀的過程由jvm執行,我們無法對其進行優化,所以單例模式的優勢就顯現出來啦。
  • 單例模式可以避免對資源的多重佔用,避免出現多線程的複雜問題。

單例模式的寫法重點

構造方法私有化

我們需要將構造方法私有化,而默認不寫的話,是公有的構造方法,外部可以顯式的調用來創建對象,我們的目的是讓外部不能創建對象。

提供獲取實例的公有方法

對外只提供一個公有的的方法,用來獲取實例,而這個實例是否是唯一的,單例的,由方法決定,外部無需關心。

單例模式的常見寫法(如下,重點)

餓漢式和懶漢式的區別

餓漢式

餓漢式,從名字上也很好理解,就是“比較餓”,迫不及待的想吃飯,實例在初始化的時候就已經建好了,不管你有沒有用到,都先建好了再說。

懶漢式

餓漢式,從名字上也很好理解,就是“比較懶”,不想吃飯,等餓的時候再吃。在初始化的時候先不建好對象,如果之後用到了,再創建對象。

1.餓漢式(靜態變量)–可以使用

A類

public class A {
    //私有的構造方法
    private A(){}
    //私有的靜態變量
    private final static A a=new A();
    //對外的公有方法
    public static A getInstance(){
        return a;
    }
}

 

測試類

public class test {
    public static void main(String[] args){
        A a1=A.getInstance();
        System.out.println(a1.hashCode());

        A a2=A.getInstance();
        System.out.println(a2.hashCode());
    }
}

 

運行結果

說明

該方法採用的靜態常量的方法來生成對應的實例,其只在類加載的時候就生成了,後續並不會再生成,所以其為單例的。

優點

在類加載的時候,就完成實例化,避免線程同步問題。

缺點

沒有達到懶加載的效果,如果從始到終都沒有用到這個實例,可能會導致內存的浪費。

2.餓漢式(靜態代碼塊)–可以使用

A類

public class A { 
    //私有的構造方法
     private A(){}
    //私有的靜態變量
     private final static A a; 
    //靜態代碼塊 
    static{ a=new A(); } 
    //對外的公有方法
    public static A getInstance(){
     return a; 
    }
}

 

測試類

public class test {
    public static void main(String[] args){
        A a1=A.getInstance();
        System.out.println(a1.hashCode());

        A a2=A.getInstance();
        System.out.println(a2.hashCode());
    }
}

 

運行結果

說明

該靜態代碼塊的餓漢式單例模式與靜態變量的餓漢式模式大同小異,只是將初始化過程移到了靜態代碼塊中。

優點缺點

與靜態變量餓漢式的優缺點類似。

3.懶漢式

A類

public class A {
    //私有的構造方法
    private A(){}
    //私有的靜態變量
    private  static A a;
    //對外的公有方法
    public static A getInstance(){
        if(a==null){
            a=new A();
        }
        return a;
    }
}

 

測試類和運行結果

同上。

優點

該方法的確做到了用到即加載,也就是當調用getInstance的時候,才判斷是否有該對象,如果不為空,則直接放回,如果為空,則新建一個對象並返回,達到了懶加載的效果。

缺點

當多線程的時候,可能會產生多個實例。比如我有兩個線程,同時調用getInstance方法,並都到了if語句,他們都新建了對象,那這裏就不是單例的啦。

4.懶漢式(線程安全,同步方法)–可以使用

public class A {
    //私有的構造方法
    private A(){}
    //私有的靜態變量
    private  static A a;
    //對外的公有方法
    public synchronized static A getInstance(){
        if(a==null){
            a=new A();
        }
        return a;
    }
}

 

測試類和運行結果

同上。

優點

通過synchronize關鍵字,解決了線程不安全的問題。如果兩個線程同時調用getInstance方法時,那就先執行一個線程,另一個等待,等第一個線程運行結束了,另一個等待的開始執行。

缺點

這種方法是解決了線程不安全的問題,卻給性能帶來了很大的問題,效率太低了,getInstance經常發生,每一次都要同步這個方法。

我們想着既然是方法同步導致了性能的問題,我們核心的代碼就是新建對象的過程,也就是new A();的過程,我們能不能只對部分代碼進行同步呢?

那就是方法5啦。

5.懶漢式(線程不安全)

A類

public class A {
    //私有的構造方法
    private A(){}
    //私有的靜態變量
    private  static A a;
    public  static A getInstance(){
        if(a==null){
            synchronized (A.class){
                a=new A();
            }
        }
        return a;
    }
} 

 

測試類和運行結果

如上。

優點

懶漢式的通用優點,用到才創建,達到懶加載的效果。

缺點

這個沒有意義,並沒有解決多線程的問題。我們可以看到如果兩個線程同時調用getInstance方法,並且都已經進入了if語句,即synchronized的位置,即便同步了,第一個線程先執行,進入synchronized同步的代碼塊,創建了對象,另一個進入等待狀態,等第一個線程執行結束,第二個線程還是會進入synchronized同步的代碼塊,創建對象。這個時候我們可以發現,對這代碼塊加了synchronized沒有任何意義,還是創建了多個對象,並不符合單例。

6.雙重檢查 –強烈推薦使用

A類

public class A {
    //私有的構造方法
    private A() {
    }

    //私有的靜態變量
    private volatile static A a;

    //對外的公有方法
    public static A getInstance() {
        if (a == null) {
            synchronized (A.class) {
                if (a == null) {
                    a = new A();
                }
            }
        }
        return a;
    }
} 

 

測試類和運行結果

同上。

優點

強烈推薦使用,這種寫法既避免了在多線程中出現線程不安全的情況,也能提高性能。

咱具體來說,如果兩個線程同時調用了getInstance方法,並且都已到達了if語句之後,synchronized語句之前,此時第一個線程進入synchronized之中,先判斷是否為空,很顯然第一次肯定為空,那麼則新建了對象。等到第二個線程進入synchronized之中,先判斷是否為空,顯然第一個已經創建了,所以即不新建對象。下次,不管是一個線程或者多個線程,在第一個if語句那就判斷出有對象了,便直接返回啦,根本進不了裏面的代碼。

缺點

就是這麼完美,沒有缺點,哈哈哈。

volatile(插曲)

咱先來看一個概念,重排序,也就是語句的執行順序會被重新安排。其主要分為三種:

1.編譯器優化的重排序:可以重新安排語句的執行順序。

2.指令級并行的重排序:現代處理器採用指令級并行技術,將多條指令重疊執行。

3.內存系統的重排序:由於處理器使用緩存和讀寫緩衝區,所以看上去可能是亂序的。

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

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

上面代碼中的a = new A();可能被被JVM分解成如下代碼:

// 可以分解為以下三個步驟
1 memory=allocate();// 分配內存 相當於c的malloc
2 ctorInstanc(memory) //初始化對象
3 s=memory //設置s指向剛分配的地址
 // 上述三個步驟可能會被重排序為 1-3-2,也就是:
1 memory=allocate();// 分配內存 相當於c的malloc
3 s=memory //設置s指向剛分配的地址
2 ctorInstanc(memory) //初始化對象

 

一旦假設發生了這樣的重排序,比如線程A在執行了步驟1和步驟3,但是步驟2還沒有執行完。這個時候線程B有進入了第一個if語句,它會判斷a不為空,即直接返回了a。其實這是一個未初始化完成的a,即會出現問題。

所以我們會將入volatile關鍵字,來禁止這樣的重排序,即可正常運行。

7.靜態內部類 –強烈推薦使用

A類

public class A {
    //私有構造函數
    private A() {
    }

    //私有的靜態內部類
    private static class B {
        //私有的靜態變量
        private static A a = new A();
    }

    //對外的公有方法
    public static A getInstance() {
        return B.a;
    }
}

 

 

優點

B在A裝載的時候並不會裝載,而是會在調用getInstance的時候裝載,這利用了JVM的裝載機制。這樣一來,優點有兩點,其一就是沒有A加載的時候,就裝載了a對象,而是在調用的時候才裝載,避免了資源的浪費。其二是多線程狀態下,沒有線程安全性的問題。

缺點

沒有缺點,太完美啦。

8.枚舉 –Java粑粑強烈推薦使用

問題1:私有構造器並不安全

如果不明白反射,可以查看我之前的文章,傳送門,萬字總結之反射(框架之魂)。

如果我們的對象是通過反射方法invoke出來,這樣新建的對象與通過調用getInstance新建的對象是不一樣的,具體咱來看代碼。

 

public class test {
    public static void main(String[] args) throws Exception {
        A a=A.getInstance();
        A b=A.getInstance();
        System.out.println("a的hash:"+a.hashCode()+",b的hash:"+b.hashCode());

        Constructor<A> constructor=A.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        A c=constructor.newInstance();
        System.out.println("a的hash:"+a.hashCode()+",c的hash:"+c.hashCode());

    }
}

 

我們來看下運行結果:

我們可以看到c的hashcode是和a,b不一樣,因為c是通過構造器反射出來的,由此可以證明私有構造器所組成的單例模式並不是十分安全的。

問題2:序列化問題

我們先將A類實現一個Serializable接口,具體代碼如下,跟之前的雙重if檢查一樣,只是多了個接口。

 

public class A implements Serializable {
    //私有的構造方法
    private A() {
    }

    //私有的靜態變量
    private volatile static A a;

    //對外的公有方法
    public static A getInstance() {
        if (a == null) {
            synchronized (A.class) {
                if (a == null) {
                    a = new A();
                }
            }
        }
        return a;
    }
} 

 

測試類:

public class test {
    public static void main(String[] args) throws Exception {
        A s = A.getInstance();

        //
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("學習Java的小姐姐"));
        oos.writeObject(s);
        oos.flush();
        oos.close();
        //
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("學習Java的小姐姐"));
        A s1 = (A)ois.readObject();
        ois.close();

        System.out.println(s+"\n"+s1);
        System.out.println("序列化前後兩個是否同一個:"+(s==s1));
    }
}

 

我們來看下運行結果,很顯然序列化前後兩個對象並不相等。為什麼會出現這種問題呢?這個講起來,又可以寫一篇文章了。簡單來說,任何一個readObject方法,不管是顯式的還是默認的,它都會返回一個新建的實例,這個新建的實例不同於該類初始化時創建的實例。

A類

public enum A {
  a;
  public A getInstance(){
      return a;
  }
}

 

看着代碼量很少,我們將其編譯下,代碼如下:

public final class  A extends Enum< A> {      
public static final A a;
public static A[] values();
public static AvalueOf(String s);
static {}; }

 

如何解決問題1?

public class test {
    public static void main(String[] args) throws Exception {
        A a1 = A.a;
        A a2 = A.a;
        System.out.println("正常情況下,實例化兩個實例是否相同:" + (a1 == a2));

        Constructor<A> constructor = null;
        constructor = A.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        A a3 = null;
        a3 = constructor.newInstance();
        System.out.println("a1的hash:" + a1.hashCode() + ",a2的hash:" + a2.hashCode() + ",a3的hash:" + a3.hashCode());
        System.out.println("通過反射攻擊單例模式情況下,實例化兩個實例是否相同:" + (a1 == a3));
    }
}

 

運行結果:

我們看到報錯了,是在尋找構造函數的時候報錯的,即沒有無參的構造方法,那我們看下他繼承的父類ENUM有沒有構造函數,看下源碼,發現有個兩個參數String和int類型的構造方法,我們再看下是不是構造方法的問題。

我們再用父類的有參構造方法試下,代碼如下:

public class test {
    public static void main(String[] args) throws Exception {
        A a1 = A.a;
        A a2 = A.a;
        System.out.println("正常情況下,實例化兩個實例是否相同:" + (a1 == a2));
        Constructor<A> constructor = null;
        constructor = A.class.getDeclaredConstructor(String.class,int.class);//其父類的構造器
        constructor.setAccessible(true);
        A a3 = null;
        a3 = constructor.newInstance("學習Java的小姐姐",1);
        System.out.println("a1的hash:" + a1.hashCode() + ",a2的hash:" + a2.hashCode() + ",a3的hash:" + a3.hashCode());
        System.out.println("通過反射攻擊單例模式情況下,實例化兩個實例是否相同:" + (a1 == a3));
    }
}

運行結果如下:

我們發現報錯信息的位置已經換了,現在是已經有構造方法,而是在newInstance方法的時候報錯了,我們跟下源碼發現,人家已經明確寫明了如果是枚舉類型,直接拋出異常,代碼如下,所以是無法使用反射來操作枚舉類型的數據的。

如何解決問題2?

public class test {
    public static void main(String[] args) throws Exception {
        A s = A.a;

        //
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("學習Java的小姐姐"));
        oos.writeObject(s);
        oos.flush();
        oos.close();
        //
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("學習Java的小姐姐"));
        A s1 = (A)ois.readObject();
        ois.close();

        System.out.println(s+"\n"+s1);
        System.out.println("序列化前後兩個是否同一個:"+(s==s1));
    }
}

 

運行結果;

優點

避免了反射帶來的對象不一致問題和反序列問題,簡單來說,就是簡單高效沒問題。

結語

看到這裏的都是真愛的,在這裏先謝謝各位大佬啦。

單例模式是最簡單的一種設計模式,主要包括八種形式,分別是餓漢式靜態變量,餓漢式靜態代碼塊,懶漢式線程不安全,懶漢式線程安全,懶漢式線程不安全(沒啥意義),懶漢式雙重否定線程安全,內部靜態類,枚舉類型。

這幾種最優的是枚舉類型和內部靜態類,其次是懶漢式雙重否定,剩下的都差不多啦。

如果有說的不對的地方,還請各位指正,我好繼續學習去。

參考資料

一個單例模式中volatile關鍵字引發的思考

 

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

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

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