站長(zhǎng)資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

28道PHP面試題,帶你梳理基礎(chǔ)知識(shí)!

本篇文章給大家整理分享28道PHP面試題(附答案分享),帶你梳理基礎(chǔ)知識(shí),有一定的參考價(jià)值,有需要的朋友可以參考一下,希望對(duì)大家有所幫助。

28道PHP面試題,帶你梳理基礎(chǔ)知識(shí)!

過(guò)完年之后打算尋找新的工作機(jī)會(huì),發(fā)現(xiàn)之前自己對(duì)于很多基礎(chǔ)的面試?yán)斫夂蛯W(xué)習(xí)不夠深刻,為了鼓勵(lì)自己持續(xù)前進(jìn)所以最近開(kāi)始在論壇和搜索引擎上開(kāi)始學(xué)習(xí)和總結(jié)相關(guān)知識(shí),其中有一些題目時(shí)論壇里面一些前輩分享過(guò)的題目或者答案,還有一部分時(shí)自己最近面試遇到的問(wèn)題,基于自己的理解和前輩們的分享歸檔了一部分,所以分享出來(lái),希望對(duì)其他的小伙伴們也有幫助,同時(shí)也希望能收到大佬們對(duì)于理解有誤的地方的指導(dǎo),最近一段時(shí)間會(huì)持續(xù)更新

本論壇的文章參考的比較多,優(yōu)先列出來(lái)大家參考,如下: https://learnku.com/articles/63520 https://learnku.com/php/t/47623 https://learnku.com/articles/28772

一、php 數(shù)組底層實(shí)現(xiàn)原理

1、底層實(shí)現(xiàn)是通過(guò)散列表(hash table) + 雙向鏈表(解決hash沖突)

  • hashtable:將不同的關(guān)鍵字(key)通過(guò)映射函數(shù)計(jì)算得到散列值(Bucket->h) 從而直接索引到對(duì)應(yīng)的Bucket

  • hash表保存當(dāng)前循環(huán)的指針,所以foreach 比f(wàn)or更快

  • Bucket:保存數(shù)組元素的key和value,以及散列值h

2、如何保證有序性

  • 1. 散列函數(shù)和元素?cái)?shù)組(Bucket)中間添加一層大小和存儲(chǔ)元素?cái)?shù)組相同的映射表。

  • 2. 用于存儲(chǔ)元素在實(shí)際存儲(chǔ)數(shù)組中的下標(biāo)

  • 3. 元素按照映射表的先后順序插入實(shí)際存儲(chǔ)數(shù)組中

  • 4. 映射表只是原理上的思路,實(shí)際上并不會(huì)有實(shí)際的映射表,而是初始化的時(shí)候分配Bucket內(nèi)存的同時(shí),還會(huì)分配相同數(shù)量的 uint32_t 大小的空間,然后將 arData 偏移到存儲(chǔ)元素?cái)?shù)組的位置。

3、解決hash重復(fù)(php使用的鏈表法):

  • 1. 鏈表法:不同關(guān)鍵字指向同一個(gè)單元時(shí),使用鏈表保存關(guān)鍵字(遍歷鏈表匹配key)

  • 2. 開(kāi)放尋址法:當(dāng)關(guān)鍵字指向已經(jīng)存在數(shù)據(jù)的單元的時(shí)候,繼續(xù)尋找其他單元,直到找到可用單元(占用其他單元位置,更容易出現(xiàn)hash沖突,性能下降)

4、基礎(chǔ)知識(shí)

  • 鏈表:隊(duì)列、棧、雙向鏈表、

  • 鏈表 :元素 + 指向下一元素的指針

  • 雙向鏈表:指向上一元素的指針 + 元素 + 指向下一元素的指針

參考:

  • 算法的時(shí)間與空間復(fù)雜度(一看就懂)

    https://zhuanlan.zhihu.com/p/50479555

  • LeetCode0:學(xué)習(xí)算法必備知識(shí):時(shí)間復(fù)雜度與空間復(fù)雜度的計(jì)算

    https://cloud.tencent.com/developer/article/1769988

