2021最新 Java基礎(chǔ)面試題精選(附刷題小程序)
為了能讓您更加方便的閱讀 本文所有的面試題目均已整理至小程序《面試手冊(cè)》 可以通過微信掃描(或長(zhǎng)按)下圖的二維碼享受更好的閱讀體驗(yàn)!

最近梳理匯總了Java面試常遇到的面試題;并將其開發(fā)成小程序《面試手冊(cè)》,方便大家閱讀,可微信掃描文章開頭的二維碼使用;包含了Java基礎(chǔ)
、并發(fā)
、JVM
、數(shù)據(jù)庫(kù)
、Spring
、SpringMVC
、SpringBoot
、SpringCloud
、設(shè)計(jì)模式
、消息隊(duì)列
、Linux
、Docker
等多個(gè)類型,資料持續(xù)更新中;
本人不才,如出現(xiàn)錯(cuò)誤或者不準(zhǔn)確的地方,望各位大神指正。
1. Java 基本概念
Java源程序的擴(kuò)展名是什么?
.java
什么是標(biāo)識(shí)符?
在java語(yǔ)言中能夠我們自己起名的都叫標(biāo)識(shí)符
標(biāo)識(shí)符有哪些特點(diǎn)?
標(biāo)識(shí)符是大小寫字母、數(shù)字字符、$和_組成,不能以數(shù)字開頭,也不能是java關(guān)鍵字,并且區(qū)分大小寫
請(qǐng)說明環(huán)境變量Path 與 classpath 區(qū)別
path是系統(tǒng)用來指定可指定文件的完整路徑。Path是用來搜索所執(zhí)行的可執(zhí)行文件路徑的,如果執(zhí)行的可執(zhí)行文件不在當(dāng)前目錄下,那就會(huì)依次搜索path中設(shè)置的路徑。
classpath是指定你在程序中所使用的類(.class)文件所在的位置。
java程序經(jīng)編譯后產(chǎn)生的字節(jié)碼文件擴(kuò)展名是什么?
字節(jié)碼文件擴(kuò)展名是 .class
請(qǐng)解釋Java語(yǔ)言的跨平臺(tái)特性?
Java語(yǔ)言是跨平臺(tái)運(yùn)行的,其實(shí)就是不同的操作系統(tǒng),使用不同的JVM映射規(guī)則,讓其與操作系統(tǒng)無關(guān),完成了跨平臺(tái)性。JVM對(duì)上層的Java源文件是不關(guān)心的,它關(guān)注的只是由源文件生成的類文件(class file)。
請(qǐng)說明JDK、JRE、JVM的區(qū)別?
JDK Java Development Kit(Java開發(fā)工具包)。JDK是整個(gè)JAVA的核心,包括了Java運(yùn)行環(huán)境(Java Runtime Environment),一堆Java工具(javac/java/javap等)
JRE Java Runtime Environment(java運(yùn)行時(shí)環(huán)境)。也就是我們說的JAVA平臺(tái)。所有的Java程序都要在JRE下才能運(yùn)行。包括JVM和JAVA核心類庫(kù)和支持文件。與JDK相比,它不包含開發(fā)工具(編譯器、調(diào)試器和其他工具)。
JVM Java Virtual Mechinal(JAVA虛擬機(jī))。JVM是JRE的一部分,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。
請(qǐng)說出常用的DOS命令并解釋?
d: 回車 盤符切換
dir (directory) 列出當(dāng)前目錄下的文件以及文件夾
cd (change directory) 改變指定目錄(進(jìn)入指定目錄)
cd.. 退回到上一層目錄
cd \ 退回到跟目錄
md (make directory) 創(chuàng)建目錄
rd (remove directory) 刪除目錄
del (delete) 刪除文件,刪除一堆后綴名一樣的文件*.txt
cls (clear screen) 清屏
exit 退出dos命令行
2. Java 基礎(chǔ)
請(qǐng)說出Java中數(shù)據(jù)類型的分類?基本數(shù)據(jù)類型都有哪些?
基本數(shù)據(jù)類型
byte
short
int
long
float
double
char
boolean
引用數(shù)據(jù)類型
數(shù)組
類
接口
Java中數(shù)據(jù)的類型轉(zhuǎn)換有幾種?分別是什么?
強(qiáng)制類型轉(zhuǎn)換 容量大的類型向容量小的類型轉(zhuǎn)換時(shí)使用
隱式類型轉(zhuǎn)換 容器小的類型向容量大的類型轉(zhuǎn)換時(shí)使用
Java語(yǔ)言中的字符char可以存儲(chǔ)一個(gè)中文漢字嗎?為什么呢?
char型變量是用來存儲(chǔ)Unicode編碼的字符的,unicode編碼字符集中包含了漢字,所以,char型變量中可以存儲(chǔ)漢字。不過,如果某個(gè)特殊的漢字沒有被包含在unicode編碼字符集中,那么,這個(gè)char型變量中就不能存儲(chǔ)這個(gè)特殊漢字。 補(bǔ)充說明:unicode編碼占用兩個(gè)字節(jié),所以,char類型的變量也是占用兩個(gè)字節(jié)。
注釋的分類及作用?
單行注釋 注釋單行代碼或?yàn)閱涡写a添加描述的時(shí)候使用
多行注釋 注釋多行代碼或?yàn)榇a添加多行描述的時(shí)候使用
文檔注釋 生產(chǎn)java幫助文檔的時(shí)候使用,開發(fā)中常用來描述類、描述方法
請(qǐng)說明 == 與 = 的區(qū)別?
== 比較運(yùn)算符,用來比較操作符兩邊的變量的值是否相等。
= ?賦值運(yùn)算符,把操作符右邊的值,賦值給左邊的變量
import的作用?
在不同包下的類之間相互訪問的時(shí)候,發(fā)現(xiàn),每次使用不同包下的類的時(shí)候,都需要加包的全路徑。比較麻煩,這個(gè)時(shí)候,java就提供了( import )導(dǎo)包的功能。 使用import可以將包中的類導(dǎo)入進(jìn)來,以后使用類的時(shí)候,不需導(dǎo)包,直接使用,簡(jiǎn)化了書寫。
請(qǐng)解釋 ==與equals()方法的區(qū)別?
== 解讀
對(duì)于基本類型和引用類型 == 的作用效果是不同的,如下所示:
基本類型:比較的是值是否相同;
引用類型:比較的是引用是否相同;
代碼示例:
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
代碼解讀:因?yàn)?x 和 y 指向的是同一個(gè)引用,所以 == 也是 true,而 new String()方法則重寫開辟了內(nèi)存空間,所以 == 結(jié)果為 false,而 equals 比較的一直是值,所以結(jié)果都為 true。
equals 解讀
equals 本質(zhì)上就是 ==,只不過 String 和 Integer 等重寫了 equals 方法,把它變成了值比較??聪旅娴拇a就明白了。
首先來看默認(rèn)情況下 equals 比較一個(gè)有相同值的對(duì)象,代碼如下:
class Cat {
?public Cat(String name) {
? ?this.name = name;
?}
?private String name;
?public String getName() {
? ?return name;
?}
?public void setName(String name) {
? ?this.name = name;
?}
}
Cat c1 = new Cat("mbb");
Cat c2 = new Cat("mbb");
System.out.println(c1.equals(c2)); // false
輸出結(jié)果出乎我們的意料,竟然是 false?這是怎么回事,看了 equals 源碼就知道了,源碼如下:
public boolean equals(Object obj) {
?return (this == obj);
}
原來 equals 本質(zhì)上就是 ==。
那問題來了,兩個(gè)相同值的 String 對(duì)象,為什么返回的是 true?代碼如下:
String s1 = new String("mbb");
String s2 = new String("mbb");
System.out.println(s1.equals(s2)); // true
同樣的,當(dāng)我們進(jìn)入 String 的 equals 方法,找到了答案,代碼如下:
public boolean equals(Object anObject) {
?if (this == anObject) {
? ?return true;
?}
?if (anObject instanceof String) {
? ?String anotherString = (String)anObject;
? ?int n = value.length;
? ?if (n == anotherString.value.length) {
? ? ?char v1[] = value;
? ? ?char v2[] = anotherString.value;
? ? ?int i = 0;
? ? ?while (n-- != 0) {
? ? ? ?if (v1[i] != v2[i])
? ? ? ? ?return false;
? ? ? ?i++;
? ? ?}
? ? ?return true;
? ?}
?}
?return false;
}
原來是 String 重寫了 Object 的 equals 方法,把引用比較改成了值比較。
總結(jié) :== 對(duì)于基本類型來說是值比較,對(duì)于引用類型來說是比較的是引用;而 equals 默認(rèn)情況下是引用比較,只是很多類重新了 equals 方法,比如 String、Integer 等把它變成了值比較,所以一般情況下 equals 比較的是值是否相等。
兩個(gè)對(duì)象的 hashCode() 相同,則 equals() 也一定為 true,對(duì)嗎?
不對(duì),兩個(gè)對(duì)象的 hashCode() 相同,equals() 不一定 true。
代碼示例:
String str1 = "通話";
String str2 = "重地";
System. out. println(String. format("str1:%d | str2:%d", str1. hashCode(),str2. hashCode()));
System. out. println(str1. equals(str2));
執(zhí)行的結(jié)果:
str1:1179395 | str2:1179395
false
代碼解讀:很顯然“通話”和“重地”的 hashCode() 相同,然而 equals() 則為 false,因?yàn)樵谏⒘斜碇?,hashCode() 相等即兩個(gè)鍵值對(duì)的哈希值相等,然而哈希值相等,并不一定能得出鍵值對(duì)相等。
請(qǐng)說明 && 和 & 的區(qū)別?
&和&&都可以用作邏輯與的運(yùn)算符,表示邏輯與(and),當(dāng)運(yùn)算符兩邊的表達(dá)式的結(jié)果都為true時(shí),整個(gè)運(yùn)算結(jié)果才為true,否則,只要有一方為false,則結(jié)果為false。
&&還具有短路的功能,即如果第一個(gè)表達(dá)式為false,則不再計(jì)算第二個(gè)表達(dá)式
&還可以用作位運(yùn)算符,當(dāng)&操作符兩邊的表達(dá)式不是boolean類型時(shí),&表示按位與操作。
三元運(yùn)算符的基本格式是什么?
三元運(yùn)算符的格式是: 條件表達(dá)式 ? 表達(dá)式1 : 表達(dá)式2
三元運(yùn)算符的執(zhí)行流程是什么?
三元運(yùn)算符的執(zhí)行流程: 首先計(jì)算條件表達(dá)式的值看其返回結(jié)果是true還是false,如果是true就執(zhí)行表達(dá)式1,如果是false就執(zhí)行表達(dá)式2
請(qǐng)說明for、while、do…while三種循環(huán)的格式以及執(zhí)行流程,以及它們的區(qū)別。
for循環(huán)語(yǔ)句格式 for(初始化語(yǔ)句;判斷條件語(yǔ)句;控制條件語(yǔ)句) { ?循環(huán)體語(yǔ)句; }
執(zhí)行流程:
執(zhí)行初始化語(yǔ)句
執(zhí)行判斷條件語(yǔ)句,看其結(jié)果是true還是false,如果是false,循環(huán)結(jié)束;如果是true,繼續(xù)執(zhí)行。
執(zhí)行循環(huán)體語(yǔ)句
執(zhí)行控制條件語(yǔ)句
回到b繼續(xù)
while循環(huán)語(yǔ)句格式 while(判斷條件語(yǔ)句) { ?循環(huán)體語(yǔ)句; }
執(zhí)行流程:
執(zhí)行判斷條件語(yǔ)句,看其結(jié)果是true還是false 如果是false,循環(huán)結(jié)束。 如果是true,繼續(xù)執(zhí)行。
執(zhí)行循環(huán)體語(yǔ)句
回到a繼續(xù)
do…while循環(huán)語(yǔ)句格式 do { ?循環(huán)體語(yǔ)句; }while((判斷條件語(yǔ)句);
執(zhí)行流程:
執(zhí)行循環(huán)體語(yǔ)句
執(zhí)行判斷條件語(yǔ)句,看其結(jié)果是true還是false,如果是false,循環(huán)結(jié)束;如果是true,繼續(xù)執(zhí)行。
回到a繼續(xù)
三種循環(huán)語(yǔ)句的區(qū)別
do…while循環(huán)至少會(huì)執(zhí)行一次循環(huán)體
for循環(huán)和while循環(huán)只有在條件成立的時(shí)候才會(huì)去執(zhí)行循環(huán)體
注意:寫程序優(yōu)先考慮for循環(huán),再考慮while循環(huán),最后考慮do…while循環(huán)
package它有什么作用?
package,包的意思,其實(shí)就是文件夾,它可以對(duì)類進(jìn)行分類管理
private 關(guān)鍵字在哪里使用? 被 private 修飾的成員有什么特點(diǎn)?
類中的成員需要私有的時(shí)候使用private關(guān)鍵字 特點(diǎn): 是一個(gè)權(quán)限修飾符。 可以修飾成員(成員變量和成員方法) 被private修飾的成員只在本類中才能訪問
為什么要有 this 關(guān)鍵字?this 關(guān)鍵字的含義?
this用來解決成員變量與局部變量重名問題 this關(guān)鍵字代表的是本類對(duì)象引用;誰(shuí)調(diào)用我,this就代表誰(shuí).
Java 中的 Math. round(-1. 5) 等于多少?
等于 -1,因?yàn)樵跀?shù)軸上取值時(shí),中間值(0.5)向右取整,所以正 0.5 是往上取整,負(fù) 0.5 是直接舍棄。
final 關(guān)鍵字是什么意思,可以修飾那些成員?被修飾的成員有哪些特點(diǎn)?
final最終的意思。
可修飾
類
成員變量
成員方法
特點(diǎn)
final修飾類,此類不能被繼承。
final修飾變量,變量就成了常量,只能被賦值一次
final修飾方法,方法不能被重寫
定義一個(gè)方法的格式是什么,以及方法的注意事項(xiàng)?
格式 修飾符 返回值類型 方法名(參數(shù)類型 參數(shù)名1, 參數(shù)類型 參數(shù)名2 ….){ 方法體 ; return 返回值 ; }
注意事項(xiàng) A. 方法不調(diào)用不執(zhí)行 B. 方法與方法是平級(jí)關(guān)系,不能嵌套定義 C. 方法定義的時(shí)候參數(shù)之間用逗號(hào)隔開 D. 方法調(diào)用的時(shí)候不用在傳遞數(shù)據(jù)類型 E. 如果方法有明確的返回值,一定要有return帶回一個(gè)值
請(qǐng)簡(jiǎn)述泛型是什么?有什么用?在哪里用?
泛型是什么? 泛型是一種特殊的類型,它把指定類型的工作推遲到客戶端代碼聲明并實(shí)例化類或方法的使用進(jìn)行。也被稱為參數(shù)化類型,可以把類型當(dāng)做參數(shù)一樣傳遞過來,在傳遞過來之前我不明確,但是在使用的時(shí)候就就明確了。
泛型的好處
提高了程序的安全性
將運(yùn)行期遇到的問題轉(zhuǎn)移到了編譯期
省去了類型強(qiáng)轉(zhuǎn)的麻煩
泛型的常見應(yīng)用
泛型類
泛型方法
泛型接口
如何編寫一個(gè)泛型方法,讓它能夠接受泛型參數(shù)并返回泛型類型?并舉例
泛型方法,指把泛型定義在方法上,使用泛型類型來替代原始類型
public static T[] sort(T[] t){
?Arrays.sort(t);
?return t;
}
請(qǐng)簡(jiǎn)述Java中如何使用泛型編寫帶有參數(shù)的類?并舉例
泛型類,指把泛型定義在類上,使用泛型類型來替代原始類型
class GenericClass {
?private T t;
?public void setT(T t) {
? ?this.t = t;
?}
?
?public T getT() {
? ?return t;
?}
}
形式參數(shù)是基本類型要的是什么?是類名、抽象類名、接口名時(shí)分別要的是什么?
形式參數(shù)是基本類型要的是一個(gè)基本類型的變量或者具體的常量值
類名時(shí) 要的是一個(gè)該類的對(duì)象
抽象類名時(shí) 要的是一個(gè)繼承自該類的一個(gè)子類對(duì)象
接口時(shí) 要的是一個(gè)實(shí)現(xiàn)了該接口的子類對(duì)象
返回值類型是基本類型返回的是什么?是類名、抽象類名、接口名分別返回的是什么?
返回值是基本數(shù)據(jù)類型的時(shí)候返回的是一個(gè)具體的值
類名時(shí) 本質(zhì)上返回的是一個(gè)該類對(duì)應(yīng)的子類對(duì)象
抽象類名時(shí) 返回的應(yīng)該是一個(gè)繼承自該類的子類對(duì)象
接口名的時(shí) 返回的是一個(gè)實(shí)現(xiàn)了該接口的子類對(duì)象
請(qǐng)簡(jiǎn)述遞歸是什么?注意事項(xiàng)是什么?
所謂遞歸,是指程序調(diào)用自身。 注意,遞歸不會(huì)無休止地調(diào)用下去,它必然有一個(gè)出口,當(dāng)滿足條件時(shí)程序也就結(jié)束了,不然的話,那就是死循環(huán)了。
請(qǐng)說說文件名稱過濾器FilenameFilter的作用?
FilenameFilter是文件名過濾器,用來過濾不符合規(guī)則的文件名,并返回合格的文件。
使用鍵盤錄入數(shù)據(jù)的三個(gè)步驟是什么?
第一步導(dǎo)包 格式: import java.util.Scanner ;位置: 在class上邊
第二步創(chuàng)建Scanner對(duì)象 格式: Scanner sc = new Scanner(System.in) ;
第三步獲取鍵盤錄入數(shù)據(jù) 格式: int x = sc.nextInt() ;
3. Java 變量
變量是什么?
變量,在程序運(yùn)行時(shí),值可以被修改的量。
變量的定義格式是什么?
數(shù)據(jù)類型 變量名 = 變量值
成員變量與局部變量的區(qū)別?
在類中的位置不同 成員變量:在類中方法外 局部變量:在方法定義中或者方法聲明上
在內(nèi)存中的位置不同 成員變量:在堆內(nèi)存 局部變量:在棧內(nèi)存
生命周期不同 成員變量:隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失 局部變量:隨著方法的調(diào)用而存在,隨著方法的調(diào)用完畢而消失
初始化值不同 成員變量:有默認(rèn)初始化值 局部變量:沒有默認(rèn)初始化值,必須定義,賦值,然后才能使用。
請(qǐng)寫出Java標(biāo)識(shí)符的命名規(guī)則
包 全部小寫
單層包 小寫,舉例:itcast,com
多層包 小寫,并用 . 隔開,舉例:cn.itcast, com.baidu
類或者接口:
一個(gè)單詞 首字母大寫,舉例:Student,Demo
多個(gè)單詞 每個(gè)單詞首字母大寫,舉例:HelloWorld,StudentName
方法或者變量:
一個(gè)單詞 首字母小寫,舉例:name,main
多個(gè)單詞 從第二個(gè)單詞開始,每個(gè)單詞首字母大寫,舉例:studentAge,showStudentNames()
常量 全部大寫
一個(gè)單詞 大寫,舉例:PI
多個(gè)單詞 大寫,并用 _ 隔開,舉例:STUDENT_MAX_AGE
靜態(tài)變量與成員變量的區(qū)別?
所屬不同 靜態(tài)變量屬于類,所以也稱為為類變量 成員變量屬于對(duì)象,所以也稱為實(shí)例變量(對(duì)象變量)
內(nèi)存中位置不同 靜態(tài)變量存儲(chǔ)于方法區(qū)的靜態(tài)區(qū) 成員變量存儲(chǔ)于堆內(nèi)存
內(nèi)存出現(xiàn)時(shí)間不同 靜態(tài)變量隨著類的加載而加載,隨著類的消失而消失 成員變量隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失
調(diào)用不同 靜態(tài)變量可以通過類名調(diào)用,也可以通過對(duì)象調(diào)用 成員變量只能通過對(duì)象名調(diào)用
4. Java String
String 類的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引處的字符。
replace():字符串替換。
trim():去除字符串兩端空白。
split():分割字符串,返回一個(gè)分割后的字符串?dāng)?shù)組。
getBytes():返回字符串的 byte 類型數(shù)組。
length():返回字符串長(zhǎng)度。
toLowerCase():將字符串轉(zhuǎn)成小寫字母。
toUpperCase():將字符串轉(zhuǎn)成大寫字符。
substring():截取字符串。
equals():字符串比較。
如何將字符串反轉(zhuǎn)?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
示例代碼:
// StringBuffer reverse StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("abcdefg"); System.out.println(stringBuffer.reverse()); // gfedcba // StringBuilder reverse StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("abcdefg"); System. out. println(stringBuilder.reverse()); // gfedcba
String str=“i” 與 String str=new String(“i”)一樣嗎?
不一樣,因?yàn)閮?nèi)存的分配方式不一樣。String str="i"的方式,Java 虛擬機(jī)會(huì)將其分配到常量池中;而 String str=new String(“i”) 則會(huì)被分到堆內(nèi)存中。
String 屬于基礎(chǔ)的數(shù)據(jù)類型嗎?
String 不屬于基礎(chǔ)類型 基礎(chǔ)類型有 8 種:
byte
boolean
char
short
int
float
long
double
而 String 屬于對(duì)象
String s = “a”+“b”+”c”; 創(chuàng)建了多少對(duì)象,分別是什么?
5個(gè)對(duì)象
a
b
c
ab
abc
因?yàn)樽址奶攸c(diǎn)是一旦被創(chuàng)建就不能被改變,所有在使用常量進(jìn)行相加的時(shí)候,都是在創(chuàng)建新的字符串對(duì)象,最后在把字符串"abc"這個(gè)常量值賦值給引用變量s
如何實(shí)現(xiàn)StringBuffer和String的相互轉(zhuǎn)換?
通過String類的構(gòu)造方法
通過StringBuffer類中的toString()方法
通過StringBuffer類中的substring()方法 (注:不常用) String 轉(zhuǎn)換到 StringBuffer的方式:
通過StringBuffer類的構(gòu)造方法
通過StringBuffer類的append()、insert()方法
如何實(shí)現(xiàn)String和int數(shù)據(jù)的相互轉(zhuǎn)換
String – Integer – int通過Integer類的intValue()方法
通過Integer類的parseInt(String s)方法 Int 轉(zhuǎn)換到 String的方式:
Int – Integer – String Integer的toSting()
通過String類的valueOf()方法
通過Integer類的toSting(int i)方法
通過與字符串""相連接
如何實(shí)現(xiàn)【基本數(shù)據(jù)類型】與【基本數(shù)據(jù)封裝類】之間的相互轉(zhuǎn)換
通過包裝類的構(gòu)造方法
通過包裝類的靜態(tài)方法valueOf() 包裝類 轉(zhuǎn)換到 基本數(shù)據(jù)類型的方式:
通過包裝類的方法xxxValue()
請(qǐng)說明String與StringBuffer二者之間的區(qū)別?
String類表示內(nèi)容不可以改變的字符串 StringBuffer類表示內(nèi)容可以被修改的字符串
請(qǐng)說明StringBuffer與StringBilder二者之間的區(qū)別?
StringBilder 是線程不安全的,運(yùn)行效率高
如果一個(gè)字符串變量是在方法里面定義,這種情況只可能有一個(gè)線程訪問它,不存在不安全的因素了,則用StringBuilder。
StringBuffer 是線程安全的,運(yùn)行要低于StringBilder
如果要在類里面定義成員變量,并且這個(gè)類的實(shí)例對(duì)象會(huì)在多線程環(huán)境下使用,那么最好用StringBuffer。
如何實(shí)現(xiàn)Date與String相互轉(zhuǎn)換?
Date 轉(zhuǎn) String
Date類的toString()方法
DateFormat類的format()方法
String 轉(zhuǎn) Date
Date類的構(gòu)造方法
已過時(shí),被DateFormat類的parse(String s)方法取代
DateFormat類的parse()方法
如何實(shí)現(xiàn)Date與long相互轉(zhuǎn)換?
Date 轉(zhuǎn) long 通過Date類的getTime()方法
long 轉(zhuǎn) Date 通過Date類的構(gòu)造方法
什么是正則表達(dá)式?
正則表達(dá)式使用單個(gè)字符串來描述、匹配一系列符合某個(gè)句法規(guī)則的字符串。在很多文本編輯器里,正則達(dá)表示通常被用來檢索、替換那些符合某個(gè)模式的文本。
5. Java 類、抽象類、接口、內(nèi)部類、代碼塊
類是什么? 對(duì)象是什么?舉例說明
是一組相關(guān)屬性和行為的集合是一個(gè)抽象的東西,對(duì)象則是該類的一個(gè)具體的體現(xiàn)。
舉例: 學(xué)生就是一個(gè)類,然后每一個(gè)學(xué)生都是學(xué)生的一個(gè)個(gè)具體的體現(xiàn),所以每一個(gè)學(xué)生就是一個(gè)學(xué)生。
類由哪些內(nèi)容組成?
類由成員變量和成員方法組成 成員變量對(duì)應(yīng)的就是事物的屬性(就是事物固有的信息,比如: 人的屬性有身高 , 姓名 , 年齡 , 學(xué)歷…) , 成員方法對(duì)應(yīng)的是行為(行為: 就是該事物可以做的事情,比如:人的行為有: 吃飯,睡覺…)
抽象類是什么,抽象類的特點(diǎn)?
抽象類的定義 使用了關(guān)鍵字abstract聲明的類叫做“抽象類”。如果一個(gè)類里包含了一個(gè)或多個(gè)抽象方法,類就必須指定成abstract(抽象)。“抽象方法”,屬于一種不完整的方法,只含有一個(gè)聲明,沒有方法主體。
抽象類的特點(diǎn):
可以是抽象類
如果子類還是抽象類,那么我們還是不能進(jìn)行實(shí)例化,還需要一個(gè)子類去繼承
也可以是非抽象類
子類必須重寫父類的抽象方法
抽象類的定義格式: abstract class 類名{}
抽象方法的定義格式: public abstract 返回值類型 方法名();
抽象類中可以存在抽象方法,也可以存在非抽象方法
抽象類不能直接進(jìn)行實(shí)例化,我們可以使用多態(tài)的形式進(jìn)行進(jìn)行間接實(shí)例化
抽象類的子類
抽象類能使用 final 修飾嗎?
不能,定義抽象類就是讓其他類繼承的,如果定義為 final 該類就不能被繼承,這樣彼此就會(huì)產(chǎn)生矛盾,所以 final 不能修飾抽象類
抽象類必須要有抽象方法嗎?
不需要,抽象類不一定非要有抽象方法。
示例代碼:
abstract class Cat {
?public static void sayHi() {
? ?System.out.println("hi~");
?}
}
上面代碼,抽象類并沒有抽象方法但完全可以正常運(yùn)行。
抽象類中有沒有構(gòu)造方法,如果有它是用來做什么的?
抽象類雖然不能進(jìn)行實(shí)例化,但是抽象類中是存在構(gòu)造方法,該構(gòu)造方法的作用是用于子類訪問父類數(shù)據(jù)時(shí)的初始化.
接口中成員變量的特點(diǎn),以及成員方法的特點(diǎn)?
接口中的成員變量都是常量,存在默認(rèn)的訪問修飾符:
public static final
接口中的成員方法都是抽象方法,存在默認(rèn)的訪問修飾符:
public abstract
抽象類和接口的區(qū)別?
成員區(qū)別
抽象類
成員變量 可以是變量,也可以是常量
構(gòu)造方法 有
成員方法 可以抽象,也可以非抽象
接口:
成員變量 只可以常量
成員方法 只可以抽象
關(guān)系區(qū)別
類與類 繼承,單繼承
類與接口 實(shí)現(xiàn),單實(shí)現(xiàn),多實(shí)現(xiàn)
接口與接口 繼承,單繼承,多繼承
設(shè)計(jì)理念區(qū)別
抽象類 被繼承體現(xiàn)的是:“is a”的關(guān)系。 抽象類中定義的是該繼承體系的共性功能。
接口 被實(shí)現(xiàn)體現(xiàn)的是:“like a”的關(guān)系。 接口中定義的是該繼承體系的擴(kuò)展功能。
請(qǐng)說出類與類,類與接口,以及接口與接口的關(guān)系以及特點(diǎn)?
類與類 是繼承的關(guān)系,
只支持單繼承,可以是多層繼承
。類與接口 是實(shí)現(xiàn)的關(guān)系,
可以是多實(shí)現(xiàn)
特點(diǎn)
一個(gè)類可以繼承一個(gè)類的同時(shí),還可以實(shí)現(xiàn)多個(gè)接口
接口與接口是繼承的關(guān)系,可以是單繼承也可以是多繼承
構(gòu)造方法的作用是什么?構(gòu)造方法的特點(diǎn)是什么?構(gòu)造方法的注意事項(xiàng)? 構(gòu)造方法中可不可以寫return 語(yǔ)句呢?
構(gòu)造方法的作用是用于給類的成員變量賦值,完成類的初始化工作
構(gòu)造方法的特點(diǎn): 構(gòu)造方法的名稱和類名相同 構(gòu)造方法沒有返回值類型,連void也沒有 構(gòu)造方法沒有具體的返回值
構(gòu)造方法的注意事項(xiàng):
如果一個(gè)類沒有給出構(gòu)造方法,系統(tǒng)將會(huì)提供一個(gè)默認(rèn)無參的構(gòu)造方法
如果我們給出類構(gòu)造方法,系統(tǒng)將不會(huì)提供默認(rèn)無參的構(gòu)造方法,這個(gè)時(shí)候如果我們還想使用無參的構(gòu)造方法來創(chuàng)建對(duì)象,那么就需要我們給出無參的構(gòu)造方法 可以寫空的return語(yǔ)句.
一個(gè)類的缺省構(gòu)造方法可以有參數(shù)嗎?
一個(gè)類的缺省構(gòu)造方法沒有參數(shù)
子父類中構(gòu)造方法的執(zhí)行有什么特點(diǎn)?為什么要這樣?
子類有所有的構(gòu)造方法默認(rèn)都會(huì)訪問父類中空參數(shù)的構(gòu)造方法。 因?yàn)樽宇悤?huì)繼承父類中的數(shù)據(jù),可能還會(huì)使用父類的數(shù)據(jù)。所以,子類初始化之前,一定要先完成父類數(shù)據(jù)的初始化。 ?每一個(gè)構(gòu)造方法的第一條語(yǔ)句默認(rèn)都是:super()
如果父類中沒有空參數(shù)的構(gòu)造方法,通過下列方式解決
子類通過super去顯示調(diào)用父類其他的帶參的構(gòu)造方法
子類通過this去調(diào)用本類的其他構(gòu)造方法(本類其他構(gòu)造也必須首先可以訪問了父類構(gòu)造)
注意:super(…)或者this(…)必須出現(xiàn)在第一條語(yǔ)句上,否則,就會(huì)有父類數(shù)據(jù)的多次初始化
請(qǐng)說明一個(gè)對(duì)象的創(chuàng)建過程做了哪些事情?
Student s = new Student();
將Student.class 字節(jié)碼文件加載到內(nèi)存
在棧內(nèi)存中,開辟一個(gè)空間存儲(chǔ) s變量,用來記錄Student對(duì)象的引用
在堆內(nèi)存中,開辟一個(gè)空間存儲(chǔ) new Student()對(duì)象的成員信息
加載類中靜態(tài)成員
執(zhí)行類中靜態(tài)代碼塊
加載對(duì)象中普通成員
執(zhí)行構(gòu)造代碼塊
執(zhí)行構(gòu)造方法
將new Student()的地址賦值給 s 變量
匿名內(nèi)部類的格式是什么?其本質(zhì)是什么?
匿名內(nèi)部類的格式 new 類名或者接口名() { 方法重寫 ; } ;
本質(zhì) 匿名內(nèi)部類本質(zhì)是一個(gè)繼承了某一個(gè)類或者實(shí)現(xiàn)了某一個(gè)接口的子類對(duì)象
內(nèi)部類有哪些訪問特點(diǎn)?
內(nèi)部類可以直接訪問外部類的成員,包括私有
外部類要訪問內(nèi)部類的成員,必須先創(chuàng)建內(nèi)部類對(duì)象
靜態(tài)代碼塊,構(gòu)造代碼塊,構(gòu)造方法的執(zhí)行順序是什么以及執(zhí)行特點(diǎn)?
先執(zhí)行所有的靜態(tài)代碼塊,再執(zhí)行所有的構(gòu)造代碼塊,最后執(zhí)行構(gòu)造方法
靜態(tài)代碼塊只執(zhí)行一次, 構(gòu)造代碼塊和構(gòu)造方法,每創(chuàng)建一次對(duì)象就執(zhí)行一次
什么是匿名對(duì)象?什么時(shí)候使用匿名對(duì)象?
匿名對(duì)象指:沒有起名字的對(duì)象 使用匿名對(duì)象: a:調(diào)用方法,僅僅只調(diào)用一次的時(shí)候 b:匿名對(duì)象可以作為實(shí)際參數(shù)傳遞
6. 封裝、繼承、多態(tài)
使用面向?qū)ο蟆痉庋b】的好處有哪些?
隱藏實(shí)現(xiàn)細(xì)節(jié),提供公共的訪問方式; 提高了代碼的復(fù)用性; 提高安全性。
繼承的好處是什么?
提高了代碼的維護(hù)型
提供了代碼的復(fù)用性
讓類與類之間產(chǎn)生了關(guān)系, 是多態(tài)的前提
Java 中的類的繼承特點(diǎn)是什么以及繼承的注意事項(xiàng)?
繼承的特點(diǎn): 在java語(yǔ)言中類的繼承只支持單繼承,不支持多繼承.但是可以多層繼承。
繼承的注意事項(xiàng):
子類只能繼承父類非私有的成員
子類不能繼承父類的構(gòu)造方法,但是可以通過super去訪問父類的構(gòu)造方法
不要為了某個(gè)功能去使用繼承
this 和 super 分別是什么,他們各自的應(yīng)用場(chǎng)景是什么?
this 代表的是本類對(duì)象的引用 , 誰(shuí)調(diào)用我這個(gè)方法,這個(gè)方法里邊的this就代表誰(shuí)。一般的使用場(chǎng)景是,當(dāng)局部變量隱藏了成員變量的時(shí)候,我們可以使用this去明確指定要訪問的是成員變量
super 代表的是父類存儲(chǔ)空間的一個(gè)標(biāo)志(可以理解為父類對(duì)象的引用),我們可以使用super來訪問父類的成員
什么是方法重寫?需要注意哪些問題?
方法重寫:指子類中出現(xiàn)了和父類中一模一樣的方法聲明,也被稱為方法覆蓋,方法復(fù)寫
需要注意的問題:
父類中私有方法不能被重寫
子類重寫父類方法時(shí),訪問權(quán)限不能更低
父類靜態(tài)方法,子類也必須通過靜態(tài)方法進(jìn)行重寫。(其實(shí)這個(gè)算不上方法重寫,但是現(xiàn)象確實(shí)如此)
請(qǐng)解釋什么是方法的重載?
方法重載指在同一個(gè)類中,允許存在一個(gè)以上的同名方法,只要它們的參數(shù)個(gè)數(shù)或者參數(shù)類型不同即可。
方法重載特點(diǎn): a) 與返回值類型無關(guān),只看方法名和參數(shù)列表 b) 在調(diào)用時(shí),虛擬機(jī)通過參數(shù)列表的不同來區(qū)分同名方法
方法重寫和重載有什么區(qū)別?
重載Overload 表示同一個(gè)類中可以有多個(gè)名稱相同的方法,但這些方法的參數(shù)列表各不相同(即參數(shù)個(gè)數(shù)或類型不同),與返回值類型無關(guān)。
重寫Override 發(fā)生在子父類中的一個(gè)現(xiàn)象, 子類中出現(xiàn)了和父類中一模一樣的方法,與返回值有關(guān).
什么是多態(tài),多態(tài)的前提是什么?
一種事物在不同時(shí)刻表現(xiàn)出來的狀態(tài)就是多態(tài)
多態(tài)的前提:
需要有繼承
需要有方法重寫(其實(shí)沒有也是可以的,但是沒有意義),不同狀態(tài)的表現(xiàn)就是就是靠方法重寫體現(xiàn)的
需要有父類的引用指向子類對(duì)象:Fu f = new 子類()
多態(tài)中成員(成員變量,成員方法,靜態(tài)成員方法)的訪問特點(diǎn)是什么?
訪問成員變量 編譯看左邊 , 運(yùn)行看左邊
因?yàn)槌蓡T變量其實(shí)就是屬性,屬性就是只該事物的描述信息,所以使用父類在訪問的時(shí)候,訪問的就是父類的成員變量
成員方法 編譯看左邊,運(yùn)行看右邊
這個(gè)是多態(tài)的本質(zhì),存在動(dòng)態(tài)綁定的機(jī)制
靜態(tài)成員方法 編譯看左邊,運(yùn)行看左邊
所以說靜態(tài)算不上重寫
多態(tài)的好處?
提供了代碼的維護(hù)性(通過繼承保證)
提供了代碼的擴(kuò)展性(通過多態(tài)保證),這個(gè)特點(diǎn)也體現(xiàn)了多態(tài)的最常見的應(yīng)用,作為參數(shù)傳遞.
多態(tài)的弊端是什么,如果我們想訪問子類的特有的功能我們應(yīng)該怎么辦?
多態(tài)的弊端,不能訪問子類中特有的功能 如果我們還想使用子類中特有的功能,我們需要使用向下轉(zhuǎn)型
向下轉(zhuǎn)型: 就是將父類的引用強(qiáng)制轉(zhuǎn)換成子類的引用,在向下轉(zhuǎn)型的過程中需要注意一個(gè)異常: ClassCastException
7. Java 容器
請(qǐng)簡(jiǎn)述集合和數(shù)組的異同點(diǎn)?
集合:
可以存儲(chǔ)不同類型的元素(通常使用存儲(chǔ)一種類型元素)
集合的長(zhǎng)度可以改變
數(shù)組:
必須存儲(chǔ)相同一類型的元素
數(shù)組的長(zhǎng)度固定
Iterator 和 ListIterator 有什么區(qū)別?
Iterator 可以遍歷 Set 和 List 集合,而 ListIterator 只能遍歷 List。
Iterator 只能單向遍歷,而 ListIterator 可以雙向遍歷(向前/后遍歷)。
ListIterator 從 Iterator 接口繼承,然后添加了一些額外的功能,比如添加一個(gè)元素、替換一個(gè)元素、獲取前面或后面元素的索引位置。
迭代器Iterator是什么?怎么使用?有什么特點(diǎn)?
Iterator 接口提供遍歷任何 Collection 的接口。我們可以從一個(gè) Collection 中使用迭代器方法來獲取迭代器實(shí)例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允許調(diào)用者在迭代過程中移除元素。
Iterator 使用代碼如下:
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
while(it.hasNext()){
?String obj = it.next();
?System.out.println(obj);
}
Iterator的特點(diǎn)是更加安全,因?yàn)樗梢源_保,在當(dāng)前遍歷的集合元素被更改的時(shí)候,就會(huì)拋出 ConcurrentModificationException 異常。
請(qǐng)簡(jiǎn)述常見的數(shù)據(jù)結(jié)構(gòu)有哪些?
線性表
鏈表
棧
隊(duì)列
樹
哈希表
請(qǐng)簡(jiǎn)述ArrayList、Vector、LinkedList三者的特點(diǎn)?
ArrayList
底層數(shù)組結(jié)構(gòu)
特點(diǎn)
線程不同步
效率高
元素查找快
增刪慢;
Vector
底層數(shù)組結(jié)構(gòu)
特點(diǎn)
線程同步
安全
元素查找快
增刪慢
LinkedList
底層鏈表結(jié)構(gòu)
特點(diǎn)
線程不同步
效率高
元素增刪快
查找慢
Array 和 ArrayList 有何區(qū)別?
Array 可以存儲(chǔ)基本數(shù)據(jù)類型和對(duì)象,ArrayList 只能存儲(chǔ)對(duì)象。
Array 是指定固定大小的,而 ArrayList 大小是自動(dòng)擴(kuò)展的。
Array 內(nèi)置方法沒有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。
請(qǐng)簡(jiǎn)述ArrayList、Vector、LinkedList,分別在什么時(shí)候使用?
線程安全
Vector
非線程安全
查找多 ArrayList
增刪多 LinkedList
請(qǐng)簡(jiǎn)述并發(fā)修改異常產(chǎn)生的原因?如何解決?
異常
ConcurrentModificationException
在迭代器迭代的過程中,集合中的元素個(gè)數(shù)發(fā)生了改變,此時(shí)導(dǎo)致并發(fā)修改異常。
解決方式
通過列表迭代器自帶的方法完成元素增刪操作。
通過for循環(huán)遍歷集合,使用集合中的方法完成元素增刪操作。
在 Queue 中 poll()和 remove()有什么區(qū)別?
相同點(diǎn):都是返回第一個(gè)元素,并在隊(duì)列中刪除返回的對(duì)象。
不同點(diǎn):如果沒有元素 poll()會(huì)返回 null,而 remove()會(huì)直接拋出 NoSuchElementException 異常。
代碼示例:
Queue<String> queue = new LinkedList<String>();
queue.offer("string"); // add
System.out.println(queue.poll());
System.out.println(queue.remove());
System.out.println(queue.size());
請(qǐng)簡(jiǎn)述List<? extends T>和List<? super T>之間有什么區(qū)別?
List<? extends T> 向下限制 ? extends T : 代表接收的泛型類型為T類型或T子類類型
List<? super T> 向上限制 ? super T :代表接收的泛型類型為T類型或T父類類型
Java 容器都有哪些?
Java 容器分為 Collection 和 Map 兩大類,其下又有很多子類,如下所示:
Collection
List
ArrayList
LinkedList
Vector
Stack
Set
HashSet
LinkedHashSet
TreeSet
Map
HashMap
LinkedHashMap
TreeMap
ConcurrentHashMap
Hashtable
說一下 HashSet 的實(shí)現(xiàn)原理?
HashSet 是基于 HashMap 實(shí)現(xiàn)的,HashSet 底層使用 HashMap 來保存所有元素,因此 HashSet 的實(shí)現(xiàn)比較簡(jiǎn)單,相關(guān) HashSet 的操作,基本上都是直接調(diào)用底層 HashMap 的相關(guān)方法來完成,HashSet 不允許重復(fù)的值。
List、Set、Map 之間的區(qū)別是什么?
List、Set、Map 的區(qū)別主要體現(xiàn)在兩個(gè)方面:元素是否有序、是否允許元素重復(fù)。
三者之間的區(qū)別,如下表:

