什么是m叉樹_不懂數據庫索引的底層原理?那是因為你心里沒點b樹

38722fe421df0b2949288d8768175c79.png

前幾天下班回到家后正在處理一個白天沒解決的bug,廁所突然傳來對象的聲音:
對象:xx,你有《時間簡史》嗎?
我:我去!妹子,你這啥癖好啊,我有時間也不會去撿屎啊!
對象:...人家說的是霍金的科普著作《時間簡史》,是一本書啦!
我:哦,那我沒有...
對象:人家想看誒,你明天幫我去圖書館借一本吧...
我:我明天還要改...
對象:你是不是不愛我了,分手!
我:我一大早就去~

第二天一大早我就到了圖書館,剛進門就看到一個索引牌,標識著不同樓層的功能,這樣我很快能定位到我要找的目標所在的樓層了。

04f4f7c8e9c4b18fc9dd62bfe72778fd.png

我到樓上后又看到每排的書架上又對書的分類進行了細分,這樣我能更快的定位到我要找的書具體在哪個書架!

并且每個樓層都有一臺查詢終端,輸入書名就能查到對應的唯一標識“索書號”,類似于P159-49/164這樣的一個編碼,書架上的書都是按照這個編碼進行排序的!有了這個編碼再去對應的書架上,很快就能找到對應的書在書架的具體位置了。

45134da77951f86197c6a396403c8fdf.png

不到十分鐘,我就從圖書館借好書出來了。

這么大的圖書館,我為什么能在這么短的時間內找到我要的書?如果這些書是雜亂無章的堆放,或者沒有任何標識的放在書架,我還能這么快的找到嗎?

這不禁讓我想到了我們開發中用到的數據庫,圖書館的書就類似我們數據表中的數據,樓層索引牌、書架分類標識、索書號就類似我們查找數據的索引。

那我們常用的數據庫的索引底層的一個數據結構是什么樣的呢?想到這里我又回到圖書館借了一本《數據庫從入門到放棄》!

要了解數據庫索引的底層原理,我們就得先了解一種叫樹的數據結構,而樹中很經典的一種數據結構就是二叉樹!所以下面我們就從二叉樹到平衡二叉樹,再到B-樹,最后到B+樹來一步一步了解數據庫索引底層的原理!

二叉樹(Binary Search Trees)

二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用于實現二叉查找樹和二叉堆。二叉樹有如下特性:

1、每個結點都包含一個元素以及n個子樹,這里0≤n≤2。
2、左子樹和右子樹是有順序的,次序不能任意顛倒。左子樹的值要小于父結點,右子樹的值要大于父結點。

光看概念有點枯燥,假設我們現在有這樣一組數[35 27 48 12 29 38 55],順序的插入到一個數的結構中,步驟如下:

5a283cc23c6f98fdb361659beb617458.png

3e875c1fa3e716e5f7d0c68890d58653.png

af193ff67dc2cbe23bdbaf4aed636b36.png

cd8fa230e0569464d7181f375f5086a9.png

d2daef2dac422f76453ac8806ed15fe0.png

60dc6c367c1dee26c50d5b614c3f7f7f.png

ceb7d943a28c17211df3196cc1279e56.png

好了,這就是一棵二叉樹啦!我們能看到,經通過一系列的插入操作之后,原本無序的一組數已經變成一個有序的結構了,并且這個樹滿足了上面提到的兩個二叉樹的特性!

但是如果同樣是上面那一組數,我們自己升序排列后再插入,也就是說按照[12 27 29 35 38 48 55]的順序插入,會怎么樣呢?

179924cb5605509b3c5a227704ac5bbe.png

由于是升序插入,新插入的數據總是比已存在的結點數據都要大,所以每次都會往結點的右邊插入,最終導致這棵樹嚴重偏科!!!上圖就是最壞的情況,也就是一棵樹退化為一個線性鏈表了,這樣查找效率自然就低了,完全沒有發揮樹的優勢了呢!
為了較大發揮二叉樹的查找效率,讓二叉樹不再偏科,保持各科平衡,所以有了平衡二叉樹!

平衡二叉樹 (AVL Trees)

平衡二叉樹是一種特殊的二叉樹,所以他也滿足前面說到的二叉樹的兩個特性,同時還有一個特性:

它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。

大家也看到了前面[35 27 48 12 29 38 55]插入完成后的圖,其實就已經是一顆平衡二叉樹啦。

那如果按照[12 27 29 35 38 48 55]的順序插入一顆平衡二叉樹,會怎么樣呢?我們看看插入以及平衡的過程:

283bc1b3d0b5793422894c94f6389b3d.png

f1df28f0ce14050a0fbf82e15bf4fcbd.png

82b5ecc13fccc7429d769fa9f33f212e.png

35bab6531c953187f8eb27a9a8403263.png

8acec0107240a78d599f51baab690a02.png

0db95069b202eaa5b405cfe3d5effeed.png

a5201c8a7e85011fd70d0be4f2c149f8.png

這棵樹始終滿足平衡二叉樹的幾個特性而保持平衡!這樣我們的樹也不會退化為線性鏈表了!我們需要查找一個數的時候就能沿著樹根一直往下找,這樣的查找效率和二分法查找是一樣的呢!

一顆平衡二叉樹能容納多少的結點呢?這跟樹的高度是有關系的,假設樹的高度為h,那每一層最多容納的結點數量為2^(n-1),整棵樹最多容納節點數為2^0+2^1+2^2+...+2^(h-1)。這樣計算,100w數據樹的高度大概在20左右,那也就是說從有著100w條數據的平衡二叉樹中找一個數據,最壞的情況下需要20次查找。如果是內存操作,效率也是很高的!但是我們數據庫中的數據基本都是放在磁盤中的,每讀取一個二叉樹的結點就是一次磁盤IO,這樣我們找一條數據如果要經過20次磁盤的IO?那性能就成了一個很大的問題了!那我們是不是可以把這棵樹壓縮一下,讓每一層能夠容納更多的節點呢?雖然我矮,但是我胖啊...

B-Tree

這顆矮胖的樹就是B-Tree,注意中間是杠精的杠而不是減,所以也不要讀成B減Tree了~

那B-Tree有哪些特性呢?一棵m階的B-Tree有如下特性:

1、每個結點最多m個子結點。
2、除了根結點和葉子結點外,每個結點最少有m/2(向上取整)個子結點。
3、如果根結點不是葉子結點,那根結點至少包含兩個子結點。
4、所有的葉子結點都位于同一層。
5、每個結點都包含k個元素(關鍵字),這里m/2≤k<m,這里m/2向下取整。
6、每個節點中的元素(關鍵字)從小到大排列。
7、每個元素(關鍵字)字左結點的值,都小于或等于該元素(關鍵字)。右結點的值都大于或等于該元素(關鍵字)。

是不是感覺跟丈母娘張口問你要彩禮一樣,列一堆的條件,而且每一條都讓你很懵逼!下面我們以一個[0,1,2,3,4,5,6,7]的數組插入一顆3階的B-Tree為例,將所有的條件都串起來,你就明白了!

b159c752b86c566343d0517eadc118dc.png

d896d5a7bd17337e7f1b5cc21be028c6.png

8984ce335ef22ae432950741362379bc.png

d4df6afc6e59ab6574d60c9317408983.png

e5f7afa8946f5402ee0a672c1e1f498f.png

0af1a1876dfbcc83608c4fb862f3ba6a.png

5f1f64c311edc20111a4b6d0a5ec4114.png

那么,你是否對B-Tree的幾點特性都清晰了呢?在二叉樹中,每個結點只有一個元素。但是在B-Tree中,每個結點都可能包含多個元素,并且非葉子結點在元素的左右都有指向子結點的指針。

如果需要查找一個元素,那流程是怎么樣的呢?我們看下圖,如果我們要在下面的B-Tree中找到關鍵字24,那流程如下:

bf4992ce8ecaf8334cd4edfc23a492b5.png

bc1985a9633da68e3ced774eec0cbd43.png

a3a92a8bfdad64fe50cda69e86b5ddaa.png

223a8a5bc87cdbb2e341a312ea77966a.png

從這個流程我們能看出,B-Tree的查詢效率好像也并不比平衡二叉樹高。但是查詢所經過的結點數量要少很多,也就意味著要少很多次的磁盤IO,這對
性能的提升是很大的。

前面對B-Tree操作的圖我們能看出來,元素就是類似1、2、3這樣的數值,但是數據庫的數據都是一條條的數據,如果某個數據庫以B-Tree的數據結構存儲數據,那數據怎么存放的呢?我們看下一張圖:

2971e4f5f879f2148e202aeac2ce9143.png

普通的B-Tree的結點中,元素就是一個個的數字。但是上圖中,我們把元素部分拆分成了key-data的形式,key就是數據的主鍵,data就是具體的數據。這樣我們在找一條數的時候,就沿著根結點往下找就ok了,效率是比較高的。

B+Tree

B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構。B+Tree與B-Tree的結構很像,但是也有幾個自己的特性:

1、所有的非葉子節點只存儲關鍵字信息。
2、所有衛星數據(具體數據)都存在葉子結點中。
3、所有的葉子結點中包含了全部元素的信息。
4、所有葉子節點之間都有一個鏈指針。

如果上面B-Tree的圖變成B+Tree,那應該如下:

f02b5e9748eb8e240350b5895cb99059.png

大家仔細對比于B-Tree的圖能發現什么不同?
1、非葉子結點上已經只有key信息了,滿足上面第1點特性!
2、所有葉子結點下面都有一個data區域,滿足上面第2點特性!
3、非葉子結點的數據在葉子結點上都能找到,如根結點的元素4、8在最底層的葉子結點上也能找到,滿足上面第3點特性!
4、注意圖中葉子結點之間的箭頭,滿足滿足上面第4點特性!

B-Tree or B+Tree?

在講這兩種數據結構在數據庫中的選擇之前,我們還需要了解的一個知識點是操作系統從磁盤讀取數據到內存是以磁盤塊(block)為基本單位的,位于同一個磁盤塊中的數據會被一次性讀取出來,而不是需要什么取什么。即使只需要一個字節,磁盤也會從這個位置開始,順序向后讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理: 當一個數據被用到時,其附近的數據也通常會馬上被使用。
預讀的長度一般為頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操作系統往往將主存和磁盤存儲區分割為連續的大小相等的塊,每個存儲塊稱為一頁(在許多操作系統中,頁得大小通常為4k)。

B-Tree和B+Tree該如何選擇呢?都有哪些優劣呢?
1、B-Tree因為非葉子結點也保存具體數據,所以在查找某個關鍵字的時候找到即可返回。而B+Tree所有的數據都在葉子結點,每次查找都得到葉子結點。所以在同樣高度的B-Tree和B+Tree中,B-Tree查找某個關鍵字的效率更高。
2、由于B+Tree所有的數據都在葉子結點,并且結點之間有指針連接,在找大于某個關鍵字或者小于某個關鍵字的數據的時候,B+Tree只需要找到該關鍵字然后沿著鏈表遍歷就可以了,而B-Tree還需要遍歷該關鍵字結點的根結點去搜索。
3、由于B-Tree的每個結點(這里的結點可以理解為一個數據頁)都存儲主鍵+實際數據,而B+Tree非葉子結點只存儲關鍵字信息,而每個頁的大小有限是有限的,所以同一頁能存儲的B-Tree的數據會比B+Tree存儲的更少。這樣同樣總量的數據,B-Tree的深度會更大,增大查詢時的磁盤I/O次數,進而影響查詢效率。
鑒于以上的比較,所以在常用的關系型數據庫中,都是選擇B+Tree的數據結構來存儲數據!下面我們以mysql的innodb存儲引擎為例講解,其他類似sqlserver、oracle的原理類似!

innodb引擎數據存儲

在InnoDB存儲引擎中,也有頁的概念,默認每個頁的大小為16K,也就是每次讀取數據時都是讀取4*4k的大小!假設我們現在有一個用戶表,我們往里面寫數據

