PHP和MySQL愛考的10道題


PHPMySQL愛考的10道題

來自《PHP程序員面試筆試寶典》,涵蓋了近三年了各大型企業常考的PHP面試題,針對面試題提取出來各種面試知識也涵蓋在了本書。

 

一、如何進行數據庫優化?

數據庫優化的過程可以使用以下的方法進行:

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中有兩個存儲引擎:MyISAMInnoDB,每個引擎都有利有弊。

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

 

五、考慮如下數據表和查詢如何添加索引能提高查詢速度?    

CREATE TABLE MYTABLE (

  ID INT,

  NAME VARCHAR (100),

  ADDRESS1 VARCHAR (100),

  ADDRESS2 VARCHAR (100),

  ZIPCODE VARCHAR (10),

  CITY VARCHAR (50),

  PROVINCE VARCHAR (2)

)

SELECT ID, VARCHAR FROM MYTABLE WHERE ID BETWEEN 0 AND 100 ORDER BY NAME, ZIPCODE

 

A.給 ID 添加索引

B.給 NAME ADDRESS1 添加索引

C.給ID 添加索引,然后給 NAME ZIPCODE 分別添加索引

D.給ZIPCODE NAME 添加索引

參考答案:C

分析:給ID字段設置索引能提高 where 條件執行的效率,給 NAME ZIPCODE設索引則能使排序更快。

 

六、 如何高效操作MySQL

MySQL對於PHP甚至是所有開發者都是非常基礎和重要的模塊,對於熟悉的LAMP體系架構,我們需要構建穩定可靠的系統,數據庫環境是必不可少和關鍵的地方。在使用MySQL過程中,有以下建議:

1使用InnoDB數據庫引擎。MySQL常用的有MyISAMInnoDB兩種,MyISAM不支持外鍵約束或者事務處理。當插入或更新一條記錄時,整個數據表都被鎖定了,隨着使用量的增加,性能會非常差。

2使用MySQLi面向對象的數據庫操作方法。PHP5支持了面向對象的訪問數據庫方法。具體的優點前面已經講過,此處不再贅述。

3對於用戶輸入進行驗證用戶輸入的內容是一個大的變量之一,防止SQL注入或黑客登等安全隱患。

4MySQL未使用utf-8字符集。utf-8字符集解決了很多國際化的問題,需要盡量使用此字符集,防止字符的問題出現。

5通過SQL來替代PHP邏輯處理通常來說,執行一個查詢比在結果中使用PHP語言來迭代處理更有效率。所以,需要盡量通過SQL來替代PHP邏輯處理,提高效率。

6優化數據庫查詢幾乎絕大部分PHP性能問題都是數據庫引起的,經常出現的慢查詢等SQL查詢問題可能會讓系統崩潰。需要對數據庫進行優化查詢。

7要正確使用數據類型

MySQL提供了諸如numeric、stringdate的數據類型。如果想存儲一個時間,那么使用date或者datetime類型。如果這個時候用integer或者string類型,那么將會使得SQL查詢非常復雜。

很多人傾向於擅自自定義一些數據的格式,例如,使用string來存儲序列化的PHP對象。這樣的話數據庫管理起來可能會變得簡單些,但會使得MySQL成為一個糟糕的數據存儲而且之后很可能會引起故障。

8不要在查詢中使*”。這會返回表中所有數據,這是懶惰的表現,會在降低效率和出錯率上都大大提高。

9合理使用索引技術不使用或過度使用索引都會造成性能降低。如果在每個字段都加了索引,那么當執行修改操作時,索引都需要重新生成,會對性能影響較大。不使用索引,同樣會造成全表查詢,低效率。使用索引一般性原則是這樣的:select語句中的任何一個where子句表示的字段都應該使用索引。

10記得備份數據庫必須進行備份,常見的有主從主主數據庫等系統架構形式。

 

七、【真題222以下說法正確的是    )。

A.使用索引能加快插入數據的速度

B.良好的索引策略有助於防止跨站攻擊

C.應當根據數據庫的實際應用理設計索引

D.刪除一條記錄將導致整個表的索引被破壞

參考答案:C

分析:索引的作用主要是幫助數據庫快速查找到對應的數據,並不能加快插入數據的速度,所以,選項A錯誤。

索引不能夠幫助防止跨站攻擊,所以,選項B錯誤。

創建合理的索引需要分析數據庫的實際用途並找出它的弱點。優化腳本中的冗余查詢同樣也能提高數據庫效率。索引是占用物理空間的,所以在實際的應用中是要合理設計使用索引的。所以,選項C正確。

索引是一種表結構,刪除一條數據也不會影響到整個表的索引,並且索引不一定是數字,也可以是字符串。所以,選項D錯誤。

 

八、如何對MySQL的系統內核優化?

大多數MySQL都部署在Linux系統上,所以,操作系統的一些參數也會影響到MySQL性能,以下參數的設置可以對Linux內核進行適當優化。

l  net.ipv4.tcp_fin_timeout = 30  #TIME_WAIT超時時間,默認是60s

l  net.ipv4.tcp_tw_reuse = 1  #1表示開啟復用,允許TIME_WAIT socket重新用於新的TCP連接,0表示關閉

l  net.ipv4.tcp_tw_recycle = 1  #1表示開啟TIME_WAIT socket快速回收,0表示關閉

l  net.ipv4.tcp_max_tw_buckets = 4096  #系統保持TIME_WAIT socket最大數量,如果超出這個數,系統將隨機清除一些TIME_WAIT並打印警告信息

l  net.ipv4.tcp_max_syn_backlog = 4096  #進入SYN隊列最大長度,加大隊列長度可容納更多的等待連接

 

