天天看點

2020JAVA基礎面試題大全

Java概述

何為程式設計

程式設計就是讓計算機為解決某個問題而使用某種程式設計語言編寫程式代碼,并最終得到結果的過程。

為了使計算機能夠了解人的意圖,人類就必須要将需解決的問題的思路、方法、和手段通過計算機能夠了解的形式告訴計算機,使得計算機能夠根據人的指令一步一步去工作,完成某種特定的任務。這種人和計算機之間交流的過程就是程式設計。

什麼是Java

Java是一門面向對象程式設計語言,不僅吸收了C++語言的各種優點,還摒棄了C++裡難以了解的多繼承、指針等概念,是以Java語言具有功能強大和簡單易用兩個特征。Java語言作為靜态面向對象程式設計語言的代表,極好地實作了面向對象理論,允許程式員以優雅的思維方式進行複雜的程式設計 。

jdk1.5之後的三大版本

    Java SE(J2SE,Java 2 Platform Standard Edition,标準版)

    Java SE 以前稱為 J2SE。它允許開發和部署在桌面、伺服器、嵌入式環境和實時環境中使用的 Java 應用程式。Java SE 包含了支援 Java Web 服務開發的類,并為Java EE和Java ME提供基礎。

    Java EE(J2EE,Java 2 Platform Enterprise Edition,企業版)

    Java EE 以前稱為 J2EE。企業版本幫助開發和部署可移植、健壯、可伸縮且安全的伺服器端Java 應用程式。Java EE 是在 Java SE 的基礎上建構的,它提供 Web 服務、元件模型、管理和通信 API,可以用來實作企業級的面向服務體系結構(service-oriented architecture,SOA)和 Web2.0應用程式。2018年2月,Eclipse 宣布正式将 JavaEE 更名為 JakartaEE

    Java ME(J2ME,Java 2 Platform Micro Edition,微型版)

    Java ME 以前稱為 J2ME。Java ME 為在移動裝置和嵌入式裝置(比如手機、PDA、電視機頂盒和列印機)上運作的應用程式提供一個健壯且靈活的環境。Java ME 包括靈活的使用者界面、健壯的安全模型、許多内置的網絡協定以及對可以動态下載下傳的連網和離線應用程式的豐富支援。基于 Java ME 規範的應用程式隻需編寫一次,就可以用于許多裝置,而且可以利用每個裝置的本機功能。

JVM、JRE和JDK的關系

JVM

Java Virtual Machine是Java虛拟機,Java程式需要運作在虛拟機上,不同的平台有自己的虛拟機,是以Java語言可以實作跨平台。

JRE

Java Runtime Environment包括Java虛拟機和Java程式所需的核心類庫等。核心類庫主要是java.lang包:包含了運作Java程式必不可少的系統類,如基本資料類型、基本數學函數、字元串處理、線程、異常處理類等,系統預設加載這個包

如果想要運作一個開發好的Java程式,計算機中隻需要安裝JRE即可。

JDK

Java Development Kit是提供給Java開發人員使用的,其中包含了Java的開發工具,也包括了JRE。是以安裝了JDK,就無需再單獨安裝JRE了。其中的開發工具:編譯工具(javac.exe),打包工具(jar.exe)等

JVM&JRE&JDK關系圖

2020JAVA基礎面試題大全

什麼是跨平台性?原理是什麼

所謂跨平台性,是指java語言編寫的程式,一次編譯後,可以在多個系統平台上運作。

實作原理:Java程式是通過java虛拟機在系統平台上運作的,隻要該系統可以安裝相應的java虛拟機,該系統就可以運作java程式。

Java語言有哪些特點

簡單易學(Java語言的文法與C語言和C++語言很接近)

面向對象(封裝,繼承,多态)

平台無關性(Java虛拟機實作平台無關性)

支援網絡程式設計并且很友善(Java語言誕生本身就是為簡化網絡程式設計設計的)

支援多線程(多線程機制使應用程式在同一時間并行執行多項任)

健壯性(Java語言的強類型機制、異常處理、垃圾的自動收集等)

安全性

什麼是位元組碼?采用位元組碼的最大好處是什麼

位元組碼:Java源代碼經過虛拟機編譯器編譯後産生的檔案(即擴充為.class的檔案),它不面向任何特定的處理器,隻面向虛拟機。

采用位元組碼的好處:

Java語言通過位元組碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。是以Java程式運作時比較高效,而且,由于位元組碼并不專對一種特定的機器,是以,Java程式無須重新編譯便可在多種不同的計算機上運作。

先看下java中的編譯器和解釋器:

Java中引入了虛拟機的概念,即在機器和編譯程式之間加入了一層抽象的虛拟機器。這台虛拟的機器在任何平台上都提供給編譯程式一個的共同的接口。編譯程式隻需要面向虛拟機,生成虛拟機能夠了解的代碼,然後由解釋器來将虛拟機代碼轉換為特定系統的機器碼執行。在Java中,這種供虛拟機了解的代碼叫做位元組碼(即擴充為.class的檔案),它不面向任何特定的處理器,隻面向虛拟機。每一種平台的解釋器是不同的,但是實作的虛拟機是相同的。Java源程式經過編譯器編譯後變成位元組碼,位元組碼由虛拟機解釋執行,虛拟機将每一條要執行的位元組碼送給解釋器,解釋器将其翻譯成特定機器上的機器碼,然後在特定的機器上運作,這就是上面提到的Java的特點的編譯與解釋并存的解釋。

Java源代碼---->編譯器---->jvm可執行的Java位元組碼(即虛拟指令)---->jvm---->jvm中解釋器----->機器可執行的二進制機器碼---->程式運作。

什麼是Java程式的主類?應用程式和小程式的主類有何不同?

一個程式中可以有多個類,但隻能有一個類是主類。在Java應用程式中,這個主類是指包含main()方法的類。而在Java小程式中,這個主類是一個繼承自系統類JApplet或Applet的子類。應用程式的主類不一定要求是public類,但小程式的主類要求必須是public類。主類是Java程式執行的入口點。

Java應用程式與小程式之間有那些差别?

簡單說應用程式是從主線程啟動(也就是main()方法)。applet小程式沒有main方法,主要是嵌在浏覽器頁面上運作(調用init()線程或者run()來啟動),嵌入浏覽器這點跟flash的小遊戲類似。

Java和C++的差別

我知道很多人沒學過C++,但是面試官就是沒事喜歡拿咱們Java和C++比呀!沒辦法!!!就算沒學過C++,也要記下來!

    -都是面向對象的語言,都支援封裝、繼承和多态

    -Java不提供指針來直接通路記憶體,程式記憶體更加安全

    -Java的類是單繼承的,C++支援多重繼承;雖然Java的類不可以多繼承,但是接口可以多繼承。

    -Java有自動記憶體管理機制,不需要程式員手動釋放無用記憶體

Oracle JDK 和 OpenJDK 的對比

