面試題總結

_zzh發表於2019-05-22

因為最近需要面試,所以特意整理了一下面試所經歷的一些面試題。分享一下,希望對自己有用,也對其他人有用。尚未有答案的,後面會陸續更新,如果有補充答案的,也十分感激。

1.get,post的區別

**顯示有區別 **
get方法是將字串拼接在位址列後面可以看見 
而post方法看不見

**傳遞的大小有區別 **
具體大小和瀏覽器有關係,ie瀏覽器是2k其他瀏覽器的最大值可能不同,但是也比較小。 
而post方法傳遞引數的大小是可以設定的,原來是認為無限大。在Php當中在php.ini檔案是可以設定引數的大小的。

**安全性 **
get方法安全性比較低因為暴露在外面而post方法安全性比較高

**提交的原理 **
get方法提交的資料都是獨立的。 
而Post方法將所有的提交的資料變成一個整體(將提交的資料變成xml格式)

**靈活性**
get方法很靈活, 
post方法不靈活,必須要有表單的參與才能用post提交很不方便

原文:http://www.php.cn/php-weizijiaocheng-379043.html

PS在查資料的時候發現一個有趣的回答:
傳送門:https://www.cnblogs.com/xkzy/p/5987742.html

2.require,include區別

 require是無條件包含也就是如果一個流程里加入require,無論條件成立與否都會先執行require
 include有返回值,而require沒有(可能因為如此require的速度比include快)
 包含檔案不存在或者語法錯誤的時候require是致命的錯誤終止執行,include不是

3.獲取URL字尾名

pathinfo()解析檔案路徑,返回其組成部分;
返回關聯陣列
dirname    檔案路徑
basename   檔名+副檔名
extension   最後一個副檔名
filename   檔名
eg: print_r( pathinfo('/ab/cd/e.php') );
Array(
  [dirname] => /ab/cd
  [basename] => e.php
  [extension] => php
  [filename] => e
)
擴充套件:
列印解析路徑    var_dump( pathinfo($path) );
列印路徑的父級路徑    var_dump( pathinfo($path, PATHINFO_DIRNAME) );
列印路徑的尾名    var_dump( pathinfo($path, PATHINFO_BASENAME) );
列印路徑的最後的副檔名   var_dump( pathinfo($path, PATHINFO_EXTENSION) );
列印路徑的檔案的名字   var_dump( pathinfo($path, PATHINFO_FILENAME) );

原文:https://www.cnblogs.com/laowenBlog/p/6527632.html

4.tcp,udp,http區別

參考連結:https://blog.csdn.net/qq_31332467/article/details/79217262

5.獲取上級目錄的方法

echo __FILE__ ; // 獲取當前所在檔案的絕對路徑及地址,結果:D:\aaa\my.php 
echo dirname(__FILE__); // 取得當前檔案所在的絕對目錄,結果:D:\aaa\ 
echo dirname(dirname(__FILE__)); //取得當前檔案的上一層目錄名,結果:D:\ 

原文:https://blog.csdn.net/viqecel/article/details/80765275 

6.資料庫主從複製
7.資料庫索引
8.高併發的解決方案

web伺服器優化 :負載均衡 
 流量優化:防盜鏈處理 將惡意請求遮蔽,
前端優化:減少http請求、新增非同步請求、啟用瀏覽器快取和檔案壓縮、cdn加速、建立獨立的圖片伺服器、
服務端優化:  頁面靜態化、併發處理、佇列處理、
資料庫優化: 資料庫快取、分庫分表、分割槽操作 、讀寫分離、負載均衡

9.MVC的理解

1、Model(業務模型):應用程式中用於處理應用程式資料邏輯的部分,通常模型物件負責在資料庫中存取資料。          
2、view(檢視):應用程式中處理資料顯示的部分。通常檢視是依據模型資料建立的。
3、controller(控制器):應用程式中處理使用者互動的部分。通常控制器負責從檢視讀取資料,控制使用者輸入,並向模型傳送資料。

10.常用的檔案操作函式

**1. 獲得檔名:**
basename — 返回路徑中的檔名部分
$path = "/home/cate/index/index2.php";\
$file = basename($path);\
echo $file; //結果index2.php

**2. 獲得目錄名**
dirname — 返回路徑中的目錄部分
$path = "/home/cate/index/index2.php";\
$file = basename($path);\
echo $file; //結果index2.php$path = "/home/cate/index/index2.php";\
$file = basename($path);\
echo $file;//結果/home/cate/index