二、冒泡排序的時(shí)間復(fù)雜度和空間復(fù)雜度

1、代碼實(shí)現(xiàn)

         $arr = [2, 4, 1, 5, 3, 6];          for ($i = 0; $i < (count($arr)); $i++) {              for ($j = $i + 1; $j < (count($arr)); $j++) {                  if ($arr[$i] <= $arr[$j]) {                      $temp = $arr[$i];                      $arr[$i] = $arr[$j];                      $arr[$j] = $temp;                  }              }          }      result : [6,5,4,3,2,1]

2、計(jì)算原理

  • 第一輪:將數(shù)組的第一個(gè)元素和其他所有的元素進(jìn)行比較,哪個(gè)元素更大,就換順序,從而冒泡出第一大(最大)的元素

  • 第一輪:將數(shù)組的第二個(gè)元素和其他所有的元素進(jìn)行比較(第一大已經(jīng)篩選出來(lái)不用繼續(xù)比較了),哪個(gè)元素更大,就換順序,從而冒泡出第二大的元素

  • … 依次類推,冒泡從大到小排序的數(shù)組

平均時(shí)間復(fù)雜度:O(n^2)

最優(yōu)時(shí)間復(fù)雜度:O(n) ,需要加判斷,第一次循環(huán)如果一次都沒(méi)有交換就直接跳出循環(huán)

空間復(fù)雜度:O(1),交換元素的時(shí)候的臨時(shí)變量占用的空間

最優(yōu)空間復(fù)雜度:O(1),排好序,不需要交換位置

3、時(shí)間復(fù)雜度和空間復(fù)雜度

時(shí)間復(fù)雜度:全程為漸進(jìn)時(shí)間復(fù)雜度,估算對(duì)處理器的使用效率(描述算法的效率趨勢(shì),并不是指算法具體使用的時(shí)間,因?yàn)椴煌瑱C(jī)器的性能不一致,只是一種效率計(jì)算的通用方法)

表示方法:大O符號(hào)表示法

復(fù)雜度量級(jí):

  • 常數(shù)階O(1)

  • 線性階O(n)

  • 平方階O(n2)

  • 立方階O(n3)

  • K次方階O(n^k)

  • 指數(shù)階(2^n)

  • 對(duì)數(shù)階O(logN)

  • 線性對(duì)數(shù)階O(nlogN)

時(shí)間復(fù)制類型:

  • 最好時(shí)間復(fù)雜度

  • 最壞時(shí)間復(fù)雜度

  • 平均時(shí)間復(fù)雜度

  • 均攤時(shí)間復(fù)雜度

空間復(fù)雜度:全程漸進(jìn)空間復(fù)雜度,估算對(duì)計(jì)算機(jī)內(nèi)存的使用程度(描述算法占用的存儲(chǔ)空間的趨勢(shì),不是實(shí)際占用空間,同上)

參考:

  • 算法的時(shí)間與空間復(fù)雜度(一看就懂)

    https://zhuanlan.zhihu.com/p/50479555

  • LeetCode0:學(xué)習(xí)算法必備知識(shí):時(shí)間復(fù)雜度與空間復(fù)雜度的計(jì)算

    https://cloud.tencent.com/developer/article/1769988

三、網(wǎng)絡(luò)七層協(xié)議及 TCP 和 TCP

應(yīng)用層、表示層、會(huì)話層、傳輸層、網(wǎng)絡(luò)層、(數(shù)據(jù))鏈路層、物理層

記憶套路:

首字:應(yīng)表會(huì)傳(物鏈網(wǎng))

第一個(gè)字:應(yīng)用層(出現(xiàn)次數(shù)多,易憶)

前四個(gè)正向:應(yīng)表 – 會(huì)傳

后三個(gè)反向:物聯(lián)網(wǎng)諧音比網(wǎng)鏈物更好記

四、TCP 和 UDP 的特點(diǎn)和區(qū)別

1、都是屬于傳輸層協(xié)議

2、TCP

  • 面向連接,所以只能一對(duì)一

  • 面向字節(jié)流傳輸

  • 數(shù)據(jù)可靠,不丟失

  • 全雙工通信

