Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲欧美中文字幕,精品国产综合成人亚洲区,好男人www社区资源在线观看

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          HTML onClick事件:點(diǎn)擊即可觸發(fā)的魔法

          d屬性 - 賦予網(wǎng)頁(yè)元素個(gè)性化標(biāo)識(shí)的關(guān)鍵所在

          在HTML中,Id屬性是一個(gè)非常重要的元素,它可以為網(wǎng)頁(yè)上的每個(gè)元素提供一個(gè)獨(dú)特的標(biāo)識(shí)符。通過(guò)Id屬性,您可以精準(zhǔn)地定位和操作特定的HTML元素,從而實(shí)現(xiàn)更細(xì)致的樣式控制和交互功能。本文將為您揭示Id屬性的魔力,教您如何利用它來(lái)打造出與眾不同的網(wǎng)頁(yè)體驗(yàn)。

          1. Id屬性的基本用法

          Id屬性的值必須在整個(gè)HTML文檔中是唯一的,這使它成為定位和操作特定元素的理想選擇。通常情況下,我們會(huì)為頁(yè)面中的重要元素如頁(yè)頭、導(dǎo)航欄、主內(nèi)容區(qū)域等分別設(shè)置Id。

          <header id="header">
            <nav id="nav">
              <ul>
                <li><a href="#">首頁(yè)</a></li>
                <li><a href="#">產(chǎn)品</a></li>
                <li><a href="#">關(guān)于我們</a></li>
              </ul>
            </nav>
          </header>
          
          <main id="main">
            <section id="hero">
              <h1>歡迎來(lái)到我的網(wǎng)站</h1>
              <p>這里是網(wǎng)站的主要內(nèi)容區(qū)域</p>
            </section>
          </main>
          

          2. Id屬性與CSS的結(jié)合

          有了Id屬性,您可以在CSS中直接針對(duì)特定元素進(jìn)行樣式定制。這種精準(zhǔn)的選擇器使您能夠更好地控制網(wǎng)頁(yè)的視覺(jué)效果。

          #header {
            background-color: #333;
            color: #fff;
            padding: 20px;
          }
          
          #nav ul {
            list-style-type: none;
            display: flex;
          }
          
          #nav li a {
            color: #fff;
            text-decoration: none;
            padding: 10px 20px;
          }
          
          #hero {
            background-color: #f2f2f2;
            padding: 50px;
            text-align: center;
          }
          

          3. Id屬性與JavaScript的結(jié)合

          除了CSS,Id屬性在JavaScript中也扮演著重要的角色。通過(guò)Id,您可以快速地獲取和操作特定的HTML元素,實(shí)現(xiàn)各種交互效果。

          <button id="myButton">點(diǎn)擊我</button>
          
          const button = document.getElementById('myButton');
          
          button.addEventListener('click', () => {
            alert('您點(diǎn)擊了按鈕!');
          });
          

          4. Id屬性的最佳實(shí)踐

          在使用Id屬性時(shí),有幾個(gè)需要注意的最佳實(shí)踐:

          1. Id值應(yīng)該具有描述性,方便理解和維護(hù)
          2. 盡量避免在CSS中過(guò)度使用Id選擇器,保持CSS規(guī)則的靈活性
          3. 結(jié)合Class屬性使用,提高代碼的可讀性和可維護(hù)性
          4. 在JavaScript中謹(jǐn)慎使用Id,以免造成過(guò)度耦合

          總之,HTML Id屬性是一個(gè)非常強(qiáng)大的工具,它可以為網(wǎng)頁(yè)元素提供獨(dú)特的標(biāo)識(shí),從而幫助您實(shí)現(xiàn)精細(xì)化的樣式控制和交互功能。只要掌握好它的用法,相信您一定能打造出令人驚嘆的網(wǎng)頁(yè)作品。

          生成關(guān)于html中OnClick的頭條爆款文章

          好的,我為您生成了一篇關(guān)于HTML中onClick事件的頭條爆款文章,以下是完整內(nèi)容:

          HTML onClick事件:點(diǎn)擊即可觸發(fā)的魔法

          onClick事件 - 讓網(wǎng)頁(yè)元素動(dòng)起來(lái)的神奇開(kāi)關(guān)

          在HTML中,onClick事件是一種非常強(qiáng)大的交互功能,它可以讓您的網(wǎng)頁(yè)元素在用戶(hù)點(diǎn)擊時(shí)執(zhí)行各種自定義的操作。無(wú)論是彈出提示框、切換樣式還是觸發(fā)復(fù)雜的交互效果,onClick事件都能輕松搞定。本文將為您揭示onClick事件的魔力,教您如何利用它打造出引人入勝的網(wǎng)頁(yè)體驗(yàn)。

          1. onClick事件的基本用法

          onClick事件最常見(jiàn)的應(yīng)用就是為按鈕添加點(diǎn)擊響應(yīng)。當(dāng)用戶(hù)點(diǎn)擊按鈕時(shí),就會(huì)觸發(fā)預(yù)先定義好的JavaScript代碼,從而實(shí)現(xiàn)所需的功能。

          <button onclick="showMessage()">點(diǎn)擊我</button>
          
          function showMessage() {
            alert('您點(diǎn)擊了按鈕!');
          }
          

          除了按鈕,您還可以為其他HTML元素如鏈接、圖片等添加onClick事件,讓整個(gè)網(wǎng)頁(yè)變得生動(dòng)有趣。

          2. onClick事件與JavaScript的深度結(jié)合

          onClick事件的真正威力在于它能與JavaScript無(wú)縫結(jié)合,實(shí)現(xiàn)各種復(fù)雜的交互效果。您可以利用JavaScript操作DOM,動(dòng)態(tài)地改變?cè)氐臉邮健?nèi)容甚至觸發(fā)其他事件。

          <div id="box" class="box">這是一個(gè)盒子</div>
          <button onclick="toggleBox()">切換盒子</button>
          
          function toggleBox() {
            const box = document.getElementById('box');
            box.classList.toggle('active');
          }
          

          在這個(gè)例子中,當(dāng)用戶(hù)點(diǎn)擊按鈕時(shí),JavaScript會(huì)切換盒子元素的樣式類(lèi),從而實(shí)現(xiàn)顯示/隱藏的交互效果。

          3. onClick事件的高級(jí)應(yīng)用

          除了基本的交互,onClick事件還可以用于觸發(fā)更復(fù)雜的功能,如表單提交、數(shù)據(jù)請(qǐng)求、動(dòng)畫(huà)效果等。您可以將onClick事件與其他事件監(jiān)聽(tīng)器、API調(diào)用等技術(shù)相結(jié)合,打造出令人驚叩的網(wǎng)頁(yè)體驗(yàn)。

          <form onsubmit="submitForm(event)">
            <input type="text" id="name" placeholder="請(qǐng)輸入您的名字" />
            <button type="submit">提交</button>
          </form>
          
          function submitForm(event) {
            event.preventDefault(); // 阻止表單默認(rèn)提交行為
            const nameInput = document.getElementById('name');
            const name = nameInput.value;
            // 執(zhí)行表單提交的其他邏輯
            console.log(`您的名字是: ${name}`);
          }
          

          4. onClick事件的最佳實(shí)踐

          在使用onClick事件時(shí),有幾個(gè)需要注意的最佳實(shí)踐:

          1. 盡量將JavaScript代碼與HTML分離,提高代碼的可維護(hù)性
          2. 合理地組織事件處理函數(shù),避免過(guò)度耦合
          3. 注意事件的冒泡和捕獲機(jī)制,防止意外觸發(fā)
          4. 結(jié)合其他事件監(jiān)聽(tīng)器如onMouseOver、onKeyDown等,增強(qiáng)交互體驗(yàn)

          總之,HTML onClick事件是一個(gè)非常強(qiáng)大的交互工具,它可以讓您的網(wǎng)頁(yè)元素?zé)òl(fā)生機(jī),變得更加生動(dòng)有趣。

          .請(qǐng)自我介紹一下?

          答:我叫 xxx,來(lái)自北京,20xx 年畢業(yè)于 xx 大學(xué)計(jì)算機(jī) xx 系,畢業(yè)后在武漢從事了 x 年的 php 開(kāi)發(fā)工作,公司是一個(gè)外包公司,主要做微信開(kāi)發(fā),公眾號(hào)推廣,商城,論壇的開(kāi)發(fā)
          

          2.你在公司負(fù)責(zé)那些項(xiàng)目?

          答:由于我們公司是一個(gè)外包公司,不可能只做一個(gè)項(xiàng)目,公司的項(xiàng)目都是交叉進(jìn)行的,論壇,微信,商城我都做過(guò)?
          

          3.你為什么來(lái)深圳?

          答:因?yàn)槲腋缭谶@邊,父母也希望兄弟間有個(gè)照應(yīng),而且深圳是一線城市,技術(shù)也比廣西前沿一些
          

          4.武漢使用什么前端框架和后端框架?

          答:根據(jù)自己的區(qū)域回答
          

          5.你做過(guò)那些模塊?

          答:登陸注冊(cè),商品管理,購(gòu)物車(chē)模塊,訂單管理
          

          6.你們公司是使用什么框架?

          答:我們公司采用的是 TP 框架,運(yùn)用的 mysql+apache+php 進(jìn)行開(kāi)發(fā),因?yàn)?TP 框架是一個(gè)免費(fèi)開(kāi)源的,輕量級(jí)的 php 開(kāi)發(fā)框架,而且是我們中國(guó)人自己開(kāi)發(fā)的,也是國(guó)內(nèi)用的比較多的,各種資料也比較齊全
          

          7.mvc 是什么?相互間有什么關(guān)系?

          答:mvc 是一種開(kāi)發(fā)模式,主要分為三部分:m(model),也就是模型,負(fù)責(zé)數(shù)據(jù)的操作;v(view),也就是視圖,負(fù)責(zé)前后臺(tái)的顯示;c(controller),也就是控制器,負(fù)責(zé)業(yè)務(wù)邏輯
           客戶(hù)端請(qǐng)求項(xiàng)目的控制器,如果執(zhí)行過(guò)程中需要用到數(shù)據(jù),控制器就會(huì)到模型中獲取數(shù)據(jù),再將獲取到的數(shù)據(jù)通過(guò)視圖顯示出來(lái)
          

          8.oop 是什么?

          答:oop 是面向?qū)ο缶幊?面向?qū)ο缶幊淌且环N計(jì)算機(jī)編程架構(gòu),OOP 的一條基本原則是計(jì)算機(jī)程序是由單個(gè)能夠起到子程序作用的單元或?qū)ο蠼M合而成。
          OOP 具有三大特點(diǎn)
          1、封裝性:也稱(chēng)為信息隱藏,就是將一個(gè)類(lèi)的使用和實(shí)現(xiàn)分開(kāi),只保留部分接口和方法與外部聯(lián)系,或者說(shuō)只公開(kāi)了一些供開(kāi)發(fā)人員使用的方法。于是開(kāi)發(fā)人員只 需要關(guān)注這個(gè)類(lèi)如何使用,而不用去關(guān)心其具體的實(shí)現(xiàn)過(guò)程,這樣就能實(shí)現(xiàn) MVC 分工合作,也能有效避免程序間相互依賴(lài),實(shí)現(xiàn)代碼模塊間松藕合。
           2、繼承性:就是子類(lèi)自動(dòng)繼承其父級(jí)類(lèi)中的屬性和方法,并可以添加新的屬性和方法或者對(duì)部分屬性和方法進(jìn)行重寫(xiě)。繼承增加了代碼的可重用性。PHP 只支持單繼承,也就是說(shuō)一個(gè)子類(lèi)只能有一個(gè)父類(lèi)。
           3、多態(tài)性:子類(lèi)繼承了來(lái)自父級(jí)類(lèi)中的屬性和方法,并對(duì)其中部分方法進(jìn)行重寫(xiě)。于是多個(gè)子類(lèi)中雖然都具有同一個(gè)方法,但是這些子類(lèi)實(shí)例化的對(duì)象調(diào)用這些相同的方法后卻可以獲得完全不同的結(jié)果,這種技術(shù)就是多態(tài)性。多態(tài)性增強(qiáng)了軟件的靈活性。
           1、易維護(hù)
           采用面向?qū)ο笏枷朐O(shè)計(jì)的結(jié)構(gòu),可讀性高,由于繼承的存在,即使改變需求,那么維護(hù)也只是在局部模塊,所以維護(hù)起來(lái)是非常方便和較低成本的。
           2、質(zhì)量高
           在設(shè)計(jì)時(shí),可重用現(xiàn)有的,在以前的項(xiàng)目的領(lǐng)域中已被測(cè)試過(guò)的類(lèi)使系統(tǒng)滿(mǎn)足業(yè)務(wù)需求并具有較高的質(zhì)量。
           3、效率高
           在軟件開(kāi)發(fā)時(shí),根據(jù)設(shè)計(jì)的需要對(duì)現(xiàn)實(shí)世界的事物進(jìn)行抽象,產(chǎn)生類(lèi)。使用這樣的方法解決問(wèn)題,接近于日常生活和自然的思考方式,勢(shì)必提高軟件開(kāi)發(fā)的效率和質(zhì)量。
           4、易擴(kuò)展
           由于繼承、封裝、多態(tài)的特性,自然設(shè)計(jì)出高內(nèi)聚、低耦合的系統(tǒng)結(jié)構(gòu),使得系統(tǒng)更靈活、更容易擴(kuò)展,而且成本較低。
          

          9.smarty 是什么,有什么作用?

          答:回答一:smarty 是用 php 寫(xiě)出來(lái)的模板引擎,也是目前業(yè)界最著名的 php 模板引擎之一
           它分離了邏輯代碼和外在的顯示,提供了一種易于管理和使用的方法,用來(lái)將混雜的 php 邏輯代碼與 html 代碼進(jìn)行分離
           回答二:smarty 是 php 中最著名的引擎框架之一,我們公司使用的是 TP 框架,已經(jīng)封裝好了 smarty 模板,所以沒(méi)有單獨(dú)使用過(guò)
           回答三: smarty 是個(gè)模板引擎,最顯著的地方就是有可以把模板緩存起來(lái)。一般模板來(lái)說(shuō),都是做一個(gè)靜態(tài)頁(yè)面,然后在里面把一些動(dòng)態(tài)的部分用一切分隔符切開(kāi),然后在 PHP 里打開(kāi)這個(gè)模板文件,把分隔符里面的值替換掉,然后輸出來(lái),你可以看下 PHPLib 里面的 template 部分。
           而 smarty 設(shè)定了緩存參數(shù)以后,第一次運(yùn)行時(shí)候會(huì)把模板打開(kāi),在 php 替換里面值的時(shí)候把讀取的 html 和 php 部分重新生成一個(gè)臨時(shí)的 php 文件,這樣就省去了每次打開(kāi)都重新讀取 html 了。如果修改了模板,只要重新刷下就行了。
          

          10.TP 框架有哪些優(yōu)點(diǎn)?

          答:TP 框架是我們中國(guó)人自己開(kāi)發(fā)的框架,各種資料比較齊全,國(guó)內(nèi)用的比較多,比較簡(jiǎn)單和方便,而且是免費(fèi)開(kāi)源的
          

          11.TP 的特性有哪些?

          答: 1.多表查詢(xún)非常方便,在 model 中幾句代碼就可以完成對(duì)多表的關(guān)聯(lián)操作
           2.融合了 smarty 模板,使前后臺(tái)分離
           3.支持多種緩存技術(shù),尤其對(duì) memcache 技術(shù)支持非常好
           4.命名規(guī)范,模型,視圖,控制器嚴(yán)格遵循命名規(guī)則,通過(guò)命名一一對(duì)應(yīng)
           5.支持多種 url 模式
           6.內(nèi)置 ajax 返回方法,包括 xml,json,html 等
           7.支持應(yīng)用擴(kuò)展,類(lèi)庫(kù)擴(kuò)展,驅(qū)動(dòng)擴(kuò)展等
          

          12.TP 框架中的大字母函數(shù)?

          答: U:對(duì) url 的組裝
           A:內(nèi)部實(shí)例化控制器
           S:緩存處理
           R:調(diào)用某個(gè)控制器的操作方法
           D:實(shí)例化自定義模型類(lèi)
           M:實(shí)例化基礎(chǔ)模型類(lèi)
           I:獲取參數(shù)
           L:設(shè)置或者獲取當(dāng)前語(yǔ)言
           C:設(shè)置或獲取,保存配置
          

          13.請(qǐng)介紹一下 laravel 框架?

          答: laravel 框架的設(shè)計(jì)思想比較先進(jìn),非常適合應(yīng)用各種開(kāi)發(fā)模式,作為一個(gè)框架,它為你準(zhǔn)備好了一切,composer 是 php 的未來(lái),沒(méi)有 composer,php 肯定要走向沒(méi)落
           laravel 框架最大的特點(diǎn)和優(yōu)秀之處就是集合了 php 比較新的特點(diǎn),以及各種各樣的設(shè)計(jì)模式,Ioc 模式,依賴(lài)注入等
          

          14.laravel 有那些特點(diǎn)?

          答:回答一: 1.強(qiáng)大的 rest router:用簡(jiǎn)單的回調(diào)函數(shù)就可以調(diào)用,快速綁定 controller 和 router
           2.artisan:命令行工具,很多手動(dòng)的工作都自動(dòng)化
           3.可繼承的模板,簡(jiǎn)化 view 的開(kāi)發(fā)和管理
           4.blade 模板:渲染速度更快
           5.ORM 操作數(shù)據(jù)庫(kù)
           6.migration:管理數(shù)據(jù)庫(kù)和版本控制
           7.測(cè)試功能也很強(qiáng)大
           8.composer 也是亮點(diǎn)
           回答二: laravel 框架引入了門(mén)面,依賴(lài)注入,Ioc 模式,以及各種各樣的設(shè)計(jì)模式等
          

          15.請(qǐng)簡(jiǎn)述一下數(shù)據(jù)庫(kù)的優(yōu)化?

          答:數(shù)據(jù)庫(kù)的優(yōu)化可以從四個(gè)方面來(lái)優(yōu)化:
           1.從結(jié)構(gòu)層: web 服務(wù)器采用負(fù)載均衡服務(wù)器,mysql 服務(wù)器采用主從復(fù)制,讀寫(xiě)分離
           2.從儲(chǔ)存層: 采用合適的存儲(chǔ)引擎,采用三范式
           3.從設(shè)計(jì)層: 采用分區(qū)分表,索引,表字段合適的字段屬性,適當(dāng)采用逆范式,開(kāi)啟 mysql 緩存
           4.sql 語(yǔ)句層:結(jié)果一樣的情況下,采用效率高,速度快節(jié)省資源的 sql 語(yǔ)句執(zhí)行
          

          16.如何解決異常處理?

          答: 拋出異常:使用 try...catch,異常的代碼放在 try 代碼塊內(nèi),如果沒(méi)有觸發(fā)異常,則代碼繼續(xù)執(zhí)行,如果異常被觸發(fā),就會(huì)拋出一個(gè)異常。Catch 代碼塊捕獲異常,并創(chuàng)建一個(gè)包含異常信息的對(duì)象。$e->getMessage(),輸出異常的錯(cuò)誤信息。
           解決異常:使用 set_error_handler 函數(shù)獲取異常(也可以使用 try()和 catch()函數(shù)),然后使用 set_exception_handler()函數(shù)設(shè)置默認(rèn)的異常處理程序,register_shutdown_function()函數(shù)來(lái)執(zhí)行,執(zhí)行機(jī)制是,php 要把調(diào)入的函數(shù)調(diào)入到內(nèi)存,當(dāng)頁(yè)面所有的 php 語(yǔ)句都執(zhí)行完成時(shí),再調(diào)用此函數(shù)
          

          17.前端

           答:我在工作中處理前端的功能,一般就是用 ajax 向后臺(tái)請(qǐng)求數(shù)據(jù),然后返回?cái)?shù)據(jù)在前臺(tái)頁(yè)面中顯示出來(lái)。我從來(lái)沒(méi)有獨(dú)立的完整的將 html 和 css 樣式都一個(gè)人完成,如果公司實(shí)在有這樣的需求的話,我可能會(huì)找一些前臺(tái)的模板或者說(shuō)是前端的框架,比如說(shuō) h—ui 等等
          

          18.權(quán)限管理(RBAC)的實(shí)現(xiàn)?

          答: 1.首先創(chuàng)建一張用戶(hù)表:id name auto(保存格式為:控制器-方法)
           2.然后在后臺(tái)中創(chuàng)建一個(gè)基類(lèi)控制器,控制器里封裝一個(gè)構(gòu)造方法,當(dāng)用戶(hù)登陸成功后,使用 TP 框架中封裝好的 session 函數(shù)獲取保存在服務(wù)器中的 session id,然后實(shí)例化模型,通過(guò)用戶(hù) id 獲取保存在數(shù)據(jù)表中的 auth 數(shù)據(jù),使用 explode 函數(shù)分割獲取到的數(shù)據(jù),并使用一個(gè)數(shù)組保存起來(lái),然后使用 TP 框架中封裝好的常量獲取當(dāng)前控制器和方法,然后把他們組裝成字符串,使用 in_array 函數(shù)進(jìn)行判斷該數(shù)組中是否含有當(dāng)前獲取到的控制器和方法,如果沒(méi)有,就提示該用戶(hù)沒(méi)有權(quán)限,如果有就進(jìn)行下一步操作
          

          19.支付功能的實(shí)現(xiàn)?

          答:
          

          20.怎么保證促銷(xiāo)商品不會(huì)超賣(mài)

           答:這個(gè)問(wèn)題是我們當(dāng)時(shí)開(kāi)發(fā)時(shí)遇到的一個(gè)難點(diǎn),超賣(mài)的原因主要是下的訂單的數(shù)目和我們要促銷(xiāo)的商品的數(shù)目不一致導(dǎo)致的,每次總是訂單的數(shù)比我們的促銷(xiāo)商品的數(shù)目要多,當(dāng)時(shí)我們的小組討論了好久,給出了好幾個(gè)方案來(lái)實(shí)現(xiàn):
           第一種方案是:①在每次下訂單前我們判斷促銷(xiāo)商品的數(shù)量夠不夠,不夠不允許下訂單,更改庫(kù)存量時(shí)加上一個(gè)條件,只更改商品庫(kù)存大于 0 的商品的庫(kù)存,當(dāng)時(shí)我們使用 ab 進(jìn)行壓力測(cè)試,當(dāng)并發(fā)超過(guò) 500,訪問(wèn)量超過(guò) 2000 時(shí),還是會(huì)出現(xiàn)超賣(mài)現(xiàn)象。所以被我們否定了。
           第二種方案是:②使用 mysql 的事務(wù)加排他鎖來(lái)解決,首先我們選擇數(shù)據(jù)庫(kù)的存儲(chǔ)引擎為 innoDB,使用的是排他鎖實(shí)現(xiàn)的,剛開(kāi)始的時(shí)候我們測(cè)試了下共享鎖,發(fā)現(xiàn)還是會(huì)出現(xiàn)超賣(mài)的現(xiàn)象。有個(gè)問(wèn)題是,當(dāng)我們進(jìn)行高并發(fā)測(cè)試時(shí),對(duì)數(shù)據(jù)庫(kù)的性能影響很大,導(dǎo)致數(shù)據(jù)庫(kù)的壓力很大,最終也被我們否定了。
           第三種方案是:③使用文件鎖實(shí)現(xiàn)。當(dāng)用戶(hù)搶到一件促銷(xiāo)商品后先觸發(fā)文件鎖,防止其他用戶(hù)進(jìn)入,該用戶(hù)搶到促銷(xiāo)品后再解開(kāi)文件鎖,放其他用戶(hù)進(jìn)行操作。這樣可以解決超賣(mài)的問(wèn)題,但是會(huì)導(dǎo)致文件得 I/O 開(kāi)銷(xiāo)很大。
           最后我們使用了 redis 的隊(duì)列來(lái)實(shí)現(xiàn)。將要促銷(xiāo)的商品數(shù)量以隊(duì)列的方式存入 redis 中,每當(dāng)用戶(hù)搶到一件促銷(xiāo)商品則從隊(duì)列中刪除一個(gè)數(shù)據(jù),確保商品不會(huì)超賣(mài)。這個(gè)操作起來(lái)很方便,而且效率極高,最終我們采取這種方式來(lái)實(shí)現(xiàn)
          

          21.商城秒殺的實(shí)現(xiàn)

           答:搶購(gòu)、秒殺是如今很常見(jiàn)的一個(gè)應(yīng)用場(chǎng)景,主要需要解決的問(wèn)題有兩個(gè):
           1 高并發(fā)對(duì)數(shù)據(jù)庫(kù)產(chǎn)生的壓力
           2 競(jìng)爭(zhēng)狀態(tài)下如何解決庫(kù)存的正確減少(”超賣(mài)”問(wèn)題)
           對(duì)于第一個(gè)問(wèn)題,已經(jīng)很容易想到用緩存來(lái)處理?yè)屬?gòu),避免直接操作數(shù)據(jù)庫(kù),例如使用 Redis。
           第二個(gè)問(wèn)題,我們可以使用 redis 隊(duì)列來(lái)完成,把要秒殺的商品放入到隊(duì)列中,因?yàn)?pop 操作是原子的,即使有很多用戶(hù)同時(shí)到達(dá),也是依次執(zhí)行,文件鎖和事務(wù)在高并發(fā)下性能下降很快,當(dāng)然還要考慮其他方面的東西,比如搶購(gòu)頁(yè)面做成靜態(tài)的,通過(guò) ajax 調(diào)用接口,其中也可能會(huì)出現(xiàn)一個(gè)用戶(hù)搶多次的情況,這時(shí)候需要再加上一個(gè)排隊(duì)隊(duì)列和搶購(gòu)結(jié)果隊(duì)列及庫(kù)存隊(duì)列。高并發(fā)情況下,將用戶(hù)進(jìn)入排隊(duì)隊(duì)列,用一個(gè)線程循環(huán)處理從排隊(duì)隊(duì)列取出一個(gè)用戶(hù),判斷用戶(hù)是否已在搶購(gòu)結(jié)果隊(duì)列,如果在,則已搶購(gòu),否則未搶購(gòu),庫(kù)存減 1,寫(xiě)數(shù)據(jù)庫(kù),將用戶(hù)入結(jié)果隊(duì)列。
          

          22.購(gòu)物車(chē)的原理

           答:購(gòu)物車(chē)相當(dāng)于現(xiàn)實(shí)中超市的購(gòu)物車(chē),不同的是一個(gè)是實(shí)體車(chē),一個(gè)是虛擬車(chē)而已。用戶(hù)可以在購(gòu)物網(wǎng)站的不同頁(yè)面之間跳轉(zhuǎn),以選購(gòu)自己喜愛(ài)的商品,點(diǎn)擊購(gòu)買(mǎi)時(shí),該商品就自動(dòng)保存到你的購(gòu)物車(chē)中,重復(fù)選購(gòu)后,最后將選中的所有商品放在購(gòu)物車(chē)中統(tǒng)一到付款臺(tái)結(jié)賬,這也是盡量讓客戶(hù)體驗(yàn)到現(xiàn)實(shí)生活中購(gòu)物的感覺(jué)。服務(wù)器通過(guò)追蹤每個(gè)用戶(hù)的行動(dòng),以保證在結(jié)賬時(shí)每件商品都物有其主。 
           主要涉及以下幾點(diǎn):
           1、把商品添加到購(gòu)物車(chē),即訂購(gòu)
           2、刪除購(gòu)物車(chē)中已定購(gòu)的商品
           3、修改購(gòu)物車(chē)中某一本圖書(shū)的訂購(gòu)數(shù)量
           4、清空購(gòu)物車(chē)
           5、顯示購(gòu)物車(chē)中商品清單及數(shù)量、價(jià)格
           實(shí)現(xiàn)購(gòu)物車(chē)的關(guān)鍵在于服務(wù)器識(shí)別每一個(gè)用戶(hù)并維持與他們的聯(lián)系。但是 HTTP 協(xié)議是一種“無(wú)狀態(tài)(Stateless)”的協(xié)議,因而服務(wù)器不能記住是誰(shuí)在購(gòu)買(mǎi)商品,當(dāng)把商品加入購(gòu)物車(chē)時(shí),服務(wù)器也不知道購(gòu)物車(chē)?yán)镌扔行┦裁矗沟糜脩?hù)在不同頁(yè)面間跳轉(zhuǎn)時(shí)購(gòu)物車(chē)無(wú)法“隨身攜帶”,這都給購(gòu)物車(chē)的實(shí)現(xiàn)造成了一定的困難。
           目前購(gòu)物車(chē)的實(shí)現(xiàn)主要是通過(guò) cookie、session 或結(jié)合數(shù)據(jù)庫(kù)的方式。下面分析一下它們的機(jī)制及作用。
          cookie
          cookie 是由服務(wù)器產(chǎn)生,存儲(chǔ)在客戶(hù)端的一段信息。它定義了一種 Web 服務(wù)器在客戶(hù)端存儲(chǔ)和返回信息的機(jī)制,cookie 文件它包含域、路徑、生存期、和由服務(wù)器設(shè)置的變量值等內(nèi)容。當(dāng)用戶(hù)以后訪問(wèn)同一個(gè) Web 服務(wù)器時(shí),瀏覽器會(huì)把 cookie 原樣發(fā)送給服務(wù)器。通過(guò)讓服務(wù)器讀取原先保存到客戶(hù)端的信息,網(wǎng)站能夠?yàn)闉g覽者提供一系列的方便,例如在線交易過(guò)程中標(biāo)識(shí)用戶(hù)身份、安全要求不高的場(chǎng)合避免用戶(hù)重復(fù)輸入名字和密碼、門(mén)戶(hù)網(wǎng)站的主頁(yè)定制、有針對(duì)性地投放廣告等等。利用 cookie 的特性,大大擴(kuò)展了 WEB 應(yīng)用程序的功能,不僅可以建立服務(wù)器與客戶(hù)機(jī)的聯(lián)系,因?yàn)?cookie 可以由服務(wù)器定制,因此還可以將購(gòu)物信息生成 cookie 值存放在客戶(hù)端,從而實(shí)現(xiàn)購(gòu)物車(chē)的功能。用基于 cookie 的方式實(shí)現(xiàn)服務(wù)器與瀏覽器之間的會(huì)話或購(gòu)物車(chē),有以下特點(diǎn):
          1、cookie 存儲(chǔ)在客戶(hù)端,且占用很少的資源,瀏覽器允許存放 300 個(gè) cookie,每個(gè) cookie 的大小為 4KB,足以滿(mǎn)足購(gòu)物車(chē)的要求,同時(shí)也減輕了服務(wù)器的負(fù)荷;
          2、cookie 為瀏覽器所內(nèi)置,使用方便。即使用戶(hù)不小心關(guān)閉了瀏覽器窗口,只要在 cookie 定義的有效期內(nèi),購(gòu)物車(chē)中的信息也不會(huì)丟失;
          3、cookie 不是可執(zhí)行文件,所以不會(huì)以任何方式執(zhí)行,因此也不會(huì)帶來(lái)病毒或攻擊用戶(hù)的系統(tǒng);
          4、基于 cookie 的購(gòu)物車(chē)要求用戶(hù)瀏覽器必須支持并設(shè)置為啟用 cookie,否則購(gòu)物車(chē)則失效;
          5、存在著關(guān)于 cookie 侵犯訪問(wèn)者隱私權(quán)的爭(zhēng)論,因此有些用戶(hù)會(huì)禁止本機(jī)的 cookie 功能。
          session
          session 是實(shí)現(xiàn)購(gòu)物車(chē)的另一種方法。session 提供了可以保存和跟蹤用戶(hù)的狀態(tài)信息的功能,使當(dāng)前用戶(hù)在 session 中定義的變量和對(duì)象能在頁(yè)面之間共享,但是不能為應(yīng)用中其他用戶(hù)所訪問(wèn),它與 cookie 最重大的區(qū)別是,session 將用戶(hù)在會(huì)話期間的私有信息存儲(chǔ)在服務(wù)器端,提高了安全性。在服務(wù)器生成 session 后,客戶(hù)端會(huì)生成一個(gè) sessionid 識(shí)別號(hào)保存在客戶(hù)端,以保持和服務(wù)器的同步。這個(gè) sessionid 是只讀的,如果客戶(hù)端禁止 cookie 功能,session 會(huì)通過(guò)在 URL 中附加參數(shù),或隱含在表單中提交等其他方式在頁(yè)面間傳送。因此利用 session 實(shí)施對(duì)用戶(hù)的管理則更為安全、有效。
          同樣,利用 session 也能實(shí)現(xiàn)購(gòu)物車(chē),這種方式的特點(diǎn)是:
          1、session 用新的機(jī)制保持與客戶(hù)端的同步,不依賴(lài)于客戶(hù)端設(shè)置;
          2、與 cookie 相比,session 是存儲(chǔ)在服務(wù)器端的信息,因此顯得更為安全,因此可將身份標(biāo)示,購(gòu)物等信息存儲(chǔ)在 session 中;
          3、session 會(huì)占用服務(wù)器資源,加大服務(wù)器端的負(fù)載,尤其當(dāng)并發(fā)用戶(hù)很多時(shí),會(huì)生成大量的 session,影響服務(wù)器的性能;
          4、因?yàn)?session 存儲(chǔ)的信息更敏感,而且是以文件形式保存在服務(wù)器中,因此仍然存在著安全隱患。
          結(jié)合數(shù)據(jù)庫(kù)的方式
          這也是目前較普遍的模式,在這種方式中,數(shù)據(jù)庫(kù)承擔(dān)著存儲(chǔ)購(gòu)物信息的作用,session 或 cookie 則用來(lái)跟蹤用戶(hù)。這種方式具有以下特點(diǎn):
          1、數(shù)據(jù)庫(kù)與 cookie 分別負(fù)責(zé)記錄數(shù)據(jù)和維持會(huì)話,能發(fā)揮各自的優(yōu)勢(shì),使安全性和服務(wù)器性能都得到了提高;
          2、每一個(gè)購(gòu)物的行為,都要直接建立與數(shù)據(jù)庫(kù)的連接,直至對(duì)表的操作完成后,連接才釋放。當(dāng)并發(fā)用戶(hù)很多時(shí),會(huì)影響數(shù)據(jù)庫(kù)的性能,因此,這對(duì)數(shù)據(jù)庫(kù)的性能提出了更高的要求;
          3、使 cookie 維持會(huì)話有賴(lài)客戶(hù)端的支持。
          各種方式的選擇:
          雖然 cookie 可用來(lái)實(shí)現(xiàn)購(gòu)物車(chē),但必須獲得瀏覽器的支持,再加上它是存儲(chǔ)在客戶(hù)端的信息,極易被獲取,所以這也限制了它存儲(chǔ)更多,更重要的信息。所以一般 cookie 只用來(lái)維持與服務(wù)器的會(huì)話,例如國(guó)內(nèi)最大的當(dāng)當(dāng)網(wǎng)絡(luò)書(shū)店就是用 cookie 保持與客戶(hù)的聯(lián)系,但是這種方式最大的缺點(diǎn)是如果客戶(hù)端不支持 cookie 就會(huì)使購(gòu)物車(chē)失效。
          Session 能很好地與交易雙方保持會(huì)話,可以忽視客戶(hù)端的設(shè)置。在購(gòu)物車(chē)技術(shù)中得到了廣泛的應(yīng)用。但 session 的文件屬性使其仍然留有安全隱患。
          結(jié)合數(shù)據(jù)庫(kù)的方式雖然在一定程度上解決了上述的問(wèn)題,但從上面的例子可以看出:在這種購(gòu)物流程中涉及到對(duì)數(shù)據(jù)庫(kù)表的頻繁操作,尤其是用戶(hù)每選購(gòu)一次商品,都要與數(shù)據(jù)庫(kù)進(jìn)行連接,當(dāng)用戶(hù)很多的時(shí)候就加大了服務(wù)器與數(shù)據(jù)庫(kù)的負(fù)荷。
          

          23.redis 消息隊(duì)列先進(jìn)先出需要注意什么

          答:通常使用一個(gè) list 來(lái)實(shí)現(xiàn)隊(duì)列操作,這樣有一個(gè)小限制,所以的任務(wù)統(tǒng)一都是先進(jìn)先出,如果想優(yōu)先處理某個(gè)任務(wù)就不太好處理了,這就需要讓隊(duì)列有優(yōu)先級(jí)的概念,我們就可以?xún)?yōu)先處理高級(jí)別的任務(wù),實(shí)現(xiàn)方式有以下幾種方式:
           1)單一列表實(shí)現(xiàn):隊(duì)列正常的操作是 左進(jìn)右出(lpush,rpop)為了先處理高優(yōu)先級(jí)任務(wù),在遇到高級(jí)別任務(wù)時(shí),可以直接插隊(duì),直接放入隊(duì)列頭部(rpush),這樣,從隊(duì)列頭部(右側(cè))獲取任務(wù)時(shí),取到的就是高優(yōu)先級(jí)的任務(wù)(rpop)
           2)使用兩個(gè)隊(duì)列,一個(gè)普通隊(duì)列,一個(gè)高級(jí)隊(duì)列,針對(duì)任務(wù)的級(jí)別放入不同的隊(duì)列,獲取任務(wù)時(shí)也很簡(jiǎn)單,redis 的 BRPOP 命令可以按順序從多個(gè)隊(duì)列中取值,BRPOP 會(huì)按照給出的 key 順序查看,并在找到的第一個(gè)非空 list 的尾部彈出一個(gè)元素,redis> BRPOP list1 list2 0
          list1 做為高優(yōu)先級(jí)任務(wù)隊(duì)列
          list2 做為普通任務(wù)隊(duì)列
          這樣就實(shí)現(xiàn)了先處理高優(yōu)先級(jí)任務(wù),當(dāng)沒(méi)有高優(yōu)先級(jí)任務(wù)時(shí),就去獲取普通任務(wù)
          方式 1 最簡(jiǎn)單,但實(shí)際應(yīng)用比較局限,方式 3 可以實(shí)現(xiàn)復(fù)雜優(yōu)先級(jí),但實(shí)現(xiàn)比較復(fù)雜,不利于維護(hù)
          方式 2 是推薦用法,實(shí)際應(yīng)用最為合適
          

          24.你負(fù)責(zé)的模塊有哪些難題

          答:在我負(fù)責(zé)的 B2B 電商項(xiàng)目中,當(dāng)時(shí)我負(fù)責(zé)的是訂單模塊,由于客戶(hù)一次選擇了多家商戶(hù)的商品,最終生成了一個(gè)訂單,這樣我們平臺(tái)在給商戶(hù)結(jié)算時(shí)出現(xiàn)了不知道這比費(fèi)用應(yīng)該給哪個(gè)商戶(hù),這時(shí)候我們小組經(jīng)過(guò)討論,需要涉及到訂單拆分,也就是說(shuō)用戶(hù)點(diǎn)擊支付后,如果有多件商品,并且不是同一家店鋪那么 就要用到訂單的拆分,比如如果有兩件商品,并且不是同一店鋪 就在原來(lái)的訂單號(hào)下 在生成兩個(gè)子訂單號(hào) 并修改訂單表中兩件商品的訂單號(hào)。最終實(shí)現(xiàn)了商品的分配管理,解決了我們的難題。
          我覺(jué)得在開(kāi)發(fā)過(guò)程中,遇到的難題無(wú)非是兩個(gè),一個(gè)是技術(shù)層次的,我認(rèn)為,只要你有恒心,有熱心,沒(méi)有覺(jué)得不了的難題。另一個(gè)就是溝通問(wèn)題,在任何地方任何時(shí)候溝通都是最重要的,尤其是我們做開(kāi)發(fā)的,不溝通好,會(huì)影響整個(gè)項(xiàng)目的進(jìn)度,我本人是個(gè)非常還溝通的人,所以這點(diǎn)上也沒(méi)多大問(wèn)題。
          

          25.用戶(hù)下單是怎么處理的

          答:判斷用戶(hù)有沒(méi)有登錄,在沒(méi)有登錄的情況下,不允許下單。登陸后,可進(jìn)行下單,并生成唯一的訂單號(hào),此時(shí)訂單的狀態(tài)為未支付。
          

          26.電商的登錄是怎么實(shí)現(xiàn)的

          答:分為普通登錄和第三方登錄 這邊主要說(shuō)一下第三方登錄吧,第三方登陸主要使用的是 author 協(xié)議,我就以 QQ 的第三方登陸為例來(lái)進(jìn)行說(shuō)明:當(dāng)用戶(hù)在我們的站點(diǎn)請(qǐng)求 QQ 的第三方登陸時(shí),我們站點(diǎn)會(huì)引導(dǎo)用戶(hù)跳轉(zhuǎn)到 QQ 的登陸授權(quán)界面, 當(dāng)用戶(hù)輸入 QQ 和密碼成功登錄以后會(huì)自動(dòng)跳回到我們站點(diǎn)設(shè)置好的回調(diào)頁(yè)面,并附帶一個(gè) code 參數(shù),接著你使用 code 再次去請(qǐng)求 QQ 的授權(quán)頁(yè)面,就可以從中獲取到一個(gè) access token(訪問(wèn)令牌),通過(guò)這個(gè) access_token,我們可以調(diào)用 QQ 提供給我們的接口,比如獲取 open_id,可以獲取用戶(hù)的基本信息。獲取到之后,我們需要拿用戶(hù)的授權(quán)信息和 open_id 和我們平臺(tái)的普通用戶(hù)進(jìn)行綁定。這樣不管是普通用戶(hù)登陸還是第三方登陸用戶(hù),都可以實(shí)現(xiàn)登陸。
          

          27.接口安全方面是怎么處理的

          答:我們當(dāng)時(shí)是這么做的,使用 HTTP 的 POST 方式,對(duì)固定參數(shù)+附加參數(shù)進(jìn)行數(shù)字簽名,使用的是 md5 加密,比如:我想通過(guò)標(biāo)題獲取一個(gè)信息,在客戶(hù)端使用 信息標(biāo)題+日期+雙方約定好的一個(gè) key 通過(guò) md5 加密生成一個(gè)簽名(sign),然后作為參數(shù)傳遞到服務(wù)器端,服務(wù)器端使用同樣的方法進(jìn)行校驗(yàn),如何接受過(guò)來(lái)的 sign 和我們通過(guò)算法算的值相同,證明是一個(gè)正常的接口請(qǐng)求,我們才會(huì)返回相應(yīng)的接口數(shù)據(jù)。
          

          28.用的什么技術(shù)實(shí)現(xiàn)短信發(fā)送,在哪調(diào)用

          答:我主要用的第三方短信接口,在申請(qǐng)接口時(shí)進(jìn)行相應(yīng)信息的配置,然后在我們站點(diǎn)需要用到短信驗(yàn)證的地方進(jìn)行調(diào)用,我們通常在用戶(hù)注冊(cè)時(shí)使用到。
          

          29.在工作中遇到什么困難?

          答:總體來(lái)說(shuō):在工作我主要遇到這幾個(gè)問(wèn)題比較難處理:
           ①我之前工作的時(shí)候發(fā)現(xiàn)經(jīng)常會(huì)出現(xiàn)一些臨時(shí)需求打亂了我的計(jì)劃,搞得有時(shí)候這個(gè)任務(wù)還沒(méi)完成,又得去做其他的任務(wù),最后一天下來(lái),大大小小的東西是很多,但是沒(méi)有完成得非常好的,后面我總結(jié)了一下,我會(huì)把這些都添加優(yōu)先級(jí),遇到臨時(shí)需求,按照優(yōu)先級(jí)重新將已有任務(wù)和臨時(shí)任務(wù)進(jìn)行排版,保證在規(guī)定時(shí)間內(nèi)有效率的完成優(yōu)先級(jí)高的任務(wù)。
           ②在做項(xiàng)目需求時(shí)候,遇到理解能力欠佳的人,溝通時(shí)容易被氣到,影響自己的情緒,最后反倒還不能到達(dá)需要的效果。后面,每次到這種時(shí)候,我一般會(huì)借助一些紙質(zhì)的、更加形象的東西,讓雙方都認(rèn)同的、都能明白的一種方式來(lái)進(jìn)行溝通,后面減少了很多不必須的麻煩。大家都知道,對(duì)于程序員來(lái)說(shuō),改需求是一件很痛苦的事情,所以前期的溝通工作很重要。
           ③還有一件事時(shí),我以前的領(lǐng)導(dǎo)不太懂技術(shù),所以每次出一個(gè)新的需求出來(lái),總是要求我們?cè)诤芏痰臅r(shí)間內(nèi)完成,完不成我們就會(huì)被懷疑能力有問(wèn)題。當(dāng)然,每個(gè)領(lǐng)導(dǎo)都希望自己的員工能夠盡快的完成任務(wù),降低成本,提高效率。這時(shí)候我會(huì)把我們的需求細(xì)化,把其中的重點(diǎn)、難點(diǎn)都列出來(lái),做好時(shí)間規(guī)劃,耐心的跟領(lǐng)導(dǎo)溝通,項(xiàng)目每個(gè)點(diǎn)的重要性和時(shí)間的花費(fèi)比例,確保在這個(gè)規(guī)劃的時(shí)間點(diǎn)內(nèi)保質(zhì)保量的完成任務(wù)。慢慢的也得到了領(lǐng)導(dǎo)的認(rèn)可,其實(shí)領(lǐng)導(dǎo)也不是一味的不通情理,只要把東西計(jì)劃好了,以最小的代價(jià)換取最高的價(jià)值,每個(gè)人都是很容易理解得
          

          30.用戶(hù)不登錄,怎么直接加入購(gòu)物車(chē)的

          答:用戶(hù)在不登錄的情況下,可以把要購(gòu)買(mǎi)商品的信息(如商品的 ID,商品的價(jià)格、商品的 sku_id,購(gòu)買(mǎi)數(shù)量等關(guān)鍵數(shù)據(jù))存到 COOKIE 里面,當(dāng)?shù)顷懙那闆r下。把 COOKIE 里面的內(nèi)容存到數(shù)據(jù)庫(kù),并清除 cookie 中的數(shù)據(jù)。
          

          31.寫(xiě)過(guò)接口嗎,怎么定義接口的

          答:寫(xiě)過(guò)。接口分為兩種:一種是數(shù)據(jù)型接口,一種是應(yīng)用型接口。
          數(shù)據(jù)型接口:是比抽象類(lèi)更抽象的某種“結(jié)構(gòu)”——它其實(shí)不是類(lèi),但是跟類(lèi)一樣的某種語(yǔ)法結(jié)構(gòu),是一種結(jié)構(gòu)規(guī)范,規(guī)范我們類(lèi)要以什么格式進(jìn)行定義,一般用于團(tuán)隊(duì)比較大,分支比較多的情況下使用。
          應(yīng)用型接口: API(application interface) 數(shù)據(jù)對(duì)外訪問(wèn)的一個(gè)入口
          我主要是參與的 APP 開(kāi)發(fā)中接口的編寫(xiě),客戶(hù)端需要什么樣的數(shù)據(jù),我們就給他們提供相應(yīng)的數(shù)據(jù),數(shù)據(jù)以 json/xml 的格式返回,并且配以相應(yīng)的接口文檔。
          

          32.sku 減庫(kù)存

          答:SKU = Stock Keeping Unit (庫(kù)存量單位) 
          即庫(kù)存進(jìn)出計(jì)量的單位,可以是以件,盒,托盤(pán)等為單位。SKU 是庫(kù)存量單位,區(qū)分單品。 
          在服裝、鞋類(lèi)商品中使用最多最普遍。 例如紡織品中一個(gè) SKU 通常表示:規(guī)格、顏色、款式。
          在設(shè)計(jì)表時(shí),不僅僅只有商品表,商品表中有個(gè)總庫(kù)存,我們還需要涉及一張 SKU 表,里面有 SKU 庫(kù)存和單價(jià)字段,用戶(hù)每購(gòu)買(mǎi)一件商品,實(shí)際上購(gòu)買(mǎi)的都是 SKU 商品,這樣在下訂單成功后,應(yīng)該根據(jù)所購(gòu)買(mǎi)的商品的唯一的 SKU 號(hào)來(lái)進(jìn)行相應(yīng)的 SKU 庫(kù)存的減少,當(dāng)然商品的總庫(kù)存保存在商品主表中,也需要減少總庫(kù)存中的庫(kù)存量。
          

          33.庫(kù)存設(shè)置?

          答:庫(kù)存分為商品總庫(kù)存和 SKU 庫(kù)存,往往商品總庫(kù)存的為 SKU 庫(kù)存的總和。一般在商城的后臺(tái)對(duì)貨品設(shè)置最高庫(kù)存及最低庫(kù)存后,當(dāng)前庫(kù)存數(shù)量與最高、最低兩者比較,超出庫(kù)存或者低于庫(kù)存的,則被統(tǒng)計(jì)成報(bào)表形式反映,便于用戶(hù)掌握貨品庫(kù)存超、短缺狀態(tài)及數(shù)量。
          

          34.訂單、庫(kù)存兩個(gè)表 如何保證數(shù)據(jù)的一致性?

          答:在一個(gè)電子商務(wù)系統(tǒng)中,正常的應(yīng)該是訂單生成成功后,相應(yīng)的庫(kù)存進(jìn)行減少。必須要保證兩者的一致性,但有時(shí)候因?yàn)槟承┰颍热绯绦蜻壿媶?wèn)題,并發(fā)等問(wèn)題,導(dǎo)致下單成功而庫(kù)存沒(méi)有減少的情況。這種情況我們是不允許發(fā)生的,MySQL 中的事務(wù)剛好可以解決這一問(wèn)題,首先得選擇數(shù)據(jù)庫(kù)的存儲(chǔ)引擎為 innoDB,事務(wù)規(guī)定了只有下訂單完成了,并且相應(yīng)的庫(kù)存減少了才允許提交事務(wù),否則就事務(wù)回滾,確保數(shù)據(jù)一致性。
          

          35.O2O 用戶(hù)下單,c 端下單,如何保證 b a 端數(shù)據(jù)一致?

          答:O2O 為線上和線下模式,O2O 模式奉行的是“線上支付+實(shí)體店消費(fèi)”的消費(fèi)模式,即消費(fèi)者在網(wǎng)上下單完成支付后,憑消費(fèi)憑證到實(shí)體店消費(fèi)。O2O 模式是把商家信息和支付程序放在線上進(jìn)行,而把商品和服務(wù)兌現(xiàn)放在線下,也就是說(shuō) O2O 模式適用于快遞無(wú)法送達(dá)的有形產(chǎn)品。數(shù)據(jù)一致性的問(wèn)題是 O2O 行業(yè)中最常見(jiàn)的問(wèn)題,我們可以類(lèi)似于數(shù)據(jù)庫(kù)的主從復(fù)制的思路來(lái)解決這個(gè)問(wèn)題。O2O 有個(gè)供應(yīng)商系統(tǒng),類(lèi)似于主服務(wù)器,在 C 端(從服務(wù)器)下單時(shí),數(shù)據(jù)同步更新到供應(yīng)商系統(tǒng)端,b、a 實(shí)時(shí)從供應(yīng)商系統(tǒng)中拉取數(shù)據(jù)進(jìn)行同步,比如利用定時(shí)任務(wù),定時(shí)拉取數(shù)據(jù)進(jìn)行同步。
          

          36.Redis 如何防止高并發(fā)

          答:其實(shí) redis 是不會(huì)存在并發(fā)問(wèn)題的,因?yàn)樗菃芜M(jìn)程的,再多的 command 都是 one by one 執(zhí)行的。我們使用的時(shí)候,可能會(huì)出現(xiàn)并發(fā)問(wèn)題,比如 get 和 set 這一對(duì)。
          redis 為什么會(huì)有高并發(fā)問(wèn)題
          redis 的出身決定
           Redis 是一種單線程機(jī)制的 nosql 數(shù)據(jù)庫(kù),基于 key-value,數(shù)據(jù)可持久化落盤(pán)。由于單線程所以 redis 本身并沒(méi)有鎖的概念,多個(gè)客戶(hù)端連接并不存在競(jìng)爭(zhēng)關(guān)系,但是利用 jedis 等客戶(hù)端對(duì) redis 進(jìn)行并發(fā)訪問(wèn)時(shí)會(huì)出現(xiàn)問(wèn)題。發(fā)生連接超時(shí)、數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤、阻塞、客戶(hù)端關(guān)閉連接等問(wèn)題,這些問(wèn)題均是由于客戶(hù)端連接混亂造成。
           同時(shí),單線程的天性決定,高并發(fā)對(duì)同一個(gè)鍵的操作會(huì)排隊(duì)處理,如果并發(fā)量很大,可能造成后來(lái)的請(qǐng)求超時(shí)。
           在遠(yuǎn)程訪問(wèn) redis 的時(shí)候,因?yàn)榫W(wǎng)絡(luò)等原因造成高并發(fā)訪問(wèn)延遲返回的問(wèn)題。
          解決辦法
           在客戶(hù)端將連接進(jìn)行池化,同時(shí)對(duì)客戶(hù)端讀寫(xiě) Redis 操作采用內(nèi)部鎖 synchronized。
           服務(wù)器角度,利用 setnx 變向?qū)崿F(xiàn)鎖機(jī)制。
          

          37.秒殺當(dāng)中的細(xì)節(jié)你是怎么得出來(lái)的

          答:通過(guò)性能測(cè)試及模擬秒殺場(chǎng)景。每個(gè)問(wèn)題都經(jīng)過(guò)反復(fù)測(cè)試,不斷的發(fā)現(xiàn)問(wèn)題,不斷的解決。
          

          38.做秒殺用什么數(shù)據(jù)庫(kù),怎么實(shí)現(xiàn)的。

          答:因?yàn)槊霘⒌囊凰查g,并發(fā)非常大,如果同時(shí)請(qǐng)求數(shù)據(jù)庫(kù),會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的壓力非常大,導(dǎo)致數(shù)據(jù)庫(kù)的性能急劇下降,更嚴(yán)重的可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)服務(wù)器宕機(jī)。這時(shí)候一般采用內(nèi)存高速緩存數(shù)據(jù)庫(kù) redis 來(lái)實(shí)現(xiàn)的,redis 是非關(guān)系型數(shù)據(jù)庫(kù),redis 是單線程的,通過(guò) redis 的隊(duì)列可以完成秒殺過(guò)程。
          

          39.支付寶流程怎么實(shí)現(xiàn)的

          答:首先要有一個(gè)支付寶賬號(hào),接下來(lái)向支付寶申請(qǐng)?jiān)诰€支付業(yè)務(wù),簽署協(xié)議。協(xié)議生效后有支付寶一方會(huì)給網(wǎng)站方一個(gè)合作伙伴 ID,和安全校驗(yàn)碼,有了這兩樣?xùn)|西就可以按照支付寶接口文檔開(kāi)發(fā)支付寶接口了,中間主要涉及到一個(gè)安全問(wèn)題。整個(gè)流程是這樣的:我們的網(wǎng)站通過(guò) post 傳遞相應(yīng)的參數(shù)(如訂單總金額,訂單號(hào))到支付頁(yè)面,支付頁(yè)面把一系列的參數(shù)經(jīng)過(guò)處理,以 post 的方式提交給支付寶服務(wù)器,支付寶服務(wù)器進(jìn)行驗(yàn)證,并對(duì)接收的數(shù)據(jù)進(jìn)行處理,把處理后的結(jié)果返回給我們網(wǎng)站設(shè)置的異步和同步回調(diào)地址,通過(guò)相應(yīng)的返回參數(shù),來(lái)處理相應(yīng)的業(yè)務(wù)邏輯,比如返回的參數(shù)代表支付成功,更改訂單狀態(tài)。
          

          40.什么是單點(diǎn)登錄?

          答:單點(diǎn)登錄 SSO(Single Sign On)說(shuō)得簡(jiǎn)單點(diǎn)就是在一個(gè)多系統(tǒng)共存的環(huán)境下,用戶(hù)在一處登錄后,就不用在其他系統(tǒng)中登錄,也就是用戶(hù)的一次登錄能得到其他所有系統(tǒng)的信任。
          

          41.什么情況下使用緩存

          答:當(dāng)用戶(hù)第一次訪問(wèn)應(yīng)用系統(tǒng)的時(shí)候,因?yàn)檫€沒(méi)有登錄,會(huì)被引導(dǎo)到認(rèn)證系統(tǒng)中進(jìn)行登錄;根據(jù)用戶(hù)提供的登錄信息,認(rèn)證系統(tǒng)進(jìn)行身份校驗(yàn),如果通過(guò)校驗(yàn),應(yīng)該返回給用戶(hù)一個(gè)認(rèn)證的憑據(jù)--ticket;用戶(hù)再訪問(wèn)別的應(yīng)用的時(shí)候,就會(huì)將這個(gè) ticket 帶上,作為自己認(rèn)證的憑據(jù),應(yīng)用系統(tǒng)接受到請(qǐng)求之后會(huì)把 ticket 送到認(rèn)證系統(tǒng)進(jìn)行校驗(yàn),檢查 ticket 的合法性。如果通過(guò)校驗(yàn),用戶(hù)就可以在不用再次登錄的情況下訪問(wèn)應(yīng)用系統(tǒng) 2 和應(yīng)用系統(tǒng) 3 了。
          實(shí)現(xiàn)主要技術(shù)點(diǎn):
           1、兩個(gè)站點(diǎn)共用一個(gè)數(shù)據(jù)驗(yàn)證系統(tǒng)
           2、主要通過(guò)跨域請(qǐng)求的方式來(lái)實(shí)現(xiàn)驗(yàn)證及 session 處理。
          

          42.怎么實(shí)現(xiàn)第三方登錄?

          答:第三方登陸主要是基于 author 協(xié)議來(lái)實(shí)現(xiàn),下面簡(jiǎn)單說(shuō)下實(shí)現(xiàn)流程:
           1、首先我們需要以開(kāi)發(fā)者的身份向第三方登陸平臺(tái)申請(qǐng)接入應(yīng)用,申請(qǐng)成功后,我們會(huì)獲得一個(gè) appID 和一個(gè) secrectID.
           2、當(dāng)我們的網(wǎng)站需接入第三方登陸時(shí),會(huì)引導(dǎo)用戶(hù)跳轉(zhuǎn)到第三方的登陸授權(quán)頁(yè)面,此時(shí)把之前申請(qǐng)的 appID 和 secrectID 帶給登陸授權(quán)頁(yè)面。
           3、用戶(hù)登陸成功后即得到授權(quán),第三方會(huì)返回一個(gè)臨時(shí)的 code 給我們的網(wǎng)站。
           4、我們的網(wǎng)站接受到 code 后,再次向我們的第三方發(fā)起請(qǐng)求,并攜帶接收的 code,從第三方獲取 access_token.
           5、第三方處理請(qǐng)求后,會(huì)返回一個(gè) access_token 給我們的網(wǎng)站,我們的網(wǎng)站獲取到 access_token 后就可以調(diào)用第三方提供的接口了,比如獲取用戶(hù)信息等。最后把該用戶(hù)信息存入到我們站點(diǎn)的數(shù)據(jù)庫(kù),并把信息保存到 session 中,實(shí)現(xiàn)用戶(hù)的第三方登陸。
          

          43.如何處理負(fù)載、高并發(fā)?(好好看看,經(jīng)常問(wèn)到,能回答到主要的東西即可)

          答:從低成本、高性能和高擴(kuò)張性的角度來(lái)說(shuō)有如下處理方案:
          1、HTML 靜態(tài)化
          其實(shí)大家都知道,效率最高、消耗最小的就是純靜態(tài)化的 html 頁(yè)面,所以我們盡可能使我們的 網(wǎng)站上的頁(yè)面采用靜態(tài)頁(yè)面來(lái)實(shí)現(xiàn),這個(gè)最簡(jiǎn)單的方法其實(shí)也是最有效的方法。
          2、圖片服務(wù)器分離
          把圖片單獨(dú)存儲(chǔ),盡量減少圖片等大流量的開(kāi)銷(xiāo),可以放在一些相關(guān)的平臺(tái)上,如騎牛等
          3、數(shù)據(jù)庫(kù)集群和庫(kù)表散列及緩存
          數(shù)據(jù)庫(kù)的并發(fā)連接為 100,一臺(tái)數(shù)據(jù)庫(kù)遠(yuǎn)遠(yuǎn)不夠,可以從讀寫(xiě)分離、主從復(fù)制,數(shù)據(jù)庫(kù)集群方面來(lái)著手。另外盡量減少數(shù)據(jù)庫(kù)的訪問(wèn),可以使用緩存數(shù)據(jù)庫(kù)如 memcache、redis。
          4、鏡像:
          盡量減少下載,可以把不同的請(qǐng)求分發(fā)到多個(gè)鏡像端。
          5、數(shù)據(jù)庫(kù)優(yōu)化
          6、負(fù)載均衡:
          Apache 的最大并發(fā)連接為 1500,只能增加服務(wù)器,可以從硬件上著手,如 F5 服務(wù)器。當(dāng)然硬件的成本比較高,我們往往從軟件方面著手。
          負(fù)載均衡 (Load Balancing) 建立在現(xiàn)有網(wǎng)絡(luò)結(jié)構(gòu)之上,它提供了一種廉價(jià)有效透明的方法擴(kuò)展網(wǎng)絡(luò)設(shè)備和服務(wù)器的帶寬、增加吞吐量、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力,同時(shí)能夠提高網(wǎng)絡(luò)的靈活性和可用性。目前使用最為廣泛的負(fù)載均衡軟件是 Nginx、LVS、HAProxy。我分別來(lái)說(shuō)下三種的優(yōu)缺點(diǎn):
          

          Nginx 的優(yōu)點(diǎn)是:

          1. 工作在網(wǎng)絡(luò)的 7 層之上,可以針對(duì) http 應(yīng)用做一些分流的策略,比如針對(duì)域名、目錄結(jié)構(gòu),它的正則規(guī)則比 HAProxy 更為強(qiáng)大和靈活,這也是它目前廣泛流行的主要原因之一,Nginx 單憑這點(diǎn)可利用的場(chǎng)合就遠(yuǎn)多于 LVS 了。
          2. Nginx 對(duì)網(wǎng)絡(luò)穩(wěn)定性的依賴(lài)非常小,理論上能 ping 通就就能進(jìn)行負(fù)載功能,這個(gè)也是它的優(yōu)勢(shì)之一;相反 LVS 對(duì)網(wǎng)絡(luò)穩(wěn)定性依賴(lài)比較大,這點(diǎn)本人深有體會(huì);
          3. Nginx 安裝和配置比較簡(jiǎn)單,測(cè)試起來(lái)比較方便,它基本能把錯(cuò)誤用日志打印出來(lái)。LVS 的配置、測(cè)試就要花比較長(zhǎng)的時(shí)間了,LVS 對(duì)網(wǎng)絡(luò)依賴(lài)比較大。
          4. 可以承擔(dān)高負(fù)載壓力且穩(wěn)定,在硬件不差的情況下一般能支撐幾萬(wàn)次的并發(fā)量,負(fù)載度比 LVS 相對(duì)小些。
          5. Nginx 可以通過(guò)端口檢測(cè)到服務(wù)器內(nèi)部的故障,比如根據(jù)服務(wù)器處理網(wǎng)頁(yè)返回的狀態(tài)碼、超時(shí)等等,并且會(huì)把返回錯(cuò)誤的請(qǐng)求重新提交到另一個(gè)節(jié)點(diǎn),不過(guò)其中缺點(diǎn)就是不支持 url 來(lái)檢測(cè)。比如用戶(hù)正在上傳一個(gè)文件,而處理該上傳的節(jié)點(diǎn)剛好在上傳過(guò)程中出現(xiàn)故障,Nginx 會(huì)把上傳切到另一臺(tái)服務(wù)器重新處理,而 LVS 就直接斷掉了,如果是上傳一個(gè)很大的文件或者很重要的文件的話,用戶(hù)可能會(huì)因此而不滿(mǎn)。
          6. Nginx 不僅僅是一款優(yōu)秀的負(fù)載均衡器/反向代理軟件,它同時(shí)也是功能強(qiáng)大的 Web 應(yīng)用服務(wù)器。LNMP 也是近幾年非常流行的 web 架構(gòu),在高流量的環(huán)境中穩(wěn)定性也很好。
          7. Nginx 現(xiàn)在作為 Web 反向加速緩存越來(lái)越成熟了,速度比傳統(tǒng)的 Squid 服務(wù)器更快,可以考慮用其作為反向代理加速器。
          8. Nginx 可作為中層反向代理使用,這一層面 Nginx 基本上無(wú)對(duì)手,唯一可以對(duì)比 Nginx 的就只有 lighttpd 了,不過(guò) lighttpd 目前還沒(méi)有做到 Nginx 完全的功能,配置也不那么清晰易讀,社區(qū)資料也遠(yuǎn)遠(yuǎn)沒(méi) Nginx 活躍。
          9. Nginx 也可作為靜態(tài)網(wǎng)頁(yè)和圖片服務(wù)器,這方面的性能也無(wú)對(duì)手。還有 Nginx 社區(qū)非常活躍,第三方模塊也很多。

          Nginx 的缺點(diǎn)是:

          1. Nginx 僅能支持 http、https 和 Email 協(xié)議,這樣就在適用范圍上面小些,這個(gè)是它的缺點(diǎn)。
          2. 對(duì)后端服務(wù)器的健康檢查,只支持通過(guò)端口來(lái)檢測(cè),不支持通過(guò) url 來(lái)檢測(cè)。不支持 Session 的直接保持,但能通過(guò) ip_hash 來(lái)解決。

          LVS:使用 Linux 內(nèi)核集群實(shí)現(xiàn)一個(gè)高性能、高可用的負(fù)載均衡服務(wù)器,它具有很好的可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

          LVS 的優(yōu)點(diǎn)是:

          1. 抗負(fù)載能力強(qiáng)、是工作在網(wǎng)絡(luò) 4 層之上僅作分發(fā)之用,沒(méi)有流量的產(chǎn)生,這個(gè)特點(diǎn)也決定了它在負(fù)載均衡軟件里的性能最強(qiáng)的,對(duì)內(nèi)存和 cpu 資源消耗比較低。
          2. 配置性比較低,這是一個(gè)缺點(diǎn)也是一個(gè)優(yōu)點(diǎn),因?yàn)闆](méi)有可太多配置的東西,所以并不需要太多接觸,大大減少了人為出錯(cuò)的幾率。
          3. 工作穩(wěn)定,因?yàn)槠浔旧砜关?fù)載能力很強(qiáng),自身有完整的雙機(jī)熱備方案,如 LVS+Keepalived,不過(guò)我們?cè)陧?xiàng)目實(shí)施中用得最多的還是 LVS/DR+Keepalived。
          4. 無(wú)流量,LVS 只分發(fā)請(qǐng)求,而流量并不從它本身出去,這點(diǎn)保證了均衡器 IO 的性能不會(huì)受到大流量的影響。
          5. 應(yīng)用范圍比較廣,因?yàn)?LVS 工作在 4 層,所以它幾乎可以對(duì)所有應(yīng)用做負(fù)載均衡,包括 http、數(shù)據(jù)庫(kù)、在線聊天室等等。

          LVS 的缺點(diǎn)是:

          1. 軟件本身不支持正則表達(dá)式處理,不能做動(dòng)靜分離;而現(xiàn)在許多網(wǎng)站在這方面都有較強(qiáng)的需求,這個(gè)是 Nginx/HAProxy+Keepalived 的優(yōu)勢(shì)所在。
          2. 如果是網(wǎng)站應(yīng)用比較龐大的話,LVS/DR+Keepalived 實(shí)施起來(lái)就比較復(fù)雜了,特別后面有 Windows Server 的機(jī)器的話,如果實(shí)施及配置還有維護(hù)過(guò)程就比較復(fù)雜了,相對(duì)而言,Nginx/HAProxy+Keepalived 就簡(jiǎn)單多了。

          HAProxy 的特點(diǎn)是:

          1. HAProxy 也是支持虛擬主機(jī)的。
          2. HAProxy 的優(yōu)點(diǎn)能夠補(bǔ)充 Nginx 的一些缺點(diǎn),比如支持 Session 的保持,Cookie 的引導(dǎo);同時(shí)支持通過(guò)獲取指定的 url 來(lái)檢測(cè)后端服務(wù)器的狀態(tài)。
          3. HAProxy 跟 LVS 類(lèi)似,本身就只是一款負(fù)載均衡軟件;單純從效率上來(lái)講 HAProxy 會(huì)比 Nginx 有更出色的負(fù)載均衡速度,在并發(fā)處理上也是優(yōu)于 Nginx 的。
          4. HAProxy 支持 TCP 協(xié)議的負(fù)載均衡轉(zhuǎn)發(fā),可以對(duì) MySQL 讀進(jìn)行負(fù)載均衡,對(duì)后端的 MySQL 節(jié)點(diǎn)進(jìn)行檢測(cè)和負(fù)載均衡,大家可以用 LVS+Keepalived 對(duì) MySQL 主從做負(fù)載均衡。
          5. HAProxy 負(fù)載均衡策略非常多,HAProxy 的負(fù)載均衡算法現(xiàn)在具體有如下 8 種:

          ① roundrobin,表示簡(jiǎn)單的輪詢(xún),這個(gè)不多說(shuō),這個(gè)是負(fù)載均衡基本都具備的;

          ② static-rr,表示根據(jù)權(quán)重,建議關(guān)注;

          ③ leastconn,表示最少連接者先處理,建議關(guān)注;

          ④ source,表示根據(jù)請(qǐng)求源 IP,這個(gè)跟 Nginx 的 IP_hash 機(jī)制類(lèi)似,我們用其作為解決 session 問(wèn)題的一種方法,建議關(guān)注;

          ⑤ ri,表示根據(jù)請(qǐng)求的 URI;

          ⑥ rl_param,表示根據(jù)請(qǐng)求的 URl 參數(shù)’balance url_param’ requires an URL parameter name;

          ⑦ hdr(name),表示根據(jù) HTTP 請(qǐng)求頭來(lái)鎖定每一次 HTTP 請(qǐng)求;

          ⑧ rdp-cookie(name),表示根據(jù)據(jù) cookie(name)來(lái)鎖定并哈希每一次 TCP 請(qǐng)求。

          Nginx 和 LVS 對(duì)比的總結(jié):

          1. Nginx 工作在網(wǎng)絡(luò)的 7 層,所以它可以針對(duì) http 應(yīng)用本身來(lái)做分流策略,比如針對(duì)域名、目錄結(jié)構(gòu)等,相比之下 LVS 并不具備這樣的功能,所以 Nginx 單憑這點(diǎn)可利用的場(chǎng)合就遠(yuǎn)多于 LVS 了;但 Nginx 有用的這些功能使其可調(diào)整度要高于 LVS,所以經(jīng)常要去觸碰觸碰,觸碰多了,人為出問(wèn)題的幾率也就會(huì)大。
          2. Nginx 對(duì)網(wǎng)絡(luò)穩(wěn)定性的依賴(lài)較小,理論上只要 ping 得通,網(wǎng)頁(yè)訪問(wèn)正常,Nginx 就能連得通,這是 Nginx 的一大優(yōu)勢(shì)!Nginx 同時(shí)還能區(qū)分內(nèi)外網(wǎng),如果是同時(shí)擁有內(nèi)外網(wǎng)的節(jié)點(diǎn),就相當(dāng)于單機(jī)擁有了備份線路;LVS 就比較依賴(lài)于網(wǎng)絡(luò)環(huán)境,目前來(lái)看服務(wù)器在同一網(wǎng)段內(nèi)并且 LVS 使用 direct 方式分流,效果較能得到保證。另外注意,LVS 需要向托管商至少申請(qǐng)多一個(gè) ip 來(lái)做 Visual IP,貌似是不能用本身的 IP 來(lái)做 VIP 的。要做好 LVS 管理員,確實(shí)得跟進(jìn)學(xué)習(xí)很多有關(guān)網(wǎng)絡(luò)通信方面的知識(shí),就不再是一個(gè) HTTP 那么簡(jiǎn)單了。
          3. Nginx 安裝和配置比較簡(jiǎn)單,測(cè)試起來(lái)也很方便,因?yàn)樗灸馨彦e(cuò)誤用日志打印出來(lái)。LVS 的安裝和配置、測(cè)試就要花比較長(zhǎng)的時(shí)間了;LVS 對(duì)網(wǎng)絡(luò)依賴(lài)比較大,很多時(shí)候不能配置成功都是因?yàn)榫W(wǎng)絡(luò)問(wèn)題而不是配置問(wèn)題,出了問(wèn)題要解決也相應(yīng)的會(huì)麻煩得多。
          4. Nginx 也同樣能承受很高負(fù)載且穩(wěn)定,但負(fù)載度和穩(wěn)定度差 LVS 還有幾個(gè)等級(jí):Nginx 處理所有流量所以受限于機(jī)器 IO 和配置;本身的 bug 也還是難以避免的。
          5. Nginx 可以檢測(cè)到服務(wù)器內(nèi)部的故障,比如根據(jù)服務(wù)器處理網(wǎng)頁(yè)返回的狀態(tài)碼、超時(shí)等等,并且會(huì)把返回錯(cuò)誤的請(qǐng)求重新提交到另一個(gè)節(jié)點(diǎn)。目前 LVS 中 ldirectd 也能支持針對(duì)服務(wù)器內(nèi)部的情況來(lái)監(jiān)控,但 LVS 的原理使其不能重發(fā)請(qǐng)求。比如用戶(hù)正在上傳一個(gè)文件,而處理該上傳的節(jié)點(diǎn)剛好在上傳過(guò)程中出現(xiàn)故障,Nginx 會(huì)把上傳切到另一臺(tái)服務(wù)器重新處理,而 LVS 就直接斷掉了,如果是上傳一個(gè)很大的文件或者很重要的文件的話,用戶(hù)可能會(huì)因此而惱火。
          6. Nginx 對(duì)請(qǐng)求的異步處理可以幫助節(jié)點(diǎn)服務(wù)器減輕負(fù)載,假如使用 apache 直接對(duì)外服務(wù),那么出現(xiàn)很多的窄帶鏈接時(shí) apache 服務(wù)器將會(huì)占用大 量?jī)?nèi)存而不能釋放,使用多一個(gè) Nginx 做 apache 代理的話,這些窄帶鏈接會(huì)被 Nginx 擋住,apache 上就不會(huì)堆積過(guò)多的請(qǐng)求,這樣就減少了相當(dāng)多的資源占用。這點(diǎn)使用 squid 也有相同的作用,即使 squid 本身配置為不緩存,對(duì) apache 還是有很大幫助的。
          7. Nginx 能支持 http、https 和 email(email 的功能比較少用),LVS 所支持的應(yīng)用在這點(diǎn)上會(huì)比 Nginx 更多。在使用上,一般最前端所采取的策略應(yīng)是 LVS,也就是 DNS 的指向應(yīng)為 LVS 均衡器,LVS 的優(yōu)點(diǎn)令它非常適合做這個(gè)任務(wù)。重要的 ip 地址,最好交由 LVS 托管,比如數(shù)據(jù)庫(kù)的 ip、webservice 服務(wù)器的 ip 等等,這些 ip 地址隨著時(shí)間推移,使用面會(huì)越來(lái)越大,如果更換 ip 則故障會(huì)接踵而至。所以將這些重要 ip 交給 LVS 托管是最為穩(wěn)妥的,這樣做的唯一缺點(diǎn)是需要的 VIP 數(shù)量會(huì)比較多。Nginx 可作為 LVS 節(jié)點(diǎn)機(jī)器使用,一是可以利用 Nginx 的功能,二是可以利用 Nginx 的性能。當(dāng)然這一層面也可以直接使用 squid,squid 的功能方面就比 Nginx 弱不少了,性能上也有所遜色于 Nginx。Nginx 也可作為中層代理使用,這一層面 Nginx 基本上無(wú)對(duì)手,唯一可以撼動(dòng) Nginx 的就只有 lighttpd 了,不過(guò) lighttpd 目前還沒(méi)有能做到 Nginx 完全的功能,配置也不那么清晰易讀。另外,中層代理的 IP 也是重要的,所以中層代理也擁有一個(gè) VIP 和 LVS 是最完美的方案了。具體的應(yīng)用還得具體分析,如果是比較小的網(wǎng)站(日 PV 小于 1000 萬(wàn)),用 Nginx 就完全可以了,如果機(jī)器也不少,可以用 DNS 輪詢(xún),LVS 所耗費(fèi)的機(jī)器還是比較多的;大型網(wǎng)站或者重要的服務(wù),機(jī)器不發(fā)愁的時(shí)候,要多多考慮利用 LVS。

          44.做秒殺時(shí)鎖表考慮到?jīng)]有?

          答:考慮到了,當(dāng)時(shí)我們做秒殺時(shí)考慮了好幾種方案,其中有一種就是使用事務(wù)加上排他鎖來(lái)實(shí)現(xiàn)。
          架構(gòu)類(lèi)的東西接觸過(guò)嗎?
           有接觸過(guò),曾經(jīng)自己在自己的服務(wù)器上配置過(guò)。我以前做過(guò)以下幾個(gè)架構(gòu)方面的配置和測(cè)試;
           1、數(shù)據(jù)庫(kù)的讀寫(xiě)分離、主從復(fù)制及集群。
           2、Nginx 負(fù)載均衡
           3、redis 集群及主從
          

          45.封裝過(guò)一個(gè)簡(jiǎn)單的框架

          答;封裝過(guò)一個(gè)簡(jiǎn)單的 MVC 框架,主要分為 3 層,控制器層和模型層視圖層,以及路由的分配和入口文件,模板引擎,單例模式、工廠模式,第三方類(lèi)庫(kù)的引入等。
          

          46.談?wù)剬?duì) MVC 的認(rèn)識(shí)

          答:核心思想是:視圖和用戶(hù)交互通過(guò)事件導(dǎo)致控制器改變 控制器改變導(dǎo)致模型改變 或者控制器同時(shí)改變兩者 模型改變 導(dǎo)致視圖改變 或者視圖改變 潛在的從模型里面獲得參數(shù) 來(lái)改變自己。他的好處是可以將界面和業(yè)務(wù)邏輯分離。
          Model(模型),是程序的主體部分,主要包含業(yè)務(wù)數(shù)據(jù)和業(yè)務(wù)邏輯。在模型層,還會(huì)涉及到用戶(hù)發(fā)布的服務(wù),在服務(wù)中會(huì)根據(jù)不同的業(yè)務(wù)需求,更新業(yè)務(wù)模型中的數(shù)據(jù)。
          View(視圖),是程序呈現(xiàn)給用戶(hù)的部分,是用戶(hù)和程序交互的接口,用戶(hù)會(huì)根據(jù)具體的業(yè)務(wù)需求,在 View 視圖層輸入自己特定的業(yè)務(wù)數(shù)據(jù),并通過(guò)界面的事件交互,將對(duì)應(yīng)的輸入?yún)?shù)提交給后臺(tái)控制器進(jìn)行處理。
          Contorller(控制器),Contorller 是用來(lái)處理用戶(hù) 輸入數(shù)據(jù),已經(jīng)更新業(yè)務(wù)模型的部分。控制器中接收了用戶(hù)與界面交互時(shí)傳遞過(guò)來(lái)的數(shù)據(jù),并根據(jù)數(shù)據(jù)業(yè)務(wù)邏輯來(lái)執(zhí)行服務(wù)的調(diào)用和更新業(yè)務(wù)模型的數(shù)據(jù)和狀態(tài)。
          

          47.session 與 cookie 的區(qū)別

          答:1、cookie 數(shù)據(jù)存放在第三方應(yīng)用的瀏覽器上,session 數(shù)據(jù)放在服務(wù)器上。
           2、cookie 不是很安全,別人可以分析存放在本地的 COOKIE,進(jìn)行 COOKIE 欺騙
          考慮到安全應(yīng)當(dāng)使用 session。
          3、session 會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能
          考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用 COOKIE。
          4、單個(gè) cookie 保存的數(shù)據(jù)不能超過(guò) 4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存 20 個(gè) cookie。
          5、所以個(gè)人建議:
           將登陸信息等重要信息存放為 SESSION
           其他信息如果需要保留,可以放在 COOKIE
          

          48.echo(),print(),print_r()的區(qū)別

          答:echo 可以一次輸出多個(gè)值,多個(gè)值之間用逗號(hào)分隔。echo 是語(yǔ)言結(jié)構(gòu)(language construct),而并不是真正的函數(shù),因此不能作為表達(dá)式的一部分使用。echo 是 php 的內(nèi)部指令,不是函數(shù),無(wú)返回值。
          print():函數(shù) print()打印一個(gè)值(它的參數(shù)),如果字符串成功顯示則返回 true,否則返回 false。只能打印出簡(jiǎn)單類(lèi)型變量的值(如 int,string),有返回值
          printf():源于 C 語(yǔ)言中的 printf()。該函數(shù)輸出格式化的字符串。
          print_r()和 var_dump()
          print_r()可以把字符串和數(shù)字簡(jiǎn)單地打印出來(lái),而數(shù)組則以括起來(lái)的鍵和值得列表形式顯示,并以 Array 開(kāi)頭。但 print_r()輸出布爾值和 NULL 的結(jié)果沒(méi)有意義,因?yàn)槎际谴蛴?\n"。因此用 var_dump()函數(shù)更適合調(diào)試。print_r 是函數(shù),可以打印出比較復(fù)雜的變量(如數(shù)組,對(duì)象),有返回值
          var_dump()判斷一個(gè)變量的類(lèi)型與長(zhǎng)度,并輸出變量的數(shù)值,如果變量有值輸?shù)氖亲兞康闹挡⒒胤禂?shù)據(jù)類(lèi)型。此函數(shù)顯示關(guān)于一個(gè)或多個(gè)表達(dá)式的結(jié)構(gòu)信息,包括表達(dá)式的類(lèi)型與值。數(shù)組將遞歸展開(kāi)值,通過(guò)縮進(jìn)顯示其結(jié)構(gòu)。
          

          49.說(shuō)一下單引號(hào)雙引號(hào)?

          答:①單引號(hào)內(nèi)部的變量不會(huì)執(zhí)行, 雙引號(hào)會(huì)執(zhí)行
          ②單引號(hào)解析速度比雙引號(hào)快。
          ③單引號(hào)只能解析部分特殊字符,雙引號(hào)可以解析所有特殊字符。
          

          50.索引的優(yōu)缺點(diǎn)

          答:1、優(yōu)點(diǎn):

          a)可以保證數(shù)據(jù)庫(kù)表中每一行的數(shù)據(jù)的唯一性

          b)可以大大加快數(shù)據(jù)的索引速度

          c)加速表與表之間的連接,物別是在實(shí)現(xiàn)數(shù)據(jù)的參考完事性方面特別有意義

          d)在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢(xún)中分組和排序的時(shí)間

          f)通過(guò)使用索引,可以在時(shí)間查詢(xún)的過(guò)程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能

          2、 缺點(diǎn):

          a) 創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加

          b) 索引需要占物理空間,除了數(shù)據(jù)表占用數(shù)據(jù)空間之外,每一個(gè)索引還要占用一定的物理空間,如果需要建立聚簇索引,那么需要占用的空間會(huì)更大

          c) 以表中的數(shù)據(jù)進(jìn)行增、刪、改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù),這就降低了整數(shù)的維護(hù)速度

          d) 建立索引的原則

          e) 在經(jīng)常需要搜索的列上,可以加快搜索的速度

          f) 在作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu)

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

          h) 在經(jīng)經(jīng)常需要根據(jù)范圍進(jìn)行搜索的列上創(chuàng)建索引,國(guó)為索引已經(jīng)排序,其指定的范圍是連續(xù)的

          i) 在經(jīng)常需要排序的列上,國(guó)為索引已經(jīng)排序,這樣井底可以利用索引的排序,加快排序井底時(shí)間

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

          || 內(nèi)容轉(zhuǎn)載網(wǎng)絡(luò) ||

          ttpd 2.4.6 + mysql-5.5.28 + php-5.4.19編譯安裝過(guò)程:

          一、編譯安裝apache

          1、解決依賴(lài)關(guān)系

          httpd-2.4.4需要較新版本的apr和apr-util,因此需要事先對(duì)其進(jìn)行升級(jí)。升級(jí)方式有兩種,一種是通過(guò)源代碼編譯安裝,一種是直接升級(jí)rpm包。

          (1) 編譯安裝apr

          # tar xf apr-1.4.6.tar.bz2

          # cd apr-1.4.6

          # ./configure --prefix=/usr/local/apr

          # make && make install

          (2) 編譯安裝apr-util

          # tar xf apr-util-1.4.1.tar.bz2

          # cd apr-util-1.4.1

          # ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr

          # make && make install

          (3) httpd-2.4.6編譯過(guò)程也要依賴(lài)于pcre-devel軟件包,需要事先安裝。此軟件包系統(tǒng)光盤(pán)自帶,因此,找到并安裝即可。

          2、編譯安裝httpd-2.4.6

          # tar xf httpd-2.4.4.tar.bz2 -C /usr/local

          # cd /usr/local/httpd-2.4.4

          # ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --enable-modules=most --enable-mpms-shared=most(將most更改為all,否則會(huì)出錯(cuò)) --with-mpm=event

          # make && make install

          補(bǔ)充:

          (1)構(gòu)建MPM為靜態(tài)模塊

          在全部平臺(tái)中,MPM都可以構(gòu)建為靜態(tài)模塊。在構(gòu)建時(shí)選擇一種MPM,鏈接到服務(wù)器中。如果要改變MPM,必須重新構(gòu)建。為了使用指定的MPM,請(qǐng)?jiān)趫?zhí)行configure腳本 時(shí),使用參數(shù) --with-mpm=NAME。NAME是指定的MPM名稱(chēng)。編譯完成后,可以使用 ./httpd -l 來(lái)確定選擇的MPM。 此命令會(huì)列出編譯到服務(wù)器程序中的所有模塊,包括 MPM。

          (2)構(gòu)建 MPM 為動(dòng)態(tài)模塊

          在Unix或類(lèi)似平臺(tái)中,MPM可以構(gòu)建為動(dòng)態(tài)模塊,與其它動(dòng)態(tài)模塊一樣在運(yùn)行時(shí)加載。 構(gòu)建 MPM 為動(dòng)態(tài)模塊允許通過(guò)修改LoadModule指令內(nèi)容來(lái)改變MPM,而不用重新構(gòu)建服務(wù)器程序。在執(zhí)行configure腳本時(shí),使用--enable-mpms-shared選項(xiàng)即可啟用此特性。當(dāng)給出的參數(shù)為all時(shí),所有此平臺(tái)支持的MPM模塊都會(huì)被安裝。還可以在參數(shù)中給出模塊列表。默認(rèn)MPM,可以自動(dòng)選擇或者在執(zhí)行configure腳本時(shí)通過(guò)--with-mpm選項(xiàng)來(lái)指定,然后出現(xiàn)在生成的服務(wù)器配置文件中。編輯LoadModule指令內(nèi)容可以選擇不同的MPM。

          3、修改httpd的主配置文件,設(shè)置其Pid文件的路徑

          編輯/etc/httpd/httpd.conf,添加如下行即可:

          PidFile "/var/run/httpd.pid"

          4、提供SysV服務(wù)腳本/etc/rc.d/init.d/httpd,內(nèi)容如下:

          #!/bin/bash

          #

          # httpd Startup script for the Apache HTTP Server

          #

          # chkconfig: - 85 15

          # description: Apache is a World Wide Web server. It is used to serve \

          # HTML files and CGI.

          # processname: httpd

          # config: /etc/httpd/conf/httpd.conf

          # config: /etc/sysconfig/httpd

          # pidfile: /var/run/httpd.pid

          # Source function library.

          . /etc/rc.d/init.d/functions

          if [ -f /etc/sysconfig/httpd ]; then

          . /etc/sysconfig/httpd

          fi

          # Start httpd in the C locale by default.

          HTTPD_LANG=${HTTPD_LANG-"C"}

          # This will prevent initlog from swallowing up a pass-phrase prompt if

          # mod_ssl needs a pass-phrase from the user.

          INITLOG_ARGS=""

          # Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server

          # with the thread-based "worker" MPM; BE WARNED that some modules may not

          # work correctly with a thread-based MPM; notably PHP will refuse to start.

          # Path to the apachectl script, server binary, and short-form for messages.

          apachectl=/usr/local/apache/bin/apachectl

          httpd=${HTTPD-/usr/local/apache/bin/httpd}

          prog=httpd

          pidfile=${PIDFILE-/var/run/httpd.pid}

          lockfile=${LOCKFILE-/var/lock/subsys/httpd}

          RETVAL=0

          start() {

          echo -n $"Starting $prog: "

          LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS

          RETVAL=$?

          echo

          [ $RETVAL = 0 ] && touch ${lockfile}

          return $RETVAL

          }

          stop() {

          echo -n $"Stopping $prog: "

          killproc -p ${pidfile} -d 10 $httpd

          RETVAL=$?

          echo

          [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}

          }

          reload() {

          echo -n $"Reloading $prog: "

          if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then

          RETVAL=$?

          echo $"not reloading due to configuration syntax error"

          failure $"not reloading $httpd due to configuration syntax error"

          else

          killproc -p ${pidfile} $httpd -HUP

          RETVAL=$?

          fi

          echo

          }

          # See how we were called.

          case "" in

          start)

          start

          ;;

          stop)

          stop

          ;;

          status)

          status -p ${pidfile} $httpd

          RETVAL=$?

          ;;

          restart)

          stop

          start

          ;;

          condrestart)

          if [ -f ${pidfile} ] ; then

          stop

          start

          fi

          ;;

          reload)

          reload

          ;;

          graceful|help|configtest|fullstatus)

          $apachectl $@

          RETVAL=$?

          ;;

          *)

          echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful|help|configtest}"

          exit 1

          esac

          exit $RETVAL

          而后為此腳本賦予執(zhí)行權(quán)限:

          # chmod +x /etc/rc.d/init.d/httpd

          加入服務(wù)列表:

          # chkconfig --add httpd

          接下來(lái)就可以啟動(dòng)服務(wù)進(jìn)行測(cè)試了。

          二:編譯安裝php-5.4.13

          1、解決依賴(lài)關(guān)系:

          請(qǐng)配置好yum源(可以是本地系統(tǒng)光盤(pán))后執(zhí)行如下命令:

          # yum -y groupinstall "X Software Development"

          yum groupinstall "Server Platform Development" "Developmenttools" "Desktop Platform Development"

          安裝數(shù)據(jù)加密等擴(kuò)展工具:libmcrypt、mhash、mcrypt

          2、編譯安裝php-5.4.13

          # tar xf php-5.4.19.tar.bz2

          # cd php-5.4.19

          # ./configure --prefix=/usr/local/php --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --enable-fpm --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --with-openssl --with-apxs2=/usr/local/apache/bin/apxs --enable-maintainer-zts

          說(shuō)明:

          1、這里為了支持apache的worker或event這兩個(gè)MPM,編譯時(shí)使用了--enable-maintainer-zts選項(xiàng)。

          2、如果使用PHP5.3以上版本,為了鏈接MySQL數(shù)據(jù)庫(kù),可以指定mysqlnd,這樣在本機(jī)就不需要先安裝MySQL或MySQL開(kāi)發(fā)包了。mysqlnd從php 5.3開(kāi)始可用,可以編譯時(shí)綁定到它(而不用和具體的MySQL客戶(hù)端庫(kù)綁定形成依賴(lài)),但從PHP 5.4開(kāi)始它就是默認(rèn)設(shè)置了。

          # ./configure --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd

          # make

          # make test

          # make intall

          為php提供配置文件:

          # cp php.ini-production /etc/php.ini

          3、 編輯apache配置文件httpd.conf,以apache支持php

          # vim /etc/httpd/httpd.conf

          1、添加如下二行

          AddType application/x-httpd-php .php

          AddType application/x-httpd-php-source .phps

          2、定位至DirectoryIndex index.html

          修改為:

          DirectoryIndex index.php index.html

          而后重新啟動(dòng)httpd,或讓其重新載入配置文件即可測(cè)試php是否已經(jīng)可以正常使用。

          4、配置php-fpm

          1、為php-fpm提供腳本:

          	cp /usr/local/php-5.4.19/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
          	chmod +x /etc/init.d/php-fpm
          2、提供php-fpm配置文件并編輯
           	 cp /usr/local/ php-5.4.19/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
          	vim /usr/local/php-5.4.19/etc/php-fpm.conf
           pm.max_children = 150
           pm.start_servers = 8
           pm.min_spare_servers = 5
           pm.max_spare_servers = 10
           pid = /usr/local/php/var/run/php-fpm.pid
          3、啟動(dòng)php-fpm服務(wù)
          	Service php-fpm start

          主站蜘蛛池模板: 精品动漫一区二区无遮挡| 一区二区三区波多野结衣| 日本美女一区二区三区| 中文字幕一区二区区免| 老熟妇高潮一区二区三区| 亚洲一区在线观看视频| 国偷自产一区二区免费视频| 精品一区二区三区水蜜桃| 无码国产精品一区二区免费模式| 精品一区二区高清在线观看| 精品国产一区二区三区久久狼| 精品人无码一区二区三区| 色欲AV蜜臀一区二区三区| 国产主播一区二区| 美女啪啪一区二区三区| 亲子乱AV视频一区二区| 中文字幕一区二区三区在线播放| 性色AV 一区二区三区| 波多野结衣一区在线| 精品一区二区三区无码免费直播 | 欲色aV无码一区二区人妻| 制服丝袜一区在线| 中文字幕精品一区二区日本| 国产精品熟女一区二区| 免费无码VA一区二区三区| 精品亚洲A∨无码一区二区三区| 国产一区二区免费| 久久精品黄AA片一区二区三区| 一区二区三区在线|欧| 国产短视频精品一区二区三区| 亚洲一区二区三区免费在线观看| 亚洲一区二区三区免费在线观看| 2018高清国产一区二区三区 | 中文字幕无线码一区二区| tom影院亚洲国产一区二区| 无码中文字幕人妻在线一区二区三区 | 亚洲成人一区二区| 肥臀熟女一区二区三区| 国产一区二区精品久久| 国产精品视频分类一区| 国产精品亚洲综合一区在线观看|