請(qǐng)簡(jiǎn)述Set集合的特點(diǎn)?
不能存儲(chǔ)重復(fù)元素;
元素是按照某種排序規(guī)則存儲(chǔ)的
說一下 HashMap 的實(shí)現(xiàn)原理?
HashMap 基于 Hash 算法實(shí)現(xiàn)的,我們通過 put(key,value)存儲(chǔ),get(key)來獲取。當(dāng)傳入 key 時(shí),HashMap 會(huì)根據(jù) key. hashCode() 計(jì)算出 hash 值,根據(jù) hash 值將 value 保存在 bucket 里。當(dāng)計(jì)算出的 hash 值相同時(shí),我們稱之為 hash 沖突,HashMap 的做法是用鏈表和紅黑樹存儲(chǔ)相同 hash 值的 value。當(dāng) hash 沖突的個(gè)數(shù)比較少時(shí),使用鏈表否則使用紅黑樹。
請(qǐng)簡(jiǎn)述HashSet是如何保證元素唯一性的?
HashSet集合中存儲(chǔ)的元素,通過重寫hashCode() 與 equals()方法來保證元素唯一性
請(qǐng)簡(jiǎn)述TreeSet是如何保證元素唯一性與排序的?
實(shí)現(xiàn)自然排序接口 Comparable,重寫 compareTo(T t)方法
實(shí)現(xiàn)比較器排序接口 Comparator,重寫 compare(T t1, T t2)方法
請(qǐng)說明Map接口和Collection接口的區(qū)別
Map接口是雙列集合頂層接口,每個(gè)位置存儲(chǔ)一對(duì)元素(key, value) Collection接口是單列集合頂層接口,每個(gè)位置存儲(chǔ)一個(gè)元素
請(qǐng)說出Map集合的遍歷方式
鍵找值
鍵值對(duì)對(duì)象,找鍵,找值
怎么確保一個(gè)集合不能被修改?
可以使用 Collections.unmodifiableCollection(Collection c) 方法來創(chuàng)建一個(gè)只讀集合,這樣改變集合的任何操作都會(huì)拋出 Java. lang. UnsupportedOperationException 異常。
示例代碼如下:
List<String> list = new ArrayList<>();
list. add("x");
Collection<String> clist = Collections.unmodifiableCollection(list);
clist.add("y"); // 運(yùn)行時(shí)此行報(bào)錯(cuò)
System.out.println(list.size());
如何實(shí)現(xiàn)數(shù)組和 List 之間的轉(zhuǎn)換?
數(shù)組轉(zhuǎn) List 使用 Arrays.asList(array) 進(jìn)行轉(zhuǎn)換。
List 轉(zhuǎn)數(shù)組 使用 List 自帶的 toArray() 方法。
代碼示例:
// list to array List<String> list = new ArrayList<String>(); list.add("這個(gè)"); list.add("小程序"); list.add("很贊"); list.toArray(); // array to list String[] array = new String[]{"這個(gè)","小程序","很贊"}; Arrays.asList(array);
如何決定使用 HashMap 還是 TreeMap?
對(duì)于在 Map 中插入、刪除、定位一個(gè)元素這類操作,HashMap 是最好的選擇,因?yàn)橄鄬?duì)而言 HashMap 的插入會(huì)更快,但如果你要對(duì)一個(gè) key 集合進(jìn)行有序的遍歷,那 TreeMap 是更好的選擇。
請(qǐng)說明HashMap和Hashtable的區(qū)別
HashMap
線程不同步
效率高
可以存儲(chǔ)null鍵null值
Hashtable
線程同步
數(shù)據(jù)安全
不可以存儲(chǔ)null鍵null值
請(qǐng)解釋Collection與Collections的區(qū)別
Collection 單列集合的頂層接口,包含集合中常用的方法。
Collections 集合工具類,包含獲取集合最大元素值、集合排序等方法。
數(shù)組有幾種創(chuàng)建的方式?分別是什么?
2種。動(dòng)態(tài)創(chuàng)建和靜態(tài)創(chuàng)建。
8. Java 異常
請(qǐng)說說什么是異常?異常的分類?
什么是異常? Java異常是java提供的用于
處理程序中錯(cuò)誤的一種機(jī)制
。 所謂錯(cuò)誤是指在程序運(yùn)行的過程中發(fā)生的一些異常事件(如:除0錯(cuò)誤,數(shù)組下標(biāo)越界,所要讀取的文件不存在)。設(shè)計(jì)良好地程序應(yīng)該在程序異常發(fā)生時(shí)提供處理這些錯(cuò)誤的方法,使得程序不會(huì)因?yàn)楫惓5陌l(fā)送而阻斷或產(chǎn)生不可預(yù)見的結(jié)果。Java程序的執(zhí)行過程中如出現(xiàn)異常事件,可以生成一個(gè)異常類對(duì)象,該異常對(duì)象封裝了異常事件的信息,并將被提交給java運(yùn)行時(shí)系統(tǒng),這個(gè)過程稱為拋出異常。
當(dāng)java運(yùn)行時(shí)系統(tǒng)接收到異常對(duì)象時(shí),會(huì)尋找能處理這一異常的代碼并把當(dāng)前異常對(duì)象交其處理,這一過程稱為捕獲異常。
異常的分類
Exception 所有異常類的父類,其子類對(duì)應(yīng)了各種各樣的可能出現(xiàn)的異常事件,一般需要用戶顯示的聲明或捕獲。
Error 稱為錯(cuò)誤,由java虛擬機(jī)生成并拋出,包括動(dòng)態(tài)鏈接失敗,虛擬機(jī)錯(cuò)誤等,程序?qū)ζ洳蛔鎏幚怼?/p>
Runtime Exception 一類特殊的異常,如被0除、數(shù)組下標(biāo)超范圍等,其產(chǎn)生比較頻繁,處理麻煩,如果顯示的聲明或捕獲將會(huì)對(duì)程序可讀性和運(yùn)行效率影響很大。因此由系統(tǒng)自動(dòng)檢測(cè)并將它們交給缺省的異常處理程序(用戶可不必對(duì)其處理)。
請(qǐng)說出異常處理的方式?
捕獲異常
try{
}catch(XxxException e){
}finally{
}拋出異常
throw \ throws()異常五個(gè)關(guān)鍵字
try try{…}語(yǔ)句制定了一段代碼,這段代碼就是一次捕獲并處理異常的范圍。在執(zhí)行過程中,這段代碼可能會(huì)產(chǎn)生并拋出一種或幾種類型的異常對(duì)象,它后面的catch語(yǔ)句要分別對(duì)這些異常做相應(yīng)的處理。如果沒有異常發(fā)生,所有的catch代碼段都被略過不執(zhí)行。
catch 在catch語(yǔ)句塊中是對(duì)異常進(jìn)行處理的代碼,每個(gè)try語(yǔ)句塊可以伴隨一個(gè)或多個(gè)catch語(yǔ)句,用于處理可能產(chǎn)生的不同類型的異常對(duì)象。在catch中聲明的異常對(duì)象(catch(XxxException e))封裝了異常事件發(fā)生的信息,在catch語(yǔ)句塊中可以使用這個(gè)對(duì)象的一些方法獲取這些信息。
finally finally語(yǔ)句為異常處理提供一個(gè)統(tǒng)一的出口,使得在控制流程轉(zhuǎn)到程序的其他部分以前,能夠?qū)Τ绦虻臓顟B(tài)做統(tǒng)一的管理。無論try所指定的程序塊中是否拋出異常,finally所指定的代碼都要執(zhí)行。通常在finally語(yǔ)句中可以進(jìn)行資源的清除工作。
throw throws關(guān)鍵字通常被應(yīng)用在聲明方法時(shí),用來指定可能拋出的異常。多個(gè)異??梢允褂枚禾?hào)隔開。當(dāng)在主函數(shù)中調(diào)用該方法時(shí),如果發(fā)生異常,就會(huì)將異常拋給指定異常對(duì)象。
throws throw關(guān)鍵字通常用在方法體中,并且拋出一個(gè)異常對(duì)象。程序在執(zhí)行到throw語(yǔ)句時(shí)立即停止,它后面的語(yǔ)句都不執(zhí)行。通常throw拋出異常后,如果想在上一級(jí)代碼中捕獲并處理異常,則需要在拋出異常的方法中使用throws關(guān)鍵字在方法聲明中指定要拋出的異常;如果要捕獲throw拋出的異常,則必須使用try{}catch{}語(yǔ)句。
請(qǐng)說說編譯期異常和運(yùn)行期異常的區(qū)別?
編譯時(shí)異常 程序正確,但因?yàn)橥庠诘沫h(huán)境條件不滿足引發(fā)。對(duì)商用軟件系統(tǒng),程序開發(fā)者必須考慮并處理這類異常。Java編譯器強(qiáng)制要求處理這類異常,如果不捕獲這類異常,程序?qū)⒉荒鼙痪幾g。
運(yùn)行期異常 這意味著程序存在bug,如數(shù)組越界,0被除,傳入?yún)?shù)不滿足規(guī)則等,這類異常需要更改程序來避免,java編譯器強(qiáng)制要求處理這類異常。
錯(cuò)誤 一般很少見,也很難通過程序解決。它可能源于程序的bug,但一般更可能源于環(huán)境問題,如內(nèi)存耗盡。錯(cuò)誤在程序中無須處理,而由運(yùn)行環(huán)境處理。
請(qǐng)說說throws與throw的區(qū)別?
throws 通常被應(yīng)用在聲明方法時(shí),用來指定可能拋出的異常。多個(gè)異常可以使用逗號(hào)隔開。當(dāng)在主函數(shù)中調(diào)用該方法時(shí),如果發(fā)生異常,就會(huì)將異常拋給指定異常對(duì)象。
throw 通常用在方法體中,并且拋出一個(gè)異常對(duì)象。程序在執(zhí)行到throw語(yǔ)句時(shí)立即停止,它后面的語(yǔ)句都不執(zhí)行。通常throw拋出異常后,如果想在上一級(jí)代碼中捕獲并處理異常,則需要在拋出異常的方法中使用throws關(guān)鍵字在方法聲明中指定要拋出的異常;如果要捕獲throw拋出的異常,則必須使用try{}catch{}語(yǔ)句。
請(qǐng)說說final、finally與finalize的區(qū)別?
final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。內(nèi)部類要訪問局部變量,局部變量必須定義成final類型。
finally 是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。
finalize 是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提高垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM不保證此方法總被調(diào)用。
請(qǐng)說說異常的注意事項(xiàng)及如何使用異常處理?
子類重寫父類方法時(shí),子類的方法必須拋出相同的異?;蚋割惍惓5淖宇?。
如果父類拋出了多個(gè)異常,子類重寫父類時(shí),只能拋出相同的異?;蛘呤撬淖蛹?,子類不能拋出父類沒有的異常。
如果被重寫的方法沒有異常拋出,那么子類的方法絕對(duì)不可以拋出異常,如果子類方法內(nèi)有異常發(fā)生,那么子類只能try…catch,不能throws
請(qǐng)說出最常見到的RuntimeException異常
NullPointerException 空指針引用異常
ClassCastException 類型強(qiáng)制轉(zhuǎn)換異常
IllegalArgumentException 傳遞非法參數(shù)異常
ArithmeticException 算術(shù)運(yùn)算異常
ArrayStoreException 向數(shù)組中存放與聲明類型不兼容對(duì)象異常
IndexOutOfBoundsException 下標(biāo)越界異常
NumberFormatException 數(shù)字格式異常
請(qǐng)簡(jiǎn)述IO流的分類
字節(jié)流
字節(jié)輸入流 InputStream
字節(jié)輸出流 OutputStream
字符流
字符輸入流 Reader
字符輸出流 Writer
9. Java IO
請(qǐng)簡(jiǎn)述字符編碼是什么?請(qǐng)說出常見字符編碼表?
字符編碼是什么? 字符編碼(英語(yǔ):Character encoding)也稱字集碼,是把字符集中的字符編碼為指定集合中某一對(duì)象,以便文本在計(jì)算機(jī)中存儲(chǔ)和通過通信網(wǎng)絡(luò)的傳遞。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII。其中,ASCII將字母、數(shù)字和其他符號(hào)編號(hào),并用7比特的二進(jìn)制來表示這個(gè)整數(shù)。通常會(huì)額外使用一個(gè)擴(kuò)充的比特,以便以1個(gè)字節(jié)的方式存儲(chǔ)。
常見的字符編碼表如下
ASCII
GB2312 是一個(gè)簡(jiǎn)體中文字符集,由6763個(gè)常用漢字和682個(gè)全角的非漢字字符組成。
GBK GBK編碼標(biāo)準(zhǔn)兼容GB2312,共收錄漢字21003個(gè)、符號(hào)883個(gè),并提供1894個(gè)造字碼位,簡(jiǎn)、繁體字融于一庫(kù)
GB18030 是在GBK基礎(chǔ)上增加了一部分漢字 Big5:在臺(tái)灣、香港與澳門地區(qū),使用的是繁體中文字符集
Unicode 將世界上所有的符號(hào)都納入其中,無論是英文、日文、還是中文等,大家都使用這個(gè)編碼表,這樣就利于同一的管理,在這個(gè)編碼表中每一個(gè)字符占兩個(gè)字節(jié)
UTF-8 為了提高Unicode的編碼效率,于是就出現(xiàn)了UTF-8編碼。UTF-8可以根據(jù)不同的符號(hào)自動(dòng)選擇編碼的長(zhǎng)短。比如英文字母可以只用1個(gè)字節(jié)就夠了。
請(qǐng)說出學(xué)習(xí)過的IO流中的常用方法?
字節(jié)輸入流 InputStream
read() 讀取一個(gè)字節(jié)
read(byte[]) 讀取一個(gè)字節(jié)數(shù)組
字節(jié)輸出流
write(int) 寫入一個(gè)字節(jié)
write(byte[]) 寫入一個(gè)字節(jié)數(shù)組
字符輸入流
read() 讀取一個(gè)字符
read(char[]) 讀取一個(gè)字符數(shù)組
字符緩沖輸入流
readLine() 讀取一行字符串
字符輸出流
write(int) 寫入一個(gè)字符
write(char[]) 寫入一個(gè)字符數(shù)組
write(String) 寫入一個(gè)字符串
字符緩沖輸出流
newLine() 寫入一個(gè)換行符
請(qǐng)說出轉(zhuǎn)換流OutputStreamWriter與InputStreamReader 的作用?
OutputStreamWriter 使用編碼表對(duì)字節(jié)流的數(shù)據(jù)進(jìn)行編碼
InputStreamReader 使用編碼表對(duì)字節(jié)流中的數(shù)據(jù)進(jìn)行解碼
Files的常用方法都有哪些?
Files.exists():檢測(cè)文件路徑是否存在。
Files.createFile():創(chuàng)建文件。
Files.createDirectory():創(chuàng)建文件夾。
Files.delete():刪除一個(gè)文件或目錄。
Files.copy():復(fù)制文件。
Files.move():移動(dòng)文件。
Files.size():查看文件個(gè)數(shù)。
Files.read():讀取文件。
Files.write():寫入文件。
BIO、NIO、AIO 有什么區(qū)別?
BIO Block IO 同步阻塞式 IO,就是我們平常使用的傳統(tǒng) IO,它的特點(diǎn)是模式簡(jiǎn)單使用方便,并發(fā)處理能力低。
NIO New IO 同步非阻塞 IO,是傳統(tǒng) IO 的升級(jí),客戶端和服務(wù)器端通過 Channel(通道)通訊,實(shí)現(xiàn)了多路復(fù)用。
AIO Asynchronous IO 是 NIO 的升級(jí),也叫 NIO2,實(shí)現(xiàn)了異步非堵塞 IO ,異步 IO 的操作基于事件和回調(diào)機(jī)制。
請(qǐng)簡(jiǎn)述打印流(PrintStream、PrintWriter)的特點(diǎn)?
PrintStream的特點(diǎn) 在OutputStream基礎(chǔ)之上提供了增強(qiáng)的功能,即可以方便地輸出各種類型的數(shù)據(jù)(而不僅限于byte類型)的格式化表示形式。PrintStream的方法從不拋出IOException
PrintWriter的特點(diǎn) 提供了PrintStream的所有打印方法,其方法也從不拋出IOException。
區(qū)別 作為處理流使用時(shí),PrintStream只能封裝OutputStream類型的字節(jié)流,而PrintWriter既可以封裝OutputStream類型的字節(jié)流,還能夠封裝Writer類型的字符輸出流并增強(qiáng)其功能。
微信掃碼關(guān)注公眾號(hào),回復(fù)【資料