Linux系統中,如果進程打開的文件句柄數量超過系統默認值1024,就會提示“too  many files open”信息,所以,要調整打開文件句柄限制。

# vi /etc/security/limits.conf  #加入以下配置,*代表所有用戶,也可以指定用戶,重啟系統生效

* soft nofile 65535

* hard nofile 65535

# ulimit -SHn 65535   #立刻生效

 

九、什么是數據庫權限?

關於MySQL的權限簡單的理解就是MySQL允許用戶做權利以內的事情,不可以越界。例如只允許一個用戶執行SELECT操作,那么就不能執行UPDATE操作只允許一個用戶從某台機器上連接MySQL,那么就不能從除那台機器以外的其他機器連接MySQL

那么MySQL的權限是如何實現的呢?這就要說到MySQL的兩階段的驗證,下面詳細來介紹第一階段:服務器首先會檢查是否允許連接。因為創建用戶的時候會加上主機限制,可以限制成本地、某個IP、某個IP段以及任何地方等,只允許你從配置的指定地方登錄。后面在實戰的時候會詳細介紹關於主機的限制。第二階段:如果能連接,那么 MySQL 會檢查發出的每個請求,看是否有足夠的權限實施它。例如要更新某個表或者查詢某個表,MySQL會檢查對某個表或者某個列是否有權限。再例如,要運行某個存儲過程,MySQL會檢查對存儲過程是否有執行權限等。

MySQL權限控制原則:

1)只授予能滿足需要的最小權限,防止用戶干壞事。例如用戶只是需要查詢,那就只給SELECT權限就可以了,不要給用戶賦予UPDATE、INSERT或者DELETE權限。

2)創建用戶的時候限制用戶的登錄主機,一般是限制成指定IP或者內網IP段。

3)初始化數據庫的時候刪除沒有密碼的用戶。安裝完數據庫的時候會自動創建一些用戶,這些用戶默認沒有密碼。

4)為每個用戶設置滿足密碼復雜度要求的密碼。

5)定期清理不需要的用戶。回收權限或者刪除用戶。

示例1:創建一個只允許從本地登錄的超級用戶feihong,並允許將權限賦予別的用戶,密碼為123

GRANT ALL PRIVILEGES ON *.* TO feihong@'localhost' IDENTIFIED BY '123' WITH GRANT OPTION;

 

GRANT命令說明:

ALL PRIVILEGES 是表示所有權限,也可以使用SELECTUPDATE等權限。

ON 用來指定權限針對哪些庫和表。

*.* 中前面的*號用來指定數據庫名,后面的*號用來指定表名。

TO 表示將權限賦予某個用戶。

feihong@'localhost' 表示feihong用戶,@后面接限制的主機,可以是IPIP段、域名以及%%表示任何地方。注意:這里%有的版本不包括本地,以前碰到過給某個用戶設置了%允許任何地方登錄,但是在本地登錄不了,這個和版本有關系,遇到這個問題再加一個localhost的用戶就可以了。

IDENTIFIED BY 指定用戶的登錄密碼。

WITH GRANT OPTION 這個選項表示該用戶可以將自己擁有的權限授權給別人。注意:經常有人在創建操作用戶的時候不指定WITH GRANT OPTION選項導致后來該用戶不能使用GRANT命令創建用戶或者給其他用戶授權。

備注:可以使用GRANT重復給用戶添加權限,權限疊加,例如先給用戶添加了一個SELECT權限,然后又給用戶添加了一個INSERT權限,那么該用戶就同時擁有了SELECTINSERT權限。

示例2:創建一個網站用戶程序用戶)。

創建一個一般的程序用戶,這個用戶可能只需要SELECT、INSERT、UPDATE、DELETE、CREATE TEMPORARY TABLES等權限,如果有存儲過程還需要加上EXECUTE權限,那么一般是指定內網網段192.168.100網段。

GRANT USAGE,SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ,CREATE TEMPORARY TABLES,EXECUTE ON 'test'.* TO webuser@'192.168.100.%' IDENTIFIED BY 123';

 

示例3:創建一個普通用戶僅有查詢權限)。

GRANT USAGE,SELECT ON 'test'.* TO public@'192.168.100.%' IDENTIFIED BY  'test';

 

示例4:查看權限

使用如下命令可以方便查看到某個用戶的權限:

SHOW GRANTS FOR 'webuser'@'192.168.100.%';

 

示例5:刪除用戶

注意刪除用戶不要使用DELETE直接刪除,因為使用DELETE刪除后用戶的權限並未刪除,新建同名用戶后又會繼承以前的權限。正確的做法是使用DROP USER命令刪除用戶,例如要刪除'webuser'@'192.168.100.%'用戶采用如下命令:

DROP USER 'webuser'@'192.168.100.%';

 

示例6:回收權限

將前面創建的webuser用戶的DELETE權限回收,使用如下命令:

REVOKE DELETE ON test.* FROM 'webuser'@'192.168.100.%';

 

 

 

十、【真題220MySQL數據庫中的字段類型varcharchar的主要區別是什么?種字段的查找效率要高,為什么?

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

 

 

購買鏈接:京東購買

以上就是PHP+mysql面試中經常愛考和愛問的幾個筆試面試問題。

 

題目來自《PHP程序員面試筆試寶典》,里面涵蓋了近三年了各大型企業常考的PHP面試題,針對面試題提取出來各種面試知識也涵蓋在了本書。

 

更多PHP面試筆試真題可以瀏覽:www.shuaiqi100.com  

 

更多有趣有料的PHP面試筆試資料可以關注:“琉憶編程庫”

或者瀏覽:www.shuaiqi100.com 獲取。

PHP程序員面試筆試寶典下載:https://pan.baidu.com/s/1-ES2ZI3z5Lhv-zTKFmJDSQ


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM