Java基礎面試系列(一)

  • 2020 年 3 月 13 日
  • 筆記

Java基礎面試總結(一)

1. 面向對象和面向過程的區別

面向過程 面向對象
性能 高於面向對象 類載入的時候需要實例化,比較消耗資源
三易(易維護,易復用,易擴展) 不如面向對象 具有封裝,繼承,多態的特性,可以設計低耦合的系統,有助於系統維護,擴展,復用

總結:

  • 面向過程
    • 優點:性能比面向對象高
    • 缺點:易維護,易復用,易擴展性比較差
    • 案例:Unix/Linux系統,單片機等等作業系統之類的
  • 面向對象
    • 優點:系統方便擴展,維護,復用
    • 缺點:性能不如面向過程,類載入的時候需要實例化,比較消耗資源
    • 案例:應用類型的系統。

2.JAVA語言的特點

  • 簡單易學
  • 面向對象(封裝,繼承,多態)
  • 平台無關性(通過Java虛擬機運行)
  • 可靠性
  • 安全性
  • 支援多執行緒(C++沒有內置的多執行緒機制,需要調用作業系統的多執行緒功能進行多執行緒程式設計)
  • 支援網路編程(Java語言的誕生就是為了簡化網路編程而設計)
  • 編譯和解釋並存

3.什麼是位元組碼?採用位元組碼的最大好處是什麼?

3.1 Java程式碼的執行流程

可以到.java文件通過Java編譯器(javac.exe)編譯成為.class文件。這個.class文件就是位元組碼文件,它是一種提供給JVM解釋執行的文件。每一個平台的都相同,由於通過不同的Java解釋器解釋形成不同的機器碼文件,使作業系統執行。

3.2 採用位元組碼的最大好處

  • 一定程度上解決了傳統解釋性語言執行效率低的問題
  • 不需要重新進行編譯就可以多平台運行

4. 什麼是Java虛擬機

任何一種可以解釋執行Java位元組碼文件的軟體均可以看做虛擬機(JVM)

4.1 Java虛擬機基本構成

任何一個JVM都包含:方法區,Java堆,Java棧,本地方法棧及其隱含暫存器

5. 什麼是Java程式的主類?

一個程式中可以擁有多個類,但僅僅只能存在一個主類。在Java程式中,擁有main方法的類被稱為主類。

6. 什麼是JDK?什麼是JRE

  • JDK是指Java開發環境,內部包含JREjava開發工具。如:javac.exe,java.exe,jar.exe
  • JRE是指Java運行環境,可以通過JRE來運行Java程式

7. 環境變數Path和ClassPath的作用是什麼?

  • 可以通過path環境變數指定JAVA_HOME/bin來直接操作Java命令
  • 可以通過classpath環境變數指定生成的.class的存放目錄

8.字元型常量和字元串常量的區別

  • 字元型常量對應一個ASCII碼值,它僅僅佔一個字元
  • 字元串常量對應的是記憶體中的一個地址,他可以佔用多個字元

9. Java語言採用何種編碼方案?有何特點?

Java語言採用了Unicode編碼標準,他為每一個字元訂製了一個唯一的數值,因此可以在任意的平台使用

10. 構造器Constructor是否可以被Override

父類的私有屬性和構造方法並不能被繼承,所以Constructor不能被重寫,但是可以被重載

11. 重載和重寫的區別

重載:發生在同一個類中,方法名相同,方法參數的個數、順序、類型不同或者方法返回值或訪問修飾符不同的時候,就稱為重載

重寫:發生在不同的類中,且該類之間存在繼承關係。當子類的方法名字,參數完全相同且其訪問修飾符大於或者等於父類方法的訪問修飾符的時候稱為方法的重寫

12. Java面向對象的三大特徵和五大原則

12.1三大特徵

  • 封裝
    • 將客觀事物抽象成類。並且將自身屬性和方法進行許可權修飾,使其只能讓其信任的類使用
  • 繼承
    • 通過繼承實現在不修改當前類的方法功能的情況下增強方法,有點類似於動態代理
  • 多態
    • 允許將父對象設置為任何其子對象,通過改變子對象來更改調用的方法

12.1 五大原則

  • 單一職責原則(SRP)
    • 一個類只做一種工作
  • 開放封閉原則(OCP)
    • 對象對擴展開放(如同動態代理或者繼承)
    • 對象對修改封閉(不能直接修改其功能)
  • 里氏替換原則(LSP)
    • 在對象為T時一個等式成立,當S為T的子類的時候,這個等式依然成立
    • 對父類的調用同樣適用於子類
  • 依賴倒置原則(DIP)
    • 高層次的不依賴低層次的
    • 即父類不依賴子類,而是子類依賴父類
  • 介面隔離原則(ISP)
    • 單一介面僅做單一功能類似於單一職責

13. Java語言的數據類型

13.1 基本數據類型

  • 整形
    • byte一個位元組
    • short兩個位元組
    • int四個位元組
    • long八個位元組。表示為1234654564651L。後面通過L聲明為一個long類型
  • 浮點型
    • float 四個位元組。表示為12.12345646f。後面通過f聲明為一個Float類型
    • double八個位元組
  • 布爾類型
    • boolean僅僅存在兩個值true或者false
  • 字元型
    • char一個位元組

