JAVA精髓(初級篇)

IO、集合、多線程

1、ArrayList、Vector、LinkedList的存儲性能和特性
答,ArrayList 和Vector他們底層的實現都是一樣的,都是使用數組方式存儲數據,  Vector中的方法由於添加了synchronized修飾,也就是加了同步鎖,因此Vector是線程安全的容器,但性能上較ArrayList差,因此已經是Java中的遺留容器。
LinkedList使用雙向鏈表實現存儲(將內存中零散的內存單元通過附加的引用關聯起來,形成一個可以按序號索引的線性結構,這種鏈式存儲方式與數組的連續存儲方式相比,內存的利用率更高),按序號索引數據需要進行前向或後向遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入速度較快。新增和刪除操作LinkedList要強於ArrayList,因爲ArrayList要移動數據,注意LinkedList沒有同步方法
       
2、List、Set、Map是否繼承自Collection接口? 
Collection是最基本的集合接口,聲明瞭適用於JAVA集合(只包括Set和List)的通用方法。 Set 和List 都繼承了Conllection;Set具有與Collection完全一樣的接口,因此沒有任何額外的功能,不像前面有兩個不同的List。實際上Set就是Collection,只 是行爲不同。(這是繼承與多態思想的典型應用:表現不同的行爲。)Set不保存重複的元素(至於如何判斷元素相同則較爲負責) 

 Map沒有繼承於Collection接口 從Map集合中檢索元素時,只要給出鍵對象,就會返回對應的值對象。

a、Collection 和 Map 的區別

容器內每個爲之所存儲的元素個數不同。
Collection類型者,每個位置只有一個元素。
Map類型者,持有 key-value pair,像個小型數據庫。

b、各自旗下的子類關係

Collection
     --List:將以特定次序存儲元素。所以取出來的順序可能和放入順序不同。
           --ArrayList / LinkedList / Vector
     --Set : 不能含有重複的元素
           --HashSet / TreeSet(可排序)
      Map
     --HashMap  線程不安全,性能快,不同步,內部結構是哈希表,允許null作爲鍵,null作爲值
     --HashTable 線程安全,但慢,多線程纔會考慮使用,同步,內部結構是哈希表,不允許null作爲鍵,null作爲值
     --TreeMap  內部結構是二叉樹,不同步,可以對map的鍵進行排序

3、List、Map、Set三個接口存取元素時,各有什麼特點? 

Set裏面不允許有重複的元素,
存元素:add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true;當集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素,返回結果爲false。
取元素:沒法說取第幾個,只能以Iterator接口取得所有的元素,再逐一遍歷各個元素。

List表示有先後順序的集合,
存元素:多次調用add(Object)方法時,每次加入的對象按先來後到的順序排序,也可以插隊,即調用add(int index,Object)方法,就可以指定當前對象在集合中的存放位置。
取元素:方法1:Iterator接口取得所有,逐一遍歷各個元素

        方法2:調用get(index i)來明確說明取第幾個。

Map是雙列的集合,存放用put方法:put(obj key,obj value),每次存儲時,要存儲一對key/value,不能存儲重複的key,這個重複的規則也是按equals比較相等。
取元素:用get(Object key)方法根據key獲得相應的value。

        也可以獲得所有的key的集合,還可以獲得所有的value的集合,

        還可以獲得key和value組合成的Map.Entry對象的集合。
4、請說出與線程同步以及線程調度相關的方法。

-wait():使一個線程處於等待(阻塞)狀態,並且釋放所持有的對象的鎖;

-sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要處理InterruptedException異常;
 
-notify():喚醒一個處於等待狀態的線程,當然在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且與優先級無關;
 
-notityAll():喚醒所有處於等待狀態的線程,該方法並不是將對象的鎖給所有線程,而是讓它們競爭,只有獲得鎖的線程才能進入就緒狀態; 

5、編寫多線程程序有幾種實現方式? 
1.繼承Thread類實現多線程
2.實現Runnable接口方式
3.使用ExecutorService、Callable、Future實現有返回結果的多線程
4.使用匿名內部類
5.線程池

Thread 類中的start() 和 run() 方法有什麼區別?
這個問題經常被問到,但還是能從此區分出面試者對Java線程模型的理解程度。start()方法被用來啓動新創建的線程,而且start()內部調用了run()方法,這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啓動,start()方法纔會啓動新線程。

6、簡述synchronized 和java.util.concurrent.locks.Lock的異同?
簡要答案:
   1.Lock能完成幾乎所有synchronized的功能,並有一些後者不具備的功能,如鎖投票、定時鎖等候、可中斷鎖等候等
   2.synchronized 是Java 語言層面的,是內置的關鍵字;Lock 則是JDK 5中出現的一個包,在使用時,synchronized 同步的代碼塊可以由JVM自動釋放;Lock 需要程序員在finally塊中手工釋放,如果不釋放,可能會引起難以預料的後果(在多線程環境中)。
7、hash碰撞以及hash算法、如何解決哈希衝突 
9、HashMap的存儲原理,需要了解HashMap的源碼。 
12、Hashtable,HashMap,ConcurrentHashMap 底層實現原理與線程安全問題 

ConcurrentHashMap是使用了鎖分段技術來保證線程安全的。

鎖分段技術:首先將數據分成一段一段的存儲,然後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。 