3、UDP(根據(jù)TCP特點(diǎn)反記)

  • 無(wú)連接,支持一對(duì)一,一對(duì)多,多對(duì)多

  • 面向保溫傳輸

  • 首部開(kāi)銷小,數(shù)據(jù)不一定可靠但是速度更快

參考:

  • github:colinlet/PHP-Interview-QA =>PHP 面試問(wèn)答 網(wǎng)絡(luò)篇

    https://github.com/colinlet/PHP-Interview-QA/blob/master/docs/01.網(wǎng)絡(luò).md#1-計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)

五、TCP 的三次握手和四次揮手

1、三次握手:

  • 1)第一次:客戶端發(fā)送SYN = 1,seq = client_isn

    作用:

    客戶端:無(wú)

    服務(wù)端:確認(rèn)自己的接收功能和客戶端的發(fā)送功能

  • 2)第二次:服務(wù)端發(fā)送SYN = 1,seq = server_isn,ACK =client_isn +1

    作用:

    客戶端:確認(rèn)自己發(fā)送和接收都正常,確認(rèn)服務(wù)端的接收和發(fā)送正常

    服務(wù)端:確認(rèn)自己的接收正常,確認(rèn)服務(wù)端的發(fā)送正常(這時(shí)候服務(wù)端還不能確認(rèn)客戶端接收是否正常)

  • 3)第三次:客戶端發(fā)送SYN = 0, ACK = server_isn+1,seq =client_isn+1

    作用:雙方確認(rèn)互相的接收和發(fā)送正常,建立連接

2、四次揮手

  • 1)第一次:客戶端發(fā)送FIN

    作用:告訴服務(wù)端我沒(méi)有數(shù)據(jù)發(fā)送了(但是還能接收數(shù)據(jù))

  • 2)第二次:服務(wù)端發(fā)送ACK

    作用:告訴客戶端收到請(qǐng)求了,可能服務(wù)端可能還有數(shù)據(jù)需要發(fā)送,所以客戶端收到進(jìn)入FIN_WAIT狀態(tài),等服務(wù)端數(shù)據(jù)傳輸完之后發(fā)送FIN

  • 3)第三次:服務(wù)端發(fā)送FIN

    作用:服務(wù)端告訴客戶端我發(fā)送完了,可以關(guān)閉連接了。

  • 4)第四次:客戶端發(fā)送ACK

    作用:客戶端收到FIN之后,擔(dān)心服務(wù)端不知道要關(guān)閉,所以發(fā)送一個(gè)ACK,進(jìn)入TIME_WAIT,等待2MSL之后如果沒(méi)有收到回復(fù),證明服務(wù)端已經(jīng)關(guān)閉了,這時(shí)候客戶端也關(guān)閉連接。

注意:

  • 當(dāng)收到對(duì)方的FIN報(bào)文時(shí),僅僅表示對(duì)方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)

  • 最后需要等待2MSL是因?yàn)榫W(wǎng)絡(luò)是不可靠的,如果服務(wù)端沒(méi)有收到最后一次ACK,服務(wù)端會(huì)重新放FIN包然后等客戶端再次發(fā)送ACK包然后關(guān)閉(所以客戶端最后發(fā)送ACK之后不能立即關(guān)閉連接)

參考:

  • github:colinlet/PHP-Interview-QA =>PHP 面試問(wèn)答 網(wǎng)絡(luò)篇

    https://github.com/colinlet/PHP-Interview-QA/blob/master/docs/01.網(wǎng)絡(luò).md#1-計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)

  • TCP 協(xié)議中的三次握手和四次揮手 (圖解)

    https://blog.csdn.net/whuslei/article/details/6667471

  • “三次握手,四次揮手” 你真的懂嗎?

    https://zhuanlan.zhihu.com/p/53374516

  • TCP 的特性

    https://hit-alibaba.github.io/interview/basic/network/TCP.html

六、HTTP 狀態(tài)碼

1、狀態(tài)碼分類

  • – 1xx:信息,服務(wù)器收到請(qǐng)求,需要請(qǐng)求者繼續(xù)操作

  • – 2xx:成功

  • – 3xx:重定向

  • – 4xx:客戶端錯(cuò)誤

  • – 5xx:服務(wù)端錯(cuò)誤

2、常用狀態(tài)碼

  • 200:請(qǐng)求成功

  • 301:永久重定向

  • 302:臨時(shí)移動(dòng)

  • 400 bad request:客戶端請(qǐng)求語(yǔ)法錯(cuò)誤

  • 401 unauthorized:客戶端沒(méi)有權(quán)限

  • 403 forbidden:服務(wù)器拒絕客戶端請(qǐng)求

  • 404 not found:客戶端請(qǐng)求資源不存在

  • 500 Internal Server Eerro:服務(wù)器內(nèi)部錯(cuò)誤

  • 502 bad gateway:作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從上游服務(wù)器接收到無(wú)效的響應(yīng)

  • 503 Service Unavailable 超載或系統(tǒng)維護(hù)

  • 504 Gateway timeout:網(wǎng)關(guān)超時(shí)

3、502 的原因及解決方法

原因:nginx將請(qǐng)求提交給網(wǎng)關(guān)(php-fpm)處理異常導(dǎo)致

1)fastcgi 緩沖區(qū)設(shè)置過(guò)小

fastcgi_buffers 8 16k;

fastcgi_buffer_size 32k;

2)php-cgi的進(jìn)程數(shù)設(shè)置過(guò)少

查看FastCgi進(jìn)程數(shù):netstat -anpo | grep "php-cgi"| wc -l

調(diào)整參數(shù)最大子進(jìn)程數(shù):max_children

一般按照單個(gè)進(jìn)程20M計(jì)算需要需要設(shè)置的子進(jìn)程數(shù)

3)max_requests(內(nèi)存溢出或頻繁重啟)

參數(shù)指明每個(gè)children最多能處理的請(qǐng)求數(shù)量,到達(dá)最大值之后會(huì)重啟children。

設(shè)置過(guò)小可能導(dǎo)致頻繁重啟children:

php將請(qǐng)求輪詢給每個(gè)children,在大流量的場(chǎng)景下,每一個(gè)children 到達(dá)最大值的時(shí)間差不多,如果設(shè)置過(guò)小可能多個(gè)children 在同一時(shí)間關(guān)閉,nginx無(wú)法將請(qǐng)求轉(zhuǎn)發(fā)給php-fpm,cpu降低,負(fù)載變高。

設(shè)置過(guò)大可能導(dǎo)致內(nèi)存泄露

4)php執(zhí)行時(shí)間超過(guò)nginx等待時(shí)間

fastcgi_connect_timeout

fastcgi_send_timeout

fastcgi_read_timeout

5)fastcgi執(zhí)行時(shí)間

max_execution_time

參考:

  • php+php-fom+nginx 配置參數(shù)調(diào)優(yōu)詳解

    http://www.voycn.com/article/phpphp-fomnginxpeizhicanshudiaoyouxiangjie

  • nginx 報(bào)錯(cuò) 502

    https://www.cnblogs.com/fengzhongzhuzu/p/9193355.html

七、http 和 HTTPS 的區(qū)別

1、端口:http 80; https :443

2、http無(wú)狀態(tài),https是有http + ssl構(gòu)建的可進(jìn)行加密傳輸?shù)膮f(xié)議

3、http明文傳輸,https加密傳輸

4、http更快,三次握手三個(gè)包,https 需要12個(gè)包(3個(gè)tcp包+9個(gè)ssl握手包)

八、redis 分布式鎖及問(wèn)題

1、實(shí)現(xiàn):

加鎖:setnx

解鎖:del

鎖超時(shí):expire

2、可能出現(xiàn)的問(wèn)題

  • 1)setnx 和expire非原子性問(wèn)題(加鎖之后還沒(méi)來(lái)得及設(shè)置超時(shí)就掛了)

    解決方案:

    Redis 2.6.12以上版本為set指令增加了可選參數(shù),偽代碼如下:set(key,1,30,NX),這樣就可以取代setnx指令

  • 2)超時(shí)誤刪其他進(jìn)程鎖。(A進(jìn)程執(zhí)行超時(shí),導(dǎo)致鎖釋放,這時(shí)候B進(jìn)程獲取鎖開(kāi)始處理請(qǐng)求,這時(shí)候A進(jìn)程處理完成,會(huì)誤刪B進(jìn)程的鎖)

    解決方案:只能刪除自己進(jìn)程的鎖 (lua腳本防止B進(jìn)程獲取過(guò)期鎖之后誤刪A進(jìn)程的鎖)

  • 3)并發(fā)場(chǎng)景,A進(jìn)程執(zhí)行超時(shí)導(dǎo)致鎖釋放,這時(shí)候B進(jìn)程獲取到鎖。

    解決方案:開(kāi)啟守護(hù)進(jìn)程,給當(dāng)前進(jìn)程要過(guò)期的鎖延時(shí)。

  • 4)單點(diǎn)實(shí)例安全問(wèn)題

    單機(jī)宕機(jī)之后導(dǎo)致所有客戶端無(wú)法獲取鎖

    解決:

    主從復(fù)制,因?yàn)槭钱惒酵瓿傻乃詿o(wú)法完全實(shí)現(xiàn)解決

參考:

  • 使用 Redis 作為分布式鎖的一些注意點(diǎn)

    https://www.cnblogs.com/gxyandwmm/p/9588383.html

  • 面試官:你真的了解 Redis 分布式鎖嗎?

    https://segmentfault.com/a/1190000038988087

九、redis 為什么是單線程?為什么快?

推薦閱讀:https://www.php.cn/redis/475918.html

十、redis 的數(shù)據(jù)類型及應(yīng)用場(chǎng)景

1、string :

普通的key/value存儲(chǔ)

2、hash:

hashmap:鍵值隊(duì)集合,存儲(chǔ)對(duì)象信息

3、list:

雙向鏈表:消息隊(duì)列

4、set:

value永遠(yuǎn)為null的hashMap:無(wú)序集合且不重復(fù):計(jì)算交集、并集、差集、去重值

5、zset:

有序集合且不重復(fù):hashMap(去重) + skiplist跳躍表(保證有序):排行榜

參考:

  • Redis 五種數(shù)據(jù)類型及應(yīng)用場(chǎng)景

    https://www.cnblogs.com/jasonZh/p/9513948.html

十一、redis 實(shí)現(xiàn)持久化的方式及原理、特點(diǎn)

1、RDB持久化(快照):指定時(shí)間間隔內(nèi)的內(nèi)存數(shù)據(jù)集快照寫(xiě)入磁盤(pán)

1)fork一個(gè)子進(jìn)程,將快照內(nèi)容寫(xiě)入臨時(shí)RDB文件中(dump.rdb),當(dāng)子進(jìn)程寫(xiě)完快照內(nèi)容之后新的文件替換老的文件

2)整個(gè)redis數(shù)據(jù)庫(kù)只包含一個(gè)備份文件

3)性能最大化,只需要fork子進(jìn)程完成持久化工作,減少磁盤(pán)IO

4)持久化之前宕機(jī)可能會(huì)導(dǎo)致數(shù)據(jù)丟失

2、AOF持久化 :以日志的形式記錄服務(wù)器的所有的寫(xiě)、刪除操作

1)每接收到一個(gè)寫(xiě)的命令用write函數(shù)追加到文件appendonly.aof

2)持久化的文件會(huì)越來(lái)越大,存在大量多余的日志(0 自增100次到100,會(huì)產(chǎn)生100條日志記錄)

3)可以設(shè)置不同的fsync策略

  • appendfsync everysec :1s一次,最多丟失1s的數(shù)據(jù)(默認(rèn))

  • appendfsync always :每次變動(dòng)都會(huì)執(zhí)行一次

  • appendfsync no :不處理