e430b030ce6c2c0b0a5b2d2d665fad05.png

這里需要注意的一點是,在某個頁內插入新行時,為了不減少數據的移動,通常是插入到當前行的后面或者是已刪除行留下來的空間,所以在某一個頁內的數據并不是完全有序的(后面頁結構部分有細講),但是為了為了數據訪問順序性,在每個記錄中都有一個指向下一條記錄的指針,以此構成了一條單向有序鏈表,不過在這里為了方便演示我是按順序排列的!

由于數據還比較少,一個頁就能容下,所以只有一個根結點,主鍵和數據也都是保存在根結點(左邊的數字代表主鍵,右邊名字、性別代表具體的數據)。假設我們寫入10條數據之后,Page1滿了,再寫入新的數據會怎么存放呢?我們繼續看下圖:

6dab1d0ce42fb71dd410c2ee02405c28.png

有個叫“秦壽生”的朋友來了,但是Page1已經放不下數據了,這時候就需要進行頁分裂,產生一個新的Page。在innodb中的流程是怎么樣的呢?

1、產生新的Page2,然后將Page1的內容復制到Page2。
2、產生新的Page3,“秦壽生”的數據放入Page3。
3、原來的Page1依然作為根結點,但是變成了一個不存放數據只存放索引的頁,并且有兩個子結點Page2、Page3。

這里有兩個問題需要注意的是
1、為什么要復制Page1為Page2而不是創建一個新的頁作為根結點,這樣就少了一步復制的開銷了?
如果是重新創建根結點,那根結點存儲的物理地址可能經常會變,不利于查找。并且在innodb中根結點是會預讀到內存中的,所以結點的物理地址固定會比較好!

2、原來Page1有10條數據,在插入第11條數據的時候進行裂變,根據前面對B-Tree、B+Tree特性的了解,那這至少是一顆11階的樹,裂變之后每個結點的元素至少為11/2=5個,那是不是應該頁裂變之后主鍵1-5的數據還是在原來的頁,主鍵6-11的數據會放到新的頁,根結點存放主鍵6?
如果是這樣的話新的頁空間利用率只有50%,并且會導致更為頻繁的頁分裂。所以innodb對這一點做了優化,新的數據放入新創建的頁,不移動原有頁面的任何記錄。

隨著數據的不斷寫入,這棵樹也逐漸枝繁葉茂,如下圖:

ecf4744530f18339d35ee15f77558ca8.png

每次新增數據,都是將一個頁寫滿,然后新創建一個頁繼續寫,這里其實是有個隱含條件的,那就是主鍵自增!主鍵自增寫入時新插入的數據不會影響到原有頁,插入效率高!且頁的利用率高!但是如果主鍵是無序的或者隨機的,那每次的插入可能會導致原有頁頻繁的分裂,影響插入效率!降低頁的利用率!這也是為什么在innodb中建議設置主鍵自增的原因!

這棵樹的非葉子結點上存的都是主鍵,那如果一個表沒有主鍵會怎么樣?在innodb中,如果一個表沒有主鍵,那默認會找建了唯一索引的列,如果也沒有,則會生成一個隱形的字段作為主鍵!

有數據插入那就有刪除,如果這個用戶表頻繁的插入和刪除,那會導致數據頁產生碎片,頁的空間利用率低,還會導致樹變的“虛高”,降低查詢效率!這可以通過索引重建來消除碎片提高查詢效率!

innodb引擎數據查找

數據插入了怎么查找呢?

1、找到數據所在的頁。這個查找過程就跟前面說到的B+Tree的搜索過程是一樣的,從根結點開始查找一直到葉子結點。
2、在頁內找具體的數據。讀取第1步找到的葉子結點數據到內存中,然后通過分塊查找的方法找到具體的數據。

這跟我們在新華字典中找某個漢字是一樣的,先通過字典的索引定位到該漢字拼音所在的頁,然后到指定的頁找到具體的漢字。innodb中定位到頁后用了哪種策略快速查找某個主鍵呢?這我們就需要從頁結構開始了解。

27eebf25abdefe236d390621acac2fa8.png

