1. 程式人生 > >2018年PHP工程師面試題

2018年PHP工程師面試題

1、TP的特性有哪些?

1.多表查詢非常方便,在model中幾句程式碼就可以完成對多表的關聯操作 
2.融合了smarty模板,使前後臺分離 
3.支援多種快取技術,尤其對memcache技術支援非常好 
4.命名規範,模型,檢視,控制器嚴格遵循命名規則,通過命名一一對應 
5.支援多種url模式 
6.內建ajax返回方法,包括xml,json,html等 
7.支援應用擴充套件,類庫擴充套件,驅動擴充套件等

2、TP框架中的大字母函式?

U:對url的組裝
A:內部例項化控制器
S:快取處理
R:呼叫某個控制器的操作方法
D:例項化自定義模型類
M:例項化基礎模型類
I:獲取引數
L:設定或者獲取當前語言
C:設定或獲取,儲存配置

3、請介紹一下laravel框架?

答: laravel框架的設計思想比較先進,非常適合應用各種開發模式,作為一個框架,它為你準備好了一切,composer是php的未來,沒有composer,php肯定要走向沒落
laravel框架最大的特點和優秀之處就是集合了php比較新的特點,以及各種各樣的設計模式,Ioc模式,依賴注入等
4、laravel有那些特點?

1.強大的rest router:用簡單的回撥函式就可以呼叫,快速繫結controller和router 
2.artisan:命令列工具,很多手動的工作都自動化 
3.可繼承的模板,簡化view的開發和管理 
4.blade模板:渲染速度更快 
5.ORM操作資料庫 
6.migration:管理資料庫和版本控制 
7.測試功能也很強大 
8.composer也是亮點

5、請簡述一下資料庫的優化?

答:資料庫的優化可以從四個方面來優化

1.從結構層: web伺服器採用負載均衡伺服器,mysql伺服器採用主從複製,讀寫分離 
2.從儲存層: 採用合適的儲存引擎,採用三正規化 
3.從設計層: 採用分割槽分表,索引,表的欄位採用合適的欄位屬性,適當的採用逆正規化,開啟mysql快取 
4.sql語句層:結果一樣的情況下,採用效率高,速度快節省資源的sql語句執行

6、如何解決異常處理?

答: 丟擲異常:使用try…catch,異常的程式碼放在try程式碼塊內,如果沒有觸發異常,則程式碼繼續執行,如果異常被觸發,就會 丟擲一個異常。Catch程式碼塊捕獲異常,並建立一個包含異常資訊的物件。$e->getMessage(),輸出異常的錯誤資訊。

解決異常:使用set_error_handler函式獲取異常(也可以使用try()和catch()函式),然後使用set_exception_handler()函式設定預設的異常處理程式,register_shutdown_function()函式來執行,執行機制是,php要把調入的函式調入到記憶體,當頁面所有的php語句都執行完成時,再呼叫此函式
7、怎麼保證促銷商品不會超賣?

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

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

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

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

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

答:搶購、秒殺是如今很常見的一個應用場景,主要需要解決的問題有兩個:

    1 高併發對資料庫產生的壓力
    2 競爭狀態下如何解決庫存的正確減少("超賣"問題)

對於第一個問題,已經很容易想到用快取來處理搶購,避免直接操作資料庫,例如使用Redis。第二個問題,我們可以使用redis佇列來完成,把要秒殺的商品放入到佇列中,因為pop操作是原子的,即使有很多使用者同時到達,也是依次執行,檔案鎖和事務在高併發下效能下降很快,當然還要考慮其他方面的東西,比如搶購頁面做成靜態的,通過ajax呼叫介面,其中也可能會出現一個使用者搶多次的情況,這時候需要再加上一個排隊佇列和搶購結果佇列及庫存佇列。高併發情況下,將使用者進入排隊佇列,用一個執行緒迴圈處理從排隊佇列取出一個使用者,判斷使用者是否已在搶購結果佇列,如果在,則已搶購,否則未搶購,庫存減1,寫資料庫,將使用者入結果佇列。
9、購物車的原理?

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

主要涉及以下幾點:

    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的檔案屬性使其仍然留有安全隱患。

結合資料庫的方式雖然在一定程度上解決了上述的問題,但從上面的例子可以看出:在這種購物流程中涉及到對資料庫表的頻繁操作,尤其是使用者每選購一次商品,都要與資料庫進行連線,當用戶很多的時候就加大了伺服器與資料庫的負荷。
10、redis訊息佇列先進先出需要注意什麼?

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

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

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

list1 做為高優先順序任務佇列
list2 做為普通任務佇列

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

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

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

11、介面安全方面是怎麼處理的?

答:我們當時是這麼做的,使用HTTP的POST方式,對固定引數+附加引數進行數字簽名,使用的是md5加密,比如:我想通過標題獲取一個資訊,在客戶端使用 資訊標題+日期+雙方約定好的一個key通過md5加密生成一個簽名(sign),然後作為引數傳遞到伺服器端,伺服器端使用同樣的方法進行校驗,如何接受過來的sign和我們通過演算法算的值相同,證明是一個正常的介面請求,我們才會返回相應的介面資料。
也可以使用RSA加密

12、寫過介面嗎,怎麼定義介面的?

答:寫過。介面分為兩種:一種是資料型介面,一種是應用型介面。

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

應用型介面: API(application interface) 資料對外訪問的一個入口

我主要是參與的APP開發中介面的編寫,客戶端需要什麼樣的資料,我們就給他們提供相應的資料,資料以json/xml的格式返回,並且配以相應的介面文件。
13、sku減庫存?

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

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

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

15、訂單、庫存兩個表 如何保證資料的一致性?

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

答:O2O為線上和線下模式,O2O模式奉行的是“線上支付+實體店消費”的消費模式,即消費者在網上下單完成支付後,憑消費憑證到實體店消費。 O2O模式是把商家資訊和支付程式放在線上進行,而把商品和服務兌現放線上下,也就是說O2O模式適用於快遞無法送達的有形產品。資料一致性的問題是O2O行業中最常見的問題,我們可以類似於資料庫的主從複製的思路來解決這個問題.O2O有個供應商系統,類似於主伺服器,在ç端(從伺服器)下單時,資料同步更新到供應商系統端,b,a實時從供應商系統中拉取資料進行同步,比如利用定時任務,定時拉取資料進行同步。
17、Redis如何防止高併發?

答:其實redis是不會存在併發問題的,因為他是單程序的,再多的命令都是一個接一個地執行的。我們使用的時候,可能會出現併發問題,比如獲得和設定這一對。Redis的為什麼 有高併發問題?Redis的的出身決定
Redis是一種單執行緒機制的nosql資料庫,基於key-value,資料可持久化落盤。由於單執行緒所以redis本身並沒有鎖的概念,多個客戶端連線並不存在競爭關係,但是利用jedis等客戶端對redis進行併發訪問時會出現問題。發生連線超時、資料轉換錯誤、阻塞、客戶端關閉連線等問題,這些問題均是由於客戶端連線混亂造成。

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

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

解決辦法

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

伺服器角度,利用setnx變向實現鎖機制。
18、支付寶流程怎麼實現的?

答:首先要有一個支付寶賬號,接下來向支付寶申請線上支付業務,簽署協議。協議生效後有支付寶一方會給網站方一個合作伙伴ID,和安全校驗碼,有了這兩樣東西就可以按照支付寶介面文件開發支付寶介面了,中間主要涉及到一個安全問題。整個流程是這樣的:我們的網站通過post傳遞相應的引數(如訂單總金額,訂單號)到支付頁面,支付頁面把一系列的引數經過處理,以post的方式提交給支付寶伺服器,支付寶伺服器進行驗證,並對接收的資料進行處理,把處理後的結果返回給我們網站設定的非同步和同步回撥地址,通過相應的返回引數,來處理相應的業務邏輯,比如返回的引數代表支付成功,更改訂單狀態。
19、什麼是單點登入?

答:單點登入SSO(Single Sign On)說得簡單點就是在一個多系統共存的環境下,使用者在一處登入後,就不用在其他系統中登入,也就是使用者的一次登入能得到其他所有系統的信任。

20、什麼情況下使用快取?

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

實現主要技術點:

    1、兩個站點共用一個數據驗證系統
    2、主要通過跨域請求的方式來實現驗證及session處理。

21、怎麼實現第三方登入?

答:第三方登陸主要是基於author協議來實現,下面簡單說下實現流程:

1、首先我們需要以開發者的身份向第三方登陸平臺申請接入應用,申請成功後,我們會獲得一個appID和一個secrectID. 
2、當我們的網站需接入第三方登陸時,會引導使用者跳轉到第三方的登陸授權頁面,此時把之前申請的appID和secrectID帶給登陸授權頁面。 
3、使用者登陸成功後即得到授權,第三方會返回一個臨時的code給我們的網站。 
4、我們的網站接受到code後,再次向我們的第三方發起請求,並攜帶接收的code,從第三方獲取access_token. 5、第三方處理請求後,會返回一個access_token給我們的網站,我們的網站獲取到access_token後就可以呼叫第三方提供的介面了,比如獲取使用者資訊等。最後把該使用者資訊存入到我們站點的資料庫,並把資訊儲存到session中,實現使用者的第三方登陸。

22、如何處理負載、高併發?(好好看看,經常問到,能回答到主要的東西即可)?

答:從低成本、高效能和高擴張性的角度來說有如下處理方案:

1、HTML靜態化

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

2、圖片伺服器分離

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

3、資料庫叢集和庫表雜湊及快取

資料庫的併發連線為100,一臺資料庫遠遠不夠,可以從讀寫分離、主從複製,資料庫叢集方面來著手。另外儘量減少資料庫的訪問,可以使用快取資料庫如memcache、redis。

4、映象:

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

5、負載均衡:

Apache的最大併發連線為1500,只能增加伺服器,可以從硬體上著手,如F5伺服器。當然硬體的成本比較高,我們往往從軟體方面著手。

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

Nginx的優點是:

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

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

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

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

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

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

    Nginx現在作為Web反向加速快取越來越成熟了,速度比傳統的Squid伺服器更快,可以考慮用其作為反向代理加速器。

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

    Nginx也可作為靜態網頁和圖片伺服器,這方面的效能也無對手。還有Nginx社群非常活躍,第三方模組也很多。

Nginx的缺點是:

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

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

LVS的優點是:

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

LVS的缺點是:

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

HAProxy的特點是:

    HAProxy也是支援虛擬主機的。
    HAProxy的優點能夠補充Nginx的一些缺點,比如支援Session的保持,Cookie的引導;同時支援通過獲取指定的url來檢測後端伺服器的狀態。
    HAProxy跟LVS類似,本身就只是一款負載均衡軟體;單純從效率上來講HAProxy會比Nginx有更出色的負載均衡速度,在併發處理上也是優於Nginx的。
    HAProxy支援TCP協議的負載均衡轉發,可以對MySQL讀進行負載均衡,對後端的MySQL節點進行檢測和負載均衡,大家可以用LVS+Keepalived對MySQL主從做負載均衡。
    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對比的總結:

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

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

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

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

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

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

    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。

資料庫優化
23、<font color="red">封裝過一個簡單的框架?</font>

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

24、談談對MVC的認識?

答:核心思想是:檢視和使用者互動通過事件導致控制器改變 控制器改變導致模型改變 或者控制器同時改變兩者 模型改變 導致檢視改變 或者檢視改變 潛在的從模型裡面獲得引數 來改變自己。他的好處是可以將介面和業務邏輯分離。

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

25、session與cookie的區別?

1、cookie資料存放在第三方應用的瀏覽器上,session資料放在伺服器上。 
2、cookie不是很安全,別人可以分析存放在本地的COOKIE,進行COOKIE欺騙,考慮到安全應當使用session。 
3、session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能,考慮到減輕伺服器效能方面,應當使用COOKIE。 
4、單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個站點最多儲存20個cookie。 
5、所以個人建議: 將登陸資訊等重要資訊存放為SESSION 其他資訊如果需要保留,可以放在COOKIE

26、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()判斷一個變數的型別與長度,並輸出變數的數值,如果變數有值輸的是變數的值並回返資料型別。此函式顯示關於一個或多個表示式的結構資訊,包括表示式的型別與值。陣列將遞迴展開值,通過縮排顯示其結構。

27、說一下單引號雙引號?

①單引號內部的變數不會執行, 雙引號會執行

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

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

28、索引的優缺點?

優點

a)可以保證資料庫表中每一行的資料的唯一性 
b)可以大大加快資料的索引速度 
c)加速表與表之間的連線,物別是在實現資料的參考完事性方面特別有意義 
d)在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間 
f)通過使用索引,可以在時間查詢的過程中,使用優化隱藏器,提高系統的效能

缺點

a) 建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加 
b) 索引需要佔物理空間,除了資料表佔用資料空間之外,每一個索引還要佔用一定的物理空間,如果需要建立聚簇索引,那麼需要佔用的空間會更大 
c) 以表中的資料進行增、刪、改的時候,索引也要動態的維護,這就降低了整數的維護速度 
d) 建立索引的原則 
e) 在經常需要搜尋的列上,可以加快搜索的速度 f) 在作為主鍵的列上,強制該列的唯一性和組織表中資料的排列結構 
g) 在經常用在連線的列上,這些列主要是一外來鍵,可以加快連線的速度 
h) 在經經常需要根據範圍進行搜尋的列上建立索引,國為索引已經排序,其指定的範圍是連續的 
i) 在經常需要排序的列上,國為索引已經排序,這樣井底可以利用索引的排序,加快排序井底時間 
j) 在經常使用在where子句中的列上,加快條件的判斷速度

原文參考:https://blog.csdn.net/u011330276/article/details/79597200