PHP 筆試 + 面試題

本章主要介紹常見的 PHP 筆試 + 面試題,包括:


  • 基礎及程序題

  • 數據庫技術題

  • 綜合技術題

  • 項目及設計題


  • 基礎及程序題

[1] 寫一個排序算法,可以是冒泡排序或者是快速排序,假設待排序對象是一維數組(不能使用系統已有函數)(C/C++、PHP、Java)
  • 假設以下的排序都是從小到大排序

  • C++ 實現冒泡排序

#include <iostream>

void bubbleSort(int arr[], int n)  // n 為數組大小 
{
    for (int i = 0; i < n - 1; i++) { // n-1 趟排序
        for (int j = i + 1; j < n; j++) {
            if (arr[i] > arr[j]) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp; 
            }
        } 
    } 
}

int main()
{
    int arr[10] = { 5, 1, 7, 2, 9, 3, 6, 8, 0, 4 };
     bubbleSort(arr, 10);  // 數組大小
    for (int i = 0; i < 10; i++) {
        std::cout << arr[i] << " ";  // 0 1 2 3 4 5 6 7 8 9
    } 
} 

  • PHP 實現冒泡排序
function bubbleSort($arr, $n)  // $n 為數組大小 
{
    for ($i = 0; $i < $n - 1; $i++) { // n-1 趟排序
        for ($j = $i + 1; $j < $n; $j++) {
            if ($arr[$i] > $arr[$j]) {
                $temp = $arr[$i];
                $arr[$i] = $arr[$j];
                $arr[$j] = $temp; 
            }
        } 
    } 
    print_r($arr);  // Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 [8] => 8 [9] => 9 )
}

bubbleSort([5, 1, 7, 2, 9, 3, 6, 8, 0, 4 ], 10);  // 數組大小

  • C++ 實現快速排序
#include<iostream>

void quickSort(int arr[], int i, int j)   
{
    if (i < j) {
        int l = i, r = j;
        int pivot = arr[i];  // 選擇一個基準值
        while (i < j) {
            while (i<j && arr[j] >= pivot) {
                j--;  // 如果后面的數比基準值大,就往前找
            }
            arr[i] = arr[j];
            while (i<j && arr[i] <= pivot) {
                i++;  // 如果前面的數比基準值小,就往后找
            }
            arr[j] = arr[i];
        }
        arr[i] = pivot;  // 或者 arr[j] = pivot;
        quickSort(arr, l, i - 1);  // 左邊
        quickSort(arr, i + 1, r); // 右邊
    }
}

int main()
{
    int arr[10] = { 5, 1, 7, 2, 9, 3, 6, 8, 0, 4 };
    quickSort(arr, 0, 9);
    for (int i = 0; i < 10; i++) {
        std::cout << arr[i] << " ";  // 0 1 2 3 4 5 6 7 8 9
    } 
} 

  • PHP 實現快速排序
function quickSort(& $arr, $i, $j)  // 傳引用調用
{
    if ($i < $j) {
        $l = $i;
        $r = $j;
        $pivot = $arr[$i];
        while ($i < $j) {
            while ($i < $j && $arr[$j] >= $pivot) {
                $j--;
            }
            $arr[$i] = $arr[$j];
            while ($i < $j && $arr[$i] <= $pivot) {
                $i++;
            }
            $arr[$j] = $arr[$i];
        }
        $arr[$i] = $pivot;
        quickSort($arr, $l , $i - 1);
        quickSort($arr, $i + 1 , $r);
    }
}

$arr = [0, 1, 8, 6, 2, 5, 4, 9, 3, 7];
quickSort($arr, 0, 9); 
print_r($arr);  // Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 [8] => 8 [9] => 9 ) 
[2] 實現一個字符串截取的函數,類似于substr,必須能夠截取中文這種多字節(jié)編碼。假設每個中文也是一個字符,普通的數字、符號、字母也是一個字符。(提示:GB編碼的中文字符高位范圍是 0x81-0xFE )
<?php
/**
* 截取字符串子串 (GBK)
*
* @param string $str 原始字符串
* @param int $len 需要截取字符串的長度
* @return string 返回截取到的字符串
*/
function GBSubstr($str, $len){
    $count = 0;
    for($i = 0; $i < strlen($str); $i++){
        if($count == $len) break;  
        if(preg_match("/[\x81-\xfe]/", substr($str, $i, 1))) {   // 如果檢測到 GBK 中文編碼的高位 0x81-0xFE
            ++$i; // 跳過低位,繼續(xù)向后匹配
        }
        ++$count;   // 次數
    }
    // echo $i; 這時 $i 的值為 9
    return substr($str, 0, $i);  // $i 是加上中文后的字符串長度
}
echo GBSubstr("ab喜cdefgh",7);  // 從頭開始截取一個長度為 7 的字符串; 輸出 "ab喜cdef"
?>
[3] 寫一個遍歷指定目錄下所有子目錄和子文件的函數(提示:可以使用遞歸的方法)
<?php
function dir_all($path) { 
    $handler = opendir($path); 
    while (false !== ($tmp = readdir($handler))) {    // $tmp 第 1 次是 ".",第2次是 "..", 之后是文件名或目錄名,和Linux中使用 ls 的效果一樣
        if(is_dir("$path/$tmp")) {   // 如果是一個目錄
            if ($tmp == "." || $tmp == "..")  // 不輸出,也不遞歸調用
                continue; 
            echo $tmp . "<br>";      // 輸出目錄名字
            dir_all("$path/$tmp");  // 把當前目錄名接到 $path 上,遞歸調用
        } 
        else {
            echo $tmp ."<br>";  // 如果是一個文件,直接輸出
        } 
    } 
}
dir_all("C:\Users\bingo\Desktop\ms");  // 輸出 ms 文件夾下的所有文件名、子目錄名以及子目錄下的文件名
?>
[4] 寫出匹配郵箱地址和URL的兩個正則表達式。類似下面的:
<?php
// 匹配郵箱
if (preg_match("/^[0-9a-z][0-9a-z\_\-\.]+@([0-9a-z][0-9a-z\-]*\.)+[a-z]{2,}$/i", "user_name.first@example.com.cn")) {  // 匹配模式 i 表示不區(qū)分大小寫
    echo "Matching!";  // 輸出 "Matching!"
}
else {
    echo "No Matching!";
}
// 匹配 URL
if (preg_match("/^(http|https):\/\/([0-9a-z][0-9a-z\-]*\.)+[a-z]{2,}(:\d+)?\/[0-9a-z%\-_\/\.]+/i", "http://www.example.com.cn/user_profile.php?uid=100")) {  // 匹配模式 i 表示不區(qū)分大小寫
    echo "Matching!";  // 輸出 "Matching!"
}
else {
    echo "No Matching!";
}
?>

  • 數據庫技術題

[1] 寫出三種以上MySQL數據庫存儲引擎的名稱(提示:不區(qū)分大小寫)
  • 存儲引擎:研究存儲數據、為存儲的數據建立索引和更新、查詢數據等技術的實現方法。存儲引擎也可以稱為表類型(即存儲和操作此表的類型)。
  • MyISAM:缺點是無法處理事務。適合場景:
    ① 選擇密集型的表:MyISAM 存儲引擎在篩選大量數據時非常迅速。
    ② 插入密集型的表:MyISAM 的并發(fā)插入特性允許同時選擇和插入數據,例如:MyISAM很適合管理郵件或Web服務器日志數據。
  • InnoDB:健壯的事務型存儲引擎,5.5版本之后的默認的存儲引擎。InnoDB還引入了行級鎖定和外鍵約束,在以下場合下,使用InnoDB是最理想的選擇:
    ① 更新密集的表。InnoDB存儲引擎特別適合處理多重并發(fā)的更新請求。
    ② 事務。InnoDB存儲引擎是支持事務的標準MySQL存儲引擎。
    ③ 自動災難恢復。與其它引擎不同,InnoDB能夠自動從災難中恢復。
    ④ 外鍵約束。MySQL支持外鍵的存儲引擎只有InnoDB。
    ⑤ 支持自動增加列AUTO_INCREMENT屬性。
    一般來說,如果需要事務支持,并且有較高的并發(fā)讀取頻率,InnoDB是不錯的選擇。
  • Memory:優(yōu)點是速度,采用的邏輯存儲介質是系統內存。但當進程崩潰時,所有的Memory數據都會丟失。它要求存儲在Memory數據表里的數據使用的是長度不變的格式,這意味著不能使用BLOB和TEXT這樣的長度可變的數據類型,VARCHAR是一種長度可變的類型,但因為它在MySQL內部當做長度固定不變的CHAR類型,所以可以使用。
    一般在以下幾種情況下使用Memory存儲引擎:
    ① 目標數據較小,而且被非常頻繁地訪問。
    ② 如果數據是臨時的、要求必須立即可用,那么就可以存放在內存表中。
    ③ 存儲在Memory表中的數據如果突然丟失,不會對應用服務產生實質的負面影響。
  • Merge:一組MyISAM表的組合,MyISAM表結構必須完全相同。
  • Archive:歸檔的意思,在歸檔之后很多的高級功能就不再支持了,僅僅支持最基本的插入和查詢兩種功能。
  • 還有 BDB(Berkeley DB)、Example、Federated、CSV、Blackhole、MaxDB 等等。
[2] 說出你所知道的三種以上開源數據庫的名稱(提示:想想目前國外流行的開源數據庫)
  • MySQL :單機的關系數據庫,普及了「可插拔」引擎這一概念,針對不同的業(yè)務場景選用不同的存儲引擎是 MySQL tuning 的一個重要的方式。比如對于有事務需求的場景使用 InnoDB;對于并發(fā)讀取的場景 MyISAM 可能比較合適。 MySQL 5.6 中引入了多線程復制和 GTID(全局事務ID),使得故障恢復和主從的運維變得比較方便。另外,5.7是 MySQL 的一個重大更新,主要是讀寫性能和復制性能上有了長足的進步。
  • ** PostgreSQL**:單機的關系型數據庫,對 SQL 支持非常強大,不管是內置類型、JSON 支持、GIS 類型以及對于復雜查詢的支持,PL/SQL 等都比 MySQL 強大得多,而且從代碼質量上來看,PostgreSQL 的代碼質量是優(yōu)于 MySQL 的。相對于MySQL 5.7以前的版本,PostgreSQL 的 SQL 優(yōu)化器比 MySQL 強大很多,幾乎所有稍微復雜的查詢PostgreSQL 的表現都優(yōu)于 MySQL。PostgreSQL 的不足之處在于沒有 MySQL 那樣強大的社區(qū)和群眾基礎。
  • NoSQL:分布式非關系型數據庫,包含的范圍有內存數據庫,持久化數據庫等。大多 NoSQL 都拋棄了關系模型,選擇更簡單的鍵值或者文檔類型進行存儲。數據結構和查詢接口都相對簡單,沒有了 SQL 的包袱,實現的難度會降低很多。另外 NoSQL 的設計幾乎都選擇犧牲掉復雜 SQL 的支持及 ACID 事務換取彈性擴展能力,業(yè)務模型相對簡單。
  • 另外,還有SQLite、BDB(Berkeley DB)、Firebird 等等。
[3] MySQL數據庫中的字段類型varchar和char的主要區(qū)別是什么?那種字段的查找效率要高,為什么?

varchar是變長,節(jié)省存儲空間,char是固定長度。查找效率要char型快,因為varchar是非定長,必須先查找長度,然后進行數據的提取,比char定長類型多了一個步驟,所以效率低一些。

[4] 說出MySQL 4.0和MySQL 4.1版本的最主要的兩個區(qū)別。如果你使用過MySQL 5,請說說MySQL 5跟MySQL 4的主要區(qū)別。(后半題選作)

MySQL 4.1 主要是比MySQL 4.0多了 子查詢字符編碼的支持 兩個特點。
MySQL5增加的功能比MySQL4要更多,包括 存儲過程視圖事務 等等。

[5] MySQL數據庫基本的三個優(yōu)化法則是什么,除了增加硬件和帶寬?(提示:從服務配置、應用、開發(fā)角度考慮)
  • 系統服務優(yōu)化,把 MySQL 的 key_buffer、cache_buffer、query_cache等增加容量;
  • 給所有經常查詢的字段增加適當的索引;
  • 優(yōu)化 SQL 語句,減少 distinct、group、join 等語句的操作。

  • 綜合技術題

[1] 請使用JavaScript寫出三種產生一個Image 標簽的方法(提示:從方法、對象、HTML角度考慮)
  • 方法角度:var img = document.createElement("img");
  • 對象角度:var img = new Image();
  • HTML角度:img.innerHTML = '<img src = "xxx.jpg" />';
[2] 請使用CSS樣式,描述兩種方法在當前列中只顯示一個div對象
  • display: none; // 對象隱藏后,隱藏部分不占據空間大小
  • visibility:hidden; // 對象隱藏后,隱藏部分還占據著空間大小
  • $("#id").hide(); // JQuery 方法,隱藏部分還占據著空間大小
[3] 請描述出兩點以上XHTML和HTML最顯著的區(qū)別

網頁編碼的發(fā)展: HTML => XHTML => XML

  • XHTML 必須強制指定文檔類型DOCTYPE,HTML比較隨意;
  • XHTML 區(qū)分大小寫,要求標簽必須小寫,HTML比較隨意;
  • XHTML 的標簽要閉合,HTML比較隨意;
  • XHMTL 的屬性值必須在引號之中,HTML比較隨意;
  • XHMTL 不支持屬性最小化,如 checked = "checked",在HTML中可以簡寫成 checked,但 XHTML不允許簡寫。
[4] 寫出五種以上你使用過的 PHP 的擴展的名稱(提示:常用的PHP擴展)

MySQL、PDO 、GD、socket、MB_Sring、Iconv、Curl、SHM、libxml
等等。

[5] 了解MVC模式嗎?請寫出三種以上目前PHP流行的MVC框架名稱(不區(qū)分大小寫)
  • MVC模式(Model-View-Controller):軟件工程中的一種軟件架構模式,把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
  • 模型Model :管理數據庫相關的數據和業(yè)務邏輯。模型提供了連接和操作數據庫的抽象層。
  • 視圖View : 負責界面顯示,如 HMTL/XML/JSON 顯示。
  • 控制器Controller :接收用戶的請求,并調用相應的模型處理。
    MVC 結構圖.png
  • PHP流行的MVC框架名稱:ThinkPHP、Zend Framework、CakePHP、php.MVC、FleaPHP、Symfony、Plite、PHP on Trax、Smutty 等等。
[6] 寫出15個以上你所知道的常用的Linux命令和它的功能
  • man ls [查ls的使用手冊]
  • who [查看已登錄系統的用戶]
  • more/less 1.txt [主屏顯式文件內容]
  • cat try.c [列出文本文件內容]
  • > 2.txt [重定向到文件,新建文件]
  • head/tail -15 ab.c [打印文件頭/尾15行,不指定參數默認10行]
  • ps -ef [列出系統所有進程]
  • who | wc -l [統計系統已成功登錄的用戶個數]
  • grep/egrep [0-9] 1.txt [在文件中查找滿足正則式的字符串]
  • ls -l [長格式的形式顯示文件內容]
  • cp file1 file2 dir [將文件復制到目錄中]
  • cp -r dir1 dir2 [復制目錄]
  • mv 1.txt 2.txt [移動文件并重命名]
  • rm file1 file2 [刪除文件]
  • find ver1.d ver2.d -name '*.c' -print [在目錄中查找文件]
  • tar cvf dir . [ 壓縮,將當前目錄開始的整個目錄樹(.),備份到dir目錄下]
  • tar xvf dir [解壓,將dir目錄下的數據恢復到文件系統中]
  • chmod a+rwx 1.txt [修改文件權限]
  • cd Desktop [修改路徑]
  • echo $addr [打印一個變量]
  • expr 3 + 4 [計算表達式]
[7] 使用過Vim編輯器嗎?如果使用過,如何在vim里切分多個可視化窗口,包括橫排和縱排。(本題選作)

vi 進入命令模式后,輸入 :sp:vsp 即可橫排和豎排切分可視化窗口。
橫:split(sp);縱:vsplit(vsp)

[8] 說說Linux下的find命令和grep命令的區(qū)別(本題選作)

find:可以按照文件名、文件類型、文件大小、文件修改/訪問時間查找;
grep:按照文件內容查找(正則表達式)。

[9] 請描述出七層網絡模型的名稱,由下到上(可以使用中文描述)

OSI參考模型:


OSI 七層參考模型.png
[10] 說說下面這些這些協議的全稱和中文解釋(提示:都是工作在應用層)SMTP、POP3、HTTP、FTP、DNS
  • SMTP (Simple Mail Transfer Protocol) 簡單郵件傳輸協議
  • POP3 (Post Office Protocol 3) 郵局協議第3版
  • HTTP (Hypertext Transfer Protocol) 超文本傳輸協議
  • FTP (File Transfer Protocol)文件傳輸協議
  • DNS (Domain Name System and Domain Name Service protocol) 域名系統(服務)協議
[11] 使用過Memcache緩存嗎,如果使用過,能夠簡單的描述一下它的工作原理嗎?(本題選作)
  • Memcache 是把所有的數據保存在內存當中,采用hash表的方式,每條數據由key和value組成,每個key是獨一無二的,當要訪問某個值的時候先按照鍵找到值,然后返回結果。
  • Memcahce采用LRU(Least Recently Used)算法來逐漸把過期數據清除掉。
[12] 請大致的說說Session的工作原理(提示:與Cookie有相應的關系)
  • Session的工作原理
    1. 當一個 Session第一次被啟用時,一個唯一的標識被存儲于本地的 Cookie 中。
    2. 首先使用 session_start() 函數,PHP從 Session 倉庫中加載已經存儲的 Session 變量。
    3. 當執(zhí)行 PHP 腳本時,通過使用 session_register() 函數注冊 Session 變量。
    4. 當 PHP腳本執(zhí)行結束時,未被銷毀的 Session 變量會被自動保存在本地一定路徑下的 Session 庫中,這個路徑可以通過 php.ini 文件中的 session.save_path 指定,下次瀏覽網頁時可以加載使用。
  • Session和Cookie的聯系以及區(qū)別
  1. 聯系:Session 在客戶端也需要保存一個標識,所以就要借助Cookie;Session是通過Cookie 來工作的;Session 和Cookie 之間是通過 $_COOKIE['PHPSESSID']來聯系的,通過 $_COOKIE['PHPSESSID'] 可以知道 Session的 id,從而獲取到其他的信息。
  2. 區(qū)別:Cookie 機制采用的是在客戶端(瀏覽器)保持狀態(tài)的方案,而Session 機制采用的是在服務器端保持狀態(tài)的方案。
[13] 說說你所了解的搜索引擎包含那些技術?(本題選作)

爬蟲(采集)、切詞(分詞)、索引(存儲)、查詢以及其他相關技術等。


  • 項目及設計題

[1] 一個Web開發(fā)團隊開發(fā)中,大致說說你所了解的所有成員的分工合作情況

分為美工、前端開發(fā)和后臺開發(fā)人員,美工負責界面效果設計、前端開發(fā)負責用戶交互和設計,后臺開發(fā)人員負責服務端的開發(fā)。

[2] 說說你做過的最得意的項目或者個人開發(fā)作品(可以是個人作品,也可以是合作項目)

這個,你猜...

[3] 假設給你5臺服務器,請大致的描述一下,如何使用你所熟悉的開源軟件,搭建一個日PV 300萬左右的中型網站

PV(page view):頁面瀏覽量,或點擊量,表示一個訪問者在24小時內瀏覽了你網站的幾個頁面。這里需要強調:同一個人瀏覽網站同一個頁面,不重復計算 PV 量,點100次也算1次。
構思(僅供參考):3臺Web服務器,兩臺MySQL數據庫服務器,采用Master/Slave同步的方式減輕數據庫負載,Web服務器可以結合Memcahe緩存來減少負載,同時三臺Web服務器內容一致,可以采用DNS輪詢的方式來進行負載平衡 。


以上就是本章的全部內容,歡迎指出錯誤和補充!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容