Oracle JDK版本将每三年釋出一次,而OpenJDK版本每三個月釋出一次;

OpenJDK 是一個參考模型并且是完全開源的,而Oracle JDK是OpenJDK的一個實作,并不是完全開源的;

Oracle JDK 比 OpenJDK 更穩定。OpenJDK和Oracle JDK的代碼幾乎相同,但Oracle JDK有更多的類和一些錯誤修複。是以,如果您想開發企業/商業軟體,我建議您選擇Oracle JDK,因為它經過了徹底的測試和穩定。某些情況下,有些人提到在使用OpenJDK 可能會遇到了許多應用程式崩潰的問題,但是,隻需切換到Oracle JDK就可以解決問題;

在響應性和JVM性能方面,Oracle JDK與OpenJDK相比提供了更好的性能;

Oracle JDK不會為即将釋出的版本提供長期支援,使用者每次都必須通過更新到最新版本獲得支援來擷取最新版本;

Oracle JDK根據二進制代碼許可協定獲得許可,而OpenJDK根據GPL v2許可獲得許可。

基礎文法

資料類型

Java有哪些資料類型

定義:Java語言是強類型語言,對于每一種資料都定義了明确的具體的資料類型,在記憶體中配置設定了不同大小的記憶體空間。

分類

  • 基本資料類型
    • 數值型
      • 整數類型(byte,short,int,long)
      • 浮點類型(float,double)
    • 字元型(char)
    • 布爾型(boolean)
  • 引用資料類型
    • 類(class)
    • 接口(interface)
    • 數組([])

Java基本資料類型圖

2020JAVA基礎面試題大全

switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上

在 Java 5 以前,switch(expr)中,expr 隻能是 byte、short、char、int。從 Java5 開始,Java 中引入了枚舉類型,expr 也可以是 enum 類型,從 Java 7 開始,expr 還可以是字元串(String),但是長整型(long)在目前所有的版本中都是不可以的。

用最有效率的方法計算 2 乘以 8

2 << 3(左移 3 位相當于乘以 2 的 3 次方,右移 3 位相當于除以 2 的 3 次方)。

Math.round(11.5) 等于多少?Math.round(-11.5)等于多少

Math.round(11.5)的傳回值是 12,Math.round(-11.5)的傳回值是-11。四舍五入的原理是在參數上加 0.5 然後進行下取整。

float f=3.4;是否正确

不正确。3.4 是雙精度數,将雙精度型(double)指派給浮點型(float)屬于下轉型(down-casting,也稱為窄化)會造成精度損失,是以需要強制類型轉換float f =(float)3.4; 或者寫成 float f =3.4F;。

short s1 = 1; s1 = s1 + 1;有錯嗎?short s1 = 1; s1 += 1;有錯嗎

對于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 類型,是以 s1+1 運算結果也是 int型,需要強制轉換類型才能指派給 short 型。

而 short s1 = 1; s1 += 1;可以正确編譯,因為 s1+= 1;相當于 s1 = (short(s1 + 1);其中有隐含的強制類型轉換。

編碼

Java語言采用何種編碼方案?有何特點?

Java語言采用Unicode編碼标準,Unicode(标準碼),它為每個字元制訂了一個唯一的數值,是以在任何的語言,平台,程式都可以放心的使用。

注釋

什麼Java注釋

定義:用于解釋說明程式的文字

分類

  • 單行注釋

    格式: // 注釋文字

  • 多行注釋

    格式:

  • 文檔注釋

    格式:

作用

在程式中,尤其是複雜的程式中,适當地加入注釋可以增加程式的可讀性,有利于程式的修改、調試和交流。注釋的内容在程式編譯的時候會被忽視,不會産生目标代碼,注釋的部分不會對程式的執行結果産生任何影響。

注意事項:多行和文檔注釋都不能嵌套使用。

通路修飾符

通路修飾符 public,private,protected,以及不寫(預設)時的差別

定義:Java中,可以使用通路修飾符來保護對類、變量、方法和構造方法的通路。Java 支援 4 種不同的通路權限。

分類

private : 在同一類内可見。使用對象:變量、方法。 注意:不能修飾類(外部類)

default (即預設,什麼也不寫,不使用任何關鍵字): 在同一包内可見,不使用任何修飾符。使用對象:類、接口、變量、方法。

protected : 對同一包内的類和所有子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)。

public : 對所有類可見。使用對象:類、接口、變量、方法

通路修飾符圖

2020JAVA基礎面試題大全

運算符

&和&&的差別

&運算符有兩種用法:(1)按位與;(2)邏輯與。

&&運算符是短路與運算。邏輯與跟短路與的差别是非常巨大的,雖然二者都要求運算符左右兩端的布爾值都是true 整個表達式的值才是 true。&&之是以稱為短路運算,是因為如果&&左邊的表達式的值是 false,右邊的表達式會被直接短路掉,不會進行運算。

注意:邏輯或運算符(|)和短路或運算符(||)的差别也是如此。

關鍵字

Java 有沒有 goto

goto 是 Java 中的保留字,在目前版本的 Java 中沒有使用。

final 有什麼用?

用于修飾類、屬性和方法;

  • 被final修飾的類不可以被繼承
  • 被final修飾的方法不可以被重寫
  • 被final修飾的變量不可以被改變,被final修飾不可變的是變量的引用,而不是引用指向的内容,引用指向的内容是可以改變的

final finally finalize差別

  • final可以修飾類、變量、方法,修飾類表示該類不能被繼承、修飾方法表示該方法不能被重寫、修飾變量表

       示該變量是一個常量不能被重新指派。

  • finally一般作用在try-catch代碼塊中,在處理異常的時候,通常我們将一定要執行的代碼方法finally代碼塊

       中,表示不管是否出現異常,該代碼塊都會執行,一般用來存放一些關閉資源的代碼。

  • finalize是一個方法,屬于Object類的一個方法,而Object類是所有類的父類,該方法一般由垃圾回收器來調

       用,當我們調用System.gc() 方法的時候,由垃圾回收器調用finalize(),回收垃圾,一個對象是否可回收的

       最後判斷。

this關鍵字的用法

this是自身的一個對象,代表對象本身,可以了解為:指向對象本身的一個指針。

this的用法在java中大體可以分為3種:

1.普通的直接引用,this相當于是指向目前對象本身。

2.形參與成員名字重名,用this來區分:

2020JAVA基礎面試題大全

3.引用本類的構造函數

2020JAVA基礎面試題大全

super關鍵字的用法

super可以了解為是指向自己超(父)類對象的一個指針,而這個超類指的是離自己最近的一個父類。

super也有三種用法:

1.普通的直接引用

與this類似,super相當于是指向目前對象的父類的引用,這樣就可以用super.xxx來引用父類的成員。

2.子類中的成員變量或方法與父類中的成員變量或方法同名時,用super進行區分

