java(集合、線程)面試要點2

集合

  • List 和 Set 區別  

  collection的子接口list和se  html

  list:①,容許重複對象②,能夠插入多個null元素③,有序容器java

    ④,經常使用的實現類有ArrayList、LinkedList和Vector,ArrayList使用索引隨意訪問,而LinkedList則更適合常常從list中添加刪除的場合。安全

  set:①,不能有重複元素②,無序容器③,只能有一個null元素多線程

    ④,實現類有HashSet、LinkedHashSet、TreeSet框架

  map:①,map不是collection的子接口或實現類,是一個接口②,map的每一個Entry都有兩個對象,一個鍵一個值,鍵不能重複。spa

    ③,能夠有多個null值,但只能有一個null鍵.net

    ④,實現類有HashMap、LinkedHashMap、HashTable、TreeMap線程

  •   List 和 Map 區別

 

  • Arraylist 與 LinkedList 區別

 

  • ArrayList 與 Vector 區別

 

  • HashMap 和 Hashtable 的區別

  一、做者不一樣code

  二、時間不一樣,Hashtable自java發佈以來,HashMap產生於jdk1.2htm

  三、繼承的父類不一樣HashTable繼承Dictinary類,HashMap繼承AbstractMap類

  四、Hashtable既不支持Null key也不支持Null value  

  五、HashMap中,null能夠做爲鍵,判斷是否存在一個鍵不能使用get()方法,當職位null時get()方法返回null,應該使用containsKey()方法判斷。

  六、Hashtable線程安全,每一個方法都加入了Synchronize方法。當須要多線程操做的時候可使用線程安全的ConcurrentHashMap。ConcurrentHashMap雖然也是線程安全的,可是它的效率比Hashtable要高好多倍。由於ConcurrentHashMap使用了分段鎖,並不對整個數據進行鎖定。

  七、爲了獲得元素的位置,首先須要根據元素的 KEY計算出一個hash值,而後再用這個hash值來計算獲得最終的位置。hash值的方法不一樣,Hashtable直接使用對象的hashCode,hashCode是JDK根據對象的地址或者字符串或者數字算出來的int類型的數值。而後再使用除留餘數發來得到最終的位置。

Hashtable在計算元素的位置時須要進行一次除法運算,而除法運算是比較耗時的。 
HashMap爲了提升計算效率,將哈希表的大小固定爲了2的冪,這樣在取模預算時,不須要作除法,只須要作位運算。位運算比除法的效率要高不少。

HashMap的效率雖然提升了,可是hash衝突卻也增長了。由於它得出的hash值的低位相同的機率比較高,而計算位運算

爲了解決這個問題,HashMap從新根據hashcode計算hash值後,又對hash值作了一些運算來打散數據。使得取得的位置更加分散,從而減小了hash衝突。固然了,爲了高效,HashMap只作了一些簡單的位處理。從而不至於把使用2 的冪次方帶來的效率提高給抵消掉。

  • HashSet 和 HashMap 區別

 

  • HashMap 和 ConcurrentHashMap 的區別

   

  • HashMap 的工做原理及代碼實現

   https://www.cnblogs.com/chengxiao/p/6059914.html

  • ConcurrentHashMap 的工做原理及代碼實現

   https://blog.csdn.net/helei810304/article/details/79786606

線程

  • 建立線程的方式及實現

  https://blog.csdn.net/m0_37840000/article/details/79756932  

建立線程的四種方式:

    ①繼承Thread類,重寫run方法

    ② 實現Runnable接口,重寫run方法

    ③使用線程池例如用Executor框架

    ④使用Callable和Future建立線程

--------繼承Thread方式--------------------------------------------------------------

public class MyThread extends Thread{

