真正越野賽車和實際買到的SUV有什麼區別?_網頁設計公司

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

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

2、進氣系統一輛標準的帕傑羅過水雖然沒有問題,但是速度要十分慢,快過沙子慢淌水這個道理大家都懂,但是賽車時前方的水坑也要全速沖,所以不改進氣車子過水的時候可能發動機就進水了。3、懸架懸架系統主要承擔緩衝和吸收衝擊的作用,以保護車身機械系統以及車輛電氣系統,如果懸架的強度不夠不能支持車輛飛躍等,這樣就導致每次爬坡到坡頂都必須減速,會浪費掉許多的時間。

對於越野車,不同的人有不同的理解,但是對於大多數人來說,大梁四驅就是越野車,可是如果越野賽車呢?

越野賽車大家都十分陌生,對於小編來說也一樣,不過通過這次參加騰衝站COC越野賽的機會,小編有幸感受到了真正的越野賽車的魅力。

越野賽車和越野車的區別在哪呢?

速度

歸根結底就在於速度兩字,其實對於豐田普拉多/三菱帕傑羅這類的我們熟悉的越野車來說,越野場地的大多數項目都不是問題,但是如果讓一輛原廠狀態的大切諾基來用越野賽車的跑法跑越野賽道的話,可能跑不完一圈車子就趴窩了。

原因就在於越野賽車需要有較高的速度,這樣就需要車子的輪胎/車身/懸架能夠承受更大的衝擊,因此真正的越野賽車對於這些方面都會進行改裝,那麼如果想讓你的車擁有迅速快速地跑完越野賽道的實力,需要改裝哪些地方呢?

1、輪胎

輪胎是和路面接觸的地方,越野賽場的路面可不一般,看似平坦實際上尖石粒到處都是,而越野賽車需要以70km/h左右的高速度碾壓路面,因此輪胎的耐用性十分重要,

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

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

而且在泥地、沙地也需要輪胎提供足夠的抓地力,在車輛飛躍的時候輪胎也需要承擔並緩衝巨大的衝擊力。所以再強的越野車,如果輪胎不行,那麼也是白搭。

2、進氣系統

一輛標準的帕傑羅過水雖然沒有問題,但是速度要十分慢,快過沙子慢淌水這個道理大家都懂,但是賽車時前方的水坑也要全速沖,所以不改進氣車子過水的時候可能發動機就進水了。

3、懸架

懸架系統主要承擔緩衝和吸收衝擊的作用,以保護車身機械系統以及車輛電氣系統,如果懸架的強度不夠不能支持車輛飛躍等,這樣就導致每次爬坡到坡頂都必須減速,會浪費掉許多的時間。

4、前後包圍

為什麼包圍要改呢?一般車輛的接近角和離去角都比較小,對於高強度越野來說肯定是不夠的,所以拆掉前後包圍是最簡單的做法,也是普遍採取的做法。

5、防翻滾架/座位

這個雖然和性能無關,但是卻是保護安全的神器,防翻滾架是每部賽車的標配,即使車輛翻滾散架,防翻滾架都會保持完整。也能夠保護車內的駕乘人員。而安全帶則無需多言了,你以為3點式安全帶夠用?

最後的最後,可能有人就會問了,我不會把車改成這個樣子啊,其實小編想說的是,有的人開車遇到溝坎減速帶什麼的都不減速的,原理其實和賽車一樣,如果你真的需要暴力開,還真的要把車子改成高強度的狀態,量產車隨便虐只會大大減少壽命,甚至會直接弄毀車輛。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

買誰都不吃虧 博越和RX5該如何選?_如何寫文案

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

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

0L兩款發動機,而且主力車型就是1。8T的動力裝配。吉利博越的1。8T發動機賬面參數是184ps馬力,最大扭矩285N。m,對比RX5 1。5T 169ps馬力和250N。m的峰值扭矩還是強了不少。配置博越的配置更加豐富1。8TD自動智慧型的吉利博越和 20T兩驅自動旗艦版的榮威RX5指導價格差價僅僅只是在1000元,而且兩車的配置都算不錯,操控配置更是完全一樣。

當下的汽車增長速度最快的車型無疑是SUV,無論是合資企業還是自主品牌車企對於SUV車型的研發力度也是非常巨大,同樣作為自主品牌,吉利博越和榮威RX5各自代表了目前各自品牌的最高技術,這兩款售價區間重疊明顯,同為國貨精品的SUV如何選擇?

我們拿出這兩台車售價最接近的細分配置車型進行對比;售價也符合當下眾多購車人士的預算訴求,十五萬以內:

吉利博越2016款1.8TD 自動智慧型,售價13.98萬

榮威RX5 2016款 20T 兩驅自動旗艦版,售價13.88萬

外觀

爭議頗大VS迎合主流

吉利博越到底好不好看?不同的人有不同的答案;吉利博越的外觀一直存在着爭議,主要的焦點集中於那採用自沃爾沃概念車的漣漪式前臉格柵。但是從辨識度上說,吉利博越是成功的,漣漪式前臉已經成為了吉利的家族標誌,精緻的設計風格已經為吉利樹立起了一種不錯的品牌形象。

榮威RX5的設計則是一種非常迎合當下審美潮流的風格,前臉進氣格柵線條流暢舒展,配合上矩陣式的燈組設計,層次豐富之下更體現出不少的細節處理。榮威RX5的車身運用了大量的黃金比例理念,將整車的視覺效果做到了很好的均衡,看過實車的人都會說,RX5是一款看上去很“大氣”的SUV。

內飾

各有千秋;博越設計感更豐富

在內飾層面小編個人是比較喜歡博越的內飾設計,運用了更多的柔和曲線設計,官方稱為西湖斷橋的元素,從使用上說,博越的內飾沒有為了體現設計感而喪失人機工程的實用性。功能性按鍵布局顯得清晰明確,操作起來也十分方便。

反觀榮威RX5,

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

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

第一眼看到榮威RX5的內飾我會想到大眾,整體設計以平實簡潔的路線為主,儘管在設計感上或許相比較於博越有一定的欠缺,但是在功能性空間表現性上也一樣有着很優秀的表現。

空間

榮威RX5空間更充裕

儘管兩台車的定位都是緊湊型SUV,但是榮威RX5的車身尺寸要比博越大了半圈,作為一款有着2700軸距的SUV車型,兩車從乘坐空間表現性上說榮威RX5要更勝一籌。

動力

博越的動力更加澎湃

榮威RX5搭載的是兩套動力總成,分別是1.5T和2.0T的渦輪增壓發動機,而吉利博越同樣也是兩套動力總成,但是1.8T以及2.0L兩款發動機,而且主力車型就是1.8T的動力裝配。

吉利博越的1.8T發動機賬面參數是184ps馬力,最大扭矩285N.m,對比RX5 1.5T 169ps馬力和250N.m的峰值扭矩還是強了不少。

配置

博越的配置更加豐富

1.8TD自動智慧型的吉利博越和 20T兩驅自動旗艦版的榮威RX5指導價格差價僅僅只是在1000元,而且兩車的配置都算不錯,操控配置更是完全一樣。

但是總體上來說博越的配置更加豐富,主要的是體現在安全性配置方面,博越搭載的前排側安全氣囊和前後頭部氣囊在名為旗艦版的榮威RX5身上並沒有裝配。

而在燈光配置方面,榮威RX5的配置則顯得有些寒酸了,原廠搭載的是鹵素光源,可以選裝LED,並且沒有霧燈標配,而這一點,價位幾乎相同的博越則有了更完善的裝備。

編輯總結:兩款車對比下來,更建議購買的還是吉利博越,榮威RX5更多的是以2.0T的車型作為主力車型向合資緊湊型SUV進行競爭,而1.5T的動力車型所搭載的配置則明顯的與2.0T車型拉開了差距。

榮威RX5的2.0T車型售價在16.68-18.68萬,從定價來說這個價格並不算低,儘管以互聯網為背景的科技性配置的確是一大亮點,但是更多的消費者更注重的是車內所能給予的實用性配置享受,而兩車相比,13.98萬的吉利博越1.8TD自動智慧型則更具有性價比。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

20萬預算買進口SUV 動力和個性化這三台都可以_網頁設計公司

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

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

一些細節方面,卡繽還是做得比較有意思的。副駕駛位的抽屜箱是橫拉打開,而非傳統的圓弧形打開,這樣駕駛員就可以在打開抽屜時,清楚看到裏面的東西。前排座椅後方用了五條限位繩來固定物品,而非傳統的網兜,這點我就覺得不慎實用。

斯巴魯XV

指導價:18.98—22.98萬

編者點評:

XV可能是這個價位區間中我們比較常見的進口SUV,以這個價格就能享受到水平對置發動機與全時四驅所帶來的快感,確實不賴。然而只有2.0L自然吸氣發動機+CVT變速箱,動力上難言充足,也僅僅是夠用而已。儘管跑得不夠快,但是有全時四驅的加持,操控性那是沒得說。

進入車廂內,XV給人的感覺比較嚴肅,到處都是黑色和銀色的內飾。不過,這也有一個好處,那就是比較耐臟。雖然整個內飾略簡單,但是從那些接線處細細一看還是能發現XV的做工有一種精緻范。

保養方面,按照4S店的建議,6萬公里下來的保養費用為10594元。這個價格就算是比較貴了,不過,想想要維護一台水平對置發動機,這又似乎變得不是那麼難以接受。

雷諾 卡繽

指導價:13.98—18.88萬

編者點評:

卡繽這台車可能很少有人聽說過,不過它可曾是歐洲小型SUV的銷量冠軍。能做冠軍肯定是有不少真材實料的。先從外形說起,卡繽採用了時下流行的雙色車身,而且都是明亮的色彩,車尾還可以選擇一些拉花,整台車看起來就是各種酷炫,相當討年輕人喜歡的風格。

動力總成方面,卡繽搭載的是1.2T渦輪增壓發動機+6速雙離合。1.2T的發動機最大功率為85KW,最大扭矩為190Nm。動力相對pSA那台1.2T發動機來說,是“書生”了一點點,不過卡繽也不是一台性能取向的車。

一些細節方面,卡繽還是做得比較有意思的。副駕駛位的抽屜箱是橫拉打開,而非傳統的圓弧形打開,

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

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

