Java開發崗面試知識點解析

本文做者參加過多場面試,應聘崗位均爲 Java 開發方向。在不斷的面試中,分類總結了 Java 開發崗位面試中的一些知識點。前端

主要包括如下幾個部分:java

  1. Java 基礎知識點程序員

  2. Java 常見集合面試

  3. 高併發編程(JUC 包)算法

  4. JVM 內存管理sql

  5. Java 8 知識點數據庫

  6. 網絡協議相關編程

  7. 數據庫相關bootstrap

  8. MVC 框架相關數組

  9. 大數據相關

  10. Linux 命令相關

  面試,是你們從學校走向社會的第一步。互聯網公司的校園招聘,從形式上說,面試通常分爲 2-3 輪技術面試 +1 輪 HR 面試可是一些公司確實是沒有 HR 面試的,直接就是三輪技術面。技術面試中,面試官通常會先就你所應聘的崗位進行相關知識的考察,也叫基礎知識業務邏輯面試只要你回答的不是特別差,面試官一般會說:「我們寫個代碼吧」,這個時候就開始了算法面試。也就是說,一輪技術面試 = 基礎知識和業務邏輯面試 + 算法面試。

  本文咱們主要從技術面試聊起。技術面試包括:業務邏輯和基礎知識面試。

  首先是業務邏輯面試,也就是講項目。面試官會對你簡歷上寫的若干個項目其中之一拿出來和你聊聊。在期間,會針對你所作的東西進行深度挖掘。包括:爲何要這麼作?優缺點分析,假如從新讓你作一次,你打算怎麼作? 等等。這個環節主要考察咱們對本身作過的項目(實習項目或者校內項目)是否有一個清晰的認識。關於業務邏輯面試的準備,建議在平時多多思考總結,對項目的數據來源、總體運行框架都應該熟悉掌握。好比說你在某公司實習過程當中,就能夠進行總結,而沒必要等到快離職的時候慌慌張張的去總結該項目。

  接下來是基礎知識面試。Java 開發屬於後臺開發方向,有人說後臺開發很坑,由於須要學習的東西太多了。沒錯,這個崗位就是須要學習好多東西。包括:本語言(Java/C++/PHP)基礎、數據庫、網絡協議、Linux 系統、計算機原理甚至前端相關知識均可以考察你,並且,並不超綱。有時候,你報的是後臺開發崗,而且熟悉的是 Java 語言,可是面試官倒是 C++ 開發方向的,就是這麼無奈~好了,閒話少說,讓咱們開始分類講解常見面試知識點。

Java 基礎知識

 

01. 面向對象的特性有哪些?

答:封裝、繼承和多態。

02. Java 中覆蓋和重載是什麼意思?

解析:覆蓋和重載是比較重要的基礎知識點,而且容易混淆,因此面試中常見。

答:覆蓋(Override)是指子類對父類方法的一種重寫,只能比父類拋出更少的異常,訪問權限不能比父類的小。

被覆蓋的方法不能是 private 的,不然只是在子類中從新定義了一個方法;重載(Overload)表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同。

面試官: 那麼構成重載的條件有哪些?

答:參數類型不一樣、參數個數不一樣、參數順序不一樣。

面試官: 函數的返回值不一樣能夠構成重載嗎?爲何?

答:不能夠,由於 Java 中調用函數並不須要強制賦值。舉例以下:

以下兩個方法:

    void f(){}    int f(){ return 1;}

只要編譯器能夠根據語境明確判斷出語義,好比在 int x = f();中,那麼的確能夠據此區分重載方法。

不過, 有時你並不關心方法的返回值,你想要的是方法調用的其餘效果 (這常被稱爲 「爲了反作用而調用」),這時你可能會調用方法而忽略其返回值,因此若是像下面的調用:

    fun();

此時 Java 如何才能判斷調用的是哪個 f( ) 呢?別人如何理解這種代碼呢?因此,根據方法返回值來區分重載方法是行不通的。

 

03. 抽象類和接口的區別有哪些?

答:

  1. 抽象類中能夠沒有抽象方法;接口中的方法必須是抽象方法;

  2. 抽象類中能夠有普通的成員變量;接口中的變量必須是 static final 類型的,必須被初始化 , 接口中只有常量,沒有變量。

  3. 抽象類只能單繼承,接口能夠繼承多個父接口;

  4. Java8 中接口中會有 default 方法,即方法能夠被實現。

面試官:抽象類和接口如何選擇?

答:

  1. 若是要建立不帶任何方法定義和成員變量的基類,那麼就應該選擇接口而不是抽象類。

  2. 若是知道某個類應該是基類,那麼第一個選擇的應該是讓它成爲一個接口,只有在必需要有方法定義和成員變量的時候,才應該選擇抽象類。

    由於抽象類中容許存在一個或多個被具體實現的方法,只要方法沒有被所有實現該類就還是抽象類。

04. Java 和 C++ 的區別:

解析:雖然咱們不太懂 C++,可是就是會這麼問,尤爲是三面(總監級別)面試中。

答:

  1. 都是面向對象的語言,都支持封裝、繼承和多態;

  2. 指針:Java 不提供指針來直接訪問內存,程序更加安全;

  3. 繼承: Java 的類是單繼承的,C++ 支持多重繼承; Java 經過一個類實現多個接口來實現 C++ 中的多重繼承; Java 中類不能夠多繼承,可是!!!接口能夠多繼承;

  4. 內存: Java 有自動內存管理機制,不須要程序員手動釋放無用內存。

05. Java 中的值傳遞和引用傳遞

答:

值傳遞是指對象被值傳遞,意味着傳遞了對象的一個副本,即便副本被改變,也不會影響源對象。引用傳遞是指對象被引用傳遞,意味着傳遞的並非實際的對象,而是對象的引用。

所以,外部對引用對象的改變會反映到全部的對象上。

06. JDK 中經常使用的包有哪些?

答:java.lang、java.util、java.io、java.net、java.sql。

07. JDK,JRE 和 JVM 的聯繫和區別:

答:

JDK 是 java 開發工具包,是 java 開發環境的核心組件,並提供編譯、調試和運行一個 java 程序所須要的全部工具,可執行文件和二進制文件,是一個平臺特定的軟件。

JRE 是 java 運行時環境,是 JVM 的實施實現,提供了運行 java 程序的平臺。JRE 包含了 JVM,可是不包含 java 編譯器 / 調試器之類的開發工具。

JVM 是 java 虛擬機,當咱們運行一個程序時,JVM 負責將字節碼轉換爲特定機器代碼,JVM 提供了內存管理 / 垃圾回收和安全機制等。

這種獨立於硬件和操做系統,正是 java 程序能夠一次編寫多處執行的緣由。

區別:

  1. JDK 用於開發,JRE 用於運行 java 程序;

  2. JDK 和 JRE 中都包含 JVM;

  3. JVM 是 java 編程語言的核心而且具備平臺獨立性。

小結:本節主要闡述了 Java 基礎知識點,這些問題主要是一面面試官在考察,難度不大,適當複習下,應該沒什麼問題。

 

 

Java 中常見集合

 

集合這方面的考察至關多,這部分是面試中必考的知識點。

01. 說說常見的集合有哪些吧?

答:

Map 接口和 Collection 接口是全部集合框架的父接口:

1. Collection 接口的子接口包括:Set 接口和 List 接口;

2. Map 接口的實現類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;

3. Set 接口的實現類主要有:HashSet、TreeSet、LinkedHashSet 等;

4. List 接口的實現類主要有:ArrayList、LinkedList、Stack 以及 Vector 等。

02. HashMap 和 Hashtable 的區別有哪些?(必問)

答:

  1. HashMap 沒有考慮同步,是線程不安全的;Hashtable 使用了 synchronized 關鍵字,是線程安全的;

  2. 前者容許 null 做爲 Key;後者不容許 null 做爲 Key。

03. HashMap 的底層實現你知道嗎?

答:

在 Java8 以前,其底層實現是數組 + 鏈表實現,Java8 使用了數組 + 鏈表 + 紅黑樹實現。此時你能夠簡單的在紙上畫圖分析:

 

04. ConcurrentHashMap 和 Hashtable 的區別? (必問)

答:

ConcurrentHashMap 結合了 HashMap 和 HashTable 兩者的優點。

HashMap 沒有考慮同步,hashtable 考慮了同步的問題。可是 hashtable 在每次同步執行時都要鎖住整個結構。

ConcurrentHashMap 鎖的方式是稍微細粒度的。 ConcurrentHashMap 將 hash 表分爲 16 個桶(默認值),諸如 get,put,remove 等經常使用操做只鎖當前須要用到的桶。

面試官:ConcurrentHashMap 的具體實現知道嗎?

答:

  1. 該類包含兩個靜態內部類 HashEntry 和 Segment;前者用來封裝映射表的鍵值對,後者用來充當鎖的角色;

  2. Segment 是一種可重入的鎖 ReentrantLock,每一個 Segment 守護一個 HashEntry 數組裏得元素,當對 HashEntry 數組的數據進行修改時,必須首先得到對應的 Segment 鎖。

05. HashMap 的長度爲何是 2 的冪次方?

答:

  1. 經過將 Key 的 hash 值與 length-1 進行 & 運算,實現了當前 Key 的定位,2 的冪次方能夠減小衝突(碰撞)的次數,提升 HashMap 查詢效率;

  2. 若是 length 爲 2 的次冪  則 length-1 轉化爲二進制一定是 11111……的形式,在於 h 的二進制與操做效率會很是的快,並且空間不浪費;

  3. 若是 length 不是 2 的次冪,好比 length 爲 15,則 length-1 爲 14,對應的二進制爲 1110,在於 h 與操做,最後一位都爲 0,而 0001,0011,0101,1001,1011,0111,1101 這幾個位置永遠都不能存放元素了,空間浪費至關大。

    更糟的是這種狀況中,數組可使用的位置比數組長度小了不少,這意味着進一步增長了碰撞的概率,減慢了查詢的效率!這樣就會形成空間的浪費。

06. List 和 Set 的區別是啥?

答:List 元素是有序的,能夠重複;Set 元素是無序的,不能夠重複。

07. List、Set 和 Map 的初始容量和加載因子

答:

1. List

  • ArrayList 的初始容量是 10;加載因子爲 0.5; 擴容增量:原容量的 0.5 倍 +1;一次擴容後長度爲 16。

  • Vector 初始容量爲 10,加載因子是 1。擴容增量:原容量的 1 倍,如 Vector 的容量爲 10,一次擴容後是容量爲 20。

2. Set

HashSet,初始容量爲 16,加載因子爲 0.75; 擴容增量:原容量的 1 倍; 如 HashSet 的容量爲 16,一次擴容後容量爲 32

3. Map

HashMap,初始容量 16,加載因子爲 0.75; 擴容增量:原容量的 1 倍; 如 HashMap 的容量爲 16,一次擴容後容量爲 32

08. Comparable 接口和 Comparator 接口有什麼區別?

答:

  1. 前者簡單,可是若是須要從新定義比較類型時,須要修改源代碼。

  2. 後者不須要修改源代碼,自定義一個比較器,實現自定義的比較方法。

09. Java 集合的快速失敗機制 「fail-fast」

答:

它是 java 集合的一種錯誤檢測機制,當多個線程對集合進行結構上的改變的操做時,有可能會產生 fail-fast 機制。

例如 :假設存在兩個線程(線程 一、線程 2),線程 1 經過 Iterator 在遍歷集合 A 中的元素,在某個時候線程 2 修改了集合 A 的結構(是結構上面的修改,而不是簡單的修改集合元素的內容),那麼這個時候程序就會拋出 ConcurrentModificationException 異常,從而產生 fail-fast 機制。

緣由: 迭代器在遍歷時直接訪問集合中的內容,而且在遍歷過程當中使用一個 modCount 變量。集合在被遍歷期間若是內容發生變化,就會改變 modCount 的值。

每當迭代器使用 hashNext()/next() 遍歷下一個元素以前,都會檢測 modCount 變量是否爲 expectedmodCount 值,是的話就返回遍歷;不然拋出異常,終止遍歷。

解決辦法:

  1. 在遍歷過程當中,全部涉及到改變 modCount 值得地方所有加上 synchronized;

  2. 使用 CopyOnWriteArrayList 來替換 ArrayList。

小結:本小節是 Java 中關於集合的考察,是 Java 崗位面試中必考的知識點,除了應該掌握以上的問題,包括各個集合的底層實現也建議各位同窗閱讀,加深理解。

 

 

高併發編程

在 Java 5.0 提供了 java.util.concurrent(簡稱 JUC )包,在此包中增長了在併發編程中很經常使用的實用工具類,用於定義相似於線程的自定義子系統,包括線程池、異步 IO 和輕量級任務框架。

01. 多線程和單線程的區別和聯繫:

答:

  1. 在單核 CPU 中,將 CPU 分爲很小的時間片,在每一時刻只能有一個線程在執行,是一種微觀上輪流佔用 CPU 的機制。

  2. 多線程會存在線程上下文切換,會致使程序執行速度變慢,即採用一個擁有兩個線程的進程執行所須要的時間比一個線程的進程執行兩次所須要的時間要多一些。

結論:即採用多線程不會提升程序的執行速度,反而會下降速度,可是對於用戶來講,能夠減小用戶的響應時間。

02. 如何指定多個線程的執行順序?

解析:面試官會給你舉個例子,如何讓 10 個線程按照順序打印 0123456789?(寫代碼實現)

答:

  1. 設定一個 orderNum,每一個線程執行結束以後,更新 orderNum,指明下一個要執行的線程。而且喚醒全部的等待線程。

  2. 在每個線程的開始,要 while 判斷 orderNum 是否等於本身的要求值!!不是,則 wait,是則執行本線程。

03. 線程和進程的區別(必考)

答:

  1. 進程是一個 「執行中的程序」,是系統進行資源分配和調度的一個獨立單位;

  2. 線程是進程的一個實體,一個進程中擁有多個線程,線程之間共享地址空間和其它資源(因此通訊和同步等操做線程比進程更加容易);

  3. 線程上下文的切換比進程上下文切換要快不少。

    • (1)進程切換時,涉及到當前進程的 CPU 環境的保存和新被調度運行進程的 CPU 環境的設置。

    • (2)線程切換僅須要保存和設置少許的寄存器內容,不涉及存儲管理方面的操做。

04. 多線程產生死鎖的 4 個必要條件?

答:

  1. 互斥條件:一個資源每次只能被一個線程使用;

  2. 請求與保持條件:一個線程因請求資源而阻塞時,對已得到的資源保持不放;

  3. 不剝奪條件:進程已經得到的資源,在未使用完以前,不能強行剝奪;

  4. 循環等待條件:若干線程之間造成一種頭尾相接的循環等待資源關係。

面試官:如何避免死鎖?(常常接着問這個問題哦~)

答:指定獲取鎖的順序,舉例以下:

  1. 好比某個線程只有得到 A 鎖和 B 鎖才能對某資源進行操做,在多線程條件下,如何避免死鎖?

  2. 得到鎖的順序是必定的,好比規定,只有得到 A 鎖的線程纔有資格獲取 B 鎖,按順序獲取鎖就能夠避免死鎖!!!

05. sleep( ) 和 wait( n)、wait( ) 的區別:

答:

  1. sleep 方法:是 Thread 類的靜態方法,當前線程將睡眠 n 毫秒,線程進入阻塞狀態。當睡眠時間到了,會解除阻塞,進行可運行狀態,等待 CPU 的到來。睡眠不釋放鎖(若是有的話);

  2. wait 方法:是 Object 的方法,必須與 synchronized 關鍵字一塊兒使用,線程進入阻塞狀態,當 notify 或者 notifyall 被調用後,會解除阻塞。可是,只有從新佔用互斥鎖以後纔會進入可運行狀態。睡眠時,釋放互斥鎖。

06. synchronized 關鍵字:

答:

底層實現:

  1. 進入時,執行 monitorenter,將計數器 +1,釋放鎖 monitorexit 時,計數器-1;

  2. 當一個線程判斷到計數器爲 0 時,則當前鎖空閒,能夠佔用;反之,當前線程進入等待狀態。

含義:(monitor 機制)

Synchronized 是在加鎖,加對象鎖。對象鎖是一種重量鎖(monitor),synchronized 的鎖機制會根據線程競爭狀況在運行時會有偏向鎖(單一線程)、輕量鎖(多個線程訪問 synchronized 區域)、對象鎖(重量鎖,多個線程存在競爭的狀況)、自旋鎖等。

該關鍵字是一個幾種鎖的封裝。

07. volatile 關鍵字

解析:關於指令重排序的問題,能夠查閱 DCL 雙檢鎖失效相關資料。

答:

該關鍵字能夠保證可見性不保證原子性。

功能:

  1. 主內存和工做內存,直接與主內存產生交互,進行讀寫操做,保證可見性;

  2. 禁止 JVM 進行的指令重排序。

08. ThreadLocal(線程局部變量)關鍵字:

答:

當使用 ThreadLocal 維護變量時,其爲每一個使用該變量的線程提供獨立的變量副本,因此每個線程均可以獨立的改變本身的副本,而不會影響其餘線程對應的副本。

ThreadLocal 內部實現機制:

  1. 每一個線程內部都會維護一個相似 HashMap 的對象,稱爲 ThreadLocalMap,裏邊會包含若干了 Entry(K-V 鍵值對),相應的線程被稱爲這些 Entry 的屬主線程;

  2. Entry 的 Key 是一個 ThreadLocal 實例,Value 是一個線程特有對象。Entry 的做用便是:爲其屬主線程創建起一個 ThreadLocal 實例與一個線程特有對象之間的對應關係;

  3. Entry 對 Key 的引用是弱引用;Entry 對 Value 的引用是強引用。

 

09. Atomic 關鍵字:

答:可使基本數據類型以原子的方式實現自增自減等操做。

10. 線程池有了解嗎?(必考)

答:

java.util.concurrent.ThreadPoolExecutor 類就是一個線程池。客戶端調用 ThreadPoolExecutor.submit(Runnable task) 提交任務,線程池內部維護的工做者線程的數量就是該線程池的線程池大小,有 3 種形態:

  • 當前線程池大小 :表示線程池中實際工做者線程的數量;

  • 最大線程池大小 (maxinumPoolSize):表示線程池中容許存在的工做者線程的數量上限;

  • 核心線程大小 (corePoolSize ):表示一個不大於最大線程池大小的工做者線程數量上限。

  1. 若是運行的線程少於 corePoolSize,則 Executor 始終首選添加新的線程,而不進行排隊;

  2. 若是運行的線程等於或者多於 corePoolSize,則 Executor 始終首選將請求加入隊列,而不是添加新線程;

  3. 若是沒法將請求加入隊列,即隊列已經滿了,則建立新的線程,除非建立此線程超出 maxinumPoolSize, 在這種狀況下,任務將被拒絕。

限於篇幅有限,更多高併發編程中的問題,請參考:

1.  Java 多線程編程核心技術

2. Java多線程與併發編程

小結:本小節內容涉及到 Java 中多線程編程,線程安全等知識,是面試中的重點和難點。

 

 

JVM 內存管理

既然是 Java 開發面試,那麼對 JVM 的考察固然也是必須的,面試官通常會問你對 JVM 有了解嗎?

我一般都會把我所瞭解的都說一遍,包括:JVM 內存劃分、JVM 垃圾回收的含義,有哪些 GC 算法,年輕代和老年代各自的特色通通闡述一遍。

 

01. JVM 內存劃分:

  1. 方法區(線程共享):常量、靜態變量、JIT(即時編譯器) 編譯後的代碼也都在方法區;

  2. 堆內存(線程共享):垃圾回收的主要場所;

  3. 程序計數器: 當前線程執行的字節碼的位置指示器;

  4. 虛擬機棧(棧內存):保存局部變量、基本數據類型變量以及堆內存中某個對象的引用變量;

  5. 本地方法棧 :爲 JVM 提供使用 native 方法的服務。

02. 相似-Xms、-Xmn 這些參數的含義:

答:

堆內存分配:

  1. JVM 初始分配的內存由-Xms 指定,默認是物理內存的 1/64;

  2. JVM 最大分配的內存由-Xmx 指定,默認是物理內存的 1/4;

  3. 默認空餘堆內存小於 40% 時,JVM 就會增大堆直到-Xmx 的最大限制;空餘堆內存大於 70% 時,JVM 會減小堆直到 -Xms 的最小限制;

  4. 所以服務器通常設置-Xms、-Xmx 相等以免在每次 GC 後調整堆的大小。對象的堆內存由稱爲垃圾回收器的自動內存管理系統回收。

非堆內存分配:

  1. JVM 使用-XX:PermSize 設置非堆內存初始值,默認是物理內存的 1/64;

  2. 由 XX:MaxPermSize 設置最大非堆內存的大小,默認是物理內存的 1/4;

  3. -Xmn2G:設置年輕代大小爲 2G;

  4. -XX:SurvivorRatio,設置年輕代中 Eden 區與 Survivor 區的比值。

03. 垃圾回收算法有哪些?

答:

  1. 引用計數 :原理是此對象有一個引用,即增長一個計數,刪除一個引用則減小一個計數。垃圾回收時,只用收集計數爲 0 的對象。此算法最致命的是沒法處理循環引用的問題;

  2. 標記-清除 :此算法執行分兩階段。第一階段從引用根節點開始標記全部被引用的對象,第二階段遍歷整個堆,把未標記的對象清除;

    此算法須要暫停整個應用,同時,會產生內存碎片;

  3. 複製算法 :此算法把內存空間劃爲兩個相等的區域,每次只使用其中一個區域。垃圾回收時,遍歷當前使用區域,把正在使用中的對象複製到另一個區域中;

    此算法每次只處理正在使用中的對象,所以複製成本比較小,同時複製過去之後還能進行相應的內存整理,不會出現 「碎片」 問題。固然,此算法的缺點也是很明顯的,就是須要兩倍內存空間;

  4. 標記-整理 :此算法結合了 「標記-清除」 和 「複製」 兩個算法的優勢。也是分兩階段,第一階段從根節點開始標記全部被引用對象,第二階段遍歷整個堆,把清除未標記對象而且把存活對象 「壓縮」 到堆的其中一塊,按順序排放。

    此算法避免了 「標記-清除」 的碎片問題,同時也避免了 「複製」 算法的空間問題。

04. root 搜索算法中,哪些能夠做爲 root?

答:

  • 被啓動類(bootstrap 加載器)加載的類和建立的對象;

  • JavaStack 中的引用的對象 (棧內存中引用的對象);

  • 方法區中靜態引用指向的對象;

  • 方法區中常量引用指向的對象;

  • Native 方法中 JNI 引用的對象。

05. GC 何時開始?

答:

