大峽谷里的甜蜜事業_包裝設計

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

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

  王文攝(影像中國)

  登高臨水,車窗外,在高黎貢山和碧羅雪山的夾擊下,怒江艱難盤旋,峽谷之中左沖右突,闖前撞后,鐘鼓雷鳴,奔騰不息,和瀾滄江、金沙江一起衝激“三江併流”的奇瑰壯麗景象。我想,那些奔波在怒江峽谷間的扶貧隊伍,不就是一道道奮力衝出貧困大峽谷的瑰麗激流嗎?

   

  一

  許多人都讀過楊朔的散文名篇《荔枝蜜》,文中主人公“老梁”如今成了“梁老”,是廣東省蜂產品協會的名譽會長。不久前,偶然得知“梁老”被珠海市駐雲南省怒江傈僳族自治州扶貧工作組請了過去,到怒江考察養蜂扶貧。他不顧高齡,翻山越嶺考察之後,認為怒江十分適合養蜂,還順道給怒江的幹部們傳授了生動的“養蜂經”。隨後,珠海在怒江幫扶了兩百多個本地中華蜂養殖點,幫助當地群眾成就甜蜜的事業。

  中秋節前,為了看個究竟,我馬不停蹄去怒江州跑了幾天。古人曾以“水無不怒石,山有欲來峰”來描寫怒江。我震撼於高山峽谷、石裂川奔的壯美景色,目睹水石相搏、響之激越的驚濤駭浪,親見碧羅雪山和高黎貢山“兩山夾一江,一江拽二山”的畫面:“掛”在陡坡的耕地,木棚屋的篝火塘,危險的溜索,以及茶馬古道。正如宋代王安石所言:“世之奇偉、瑰怪,非常之觀,常在於險遠,而人之所罕至焉,故非有志者不能至也。”壯麗的風景往往綻放有志者非同尋常的壯美人生。

  珠海駐怒江扶貧工作組組長張松,一上車就說起他的養蜂扶貧經歷:從珠海帶來的企業,考察一遍多數都跑了。為啥?交通不便,百分之九十八的高山峽谷,怒江五十多萬人口,貧困的佔了一半。當地無機場、無火車、無航運、無高速公路,進出一趟要幾天時間。一年兩百多天都在下雨,道路常見塌方。

  一路顛簸一路看,我逐漸對怒江作為我國最貧困的“三區三州”之一有了切身認識。怒江的大山裡,很多地方風景優美,卻也是與貧困作鬥爭的一線。海拔越低,平地越少,山頂的村民除了在緩坡上種些玉米等糧食外,少有可脫貧致富的產業。

  怒江,渾身透露着大自然的那股韌勁兒。一邊雲霧繚繞,風光旖旎,幽谷懸岩,絕壑奔流,穠花異草,山水如畫;一邊面臨着艱巨的脫貧攻堅任務。鮮紅的三角梅,一簇簇迎風搖曳,山坡上開得正艷。張松說,扶貧還是要結合怒江當地實際,找准產業扶貧項目。“這不,我們把梁老請了過來,一番考察,發現怒江生態環境好,蜂蜜質量高,技術容易學,當地就有樹桶養蜂的傳統。而養蜂最需要的花源和蜜源,怒江都具備。玉米多,有充足的花粉供養小蜜蜂,利於蜂群繁殖。崇山峻岭,生態植被好,野桂花、杜鵑花、板栗花、草果花、油菜花……各種花多,有充足的蜜源,缺的是技術培訓和扶貧引領。”

  扶貧先扶志,有志者事竟成。扶貧項目確定后,工作組找到珠海專業養蜂的何伯農業公司合作,請他們派技術人員負責培訓,雙方一拍即合。一年來,派駐的一百多名珠海養蜂人行走在怒江的高山峽谷間,風餐露宿,披星戴月,培訓了兩千多名怒江養蜂人。

  養蜂人的到來打破了峽谷的寧靜,給怒江的山水增添了幾分熱鬧,也為我重新審視怒江打開了想象空間。怒江州因怒江而聞名。我以前覺得,怒江之美,最壯觀的是大峽谷,但現在覺得,怒江之美,還有那行走峽谷間,日夜與貧困頑強抗爭的養蜂人的堅韌。對為幫助他人實現美好生活而奔走的人,我們應該表達足夠的敬意!這正是人們綿延不息、不屈不撓、砥礪前行的精神偉力!

  登高臨水,車窗外,在高黎貢山和碧羅雪山的夾擊下,怒江艱難盤旋,峽谷之中左沖右突,闖前撞后,鐘鼓雷鳴,奔騰不息,和瀾滄江、金沙江一起衝激“三江併流”的奇瑰壯麗景象。我想,那些奔波在怒江峽谷間的扶貧隊伍,不就是一道道奮力衝出貧困大峽谷的瑰麗激流嗎?

  二

  扶貧工作組的同志熱情邀請我們去一個養蜂培訓點看看。綿綿細雨中,車子從丙中洛出發,沿怒江而行,崎嶇山路,斗折蛇行。遠眺山峰,一座座高腳木樓,錯落有致。約一個小時,來到一處山坡。坡地一字形擺放好幾排蜂箱,小蜜蜂從箱底沿小孔忙碌地進進出出。

  這裡是貢山獨龍族怒族自治縣閃當村吉木登小組的養蜂培訓點。村小組幹部領我們爬上山坡,鑽進一個簡陋的塑料棚。地上幾個木箱,箱上鋪着軍大衣,這就是守夜的床了。剛一坐下,他就介紹起小組養蜂培訓情況。

  “包了五十箱蜂,有一箱跑了蜂王,還有四十九箱蜂。”

  “大夥培訓了一個多月,每天傍晚5點到9點,集中培訓三四個小時。”

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

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

  他指着蜂箱旁邊席地散坐的十餘個村民說:“來培訓的都是建檔立卡貧困戶,免費培訓,我們村幹部要先學會,再教組裡的人。我有信心帶領大家學好養蜂技術,帶動脫貧。”

  老譚,是珠海何伯公司派駐的技術員,負責吉木登村小組培訓。他一身黃色的技術員服,十分醒目。談起養蜂,老譚滔滔不絕:“先要學習分蜂,繁育蜂群,一箱分成兩箱,一群分成兩群,也就幾天工夫。再有十多天就可以產蜜了。”

  “分群就要育王,育王先要製作育王杯。”

  老譚舉起一排蜂蠟製作的蜂巢說:“瞧,這就是育王杯,把一到三天的蜜蜂幼蟲放進去,喂以蜂王漿,長大就是蜂王,再挑選出強壯的放進蜂箱就可以分群了。”

  “新蜂王放進去前,先要把老蜂王關起來,不然會打架。”老譚小心地打開蜂箱,從箱角拿起一個火柴盒大小的白塑料盒,有細欄杆遮攔。細瞅,裏面關着一隻大個頭的黑蜂王。“蜂王個頭大,鑽不出蜂盒,瞧,那幾隻進出忙碌的小蜜蜂在忙着喂它呢。”

  “蜂群如果沒有蜂王,蜜蜂就會四散而去。剛放的新蜂王需要老蜂王壓壓陣容,等到新蜂王立穩了,就可以和老蜂王分開,分出新的群。蜂群多,產蜜才多啊!”

  我好奇地問:“為什麼老要換新蜂王呢?”

  “蜂王壽命三年,繁殖能力下降。新蜂王年輕力壯,蜂群的繁殖就快。年輕的蜂王一天多的可產八百多粒子。”

  面對眾人的好奇,老譚小心翼翼取出一巢框蜜蜂給我們看,巢框密密麻麻爬滿蜜蜂。蜂王早早躲藏起來。他指着巢框白色的部分說:“白色的是蜂蠟,下面覆蓋的就是蜂蜜。取蜜時要先割掉蠟。黃色的部分是花粉,哺喂花粉長大的就是小蜜蜂。”

  “蜂蜜是蜜蜂的糧食,人類都取走後,蜜蜂怎麼辦?”

  老譚笑着說:“不用擔心,每次取蜜,都會給蜜蜂留口糧的。蜜蜂雖然很勤勞,但是,當蜂蜜充足的時候,蜜蜂也會懶惰不再工作。人們取走蜂蜜后,小蜜蜂就又會辛勤勞動了。”

  我開始為蜜蜂着迷。蜜蜂的團結合作、勤勞奉獻,給我留下了深刻印象。它們以自己獨特的方式“參与”到東西部結對扶貧事業中。今年,珠海投入幫扶資金三千多萬元,向怒江一百八十七個養殖點贈送一萬八千餘箱蜜蜂。村裡每個建檔立卡貧困戶可分到五箱蜜蜂,按一箱年產十斤蜜、每斤五十元計算,一戶年收入兩千五百元。如果學會分箱技術,收入就更高,並且由何伯公司以保底價收購。貧困戶可以採取承包養、合作社養等多種方式。

  “收蜜啦,收蜜啦!”山花綻放,老窩河歡快地匯入怒江,清脆的歡呼聲傳遍山林。瀘水新寨村的養蜂點,第一次收蜜就搖出三百斤純蜜,不等收購,被本地市場一掃而光。去年,怒江三十個養殖點,就幫扶建檔立卡貧困戶一千五百多戶,六千五百多人受益,其中七百四十多人當年脫貧。

  養蜂扶貧賬,越算越開心。“這中間還有個小曲折,剛開始貢山縣個別同志對引進外地中蜂養殖有疑慮,我趕到縣裡組織養蜂座談會,從科學角度作解釋,說服大家同意引進珠海中蜂養殖。”梁老的一番話解開了謎底,“過去怒江人也養蜂,是從樹洞、岩穴里的蜂窩獵蜜取子,毀巢取蜜,方法原始。如今科學馴化養蜂,送蜂上門、技術幫扶、保底收購,加上其他種養項目,收入倍增,很快邁上脫貧奔小康之路……”

  短短几天,我目睹了峽谷萬物從不放棄生長的強大生命力。樹木枝繁恭弘=叶 恭弘茂,灌木千姿百態。野薔薇,就跟裝了彈簧似的,要蹦到太陽身邊去。萬物生長,增添了我對蜜蜂的喜愛,也啟迪我找到了此行的收穫:扶貧一定要扶到群眾心坎上。只有切合實際的精準扶貧,村民收穫才會更大。不僅要扶智扶志,還要做好技術服務,這樣扶貧會更有生命力。

  養蜂的知識還沒學夠,催生植物的雨水又到了,滴滴答答地送來了漫山遍野的花期。像蜜蜂抓緊花期釀蜜一樣,怒江也到了脫貧攻堅的關鍵期。讓我感動的是,梁老以七十七歲高齡與三百多名珠海扶貧幹部一起,奔走在怒江的高山峽谷間,為消除貧困而跋山涉水。珠海市三年來在此地投入幫扶資金近九億元,支持了養蜂、中藥種植、蔬菜基地、扶貧搬遷等四百多個扶貧項目,帶動建檔立卡貧困群眾兩萬多人脫貧。當地群眾正在擺脫深度貧困,迎來新的歷史性跨越。

  望着飛來飛去的小蜜蜂,我也忽然想到,這些勤勞的小蜜蜂知不知道自己的辛勤勞動,也是在為怒江脫貧攻堅而釀造甜蜜的未來呢?

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

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

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

考研經驗分享(上岸南理工)_包裝設計

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

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

 

前言

對於很多人來說,考研(升學)是一個不可避免的話題,這其中也面臨着很大的抉擇和猶豫之中。如果是其他專業的話,這方面的猶豫和掙扎可能少一點,但是對於計算機專業的我們來說,這方面的猶豫可能會更多一些。今天藉著這個話題聊聊考研以及自己路途的所見所聞。以下均代表個人意見,請斟酌查看!

為什麼考研

首先,對於考研的群體來說,大致可能分為下面幾種類型:

  • 提升學歷、學校層次、擴大更好機會
  • 深入研究科研(算法類),不想搞工程
  • 不想工作,也沒工作技能,考研緩衝
  • 跟風考研

對於上面的幾種類型,你要弄清楚你當前階段想要的和得到的是什麼,不滿足的是什麼。考研的選擇你要充分考慮你自己的需求,而你自己當前的能力水平、學歷學校層次、家庭條件、熱愛技術的方向等等因素都是需要你進行綜合考慮的。

首先計算機專業的考研我一直覺得一定要慎重選擇的。這是一個機會的選擇問題

  • 首先考研肯定有風險,風險也挺大,好的學校報考人數較多,這是其中一個需要進行考慮得東西
  • 其次考研基本就是要放棄大三暑期實習生招聘、大四秋招。然而在這個期間很多大廠、互聯網企業會提供很多機會、優質的待遇。如果實例夠強、運氣不那麼差還是有很大機會找到心儀的工作的。
  • 還有很多人懷揣夢想想搞算法,到了研究生階段沒有自己的方向跟着導師盲目研究,就業時跟985本碩等其他大佬競爭,難。
  • 還有成長平台的問題,三年(兩年半)時間。你可能會遇到0成長外包,也可能遇到高成長上進的公司。也可能遇到伯樂研究三年,也可能給了低微的報酬幫導師打三年的工。
  • 最直接的就是錢的問題。工作存款和升學消費這也是挺大數據的一個對比。

當然,考研是有很多好處的,比如提升學歷,提升學校,更多機會,更優秀的圈子等等。

對於我為啥考研其實原因也挺多:

  • 首先,從我自己來說很想擺脫雙非的帽子吧,想在研究生專心搞一些自己更喜歡的東西,然後有更大的機會進大廠
  • 其次,地處農村,身邊高學歷確實不多,這個不累述懂就行了吧。
  • 最後,在考的時候有算法夢,但考完之後還是打算工程,但是多認識一些人,擴個圈子、和有趣的人做些有趣的事也是一方面目的。

擇校選擇

考研擇校一般在考研初中期決定,一個學校也能部分的代表考研的價值和含金量,但是這個考研很容易部分學校扎堆,部分學校沒人考這種。

首先我覺得要考研的話就是要對學校層次定位,這個分為主觀和客觀條件。

  • 從客觀來講,考研群體擇校大致是這樣的:二(三)本更多報考部分211或一本,一本報考更多部分985或211,211報985更多一些。也就是大部分人考研選擇的層次都比自己當前院校強一點或高那麼一個層次。
  • 從主觀來講,要看你個人的學習能力和決心,你如果處在專業頂尖的存在和期望,那你可能比普通的同等次的人擇校高一些層次,還有有些懷揣名校夢的大佬肯定選擇也會不同。別太飄也別太慫了。
    在這裏插入圖片描述

其次就是同層次院校的(區域)選擇問題:

  • 考研分旱區和澇區,差不多水平院校有些地方的研究生可能要比有些地方的好考一些,比如東北地區,西部等地區有些985,211上岸的難度還是很可觀的,而幾大直轄市、江浙以及部分發達地區和城市的院校報考的真是扎堆。這真的挺讓人糾結的:學計算機當然在大城市,發達地區更好,但這些地方的院校競爭太大 考的性價比還不如部分其他地區,這就讓人進退兩難。同時自己也要考慮好自己是否有地域偏好等問題。

最後學校的專業也考客觀考慮一下,某些院校的不同專業、專學碩考起來的難度也不同,當然有的學校偶爾可能爆熱,,有時也可能爆冷。

幾個問題

有個別學弟妹問幾個問題在這裏闡述一下。
是否需要報班?

  • 可以但沒必要,報班挺貴的,你跟着身邊研友,看着各個老師出的視頻、練習跟上進度(用某度雲可以嫌慢偶爾開個會員)。就差不多了,報班有作用但個人覺得這個短期衝刺每天都在高強度學習自我規劃好完全沒必要去花那一大筆錢,加個該校考研群,買個資料進個vip群就行了。可能也就2-3百左右然後還有他們學校專業課歷年試題之類。

怎麼確定自己要報的方向?

  • 這個挺重要,有的學校其實進去之後方向每那麼明顯主要跟導師,但有的學校計算機和軟件可能不在同一個校區(地區),有的可能支持校內調劑,並且有的專碩、學碩年限可能相同或不太相同,但是我個人覺得:學校相比來說更重要些,學院專業次之。能狗進去就好。當然,能選擇好的地理,教育資源當然最好,具體政策要看你報考的學校了。

對自己報考的方向知識淺薄,複試是否會受影響?

  • 有點影響但不致命,如果考名校那可能壓力比較大,每年跨考計算機上岸的其實都挺多的,不過跨考或者你專業技能較弱在複習無論初試還是複試可能要花更多時間,更累。當下定決心、肝就完事了,千萬不要因為跨考、專業知識薄弱自卑。其實客觀來說,考研的除了個別真的強,大部分其實是偏向本科期間考試偏強的那部分人。很多專業技能強得要麼保了,還有進大廠了。剩下考研群體強得,多但是沒那麼多。所以你跟他們的差距真的沒那麼大。好好準備,好好學習沒啥問題,別擔心!

如何正確看待分數:

  • 分數這個東西,不同專業、不同省份、不同學校都可能不同,不能只光光拿分數來看,有的省份政治英語壓分,這就低一些,有的省份(學校)專業課偏難,均分降低這分又低了,分數只能代表部分或者其他大部分人水平但是絕對不能代表所有的水平。

初試準備

談起準備,老學長不由得羞愧起來,我是去年7月份初才真正意義上開始準備考研,並且在準備初期做了無用得功——不看視頻直接看書刷各個章節測試,這樣也浪費了幾天後來開始買了1000題跟着宇哥得視頻開始刷題。

準備開始時間問題

  • 這個準備得時間,當然是越早越好,但是個人覺得大三下部分時間+暑期+大四上時間上應該是足夠了,當然奮戰清北復交那種或者專業課爆炸多、難那種另外可以特殊考慮。如果專業課2門,其實暑假開始時間上還行,如果專業課比較多,那建議提前開始。比如我的專業課三門,然後開始準備比較晚,效率也不是很高,專業課考的就比較一般。
  • 另外,如果對數據結構、高數掌握不太好得童鞋一定要提早開始,因為這兩門佔用得時間相對較多,學習起來較慢,如果開始得很晚如果學習時候遇到障礙,(隊友研友如果都掌握了)心態很可能會崩塔。這時就要穩住心態了。我很多研友在大三下就開始準備很多,等我複習得時候暑期他們高數和1800的高數部分都差不多了,當他們開始線性代數的時候我還在搞高數,晚上跑步時候他們談論線性代數的問題,,我啥都聽不懂。。。。插不上一句話。。。。在這裏插入圖片描述
  • 當然最後如果此時看到的你如果非常想考研,也是不晚的,也有部分人開學后三四個月上岸,這取決於個人當前學習能力和知識儲備決心。當然,未雨綢繆肯定最最穩妥的做法。

對於學科的看法,我覺得最主要要穩住的就是數學、專業課,英語政治順帶搞搞就行。

數學:

  • 個人覺得考研最重要的就是數學了。講真,英語政治只要稍微搞搞,那種差距沒那麼明顯(個別大佬請pass此條),主要數學不能炸,數學最近幾年是一年容易一年難,但是總體難度還是趨向上升的階段,在這個時間段內你能否以平和的心態寫完這張數學卷,或者會算就是算錯,那是非常傷的。
  • 對於高數的複習,可能近半時間都在搞得是高數,大部分暑假當然也是在搞高數,刷完1800或1000或者其他配套的練習,至於跟誰的視頻,我覺得各個老師風格不同,蘿蔔青菜,各有喜愛,我當時跟的是宇哥。高數怎麼開始?就是看視頻+刷題,就是看視頻+套公式刷題+總結+回顧。簡單粗暴而又高效。對於比較好的習題冊,1800、1000題(難一點)、660比較適合開始。開學后可以閉關修鍊之類強化,最後真題模擬題開涮。
  • 高數還是要搞得穩一點,提高速度和正確率,掌握部分偏難題,有些卷子可能容易一些,如果考難了可能會比較懵逼會直接爆炸。我有些研友平時就刷高數基礎題,難題不碰他說考研難得也做不出來,結果20考研這卷子他就炸了。。。
  • 線代跟李永樂老師就得了
    在這裏插入圖片描述

專業課:

專業課這個地方也有坑的,專業課的難度看學校。有的學校專業課門數多,還難那種我們俗稱壓分,所以有時候我們有時經常聽到 誰誰考了啥350360複試都沒進,,還有時候聽到誰誰310320都上岸了某好學校。這個雖然專業課不是全部,但是佔大部分。

專業課難度:

  • 有的學校專業課真的考的又難又多門數也多(我就是),上岸的人專業課可能專業課均分只有8090分,這樣的直接影響就是你的整體分數會被拉低不易調劑,如果專業課均分90和專業課均分130的那就是40分的差距,,如果這個人320涼了可能不一定好調劑,,但是360涼了調劑相比320肯定選擇就多了很多,調劑不看專業課是啥,只看分數。有些院校、區域可能都有這種壓分的傾向,所以在報考時候也要慎重選擇,考慮清楚。如果你是一鼓作氣只想該學校,那就沒啥顧慮,如果你是只想有更好的學上,那就得認真打聽了。

數據結構:

  • 這門專業課應該是計算機必不可少的,專業課都可以使用王道或其他專業考研教材刷題都挺好的,如果數據結構基礎較好,那麼學起來、刷起來可能會容易很多,如果基礎不太好,多看看視頻。在這裏推薦B站,哪裡不會搜哪裡,數據結構的話青島大學的王卓老師講的課程真的挺好的,當然鄙人也總結了部分各位可以觀摩,我當初就用個平板忘記了就看看,不過我有數據結構的基礎,在這方面也沒花太多時間。
  • 不過可能很多人的數據結構可能並不是很好,尤其是入門時候可能很痛苦,抽象的鏈表二叉樹搞不明白,遞歸算法想不通順。剛開始入門需要多看基礎類的視頻和博文,看的多了慢慢就消化了,總的來說這就是一個時間花費的問題。如果你是大二或者大三上看到此文章,這或許也是n年後的事情,提早刷題、多刷題還是非常有必要的,有算法基礎學數據結構其實還是很容易的。

買對應學校資料

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

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

  • 考研除了408統考之外基本各個學校各自出題這樣,都是他們學校自己的老師出題,那你搞到他們的題庫和歷年真題就是很重要了,加入他們的考研群、購買他們的考研專業課資料、試題很有必要的。跟着王道學完一遍專業課到了秋天就要抱着他們歷年考研試題,期末試題等進行研究了。當然有些學校沒歷年真題但是只有回憶版,你要通過他們學校的學長的考研小機構進行操作一番了。重要一點:他們學校真題和題集很重要! 你的考研專業課試卷可能就是他們學校普通2-3門科目的期末考試組合起來的一張試卷。所以考本校的話專業課這方面優勢可能要大一些的。

英語

英語這個東西比較玄學,有人天生英語好,不努力不怎麼花試卷也能每次都考的不行。英語個人覺得前中期每天早晚稍微背背單詞就行了,但是對於可能很多二本的學弟學妹們可能英語是個必殺砍,這樣的話你們就要在英語方面每天堅持花時間背單詞。然後有時間搞搞其他模塊。

對於英語整張試捲來說,無聽力,完型分值較低,閱讀理解佔比最大,差距都靠閱讀理解拉開。20個閱讀理解每空2分,學的好的人可能錯4個以內(篇均錯1以內),有的人每篇5個平均錯2個那就錯8個,這樣8分差距就出來了。所以有時間多練閱讀理解即可。

歷年真題考前做完。而我英語的複習比較懶,,單詞沒怎麼背,,真題就做了10-19的前面部分。。新題型考前一天做了兩篇,,大小作文考前一晚整理模板,,,說來真慚愧。這樣準備導致最終結果也很一般,各位一定要提早準備好該準備的東西。。

在這裏插入圖片描述

政治

政治最後搞,考前一兩個月這樣搞搞,部分不理解的地方可以看徐濤老師視頻(不用全看),本來想背濤哥 核心考岸,後來說等肖8背肖8,後來又覺得肖8大題太多背肖4,,再後來覺得肖4所有題還是有點多再背重點題,,不重點的看看,,最後考試時候瘋狂胡扯、瘋狂套就得了。。當然,政治選擇題其實有點難的,想拿高分也得花時間的,要根據自己需求去中和時間。

總結

對於各科來說,數學和專業課是拉分較大的地方(重點關注),政治和英語可能是個別人 的強勢(不建議頭鐵花太多時間,個別大佬例外)。跟着各個考研老師的大節奏,穩重求進。前期剛高數,中期高數專業課,後期習題真題各科齊頭並進。考前多看看專業課(類似考前突擊)。

複試準備

對於不同學校,複試內容也不同,各個學校複試佔比也不同,有6:4的,還有5:5的。雖然初試很重要,但是複試的落差也可能造成不小的波動。我們常看到某新聞,某某某高分被刷,那可能真的就是以為自己穩了複試隨便搞結果涼涼了。有的學校複試有機試、筆試。有的可能主要面試。並且有機試的一定要準備好因為機試拉分比較大,筆試也是同樣的。對於大部分的複試來說都是公平的,但是有些院校不保護一志願,比如蘭某大學,寧某大學。大量等待雙985調劑生的學校也是存在的,這些也要慎重考慮。

如果時間來得及,提升硬實力還是很有必要的,多參賽,多證書,GPA高點,四六級好點也都挺好的。

我的南理準備

專業課

我是考的20軟工專碩,本來是825(數據結構+操作系統)然後在7月初轉成824(數據結構+操作系統+離散數學),因為數據結構有基礎,但是我的複習進度比較慢,9分月開開始操作系統的複習,10月份才開始離散數學的複習,離散對於剛開始的我確實是蒙的一批,都不知道怎麼搞了。因為離散的那本書的內容太多了,課後習題也比較多,後來還好找到了一份答案再繼續看。

對於專業課的複習,我剛開始就是第一遍跟着王道把數據結構和操作系統學完題目做完。9月(可以早點)後來就做他們學校的考研專業課資料了,我買的是蘭碼計算機考研資料。價格其實算算的話也還行。關鍵是買了資料後進群就有一群同樣考研的人,你不進去的話別人都在討論的問題每天的進度都有一定約束力。並且一些注意點的話,學習資源之類也可以分享,雖然表面上各個確實是競爭對手,但實際上還是比較熱心的幫助的。並且裏面學長的話也會分享很多經驗可以借鑒。可能各個學校都有這樣的群,加入其實還是很有必要的。

不過我自己最後考研專業課有點難,考的懵逼炸了,比估分低了20,,分數出來就知道涼了,然後就投身 苦逼的春招去了。。

南理考研

對於很多網上黑理航倆兄弟,怎麼說,大部分還行,可能以往複試、出成績就是有點慢吧。就今年來說,計算機和軟工擴招挺多,複試線290左右(專業課均分低)。競爭雖然挺高但是光看分數來說其實還行。因為咱們這種低分黨比價多所以有點危險,但是你如果準備充足,選擇對的方法、找的對的隊友。其實來說也還行。並且複試來說流程非常公平的。至於找不找導師其實都是錄取后的事情了,,因為錄取前導師一般不會理你,或者最多說:加油,請錄取后再聯繫之類。複試有筆試、機試、面試適合能力較強的人準備。

在這裏比較吹一波南理的考研群確實是挺好的,裏面的學長挺負責人也挺人性化的,基本複試的內容群里也都分享ppt之類的資料,也會帶領大家進行刷題,其實很多小白在這麼疫情幾個月的訓練算法提升確實挺大挺有收穫的。

其實每個學校可能都有那麼些挺好的組織,這個需要你來斟酌,如果你想考南理的話可以加他們蘭碼的企鵝號(良心推薦)801169280

結語

對於我自己來說,,我是渣渣中被擴招擴進來的幸運兒,,本來初試成績在擴招名次之外差10名,然後得知進複試準備複試內容(10分鐘筆試,8分鐘機試,10+分鐘面),也是疫情影響遠程複試。不過最後順利的逆襲綜合成績前進了20名進了(所以務必好好準備複試)。本來都簽了工作也準備解約了。確實蠻幸運的。

通過找工作那麼久了解市場、需求。結合自身的特長和能力,還是在研究生階段打算搞工程,算法工程師還是太難了,其實工程相對來說對更多人來說可能真的挺好的。不少無方向啥都不懂進去就是跟導師搞算法,結果最終搞着搞着根本不夠格作為一名算法工程師還是去搞開發,何必呢!所以無論搞啥一定要有自己選擇的目標和方面,分析市場,分析自己。包括考不考研也是一樣的問題!

在這裏插入圖片描述

在考研過程,感謝所有認可和支持認為我還行的人,以及身邊的研伴和朋友的支持。後面我會繼續知識輸出,歷所能及得分享!

在這裏插入圖片描述
下面是20年和前幾年考研學長統計得一些情況:
在這裏插入圖片描述
最後,我是一枚幸運的渣渣,只是運氣好而已在最底層僥倖上岸。如果是看到的你,奉勸:要早、要堅持、要進群、要有隊友。我想起崔的一首詩:

 

  • 昔人已乘黃鶴去,此地空餘黃鶴樓。
    黃鶴一去不復返,白雲千載空悠悠。

未來是你們的,不管考研與否,向著自己喜歡的東西和方向,加油!

歡迎關注微信公眾號:bigsai 一直分享技術和經驗的bigsai哥哥。

在這裏插入圖片描述
在這裏插入圖片描述

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

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

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

AirPods Max 各種顏色耳罩搭配看起來如何?試試這網站,自由搭配出個人專屬配色耳機_包裝設計

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

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

日前 Apple 的首款頭戴式主動降噪藍牙耳機 AirPods Max 無預警突然在 Apple 台灣官網開放訂購,當時最早一批訂購的消費者可在 2 月初收到產品,如果有另外使用官網的免費鐫刻服務添加文字、表情符號或數字的消費者則需要再多等幾天。即便對不少人而言這組耳機的售價可能有些難以負擔,但對於 Apple 的忠實顧客或其他有需求的族群,仍然是款不錯的耳機。

AirPods Max 各種顏色耳罩搭配看起來如何?試試這網站,自由搭配出個人專屬配色耳機

在 Apple 台灣官網比外界預期還早開放 AirPods Max 訂購,雖然開賣時間早卻也讓許多原本已有計劃入手 AirPods Max 的消費者有些措手不及,因為這次光是耳機就有銀色、太空灰色、綠色、天藍色以及粉紅色共五種顏色選擇,消費者還能依照個人的需求添購其他顏色的耳罩,搭配出更多種不同的專屬風格。

