面試題總彙

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就不佔用太多資源了。
第六,使用流量分析統計軟件。 
  在網站上一個流量分析統計軟件,可以即時知道哪些地方耗費了大量流量,哪些頁面需要再進行優化,因此,解決流量問題還需要進行精確的統計分析纔可以。我推薦使用的流量分析統計軟件是Analytics(Google分析)。

45、主要運用到哪些緩存
一、數據緩存

這裏所說的數據緩存是指數據庫查詢緩存,每次訪問頁面的時候,都會先檢測相應的緩存數據是否存在,如果不存在,就連接數據庫,得到數據,並把查詢結果序列化後保存到文件中,以後同樣的查詢結果就直接從緩存表或文件中獲得。

用的最廣的例子看Discuz的搜索功能,把結果ID緩存到一個表中,下次搜索相同關鍵字時先搜索緩存表。
舉個常用的方法,多表關聯的時候,把附表中的內容生成數組保存到主表的一個字段中,需要的時候數組分解一下,這樣的好處是隻讀一個表,壞處就是兩個數據同步會多不少步驟,數據庫永遠是瓶頸,用硬盤換速度,是這個的關鍵點。

二、頁面緩存

每次訪問頁面的時候,都會先檢測相應的緩存頁面文件是否存在,如果不存在,就連接數據庫,得到數據,顯示頁面並同時生成緩存頁面文件,這樣下次訪問的時候頁面文件就發揮作用了。(模板引擎和網上常見的一些緩存類通常有此功能)。

三、時間觸發緩存

檢查文件是否存在並且時間戳小於設置的過期時間,如果文件修改的時間戳比當前時間戳減去過期時間戳大,那麼就用緩存,否則更新緩存。

四、內容觸發緩存

當插入數據或更新數據時,強制更新緩存。

五、靜態緩存

這裏所說的靜態緩存是指靜態化,直接生成HTML或XML等文本文件,有更新的時候重生成一次,適合於不太變化的頁面,這就不說了。
    六、內存緩存
     Memcached是高性能的,分佈式的內存對象緩存系統,用於在動態應用中減少數據庫負載,提升訪問速度。redis 也可以做到。

46、php的設計模式
1、單例模式 2、工廠模式 3、觀察者模式 4、命令鏈模式 5、策略模式

單例模式:

一個類在整個應用中,只有一個對象實例的設計模式

類必須自行創建這個實例

必須自行向整個系統提供這個實例

三私:私有靜態成員變量、構造函數、克隆函數

一公:公共的靜態方法

2、工廠模式

可以根據輸入的參數或者應用程序配置的不同一創建一種專門用來實例化並返回其它類的實例的類

3、觀察者模式

觀察者模式提供了組件之間緊密耦合的另一種方法。

該模式:一個對象通過添加一個方法(該方法允許另一個對象,即觀察者註冊自己)全本身變得可觀察。當可觀察的對象更改時,它會將消息發送到已註冊的觀察者。這些觀察者使用該信息執行的操作與可觀察的對象無關。

4、命令鏈模式:

以鬆散耦合主題爲基礎,發送消息、命令和請求,或通過一組處理程序發送任意內容。每個處理程序都會自行判斷自己能否處理請求,如果可以,該請求被處理,進程停止。

5、策略模式:

此算法是從複雜類提取的,因而可以方便地替換。

 

 

47.Mysql事務的特性
事務是作爲一個邏輯單元執行的一系列操作,一個邏輯工作單元必須有四個屬性,稱爲 ACID(原子性、一致性、隔離性和持久性)屬性,只有這樣才能成爲一個事務:
原子性
事務必須是原子工作單元;對於其數據修改,要麼全都執行,要麼全都不執行。
一致性
事務在完成時,必須使所有的數據都保持一致狀態。在相關數據庫中,所有規則都必須應用於事務的修改,以保持所有數據的完整性。
    事務結束時,所有的內部數據結構(如 B 樹索引或雙向鏈表)都必須是正確的。
隔離性
由併發事務所作的修改必須與任何其它併發事務所作的修改隔離。事務查看數據時數據所處的狀態,要麼是另一併發事務修改它之前的狀態,
       要麼是另一事務修改它之後的狀態,事務不會查看中間狀態的數據。這稱爲可串行性,因爲它能夠重新裝載起始數據,
       並且重播一系列事務,以使數據結束時的狀態與原始事務執行的狀態相同。

持久性
事務完成之後,它對於系統的影響是永久性的。該修改即使出現系統故障也將一直保持。

begin 開始一個事務

rollback事務回滾

commit事務確認

 

 

48、Mysql事務的應運場景
事務處理在各種管理系統中都有着廣泛的應用,比如人員管理系統,很多同步數據庫操作大都需要用到事務處理。比如說,在人員管理系統中,你刪除一個人員,你即需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務!

比如手機充值過程,支付寶金額減少,相應的手機話費增加,只要有一個操作不成功,則另外一個操作也不會成功

 

 

 

49.Include和require的區別
require函數通常放在PHP程序的最前面,在PHP程序執行之前,就會先讀取require指定引入的文件,使它變成PHP程序網頁的一部分。

include函數一般是放在流程控制的處理部分中。PHP程序在讀到include的文件時,纔將它讀進來,這種方式可以把程序執行時的流程簡單化。

他們兩個的用途是一樣的,不一定非要哪個放在最前面哪個放在中間,他們最根本的區別在於錯誤處理的方式不一樣。

require一個文件存在錯誤的話,那麼程序就會中斷執行,並顯示致命錯誤

而include一個文件存在錯誤的話,那麼程序不會中斷,會繼續執行,並顯示一個警告的錯誤

 

其它區別:include有返回值,而require沒有。

 

50、索引的建立與使用
     索引就是類似書的目錄,提高檢索數據的效率。

索引是系統按照某個具體的算法(哈希,散列,二叉樹),將數據從全部數據裏進行提取,維護成一個索引文件,然後系統在進行數據查詢的時候,發現如果查詢條件剛好滿足索引條件,就可以從索引文件中快速的定位的數據所在位置。

mysql中有以下幾種索引:

主鍵索引(primary key效率最高的索引)

唯一索引(unique key):不爲空的情況下效率最高

普通索引(index)對數據沒有要求,文件很大,效率比較低

全文索引(fulltext),對整個文章內部進行關鍵字索引(mysql5.5以後InnoDB支持全文索引)

英文的全文索引很簡單:英文單詞默認是用空格分離的

中文的全文索引很難:中文的詞組成很麻煩,需要利用分詞工具(sphinx)

 

     索引可以在創建表的同時創建索引,也可以在修改表結構時添加索引,索引主要是加在經常做爲查詢條件的字段上,可以使用相應的手段來檢測所執行的sql語句中是否使用到了索引。

 

51.正則匹配表達式各個符文表達的意義
\ 將下一個字符標記爲一個特殊字符、或一個原義字符、或一個向後引用、或一個八進制轉義符。例如,’n’ 匹配字符 “n”。’\n’ 匹配一個換行符。序列 ‘\\’ 匹配 “\” 而 “\(” 則匹配 “(”。

^ 匹配輸入字符串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 ‘\n’ 或 ‘\r’ 之後的位置。

$ 匹配輸入字符串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。

* 匹配前面的子表達式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等價於{0,}。

+ 匹配前面的子表達式一次或多次。例如,’zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等價於 {1,}。

? 匹配前面的子表達式零次或一次。例如,”do(es)?” 可以匹配 “do” 或 “does” 中的”do” 。? 等價於 {0,1}。

{n} n 是一個非負整數。匹配確定的 n 次。

{n,} n 是一個非負整數。至少匹配n 次。

{n,m} m 和 n 均爲非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。

. 匹配除 “\n” 之外的任何單個字符。要匹配包括 ‘\n’ 在內的任何字符,請使用象 ‘[.\n]’ 的模式。

x|y 匹配 x 或 y。

[xyz] 字符集合。匹配所包含的任意一個字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。

[^xyz] 負值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p'。

[a-z] 字符範圍。匹配指定範圍內的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 範圍內的任意小寫字母字符。

[^a-z] 負值字符範圍。匹配任何不在指定範圍內的任意字符。例如,’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 範圍內的任意字符。

\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。

\d 匹配一個數字字符。等價於 [0-9]。

\D 匹配一個非數字字符。等價於 [^0-9]。

\f 匹配一個換頁符。等價於 \x0c 和 \cL。

\n 匹配一個換行符。等價於 \x0a 和 \cJ。

\r 匹配一個回車符。等價於 \x0d 和 \cM。

\s 匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。

\S 匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。

\t 匹配一個製表符。等價於 \x09 和 \cI。

\v 匹配一個垂直製表符。等價於 \x0b 和 \cK。

\w 匹配包括下劃線的任何單詞字符。等價於’[A-Za-z0-9_]’。

\W 匹配任何非單詞字符。等價於 ‘[^A-Za-z0-9_]’。

 

 

52.PHP的變量類型
四種標量類型:

boolean (布爾型):這是最簡單的類型,只有兩種取值,可以爲 TRUE/true 或 FALSE/false ,不區分大小寫。詳細請查看:PHP布爾類型(boolean)

integer (整型):在32 位操作系統中它的有效範圍是:-2 147 483 648~+2 147 483 647。整型值可以使用十進制,十六進制或八進制表示,前面可以加上可選的符號(- 或者 +)。八進制表示數字前必須加上 0(零),十六進制表示數字前必須加上 0x。

float (浮點型, 也稱作 double)

string (字符串):字符型變量不同於其他編程語言有字符與字符串之分,在PHP 中,統一使用字符型變量來定義字符或者字符串。

兩種複合類型:

array (數組):數組型變量是一種比較特殊的變量類型,將在後續章節中詳細說明。

object (對象):對象也是一種特殊的數據類型。要創建object變量,請使用 new 關鍵字。詳細請查看:PHP對象類型(object)

最後是兩種特殊類型:

resource(資源):源是一種特殊變量,保存了到外部資源的一個引用。資源是通過專門的函數來建立和使用的。詳情請查看:PHP資源類型(resource)

NULL(NULL):表示一個變量沒有值。NULL 類型唯一可能的值就是 NULL。

 

54.商城秒殺的實現
  搶購、秒殺是如今很常見的一個應用場景,主要需要解決的問題有兩個:
1 高併發對數據庫產生的壓力
2 競爭狀態下如何解決庫存的正確減少("超賣"問題)
對於第一個問題,已經很容易想到用緩存來處理搶購,避免直接操作數據庫,例如使用Redis。第二個問題,我們可以使用redis隊列來完成,把要秒殺的商品放入到隊列中,因爲pop操作是原子的,即使有很多用戶同時到達,也是依次執行,文件鎖和事務在高併發下性能下降很快,當然還要考慮其他方面的東西,比如搶購頁面做成靜態的,通過ajax調用接口,其中也可能會出現一個用戶搶多次的情況,這時候需要再加上一個排隊隊列和搶購結果隊列及庫存隊列。高併發情況下,將用戶進入排隊隊列,用一個線程循環處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結果隊列,如果在,則已搶購,否則未搶購,庫存減1,寫數據庫,將用戶入結果隊列。

55.購物車的原理
 購物車相當於現實中超市的購物車,不同的是一個是實體車,一個是虛擬車而已。用戶可以在購物網站的不同頁面之間跳轉,以選購自己喜愛的商品,點擊購買時,該商品就自動保存到你的購物車中,重複選購後,最後將選中的所有商品放在購物車中統一到付款臺結賬,這也是儘量讓客戶體驗到現實生活中購物的感覺。服務器通過追蹤每個用戶的行動,以保證在結賬時每件商品都物有其主。   

 主要涉及以下幾點:

   1、把商品添加到購物車,即訂購

 

   2、  刪除購物車中已定購的商品

 

   3、 修改購物車中某一本圖書的訂購數量

 

        4、 清空購物車

 

        5、 顯示購物車中商品清單及數量、價格

 

     實現購物車的關鍵在於服務器識別每一個用戶並維持與他們的聯繫。但是HTTP協議是一種“無狀態(Stateless)”的協議,因而服務器不能記住是誰在購買商品,當把商品加入購物車時,服務器也不知道購物車裏原先有些什麼,使得用戶在不同頁面間跳轉時購物車無法“隨身攜帶”,這都給購物車的實現造成了一定的困難。

 

     目前購物車的實現主要是通過cookie、session或結合數據庫的方式。下面分析一下它們的機制及作用。

 

1. cookie

 

     cookie是由服務器產生,存儲在客戶端的一段信息。它定義了一種Web服務器在客戶端存儲和返回信息的機制,cookie文件它包含域、路徑、生存期、和由服務器設置的變量值等內容。當用戶以後訪問同一個Web服務器時,瀏覽器會把cookie原樣發送給服務器。通過讓服務器讀取原先保存到客戶端的信息,網站能夠爲瀏覽者提供一系列的方便,例如在線交易過程中標識用戶身份、安全要求不高的場合避免用戶重複輸入名字和密碼、門戶網站的主頁定製、有針對性地投放廣告等等。利用cookie的特性,大大擴展了WEB應用程序的功能,不僅可以建立服務器與客戶機的聯繫,因爲cookie可以由服務器定製,因此還可以將購物信息生成cookie值存放在客戶端,從而實現購物車的功能。用基於cookie的方式實現服務器與瀏覽器之間的會話或購物車,有以下特點:

 

   1、 cookie存儲在客戶端,且佔用很少的資源,瀏覽器允許存放300個cookie,每個cookie的大小爲4KB,足以滿足購物車的要求,同時也減輕了服務器的負荷;

 

   2、 cookie爲瀏覽器所內置,使用方便。即使用戶不小心關閉了瀏覽器窗口,只要在cookie定義的有效期內,購物車中的信息也不會丟失;

 

  3、 cookie不是可執行文件,所以不會以任何方式執行,因此也不會帶來病毒或攻擊用戶的系統;

 

  4、  基於cookie的購物車要求用戶瀏覽器必須支持並設置爲啓用cookie,否則購物車則失效;

 

  5、 存在着關於cookie侵犯訪問者隱私權的爭論,因此有些用戶會禁止本機的cookie功能。

 

2. session

 

     session是實現購物車的另一種方法。session提供了可以保存和跟蹤用戶的狀態信息的功能,使當前用戶在session中定義的變量和對象能在頁面之間共享,但是不能爲應用中其他用戶所訪問,它與cookie最重大的區別是,session將用戶在會話期間的私有信息存儲在服務器端,提高了安全性。在服務器生成session後,客戶端會生成一個sessionid識別號保存在客戶端,以保持和服務器的同步。這個sessionid是隻讀的,如果客戶端禁止cookie功能,session會通過在URL中附加參數,或隱含在表單中提交等其他方式在頁面間傳送。因此利用session實施對用戶的管理則更爲安全、有效。

 

     同樣,利用session也能實現購物車,這種方式的特點是:

 

1、 session用新的機制保持與客戶端的同步,不依賴於客戶端設置;

 

2、 與cookie相比,session是存儲在服務器端的信息,因此顯得更爲安全,因此可將身份標示,購物等信息存儲在session中;

 

3、session會佔用服務器資源,加大服務器端的負載,尤其當併發用戶很多時,會生成大量的session,影響服務器的性能;

 

4、因爲session存儲的信息更敏感,而且是以文件形式保存在服務器中,因此仍然存在着安全隱患。

 

3. 結合數據庫的方式

 

     這也是目前較普遍的模式,在這種方式中,數據庫承擔着存儲購物信息的作用,session或cookie則用來跟蹤用戶。這種方式具有以下特點:

 

1、 數據庫與cookie分別負責記錄數據和維持會話,能發揮各自的優勢,使安全性和服務器性能都得到了提高;

 

2、每一個購物的行爲,都要直接建立與數據庫的連接,直至對錶的操作完成後,連接才釋放。當併發用戶很多時,會影響數據庫的性能,因此,這對數據庫的性能提出了更高的要求;

 

3、使cookie維持會話有賴客戶端的支持。

 

各種方式的選擇:

 

     雖然cookie可用來實現購物車,但必須獲得瀏覽器的支持,再加上它是存儲在客戶端的信息,極易被獲取,所以這也限制了它存儲更多,更重要的信息。所以一般cookie只用來維持與服務器的會話,例如國內最大的當當網絡書店就是用cookie保持與客戶的聯繫,但是這種方式最大的缺點是如果客戶端不支持cookie就會使購物車失效。

 

     Session 能很好地與交易雙方保持會話,可以忽視客戶端的設置。在購物車技術中得到了廣泛的應用。但session的文件屬性使其仍然留有安全隱患。

 

結合數據庫的方式雖然在一定程度上解決了上述的問題,但從上面的例子可以看出:在這種購物流程中涉及到對數據庫表的頻繁操作,尤其是用戶每選購一次商品,都要與數據庫進行連接,當用戶很多的時候就加大了服務器與數據庫的負荷。

 

 

56.redis消息隊列先進先出需要注意什麼
   通常使用一個list來實現隊列操作,這樣有一個小限制,所以的任務統一都是先進先出,如果想優先處理某個任務就不太好處理了,這就需要讓隊列有優先級的概念,我們就可以優先處理高級別的任務,實現方式有以下幾種方式:

   1)單一列表實現:隊列正常的操作是 左進右出(lpush,rpop)爲了先處理高優先級任務,在遇到高級別任務時,可以直接插隊,直接放入隊列頭部(rpush),這樣,從隊列頭部(右側)獲取任務時,取到的就是高優先級的任務(rpop)

   2)使用兩個隊列,一個普通隊列,一個高級隊列,針對任務的級別放入不同的隊列,獲取任務時也很簡單,redis的BRPOP命令可以按順序從多個隊列中取值,BRPOP會按照給出的 key 順序查看,並在找到的第一個非空 list 的尾部彈出一個元素,redis> BRPOP list1 list2 0

list1 做爲高優先級任務隊列
list2 做爲普通任務隊列

這樣就實現了先處理高優先級任務,當沒有高優先級任務時,就去獲取普通任務

方式1最簡單,但實際應用比較侷限,方式3可以實現複雜優先級,但實現比較複雜,不利於維護

方式2是推薦用法,實際應用最爲合適

57 、你負責的模塊有哪些難題
    在我負責的B2B電商項目中,當時我負責的是訂單模塊,由於客戶一次選擇了多家商戶的商品,最終生成了一個訂單,這樣我們平臺在給商戶結算時出現了不知道這比費用應該給哪個商戶,這時候我們小組經過討論,需要涉及到訂單拆分,也就是說用戶點擊支付後,如果有多件商品,並且不是同一家店鋪那麼 就要用到訂單的拆分,比如如果有兩件商品,並且不是同一店鋪 就在原來的訂單號下 在生成兩個子訂單號 並修改訂單表中兩件商品的訂單號。最終實現了商品的分配管理,解決了我們的難題。

    我覺得在開發過程中,遇到的難題無非是兩個,一個是技術層次的,我認爲,只要你有恆心,有熱心,沒有覺得不了的難題。另一個就是溝通問題,在任何地方任何時候溝通都是最重要的,尤其是我們做開發的,不溝通好,會影響整個項目的進度,我本人是個非常還溝通的人,所以這點上也沒多大問題。

58、 用戶下單是怎麼處理的
  判斷用戶有沒有登錄,在沒有登錄的情況下,不允許下單。登陸後,可進行下單

  並生成唯一的訂單號,此時訂單的狀態爲未支付。

 

59 、電商的登錄是怎麼登錄的
  分爲普通登錄和第三方登錄 這邊主要說一下第三方登錄吧,第三方登陸主要使用的是author協議,我就以QQ的第三方登陸爲例來進行說明:當用戶在我們的站點請求QQ的第三方登陸時,我們站點會引導用戶跳轉到QQ的登陸授權界面, 當用戶輸入QQ和密碼成功登錄以後會自動跳回到我們站點設置好的回調頁面,並附帶一個code參數,接着你使用code再次去請求QQ的授權頁面,就可以從中獲取到一個access token(訪問令牌),通過這個access_token,我們可以調用QQ提供給我們的接口,比如獲取open_id,可以獲取用戶的基本信息。獲取到之後,我們需要拿用戶的授權信息和open_id和我們平臺的普通用戶進行綁定。這樣不管是普通用戶登陸還是第三方登陸用戶,都可以實現登陸。

60 、有負責開發app嗎
     我以前有過使用 hybrid APP開發過APP,做過一個簡單的廣場舞APP,但我主要參與到APP的接口編寫這塊中。

61 、開發app過程中遇到了什麼難題
     hybrid APP開發過程中,前端知識是我的硬傷,以前,前端我一直都沒有花太多精力在上面,所以在使用hybrid APP 開發過程中,頁面樣式總是調得很難看,後面我花了一週時間自己自學惡補了以下前端的東西,感覺收穫很大。還有我記得以前在公司寫接口時,我們的安卓工程師認爲他們APP的分頁效果,得我們接口這邊事先分好頁,然後他們再調用接口,其實分頁的頁碼需要他那邊提供給我們,但是他就認定了是我們這邊的問題,後面經過多次溝通和測試,我們共同完成了這項任務。

62 、linux殺死一個進程命令是什麼
    首先,我們得知道要殺死的進程的進程ID,可以通過ps -ef | grep 進程名稱 查到當前運行的進程ID,然後通過kill命令殺死進程 ,如 kill  -9  3329 表示強制殺死進程,當然還有不同的等級,取決於中間的數字。

63 、redis 常用的數據類型

  Redis 的數據類型主要有:

     string:字符串類型,可以包含任何數據。包括jpg圖片或者序列化的對象。裏面的incr方法可以實現網站計數器功能,每次訪問一個就可以進行加1操作。降低了數據庫的壓力。

     list:是一個雙向鏈表,通過push,pop操作從鏈表的頭部或者尾部添加刪除元素。

這使得list既可以用作棧,也可以用作隊列。比如可以獲取最新添加的10個商品,獲取最新的登陸的10個信息,做商品的秒殺等等。都可以通過鏈表中的隊列來實現,極大節省了各方面的資源。

     hash:hash數據類型是redis模仿數據庫把一條記錄信息給存儲起來,這樣可以把數據庫中的每一條記錄保存在hash中,作爲緩存處理,非常接近於數據庫的操作。

     set :set是string類型的無序集合。set集合類型除了基本的添加刪除操作,其他有用的操作還包含集合的取並集(union),交集(intersection),差集(difference)。通過這些操作可以很容易的實現sns中的好友推薦功能。比如qq好友推薦、微博系統的關注關係使用

     sorted set:和set一樣sorted set也是string類型元素的集合,不同的是每個元素都會關聯一個權。通過權值可以有序的獲取集合中的元素,它的適用場合如:獲得熱門帖子(回覆量)信息,根據學生成績排序獲得信息等.

    簡單說下無序集合、有序集合、鏈表三者的主要區別:

set類型:集合類型、內部元素沒有順序,同一個集合沒有重複元素

list鏈表類型:內部元素有彼此的先後順序,同一個鏈表允許有重複元素

Sort set類型:排序集合類型,相比set類型有排序功能

64 、你是如何測試網站的性能的
   常用的網站性能測試有:壓力測試,負載測試,容量測試,併發性能測試,兼容性測試(不同的操作系統和不同的瀏覽器)。在項目正式上線前,我們技術部會使用壓力測試工具來測試網站的性能(我們主要是進行壓力測試的)。我主要用過兩款軟件:一個apache自帶的ab壓力測試工具,這個測試的最大併發量相對較小,一般1000左右就會出現請求拒絕。另一個軟件是webbench,這個軟件首先得安裝,最大併發可以到3W。當然還有一些其他的專業的測試工具,如國外的 Page Speed Online、Pingdom Tools等等,我們公司有專門的測試部,我們會配合他們完成測試工作。

65.ab命令參數是什麼
ab.exe  -n  5000  -c 50  http://www.test.com/index.php   

-n是總的執行次數,-c 併發的次數, http://www.test.com/index.php要執行的文件

66、接口安全方面是怎麼處理的
   我們當時是這麼做的,使用HTTP的POST方式,對固定參數+附加參數進行數字簽名,使用的是md5加密,比如:我想通過標題獲取一個信息,在客戶端使用 信息標題+日期+雙方約定好的一個key通過md5加密生成一個簽名(sign),然後作爲參數傳遞到服務器端,服務器端使用同樣的方法進行校驗,如何接受過來的sign和我們通過算法算的值相同,證明是一個正常的接口請求,我們纔會返回相應的接口數據。

67、用的什麼技術實現短信發送,在哪調用
  我主要用的第三方短信接口,在申請接口時進行相應信息的配置,然後在我們站點需要用到短信驗證的地方進行調用,我們通常在用戶註冊時使用到。

68、上一家公司用的什麼框架寫的項目,還接觸過什麼框架?
   我的上一家公司主要使用的是XXX框架,我對該框架非常熟悉,我們公司在該框架上做了一些相應的擴展,引入了一些自己編寫的類庫文件和插件庫。我以前還使用過yii2,ci、laravel框架,以前還自己封裝過MVC框架。一個新的框架掌握起來很容易,你只要抓住其中的幾個點,比如路由規則、MVC、數據庫相關的操作,其他的都可以查手冊,孰能生巧,通過一個小項目就可以把框架用得很熟,當然框架底層的東西,我們還是得用一些好的IDE工具去追它的底層源碼。

69、在工作中遇到什麼困難?
   總體來說:在工作我主要遇到這幾個問題比較難處理:

   ①我之前工作的時候發現經常會出現一些臨時需求打亂了我的計劃,搞得有時候這個任務還沒完成,又得去做其他的任務,最後一天下來,大大小小的東西是很多,但是沒有完成得非常好的,後面我總結了一下,我會把這些都添加優先級,遇到臨時需求,按照優先級重新將已有任務和臨時任務進行排版,保證在規定時間內有效率的完成優先級高的任務。

  ②在做項目需求時候,遇到理解能力欠佳的人,溝通時容易被氣到,影響自己的情緒,最後反倒還不能到達需要的效果。後面,每次到這種時候,我一般會藉助一些紙質的、更加形象的東西,讓雙方都認同的、都能明白的一種方式來進行溝通,後面減少了很多不必須的麻煩。大家都知道,對於程序員來說,改需求是一件很痛苦的事情,所以前期的溝通工作很重要。

 ③還有一件事時,我以前的領導不太懂技術,所以每次出一個新的需求出來,總是要求我們在很短的時間內完成,完不成我們就會被懷疑能力有問題。當然,每個領導都希望自己的員工能夠儘快的完成任務,降低成本,提高效率。這時候我會把我們的需求細化,把其中的重點、難點都列出來,做好時間規劃,耐心的跟領導溝通,項目每個點的重要性和時間的花費比例,確保在這個規劃的時間點內保質保量的完成任務。慢慢的也得到了領導的認可,其實領導也不是一味的不通情理,只要把東西計劃好了,以最小的代價換取最高的價值,每個人都是很容易理解得。

70、Memcache緩存機制 以及分佈式
Memcached是一個高性能的分佈式內存對象緩存系統。目前全世界不少人使用這個緩存項目來構建自己大負載的網站,來分擔數據庫的壓力,通過在內在裏維護一個統一的巨大的的hash表,它能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等,簡單的說就是將數據調用到內存中,然後從內存中讀取,從而大大提高讀取速度。

 傳統的查詢方法是直接查詢數據庫,數據庫將結果返回給查詢語句,而當有Memcache中間緩存層時,查詢的是Memcache緩存數據,下面詳細瞭解Memcache各類數據操作原理:

1. 查詢數據(select),首先通過指定的Key查詢(get)Memcache中間緩存層數據,如果存在相對應數據,則直接獲取出數據結果,查詢過程完全不需要查詢數據庫。如果不存在,則查詢MySQL數據庫,並以key對應value的形式將查詢結果存儲在Memcache緩存數據中,然後將結果返回給查詢語句。
2. 更新數據(update),首先更新數據,然後刪除相關的memcache數據(delete)。
3. 增加數據(add),首先刪除相關緩存數據,然後增加數據。
4. 刪除數據(delete),刪除數據,並刪除Memcache數據。

 

memcache的應用場景有:

 1.如果是一個小網站,pv值不大,就不考慮使用memcached
 2.變化頻繁,查詢頻繁,但是不一定寫入數據庫(適合memcached)(用戶在線狀態)
 3.變化頻繁,一變化就要入庫(比如股票,金融)不適合memcached
 4.變化不頻繁,查詢頻繁,不管入不入庫,都比較適合memcache,(新浪的新聞頻道)

    分佈式是指將不同的業務分佈在不同的地方(幾臺服務器)。 而集羣指的是將幾臺服務器集中在一起,實現同一業務。
分佈式中的每一個節點,都可以做集羣。 而集羣並不一定就是分佈式的。

舉例:就比如新浪網,訪問的人多了,他可以做一個集羣,前面放一個響應服務器,後面幾臺服務器完成同一業務,如果有業務訪問的時候,響應服務器看哪臺服務器的負載不是很重,就交給哪一臺去完成。而分佈式,從窄意上理解,也跟集羣差不多,但是它的組織比較鬆散,不像集羣,有一個組織性,一臺服務器垮了,其它的服務器可以頂上來。memcache的分佈式算法取決於客戶端,主要用取餘算法和一致性哈希算法。

71、 直播是怎麼實現的?
   ①直播視頻從技術架構角度主要分爲三個部分:

     直播視頻採集SDK=>直播CDN(也即直播流分發加速)=》直播視頻播放器SDK

  ②音視頻處理的一般流程:

   數據採集→數據編碼→數據傳輸(流媒體服務器) →解碼數據→播放顯示

1、數據採集:攝像機及拾音器收集視頻及音頻數據,此時得到的爲原始數據,要用到攝像機和拾音器。

2、數據編碼:使用相關硬件或軟件對音視頻原始數據進行編碼處理(數字化)及加工(如音視頻混合、打包封裝等),得到可用的音視頻數據,編碼的方式:CBR、VBR,編碼格式分爲音頻和視頻,音頻一般有MP3、OGG、AAC,視頻一般有TS、MKV、AVI、MP4等。

3、數據傳輸:將編碼完成後的音視頻數據進行傳輸,早期的音視頻通過同軸電纜之類的線纜進行傳輸,IP網絡發展後,使用IP網絡優傳輸

涉及技術或協議:

傳輸協議:RTP與RTCP、RTSP、RTMP、HTTP、HLS(HTTP Live Streaming)等

控制信令:SIP和SDP、SNMP等

4、解碼數據:

使用相關硬件或軟件對接收到的編碼後的音視頻數據進行解碼,得到可以直接顯示的圖像/聲音

涉及技術或協議:

一般對應的編碼器都會帶有相應的解碼器,也有一些第三方解碼插件等

5、播放顯示:

在顯示器(電視、監視屏等)或揚聲器(耳機、喇叭等)裏,顯示相應的圖像畫面或聲音

涉及技術或協議:

顯示器、揚聲器、3D眼鏡等

72 、用戶不登錄,怎麼直接加入購物車的
    用戶在不登錄的情況下,可以把要購買商品的信息(如商品的ID,商品的價格、商品的sku_id,購買數量等關鍵數據)存到COOKIE裏面,當登陸的情況下。把COOKIE裏面的內容存到數據庫,並清除cookie中的數據。

73、寫過接口嗎,怎麼定義接口的
答案:寫過。接口分爲兩種:一種是數據型接口,一種是應用型接口。

   數據型接口:是比抽象類更抽象的某種“結構”——它其實不是類,但是跟類一樣的某種語法結構,是一種結構規範,規範我們類要以什麼格式進行定義,一般用於團隊比較大,分支比較多的情況下使用。

   應用型接口: API(application interface) 數據對外訪問的一個入口

   我主要是參與的APP開發中接口的編寫,客戶端需要什麼樣的數據,我們就給他們提供相應的數據,數據以json/xml的格式返回,並且配以相應的接口文檔。

 

74、靜態化如何實現的
答:這裏要說的靜態化指的是頁面靜態化,也即生成實實在在的靜態文件,也即不需要查詢數據庫就可以直接從文件中獲取數據,指的是真靜態。它的實現方式主要有兩種:

   一種是我們在添加信息入庫的時候就生成的靜態文件,也稱爲模板替換技術,這種主要用在後臺,用於一些基本上很少變化的信息上,在添加信息的時候使用添加的信息來替換制定好的模板中的內容,達到生成靜態文件的目的,這樣在前臺訪問該信息時,可以直接從生成好的靜態文件中獲取信息,如一些CMS系統。

   另外一種是用戶在訪問我們的頁面時先判斷是否有對應的緩存文件存在,如果存在就讀緩存,不存在就讀數據庫,同時生成緩存文件。這種實現的主要原理是基於PHP中的ob緩衝技術來實現的,當沒有靜態文件時,從數據庫中讀取,讀取的數據使用OB緩存,使用相關的函數從OB緩衝中讀取數據,寫入到文件中,形成靜態文件。當然這個過程中要考慮靜態文件的緩存週期問題,我們可以根據文件的最後修改時間和當前時間及設定的緩存時間來定時更新緩存文件。

75、僞靜態如何實現的
答:僞靜態不是真正意義上的靜態化,之所以使用僞靜態,主要是爲了SEO推廣,搜索引擎對動態的文件獲取難度大,不利於網站的推廣。僞靜態的實現原理主要是基於apache/nginx等web服務器的rewrite機制。利用Apache/nginx裏面相關的服務器變量和指令來完成重寫。主要有兩種方式,一種是直接在配置虛擬機的位置配置僞靜態,這個每次修改完成後需要重啓web服務器。另一種採用分佈式的,可以在網站的根目錄上創建.htaccess的文件,在裏面配置相應的重寫規則來實現僞靜態,這種每次重寫時不需要重啓web服務器,且結構上比較清晰。具體的配置可以參考 Apache/nginx的手冊。

76 、 mysql優化,讀寫分離如何實現?
答:mysql優化前面已經總結了。主要說下讀寫分離,當我們的數據量很大時,數據庫服務器的壓力變大,這時候我們需要從架構方面來解決這一問題,在一個網站中讀的操作很多,寫的操作很少,這時候我們需要配置讀寫分離,把讀操作和寫操作分離出來,最大程度的利用好數據庫服務器。讀寫分離的實現原理就是在執行SQL語句的時候,判斷到底是讀操作還是寫操作,把讀的操作轉向到讀服務器上(從服務器,一般是多臺),寫的操作轉到寫的服務器上(主服務器,一般是一臺,視數據量來看)。當然爲了保證多臺數據庫數據的一致性,需要主從複製。主從複製的實現原理是:mysql中有一種日誌,叫做bin日誌(二進制日誌),會記錄下所有修改過數據庫的sql語句。主從複製的原理實際是多臺服務器都開啓bin日誌,然後主服務器會把執行過的sql語句記錄到bin日誌中,之後從服務器讀取這個bin日誌,把該日誌的內容保存到自己中繼日誌裏面,從服務器再把中繼日誌中記錄的sql語句同樣的執行一遍。這樣從服務器上的數據就和主服務器相同了。

 

77、sku減庫存
    SKU = Stock Keeping Unit (庫存量單位)   
即庫存進出計量的單位,可以是以件,盒,托盤等爲單位。SKU是庫存量單位,區分單品。   
在服裝、鞋類商品中使用最多最普遍。 例如紡織品中一個SKU通常表示:規格、顏色、款式。

在設計表時,不僅僅只有商品表,商品表中有個總庫存,我們還需要涉及一張SKU表,裏面有SKU庫存和單價字段,用戶每購買一件商品,實際上購買的都是SKU商品,這樣在下訂單成功後,應該根據所購買的商品的唯一的SKU號來進行相應的SKU庫存的減少,當然商品的總庫存保存在商品主表中,也需要減少總庫存中的庫存量。

 

78 、Linux查看日誌
   Linux日誌文件一般在/var/log目錄下,通過查看日誌,我們可以看到Linux系統內核和許多程序會產生各種錯誤信息、警告信息和提示信息,這些信息對於管理員瞭解系統的運營狀態是非常有用的,這些信息都被保存在相應的日誌文件中。syslog是一個歷史悠久的日誌系統,幾乎所有的UNIX和Linux操作系統都是採用syslog進行系統日誌的管理和配置。在默認的syslog配置下,日誌文件通常都保存在“/var/log”目錄下。默認配置的syslog日誌如下:

 

我們可以通過下面幾個命令分別進行查看:

 

1、cat命令:

     功能:1)顯示整個文件。

          2)把文件串連接後傳到基本輸出,如將幾個文件合併爲一個文件或輸出到屏幕。

2、more命令:

     以百分比的形式查看日誌。  

3、less命令:

     跟more功能差不多,只不過less支持前後翻閱文件。

4、head命令:

     功能:從文本文件的頭部開始查看,head 命令用於查看一個文本文件的開頭部分。

5、tail命令:

     功能:tail 命令用於顯示文本文件的末尾幾行。

79、庫存設置?
    庫存分爲商品總庫存和SKU庫存,往往商品總庫存的爲SKU庫存的總和。一般在商城的後臺對貨品設置最高庫存及最低庫存後,當前庫存數量與最高、最低兩者比較,超出庫存或者低於庫存的,則被統計成報表形式反映,便於用戶掌握貨品庫存超、短缺狀態及數量。

80、訂單、庫存兩個表 如何保證數據的一致性?
     在一個電子商務系統中,正常的應該是訂單生成成功後,相應的庫存進行減少。必須要保證兩者的一致性,但有時候因爲某些原因,比如程序邏輯問題,併發等問題,導致下單成功而庫存沒有減少的情況。這種情況我們是不允許發生的,MySQL中的事務剛好可以解決這一問題,首先得選擇數據庫的存儲引擎爲innoDB,事務規定了只有下訂單完成了,並且相應的庫存減少了才允許提交事務,否則就事務回滾,確保數據一致性。

 81、O2O  用戶下單  c端下單  如何保證b a端 數據一致  O2O爲線上和線下模式, O2O模式奉行的是“線上支付+實體店消費”的消費模式,即消費者在網上下單完成支付後,憑消費憑證到實體店消費。O2O模式是把商家信息和支付程序放在線上進行,而把商品和服務兌現放在線下,也就是說O2O模式適用於快遞無法送達的有形產品。數據一致性的問題是O2O行業中最常見的問題,我們可以類似於數據庫的主從複製的思路來解決這個問題。O2O有個供應商系統,類似於主服務器,在C端(從服務器)下單時,數據同步更新到供應商系統端,b、a實時從供應商系統中拉取數據進行同步,比如利用定時任務,定時拉取數據進行同步。
82 、Redis 如何防止高併發
其實redis是不會存在併發問題的,因爲他是單進程的,再多的command都是one by one執行的。我們使用的時候,可能會出現併發問題,比如get和set這一對。

redis爲什麼會有高併發問題

redis的出身決定 

   Redis是一種單線程機制的nosql數據庫,基於key-value,數據可持久化落盤。由於單線程所以redis本身並沒有鎖的概念,多個客戶端連接並不存在競爭關係,但是利用jedis等客戶端對redis進行併發訪問時會出現問題。發生連接超時、數據轉換錯誤、阻塞、客戶端關閉連接等問題,這些問題均是由於客戶端連接混亂造成。

 

同時,單線程的天性決定,高併發對同一個鍵的操作會排隊處理,如果併發量很大,可能造成後來的請求超時。

在遠程訪問redis的時候,因爲網絡等原因造成高併發訪問延遲返回的問題。

解決辦法

在客戶端將連接進行池化,同時對客戶端讀寫Redis操作採用內部鎖synchronized。

服務器角度,利用setnx變向實現鎖機制。
85 、 秒殺當中的細節你是怎麼得出來的
   通過性能測試及模擬秒殺場景。每個問題都經過反覆測試,不斷的發現問題,不斷的解決。

86 、開源產品的弊端
   很多公司爲了快速的開發出一款產品,降低成本,往往會採用一些開源的產品來完成,一款好的開源產品可以起到事半功倍的效果,我們只需要在它的基礎上做些二次開發,就可以達到我們想要的簡單的效果。但是,往往這些開源產品也有自己的弊端。

      比如我以前用過的ecshop:產品線不完整,只有單用戶產品,後臺操作過於煩雜,無用功能比較多,使用起來有很多BUG和不便,系統功能相對薄弱,運營起來很費人力成本。被商派收購之後,宣傳推廣也停滯不前。而且是面向過程的,你必須按照它的規則進行修改,操作起來相對很繁瑣。對PHP5.4以上的版本支持不好,jQuery的兼容性上要好好處理。

      PHPCMS:靜態處理不好,SEO有待加強,訪問速度也較慢。

      Shopex:代碼不開源,修改很麻煩,只能通過插件的方式去改進,底層是不知道的,有漏洞更新也是很慢,當數量達到一定量的時候shopex很吃內存服務質量也不好,基本用戶提的意見,很難被有效採取。最頭疼的是他的後臺操作,易用性很差,前臺模板也不好看。並且系統各方面的壓力承受能力都有不足。

系統出了問題也只能等待解決,有受制於人的感覺。

      總之,使用別人成型的東西,就要遵循別人的規範,責任在於自己。

87 、做秒殺用什麼數據庫,怎麼實現的。
   因爲秒殺的一瞬間,併發非常大,如果同時請求數據庫,會導致數據庫的壓力非常大,導致數據庫的性能急劇下降,更嚴重的可能會導致數據庫服務器宕機。這時候一般採用內存高速緩存數據庫redis來實現的,redis是非關係型數據庫,redis是單線程的,通過redis的隊列可以完成秒殺過程。
88 、支付寶流程怎麼實現的
   首先要有一個支付寶賬號,接下來向支付寶申請在線支付業務,簽署協議。協議生效後有支付寶一方會給網站方一個合作伙伴ID,和安全校驗碼,有了這兩樣東西就可以按照支付寶接口文檔開發支付寶接口了,中間主要涉及到一個安全問題。整個流程是這樣的:我們的網站通過post傳遞相應的參數(如訂單總金額,訂單號)到支付頁面,支付頁面把一系列的參數經過處理,以post的方式提交給支付寶服務器,支付寶服務器進行驗證,並對接收的數據進行處理,把處理後的結果返回給我們網站設置的異步和同步回調地址,通過相應的返回參數,來處理相應的業務邏輯,比如返回的參數代表支付成功,更改訂單狀態。

89、什麼是單點登錄?
   單點登錄SSO(Single Sign On)說得簡單點就是在一個多系統共存的環境下,用戶在一處登錄後,就不用在其他系統中登錄,也就是用戶的一次登錄能得到其他所有系統的信任。

什麼情況下使用緩存

當用戶第一次訪問應用系統的時候,因爲還沒有登錄,會被引導到認證系統中進行登錄;根據用戶提供的登錄信息,認證系統進行身份校驗,如果通過校驗,應該返回給用戶一個認證的憑據--ticket;用戶再訪問別的應用的時候,就會將這個ticket帶上,作爲自己認證的憑據,應用系統接受到請求之後會把 ticket送到認證系統進行校驗,檢查ticket的合法性。如果通過校驗,用戶就可以在不用再次登錄的情況下訪問應用系統2和應用系統3了。

   實現主要技術點:

   1、兩個站點共用一個數據驗證系統

   2、主要通過跨域請求的方式來實現驗證及session處理。

90、怎麼實現第三方登錄?
    第三方登陸主要是基於author協議來實現,下面簡單說下實現流程:

1、首先我們需要以開發者的身份向第三方登陸平臺申請接入應用,申請成功後,我們會獲得一個appID和一個secrectID.

2、當我們的網站需接入第三方登陸時,會引導用戶跳轉到第三方的登陸授權頁面,此時把之前申請的appID和secrectID帶給登陸授權頁面。

3、用戶登陸成功後即得到授權,第三方會返回一個臨時的code給我們的網站。

4、我們的網站接受到code後,再次向我們的第三方發起請求,並攜帶接收的code,從第三方獲取access_token.

5、第三方處理請求後,會返回一個access_token給我們的網站,我們的網站獲取到access_token後就可以調用第三方提供的接口了,比如獲取用戶信息等。最後把該用戶信息存入到我們站點的數據庫,並把信息保存到session中,實現用戶的第三方登陸。

