Java重點(diǎn)

0,編程語(yǔ)言的分類

第一種分法:

  • 解釋型語(yǔ)言:源代碼不是直接翻譯成機(jī)器語(yǔ)言,而是先翻譯成中間代碼,再由解釋器對(duì)中間代碼進(jìn)行解釋運(yùn)行。比如Python/JavaScript / Perl /Shell等都是解釋型語(yǔ)言。

  • 編譯型語(yǔ)言:程序在執(zhí)行之前需要一個(gè)專門的編譯過(guò)程,把程序編譯成 為機(jī)器語(yǔ)言的文件,運(yùn)行時(shí)不需要重新翻譯,直接使用編譯的結(jié)果就行了。程序執(zhí)行效率高,依賴編譯器,跨平臺(tái)性差些。如C、C++、Delphi等.

第二種分法:

  • 面向?qū)ο螅篔ava,C++,C#,Python,PHP,JavaScript
  • 面向過(guò)程:C

第三種分法:

  • 強(qiáng)類型:C,C++,Java,C#,python。一種總是強(qiáng)制類型定義的語(yǔ)言,要求變量的使用要嚴(yán)格符合定義,所有變量都必須先定義后使用。java、.NET、C++、python等都是強(qiáng)制類型定義的。也就是說(shuō),一旦一個(gè)變量被指定了某個(gè)數(shù)據(jù)類型,如果不經(jīng)過(guò)強(qiáng)制轉(zhuǎn)換,那么它就永遠(yuǎn)是這個(gè)數(shù)據(jù)類型了。
  • 弱類型:數(shù)據(jù)類型可以被忽略的語(yǔ)言。它與強(qiáng)類型定義語(yǔ)言相反, 一個(gè)變量可以賦不同數(shù)據(jù)類型的值。PHP,JavaScript

1,Java泛型,擦除

不可以把List<String>傳遞給一個(gè)接受List<Object>參數(shù)的方法。List<String>只接受String。

  • Java的泛型是如何工作的 ? 什么是類型擦除 ?

    • 泛型是通過(guò)類型擦除來(lái)實(shí)現(xiàn)的,編譯器在編譯時(shí)擦除了所有類型相關(guān)的信息,所以在運(yùn)行時(shí)不存在任何類型相關(guān)的信息。例如List<String>在運(yùn)行時(shí)僅用一個(gè)List來(lái)表示。這樣做的目的,是確保能和Java 5之前的版本開發(fā)二進(jìn)制類庫(kù)進(jìn)行兼容。你無(wú)法在運(yùn)行時(shí)訪問到類型參數(shù),因?yàn)榫幾g器已經(jīng)把泛型類型轉(zhuǎn)換成了原始類型。
  • 什么是泛型中的限定通配符和非限定通配符 ?

    • 限定通配符對(duì)類型進(jìn)行了限制。有兩種限定通配符,一種是<? extends T>它通過(guò)確保類型必須是T的子類來(lái)設(shè)定類型的上界,另一種是<? super T>它通過(guò)確保類型必須是T的父類來(lái)設(shè)定類型的下界。泛型類型必須用限定內(nèi)的類型來(lái)進(jìn)行初始化,否則會(huì)導(dǎo)致編譯錯(cuò)誤。另一方面<?>表示了非限定通配符,因?yàn)?lt;?>可以用任意類型來(lái)替代。
  • List<? extends T>和List <? super T>之間有什么區(qū)別 ?

  • 這和上一個(gè)面試題有聯(lián)系,有時(shí)面試官會(huì)用這個(gè)問題來(lái)評(píng)估你對(duì)泛型的理解,而不是直接問你什么是限定通配符和非限定通配符。這兩個(gè)List的聲明都是限定通配符的例子,List<? extends T>可以接受任何繼承自T的類型的List,而List<? super T>可以接受任何T的父類構(gòu)成的List。例如List<? extends Number>可以接受List<Integer>或List<Float>。

2,數(shù)組和鏈表的區(qū)別

3, Java線程,柵欄

4, Java內(nèi)部類,有幾種,能不能從外部訪問,為什么有內(nèi)部類?

