1. 程式人生 > >2018年PHP50道重點面試題

2018年PHP50道重點面試題

1.請自我介紹一下?

答:我叫 xxx,來自北京,20xx 年畢業於 xx 大學計算機 xx 系,畢業後在武漢從事了 x 年的 php 開發工作,公司是一個外包公司,主要做微信開發,公眾號推廣,商城,論壇的開發
2.你在公司負責那些專案?

答:由於我們公司是一個外包公司,不可能只做一個專案,公司的專案都是交叉進行的,論壇,微信,商城我都做過?
3.你為什麼來深圳?

答:因為我哥在這邊,父母也希望兄弟間有個照應,而且深圳是一線城市,技術也比廣西前沿一些
4.武漢使用什麼前端框架和後端框架?

答:根據自己的區域回答
5.你做過那些模組?

答:登陸註冊,商品管理,購物車模組,訂單管理
6.你們公司是使用什麼框架?

答:我們公司採用的是 TP 框架,運用的 mysql+apache+php 進行開發,因為 TP 框架是一個免費開源的,輕量級的 php 開發框架,而且是我們中國人自己開發的,也是國內用的比較多的,各種資料也比較齊全
7.mvc 是什麼?相互間有什麼關係?

答:mvc 是一種開發模式,主要分為三部分:m(model),也就是模型,負責資料的操作;v(view),也就是檢視,負責前後臺的顯示;c(controller),也就是控制器,負責業務邏輯
 客戶端請求專案的控制器,如果執行過程中需要用到資料,控制器就會到模型中獲取資料,再將獲取到的資料通過檢視顯示出來
8.oop 是什麼?

答:oop 是面向物件程式設計,面向物件程式設計是一種計算機程式設計架構,OOP 的一條基本原則是計算機程式是由單個能夠起到子程式作用的單元或物件組合而成。
OOP 具有三大特點
1、封裝性:也稱為資訊隱藏,就是將一個類的使用和實現分開,只保留部分介面和方法與外部聯絡,或者說只公開了一些供開發人員使用的方法。於是開發人員只 需要關注這個類如何使用,而不用去關心其具體的實現過程,這樣就能實現 MVC 分工合作,也能有效避免程式間相互依賴,實現程式碼模組間鬆藕合。
 2、繼承性:就是子類自動繼承其父級類中的屬性和方法,並可以新增新的屬性和方法或者對部分屬性和方法進行重寫。繼承增加了程式碼的可重用性。PHP 只支援單繼承,也就是說一個子類只能有一個父類。
 3、多型性:子類繼承了來自父級類中的屬性和方法,並對其中部分方法進行重寫。於是多個子類中雖然都具有同一個方法,但是這些子類例項化的物件呼叫這些相同的方法後卻可以獲得完全不同的結果,這種技術就是多型性。多型性增強了軟體的靈活性。
 1、易維護
 採用面向物件思想設計的結構,可讀性高,由於繼承的存在,即使改變需求,那麼維護也只是在區域性模組,所以維護起來是非常方便和較低成本的。
 2、質量高
 在設計時,可重用現有的,在以前的專案的領域中已被測試過的類使系統滿足業務需求並具有較高的質量。
 3、效率高
 在軟體開發時,根據設計的需要對現實世界的事物進行抽象,產生類。使用這樣的方法解決問題,接近於日常生活和自然的思考方式,勢必提高軟體開發的效率和質量。
 4、易擴充套件
 由於繼承、封裝、多型的特性,自然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴充套件,而且成本較低。
9.smarty 是什麼,有什麼作用?

