日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

阿里巴巴一面 :十道经典面试题解析

發(fā)布時(shí)間:2023/12/29 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 阿里巴巴一面 :十道经典面试题解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 用到分布式事務(wù)嘛?為什么用這種方案,有其他方案嘛?

什么是分布式事務(wù)

談到事務(wù),我們就會(huì)想到數(shù)據(jù)庫(kù)事務(wù),很容易就想到原子性、一致性、持久性、隔離性

分布式事務(wù)跟數(shù)據(jù)庫(kù)事務(wù)有點(diǎn)不一樣,它是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上。簡(jiǎn)單來說,分布式事務(wù)指的就是分布式系統(tǒng)中的事務(wù),它的存在就是為了保證不同數(shù)據(jù)庫(kù)節(jié)點(diǎn)的數(shù)據(jù)一致性。

分布式事務(wù)基礎(chǔ)

分布式事務(wù)需要需要知道CAP理論BASE理論

CAP理論

  • 一致性(C:Consistency):一致性是指數(shù)據(jù)在多個(gè)副本之間能否保持一致的特性。例如一個(gè)數(shù)據(jù)在某個(gè)分區(qū)節(jié)點(diǎn)更新之后,在其他分區(qū)節(jié)點(diǎn)讀出來的數(shù)據(jù)也是更新之后的數(shù)據(jù)。
  • 可用性(A:Availability):可用性是指系統(tǒng)提供的服務(wù)必須一直處于可用的狀態(tài),對(duì)于用戶的每一個(gè)操作請(qǐng)求總是能夠在有限的時(shí)間內(nèi)返回結(jié)果。這里的重點(diǎn)是"有限時(shí)間內(nèi)"和"返回結(jié)果"。
  • 分區(qū)容錯(cuò)性(P:Partition tolerance):分布式系統(tǒng)在遇到任何網(wǎng)絡(luò)分區(qū)故障的時(shí)候,仍然需要能夠保證對(duì)外提供滿足一致性和可用性的服務(wù)。

一個(gè)分布式系統(tǒng)中,CAP理論它只能同時(shí)滿足(一致性、可用性、分區(qū)容錯(cuò)性)中的兩點(diǎn)。

BASE 理論

BASE 理論, 是對(duì)CAP中AP的一個(gè)擴(kuò)展,對(duì)于我們的業(yè)務(wù)系統(tǒng),我們考慮犧牲一致性來?yè)Q取系統(tǒng)的可用性和分區(qū)容錯(cuò)性。BASE是Basically Available(基本可用),Soft state(軟狀態(tài)),和 Eventually consistent(最終一致性)三個(gè)短語(yǔ)的縮寫。

  • 基本可用是指,通過支持局部故障而不是系統(tǒng)全局故障來實(shí)現(xiàn)的;
  • Soft State表示狀態(tài)可以有一段時(shí)間不同步;
  • 最終一致,最終數(shù)據(jù)是一致的就可以了,而不是實(shí)時(shí)保持強(qiáng)一致。

分布式事務(wù)的幾種解決方案

  • 2PC(二階段提交)方案,事務(wù)的提交分為兩個(gè)階段:準(zhǔn)備階段和提交執(zhí)行方案。
  • TCC(即Try、Confirm、Cancel),它采用了補(bǔ)償機(jī)制,核心思想是:針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償(撤銷)操作。
  • 本地消息表,它的核心思想就是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理。
  • 最大努力通知,實(shí)現(xiàn)最大努力通知,可以采用MQ的ack機(jī)制。
  • Saga事務(wù),它的核心思想是將長(zhǎng)事務(wù)拆分為多個(gè)本地短事務(wù),由Saga事務(wù)協(xié)調(diào)器協(xié)調(diào),如果正常結(jié)束那就正常完成,如果某個(gè)步驟失敗,則根據(jù)相反順序一次調(diào)用補(bǔ)償操作。

業(yè)界目前使用本地消息表這種方案是比較多的,它的核心思想就是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理。可以看一下基本的實(shí)現(xiàn)流程圖吧:

對(duì)于消息發(fā)送方:

  • 首先需要有一個(gè)消息表,記錄著消息狀態(tài)相關(guān)信息。
  • 業(yè)務(wù)數(shù)據(jù)和消息表在同一個(gè)數(shù)據(jù)庫(kù),即要保證它倆在同一個(gè)本地事務(wù)。
  • 在本地事務(wù)中處理完業(yè)務(wù)數(shù)據(jù)和寫消息表操作后,通過寫消息到MQ消息隊(duì)列。
  • 消息會(huì)發(fā)到消息消費(fèi)方,如果發(fā)送失敗,即進(jìn)行重試。

