主頁 > 軟體設計 > MySQL事務淺析|由淺入深

MySQL事務淺析|由淺入深

2021-02-11 13:02:41 軟體設計

MySQL事務淺析|由淺入深

很多人都在講事務,事務是個啥,我感覺我沒開事物也沒什么事情啊,學事務有必要嗎?

“白嫖表情包”的圖片搜索結果

今天照舊,本文在一開始將講解一些入門適合理解的知識,在后面逐層加深,如果對事務有了解,希望知道細節,可以在下面的目錄跳一下

文章目錄

  • MySQL事務淺析|由淺入深
  • 事務是個啥?
    • For Example1
      • 例子2 臟寫
      • 例子3 臟讀
      • 例子4 不可重復讀
      • 例子5 幻讀
    • 并發編程帶來的資料庫隱患
    • 通過對事務的分析,得到了四個特點 ACID
  • MySQL如何保證事務完好
    • 持久性的保證
    • 原子性的保證
    • 隔離性的保證|MVCC
      • MVCC
        • 沒錯,有個東西叫Undo日志
      • 那么這四級隔離都是如何具體實作的?
      • 什么是ReadView?
      • 修改ReadView就能獲得不同的隔離策略:
    • 防止臟寫 | MySQL讀寫鎖
      • 一致性讀與鎖定讀
      • 共享鎖與獨占鎖
      • 表鎖
  • MySQL的鎖
      • MySQL對自增id的保護

不會吧不會吧,不開事務你們系統還好嗎?

事務是個啥?

