回滾機制_【巨杉數據庫SequoiaDB】巨杉 Tech | 并發性與鎖機制解析與實踐

01

概述

數據庫是一個多用戶使用的共享資源。當多個用戶并發地存取數據時,在數據庫中就會產生多個事務同時存取同一數據的情況。若對并發操作不加控制就可能會讀取和存儲不正確的數據,破壞數據庫的一致性。加鎖是實現數據庫并發控制的一個非常重要的技術。當事務在對某個數據對象進行操作前,先向系統發出請求,對其加鎖。加鎖后事務就對該數據對象有了一定的控制,在該事務釋放鎖之前,其他的事務不能對此數據對象進行更新操作。

OLTP 場景下通常要求具有很高的并發性。并發事務實際上取決于資源的使用狀況,原則上應盡量減少對資源的鎖定時間,減少對資源的鎖定范圍,從而能夠盡量增加并發事務的數量,那么影響并發的因素有哪些呢?本文將從巨杉分布式數據庫本身的機制以及隔離級別、數據庫鎖、參數、及實際例子進行詳解,讀完本文將對巨杉數據庫并發性與鎖機制有一個初步的了解。

02

隔離級別與并發性

在單用戶環境中,每個事務都是順序執行的,而不會遇到與其他事務的沖突。但是,在多用戶環境下,多個事務并發執行。因此每個事務都有可能與其他正在運行的事務發生沖突。有可能與其他事務發生沖突的事務稱為交錯的或并行的事務,而相互隔離的事務稱為串行化事務,這意味著同時運行它們的結果與一個接一個連續地運行它們的結果沒有區別。在多用戶環境下,在使用并行事務時,會發生四種現象:

  • 丟失更新:這種情況發生在兩個事務讀取并嘗試更新同一數據時,其中一個更新會丟失。例如:事務 1 和事務 2 讀取同一行數據,并都根據所讀取的數據計算出該行的新值。如果事務 1 用它的新值更新該行以后,事務 2 又更新了同一行,則事務 1 所執行的更新操作就丟失了。
  • 臟讀:當事務讀取尚未提交的數據時,就會發生這種情況。例如:事務 1 更改了一行數據,而事務 2 在事務1 提交更改之前讀取了已更改的行。如果事務 1 回滾該更改,則事務 2 就會讀取被認為是不曾存在的數據。
  • 不可重復的讀:當一個事務兩次讀取同一行數據,但每次獲得不同的數據值時,就會發生這種情況。例如:事務 1 讀取了一行數據,而事務 2 在更改或刪除該行后提交了更改。當事務 1 嘗試再次讀取該行時,它會檢索到不同的數據值(如果該行已經被更新的話),或發現該行不復存在了(如果該行被刪除的話)。
  • 幻像:當最初沒有看到某個與搜索條件匹配的數據行,而在稍后的讀操作中又看到該行時,就會發生這種情況。例如:事務 1 讀取滿足某個搜索條件的一組數據行,而事務 2 插入了與事務 1 的搜索條件匹配的新行。如果事務 1 再次執行產生原先行集的查詢,就會檢索到不同的行集。

維護數據庫的一致性和數據完整性,同時又允許多個應用程序同時訪問同一數據,這樣的特性稱為并發性。巨杉數據庫目前通過事務、隔離級別、鎖等機制來對并發性進行控制,它決定在第一個事務訪問數據時,如何對其他事務鎖定或隔離該事務所使用的數據。目前巨杉數據庫支持以下隔離級別來實現并發性:

  • 讀未提交(ReadUncommitted):該隔離級別指即使一個事務的更新語句沒有提交,但是別的事務可以讀到這個改變,幾種異常情況都可能出現。會出現讀取的數據是不對的。
  • 讀已提交(Read Committed):該隔離級別指一個事務只能看到其他事務的已經提交的更新,看不到未提交的更新,消除了臟讀和第一類丟失更新,這是大多數數據庫的默認隔離級別。保證了一個事務不會讀到另一個并行事務已修改但未提交的數據,避免了“臟讀取”,但不能避免“幻讀”和“不可重復讀取”。該級別適用于大多數系統。
  • 讀穩定性(RepeatableStability):該隔離級別指一個事務中進行兩次或多次同樣的對于數據內容的查詢,得到的結果是一樣的。假設SQL語句中包括查詢條件, 則會對全部符合條件的紀錄加對應的鎖。假設沒有條件語句。也就是對表中的全部記錄進行處理。則會對全部的紀錄加鎖。
  • 可重復讀(Repeatable Read):REPEATABLE READ隔離級解決了READUNCOMMITTED隔離級導致的問題。它確保同一事務的多個實例在并發讀取數據時,會“看到同樣的”數據行。不過理論上,這會導致另一個棘手問題:幻讀(Phantom Read)。簡單來說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影”行。數據庫存儲引擎可以通過多版本并發控制 (Multiversion Concurrency Control)機制解決了幻讀問題,如MySQL的InnoDB和Falcon。巨杉數據庫對于多版本控制(MVCC)技術是通過采用事務鎖、內存老版本以及磁盤回滾段重建老版本的設計來實現。此架構設計的理論基礎是通過對內存結構的合理利用,存儲數據和索引的老版本信息,從而實現數據的快速的并發訪問。

03

數據庫鎖參數與并發性實踐

1. SequoiaDB的事務配置

事務作為一個完整的工作單元執行,事務中的操作要么全部執行成功要么全部執行失敗。SequoiaDB事務中的操作只能是插入數據、修改數據以及刪除數據,在事務過程中執行的其它操作不會納入事務范疇,也就是說事務回滾時非事務操作不會被執行回滾。如果一個表或表空間中有數據涉及事務操作,則該表或表空間不允許被刪除。

  • 事務開啟、提交與回滾

在SDB中,關于事務啟停的配置項如下:

f70589d25a6a77934c0e286298a24ac9.png

?

默認情況下,SequoiaDB 所有節點的事務功能都是開啟的。若用戶不需要使用事務功能,可參考以下方法,關閉事務功能。

步驟1:通過sdb shell設置集群所有節點都關閉事務。

db.updateConf( { transactionon: false }, { Global: true } )
72b9b98c40249d6e98163899c8fcf40c.gif

步驟2:在集群每臺服務器上都重啟 SequoiaDB 的所有節點。???????

[sdbadmin@ubuntu-dev1 ~]$ /opt/sequoiadb/bin/sdbstop -t all[sdbadmin@ubuntu-dev1?~]$?/opt/sequoiadb/bin/sdbstart?-t?all

注意:

1. 開啟及關閉節點的事務功能都要求重啟該節點。

2. 在開啟節點事務功能的情況下,節點的配置項logfilenum(該配置項默認值為20)的值不能小于 5。

SequoiaDB 事務支持的操作如下:

  • 寫事務操作:INSERT、UPDATE、DELETE。
  • 讀事務操作:QUERY。

SequoiaDB的其它操作(如:創建表、創建索引、創建并讀寫LOB等其它非 CRUD 操作)不在事務功能的考慮范圍。

支持隔離級別配置參數及取值如下:

96ca8d88239864b5594f88bca7b2b0d4.png

?

可以通過以下方式修改:

db.updateConf( { transisolation: 1 }, { Global: true } )
72b9b98c40249d6e98163899c8fcf40c.gif

注意:該參數在線生效,會在下一次事務中生效

通過 "transBegin"、"transCommit" 及"transRollback" 方法,用戶可以在一個事務中,對若干個操作進行事務控制。其使用方式如下:

> db.transBegin()> 操作1> 操作2> 操作3> ...>?db.transCommit()?or?db.transRollback()

在上述使用模式中,用戶必須顯式調用"transCommit" 及 "transRollback" 方法來結束當前事務。然而,對于寫事務操作,若在操作過程發生錯誤,數據庫配置中的 transautorollback 配置項可以決定當前會話所有未提交的寫操作是否自動回滾。transautorollback 的描述如下:

注意:該配置項只有在事務功能開啟(即 transactionon 為 true )的情況下才生效。

默認情況下,transautorollback 配置項的值為 true。所以,當寫事務操作過程出現失敗時,當前事務所有未提交的寫操作都將被自動回滾。

  • 事務自動提交

數據庫配置中,關于事務自動提交的配置項如下:

6e28e5af6ee55d161afae7cc9f6d68de.png
72b9b98c40249d6e98163899c8fcf40c.gif

??

