一、 PHP部分
PHP如何實(shí)現(xiàn)靜態(tài)化
PHP的靜態(tài)化分為:純靜態(tài)和偽靜態(tài)。其中純靜態(tài)又分為:局部純靜態(tài)和全部純靜態(tài)。
PHP偽靜態(tài):利用Apache mod_rewrite實(shí)現(xiàn)URL重寫(xiě)的方法;
PHP純靜態(tài),就是生成HTML文件的方式,我們須要開(kāi)啟PHP自帶的緩存機(jī)制,即ob_start來(lái)開(kāi)啟緩存。
PHP經(jīng)典四大排序算法
PHP的四種基本排序算法為:冒泡排序、插入排序、選擇排序和快速排序。
冒泡排序:對(duì)數(shù)組進(jìn)行多輪冒泡,每一輪對(duì)數(shù)組中的元素兩兩比較,調(diào)整位置,冒出一個(gè)最大的數(shù)來(lái)。
插入排序:假設(shè)組前面的元素是排好序的,遍歷數(shù)組后面的元素,在已排好序的元素隊(duì)列中找到合適的位置,插入其中。
選擇排序:進(jìn)行多次選擇,每次選出最大元素放入指定位置。
快速排序:遞歸算法。先選擇數(shù)組的第一個(gè)元素作為標(biāo)準(zhǔn),然后把小于或等于它和大于它的數(shù)分別放入兩個(gè)數(shù)組中,對(duì)這兩個(gè)數(shù)組也進(jìn)行相同的處理,最后合并這兩個(gè)數(shù)組和第一個(gè)元素。
PHP常見(jiàn)運(yùn)行模式
1)CGI(通用網(wǎng)關(guān)接口/ Common Gateway Interface)
2)FastCGI(常駐型CGI / Long-Live CGI)lamp
3)CLI(命令行運(yùn)行 / Command Line Interface)
4)Web模塊模式(Apache等Web服務(wù)器運(yùn)行的模式)
5)ISAPI(Internet Server Application Program Interface)
你了解設(shè)計(jì)模式嗎?說(shuō)下你最常用的設(shè)計(jì)模式
大概有23種設(shè)計(jì)模式,PHP常見(jiàn)的大概有10幾種,雖然不算是基礎(chǔ),但是你必須要懂得。
總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類(lèi):
1、創(chuàng)建型模式共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
2、結(jié)構(gòu)型模式共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
3、行為型模式共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問(wèn)者模式、中介者模式、解釋器模式。

