比帕薩特便宜3萬多 舒適上檔次的大牌B級車真不差!_網頁設計公司

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

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

無鑰匙啟動/進入、自動駐車、換擋撥片等配置一應俱全。作為一款中級車的雅閣後排空間也有着很好的表現,完全可以體現家、商兩用意,雅閣採用真皮座椅的質感很棒,雅閣的座椅乘坐舒適度很高。車系搭載了2。0L/2。4L的自然吸氣發動機,整套的動力系統是比較充沛的,並搭載了CVT變速箱,十分平順,穩定性也特別高,加速力道的輸出相當平均。

帕薩特在國內的中級車市場里,蟬聯了多年的中級車銷量冠軍,帕薩特這個名字一定已深入人心了。銷量好,自然就會供不應求,優惠的力度也是比較低。B級車的車型可選擇非常多,這不,今天小編就給大家挑選幾輛品質好,優惠幅度大的B級車。

上海通用別克-君威

指導價:17.89-27.99萬

君威車型的外觀設計優雅、年輕化了許多,車身的線條也非常動感,其轎跑的運動造型備受歡迎,前臉採用了別克家族式設計,直瀑式鍍鉻中網有很大的視覺衝擊力,尾部上翹的設計突出了視覺的亮點,雙邊共兩出的排氣更顯運動氣息。

環抱式的中控台一直非常吸引人,君威的中控採用了大量的軟質材料覆蓋,整體的質感提升不少,胎壓監測、無鑰匙進入/啟動、上坡輔助、后視鏡自動摺疊等豐富的配置。

長寬高4843*1856*1484*2737mm,軸距為2737mm的車身尺寸的空間略顯倉促,相比在同級別里君威的乘坐方面並沒有優勢,但實際表現也還是不錯的,滿足日常使用。車型搭載了1.6T/2.0T渦輪發動機,配備6AT變速箱,整體的平順性不是特別高,但是豐富的行駛質感是非常不錯,整個底盤非常的硬朗,

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

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

指向也非常精準。

廣汽本田-雅閣

指導價:16.98-27.98萬

雅閣的外形採用了本田的家族式設計,前臉採用了飛翼式中網,車身整體十分寬大,車身線條十分動感。排氣管採用了雙邊雙出的設計,還有一道細長的鍍鉻裝飾點綴,讓尾部看起來非常大氣!

中控台的雙層設計非常有層次感,線條更為豐富,大量的真皮材料和木紋飾板的使用提升了整車的質感。無鑰匙啟動/進入、自動駐車、換擋撥片等配置一應俱全。

作為一款中級車的雅閣後排空間也有着很好的表現,完全可以體現家、商兩用意,雅閣採用真皮座椅的質感很棒,雅閣的座椅乘坐舒適度很高。車系搭載了2.0L/2.4L的自然吸氣發動機,整套的動力系統是比較充沛的,並搭載了CVT變速箱,十分平順,穩定性也特別高,加速力道的輸出相當平均。

東風日產-天籟

指導價:17.58-29.88萬

天籟採用了日產最新家族式設計風格,包括了“迴旋鏢”式前大燈以及“V”型前格柵,新車的前保險杠也相應地進行調整以配合前格柵造型設計,搭配全新樣式的17英寸多輻式輪圈,整體看上去更加年輕時尚,並且富含肌肉感。

內飾方面,天籟採用了以黑色為主調,整體的布局都非常簡潔、舒適,易於操作。主/副駕駛座安全氣囊、前側氣囊、前/後排頭部氣囊(氣簾)安全裝備全系標配,可見日產對安全性的重視性!

天籟車身尺寸長寬高分別為5003/1830/1490mm,軸距達到2900mm,空間方面不是能用拳頭能量的,座椅舒適度非常高,有買了天籟車主的說法,天籟的座椅就像移動沙發!可見舒適程度是非常高的!車系搭載了2.0L/2.5L自然吸氣發動機,動力方面絕對的夠用,搭載了CVT變速箱,開起來平順性非常不錯,如絲般順滑的感覺。整個底盤的濾震處理的非常不錯,底盤的調校以舒適為主!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

為何德國車能稱霸全球?帶你到汽車發源地一探究竟_網頁設計公司

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

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

本茨他媳婦,瞞着丈夫,帶著兒子Eugen和Richard,獨自駕駛車輛從曼海姆途徑海德堡最終到達普福爾茨海姆,成為世界上第一個駕駛汽車進行長途旅行的人。德國最美公路-B500這就是德國最美公路,因為公路橫跨整個黑森林,這條路又稱黑森林之路。

前不久去了德國的慕尼黑,參加寶馬的100周年慶,那種從螺絲釘里散發出來的汽車文化着實讓我們嚮往,這一次呢由於梅賽德斯奔馳的活動,又回到了德國,不過這次的行程可比上次豐富多了。

Mercedes me

我們先來到了漢堡市。這間佔地550平方米的Mercedes me是集餐飲,藝術,諮詢服務於一體的新概念品牌體驗店,於2014年6月6日開業。進去就是我們本次活動的主角表兄弟,見怪不怪的是旅行版的車在這邊路上隨處可見,知識淵博的朋友可能會知道這是全球性都之首,不過可是有家室的人,所以還是去看場球賽吧。

德國戰車

比賽在北方銀行競技球場(德語:volksparkstation)。上場的是德國隊和捷克隊,德國戰車可不是浪得虛名,所以···最後結果好像是3比0。可怕的是之前在活動現場,曾在綠茵場上歷下赫赫戰功的名將、前德國國家隊隊長奧利弗·比埃爾霍夫就預測當晚世界杯預選賽德國隊將以3:0大比分獲勝。

綠色地獄

因為紐博格林賽道整個建在森林里,由於賽道太長導致救援困難,所以又有綠色地獄之稱。而紐北的駕駛學院Nurburgring driving academy,差不多就是紐北的新東方,教練教一些你必備的知識,坐上大巴講解一遍賽道,就可以刷圈了,不過畢竟不是老司機,而且真實的路況像路面坡度起伏,顛簸程度,比之前從圖片和視頻上看起來更誇張。當天的教練說一般的家用車在紐北造上5公里左右剎車系統就開始衰竭,

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

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

