Java常見面試題 很是實用【我的經驗】

必收藏的Java面試題

目錄

Java 面試題前端

    一. 容器部分vue

    二. 多線程部分java

    三. SpringMvc部分mysql

    四. Mybatis部分面試

    五. MySQL部分redis

    六. Redis部分算法

    七. RabbitMQ部分spring

    八. JVM 虛擬機部分sql

    九. 其餘面試部分數據庫

自述

本人正在努力複習,總結面試經驗並記錄 Java 面試常見問題,歡迎留言監督
一直在更新

容器部分面試題

Java 容器都有哪些

  • Collection 的子類 ListSet
  • List 的子類 ArrayListLinkedList
  • Set 的子類 HashSetTreeSet
  • Map 的子類 HashMapTreeMao

Collecion 和 Collections 有什麼區別

  • java.util,Collection 是一個集合的頂級接口,它提供了對集合對象進行基本操做的通用接口方法,Collection 接口的意義是爲各類具體的集合提供了最大化的統一操做方式,其直接繼承接口的有 List 和 Set
  • java.util.Collections 是一個包裝類(工具類),它包含了各類有關集合操做的靜態多態方法。此類不能被實例化,用於對集合中元素進行排序、搜索以及線程安全等各類操做,服務於 Java 的 Collection 框架

List、Set、Map 之間的區別

  • List、Set 都繼承 Collection 接口,而 Map 則不是
  • List 是一個有序集合,元素可重複,可有多個NULL值。可使用各類循環遍歷集合,由於它是有序的
  • Set 是一個無序集合,元素不可重複,重複元素會被覆蓋掉(注意:元素雖然無放入順序,但元素在 Set 中的位置是由該元素的 HashCode 決定的,其位置是固定的,加入 Set 的 Object 必須定義 equals()方法),Set 只能用迭代,由於它是無序的
  • Map 是由一系列鍵值對組成的集合,提供了 key 和 value 的映射。在 Map 中保證 key 與 value 一一對應的關係。一個 key 對應一個 value ,不能存在相同的 key,但 value 能夠相同
  • Set 與 List 相比較
  1. Set 檢索元素效率較低,刪除和插入效率高,由於刪除和插入不會引發元素的位置變化
  2. List 可動態增加,查找元素效率高,可是刪除和插入效率低,由於刪除或插入一條元素,會引發其餘元素位置變化
  • Map 適合存儲鍵值對的數據

HashMap 和 HashTable 的區別

  1. 繼承的父類不一樣,但兩者都實現了 Map接口
  • HashTable 繼承自 Dictionary
  • HashMap 繼承自 AbstractMap
  1. 線程安全不一樣
  • HashMap 在缺省的狀況下是非Synchronize的
  • HashTable 的方法是Synchronize的
  • 在多線程下直接使用 HashTable 不須要本身爲它的方法實現同步。但使用 HashMap 時須要手動增長同步處理Map m = Collections.synchronizeMap(hashMap);
  1. 是否提供 contains() 方法
  • HashMap 把 HashTable 的 contains() 方法去掉了,改爲了 containsValue() 和 containsKey(),由於 contains 容易讓人誤解
  • HashTable 則保留了 contains()、containsValue()、containsKey() 三個方法,其中 contains() 與 containsValue() 功能相同
  1. key 和 value 是否能夠爲 null 值
  • HashTable 中,key 和 value 都不能爲 null 值
  • HashMap 中,null 做爲鍵,但這樣的鍵只有一個。能夠有多個 value 爲 null 值的鍵。當 get() 方式返回 null 有多是 HashMap 中沒有該鍵,也有可能返回的 value 爲 null。因此 HashMap 用containsKey()方法判斷是否存在鍵
  1. 遍歷方式不一樣
  • HashTable 與 HashMap 都是使用 Iterator 迭代器遍歷,而因爲歷史的緣由,HashTable 還使用了 Enumeration 的方式
  1. hash 值不一樣
  • 哈希值的使用不一樣,HashTable直接使用對象的HashCode,而 HashMap 從新計算哈希值
  • hashCode是jdk根據對象的地址或者字符串或者數字算出來的int類型的數值
  • HashTable 使用的取模運算
  • HashMap 使用的與運算,先用 hash & 0x7FFFFFFF 後,再對 length 取模,&0x7FFFFFFF 的目的是爲了將負的 hash 值轉化爲正值,由於 hash 值有可能爲負數,而 &0x7FFFFFFF 後,只有符號外改變,然後面的位都不變
  1. 內部實現使用的數組初始化和擴容方式不一樣
  • HashTable 在不指定容量的狀況下默認是11,而 HashMap 爲16,HashTable 不要求底層數組的容量必定要是2的整數次冪,而 HashMap 底層數組則必定爲2的整數次冪
  • HashTable 擴容時,將容量變成原來的2倍+1 (old * 2 + 1),而 HashMap 則直接改成原來的2倍 (old * 2)

如何決定使用 HashMap 仍是 TreeMap

  • 若是須要獲得一個有序的 Map 集合就應該使用 TreeMap (由於 HashMap 的排序順序不是固定的)除此以外,因爲 HashMap 有比 TreeMap 更好的性能,在不須要使用排序的狀況下使用 HashMap 會更好