匿名內(nèi)部類,靜態(tài)內(nèi)部類,成員內(nèi)部類,局部?jī)?nèi)部類(定義在代碼塊中的類)。

內(nèi)部類最吸引人注意的原因是:每個(gè)內(nèi)部類都能獨(dú)立的繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍類是否已經(jīng)繼承了某個(gè)就(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒有影響。

?①,內(nèi)部類提供進(jìn)入其外圍類的綠色通道;

②,一般來(lái)說(shuō),內(nèi)部類繼承自某個(gè)類或?qū)崿F(xiàn)某個(gè)接口,和接口一起實(shí)現(xiàn)java中多重繼承;如果擁有的是抽象類或具體的類,而不是接口,那就只能使用內(nèi)部類才能實(shí)現(xiàn)多重繼承。

③?,private內(nèi)部類給類的設(shè)計(jì)者提供了一種途徑,通過(guò)這種方式可以完全阻止任何依賴于類型的編碼,并且完全隱藏了實(shí)現(xiàn)的細(xì)節(jié);

④,匿名內(nèi)部類可以使得代碼更加地靈活。

5,HashMap,HashTable, LinkedHashMap,TreeMap

* 一般情況下,我們用的最多的是HashMap,在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。
* 如果要按自然順序或自定義順序遍歷鍵,那么TreeMap會(huì)更好。
* 如果需要輸出的順序和輸入的相同,那么用LinkedHashMap 可以實(shí)現(xiàn),它還可以按讀取順序來(lái)排列。
  • HashMap是一個(gè)最常用的Map,它根據(jù)鍵的hashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度。HashMap最多只允許一條記錄的鍵為NULL,允許多條記錄的值為NULL。HashMap不支持線程同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap,可能會(huì)導(dǎo)致數(shù)據(jù)的不一致性。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力。
    Map m = Collections.synchronizedMap(new HashMap());

  • Hashtable與HashMap類似,不同的是:它不允許記錄的鍵或者值為空;它支持線程的同步,即任一時(shí)刻只有一個(gè)線程能寫Hashtable,因此也導(dǎo)致了Hashtable在寫入時(shí)會(huì)比較慢。

  • LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時(shí),先得到的記錄肯定是先插入的。在遍歷的時(shí)候會(huì)比HashMap慢TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按升序排序,也可以指定排序的比較器。當(dāng)用Iterator遍歷TreeMap時(shí),得到的記錄是排過(guò)序的。
    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

5,HashMap線程不安全,CocurrentHashMap線程安全,以及HashMap的結(jié)構(gòu)。

HashMap實(shí)際上是一個(gè)“鏈表散列”的數(shù)據(jù)結(jié)構(gòu),即數(shù)組和鏈表的結(jié)合體。


Paste_Image.png

從上圖中可以看出,HashMap底層就是一個(gè)數(shù)組結(jié)構(gòu),數(shù)組中的每一項(xiàng)又是一個(gè)鏈表。當(dāng)新建一個(gè)HashMap的時(shí)候,就會(huì)初始化一個(gè)數(shù)組。

    • 在HashMap中添加值步驟
      第一步,對(duì)key的hashcode進(jìn)行hash計(jì)算,獲取應(yīng)該保存到數(shù)組中的index。
      第二步,判斷index所指向的數(shù)組元素是否為空,如果為空則直接插入。
      第三步,如果不為空,則依次查找entry中next所指定的元素,判讀key是否相等,如果相等,則替換久的值,返回。
      第四步,如果都不相等,則將此鏈表頭元素賦值給待插入entry的next變量,讓后將待插入元素插入到entry數(shù)組中去。