**3.得到路徑關聯陣列**
pathinfo() 函式以陣列的形式返回關於檔案路徑的資訊。
返回的陣列元素如下:
-   [dirname]: 目錄路徑
-   [basename]: 檔名
-   [extension]: 檔案字尾名
-   [filename]: 不包含字尾的檔名
pathinfo(path,options)
| path | 必需。規定要檢查的路徑。 |
| options | 可選。規定要返回的陣列元素。預設是 all。

可能的值:

-   PATHINFO_DIRNAME - 只返回 dirname
-   PATHINFO_BASENAME - 只返回 basename
-   PATHINFO_EXTENSION - 只返回 extension
-   PATHINFO_FILENAME - 只返回 filename

 |
 **4.filesize取得檔案大小**
filesize ( string $filename )
返回檔案大小的位元組數,如果出錯返回  **FALSE** 並生成一條  **E_WARNING** 級的錯誤。

 **判斷目錄是否存在**
 $lujing = "./nihao/wohao";
 if(!is_dir($liujing)){ 
     mkdir(iconv("UTF-8", "GBK", $lujing),0777,true);
 }

 **判斷檔案是否存在**
 file_exists(path);

 更多請參照:http://www.w3school.com.cn/php/php_ref_filesystem.asp

原文:http://www.w3school.com.cn/php/php_ref_filesystem.asp

11.常見的排序演算法

1. 氣泡排序
思路分析:在要排序的一組數中,對當前還未排好的序列,從前往後對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即,每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。

程式碼實現:
$arr=array(1,43,54,62,21,66,32,78,36,76,39);  
function bubbleSort($arr)
{  
  $len=count($arr);
  //該層迴圈控制 需要冒泡的輪數
  for($i=1;$i<$len;$i++)
  { //該層迴圈用來控制每輪 冒出一個數 需要比較的次數
    for($k=0;$k<$len-$i;$k++)
    {
       if($arr[$k]>$arr[$k+1])
        {
            $tmp=$arr[$k+1];
            $arr[$k+1]=$arr[$k];
            $arr[$k]=$tmp;
        }
    }
  }
  return $arr;
}

2. 選擇排序 
思路分析:在要排序的一組數中,選出最小的一個數與第一個位置的數交換。然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後一個數比較為止。

程式碼實現:
function selectSort($arr) {
//雙重迴圈完成,外層控制輪數,內層控制比較次數
 $len=count($arr);
    for($i=0; $i<$len-1; $i++) {
        //先假設最小的值的位置
        $p = $i;

        for($j=$i+1; $j<$len; $j++) {
            //$arr[$p] 是當前已知的最小值
            if($arr[$p] > $arr[$j]) {
            //比較,發現更小的,記錄下最小值的位置;並且在下次比較時採用已知的最小值進行比較。
                $p = $j;
            }
        }
        //已經確定了當前的最小值的位置,儲存到$p中。如果發現最小值的位置與當前假設的位置$i不同,則位置互換即可。
        if($p != $i) {
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    //返回最終結果
    return $arr;
}

3.插入排序
思路分析:在要排序的一組數中,假設前面的數已經是排好順序的,現在要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反覆迴圈,直到全部排好順序。

程式碼實現:
function insertSort($arr) {
    $len=count($arr); 
    for($i=1, $i<$len; $i++) {
        $tmp = $arr[$i];
        //內層迴圈控制,比較並插入
        for($j=$i-1;$j>=0;$j--) {
            if($tmp < $arr[$j]) {
                //發現插入的元素要小,交換位置,將後邊的元素與前面的元素互換
                $arr[$j+1] = $arr[$j];
                $arr[$j] = $tmp;
            } else {
                //如果碰到不需要移動的元素,由於是已經排序好是陣列,則前面的就不需要再次比較了。
                break;
            }
        }
    }
    return $arr;
}

4.快速排序  
思路分析:選擇一個基準元素,通常選擇第一個元素或者最後一個元素。通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素。此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞迴地排序劃分的兩部分。

程式碼實現:
function quickSort($arr) {
    //先判斷是否需要繼續進行
    $length = count($arr);
    if($length <= 1) {
        return $arr;
    }
    //選擇第一個元素作為基準
    $base_num = $arr[0];
    //遍歷除了標尺外的所有元素,按照大小關係放入兩個陣列內
    //初始化兩個陣列
    $left_array = array();  //小於基準的
    $right_array = array();  //大於基準的
    for($i=1; $i<$length; $i++) {
        if($base_num > $arr[$i]) {
            //放入左邊陣列
            $left_array[] = $arr[$i];
        } else {
            //放入右邊
            $right_array[] = $arr[$i];
        }
    }
    //再分別對左邊和右邊的陣列進行相同的排序處理方式遞迴呼叫這個函式
    $left_array = quick_sort($left_array);
    $right_array = quick_sort($right_array);
    //合併
    return array_merge($left_array, array($base_num), $right_array);
}

原文:https://www.cnblogs.com/rainblack/p/5808694.html

12.介面與抽象類的區別

1. 介面
(1)對介面的使用是通過關鍵字implements
(2)介面不能定義成員變數(包括類靜態變數),能定義常量
(3)子類必須實現介面定義的所有方法
(4)介面只能定義不能實現該方法
(5)介面沒有建構函式
(6)介面中的方法和實現它的類預設都是public型別的
2. 抽象類
(1)對抽象類的使用是通過關鍵字extends
(2)不能被例項化,可以定義子類必須實現的方法
(3)子類必須定義父類中的所有抽象方法,這些方法的訪問控制必須和父類中一樣(或者更為寬鬆)
(4)如一個類中有一個抽象方法,則該類必須定義為抽象類
(5)抽象類可以有建構函式
(6)抽象類中的方法可以使用private,protected,public來修飾。
(7)一個類可以同時實現多個介面,但一個類只能繼承於一個抽象類。
3. Final類/方法
(1)final類不能被繼承
(2)final方法不能被重寫
4. Static類/方法
(1)可以不例項化類而直接訪問
(2)靜態屬性不可以由物件通過->操作符來訪問,用::方式呼叫

原文:http://www.php.cn/php-weizijiaocheng-372186.html

13.innoDB,MyISAM的區別

MyISAM:
不支援事務;
資料儲存在磁碟,可被壓縮,儲存空間較小;
只支援表級鎖;
支援(FULLTEXT型別的)全文索引。儲存有表的總行數;
如果select count(*) from table;會直接取出出該值;
如果執行大量的SELECT,MyISAM是更好的選擇;
不支援外來鍵;
如果執行大量的SELECT,MyISAM是更好的選擇;

InnoDB:
支援事務;
儲存在共享空間,需要更多的記憶體和儲存;
具有事務、回滾和崩潰修復能力;
只支援行級鎖;
不支援(FULLTEXT型別的)全文索引,但是innodb可以使用sphinx外掛支援全文索引,並且效果更好;
支援外來鍵;
如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表。

**MyISAM和InnoDB兩者的應用場景:**\
1) MyISAM管理非事務表。它提供高速儲存和檢索,以及全文搜尋能力。如果應用中需要執行大量的SELECT查詢,那麼MyISAM是更好的選擇。\
2) InnoDB用於事務處理應用程式,具有眾多特性,包括ACID事務支援。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多使用者併發操作的效能。

原文:https://www.cnblogs.com/kevingrace/p/5685355.html

14.常見的設計模式

#策略模式
策略模式是物件的行為模式,用意是對一組演算法的封裝。動態的選擇需要的演算法並使用。
策略模式指的是程式中涉及決策控制的一種模式。策略模式功能非常強大,因為這個設計模式本身的核心思想就是物件導向程式設計的多形性思想。
策略模式的三個角色:
1.抽象策略角色
2.具體策略角色
3.環境角色(對抽象策略角色的引用)
實現步驟:
1.定義抽象角色類(定義好各個實現的共同抽象方法)
2.定義具體策略類(具體實現父類的共同方法)
3.定義環境角色類(私有化申明抽象角色變數,過載構造方法,執行抽象方法)
就在程式設計領域之外,有許多例子是關於策略模式的。例如:
如果我需要在早晨從家裡出發去上班,我可以有幾個策略考慮:我可以乘坐地鐵,乘坐公交車,走路或其它的途徑。每個策略可以得到相同的結果,但是使用了不同的資源。

# 工廠模式
工廠模式是我們最常用的例項化物件模式,是用工廠方法代替new操作的一種模式。
使用工廠模式的好處是,如果你想要更改所例項化的類名等,則只需更改該工廠方法內容即可,不需逐一尋找程式碼中具體例項化的地方(new處)修改了。為系統結構提供靈活的動態擴充套件機制,減少了耦合。

# 單例模式
單例模式確保某個類只有一個例項,而且自行例項化並向整個系統提供這個例項。
單例模式是一種常見的設計模式,在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、資料庫操作、顯示卡的驅動程式常被設計成單例。
單例模式分3種:懶漢式單例、餓漢式單例、登記式單例。
單例模式有以下3個特點:
1.只能有一個例項。
2.必須自行建立這個例項。
3.必須給其他物件提供這一例項。
那麼為什麼要使用PHP單例模式?
PHP一個主要應用場合就是應用程式與資料庫打交道的場景,在一個應用中會存在大量的資料庫操作,針對資料庫控制程式碼連線資料庫的行為,使用單例模式可以避免大量的new操作。因為每一次new操作都會消耗系統和記憶體的資源。