HashMap 的實現原理

  • 利用key的hashCode從新hash計算出當前對象的元素在數組中的下標
    存儲時,若是出現hash值相同的key,此時有兩種狀況。(1)若是key相同,則覆蓋原始值;(2)若是key不一樣(出現衝突),則將當前的key-value放入鏈表中
    獲取時,直接找到hash值對應的下標,在進一步判斷key是否相同,從而找到對應值。
    理解了以上過程就不難明白HashMap是如何解決hash衝突的問題,核心就是使用了數組的存儲方式,而後將衝突的key的對象放入鏈表中,一旦發現衝突就在鏈表中作進一步的對比。

HashSet 的實現原理

  • HashSet 其實是一個 HashMap 實例,都是一個存放鏈表的數組。它不保證存儲元素的迭代順序;此類容許使用 null 元素。HashSet 中不容許有重複元素,這是由於 HashSet 是基於 HashMap 實現的,HashSet 中的元素都存放在 HashMap 的 key 上面,而 value 中的值都是統一的一個固定對象 private static final Object PRESENT = new Object();
  • HashSet 中 add() 方法調用的是底層 HashMap 中的 put() 方法,而若是是在 HashMap 中調用 put() ,首先會判斷 key 是否存在,若是 key 存在則修改 value 值,若是 key 不存在這插入這個 key-value。而在 set 中,由於 value 值沒有用,也就不存在修改 value 值的說法,所以往 HashSet 中添加元素,首先判斷元素(也就是key)是否存在,若是不存在這插入,若是存在着不插入,這樣 HashSet 中就不存在重複值。因此判斷 key 是否存在就要重寫元素的類的 equals() 和 hashCode() 方法,當向 Set 中添加對象時,首先調用此對象所在類的 hashCode() 方法,計算次對象的哈希值,此哈希值決定了此對象在Set中存放的位置;若此位置沒有被存儲對象則直接存儲,若已有對象則經過對象所在類的 equals() 比較兩個對象是否相同,相同則不能被添加。
  1. AarrayList 是動態數組構成 LinkList 是鏈表組成
  2. AarrayList 經常使用於常常查詢的集合,由於 LinkList 是線性存儲方式,須要移動指針從前日後查找
  3. LinkList 經常使用於新增和刪除的集合,由於 ArrayList 是數組構成,刪除某個值會對下標影響,須要進行數據的移動
  4. AarrayList 自由度較低,須要手動設置固定的大小,可是它的操做比較方便的,①直接建立②添加對象③根據下標進行使用
  5. LinkList 自由度較高,可以動態的隨數組的數據量而變化
  6. ArrayList 主要開銷在List須要預留必定空間
  7. LinkList 主要開銷在須要存儲結點信息以及結點指針信息

如何實現數組與 List 之間的轉換

  • List to Array : 可使用 List 的 toArray() 方法,傳入一個數組的類型例如 Stirng[] strs = strList.toArray(new String[strList.size()]);
  • Array to List : 可使用 java.util.ArraysasList()方法 例如 List<String> strList = Arrays.asList(strs);

ArrayList 與 Vector 的區別是什麼

  • ArrayList 是非線程安全的,而 Vector 使用了 Synchronized 來實現線程同步的
  • ArrayList 在性能方面要優於 Vector
  • ArrayList 和 Vector 都會根據實際狀況來動態擴容的,不一樣的是 ArrayList 擴容到原大小的1.5倍,而 Vector 擴容到原大小的2倍

Array 與 ArrayList 有什麼區別

  • Array 是數組,當定義數組時,必須指定數據類型及數組長度
  • ArrayList 是動態數組,長度能夠動態改變,會自動擴容,不使用泛型的時候,能夠添加不一樣類型元素

在 Queue 中 poll() 與 remove() 有什麼區別

  • poll() 和 remove() 都是從隊列頭刪除一個元素,若是隊列元素爲空,remove() 方法會拋出NoSuchElementException異常,而 poll() 方法只會返回 null

哪些集合類是線程安全的

  1. Vector :比 ArrayList 多了同步化機制(線程安全)
  2. HashTable :比 HashMap 多了線程安全
  3. ConcurrentHashMap :是一種高效可是線程安全的集合
  4. Stack :棧,繼承於 Vector 也是線程安全

迭代器 Iterator 是什麼

  • Iterator 是集合專用的遍歷方式
  • Iterator<E> iterator() : 返回此集合中元素的迭代器,經過集合的iterator()方法獲得,因此Iterator是依賴於集合而存在的

Iterator 怎麼使用 ? 有什麼特色

Iterator 的使用方法

  • java.lang.Iterable 接口被 java.util.Collection 接口繼承,java.util.Collection 接口的 iterator() 方法返回一個 Iterator 對象
  • next() 方法獲取集合中下一個元素
  • hasNext() 方法檢查集合中是否還有元素
  • remove() 方法將迭代器新返回的元素刪除

Iterator 的特色

  • Iterator 遍歷集合過程當中不容許線程對集合元素進行修改
  • Iterator 遍歷集合過程當中能夠用remove()方法來移除元素,移除的元素是上一次Iterator.next()返回的元素
  • Iterator 的next()方法是經過遊標指向的形式返回Iterator下一個元素

Iterator 與 LinkIterator 有什麼區別

  • 使用範圍不一樣
  1. Iterator 適用於全部集合, Set、List、Map以及這些集合的子類型,而 ListIterator 只適用於 List 及其子類型
  2. ListIterator 有 add() 方法,能夠向 List 中添加元素,而 Iterator 不能
  3. ListIterator 和 Iterator 都有 hasNext() 和 next() 方法,來實現順序向後遍歷。而 ListIterator 有 hasPrevious() 和 previous() 方法,能夠實現逆向遍歷,可是 Iterator 不能
  4. ListIterator 可使用 nextIdnex() 和 previousIndex() 方法定位到當前索引位置,而 Iterator 不能
  5. 它們均可以實現 remove() 刪除操做,可是 ListIterator 可使用 set() 方法實現對象修改,而 Iterator 不能

怎麼確保一個集合不能被修改

  • 能夠採用 java.util.Collections 工具類
  • Collections.unmodifiableMap(map)
  • Collections.unmodifiableList(list)
  • Collections.unmodifiableSet(set)
  • 如諾修改則會報錯java.lang.UnsupportedOperationException

多線程部分面試題

併發和並行有什麼區別

  • 併發:不一樣的代碼塊交替執行
  • 並行:不一樣的代碼塊同時執行
  • 我的理解
  1. 併發就是放下手頭的任務A去執行另一個任務B,執行完任務B後,再回來執行任務A,就好比說吃飯時來電話了,去接電話,打完電話後又回來吃飯
  2. 並行就是執行A的同時,接受到任務B,而後我一塊兒執行,就好比說吃飯時來電話了,一邊吃飯一邊打電話

線程和進程的區別

  • 根本區別 :進程是操做系統資源分配的基本單位,而線程是任務調度和執行的基本單位
  • 在操做系統中能同時運行多個進程,進程中會執行多個線程
  • 線程是操做系統可以進行運算調度的最小單位

守護線程是什麼

  • JVM內部的實現是若是運行的程序只剩下守護線程的話,程序將終止運行,直接結束。因此守護線程是做爲輔助線程存在的

建立線程有哪幾種方式

  1. 繼承Thread類建立線程類
  • 定義Thread類的子類,並重寫該類的run()方法
  • 建立Thread子類的實例,即建立了線程對象
  • 調用線程對象的start()方法來啓動該線程
  1. 實現Runnable接口建立線程類
  • 建立runnable接口的實現類,並重寫該接口的run()方法
  • 建立Runnable實現類的實例,並依此實例做爲Thread的target來建立Thread對象,該 Thread 對象纔是真正的線程對象
  • 調用線程對象的start()方法來啓動該線程
  1. 經過 Callable 和 Future 建立線程
  • 建立Callable接口的實現類,並重寫call()方法,該call()方法將做爲線程執行體,而且有返回值
  • 建立Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值
  • 使用FutureTask對象做爲Thread對象的target建立並啓動新線程
  • 調用FutureTask對象的get()方法來得到子線程執行結束後的返回值

runnable 和 callable 有什麼區別

  • 相同點
  1. 都是接口
  2. 均可以編寫多線程程序
  3. 都是採用Thread.start()啓動線程
  • 不一樣點
  1. Runnable沒有返回值,Callable能夠返回執行結果,是個泛型和FutureFutureTask配合能夠用來獲取異步執行的結果
  2. Callable接口的call()方法容許拋出異常,Runnablerun()方法異常只能在內部消化,不能往上繼續拋

注意 Callalble接口支持返回執行結果,須要調用FutureTask.get()獲得,此方法會阻塞主進程的繼續往下執行,若是不調用不會阻塞

線程有哪些狀態

  • 新建 就緒 運行 阻塞 死亡

sleep() 和 wait() 的區別

  • 最大區別是sleep() 休眠時不釋放同步對象鎖,其餘線程沒法訪問 而wait()休眠時,釋放同步對象鎖其餘線程能夠訪問
  • sleep() 執行完後會自動恢復運行不須要其餘線程喚起.而 wait() 執行後會放棄對象的使用權,其餘線程能夠訪問到,須要其餘線程調用 Monitor.Pulse() 或者 Monitor.PulseAll() 來喚醒或者通知等待隊列

線程的 run() 和 start() 的區別

  • start() 是來啓動線程的
  • run() 只是 Thread 類中一個普通方法,仍是在主線程中執行

notify() 和 notifyAll() 有什麼區別

  • notify() 方法隨機喚醒對象的等待池中的一個線程,進入鎖池
  • notifyAll() 喚醒對象的等待池中的全部線程,進入鎖池。

建立線程池有哪幾種方式

  • 利用Executors建立線程池
  1. newCachedThreadPool(),它是用來處理大量短期工做任務的線程池
  2. newFixedThreadPool(int nThreads),重用指定數目nThreads的線程
  3. newSingleThreadExecutor(),它的特色在於工做線程數目限制爲1
  4. newSingleThreadScheduledExecutor()newScheduledThreadPool(int corePoolSize),建立的是個ScheduledExecutorService,能夠進行定時或週期性的工做調度,區別在於單一工做線程仍是多個工做線程。
  5. newWorkStealingPool(int parallelism),這是一個常常被人忽略的線程池,Java 8 才加入這個建立方法,其內部會構建ForkJoinPool,利用Work-Stealing算法,並行地處理任務,不保證處理順序

