博主是三線省會城市的苦逼技術開發,主攻PHP方向,平時前后端語言也都有涉及,因為都是自學,上手就是框架,工作五年來基礎補的不穩,換工作的時候苦不堪言,感覺一上來就問Ngnix的運行機制,php的被編譯過程這類的問題,都很懵逼,在跳槽的過程中,整理一些面試過的問題,盡量回憶,答案時候來自己總結的,有不對的地方請大家指正。
基礎篇:
1.請簡單描述一下PHP?
PHP是一種服務器端腳本語言,最常用於Web應用程序。PHP附帶了各種框架和CMS,可以幫助創建網站。面向對象,PHP類似於Java和C#等語言,這使得它易於學習和實現。一些基於PHP的流行應用程序是WordPress等。
2.PHP頁面中包含文件的方式是什么?他們有什么不同?
包含文件函數有include(),require()兩個函數
其中require()包含的文件如果不存在,則會返回一個致命的錯誤,並終止代碼運行
而include()包含的文件如果不存在,則會返回一個錯誤,但是代碼可以繼續執行
3.PHP中GET,和POST方法的基本區別在哪?
GET方法中,最大只能傳送1024個字節,但是POST方法可以傳輸大量的數據,而且GET方法比POST方法的安全性方面低很多
4.PHP中如何區別會話和Cookie?
會話就是SESSION,一般是存儲在服務器上面的,而cookie是以文本的形式存儲在用戶的計算機上面的;
SESSION能夠存儲多個變量,並且可以持續保持活動狀態。
5.header()函數在PHP中的作用?
該header() 函數的目的 是將原始HTTP標頭發送到客戶端瀏覽器。請記住,在發送實際輸出之前必須調用此函數。例如,確保在使用此功能之前不打印任何HTML元素。
6.php如何通過頭文件設置編碼類型?
header( 'Content-Type:text/html;charset=utf-8 ');
7.php正則匹配(email,HTML,JS)?
代碼示例:過濾所有JS
echo preg_replace(“/<script[^>]*?>.*?<\/script>/si”, “”, $script);
進階篇:
1.簡述一下php-fpm。
php-fpm即php-Fastcgi Process Manager.
php-fpm是 FastCGI 的實現,並提供了進程管理的功能。進程包含 master 進程和 worker 進程兩種進程。master 進程只有一個,負責監聽端口,接收來自 Web Server 的請求,而 worker 進程則一般有多個(具體數量根據實際需要配置),每個進程內部都嵌入了一個 PHP 解釋器,是 PHP 代碼真正執行的地方。
2.Nginx與php-fpm如何結合運行?
Nginx與php-fpm的結合流程如下:
1.瀏覽器端輸入網址鏈接;
2.瀏覽器發送請求到Nginx服務器端;
3.Nginx通過路由訪問設置好的根目錄下面的xxx.php文件;
4.同時加載Nginx的fast-cgi模式;
5.fast-cgi監聽127.0.0.1:9000地址;
6.整個請求到達127.0.0.1:9000;
7.php-fpm監聽9000端口,接收到請求,啟用worker進程處理請求(php解釋器);
8.phpfpm處理完成,返回給Nginx;
9.Nginx將處理結果返回給瀏覽器。
3.memcached、redis、mongodb的區別聯系
這是3個場景完全不同的東西,但是又統稱為Nosql技術。
1.memcached:單一鍵值對內存緩存的,做對象緩存無可替代的分布式緩存;
2.redis:是算法和數據結構的集合,快速的數據結構操作是他最大的特點,支持數據持久化;3.mongodb是bson結構、介於rdb和nosql之間的,更松散更靈活的,但是不支持事務,只用作非重要數據存儲
4.簡述一下Mysql的優化方向
這個問題很籠統,因為大部分的mysql優化要看業務邏輯,有的能水平分表,有的不能,有的能做索引,有的不能,所以回答這類問題,我們一般也選擇比較籠統的回答如:
1.可以送mysql的類型上面優化,有些使用MyISAM作為數據表類型,便於快速讀取;
2.mysql在創建表和字段的時候盡量根據業務邏輯選擇合適的類型(int,smallint,varchar等);
3.對mysql的慢查詢日志進行分析,看看那些表的查詢速度較慢,這時候可以采用分表的方式,分表有多種辦法,水平和垂直,一般的業務邏輯(賬戶流水,記錄用戶行為習慣等)都是垂直分表,也就是一個大表拆分成多個小表,可以按照用戶ID求余分表,可以按照流水業務按年度、月度分表等
4.建立索引,對經常查詢的字段建立對應的索引,可以明顯提高查詢的效率(順便介紹下索引的原理回家很多印象分),優化查詢語句,已添加索引的字段不能使用sql函數,會使索引無效。
5.讀寫分離
5.簡述一下PHP的自動加載原理
說到自動加載,如果一直使用框架的同學可能有點懵逼,內心當中澎湃這,實例化?繼承?等等等等,但是從基本的概念分析,我們說的是類的自動加載,也就是你在new的時候后面的引入文件。
在編寫面向對象(OOP) 程序時,很多開發者為每個類新建一個 PHP 文件。 這會帶來一個煩惱:每個腳本的開頭,都需要包含(include)一個長長的列表(每個類都有個文件)。
這時候首先想到的可能是魔術方法__autoload()方法
function __autoload($class) { // 根據類名確定文件名 $file = $class . '.php'; if (file_exists($file)) { include $file; // 引入PHP文件 } }
使用的時候new一下就OK啦,但是在引入命名空間的時候這種方法過於簡單,不利於程序的維護,這時候引入spl_autoload_register()函數,spl_autoload_register 函數的功能就是把傳入的函數(參數可以為回調函數或函數名稱形式)注冊到 SPL __autoload 函數隊列中,並移除系統默認的 __autoload() 函數,類似一個雙向隊列。
簡單描述一下TP5中的自動加載實現
首先創建一個Index.php,加入位置在\app\index\controller\hello中
namespace app\index\controller\hello; class Index { function __construct() { echo '<h1> Welcome To Home </h1>'; } }
接着我們在創建一個加載類(不需要命名空間),它處於根目錄\中:
class Loader { /* 路徑映射 */ public static $vendorMap = array( 'app' => __DIR__ . DIRECTORY_SEPARATOR . 'app', ); /** * 自動加載器 */ public static function autoload($class) { $file = self::findFile($class); if (file_exists($file)) { self::includeFile($file); } } /** * 解析文件路徑 */ private static function findFile($class) { $vendor = substr($class, 0, strpos($class, '\\')); // 頂級命名空間 $vendorDir = self::$vendorMap[$vendor]; // 文件基目錄 $filePath = substr($class, strlen($vendor)) . '.php'; // 文件相對路徑 return strtr($vendorDir . $filePath, '\\', DIRECTORY_SEPARATOR); // 文件標准路徑 } /** * 引入文件 */ private static function includeFile($file) { if (is_file($file)) { include $file; } } }
最后,將 Loader 類中的 autoload 注冊到 spl_autoload_register 函數中:
include 'Loader.php'; // 引入加載器 spl_autoload_register('Loader::autoload'); // 注冊自動加載 new app\index\controller\hello\Index(); // 實例化未引用的類