2020年PHP面試題總結(未完成)


1、Websocket協議的應用場景,解決了什么問題,列舉你所了解的實現了websocket協議的項目或者軟件(不分語言)。

 答:服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬於服務器推送技術的一種。在 WebSocket API 中,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。

 

2、簡述Https雙向認證的主要過程。

答:

① 瀏覽器發送一個連接請求給安全服務器。
② 服務器將自己的證書,以及同證書相關的信息發送給客戶瀏覽器。
③ 客戶瀏覽器檢查服務器送過來的證書是否是由自己信賴的 CA 中心所簽發的。如果是,就繼續執行協議;如果不是,客戶瀏覽器就給客戶一個警告消息:警告客戶這個證書不是可以信賴的,詢問客戶是否需要繼續。
④ 接着客戶瀏覽器比較證書里的消息,例如域名和公鑰,與服務器剛剛發送的相關消息是否一致,如果是一致的,客戶瀏覽器認可這個服務器的合法身份。
⑤ 服務器要求客戶發送客戶自己的證書。收到后,服務器驗證客戶的證書,如果沒有通過驗證,拒絕連接;如果通過驗證,服務器獲得用戶的公鑰。
⑥ 客戶瀏覽器告訴服務器自己所能夠支持的通訊對稱密碼方案。
⑦ 服務器從客戶發送過來的密碼方案中,選擇一種加密程度最高的密碼方案,用客戶的公鑰加過密后通知瀏覽器。
⑧ 瀏覽器針對這個密碼方案,選擇一個通話密鑰,接着用服務器的公鑰加過密后發送給服務器。
⑨ 服務器接收到瀏覽器送過來的消息,用自己的私鑰解密,獲得通話密鑰。
⑩ 服務器、瀏覽器接下來的通訊都是用對稱密碼方案,對稱密鑰是加過密的。
 

3、CGI、php-cgi、Fastcgi、php-fpm幾者的關系。

 答:

CGI全稱是“公共網關接口”(Common Gateway Interface),HTTP服務器與你的或其它機器上的程序進行“交談”的一種工具,其程序須運行在網絡服務器上。CGI可以用任何一種語言編寫,只要這種語言具有標准輸入、輸出和環境變量。如php,perl,tcl等。

 

PHP-CGI是PHP自帶的FastCGI管理器。

 

FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活后,不會每次都要花費時間去fork一次(這是CGI最為人詬病的fork-and-execute 模式)。它還支持分布式的運算,即 FastCGI 程序可以在網站服務器以外的主機上執行並且接受來自其它網站服務器來的請求。

 

PHP-FPM是一個PHP FastCGI管理器,是只用於PHP的。PHP-FPM其實是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP后才可以使用。

4、PHP有哪幾種運行模式,並說明每種模式應用場景。

答:

 1、CGI

 2、Fastcgi

 3、module形式,一般用於apache模塊,模式是以mod_php5模塊的形式集成,此時mod_php5模塊的作用是接收Apache傳遞過來的PHP文件請求,並處理這些請求,然后將處理后的結果返回給Apache。

4、cli模式。命令行執行php

 

5、簡述PHP類的自動加載原理和實現方式。

 

6、簡述對觀察者模式的理解,用偽代碼說明觀察者模式。

 

<?php
//觀察則模式

// 目標
interface Observables{
	public function attach(Observer $ob):void;
	public function detach(Observer $ob):void;
	public function notify():void;
}

// 具體目標
class Saler implements Observables{
	protected $obs   = [];
	protected $range = 0;

	public function attach(Observer $ob):void{
		$this->obs[] = $ob;
	}

	public function detach(Observer $ob):void{
		foreach ($ob as $value) {
			if ($value != $ob) {
				$this->obs[] = $value;
			}
		}
	}

	public function notify():void{
		if ($this->range != 0) {
			foreach ($this->obs as $ob) {
				$ob->update($this);
			}
		}
	}

	public function increPrice(int $range):void{
		$this->range = $range;
	}

	public function getRange():int{
		return $this->range;
	}
}

// 觀察者
interface Observer{
	public function update(Observables $obv):void;
}


// 具體觀察者1
class PoorBuyer implements Observer{
	public function update(Observables $obv):void{
		if ($obv->getRange() > 0) {
			echo "窮人:漲價了不買了\n";
		}else{
			echo "窮人:降價了趕緊買\n";
		}
	}
}

// 具體觀察者2
class RichBuyer implements Observer{
	public function update(Observables $obv):void{
		if ($obv->getRange() > 0) {
			echo "富人:漲價了啊,價格波動沒關系,趕緊買吧\n";
		}else{
			echo "富人:降價了啊,價格波動沒關系,趕緊買吧\n";
		}
	}
}



$poor = new PoorBuyer();
$rich = new RichBuyer();
$saler = new Saler();

$saler->increPrice(-1);
$saler->attach($rich);
$saler->attach($poor);
$saler->notify();

 

7、簡述對適配器模式的理解,如果日常開發中使用了適配器模式,請寫出偽代碼。

 

8、PHP匹配IP地址的正則表達式,要求匹配結果為有效的IP地址。

 

9、PHP匹配郵箱的正則表達式。

 

$mail = 'kevinlee@test.com'; //郵箱地址
$pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/";
preg_match($pattern, $mail, $matches);
var_dump($matches); //輸出匹配結果

 

 

10、簡述Laravel應用的生命周期。

 

11、如何實現多機器session共享?

 

12、請闡述opcache原理。

 

13、請簡述進程與線程的區別。

答:

1、 址空間和其他資源(如打開文件):進程間相互獨立,同一進程的每個線程間共享。某進程內的線程在其他進程不可見。

