設計模式(面向對象)有七大原則,分別是: 1.開放-封閉原則 2.單一職責原則 3.依賴倒轉原則 4.迪米特法則(也稱爲最小知識原則) 5.接口隔離原則 6.合成/聚合複用原則 7.里氏代換原則 詳情參考 :http://www.javashuo.com/article/p-dgyfepja-dx.htmlhtml
B-Tree是知足條件: d>=2,即B-Tree的度; h爲B-Tree的高; 每一個非葉子結點由n-1個key和n個指針組成,其中djava
A和B選項的區別在於第3步和第4步,B中當i=999時,先執行步驟3,則i=i+2=1001,接着第4步s=s+1001,如此看來這種三、4步的寫法求得的S會多加了一個i=1001.mysql
1)編譯器負責把java文件編譯爲class文件, 2)JAVA虛擬機(JVM)對class文件,進行加載、校驗、執行, 故本題的答案爲C。redis
補圖:算法
無sql
略數據庫
選項B 應該是 釋放鎖就是刪除 key。編程
這個場景是假設有一個 redis cluster,有 5 個 redis master 實例。而後執行以下步驟獲取一把鎖:設計模式
獲取當前時間戳,單位是毫秒; 跟上面相似,輪流嘗試在每一個 master 節點上建立鎖,過時時間較短,通常就幾十毫秒; 嘗試在大多數節點上創建一個鎖,好比 5 個節點就要求是 3 個節點 n / 2 + 1; 客戶端計算創建好鎖的時間,若是創建鎖的時間小於超時時間,就算創建成功了; 要是鎖創建失敗了,那麼就依次以前創建過的鎖刪除; 只要別人創建了一把分佈式鎖,你就得不斷輪詢去嘗試獲取鎖。緩存
髒讀 : 髒讀就是指當一個事務正在訪問數據,而且對數據進行了修改,而這種修改尚未提交到數據庫中,這時,另一個事務也訪問這個數據,而後使用了這個數據。 不可重複讀 : 是指在一個事務內,屢次讀同一數據。在這個事務尚未結束時,另一個事務再修改數據。那麼第一個事務兩次讀到的的數據多是不同的,所以稱爲是不可重複讀。 幻讀: 當某事物正在執行插入或刪除操做同時,第二個事物也在操做此表的數據,就會顯示有一行還未存在的數據,就像發生了幻覺同樣。
解決辦法:若是在操做事務完成數據處理以前,任何其餘事務都不能夠操做此數據,則可避免該問題。
Java虛擬機管理的內存包括幾個運行時數據內存:方法區、虛擬機棧、本地方法棧、堆、程序計數器,其中方法區和堆是由線程共享的數據區,其餘幾個是線程隔離的數據區
redis 內存淘汰機制有如下幾個:
noeviction: 當內存不足以容納新寫入數據時,新寫入操做會報錯,這個通常沒人用吧,實在是太噁心了。 allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key(這個是最經常使用的)。 allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個 key,這個通常沒人用吧,爲啥要隨機,確定是把最近最少使用的 key 給幹掉啊。 volatile-lru:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的 key(這個通常不太合適)。 volatile-random:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個 key。 volatile-ttl:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的 key 優先移除。
ActiveMQ 基於 Java 開發的, RabbitMQ 是基於 erlang 開發的。 因此選項A 錯誤。 B、C、D都正確。
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
單機吞吐量 | 萬級,比 RocketMQ、Kafka 低一個數量級 | 同 ActiveMQ | 10 萬級,支撐高吞吐 | 10 萬級,高吞吐,通常配合大數據類的系統來進行實時數據計算、日誌採集等場景 |
topic 數量對吞吐量的影響 | topic 能夠達到幾百/幾千的級別,吞吐量會有較小幅度的降低,這是 RocketMQ 的一大優點,在同等機器下,能夠支撐大量的 topic | topic 從幾十到幾百個時候,吞吐量會大幅度降低,在同等機器下,Kafka 儘可能保證 topic 數量不要過多,若是要支撐大規模的 topic,須要增長更多的機器資源 | ||
時效性 | ms 級 | 微秒級,這是 RabbitMQ 的一大特色,延遲最低 | ms 級 | 延遲在 ms 級之內 |
可用性 | 高,基於主從架構實現高可用 | 同 ActiveMQ | 很是高,分佈式架構 | 很是高,分佈式,一個數據多個副本,少數機器宕機,不會丟失數據,不會致使不可用 |
消息可靠性 | 有較低的機率丟失數據 | 基本不丟 | 通過參數優化配置,能夠作到 0 丟失 | 同 RocketMQ |
功能支持 | MQ 領域的功能極其完備 | 基於 erlang 開發,併發能力很強,性能極好,延時很低 | MQ 功能較爲完善,仍是分佈式的,擴展性好 | 功能較爲簡單,主要支持簡單的 MQ 功能,在大數據領域的實時計算以及日誌採集被大規模使用 |
分佈式服務接口,只靠數據庫的事務是保證不了冪等性的。 選項D錯誤。
所謂冪等性,就是說一個接口,屢次發起同一個請求,你這個接口得保證結果是準確的,好比不能多扣款、不能多插入一條數據、不能將統計值多加了 1。這就是冪等性。
其實保證冪等性主要是三點:
要求是支付一個訂單,必須插入一條支付流水,order_id 建一個惟一鍵 unique key。你在支付一個訂單以前,先插入一條支付流水,order_id 就已經進去了。你就能夠寫一個標識到 redis 裏面去,set order_id payed,下一次重複請求過來了,先查 redis 的 order_id 對應的 value,若是是 payed 就說明已經支付過了,你就別重複支付了。
緩存雪崩的事前事中過後的解決方案以下。
Cache Aside Pattern 最經典的緩存+數據庫讀寫的模式,就是 Cache Aside Pattern。
讀的時候,先讀緩存,緩存沒有的話,就讀數據庫,而後取出數據後放入緩存,同時返回響應。 更新的時候,先更新數據庫,而後再刪除緩存。 爲何是刪除緩存,而不是更新緩存?
緣由很簡單,不少時候,在複雜點的緩存場景,緩存不僅僅是數據庫中直接取出來的值。
好比可能更新了某個表的一個字段,而後其對應的緩存,是須要查詢另外兩個表的數據並進行運算,才能計算出緩存最新的值的。
另外更新緩存的代價有時候是很高的。是否是說,每次修改數據庫的時候,都必定要將其對應的緩存更新一份?也許有的場景是這樣,可是對於比較複雜的緩存數據計算的場景,就不是這樣了。若是你頻繁修改一個緩存涉及的多個表,緩存也頻繁更新。可是問題在於,這個緩存到底會不會被頻繁訪問到?
舉個栗子,一個緩存涉及的表的字段,在 1 分鐘內就修改了 20 次,或者是 100 次,那麼緩存更新 20 次、100 次;可是這個緩存在 1 分鐘內只被讀取了 1 次,有大量的冷數據。實際上,若是你只是刪除緩存的話,那麼在 1 分鐘內,這個緩存不過就從新計算一次而已,開銷大幅度下降。用到緩存纔去算緩存。
其實刪除緩存,而不是更新緩存,就是一個 lazy 計算的思想,不要每次都從新作複雜的計算,無論它會不會用到,而是讓它到須要被使用的時候再從新計算。像 mybatis,hibernate,都有懶加載思想。查詢一個部門,部門帶了一個員工的 list,沒有必要說每次查詢部門,都裏面的 1000 個員工的數據也同時查出來啊。80% 的狀況,查這個部門,就只是要訪問這個部門的信息就能夠了。先查部門,同時要訪問裏面的員工,那麼這個時候只有在你要訪問裏面的員工的時候,纔會去數據庫裏面查詢 1000 個員工。
全對,IO和NIO的主要對好比下:
IO | NIO |
---|---|
面向流 | 面向緩衝 |
阻塞IO | 非阻塞IO |
無 | 選擇器 |