1. 程式人生 > >Java相關面試題總結+答案(九)

Java相關面試題總結+答案(九)

高速緩存 serial 串行化 jedis 5.1 ria 最大 配置文件 ack

【MySQL】


164. 數據庫的三範式是什麽?

  • 第一範式:強調的是列的原子性,即數據庫表的每一列都是不可分割的原子數據項。
  • 第二範式:屬性完全依賴於主鍵(滿足第一範式的前提下),即任意一個字段只依賴於表中的同一個字段。
  • 第三範式:任何非主屬性不依賴於其它非主屬性(滿足第二範式的前提下)。即不存在傳遞依賴。

165. 一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啟 MySQL 數據庫,又插入了一條數據,此時 id 是幾?

  • 數據庫引擎如果是 MyISAM ,那 id 就是 8。
  • 數據庫引擎如果是 InnoDB,那 id 就是 6。

  InnoDB 表只會把自增主鍵的最大 id 記錄在內存中,所以重啟之後會導致最大 id 丟失。

166. 如何獲取當前數據庫版本?

  使用 select version() 獲取當前 MySQL 數據庫版本。

167. 說一下 ACID 是什麽?

  • Atomicity(原子性):一個事務(transaction)中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。即,事務不可分割、不可約簡。
  • Consistency(一致性):在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設約束、觸發器、級聯回滾等。
  • Isolation(隔離性):數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
  • Durability(持久性):事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

168. char 和 varchar 的區別是什麽?

  • char(n) :固定長度類型,比如訂閱 char(10),當你輸入"abc"三個字符的時候,它們占的空間還是 10 個字節,其他 7 個是空字節。

  char 優點:效率高;缺點:占用空間;適用場景:存儲密碼的 md5 值,固定長度的,使用 char 非常合適。

  • varchar(n) :可變長度,存儲的值是每個值占用的字節再加上一個用來記錄其長度的字節的長度。

  所以,從空間上考慮 varcahr 比較合適;從效率上考慮 char 比較合適,二者使用需要權衡。

169. float 和 double 的區別是什麽?

  • float 最多可以存儲 8 位的十進制數,並在內存中占 4 字節。
  • double 最可可以存儲 16 位的十進制數,並在內存中占 8 字節。

170. MySQL 的內連接、左連接、右連接有什麽區別?

內連接關鍵字:inner join;左連接:left join;右連接:right join。

內連接是把匹配的關聯數據顯示出來;左連接是左邊的表全部顯示出來,右邊的表顯示出符合條件的數據;右連接正好相反。

171. MySQL 索引是怎麽實現的?

索引是滿足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。

具體來說 MySQL 中的索引,不同的數據引擎實現有所不同,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,可以到達二分法的性能,找到數據區域之後就找到了完整的數據結構了,所有索引的性能也是更好的。

172. 怎麽驗證 MySQL 的索引是否滿足需求?

使用 explain 查看 SQL 是如何執行查詢語句的,從而分析你的索引是否滿足需求。

explain 語法:explain select * from table where type=1。

173. 說一下數據庫的事務隔離?

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 條記錄,這就好像產生了幻覺。發生幻讀的原因也是另外一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據,同一個記錄的數據內容被修改了,所有數據行的記錄就變多或者變少了。

174. 說一下 MySQL 常用的引擎?

  • InnoDB 引擎:mysql 5.1 後默認的數據庫引擎,提供了對數據庫 acid 事務的支持,並且還提供了行級鎖和外鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL 運行的時候,InnoDB 會在內存中建立緩沖池,用於緩沖數據和索引。但是該引擎是不支持全文搜索,同時啟動也比較的慢,它是不會保存表的行數的,所以當進行 select count(*) from table 指令的時候,需要進行掃描全表。由於鎖的粒度小,寫操作是不會鎖定全表的,所以在並發度較高的場景下使用會提升效率的。
  • MyIASM 引擎:不提供事務的支持,也不支持行級鎖和外鍵。因此當執行插入和更新語句時,即執行寫操作的時候需要鎖定這個表,所以會導致效率會降低。不過和 InnoDB 不同的是,MyIASM 引擎是保存了表的行數,於是當進行 select count(*) from table 語句時,可以直接的讀取已經保存的值而不需要進行掃描全表。所以,如果表的讀操作遠遠多於寫操作時,並且不需要事務的支持的,可以將 MyIASM 作為數據庫引擎的首選。

175. 說一下 MySQL 的行鎖和表鎖?

MyISAM 只支持表鎖,InnoDB 支持表鎖和行鎖,默認為行鎖。

    • 表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖沖突的概率最高,並發量最低。
    • 行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖沖突的概率小,並發度最高。
  • 176. 說一下樂觀鎖和悲觀鎖?
  • 樂觀鎖:每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
  • 悲觀鎖:每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。

  數據庫的樂觀鎖需要自己實現,在表裏面添加一個 version 字段,每次修改成功值加 1,這樣每次修改的時候先對比一下,自己擁有的 version 和數據庫現在的 version 是否一致,如果不一致就不修改,這樣就實現了樂觀鎖。

