深入理解JS:var、let、const的異同_網頁設計公司

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

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

目錄

  • 序言
  • var 與 let 的區別
    • 作用域
    • 重複聲明
    • 綁定全局對象
    • 變量提升與暫存死區
  • let 與 const 異同
  • 參考

1.序言

var、let 和 const 都是 JavaScript 中用來聲明變量的關鍵字,並且 let 和 const 關鍵字是在 ES6 中才新增的。既然都是用來聲明變量的,那它們之間有什麼區別呢?讓我們來一探究竟。

2.var 與 let 的區別

(1)作用域

用 var 聲明的變量的作用域是它當前的執行上下文,即如果是在任何函數外面,則是全局執行上下文,如果在函數裏面,則是當前函數執行上下文。換句話說,var 聲明的變量的作用域只能是全局或者整個函數塊的。

而 let 聲明的變量的作用域則是它當前所處代碼塊,即它的作用域既可以是全局或者整個函數塊,也可以是 if、while、switch等用{}限定的代碼塊。

另外,var 和 let 的作用域規則都是一樣的,其聲明的變量只在其聲明的塊或子塊中可用。

示例代碼:

function varTest() {
  var a = 1;

  {
    var a = 2; // 函數塊中,同一個變量
    console.log(a); // 2
  }

  console.log(a); // 2
}

function letTest() {
  let a = 1;

  {
    let a = 2; // 代碼塊中,新的變量
    console.log(a); // 2
  }

  console.log(a); // 1
}

varTest();
letTest();

從上述示例中可以看出,let 聲明的變量的作用域可以比 var 聲明的變量的作用域有更小的限定範圍,更具靈活。

(2)重複聲明

var 允許在同一作用域中重複聲明,而 let 不允許在同一作用域中重複聲明,否則將拋出異常。

var 相關示例代碼:

var a = 1;
var a = 2;

console.log(a) // 2

function test() {
  var a = 3;
  var a = 4;
  console.log(a) // 4
}

test()

let 相關示例代碼:

if(false) {
  let a = 1;
  let a = 2; // SyntaxError: Identifier 'a' has already been declared
}
switch(index) {
  case 0:
    let a = 1;
  break;

  default:
    let a = 2; // SyntaxError: Identifier 'a' has already been declared
    break;
}

從上述示例中可以看出,let 聲明的重複性檢查是發生在詞法分析階段,也就是在代碼正式開始執行之前就會進行檢查。

(3)綁定全局對象

var 在全局環境聲明變量,會在全局對象里新建一個屬性,而 let 在全局環境聲明變量,則不會在全局對象里新建一個屬性。

示例代碼:

var foo = 'global'
let bar = 'global'

console.log(this.foo) // global
console.log(this.bar) // undefined

那這裏就一個疑問, let 在全局環境聲明變量不在全局對象的屬性中,那它是保存在哪的呢?

var foo = 'global'
let bar = 'global'

function test() {}

console.dir(test)

在Chrome瀏覽器的控制台中,通過執行上述代碼,查看 test 函數的作用域鏈,其結果如圖:

由上圖可知,let 在全局環境聲明變量 bar 保存在[[Scopes]][0]: Script這個變量對象的屬性中,而[[Scopes]][1]: Global就是我們常說的全局對象。

(4)變量提升與暫存死區

var 聲明變量存在變量提升,如何理解變量提升呢?

要解釋清楚這個,就要涉及到執行上下文和變量對象。

在 JavaScript 代碼運行時,解釋執行全局代碼、調用函數或使用 eval 函數執行一個字符串表達式都會創建並進入一個新的執行環境,而這個執行環境被稱之為執行上下文。因此執行上下文有三類:全局執行上下文、函數執行上下文、eval 函數執行上下文。

執行上下文可以理解為一個抽象的對象,如下圖:

Variable object:變量對象,用於存儲被定義在執行上下文中的變量 (variables) 和函數聲明 (function declarations) 。

Scope chain:作用域鏈,是一個對象列表 (list of objects) ,用以檢索上下文代碼中出現的標識符 (identifiers) 。