消息消費(fèi)方:

  • 處理消息隊(duì)列中的消息,完成自己的業(yè)務(wù)邏輯。
  • 此時(shí)如果本地事務(wù)處理成功,則表明已經(jīng)處理成功了。
  • 如果本地事務(wù)處理失敗,那么就會(huì)重試執(zhí)行。
  • 如果是業(yè)務(wù)上面的失敗,給消息生產(chǎn)方發(fā)送一個(gè)業(yè)務(wù)補(bǔ)償消息,通知進(jìn)行回滾等操作。

生產(chǎn)方和消費(fèi)方定時(shí)掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發(fā)送一遍。如果有靠譜的自動(dòng)對(duì)賬補(bǔ)賬邏輯,這種方案還是非常實(shí)用的。

2.JDK6、7、8分別提供了哪些新特性

JDK 6 新特性

  • Desktop類(它允許一個(gè)Java應(yīng)用程序啟動(dòng)本地的另一個(gè)應(yīng)用程序去處理URI或文件請(qǐng)求)
  • 使用JAXB2來實(shí)現(xiàn)對(duì)象與XML之間的映射
  • 輕量級(jí) Http Server API
  • 插入式注解處理API(lombok框架基于這個(gè)特性實(shí)現(xiàn))
  • STAX(是JDK6中一種處理XML文檔的API)

JDK 7的新特性

  • switch 支持String字符串類型
  • try-with-resources,資源自動(dòng)關(guān)閉
  • 整數(shù)類型如(byte,short,int,long)能夠用二進(jìn)制來表示
  • 數(shù)字常量支持下劃線
  • 泛型實(shí)例化類型自動(dòng)推斷,即”<>”
  • 一個(gè)catch中捕獲多個(gè)異常類型,用(|)分隔開
  • 增強(qiáng)的文件系統(tǒng)
  • Fork/join 框架

JDK8 的新特性

  • lambada表達(dá)式
  • 函數(shù)式接口
  • 方法引用
  • 默認(rèn)方法
  • Stream API
  • Optional
  • Date Time API(如LocalDate)
  • 重復(fù)注解
  • Base64
  • JVM的新特性(如元空間Metaspace代替持久代)

