PHP常見面試題總結

一、include 和 require 都能把另一個文件包含到當前文件中 他們有什麼區別?include 和 include_once 又有什麼區別?php

兩者區別只有一個,那就是對包含文件的需求程度html

include 就是包含,若是被包含的文件不存在的話, 那麼則會提示一個錯誤,可是程序會繼續執行下去。mysql

require 意思是須要,若是被包含文件不存在或者 沒法打開的時候,則會提示錯誤,而且會終止程序的執行。laravel

這兩種結構除了在如何處理失敗以外徹底同樣。sql

once 的意思是一次,那麼 include_once 和 require_once 表示只包含一次,避免重複包含。數據庫

 

二、用最少的代碼寫一個求 3 值最大的函數數組

 

 

三、表單中 get 與 post 提交方法的區別?瀏覽器

3.一、GET 請求可以被 cache,GET 請求可以被保存在瀏覽器的瀏覽歷史 裏面(密碼等重要數據 GET 提交,別人查看歷史記錄,就能夠直接看 到這些私密數據)POST 不進行緩存。緩存

3.二、GET 參數是帶在 URL 後面,傳統 IE 中 URL 的最大可用長度爲 2053 字符,其餘瀏覽器對 URL 長度限制實現上有所不一樣。POST 請求無長 度限制(目前理論上是這樣的)。安全

3.三、GET 提交的數據大小,不一樣瀏覽器的限制不一樣,通常在 2k-8K 之間, POST 提交數據比較大,大小靠服務器的設定值限制,並且某些數據 只能用 POST 方法「攜帶」,好比 file。

3.四、所有用 POST 不是十分合理,最好先把請求按功能和場景分下類, 對數據請求頻繁,數據不敏感且數據量在普通瀏覽器最小限定的 2k 範圍內,這樣的狀況使用 GET。其餘地方使用 POST。

3.五、GET 的本質是「得」,而 POST 的本質是「給」。並且,GET 是「冪 等」的,在這一點上,GET 被認爲是「安全的」。但實際上 server 端 也能夠用做資源更新,可是這種用法違反了約定,容易形成 CSRF(跨 站請求僞造)。

 
四、用 PHP 打印出前一天的時間
格式是 2005-5-10 22:21:21
echo date('Y-m-d H:i:s',time()-24*3600); 或 echo date('Y-m-d H:i:s',strtotime('-1 day'));

 

五、假設如今有一個字符串 ww.baidu.com 如何使用 PHP 對他進行操做使字符串以 moc.udiab.輸出?

$str='www.baidu.com';
//先替換,再反轉
echo strrev('www','',$str);

  

六、用 php 寫出顯示客戶端 IP 與服務器 IP 的代碼

客戶端 IP:

   $SERVER[「REMOTE_ADDR」]

或者

   getenv('REMOTE_ADDR');

服務器 IP: $_SERVER[「SERVER_ADDR」]

 
 
七、寫個函數用來對二維數組排序

 

 

 八、'01' == '1'; 結果是 TRUE
in_array('01',array('1'));結果是1
 

 

 

九、簡述單引號和雙引號的用法 雙引號串中的內容能夠被解釋並且替換,

單引號串中的內容總被認爲是普通字符。

 

十、計算某段字符串中某個字符出現的次數

 (例如:gdfgfdgd59gmkblg 中 g 的次數) $text = 'gdfgfdgd59gmkblg';

echo substr_count ( $text,'g'); 

 

十一、有一個樓梯n級臺階,每次能夠上一級或兩級臺階,有幾種不一樣上法?

 這是一個經典的遞歸問題.也就是費波納西級數.
