1. 程式人生 > >PHP常用知識點彙總

PHP常用知識點彙總

常見面試題

1、酒店預訂怎麼實現?怎麼設計表

  你好,我大概的說下我們的業務流程,我們的業務流程是:使用者在網站瀏覽酒店資訊,可以根據地區檢索出該地區的酒店資訊。列表展示酒店的資訊由:酒店的名稱,酒店圖片,酒店位置,評論人數,評論分數以及最低入住價格。使用者選中要入住的酒店進入酒店詳情頁面,檢視酒店的介紹以及酒店的房型列表,使用者根據他要入住的時間和離店的時間,檢索出這個時間段內的所有可選房型(房間數量-當天的訂單-當天未離店訂單=剩餘房間數量)顯示給使用者。使用者選擇好房型後就可以進行下單,要求有訂單的開始時間,結束時間,房間數量,住客姓名,抵店時間,聯絡方式,備註資訊等等。

 那我的表是這麼設計的,總共有6張表,分別是:

使用者表user,裡面有下面幾個欄位,(使用者編號,使用者名稱稱,使用者密碼,使用者聯絡方式)

酒店表hotel,裡面有(酒店編號,酒店名稱,酒店圖片,評論人數,評論分數,最低入住價格,所在地區)

酒店圖片表pic(圖片編號,圖片地址,圖片排序,圖片所屬酒店)

評論表comment(評論編號,評論內容,評論時間,使用者編號,酒店編號)

房型表house(房型編號,床型,早餐,寬頻,人數上限,房價,房間數量,最長預定時間)

訂單表order(訂單編號,開始時間,結束時間,房間數量,住客姓名,最晚抵店時間,聯絡電話,使用優惠券,備註,訂單狀態)  

以上就是我對這個酒店預訂系統的設計

2、預定時間怎麼寫入資料庫的

以預訂當時的時間戳作為預訂時間寫入資料庫。使用者下訂單時會選擇一個抵店時間,將該抵店時間以時間戳方式存入資料庫中。離店時間以當時的日期轉為時間戳方式存入資料庫中

3、怎麼判斷還有沒有房間

我可以根據使用者的入住時間和離店時間來檢索這個有效時間段內房間的庫存。房間數量扣除在這個時間段內入住的訂單和在這個時間段內離店的訂單。扣除後等到的數量才是這段時間內有效房間數量。

4、怎麼記錄每天的房間庫存

我的思路是根據一個公式來推理實現的,每天房間的庫存=房型下房間數量-(當天入住的訂單+當天未離店的訂單),這樣我就可以得到每天還有多少房間是剩餘的了。

5、怎麼在資料庫裡對房間做唯一標識

上面所設計的房型表就是我們的房間表,每個房間是唯一的,我們是使用數字作為編號的,也即使用主鍵作為唯一標識。

6、最近出的新功能

    最近我們出了個會員機制,客戶第一次預訂酒店成功後,可以辦理會員卡,憑藉會員卡,下次來的時候可以打折,會員在一些比較特殊的日期預訂酒店成功,可以享受不一樣的優惠措施。

7、怎麼保證促銷商品不會超賣

   這個問題是我們當時開發時遇到的一個難點,超賣的原因主要是下的訂單的數目和我們要促銷的商品的數目不一致導致的,每次總是訂單的數比我們的促銷商品的數目要多,當時我們的小組討論了好久,給出了好幾個方案來實現:

第一種方案是:①在每次下訂單前我們判斷促銷商品的數量夠不夠,不夠不允許下訂單,更改庫存量時加上一個條件,只更改商品庫存大於0的商品的庫存,當時我們使用ab進行壓力測試,當併發超過500,訪問量超過2000時,還是會出現超賣現象。所以被我們否定了。

第二種方案是:②使用mysql的事務加排他鎖來解決,首先我們選擇資料庫的儲存引擎為innoDB,使用的是排他鎖實現的,剛開始的時候我們測試了下共享鎖,發現還是會出現超賣的現象。有個問題是,當我們進行高併發測試時,對資料庫的效能影響很大,導致資料庫的壓力很大,最終也被我們否定了。

第三種方案是:③使用檔案鎖實現。當用戶搶到一件促銷商品後先觸發檔案鎖,防止其他使用者進入,該使用者搶到促銷品後再解開檔案鎖,放其他使用者進行操作。這樣可以解決超賣的問題,但是會導致檔案得I/O開銷很大。

最後我們使用了redis的佇列來實現。將要促銷的商品數量以佇列的方式存入redis中,每當使用者搶到一件促銷商品則從佇列中刪除一個數據,確保商品不會超賣。這個操作起來很方便,而且效率極高,最終我們採取這種方式來實現

8、redis叢集怎麼做

1、Redis叢集提供了以下兩個好處

1、將資料自動切分(split)到多個節點

2、當叢集中的某一個節點故障時,redis還可以繼續處理客戶端的請求。

2、叢集的方案:

   redis-cluster叢集,採用無中心結構,每個節點儲存資料和整個叢集狀態,每個節點都和其他所有節點連線,主要通過節點的配置,輔以redis的主從來完成叢集。由於這塊東西我使用得很少,所以只是平時抽時間去研究過,並沒有真正的在線上實現過。

 

9、redis和memcacahe、mongoDB的區別

答:都是非關係型資料庫,效能都非常高,但是mongoDB和memcache、redis是不同的兩種型別。後兩者主要用於資料的快取,前者主要用在查詢和儲存大資料方面,是最接近資料庫的文件型的非關係資料庫。

 這裡我主要談談memcache和redis的區別。

①從資料儲存位置上來分,memcache的資料存在記憶體中,而redis既可以儲存在記憶體中,也可以儲存的到磁碟中,達到持久化儲存的功能,memcache一旦斷電,資料全部丟失,redis可以利用快照和AOF把資料存到磁碟中,當恢復時又從磁碟中讀取到記憶體中,當實體記憶體使用完畢後,可以把資料寫入到磁碟中。

 ②從儲存資料的型別上來分,memcache和redis儲存的方式都是鍵值對,只不過redis值的型別比較豐富,有string(字串),hash(雜湊),list(列表),set(集合)zset(有序集合),而memcache主要儲存的是字串。

 ③從架構層次來分,Redis支援master-slave(主—從)模式應用,memcache支援分散式。

 ④另外從儲存資料的大小上來分,Redis單個value的最大限制是1GB,memcached只能儲存1MB的資料。但是Memcache在儲存100K以上的資料,效能稍微好一點。

  ⑤另外redis只支援單核,memcache可以支援多核,當然關於redis取代memcache的說法,在一般情況下,兩者效能都很高,在大多的業務場景選擇上,redis的選擇可能更加具有優勢,但也不能說可以完全取代,最終還是取決於你的應用場景。

10、持久化redis有幾種方式?

答:主要有兩種方式:

① 快照持久化

在redis配置檔案中已經自動開啟了,

格式是:save N M

表示在N秒之內,redis至少發生M次修改則redis抓快照到磁碟。

當然我們也可以手動執行save或者bgsave(非同步)命令來做快照

②append only file  AOF持久化

 總共有三種模式,如

appendfsync everysec預設的是每秒強制寫入磁碟一次

appendfsync always 每次執行寫操作的時候就強制寫入磁碟

appendfsync no 完全取決於os,效能最好但是持久化沒法保證

其中第三種模式最好。redis預設的也是採取第三種模式。

11、mysql儲存引擎

答:常用的主要分為兩種,一種是innodb,一種是myisam,兩者的主要區別是

     ①myisam不支援事務處理,而innoDB支援事務處理

②myisam 不支援外來鍵,innoDB支援外來鍵

③myisam支援全文檢索,而innoDB在MySQL5.6版本之後才支援全文檢索

④資料的儲存形式不一樣,mysiam表存放在三個檔案:結構、索引、資料,innoDB儲存把結構儲存為一個檔案,索引和資料儲存為一個檔案

⑤myisam在查詢和增加資料效能更優於innoDB,innoDB在批量刪除方面效能較高。

⑥myisam支援表鎖,而innoDB支援行鎖

12、 sql注入是什麼及如何預防sql注入?

答:SQL注入攻擊指的是使用者或者黑客通過構建特殊的輸入作為引數傳入我們的Web應用程式端,而這些輸入大都是SQL語法裡的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式設計師沒有細緻地過濾使用者輸入的資料,致使非法資料侵入系統而造成的。因此我們在做開發過程中一定要預防sql注入,主要從兩方面著手:1、佔位符的方式,就是對sql語句進行預處理,然後執行sql語句

2、通過addslashes或者mysql_real_escape_string這兩個函式對使用者輸入的值進行轉義處理,把一些特殊的字元轉義掉。

13、有用過預處理麼?

答:用過,PDO類中,有個prepare方法可以實現預處理,PDOStament類中 的excute方法可以執行預處理,預處理的引數分為兩種,一種是:字串佔位符,另一種是?佔位符,:字串佔位符在執行預處理傳遞引數時傳入的是關聯陣列,而?佔位符傳遞的是索引陣列。兩者不能混合使用,但一般推薦使用:字串佔位符。

14、用框架還用自己的處理嗎

答:一般成熟的開源框架中都考慮到了資料安全這方面的東西,但有時候我們可能會使用一些原生的SQL語句時,我們就需要考慮自己對sql語句進行預處理。當然有時候框架中的過濾方法我們不希望採用,比如使用文字編輯器時,我們可以使用自己的過濾方式。

 

15、mysql優化怎麼做的?

答:mysql優化主要從以下幾個方面來實現:

  ①設計角度:儲存引擎的選擇,欄位型別選擇,正規化

  ②功能角度:可以利用mysql自身的特性,如索引,查詢快取,碎片整理,分割槽、分表等

  ③sql語句的優化方面:儘量簡化查詢語句,能查詢欄位少就儘量少查詢欄位,優化分頁語句、分組語句等。

  ④部署大負載架構體系:資料庫伺服器單獨出來,負載大時可以採用主從複製,讀寫分離機制進行設計

  ⑤從硬體上升級資料庫伺服器。

 

16、訂單表用是什麼儲存引擎

答:因為訂單表存在著事務的處理,比如下了訂單,商品的庫存就要減少,這裡就涉及到了事務,所以就用到innodb。

19 、sql語句的優化

答:首先我們得確定哪些sql語句需要優化,一般在一個系統中,查詢語句最多,所以我們主要是針對查詢語句進行優化。主要採用兩種方式來確定要優化的sql語句:

   ①使用慢查詢日誌,設定需要優化的sql語句的執行時間,記錄下超過該設定時間的語句,即為需要優化的語句。

   ②使用profiling機制,記錄下每條sql語句的執行時間,找出執行較慢的語句,即為需要優化的語句。

   我們主要通過給表字段新增索引的方式進行優化,加上索引後,sql語句的執行時間顯著提高了,但並不是加上索引了這條sql語句就會用到索引,所以首先看執行慢的語句後面是否有加索引,我們可以使用explain或者desc加在要執行的sql語句前,檢視是否使用到索引。有幾個地方需要注意的是:

  ①為了避免建議索引而造成索引檔案過大,有時候我們會使用複合索引,這時候要遵循最左原則。

  ②like查詢,前%不會用到索引

  ③如果條件中有or,則要求or的索引欄位都必須有索引,否則不能用到索引。

  ④如果列型別是字串,一定要在條件中將資料使用引號引用起來,否則不使用索引。

  ⑤優化group by 語句

  ⑥儘量避免模糊匹配,這樣會導致全盤掃描

21、 索引有幾種

答:索引主要有:

      主鍵索引:資料記錄裡面不能有null,資料內容不能重複,在一張表裡面不能有多個主鍵索引。

      普通索引:使用欄位關鍵字建立的索引,主要是提高查詢速度

      唯一索引:欄位資料是唯一的,資料內容裡面能否為null,在一張表裡面,是可以新增多個唯一索引。

      全文索引:在比較老的版本中,只有myisam引擎支援全文索引,在innodb5.6後引擎也支援全文索引,在mysql中全文索引不支援中文。我們一般使用sphinx集合coreseek來實現中文的全文索引。

23 、左前索引原則

答:左前索引主要指的是在複合索引中,給兩個或多個欄位建立了複合索引後,在sql語句後的條件中,只有複合索引前面的欄位在條件的前面時,該索引才起作用,比如建立了個複合索引index (a,b),在使用where或者orderby條件時,如果只有條件b的,該索引不會生效,必須有條件a且必須要在條件b的前面該索引才會生效。

24 、分散式資料庫

答:我所知道的分散式資料庫有memcache,主要是分散式的非關係型資料庫,用於快取處理。

    分散式是指將不同的業務分佈在不同的地方。 而叢集指的是將幾臺伺服器集中在一起,實現同一業務。

分散式中的每一個節點,都可以做叢集。 而叢集並不一定就是分散式的。

舉例:就比如新浪網,訪問的人多了,他可以做一個群集,前面放一個響應伺服器,後面幾臺伺服器完成同一業務,如果有業務訪問的時候,響應伺服器看哪臺伺服器的負載不是很重,就將給哪一臺去完成。

而分散式,從窄意上理解,也跟叢集差不多, 但是它的組織比較鬆散,不像叢集,有一個組織性,一臺伺服器垮了,其它的伺服器可以頂上來。

  memcache的應用場景

1、適用memcached的業務場景?

1)如果網站包含了訪問量很大的動態網頁,因而資料庫的負載將會很高。由於大部分資料庫請求都是讀操作,那麼memcached可以顯著地減小資料庫負

載。

2)利用memcached可以快取session資料、臨時資料以減少對他們的資料庫寫操作。

4)快取一些很小但是被頻繁訪問的檔案。

5)訪問比較頻繁,安全性不高,丟失無所謂,修改比較頻繁的資料,比如一些使用者的線上狀態

 

2 、不適用memcached的業務場景?

1)快取物件的大小大於1MB

memcache本身就不是為了處理龐大的多媒體(large media)和巨大的二進位制塊(streaming huge blobs)而設計的。

2)key的長度大於250字元

3)應用執行在不安全的環境中

4)業務本身需要的是持久化資料或者說需要的應該是database

25、nginx日誌,怎麼統計每個ip的訪問量

(參考阿銘哥手冊)

   stub_status模組主要用於檢視Nginx的一些狀態資訊,例如統計nginx的訪問量,首先我們得檢視該模組有沒有安裝,如果沒有安裝,得先安裝,安裝好後,修改nginx的配置檔案,開啟該模組,然後就可以使用以下命令來進行統計,如:

 1.根據訪問IP統計UV

