其實最近還在職,不過處於辭職交接狀態,就掛了履歷,但沒投。看到有邀約的,就和自己高度匹配的幾家面試了,陸續拿到了幾個offer。回憶一波面試題。依照類別來分了,因為有些也忘了是那次面試的,列的都是印像比較深刻的題目,有些忘了。如果回答錯了,歡迎糾正補充。 (更多:PHP面試題總結)
<strong>mysql</strong>
答:2.你剛才一直在提索引,把你知道的關於索引的一些技巧說下1、select * 問題,客戶端需要什麼,就給什麼,不要給多餘的字段,這種情況可能還會導致本來可以走覆蓋索引的語句不能走覆蓋索引。
2、不要在查詢語句欄位上做函數運算,這樣會讓索引失效。
3、一定要避免mysql自動類型轉換,例如 where ‘9’ =9。
4、能不設定允許 null 的欄位盡量不要設置,因為 null 會導致 mysql 多一層判斷。
5、使用 like 的時候如果是通配符
%在最前面的話也會走的全表掃描。
歡迎補充。
#答:3.索引底層是什麼資料結構?1、要在區分度高的字段上建立索引,否則索引意義不大。
2、字串建立索引要注意大小,索引長度過長,佔用的空間也就越大,適當的可以截取進行索引,缺點是不能使用到覆蓋索引,具體根據業務合理安排。
3、建立聯合索引要知道最左前綴原則,舉例( name, email, phone ),最終能走這個聯合索引的一定只會是( name ),( name, email ),( name, email, phone ),其他只能走全表,需要依照業務合理設定聯合索引的順序。
答:B 樹。4.為什麼用的是B 樹,不能用紅黑樹或其他的?
答案:可以使用紅黑樹。但是這樣的話可能會造成樹的高度過高,意味著相同查詢下,會進行更多的磁碟I/O,影響效能,而 B 樹可以保持樹的高度不至於過高。這題答得不是很好,不只是這樣,歡迎補充。5.你知道索引下推嗎?
本質上是對普通索引需要回表的一種優化,也就是引擎層在對索引指標遍歷的過程中,先做一些優先的判斷,過濾掉不符合條件的,可以減少磁碟IO。6.假設現在有人操作資料庫,不小心執行錯了語句,誤刪除了很多數據,這時候能恢復嗎?咋麼恢復。
答:首先,一定要開啟 bin-log ,如果沒有開啟的話,可能就恢復不了。要看具體的檔案系統是否能恢復。開啟了 bin-log ,類型設定要設定成 row 或 mixed ,不能設定 statement 。然後,如果是誤刪行的話,就可以把裡面對應的刪除事件換成插入事件,在備用庫上執行。如果是誤刪表的話,可以先取得最近的一次全量備份,放到備庫,然後拿出 bin-log , 除了不執行刪除的事件,其他事件依序重播。7.為什麼不能設定成 statement ?
答案:設定成statement ,實際bin-log 儲存的是sql 語句( 非具體刪除的主鍵id ),這樣如果是主從架構的話,主和從可能因為選擇的索引不一樣而導致主從不一致。8.你剛才說到主從,那你說說主從運行的機制吧
答:首先主庫還是要開啟bin-log , 從庫先設定要連接的主庫change master… 然後執行start slave,這時候從庫會建立兩個線程,一個io_thread ,主要負責連接主資料庫。一個sql_thread 主要是負責執行中轉日誌語句。首先,主庫接收到從庫的同步請求,根據傳遞的bin-log 檔案名稱和開始同步的位置,發送二進位檔案給從庫,從庫io_thread 負責把接收到的資料放入到中轉日誌,然後sql_thread 負責從中轉日誌讀取解析執行,執行完成,更新同步的位置標誌。9.你知道主從延遲嗎?有些時候延遲的時間還會很長。遇到這種情況咋麼辦?
答:這種問題,注意了。劃重點。問你出現問題,尋找解決方案的時候,一定要對症下藥,也就是說這個問題你可以這樣考慮,什麼情況下導致的主從延遲。
1、如果主庫和從庫伺服器配置不一樣,從庫的差點,那麼就可能導致延遲時間加長。這時候,換成相同的伺服器配置伺服器即可。
2、從庫壓力太大了。一般主從了,從函式庫基本上用來查詢,例如可能營運或開發者自己都在從函式庫上進行一系列的 sql 操作。那簡單唄。多配幾個從庫,分攤壓力,一主多從。
3、大事務。例如 delete 這種語句 不 limit 限制一下,如果資料量過大,導致主函式庫運作時都花了長時間,再同步到從函式庫,這個時間間隔過長。
<strong>設計模式</strong>
#你知道哪些設計模式,你平常有使用到嗎?可以結合你的業務場景說下來嗎?
回答這裡我先舉例平常使用Laravel,裡面就用到大量設計模式,比如門面,組合,裝飾,觀察者…… 具體場景帶入,然後根據之前業務上的場景說了下…., 最後也說了設計模式不是銀彈,只有在適當的場景使用合適的模式才能體現它的價值。
<strong>手寫演算法</strong>
#給定一個已排序的陣列和一個指定值,傳回指定值在陣列中的下標位置,如果不存在,則傳回將給定值插入陣列之後的下標位置。注意時間複雜度。
例如給定有序數組[1,3,5,6] 給定值5.那麼回傳下標2.
給定有序數組[1,3,5, 6] 給定值7,回傳下標4.
#答案:
function searchInsert($nums, $target) { if (!count($nums)) return 0; $l=0; $r = count($nums)-1; while ($l <= $r){ $middle = $l + (($r - $l) >> 1); if ($nums[$middle] == $target) return $middle; if ($nums[$middle] < $target){ $l = $middle+1; }else{ $r = $middle-1; } } return $l; }
典型的可以使用二分,時間複雜度O(log2n)。空間複雜度O(1)。
<strong>網路</strong>
#1.傳輸層主要有哪些協定?
答:主要有 TCP 和 UDP 協定。他們的差別在於 TCP 是需要連線的 會經過三次握手,而且可以保證訊息的可靠性。 UDP 是不需要連接的,不保證訊息的可靠性。
2.你能大體說說 TCP 的三次握手嗎?
答:首先伺服器監聽某個端口,客戶端發起請求攜帶syn資料包(第一次),服務端接收到這個資料包,返回syn/ack 的資料包給客戶端(第二次),最後客戶端再次發送一個ack 的資料包(第三次)。
4.為什麼需要三次握手?
答:主要是為了確認雙方接收是否正常。
第一次:客戶端什麼都不能確認。服務端能確認客戶端的發送正常,自己的接收正常
第二次:客戶端能確認自己的發送和接收正常,服務端的發送和接收正常。服務端能確認自己接收正常,客戶端的發送正常。
第三次:全部都能確認了。
並發
#假設現在有多個入口可以同時使用一個帳戶操作,這個帳戶只有十塊錢,有哪些方法可以使得不超扣消費?開放性題目,只要能解決問題的就是好方案,沒有唯一答案。
答:mysql:可以直接 where amount>=current_amount and amount>0 …… , 或悲觀鎖定 for update。 redis:lua 腳本。 php 層面可以利用文件鎖,也可以使用佇列的特性,只有一個消費的出口。
<strong>設計</strong>
#如果我們公司有很多專案都有登入的功能,會咋麼設計?
回答:需要把這個登入單獨抽出來當作一個模組開發,類似於登入中心,所有的其他子系統登入都需要從這個系統中認證。
<strong>其他</strong>
#1.看你專案裡說到使用過swoole,也寫點go ,你可以說說他們協程上的差別嗎?
答:設計上他們是一樣的,主要差別在於,協程調度器模式。 swoole 的協程調度器是單線程,go 的協程調度器是多線程。這就意味著,同一時刻 swoole 只有一個協程在運行,而 go 同一時刻可以多個協程在運行。所以在 swoole 協程中不需要對全域變數進行加鎖。而且 swoole 本質是單執行緒多進程的,意味著它沒有超全域的變量,只是一個進程級變數。而 go 多線程,多線程必然會存在臨界變數鎖的問題。當然,go 也提供了開箱即用的 sync 讀寫鎖,或者你也可以直接使用通道來取代。
2.你可以說說 go 的 gmp 調度模型嗎?
答:巴拉巴拉半天,我自己都覺得沒說清楚,好吧,我不是很了解。此時猜測面試官心裡,早說不知道不就完事了嗎
3.說說你們這個專案最難的點是哪個地方,你是咋麼解決的?
那就要看你自己對專案的掌握程度以及這個專案的含金量了。
以上是新鮮出爐的PHP高級面試題來啦! 【附答案】的詳細內容。更多資訊請關注PHP中文網其他相關文章!