這篇文章帶給大家的內容是關於2018PHP面試真題最新總結(附答案),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
相關推薦:《2019年PHP面試題大匯總(收藏)》
一、PHP常考基礎
#1、PHP與ASP、JSP有什麼差別?
ASP全名Active Server Pages,是一個基於Windows平台的Web伺服器端的開發環境,利用它可以產生和運行動態的、交互的、高性能的Web服務應用程序,它只能在微軟平台使用,移植性不好。 ASP採用腳本語言VB Script、JScript(JavaScript)作為自己的開發語言。國內早期大部分網站都用它來開發。但因微軟全面轉向,ASP.NET放棄了ASP的Web開發模式,所以現在已經被淘汰使用。
PHP是一種跨平台的伺服器端的嵌入式腳本語言。它大量借用C、Java和Perl語言的語法,並耦合PHP自己的特性,使Web開發者能夠快速地寫出動態生成頁面。它可嵌入HTML中,非常適合Web開發,而且它支援目前絕大多數資料庫。除此之外,PHP是完全免費的,不用花錢,開發人員就可以從PHP官方網站(http://www.php.net)自由下載。而且開發人員可以不受限制地取得原始碼,甚至從中加入自己所需的特色,開發效率高,成本低。
JSP是Sun公司推出的網路程式語言,跨平台運行,安全性高,運行效率也高。它的開發語言主要基於Java。
ASP、JSP、PHP三者都提供在HTML 程式碼中混合某種程式碼、由語言引擎解釋執行,但JSP程式碼被編譯成Servlet並由Java虛擬機解釋執行,這種編譯作業僅在對JSP頁面的第一次請求時發生。在ASP、PHP、JSP環境下,HTML程式碼主要負責描述資訊的顯示樣式,而程式碼則用來描述處理邏輯。普通的HTML頁面只依賴Web伺服器,而ASP、PHP、JSP頁面則需要附加的語言引擎分析和執行程式碼。程式碼的執行結果被重新嵌入HTML程式碼中,然後一起傳送給瀏覽器。 ASP、PHP、JSP三者都是面向 Web 伺服器的技術,客戶端瀏覽器不需要任何附加的軟體支援。
2、在PHP中,單引號和雙引號所包圍的字串的差異是( )。
A.單引號解析其中rt等轉義字符,而雙引號不解析
B.雙引號速度快,單引號速度慢
C.單引號速度快,雙引號速度慢
#D.雙引號解析其中以$開頭的變量,而單引號不解析
參考答案:D。
分析:雙引號是可以解析$符開頭的變數和轉義字元的,而單引號不解析也不轉義字元。所以,選項A錯誤,選項D正確。
對於選項B和選項C,由於題目中明確說了引號內包含的是字串,因此不需要對變數進行解析,在這種情況下雙引號和單引號的效率是相同的。選項B和選項C都是錯誤的。
3、物件導向與過程導向有什麼差別?
物件導向是當今軟體開發方法的主流方法之一,它是把資料及對資料的操作方法放在一起,作為一個相互依存的整體,即物件。對同類物件抽像出其共通性,即類,類別中的大多數數據,只能被本類的方法處理。類別透過一個簡單的外部介面與外界發生關係,物件與物件之間透過訊息進行通訊。程序流程由使用者在使用中決定。例如,站在抽象的角度,人類具有身高、體重、年齡、血型等一些特稱,人類會勞動、會直立行走、會吃飯、會用自己的頭腦去創造工具等這些方法,人類僅僅只是一個抽象的概念,它是不存在的實體,但是所有具備人類這個群體的屬性與方法的對像都稱為人,這個對像人是實際存在的實體,每個人都是人這個群體的一個對象。
而以過程為中心是一種以事件為中心的開發方法,就是自頂向下順序執行,逐步求精,其程式結構是依功能劃分為若干個基本模組,這些模組形成一個樹狀結構,各模組之間的關係也比較簡單,在功能上相對獨立,每一模組內部一般都是由順序、選擇和循環三種基本結構組成,其模組化實現的具體方法是使用子程序,而程序流程在寫程式時就已經決定。例如五子棋,過程導向的設計想法就是先分析問題的步驟:第一步,開始遊戲;第二步,黑子先走;第三步,畫畫面;第四步,判斷輸贏;第五步,輪到白子;第六步,繪製畫面;第七步,判斷輸贏;第八步,回到步驟二;第九步,輸出最後結果。把上面每個步驟用分別的函數來實現,就是一個流程導向的開發方法。
具體而言,二者主要有以下幾個面向的差異。
1)出發點不同。物件導向是用符合常規思考方式來處理客觀世界的問題,強調把問題域的要領直接映射到物件及物件之間的介面。而以過程為導向方法則不然,它強調的是過程的抽象化與模組化,它是以過程為中心構造或處理客觀世界問題的。
2)層次邏輯關係不同。物件導向方法則是用電腦邏輯來模擬客觀世界中的物理存在,以物件的集合類別作為處理問題的基本單位,盡可能地使電腦世界向客觀世界靠攏,以使問題的處理更清晰直接,面向物件方法是用類別的層次結構來體現類別之間的繼承和發展。過程導向方法處理問題的基本單位是能清晰準確地表達過程的模組,用模組的層次結構概括模組或模組間的關係與功能,把客觀世界的問題抽象成電腦可以處理的過程。
3)資料處理方式與控製程序方式不同。物件導向方法將資料與對應的程式碼封裝成一個整體,原則上其他物件不能直接修改其數據,即物件的修改只能由自身的成員函數完成,控製程式方式上是透過「事件驅動」來啟動和運行程式。而面向過程方法是直接透過程式處理數據,處理完畢後即可顯示處理結果,在控製程式方式上是依照設計調用或返回程序,不能自由導航,各模組之間存在著控制與被控制、調用與被調用。
4)分析設計與編碼轉換方式不同。物件導向方法貫穿軟體生命週期的分析、設計及編碼之間是一種平滑過程,從分析到設計再到編碼是採用一致性的模型表示,即實現的是一種無縫連接。而以過程為導向方法強調分析、設計與編碼之間依規則轉換,貫穿軟體生命週期的分析、設計與編碼之間,實現的是一種有縫的連結。
4、在PHP中,自訂一個類別的方式是( )。
A.
B.
C.
D.
參考答案:B。
分析:定義一個類別是使用class關鍵字加類別名稱來定義的,定義格式為:class 類別名稱{}。實例化一個類別的格式為:$object=new 類別名稱();。
【真題11】 取得實例化物件所屬類別名字的函數是( )。
A. get_class() B. get_object_vars()
C. get_class_methods() D. get_classname()
參考答案:A。
分析:對於選項A,get_class()函數用來傳回一個物件的類別的名稱。所以,選項A正確。
對於選項B,get_object_vars()函數用來得到給定物件的屬性。所以,選項B錯誤。
對於選項C,get_class_methods()函數用來取得類別方法的名字。所以,選項C錯誤。
對於選項D,PHP中沒有此方法。所以,選項D錯誤。
5.以下有關PHP物件導向的敘述中,不正確的是( )。
A.要實作一個接口,使用 implements操作符,類別中必須實作介面中定義的所有方法,否則會報一個致命錯誤
B.類別名稱可以是任何非 PHP保留字的合法標籤,漢字也可以當作PHP的類別名稱
C.如果PHP的子類別中定義了建構函數,則建立子類別的物件時,會隱式地呼叫其父類別的建構子
D.序列化一個物件將會保存物件的所有變量,但是不會保存物件的方法,只會保存類別的名字
參考答案:C。
分析:子類別定義的建構子會覆寫父類別的建構函數,如果要子類別的建構子類別執行,同時也執行父類別的建構函數,那麼必須明確地使用parent::__construct();去調用。所以,選項C錯誤。
6.在下面關於PHP抽象類別的描述中,錯誤的是( )。
A. PHP中抽象類別使用abstract關鍵字定義
B.沒有方法體的方法叫抽象方法,包含抽象方法的類別必須是抽象類別
C.抽象類別中必須有抽象方法,否則不叫抽象類別
D.抽象類別不能實例化,也就是不可以new成物件
參考答案:C。
分析:抽象類別可以是個空類,也就是不一定需要有抽象方法。但抽象方法只能存在抽象類別中。所以,選項C錯誤。
7、什麼是多型?
多態是物件導向程式設計中程式碼重用的一個重要機制,它表示當同一個操作作用在不同的物件的時候,會有不同的語義,從而產生不同的結果。例如,同樣是「 」操作,3 4用來實現整數相加,而「3」 「4」卻實現了字串的連接。一般而言,多態有兩種實作方式:覆蓋和重載。
8、 include與require有什麼不同?
require和include有著相似的功能:將指定檔案中的所有程式碼/文字/標記複製到使用require或include語句的檔案中。通常被用在資料、檔案或程式碼需要被分享的場景。透過把需要被分享的程式碼或資料放到一個單獨PHP檔案中,在需要使用的檔案中透過require或include來引用。 require()和include()也不是真正的函數,因此,require()和include()語句也可以不加圓括號而直接加參數。
9、下列程式碼的輸出是( )。
<?php define("x","5"); $x=x+10; echo x; ?>
A. Error B. 5 C. 10 D. 15
參考答案:B。
分析:在PHP中,define函數用來定義一個常數,而常數的值在設定以後,是無法改變的。本題中,x的值始終為5。所以,選項B正確。
10、如何對變數進行引用?
可以在變數的前面加&符號對變數進行引用,變數的引用相當於給變數取了一個別名,透過不同的名字存取同一個變數內容,所以改變其中一個變數的值,另一個變數也會跟著改變。
【真題54】 有下列程式碼:
<?php $a="hello"; $b= &$a; unset($b); $b="world"; echo $a; ?>
程式的運作結果為( )
A. hello B. world C. NULL D. unset
參考答案:A。
分析:這個程式碼的執行過程如下圖所示。
1)首先执行$b= &$a后,a和b引用同一个字符串变量“hello”。
2)接着执行unset($b),这个函数可以断开这个引用关系。此时由于a仍然指向字符串“hello”,也就是说,这个字符串仍然被a使用,因此这个字符串不会被回收。
3)接着执行$b="world",此时,b指向一个新的字符串“world”,这并不会影响a的值。因此输出结果为hello。
2、PHP常考进阶
11、请写一个函数验证电子邮件的格式是否正确。
参考答案:
function checkEmail($email) { $pregEmail= "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i"; return preg_match($pregEmail,$email); }
分析:首尾两个斜杠/是正则表达式的限定符,这是Perl正则的标准,而PHP与Perl有相同的正则的规范。两个斜杠之间表示的是正则内容,后面的i表示忽略大小写。
这个正则表达式表示的含义如下:
1)必须以([0-9A-Za-z\-_\.]+)开头,也就是说,邮件地址以多个字母、数组、“-”或“.”开头。
2)紧接着是字符“@”。
3)然后接着是多个字母或数字的字符串,接着是一个字符“.”,接着是两个或三个字母;然后接下来一部分可有可无的:一个“.”后面跟着两个字母。
4)邮件的结束符是满足3)的字符串。
12、以下可以匹配中国居民身份证号码的正则表达式是( )。
A.d{15} B.d{18}
C.d D.(^d{15}$)|(^\d{18}$)|(^d{17}(d|X|x)$)
参考答案:D。
分析:d表示0~9任意数字。
13、【真题96】 一个函数的参数不能是对变量的引用,除非在php.ini中把( )设为on。
参考答案:allow_call_time_pass_reference。
分析:在PHP函数调用的时候,基本数据类型默认会使用值传递,而不是引用传递。allow_call_time_pass_reference 选项的作用为是否启用在函数调用时强制参数被按照引用传递。如果把allow_call_time_pass_reference 配置为on,那么在函数调用的时候会默认使用引用传值。但是不推荐使用这种方法,原因是该方法在未来的版本中很可能不再支持。如果想使用引用传递,那么推荐在函数调用的时候显式地使用&进行引用传递。
14、文件读操作
读取文件前,通常会判断文件能否读取,例如,是否有读权限,可以使用is_readable函数;示例代码如下:
<?php $file = "test.txt"; if(is_readable($file) == false) { echo "can not read\n"; } else{ echo "can read \n"; } ?>
当然也需要判断文件是否存在,可以使用file_exists()函数。示例代码如下:
<?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参数是可选项,如果忽略,则将继续从流中读取数据直到行结束。指定最大行的长度在利用资源上更为有效。此外,还有fread、file_get_contents等读取文件的方法,此处不再赘述。
15、什么是异常处理与错误处理?
当运行的程序发生异常被抛出时,程序不会继续执行异常处后面的代码,PHP 会尝试查找匹配的“catch”代码块。如果异常没有被捕获,那么将会发生严重的错误,程序会终止或者不受控制地执行。示例代码如下:
<?php function GetNum($num) { if($num > 10) { throw new Exception("Exception ocur"); } return true; } GetNum(100); ?>
程序的运行结果为
Uncaught exception 'Exception' with message 'Exception ocur'
从这个例子可以看出,如果不对异常进行处理,那么当程序有异常抛出的时候就会结束执行。而对于对象方法的异常处理,还有另外一种处理方法,下面介绍在PHP中当调用一些不存在的对象方法时的异常处理,从而保证程序正常运行。这主要是通过__call方法来实现的。
方法声明为__call($funname,$arr_value),当被调用方法不存在的时候会默认调用这个方法。
示例代码如下:
class My { function __call($n,$v) { echo "错误的方法名:".$n; echo "错误的参数:".$v; } }
16、什么是内存管理?
内存管理主要是指程序运行时对计算机内存资源的分配、使用和释放等技术,内存管理的目标是高效、快速地分配内存同时及时地释放和回收内存资源。内存管理主要包括是否有足够的内存供程序使用,从内存池中获取可用内存,使用后及时销毁并重新分配给其他程序使用。
在PHP开发过程中,如果遇到大数组等操作,那么可能会造成内存溢出等问题。一些常见的处理方法如下:
1)通过ini_set('memory_limit','64M')方法重置php可以使用的内存大小,一般在远程主机上是不能修改php.ini文件的,只能通过程序设置。注:在safe_mode(安全模式)下,ini_set会失效。
2)另一方面可以对数组进行分批处理,及时销毁无用的变量,尽量减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。同时对于数据库、文件操作完要及时关闭,对象使用完要及时调用析构函数等。
3)及时使用unset()函数释放变量,使用时需要注意以下两点:
① unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。
② 只有当指向该变量的所有变量都销毁后,才能成功释放内存。
17、与MySQL一样,Redis在使用过程中,也会碰到很多的问题,适当的技巧和优化将大大提高Redis的使用性能,提高服务的质量。现将常见的一些问题总结如下:
1.停止使用keys *操作
keys*操作执行速度将会变慢。因为keys命令的时间复杂度是O(n),其中n是要返回的keys的个数,由此可见这个命令的复杂度就取决于数据量的大小了。当数据量比较大时,在这个操作执行期间,其他任何命令在实例中都无法执行,严重影响了性能。
可以使用scan命令来代替,scan命令通过增量迭代的方式来扫描数据库。
2.定位Redis速度降低的原因
使用INFO commandstats命令来查看所有命令的统计情况,如命令执行了多少次,执行命令所耗费的毫秒数等信息。
18、Memcache的特征和特性
Memcache的特征如下:
1)协议简单。
2)基于libevent的事件处理。
3)内置内存存储方式。
4)Memcached不互相通信的分布式。
Memcache的特性如下:
(1)单个item 最大的数据为1MB。
(2)单进程最大的使用内存为2GB,需要更多内存时可开多个端口。
(3)Memcached是多线程,非阻塞io复用的网络模型,Redis是单线程。
(4)键长最大为250字节。
19、下面可以用于服务器共享session的方式有( )。
A.利用NFS共享Session数据 B.基于数据库的Session共享
C.基于Cookie的Session共享 D.使用类似BIG-IP的负载设备来实现资源共享
参考答案:A、B、C、D。
分析:共享Session的方式主要有以下几种:
1)基于NFS的Session共享。NFS(Network File System)最早由Sun公司为解决Unix网络主机间的目录共享而研发。仅需将共享目录服务器mount到其他服务器的本地session目录即可。
2)基于数据库的Session共享。
3)基于Cookie的Session共享。原理是将全站用户的Session信息加密、序列化后以Cookie的方式,统一种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现用户的Cookie化Session 在多服务间的共享访问。
4)基于缓存(Memcache)的Session共享。Memcache是一款基于Libevent多路异步I/O技术的内存共享系统,简单的key + value数据存储模式使得代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势,目前能达到2000/s平均查询,并且服务器CPU消耗依然不到10%。
所以,本题的答案为A、B、C、D。
20、如何預防各類安全性問題?
常見的安全性問題主要包括以下幾個面向:
1)SQL注入攻擊。所謂SQL注入式攻擊,就是攻擊者把SQL指令插入Web表單的網域或頁面請求的查詢字串中,欺騙伺服器執行惡意的SQL指令。在某些表單中,使用者輸入的內容直接用來建構動態SQL指令,或作為預存程序的輸入參數,這類表單特別容易受到SQL注入式攻擊。例如,對於一個站點http://www.shuaiqi100.com/New...,id是查詢參數,透過id獲取顯示某條信息,在JSP程式中,用SQL語句來讀取該條新聞:「select * from news where id =” id,正常執行的話,只需要將id替換為參數2即可,沒有任何問題,但是當非法用戶將id的參數變為id=2;drop database news時,則執行的SQL語句除了讀取對應的新聞資訊外,還會執行drop database news訊息,可是後面這條語句是非法的。
由於SQL注入攻擊利用的是合法的SQL語句,使得這種攻擊無法被防火牆檢查,而且由於對任何基於SQL語言標準的資料庫都適用,所以危害特別大。儘管如此,目前防止SQL注入攻擊的方法也非常多,具體而言,有以下一些方法:使用預處理語句和參數分別傳送到資料庫伺服器進行解析,參數將會被當作普通字元處理。使用這種方式後,攻擊者無法注入惡意的SQL。那麼如何防止SQL注入攻擊呢,以下介紹常用的一些方法:
① 預處理語句和參數分別傳送到資料庫伺服器進行解析。
② 使用函數addslashes()轉義提交的內容。
③ PHP設定檔中開啟magic_quotes_gpc=on;將自動轉換使用者查詢的SQL語句,對防止SQL注入有重大作用。
④ 在PHP設定檔中,將register_globals設定為off,關閉全域變數註冊。
⑤ 在PHP設定檔中,開啟安全模式safe_mode=on;。
⑥ SQL語句的書寫盡量不要省略小引號與單引號。
⑦ 提高資料庫表格和欄位的命名技巧,對一些重要的欄位依照程式的特性命名,取不易被猜到的名字。
⑧ 控制錯誤訊息,關閉錯誤訊息的輸出,將錯誤訊息寫到日誌檔案中,不要在網站暴露錯誤訊息。
2)資料庫操作安全性問題。例如,未對使用者的權限進行限制,update、delete、insert等誤操作造成系統安全性問題。
解決方法為給不同的使用者授不同的權限,這樣能夠保證只有有權限的使用者才能進行特定的操作。
3)沒有驗證使用者http請求方式。惡意的使用者可以模擬http對網站進行請求產生惡意攻擊,為了防止這種攻擊需要檢查使用者的http請求中的存取來源是否可信,對http頭中的referer進行過濾,只允許本域網站存取。
4)沒有驗證表單來源的唯一性,不能識別是合法的表單提交還是駭客偽造的表單提交。
為了防止駭客偽造表單提交,可以使用一次性令牌Token。透過伺服器端以某種策略產生隨機字串作為令牌保存在Session裡,然後發出請求的頁面時,把該令牌以隱藏域一類的形式,與其他資訊一併發出,在接收頁面中把接收到的資訊中的令牌與Session中的令牌比較,一致才處理請求,否則拒絕請求,以此保證表單的來源唯一,防止駭客偽造的表單提交。
21、PHP的开发框架有哪些?
CodeIgniter是一个轻量级的PHP开发框架,具有快速开发、灵活性高等优点,它特别适合互联网公司的快速迭代场景,因此很受欢迎,据说腾讯、去哪儿网等应用场景都使用了这个框架。CodeIgniter具有动态实例化、松耦合、组件单一性等很多优点。动态实例化是指组件的导入和函数在执行时才会生效。松耦合是指系统模块之间的关联依赖很少,确保系统具有很好的重用性和灵活性。框架内的类和功能都是高度自治的,具有非常好的组件单一性。
在CodeIgniter中,模型代表数据结构,包含取出、插入、更新数据库的这些功能。视图通常是一个网页,但是在CodeIgniter中,一个视图也可以是一个页面片段,如头部、顶部HTML代码片段。它还可以是一个RSS页面,或其他任一页面。控制器相当于一个指挥者,或者说是一个“中介”,它负责联系视图和模型,以及其他任何处理HTTP请求和产生网页的资源。
Zend Framework是完全基于PHP语言的针对Web应用开发的框架,与众多的其他PHP开发框架相比,Zend Framework是一个PHP“官方”的框架,它由Zend公司负责开发和维护。Zend Framework同样基于MVC模式,Zend Framework采用了ORM(Object Relational Mapping,对象关系映射)思路,这是一种为了解决面向对象编程与关系数据库存在的互不匹配现象的技术。简单地说,这种技术将数据库中的一个表映射为程序中的一个对象,表中的字段映射为对象的属性,然后通过提供的方法完成对数据库的操作。就这一点而言,Zend Framework很相似于现在流行的非PHP的开发框架Ruby on Rails。
ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,其遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。
此外,还有FleaPHP、CakePHP等很多优秀的框架,此处就不一一列举,它们本质上都是基于MVC的架构,下面着重介绍一下在互联网公司使用比较广泛的CI框架。
3、PHP+mysql
1、问题:设教务管理系统中有三个基本表:
学生信息表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
2、UNION和UNION ALL有什么区别?
UNION在进行表求并集后会去掉重复的元素,所以会对所产生的结果集进行排序运算,删除重复的记录再返回结果。
而UNION ALL只是简单地将两个结果合并后就返回。因此,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据。
从上面的对比可以看出,在执行查询操作的时候,UNION ALL要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据,那么最好使用UNION ALL。例如,如下有两个学生表Table1和Table2。
Table1
C1 C2
1 1
2 2
3 3
Table2
C1 C2
3 3
4 4
1 1
select from Table1 union select from Table2 的查询结果为
C1 C2
1 1
2 2
3 3
4 4
select from Table1 union all select from Table2 的查询结果为
C1 C2
1 1
2 2
3 3
3 3
4 4
1 1
3、什么是数据库三级封锁协议?
众所周知,基本的封锁类型有两种:排它锁(X锁)和共享锁(S锁)。所谓X锁是事务T对数据A加上X锁时,只允许事务T读取和修改数据A。所谓S锁是事务T对数据A加上S锁时,其他事务只能再对数据A加S锁,而不能加X锁,直到T释放A上的S锁。若事务T对数据对象A加了S锁,则T就可以对A进行读取,但不能进行更新(S锁因此又称为读锁),在T释放A上的S锁以前,其他事务可以再对A加S锁,但不能加X锁,从而可以读取A,但不能更新A。
在运用X锁和S锁对数据对象加锁时,还需要约定一些规则,例如,何时申请X锁或S锁、持锁时间、何时释放等,称这些规则为封锁协议(Locking Protocol)。对封锁方式规定不同的规则,就形成了各种不同的封锁协议。一般使用三级封锁协议,也称为三级加锁协议。该协议是为了保证正确的调度事务的并发操作。三级加锁协议是事务在对数据库对象加锁、解锁时必须遵守的一种规则。下面分别介绍这三级封锁协议。
一级封锁协议:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。一级封锁协议可以防止丢失修改,并保证事务T是可恢复的。使用一级封锁协议可以解决丢失修改问题。在一级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,它不能保证可重复读和不读“脏”数据。
二级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后方可释放S锁。二级封锁协议除防止了丢失修改,还可以进一步防止读“脏”数据。但在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读。
三级封锁协议:一级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。三级封锁协议除防止了丢失修改和不读“脏”数据外,还进一步防止了不可重复读。
4、以下关于mysql_pconnect的说法中,正确的是( )。
A.与数据库进行多连接 B.与mysql_connect功能相同
C.与@mysql_connect功能相同 D.与数据库建立持久连接
参考答案:D。
分析:mysql_pconnect()函数打开一个到 MySQL 服务器的持久连接。
mysql_pconnect()和mysql_connect()非常相似,虽然只多了一个p,但它们有两个主要区别:当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接标识而不打开新连接。其次,当脚本执行完毕后到SQL服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close()不会关闭由mysql_pconnect()建立的连接)。所以,选项D正确。
【真題204】 PDO透過執行SQL查詢與資料庫交互,可以分成多種不同的策略,使用哪一種方法取決於你要做什麼操作。如果傳送DML語句,那麼下面最適合的方式是( )。
A.使用PDO物件中的exec()方法
B.使用PDO物件中的query()方法
C.使用PDO物件中的prepare()和PDOStatement物件中的execute()兩個方法結合
D.以上方式都可以
參考答案:A。
分析:PDO->exec()方法主要是針對沒有結果集合回傳的操作,例如INSERT、UPDATE、DELETE 等操作,它傳回的結果是目前操作影響的列數。所以,選項A正確。
5、PHP的mysql系列函數中常用的遍歷資料的函數是( )。
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系列函數常用的遍歷資料函數有mysql_fetch_row、mysql_fetch_ array和mysql_fetch_assoc等三個函數,但不存在mysql_fetch_rows。
所以,本題的答案為D。
6、更改表格欄位名稱的標準語法為( )。
A. alter table 表名 add 字段字型別[first|after]
B. alter table 表名 drop 字段[first|after]
C. alter table 表名 change 原名新名新型別[first|after]
D. alter table 表名 modify 原名字段類型[first|after]
參考答案:C。
分析:修改表格字段名的語法:alter table 表名change 原始字段名新字段名類型;。
修改欄位類型的語法:alter table 表名modify 欄位名稱類型;。
增加一個欄位:alter table 表名add column 欄位名稱類型 not null(或default null);新增一個欄位預設不為空(預設為空)。
刪除一個欄位:alter table 表名drop column 新欄位名稱;。
以上是2018PHP面試真題最新總結(附答案)的詳細內容。更多資訊請關注PHP中文網其他相關文章!