Java複習

一、COllections.sort內部原理

Collection.sort()排序通過泛化實現對所有類型的排序,對於基礎類型如int,string,按照字符表,數字大小排序。對於自定義類型,通過實現Comparable接口,重寫comparableTo()方法自定義比較大小的方式。也可以使用Comparator外比較器,Comparable接口的方式比實現Comparator接口的耦合性要強一些。

Collection.sort內部調用的是Arrays.sort方法,對於Arrays類,有兩個sort方法,sort(Object)和sort(int),前者使用歸併排序,後者使用快排。

import java.util.*;
class xd{
    int a;
    int b;
    xd(int a,int b){
        this.a=a;
        this.b=b;
    }
}
public class Main(){
    public static void main(String[] args){
        xd a=new xd(2,3);
        xd b=new xd(4,1);
        xd c=new xd(1,2);
        ArrayList<xd> list=new ArrayList<>();
        array.add(a);
        array.add(b);
        array.add(c);
        Collections.sort(array,new Comparator<xd>(){
            @Override
            public int compare(xd o1,xd o2){
                if(o1.a>o2.a)
                    return 1;
                else if(o1.a<o2.a)
                    return -1;
                return 0;
            }
        });
        for(int i=0;i<array.size();i++)
            System.out.println(array.get(i).a);
        for(int i=0;i<array.size();i++)
            System.out.println(array.get(i).b);
    }
}

二、TreeMap和TreeSet

TreeMap和TreeSet都是Java Collection Framework的兩個重要成員,其中TreeMap實現了Map接口,TreeSet實現了set接口。TreeSet底層是通過TreeMap來實現的。二者的實現方式完全一樣,而TreeMap的實現就是紅黑樹算法。

  • TreeMap和TreeSet都是有序的集合,它們存儲的值都是排好序的
  • TreeMap和TreeSet都是非同步的集合,他們不能再多線程之間共享,不過可以使用Collections.synchronizedMap()來實現同步
  • 運行速度都比Hash集合慢,時間複雜度爲O(logN)。而HashMap/HashSet則爲O(1)。
  • TreeSet實現了Set接口而TreeMap實現了Map接口。
  • TreeSet只存儲一個對象,而TreeMap存儲兩個對象key和Value。
  • TreeSet中不能有重複對象,而TreeMap可以有重複對象。

三、集合和有序集合有什麼區別?

有序集合裏的元素可以根據key或index訪問,有序集合在屬性的增加、刪除、修改中擁有較好的性能。

無序集合裏的元素只能遍歷。

  • 無序集:set
  • 有序集:List

凡是實現set的AbstractSet、CopyOnWriteArraySet、EnumSet、HashSet、LinkedHashSet、TreeSet都是無序的

凡是實現List的AbstractList、ArrayList、LinkedList、Stack、Vector都是有序的

  • Map:Map可以根據key來訪問,從這個角度將,Map也是有序的 

四、Set是無序的,怎麼保證有序

Set是無序的,但是TreeSet可以保證有序。

五、Java集合框架

Java集合大致可以分爲Set、List、Queue和Map四種體系。其中Set代表無序,不可重複的集合。List代表有序,可以重複的集合。Map代表映射關係的集合。Java5又增加了Queue體系,代表一種隊列集合實現。

 Java集合和數組的區別:

數組元素在初始化時指定,意味着只能保存定長的數據。而集合可以保存數量不確定的數據。數組元素既可以保存基本類型的值,也可以是對象。集合裏只能保存對象。基本數據類型要轉換成對應的包裝類才能放入集合類中。

Java集合類之間的繼承關係:Java的集合類主要由兩個接口派生而出:Collection和Map。

Map實現類用於保存具有映射關係的數據。Map保存的每項數據都是key-value對,也就是由key和value兩個值組成。

六、Iterator和ListIterator的區別是什麼

Iterator可以用來遍歷Set和List集合,但是ListIterator只能遍歷List。Iterator對集合只能是前向遍歷,ListIterator既可以前向也可以後向。

七、快速失敗和安全失敗的區別是什麼

Iterator的安全失敗是基於對底層集合做拷貝,它不受源集合上修改的影響。Java.concurrent包下面的所有類都是安全失敗的。而快速失敗受到源集合修改的影響,Java.util包下面的所有集合類都是快速失敗的。快速失敗的迭代器會拋出ConcurrentModificationException異常,而安全失敗的迭代器不會拋出此異常。

八、Java哪些類是線程安全的

Vector:比ArrayList多了個同步機制(Synchronized)

HashTable:HashMap的線程安全版本

Stack:Stack也是線程安全的,繼承與Vector

九、Volatile和synchronized區別

  • 加鎖機制既可以保證可見性又可以保證原子性,而volatile只能確保可見性,不能保證原子性
  • volatile不會進行加鎖操作。volatile變量是一種稍弱的同步機制在訪問volatile變量時不會執行加鎖操作。也就不會使線程阻塞,因此volatile是一種比Synchronized更輕量級的同步機制。
  • volatile不如synchronized安全。

十、Volatile

volatile關鍵字保證了內存可見性,防止指令重排序。volatile並不保證原子性。

  • volatile保證內存可見性的原理是每次訪問變量時都會進行一次刷新,因此每次訪問都是主內存中最新的版本。所以volatile關鍵字的作用之一就是保證變量修改的實時可見性。
  • 由於volatile屏蔽掉了JVM中必要的代碼優化,所以在效率上比較低。

十一、Java編寫一個會導致死鎖的程序

public static void main(String[] args){
    final Object a=new Object();
    final Object b=new Object();
    Thread threadA=new Thread(new Runnable(){
        @Override
        public void run(){
            synchronized(a){
                try{
                    Thread.sleep(5000);
                    synchronized(b){
                        Thread.sleep(1000);
                        System.out.println("鎖住b");
                    }
                 }
                catch(Exception e){
                     e.printStackTrace();
                }
            }
        });


    Thread threadB=new Thread(new Runnable(){
        @Override
        public void run(){
            synchronized(b){
                try{
                   Thread.sleep(5000);
                   Synchroninzed(a){
                        Thread.sleep(1000);
                        System.out.println(“鎖住A”);
                }catch(Exception e){
                  e.printStackTrace();
                    }
            });

     ThreadA.start();
     ThreadB.start();
}

十二、自旋鎖、偏向鎖、輕量級鎖、重量級鎖

阻塞操作會導致在用戶態和內核態之間切換,嚴重影響性能。在很多場景下,同步資源的鎖定時間很短,爲了這一小段時間去切換線程可能會償失,可以讓線程“稍微等待一會”,這就是自旋鎖。

無鎖、偏向鎖、輕量級鎖、重量級鎖都是針對synchronized的。synchronized是悲觀鎖,在操作同步資源之前需要給同步資源加鎖,這把鎖就存在Java對象頭裏面。

一個線程訪問:在大多數情況下,鎖總是由一個線程獲得,不存在多線程競爭,所以出現了偏向鎖。其目標就是在只有一個線程執行同步代碼塊的情況下能夠提高性能

輕量級鎖:兩個線程交替訪問,鎖升級,升級爲輕量級鎖。

重量級鎖:多個線程訪問,競爭激烈,升級了重量級鎖。

十三、

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章