左邊藍色區域稱為Page Directory,這塊區域由多個slot組成,是一個稀疏索引結構,即一個槽中可能屬于多個記錄,最少屬于4條記錄,最多屬于8條記錄。槽內的數據是有序存放的,所以當我們尋找一條數據的時候可以先在槽中通過二分法查找到一個大致的位置。

右邊區域為數據區域,每一個數據頁中都包含多條行數據。注意看圖中最上面和最下面的兩條特殊的行記錄Infimum和Supremum,這是兩個虛擬的行記錄。在沒有其他用戶數據的時候Infimum的下一條記錄的指針指向Supremum,當有用戶數據的時候,Infimum的下一條記錄的指針指向當前頁中最小的用戶記錄,當前頁中最大的用戶記錄的下一條記錄的指針指向Supremum,至此整個頁內的所有行記錄形成一個單向鏈表。

行記錄被Page Directory邏輯的分成了多個塊,塊與塊之間是有序的,也就是說“4”這個槽指向的數據塊內最大的行記錄的主鍵都要比“8”這個槽指向的數據塊內最小的行記錄的主鍵要小。但是塊內部的行記錄不一定有序。

每個行記錄的都有一個n_owned的區域(圖中粉紅色區域),n_owned標識這個這個塊有多少條數據,偽記錄Infimum的n_owned值總是1,記錄Supremum的n_owned的取值范圍為[1,8],其他用戶記錄n_owned的取值范圍[4,8],并且只有每個塊中最大的那條記錄的n_owned才會有值,其他的用戶記錄的n_owned為0。

所以當我們要找主鍵為6的記錄時,先通過二分法稀疏索引中找到對應的槽,也就是Page Directory中“8”這個槽,“8”這個槽指向的是該數據塊中最大的記錄,而數據是單向鏈表結構所以無法逆向查找,所以需要找到上一個槽即“4”這個槽,然后通過“4”這個槽中最大的用戶記錄的指針沿著鏈表順序查找到目標記錄。

聚集索引&非聚集索引

前面關于數據存儲的都是演示的聚集索引的實現,如果上面的用戶表需要以“用戶名字”建立一個非聚集索引,是怎么實現的呢?我們看下圖:

4ee8c5a2e010295b945d4f9a245891af.png

非聚集索引的存儲結構與前面是一樣的,不同的是在葉子結點的數據部分存的不再是具體的數據,而數據的聚集索引的key。所以通過非聚集索引查找的過程是先找到該索引key對應的聚集索引的key,然后再拿聚集索引的key到主鍵索引樹上查找對應的數據,這個過程稱為回表

圖中的這些名字均來源于網絡,希望沒有誤傷正在看這篇文章的你~^_^

innodb與MyISAM兩種存儲引擎對比

上面包括存儲和搜索都是拿的innodb引擎為例,那MyISAM與innodb在存儲上有啥不同呢?憋縮話,看圖:

93c5fcd40a0a3f94c9f2f57547ba1b07.png

上圖為MyISAM主鍵索引的存儲結構,我們能看到的不同是

1、主鍵索引樹的葉子結點的數據區域沒有存放實際的數據,存放的是數據記錄的地址。
2、數據的存儲不是按主鍵順序存放的,按寫入的順序存放。

也就是說innodb引擎數據在物理上是按主鍵順序存放,而MyISAM引擎數據在物理上按插入的順序存放。并且MyISAM的葉子結點不存放數據,所以非聚集索引的存儲結構與聚集索引類似,在使用非聚集索引查找數據的時候通過非聚集索引樹就能直接找到數據的地址了,不需要回表,這比innodb的搜索效率會更高呢!

索引優化建議?

大家經常會在很多的文章或書中能看到一些索引的使用建議,比如說

1、like的模糊查詢以%開頭,會導致索引失效。
2、一個表建的索引盡量不要超過5個。
3、盡量使用覆蓋索引。
4、盡量不要在重復數據多的列上建索引。
5、。。。。。。。。。。。
6、。。。。。。。。。。。