觀察者模式是如何實(shí)現(xiàn)的?工廠模式是如何實(shí)現(xiàn)的?適配器模式是如何實(shí)現(xiàn)的?……
觀察者模式:定義了對(duì)象之間的一對(duì)多依賴,這樣一來(lái),當(dāng)一個(gè)對(duì)象改變狀態(tài)時(shí),它的所有依賴者都會(huì)收到通知并且有所作為。即出版者+訂閱者=觀察者模式。
工廠模式 :將調(diào)用者和創(chuàng)建者分離,調(diào)用者直接向工廠類(lèi)請(qǐng)求獲取調(diào)用對(duì)象,減少代碼耦合,提高系統(tǒng)的維護(hù)性和擴(kuò)展性;
工廠模式應(yīng)用場(chǎng)景:有多個(gè)產(chǎn)品類(lèi)時(shí)就要用到工廠模式,比如在數(shù)據(jù)庫(kù)連接中,我們可以采用多種數(shù)據(jù)庫(kù)連接方法,有mysql擴(kuò)展,mysqli擴(kuò)展,PDO擴(kuò)展等,在這種情況下我們可以一個(gè)擴(kuò)展對(duì)應(yīng)一個(gè)產(chǎn)品類(lèi),然后采用工廠模式。
適配器模式核心思想:把對(duì)某些相似的類(lèi)的操作轉(zhuǎn)化為一個(gè)統(tǒng)一的“接口”(這里是比喻的說(shuō)話)–適配器,或者比喻為一個(gè)“界面”,統(tǒng)一或屏蔽了那些類(lèi)的細(xì)節(jié)。適配器模式還構(gòu)造了一種“機(jī)制”,使“適配”的類(lèi)可以很容易的增減,而不用修改與適配器交互的代碼,符合“減少代碼間耦合”的設(shè)計(jì)原則。
PHP的優(yōu)化方案
1.如果一個(gè)方法可靜態(tài)化,就對(duì)它做靜態(tài)聲明。速率可提升至4倍。
2.echo 比 print 快。
3.使用echo的多重參數(shù)(譯注:指用逗號(hào)而不是句點(diǎn))代替字符串連接。
4.在執(zhí)行for循環(huán)之前確定最大循環(huán)數(shù),不要每循環(huán)一次都計(jì)算最大值。
5.注銷(xiāo)那些不用的變量尤其是大數(shù)組,以便釋放內(nèi)存。
6.盡量避免使用__get,__set,__autoload。
7.require_once()代價(jià)昂貴。
8.在包含文件時(shí)使用完整路徑,解析操作系統(tǒng)路徑所需的時(shí)間會(huì)更少。
9.如果你想知道腳本開(kāi)始執(zhí)行(譯注:即服務(wù)器端收到客戶端請(qǐng)求)的時(shí)刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。
10.函數(shù)代替正則表達(dá)式完成相同功能。
11.str_replace函數(shù)比preg_replace函數(shù)快,但strtr函數(shù)的效率是str_replace函數(shù)的四倍。
12.如果一個(gè)字符串替換函數(shù),可接受數(shù)組或字符作為參數(shù),并且參數(shù)長(zhǎng)度不太長(zhǎng),那么可以考慮額外寫(xiě)一段替換代碼,使得每次傳遞參數(shù)是一個(gè)字符,而不是只寫(xiě)一行代碼接受數(shù)組作為查詢和替換的參數(shù)。
13.使用選擇分支語(yǔ)句(譯注:即switch case)好于使用多個(gè)if,else if語(yǔ)句。
14.用@屏蔽錯(cuò)誤消息的做法非常低效。
15.打開(kāi)apache的mod_deflate模塊。
16.數(shù)據(jù)庫(kù)連接當(dāng)使用完畢時(shí)應(yīng)關(guān)掉。
17.$row[‘id’]的效率是$row[id]的7倍。
18.錯(cuò)誤消息代價(jià)昂貴。
19.盡量不要在for循環(huán)中使用函數(shù),比如for ($x=0; $x < count($array); $x)每循環(huán)一次都會(huì)調(diào)用count()函數(shù)。
20.在方法中遞增局部變量,速度是最快的。幾乎與在函數(shù)中調(diào)用局部變量的速度相當(dāng)。
21.遞增一個(gè)全局變量要比遞增一個(gè)局部變量慢2倍。
22.遞增一個(gè)對(duì)象屬性(如:$this->prop++)要比遞增一個(gè)局部變量慢3倍。
23.遞增一個(gè)未預(yù)定義的局部變量要比遞增一個(gè)預(yù)定義的局部變量慢9至10倍。
24.僅定義一個(gè)局部變量而沒(méi)在函數(shù)中調(diào)用它,同樣會(huì)減慢速度(其程度相當(dāng)于遞增一個(gè)局部變量)。PHP大概會(huì)檢查看是否存在全局變量。
25.方法調(diào)用看來(lái)與類(lèi)中定義的方法的數(shù)量無(wú)關(guān),因?yàn)槲?在測(cè)試方法之前和之后都)添加了10個(gè)方法,但性能上沒(méi)有變化。
26.派生類(lèi)中的方法運(yùn)行起來(lái)要快于在基類(lèi)中定義的同樣的方法。
27.調(diào)用帶有一個(gè)參數(shù)的空函數(shù),其花費(fèi)的時(shí)間相當(dāng)于執(zhí)行7至8次的局部變量遞增操作。類(lèi)似的方法調(diào)用所花費(fèi)的時(shí)間接近于15次的局部變量遞增操作。
28.用單引號(hào)代替雙引號(hào)來(lái)包含字符串,這樣做會(huì)更快一些。因?yàn)镻HP會(huì)在雙引號(hào)包圍的字符串中搜尋變量,單引號(hào)則不會(huì)
說(shuō)下你了解的session和cookie
1、存儲(chǔ)位置不同
cookie的數(shù)據(jù)信息存放在客戶端瀏覽器上。
session的數(shù)據(jù)信息存放在服務(wù)器上。
2、存儲(chǔ)容量不同
單個(gè)cookie保存的數(shù)據(jù)<=4KB,一個(gè)站點(diǎn)最多保存20個(gè)Cookie。
對(duì)于session來(lái)說(shuō)并沒(méi)有上限,但出于對(duì)服務(wù)器端的性能考慮,session內(nèi)不要存放過(guò)多的東西,并且設(shè)置session刪除機(jī)制。
3、存儲(chǔ)方式不同
cookie中只能保管ASCII字符串,并需要通過(guò)編碼方式存儲(chǔ)為Unicode字符或者二進(jìn)制數(shù)據(jù)。
session中能夠存儲(chǔ)任何類(lèi)型的數(shù)據(jù),包括且不限于string,integer,list,map等。
4、隱私策略不同
cookie對(duì)客戶端是可見(jiàn)的,別有用心的人可以分析存放在本地的cookie并進(jìn)行cookie欺騙,所以它是不安全的。
session存儲(chǔ)在服務(wù)器上,對(duì)客戶端是透明對(duì),不存在敏感信息泄漏的風(fēng)險(xiǎn)。
5、有效期上不同
開(kāi)發(fā)可以通過(guò)設(shè)置cookie的屬性,達(dá)到使cookie長(zhǎng)期有效的效果。
session依賴于名為JSESSIONID的cookie,而cookie JSESSIONID的過(guò)期時(shí)間默認(rèn)為-1,只需關(guān)閉窗口該session就會(huì)失效,因而session不能達(dá)到長(zhǎng)期有效的效果。
6、服務(wù)器壓力不同
cookie保管在客戶端,不占用服務(wù)器資源。對(duì)于并發(fā)用戶十分多的網(wǎng)站,cookie是很好的選擇。
session是保管在服務(wù)器端的,每個(gè)用戶都會(huì)產(chǎn)生一個(gè)session。假如并發(fā)訪問(wèn)的用戶十分多,會(huì)產(chǎn)生十分多的session,耗費(fèi)大量的內(nèi)存。
7、瀏覽器支持不同
假如客戶端瀏覽器不支持cookie:
cookie是需要客戶端瀏覽器支持的,假如客戶端禁用了cookie,或者不支持cookie,則會(huì)話跟蹤會(huì)失效。關(guān)于WAP上的應(yīng)用,常規(guī)的cookie就派不上用場(chǎng)了。
運(yùn)用session需要使用URL地址重寫(xiě)的方式,就是把session id附加在URL路徑的后面,附加的方式也有兩種,一種是作為URL路徑的附加信息,另一種是作為查詢字符串附加在URL后面。。一切用到session程序的URL都要進(jìn)行URL地址重寫(xiě),否則session會(huì)話跟蹤還會(huì)失效。
假如客戶端支持cookie:
cookie既能夠設(shè)為本瀏覽器窗口以及子窗口內(nèi)有效,也能夠設(shè)為一切窗口內(nèi)有效。
session只能在本窗口以及子窗口內(nèi)有效。
8、跨域支持上不同
cookie支持跨域名訪問(wèn)。
session不支持跨域名訪問(wèn)。
如何實(shí)現(xiàn)不基于session和cookie的用戶認(rèn)證。
將用戶信息加密放到http的header部分,每次拿到http的時(shí)候,驗(yàn)證獲取header的信息。
什么是CSRF攻擊,XSS攻擊?如何防范
CSRF(Cross-site request forgery)跨站請(qǐng)求偽造,黑客建立一個(gè)偽造網(wǎng)站或發(fā)送郵箱帶了一個(gè)正常URL鏈接來(lái)讓正常用戶訪問(wèn),來(lái)讓正常用戶讓自己瀏覽器里的COOKIE權(quán)限來(lái)執(zhí)行一些非法請(qǐng)求,
如轉(zhuǎn)賬,提權(quán)等操作,
防范方法有,驗(yàn)證 HTTP Referer 字段;在請(qǐng)求地址中添加 token 并驗(yàn)證;
XSS攻擊
主要將XSS代碼提交存儲(chǔ)在服務(wù)器端(數(shù)據(jù)庫(kù),內(nèi)存,文件系統(tǒng)等),下次請(qǐng)求目標(biāo)頁(yè)面時(shí)不用再提交XSS代碼。當(dāng)目標(biāo)用戶訪問(wèn)該頁(yè)面獲取數(shù)據(jù)時(shí),XSS代碼會(huì)從服務(wù)器解析之后加載出來(lái),返回到瀏覽器做正常的HTML和JS解析執(zhí)行,XSS攻擊就發(fā)生了。
防范方法:通過(guò)過(guò)濾是針對(duì)非法的HTML代碼包括單雙引號(hào)等,使用htmlspecialchars()函數(shù)
你了解RESTful API嗎?說(shuō)說(shuō)干什么用的。
RESTful API是REST風(fēng)格的API,是一套用來(lái)規(guī)范多種形式的前端和同一個(gè)后臺(tái)的交互方式的協(xié)議。RESTful API由后臺(tái)也就是SERVER來(lái)提供前端來(lái)調(diào)用;前端調(diào)用API向后臺(tái)發(fā)起HTTP請(qǐng)求,后臺(tái)響應(yīng)請(qǐng)求將處理結(jié)果反饋給前端。
php設(shè)計(jì)模式六大原則
單一職責(zé)原則:不要存在多于一個(gè)導(dǎo)致類(lèi)變更的原因。通俗的說(shuō),即一個(gè)類(lèi)只負(fù)責(zé)一項(xiàng)職責(zé)。
開(kāi)放封閉原則:一個(gè)軟件實(shí)體如類(lèi)、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。
里氏替換原則:所有引用基類(lèi)的地方必須能透明地使用其子類(lèi)的對(duì)象。
接口隔離原則:客戶端不應(yīng)該依賴它不需要的接口;一個(gè)類(lèi)對(duì)另一個(gè)類(lèi)的依賴應(yīng)該建立在最小的接口上。
迪米特原則:一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象保持最少的了解。
依賴倒置原則:高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象。
如何實(shí)現(xiàn)自動(dòng)加載?不用composer如何實(shí)現(xiàn)?PSR-4是什么?
自動(dòng)加載就是當(dāng)我們?cè)诋?dāng)前文件中實(shí)例化一個(gè)不存在的類(lèi)時(shí),調(diào)用自動(dòng)加載機(jī)制引入相應(yīng)的類(lèi)文件。
注:自動(dòng)加載有兩種方式(都是php內(nèi)置的),一種是通過(guò)__autoload(),另一種是通過(guò)spl_autoload_register()。
PSR是PHP Standards Recommendation的簡(jiǎn)稱,制定的代碼規(guī)范,簡(jiǎn)稱PSR,是代碼開(kāi)發(fā)的事實(shí)標(biāo)準(zhǔn)。
PSR-4使代碼更加規(guī)范,能夠滿足面向package的自動(dòng)加載,它規(guī)范了如何從文件路徑自動(dòng)加載類(lèi),同時(shí)規(guī)范了自動(dòng)加載文件的位置。
抽象類(lèi)和接口分別是什么,他們區(qū)別?
抽象類(lèi):是基于類(lèi)來(lái)說(shuō),其本身就是類(lèi),只是一種特殊的類(lèi),不能直接實(shí)例,可以在類(lèi)里定義方法,屬性。類(lèi)似于模版,規(guī)范后讓子類(lèi)實(shí)現(xiàn)詳細(xì)功能。
接口(Interface)—— 定義行為
抽象類(lèi)(Abstract Class) —— 實(shí)現(xiàn)行為
具體類(lèi)(class)——執(zhí)行行為
接口:主要基于方法的規(guī)范,有點(diǎn)像抽象類(lèi)里的抽象方法,只是其相對(duì)于抽象方法來(lái)說(shuō),更加獨(dú)立??勺屇硞€(gè)類(lèi)通過(guò)組合多個(gè)方法來(lái)形成新的類(lèi)。
抽象類(lèi)與接口的相同點(diǎn):
1、都是用于聲明某一種事物,規(guī)范名稱、參數(shù),形成模塊,未有詳細(xì)的實(shí)現(xiàn)細(xì)節(jié)。
2、都是通過(guò)類(lèi)來(lái)實(shí)現(xiàn)相關(guān)的細(xì)節(jié)工作
3、語(yǔ)法上,抽象類(lèi)的抽象方法與接口一樣,不能有方法體,即{}符號(hào)
4、都可以用繼承,接口可以繼承接口形成新的接口,抽象類(lèi)可以繼承抽象類(lèi)從而形成新的抽象類(lèi)
抽象類(lèi)與接口的不同點(diǎn):
1、抽象類(lèi)可以有屬性、普通方法、抽象方法,但接口不能有屬性、普通方法、可以有常量
2、抽象類(lèi)內(nèi)未必有抽象方法,但接口內(nèi)一定會(huì)有“抽象”方法
3、語(yǔ)法上有不同
4、抽象類(lèi)用abstract關(guān)鍵字在類(lèi)前聲明,且有class聲明為類(lèi),接口是用interface來(lái)聲明,但不能用class來(lái)聲明,因?yàn)榻涌诓皇穷?lèi)。
5、抽象類(lèi)的抽象方法一定要用abstract來(lái)聲明,而接口則不需要
6、抽象類(lèi)是用extends關(guān)鍵字讓子類(lèi)繼承父類(lèi)后,在子類(lèi)實(shí)現(xiàn)詳細(xì)的抽象方法。而接口則是用implements讓普通類(lèi)在類(lèi)里實(shí)現(xiàn)接口的詳細(xì)方法,且接口可以一次性實(shí)現(xiàn)多個(gè)方法,用逗號(hào)分開(kāi)各個(gè)接口就可
微服務(wù)的了解
概念:又稱微服務(wù)架構(gòu),是一種架構(gòu)風(fēng)格,它將應(yīng)用程序構(gòu)建為以業(yè)務(wù)領(lǐng)域?yàn)槟P偷男⌒妥灾畏?wù)集合 。
優(yōu)勢(shì):
獨(dú)立開(kāi)發(fā) – 所有微服務(wù)都可以根據(jù)各自的功能輕松開(kāi)發(fā)
獨(dú)立部署 – 基于其服務(wù),可以在任何應(yīng)用程序中單獨(dú)部署它們
故障隔離 – 即使應(yīng)用程序的一項(xiàng)服務(wù)不起作用,系統(tǒng)仍可繼續(xù)運(yùn)行
混合技術(shù)堆棧 – 可以使用不同的語(yǔ)言和技術(shù)來(lái)構(gòu)建同一應(yīng)用程序的不同服務(wù)
粒度縮放 – 單個(gè)組件可根據(jù)需要進(jìn)行縮放,無(wú)需將所有組件縮放在一起
特點(diǎn):
解耦 – 系統(tǒng)內(nèi)的服務(wù)很大程度上是分離的。因此,整個(gè)應(yīng)用程序可以輕松構(gòu)建,更改和擴(kuò)展
組件化 – 微服務(wù)被視為可以輕松更換和升級(jí)的獨(dú)立組件
業(yè)務(wù)能力 – 微服務(wù)非常簡(jiǎn)單,專注于單一功能
自治 – 開(kāi)發(fā)人員和團(tuán)隊(duì)可以彼此獨(dú)立工作,從而提高速度
持續(xù)交付 – 通過(guò)軟件創(chuàng)建,測(cè)試和批準(zhǔn)的系統(tǒng)自動(dòng)化,允許頻繁發(fā)布軟件
責(zé)任 – 微服務(wù)不關(guān)注應(yīng)用程序作為項(xiàng)目。相反,他們將應(yīng)用程序視為他們負(fù)責(zé)的產(chǎn)品
分散治理 – 重點(diǎn)是使用正確的工具來(lái)做正確的工作。這意味著沒(méi)有標(biāo)準(zhǔn)化模式或任何技術(shù)模式。開(kāi)發(fā)人員可以自由選擇最有用的工具來(lái)解決他們的問(wèn)題
敏捷 – 微服務(wù)支持敏捷開(kāi)發(fā)。任何新功能都可以快速開(kāi)發(fā)并再次丟棄
垃圾回收機(jī)制
php7的垃圾回收包含兩個(gè)部分,一個(gè)是垃圾收集器,一個(gè)是垃圾回收算法。
垃圾收集器,把剛剛提到的,可能是垃圾的元素收集到回收池中 也就是把變量的 zend_refcount>0的變量 放在回收池中。 當(dāng)回收池的值達(dá)到一定額度了,會(huì)進(jìn)行統(tǒng)一遍歷處理。進(jìn)行模擬刪除,如果zend_refcount=0那就認(rèn)為是垃圾,直接刪除它。 遍歷回收池中的每一個(gè)變量,根據(jù)每一個(gè)變量,再遍歷每一個(gè)成員,如果成員還有嵌套的話繼續(xù)遍歷。然后把所有成員的 做模擬的 refcount -1。如果此時(shí)外部的變量的 引用次數(shù)為 0 。那么可以視為垃圾,清楚。如果大于0,那么恢復(fù)引用次數(shù),并從垃圾回收池中取出。
高并發(fā)解決方案
1、流量?jī)?yōu)化
防盜鏈處理(去除惡意請(qǐng)求)
2、前端優(yōu)化
(1) 減少HTTP請(qǐng)求[將css,js等合并]
(2) 添加異步請(qǐng)求(先不將所有數(shù)據(jù)都展示給用戶,用戶觸發(fā)某個(gè)事件,才會(huì)異步請(qǐng)求數(shù)據(jù))
(3) 啟用瀏覽器緩存和文件壓縮
(4) CDN加速
(5) 建立獨(dú)立的圖片服務(wù)器(減少I(mǎi)/O)
3、服務(wù)端優(yōu)化
(1) 頁(yè)面靜態(tài)化
(2) 并發(fā)處理
(3) 隊(duì)列處理
4、數(shù)據(jù)庫(kù)優(yōu)化
(1) 數(shù)據(jù)庫(kù)緩存
(2) 分庫(kù)分表,分區(qū)
(3) 讀寫(xiě)分離
(4) 負(fù)載均衡
5、web服務(wù)器優(yōu)化
(1) nginx反向代理實(shí)現(xiàn)負(fù)載均衡
(2) lvs實(shí)現(xiàn)負(fù)載均衡
防止sql注入
防止注入的第一步就是驗(yàn)證數(shù)據(jù),可以根據(jù)相應(yīng)類(lèi)型進(jìn)行嚴(yán)格的驗(yàn)證。比如 int 類(lèi)型直接同過(guò) intval 進(jìn)行轉(zhuǎn)換就行:
參數(shù)化綁定,防止 SQL 注入的又一道屏障。php MySQLi 和 PDO 均提供這樣的功能。比如 MySQLi 可以這樣去查詢:
魔術(shù)常量、超全局變量、魔術(shù)方法
https://blog.csdn.net/t707584896/article/details/128798962
對(duì)象的克隆與引用有什么區(qū)別
引用就是:當(dāng)改變$Object1對(duì)象時(shí),$Object2也做相同的變化。
克隆就是:克隆的對(duì)象$Object1與原來(lái)的對(duì)象沒(méi)有任何關(guān)系,它是將原來(lái)的對(duì)象從當(dāng)前位置從新復(fù)制了一份。
什么是composer?composer的意義?工作原理
composer是一個(gè)依賴管理工具,composer會(huì)幫你安裝這些依賴的庫(kù)文件;
比如composer可以解決自動(dòng)加載類(lèi),不用你寫(xiě)過(guò)多的new。
二. 數(shù)據(jù)庫(kù)方面
數(shù)據(jù)庫(kù)三大范式是什么?
第一范式:
1NF是對(duì)屬性的原子性,要求屬性具有原子性,不可再分解;
第二范式:
2NF是對(duì)記錄的唯一性,要求記錄有唯一標(biāo)識(shí),即實(shí)體的唯一性,即不存在部分依賴;
第三范式:
3NF是對(duì)字段的冗余性,要求任何字段不能由其他字段派生出來(lái),它要求字段沒(méi)有冗余,即不存
msyql的存儲(chǔ)引擎,以及各自的區(qū)別,myisam和innodb區(qū)別
InnoDB是MySQL默認(rèn)的存儲(chǔ)引擎。
2.只有 InnoDB 支持事務(wù),MyISAM不支持事務(wù)。
3.MyISAM不支持行級(jí)鎖和外鍵, InnoDB支持。
4.InnoDB表的大小更加的大,用MyISAM可省很多的硬盤(pán)空間。
5.InnoDB 引擎的索引和文件是存放在一起的,找到索引就可以找到數(shù)據(jù),是聚簇式設(shè)計(jì)。
6.MyISAM 引擎采用的是非聚簇式(即使是主鍵)設(shè)計(jì),索引文件和數(shù)據(jù)文件不在同一個(gè)文件中。
mysql索引有哪些,你是如何做索引的?
從數(shù)據(jù)結(jié)構(gòu)角度
(1)、B+樹(shù)索引(O(log(n))):關(guān)于B+樹(shù)索引,可以參考 MySQL索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理
(2)、hash索引:
從物理存儲(chǔ)角度
(1)、聚集索引(clustered index)
(2)、非聚集索引(non-clustered index)
從邏輯角度
(1)、主鍵索引:主鍵索引是一種特殊的唯一索引,不允許有空值
(2)、普通索引或者單列索引
(3)、多列索引(復(fù)合索引):復(fù)合索引指多個(gè)字段上創(chuàng)建的索引,只有在查詢條件中使用了創(chuàng)建索引時(shí)的第一個(gè)字段,索引才會(huì)被使用。使用復(fù)合索引時(shí)遵循最左前綴集合
(4)、唯一索引或者非唯一索引
(5)、空間索引:空間索引是對(duì)空間數(shù)據(jù)類(lèi)型的字段建立的索引
mysql索引優(yōu)化
列越小越快
枚舉類(lèi)型替代varchar
避免null值
固定長(zhǎng)度的表比動(dòng)態(tài)的快(避免text等不定長(zhǎng)字段)
垂直分表(降低表的復(fù)雜度,不常用的字段分離出來(lái)單獨(dú)存儲(chǔ))
合理設(shè)置索引
分表,分布式(主從)
mysql的事務(wù)特性
原子性:事務(wù)是一個(gè)不可分割的工作單位,要么同時(shí)成功,要么同時(shí)失敗。例:當(dāng)兩個(gè)人發(fā)起轉(zhuǎn)賬業(yè)務(wù)時(shí),如果A轉(zhuǎn)賬發(fā)起,而B(niǎo)因?yàn)橐恍┰虿荒艹晒邮?,事?wù)最終將不會(huì)提交,則A和B的請(qǐng)求最終不會(huì)成功。
持久性:一旦事務(wù)提交,他對(duì)數(shù)據(jù)庫(kù)的改變就是永久的。注:只要提交了事務(wù),將會(huì)對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)進(jìn)行永久性刷新。
隔離性:多個(gè)事務(wù)之間相互隔離的,互不干擾
一致性:事務(wù)執(zhí)行接收之后,數(shù)據(jù)庫(kù)完整性不被破壞
注意:只有當(dāng)前三條性質(zhì)都滿足了,才能保證事務(wù)的一致性
mysql的讀寫(xiě)分離
讀寫(xiě)分離解決的是,數(shù)據(jù)庫(kù)的寫(xiě)操作,影響了查詢的效率,適用于讀遠(yuǎn)大于寫(xiě)的場(chǎng)景。讀寫(xiě)分離的實(shí)現(xiàn)基礎(chǔ)是主從復(fù)制,主數(shù)據(jù)庫(kù)利用主從復(fù)制將自身數(shù)據(jù)的改變同步到從數(shù)據(jù)庫(kù)集群中,然后主數(shù)據(jù)庫(kù)負(fù)責(zé)處理寫(xiě)操作(當(dāng)然也可以執(zhí)行讀操作),從數(shù)據(jù)庫(kù)負(fù)責(zé)處理讀操作,不能執(zhí)行寫(xiě)操作。并可以根據(jù)壓力情況,部署多個(gè)從數(shù)據(jù)庫(kù)提高讀操作的速度,減少主數(shù)據(jù)庫(kù)的壓力,提高系統(tǒng)總體的性能。
msyql如何分表分庫(kù)分表
https://blog.csdn.net/shida219/article/details/117981566
msyql 查詢和更新執(zhí)行過(guò)程

