Go+MySQL階段考核總結(jié)
階段時(shí)間:2021年8月12日~2021年9月16日
Golang基礎(chǔ)知識(shí)博客:go基礎(chǔ)博客
這個(gè)階段我學(xué)習(xí)到了Go基礎(chǔ)和mysql驹碍,考核總體一般帖族,因?yàn)橛幸恍└拍顩](méi)有弄清楚倦零,我所記到的我考核的時(shí)候,我不清楚的知識(shí)點(diǎn)有:
go基礎(chǔ)方面:
gc
interface
類(lèi)型斷言使用
http編程
原子操作
線程和協(xié)程的關(guān)系
mysql方面:
內(nèi)外連接語(yǔ)句不熟
關(guān)系型和非關(guān)系型的區(qū)別
MyIsam與innoDB的具體區(qū)別
考核后的學(xué)習(xí):
gc:garbage collection(垃圾回收)
golang本身支持gc趴拧,gc的實(shí)現(xiàn)也主要通過(guò)以下方法:
三色標(biāo)記法
后臺(tái)并發(fā)標(biāo)記
后臺(tái)并發(fā)消除
混合寫(xiě)屏障
輔助gc
每個(gè)方法的具體步驟就不在這里詳述了。
interface與類(lèi)型斷言:
接口是一種類(lèi)型,一種抽象的類(lèi)型,是一組方法的集合缔杉,是duck-type programming的一種體現(xiàn)
接口類(lèi)型的變量可以接收任意類(lèi)型的值,想要實(shí)現(xiàn)可以存儲(chǔ)多類(lèi)型的數(shù)組或者map就很方便搁料。
想要判斷空接口中的值這個(gè)時(shí)候就可以使用類(lèi)型斷言
x.(T)
其中:
? ? x:表示類(lèi)型為interface{}的變量
T:表示斷言x可能是的類(lèi)型或详。
該語(yǔ)法返回兩個(gè)參數(shù),第一個(gè)參數(shù)是x轉(zhuǎn)化為T(mén)類(lèi)型后的變量郭计,第二個(gè)值是一個(gè)布爾值霸琴,
若為true則表示斷言成功,為false則表示斷言失敗昭伸。
packagemain
import"fmt"
funcmain() {
varxinterface{}
x="pprof.cn"
v,ok:=x.(string)
ifok{
fmt.Println(v)
}else{
fmt.Println("類(lèi)型斷言失敗")
?? }
}
//當(dāng)然如果條件多的話也可以使用switch語(yǔ)句
http編程
三次握手梧乘,四次揮手(每一次的作用):
第一次握手:客戶端要求與服務(wù)器連接,發(fā)送SYN包(SYN=j)到服務(wù)器庐杨,并進(jìn)入SYN_SEND狀態(tài)选调,等待服務(wù)器確認(rèn)
第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ACK=j+1)灵份,同時(shí)自己也發(fā)送一個(gè)SYN包(SYN=k)仁堪,即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)
第三次握手:客戶端收到服務(wù)器的SYN+ACK包填渠,向服務(wù)器發(fā)送確認(rèn)包ACK(ACK=k+1)弦聂,此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài)氛什。
完成三次握手横浑,客戶端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。
先手中斷連接端的可以是Client端屉更,也可以是Server端
(案例:假如先要求中斷的是Client端)
第一次揮手:Client端給Server端發(fā)信息說(shuō)沒(méi)有數(shù)據(jù)需要傳送了
第二次揮手:Server端收到信息之后自己可能還需要發(fā)送數(shù)據(jù)給Client端徙融,所以需要發(fā)一次消息讓Client端知道
第三次揮手:Server端傳輸所有的數(shù)據(jù)完畢,然后給Client端發(fā)送FIN報(bào)文瑰谜,表示完成欺冀,可以中斷了树绩。
第四次揮手:Client端收到之后,發(fā)送ACK確認(rèn)標(biāo)識(shí)隐轩,連接結(jié)束饺饭。
(問(wèn)題:為什么連接的時(shí)候是三次握手,但是揮手的時(shí)候卻是四次呢职车?
答:因?yàn)楫?dāng)Server端收到Client端的SYN連接請(qǐng)求報(bào)文后瘫俊,可以直接發(fā)送SYN+ACK報(bào)文。其中ACK報(bào)文是用來(lái)應(yīng)答的悴灵,SYN報(bào)文是用來(lái)同步的扛芽。但是關(guān)閉連接時(shí),當(dāng)Server端收到FIN報(bào)文時(shí)积瞒,很可能并不會(huì)立即關(guān)閉SOCKET川尖,所以只能先回復(fù)一個(gè)ACK報(bào)文,告訴Client端茫孔,"你發(fā)的FIN報(bào)文我收到了"叮喳。只有等到我Server端所有的報(bào)文都發(fā)送完了,我才能發(fā)送FIN報(bào)文缰贝,因此不能一起發(fā)送馍悟。故需要四步握手。)
位碼即tcp標(biāo)志位,有6種標(biāo)示:
SYN(synchronous建立連接)
ACK(acknowledgement 確認(rèn))
PSH(push傳送)
FIN(finish結(jié)束)
RST(reset重置)
URG(urgent緊急)
Sequence number(順序號(hào)碼)
Acknowledge number(確認(rèn)號(hào)碼)
原子操作
代碼中的加鎖操作因?yàn)樯婕皟?nèi)核態(tài)的上下文切換會(huì)比較耗時(shí)剩晴、代價(jià)比較高赋朦。針對(duì)基本數(shù)據(jù)類(lèi)型我們還可以使用原子操作來(lái)保證并發(fā)安全,因?yàn)樵硬僮魇荊o語(yǔ)言提供的方法它在用戶態(tài)就可以完成李破,因此性能比加鎖操作更好宠哄。Go語(yǔ)言中原子操作由內(nèi)置的標(biāo)準(zhǔn)庫(kù)sync/atomic提供。
這個(gè)包內(nèi)有各種各樣功能的方法:
讀取操作(Load)
寫(xiě)入操作(Store)
修改操作(Add)
交換操作(Swap)
比較并交換操作(CompareAndSwap)
atomic包提供了底層的原子級(jí)內(nèi)存操作嗤攻,對(duì)于同步算法的實(shí)現(xiàn)很有用毛嫉。這些函數(shù)必須謹(jǐn)慎地保證正確使用。除了某些特殊的底層應(yīng)用妇菱,使用通道或者sync包的函數(shù)/類(lèi)型實(shí)現(xiàn)同步更好承粤。
線程和協(xié)程的關(guān)系
多個(gè)協(xié)程可由一個(gè)或多個(gè)線程管理,協(xié)程的調(diào)度發(fā)生在其所在的線程中闯团。
可以被調(diào)度辛臊,調(diào)度策略由應(yīng)用層代碼定義,即可被高度自定義實(shí)現(xiàn)房交。
執(zhí)行效率高彻舰。
占用內(nèi)存少。
funcTestGorutine(t*testing.T) {
? ? runtime.GOMAXPROCS(1)// 指定最大 P 為 1,從而管理協(xié)程最多的線程為 1 個(gè)
? ? wg:=sync.WaitGroup{}// 控制等待所有協(xié)程都執(zhí)行完再退出程序
? ? wg.Add(2)
? ? // 運(yùn)行一個(gè)協(xié)程
? ? gofunc() {
? ? ? ? fmt.Println(1)
? ? ? ? fmt.Println(2)
? ? ? ? fmt.Println(3)
? ? ? ? wg.Done()
? ? }()
? ? // 運(yùn)行第二個(gè)協(xié)程
? ? gofunc() {
? ? ? ? fmt.Println(65)
? ? ? ? fmt.Println(66)
? ? ? ? // 設(shè)置個(gè)睡眠刃唤,讓該協(xié)程執(zhí)行超時(shí)而被掛起隔心,引起超時(shí)調(diào)度
? ? ? ? time.Sleep(time.Second)
? ? ? ? fmt.Println(67)
? ? ? ? wg.Done()
? ? }()
? ? wg.Wait()
}
上面的代碼片段跑了兩個(gè)協(xié)程,運(yùn)行后尚胞,觀察輸出的順序是交錯(cuò)的
意味著在執(zhí)行協(xié)程A的過(guò)程中硬霍,可以隨時(shí)中斷,去執(zhí)協(xié)程行B笼裳,協(xié)程B也可能在執(zhí)行過(guò)程中中斷再去執(zhí)行協(xié)程A唯卖。
看起來(lái)協(xié)程A 和 協(xié)程B 的運(yùn)行像是線程的切換,但是這里的 A 和 B 都運(yùn)行在同一個(gè)線程里面躬柬。它們的調(diào)度不是線程的切換拜轨,而是純應(yīng)用態(tài)的協(xié)程調(diào)度
runtime.GOMAXPROCS(1)
time.Sleep(time.Second)
如果不設(shè)置 runtime.GOMAXPROCS(1),那么程序?qū)?huì)根據(jù)操作系統(tǒng)的 CPU 核數(shù)而啟動(dòng)對(duì)應(yīng)數(shù)量的 P楔脯,導(dǎo)致多個(gè) M,即線程的啟動(dòng)胯甩。那么我們程序中的協(xié)程昧廷,就會(huì)被分配到不同的線程里面去了,故設(shè)置數(shù)量 1偎箫,使得它們都被分配到了同一個(gè)線程里面木柬,存于線程的協(xié)程隊(duì)列里面,等待被執(zhí)行或調(diào)度淹办。
因?yàn)閰f(xié)程的調(diào)度切換不是線程切換眉枕,而是由程序自身控制,因此怜森,沒(méi)有線程切換的開(kāi)銷(xiāo)速挑,和多線程比,線程數(shù)量越多副硅,協(xié)程的性能優(yōu)勢(shì)就越明顯姥宝。調(diào)度發(fā)生在應(yīng)用態(tài)而非內(nèi)核態(tài)。
內(nèi)存的花銷(xiāo)恐疲,使用其所在的線程的內(nèi)存腊满,意味著線程的內(nèi)存可以供多個(gè)協(xié)程使用。
其次協(xié)程的調(diào)度不需要多線程的鎖機(jī)制培己,因?yàn)橹挥幸粋€(gè)線程碳蛋,也不存在同時(shí)寫(xiě)變量沖突,所以執(zhí)行效率比多線程高很多省咨。
比較的點(diǎn)線程協(xié)程
數(shù)據(jù)存儲(chǔ)內(nèi)核態(tài)的內(nèi)存空間一般是線程提供的用戶態(tài)內(nèi)存空間
切換操作操作最終在內(nèi)核層完成肃弟,應(yīng)用層需要調(diào)用內(nèi)核層提供的 syscall 底層函數(shù)應(yīng)用層使用代碼進(jìn)行簡(jiǎn)單的現(xiàn)場(chǎng)保存和恢復(fù)即可
任務(wù)調(diào)度由內(nèi)核實(shí)現(xiàn),搶占方式零蓉,依賴各種鎖由用戶態(tài)的實(shí)現(xiàn)的具體調(diào)度器進(jìn)行愕乎。例如 go 協(xié)程的調(diào)度器
語(yǔ)音支持程度絕大部分編程語(yǔ)言部分語(yǔ)言:Lua阵苇,Go,Python ...
實(shí)現(xiàn)規(guī)范按照現(xiàn)代操作系統(tǒng)規(guī)范實(shí)現(xiàn)無(wú)統(tǒng)一規(guī)范感论。在應(yīng)用層由開(kāi)發(fā)者實(shí)現(xiàn)绅项,高度自定義,比如只支持單線程的線程比肄。不同的調(diào)度策略快耿,等等
sql語(yǔ)句使用和記憶不熟練,目前重新記憶了之前做的mysql筆記
關(guān)系型數(shù)據(jù)庫(kù)和非關(guān)系型的區(qū)別
關(guān)系型數(shù)據(jù)庫(kù):
關(guān)系型數(shù)據(jù)庫(kù)最典型的數(shù)據(jù)結(jié)構(gòu)是表芳绩,由二維表及其之間的聯(lián)系所組成的一個(gè)數(shù)據(jù)組織
優(yōu)點(diǎn):1掀亥、 易于維護(hù):都是使用表結(jié)構(gòu),格式一致妥色;2搪花、使用方便:SQL語(yǔ)言通用,可用于復(fù)雜查詢嘹害;3撮竿、復(fù)雜操作:支持SQL,可用于一個(gè)表以及多個(gè)表之間非常復(fù)雜的查詢笔呀。缺點(diǎn):1幢踏、讀寫(xiě)性能比較差,尤其是海量數(shù)據(jù)的高效率讀寫(xiě)许师;2房蝉、固定的表結(jié)構(gòu),靈活度稍欠微渠;3搭幻、高并發(fā)讀寫(xiě)需求,傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)來(lái)說(shuō)逞盆,硬盤(pán)I/O是一個(gè)很大的瓶頸粗卜。
非關(guān)系型數(shù)據(jù)庫(kù):
非關(guān)系型數(shù)據(jù)庫(kù)嚴(yán)格上不是一種數(shù)據(jù)庫(kù),應(yīng)該是一種數(shù)據(jù)結(jié)構(gòu)化存儲(chǔ)方法的集合纳击,可以是文檔或者鍵值對(duì)等续扔。
優(yōu)點(diǎn):1、格式靈活:存儲(chǔ)數(shù)據(jù)的格式可以是key,value形式焕数、文檔形式纱昧、圖片形式等等,文檔形式堡赔、圖片形式等等识脆,使用靈活,應(yīng)用場(chǎng)景廣泛,而關(guān)系型數(shù)據(jù)庫(kù)則只支持基礎(chǔ)類(lèi)型灼捂。2离例、速度快:nosql可以使用硬盤(pán)或者隨機(jī)存儲(chǔ)器作為載體,而關(guān)系型數(shù)據(jù)庫(kù)只能使用硬盤(pán)悉稠;3宫蛆、高擴(kuò)展性;4的猛、成本低:nosql數(shù)據(jù)庫(kù)部署簡(jiǎn)單耀盗,基本都是開(kāi)源軟件。
缺點(diǎn):1卦尊、不提供sql支持叛拷,學(xué)習(xí)和使用成本較高;2岂却、無(wú)事務(wù)處理忿薇;3、數(shù)據(jù)結(jié)構(gòu)相對(duì)復(fù)雜躏哩,復(fù)雜查詢方面稍欠署浩。
MyISAM與InnoDB 的區(qū)別
InnoDB支持事務(wù),MyISAM不支持震庭,對(duì)于InnoDB每一條SQL語(yǔ)言都默認(rèn)封裝成事務(wù)瑰抵,自動(dòng)提交你雌,這樣會(huì)影響速度器联,所以最好把多條SQL語(yǔ)言放在begin和commit之間,組成一個(gè)事務(wù)婿崭;
InnoDB支持外鍵拨拓,而MyISAM不支持。對(duì)一個(gè)包含外鍵的InnoDB表轉(zhuǎn)為MYISAM會(huì)失斆フ弧渣磷;
InnoDB是聚集索引,使用B+Tree作為索引結(jié)構(gòu)授瘦,數(shù)據(jù)文件是和(主鍵)索引綁在一起的(表數(shù)據(jù)文件本身就是按B+Tree組織的一個(gè)索引結(jié)構(gòu))醋界,必須要有主鍵,通過(guò)主鍵索引效率很高提完。但是輔助索引需要兩次查詢形纺,先查詢到主鍵,然后再通過(guò)主鍵查詢到數(shù)據(jù)徒欣。因此逐样,主鍵不應(yīng)該過(guò)大,因?yàn)橹麈I太大,其他索引也都會(huì)很大脂新。 MyISAM是非聚集索引挪捕,也是使用B+Tree作為索引結(jié)構(gòu),索引和數(shù)據(jù)文件是分離的争便,索引保存的是數(shù)據(jù)文件的指針级零。主鍵索引和輔助索引是獨(dú)立的。也就是說(shuō):InnoDB的B+樹(shù)主鍵索引的葉子節(jié)點(diǎn)就是數(shù)據(jù)文件始花,輔助索引的葉子節(jié)點(diǎn)是主鍵的值妄讯;而MyISAM的B+樹(shù)主鍵索引和輔助索引的葉子節(jié)點(diǎn)都是數(shù)據(jù)文件的地址指針。
InnoDB不保存表的具體行數(shù)酷宵,執(zhí)行select count(*) from table時(shí)需要全表掃描亥贸。而MyISAM用一個(gè)變量保存了整個(gè)表的行數(shù),執(zhí)行上述語(yǔ)句時(shí)只需要讀出該變量即可浇垦,速度很快(注意不能加有任何WHERE條件)炕置;
InnoDB支持表、行(默認(rèn))級(jí)鎖男韧,而MyISAM支持表級(jí)鎖
InnoDB表必須有唯一索引(如主鍵)(用戶沒(méi)有指定的話會(huì)自己找/生產(chǎn)一個(gè)隱藏列Row_id來(lái)充當(dāng)默認(rèn)主鍵)朴摊,而Myisam可以沒(méi)有
這兩者如何進(jìn)行選擇:
是否要支持事務(wù),如果要請(qǐng)選擇innodb此虑,如果不需要可以考慮MyISAM甚纲;
如果表中絕大多數(shù)都只是讀查詢,可以考慮MyISAM朦前,如果既有讀也有寫(xiě)介杆,請(qǐng)使用InnoDB。
系統(tǒng)奔潰后韭寸,MyISAM恢復(fù)起來(lái)更困難春哨,能否接受;
MySQL5.5版本開(kāi)始Innodb已經(jīng)成為Mysql的默認(rèn)引擎(之前是MyISAM)恩伺,說(shuō)明其優(yōu)勢(shì)是有目共睹的赴背,如果你不知道用什么,那就用InnoDB晶渠,至少不會(huì)差凰荚。
最后,還需要定時(shí)對(duì)基礎(chǔ)知識(shí)進(jìn)行復(fù)習(xí)褒脯,避免忘記便瑟,之后的計(jì)劃就是盡快通過(guò)緩考課程,進(jìn)行下一階段gin以及其他知識(shí)的學(xué)習(xí)憨颠,中間也要抽出時(shí)間準(zhǔn)備四級(jí)胳徽,今年12月份积锅,必過(guò)四級(jí)!Q痢缚陷!