標籤: 台中搬家公司

  • 同級中最大的SUV!自動擋僅需7.89萬起!

    同級中最大的SUV!自動擋僅需7.89萬起!

    29萬起。然而如果要求更多的話,可以再選往上的幾個配置如自動尊貴型和自動旗艦型,基本能夠做到在10萬元左右的落地價,就能夠享受着豐富配置的高級體驗,如對新手司機非常有用的360度全景影像,無鑰匙進入與一鍵啟動,电子駐車功能等等,這種事情只會發生在我們的自主品牌身上,所以除了說愛國,大部分人選擇自主品牌車輛還是有很大原因的,性價比高嘛。

    前言

    對於現在大多數的中國消費者來說,購車要求雖然不盡一致,但很多人還是喜歡着“又長又大又硬”的車輛,這樣說好像有點污,不過嘿嘿嘿,確實越長軸距的車輛,空間越大的車,車殼越硬的車,都能夠吸引無數人的要求,再加上一个中庸且高尚的外觀,銷量估計不成問題。至於配置方面,回過頭來看我們國家的自主品牌,肯定要啥有啥,您的預算內肯定能夠買到滿意的配置。

    而其中備受人們關注的一汽森雅R7,除了超高顏值和超配置之外,重點來了,就是繼手動擋上市后終於又在這次的廣州車展上上市了其自動擋版本!相信許多朋友們都期待已久,畢竟手動擋在城市中行走確實有些不方便,自動擋的到來,相信肯定會對森雅R7的銷量帶來很大的幫助。

    先從外觀開始說起,畢竟這是許多人所考慮的重中之重,如雄鷹般沉穩大氣的前臉線條,配合大燈看起來非常犀利,腰線舒展優雅,整體風格時尚硬朗,這個臉套在一輛SUV的臉上剛好合適。

    除了外觀招人喜歡之外,在同級的小型SUV中,森雅R7帶給人的空間體驗更加豐富,軸距達到了2600mm,屬於同級最大的超長軸距,採用緊湊布置,內部空間實現了最大化,後排座椅支持放倒,實現車內空間多樣化設置,在這一點上,就能夠符合人們喜歡“又長又大”的購車需求了。

    內飾設計上採用環抱式駕駛艙設計,智能彩屏儀錶,貫穿式副儀錶板,盡可能地將消費者眼前所能看到的中控設計,利用最好的效果呈現出來。

    同時在配置上更有着越級別的表現,除了1.6L自動舒適版之外,其他自動擋版本都全部標配ESp車身穩定系統,真皮座椅,多功能真皮方向盤,定速巡航和發動機啟停裝置,價格上也只要8.29萬起。

    然而如果要求更多的話,可以再選往上的幾個配置如自動尊貴型和自動旗艦型,基本能夠做到在10萬元左右的落地價,就能夠享受着豐富配置的高級體驗,如對新手司機非常有用的360度全景影像,無鑰匙進入與一鍵啟動,电子駐車功能等等,這種事情只會發生在我們的自主品牌身上,所以除了說愛國,大部分人選擇自主品牌車輛還是有很大原因的,性價比高嘛。

    自主品牌除了性價比很高之外,消費者還會考慮的另外一個原因就是它的安全性如何,因為對於一款新出的車型,還沒有經過市場的考驗,很難在消費者印象中樹立品質形象,舉個例子,相信大家都看過不少汽車追尾事故的圖片,其中沃爾沃都能夠在大多數事故中以較完整的車身取勝,那麼對於森雅R7來說,同樣也是採用了高強度的籠型車身,搭載博世九代ESp,集成剎車輔助,上坡輔助和牽引力控制等主動安全系統,同時在細節的地方,剎車踏板為防侵入式設計,能夠在正面碰撞時減少對駕駛員腳部傷害的風險,發動機蓋採用可壓潰式設計,降低碰撞時對行人的傷害。

    手動擋版本森雅R7在4月27日於北京上市,上市后首月訂單就超過了1萬台,非常受消費者歡迎,而這次在廣州車展上正式上市其自動擋版本,均搭載愛信第三代6速自動變速器,自動擋版本定價在7.89-9.99萬這個區間,而手動擋則為6.89萬起步。

    發動機採用1.6L自然吸氣發動機,這對於一輛小型SUV來說,代步肯定是足夠的,油耗也不會特別的高,所以我們不需要盲目地追求大排量和帶渦輪,其實實用以及不錯的油耗體現,才是日後我們養車所關注的最大問題,而這款匹配了6速自動變速箱的試駕感受會如何,要試駕后,屆時會為大家送上對應的試駕文章。

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

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

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

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

  • 新創酷9.99萬起售 這麼超值是要砸場子的節奏?

    新創酷9.99萬起售 這麼超值是要砸場子的節奏?

    很久很久以前小編美美並不是做編輯而是說書的今天小編美美就來說一個古老而又神秘的故事。

    很久很久以前

    小編美美並不是做編輯

    而是

    說書的

    今天小編美美就來說一個古老

    而又神秘的故事

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

    ※超省錢租車方案

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

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

  • 又大又漂亮SUV僅5.89萬?11月上市的這幾款性價比特高

    又大又漂亮SUV僅5.89萬?11月上市的這幾款性價比特高

    4T渦輪增壓發動機,最大功率達到143馬力,匹配6速手自一體變速箱或6速手動變速箱。編者點評:新款創酷設計一下子變得年輕、運動。這樣的設計風格無疑對20多歲的朋友們更有吸引力。而且自動擋車型的起售價僅11。99萬,還採用了1。

    在11月份,因為廣州車展的緣故,各大汽車廠商都在這個月里推出了今年最後一波重點新車!今天編者就和大家聊聊這個月上市的重點高性價比新SUV,要買SUV不妨多看看這些新車!

    奇瑞汽車-瑞虎3x

    指導價:5.89-8.09萬

    奇瑞全新的小型SUV–瑞虎3x也在本月上市,5.89萬的起售價,讓很多粉絲都在後台跟我們聊過這款車。

    其實瑞虎3x的車身長寬高為4200*1760*1570mm,軸距為2555mm。編者此前親身體驗過這款車的空間,它的乘坐空間夠用,基本上頭部、腿部空間都有富餘。而且後備廂的空間也不錯。

    動力方面,其採用1.5L發動機最大功率106馬力,最大扭矩為135牛米。搭配4擋自動變速箱或5擋手動變速箱。

    編者點評:

    如果你想要買人生的第一輛車的話,瑞虎3x這一類的低價、年輕化的SUV車型可以說是比較合適的。它賣點在於不錯的外觀內飾設計、不錯的空間實用性,還有較高的性價比。另外較高的坐姿,在行車過程中也更方便察看前方的車流。

    上汽通用雪佛蘭-創酷

    指導價:9.99—14.99萬

    在前幾天,雪佛蘭2017款創酷正式上市了。這次上市的為中期改款車型,它的外觀運用了雪佛蘭全新家族化設計,在前臉造型的變化尤為明顯!

    其採用立體雙格柵的造型、修長的大燈,較老款車型更有運動感。大燈中還帶有U型LED日間行車燈,配置方面,新車提供胎壓監測、智能啟停功能、ESp、7英寸觸摸屏等亮點配置。

    動力系統方面,它搭載的是1.4T渦輪增壓發動機,最大功率達到143馬力,匹配6速手自一體變速箱或6速手動變速箱。

    編者點評:

    新款創酷設計一下子變得年輕、運動。這樣的設計風格無疑對20多歲的朋友們更有吸引力。而且自動擋車型的起售價僅11.99萬,還採用了1.4T發動機,動力表現十分充沛。喜歡這個價位SUV車型的朋友可以多關注它!

    東風標緻-標緻4008

    指導價:18.57-27.37萬

    因為漂亮、科幻的外觀而備受期待的法系全新SUV,標緻4008也在這個月上市!18.57-27.37萬的售價區間讓它比起翼虎、途觀這些對手車型的指導價要稍低一些。

    在外觀和內飾設計方面,標緻4008足夠前衛、時尚。而在動力方面它搭載1.6T、1.8T渦輪增壓發動機,最大功率分別為167馬力、204馬力。匹配6擋手自一體變速箱!

    pSA集團採用的這兩套動力系統其實在動力、平順性、油耗方面都有比較出色的表現,如果你需求動力充沛、提速給力的車型,標緻4008可以成為你重點考慮的車型之一。

    編者點評:

    外觀和內飾的超前的設計、三大件不錯的性能,讓標緻4008的競爭力表現不錯。雖然低配車型的舒適性配置有些缺失,但是其安全性配置還是很厚道的,所以不失為一款競爭力出色的歐系SUV。

    最後總結:

    上面提到的車型都是本月已經上市的高關注度SUV車型,在性價比方面都表現不錯,而我個人比較喜歡標緻4008,前衛的設計和不錯的操控性是它能打動我的地方!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※回頭車貨運收費標準

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

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

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

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

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

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

  • 武漢肺炎對全球食品業的衝擊 麵粉大缺貨 牛奶、啤酒、茶葉過剩成廚餘

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

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

    ※超省錢租車方案

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

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

  • IUCN:亞當峰朝聖者腳下 斯里蘭卡瀕危兩棲類正在消失

    環境資訊中心綜合外電;黃鈺婷 翻譯;林大利 審校;稿源:Mongabay

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

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

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

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

  • 英封城期間 販賣機賣肉和菜、直接向漁夫買 掀新商機

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

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

    ※超省錢租車方案

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

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

  • 印度全國封鎖後 恆河上游部分河段可飲用

    摘錄自2020年4月24日中央社報導

    一般帶大量超級細菌的恆河,在印度全國封鎖近一個月後,因為幾乎沒有人類污染,瑜伽聖城瑞詩凱詩(Rishikesh)這段恆河河水,經政府檢測水質達到可飲用的標準。

    印度北部北阿坎德省(Uttarakhand)污染控制局最近從瑞詩凱詩及哈里德瓦(Haridwar)的恆河河段抽樣進行化驗,發現水質可以飲用。

    官方報告表示,哈基寶里河壇段的恆河水,生化需氧量(Biochemical oxygen demand)也下降20%。專家說,這意味著恆河水含氧量變高,水族可舒適地在河中呼吸。

    印度中央污染控制局(Central Pollution Control Board)近日發表的調查報告顯示,恆河36個監測站中,有27個監測站測得恆河水質已變為可安全沐浴和水中生物可安全生活的水準。

    生活環境
    土地水文
    土地利用
    國際新聞
    印度
    封城
    武漢肺炎
    恆河

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

    【其他文章推薦】

    ※回頭車貨運收費標準

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

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

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

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

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

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

  • 深入正則表達式(3):正則表達式工作引擎流程分析與原理釋義

    作為正則的使用者也一樣,不懂正則引擎原理的情況下,同樣可以寫出滿足需求的正則,但是不知道原理,卻很難寫出高效且沒有隱患的正則。所以對於經常使用正則,或是有興趣深入學習正則的人,還是有必要了解一下正則引擎的匹配原理的。

    有興趣可以回顧《深入正則表達式(0):正則表達式概述》

    正則引擎類型

    正則引擎主要可以分為兩大類:一種是DFA(Deterministic Finite Automatons/確定性有限自動機—),一種是NFA(Nondeterministic Finite Automatons/非確定性有限自動機)。總的來說,

    • DFA可以稱為文本主導的正則引擎

    • NFA可以稱為表達式主導的正則引擎

    NFA與DFA工作的區別:

    我們常常說用正則去匹配文本,這是NFA的思路,DFA本質上其實是用文本去匹配正則

    'for tonight's'.match(/to(nite|knite|night)/);
    • 如果是NFA引擎,表達式佔主導地位。在字符串先查找字符串中的t,然後依次匹配,如果是o,則繼續(以此循環)。匹配到to后,到n,就面臨三種選擇,每一種都去嘗試匹配一下(它也不嫌累),第一個分支也是依次匹配,到t這裏停止(nite分到t這裏直接被淘汰);同理,接着第二個分支在k這裏也停止了;終於在第三個分支柳暗花明,找到了自己的歸宿。 NFA 工作方式是以正則表達式為標準,反覆測試字符串,這樣同樣一個字符串有可能被反覆測試了很多次!

    • 如果是DFA引擎呢,文本佔主導地位。從整個字符串第一個字符開始f開始查找t,查找到t后,定位到t,以知其後為o,則去查看正則表達式其相應位置后是否為o,如果是,則繼續(以此循環),再去查正則表達式o后是否為n(此時淘汰knite分支),再后是否為g(淘汰nite分支),這個時候只剩一個分支,直接匹配到終止即可。

    只有正則表達式才有分支和範圍,文本僅僅是一個字符流。這帶來什麼樣的後果?就是NFA引擎在匹配失敗的時候,如果有其他的分支或者範圍,它會返回,記住,返回,去嘗試其他的分支而DFA引擎一旦匹配失敗,就結束了,它沒有退路。

    這就是它們之間的本質區別。其他的不同都是這個特性衍生出來的。

    NFA VS DFA

    首先,正則表達式在計算機看來只是一串符號,正則引擎首先肯定要解析它。NFA引擎只需要編譯就好了;而DFA引擎則比較繁瑣,編譯完還不算,還要遍歷出表達式中所有的可能。因為對DFA引擎來說機會只有一次,它必須得提前知道所有的可能,才能匹配出最優的結果。

    所以,在編譯階段,NFA引擎比DFA引擎快

     

    其次,DFA引擎在匹配途中一遍過,溜得飛起。相反NFA引擎就比較苦逼了,它得不厭其煩的去嘗試每一種可能性,可能一段文本它得不停返回又匹配,重複好多次。當然運氣好的話也是可以一遍過的。

    所以,在運行階段,NFA引擎比DFA引擎慢

     

    最後,因為NFA引擎是表達式佔主導地位,所以它的表達能力更強,開發者的控制度更高,也就是說開發者更容易寫出性能好又強大的正則來,當然也更容易造成性能的浪費甚至撐爆CPU。DFA引擎下的表達式,只要可能性是一樣的,任何一種寫法都是沒有差別(可能對編譯有細微的差別)的,因為對DFA引擎來說,表達式其實是死的。而NFA引擎下的表達式,高手寫的正則和新手寫的正則,性能可能相差10倍甚至更多。

    也正是因為主導權的不同,正則中的很多概念,比如非貪婪模式、反向引用、零寬斷言等只有NFA引擎才有。

    所以,在表達能力上,NFA引擎秒殺DFA引擎

     

    但是NFA以表達式為主導,因而NFA更容易操縱,因此一般程序員更偏愛NFA引擎!

    當今市面上大多數正則引擎都是NFA引擎,應該就是勝在表達能力上。

     

    總體來說,兩種引擎的工作方式完全不同,一個(NFA)以表達式為主導,一個(DFA)以文本為主導!兩種引擎各有所長,而真正的引用則取決與你的需要以及所使用的語言。

    這兩種引擎都有了很久的歷史(至今二十多年),當中也由這兩種引擎產生了很多變體!

    因為NFA引擎比較靈活,很多語言在實現上有細微的差別。所以後來大家弄了一個標準,符合這個標準的正則引擎就叫做POSIX NFA引擎,其餘的就只能叫做傳統型NFA引擎咯。

    Deterministic finite automaton,Non-deterministic finite automaton,Traditional NFA,Portable Operating System Interface for uniX NFA

    於是POSIX的出台規避了不必要變體的繼續產生。這樣一來,主流的正則引擎又分為3類:DFA,傳統型NFA,POSIX NFA。

    正則引擎三國

    DFA引擎

    DFA引擎在線性時狀態下執行,因為它們不要求回溯(並因此它們永遠不測試相同的字符兩次)。

    DFA引擎還可以確保匹配最長的可能的字符串。但是,因為 DFA 引擎只包含有限的狀態,所以它不能匹配具有反向引用的模式;並且因為它不構造显示擴展,所以它不可以捕獲子表達式。

    DFN不回溯,所以匹配快速,因而不支持捕獲組,支持反向引用和$number引用

    傳統的 NFA引擎

    傳統的 NFA 引擎運行所謂的“貪婪的”匹配回溯算法,以指定順序測試正則表達式的所有可能的擴展並接受第一個匹配項。因為傳統的 NFA 構造正則表達式的特定擴展以獲得成功的匹配,所以它可以捕獲子表達式匹配和匹配的反向引用。但是,因為傳統的 NFA 回溯,所以它可以訪問完全相同的狀態多次(如果通過不同的路徑到達該狀態)。因此,在最壞情況下,它的執行速度可能非常慢。因為傳統的 NFA 接受它找到的第一個匹配,所以它還可能會導致其他(可能更長)匹配未被發現

    大多數編程語言和工具使用的是傳統型的NFA引擎,它有一些DFA不支持的特性:

    • 捕獲組、反向引用和$number引用方式;

    • 環視(Lookaround,(?<=…)、(?<!…)、(?=…)、(?!…)),或者有的有文章叫做預搜索;

    • 忽略優化量詞(??、*?、+?、{m,n}?、{m,}?),或者有的文章叫做非貪婪模式;

    • 佔有優先量詞(?+、*+、++、{m,n}+、{m,}+,目前僅Java和PCRE支持),固化分組(?>…)。

    POSIX NFA引擎

    POSIX NFA引擎主要指符合POSIX標準的NFA引擎,與傳統的 NFA 引擎類似,不同的一點在於:提供longest-leftmost匹配,也就是在找到最左側最長匹配之前,它將繼續回溯(可以確保已找到了可能的最長的匹配之前它們將繼續回溯)。因此,POSIX NFA 引擎的速度慢於傳統的 NFA 引擎;並且在使用 POSIX NFA 時,您恐怕不會願意在更改回溯搜索的順序的情況下來支持較短的匹配搜索,而非較長的匹配搜索。

    同DFA一樣,非貪婪模式或者說忽略優先量詞對於POSIX NFA同樣是沒有意義的。

    三種引擎的使用情況

    • 使用傳統型NFA引擎的程序主要有(主流):

      • Java、Emacs(JavaScript/actionScript)、Perl、PHP、Python、Ruby、.NET語言

      • VI,GNU Emacs,PCRE library,sed;

    • 使用POSIX NFA引擎的程序主要有:mawk,Mortice Kern Systems’ utilities,GNU Emacs(使用時可以明確指定);

    • 使用DFA引擎的程序主要有:awk,egrep,flex,lex,MySQL,Procmail等;

    • 也有使用DFA/NFA混合的引擎:GNU awk,GNU grep/egrep,Tcl。

     

    《精通正則表達式》書中說POSIX NFA引擎不支持非貪婪模式,很明顯JavaScript不是POSIX NFA引擎。

    '123456'.match(/\d{3,6}/);
    // ["123456", index: 0, input: "123456", groups: undefined]
    '123456'.match(/\d{3,6}?/);
    // ["123", index: 0, input: "123456", groups: undefined]

    JavaScript的正則引擎是傳統型NFA引擎。

    為什麼POSIX NFA引擎不支持也沒有必要支持非貪婪模式?

    回溯

    現在我們知道,NFA引擎是用表達式去匹配文本,而表達式又有若干分支和範圍,一個分支或者範圍匹配失敗並不意味着最終匹配失敗,正則引擎會去嘗試下一個分支或者範圍。

    正是因為這樣的機制,引申出了NFA引擎的核心特點——回溯。

    首先我們要區分備選狀態和回溯。

    什麼是備選狀態?就是說這一個分支不行,那我就換一個分支,這個範圍不行,那我就換一個範圍。正則表達式中可以商榷的部分就叫做備選狀態。

    備選狀態可以實現模糊匹配,是正則表達能力的一方面。

    回溯可不是個好東西。想象一下,面前有兩條路,你選擇了一條,走到盡頭髮現是條死路,你只好原路返回嘗試另一條路。這個原路返回的過程就叫回溯,它在正則中的含義是吐出已經匹配過的文本。

    我們來看兩個例子:

    'abbbc'.match(/ab{1,3}c/);
    // ["abbbc", index: 0, input: "abbbc", groups: undefined]
    'abc'.match(/ab{1,3}c/);
    // ["abc", index: 0, input: "abc", groups: undefined]

    第一個例子,第一次a匹配a成功,接着碰到貪婪匹配,不巧正好是三個b貪婪得逞,最後用c匹配c成功。

    正則 文本
    /a/ a
    /ab{1,3}/ ab
    /ab{1,3}/ abb
    /ab{1,3}/ abbb
    /ab{1,3}c/ abbbc

    第二個例子的區別在於文本只有一個b。所以表達式在匹配第一個b成功後繼續嘗試匹配b,然而它見到的只有黃臉婆c。不得已將c吐出來,委屈一下,畢竟貪婪匹配也只是盡量匹配更多嘛,還是要臣服於匹配成功這個目標。最後不負眾望用c匹配c成功。

    正則 文本
    /a/ a
    /ab{1,3}/ ab
    /ab{1,3}/ abc
    /ab{1,3}/ ab
    /ab{1,3}c/ abc

    請問,第二個例子發生回溯了嗎?

    並沒有。

    誒,你這樣就不講道理了。不是把c吐出來了嘛,怎麼就不叫回溯了?

    回溯是吐出已經匹配過的文本。匹配過程中造成的匹配失敗不算回溯

    為了讓大家更好的理解,我舉一個例子:

    你和一個女孩子(或者男孩子)談戀愛,接觸了半個月後發現實在不合適,於是提出分手。這不叫回溯,僅僅是不合適而已。

    你和一個女孩子(或者男孩子)談戀愛,這段關係維持了兩年,並且已經同居。但由於某些不可描述的原因,疲憊掙扎之後,兩人最終還是和平分手。這才叫回溯。

    雖然都是分手,但你們應該能理解它們的區別吧。

    為了讓大家更好的理解,我舉一個例子:

    你和一個女孩子(或者男孩子)談戀愛,接觸了半個月後發現實在不合適,於是提出分手。這不叫回溯,僅僅是不合適而已。

    你和一個女孩子(或者男孩子)談戀愛,這段關係維持了兩年,並且已經同居。但由於某些不可描述的原因,疲憊掙扎之後,兩人最終還是和平分手。這才叫回溯。

    雖然都是分手,但你們應該能理解它們的區別吧。

    網絡上有很多文章都認為上面第二個例子發生了回溯。至少根據我查閱的資料,第二個例子發生的情況不能被稱為回溯。當然也有可能我([馬蹄疾]是錯的,歡迎討論。

    我們再來看一個真正的回溯例子:

    'ababc'.match(/ab{1,3}c/);
    // ["abc", index: 2, input: "ababc", groups: undefined]

    匹配文本到ab為止,都沒什麼問題。後面既匹配不到b,也匹配不到c。引擎只好將文本ab吐出來,從下一個位置開始匹配。因為上一次是從第一個字符a開始匹配,所以下一個位置當然就是從第二個字符b開始咯。

    正則 文本
    /a/ a
    /ab{1,3}/ ab
    /ab{1,3}/ aba
    /ab{1,3}/ ab
    /ab{1,3}c/ aba
    /a/ ab
    /a/ aba
    /ab{1,3}/ abab
    /ab{1,3}/ ababc
    /ab{1,3}/ abab
    /ab{1,3}c/ ababc

    一開始引擎是以為會和最早的ab走完餘生的,然而命運弄人,從此天涯。

    這他媽才叫回溯!

    還有一個細節。上面例子中的回溯並沒有往回吐呀,吐出來之後不應該往回走嘛,怎麼往後走了?

    我們再來看一個例子:

    '"abc"def'.match(/".*"/);
    // [""abc"", index: 0, input: ""abc"def", groups: undefined]

    因為.*是貪婪匹配,所以它把後面的字符都吞進去了。直到發現目標完不成,不得已往回吐,吐到第二個”為止,終於匹配成功。這就好比結了婚還在外面養小三,幾經折騰才發現家庭才是最重要的,自己的行為背離了初衷,於是幡然悔悟。

    正則 文本
    /”/
    /”.*/ “a
    /”.*/ “ab
    /”.*/ “abc
    /”.*/ “abc”
    /”.*/ “abc”d
    /”.*/ “abc”de
    /”.*/ “abc”def
    /”.*”/ “abc”def
    /”.*”/ “abc”de
    /”.*”/ “abc”d
    /”.*”/ “abc”

    我想說的是,不要被回溯的回字迷惑了。它的本質是把已經吞進去的字符吐出來。至於吐出來之後是往回走還是往後走,是要根據情況而定的。

    優化正則表達式

    現在我們知道了控制回溯是控制正則表達式性能的關鍵。

    控制回溯又可以拆分成兩部分:第一是控製備選狀態的數量,第二是控製備選狀態的順序。

    備選狀態的數量當然是核心,然而如果備選狀態雖然多,卻早早的匹配成功了,早匹配早下班,也就沒那麼多糟心事了。

    傳統NFA工作流程

    許多因素影響正則表達式的效率,首先,正則表達式適配的文本千差萬別,部分匹配時比完全不匹配所用的時間要長。上面提到過,JavaScript是傳統NFA引擎,當然每種瀏覽器的正則表達式引擎也有不同的內部優化。

    為了有效地使用正則表達式,重要的是理解它們的工作原理。下面是一個正則表達式處理的基本步驟:

    第一步:編譯

    當你創建了一個正則表達式對象之後(使用一個正則表達式直接量或者RegExp構造器),瀏覽器檢查你的模板有沒有錯誤,然後將它轉換成一個本機代碼例程,用於執行匹配工作。如果你將正則表達式賦給一個變量,你可以避免重複執行此步驟。

    第二步:設置起始位置

    當一個正則表達式投入使用時,首先要確定目標字符串中開始搜索的位置。它是字符串的起始位置,或由正則表達式的lastIndex屬性指定,但是當它從第四步返回到這裏的時候(因為嘗試匹配失敗),此位置將位於最後一次嘗試起始位置推后一個字符的位置上。

          瀏覽器優化正則表達式引擎的辦法是,在這一階段中通過早期預測跳過一些不必要的工作。例如,如果一個正則表達式以^開頭,IE 和Chrome通常判斷在字符串起始位置上是否能夠匹配,然後可避免愚蠢地搜索後續位置。另一個例子是匹配第三個字母是x的字符串,一個聰明的辦法是先找到x,然後再將起始位置回溯兩個字符。

    第三步:匹配每個正則表達式的字元

          正則表達式一旦找好起始位置,它將一個一個地掃描目標文本和正則表達式模板。當一個特定字元匹配失敗時,正則表達式將試圖回溯到掃描之前的位置上,然後進入正則表達式其他可能的路徑上。

          第四步:匹配成功或失敗

          如果在字符串的當前位置上發現一個完全匹配,那麼正則表達式宣布成功。如果正則表達式的所有可能路徑都嘗試過了,但是沒有成功地匹配,那麼正則表達式引擎回到第二步,從字符串的下一個字符重新嘗試。只有字符串中的每個字符(以及最後一個字符後面的位置)都經歷了這樣的過程之後,還沒有成功匹配,那麼正則表達式就宣布徹底失敗。

          牢記這一過程將有助於您明智地判別那些影響正則表達式性能問題的類型。

     

    工具

    [ regex101 ]是一個很多人推薦過的工具,可以拆分解釋正則的含義,還可以查看匹配過程,幫助理解正則引擎。如果只能要一個正則工具,那就是它了。

    [ regexper ]是一個能讓正則的備選狀態可視化的工具,也有助於理解複雜的正則語法。

     

    參考文章:

     https://baike.baidu.com/item/正則表達式

    正則表達式工作原理 https://www.cnblogs.com/aaronjs/archive/2012/06/30/2570800.html

    一次性搞懂JavaScript正則表達式之引擎 https://juejin.im/post/5becc2aef265da6110369c93

     

    轉載本站文章《深入正則表達式(3):正則表達式工作引擎流程分析與原理釋義》,
    請註明出處:https://www.zhoulujun.cn/html/theory/algorithm/IntroductionAlgorithms/8430.html

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

    ※超省錢租車方案

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

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

  • 一次找出範圍內的所有素數,埃式篩法是什麼神仙算法?

    一次找出範圍內的所有素數,埃式篩法是什麼神仙算法?

    本文始發於個人公眾號:TechFlow,原創不易,求個關注

    今天這篇是算法與數據結構專題的第23篇文章,我們繼續數論相關的算法,來看看大名鼎鼎的埃式篩法。

    我們都知道在數學領域,素數非常重要,有海量的公式和研究關於素數,比如那個非常著名至今沒有人解出來的哥德巴赫猜想。和數學領域一樣,素數在信息領域也非常重要,有着大量的應用。舉個簡單的例子,很多安全加密算法也是利用的質數。我們想要利用素數去進行各種計算之前,總是要先找到素數。所以這就有了一個最簡單也最不簡單的問題,我們怎麼樣來尋找素數呢?

    判斷素數

    尋找素數最樸素的方法當然是一個一個遍歷,我們依次遍歷每一個數,然後分別判斷是否是素數。所以問題的核心又回到了判斷素數上,那麼怎麼判斷一個數是不是素數呢?

    素數的性質只有一個,就是只有1和它本身這兩個因數,我們要判斷素數也只能利用這個性質。所以可以想到,假如我們要判斷n是否是素數,可以從2開始遍歷到n-1,如果這n-1個數都不能整除n,那麼說明n就是素數。這個我沒記錯在C語言的練習題當中出現過,總之非常簡單,可以說是最簡單的算法了。

    def is_prime(n):
        for i in range(2, n):
            if n % i == 0:
                return False
        return n != 1
    

    顯然,這個算法是可以優化的,比如當n是偶數的時候,我們根本不需要循環,除了2意外的偶數一定是合數。再比如,我們循環的上界其實也沒有必要到n-1,到就可以了。因為因數如果存在一定是成對出現的,如果存在小於根號n的因數,那麼n除以它一定大於根號n。

    這個改進也很簡單,稍作改動即可:

    def is_prime(n):
        if n % 2 == 0 and n != 2:
            return False
        for i in range(3, int(math.sqrt(n) + 1)):
            if n % i == 0:
                return False
        return n != 1
    

    這樣我們把O(n)的算法優化到了O()也算是有了很大的改進了,但是還沒有結束,我們還可以繼續優化。數學上有一個定理,只有形如6n-1和6n+1的自然數可能是素數,這裏的n是大於等於1的整數。

    這個定理乍一看好像很高級,但其實很簡單,因為所有自然數都可以寫成6n,6n+1,6n+2,6n+3,6n+4,6n+5這6種,其中6n,6n+2,6n+4是偶數,一定不是素數。6n+3可以寫成3(2n+1),顯然也不是素數,所以只有可能6n+1和6n+5可能是素數。6n+5等價於6n-1,所以我們一般寫成6n-1和6n+1。

    利用這個定理,我們的代碼可以進一步優化:

    def is_prime(n):
        if n % 6 not in (1, 5) and n not in (2, 3):
            return False
        for i in range(3, int(math.sqrt(n) + 1)):
            if n % i == 0:
                return False
        return n != 1
    

    雖然這樣已經很快了,但仍然不是最優的,尤其是當我們需要尋找大量素數的時候,仍會消耗大量的時間。那麼有沒有什麼辦法可以批量查找素數呢?

    有,這個方法叫做埃拉托斯特尼算法。這個名字念起來非常拗口,這是一個古希臘的名字。此人是個古希臘的大牛,是大名鼎鼎的阿基米德的好友。他雖然沒有阿基米德那麼出名,但是也非常非常厲害,在數學、天文學、地理學、文學、歷史學等多個領域都有建樹。並且還自創方法測量了地球直徑、地月距離、地日距離以及黃赤交角等諸多數值。要知道他生活的年代是兩千五百多年前,那時候中國還是春秋戰國時期,可以想見此人有多厲害。

    埃式篩法

    我們今天要介紹的埃拉托斯特尼算法就是他發明的用來篩選素數的方法,為了方便我們一般簡稱為埃式篩法或者篩法。埃式篩法的思路非常簡單,就是用已經篩選出來的素數去過濾所有能夠被它整除的數。這些素數就像是篩子一樣去過濾自然數,最後被篩剩下的數自然就是不能被前面素數整除的數,根據素數的定義,這些剩下的數也是素數。

    舉個例子,比如我們要篩選出100以內的所有素數,我們知道2是最小的素數,我們先用2可以篩掉所有的偶數。然後往後遍歷到3,3是被2篩剩下的第一個數,也是素數,我們再用3去篩除所有能被3整除的數。篩完之後我們繼續往後遍歷,第一個遇到的數是7,所以7也是素數,我們再重複以上的過程,直到遍歷結束為止。結束的時候,我們就獲得了100以內的所有素數。

    如果還不太明白,可以看下下面這張動圖,非常清楚地還原了這整個過程。

    不見圖 請翻牆

    這個思想非常簡單,理解了之後寫出代碼來真的很容易:

    def eratosthenes(n):
        primes = []
        is_prime = [True] * (n + 1)
        for i in range(2, n+1):
            if is_prime[i]:
                primes.append(i)
                # 用當前素數i去篩掉所有能被它整除的數
                for j in range(i * 2, n+1, i):
                    is_prime[j] = False
        return primes
    

    我們運行一次代碼看看:

    和我們的預期一樣,獲得了小於100的所有素數。我們來分析一下篩法的複雜度,從代碼當中我們可以看到,我們一共有了兩層循環,最外面一層循環固定是遍歷n次。而裏面的這一層循環遍歷的次數一直在變化,並且它的運算次數和素數的大小相關,看起來似乎不太方便計算。實際上是可以的,根據素數分佈定理以及一系列複雜的運算(相信我,你們不會感興趣的),我們是可以得出篩法的複雜度是

    極致優化

    篩法的複雜度已經非常近似了,因為即使在n很大的時候,經過兩次ln的計算,也非常近似常數了,實際上在絕大多數使用場景當中,上面的算法已經足夠應用了。

    但是仍然有大牛不知滿足,繼續對算法做出了優化,將其優化到了的複雜度。雖然從效率上來看並沒有數量級的提升,但是應用到的思想非常巧妙,值得我們學習。在我們理解這個優化之前,先來看看之前的篩法還有什麼可以優化的地方。比較明顯地可以看出來,對於一個合數而言,它可能會被多個素數篩去。比如38,它有2和19這兩個素因數,那麼它就會被置為兩次False,這就帶來了額外的開銷,如果對於每一個合數我們只更新一次,那麼是不是就能優化到了呢?

    怎麼樣保證每個合數只被更新一次呢?這裏要用到一個定理,就是每個合數分解質因數只有的結果是唯一的。既然是唯一的,那麼一定可以找到最小的質因數,如果我們能夠保證一個合數只會被它最小的質因數更新為False,那麼整個優化就完成了。

    那我們具體怎麼做呢?其實也不難,我們假設整數n的最小質因數是m,那麼我們用小於m的素數i乘上n可以得到一個合數。我們將這個合數消除,對於這個合數而言,i一定是它最小的質因數。因為它等於i * n,n最小的質因數是m,i 又小於m,所以i是它最小的質因數,我們用這樣的方法來生成消除的合數,這樣來保證每個合數只會被它最小的質因數消除。

    根據這一點,我們可以寫出新的代碼:

    def ertosthenes(n):
        primes = []
        is_prime = [True] * (n+1)
        for i in range(2, n+1):
            if is_prime[i]:
                primes.append(i)
            for j, p in enumerate(primes):
                # 防止越界
                if p > n // i:
                    break
                # 過濾
       is_prime[i * p] = False
                # 當i % p等於0的時候說明p就是i最小的質因數
                if i % p == 0:
                    break
                    
        return primes
    

    總結

    到這裏,我們關於埃式篩法的介紹就告一段落了。埃式篩法的優化版本相對來說要難以記憶一些,如果記不住的話,可以就只使用優化之前的版本,兩者的效率相差並不大,完全在可以接受的範圍之內。

    篩法看着代碼非常簡單,但是非常重要,有了它,我們就可以在短時間內獲得大量的素數,快速地獲得一個素數表。有了素數表之後,很多問題就簡單許多了,比如因數分解的問題,比如信息加密的問題等等。我每次回顧篩法算法的時候都會忍不住感慨,這個兩千多年前被發明出來的算法至今看來非但不過時,仍然還是那麼巧妙。希望大家都能懷着崇敬的心情,理解算法當中的精髓。

    如果喜歡本文,可以的話,請點個關注,給我一點鼓勵,也方便獲取更多文章。

    本文使用 mdnice 排版

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

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

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

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

  • 容器技術之Docker私有鏡像倉庫docker-distribution

    容器技術之Docker私有鏡像倉庫docker-distribution

      在前邊的博客中我們說到docker的架構由docker客戶端、服務端以及倉庫組成;docker倉庫就是用來存放鏡像的地方;其實docker registry我們理解為存放docker鏡像倉庫的倉庫比較準確吧;因為docker的鏡像倉庫通常是把同一類的鏡像用不同的版本來區別,而registry則是用來存放這些倉庫的倉庫;默認安裝docker都是從dockerhub鏡像倉庫下載鏡像;其實在生產環境中,我們很少去公有倉庫上下載鏡像,原因之一是公有倉庫中的鏡像在生產環境中使用,有些不適配,通常我們是去公有倉庫下載基礎鏡像,然後基於基礎鏡像構建適合自己生產環境中的鏡像;其次公有倉庫鏡像有很多都不是安全的鏡像,這麼說吧,我們不確定自己下載的鏡像是否有後門,是否有挖礦代碼,所以基於種種因素,我們還是有必要搭建自己私有的鏡像倉庫;今天我們就來聊一聊docker的私有鏡像倉庫的搭建;

      1、查看docker-distribution包簡介

    [root@docker_registry ~]# yum info docker-distribution
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
     * base: mirrors.aliyun.com
     * extras: mirrors.aliyun.com
     * updates: mirrors.aliyun.com
    Available Packages
    Name        : docker-distribution
    Arch        : x86_64
    Version     : 2.6.2
    Release     : 2.git48294d9.el7
    Size        : 3.5 M
    Repo        : extras/7/x86_64
    Summary     : Docker toolset to pack, ship, store, and deliver content
    URL         : https://github.com/docker/distribution
    License     : ASL 2.0
    Description : Docker toolset to pack, ship, store, and deliver content
    
    [root@docker_registry ~]# 
    

      提示:docker-distribution這個包就是提供簡單倉庫服務軟件實現;

      2、安裝docker-distribution

    [root@docker_registry ~]# yum install -y docker-distribution
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
     * base: mirrors.aliyun.com
     * extras: mirrors.aliyun.com
     * updates: mirrors.aliyun.com
    Resolving Dependencies
    There are unfinished transactions remaining. You might consider running yum-complete-transaction, or "yum-complete-transaction --cleanup-only" and "yum history redo last", first to finish them. If those don't work you'll have to try removing/installing packages by hand (maybe package-cleanup can help).
    The program yum-complete-transaction is found in the yum-utils package.
    --> Running transaction check
    ---> Package docker-distribution.x86_64 0:2.6.2-2.git48294d9.el7 will be installed
    --> Finished Dependency Resolution
    
    Dependencies Resolved
    
    ===================================================================================================================
     Package                         Arch               Version                               Repository          Size
    ===================================================================================================================
    Installing:
     docker-distribution             x86_64             2.6.2-2.git48294d9.el7                extras             3.5 M
    
    Transaction Summary
    ===================================================================================================================
    Install  1 Package
    
    Total download size: 3.5 M
    Installed size: 12 M
    Downloading packages:
    docker-distribution-2.6.2-2.git48294d9.el7.x86_64.rpm                                       | 3.5 MB  00:00:03     
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
      Installing : docker-distribution-2.6.2-2.git48294d9.el7.x86_64                                               1/1 
      Verifying  : docker-distribution-2.6.2-2.git48294d9.el7.x86_64                                               1/1 
    
    Installed:
      docker-distribution.x86_64 0:2.6.2-2.git48294d9.el7                                                              
    
    Complete!
    [root@docker_registry ~]# 
    

      3、查看docker-distribution安裝了那些文件

    [root@docker_registry ~]# rpm -ql docker-distribution
    /etc/docker-distribution/registry/config.yml
    /usr/bin/registry
    /usr/lib/systemd/system/docker-distribution.service
    /usr/share/doc/docker-distribution-2.6.2
    /usr/share/doc/docker-distribution-2.6.2/AUTHORS
    /usr/share/doc/docker-distribution-2.6.2/CONTRIBUTING.md
    /usr/share/doc/docker-distribution-2.6.2/LICENSE
    /usr/share/doc/docker-distribution-2.6.2/MAINTAINERS
    /usr/share/doc/docker-distribution-2.6.2/README.md
    /var/lib/registry
    [root@docker_registry ~]# 
    

      提示:/etc/docker-distribution/registry/config.yml這個文件用於配置registry的配置文件;/usr/bin/registry是二進制應用程序;/usr/lib/systemd/system/docker-distribution.service 這個文件是docker-distribution的unit file;/var/lib/registry這個目錄用於存放我們上傳到registry上的鏡像存放地;

      4、查看配置文件

    [root@docker_registry ~]# cat /etc/docker-distribution/registry/config.yml
    version: 0.1
    log:
      fields:
        service: registry
    storage:
        cache:
            layerinfo: inmemory
        filesystem:
            rootdirectory: /var/lib/registry
    http:
        addr: :5000
    [root@docker_registry ~]# 
    

      提示:這個配置文件是一個yml語法的配置文件,從上面的信息可以看到,默認情況docker-distribution監聽在tcp的5000端口;存放鏡像的目錄是/var/lib/registry/目錄下;

      5、啟動docker-distribution

    [root@docker_registry ~]# systemctl start docker-distribution
    [root@docker_registry ~]# ss -tnl
    State       Recv-Q Send-Q            Local Address:Port                           Peer Address:Port              
    LISTEN      0      128                           *:22                                        *:*                  
    LISTEN      0      100                   127.0.0.1:25                                        *:*                  
    LISTEN      0      128                          :::22                                       :::*                  
    LISTEN      0      100                         ::1:25                                       :::*                  
    LISTEN      0      128                          :::5000                                     :::*                  
    [root@docker_registry ~]# 
    

      提示:可以看到5000端口已經處於監聽狀態了;到此docker-distribution就啟動起來了;這個倉庫服務很簡陋,沒有用戶認證功能,默認是基於http通信而非https,所以從某些角度講,不是一個安全的倉庫;所以一般不見在互聯網上使用,在自己的內外環境中可以使用;

      這裏補充一點,docker的鏡像通常是 registry地址加repository名稱加版本這三部分組成,registry可以是域名,可以是ip地址加端口,也可以說域名加端口,默認https是443端口,http是80端口,如果不寫端口默認是443而非80(原因是docker默認不支持從http協議的倉庫下載/上傳鏡像);例如 quay.io/coreos/flannel:v0.12.0-s390x  從這個鏡像名我們就可以知道registry是https://quay.io;repository名稱為coreos/flannel 版本是v0.12.0-s390x;

      示例:下載第三方倉庫鏡像到本地

      提示:可以看到下載下來的鏡像名稱就是我們剛才說的registry+repository+版本;從上面的信息我們可以總結一點,docker鏡像的名稱(標籤)反應了該鏡像來自哪個registry的那個倉庫;所以我們要下載私有鏡像倉庫中的鏡像就需要把加上私有registry的名稱或地址+repository+版本來下載私有鏡像倉庫中的鏡像;同理上傳鏡像也需要寫明上傳到那個registry中的那個repository中去;

      示例:上傳本地鏡像到私有倉庫

      提示:要把本地倉庫鏡像傳到私有倉庫中去,首先我們要把本地鏡像打一個新的標籤,按照我們剛才上面說的邏輯,然後在上傳新打到標籤的鏡像到私有倉庫就可以了;從上面的信息我們看到當我們打好標籤后,上傳鏡像時報錯了,提示我們倉庫不是https的;默認情況docker不支持http明文上傳/下載鏡像;如果我們非要用http上傳下載鏡像我們需要在配置文件中明確的告訴docker非安全倉庫地址;

      配置docker支持私有倉庫上傳下載鏡像

    [root@docker_registry ~]# cat /etc/docker/daemon.json
    {
            "registry-mirrors": ["https://registry.docker-cn.com","https://cyr1uljt.mirror.aliyuncs.com"],
            "insecure-registries": ["192.168.0.99:5000"]
    }
    
    [root@docker_registry ~]# systemctl daemon-reload    
    [root@docker_registry ~]# systemctl restart docker 
    

      提示:我們通過在配置文件中配置insecure-registries來告訴docker192.168.0.99:5000這個registry是不安全的,但是我們信任這個倉庫,大概就是這個意思嘛;通常我們是寫主機名然後配合hosts文件來解析的方式來對registry解析;從而把鏡像命名為主機名+倉庫名+版本的形式;如下所示;這裏還需要注意一點insecure-registries後面的列表中的倉庫如果有域名,域名不能有下劃線(“_”),否則重啟docker會起不來;

    [root@docker_registry ~]# cat /etc/docker/daemon.json 
    {
            "registry-mirrors": ["https://registry.docker-cn.com","https://cyr1uljt.mirror.aliyuncs.com"],
            "insecure-registries": ["192.168.0.99:5000","docker-registry.io:5000"]
    
    }
    [root@docker_registry ~]# cat /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.0.99 docker-registry.io registry
    192.168.0.22 docker-node01.io node01
    192.168.0.23 docker-node02.io node02
    [root@docker_registry ~]# systemctl restart docker
    [root@docker_registry ~]# docker info
    Client:
     Debug Mode: false
    
    Server:
     Containers: 0
      Running: 0
      Paused: 0
      Stopped: 0
     Images: 1
     Server Version: 19.03.11
     Storage Driver: overlay2
      Backing Filesystem: xfs
      Supports d_type: true
      Native Overlay Diff: true
     Logging Driver: json-file
     Cgroup Driver: cgroupfs
     Plugins:
      Volume: local
      Network: bridge host ipvlan macvlan null overlay
      Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
     Swarm: inactive
     Runtimes: runc
     Default Runtime: runc
     Init Binary: docker-init
     containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
     runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
     init version: fec3683
     Security Options:
      seccomp
       Profile: default
     Kernel Version: 3.10.0-693.el7.x86_64
     Operating System: CentOS Linux 7 (Core)
     OSType: linux
     Architecture: x86_64
     CPUs: 4
     Total Memory: 1.785GiB
     Name: docker_registry
     ID: R34V:IG2F:23I6:6WG6:FFQ4:75SV:3UKZ:RFH7:DGCO:QS7V:CS7K:NSH6
     Docker Root Dir: /var/lib/docker
     Debug Mode: false
     Registry: https://index.docker.io/v1/
     Labels:
     Experimental: false
     Insecure Registries:
      192.168.0.99:5000
      docker-registry.io:5000
      127.0.0.0/8
     Registry Mirrors:
      https://registry.docker-cn.com/
      https://cyr1uljt.mirror.aliyuncs.com/
     Live Restore Enabled: false
    
    [root@docker_registry ~]#
    

      提示:重啟docker后,如果在docker info 中能夠看到我們配置的內容說明配置生效了;現在我們再來傳我們新打的標籤的鏡像,看看是否能夠傳到我們的私有倉庫呢?

    [root@docker_registry ~]# docker images
    REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
    docker-registry.io:5000/centos   7                   b5b4d78bc90c        4 weeks ago         203MB
    centos                           7                   b5b4d78bc90c        4 weeks ago         203MB
    192.168.0.99:5000/flannel        v0.12.0-s390x       57eade024bfb        2 months ago        56.9MB
    quay.io/coreos/flannel           v0.12.0-s390x       57eade024bfb        2 months ago        56.9MB
    [root@docker_registry ~]# docker push 192.168.0.99:5000/flannel:v0.12.0-s390x
    The push refers to repository [192.168.0.99:5000/flannel]
    b67de7789e55: Pushed 
    4c4bfa1b47e6: Pushed 
    3b7ae8a9c323: Pushed 
    fbd88a276dca: Pushed 
    271ca11ef489: Pushed 
    1f106b41b4d6: Pushed 
    v0.12.0-s390x: digest: sha256:3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6 size: 1579
    [root@docker_registry ~]# docker push docker-registry.io:5000/centos:7
    The push refers to repository [docker-registry.io:5000/centos]
    edf3aa290fb3: Pushed 
    7: digest: sha256:c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941 size: 529
    [root@docker_registry ~]# 
    

      提示:可以看到我們上傳的兩個鏡像都完成了上傳沒有報錯,接下來我們去/var/lib/registry/這個目錄,看看是否有這兩個鏡像相關目錄?

    [root@docker_registry ~]# tree /var/lib/registry/
    /var/lib/registry/
    └── docker
        └── registry
            └── v2
                ├── blobs
                │   └── sha256
                │       ├── 13
                │       │   └── 13b80a37370b57f558a2e06092c39224e5d1ebac50e48df0afdeb43cf2303e60
                │       │       └── data
                │       ├── 17
                │       │   └── 176bad61a3a435da03ec603d2bd8f7a69286d92f21f447b17f21f0bc4e085bde
                │       │       └── data
                │       ├── 1b
                │       │   └── 1b56fbc8a8e10830867455c0794a70f5469c154cdc013554daf501aeda3f30fe
                │       │       └── data
                │       ├── 26
                │       │   └── 266247e2e603e1c840f97cb4d97a08b9184344e9802966cb42c93d21c407839f
                │       │       └── data
                │       ├── 3c
                │       │   └── 3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6
                │       │       └── data
                │       ├── 42
                │       │   └── 42d8e66fa893de4beb5d136b787cf182b24b7f4972c4212b9493b661ad1d7e85
                │       │       └── data
                │       ├── 52
                │       │   └── 524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
                │       │       └── data
                │       ├── 57
                │       │   └── 57eade024bfbd48c45ef2bad996c4d6a0fa41b692247294745265af738066813
                │       │       └── data
                │       ├── 85
                │       │   └── 85ecb68de4693bb4093d923f6d1062766e4fa7cbb3bf456a2bc19dd3e6c5e6c6
                │       │       └── data
                │       ├── b5
                │       │   └── b5b4d78bc90ccd15806443fb881e35b5ddba924e2f475c1071a38a3094c3081d
                │       │       └── data
                │       └── c2
                │           └── c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941
                │               └── data
                └── repositories
                    ├── centos
                    │   ├── _layers
                    │   │   └── sha256
                    │   │       ├── 524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
                    │   │       │   └── link
                    │   │       └── b5b4d78bc90ccd15806443fb881e35b5ddba924e2f475c1071a38a3094c3081d
                    │   │           └── link
                    │   ├── _manifests
                    │   │   ├── revisions
                    │   │   │   └── sha256
                    │   │   │       └── c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941
                    │   │   │           └── link
                    │   │   └── tags
                    │   │       └── 7
                    │   │           ├── current
                    │   │           │   └── link
                    │   │           └── index
                    │   │               └── sha256
                    │   │                   └── c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941
                    │   │                       └── link
                    │   └── _uploads
                    └── flannel
                        ├── _layers
                        │   └── sha256
                        │       ├── 13b80a37370b57f558a2e06092c39224e5d1ebac50e48df0afdeb43cf2303e60
                        │       │   └── link
                        │       ├── 176bad61a3a435da03ec603d2bd8f7a69286d92f21f447b17f21f0bc4e085bde
                        │       │   └── link
                        │       ├── 1b56fbc8a8e10830867455c0794a70f5469c154cdc013554daf501aeda3f30fe
                        │       │   └── link
                        │       ├── 266247e2e603e1c840f97cb4d97a08b9184344e9802966cb42c93d21c407839f
                        │       │   └── link
                        │       ├── 42d8e66fa893de4beb5d136b787cf182b24b7f4972c4212b9493b661ad1d7e85
                        │       │   └── link
                        │       ├── 57eade024bfbd48c45ef2bad996c4d6a0fa41b692247294745265af738066813
                        │       │   └── link
                        │       └── 85ecb68de4693bb4093d923f6d1062766e4fa7cbb3bf456a2bc19dd3e6c5e6c6
                        │           └── link
                        ├── _manifests
                        │   ├── revisions
                        │   │   └── sha256
                        │   │       └── 3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6
                        │   │           └── link
                        │   └── tags
                        │       └── v0.12.0-s390x
                        │           ├── current
                        │           │   └── link
                        │           └── index
                        │               └── sha256
                        │                   └── 3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6
                        │                       └── link
                        └── _uploads
    
    65 directories, 26 files
    [root@docker_registry ~]# 
    

      提示:可以看到對應目錄下有兩個子目錄就是以我們上傳的鏡像名稱命名的;

      示例:查看私有倉庫中存在的進行列表

    [root@docker_registry ~]# curl docker-registry.io:5000/v2/_catalog
    {"repositories":["centos","flannel"]}
    [root@docker_registry ~]# 

      示例:下載私有倉庫中的鏡像到本地

    [root@docker_node01 ~]# ip a l ens33
    2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 00:0c:29:22:36:7f brd ff:ff:ff:ff:ff:ff
        inet 192.168.0.22/24 brd 192.168.0.255 scope global ens33
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:fe22:367f/64 scope link 
           valid_lft forever preferred_lft forever
    [root@docker_node01 ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    linux1874/myimg     v0.1                e408b1c6e04f        2 weeks ago         1.22MB
    wordpress           latest              c3fa1c8546fb        5 weeks ago         540MB
    mysql               5.7                 f965319e89de        5 weeks ago         448MB
    alpine              v3                  f70734b6a266        6 weeks ago         5.61MB
    nginx               1.14-alpine         8a2fb25a19f5        14 months ago       16MB
    httpd               2.4.37-alpine       dfd436f9a5d8        17 months ago       91.8MB
    [root@docker_node01 ~]# docker pull 192.168.0.99:5000/flannel:v0.12.0-s390x
    v0.12.0-s390x: Pulling from flannel
    176bad61a3a4: Pull complete 
    13b80a37370b: Pull complete 
    42d8e66fa893: Pull complete 
    266247e2e603: Pull complete 
    1b56fbc8a8e1: Pull complete 
    85ecb68de469: Pull complete 
    Digest: sha256:3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6
    Status: Downloaded newer image for 192.168.0.99:5000/flannel:v0.12.0-s390x
    192.168.0.99:5000/flannel:v0.12.0-s390x
    [root@docker_node01 ~]# docker images
    REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
    linux1874/myimg             v0.1                e408b1c6e04f        2 weeks ago         1.22MB
    wordpress                   latest              c3fa1c8546fb        5 weeks ago         540MB
    mysql                       5.7                 f965319e89de        5 weeks ago         448MB
    alpine                      v3                  f70734b6a266        6 weeks ago         5.61MB
    192.168.0.99:5000/flannel   v0.12.0-s390x       57eade024bfb        2 months ago        56.9MB
    nginx                       1.14-alpine         8a2fb25a19f5        14 months ago       16MB
    httpd                       2.4.37-alpine       dfd436f9a5d8        17 months ago       91.8MB
    [root@docker_node01 ~]# 
    

      提示:下載私有倉庫中的鏡像,默認情況docker也是不支持直接訪問http協議的倉庫,需要我們手動去配置insecure-registries,然後重啟docker才可以;

      示例:刪除私有倉庫中的鏡像

      1、獲取對應鏡像的sha256的值 curl –header “Accept:application/vnd.docker.distribution.manifest.v2+json” -I -X GET http://<registry addr>/v2/<image name>/manifests/<image tag>

      2、刪除對應鏡像版本元數據 curl -I -X DELETE http://<registry addr>/v2/<image name>/manifests/<image digest>

      提示:如果響應405方法不被允許;我們需要修改私有倉庫的配置文件,將其配置為允許刪除;如下

    [root@docker_registry ~]# cat /etc/docker-distribution/registry/config.yml
    version: 0.1
    log:
      fields:
        service: registry
    storage:
        delete:
            enabled: true
        cache:
            layerinfo: inmemory
        filesystem:
            rootdirectory: /var/lib/registry
    http:
        addr: :5000
    [root@docker_registry ~]# systemctl restart docker-distribution           
    [root@docker_registry ~]# curl -IX DELETE http://docker-registry.io:5000/v2/centos/manifests/sha256:c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941
    HTTP/1.1 202 Accepted
    Docker-Distribution-Api-Version: registry/2.0
    Date: Sat, 06 Jun 2020 19:55:52 GMT
    Content-Length: 0
    Content-Type: text/plain; charset=utf-8
    
    [root@docker_registry ~]#
    

      提示:degest值包含”sha256:”

      3、垃圾回收清理

    [root@docker_registry ~]# registry garbage-collect /etc/docker-distribution/registry/config.yml 
    centos
    flannel
    flannel: marking manifest sha256:3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6 
    flannel: marking blob sha256:57eade024bfbd48c45ef2bad996c4d6a0fa41b692247294745265af738066813
    flannel: marking blob sha256:176bad61a3a435da03ec603d2bd8f7a69286d92f21f447b17f21f0bc4e085bde
    flannel: marking blob sha256:13b80a37370b57f558a2e06092c39224e5d1ebac50e48df0afdeb43cf2303e60
    flannel: marking blob sha256:42d8e66fa893de4beb5d136b787cf182b24b7f4972c4212b9493b661ad1d7e85
    flannel: marking blob sha256:266247e2e603e1c840f97cb4d97a08b9184344e9802966cb42c93d21c407839f
    flannel: marking blob sha256:1b56fbc8a8e10830867455c0794a70f5469c154cdc013554daf501aeda3f30fe
    flannel: marking blob sha256:85ecb68de4693bb4093d923f6d1062766e4fa7cbb3bf456a2bc19dd3e6c5e6c6
    myweb
    myweb: marking manifest sha256:aaf04cf567a776e36eb3b0bafaec17ed8d9e0a743bdb897dca13f251250ae493 
    myweb: marking blob sha256:4f406abeaab7f848178867409142090d1a551b22b968be6a6dae733c8403738e
    myweb: marking blob sha256:524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
    myweb: marking blob sha256:c941076f9075280c41b502283f37ab8bafef3a66f4a7ba299838dce07641a48d
    test
    test: marking manifest sha256:5ecad23ab8a52e55f93968f708d325261032dd613287aec92e7cf8ddd6426635 
    test: marking blob sha256:370e3a843c3cb12700301e3f87f929939146cd8b676260bedcd83aaa7fcc2939
    test: marking blob sha256:524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
    test: marking manifest sha256:da8b53210bf1f4dc4873bbd5589abad616663cda45205ae3a4fffb0729d2730d 
    test: marking blob sha256:461f6ceabc885e2e90b5f9ee82aefc9a30a39510c40e7cd8fb7436a4d340fe1d
    test: marking blob sha256:524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
    test: marking blob sha256:035e026f1d6b0acba3413ba616dcbabf75d20e945778c52716e601255452b7b7
    
    17 blobs marked, 2 blobs eligible for deletion
    blob eligible for deletion: sha256:b5b4d78bc90ccd15806443fb881e35b5ddba924e2f475c1071a38a3094c3081d
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/b5/b5b4d78bc90ccd15806443fb881e35b5ddba924e2f475c1071a38a3094c3081d  go.version=go1.9.4 instance.id=b3029d7f-99e8-4941-8c87-989514b584ea
    blob eligible for deletion: sha256:c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/c2/c2f1d5a9c0a81350fa0ad7e1eee99e379d75fe53823d44b5469eb2eb6092c941  go.version=go1.9.4 instance.id=b3029d7f-99e8-4941-8c87-989514b584ea
    [root@docker_registry ~]# 
    

      測試:下載docker-registry.io:5000/centos:7 看看是否還能下載?

    [root@docker_node01 ~]# docker pull 192.168.0.99:5000/centos:7
    Error response from daemon: manifest for 192.168.0.99:5000/centos:7 not found: manifest unknown: manifest unknown
    [root@docker_node01 ~]# 
    

      提示:以上提示告訴我們沒有對應鏡像的元數據信息;說明我們私有倉庫沒有對應鏡像;以上方法適合精準刪除某個鏡像的某個版本,如果是刪除一個倉庫,直接刪除 /var/lib/registry/docker/registry/v2/repositories/下對應倉庫的目錄,然後在用registry命令做垃圾回收;如下

    [root@docker_registry ~]# ll /var/lib/registry/docker/registry/v2/repositories/
    total 0
    drwxr-xr-x 5 root root 55 Jun  6 14:16 centos
    drwxr-xr-x 5 root root 55 Jun  6 14:15 flannel
    drwxr-xr-x 5 root root 55 Jun  6 15:25 myweb
    drwxr-xr-x 5 root root 55 Jun  6 15:24 test
    [root@docker_registry ~]# rm -rf /var/lib/registry/docker/registry/v2/repositories/test
    [root@docker_registry ~]# rm -rf /var/lib/registry/docker/registry/v2/repositories/myweb
    [root@docker_registry ~]# ll /var/lib/registry/docker/registry/v2/repositories/
    total 0
    drwxr-xr-x 5 root root 55 Jun  6 14:16 centos
    drwxr-xr-x 5 root root 55 Jun  6 14:15 flannel
    [root@docker_registry ~]# registry garbage-collect /etc/docker-distribution/registry/config.yml 
    centos
    flannel
    flannel: marking manifest sha256:3ce5b8d40451787e1166bf6b207c7834c13f7a0712b46ddbfb591d8b5906bfa6 
    flannel: marking blob sha256:57eade024bfbd48c45ef2bad996c4d6a0fa41b692247294745265af738066813
    flannel: marking blob sha256:176bad61a3a435da03ec603d2bd8f7a69286d92f21f447b17f21f0bc4e085bde
    flannel: marking blob sha256:13b80a37370b57f558a2e06092c39224e5d1ebac50e48df0afdeb43cf2303e60
    flannel: marking blob sha256:42d8e66fa893de4beb5d136b787cf182b24b7f4972c4212b9493b661ad1d7e85
    flannel: marking blob sha256:266247e2e603e1c840f97cb4d97a08b9184344e9802966cb42c93d21c407839f
    flannel: marking blob sha256:1b56fbc8a8e10830867455c0794a70f5469c154cdc013554daf501aeda3f30fe
    flannel: marking blob sha256:85ecb68de4693bb4093d923f6d1062766e4fa7cbb3bf456a2bc19dd3e6c5e6c6
    
    8 blobs marked, 9 blobs eligible for deletion
    blob eligible for deletion: sha256:370e3a843c3cb12700301e3f87f929939146cd8b676260bedcd83aaa7fcc2939
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/37/370e3a843c3cb12700301e3f87f929939146cd8b676260bedcd83aaa7fcc2939  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/52/524b0c1e57f8ee5fee01a1decba2f301c324a6513ca3551021264e3aa7341ebc  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:5ecad23ab8a52e55f93968f708d325261032dd613287aec92e7cf8ddd6426635
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/5e/5ecad23ab8a52e55f93968f708d325261032dd613287aec92e7cf8ddd6426635  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:aaf04cf567a776e36eb3b0bafaec17ed8d9e0a743bdb897dca13f251250ae493
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/aa/aaf04cf567a776e36eb3b0bafaec17ed8d9e0a743bdb897dca13f251250ae493  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:035e026f1d6b0acba3413ba616dcbabf75d20e945778c52716e601255452b7b7
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/03/035e026f1d6b0acba3413ba616dcbabf75d20e945778c52716e601255452b7b7  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:461f6ceabc885e2e90b5f9ee82aefc9a30a39510c40e7cd8fb7436a4d340fe1d
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/46/461f6ceabc885e2e90b5f9ee82aefc9a30a39510c40e7cd8fb7436a4d340fe1d  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:4f406abeaab7f848178867409142090d1a551b22b968be6a6dae733c8403738e
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/4f/4f406abeaab7f848178867409142090d1a551b22b968be6a6dae733c8403738e  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:c941076f9075280c41b502283f37ab8bafef3a66f4a7ba299838dce07641a48d
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/c9/c941076f9075280c41b502283f37ab8bafef3a66f4a7ba299838dce07641a48d  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    blob eligible for deletion: sha256:da8b53210bf1f4dc4873bbd5589abad616663cda45205ae3a4fffb0729d2730d
    INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/da/da8b53210bf1f4dc4873bbd5589abad616663cda45205ae3a4fffb0729d2730d  go.version=go1.9.4 instance.id=1a15f1e7-194f-4a82-b79d-9f437d975f6e
    [root@docker_registry ~]# 
    

      提示:這種方式比較粗暴簡單,通常是一個倉庫里只有一個版本鏡像可以使用這種方式刪除,如果一個倉庫有多個版本,那麼還是建議使用第一種方式;

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

    【其他文章推薦】

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

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

    ※回頭車貨運收費標準

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

    ※超省錢租車方案

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

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