GC 常常發生的區域是堆區,堆區還能夠細分爲新生代、老年代,新生代還分爲一個 Eden 區和兩個 Survivor 區。

  1. 對象優先在 Eden 中分配,當 Eden 中沒有足夠空間時,虛擬機將發生一次 Minor GC,由於 Java 大多數對象都是朝生夕滅,因此 Minor GC 很是頻繁,並且速度也很快;

  2. Full GC,發生在老年代的 GC,當老年代沒有足夠的空間時即發生 Full GC,發生 Full GC 通常都會有一次 Minor GC。

    大對象直接進入老年代,如很長的字符串數組,虛擬機提供一個;XX:PretenureSizeThreadhold 參數,令大於這個參數值的對象直接在老年代中分配,避免在 Eden 區和兩個 Survivor 區發生大量的內存拷貝;

  3. 發生 Minor GC 時,虛擬機會檢測以前每次晉升到老年代的平均大小是否大於老年代的剩餘空間大小,若是大於,則進行一次 Full GC,若是小於,則查看 HandlePromotionFailure 設置是否容許擔保失敗,若是容許,那隻會進行一次 Minor GC,若是不容許,則改成進行一次 Full GC。

06. 內存泄漏和內存溢出

答:

概念:

  1. 內存溢出指的是內存不夠用了;

  2. 內存泄漏是指對象可達,可是沒用了。即本該被 GC 回收的對象並無被回收;

  3. 內存泄露是致使內存溢出的緣由之一;內存泄露積累起來將致使內存溢出。

內存泄漏的緣由分析:

  1. 長生命週期的對象引用短生命週期的對象;

  2. 沒有將無用對象置爲 null。

小結:本小節涉及到 JVM 虛擬機,包括對內存的管理等知識,相對較深。除了以上問題,面試官會繼續問你一些比較深的問題,可能也是爲了看看你的極限在哪裏吧。

好比:內存調優、內存管理,是否遇到過內存泄漏的實際案例、是否真正關心過內存等。因爲本人實際項目經驗不足,這些深層次問題並無接觸過,各位有須要能夠上網查閱。

 

 

Java 8 相關知識

關於 Java8 中新知識點,面試官會讓你說說 Java8 你瞭解多少,下邊主要闡述我所瞭解,而且在面試中回答的 Java8 新增知識點。

0.1 HashMap 的底層實現有變化:HashMap 是數組 + 鏈表 + 紅黑樹(JDK1.8 增長了紅黑樹部分)實現。

02. JVM 內存管理方面,由元空間代替了永久代。

區別:

1. 元空間並不在虛擬機中,而是使用本地內存;

2. 默認狀況下,元空間的大小僅受本地內存限制;

3. 也能夠經過 -XX:MetaspaceSize 指定元空間大小。

03. Lambda 表達式(也稱爲閉包),容許咱們將函數當成參數傳遞給某個方法,或者把代碼自己當作數據處理。

04. 函數式接口:指的是隻有一個函數的接口,java.lang.Runnable 和 java.util.concurrent.Callable 就是函數式接口的例子;java8 提供了一個特殊的註解 @Functionallnterface 來標明該接口是一個函數式接口。

05. 引入重複註解:Java 8 中使用 @Repeatable 註解定義重複註解。

06. 接口中能夠實現方法 default 方法。

07. 註解的使用場景拓寬: 註解幾乎可使用在任何元素上:局部變量、接口類型、超類和接口實現類,甚至能夠用在函數的異常定義上。

08. 新的包 java.time 包

  1. 包含了全部關於日期、時間、時區、持續時間和時鐘操做的類。

  2. 這些類都是不可變的、線程安全的。

小結:Java8 的一些新特性,面試官通常狀況下不要求你有多麼精通,主要是看看你有沒有一些瞭解。

 

 

網絡協議相關 

網絡協議方面,考察最多的包括服務器和客戶端在三次握手、四次揮手過程當中的狀態變化;還有網絡擁塞控制,及其解決辦法等。

01. 三次握手、四次揮手示意圖:

 

總共有四種狀態:主動創建鏈接、主動斷開鏈接、被動創建連和被動斷開鏈接