f(n) = f(n-1) + f(n-2).
若是咱們第一部選1個臺階,那麼後面就會剩下n-1個臺階,也就是會有f(n-1)種走法.若是咱們第一部選2個臺階,後面會有f(n-2)個臺階.所以,對於n個臺階來講,就會有f(n-1) + f(n-2)種走法.
所以,1個臺階f(1) = 1.
f(2) = 2,
f(3) = 3 
f(4) = 5 
f(5) = 8 
f(6) = 13 
f(7) = 21 
f(8) = 34 
f(9) = 55 
f(10) = 89 
f(11) = 89+55 = 144 
f(12) = 144 + 89 = 233
.
2.
這類題可這樣理解 
假設走到第n階有f(n)種走法,走到第n+1階有f(n+1)種走法; 
則走到第n+2階,則可分紅兩種狀況:
一,最後一步是從第n階直接登兩級到第n+2階 
二,最後一步是從第n+1階直接登一級到第n+2階 
因爲從地面到第n階,和到第n+1階的走法已經知道 
故從地面到第n+2階的走法:
f(n+2)=f(n)+f(n+1) 
n=1時,1種走法 
n=2時,2種走法 
n=3時,1+2=3種走法 
n=4時,2+3=5種走法 
 
 
十二、普通傳值與引用傳值及unset
<?php //普通傳值
$param1=1; $param2=2; $param2 = $param1; $param1 = 5; //變量1和變量2是兩塊內存,互不影響;
echo $param2; //因此此處仍是顯示爲1 //引用傳值 ↓↓
$param1=1; $param2=2; $param2 = &$param1; //把變量1的內存地址賦給變量2;此時的變量2和變量1全等;
echo $param2;// 1
$param1 = 5; //變量1和變量2是一處內存,改變其中一個,另一個也被改變;
echo $param2; //顯示爲5
?>


$a = 1; $b = &$a; unset($a); echo $b; //1

首先,要理解變量名存儲在內存棧中,它是指向堆中具體內存的地址,經過變量名查找堆中的內存;
普通傳值,傳值之後,是不一樣的地址名稱,指向不一樣的內存實體;
引用傳值,傳引用後,是不一樣的地址名稱,但都指向同一個內存實體;改變其中一個,另一個就也被改變;

unset並無真正銷燬變量的做用...僅僅是切斷了變量與內存之間的關係,內存只要還被引用着就不會被釋放; $b和$a同時指向1,切斷其中$a的關係,$b仍是指向1,因此上題不報錯,照樣輸出1。

 

1三、
//--------------如何理解static靜態變量-----------
 
/** 普通局部變量 */
function local() { $loc = 0; //這樣,若是直接不給初值0是錯誤的。
    ++$loc; echo $loc . '<br>'; } local(); //1
local(); //1
local(); //1
echo '===================================<br/>'; /** static靜態局部變量 */
function static_local() { static $local = 0 ; //此處能夠不賦0值
    $local++; echo $local . '<br>'; } static_local(); //1
static_local(); //2
static_local(); //3 //echo $local; 注意雖然靜態變量,可是它仍然是局部的,在外不能直接訪問的。
echo '=======================================<br>'; /** static靜態全局變量(實際上:全局變量自己就是靜態存儲方式,全部的全局變量都是靜態變量) */
function static_global() { global $glo; //此處,能夠不賦值0,固然賦值0,後每次調用時其值都爲0,每次調用函數獲得的值都會是1,可是不能想固然的寫上"static"加以修飾,那樣是錯誤的.
    $glo++; echo $glo . '<br>'; } static_global(); //1
static_global(); //2
static_global(); //3
?>
在 PHP 中,做用域是不重疊的,函數以外的是全局變量,

函數內部定義的則是局部變量,兩者是兩個不一樣的變量,除非 在函數內使用 global 顯式聲明使用全局變量或直接用 $_GLOBALS 來引用。

 
 1四、$arr = array(‘james’, ‘tom’, ‘symfony’); 請將$arr 數組的值用’ , ’分割併合併成字符串輸出

echo implode(‘ , ’ , $arr);

$str = ‘jack, james, tom, symfony’;請將$str 用’ , ’分割,並把分割後的值放到$arr 數組中

$arr = explode(‘ , ’ , $str);

 

1五、說出數組涉及到的經常使用函數

array-- 聲明一個數組
count -- 計算數組中的單元數目或對象中的屬性個數

foreach-- 遍歷數組

list -- 遍歷數組

explode-- 將字符串轉成數組
implode-- 將數組轉成一個新字符串
array_merge-- 合併一個或多個數組
is_array-- 檢查是不是數組
print_r -- 輸出數組
sort -- 數組排序
array_keys-- 返回數組中全部的鍵名

array_values-- 返回數組中全部的值
key-- 從關聯數組中取得鍵名

 

 1六、字符串的經常使用函數

trim()-- 去除字符串首尾處的空白字符(或者其餘字符)

strlen()-- 字符串長度
substr()-- 截取字符串
str_replace()-- 替換字符串函數

substr_replace()-- 對指定字符串中的部分字符串進行替換 

strstr()-- 檢索字符串函數

explode()-- 分割字符串函數

implode()-- 將數組合併成字符串

str_repeat()-- 重複一個字符串

addslashes()-- 轉義字符串

htmlspecialchars()--THML 實體轉義

 
1七、寫一個函數,可以遍歷一個文件夾下的全部文件和子文件夾
 

 

1八、如下代碼的執行後是,$result 值爲: 
答案:false
is_null-- 檢測變量是否爲NULL,
若是變量是 null 則返回 TRUE,不然返回 FALSE。

在下列狀況下一個變量被認爲是 NULL: 1) 被賦值爲 NULL
2) 還沒有被賦值
3) 被 unset()

 

1九、請列舉出你所知道的全局環境變量

 $_ENV;

$_SERVER;

$_REQUEST

$_FILES

$_SESSION;

$_COOKIE;

$_GET;

$_POST;
$GLOBALS;
 
20、session 與 cookie 的關係和區別?

COOKIE保存在客戶端,而SESSION則保存在服務器端

從安全性來說,SESSION的安全性更高

從保存內容的類型的角度來說,COOKIE只保存字符串(及可以自動轉換成字符串)

從保存內容的大小來看,COOKIE保存的內容是有限的,比較小,而SESSION基本上沒有這個限制

從性能的角度來說,用SESSION的話,對服務器的壓力會更大一些

SEEION依賴於COOKIE,但若是禁用COOKIE,也能夠經過url傳遞


 
2一、寫出 php 的 public, protected, private 三種訪問控制模式的區別
public:公有,任何地方均可以訪問

protected: 繼承,只能在本類或子類中訪問,在其它地方不容許訪問

private: 私有,只能在本類中訪問,在其餘地方不容許訪問

 

 

2二、請寫出單例模式如何設計
<?php
namespace Test;

class Database
{
   //私有化內部實例化的對象
    private static $instance = null;
   //私有化構造方法,禁止外部實例化
    private function __construct(){}
    //私有化__clone,防止被克隆
    private function __clone(){}
    // 公有靜態實例方法
    public static function getInstance(){
       if(!empty(self::$instance)){
           return self::$instance;
       }else{
           self::$instance=new Database();
           return self::$instance;
       }
    }
}

$obj1=Database::getInstance();
$obj2=Database::getInstance();
$obj3=Database::getInstance();
var_dump($obj1,$obj2,$obj3);
echo $obj1==$obj2?1:0;
echo "<br>";
echo $obj1==$obj3?1:0;

有些類只須要實例化一次,像數據庫鏈接類,實例化屢次的話會浪費資源,這時候就會用到單例模式

簡單的來講是「三私一公」:

構造方法私有化後就不能從外部實例化類了,可是怎麼實例化呢?

就要用到靜態方法了,將其公有化,即可在外部實例化類了,

在方法裏判斷對象是否爲空,若是爲空就實例化,存在就直接將它返回,這樣便實現了只實例化一次了

 

2三、接口和抽象類的區別是什麼?

抽象類是一種不能被實例化的類,只能做爲其餘類的父類來使用。 抽象類是經過關鍵字 abstract 來聲明的。

抽象類與普通類類似,都包含成員變量和成員方法,二者的區別 在於,抽象類中至少要包含一個抽象方法,

抽象方法沒有方法體,該方法天生就是要被子類重寫的。 抽象方法的格式爲:abstract function abstractMethod();

接口是經過 interface 關鍵字來聲明的,接口中的成員常量和方法都是 public 的,方法能夠不寫關鍵字 public, 接口中的方法也是沒有方法體。接口中的方法也天生就是要被子類實現的。

抽象類和接口實現的功能十分類似,最大的不一樣是接口能實現多繼承。在應用中選擇抽象類仍是接口要看具體實現。 子類繼承抽象類使用 extends,子類實現接口使用 implements。

 
2四、類中如何定義常量, 如何類中調用常量,如何在類外調用常量

類中的常量也就是成員常量,常量就是不會改變的量,是一個恆 值。定義常量使用關鍵字 const,例如:const PI = 3.1415326;

不管是類內仍是類外,常量的訪問和變量是不同的,常量不需 要實例化對象,

訪問常量的格式都是類名加做用域操做符號(雙冒號)來調用, 即:類名:: 類常量名。

 
2五、如下代碼的執行結果是:
echo class b something
類 b 繼承自類 a,兩個類都定義了構造函數,因爲兩者名字相同,

因此子類中的構造函數覆蓋了父類的構造函數,要想子類對象實例化時也執行父類的構造函數,須要在子類構造函數中使用parent::__construct()來顯示調用父類構造函數。

 
2六、sql 語句應該考慮哪些安全性? 
防止 Sql 注入,對特殊字符進行轉義、過濾或者使用預編譯的 sql 語句綁定變量。

最小權限原則,特別是不要用 root 帳戶,爲不一樣的類型的動做或 者組建使用不一樣的帳戶。

當 sql 運行出錯時,不要把數據庫返回的錯誤信息所有顯示給用 戶,以防止泄露服務器和數據庫相關信息。

 
 2七、如何用命令把 mysql 裏的數據備份出來
(1). 導出一張表 

mysqldump -u 用戶名 -p 密碼 庫名 表名 > 文件名(如 D:/a.sql)

(2). 導出多張表

mysqldump-u用戶名-p密碼 庫名 表名1表名2表名3>文件名(如 D:/a.sql)

(3). 導出全部表
mysqldump -u 用戶名 -p 密碼 庫名 > 文件名(如 D:/a.sql)

(4). 導出一個庫
mysqldump -u 用戶名 -p 密碼 -B 庫名 > 文件名(如 D:/a.sql)

 

 

2八、MySQL 數據庫中的字段類型 varchar 和 char 的主要區別? 那種字段的查找效率要高,爲何?

區別一,定長和變長
char 表示定長,長度固定,varchar 表示變長,即長度可變 當所插入的字符串超出它們的長度時,視狀況來處理,若是是嚴格模式,則會拒絕插入並提示錯誤信息,若是是寬鬆模式,則會截取 而後插入。若是插入的字符串長度小於定義長度時,則會以不一樣的方 式來處理,如char(10) ,表示存儲的是10個字符,不管你插入的 是多少,都是 10 個,若是少於 10 個,則用空格填滿。而 varchar(10) , 小於 10 個的話,則插入多少個字符就存多少個。

varchar 怎麼知道所 存儲字符串的長度呢?實際上,對於 varchar 字段來講,須要使用一 個(若是字符串長度小於 255)或兩個字節(長度大於 255)來存儲字符串的長度。

區別之二,存儲的容量不一樣
對 char 來講,最多能存放的字符個數 255,和編碼無關。
而 varchar 呢,最多能存放 65,532 個字符。
varchar 的最大有效長度由最大行大小和使用的字符集肯定,總體最大長度是 65,532 字節,最大有效長度是 65532 字節,在 varchar 存字符串的時候,第一個字節是空的,不存任何的數據,而後還須要兩個字節來存放字符串的長度。因此有效長度就是 65535 - 1 - 2= 65532 由字符集來肯定,字符集分單字節和多字節

Latin1 一個字符佔一個字節,最多能存放 65532 個字符
GBK 一個字符佔兩個字節, 最多能存 32766 個字符
UTF8 一個字符佔三個字節, 最多能存 21844 個字符 注意,char 和 varchar 後面的長度表示的是字符的個數,而不是字節數。

兩相比較,char 的效率高,沒有碎片,尤爲更新比較頻繁的時候,方便數據文件指針的操做。但不夠靈活,在實際使用時,應根據實際需求來選用合適的數據類型。

 

 

2九、IP 該如何存儲?

最簡單的辦法是使用字符串(varchar)來保存,若是從效率考慮 的話,能夠將 ip 保存爲整型(unsignedint) ,使用 php 或 mysql 提供的函數將 ip 轉換爲整型,而後存儲便可。

PHP 函數:long2ip()和 ip2long()

MySQL 函數:inet_aton()和 inet_ntoa

 

30、請簡述項目中優化 sql 語句執行效率的方法,從哪些方面,sql語句性能如何分析?

1) 儘可能選擇較小的列
2) 將where中用的比較頻繁的字段創建索引
3) select 子句中避免使用‘*’
4) 避免在索引列上使用計算、not in 和<>等操做 5) 當只須要一行數據的時候使用limit1
5) 保證單表數據不超過200W,適時分割表。