2020JAVA基礎面試題大全

3、引用父類構造函數

  • super(參數):調用父類中的某一個構造函數(應該為構造函數中的第一條語句)。
  • this(參數):調用本類中另一種形式的構造函數(應該為構造函數中的第一條語句)。

this與super的差別

  • super: 它引用目前對象的直接父類中的成員(用來通路直接父類中被隐藏的父類中成員資料或函數,基類與派生類中有相同成員定義時如:super.變量名 super.成員函資料名(實參)
  • this:它代表目前對象名(在程式中易産生二義性之處,應使用this來指明目前對象;如果函數的形參與類中的成員資料同名,這時需用this來指明成員變量名)
  • super()和this()類似,差別是,super()在子類中調用父類的構造方法,this()在本類内調用本類的其它構造方法。
  • super()和this()均需放在構造方法内第一行。
  • 盡管可以用this調用一個構造器,但卻不能調用兩個。
  • this和super不能同時出現在一個構造函數裡面,因為this必然會調用其它的構造函數,其它的構造函數必然也會有super語句的存在,是以在同一個構造函數裡面有相同的語句,就失去了語句的意義,編譯器也不會通過。
  • this()和super()都指的是對象,是以,均不可以在static環境中使用。包括:static變量,static方法,static語句塊。
  • 從本質上講,this是一個指向本對象的指針, 然而super是一個Java關鍵字。

static存在的主要意義

static的主要意義是在于建立獨立于具體對象的域變量或者方法。以緻于即使沒有建立對象,也能使用屬性和調用方法!

static關鍵字還有一個比較關鍵的作用就是 用來形成靜态代碼塊以優化程式性能。static塊可以置于類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,并且隻會執行一次。

為什麼說static塊可以用來優化程式性能,是因為它的特性:隻會在類加載的時候執行一次。是以,很多時候會将一些隻需要進行一次的初始化操作都放在static代碼塊中進行。

static的獨特之處

1、被static修飾的變量或者方法是獨立于該類的任何對象,也就是說,這些變量和方法不屬于任何一個執行個體對象,而是被類的執行個體對象所共享。

2020JAVA基礎面試題大全

2、在該類被第一次加載的時候,就會去加載被static修飾的部分,而且隻在類第一次使用時加載并進行初始化,注意這是第一次用就要初始化,後面根據需要是可以再次指派的。

3、static變量值在類加載的時候配置設定空間,以後建立類對象的時候不會重新配置設定。指派的話,是可以任意指派的!

4、被static修飾的變量或者方法是優先于對象存在的,也就是說當一個類加載完畢之後,即便沒有建立對象,也可以去通路。

static應用場景

因為static是被類的執行個體對象所共享,是以如果某個成員變量是被所有對象所共享的,那麼這個成員變量就應該定義為靜态變量。

是以比較常見的static應用場景有:

2020JAVA基礎面試題大全

static注意事項

1、靜态隻能通路靜态。 2、非靜态既可以通路非靜态的,也可以通路靜态的。

流程控制語句

break ,continue ,return 的差別及作用

break 跳出總上一層循環,不再執行循環(結束目前的循環體)

continue 跳出本次循環,繼續執行下次循環(結束正在執行的循環 進入下一個循環條件)

return 程式傳回,不再執行下面的代碼(結束目前的方法 直接傳回)

在 Java 中,如何跳出目前的多重嵌套循環

在Java中,要想跳出多重循環,可以在外面的循環語句前定義一個标号,然後在裡層循環體的代碼中使用帶有标号的break 語句,即可跳出外層循環。例如:

2020JAVA基礎面試題大全

面向對象

面向對象概述

面向對象和面向過程的差別

面向過程:

優點:性能比面向對象高,因為類調用時需要執行個體化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發、Linux/Unix等一般采用面向過程開發,性能是最重要的因素。

缺點:沒有面向對象易維護、易複用、易擴充

面向對象:

優點:易維護、易複用、易擴充,由于面向對象有封裝、繼承、多态性的特性,可以設計出低耦合的系統,使系統更加靈活、更加易于維護

缺點:性能比面向過程低

面向過程是具體化的,流程化的,解決一個問題,你需要一步一步的分析,一步一步的實作。

面向對象是模型化的,你隻需抽象出一個類,這是一個封閉的盒子,在這裡你擁有資料也擁有解決問題的方法。需要什麼功能直接使用就可以了,不必去一步一步的實作,至于這個功能是如何實作的,管我們什麼事?我們會用就可以了。

面向對象的底層其實還是面向過程,把面向過程抽象成類,然後封裝,友善我們使用的就是面向對象了。

面向對象三大特性

面向對象的特征有哪些方面

面向對象的特征主要有以下幾個方面:

抽象:抽象是将一類對象的共同特征總結出來構造類的過程,包括資料抽象和行為抽象兩方面。抽象隻關注對象有哪些屬性和行為,并不關注這些行為的細節是什麼。

封裝

封裝把一個對象的屬性私有化,同時提供一些可以被外界通路的屬性的方法,如果屬性不想被外界通路,我們大可不必提供方法給外界通路。但是如果一個類沒有提供給外界通路的方法,那麼這個類也沒有什麼意義了。

繼承

繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。通過使用繼承我們能夠非常友善地複用以前的代碼。

關于繼承如下 3 點請記住:

  1. 子類擁有父類非 private 的屬性和方法。
  2. 子類可以擁有自己屬性和方法,即子類可以對父類進行擴充。
  3. 子類可以用自己的方式實作父類的方法。(以後介紹)。

多态

所謂多态就是指程式中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在程式設計時并不确定,而是在程式運作期間才确定,即一個引用變量到底會指向哪個類的執行個體對象,該引用變量發出的方法調用到底是哪個類中實作的方法,必須在由程式運作期間才能決定。

在Java中有兩種形式可以實作多态:繼承(多個子類對同一方法的重寫)和接口(實作接口并覆寫接口中同一方法)。

其中Java 面向對象程式設計三大特性:封裝 繼承 多态

封裝:隐藏對象的屬性和實作細節,僅對外提供公共通路方式,将變化隔離,便于使用,提高複用性和安全性。

繼承:繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。通過使用繼承可以提高代碼複用性。繼承是多态的前提。

關于繼承如下 3 點請記住:

  1. 子類擁有父類非 private 的屬性和方法。
  2. 子類可以擁有自己屬性和方法,即子類可以對父類進行擴充。
  3. 子類可以用自己的方式實作父類的方法。

多态性:父類或接口定義的引用變量可以指向子類或具體實作類的執行個體對象。提高了程式的拓展性。

在Java中有兩種形式可以實作多态:繼承(多個子類對同一方法的重寫)和接口(實作接口并覆寫接口中同一方法)。

方法重載(overload)實作的是編譯時的多态性(也稱為前綁定),而方法重寫(override)實作的是運作時的多态性(也稱為後綁定)。

一個引用變量到底會指向哪個類的執行個體對象,該引用變量發出的方法調用到底是哪個類中實作的方法,必須在由程式運作期間才能決定。運作時的多态是面向對象最精髓的東西,要實作多态需要做兩件事:

  •     方法重寫(子類繼承父類并重寫父類中已有的或抽象的方法);
  •     對象造型(用父類型引用子類型對象,這樣同樣的引用調用同樣的方法就會根據子類對象的不同而表現出不同的行為)。

什麼是多态機制?Java語言是如何實作多态的?

所謂多态就是指程式中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在程式設計時并不确定,而是在程式運作期間才确定,即一個引用變量倒底會指向哪個類的執行個體對象,該引用變量發出的方法調用到底是哪個類中實作的方法,必須在由程式運作期間才能決定。因為在程式運作時才确定具體的類,這樣,不用修改源程式代碼,就可以讓引用變量綁定到各種不同的類實作上,進而導緻該引用調用的具體方法随之改變,即不修改程式代碼就可以改變程式運作時所綁定的具體代碼,讓程式可以選擇多個運作狀态,這就是多态性。多态分為編譯時多态和運作時多态。其中編輯時多态是靜态的,主要是指方法的重載,它是根據參數清單的不同來區分不同的函數,通過編輯之後會變成兩個不同的函數,在運作時談不上多态。而運作時多态是動态的,它是通過動态綁定來實作的,也就是我們所說的多态性。

多态的實作

Java實作多态有三個必要條件:繼承、重寫、向上轉型。

繼承:在多态中必須存在有繼承關系的子類和父類。

重寫:子類對父類中某些方法進行重新定義,在調用這些方法時就會調用子類的方法。

向上轉型:在多态中需要将子類的引用賦給父類對象,隻有這樣該引用才能夠具備技能調用父類的方法和子類的方法。

隻有滿足了上述三個條件,我們才能夠在同一個繼承結構中使用統一的邏輯實作代碼處理不同的對象,進而達到執行不同的行為。

對于Java而言,它多态的實作機制遵循一個原則:當超類對象引用變量引用子類對象時,被引用對象的類型而不是引用變量的類型決定了調用誰的成員方法,但是這個被調用的方法必須是在超類中定義過的,也就是說被子類覆寫的方法。

面向對象五大基本原則是什麼(可選)

  • 單一職責原則SRP(Single Responsibility Principle)類的功能要單一,不能包羅萬象,跟雜貨鋪似的。
  • 開放封閉原則OCP(Open-Close Principle)

    一個子產品對于拓展是開放的,對于修改是封閉的,想要增加功能熱烈歡迎,想要修改,哼,一萬個不樂意。

  • 裡式替換原則LSP(the Liskov Substitution Principle LSP)

    子類可以替換父類出現在父類能夠出現的任何地方。比如你能代表你爸去你外婆家幹活。哈哈~~

  • 依賴倒置原則DIP(the Dependency Inversion Principle DIP)

    高層次的子產品不應該依賴于低層次的子產品,他們都應該依賴于抽象。抽象不應該依賴于具體實作,具體實作應該依賴于抽象。就是你出國要說你是中國人,而不能說你是哪個村子的。比如說中國人是抽象的,下面有具體的xx省,xx市,xx縣。你要依賴的抽象是中國人,而不是你是xx村的。

  • 接口分離原則ISP(the Interface Segregation Principle ISP)

    設計時采用多個與特定客戶類有關的接口比采用一個通用的接口要好。就比如一個手機擁有打電話,看視訊,玩遊戲等功能,把這幾個功能拆分成不同的接口,比在一個接口裡要好的多。

類與接口

抽象類和接口的對比

抽象類是用來捕捉子類的通用特性的。接口是抽象方法的集合。

從設計層面來說,抽象類是對類的抽象,是一種模闆設計,接口是行為的抽象,是一種行為的規範。

相同點

  • 接口和抽象類都不能執行個體化
  • 都位于繼承的頂端,用于被其他實作或繼承
  • 都包含抽象方法,其子類都必須覆寫這些抽象方法
2020JAVA基礎面試題大全

備注:Java8中接口中引入預設方法和靜态方法,以此來減少抽象類和接口之間的差異。

現在,我們可以為接口提供預設實作的方法了,并且不用強制子類來實作它。

接口和抽象類各有優缺點,在接口和抽象類的選擇上,必須遵守這樣一個原則:

  •     行為模型應該總是通過接口而不是抽象類定義,是以通常是優先選用接口,盡量少用抽象類。
  •     選擇抽象類的時候通常是如下情況:需要定義子類的行為,又要為子類提供通用的功能。

普通類和抽象類有哪些差別?

  • 普通類不能包含抽象方法,抽象類可以包含抽象方法。
  • 抽象類不能直接執行個體化,普通類可以直接執行個體化。

抽象類能使用 final 修飾嗎?

不能,定義抽象類就是讓其他類繼承的,如果定義為 final 該類就不能被繼承,這樣彼此就會産生沖突,是以 final 不能修飾抽象類

建立一個對象用什麼關鍵字?對象執行個體與對象引用有何不同?

new關鍵字,new建立對象執行個體(對象執行個體在堆記憶體中),對象引用指向對象執行個體(對象引用存放在棧記憶體中)。一個對象引用可以指向0個或1個對象(一根繩子可以不系氣球,也可以系一個氣球);一個對象可以有n個引用指向它(可以用n條繩子系住一個氣球)

變量與方法

成員變量與局部變量的差別有哪些

變量:在程式執行的過程中,在某個範圍内其值可以發生改變的量。從本質上講,變量其實是記憶體中的一小塊區域

成員變量:方法外部,類内部定義的變量

局部變量:類的方法中的變量。

成員變量和局部變量的差別

作用域

成員變量:針對整個類有效。

局部變量:隻在某個範圍内有效。(一般指的就是方法,語句體内)

存儲位置

成員變量:随着對象的建立而存在,随着對象的消失而消失,存儲在堆記憶體中。

局部變量:在方法被調用,或者語句被執行的時候存在,存儲在棧記憶體中。當方法調用完,或者語句結束後,就自動釋放。

生命周期

成員變量:随着對象的建立而存在,随着對象的消失而消失

局部變量:當方法調用完,或者語句結束後,就自動釋放。

初始值

成員變量:有預設初始值。

局部變量:沒有預設初始值,使用前必須指派。

使用原則

在使用變量時需要遵循的原則為:就近原則

首先在局部範圍找,有就使用;接着在成員位置找。

在Java中定義一個不做事且沒有參數的構造方法的作用

Java程式在執行子類的構造方法之前,如果沒有用super()來調用父類特定的構造方法,則會調用父類中“沒有參數的構造方法”。是以,如果父類中隻定義了有參數的構造方法,而在子類的構造方法中又沒有用super()來調用父類中特定的構造方法,則編譯時将發生錯誤,因為Java程式在父類中找不到沒有參數的構造方法可供執行。解決辦法是在父類裡加上一個不做事且沒有參數的構造方法。

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

幫助子類做初始化工作。

一個類的構造方法的作用是什麼?若一個類沒有聲明構造方法,改程式能正确執行嗎?為什麼?

主要作用是完成對類對象的初始化工作。可以執行。因為一個類即使沒有聲明構造方法也會有預設的不帶參數的構造方法。

構造方法有哪些特性?

名字與類名相同;

沒有傳回值,但不能用void聲明構造函數;

生成類的對象時自動執行,無需調用。

靜态變量和執行個體變量差別

靜态變量: 靜态變量由于不屬于任何執行個體對象,屬于類的,是以在記憶體中隻會有一份,在類的加載過程中,JVM隻為靜态變量配置設定一次記憶體空間。

執行個體變量: 每次建立對象,都會為每個對象配置設定成員變量記憶體空間,執行個體變量是屬于執行個體對象的,在記憶體中,建立幾次對象,就有幾份成員變量。

靜态變量與普通變量差別

static變量也稱作靜态變量,靜态變量和非靜态變量的差別是:靜态變量被所有的對象所共享,在記憶體中隻有一個副本,它當且僅當在類初次加載時會被初始化。而非靜态變量是對象所擁有的,在建立對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。

還有一點就是static成員變量的初始化順序按照定義的順序進行初始化。

靜态方法和執行個體方法有何不同?

靜态方法和執行個體方法的差別主要展現在兩個方面:

    在外部調用靜态方法時,可以使用"類名.方法名"的方式,也可以使用"對象名.方法名"的方式。而執行個體方法隻有後面這種方式。也就是說,調用靜态方法可以無需建立對象。

    靜态方法在通路本類的成員時,隻允許通路靜态成員(即靜态成員變量和靜态方法),而不允許通路執行個體成員變量和執行個體方法;執行個體方法則無此限制

在一個靜态方法内調用一個非靜态成員為什麼是非法的?

由于靜态方法可以不通過對象進行調用,是以在靜态方法裡,不能調用其他非靜态變量,也不可以通路非靜态變量成員。

什麼是方法的傳回值?傳回值的作用是什麼?

方法的傳回值是指我們擷取到的某個方法體中的代碼執行後産生的結果!(前提是該方法可能産生結果)。傳回值的作用:接收出結果,使得它可以用于其他的操作!

内部類

什麼是内部類?

在Java中,可以将一個類的定義放在另外一個類的定義内部,這就是内部類。内部類本身就是類的一個屬性,與其他屬性定義方式一緻。

内部類的分類有哪些

内部類可以分為四種:成員内部類、局部内部類、匿名内部類和靜态内部類。

靜态内部類

定義在類内部的靜态類,就是靜态内部類

2020JAVA基礎面試題大全

靜态内部類可以通路外部類所有的靜态變量,而不可通路外部類的非靜态變量;靜态内部類的建立方式,

new 外部類.靜态内部類()

,如下:

2020JAVA基礎面試題大全

成員内部類

定義在類内部,成員位置上的非靜态類,就是成員内部類。

2020JAVA基礎面試題大全

成員内部類可以通路外部類所有的變量和方法,包括靜态和非靜态,私有和公有。成員内部類依賴于外部類的執行個體,它的建立方式

外部類執行個體.new 内部類()

,如下:

2020JAVA基礎面試題大全

局部内部類

定義在方法中的内部類,就是局部内部類。

2020JAVA基礎面試題大全

定義在執行個體方法中的局部類可以通路外部類的所有變量和方法,定義在靜态方法中的局部類隻能通路外部類的靜态變量和方法。局部内部類的建立方式,在對應方法内,

new 内部類()

,如下:

2020JAVA基礎面試題大全

匿名内部類

匿名内部類就是沒有名字的内部類,日常開發中使用的比較多。

2020JAVA基礎面試題大全

除了沒有名字,匿名内部類還有以下特點:

    -匿名内部類必須繼承一個抽象類或者實作一個接口。

   -匿名内部類不能定義任何靜态成員和靜态方法。

   -當所在的方法的形參需要被匿名内部類使用時,必須聲明為 final。

    -匿名内部類不能是抽象的,它必須要實作繼承的類或者實作的接口的所有抽象方法。

匿名内部類建立方式:

2020JAVA基礎面試題大全

内部類的優點

我們為什麼要使用内部類呢?因為它有以下優點:

  • 一個内部類對象可以通路建立它的外部類對象的内容,包括私有資料!
  • 内部類不為同一包的其他類所見,具有很好的封裝性;
  • 内部類有效實作了“多重繼承”,優化 java 單繼承的缺陷。
  • 匿名内部類可以很友善的定義回調。

内部類有哪些應用場景

  • 一些多算法場合
  • 解決一些非面向對象的語句塊。
  • 适當使用内部類,使得代碼更加靈活和富有擴充性。
  • 當某個類除了它的外部類,不再被其他的類使用時。

局部内部類和匿名内部類通路局部變量的時候,為什麼變量必須要加上final?

局部内部類和匿名内部類通路局部變量的時候,為什麼變量必須要加上final呢?它内部原理是什麼呢?

先看這段代碼:

2020JAVA基礎面試題大全

以上例子,為什麼要加final呢?是因為生命周期不一緻, 局部變量直接存儲在棧中,當方法執行結束後,非final的局部變量就被銷毀。而局部内部類對局部變量的引用依然存在,如果局部内部類要調用局部變量時,就會出錯。加了final,可以確定局部内部類使用的變量與外層的局部變量區分開,解決了這個問題。

内部類相關,看程式說出運作結果

2020JAVA基礎面試題大全

運作結果:

2020JAVA基礎面試題大全

重寫與重載

構造器(constructor)是否可被重寫(override)

構造器不能被繼承,是以不能被重寫,但可以被重載。

重載(Overload)和重寫(Override)的差別。重載的方法能否根據傳回類型進行區分?

方法的重載和重寫都是實作多态的方式,差別在于前者實作的是編譯時的多态性,而後者實作的是運作時的多态性。

重載:發生在同一個類中,方法名相同參數清單不同(參數類型不同、個數不同、順序不同),與方法傳回值和通路修飾符無關,即重載的方法不能根據傳回類型進行區分

重寫:發生在父子類中,方法名、參數清單必須相同,傳回值小于等于父類,抛出的異常小于等于父類,通路修飾符大于等于父類(裡氏代換原則);如果父類方法通路修飾符為private則子類中就不是重寫。

對象相等判斷

對象相等判斷

== 和 equals 的差別是什麼

== : 它的作用是判斷兩個對象的位址是不是相等。即,判斷兩個對象是不是同一個對象。(基本資料類型 == 比較的是值,引用資料類型 == 比較的是記憶體位址)

equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:

情況1:類沒有覆寫 equals() 方法。則通過 equals() 比較該類的兩個對象時,等價于通過“==”比較這兩個對象。

情況2:類覆寫了 equals() 方法。一般,我們都覆寫 equals() 方法來兩個對象的内容相等;若它們的内容相等,則傳回 true (即,認為這兩個對象相等)。

舉個例子:

2020JAVA基礎面試題大全

說明:

  •     String中的equals方法是被重寫過的,因為object的equals方法是比較的對象的記憶體位址,而String的equals方法比較的是對象的值。
  •     當建立String類型的對象時,虛拟機會在常量池中查找有沒有已經存在的值和要建立的值相同的對象,如果有就把它賦給目前引用。如果沒有就在常量池中重新建立一個String對象。

hashCode 與 equals (重要)

HashSet如何檢查重複

兩個對象的 hashCode() 相同,則 equals() 也一定為 true,對嗎?

hashCode和equals方法的關系

面試官可能會問你:“你重寫過 hashcode 和 equals 麼,為什麼重寫equals時必須重寫hashCode方法?”

hashCode()介紹

hashCode() 的作用是擷取哈希碼,也稱為散列碼;它實際上是傳回一個int整數。這個哈希碼的作用是确定該對象在哈希表中的索引位置。hashCode() 定義在JDK的Object.java中,這就意味着Java中的任何類都包含有hashCode()函數。

散清單存儲的是鍵值對(key-value),它的特點是:能根據“鍵”快速的檢索出對應的“值”。這其中就利用到了散列碼!(可以快速找到所需要的對象)

為什麼要有 hashCode

我們以“HashSet 如何檢查重複”為例子來說明為什麼要有 hashCode:

當你把對象加入 HashSet 時,HashSet 會先計算對象的 hashcode 值來判斷對象加入的位置,同時也會與其他已經加入的對象的 hashcode 值作比較,如果沒有相符的hashcode,HashSet會假設對象沒有重複出現。但是如果發現有相同 hashcode 值的對象,這時會調用 equals()方法來檢查 hashcode 相等的對象是否真的相同。如果兩者相同,HashSet 就不會讓其加入操作成功。如果不同的話,就會重新散列到其他位置。(摘自我的Java啟蒙書《Head first java》第二版)。這樣我們就大大減少了 equals 的次數,相應就大大提高了執行速度。

hashCode()與equals()的相關規定

如果兩個對象相等,則hashcode一定也是相同的

兩個對象相等,對兩個對象分别調用equals方法都傳回true

兩個對象有相同的hashcode值,它們也不一定是相等的

是以,equals 方法被覆寫過,則 hashCode 方法也必須被覆寫

hashCode() 的預設行為是對堆上的對象産生獨特值。如果沒有重寫 hashCode(),則該 class 的兩個對象無論如何都不會相等(即使這兩個對象指向相同的資料)

對象的相等與指向他們的引用相等,兩者有什麼不同?

對象的相等 比的是記憶體中存放的内容是否相等而 引用相等 比較的是他們指向的記憶體位址是否相等。

值傳遞

當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,并可傳回變化後的結果,那麼這裡到底是值傳遞還是引用傳遞

是值傳遞。Java 語言的方法調用隻支援參數的值傳遞。當一個對象執行個體作為一個參數被傳遞到方法中時,參數的值就是對該對象的引用。對象的屬性可以在被調用過程中被改變,但對對象引用的改變是不會影響到調用者的

為什麼 Java 中隻有值傳遞

首先回顧一下在程式設計語言中有關将參數傳遞給方法(或函數)的一些專業術語。按值調用(call by value)表示方法接收的是調用者提供的值,而按引用調用(call by reference)表示方法接收的是調用者提供的變量位址。一個方法可以修改傳遞引用所對應的變量值,而不能修改傳遞值調用所對應的變量值。 它用來描述各種程式設計語言(不隻是Java)中方法參數傳遞方式。

Java程式設計語言總是采用按值調用。也就是說,方法得到的是所有參數值的一個拷貝,也就是說,方法不能修改傳遞給它的任何參數變量的内容。

下面通過 3 個例子來給大家說明

example 1

2020JAVA基礎面試題大全

結果:

2020JAVA基礎面試題大全

解析:

2020JAVA基礎面試題大全

在swap方法中,a、b的值進行交換,并不會影響到 num1、num2。因為,a、b中的值,隻是從 num1、num2 的複制過來的。也就是說,a、b相當于num1、num2 的副本,副本的内容無論怎麼修改,都不會影響到原件本身。

通過上面例子,我們已經知道了一個方法不能修改一個基本資料類型的參數,而對象引用作為參數就不一樣,請看 example2.

example 2

2020JAVA基礎面試題大全

結果:

2020JAVA基礎面試題大全

解析:

2020JAVA基礎面試題大全

array 被初始化 arr 的拷貝也就是一個對象的引用,也就是說 array 和 arr 指向的時同一個數組對象。 是以,外部對引用對象的改變會反映到所對應的對象上。

通過 example2 我們已經看到,實作一個改變對象參數狀态的方法并不是一件難事。理由很簡單,方法得到的是對象引用的拷貝,對象引用及其他的拷貝同時引用同一個對象。

很多程式設計語言(特别是,C++和Pascal)提供了兩種參數傳遞的方式:值調用和引用調用。有些程式員(甚至本書的作者)認為Java程式設計語言對對象采用的是引用調用,實際上,這種了解是不對的。由于這種誤解具有一定的普遍性,是以下面給出一個反例來詳細地闡述一下這個問題。

example 3

2020JAVA基礎面試題大全

結果:

2020JAVA基礎面試題大全

解析:

交換之前:

2020JAVA基礎面試題大全

交換之後:

2020JAVA基礎面試題大全

通過上面兩張圖可以很清晰的看出: 方法并沒有改變存儲在變量 s1 和 s2 中的對象引用。swap方法的參數x和y被初始化為兩個對象引用的拷貝,這個方法交換的是這兩個拷貝

總結

Java程式設計語言對對象采用的不是引用調用,實際上,對象引用是按值傳遞的。

下面再總結一下Java中方法參數的使用情況:

  • 一個方法不能修改一個基本資料類型的參數(即數值型或布爾型》
  • 一個方法可以改變一個對象參數的狀态。
  • 一個方法不能讓對象參數引用一個新的對象。

值傳遞和引用傳遞有什麼差別

值傳遞:指的是在方法調用時,傳遞的參數是按值的拷貝傳遞,傳遞的是值的拷貝,也就是說傳遞後就互不相關了。

引用傳遞:指的是在方法調用時,傳遞的參數是按引用進行傳遞,其實傳遞的引用的位址,也就是變量所對應的記憶體空間的位址。傳遞的是值的引用,也就是說傳遞前和傳遞後都指向同一個引用(也就是同一個記憶體空間)。

Java包

JDK 中常用的包有哪些

    java.lang:這個是系統的基礎類;

    java.io:這裡面是所有輸入輸出有關的類,比如檔案操作等;

    java.nio:為了完善 io 包中的功能,提高 io 包中性能而寫的一個新包;

    java.net:這裡面是與網絡有關的類;

    java.util:這個是系統輔助類,特别是集合類;

    java.sql:這個是資料庫操作的類。

import java和javax有什麼差別

剛開始的時候 JavaAPI 所必需的包是 java 開頭的包,javax 當時隻是擴充 API 包來說使用。然而随着時間的推移,javax 逐漸的擴充成為 Java API 的組成部分。但是,将擴充從 javax 包移動到 java 包将是太麻煩了,最終會破壞一堆現有的代碼。是以,最終決定 javax 包将成為标準API的一部分。

是以,實際上java和javax沒有差別。這都是一個名字。

IO流

java 中 IO 流分為幾種?

  • 按照流的流向分,可以分為輸入流和輸出流;
  • 按照操作單元劃分,可以劃分為位元組流和字元流;
  • 按照流的角色劃分為節點流和處理流。

Java Io流共涉及40多個類,這些類看上去很雜亂,但實際上很有規則,而且彼此之間存在非常緊密的聯系, Java I0流的40多個類都是從如下4個抽象類基類中派生出來的。

    InputStream/Reader: 所有的輸入流的基類,前者是位元組輸入流,後者是字元輸入流。

    OutputStream/Writer: 所有輸出流的基類,前者是位元組輸出流,後者是字元輸出流。

按操作方式分類結構圖:

2020JAVA基礎面試題大全

按操作對象分類結構圖:

2020JAVA基礎面試題大全

BIO,NIO,AIO 有什麼差別?

簡答

    BIO:Block IO 同步阻塞式 IO,就是我們平常使用的傳統 IO,它的特點是模式簡單使用友善,并發處理能力低。

    NIO:Non IO 同步非阻塞 IO,是傳統 IO 的更新,用戶端和伺服器端通過 Channel(通道)通訊,實作了多路複用。

    AIO:Asynchronous IO 是 NIO 的更新,也叫 NIO2,實作了異步非堵塞 IO ,異步 IO 的操作基于事件和回調機制。

詳細回答

    BIO (Blocking I/O): 同步阻塞I/O模式,資料的讀取寫入必須阻塞在一個線程内等待其完成。在活動連接配接數不是特别高(小于單機1000)的情況下,這種模型是比較不錯的,可以讓每一個連接配接專注于自己的 I/O 并且程式設計模型簡單,也不用過多考慮系統的過載、限流等問題。線程池本身就是一個天然的漏鬥,可以緩沖一些系統處理不了的連接配接或請求。但是,當面對十萬甚至百萬級連接配接的時候,傳統的 BIO 模型是無能為力的。是以,我們需要一種更高效的 I/O 處理模型來應對更高的并發量。

    NIO (New I/O): NIO是一種同步非阻塞的I/O模型,在Java 1.4 中引入了NIO架構,對應 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以了解為Non-blocking,不單純是New。它支援面向緩沖的,基于通道的I/O操作方法。 NIO提供了與傳統BIO模型中的 Socket 和 ServerSocket 相對應的 SocketChannel 和 ServerSocketChannel 兩種不同的套接字通道實作,兩種通道都支援阻塞和非阻塞兩種模式。阻塞模式使用就像傳統中的支援一樣,比較簡單,但是性能和可靠性都不好;非阻塞模式正好與之相反。對于低負載、低并發的應用程式,可以使用同步阻塞I/O來提升開發速率和更好的維護性;對于高負載、高并發的(網絡)應用,應使用 NIO 的非阻塞模式來開發

    AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改進版 NIO 2,它是異步非阻塞的IO模型。異步 IO 是基于事件和回調機制實作的,也就是應用操作之後會直接傳回,不會堵塞在那裡,當背景處理完成,作業系統會通知相應的線程進行後續的操作。AIO 是異步IO的縮寫,雖然 NIO 在網絡操作中,提供了非阻塞的方法,但是 NIO 的 IO 行為還是同步的。對于 NIO 來說,我們的業務線程是在 IO 操作準備好時,得到通知,接着就由這個線程自行進行 IO 操作,IO操作本身是同步的。查閱網上相關資料,我發現就目前來說 AIO 的應用還不是很廣泛,Netty 之前也嘗試使用過 AIO,不過又放棄了。

Files的常用方法都有哪些?

Files. exists():檢測檔案路徑是否存在。

Files. createFile():建立檔案。

Files. createDirectory():建立檔案夾。

Files. delete():删除一個檔案或目錄。

Files. copy():複制檔案。

Files. move():移動檔案。

Files. size():檢視檔案個數。

Files. read():讀取檔案。

Files. write():寫入檔案。

反射

什麼是反射機制?

JAVA反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動态擷取的資訊以及動态調用對象的方法的功能稱為java語言的反射機制。

靜态編譯和動态編譯

  • **靜态編譯:**在編譯時确定類型,綁定對象
  • **動态編譯:**運作時确定類型,綁定對象

反射機制優缺點

  • 優點: 運作期類型的判斷,動态加載類,提高代碼靈活度。
  • 缺點: 性能瓶頸:反射相當于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多。

反射機制的應用場景有哪些?

反射是架構設計的靈魂。

在我們平時的項目開發過程中,基本上很少會直接使用到反射機制,但這不能說明反射機制沒有用,實際上有很多設計、開發都與反射機制有關,例如子產品化的開發,通過反射去調用對應的位元組碼;動态代理設計模式也采用了反射機制,還有我們日常使用的 Spring/Hibernate 等架構也大量使用到了反射機制。

舉例:①我們在使用JDBC連接配接資料庫時使用Class.forName()通過反射加載資料庫的驅動程式;②Spring架構也用到很多反射機制,最經典的就是xml的配置模式。Spring 通過 XML 配置模式裝載 Bean 的過程:1) 将程式内所有 XML 或 Properties 配置檔案加載入記憶體中; 2)Java類裡面解析xml或properties裡面的内容,得到對應實體類的位元組碼字元串以及相關的屬性資訊; 3)使用反射機制,根據這個字元串獲得某個類的Class執行個體; 4)動态配置執行個體的屬性