91、壓力測試是在什麼環境下做的?
     環境分爲開發環境和線上環境,我們做測試是在開發環境上進行測試的,只有測試通過了纔會上線。

92、App數據是怎麼來的
     APP數據是客戶端傳遞相應的參數調用服務器端的接口,服務器端從數據庫或者緩存數據從讀取數據轉換爲XML/json數據,提供給APP端。

93、如何處理負載、高併發?(好好看看,經常問到,能回答到主要的東西即可)
  從低成本、高性能和高擴張性的角度來說有如下處理方案:

1、HTML靜態化

其實大家都知道,效率最高、消耗最小的就是純靜態化的html頁面,所以我們儘可能使我們的 網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。

2、圖片服務器分離

        把圖片單獨存儲,儘量減少圖片等大流量的開銷,可以放在一些相關的平臺上,如騎牛等

3、數據庫集羣和庫表散列及緩存

       數據庫的併發連接爲100,一臺數據庫遠遠不夠,可以從讀寫分離、主從複製,數據庫集羣方面來着手。另外儘量減少數據庫的訪問,可以使用緩存數據庫如memcache、redis。

4、鏡像:

       儘量減少下載,可以把不同的請求分發到多個鏡像端。

5、負載均衡:

   Apache的最大併發連接爲1500,只能增加服務器,可以從硬件上着手,如F5服務器。當然硬件的成本比較高,我們往往從軟件方面着手。

   負載均衡 (Load Balancing) 建立在現有網絡結構之上,它提供了一種廉價有效透明的方法擴展網絡設備和服務器的帶寬、增加吞吐量、加強網絡數據處理能力,同時能夠提高網絡的靈活性和可用性。目前使用最爲廣泛的負載均衡軟件是Nginx、LVS、HAProxy。我分別來說下三種的優缺點:

 Nginx的優點是:

1. 工作在網絡的7層之上,可以針對http應用做一些分流的策略,比如針對域名、目錄結構,它的正則規則比HAProxy更爲強大和靈活,這也是它目前廣泛流行的主要原因之一,Nginx單憑這點可利用的場合就遠多於LVS了。 

2. Nginx對網絡穩定性的依賴非常小,理論上能ping通就就能進行負載功能,這個也是它的優勢之一;相反LVS對網絡穩定性依賴比較大,這點本人深有體會; 

3. Nginx安裝和配置比較簡單,測試起來比較方便,它基本能把錯誤用日誌打印出來。LVS的配置、測試就要花比較長的時間了,LVS對網絡依賴比較大。 

4. 可以承擔高負載壓力且穩定,在硬件不差的情況下一般能支撐幾萬次的併發量,負載度比LVS相對小些。 

5. Nginx可以通過端口檢測到服務器內部的故障,比如根據服務器處理網頁返回的狀態碼、超時等等,並且會把返回錯誤的請求重新提交到另一個節點,不過其中缺點就是不支持url來檢測。比如用戶正在上傳一個文件,而處理該上傳的節點剛好在上傳過程中出現故障,Nginx會把上傳切到另一臺服務器重新處理,而LVS就直接斷掉了,如果是上傳一個很大的文件或者很重要的文件的話,用戶可能會因此而不滿。 

6. Nginx不僅僅是一款優秀的負載均衡器/反向代理軟件,它同時也是功能強大的Web應用服務器。LNMP也是近幾年非常流行的web架構,在高流量的環境中穩定性也很好。 

7. Nginx現在作爲Web反向加速緩存越來越成熟了,速度比傳統的Squid服務器更快,可以考慮用其作爲反向代理加速器。 

8. Nginx可作爲中層反向代理使用,這一層面Nginx基本上無對手,唯一可以對比Nginx的就只有 lighttpd了,不過 lighttpd目前還沒有做到Nginx完全的功能,配置也不那麼清晰易讀,社區資料也遠遠沒Nginx活躍。 

9. Nginx也可作爲靜態網頁和圖片服務器,這方面的性能也無對手。還有Nginx社區非常活躍,第三方模塊也很多。

Nginx的缺點是:

1. Nginx僅能支持http、https和Email協議,這樣就在適用範圍上面小些,這個是它的缺點。 
2. 對後端服務器的健康檢查,只支持通過端口來檢測,不支持通過url來檢測。不支持Session的直接保持,但能通過ip_hash來解決。

LVS:使用Linux內核集羣實現一個高性能、高可用的負載均衡服務器,它具有很好的可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

LVS的優點是:

1. 抗負載能力強、是工作在網絡4層之上僅作分發之用,沒有流量的產生,這個特點也決定了它在負載均衡軟件裏的性能最強的,對內存和cpu資源消耗比較低。 
2. 配置性比較低,這是一個缺點也是一個優點,因爲沒有可太多配置的東西,所以並不需要太多接觸,大大減少了人爲出錯的機率。 
3. 工作穩定,因爲其本身抗負載能力很強,自身有完整的雙機熱備方案,如LVS+Keepalived,不過我們在項目實施中用得最多的還是LVS/DR+Keepalived。
4. 無流量,LVS只分發請求,而流量並不從它本身出去,這點保證了均衡器IO的性能不會受到大流量的影響。 
5. 應用範圍比較廣,因爲LVS工作在4層,所以它幾乎可以對所有應用做負載均衡,包括http、數據庫、在線聊天室等等。

LVS的缺點是:   

1. 軟件本身不支持正則表達式處理,不能做動靜分離;而現在許多網站在這方面都有較強的需求,這個是Nginx/HAProxy+Keepalived的優勢所在。
2. 如果是網站應用比較龐大的話,LVS/DR+Keepalived實施起來就比較複雜了,特別後面有 Windows Server的機器的話,如果實施及配置還有維護過程就比較複雜了,相對而言,Nginx/HAProxy+Keepalived就簡單多了。

HAProxy的特點是:   

1. HAProxy也是支持虛擬主機的。 
2. HAProxy的優點能夠補充Nginx的一些缺點,比如支持Session的保持,Cookie的引導;同時支持通過獲取指定的url來檢測後端服務器的狀態。 
3. HAProxy跟LVS類似,本身就只是一款負載均衡軟件;單純從效率上來講HAProxy會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的。
4. HAProxy支持TCP協議的負載均衡轉發,可以對MySQL讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,大家可以用LVS+Keepalived對MySQL主從做負載均衡。
5. HAProxy負載均衡策略非常多,HAProxy的負載均衡算法現在具體有如下8種:

① roundrobin,表示簡單的輪詢,這個不多說,這個是負載均衡基本都具備的; 
② static-rr,表示根據權重,建議關注; 
③ leastconn,表示最少連接者先處理,建議關注; 
④ source,表示根據請求源IP,這個跟Nginx的IP_hash機制類似,我們用其作爲解決session問題的一種方法,建議關注; 
⑤ ri,表示根據請求的URI; 
⑥ rl_param,表示根據請求的URl參數’balance url_param’ requires an URL parameter name; 
⑦ hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求; 
⑧ rdp-cookie(name),表示根據據cookie(name)來鎖定並哈希每一次TCP請求。

Nginx和LVS對比的總結:   

1. Nginx工作在網絡的7層,所以它可以針對http應用本身來做分流策略,比如針對域名、目錄結構等,相比之下LVS並不具備這樣的功能,所以Nginx單憑這點可利用的場合就遠多於LVS了;但Nginx有用的這些功能使其可調整度要高於LVS,所以經常要去觸碰觸碰,觸碰多了,人爲出問題的機率也就會大。    

2. Nginx對網絡穩定性的依賴較小,理論上只要ping得通,網頁訪問正常,Nginx就能連得通,這是Nginx的一大優勢!Nginx同時還能區分內外網,如果是同時擁有內外網的節點,就相當於單機擁有了備份線路;LVS就比較依賴於網絡環境,目前來看服務器在同一網段內並且LVS使用direct方式分流,效果較能得到保證。另外注意,LVS需要向託管商至少申請多一個ip來做Visual IP,貌似是不能用本身的IP來做VIP的。要做好LVS管理員,確實得跟進學習很多有關網絡通信方面的知識,就不再是一個HTTP那麼簡單了。

3. Nginx安裝和配置比較簡單,測試起來也很方便,因爲它基本能把錯誤用日誌打印出來。LVS的安裝和配置、測試就要花比較長的時間了;LVS對網絡依賴比較大,很多時候不能配置成功都是因爲網絡問題而不是配置問題,出了問題要解決也相應的會麻煩得多。 

4. Nginx也同樣能承受很高負載且穩定,但負載度和穩定度差LVS還有幾個等級:Nginx處理所有流量所以受限於機器IO和配置;本身的bug也還是難以避免的。 

5. Nginx可以檢測到服務器內部的故障,比如根據服務器處理網頁返回的狀態碼、超時等等,並且會把返回錯誤的請求重新提交到另一個節點。目前LVS中 ldirectd也能支持針對服務器內部的情況來監控,但LVS的原理使其不能重發請求。比如用戶正在上傳一個文件,而處理該上傳的節點剛好在上傳過程中出現故障,Nginx會把上傳切到另一臺服務器重新處理,而LVS就直接斷掉了,如果是上傳一個很大的文件或者很重要的文件的話,用戶可能會因此而惱火。 

6. Nginx對請求的異步處理可以幫助節點服務器減輕負載,假如使用 apache直接對外服務,那麼出現很多的窄帶鏈接時apache服務器將會佔用大 量內存而不能釋放,使用多一個Nginx做apache代理的話,這些窄帶鏈接會被Nginx擋住,apache上就不會堆積過多的請求,這樣就減少了相當多的資源佔用。這點使用squid也有相同的作用,即使squid本身配置爲不緩存,對apache還是有很大幫助的。 

7. Nginx能支持http、https和email(email的功能比較少用),LVS所支持的應用在這點上會比Nginx更多。在使用上,一般最前端所採取的策略應是LVS,也就是DNS的指向應爲LVS均衡器,LVS的優點令它非常適合做這個任務。重要的ip地址,最好交由LVS託管,比如數據庫的 ip、webservice服務器的ip等等,這些ip地址隨着時間推移,使用面會越來越大,如果更換ip則故障會接踵而至。所以將這些重要ip交給 LVS託管是最爲穩妥的,這樣做的唯一缺點是需要的VIP數量會比較多。Nginx可作爲LVS節點機器使用,一是可以利用Nginx的功能,二是可以利用Nginx的性能。當然這一層面也可以直接使用squid,squid的功能方面就比Nginx弱不少了,性能上也有所遜色於Nginx。Nginx也可作爲中層代理使用,這一層面Nginx基本上無對手,唯一可以撼動Nginx的就只有lighttpd了,不過lighttpd目前還沒有能做到 Nginx完全的功能,配置也不那麼清晰易讀。另外,中層代理的IP也是重要的,所以中層代理也擁有一個VIP和LVS是最完美的方案了。具體的應用還得具體分析,如果是比較小的網站(日PV小於1000萬),用Nginx就完全可以了,如果機器也不少,可以用DNS輪詢,LVS所耗費的機器還是比較多的;大型網站或者重要的服務,機器不發愁的時候,要多多考慮利用LVS。

數據庫優化

96、做秒殺時鎖表考慮到沒有?
考慮到了,當時我們做秒殺時考慮了好幾種方案,其中有一種就是使用事務加上排他鎖來實現。

