mybatis select语句会默认带排序吗_10月阿里最新38道Java面试题解析(MyBatis+消息队列+Redis)...
MyBatis面試題
一、談談你對 MyBatis 的理解?
1. Mybatis是一個半ORM(對象關系映射)框架,它內部封裝了 JDBC,開發時只需要關注 SQL 語句本身,不需要花費精力去處理加載驅動、創建連接、創建 Statement 等繁雜的過程。程序員直接編寫原生態 SQL,可以嚴格控制 SQL 執行性能,靈活度高。
2. MyBatis 可以使用 XML 或注解來配置和映射原生信息,將 POJO 映射成數據庫中的記錄,避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。
3. 通過 XML 文件或注解的方式將要執行的各種 Statement 配置起來,并通過 Java 對象和 Statement 中 SQL 的動態參數進行映射生成最終執行的 SQL 語句,最后由 MyBatis 框架執行 SQL并將結果映射為 Java 對象并返回。(從執行 SQL到返回 Result 的過程)。
二、MyBaits 的優缺點有哪些?
§?優點:
1. 基于 SQL 語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影響,SQL 寫在 XML 里,解除 SQL 與程序代碼的耦合,便于統一管理;提供XML標簽,支持編寫動態 SQL 語句,并可重用;
2. 與 JDBC 相比,減少了代碼量,消除了 JDBC 大量冗余的代碼,不需要手動開關連接;
3. 很好的與各種數據庫兼容(因為 MyBatis 使用 JDBC 來連接數據庫,所以只要 JDBC 支持的數據庫 MyBatis 都支持);
4. 提供映射標簽,支持對象與數據庫的 ORM 字段關系映射;提供對象關系映射標簽,支持對象關系組件維護。
§?缺點:
1. SQL 語句的編寫工作量較大,尤其當字段多、關聯表多時,對開發人員編寫 SQL 語句的功底有一定要求;
2. SQL 語句依賴于數據庫,導致數據庫移植性差,不能隨意更換數據庫。
三、MyBatis 與 Hibernate 有哪些不同?
1. MyBatis 和 Hibernate不同,它不完全是一個 ORM 框架,因為 MyBatis 需要程序員自己編寫 SQL 語句;Hibernate 對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件,如果用 Hibernate 開發可以節省很多代碼,提高效率;
2. MyBatis 直接編寫原生態 SQL,可以嚴格控制 SQL 執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,因為這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是 MyBatis 無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件,則需要自定義多套 SQL 映射文件,工作量大。
四、MyBatis 中 #{} 和 ${}的區別是什么?
§?#{} 是預編譯處理,${} 是字符串替換
1. Mybatis 在處理 #{} 時,會將 SQL 中的 #{} 替換為 ? 號,調用 PreparedStatement 的 set 方法來賦值;使用 #{} 可以有效的防止 SQL 注入,提高系統安全性;2. MyBatis 在處理 ${} 時,就是把 ${} 替換成變量的值。
五、MyBatis 是如何進行分頁的?分頁插件的原理是什么?
MyBatis 使用 RowBounds 對象進行分頁,它是針對 ResultSet 結果集執行的內存分頁,而非物理分頁??梢栽?SQL 內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。
分頁插件的基本原理是使用 MyBatis 提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的 SQL,然后重寫 SQL,根據 dialect 方言,添加對應的物理分頁語句和物理分頁參數。
六、MyBatis 有幾種分頁方式?
1. 數組分頁
2. SQL 分頁
3. 攔截器分頁
4. RowBounds 分頁
七、MyBatis 邏輯分頁和物理分頁的區別是什么?
1. 物理分頁速度上并不一定快于邏輯分頁,邏輯分頁速度上也并不一定快于物理分頁。
2. 物理分頁總是優于邏輯分頁:沒有必要將屬于數據庫端的壓力加到應用端來,就算速度上存在優勢,然而其它性能上的優點足以彌補這個缺點。
八、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 的一級緩存和二級緩存?
一級緩存:基于 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空,默認打開一級緩存;
二級緩存:與一級緩存其機制相同,默認也是采用 PerpetualCache,HashMap 存儲,不同在于其存儲作用域為 Mapper(Namespace),并且可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啟二級緩存,使用二級緩存屬性類需要實現 Serializable 序列化接口(可用來保存對象的狀態),可在它的映射文件中配置 ;
對于緩存數據更新機制,當某一個作用域(一級緩存 Session / 二級緩存 Namespaces)的進行了 C/U/D 操作后,默認該作用域下所有 select 中的緩存將被 clear。
十、Mybatis 有哪些執行器(Executor)?
Mybatis 有 3 種基本的執行器(Executor):
1. SimpleExecutor:每執行一次 update 或 select,就開啟一個 Statement 對象,用完立刻關閉 Statement 對象;
2. ReuseExecutor:執行 update 或 select,以 SQL 作為 key 查找 Statement 對象,存在就使用,不存在就創建,用完后,不關閉 Statement 對象,而是放置于 Map 內,供下一次使用。簡言之,就是重復使用 Statement 對象;
3. BatchExecutor:執行 update(沒有 select,JDBC 批處理不支持select),將所有 SQL 都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個 Statement 對象,每個 Statement對 象都是 addBatch() 完畢后,等待逐一執行 executeBatch() 批處理。與 JDBC 批處理相同。
十一、MyBatis 動態 SQL 是做什么的?都有哪些動態 SQL?能簡述一下動態 SQL的執行原理不?
1. MyBatis 動態 SQL 可以讓我們在 XML 映射文件內,以標簽的形式編寫動態 SQL,完成邏輯判斷和動態拼接 SQL 的功能;
2. MyBatis 提供了 9 種動態 SQL 標簽:trim、where、set、foreach、if、choose、when、otherwise、bind;
3. 執行原理:使用 OGNL 從 SQL 參數對象中計算表達式的值,根據表達式的值動態拼接 SQL,以此來完成動態 SQL 的功能。
消息隊列面試題
一、消息隊列的基本作用?消息隊列的主要作用是:解耦、異步、削峰。- 解耦
- 異步
- 削峰
- 優點
- 缺點
- RabbitMQ:鏡像集群模式
- Kafka:partition 和 replica 機制
四、如何保證消息不被重復消費?或者說,如何保證消息消費的冪等性?
要保證消息不被重復消費,其實就是要保證消息消費時的冪等性。冪等性:無論你重復請求多少次,得到的結果都是一樣的。例如:一條數據重復出現兩次,數據庫里就只有一條數據,這就保證了系統的冪等性。- 那么如何保證冪等性呢?
五、如何保證消息的可靠性傳輸?或者說,如何處理消息丟失的問題?
- RabbitMQ
- Kafka
六、如何保證消息的順序性?
RabbitMQ
- Kafka
1. 先修復 consumer 的問題,確保其恢復消費速度,然后將現有 consumer 都停掉;
2. 新建一個 topic,partition 是原來的 10 倍,臨時建立好原先 10 倍的 queue 數量;3. 然后寫一個臨時的分發數據的 consumer 程序,這個程序部署上去消費積壓的數據,消費之后不做耗時的處理,直接均勻輪詢寫入臨時建立好的 10 倍數量的 queue;4. 接著臨時征用 10 倍的機器來部署 consumer,每一批 consumer 消費一個臨時 queue 的數據。這種做法相當于是臨時將 queue 資源和 consumer 資源擴大 10 倍,以正常的 10 倍速度來消費數據;5. 等快速消費完積壓數據之后,得恢復原先部署的架構,重新用原先的 consumer 機器來消費消息。八、MQ 中的消息過期失效了怎么辦?
假設你用的是 RabbitMQ,RabbtiMQ 是可以設置過期時間的,也就是 TTL。如果消息在 Queue 中積壓超過一定的時間就會被 RabbitMQ 給清理掉,這個數據就沒了。這時的問題就不是數據會大量積壓在 MQ 里,而是大量的數據會直接搞丟。這個情況下,就不是說要增加 Consumer 消費積壓的消息,因為實際上沒啥積壓,而是丟了大量的消息。我們可以采取一個方案,就是批量重導。就是大量積壓的時候,直接丟棄數據了,然后等過了高峰期以后開始寫程序,將丟失的那批數據一點一點的查出來,然后重新灌入 MQ 里面去,把丟的數據給補回來。九、RabbitMQ 有哪些重要的角色?RabbitMQ 中重要的角色有:生產者、消費者和代理。1. 生產者:消息的創建者,負責創建和推送數據到消息服務器;2. 消費者:消息的接收方,用于處理數據和確認消息;3. 代理:就是 RabbitMQ 本身,用于扮演“快遞”的角色,本身不生產消息,只是扮演“快遞”的角色。十、RabbitMQ 有哪些重要的組件?
1. ConnectionFactory(連接管理器):應用程序與 rabbit 之間建立連接的管理器,程序代碼中使用;2. Channel(信道):消息推送使用的通道;3. Exchange(交換器):用于接受、分配消息;4. Queue(隊列):用于存儲生產者的消息;5. RoutingKey(路由鍵):用于把生成者的數據分配到交換器上;6. BindingKey(綁定鍵):用于把交換器的消息綁定到隊列上。十一、RabbitMQ 有幾種廣播類型?
RabbitMQ 有三種廣播模式:fanout、direct、topic。1. fanout:所有 bind 到此 exchange 的 queue 都可以接收消息;很像子網廣播,每臺子網內的主機都獲得了一份復制的消息。fanout 交換機轉發消息是最快的。?2. direct:通過 routingKey 和 exchange 中的 bindingKey 決定的那個唯一的 queue 可以接收消息;3. topic:所有符合 routingKey 所 bind 的 queue 可以接收消息。十二、Kafka 可以脫離 zookeeper 單獨使用嗎?為什么?Kafka 不能脫離 zookeeper 單獨使用,因為 Kafka 使用 zookeeper 管理和協調 Kafka 的節點服務器。
十三、Kafka 有幾種數據保留的策略?Kafka 有兩種數據保存策略:按照過期時間保留和按照存儲的消息大小保留。十四、Kafka 的分區策略有哪些?
所謂分區策略就是決定生產者將消息發送到哪個分區的算法。
1. 輪詢策略:默認的分區策略,非常優秀的負載均衡表現,它總是能保證消息最大限度地被平均分配到所有分區上;
2. 隨機策略:實現隨機策略版的 partition 方法;
3. 按消息鍵保序策略:也稱 Key-Ordering 策略,可以保證同一個 Key 的所有消息都進入到相同的分區里,由于每個分區下的消息處理是有順序的,所以稱之為消息鍵保序策略;4. 自定義分區策略:在編寫生產者程序時,你可以編寫一個具體的類實現org.apache.kafka.clients.producer.Partitioner 接口。這個接口也很簡單,只定義了兩個方法:partition() 和 close(),通常只用實現 partition() 方法即可。同時還需要設置 partitioner.class 參數為你自己實現類的全限定類名。
Redis面試題
一、談下你對 Redis 的了解?
Redis(全稱:Remote Dictionary Server 遠程字典服務)是一個開源的使用 ANSI C 語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value 數據庫,并提供多種語言的 API。
二、Redis 一般都有哪些使用場景?- Redis 適合的場景
- Redis?不適合的場景
- 1. string 字符串
- 2. Hash(哈希)
在 Redis中哈希類型是指鍵本身是一種鍵值對結構,如 value={{field1,value1},......{fieldN,valueN}}??
使用場景:哈希結構相對于字符串序列化緩存信息更加直觀,并且在更新操作上更加便捷。所以常常用于用戶信息等管理,但是哈希類型和關系型數據庫有所不同,哈希類型是稀疏的,而關系型數據庫是完全結構化的,關系型數據庫可以做復雜的關系查詢,而 Redis 去模擬關系型復雜查詢開發困難且維護成本高。3. List(列表)
- 4.?Set(集合)
- 5. zset(sorted set:有序集合)
官方解釋:
https://blog.csdn.net/xlgen157387/article/details/79470556
官方 FAQ 表示,因為 Redis 是基于內存的操作,CPU 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器內存的大小或者網絡帶寬。既然單線程容易實現,而且 CPU 不會成為瓶頸,那就順理成章地采用單線程的方案了,畢竟采用多線程會有很多麻煩。六、Redis 為什么這么快?1. 完全基于內存,絕大部分請求是純粹的內存操作,非??焖?#xff1b;2. 數據結構簡單,對數據操作也簡單;3. 采用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的性能消耗;4. 使用多路 I/O 復用模型,非阻塞 IO。七、什么是緩存穿透?怎么解決?緩存穿透是指查詢一個一定不存在的數據,由于緩存是不命中時需要從數據庫查詢,查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成緩存穿透。
解決辦法:
1. 空值做了緩存,意味著緩存中存了更多的鍵,需要更多的內存空間,比較有效的方法是針對這類數據設置一個較短的過期時間,讓其自動剔除。
2. 緩存和存儲的數據會有一段時間窗口的不一致,可能會對業務有一定影響。例如:過期時間設置為 5分鐘,如果此時存儲添加了這個數據,那此段時間就會出現緩存和存儲數據的不一致,此時可以利用消息系統或者其他方式清除掉緩存層中的空對象。
2. 布隆過濾器:將所有可能存在的數據哈希到一個足夠大的 bitmap 中,一個一定不存在的數據會被這個 bitmap 攔截掉,從而避免了對底層存儲系統的查詢壓力。
八、什么是緩存雪崩?該如何解決?如果緩存集中在一段時間內失效,發生大量的緩存穿透,所有的查詢都落在數據庫上,造成了緩存雪崩。- 解決辦法:
十、Redis 持久化有幾種方式?
持久化就是把內存的數據寫到磁盤中去,防止服務宕機了內存數據丟失。Redis 提供了兩種持久化方式:RDB(默認) 和 AOF。
- RDB
- AOF
WRITE:根據條件,將 aof_buf 中的緩存寫入到 AOF 文件;
SAVE:根據條件,調用 fsync 或 fdatasync 函數,將 AOF 文件保存到磁盤中。
- RDB 和 AOF 的區別:
十一、Redis 怎么實現分布式鎖?
Redis 為單線程模式,采用隊列模式將并發訪問變成串行訪問,且多客戶端對 Redis 的連接并不存在競爭關系。Redis 中可以使用 SETNX 命令實現分布式鎖。一般使用 setnx(set if not exists) 指令,只允許被一個程序占有,使用完調用 del 釋放鎖。
十二、Redis 淘汰策略有哪些?
1. volatile-lru:從已設置過期時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰;2. volatile-ttl:從已設置過期時間的數據集(server. db[i]. expires)中挑選將要過期的數據淘汰。3. volatile-random:從已設置過期時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。4. allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。5. allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。6、no-enviction(驅逐):禁止驅逐數據。十三、Redis 常見性能問題和解決方案?
1. Master 最好不要做任何持久化工作,如 RDB 內存快照和 AOF 日志文件。如果數據比較重要,某個 Slave 開啟 AOF 備份數據,策略設置為每秒同步一次;2. 為了主從復制的速度和連接的穩定性, Master 和 Slave 最好在同一個局域網內;3. 主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master?你在看嗎?
總結
以上是生活随笔為你收集整理的mybatis select语句会默认带排序吗_10月阿里最新38道Java面试题解析(MyBatis+消息队列+Redis)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 香爆了!5G版“P50” 鼎桥TD Te
- 下一篇: λ表达式_Java 8新特性:学习如何使