Java擷取反射的三種方法

1.通過new對象實作反射機制 2.通過路徑實作反射機制 3.通過類名實作反射機制

2020JAVA基礎面試題大全
2020JAVA基礎面試題大全

網絡程式設計

常用API

String相關

字元型常量和字元串常量的差別

    形式上: 字元常量是單引号引起的一個字元 字元串常量是雙引号引起的若幹個字元

    含義上: 字元常量相當于一個整形值(ASCII值),可以參加表達式運算 字元串常量代表一個位址值(該字元串在記憶體中存放位置)

    占記憶體大小 字元常量隻占一個位元組 字元串常量占若幹個位元組(至少一個字元結束标志)

什麼是字元串常量池?

字元串常量池位于堆記憶體中,專門用來存儲字元串常量,可以提高記憶體的使用率,避免開辟多塊空間存儲相同的字元串,在建立字元串時 JVM 會首先檢查字元串常量池,如果該字元串已經存在池中,則傳回它的引用,如果不存在,則執行個體化一個字元串放到池中,并傳回其引用。

String 是最基本的資料類型嗎

不是。Java 中的基本資料類型隻有 8 個 :byte、short、int、long、float、double、char、boolean;除了基本類型(primitive type),剩下的都是引用類型(referencetype),Java 5 以後引入的枚舉類型也算是一種比較特殊的引用類型。

這是很基礎的東西,但是很多初學者卻容易忽視,Java 的 8 種基本資料類型中不包括 String,基本資料類型中用來描述文本資料的是 char,但是它隻能表示單個字元,比如 ‘a’,‘好’ 之類的,如果要描述一段文本,就需要用多個 char 類型的變量,也就是一個 char 類型數組,比如“你好” 就是長度為2的數組 char[] chars = {‘你’,‘好’};

但是使用數組過于麻煩,是以就有了 String,String 底層就是一個 char 類型的數組,隻是使用的時候開發者不需要直接操作底層數組,用更加簡便的方式即可完成對字元串的使用。

String有哪些特性

    不變性:String 是隻讀字元串,是一個典型的 immutable 對象,對它進行任何操作,其實都是建立一個新的對象,再把引用指向該對象。不變模式的主要作用在于當一個對象需要被多線程共享并頻繁通路時,可以保證資料的一緻性。

    常量池優化:String 對象建立之後,會在字元串常量池中進行緩存,如果下次建立同樣的對象時,會直接傳回緩存的引用。

    final:使用 final 來定義 String 類,表示 String 類不能被繼承,提高了系統的安全性。

String為什麼是不可變的嗎?

簡單來說就是String類利用了final修飾的char類型數組存儲字元,源碼如下圖是以:

2020JAVA基礎面試題大全

String真的是不可變的嗎?

我覺得如果别人問這個問題的話,回答不可變就可以了。 下面隻是給大家看兩個有代表性的例子:

1) String不可變但不代表引用不可以變

2020JAVA基礎面試題大全

結果:

2020JAVA基礎面試題大全

解析:

實際上,原來String的内容是不變的,隻是str由原來指向"Hello"的記憶體位址轉為指向"Hello World"的記憶體位址而已,也就是說多開辟了一塊記憶體區域給"Hello World"字元串。

2) 通過反射是可以修改所謂的“不可變”對象

2020JAVA基礎面試題大全

結果:

2020JAVA基礎面試題大全

解析:

用反射可以通路私有成員, 然後反射出String對象中的value屬性, 進而改變通過獲得的value引用改變數組的結構。但是一般我們不會這麼做,這裡隻是簡單提一下有這個東西。

是否可以繼承 String 類

String 類是 final 類,不可以被繼承。

String str="i"與 String str=new String(“i”)一樣嗎?

不一樣,因為記憶體的配置設定方式不一樣。String str="i"的方式,java 虛拟機會将其配置設定到常量池中;而 String str=new String(“i”) 則會被分到堆記憶體中。

String s = new String(“xyz”);建立了幾個字元串對象

