Java 基礎面經(一)

1 面向對象的特點有哪些?

抽象、繼承、封裝、多態

2 抽象類和普通類的區別?

  1. 抽象方法的訪問修飾符必須爲 public 和 protected。
  2. 抽象類不能被實例化。
  3. 如果一個類繼承於抽象類,則子類必須實現父類的抽象方法,如果子類沒有實現父類的抽象方法,則子類必須也一個抽象類。

3 抽象類和接口的區別?

  1. 一個類只能繼承一個抽象類,而一個類可以實現多個接口。
  2. 抽象類可以有構造方法,接口中不能有構造方法。
  3. 抽象類中可以有成員變量,接口中沒有成員變量。(被 final 修飾變成了常量)
  4. 抽象類中可以有普通方法,接口中所有方法都必須是抽象的。(1.8後允許接口定義非抽象方法)
  5. 抽象類中抽象方法的訪問類型可以是 public,protected,但接口中抽象方法的訪問類型只能是public,並且默認爲 public abstract(省略則自動默認補全)。
  6. 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是 public static final 類型的;
  7. 抽象類中可以有靜態代碼塊和靜態方法,接口中不能含有靜態代碼塊以及靜態方法

4 重載(Overload)的特點

  1. 在使用重載時只能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法內的幾個參數類型必須不一樣,例如可以是fun(int,float), 但是不能爲fun(int, int));
  2. 不能通過訪問權限、返回類型、拋出的異常進行重載;
  3. 方法的異常類型和數目不會對重載造成影響;
  4. 對於繼承來說,如果某一方法在父類中是訪問權限是 priavte,那麼就不能在子類對其進行重載,如果定義的話,也只是定義了一個新方法,而不會達到重載的效果。

5 重寫(Override)的特點

  1. 覆蓋的方法的標誌必須要和被覆蓋的方法的標誌完全匹配,才能達到覆蓋的效果;
  2. 覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
  3. 覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
  4. 被覆蓋的方法不能爲 private,否則在其子類中只是新定義了一個方法,並沒有對其進行覆蓋。
  5. 子類方法不能縮小父類方法的訪問權限。
  6. 方法被定義爲 final 不能被重寫。

6 基本類型

java 的基本類型如下:

  • 整型:byte(1字節)、short(2字節)、int(4字節)、long(8字節)
  • 浮點型:float(4字節)、double(8字節)
  • 字符型:char(2字節)
  • 布爾類型:boolean(1字節)

其中數據類型轉換(自動),即較小的類型轉換爲一個更大的類型,爲: byte -> short -> char -> int -> long -> float ->double

7 自動拆箱和自動裝箱

在 Java SE5 中,爲了減少開發人員的工作,Java 提供了自動拆箱與自動裝箱功能。自動裝箱就是將基本數據類型自動轉換成對應的包裝類,自動拆箱就是將包裝類自動轉換成對應的基本數據類型。

哪些場景會發生裝箱與拆箱?

  1. 將基本數據類型放入集合類
  2. 包裝類型和基本類型的大小比較
  3. 包裝類型的運算
  4. 三目運算符的使用
  5. 函數參數與返回值

8 Java 類的實例化順序?

其順序爲:

  1. 父類靜態成員和靜態代碼塊
  2. 子類靜態成員和靜態代碼塊
  3. 父類非靜態成員和非靜態代碼塊
  4. 父類構造方法
  5. 子類非靜態成員和非靜態代碼塊
  6. 子類構造方法

9 值傳遞與引用傳遞

可參考: java基本數據類型傳遞與引用傳遞區別詳解

關於值傳遞與引用傳遞,這個問題一般是相對函數而言的,即 java 中的方法參數。值傳遞指的是方法接收的是調用着提供的值,引用傳遞指的是方法接收的是調用者提供的變量地址(C 語言的指針)。值傳遞與引用傳遞的根本區別是一個方法可以修改傳遞引用所對應的變量值,而不能修改傳遞值調用所對應的變量值。在 java 中並不存在引用調用,方法得到的是所有參數值的一個拷貝,方法並不能修改傳遞給它的任何參數變量的內容。

  1. 一個方法不能修改一個基本數據類型的參數(數值型和布爾型),這裏使用的是值傳遞。
  2. 一個方法可以修改一個引用所指向的對象狀態,但這仍然是值傳遞而非引用傳遞。

