PHP核心技術面試題,跳槽必備!

1 oop是什麼?

答:oop是面向對象編程,面向對象編程是一種計算機編程架構,OOP 的一條基本原則是計算機程序是由單個可以起到子程序做用的單元或對象組合而成。php

OOP具備三大特色html

一、封裝性:也稱爲信息隱藏,就是將一個類的使用和實現分開,只保留部分接口和方法與外部聯繫,或者說只公開了一些供開發人員使用的方法。因而開發人員只 須要關注這個類如何使用,而不用去關心其具體的實現過程,這樣就能實現MVC分工合做,也能有效避免程序間相互依賴,實現代碼模塊間鬆藕合。mysql

二、繼承性:就是子類自動繼承其父級類中的屬性和方法,並能夠添加新的屬性和方法或者對部分屬性和方法進行重寫。繼承增長了代碼的可重用性。PHP只支持單繼承,也就是說一個子類只能有一個父類。laravel

三、多態性:子類繼承了來自父級類中的屬性和方法,並對其中部分方法進行重寫。因而多個子類中雖然都具備同一個方法,可是這些子類實例化的對象調用這些相同的方法後卻能夠得到徹底不一樣的結果,這種技術就是多態性。多態性加強了軟件的靈活性。web

一、易維護正則表達式

採用面向對象思想設計的結構,可讀性高,因爲繼承的存在,即便改變需求,那麼維護也只是在局部模塊,因此維護起來是很是方便和較低成本的。redis

二、質量高sql

在設計時,可重用現有的,在之前的項目的領域中已被測試過的類使系統知足業務需求並具備較高的質量。shell

三、效率高數據庫

在軟件開發時,根據設計的須要對現實世界的事物進行抽象,產生類。使用這樣的方法解決問題,接近於平常生活和天然的思考方式,勢必提升軟件開發的效率和質量。

四、易擴展

因爲繼承、封裝、多態的特性,天然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴展,並且成本較低。

2 合併兩個數組有幾種方式,試比較它們的異同

方式:

一、array_merge()

二、’+’

三、array_merge_recursive

異同:

array_merge 簡單的合併數組

array_merge_recursive 合併兩個數組,若是數組中有徹底同樣的數據,將它們遞歸合併

array_combine 和 ‘+’ :合併兩個數組,前者的值做爲新數組的鍵

3 PHP的is_writeable()函數存在Bug,沒法準確判斷一個目錄/文件是否可寫,請寫一個函數來判斷目錄/文件是否絕對可寫

答:其中bug存在兩個方面,

一、在windowns中,當文件只有只讀屬性時,is_writeable()函數才返回false,當返回true時,該文件不必定是可寫的。

若是是目錄,在目錄中新建文件並經過打開文件來判斷;

若是是文件,能夠經過打開文件(fopen),來測試文件是否可寫。

二、在Unix中,當php配置文件中開啓safe_mode時(safe_mode=on),is_writeable()一樣不可用。

讀取配置文件是否safe_mode是否開啓。

/**
* Tests for file writability
*
* is_writable() returns TRUE on Windows servers when you really can't write to
* the file, based on the read-only attribute. is_writable() is also unreliable
* on Unix servers if safe_mode is on.
*
* @access   private
* @return   void
*/

if ( ! function_exists('is_really_writable'))
{
    function is_really_writable($file){

    // If we're on a Unix server with safe_mode off we call is_writable
    if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE){
        return is_writable($file);
    }

    // For windows servers and safe_mode "on" installations we'll actually
    // write a file then read it. Bah...
    if (is_dir($file)){

        $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));

        if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE){
            return FALSE;
        }

        fclose($fp);
        @chmod($file, DIR_WRITE_MODE);
        @unlink($file);
        return TRUE;

    } elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE) {

        return FALSE;
    }

    fclose($fp);
    return TRUE;

    }

}

4 PHP的垃圾收集機制是怎樣的?