很多這里就不一一列舉了!那看完這篇文章,我們能否帶著疑問去分析一下為什么要有這些建議?為什么like的模糊查詢以%開頭,會導致索引失效?為什么一個表建的索引盡量不要超過5個?為什么? 為什么??為什么???相信看到這里的你再加上自己的一些思考應該有答案了吧?


原文鏈接:不懂數據庫索引的底層原理?那是因為你心里沒點b樹 - 蘇蘇喂 - 博客園

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271691.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271691.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271691.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

可重入鎖是什么和demo

可重入鎖 reentrantlock是獨占鎖且可重入的 synchronized 也可以重入 可重入意思就是這個線程已經獲取鎖了&#xff0c;你再獲取該鎖還能獲取 獲取的還是原來的鎖 不會出現問題 可以降低編程難度 代碼如下: new Thread(new Runnable() {Overridepublic void run() {synchr…

linux 安裝python 3.x,Linux 安裝python3.x步驟

本文轉發自博客園非真的文章&#xff0c;內容略有改動linux系統本身默認安裝有2.x版本的python&#xff0c;版本x根據不同版本系統有所不同&#xff0c;通過python --V 或 python --version 查看系統自帶的python版本。有一些系統命令時需要用到python2&#xff0c;不能卸載&am…

數據庫:SQLServer中游標的用法筆記

一、游標的概念知識游標可以理解為SQL Server的一種數據訪問機制&#xff0c;它允許用戶訪問數據的維度是數據行。用戶可以對每一行數據進行單獨處理&#xff0c;從而降低系統開銷和潛在的阻隔情況&#xff0c;游標主要用于存儲過程&#xff0c;觸發器和 T_SQL復雜的腳本中&…

BZOJ_1009_[HNOI2008]_GT考試_(動態規劃+kmp+矩陣乘法優化+快速冪)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id1009 字符串全部由0~9組成,給出一個串s,求一個長度為n的串,不包含s的種類有多少. 分析 第一眼以為是組合.然后更滑稽的是用錯誤的方法手算樣例居然算出來是對的...我數學是有多差... 題解也是看了好半天,有點難理解. 感覺…

智慧政務解決方案(28頁)pdf_【金眾電子】智慧政務解決方案

智慧政務解決方案立式黨建廣告機廣告機簡介&#xff1a;KC-立式政務廣告機(室內/室外可選)液晶屏幕特別賣點&#xff1a;安裝簡易、亮度調節、實時更新、傳輸安全應用場所&#xff1a;各種需要文化傳播的政務機構、政府機關、會議場所等。雙立柱政務文化欄/宣傳欄文化欄簡介&am…

笨辦法學linux dhcp,了解網關、DNS、子網掩碼、MAC地址、DHCP

原標題&#xff1a;了解網關、DNS、子網掩碼、MAC地址、DHCP什么是網關、DNS、子網掩碼&#xff0c;它有什么作用&#xff0c;確實&#xff0c;我們平時在網絡中總是在不斷的提到網關&#xff0c;卻很少真正的去了解它。一、什么是網關1、什么是網關網關是一種充當轉換重任的計…

數據庫:SQLServer Stuff 函數用法筆記

今天小編給大家分享一下自己整理一下SQLServer Stuff函數用法技巧和常用示例&#xff0c;有需要的朋友可以學習一下。一、Stuff函數的作用1.1官方解釋STUFF 函數將字符串插入到另一個字符串中。 它從第一個字符串的開始位置刪除指定長度的字符&#xff1b;然后將第二個字符串插…

自定義注解,aop實現注解鎖

多線程環境下&#xff0c;會出現線程不安全的問題&#xff0c;所以要對某些方法加鎖以保證線程安全 但是如果方法過多&#xff0c;每個方法前后都加這么一句&#xff0c;有點麻煩了&#xff0c;而且代碼可讀性也會差一些。可以使用aop切面編程&#xff0c;對某些加有特定注解&…

Android——實現歡迎界面的自動跳轉(轉)