awk '{print $1}'  access.log|sort | uniq -c |wc -l

2.統計訪問URL統計PV

awk '{print $7}' access.log|wc -l

3.查詢訪問最頻繁的URL

awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more

4.查詢訪問最頻繁的IP

awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|more

統計nginx日誌中訪問最多的100個ip及訪問次數

awk ‘{print $1}’ access.log|sort | uniq -c |sort -n -k 1 -r| head -n 100

26、http協議

HTTP是一個屬於應用層的面向物件的協議,由於其簡捷、快速的方式,適用於分散式超媒體資訊系統

HTTP協議的主要特點可概括如下:

1.支援客戶/伺服器模式。

2.簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用 的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

3.靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加 以標記。

4.無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請 求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。

5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。 缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次 連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。

27、cookie與session的區別

1、cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上。

2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙

        考慮到安全應當使用session。

3、session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能

        考慮到減輕伺服器效能方面,應當使用COOKIE。

4、單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個站點最多儲存20個cookie。

5、所以個人建議:

        將登陸資訊等重要資訊存放為SESSION

       其他資訊如果需要保留,可以放在COOKIE中

 

28、php在儲存session以什麼形式存在

PHP為session的儲存提供了三種方式: 檔案/ 記憶體/ 自定義儲存,預設是使用檔案儲存.在訪問量大的網站上採用這種方式就不大合 適,因為這樣會導致大量的輸入輸出的冗餘.我們可以在php.ini更改配置檔案或者php指令碼中通過相應的函式來設定session檔案的儲存型別來改變session檔案的儲存形式

 

29、xss攻擊怎麼防止

XSS又稱CSS,全稱Cross SiteScript(跨站指令碼攻擊), XSS攻擊類似於SQL注入攻擊,是Web程式中常見的漏洞,XSS屬於被動式且用於客戶端的攻擊方式,所以容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML程式碼,當用戶瀏覽該網站時,這段HTML程式碼會自動執行,從而達到攻擊的目的。如,盜取使用者Cookie資訊、破壞頁面結

常見的惡意字元XSS輸入:

1. XSS 輸入通常包含 JavaScript 指令碼,如彈出惡意警告框:<script>alert("XSS");</script>

2. XSS 輸入也可能是 HTML 程式碼段,譬如:

(1) 網頁不停地重新整理 <meta http-equiv="refresh" content="0;">

(2) 嵌入其它網站的連結 <iframe src=http://xxxx width=250 height=250></iframe>

構、重定向到其它網站等。

方法:利用php htmlentities()函式

php防止XSS跨站指令碼攻擊的方法:是針對非法的HTML程式碼包括單雙引號等,使用htmlspecialchars()函式。