PHP能夠自動進行內存管理,清除再也不須要的對象。PHP使用了引用計數(reference counting)這種單純的垃圾回收(garbage collection)機制。每一個對象都內含一個引用計數器,每一個reference鏈接到對象,計數器加1。當reference離開生存空間或被設爲NULL,計數器減1。當某個對象的引用計數器爲零時,PHP知道你將再也不須要使用這個對象,釋放其所佔的內存空間。

5 寫一個函數,儘量高效的,從一個標準url裏取出文件的擴展名,

例如:http://www.startphp.cn/abc/de/fg.php?id=1須要取出php或.php

<?php

    // 方案一
    function getExt1($url){

        $arr = parse_url($url);
        //Array ( [scheme] => http [host] => www.startphp.cn [path] => /abc/de/fg.php [query] => id=1 )

        $file = basename($arr['path']);
        $ext = explode('.', $file);
        return $ext[count($ext)-1];
    }



    // 方案二
    function getExt2($url){

        $url = basename($url);
        $pos1 = strpos($url,'.');
        $pos2 = strpos($url,'?');

        if (strstr($url,'?')) {
            return substr($url,$pos1+1,$pos2-$pos1-1);

        } else {
            return substr($url,$pos1);
        }
    }

    $path = "http://www.startphp.cn/abc/de/fg.php?id=1";
    echo getExt1($path);
    echo "<br />";
    echo getExt2($path);

?>

6 使用正則表達式提取一段標識語言(html或xml)代碼段中指定標籤的指定屬性值(需考慮屬性值對不規則的狀況,如大小寫不敏感,屬性名值與等號間有空格等)。此處假設需提取test標籤的attr屬性值,請自行構建包含該標籤的串(騰訊)

以下:

<?php
    header("content-type:text/html;charset=utf-8");

    function getAttrValue($str,$tagName,$attrName){
        $pattern1="/<".$tagName."(s+w+s*=s*(['"]?)([^'"]*)())*s+".$attrName."s*=s*(['"]?)([^'"]*)()(s+w+s*=s*(['"]?)([^'"]*)(9))*s*>/i";

        $arr=array();
        $re=preg_match($pattern1,$str,$arr);

        if($re){
            echo"<br/>$arr[6]={$arr[6]}";
        }else{
            echo"<br/>沒找到。";
        }

    }

    // 示例

    $str1="<test attr='ddd'>";
    getAttrValue($str1,"test","attr");//找test標籤中attr屬性的值,結果爲ddd

    $str2="<test2 attr='ddd'attr2='ddd2't1="t1 value"t2='t2 value'>";

    getAttrValue($str2,"test2","t1");//找test2標籤中t1屬性的值,結果爲t1 value

?>

7 php中WEB上傳文件的原理是什麼,如何限制上傳文件的大小?

上傳文件的表單使用post方式,而且要在form中添加enctype='multipart/form-data'。

通常能夠加上隱藏域:,位置在file域前面。

value的值是上傳文件的客戶端字節限制。能夠避免用戶在花時間等待上傳大文件以後才發現文件過大上傳失敗的麻煩。

使用file文件域來選擇要上傳的文件,當點擊提交按鈕以後,文件會被上傳到服務器中的臨時目錄,在腳本運行結束時會被銷燬,因此應該在腳本結束以前,將其移動到服務器上的某個目錄下,能夠經過函數move_uploaded_file()來移動臨時文件,要獲取臨時文件的信息,使用$_FILES。

限制上傳文件大小的因素有:

客戶端的隱藏域MAX_FILE_SIZE的數值(能夠被繞開)。

服務器端的upload_max_filesize,post_max_size和memory_limit。這幾項不可以用腳原本設置。

自定義文件大小限制邏輯。即便服務器的限制是能本身決定,也會有須要個別考慮的狀況。因此這個限制方式常常是必要的。

8 請說明 PHP 中傳值與傳引用的區別,何時傳值何時傳引用?

按值傳遞:函數範圍內對值的任何改變在函數外部都會被忽略

按引用傳遞:函數範圍內對值的任何改變在函數外部也能反映出這些修改

優缺點:按值傳遞時,php必須複製值。特別是對於大型的字符串和對象來講,這將會是一個代價很大的操做。按引用傳遞則不須要複製值,對於性能提升頗有好處。(優缺點會考到)

9 MySQL數據庫中的字段類型varchar和char的主要區別是什麼?

Varchar是變長,節省存儲空間,char是固定長度。查找效率要char型快,由於varchar是非定長,必須先查找長度,而後進行數據的提取,比char定長類型多了一個步驟,因此效率低一些。

10 靜態化如何實現的?僞靜態如何實現?

一、 靜態化指的是頁面靜態化,也即生成實實在在的靜態文件,也即不須要查詢數據庫就能夠直接從文件中獲取數據,指的是真靜態。

實現方式主要有兩種:一種是咱們在添加信息入庫的時候就生成的靜態文件,也稱爲模板替換技術。一種是用戶在訪問咱們的頁面時先判斷是否有對應的緩存文件存在,若是存在就讀緩存,不存在就讀數據庫,同時生成緩存文件。

二、僞靜態不是真正意義上的靜態化,之因此使用僞靜態,主要是爲了SEO推廣,搜索引擎對動態的文件獲取難度大,不利於網站的推廣。實習原理是基於Apache或Nginx的rewrite機智

主要有兩種方式:一種是直接在配置虛擬機的位置配置僞靜態,這個每次修改完成後須要重啓web服務器。另外一種採用分佈式的,能夠在網站的根目錄上建立.htaccess的文件,在裏面配置相應的重寫規則來實現僞靜態,這種每次重寫時不須要重啓web服務器,且結構上比較清晰。

11 如何處理負載,高併發?

一、HTML靜態化

效率最高、消耗最小的就是純靜態化的html頁面,因此咱們儘量使咱們的 網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。

二、圖片服務器分離

把圖片單獨存儲,儘可能減小圖片等大流量的開銷,能夠放在一些相關的平臺上,如七牛等

三、數據庫集羣和庫表散列及緩存

數據庫的併發鏈接爲100,一臺數據庫遠遠不夠,能夠從讀寫分離、主從複製,數據庫集羣方面來着手。另外儘可能減小數據庫的訪問,可使用緩存數據庫如memcache、redis。

四、鏡像:

儘可能減小下載,能夠把不一樣的請求分發到多個鏡像端。

五、負載均衡:

Apache的最大併發鏈接爲1500,只能增長服務器,能夠從硬件上着手,如F5服務器。固然硬件的成本比較高,咱們每每從軟件方面着手。

12 PHP7的新特性?

標量類型聲明:PHP 7 中的函數的形參類型聲明能夠是標量了。在 PHP 5 中只能是類名、接口、array 或者 callable (PHP 5.4,便可以是函數,包括匿名函數),如今也可使用 string、int、float和 bool 了。

返回值類型聲明:增長了對返回類型聲明的支持。相似於參數類型聲明,返回類型聲明指明瞭函數返回值的類型。可用的類型與參數聲明中可用的類型相同。NULL 合併運算符:因爲平常使用中存在大量同時使用三元表達式和 isset()的狀況,NULL 合併運算符使得變量存在且值不爲NULL, 它就會返回自身的值,不然返回它的第二個操做數。

use 增強:從同一 namespace 導入的類、函數和常量如今能夠經過單個 use 語句 一次性導入了 匿名類:如今支持經過new class 來實例化一個匿名類

13 常見的 PHP 安全性攻擊 SQL注入:

用戶利用在表單字段輸入SQL語句的方式來影響正常的SQL執行。

防止:使用mysql_real_escape_string()過濾數據 手動檢查每一數據是否爲正確的數據類型 使用預處理語句並綁定變量 參數化SQL:是指在設計與數據庫連接並訪問數據時,在須要填入數值或數據的地方,使用參數 (Parameter) 來給值,用@或?來表示參數。

XSS攻擊 :跨站點腳本攻擊,由用戶輸入一些數據到你的網站,其中包括客戶端腳本(一般JavaScript)。若是你沒有過濾就輸出數據到另外一個web頁面,這個腳本將被執行。

防止:爲了防止XSS攻擊,使用PHP的htmlentities()函數過濾再輸出到瀏覽器。

CSRF:跨站點請求僞造,是指一個頁面發出的請求,看起來就像是網站的信任用戶,可是是僞造的

防止:通常來講,確保用戶來自你的表單,而且匹配每個你發送出去的表單。有兩點必定要記住:對用戶會話採用適當的安全措施,例如:給每個會話更新id和用戶使用SSL。生成另外一個一次性的令牌並將其嵌入表單,保存在會話中(一個會話變量),在提交時檢查它。如laravel中的 _token

代碼注入:代碼注入是利用計算機漏洞經過處理無效數據形成的。問題出在,當你不當心執行任意代碼,一般經過文件包含。寫得很糟糕的代碼能夠容許一個遠程文件包含並執行。如許多PHP函數,如require能夠包含URL或文件名。
防止代碼注入 過濾用戶輸入 在php.ini中設置禁用allow_url_fopen和allow_url_include。這將禁用require/include/fopen的遠程文件

16 面向對象的特徵有哪些方面?

主要有封裝,繼承,多態。若是是4個方面則加上:抽象。

封裝:

封裝是保證軟件部件具備優良的模塊性的基礎,封裝的目標就是要實現軟件部件的高內聚,低耦合,防止程序相互依賴性而帶來的變更影響.

繼承:

在定義和實現一個類的時候,能夠在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容做爲本身的內容,並能夠加入若干新的內容,或修改原來的方法使之更適合特殊的須要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關係,提升了軟件的可重用性和可擴展性。

多態:

多態是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。

抽象:

抽象就是找出一些事物的類似和共性之處,而後將這些事物歸爲一個類,這個類只考慮這些事物的類似和共性之處,而且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一隻螞蟻和大象,你可以想象出它們的相同之處,那就是抽象。

17說說對SQL語句優化有哪些方法?(選擇幾條)

(1)Where子句中:where表之間的鏈接必須寫在其餘Where條件以前,那些能夠過濾掉最大數量記錄的條件必須寫在Where子句的末尾.HAVING最後。

(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。

(3) 避免在索引列上使用計算

(4)避免在索引列上使用IS NULL和IS NOT NULL

(5)對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。

(6)應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描

(7)應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描

18 MySQL數據庫做發佈系統的存儲,一天五萬條以上的增量,預計運維三年,怎麼優化?

(1)設計良好的數據庫結構,容許部分數據冗餘,儘可能避免join查詢,提升效率。

(2) 選擇合適的表字段數據類型和存儲引擎,適當的添加索引。

(3) 作mysql主從複製讀寫分離。

(4)對數據表進行分表,減小單表中的數據量提升查詢速度。

(5)添加緩存機制,好比redis,memcached等。

(6)對不常常改動的頁面,生成靜態頁面(好比作ob緩存)。

(7)書寫高效率的SQL。好比 SELECT * FROM TABEL 改成 SELECT field_1, field_2, field_3 FROM TABLE.

19 對於大流量的網站,您採用什麼樣的方法來解決各頁面訪問量統計問題?

(1) 確認服務器是否能支撐當前訪問量。

(2) 優化數據庫訪問。

(3)禁止外部訪問連接(盜鏈), 好比圖片盜鏈。

(4)控制文件下載。

(5)作負載均衡,使用不一樣主機分流。

(6)使用瀏覽統計軟件,瞭解訪問量,有針對性的進行優化。

20 談談你對 mysql 引擎中的 MyISAM與InnoDB的區別理解?

InnoDB和MyISAM是許多人在使用MySQL時最經常使用的兩個表類型,這兩個表類型各有優劣,視具體應用而定。基本的差異爲:MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。

如下是一些細節和具體實現的差異:

MyISAM與InnoDB的區別是什麼?

一、 存儲結構

MyISAM:每一個MyISAM在磁盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。.frm文件存儲表定義。數據文件的擴展名爲.MYD (MYData)。索引文件的擴展名是.MYI (MYIndex)。

InnoDB:全部的表都保存在同一個數據文件中(也多是多個文件,或者是獨立的表空間文件),InnoDB表的大小隻受限於操做系統文件的大小,通常爲2GB。

二、 存儲空間

MyISAM:可被壓縮,存儲空間較小。支持三種不一樣的存儲格式:靜態表(默認,可是注意數據末尾不能有空格,會被去掉)、動態表、壓縮表。

InnoDB:須要更多的內存和存儲,它會在主內存中創建其專用的緩衝池用於高速緩衝數據和索引。

三、 可移植性、備份及恢復

MyISAM:數據是以文件的形式存儲,因此在跨平臺的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操做。

InnoDB:免費的方案能夠是拷貝數據文件、備份 binlog,或者用 mysqldump,在數據量達到幾十G的時候就相對痛苦了。

四、 事務支持

MyISAM:強調的是性能,每次查詢具備原子性,其執行數度比InnoDB類型更快,可是不提供事務支持。

InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。 具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。

五、 AUTO_INCREMENT

MyISAM:能夠和其餘字段一塊兒創建聯合索引。引擎的自動增加列必須是索引,若是是組合索引,自動增加能夠不是第一列,他能夠根據前面幾列進行排序後遞增。

InnoDB:InnoDB中必須包含只有該字段的索引。引擎的自動增加列必須是索引,若是是組合索引也必須是組合索引的第一列。

六、 表鎖差別

MyISAM:只支持表級鎖,用戶在操做myisam表時,select,update,delete,insert語句都會給表自動加鎖,若是加鎖之後的表知足insert併發的狀況下,能夠在表的尾部插入新的數據。

InnoDB:支持事務和行級鎖,是innodb的最大特點。行鎖大幅度提升了多用戶併發操做的新能。可是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。

七、 全文索引

MyISAM:支持 FULLTEXT類型的全文索引

InnoDB:不支持FULLTEXT類型的全文索引,可是innodb可使用sphinx插件支持全文索引,而且效果更好。

八、 表主鍵

MyISAM:容許沒有任何索引和主鍵的表存在,索引都是保存行的地址。

InnoDB:若是沒有設定主鍵或者非空惟一索引,就會自動生成一個6字節的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值。

九、 表的具體行數

MyISAM:保存有表的總行數,若是select count(*) from table;會直接取出出該值。

InnoDB:沒有保存表的總行數,若是使用select count(*) from table;就會遍歷整個表,消耗至關大,可是在加了wehre條件後,myisam和innodb處理的方式都同樣。

十、 CURD操做

MyISAM:若是執行大量的SELECT,MyISAM是更好的選擇。

InnoDB:若是你的數據執行大量的INSERT或UPDATE,出於性能方面的考慮,應該使用InnoDB表。DELETE 從性能上InnoDB更優,但DELETE FROM table時,InnoDB不會從新創建表,而是一行一行的刪除,在innodb上若是要清空保存有大量數據的表,最好使用truncate table這個命令。

十一、 外鍵

MyISAM:不支持

InnoDB:支持

經過上述的分析,基本上能夠考慮使用InnoDB來替代MyISAM引擎了,緣由是InnoDB自身不少良好的特色,好比事務支持、存儲 過程、視圖、行級鎖定等等,在併發不少的狀況下,相信InnoDB的表現確定要比MyISAM強不少。另外,任何一種表都不是萬能的,只用恰當的針對業務類型來選擇合適的表類型,才能最大的發揮MySQL的性能優點。若是不是很複雜的Web應用,非關鍵應用,仍是能夠繼續考慮MyISAM的,這個具體狀況能夠本身斟酌。

點關注,不迷路

好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是人才。以前說過,PHP方面的技術點不少,也是由於太多了,實在是寫不過來,寫過來了你們也不會看的太多,因此我這裏把它整理成了PDF和文檔,若是有須要的能夠

點擊進入暗號: PHP+「平臺」

在這裏插入圖片描述

在這裏插入圖片描述


更多學習內容能夠訪問【對標大廠】精品PHP架構師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續更新)

以上內容但願幫助到你們,不少PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裏入手去提高,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨須要的能夠免費分享給你們,須要的能夠加入個人 PHP技術交流羣

相關文章
相關標籤/搜索