線程池都有哪些狀態

  1. 運行 RUNNING:線程池一旦被建立,就處於 RUNNING 狀態,任務數爲 0,可以接收新任務,對已排隊的任務進行處理
  2. 關閉 SHUTDOWN:不接收新任務,但能處理已排隊的任務。調用線程池的 shutdown() 方法,線程池由 RUNNING 轉變爲 SHUTDOWN 狀態
  3. 中止 STOP:不接收新任務,不處理已排隊的任務,而且會中斷正在處理的任務。調用線程池的 shutdownNow() 方法,線程池由(RUNNINGSHUTDOWN ) 轉變爲 STOP 狀態
  4. 整理 TIDYING:
  • SHUTDOWN狀態下,任務數爲 0, 其餘全部任務已終止,線程池會變爲 TIDYING 狀態,會執行 terminated() 方法。線程池中的 terminated() 方法是空實現,能夠重寫該方法進行相應的處理
  • 線程池在 SHUTDOWN 狀態,任務隊列爲空且執行中任務爲空,線程池就會由 SHUTDOWN 轉變爲 TIDYING 狀態
  • 線程池在 STOP 狀態,線程池中執行中任務爲空時,就會由 STOP 轉變爲 TIDYING 狀態
  1. 終止 TERMINATED:線程池完全終止。線程池在 TIDYING 狀態執行完 terminated() 方法就會由 TIDYING 轉變爲 TERMINATED 狀態

線程池中的 submit() 和 execute() 有什麼區別

  • 兩個方法均可以向線程池提交任務
  • execute()方法的返回類型是 void,它定義在Executor接口中
  • submit()方法能夠返回持有計算結果的 Future 對象,它定義在ExecutorService接口中

在Java程序中怎麼確保多線程運行安全

  1. 使用synchronied關鍵字
  2. 使用volatile 關鍵字,防止指令重排,全部對該變量讀寫都是直接操做共享內存
  3. lock鎖機制 lock()unlock()
  4. 使用線程安全的類 好比StringBufferHashTableVector

線程安全問題主要是:原子性,可見性,有序性

synchronized 和 volatile 的做用什麼?有什麼區別

  1. 做用
  • synchronized 表示只有一個線程能夠獲取做用對象的鎖,執行代碼,阻塞其餘線程
  • volatile 表示變量在 CPU 的寄存器中是不肯定的,必須從主存中讀取。保證多線程環境下變量的可見性,禁止指令重排序
  1. 區別
  • synchronized 能夠做用於變量、方法、對象。volatile 只能做用於變量
  • synchronized 能夠保證線程間的有序性、原子性和可見性。volatile 只保證了可見性和有序性,沒法保證原子性
  • synchronized 線程阻塞,volatile 線程不阻塞

synchronized 和 Lock 有什麼區別

  • synchronized是一個Java關鍵字,在jvm層面上,而Lock是一個類
  • synchronized以獲取鎖的線程執行完同步代碼,釋放鎖,若是線程中發生異常,jvm會讓線程釋放鎖。而Lock必須在finally中釋放鎖,不然容易形成線程死鎖
  • Lock能夠查看鎖的狀態,而synchronized不能
  • 在性能上來講,若是競爭資源不激烈,二者的性能是差很少的,而當競爭資源很是激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優於synchronized。因此說,在具體使用時要根據適當狀況選擇
  • synchronized是非公平鎖,而Lock是可公平鎖

Spring Mvc面試題部分

爲何要是使用 Spring

  • 輕量 非侵入型框架
  • 控制反轉 IOC,促進了鬆耦合
  • 面向切面編程 AOP
  • 容器 採用Java Bean 代替 沉重的EJB容器
  • 方便集成 能夠和不少框架相互集成如MybatisShiro
  • 豐富的功能 Spring 已經寫好了不少常的模板如JDBC抽象類事務管理JMSJMXWeb Service...等

解釋一下什麼是 aop

  • AOP是面向切面編程,是OOP編程的有效補充
  • AOP包括Aspect切面,Join Point鏈接點,Advice通知,Ponitcut切點

其中Advice通知包括5中模式

  1. Before advice:方法執行前‘加強’
  2. After returning advice:方法執行後‘加強’
  3. After throwing advice:方法執行中拋出異常時‘加強’
  4. After finally advice:方法執行完後‘加強’
  5. Around advice:環繞加強‘以上四種的整合’

解釋一下什麼是 ioc

  • IOC是控制反轉,是將代碼自己的控制權移到外部Spring容器中進行集中管理,也是爲了達到鬆耦合

Spring 主要有哪些模塊

  1. Spring Core
  • 框架基礎部分,提供了IOC容器,對Bean進行集中管理
  1. Spring Context
  • 基於Bean,提供上下文信息
  1. Spring Dao
  • 提供了JDBC的抽象層,它可消除冗長的JDBC編碼,提供了聲明性事務管理方法
  1. Spring ORM
  • 提供了對象/關係映射經常使用的API集成層,如MybatisHibernate
  1. Spring Aop
  • 提供了AOP面向切面的編程實現
  1. Spring Web
  • 提供了Web開發的信息上下文,可與其餘的Web集成開發
  1. Spring Web Mvc
  • 提供了Web應用的Model - View - Controller全功能的實現

Spring 經常使用的注入方式有哪些

  • 構造方法注入
  • Setter方法注入

不過值得一提的是:Setter注入時若是寫了帶參構造方法,那麼無參構造方法必須也要寫上,不然注入失敗

  • 基於註解得注入

基本上有五種經常使用註冊Bean的註解

  1. @Component:通用註解
  2. @Controller:註冊控制層Bean
  3. @Service:註冊服務層Bean
  4. @Repository:註冊Dao層Bean
  5. @Configuration:註冊配置類

Spring 中的 bean 是線程安全的嗎

  • 線程不安全
  • Spring容器中的Bean是否線程安全,容器自己並無提供Bean的線程安全策略,所以能夠說Spring容器中的Bean自己不具有線程安全的特性

Spring 支持幾種 bean 的做用域

  1. singleton:單例,默認的做用域
  2. prototype:原型,每次都會建立新對象
  3. request:請求,每次Http請求都會建立一個新對象
  4. session:會話,同一個會話建立一個實例,不一樣會話使用不一樣實例
  5. global-session:全局會話,全部會話共享一個實例
  • 後面三種只有在Web應用中使用Spring纔有效

Spring 自動裝配 bean 有哪些方式

  • default:默認方式和‘no’效果同樣
  • no :不自動配置,須要使用 節點或參數
  • byName:根據名稱進行裝配
  • byType:根據類型進行裝配
  • constructor :根據構造函數進行裝配

Spring 事務實現方式有哪些

  • 編程式事務管理對基於 POJO 的應用來講是惟一選擇,咱們須要在代碼中調用beginTransaction()、commit()、rollback()等事務管理相關的方法,這就是編程式事務管理
  • 基於 TransactionProxyFactoryBean的聲明式事務管理
  • 基於 @Transactional 的聲明式事務管理
  • 基於Aspectj AOP配置事務

Spring 的事務隔離是什麼


Spring Mvc 的運行流程

image

  1. 用戶發送一個請求至前端控制器DispatcherServlet
  2. DispatcherServlet收到請求調用處理器映射器HandlerMapping
  3. 處理器映射器根據請求url找到具體的處理器,生成處理器執行鏈HandlerExecutionChain(包括處理器對象和處理器攔截器)一併返回給DispatcherServlet
  4. DispatcherServlet根據處理器Handler獲取處理器適配器HandlerAdapter執行HandlerAdapter處理一系列的操做
  5. 執行處理器Handler(Controller,也叫頁面控制器)
  6. Handler執行完成返回ModelAndViewHandlerAdapter
  7. HandlerAdapterHandler執行結果ModelAndView返回到DispatcherServlet
  8. DispatcherServlet``將ModelAndView傳給ViewReslover視圖解析器
  9. ViewReslover解析後返回具體View
  10. DispatcherServletView進行渲染視圖(即將模型數據model填充至視圖中)
  11. DispatcherServlet響應用戶

Spring Mvc 有哪些組件

  • DispatcherServlet:前端控制器
  • HandlerMapping:處理器映射器
  • HandlerAdapter:處理器適配器
  • HandlerInterceptor:攔截器
  • ViewResolver:視圖解析器
  • MultipartResolver:文件上傳處理器
  • HandlerExceptionResolver:異常處理器
  • DataBinder:數據轉換
  • HttpMessageConverter:消息轉換器
  • FlashMapManager:頁面跳轉參數管理器
  • HandlerExecutionChain:處理程序執行鏈
  • RequestToViewNameTranslator:請求轉視圖翻譯器
  • ThemeResolver
  • LocaleResolver:語言環境處理器

@RequestMapping 的做用是什麼

  • @RequestMapping是一個註解,用來標識 http 請求地址與 Controller 類的方法之間的映射
  • 指定 http 請求的類型使用

GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

@Autowired 與 @Resource 的區別

  • @AutowiredSpring提供的註解,須要導入包org.springframework.beans.factory.annotation.Autowired,採起的策略爲按照類型注入
  • @Resource註解由J2EE提供,須要導入包javax.annotation.Resource,默認按照ByName自動注入

Mybatis部分面試題

Mybatis 中 #{} 和 ${} 的區別

  • #{} 表示一個佔位符

能夠有效的防止SQL注入

  • ${} 表示拼接SQL串

能夠用於動態判斷字段
order by ${field} desc能夠動態修改fieId來達到動態根據字段降序查詢

Mybatis 有幾種分頁方式

  1. 原始分割

取出數據後,進行手動分割

  1. LIMIT關鍵字

修改執行SQL語句

  1. RowBounds實現分頁

PageInfo信息封裝成RowBounds,調用DAO層方法

  1. Mybatis的Interceptor實現

原理就是執行SQL語句前,在原SQL語句後加上limit關鍵字,不用本身去手動添加

RowBounds 是一次性查詢所有結果嗎?爲何

  • RowBounds 表面是在「全部」數據中檢索數據,其實並不是是一次性查詢出全部數據,由於 MyBatis 是對 jdbc 的封裝,在 jdbc 驅動中有一個 Fetch Size 的配置,它規定了每次最多從數據庫查詢多少條數據,假如你要查詢更多數據,它會在你執行 next()的時候,去查詢更多的數據。就比如你去自動取款機取 10000 元,但取款機每次最多能取 2500 元,因此你要取 4 次才能把錢取完。只是對於 jdbc 來講,當你調用 next()的時候會自動幫你完成查詢工做。這樣作的好處能夠有效的防止內存溢出。

Mybatis 邏輯分頁和物理分頁的區別是什麼

  • 邏輯分頁是一次性查詢不少數據,而後再在結果中檢索分頁的數據。這樣作弊端是須要消耗大量的內存、有內存溢出的風險、對數據庫壓力較大。
  • 物理分頁是從數據庫查詢指定條數的數據,彌補了一次性所有查出的全部數據的種種缺點,好比須要大量的內存,對數據庫查詢壓力較大等問題

Myabtis 是否支持延遲加載,延遲加載的原理是什麼

  • MyBatis 支持延遲加載,設置 lazyLoadingEnabled=true 便可
  • 延遲加載的原理的是調用的時候觸發加載,而不是在初始化的時候就加載信息。好比調用 a.getB().getName(),這個時候發現 a.getB() 的值爲 null,此時會單獨觸發事先保存好的關聯 B 對象的 SQL,先查詢出來 B,而後再調用 a.setB(b),而這時候再調用 a.getB(). getName() 就有值了,這就是延遲加載的基本原理

Mybatis 一級緩存和二級緩存

  1. 一級緩存
  • 基於PerpetualCacheHashMap本地緩存,它的聲明週期是和 SQLSession一致的,有多個 SQLSession 或者分佈式的環境中數據庫操做,可能會出現髒數據
  • Session flushclose 以後,該Sessio中的全部Cache 就將清空,默認一級緩存是開啓的
  1. 二級緩存
  • 也是基於PerpetualCacheHashMap本地緩存,不一樣在於其存儲做用域爲Mapper 級別的,若是多個SQLSession之間須要共享緩存,則須要使用到二級緩存
  • 二級緩存可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啓二級緩存,使用二級緩存屬性類須要實現 Serializable 序列化接口(可用來保存對象的狀態)
  1. 擴展
  • 開啓二級緩存後的查詢流程:二級緩存 -> 一級緩存 -> 數據庫
  • 緩存更新機制:當某一個做用域(一級緩存 Session/二級緩存 Mapper)進行了C/U/D 操做後,默認該做用域下全部 select 中的緩存將被 clear

Mybatis 和 Hibernate 有哪些區別

  • Mybatis 更加靈活,能夠本身寫SQL語句
  • 也正是本身寫了不少SQL語句,因此移植性比較差
  • Mybatis 入門比較簡單,使用門檻也低
  • hibernate 能夠自行把二級緩存更換爲第三方的

Mybatis 有哪些執行器

  1. SimpleExecutor:每執行一次UPDATE\SELECT 就開啓一個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 分頁插件的實現原理是什麼

  • 分頁插件的基本原理是使用 MyBatis 提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的 SQL,而後重寫 SQL,根據 dialect 方言,添加對應的物理分頁語句和物理分頁參數

Mybatis 如何編寫一個自定義插件

MyBatis 自定義插件針對 MyBatis 四大對象(Executor、StatementHandler、ParameterHandler、ResultSetHandler)進行攔截

  1. Executor:攔截內部執行器,它負責調用 StatementHandler 操做數據庫,並把結果集經過 ResultSetHandler 進行自動映射,另外它還處理了二級緩存的操做
    . StatementHandler:攔截 SQL 語法構建的處理,它是 MyBatis 直接和數據庫執行 SQL 腳本的對象,另外它也實現了 MyBatis 的一級緩存
  2. ParameterHandler:攔截參數的處理
  3. ResultSetHandler:攔截結果集的處理

MyBatis 插件要實現 Interceptor 接口

  1. setProperties 方法是在 MyBatis 進行配置插件的時候能夠配置自定義相關屬性,即:接口實現對象的參數配置
  2. plugin 方法是插件用於封裝目標對象的,經過該方法咱們能夠返回目標對象自己,也能夠返回一個它的代理,能夠決定是否要進行攔截進而決定要返回一個什麼樣的目標對象,官方提供了示例:return Plugin. wrap(target, this)
  3. intercept 方法就是要進行攔截的時候要執行的方法
public interface Interceptor {   
   Object intercept(Invocation invocation) throws Throwable;       
   Object plugin(Object target);    
   void setProperties(Properties properties);
}

官方插件實現:

@Intercepts({@Signature(type = Executor. class, method = "query",
        args = {MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class})})
public class TestInterceptor implements Interceptor {
   public Object intercept(Invocation invocation) throws Throwable {
     Object target = invocation. getTarget(); //被代理對象
     Method method = invocation. getMethod(); //代理方法
     Object[] args = invocation. getArgs(); //方法參數
     // do something . . . . . .  方法攔截前執行代碼塊
     Object result = invocation. proceed();
     // do something . . . . . . . 方法攔截後執行代碼塊
     return result;
   }
   public Object plugin(Object target) {
     return Plugin. wrap(target, this);
   }
}

具體案例請看 Mybatis 實現自定義插件 通俗易懂

MySQL部分面試題

數據庫的三範式是什麼

如何獲取當前數據庫的版本

說一下 ACID 是什麼

char 和 varchar 的區別

float 和 double 的區別

MySQL 內鏈接、左鏈接、右鏈接有什麼區別

MySQL 的索引是怎麼實現的

怎麼驗證 MySQL 的索引是否知足需求

數據的事務隔離

MySQL 經常使用的引擎

InnoDB 和 Myisam 都是用 B+Tree 來存儲數據的

  1. InnoDB 支持事務,且支持四種隔離級別(讀未提交、讀已提交、可重複讀、串行化),默認的爲可重複讀.
  2. Myisam 只支持表鎖,且不支持事務.Myisam 因爲有單獨的索引文件,在讀取數據方面的性能很高.

MySQL 的行鎖和表鎖

樂觀鎖和悲觀鎖

MySQL 問題排查都有哪些手段

如何作 MySQL 的性能優化

Redis部分面試題

Redis 是什麼?都有哪些使用場景

Redis 爲何是單線程的

Redis 的緩存預熱

  1. 在項目配置文件中生命自定義的key ,在項目啓動時會判斷redis是否存在key ,若是沒有就會建立一個key傳入null
  2. 數據加熱的含義就是在正式部署以前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中

redis 緩存雪崩是什麼,怎麼解決 ?

緩存雪崩是指,緩存層出現了錯誤,不能正常工做了.因而全部的請求都會達到存儲層,存儲層的調用量會暴增,形成存儲層也會掛掉的狀況.

解決方案

  1. redis 高可用 就是搭建 redis 集羣,其中一臺redis掛掉後 可使用其餘的 redis
  2. 限流降級 就是每個 key 只能一個線程來查詢數據和緩存,其餘線程等待
  3. 數據預熱 數據加熱的含義就是在正式部署以前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中.在即將發生大併發訪問前手動觸發加載緩存不一樣的 key ,設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻.*

緩存穿透是什麼?如何解決

就是訪問redis數據庫,查不到數據,就是沒有命中,會去持久化數據庫查詢,仍是沒有查到.假如高併發的狀況下,持久化數據庫一下增長了很大壓力,就至關於出現了緩存穿透

解決方案

  1. 緩存空對象 在存儲層命中失敗後,即便返回空對象也將其緩存,並設置一個過時時間,以後訪問的這個數據將會從緩存中取出,很好的保護了後端數據源,這樣也會有出現問題 例如空值被緩存也就會增長大量的緩存空間,設置了過時時間仍是會存在緩存層和存儲層的數據會有一段時間窗口的不一致,這對於須要保持一致性的業務會有影響
  2. 布隆過濾器 對全部可能查詢的參數以 hash 形式存儲,查詢時發現值不存在就直接丟棄,不會去持久層查詢

Redis 支持的數據類型有哪些

Redis 支持的 Java 客戶端有哪些

Jedis 與 Redisson 有哪些區別

怎麼保證緩存與數據庫數據的一致性

Redis 持久化有幾種方式

Redis 怎麼實現分佈式鎖

Redis 分佈式鎖有什麼缺陷

Redis 如何作內存優化

Redis 淘汰策略有哪些

Redis 常見的問題有哪些? 該如何解決

RabbitMQ部分面試題

RabbitMq 的使用場景有哪些

RabbitMq 有哪些重要的角色

RabbitMQ的消息存儲方式

RabbitMQ 對於 queue 中的 message 的保存方式有兩種方式:discram.若是採用disc,則須要對 exchange/queue/delivery mode 都要設置成 durable 模式. Disc 方式的好處是當 RabbitMQ 失效了, message 仍然能夠在重啓以後恢復.而使用 ram 方式, RabbitMQ 處理 message 的效率要高不少, ram 和 disc 兩種方式的效率比大概是 3:1.因此若是在有其它 HA 手段保障的狀況下,選用 ram 方式是能夠提升消息隊列的工做效率的.

RabbitMq 中 vhost 的做用是什麼

RabbitMq 的消息是怎麼發送的

RabbitMq 怎麼保證消息的穩定性

RabbitMq 怎麼避免丟失消息

要保證消息持久化成功的條件有哪些

RabbitMq 持久化有什麼缺點

RabbitMq 有幾種廣播方式

RabbitMq 節點的類型有哪些

RabbitMq 集羣搭建須要注意哪些問題

RabbitMq 每一個節點是其餘節點的完整拷貝嗎

RabbitMq 集羣中惟一一個磁盤節點崩潰了會發生什麼

RabbitMq 對集羣中止順序有要求嗎

JVM部分面試題

JVM 主要的組成部分?及其做用

JVM 運行時數據區是什麼

堆和棧的區別

  1. 棧內存用來存儲局部變量和方法調用
  2. 而堆內存用來存儲 Java 中的對象.不管是成員變量,局部變量,仍是類變量.,它們指向的對象都存儲在堆內存中.
  3. 棧內存歸屬單個線程,一個棧對應一個線程,其中儲存的變量只能在該線程中能夠訪問到,也能夠理解爲私有內存
  4. 而堆內存中的對象 全部線程都可見,堆內存中對象能夠被全部線程訪問到
  5. 棧內存要遠小於堆內存

隊列和棧是什麼?有什麼區別

什麼是雙親委派模型

類加載的執行過程

怎麼判斷對象是否能夠收回

Java 中有哪些引用類型

JVM 中垃圾回收算法

JVM 有哪些垃圾回收器

介紹一下 CMS 垃圾回收器

新生代垃圾回收器和老生代垃圾回收器有哪些?有什麼區別

簡述分代垃圾回收器是怎麼工做的

JVM 調優的工具備哪些

JVM 調優的參數有哪些

其餘部分面試題

Api 接口如何實現 ?

在類裏使用 implements 關鍵字實現 Api 接口

MySQL 連接數據庫經常使用的幾種方式 ?

  1. Mybatis 框架
  2. Hibernate 框架
  3. JDBC 技術
  4. c3p0 鏈接池
  5. dbcp 鏈接池

SpringBoot 如何集成 Redis ?

在 pom.xml 文件引入 redis 依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在 application 配置文件中 書寫 redis 配置

spring.redis.host=127.0.0.1
    #Redis服務器鏈接端口
    spring.redis.port=6379
    #Redis服務器鏈接密碼(默認爲空)
    #spring.redis.password=

SpringCloud 的優勢 ?

  1. 服務之間採用Restful等輕量級通信
  2. 精準的制定優化服務方案,提升系統的可維護性
  3. 服務之間拆分細緻,資源可重複利用,提升開發效率