答:回答一:smarty 是用 php 寫出來的模板引擎,也是目前業界最著名的 php 模板引擎之一
 它分離了邏輯程式碼和外在的顯示,提供了一種易於管理和使用的方法,用來將混雜的 php 邏輯程式碼與 html 程式碼進行分離
 回答二:smarty 是 php 中最著名的引擎框架之一,我們公司使用的是 TP 框架,已經封裝好了 smarty 模板,所以沒有單獨使用過
 回答三: smarty 是個模板引擎,最顯著的地方就是有可以把模板快取起來。一般模板來說,都是做一個靜態頁面,然後在裡面把一些動態的部分用一切分隔符切開,然後在 PHP 裡開啟這個模板檔案,把分隔符裡面的值替換掉,然後輸出來,你可以看下 PHPLib 裡面的 template 部分。
 而 smarty 設定了快取引數以後,第一次執行時候會把模板開啟,在 php 替換裡面值的時候把讀取的 html 和 php 部分重新生成一個臨時的 php 檔案,這樣就省去了每次開啟都重新讀取 html 了。如果修改了模板,只要重新刷下就行了。
10.TP 框架有哪些優點?

答:TP 框架是我們中國人自己開發的框架,各種資料比較齊全,國內用的比較多,比較簡單和方便,而且是免費開源的
11.TP 的特性有哪些?

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

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

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

答:回答一: 1.強大的 rest router:用簡單的回撥函式就可以呼叫,快速繫結 controller 和 router
 2.artisan:命令列工具,很多手動的工作都自動化
 3.可繼承的模板,簡化 view 的開發和管理
 4.blade 模板:渲染速度更快
 5.ORM 操作資料庫
 6.migration:管理資料庫和版本控制
 7.測試功能也很強大
 8.composer 也是亮點
 回答二: laravel 框架引入了門面,依賴注入,Ioc 模式,以及各種各樣的設計模式等
15.請簡述一下資料庫的優化?

答:資料庫的優化可以從四個方面來優化:
 1.從結構層: web 伺服器採用負載均衡伺服器,mysql 伺服器採用主從複製,讀寫分離
 2.從儲存層: 採用合適的儲存引擎,採用三正規化
 3.從設計層: 採用分割槽分表,索引,表字段合適的欄位屬性,適當採用逆正規化,開啟 mysql 快取
 4.sql 語句層:結果一樣的情況下,採用效率高,速度快節省資源的 sql 語句執行
16.如何解決異常處理?

答: 丟擲異常:使用 try...catch,異常的程式碼放在 try 程式碼塊內,如果沒有觸發異常,則程式碼繼續執行,如果異常被觸發,就會丟擲一個異常。Catch 程式碼塊捕獲異常,並建立一個包含異常資訊的物件。$e->getMessage(),輸出異常的錯誤資訊。
 解決異常:使用 set_error_handler 函式獲取異常(也可以使用 try()和 catch()函式),然後使用 set_exception_handler()函式設定預設的異常處理程式,register_shutdown_function()函式來執行,執行機制是,php 要把調入的函式調入到記憶體,當頁面所有的 php 語句都執行完成時,再呼叫此函式
17.前端

 答:我在工作中處理前端的功能,一般就是用 ajax 向後臺請求資料,然後返回資料在前臺頁面中顯示出來。我從來沒有獨立的完整的將 html 和 css 樣式都一個人完成,如果公司實在有這樣的需求的話,我可能會找一些前臺的模板或者說是前端的框架,比如說 h—ui 等等
18.許可權管理(RBAC)的實現?

答: 1.首先建立一張使用者表:id name auto(儲存格式為:控制器-方法)
 2.然後在後臺中建立一個基類控制器,控制器裡封裝一個構造方法,當用戶登陸成功後,使用 TP 框架中封裝好的 session 函式獲取儲存在伺服器中的 session id,然後例項化模型,通過使用者 id 獲取儲存在資料表中的 auth 資料,使用 explode 函式分割獲取到的資料,並使用一個數組儲存起來,然後使用 TP 框架中封裝好的常量獲取當前控制器和方法,然後把他們組裝成字串,使用 in_array 函式進行判斷該陣列中是否含有當前獲取到的控制器和方法,如果沒有,就提示該使用者沒有許可權,如果有就進行下一步操作
19.支付功能的實現?