架構類的東西接觸過嗎?

  有接觸過,曾經自己在自己的服務器上配置過。我以前做過以下幾個架構方面的配置和測試;

   1、數據庫的讀寫分離、主從複製及集羣。

   2、Nginx負載均衡

   3、redis集羣及主從

97、封裝過一個簡單的框架
封裝過一個簡單的MVC框架,主要分爲3層,控制器層和模型層視圖層,以及路由的分配和入口文件,模板引擎,單例模式、工廠模式,第三方類庫的引入等。

98、你做過多大的壓力測試
    我在開發環境下,通過ab壓力和webbench做過相關的壓力測試,當Apache最大到1000併發時,發現請求超時或者服務器積極拒絕。webbench併發到3000時,請求非常慢,5000時,服務器積極拒絕。

99、開發商城有什麼前景?
商城創業服務平臺,將創業者進行整合,將線下商家搬到線上,使線上商家擺脫地理位置的限制,降低推廣成本,通過商城平臺從線上快速引流,以全新的方式開展營銷策略。線上交易數據可查,永久保存,商家通過平臺交易行爲加以分析,進行開展二次營銷,多次營銷,深度挖掘幼稚客戶,培養忠實客戶。

2.商城創業服務平臺憑着創新的模式,將帶領廣大創業者咋移動互聯網,O2O電商模式的大浪中殺出重圍,取得成功!

100.談談對MVC的認識
  核心思想是:視圖和用戶交互通過事件導致控制器改變 控制器改變導致模型改變 或者控制器同時改變兩者 模型改變 導致視圖改變 或者視圖改變 潛在的從模型裏面獲得參數 來改變自己。他的好處是可以將界面和業務邏輯分離。

Model(模型),是程序的主體部分,主要包含業務數據和業務邏輯。在模型層,還會涉及到用戶發佈的服務,在服務中會根據不同的業務需求,更新業務模型中的數據。
View(視圖),是程序呈現給用戶的部分,是用戶和程序交互的接口,用戶會根據具體的業務需求,在View視圖層輸入自己特定的業務數據,並通過界面的事件交互,將對應的輸入參數提交給後臺控制器進行處理。
Contorller(控制器),Contorller是用來處理用戶 輸入數據,已經更新業務模型的部分。控制器中接收了用戶與界面交互時傳遞過來的數據,並根據數據業務邏輯來執行服務的調用和更新業務模型的數據和狀態。

101、session與cookie的區別
1、cookie數據存放在第三方應用的瀏覽器上,session數據放在服務器上。

2、cookie不是很安全,別人可以分析存放在本地的COOKIE,進行COOKIE欺騙
   考慮到安全應當使用session。

3、session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
   考慮到減輕服務器性能方面,應當使用COOKIE。

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

5、所以個人建議:
   將登陸信息等重要信息存放爲SESSION
   其他信息如果需要保留,可以放在COOKIE

102、echo(),print(),print_r()的區別
echo可以一次輸出多個值,多個值之間用逗號分隔。echo是語言結構(language construct),而並不是真正的函數,因此不能作爲表達式的一部分使用。echo是php的內部指令,不是函數,無返回值。

print():函數print()打印一個值(它的參數),如果字符串成功顯示則返回true,否則返回false。只能打印出簡單類型變量的值(如int,string),有返回值

printf():源於C語言中的printf()。該函數輸出格式化的字符串。

print_r()和var_dump()
print_r()可以把字符串和數字簡單地打印出來,而數組則以括起來的鍵和值得列表形式顯示,並以Array開頭。但print_r()輸出布爾值和NULL的結果沒有意義,因爲都是打印"\n"。因此用var_dump()函數更適合調試。print_r是函數,可以打印出比較複雜的變量(如數組,對象),有返回值
var_dump()判斷一個變量的類型與長度,並輸出變量的數值,如果變量有值輸的是變量的值並回返數據類型。此函數顯示關於一個或多個表達式的結構信息,包括表達式的類型與值。數組將遞歸展開值,通過縮進顯示其結構。

103、 說一下單引號雙引號?
  ①單引號內部的變量不會執行, 雙引號會執行

  ②單引號解析速度比雙引號快。

  ③單引號只能解析部分特殊字符,雙引號可以解析所有特殊字符。

104、索引的優缺點
1、優點:

a)可以保證數據庫表中每一行的數據的唯一性

b)可以大大加快數據的索引速度

c)加速表與表之間的連接,物別是在實現數據的參考完事性方面特別有意義

d)在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間

f)通過使用索引,可以在時間查詢的過程中,使用優化隱藏器,提高系統的性能

2、缺點:

創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加

索引需要佔物理空間,除了數據表佔用數據空間之外,每一個索引還要佔用一定的物理空間,如果需要建立聚簇索引,那麼需要佔用的空間會更大

以表中的數據進行增、刪、改的時候,索引也要動態的維護,這就降低了整數的維護速度

建立索引的原則

在經常需要搜索的列上,可以加快搜索的速度

在作爲主鍵的列上,強制該列的唯一性和組織表中數據的排列結構

在經常用在連接的列上,這些列主要是一外鍵,可以加快連接的速度

在經經常需要根據範圍進行搜索的列上創建索引,國爲索引已經排序,其指定的範圍是連續的

在經常需要排序的列上,國爲索引已經排序,這樣井底可以利用索引的排序,加快排序井底時間

在經常使用在where子句中的列上,加快條件的判斷速度

105.get和post的區別
1. get是從服務器上獲取數據,post是向服務器傳送數據。
2. get是把參數數據隊列加到提交表單的ACTION屬性所指的URL中,值和表單內各個字段一一對應,在URL中可以看到。post是通過HTTP post機制,將表單內各個字段與其內容放置在HTML HEADER內一起傳送到ACTION屬性所指的URL地址。用戶看不到這個過程。
3. get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,一般被默認爲不受限制。4.. get安全性非常低,post安全性較高。但是執行效率卻比Post方法好。

106.如何修改session的生存時間
一:在php.ini 中設置 session.gc_maxlifetime = 1440 //默認時間
二:代碼實現
$lifeTime = 24 * 3600;  // 保存一天 
session_set_cookie_params($lifeTime); 
session_start();

107.PHP版本差別
PHP5.2 以前:autoload, PDO 和 MySQLi, 類型約束  、JSON 支持
PHP5.3:棄用的功能,匿名函數,新增魔術方法,命名空間,後期靜態綁定Heredoc 和 Nowdoc, const, 三元運算符,Phar
PHP5.4:Short Open Tag, 數組簡寫形式,Traits, 內置 Web 服務器,細節修改
PHP5.5:yield, list() 用於 foreach, 細節修改
PHP5.6: 常量增強,可變函數參數,命名空間增強

108.對稱加密 與 非對稱加密
對稱加密與解密使用的是同樣的密鑰,但由於需要將密鑰在網絡傳輸,所以安全性不高

非對稱加密使用了一對密鑰,公鑰與私鑰,把以安全性高,但加密與解密速度慢

解決的辦法是將對稱加密的密鑰使用非對稱加密的公鑰進行加密,然後發送出去,接收方使用私鑰進行解密得到對稱加密的密鑰,然後雙方可以使用對稱加密來進行溝通

(一)對稱加密(Symmetric Cryptography)

對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的密鑰(secret key),這種方法在密碼學中叫做對稱加密算法。

   採用單鑰密碼系統的加密方法,同一個密鑰可以同時用作信息的加密和解密加密方式DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES

優缺點

對稱加密算法的優點是算法公開、計算量小、加密速度快、加密效率高。

對稱加密算法的缺點是在數據傳送前,發送方和接收方必須商定好祕鑰,然後 使雙方都能保存好祕鑰。其次如果一方的祕鑰被泄露,那麼加密信息也就不安全了。另外,每對用戶每次使用對稱加密算法時,都需要使用其他人不知道的唯一祕 鑰,這會使得收、發雙方所擁有的鑰匙數量巨大,密鑰管理成爲雙方的負擔。

(二)非對稱加密(asymmetric Cryptography)

允許在不安全的媒體上的通訊雙方交換信息,安全地達成一致的密鑰,這就是“公開密鑰系統”。相對於“對稱加密算法”這種方法也叫做“非對稱加密算法”。

非對稱加密算法需要兩個密鑰來進行加密和解密

優缺點

  非對稱加密與對稱加密相比,其安全性更好:對稱加密的通信雙方使用相同的祕鑰,如果一方的祕鑰遭泄露,那麼整個通信就會被破解。而非對稱加密使用一對祕鑰,一個用來加密,一個用來解密,而且公鑰是公開的,祕鑰是自己保存的,不需要像對稱加密那樣在通信之前要先同步祕鑰。

  非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少量數據進行加密。

109.ob系列函數
1、ob_start() //打開緩衝區,所有輸出的信息不直接發送到瀏覽器,而是保存在緩衝區裏面

2、ob_clean() //刪除內部緩衝區的內容,不關閉緩衝區(不輸出)

3、ob_end_clean() //刪除內部緩衝區的內容,關閉緩衝區(不輸出)

4、ob_get_clean() //返回內部緩衝區的內容,關閉緩衝區。【相當於執行ob_get_contents() and ob_end_clean()】

5、ob_flush() //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,不關閉緩衝區。

6、ob_end_flush() //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,關閉緩衝區

7、ob_get_flush() //返回內部緩衝區的內容,並關閉緩衝區的內容

8、ob_get_contents()//返回緩衝區的內容,不輸出

9、ob_get_length() //返回內部緩衝區的長度,如果緩衝區未被激活,該函數返回false

110.Linux基本命令,目錄結構
arch 顯示機器的處理器架構(1) 
uname -m 顯示機器的處理器架構(2) 
uname -r 顯示正在使用的內核版本 
dmidecode -q 顯示硬件系統部件 - (SMBIOS / DMI) 
hdparm -i /dev/hda 羅列一個磁盤的架構特性 
hdparm -tT /dev/sda 在磁盤上執行測試性讀取操作 
cat /porc/cpuinfo 顯示CPU info的信息 
cat /porc/interrupts 顯示中斷 
cat /porc/meminfo 校驗內存使用 
cat /porc/swaps 顯示哪些swap被使用 
cat /porc/verion 顯示內核的版本 
cat /porc/net/dev 顯示網絡適配器及統計 
cat /porc/mounts 顯示已加載的文件系統 

date 顯示系統日期 
cal 2007 顯示2007年的日曆表 
date 041217002007.00 設置日期和時間 -月日時分年.秒 
clock -w 將時間修改保存到 BIOS 

文件搜索 
find / -name file1 從 '/'開始進入根文件系統搜索文件和目錄 

locate \*.ps 尋找以 '.ps'結尾的文件 -先運行'updatedb'命令 
whereis halt 顯示一個二進制文件、源碼或man的位置 
which halt 顯示一個二進制文件或可執行文件的完整路徑 

 

掛載一個文件系統 
mount /dev/hda2 /mnt/hda2 掛載一個叫做hda2的盤- 確定目錄'/ mnt/hda2' 已經存在 
umount /dev/hda2 卸載一個叫做hda2的盤- 先從掛載點'/ mnt/hda2' 退出 


追加命令

1,linux裏把文件/etc/aaa中的內容追加到/usr/bbb中的內容的後面
  sudo cat /etc/aaa >>/usr/bbb
2,更改/etc/index.html的文件所有者爲apache,文件羣組爲apache
  sudo chmod apache:apache  /etc/index.html
3,更改/etc/index.html的所有者權限爲讀取、寫入、執行。羣組權限爲讀取。其他權限爲讀取
  sudo chmod 744 /etc/index.html
4,刪除/etc下名爲hello的文件
  sudo rm /etc/index.html

當然,如果你是以orot用戶執行以上操作,可以去掉前邊的sudo!

 

df -hl 查看磁盤剩餘空間

df -h 查看每個根路徑的分區大小

du -sh [目錄名] 返回該目錄的大小

du -sm [文件夾] 返回該文件夾總M數

關機 (系統的關機、重啓以及登出) 
shutdown -h now 關閉系統(1) 
init 0 關閉系統(2) 
telinit 0 關閉系統(3) 
shutdown -h hour:minutes & 按預定時間關閉系統 
shutdown -c 取消按預定時間關閉系統 
shutdown -r now 重啓(1) 
reboot 重啓(2) 
logout 註銷

文件和目錄 
pwd 顯示工作路徑 
ls 查看目錄中的文件 
ls -F 查看目錄中的文件 
ls -l 顯示文件和目錄的詳細資料 
ls -a 顯示隱藏文件 
ls *[0-9]* 顯示包含數字的文件名和目錄名 
tree 顯示文件和目錄由根目錄開始的樹形結構(1) 
lstree 顯示文件和目錄由根目錄開始的樹形結構(2) 
mkdir dir1 創建一個叫做 'dir1'的目錄' 

磁盤空間 
df -h 顯示已經掛載的分區列表 
ls -lSr |more 以尺寸大小排列文件和目錄 
du -sh dir1 估算目錄 'dir1'已經使用的磁盤空間' 

下載、解壓

1)對於.tar結尾的文件 
  tar -xf all.tar 

2)對於.gz結尾的文件 
  gzip -d all.gz 
  gunzip all.gz 

# zip all.zip *.jpg 
  這條命令是將所有.jpg的文件壓縮成一個zip包 
# unzip all.zip 
  這條命令是將all.zip中的所有文件解壓出來

下載命令

wget + 空格 +要下載文件的url路徑

=====================================

Shell 腳本:

必須以  #!/bin/sh  開頭

簡單例子:判斷這個目錄下有沒有文件(File)

#!/bin/bash
Num=`ls -al /opt |grep "^-"|wc -l `
if [ $Num != 0 ]
 then echo "/opt has $Num files"
else
 echo "/opt has none file"
fi

ls -al /opt |grep "^-"|wc -l  這個命令能夠統計文件個數 爲0就是沒有文件 非零就是有文件

 

111.memcache緩存什麼數據
一、經常被讀取並且實時性要求不強可以等到自動過期的數據。例如網站首頁最新文章列表、某某排行等數據。

二、經常被讀取並且實時性要求強的數據。比如用戶的好友列表,用戶文章列表,用戶閱讀記錄等。

三、統計類緩存,比如文章瀏覽數、網站PV等。

    四、活躍用戶的基本信息或者某篇熱門文章。

    五、session數據

112.魔術方法、魔術常量
1。__construct()
實例化對象時被調用,當__construct和以類名爲函數名的函數同時存在時,__construct將被調用,另一個不被調用。

2。__destruct()

當刪除一個對象或對象操作終止時被調用。

3。__call()
對象調用某個方法,若方法存在,則直接調用;若不存在,則會去調用__call函數。

4。__get()
讀取一個對象的屬性時,若屬性存在,則直接返回屬性值;若不存在,則會調用__get函數。

5。__set()
設置一個對象的屬性時,若屬性存在,則直接賦值;若不存在,則會調用__set函數。

6。__toString()

打印一個對象的時被調用。如echo $obj;或print $obj;

7。__clone()

克隆對象時被調用。如:$t=new Test();$t1=clone $t;

8。__sleep()

serialize之前被調用。若對象比較大,想刪減一點東東再序列化,可考慮一下此函數。

9。__wakeup()

unserialize時被調用,做些對象的初始化工作。

10。__isset()
檢測一個對象的屬性是否存在時被調用。如:isset($c->name)。

11。__unset()
unset一個對象的屬性時被調用。如:unset($c->name)。

12。__set_state()
調用var_export時,被調用。用__set_state的返回值做爲var_export的返回值。

13。__autoload()
實例化一個對象時,如果對應的類不存在,則該方法被調用。

魔術常量:

1。__LINE__
返回文件中的當前行號。

2。__FILE__
返回文件的完整路徑和文件名。如果用在包含文件中,則返回包含文件名。自 PHP 4.0.2 起,__FILE__ 總是包含一個絕對路徑,而在此之前的版本有時會包含一個相對路徑。

3。__FUNCTION__
返回函數名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該函數被定義時的名字(區分大小寫)。在PHP 4 中該值總是小寫字母的。

4。__CLasS__
返回類的名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該類被定義時的名字(區分大小寫)。在PHP 4 中該值總是小寫字母的。

5。__METHOD__
返回類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區分大小寫)。

__set()當程序試圖寫入一個不存在或者不可見的成員變量時,__set()方法包含兩個參數,分別表示變量名稱和變量值,兩個參數都不可省略

__get()當程序試圖調用一個未定義或不可見的成員變量時,__get()方法有一個參數,表示要調用的變量名

__sleep() 常用於提交未提交的數據,或類似的清理操作如果有一些很大的對象,但不需要全部保存,這個功能就很好用。

__construct()  在類實例化對象的同時執行該函數

__distruct() 在類實例化的對象銷燬時執行

__call()對象調用某個方法,若方法存在,則直接調用;若不存在,則會去調用__call函數。

__clone()克隆對象時被調用。如:$t=new Test();$t1=clone $t;

__toString()打印一個對象的時被調用。如echo $obj;或print $obj;

__isset()檢測一個對象的屬性是否存在時被調用。如:isset($c->name)。

__unset()unset一個對象的屬性時被調用。如:unset($c->name)。

__autoload()實例化一個對象時,如果對應的類不存在,則該方法被調用。

113.創建索引的原則  
索引是建立在數據庫表中的某些列的上面。因此,在創建索引的時候,應該 仔細考慮在哪些列上可以創建索引,在哪些列上不能創建索引。一般來說,應該在這些列上創建索引, 例如:在經常需要搜索的列上,可以加快搜索的速度;在作爲 主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,其指定的範圍是連續的;在經常需要排序的列上創建索引,因爲索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。

同樣,對於有些列不應該創建索引。一般來說,不應該創建索引的的 這些列具有下列特點:

第一,對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。

第二,對於那些只有很少數據值的列也不應該增加索引。這是因爲,由於這些列的 取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加 快檢索速度。

第三,對於那些定義爲text, image和bit數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。第四,當修改性能遠遠大於檢索性能時,不應該創建索 引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因 此,當修改性能遠遠大於檢索性能時,不應該創建索引。

114.http的三次握手?
答:三次握手(three times handshake; three-way handshake)所謂的“三次握手”即對每次發送的數據量是怎樣跟蹤進行協商使數據段的發送和接收同步,根據所接收到的數據量而確定的數據確認數及數據發送、接收完畢後何時撤消聯繫,並建立虛連接。

TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。

(1)第一次握手:建立連接時,第三方應用端A發送SYN包(SYN=j)到服務器B,並進入SYN_SEND狀態,等待服務器B確認。

(2)第二次握手:服務器B收到SYN包,必須確認第三方應用A的SYN(ACK=j+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器B進入SYN_RECV狀態。

(3)第三次握手:第三方應用端A收到服務器B的SYN+ACK包,向服務器B發送確認包ACK(ACK=k+1),此包發送完畢,第三方應用端A和服務器B進入ESTABLISHED狀態,完成三次握手。

完成三次握手,第三方應用端與服務器開始傳送數據

115、解釋一下OOP?面向對象
OOP具有三大特點

1、封裝性:也稱爲信息隱藏,就是將一個類的使用和實現分開,只保留部分接口和方法與外部聯繫,或者說只公開了一些供開發人員使用的方法。於是開發人員只 需要關注這個類如何使用,而不用去關心其具體的實現過程,這樣就能實現MVC分工合作,也能有效避免程序間相互依賴,實現代碼模塊間鬆藕合。

2、繼承性:就是子類自動繼承其父級類中的屬性和方法,並可以添加新的屬性和方法或者對部分屬性和方法進行重寫。繼承增加了代碼的可重用性。PHP只支持單繼承,也就是說一個子類只能有一個父類。

3、多態性:子類繼承了來自父級類中的屬性和方法,並對其中部分方法進行重寫。於是多個子類中雖然都具有同一個方法,但是這些子類實例化的對象調用這些相同的方法後卻可以獲得完全不同的結果,這種技術就是多態性。多態性增強了軟件的靈活性。

1、易維護

採用面向對象思想設計的結構,可讀性高,由於繼承的存在,即使改變需求,那麼維護也只是在局部模塊,所以維護起來是非常方便和較低成本的。

2、質量高

在設計時,可重用現有的,在以前的項目的領域中已被測試過的類使系統滿足業務需求並具有較高的質量。

3、效率高

在軟件開發時,根據設計的需要對現實世界的事物進行抽象,產生類。使用這樣的方法解決問題,接近於日常生活和自然的思考方式,勢必提高軟件開發的效率和質量。

4、易擴展

由於繼承、封裝、多態的特性,自然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴展,而且成本較低。

116.cookie僞造
你的第三方應用端的cookie被惡意的用戶截取到,然後向服務器端發送,並且通過驗證,他們就會冒充用戶進行登錄,這就是cookie僞造

防cookie僞造:

現在更通用的做法是使用session來標識用戶,也就是說我們爲每個第三方應用端生成一個唯一的id,然後在服務端存儲這個id所對應的狀態。

這樣cookie裏面僅僅保存了這個id,而沒有任何其他的東西。而且這個id往往還有個特性,它是隨機生成,且每次登陸都會產生一個新的。這樣就更降低了信息泄漏的風險。

117.PHP 的垃圾收集機制是怎樣的
PHP作爲腳本語言是頁面結束即釋放變量所佔內存的。 當一個 PHP線程結束時,當前佔用的所有內存空間都會被銷燬,當前程序中所有對象同時被銷燬。GC進程一般都跟着每起一個SESSION而開始運行的.gc目的是爲了在session文件過期以後自動銷燬刪除這些文件.在PHP中,沒有任何變量指向這個對象時,這個對象就成爲垃圾。PHP會將其在內存中銷燬;這是PHP的GC垃圾處理機制,防止內存溢出。 執行這些函數也可以起到回收作用__destruct /unset/mysql_close /fclose php對session有明確的gc處理時間設定session.gc_maxlifetime 如果說有垃圾,那就是整體的程序在框架使用中,會多次調用同一文件等等造成的非單件模式等。所以在出來的時候,必要的用_once引用,在聲明類的時候使用單件模式。還有簡化邏輯等等。

118.接口和抽象類的區別是什麼?
抽象類是一種不能被實例化的類,只能作爲其他類的父類來使用。抽象類是通過關鍵字abstract來聲明的。
抽象類與普通類相似,都包含成員變量和成員方法,兩者的區別在於,抽象類中至少要包含一個抽象方法,抽象方法沒有方法體,該方法天生就是要被子類重寫的。
抽象方法的格式爲:abstract function abstractMethod();

接口是通過 interface 關鍵字來聲明的,接口中的成員常量和方法都是 public 的,方法可以不寫關鍵字public,接口中的方法也是沒有方法體。接口中的方法也天生就是要被子類實現的。
抽象類和接口實現的功能十分相似,最大的不同是接口能實現多繼承。在應用中選擇抽象類還是接口要看具體實現。
子類繼承抽象類使用 extends,子類實現接口使用implements。

119.Session相關問題
session共享:

1.各種web框架早已考慮到這個問題,比如asp.net,是支持通過配置文件修改session的存儲介質爲sql server的,所有機器的會話數據都從同一個數據庫讀,就不會存在不一致的問題;

2.以cookie加密的方式保存在第三方應用端.優點是減輕服務器端的壓力,缺點是受到cookie的大小限制,可能佔用一定帶寬,因爲每次請求會在頭部附帶一定大小的cookie信息,另外這種方式在用戶禁止使用cookie的情況下無效.

3.服務器間同步。定時同步各個服務器的session信息,此方法可能有一定延時,用戶體驗也不是很好。

php支持把會話數據存儲到某臺memcache服務器,你也可以手工把session文件存放的目錄改爲nfs網絡文件系統,從而實現文件的跨機器共享。

session運行原理:

(1)當一個session第一次被啓用時,一個唯一的標識被存儲於本地的cookie中。

(2)首先使用session_start()函數,PHP從session倉庫中加載已經存儲的session變量。

(3)當執行PHP腳本時,通過使用session_register()函數註冊session變量。

(4)當PHP腳本執行結束時,未被銷燬的session變量會被自動保存在本地一定路徑下的session庫中,這個路徑可以通過php.ini文件中的session.save_path指定,下次瀏覽網頁時可以加載使用。

爲什麼session依賴cookie:

當用戶請求servlet,servlet會首先查看第三方應用端cookie中是否有sessionID,如果有則證明是舊的會話,那麼就通過cookie將sessionID發送到服務器,服務器就會根據sessionID到服務器的內存中查找session對象(因爲每個session都會有一個sessionID來標識session對象),找到之後然後使用。

如果cookie中沒有sessionID這證明是一個新的會話。服務器就會創建一個新的Session對象,然後將SessionID存放早cookie中,通過cookie把sessionID發送到第三方應用端。第三方應用端下一次訪問的時候,就會將SessionID發送到服務器以便再次找到這個session對象,完成會話跟蹤所以如果用戶將cookie關閉session也將會失效。session是依賴與cookie的。

與cookie的區別與聯繫:cookie在第三方應用端保存用戶的信息,而session在服務器上保存第三方應用的信息

session依賴於cookie。如果用戶關閉cookie,則session失效,原因是sessionID無法從第三方應用端傳遞到服務端,也不能從服務端傳遞到第三方應用端.

session怎麼設置過期時間:

第一種方法即設置php.ini配置文件,設置session.gc_maxlifetime和session.cookie_lifetime節點屬性值

第二種方法即設置Session時間戳

120.字符串反轉
給定字符串abcdef,寫出反轉函數,將字符串反轉爲fedcba. 

function myStrReve($str){  

    $len = strlen($str);  

    $result = '';   

    for($i = $len - 1; $i >=0 ; $i-- ){  

        $result .= $str[$i];  

    }     

    return $result;  

}  

121.GD庫是做什麼用的?
gd庫提供了一系列用來處理圖片的API,使用GD庫可以處理圖片,或者生成圖片。 
在網站上GD庫通常用來生成縮略圖或者用來對圖片加水印或者對網站數據生成報表。
122.COOKIE、SESSION的聯繫和區別,多臺web服務器如何共享SESSION?
使用session_start()調用session,服務器端在生成session文件的同時,生成sessionID哈希值和默認值爲PHPSESSID的sessionname,並向第三方應用端發送變量爲(默認的是)PHPSESSID(sessionname),值爲一個128位的哈希 值。服務器端將通過該cookie與第三方應用端進行交互。

session變量的值經PHP內部系列化後保存在服務器機器上的文本文件中,和第三方應用端的變量名默認情況下爲PHPSESSID的cookie進行對應交 互,即服務器自動發送了HTTP頭:header('Set- Cookie:session_name()=session_id();path=/');即setcookie(session_name(),session_id());當從該頁跳轉到的新頁面並調用session_start()後,PHP將檢查與給定ID相關聯的服務器端存貯的session數據,如果沒找到,則新建一個數據集。

123、什麼是隊列?排它鎖,Myisam死鎖如何解決?
在默認情況下MYisam是表級鎖,所以同時操作單張表的多個動作只能以隊列的方式進行;

排它鎖又名寫鎖,在SQL執行過程中爲排除其它請求而寫鎖,在執行完畢後會自動釋放;

死鎖解決:先找到死鎖的線程號,然後殺掉線程ID

124、打開php.ini中的safe_mode,會影響哪些函數?至少說出6個。
1)用戶輸入輸出函數(fopen()file()require(),只能用於調用這些函數有相同腳本的擁有者)

2)創建新文件(限制用戶只在該用戶擁有目錄下創建文件)

3)用戶調用popen()systen()exec()等腳本,只有腳本處在safe_mode_exec_dir配置指令指定的目錄中才可能

4)加強HTTP認證,認證腳本擁有者的UID的劃入認證領域範圍內,此外啓用安全模式下,不會設置PHP_AUTH

5)mysql服務器所用的用戶名必須與調用mysql_connect()的文件的擁有者用戶名相同6)

受影響的函數變量以及配置命令達到40個

125.Smarty的原理
smarty是個模板引擎,最顯著的地方就是有可以把模板緩存起來。一般模板來說,都是做一個靜態頁面,然後在裏面把一些動態的部分用一切分隔符切開,然後在PHP裏打開這個模板文件,把分隔符裏面的值替換掉,然後輸出來,你可以看下PHPLib裏面的template部分。

而smarty設定了緩存參數以後,第一運行時候會把模板打開,在php替換裏面值的時候把讀取的html和php部分重新生成一個臨時的php文件,這樣就省去了每次打開都重新讀取html了。如果修改了模板,只要重新刷下就行了。

126、寫出五種以上你使用過的PHP的擴展的名稱(提示:常用的PHP擴展)
 mb_sring、iconv、curl、GD、XML、socket、MySQL、PDO等

127、怎麼把文件保存到指定目錄?怎麼避免上傳文件重名問題?
  可以通過上傳的文件名獲取到文件後綴,然後使用時間戳+隨機數+文件後綴的方式爲文件重新命名,這樣就避免了重名。可以自己設置上傳文件的保存目錄,與文件名拼湊形成一個文件路徑,使用move_uploaded_file(),就可以完成將文件保存到指定目錄。

128、在Smarty模板語法中如何獲取php的全局環境變量
$smarty.get.變量#顯示通過get方式傳過來的指定變量的值

$smarty.post.變量#顯示通過post方式傳過來的指定變量的值$smarty.cookies.變量#顯示通過cookie中指定變量的值

$smarty.server.SERVER_NAME#顯示server變量值,$_SERVER系列變量$smarty.env.PATH#顯示系統環境變量值,$_ENV系列變量$smarty.session.變量#顯示session中指定變量的值

$smarty.request.變量#顯示通過post、get、cookie中指定變量的值

129、禁用COOKIE後SEESION還能用嗎?
    可以,Cookie和session都是用來實現會話機制的,由於http協議是無狀態的,所以要想跟蹤一個用戶在同一個網站之間不同頁面的狀態,需要有這麼一個機制----會話機制。

Cookie:將會話信息的保存到瀏覽器端。Session:將會話信息保存到服務器端。

session默認情況下是基於cookie的,對於session來說,每生成一個sessionid,都會將其發送到瀏覽器端,讓後將其保存到cookie當中。

如果禁用了cookie,則基於cookie的session不好使了,我們可以使用get,傳遞SID。

130、PHP7有哪些新特性?
PHP7在PHP5的基礎上又做了一次質的提升,當然改變很多,我這裏以我的總結簡單說下,主要發生了下面這些更改:

移除了一些舊的特性

ZEND引擎升級到Zend Engine 3,也就是所謂的PHP NG

增加抽象語法樹,使編譯更加科學

64位的INT支持

統一的變量語法

原聲的TLS - 對擴展開發有意義

一致性foreach循環的改進

新增 <=>、**、??、\u{xxxx}操作符

增加了返回類型的聲明

增加了標量類型的聲明

核心錯誤可以通過異常捕獲了

增加了上下文敏感的詞法分析  

131、什麼是JS中的閉包,什麼是PHP中的閉包函數?
   JS的閉包:

      所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。

   先看下下面這段代碼

   

這段代碼有兩個特點:1、函數b嵌套在函數a內部;2、函數a返回函數b。

這樣在執行完var c=a()後,變量c實際上是指向了函數b,再執行c()後就會彈出一個窗口顯示i的值(第一次爲1)。這段代碼其實就創建了一個閉包,爲什麼?因爲函數a外的變量c引用了函數a內的函數b,就是說:
  當函數a的內部函數b被函數a外的一個變量引用的時候,就創建了一個閉包。

①這裏首先得說下JS的垃圾回收機制:

在Javascript中,如果一個對象不再被引用,那麼這個對象就會被GC回收。如果兩個對象互相引用,而不再被第3者所引用,那麼這兩個互相引用的對象也會被回收。因爲函數a被b引用,b又被a外的c引用,這就是爲什麼函數a執行後不會被回收的原因。

②閉包有什麼作用呢?

    1)可以在全局作用域實現對局部變量的引用

    2)可以一直保存我們的變量或函數駐留在內存中,而不會被GC回收

 ③閉包的應用場景

   1、保護函數內的變量安全。以最開始的例子爲例,函數a中i只有函數b才能訪問,而無法通過其他途徑訪問到,因此保護了i的安全性。
  2、在內存中維持一個變量。依然如前例,由於閉包,函數a中i的一直存在於內存中,因此每次執行c(),都會給i自加1。

我眼中的閉包:

   函數中函數,且該函數捆綁了一些局部變量,又由於全局變量的引用,會導致函數與變量都不會被回收,這就是我眼中的閉包。

 

 PHP中的閉包函數:

在PHP5.3以後,允許創建匿名函數,中匿名函數,也叫閉包函數(closures ),允許 臨時創建一個沒有指定名稱的函數。最經常用作回調函數(callback)的參數。

 

用好閉包,可以幫我們

1 減少foreach的循環的代碼

2 減少函數的參數

3 解除遞歸函數

 

 

 

 

 

 

 

 

 

PHP異步處理   redis的異步處理    數據庫的死鎖、悲觀鎖/樂觀鎖、排他鎖/共享鎖、髒讀、幻讀、API優化/設計、框架底層、主從延遲、redis集羣、
--------------------- 
原文:https://blog.csdn.net/qq_34306360/article/details/79187075 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章