SpringCloud 用了哪些組件 ?

  1. netflix Eureka 註冊中心
  2. netflix Ribbon 負載均衡
  3. netflix Zuul 網關
  4. netflix Hystrix 熔斷器
  5. feign 服務調用

List 和 Set 的區別

  1. List 容許有多個重複對象,而 Set 不容許有重複對象
  2. List 容許有多個NULL值,而 Set 只容許有一個NULL值
  3. List 是一個有序的容器,輸出順序便是輸入順序
  4. Set 是一個無序的容器沒法保證每一個元素的順序,可是能夠用 TreeSet 經過 Comparator 或者 Comparable 維護排序順序
  5. List的實現類有 ArrayList、LinkList、Vector 其中 ArrayList 最經常使用於查詢較多,隨意訪問.LinkList 同於新增和刪除較多的狀況,Vector 表示底層數組,線程安全象
  6. Set的實現類有 HashSet、TreeSet、LinkedHashSet 其中基於 HashMap 實現的 HashSet 最爲流行,TreeSet 是一個有序的Set容器象

擴展

Map的實現類有HashMap、HashTable、TreeMap

Java 中 static 的做用

  1. 表示全局或靜態的意思、用來修飾成員變量和成員方法,也能夠造成靜態代碼塊
  2. 達到了不用實例化就可使用被 public static 修飾的變量或方法

什麼單例模式 ?

保證整個項目中一個類只有一個對象的實例,實現這種功能就叫作單例模式

  1. 單例模式的好處:
  1. 單例模式節省公共資源
  2. 單例模式方便控制
  1. 如何保證是單利模式 ?
  1. 構造私有化
  2. 以靜態方法返回實例
  3. 確保對象實例只有一個
  1. 單例模式有哪幾個 ?
  1. 餓漢模式

把對象建立好,須要使用的時候直接拿到就行

  1. 懶漢模式

等你須要的時候在建立對象,後邊就不會再次建立

SpringBoot 經常使用的幾個註解 ?

  1. @SpringBootApplication SpringBoot的核心註解 啓動類
  2. @EnableAutoConfiguration 開啓SpringBoot自動配置
  3. @RestController 在控制層 是@ResponseBody註解與@Controller註解的合集
  4. @RequestMapper 處理請求地址映射的註解
  5. @RequestParam 獲取url上傳過來的參數
  6. @Configuration 聲明配置類
  7. @Component 通用註解
  8. @Service 業務邏輯層

Java 八大數據類型

char 字符型 byte 字節型 boolean 布爾型

float 單浮點型 double 雙浮點型

int 整數型 short 短整數型 long 長整數型

MySQL分頁和升序降序如何實現 ?

  1. 能夠用 limit

select nameagesex from t_student limit(0,5);

  1. 升序 order by xx asc

select nameagesex from t_student order by age asc;

  1. 降序 order by xx desc

select nameagesex from t_student order by age desc;

maven 是幹什麼的,它有什麼好處 ?

  1. maven 專門構建和管理Java項目的工具
  2. maven的好處在於能夠將項目過程規範化、自動化、高效化以及強大的可擴展性

Sql調優

  1. 建立索引 儘可能避免全盤掃描 首先考慮在 where 和 order by 涉及的列上建立索引
  2. 避免在索引上使用計算 注意就是IN關鍵字不走索引,它是走全盤掃描
  3. 使用預編譯防止 sql 注入
  4. 儘可能將多條 SQL語句壓縮到一條 SQL 語句中
  5. 最最最好的就是少用 * , 應該寫成要查詢的字段名,儘可能避免在 where 條件中判斷 null
  6. 儘可能不用like 的前置百分比
  7. 對於連續的數值,能用 between 就不要用 in
  8. 在新建臨時表時,若是一次性插入數據量較大.能夠用 select into 代替 create table

MySQL 如何添加索引 ?

  1. PRIMARY KEY (主鍵索引)
  2. 添加INDEX(普通索引) ALTER TABLE table_name ADD INDEX index_name ( column )
  3. 添加FULLTEXT(全文索引) ALTER TABLE table_name ADD FULLTEXT ( column)
  4. 添加多列索引 ALTER TABLE table_name ADD INDEX index_name ( column1column2column3 )

MySQL 索引的實現方式?

MySQL 索引底層的實現方式是 B+Tree也就是B+樹 具體查看 B+Tree實現方式

Vue的數據雙向綁定原理

使用v-mode屬性, 它的原理是利用了Object.defineProperty()方法從新定義了對象獲取屬性值(get)和設置屬性值(set)的操做來實現的

ActiveMQ的消息存儲方式

  • 採起先進先出模式,同一時間,消息只會發送給某一個消費者,只有當該消息被消費並告知已收到時,它才能在代理的存儲中被刪除.
  • 對於持久性訂閱來講,每個消費者都會獲取消息的拷貝.爲了節約空間,代理的存儲介質中只存儲了一份消息,存儲介質的持久訂閱對象爲其之後的被存儲的消息維護了一個指針,消費者消費時,從存儲介質中複製一個消息.消息被全部訂閱者獲取後才能刪除.

KahaDB消息存儲

基於文件的消息存儲機制,爲了提升消息存儲的可靠性和可恢復性,它整合了一個事務日誌.KahaDB擁有高性能和可擴展性等特色.因爲KahaDB使用的是基於文件的存儲,因此不須要使用第三方數據庫

相關文章
相關標籤/搜索