2、通信:進程間通信IPC,線程間可以直接讀寫進程數據段(如全局變量)來進行通信—需要進程同步和互斥手段的輔助,以保證數據的一致性。

3、調度和切換:線程上下文切換比進程上下文切換要快得多

4、在多線程操作系統中,進程不是一個可執行的實體

 

14、在mysql中存有2000W數據,redis中只存20W數據,如何保證redis中的數據都是熱點數據?

 

15、請寫出HTTP工作過程步驟。

 

16、抽象工廠模式。

<?php
abstract class AbstractClass{
	abstract public function myTest():void;
}

class Mysql extends AbstractClass{
	public function myTest():void{
		echo 'mysql';
	}
}

class MyPdo extends AbstractClass{
	public function myTest():void{
		echo "pdo";
	}
}

class Factory{
	public static function myFactory(string $className='Mysql'):object{
		return new $className();
	}
}

$mysql = Factory::myFactory('Mysql');
$pdo = Factory::myFactory('MyPdo');

var_dump($pdo);
var_dump($mysql);

$mysql->myTest();
echo "\n";
$pdo->myTest();

 

17、單列模式模式

<?php

class Single {
	private static $instance = null;
	private function __construct(){}

	public static function getInstance(){
		if (!(self::$instance instanceof self)) {
			self::$instance = new self;
		}

		return self::$instance;
	}

	private function __clone(){}
}

$test1 = Single::getInstance();
$test2 = Single::getInstance();

var_dump($test1);
var_dump($test2);

 

18、Redis的兩種持久化RDB和AOF的區別。

RDB:在指定時間間隔內,將內存中的數據集快照寫入磁盤,也就是Snapshot快照,它恢復時是將快照文件直接讀到內存中,來達到恢復數據的。在默認情況下, Redis 將數據庫快照保存在名字為 dump.rdb 的二進制文件中。通過觸發快照的形式,來做到將指定時間間隔內的數據持久化到dump.rdb。例如,可以2分鍾內持久化一次,將對數據庫的寫操作,備份到磁盤上的dump.rdb。如何觸發持久化呢?可以通過查看或者設置redis.conf配置文件來指定觸發規則。

RDB優點:

1、如果要進行大規模數據的恢復,RDB方式要比AOF方式恢復速度要快。

2、RDB可以最大化Redis性能,父進程做的就是fork子進程,然后繼續接受客戶端請求,讓子進程負責持久化操作,父進程無需進行IO操作。

3、RDB是一個非常緊湊(compact)的文件,它保存了某個時間點的數據集,非常適合用作備份,同時也非常適合用作災難性恢復,它只有一個文件,內容緊湊,通過備份原文件到本機外的其他主機上,一旦本機發生宕機,就能將備份文件復制到redis安裝目錄下,通過啟用服務就能完成數據的恢復。

RDB的缺點:

1、RDB這種持久化方式不太適應對數據完整性要求嚴格的情況,因為,盡管我們可以用過修改快照實現持久化的頻率,但是要持久化的數據是一段時間內的整個數據集的狀態,如果在還沒有觸發快照時,本機就宕機了,那么對數據庫所做的寫操作就隨之而消失了並沒有持久化本地dump.rdb文件中。

2、每次進行RDB時,父進程都會fork一個子進程,由子進程來進行實際的持久化操作,如果數據集龐大,那么fork出子進程的這個過程將是非常耗時的,就會出現服務器暫停客戶端請求,將內存中的數據復制一份給子進程,讓子進程進行持久化操作。

AOF:以日志的形式記錄Redis每一個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件不可以改寫文件,redis啟動之后會讀取appendonly.aof文件來實現重新恢復數據,完成恢復數據的工作。默認不開啟,需要將redis.conf中的appendonly  no改為yes啟動Redis。

 

AOF的優點:

1、AOF有着多種持久化策略:
appendfsync always:每修改同步,每一次發生數據變更都會持久化到磁盤上,性能較差,但數據完整性較好。

appendfsync everysec: 每秒同步,每秒內記錄操作,異步操作,如果一秒內宕機,有數據丟失。

appendfsync no:不同步。

2、AOF文件是一個只進行追加操作的日志文件,對文件寫入不需要進行seek,即使在追加的過程中,寫入了不完整的命令(例如:磁盤已滿),可以使用redis-check-aof工具可以修復這種問題

3、Redis可以在AOF文件變得過大時,會自動地在后台對AOF進行重寫:重寫后的新的AOF文件包含了恢復當前數據集所需的最小命令集合。整個重寫操作是絕對安全的,因為Redis在創建AOF文件的過程中,會繼續將命令追加到現有的AOF文件中,即使在重寫的過程中發生宕機,現有的AOF文件也不會丟失。一旦新AOF文件創建完畢,Redis就會從舊的AOF文件切換到新的AOF文件,並對新的AOF文件進行追加操作。

4、AOF文件有序地保存了對數據庫執行的所有寫入操作。這些寫入操作一Redis協議的格式保存,易於對文件進行分析;例如,如果不小心執行了FLUSHALL命令,但只要AOF文件未被重寫,通過停止服務器,移除AOF文件末尾的FLUSHALL命令,重啟服務器就能達到FLUSHALL執行之前的狀態。

AOF的缺點:

1、對於相同的數據集來說,AOF文件要比RDB文件大

2、根據所使用的持久化策略來說,AOF的速度要慢與RDB。一般情況下,每秒同步策略效果較好。不使用同步策略的情況下,AOF與RDB速度一樣快。

 

19、簡述下laravel的控制反轉。

答:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM