本章主要介紹常見的 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的兩個正則表達式。類似下面的:
- 郵箱地址:user_name.first@example.com.cn
- URL地址:http://www.example.com.cn/user_profile.php?uid=100
** 提示:使用標準的正則表達式,就是 PHP 中 preg_* 類的正則處理函數能夠解析的正則**
<?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的工作原理:
- 當一個 Session第一次被啟用時,一個唯一的標識被存儲于本地的 Cookie 中。
- 首先使用 session_start() 函數,PHP從 Session 倉庫中加載已經存儲的 Session 變量。
- 當執(zhí)行 PHP 腳本時,通過使用 session_register() 函數注冊 Session 變量。
- 當 PHP腳本執(zhí)行結束時,未被銷毀的 Session 變量會被自動保存在本地一定路徑下的 Session 庫中,這個路徑可以通過 php.ini 文件中的 session.save_path 指定,下次瀏覽網頁時可以加載使用。
- Session和Cookie的聯系以及區(qū)別:
- 聯系:Session 在客戶端也需要保存一個標識,所以就要借助Cookie;Session是通過Cookie 來工作的;Session 和Cookie 之間是通過 $_COOKIE['PHPSESSID']來聯系的,通過 $_COOKIE['PHPSESSID'] 可以知道 Session的 id,從而獲取到其他的信息。
- 區(qū)別:Cookie 機制采用的是在客戶端(瀏覽器)保持狀態(tài)的方案,而Session 機制采用的是在服務器端保持狀態(tài)的方案。
-
可參考文章:
PHP中Session和Cookie的探究
[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輪詢的方式來進行負載平衡 。
以上就是本章的全部內容,歡迎指出錯誤和補充!