在使用htmlspecialchars()函式的時候注意第二個引數, 直接用htmlspecialchars($string)的話,第二個引數預設是ENT_COMPAT,函式預設只是轉化雙引號("),不對單引號(')做轉義。

所以,htmlspecialchars()函式更多的時候要加上第二個引數,應該這樣用: htmlspecialchars($string,ENT_QUOTES)。當然,如果需要不轉化如何的引號,用htmlspecialchars($string,ENT_NOQUOTES)。

另外,儘量少用htmlentities(), 在全部英文的時候htmlentities()和htmlspecialchars()沒有區別,都可以達到目的。但是,中文情況下, htmlentities()卻會轉化所有的html程式碼,連同裡面的它無法識別的中文字元也給轉化了。

htmlentities()和htmlspecialchars()這兩個函式對單引號(')之類的字串支援不好,都不能轉化, 所以用htmlentities()和htmlspecialchars()轉化的字串只能防止XSS攻擊,不能防止SQL注入攻擊。

所有有列印的語句如echo,print等,在列印前都要使用htmlentities()進行過濾,這樣可以防止XSS,注意中文要寫出htmlentities($name,ENT_NOQUOTES,GB2312)。

 

 

30、禁用cookie後,session還能用嗎?

可以,在儲存session的檔案中,生成sessionID,通過get傳參的方式將sessionID傳到要實現session共享的頁面,讀取sessionID,從而從session中獲取資料。

 

31、mongodb基於什麼開發的

MongoDB是一個基於分散式檔案儲存的資料庫。由C++語言編寫。旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。

32、mongodb是非正規化還是正規化

資料表示的方式有很多種,其中最重要的問題之一就是在多大程度上對資料進行正規化化。正規化化(normalization)是將資料分散到多個不同的集合,不同集合之間可以相互引用資料。雖然很多文件可以引用某一塊資料,但是這塊資料只儲存在一個集合中。所以,如果要修改這塊資料,只需修改儲存這塊資料的那一個文件就行了。但是,MongoDB沒有提供連線(join)工具,所以在不同集合之間執行連線查詢需要進行多次查詢。

反正規化化(denormalization)與正規化化相反:將每個文件所需的資料都嵌入在文件內部。每個文件都擁有自己的資料副本,而不是所有文件共同引用同一個資料副本。這意味著,如果資訊發生了變化,那麼所有相關文件都需要進行更新,但是在執行查詢時,只需要一次查詢,就可以得到所有資料。

決定何時採用正規化化何時採用反正規化化時比較困難的。正規化化能夠提高資料寫入速度,反正規化化能夠提高資料讀取速度。需要根據自己應用程式的十幾需要仔細權衡。

 

33、mongodb與mysql區別

 

 

 

MySQL是關係型資料庫。

   優勢:

在不同的引擎上有不同 的儲存方式。

查詢語句是使用傳統的sql語句,擁有較為成熟的體系,成熟度很高。

開源資料庫的份額在不斷增加,mysql的份額頁在持續增長。

   缺點:

在海量資料處理的時候效率會顯著變慢。

Mongodb是非關係型資料庫(nosql ),屬於文件型資料庫。文件是mongoDB中資料的基本單元,類似關係資料庫的行,多個鍵值對有序地放置在一起便是文件,語法有點類似javascript面向物件的查詢語言,它是一個面向集合的,模式自由的文件型資料庫。

儲存方式:虛擬記憶體+持久化。

查詢語句:是獨特的Mongodb的查詢方式。

適合場景:事件的記錄,內容管理或者部落格平臺等等。

架構特點:可以通過副本集,以及分片來實現高可用。

資料處理:資料是儲存在硬碟上的,只不過需要經常讀取的資料會被載入到記憶體中,將資料儲存在實體記憶體中,從而達到高速讀寫。

成熟度與廣泛度:新興資料庫,成熟度較低,Nosql資料庫中最為接近關係型資料庫,比較完善的DB之一,適用人群不斷在增長。

優點:

快速!在適量級的記憶體的Mongodb的效能是非常迅速的,它將熱資料儲存在實體記憶體中,使得熱資料的讀寫變得十分快。高擴充套件性,儲存的資料格式是json格式!

缺點:

不支援事務,而且開發文件不是很完全,完善。

 

   Mysql和Mongodb主要應用場景(簡單瞭解敘述下即可)

1.如果需要將mongodb作為後端db來代替mysql使用,即這裡mysql與mongodb 屬於平行級別,那麼,這樣的使用可能有以下幾種情況的考量: (1)mongodb所負責部分以文件形式儲存,能夠有較好的程式碼親和性,json格式的直接寫入方便。(如日誌之類) (2)從data models設計階段就將原子性考慮於其中,無需事務之類的輔助。開發用如nodejs之類的語言來進行開發,對開發比較方便。 (3)mongodb本身的failover機制,無需使用如MHA之類的方式實現。

2.將mongodb作為類似redis ,memcache來做快取db,為mysql提供服務,或是後端日誌收集分析。 考慮到mongodb屬於nosql型資料庫,sql語句與資料結構不如mysql那麼親和 ,也會有很多時候將mongodb做為輔助mysql而使用的類redis memcache 之類的快取db來使用。 亦或是僅作日誌收集分析。

 

34、寫一個函式統計每一個元素出現的次數

PHP 中的 array_count_values() 函式可以實現 array_count_values() 函式用於統計陣列中所有值出現的次數。 本函式返回一個數組,其元素的鍵名是原陣列的值,鍵值是該值在原陣列中出現的次數。

 

35、手寫排序

主要從原理方面來說:重點介紹氣泡排序和選擇排序

 

· // 氣泡排序

function BubbleSort($arr) {

    // 獲得陣列總長度

    $num = count($arr);

    // 正向遍歷陣列

    for ($i = 1; $i < $num; $i++) {

        // 反向遍歷

        for ($j = $num - 1; $j >= $i ; $j--) {

            // 相鄰兩個數比較

            if ($arr[$j] < $arr[$j-1]) {

                // 暫存較小的數

                $iTemp = $arr[$j-1];

                // 把較大的放前面

                $arr[$j-1] = $arr[$j];

                // 較小的放後面

                $arr[$j] = $iTemp;

            }

        }

    }

    return $arr;

}

·  // 交換法排序

function ExchangeSort($arr){

    $num = count($arr);

    // 遍歷陣列

    for ($i = 0;$i < $num - 1; $i++) {

        // 獲得當前索引的下一個索引

        for ($j = $i + 1; $j < $num; $j++) {

            // 比較相鄰兩個的值大小

            if ($arr[$j] < $arr[$i]) {

                // 暫存較小的數

                $iTemp = $arr[$i];

                // 把較大的放前面

                $arr[$i] = $arr[$j];

                // 較小的放後面

                $arr[$j] = $iTemp;

            }

        }

    }

    return $arr;

}

·  // 選擇法排序

function SelectSort($arr) {

    // 獲得陣列總長度

    $num = count($arr);

    // 遍歷陣列

    for ($i = 0;$i < $num-1; $i++) {

        // 暫存當前值

        $iTemp = $arr[$i];

        // 暫存當前位置

        $iPos = $i;

        // 遍歷當前位置以後的資料

        for ($j = $i + 1;$j < $num; $j++){

            // 如果有小於當前值的

            if ($arr[$j] < $iTemp) {

                // 暫存最小值

                $iTemp = $arr[$j];

                // 暫存位置

                $iPos = $j;

            }

        }

        // 把當前值放到算好的位置

        $arr[$iPos] = $arr[$i];

        // 把當前值換成算好的值

        $arr[$i] = $iTemp;

    }

    return $arr;

}

·  // 插入法排序

function InsertSort($arr){

    $num = count($arr);

    // 遍歷陣列

    for ($i = 1;$i < $num; $i++) {

        // 獲得當前值

        $iTemp = $arr[$i];

        // 獲得當前值的前一個位置

        $iPos = $i - 1;

        // 如果當前值小於前一個值切未到陣列開始位置

        while (($iPos >= 0) && ($iTemp < $arr[$iPos])) {

            // 把前一個的值往後放一位

            $arr[$iPos + 1] = $arr[$iPos];

            // 位置遞減

            $iPos--;

        }

        $arr[$iPos+1] = $iTemp;

    }

    return $arr;

}

·  // 快速排序

function QuickSort($arr){

    $num = count($arr);

    $l = $r = 0;

    $left = $right = array();

    // 從索引的第二個開始遍歷陣列

    for ($i = 1;$i < $num; $i++) {

        // 如果值小於索引1

        if ($arr[$i] < $arr[0]) {

            // 裝入左索引陣列(小於索引1的資料)

            $left[] = $arr[$i];

            $l++;

        } else {

            // 否則裝入右索引中(大於索引1的資料)

            $right[] = $arr[$i];

            $r++; //

        }       

    }

    // 如果左索引有值 則對左索引排序

    if($l > 1) {

        $left = QuickSort($left);

    }

    // 排序後的陣列

    $new_arr = $left;

    // 將當前陣列第一個放到最後

    $new_arr[] = $arr[0];

    // 如果又索引有值 則對右索引排序

    if ($r > 1) {

        $right = QuickSort($right);

    }

    // 根據右索引的長度再次增加資料

    for($i = 0;$i < $r; $i++) {

        $new_arr[] = $right[$i];

    }

    return $new_arr;

}

36、設計模式

   在PHP中,我主要使用了以下兩種設計模式

1、單例模式

單例模式顧名思義,就是隻有一個例項。作為物件的建立模式, 單例模式確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。

單例模式的要點有三個:

一是某個類只能有一個例項;

二是它必須自行建立這個例項;

三是它必須自行向整個系統提供這個例項。

典型的代表如框架中的基類物件。

2、簡單工廠模式

①抽象基類:類中定義抽象一些方法,用以在子類中實現

②繼承自抽象基類的子類:實現基類中的抽象方法

③工廠類:用以例項化所有相對應的子類

    這種我們使用最常見,基本所有的MVC框架中都是這樣產生的。

37、用過什麼PHP框架

在開發過程中,我主要使用過了這麼幾種框架。thinkPHP框架、CI框架,laravel框架和yii框架。我接觸到的第一個框架是TP框架,我簡單的說下我對這幾個框架的看法:

ThinkPHP框架

  優點:

TP借鑑了Java思想,基於PHP5,充分利用了PHP5的特性,部署簡單隻需一個入口檔案,一切搞定,簡單高效,中文文件齊全,入門超級簡單。自帶模板引擎,具有獨特的資料驗證和自動填充功能,框架更新速度比較迅速。

 缺點:一個Model中可以操作多個表,但TP只能一個。

TP預設初始化了很多配置,使用起來很方便,但自然也會影響效率。但是把一些載入配置的時間拿去研究演算法,這些小影響近乎可以忽略了。

CodeIgniter框架

優點:

配置簡單,上手很快,全部的配置使用PHP指令碼來配置,沒有使用很多太複雜的設計模式,執行效能和程式碼可讀性上都不錯,執行效率比較高,具有基本的MVC功能. 快速簡潔,程式碼量少,框架簡單,容易上手,自帶了很多簡單好用的library,框架適合中小型專案,大型專案也不是不可以,只是擴充套件能力稍差。

缺點:

1. 把Model層簡單的理解為資料庫操作

2. PHP框架略顯簡單,只能夠滿足小型應用,略微不太能夠滿足中型應用需要

 

laravel框架(目前最新的是5.3,要求PHP版本較高5.6)

       優點:

   1.Laravel注重程式碼的模組化和可擴充套件性。

   2.artisan: 命令列工具,很多手動的工作都自動了

   3.可繼承的模版,簡化view的開發和管理

   Laravel一直是PHP開發者最受歡迎的PHP框架。這是一個年輕的框架,但是擁有優雅的語法,可簡單快速開發你的應用。它擁有大多數常見的功能,如:路由,身份驗證,會話,佇列和快取。 

  缺點:

   laravel的中英文文件比較少 demo也比較少 有時候一個功能要試好久 甚至要看原始碼

 

YII框架(目前是2.0版本)

優點:

 1、快速,敏捷,不拖沓,給程式設計師飛翔的能力;

 2、有gii功能!(建立控制器,model層,crud等操作);

 3、具有高度的可重用性和可擴充套件性,是純粹的面向物件的。開發速度快,完備的文件,可重用性可高擴充套件,是最高效的開發框架之一。

缺點:

1、對Model層的指導和考慮較少

2、文件例項較少

3、英文太多

4、要求PHP技術精通,OOP程式設計要熟練!

5、要求會bootstrap

38 、程式碼管理工具

   我使用過的版本控制工具有兩種:早期的時候使用的是SVN,現在主要使用git,我就我個人的觀點,簡單的說下兩者的區別:

1. Git是分散式的,SVN是集中式的,好處是跟其他同事不會有太多的衝突,自己寫的程式碼放在自己電腦上,一段時間後再提交、合併,也可以不用聯網在本地提交;

2. Git下載下來後,在本地不必聯網就可以看到所有的log,很方便學習,SVN卻需要聯網;

3. Git鼓勵分Branch(分支),而SVN,說實話,我用Branch的次數還挺少的,SVN自帶的Branch merge我還真沒用過,有merge時用的是Beyond Compare工具合併後再Commit的;

4. SVN在Commit前,我們都建議是先Update一下,跟本地的程式碼編譯沒問題,並確保開發的功能正常後再提交

SVN 的主要功能

    SVN屬於集中化的版本控制系統,有個不太精確的比喻:SVN = 版本控制+ 備份伺服器

     SVN使用起來有點像是檔案倉庫的感覺,支援並行讀寫檔案,支援程式碼的版本化管理,功能包括取出、匯入、更新、分支、改名、還原、合併等。

     功能有許多我就不一一列了,SVN大都採用圖形介面操作,直觀,上手快。

Git的主要功能

      Git是一個分散式版本控制系統,操作命令包括:clone,pull,push,branch ,merge ,rebas,Git擅長的是程式程式碼的版本化管理。

 

SVN 的優缺點

      SVN對中文支援好,操作簡單,使用沒有難度,美工人員,產品人員,測試人員,實施人員都可輕鬆上手。使用介面統一,功能完善,操作方便。

Git的優缺點

      對程式原始碼進行差異化的版本管理,程式碼庫佔極少的空間。易於程式碼的分支化管理。不支援中文,圖形介面支援差,使用難度大。不易推廣。

SVN 和 Git 哪個更適用於專案管理?

     SVN更適用於專案管理, Git僅適用於程式碼管理。

     一個研發隊伍的成員正常包括:需求分析、設計、美工、程式設計師、測試、實施、運維,每個成員在工作中都有產出物,  包括了文件、設計程式碼、程式程式碼,這些都需要按專案集中進行管理的。SVN能清楚的按目錄進行分類管理, 使專案組的管理處於有序高效的狀態。

現在越來越多人使用git做為版本控制工具,我以前的公司也是使用git.

 

39、手寫單例模式怎麼寫

  三私一公。

class Example

{

//儲存例例項在此屬性中

private static $_instance;

  

//建構函式宣告為private,防止直接建立物件

private function __construct()

{

echo 'I am Construceted';

}

  

//單例方法

public static function singleton()

{

if(!isset(self::$_instance))

{

$c=__CLASS__;

self::$_instance=new $c;

}

return self::$_instance;

}

  

//阻止使用者複製物件例項

public function __clone()

{

trigger_error('Clone is not allow' ,E_USER_ERROR);

}

  

function test()

{

echo("test");

  

}

}

  

// 這個寫法會出錯,因為構造方法被宣告為private

$test = new Example;

  

// 下面將得到Example類的單例物件

$test = Example::singleton();

$test->test();

  

// 複製物件將導致一個E_USER_ERROR.

$test_clone = clone $test;

?>

 

 

40、nosql和Mysql的區別

   也即非關係型資料庫和關係型資料庫。

目前世界上主流的儲存系統大部分還是採用了關係型資料庫,其主要有一下優點:

1.事務處理—保持資料的一致性;

2.由於以標準化為前提,資料更新的開銷很小(相同的欄位基本上只有一處);

3.可以進行Join等複雜查詢。

nosql在優勢方面,主要體現在下面這三點: 

1. 簡單的擴充套件:典型例子是Cassandra,由於其架構是類似於經典的P2P,所以能通過輕鬆地新增新的節點來擴充套件這個叢集;

2. 快速的讀寫:主要例子有Redis,由於其邏輯簡單,而且純記憶體操作,使得其效能非常出色,單節點每秒可以處理超過10萬次讀寫操作; 

3. 低廉的成本:這是大多數分散式資料庫共有的特點,因為主要都是開源軟體,沒有昂貴的License成本; 

4. 

但瑕不掩瑜,NoSQL資料庫還存在著很多的不足,常見主要有下面這幾個: 

1. 不提供對SQL的支援:如果不支援SQL這樣的工業標準,將會對使用者產生一定的學習和應用遷移成本; 

2. 支援的特性不夠豐富:現有產品所提供的功能都比較有限,大多數NoSQL資料庫都不支援事務,也不像 SQL Server和Oracle那樣能提供各種附加功能,比如BI和報表等; 

3. 現有產品的不夠成熟:大多數產品都還處於初創期,和關係型資料庫幾十年的完善不可同日而語; 

 

41、在TP中M方法與D方法的區別

雖然都是例項化模型物件,兩者還是有區別的

D和M的區別主要在於

M方法不需要建立模型類檔案,M方法不會讀取模型類,所以預設情況下自動驗證是無效的,但是可以通過動態賦值的方式實現

而D方法必須有建立模型類。

我們可以用下面兩種方法去建立一個數據表的對映物件

第一種:$Test = D(‘Test’)

第二種:$Test = new Model(‘Test’)

雖然這兩種都可以對資料進行select,insert,delete,udpate操作,在

資料驗證上有很大的不同,

用第一種方式例項一個模型就會有資料檢查功能,如果 title 沒有填寫的話就會提示 “請輸入標題” (這個是tp提供的一個自動驗證功能,當然也需要在相應的model中定義好驗證條件);

如果用第二種就沒有了這個資料驗證功能,需要手動驗證。

D函式例項化的是你當前專案的Lib/Model下面的模組。

如果該模組不存在的話,直接返回例項化Model的物件(意義就與M()函式相同)。

而M只返回,例項化Model的物件。它的$name引數作為資料庫的表名來處理對資料庫的操作。

42、對網站大訪問量的優化方案

   提高訪問速度。從硬體,最好從網站程式等等方面考慮。我給出以下幾種方案:

1.儘量使用靜態頁,不要老使用動態資訊呼叫。非常容易出問題

2.圖片內容與網站資料儘量放在同一個伺服器或者機房內。大量外鏈圖片是會有問題的

3.一次又一次,一遍又一遍的分析流量走向,然後縮短瀏覽者瀏覽距離,舉個例子,瀏覽者如果現在在你網站看一個新聞需要點5次滑鼠,你就要縮短這個點選數。

4.一次又一次,一遍又一遍的分析,修改你的網站資料庫結構,使其更加簡潔。

5.提高網站的安防能力

6.買個好伺服器,託管在一個好的機房!

43、網站高併發大流量訪問的處理及解決方法

  第一:確認伺服器硬體是否足夠支援當前的流量。 

普通的P4伺服器一般最多能支援每天10萬獨立IP,如果訪問量比這個還要大,那麼必須首先配置一臺更高效能的專用伺服器才能解決問題,否則怎麼優化都不可能徹底解決效能問題。

第二:優化資料庫訪問 

 前臺實現完全的靜態化當然最好,可以完全不用訪問資料庫,不過對於頻繁更新的網站,靜態化往往不能滿足某些功能。

 快取就是另一個解決方案,就是將動態資料儲存到快取檔案中,動態網頁直接呼叫這些檔案,而不必再訪問資料庫,技術如果確實無法避免對資料庫的訪問,那麼可以嘗試優化資料庫的查詢SQL.避免使用Select * from這樣的語句,每次查詢只返回自己需要的結果,避免短時間內的大量SQL查詢。最好在相同欄位進行比較操作,在建立好的索引欄位上儘量減少函式操作,如果要做到極致的話需要程式碼的優化;

 第三,禁止外部的盜鏈。 

   外部網站的或者檔案盜鏈往往會帶來大量的負載壓力,因此應該嚴格限制外部對於自身的圖片或者檔案盜鏈,好在目前可以簡單地通過refer來控制盜鏈,自己就可以通過配置來禁止盜鏈。當然,偽造refer也可以通過來實現盜鏈,不過目前蓄意偽造refer盜鏈的還不多,可以先不去考慮,或者使用非技術手段來解決,比如在圖片上增加水印。

第四,控制大檔案的下載。 

   大檔案的下載會佔用很大的流量,並且對於非SCSI硬碟來說,大量檔案下載會消耗CPU,使得網站響應能力下降。因此,儘量不要提供超過2M的大檔案下載,如果需要提供,建議將大檔案放在另外一臺伺服器上。

第五,使用不同主機分流主要流量 

   將檔案放在不同的主機上,提供不同的映象供使用者下載。比如如果覺得RSS檔案佔用流量大,那麼使用FeedBurner或者FeedSky等服務將RSS輸出放在其他主機上,這樣別人訪問的流量壓力就大多集中在FeedBurner的主機上,RSS就不佔用太多資源了。

第六,使用流量分析統計軟體。