msyql悲觀和樂(lè)觀鎖
https://blog.csdn.net/weixin_45433031/article/details/120838045
msyql索引回表
InnoDB引擎中,非主鍵索引查找數(shù)據(jù)時(shí)需要先找到主鍵,再根據(jù)主鍵查找具體行數(shù)據(jù),這種現(xiàn)象叫回表查詢
索引覆蓋,即將查詢sql中的字段添加到聯(lián)合索引里面,只要保證查詢語(yǔ)句里面的字段都在索引文件中,就無(wú)需進(jìn)行回表查詢;
msyql索引失效
1、like查詢以“%”開(kāi)頭;
2、or語(yǔ)句前后沒(méi)有同時(shí)使用索引;
3、組合索引中不是使用第一列索引;
4、在索引列上使用“IS NULL”或“IS NOT NULL”操作;
5、在索引字段上使用“not”,“<>”,“!=”。
6、如果列類(lèi)型是字符串,那一定要在條件中將數(shù)據(jù)使用引號(hào)引用起來(lái),否則不使用索引
7、當(dāng)全表掃描速度比索引速度快時(shí),mysql會(huì)使用全表掃描,此時(shí)索引失效。
什么是死鎖?什么是臟讀?幻讀?不可重復(fù)讀?
臟讀(無(wú)效的數(shù)據(jù))
a事務(wù)把數(shù)據(jù)改完之后并沒(méi)有提交,b事務(wù)讀到這個(gè)改完數(shù)據(jù)之后的事務(wù),
b事務(wù)讀完之后,a事務(wù)又把數(shù)據(jù)做了一個(gè)回滾操作,這種現(xiàn)象叫臟讀
不可重復(fù)讀
a事務(wù)把數(shù)據(jù)讀完拿去用了,b事務(wù)剛好直接把數(shù)據(jù)給改了,并且提交了,
a事務(wù)會(huì)發(fā)現(xiàn)之前讀的數(shù)據(jù)不準(zhǔn)確了
幻讀現(xiàn)象
是不可重復(fù)讀的一種特殊現(xiàn)象,
舉例:假設(shè)一張表一共有10條數(shù)據(jù),a事務(wù)把id大于3的數(shù)據(jù)name全部改成了xx,
就在剛剛改完的那一刻,b事務(wù)又插入一條數(shù)據(jù),a事務(wù)改完之后,會(huì)發(fā)現(xiàn)有一條數(shù)據(jù)沒(méi)有修改成功
MySQL數(shù)據(jù)庫(kù)cpu飆升到100%的話怎么處理?
https://blog.csdn.net/t707584896/article/details/129971047
MySQL主從復(fù)制解決了哪些問(wèn)題?
1、數(shù)據(jù)的備份(很多企業(yè)用從庫(kù)來(lái)做專業(yè)數(shù)據(jù)庫(kù)備份服務(wù)器)
2、讀寫(xiě)分離,這樣減少主庫(kù)的壓力,支持更大的并發(fā),主寫(xiě)從讀。還可以單獨(dú)使用一個(gè)從庫(kù)來(lái)做為企業(yè)內(nèi)部人員查詢數(shù)據(jù)使用的服務(wù)器,這樣更有利于減少線上服務(wù)器的訪問(wèn)壓力。
3、高可用,主從復(fù)制+故障切換,實(shí)現(xiàn)線上業(yè)務(wù)不宕機(jī)運(yùn)行。
binlog和redo log有什么區(qū)別?
1.Redo Log是屬于InnoDB引擎功能,Binlog是屬于MySQL Server自帶功能,并且是以二進(jìn)制文件記錄。
2.Redo Log屬于物理日志,記錄該數(shù)據(jù)頁(yè)更新?tīng)顟B(tài)內(nèi)容,Binlog是邏輯日志,記錄更新過(guò)程。
3.Redo Log日志是循環(huán)寫(xiě),日志空間大小是固定,Binlog是追加寫(xiě)入,寫(xiě)完一個(gè)寫(xiě)下一個(gè),不會(huì)覆蓋使用。
4.Redo Log作為服務(wù)器異常宕機(jī)后事務(wù)數(shù)據(jù)自動(dòng)恢復(fù)使用,Binlog可以作為主從復(fù)制和數(shù)據(jù)恢復(fù)使用。Binlog沒(méi)有自動(dòng)crash-safe能力。
5.由binlog和redo log的概念和區(qū)別可知:binlog日志只用于歸檔,只依靠binlog是沒(méi)有crash-safe能力的。但只有redo log也不行,因?yàn)閞edo log是InnoDB特有的,且日志上的記錄落盤(pán)后會(huì)被覆蓋掉。因此需要binlog和redo log二者同時(shí)記錄,才能保證當(dāng)數(shù)據(jù)庫(kù)發(fā)生宕機(jī)重啟時(shí),數(shù)據(jù)不會(huì)丟失
慢SQL如何定位呢?
1.首先確認(rèn)是否開(kāi)啟了慢查詢
2.設(shè)置慢查詢的時(shí)間限制
3.查詢慢查詢?nèi)罩究啥ㄎ痪唧w的慢sql
4.相關(guān)sql查詢
5.用Explain分析具體的sql語(yǔ)句
id:選擇標(biāo)識(shí)符
select_type:表示查詢的類(lèi)型。
table:輸出結(jié)果集的表
partitions:匹配的分區(qū)
type:表示表的連接類(lèi)型
possible_keys:表示查詢時(shí),可能使?的索引
key:表示實(shí)際使?的索引
key_len:索引字段的長(zhǎng)度
ref:列與索引的比較
rows:掃描出的行數(shù)(估算的行數(shù))
filtered:按表?xiàng)l件過(guò)濾的?百分比
Extra:執(zhí)行情況的描述和說(shuō)明
MySQL單表過(guò)億條數(shù)據(jù),如何優(yōu)化查詢速度?
分庫(kù):是為了解決數(shù)據(jù)庫(kù)連接資源不足問(wèn)題,和磁盤(pán)IO的性能瓶頸問(wèn)題。
分表:是為了解決單表數(shù)據(jù)量太大,sql語(yǔ)句查詢數(shù)據(jù)時(shí),即使走了索引也非常耗時(shí)問(wèn)題。此外還可以解決消耗cpu資源問(wèn)題。
分庫(kù)分表:可以解決 數(shù)據(jù)庫(kù)連接資源不足、磁盤(pán)IO的性能瓶頸、檢索數(shù)據(jù)耗時(shí) 和 消耗cpu資源等問(wèn)題。
https://www.zhihu.com/question/439988021/answer/2436380280
百億級(jí)數(shù)據(jù)分表后怎么分頁(yè)查詢?
分表規(guī)則定位具體表,或者雙寫(xiě)
最后考慮 離線數(shù)倉(cāng)或者ES查詢
redis和memcache有什么區(qū)別
多線程:memcache支持多線程,Redis支持單線程
持久化:Redis支持持久化(周期性的將數(shù)據(jù)寫(xiě)到磁盤(pán)中),memcache不支持持久化
分布式:Redis做主從結(jié)構(gòu),memcache服務(wù)器需要通過(guò)hash一致化來(lái)支撐主從結(jié)構(gòu)
redis常見(jiàn)數(shù)據(jù)結(jié)構(gòu)有哪些
最常用的的有5種,字符串(String)、哈希(Hash)、列表(list)、集合(set)、有序集合(ZSET)
redis緩存雪崩、緩存穿透、緩存擊穿
https://blog.csdn.net/t707584896/article/details/128812799
redis淘汰策略
volatile-lru,針對(duì)設(shè)置了過(guò)期時(shí)間的key,使用lru算法進(jìn)行淘汰。
allkeys-lru,針對(duì)所有key使用lru算法進(jìn)行淘汰。
volatile-lfu,針對(duì)設(shè)置了過(guò)期時(shí)間的key,使用lfu算法進(jìn)行淘汰。
allkeys-lfu,針對(duì)所有key使用lfu算法進(jìn)行淘汰。
volatile-random,從所有設(shè)置了過(guò)期時(shí)間的key中使用隨機(jī)淘汰的方式進(jìn)行淘汰。
allkeys-random,針對(duì)所有的key使用隨機(jī)淘汰機(jī)制進(jìn)行淘汰。
volatile-ttl,刪除生存時(shí)間最近的一個(gè)鍵。
noeviction(默認(rèn)),不刪除鍵,值返回錯(cuò)誤。
redis分布式鎖怎么實(shí)現(xiàn)
https://www.zhihu.com/question/300767410/answer/1931519430
Redis的持久化機(jī)制
區(qū)別:
RDB持久化是指在指定的時(shí)間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫(xiě)入磁盤(pán),實(shí)際操作過(guò)程就是有一個(gè)fork子進(jìn)程,先將數(shù)據(jù)集寫(xiě)入到臨時(shí)文件中,寫(xiě)入成功后,再替換之前的文件,用二進(jìn)制壓縮存儲(chǔ)。
AOF持久化以日志的形式記錄服務(wù)器所處理的每一個(gè)寫(xiě)、刪除操作,查詢操作不會(huì)記錄,以文本的方式記錄,可以打開(kāi)文件看到詳細(xì)的操作記錄。
RDB的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):RDB持久化文件,速度比較快,而且存儲(chǔ)的是一個(gè)二進(jìn)制文件,傳輸起來(lái)很方便。
缺點(diǎn):RDB無(wú)法保證數(shù)據(jù)的絕對(duì)安全,有時(shí)候就是1s也會(huì)有很大的數(shù)據(jù)丟失。
AOF的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):AOF相對(duì)RDB更加安全,一般不會(huì)有數(shù)據(jù)的丟失或者很少,官方推薦同時(shí)開(kāi)啟AOF和RDB。
缺點(diǎn):AOF持久化的速度,相對(duì)于RDB較慢,存儲(chǔ)的是一個(gè)文本文件,到了后期文件會(huì)比較大,傳輸困難。
redis如何解決秒殺超賣(mài)問(wèn)題
隊(duì)列、事物、分布式鎖等很多方式,自行了解
https://zhuanlan.zhihu.com/p/268290754
MySQL里有2000w數(shù)據(jù),redis中只存20w數(shù)據(jù),如何保證redis中數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)
分析題目:保證Redis 中的 20w 數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù) 說(shuō)明是被頻繁訪問(wèn)的數(shù)據(jù),并且要保證Redis的內(nèi)存能夠存放20w數(shù)據(jù),要計(jì)算出Redis內(nèi)存的大小。
a、保留熱點(diǎn)數(shù)據(jù):對(duì)于保留 Redis 熱點(diǎn)數(shù)據(jù)來(lái)說(shuō),我們可以使用 Redis 的內(nèi)存淘汰策略來(lái)實(shí)現(xiàn),可以使用allkeys-lru淘汰策略,該淘汰策略是從 Redis 的數(shù)據(jù)中挑選最近最少使用的數(shù)據(jù)刪除,這樣頻繁被訪問(wèn)的數(shù)據(jù)就可以保留下來(lái)了。
b、保證 Redis 只存20w的數(shù)據(jù):1個(gè)中文占2個(gè)字節(jié),假如1條數(shù)據(jù)有100個(gè)中文,則1條數(shù)據(jù)占200字節(jié),20w數(shù)據(jù) 乘以 200字節(jié) 等于 4000 字節(jié)(大概等于38M);所以要保證能存20w數(shù)據(jù),Redis 需要38M的內(nèi)存。
redis主從哨兵和集群的區(qū)別
一、架構(gòu)不同
redis主從:一主多從;
redis集群:多主多從;
二、存儲(chǔ)不同
redis主從:主節(jié)點(diǎn)和從節(jié)點(diǎn)都是存儲(chǔ)所有數(shù)據(jù);
redis集群:數(shù)據(jù)的存儲(chǔ)是通過(guò)hash計(jì)算16384的槽位,算出要將數(shù)據(jù)存儲(chǔ)的節(jié)點(diǎn),然后進(jìn)行存儲(chǔ);
三、選舉不同
redis主從:通過(guò)啟動(dòng)redis自帶的哨兵(sentinel)集群進(jìn)行選舉,也可以是一個(gè)哨兵
選舉流程:1、先發(fā)現(xiàn)主節(jié)點(diǎn)fail的哨兵,將成為哨兵中的leader,之后的主節(jié)點(diǎn)選舉將通過(guò)這個(gè)leader進(jìn)行故障轉(zhuǎn)移操作,從存活的slave中選舉新的master,新的master選舉同集群的master節(jié)點(diǎn)選舉類(lèi)似;
redis集群:集群可以自己進(jìn)行選舉
選舉流程:1、當(dāng)主節(jié)點(diǎn)掛掉,從節(jié)點(diǎn)就會(huì)廣播該主節(jié)點(diǎn)fail;
2、延遲時(shí)間后進(jìn)行選舉(延遲的時(shí)間算法為:延遲時(shí)間+隨機(jī)數(shù)+rank*1000,從節(jié)點(diǎn)數(shù)據(jù)越多,rank越小,因?yàn)橹鲝臄?shù)據(jù)復(fù)制是異步進(jìn)行的,所以 所有的從節(jié)點(diǎn)的數(shù)據(jù)可能會(huì)不同),延遲的原因是等待主節(jié)點(diǎn)fail廣播到所有存活的主節(jié)點(diǎn),否則主節(jié)點(diǎn)會(huì)拒絕參加選舉;
3、參加選舉的從節(jié)點(diǎn)向所有的存活的節(jié)點(diǎn)發(fā)送ack請(qǐng)求,但只有主節(jié)點(diǎn)會(huì)回復(fù)它,并且主節(jié)點(diǎn)只會(huì)回復(fù)第一個(gè)到達(dá)參加選舉的從節(jié)點(diǎn),一半以上的主節(jié)點(diǎn)回復(fù),該節(jié)點(diǎn)就會(huì)成為主節(jié)點(diǎn),廣播告訴其他節(jié)點(diǎn)該節(jié)點(diǎn)成為主節(jié)點(diǎn)。
四、節(jié)點(diǎn)擴(kuò)容不同
redis主從:只能擴(kuò)容從節(jié)點(diǎn),無(wú)法對(duì)主節(jié)點(diǎn)進(jìn)行擴(kuò)容;
redis集群:可以擴(kuò)容整個(gè)主從節(jié)點(diǎn),但是擴(kuò)容后需要進(jìn)行槽位的分片,否則無(wú)法進(jìn)行數(shù)據(jù)寫(xiě)入,命令為:
/usr/local/redis-5.0.3/src/redis-cli -a zhuge --cluster reshard 192.168.0.61:8001,其中的192.168.0.61:8001為新加入的主從節(jié)點(diǎn);
redis消息隊(duì)列如何防止數(shù)據(jù)丟失
Redis實(shí)現(xiàn)消息隊(duì)列有兩種形式:
廣播訂閱模式:基于Redis的 Pub/Sub 機(jī)制,一旦有客戶端往某個(gè)key里面 publish一個(gè)消息,所有subscribe的客戶端都會(huì)觸發(fā)事件
集群訂閱模式:基于Redis List雙向+ 原子性 + BRPOP
Redis消息隊(duì)列時(shí),當(dāng)Redis宕機(jī)后,消息可能會(huì)丟失(也要看持久化的策略)。如果收消息方(消費(fèi)端)未有重發(fā)和驗(yàn)證機(jī)制,Redis內(nèi)的數(shù)據(jù)會(huì)出現(xiàn)丟失。所以,使用Redis的作為消息隊(duì)列,通常是對(duì)于消息的準(zhǔn)確性并非特別高的場(chǎng)景。
如果絕對(duì)的保證數(shù)據(jù)最終一致性,保證消息百分百不丟,那么需要:
1.寫(xiě)入時(shí)候要求啟用事務(wù)處理,保證寫(xiě)一定成功。
2. redis配置成任何變更一定實(shí)時(shí)持久化,比如存儲(chǔ)端是磁盤(pán)的話,每次變更馬上同步寫(xiě)入磁盤(pán),才算完成。redis是支持這種方式配置的,但是這么做會(huì)使它的內(nèi)存數(shù)據(jù)庫(kù)特性完全消失,性能變得十分低下。
3. 消費(fèi)端也要實(shí)現(xiàn)事務(wù)方式,處理完成后,再回來(lái)真實(shí)刪除消息。
4. 多線程或者多端同時(shí)并發(fā)處理,可以通過(guò)鎖的方式來(lái)規(guī)避。
3 4的需求需要自己實(shí)現(xiàn),可以一起考慮,用另外一個(gè)隊(duì)列實(shí)現(xiàn)的方式也可以,但是更好的方式是在隊(duì)列內(nèi)部實(shí)現(xiàn)個(gè)計(jì)數(shù)器。hash格式的加個(gè)字段加數(shù)值,list的先推一個(gè)數(shù)值打底,string的頭上加個(gè)數(shù)值再加個(gè)分隔符,就可以做個(gè)簡(jiǎn)單計(jì)數(shù)器了,雖然土,勝在夠?qū)嵱谩?/span>
除了特定的系統(tǒng)之外,一般不會(huì)要求這么強(qiáng)的一致性,實(shí)現(xiàn)倒不難,但是性能會(huì)很差很差。
銀行類(lèi)支付類(lèi)業(yè)務(wù)會(huì)要求嚴(yán)格的事務(wù)一致性,而互聯(lián)網(wǎng)類(lèi)業(yè)務(wù)一般會(huì)用點(diǎn)取巧的方式,就是可以容忍極短時(shí)間內(nèi)少量數(shù)據(jù)丟失的方式,換取更高性能。
比如上面的redis處理,可以改為1000條數(shù)據(jù)變更的時(shí)候再真實(shí)落盤(pán),即寫(xiě)入磁盤(pán)。那么極限情況下,如突然斷電,存在可能丟失這1000條數(shù)據(jù)的風(fēng)險(xiǎn)。當(dāng)然這種情況出現(xiàn)的概率也是很低的(遠(yuǎn)離藍(lán)翔挖掘機(jī)?),所以大部分場(chǎng)景下可以接受。
MQ消息隊(duì)列你怎么選擇,各大優(yōu)劣
1 RabbitMQ
優(yōu)點(diǎn):輕量級(jí)、容易部署和使用、支持多種客戶端開(kāi)發(fā)語(yǔ)言、支持靈活的路由配置
缺點(diǎn):對(duì)消息堆積的支持并不好、性能和吞吐量較差、使用 Erlang 語(yǔ)言編寫(xiě),比較難進(jìn)行二次開(kāi)發(fā)
2 RocketMQ
優(yōu)點(diǎn):性能好、穩(wěn)定可靠、有活躍的中文社區(qū)、使用 Java 開(kāi)發(fā),容易進(jìn)行二次開(kāi)發(fā)、特點(diǎn)響應(yīng)快
缺點(diǎn):兼容性較差
3 Kafka
優(yōu)點(diǎn):兼容性極好、設(shè)計(jì)上大量使用了批量和異步的思想,有超高的性能、
缺點(diǎn):由于 "先攢一波再一起處理" 的設(shè)計(jì),時(shí)延較高,不太適合在線業(yè)務(wù)場(chǎng)景
4 總結(jié)
如果說(shuō),消息隊(duì)列并不是你將要構(gòu)建的主角之一,對(duì)消息隊(duì)列的功能和性能都沒(méi)有很高的要求,只需要一個(gè)開(kāi)箱即用易于維護(hù)的產(chǎn)品,建議使用 RabbitMQ。
如果系統(tǒng)使用消息隊(duì)列的主要場(chǎng)景是處理在線業(yè)務(wù),比如在交易系統(tǒng)中用消息隊(duì)列傳遞訂單,那 RocketMQ 的低延遲和金融級(jí)的穩(wěn)定性是我們需要的。
如果需要的是處理海量的數(shù)據(jù),像收集日志、監(jiān)控信息或是前端的埋點(diǎn)這類(lèi)數(shù)據(jù),或是應(yīng)用場(chǎng)景大量使用了大數(shù)據(jù)、流計(jì)算相關(guān)的開(kāi)源產(chǎn)品,那 Kafka 是最適合的消息隊(duì)列。
int(1)和int(10)區(qū)別
INT(1) 和 INT(10)本身沒(méi)有區(qū)別,但是INT[(M)] 加上ZEROFILL值后,會(huì)對(duì)值有寬度的設(shè)置,不夠位數(shù)前面自動(dòng)補(bǔ)0.
MySQL:數(shù)據(jù)庫(kù)自增 ID 用完了會(huì)咋樣?
把主鍵類(lèi)型改為 bigint,也就是 8 個(gè)字節(jié)。這樣能存儲(chǔ)的最大數(shù)據(jù)量就是 2^64
PS:單表 21 億的數(shù)據(jù)量顯然不現(xiàn)實(shí),一般來(lái)說(shuō)數(shù)據(jù)量達(dá)到 500 萬(wàn)就該分表了
三、 服務(wù)器&其它方面
說(shuō)下一些你常用的linux命令
1.pwd 命令 2.ls 命令 3.cd 命令 4.man 命令 5.grep 命令 6.find 命令 7.chmod 命令 8.ps 命令 9.kill 命令 10.tail 命令 11.netstat 命令 8.date 查看當(dāng)前系統(tǒng)時(shí)間 10.echo 打印
多進(jìn)程同時(shí)讀寫(xiě)一個(gè)文件
$pid = pcntl_fork();$fp = fopen("test.txt", "a");if (flock($fp, LOCK_EX)){ fwrite($fp, "content"); fflush($fp); flock($fp, LOCK_UN);}else{ echo "此文件正在被其他進(jìn)程占用";}
常用的服務(wù)端口號(hào)
https://blog.csdn.net/zhanghongshun624/article/details/127920039
api接口的安全性設(shè)計(jì)
https://blog.csdn.net/t707584896/article/details/129266951
如何防止數(shù)據(jù)重復(fù)提交,重復(fù)寫(xiě)入
主要從并發(fā)上面考慮:緩存、分流、redis鎖、隊(duì)列、mysql所有等方面
SSO單點(diǎn)登陸
在多個(gè)系統(tǒng)中,只需要登陸/注銷(xiāo)一次,就可以完成所有系統(tǒng)中的用戶登陸驗(yàn)證。
同一個(gè)域名下的子域名各個(gè)系統(tǒng)可以使用設(shè)置頂級(jí)域名的cookie存儲(chǔ)登陸信息來(lái)實(shí)現(xiàn);
攔截登陸請(qǐng)求給用戶中心發(fā)放令牌到子系統(tǒng),子系統(tǒng)校驗(yàn)令牌后局部登陸,注銷(xiāo)時(shí)用戶中心發(fā)送請(qǐng)求到各個(gè)子系統(tǒng)注銷(xiāo)局部登陸;
jwt,各個(gè)子系統(tǒng)使用相同的secret,相同的token可以在不同系統(tǒng)中使用;
以上方式的前提都要有統(tǒng)一的用戶信息存儲(chǔ)中心。
兩臺(tái) mysql 服務(wù)器,其中一臺(tái)掛了,怎么讓業(yè)務(wù)端無(wú)感切換
https://blog.csdn.net/sinat_36757755/article/details/124049382
微服務(wù)之間怎么通信
1、基于網(wǎng)關(guān) API
2、基于 RPC
3、基于 SideCar
https://zhuanlan.zhihu.com/p/452558073
TCP三次握手四次揮手
握手:
客戶端請(qǐng)求服務(wù)端,發(fā)送連接請(qǐng)求標(biāo)示和一串順序碼(X)
服務(wù)端收到請(qǐng)求,回復(fù)確認(rèn)標(biāo)示和順序碼(X)+1的確認(rèn)碼和另一個(gè)順序碼(Y)
客戶端驗(yàn)證(X)+1確認(rèn)碼,通過(guò)后發(fā)送確認(rèn)標(biāo)示和(Y)+1的順序碼給服務(wù)端,服務(wù)端驗(yàn)證通過(guò)后建立連接
揮手:
第一次握手:TCP發(fā)送一個(gè)FIN(結(jié)束),用來(lái)關(guān)閉客戶到服務(wù)端的連接。
第二次握手:服務(wù)端收到這個(gè)FIN,他發(fā)回一個(gè)ACK(確認(rèn)),確認(rèn)收到序號(hào)為收到序號(hào)+1。
第三次握手:服務(wù)端發(fā)送一個(gè)FIN(結(jié)束)到客戶端,服務(wù)端關(guān)閉客戶端的連接。
第四次握手:客戶端發(fā)送ACK(確認(rèn))報(bào)文確認(rèn),并將確認(rèn)的序號(hào)+1,這樣關(guān)閉完成
為什么是四次不是三次?
server端收到結(jié)束請(qǐng)求后,需要等待數(shù)據(jù)傳輸完畢,所以只能先發(fā)送一個(gè)收到請(qǐng)求的確認(rèn)信息給客戶端,等數(shù)據(jù)傳輸完畢后再發(fā)送結(jié)束報(bào)文。
正常請(qǐng)求一個(gè)php網(wǎng)站,在瀏覽器輸入網(wǎng)址打開(kāi)網(wǎng)站,顯示網(wǎng)頁(yè)。但是在整個(gè)請(qǐng)求流程中瀏覽器做什么?服務(wù)器又是怎么在后臺(tái)執(zhí)行的?接下來(lái)就簡(jiǎn)單解析下一個(gè)完整的PHP請(qǐng)求的執(zhí)行過(guò)程。
1、構(gòu)建請(qǐng)求
2、查找緩存
3、域名解析
4、與服務(wù)器建立連接
TCP的三次握手
5、發(fā)起HTTP請(qǐng)求
6、服務(wù)器處理請(qǐng)求
7、服務(wù)器響應(yīng)HTTP請(qǐng)求
8、客戶端解析返回?cái)?shù)據(jù)
9、與服務(wù)器斷開(kāi)連接
TCP的四次揮手
https://blog.csdn.net/weixin_43844718/article/details/126975557
網(wǎng)絡(luò)七層協(xié)議/OSI七層模型