事務自動提交功能默認情況下是關閉的。當transautocommit 設置為 true 時,事務自動提交功能將開啟。此時,使用事務存在以下兩點不同:

  • 用戶不需要顯式調用 "transBegin" 和"transCommit" 或者 "transRollback" 方法來控制事務的開啟、提交或者回滾。
  • 事務提交或者回滾的范圍僅僅局限于單個操作。當單個操作成功時,該操作將被自動提交;當單個操作失敗時,該操作將被自動回滾。

例如,如下操作中:

> /* transautocommit 設置為 true */> db.foo.bar.update({$inc:{"salary": 1000}}, {"department": "A"}) // 更新 1> db.foo.bar.update({$inc:{"salary": 2000}}, {"department": "B"}) // 更新 2> db.foo.bar.update({$inc:{"salary": 3000}}, {"department": "C"}) // 更新 3>?...

更新 1、更新 2、更新 3 分別為獨立的操作。假設更新 1 和 更新 2 操作成功,而更新 3失敗。那么更新 1 和 更新 2 修改的記錄將全部被自動提交。而更新 3 修改的記錄將全部被自動回滾。

  • 其它配置

數據庫配置中,關于事務的其它主要配置項如下:

1c5fde1962fed76e657990b95fd06961.png

?

  • 調整設置

當用戶希望調整事務的設置時(如:是否開啟事務、調整事務配置項等),有如下 3 種方式供用戶選擇使用:

  1. 用戶可以將數據庫配置描述的事務配置項,配置到集群所有(或者部分)節點的配置文件中。若修改的配置項要求重啟節點才能生效,用戶需重啟相應的節點。
  2. 使用 updateConf()命令在 sdb shell 中修改集群的事務配置項。若修改的配置項要求重啟節點才能生效,用戶需重啟相應的節點。
  3. 使用 setSessionAttr()命令在會話中修改當前會話的事務配置項。該設置只在當前會話生效,并不影響其它會話的設置情況。

2. SequoiaDB并發與鎖操作實踐

示例:

建立數據庫以及表

mysql> use company;Database changedmysql>  create table t1 (a int,b int);Query?OK,?0?rows?affected?(0.03?sec)

1)事務提交與回滾

例子1:

使用事務回滾插入操作。事務回滾后,插入的記錄將被回滾,集合中無記錄:

mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> insert into t1 values(1,1);Query OK, 1 row affected (0.08 sec)mysql> select * from t1;+------+------+| a    | b    |+------+------+|    1 |    1 |+------+------+1 row in set (0.00 sec)mysql> rollback;Query OK, 0 rows affected (0.01 sec)mysql> select * from t1;Empty?set?(0.00?sec)

例子2:

使用事務提交插入操作。提交事務后,插入的記錄將被持久化到數據庫:

mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> insert into t1 values(1,1);Query OK, 1 row affected (0.00 sec)mysql> commit;Query OK, 0 rows affected (0.01 sec)mysql> select * from t1;+------+------+| a    | b    |+------+------+|    1 |    1 |+------+------+1?row?in?set?(0.01?sec)

2)隔離級別為RU并發與鎖

例子3:

在隔離級別為RU(transisolation 設置為0)的情況下,設置當前會話級(會話1及會話2同時設置)隔離級別為read uncommitted :

???????

mysql> SELECT @@tx_isolation;+-----------------+| @@tx_isolation  |+-----------------+| REPEATABLE-READ |+-----------------+1 row in set, 1 warning (0.00 sec)mysql> set session transaction isolation level read uncommitted;Query OK, 0 rows affected (0.00 sec)mysql> SELECT @@tx_isolation;+------------------+| @@tx_isolation   |+------------------+| READ-UNCOMMITTED |+------------------+1?row?in?set,?1?warning?(0.00?sec)

在窗口1:會話1對該表寫入數據,并不提交。

???????

mysql> create table t3(a int,b int);Query OK, 0 rows affected (0.02 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> insert into t3 values(1,1);Query?OK,?1?row?affected?(0.03?sec)

在窗口2:會話2對該表進行查詢,查到的是未提交的數據。

mysql>  select * from t3;+------+------+| a    | b    |+------+------+|???1?|????1?|+------+------+1?row?in?set?(0.01?sec)

小結:由于采用了隔離級別是RU,允許臟讀,在第二個會話中不會產生鎖等待,而直接會讀到未提交的數據。該隔離級別建議設置在以讀為主的歷史數據平臺應用中,在真實的OLTP環境中,不能滿足業務需求。這樣業務查詢會讀取到未提交事務的修改,如果事務發生回滾,那么讀取的數據是錯誤的。不能滿足一致性的要求。

3)隔離級別為RC并發與鎖