同行的小夥伴見到冒煙趕緊拿出手機發小視頻,畢竟自己的車可舍不得開到冒煙。

奔馳之路

又累又爽的運動,下賽道算一個吧,在結束了紐北體驗后我們又重走了一遍奔馳之路,参觀了世上第一個加油站,話說在1888年8月的一天,貝塔.本茨也就是卡爾.本茨他媳婦,瞞着丈夫,帶著兒子Eugen和Richard,獨自駕駛車輛從曼海姆途徑海德堡最終到達普福爾茨海姆,成為世界上第一個駕駛汽車進行長途旅行的人。

德國最美公路-B500

這就是德國最美公路,因為公路橫跨整個黑森林,這條路又稱黑森林之路。

而黑森林最為有名的特產,就是黑森林蛋糕。相傳,櫻桃豐收的時候,農婦們除了將過剩的櫻桃製成果醬外,在做蛋糕時,也會大方地將櫻桃一顆顆塞在蛋糕的夾層里,或是作為裝飾細心地點綴在蛋糕的表面。而在打制蛋糕的鮮奶油時,更會加入大量櫻桃汁。製作蛋糕坯時,麵糊中也加入櫻桃汁和櫻桃酒。這種以櫻桃與鮮奶油為主的蛋糕從黑森林傳到外地后,也就變成所謂的“黑森林蛋糕”了。

奔馳博物館

建築內部仿照人體DNA建造的標誌性雙螺旋結構呈現了名牌的歷史和經典,這裏總共展出了160輛車和1500多件展品,毫無間斷的展現出汽車130年的發展歷,畢竟有汽車發明者之稱,其他汽車博物館再講也沒有奔馳的故事多。

老爺車試駕

來到汽車文化底蘊濃厚的國家怎麼能不試一下老爺車呢?大家見過各種樣式的換擋桿,可有見過手動擋的懷擋?讓我們來一起和駕駛員感受下,哈哈。坐在奔馳老爺車中,穿行在德國城市和鄉村間,彷彿一起回到了50年前。

整個行程下來,是相當的精彩,真希望在不久的將來能再次到德國為大家帶來更多好玩的資訊。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

2020年輻射安全監管工作座談會在甘召開_如何寫文案

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

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

2020-10-21

2020-10-21
分享到:
[打印]
字號:[大] [中] [小]   2020年10月19-20日,全國輻射安全監管工作座談會在甘肅省蘭州市成功召開,生態環境部副部長、國家核安全局局長劉華出席會議並講話。   會上,生態環境部輻射源安全監管司、核設施安全監管司負責人分別介紹2020年輻射安全監管工作情況。江蘇省生態環境廳、輻射環境監測技術中心作典型發言,分別介紹輻射安全監管工作經驗。   會議指出,全系統要強化政治意識,切實提升核與輻射安全的責任感和使命感;強化憂患意識,清醒應對當前核與輻射安全監管工作中的風險和挑戰;強化擔當意識,努力加強核與輻射安全監管隊伍建設。要準確把握形勢任務,創新思路方法,

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

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

加快推進核與輻射安全監管體系和監管能力現代化。   會議要求,全系統要聚焦工作重點,強化擔當作為,一要堅決貫徹落實黨中央決策部署和中央領導指示批示,做好各項重點工作;二要強化核技術利用領域事中事後監管,嚴格處罰違法行為;三要用好國家核技術利用輻射安全管理系統,推進政務全程網辦和監管信息化;四要進一步做好輻射安全培訓考核,鞏固改革成果;五要在第二次全國污染源普查成果的基礎上做好伴生放射性礦輻射安全監管工作;六要完善電磁輻射污染防治相關監管制度頂層設計,破解鄰避難題;七要認真落實放射性物品運輸法律法規要求,堅決做到履職盡責;八要繼續做好輻射監測工作,切實加強核與輻射應急能力建設。   生態環境部相關司局、各地區核與輻射安全監督站和技術支持單位、各省(區、市)生態環境保護主管部門,以及解放軍有關單位相關負責人出席了會議。

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

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

生態環境部黨組召開會議 傳達學習貫徹黨的十九屆五中全會精神_網頁設計

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

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

2020-10-30 來源:生態環境部