swoole的了解
技術(shù)特點(diǎn):
1 常駐內(nèi)存,避免重復(fù)加載帶來(lái)的性能損耗,提升海量性能;
2 基于epoll,輕松支持高并發(fā);
3 協(xié)程異步I/O,提高對(duì)I/O密集型場(chǎng)景并發(fā)處理能力;
4 支持多種通信協(xié)議,方便地開(kāi)發(fā) Http、WebSocket、TCP、UDP 等應(yīng)用
swoole與php-fpm對(duì)比有哪些優(yōu)缺點(diǎn)?
優(yōu)點(diǎn):
1 常駐內(nèi)存的 cli 運(yùn)行模式,不用每次請(qǐng)求加載一次項(xiàng)目代碼
2 大大提高了對(duì)連接請(qǐng)求的并發(fā)能力
3 協(xié)程異步I/O,提高對(duì)I/O密集型場(chǎng)景并發(fā)處理能力
4 支持多種通信協(xié)議,能搭建 TCP/UDP/UnixSocket 服務(wù)器
5 原生支持毫秒定時(shí)器
缺點(diǎn)
1 相關(guān)文檔較少
2 不支持 xdebug,不支持手動(dòng) dump,不熟悉相關(guān)工具的話,不太方便調(diào)試
3 入門(mén)難度高,多數(shù) phper 不了解 TCP/IP 網(wǎng)絡(luò)協(xié)議、多進(jìn)程 / 多線程、異步 io 等
Nginx+Php-fpm運(yùn)行原理
http://www.test.cc
|
Nginx
|
路由到 http://www.test.cc/index.php
|
加載nginx的fast-cgi模塊
|
fast-cgi監(jiān)聽(tīng)127.0.0.1:9000地址
|
www.test.com/index.php請(qǐng)求到達(dá)127.0.0.1:9000
|
php-fpm 監(jiān)聽(tīng)127.0.0.1:9000
|
php-fpm 接收到請(qǐng)求,啟用worker進(jìn)程處理請(qǐng)求
|
php-fpm 處理完請(qǐng)求并撤消內(nèi)存,返回給nginx
|
nginx 將結(jié)果通過(guò)http返回給瀏覽器
遇到一個(gè)網(wǎng)站打開(kāi)慢怎么排查
1.打不開(kāi),則ping域名,看是否能請(qǐng)求成功。
2.慢,說(shuō)明能打開(kāi),直接走這一步,free/top命令查看服務(wù)器內(nèi)存和CPU使用情況,iftop等工具查看帶寬
3.chrome的debug->network查看響應(yīng)慢的
4.排查響應(yīng)慢的接口代碼,看php,mysql,redis等的日志看錯(cuò)誤信息(mysql的慢查詢?nèi)罩竟δ埽琾hp-fpm慢日志功能,需要配置開(kāi)啟)
高并發(fā)解決方案
1、流量?jī)?yōu)化
防盜鏈處理(去除惡意請(qǐng)求)
2、前端優(yōu)化
(1) 減少HTTP請(qǐng)求[將css,js等合并]
(2) 添加異步請(qǐng)求(先不將所有數(shù)據(jù)都展示給用戶,用戶觸發(fā)某個(gè)事件,才會(huì)異步請(qǐng)求數(shù)據(jù))
(3) 啟用瀏覽器緩存和文件壓縮
(4) CDN加速
(5) 建立獨(dú)立的圖片服務(wù)器(減少I(mǎi)/O)
3、服務(wù)端優(yōu)化
(1) 頁(yè)面靜態(tài)化
(2) 并發(fā)處理
(3) 隊(duì)列處理
4、數(shù)據(jù)庫(kù)優(yōu)化
(1) 數(shù)據(jù)庫(kù)緩存
(2) 分庫(kù)分表,分區(qū)
(3) 讀寫(xiě)分離
5、web服務(wù)器優(yōu)化
(1) 分布式部署
集群
(2) 負(fù)載均衡
如何選擇消息隊(duì)列?
https://blog.mimvp.com/article/47038.html
什么是MQ?
mq是一個(gè)消息隊(duì)列,其主要目的是為了解決傳統(tǒng)的消息傳輸上管理困難,效率不高的問(wèn)題.
mq有三大優(yōu)點(diǎn):解耦,異步,削峰.
解耦: 如果是傳統(tǒng)的消息通訊方式,無(wú)論是哪一方都要去維護(hù)一份供外部通訊的這個(gè)一個(gè)接口,而且各方處理消息的能力有限,效率上明顯跟不上,并且這樣子二者之間的耦合度非常高,對(duì)于拓展管理方面極不友好,而是要了mq就不一樣,發(fā)送方只需要將消息發(fā)送給mq就可以了,別的不用考慮,接口什么的由mq去維護(hù),接收方也只需要去mq里消費(fèi)消息就可以了,就需要其他開(kāi)銷(xiāo),一切由mq中間件來(lái)做,達(dá)到了解耦操作.
異步: 使用mq,還可以達(dá)到異步效果,極大地提升了消息傳輸?shù)男?發(fā)送方在發(fā)送消息后不需要關(guān)心消費(fèi)方是否能消費(fèi)完成,還可以繼續(xù)發(fā)送其他消息.
削峰:如果是傳統(tǒng)的消息通訊,一下子有大量的消息發(fā)送給接收方,這樣對(duì)于接收方的處理壓力是很大的,而我們剛好可以利用mq達(dá)到一個(gè)緩沖操作,一旦流量超出了接收方處理范圍,不用擔(dān)心,只需要慢慢消費(fèi)即可,像經(jīng)典的雙十一,就很容易會(huì)使用到mq這么一個(gè)優(yōu)點(diǎn).
雖然mq有三大優(yōu)點(diǎn),但是我們還是得關(guān)心其一些缺點(diǎn):
因?yàn)樵黾恿酥虚g件,系統(tǒng)復(fù)雜度肯定大大提高,增加了很多維護(hù)的成本,比如我們要保證消息不丟失(一致性)和消息冪等性問(wèn)題,還要保證mq的高可用等.
mq消息隊(duì)列如何保證消息的可靠性傳輸
消息的可靠性傳輸分為兩個(gè)問(wèn)題,一個(gè)是保證消息不被重復(fù)消費(fèi),另一個(gè)是保證消息不丟失.
保證消息不重復(fù)被消費(fèi),就是保證消息的冪等性問(wèn)題,消息的冪等性是指一個(gè)操作執(zhí)行任意多次所產(chǎn)生的影響均與一次執(zhí)行的影響相同,在mq里,也就是消息只能被消費(fèi)一次,不能被重復(fù)消費(fèi).
來(lái)看看消息丟失的場(chǎng)景:
發(fā)送方丟失,可能發(fā)送方在發(fā)送消息的過(guò)程中,出現(xiàn)網(wǎng)絡(luò)問(wèn)題等導(dǎo)致mq接收不到消息,導(dǎo)致了消息丟失.
要解決這個(gè)問(wèn)題,首先可以采用事務(wù)機(jī)制,在發(fā)送消息的時(shí)候?qū)崿F(xiàn)事務(wù)機(jī)制,若是出現(xiàn)發(fā)送失敗的情況,可以進(jìn)行回滾,而讓消息重新被發(fā)送.但是開(kāi)啟了事務(wù),發(fā)送方就必須同步等待事務(wù)執(zhí)行完畢或者回滾,導(dǎo)致消息一多,性能會(huì)下降.
但是,還有一個(gè)更好的辦法:可以采用確認(rèn)機(jī)制,發(fā)送方在發(fā)送消息的時(shí)候必須要保證要收到一個(gè)確認(rèn)消息,如果沒(méi)有收到或者收到失敗的確認(rèn)消息,就說(shuō)明消息發(fā)送失敗,要重新進(jìn)行發(fā)送,確認(rèn)機(jī)制是可以采用異步進(jìn)行的,這樣就極大地保證了在保留效率的基礎(chǔ)上又能保證消息的不丟失問(wèn)題.
第二個(gè)丟失問(wèn)題可能是在mq方發(fā)生的,如果mq沒(méi)有進(jìn)行持久化,出現(xiàn)了宕機(jī)關(guān)機(jī)等情況,消息就會(huì)丟失,解決辦法無(wú)非就是將消息進(jìn)行持久化,這樣在出現(xiàn)問(wèn)題的時(shí)候可以及時(shí)對(duì)消息進(jìn)行恢復(fù).
第三個(gè)丟失問(wèn)題可能在消費(fèi)方發(fā)生,這和發(fā)送方丟失問(wèn)題類(lèi)似,解決這個(gè)問(wèn)題也是采用確認(rèn)機(jī)制,這樣一來(lái)就可以實(shí)現(xiàn)效率上的保證和消息不丟失的保證.
但是解決了這些問(wèn)題,就會(huì)產(chǎn)生下面的冪等性問(wèn)題:
我們都知道m(xù)q是可以進(jìn)行重發(fā)的,且只有在它認(rèn)為失敗的情況會(huì)進(jìn)行重發(fā).什么時(shí)候mq會(huì)認(rèn)為它發(fā)送給消費(fèi)者的消息是失敗的呢?也就是超出了它等待消費(fèi)者響應(yīng)的時(shí)間,這是一個(gè)超時(shí)時(shí)間,若是過(guò)了這個(gè)時(shí)間消費(fèi)者仍然沒(méi)有響應(yīng),說(shuō)明mq發(fā)送失敗,就會(huì)進(jìn)行重試,而其實(shí)這個(gè)時(shí)候消費(fèi)者可能是沒(méi)有失敗的,它只是因?yàn)槟硞€(gè)原因?qū)е孪M(fèi)超出了mq的等待時(shí)間而已,這個(gè)時(shí)候mq再發(fā)送一次消息,消費(fèi)者就會(huì)重復(fù)消費(fèi).
實(shí)現(xiàn)冪等性消費(fèi):
MQ相關(guān)面試題
https://blog.csdn.net/weixin_47303191/article/details/124693751
MongoDB相關(guān)面試題
https://blog.csdn.net/KangJinXuan/article/details/126936926
使用swoole遇到了哪些問(wèn)題
a.進(jìn)程隔離:
多進(jìn)程之間會(huì)產(chǎn)生進(jìn)程隔離,global無(wú)效,不能共用一個(gè)mysql,redis連接,所以每個(gè)進(jìn)程單獨(dú)開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接
如何解決:redis 、swoole_table
b.是否可以共用1個(gè)redis或mysql連接
不可以,無(wú)法確定返回處理的reactor的id
c. 為什么客戶端請(qǐng)求一次數(shù)據(jù),服務(wù)器接收兩條記錄
icons
d.為什么onReceive收到的數(shù)據(jù)這么大
客戶端發(fā)送的多次請(qǐng)求,服務(wù)端是可以一次性接收的。并不是客戶端發(fā)送一次,服務(wù)端接收一次
不可以。
進(jìn)程、線程、協(xié)程區(qū)別
進(jìn)程擁有自己獨(dú)立的堆和棧,既不共享堆,亦不共享?xiàng)?,進(jìn)程由操作系統(tǒng)調(diào)度。
線程擁有自己獨(dú)立的棧和共享的堆,共享堆,不共享?xiàng)#€程也由操作系統(tǒng)調(diào)度。
協(xié)程和線程一樣共享堆,不共享?xiàng)?,協(xié)程由程序員在代碼里調(diào)度。
為什么你要用swoole,能解決你項(xiàng)目中的哪些痛點(diǎn)?
swoole是一個(gè)網(wǎng)絡(luò)通訊和異步IO的引擎,一個(gè)基礎(chǔ)庫(kù);
swoole相比于apache/fpm,主要節(jié)省了PHP框架和全局對(duì)象每次創(chuàng)建銷(xiāo)毀帶來(lái)的性能開(kāi)銷(xiāo),是進(jìn)程常駐內(nèi)存型。
你是如何通過(guò)swoole提升性能的,怎么做的?
(1).進(jìn)程常駐內(nèi)存:
swoole本身是進(jìn)程常駐內(nèi)存,在進(jìn)程啟動(dòng)的時(shí)候就將PHP框架等代碼讀取并編譯完成,不需要每次啟動(dòng)的時(shí)候都執(zhí)行編譯步驟,大大降低了腳本的運(yùn)行時(shí)間;
(2).連接池
php-fpm的模式php因?yàn)槊看握?qǐng)求結(jié)束時(shí)都會(huì)銷(xiāo)毀所有資源,因此無(wú)法使用連接池;而基于swoole的進(jìn)程常駐內(nèi)存模式,可以通過(guò)連接池的方式來(lái)加速程序,
使用連接池既可以降低程序的響應(yīng)時(shí)間,又可以有效保護(hù)后端資源。,限定了最多連接數(shù)量,不會(huì)直接全部打到數(shù)據(jù)庫(kù)
(3).可以使用協(xié)程處理異步IO
當(dāng)開(kāi)發(fā)中需要去請(qǐng)求多處的數(shù)據(jù),而每一塊的數(shù)據(jù)單獨(dú)請(qǐng)求都要花較長(zhǎng)時(shí)間,常規(guī)的php-fpm是阻塞式運(yùn)行,無(wú)法對(duì)這類(lèi)型的數(shù)據(jù)處理進(jìn)行加速;而基于swoole的程序,可以將這類(lèi)的業(yè)務(wù)并行化處理,并行去請(qǐng)求后端的數(shù)據(jù)源,能夠大大優(yōu)化了此類(lèi)業(yè)務(wù)的運(yùn)行時(shí)間。
例如:我們開(kāi)發(fā)的時(shí)候經(jīng)常會(huì)遇到一個(gè)請(qǐng)求要查詢多塊數(shù)據(jù),每個(gè)數(shù)據(jù)之間都需要占用比較長(zhǎng)的時(shí)間,常規(guī)的php-fpm模式因?yàn)槭亲枞J竭\(yùn)行,無(wú)法對(duì)這類(lèi)業(yè)務(wù)進(jìn)行很好的加速。但是基于swoole的程序,可以將這類(lèi)請(qǐng)求協(xié)程化處理,并行的去請(qǐng)求后端數(shù)據(jù)源,將原本sum(a+b+c)的時(shí)間變成接近max(a, b, c)。能夠大大的優(yōu)化此類(lèi)業(yè)務(wù)。
swoole里的協(xié)程是什么,怎么用?為什么協(xié)程可以提高并發(fā)?
協(xié)程是通過(guò)協(xié)作而不是搶占的方式來(lái)進(jìn)行切換,它創(chuàng)建和切換對(duì)內(nèi)存等資源比線程小的多(可以理解為更小的線程);
協(xié)程的使用是通過(guò)Swoole\Coroutine或者Co\命名空間短命名簡(jiǎn)化類(lèi)名來(lái)創(chuàng)建;
協(xié)程可以異步處理任務(wù),支持并發(fā),并且資源消耗小。
用了swoole以后,會(huì)不會(huì)發(fā)生內(nèi)存泄漏?如果發(fā)生了怎么解決?
swoole由于是常駐內(nèi)存,一旦資源加載進(jìn)入后,會(huì)一直存在于內(nèi)存中。對(duì)于局部變量,swoole會(huì)在回調(diào)函數(shù)結(jié)束后自動(dòng)釋放;對(duì)于全局變量(lobal聲明的變量,
static聲明的對(duì)象屬性或者函數(shù)內(nèi)的靜態(tài)變量和超全局變量),swoole不會(huì)自動(dòng)釋放;因此操作不好會(huì)發(fā)生內(nèi)存泄漏。
解決:(1).在onClose回調(diào)內(nèi)清理變量;
(2).swoole提供了max_request和max_task_request機(jī)制:進(jìn)程完成指定數(shù)量的任務(wù)后,會(huì)自動(dòng)退出,達(dá)到釋放資源和內(nèi)存的目的;而后manager進(jìn)程會(huì)重新拉起新worker/task進(jìn)程來(lái)繼續(xù)處理任務(wù)。
使用限制:
max_request只能用于同步阻塞、無(wú)狀態(tài)的請(qǐng)求響應(yīng)式服務(wù)器程序;
純異步的Server不應(yīng)當(dāng)設(shè)置max_request
使用Base模式時(shí)max_request是無(wú)效的文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-470991.html
Swoole進(jìn)程結(jié)構(gòu)
當(dāng)啟動(dòng)一個(gè)Swoole應(yīng)用時(shí),一共會(huì)創(chuàng)建2 + n + m個(gè)進(jìn)程,2為一個(gè)Master進(jìn)程和一個(gè)Manager進(jìn)程,其中n為Worker進(jìn)程數(shù)。m為T(mén)askWorker進(jìn)程數(shù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-470991.html
到了這里,關(guān)于PHP常見(jiàn)中高面試題匯總(附答案)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!