177. MySQL 問題排查都有哪些手段?

  • 使用 show processlist 命令查看當前所有連接信息。
  • 使用 explain 命令查詢 SQL 語句執行計劃。
  • 開啟慢查詢日誌,查看慢查詢的 SQL。

178. 如何做 MySQL 的性能優化?

  • 為搜索字段創建索引。
  • 避免使用 select *,列出需要查詢的字段。
  • 垂直分割分表。
  • 選擇正確的存儲引擎。

【Redis】


179. Redis 是什麽?都有哪些使用場景?

Redis 是一個使用 C 語言開發的高速緩存數據庫。

Redis 使用場景:

    • 記錄帖子點贊數、點擊數、評論數;
    • 緩存近期熱帖;
    • 緩存文章詳情信息;
    • 記錄用戶會話信息。

180. Redis 有哪些功能?

  • 數據緩存功能
  • 分布式鎖的功能
  • 支持數據持久化
  • 支持事務
  • 支持消息隊列

181. Redis 和 memcache 有什麽區別?

  • 存儲方式不同:memcache 把數據全部存在內存之中,斷電後會掛掉,數據不能超過內存大小;Redis 有部份存在硬盤上,這樣能保證數據的持久性。
  • 數據支持類型:memcache 對數據類型支持相對簡單;Redis 有復雜的數據類型。
  • 使用底層模型不同:它們之間底層實現方式,以及與客戶端之間通信的應用協議不一樣,Redis 自己構建了 vm 機制,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。
  • value 值大小不同:Redis 最大可以達到 512mb;memcache 只有 1mb。

182. Redis 為什麽是單線程的?

因為 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器內存或者網絡帶寬。既然單線程容易實現,而且 cpu 又不會成為瓶頸,那就順理成章地采用單線程的方案了。

關於 Redis 的性能,官方網站也有,普通筆記本輕松處理每秒幾十萬的請求。

而且單線程並不代表就慢 nginx 和 nodejs 也都是高性能單線程的代表。

183. 什麽是緩存穿透?怎麽解決?

緩存穿透:指查詢一個一定不存在的數據,由於緩存是不命中時需要從數據庫查詢,查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成緩存穿透。

解決方案:最簡單粗暴的方法如果一個查詢返回的數據為空(不管是數據不存在,還是系統故障),我們就把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。

184. Redis 支持的數據類型有哪些?

  Redis 支持的數據類型:string(字符串)、list(列表)、hash(散列表)、set(集合)、zset(有序集合)。

185. Redis 支持的 Java 客戶端都有哪些?

  支持的 Java 客戶端有 Redisson、jedis、lettuce 等。

186. jedis 和 Redisson 有哪些區別?

  • jedis:提供了比較全面的 Redis 命令的支持。
  • Redisson:實現了分布式和可擴展的 Java 數據結構,與 jedis 相比 Redisson 的功能相對簡單,不支持排序、事務、管道、分區等 Redis 特性。

187. 怎麽保證緩存和數據庫數據的一致性?

  • 合理設置緩存的過期時間。
  • 新增、更改、刪除數據庫操作時同步更新 Redis,可以使用事物機制來保證數據的一致性。

188. Redis 持久化有幾種方式?

Redis 的持久化有兩種方式,或者說有兩種策略:

    • RDB(Redis Database):指定的時間間隔能對你的數據進行快照存儲。
    • AOF(Append Only File):每一個收到的寫命令都通過write函數追加到文件中。

189. Redis 怎麽實現分布式鎖?

Redis 分布式鎖其實就是在系統裏面占一個“坑”,其他程序也要占“坑”的時候,占用成功了就可以繼續執行,失敗了就只能放棄或稍後重試。

占坑一般使用 setnx(set if not exists)指令,只允許被一個程序占有,使用完調用 del 釋放鎖。

190. Redis 分布式鎖有什麽缺陷?

  Redis 分布式鎖不能解決超時的問題,分布式鎖有一個超時時間,程序的執行如果超出了鎖的超時時間就會出現問題。

191. Redis 如何做內存優化?

  盡量使用 Redis 的散列表,把相關的信息放到散列表裏面存儲,而不是把每個字段單獨存儲,這樣可以有效的減少內存使用。比如將 Web 系統的用戶對象,應該放到散列表裏面再整體存儲到 Redis,而不是把用戶的姓名、年齡、密碼、郵箱等字段分別設置 key 進行存儲。

192. 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(驅逐):禁止驅逐數據。

193. Redis 常見的性能問題有哪些?該如何解決?

  • 主服務器寫內存快照,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以主服務器最好不要寫內存快照。
  • Redis 主從復制的性能問題,為了主從復制的速度和連接的穩定性,主從庫最好在同一個局域網內。

Java相關面試題總結+答案(九)