兩兩組合仍是 4 種組合:

  1. 主動創建鏈接、主動斷開鏈接會經歷的狀態:
    SYNC_SENT——ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT

  2. 主動創建鏈接、被動斷開鏈接會經歷的狀態:
    SYNC_SENT——ESTABLISHED—-CLOSE_WAIT—-LAST_ACK

  3. 被動創建鏈接、主動斷開鏈接會經歷的狀態:
    LISTEN—-SYN_RCVD—-ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT

  4. 被動創建鏈接、被動斷開鏈接會經歷的狀態:
    LISTEN—-SYN_RCVD—-ESTABLISHED—-CLOSE_WAIT—-LAST_ACK

02. 滑動窗口機制

由發送方和接收方在三次握手階段,互相將本身的最大可接收的數據量告訴對方。

也就是本身的數據接收緩衝池的大小。這樣對方能夠根據已發送的數據量來計算是否能夠接着發送。

在處理過程當中,當接收緩衝池的大小發生變化時,要給對方發送更新窗口大小的通知。

03. 擁塞避免機制

擁塞:對資源的需求超過了可用的資源。若網絡中許多資源同時供應不足,網絡的性能就要明顯變壞,整個網絡的吞吐量隨之負荷的增大而降低。

擁塞控制:防止過多的數據注入到網絡中,使得網絡中的路由器或鏈路不致過載。

擁塞控制方法:

  • 慢開始 + 擁塞避免;

  • 快重傳 + 快恢復。

 

 

04. 瀏覽器中輸入:「www.xxx.com」 以後都發生了什麼?請詳細闡述。

解析:經典的網絡協議問題。

答:

  1. 由域名→IP 地址
    尋找 IP 地址的過程依次通過了瀏覽器緩存、系統緩存、hosts 文件、路由器緩存、 遞歸搜索根域名服務器。

  2. 創建 TCP/IP 鏈接(三次握手具體過程)

  3. 由瀏覽器發送一個 HTTP 請求

  4. 通過路由器的轉發,經過服務器的防火牆,該 HTTP 請求到達了服務器

  5. 服務器處理該 HTTP 請求,返回一個 HTML 文件

  6. 瀏覽器解析該 HTML 文件,而且顯示在瀏覽器端

  7. 這裏須要注意:

    • HTTP 協議是一種基於 TCP/IP 的應用層協議,進行 HTTP 數據請求必須先創建 TCP/IP 鏈接

    • 能夠這樣理解:HTTP 是轎車,提供了封裝或者顯示數據的具體形式;Socket 是發動機,提供了網絡通訊的能力。

    • 兩個計算機之間的交流無非是兩個端口之間的數據通訊 , 具體的數據會以什麼樣的形式展示是以不一樣的應用層協議來定義的。

05. 常見 HTTP 狀態碼

  1. 1xx(臨時響應)

  2. 2xx(成功)

  3. 3xx(重定向):表示要完成請求須要進一步操做

  4. 4xx(錯誤):表示請求可能出錯,妨礙了服務器的處理

  5. 5xx(服務器錯誤):表示服務器在嘗試處理請求時發生內部錯誤

  6. 常見狀態碼:

    • 200(成功)

    • 304(未修改):自從上次請求後,請求的網頁未修改過。服務器返回此響應時,不會返回網頁內容

    • 401(未受權):請求要求身份驗證

    • 403(禁止):服務器拒絕請求

    • 404(未找到):服務器找不到請求的網頁

06. TCP 和 UDP 的區別:

答:

    1. 回答發送數據前是否存在創建鏈接的過程;

    2. TCP過確認機制,丟包能夠重發,保證數據的正確性;UDP不保證正確性,只是單純的負責發送數據包;

    3. UDP 是面向報文的。發送方的 UDP 對應用程序交下來的報文,在添加首部後就向下交付給 IP 層。既不拆分,也不合並,而是保留這些報文的邊界,因 此,應用程序須要選擇合適的報文大小;

    4. UDP 的頭部,只有 8 個字節,相對於 TCP 頭部的 20 個字節信息包的額外開銷很小。

相關文章
相關標籤/搜索