1.請自我介紹一下?
答:我叫 xxx,來自北京,20xx 年畢業(yè)于 xx 大學計算機 xx 系,畢業(yè)后在武漢從事了 x 年的 php 開發(fā)工作,公司是一個外包公司,主要做微信開發(fā),公眾號推廣,商城,,論壇的開發(fā)
2.你在公司負責那些項目?
答:由于我們公司是一個外包公司,不可能只做一個項目,公司的項目都是交叉進行的,論壇,微信,商城我都做過?
3.你為什么來深圳?
答:因為我哥在這邊,父母也希望兄弟間有個照應(根據(jù)自己的餓情況回答),而且深圳是一線城市,技術(shù)也比廣西前沿一些
4.武漢使用什么前端框架和后端框架?
答:根據(jù)自己的區(qū)域回答
5.你做過那些模塊?
答:登陸注冊,商品管理,購物車模塊,訂單管理
6.你們公司是使用什么框架?
答:我們公司采用的是 TP 框架,運用的 mysql+apache+php 進行開發(fā),因為 TP 框架是一個免費開源的,輕量級的 php 開發(fā)框架,而且是我們中國人自己開發(fā)的,也是國內(nèi)用的比較多的,各種資料也比較齊全
7.mvc 是什么?相互間有什么關(guān)系?
答:mvc 是一種開發(fā)模式,主要分為三部分:m(model),也就是模型,負責數(shù)據(jù)的操作;v(view),也就是視圖,負責前后臺的顯示;c(controller),也就是控制器,負責業(yè)務邏輯
客戶端請求項目的控制器,如果執(zhí)行過程中需要用到數(shù)據(jù),控制器就會到模型中獲取數(shù)據(jù),再將獲取到的數(shù)據(jù)通過視圖顯示出來
8.OOP是什么?
答:oop 是面向?qū)ο缶幊蹋嫦驅(qū)ο缶幊淌且环N計算機編程架構(gòu),OOP 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或?qū)ο蠼M合而成。
OOP 具有三大特點
1、封裝性:也稱為信息隱藏,就是將一個類的使用和實現(xiàn)分開,只保留部分接口和方法與外部聯(lián)系,或者說只公開了一些供開發(fā)人員使用的方法。于是開發(fā)人員只 需要關(guān)注這個類如何使用,而不用去關(guān)心其具體的實現(xiàn)過程,這樣就能實現(xiàn) MVC 分工合作,也能有效避免程序間相互依賴,實現(xiàn)代碼模塊間松藕合。
2、繼承性:就是子類自動繼承其父級類中的屬性和方法,并可以添加新的屬性和方法或者對部分屬性和方法進行重寫。繼承增加了代碼的可重用性。PHP 只支持單繼承,也就是說一個子類只能有一個父類。
3、多態(tài)性:子類繼承了來自父級類中的屬性和方法,并對其中部分方法進行重寫。于是多個子類中雖然都具有同一個方法,但是這些子類實例化的對象調(diào)用這些相同的方法后卻可以獲得完全不同的結(jié)果,這種技術(shù)就是多態(tài)性。多態(tài)性增強了軟件的靈活性,具體表現(xiàn)在:
3.1 易維護:采用面向?qū)ο笏枷朐O(shè)計的結(jié)構(gòu),可讀性高,由于繼承的存在,即使改變需求,那么維護也只是在局部模塊,所以維護起來是非常方便和較低成本的。
3.2 質(zhì)量高:在設(shè)計時,可重用現(xiàn)有的,在以前的項目的領(lǐng)域中已被測試過的類使系統(tǒng)滿足業(yè)務需求并具有較高的質(zhì)量。
3.3 效率高:在軟件開發(fā)時,根據(jù)設(shè)計的需要對現(xiàn)實世界的事物進行抽象,產(chǎn)生類。使用這樣的方法解決問題,接近于日常生活和自然的思考方式,勢必提高軟件開發(fā)的效率和質(zhì)量。
3.4易擴展:由于繼承、封裝、多態(tài)的特性,自然設(shè)計出高內(nèi)聚、低耦合的系統(tǒng)結(jié)構(gòu),使得系統(tǒng)更靈活、更容易擴展,而且成本較低。
9.smarty 是什么,有什么作用?
答:回答一:smarty 是用 php 寫出來的模板引擎,也是目前業(yè)界最著名的 php 模板引擎之一它分離了邏輯代碼和外在的顯示,提供了一種易于管理和使用的方法,用來將混雜的 php 邏輯代碼與 html 代碼進行分離
回答二:smarty 是 php 中最著名的引擎框架之一,我們公司使用的是 TP 框架,已經(jīng)封裝好了 smarty 模板,所以沒有單獨使用過
回答三:smarty 是個模板引擎,最顯著的地方就是有可以把模板緩存起來。一般模板來說,都是做一個靜態(tài)頁面,然后在里面把一些動態(tài)的部分用一切分隔符切開,然后在 PHP 里打開這個模板文件,把分隔符里面的值替換掉,然后輸出來,你可以看下 PHPLib 里面的template 部分。
而 smarty 設(shè)定了緩存參數(shù)以后,第一次運行時候會把模板打開,在 php 替換里面值的時候把讀取的 html 和 php 部分重新生成一個臨時的 php 文件,這樣就省去了每次打開都重新讀取 html 了。如果修改了模板,只要重新刷下就行了。
10.TP 框架有哪些優(yōu)點?
答:TP 框架是我們中國人自己開發(fā)的框架,各種資料比較齊全,國內(nèi)用的比較多,比較簡單和方便,而且是免費開源的
11.TP 的特性有哪些?
答:
- 多表查詢非常方便,在 model 中幾句代碼就可以完成對多表的關(guān)聯(lián)操作
- 融合了 smarty 模板,使前后臺分離
- 命名規(guī)范,模型,視圖,控制器嚴格遵循命名規(guī)則,通過命名一一對應
- 命名規(guī)范,模型,視圖,控制器嚴格遵循命名規(guī)則,通過命名一一對應
- 支持多種 url 模式
- 內(nèi)置 ajax 返回方法,包括 xml,json,html 等
- 支持應用擴展,類庫擴展,驅(qū)動擴展等
12.TP 框架中的大字母函數(shù)?
答:U:對 url 的組裝
A:內(nèi)部實例化控制器
S:緩存處理
R:調(diào)用某個控制器的操作方法
D:實例化自定義模型類
M:實例化基礎(chǔ)模型類
I:獲取參數(shù)
L:設(shè)置或者獲取當前語言
C:設(shè)置或獲取,保存配置
13.請介紹一下 laravel 框架?
答:laravel 框架的設(shè)計思想比較先進,非常適合應用各種開發(fā)模式,作為一個框架,它為你準備好了一切,composer 是 php 的未來。
laravel 框架最大的特點和優(yōu)秀之處就是集合了 php 比較新的特點,以及各種各樣的設(shè)計模式,Ioc 模式,依賴注入等
14.laravel 有那些特點?
答:回答一:
- 強大的 rest router:用簡單的回調(diào)函數(shù)就可以調(diào)用,快速綁定 controller 和 router
- artisan:命令行工具,很多手動的工作都自動化
- 可繼承的模板,簡化 view 的開發(fā)和管理
- blade 模板:渲染速度更快
- ORM 操作數(shù)據(jù)
- migration:管理數(shù)據(jù)庫和版本控制
- 測試功能也很強大
- composer 也是亮點
回答二:laravel 框架引入了門面,依賴注入,Ioc 模式,以及各種各樣的設(shè)計模式等
15.請簡述一下數(shù)據(jù)庫的優(yōu)化?
答:數(shù)據(jù)庫的優(yōu)化可以從四個方面來優(yōu)化:
- 從結(jié)構(gòu)層: web 服務器采用負載均衡服務器,mysql 服務器采用主從復制,讀寫分離
- 從儲存層: 采用合適的存儲引擎,采用三范式
- 從設(shè)計層: 采用分區(qū)分表,索引,表字段合適的字段屬性,適當采用逆范式,開啟 mysql 緩存
- sql 語句層:結(jié)果一樣的情況下,采用效率高,速度快節(jié)省資源的 sql 語句執(zhí)行
16.如何解決異常處理?
答: 拋出異常:使用 try...catch,異常的代碼放在 try 代碼塊內(nèi),如果沒有觸發(fā)異常,則代碼繼續(xù)執(zhí)行,如果異常被觸發(fā),就會拋出一個異常。Catch 代碼塊捕獲異常,并創(chuàng)建一個包含異常信息的對象。$e->getMessage(),輸出異常的錯誤信息。
解決異常:使用 set_error_handler 函數(shù)獲取異常(也可以使用 try()和 catch()函數(shù)),然后使用 set_exception_handler()函數(shù)設(shè)置默認的異常處理程序,register_shutdown_function()函數(shù)來執(zhí)行,執(zhí)行機制是,php 要把調(diào)入的函數(shù)調(diào)入到內(nèi)存,當頁面所有的 php 語句都執(zhí)行完成時,再調(diào)用此函數(shù)
17.前端
答:我在工作中處理前端的功能,一般就是用 ajax 向后臺請求數(shù)據(jù),然后返回數(shù)據(jù)在前臺頁面中顯示出來。我從來沒有獨立的完整的將 html 和 css 樣式都一個人完成,如果公司實在有這樣的需求的話,我可能會找一些前臺的模板或者說是前端的框架,比如說 h—ui 等等
18.權(quán)限管理(RBAC)的實現(xiàn)?
答:
- 首先創(chuàng)建一張用戶表:id name auto(保存格式為:控制器-方法)
- 然后在后臺中創(chuàng)建一個基類控制器,控制器里封裝一個構(gòu)造方法,當用戶登陸成功后,使用 TP 框架中封裝好的 session 函數(shù)獲取保存在服務器中的 session id,然后實例化模型,通過用戶 id 獲取保存在數(shù)據(jù)表中的 auth 數(shù)據(jù),使用 explode 函數(shù)分割獲取到的數(shù)據(jù),并使用一個數(shù)組保存起來,然后使用 TP 框架中封裝好的常量獲取當前控制器和方法,然后把他們組裝成字符串,使用 in_array 函數(shù)進行判斷該數(shù)組中是否含有當前獲取到的控制器和方法,如果沒有,就提示該用戶沒有權(quán)限,如果有就進行下一步操作
19.支付功能的實現(xiàn)?
答:
20.怎么保證促銷商品不會超賣
答:這個問題是我們當時開發(fā)時遇到的一個難點,超賣的原因主要是下的訂單的數(shù)目和我們要促銷的商品的數(shù)目不一致導致的,每次總是訂單的數(shù)比我們的促銷商品的數(shù)目要多,當時我們的小組討論了好久,給出了好幾個方案來實現(xiàn):
第一種方案是:①在每次下訂單前我們判斷促銷商品的數(shù)量夠不夠,不夠不允許下訂單,更改庫存量時加上一個條件,只更改商品庫存大于 0 的商品的庫存,當時我們使用 ab 進行壓力測試,當并發(fā)超過 500,訪問量超過 2000 時,還是會出現(xiàn)超賣現(xiàn)象。所以被我們否定了。
第二種方案是:②使用 mysql 的事務加排他鎖來解決,首先我們選擇數(shù)據(jù)庫的存儲引擎為 innoDB,使用的是排他鎖實現(xiàn)的,剛開始的時候我們測試了下共享鎖,發(fā)現(xiàn)還是會出現(xiàn)超賣的現(xiàn)象。有個問題是,當我們進行高并發(fā)測試時,對數(shù)據(jù)庫的性能影響很大,導致數(shù)據(jù)庫的壓力很大,最終也被我們否定了。
第三種方案是:③使用文件鎖實現(xiàn)。當用戶搶到一件促銷商品后先觸發(fā)文件鎖,防止其他用戶進入,該用戶搶到促銷品后再解開文件鎖,放其他用戶進行操作。這樣可以解決超賣的問題,但是會導致文件得 I/O 開銷很大。
最后我們使用了 redis 的隊列來實現(xiàn)。將要促銷的商品數(shù)量以隊列的方式存入 redis 中,每當用戶搶到一件促銷商品則從隊列中刪除一個數(shù)據(jù),確保商品不會超賣。這個操作起來很方便,而且效率極高,最終我們采取這種方式來實現(xiàn)
21.商城秒殺的實現(xiàn)
答:搶購、秒殺是如今很常見的一個應用場景,主要需要解決的問題有兩個:
- 高并發(fā)對數(shù)據(jù)庫產(chǎn)生的壓力
- 競爭狀態(tài)下如何解決庫存的正確減少(”超賣”問題)
對于第一個問題,已經(jīng)很容易想到用緩存來處理搶購,避免直接操作數(shù)據(jù)庫,例如使用 Redis。
第二個問題,我們可以使用 redis 隊列來完成,把要秒殺的商品放入到隊列中,因為 pop 操作是原子的,即使有很多用戶同時到達,也是依次執(zhí)行,文件鎖和事務在高并發(fā)下性能下降很快,當然還要考慮其他方面的東西,比如搶購頁面做成靜態(tài)的,通過 ajax 調(diào)用接口,其中也可能會出現(xiàn)一個用戶搶多次的情況,這時候需要再加上一個排隊隊列和搶購結(jié)果隊列及庫存隊列。高并發(fā)情況下,將用戶進入排隊隊列,用一個線程循環(huán)處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結(jié)果隊列,如果在,則已搶購,否則未搶購,庫存減 1,寫數(shù)據(jù)庫,將用戶入結(jié)果隊列。
22.購物車的原理
答:購物車相當于現(xiàn)實中超市的購物車,不同的是一個是實體車,一個是虛擬車而已。用戶可以在購物網(wǎng)站的不同頁面之間跳轉(zhuǎn),以選購自己喜愛的商品,點擊購買時,該商品就自動保存到你的購物車中,重復選購后,最后將選中的所有商品放在購物車中統(tǒng)一到付款臺結(jié)賬,這也是盡量讓客戶體驗到現(xiàn)實生活中購物的感覺。服務器通過追蹤每個用戶的行動,以保證在結(jié)賬時每件商品都物有其主。
主要涉及以下幾點:
- 把商品添加到購物車,即訂購
- 刪除購物車中已定購的商品
- 修改購物車中某一本圖書的訂購數(shù)量
- 清空購物車
- 顯示購物車中商品清單及數(shù)量、價格
實現(xiàn)購物車的關(guān)鍵在于服務器識別每一個用戶并維持與他們的聯(lián)系。但是 HTTP 協(xié)議是一種“無狀態(tài)(Stateless)”的協(xié)議,因而服務器不能記住是誰在購買商品,當把商品加入購物車時,服務器也不知道購物車里原先有些什么,使得用戶在不同頁面間跳轉(zhuǎn)時購物車無法“隨身攜帶”,這都給購物車的實現(xiàn)造成了一定的困難。
目前購物車的實現(xiàn)主要是通過 cookie、session 或結(jié)合數(shù)據(jù)庫的方式。下面分析一下它們的機制及作用。
1、cookie
cookie 是由服務器產(chǎn)生,存儲在客戶端的一段信息。它定義了一種 Web 服務器在客戶端存儲和返回信息的機制,cookie 文件它包含域、路徑、生存期、和由服務器設(shè)置的變量值等內(nèi)容。當用戶以后訪問同一個 Web 服務器時,瀏覽器會把 cookie 原樣發(fā)送給服務器。通過讓服務器讀取原先保存到客戶端的信息,網(wǎng)站能夠為瀏覽者提供一系列的方便,例如在線交易過程中標識用戶身份、安全要求不高的場合避免用戶重復輸入名字和密碼、門戶網(wǎng)站的主頁定制、有針對性地投放廣告等等。利用 cookie 的特性,大大擴展了 WEB 應用程序的功能,不僅可以建立服務器與客戶機的聯(lián)系,因為 cookie 可以由服務器定制,因此還可以將購物信息生成 cookie 值存放在客戶端,從而實現(xiàn)購物車的功能。用基于 cookie 的方式實現(xiàn)服務器與瀏覽器之間的會話或購物車,有以下特點:
(1)cookie 存儲在客戶端,且占用很少的資源,瀏覽器允許存放 300 個 cookie,每個 cookie 的大小為 4KB,足以滿足購物車的要求,同時也減輕了服務器的負荷;
(2)cookie 為瀏覽器所內(nèi)置,使用方便。即使用戶不小心關(guān)閉了瀏覽器窗口,只要在 cookie 定義的有效期內(nèi),購物車中的信息也不會丟失;
(3)cookie 不是可執(zhí)行文件,所以不會以任何方式執(zhí)行,因此也不會帶來病毒或攻擊用戶的系統(tǒng);
(4)基于 cookie 的購物車要求用戶瀏覽器必須支持并設(shè)置為啟用 cookie,否則購物車則失效;
(5)存在著關(guān)于 cookie 侵犯訪問者隱私權(quán)的爭論,因此有些用戶會禁止本機的 cookie 功能。
2、session
session 是實現(xiàn)購物車的另一種方法。session 提供了可以保存和跟蹤用戶的狀態(tài)信息的功能,使當前用戶在 session 中定義的變量和對象能在頁面之間共享,但是不能為應用中其他用戶所訪問,它與 cookie 最重大的區(qū)別是,session 將用戶在會話期間的私有信息存儲在服務器端,提高了安全性。在服務器生成 session 后,客戶端會生成一個 sessionid 識別號保存在客戶端,以保持和服務器的同步。這個 sessionid 是只讀的,如果客戶端禁止 cookie 功能,session 會通過在 URL 中附加參數(shù),或隱含在表單中提交等其他方式在頁面間傳送。因此利用 session 實施對用戶的管理則更為安全、有效。
同樣,利用 session 也能實現(xiàn)購物車,這種方式的特點是:
(1)session 用新的機制保持與客戶端的同步,不依賴于客戶端設(shè)置;
(2)與 cookie 相比,session 是存儲在服務器端的信息,因此顯得更為安全,因此可將身份標示,購物等信息存儲在 session 中;
(3)session 會占用服務器資源,加大服務器端的負載,尤其當并發(fā)用戶很多時,會生成大量的 session,影響服務器的性能;
(4)因為 session 存儲的信息更敏感,而且是以文件形式保存在服務器中,因此仍然存在著安全隱患。
3、結(jié)合數(shù)據(jù)庫的方式
這也是目前較普遍的模式,在這種方式中,數(shù)據(jù)庫承擔著存儲購物信息的作用,session 或 cookie 則用來跟蹤用戶。這種方式具有以下特點:
(1)數(shù)據(jù)庫與 cookie 分別負責記錄數(shù)據(jù)和維持會話,能發(fā)揮各自的優(yōu)勢,使安全性和服務器性能都得到了提高;
(2)每一個購物的行為,都要直接建立與數(shù)據(jù)庫的連接,直至對表的操作完成后,連接才釋放。當并發(fā)用戶很多時,會影響數(shù)據(jù)庫的性能,因此,這對數(shù)據(jù)庫的性能提出了更高的要求;
(3)使 cookie 維持會話有賴客戶端的支持。
各種方式的選擇:
雖然 cookie 可用來實現(xiàn)購物車,但必須獲得瀏覽器的支持,再加上它是存儲在客戶端的信息,極易被獲取,所以這也限制了它存儲更多,更重要的信息。所以一般 cookie 只用來維持與服務器的會話,例如國內(nèi)最大的當當網(wǎng)絡(luò)書店就是用 cookie 保持與客戶的聯(lián)系,但是這種方式最大的缺點是如果客戶端不支持 cookie 就會使購物車失效。
Session 能很好地與交易雙方保持會話,可以忽視客戶端的設(shè)置。在購物車技術(shù)中得到了廣泛的應用。但 session 的文件屬性使其仍然留有安全隱患。
結(jié)合數(shù)據(jù)庫的方式雖然在一定程度上解決了上述的問題,但從上面的例子可以看出:在這種購物流程中涉及到對數(shù)據(jù)庫表的頻繁操作,尤其是用戶每選購一次商品,都要與數(shù)據(jù)庫進行連接,當用戶很多的時候就加大了服務器與數(shù)據(jù)庫的負荷。
23.redis 消息隊列先進先出需要注意什么
答:通常使用一個 list 來實現(xiàn)隊列操作,這樣有一個小限制,所以的任務統(tǒng)一都是先進先出,如果想優(yōu)先處理某個任務就不太好處理了,這就需要讓隊列有優(yōu)先級的概念,我們就可以優(yōu)先處理高級別的任務,實現(xiàn)方式有以下幾種方式:
1)單一列表實現(xiàn):隊列正常的操作是 左進右出(lpush,rpop)為了先處理高優(yōu)先級任務,在遇到高級別任務時,可以直接插隊,直接放入隊列頭部(rpush),這樣,從隊列頭部(右側(cè))獲取任務時,取到的就是高優(yōu)先級的任務(rpop)
2)使用兩個隊列,一個普通隊列,一個高級隊列,針對任務的級別放入不同的隊列,獲取任務時也很簡單,redis 的 BRPOP 命令可以按順序從多個隊列中取值,BRPOP 會按照給出的 key 順序查看,并在找到的第一個非空 list 的尾部彈出一個元素,redis> BRPOP list1 list2 0
list1 做為高優(yōu)先級任務隊列
list2 做為普通任務隊列
這樣就實現(xiàn)了先處理高優(yōu)先級任務,當沒有高優(yōu)先級任務時,就去獲取普通任務
方式 1 最簡單,但實際應用比較局限,方式 3 可以實現(xiàn)復雜優(yōu)先級,但實現(xiàn)比較復雜,不利于維護
方式 2 是推薦用法,實際應用最為合適
24.你負責的模塊有哪些難題
答:在我負責的 B2B 電商項目中,當時我負責的是訂單模塊,由于客戶一次選擇了多家商戶的商品,最終生成了一個訂單,這樣我們平臺在給商戶結(jié)算時出現(xiàn)了不知道這比費用應該給哪個商戶,這時候我們小組經(jīng)過討論,需要涉及到訂單拆分,也就是說用戶點擊支付后,如果有多件商品,并且不是同一家店鋪那么 就要用到訂單的拆分,比如如果有兩件商品,并且不是同一店鋪 就在原來的訂單號下 在生成兩個子訂單號 并修改訂單表中兩件商品的訂單號。最終實現(xiàn)了商品的分配管理,解決了我們的難題。
我覺得在開發(fā)過程中,遇到的難題無非是兩個,一個是技術(shù)層次的,我認為,只要你有恒心,有熱心,沒有覺得不了的難題。另一個就是溝通問題,在任何地方任何時候溝通都是最重要的,尤其是我們做開發(fā)的,不溝通好,會影響整個項目的進度,我本人是個非常還溝通的人,所以這點上也沒多大問題。
25.用戶下單是怎么處理的
答:判斷用戶有沒有登錄,在沒有登錄的情況下,不允許下單。登陸后,可進行下單,并生成唯一的訂單號,此時訂單的狀態(tài)為未支付。
26.電商的登錄是怎么實現(xiàn)的
答:分為普通登錄和第三方登錄 這邊主要說一下第三方登錄吧,第三方登陸主要使用的是 author 協(xié)議,我就以 QQ 的第三方登陸為例來進行說明:當用戶在我們的站點請求 QQ 的第三方登陸時,我們站點會引導用戶跳轉(zhuǎn)到 QQ 的登陸授權(quán)界面, 當用戶輸入 QQ 和密碼成功登錄以后會自動跳回到我們站點設(shè)置好的回調(diào)頁面,并附帶一個 code 參數(shù),接著你使用 code 再次去請求 QQ 的授權(quán)頁面,就可以從中獲取到一個 access token(訪問令牌),通過這個 access_token,我們可以調(diào)用 QQ 提供給我們的接口,比如獲取 open_id,可以獲取用戶的基本信息。獲取到之后,我們需要拿用戶的授權(quán)信息和 open_id 和我們平臺的普通用戶進行綁定。這樣不管是普通用戶登陸還是第三方登陸用戶,都可以實現(xiàn)登陸。
27.接口安全方面是怎么處理的
答:我們當時是這么做的,使用 HTTP 的 POST 方式,對固定參數(shù)+附加參數(shù)進行數(shù)字簽名,使用的是 md5 加密,比如:我想通過標題獲取一個息,在客戶端使用 信息標題+日期+雙方約定好的一個 key 通過 md5 加密生成一個簽名(sign),然后作為參數(shù)傳遞到服務器端,服務器端使用同樣的方法進行校驗,如何接受過來的 sign 和我們通過算法算的值相同,證明是一個正常的接口請求,我們才會返回相應的接口數(shù)據(jù)。
28.用的什么技術(shù)實現(xiàn)短信發(fā)送,在哪調(diào)用
答:我主要用的第三方短信接口,在申請接口時進行相應信息的配置,然后在我們站點需要用到短信驗證的地方進行調(diào)用,我們通常在用戶注冊時使用到。
29.在工作中遇到過什么困難?
答:總體來說:在工作我主要遇到這幾個問題比較難處理:
① 我之前工作的時候發(fā)現(xiàn)經(jīng)常會出現(xiàn)一些臨時需求打亂了我的計劃,搞得有時候這個任務還沒完成,又得去做其他的任務,最后一天下來,大大小小的東西是很多,但是沒有完成得非常好的,后面我總結(jié)了一下,我會把這些都添加優(yōu)先級,遇到臨時需求,按照優(yōu)先級重新將已有任務和臨時任務進行排版,保證在規(guī)定時間內(nèi)有效率的完成優(yōu)先級高的任務。
② 在做項目需求時候,遇到理解能力欠佳的人,溝通時容易被氣到,影響自己的情緒,最后反倒還不能到達需要的效果。后面,每次到這種時候,我一般會借助一些紙質(zhì)的、更加形象的東西,讓雙方都認同的、都能明白的一種方式來進行溝通,后面減少了很多不必須的麻煩。大家都知道,對于程序員來說,改需求是一件很痛苦的事情,所以前期的溝通工作很重要。
③ 還有一件事時,我以前的領(lǐng)導不太懂技術(shù),所以每次出一個新的需求出來,總是要求我們在很短的時間內(nèi)完成,完不成我們就會被懷疑能力有問題。當然,每個領(lǐng)導都希望自己的員工能夠盡快的完成任務,降低成本,提高效率。這時候我會把我們的需求細化,把其中的重點、難點都列出來,做好時間規(guī)劃,耐心的跟領(lǐng)導溝通,項目每個點的重要性和時間的花費比例,確保在這個規(guī)劃的時間點內(nèi)保質(zhì)保量的完成任務。慢慢的也得到了領(lǐng)導的認可,其實領(lǐng)導也不是一味的不通情理,只要把東西計劃好了,以最小的代價換取最高的價值,每個人都是很容易理解得
30.用戶不登錄,怎么直接加入購物車的
答:用戶在不登錄的情況下,可以把要購買商品的信息(如商品的 ID,商品的價格、商品的 sku_id,購買數(shù)量等關(guān)鍵數(shù)據(jù))存到 COOKIE 里面,當?shù)顷懙那闆r下。把 COOKIE 里面的內(nèi)容存到數(shù)據(jù)庫,并清除 cookie 中的數(shù)據(jù)。
31.寫過接口嗎,怎么定義接口的
答:寫過。接口分為兩種:一種是數(shù)據(jù)型接口,一種是應用型接口。
數(shù)據(jù)型接口:是比抽象類更抽象的某種“結(jié)構(gòu)”——它其實不是類,但是跟類一樣的某種語法結(jié)構(gòu),是一種結(jié)構(gòu)規(guī)范,規(guī)范我們類要以什么格式進行定義,一般用于團隊比較大,分支比較多的情況下使用。
應用型接口: API(application interface) 數(shù)據(jù)對外訪問的一個入口
我主要是參與的 APP 開發(fā)中接口的編寫,客戶端需要什么樣的數(shù)據(jù),我們就給他們提供相應的數(shù)據(jù),數(shù)據(jù)以 json/xml 的格式返回,并且配以相應的接口文檔。
32.sku 減庫存
答:SKU = Stock Keeping Unit (庫存量單位)
即庫存進出計量的單位,可以是以件,盒,托盤等為單位。SKU 是庫存量單位,區(qū)分單品。
在服裝、鞋類商品中使用最多最普遍。 例如紡織品中一個 SKU 通常表示:規(guī)格、顏色、款式。
在設(shè)計表時,不僅僅只有商品表,商品表中有個總庫存,我們還需要涉及一張 SKU 表,里面有 SKU 庫存和單價字段,用戶每購買一件商品,實際上購買的都是 SKU 商品,這樣在下訂單成功后,應該根據(jù)所購買的商品的唯一的 SKU 號來進行相應的 SKU 庫存的減少,當然商品的總庫存保存在商品主表中,也需要減少總庫存中的庫存量。
33.庫存設(shè)置?
答:庫存分為商品總庫存和 SKU 庫存,往往商品總庫存的為 SKU 庫存的總和。一般在商城的后臺對貨品設(shè)置最高庫存及最低庫存后,當前庫存數(shù)量與最高、最低兩者比較,超出庫存或者低于庫存的,則被統(tǒng)計成報表形式反映,便于用戶掌握貨品庫存超、短缺狀態(tài)及數(shù)量。
34.訂單、庫存兩個表 如何保證數(shù)據(jù)的一致性?
答:在一個電子商務系統(tǒng)中,正常的應該是訂單生成成功后,相應的庫存進行減少。必須要保證兩者的一致性,但有時候因為某些原因,比如程序邏輯問題,并發(fā)等問題,導致下單成功而庫存沒有減少的情況。這種情況我們是不允許發(fā)生的,MySQL 中的事務剛好可以解決這一問題,首先得選擇數(shù)據(jù)庫的存儲引擎為 innoDB,事務規(guī)定了只有下訂單完成了,并且相應的庫存減少了才允許提交事務,否則就事務回滾,確保數(shù)據(jù)一致性。
35.O2O 用戶下單,c 端下單,如何保證 b a 端數(shù)據(jù)一致?
答:O2O 為線上和線下模式,O2O 模式奉行的是“線上支付+實體店消費”的消費模式,即消費者在網(wǎng)上下單完成支付后,憑消費憑證到實體店消費。O2O 模式是把商家信息和支付程序放在線上進行,而把商品和服務兌現(xiàn)放在線下,也就是說 O2O 模式適用于快遞無法送達的有形產(chǎn)品。數(shù)據(jù)一致性的問題是 O2O 行業(yè)中最常見的問題,我們可以類似于數(shù)據(jù)庫的主從復制的思路來解決這個問題。O2O 有個供應商系統(tǒng),類似于主服務器,在 C 端(從服務器)下單時,數(shù)據(jù)同步更新到供應商系統(tǒng)端,b、a 實時從供應商系統(tǒng)中拉取數(shù)據(jù)進行同步,比如利用定時任務,定時拉取數(shù)據(jù)進行同步。
36.Redis 如何防止高并發(fā)
答:其實 redis 是不會存在并發(fā)問題的,因為他是單進程的,再多的 command 都是 one by one 執(zhí)行的。我們使用的時候,可能會出現(xiàn)并發(fā)問題,比如 get 和 set 這一對。
redis 為什么會有高并發(fā)問題
redis 的出身決定
Redis 是一種單線程機制的 nosql 數(shù)據(jù)庫,基于 key-value,數(shù)據(jù)可持久化落盤。由于單線程所以 redis 本身并沒有鎖的概念,多個客戶端連接并不存在競爭關(guān)系,但是利用 jedis 等客戶端對 redis 進行并發(fā)訪問時會出現(xiàn)問題。發(fā)生連接超時、數(shù)據(jù)轉(zhuǎn)換錯誤、阻塞、客戶端關(guān)閉連接等問題,這些問題均是由于客戶端連接混亂造成。
同時,單線程的天性決定,高并發(fā)對同一個鍵的操作會排隊處理,如果并發(fā)量很大,可能造成后來的請求超時。
在遠程訪問 redis 的時候,因為網(wǎng)絡(luò)等原因造成高并發(fā)訪問延遲返回的問題。
解決辦法
在客戶端將連接進行池化,同時對客戶端讀寫 Redis 操作采用內(nèi)部鎖 synchronized。
服務器角度,利用 setnx 變向?qū)崿F(xiàn)鎖機制。
37.秒殺當中的細節(jié)你是怎么得出來的
答:通過性能測試及模擬秒殺場景。每個問題都經(jīng)過反復測試,不斷的發(fā)現(xiàn)問題,不斷的解決。
38.做秒殺用什么數(shù)據(jù)庫,怎么實現(xiàn)的。
答:因為秒殺的一瞬間,并發(fā)非常大,如果同時請求數(shù)據(jù)庫,會導致數(shù)據(jù)庫的壓力非常大,導致數(shù)據(jù)庫的性能急劇下降,更嚴重的可能會導致數(shù)據(jù)庫服務器宕機。這時候一般采用內(nèi)存高速緩存數(shù)據(jù)庫 redis 來實現(xiàn)的,redis 是非關(guān)系型數(shù)據(jù)庫,redis 是單線程的,通過 redis 的隊列可以完成秒殺過程。
39.支付寶流程怎么實現(xiàn)的
答:首先要有一個支付寶賬號,接下來向支付寶申請在線支付業(yè)務,簽署協(xié)議。協(xié)議生效后有支付寶一方會給網(wǎng)站方一個合作伙伴 ID,和安全校驗碼,有了這兩樣東西就可以按照支付寶接口文檔開發(fā)支付寶接口了,中間主要涉及到一個安全問題。整個流程是這樣的:我們的網(wǎng)站通過 post 傳遞相應的參數(shù)(如訂單總金額,訂單號)到支付頁面,支付頁面把一系列的參數(shù)經(jīng)過處理,以 post 的方式提交給支付寶服務器,支付寶服務器進行驗證,并對接收的數(shù)據(jù)進行處理,把處理后的結(jié)果返回給我們網(wǎng)站設(shè)置的異步和同步回調(diào)地址,通過相應的返回參數(shù),來處理相應的業(yè)務邏輯,比如返回的參數(shù)代表支付成功,更改訂單狀態(tài)。
40.什么是單點登錄?
答:單點登錄 SSO(Single Sign On)說得簡單點就是在一個多系統(tǒng)共存的環(huán)境下,用戶在一處登錄后,就不用在其他系統(tǒng)中登錄,也就是用戶的一次登錄能得到其他所有系統(tǒng)的信任。
41.什么情況下使用緩存
答:當用戶第一次訪問應用系統(tǒng)的時候,因為還沒有登錄,會被引導到認證系統(tǒng)中進行登錄;根據(jù)用戶提供的登錄信息,認證系統(tǒng)進行身份校驗,如果通過校驗,應該返回給用戶一個認證的憑據(jù)--ticket;用戶再訪問別的應用的時候,就會將這個 ticket 帶上,作為自己認證的憑據(jù),應用系統(tǒng)接受到請求之后會把 ticket 送到認證系統(tǒng)進行校驗,檢查 ticket 的合法性。如果通過校驗,用戶就可以在不用再次登錄的情況下訪問應用系統(tǒng) 2 和應用系統(tǒng) 3 了。
實現(xiàn)主要技術(shù)點:
- 兩個站點共用一個數(shù)據(jù)驗證系統(tǒng)
- 主要通過跨域請求的方式來實現(xiàn)驗證及 session 處理。
42.怎么實現(xiàn)第三方登錄?
答:第三方登陸主要是基于 author 協(xié)議來實現(xiàn),下面簡單說下實現(xiàn)流程:
- 首先我們需要以開發(fā)者的身份向第三方登陸平臺申請接入應用,申請成功后,我們會獲得一個 appID 和一個 secrectID.
- 當我們的網(wǎng)站需接入第三方登陸時,會引導用戶跳轉(zhuǎn)到第三方的登陸授權(quán)頁面,此時把之前申請的 appID 和 secrectID 帶給登陸授權(quán)頁面。
- 用戶登陸成功后即得到授權(quán),第三方會返回一個臨時的 code 給我們的網(wǎng)站。
- 我們的網(wǎng)站接受到 code 后,再次向我們的第三方發(fā)起請求,并攜帶接收的 code,從第三方獲取 access_token.
- 第三方處理請求后,會返回一個 access_token 給我們的網(wǎng)站,我們的網(wǎng)站獲取到 access_token 后就可以調(diào)用第三方提供的接口了,比如獲取用戶信息等。最后把該用戶信息存入到我們站點的數(shù)據(jù)庫,并把信息保存到 session 中,實現(xiàn)用戶的第三方登陸。
43.如何處理負載、高并發(fā)?(好好看看,經(jīng)常問到,能回答到主要的東西即可)
答:從低成本、高性能和高擴張性的角度來說有如下處理方案:
1、HTML 靜態(tài)化
其實大家都知道,效率最高、消耗最小的就是純靜態(tài)化的 html 頁面,所以我們盡可能使我們的 網(wǎng)站上的頁面采用靜態(tài)頁面來實現(xiàn),這個最簡單的方法其實也是最有效的方法。
2、圖片服務器分離
把圖片單獨存儲,盡量減少圖片等大流量的開銷,可以放在一些相關(guān)的平臺上,如騎牛等
3、數(shù)據(jù)庫集群和庫表散列及緩存
數(shù)據(jù)庫的并發(fā)連接為 100,一臺數(shù)據(jù)庫遠遠不夠,可以從讀寫分離、主從復制,數(shù)據(jù)庫集群方面來著手。另外盡量減少數(shù)據(jù)庫的訪問,可以使用緩存數(shù)據(jù)庫如 memcache、redis。
4、鏡像:
盡量減少下載,可以把不同的請求分發(fā)到多個鏡像端。
5、數(shù)據(jù)庫優(yōu)化
6、負載均衡:
Apache 的最大并發(fā)連接為 1500,只能增加服務器,可以從硬件上著手,如 F5 服務器。當然硬件的成本比較高,我們往往從軟件方面著手。
負載均衡 (Load Balancing) 建立在現(xiàn)有網(wǎng)絡(luò)結(jié)構(gòu)之上,它提供了一種廉價有效透明的方法擴展網(wǎng)絡(luò)設(shè)備和服務器的帶寬、增加吞吐量、加強網(wǎng)絡(luò)數(shù)據(jù)處理能力,同時能夠提高網(wǎng)絡(luò)的靈活性和可用性。目前使用最為廣泛的負載均衡軟件是 Nginx、LVS、HAProxy。我分別來說下三種的優(yōu)缺點:
Nginx 的優(yōu)點是:
- 工作在網(wǎng)絡(luò)的 7 層之上,可以針對 http 應用做一些分流的策略,比如針對域名、目錄結(jié)構(gòu),它的正則規(guī)則比 HAProxy 更為強大和靈活,這也是它目前廣泛流行的主要原因之一,Nginx 單憑這點可利用的場合就遠多于 LVS 了。
- Nginx 對網(wǎng)絡(luò)穩(wěn)定性的依賴非常小,理論上能 ping 通就就能進行負載功能,這個也是它的優(yōu)勢之一;相反 LVS 對網(wǎng)絡(luò)穩(wěn)定性依賴比較大,這點本人深有體會;
- Nginx 安裝和配置比較簡單,測試起來比較方便,它基本能把錯誤用日志打印出來。LVS 的配置、測試就要花比較長的時間了,LVS 對網(wǎng)絡(luò)依賴比較大。
- 可以承擔高負載壓力且穩(wěn)定,在硬件不差的情況下一般能支撐幾萬次的并發(fā)量,負載度比 LVS 相對小些。
- Nginx 可以通過端口檢測到服務器內(nèi)部的故障,比如根據(jù)服務器處理網(wǎng)頁返回的狀態(tài)碼、超時等等,并且會把返回錯誤的請求重新提交到另一個節(jié)點,不過其中缺點就是不支持 url 來檢測。比如用戶正在上傳一個文件,而處理該上傳的節(jié)點剛好在上傳過程中出現(xiàn)故障,Nginx 會把上傳切到另一臺服務器重新處理,而 LVS 就直接斷掉了,如果是上傳一個很大的文件或者很重要的文件的話,用戶可能會因此而不滿。
- Nginx 不僅僅是一款優(yōu)秀的負載均衡器/反向代理軟件,它同時也是功能強大的 Web 應用服務器。LNMP 也是近幾年非常流行的 web 架構(gòu),在高流量的環(huán)境中穩(wěn)定性也很好。
- Nginx 現(xiàn)在作為 Web 反向加速緩存越來越成熟了,速度比傳統(tǒng)的 Squid 服務器更快,可以考慮用其作為反向代理加速器。
- Nginx 可作為中層反向代理使用,這一層面 Nginx 基本上無對手,唯一可以對比 Nginx 的就只有 lighttpd 了,不過 lighttpd 目前還沒有做到 Nginx 完全的功能,配置也不那么清晰易讀,社區(qū)資料也遠遠沒 Nginx 活躍。
- Nginx 也可作為靜態(tài)網(wǎng)頁和圖片服務器,這方面的性能也無對手。還有 Nginx 社區(qū)非常活躍,第三方模塊也很多。
Nginx 的缺點是:
- Nginx 僅能支持 http、https 和 Email 協(xié)議,這樣就在適用范圍上面小些,這個是它的缺點。
- 對后端服務器的健康檢查,只支持通過端口來檢測,不支持通過 url 來檢測。不支持 Session 的直接保持,但能通過 ip_hash 來解決。
LVS:使用 Linux 內(nèi)核集群實現(xiàn)一個高性能、高可用的負載均衡服務器,它具有很好的可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。
LVS 的優(yōu)點是:
- 抗負載能力強、是工作在網(wǎng)絡(luò) 4 層之上僅作分發(fā)之用,沒有流量的產(chǎn)生,這個特點也決定了它在負載均衡軟件里的性能最強的,對內(nèi)存和 cpu 資源消耗比較低。
- 配置性比較低,這是一個缺點也是一個優(yōu)點,因為沒有可太多配置的東西,所以并不需要太多接觸,大大減少了人為出錯的幾率。
- 工作穩(wěn)定,因為其本身抗負載能力很強,自身有完整的雙機熱備方案,如 LVS+Keepalived,不過我們在項目實施中用得最多的還是 LVS/DR+Keepalived。
- 無流量,LVS 只分發(fā)請求,而流量并不從它本身出去,這點保證了均衡器 IO 的性能不會受到大流量的影響。
- 應用范圍比較廣,因為 LVS 工作在 4 層,所以它幾乎可以對所有應用做負載均衡,包括 http、數(shù)據(jù)庫、在線聊天室等等。
LVS 的缺點是:
- 軟件本身不支持正則表達式處理,不能做動靜分離;而現(xiàn)在許多網(wǎng)站在這方面都有較強的需求,這個是 Nginx/HAProxy+Keepalived 的優(yōu)勢所在。
- 如果是網(wǎng)站應用比較龐大的話,LVS/DR+Keepalived 實施起來就比較復雜了,特別后面有 Windows Server 的機器的話,如果實施及配置還有維護過程就比較復雜了,相對而言,Nginx/HAProxy+Keepalived 就簡單多了。
HAProxy 的特點是:
- HAProxy 也是支持虛擬主機的。
- HAProxy 的優(yōu)點能夠補充 Nginx 的一些缺點,比如支持 Session 的保持,Cookie 的引導;同時支持通過獲取指定的 url 來檢測后端服務器的狀態(tài)。
- HAProxy 跟 LVS 類似,本身就只是一款負載均衡軟件;單純從效率上來講 HAProxy 會比 Nginx 有更出色的負載均衡速度,在并發(fā)處理上也是優(yōu)于 Nginx 的。
- HAProxy 支持 TCP 協(xié)議的負載均衡轉(zhuǎn)發(fā),可以對 MySQL 讀進行負載均衡,對后端的 MySQL 節(jié)點進行檢測和負載均衡,大家可以用 LVS+Keepalived 對 MySQL 主從做負載均衡。
- HAProxy 負載均衡策略非常多,HAProxy 的負載均衡算法現(xiàn)在具體有如下 8 種:
① roundrobin,表示簡單的輪詢,這個不多說,這個是負載均衡基本都具備的;
② static-rr,表示根據(jù)權(quán)重,建議關(guān)注;
③ leastconn,表示最少連接者先處理,建議關(guān)注;
④ source,表示根據(jù)請求源 IP,這個跟 Nginx 的 IP_hash 機制類似,我們用其作為解決 session 問題的一種方法,建議關(guān)注;
⑤ ri,表示根據(jù)請求的 URI;
⑥ rl_param,表示根據(jù)請求的 URl 參數(shù)’balance url_param’ requires an URL parameter name;
⑦ hdr(name),表示根據(jù) HTTP 請求頭來鎖定每一次 HTTP 請求;
⑧ rdp-cookie(name),表示根據(jù)據(jù) cookie(name)來鎖定并哈希每一次 TCP 請求。
Nginx 和 LVS 對比的總結(jié):
- Nginx 工作在網(wǎng)絡(luò)的 7 層,所以它可以針對 http 應用本身來做分流策略,比如針對域名、目錄結(jié)構(gòu)等,相比之下 LVS 并不具備這樣的功能,所以 Nginx 單憑這點可利用的場合就遠多于 LVS 了;但 Nginx 有用的這些功能使其可調(diào)整度要高于 LVS,所以經(jīng)常要去觸碰觸碰,觸碰多了,人為出問題的幾率也就會大。
- Nginx 對網(wǎng)絡(luò)穩(wěn)定性的依賴較小,理論上只要 ping 得通,網(wǎng)頁訪問正常,Nginx 就能連得通,這是 Nginx 的一大優(yōu)勢!Nginx 同時還能區(qū)分內(nèi)外網(wǎng),如果是同時擁有內(nèi)外網(wǎng)的節(jié)點,就相當于單機擁有了備份線路;LVS 就比較依賴于網(wǎng)絡(luò)環(huán)境,目前來看服務器在同一網(wǎng)段內(nèi)并且 LVS 使用 direct 方式分流,效果較能得到保證。另外注意,LVS 需要向托管商至少申請多一個 ip 來做 Visual IP,貌似是不能用本身的 IP 來做 VIP 的。要做好 LVS 管理員,確實得跟進學習很多有關(guān)網(wǎng)絡(luò)通信方面的知識,就不再是一個 HTTP 那么簡單了。
- Nginx 安裝和配置比較簡單,測試起來也很方便,因為它基本能把錯誤用日志打印出來。LVS 的安裝和配置、測試就要花比較長的時間了;LVS 對網(wǎng)絡(luò)依賴比較大,很多時候不能配置成功都是因為網(wǎng)絡(luò)問題而不是配置問題,出了問題要解決也相應的會麻煩得多。
- Nginx 也同樣能承受很高負載且穩(wěn)定,但負載度和穩(wěn)定度差 LVS 還有幾個等級:Nginx 處理所有流量所以受限于機器 IO 和配置;本身的 bug 也還是難以避免的。
- Nginx 可以檢測到服務器內(nèi)部的故障,比如根據(jù)服務器處理網(wǎng)頁返回的狀態(tài)碼、超時等等,并且會把返回錯誤的請求重新提交到另一個節(jié)點。目前 LVS 中 ldirectd 也能支持針對服務器內(nèi)部的情況來監(jiān)控,但 LVS 的原理使其不能重發(fā)請求。比如用戶正在上傳一個文件,而處理該上傳的節(jié)點剛好在上傳過程中出現(xiàn)故障,Nginx 會把上傳切到另一臺服務器重新處理,而 LVS 就直接斷掉了,如果是上傳一個很大的文件或者很重要的文件的話,用戶可能會因此而惱火。
- Nginx 對請求的異步處理可以幫助節(jié)點服務器減輕負載,假如使用 apache 直接對外服務,那么出現(xiàn)很多的窄帶鏈接時 apache 服務器將會占用大 量內(nèi)存而不能釋放,使用多一個 Nginx 做 apache 代理的話,這些窄帶鏈接會被 Nginx 擋住,apache 上就不會堆積過多的請求,這樣就減少了相當多的資源占用。這點使用 squid 也有相同的作用,即使 squid 本身配置為不緩存,對 apache 還是有很大幫助的。
- Nginx 能支持 http、https 和 email(email 的功能比較少用),LVS 所支持的應用在這點上會比 Nginx 更多。在使用上,一般最前端所采取的策略應是 LVS,也就是 DNS 的指向應為 LVS 均衡器,LVS 的優(yōu)點令它非常適合做這個任務。重要的 ip 地址,最好交由 LVS 托管,比如數(shù)據(jù)庫的 ip、webservice 服務器的 ip 等等,這些 ip 地址隨著時間推移,使用面會越來越大,如果更換 ip 則故障會接踵而至。所以將這些重要 ip 交給 LVS 托管是最為穩(wěn)妥的,這樣做的唯一缺點是需要的 VIP 數(shù)量會比較多。Nginx 可作為 LVS 節(jié)點機器使用,一是可以利用 Nginx 的功能,二是可以利用 Nginx 的性能。當然這一層面也可以直接使用 squid,squid 的功能方面就比 Nginx 弱不少了,性能上也有所遜色于 Nginx。Nginx 也可作為中層代理使用,這一層面 Nginx 基本上無對手,唯一可以撼動 Nginx 的就只有 lighttpd 了,不過 lighttpd 目前還沒有能做到 Nginx 完全的功能,配置也不那么清晰易讀。另外,中層代理的 IP 也是重要的,所以中層代理也擁有一個 VIP 和 LVS 是最完美的方案了。具體的應用還得具體分析,如果是比較小的網(wǎng)站(日 PV 小于 1000 萬),用 Nginx 就完全可以了,如果機器也不少,可以用 DNS 輪詢,LVS 所耗費的機器還是比較多的;大型網(wǎng)站或者重要的服務,機器不發(fā)愁的時候,要多多考慮利用 LVS。
44.做秒殺時鎖表考慮到?jīng)]有?
答:考慮到了,當時我們做秒殺時考慮了好幾種方案,其中有一種就是使用事務加上排他鎖來實現(xiàn)。
架構(gòu)類的東西接觸過嗎?
有接觸過,曾經(jīng)自己在自己的服務器上配置過。我以前做過以下幾個架構(gòu)方面的配置和測試;
- 數(shù)據(jù)庫的讀寫分離、主從復制及集群。
- Nginx 負載均衡
- redis 集群及主從
45.封裝過一個簡單的框架
答;封裝過一個簡單的 MVC 框架,主要分為 3 層,控制器層和模型層視圖層,以及路由的分配和入口文件,模板引擎,單例模式、工廠模式,第三方類庫的引入等。
46.談談對 MVC 的認識
答:核心思想是:視圖和用戶交互通過事件導致控制器改變 控制器改變導致模型改變 或者控制器同時改變兩者 模型改變 導致視圖改變 或者視圖改變 潛在的從模型里面獲得參數(shù) 來改變自己。他的好處是可以將界面和業(yè)務邏輯分離。
Model(模型),是程序的主體部分,主要包含業(yè)務數(shù)據(jù)和業(yè)務邏輯。在模型層,還會涉及到用戶發(fā)布的服務,在服務中會根據(jù)不同的業(yè)務需求,更新業(yè)務模型中的數(shù)據(jù)。
View(視圖),是程序呈現(xiàn)給用戶的部分,是用戶和程序交互的接口,用戶會根據(jù)具體的業(yè)務需求,在 View 視圖層輸入自己特定的業(yè)務數(shù)據(jù),并通過界面的事件交互,將對應的輸入?yún)?shù)提交給后臺控制器進行處理。
Contorller(控制器),Contorller 是用來處理用戶 輸入數(shù)據(jù),已經(jīng)更新業(yè)務模型的部分。控制器中接收了用戶與界面交互時傳遞過來的數(shù)據(jù),并根據(jù)數(shù)據(jù)業(yè)務邏輯來執(zhí)行服務的調(diào)用和更新業(yè)務模型的數(shù)據(jù)和狀態(tài)。
47.session 與 cookie 的區(qū)別
答:
1、cookie 數(shù)據(jù)存放在第三方應用的瀏覽器上,session 數(shù)據(jù)放在服務器上。
2、cookie 不是很安全,別人可以分析存放在本地的 COOKIE,進行 COOKIE 欺騙
考慮到安全應當使用 session。
3、session 會在一定時間內(nèi)保存在服務器上。當訪問增多,會比較占用你服務器的性能
考慮到減輕服務器性能方面,應當使用 COOKIE。
4、單個 cookie 保存的數(shù)據(jù)不能超過 4K,很多瀏覽器都限制一個站點最多保存 20 個 cookie。
5、所以個人建議:
將登陸信息等重要信息存放為 SESSION
其他信息如果需要保留,可以放在 COOKIE
48.echo(),print(),print_r()的區(qū)別
答:echo 可以一次輸出多個值,多個值之間用逗號分隔。echo 是語言結(jié)構(gòu)(language construct),而并不是真正的函數(shù),因此不能作為表達式的一部分使用。echo 是 php 的內(nèi)部指令,不是函數(shù),無返回值。
print():函數(shù) print()打印一個值(它的參數(shù)),如果字符串成功顯示則返回 true,否則返回 false。只能打印出簡單類型變量的值(如 int,string),有返回值
printf():源于 C 語言中的 printf()。該函數(shù)輸出格式化的字符串。
print_r()和 var_dump()
print_r()可以把字符串和數(shù)字簡單地打印出來,而數(shù)組則以括起來的鍵和值得列表形式顯示,并以 Array 開頭。但 print_r()輸出布爾值和 NULL 的結(jié)果沒有意義,因為都是打印"\n"。因此用 var_dump()函數(shù)更適合調(diào)試。print_r 是函數(shù),可以打印出比較復雜的變量(如數(shù)組,對象),有返回值
var_dump()判斷一個變量的類型與長度,并輸出變量的數(shù)值,如果變量有值輸?shù)氖亲兞康闹挡⒒胤禂?shù)據(jù)類型。此函數(shù)顯示關(guān)于一個或多個表達式的結(jié)構(gòu)信息,包括表達式的類型與值。數(shù)組將遞歸展開值,通過縮進顯示其結(jié)構(gòu)。
49.說一下單引號雙引號?
答:①單引號內(nèi)部的變量不會執(zhí)行, 雙引號會執(zhí)行
②單引號解析速度比雙引號快。
③單引號只能解析部分特殊字符,雙引號可以解析所有特殊字符。
50.索引的優(yōu)缺點
答:1、優(yōu)點:
a)可以保證數(shù)據(jù)庫表中每一行的數(shù)據(jù)的唯一性
b)可以大大加快數(shù)據(jù)的索引速度
c)加速表與表之間的連接,物別是在實現(xiàn)數(shù)據(jù)的參考完事性方面特別有意義
d)在使用分組和排序子句進行數(shù)據(jù)檢索時,同樣可以顯著減少查詢中分組和排序的時間
f)通過使用索引,可以在時間查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能
2、 缺點:
a) 創(chuàng)建索引和維護索引要耗費時間,這種時間隨著數(shù)據(jù)量的增加而增加
b) 索引需要占物理空間,除了數(shù)據(jù)表占用數(shù)據(jù)空間之外,每一個索引還要占用一定的物理空間,如果需要建立聚簇索引,那么需要占用的空間會更大
c) 以表中的數(shù)據(jù)進行增、刪、改的時候,索引也要動態(tài)的維護,這就降低了整數(shù)的維護速度
d) 建立索引的原則
e) 在經(jīng)常需要搜索的列上,可以加快搜索的速度
f) 在作為主鍵的列上,強制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu)
g) 在經(jīng)常用在連接的列上,這些列主要是一外鍵,可以加快連接的速度
h) 在經(jīng)經(jīng)常需要根據(jù)范圍進行搜索的列上創(chuàng)建索引,國為索引已經(jīng)排序,其指定的范圍是連續(xù)的
i) 在經(jīng)常需要排序的列上,國為索引已經(jīng)排序,這樣井底可以利用索引的排序,加快排序井底時間
j) 在經(jīng)常使用在 where 子句中的列上,加快條件的判斷速度
51.get 和 post 的區(qū)別
答:
- get 是從服務器上獲取數(shù)據(jù),post 是向服務器傳送數(shù)據(jù)。
- get 是把參數(shù)數(shù)據(jù)隊列加到提交表單的 ACTION 屬性所指的 URL 中,值和表單內(nèi)各個字段一一對應,在 URL 中可以看到。post 是通過 HTTP post 機制,將表單內(nèi)各個字段與其內(nèi)容放置在 HTML HEADER 內(nèi)一起傳送到 ACTION 屬性所指的 URL 地址。用戶看不到這個過程。
- get 傳送的數(shù)據(jù)量較小,不能大于 2KB。post 傳送的數(shù)據(jù)量較大,一般被默認為不受限制。
- get 安全性非常低,post 安全性較高。但是執(zhí)行效率卻比 Post 方法好。
52.如何修改 session 的生存時間
答:一:在 php.ini 中設(shè)置 session.gc_maxlifetime = 1440 //默認時間
二:代碼實現(xiàn)
$lifeTime = 24 * 3600; // 保存一天
session_set_cookie_params($lifeTime);
session_start();
53.Linux 基本命令,目錄結(jié)構(gòu)
答:arch 顯示機器的處理器架構(gòu)(1)
uname -m 顯示機器的處理器架構(gòu)(2)
uname -r 顯示正在使用的內(nèi)核版本
dmidecode -q 顯示硬件系統(tǒng)部件 - (SMBIOS / DMI)
hdparm -i /dev/hda 羅列一個磁盤的架構(gòu)特性
hdparm -tT /dev/sda 在磁盤上執(zhí)行測試性讀取操作
cat /porc/cpuinfo 顯示 CPU info 的信息
cat /porc/interrupts 顯示中斷
cat /porc/meminfo 校驗內(nèi)存使用
cat /porc/swaps 顯示哪些 swap 被使用
cat /porc/verion 顯示內(nèi)核的版本
cat /porc/net/dev 顯示網(wǎng)絡(luò)適配器及統(tǒng)計
cat /porc/mounts 顯示已加載的文件系統(tǒng)
date 顯示系統(tǒng)日期
cal 2007 顯示 2007 年的日歷表
date 041217002007.00 設(shè)置日期和時間 -月日時分年.秒
clock -w 將時間修改保存到 BIOS
文件搜索
find / -name file1 從 '/'開始進入根文件系統(tǒng)搜索文件和目錄
locate *.ps 尋找以 '.ps'結(jié)尾的文件 -先運行'updatedb'命令
whereis halt 顯示一個二進制文件、源碼或 man 的位置
which halt 顯示一個二進制文件或可執(zhí)行文件的完整路徑
掛載一個文件系統(tǒng)
mount /dev/hda2 /mnt/hda2 掛載一個叫做 hda2 的盤- 確定目錄'/ mnt/hda2' 已經(jīng)存在
umount /dev/hda2 卸載一個叫做 hda2 的盤- 先從掛載點'/ mnt/hda2' 退出
追加命令
- linux 里把文件/etc/aaa 中的內(nèi)容追加到/usr/bbb 中的內(nèi)容的后面
sudo cat /etc/aaa >>/usr/bbb - 更改/etc/index.html 的文件所有者為 apache,文件群組為 apache
sudo chmod apache:apache /etc/index.html - 更改/etc/index.html 的所有者權(quán)限為讀取、寫入、執(zhí)行。群組權(quán)限為讀取。其他權(quán)限為讀取
sudo chmod 744 /etc/index.html - 刪除/etc 下名為 hello 的文件
sudo rm /etc/index.html
當然,如果你是以 orot 用戶執(zhí)行以上操作,可以去掉前邊的 sudo!
df -hl 查看磁盤剩余空間
df -h 查看每個根路徑的分區(qū)大小
du -sh [目錄名] 返回該目錄的大小
du -sm [文件夾] 返回該文件夾總 M 數(shù)
關(guān)機 (系統(tǒng)的關(guān)機、重啟以及登出)
shutdown -h now 關(guān)閉系統(tǒng)(1)
init 0 關(guān)閉系統(tǒng)(2)
telinit 0 關(guān)閉系統(tǒng)(3)
shutdown -h hour:minutes & 按預定時間關(guān)閉系統(tǒng)
shutdown -c 取消按預定時間關(guān)閉系統(tǒng)
shutdown -r now 重啟(1)
reboot 重啟(2)
logout 注銷
文件和目錄
pwd 顯示工作路徑
ls 查看目錄中的文件
ls -F 查看目錄中的文件
ls -l 顯示文件和目錄的詳細資料
ls -a 顯示隱藏文件
ls[0-9]顯示包含數(shù)字的文件名和目錄名
tree 顯示文件和目錄由根目錄開始的樹形結(jié)構(gòu)(1)
lstree 顯示文件和目錄由根目錄開始的樹形結(jié)構(gòu)(2)
mkdir dir1 創(chuàng)建一個叫做 'dir1'的目錄'
磁盤空間
df -h 顯示已經(jīng)掛載的分區(qū)列表
ls -lSr |more 以尺寸大小排列文件和目錄
du -sh dir1 估算目錄 'dir1'已經(jīng)使用的磁盤空間'
下載、解壓
1)對于.tar 結(jié)尾的文件
tar -xf all.tar
2)對于.gz 結(jié)尾的文件
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"
fils -al /opt |grep "^-"|wc -l 這個命令能夠統(tǒng)計文件個數(shù) 為 0 就是沒有文件 非零就是有文件
54..memcache 緩存什么數(shù)據(jù)
答:一、經(jīng)常被讀取并且實時性要求不強可以等到自動過期的數(shù)據(jù)。例如網(wǎng)站首頁最新文章列表、某某排行等數(shù)據(jù)。
二、經(jīng)常被讀取并且實時性要求強的數(shù)據(jù)。比如用戶的好友列表,用戶文章列表,用戶閱讀記錄等。
三、統(tǒng)計類緩存,比如文章瀏覽數(shù)、網(wǎng)站 PV 等。
四、活躍用戶的基本信息或者某篇熱門文章。
五、session 數(shù)據(jù)
55.魔術(shù)方法、魔術(shù)常量
答:1、__construct()
實例化對象時被調(diào)用,當 __construct 和以類名為函數(shù)名的函數(shù)同時存在時,__construct 將被調(diào)用,另一個不被調(diào)用。
2、__destruct()
當刪除一個對象或?qū)ο蟛僮鹘K止時被調(diào)用。
3、__call()
對象調(diào)用某個方法,若方法存在,則直接調(diào)用;若不存在,則會去調(diào)用 __call 函數(shù)。
4、__get()
讀取一個對象的屬性時,若屬性存在,則直接返回屬性值;若不存在,則會調(diào)用 __get 函數(shù)。
5、__set()
設(shè)置一個對象的屬性時,若屬性存在,則直接賦值;若不存在,則會調(diào)用 __set 函數(shù)。
6、__clone()
克隆對象時被調(diào)用。如:t=newTest();t1=clone $t;bj;
7、__clone()
克隆對象時被調(diào)用。如:t=newTest();t1=clone $t;
8、__sleep()
serialize 之前被調(diào)用。若對象比較大,想刪減一點東東再序列化,可考慮一下此函數(shù)。
9、__wakeup()
unserialize 時被調(diào)用,做些對象的初始化工作。
10、__isset()
檢測一個對象的屬性是否存在時被調(diào)用。如:isset($c->name)。
11、__unset()
unset 一個對象的屬性時被調(diào)用。如:unset($c->name)。
12、__set_state()
調(diào)用 var_export 時,被調(diào)用。用 __set_state 的返回值做為 var_export 的返回值。
13、__autoload()
實例化一個對象時,如果對應的類不存在,則該方法被調(diào)用。
魔術(shù)常量:
1、__LINE__
返回文件中的當前行號。
2、__FILE__
返回文件的完整路徑和文件名。如果用在包含文件中,則返回包含文件名。自 PHP 4.0.2 起,FILE總是包含一個絕對路徑,而在此之前的版本有時會包含一個相對路徑。
3、__FUNCTION__
返回函數(shù)名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該函數(shù)被定義時的名字(區(qū)分大小寫)。在 PHP 4 中該值總是小寫字母的。
4、__CLasS__
返回類的名稱(PHP 4.3.0 新加)。自 PHP 5 起本常量返回該類被定義時的名字(區(qū)分大小寫)。在 PHP 4 中該值總是小寫字母的。
5、__METHOD__
返回類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區(qū)分大小寫)。
6、__set()當程序試圖寫入一個不存在或者不可見的成員變量時,__set()方法包含兩個參數(shù),分別表示變量名稱和變量值,兩個參數(shù)都不可省略
7、_get()當程序試圖調(diào)用一個未定義或不可見的成員變量時,__get()方法有一個參數(shù),表示要調(diào)用的變量名
__sleep() 常用于提交未提交的數(shù)據(jù),或類似的清理操作如果有一些很大的對象,但不需要全部保存,這個功能就很好用。
__construct() 在類實例化對象的同時執(zhí)行該函數(shù)
__distruct() 在類實例化的對象銷毀時執(zhí)行
__call()對象調(diào)用某個方法,若方法存在,則直接調(diào)用;若不存在,則會去調(diào)用 __call 函數(shù)。
__clone()克隆對象時被調(diào)用。如:t1=clone $t;
__toString()打印一個對象的時被調(diào)用。如 echo obj;
__isset()檢測一個對象的屬性是否存在時被調(diào)用。如:isset($c->name)。
__unset()unset 一個對象的屬性時被調(diào)用。如:unset($c->name)。
__autoload()實例化一個對象時,如果對應的類不存在,則該方法被調(diào)用。
56.接口和抽象類的區(qū)別是什么?
答:抽象類是一種不能被實例化的類,只能作為其他類的父類來使用。抽象類是通過關(guān)鍵字 abstract 來聲明的。
抽象類與普通類相似,都包含成員變量和成員方法,兩者的區(qū)別在于,抽象類中至少要包含一個抽象方法,抽象方法沒有方法體,該方法天生就是要被子類重寫的。
抽象方法的格式為:abstract function abstractMethod();
接口是通過 interface 關(guān)鍵字來聲明的,接口中的成員常量和方法都是 public 的,方法可以不寫關(guān)鍵字 public,接口中的方法也是沒有方法體。接口中的方法也天生就是要被子類實現(xiàn)的。
抽象類和接口實現(xiàn)的功能十分相似,最大的不同是接口能實現(xiàn)多繼承。在應用中選擇抽象類還是接口要看具體實現(xiàn)。
子類繼承抽象類使用 extends,子類實現(xiàn)接口使用 implements。
57.什么是隊列?排它鎖,Myisam 死鎖如何解決?
答:在默認情況下 MYisam 是表級鎖,所以同時操作單張表的多個動作只能以隊列的方式進行;
排它鎖又名寫鎖,在 SQL 執(zhí)行過程中為排除其它請求而寫鎖,在執(zhí)行完畢后會自動釋放;
死鎖解決:先找到死鎖的線程號,然后殺掉線程 ID
58.bootstrap 框架有哪些優(yōu)點?
答:bootstrap 是一款 web 開發(fā)框架,它由 CSS,JavaScript,Html,三部分構(gòu)成,它簡潔靈活,使得 web 開發(fā)更加的快捷
優(yōu)點:
①節(jié)省時間: 使用 bootstrap 框架,可以大大的節(jié)省項目開發(fā)時間,它包含了很多現(xiàn)成的代碼,如果需要使用,只需要找到合適的代碼,插入合適的位置即可,此外,CSS 是使用 LESS 編寫,很多樣式和設(shè)計都已經(jīng)設(shè)計完成了
②定制化: bootstrap 可以根據(jù)自己的項目,留取框架中自己需要的部分
③設(shè)計合理:
- 柵格系統(tǒng): bootstrap 定義 12 格柵系統(tǒng),在頁面已經(jīng)完成時,你可以根據(jù)合適的網(wǎng)格,以自己的需求改變行數(shù)和布局大小,樣式已經(jīng)開發(fā)完成了,只需要把代碼放入合適的 HTML 代碼位置即可
- LESS: LESS 是基于 CSS 之上的高級語言,其目的是使得 CSS 開發(fā)更加靈活,更加強大
- JavaScript:bootstrap 提供 JavaScript 庫,該庫超越了基本的架構(gòu)和樣式,開發(fā)者可以輕松的操作窗口警告框,工具提示框等,可避免了我們費神費力的寫腳本
- 一致性: bootstrap 可以保證界面在不同平臺的統(tǒng)一性,無論實在 IE,Chrome 等
- 持續(xù)更新: bootstrap 在不斷的改進,更具規(guī)律性和持續(xù)性
- 響應式: 無論是在 PC 端還是移動端,都可以保持界面的一致性
- 文檔多: bootstrap 的非常多
點關(guān)注,不迷路
好了各位,以上就是這篇文章的全部內(nèi)容了,能看到這里的人呀,都是人才。之前說過,PHP方面的技術(shù)點很多,也是因為太多了,實在是寫不過來,寫過來了大家也不會看的太多,所以我這里把它整理成了PDF和文檔,如果有需要的可以
更多學習內(nèi)容可以訪問【對標大廠】精品PHP架構(gòu)師教程目錄大全,只要你能看完保證薪資上升一個臺階(持續(xù)更新)
以上內(nèi)容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業(yè)務代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限于:分布式架構(gòu)、高可擴展、高性能、高并發(fā)、服務器性能調(diào)優(yōu)、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優(yōu)化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要的可以加入我的PHP技術(shù)交流群953224940