6)選取最適用的字段屬性,儘量減小定義字段長度,儘可能把字段 設置 not null 例如'省份,性別',最好設置爲 enum

 

 

針對查詢較慢的語句,可使用explain 來分析該語句具體的執 行狀況。

 

3一、今有雞翁一,值錢五;雞母一,值錢三;雞雛三,值錢一; 百錢買雞百隻,問雞翁,母,雛個幾何?

題目大意:公雞 5 文錢一隻,母雞 3 文錢一隻,小雞 1 文錢 3 只, 如今用 100 文錢共買了 100 只雞,

問:在這 100 只雞中,公雞,母雞和小雞是多少隻?(設每種至少一隻)

 

 

 
 3二、
打印九九乘法表

 

 

3三、寫程序冒泡排序(數組排序)
內層每循環一次,較大的數會日後挪一位
外層每循環一次,最大的數會排到最後面
$order_array=array(
5,4,3,6,7,1,2,10,8,9
);
function bubble_order($arr){
    //獲得長度
    $count_num=count($arr);

    for($k=1;$k<$count_num;$k++){

        //對長度愈來愈少的一組數據 找出最大讓其浮到最後

        for($i=0;$i<$count_num-$k;$i++){

            if($arr[$i]>$arr[$i+1]){//相鄰比較
                $tem=$arr[$i];
                $arr[$i]=$arr[$i+1];
                $arr[$i+1]=$tem;
            }

        }
    }
    return $arr;
}
$new_order_arr=bubble_order($order_array);

 

  3四、HTTP 響應狀態碼常見的有那些,表明什麼意思
響應狀態碼: 
常見狀態碼

 

 

 3五、簡述在 MySQL 數據庫中 MyISAM 和 InnoDB 的區別

區別主要有如下幾個:

構成上,MyISAM 的表在磁盤中有三個文件組成,分別是表定義文 件(.frm) 、數據文件(.MYD) 、索引文件(.MYI),而 InnoDB 的 表由表定義文件(.frm)、表空間數據和日誌文件組成。

安全方面,MyISAM 強調的是性能,其查詢效率較高,但不支持事 務和外鍵等安全性方面的功能,而 InnoDB 支持事務和外鍵等高級功 能,查詢效率稍低。

 
 
3六、反轉數組函數的實現
/**
 * 反轉數組
 * @param  array $arr 
 * @return array
 */
function reverse($arr)
{
    $n = count($arr);

    $left = 0;
    $right = $n - 1;

    while ($left < $right) {
        $temp = $arr[$left];
        $arr[$left++] = $arr[$right];
        $arr[$right--] = $temp;
    }

    return $arr;
}

 

3七、打亂數組

/**
 * 打亂數組
 * @param  array $arr 
 * @return array      
 */
function custom_shuffle($arr)
{
    $n = count($arr);
    for ($i = 0; $i < $n; $i++) {
        $rand_pos = mt_rand(0, $n - 1);
        if ($rand_pos != $i) {
            $temp = $arr[$i];
            $arr[$i] = $arr[$rand_pos];
            $arr[$rand_pos] = $temp;
        }
    }
    return $arr;
}

 

3八、Memcache與Redis的區別

Memcache

  1. 該產品自己特別是數據在內存裏邊的存儲,若是服務器忽然斷電,則所有數據就會丟失
  2. 單個key(變量)存放的數據有1M的限制
  3. 存儲數據的類型都是String字符串類型
  4. 自己沒有持久化功能
  5. 可使用多核(多線程)

Redis

  1. 數據類型比較豐富:String、List、Set、Sortedset、Hash
  2. 有持久化功能,能夠把數據隨時存儲在磁盤上
  3. 自己有必定的計算功能
  4. 單個key(變量)存放的數據有1GB的限制

 

 3九、最左前綴原則
 有一個複合索引: INDEX(`a`, `b`, `c`)
 
使用方式 可否用上索引
select * from users where a = 1 and b = 2 能用上a、b
select * from users where b = 2 and a = 1 能用上a、b(有MySQL查詢優化器)
select * from users where a = 2 and c = 1 能用上a
select * from users where b = 2 and c = 1 不能
 
相關文章
相關標籤/搜索