thisValue:this 指針,是一個與執行上下文相關的特殊對象,也被稱之為上下文對象。

一個執行上下文的生命周期可以分為三個階段:創建、執行、釋放。如下圖:

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

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

而所有使用 var 聲明的變量都會在執行上下文的創建階段時作為變量對象的屬性被創建並初始化,這樣才能保證在執行階段能通過標識符在變量對象里找到對應變量進行賦值操作等。

而用 var 聲明的變量構建變量對象時進行的操作如下:

  • 由名稱和對應值(undefined)組成一個變量對象的屬性被創建(創建並初始化)
  • 如果變量名稱跟已經聲明的形式參數或函數相同,則變量聲明不會幹擾已經存在的這類屬性。

上述過程就是我們所謂的“變量提升”,這也就能解釋為什麼變量可以在聲明之前使用,因為使用是在執行階段,而在此之前的創建階段就已經將聲明的變量添加到了變量對象中,所以執行階段通過標識符可以在變量對象中查找到,也就不會報錯。

示例代碼:

console.log(a) // undefined

var a = 1;

console.log(a) // 1

let 聲明變量存在暫存死區,如何理解暫存死區呢?

其實 let 也存在與 var 類似的“變量提升”過程,但與 var 不同的是其在執行上下文的創建階段,只會創建變量而不會被初始化(undefined),並且 ES6 規定了其初始化過程是在執行上下文的執行階段(即直到它們的定義被執行時才初始化),使用未被初始化的變量將會報錯。

let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

在變量初始化前訪問該變量會導致 ReferenceError,因此從進入作用域創建變量,到變量開始可被訪問的一段時間(過程),就稱為暫存死區(Temporal Dead Zone)。

示例代碼 1:

console.log(bar); // undefined
console.log(foo); // ReferenceError: foo is not defined

var bar = 1;
let foo = 2;

示例代碼 2:

var foo = 33;
{
  let foo = (foo + 55); // ReferenceError: foo is not defined
}

注:首先,需要分清變量的創建、初始化、賦值是三個不同的過程。另外,從 ES5 開始用詞法環境(Lexical Environment)替代了 ES3 中的變量對象(Variable object)來管理靜態作用域,但作用是相同的。為了方便理解,上述講解中仍保留使用變量對象來進行描述。

小結

  1. var 聲明的變量在執行上下文創建階段就會被「創建」和「初始化」,因此對於執行階段來說,可以在聲明之前使用。

  2. let 聲明的變量在執行上下文創建階段只會被「創建」而不會被「初始化」,因此對於執行階段來說,如果在其定義執行前使用,相當於使用了未被初始化的變量,會報錯。

3.let 與 const 異同

const 與 let 很類似,都具有上面提到的 let 的特性,唯一區別就在於 const 聲明的是一個只讀變量,聲明之後不允許改變其值。因此,const 一旦聲明必須初始化,否則會報錯。

示例代碼:

let a;
const b = "constant"

a = "variable"
b = 'change' // TypeError: Assignment to constant variable

如何理解聲明之後不允許改變其值?

其實 const 其實保證的不是變量的值不變,而是保證變量指向的內存地址所保存的數據不允許改動(即棧內存在的值和地址)。

JavaScript 的數據類型分為兩類:原始值類型和對象(Object類型)。

對於原始值類型(undefined、null、true/false、number、string),值就保存在變量指向的那個內存地址(在棧中),因此 const 聲明的原始值類型變量等同於常量。

對於對象類型(object,array,function等),變量指向的內存地址其實是保存了一個指向實際數據的指針,所以 const 只能保證指針是不可修改的,至於指針指向的數據結構是無法保證其不能被修改的(在堆中)。

示例代碼:

const obj = {
  value: 1
}

obj.value = 2

console.log(obj) // { value: 2 }

obj = {} // TypeError: Assignment to constant variable

4.參考

var – JavaScript | MDN

let – JavaScript – MDN – Mozilla

const – JavaScript – MDN – Mozilla

