日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java array 元素的位置_Java常见面试题 非常实用「个人经验」

發布時間:2025/4/5 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java array 元素的位置_Java常见面试题 非常实用「个人经验」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 容器都有哪些

  • Collection 的子類 List、Set
  • List 的子類 ArrayList、LinkedList等
  • Set 的子類 HashSet、TreeSet等
  • Map 的子類 HashMap、TreeMao等

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 相比較
  • Set 檢索元素效率較低,刪除和插入效率高,因為刪除和插入不會引起元素的位置變化
  • List 可動態增長,查找元素效率高,但是刪除和插入效率低,因為刪除或插入一條元素,會引起其他元素位置變化
    • Map 適合存儲鍵值對的數據

    HashMap 和 HashTable 的區別

  • 繼承的父類不同,但二者都實現了 Map接口
    • HashTable 繼承自 Dictionary
    • HashMap 繼承自 AbstractMap
  • 線程安全不同
    • HashMap 在缺省的情況下是非Synchronize的
    • HashTable 的方法是Synchronize的
    • 在多線程下直接使用 HashTable 不需要自己為它的方法實現同步。但使用 HashMap 時需要手動增加同步處理Map m = Collections.synchronizeMap(hashMap);
  • 是否提供 contains() 方法
    • HashMap 把 HashTable 的 contains() 方法去掉了,改成了 containsValue() 和 containsKey(),因為 contains 容易讓人誤解
    • HashTable 則保留了 contains()、containsValue()、containsKey() 三個方法,其中 contains() 與 containsValue() 功能相同
  • key 和 value 是否可以為 null 值
    • HashTable 中,key 和 value 都不能為 null 值
    • HashMap 中,null 作為鍵,但這樣的鍵只有一個。可以有多個 value 為 null 值的鍵。當 get() 方式返回 null 有可能是 HashMap 中沒有該鍵,也有可能返回的 value 為 null。所以 HashMap 用containsKey()方法判斷是否存在鍵
  • 遍歷方式不同
    • HashTable 與 HashMap 都是使用 Iterator 迭代器遍歷,而由于歷史的原因,HashTable 還使用了 Enumeration 的方式
  • hash 值不同
    • 哈希值的使用不同,HashTable直接使用對象的HashCode,而 HashMap 重新計算哈希值
    • hashCode是jdk根據對象的地址或者字符串或者數字算出來的int類型的數值
    • HashTable 使用的取模運算
    • HashMap 使用的與運算,先用 hash & 0x7FFFFFFF 后,再對 length 取模,&0x7FFFFFFF 的目的是為了將負的 hash 值轉化為正值,因為 hash 值有可能為負數,而 &0x7FFFFFFF 后,只有符號外改變,而后面的位都不變
  • 內部實現使用的數組初始化和擴容方式不同
    • 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() 比較兩個對象是否相同,相同則不能被添加。

    ArrayList 與 LinkList 的區別是什么

  • AarrayList 是動態數組構成 LinkList 是鏈表組成
  • AarrayList 常用于經常查詢的集合,因為 LinkList 是線性存儲方式,需要移動指針從前往后查找
  • LinkList 常用于新增和刪除的集合,因為 ArrayList 是數組構成,刪除某個值會對下標影響,需要進行數據的移動
  • AarrayList 自由度較低,需要手動設置固定的大小,但是它的操作比較方便的,①直接創建②添加對象③根據下標進行使用
  • LinkList 自由度較高,能夠動態的隨數組的數據量而變化
  • ArrayList 主要開銷在List需要預留一定空間
  • LinkList 主要開銷在需要存儲結點信息以及結點指針信息
  • 如何實現數組與 List 之間的轉換

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

    哪些集合類是線程安全的

  • Vector :比 ArrayList 多了同步化機制(線程安全)
  • HashTable :比 HashMap 多了線程安全
  • ConcurrentHashMap :是一種高效但是線程安全的集合
  • Stack :棧,繼承于 Vector 也是線程安全
  • 迭代器 Iterator 是什么

    • Iterator 是集合專用的遍歷方式
    • Iterator 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 有什么區別

    • 使用范圍不同
  • Iterator 適用于所有集合, Set、List、Map以及這些集合的子類型,而 ListIterator 只適用于 List 及其子類型
  • ListIterator 有 add() 方法,可以向 List 中添加元素,而 Iterator 不能
  • ListIterator 和 Iterator 都有 hasNext() 和 next() 方法,來實現順序向后遍歷。而 ListIterator 有 hasPrevious() 和 previous() 方法,可以實現逆向遍歷,但是 Iterator 不能
  • ListIterator 可以使用 nextIdnex() 和 previousIndex() 方法定位到當前索引位置,而 Iterator 不能
  • 它們都可以實現 remove() 刪除操作,但是 ListIterator 可以使用 set() 方法實現對象修改,而 Iterator 不能
  • 怎么確保一個集合不能被修改

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

    2|3多線程部分面試題

    并發和并行有什么區別

    • 并發:不同的代碼塊交替執行
    • 并行:不同的代碼塊同時執行
    • 個人理解
  • 并發就是放下手頭的任務A去執行另外一個任務B,執行完任務B后,再回來執行任務A,就比如說吃飯時來電話了,去接電話,打完電話后又回來吃飯
  • 并行就是執行A的同時,接受到任務B,然后我一起執行,就比如說吃飯時來電話了,一邊吃飯一邊打電話
  • 線程和進程的區別

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

    守護線程是什么

    • JVM內部的實現是如果運行的程序只剩下守護線程的話,程序將終止運行,直接結束。所以守護線程是作為輔助線程存在的

    創建線程有哪幾種方式

  • 繼承Thread類創建線程類
    • 定義Thread類的子類,并重寫該類的run()方法
    • 創建Thread子類的實例,即創建了線程對象
    • 調用線程對象的start()方法來啟動該線程
  • 實現Runnable接口創建線程類
    • 創建runnable接口的實現類,并重寫該接口的run()方法
    • 創建Runnable實現類的實例,并依此實例作為Thread的target來創建Thread對象,該 Thread對象才是真正的線程對象
    • 調用線程對象的start()方法來啟動該線程
  • 通過 Callable 和 Future 創建線程
    • 創建Callable接口的實現類,并重寫call()方法,該call()方法將作為線程執行體,并且有返回值
    • 創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值
    • 使用FutureTask對象作為Thread對象的target創建并啟動新線程
    • 調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值

    怎么驗證 MySQL 的索引是否滿足需求

    • 使用explain函數驗證索引是否有效

    事務的隔離級別

  • Read uncommitted (讀未提交):最低級別
  • Read committed (讀已提交):讀已提交,可避免臟讀情況發生。
  • Repeatable Read(可重復讀):確保事務可以多次從一個字段中讀取相同的值,在此事務持續期間,禁止其他事務對此字段的更新,可以避免臟讀和不可重復讀,仍會出現幻讀問題
  • Serializable (串行化):最嚴格的事務隔離級別,要求所有事務被串行執行,不能并發執行,可避免臟讀、不可重復讀、幻讀情況的發生
  • MySQL 常用的引擎

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

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

    • 行級鎖

    是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操作的行進行加鎖。行級鎖能大大減少數據庫操作的沖突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分為共享鎖 和 排他鎖。

    • 行級鎖的特點

    開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高。

    • 表級鎖

    表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MYISAM與INNODB都支持表級鎖定。表級鎖定分為表共享讀鎖(共享鎖)與表獨占寫鎖(排他鎖)

    • 表級鎖的特點

    開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖沖突的概率最高,并發度最低。

    • 頁級鎖

    頁級鎖是MySQL中鎖定粒度介于行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但沖突多,行級沖突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。BDB支持頁級鎖

    • 頁級鎖的特點

    開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般

    • 擴展
  • MyISAM和MEMORY采用表級鎖(tabl-level locking)
  • BDB采用頁面鎖(page-level locking)或表級鎖,默認為頁面鎖
  • InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖
  • 樂觀鎖和悲觀鎖

  • 樂觀鎖認為一般情況下數據不會造成沖突,所以在數據進行提交更新時才會對數據的沖突與否進行檢測。如果沒有沖突那就OK;如果出現沖突了,則返回錯誤信息并讓用戶決定如何去做.常見的做法有兩種:版本號控制及時間戳控制
  • 悲觀鎖,正如其名,它指的是對數據被外界(包括當前系統的其它事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個數據處理過程中,將數據處于鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排它性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)常見做法:select ... for update悲觀鎖語法鎖住記錄 兩個事務同時修改的話,事務A先執行事務B就會被阻塞,事務A執行update完后,事務B就會看到事務A執行完后更新的結果
  • MySQL 問題排查都有哪些手段

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

    如何做 MySQL 的性能優化

  • 創建索引 盡量避免全盤掃描 首先考慮在 where 和 order by 涉及的列上創建索引
  • 避免在索引上使用計算 注意就是IN關鍵字不走索引,它是走全盤掃描
  • 使用預編譯防止 sql 注入
  • 盡量將多條 SQL語句壓縮到一條 SQL 語句中
  • 最最最好的就是少用 * , 應該寫成要查詢的字段名,盡量避免在 where 條件中判斷 null
  • 盡量不用like 的前置百分比
  • 對于連續的數值,能用 between 就不要用 in
  • 在新建臨時表時,如果一次性插入數據量較大.可以用 select into 代替 create table
  • 選擇正確的存儲引擎
  • 垂直/水平分割、分庫分表、讀寫分離
  • 2|7Redis部分面試題

    Redis 是什么?有什么優點?都有哪些使用場景

    • Reids 是完全開源免費的,用C語言編寫的,遵守BSD協議, 是一個高性能的(key/value)分布式內存數據庫,基于內存運行 并支持持久化的NoSQL數據庫,是當前最熱門的NoSql數據庫之一, 也被人們稱為數據結構服務器
    • 優點
  • Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用
  • Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲
  • Redis支持數據的備份,即master-slave模式的數據備份
    • 應用場景
  • 內存存儲和持久化:redis支持異步將內存中的數據寫到硬盤上,同時不影響繼續服務
  • 取最新N個數據的操作,如:可以將最新的10條評論的ID放在Redis的List集合里面
  • 模擬類似于HttpSession這種需要設定過期時間的功能
  • 發布、訂閱消息系統
  • 定時器、計數器
  • Redis 為什么是單線程的

    • Redis是基于內存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存的大小或者網絡帶寬。既然單線程容易實現,而且CPU不會成為瓶頸

    Redis 的緩存預熱

  • 在項目配置文件中生命自定義的key ,在項目啟動時會判斷redis是否存在key ,如果沒有就會創建一個key傳入null值
  • 數據加熱的含義就是在正式部署之前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中
  • redis 緩存雪崩是什么,怎么解決 ?

    緩存雪崩是指,緩存層出現了錯誤,不能正常工作了.于是所有的請求都會達到存儲層,存儲層的調用量會暴增,造成存儲層也會掛掉的情況.

    解決方案

  • redis 高可用 就是搭建 redis 集群,其中一臺redis掛掉后 可以使用其他的 redis
  • 限流降級 就是每一個 key 只能一個線程來查詢數據和緩存,其他線程等待
  • 數據預熱 數據加熱的含義就是在正式部署之前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中.在即將發生大并發訪問前手動觸發加載緩存不同的 key ,設置不同的過期時間,讓緩存失效的時間點盡量均勻.*
  • 緩存穿透是什么?如何解決

    就是訪問redis數據庫,查不到數據,就是沒有命中,會去持久化數據庫查詢,還是沒有查到.假如高并發的情況下,持久化數據庫一下增加了很大壓力,就相當于出現了緩存穿透

    解決方案

  • 緩存空對象 在存儲層命中失敗后,即使返回空對象也將其緩存,并設置一個過期時間,之后訪問的這個數據將會從緩存中取出,很好的保護了后端數據源,這樣也會有出現問題 例如空值被緩存也就會增加大量的緩存空間,設置了過期時間還是會存在緩存層和存儲層的數據會有一段時間窗口的不一致,這對于需要保持一致性的業務會有影響
  • 布隆過濾器 對所有可能查詢的參數以 hash 形式存儲,查詢時發現值不存在就直接丟棄,不會去持久層查詢
  • Redis 支持的數據類型有哪些

    • String、List、Set、Hash、ZSet這5種

    Redis 支持的 Java 客戶端有哪些

    • Redisson、Jedis、lettuce 等等,官方推薦使用 Redisson

    Jedis 與 Redisson 有哪些區別

    • Jedis 和 Redisson 都是Java中對Redis操作的封裝。Jedis 只是簡單的封裝了 Redis 的API庫,可以看作是Redis客戶端,它的方法和Redis 的命令很類似。Redisson 不僅封裝了 redis ,還封裝了對更多數據結構的支持,以及鎖等功能,相比于Jedis 更加大。但Jedis相比于Redisson 更原生一些,更靈活

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

  • 對刪除緩存進行重試,數據的一致性要求越高,我越是重試得快。
  • 定期全量更新,簡單地說,就是我定期把緩存全部清掉,然后再全量加載。
  • 給所有的緩存一個失效期
  • Redis 持久化有幾種方式

    • 快照方式(RDB, Redis DataBase)將某一個時刻的內存數據,以二進制的方式寫入磁盤
    • 文件追加方式(AOF, Append Only File),記錄所有的操作命令,并以文本的形式追加到文件中
    • 混合持久化方式,Redis 4.0 之后新增的方式,混合持久化是結合了 RDB 和 AOF 的優點,在寫入的時候,先把當前的數據以 RDB 的形式寫入文件的開頭,再將后續的操作命令以 AOF 的格式存入文件,這樣既能保證 Redis 重啟時的速度,又能簡單數據丟失的風險

    Redis 怎么實現分布式鎖

    • SET key value [EX seconds] [PX milliseconds] [NX|XX]
    • EX second :設置鍵的過期時間為second秒
    • PX millisecond :設置鍵的過期時間為millisecond毫秒
    • NX :只在鍵不存在時,才對鍵進行設置操作
    • XX :只在鍵已經存在時,才對鍵進行設置操作
    • SET操作成功完成時,返回OK ,否則返回nil

    Redis 分布式鎖有什么缺陷

  • 死鎖
    • 設置鎖的過期時間,且需要保證setNx和設置過期時間操作的原子性
  • 錯位解鎖
    • 加鎖時記錄當前線程ID,解鎖時判斷ID是否一致
    • 解鎖時,查詢redis里記錄鎖的ID,以及刪除redis中鎖的記錄,這兩步操作可以使用lua腳本保持原子性
  • 業務并發執行問題
    • 加鎖成功后開啟守護線程,當臨近過期時間,業務還未完成時,開始續時,重復此步驟直到業務完成

    Redis 如何做內存優化

    • 縮減鍵值對象:滿足業務要求下 key 越短越好;value 值進行適當壓縮
    • 共享對象池:即 Redis 內部維護[0-9999]的整數對象池,開發中在滿足需求的前提下,盡量使用整數對象以節省內存
    • 盡可能使用散列表(hashes)
    • 編碼優化,控制編碼類型
    • 控制 key 的數量

    Redis 淘汰策略有哪些

    • noeviction: 不刪除策略, 達到最大內存限制時, 如果需要更多內存, 直接返回錯誤信息。 大多數寫命令都會導致占用更多的內存(有極少數會例外, 如 DEL )
    • allkeys-lru: 所有key通用; 優先刪除最近最少使用(less recently used ,LRU) 的 key
    • volatile-lru: 只限于設置了 expire 的部分; 優先刪除最近最少使用(less recently used ,LRU) 的 key
    • allkeys-random: 所有key通用; 隨機刪除一部分 key
    • volatile-random: 只限于設置了 expire 的部分; 隨機刪除一部分 key
    • volatile-ttl: 只限于設置了 expire 的部分; 優先刪除剩余時間(time to live,TTL) 短的key

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

  • 緩存和數據庫雙寫一致性問題
    • 就是如果對數據有強一致性要求,不能放緩存。我們所做的一切,只能保證最終一致性
    • 采取正確更新策略,先更新數據庫,再刪緩存。其次,因為可能存在刪除緩存失敗的問題,提供一個補償措施即可,例如利用消息隊列
  • 緩存穿透問題
    • 利用互斥鎖,緩存失效的時候,先去獲得鎖,得到鎖了,再去請求數據庫。沒得到鎖,則休眠一段時間重試
    • 采用異步更新策略,無論 Key 是否取到值,都直接返回。Value 值中維護一個緩存失效時間,緩存如果過期,異步起一個線程去讀數據庫,更新緩存。需要做緩存預熱(項目啟動前,先加載緩存)操作
    • 提供一個能迅速判斷請求是否有效的攔截機制,比如,利用布隆過濾器,內部維護一系列合法有效的 Key。迅速判斷出,請求所攜帶的 Key 是否合法有效。如果不合法,則直接返回
  • 緩存雪崩問題
    • 給緩存的失效時間,加上一個隨機值,避免集體失效
    • 使用互斥鎖,但是該方案吞吐量明顯下降
    • 雙緩存。我們有兩個緩存,緩存 A 和緩存 B。緩存 A 的失效時間為 20 分鐘,緩存 B 不設失效時間。自己做緩存預熱操作(從A中讀不到,就去B讀,返回數據時需要異步啟動一個更新線程,更新線程同時更新緩存 A 和緩存 B)
  • 緩存的并發競爭問題
  • 如果對這個 Key 操作,不要求順序
    • 這種情況下,準備一個分布式鎖,大家去搶鎖,搶到鎖就做 set 操作即可,比較簡單。
  • 如果對這個 Key 操作,要求順序
    • 假設有一個 key1,系統 A 需要將 key1 設置為 valueA,系統 B 需要將 key1 設置為 valueB,系統 C 需要將 key1 設置為 valueC
    • 期望按照 key1 的 value 值按照 valueA > valueB > valueC 的順序變化。這種時候我們在數據寫入數據庫的時候,需要保存一個時間戳。
    • 系統A key 1 {valueA 3:00}
    • 系統B key 1 {valueB 3:05}
    • 系統C key 1 {valueC 3:10}
    • 那么,假設這會系統 B 先搶到鎖,將 key1 設置為{valueB 3:05}。接下來系統 A 搶到鎖,發現自己的 valueA 的時間戳早于緩存中的時間戳,那就不做 set 操作了,以此類推。
    • 其他方法,比如利用隊列,將 set 方法變成串行訪問也可以。總之,靈活變通。

    2|8RabbitMQ部分面試題

    RabbitMq 的使用場景有哪些

  • 多個應用之間的耦合
  • 跨系統的異步通信
  • 流量削峰
    • 比如:注冊用戶、發送激活郵箱、訂單下單等

    RabbitMq 有哪些重要的角色

    • 生產者:消息的創建者,負責創建和推送數據到消息服務器
    • 消費者:消息的接收方,負責處理數據和確認消息
    • 代理:就是RabbiMQ本身,不生產不消費,只是快遞消息

    RabbitMq 有哪些重要的組件

    • ConnectionFactory(連接管理器):應用程序與Rabbit之間建立連接的管理器,程序代碼中使用
    • Channel(信道):消息推送使用的通道
    • Exchange(交換器):用于接受、分配消息
    • Queue(隊列):用于存儲生產者的消息
    • RoutingKey(路由鍵):用于把生成者的數據分配到交換器上
    • BindingKey(綁定鍵):用于把交換器的消息綁定到隊列上

    RabbitMQ的消息存儲方式

    RabbitMQ 對于 queue 中的 message 的保存方式有兩種方式:disc ram.如果采用disc,則需要對 exchange/queue/delivery mode 都要設置成 durable 模式. Disc 方式的好處是當 RabbitMQ 失效了, message 仍然可以在重啟之后恢復.而使用 ram 方式, RabbitMQ 處理 message 的效率要高很多, ram 和 disc 兩種方式的效率比大概是 3:1.所以如果在有其它 HA 手段保障的情況下,選用 ram 方式是可以提高消息隊列的工作效率的.

    RabbitMq 中 vhost 的作用是什么

    • vhost本質上是一個mini版的RabbitMQ服務器,擁有自己的隊列、綁定、交換器和權限控制
    • 從 RabbitMQ 的全局角度 vhost可以作為不同權限隔離的手段(一個典型的例子,不同的應用可以跑在不同的vhost中)

    RabbitMq 的消息是怎么發送的

    • 生產者把生產的小心通過channel發送到Exchange上,Exchange通過綁定的router key來選擇Queue,消費者監聽到Queue上有新的消息,就消費調此消息

    RabbitMq 怎么保證消息的穩定性

    • 提供了事務的功能,通過將 channel 設置為 confirm(確認模式)

    RabbitMq 怎么避免丟失消息

  • 消息持久化
  • 消費端的ack簽收機制
  • 設置集群鏡像模式
  • 消息補償機制
  • 要保證消息持久化成功的條件有哪些

  • 聲明隊列必須設置持久化 durable 設置為 true
  • 消息推送投遞模式必須設置持久化,deliveryMode 設置為 2(持久)
  • 消息已經到達持久化交換器
  • 消息已經到達持久化隊列
    • 以上四個條件都滿足才能保證消息持久化成功

    RabbitMq 持久化有什么缺點

    • 持久化的缺點就是降低了服務器的吞吐量,因為使用的是磁盤而非內存存儲,從而降低了吞吐量。可盡量使用 ssd 硬盤來緩解吞吐量的問題

    RabbitMq 有幾種廣播方式

  • fanout廣播模式:所有bind到此exchange的queue都可以接收消息
  • direct直接交換:通過routingKey和exchange決定的那個唯一的queue可以接收消息
  • topic通配符模式:所有符合routingKey(此時可以是一個表達式)的routingKey所bind的queue可以接收消息
  • RabbitMq 怎么實現延遲消息隊列

    • 通過消息過期后進入死信交換器,再由交換器轉發到延遲消費隊列,實現延遲功能
    • 使用 RabbitMQ-delayed-message-exchange 插件實現延遲功能。

    RabbitMq 集群有什么用

    • 高可用:某個服務器出現問題,整個 RabbitMQ 還可以繼續使用
    • 高容量:集群可以承載更多的消息量。

    RabbitMq 節點的類型有哪些

    • 磁盤節點:消息會存儲到磁盤
    • 內存節點:消息都存儲在內存中,重啟服務器消息丟失,性能高于磁盤類型

    RabbitMq 集群搭建需要注意哪些問題

  • 各節點之間使用–link連接,此屬性不能忽略
  • 各節點使用的 erlang cookie 值必須相同,此值相當于秘鑰的功能,用于各節點的認證
  • 整個集群中必須包含一個磁盤節點
  • RabbitMq 每個節點是其他節點的完整拷貝嗎

    不是

    • 如果每個節點都擁有所有隊列的完全拷貝,這樣新增節點,不但沒有新增存儲空間,反而增加了更多的冗余數據
    • 如果每條消息都需要完整拷貝到每一個集群節點,那新增節點并沒有提升處理消息的能力,最多是保持和單節點相同的性能甚至是更糟

    RabbitMq 集群中唯一一個磁盤節點崩潰了會發生什么

    • 唯一磁盤節點崩潰了,集群是可以保持運行的,但不能更改任何東西
  • 不能創建隊列
  • 不能創建交換器
  • 不能創建綁定
  • 不能添加用戶
  • 不能更改權限
  • 不能添加和刪除集群節點
  • RabbitMq 對集群停止順序有要求嗎

    • RabbitMQ 對集群的停止的順序是有要求的,應該先關閉內存節點,最后再關閉磁盤節點。如果順序恰好相反的話,可能會造成消息的丟失

    2|9JVM部分面試題

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

  • 類加載器(Class Loader):加載類文件到內存。Class loader只管加載,只要符合文件結構就加載,至于能否運行,它不負責,那是有Exectution Engine 負責的
  • 執行引擎(Execution Engine):也叫解釋器,負責解釋命令,交由操作系統執行
  • 本地庫接口(Native Interface):本地接口的作用是融合不同的語言為java所用
  • 運行時數據區(Runtime Data Area)
  • JVM 運行時數據區是什么

    • 堆是java對象的存儲區域,任何用new字段分配的java對象實例和數組,都被分配在堆上,java堆可用-Xms和-Xmx進行內存控制,
    • 常量池:運行時常量池是方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后進入方法區的運行時常量池中存放,jdk1.7以后,運行時常量池從方法區移到了堆上
    • 方法區:用于存儲已被虛擬機加載的類信息,常量,靜態變量,即是編譯器編譯后的代碼等數據
    • 虛擬機棧:虛擬機棧中執行每個方法的時候,都會創建一個棧楨用于存儲局部變量表,操作數棧,動態鏈接,方法出口等信息
    • 本地方法棧:與虛擬機發揮的作用相似,相比于虛擬機棧為Java方法服務,本地方法棧為虛擬機使用的Native方法服務,執行每個本地方法的時候,都會創建一個棧幀用于存儲局部變量表,操作數棧,動態鏈接,方法出口等信息
    • 程序計數器:指示Java虛擬機下一條需要執行的字節碼指令

    堆和棧的區別

  • 棧內存用來存儲局部變量和方法調用
  • 而堆內存用來存儲 Java 中的對象.無論是成員變量,局部變量,還是類變量.,它們指向的對象都存儲在堆內存中.
  • 棧內存歸屬單個線程,一個棧對應一個線程,其中儲存的變量只能在該線程中可以訪問到,也可以理解為私有內存
  • 而堆內存中的對象 所有線程均可見,堆內存中對象可以被所有線程訪問到
  • 棧內存要遠小于堆內存
  • 隊列和棧是什么?有什么區別

    • 隊列和棧是兩種不同的數據結構
  • 操作名稱不同
    • 隊列的插入稱為入隊,隊列的刪除稱為出隊。棧的插入稱為進棧,棧的刪除稱為出棧
  • 可操作的方式不同
    • 隊列是在隊尾入隊,隊頭出隊,即兩邊都可操作。而棧的進棧和出棧都是在棧頂進行的,無法對棧底直接進行操作。

    • 隊列先進先出 FIFO,棧是后進先出 LIFO

    類加載器有哪些?什么是雙親委派模型

  • 啟動類加載器 Bootstrap ClassLoader:加載lib目錄下核心庫
  • 擴展類加載器 Extension ClassLoader:加載libext目錄下擴展包
  • 應用程序類加載器 Application ClassLoader: 加載用戶路徑(classpath)上指定的類庫
  • 雙親委派的意思是如果一個類加載器需要加載類,那么首先它會把這個類請求委派給父類加載器去完成,每一層都是如此。一直遞歸到頂層,當父加載器無法完成這個請求時,子類才會嘗試去加載。這里的雙親其實就指的是父類,沒有mother。父類也不是我們平日所說的那種繼承關系,只是調用邏輯是這樣

    類加載的執行過程

    • 加載
  • 加載指的是把class字節碼文件從各個來源通過類加載器裝載入內存中
  • 字節碼來源:一般的加載來源包括從本地路徑下編譯生成的.class文件,從jar包中的.class文件,從遠程網絡,以及動態代理實時編譯類加載器。一般包括啟動類加載器,擴展類加載器,應用類加載器,以及用戶的自定義類加載器
    • 鏈接
  • 驗證
  • 主要是為了保證加載進來的字節流符合虛擬機規范,不會造成安全錯誤,包括對于文件格式的驗證

  • 準備
  • 主要是為類變量(注意,不是實例變量)分配內存,并且賦予初值。特別需要注意,初值,不是代碼中具體寫的初始化的值,而是Java虛擬機根據不同變量類型的默認初始值:8種基本類型的初值,默認為0;引用類型的初值則為null;

  • 解析
  • 將常量池內的符號引用替換為直接引用的過程。在解析階段,虛擬機會把所有的類名,方法名,字段名這些符號引用替換為具體的內存地址或偏移量,也就是直接引用

    • 初始化

    這個階段主要是對類變量初始化,是執行類構造器的過程

    怎么判斷對象是否可以收回

  • 引用計數算法
    • 判斷對象的引用數量
  • 通過判斷對象的引用數量來決定對象是否可以被回收
  • 每個對象實例都有一個引用計數器,被引用則+1,完成引用則-1
  • 任何引用計數為0的對象實例可以被當作垃圾收集
    • 優缺點
  • 優點:執行效率高,程序執行受影響較小
  • 缺點:無法檢測出循環引用的情況,導致內存泄漏
  • 可達性分析算法
    • 通過判斷對象的引用鏈是否可達來決定對象是否可以被回收
    • 可以作為GC Root對象的對象有
  • 虛擬機棧中引用的對象(棧幀中的本地變量表)
  • 方法區中的常量引用對象
  • 方法區中類靜態屬性引用對象
  • 本地方法棧中JNI(Native方法)的引用對象
  • 活躍線程中的引用對象
  • Java 中有哪些引用類型

  • 強引用(strongreference)
  • 就是指在程序代碼之中普遍存在的,類似“Object obj=new Object()” 這類的引用,只要強引用還存在,垃圾收集器永遠不會回收掉被引用的對象實例

  • 軟引用(softreference)
  • 是用來描述一些還有用但并非必需的對象。對于軟引用關聯著的對象, 在系統將要發生內存溢出異常之前,將會把這些對象實例列進回收范圍之中進行 第二次回收。如果這次回收還沒有足夠的內存,才會拋出內存溢出異常。在 JDK 1.2 之后,提供了SoftReference 類來實現軟引用

  • 弱引用(weakreference)
  • 也是用來描述非必需對象的,但是它的強度比軟引用更弱一些,被弱 引用關聯的對象實例只能生存到下一次垃圾收集發生之前。當垃圾收集器工作時, 無論當前內存是否足夠,都會回收掉只被弱引用關聯的對象實例。在 JDK 1.2 之 后,提供了WeakReference 類來實現弱引用

  • 虛引用(phantomreference)
  • 也稱為幽靈引用或者幻影引用,它是最弱的一種引用關系。一個對象實例是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用 來取得一個對象實例。為一個對象設置虛引用關聯的唯一目的就是能在這個對象 實例被收集器回收時收到一個系統通知。在 JDK 1.2 之后,提供了 PhantomReference 類來實現虛引用

    JVM 垃圾回收算法

  • 標記-清除算法
  • 標記-清除算法采用從根集合(GC Roots)進行掃描,對存活的對象進行標記,標記完畢后,再掃描整個空間中未被標記的對象,進行回收,如下圖所示。標記-清除算法不需要進行對象的移動,只需對不存活的對象進行處理,在存活對象比較多的情況下極為高效,但由于標記-清除算法直接回收不存活的對象,因此會造成內存碎片

  • 復制除算法
  • 復制算法的提出是為了克服句柄的開銷和解決內存碎片的問題。它開始時把堆分成 一個對象 面和多個空閑面, 程序從對象面為對象分配空間,當對象滿了,基于copying算法的垃圾 收集就從根集合(GC Roots)中掃描活動對象,并將每個 活動對象復制到空閑面(使得活動對象所占的內存之間沒有空閑洞),這樣空閑面變成了對象面,原來的對象面變成了空閑面,程序會在新的對象面中分配內存

  • 標記-整理(壓縮)算法
  • 標記-整理算法采用標記-清除算法一樣的方式進行對象的標記,但在清除時不同,在回收不存活的對象占用的空間后,會將所有的存活對象往左端空閑空間移動,并更新對應的指針。標記-整理算法是在標記-清除算法的基礎上,又進行了對象的移動,因此成本更高,但是卻解決了內存碎片的問題

    JVM 有哪些垃圾回收器

    • 新生代收集器:Serial、ParNew、Parallel Scavenge
    • 老年代收集器:CMS、Serial Old、Parallel Old
    • 整堆收集器: G1

    介紹一下 CMS 垃圾回收器

    • CMS收集器 :一種以獲取最短回收停頓時間為目標的收集器
    • 特點:基于標記-清除算法實現。并發收集、低停頓
    • 應用場景:適用于注重服務的響應速度,希望系統停頓時間最短,給用戶帶來更好的體驗等場景下。如web程序、b/s服務
    • CMS收集器的運行過程分為下列4步:
  • 初始標記:標記GC Roots能直接到的對象,速度很快但是仍存在Stop The World問題
  • 并發標記:進行GC Roots Tracing 的過程,找出存活對象且用戶線程可并發執行
  • 重新標記:為了修正并發標記期間因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄。仍然存在Stop The World問題
  • 并發清除:對標記的對象進行清除回收
    • CMS收集器的內存回收過程是與用戶線程一起并發執行的
    • CMS收集器的缺點:
    • 對CPU資源非常敏感
    • 無法處理浮動垃圾,可能出現Concurrent Model Failure失敗而導致另一次Full GC的產生
    • 因為采用標記-清除算法所以會存在空間碎片的問題,導致大對象無法分配空間,不得不提前觸發一次Full GC

    CMS收集器的工作過程圖:

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

    • 新生代收集器:Serial、ParNew、Parallel Scavenge
    • 老年代收集器:CMS、Serial Old、Parallel Old
    • 區別:

    新生代垃圾回收器一般采用的是復制算法,復制算法的優點是效率高,缺點是內存利用率低;老年代回收器一般采用的是標記-整理的算法進行垃圾回收

    簡述分代垃圾回收器是怎么工作的

    • 分代回收器有兩個分區:老生代和新生代,新生代默認的空間占比總空間的 1/3,老生代的默認占比是 2/3。 新生代使用的是復制算法,新生代里有 3 個分區:Eden、To Survivor、From Survivor,它們的默認占比是 8:1:1
    • 執行流程
  • 把 Eden + From Survivor 存活的對象放入 To Survivor 區
  • 清空 Eden 和 From Survivor 分區; From Survivor 和 To Survivor 分區交換,From Survivor 變 To Survivor,To Survivor 變 From Survivor
  • 每次在 From Survivor 到 To Survivor 移動時都存活的對象,年齡就 +1,當年齡到達 15(默認配置是 15)時,升級為老生代。大對象也會直接進入老生代
  • 老生代當空間占用到達某個值之后就會觸發全局垃圾收回,一般使用標記整理的執行算法
  • 以上這些循環往復就構成了整個分代垃圾回收的整體執行流程
  • JVM 調優的工具有哪些

    • jconsole jdk自帶的工具:是一個基于JMX(java management extensions)的GUI性能監測工具(jdk/bin目錄下點擊jconsole.exe即可啟動)
    • VisualVM:它提供了一個可視界面,用于查看 Java 虛擬機 (Java Virtual Machine, JVM) 上運行的基于 Java 技術的應用程序(Java 應用程序)的詳細信息(jdk/bin目錄下面雙擊jvisualvm.exe既可使用)
    • MAT 第三方調優工具:一個基于Eclipse的內存分析工具,是一個快速、功能豐富的Java heap分析工具,它可以幫助我們查找內存泄漏和減少內存消耗(MAT以eclipse 插件的形式來安裝)
    • GChisto:專業分析gc日志的工具,可以通過gc日志來分析:Minor GC、full gc的時間、頻率等等,通過列表、報表、圖表等不同的形式來反應gc的情況(配置好本地的jdk環境之后,雙擊GChisto.jar,在彈出的輸入框中點擊 add 選擇gc.log日志)
    • gcviewer:分析小工具,用于可視化查看由Sun / Oracle, IBM, HP 和 BEA Java 虛擬機產生的垃圾收集器的日志

    JVM 調優的參數有哪些

    2|10算法題

    2|11其他部分面試題

    Api 接口如何實現 ?

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

    MySQL 鏈接數據庫常用的幾種方式 ?

  • Mybatis 框架
  • Hibernate 框架
  • JDBC 技術
  • c3p0 連接池
  • dbcp 連接池
  • SpringBoot 如何集成 Redis ?

    在 pom.xml 文件引入 redis 依賴

    org.springframework.boot spring-boot-starter-data-redis

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

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

    SpringCloud 的優點 ?

  • 服務之間采用Restful等輕量級通訊
  • 精準的制定優化服務方案,提高系統的可維護性
  • 服務之間拆分細致,資源可重復利用,提高開發效率
  • SpringCloud 用了哪些組件 ?

  • netflix Eureka 注冊中心
  • netflix Ribbon 負載均衡
  • netflix Zuul 網關
  • netflix Hystrix 熔斷器
  • feign 服務調用
  • List 和 Set 的區別

  • List 允許有多個重復對象,而 Set 不允許有重復對象
  • List 允許有多個NULL值,而 Set 只允許有一個NULL值
  • List 是一個有序的容器,輸出順序即是輸入順序
  • Set 是一個無序的容器無法保證每個元素的順序,但是可以用 TreeSet 通過 Comparator 或者 Comparable 維護排序順序
  • List的實現類有 ArrayList、LinkList、Vector 其中 ArrayList 最常用于查詢較多,隨意訪問.LinkList 同于新增和刪除較多的情況,Vector 表示底層數組,線程安全象
  • Set的實現類有 HashSet、TreeSet、LinkedHashSet 其中基于 HashMap 實現的 HashSet 最為流行,TreeSet 是一個有序的Set容器象
  • 擴展 Map的實現類有HashMap、HashTable、TreeMap

    Java 中 static 的作用

  • 表示全局或靜態的意思、用來修飾成員變量和成員方法,也可以形成靜態代碼塊
  • 達到了不用實例化就可以使用被 public static 修飾的變量或方法
  • 什么單例模式 ?

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

  • 單例模式的好處:
  • 單例模式節省公共資源
  • 單例模式方便控制
  • 如何保證是單利模式 ?
  • 構造私有化
  • 以靜態方法返回實例
  • 確保對象實例只有一個
  • 單例模式有哪幾個 ?
  • 餓漢模式
  • 把對象創建好,需要使用的時候直接拿到就行

  • 懶漢模式
  • 等你需要的時候在創建對象,后邊就不會再次創建

    SpringBoot 常用的幾個注解 ?

  • @SpringBootApplication SpringBoot的核心注解 啟動類
  • @EnableAutoConfiguration 開啟SpringBoot自動配置
  • @RestController 在控制層 是@ResponseBody注解與@Controller注解的合集
  • @RequestMapper 處理請求地址映射的注解
  • @RequestParam 獲取url上傳過來的參數
  • @Configuration 聲明配置類
  • @Component 通用注解
  • @Service 業務邏輯層
  • Java 八大數據類型

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

    float 單浮點型 double 雙浮點型

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

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

  • 可以用 limit
  • select name,age,sex from t_student limit(0,5);

  • 升序 order by xx asc
  • select name,age,sex from t_student order by age asc;

  • 降序 order by xx desc
  • select name,age,sex from t_student order by age desc;

    maven 是干什么的,它有什么好處 ?

  • maven 專門構建和管理Java項目的工具
  • maven的好處在于可以將項目過程規范化、自動化、高效化以及強大的可擴展性
  • MySQL 如何添加索引 ?

  • PRIMARY KEY (主鍵索引)
  • 添加INDEX(普通索引) ALTER TABLE table_name ADD INDEX index_name ( column )
  • 添加UNIQUE(唯一索引) ALTER TABLE table_name ADD UNIQUE index_name ( column )
  • 添加FULLTEXT(全文索引) ALTER TABLE table_name ADD FULLTEXT ( column)
  • 添加多列索引 ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )
  • MySQL 索引的實現方式?

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

    Vue的數據雙向綁定原理

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

    ActiveMQ的消息存儲方式

    • 采取先進先出模式,同一時間,消息只會發送給某一個消費者,只有當該消息被消費并告知已收到時,它才能在代理的存儲中被刪除.
    • 對于持久性訂閱來說,每一個消費者都會獲取消息的拷貝.為了節約空間,代理的存儲介質中只存儲了一份消息,存儲介質的持久訂閱對象為其以后的被存儲的消息維護了一個指針,消費者消費時,從存儲介質中復制一個消息.消息被所有訂閱者獲取后才能刪除.

    KahaDB消息存儲

    基于文件的消息存儲機制,為了提高消息存儲的可靠性和可恢復性,它整合了一個事務日志.KahaDB擁有高性能和可擴展性等特點.由于KahaDB使用的是基于文件的存儲,所以不需要使用第三方數據庫

    學習沒資料,面試找不到方向怎么辦?

    下面是針對一到五年開發的Java程序員整理的Java實戰視頻+電子版本書籍+面試試題資料文檔分享給大家學習!

    面試試題資料及答案:

    面試試題資料

    電子版本書籍:

    電子版本書籍

    電子書

    領取步驟:

    1、轉發+點贊文章

    2、關注我,私信“電子書”,即可免費領取

    總結

    以上是生活随笔為你收集整理的java array 元素的位置_Java常见面试题 非常实用「个人经验」的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。