相信在做的各位,大部分都是為了吃飯、或者為了遠大崇高的理想而奮斗(摸魚

那么,我們用錢,,,買回來的手辦來舉例,相信各位的體驗將更加深刻,

“初音手辦”的圖片搜索結果

img

For Example1

現有以下場景,你在bilibili(無意打擾,勿殺)中花費了1w元,買下了自己的老婆(不是

注意這個細節:買下,而不是買回

那么分析這個流程,其中有四個模塊

image-20210209205827067

有的杠精就要跳出來,我付款不是一個流程嗎?為啥是個扣款加收到?

這個問題建議你復習一下什么是微信錢包嗷,以及正視b站和tx不是一家公司的問題,

好的,凡是總是怕萬一嘛,快遞還可能被炸毀嘞,

如果你在扣款成功后,啪,很快啊,微信或者bilibili的服務器掛了,

你重新審視這張簡單無比的圖片,發現一個嚴重的問題:

如果沒有其他手段保證的話,bilibili沒收到錢,老婆沒了,

那么請問這個問題,他嚴重嗎,答案肯定是嚴重的,

同時上述的問題是事務持久性的體現,對資料的修改是永久的,即使故障也不會丟失,

下面我將繼續舉出幾個例子,建議看一下,別覺得簡單就跳了,對后面的理解有很大的幫助,

例子2 臟寫

又是你,作為當代光榮程式員,你完成了leader的任務,寫下了五百行代碼,踏上了回家與老婆鼓掌的出租車

但是很不幸,有個憨批張三,

他把你剛剛交上去的代碼改成了一個字符畫豬(* ̄(oo) ̄)

你的五百行代碼不翼而飛,還被換成了豬,

那么請問,如何生吃張三更快人心?

image-20210209211514088

一個事務修改了另一個 未提交的事務 修改過的資料,稱為臟寫

例子3 臟讀

恭喜你,你終于買了1w元的老婆!(高興的拍起肚皮

但是,生活再次對你下手,你買回來的,是個半成品,沒上色啊喂!

“半成品手辦”的圖片搜索結果

一個事物讀取到了 另一個未提交的事務修改過的資料,稱為臟讀

例子4 不可重復讀

一番波折,你終于帶回了自己的老婆(不是,女朋友大大別打我

你看看她的樣子

select * from home where id =1;

image-20210209212958774

很不巧,領居家的熊孩子來家里玩,

“鄰居家的熊孩子”的圖片搜索結果

鄰居走了以后,你又看了看她的樣子

select * from home where id =1;

發現老婆,她,變成了這樣

“托馬斯”的圖片搜索結果

一個事務內兩次讀到的資料不一樣,稱為不可重復讀

換句話說,一個事務提交修改,會影響其他未完成的事務內的資料

又或者說,如果一個事務只能讀到另一個已經提交的事務修改過的資料,并且其他事務每對該資料進行一次修改并提交后,該事務都能查詢得到最新值

例子5 幻讀

你今個又來看自己的老婆

select * from home where id =1;

ans: 初音(韶華)

覺得她很棒♂,于是你放心的去了一趟扯碩,

回來你又來看老婆

select * from home where id =1;

ans: 初音,2233

但是發生了奇怪的事情,老婆多了一個?!

這不是好事情嗎,滑稽?

但是《正 直》的你不這么認為,于是給2233擺正,微笑入睡

讀到了其他事務 增加的記錄,稱為幻讀,(可能這就是幻術吧

并發編程帶來的資料庫隱患

我們使用SQL時,看起來似乎永遠都是單執行緒操作,而實際上資料庫幾乎是并發的一個高峰點,有無數的執行緒同時在這里進行操作,如果對資料的讀寫不能加以限制,那么你將再次痛失老婆(并不

大佬們把資料庫的隱患,歸結到了四種,臟寫,臟讀,不可重復讀與幻讀

這四個概念在上文給大家講了例子,下面簡要總結一下

  1. 臟寫:一個事物寫了另一個未提交事物修改的資料,
  2. 臟讀:一個事物讀到了另一個未提交事物所修改的資料,
  3. 不可重復讀:由于其他事務的操作,一個事務內兩次讀某條資料的結果不同,
  4. 幻讀:由于其他事務的操作,一個事務第二次查詢到了多的資料,

同時把我們的一組邏輯操作稱為事務(比如去銀行取錢,買手辦等等

通過對事務的分析,得到了四個特點 ACID

  • Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節,事務在執行程序中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣,即,事務不可分割、不可約簡,
  • Consistency(一致性):在事務開始之前和事務結束以后,資料庫的完整性沒有被破壞,
  • Isolation(隔離性):資料庫允許多個并發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致資料的不一致,
  • Durability(持久性):事務處理結束后,對資料的修改就是永久的,即便系統故障也不會丟失,

以上來自維基百科,下面是人話版本

  • Atomicity(原子性):這個簡單,你一組操作肯定是要綁在一起的嘛,沒什么說的,要死一起死,
  • Consistency(一致性):真實世界中,資料是有格式的,比如小數位啊,沒有負數啊等等,一致性就是為了保證資料處理前后,都符合特定的要求(主鍵,外鍵,其他約束等等),
  • Isolation(隔離性):學過JUC的老鐵應該懂,當多個執行緒一起操作一個臨界區的時候,沒限制多半要出事,隔離性是為了保證多個事務在執行的時候,能像單執行緒一樣順利,
  • Durability(持久性):事務處理結束后,對資料的修改就是永久的,即便系統故障也不會丟失,(沒什么說的,懂的都懂)

MySQL如何保證事務完好

一致性我們就不多說了,用觸發器,約束這些是很基礎的資料庫操作,

我們的主要關注點放在持久性、原子性和隔離性上,

持久性的保證

持久性:對資料的修改是永久的,即使故障也不會丟失,

MySQL里面有個叫redo的玩意兒

MySQL執行每條更新資料的操作,都會產生一個redo日志(即時的),然后再依次執行redo日志,

為啥?不直接把結果io到庫里,非要搞個redo,裝杯嗎這是?

這里大家需要考慮一個問題:

直接io結果會涉及隨機讀寫,使用redo日志是順序讀寫

MySQL中以典型的innodb為例,使用的是聚簇索引(不懂的可以去搜索一下

img

圖源:從根上理解MySQL

這里的索引部分是一頁,下面的資料又是不同的頁,如果一個操作將更新多個資料,可能將涉及大量的隨機讀寫,我們不可能等這么長時間完成(等一半就暴斃了怎么辦)所以使用了redo日志,后面慢慢寫redo日志就行了嘛,這里的redo日志可能大家沒聽過,不知道binlog這個名字大家熟悉嗎,哈哈哈

資料的修改操作將記錄在binlog,然后將有一個執行緒慢慢寫binlog,(修改會暫時保存在快取中)

原子性的保證

原子性:同生共死,要么都成功,要么都失敗,那么我們需要關注的是,執行到一半,后悔了,我要恢復,怎么辦?

MySQL的方式是使用undo日志

undo日志的原理其實不難,為了知道每一步我們都干了點啥,我們每修改一次資料,就做一次記錄順序讀寫,很快的),要是有問題,就用這些記錄把資料恢復了就行,

下面我們從設計undo日志的角度出發,來理解undo日志

為了記錄一個資料的修改,同時達到順序讀寫的效果,鏈表可能是我們理想的資料結構

image-20210209230513906

日志肯定要分開存盤,不然回滾還要篩選找到日志,很麻煩,那我們直接把undo日志掛在記錄上應該就可以了,

image-20210209230732652

現在我們還有一個因素要考慮:并發,多事務執行,

對于并發問題:我們必須意識到:不能允許多個事務同時修改一個數,這屬于臟寫,所以我們將使用來保證,

那么我們已經使用鎖來保證當前資料只能被一個事務修改,我們下面需要考慮的是修改資料也有很多種類的,洗掉,增加,修改,怎么處理?

加一個標志位標識種類,不同種類有不同的內容,完美

綜合我們可以設計出這樣的結構

因為mysql為了提高讀取速度,在存盤,讀取資料時以頁面(16kb)為單位

同時頁面有多種型別,undo日志和資料頁就是兩種不同的型別頁,

image_1d65h98l3qve1ekb13epv4f37685.png-70.6kB

image_1d658eq7rokf19jffpt20010b63t.png-52.6kB

圖片來源:掘金小冊《MySQL 是怎樣運行的:從根兒上理解 MySQL》

當我們發生情況,要回滾的時候,按照這個日志回滾回去就行了,

但是由于MySQL中,delete行為的不同:

delete并不會洗掉資料,而是在當前事務內,標記這個點被洗掉了(行里面有一個Header標志位),然后在事務結束后放入垃圾鏈表,垃圾鏈表可以快速的被回收利用或在未來釋放空間

如下圖所示

下面是一個正常的表,左邊是正常的記錄,右邊是該表的垃圾鏈表,記錄洗掉的空間,

image-20210210112520491

事務收到請求,把標志位delete_mask置為1

image-20210210112436732

在事務結束后,將該節點加入垃圾鏈表

image-20210210112453879

標志這一步驟看似多此一舉,實際上保證了MVCC,標志記錄是很快的,當其他事務讀取到時,可以感知到該條記錄是否被洗掉,而不是等到結束才感知到,

同時,這些操作在事務內是單向的,日志也是使用鏈表記錄,這樣就構成了版本鏈

img

關于具體的存盤方式啊,回滾段啊就不再贅述了,這部分的內容不是很容易理解

還是很推薦這本書MySQL 是怎樣運行的:從根兒上理解 MySQL,也有紙質書,

隔離性的保證|MVCC

說到隔離性,必須要提一下大家小學三年級就知道的四個隔離級別

一般是大寫的,為了大家英文看的舒服,寫成小寫容易認出來單詞

  1. Read Uncommitted 讀未提交
  2. Read Committed 讀提交
  3. Repeatable Read 可重復讀
  4. Serializable 可串行化

Read Uncommitted 讀未提交,有的地方叫未提交讀,本人覺得讀未提交更符合他描述的情況,因為他描述的是可以讀到未提交的資訊,

這四種級別的隔離程度逐級增加,解決了臟寫,臟讀,不可重復讀,幻讀的問題,

其中臟寫是非常恐怖的,所以MySQL默認是必須解決臟寫的

既然寫到了隔離級別,我們就把他講完,然后說一下臟寫的解決,

隔離級別臟寫臟讀不可重復讀幻讀
READ UNCOMMITTEDNot PossiblePossiblePossiblePossible
READ COMMITTEDNot PossibleNot PossiblePossiblePossible
REPEATABLE READNot PossibleNot PossibleNot PossiblePossible
SERIALIZABLENot PossibleNot PossibleNot PossibleNot Possible

MVCC

首先,預備一下,在MySQL中,一個表除了我們設定的幾個欄位,還存在一些隱含欄位

這里強調一下,Innodb是支持事務的,MyISAM是不支持事務的,

所以MVCC是跟innodb關聯的,

MySQL默認是使用COMPACT行格式的,當然無論什么格式,都會存在隱含列以及Header標志

我們用COMPACT行格式來舉例講解

image_1c9g4t114n0j1gkro2r1h8h1d1t16.png-42.4kB

暫時不關心奇奇怪怪的設定了,之前所提到的delete_mask就在記錄頭中

記錄的真實資料部分包含了三個隱含列

的資料以外,MySQL會為每個記錄默認的添加一些列(也稱為隱藏列),具體的列如下:

列名是否必須占用空間描述
row_id6位元組行ID,唯一標識一條記錄
transaction_id6位元組事務ID
roll_pointer7位元組回滾指標

實際上這幾個列的真正名稱其實是:DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR,我們為了美觀才寫成了row_id、transaction_id和roll_pointer,

其中,row_id 是為了在沒有指定主鍵,且沒有唯一列時作為該條資料主鍵的(主鍵的必要的,否則無法區分資料),若指定了主鍵,他就是空的,

roll_pointer 就是上文我們所提到的記錄指向undo日志的指標,

transaction_id 是最后一個修改該行的事務id,

事務id:為了區分不同的事務,事務也要有個類似主鍵的東西嘛,就是id號,

MySQL內部會維護一個遞增的id號,

MVCC聽起來很高大上,實際上并不復雜,大家先不要關注什么MySQL的具體實作,下面先簡單說一下MVCC是啥,怎么用的,

首先,我們需要明確我們的需求:

不同的事務能看到不同的資料(寫是不允許混用的,用上鎖保證了)

為了達到這個目的,我們可能需要這樣做:給每個執行緒一個快取空間(類似JUC,Java并發中的JMM)

那么問題來了:資料庫很可能是一個系統中并發量最高的地方,大張旗鼓的新開空間,可能造成困難,

如果可以利用一下之前的東西?

沒錯,有個東西叫Undo日志

undo日志里面包含了修改資料的內容對吧,而且為了回滾,都會記錄在哪里,而且還保證了查詢速度,

那么很簡單,既然每個事務都會記錄這個undo日志,我在查詢的時候,只需要看看最后占用這個資料的事務id,是不是比自己小?

事務id是遞增的

如果比自己小,說明這個資料是安全的,可以讀取,否則就在undo日志里面找個合適的出來,

如下圖:

依次從大到小,找到合適的版本就行了(trx_id)

image_1d8po6kgkejilj2g4t3t81evm20.png-81.7kB

MVCC的基礎原理就是這樣,不是很復雜吧,

但是,我們都知道,SQL是規定了幾個隔離級別的,觀察上面的實作,我們發現這個方法是第三級Repeatable Read 可重復讀

在一個事務內,查詢時總跟自己的事務id進行比較

那么這四級隔離都是如何具體實作的?

首先要明確的是,mysql的事務id肯定不是記錄自己的id這么簡單

MySQL是如何記錄當前活躍的事務的?

答:使用ReadView

什么是ReadView?

我們還是按照軟體設計的正常思路:需求-》設計

需求是什么

我們需要在一個合適的時間點,查看自己的事務id與當前所有的事務;因為事務可能很多,最好給一個快速判斷是否為過去事務的方法,

實作

我們設計一個獨特的記錄結構賦予每一個事務

首先需要記錄當前所有的事務

  • m_ids:表示在生成ReadView時當前系統中活躍的讀寫事務的事務id串列,

為了能夠快速的查看目標版本是不是安全的,我們只需要看目標的版本是不是在當前資料庫內的事務區間內,要是不在里面,就直接回傳安全,否則我們就驗證一下是否真的不安全就行了(當前事務內是否包含)

  • min_trx_id:表示在生成ReadView時當前系統中活躍的讀寫事務中最小的事務id,也就是m_ids中的最小值,

  • max_trx_id:表示生成ReadView時系統中應該分配給下一個事務的id值,

    小貼士: 注意max_trx_id并不是m_ids中的最大值,事務id是遞增分配的,比方說現在有id為1,2,3這三個事務,之后id為3的事務提交了,那么一個新的讀事務在生成ReadView時,m_ids就包括1和2,min_trx_id的值就是1,max_trx_id的值就是4,

最后,記錄當前的事務id

  • creator_trx_id:表示生成該ReadView的事務的事務id

    小貼士: 我們前邊說過,只有在對表中的記錄做改動時(執行INSERT、DELETE、UPDATE這些陳述句時)才會為事務分配事務id,否則在一個只讀事務中的事務id值都默認為0,

我們設定每次的查詢都根據ReadView來獲取結果(這是為了解耦,大家可以思考一下,如果只跟ReadView互動,將會很大程度解耦)

被訪問的記錄上有header記錄了最后修改的事務id(trx_id)

在訪問某條記錄時,按照下邊的步驟判斷記錄的某個版本是否可見:

  • 如果被訪問版本的trx_id屬性值與ReadView中的creator_trx_id相同,意味著當前事務在訪問它自己修改過的記錄,所以該版本可以被當前事務訪問,
  • 如果被訪問版本的trx_id屬性值小于 ReadView中的min_trx_id值,表明生成該版本的事務在當前事務生成ReadView前已經提交,所以該版本可以被當前事務訪問,
  • 如果被訪問版本的trx_id屬性值大于或等于 ReadView中的max_trx_id值,表明生成該版本的事務在當前事務生成ReadView后才開啟,所以該版本不可以被當前事務訪問,
  • 如果被訪問版本的trx_id屬性值在ReadViewmin_trx_idmax_trx_id之間,那就需要判斷一下trx_id屬性值是不是在m_ids串列中,如果在,說明創建ReadView時生成該版本的事務還是活躍的,該版本不可以被訪問;如果不在,說明創建ReadView時生成該版本的事務已經被提交,該版本可以被訪問,

未命名繪圖

有點蒙圈

Read View其實實質是當前的事務id

為了快速的判斷,給出了記錄與范圍

試想,目標記錄有個事務id 100,

能訪問的條件:

  • 記錄的事務id是不在當前活躍的事務id中
  • 記錄的事務id已經不活躍小于當前事務id,
    如果命中了,就不能訪問,為了加速,我們直接獲取最大與最小的范圍,在范圍之外我們可以迅速判斷,

修改ReadView就能獲得不同的隔離策略:

  • Read uncommitted:直接讀取最新的記錄
  • Read committed: **每次查詢都生成一個新的ReadView,**這樣,我們的權限范圍就始終是最新的,就能查到最新的資料
  • Repeatable read: 在第一次讀取資料時生成一個ReadView,之后使用這個id,這就保證了我們每次讀取,狀態都是相同的,
  • Serializable:使用鎖保證一個事務訪問,

防止臟寫 | MySQL讀寫鎖

Java程式中,為了保證臨界區的安全,我們經常會提到一個概念,叫鎖,

我們可以這樣理解,東陽市大學有個廁所,經常出現一個人進了一個有人的廁所的尷尬情況,

為了保證男孩子和女孩子們的安全,出現了一個叫信號量的東西,

廁所的門口放了一張卡,只有擁有這張卡,才能進入,使用完后要及時歸還,下個人才能使用,

這就是鎖,不難吧,

回到MySQL的世界,我們的資料在并發狀態一般就這幾種情況:(AA BB AB|BA)

  1. 多個事務一起讀
  2. 多個事務一起寫
  3. 一個事務寫,另一個事務讀

其中存在寫的地方需要我們上鎖來保護資料(懂的人已經發現了這是讀寫鎖)

一致性讀與鎖定讀

MySQL讀取的資料有兩種方式:一致性讀與鎖定讀,他們分別對應著無鎖、與顯式上鎖

一致性讀(Consistent Reads)

一致性讀并不會對表中的任何記錄做加鎖操作,其他事務可以自由的對表中的記錄做改動,一致性讀使用的方式是MVCC

鎖定讀

鎖定讀是類似Java日常開發中對臨界區的保護,必須先上鎖才能訪問資料,

MySQL為了保證多個事務能夠一起讀的同時,寫操作還能鎖死資料,設計出了兩把鎖

共享鎖與獨占鎖

  • 讀操作請求一個共享鎖
  • 寫操作請求一個獨占鎖

當有獨占鎖出現后,共享鎖也將被鎖定

若有共享鎖存在,需要等待解鎖才能申請獨占鎖

我們可以從打掃廁所的角度來理解:(抱歉今個有點重口味

當清潔工打掃時,會等里面的同學出來,然后在門口放上警示(獨占鎖

當無人打掃時,xdm可以一起幸♂福的沖沖沖

這就是共享鎖與讀寫鎖,實質上并不難,他們的原理還是信號量

image_1d9jvmt0n5cl4b71ahh1ki4pjner.png-77.1kB

但是啊,這個時候東陽市大學又整了新操作,他們要修整宿舍樓,修整宿舍樓的時候,也是要限制滴

上述情況中,宿舍樓對應了一張表,廁所對應了一行記錄

于是MySQL就出現了不同粒度的鎖:表鎖

表鎖

MySQL中也有修改表的陳述句,這些陳述句修改的級別是表而不是上文的一行資料,于是表鎖出現了

給表加的鎖也可以分為共享鎖共享鎖)和獨占鎖獨占鎖):

  • 給表加共享鎖

    如果一個事務給表加了共享鎖,那么:

    • 別的事務可以繼續獲得該表的共享鎖
    • 別的事務可以繼續獲得該表中的某些記錄的共享鎖
    • 別的事務不可以繼續獲得該表的獨占鎖
    • 別的事務不可以繼續獲得該表中的某些記錄的獨占鎖
  • 給表加獨占鎖

    如果一個事務給表加了獨占鎖(意味著該事務要獨占這個表),那么:

    • 別的事務不可以繼續獲得該表的共享鎖
    • 別的事務不可以繼續獲得該表中的某些記錄的共享鎖
    • 別的事務不可以繼續獲得該表的獨占鎖
    • 別的事務不可以繼續獲得該表中的某些記錄的獨占鎖

綜合來講與行級鎖幾乎一致,只是層級高了,

但是這其中又有些不一樣的地方:表鎖需要考慮這個表里面有沒有行鎖,表的上鎖需要等待行鎖

但是一個庫可能有幾百萬行,不可能一個一個查吧

為了提高表鎖的效率,我們提出一種意向鎖,使用意向鎖來包裹一次原來的行級鎖,以此表示是否有正在進行的鎖任務,

當我們準備獲取鎖的時候,先用意向鎖上鎖,此時其他的事務發現這個表被上了意向鎖,表示這個表已經鎖定了,需要等待一下,

用鎖來表示當前是否有人訪問,免去了遍歷查詢的痛哭,好!

當然,既然是包裹一層,自然意向鎖也有兩種,共享與獨占,

兼容性獨占意向獨占共享意向共享
獨占不兼容不兼容不兼容不兼容
意向獨占不兼容兼容不兼容兼容
共享不兼容不兼容兼容兼容
意向共享不兼容兼容兼容兼容

MySQL的鎖

MySQL中MyISAMMEMORYMERGE這些存盤引擎只支持表級鎖,只有Innodb才支持事務、行鎖

MySQL對自增id的保護

自增關鍵字AUTO_INCREMENT也會使用鎖來保證唯一與遞增

他主要有兩種實作方式:重量級別的表鎖與輕量級的鎖,他們對應了目標數量是否確實的兩種情況

  • 如果目標的數量不確定,那就有必要先把整個表鎖起來,然后再慢慢增加
  • 如果目標數量是確定,我們直接用輕量級的鎖快速賦值,

寫到這里,已經7k字了,豬豬男孩決定不再繼續深入了,關于鎖的具體實作,大家可以看看

掘金小冊《MySQL 是怎樣運行的:從根兒上理解 MySQL》

覺得有用,還請一鍵三連,送弟弟上岸,

在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/258778.html

標籤:其他

上一篇:verilog2bit全流程覆寫V7_330上板實驗

下一篇:「情人節快到了」“碼”出禮物,一片“芯”意

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more