倘若各位在 AirPods 顏色挑選上猶豫不決,不知道每種耳機和耳罩顏色在實際搭配看起來如何,現在就有個 AirPods Max 耳罩搭配的模擬網站(點我前往),讓使用者可以直接選擇各種顏色的 AirPods 耳機、左耳耳罩襯墊、右耳耳罩襯墊,同時也能計算出需要付出的費用,可說是相當貼心呀!當然,如果本來也沒有要買,只是想玩玩體驗一下顏色搭配的樂趣,也是能試試看(點我前往)。
假如只是一般選購一組耳機和耳罩襯墊都同色的 AirPods Max ,建議售價為 549 美元(台灣建議售價為 18,490 元新台幣):

如果只添購一組不同色的 AirPods Max 耳罩襯墊, AirPods Max 耳機本體加上 AirPods 耳罩襯墊的建議售價為 618 美元(台灣建議售價為 20,780 元):

當然,選購一組不同色的 AirPods Max 耳罩襯墊,原本耳機標配的同色耳罩襯墊也是能拿來搭配一下:

如果 AirPods Max 耳機、左耳耳罩襯墊與右耳耳罩襯墊都要不同的顏色,則總共需要購買兩組 AirPods Max 耳罩襯墊,那麼售價總共需要 687 美元(台灣建議售價為 23,070 元):

以下也整理幾種配色也不錯的搭配方式,可以提供給之後想另外加購耳罩襯墊的 AirPods Max 的消費者參考:

像是銀色是許多果粉心中最能代表 Apple 的產品配色,不過實際使用上擔心銀色的耳罩襯墊容易髒,搭配黑色耳罩襯墊就是低調又不會太難與服裝搭配:

今年 iPhone 12 系列、 iPad Air 4 或 Apple Watch SE 都推出藍色的配色,銀色的 AirPods Max 搭配藍色耳罩襯墊也相當好看:

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

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

如果想左右耳都用不同顏色,粉紅色和藍色也相當搶眼:

綠色的 AirPods Max 則推薦能選擇黑色或銀色的耳罩襯墊進行搭配:

雖然 AirPods Max 耳機已經突然在 Apple 台灣官網開放訂購,不過目前 AirPods Max 其他耳罩襯墊至截稿前還沒有辦法購買的。因此,如果未來想另外添購其他顏色耳罩進行搭配,還是先多試試看這次分享的 AirPods Max 配色模擬網評估一番囉!畢竟光是訂購一組 AirPods Max 和添購一款其他配色耳罩襯墊備用,就已經要花費超過兩萬元不算太便宜的開銷。

AirPods Max 商品頁面:點我前往訂購(Apple 台灣官網)
*Apple 官網訂購享最高 12 期 0% 利率分期付款
AirPods 耳罩襯墊:點我前往(Apple 台灣官網)

假如想買 AirPods Max ,卻仍遲遲無法決定要訂購哪款配色的 AirPods Max ,亦不確定之後會不會加購其他顏色的耳罩襯墊,那麼像是太空灰色或銀色的 AirPods Max 都是顏色上比較耐看的,最早一批訂購的台灣消費者預計能在 2021 年 2 月 4 日收到。

延伸閱讀:
Apple M1 版 MacBook Pro、MacBook Air、Mac mini 通過 NCC 認證

iPhone 12 Pro Max 對決三星 Galaxy Note20 Ultra 電池續航測試:兩陣營大尺寸旗艦擔當,究竟誰輸誰贏?

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

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

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

[leetcode] 並查集(Ⅱ)_包裝設計

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

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

最長連續序列

題目[128]:鏈接。

解題思路

節點本身的值作為節點的標號,兩節點相鄰,即允許合併(x, y)的條件為x == y+1

因為數組中可能會出現值為 -1 的節點,因此不能把 root[x] == -1 作為根節點的特徵,所以採取 root[x] == x 作為判斷是否為根節點的條件。默認較小的節點作為連通分量的根。

此外,使用 map<int, int> counter 記錄節點所在連通分量的節點個數(也是merge 的返回值)。

class Solution
{
public:
    unordered_map<int, int> counter;
    unordered_map<int, int> root;
    int longestConsecutive(vector<int> &nums)
    {
        int len = nums.size();
        // use map to discard the duplicate values
        for (int x : nums)
            root[x] = x, counter[x] = 1;
        int result = len == 0 ? 0 : 1;
        for (int x : nums)
        {
            if (root.count(x + 1) == 1)
                result = max(result, merge(x, x + 1));
        }
        return result;
    }
    int find(int x)
    {
        return root[x] == x ? x : (root[x] = find(root[x]));
    }
    int merge(int x, int y)
    {
        x = find(x);
        y = find(y);
        if (x != y)
        {
            root[y] = x;
            counter[x] += counter[y];
        }
        return counter[x];
    }
};

連通網絡的操作次數

題目[1319]:Link.

解題思路

考慮使用並查集。

考慮到特殊情況,要使 N 個點連通,至少需要 N-1 條邊,否則返回 -1 即可。

通過並查集,可以計算出多餘的邊的數目(多餘的邊是指使得圖成環的邊),只要 findroot(x) == findroot(y) 說明邊 (x,y) 使得圖成環。

遍歷所有邊,在並查集中執行合併 merge 操作(多餘的邊忽略不合併,只進行計數)。設 components 為合併后后 root 數組中 -1 的個數(也就是連通分量的個數),要想所有的連通分支都連起來,需要 components - 1 個邊,所以要求「多餘的邊」的數目必須大於等於 components - 1

一個簡單的例子如下:

0--1         0--1                0--1
| /    =>    |          =>       |  | 
2  3         2  3                2  3
             components = 2
             duplicateEdge = 1

代碼實現

class Solution
{
public:
    vector<int> root;
    int result = 0;
    int makeConnected(int n, vector<vector<int>> &connections)
    {
        int E = connections.size();
        // corner cases
        if (n == 0 || n == 1)
            return 0;
        if (E < n - 1)
            return -1;
        root.resize(n), root.assign(n, -1);
        // merge
        for (auto &v : connections)
        {
            int a = v[0], b = v[1];
            merge(a, b);
        }
        int components = count(root.begin(), root.end(), -1);
        if (counter >= (components - 1))
            return components - 1;
        // should not be here
        return -1;
    }
    int find(int x)
    {
        return root[x] == -1 ? x : (root[x] = find(root[x]));
    }
    // the number of duplicate edges
    int counter = 0;
    void merge(int x, int y)
    {
        x = find(x), y = find(y);
        if (x != y)
            root[y] = x;
        else
        {
            // there is a duplicate edge
            counter++;
        }
    }
};

等式方程的可滿足性

題目[990]:Link.

解題思路

考慮並查集。遍歷所有的包含 == 的等式,顯然,相等的 2 個變量就合併。對於不等式 x!=y ,必須滿足 findroot(x) != findroot(y) 才不會出現邏輯上的錯誤。也就是說,不相等的 2 個變量必然在不同的連通分支當中。

#define getidx(x) ((x) - 'a')
class Solution
{
public:
    vector<int> root;
    bool equationsPossible(vector<string> &equations)
    {
        root.resize('z' - 'a' + 1, -1);
        vector<int> notequal;
        int len = equations.size();
        for (int i = 0; i < len; i++)
        {
            auto &s = equations[i];
            if (s[1] == '!')
            {
                notequal.emplace_back(i);
                continue;
            }
            int a = getidx(s[0]), b = getidx(s[3]);
            merge(a, b);
        }
        for (int i : notequal)
        {
            auto &s = equations[i];
            int a = getidx(s[0]), b = getidx(s[3]);
            if (find(a) == find(b))
                return false;
        }
        return true;
    }
    int find(int x)
    {
        return (root[x] == -1) ? x : (root[x] = find(root[x]));
    }
    void merge(int x, int y)
    {
        x = find(x), y = find(y);
        if (x != y)
            root[y] = x;
    }
};

盡量減少惡意軟件的傳播 II

題目[928]:這題有點難。

解題思路

參考 題解1 和 題解2 。

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

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

首先,對原來的並查集結構添加一點改進,利用 vector<int> size[N] 記錄某個連通分量中節點的數目,注意當且僅當 x 是該連通分量的根節點時,size[x] 才表示該連通分量的節點數目。這是因為在 merge 中,只對根節點的 size 進行了處理。

vector<int> root;
vector<int> size;
int find(int x)
{
    return root[x] == -1 ? (x) : (root[x] = find(root[x]));
}
void merge(int x, int y)
{
    x = find(x), y = find(y);
    if (x != y)
        root[y] = x, size[x] += size[y];	// pay attention here
}
// get the size of the connected component where node x is in
int getComponentSize(int x)
{
    return size[find(x)];
}

然後,建立一個基本圖,該圖是原圖 graph 去除所有感染節點 initial 的結果,並把這個基本圖轉換為上述改進后的並查集。把這個基本圖中的節點暫且稱為 clean nodes 或者 non-infected nodes .

從直覺上來說,我們應該在 initial 中找到那個標號最小,感染最多 non-infected nodes 的節點,但是這樣是否符合預期?

顯然是不符合的,來看個例子,設 initial nodes = [a,b,c] ,並設 2 個沒有被感染的連通分量為 N1, N2 ,且這 2 個連通分量的點數滿足 size(N1) > size(N2),原圖 graph 結構如下:

a--N1--c

b--N2

根據題目的意思,需要找到的是使得最終感染數目 M(initial) 最小的節點。

如果我們按照上述所謂的「直覺」:“在 initial 中找到那個感染最多 non-infected nodes 的節點”,應該去除的是節點 a ,但是由於 c 的存在,N1 依舊會被感染,這樣 M(initial) = size(N1) + size(N2)。(也就是說,某個連通分量相鄰的感染節點多於 1 個,該連通分量最終是必然被感染的,因為我們只能去除一個感染節點。)

實際上,這種情況下正確答案是去除 b ,因為除 b 后:M(initial) = size(N1) ,該結果才是最小的。

所以,我們要找的是:在 initial 中找到那個感染最多 non-infected nodes 的節點 ans,但這些 non-infected nodes 節點只能被 ans 感染,不能被其他的 initial 節點感染(即只能被感染一次)。

代碼實現

class Solution
{
public:
    vector<int> root;
    vector<int> size;
    int minMalwareSpread(vector<vector<int>> &graph, vector<int> &initial)
    {
        int N = graph.size();
        root.resize(N, -1);
        size.resize(N, 1);

        // use hash table to mark infected nodes
        vector<bool> init(N, false);
        for (int x : initial)
            init[x] = true;
        // change the non-infected graph into disjoint union set
        for (int i = 0; i < N; i++)
        {
            if (init[i])
                continue;
            for (int j = 0; j < i; j++)
            {
                if (init[j])
                    continue;
                if (graph[i][j] == 1)
                    merge(i, j);
            }
        }
        // table[x] = {...}
        // the set {...} means the non-infected components which initial node x will infect
        // counter[x] = k
        // k means that the non-infected component x will be infected by initial nodes for k times
        vector<int> counter(N, 0);
        unordered_map<int, unordered_set<int>> table;
        for (int u : initial)
        {
            unordered_set<int> infected;
            for (int v = 0; v < graph[u].size(); v++)
            {
                if (!init[v] && graph[u][v] == 1)
                    infected.insert(find(v));
            }
            table[u] = infected;
            for (int x : infected)
                counter[x]++;
        }

        // find the node we want
        int ans = N + 1, maxInfected = -1;
        for (int u : initial)
        {
            int sum = 0;
            for (int x : table[u])
                if (counter[x] == 1)	// must be infected only once
                    sum += getComponentSize(x);
            if (sum > maxInfected || (sum == maxInfected && u < ans))
            {
                ans = u;
                maxInfected = sum;
            }
        }
        return ans;
    }

    int find(int x)
    {
        return root[x] == -1 ? (x) : (root[x] = find(root[x]));
    }

    void merge(int x, int y)
    {
        x = find(x), y = find(y);
        if (x != y)
            root[y] = x, size[x] += size[y];
    }

    int getComponentSize(int x)
    {
        return size[find(x)];
    }
};

盡量減少惡意軟件的傳播

題目[924]:做了上面那題之後簡單一點。

解題思路

依然是使用上題中 盡量減少惡意軟件的傳播 II 改進后的並查集結構。

對整個原圖處理,轉換為並查集。然後,模擬處理。即 \(\forall x \in initial\) ,使用集合 \(newSet = initial – \{x\}\) 去模擬感染原圖,得到最終的感染節點數 t,選取感染節點數 t 最小且標號值最小的 \(x\) 作為返回結果。

代碼實現

class Solution
{
public:
    vector<int> root, size;
    int minMalwareSpread(vector<vector<int>> &graph, vector<int> &initial)
    {
        int N = graph.size();
        root.resize(N, -1);
        size.resize(N, 1);

        for (int i = 0; i < N; i++)
            for (int j = 0; j < i; j++)
                if (graph[i][j] == 1)
                    merge(i, j);

        int ans = N + 1, minval = N + 1;
        // assume that discard the node x in the initial set
        // get the injected value
        for (int x : initial)
        {
            int t = getInjected(x, initial);
            if (t < minval || (t == minval && ans > x))
            {
                minval = t;
                ans = x;
            }
        }
        return ans;
    }
    // use set initial - {x} to inject the graph
    int getInjected(int x, vector<int> &initial)
    {
        unordered_set<int> s;
        for (int k : initial)
        {
            if (k == x)
                continue;
            s.insert(find(k));
        }
        int sum = 0;
        for (int t : s)
            sum += size[find(t)];
        return sum;
    }
    int find(int x)
    {
        return root[x] == -1 ? (x) : (root[x] = find(root[x]));
    }
    void merge(int x, int y)
    {
        x = find(x), y = find(y);
        if (x != y)
            root[y] = x, size[x] += size[y];
    }
};

被圍繞的區域

題目[130]:本題難度一般。

解題思路

本題最特殊的節點是邊界上的 O 以及內部與邊界 O 相鄰的節點。

首先,通過邊界的 O 入手,從它開始進行 DFS 搜索,把所有這些的特殊節點標記為 Y 。然後,在 board 中剩下的 O 就是普通的節點(必然是不與邊界 O 相鄰且被 X 所圍繞的),可以把它們全部換成 X 。最後,把所有的 Y 還原為 O

對於搜索方法,既可以是 DFS 也可以是 BFS

代碼實現

class Solution
{
public:
    const vector<vector<int>> direction = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    int row, col;
    void solve(vector<vector<char>> &board)
    {
        row = board.size();
        if (row == 0)
            return;
        col = board[0].size();
        #define func bfs
        for (int j = 0; j < col; j++)
        {
            if (board[0][j] == 'O')
                func(0, j, board);
            if (board[row - 1][j] == 'O')
                func(row - 1, j, board);
        }

        for (int i = 0; i < row; i++)
        {
            if (board[i][0] == 'O')
                func(i, 0, board);
            if (board[i][col - 1] == 'O')
                func(i, col - 1, board);
        }

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                if (board[i][j] == 'O')
                    board[i][j] = 'X';
                if (board[i][j] == 'Y')
                    board[i][j] = 'O';
            }
        }
    }

    void dfs(int i, int j, vector<vector<char>> &board)
    {
        board[i][j] = 'Y';
        for (auto &v : direction)
        {
            int a = i + v[0], b = j + v[1];
            if (a < 0 || b < 0 || a >= row || b >= col)
                continue;
            if (board[a][b] == 'O')
                dfs(a, b, board);
        }
    }

    void bfs(int i, int j, vector<vector<char>> &board)
    {
        typedef pair<int, int> node;
        queue<node> q;
        q.push(node(i, j));
        board[i][j] = 'Y';
        while (!q.empty())
        {
            node n = q.front();
            q.pop();
            for (auto &v : direction)
            {
                int a = n.first + v[0], b = n.second + v[1];
                if (!(a < 0 || b < 0 || a >= row || b >= col) && board[a][b] == 'O')
                    board[a][b] = 'Y', q.push(node(a, b));
            }
        }
    }
};

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

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

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

