【精講】2022年P(guān)HP中高級面試題(二)
?function?IP2Long($ip)?{
?$ips?=?explode('.',?$ip);?
??if(count($ips)?!=?4)?{
???return?false;
??}
???return?($ips[0]?<24)?+?($ips[1]?<16)?+?($ips[2]?<8)?+?$ips[3];
?}
?function?Long2IP($int)?{
?$ip1?=?$ipint?>>?24;
?$ip2?=?($ipint?>>?16)?&?255;
?$ip3?=?($ipint?>>?8)?&?255;
?$ip4?=?$ipint?&?255;
?return?$ip1.'.'.$ip2.'.'.$ip3.'.'.$ip4;?
?}
2.php鏈?zhǔn)秸{(diào)用:
1 使用魔法函數(shù)__call結(jié)合call_user_func來實(shí)現(xiàn)
2 使用魔法函數(shù)__call結(jié)合call_user_func_array來實(shí)現(xiàn)
3 不使用魔法函數(shù)__call來實(shí)現(xiàn),修改 __call() 為 trim重點(diǎn)在于,返回$this指針,方便調(diào)用后者函數(shù)。
3.?不使用第三個(gè)變量來交換兩個(gè)變量的值
兩個(gè)為 數(shù)字時(shí)
?
/**
?*雙方變量為數(shù)字時(shí),可用交換方法,使用加減運(yùn)算符,相當(dāng)于數(shù)學(xué)運(yùn)算了
?*/
$a?=?1;?//a變量原始值
$b?=?2;??//b變量原始值
echo?'交換之前?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出原始值
$a?=?$a?+?$b;?//?$a?$b和值
$b?=?$a?-?$b;?//?不解釋..
$a?=?$a?-?$b;?//?不解釋..
echo?'交換之后?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出結(jié)果值兩個(gè)為字符串時(shí)
/**
?*?雙方變量為字符串或者數(shù)字時(shí),可用交換方法四
?*?使用異或運(yùn)算
?*/
$a?=?"This?is?A";?//?a變量原始值
$b?=?"This?is?B";?//?b變量原始值
echo?'交換之前?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出原始值
/**
?*?原始二進(jìn)制:
?*?$a:010101000110100001101001011100110010000001101001011100110010000001?000001
?*?$b:010101000110100001101001011100110010000001101001011100110010000001?000010
?*?下面主要使用按位異或交換,具體請參照下列給出的二進(jìn)制過程,
?*/
$a?=?$a?^?$b;?//?此刻?$a:000000000000000000000000000000000000000000000000000000000000000000?000011
$b?=?$b?^?$a;?//?此刻?$b:010101000110100001101001011100110010000001101001011100110010000001?000001
$a?=?$a?^?$b;?//?此刻?$a:010101000110100001101001011100110010000001101001011100110010000001?000010
echo?'交換之后?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出結(jié)果值或者 str_replace 處理
$a?=?"This?is?A";?//?a變量原始值
$b?=?"This?is?B";?//?b變量原始值
echo?'交換之前?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出原始值
$a?.=?$b;?//?將$b的值追加到$a中
$b?=?str_replace($b,?"",?$a);?//?在$a(原始$a+$b)中,將$b替換為空,則余下的返回值為$a
$a?=?str_replace($b,?"",?$a);?//?此時(shí),$b為原始$a值,則在$a(原始$a+b)中將$b(原始$a)替換為空,則余下的返回值則為原始$b,交換成功
echo?'交換之后?$a?的值:'?.?$a?.?',?$b?的值:'?.?$b,?'
';?//?輸出結(jié)果值
4.Strtoupper/strtolower 遇到中文會亂碼
需要手動分割字符串,然后 ord 函數(shù)判斷是否是單詞,是則大小寫轉(zhuǎn)換,中文則不處 理
mb_convert_case 函數(shù)中有可選參數(shù),直接能處理這種情況
CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。
FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。
PHP-CGI:是 PHP (Web Application)對 Web Server 提供的 CGI 協(xié)議的接口程 序。
PHP-FPM:是 PHP(Web Application)對 Web Server 提供的 FastCGI 協(xié)議的接口 程序,額外還提供了相對智能一些任務(wù)管理。
Fastcgi 是常駐類型的,不需要每次去激活了
FastCGI程序會 先啟動一個(gè)master,解析配置環(huán)境,初始化執(zhí)行環(huán)境,然后再啟動多個(gè)worker。當(dāng)請求過來時(shí),master會傳遞給一個(gè)worker,然后立即可以接受下一個(gè)請 求。
首先要說的是:fastcgi是一個(gè)協(xié)議,php-fpm實(shí)現(xiàn)了這個(gè)協(xié)議。
大家都知道,PHP的解釋器是php-cgi。php-cgi只是個(gè)CGI程序,他自己本身只能解析 請求,返回結(jié)果,不會進(jìn)程管理,所以就出現(xiàn)了一些能夠調(diào)度php-cgi進(jìn)程的程序,php-fpm就是這樣的一個(gè)東西。它克服了php-cgi變更php.ini配置后,需重啟php-cgi才能讓新的php-ini生效,不可以平滑重啟,直接殺死php-cgi進(jìn)程,php就不能運(yùn)行了 的問題。修改php.ini之后,php-cgi進(jìn)程的確沒辦法平滑重啟的。php-fpm對此的處理 機(jī)制是新的worker用新的配置,已經(jīng)存在的worker處理完手上的活就可以歇著了,通 過這種機(jī)制來平滑過度。

6.Explain 后需要關(guān)注的信息
|
列名
|
備注
|
|
type
|
本次查詢表聯(lián)接類型,從這里可以看到本次查詢大概的效率
|
|
key
|
最終選擇的索引,如果沒有索引的話,本次查詢效率通常很差
|
|
key_le n
|
本次查詢用于結(jié)果過濾的索引實(shí)際長度,參見另一篇分享(FAQ系列-解讀EXPLAIN執(zhí)行計(jì)劃中的key_len)
|
|
rows
|
預(yù)計(jì)需要掃描的記錄數(shù),預(yù)計(jì)需要掃描的記錄數(shù)越小越好
|
|
Extra
|
額外附加信息,主要確認(rèn)是否出現(xiàn) Using filesort、Using temporary 這 兩種情況
|
首先看下 type 有幾種結(jié)果,分別表示什么意思:
|
類型
|
備注
|
|
ALL
|
執(zhí)行full table scan,這是最差的一種方式
|
|
index
|
執(zhí)行full index scan,并且可以通過索引完成結(jié)果掃描并且直接從索引中 取的想要的結(jié)果數(shù)據(jù),也就是可以避免回表,比ALL略好,因?yàn)樗饕募?常比全部數(shù)據(jù)要來的小
|
|
range
|
利用索引進(jìn)行范圍查詢,比index略好
|
|
index_sub query
|
子查詢中可以用到索引
|
|
unique_su bquery
|
子查詢中可以用到唯一索引,效率比 index_subquery 更高些
|
|
index_mer ge
|
可以利用index merge特性用到多個(gè)索引,提高查詢效率
|
|
ref_or_null
|
表連接類型是ref,但進(jìn)行掃描的索引列中可能包含NULL值
|
|
fulltext
|
全文檢索
|
|
ref
|
基于索引的等值查詢,或者表間等值連接
|
|
eq_ref
|
表連接時(shí)基于主鍵或非NULL的唯一索引完成掃描,比ref略好
|
|
const
|
基于主鍵或唯一索引唯一值查詢,最多返回一條結(jié)果,比eq_ref略好
|
|
system
|
查詢對象表只有一行數(shù)據(jù),這是最好的情況
|
上面幾種情況,從上到下一次是最差到最好。再來看下Extra列中需要注意出現(xiàn)的幾種情況:
|
關(guān)鍵字
|
備注
|
|
Using filesort
|
將用外部排序而不是按照索引順序排列結(jié)果,數(shù)據(jù)較少時(shí)從內(nèi)存排序, 否則需要在磁盤完成排序,代價(jià)非常高,需要添加合適的索引
|
|
Using temporary
|
需要創(chuàng)建一個(gè)臨時(shí)表來存儲結(jié)果,這通常發(fā)生在對沒有索引的列進(jìn)行GROUP BY時(shí),或者ORDER BY里的列不都在索引里,需要添加合適 的索引
|
|
Using index
|
表示MySQL使用覆蓋索引避免全表掃描,不需要再到表中進(jìn)行二次查 找數(shù)據(jù),這是比較好的結(jié)果之一。注意不要和type中的index類型混淆
|
|
Using where
|
通常是進(jìn)行了全表引掃描后再用WHERE子句完成結(jié)果過濾,需要添加 合適的索引
|
|
Impossible WHERE
|
對Where子句判斷的結(jié)果總是false而不能選擇任何數(shù)據(jù),例如where 1=0,無需過多關(guān)注
|
|
Select tables optimized away
|
使用某些聚合函數(shù)來訪問存在索引的某個(gè)字段時(shí),優(yōu)化器會通過索引直 接一次定位到所需要的數(shù)據(jù)行完成整個(gè)查詢,例如MIN()\MAX(),這 種也是比較好的結(jié)果之一
|
7.Php-fpm 運(yùn)行的三種模式:
Static模式最簡單,直接啟動配置的固定數(shù)量的進(jìn)程,但是靈活性不夠高
ondemand?模式相對 static 模式比較復(fù)雜,會根據(jù)請求量的增加動態(tài)增加,但是處理完請求后不會立即釋放,而是由定時(shí)事件定時(shí)的檢測空閑到一定時(shí)間的進(jìn)程才會釋放
Dynamic 模式類似于 ondemand 模式,但進(jìn)程的回收機(jī)制不同于 ondemand 模式, 會根據(jù) idle 數(shù)量進(jìn)行增加和減少worker數(shù)量
8.Php-fpm 運(yùn)行的邏輯:
Fpm 的實(shí)現(xiàn)就是創(chuàng)建一個(gè) master 進(jìn)程,在 master 進(jìn)程中創(chuàng)建 worker pool 并監(jiān)聽 socket,然后 fork出多個(gè)子進(jìn)程(work),這些 worker 在啟動后阻塞在 fcgi_accept_request() 上,各自 accept 請求,有請求到達(dá)后 worker 開始讀取請求數(shù) 據(jù),讀取完成后開始處理然后再返回,在這期間是不會接收其它請求的,也就是說 fpm 的子進(jìn)程同時(shí)只能響應(yīng)一個(gè)請求,只有把這個(gè)請求處理完成后才會 accept 下一個(gè)請 求,所以有多少子進(jìn)程就能同時(shí)處理多少請求。
10.Fpm 工作流程:
?FastCGI 進(jìn)程管理器自身初始化,啟動多個(gè) CGI 解釋器進(jìn)程,并等待來自 Web Server 的連接。
Web 服務(wù)器與 FastCGI 進(jìn)程管理器進(jìn)行 Socket 通信,通過 FastCGI 協(xié)議發(fā) 送 CGI 環(huán)境變量和標(biāo)準(zhǔn)輸入數(shù)據(jù)給 CGI 解釋器進(jìn)程。
CGI 解釋器進(jìn)程完成處理后將標(biāo)準(zhǔn)輸出和錯(cuò)誤信息從同一連接返回 Web Server。
CGI 解釋器進(jìn)程接著等待并處理來自 Web Server 的下一個(gè)連接。
11.Nginx 與 php-fpm 有兩種通信方式:

12.數(shù)據(jù)庫連接池實(shí)現(xiàn)原理
連接池的作用就是為了提高性能,將已經(jīng)創(chuàng)建好的連接保存在池中,當(dāng)有請求來時(shí),直 接使用已經(jīng)創(chuàng)建好的連接對 Server 端進(jìn)行訪問。這樣 省略了創(chuàng)建連接和銷毀連接的過 程,從而提高性能。
13.Redis 常見應(yīng)用場景
首頁熱點(diǎn)新聞/商品,避免頻繁讀取數(shù)據(jù)庫 bitmap 用來記錄連續(xù)簽到/登錄情況 新
聞閱讀量的計(jì)數(shù)器
最新新聞列表 lpush 就行,然后讀取 簡單的消息發(fā)布系統(tǒng) pubsub sortedset 來做
排行榜
2 DNS 負(fù)載均衡,DNS支持一個(gè)域名多個(gè)ip地址了
3 反向代理負(fù)載均衡,NGINX 根據(jù)一定規(guī)則進(jìn)行請求分發(fā)
4 F5硬件級別
6 CDN 對于靜態(tài)文件的負(fù)載均衡 負(fù)載均衡構(gòu)建在原有網(wǎng)絡(luò)結(jié)構(gòu)之上,它提供了一種透明且廉價(jià)有效的方法擴(kuò)展服務(wù)器和 網(wǎng)絡(luò)設(shè)備的帶寬、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力、增加吞吐量、提高網(wǎng)絡(luò)的可用性和靈活性。
15.數(shù)據(jù)庫主從復(fù)制的原理,會不會延遲,會該怎樣解決
三個(gè)要點(diǎn):網(wǎng)絡(luò)延遲,master 負(fù)載 slave 負(fù)載 slave 對數(shù)據(jù)安全性的要求
master 將數(shù)據(jù)改變記錄到 binlog 中?
slave 啟動一個(gè)io線程,從指定位置開 始同步 binlog?
讀取到 master 數(shù)據(jù)的更新,slave 寫入到 replaylog 中,然后開始重 放數(shù)據(jù)
Tps 是事務(wù)數(shù)/秒 qps 是每秒查詢率
解決:減少網(wǎng)絡(luò)延遲,關(guān)閉 slave 的 sync_binlog 設(shè)置成大點(diǎn)就行,累計(jì)多次事務(wù)之后 刷盤 innodb_flush_log_at_trx_commit = 2 事務(wù)提交之后刷盤,slave 上也可以關(guān)閉 這個(gè),缺點(diǎn)是意外斷電了會丟失數(shù)據(jù)
數(shù)據(jù)庫集群方案就行,刪掉主庫了會自動選舉從庫,業(yè)務(wù)保持穩(wěn)定,然后就是精細(xì)化的 備份

2021年最新大廠php+go面試題集(四)

2021年最新大廠php+go面試題集(三)

2021年最新大廠php+go面試題集(二)

2021年最新大廠php+go面試題集(1)

面試官問:如何防超賣,有幾種實(shí)現(xiàn)方式
