1.mybatis 中 #{}和 ${}的區別是什麼?
#{}是預編譯處理,${}是字串替換;
Mybatis在處理#{}時,會將sql中的#{}替換為?號,呼叫PreparedStatement的set方法來賦值;
Mybatis在處理${}時,就是把${}替換成變數的值;
使用#{}可以有效的防止SQL注入,提高系統安全性。
2. mybatis 有幾種分頁方式?
陣列分頁
sql分頁
攔截器分頁
RowBounds分頁
3. mybatis 是否支援延遲載入?延遲載入的原理是什麼?
Mybatis僅支援association關聯物件和collection關聯集合物件的延遲載入,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置檔案中,可以配置是否啟用延遲載入lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB建立目標物件的代理物件,當呼叫目標方法時,進入攔截器方法,比如呼叫a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨傳送事先儲存好的查詢關聯B物件的sql,
把B查詢上來,然後呼叫a.setB(b),於是a的物件b屬性就有值了,接著完成a.getB().getName()方法的呼叫。這就是延遲載入的基本原理。
當然了,不光是Mybatis,幾乎所有的包括Hibernate,支援延遲載入的原理都是一樣的。
4. 說一下 mybatis 的一級快取和二級快取?
一級快取: 基於 PerpetualCache 的 HashMap 本地快取,其儲存作用域為 Session,當 Session flush 或 close 之後,該 Session 中的所有 Cache 就將清空,預設開啟一級快取。
二級快取與一級快取其機制相同,預設也是採用 PerpetualCache,HashMap 儲存,不同在於其儲存作用域為 Mapper(Namespace),並且可自定義儲存源,如 Ehcache。
預設不開啟二級快取,要開啟二級快取,使用二級快取屬性類需要實現Serializable序列化介面(可用來儲存物件的狀態),可在它的對映檔案中配置<cache/> ;
對於快取資料更新機制,當某一個作用域(一級快取 Session/二級快取Namespaces)的進行了C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。
5. 說一下 mybatis 的一級快取和二級快取?
(1)Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程式設計師自己編寫Sql語句。
(2)Mybatis直接編寫原生態sql,可以嚴格控制sql執行效能,靈活度高,非常適合對關係資料模型要求不高的軟體開發,因為這類軟體需求變化頻繁,一但需求變化要求迅速輸出成果。
但是靈活的前提是mybatis無法做到資料庫無關性,如果需要實現支援多種資料庫的軟體,則需要自定義多套sql對映檔案,工作量大。
(3)Hibernate物件/關係對映能力強,資料庫無關性好,對於關係模型要求高的軟體,如果用hibernate開發可以節省很多程式碼,提高效率。
6.rabbitmq 的使用場景有哪些?
①. 跨系統的非同步通訊,所有需要非同步互動的地方都可以使用訊息佇列。就像我們除了打電話(同步)以外,還需要發簡訊,發電子郵件(非同步)的通訊方式。
②. 多個應用之間的耦合,由於訊息是平臺無關和語言無關的,而且語義上也不再是函式呼叫,因此更適合作為多個應用之間的鬆耦合的介面。基於訊息佇列的耦合,不需要傳送方和接收方同時線上。
在企業應用整合(EAI)中,檔案傳輸,共享資料庫,訊息佇列,遠端過程呼叫都可以作為整合的方法。
③. 應用內的同步變非同步,比如訂單處理,就可以由前端應用將訂單資訊放到佇列,後端應用從佇列裡依次獲得訊息處理,高峰時的大量訂單可以積壓在佇列裡慢慢處理掉。由於同步通常意味著阻塞,而大量執行緒的阻塞會降低計算機的效能。
④. 訊息驅動的架構(EDA),系統分解為訊息佇列,和訊息製造者和訊息消費者,一個處理流程可以根據需要拆成多個階段(Stage),階段之間用佇列連線起來,前一個階段處理的結果放入佇列,後一個階段從佇列中獲取訊息繼續處理。
⑤. 應用需要更靈活的耦合方式,如釋出訂閱,比如可以指定路由規則。
⑥. 跨區域網,甚至跨城市的通訊(CDN行業),比如北京機房與廣州機房的應用程式的通訊。
#### 7.rabbitmq 有哪些重要的元件?
ConnectionFactory(連線管理器):應用程式與Rabbit之間建立連線的管理器,程式程式碼中使用。
Channel(通道):訊息推送使用的通道。
Exchange(交換器):用於接受、分配訊息。
Queue(佇列):用於儲存生產者的訊息。
RoutingKey(路由鍵):用於把生成者的資料分配到交換器上。
BindingKey(繫結鍵):用於把交換器的訊息繫結到佇列上。
8.rabbitmq 中 vhost 的作用是什麼?
vhost 可以理解為虛擬 broker ,即 mini-RabbitMQ server。其內部均含有獨立的 queue、exchange 和 binding 等,但最最重要的是,其擁有獨立的許可權系統,可以做到 vhost 範圍的使用者控制。
當然,從 RabbitMQ 的全域性角度,vhost 可以作為不同許可權隔離的手段(一個典型的例子就是不同的應用可以跑在不同的 vhost 中)。
#### 9.rabbitmq 的訊息是怎麼傳送的?
首先客戶端必須連線到 RabbitMQ 伺服器才能釋出和消費訊息,客戶端和 rabbit server 之間會建立一個 tcp 連線,一旦 tcp 開啟並通過了認證(認證就是你傳送給 rabbit 伺服器的使用者名稱和密碼),
你的客戶端和 RabbitMQ 就建立了一條 amqp 通道(channel),通道是建立在“真實” tcp 上的虛擬連線,amqp 命令都是通過通道傳送出去的,每個通道都會有一個唯一的 id,不論是釋出訊息,訂閱佇列都是通過這個通道完成的。
10.rabbitmq 怎麼保證訊息的穩定性?
提供了事務的功能。
通過將 channel 設定為 confirm(確認)模式。
11.rabbitmq 怎麼避免訊息丟失?
訊息持久化
ACK確認機制
設定叢集映象模式
訊息補償機制
12.要保證訊息持久化成功的條件有哪些?
宣告佇列必須設定持久化 durable 設定為 true.
訊息推送投遞模式必須設定持久化,deliveryMode 設定為 2(持久)。
訊息已經到達持久化交換器。
訊息已經到達持久化佇列。
以上四個條件都滿足才能保證訊息持久化成功。
13.rabbitmq 持久化有什麼缺點?
持久化的缺點就是降低了伺服器的吞吐量,因為使用的是磁碟而非記憶體儲存,從而降低了吞吐量。可儘量使用 ssd 硬碟來緩解吞吐量的問題。
14. rabbitmq 有幾種廣播型別?
三種廣播模式:
fanout: 所有bind到此exchange的queue都可以接收訊息(純廣播,繫結到RabbitMQ的接受者都能收到訊息);
direct: 通過routingKey和exchange決定的那個唯一的queue可以接收訊息;
topic:所有符合routingKey(此時可以是一個表示式)的routingKey所bind的queue可以接收訊息;
15. rabbitmq 怎麼實現延遲訊息佇列?
通過訊息過期後進入死信交換器,再由交換器轉發到延遲消費佇列,實現延遲功能;
使用 RabbitMQ-delayed-message-exchange 外掛實現延遲功能。
16.rabbitmq 叢集有什麼用?
叢集主要有以下兩個用途:
高可用:某個伺服器出現問題,整個 RabbitMQ 還可以繼續使用;
高容量:叢集可以承載更多的訊息量。
17. kafka 可以脫離 zookeeper 單獨使用嗎?為什麼?
kafka 不能脫離 zookeeper 單獨使用,因為 kafka 使用 zookeeper 管理和協調 kafka 的節點伺服器。
18. kafka 有幾種資料保留的策略?
kafka 有兩種資料儲存策略:按照過期時間保留和按照儲存的訊息大小保留。
19. kafka 同時設定了 7 天和 10G 清除資料,到第五天的時候訊息達到了 10G,這個時候 kafka 將如何處理?
這個時候 kafka 會執行資料清除工作,時間和大小不論那個滿足條件,都會清空資料。
20. kafka 同時設定了 7 天和 10G 清除資料,到第五天的時候訊息達到了 10G,這個時候 kafka 將如何處理?
cpu 效能瓶頸
磁碟讀寫瓶頸
網路瓶頸
21.zookeeper 是什麼?
zookeeper 是一個分散式的,開放原始碼的分散式應用程式協調服務,是 google chubby 的開源實現,是 hadoop 和 hbase 的重要元件。
它是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。
22.zookeeper 都有哪些功能?
叢集管理:監控節點存活狀態、執行請求等。
主節點選舉:主節點掛掉了之後可以從備用的節點開始新一輪選主,主節點選舉說的就是這個選舉的過程,使用 zookeeper 可以協助完成這個過程。
分散式鎖:zookeeper 提供兩種鎖:獨佔鎖、共享鎖。獨佔鎖即一次只能有一個執行緒使用資源,共享鎖是讀鎖共享,讀寫互斥,即可以有多線執行緒同時讀同一個資源,如果要使用寫鎖也只能有一個執行緒使用。zookeeper可以對分散式鎖進行控制。
命名服務:在分散式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等資訊。
23.zookeeper 有幾種部署模式?
zookeeper 有三種部署模式:
單機部署:一臺叢集上執行;
叢集部署:多臺叢集執行;
偽叢集部署:一臺叢集啟動多個 zookeeper 例項執行。
24.zookeeper 怎麼保證主從節點的狀態同步?
zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 zab 協議。 zab 協議有兩種模式,分別是恢復模式(選主)和廣播模式(同步)。
當服務啟動或者在領導者崩潰後,zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 server 具有相同的系統狀態。
25.說一下 zookeeper 的通知機制?
客戶端端會對某個 znode 建立一個 watcher 事件,當該 znode 發生變化時,這些客戶端會收到 zookeeper 的通知,然後客戶端可以根據 znode 變化來做出業務上的改變。
26.資料庫的三正規化是什麼?
第一正規化:強調的是列的原子性,即資料庫表的每一列都是不可分割的原子資料項。
第二正規化:要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性。
第三正規化:任何非主屬性不依賴於其它非主屬性。
27.說一下 ACID 是什麼?
Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,
就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。
Consistency(一致性):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設約束、觸發器、級聯回滾等。
Isolation(隔離性):資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。
事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。
Durability(永續性):事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。
28.mysql 索引是怎麼實現的?
索引是滿足某種特定查詢演算法的資料結構,而這些資料結構會以某種方式指向資料,從而實現高效查詢資料。
具體來說 MySQL 中的索引,不同的資料引擎實現有所不同,但目前主流的資料庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜尋效率,
可以到達二分法的效能,找到資料區域之後就找到了完整的資料結構了,所有索引的效能也是更好的。
29.mysql 索引是怎麼實現的?
MySQL 的事務隔離是在 MySQL. ini 配置檔案裡新增的,在檔案的最後新增:transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
READ-UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀)。
READ-COMMITTED:提交讀,一個事務提交後才能被其他事務讀取到(會造成幻讀、不可重複讀)。
REPEATABLE-READ:可重複讀,預設級別,保證多次讀取同一個資料時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的資料(會造成幻讀)。
SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。
髒讀 :表示一個事務能夠讀取另一個事務中還未提交的資料。比如,某個事務嘗試插入記錄 A,此時該事務還未提交,然後另一個事務嘗試讀取到了記錄 A。
不可重複讀 :是指在一個事務內,多次讀同一資料。
幻讀 :指同一個事務內多次查詢返回的結果集不一樣。比如同一個事務 A 第一次查詢時候有 n 條記錄,但是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。
發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裡面的資料,同一個記錄的資料內容被修改了,所有資料行的記錄就變多或者變少了。
30. 說一下 mysql 常用的引擎?
InnoDB 引擎:InnoDB 引擎提供了對資料庫 acid 事務的支援,並且還提供了行級鎖和外來鍵的約束,它的設計的目標就是處理大資料容量的資料庫系統。MySQL 執行的時候,InnoDB 會在記憶體中建立緩衝池,用於緩衝資料和索引。
但是該引擎是不支援全文搜尋,同時啟動也比較的慢,它是不會儲存表的行數的,所以當進行 select count(*) from table 指令的時候,需要進行掃描全表。由於鎖的粒度小,寫操作是不會鎖定全表的,所以在併發度較高的場景下使用會提升效率的。
MyIASM 引擎:MySQL 的預設引擎,但不提供事務的支援,也不支援行級鎖和外來鍵。因此當執行插入和更新語句時,即執行寫操作的時候需要鎖定這個表,所以會導致效率會降低。不過和 InnoDB 不同的是,
MyIASM 引擎是儲存了表的行數,於是當進行 select count(*) from table 語句時,可以直接的讀取已經儲存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時,並且不需要事務的支援的,可以將 MyIASM 作為資料庫引擎的首選。
31. 說一下 mysql 的行鎖和表鎖?
MyISAM 只支援表鎖,InnoDB 支援表鎖和行鎖,預設為行鎖。
表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的概率最高,併發量最低。
行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的概率小,併發度最高。
32. 說一下樂觀鎖和悲觀鎖?
樂觀鎖:每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個資料。
悲觀鎖:每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻止,直到這個鎖被釋放。
資料庫的樂觀鎖需要自己實現,在表裡面新增一個 version 欄位,每次修改成功值加 1,這樣每次修改的時候先對比一下,自己擁有的 version 和資料庫現在的 version 是否一致,
如果不一致就不修改,這樣就實現了樂觀鎖。
33. redis 是什麼?都有哪些使用場景?
Redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。
Redis 使用場景:
資料高併發的讀寫
海量資料的讀寫
對擴充套件性要求高的資料
34. redis 和 memecache 有什麼區別?
memcached所有的值均是簡單的字串,redis作為其替代者,支援更為豐富的資料型別
redis的速度比memcached快很多
redis可以持久化其資料
35.redis 為什麼是單執行緒的?
因為 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器記憶體或者網路頻寬。既然單執行緒容易實現,而且 cpu 又不會成為瓶頸,那就順理成章地採用單執行緒的方案了。
關於 Redis 的效能,官方網站也有,普通筆記本輕鬆處理每秒幾十萬的請求。
而且單執行緒並不代表就慢 nginx 和 nodejs 也都是高效能單執行緒的代表。
36.什麼是快取穿透?怎麼解決?
快取穿透:指查詢一個一定不存在的資料,由於快取是不命中時需要從資料庫查詢,查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,造成快取穿透。
解決方案:最簡單粗暴的方法如果一個查詢返回的資料為空(不管是資料不存在,還是系統故障),我們就把這個空結果進行快取,但它的過期時間會很短,最長不超過五分鐘。
37.redis 持久化有幾種方式?
Redis 的持久化有兩種方式,或者說有兩種策略:
RDB(Redis Database):指定的時間間隔能對你的資料進行快照儲存。
AOF(Append Only File):每一個收到的寫命令都通過write函式追加到檔案中。
38.redis 怎麼實現分散式鎖?
Redis 分散式鎖其實就是在系統裡面佔一個“坑”,其他程式也要佔“坑”的時候,佔用成功了就可以繼續執行,失敗了就只能放棄或稍後重試。
佔坑一般使用 setnx(set if not exists)指令,只允許被一個程式佔有,使用完呼叫 del 釋放鎖。
39.redis 淘汰策略有哪些?
volatile-lru:從已設定過期時間的資料集(server. db[i]. expires)中挑選最近最少使用的資料淘汰。
volatile-ttl:從已設定過期時間的資料集(server. db[i]. expires)中挑選將要過期的資料淘汰。
volatile-random:從已設定過期時間的資料集(server. db[i]. expires)中任意選擇資料淘汰。
allkeys-lru:從資料集(server. db[i]. dict)中挑選最近最少使用的資料淘汰。
allkeys-random:從資料集(server. db[i]. dict)中任意選擇資料淘汰。
no-enviction(驅逐):禁止驅逐資料。
40.說一下 jvm 的主要組成部分?及其作用?
類載入器(ClassLoader)
執行時資料區(Runtime Data Area)
執行引擎(Execution Engine)
本地庫介面(Native Interface)
元件的作用: 首先通過類載入器(ClassLoader)會把 Java 程式碼轉換成位元組碼,執行時資料區(Runtime Data Area)再把位元組碼載入到記憶體中,而位元組碼檔案只是 JVM 的一套指令集規範,
並不能直接交個底層作業系統去執行,因此需要特定的命令解析器執行引擎(Execution Engine),將位元組碼翻譯成底層系統指令,
再交由 CPU 去執行,而這個過程中需要呼叫其他語言的本地庫介面(Native Interface)來實現整個程式的功能。
41.說一下堆疊的區別?
1. 棧記憶體儲存的是區域性變數而堆記憶體儲存的是實體;
2. 棧記憶體的更新速度要快於堆記憶體,因為區域性變數的生命週期很短;
3. 棧記憶體存放的變數生命週期一旦結束就會被釋放,而堆記憶體存放的實體會被垃圾回收機制不定時的回收。
42.佇列和棧是什麼?有什麼區別?
佇列和棧都是被用來預儲存資料的。
佇列允許先進先出檢索元素,但也有例外的情況,Deque 介面允許從兩端檢索元素。
棧和佇列很相似,但它執行對元素進行後進先出進行檢索。
43. 什麼是雙親委派模型?
在介紹雙親委派模型之前先說下類載入器。對於任意一個類,都需要由載入它的類載入器和這個類本身一同確立在 JVM 中的唯一性,每一個類載入器,都有一個獨立的類名稱空間。
類載入器就是根據指定全限定名稱將 class 檔案載入到 JVM 記憶體,然後再轉化為 class 物件。
類載入器分類:
啟動類載入器(Bootstrap ClassLoader),是虛擬機器自身的一部分,用來載入Java_HOME/lib/目錄中的,或者被 -Xbootclasspath 引數所指定的路徑中並且被虛擬機器識別的類庫;
其他類載入器:
擴充套件類載入器(Extension ClassLoader):負責載入<java_home style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; text-size-adjust: none; -webkit-font-smoothing: antialiased; outline: 0px !important;">\lib\ext目錄或Java. ext. dirs系統變數指定的路徑中的所有類庫;</java_home>
應用程式類載入器(Application ClassLoader)。負責載入使用者類路徑(classpath)上的指定類庫,我們可以直接使用這個類載入器。一般情況,如果我們沒有自定義類載入器預設就是用這個載入器。
雙親委派模型:如果一個類載入器收到了類載入的請求,它首先不會自己去載入這個類,而是把這個請求委派給父類載入器去完成,每一層的類載入器都是如此,這樣所有的載入請求都會被傳送到頂層的啟動類載入器中,
只有當父載入無法完成載入請求(它的搜尋範圍中沒找到所需的類)時,子載入器才會嘗試去載入類。
44. 說一下類載入的執行過程?
類載入分為以下 5 個步驟:
載入:根據查詢路徑找到相應的 class 檔案然後匯入;
檢查:檢查載入的 class 檔案的正確性;
準備:給類中的靜態變數分配記憶體空間;
解析:虛擬機器將常量池中的符號引用替換成直接引用的過程。符號引用就理解為一個標示,而在直接引用直接指向記憶體中的地址;
初始化:對靜態變數和靜態程式碼塊執行初始化工作。
45. 說一下 jvm 有哪些垃圾回收演算法?
標記-清除演算法
標記-整理演算法
複製演算法
分代演算法
46. 說一下 jvm 有哪些垃圾回收器?
Serial:最早的單執行緒序列垃圾回收器。
Serial Old:Serial 垃圾回收器的老年版本,同樣也是單執行緒的,可以作為 CMS 垃圾回收器的備選預案。
ParNew:是 Serial 的多執行緒版本。
Parallel 和 ParNew 收集器類似是多執行緒的,但 Parallel 是吞吐量優先的收集器,可以犧牲等待時間換取系統的吞吐量。
Parallel Old 是 Parallel 老生代版本,Parallel 使用的是複製的記憶體回收演算法,Parallel Old 使用的是標記-整理的記憶體回收演算法。
CMS:一種以獲得最短停頓時間為目標的收集器,非常適用 B/S 系統。
G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 以後的預設 GC 選項。