兩個對象,一個是靜态區的"xyz",一個是用new建立在堆上的對象。

2020JAVA基礎面試題大全

如何将字元串反轉?

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

示例代碼:

2020JAVA基礎面試題大全

數組有沒有 length()方法?String 有沒有 length()方法

數組沒有 length()方法 ,有 length 的屬性。String 有 length()方法。JavaScript中,獲得字元串的長度是通過 length 屬性得到的,這一點容易和 Java 混淆。

String 類的常用方法都有那些?

  •     indexOf():傳回指定字元的索引。
  •     charAt():傳回指定索引處的字元。
  •     replace():字元串替換。
  •     trim():去除字元串兩端空白。
  •     split():分割字元串,傳回一個分割後的字元串數組。
  •     getBytes():傳回字元串的 byte 類型數組。
  •     length():傳回字元串長度。
  •     toLowerCase():将字元串轉成小寫字母。
  •     toUpperCase():将字元串轉成大寫字元。
  •     substring():截取字元串。
  •     equals():字元串比較。

在使用 HashMap 的時候,用 String 做 key 有什麼好處?

HashMap 内部實作是通過 key 的 hashcode 來确定 value 的存儲位置,因為字元串是不可變的,是以當建立字元串時,它的 hashcode 被緩存下來,不需要再次計算,是以相比于其他對象更快。