優質 NAS 快取選擇,全新 Seagate IronWolf 125 4TB SSD 開箱實測_包裝設計

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

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

Seagate的IronWolf系列,主要面向NAS專用的儲存設備,因為成本考量傳統都是使用 HDD 介面,不過今天我們要開箱的產品是Seagate IronWolf 125系列的4TB SSD,相比去年推出的IronWolf 110,這次全新的IronWolf 125其實可以分為 IronWolf 125 與 IronWolf Pro 125,其實主要就是將IronWolf 110系列的特色一分為二,IronWolf 125有著較低一點點的TBW(壽命)與MTBF(可靠性),而 IronWolf Pro 125 則是繼承了 IronWolf 110 的優點,並且在小檔讀取寫入(較快)以及供電上(只要5V即可驅動)有了改善,讓消費者有更多樣的選擇。

Seagate IronWolf 125 4TB SSD  開箱

IronWolf 125 4TB SSD 從外包裝上就有著霸氣的IronWolf圖案。

包裝上也採用了靜電袋包裝,相當用心。

撕開包裝後,可以看到正面有著大大的IronWolf LOGO。

而背面則是相關資訊,IronWolf 125與IronWolf 110最大的不同就在於供電的差異,IronWolf 125改回SSD的一般5V供電,使得在外接使用上會變得更為方便。

 

Seagate IronWolf 125 4TB SSD 效能測試

IronWolf 125 4TB SSD 屬於全新的IronWolf 125系列,從容量配置上來說,其實是更貼近硬碟的使用者,相比IronWolf 110與IronWolf Pro 125的最大容量3.84TB,IronWolf 125最大容量就是今天我們要測試的4TB版本,不過由於價格定位上的關係,一般大眾比較能接受的IronWolf 125 4TB SSD是有著5,600 TBW與1,800,000hr的MTBF,相比更高價格的IronWolf 125 Pro 3.84TB SSD則是有著7,000 TBW與2,000,000hr的MTBF。

首先可以看到,實際可使用的容量為3.63 TB。(換算格式不同)

IronWolf 125全系列的最大改動,為供電改為原本的5V即可驅動,因此可以直接透過外接硬碟盒驅動,在使用上就變得非常方便,尤其SATA SSD外接硬碟盒目前非常便宜的情況下,搭配一個超大容量的外接SSD就變得非常實用。

接著我們來實際測試傳輸速度,首先使用CrystalDiskMark進行讀寫測試,實際測試的讀寫速度分別為558.72 MB/s 與539.2 MB/s。

接著使用ATTO Disk Benchmark進行讀寫測試,最大的讀寫速度分別為559.7 MB/s 與540.4 MB/s。

因為是SSD,我們另外用了AS SSD Benchmark進行最後測試,其讀取寫入速度分別為523.98 MB/s 與508.28 MB/s,分數為1231。

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

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

而平常的傳輸檔案上,我們將檔案從桌面移動到SSD內,其實際的寫入速度初期會因為快取的關係跑到非常快,但穩定後速度為494 MB/s。

而反過來將檔案從SSD移到桌面上,則實際的讀取速度為501 MB/s。

 

原廠支援

除了擁有高水準的硬體表現外,Seagate IronWolf全系列還可以在相容的NAS上,啟動專屬的IronWolf Health Management (IHM) 保護機制,直接透過圖表監測NAS 每天的資料流量,掌握各種狀況,項目包含了:資料傳輸、效能、可讀性、可寫性、整體可靠性及其他相關的硬碟健康狀態參數(例如溫度、撞擊、振動、連線穩定度以及訊號完整性)並且針對資料保護提供了預防措施,在使用上更有保障。

除此之外 IronWolf 125 SSD 皆附有3年的Seagate Rescue資料救援服務,使用前須先至官網註冊,在救援計畫保固期限內,當硬碟發生損壞故障情形,資料無法讀取時,Seagate原廠提供免費的救援服務,盡其所能的為使用者救出硬碟內的資料,客戶滿意度高達 95%。

總結

IronWolf 125 SSD系列,除了同樣有著五年的保固外,SSD使用者更在意的TBW,更是有著超乎想像的水準,相比同樣用途的競品有著2~3倍的TBW,長期使用上不擔心,有著如此高TBW的優勢情況下,即使是拿來當作NAS的快取加速使用上,也不再擔心頻繁的寫入下造成的使用壽命縮短,放心的使用吧。

更大的容量 更安全的使用 全新Seagate IronWolf Pro NAS 18TB HDD 開箱

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

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

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

帥氣 寬敞 大氣!聽說大部分成熟男人都選了這幾輛座駕!_包裝設計

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

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

能給駕駛者提供更多的操控樂趣,但是也說不上運動型的底盤。如果忽略高轉速時比較轟耳的噪音,雅閣的舒適性是很不錯的。一汽馬自達-阿特茲指導價:17。58-23。98萬元阿特茲的顏值是一直都為車友們所稱道的,也承認,馬自達的魂動外觀的確是很有設計感,既有肌肉感的同時線條又十分流暢。



上世紀六七十年代,豐田乘着美國人的石油危機,憑藉其高可靠性,低油耗的汽車佔領了美國的汽車市場,奠定了豐田國際化的基礎。然而時至今日,日系車當中的佼佼者已經不止豐田一家。今天就和大家看看,在最能體現車企實力的B級車市場,“兩田一馬”,外加一個日產,其主力車型到底有什麼能耐。

指導價:18.48-32.98萬元

舊的凱美瑞會給人中庸,低調的感覺,難免會有“大叔車”的嫌疑。而新款的凱美瑞,採用了全新的家族式“Keen Look”前臉,六邊形的大嘴下格柵也讓車頭更加動感霸氣。側面的線條則比較簡潔流暢,變化不大,車尾造型依舊比較緊湊,橫穿左右的鍍鉻飾條是近來比較流行的元素,也讓車尾的整體感更強。

凱美瑞的內飾延續了以往車型的穩重大氣風格,採用人造皮革+縫線的工藝,內飾高級感更強。略遺憾的是中控大屏並沒有像其他主動和被動安全配置那樣都有全系標配。座椅厚實舒適的同時也保證一定的橫向支撐,舒適性不錯。

動力方面,搭載2.0L自然吸氣代號為6AR-FSE的發動機採用了D4-S雙模式噴射系統和VVT-iW新世代可變氣門正時技術,最大馬力167pS,6AT手自一體的變速箱集成了空擋控制系統、減擋補油控制系統和預緊差速器,動力平順性很好。實際駕駛感受起步動力是很靈敏的,雖然沒有很強的推背感,但也不會有“力不從心”的感覺,中後段的發力也有足夠的底氣。

凱美瑞的底盤是偏向舒適的設定,車內不會感受到十分直接的震動,同時轉向的助力比較沉穩,但轉向的靈敏度一般。總體來說如果你想要體驗操控樂趣的話,凱美瑞並不適合你,凱美瑞還是適合追求舒適、安靜的家用車用戶。

指導價:16.98-23.78萬元

本田也是很靈敏的廠商,它已經意識到現在購車群體的年輕化,所以就一改了以往雅閣那些濃濃的商務風,於是我們就看到呈現在我們眼前這個前臉造型立體,車身線條凌厲,有一雙科技感十足的LED大燈的新雅閣。當然,還有一些看不見的科技,如前置攝像頭和毫米波雷達,是Honda SENSING的基礎,該系統比較複雜,總的來說就是提供行駛安全輔助和保障。

和外觀不同,雅閣的內飾並沒有大改,對稱式的布局,線條十分流暢且有一點的高級感。不得不提是中控的雙屏設計了,兩個屏幕各司其職,用起來順手,看起來NB。但當你看了儀錶盤,你發現中央的行車電腦還是單色屏,也許是本田控製成本的手段,反正這個屏幕能显示必要信息足矣。

動力方面,2.0L/2.4L地球夢發動機,最大馬力155pS/186pS,搭配的CVT變速箱,都是本田的看見本領。和外觀的動感不同,雅閣的雖然油門響應靈敏,但動力的輸出卻不慌不忙,不會給你很激烈的加速感,

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

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

整個加速過程很平順。如果你打算購買雅閣,就不要想激烈駕駛了,好好享受那平順的CVT吧。

雅閣的採用多連桿獨立后懸挂,算是B級車標配了,底盤的質感很不錯,反應靈敏,處理震動的動作夠快,比凱美瑞的質感要硬。能給駕駛者提供更多的操控樂趣,但是也說不上運動型的底盤。如果忽略高轉速時比較轟耳的噪音,雅閣的舒適性是很不錯的。

指導價:17.58-23.98萬元

阿特茲的顏值是一直都為車友們所稱道的,也承認,馬自達的魂動外觀的確是很有設計感,既有肌肉感的同時線條又十分流暢。於是,2017款的阿特茲也延續了這種設計理念,大嘴格柵通過鍍鉻飾條與兩隻鷹眼大燈相連,感覺像一種很猛的動物,但是又說不出像什麼動物,大家發揮想象力吧。

內飾設計的改變也不少,全新樣式的方向盤和中控按鍵、懸浮式的中控屏,還有一些銀色飾條的加入,運動感更強,唯一不變的應該是變速箱擋把了。內飾採用軟質的皮革材料,也有縫線工藝,質感不錯。座椅的填充比較結實,不是很厚,支撐性和包裹性都比較好,也符合阿特茲偏向運動的風格。

2.0L/2.5L的Skyactiv發動機,最大馬力158/192pS,搭配換擋邏輯聰明,能夠幾乎讓你忘記它存在的6AT手自一體變速箱,組成這個好開有活力的動力系統。實際駕駛的感受是與歐系車類似的,油門初段比較沉重,後段較線性,動力輸出並不弱且提速很快,但又不會有渦輪增壓車那種激烈的推背感。

國產的阿特茲是針對了國內的情況進行了特殊的調校,前段偏軟,小坑小窪的過濾很到位,但仍保留一定的路感,後段的懸挂表現更加紮實,能為高速轉彎的阿特茲提供更好的支撐性。

指導價:17.58-29.98萬元

全新天籟的外觀加入了日產家族式的V-motion設計理念,V字型的中網鍍鉻飾條以及回力標的大燈造型,這些設計都是為了讓日產的外形更加年輕動感,減少了舊款日產圓潤成熟的氣息。至於新日產的外觀好不好看,那就是見仁見智的了。

至於中控的布局變化變化不大,仍然是簡潔商務風,方方正正的中控台造型給人穩重大氣的感覺,只是少了一點時尚感。觸控大屏的加入是新天籟的一個進化,多媒體功能得到了一些升級。至於座椅則一直是天籟的優點,寬大且柔軟,舒適性很好。

動力方面,新款天籟依舊搭載2.0L/2.5L+CVT變速箱的動力系統,最大馬力為150pS/186pS。實際的動力表現依舊是十分平順線性,沒有什麼爆發點。舊天籟的懸挂調校是很軟的,但新天籟在保證舒適性的基礎上給懸挂增加了一點韌性,配合彎道自動循跡系統,新天籟在轉彎時的側傾控制會比舊款天籟要好,但相對同級車型依然不算突出。

總結:

和德系車不同,日系車的動力少了一份直接;和美系車也不同,日系車少了一份力量感。乍一看彷彿沒有什麼優點,但是當你開在路上的時候你又不會發現動力不夠用,你也不會收到乘客投訴你後排的舒適性。這就是日系B級車,看似平庸,實際上這種中庸的均衡的表現,已經蘊含着不少技術的力量在裡頭。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

IDEA 插件推薦 —— 讓你寫出好代碼的神器!_包裝設計

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

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

概述

今天介紹的插件主要是圍繞編碼規範的。有追求的程序員,往往都有代碼潔癖,要盡量減少代碼的「壞味道」。

代碼靜態檢查是有很多種類,例如圈複雜度、重複率等。業界提供了很多靜態檢查的插件來識別這些不合規的代碼,幫助提高項目的質量。比較知名的一個產品是 SonarQube,它提供了一個「門禁」平台,集成了很多靜態檢查檢查。下次有機會介紹一下該平台的搭建。

本文主要介紹 IDEA 中對於 Java 語言靜態檢查的好插件:

  • Alibaba Java Coding Guidelines 阿里基於他們 Java 規範提供的插件
  • CheckStyle-IDEA 檢查代碼的格式是否符合規範
  • FindBugs-IDEA 檢查代碼是否有常見的一些 Bug

Alibaba Java Coding Guidelines

阿里巴巴 Java 編碼指南插件支持。

首先說說阿里的 p3c 項目,它的 Github 主頁地址是:https://github.com/alibaba/p3c 阿里之前開源過一份 Java 開發手冊。手冊從編程規約、異常日誌、單元測試、MySQL 數據庫、工程結構、設計規約等角度,介紹了阿里的 Java 開發規範,這個對於 Java 新手幫助挺大的,能夠學到不少東西。有一些坑可能老司機也會翻車。

開發人員 Coding 時,可能就忘記規範了,寫出來的代碼還是會有『壞味道』。這時候Alibaba Java Coding Guidelines 插件就派上用場了。它會根據上面的 Java 開發規範對你的代碼進行檢查,不符合規範的代碼會有提示,並給出修改建議。阿里作為國內 Java 大廠,基於成千上萬的工程師總結出來的踩坑經驗,我相信給出的規範建議還是比較可靠的。

上個栗子:

  String str = "hello";
  for (int i = 0; i < 100; i++) {
      str = str + "world!";
  }

先不要往下看,試着分析一下這段代碼哪裡可以優化?

其實,插鍵掃描的結果不僅有這個問題,還有『魔法数字』的問題。插件的用法,見下面的截圖。

除此以外,建議在 IDEA 進行代碼提交時,勾選上它提供的檢查項按鈕,這樣如果有不合規的代碼進行提交,就會提醒你修改:

CheckStyle-IDEA

項目主頁:https://github.com/jshiell/checkstyle-idea

安裝好之後,進入設置,勾選上你要選用的默認檢查規範:

大廠往往都有自己的語言規範,可以導入選用:

右鍵菜單,選擇 Check Current File 即可檢查當前文件是否符合編碼規範:

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

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

檢查結果:

如果不符合規範的寫法有點多,整改起來就會很痛苦了,這時候該怎麼辦?有一個功能叫格式化代碼(Reformat Code),快捷鍵是:

  • Mac:Command+Option+L
  • Win:Ctrl+Shift+L

如果想按照你指定的規則進行格式化,可以按照如下方式進行自定義:

FindBugs-IDEA

FindBugs 是一款老牌 Java 靜態檢查插件了。它的功能和阿里 p3c 那個插件很像,只不過它歷史悠久、國際化一點。它同樣的可以掃描代碼,發現一些可能會引入 Bug 的代碼段,給出參考建議。

啟動 FindBugs 的方式,右鍵菜單中,Findbugs 提供了好幾個選項:

  • Analyze Current File:檢查當前文件
  • Analyze Class uner Cursor:檢查光標處的類
  • Analyze Package Files:檢查包文件
  • Analyze Modul Files:檢查 Module 文件
  • Analyze Project Files:檢查項目文件
  • Analyze Scope Files:檢查指定範圍內的文件
  • Analyze All Modified Files:檢查所有修改過的文件
  • Analyze changelist files:檢查變更列表中的文件

