您當前的位置:首頁 > 收藏

2020最新大廠內部 PHP 高階工程師面試題彙總(一)

作者:由 阿布阿布 發表于 收藏時間:2020-08-29

1、給你四個座標點,判斷它們能不能組成一個矩形,如判斷 ([0,0],[0,1],[1,1],[1,0]) 能組成一個矩形。

我們分析這道題, 給4個標點,判斷是否矩形

高中知識,矩形有4條邊,兩兩相等, 矩形兩條對角線相等, 矩形的長短邊與對角線滿足勾股定理。

故解題思路為,根據座標點,

列出所有的兩點組合邊長的陣列,去重,看是不是隻剩 3個長度(注意正方形2個長度)

判斷是否滿足勾股定理

調優一下,先判斷有沒有重複的點,有的話肯定不是矩形

程式碼如下:

<?php

function isRectangle($point1, $point2, $point3, $point4){

if ($point1 == $point2 || $point1 == $point3 || $point1 == $point4 || $point2 == $point3 || $point2 == $point4 || $point3 == $point4) {

return false;

}

$lengthArr = [];

$lengthArr[] = getLengthSquare($point1, $point2);

$lengthArr[] = getLengthSquare($point1, $point3);

$lengthArr[] = getLengthSquare($point1, $point4);

$lengthArr[] = getLengthSquare($point2, $point3);

$lengthArr[] = getLengthSquare($point2, $point4);

$lengthArr[] = getLengthSquare($point3, $point4);

$lengthArr = array_unique($lengthArr);

$lengthCount = count($lengthArr);

if ($lengthCount == 3 || $lengthCount == 2 ) {

if ($lengthCount == 2) {

return(max($lengthArr) == 2*min($lengthArr));

} else {

$maxLength = max($lengthArr);

$minLength = min($lengthArr);

$otherLength = array_diff($lengthArr, [$maxLength, $minLength]);

return($minLength + $otherLength == $maxLength);

}

} else {

return false;

}

}

function getLengthSquare($point1, $point2){

$res = pow($point1[0]-$point2[0], 2)+pow($point1[1]-$point2[1], 2);

return $res;

}

var_dump(isRectangle([0,0],[0,2],[2,2],[2,0]));

2、寫一段程式碼判斷單向連結串列中有沒有形成環,如果形成環,請找出環的入口處,即 P 點

/*

*單鏈表的結點類

*/

class LNode{

//為了簡化訪問單鏈表,結點中的資料項的訪問許可權都設為public

public int data;

public LNode next;

}

class LinkListUtli {

//當單鏈表中沒有環時返回null,有環時返回環的入口結點

public static LNode searchEntranceNode(LNode L)

{

LNode slow=L;//p表示從頭結點開始每次往後走一步的指標

LNode fast=L;//q表示從頭結點開始每次往後走兩步的指標

while(fast !=null && fast。next !=null)

{

if(slow==fast) break;//p與q相等,單鏈表有環

slow=slow。next;

fast=fast。next。next;

}

if(fast==null || fast。next==null) return null;

// 重新遍歷,尋找環的入口點

slow=L;

while(slow!=fast)

{

slow=slow。next;

fast=fast。next;

}

return slow;

}

}

3、寫一個函式,獲取一篇文章內容中的全部圖片,並下載

function download_images($article_url = ‘’, $image_path = ‘tmp’){

// 獲取文章類容

$content = file_get_contents($article_url);

// 利用正則表示式得到圖片連結

$reg_tag = ‘//’;

$ret = preg_match_all($reg_tag, $content, $match_result);

$pic_url_array = array_unique($match_result1[1]);

// 建立路徑

$dir = getcwd() 。 DIRECTORY_SEPARATOR 。$image_path;

mkdir(iconv(“UTF-8”, “GBK”, $dir), 0777, true);

foreach($pic_url_array as $pic_url){

// 獲取檔案資訊

$ch = curl_init($pic_url);

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_NOBODY, 0);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE );

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE );

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$fileInfo = curl_exec($ch);

$httpinfo = curl_getinfo($ch);

curl_close($ch);

// 獲取圖片檔案字尾

$ext = strrchr($pic_url, ‘。’);

$filename = $dir 。 ‘/’ 。 uniqid() 。 $ext;

// 儲存圖片資訊到檔案

$local_file = fopen($filename, ‘w’);

if(false !== $local_file){

if( false !== fwrite($local_file, $filecontent) ){

fclose($local_file);

}

}

}

}

4、獲取當前客戶端的 IP 地址,並判斷是否在(111.111.111.111,222.222.222.222)