深入理解JavaScript系列(12):變量對象(Variable Object)

ES6 let 與 const

詳解ES6暫存死區TDZ

嗨,你知道 let 和 const 嗎?

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

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

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

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

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

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

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

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

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

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

速度

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

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

1、輪胎

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

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

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

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

2、進氣系統

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

3、懸架

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

4、前後包圍

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

5、防翻滾架/座位

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

最後的最後,可能有人就會問了,我不會把車改成這個樣子啊,其實小編想說的是,有的人開車遇到溝坎減速帶什麼的都不減速的,原理其實和賽車一樣,如果你真的需要暴力開,還真的要把車子改成高強度的狀態,量產車隨便虐只會大大減少壽命,甚至會直接弄毀車輛。本站聲明:網站內容來源於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日誌中設置了兩個標誌位置,checkpointwrite_pos,分別表示記錄擦除的位置和記錄寫入的位置。redo log日誌的數據寫入示意圖可見下圖。

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

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文案是廣告用的文字。舉凡任何宣傳、行銷、販賣商品時所用到的文字都是文案。在網路時代,文案成為行銷中最重要的宣傳方式,好的文案可節省大量宣傳資源,達成行銷目的。

學習源碼的第八個月,我成了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,一個在學習路上匍匐前行的小菜鳥!

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

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

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