這樣駕駛員就可以在打開抽屜時,清楚看到裏面的東西。前排座椅後方用了五條限位繩來固定物品,而非傳統的網兜,這點我就覺得不慎實用。尾箱隔板有兩面,一面是常規的絨面,可以用來放置一些摩擦力較小的物品,防止滑動;另一面是光面,可以用來放一些比較容易弄髒的物品,這樣也便於清潔。在這點上,法國人還是想得比較細心。

保養方面,6萬公里中的保養費用為5926元。這樣的養護成本在同級別中,算是很便宜了。雷諾還給出了一個殺手鐧,那就是送車主10次免費更換機油和機油濾清器,這樣的待遇恐怕也沒哪個廠家敢給。

鈴木 吉姆尼

指導價:14.18—16.08萬

編者點評:

吉姆尼這台車是很多越野愛好者心中的完美伴侶,車身長度僅為3665mm,這樣短小精悍的車身造型可以很好地通過不少比較窄的路面,在城市中穿越也比較輕鬆,特別是在找停車位的時候,許多地方的停車位規劃並不完善,而且尺寸偏小。這時候,吉姆尼甚至比普通轎車還更容易泊進去。

不過,吉姆尼的安全配置就十分寒酸了,僅僅有ABS防抱死,連ESp都沒有。其他配置方面,也同樣乏善可陳。買回來要好好越野肯定是要先去改裝一下的,起碼給它裝兩把前橋和後橋的差速鎖。

吉姆尼的內飾可以說是樸實無華,一眼望去儘是各種塑料。話雖如此,但是它的塑料還是做得比較用心的。油耗方面,手動版的百公里平均油耗為7.7L,而自動版的則為9.3L。相差還是挺大的。可以看出,儘管吉姆尼的排量較低,但也不是一個省油的主。

除非你是一個越野愛好者,不然這台車在城市中也許只能帶給你較高的回頭率。

這三款車各有各的特點,XV算是進口車中比較常見的,卡繽則充滿陽光,相當有范,而吉姆尼顯然就屬於劍走偏鋒的類型。選擇一台進口車,同時也是選擇了另一種生活。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

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

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

超乾貨!為了讓你徹底弄懂MySQL事務日誌,我通宵肝出了這份圖解!_如何寫文案

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

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

還記得剛上研究生的時候,導師常掛在嘴邊的一句話,“科研的基礎不過就是數據而已。”如今看來,無論是人文社科,還是自然科學,或許都可在一定程度上看作是數據的科學。

倘若剝開研究領域的外衣,將人的操作抽象出來,那麼科研的過程大概就是根據數據流動探索其中的未知信息吧。當然科學研究的範疇涵蓋甚廣,也不是一兩句話能夠拎得清的。不過從這個角度上的闡述,也只是為了引出數據的重要性。

在當今社會,充斥着大量的數據。從眾多APP上的賬戶資料到銀行信用體系等個人檔案,都離不開對大量數據的組織、存儲和管理。而這,便是數據庫存在的目的和價值。

目前數據庫的類型主要分為兩種,一種是關係型數據庫,另一種是非關係型數據庫(NoSQL)。而我們今天的主角MySQL就是關係型數據庫中的一種。

1 關係型數據庫與NoSQL

關係型數據庫,顧名思義,是指存儲的數據之間具有關係。這種所謂的關係通常用二維表格中的行列來表示,即一個二維表的邏輯結構能夠反映表中數據的存儲關係。

概念總是拗口難懂的。那麼簡單來說,關係型數據庫的存儲就是按照表格進行的。數據的存儲實際上就是對一個或者多個表格的存儲。通過對這些表格進行分類、合併、連接或者選取等運算來實現對數據庫的管理。常見的關係型數據庫有MySQL、Oracle、DB2和SqlServer等。

非關係型數據庫(NoSQL)是相對於關係型數據庫的一種泛指,它的特點是去掉了關係型數據庫中的關係特性,從而可獲得更好的擴展性。NoSQL並沒有嚴格的存儲方式,但採用不同的存儲結構都是為了獲得更高的性能和更高的併發。NoSQL根據存儲方式可分為四大類,鍵值存儲數據庫、列存儲數據庫、文檔型數據庫和圖形數據庫。這四種數據的存儲原理不盡相同,因而在應用場景上也有些許的差異。一般常用的有作為數據緩存的redis和分佈式系統的HBase。目前常見的數據庫排名可見網站:

https://db-engines.com/en/ranking

關係型數據庫與非關係型數據庫本質上的區別就在於存儲的數據是否具有一定的邏輯關係,由此產生的兩類數據庫看的性能和優劣勢上也有一定的區別。二者對比可見下圖。

2 MySQL簡介

介紹

在關係型數據庫中,MySQL可以說是其中的王者。它是目前最流行的數據庫之一,由瑞典 MySQL AB 公司開發,目前屬於 Oracle 公司。MySQL數據庫具有以下幾個方面的優勢:

  • 體積小、速度快;
  • 代碼開源,採用了 GPL 協議,可以修改源碼來開發自己的 MySQL 系統;
  • 支持大型的數據庫,可以處理擁有上千萬條記錄的大型數據庫;
  • 使用標準的 SQL 數據語言形式,並採用優化的 SQL 查詢算法,有效地提高查詢速度;
  • 使用 C 和 C++ 編寫,並使用多種編譯器進行測試,保證源代碼的可移植性;
  • 可運行在多個系統上,並且支持多種語言;
  • 核心程序採用完全的多線程編程,可以靈活地為用戶提供服務,充分利用CPU資源。

邏輯架構

MySQL的邏輯架構可分為四層,包括連接層、服務層、引擎層和存儲層,各層的接口交互及作用如下圖所示。需要注意的是,由於本文將主要講解事務的實現原理,因此下文針對的都是InnoDB引擎下的情況。

連接層:負責處理客戶端的連接以及權限的認證。

服務層:定義有許多不同的模塊,包括權限判斷,SQL接口,SQL解析,SQL分析優化, 緩存查詢的處理以及部分內置函數執行等。MySQL的查詢語句在服務層內進行解析、優化、緩存以及內置函數的實現和存儲。

引擎層:負責MySQL中數據的存儲和提取。MySQL中的服務器層不管理事務,事務是由存儲引擎實現的。其中使用最為廣泛的存儲引擎為InnoDB,其它的引擎都不支持事務。

存儲層:負責將數據存儲與設備的文件系統中。

3 MySQL事務

事務是MySQL區別於NoSQL的重要特徵,是保證關係型數據庫數據一致性的關鍵技術。事務可看作是對數據庫操作的基本執行單元,可能包含一個或者多個SQL語句。這些語句在執行時,要麼都執行,要麼都不執行。

事務的執行主要包括兩個操作,提交和回滾。

提交:commit,將事務執行結果寫入數據庫。

回滾:rollback,回滾所有已經執行的語句,返回修改之前的數據。

MySQL事務包含四個特性,號稱ACID四大天王。

原子性(Atomicity) :語句要麼全執行,要麼全不執行,是事務最核心的特性,事務本身就是以原子性來定義的;實現主要基於undo log日誌實現的。

持久性(Durability :保證事務提交后不會因為宕機等原因導致數據丟失;實現主要基於redo log日誌。

隔離性(Isolation) :保證事務執行盡可能不受其他事務影響;InnoDB默認的隔離級別是RR,RR的實現主要基於鎖機制、數據的隱藏列、undo log和類next-key lock機制。

一致性(Consistency) :事務追求的最終目標,一致性的實現既需要數據庫層面的保障,也需要應用層面的保障。

原子性

事務的原子性就如原子操作一般,表示事務不可再分,其中的操作要麼都做,要麼都不做;如果事務中一個SQL語句執行失敗,則已執行的語句也必須回滾,數據庫退回到事務前的狀態。只有0和1,沒有其它值。

事務的原子性表明事務就是一個整體,當事務無法成功執行的時候,需要將事務中已經執行過的語句全部回滾,使得數據庫回歸到最初未開始事務的狀態。

事務的原子性就是通過undo log日誌進行實現的。當事務需要進行回滾時,InnoDB引擎就會調用undo log日誌進行SQL語句的撤銷,實現數據的回滾。

持久性

事務的持久性是指當事務提交之後,數據庫的改變就應該是永久性的,而不是暫時的。這也就是說,當事務提交之後,任何其它操作甚至是系統的宕機故障都不會對原來事務的執行結果產生影響。

事務的持久性是通過InnoDB存儲引擎中的redo log日誌來實現的,具體實現思路見下文。

隔離性

原子性和持久性是單個事務本身層面的性質,而隔離性是指事務之間應該保持的關係。隔離性要求不同事務之間的影響是互不干擾的,一個事務的操作與其它事務是相互隔離的。

由於事務可能並不只包含一條SQL語句,所以在事務的執行期間很有可能會有其它事務開始執行。因此多事務的併發性就要求事務之間的操作是相互隔離的。這一點跟多線程之間數據同步的概念有些類似。

鎖機制

事務之間的隔離,是通過鎖機制實現的。當一個事務需要對數據庫中的某行數據進行修改時,需要先給數據加鎖;加了鎖的數據,其它事務是不運行操作的,只能等待當前事務提交或回滾將鎖釋放。

鎖機制並不是一個陌生的概念,在許多場景中都會利用到不同實現的鎖對數據進行保護和同步。而在MySQL中,根據不同的劃分標準,還可將鎖分為不同的種類。

按照粒度劃分:行鎖、表鎖、頁鎖

按照使用方式劃分:共享鎖、排它鎖

按照思想劃分:悲觀鎖、樂觀鎖

鎖機制的知識點很多,由於篇幅不好全部展開講。這裏對按照粒度劃分的鎖進行簡單介紹。

粒度:指數據倉庫的數據單位中保存數據的細化或綜合程度的級別。細化程度越高,粒度級就越小;相反,細化程度越低,粒度級就越大。

MySQL按照鎖的粒度劃分可以分為行鎖、表鎖和頁鎖。

行鎖:粒度最小的鎖,表示只針對當前操作的行進行加鎖;

表鎖:粒度最大的鎖,表示當前的操作對整張表加鎖;

頁鎖:粒度介於行級鎖和表級鎖中間的一種鎖,表示對頁進行加鎖。

這三種鎖是在不同層次上對數據進行鎖定,由於粒度的不同,其帶來的好處和劣勢也不一而同。

表鎖在操作數據時會鎖定整張表,因而併發性能較差;

行鎖則只鎖定需要操作的數據,併發性能好。但是由於加鎖本身需要消耗資源(獲得鎖、檢查鎖、釋放鎖等都需要消耗資源),因此在鎖定數據較多情況下使用表鎖可以節省大量資源。

MySQL中不同的存儲引擎能夠支持的鎖也是不一樣的。MyIsam只支持表鎖,而InnoDB同時支持表鎖和行鎖,且出於性能考慮,絕大多數情況下使用的都是行鎖。

併發讀寫問題

在併發情況下,MySQL的同時讀寫可能會導致三類問題,臟讀、不可重複度和幻讀。

(1)臟讀:當前事務中讀到其他事務未提交的數據,也就是臟數據。

以上圖為例,事務A在讀取文章的閱讀量時,讀取到了事務B為提交的數據。如果事務B最後沒有順利提交,導致事務回滾,那麼實際上閱讀量並沒有修改成功,而事務A卻是讀到的修改后的值,顯然不合情理。

(2)不可重複讀:在事務A中先後兩次讀取同一個數據,但是兩次讀取的結果不一樣。臟讀與不可重複讀的區別在於:前者讀到的是其他事務未提交的數據,後者讀到的是其他事務已提交的數據。

以上圖為例,事務A在先後讀取文章閱讀量的數據時,結果卻不一樣。說明事務A在執行的過程中,閱讀量的值被其它事務給修改了。這樣使得數據的查詢結果不再可靠,同樣也不合實際。

(3)幻讀:在事務A中按照某個條件先後兩次查詢數據庫,兩次查詢結果的行數不同,這種現象稱為幻讀。不可重複讀與幻讀的區別可以通俗的理解為:前者是數據變了,後者是數據的行數變了。

以上圖為例,當對0<閱讀量<100的文章進行查詢時,先查到了一個結果,後來查詢到了兩個結果。這表明同一個事務的查詢結果數不一,行數不一致。這樣的問題使得在根據某些條件對數據篩選的時候,前後篩選結果不具有可靠性。

隔離級別

根據上面這三種問題,產生了四種隔離級別,表明數據庫不同程度的隔離性質。

在實際的數據庫設計中,隔離級別越高,導致數據庫的併發效率會越低;而隔離級別太低,又會導致數據庫在讀寫過程中會遇到各種亂七八糟的問題。

因此在大多數數據庫系統中,默認的隔離級別時讀已提交(如Oracle)或者可重複讀RR(MySQL的InnoDB引擎)。

MVCC

又是一個難嚼的大塊頭。MVCC就是用來實現上面的第三個隔離級別,可重複讀RR。

MVCC:Multi-Version Concurrency Control,即多版本的併發控制協議。

MVCC的特點就是在同一時刻,不同事務可以讀取到不同版本的數據,從而可以解決臟讀和不可重複讀的問題。

MVCC實際上就是通過數據的隱藏列和回滾日誌(undo log),實現多個版本數據的共存。這樣的好處是,使用MVCC進行讀數據的時候,不用加鎖,從而避免了同時讀寫的衝突。

在實現MVCC時,每一行的數據中會額外保存幾個隱藏的列,比如當前行創建時的版本號和刪除時間和指向undo log的回滾指針。這裏的版本號並不是實際的時間值,而是系統版本號。每開始新的事務,系統版本號都會自動遞增。事務開始時的系統版本號會作為事務的版本號,用來和查詢每行記錄的版本號進行比較。

每個事務又有自己的版本號,這樣事務內執行數據操作時,就通過版本號的比較來達到數據版本控制的目的。

另外,InnoDB實現的隔離級別RR時可以避免幻讀現象的,這是通過next-key lock機制實現的。這裏簡單講講吧。

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

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

next-key lock實際上就是行鎖的一種,只不過它不只是會鎖住當前行記錄的本身,還會鎖定一個範圍。比如上面幻讀的例子,開始查詢0<閱讀量<100的文章時,只查到了一個結果。next-key lock會將查詢出的這一行進行鎖定,同時還會對0<閱讀量<100這個範圍進行加鎖,這實際上是一種間隙鎖。間隙鎖能夠防止其他事務在這個間隙修改或者插入記錄。這樣一來,就保證了在0<閱讀量<100這個間隙中,只存在原來的一行數據,從而避免了幻讀。

間隙鎖:封鎖索引記錄中的間隔

雖然InnoDB使用next-key lock能夠避免幻讀問題,但卻並不是真正的可串行化隔離。再來看一個例子吧。

首先提一個問題,在T6事務A提交事務之後,猜一猜文章A和文章B的閱讀量為多少?

答案是,文章AB的閱讀量都被修改成了10000。這代表着事務B的提交實際上對事務A的執行產生了影響,表明兩個事務之間並不是完全隔離的。雖然能夠避免幻讀現象,但是卻沒有達到可串行化的級別。

這還說明,避免臟讀、不可重複讀和幻讀,是達到可串行化的隔離級別的必要不充分條件。可串行化是都能夠避免臟讀、不可重複讀和幻讀,但是避免臟讀、不可重複讀和幻讀卻不一定達到了可串行化。

一致性

一致性是指事務執行結束后,數據庫的完整性約束沒有被破壞,事務執行的前後都是合法的數據狀態。

一致性是事務追求的最終目標:前面提到的原子性、持久性和隔離性,都是為了保證數據庫狀態的一致性。

這就不多說了吧。你細品。

4 MySQL日誌系統

了解完MySQL的基本架構,大體上能夠對MySQL的執行流程有了比較清晰的認知。接下來我將在講述MySQL事務之前,先為大家介紹以下日誌系統,以方便之後更好的理解事務的特性和實現。

MySQL日誌系統是數據庫的重要組件,用於記錄數據庫的更新和修改。若數據庫發生故障,可通過不同日誌記錄恢複數據庫的原來數據。因此實際上日誌系統直接決定着MySQL運行的魯棒性和穩健性。

MySQL的日誌有很多種,如二進制日誌(binlog)、錯誤日誌、查詢日誌、慢查詢日誌等,此外InnoDB存儲引擎還提供了兩種日誌:redo log(重做日誌)和undo log(回滾日誌)。這裏將重點針對InnoDB引擎,對重做日誌、回滾日誌和二進制日誌這三種進行分析。

重做日誌(redo log)

重做日誌(redo log)是InnoDB引擎層的日誌,用來記錄事務操作引起數據的變化,記錄的是數據頁的物理修改。

重做日記的作用其實很好理解,我打個比方。數據庫中數據的修改就好比你寫的論文,萬一哪天論文丟了怎麼呢?以防這種不幸的發生,我們可以在寫論文的時候,每一次修改都拿個小本本記錄一下,記錄什麼時間對某一頁進行了怎麼樣的修改。這就是重做日誌。

InnoDB引擎對數據的更新,是先將更新記錄寫入redo log日誌,然後會在系統空閑的時候或者是按照設定的更新策略再將日誌中的內容更新到磁盤之中。這就是所謂的預寫式技術(Write Ahead logging)。這種技術可以大大減少IO操作的頻率,提升數據刷新的效率。

臟數據刷盤

值得注意的是,redo log日誌的大小是固定的,為了能夠持續不斷的對更新記錄進行寫入,在redo log日誌中設置了兩個標誌位置,checkpoint和write_pos,分別表示記錄擦除的位置和記錄寫入的位置。redo log日誌的數據寫入示意圖可見下圖。

當write_pos標誌到了日誌結尾時,會從結尾跳至日誌頭部進行重新循環寫入。所以redo log的邏輯結構並不是線性的,而是可看作一個圓周運動。write_pos與checkpoint中間的空間可用於寫入新數據,寫入和擦除都是往後推移,循環往複的。

當write_pos追上checkpoint時,表示redo log日誌已經寫滿。這時不能繼續執行新的數據庫更新語句,需要停下來先刪除一些記錄,執行checkpoint規則騰出可寫空間。

checkpoint規則:checkpoint觸發后,將buffer中臟數據頁和臟日誌頁都刷到磁盤。

臟數據:指內存中未刷到磁盤的數據。

redo log中最重要的概念就是緩衝池buffer pool,這是在內存中分配的一個區域,包含了磁盤中部分數據頁的映射,作為訪問數據庫的緩衝。

當請求讀取數據時,會先判斷是否在緩衝池命中,如果未命中才會在磁盤上進行檢索後放入緩衝池;

當請求寫入數據時,會先寫入緩衝池,緩衝池中修改的數據會定期刷新到磁盤中。這一過程也被稱之為刷臟 。

因此,當數據修改時,除了修改buffer pool中的數據,還會在redo log中記錄這次操作;當事務提交時,會根據redo log的記錄對數據進行刷盤。如果MySQL宕機,重啟時可以讀取redo log中的數據,對數據庫進行恢復,從而保證了事務的持久性,使得數據庫獲得crash-safe能力。

臟日誌刷盤

除了上面提到的對於臟數據的刷盤,實際上redo log日誌在記錄時,為了保證日誌文件的持久化,也需要經歷將日誌記錄從內存寫入到磁盤的過程。redo log日誌可分為兩個部分,一是存在易失性內存中的緩存日誌redo log buff,二是保存在磁盤上的redo log日誌文件redo log file。

為了確保每次記錄都能夠寫入到磁盤中的日誌中,每次將redo log buffer中的日誌寫入redo log file的過程中都會調用一次操作系統的fsync操作。

fsync函數:包含在UNIX系統頭文件#include <unistd.h>中,用於同步內存中所有已修改的文件數據到儲存設備。

在寫入的過程中,還需要經過操作系統內核空間的os buffer。redo log日誌的寫入過程可見下圖。

二進制日誌(binlog)

二進制日誌binlog是服務層的日誌,還被稱為歸檔日誌。binlog主要記錄數據庫的變化情況,內容包括數據庫所有的更新操作。所有涉及數據變動的操作,都要記錄進二進制日誌中。因此有了binlog可以很方便的對數據進行複製和備份,因而也常用作主從庫的同步。

這裏binlog所存儲的內容看起來似乎與redo log很相似,但是其實不然。redo log是一種物理日誌,記錄的是實際上對某個數據進行了怎麼樣的修改;而binlog是邏輯日誌,記錄的是SQL語句的原始邏輯,比如”給ID=2這一行的a字段加1 “。binlog日誌中的內容是二進制的,根據日記格式參數的不同,可能基於SQL語句、基於數據本身或者二者的混合。一般常用記錄的都是SQL語句。

這裏的物理和邏輯的概念,我的個人理解是:

物理的日誌可看作是實際數據庫中數據頁上的變化信息,只看重結果,而不在乎是通過“何種途徑”導致了這種結果;

邏輯的日誌可看作是通過了某一種方法或者操作手段導致數據發生了變化,存儲的是邏輯性的操作。

同時,redo log是基於crash recovery,保證MySQL宕機后的數據恢復;而binlog是基於point-in-time recovery,保證服務器可以基於時間點對數據進行恢復,或者對數據進行備份。

事實上最開始MySQL是沒有redo log日誌的。因為起先MySQL是沒有InnoDB引擎的,自帶的引擎是MyISAM。binlog是服務層的日誌,因此所有引擎都能夠使用。但是光靠binlog日誌只能提供歸檔的作用,無法提供crash-safe能力,所以InnoDB引擎就採用了學自於Oracle的技術,也就是redo log,這才擁有了crash-safe能力。這裏對redo log日誌和binlog日誌的特點分別進行了對比:

在MySQL執行更新語句時,都會涉及到redo log日誌和binlog日誌的讀寫。一條更新語句的執行過程如下:

從上圖可以看出,MySQL在執行更新語句的時候,在服務層進行語句的解析和執行,在引擎層進行數據的提取和存儲;同時在服務層對binlog進行寫入,在InnoDB內進行redo log的寫入。

不僅如此,在對redo log寫入時有兩個階段的提交,一是binlog寫入之前prepare狀態的寫入,二是binlog寫入之後commit狀態的寫入。

之所以要安排這麼一個兩階段提交,自然是有它的道理的。現在我們可以假設不採用兩階段提交的方式,而是採用“單階段”進行提交,即要麼先寫入redo log,后寫入binlog;要麼先寫入binlog,后寫入redo log。這兩種方式的提交都會導致原先數據庫的狀態和被恢復后的數據庫的狀態不一致。

先寫入redo log,后寫入binlog:

在寫完redo log之後,數據此時具有crash-safe能力,因此系統崩潰,數據會恢復成事務開始之前的狀態。但是,若在redo log寫完時候,binlog寫入之前,系統發生了宕機。此時binlog沒有對上面的更新語句進行保存,導致當使用binlog進行數據庫的備份或者恢復時,就少了上述的更新語句。從而使得id=2這一行的數據沒有被更新。

先寫入binlog,后寫入redo log:

寫完binlog之後,所有的語句都被保存,所以通過binlog複製或恢復出來的數據庫中id=2這一行的數據會被更新為a=1。但是如果在redo log寫入之前,系統崩潰,那麼redo log中記錄的這個事務會無效,導致實際數據庫中id=2這一行的數據並沒有更新。

由此可見,兩階段的提交就是為了避免上述的問題,使得binlog和redo log中保存的信息是一致的。

回滾日誌(undo log)

回滾日誌同樣也是InnoDB引擎提供的日誌,顧名思義,回滾日誌的作用就是對數據進行回滾。當事務對數據庫進行修改,InnoDB引擎不僅會記錄redo log,還會生成對應的undo log日誌;如果事務執行失敗或調用了rollback,導致事務需要回滾,就可以利用undo log中的信息將數據回滾到修改之前的樣子。

但是undo log不redo log不一樣,它屬於邏輯日誌。它對SQL語句執行相關的信息進行記錄。當發生回滾時,InnoDB引擎會根據undo log日誌中的記錄做與之前相反的工作。比如對於每個數據插入操作(insert),回滾時會執行數據刪除操作(delete);對於每個數據刪除操作(delete),回滾時會執行數據插入操作(insert);對於每個數據更新操作(update),回滾時會執行一個相反的數據更新操作(update),把數據改回去。undo log由兩個作用,一是提供回滾,二是實現MVCC。

5 主從複製

主從複製的概念很簡單,就是從原來的數據庫複製一個完全一樣的數據庫,原來的數據庫稱作主數據庫,複製的數據庫稱為從數據庫。從數據庫會與主數據庫進行數據同步,保持二者的數據一致性。

主從複製的原理實際上就是通過bin log日誌實現的。bin log日誌中保存了數據庫中所有SQL語句,通過對bin log日誌中SQL的複製,然後再進行語句的執行即可實現從數據庫與主數據庫的同步。

主從複製的過程可見下圖。主從複製的過程主要是靠三個線程進行的,一個運行在主服務器中的發送線程,用於發送binlog日誌到從服務器。兩外兩個運行在從服務器上的I/O線程和SQL線程。I/O線程用於讀取主服務器發送過來的binlog日誌內容,並拷貝到本地的中繼日誌中。SQL線程用於讀取中繼日誌中關於數據更新的SQL語句並執行,從而實現主從庫的數據一致。

之所以需要實現主從複製,實際上是由實際應用場景所決定的。主從複製能夠帶來的好處有:

1 通過複製實現數據的異地備份,當主數據庫故障時,可切換從數據庫,避免數據丟失。

2 可實現架構的擴展,當業務量越來越大,I/O訪問頻率過高時,採用多庫的存儲,可以降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。

3 可實現讀寫分離,使數據庫能支持更大的併發。

4 實現服務器的負載均衡,通過在主服務器和從服務器之間切分處理客戶查詢的負荷。

6 總結

MySQL數據庫應該算是程序員必須掌握的技術之一了。無論是項目過程中還是面試中,MySQL都是非常重要的基礎知識。不過,對於MySQL來說,真的東西太多了。我在寫這篇文章的時候,查閱了大量的資料,發現越看不懂的越多。還真是應了那句話:

你知道的越多,不知道的也就越多。

這篇文章着重是從理論的角度去解析MySQL基本的事務和日誌系統的基本原理,我在表述的時候盡可能的避免採用實際的代碼去描述。即便是這篇將近一萬字+近二十副純手工繪製的圖解,也難以將MySQL的博大精深分析透徹。

但是我相信,對於初學者而言,這些理論能夠讓你對MySQL有一個整體的感知,讓你對“何謂關係型數據庫”這麼一個問題有了比較清晰的認知;而對於熟練掌握MySQL的大佬來說,或許本文也能夠喚醒你塵封已久的底層理論基礎,對你之後的面試也會有一定幫助。

技術這種東西沒有絕對的對錯,倘若文中有誤還請諒解,並歡迎與我討論。自主思考永遠比被動接受更有效。

7 reference

https://www.cnblogs.com/kismetv/p/10331633.html

https://www.cnblogs.com/ivy-zheng/p/11094528.html

https://blog.csdn.net/qq_39016934/article/details/90116706

https://www.jianshu.com/p/5af73b203f2a

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_2

微信搜索業餘碼農,閱讀更多技術隨筆。

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

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

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

帶你學夠浪:Go語言基礎系列-環境配置和 Hello world_網頁設計公司

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

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

文章每周持續更新,原創不易,「三連」讓更多人看到是對我最大的肯定。可以微信搜索公眾號「 後端技術學堂 」第一時間閱讀(一般比博客早更新一到兩篇)

前面幾周陸陸續續寫了一些後端技術的文章,包括數據庫、微服務、內存管理等等,我比較傾向於成體系的學習,所以數據庫和微服務還有後續系列文章補充。

最近工作上比較多的 Golang 編程,現在很多互聯網公司都在轉向 Golang 開發,所以打算寫一寫有關 Go 語言學習的系列文章,目標是從 Go 基礎到進階輸出一系列文章,沉澱下這些知識同時也給大家做參考,力求做到通俗易懂,即使你是 Golang 小白也能看懂,如果你是老手也能溫故知新。

本文將要和你分享 linux 下安裝 Golang 環境,並且講解如何通過配置 VSCode 遠程開發調試 Golang 程序。

下載源碼

你可以用系統自帶的包管理工具比如 yum 或 apt-get 來安裝Golang開發環境。不過,為了通用性,我選擇通過源碼的方式來安裝和講解,在官網下載源碼,下載地址 https://golang.org/dl/

手動安裝

解壓安裝

我這裏下載下來的源碼包 go1.14.2.linux-amd64.tar.gz 放到遠程 Linux 服務器目錄下。執行以下命令安裝到 /usr/local 目錄。

tar -zxvf -C /usr/local/ `go1.14.2.linux-amd64.tar.gz`

創建工作空間

工作空間是你Go項目的「工作目錄」,挑選一個合適目錄,執行下面操作:

mkdir GoPath
mkdir -p GoPath/src
mkdir -p GoPath/bin
mkdir -p GoPath/pkg

三個目錄含義:

  src: 源碼路徑(例如:.go、.c、.h、.s 等)
  pkg: 編譯包時,生成的.a文件存放路徑
  bin: 編譯生成的可執行文件路徑

配置環境變量

安裝過程中有這麼幾個環境變量需要配置,先來了解一下:

GOROOT:Go的安裝路徑,也就是前面我們解壓到的目錄 /usr/local/go。

GOBIN:Go項目的二進制文件存放目錄。

GOPATH:Go的工作空間。前面有介紹的工作空間目錄。

在 /etc/profile 文件追加以下內容完成設置。

export GOROOT=/usr/local/go
export GOPATH=/yourpath/GoPath # 設置你自己的GoPath路徑 
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOROOT/bin  # 加入到PATH環境變量
export PATH=$PATH:$GOPATH/bin
# source /etc/profile #立即生效

驗證安裝

# go version  #檢查版本
# go version go1.14.2 linux/amd64 # 輸出版本號

如果看到版本信息就代表安裝成功了!

遠程開發

上面我們在 Linux 環境下安裝好了 Golang 開發環境,但我不想每次打開終端登錄服務器編寫調試程序,怎麼才能在本地PC開發調試Golang程序呢?

看過我上一篇Vscode遠程開發的小夥伴應該能想到方法,我們就要用Vscode搭建Golang遠程開發環境。具體的遠程開發配置可以查看我的另一篇文章。

Golang開發插件

首先安裝官方推薦的 Go 開發插件,如下,點他安裝。

接着還會出現如下的提示,是因為缺少其他 Go 開發相關插件,點 install all 全都裝上就行。

Hello World

編程界有個慣例,什麼語言開始學習都是從 Hello World 開始。現在,我們就用 Golang 編寫第一個 HelloWorld 程序吧。

上代碼:

package main // 所有Go程序從main包開始運行

import "fmt" // 導入fmt包

func main() {
	fmt.Print("hello world", " i am ready to go :)\n")
	fmt.Println("hello world", "i am ready to go :)")
}

格式化 包

fmt 實現了類似 C++/C 語言的格式IO庫功能。

Print 和 Println 都可用於打印輸出,但是功能略有不同。可以看到我在Print 函數中,對后一個字符串加了空格和換行符,這樣兩個打印出來的結果是相同的。

Print

func Print(a ...interface{}) (n int, err error)

Print採用默認格式將其參數格式化並寫入標準輸出。如果兩個相鄰的參數都不是字符串,會在它們的輸出之間添加空格。返回寫入的字節數和遇到的任何錯誤。

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

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

Println

func Println(a ...interface{}) (n int, err error)

Println採用默認格式將其參數格式化並寫入標準輸出。總是會在相鄰參數的輸出之間添加空格並在輸出結束后添加換行符。返回寫入的字節數和遇到的任何錯誤。

調試

終端調試

在終端命令行源碼所在目錄輸入go run 運行程序。


# go run HelloWorld.go 
//輸出
hello world i am ready to go :)
hello world i am ready to go :)