  public void  run(){//重寫run方法}
 } public class Test{   public static void main(String[] args){     new MyThread().start();//啓動線程    } }

  -----實現Runnable接口方式-----------------------------------------------

public class MyThread implements Runnable{
  public void run(){} } public class test{ public static void main(String[] args){ MyThrea tt = new MyThread(); Thread thread = new Thread(tt); thread.start(); } }

  ------------------------使用Callable和Future建立線程---------------------

1】建立Callable接口的實現類,並實現call()方法,而後建立該實現類的實例(從java8開始能夠直接使用Lambda表達式建立Callable對象)。

2】使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了Callable對象的call()方法的返回值 3】使用FutureTask對象做爲Thread對象的target建立並啓動線程(由於FutureTask實現了Runnable接口) 4】調用FutureTask對象的get()方法來得到子線程執行結束後的返回值 代碼實例: public class Main {   public static void main(String[] args){    MyThread3 th=new MyThread3();    //使用Lambda表達式建立Callable對象    //使用FutureTask類來包裝Callable對象     FutureTask<Integer> future=new FutureTask<Integer>(     (Callable<Integer>)()->{       return 5;     }    );    new Thread(task,"有返回值的線程").start();//實質上仍是以Callable對象來建立並啓動線程    try{     System.out.println("子線程的返回值:"+future.get());//get()方法會阻塞,直到子線程執行結束才返回     }catch(Exception e){     ex.printStackTrace();    }   } }
  • sleep() 、join()、yield()有什麼區別
1、sleep()
使當前線程(即調用該方法的線程)暫停執行一段時間,讓其餘線程有機會繼續執行,但它並不釋放對象鎖。也就是說若是有synchronized同步快,其餘線程仍然不能訪問共享數據。注意該方法要捕捉異常。
例若有兩個線程同時執行(沒有synchronized)一個線程優先級爲MAX_PRIORITY,另外一個爲MIN_PRIORITY,若是沒有Sleep()方法,只有高優先級的線程執行完畢後,低優先級的線程纔可以執行;可是高優先級的線程sleep(500)後,低優先級就有機會執行了。 總之,sleep()可使低優先級的線程獲得執行的機會,固然也可讓同優先級、高優先級的線程有執行的機會。 2、join() join()方法使調用該方法的線程在此以前執行完畢,也就是等待該方法的線程執行完畢後再往下繼續執行。注意該方法也須要捕捉異常。 3、yield() 該方法與sleep()相似,只是不能由用戶指定暫停多長時間,而且yield()方法只能讓同優先級的線程有執行的機會。
四、wait:Object類的方法,必須放在循環體和同步代碼塊中,執行該方法的線程會釋放鎖,進入線程等待池中等待被再次喚醒(notify隨機喚醒,notifyAll所有喚醒,線程結束自動喚醒)即放入鎖池中競爭同步鎖
  • 說說 CountDownLatch 原理
  • 說說 CyclicBarrier 原理
  • 說說 Semaphore 原理
  • 說說 Exchanger 原理
  • 說說 CountDownLatch 與 CyclicBarrier 區別
  • ThreadLocal 原理分析
  • 講講線程池的實現原理
  • 線程池的幾種方式與使用場景
  • 線程的生命週期

  

(1)生命週期的五種狀態

新建(new Thread) 當建立Thread類的一個實例(對象)時,此線程進入新建狀態(未被啓動)。 例如:Thread t1=new Thread(); 就緒(runnable) 線程已經被啓動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候獲得CPU資源。例如:t1.start(); 運行(running) 線程得到CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束。 死亡(dead) 當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。 天然終止:正常運行run()方法後終止 異常終止:調用stop()方法讓一個線程終止運行 堵塞(blocked) 因爲某種緣由致使正在運行的線程讓出CPU並暫停本身的執行,即進入堵塞狀態。 正在睡眠:用sleep(long t) 方法可以使線程進入睡眠方式。一個睡眠着的線程在指定的時間過去可進入就緒狀態。 正在等待:調用wait()方法。(調用motify()方法回到就緒狀態) 被另外一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)

鎖機制

  • 說說線程安全問題
  • volatile 實現原理
  • synchronize 實現原理
  • synchronized 與 lock 的區別
  • CAS 樂觀鎖
  • ABA 問題
  • 樂觀鎖的業務場景及實現方式
相關文章
相關標籤/搜索