<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java面試題總結

      一、Java集合框架是什么?說出一些集合框架的優點?

      每種編程語言中都有集合,最初的Java版本包含幾種集合類:Vector、Stack、HashTable和Array。隨著集合的廣泛使用,Java 1.2提出了囊括所有集合接口、實現和算法的集合框架。在保證線程安全的情況下使用泛型和并發集合類,Java已經經歷了很久。它還包括在Java并發包中,阻塞接口以及它們的實現。
      集合框架的部分優點如下:

      1. 降低開發成本:使用核心集合類降低開發成本,而非實現我們自己的集合類。
      2. 提高代碼質量:隨著使用經過嚴格測試的集合框架類,代碼質量會得到提高。
      3. 降低維護成本:通過使用JDK附帶的集合類,可以降低代碼維護成本。
      4. 復用性和可操作性 。

      二、集合框架中的泛型有什么優點?

      Java 1.5引入了泛型,所有的集合接口和實現都大量地使用它。泛型允許我們為集合提供一個可以容納的對象類型,因此,如果你添加其它類型的任何元素,它會在編譯時報錯。這避免了在運行時出現ClassCastException,因為你將會在編譯時得到報錯信息。泛型也使得代碼整潔,我們不需要使用顯式轉換和instanceOf操作符。它也給運行時帶來好處,因為不會產生類型檢查的字節碼指令。

      三、Java集合框架的基礎接口有哪些?

      1. Collection:為集合層級的根接口。一個集合代表一組對象,這些對象即為它的元素。Java平臺不提供這個接口任何直接的實現。
      2. Set:是一個不能包含重復元素的集合。這個接口對數學集合抽象進行建模,被用來代表集合,就如一副牌。
      3. List:是一個有序集合,可以包含重復元素。你可以通過它的索引來訪問任何元素。List更像長度動態變換的數組。
      4. Map:是一個將key映射到value的對象.一個Map不能包含重復的key:每個key最多只能映射一個value。
      5. 一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

      四、為何Collection不從Cloneable和Serializable接口繼承?

      Collection接口指定一組對象,對象即為它的元素。如何維護這些元素由Collection的具體實現決定。例如,一些如List的Collection實現允許重復的元素,而其它的如Set就不允許。很多Collection實現有一個公有的clone方法。然而,把它放到集合的所有實現中也是沒有意義的。這是因為Collection是一個抽象表現。重要的是實現。

      當與具體實現打交道的時候,克隆或序列化的語義和含義才發揮作用。所以,具體實現應該決定如何對它進行克隆或序列化,或它是否可以被克隆或序列化。

      在所有的實現中授權克隆和序列化,最終導致更少的靈活性和更多的限制。特定的實現應該決定它是否可以被克隆和序列化。

      五、為何Map接口不繼承Collection接口?

      盡管Map接口和它的實現也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map繼承Collection毫無意義,反之亦然。

      如果Map繼承Collection接口,那么元素去哪兒?Map包含key - value對,它提供抽取key或value列表集合的方法,但是它不適合“一組對象”規范。

      六、Iterator是什么?

      Iterator接口提供遍歷任何Collection的接口。我們可以從一個Collection中使用迭代器方法來獲取迭代器實例。迭代器取代了Java集合框架中的Enumeration。迭代器允許調用者在迭代過程中移除元素。

      七、Enumeration和Iterator接口的區別?

      1. 速度和內存:Enumeration的速度是Iterator的兩倍,也使用更少的內存。Enumeration是非常基礎的,也滿足了基礎的需要。
      2. 安全性:與Enumeration相比,Iterator更加安全,因為當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。
      3. 移除元素:迭代器允許調用者從集合中移除元素,而Enumeration不能做到。為了使它的功能更加清晰,迭代器方法名已經經過改善。

      八、為何沒有像Iterator.add()這樣的方法,向集合中添加元素?

      語義不明,已知的是,Iterator的協議不能確保迭代的次序。然而要注意,ListIterator沒有提供一個add操作,它要確保迭代的順序。

      九、為何迭代器沒有一個方法可以直接獲取下一個元素,而不需要移動游標?

      它可以在當前Iterator的頂層實現,但是它用得很少,如果將它加到接口中,每個繼承都要去實現它,這沒有意義。

      十、Iterater和ListIterator之間有什么區別?

      1. 遍歷范圍:我們可以使用Iterator來遍歷Set和List集合,而ListIterator只能遍歷List。
      2. 遍歷方向:Iterator只可以向前遍歷,而LIstIterator可以雙向遍歷。
      3. 額外功能:ListIterator從Iterator接口繼承,然后添加了一些額外的功能,比如添加一個元素、替換一個元素、獲取前面或后面元素的索引位置。

      十一、遍歷一個List有哪些不同的方式?

      List<String> strList = new ArrayList<>();
      //使用for - each循環
      for(String obj : strList){
         
          System.out.println(obj);
      }
      //using iterator
      Iterator<String> it = strList.iterator();
      while(it.hasNext()){
         
          String obj = it.next();
          System.out.println(obj);
      }
       
       

      使用迭代器更加線程安全,因為它可以確保,在當前遍歷的集合元素被更改的時候,它會拋出ConcurrentModificationException。

      十二、通過迭代器fail - fast屬性,你明白了什么?

      每次我們嘗試獲取下一個元素的時候,Iterator fail - fast屬性檢查當前集合結構里的任何改動。如果發現任何改動,它拋出ConcurrentModificationException。Collection中所有Iterator的實現都是按fail - fast來設計的(ConcurrentHashMap和CopyOnWriteArrayList這類并發集合類除外)。

      十三、fail - fast與fail - safe有什么區別?

      1. 作用方式:Iterator的fail - fast屬性與當前的集合共同起作用,因此它不會受到集合中任何改動的影響。Java.util包中的所有集合類都被設計為fail - fast的,而java.util.concurrent中的集合類都為fail - safe的。
      2. 異常拋出:Fail - fast迭代器拋出ConcurrentModificationException,而fail - safe迭代器從不拋出ConcurrentModificationException。

      十四、在迭代一個集合的時候,如何避免ConcurrentModificationException?

      1. 同步操作:在遍歷一個集合的時候,我們可以使用并發集合類來避免ConcurrentModificationException。例如使用CopyOnWriteArrayList來替換ArrayList。
      2. 使用迭代器的remove方法:邊遍歷邊修改Collection的唯一正確方式是使用Iterator.remove()方法。

      十五、怎么確保一個集合不能被修改?

      可以使用Collections.unmodifiableCollection(Collection c)方法來創建一個只讀集合,這樣改變集合的任何操作都會拋出Java.lang.UnsupportedOperationException異常。
      示例代碼如下:

      List list = new ArrayList<>();
      list.add("x");
      Collection clist = Collections.unmodifiableCollection(list);
      clist.add("y"); // 運行時此行報錯
      System.out.println(list.size());
       
       

      十六、ArrayList和LinkedList的區別是什么?

      1. 底層數據結構:ArrayList是基于數組實現的,LinkedList是基于雙向鏈表實現的。
      2. 隨機訪問性能:ArrayList支持快速隨機訪問,時間復雜度為O(1),因為它可以通過數組索引直接訪問元素。而LinkedList的隨機訪問性能較差,時間復雜度為O(n),因為它需要遍歷鏈表來找到指定位置的元素。
      3. 插入和刪除性能:在ArrayList中,插入和刪除元素可能需要移動大量元素,尤其是在數組中間位置進行操作時,時間復雜度為O(n)。而LinkedList的插入和刪除操作只需要修改相鄰節點的引用,時間復雜度為O(1),但如果要找到指定位置的節點,仍然需要O(n)的時間。
      4. 內存占用:ArrayList的內存占用相對較小,因為它只需要存儲元素本身。而LinkedList每個節點除了存儲元素外,還需要存儲兩個引用(指向前一個和后一個節點),因此內存占用較大。

      十七、HashMap和HashTable的區別是什么?

      1. 線程安全性:HashMap是非線程安全的,HashTable是線程安全的,HashTable使用了synchronized關鍵字來保證線程安全。
      2. null鍵值對:HashMap的key和value都允許為null,但是HashTable的key和value都不允許為null。
      3. 性能:由于HashTable是線程安全的,所以在單線程環境下,HashMap的性能要高于HashTable。
      4. 初始容量和擴容機制:HashMap的初始容量為16,擴容每次都是2的n次冪。HashTable的初始容量為11,擴容是原來的2倍加1。

      十八、HashSet和TreeSet的區別是什么?

      1. 底層數據結構:HashSet基于HashMap實現,使用哈希表存儲元素。TreeSet基于紅黑樹實現,元素按照自然順序或自定義順序排序。
      2. 元素順序:HashSet中的元素是無序的,插入順序和存儲順序不一定相同。而TreeSet中的元素是有序的,可以按照自然順序(如數字從小到大、字符串按字典序)或通過實現Comparator接口來定義自定義順序。
      3. 添加和查詢性能:HashSet的添加和查詢操作平均時間復雜度為O(1),因為它使用哈希表進行快速查找。TreeSet的添加和查詢操作時間復雜度為O(log n),因為紅黑樹的高度是對數級別的。
      4. 唯一性保證:HashSet通過hashCode()和equals()方法來保證元素的唯一性。TreeSet通過比較元素的順序來保證唯一性,如果兩個元素比較相等,則不會同時存在于TreeSet中。

      十九、ConcurrentHashMap的實現原理是什么?

      1. JDK 1.7:在JDK 1.7中,ConcurrentHashMap采用分段鎖機制,它將數據分成多個段(Segment),每個段都有自己的鎖。當一個線程訪問某個段時,不會影響其他段的訪問,從而提高了并發性能。每個Segment類似于一個小型的HashMap,包含一個數組和鏈表。
      2. JDK 1.8:在JDK 1.8中,ConcurrentHashMap摒棄了分段鎖機制,采用CAS(Compare and Swap)操作和Synchronized關鍵字相結合的方式。它的底層數據結構和HashMap類似,也是數組 + 鏈表 + 紅黑樹。在進行插入、刪除、查詢等操作時,首先通過CAS操作嘗試更新數據,如果失敗,則使用Synchronized關鍵字對節點進行加鎖,以保證線程安全。

      二十、如何遍歷HashMap和HashTable?

      遍歷HashMap

      HashMap<String, Integer> hashMap = new HashMap<>();
      hashMap.put("one", 1);
      hashMap.put("two", 2);
      // 使用entrySet遍歷
      for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
         
          System.out.println(entry.getKey() + " : " + entry.getValue());
      }
      // 使用keySet遍歷
      for (String key : hashMap.keySet()) {
         
          System.out.println(key + " : " + hashMap.get(key));
      }
       
       

      遍歷HashTable

      Hashtable<String, Integer> hashtable = new Hashtable<>();
      hashtable.put("one", 1);
      hashtable.put("two", 2);
      // 使用entrySet遍歷
      for (Map.Entry<String, Integer> entry : hashtable.entrySet()) {
         
          System.out.println(entry.getKey() + " : " + entry.getValue());
      }
      // 使用keySet遍歷
      for (String key : hashtable.keySet()) {
         
          System.out.println(key + " : " + hashtable.get(key));
      }
       
       

      二十一、如何實現一個線程安全的List?

      1. 使用Vector:Vector是Java早期提供的一個線程安全的List實現,它的方法都使用了synchronized關鍵字進行同步。但是由于同步機制的開銷,性能相對較低。
      2. 使用Collections.synchronizedList():可以通過Collections類的synchronizedList()方法將一個普通的List轉換為線程安全的List。
      List<String> list = new ArrayList<>();
      List<String> synchronizedList = Collections.synchronizedList(list);
       
       
      1. 使用CopyOnWriteArrayList:CopyOnWriteArrayList是Java并發包提供的一個線程安全的List實現。它的原理是在進行寫操作(如添加、刪除元素)時,會先復制一個新的數組,在新數組上進行操作,操作完成后再將原數組引用指向新數組。讀操作則直接讀取原數組,這樣讀操作和寫操作可以并發進行,并且讀操作不會受到寫操作的影響。

      二十二、如何實現一個線程安全的Set?

      1. 使用Collections.synchronizedSet():通過Collections類的synchronizedSet()方法將一個普通的Set轉換為線程安全的Set。
      Set<String> set = new HashSet<>();
      Set<String> synchronizedSet = Collections.synchronizedSet(set);
       
       
      1. 使用CopyOnWriteArraySet:CopyOnWriteArraySet是Java并發包提供的一個線程安全的Set實現,它內部是基于CopyOnWriteArrayList實現的。它的特點和CopyOnWriteArrayList類似,寫操作時復制數組,讀操作直接讀取原數組,保證了線程安全。

      二十三、如何實現一個線程安全的Map?

      1. 使用HashTable:HashTable是一個線程安全的Map實現,它的方法都使用了synchronized關鍵字進行同步,但是性能較低。
      2. 使用Collections.synchronizedMap():通過Collections類的synchronizedMap()方法將一個普通的Map轉換為線程安全的Map。
      Map<String, Integer> map = new HashMap<>();
      Map<String, Integer> synchronizedMap = Collections.synchronizedMap(map);
       
       
      1. 使用ConcurrentHashMap:ConcurrentHashMap是Java并發包提供的高效線程安全的Map實現,在JDK 1.7中采用分段鎖機制,JDK 1.8中采用CAS和Synchronized相結合的方式,具有較高的并發性能。

      二十四、如何在Java中實現LRU緩存?

      LRU(Least Recently Used)緩存即最近最少使用緩存。可以使用LinkedHashMap來實現LRU緩存。LinkedHashMap維護了一個雙向鏈表,記錄了元素的訪問順序。

      import java.util.LinkedHashMap;
      import java.util.Map;
      public class LRUCache<K, V> extends LinkedHashMap<K, V> {
         
          private final int capacity;
          public LRUCache(int capacity) {
         
              super(capacity, 0.75f, true);
              this.capacity = capacity;
          }
          @Override
          protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
         
              return size() > capacity;
          }
      }
       
       

      在上述代碼中,通過繼承LinkedHashMap并重寫removeEldestEntry方法,當緩存大小超過設定的capacity時,自動移除最久未使用的元素。

      二十五、如何在Java中實現FIFO隊列?

      可以使用Queue接口的實現類,如ArrayDeque或LinkedList來實現FIFO(先進先出)隊列。

      使用ArrayDeque實現FIFO隊列

      import java.util.ArrayDeque;
      import java.util.Queue;
      public class FIFOQueueExample {
         
          public static void main(String[] args) {
         
              Queue<Integer> queue = new ArrayDeque<>();
              queue.add(1);
              queue.add(2);
              queue.add(3);
              while (!queue.isEmpty()) {
         
                  System.out.println(queue.poll());
              }
          }
      }
       
       

      使用LinkedList實現FIFO隊列

      import java.util.LinkedList;
      import java.util.Queue;
      public class FIFOQueueExample {
         
          public static void main(String[] args) {
         
              Queue<Integer> queue = new LinkedList<>();
              queue.add(1);
              queue.add(2);
              queue.add(3);
              while (!queue.isEmpty()) {
         
                  System.out.println(queue.poll());
              }
          }
      }
       
       

      在這兩個例子中,add方法用于向隊列中添加元素,poll方法用于從隊列頭部取出元素,從而實現了FIFO的特性。

      二十六、如何在Java中實現優先級隊列?

      可以使用PriorityQueue類來實現優先級隊列。PriorityQueue是一個基于堆數據結構的無界優先級隊列,默認情況下,元素按照自然順序進行排序,也可以通過傳入自定義的Comparator來實現自定義排序。

      import java.util.PriorityQueue;
      public class PriorityQueueExample {
         
          public static void main(String[] args) {
         
              PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
              priorityQueue.add(3);
              priorityQueue.add(1);
              priorityQueue.add(2);
              while (!priorityQueue.isEmpty()) {
         
                  System.out.println(priorityQueue.poll());
              }
          }
      }
       
       

      在上述示例中,元素按照從小到大的順序被取出。如果需要自定義排序,可以創建一個實現Comparator接口的類,并在創建PriorityQueue時傳入該類的實例。

      二十七、如何在Java中實現棧?

      在 Java 里實現棧有兩種比較常見的方法:一是借助 Java 集合框架中的Stack類,二是利用Deque接口的實現類,像ArrayDeque。下面為你詳細介紹這兩種實現方式。

      方法一:使用 Java 內置的Stack類
      Java 提供了java.util.Stack類,它繼承自Vector,能用來實現棧的基本功能。下面是一個簡單的示例:

      ```java
      import java.util.Stack;

      public class StackExample {
      public static void main(String[] args) {
      // 創建一個棧對象
      Stack stack = new Stack<>();

          // 入棧操作
          stack.push("Java");
          stack.push("Python");
          stack.push("C++");
      
          // 出棧操作
          System.out.println("出棧元素: " + stack.pop()); // 輸出: C++
      
          // 獲取棧頂元素
          System.out.println("棧頂元素: " + stack.peek()); // 輸出: Python
      
          // 判斷棧是否為空
          System.out.println("棧是否為空: " + stack.isEmpty()); // 輸出: false
      
          // 獲取棧的大小
          System.out.println("棧的大小: " + stack.size()); // 輸出: 2
      }
       
       

      }
      ...

      方法二:使用Deque接口(推薦做法)
      雖然Stack類使用起來很方便,但由于它是線程安全的,在單線程環境下會帶來一些性能損耗。所以,更推薦使用Deque接口的實現類,例如ArrayDeque。

      ```java
      import java.util.Deque;
      import java.util.ArrayDeque;

      public class DequeStackExample {
      public static void main(String[] args) {
      // 創建一個使用ArrayDeque實現的棧
      Deque stack = new ArrayDeque<>();

          // 入棧操作
          stack.push("Apple");
          stack.push("Banana");
          stack.push("Cherry");
      
          // 出棧操作
          System.out.println("出棧元素: " + stack.pop()); // 輸出: Cherry
      
          // 獲取棧頂元素
          System.out.println("棧頂元素: " + stack.peek()); // 輸出: Banana
      
          // 判斷棧是否為空
          System.out.println("棧是否為空: " + stack.isEmpty()); // 輸出: false
      
          // 獲取棧的大小
          System.out.println("棧的大小: " + stack.size()); // 輸出: 2
      }
       
       

      }
      ...

      方法三:自定義棧類(基于數組)
      你還可以基于數組來實現一個簡單的棧,這有助于你更深入地理解棧的底層原理。

      ```java
      public class CustomStack {
      private T[] array;
      private int top;
      private int capacity;

      @SuppressWarnings("unchecked")
      public CustomStack(int capacity) {
          this.capacity = capacity;
          this.array = (T[]) new Object[capacity];
          this.top = -1;
      }
      
      // 入棧操作
      public void push(T element) {
          if (isFull()) {
              throw new RuntimeException("棧已滿");
          }
          array[++top] = element;
      }
      
      // 出棧操作
      public T pop() {
          if (isEmpty()) {
              throw new RuntimeException("棧為空");
          }
          return array[top--];
      }
      
      // 獲取棧頂元素
      public T peek() {
          if (isEmpty()) {
              throw new RuntimeException("棧為空");
          }
          return array[top];
      }
      
      // 判斷棧是否為空
      public boolean isEmpty() {
          return top == -1;
      }
      
      // 判斷棧是否已滿
      public boolean isFull() {
          return top == capacity - 1;
      }
      
      // 獲取棧的大小
      public int size() {
          return top + 1;
      }
      
      public static void main(String[] args) {
          CustomStack<Integer> stack = new CustomStack<>(3);
          stack.push(10);
          stack.push(20);
          stack.push(30);
          System.out.println(stack.pop()); // 輸出: 30
          System.out.println(stack.peek()); // 輸出: 20
      }
       
       

      }

      posted @ 2025-10-21 13:21  我是一只小小鳥~  閱讀(9)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲 日韩 国产 制服 在线| 亚洲欧美在线综合一区二区三区| 久久久www免费人成精品| 五月丁香六月狠狠爱综合| 亚洲一国产一区二区三区| 国产综合视频一区二区三区| 欧美极品色午夜在线视频| 日韩a∨精品日韩在线观看 | 国产69精品久久久久99尤物| 亚洲欧美日韩愉拍自拍美利坚| 四虎国产精品久久免费地址| 精选国产av精选一区二区三区| 亚洲人成伊人成综合网小说| 国产精品视频白浆免费视频| 国产精品色呦呦在线观看| 亚洲AV无码破坏版在线观看 | 久久精品av国产一区二区| 国产JJIZZ女人多水喷水| 太仆寺旗| 97se亚洲综合自在线| 亚洲日韩VA无码中文字幕| 色偷偷www.8888在线观看| 亚洲AV无码破坏版在线观看| 精品视频一区二区| 香港日本三级亚洲三级| 在线观看成人av天堂不卡| 极品蜜臀黄色在线观看| 全免费A级毛片免费看无码| 美日韩不卡一区二区三区| 免费av网站| 国产在线观看91精品亚瑟| 亚洲中文字幕成人综合网| 国产精品青草久久久久福利99 | 日韩精品人妻黄色一级片 | 久久久久国产一级毛片高清版A | 在线精品视频一区二区三四| 国产精品国产三级国av| 亚洲成人av在线高清| 亚洲中文字幕久久精品蜜桃| 亚洲精品一区二区三区大| 欧洲亚洲精品免费二区|