也可以先編譯go build 得到可執行文件后再運行。

# go build HelloWorld.go 
# ls
HelloWorld  HelloWorld.go
# ./HelloWorld 
hello world i am ready to go :)
hello world i am ready to go :)

Vscode調試

按F5啟動調試,編輯與調試控制台輸出如下:

命令行參數獲取

命令行參數可以通過os 包的 Args 函數獲取,代碼如下:

package main

import (
	"fmt"
	"os"
	"strconv"
)

func main() {
	// 命令行參數獲取,os.Args第一個參數是程序自身
	fmt.Println(os.Args)
	for idx, args := range os.Args {
		fmt.Println("參數"+strconv.Itoa(idx)+":", args)
	}
}

終端設置

以下是帶參數argv1 argv2 運行golang程序和輸出。

# go run basic.go argv1 argv2 

# 輸出
[/tmp/go-build441686724/b001/exe/basic argv1 argv2]
參數0: /tmp/go-build441686724/b001/exe/basic
參數1: argv1
參數2: argv2

VSCode設置

launch.json文件的 args 屬性配置可以設置程序啟動調試的參數。

設置之後,按F5 啟動調試,就會在調試控制台輸出配置的參數。

環境變量獲取

命令行參數可以通過os 包的 Getenv 函數獲取,代碼如下:

package main

import (
	"fmt"
	"os"
)

func main() {
	// 獲取環境變量
	fmt.Println(os.Getenv("type"), os.Getenv("name"), os.Getenv("GOROOT"))
}

VSCode設置環境變量

launch.json 文件的 args 屬性配置可以設置 VSCode 調試的 Golang 程序環境變量。

設置的格式是:name:vaule 形式,注意都是字符串。

終端設置環境變量

終端的環境變量設置就是可以用 Linux 的 export 命令設置,之後就可以用 os.Getenv 函數讀取。

比如我們最初設置 GOROOT 環境變量的命令

export GOROOT=/usr/local/go

就可以用 os.Getenv("GOROOT") 讀取,比較簡單,這裏就不多說了。

總結

現在,你有了一個可以遠程開發調試 Golang 的環境,趕緊去寫個 hello world 體驗一下吧!今天的分享就到這,下一篇文章講解基礎語法。

老規矩,感謝各位的閱讀,文章的目的是分享對知識的理解,技術類文章我都會反覆求證以求最大程度保證準確性,若文中出現明顯紕漏也歡迎指出,我們一起在探討中學習。今天的技術分享就到這裏,我們下期再見。

Reference

設置GOPATH

Visual Studio Code變量參考

Golang 獲取系統環境變量

os庫獲取命令行參數

原創不易,不想被白票,如果在我這有收穫,就動動手指「點贊」和「轉發」是對我持續創作的最大支持。

可以微信搜索公眾號「 後端技術學堂 」回復「資料」「1024」有我給你準備的各種編程學習資料。文章每周持續更新,我們下期見!

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

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

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

學習源碼的第八個月,我成了Spring的開源貢獻者_網頁設計

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

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

我的經歷

關注我的朋友都知道,關注兩個字划重點,要考!

我最近一直在寫Spring的文章,而且僅僅是Spring FrameWork的文章 ,從最開始的官網入門到現在源碼的深度分析。主要就是三個系列

官網入門系列,Spring官網讀書筆記,這一系列的文章是入門Spring的不二之選,也是後續源碼閱讀的基礎

雜談系列,Spring雜談,這主要是一些補充內容,可以幫助大家更全面學習到Spring中的各個知識點,同時也會分享一些源碼閱讀技巧,個人學習心得之類的,雜談嘛,就是不知道放哪裡的文章都打算放這裏,比如這篇文章。

源碼分析系列,Spring源碼解析,該專欄目前正在創作中,相對而言學習難度比較大,而且因為筆者寫的比較細,估計大部分同學看起來會很費勁,不過如果你能認真看完,收穫絕對巨大!當然有不懂得地方也可以給筆者留言,或者關注文章末尾的公眾號。

本文的主要目的是教(zhuang)學(bi)

就是從筆者的實際經驗出發,談一談怎麼成為一個開源項目的貢獻者。

我先說說我自己的經歷吧,在創作上篇文章的時候,筆者發現Spring在實例化對象的時候有這麼一段代碼,在org.springframework.beans.factory.support.ConstructorResolver#resolveConstructorArguments方法中

// 本文不探討技術細節,只是為了簡單說明這個問題,所以省略無關代碼	
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

      // ....
		for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
			int index = entry.getKey();
			if (index < 0) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid constructor argument index: " + index);
			}
            // 問題就出在這裏
			if (index > minNrOfArgs) {
				minNrOfArgs = index + 1;
			}
       // ..... 

上述代碼中,minNrOfArgs這個變量就是保存方法需要的最小參數個數,但是index是下標索引,索引是從0開始的,如果有下標為n的元素,那麼最小的參數個數應該是n+1嘛,所以if中的邏輯是沒有問題的,但是if這個判斷是有問題的,正確的做法應該是

if (index+1 > minNrOfArgs) {
    minNrOfArgs = index + 1;
}

當發現這個問題的時候,第一反應就是肯定是我的姿勢不對,錯的怎麼可能是代碼,肯定是我!

接下來,我就對這段代碼進行了慘無人道的調試,在無數次debug后,我發現,這個地方確實有問題!

在確認了這個問題之後,我要思考的就是怎麼把自己的想法反饋給Spring,換而言之,怎麼為偉大的開源來做貢獻呢?正常來要達到這個目的有兩個方式

  • 提交issue
  • 直接在GitHub上提交PR(pull request)

對應的就是在GitHub上點擊下圖紅框選中的兩個位置

如果是使用提交issue的方式,相當於給官方團隊提交了一個議題,這個議題可能是你發現代碼中的某個bug,也可能是你覺得官方的做法不夠好,你有更好的想法等等。感興趣的話,大家可以去看看Spring中現在有哪些還未關閉的issue,說不定其中一個你就能解決呢~!

如果要採用提交PR的方式的話,首先你得將代碼fork到自己的GitHub中,然後在從自己的GitHub檢出到本地,在本地做完修改后,提交到GitHub倉庫中,最後從自己的GitHub向Spring官方倉庫發起一個PR。

像我的話很早就已經將代碼fork到了自己GitHub

上圖中的第一個紅框,說明我這個倉庫是從Spring官方fork過來的,第二個紅框就是可以從這裏向Spring官方提交一個PR。關於詳細的如何提交PR,大家可以自行百度,這裏不做詳細的介紹了。

另外,說了這麼多,先給大家看下我提交的issue吧。

issue鏈接:https://github.com/spring-projects/spring-framework/issues/25130

因為內容也不長,所以我這裏把原文就直接放到下面了

In ConstructorResolver:

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
		TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
		// ...

		for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
			int index = entry.getKey();
			if (index < 0) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Invalid constructor argument index: " + index);
			}
			if (index > minNrOfArgs) {
				minNrOfArgs = index + 1;
			}
			// ....
		}
// ....
 return minNrOfArgs;
}

I assume that method resolveConstructorArguments is to resolve contructor arguments in the XML file and return the minimum number of parameters required by contructor 。but if the first parameter is autowired , the second parameter is config by XML file,the method will not work well。

example:

public class FactoryObject {
	
