題目來自《PHP程序員面試筆試寶典》,里面涵蓋了近三年了各大型企業(yè)程寥ⅲ考的PHP面試題约巷,針對面試題提取出來各種面試知識也涵蓋在了本書。
[if !supportLists]1司训、[endif]PHP彻辜瘢考基礎(chǔ)
1、PHP與ASP壳猜、JSP有什么區(qū)別勾徽?
ASP全名Active Server Pages,是一個基于Windows平臺的Web服務(wù)器端的開發(fā)環(huán)境统扳,利用它可以產(chǎn)生和運(yùn)行動態(tài)的喘帚、交互的畅姊、高性能的Web服務(wù)應(yīng)用程序,它只能在微軟平臺上使用吹由,移植性不好若未。ASP采用腳本語言VB Script、JScript(JavaScript)作為自己的開發(fā)語言倾鲫。國內(nèi)早期大部分網(wǎng)站都用它來開發(fā)粗合。但因微軟全面轉(zhuǎn)向,ASP.NET放棄了ASP的Web開發(fā)模式乌昔,所以現(xiàn)在已經(jīng)被淘汰使用舌劳。
PHP是一種跨平臺的服務(wù)器端的嵌入式腳本語言。它大量地借用C玫荣、Java和Perl語言的語法甚淡,并耦合PHP自己的特性,使Web開發(fā)者能夠快速地寫出動態(tài)生成頁面捅厂。它可嵌入HTML中贯卦,非常適合Web開發(fā),而且它支持目前絕大多數(shù)數(shù)據(jù)庫焙贷。除此以外撵割,PHP是完全免費(fèi)的,不用花錢辙芍,開發(fā)人員就可以從PHP官方站點(diǎn)(http://www.php.net)自由下載啡彬。而且開發(fā)人員可以不受限制地獲得源碼,甚至可以從中加入自己需要的特色故硅,開發(fā)效率高庶灿,成本低。
JSP是Sun公司推出的一種網(wǎng)絡(luò)編程語言吃衅,跨平臺運(yùn)行往踢,安全性高,運(yùn)行效率也高徘层。它的開發(fā)語言主要基于Java峻呕。
ASP、JSP趣效、PHP三者都提供在 HTML 代碼中混合某種程序代碼瘦癌、由語言引擎解釋執(zhí)行跷敬,但JSP代碼被編譯成 Servlet并由Java虛擬機(jī)解釋執(zhí)行,這種編譯操作僅在對JSP頁面的第一次請求時發(fā)生妄帘。在ASP楞黄、PHP抡驼、JSP環(huán)境下,HTML代碼主要負(fù)責(zé)描述信息的顯示樣式致盟,而程序代碼則用來描述處理邏輯碎税。普通的HTML頁面只依賴于Web服務(wù)器馏锡,而ASP、PHP匪煌、JSP頁面需要附加的語言引擎分析和執(zhí)行程序代碼萎庭。程序代碼的執(zhí)行結(jié)果被重新嵌入HTML代碼中齿拂,然后一起發(fā)送給瀏覽器署海。ASP、PHP捻勉、JSP三者都是面向 Web 服務(wù)器的技術(shù)贯底,客戶端瀏覽器不需要任何附加的軟件支持撒强。
2飘哨、在PHP中,單引號和雙引號所包圍的字符串的區(qū)別是(????)琐凭。
A.單引號解析其中\(zhòng)r\t等轉(zhuǎn)義字符,而雙引號不解析
B.雙引號速度快牙躺,單引號速度慢
C.單引號速度快孽拷,雙引號速度慢
D.雙引號解析其中以$開頭的變量半抱,而單引號不解析
參考答案:D窿侈。
分析:雙引號是可以解析$符開頭的變量和轉(zhuǎn)義字符的史简,而單引號不解析也不轉(zhuǎn)義字符。所以环形,選項(xiàng)A錯誤抬吟,選項(xiàng)D正確火本。
對于選項(xiàng)B和選項(xiàng)C聪建,由于題目中明確說了引號內(nèi)包含的是字符串金麸,因此不需要對變量進(jìn)行解析挥下,在這種情況下雙引號和單引號的效率是相同的棚瘟。選項(xiàng)B和選項(xiàng)C都是錯誤的。
3庄蹋、面向?qū)ο笈c面向過程有什么區(qū)別限书?
面向?qū)ο笫钱?dāng)今軟件開發(fā)方法的主流方法之一倦西,它是把數(shù)據(jù)及對數(shù)據(jù)的操作方法放在一起调限,作為一個相互依存的整體,即對象秦躯。對同類對象抽象出其共性,即類,類中的大多數(shù)數(shù)據(jù),只能被本類的方法進(jìn)行處理载荔。類通過一個簡單的外部接口與外界發(fā)生關(guān)系懒熙,對象與對象之間通過消息進(jìn)行通信工扎。程序流程由用戶在使用中決定肢娘。例如舆驶,站在抽象的角度贞远,人類具有身高蓝仲、體重袱结、年齡、血型等一些特稱溢吻,人類會勞動促王、會直立行走蝇狼、會吃飯迅耘、會用自己的頭腦去創(chuàng)造工具等這些方法颤专,人類僅僅只是一個抽象的概念钠乏,它是不存在的實(shí)體晓避,但是所有具備人類這個群體的屬性與方法的對象都稱為人够滑,這個對象人是實(shí)際存在的實(shí)體彰触,每個人都是人這個群體的一個對象况毅。
而面向過程是一種以事件為中心的開發(fā)方法尔许,就是自頂向下順序執(zhí)行,逐步求精蒸甜,其程序結(jié)構(gòu)是按功能劃分為若干個基本模塊柠新,這些模塊形成一個樹狀結(jié)構(gòu)恨憎,各模塊之間的關(guān)系也比較簡單憔恳,在功能上相對獨(dú)立钥组,每一模塊內(nèi)部一般都是由順序者铜、選擇和循環(huán)三種基本結(jié)構(gòu)組成作烟,其模塊化實(shí)現(xiàn)的具體方法是使用子程序,而程序流程在寫程序時就已經(jīng)決定衣厘。例如五子棋影暴,面向過程的設(shè)計思路就是首先分析問題的步驟:第一步型宙,開始游戲妆兑;第二步搁嗓,黑子先走腺逛;第三步棍矛,繪制畫面;第四步茂契,判斷輸贏;第五步脐雪,輪到白子战秋;第六步脂信,繪制畫面狰闪;第七步埋泵,判斷輸贏丽声;第八步雁社,返回步驟二霉撵;第九步喊巍,輸出最后結(jié)果崭参。把上面每個步驟用分別的函數(shù)來實(shí)現(xiàn)何暮,就是一個面向過程的開發(fā)方法海洼。
具體而言坏逢,二者主要有以下幾個方面的不同之處是整。
1)出發(fā)點(diǎn)不同浮入。面向?qū)ο笫怯梅铣R?guī)思維方式來處理客觀世界的問題事秀,強(qiáng)調(diào)把問題域的要領(lǐng)直接映射到對象及對象之間的接口上易迹。而面向過程方法則不然赴蝇,它強(qiáng)調(diào)的是過程的抽象化與模塊化句伶,它是以過程為中心構(gòu)造或處理客觀世界問題的考余。
2)層次邏輯關(guān)系不同楚堤。面向?qū)ο蠓椒▌t是用計算機(jī)邏輯來模擬客觀世界中的物理存在身冬,以對象的集合類作為處理問題的基本單位酥筝,盡可能地使計算機(jī)世界向客觀世界靠攏,以使問題的處理更清晰直接茁影,面向?qū)ο蠓椒ㄊ怯妙惖膶哟谓Y(jié)構(gòu)來體現(xiàn)類之間的繼承和發(fā)展募闲。面向過程方法處理問題的基本單位是能清晰準(zhǔn)確地表達(dá)過程的模塊浩螺,用模塊的層次結(jié)構(gòu)概括模塊或模塊間的關(guān)系與功能年扩,把客觀世界的問題抽象成計算機(jī)可以處理的過程。
3)數(shù)據(jù)處理方式與控制程序方式不同腿时。面向?qū)ο蠓椒▽?shù)據(jù)與對應(yīng)的代碼封裝成一個整體批糟,原則上其他對象不能直接修改其數(shù)據(jù)徽鼎,即對象的修改只能由自身的成員函數(shù)完成否淤,控制程序方式上是通過“事件驅(qū)動”來激活和運(yùn)行程序石抡。而面向過程方法是直接通過程序來處理數(shù)據(jù)啰扛,處理完畢后即可顯示處理結(jié)果隐解,在控制程序方式上是按照設(shè)計調(diào)用或返回程序,不能自由導(dǎo)航溜嗜,各模塊之間存在著控制與被控制炸宵、調(diào)用與被調(diào)用土全。
4)分析設(shè)計與編碼轉(zhuǎn)換方式不同裹匙。面向?qū)ο蠓椒ㄘ灤┸浖芷诘姆治龈乓场⒃O(shè)計及編碼之間是一種平滑過程惰匙,從分析到設(shè)計再到編碼是采用一致性的模型表示哑梳,即實(shí)現(xiàn)的是一種無縫連接鸠真。而面向過程方法強(qiáng)調(diào)分析吠卷、設(shè)計及編碼之間按規(guī)則進(jìn)行轉(zhuǎn)換撤嫩,貫穿軟件生命周期的分析序攘、設(shè)計及編碼之間程奠,實(shí)現(xiàn)的是一種有縫的連接。
4距境、在PHP中垫桂,自定義一個類的方式是(????)诬滩。
A.<?php default class Class_Name(){ //...... } ?>
B.<?php class Class_Name{ //......} ?>
C.<?php public function Class_Name(){//......}?>
D.<?php function Class_Name{//......}?>
參考答案:B疼鸟。
分析:定義一個類是使用class關(guān)鍵字加類名來定義的空镜,定義格式為:class類名{}馋袜。實(shí)例化一個類的格式為:$object=new類名();。
【真題11】 獲得實(shí)例化對象所屬類名字的函數(shù)是()茴厉。
A.get_class() B.get_object_vars()
C.get_class_methods() D.get_classname()
參考答案:A矾缓。
分析:對于選項(xiàng)A嗜闻,get_class()函數(shù)用于返回一個對象的類的名稱琉雳。所以,選項(xiàng)A正確友瘤。
對于選項(xiàng)B翠肘,get_object_vars()函數(shù)用于得到給定對象的屬性。所以辫秧,選項(xiàng)B錯誤束倍。
對于選項(xiàng)C,get_class_methods()函數(shù)用于獲取類方法的名字绪妹。所以甥桂,選項(xiàng)C錯誤。
對于選項(xiàng)D邮旷,PHP中沒有該方法黄选。所以,選項(xiàng)D錯誤廊移。
5糕簿、以下有關(guān)PHP面向?qū)ο蟮恼f法中,不正確的是( ???)狡孔。
A.要實(shí)現(xiàn)一個接口懂诗,使用implements操作符,類中必須實(shí)現(xiàn)接口中定義的所有方法苗膝,否則會報一個致命錯誤
B.類名可以是任何非PHP保留字的合法標(biāo)簽殃恒,漢字也可以作為PHP的類名
C.如果PHP的子類中定義了構(gòu)造函數(shù),則創(chuàng)建子類的對象時辱揭,會隱式地調(diào)用其父類的構(gòu)造函數(shù)
D.序列化一個對象將會保存對象的所有變量离唐,但是不會保存對象的方法,只會保存類的名字
參考答案:C问窃。
分析:子類定義的構(gòu)造函數(shù)會覆蓋父類的構(gòu)造函數(shù)亥鬓,如果要子類的構(gòu)造函數(shù)執(zhí)行,同時也執(zhí)行父類的構(gòu)造函數(shù)域庇,那么必須顯式地使用parent::__construct();去調(diào)用嵌戈。所以,選項(xiàng)C錯誤听皿。
6熟呛、下面關(guān)于PHP抽象類的描述中,錯誤的是( ???)尉姨。
A.PHP中抽象類使用abstract關(guān)鍵字定義
B.沒有方法體的方法叫抽象方法庵朝,包含抽象方法的類必須是抽象類
C.抽象類中必須有抽象方法,否則不叫抽象類
D.抽象類不能實(shí)例化又厉,也就是不可以new成對象
參考答案:C九府。
分析:抽象類可以是個空類,也就是不一定需要有抽象方法馋没。但抽象方法只能存在抽象類中昔逗。所以,選項(xiàng)C錯誤篷朵。
7勾怒、什么是多態(tài)婆排?
多態(tài)是面向?qū)ο蟪绦蛟O(shè)計中代碼重用的一個重要機(jī)制,它表示當(dāng)同一個操作作用在不同的對象的時候笔链,會有不同的語義段只,從而會產(chǎn)生不同的結(jié)果。例如鉴扫,同樣是“+”操作赞枕,3+4用來實(shí)現(xiàn)整數(shù)相加,而“3”+“4”卻實(shí)現(xiàn)了字符串的連接坪创。一般而言炕婶,多態(tài)有兩種實(shí)現(xiàn)方式:覆蓋和重載。
8莱预、 include與require有什么區(qū)別柠掂?
require和include有著相似的功能:將指定文件中的所有代碼/文本/標(biāo)記復(fù)制到使用require或include語句的文件中。通常被用在數(shù)據(jù)依沮、文件或代碼需要被共享的場景涯贞。通過把需要被共享的代碼或數(shù)據(jù)放到一個單獨(dú)PHP文件中,在需要使用的文件中通過require或include來引用危喉。require()和include()也不是真正的函數(shù)宋渔,因此,require()和include()語句也可以不加圓括號而直接加參數(shù)辜限。
9皇拣、下列代碼的輸出是()。
<?php
????define("x","5");
????$x=x+10;
????echo x;
?>
A.Error B.5 C.10 D.15
參考答案:B薄嫡。
分析:在PHP中审磁,define函數(shù)用于定義一個常量,而常量的值在設(shè)定以后岂座,是無法更改的。本題中杭措,x的值始終為5费什。所以,選項(xiàng)B正確手素。
10鸳址、如何對變量進(jìn)行引用?
可以在變量的前面加&符號對變量進(jìn)行引用泉懦,變量的引用相當(dāng)于給變量起了個別名稿黍,通過不同的名字訪問同一個變量內(nèi)容,所以改變其中一個變量的值崩哩,另一個變量也會跟著改變巡球。
【真題54】 有如下代碼:
<?php
????$a="hello";
????$b= &$a;
????unset($b);
????$b="world";
????echo $a;
?>
程序的運(yùn)行結(jié)果為()
A.hello B.world C.NULL D.unset
參考答案:A言沐。
分析:這個代碼的執(zhí)行過程如下圖所示。
1)首先執(zhí)行$b= &$a后酣栈,a和b引用同一個字符串變量“hello”险胰。
2)接著執(zhí)行unset($b),這個函數(shù)可以斷開這個引用關(guān)系矿筝。此時由于a仍然指向字符串“hello”起便,也就是說,這個字符串仍然被a使用窖维,因此這個字符串不會被回收榆综。
3)接著執(zhí)行$b="world",此時铸史,b指向一個新的字符串“world”鼻疮,這并不會影響a的值。因此輸出結(jié)果為hello沛贪。
[if !supportLists]2陋守、[endif]PHP常考進(jìn)階
11利赋、請寫一個函數(shù)驗(yàn)證電子郵件的格式是否正確水评。
參考答案:
function checkEmail($email)
{
????$pregEmail= "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
????return preg_match($pregEmail,$email); ?
}
分析:首尾兩個斜杠/是正則表達(dá)式的限定符,這是Perl正則的標(biāo)準(zhǔn)媚送,而PHP與Perl有相同的正則的規(guī)范中燥。兩個斜杠之間表示的是正則內(nèi)容,后面的i表示忽略大小寫塘偎。
這個正則表達(dá)式表示的含義如下:
1)必須以([0-9A-Za-z\\-_\\.]+)開頭疗涉,也就是說,郵件地址以多個字母吟秩、數(shù)組咱扣、“-”或“.”開頭。
2)緊接著是字符“@”涵防。
3)然后接著是多個字母或數(shù)字的字符串闹伪,接著是一個字符“.”,接著是兩個或三個字母壮池;然后接下來一部分可有可無的:一個“.”后面跟著兩個字母偏瓤。
4)郵件的結(jié)束符是滿足3)的字符串。
12椰憋、以下可以匹配中國居民身份證號碼的正則表達(dá)式是()厅克。
A.\d{15} B.\d{18}
C.\d D.(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
參考答案:D。
分析:\d表示0~9任意數(shù)字橙依。
13证舟、【真題96】 一個函數(shù)的參數(shù)不能是對變量的引用硕旗,除非在php.ini中把()設(shè)為on。
參考答案:allow_call_time_pass_reference褪储。
分析:在PHP函數(shù)調(diào)用的時候卵渴,基本數(shù)據(jù)類型默認(rèn)會使用值傳遞,而不是引用傳遞鲤竹。allow_call_time_pass_reference?選項(xiàng)的作用為是否啟用在函數(shù)調(diào)用時強(qiáng)制參數(shù)被按照引用傳遞浪读。如果把a(bǔ)llow_call_time_pass_reference?配置為on,那么在函數(shù)調(diào)用的時候會默認(rèn)使用引用傳值辛藻。但是不推薦使用這種方法碘橘,原因是該方法在未來的版本中很可能不再支持。如果想使用引用傳遞吱肌,那么推薦在函數(shù)調(diào)用的時候顯式地使用&進(jìn)行引用傳遞痘拆。
14、文件讀操作
讀取文件前氮墨,通常會判斷文件能否讀取纺蛆,例如,是否有讀權(quán)限规揪,可以使用is_readable函數(shù)桥氏;示例代碼如下:
<?php
????$file = "test.txt";
????if(is_readable($file) == false) {
????????echo "can not read\n";
????}
????else{
????????echo "can read \n";
????}
?>
當(dāng)然也需要判斷文件是否存在,可以使用file_exists()函數(shù)猛铅。示例代碼如下:
<?php
????$file = "test.txt";
????if(file_exists($file) == false) {
????????echo "file not exist\n";
????}
????else{
????}
????echo "file is exists \n";
?>
讀取文件的方法有很多種字支,此處列舉最常用的按行讀取方法,示例代碼如下:
<?php
????$file = "test.txt";
????$fp = fopen($file,"r");
????while(!feof($fp)){
????????echo fgets($fp,1024);
????} ???
????fclose($fp);
?>
需要注意的是奸忽,讀取文件的length參數(shù)是可選項(xiàng)堕伪,如果忽略,則將繼續(xù)從流中讀取數(shù)據(jù)直到行結(jié)束栗菜。指定最大行的長度在利用資源上更為有效欠雌。此外,還有fread疙筹、file_get_contents等讀取文件的方法桨昙,此處不再贅述。
15腌歉、什么是異常處理與錯誤處理?
當(dāng)運(yùn)行的程序發(fā)生異常被拋出時齐苛,程序不會繼續(xù)執(zhí)行異常處后面的代碼翘盖,PHP會嘗試查找匹配的“catch”代碼塊。如果異常沒有被捕獲凹蜂,那么將會發(fā)生嚴(yán)重的錯誤馍驯,程序會終止或者不受控制地執(zhí)行阁危。示例代碼如下:
<?php
????function GetNum($num)
????{
????????if($num > 10)
????????{
????????????throw new Exception("Exception ocur");
????????}
????????return true;
????}
????GetNum(100);
?>
程序的運(yùn)行結(jié)果為
Uncaught exception 'Exception' with message 'Exception ocur'
從這個例子可以看出,如果不對異常進(jìn)行處理汰瘫,那么當(dāng)程序有異常拋出的時候就會結(jié)束執(zhí)行狂打。而對于對象方法的異常處理,還有另外一種處理方法混弥,下面介紹在PHP中當(dāng)調(diào)用一些不存在的對象方法時的異常處理趴乡,從而保證程序正常運(yùn)行。這主要是通過__call方法來實(shí)現(xiàn)的蝗拿。
方法聲明為__call($funname,$arr_value)晾捏,當(dāng)被調(diào)用方法不存在的時候會默認(rèn)調(diào)用這個方法。
示例代碼如下:
class My {
????function __call($n,$v) {
echo "錯誤的方法名:".$n;
echo "錯誤的參數(shù):".$v;
????}
}
16哀托、什么是內(nèi)存管理惦辛?
內(nèi)存管理主要是指程序運(yùn)行時對計算機(jī)內(nèi)存資源的分配、使用和釋放等技術(shù)仓手,內(nèi)存管理的目標(biāo)是高效胖齐、快速地分配內(nèi)存同時及時地釋放和回收內(nèi)存資源。內(nèi)存管理主要包括是否有足夠的內(nèi)存供程序使用嗽冒,從內(nèi)存池中獲取可用內(nèi)存呀伙,使用后及時銷毀并重新分配給其他程序使用。
在PHP開發(fā)過程中辛慰,如果遇到大數(shù)組等操作区匠,那么可能會造成內(nèi)存溢出等問題。一些常見的處理方法如下:
1)通過ini_set('memory_limit','64M')方法重置php可以使用的內(nèi)存大小帅腌,一般在遠(yuǎn)程主機(jī)上是不能修改php.ini文件的驰弄,只能通過程序設(shè)置。注:在safe_mode(安全模式)下速客,ini_set會失效戚篙。
2)另一方面可以對數(shù)組進(jìn)行分批處理,及時銷毀無用的變量溺职,盡量減少靜態(tài)變量的使用岔擂,在需要數(shù)據(jù)重用時,可以考慮使用引用(&)浪耘。同時對于數(shù)據(jù)庫乱灵、文件操作完要及時關(guān)閉,對象使用完要及時調(diào)用析構(gòu)函數(shù)等七冲。
3)及時使用unset()函數(shù)釋放變量痛倚,使用時需要注意以下兩點(diǎn):
① unset()函數(shù)只能在變量值占用內(nèi)存空間超過256字節(jié)時才會釋放內(nèi)存空間。
② 只有當(dāng)指向該變量的所有變量都銷毀后澜躺,才能成功釋放內(nèi)存蝉稳。
17抒蚜、與MySQL一樣,Redis在使用過程中耘戚,也會碰到很多的問題嗡髓,適當(dāng)?shù)募记珊蛢?yōu)化將大大提高Redis的使用性能,提高服務(wù)的質(zhì)量∈战颍現(xiàn)將常見的一些問題總結(jié)如下:
1.停止使用keys *操作
keys*操作執(zhí)行速度將會變慢饿这。因?yàn)閗eys命令的時間復(fù)雜度是O(n),其中n是要返回的keys的個數(shù)朋截,由此可見這個命令的復(fù)雜度就取決于數(shù)據(jù)量的大小了蛹稍。當(dāng)數(shù)據(jù)量比較大時,在這個操作執(zhí)行期間部服,其他任何命令在實(shí)例中都無法執(zhí)行唆姐,嚴(yán)重影響了性能。
可以使用scan命令來代替廓八,scan命令通過增量迭代的方式來掃描數(shù)據(jù)庫奉芦。
2.定位Redis速度降低的原因
使用INFO commandstats命令來查看所有命令的統(tǒng)計情況,如命令執(zhí)行了多少次剧蹂,執(zhí)行命令所耗費(fèi)的毫秒數(shù)等信息声功。
18、Memcache的特征和特性
Memcache的特征如下:
1)協(xié)議簡單宠叼。
2)基于libevent的事件處理先巴。
3)內(nèi)置內(nèi)存存儲方式。
4)Memcached不互相通信的分布式冒冬。
Memcache的特性如下:
(1)單個item 最大的數(shù)據(jù)為1MB伸蚯。
(2)單進(jìn)程最大的使用內(nèi)存為2GB,需要更多內(nèi)存時可開多個端口简烤。
(3)Memcached是多線程剂邮,非阻塞io復(fù)用的網(wǎng)絡(luò)模型,Redis是單線程横侦。
(4)鍵長最大為250字節(jié)挥萌。
19、下面可以用于服務(wù)器共享session的方式有( ???)枉侧。
A.利用NFS共享Session數(shù)據(jù) B.基于數(shù)據(jù)庫的Session共享
C.基于Cookie的Session共享 D.使用類似BIG-IP的負(fù)載設(shè)備來實(shí)現(xiàn)資源共享
參考答案:A引瀑、B、C榨馁、D伤疙。
分析:共享Session的方式主要有以下幾種:
1)基于NFS的Session共享。NFS(Network? File System)最早由Sun公司為解決Unix網(wǎng)絡(luò)主機(jī)間的目錄共享而研發(fā)。僅需將共享目錄服務(wù)器mount到其他服務(wù)器的本地session目錄即可徒像。
2)基于數(shù)據(jù)庫的Session共享。
3)基于Cookie的Session共享蛙讥。原理是將全站用戶的Session信息加密锯蛀、序列化后以Cookie的方式,統(tǒng)一種植在根域名下(如:.host.com)次慢,利用瀏覽器訪問該根域名下的所有二級域名站點(diǎn)時旁涤,會傳遞與之域名對應(yīng)的所有Cookie內(nèi)容的特性,從而實(shí)現(xiàn)用戶的Cookie化Session 在多服務(wù)間的共享訪問迫像。
4)基于緩存(Memcache)的Session共享劈愚。Memcache是一款基于Libevent多路異步I/O技術(shù)的內(nèi)存共享系統(tǒng),簡單的key + value數(shù)據(jù)存儲模式使得代碼邏輯小巧高效闻妓,因此在并發(fā)處理能力上占據(jù)了絕對優(yōu)勢菌羽,目前能達(dá)到2000/s平均查詢,并且服務(wù)器CPU消耗依然不到10%由缆。
所以注祖,本題的答案為A、B均唉、C是晨、D。
20舔箭、如何預(yù)防各類安全性問題罩缴?
常見的安全性問題主要包括以下方面:
1)SQL注入攻擊。所謂SQL注入式攻擊层扶,就是攻擊者把SQL命令插入Web表單的域或頁面請求的查詢字符串中箫章,欺騙服務(wù)器執(zhí)行惡意的SQL命令。在某些表單中怒医,用戶輸入的內(nèi)容直接用來構(gòu)造動態(tài)SQL命令炉抒,或作為存儲過程的輸入?yún)?shù),這類表單特別容易受到SQL注入式攻擊稚叹。例如焰薄,對于一個站點(diǎn)http://www.shuaiqi100.com/News/details.jsp?id=2的頁面,id是查詢參數(shù)扒袖,通過id獲取顯示某條信息塞茅,在JSP程序中,用SQL語句來讀取該條新聞:“select * from news where id =”+ id季率,正常執(zhí)行的話野瘦,只需要將id替換為參數(shù)2即可,沒有任何問題,但是當(dāng)非法用戶將id的參數(shù)變?yōu)閕d=2;drop database news時鞭光,則執(zhí)行的SQL語句除了讀取對應(yīng)的新聞信息外吏廉,還會執(zhí)行drop database news信息,可是后面這條語句是非法的惰许。
由于SQL注入攻擊利用的是合法的SQL語句席覆,使得這種攻擊不能被防火墻檢查,而且由于對任何基于SQL語言標(biāo)準(zhǔn)的數(shù)據(jù)庫都適用汹买,所以危害特別大佩伤。盡管如此,目前防止SQL注入攻擊的方法也非常多晦毙,具體而言生巡,有以下一些方法:使用預(yù)處理語句和參數(shù)分別發(fā)送到數(shù)據(jù)庫服務(wù)器進(jìn)行解析,參數(shù)將會被當(dāng)作普通字符處理见妒。使用這種方式后孤荣,攻擊者無法注入惡意的SQL。那么如何防止SQL注入攻擊呢徐鹤,下面介紹常用的一些方法:
① 預(yù)處理語句和參數(shù)分別發(fā)送到數(shù)據(jù)庫服務(wù)器進(jìn)行解析垃环。
② 使用函數(shù)addslashes()轉(zhuǎn)義提交的內(nèi)容。
③ PHP配置文件中開啟magic_quotes_gpc=on;將自動轉(zhuǎn)換用戶查詢的SQL語句返敬,對防止SQL注入有重大作用遂庄。
④ 在PHP配置文件中,將register_globals設(shè)置為off劲赠,關(guān)閉全局變量注冊涛目。
⑤ 在PHP配置文件中,開啟安全模式safe_mode=on;凛澎。
⑥ SQL語句的書寫盡量不要省略小引號與單引號霹肝。
⑦ 提高數(shù)據(jù)庫表和字段的命名技巧,對一些重要的字段根據(jù)程序的特點(diǎn)命名塑煎,取不易被猜到的名字沫换。
⑧ 控制錯誤信息,關(guān)閉錯誤信息的輸出最铁,將錯誤信息寫到日志文件中讯赏,不要在網(wǎng)站暴露錯誤信息。
2)數(shù)據(jù)庫操作安全問題冷尉。例如漱挎,未對用戶的權(quán)限進(jìn)行限制,update雀哨、delete磕谅、insert等誤操作造成系統(tǒng)安全性問題私爷。
解決方法為給不同的用戶授不同的權(quán)限,這樣能夠保證只有有權(quán)限的用戶才能進(jìn)行特定的操作膊夹。
3)沒有驗(yàn)證用戶http請求方式衬浑。惡意的用戶可以模擬http對網(wǎng)站進(jìn)行請求產(chǎn)生惡意攻擊,為了防止這種攻擊需要檢查用戶的http請求中的訪問來源是否可信放刨,對http頭中的referer進(jìn)行過濾明肮,只允許本域站點(diǎn)訪問骚揍。
4)沒有驗(yàn)證表單來源的唯一性,不能識別是合法的表單提交還是黑客偽造的表單提交碱鳞。
為了防止黑客偽造表單提交侵佃,可以使用一次性令牌Token麻昼。通過服務(wù)器端以某種策略生成隨機(jī)字符串作為令牌保存在Session里,然后發(fā)出請求的頁面時馋辈,把該令牌以隱藏域一類的形式抚芦,與其他信息一并發(fā)出,在接收頁面中把接收到的信息中的令牌與Session中的令牌比較迈螟,一致才處理請求叉抡,否則拒絕請求,以此保證表單的來源唯一答毫,防止黑客偽造的表單提交褥民。
21、PHP的開發(fā)框架有哪些洗搂?
CodeIgniter是一個輕量級的PHP開發(fā)框架消返,具有快速開發(fā)、靈活性高等優(yōu)點(diǎn)耘拇,它特別適合互聯(lián)網(wǎng)公司的快速迭代場景撵颊,因此很受歡迎,據(jù)說騰訊惫叛、去哪兒網(wǎng)等應(yīng)用場景都使用了這個框架倡勇。CodeIgniter具有動態(tài)實(shí)例化、松耦合嘉涌、組件單一性等很多優(yōu)點(diǎn)妻熊。動態(tài)實(shí)例化是指組件的導(dǎo)入和函數(shù)在執(zhí)行時才會生效。松耦合是指系統(tǒng)模塊之間的關(guān)聯(lián)依賴很少洛心,確保系統(tǒng)具有很好的重用性和靈活性固耘。框架內(nèi)的類和功能都是高度自治的词身,具有非常好的組件單一性厅目。
在CodeIgniter中,模型代表數(shù)據(jù)結(jié)構(gòu),包含取出损敷、插入葫笼、更新數(shù)據(jù)庫的這些功能。視圖通常是一個網(wǎng)頁拗馒,但是在CodeIgniter中路星,一個視圖也可以是一個頁面片段,如頭部诱桂、頂部HTML代碼片段洋丐。它還可以是一個RSS頁面,或其他任一頁面挥等∮丫控制器相當(dāng)于一個指揮者,或者說是一個“中介”肝劲,它負(fù)責(zé)聯(lián)系視圖和模型迁客,以及其他任何處理HTTP請求和產(chǎn)生網(wǎng)頁的資源。
Zend Framework是完全基于PHP語言的針對Web應(yīng)用開發(fā)的框架辞槐,與眾多的其他PHP開發(fā)框架相比掷漱,Zend Framework是一個PHP“官方”的框架,它由Zend公司負(fù)責(zé)開發(fā)和維護(hù)榄檬。Zend?Framework同樣基于MVC模式卜范,Zend Framework采用了ORM(Object Relational Mapping,對象關(guān)系映射)思路丙号,這是一種為了解決面向?qū)ο缶幊膛c關(guān)系數(shù)據(jù)庫存在的互不匹配現(xiàn)象的技術(shù)先朦。簡單地說,這種技術(shù)將數(shù)據(jù)庫中的一個表映射為程序中的一個對象犬缨,表中的字段映射為對象的屬性喳魏,然后通過提供的方法完成對數(shù)據(jù)庫的操作。就這一點(diǎn)而言怀薛,Zend Framework很相似于現(xiàn)在流行的非PHP的開發(fā)框架Ruby on Rails刺彩。
ThinkPHP是一個快速、兼容而且簡單的輕量級國產(chǎn)PHP開發(fā)框架枝恋,誕生于2006年初创倔,原名FCS,2007年元旦正式更名為ThinkPHP焚碌,其遵循Apache2開源協(xié)議發(fā)布畦攘,從Struts結(jié)構(gòu)移植過來并做了改進(jìn)和完善,同時也借鑒了國外很多優(yōu)秀的框架和模式十电,使用面向?qū)ο蟮拈_發(fā)結(jié)構(gòu)和MVC模式知押,融合了Struts的思想和TagLib(標(biāo)簽庫)叹螟、RoR的ORM映射和ActiveRecord模式。
此外台盯,還有FleaPHP罢绽、CakePHP等很多優(yōu)秀的框架,此處就不一一列舉静盅,它們本質(zhì)上都是基于MVC的架構(gòu)良价,下面著重介紹一下在互聯(lián)網(wǎng)公司使用比較廣泛的CI框架。
[if !supportLists]3蒿叠、[endif]PHP+mysql
問題:設(shè)教務(wù)管理系統(tǒng)中有三個基本表:
學(xué)生信息表S(SNO, SNAME, AGE, SEX)明垢,其屬性分別表示學(xué)號、學(xué)生姓名市咽、年齡和性別袖外。
選課信息表SC(SNO, CNO, SCGRADE),其屬性分別表示學(xué)號魂务、課程號和成績。
課程信息表C(CNO, CNAME, CTEACHER)泌射,其屬性分別表示課程號粘姜、課程名稱和任課老師姓名。
1)把SC表中每門課程的平均成績插入另外一個已經(jīng)存在的表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)規(guī)定女同學(xué)選修何昊老師的課程成績都應(yīng)該在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表中把何昊老師的女學(xué)生選課記錄刪除拒秘。
DELETE FROM SC WHERE CNO=(SELECT CNO FROM C WHERE C.CTEACHER ='何昊') AND SNO IN (SELECT SNO FROM S WHERE SEX='女')
4)找出沒有選修過“何昊”老師講授課程的所有學(xué)生姓名号显。
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)的學(xué)生姓名及其平均成績。
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)列出既學(xué)過“1”號課程躺酒,又學(xué)過“2”號課程的所有學(xué)生姓名押蚤。
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”號同學(xué)該門課成績高的所有學(xué)生的學(xué)號。
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”號課成績高的所有學(xué)生的學(xué)號及其“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
UNION和UNION ALL有什么區(qū)別揽碘?
UNION在進(jìn)行表求并集后會去掉重復(fù)的元素,所以會對所產(chǎn)生的結(jié)果集進(jìn)行排序運(yùn)算园匹,刪除重復(fù)的記錄再返回結(jié)果雳刺。
而UNION ALL只是簡單地將兩個結(jié)果合并后就返回。因此裸违,如果返回的兩個結(jié)果集中有重復(fù)的數(shù)據(jù)掖桦,那么返回的結(jié)果集就會包含重復(fù)的數(shù)據(jù)。
從上面的對比可以看出供汛,在執(zhí)行查詢操作的時候枪汪,UNION ALL要比UNION快很多涌穆,所以,如果可以確認(rèn)合并的兩個結(jié)果集中不包含重復(fù)的數(shù)據(jù)料饥,那么最好使用UNION ALL蒲犬。例如,如下有兩個學(xué)生表Table1和Table2岸啡。
Table1
C1C2
11
22
33
Table2
C1C2
33
44
11
select * from Table1 union select * from Table2的查詢結(jié)果為
C1C2
11
22
33
44
select * from Table1 union all select * from Table2的查詢結(jié)果為
C1C2
11
22
33
33
44
11
3原叮、什么是數(shù)據(jù)庫三級封鎖協(xié)議?
眾所周知巡蘸,基本的封鎖類型有兩種:排它鎖(X鎖)和共享鎖(S鎖)奋隶。所謂X鎖是事務(wù)T對數(shù)據(jù)A加上X鎖時,只允許事務(wù)T讀取和修改數(shù)據(jù)A悦荒。所謂S鎖是事務(wù)T對數(shù)據(jù)A加上S鎖時唯欣,其他事務(wù)只能再對數(shù)據(jù)A加S鎖,而不能加X鎖搬味,直到T釋放A上的S鎖境氢。若事務(wù)T對數(shù)據(jù)對象A加了S鎖,則T就可以對A進(jìn)行讀取碰纬,但不能進(jìn)行更新(S鎖因此又稱為讀鎖)萍聊,在T釋放A上的S鎖以前,其他事務(wù)可以再對A加S鎖悦析,但不能加X鎖寿桨,從而可以讀取A,但不能更新A强戴。
在運(yùn)用X鎖和S鎖對數(shù)據(jù)對象加鎖時亭螟,還需要約定一些規(guī)則,例如骑歹,何時申請X鎖或S鎖预烙、持鎖時間、何時釋放等道媚,稱這些規(guī)則為封鎖協(xié)議(Locking Protocol)默伍。對封鎖方式規(guī)定不同的規(guī)則,就形成了各種不同的封鎖協(xié)議衰琐。一般使用三級封鎖協(xié)議也糊,也稱為三級加鎖協(xié)議。該協(xié)議是為了保證正確的調(diào)度事務(wù)的并發(fā)操作羡宙。三級加鎖協(xié)議是事務(wù)在對數(shù)據(jù)庫對象加鎖狸剃、解鎖時必須遵守的一種規(guī)則。下面分別介紹這三級封鎖協(xié)議狗热。
一級封鎖協(xié)議:事務(wù)T在修改數(shù)據(jù)R之前必須先對其加X鎖钞馁,直到事務(wù)結(jié)束才釋放虑省。事務(wù)結(jié)束包括正常結(jié)束(COMMIT)和非正常結(jié)束(ROLLBACK)。一級封鎖協(xié)議可以防止丟失修改僧凰,并保證事務(wù)T是可恢復(fù)的探颈。使用一級封鎖協(xié)議可以解決丟失修改問題。在一級封鎖協(xié)議中训措,如果僅僅是讀數(shù)據(jù)不對其進(jìn)行修改伪节,是不需要加鎖的,它不能保證可重復(fù)讀和不讀“臟”數(shù)據(jù)绩鸣。
二級封鎖協(xié)議:一級封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前必須先對其加S鎖怀大,讀完后方可釋放S鎖。二級封鎖協(xié)議除防止了丟失修改呀闻,還可以進(jìn)一步防止讀“臟”數(shù)據(jù)化借。但在二級封鎖協(xié)議中,由于讀完數(shù)據(jù)后即可釋放S鎖捡多,所以它不能保證可重復(fù)讀蓖康。
三級封鎖協(xié)議:一級封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前必須先對其加S鎖,直到事務(wù)結(jié)束才釋放垒手。三級封鎖協(xié)議除防止了丟失修改和不讀“臟”數(shù)據(jù)外钓瞭,還進(jìn)一步防止了不可重復(fù)讀。
4淫奔、以下關(guān)于mysql_pconnect的說法中,正確的是()堤结。
A.與數(shù)據(jù)庫進(jìn)行多連接 B.與mysql_connect功能相同
C.與@mysql_connect功能相同 D.與數(shù)據(jù)庫建立持久連接
參考答案:D唆迁。
分析:mysql_pconnect()函數(shù)打開一個到 MySQL 服務(wù)器的持久連接。
mysql_pconnect()和mysql_connect()非常相似竞穷,雖然只多了一個p唐责,但它們有兩個主要區(qū)別:當(dāng)連接的時候本函數(shù)將先嘗試尋找一個在同一個主機(jī)上用同樣的用戶名和密碼已經(jīng)打開的(持久)連接,如果找到瘾带,則返回此連接標(biāo)識而不打開新連接鼠哥。其次,當(dāng)腳本執(zhí)行完畢后到SQL服務(wù)器的連接不會被關(guān)閉看政,此連接將保持打開以備以后使用(mysql_close()不會關(guān)閉由mysql_pconnect()建立的連接)朴恳。所以,選項(xiàng)D正確允蚣。
【真題204】 PDO通過執(zhí)行SQL查詢與數(shù)據(jù)庫進(jìn)行交互于颖,可以分為多種不同的策略,使用哪一種方法取決于你要做什么操作嚷兔。如果向數(shù)據(jù)庫發(fā)送DML語句森渐,那么下面最合適的方式是()做入。
A.使用PDO對象中的exec()方法
B.使用PDO對象中的query()方法
C.使用PDO對象中的prepare()和PDOStatement對象中的execute()兩個方法結(jié)合
D.以上方式都可以
參考答案:A。
分析:PDO->exec()方法主要是針對沒有結(jié)果集合返回的操作同衣,例如INSERT竟块、UPDATE、DELETE等操作耐齐,它返回的結(jié)果是當(dāng)前操作影響的列數(shù)浪秘。所以,選項(xiàng)A正確蚪缀。
5秫逝、PHP的mysql系列函數(shù)中常用的遍歷數(shù)據(jù)的函數(shù)是()。
A.mysql_fetch_row询枚,mysql_fetch_assoc违帆,mysql_affetced_rows
B.mysql_fecth_row,mysql_fecth_assoc金蜀,mysql_affetced_rows
C.mysql_fetch_rows刷后,mysql_fetch_array,mysql_fetch_assoc
D.mysql_fecth_row渊抄,mysql_fecth_array尝胆,mysql_fecth_assoc
參考答案:D。
分析:最常用的mysql系列函數(shù)常用的遍歷數(shù)據(jù)函數(shù)有mysql_fetch_row护桦、mysql_fetch_?array和mysql_fetch_assoc等三個函數(shù)含衔,但不存在mysql_fetch_rows。
所以二庵,本題的答案為D贪染。
6、更改表字段名的標(biāo)準(zhǔn)語法為()催享。
A.a(chǎn)lter table 表名 ?add 字段字類型[first|after]
B.a(chǎn)lter table 表名 ?drop ?字段[first|after]
C.a(chǎn)lter table 表名 ?change 原名新名新類型[first|after]
D.a(chǎn)lter table 表名 ?modify ?原名字段類型[first|after]
參考答案:C杭隙。
分析:修改表字段名的語法:alter table表名change 原字段名新字段名類型;。
修改字段類型的語法:alter table表名modify 字段名類型;因妙。
增加一個字段:alter table表名add column 字段名類型 not null(或default null)痰憎;新增一個字段默認(rèn)不為空(默認(rèn)為空)。
刪除一個字段:alter table表名drop column 新字段名;攀涵。
更多PHP面試真題可以關(guān)注公眾號“琉憶編程庫”铣耘,或者訪問 www.shuaiqi100.com