如果沒有使用代理伺服器:

$ip = $_SERVER[‘REMOTE_ADDR’];

使用透明代理

$ip = $_SERVER[‘HTTP_X_FORWARDED_FOR’];

5、nginx 的 log_format 配置如下:

log_format main ‘remoteaddr−remote_user [timelocal]“request”’

‘statusbody_bytes_sent “httpreferer”″“http_user_agent” “upstreamresponsetime”“request_time” “http_x_forwarded_for”‘;

從今天的 nginx log 檔案 access。log 中:

a、列出 “request_time” 最大的 20 行?

b、列出早上 10 點訪問量做多的 20 個 url 地址?

6、什麼是 CSRF 攻擊?XSS 攻擊?如何防範?

CSRF:跨站請求偽造,可以透過透過判斷來源和加 Token 的方式來防範。

XSS:跨站指令碼攻擊,可以透過對內容轉義和過濾來防範,還有 CSP

7、應用中我們經常會遇到在 user 表隨機調取 10 條資料來展示的情況,簡述你如何實現該功能。

SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

8、從撲克牌中隨機抽 5 張牌,判斷是不是一個順子,即這 5 張牌是連續的

這個問題有個關鍵點,撲克牌,1-13 不能再多了。這就很簡單了。用 PHP 來做,定義一個數組分別存著 1 到 13, 拿出一個,置空一個,最後看下 這五個置空的 是不是連續的。這種情況不考慮抽出的順序。

9、兩條相交的單向連結串列,如何求它們的第一個公共節點

思想:

如果兩個連結串列相交,則從相交點開始,後面的節點都相同,即最後一個節點肯定相同;

從頭到尾遍歷兩個連結串列,並記錄連結串列長度,當二者的尾節點不同,則二者肯定不相交;

尾節點相同,如果 A 長為 LA,B 為 LB,如果 LA>LB, 則 A 前 LA-LB 個先跳過

如果兩個單向連結串列有公共的結點,也就是說兩個連結串列從某一結點開始,它們的 m_pNext 都指向同一個結點。但由於是單向連結串列的結點,每個結點只有一個 m_pNext,因此從第一個公共結點開始,之後它們所有結點都是重合的,不可能再出現分叉。所以,兩個有公共結點而部分重合的連結串列,拓撲形狀看起來像一個 Y,而不可能像 X。

10、最長公共子序列問題 LCS,如有 [1,2,5,11,32,15,77] 和 [99,32,15,5,1,77] 兩個陣列,找到它們共同都擁有的數,寫出時間複雜度最優的程式碼,不能用 array_intersect(這裡有坑,需要去研究一下動態規劃)。

11、linux 的記憶體分配和多執行緒原理

12、MYSQL 中主鍵與唯一索引的區別

主鍵:絕對不能有空值。唯一索引:可以有空值

13、http 與 https 的主要區別

關鍵是 S 上。簡而言之,https 建立連線後要先把 SSL 的證書發下去,有了公鑰和私鑰,就可以解密了。

14、http 狀態碼及其含意

200 請求已成功,請求所希望的響應頭或資料體將隨此響應返回。

301 被請求的資源已永久移動到新位置。

302 請求的資源現在臨時從不同的 URI 響應請求。

400 1、語義有誤,當前請求無法被伺服器理解。2、請求引數有誤。

401 當前請求需要使用者驗證。

403 伺服器已經理解請求,但是拒絕執行它。

404 請求失敗,請求所希望得到的資源未被在伺服器上發現。

500 伺服器遇到了一個未曾預料的狀況,無法完成對請求的處理,會在程式碼出錯時出現。

501 伺服器不支援當前請求所需要的某個功能。無法識別請求的方法。

502 作為閘道器或者代理工作的伺服器嘗試執行請求時,從上游伺服器接收到無效的響應。

503 由於臨時的伺服器維護或者過載,伺服器當前無法處理請求。

15、linux 中怎麼檢視系統資源佔用情況

top、htop、free、uptime

16、SQL 注入的原理是什麼?如何防止 SQL 注入

原理:第一 SQL 本身有問題(這個不是主要問題)。第二你寫的 SQL 很有問題(這是最主要的)

防範:第一,絕對不要相信使用者輸入的任何東西。第二,預編譯。現在的框架一般都會有 SQL 過濾的。

17、isset (null) isset (false) empty (null) empty (false) 輸出

PHP 入門問題,isset 和 empty 的區別

分別是 false, true, true, true

18、最佳化 MYSQL 的方法

第一,資料超過一定數量或者體積,請拆分表,垂直或者水平分(最有效果的最佳化)

