Java 8 新特性 及 常見 面試題

Java 8 新特性簡介:

1. 代碼更少(增加了新語法:Lambda 表達式)
2. 強大的 Stream API(集合數據的操作)
3. 最大化的減少空指針 異常:Optional 類 的使用
4. 接口的新特性
5. 註解的新特性
6. 集合的底層 源碼實現
7. 新日期時間的 api

題一:抽象類 和 接口的 異同?

抽象類:含有 abstract 修飾符的 class 就算 抽象類;它既可以有抽象方法,也可以有 普通方法,構造方法,靜態方法,但是不能有抽象構造方法 和 抽象靜態方法。且如果其子類沒有實現其所有的 抽象方法,那麼該 子類 也必須是 抽象類;
接口:他可以看成是 抽象類的 一個特例,使用 interface 修飾符;
內部結構:
    jdk7:接口只有常量和抽象方法,無構造器
    jdk8:接口增加了 默認方法 和 靜態方法,無構造器
    jdk9:接口允許 以 private 修飾的方法,無構造器
共同點:
    不能實例化;
    多態方式的一種使用;
不同點:
    抽象類是單繼承的,而接口可以多繼承(實現);

題二:xxx 與 yyy 的 異同?

1、overload(重載) 與 overwrite(重寫)
    重載:表示一個類中 可以有多個名稱相同的方法,但彼此的參數不同(參數個數或參數類型),與方法的作用域和返回類型無關;
    重寫:表示子類中的方法可以與父類的某個方法的 名稱和參數完全相同;當通過子類創建的對象調用這個方法時,將調用 子類中的定義方法,相當於將父類的此方法覆蓋,這也是多態的一種表現;
2、throw 與 throws
    throw:手動拋出異常,一般出現在函數體中;
    throws:聲明方法可能拋出的異常,一般出現在 方法頭部;
3、final 、finally 與 finalize
    final:用於聲明屬性,方法和類,表示屬性不可變,方法不可重寫,類不可繼承;
    finally:它是異常處理語句結構的一部分,表示總是會執行;
    finalize:它是 Object 類的 一個方法,在 垃圾收集器 執行 的時候會調用被回收對象的 此方法,可以重寫 此方法 提供垃圾收集時代的其他資源回收,例如關閉文件等。jvm 不保證此方法總被調用;
4、Collection 與 Collections
     Collection:它是接口, 集合類的上級接口,繼承與他有關的接口主要有List和Set;
    Collections:它 是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全等操作;如 Collections.sort(xxx);
5、ArrayList 與 LinkedList、Vector
        ArrayList:對數組進行封裝,實現長度可變的數組,和數組採用相同的存儲方式,在內存中分配連續的空間。優點在於遍歷元素和隨機訪問元素效率高;多線程不安全;
        LinkedList:採用雙向鏈表的存儲方式,優點在於插入和刪除元素效率高;多線程不安全;
        Vector:類似於 ArrayList;但其使用了 synchronized 方法(多線程安全),使得性能上比 ArrayList 差;同時,在數組擴容時, ArrayList 是增加原來的 0.5倍,變成 1.5倍長度,而Vector 是增加 1倍,變成 2倍長度。
        jdk7:創建 ArrayList 對象時,默認長度爲 10,類似餓漢模式
        jdk8:創建 ArrayList 對象時,默認長度爲 0,在你第一次插入數據時,創建一個 長度爲10 的數組,類似懶漢模式
6、String 、StringBuffer、StringBuilder
        在這方面運行速度快慢爲:StringBuilder > StringBuffer > String,原因如下:
            String爲字符串常量,而StringBuilder和StringBuffer均爲字符串變量,即String對象一旦創建之後該對象是不可更改的,但後兩者的對象是變量,是可以更改的。Java中對String對象進行的操作實際上是一個不斷創建新的對象並且將舊的對象回收的一個過程,所以執行速度很慢。而StringBuilder和StringBuffer的對象是變量,對變量進行操作就是直接對該對象進行更改,而不進行創建和回收的操作,所以速度要比String快很多。
        在線程安全上,StringBuilder是線程不安全的,而StringBuffer是線程安全的。StringBuffer中很多方法可以帶有synchronized關鍵字,所以可以保證線程是安全的。
        即:String:適用於少量的字符串操作的情況
        	StringBuilder:適用於單線程下在字符緩衝區進行大量操作的情況
        	StringBuffer:適用多線程下在字符緩衝區進行大量操作的情況