ConcurrentHashMap提供了與Hashtable和SynchronizedMap不同的鎖機制。Hashtable中採用的鎖機制是一次鎖住整個hash表,從而在同一時刻只能由一個線程對其進行操作;而ConcurrentHashMap中則是一次鎖住一個桶。

ConcurrentHashMap默認將hash表分爲16個桶,諸如get、put、remove等常用操作只鎖住當前需要用到的桶。這樣,原來只能一個線程進入,現在卻能同時有16個寫線程執行,併發性能的提升是顯而易見的(也就是默認提升了16倍)。

13、Hash衝突怎麼辦?哪些解決散列衝突的方法? 
14、講講IO裏面的常見類,字節流、字符流、接口、實現類、方法阻塞。 

字節流
字節流主要是操作byte類型數據,也byte數組爲準,主要操作類就是
·字節輸出流:OutputStream
·字節輸入流:InputStream
字符流
在程序中一個字符等於2個字節,那麼java提供了Reader、Writer兩個專門操作字符流的類。
·字符輸出流:Writer
·字符輸入流:Reader
字節-字符轉換流
OutputStreamWriter和InputStreamReader
在整個IO包中,實際上就是字節流和字符流,但是除了這兩個流之外,還存在一組字節流-字符流的轉換類。
[java] view plaincopyprint?
•OutputStreamWriter:是Writer的子類,將輸出的字符流轉換爲字節流。即:將一個字符流的輸出對象變爲字節流的輸出對象  
•InputStreamReader:是Reader的子類,將輸入的字節流變爲字符流,即:將一個字節流的輸入對象變爲字符流的輸入對象
15、講講NIO。

思路:分而治之,將任務拆分開來,由專門的人負責專門的任務。
具體來講,銀行專門指派一名職員A,A的工作就是每當有顧客到銀行,他就遞上表格讓顧客填寫,每當有顧客填好表後,A就將其隨機指派給剩餘的9名職員完成後續步驟。 

16、遞歸讀取文件夾下的文件,代碼怎麼實現

/** 
 * 遞歸讀取文件夾下的 所有文件 
 * 
 * @param testFileDir 文件名或目錄名 
 */  
private static void testLoopOutAllFileName(String testFileDir) {  
    if (testFileDir == null) {  
        //因爲new File(null)會空指針異常,所以要判斷下  
        return;  
    }  
    File[] testFile = new File(testFileDir).listFiles();  
    if (testFile == null) {  
        return;  
    }  
    for (File file : testFile) {  
        if (file.isFile()) {  
            System.out.println(file.getName());  
        } else if (file.isDirectory()) {  
            System.out.println("-------this is a directory, and its files are as follows:-------");  
            testLoopOutAllFileName(file.getPath());  
        } else {  
            System.out.println("文件讀入有誤!");  
        }  
    }  
}  


17、常用的線程池模式以及不同線程池的使用場景 
18、newFixedThreadPool此種線程池如果線程數達到最大值後會怎麼辦,底層原理。 
19、瞭解可重入鎖的含義,以及ReentrantLock 和synchronized的區別 

20、atomicinteger和volatile等線程安全操作的關鍵字的理解和使用 
 對於可見性,Java提供了volatile關鍵字來保證可見性。
 當一個共享變量被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他線程需要讀取時,它會去內存中讀取新值。但是不能保證原子性
另外,通過synchronized和Lock也能夠保證可見性,synchronized和Lock能保證同一時刻只有一個線程獲取鎖然後執行同步代碼,並且在釋放鎖之前會將對變量的修改刷新到主存當中。因此可以保證可見性
atomicinteger:保證了全局變量的原子性

21、進程和線程的區別 

22、什麼是線程安全?
如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變量的值也和預期的是一樣的,就是線程安全的。
23、同步和異步,阻塞和非阻塞 
       同步:一個服務的完成需要依賴其他服務時,只有等待被依賴的服務完成後,纔算完成,這是一種可靠的服務序列。要麼成功都成功,失敗都失敗,服務的狀態可以保持一致
       異步:一個服務的完成需要依賴其他服務時,只通知其他依賴服務開始執行,而不需要等待被依賴的服務完成,此時該服務就算完成了。被依賴的服務是否最終完成無法確定,一次它是一個不可靠的服務序列
阻塞:阻塞調用是指調用結果返回之前,當前線程會被掛起,一直處於等待消息通知,不能夠執行其他業務,函數只有在得到結果之後纔會返回。
      非阻塞:非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回

1、同步阻塞:小明啥都不幹等奶茶。
2、同步非阻塞:小明一邊玩手機一邊等奶茶。
3、異步阻塞:小明拿着小票啥都不幹等着奶茶妹告訴他奶茶好了
4、異步非阻塞:小明拿着小票玩着手機等着奶茶妹告訴他奶茶好了

24、多線程的三大特性
1、原子性:即一個操作或者多個操作 要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行。
2、可見性:當多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。
3、有序性:程序執行的順序按照代碼的先後順序執行。


25、怎麼禁止java的反射機制

java默認走的是無參構造函數,把對象的無參構造函數私有化,即可

26、在靜態方法上使用同步時會發生什麼事?

答:同步靜態方法時會獲取該類的“Class”對象,所以當一個線程進入同步的靜態方法中時,線程監視器獲取類本身的對象鎖,其它線程不能進入這個類的任何靜態同步方法。它不像實例方法,因爲多個線程可以同時訪問不同實例同步實例方法

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