6, java wait()和sleep()區(qū)別

  • 1,原理不同。 sleep()是Thread的靜態(tài)方法,會(huì)使線程暫停執(zhí)行一段時(shí)間,直到計(jì)時(shí)時(shí)間到。而wait()是Objet類的方法,用于線程間通信。該方法會(huì)使當(dāng)前擁有該對(duì)象鎖的線程等待,直到其他線程調(diào)用notify()方法時(shí)才醒來(lái),當(dāng)然也可以定義一段時(shí)間自動(dòng)醒來(lái)。
  • 2,對(duì)鎖的處理機(jī)制不同。sleep方法不涉及線程間通信,不會(huì)釋放鎖。當(dāng)調(diào)用wait方法后,線程會(huì)釋放掉它所占用的鎖,從而使線程所在對(duì)象中的其他synchronized數(shù)據(jù)可以被別的線程使用。
  • 3,使用區(qū)域不同。sleep可以在任意位置使用。而由于wait方法對(duì)資源的處理,wait方法必須放在同步控制方法或者同步語(yǔ)句塊中使用。
  • 4,wait方法推薦使用,sleep方法由于不會(huì)釋放鎖,會(huì)引起死鎖的問題。

其他相關(guān)知識(shí),

  • java yield()和sleep()區(qū)別
  • sleep方法一定會(huì)讓進(jìn)程休眠,他不考慮其他進(jìn)程的優(yōu)先級(jí),可能會(huì)給低優(yōu)先級(jí)的進(jìn)程運(yùn)行的機(jī)會(huì)。而yield僅僅會(huì)給相同或者更高優(yōu)先級(jí)的進(jìn)程運(yùn)行機(jī)會(huì)。
  • 線程執(zhí)行sleep方法后會(huì)進(jìn)入阻塞狀態(tài)。而yield后會(huì)進(jìn)入可執(zhí)行狀態(tài)。
  • sleep方法會(huì)拋出InterruptedException中斷異常,而yield方法沒有聲明任何異常。
  • sleep方法比yield方法具有更好的移植性。

7, 如何不用構(gòu)造函數(shù)就能獲得對(duì)象。

Class.forName,反射

假設(shè)Sub類繼承自Base類。他們都有一個(gè)f()方法。

try{
  Class c = Class.forName("Sub");
  Base b = (Base)c.newInstance();
  b.f();
}catch(Exception e){
  e.printStackTrace();
}

這樣就會(huì)調(diào)用Base類的子類Sub類的f方法(多態(tài))。

8, 對(duì)線程的中斷的理解。

9,如何實(shí)現(xiàn)4個(gè)線程,讓前三個(gè)并發(fā)執(zhí)行完后,才繼續(xù)執(zhí)行第四個(gè)

第一種方法,使用join(),確保子線程運(yùn)行完畢才運(yùn)行主線程。

public class Test{
    private Runnable task1 = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("task1");
        }
    };

    private Runnable task2 = new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("task2");
        }
    };
    
    private Runnable task3 = new Runnable() {
        @Override
        public void run() {
            System.out.println("task3");
        }
    };
    
    private Runnable task4 = new Runnable() {
        @Override
        public void run() {
            System.out.println("task4");
        }
    };

    public static void main(String...args){
          Test test = new Test();
          test.go123();
          test.go4();      
    }
    
    public void go123(){
          Thread myThread1 = new Thread(task1);
           myThread1.start();
           
           Thread myThread2 = new Thread(task2);
           myThread2.start();
           
           Thread myThread3 = new Thread(task3);
           myThread3.start();
           
           try {
            myThread1.join();
            myThread2.join();
            myThread3.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           
    }
    
    public void go4(){
        Thread myThread4 = new Thread(task4);
        myThread4.start();
    }
}

第二種方法,使用柵欄CyclicBarrier

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,898評(píng)論 18 399
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,280評(píng)論 0 62
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,901評(píng)論 11 349
  • 餅干.王微.小盧同學(xué)~作業(yè) 把自己的想法,變成現(xiàn)實(shí)……
    李巖立裁造型師閱讀 1,023評(píng)論 3 6
  • 黑暗的黎明 雪沒來(lái)得及融化 就鋪開了一排墳?zāi)?燕子被吊死在電線上 烏云在流著尸血 該死的冷風(fēng) 夾帶著腐敗的回憶 吹...
    竇什三閱讀 260評(píng)論 0 0

友情鏈接更多精彩內(nèi)容