2020-10-30
來源:生態環境部 分享到:
[打印]
字號:[大] [中] [小]

  10月30日,生態環境部黨組書記孫金龍主持召開部黨組會議,傳達學習黨的十九屆五中全會精神,研究部署貫徹落實工作。生態環境部部長黃潤秋列席會議。

  會議傳達學習習近平總書記在黨的十九屆五中全會上關於中央政治局工作的報告、在全會第二次全體會議上的重要講話和《中共中央關於制定國民經濟和社會發展第十四個五年規劃和二〇三五年遠景目標的建議(討論稿)》的說明及全會通過的《建議》主要內容。

  會議指出,全會是在決勝全面建成小康社會、開啟全面建設社會主義現代化國家新征程的關鍵時期召開的一次具有全局性、歷史性意義的重要會議。全會從黨和國家事業發展的全局和長遠出發,擘畫了“十四五”乃至到2035年經濟社會發展的宏偉藍圖,集中回答了新形勢下實現什麼樣的發展、如何實現發展這個重大問題,對實現“兩個一百年”奮鬥目標、實現中華民族偉大復興的中國夢,具有重大的現實意義和深遠的歷史意義。全會審議通過的《建議》,清晰展望了二〇三五年基本實現社會主義現代化的遠景目標,明確提出了“十四五”時期我國發展的指導方針、主要目標、重點任務、重大舉措,是開啟全面建設社會主義現代化國家新征程、向第二個百年奮鬥目標進軍的綱領性文件。習近平總書記在全會上的重要講話,充分肯定黨的十九屆四中全會以來中央政治局的工作,高度評價決勝全面建成小康社會取得的決定性成就,深刻分析國際國內形勢帶來的新矛盾新挑戰,進一步明確我國社會主要矛盾變化帶來的新特徵新要求,作出我國仍處於重要戰略機遇期,但機遇和挑戰都有新的發展變化的重大戰略判斷,為謀划今後五年乃至到2035年我國經濟社會發展提供了科學指南和根本遵循。

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

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

  會議強調,“十三五”時期是我國極不平凡的五年,以習近平同志為核心的黨中央高瞻遠矚、運籌帷幄、把舵定向,團結帶領全黨全國各族人民砥礪前行、開拓創新,推動黨和國家各項事業取得新的重大成就。黨的十九屆四中全會以來,尤其是今年面對突如其來的新冠肺炎疫情,習近平總書記親自領導、親自指揮、親自部署,統籌全局、果斷決策,統籌疫情防控和經濟社會發展取得重大戰略成果,彰顯了中國共產黨領導和中國特色社會主義制度的顯著優勢。實踐再次雄辯地證明,有習近平同志為核心的黨中央、全黨的核心領航掌舵,有全黨全國各族人民團結一心、頑強奮鬥,我們就一定能夠戰勝前進道路上出現的各種艱難險阻,一定能夠在新時代把中國特色社會主義更加有力地推向前進。

  會議指出,全會對生態文明建設和生態環境保護作出重大決策部署。習近平總書記的重要講話,總結了黨的十九屆四中全會以來,黨和國家事業包括生態文明建設和生態環境保護繼續取得新的重大成就。《建議》明確提出二〇三五年“美麗中國建設目標基本實現”的遠景目標和“十四五”時期“生態文明建設實現新進步”的新目標新任務,並就“推動綠色發展,促進人與自然和諧共生”作出具體部署,充分體現了以習近平同志為核心的黨中央對生態文明建設和生態環境保護一以貫之的高度重視,充分展示了持續改善生態環境質量,提高人民群眾獲得感、幸福感、安全感的堅定意志和戰略定力,為新時代加強生態文明建設和生態環境保護工作提供了方向指引和行動指南。生態環境系統要深刻領會和貫徹落實新部署新任務新要求,鞏固拓展“十三五”生態環境保護工作成效,接續奮鬥、持續攻堅,努力推動“十四五”時期生態環境保護工作邁上新台階。

  會議強調,學習宣傳貫徹黨的十九屆五中全會精神是當前和今後一個時期的重大政治任務。要按照黨中央部署要求,制定詳細方案計劃,多層次多形式開展學習活動,與學習貫徹習近平新時代中國特色社會主義思想特別是習近平生態文明思想結合起來,與學習《習近平談治國理政》第三卷結合起來,做到學深悟透、融會貫通、學以致用、學用結合。要加強調度評估,堅決打贏打好污染防治攻堅戰,確保如期圓滿實現“十三五”規劃目標任務,增添全面建成小康社會的成色和綠色底色。要認真落實《建議》要求,积極謀划“十四五”生態環境保護工作,抓緊編製“十四五”生態環境保護、二氧化碳排放達峰行動等規劃計劃。要堅持方向不變、力度不減,突出精準治污、科學治污、依法治污,加強細顆粒物和臭氧協同控制,深入打好污染防治攻堅戰。要加快構建現代環境治理體系,推進生態環境治理體系和治理能力現代化。要進一步提升環境應急響應處置能力,加強核安全監管,確保生態環境安全和核與輻射安全。要以狠抓落實中央巡視整改為契機,堅決落實全面從嚴治黨主體責任,認真貫徹新時代黨的組織路線,樹立正確選人用人導向,加快打造生態環境保護鐵軍。

  中央紀委國家監委駐生態環境部紀檢監察組組長、部黨組成員庫熱西,部黨組成員、副部長翟青、趙英民、劉華、庄國泰出席會議。

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

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

生態環境部環評司有關負責人就《經濟、技術政策生態環境影響分析技術指南(試行)》有關問題答記者問_租車

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

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

2020-11-10 來源:生態環境部

2020-11-10
來源:生態環境部 分享到:
[打印]
字號:[大] [中] [小]   生態環境部近日印發了《 經濟、技術政策生態環境影響分析技術指南》(試行)(以下簡稱《指南》)。針對《指南》的出台背景、主要內容、實施重點等問題,生態環境部環評司有關負責人回答了記者的提問。
  問:《指南》發布的背景和意義是什麼?   答:《指南》是貫徹落實《中華人民共和國環境保護法》的重要舉措。《環境保護法》第十四條規定“國務院有關部門和省、自治區、直轄市人民政府組織制定經濟、技術政策,應當充分考慮對環境的影響,聽取有關方面和專家的意見”。為貫徹落實上述規定,“十三五”以來,我部組織環境工程評估中心、環境與經濟政策研究中心、清華大學、北京師範大學等單位,針對區域、產業和城鎮化等領域的典型政策開展了環境評價研究,同時借鑒美國、加拿大、英國、歐盟、世界銀行和相關國際組織制定的政策(戰略)環境評價技術指南等,探索形成了適用於政策生態環境影響分析的技術方法、內容框架和成果要求,在此基礎上編製形成《指南》,可以為經濟、技術政策的制定者在分析政策的生態環境影響方面提供參考。
  問:《指南》的定位是什麼?   答:《指南》是推動政策制定過程中充分考慮生態環境影響的技術指引文件。《指南》列舉了適用的政策類型,提出了一般性分析程序和技術路線,提供了推薦性指標體系和技術方法,政策制定部門在開展環境影響分析工作過程中可根據實際情況增補或調整指標體系,選擇或創新技術方法。
  問:政策生態環境影響分析的作用是什麼?   答:經濟、技術政策關係到一個國家、地區或部門長期發展前景,影響涉及時間跨度大,空間範圍廣,影響類型多樣,政策執行過程中不確定性因素多,可能會對生態環境造成潛在的重大影響。《指南》從環境質量、生態保護、資源消耗、應對氣候變化等四個方面構建了較為全面的指標體系,政策制定部門可通過全面梳理重點識別,判斷政策是否存在重大不利生態環境影響。針對具有潛在重大不利生態環境影響的政策內容,分析其影響範圍和程度,預警可能引發的生態環境風險,通過優化政策內容、完善保障措施和制度,從源頭降低生態環境影響,防控生態環境風險。針對促進生態環境保護、改善環境質量的政策內容,通過提高保障措施和制度的有效性,推動政策落地實施。
  問:政策生態環境影響分析是否涉及新增行政程序?   答:根據《環境保護法》第十四條“國務院有關部門和省、自治區、直轄市人民政府組織制定經濟、技術政策,應當充分考慮對環境的影響”的規定,《重大行政決策程序暫行條例》縣級以上地方人民政府在制(修)定相關政策時應在決策啟動階段開展環境影響和環境效益等分析預測的要求,

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

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