第二,務必有自增主鍵。透過自增主鍵來查資料是最快的。

第三,常用的查詢欄位建立聯合索引,寫 SQL 一定要尊從最左原則,用到這個索引。

第四,不要把邏輯運算放到 sql 裡。言外之意是,不要寫太複雜的 SQL,你能寫複雜的 SQL 你肯定也能透過 PHP 實現。

19、資料庫中的事務是什麼?

事務(transaction)是作為一個單元的一組有序的資料庫操作。如果組中的所有操作都成功,則認為事務成功,即使只有一個操作失敗,事務也不成功。如果所有操作完成,

事務則提交,其修改將作用於所有其他資料庫程序。如果一個操作失敗,則事務將回滾,該事務所有操作的影響都將取消。

20、寫一個函式,儘可能高效的從一個標準 URL 中取出檔案的副檔名

會 寫正則最好。

21、引數為多個日期時間的陣列,返回離當前時間最近的那個時間

遍歷陣列,求當前時間差,和第一個進行對比,小於第一個交換位置。最後取第一個即可。

22、echo、print、print_r 的區別

這三個放在一起,回答的點在於,print_r 是函式,echo、print 是結構語言。

至於他們具體的區別參考:

https://www。

cnblogs。com/xiaotaoing/

p/66873

。。。

23、http 協議的 header 中有哪些 key 及含義

這個問題,很難。一會半會說不清楚。如果做過 PHP restful 介面開發,也踩過這裡面的坑,那應該是可以答出來常用的幾個 KEY 的。

24、二叉樹前中後遍歷程式碼

層序遍歷

先序遍歷

中序遍歷

後序遍歷

25、PHP 的陣列和 C 語言的陣列結構上有何區別?

但從 PHP 來講,考的是 PHP 陣列的實現。可以簡單的認為,PHP 的陣列是 hash 桶 + 十字連結串列(實際上是數列 Array,列表 List,散列表 / 關聯陣列 / 字典 Hashtable 的聚合體)。優點是查詢效率很高,遍歷很方便,缺點是,佔記憶體較多。(還是空間換時間的思路,畢竟現在記憶體又不值錢)

C 語言的陣列,就是定長定型別的數列。

26、Redis 的跳躍表怎麼實現的

跳躍表 (skiplist) 是一種有序資料結構,它透過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。

27、雜湊是什麼?hash 衝突後,資料怎麼存?

28、聚簇索引,聚集索引的區別?

29、B+Tree 是怎麼進行搜尋的

30、陣列和 hash 的區別是什麼?