檢查結果:

檢查結果分為如下類別:

  • Bad practice:不好的做法,代碼違反了公認的最佳實踐標準;
  • Malicious code vulnerbility:惡意的代碼漏洞;
  • Correctness:可能不正確,比如錯誤的強制類型轉換;
  • Performance:潛在的性能問題;
  • Security:安全性;
  • Dodgy code:糟糕的代碼,FindBugs團隊認為該類型下的問題代碼導 Bug 的可能性很高;
  • Experimental:實驗;
  • Multithreaded correctness:關注於同步和多線程問題;
  • Internationalization:國際化

掃描出來的結果怎麼看懂,官網有專門的一頁介紹 FindBugs Bug Description http://findbugs.sourceforge.net/bugDescriptions.html

除了上面右鍵菜單啟動檢查之外,還可以在相應文件夾右鍵菜單中啟動:

針對檢查的嚴格程度,其實是可以調節的,建議修改為 low,這樣會盡可能的掃描出有潛在 Bug 的代碼片段:

總結

以上是目前工作中經常用到的靜態代碼檢查插鍵,雖然不是用了它們就真的能寫出好代碼,但是這些工具的確能夠讓你能夠在前人的肩膀上少踩一些坑。比如阿里的那個檢查插鍵,你可以按照它的提示,對照着他們的 Java 開發手冊查看,分析一下,為何他們會有如此的規約。高樓大廈不都是一磚一瓦砌成的嘛?小知識點的基礎打紮實了,才能走得更高!

由於國內網絡問題,我提前將最新版的《阿里巴巴 Java 開發手冊(泰山版).pdf》上傳至雲盤了,有需要的小夥伴公眾號後台回復 泰山版 即可獲得下載鏈接。

一言

上周的寫的一篇文章分享到微信群里,群友有人指出來標題有錯別字,真是有點尷尬!其實,我寫文章也比較隨意,也是最近才開始堅持每周至少輸出一篇分享的。但想想既然寫了,就要盡量保證質量。引以為戒,以後要認真點才行!

目前分享的內容主要是開發環境、效率工具等。自己一直對這方面的文章比較感興趣,因此之前就有相關積累。今後希望能通過閱讀帶來一些讀書總結的分享,也希望關注的同學後台多留言,給出你的建議,感謝~

生命不息,折騰不止!關注 「Coder魔法院」,祝你 Niubilitiy !

參考

  • 代碼缺陷掃描神器——FindBugs:https://juejin.im/entry/591ad01ba22b9d005833903e

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

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

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

吐血輸出:2萬字長文帶你細細盤點五種負載均衡策略。_包裝設計

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

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

2020 年 5 月 15 日,Dubbo 發布 2.7.7 release 版本。其中有這麼一個 Features

新增一個負載均衡策略。

熟悉我的老讀者肯定是知道的,Dubbo 的負載均衡我都寫過專門的文章,對每個負載均衡算法進行了源碼的解讀,還分享了自己調試過程中的一些騷操作。

新的負載均衡出來了,那必須的得解讀一波。

先看一下提交記錄:

https://github.com/chickenlj/incubator-dubbo/commit/6d2ba7ec7b5a1cb7971143d4262d0a1bfc826d45

負載均衡是基於 SPI 實現的,我們看到對應的文件中多了一個名為 shortestresponse 的 key。

這個,就是新增的負載均衡策略了。看名字,你也知道了這個策略的名稱就叫:最短響應。

所以截止 2.7.7 版本,官方提供了五種負載均衡算法了,他們分別是:

  1. ConsistentHashLoadBalance 一致性哈希負載均衡
  2. LeastActiveLoadBalance 最小活躍數負載均衡
  3. RandomLoadBalance 加權隨機負載均衡
  4. RoundRobinLoadBalance 加權輪詢負載均衡
  5. ShortestResponseLoadBalance 最短響應時間負載均衡

前面四種我已經在之前的文章中進行了詳細的分析。有的讀者反饋說想看合輯,所以我會在這篇文章中把之前文章也整合進來。

所以,需要特彆強調一下的是,這篇文章集合了之前寫的三篇負載均衡的文章。看完最短響應時間負載均衡這一部分后,如果你看過我之前的那三篇文章,你可以溫故而知新,也可以直接拉到文末看看我推薦的一個活動,然後點個贊再走。如果你沒有看過那三篇,這篇文章如果你細看,肯定有很多收穫,以後談起負載均衡的時候若數家珍,但是肯定需要看非常非常長的時間,做好心理準備。

我已經預感到了,這篇文章妥妥的會超過 2 萬字。屬於硬核勸退文章,想想就害怕。

最短響應時間負載均衡

首先,我們看一下這個類上的註解,先有個整體的認知。

org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance

我來翻譯一下是什麼意思:

  1. 從多個服務提供者中選擇出調用成功的且響應時間最短的服務提供者,由於滿足這樣條件的服務提供者有可能有多個。所以當選擇出多個服務提供者后要根據他們的權重做分析。
  2. 但是如果只選擇出來了一個,直接用選出來這個。
  3. 如果真的有多個,看它們的權重是否一樣,如果不一樣,則走加權隨機算法的邏輯。
  4. 如果它們的權重是一樣的,則隨機調用一個。

再配個圖,就好理解了,可以先不管圖片中的標號:

有了上面的整體概念的鋪墊了,接下來分析源碼的時候就簡單了。

源碼一共就 66 行,我把它分為 5 個片段去一一分析。

這裏一到五的標號,對應上面流程圖中的標號。我們一個個的說。

標號為①的部分

這一部分是定義並初始化一些參數,為接下來的代碼服務的,翻譯一下每個參數對應的註釋:

length 參數:服務提供者的數量。

shortestResponse 參數:所有服務提供者的估計最短響應時間。(這個地方我覺得註釋描述的不太準確,看後面的代碼可以知道這隻是一個零時變量,在循環中存儲當前最短響應時間是多少。)

shortCount 參數:具有相同最短響應時間的服務提供者個數,初始化為 0。

shortestIndexes 參數:數組裡面放的是具有相同最短響應時間的服務提供者的下標。

weights 參數:每一個服務提供者的權重。

totalWeight 參數:多個具有相同最短響應時間的服務提供者對應的預熱(預熱這個點還是挺重要的,在下面講最小活躍數負載均衡的時候有詳細說明)權重之和。

firstWeight 參數:第一個具有最短響應時間的服務提供者的權重。

sameWeight 參數:多個滿足條件的提供者的權重是否一致。

標號為②的部分

這一部分代碼的關鍵,就在上面框起來的部分。而框起來的部分,最關鍵的地方,就在於第一行。

獲取調用成功的平均時間。

成功調用的平均時間怎麼算的?

調用成功的請求數總數對應的總耗時 / 調用成功的請求數總數 = 成功調用的平均時間。

所以,在下面這個方法中,首先獲取到了調用成功的請求數總數:

這個 succeeded 參數是怎麼來的呢?

答案就是:總的請求數減去請求失敗的數量,就是請求成功的總數!

那麼為什麼不能直接獲取請求成功的總數呢?

別問,問就是沒有這個選項啊。你看,在 RpcStatus 裏面沒有這個參數呀。

請求成功的總數我們有了,接下來成功總耗時怎麼拿到的呢?

答案就是:總的請求時間減去請求失敗的總時間,就是請求成功的總耗時!

那麼為什麼不能直接獲取請求成功的總耗時呢?

別問,問就是……

我們看一下 RpcStatus 中的這幾個參數是在哪裡維護的:

org.apache.dubbo.rpc.RpcStatus#endCount(org.apache.dubbo.rpc.RpcStatus, long, boolean)

其中的第二個入參是本次請求調用時長,第三個入參是本次調用是否成功。

具體的方法不必細說了吧,已經顯而易見了。

再回去看框起來的那三行代碼:

  1. 第一行獲取到了該服務提供者成功請求的平均耗時。
  2. 第二行獲取的是該服務提供者的活躍數,也就是堆積的請求數。
  3. 第三行獲取的就是如果當前這個請求發給這個服務提供者預計需要等待的時間。乘以 active 的原因是因為它需要排在堆積的請求的後面嘛。

這裏,我們就獲取到了如果選擇當前循環中的服務提供者的預計等待時間是多長。

後面的代碼怎麼寫?

當然是出來一個更短的就把這個踢出去呀,或者出來一個一樣長時間的就記錄一下,接着去 pk 權重了。

所以,接下來 shortestIndexes 參數和 weights 參數就排上用場了:

另外,多說一句的,它裏面有這樣的一行註釋:

和 LeastActiveLoadBalance 負載均衡策略一致,我給你截圖對比一下:

可以看到,確實是非常的相似,只是一個是判斷誰的響應時間短,一個是判斷誰的活躍數低。

標號為③的地方

標號為③的地方是這樣的:

裏面參數的含義我們都知道了,所以,標號為③的地方的含義就很好解釋了:經過選擇后只有一個服務提供者滿足條件。所以,直接使用這個服務提供者。

標號為④的地方

這個地方我就不展開講了(後面的加權隨機負載均衡那一小節有詳細說明),熟悉的朋友一眼就看出來這是加權隨機負載均衡的寫法了。

不信?我給你對比一下:

你看,是不是一模一樣的。

標號為⑤的地方

一行代碼,沒啥說的。就是從多個滿足條件的且權重一樣的服務提供者中隨機選擇一個。

如果一定要多說一句的話,我截個圖吧:

可以看到,這行代碼在最短響應時間、加權隨機、最小活躍數負載均衡策略中都出現了,且都在最後一行。

好了,到這裏最短響應時間負載均衡策略就講完了,你再回過頭去看那張流程圖,會發現其實流程非常的清晰,完全可以根據代碼結構畫出流程圖。一個是說明這個算法是真的不複雜,另一個是說明好的代碼會說話。

優雅

你知道 Dubbo 加入這個新的負載均衡算法提交了幾個文件嗎?

四個文件,其中還包含兩個測試文件:

這裏就是策略模式和 SPI 的好處。對原有的負載均衡策略沒有任何侵略性。只需要按照規則擴展配置文件,實現對應接口即可。

這是什麼?

這就是值得學習優雅!

那我們優雅的進入下一議題。

最小活躍數負載均衡

這一小節所示源碼,沒有特別標註的地方均為 2.6.0 版本。

為什麼沒有用截止目前(我當時寫這段文章的時候是2019年12月01日)的最新的版本號 2.7.4.1 呢?因為 2.6.0 這個版本裏面有兩個 bug 。從 bug 講起來,印象更加深刻。

最後會對 2.6.0/2.6.5/2.7.4.1 版本進行對比,通過對比學習,加深印象。

我這裏補充一句啊,僅僅半年的時間,版本號就從 2.7.4.1 到了 2.7.7。其中還包含一個 2.7.5 這樣的大版本。

所以還有人說 Dubbo 不夠活躍?(幾年前的文章現在還有人在發。)

對吧,我們不吵架,我們擺事實,聊數據嘛。

Demo 準備

我看源碼的習慣是先搞個 Demo 把調試環境搭起來。然後帶着疑問去抽絲剝繭的 Debug,不放過在這個過程中在腦海裏面一閃而過的任何疑問。

這一小節分享的是Dubbo負載均衡策略之一最小活躍數(LeastActiveLoadBalance)。所以我先搭建一個 Dubbo 的項目,並啟動三個 provider 供 consumer 調用。

三個 provider 的 loadbalance 均配置的是 leastactive。權重分別是默認權重、200、300。

**默認權重是多少?**後面看源碼的時候,源碼會告訴你。

三個不同的服務提供者會給調用方返回自己是什麼權重的服務。

啟動三個實例。(注:上面的 provider.xml 和 DemoServiceImpl 其實只有一個,每次啟動的時候手動修改端口、權重即可。)

到 zookeeper 上檢查一下,服務提供者是否正常:

可以看到三個服務提供者分別在 20880、20881、20882 端口。(每個紅框的最後5個数字就是端口號)。

最後,我們再看服務消費者。消費者很簡單,配置consumer.xml

直接調用接口並打印返回值即可。

斷點打在哪?

相信很多朋友也很想看源碼,但是不知道從何處下手。處於一種在源碼裏面”亂逛”的狀態,一圈逛下來,收穫並不大。

這一部分我想分享一下我是怎麼去看源碼。首先我會帶着問題去源碼裏面尋找答案,即有針對性的看源碼。

如果是這種框架類的,正如上面寫的,我會先翻一翻官網(Dubbo 的官方文檔其實寫的挺好了),然後搭建一個簡單的 Demo 項目,然後 Debug 跟進去看。Debug 的時候當然需要是設置斷點的,那麼這個斷點如何設置呢?

第一個斷點,當然毋庸置疑,是打在調用方法的地方,比如本文中,第一個斷點是在這個地方:

接下里怎麼辦?

你當然可以從第一個斷點處,一步一步的跟進去。但是在這個過程中,你發現了嗎?大多數情況你都是被源碼牽着鼻子走的。本來你就只帶着一個問題去看源碼的,有可能你Debug了十分鐘,還沒找到關鍵的代碼。也有可能你Debug了十分鐘,問題從一個變成了無數個。

所以不要慌,我們點支煙,慢慢分析。

首先怎麼避免被源碼牽着四處亂逛呢?

我們得找到一個突破口,還記得我在《很開心,在使用mybatis的過程中我踩到一個坑》這篇文章中提到的逆向排查的方法嗎?這次的文章,我再次展示一下該方法。

看源碼之前,我們的目標要十分明確,就是想要找到 Dubbo 最小活躍數算法的具體實現類以及實現類的具體邏輯是什麼。

根據我們的 provider.xml 裏面的:

很明顯,我們知道 loadbalance 是關鍵字。所以我們拿着 loadbalance 全局搜索,可以看到 Dubbo 包下面的 LoadBalance。

這是一個 SPI 接口 com.alibaba.dubbo.rpc.cluster.LoadBalance:

其實現類為:

com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance

AbstractLoadBalance 是一個抽象類,該類裏面有一個抽象方法doSelect。這個抽象方法其中的一個實現類就是我們要分析的最少活躍次數負載均衡的源碼。

同時,到這裏我們知道了 LoadBalance 是一個 SPI 接口,說明我們可以擴展自己的負載均衡策略。抽象方法 doSelect 有四個實現類。這個四個實現類,就是 Dubbo 官方提供的負載均衡策略(截止 2.7.7 版本之前),他們分別是:

  1. ConsistentHashLoadBalance 一致性哈希算法
  2. LeastActiveLoadBalance 最小活躍數算法
  3. RandomLoadBalance 加權隨機算法
  4. RoundRobinLoadBalance 加權輪詢算法

我們已經找到了 LeastActiveLoadBalance 這個類了,那麼我們的第二個斷點打在哪裡已經很明確了。

目前看來,兩個斷點就可以支撐我們的分析了。

有的朋友可能想問,那我想知道 Dubbo 是怎麼識別出我們想要的是最少活躍次數算法,而不是其他的算法呢?其他的算法是怎麼實現的呢?從第一個斷點到第二個斷點直接有着怎樣的調用鏈呢?