政策制定主體應將生態環境影響分析工作融入政策制定過程。本《指南》僅提供技術指引,不增加行政程序。
  問:《指南》包括哪些主要內容?   答:《指南》包括七部分內容。一是確定經濟、技術政策生態環境影響分析的適用範圍;二是確定政策生態環境影響分析的工作流程;三是提出政策分析內容及步驟,即政策要素解析,相關政策回顧性分析,政策與黨中央、國務院相關決策部署的符合性分析等;四是提出“初步識別”的內容及推薦方法,建議從環境質量、生態保護、資源消耗、應對氣候變化四個方面梳理政策生態環境影響,推薦採用快速、定性分析方法識別政策是否存在重大生態環境影響;五是提出“影響分析”的內容及推薦方法。推薦採用列表法分析政策直接、間接及累積性生態環境影響的範圍和程度,結合不確定性分析預測存在的生態環境風險;六是提出保障措施及制度分析的內容和步驟;七是明確結論與建議。
  問:《指南》推薦採用哪些技術方法?   答:經濟、技術政策生態環境影響範圍廣,影響產生的邏輯鏈條長,執行過程中不確定性因素多,難以定量分析。同時,一些政策出台的周期短、時效性強,需儘快判斷其可能造成的生態環境影響或風險,為政策制定和實施提供支撐和保障,因此《指南》推薦採用快速、定性方法開展生態環境影響分析。在生態環境影響初步識別階段,結合推薦性指標體系採用矩陣分析、檢查表、專家分析等方法,判斷政策是否存在重大不利生態環境影響。在環境影響分析階段,結合政策產生生態環境影響的作用方式和受影響區域特點,採用列表法分析政策對各受影響區域的直接、間接、累積性影響及生態環境風險。鑒於政策生態環境影響分析尚無普遍實踐,開展工作過程中可根據政策類型、政策內容和管理需求合理選擇或創新政策生態環境影響分析技術方法。
  問:《指南》發布后將重點推動哪些後續工作?   答:一是組織開展試點研究,形成案例庫。目前政策生態環境影響分析處於初步推廣階段,下一步將選取典型省份、典型政策領域作為試點推動開展政策生態環境影響分析工作,在試點基礎上逐步完善技術方法體系,建立政策生態環境影響分析案例庫。二是持續開展專題研究,提供更為完善的技術支撐。根據政策類型及政策內容不同,產生生態環境影響的作用機制不同,影響類型和程度也存在很大差異。基於本《指南》提出的一般性程序、技術路線和推薦方法,後續將進一步組織開展專題研究,分析政策生態環境影響機制,研究制定針對不同領域和政策類型的技術路線,提出適用於各分析環節的技術方法,為推動決策機構在政策制定過程中更好考慮對生態環境影響提供技術保障。

※超省錢租車方案

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

沒錯 Facebook 又改版了,差在哪你看得出來嗎?_網頁設計公司

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

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

這世界上有蠻多事情都有機會阻止甚至是逆轉,但 Facebook 似乎想讓我們知道,他們的改版不僅一定改,而且還會一直改。眼看大家還在適應剛改變的新版 Facebook,這次官方又再次宣布將會有重新設計的調整,魔爪則是伸向了粉絲專頁。繼續閱讀沒錯 Facebook 又改版了,差在哪你看得出來嗎?報導內文。

▲圖片來源:Facebook

沒錯 Facebook 又改版了,差在哪你看得出來嗎?

也許是看到了許多人對於新版粉絲專頁變難用的抱怨。總之,Facebook 已經捲起袖子要來做出改變。根據官方的改版要點整理,粉絲專頁的新設計將會更簡潔直覺,讓人更容易掌握專頁的資訊,也可以更快速切換個人檔案與粉絲專頁。

Facebook 還為粉絲專頁提供了專屬的動態消息 News Feed,讓人更容易在專頁上加入對話與追蹤趨勢加強社群之間互動的機會(這看起來就是將快速跟隨的功能再延伸提供…),並會讓知名人物的評論更容易置頂 — 這的確是比較能吸引其他粉絲互動是沒錯啦。

▲圖片來源:Facebook

應該也算是粉絲專頁的版面調整之一。就是近期已經更為偏重希望使用者多「追蹤(Follow)」的政策與功能,已經導致很多粉絲頁變成追蹤數大於讚數的狀況。現在 Facebook 也移除了按讚的孤能,也讓專頁只主要顯示追蹤數字。據說這樣是希望簡化與互動的方式… 但大家狂衝的讚數似乎也突然變得無意義起來了。

▲圖片來源:Facebook

最後,在一波看不太出來的改版之後,Facebook 也針對變得難用的粉絲專頁管理工具做出改進。針對頁面小編的權限提供了更好的權限管理工具 — 可針對廣告、內容、回訊的資格進行分別設定,也改進了通知功能,並加入新的問答頁面與安全功能等。