7、HashMap、LinkedHashMap、Hashtable、ConcurrentHashMap
        HashMap是基於哈希表的Map接口的非同步實現(多線程不安全), 允許使用null值和null鍵(HashMap最多隻允許一條記錄的鍵爲null,允許多條記錄的值爲null);
        Hashtable也是一個散列表,它存儲的內容是鍵值對。基於Dictionary類 存儲數據: 首先判斷value是否爲空,爲空則拋出異常;計算key的hash值,並根據hash值獲得key在table數組中的位置index,如果table[index]元素不爲空,則進行迭代,如果遇到相同的key,則直接替換,並返回舊value;否則,我們可以將其插入到table[index]位置。 key和value都不允許爲null,Hashtable遇到null,直接返回NullPointerException。 線程安全,幾乎所有的public的方法都是synchronized的,較HashMap速度慢。
        ConcurrentHashMap是弱一致性,也就是說遍歷過程中其他線程可能對鏈表結構做了調整,因此get和containsKey返回的可能是過時的數據 ConcurrentHashMap是基於分段鎖設計來實現線程安全性,只有在同一個分段內才存在競態關係,不同的分段鎖之間沒有鎖競爭。
        LinkedHashMap是HashMap的一個子類,它保留插入順序,幫助我們實現了有序的HashMap。 其維護一個雙向鏈表,並不是說其除了維護存入的數據,另外維護了一個雙向鏈表對象,而是說其根據重寫HashMap的實體類Entry,來實現能夠將HashMap的數據組成一個雙向列表,其存儲的結構還是數組+鏈表的形式。
        TreeMap 是一個有序的key-value集合,它是通過紅黑樹實現的。 該映射根據其鍵的自然順序(字母排序)進行排序,或者根據創建映射時提供的 Comparator 進行排序,具體取決於使用的構造方法。 TreeMap是非線程安全的。
        jdk7:創建 HashMap對象時,默認長度爲 16,類似餓漢模式(內部數據結構是 數組加鏈表);新加元素時 元素往頭部添加
        jdk8:創建 HashMap對象時,默認長度爲 0,在你第一次插入數據時,創建一個 長度爲16 的數組,類似懶漢模式(內部數據結構是 數組加鏈表再加紅黑樹);新加元素時 元素往樹尾部添加
8、http 、 https
        HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,爲了保證這些隱私數據能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。
        HTTPS和HTTP的區別主要如下:
        1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
        2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
        3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。
        4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
9、json、gson
        JSON是一種與開發語言無關的,輕量級的數據格式,全稱是JavaScript Object Notation,現在幾乎每種語言都有處理JSON的API。
        Gson是Google提供的用來在Java對象和JSON數據之間進行映射的Java類庫,可以將一個JSON字符串轉成一個Java對象,或者反過來 。
10、sleep()/wait()
        sleep就是正在執行的線程主動讓出cpu,cpu去執行其他線程,在sleep指定的時間過後,cpu纔會回到這個線程上繼續往下執行 。如果當前線程進入了同步鎖,sleep方法並不會釋放鎖,即使當前線程使用sleep方法讓出了cpu,但其他被同步鎖擋住了的線程也無法得到執行。
        wait是指在一個已經進入了同步鎖的線程內,讓自己暫時讓出同步鎖,以便其他正在等待此鎖的線程可以得到同步鎖並運行。只有其他線程調用了notify方法,調用wait方法的線程就會解除wait狀態和程序可以再次得到鎖後繼續向下運行。 
【注意】notify並不釋放鎖,只是告訴調用過wait方法的線程可以去參與獲得鎖的競爭了,但不是馬上得到鎖,因爲鎖還在別人手裏,別人還沒釋放。如果notify方法後面的代碼還有很多,需要這些代碼執行完後纔會釋放鎖 。
【總結】notify是告訴wait()的線程什麼時候可以去繼續去申請鎖了。
    舉例:這兩個方法來自不同的類分別是,sleep來自Thread類,和wait來自Object類。sleep是Thread的靜態類方法,誰調用的誰去睡覺,即使在a線程裏調用了b的sleep方法,實際上還是a去睡覺,要讓b線程睡覺要在b的代碼中調用sleep。
        最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
11、== / equals()
        java中的數據類型分爲兩種:
        一 、基本數據類型:
         byte、short、int、long、float、double、char、boolean
          比較它們需要用  ==  ,比較的是它們的值是否相等
           二、引用數據類型:
           也就是對基本數據類型的封裝,用 == 比較的是它們的內存地址(其實還是比較的基本數據類型,它們的內存地址不就是int嗎)。當new的時候,會給它一個新的內存地址,所以再通過==比較,就會返回false;在Object類中的equals方法其實比較的也是內存地址,用==和equals方法比較結果是一樣的,但在一些類中把equals方法重寫了,如String、Integer等類中,而不是單純的比較內存地址了,而是比較內容或者值是否相等。
            這個equals方法不是固定的,有需要的時候,我們根據情況自己重寫。
12、cookie / session
        cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
        cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
       考慮到安全應當使用session。
        session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
       考慮到減輕服務器性能方面,應當使用COOKIE。
        單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
    所以個人建議:
           將登陸信息等重要信息存放爲SESSION
           其他信息如果需要保留,可以放在COOKIE中
13、DOM / SAX 解析
        SAX解析方式:逐行掃描文檔,一遍掃描一遍解析。相比於DOM,SAX可以在解析文檔的任意時刻停止解析解析,是一種速度更快,更高效的方法。 優點:解析可以立即開始,速度快,沒有內存壓力 缺點:不能對結點做修改 ;適用於讀取 XML文件。
        DOM解析方式:DOM解析器在解析XML文檔時,會把文檔中的所有元素,按照其出現的層次關係,解析成一個個Node對象(節點) 優點:把XML文件在內存中構建屬性結構,可以遍歷和修改節點。 缺點:如果文件比較大,內存有壓力,解析的時間會比較長。適用於修改 XML文件
14、stack / queue
        棧與隊列的相同點: 
            1.都是線性結構。 
            2.插入操作都是限定在表尾進行。
            3.都可以通過順序結構和鏈式結構實現。
            4.插入與刪除的時間複雜度都是O(1),在空間複雜度上兩者也一樣。
            5.多鏈棧和多鏈隊列的管理模式可以相同。 
        棧與隊列的不同點: 
            1.刪除數據元素的位置不同,棧的刪除操作在表尾進行,隊列的刪除操作在表頭進行。 
            2.應用場景不同;常見棧的應用場景包括括號問題的求解,表達式的轉換和求值,函數調用和遞歸實現,深度優先搜索遍歷等;常見的隊列的應用場景包括計算機系統中各種資源的管理,消息緩衝器的管理和廣度優先搜索遍歷等。 
            3.順序棧能夠實現多棧空間共享,而順序隊列不能。
15、集合類
       ![在這裏插入圖片描述](https://img-blog.csdn.net/20180922213024919?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODkxMzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
        Collection是一個接口,它主要的兩個分支是:List 和 Set。
        List和Set都是接口,它們繼承於Collection。List是有序的隊列,List中可以有重複的元素;而Set是數學概念中的集合,Set中沒有重複元素!
        List和Set都有它們各自的實現類。
         爲了方便,我們抽象出了AbstractCollection抽象類,它實現了Collection中的絕大部分函數;這樣,在Collection的實現類中,我們就可以通過繼承AbstractCollection省去重複編碼。AbstractList和AbstractSet都繼承於AbstractCollection,具體的List實現類繼承於AbstractList,而Set的實現類則繼承於AbstractSet。
          另外,Collection中有一個iterator()函數,它的作用是返回一個Iterator接口。通常,我們通過Iterator迭代器來遍歷集合。ListIterator是List接口所特有的,在List接口中,通過ListIterator()返回一個ListIterator對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章