和付費網盤說再見,跟着本文自己起個網盤(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 在線預覽

網盤支持文檔 txtpdfdocxppt 在線預覽功能,支持圖片的在線預覽。圖片預覽效果如下:

pdf 文件預覽效果如下:

4.6 分享下載鏈接

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

五、最後

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

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

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

關注公眾號加入交流群

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

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

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

國外零售商洩漏 Intel 第 11 代 Rocket Lake-S 處理器的售價,i9-11900K 價格比上一代便宜一些_網頁設計公司

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

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

先前 CES 2021 發表會上,Intel 正式透露第 11 代 Rocket Lake-S 處理器(i9-11900K)官方效能跑分之後,相信不少玩家都非常期待,不僅比上一代還強,也勝過對手的 AMD 12 核心 Ryzen 5900X,不過當時並沒有公布售價,也因此想買的人究竟該準備多少,只能參考第 10 代的價格。最近國外就有一間零售商,疑似搶先放上第 11 代 Rocket Lake-S 處理器的價格列表,從 i9、i7、一直到 i5 都有,有些比較貴,有些便宜。

國外零售商洩漏 Intel 第 11 代 Rocket Lake-S 處理器的售價

近日比利時一間 2Compute 電腦硬體零售商在它的官網上,洩漏第 11 代 Rocket Lake-S 處理器的價格列表,而且現在還沒刪除,感覺就像是故意放上去一樣。

根據列表顯示,新一代遊戲旗艦處理器 8 核心 16 執行緒的 i9-11900K 單顆未稅價為 499.70 歐元,含稅之後變成 605 歐元,代表說比上一代 i9-10900K 還便宜 9.8% 左右。

下圖是 i9-11900K 的價格:

i9-10900K 的價格,單顆未稅價 549 歐元,含稅之後 665 歐元:

下方為第 11 代 Rocket Lake-S 處理器與第 10 代 Comet Lake-S 處理器的比較圖,i9-11900KF 也比上一代便宜,但 i9-11900 與 i9-11900F 就沒有,其餘 i7、i5 大多數也比上一代貴:

2Compute 網站洩漏的 Rocket Lake-S 處理器價格清單(含稅價):

  • i5-11400:205 歐元
  • i5-11400F:175 歐元
  • i5-11500:227 歐元
  • i5-11600:250 歐元
  • i5-11600K:294 歐元
  • i5-11600KF:265 歐元
  • i7-11700:371 歐元
  • i7-11700F:342 歐元
  • i7-11700K:456 歐元
  • i7-11700KF:427 歐元
  • i9-11900:494 歐元
  • i9-11900F:465 歐元
  • i9-11900K:605 歐元
  • i9-11900KF:576 歐元

如果比較整體價格,第 11 代 Rocket Lake-S 處理器平均大約比第 10 代 Comet Lake-S 處理器貴 14% 左右。當然,這是零售商搶先洩漏的清單,也因此一切還是要以 Intel 官方為主。

Intel 第 11 代 Rocket Lake-S 處理器預計會在 3 月正式推出,下個月應該會有更確切的消息出現。

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

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

有趣的是,除了 2Compute,國外其實還有其他零售商也洩漏這價格清單,不過大家都不太一樣,讓人看起來有點亂:

Intel 11th Gen Price

10th Gen sheet is for comparison pic.twitter.com/kAvMbIQjKm

— 포시포시 (@harukaze5719) January 17, 2021

資料來源:Video Cardz

Intel 第 11 代「Rocket Lake」與第 12 代「Alder Lake」搶先看

您也許會喜歡:

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

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

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

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

次世代 ROG Phone 騰訊搶先預告登場!傳升級 65W 快充應援你的電競行動生活_網頁設計公司

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

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

2021 年新世代電競手機戰爭最早將在 3 月開打?根據華碩 ROG 在微博最近釋出的預告,可以看到採用新設計「即將升級」的 ROG Phone(可能是 ROG Phone 4 但也有消息指出會跳版號到 ROG Phone 5)即將來襲。繼續閱讀次世代 ROG Phone 騰訊搶先預告登場!傳將升級65W 快充應援你的電競行動生活報導內文。

次世代 ROG Phone 騰訊搶先預告登場!傳升級 65W 快充應援你的電競行動生活

身為電競手機概念的先驅者,ROG 絕對可以被算上一角。現在,他們的旗艦電競手機 ROG Phone 的戰力升級版,也確認將在與騰訊繼續合作之下推出 — 儘管,由內部型號 I003D 跳至 I005DA 的新款 ROG 電競手機,是否會跳號成為 ROG Phone 5 仍是個謎(還是會一次推兩款?)。
根據官方在社群平台的預告圖片,有著明顯可見的銀河星座背景,被許多人推測可能最快將會在 3 月推出。而從手機螢幕刻意在底端「留黑」的圖片也可以斷言,新世代 ROG 電競手機可能將不再延續上下螢幕邊框比例對稱的設計語言,在頂端與左右三邊都將迎接盡可能薄到視覺難以察覺的超薄邊框。

這樣一張簡單的預告圖片,似乎可預期 ROG Phone 將迎接手機內外的全面硬體大改 — 所以老配件可能… 至於前置鏡頭何去何從,這好像對華碩來講也不是問題?(ZenFone 7 Pro 表示:)但就目前流傳的實機照看來,背面很可能與 ROG Phone 3 相比沒有太多的變動,但疑似多了個疑似為遊戲專用的按鈕;側面的充電孔應該依然有保留 。至於「05」的編號,看來也就是會直接跳號了?

▲圖片來源:WHYLAB(微博)

是說,先前已有強大跑分數字流出,以電競遊戲高效能而生做為最主要特色的 ROG Phone,一直以來都提供了許多超前業界的規格。但顯然對使用者而言,仍有著更完美規格方面的期待 — 像是快充規格方面,根據最近的傳言則是指出將從先前的 30W 一舉提升至 65W;電量部分更可能直衝 6,000mAh,應該會是更符合使用者需求的提升。

看來在更多配件曝光之前,已經可以預期 ROG Phone 4 / ROG Phone 5 將「升級」成更完美電競手機了?

▲圖片來源:PhoneArena

本篇圖片 / 引用來源

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

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

延伸閱讀:

中國電動車全面跟上 1,000 公里續航?專家:不可能「全都好」

不只潮更厲害!AirPods Max 開箱使用體驗(同場加映:全色系動眼看!)

您也許會喜歡:

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

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

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

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

[C#.NET 拾遺補漏]01:字符串操作_網頁設計公司

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

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

字符串操作在任意編程語言的日常編程中都隨處可見,今天來匯總一下 C# 中關於字符串的一些你可能遺忘或遺漏的知識點。

逐字字符串

在普通字符串中,反斜杠字符是轉義字符。而在逐字字符串(Verbatim Strings)中,字符將被編程器按照原義進行解釋。使用逐字字符串只需在字符串前面加上 @ 符號。

// 逐字字符串:轉義符
var filename = @"c:\temp\newfile.txt";
Console.WriteLine(filenaame);

// 逐字字符串:多行文本
var multiLine = @"This is a
multiline paragraph."
;
Console.WriteLine(multiLine);

// 非逐字字符串
var escapedFilename = "c:\temp\newfile.txt";
Console.WriteLine(escapedFilename);

輸出:

c:\temp\newfile.txt
This is a
multiline paragraph.
c: emp
ewfile.txt

逐字字符串中唯一不被原樣解釋的字符是雙引號。由於雙引號是定義字符串的關鍵字符,所以在逐字字符串中要表達雙引號需要用雙引號進行轉義。

varstr = @"""I don't think so"", he said.";
Console.WriteLine(str);
// 輸出:"I don't think so", he said.

在逐字字符串中也可以 $ 符號實現字符串內插值。

Console.WriteLine($@"Testing \n 1 2 {5 - 2}");
// 輸出:Testing \n 1 2 3

数字格式化轉換

典型的的格式化方法為:

string.Format("{index[:format]}", number)

可使用“0”和“#”佔位符進行補位。“0” 表示位數不夠位數就補充“0”,小數部分如果位數多了則會四舍五入;“#”表示佔位,用於輔助“0”進行補位。

標準格式化用法:

// “0”描述:佔位符,如果可能,填充位
string.Format("{0:000000}",1234); // 結果:001234

// “#”描述:佔位符,如果可能,填充位
string.Format("{0:######}",1234); // 結果:1234
string.Format("{0:#0####}",1234); // 結果:01234
string.Format("{0:0#0####}",1234); // 結果:0001234

// "."描述:小數點
string.Format("{0:000.000}", 1234); // 結果:1234.000
string.Format("{0:000.000}", 4321.12543); // 結果:4321.125

// ","描述:千分表示
string.Format("{0:0,0}", 1234567); //結果:1,234,567

// "%"描述:格式化為百分數
string.Format("{0:0%}",1234); // 結果:123400%
string.Format("{0:#%}", 1234.125); // 結果:123413%
string.Format("{0:0.00%}",1234); // 結果:123400.00%
string.Format("{0:#.00%}",1234.125); // 結果:123412.50%

內置快捷字母格式化用法:

// E-科學計數法表示
(25000).ToString("E"); // 結果:2.500000E+004

// C-貨幣表示,帶有逗號分隔符,默認小數點后保留兩位,四舍五入
(2.5).ToString("C"); // 結果:¥2.50

// D[length]-十進制數
(25).ToString("D5"); // 結果:00025

// F[precision]-浮點數,保留小數位數(四舍五入)
(25).ToString("F2"); // 結果:25.00

// G[digits]-常規,保留指定位數的有效数字,四舍五入
(2.52).ToString("G2"); // 結果:2.5

// N-帶有逗號分隔符,默認小數點后保留兩位,四舍五入
(2500000).ToString("N"); // 結果:2,500,000.00

// X-十六進制,非整型將產生格式異常
(255).ToString("X"); // 結果:FF

ToString 也可以自定義補零格式化:

(15).ToString("000");              // 結果:015
(15).ToString("value is 0"); // 結果:value is 15
(10.456).ToString("0.00"); // 結果:10.46
(10.456).ToString("00"); // 結果:10
(10.456).ToString("value is 0.0"); // 結果:value is 10.5

轉換為二進制、八進制、十六進制輸出:

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

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

int number = 15;
Convert.ToString(number, 2); // 結果:1111
Convert.ToString(number, 8); // 結果:17
Convert.ToString(number, 16); // 結果:f

自定義格式化器:

public class CustomFormat : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (!this.Equals(formatProvider))
{
return null;
}
if (format == "Reverse")
{
return string.Join("", arg.ToString().Reverse());
}
return arg.ToString();
}

public object GetFormat(Type formatType)
{
return formatType == typeof(ICustomFormatter) ? this : null;
}
}

使用自定義格式化器:

String.Format(newCustomFormat(), "-> {0:Reverse} <-", "Hello World");
// 輸出:-> dlroW olleH <-

字符串拼接

將數組中的字符串拼接成一個字符串:

var parts = new[] { "Foo", "Bar", "Fizz", "Buzz"};
var joined = string.Join(", ", parts);
// joined = "Foo, Bar, Fizz, Buzz"

以下四種方式都可以達到相同的字符串拼接的目的:

string first = "Hello";
string second = "World";
string foo = first + " " + second;
string foo = string.Concat(first, " ", second);
string foo = string.Format("{0} {1}", firstname, lastname);
string foo = $"{firstname} {lastname}";

字符串內插法

簡單用法:

var name = "World";
var str =$"Hello, {name}!";
// str = "Hello, World!"

帶日期格式化:

var date = DateTime.Now;
var str = $"Today is {date:yyyy-MM-dd}!";

補齊格式化(Padding):

var number = 42;

// 向左補齊
var str = $"The answer to life, the universe and everything is {number, 5}.";
// str = "The answer to life, the universe and everything is ___42." ('_'表示空格)

// 向右補齊
var str = $"The answer to life, the universe and everything is ${number, -5}.";
// str = "The answer to life, the universe and everything is 42___."

結合內置快捷字母格式化:

var amount = 2.5;
var str = $"It costs {amount:C}";
// str = "¥2.50"

var number = 42;
var str = $"The answer to life, the universe and everything is {number, 5:f1}.";
// str = "The answer to life, the universe and everything is ___42.1"

參考:

1.《C# 7.0 in a Nutshell》

2. https://bit.ly/2U1eIK9

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

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

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

Nvidia 悄悄放寬 G-Sync Ultimate 認證的標準,高亮度不再是必要條件_如何寫文案

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

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

在 2013 年時,Nvidia 推出了新的同步技術 G-Sync,確保顯示器畫面更新與顯示卡處理保持同步,從而避免影像撕裂、卡頓等現象,進而提升用戶接受到的影像品質,顯示器上必須搭載專用的 G-Sync 硬體模組來達成這個目標。在此 2 年之後,AMD 推出了自家的 FreeSync 同步,採開放式設計且不需要專用的硬體,顯示效果也不錯,很快就蔚為風潮,並且被納入了 VESA 適應性同步標準之中。

Nvidia 悄悄放寬 G-Sync Ultimate 認證的標準,高亮度不再是必要條件

隨著 AMD 的進展,Nvidia 也逐步開放了三種不同等級的 G-Sync,分別為不需要加裝專用硬體模組的 G-Sync Compatible,需加裝硬體模組的 G-Sync,以及除需安裝硬體模組還額外支援最高解析度與更新率、超低延遲、多區背光、廣色域且亮度不低於 1000nits(HDR 1000 認證)的 G-Sync Ultimate。近日,Nvidia 將 Asus PG32UQX、LG 34GP950G 與微星 MEG381CQR 納入 G-Sync Ultimate 列表中,但除了第一款螢幕可達到 1400nits 外,後兩款在亮度方面卻僅通過 HDR 600 的認證,實際上並不能滿足 G-Sync Ultimate 的條件。

從 Nvidia 官網上所看到的最新資訊,可以發現關於 G-Sync Ultimate 有關於亮度高於 1000nits 的要求已經悄悄被刪除,也不再提到高亮度的好處,也就是說未來對製造商來說,要想拿到最高等級的 G-Sync Ultimate 認證,相對更為容易與簡單。

不過從消費者角度來看,雖然市面上標榜通過 G-Sync Ultimate 認證的選項會變多,但也表示其他規格方面的落差也會變大,容易引起混亂,在選購時更得睜大眼睛,避免被認證標章的話術所迷惑。

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

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

◎資料來源:PC Gamer、Tom’s Hardware

您也許會喜歡:

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

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

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

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