整體來講,這次的改版理論上應該是要讓觸及互動等表現更好,粉絲專頁的管理也會變得更為簡單才是。只是實際表現如何,顯然還有待台灣這邊開始更新才會知道了 — 據說會在未來幾週內更新(怕.mov)。

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

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

引用來源

延伸閱讀:

IKEA 直接賣「家」了,來看看這既環保又有型的 Tiny Home 小屋拖車

傳超值款 iPad(第九代)將更薄更輕且依然有指紋辨識,至於 iPad Pro…

您也許會喜歡:

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

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

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

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

蘋果 AirTags 防丟追蹤器還沒出,但已有皮革鑰匙圈與眼鏡環三方配件照流出_網頁設計公司

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

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

雖說蘋果的防丟失裝置 AirTags 還沒正式推出,不過目前看來就連副廠配件商也已經備戰中。至於為什麼我們會知道,當然是因為產品照已經被爆料出來啦(笑)。繼續閱讀蘋果 AirTags 防丟追蹤器還沒出,但已有皮革鑰匙圈與眼鏡環三方配件照流出報導內文。

▲圖片來源:Voice

蘋果 AirTags 防丟追蹤器還沒出,但已有皮革鑰匙圈與眼鏡環三方配件照流出

如果有常在注意 Apple 皮革配件產品的朋友,應該都不會對 Nomad 感到太陌生。他們時常針對 iPhone / MacBook 等裝置推出質感不輸原廠的相應保護殼與保護套配件。現在,則是被爆料大神 Evan Bless 給發現,他們已經為 Apple 可能就要推出的 AirTags 藍牙追蹤裝置打造了相關配件。

▲圖片來源:Voice

為了這樣的防丟失產品,Nomad 也設計了與原廠先前流出的配件基本相同功能的鑰匙圈保護套。有意思的是,相對於原廠的圓形造型,Nomad 的皮革鑰匙圈則是方形的設計。然而當我們還在思索這到底是不是為 AirTags 所設計的配件的時候,第二張爆料的眼鏡固定環就巧妙地在調整鬆緊度的圓形機制上,加入了可塞進 AirTags 的空間。

▲圖片來源:Voice

目前看來 AirTags 應該是個功能與 Tile 功能類似,但可能導入 U1 超寬頻晶片來提供更好掌握方向定位的尋物方式。具體的應用似乎也是以盡可能輕便能裝在隨身物品上,藉此在不小心丟失物品時可以起到尋物功能的方向。

▲圖片來源:MacRumors

雖說這並不算什麼新功能,不過相信蘋果只要推出,周邊的各種配件商的一波跟進,將會激盪出不少創新的應用方式吧?

本篇圖片 / 引用來源

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

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

延伸閱讀:

蘋果 App Store 突破 2 千億美金收益,Apple Music 與 Apple TV 也創新紀錄

沒錯 Facebook 又改版了,差在哪你看得出來嗎?

您也許會喜歡:

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

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

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

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

微軟將推出對使用者更友善、更容易使用的檔案恢復工具_網頁設計公司

1{icon} {views}

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

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

人嘛!難免有錯手刪掉不該刪檔案的時候,在 2020 年初時,Microsoft 發表了一個供 Windows 系統恢復檔案的工具,允許用戶反會撤銷決定,恢復從各地永久刪除的檔案,包括資源回收桶。雖然這是個福音,但對於大多數用戶來說還是有不算低的門檻,不過接下來,Microsoft 將讓它變得更友善、更容易使用。

微軟將推出對使用者更友善、更容易使用的檔案恢復工具

在之前推出的 Windows 檔案恢復工具,其實是一個指令工具,它的工作方式與其他第三方應用不太一樣,只能輸入指令來使用它,雖說是免費使用,但因為對使用者友好程度低,使得這個工具立意良善卻普及度不如預期。根據消息,Microsoft 有計畫讓這工具的使用更加簡單,新的改良正在路上。

這項工具目前已經對測試人員釋出,根據 Windows Latest 報導,在最新測試版本中除了速度變得更快,還支援一般與廣泛兩種模式。使用新的「一般」模式,你可以掃描磁碟機 (NTFS 檔案系統) 以尋找被刪除檔案並嘗試還原。Microsoft 指出,一般模式是使用者的標準恢復選項,適用於恢復近期刪除的檔案。任何具備一點指令基本知識的人都能夠恢復他們的檔案,雖然一般模式對使用者更友好,但如果硬碟中的可用空間已經被其他檔案所覆蓋,它可能就失去作用了,尤其是如果你的電腦中是使用 SSD 的話。

Microsoft 表示,從 2020 年首度發表檔案恢復工具以來,陸續收到許多使用者的意見回饋,未來幾個月內,該工具將會推出更多改良,第一個大更新會在 2021 年初與 Windows 10 2004 更新或更新的版本推出給普羅大眾。

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

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

◎資料來源:Windows Latest

您也許會喜歡:

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

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

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

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

ClickHouse源碼筆記1:聚合函數的實現_網頁設計公司

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

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

由於工作的需求,後續筆者工作需要和開源的OLAP數據庫ClickHouse打交道。ClickHouse是Yandex在2016年6月15日開源了一個分析型數據庫,以強悍的單機處理能力被稱道
筆者在實際測試ClickHouse和閱讀ClickHouse的源碼過程之中,對”戰鬥民族”開發的數據庫十分欣賞。ClickHouse不僅是一個很好的數據庫學習材料,而且同時應用了大量的CPP17的新特性進行開發,也是一個大型的Modern CPP的教導資料。
筆者接下來會陸續將閱讀ClickHouse的部分心得體會與通過源碼閱讀筆記的方式和大家分享,坦白說,這種源碼閱讀筆記很難寫啊。(多一分繁瑣,少一分就模糊了~~)
第一篇文章,我們就從聚合函數的實現開始聊起~~ 上車!

1.基礎知識的梳理

什麼是聚合函數?

聚合函數: 顧名思義就是對一組數據執行聚合計算並返回結果的函數。
這類函數在數據庫之中很常見,如:count, max, min, sum等等。