String和StringBuffer、StringBuilder的差別是什麼?String為什麼是不可變的

可變性

String類中使用字元數組儲存字元串,private final char value[],是以string對象是不可變的。StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字元數組儲存字元串,char[] value,這兩種對象都是可變的。

線程安全性

String中的對象是不可變的,也就可以了解為常量,線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字元串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對方法加了同步鎖或者對調用的方法加了同步鎖,是以是線程安全的。StringBuilder并沒有對方法進行加同步鎖,是以是非線程安全的。

性能

每次對String 類型進行改變的時候,都會生成一個新的String對象,然後将指針指向新的String 對象。StringBuffer每次都會對StringBuffer對象本身進行操作,而不是生成新的對象并改變對象引用。相同情況下使用StirngBuilder 相比使用StringBuffer 僅能獲得10%~15% 左右的性能提升,但卻要冒多線程不安全的風險。

對于三者使用的總結

如果要操作少量的資料用 = String

單線程操作字元串緩沖區 下操作大量資料 = StringBuilder

多線程操作字元串緩沖區 下操作大量資料 = StringBuffer

Date相關

包裝類相關

自動裝箱與拆箱

裝箱:将基本類型用它們對應的引用類型包裝起來;

拆箱:将包裝類型轉換為基本資料類型;

int 和 Integer 有什麼差別

Java 是一個近乎純潔的面向對象程式設計語言,但是為了程式設計的友善還是引入了基本資料類型,但是為了能夠将這些基本資料類型當成對象操作,Java 為每一個基本資料類型都引入了對應的包裝類型(wrapper class),int 的包裝類就是 Integer,從 Java 5 開始引入了自動裝箱/拆箱機制,使得二者可以互相轉換。

Java 為每個原始類型提供了包裝類型:

原始類型: boolean,char,byte,short,int,long,float,double

包裝類型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

Integer a= 127 與 Integer b = 127相等嗎

對于對象引用類型:==比較的是對象的記憶體位址。

對于基本資料類型:==比較的是值。

如果整型字面量的值在-128到127之間,那麼自動裝箱時不會new新的Integer對象,而是直接引用常量池中的Integer對象,超過範圍 a1==b1的結果是false

2020JAVA基礎面試題大全

繼續閱讀