4)AOF文件太大之后會(huì)進(jìn)行重寫(xiě):壓縮AOF文件大小

  • fork一個(gè)子進(jìn)程,將redis內(nèi)地?cái)?shù)據(jù)對(duì)象的最新?tīng)顟B(tài)寫(xiě)入AOF臨時(shí)文件(類似rdb快照)

  • 主進(jìn)程收到的變動(dòng)會(huì)先寫(xiě)入內(nèi)存中,然后同步到老的AOF文件中(重寫(xiě)失敗之后也能保證數(shù)據(jù)完整性)

  • 子進(jìn)程完成重寫(xiě)之后會(huì)將內(nèi)存中的新變動(dòng)同步追加到AOF的臨時(shí)文件中

  • 父進(jìn)程將臨時(shí)AOF文件替換成新的AOF文件,并重命名。之后收到的新命令寫(xiě)入到新的文件中

參考:

  • Redis 專題:萬(wàn)字長(zhǎng)文詳解持久化原理

    https://segmentfault.com/a/1190000039208726

  • Redis 持久化

    https://segmentfault.com/a/1190000002906345

  • RDB 和 AOF 持久化的原理是什么?我應(yīng)該用哪一個(gè)?它們的優(yōu)缺點(diǎn)?

    https://segmentfault.com/a/1190000018388385

十二、秒殺設(shè)計(jì)流程及難點(diǎn)

1、靜態(tài)緩存

2、nginx 負(fù)載均衡

三種方式:DNS輪詢、IP負(fù)債均衡、CDN

3、限流機(jī)制

方式:ip限流、接口令牌限流、用戶限流、header動(dòng)態(tài)token(前端加密,后端解密)

4、分布式鎖

方式:

  • setnx + expire (非原子性,redis2.6 之后set保證原子性)

  • 釋放鎖超時(shí) (開(kāi)啟守護(hù)進(jìn)程自動(dòng)續(xù)時(shí)間)

  • 過(guò)期鎖誤刪其他線程(requestId驗(yàn)證或者lua腳本保證查 + 刪的原子性)

5、緩存數(shù)據(jù)

方式:

  • 緩存擊穿:緩存數(shù)據(jù)預(yù)熱 + 布隆過(guò)濾器/空緩存

  • 緩存雪崩:緩存設(shè)置隨機(jī)過(guò)期時(shí)間,防止同一時(shí)間過(guò)期

6、庫(kù)存及訂單

  • 扣庫(kù)存

    • redis 自減庫(kù)存,并發(fā)場(chǎng)景下可能導(dǎo)致負(fù)數(shù),影響庫(kù)存回倉(cāng):使用lua腳本保證原子性

    • redis預(yù)扣庫(kù)存之后,然后使用異步消息創(chuàng)建訂單并更新庫(kù)存變動(dòng)

    • 數(shù)據(jù)庫(kù)更新庫(kù)存使用樂(lè)觀鎖:where stock_num – sell_num > 0

    • 添加消息發(fā)送記錄表及重試機(jī)制,防止異步消息丟失

  • 創(chuàng)建訂單

    • 前端建立websocket連接或者輪詢監(jiān)聽(tīng)訂單狀態(tài)

    • 消費(fèi)驗(yàn)證記錄狀態(tài),防止重復(fù)消費(fèi)

  • 回倉(cāng)

    • 創(chuàng)建訂單之后發(fā)送延時(shí)消息,驗(yàn)證訂單支付狀態(tài)及庫(kù)存是否需要回倉(cāng)

十三、防 sql 注入

1、過(guò)濾特殊字符

2、過(guò)濾數(shù)據(jù)庫(kù)關(guān)鍵字

3、驗(yàn)證數(shù)據(jù)類型及格式

4、使用預(yù)編譯模式,綁定變量

十四、事務(wù)隔離級(jí)別

1、標(biāo)準(zhǔn)的sql隔離級(jí)別實(shí)現(xiàn)原理

  • 未提交讀:其他事務(wù)可以直接讀到?jīng)]有提交的:臟讀

    • 事務(wù)對(duì)當(dāng)前被讀取的數(shù)據(jù)不加鎖

    • 在更新的瞬間加行級(jí)共享鎖到事務(wù)結(jié)束釋放

  • 提交讀:事務(wù)開(kāi)始和結(jié)束之間讀取的數(shù)據(jù)可能不一致,事務(wù)中其他事務(wù)修改了數(shù)據(jù):不可重復(fù)度

    • 事務(wù)對(duì)當(dāng)前讀取的數(shù)據(jù)(被讀到的時(shí)候)行級(jí)共享鎖,讀完釋放

    • 在更新的瞬間加行級(jí)排他鎖到事務(wù)結(jié)束釋放

  • 可重復(fù)讀:事務(wù)開(kāi)始和結(jié)束之前讀取的數(shù)據(jù)保持一致,事務(wù)中其他事務(wù)不能修改數(shù)據(jù):可重復(fù)讀

    • 事務(wù)對(duì)當(dāng)前讀到的數(shù)據(jù)從事務(wù)一開(kāi)始就加一個(gè)行級(jí)共享鎖

    • 在更新的瞬間加行級(jí)排他鎖到事務(wù)結(jié)束釋放

    • 其他事務(wù)再事務(wù)過(guò)程中可能會(huì)新增數(shù)據(jù)導(dǎo)致幻讀

  • 串行化

    • 事務(wù)讀取數(shù)據(jù)時(shí)加表級(jí)共享鎖

    • 事務(wù)更新數(shù)據(jù)時(shí)加表級(jí)排他鎖

2、innodb的事務(wù)隔離級(jí)別及實(shí)現(xiàn)原理(!!和上面的不一樣,區(qū)分理解一個(gè)是隔離級(jí)別 一個(gè)是!!事務(wù)!!隔離級(jí)別)

1)基本概念

  • mvcc:多版本并發(fā)控制:依賴于undo log 和read view

    • 讓數(shù)據(jù)都讀不會(huì)對(duì)數(shù)據(jù)加鎖,提高數(shù)據(jù)庫(kù)并發(fā)處理能力

    • 寫(xiě)操作才會(huì)加鎖

    • 一條數(shù)據(jù)有多個(gè)版本,每次事務(wù)更新數(shù)據(jù)的時(shí)候會(huì)生成一個(gè)新的數(shù)據(jù)版本,舊的數(shù)據(jù)保留在undo log

    • 一個(gè)事務(wù)啟動(dòng)的時(shí)候只能看到所有已經(jīng)提交的事務(wù)結(jié)果

  • 當(dāng)前讀:讀取的是最新版本

  • 快照讀:讀取的是歷史版本

  • 間隙鎖:間隙鎖會(huì)鎖住一個(gè)范圍內(nèi)的索引

    • update id between 10 and 20

    • 無(wú)論是否范圍內(nèi)是否存在數(shù)據(jù),都會(huì)鎖住整個(gè)范圍:insert id = 15,將被防止

    • 只有可重復(fù)讀隔離級(jí)別才有間隙鎖

  • next-key lock:

    • 索引記錄上的記錄鎖+ 間隙鎖(索引值到前一個(gè)索引值之間的間隙鎖)

    • 前開(kāi)后閉

    • 阻止幻讀

2)事務(wù)隔離級(jí)別

  • 未提交讀

    • 事務(wù)對(duì)當(dāng)前讀取的數(shù)據(jù)不加鎖,都是當(dāng)前讀

    • 在更新的瞬間加行級(jí)共享鎖到事務(wù)結(jié)束釋放

  • 提交讀

    • 事務(wù)對(duì)當(dāng)前讀取的數(shù)據(jù)不加鎖,都是快照讀

    • 在更新的瞬間加行級(jí)排他鎖到事務(wù)結(jié)束釋放

  • 可重復(fù)讀

    • 事務(wù)對(duì)當(dāng)前讀取的數(shù)據(jù)不加鎖,都是快照讀

    • 事務(wù)再更新某數(shù)據(jù)的瞬間,必須加行級(jí)排他鎖(Record 記錄鎖、GAP間隙鎖、next-key 鎖),事務(wù)結(jié)束釋放

    • 間隙鎖解決的是幻讀問(wèn)題

      • 主從復(fù)制的情況下 ,如果沒(méi)有間隙鎖,master庫(kù)的A、B進(jìn)程

      • A進(jìn)程 delete id < 6 ;然后還沒(méi)有commit

      • B進(jìn)程insert id = 3,commit

      • A進(jìn)程提交commit

      • 該場(chǎng)景下,主庫(kù)會(huì)存在一條id =3 的記錄,但是binlog里面是先刪除再新增就會(huì)導(dǎo)致從庫(kù)沒(méi)有數(shù)據(jù),導(dǎo)致主從的數(shù)據(jù)不一致

    • MVCC的快照解決的是不可重復(fù)讀問(wèn)題

  • 串行化

    • 事務(wù)讀取數(shù)據(jù)時(shí)加表級(jí),當(dāng)前讀

    • 事務(wù)更新數(shù)據(jù)時(shí)加表級(jí)排他鎖