ClickHouse的實現接口
  • IAggregateFunction接口
    在ClickHouse之中,定義了一個統一的聚合函數接口:IAggregateFunction.(在ClickHouse之中,所有的接口類都是以大寫的I開頭的。) 上文筆者提到的聚合函數,則都是作為抽象類IAggregateFunction的子類實現的。其中該接口最為核心的方法是下面這5個方法:
    • add函數:最為核心的調用接口,將對應AggregateDataPtr指針之中數據取出,與列columns中的第row_num的數據進行對應的聚合計算。(這裏可以看到ClickHouse是一個純粹的列式存儲數據庫,所有的操作都是基於列的數據結構。)
    • merge函數:將兩個聚合結果進行合併的函數,通常用在併發執行聚合函數的過程之中,需要將對應的聚合結果進行合併。
    • serialize函數與deserialize函數:序列化與反序列化的函數,通常用於spill to disk或分佈式場景需要保存或傳輸中間結果的。
    • addBatch函數:這是函數也是非常重要的,雖然它僅僅實現了一個for循環調用add函數。它通過這樣的方式來減少虛函數的調用次數,並且增加了編譯器內聯的概率。(虛函數的調用需要一次訪存指令,一次查表,最終才能定位到需要調用的函數上,這在傳統的火山模型的實現上會帶來極大的CPU開銷。
  /** Adds a value into aggregation data on which place points to.
     *  columns points to columns containing arguments of aggregation function.
     *  row_num is number of row which should be added.
     *  Additional parameter arena should be used instead of standard memory allocator if the addition requires memory allocation.
     */
    virtual void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena * arena) const = 0;

    /// Merges state (on which place points to) with other state of current aggregation function.
    virtual void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena * arena) const = 0;

    /// Serializes state (to transmit it over the network, for example).
    virtual void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const = 0;

    /// Deserializes state. This function is called only for empty (just created) states.
    virtual void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena * arena) const = 0;
    // /** Contains a loop with calls to "add" function. You can collect arguments into array "places"
      *  and do a single call to "addBatch" for devirtualization and inlining.
      */
    virtual void addBatch(size_t batch_size, AggregateDataPtr * places, size_t place_offset, const IColumn ** columns, Arena * arena) const = 0;

  • 抽象類IColumn
    上面的接口IAggregateFunction的函數使用到了ClickHouse的核心接口IColumn類,這裏也進行簡要的介紹。 IColumn 接口表達了所有數據在ClickHouse之中的用內存表達的數據結構,其他帶有具體數據類型的如ColumnUInt8、ColumnArray 等, 都實現了對應的列接口,並且在子類之中具象實現了不同的內存布局。
    IColumn的子類實現細節很瑣碎,筆者這裏就暫時不展開講了,筆者這裏就簡單講講涉及到聚合函數調用部分的IColumn接口的對應方法:
    這裏columns是一個二維數組,通過columns[0]可以取到第一列。(這裏只有涉及到一列,為什麼columns是二維數組呢?因為處理array等列的時候,也是通過對應的接口,而array就需要應用二維數組了. )
    注意這裡有一個強制的類型轉換,column已經轉換為ColVecType類型了,這是模板派生出IColumn的子類。
    然後通過IColumn子類實現的getData方法獲取對應row_num行的數據進行add函數調用就完成了一次聚合函數的計算了。
    void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const override
    {
        const auto & column = static_cast<const ColVecType &>(*columns[0]);
        this->data(place).add(column.getData()[row_num]);
    }
  • IAggregateFunctionHelper接口
    這個接口是上面提到 IAggregateFunction的輔助子類接口,它很巧妙的通過模板的類型派生,將虛函數的調用轉換為函數指針的調用,這個在實際聚合函數的實現過程之中能夠大大提高計算的效率。
    函數addFree就實現了我上述所說的過程,但是它是一個private的函數,所以通常我們都是通過getAddressOfAddFunction獲取對應的函數地址。這在聚合查詢的過程之中能夠提高20%左右的執行效率。
template <typename Derived>
class IAggregateFunctionHelper : public IAggregateFunction
{
private:
    static void addFree(const IAggregateFunction * that, AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena * arena)
    {
        static_cast<const Derived &>(*that).add(place, columns, row_num, arena);
    }

public:
    IAggregateFunctionHelper(const DataTypes & argument_types_, const Array & parameters_)
        : IAggregateFunction(argument_types_, parameters_) {}

    AddFunc getAddressOfAddFunction() const override { return &addFree; }
  • AggregateFunctionFactory類
    顧名思義,這個是一個生成聚合函數的工廠類。它的邏輯很簡單,所有ClickHouse之中所相關的聚合函數都是通過這個工廠類註冊並且獲取,然後進行調用的。
class AggregateFunctionFactory final : private boost::noncopyable, public IFactoryWithAliases<AggregateFunctionCreator>
{
public:

    static AggregateFunctionFactory & instance();

    /// Register a function by its name.
    /// No locking, you must register all functions before usage of get.
    void registerFunction(
        const String & name,
        Creator creator,
        CaseSensitiveness case_sensitiveness = CaseSensitive);

    /// Throws an exception if not found.
    AggregateFunctionPtr get(
        const String & name,
        const DataTypes & argument_types,
        const Array & parameters = {},
        int recursion_level = 0) const;

2.聚合函數的註冊流程

有了上述的背景知識,我們接下來舉個栗子。來看看一個聚合函數的實現細節,以及它是如何被使用的。

AggregateFunctionSum

筆者這裏選取了一個很簡單的聚合算子Sum,我們來看看它實現的代碼細節。
這裏我們可以看到AggregateFunctionSum是個final類,無法被繼承了。而它繼承了上面提到的IAggregateFunctionHelp類的子類IAggregateFunctionDataHelper類。

這裏我們就重點看,這個類override了getName方法,返回了對應的名字sum。並且實現了我們上文提到的四個核心的方法。