答:
20.怎麼保證促銷商品不會超賣

 答:這個問題是我們當時開發時遇到的一個難點,超賣的原因主要是下的訂單的數目和我們要促銷的商品的數目不一致導致的,每次總是訂單的數比我們的促銷商品的數目要多,當時我們的小組討論了好久,給出了好幾個方案來實現:
 第一種方案是:①在每次下訂單前我們判斷促銷商品的數量夠不夠,不夠不允許下訂單,更改庫存量時加上一個條件,只更改商品庫存大於 0 的商品的庫存,當時我們使用 ab 進行壓力測試,當併發超過 500,訪問量超過 2000 時,還是會出現超賣現象。所以被我們否定了。
 第二種方案是:②使用 mysql 的事務加排他鎖來解決,首先我們選擇資料庫的儲存引擎為 innoDB,使用的是排他鎖實現的,剛開始的時候我們測試了下共享鎖,發現還是會出現超賣的現象。有個問題是,當我們進行高併發測試時,對資料庫的效能影響很大,導致資料庫的壓力很大,最終也被我們否定了。
 第三種方案是:③使用檔案鎖實現。當用戶搶到一件促銷商品後先觸發檔案鎖,防止其他使用者進入,該使用者搶到促銷品後再解開檔案鎖,放其他使用者進行操作。這樣可以解決超賣的問題,但是會導致檔案得 I/O 開銷很大。
 最後我們使用了 redis 的佇列來實現。將要促銷的商品數量以佇列的方式存入 redis 中,每當使用者搶到一件促銷商品則從佇列中刪除一個數據,確保商品不會超賣。這個操作起來很方便,而且效率極高,最終我們採取這種方式來實現
21.商城秒殺的實現

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

 答:購物車相當於現實中超市的購物車,不同的是一個是實體車,一個是虛擬車而已。使用者可以在購物網站的不同頁面之間跳轉,以選購自己喜愛的商品,點選購買時,該商品就自動儲存到你的購物車中,重複選購後,最後將選中的所有商品放在購物車中統一到付款臺結賬,這也是儘量讓客戶體驗到現實生活中購物的感覺。伺服器通過追蹤每個使用者的行動,以保證在結賬時每件商品都物有其主。 
 主要涉及以下幾點:
 1、把商品新增到購物車,即訂購
 2、刪除購物車中已定購的商品
 3、修改購物車中某一本圖書的訂購數量
 4、清空購物車
 5、顯示購物車中商品清單及數量、價格
 實現購物車的關鍵在於伺服器識別每一個使用者並維持與他們的聯絡。但是 HTTP 協議是一種“無狀態(Stateless)”的協議,因而伺服器不能記住是誰在購買商品,當把商品加入購物車時,伺服器也不知道購物車裡原先有些什麼,使得使用者在不同頁面間跳轉時購物車無法“隨身攜帶”,這都給購物車的實現造成了一定的困難。
 目前購物車的實現主要是通過 cookie、session 或結合資料庫的方式。下面分析一下它們的機制及作用。
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 功能。
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 儲存的資訊更敏感,而且是以檔案形式儲存在伺服器中,因此仍然存在著安全隱患。
結合資料庫的方式
這也是目前較普遍的模式,在這種方式中,資料庫承擔著儲存購物資訊的作用,session 或 cookie 則用來跟蹤使用者。這種方式具有以下特點:
1、資料庫與 cookie 分別負責記錄資料和維持會話,能發揮各自的優勢,使安全性和伺服器效能都得到了提高;
2、每一個購物的行為,都要直接建立與資料庫的連線,直至對錶的操作完成後,連線才釋放。當併發使用者很多時,會影響資料庫的效能,因此,這對資料庫的效能提出了更高的要求;
3、使 cookie 維持會話有賴客戶端的支援。
各種方式的選擇:
雖然 cookie 可用來實現購物車,但必須獲得瀏覽器的支援,再加上它是儲存在客戶端的資訊,極易被獲取,所以這也限制了它儲存更多,更重要的資訊。所以一般 cookie 只用來維持與伺服器的會話,例如國內最大的當當網路書店就是用 cookie 保持與客戶的聯絡,但是這種方式最大的缺點是如果客戶端不支援 cookie 就會使購物車失效。
Session 能很好地與交易雙方保持會話,可以忽視客戶端的設定。在購物車技術中得到了廣泛的應用。但 session 的檔案屬性使其仍然留有安全隱患。
結合資料庫的方式雖然在一定程度上解決了上述的問題,但從上面的例子可以看出:在這種購物流程中涉及到對資料庫表的頻繁操作,尤其是使用者每選購一次商品,都要與資料庫進行連線,當用戶很多的時候就加大了伺服器與資料庫的負荷。
23.redis 訊息佇列先進先出需要注意什麼

答:通常使用一個 list 來實現佇列操作,這樣有一個小限制,所以的任務統一都是先進先出,如果想優先處理某個任務就不太好處理了,這就需要讓佇列有優先順序的概念,我們就可以優先處理高級別的任務,實現方式有以下幾種方式:
 1)單一列表實現:佇列正常的操作是 左進右出(lpush,rpop)為了先處理高優先順序任務,在遇到高級別任務時,可以直接插隊,直接放入佇列頭部(rpush),這樣,從佇列頭部(右側)獲取任務時,取到的就是高優先順序的任務(rpop)
 2)使用兩個佇列,一個普通佇列,一個高階佇列,針對任務的級別放入不同的佇列,獲取任務時也很簡單,redis 的 BRPOP 命令可以按順序從多個佇列中取值,BRPOP 會按照給出的 key 順序檢視,並在找到的第一個非空 list 的尾部彈出一個元素,redis> BRPOP list1 list2 0
list1 做為高優先順序任務佇列
list2 做為普通任務佇列
這樣就實現了先處理高優先順序任務,當沒有高優先順序任務時,就去獲取普通任務
方式 1 最簡單,但實際應用比較侷限,方式 3 可以實現複雜優先順序,但實現比較複雜,不利於維護
方式 2 是推薦用法,實際應用最為合適
24.你負責的模組有哪些難題

答:在我負責的 B2B 電商專案中,當時我負責的是訂單模組,由於客戶一次選擇了多家商戶的商品,最終生成了一個訂單,這樣我們平臺在給商戶結算時出現了不知道這比費用應該給哪個商戶,這時候我們小組經過討論,需要涉及到訂單拆分,也就是說使用者點選支付後,如果有多件商品,並且不是同一家店鋪那麼 就要用到訂單的拆分,比如如果有兩件商品,並且不是同一店鋪 就在原來的訂單號下 在生成兩個子訂單號 並修改訂單表中兩件商品的訂單號。最終實現了商品的分配管理,解決了我們的難題。
我覺得在開發過程中,遇到的難題無非是兩個,一個是技術層次的,我認為,只要你有恆心,有熱心,沒有覺得不了的難題。另一個就是溝通問題,在任何地方任何時候溝通都是最重要的,尤其是我們做開發的,不溝通好,會影響整個專案的進度,我本人是個非常還溝通的人,所以這點上也沒多大問題。
25.使用者下單是怎麼處理的

答:判斷使用者有沒有登入,在沒有登入的情況下,不允許下單。登陸後,可進行下單,並生成唯一的訂單號,此時訂單的狀態為未支付。
26.電商的登入是怎麼實現的

答:分為普通登入和第三方登入 這邊主要說一下第三方登入吧,第三方登陸主要使用的是 author 協議,我就以 QQ 的第三方登陸為例來進行說明:當用戶在我們的站點請求 QQ 的第三方登陸時,我們站點會引導使用者跳轉到 QQ 的登陸授權介面, 當用戶輸入 QQ 和密碼成功登入以後會自動跳回到我們站點設定好的回撥頁面,並附帶一個 code 引數,接著你使用 code 再次去請求 QQ 的授權頁面,就可以從中獲取到一個 access token(訪問令牌),通過這個 access_token,我們可以呼叫 QQ 提供給我們的介面,比如獲取 open_id,可以獲取使用者的基本資訊。獲取到之後,我們需要拿使用者的授權資訊和 open_id 和我們平臺的普通使用者進行繫結。這樣不管是普通使用者登陸還是第三方登陸使用者,都可以實現登陸。
27.介面安全方面是怎麼處理的

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

答:我主要用的第三方簡訊介面,在申請介面時進行相應資訊的配置,然後在我們站點需要用到簡訊驗證的地方進行呼叫,我們通常在使用者註冊時使用到。
29.在工作中遇到什麼困難?

答:總體來說:在工作我主要遇到這幾個問題比較難處理:
 ①我之前工作的時候發現經常會出現一些臨時需求打亂了我的計劃,搞得有時候這個任務還沒完成,又得去做其他的任務,最後一天下來,大大小小的東西是很多,但是沒有完成得非常好的,後面我總結了一下,我會把這些都新增優先順序,遇到臨時需求,按照優先順序重新將已有任務和臨時任務進行排版,保證在規定時間內有效率的完成優先順序高的任務。
 ②在做專案需求時候,遇到理解能力欠佳的人,溝通時容易被氣到,影響自己的情緒,最後反倒還不能到達需要的效果。後面,每次到這種時候,我一般會藉助一些紙質的、更加形象的東西,讓雙方都認同的、都能明白的一種方式來進行溝通,後面減少了很多不必須的麻煩。大家都知道,對於程式設計師來說,改需求是一件很痛苦的事情,所以前期的溝通工作很重要。
 ③還有一件事時,我以前的領導不太懂技術,所以每次出一個新的需求出來,總是要求我們在很短的時間內完成,完不成我們就會被懷疑能力有問題。當然,每個領導都希望自己的員工能夠儘快的完成任務,降低成本,提高效率。這時候我會把我們的需求細化,把其中的重點、難點都列出來,做好時間規劃,耐心的跟領導溝通,專案每個點的重要性和時間的花費比例,確保在這個規劃的時間點內保質保量的完成任務。慢慢的也得到了領導的認可,其實領導也不是一味的不通情理,只要把東西計劃好了,以最小的代價換取最高的價值,每個人都是很容易理解得
30.使用者不登入,怎麼直接加入購物車的

答:使用者在不登入的情況下,可以把要購買商品的資訊(如商品的 ID,商品的價格、商品的 sku_id,購買數量等關鍵資料)存到 COOKIE 裡面,當登陸的情況下。把 COOKIE 裡面的內容存到資料庫,並清除 cookie 中的資料。
31.寫過介面嗎,怎麼定義介面的

答:寫過。介面分為兩種:一種是資料型介面,一種是應用型介面。
資料型介面:是比抽象類更抽象的某種“結構”——它其實不是類,但是跟類一樣的某種語法結構,是一種結構規範,規範我們類要以什麼格式進行定義,一般用於團隊比較大,分支比較多的情況下使用。
應用型介面: API(application interface) 資料對外訪問的一個入口
我主要是參與的 APP 開發中介面的編寫,客戶端需要什麼樣的資料,我們就給他們提供相應的資料,資料以 json/xml 的格式返回,並且配以相應的介面文件。
32.sku 減庫存

答:SKU = Stock Keeping Unit (庫存量單位) 
即庫存進出計量的單位,可以是以件,盒,托盤等為單位。SKU 是庫存量單位,區分單品。 
在服裝、鞋類商品中使用最多最普遍。 例如紡織品中一個 SKU 通常表示:規格、顏色、款式。
在設計表時,不僅僅只有商品表,商品表中有個總庫存,我們還需要涉及一張 SKU 表,裡面有 SKU 庫存和單價欄位,使用者每購買一件商品,實際上購買的都是 SKU 商品,這樣在下訂單成功後,應該根據所購買的商品的唯一的 SKU 號來進行相應的 SKU 庫存的減少,當然商品的總庫存儲存在商品主表中,也需要減少總庫存中的庫存量。
33.庫存設定?

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

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

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

答:其實 redis 是不會存在併發問題的,因為他是單程序的,再多的 command 都是 one by one 執行的。我們使用的時候,可能會出現併發問題,比如 get 和 set 這一對。
redis 為什麼會有高併發問題
redis 的出身決定
 Redis 是一種單執行緒機制的 nosql 資料庫,基於 key-value,資料可持久化落盤。由於單執行緒所以 redis 本身並沒有鎖的概念,多個客戶端連線並不存在競爭關係,但是利用 jedis 等客戶端對 redis 進行併發訪問時會出現問題。發生連線超時、資料轉換錯誤、阻塞、客戶端關閉連線等問題,這些問題均是由於客戶端連線混亂造成。
 同時,單執行緒的天性決定,高併發對同一個鍵的操作會排隊處理,如果併發量很大,可能造成後來的請求超時。
 在遠端訪問 redis 的時候,因為網路等原因造成高併發訪問延遲返回的問題。
解決辦法
 在客戶端將連線進行池化,同時對客戶端讀寫 Redis 操作採用內部鎖 synchronized。
 伺服器角度,利用 setnx 變向實現鎖機制。
37.秒殺當中的細節你是怎麼得出來的

答:通過效能測試及模擬秒殺場景。每個問題都經過反覆測試,不斷的發現問題,不斷的解決。
38.做秒殺用什麼資料庫,怎麼實現的。

答:因為秒殺的一瞬間,併發非常大,如果同時請求資料庫,會導致資料庫的壓力非常大,導致資料庫的效能急劇下降,更嚴重的可能會導致資料庫伺服器宕機。這時候一般採用記憶體快取記憶體資料庫 redis 來實現的,redis 是非關係型資料庫,redis 是單執行緒的,通過 redis 的佇列可以完成秒殺過程。
39.支付寶流程怎麼實現的

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

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

答:當用戶第一次訪問應用系統的時候,因為還沒有登入,會被引導到認證系統中進行登入;根據使用者提供的登入資訊,認證系統進行身份校驗,如果通過校驗,應該返回給使用者一個認證的憑據--ticket;使用者再訪問別的應用的時候,就會將這個 ticket 帶上,作為自己認證的憑據,應用系統接受到請求之後會把 ticket 送到認證系統進行校驗,檢查 ticket 的合法性。如果通過校驗,使用者就可以在不用再次登入的情況下訪問應用系統 2 和應用系統 3 了。
實現主要技術點:
 1、兩個站點共用一個數據驗證系統
 2、主要通過跨域請求的方式來實現驗證及 session 處理。
42.怎麼實現第三方登入?

答:第三方登陸主要是基於 author 協議來實現,下面簡單說下實現流程:
 1、首先我們需要以開發者的身份向第三方登陸平臺申請接入應用,申請成功後,我們會獲得一個 appID 和一個 secrectID.
 2、當我們的網站需接入第三方登陸時,會引導使用者跳轉到第三方的登陸授權頁面,此時把之前申請的 appID 和 secrectID 帶給登陸授權頁面。
 3、使用者登陸成功後即得到授權,第三方會返回一個臨時的 code 給我們的網站。
 4、我們的網站接受到 code 後,再次向我們的第三方發起請求,並攜帶接收的 code,從第三方獲取 access_token.
 5、第三方處理請求後,會返回一個 access_token 給我們的網站,我們的網站獲取到 access_token 後就可以呼叫第三方提供的介面了,比如獲取使用者資訊等。最後把該使用者資訊存入到我們站點的資料庫,並把資訊儲存到 session 中,實現使用者的第三方登陸。
43.如何處理負載、高併發?(好好看看,經常問到,能回答到主要的東西即可)

答:從低成本、高效能和高擴張性的角度來說有如下處理方案:
1、HTML 靜態化
其實大家都知道,效率最高、消耗最小的就是純靜態化的 html 頁面,所以我們儘可能使我們的 網站上的頁面採用靜態頁面來實現,這個最簡單的方法其實也是最有效的方法。
2、圖片伺服器分離
把圖片單獨儲存,儘量減少圖片等大流量的開銷,可以放在一些相關的平臺上,如騎牛等
3、資料庫叢集和庫表雜湊及快取
資料庫的併發連線為 100,一臺資料庫遠遠不夠,可以從讀寫分離、主從複製,資料庫叢集方面來著手。另外儘量減少資料庫的訪問,可以使用快取資料庫如 memcache、redis。
4、映象:
儘量減少下載,可以把不同的請求分發到多個映象端。
5、資料庫優化
6、負載均衡:
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。
44.做秒殺時鎖表考慮到沒有?

答:考慮到了,當時我們做秒殺時考慮了好幾種方案,其中有一種就是使用事務加上排他鎖來實現。
架構類的東西接觸過嗎?
 有接觸過,曾經自己在自己的伺服器上配置過。我以前做過以下幾個架構方面的配置和測試;
 1、資料庫的讀寫分離、主從複製及叢集。
 2、Nginx 負載均衡
 3、redis 叢集及主從
45.封裝過一個簡單的框架

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

答:核心思想是:檢視和使用者互動通過事件導致控制器改變 控制器改變導致模型改變 或者控制器同時改變兩者 模型改變 導致檢視改變 或者檢視改變 潛在的從模型裡面獲得引數 來改變自己。他的好處是可以將介面和業務邏輯分離。
Model(模型),是程式的主體部分,主要包含業務資料和業務邏輯。在模型層,還會涉及到使用者釋出的服務,在服務中會根據不同的業務需求,更新業務模型中的資料。
View(檢視),是程式呈現給使用者的部分,是使用者和程式互動的介面,使用者會根據具體的業務需求,在 View 檢視層輸入自己特定的業務資料,並通過介面的事件互動,將對應的輸入引數提交給後臺控制器進行處理。
Contorller(控制器),Contorller 是用來處理使用者 輸入資料,已經更新業務模型的部分。控制器中接收了使用者與介面互動時傳遞過來的資料,並根據資料業務邏輯來執行服務的呼叫和更新業務模型的資料和狀態。
47.session 與 cookie 的區別

答:1、cookie 資料存放在第三方應用的瀏覽器上,session 資料放在伺服器上。
 2、cookie 不是很安全,別人可以分析存放在本地的 COOKIE,進行 COOKIE 欺騙
考慮到安全應當使用 session。
3、session 會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能
考慮到減輕伺服器效能方面,應當使用 COOKIE。
4、單個 cookie 儲存的資料不能超過 4K,很多瀏覽器都限制一個站點最多儲存 20 個 cookie。
5、所以個人建議:
 將登陸資訊等重要資訊存放為 SESSION
 其他資訊如果需要保留,可以放在 COOKIE
48.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 的結果沒有意義,因為都是列印"
"。因此用 var_dump()函式更適合除錯。print_r 是函式,可以打印出比較複雜的變數(如陣列,物件),有返回值
var_dump()判斷一個變數的型別與長度,並輸出變數的數值,如果變數有值輸的是變數的值並回返資料型別。此函式顯示關於一個或多個表示式的結構資訊,包括表示式的型別與值。陣列將遞迴展開值,通過縮排顯示其結構。
49.說一下單引號雙引號?

答:①單引號內部的變數不會執行, 雙引號會執行
②單引號解析速度比雙引號快。
③單引號只能解析部分特殊字元,雙引號可以解析所有特殊字元。
50.索引的優缺點

答:1、優點:

a)可以保證資料庫表中每一行的資料的唯一性

b)可以大大加快資料的索引速度

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

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

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

2、 缺點:

a) 建立索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加

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

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

d) 建立索引的原則

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

f) 在作為主鍵的列上,強制該列的唯一性和組織表中資料的排列結構

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

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

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

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