3. https原理,工作流程

  • HTTPS = HTTP + SSL/TLS,即用SSL/TLS對(duì)數(shù)據(jù)進(jìn)行加密和解密,Http進(jìn)行傳輸。
  • SSL,即Secure Sockets Layer(安全套接層協(xié)議),是網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。
  • TLS,即Transport Layer Security(安全傳輸層協(xié)議),它是SSL3.0的后續(xù)版本。

  • 客戶端發(fā)起Https請(qǐng)求,連接到服務(wù)器的443端口。
  • 服務(wù)器必須要有一套數(shù)字證書(證書內(nèi)容有公鑰、證書頒發(fā)機(jī)構(gòu)、失效日期等)。
  • 服務(wù)器將自己的數(shù)字證書發(fā)送給客戶端(公鑰在證書里面,私鑰由服務(wù)器持有)。
  • 客戶端收到數(shù)字證書之后,會(huì)驗(yàn)證證書的合法性。如果證書驗(yàn)證通過,就會(huì)生成一個(gè)隨機(jī)的對(duì)稱密鑰,用證書的公鑰加密。
  • 客戶端將公鑰加密后的密鑰發(fā)送到服務(wù)器。
  • 服務(wù)器接收到客戶端發(fā)來的密文密鑰之后,用自己之前保留的私鑰對(duì)其進(jìn)行非對(duì)稱解密,解密之后就得到客戶端的密鑰,然后用客戶端密鑰對(duì)返回?cái)?shù)據(jù)進(jìn)行對(duì)稱加密,醬紫傳輸?shù)臄?shù)據(jù)都是密文啦。
  • 服務(wù)器將加密后的密文返回到客戶端。
  • 客戶端收到后,用自己的密鑰對(duì)其進(jìn)行對(duì)稱解密,得到服務(wù)器返回的數(shù)據(jù)。
  • 4. 講講java jmm volatile的實(shí)現(xiàn)原理

    volatile關(guān)鍵字是Java虛擬機(jī)提供的的最輕量級(jí)的同步機(jī)制,它作為一個(gè)修飾符,用來修飾變量。它保證變量對(duì)所有線程可見性,禁止指令重排,但是不保證原子性。

    volatile是如何保證可見性的呢?我們先來看下java內(nèi)存模型(jmm)

    • Java虛擬機(jī)規(guī)范試圖定義一種Java內(nèi)存模型,來屏蔽掉各種硬件和操作系統(tǒng)的內(nèi)存訪問差異,以實(shí)現(xiàn)讓Java程序在各種平臺(tái)上都能達(dá)到一致的內(nèi)存訪問效果。
    • 為了更好的執(zhí)行性能,java內(nèi)存模型并沒有限制執(zhí)行引擎使用處理器的特定寄存器或緩存來和主內(nèi)存打交道,也沒有限制編譯器進(jìn)行調(diào)整代碼順序優(yōu)化。所以Java內(nèi)存模型會(huì)存在緩存一致性問題和指令重排序問題的。
    • Java內(nèi)存模型規(guī)定所有的變量都是存在主內(nèi)存當(dāng)中,每個(gè)線程都有自己的工作內(nèi)存。這里的變量包括實(shí)例變量和靜態(tài)變量,但是不包括局部變量,因?yàn)榫植孔兞渴蔷€程私有的。
    • 線程的工作內(nèi)存保存了被該線程使用的變量的主內(nèi)存副本,線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行,而不能直接操作操作主內(nèi)存。并且每個(gè)線程不能訪問其他線程的工作內(nèi)存。

    volatile變量,保證新值能立即同步回主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新,所以我們說volatile保證了多線程操作變量的可見性

    指令重排是指在程序執(zhí)行過程中,為了提高性能, 編譯器和CPU可能會(huì)對(duì)指令進(jìn)行重新排序。volatile是如何禁止指令重排的?在Java語(yǔ)言中,有一個(gè)先行發(fā)生原則(happens-before)

    • 程序次序規(guī)則:在一個(gè)線程內(nèi),按照控制流順序,書寫在前面的操作先行發(fā)生于書寫在后面的操作。
    • 管程鎖定規(guī)則:一個(gè)unLock操作先行發(fā)生于后面對(duì)同一個(gè)鎖額lock操作
    • volatile變量規(guī)則:對(duì)一個(gè)變量的寫操作先行發(fā)生于后面對(duì)這個(gè)變量的讀操作
    • 線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法先行發(fā)生于此線程的每個(gè)一個(gè)動(dòng)作
    • 線程終止規(guī)則:線程中所有的操作都先行發(fā)生于線程的終止檢測(cè),我們可以通過Thread.join()方法結(jié)束、Thread.isAlive()的返回值手段檢測(cè)到線程已經(jīng)終止執(zhí)行
    • 線程中斷規(guī)則:對(duì)線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生
    • 對(duì)象終結(jié)規(guī)則:一個(gè)對(duì)象的初始化完成先行發(fā)生于他的finalize()方法的開始
    • 傳遞性:如果操作A先行發(fā)生于操作B,而操作B又先行發(fā)生于操作C,則可以得出操作A先行發(fā)生于操作C

    實(shí)際上volatile保證可見性和禁止指令重排都跟內(nèi)存屏障有關(guān)。我們來看一段volatile使用的demo代碼

    public class Singleton { private volatile static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } 復(fù)制代碼

    編譯后,對(duì)比有volatile關(guān)鍵字和沒有volatile關(guān)鍵字時(shí)所生成的匯編代碼,發(fā)現(xiàn)有volatile關(guān)鍵字修飾時(shí),會(huì)多出一個(gè)lock addl $0x0,(%esp),即多出一個(gè)lock前綴指令,lock指令相當(dāng)于一個(gè)「內(nèi)存屏障」

    lock指令相當(dāng)于一個(gè)內(nèi)存屏障,它保證以下這幾點(diǎn):

    • 1.重排序時(shí)不能把后面的指令重排序到內(nèi)存屏障之前的位置
    • 2.將本處理器的緩存寫入內(nèi)存
    • 3.如果是寫入動(dòng)作,會(huì)導(dǎo)致其他處理器中對(duì)應(yīng)的緩存無效。

    第2點(diǎn)和第3點(diǎn)就是保證volatile保證可見性的體現(xiàn)嘛,第1點(diǎn)就是禁止指令重排列的體現(xiàn)。內(nèi)存屏障又是什么呢?

    內(nèi)存屏障四大分類:(Load 代表讀取指令,Store代表寫入指令)

    內(nèi)存屏障類型抽象場(chǎng)景描述
    LoadLoad屏障Load1; LoadLoad; Load2在Load2要讀取的數(shù)據(jù)被訪問前,保證Load1要讀取的數(shù)據(jù)被讀取完畢。
    StoreStore屏障Store1; StoreStore; Store2在Store2寫入執(zhí)行前,保證Store1的寫入操作對(duì)其它處理器可見
    LoadStore屏障Load1; LoadStore; Store2在Store2被寫入前,保證Load1要讀取的數(shù)據(jù)被讀取完畢。
    StoreLoad屏障Store1; StoreLoad; Load2在Load2讀取操作執(zhí)行前,保證Store1的寫入對(duì)所有處理器可見。

    為了實(shí)現(xiàn)volatile的內(nèi)存語(yǔ)義,Java內(nèi)存模型采取以下的保守策略

    • 在每個(gè)volatile寫操作的前面插入一個(gè)StoreStore屏障。
    • 在每個(gè)volatile寫操作的后面插入一個(gè)StoreLoad屏障。
    • 在每個(gè)volatile讀操作的后面插入一個(gè)LoadLoad屏障。
    • 在每個(gè)volatile讀操作的后面插入一個(gè)LoadStore屏障。

    有些小伙伴,可能對(duì)這個(gè)還是有點(diǎn)疑惑,內(nèi)存屏障這玩意太抽象了。我們照著代碼看下吧:

    內(nèi)存屏障保證前面的指令先執(zhí)行,所以這就保證了禁止了指令重排啦,同時(shí)內(nèi)存屏障保證緩存寫入內(nèi)存和其他處理器緩存失效,這也就保證了可見性,哈哈~

    5. 講一講7層網(wǎng)絡(luò)模型,tcp的為什么要三次握手

    計(jì)算機(jī)網(wǎng)路體系結(jié)構(gòu)有三層:OSI七層模型、TCP/IP四層模型、五層體系結(jié)構(gòu),如圖:

    七層模型,亦稱OSI(Open System Interconnection),國(guó)際標(biāo)準(zhǔn)化組織(International Organization for Standardization)制定的一個(gè)用于計(jì)算機(jī)或通信系統(tǒng)間互聯(lián)的標(biāo)準(zhǔn)體系。

    • 應(yīng)用層:網(wǎng)絡(luò)服務(wù)與最終用戶的一個(gè)接口,常見的協(xié)議有:HTTP FTP SMTP SNMP DNS.
    • 表示層:數(shù)據(jù)的表示、安全、壓縮。,確保一個(gè)系統(tǒng)的應(yīng)用層所發(fā)送的信息可以被另一個(gè)系統(tǒng)的應(yīng)用層讀取。
    • 會(huì)話層:建立、管理、終止會(huì)話,對(duì)應(yīng)主機(jī)進(jìn)程,指本地主機(jī)與遠(yuǎn)程主機(jī)正在進(jìn)行的會(huì)話.
    • 傳輸層:定義傳輸數(shù)據(jù)的協(xié)議端口號(hào),以及流控和差錯(cuò)校驗(yàn),協(xié)議有TCP UDP.
    • 網(wǎng)絡(luò)層:進(jìn)行邏輯地址尋址,實(shí)現(xiàn)不同網(wǎng)絡(luò)之間的路徑選擇,協(xié)議有ICMP IGMP IP等.
    • 數(shù)據(jù)鏈路層:在物理層提供比特流服務(wù)的基礎(chǔ)上,建立相鄰結(jié)點(diǎn)之間的數(shù)據(jù)鏈路。
    • 物理層:建立、維護(hù)、斷開物理連接。

    6.說說線程池的工作原理

    面試官如果要我們講下線程池工作原理的話,大家講下以下這個(gè)流程圖就可以啦:

    為了形象描述線程池執(zhí)行,加深大家的理解,我打個(gè)比喻:

    • 核心線程比作公司正式員工
    • 非核心線程比作外包員工
    • 阻塞隊(duì)列比作需求池
    • 提交任務(wù)比作提需求

    • 當(dāng)產(chǎn)品提個(gè)需求,正式員工(核心線程)先接需求(執(zhí)行任務(wù))
    • 如果正式員工都有需求在做,即核心線程數(shù)已滿),產(chǎn)品就把需求先放需求池(阻塞隊(duì)列)。
    • 如果需求池(阻塞隊(duì)列)也滿了,但是這時(shí)候產(chǎn)品繼續(xù)提需求,怎么辦呢?那就請(qǐng)外包(非核心線程)來做。
    • 如果所有員工(最大線程數(shù)也滿了)都有需求在做了,那就執(zhí)行拒絕策略。
    • 如果外包員工把需求做完了,它經(jīng)過一段(keepAliveTime)空閑時(shí)間,就離開公司了。

    7.你們數(shù)據(jù)庫(kù)的高可用是怎么實(shí)現(xiàn)的?

    高可用,即High Availability,是分布式系統(tǒng)架構(gòu)設(shè)計(jì)中必須考慮的因素之一,它通常是指,通過設(shè)計(jì)減少系統(tǒng)不能提供服務(wù)的時(shí)間。單機(jī)部署談不上高可用,因?yàn)?strong>單點(diǎn)故障問題。高可用都是多個(gè)節(jié)點(diǎn)的,我們?cè)诳紤]MySQL數(shù)據(jù)庫(kù)的高可用的架構(gòu)時(shí),需要考慮這幾個(gè)方面:

    • 如果數(shù)據(jù)庫(kù)節(jié)點(diǎn)宕機(jī),需要盡快回復(fù),保證業(yè)務(wù)不受宕機(jī)影響。
    • 從數(shù)據(jù)庫(kù)節(jié)點(diǎn)的數(shù)據(jù),盡可能跟主節(jié)點(diǎn)數(shù)據(jù)實(shí)時(shí)保持一致,至少保證最終一致性。
    • 數(shù)據(jù)庫(kù)節(jié)點(diǎn)切換時(shí),數(shù)據(jù)不能缺失。

    7.1 主從或主主半同步復(fù)制

    用雙節(jié)點(diǎn)數(shù)據(jù)庫(kù),搭建單向或者雙向的半同步復(fù)制。架構(gòu)如下:

    通常會(huì)和proxy、keepalived等第三方軟件同時(shí)使用,即可以用來監(jiān)控?cái)?shù)據(jù)庫(kù)的健康,又可以執(zhí)行一系列管理命令。如果主庫(kù)發(fā)生故障,切換到備庫(kù)后仍然可以繼續(xù)使用數(shù)據(jù)庫(kù)。

    這種方案優(yōu)點(diǎn)是架構(gòu)、部署比較簡(jiǎn)單,主機(jī)宕機(jī)直接切換即可。缺點(diǎn)是完全依賴于半同步復(fù)制,半同步復(fù)制退化為異步復(fù)制,無法保證數(shù)據(jù)一致性;另外,還需要額外考慮haproxy、keepalived的高可用機(jī)制。

    7.2 半同步復(fù)制優(yōu)化

    半同步復(fù)制機(jī)制是可靠的,可以保證數(shù)據(jù)一致性的。但是如果網(wǎng)絡(luò)發(fā)生波動(dòng),半同步復(fù)制發(fā)生超時(shí)會(huì)切換為異步復(fù)制,異復(fù)制是無法保證數(shù)據(jù)的一致性的。因此,可以在半同復(fù)制的基礎(chǔ)上優(yōu)化一下,盡可能保證半同復(fù)制。如雙通道復(fù)制方案

    • 優(yōu)點(diǎn):這種方案架構(gòu)、部署也比較簡(jiǎn)單,主機(jī)宕機(jī)也是直接切換即可。比方案1的半同步復(fù)制,更能保證數(shù)據(jù)的一致性。
    • 缺點(diǎn):需要修改內(nèi)核源碼或者使用mysql通信協(xié)議,沒有從根本上解決數(shù)據(jù)一致性問題。

    7.3 高可用架構(gòu)優(yōu)化

    保證高可用,可以把主從雙節(jié)點(diǎn)數(shù)據(jù)庫(kù)擴(kuò)展為數(shù)據(jù)庫(kù)集群。Zookeeper可以作為集群管理,它使用分布式算法保證集群數(shù)據(jù)的一致性,可以較好的避免網(wǎng)絡(luò)分區(qū)現(xiàn)象的產(chǎn)生。

    • 優(yōu)點(diǎn):保證了整個(gè)系統(tǒng)的高可用性,擴(kuò)展性也較好,可以擴(kuò)展為大規(guī)模集群。
    • 缺點(diǎn):數(shù)據(jù)一致性仍然依賴于原生的mysql半同步復(fù)制;引入Zookeeper使系統(tǒng)邏輯更復(fù)雜。

    7.4 共享存儲(chǔ)

    共享存儲(chǔ)實(shí)現(xiàn)了數(shù)據(jù)庫(kù)服務(wù)器和存儲(chǔ)設(shè)備的解耦,不同數(shù)據(jù)庫(kù)之間的數(shù)據(jù)同步不再依賴于MySQL的原生復(fù)制功能,而是通過磁盤數(shù)據(jù)同步的手段,來保證數(shù)據(jù)的一致性。

    DRBD磁盤復(fù)制

    DRBD是一個(gè)用軟件實(shí)現(xiàn)的、無共享的、服務(wù)器之間鏡像塊設(shè)備內(nèi)容的存儲(chǔ)復(fù)制解決方案。主要用于對(duì)服務(wù)器之間的磁盤、分區(qū)、邏輯卷等進(jìn)行數(shù)據(jù)鏡像,當(dāng)用戶將數(shù)據(jù)寫入本地磁盤時(shí),還會(huì)將數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)中另一臺(tái)主機(jī)的磁盤上,這樣的本地主機(jī)(主節(jié)點(diǎn))與遠(yuǎn)程主機(jī)(備節(jié)點(diǎn))的數(shù)據(jù)就可以保證實(shí)時(shí)同步。常用架構(gòu)如下:

    當(dāng)本地主機(jī)出現(xiàn)問題,遠(yuǎn)程主機(jī)上還保留著一份相同的數(shù)據(jù),即可以繼續(xù)使用,保證了數(shù)據(jù)的安全。

    • 優(yōu)點(diǎn):部署簡(jiǎn)單,價(jià)格合適,保證數(shù)據(jù)的強(qiáng)一致性
    • 缺點(diǎn):對(duì)IO性能影響較大,從庫(kù)不提供讀操作

    7.5 分布式協(xié)議

    分布式協(xié)議可以很好解決數(shù)據(jù)一致性問題。常見的部署方案就是MySQL cluster,它是官方集群的部署方案,通過使用NDB存儲(chǔ)引擎實(shí)時(shí)備份冗余數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)庫(kù)的高可用性和數(shù)據(jù)一致性。如下:

    • 優(yōu)點(diǎn):不依賴于第三方軟件,可以實(shí)現(xiàn)數(shù)據(jù)的強(qiáng)一致性;
    • 缺點(diǎn):配置較復(fù)雜;需要使用NDB儲(chǔ)存引擎;至少三節(jié)點(diǎn);

    8. 讀寫分離的場(chǎng)景下,怎么保證從數(shù)據(jù)庫(kù)讀到最新的數(shù)據(jù)?

    數(shù)據(jù)庫(kù)讀寫分離,主要解決高并發(fā)時(shí),提高系統(tǒng)的吞吐量。來看下讀寫分離數(shù)據(jù)庫(kù)模型:

    • 寫請(qǐng)求是直接寫主庫(kù),然后同步數(shù)據(jù)到從庫(kù)
    • 讀請(qǐng)求一般直接讀從庫(kù),除飛強(qiáng)制讀主庫(kù)

    在高并發(fā)場(chǎng)景或者網(wǎng)絡(luò)不佳的場(chǎng)景,如果存在較大的主從同步數(shù)據(jù)延遲,這時(shí)候讀請(qǐng)求去讀從庫(kù),就會(huì)讀到舊數(shù)據(jù)。這時(shí)候最簡(jiǎn)單暴力的方法,就是強(qiáng)制讀主庫(kù)。實(shí)際上可以使用緩存標(biāo)記法

    • A發(fā)起寫請(qǐng)求,更新主庫(kù)數(shù)據(jù),并在緩存中設(shè)置一個(gè)標(biāo)記,表示數(shù)據(jù)已更新,標(biāo)記格式為:userId+業(yè)務(wù)Id。
    • 設(shè)置此標(biāo)記,設(shè)置過期時(shí)間(估值為主庫(kù)和從庫(kù)同步延遲的時(shí)間)
    • B發(fā)起讀請(qǐng)求,先判斷此請(qǐng)求,在緩存中有沒有更新標(biāo)記。
    • 如果存在標(biāo)記,走主庫(kù);如果沒有,請(qǐng)求走從庫(kù)。

    這個(gè)方案,解決了數(shù)據(jù)不一致問題,但是每次請(qǐng)求都要先跟緩存打交道,會(huì)影響系統(tǒng)吞吐。

    9. 如何保證MySQL數(shù)據(jù)不丟?

    MySQL這種關(guān)系型數(shù)據(jù)庫(kù),是日志先行策略(Write-Ahead Logging),只要binlog和redo log日志能保證持久化到磁盤,我們就能確保MySQL異常重啟后,數(shù)據(jù)不丟失。

    binlog日志

    binlog,又稱為二進(jìn)制日志,它會(huì)記錄數(shù)據(jù)庫(kù)執(zhí)行更改的所有操作,但是不包括查詢select等操作。一般用于恢復(fù)、復(fù)制等功能。它的格式有三種:statement、mixed和row

    • statement:每一條會(huì)修改數(shù)據(jù)的sql都會(huì)記錄到binlog中,不建議使用。
    • row:基于行的變更情況記錄,會(huì)記錄行更改前后的內(nèi)容,推薦使用
    • mixed:混合statement和row兩個(gè)模式,不建議使用。

    binlog 的寫入機(jī)制是怎樣的呢?

    事務(wù)執(zhí)行過程中,先把日志寫到 binlog cache,事務(wù)提交的時(shí)候,再把binlog cache寫到binlog文件中 。

    系統(tǒng)為每個(gè)客戶端線程分配一個(gè)binlog cache,其大小值控制參數(shù)是binlog_cache_size。如果binlog cache的值超過閥值,就會(huì)臨時(shí)持久化到磁盤。當(dāng)事務(wù)提交的時(shí)候,再將 binlog cache中完整的事務(wù)持久化到磁盤中,并且清空binlog cache。

    binlog寫文件分write和fsync兩個(gè)過程:

    • write:指把日志寫到文件系統(tǒng)的page cache,并沒有把數(shù)據(jù)持久化到磁盤,因此速度較快。
    • fsync,實(shí)際的寫盤操作,即把數(shù)據(jù)持久化到磁盤。

    write和fsync的寫入時(shí)機(jī),是由變量sync_binlog控制的:

    如果IO出現(xiàn)性能瓶頸,可以將sync_binlog設(shè)置成一個(gè)較大的值。比如設(shè)置為(100~1000)。但是,會(huì)存在數(shù)據(jù)丟失的風(fēng)險(xiǎn),當(dāng)主機(jī)異常重啟時(shí),會(huì)丟失N個(gè)最近提交的事務(wù)binlog

    redo log日志

    redo log,又稱為重做日志文件,只記錄事務(wù)對(duì)數(shù)據(jù)頁(yè)做了哪些修改,它記錄的是數(shù)據(jù)修改之后的值。redo 有三種狀態(tài)

    • 物理上是在MySQL進(jìn)程內(nèi)存中,存在redo log buffer中,
    • 物理上在文件系統(tǒng)的page cache里,寫到磁盤 (write),但是還沒有持久化(fsync)。
    • 存在hard disk,已經(jīng)持久化到磁盤。

    日志寫到redo log buffer是很快的;wirte到page cache也很快,但是持久化到磁盤的速度就慢多了。

    為了控制redo log的寫入策略,Innodb根據(jù)innodb_flush_log_at_trx_commit參數(shù)不同的取值采用不同的策略,它有三種不同的取值:

    • 設(shè)置為0時(shí),表示每次事務(wù)提交時(shí)都只是把redo log留在redo log buffer 中 ;
    • 設(shè)置為1時(shí),表示每次事務(wù)提交時(shí)都將 redo log 直接持久化到磁盤;
    • 設(shè)置為2時(shí),表示每次事務(wù)提交時(shí)都只是把redo log 寫到page cache。

    三種模式下,0的性能最好,但是不安全,MySQL進(jìn)程一旦崩潰會(huì)導(dǎo)致丟失一秒的數(shù)據(jù)。1的安全性最高,但是對(duì)性能影響最大,2的話主要由操作系統(tǒng)自行控制刷磁盤的時(shí)間,如果僅僅是MySQL宕機(jī),對(duì)數(shù)據(jù)不會(huì)產(chǎn)生影響,如果是主機(jī)異常宕機(jī)了,同樣會(huì)丟失數(shù)據(jù)。

    10. 高并發(fā)下如何設(shè)計(jì)秒殺系統(tǒng)?

    設(shè)計(jì)一個(gè)秒殺系統(tǒng),需要考慮這些問題:

    如何解決這些問題呢?

    • 頁(yè)面靜態(tài)化
    • 按鈕至灰控制
    • 服務(wù)單一職責(zé)
    • 秒殺鏈接加鹽
    • 限流
    • 分布式鎖
    • MQ異步處理
    • 限流&降級(jí)&熔斷

    頁(yè)面靜態(tài)化

    秒殺活動(dòng)的頁(yè)面,大多數(shù)內(nèi)容都是固定不變的,如商品名稱,商品圖片等等,可以對(duì)活動(dòng)頁(yè)面做靜態(tài)化處理,減少訪問服務(wù)端的請(qǐng)求。秒殺用戶會(huì)分布在全國(guó)各地,有的在上海,有的在深圳,地域相差很遠(yuǎn),網(wǎng)速也各不相同。為了讓用戶最快訪問到活動(dòng)頁(yè)面,可以使用CDN(Content Delivery Network,內(nèi)容分發(fā)網(wǎng)絡(luò))。CDN可以讓用戶就近獲取所需內(nèi)容。

    按鈕至灰控制

    秒殺活動(dòng)開始前,按鈕一般需要置灰的。只有時(shí)間到了,才能變得可以點(diǎn)擊。這是防止,秒殺用戶在時(shí)間快到的前幾秒,瘋狂請(qǐng)求服務(wù)器,然后秒殺時(shí)間點(diǎn)還沒到,服務(wù)器就自己掛了。

    服務(wù)單一職責(zé)

    我們都知道微服務(wù)設(shè)計(jì)思想,也就是把各個(gè)功能模塊拆分,功能那個(gè)類似的放一起,再用分布式的部署方式。

    如用戶登錄相關(guān)的,就設(shè)計(jì)個(gè)用戶服務(wù),訂單相關(guān)的就搞個(gè)訂單服務(wù),再到禮物相關(guān)的就搞個(gè)禮物服務(wù)等等。那么,秒殺相關(guān)的業(yè)務(wù)邏輯也可以放到一起,搞個(gè)秒殺服務(wù),單獨(dú)給它搞個(gè)秒殺數(shù)據(jù)庫(kù)。

    服務(wù)單一職責(zé)有個(gè)好處:如果秒殺沒抗住高并發(fā)的壓力,秒殺庫(kù)崩了,服務(wù)掛了,也不會(huì)影響到系統(tǒng)的其他服務(wù)。

    秒殺鏈接加鹽

    鏈接如果明文暴露的話,會(huì)有人獲取到請(qǐng)求Url,提前秒殺了。因此,需要給秒殺鏈接加鹽。可以把URL動(dòng)態(tài)化,如通過MD5加密算法加密隨機(jī)的字符串去做url。

    限流

    一般有兩種方式限流:nginx限流和redis限流。

    • 為了防止某個(gè)用戶請(qǐng)求過于頻繁,我們可以對(duì)同一用戶限流
    • 為了防止黃牛模擬幾個(gè)用戶請(qǐng)求,我們可以對(duì)某個(gè)IP進(jìn)行限流
    • 為了防止有人使用代理,每次請(qǐng)求都更換IP請(qǐng)求,我們可以對(duì)接口進(jìn)行限流
    • 為了防止瞬時(shí)過大的流量壓垮系統(tǒng),還可以使用阿里的Sentinel、Hystrix組件進(jìn)行限流。

    分布式鎖

    可以使用redis分布式鎖解決超賣問題。

    使用Redis的SET EX PX NX + 校驗(yàn)唯一隨機(jī)值,再刪除釋放鎖。

    if(jedis.set(key_resource_id, uni_request_id, "NX", "EX", 100s) == 1){ //加鎖try {do something //業(yè)務(wù)處理}catch(){}finally {//判斷是不是當(dāng)前線程加的鎖,是才釋放if (uni_request_id.equals(jedis.get(key_resource_id))) {jedis.del(lockKey); //釋放鎖}} } 復(fù)制代碼

    在這里,判斷是不是當(dāng)前線程加的鎖和釋放鎖不是一個(gè)原子操作。如果調(diào)用jedis.del()釋放鎖的時(shí)候,可能這把鎖已經(jīng)不屬于當(dāng)前客戶端,會(huì)解除他人加的鎖。

    為了更嚴(yán)謹(jǐn),一般也是用lua腳本代替。lua腳本如下:

    if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) elsereturn 0 end; 復(fù)制代碼

    MQ異步處理

    如果瞬間流量特別大,可以使用消息隊(duì)列削峰,異步處理。用戶請(qǐng)求過來的時(shí)候,先放到消息隊(duì)列,再拿出來消費(fèi)。

    限流&降級(jí)&熔斷

    • 限流,就是限制請(qǐng)求,防止過大的請(qǐng)求壓垮服務(wù)器;
    • 降級(jí),就是秒殺服務(wù)有問題了,就降級(jí)處理,不要影響別的服務(wù);
    • 熔斷,服務(wù)有問題就熔斷,一般熔斷降級(jí)是一起出現(xiàn)。

    更多大廠面試資料及答案可關(guān)注下方公公眾號(hào)【不脫發(fā)有志青年】即可免費(fèi)獲取

    ?

    總結(jié)

    以上是生活随笔為你收集整理的阿里巴巴一面 :十道经典面试题解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 精品免费一区二区 | va视频在线 | 久色成人网 | 电影《两个尼姑》免费播放 | 成人免费看片网站 | 天堂在线观看av | 色老板精品凹凸在线视频观看 | 国产有码视频 | 国产精品久久久久久久av福利 | 日日操日日操 | 手机av在线免费 | 中文字幕乱码人妻一区二区三区 | 91麻豆产精品久久久久久 | 日皮在线观看 | 国产黄色高清视频 | 欧美乱大交xxxxx潮喷l头像 | 96超碰在线 | 天堂аⅴ在线最新版在线 | 妺妺窝人体色www在线小说 | 综合热久久| 午夜日韩 | 国产91丝袜在线18 | 久久毛片网| 污污免费视频 | 国产精品毛片一区二区在线看舒淇 | 奇米在线 | 欧美在线播放一区二区 | 欧美操操操 | 黄色短视频在线播放 | 日本三级大全 | 很很干很很日 | av天天射| 黄瓜视频污在线观看 | 精品在线第一页 | 欧美色人阁| 男人天堂综合 | 亚洲乱码少妇 | 91精品国自产在线观看 | 亚洲第一看片 | 91精品国产欧美一区二区成人 | 射综合网 | 久久久一区二区三区四区 | 日韩日b | 色综合天天综合网天天狠天天 | 综合久久网 | 久久久九九九九 | 国产一区二区网站 | 国产在线观看你懂的 | 在线视频欧美一区 | 四虎成人精品在永久免费 | 久久精品视频8 | 国产欧美亚洲精品 | 30一40一50老女人毛片 | 波多野结衣毛片 | 大屁股一区二区三区 | 在线看网站 | 日日摸夜夜添狠狠添欧美 | 欧美性69| 干美女av | 国产精品人八做人人女人a级刘 | 久久丫精品忘忧草西安产品 | 欧美性生交xxxxx久久久 | 肥婆大荫蒂欧美另类 | 电影《两个尼姑》免费播放 | 日本少妇网站 | 大尺度叫床戏做爰视频 | 中文字幕日本人妻久久久免费 | 不卡的av在线播放 | 精品爆乳一区二区三区 | 麻豆影视在线免费观看 | 99色影院| 久久人妻少妇嫩草av蜜桃 | 91欧美一区二区三区 | 91干视频 | 日韩毛片在线看 | www.欧美色 | 人成免费在线视频 | 国内精品人妻无码久久久影院蜜桃 | 久艹av | 亚洲香蕉在线 | 亚洲小说在线 | 久久精品久久精品久久精品 | 韩国一区二区视频 | 欧美高清另类 | 瑟瑟视频在线观看 | 中文字幕 国产 | 美色视频 | 国产黄色一级片视频 | 亚洲瘦老头同性xxxxx | 曰韩毛片 | 欧美一区二区三区精品 | 永久精品视频 | 欧美brazzers| 激情五月综合色婷婷一区二区 | 国产日产精品一区 | 天堂在线资源库 | 成人动漫av在线 | 成年人在线视频 | 日韩在线视屏 |