10 final 修飾符的作用

final 表示無法改變。

  1. final 類不能被繼承,沒有子類,final 類中的方法默認是 final 的。
  2. final 方法不能被子類的方法覆蓋,但可以被繼承。
  3. final 成員變量表示常量,只能被賦值一次,賦值後值不再改變。
  4. final 不能用於修飾構造方法。

11 String,StringBuilder,StringBuffer 的區別?

  1. String 是不可變的,而 StringBuilder 和 StringBuffer 是可變的。
  2. 運行速度快慢爲:StringBuilder > StringBuffer > String。
  3. StringBuilder 是線程不安全的,而 StringBuffer,String 是線程安全的。

12 Error 與 Exception 的區別?

可參考:Java異常Error和Exception的區別

在這裏插入圖片描述
事實上,Java 的異常可以分爲以下三類:

  1. 錯誤: 錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中通常被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。
  2. 檢查性異常:最具代表的檢查性異常是用戶錯誤或問題引起的異常,這是程序員無法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。
  3. 運行時異常: 運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常可以在編譯時被忽略。

所有異常類型都是內置類 Throwable 的子類,因而 Throwable 在異常類的層次結構的頂層。接下來 Throwable 分成了兩個不同的分支,一個分支是 Error,它表示不希望被程序捕獲或者是程序無法處理的錯誤。另一個分支是 Exception,它表示用戶程序可能捕捉的異常情況或者說是程序可以處理的異常。其中異常類 Exception 又分爲運行時異常( RuntimeException )和非運行時異常。

  1. Error:Error 類對象由 Java 虛擬機生成並拋出,大多數錯誤與代碼編寫者所執行的操作無關。例如,Java虛擬機運行錯誤(Virtual MachineError),當 JVM 不再有繼續執行操作所需的內存資源時,將出現 OutOfMemoryError。這些異常發生時,Java 虛擬機(JVM)一般會選擇線程終止;還有發生在虛擬機試圖執行應用時,如類定義錯誤(NoClassDefFoundError)、鏈接錯誤(LinkageError)。這些錯誤是不可查的,因爲它們在應用程序的控制和處理能力之外,而且絕大多數是程序運行時不允許出現的狀況。對於設計合理的應用程序來說,即使確實發生了錯誤,本質上也不應該試圖去處理它所引起的異常狀況。在 Java 中,錯誤通常是使用 Error 的子類描述。
  2. Exception:在 Exception 分支中有一個重要的子類 RuntimeException(運行時異常),該類型的異常自動爲你所編寫的程序定義 ArrayIndexOutOfBoundsException(數組下標越界)、NullPointerException(空指針異常)、ArithmeticException(算術異常)、MissingResourceException(丟失資源)、ClassNotFoundException(找不到類)等異常,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯誤引起的,程序應該從邏輯角度儘可能避免這類異常的發生;而 RuntimeException 之外的異常我們統稱爲非運行時異常,類型上屬於 Exception 類及其子類,從程序語法角度講是必須進行處理的異常,如果不處理,程序就不能編譯通過。如 IOException、SQLException 等以及用戶自定義的 Exception 異常,一般情況下不自定義檢查異常。

13 throw 和 throws 的區別?

  1. throw 語句用在方法體內,表示拋出異常,由方法體內的語句處理。 throws 語句用在方法聲明後面,表示拋出異常,由該方法的調用者來處理。
  2. throws 主要是聲明這個方法會拋出這種類型的異常,使它的調用者知道要捕獲這個異常。 throw 是當程序出現某種邏輯錯誤時由程序員主動拋出某種特定類型的異常是,具體向外拋異常的動作,所以它是拋出一個異常實例。
  3. throws 表示出現異常的一種可能性,並不一定會發生這些異常;throw 則是拋出了異常,執行 throw 則一定拋出了某種異常對象。
  4. 兩者都是消極處理異常的方式(這裏的消極並不是說這種方式不好),只是拋出或者可能拋出異常,但是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。

14 JDK、JRE、JVM 的區別?

可參考:淺談JDK、JRE、JVM區別與聯繫

14.1 什麼是 JDK?