# 註冊模式
註冊模式,解決全域性共享和交換物件。已經建立好的物件,掛在到某個全域性可以使用的陣列上,在需要使用的時候,直接從該陣列上獲取即可。將物件註冊到全域性的樹上。任何地方直接去訪問。

# 介面卡模式
將各種截然不同的函式介面封裝成統一的API。 \
PHP中的資料庫操作有MySQL,MySQLi,PDO三種,可以用介面卡模式統一成一致,使不同的資料庫操作,統一成一樣的API。類似的場景還有cache介面卡,可以將memcache,redis,file,apc等不同的快取函式,統一成一致。 \
首先定義一個介面(有幾個方法,以及相應的引數)。然後,有幾種不同的情況,就寫幾個類實現該介面。將完成相似功能的函式,統一成一致的方法。

原文:https://www.cnblogs.com/leedaily/p/8250158.html

15.寫出乘法表的演算法

1.九九乘法表 for 實現:
for($i=1;$i<10;$i++){    
    for($j=1;$j<=$i;$j++){        
    echo $i.'*'.$j.'='.$i*$j.'   ';   
    }    
    echo '<br />';
}
2.九九乘法表 while 實現:
$m = 1;
while($m<10){    
    $n = 1;   
    while($n<=$m){       
    echo $m.'*'.$n.'='.$m*$n.'   ';        
    $n++;       
}       
echo '<br>';        
$m++;}

原文:https://blog.csdn.net/hahahahahahahaha__1/article/details/80665491 

16.echo,print_r ,print,var_dump區別

 echo是PHP語句, print和print_r是函式,語句沒有返回值,函式可以有返回值(即便沒有用)
 print() 只能列印出簡單型別變數的值(如int,string)
 print_r() 可以列印出複雜型別變數的值(如陣列,物件)
 echo 輸出一個或者多個字串
 echo:語句結構;
 print:是函式,有返回值
 print_r:能列印陣列,物件
 var_dump:能列印物件陣列,並且帶資料型別

17.session和cookie的區別

 session:儲存使用者訪問的全域性唯一變數,儲存在伺服器上的php指定的目錄中的(session_dir)的位置進行的存放
 cookie:用來儲存連續訪問一個頁面時所使用,是儲存在客戶端,對於Cookie來說是儲存在使用者WIN的Temp目錄中的。
兩者都可通過時間來設定時間長短

18.用PHP寫出顯示客戶端IP與伺服器IP的程式碼

客戶端:$_SERVER["REMOTE_ADDR"]
伺服器:$_SERVER["SERVER_ADDR"]

19.sql語句應該考慮哪些安全性

(1)防止sql注入,對特殊字元進行轉義,過濾或者使用預編譯sql語句繫結
(2)使用最小許可權原則,特別是不要使用root賬戶,微不同的動作或者操作建立不同的賬戶
(3)當sql出錯時,不要把資料庫出錯的資訊暴露到客戶端

20.優化mysqi資料庫的方法

(1)選取適當的欄位,打欄位設定為NOT NULL,在查詢的時候資料庫不用比較NULL;
(2)使用連結(join)代替子查詢;
(3)使用聯合(UNION)查詢代替手動建立臨時表;
(4)儘量減少使用(LIKE)關鍵字和萬用字元
(5)使用事務和外健

21.對於大流量的網站,你會採用什麼方法來解決訪問量?

(1)首先確認伺服器硬體是否滿足支援當前的流量;
(2)優化資料庫的訪問;
(3)禁止外部盜鏈;
(4)控制大檔案下載;
(5)使用不同的主機分流;
(6)使用流量分析統計;

22.isset(),empty()的區別

isset():
若變數不存在則返回 FALSE 
若變數存在且其值為NULL,也返回 FALSE 
若變數存在且值不為NULL,則返回 TURE 
同時檢查多個變數時,每個單項都符合上一條要求時才返回 TRUE,否則結果為 FALSE 

empty():
若變數不存在則返回 TRUE
若變數存在且其值為""、0、"0"、NULL、、FALSE、array()、var $var; 以及沒有任何屬性的物件,則返回 TURE\
若變數存在且值不為""、0、"0"、NULL、、FALSE、array()、var $var; 以及沒有任何屬性的物件,則返回 FALSE

相關文章