參考:

  • 深入理解 MySQL 中事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理

    https://segmentfault.com/a/1190000025156465

  • 小胖問(wèn)我:MySQL 事務(wù)與 MVCC 原理

    https://segmentfault.com/a/1190000039809030

  • 快照在 MVCC 中是怎么工作的?

    https://www.jianshu.com/p/6c4454ffecc3

  • MVCC 我知道,但是為什么要設(shè)計(jì)間隙鎖?

    https://www.jianshu.com/p/fbec6d1fa16c

  • 間隙鎖和 next-key lock

    https://www.jianshu.com/p/d1aba64b5c03

十五、索引原理

索引就是幫助數(shù)據(jù)庫(kù)高效查找數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu),存儲(chǔ)再磁盤(pán)中,需要消耗磁盤(pán)IO

1、存儲(chǔ)引擎

  • myisam 支持表鎖,索引和數(shù)據(jù)分開(kāi)存儲(chǔ)適合跨服務(wù)器遷移

  • innodb 支持行鎖,索引和數(shù)據(jù)存儲(chǔ)再一個(gè)文件

2、索引類型

  • hash索引

    • 適合精確查詢且效率高

    • 無(wú)法排序、不適合范圍查詢

    • hash沖突的情況下需要遍歷鏈表(php數(shù)組的實(shí)現(xiàn)原理、redis zset 的實(shí)現(xiàn)原理類似)

  • b-tree、b+tree

    • b-tree 和b+tree的去區(qū)別

      • b+tree 的數(shù)據(jù)全部存儲(chǔ)在葉子節(jié)點(diǎn),內(nèi)部節(jié)點(diǎn)只存key,一次磁盤(pán)IO能獲取到

贊(0)
分享到: 更多 (0)
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久精品国产一区二区电影| 欧美日韩一区二区成人午夜电影 | 三上悠亚国产精品一区| 日韩免费人妻AV无码专区蜜桃| 午夜精品视频在线| 日韩人妻无码精品专区| 国产免费无遮挡精品视频| 亚洲AV成人精品日韩一区| 亚洲精品成人无码中文毛片不卡| 国产精品午夜高清在线观看| 99re热免费精品视频观看| 91久久福利国产成人精品| 99精品视频观看| 国产精品二区观看| 黄大色黄美女精品大毛片| 亚洲av日韩av天堂影片精品| 国产亚洲女在线线精品| 国产精品综合在线| 亚洲精品午夜视频| 国自产精品手机在线观看视频| 国产天堂亚洲精品| 国产精品电影网在线好看| 四虎精品在线视频| 国产欧美另类久久久精品图片| 国产69精品久久久久观看软件| 国内精品免费麻豆网站91麻豆 | 精品无人区麻豆乱码无限制| 亚洲精品美女视频| 久久亚洲AV无码精品色午夜麻豆| 99久久久国产精品免费牛牛四川| 久久水蜜桃亚洲av无码精品麻豆| 亚洲日本精品一区二区| 久久久久无码精品国产不卡| 久久精品亚洲一区二区三区浴池| 99精品热女视频专线| 久久久精品国产sm调教网站| 久久99精品久久久久婷婷| 2019天堂精品视频在线观看| 精品国产污污免费网站aⅴ| 久久久久夜夜夜精品国产| 一级A毛片免费观看久久精品|