 public DmzService getDmz(String name, int age, Date birthDay, OrderService orderService) {

	public DmzService getDmz(OrderService orderService,String name) {
		
		return new DmzService(orderService,name);
	}

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
	   default-autowire="constructor">
	<bean id="factoryObject" class="com.dmz.spring.first.instantiation.service.FactoryObject"/>

	<bean class="com.dmz.spring.first.instantiation.service.OrderService" id="orderService"/>

	<bean id="dmzService" factory-bean="factoryObject" factory-method="getDmz">
		<constructor-arg index="1"  value="dmz"/>
	</bean>

</beans>

the resolveConstructorArguments method will return 1,but correct answer is 2。

I think the problem arises because of this judgment:

if (index > minNrOfArgs) {
 minNrOfArgs = index + 1;
}

It might be better to change it to look like this

if (index + 1 > minNrOfArgs) {
 minNrOfArgs = index + 1;
}s

我在提交issue時主要是按照這種思路

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

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

  1. 首先擺出有問題的代碼
  2. 描述具體的問題,我是直接通過一個例子來描述的
  3. 說出自己的建議

這幾天我又多看了看別人提交的issue,對比起來,我覺得至少應該還要添加一點

  • 應該要明確的指出具體哪個版本上出現的問題

碰到的問題

1、擔心鬧烏龍

雖然在之前我已經調試過了無數次代碼,但是心裏還是沒譜啊。畢竟我這麼謹(cai)慎(ji)的一個人,萬一被人噴了怎麼辦?不知道你會不會這麼想,反正我當時就是這麼想的,如果你是這麼想的,建議你去看看別人提交的issue。搜索條件如下

is:closed label:”status: invalid”

我覺得你看幾個,自然就有信心了!

2、不知道要怎麼提交

每個開源的項目,只要作者希望這個項目越來越好的話,都會詳細的說明如何給這個項目做開源貢獻,Spring肯定也不例外,這裏還是以提交issue為例,當你點擊New issue的時候會出現下面這張圖

在上圖左邊的框里很明確的告訴了你提交issue應該要注意什麼

  • 首先,你應該要去Stack Overflow提問
  • 如果是bug,你應該要指明版本以及你想要做什麼
  • 如果是一個增強的話,要提供上下文並且描述清楚問題
  • 同一個問題,issue跟PR最好只提交一個,因為GitHub認為它們是一樣的,如果你還不能確定的話,先提交一個issue

而右上角還有更加詳細的文檔可供參考。

3、英文

大家應該看到了,整個issue都是用英文寫的,那麼英文不好怎麼辦呢?這個時候就要掏出我們的神器了

嗯,就是詞典,筆者習慣是使用有道詞典。我建議英文不好的同學可以這樣,先將整個issue用中文寫好,如果你真的英文一竅不通的話,可以直接通過翻譯軟件逐句翻譯,然後粘貼到GitHub上。但是千萬千萬不要使用中文,就像下面這個哥們

issue鏈接:https://github.com/spring-projects/spring-framework/pull/25127

像這種issue是會被直接打上invalid(不合格)標籤的,你就想想吧,你學不會英文,你指望我們的外國朋友能看懂中文嘛?是我中華上線五千年的文化不夠博大精深嗎?

4、擔心問題描述的不清楚

其實這個問題就是因為英文不好衍生出來的。因為英文不好,自然就會擔心我寫的東西他能不能看懂呢?我的建議就是,結合你測試的代碼去描述問題。你不用去擔心別人看不懂你寫的代碼,就以我那個issue的處理流程為例吧。

在你剛剛提交issue時,有專門的issuemaster(issue管理員)會給你提交的issue打上一個wait-for-triage的標籤,標誌這個issue是待處理的。

隨後我提交的這個issue,就被指派給了jhoeller。你要擔心他看不懂代碼嗎?給你看兩個東西吧

你知道那個紅框是啥意思嗎?就是說我發現的那個有問題代碼的類的作者就是他。

再看一張

就是說,jhoeller從2003年開始就已經是Spring這個項目的管理者以及發布經理了。2003年,我還是一個小學生……..

所以啊,只要你稍微正常點,基本上人家都能get到你的點。

給你的建議

其實筆者從發現這個問題到最終提交issue大概經過了一周時間,期間一直在猶豫要不要提交issue,就是因為上面提到的幾個問題,一直躊躇不前。但是等我下定決心要去做這件事的時候總共就花了幾個小時的時間。包括研究issue提交的規則以及寫一篇英文版的issue。並且我提交issue的第二天就馬上被處理了,並且jhoeller在 f9aae8d 這個commit中已經接受我的建議。

所以我要說的就是,

真正動手的話,不管什麼問題總能找到解決方案

而只是停留在空想,在躊躇,你永遠有一堆問題

臨淵羡魚,不如退而結網

以此文與君共勉!

如果本文對你由幫助的話,記得點個贊吧!也歡迎關注我的公眾號,微信搜索:程序員DMZ,或者掃描下方二維碼,跟着我一起認認真真學Java,踏踏實實做一個coder。

我叫DMZ,一個在學習路上匍匐前行的小菜鳥!

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

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

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

初窺Ansible playbook_貨運

※回頭車貨運收費標準

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

Ansible是一個系列文章,我會盡量以通俗易懂、詼諧幽默的總結方式給大家呈現這些枯燥的知識點,讓學習變的有趣一些。
Ansible系列博文直達鏈接:Ansible入門系列

前言

在上一篇文章中說到Ansible有兩種玩法,一種是Ansible Ad-Hoc,另一種是就是這裏要說的playbook。playbook是Ansible進行配置管理的組件,雖然Ansible的日常Ad-Hoc命令功能很強大,能完成一些基本的配置管理工作,但是Ad-Hoc命令無法支撐複雜環境的配置管理工作。在我們實際使用Ansible的工作中,大部分時間都是在編寫playbook,接下來就重點說說如何玩轉這個playbook。

執行playbook命令

我們都是按照yaml語法規則來編寫playbook,至於yaml怎麼玩,後面的文章我會總結一下的。在我們按照要求編寫好了yaml文件后,如何來執行這個yaml文件呢?

Ansible提供了一個單獨的命令:ansible-playbook命令,我們可以通過這個命令來執行yaml腳本。常見的ansible-playbook的使用方法如下:

最簡單的使用方法:

ansible-playbook copyDemo.yaml

我們還可以使用以下命令查看輸出的細節:

ansible-playbook copyDemo.yaml --verbose

我們也可以使用以下命令查看該yaml腳本將影響的主機列表:

ansible-playbook copyDemo.yaml --list-hosts

還可以使用以下命令檢查yaml腳本語法是否正確:

ansible-playbook copyDemo.yaml --syntax-check

上面的幾種使用方法基本就涵蓋了我們日常工作中80%的場景了,剩餘的20%場景,比如并行、異步等,很少用到,等真正用到的時候再去查閱相關資料也來的及。而工作中,更多的時候,我們不是在編寫playbook,就是在編寫playbook的路上。所以,接下來我重點說說如何寫這個playbook,也就是playbook的基本語法。

playbook基本語法

最基本的playbook腳本分為三個部分:

  1. 在哪些機器上以什麼身份執行
  2. 執行的任務有哪些
  3. 善後任務有哪些

我們在編寫playbook腳本的時候,總是離不開上面的三個部分的。下面先來一個稍微有點複雜的playbook腳本,讓大家先有一個整體的認識。

---
- hosts: server1
  user: root
  vars:
    http_port: 80
    max_clients: 200

  tasks:
    - name: Write apache config file
      template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf
      notify:
        - restart apache
    - name: Ensure apache is running
      service: name=httpd state=started

  handlers:
    - name: restart apache
      service: name=httpd state=restarted

現在就對上述三部分稍作詳細總結。

主機和用戶

上面的yaml腳本,我們一開始就會看到hosts、user和vars,其中vars在後面的文章進行專門總結。而這裏的hosts和user就是表示我們這個yaml將要在哪些主機上用哪個用戶身份去操作。而這裏的深一層次的關係如下錶所示:

key 含義
hosts 為主機的IP,或者主機組名,或者關鍵字all
user 在遠程以哪個身份執行
become 切換成其他用戶身份執行,值為yes或者no
become_method 與become一起使用,值可以為sudo/su等
become_user 與become一起使用,可以是root或者其它用戶名

在實際工作中,如果我們不指定user時,則默認使用連接遠程主機的用戶進行操作,如果指定了執行用戶而與ansible_ssh_user指定用戶不一致時,則需要開啟become操作,這裏的become配置與ansible.cfg中配置將相互配合完成工作,yaml中的become優先級高於ansible.cfg中配置中的優先級。

任務列表

任務列表是整個playbook的核心,對於任務列表,我們首先需要知道以下三點內容:

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

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

  • 任務是從上到下順序執行的,如果中間發生錯誤,那麼整個playbook會中止;
  • 每一個任務都是對模塊的一次調用,只是使用不同的參數和變量而已;
  • 每一個任務最好有一個name屬性,這樣在執行yaml腳本時,可以看到執行進度信息。

對於任務的參數有兩種不同的寫法,我們在編寫yaml腳本時,可以按照自己的喜好進行選擇。

寫法一:

- name: Write apache config file
  template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf

寫法二:

- name: Write apache config file
  template: 
    src: /home/test1/httpd.j2
    dest: /home/test2/httpd.conf

這兩種寫法都是OK的,我一般喜歡第二種寫法。

最後,對於任務我們還需要特別一個點,那就是任務的執行狀態。我們在執行Ansible Ad-Hoc或者ansible-playbook的時候,在輸出中都會有一個changed字段,比如:

192.168.1.3                : ok=2    changed=0    unreachable=0    failed=0  

或者

192.168.1.3                : ok=2    changed=1    unreachable=0    failed=0

這裏的這個changed就是人物的執行狀態,但是它為什麼一會是0,一會有是1呢?這就要說到Ansible中一個叫做“冪等性”的概念。

冪等性

冪等性是數學和計算機科學上一個常見的概念,多次執行產生的結果不會發生改變,這樣的特性就被成為冪等性。

大多數的Ansible模塊在設計時保證了冪等性,冪等性保證了Ansible腳本多次執行情況下的相同結果,盡可能的避免使用那些不能滿足冪等性的模塊。比如我們經常使用的shell模塊就是非冪等性的。

我們要明白Ansible是以“結果為導向的”,我們指定了一個“目標狀態”,Ansible會自動判斷“當前狀態”是否與“目標狀態”一致,如果一致,則不進行任何操作;如果不一致,那麼就將“當前狀態”變成“目標狀態”,這就是“冪等性”,“冪等性”可以保證我們重複的執行同一項操作時,得到的結果是一樣的。

那這個冪等性與上面的changed又有什麼關係呢?且聽我下面慢慢道來!

  • 當changed為false或者0時,表示Ansible沒有進行任何操作,沒有“改變什麼”;
  • 當changed為true或者大於0時,表示Ansible執行了操作,“當前狀態”已經被Ansible改變成了“目標狀態”。

拿copy這個模塊來舉例子說明,當我們準備將一個文件通過Ansible拷貝到遠程主機時,copy模塊首先檢查遠程是否已經存在了該文件,如果不存在,則把文件拷貝過去,返回changed為大於0;如果存在時,則開始比對兩個文件的md5值,如果md5值一致,則說明兩個文件是一樣的,則不需要拷貝,此時copy模塊則什麼都不幹,返回changed為0。

總結

通過三篇文章總結了Ansible中的常用模塊、Ansible Ad-Hoc和ansible-playbook的一些慣用用法,從我的實際學習經驗來說,學到這裏,你可以將這三塊內容結合起來使用了,至少可以在你們生產環境鼓搗一下了。生來就是折騰,更何況我們這麼拚命、努力的學習呢!

果凍想,認真玩技術的地方。

2019年5月18日,於內蒙古呼和浩特。

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

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

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

面試官問我會不會Elasticsearch,我語塞了…_網頁設計公司

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

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

少點代碼,多點頭髮

本文已經收錄至我的GitHub,歡迎大家踴躍star 和 issues。

https://github.com/midou-tech/articles

從今天開始準備給大家帶來全新的一系列文章,Elasticsearch系列

新系列肯定會有很多疑惑,先為大家答疑解惑,下面是今天要講的問題

為什麼寫Elasticsearch系列文章?

之前在文章中也陸陸續續的提到過,龍叔是做搜索引擎的。搜索引擎技術屬於商業技術,大家耳熟能詳的百度搜索,Google搜索,這可都是因為把握核心搜索技術,從而誕生了商業帝國。

每個互聯網大廠都想去分一杯搜索的羹,360搜索、神馬、頭條、搜狗搜索等等,由此可見搜索技術的商業作用和機密性了。

搜索把握用戶的入口

蘑菇街的搜索引擎是一款使用C++開發、完全自研、沒有開源的搜索引擎,沒有開源就是不能隨便寫出來的。

但是現在不一樣了

第一、我離職了,離開了意味着不在持有那些商業機密了,就算不講出來我也沒啥心理負擔(但還是不能講的,離職協議寫的很清楚,不能泄露公司商業機密)。

第二、去新的公司還是在搜索領域,他們用Es Elasticsearch是一個開源搜索,開源的東西可以隨便說,但還是不能說公司的商業數據。

自己一直在搜索領域做,輸出搜索相關的文章,第一個可以讓自己更好的學習和總結,第二個可以讓粉絲們了解到搜索這個神秘的技術,增加大家自身的核心競爭力。

後面會說到,Elasticsearch是搜索引擎,但不簡單隻能使用在搜索領域,他可以作用的場景非常多。

Elasticsearch是什麼?

Elasticsearch 是一個分佈式的開源搜索和分析引擎,適用於所有類型的數據,包括文本、数字、地理空間、結構化和非結構化數據。

Elasticsearch 在 Apache Lucene 的基礎上開發而成,Elasticsearch 以其簡單的 REST 風格 API、分佈式特性、速度和可擴展性而聞名,是 Elastic Stack 的核心組件。

Elastic Stack 是適用於數據採集、充實、存儲、分析和可視化的一組開源工具。人們通常將 Elastic Stack 稱為 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列豐富的輕量型數據採集代理,這些代理統稱為 Beats,可用來向 Elasticsearch 發送數據。

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

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

Elasticsearch 的實現原理主要分為以下幾個步驟,首先用戶將數據提交到Elasticsearch 數據中心,再通過分詞控制器去將對應的數據分詞,將其權重和分詞結果一併存入數據,當用戶搜索數據時候,再根據權重將結果排名,打分,再將返回結果呈現給用戶。

是什麼差不多搞清楚了,再說說ES都哪些成熟的應用以及在哪些領域使用。

Elasticsearch在哪些領域使用?

  • 應用程序搜索
  • 網站搜索
  • 企業搜索
  • 日誌處理和分析
  • 基礎設施指標和容器監測
  • 應用程序性能監測
  • 地理空間數據分析和可視化
  • 安全分析
  • 業務分析

Elasticsearch有哪些特點?

Elasticsearch 很快。 由於 Elasticsearch 是在 Lucene 基礎上構建而成的,所以在全文本搜索方面表現十分出色。Elasticsearch 同時還是一個近實時的搜索平台,這意味着從文檔索引操作到文檔變為可搜索狀態之間的延時很短,一般只有一秒。因此,Elasticsearch 非常適用於對時間有嚴苛要求的用例,例如安全分析和基礎設施監測。

Elasticsearch 具有分佈式的本質特徵。 Elasticsearch 中存儲的文檔分佈在不同的容器中,這些容器稱為分片,可以進行複製以提供數據冗餘副本,以防發生硬件故障。Elasticsearch 的分佈式特性使得它可以擴展至數百台(甚至數千台)服務器,並處理 PB 量級的數據。

Elasticsearch 包含一系列廣泛的功能。 除了速度、可擴展性和彈性等優勢以外,Elasticsearch 還有大量強大的內置功能(例如數據匯總和索引生命周期管理),可以方便用戶更加高效地存儲和搜索數據。

Elastic Stack 簡化了數據採集、可視化和報告過程。 通過與 Beats 和 Logstash 進行集成,用戶能夠在向 Elasticsearch 中索引數據之前輕鬆地處理數據。同時,Kibana 不僅可針對 Elasticsearch 數據提供實時可視化,同時還提供 UI 以便用戶快速訪問應用程序性能監測 (APM)、日誌和基礎設施指標等數據。

學習Elasticsearch能提高哪些競爭力?

看到Elasticsearch在這麼多的領域在使用,特點也這麼明顯。看到這裏估計都不用在說什麼核心競爭力,你已經意識到了。

Elastic 於 2018 年 6 月 29 日正式推出 Elastic Certified Engineer 認證考試,認證通過可以獲得官方頒發的證書和徽章,title就是 Elastic認證工程師

具體認證的細節和含金量,沒有具體研究過,但是可以很明顯的感受到官方出了這樣一個認證,表明社會需要大量這樣的人才,而這方面人才的培養和考核指標還欠缺。

有沒有必要一定要考這個認證?

個人覺得,和英語四六級一樣,通過了再說沒用。

如果你是學生,可以考慮去考一個認證,因為你很難有業務場景驅使你去做這方面的成長,認證一定是有難度的,一個一個的困難會驅使你成長,最終這個認證也會成為招聘時一個非常大的亮點。

這個認證會有哪些幫助?

  • 對於快速的構建知識體系幫助。

  • 對於全面的熟悉官方文檔幫助。

  • 對於實戰解決線上問題幫助。(遇到了相關技術問題基本上不需要再求助於社區,80%以上的問題自己基本就能解決。)

  • 對於增強信心、克服英文恐懼幫助。

Elasticsearch 支持哪些編程語言?

  • Java
  • JavaScript (Node.js)
  • Go
  • .NET (C#)
  • PHP
  • Perl
  • Python
  • Ruby

哪裡可以找到有關 Elasticsearch 的更多信息?

  • Elasticsearch GitHub 存儲庫:https://github.com/elastic
  • Elasticsearch 官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
  • Elasticsearch中文社區:https://elasticsearch.cn

我是龍叔,一個分享互聯網技術和心路歷程的star。

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

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

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

和付費網盤說再見,跟着本文自己起個網盤(Java 開源項目)_租車

※超省錢租車方案

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

本文適合有 Java 基礎知識的人群,跟着本文可學習和運行 Java 網盤項目。

本文作者:HelloGitHub-秦人

HelloGitHub 推出的《講解開源項目》系列。

今天給大家帶來一款開源 Java 版網盤項目—— kiftd-source,本文將用 3 分鐘帶大家搭建一個個人網盤,技術便利生活,你值得擁有~

項目地址:https://github.com/KOHGYLW/kiftd-source

一、項目介紹

kiftd 是一款開源、使用簡單、功能完整的 Java 網盤/雲盤系統。支持在線視頻播放、文檔在線預覽、音樂播放、圖片查看等功能的文件雲存儲平台。

技術棧

  • JDK 版本:1.8.0_131
  • 項目管理框架:Maven(m2e 1.8.0 for Eclipse)
  • Archetype:mavem-archetype-quickstart 1.1
  • Spring Boot:SpringBoot 基於 Spring 開發,旨在提高微服務的開發效率。
  • MyBatis:一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。
  • H2 DB:一款開源的嵌入式數據庫引擎,採用 Java 語言編寫,不受平台的限制。

二、網盤搭建

2.1 Windows 環境運行

2.1.1 下載安裝包

直接從官網下載最新的安裝包,安裝地址:https://kohgylw.gitee.io/

項目比較溫馨,支持三種下載方式:Github、阿里雲、Gitee 下載。如下圖:

2.1.2 檢查配置

這裏主要檢查一下本地 JDK 是否已安裝,在命令行窗口執行 java -version 查看 Java 版本。如下所示表示已安裝,就可以進行下一步操作。

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

2.1.3 運行 jar

雙擊 kiftd-1.0.29-RELEASE.jar,或者在命令行執行 java -jar kiftd-1.0.29-RELEASE.jar 命令都運行可以jar 文件,會彈出安裝的界面,如下圖:

這個界面的這幾個按鈕說明一下:

  • 開啟(Start):運行網盤服務,初次啟動的端口默認是 8080。
  • 文件(Files):這個按鈕菜單中主要有網盤文件導入,導出,刪除,刷新功能。
  • 設置(Setting):設置功能主要可以設置網盤的服務端口,網盤的物理存儲路徑等信息。
  • 退出(Exit):關閉網盤系統。

點擊 開啟(Start) 按鈕即可運行網盤,這裏我設置的端口是 8090,在瀏覽器訪問: localhost:8090,運行效果如下圖:

項目是運行了,發現一個問題無法上傳文件?因為我們忘了登錄這個操作。點擊系統 登錄按鈕,填入賬號和密碼即可登錄。那麼登錄密碼在哪裡呢?這裏我直接告訴大家,用戶信息在 conf/account.properties,文件內容如下:

#<This is the default kiftd account setting file. >
#Sun May 10 21:56:28 CST 2020
admin.pwd=000000  #用戶名.密碼=000000
authOverall=l
admin.auth=cudrm
  • 用戶名:admin
  • 密碼:000000

這樣登錄之後就可以使用網盤的所有功能了。

2.2 Linux 環境運行

2.2.1 安裝 Screen 工具

Screen 工具能夠虛擬出一個終端並執行相應的操作。因為本篇所講的網盤需要一個終端。執行如下命令安裝 Screen:

yum install screen

2.2.2 Screen 常用命令

screen -S myScreen #創建虛擬終端
java -jar kiftd-1.0.29-RELEASE.jar -console #在虛擬終端中以命令模式啟動 kiftd
screen -r myScreen #返回之前的虛擬終端並繼續操作 kiftd。

2.2.3 命令行操作

在 Linux 環境上使用 console 模式啟動的效果是這樣的:

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

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

命令行輸入 -start 即可運行項目。例如輸入 -files 控制台显示是這樣的:

其實和 Windows 上一樣,包括文件導入,導出,刪除功能,多了幾個命令是查看文件,切換目錄等功能。

三、開發環境運行

3.1 下載項目

兩種方式下載項目,使用 GitBash 下載項目:

git clone https://github.com/KOHGYLW/kiftd-source.git

另外一種方式直接下載 zip 壓縮包,如下圖:

3.2 運行

打開 kohgylw.kiftd.mc.MC 類,進行測試運行。注意:本文使用 Eclipse 工具打開。

3.3 閱讀代碼

3.3.1 前台請求

就以創建目錄這個功能為例。我們先看前端功能。點擊“操作”->“新建文件夾”,填寫文件夾名稱,點擊保存如下圖:

我們知道前台 新建文件夾 功能調用的後台接口是 newFolder.ajax

3.3.2 後端接口
通過前台請求可知調用的後台接口為 homeController/newFolder.ajax。打開代碼實現,我們會看到下面這個方法。

public String newFolder(final HttpServletRequest request) {
		
        ...
        //參數校驗的部分代碼已省略
		Folder f = new Folder();
		f.setFolderId(UUID.randomUUID().toString());
		f.setFolderName(folderName);
		f.setFolderCreationDate(ServerTimeUtil.accurateToDay());
		if (account != null) {
			f.setFolderCreator(account);
		} else {
			f.setFolderCreator("匿名用戶");
		}
		f.setFolderParent(parentId);
		int i = 0;
		while (true) {
			try {
                // 數據庫插入新建文件夾的數據
				final int r = this.fm.insertNewFolder(f);
				if (r > 0) {
					if (fu.isValidFolder(f)) {
						this.lu.writeCreateFolderEvent(request, f);
						return "createFolderSuccess";
					} else {
						return "cannotCreateFolder";
					}
				}
				break;
			} catch (Exception e) {
				f.setFolderId(UUID.randomUUID().toString());
				i++;
			}
			if (i >= 10) {
				break;
			}
		}
		return "cannotCreateFolder";
	}

四、功能說明

4.1 上傳

  1. 點擊 操作,可以上傳文件和上傳文件夾,如下圖:

  2. 將本地需要上傳的文件,拖拽網盤頁面也可以上傳此文件。

4.2 視頻/音頻播放

  1. 上傳視頻到網盤,網盤也支持在線視頻播放,效果如下圖:

  2. 上傳音頻,例如我最喜歡 周杰倫 的歌曲,可以在線播放了。

4.3 快捷鍵使用

網盤還對一些常用功能添加了快捷鍵。功能和快捷鍵參照如下:

功能 快捷鍵
上傳文件夾 Shift +U
上傳文件 Shift +F
新建文件 Shift +N
複製 Shift +C
剪切 Shift +X
刪除 Shift +D

4.4 配置文件修改

配置文件在項目 conf 目錄,包括兩個配置文件:

  • account.properties:配置賬號信息,權限信息
  • server.properties:服務器的配置文件,可配置服務器端口,緩衝文件大小等

4.5 在線預覽

網盤支持文檔 txt、pdf、docx、ppt 在線預覽功能,支持圖片的在線預覽。圖片預覽效果如下:

pdf 文件預覽效果如下:

4.6 分享下載鏈接

網盤也考慮文件的分享,它可以生成下載鏈接,瀏覽器訪問下載鏈接就可以直接下載文件。選擇需要下載的文件,點擊 下載 按鈕,選擇 下載鏈接+,既可以生成文件下載鏈接。如下圖:

五、最後

教程至此已經結束,你自己的網盤跑起來了嗎?網盤是不是還不錯?而且搭建也特別簡單。一些重要的東西就可以存放到自己的網盤啦!說到底,編程語言只是工具,我們只要很好的使用工具,再加上自己天馬行空的思想,我想會創造出更多不可思議的項目。

Java 語言為什麼經久不衰,因為它能做的事情太多了,而且生態也特別豐富。如果你也有興趣那就加入 Javaer 開發者的大家庭吧!開源分享讓我們彼此認識,有了開源項目讓我們看到編程語言的絢麗多彩。

教程至此,你應該也能快速運行個人網盤了。編程是不是也特別有意思呢?先下載安裝包給自己部署一套網盤系統吧。對源碼感興趣的朋友可以開始學習項目源碼了~

關注公眾號加入交流群

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

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

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

Python編程思想(3):数字及其相關運算_包裝設計

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

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

Python 提供了三種數值類型:int(整型),float(浮點型)和complex(複數)。

  • int:通常被稱為整型或者整數,如200、299、10都屬於整型;
  • float:浮點數包含整數和小數部分,如3.1415926,2.71828都屬於浮點數;
  • complex:複數包含實數部分和虛數部分,形如 a+bj,其實部和虛部都是浮點類型;

需要注意的是,Python3 已經廢棄了 Python2 的 Long(長整型),在 Python3 中,int 的大小沒有限制,可以作為 Long 使用。這也是為什麼Python非常適合科學計算的原因,因為Python可以處理無限大的整數。在Python中進行數值運算,並不需要考慮溢出問題,因為Python的數值永遠不會溢出。  
1. 數值類型之間的轉換   Python 的三種數值類型可以進行相互轉換,轉換方式為:数字類型+圓括號,如下實例:

a = 456
b = 2.71828
print("int(b)=",int(b))
print("float(a)=",float(a))
print("complex(a)=",complex(a))
print("complex(a,b)=",complex(a,b))

執行結果如下圖所示:    
2. 常用的數學函數   Python 提供了豐富的數學函數以降低編程實現的難度,本問將介紹一些常用的函數。

import math
#求絕對值:abs(x)
print("abs(-200)=",abs(-200))

#向上取整:ceil(x)
print("ceil(3.1415)=",math.ceil(3.1415))

#向下取整:floor(x)
print("floor(3.678)=",math.floor(3.678))

#四舍五入:round(x)
print("round(3.678)=",round(3.678))

#乘方運算:pow(x,y),x的y次方
print("pow(3,4)=",pow(3,4))

#求平方根:sqrt(x)
print("sqrt(144)=",math.sqrt(144))

執行結果如下圖所示:

 
3. 運算符   計算機的最基本用途之一就是執行數學運算,作為一門計算機編程語言,Python 也提供了一套豐富的運算符來滿足各種運算需求。 Python 運算符主要可以分為6種:算術運算符、比較運算符、賦值運算符、邏輯運算符、位運算符和成員運算符。  
(1)算術運算符 對於算術運算,大家並不陌生,常用的加減乘除就是算術運算。不過,在編程語言里,算術運算符特殊一些,Python 中的算術運算有7種:加(+)、減(-)、乘( * )、除(/)、取模(%)、冪運算( ** )和取整預算(//)。以下通過實例演示算術運算符的用法。

#初始化測試數據
x = 30
y = 24
z = 12
#分別進行7種算術運算
z = x + y
print("x + y =", z)
z = x - y
print("x - y =", z)
z = x * y
print("x * y =", z)
z = x / y
print("x / y =", z)
z = x % y
print("x % y =", z)
z = x ** y
print("x ** y =", z)
z = x // y
print("x // y =", z)

執行結果如下圖所示:

 

  (2)比較運算符

比較無處不在,大於、小於、等於、不等於……和 C/C++、Java 等編程語言一樣,Python 也提供了6種比較運算符:>(大於),<(小於),==(等於),!=(不等於),>=(大於等於),<=(小於等於)。比較運算的結果是一個布爾值,True 或者 False,看下面的案例代碼:

# 初始化變量
x = 12
y = 7
#分別進行6種比較運算
print("x == y:", x == y)
print("x != y:", x != y)
print("x > y:", x > y)
print("x < y:", x < y)
print("x >= y:", x >= y)
print("x <= y:", x <= y)

執行結果如下圖所示:  
(3)賦值運算符 其實在前面的代碼中已經用到賦值運算,如 x = 12,就是一個最簡單的賦值運算,“=”就是最簡單的賦值運算符。將簡單的賦值運算與算術運算結合,Python 形成了更豐富的賦值運算符:+=、-=、=、/=、%=、*=、//=。看下面的案例代碼:

#初始化變量
x = 12
y = 21
#分別進行7種賦值運算
y = x
print("y = x, y =", y)
y += x
print("y += x, y =", y)
y -= x
print("y -= x, y =", y)
y *= x
print("y *= x, y =", y)
y /= x
print("y /= x, y =", y)
y **= x
print("y **= x, y =", y)
y //= x
print("y //= x, y =", y)

執行結果:

 

 

(4)邏輯運算符 所謂邏輯運算,就是:與、或、非。Python 中的3種邏輯運算符分別為:and(與),or(或),not(非),邏輯運算的結果是布爾值:True 或者 False。

  1. A and B:當A和B有一個為False時,結果就為False,只有A和B都為True時,結果才為True;
  2. A or B:只有當A和B都是False時,結果才為False,只要有一個為True,結果就為True;
  3. not A:當 A 為 True 時,返回 False,否則返回 True。

看下面的案例:

#初始化變量
a = 2
b = 3
c = 5
#分別執行3種邏輯運算
print("a>b and a<c :", a>b and a<c)
print("a<b and c :", a<b and c)
print("a>b or c :", a>b or a<c)
print("a<b or c :", a<b or c)
print("a or a<c :", a or a<c)
print("not a :", not a)
print("not a<b :", not a<b)

執行結果如下圖所示:

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

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

 
(5)位運算符 程序中的所有數值在計算機內存中都是以二進制的形式儲存的。位運算就是直接對整數在內存中的二進制位進行操作。Python 中有6種位運算符:

  • &:按位與,參与運算的兩個值,如果兩個相應位都為1,則該位的結果為1,否則為0;
  • |:按位或,只要對應的2個二進位有一個為1時,結果位就為1;
  • ^:按位異或,當兩對應的二進位相異時,結果為1;
  • ~:按位取反,對數據的每個二進制位取反,即把1變為0,把0變為1;
  • >>:按位右移,將>>左側的數按位向右移動>>右邊的數指定的位;
  • <<:按位左移,將<<左側的數按位向左移動<<右邊的數指定的位;

看下面的案例代碼:

a = 21
b = 6
print('a & b = ',a & b)
print('a | b = ',a | b)
print('a ^ b = ',a ^ b)
print('~a = ',~a)
print('a << 2 = ',a << 2)
print('a >> 2 = ',a >> 2)

執行結果如下圖所示:

 

 

 這裏講a=21,b=6,轉換為二進制如下:

a = 0001 0101
b = 0000 0110

a&b = 0000 0100
a|b = 0001 0111
a^b = 0001 0011
~a = 1110 1010
a<<2 = 01010100
a>>2 = 0000 0101

(6)成員運算符 除了前面介紹的5種運算符,Python 還支持成員運算符。介紹成員運算符之前,我們需要提前了解一個概念:數據結構,如字符串、列表、元組、字典。在接下來的文章中我們將詳細介紹這些基礎的數據結構。字符串、列表、字典,它們就像一個集合,其中包含若干元素,這些元素就是集合的成員;對於一個給定的元素,它有可能在一個給定的集合中,也可能不在,Python 中採用成員運算符來判斷元素是否屬於成員,成員運算的結果為布爾值,True 或者 False。 看下面的代碼:

#初始化字符串和列表
temp1 = "abcdefg"
temp2 = [4,2,3,5,8,9]
a = "cdf"
b = 5
c = "cde"
print("a in temp1?", a in temp1)
print("b in temp2?", b in temp2)
print("c in temp1?", c in temp1)

  執行結果如下圖所示:    

 

 

 

 

 

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

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

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