RR隔離級別的實現概述:

巨杉數據庫在RC隔離級別上除了支持傳統關系型數據庫的讀已提交以外,通過MVCC多版本訪問的方式支持讀取最后一次提交的版本而不會產生鎖等待,從而提高業務的并行處理能力。

例子4:在隔離級別為RC(transisolation 設置為1,translockwait為true)的情況下,看看并發情況:

66c648d681e7dac009727f93c18aefd2.png

?

首先,修改隔離級別為1,translockwait為true該修改將在下一次連接的時候生效。

> db.updateConf({transisolation:1},{Global:true});Takes 0.051656s.> db.updateConf({translockwait:true},{Global:true});Takes 0.041699s.> db.updateConf({transactiontimeout:30},{Global:true});Takes 0.099934s.> db.updateConf({transautocommit:true},{Global:true});Takes?0.040183s.

備注:也可以通過mysql端進行當前session隔離級別參數的修改。

設置當前會話級(會話1及會話2同時設置)隔離級別為read committed :

???????

mysql> set session transaction isolation level read committed;  Query?OK,?0?rows?affected?(0.00?sec)

在窗口1:事務1對該表寫入數據,并不提交。

???????

mysql> create table t4 (a int,b int);Query OK, 0 rows affected (0.09 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> insert into t4 values(1,1);Query?OK,?1?row?affected?(0.03?sec)

在窗口2:事務2對該表進行查詢,可以看到一直會處于等待鎖的狀態,直到鎖超時(transactiontimeout設置為30秒)退出。

???????

mysql> select * from t4;ERROR?1030?(HY000):?Got?eror?40013?from?storage?engine

通過捉取鎖的快照,可以看到第一個事務持有鎖的信息,持有該表上的IX,IS鎖以及記錄上的X鎖。如下圖所示:

c59dfcf73d6c659c36b7a3e701b1c8a6.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

而第二個事務等待鎖的情況,在等鎖該表記錄上的S鎖。如下圖所示:

d64c51a2792d3ae20a9b979c7007661e.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

小結:由于采用了隔離級別是RC 并且translockwait設置為true的情況下,在第二個事務中會產生鎖等待,直到第一個事務釋放該表上的行鎖,第二個事務才能執行,否則會一直等待到鎖超時退出為止。這也是大多數傳統關系型數據庫的默認隔離級別。

例子5:

在隔離級別為RC(transisolation 設置為1,translockwait為false)的情況下,看看并發情況:

我們先來看看translockwait設置為false的說明: 不等待記錄鎖,直接從系統讀取最后一次提交的版本。

設置SDB參數配置:

???????

> db.updateConf({translockwait:false},{Global:true});Takes?0.041699s.

備注:可以通過mysql端進行當前session隔離級別參數的修改。

設置當前會話級(會話1及會話2同時設置)隔離級別為read committed :

???????

mysql> set session transaction isolation level read committed;  Query?OK,?0?rows?affected?(0.00?sec)

在窗口1:事務1對該表寫入數據,并不提交。

???????

mysql> create table t5 (a int,b int);Query OK, 0 rows affected (0.09 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> insert into t5 values(1,1);Query?OK,?1?row?affected?(0.03?sec)

在窗口2:事務2對該表進行查詢,可以看到馬上返回,并沒有發生鎖等待的情況。這時候查到的數據是最后一次提交的版本

mysql> select * from t5;Empty?set?(0.01?sec)

小結:由于采用了隔離級別是RC 并且translockwait設置為false的情況下,在第二個事務不會產生鎖等待,而是會讀到最后一次版本已提交的數據。通過鎖快照也可以看到沒有任何鎖等待的情況出現。該隔離級別設置適用于絕大多數的OLTP場景。

4)隔離級別為RS并發與鎖

例子6:

在隔離級別為RS(transisolation 設置為2)的情況下,看看并發情況:

> db.updateConf({transisolation:1},{Global:true});Takes?0.051656s.

在窗口1:事務1對該表進行查詢數據,不提交。

???????

mysql> create table t6 (a int,b int,primary key(a));Query OK, 0 rows affected (0.09 sec)mysql> insert into t6 values(1,1);Query OK, 1 row affected (0.03 sec)mysql> insert into t6 values(2,1);Query OK, 1 row affected (0.03 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> select * from t6;+------+------+| a    | b    |+------+------+|    1 |    1 ||    2 |    1 |+------+------+1?row?in?set?(0.01?sec)

在窗口2:事務2對該表進行更新,可以看到處于鎖等待的狀態。最終鎖超時事務進行回滾:

???????

mysql> egin;Query OK, 0 rows affected (0.00 sec)mysql> update t6 set b=11 where b=1;ERROR?1030?(HY000):?Got?error?40013?from?storage?engine

通過捉取鎖的快照,可以看到第一個事務持有鎖的情況,查詢拿到了該表上的S鎖。如下圖所示:

4e82d0480ab5ce7ac04d3af8a9857424.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

而事務2需要取到該表上的X鎖而產生了等待,如下圖所示:

d5c1af8ea2bf72dd96b733ef874a2308.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

小結:由于采用了隔離級別是RS ,在第二個事務更新的事務會產生鎖等待,任何事務查找的記錄都不允許更新,直到該讀取的表的鎖被釋放。通過鎖快照也可以看到有鎖等待的情況出現。RS場景并發性較差,一般適應于總帳計算系統系統。查到的數據該事務不提交,側不允許被修改。

5)隔離級別為RR并發與鎖

RR隔離級別的實現概述:

在多版本控制技術的事務鎖實現中,RR(可重復讀)配置下的讀操作可以在使用完記錄之后立即釋放鎖,不需要一直持有,直到事務提交或者回滾。但是寫事務操作則需要一直持有插入、更改和刪除的鎖,直到事務完成提交或者回滾。巨杉數據庫鎖的實現是采用悲觀鎖機制,與傳統關系型數據庫的采用的主流鎖機制類似。

在多版本控制技術的實現中,除了引入悲觀鎖的機制以外,巨杉數據庫還采用了內存老版本機制提升數據庫并發訪問及操作的能力。內存老版本是通過在記錄鎖上附加有一個存儲原版本數據和索引相關的結構,于內存中存儲了老版本的數據。

以下通過實例操作進行詳解:

例子7:

在隔離級別為RR(transisolation 設置為3)的情況下,看看并發情況:

> db.updateConf({transisolation:3},{Global:true});Takes 0.051656s.> db.updateConf({mvccon:true},{Global:true})Takes 0.156197s.> db.updateConf({globtranson:true},{Global:true})Takes?0.051241s.

備注:打開RR隔離,除了transisolation 設置為3以外,需要修改以上多二個參數。mvccon及globtranson這二個參數為true。通過mysql端也可以直接進行設置。

通過mysql直接設置當前會話級(會話1及會話2同時設置)隔離級別為REPEATABLEREAD;

???????

mysql> set session transaction isolation level REPEATABLE READ;  Query?OK,?0?rows?affected?(0.00?sec)

在窗口1:事務1對該表rr進行查詢數據,不提交

mysql> create table rr (a int);Query OK, 0 rows affected (0.06 sec)mysql> insert into rr values(1);Query OK, 1 row affected (0.19 sec)mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> select * from rr;+------+| a    |+------+|    1 |+------+1?row?in?set?(0.00?sec)

在窗口2:事務2對該表rr(事務1第一次查詢后)進行數據更新后提交。

mysql> begin;Query OK, 0 rows affected (0.00 sec)mysql> update rr set a=2 where a=1;Query OK, 1 row affected (0.01 sec)Rows matched: 1  Changed: 1  Warnings: 0mysql> commit;Query?OK,?0?rows?affected?(0.01?sec)

在窗口1:事務1對該表rr進行再次查詢數據,查詢到的數據可以看到不會由于事務2的更新提交而改變,而是讀到事務開始前的版本數據。

mysql> select * from rr;+------+| a    |+------+|    1 |+------+1?row?in?set?(0.00?sec)

通過捉取鎖的快照,可以看到第一個查詢的事務1在整個事務的查詢中沒有持任何鎖,而事務2更新的操作持用該表的行鎖。如下所示:

事務1持有鎖的情況(未持有鎖):

72b9b98c40249d6e98163899c8fcf40c.gif

?

事務2持有鎖的情況,持有該表的X鎖,如下圖所示:

3418d39a0ea4dbc605a4a9d88f16f8bd.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

aad8f8e1bdb8121e2df5684c21d4b396.png
72b9b98c40249d6e98163899c8fcf40c.gif

?

小結:由于采用了隔離級別是RR ,任何查詢都不會持用鎖,也不會等鎖,可以看到在第二個事務更新的操作不會影響事務1,任何更新的操作不會影響查詢,由于事務1是在事務2之前執行查詢,當前事務1始終查到的是rr表的事務2的更新前版本。該隔離級別適應于大并發查詢的交易場景,能有效提高整個應用的并發性。

05

總結

巨杉數據庫完整支持傳統關系型數據庫的幾種常用隔離級別,可滿足所有核心生產場景(OLTP及OLAP等場景)需求。創新性采用事務鎖、內存老版本以及磁盤回滾段重建老版本的設計來實現了多版本并發控制技術。通過對內存結構的合理利用,存儲數據和索引的老版本信息,從而實現多版本數據的快速的并發訪問。

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

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

相關文章

Android系統源碼學習——源碼目錄結構介紹

2019獨角獸企業重金招聘Python工程師標準>>> Android 4.0源碼目錄結構: 本文介紹Android源碼目錄結構,以便讀者理清Android編譯系統核心代碼在Android源代碼的位置。 Android源碼體積非常龐大,由Dalvik虛擬機、Linux內核、編譯系統、框架代碼…

簡答題c語言文件操作順序,計算機基礎與程序設計2012年4月真題試題(02275)

計算機基礎與程序設計2012年4月真題試題與答案解析(02275)計算機基礎與程序設計2012年4月真題試題與答案解析(02275),本試卷總共100分。一、單項選擇題(本大題共20小題.每小題1分,共20分)在每小題列出的四個備選項中只有一個是符合題目要求的&#xff0c…

匯編實驗3

1.運行如下代碼: assume cs:codecode segment mov ah,2 mov dl,3 add dl,30h int 21h mov ah,2 mov dl,6 add dl,30h int 21h mov ah,4ch int 21hcode endsend 進行匯編運行之后結果為: 將第四行和第九行的寄存器dl的值修改之后代碼如下: a…

聽了一堂《**學院》的課,我也是醉了

這還是首席講師的ppt,這說話咋感覺,不像是技術出身,反倒是MongoDB的銷售人員呢。 這說話,不大講相對,凈他媽的 絕對,這水平,我真醉了。 這牛逼吹得,嘖嘖嘖。 我還是看書吧。 轉載于:…

react 組件引用組件_React Elements VS React組件

react 組件引用組件A few months ago I posted to Twitter what I thought was a simple question:幾個月前,我在Twitter上發布了一個我認為簡單的問題: What surprised me wasn’t the joint confusion around this question, but rather the amount o…

appium 環境搭建(不推薦安裝此版本appium,推薦安裝appium desktop)

一:安裝node.js 1、雙擊這個軟件 2、一鍵安裝,全都下一步,不要私自更改安裝路徑 3、打開cmd,輸入npm,出現如下截圖表示成功 二:安裝appium 1、雙擊appium-installer.exe 2、一鍵安裝,全都下一步…

二級c語言上機題庫及解析,2013年計算機二級C語言上機題庫及答案解析(3)

填空題給定程序中,函數fun的功能是:在形參ss所指字符串數組中,查找含有形參substr所指子串的所有字符串并輸出,若沒找到則輸出相應信息。ss所指字符串數組中共有N個字符串,且串長小于M。程序中庫函數strstr(s1, s2)的功能是在 s1串…

js 數組遍歷符合條件跳出循環體_C++模擬面試:從數組“緊湊”操作說開來

面試官自來也去掉一個字符串中的空格。假設用C語言來解答,字符串是char數組。O(n)時間復雜度實現不難,比如額外申請一個新數組,然后遍歷一遍字符串,將符合條件的字符存儲到新數組中,實現起來很簡單。但這顯然不能讓面試…

項目NABCD的分析

N:你的創意解決了用戶的什么需求 本項目解決了在校大學生和社會工程人士在計算一些工程測量中的需求, 可以通過自己提供的一些測得的已知數據來推算出自己想要的數據結果, 比用戶自己手動計算更有效更快更節省時間 A:有什么招數來…

git 命令git 地址_這是我上周使用的所有Git命令及其作用。

git 命令git 地址by Sam Corcos由Sam Corcos 這是我上周使用的所有Git命令及其作用。 (Here are all the Git commands I used last week, and what they do.) Like most newbies, I started out searching StackOverflow for Git commands, then copy-pasting answers, witho…

兩個隊列實現一個棧思路c語言,兩個棧實現隊列功能C語言實現能運行!

#include#includetypedef struct sq{char *ps;int top;int Maxsize;}stack;void initstack(stack *s,int ms){s->ps(char*)malloc(ms*sizeof(char));s->top-1;s->Maxsizems;};void push(stack *s,char val){if(s->tops->Maxsize-1){printf("棧已滿\n"…

基本入門程序編寫格式和注意事項

在安裝好JDK后聯系程序的基本寫法。1、先創建記事本,如果有超級記事本如:notepad、ultraedit、editplus等更好。重命名把記事本后面的后綴名改為.java 但是值得注意的是要看看自己創建的記事本文檔是否是隱藏后綴名的。要是有設置隱藏的就取消隱藏,以免混…

.dll文件存在但是不顯示_一招巧妙解決U盤內文件明明存在,打開U盤而內容卻不顯示的問題...

大家可能都遇到過這種情況,就是說U盤中明明有文件,但是插在電腦上就是什么文件都沒有,一片空白,這樣的問題對于那些對文件很重要且僅保存了1份的人來說是很.kongbu.,因為U盤中的內容都是命根子。給大家介紹絕對有用的解…

《java入門第一季》之面向對象(包概述)

由于eclipse等ide的強大功能,使得建包,導包用一些快捷鍵就能完成。這里對包的概念做稍微的敘述,了解即可: 分包后使得項目更加清晰,提高代碼維護性。 包: A:其實就是文件夾 B:作用 …

Vue 框架-05-動態綁定 css 樣式

Vue 框架-05-動態綁定 css 樣式 今天的小實例是關于 Vue 框架動態綁定 css 樣式,這也是非常常用的一個部分 首先說一下 動態綁定,相對的大家都知道靜態綁定,靜態綁定的話,直接加 class“”就可以了,使用 Vue 呢之前也介…

ember.js_如何設置基本的Ember.js應用

ember.jsby Tracy Lee | ladyleet特雷西李(Tracy Lee)| Ladyleet 如何設置基本的Ember.js應用 (How to set up a Basic Ember.js app) So, you want to test out Ember, eh? This article will walk through building a basic app.所以,您想測試Ember,…

分數轉小數C語言,這是把小數轉換成分數的程序,可是輸入0.6666無限循環

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#include int main(){double a;scanf("%lf", &a);輸入小數int b, c 0, d 0;double b1 a;do{b1 *10;b (int)b1;printf("%d\n", b);if(b%10!0){c;if(d>0){c d;d 0;}}else{d;}}while(d<5);printf("…

arm處理器的歷史及現狀

1 arm處理器的發展歷史 arm1 arm2 arm3 arm6 arm7 arm9 arm11 arm cortex 2 arm處理器現狀 arm cortex A a即application&#xff0c;即應用處理器&#xff0c;主要用在智能手機、平板電腦和服務器上。 arm cortex M m即mcu&#xff0c;即單片機上的處理器&#xff0c;它的特點…

Linq常用List操作總結,ForEach、分頁、交并集、去重、SelectMany等

1 /*2 以下圍繞Person類實現&#xff0c;Person類只有Name和Age兩個屬性3 一.List<T>排序4 1.1 List<T>提供了很多排序方法&#xff0c;sort(),Orderby(),OrderByDescending().5 */6 7 lstPerson lstPerson.OrderByDescending(x>x.Name).ToList(); //降序8 ls…

bool查詢原理 es_ES系列之原理copy_to用好了這么香

寫在前面Elasticsearch(以下簡稱ES)有個copy_to的功能&#xff0c;之前在一個項目中用到&#xff0c;感覺像是發現了一個神器。這個東西并不是像有些人說的是個語法糖。它用好了不但能提高檢索的效率&#xff0c;還可以簡化查詢語句。基本用法介紹直接上示例。先看看mapping&am…