在沒有徹底搞清楚最少活躍數算法之前,這些統統先記錄在案但不予理睬。一定要明確目標,帶着一個問題進來,就先把帶來的問題解決了。之後再去解決在這個過程中碰到的其他問題。在這樣環環相扣解決問題的過程中,你就慢慢的把握了源碼的精髓。這是我個人的一點看源碼的心得。供諸君參考。

模擬環境

既然叫做最小活躍數策略。那我們得讓現有的三個消費者都有一些調用次數。所以我們得改造一下服務提供者和消費者。

服務提供者端的改造如下:

!

PS:這裏以權重為 300 的服務端為例。另外的兩個服務端改造點相同。

客戶端的改造點如下:

一共發送 21 個請求:其中前 20 個先發到服務端讓其 hold 住(因為服務端有 sleep),最後一個請求就是我們需要 Debug 跟蹤的請求。

運行一下,讓程序停在斷點的地方,然後看看控制台的輸出:

權重為300的服務端共計收到9個請求

權重為200的服務端共計收到6個請求

默認權重的服務端共計收到5個請求

我們還有一個請求在 Debug。直接進入到我們的第二個斷點的位置,並 Debug 到下圖所示的一行代碼(可以點看查看大圖):

正如上面這圖所說的:weight=100 回答了一個問題,active=0 提出的一個問題。

weight=100 回答了什麼問題呢?

默認權重是多少?是 100。

我們服務端的活躍數分別應該是下面這樣的

  • 權重為300的服務端,active=9
  • 權重為200的服務端,active=6
  • 默認權重(100)的服務端,active=5

但是這裏為什麼截圖中的active會等於 0 呢?這是一個問題。

繼續往下 Debug 你會發現,每一個服務端的 active 都是 0。所以相比之下沒有一個 invoker 有最小 active 。於是程序走到了根據權重選擇 invoker 的邏輯中。

active為什麼是0?

active 為 0 說明在 Dubbo 調用的過程中 active 並沒有發生變化。那 active 為什麼是 0,其實就是在問 active 什麼時候發生變化

要回答這個問題我們得知道 active 是在哪裡定義的,因為在其定義的地方,必有其修改的方法。

下面這圖說明了active是定義在RpcStatus類裏面的一個類型為AtomicInteger 的成員變量。

在 RpcStatus 類中,有三處()調用 active 值的方法,一個增加、一個減少、一個獲取:

很明顯,我們需要看的是第一個,在哪裡增加。

所以我們找到了 beginCount(URL,String) 方法,該方法只有兩個 Filter 調用。ActiveLimitFilter,見名知意,這就是我們要找的東西。

com.alibaba.dubbo.rpc.filter.ActiveLimitFilter具體如下:

看到這裏,我們就知道怎麼去回答這個問題了:為什麼active是0呢?因為在客戶端沒有配置ActiveLimitFilter。所以,ActiveLimitFilter沒有生效,導致active沒有發生變化。

怎麼讓其生效呢?已經呼之欲出了。

好了,再來試驗一次:

加上Filter之後,我們通過Debug可以看到,對應權重的活躍數就和我們預期的是一致的了。

1.權重為300的活躍數為6

2.權重為200的活躍數為11

3.默認權重(100)的活躍數為3

根據活躍數我們可以分析出來,最後我們Debug住的這個請求,一定會選擇默認權重的invoker去執行,因為他是當前活躍數最小的invoker。如下所示:

雖然到這裏我們還沒開始進行源碼的分析,只是把流程梳理清楚了。但是把Demo完整的搭建了起來,而且知道了最少活躍數負載均衡算法必須配合ActiveLimitFilter使用,位於RpcStatus類的active字段才會起作用,否則,它就是一個基於權重的算法。

比起其他地方直接告訴你,要配置ActiveLimitFilter才行哦,我們自己實驗得出的結論,能讓我們的印象更加深刻。

我們再仔細看一下加上ActiveLimitFilter之後的各個服務的活躍數情況:

  • 權重為300的活躍數為6
  • 權重為200的活躍數為11
  • 默認權重(100)的活躍數為3

你不覺得奇怪嗎,為什麼權重為200的活躍數是最高的

其在業務上的含義是:我們有三台性能各異的服務器,A服務器性能最好,所以權重為300,B服務器性能中等,所以權重為200,C服務器性能最差,所以權重為100。

當我們選擇最小活躍次數的負載均衡算法時,我們期望的是性能最好的A服務器承擔更多的請求,而真實的情況是性能中等的B服務器承擔的請求更多。這與我們的設定相悖。

如果你說20個請求數據量太少,可能是巧合,不足以說明問題。說明你還沒被我帶偏,我們不能基於巧合編程。

所以為了驗證這個地方確實有問題,我把請求擴大到一萬個。

同時,記得擴大 provider 端的 Dubbo 線程池:

由於每個服務端運行的代碼都是一樣的,所以我們期望的結果應該是權重最高的承擔更多的請求。但是最終的結果如圖所示:

各個服務器均攤了請求。這就是我文章最開始的時候說的Dubbo 2.6.0 版本中最小活躍數負載均衡算法的Bug之一。

接下來,我們帶着這個問題,去分析源碼。

剖析源碼

com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance的源碼如下,我逐行進行了解讀。可以點開查看大圖,細細品讀,非常爽:

下圖中紅框框起來的部分就是一個基於權重選擇invoker的邏輯:

我給大家畫圖分析一下:

請仔細分析圖中給出的舉例說明。同時,上面這圖也是按照比例畫的,可以直觀的看到,對於某一個請求,區間(權重)越大的服務器,就越可能會承擔這個請求。所以,當請求足夠多的時候,各個服務器承擔的請求數,應該就是區間,即權重的比值。

其中第 81 行有調用 getWeight 方法,位於抽象類 AbstractLoadBalance 中,也需要進行重點解讀的代碼。

com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance 的源碼如下,我也進行了大量的備註:

在 AbstractLoadBalance 類中提到了一個預熱的概念。官網中是這樣的介紹該功能的:

權重的計算過程主要用於保證當服務運行時長小於服務預熱時間時,對服務進行降權,避免讓服務在啟動之初就處於高負載狀態。服務預熱是一個優化手段,與此類似的還有 JVM 預熱。主要目的是讓服務啟動后“低功率”運行一段時間,使其效率慢慢提升至最佳狀態。

從上圖代碼裏面的公式(演變后):*計算后的權重=(uptime/warmup)weight 可以看出:隨着服務啟動時間的增加(uptime),計算后的權重會越來越接近weight。從實際場景的角度來看,隨着服務啟動時間的增加,服務承擔的流量會慢慢上升,沒有一個陡升的過程。所以這是一個優化手段。同時 Dubbo 接口還支持延遲暴露。

在仔細的看完上面的源碼解析圖后,配合官網的總結加上我的靈魂畫作,相信你可以對最小活躍數負載均衡算法有一個比較深入的理解:

  1. 遍歷 invokers 列表,尋找活躍數最小的 Invoker
  2. 如果有多個 Invoker 具有相同的最小活躍數,此時記錄下這些 Invoker 在 invokers 集合中的下標,並累加它們的權重,比較它們的權重值是否相等
  3. 如果只有一個 Invoker 具有最小的活躍數,此時直接返回該 Invoker 即可
  4. 如果有多個 Invoker 具有最小活躍數,且它們的權重不相等,此時處理方式和 RandomLoadBalance 一致
  5. 如果有多個 Invoker 具有最小活躍數,但它們的權重相等,此時隨機返回一個即可

所以我覺得最小活躍數負載均衡的全稱應該叫做:有最小活躍數用最小活躍數,沒有最小活躍數根據權重選擇,權重一樣則隨機返回的負載均衡算法。

Bug在哪裡?

Dubbo2.6.0最小活躍數算法Bug一

問題出在標號為 ① 和 ② 這兩行代碼中:

標號為 ① 的代碼在url中取出的是沒有經過 getWeight 方法降權處理的權重值,這個值會被累加到權重總和(totalWeight)中。

標號為 ② 的代碼取的是經過 getWeight 方法處理后的權重值。

取值的差異會導致一個問題,標號為 ② 的代碼的左邊,offsetWeight 是一個在 [0,totalWeight) 範圍內的隨機數,右邊是經過 getWeight 方法降權后的權重。所以在經過 leastCount 次的循環減法后,offsetWeight 在服務啟動時間還沒到熱啟動設置(默認10分鐘)的這段時間內,極大可能仍然大於 0。導致不會進入到標號為 ③ 的代碼中。直接到標號為 ④ 的代碼處,變成了隨機調用策略。這與設計不符,所以是個 bug。

前面章節說的情況就是這個Bug導致的。

這個Bug對應的issues地址和pull request分為:

https://github.com/apache/dubbo/issues/904

https://github.com/apache/dubbo/pull/2172

那怎麼修復的呢?我們直接對比 Dubbo 2.7.4.1 的代碼:

可以看到獲取weight的方法變了:從url中直接獲取變成了通過getWeight方法獲取。獲取到的變量名稱也變了:從weight變成了afterWarmup,更加的見名知意。

還有一處變化是獲取隨機值的方法的變化,從Randmo變成了ThreadLoaclRandom,性能得到了提升。這處變化就不展開講了,有興趣的朋友可以去了解一下。

Dubbo2.6.0最小活躍數算法Bug二

這個Bug我沒有遇到,但是我在官方文檔上看了其描述(官方文檔中的版本是2.6.4),引用如下:

官網上說這個問題在2.6.5版本進行修復。我對比了2.6.0/2.6.5/2.7.4.1三個版本,發現每個版本都略有不同。如下所示:

圖中標記為①的三處代碼:

2.6.0版本的是有Bug的代碼,原因在上面說過了。

2.6.5版本的修復方式是獲取隨機數的時候加一,所以取值範圍就從**[0,totalWeight)變成了[0,totalWeight]**,這樣就可以避免這個問題。

2.7.4.1版本的取值範圍還是[0,totalWeight),但是它的修復方法體現在了標記為②的代碼處。2.6.0/2.6.5版本標記為②的地方都是if(offsetWeight<=0),而2.7.4.1版本變成了if(offsetWeight<0)

你品一品,是不是效果是一樣的,但是更加優雅了。

朋友們,魔鬼,都在細節里啊!

好了,進入下一議題。

一致性哈希負載均衡

這一部分是對於Dubbo負載均衡策略之一的一致性哈希負載均衡的詳細分析。對源碼逐行解讀、根據實際運行結果,配以豐富的圖片,可能是東半球講一致性哈希算法在Dubbo中的實現最詳細的文章了。

本小節所示源碼,沒有特別標註的地方,均為2.7.4.1版本。

在撰寫本文的過程中,發現了Dubbo2.7.0版本之後的一個bug。會導致性能問題,如果你們的負載均衡配置的是一致性哈希或者考慮使用一致性哈希的話,可以了解一下。

哈希算法

在介紹一致性哈希算法之前,我們看看哈希算法,以及它解決了什麼問題,帶來了什麼問題。

如上圖所示,假設0,1,2號服務器都存儲的有用戶信息,那麼當我們需要獲取某用戶信息時,因為我們不知道該用戶信息存放在哪一台服務器中,所以需要分別查詢0,1,2號服務器。這樣獲取數據的效率是極低的。

對於這樣的場景,我們可以引入哈希算法。

還是上面的場景,但前提是每一台服務器存放用戶信息時是根據某一種哈希算法存放的。所以取用戶信息的時候,也按照同樣的哈希算法取即可。

假設我們要查詢用戶號為100的用戶信息,經過某個哈希算法,比如這裏的userId mod n,即100 mod 3結果為1。所以用戶號100的這個請求最終會被1號服務器接收並處理。

這樣就解決了無效查詢的問題。

但是這樣的方案會帶來什麼問題呢?

擴容或者縮容時,會導致大量的數據遷移。最少也會影響百分之50的數據。

為了說明問題,我們加入一台服務器3。服務器的數量n就從3變成了4。還是查詢用戶號為100的用戶信息時,100 mod 4結果為0。這時,請求就被0號服務器接收了。

當服務器數量為3時,用戶號為100的請求會被1號服務器處理。

當服務器數量為4時,用戶號為100的請求會被0號服務器處理。

所以,當服務器數量增加或者減少時,一定會涉及到大量數據遷移的問題。可謂是牽一發而動全身。

對於上訴哈希算法其優點是簡單易用,大多數分庫分表規則就採取的這種方式。一般是提前根據數據量,預先估算好分區數。

缺點是由於擴容或收縮節點導致節點數量變化時,節點的映射關係需要重新計算,會導致數據進行遷移。所以擴容時通常採用翻倍擴容,避免數據映射全部被打亂,導致全量遷移的情況,這樣只會發生50%的數據遷移。

假設這是一個緩存服務,數據的遷移會導致在遷移的時間段內,有緩存是失效的。

緩存失效,可怕啊。還記得我之前的文章嗎,《當周杰倫把QQ音樂干翻的時候,作為程序猿我看到了什麼?》就是講緩存擊穿、緩存穿透、緩存雪崩的場景和對應的解決方案。

一致性哈希算法

為了解決哈希算法帶來的數據遷移問題,一致性哈希算法應運而生。

對於一致性哈希算法,官方說法如下:

一致性哈希算法在1997年由麻省理工學院提出,是一種特殊的哈希算法,在移除或者添加一個服務器時,能夠盡可能小地改變已存在的服務請求與處理請求服務器之間的映射關係。一致性哈希解決了簡單哈希算法在分佈式哈希表( Distributed Hash Table,DHT) 中存在的動態伸縮等問題。

什麼意思呢?我用大白話加畫圖的方式給你簡單的介紹一下。

一致性哈希,你可以想象成一個哈希環,它由0到2^32-1個點組成。A,B,C分別是三台服務器,每一台的IP加端口經過哈希計算后的值,在哈希環上對應如下:

當請求到來時,對請求中的某些參數進行哈希計算后,也會得出一個哈希值,此值在哈希環上也會有對應的位置,這個請求會沿着順時針的方向,尋找最近的服務器來處理它,如下圖所示:

一致性哈希就是這麼個東西。那它是怎麼解決服務器的擴容或收縮導致大量的數據遷移的呢?

看一下當我們使用一致性哈希算法時,加入服務器會發什麼事情。

當我們加入一個D服務器后,假設其IP加端口,經過哈希計算后落在了哈希環上圖中所示的位置。

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

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

這時影響的範圍只有圖中標註了五角星的區間。這個區間的請求從原來的由C服務器處理變成了由D服務器請求。而D到C,C到A,A到B這個區間的請求沒有影響,加入D節點后,A、B服務器是無感知的。

所以,在一致性哈希算法中,如果增加一台服務器,則受影響的區間僅僅是新服務器(D)在哈希環空間中,逆時針方向遇到的第一台服務器(B)之間的區間,其它區間(D到C,C到A,A到B)不會受到影響。

在加入了D服務器的情況下,我們再假設一段時間后,C服務器宕機了:

當C服務器宕機后,影響的範圍也是圖中標註了五角星的區間。C節點宕機后,B、D服務器是無感知的。

所以,在一致性哈希算法中,如果宕機一台服務器,則受影響的區間僅僅是宕機服務器(C)在哈希環空間中,逆時針方向遇到的第一台服務器(D)之間的區間,其它區間(C到A,A到B,B到D)不會受到影響。

綜上所述,在一致性哈希算法中,不管是增加節點,還是宕機節點,受影響的區間僅僅是增加或者宕機服務器在哈希環空間中,逆時針方向遇到的第一台服務器之間的區間,其它區間不會受到影響。

是不是很完美?

不是的,理想和現實的差距是巨大的。

一致性哈希算法帶來了什麼問題?

當節點很少的時候可能會出現這樣的分佈情況,A服務會承擔大部分請求。這種情況就叫做數據傾斜。

怎麼解決數據傾斜呢?加入虛擬節點。

怎麼去理解這個虛擬節點呢?

首先一個服務器根據需要可以有多個虛擬節點。假設一台服務器有n個虛擬節點。那麼哈希計算時,可以使用IP+端口+編號的形式進行哈希值計算。其中的編號就是0到n的数字。由於IP+端口是一樣的,所以這n個節點都是指向的同一台機器。

如下圖所示:

在沒有加入虛擬節點之前,A服務器承擔了絕大多數的請求。但是假設每個服務器有一個虛擬節點(A-1,B-1,C-1),經過哈希計算后落在了如上圖所示的位置。那麼A服務器的承擔的請求就在一定程度上(圖中標註了五角星的部分)分攤給了B-1、C-1虛擬節點,實際上就是分攤給了B、C服務器。

一致性哈希算法中,加入虛擬節點,可以解決數據傾斜問題。

當你在面試的過程中,如果聽到了類似於數據傾斜的字眼。那大概率是在問你一致性哈希算法和虛擬節點。

在介紹了相關背景后,我們可以去看看一致性哈希算法在Dubbo中的應用了。

一致性哈希算法在Dubbo中的應用

前面我們說了Dubbo中負載均衡的實現是通過org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance中的 doSelect 抽象方法實現的,一致性哈希負載均衡的實現類如下所示:

org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance

由於一致性哈希實現類看起來稍微有點抽象,不太好演示,所以我想到了一個”騷”操作。前面的文章說過 LoadBalance 是一個 SPI 接口:

既然是一個 SPI 接口,那我們可以自己擴展一個一模一樣的算法,只是在算法裏面加入一點輸出語句方便我們觀察情況。怎麼擴展 SPI 接口就不描述了,只要記住代碼裏面的輸出語句都是額外加的,此外沒有任何改動即可,如下:

整個類如下圖片所示,請先看完整個類,有一個整體的概念后,我會進行方法級別的分析。

圖片很長,其中我加了很多註釋和輸出語句,可以點開大圖查看,一定會幫你更加好的理解一致性哈希在Dubbo中的應用:

改造之後,我們先把程序跑起來,有了輸出就好分析了。

服務端代碼如下:

其中的端口是需要手動修改的,我分別啟動服務在20881和20882端口。

項目中provider.xml配置如下:

consumer.xml配置如下:

然後,啟動在20881和20882端口分別啟動兩個服務端。客戶端消費如下:

運行結果輸出如下,可以先看個大概的輸出,下面會對每一部分輸出進行逐一的解讀

好了,用例也跑起來了,日誌也有了。接下來開始結合代碼和日誌進行方法級別的分析。

首先是doSelect方法的入口:

從上圖我們知道了,第一次調用需要對selectors進行put操作,selectors的 key 是接口中定義的方法,value 是 ConsistentHashSelector 內部類

ConsistentHashSelector通過調用其構造函數進行初始化的。invokers(服務端)作為參數傳遞到了構造函數中,構造函數裏面的邏輯,就是把服務端映射到哈希環上的過程,請看下圖,結合代碼,仔細分析輸出數據:

從上圖可以看出,當 ConsistentHashSelector 的構造方法調用完成后,8個虛擬節點在哈希環上已經映射完成。兩台服務器,每一台4個虛擬節點組成了這8個虛擬節點。

doSelect方法繼續執行,並打印出每個虛擬節點的哈希值和對應的服務端,請仔細品讀下圖:

說明一下:上面圖中的哈希環是沒有考慮比例的,僅僅是展現了兩個服務器在哈希環上的相對位置。而且為了演示說明方便,僅僅只有8個節點。假設我們有4台服務器,每台服務器的虛擬節點是默認值(160),這個情況下哈希環上一共有160*4=640個節點。

哈希環映射完成后,接下來的邏輯是把這次請求經過哈希計算后,映射到哈希環上,並順時針方向尋找遇到的第一個節點,讓該節點處理該請求:

還記得地址為 468e8565 的 A 服務器是什麼端口嗎?前面的圖片中有哦,該服務對應的端口是 20882 。

最後我們看看輸出結果:

和我們預期的一致。整個調用就算是完成了。

再對兩個方法進行一個補充說明。

第一個方法是 selectForKey,這個方法裏面邏輯如下圖所示:

虛擬節點都存儲在 TreeMap 中。順時針查詢的邏輯由 TreeMap 保證。看一下下面的 Demo 你就明白了。

第二個方法是 hash 方法,其中的 & 0xFFFFFFFFL 的目的如下:

&是位運算符,而 0xFFFFFFFFL 轉換為四字節表現后,其低32位全是1,所以保證了哈希環的範圍是 [0,Integer.MAX_VALUE]:

所以這裏我們可以改造這個哈希環的範圍,假設我們改為 100000。十進制的 100000 對於的 16 進製為 186A0 。所以我們改造后的哈希算法為:

再次調用后可以看到,計算后的哈希值都在10萬以內。但是分佈極不均勻,說明修改數據后這個哈希算法不是一個優秀的哈希算法:

以上,就是對一致性哈希算法在Dubbo中的實現的解讀。需要特殊說明一下的是,一致性哈希負載均衡策略和權重沒有任何關係

我又發現了一個BUG

前面我介紹了Dubbo 2.6.5版本之前,最小活躍數算法的兩個 bug。

很不幸,這次我又發現了Dubbo 2.7.4.1版本,一致性哈希負載均衡策略的一個bug,我提交了issue 地址如下:

https://github.com/apache/dubbo/issues/5429

我在這裏詳細說一下這個Bug現象、原因和我的解決方案。

現象如下,我們調用三次服務端:

輸出日誌如下(有部分刪減):

可以看到,在三次調用的過程中並沒有發生服務的上下線操作,但是每一次調用都重新進行了哈希環的映射。而我們預期的結果是應該只有在第一次調用的時候進行哈希環的映射,如果沒有服務上下線的操作,後續請求根據已經映射好的哈希環進行處理。

上面輸出的原因是由於每次調用的invokers的identityHashCode發生了變化:

我們看一下三次調用invokers的情況:

經過debug我們可以看出因為每次調用的invokers地址值不是同一個,所以System.identityHashCode(invokers)方法返回的值都不一樣。

接下來的問題就是為什麼每次調用的invokers地址值都不一樣呢?

經過Debug之後,可以找到這個地方:

org.apache.dubbo.rpc.cluster.RouterChain#route

問題就出在這個TagRouter中:

org.apache.dubbo.rpc.cluster.router.tag.TagRouter#filterInvoker

所以,在TagRouter中的stream操作,改變了invokers,導致每次調用時其

System.identityHashCode(invokers)返回的值不一樣。所以每次調用都會進行哈希環的映射操作,在服務節點多,虛擬節點多的情況下會有一定的性能問題。

到這一步,問題又發生了變化。這個TagRouter怎麼來的呢

如果了解Dubbo 2.7.x版本新特性的朋友可能知道,標籤路由是Dubbo2.7引入的新功能。

通過加載下面的配置加載了RouterFactrory:

META-INF\dubbo\internal\org.apache.dubbo.rpc.cluster.RouterFactory(Dubbo 2.7.0版本之前)

META-INF\dubbo\internal\com.alibaba.dubbo.rpc.cluster.RouterFactory(Dubbo 2.7.0之前)

下面是Dubbo 2.6.7(2.6.x的最後一個版本)和Dubbo 2.7.0版本該文件的對比:

可以看到確實是在 Dubbo 2.7.0 之後引入了 TagRouter。

至此,Dubbo 2.7.0 版本之後,一致性哈希負載均衡算法的 Bug 的來龍去脈也介紹清楚了。

解決方案是什麼呢?特別簡單,把獲取 identityHashCode 的方法從 System.identityHashCode(invokers) 修改為 invokers.hashCode() 即可。

此方案是我提的 issue 裏面的評論,這裏 System.identityHashCode 和 hashCode 之間的聯繫和區別就不進行展開講述了,不清楚的大家可以自行了解一下。

(我的另外一篇文章:夠強!一行代碼就修復了我提的Dubbo的Bug。)

改完之後,我們再看看運行效果:

可以看到第二次調用的時候並沒有進行哈希環的映射操作,而是直接取到了值,進行調用。

加入節點,畫圖分析

最後,我再分析一種情況。在A、B、C三個服務器(20881、20882、20883端口)都在正常運行,哈希映射已經完成的情況下,我們再啟動一個D節點(20884端口),這時的日誌輸出和對應的哈希環變化情況如下:

根據日誌作圖如下:

根據輸出日誌和上圖再加上源碼,你再細細回味一下。我個人覺得還是講的非常詳細了。

一致性哈希的應用場景

當大家談到一致性哈希算法的時候,首先的第一印象應該是在緩存場景下的使用,因為在一個優秀的哈希算法加持下,其上下線節點對整體數據的影響(遷移)都是比較友好的。

但是想一下為什麼 Dubbo 在負載均衡策略裏面提供了基於一致性哈希的負載均衡策略?它的實際使用場景是什麼?

我最開始也想不明白。我想的是在 Dubbo 的場景下,假設需求是想要一個用戶的請求一直讓一台服務器處理,那我們可以採用一致性哈希負載均衡策略,把用戶號進行哈希計算,可以實現這樣的需求。但是這樣的需求未免有點太牽強了,適用場景略小。

直到有天晚上,我睡覺之前,電光火石之間突然想到了一個稍微適用的場景了。

如果需求是需要保證某一類請求必須順序處理呢?

如果你用其他負載均衡策略,請求分發到了不同的機器上去,就很難保證請求的順序處理了。比如A,B請求要求順序處理,現在A請求先發送,被負載到了A服務器上,B請求后發送,被負載到了B服務器上。而B服務器由於性能好或者當前沒有其他請求或者其他原因極有可能在A服務器還在處理A請求之前就把B請求處理完成了。這樣不符合我們的要求。

這時,一致性哈希負載均衡策略就上場了,它幫我們保證了某一類請求都發送到固定的機器上去執行。比如把同一個用戶的請求發送到同一台機器上去執行,就意味着把某一類請求發送到同一台機器上去執行。所以我們只需要在該機器上運行的程序中保證順序執行就行了,比如你加一個隊列。

一致性哈希算法+隊列,可以實現順序處理的需求。

好了,一致性哈希負載均衡算法就寫到這裏。

繼續進入下一個議題。

加權輪詢負載均衡

這一小節是對於Dubbo負載均衡策略之一的加權隨機算法的詳細分析。

從 2.6.4 版本聊起,該版本在某些情況下存在着比較嚴重的性能問題。由問題入手,層層深入,了解該算法在 Dubbo 中的演變過程,讀懂它的前世今生。

什麼是輪詢?

在描述加權輪詢之前,先解釋一下什麼是輪詢算法,如下圖所示:

假設我們有A、B、C三台服務器,共計處理6個請求,服務處理請求的情況如下:

  1. 第一個請求發送給了A服務器
  2. 第二個請求發送給了B服務器
  3. 第三個請求發送給了C服務器
  4. 第四個請求發送給了A服務器
  5. 第五個請求發送給了B服務器
  6. 第六個請求發送給了C服務器
  7. ……

上面這個例子演示的過程就叫做輪詢。可以看出,所謂輪詢就是將請求輪流分配給每台服務器

輪詢的優點是無需記錄當前所有服務器的鏈接狀態,所以它一種無狀態負載均衡算法,實現簡單,適用於每台服務器性能相近的場景下。

輪詢的缺點也是顯而易見的,它的應用場景要求所有服務器的性能都相同,非常的局限。

大多數實際情況下,服務器性能是各有差異,針對性能好的服務器,我們需要讓它承擔更多的請求,即需要給它配上更高的權重。

所以加權輪詢,應運而生。

什麼是加權輪詢?

為了解決輪詢算法應用場景的局限性。當遇到每台服務器的性能不一致的情況,我們需要對輪詢過程進行加權,以調控每台服務器的負載。

經過加權后,每台服務器能夠得到的請求數比例,接近或等於他們的權重比。比如服務器 A、B、C 權重比為 5:3:2。那麼在10次請求中,服務器 A 將收到其中的5次請求,服務器 B 會收到其中的3次請求,服務器 C 則收到其中的2次請求。

這裏要和加權隨機算法做區分哦。直接把前面介紹的加權隨機算法畫的圖拿過來:

上面這圖是按照比例畫的,可以直觀的看到,對於某一個請求,區間(權重)越大的服務器,就越可能會承擔這個請求。所以,當請求足夠多的時候,各個服務器承擔的請求數,應該就是區間,即權重的比值。

假設有A、B、C三台服務器,權重之比為5:3:2,一共處理10個請求。

那麼負載均衡採用加權隨機算法時,很有可能A、B服務就處理完了這10個請求,因為它是隨機調用。

採用負載均衡採用輪詢加權算法時,A、B、C服務一定是分別承擔5、3、2個請求。

Dubbo2.6.4版本的實現

對於Dubbo2.6.4版本的實現分析,可以看下圖,我加了很多註釋,其中的輸出語句都是我加的:

示例代碼還是沿用之前文章中的Demo,這裏分別在 20881、20882、20883 端口啟動三個服務,各自的權重分別為 1,2,3。

客戶端調用 8 次:

輸出結果如下:

可以看到第七次調用后mod=0,回到了第一次調用的狀態。形成了一個閉環。

再看看判斷的條件是什麼:

其中mod在代碼中扮演了極其重要的角色,mod根據一個方法的調用次數不同而不同,取值範圍是[0,weightSum)。

因為weightSum=6,所以列舉mod不同值時,最終的選擇結果和權重變化:

可以看到20881,20882,20883承擔的請求數量比值為1:2:3。同時我們可以看出,當 mod >= 1 后,20881端口的服務就不會被選中了,因為它的權重被減為0了。當 mod >= 4 后,20882端口的服務就不會被選中了,因為它的權重被減為0了。

結合判斷條件和輸出結果,我們詳細分析一下(下面內容稍微有點繞,如果看不懂,多結合上面的圖片看幾次):

第一次調用

mod=0,第一次循環就滿足代碼塊①的條件,直接返回當前循環的invoker,即20881端口的服務。此時各端口的權重情況如下:

第二次調用

mod=1,需要進入代碼塊②,對mod進行一次遞減。

第一次循環對20881端口的服務權重減一,mod-1=0。

第二次循環,mod=0,循環對象是20882端口的服務,權重為2,滿足代碼塊①,返回當前循環的20882端口的服務。

此時各端口的權重情況如下:

第三次調用

mod=2,需要進入代碼塊②,對mod進行兩次遞減。

第一次循環對20881端口的服務權重減一,mod-1=1;

第二次循環對20882端口的服務權重減一,mod-1=0;

第三次循環時,mod已經為0,當前循環的是20883端口的服務,權重為3,滿足代碼塊①,返回當前循環的20883端口的服務。

此時各端口的權重情況如下:

第四次調用

mod=3,需要進入代碼塊②,對mod進行三次遞減。

第一次循環對20881端口的服務權重減一,從1變為0,mod-1=2;

第二次循環對20882端口的服務權重減一,從2變為1,mod-1=1;

第三次循環對20883端口的服務權重減一,從3變為2,mod-1=0;

第四次循環的是20881端口的服務,此時mod已經為0,但是20881端口的服務的權重已經變為0了,不滿足代碼塊①和代碼塊②,進入第五次循環。

第五次循環的是20882端口的服務,當前權重為1,mod=0,滿足代碼塊①,返回20882端口的服務。

此時各端口的權重情況如下:

第五次調用

mod=4,需要進入代碼塊②,對mod進行四次遞減。

第一次循環對20881端口的服務權重減一,從1變為0,mod-1=3;

第二次循環對20882端口的服務權重減一,從2變為1,mod-1=2;

第三次循環對20883端口的服務權重減一,從3變為2,mod-1=1;

第四次循環的是20881端口的服務,此時mod為1,但是20881端口的服務的權重已經變為0了,不滿足代碼塊②,mod不變,進入第五次循環。

第五次循環時,mod為1,循環對象是20882端口的服務,權重為1,滿足代碼塊②,權重從1變為0,mod從1變為0,進入第六次循環。

第六次循環時,mod為0,循環對象是20883端口的服務,權重為2,滿足條件①,返回當前20883端口的服務。

此時各端口的權重情況如下:

第六次調用

第六次調用,mod=5,會循環九次,最終選擇20883端口的服務,讀者可以自行分析一波,分析出來了,就了解的透透的了。

第七次調用

第七次調用,又回到mod=0的狀態:

2.6.4版本的加權輪詢就分析完了,但是事情並沒有這麼簡單。這個版本的加權輪詢是有性能問題的。

該問題對應的issue地址如下:

https://github.com/apache/dubbo/issues/2578

問題出現在invoker返回的時機上:

截取issue裏面的一個回答:

10分鐘才選出一個invoker,還怎麼玩?

有時間可以讀一讀這個issue,裏面各路大神針對該問題進行了激烈的討論,第一種改造方案被接受后,很快就被推翻,被第二種方案代替,可以說優化思路十分值得學習,很精彩,接下來的行文路線就是按照該issue展開的。

推翻,重建。

上面的代碼時間複雜度是O(mod),而第一次修復之後時間複雜度降低到了常量級別。可以說是一次非常優秀的優化,值得我們學習,看一下優化之後的代碼:

其關鍵優化的點是這段代碼,我加入輸出語句,便於分析。

輸出日誌如下:

把上面的輸出轉化到表格中去,7次請求的選擇過程如下:

該算法的原理是:

把服務端都放到集合中(invokerToWeightList),然後獲取服務端個數(length),並計算出服務端權重最大的值(maxWeight)。

index表示本次請求到來時,處理該請求的服務端下標,初始值為0,取值範圍是[0,length)。

currentWeight表示當前調度的權重,初始值為0,取值範圍是[0,maxWeight)。

當請求到來時,從index(就是0)開始輪詢服務端集合(invokerToWeightList),如果是一輪循環的開始(index=0)時,則對currentWeight進行加一操作(不會超過maxWeight),在循環中找出第一個權重大於currentWeight的服務並返回。

這裏說的一輪循環是指index再次變為0所經歷過的循環,這裏可以把index=0看做是一輪循環的開始。每一輪循環的次數與Invoker的數量有關,Invoker數量通常不會太多,所以我們可以認為上面代碼的時間複雜度為常數級。

從issue上看出,這個算法最終被merged了。

但是很快又被推翻了:

這個算法不夠平滑。什麼意思呢?

翻譯一下上面的內容就是:服務器[A, B, C]對應權重[5, 1, 1]。進行7次負載均衡后,選擇出來的序列為[A, A, A, A, A, B, C]。前5個請求全部都落在了服務器A上,這將會使服務器A短時間內接收大量的請求,壓力陡增。而B和C此時無請求,處於空閑狀態。而我們期望的結果是這樣的[A, A, B, A, C, A, A],不同服務器可以穿插獲取請求。

我們設置20881端口的權重為5,20882、20883端口的權重均為1。

進行實驗,發現確實如此:可以看到一共進行7次請求,第1次到5次請求都分發給了權重為5的20881端口的服務,前五次請求,20881和20882都處於空閑狀態:

轉化為表格如下:

從表格的最終結果一欄也可以直觀的看出,七次請求對應的服務器端口為:

分佈確實不夠均勻。

再推翻,再重建,平滑加權。

從issue中可以看到,再次重構的加權算法的靈感來源是Nginx的平滑加權輪詢負載均衡

看代碼之前,先介紹其計算過程。

假設每個服務器有兩個權重,一個是配置的weight,不會變化,一個是currentWeight會動態調整,初始值為0。當有新的請求進來時,遍歷服務器列表,讓它的currentWeight加上自身權重。遍歷完成后,找到最大的currentWeight,並將其減去權重總和,然後返回相應的服務器即可。

如果你還是不知道上面的表格是如何算出來的,我再給你詳細的分析一下第1、2個請求的計算過程:

第一個請求計算過程如下:

第二個請求計算過程如下:

後面的請求你就可以自己分析了。

從表格的最終結果一欄也可以直觀的看出,七次請求對應的服務器端口為:

可以看到,權重之比同樣是5:1:1,但是最終的請求分發的就比較的”平滑”。對比一下:

對於平滑加權算法,我想多說一句。我覺得這個算法非常的神奇,我是徹底的明白了它每一步的計算過程,知道它最終會形成一個閉環,但是我想了很久,我還是不知道背後的數學原理是什麼,不明白為什麼會形成一個閉環,非常的神奇。

很正常,我不糾結的,程序猿的工作不就是這樣嗎?我也不知道為什麼,它能工作。別問,問就是玄學,如果一定要說出點什麼的話,我想,我願稱之為:絕活吧。

但是我們只要能夠理解我前面所表達的平滑加權輪詢算法的計算過程,知道其最終會形成閉環,就能理解下面的代碼。配合代碼中的註釋食用,效果更佳。

以下代碼以及註釋來源官網:

http://dubbo.apache.org/zh-cn/docs/source_code_guide/loadbalance.html

總結

好了,到這裏關於Dubbo的五種負載均衡策略就講完了。簡單總結一下:(加權隨機算法在講最小活躍數算法的時候提到過,因為原理十分簡單,這裏就不專門拿出章節來描述了。)

最短響應時間負載均衡:在所有服務提供者中選出平均響應時間最短的一個,如果能選出來,則使用選出來的一個。如果不能選出來多個,再根據權重選,如果權重也一樣,則隨機選擇。

一致性哈希負載均衡:在一致性哈希算法中,不管是增加節點,還是宕機節點,受影響的區間僅僅是增加或者宕機服務器在哈希環空間中,逆時針方向遇到的第一台服務器之間的區間,其它區間不會受到影響。為了解決數據傾斜的問題,引入了虛擬節點的概念。一致性哈希算法是 Dubbo 中唯一一個與權重沒有任何關係的負載均衡算法,可以保證相同參數的請求打到同一台機器上。

最小活躍數負載均衡:需要配合 activeFilter 使用,活躍數在方法調用前後進行維護,響應越快的服務器堆積的請求越少,對應的活躍數也少。Dubbo 在選擇的時候遵循下面的規則,有最小活躍數用最小活躍數,沒有最小活躍數根據權重選擇,權重一樣則隨機返回的負載均衡算法。

加權隨機算法:隨機,顧名思義,就是從多個服務提供者中隨機選擇一個出來。加權,就是指需要按照權重設置隨機概率。常見場景就是對於性能好的機器可以把對應的權重設置的大一點,而性能相對較差的,權重設置的小一點。哎,像極了這個社會上的某些現象,對外宣傳是隨機搖號,背後指不定有一群權重高的人呢。

加權輪詢負載均衡:輪詢就是雨露均沾的意思,所有的服務提供者都需要調用。而當輪詢遇到加權則可以讓請求(不論多少)嚴格按照我們的權重之比進行分配。比如有A、B、C三台服務器,權重之比為5:3:2,一共處理10個請求。那麼採用負載均衡採用輪詢加權算法時,A、B、C服務一定是分別承擔5、3、2個請求。同時需要注意的是加權輪詢算法的兩次升級過程,以及最終的“平滑”的解決方案。

再說一件事

本文主要聊的是負載均衡嘛,讓我想起了 2019 年阿里巴巴第五屆中間件挑戰賽的初賽賽題也是實現一個負載均衡策略。

具體的賽題可以看這裏:

https://tianchi.aliyun.com/competition/entrance/231714/information

這種比賽還是很有意思的,你報名之後僅僅是讀懂賽題,然後自己多想想怎麼實現,哪怕是不提交代碼,在比賽完成后看前幾名的賽題分析,再去把他們的代碼拉下來看看,你就會發現,其實最終的思路都大同小異,差別會體現在參數調優和代碼優化程度上。

當然最大的差別還是會體現在語言的層面。如果不限制參數語言的話,Java 系的选手一定是被 C 系选手吊打的。

但是,被吊打不重要,重要的是真的能學到很多的東西,而這些東西,在絕大部分工作中是很難學到的。

最近,阿里巴巴第六屆中間件挑戰賽也開始了,可以看一下這個鏈接:

https://tianchi.aliyun.com/competition/entrance/231790/introduction?spm=5176.12281968.1008.3.65818188YmzFqa

這次是分為三個賽道,選擇性更多了。

作為這個比賽的長期關注者(持續關注三年了吧),這次作為一個自來水免費宣傳一波。

朋友,我真心建議你去看一下,報個名,玩一玩,收穫真的很大的。

當然,如果能在報名的時候邀請人那一欄填【why技術】,我真心感謝你。

最後說一句(求關注)

點個“贊”吧,周更很累的,不要白嫖我,需要一點正反饋。

才疏學淺,難免會有紕漏,如果你發現了錯誤的地方,還請你留言指出來,我對其加以修改。

感謝您的閱讀,我堅持原創,十分歡迎並感謝您的關注。

我是 why,一個被代碼耽誤的文學創作者,不是大佬,但是喜歡分享,是一個又暖又有料的四川好男人。

歡迎關注我的微信公眾號:why技術。在這裏我會分享一些java技術相關的知識,用匠心敲代碼,對每一行代碼負責。偶爾也會荒腔走板的聊一聊生活,寫一寫書評、影評。感謝你的關注,願你我共同進步。

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

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

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

這款2.0L全新SUV氣場堪比寶馬X6!上市后13萬內就賣瘋_包裝設計

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

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

不過遺憾的是T90並沒有配備群眾們喜聞樂見的全景天窗,只是尺寸也不算很大的普通天窗。乘坐空間這一點對於國內消費者來說就是重中之重了,國人就是喜歡大尺寸、大空間,畢竟拖家帶口空間小了坐着確實憋屈。T90的座椅使用了和天籟同級的人體工程學座椅,座椅填充物柔軟,舒適性和包裹性都非常好,絕對也能稱得上是移動大沙發。

前段時間小編去體驗了一把國產版寶馬X6-啟辰T90,之所以說是X6,是因為在外形上,T90和X6看起來確實比較像。T90定位中型轎跑型SUV,上市之後將會成為啟辰的旗艦車型。預售價將會在廣州車展上公布。

由於是中型SUV,所以T90的尺寸自然不會小,長寬高為4793*1865*1592mm,軸距為2765mm,個頭算是挺大的了。因為是溜背的造型,再加上較長的車身,所以側面來看T90顯得很修長,同時空載的時候最小離地間隙為194mm,通過性還是不錯的。不過最吸引人的是廠家宣稱T90是啟辰“風雕美學”設計理念的第一款車型,整車原創度非常高,同時別緻的前進氣格柵也使T90讓人眼前一亮。

到了車內,大家會發現T90的原創度會更高了,內飾不管是做工還是用料,都是十分的用心。新車的氣味較小,可見內飾選材還是比較嚴格的。同時配置又很高,尤其是中控那個高達12.3英寸的大屏幕,絕對很奪人眼球,同時它的分辨率高達1920*768,畫面清晰,運行流暢,

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

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

沒有遇到卡頓的情況。同時它還可以分屏显示,左側小屏幕显示菜單功能,不會影響右側屏幕的显示。配備百度CarLife系統,這是啟辰和百度合作開發的,可以鏈接安卓和蘋果手機,功能豐富。

不單中控做的好,內飾用料也很不錯。進入車內凡是手可以碰到的地方全部是使用了軟性材料,比如中控面板,扶手箱,門把手等,所以幾乎你在車內是感覺不到廉價感覺的。不過遺憾的是T90並沒有配備群眾們喜聞樂見的全景天窗,只是尺寸也不算很大的普通天窗。

乘坐空間這一點對於國內消費者來說就是重中之重了,國人就是喜歡大尺寸、大空間,畢竟拖家帶口空間小了坐着確實憋屈。T90的座椅使用了和天籟同級的人體工程學座椅,座椅填充物柔軟,舒適性和包裹性都非常好,絕對也能稱得上是移動大沙發。後排空間較大,但是溜背的造型會犧牲一定的頭部空間。

動力系統應該是T90最拿得出手的東西了。T90配備日產MR20自然吸氣發動機,排量為2.0L,最大功率144馬力,最大扭矩198牛·米,匹配CVT無級變速箱。這套動力系統同時也在天籟和逍客上面使用,所以T90的動力系統應該是很讓人放心了。畢竟這是一套成熟、可靠、穩定、經濟的動力系統。

T90馬上就會成為啟辰的旗艦轎車,所以啟辰方面也是特別重視的,從整車的做工來看也能看出來廠家確實是在用心做產品。後期我們還會有T90的試駕文章,喜歡它的消費者可以留意一下。

儘管T90會在即將到來的廣州車展公布預售價,但是官方曾說,這款車的預售價在20萬以下,聽到這價格我就心涼了半截,只是覺得,好貴…到時候價格真的是接近20萬了,那估計銷量真的堪比寶馬X6了。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

春節假期第四天全國主要道路交通安全順暢_包裝設計

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

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

新華社北京1月27日電 公安部交管局27日發布信息,春節假期第四天,各主要高速公路、國省道幹線公路交通安全順暢,根據全國35條高速公路200個重要通道監測節點流量監測情況,交通總流量與去年同期相比下降39.9%。截至17時,未發生長時間長距離交通擁堵,未接報一次死亡5人以上較大交通事故。

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

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

全國公安交管部門根據公安部統一部署,在當地黨委政府和公安機關的統一指揮下,主動擔當、积極作為,統籌春節假日交通安保和交通應急管理,會同和配合有關部門嚴密重點路段管控、嚴密重點部位防護、嚴密重點車輛查控,全力投入疫情防控工作,全力保障道路交通安全暢通。據統計,各地公安交管部門共出動警力18萬餘人次,出動警車7萬餘輛次,啟動交警執法站4100餘個,設立臨時執勤點1.2萬餘個。

根據中央氣象台預報,27日至28日,西南部局地有大雪或暴雪。27日夜間至28日早晨,湖北東部、湖南北部、江西東北部、山東中部、江蘇北部等地部分地區將有大霧天氣,局部有濃霧或強濃霧。公安部交管局提示廣大駕駛人朋友:霧天行車要打開霧燈,控制車速、保持安全車距;在冰雪路面行車時,要做到“緩加油、輕減速、慢轉彎”;請牢記“安全帶——生命帶”,駕車一定系好安全帶,莫忘為兒童選用適合其年齡、體重的兒童安全座椅。特別是請按照各地疫情防控工作的要求,盡量減少交通出行。

本站聲明:網站內容來http://www.societynews.cn/html/wh/fq/,如有侵權,請聯繫我們,我們將及時處理

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

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