13.2 引用數據類型

  • class類型
    • 系統的類,自定義的類都屬於類類型
    • String也是一個類類型,成為字元串類型
  • enum枚舉類型

14. this和super

this super
作用 調用本類對象的方法或者屬性 調用父類的public或者protected方法或者屬性
方法 this(參數)調用本類中的構造方法 super(參數)調用父類的構造方法
記憶體表現 當前類的記憶體地址 可以理解為父類的記憶體地址

15. 靜態和非靜態的區別

static no static
調用方式 類名調用 對象調用
記憶體表現 存在於方法區的靜態區 堆中
生命周期 類消亡的時候消亡 對象消亡的時候消亡
執行緒安全 共享數據,所以會存在並發問題 僅僅針對一個對象,所以無並發問題

16.抽象類和介面的區別

16.1 抽象類

為什麼要有抽象類?

Java將一些特性抽取形成一個抽象的模型,但是這個模型不能被實例化,因為他沒有任何具體的特徵,只能作為一個參考模板。它可以通過被繼承獲得其內部的所有的屬性和方法

抽象類特點:

  • abstract關鍵字修飾
  • 有構造方法,屬於類的範疇
  • 內部可以存在抽象方法也可以不存在抽象方法
  • 方法和成員能被static修飾
  • 類不能被final修飾,因為其本身不能實例化,作用僅僅是為了讓子類重寫,而final作用在類上就不能繼承了
  • 不能被private修飾,修飾以後子類無法重寫
  • 抽象方法沒有方法體

16.2 介面

介面,相當於一個標準,只有實現了這個標準才可以做具體的事情,比如JDBC,JDK提供了一套連接資料庫的介面,各大資料庫廠商實現這些介面,來讓Java連接他們的資料庫。

介面的特點:

  • interface關鍵字修飾
  • 成員變數默認被public static final修飾
  • 成員方法默認被public abstract修飾
  • JDK1.8出現了defalut方法可以擁有方法體
  • 支援多實現

介面的作用

  • 有利於程式碼的規範。符合介面分離原則
  • 降低程式之間的耦合。
  • 將若干功能拆分,使類和介面之間按照規範進行實現和依賴。依賴倒置 原則

16.3 區別

抽象類 介面
關鍵字修飾 abstract interface
是否可以被實例化 不可以 不可以
構造方法 存在構造方法 不存在構造方法
成員變數默認修飾 無默認修飾 默認被public static final修飾
方法 可以存在抽象也可存在非抽象方法 均為抽象方法或者默認方法
繼承或實現 單繼承 多實現(彌補多繼承)
本質 is a 關係。從屬關係 like a 關係。強調功能

17. 在調用子類構造方法之前會先調用父類沒有參數的構造方法,其目的是?

幫助子類做初始化工作

18. 一個類的構造方法的作用是什麼?若一個類沒有聲明構造方法,該程式可以正確的執行嗎?

構造方法的作用是完成類的初始化工作,沒有生命也可以執行,因為類默認存在構造方法

19. 成員變數和局部變數的區別?

成員變數 局部變數
記憶體 跟隨對象存放於堆中 存放於棧中
生命周期 跟隨對象 跟隨方法
初始化 會初始化 不會被初始化

20. 多態實現的機制

Java中存在兩種多態機制

  • 編譯時多態
    • 主要是方法的重載
  • 運行時多態
    • 動態綁定,在執行期間判斷引用對象的實際類型,根據類型調用不同的屬性或者方法

JVM在運行時默認是綁定在父類的引用上的,只有在遇到非靜態方法的時候才會動態綁定到子類的引用上,當執行完子類的非靜態方法以後又回到父類的引用上,知道下次遇到非靜態方法

21. Java類中各成員的載入和記憶體的存放位置

21.1 什麼時候載入類

  • 創建對象
  • 使用類中的靜態成員
  • 執行Java位元組碼文件

21.2 類所有內容載入順序和記憶體中的存放位置

假設一個場景:Person person = new Person()

分析其記憶體的實際操作

  • Java棧中載入main函數,建立main函數的變數p
  • 載入類文件。new對象的時候需要person.class文件,所以需要載入類Person
    • 載入類文件的時候,除了非靜態成員變數不會被載入,其他的屬性和方法均會被載入
  • 類載入以後各個成員的存放位置
    • 靜態成員屬性和方法。存放於方法區的靜態區
    • 非靜態方法。存放於方法區的非靜態區
    • 靜態程式碼塊和構造程式碼塊存放於靜態區

這裡有一個問題:為什麼會將非靜態方法也放置於方法區,而不是跟隨對象生存。

​ 非靜態方法只有對象才可以調用,如果讓類中的所有的靜態方法都隨著對象創建一次,非常佔據系統資源。所以採用了讓所有的對象共享這些方法,通過this關鍵字執行調用非靜態方法的對象。

  • 執行靜態程式碼塊
  • 開闢空間。在堆記憶體中創建空間,分配記憶體地址
  • 默認初始化。對Person的成員屬性進行默認初始化賦值
  • 顯示初始化。對Person的成員屬性進行賦值
  • 構造程式碼塊執行
  • 將記憶體地址賦值給p變數