31、寫個函式,判斷下面擴號是否閉合,左右對稱即為閉合: ((())),)(()),(()))),(((((()),(()()),()()

32、 找出陣列中不重複的值 [1,2,3,3,2,1,5]

用普通方法,肯定很容易的。

33、32 題你的時間複雜度是多少?有的情況下,你寫了個演算法,然後面試官會讓你把你的演算法的時間複雜度表示式寫出來

34、PHP 的的這種弱型別變數是怎麼實現的?

考 zval 的,PHP 的八種類型,本質只有一個結構。

35、在 HTTP 通訊過程中,是客戶端還是服務端主動斷開連線?

三次握手和四次揮手,以及他們每步的狀態。

這個問題最好能一步到位回答的全面的。一般都是有客戶端告訴服務端,我這邊東西發完了,可以斷連線了麼。但是如果客戶端發完 FIN 服務端沒有回覆,就會重試,直到超過超時時間,就斷了。服務端也一樣,超過時間,服務端就斷了。

36、PHP 中發起 http 請求有哪幾種方式?它們有何區別?

GET

POST

HEAD

PUT

DELETE

OPTIONS

TRACE

CONNECT

37、有一顆二叉樹,寫程式碼找出來從根節點到 flag 節點的最短路徑並打印出來,flag 節點有多個。比如下圖這個樹中的 6 和 14 是 flag 節點,請寫程式碼列印 8、3、6 和 8、10、14 兩個路徑

典型的二叉搜尋樹。大學資料結構的基礎題。

38、有兩個檔案檔案,大小都超過了 1G,一行一條資料,每行資料不超過 500 位元組,兩檔案中有一部分內容是完全相同的,請寫程式碼找到相同的行,並寫到新檔案中。PHP 最大允許內內為 255M。

將檔案拆分成若干個小檔案,根據內容計算 hash 值,分散到不同檔案。

39、請寫出自少兩個支援回撥處理的 PHP 函式,並自己實現一個支援回撥的 PHP 函式

array_map,array_filter, array_walk

40、請寫出自少兩個獲取指定資料夾下所有檔案的方法(程式碼或思路)。

核心方法是 scandir, 核心思想是遞迴。

41、請寫出自少三種擷取檔名字尾的方法或函式(PHP 原生函式和自己實現函式均可)

echo substr(strrchr($file, ’。‘), 1);

echo substr($file, strrpos($file, ’。‘)+1);

$arr=explode(’。‘, $file);

echo $arr[count($arr)-1];

$arr=explode(’。‘, $file);

echo end($arr);

echo strrev(explode(’。‘, strrev($file))[0]);

echo pathinfo($file)[’extension‘];

echo pathinfo($file, PATHINFO_EXTENSION);

42、PHP 如何實現不用自帶的 cookie 函式為客戶端下發 cookie。對於分散式系統,如何來儲存 session 值。

這個題有點繞。考的還是 COOKIE 和 SESSION 的基礎知識。服務端透過 set-cookie 命令來通知客戶端儲存 cookie。

只要按照 domain path 過期時間等規則 用 header 函式就可以實現。

分散式系統 session,集中處理。按我們公司的架構,為了實現高可用和高容災,提供一個分散式的驗籤服務。具體的可以看下 redis 的分散式服務架構。

43、請用 SHELL 統計 5 分鐘內,nginx 日誌裡訪問最多的 URL 地址,對應的 IP 是哪些?

44、寫一段 shell 指令碼實現備份 mysql 指定庫(如 test) 到指定資料夾並打包,並刪除 30 天前的備份,然後將新的備份推送到遠端伺服器,完成後送郵件通知。

45、mysql 資料庫中 innodb 和 myisam 引擎的區別

區別主要在資料和索引的儲存結構和儲存方式上,以及對於事務的支援。

46、從使用者在瀏覽器中輸入網址並回車,到看到完整的見面,中間都經歷了哪些過程。

入門問題。這個問題有一個很大的坑,面試官可能會從這個問題下手問你一大堆問題。

以 PHP 為例:通常最簡單的回答,從使用者的電腦找到最近的 DNS 服務,然後解析到對應的 IP 然後雙方開始 HTTP 連線,然後傳送請求資訊,伺服器拿到請求資訊就開始準備迴應的資訊,中間要經過 nginx 轉發到 frstCGI (PHP-FPM), 然後 PHP 開始解析框架,解析請求頭部,找到對應的 API,該查資料庫查資料,該組裝 HTML 組裝 HTML,完事了就重新返回給使用者。使用者拿到返回資料,瀏覽器開始渲染頁面,JS 開始載入。

47、如何分析一條 sql 語句的效能。

explain,具體的請百度。(基本很少用效能分析語句。MYSQL 的表設計上儘量冗餘一部分欄位,避免在 MYSQL 裡處理大量的邏輯運算。我們是做 PHP 服務開發的,mysql 語句能簡單儘量簡單。邏輯運算的地方可以在 PHP 裡做。)

48、ping 一個伺服器 ping 不通,用哪個命令跟蹤路由包?

linux:traceroute,windows:tracert

49、$a=[0,1,2,3]; $b=[1,2,3,4,5]; $a+=$b; var_dump ($a) 等於多少?

基礎問題。本質還是考 PHP 陣列的結構和特點。

結果是 01235。PHP 用數字索引和 STRING 索引差別還是很大的

50、$a=[1,2,3]; foreach ($a as &$v){} foreach ($a as $v){} var_dump ($a) 等於多少;

122

此處有一坑。foreach 完之後,$index , $value 並不會消失保留最後一次賦值。

這裡的第一次 foreach 之後,陣列中最後一個元素變成引用,引用變數 $v 繼續存在且指向陣列的最後一個元素。第二次遍歷,因為遍歷變數名是 $v , 所以等於說每次遍歷都將此次遍歷的值修改成最後元素的值,直至到遍歷最後一個元素(引用元素),因為此時陣列的最後一個元素已被修改成上一個元素的值,最後一次賦值就是 自己 == 自己。 故最後一個等於倒數第二個

更多學習內容可以訪問

以上內容希望幫助到大家

,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務程式碼寫多了沒有方向感,不知道該從那裡入手去提升,對此我整理了一些資料,包括但不限於:

分散式架構、高可擴充套件、高效能、高併發、伺服器效能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql最佳化、shell指令碼、Docker、微服務、Nginx

等多個知識點高階進階乾貨需要的可以免費分享給大家,需要的可以加入我的

PHP技術交流群953224940

標簽: PHP  lengthArr  file  遍歷  請求