Android實現歡迎界面的自動跳轉&#xff0c;就是打開某一個安卓手機應用&#xff0c;出現的歡迎界面停留幾秒鐘&#xff0c;自動進入應用程序的主界面。在網上看到很多種實現辦法&#xff0c;但是感覺這種方法還是比較簡單的。 在onCreate里設置個Timer&#xff0c;然后建立Int…

手機端刷recovery工具_MIUI/REDMIN手機玩機匯集

愿你刷機半生歸來仍是MIUI1解鎖篇解鎖Bootloader準備工作&#xff1a;1.手機備份數據2.手機進入開發者模式①進入“設置 -> 我的設備 -> 全部參數"中連續點擊MIUI版本&#xff0c;進入”開發者模式“②進入“設置 -> 開發者選項 -> 設備解鎖狀態”中綁定賬號和…

數據結構基礎:線性表學習筆記

1、線性表定義線性表是指n個元素的有限序列(n>0),通常用(a1,a2,a3...,an),來表示。2、線性表特點1、存在唯一的一個首元素2、存在唯一一個尾元素3、除第首元素外&#xff0c;每個元素只有一個直接前驅。4、除尾元素外&#xff0c;每個元素只有一個直接后繼。3、線性表的存儲…

c語言流水燈小程序,流水燈小程序.doc

流水燈小程序流水燈小程序#include void delay() //延時函數&#xff0c;這里延時100ms{int i,j;for(i0;i<100;i){for(j0;j<2242;j){} //j循環一次大概1ms}}void main(){ //這里看LED原理圖LPC_IOCON->JTAG_TMS_PIO1_00x01;//定義p1.0引腳為輸出LPC_IOCON->JTAG_TD…

iphone導出照片到電腦_iPhone里的照片如何快速導入電腦

前幾日我一好友發微信問我&#xff1a;“向陽&#xff0c;我手機里有一萬多張照片&#xff0c;怎么能快速的備份到電腦里&#xff1f;”我一看這問題&#xff0c;確實很多果友從用蘋果手機開始&#xff0c;機器已經更新換代了好多代了&#xff0c;照片是越來越多&#xff0c;內…

數據結構基礎:棧和隊列學習筆記

1、棧1.1 棧的定義棧是只能通過訪問它的一端來實現數據的存儲和檢索的一種特殊的線性數據結構。棧的修改要遵循先進后出的原則&#xff0c;這個是棧的核心。在棧中進行插入和刪除操作的一端稱為棧頂&#xff08;Top&#xff09;。另一端被稱為棧底&#xff08;bottom&#xff0…

Jquery高級編程

1.javascript具有等于&#xff08;&#xff09;和等同&#xff08;&#xff09;等號操作符是危險的&#xff0c;因為它在執行比較之前&#xff0c;強制執行類型轉換。 2.非侵擾式編程。 3.3.3Jquery的框架結構&#xff0c;待深入理解。 4.選擇器 a.元素選擇器&#xff08;元素屬…

C語言鏈表為什么倒著輸出,關于鏈表倒著存,正著輸出。

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓題目要求是你輸入a->b->c->d&#xff0c;然后存在內存里&#xff0c;然后改變在內存里的存儲&#xff0c;改成存d->c->b->a&#xff0c;然后輸出還是abcd&#xff0c;能不能就是用一個數組也存一份輸入的&#x…

idea @Autowired 注入爆紅(無法注入)

問題如下圖所示,idea Autowired 注入爆紅(無法注入) seettings ----> Editor Inspactions ----->spring ---->spring Core ----> Code ----> Autowring for Bean Class 去掉那個勾 效果如下

華為手機相冊怎么鏡像翻轉_怎么利用手機相冊制作電子視頻

怎么通過手機照片制作視頻&#xff1f;將照片做成視頻并不是很難&#xff0c;可以直接在手機上進行操作&#xff0c;下面來看看是怎么操作的。方法/步驟在手機上打開清爽視頻編輯器&#xff0c;有視頻編輯、美拍美攝、電子相冊、特效模板、動感視頻、創意視頻、動態字幕、視頻變…

Cluster_analysis

https://en.wikipedia.org/wiki/Cluster_analysis轉載于:https://www.cnblogs.com/WCFGROUP/p/5557907.html