1.laravel中的設(shè)計模式
單例模式 工程模式
class DB{
private static $Instance=null;
private $link;
private function __construct($host,$user,$pwd)
{
$this->link=mysql_connect($host,$user,$pwd);
if(!$this->link){
return false;
}
return $this->link;
}
private function __clone()
{
return false治专;
}
public function static getInstance($host,$user,$pwd)
{
if(self::$Instance==null){
return self::$Instance=new self($host,$user,$pwd);
}
return self::$Instance;
}
}
2.php常用數(shù)組函數(shù)
array_chunk() array_diff() list() in_array() sort() array_merge() array_coulmn() array_search()
3.排序
function($arr,$key)
{
for($i=0;$i<count($i)-1;i++){
for($j=0;$j<count($j)-1-$i;$j++){
if($arr[$j][$key]<$arr[$j+1][$key]){
$tmp=$arr[$j+1];
$arr[$j+1]=$arr[$j];
$arr[$j]=$tmp;
}
}
}
return $arr;
}
4.PHP中數(shù)組的結(jié)構(gòu)實現(xiàn)
hashtable
5.nginx epoll 和poll
6.數(shù)據(jù)庫的事務隔離級別
mysql事務隔離級別
①讀未提交
②讀已提交
③可重復讀
④串行化
為了解決臟讀、不可重復讀暖途、幻讀 支持程度
7.抽象類和接口的區(qū)別
抽象類特點
①顧名思義鳞溉,它是抽象的瘾带,當然也就是不能被實例化。所以熟菲,抽象類一般是作為我們的基類來進行定義的
②在一個類中只要有一個方法被定義為抽象的月弛,那么這個類就必須加上abstract關(guān)鍵字成為抽象類
③被定義為抽象的方法只聲明其調(diào)用方式肴盏,不能定義其具體的功能實現(xiàn)
④子類必須定義父類中的所有抽象方法,這些方法的訪問控制必須和父類一致或更為寬松
⑤方法的調(diào)用方式必須匹配帽衙,即類型和所需參數(shù)數(shù)量必須一致菜皂。子類實現(xiàn)的抽象方法可以增加參數(shù)但必須有默認值
接口的特點
①可以指定某個類必須實現(xiàn)哪些方法,但不需要定義這些方法的具體內(nèi)容
②就行定義一個標準的類一樣厉萝,但其中定義所有的方法都是空的
③接口中定義的所有方法都必須是共有恍飘,這是接口的特性
④類中必須實現(xiàn)接口中定義的所有方法,否則會報一個致命錯誤谴垫,類可以實現(xiàn)多個接口用逗號來分隔多個接口名稱
⑤類要實現(xiàn)接口章母,必須使用和接口中所定義的方法完全一致的方式,否則會導致致命錯誤
⑥接口也可以繼承通過extends操作符
⑦接口也可以繼承定義常量翩剪,接口常量和類常量的使用完全相同乳怎,但是不能唄子類或子接口所覆蓋
抽象類和接口區(qū)別
①抽象類的子類遵循繼承原則,只能有一個父類前弯;但一個類可以實現(xiàn)多個接口
②抽象類中可以有非抽象的已經(jīng)實現(xiàn)的方法蚪缀;接口中全是抽象方法,都是方法定義
③抽象類中方法和變量的訪問控制自己定義恕出;接口中只能是公用的
8.主鍵索引和唯一索引的區(qū)別
①主鍵索引是一種約束询枚,唯一索引是一種索引,兩者在本質(zhì)上是不同的
②唯一索引可以是多個 主鍵索引在一個表中只能有一個
③主鍵索引唯一且不能為空浙巫,唯一索引允許空值
9.多態(tài)
多態(tài)是指 OOP 能夠根據(jù)使用類的上下文來重新定義或改變類的性質(zhì)或行為金蜀,或者說接口的多種不同的實現(xiàn)方式即為多態(tài)
10.cookie和session區(qū)別
http是無狀態(tài)的cookie可以解決記錄在客戶端狀態(tài)的問題,cookie會根據(jù)從服務端發(fā)來的響應報文里的set-cookie首部字段通知客戶端去保存cookie的畴,等下一次客戶端在向服務端發(fā)送請求時客戶端會自動再請求報文里加入cookie值渊抄,服務端接收到來自客戶端的cookie會進行對比從而得到之前的狀態(tài)信息
cookie安全保護機制是同源策略(三元組name,domin丧裁,path)進行判斷的抒线,還有httponly和secure屬性限制當secure設(shè)置為true,cookie就只能在https中傳送到服務端渣慕,對重要的值會加上httponly,防止惡意獲取
cookie禁用怎么使用session
通過url來傳送sessionId
設(shè)置session.use_trans_sid = 1或者編譯時打開打開了--enable-trans-sid選項
這樣他會在每個url后面自動加上PHPSESSID的值抱慌,然后正常使用session就可以了
session生理周期回收機制
PHP內(nèi)置了session回收機制
在php.ini中session.gc_maxlifetime為session設(shè)置了生存時間(默認為1440s)
如果session文件的最后更新時間到現(xiàn)在超過了生存時間逊桦,這個session文件就被認為是過期的了。在下一次session回收的時候就會被刪除抑进。那下一次session回收是在什么時候呢强经?這和php請求次數(shù)有關(guān)的。在PHP內(nèi)部機制中寺渗,當php被請求了N次后就會有一次觸發(fā)回收機制匿情。到底是請求多少次觸發(fā)一次是通過以下兩個參數(shù)控制的:
session.gc_probability = 1
session.gc_divisor = 100
11.redis
memcache
key 不能超過 250 個字節(jié)兰迫;
value 不能超過 1M 字節(jié);
key 的最大失效時間是 30 天炬称;
只支持 K-V 結(jié)構(gòu)汁果,不提供持久化和主從同步功能
redis
與 memcache 不同的是,Redis 采用單線程模式處理請求玲躯。這樣做的原因有 2 個:一個是因為采用了非阻塞的異步事件處理機制据德;另一個是緩存數(shù)據(jù)都是內(nèi)存操作 IO 時間不會太長,單線程可以避免線程上下文切換產(chǎn)生的代價跷车。
Redis 支持持久化棘利,所以 Redis 不僅僅可以用作緩存,也可以用作 NoSQL 數(shù)據(jù)庫朽缴。
相比 memcache善玫,Redis 還有一個非常大的優(yōu)勢,就是除了 K-V 之外密强,還支持多種數(shù)據(jù)格式茅郎,例如 list、set誓斥、sorted set只洒、hash 等。
Redis 提供主從同步機制劳坑,以及 Cluster 集群部署能力毕谴,能夠提供高可用服務
reids單線程為什么快?
redis采用單線程模式處理請求距芬。這樣做的原因有2個:一個是采用了非阻塞的異步事件處理機制涝开;另一個是緩存數(shù)據(jù)都是內(nèi)存io時間不會太長,單線程可以避免線程上下文切換產(chǎn)生的代價
緩存雪崩
緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時間框仔,而查詢數(shù)據(jù)量巨大舀武,引起數(shù)據(jù)庫壓力過大甚至down機。和緩存擊穿不同的是离斩, 緩存擊穿指并發(fā)查同一條數(shù)據(jù)银舱,緩存雪崩是不同數(shù)據(jù)都過期了,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫
解決方案
使用快速失敗的熔斷策略跛梗,減少 DB 瞬間壓力寻馏;
使用主從模式和集群模式來盡量保證緩存服務的高可用
緩存穿透
緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),而用戶不斷發(fā)起請求核偿。由于緩存是不命中時被動寫的诚欠,并且出于容錯考慮,如果從存儲層查不到數(shù)據(jù)則不寫入緩存,這將導致這個不存在的數(shù)據(jù)每次請求都要到存儲層去查詢轰绵,失去了緩存的意義粉寞。
在流量大時,可能DB就掛掉了左腔,要是有人利用不存在的key頻繁攻擊我們的應用唧垦,這就是漏洞
解決方案
從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到翔悠,這時也可以將key-value對寫為key-null业崖,緩存有效時間可以設(shè)置短點,如30秒(設(shè)置太長會導致正常情況也沒法使用)蓄愁。這樣可以防止攻擊用戶反復用同一個id暴力攻擊
緩存擊穿
緩存擊穿是指緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)(一般是緩存時間到期)双炕,這時由于并發(fā)用戶特別多,同時讀緩存沒讀到數(shù)據(jù)撮抓,又同時去數(shù)據(jù)庫去取數(shù)據(jù)妇斤,引起數(shù)據(jù)庫壓力瞬間增大,造成過大壓力丹拯。
解決方案
1站超、設(shè)置熱點數(shù)據(jù)永遠不過期
3、布隆過濾器
4乖酬、加互斥鎖
持久化
Redis 提供了 RDB 和 AOF 兩種持久化方式死相,RDB 是把內(nèi)存中的數(shù)據(jù)集以快照形式寫入磁盤,實際操作是通過 fork 子進程執(zhí)行咬像,采用二進制壓縮存儲算撮;AOF 是以文本日志的形式記錄 Redis 處理的每一個寫入或刪除操作。
RDB 把整個 Redis 的數(shù)據(jù)保存在單一文件中县昂,比較適合用來做災備肮柜,但缺點是快照保存完成之前如果宕機,這段時間的數(shù)據(jù)將會丟失倒彰,另外保存快照時可能導致服務短時間不可用审洞。
AOF 對日志文件的寫入操作使用的追加模式,有靈活的同步策略待讳,支持每秒同步芒澜、每次修改同步和不同步,缺點就是相同規(guī)模的數(shù)據(jù)集创淡,AOF 要大于 RDB痴晦,AOF 在運行效率上往往會慢于 RDB。
過期策略和內(nèi)存淘汰
過期策略
客戶端主動給Rediskey設(shè)置的過期時間到達過期時間進行刪除
惰性刪除:key被操作時會檢查過期時間不會主動刪除 導致冷數(shù)據(jù)長期存在內(nèi)存中無法釋放占用內(nèi)存
定期刪除:隨機檢測部分的key辩昆,并刪除,當過期數(shù)據(jù)達到25%時候會再次檢查
內(nèi)存淘汰
默認策略 申請內(nèi)存操作報錯
FIFO先進先出 越早過期的key就越早刪除
隨機刪除
LRU最近最少使用的key刪除
LFU最不經(jīng)常使用的key先刪除
Nginx
Nginx采用異步非阻塞的方式來處理網(wǎng)絡事件
master進程先建好需要listen的socket后旨袒,然后再fork出多個woker進程汁针,這樣每個work進程都可以去accept這個socket术辐。當一個client連接到來時,所有accept的work進程都會受到通知施无,但只有一個進程可以accept成功辉词,其它的則會accept失敗。Nginx提供了一把共享鎖accept_mutex來保證同一時刻只有一個work進程在accept連接猾骡,從而解決驚群問題瑞躺。當一個worker進程accept這個連接后,就開始讀取請求兴想,解析請求幢哨,處理請求,產(chǎn)生數(shù)據(jù)后嫂便,再返回給客戶端捞镰,最后才斷開連接,這樣一個完成的請求就結(jié)束了毙替。
PHP浮點計算減少誤差
bcmath 還提供了以下方法:
bccomp 比較兩個任意精度的數(shù)字
bcmod 對一個任意精度數(shù)字取模
bcpow 任意精度數(shù)字的乘方
bcpowmod 高精度數(shù)字乘方求模
bcscale 設(shè)置所有bc數(shù)學函數(shù)的默認小數(shù)點保留位數(shù)
bcsqrt 任意精度數(shù)字的二次方根
PHP array_merge和+
數(shù)組相加以數(shù)字和字符串為key值都不變 并以前面數(shù)組為基準 相同鍵值會覆蓋
數(shù)組合并以字符串為key值的不變 并以后面的為基準 相同鍵值會覆蓋
12.線程間如何進行通訊
①線程之間可以通過共享內(nèi)存或給予網(wǎng)絡通信
②如果是通過共享內(nèi)存來進行通信岸售,則需要考慮并發(fā)問題,什么時候阻塞厂画,什么時候喚醒
③像Java中wait()凸丸,notify(),就是阻塞和喚醒
④通過網(wǎng)絡就比較簡單了,通過網(wǎng)絡將通信數(shù)據(jù)發(fā)送給對方袱院,當然也要考慮并發(fā)問題屎慢,處理方式就是加上等方式
13.分布式鎖實現(xiàn)
分布式鎖解決的問題本質(zhì)是:能夠?qū)Ψ植荚诙嗯_機器中的線程對共享資源互斥訪問,在這個原理上可以有很多的實現(xiàn)方式
①基于mysql坑填,分布式環(huán)境中的線程連接同一個數(shù)據(jù)庫抛人,通過數(shù)據(jù)庫中的行鎖來達到互斥訪問,但是MySQL的加鎖和釋放鎖性能比較低脐瑰,不適合真正的生產(chǎn)場景
②基于redis妖枚,reids中的數(shù)據(jù)也是在內(nèi)存,基于redis的消費訂閱功能苍在,數(shù)據(jù)超時時間绝页,lua腳本等功能,也能很好的實現(xiàn)分布式鎖
14.redis數(shù)據(jù)結(jié)構(gòu)和使用場景
①字符串:可以用來做最簡單的數(shù)據(jù)緩存寂恬,可以緩存某個簡單的字符串续誉,也可以緩存某個json字符串,redis分布式鎖的實現(xiàn)就利用這種數(shù)據(jù)結(jié)構(gòu)初肉,還包括可以實現(xiàn)計數(shù)器酷鸦、session共享、分布式id
②哈希表:可以用來存儲key-value對,更適合用來存儲對象
③列表:redis的列表通過命令的組合臼隔,既可以當做棧又可以當做隊列來使用嘹裂,也可以緩存公眾號、微博等消息流數(shù)據(jù)
④集合:和列表類似摔握,也可以存儲多個元素寄狼,但不能重復,集合可以進行交集氨淌、并集泊愧、差集操作,從而可以實現(xiàn)類似盛正,我和某人共同關(guān)注的人删咱,朋友圈點贊等功能
⑤有序集合:集合是無序的,有序集合可以設(shè)置順序蛮艰,可以用來實現(xiàn)排行榜等功能
15.redis集群策略
redis提供了三種集群策略:
①主從模式:這種模式比較簡單腋腮,主庫可以讀寫,并且和從庫進行數(shù)據(jù)同步壤蚜,這種模式下即寡,客戶端直接連接主庫或某個從庫,但是主庫或從庫宕機后袜刷,客戶端需要手動修改ip聪富,另外,這種模式也比較難以擴容著蟹,整個集群所能存儲的數(shù)據(jù)受到某臺機器的內(nèi)存容量墩蔓,所以不支持特大數(shù)據(jù)量存儲
②哨兵模式:這種模式在主從的基礎(chǔ)上新增了哨兵節(jié)點,當主庫宕機后萧豆,哨兵節(jié)點會發(fā)現(xiàn)主節(jié)點宕機奸披,然后從從庫選擇一個庫作為主庫,另外哨兵也可以做集群涮雷,從而可以保證某一個哨兵節(jié)點宕機后阵面,還有其它哨兵節(jié)點可以繼續(xù)工作,這種模式可以比較好的保證redis集群高可用洪鸭,但是仍然不能解決redis容量上限問題
③cluster模式:cluster模式是用的比較多的模式样刷,它支持多主多從,這種模式按照key進行槽位分配览爵,可以使不同的key分撒到不同的主節(jié)點上置鼻,利用這種模式可以使整個集群支撐大的容量,同時主節(jié)點可以擁有自己多個從節(jié)點蜓竹,如果該節(jié)點宕機箕母,會從的從節(jié)點選舉一個新的主節(jié)點
對于這三種模式储藐,如果redis要存的數(shù)據(jù)量不大,可以選擇哨兵模式嘶是,如果redis要存的數(shù)據(jù)量大邑茄,并且要持續(xù)擴展,那么選擇cluster模式
16.B樹和B+樹
①B樹特點:節(jié)點排序 一個節(jié)點可以存儲多個元素俊啼,多個元素也排好了順序
②B+樹特點:擁有B樹的特點 葉子結(jié)點之間有指針 非葉子節(jié)點上的元素在葉子節(jié)點有冗余,這就是葉子節(jié)點中也存儲了所有元素左医,并且排好了順序
mysql索引使用的是B+樹授帕,因為索引是用來加快查詢的,而B+樹對數(shù)據(jù)進行排序所以是可以提高查詢速度的浮梢,然后通過一個節(jié)點存儲多個元素跛十,從而可以使B+樹的節(jié)點不會太高,在mysql中一個innodb也就是月給他節(jié)點秕硝,一個innodb頁默認16kb芥映,所以一般情況下一顆兩層的B+數(shù)可以存儲2000萬行左右的數(shù)據(jù)然后通過利用B+樹葉子結(jié)點存儲了數(shù)據(jù)所有元素并且進行了排序,可以很好的支持全表掃描远豺,范圍查找等sql語句
17.poll和epoll
①select模型奈偏,使用的是數(shù)組存儲socket連接文件描述符,容量是固定的躯护,需要通過輪詢來判斷是否發(fā)生了io事件
②poll模型惊来,使用的是鏈表來存儲socket連接文件描述符,容量是不固定的棺滞,同樣需要通過輪詢來判斷是否發(fā)生了io事件
③epoll模型裁蚁,epoll和poll模型完全不同,epoll是一種事件通知模型继准,當發(fā)生了io事件枉证,應用程序才進行io操作,不需要向poll那樣主動去輪詢