JDK (Java Development Kit) 是整個 JAVA 的核心,是 Java 語言的軟件開發工具包 (SDK),包括了 Java 運行環境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb 等)和 Java 基礎的類庫(即 Java API 包括 rt.jar )。

JDK 是 java 開發工具包,基本上每個學 java 的人都會先在機器 上裝一個 JDK,那它都包含哪幾部分呢?在目錄下面有六個文件夾、一個 src 類庫源碼壓縮包、和其他幾個聲明文件。其中,真正在運行 java 時起作用的是以下四個文件夾:bin(最主要的是編譯器)、include( java 和 JVM 交互用的頭文件)、lib(類庫)、 jre(java 運行環境)。有這樣一個關係,JDK 包含 JRE,而 JRE 包含 JVM。

jre 目錄裏面有兩個文件夾 bin 和 lib,在這裏可以認爲 bin 裏的就是 jvm,lib 中則是 jvm 工作所需要的類庫,而 jvm 和 lib 合起來就稱爲 jre。

總的來說 JDK 是用於 java 程序的開發,而 jre 則是隻能運行 class 而沒有編譯的功能。

14.2 什麼是 JRE?

JRE(Java Runtime Environment,Java 運行環境),包含 JVM 標準實現及 Java 核心類庫。JRE 是 Java 運行環境,並不是一個開發環境,所以沒有包含任何開發工具(如編譯器和調試器)。

JRE 是指 java 運行環境。光有 JVM 還不能完成 class 的執行,因爲在解釋 class 的時候 JVM 需要調用解釋所需要的類庫 lib。 (jre 裏有運行.class 的 java.exe)。

JRE 是運行 Java 程序必不可少的(除非用其他一些編譯環境編譯成 .exe 可執行文件),JRE 的地位就象一臺 PC 機一樣,我們寫好的 Win64 應用程序需要操作系統幫我們運行,同樣的,我們編寫的 Java 程序也必須要 JRE 才能運行。

14.3 什麼是 JVM?

JVM(Java Virtual Machine),即 java 虛擬機,是 java 運行時的環境,JVM 是一種用於計算設備的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。針對 java 用戶,也就是擁有可運行的.class 文件包(jar 或者 war)的用戶。裏面主要包含了 jvm 和 java 運行時基本類庫(rt.jar)。rt.jar 可以簡單粗暴地理解爲:它就是 java 源碼編譯成的 jar 包。Java 虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的機器指令執行。這就是 Java 的能夠“一次編譯,到處運行”的原因。

14.4 JDK、JRE、JVM 三者的聯繫?

JVM 不能單獨搞定 class 的執行,解釋 class 的時候 JVM 需要調用解釋所需要的類庫 lib。在 JDK 下面的的 jre 目錄裏面有兩個文件夾 bin 和 lib,在這裏可以認爲 bin 裏的就是 jvm,lib 中則是 jvm 工作所需要的類庫,而 jvm 和 lib 和起來就稱爲 jre,jvm + lib = JRE。總體來說就是,我們利用 JDK(調用 JAVA API)開發了屬於我們自己的 JAVA 程序後,通過 JDK 中的編譯程序(javac)將我們的文本 java 文件編譯成 JAVA 字節碼,在 JRE 上運行這些 JAVA 字節碼,JVM 解析這些字節碼,映射到 CPU 指令集或 OS 的系統調用。

14.5 JDK、JRE 的區別?

在 bin 文件夾下會發現,JDK 有 javac.exe 而 JRE 裏面沒有,javac 指令是用來將 java 文件編譯成 class 文件的,這是開發者需要的,而用戶(只需要運行的人)是不需要的。JDK 還有 jar.exe, javadoc.exe 等等用於開發的可執行指令文件。這也證實了一個是開發環境,一個是運行環境。

14.6 JRE、JVM 的區別?

JVM 並不代表就可以執行 class 了,JVM 執行 .class 還需要 JRE 下的 lib 類庫的支持,尤其是 rt.jar。

參考:接口和抽象類有什麼聯繫和區別?
【面試題】重載和重寫的區別
Java的基本數據類型詳解
【Java面試官】史上最全的JAVA專業術語面試100問
java中throw和throws的區別.

發佈了123 篇原創文章 · 獲贊 226 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章