  • add
  • merge
  • seriable
  • deserialize
template <typename T, typename TResult, typename Data>
class AggregateFunctionSum final : public IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data>>
{
public:
    using ResultDataType = std::conditional_t<IsDecimalNumber<T>, DataTypeDecimal<TResult>, DataTypeNumber<TResult>>;
    using ColVecType = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<T>, ColumnVector<T>>;
    using ColVecResult = std::conditional_t<IsDecimalNumber<T>, ColumnDecimal<TResult>, ColumnVector<TResult>>;

    String getName() const override { return "sum"; }

    AggregateFunctionSum(const DataTypes & argument_types_)
        : IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data>>(argument_types_, {})
        , scale(0)
    {}

    AggregateFunctionSum(const IDataType & data_type, const DataTypes & argument_types_)
        : IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data>>(argument_types_, {})
        , scale(getDecimalScale(data_type))
    {}

    DataTypePtr getReturnType() const override
    {
        if constexpr (IsDecimalNumber<T>)
            return std::make_shared<ResultDataType>(ResultDataType::maxPrecision(), scale);
        else
            return std::make_shared<ResultDataType>();
    }

    void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const override
    {
        const auto & column = static_cast<const ColVecType &>(*columns[0]);
        this->data(place).add(column.getData()[row_num]);
    }

    void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena *) const override
    {
        this->data(place).merge(this->data(rhs));
    }

    void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const override
    {
        this->data(place).write(buf);
    }

    void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena *) const override
    {
        this->data(place).read(buf);
    }

    void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override
    {
        auto & column = static_cast<ColVecResult &>(to);
        column.getData().push_back(this->data(place).get());
    }

private:
    UInt32 scale;
};

接下來,ClickHouse實現了兩種聚合計算:AggregateFunctionSumDataAggregateFunctionSumKahanData。後者是用Kahan算法避免float類型精度損失的,我們可以暫時不細看。直接看SumData的實現。這是個模板類,之前我們講到AggregateFunction的函數就是通過AggregateDataPtr指針來獲取AggregateFunctionSumData的地址,來調用add實現聚合算子的。我們可以看到AggregateFunctionSumData實現了前文提到的add, merge, write,read四大方法,正好和接口一一對應上了。

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

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

template <typename T>
struct AggregateFunctionSumData
{
    T sum{};

    void add(T value)
    {
        sum += value;
    }

    void merge(const AggregateFunctionSumData & rhs)
    {
        sum += rhs.sum;
    }

    void write(WriteBuffer & buf) const
    {
        writeBinary(sum, buf);
    }

    void read(ReadBuffer & buf)
    {
        readBinary(sum, buf);
    }

    T get() const
    {
        return sum;
    }
};

ClickHouse在Server啟動時。main函數之中會調用registerAggregateFunction的初始化函數註冊所有的聚合函數。
然後調用到下面的函數:

void registerAggregateFunctionSum(AggregateFunctionFactory & factory)
{
    factory.registerFunction("sum", createAggregateFunctionSum<AggregateFunctionSumSimple>, AggregateFunctionFactory::CaseInsensitive);
    factory.registerFunction("sumWithOverflow", createAggregateFunctionSum<AggregateFunctionSumWithOverflow>);
    factory.registerFunction("sumKahan", createAggregateFunctionSum<AggregateFunctionSumKahan>);
}

這裏又調用了 factory.registerFunction("sum", createAggregateFunctionSum<AggregateFunctionSumSimple>, AggregateFunctionFactory::CaseInsensitive);來進行上述我們看到的聚合函數的註冊。這裡有一點很噁心的模板代碼,筆者這裏簡化了一下,把註冊的部分函數拉出來:

createAggregateFunctionSum(const std::string & name, const DataTypes & argument_types, const Array & parameters)
{
    AggregateFunctionPtr res;
    DataTypePtr data_type = argument_types[0];
    if (isDecimal(data_type))
        res.reset(createWithDecimalType<Function>(*data_type, *data_type, argument_types));
    else
        res.reset(createWithNumericType<Function>(*data_type, argument_types));
    return res;

這裏的Function模板就是上面的AggregateFunctionSumSimple, 而它又是下面的模板類型:

template <typename T> using AggregateFunctionSumSimple = typename SumSimple<T>::Function;

template <typename T>
struct SumSimple
{
    /// @note It uses slow Decimal128 (cause we need such a variant). sumWithOverflow is faster for Decimal32/64
    using ResultType = std::conditional_t<IsDecimalNumber<T>, Decimal128, NearestFieldType<T>>;
    using AggregateDataType = AggregateFunctionSumData<ResultType>;
    using Function = AggregateFunctionSum<T, ResultType, AggregateDataType>;
};

不知道讀者被繞暈了沒,最終繞回來還是new出來這個AggregateFunctionSum<T, ResultType, AggregateDataType>
也就是完成了這個求和算子的註冊,後續我們get出來就可以愉快的調用啦。(這裏這部分的模板變化比較複雜,如果看不明白可以回到源碼梳理一下~~~)

3. 小結

好了,關於聚合函數的基礎信息,和它是如何實現並且通過工廠方法註冊獲取的流程算是搞明白了。
關於其他的聚合算子,也是大同小異的方式。筆者就不再贅述了,感興趣的可以回到源碼之中繼續一探究竟。講完了聚合函數的實現,下一篇筆者就要繼續給探究聚合函數究竟在ClickHouse之中是如何和列存結合使用,並實現向量化的~~。
筆者是一個ClickHouse的初學者,對ClickHouse有興趣的同學,也歡迎和筆者多多指教,交流。

4. 參考資料

官方文檔
ClickHouse源代碼

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

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

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

如何在Spring Boot應用啟動之後立刻執行一段邏輯_網頁設計公司

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

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

1. 前言

不知道你有沒有接到這種需求,項目啟動后立馬執行一些邏輯。比如簡單的緩存預熱,或者上線后的廣播之類等等。如果你使用 Spring Boot 框架的話就可以藉助其提供的接口CommandLineRunnerApplicationRunner來實現。

2. CommandLineRunner

org.springframework.boot.CommandLineRunnerSpring Boot提供的一個接口,當你實現該接口並將之注入Spring IoC容器后,Spring Boot應用啟動后就會執行其run方法。一個Spring Boot可以存在多個CommandLineRunner的實現,當存在多個時,你可以實現Ordered接口控制這些實現的執行順序(Order 數值越大優先級越低)。接下來我們來聲明兩個實現並指定順序:

優先執行:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * 優先級最高
 * 該類期望在springboot 啟動后第一順位執行
 * @author felord.cn
 * @since 12:57
 **/
@Slf4j
@Component
public class HighOrderCommandLineRunner implements CommandLineRunner, Ordered {
    @Override
    public void run(String... args) throws Exception {
        for (String arg : args) {
            log.info("arg = " + arg);
        }
        log.info("i am highOrderRunner");
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE+1;
    }
}

第二順序執行:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * 優先級低於{@code HighOrderCommandLineRunner}
 * @author felord.cn
 * @since 12:59
 **/
@Slf4j
@Component
public class LowOrderCommandLineRunner implements CommandLineRunner, Ordered {

    @Override
    public void run(String... args) throws Exception {
        log.info("i am lowOrderRunner");
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE+1;
    }
}

然後啟動Spring Boot應用后,控制台按照預定的順序打印出了結果:

2020-05-30 23:11:03.685  INFO 11976 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-05-30 23:11:03.701  INFO 11976 --- [           main] c.f.Application  : Started SpringBootApplication in 4.272 seconds (JVM running for 6.316)
2020-05-30 23:11:03.706  INFO 11976 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-05-30 23:11:03.706  INFO 11976 --- [           main] c.f.LowOrderCommandLineRunner   : i am lowOrderRunner

3. ApplicationRunner

Spring Boot 1.3.0又引入了一個和CommandLineRunner功能一樣的接口ApplicationRunnerCommandLineRunner接收可變參數String... args,而ApplicationRunner 接收一個封裝好的對象參數ApplicationArguments。除此之外它們功能完全一樣,甚至連方法名都一樣。 聲明一個ApplicationRunner並讓它優先級最低:

package cn.felord;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * 優先級最低
 * @author felord.cn
 * @since 13:00
 **/
@Slf4j
@Component
public class DefaultApplicationRunner implements ApplicationRunner, Ordered {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("i am applicationRunner");
        Set<String> optionNames = args.getOptionNames();
        log.info("optionNames = " + optionNames);
        String[] sourceArgs = args.getSourceArgs();
        log.info("sourceArgs = " + Arrays.toString(sourceArgs));
        List<String> nonOptionArgs = args.getNonOptionArgs();
        log.info("nonOptionArgs = " + nonOptionArgs);
        List<String> optionValues = args.getOptionValues("foo");
        log.info("optionValues = " + optionValues);
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE+2;
    }
}

按照順序打印了三個類的執行結果:

2020-06-01 13:02:39.420  INFO 19032 --- [           main] c.f.MybatisResultmapApplication  : Started MybatisResultmapApplication in 1.801 seconds (JVM running for 2.266)
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.LowOrderCommandLineRunner    : i am lowOrderRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : i am applicationRunner
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : optionNames = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : sourceArgs = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : nonOptionArgs = []
2020-06-01 13:02:39.423  INFO 19032 --- [           main] c.f.DefaultApplicationRunner     : optionValues = null

Ordered接口並不能被 @Order註解所代替。

4. 傳遞參數

相信很多同學看到這裏都開始對這兩個run方法的入參感興趣了。Spring Boot應用啟動時是可以接受參數的,換句話說也就是Spring Bootmain方法是可以接受參數的。這些參數通過命令行 java -jar yourapp.jar 來傳遞。CommandLineRunner會原封不動照單全收這些接口,這些參數也可以封裝到ApplicationArguments對象中供ApplicationRunner調用。 我們來認識一下ApplicationArguments的相關方法:

  • getSourceArgs() 被傳遞給應用程序的原始參數,返回這些參數的字符串數組。

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

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

  • getOptionNames() 獲取選項名稱的Set字符串集合。如 --spring.profiles.active=dev --debug 將返回["spring.profiles.active","debug"]

  • getOptionValues(String name) 通過名稱來獲取該名稱對應的選項值。如--foo=bar --foo=baz 將返回["bar","baz"]

  • containsOption(String name) 用來判斷是否包含某個選項的名稱。

  • getNonOptionArgs() 用來獲取所有的無選項參數。

    接下來我們試驗一波,你可以通過下面的命令運行一個 Spring Boot應用 Jar

java -jar yourapp.jar --foo=bar --foo=baz --dev.name=碼農小胖哥 java felordcn

或者在IDEA開發工具中打開Spring Boot應用main方法的配置項,進行如下配置,其他IDE工具同理。

運行Spring Boot應用,將會打印出:

2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --foo=bar
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --foo=baz
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = --dev.name=碼農小胖哥
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = java
2020-06-01 15:04:31.490  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : arg = felordcn
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.HighOrderCommandLineRunner   : i am highOrderRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.LowOrderCommandLineRunner    : i am lowOrderRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : i am applicationRunner
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : optionNames = [dev.name, foo]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : sourceArgs = [--foo=bar, --foo=baz, --dev.name=碼農小胖哥, java, felordcn]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : nonOptionArgs = [java, felordcn]
2020-06-01 15:04:31.491  INFO 13208 --- [           main] c.f.DefaultApplicationRunner     : optionValues = [bar, baz]

然後你就可以根據實際需要動態地執行一些邏輯。

5. 總結

今天我們對CommandLineRunnerApplicationRunner進行了講解,從用法到順序執行,又對Spring Boot傳遞參數進行了介紹和演示,希望對你有所幫助。多多關注:碼農小胖哥,更多編程乾貨分享給你。

關注公眾號:Felordcn 獲取更多資訊

個人博客:https://felord.cn

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

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

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