PHP愛考的那些筆試題
來自《PHP程序員面試筆試寶典》,涵蓋了近三年了各大型企業常考的PHP面試題,針對面試題提取出來各種面試知識也涵蓋在了本書。
一、單例模式是在應用程序中最多只能擁有一個該類的實例存在,一旦創建就會一直在內存中。
由於單例模式的設定,所以常應用於數據庫類設計,它可以保證只連接一次數據庫。
單例類的特點如下:
1)單例類不能直接實例化創建,只能由類本身實例化。因此,構造函數必須標記為private,從而防止類被實例化。
2)需要保證一個能訪問到的實例公開的靜態方法和一個私有靜態成員變量來保存類實例。
3)類中通常需要有一個空的私有__clone()方法防止別人對單例類進行實例克隆。
示例代碼如下:
<?php
class Database
{
private static $instance;
private function __construct()
{
// to do
}
private function __clone()
{
// to do
}
public static function getInstance()
{
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
}
$a =Database::getInstance();
$b =Database::getInstance();
print_r($a === $b);
?>
二、【真題180】 寫一個函數,盡可能高效地從一個標准 url 里取出文件的擴展名。例如,http://www.sina.com.cn/abc/de/fg.php?id=1 需要取出 php 或 .php。
參考答案:方法一:
function getExt($url){
$arr = parse_url($url);
$file = basename($arr['path']);
$ext = explode(".",$file);
return $ext[1];
}
方法二:
function getExt($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);
}
}
三、1.PHP相關的日期函數
1)checkdate($month,$date,$year)函數的功能是在日期用於計算或被保存在數據庫中之前,判斷日期是否是一個合法的日期。如下例所示:
<?php
echo checkdate(2,30,2005) ? "valid" : "invalid"; //輸出invalid
echo checkdate(4,6,2010) ? "valid" : "invalid"; //輸出valid
?>
如果日期有效,則輸出valid,如果日期無效,則輸出invalid。
2)mktime($hour, $minute, $second, $month, $day, $year)函數的功能是獲得即時時間的UNIX時間戳。示例代碼如下:
<?php
// returns timestamp for 2017-11-25 13:15:23
echo mktime(13,15,23,11,25,2017); //輸出1511586923
?>
mktime可以根據實際返回unix時間戳。
3)date($format, $ts)函數的功能是顯示格式化時間或日期。示例代碼如下:
<?php
echo date("d-M-Y h:i A", mktime()); //輸出13-Sep-2005 01:16 PM
?>
4)strtotime($str)函數的功能是將非標准化的日期/時間字符串轉換成標准、兼容的UNIX時間戳。示例代碼如下:
<?php
echo date("d-M-y", strtotime("today")); //輸出25-Nov-17
echo date("d-M-y", strtotime("tomorrow")); //輸出26-Nov-17
echo date("d-M-y", strtotime("today +3 days")); //輸出28-Nov-17
?>
strtotime("today")獲取的是今天的時間戳,strtotime("tomorrow")獲取的是明天時間的時間戳,strtotime("today +3 days")獲取到的是三天后的時間戳。
四、【真題173】 在如下代碼中,date()將會輸出( )。
<?php
$date="2009-5-19";
$time="14:31:38";
$datetime=$date.$time;
echo date("Y-m-d:H:i:s",strtotime($datetime));
?>
A.2009-05-19:14:31:38 B.19-5-2009:2:31:38
C.2009-5-19:2:31:38 D.19/5/2009:14:31:38
參考答案:A。
分析:日期中輸出的H:i:s中的H表示24小時制的小時,i表示分,s表示秒。所以根據拼接的時間通過strtotime()函數轉換成時間戳后再轉成日期就可以得到2009-05-19:14:31:38。所以,選項A正確。
五、++與—的含義是什么?
遞增與遞減有兩種使用方法。
1)++$a或--$a:表示先將變量增加或減少1,后做賦值操作,稱為前置遞增或遞減運算符。
2)$a++或$a--:表示先做賦值操作,后將變量增加或減少1,稱為后置遞增或遞減運算符。
【真題74】 若$y、$ x為int型變量,則執行以下語句后,$y的值為( )。
$x=1;
++$x;
$y = $x++;
A.1 B.2 C.3 D.0
參考答案:B。
分析:前置運算++$x,首先對$x 執行加一運算,然后返回$x,對於后置運算$x++,首先返回$x,然后對$x執行加一運算。
六、PHP中遍歷數組有三種常用的方法:
(1)使用for語句循環遍歷數組
使用for語句循環遍歷數組要求遍歷的數組必須是索引數組。PHP中不僅有聯合數組而且還有索引數組,所以PHP中很少用for語句循環遍歷數組。
for語句遍歷數組的方式如下:
<?php
$arr = array(1,2,3);
for($i=0; $i<count($arr); $i++){
echo $arr[$i]." ";
}
?>
程序的運行結果為
1 2 3
(2)使用foreach語句遍歷數組
foreach 僅能用於數組,當試圖將其用於其他數據類型或者一個未初始化的變量時會產生錯誤。foreach的使用格式如下:
1)foreach (array_expression as $value){}。
2)foreach (array_expression as $key => $value){}。
需要注意的是,第1種方法遍歷給定的 array_expression 數組。每次循環中,當前單元的值被賦給 $value並且數組內部的指針向前移一步(因此下一次循環中將會得到下一個單元)。第2種格式做同樣的事,此外,當前單元的鍵名也會在每次循環中被賦給變量 $key。
示例代碼如下:
<?php
$speed = array(50,120,180,240,380);
foreach($speed as $keys=>$values){
echo $keys."=>".$values."\n";
}
?>
程序的運行結果為
0=>50
1=>120
2=>180
3=>240
4=>380
(3)聯合使用list()、each()和while循環遍歷數組
list()、each()、while循環遍歷方法:
<?php
$arr = array(
array("aa0","bb0","cc0"),
array("aa1","bb1","cc1"),
array("aa2","bb2","cc2"),
array("aa3","bb3","cc3")
);
while (list($key,$value) = each($arr)){
list($param1,$param2,$param3) = $value;
echo "$param1 $param2 $param3"."\n";
}
?>
程序的運行結果為
aa0 bb0 cc0
aa1 bb1 cc1
aa2 bb2 cc2
aa3 bb3 cc3
需要注意的是,list()函數不是一個真正的函數,它是PHP的一個語言結構,僅能用於數字索引的數組,且數字索引從0開始。
Mysql部分
一、如何進行數據庫優化?
數據庫優化的過程可以使用以下的方法進行:
1)選取最適用的字段屬性,盡可能減少定義字段長度,盡量把字段設置NOT NULL,例如'省份、性別',最好設置為ENUM。
2)使用連接(JOIN)來代替子查詢。
① 刪除沒有任何訂單客戶:DELETE FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。
② 提取所有沒有訂單客戶:SELECT FROM customerinfo WHERE customerid NOT in(SELECT customerid FROM orderinfo)。
③ 提高b的速度優化:SELECT FROM customerinfo LEFT JOIN orderid customerinfo. customerid=orderinfo.customerid WHERE orderinfo.customerid IS NULL。
3)使用聯合(UNION)來代替手動創建的臨時表。創建臨時表:SELECT name FROM 'nametest' UNION SELECT username FROM 'nametest2'。
4)事務處理。保證數據完整性,例如添加和修改。同時,如果兩者成立,則都執行,一者失敗都失敗:
mysql_query("BEGIN");
mysql_query("INSERT INTO customerinfo (name) VALUES ('$name1')";
mysql_query("SELECT * FROM 'orderinfo' where customerid=".$id");
mysql_query("COMMIT");
5)鎖定表,優化事務處理。用一個SELECT語句取出初始數據,通過一些計算,用UPDATE語句將新值更新到表中。包含有WRITE關鍵字的LOCK TABLE語句可以保證在UNLOCK TABLES命令被執行之前,不會有其他的訪問來對customerinfo表進行插入、更新或者刪除的操作。
mysql_query("LOCK TABLE customerinfo READ, orderinfo WRITE");
mysql_query("SELECT customerid FROM 'customerinfo' where id=".$id);
mysql_query("UPDATE 'orderinfo' SET ordertitle='$title' where customerid=".$id);
mysql_query("UNLOCK TABLES");
6)使用外鍵,優化鎖定表。把customerinfo里的customerid映射到orderinfo里的customerid,任何一條沒有合法的customerid的記錄不會寫到orderinfo里。
CREATE TABLE customerinfo
(
customerid INT NOT NULL,
PRIMARY KEY(customerid)
)TYPE = INNODB;
CREATE TABLE orderinfo
(
orderid INT NOT NULL,
customerid INT NOT NULL,
PRIMARY KEY(customerid,orderid),
FOREIGN KEY (customerid) REFERENCES customerinfo
(customerid) ON DELETE CASCADE
)TYPE = INNODB;
注意:'ON DELETE CASCADE',該參數保證當customerinfo表中的一條記錄刪除的話同時也會刪除order。
表中的該用戶的所有記錄,注意使用外鍵時要定義數據庫引擎為INNODB。
二、選擇正確的存儲引擎?
在MySQL中有兩個存儲引擎:MyISAM和InnoDB,每個引擎都有利有弊。
MyISAM適合於一些需要大量查詢的應用,但其對於有大量寫操作的支持並不是很好。甚至只是需要update一個字段,整個表都會被鎖起來,而其他進程,就算是讀進程都無法操作直到讀操作完成。另外,MyISAM 對於 SELECT COUNT(*) 這類的計算是超快無比的。
InnoDB 的趨勢會是一個非常復雜的存儲引擎,對於一些小的應用,它會比 MyISAM 還慢。但是它支持“行鎖”,於是在寫操作比較多的時候,會更優秀。並且,它還支持更多的高級應用,例如事務。
三、【真題231】 用什么方法檢查PHP腳本的執行效率(通常是腳本執行時間)和數據庫SQL的效率(通常是數據庫query時間),並定位和分析腳本執行和數據庫查詢的瓶頸所在?
參考答案:檢查PHP腳本的執行效率的方法如下:可以在檢查的代碼開頭記錄一個時間,然后在代碼的結尾也記錄一個時間,結尾時間減去開頭時間取這個時間的差值,從而檢查PHP的腳本執行效率,記錄時間可以使用microtime()函數。
檢查數據庫SQL的效率的方法如下:可以通過explain顯示MySQL如何使用索引來處理select語句及連接表,幫助選擇更好的索引和寫出更優化的查詢語句。然后啟用slow query log記錄慢查詢,通過查看SQL的執行時間和效率來定位分析腳本執行的問題和瓶頸所在。
四、 以下代碼的運行結果為( )。
<?php
mysql_connect('localhost','root',"");
$result = mysql_query("SELECT id,name FROM tb1");
while($row = mysql_fetch_array($result,MySQL_ASSOC)){
echo' ID:' .$row[0].' Name:' .$row[];
}
?>
A.報錯 B.循環換行打印全部記錄
C.無任何結果 D.只打印第一條記錄
參考答案:A。
分析:因為代碼中沒有指明要操作的數據庫名,所以會報錯。
所以,本題的答案為A。
問題:設教務管理系統中有三個基本表:
學生信息表S(SNO, SNAME, AGE, SEX),其屬性分別表示學號、學生姓名、年齡和性別。
選課信息表SC(SNO, CNO, SCGRADE),其屬性分別表示學號、課程號和成績。
課程信息表C(CNO, CNAME, CTEACHER),其屬性分別表示課程號、課程名稱和任課老師姓名。
1)把SC表中每門課程的平均成績插入另外一個已經存在的表SC_C(CNO, CNAME, AVG_GRADE)中,其中AVG_GRADE表示的是每門課程的平均成績。
INSERT INTO SC_C(CNO, CNAME, AVG_GRADE)
SELECT SC.CNO, C.CNAME, AVG(SCGRADE) FROM SC, C WHERE SC.CNO = C.CNO GROUP BY SC.CNO
2)規定女同學選修何昊老師的課程成績都應該在80分以上(包含80分)。
ALERT TABLE SC, S, C
ADD CONSTRAINT GRADE CHECK(SCGRADE>=80)
WHERE SC.CNO=C.CNO AND SC.SNO=S.SNO AND C.CTEACHER='何昊' AND S.SEX=
"女"
3)從SC表中把何昊老師的女學生選課記錄刪除。
DELETE FROM SC WHERE CNO=(SELECT CNO FROM C WHERE C.CTEACHER ='何昊') AND SNO IN (SELECT SNO FROM S WHERE SEX='女')
4)找出沒有選修過“何昊”老師講授課程的所有學生姓名。
SELECT SNAME FROM S
WHERE NOT EXISTS(
SELECT * FROM SC,C WHERE SC.CNO=C.CNO AND CNAME='何昊' AND SC.SNO=S.SNO)
5)列出有兩門以上(含兩門)不及格課程(成績小於60)的學生姓名及其平均成績。
SELECT S.SNO,S.SNAME,AVG_SCGRADE=AVG(SC.SCGRADE)
FROM S,SC,(
SELECT SNO FROM SC WHERE SCGRADE<60 GROUP BY SNO
HAVING COUNT(DISTINCT CNO)>=2)A WHERE S.SNO=A.SNO AND SC.SNO = A.SNO
GROUP BY S.SNO,S.SNAME
6)列出既學過“1”號課程,又學過“2”號課程的所有學生姓名。
SELECT S.SNO,S.SNAME
FROM S,(SELECT SC.SNO FROM SC,C
WHERE SC.CNO=C.CNO AND C.CNAME IN('1','2')
GROUP BY SNO
HAVING COUNT(DISTINCT CNO)=2
)SC WHERE S.SNO=SC.SNO
7)列出“1”號課成績比“2”號同學該門課成績高的所有學生的學號。
SELECT S.SNO,S.SNAME
FROM S,(
SELECT SC1.SNO
FROM SC SC1,C C1,SC SC2,C C2
WHERE SC1.CNO=C1.CNO AND C1.NAME='1'
AND SC2.CNO=C2.CNO AND C2.NAME='2'
AND SC1.SCGRADE>SC2.SCGRADE
)SC WHERE S.SNO=SC.SNO
8)列出“1”號課成績比“2”號課成績高的所有學生的學號及其“1”號課和“2”號課的成績。
SELECT S.SNO,S.SNAME,SC.[1號課成績],SC.[2號課成績]
FROM S,(
SELECT SC1.SNO,[1號課成績]=SC1.SCGRADE,[2號課成績]=SC2.SCGRADE
FROM SC SC1,C C1,SC SC2,C C2
WHERE SC1.CNO=C1.CNO AND C1.NAME='1'
AND SC2.CNO=C2.CNO AND C2.NAME='2'
AND SC1.SCGRADE>SC2.SCGRADE
)SC WHERE S.SNO=SC.SNO
購買鏈接:京東購買
題目來自《PHP程序員面試筆試寶典》,里面涵蓋了近三年了各大型企業常考的PHP面試題,針對面試題提取出來各種面試知識也涵蓋在了本書。
更多PHP面試筆試真題可以瀏覽:www.shuaiqi100.com
更多有趣有料的PHP面試筆試資料可以關注:“琉憶編程庫”
或者瀏覽:www.shuaiqi100.com 獲取。
PHP程序員面試筆試寶典下載:https://pan.baidu.com/s/1-ES2ZI3z5Lhv-zTKFmJDSQ