Java基礎(chǔ)面試題突擊1
|
文章導(dǎo)讀目錄
|
JDK
:java development kit (java開發(fā)工具),JDK 是用于開發(fā) Java 程序的最小環(huán)境。
JRE
:java runtime environment (java運(yùn)行時(shí)環(huán)境),是提供給 Java 程序運(yùn)行的最小環(huán)境。
JRE是java運(yùn)行時(shí)環(huán)境而JDK是java開發(fā)工具包。運(yùn)行java程序只需安裝JRE。如果需要編寫java程序,需要安裝JDK。但是JRE可以獨(dú)立安裝。
JDK包含JRE,同時(shí)還包含了編譯 Java 源碼的編譯器 Javac,還包含了很多 Java 程序調(diào)試和分析的工具。
JRE包含了java虛擬機(jī)、java基礎(chǔ)類庫。是使用java語言編寫的程序運(yùn)行所需要的軟件環(huán)境,是提供給想運(yùn)行java程序的用戶使用的。

二、Java為什么能跨平臺(tái)?Tip:mac怎么查看jdk目錄呢?
終端輸入:/usr/libexec/java_home -V會(huì)顯示jdk版本和所在目錄
command + shift +G前往要去的路徑
Java是跨平臺(tái)的原因是因?yàn)镴ava代碼是運(yùn)行在JVM上的,而不是直接運(yùn)行在操作系統(tǒng)上。
這意味著,Java程序的代碼不會(huì)直接與操作系統(tǒng)交互,而是通過JVM來間接交互。java是半編譯語言,java源程序在經(jīng)過java編譯器編譯后成為java字節(jié)碼文件,再由運(yùn)行在不同平臺(tái)上的虛擬機(jī)(例如:windows、Linnux)將相同的字節(jié)碼解釋運(yùn)行,轉(zhuǎn)換成具體平臺(tái)上的機(jī)器指令。從而實(shí)現(xiàn)了一次編寫,到處運(yùn)行。

1、Java中數(shù)據(jù)類型

2、八大基本數(shù)據(jù)類型
-
整型的byte、short、int、long;
-
字符型的char;
-
浮點(diǎn)型的float、double;
-
布爾型的boolean。
將6種數(shù)據(jù)類型按取值范圍的大小順序排列一下:
double > float >
long > int > short > byte
1)數(shù)據(jù)類型轉(zhuǎn)換
取值范圍從小轉(zhuǎn)換到大,是可以直接轉(zhuǎn)換的,
在自動(dòng)類型轉(zhuǎn)化中、int–> float、long–> float、long–> double、float --> double
可能精度損失外,自動(dòng)轉(zhuǎn)換不會(huì)出現(xiàn)任何運(yùn)行時(shí)異常。而從大轉(zhuǎn)成小,則必須使用強(qiáng)制轉(zhuǎn)換。
2)類型提升
在表達(dá)式計(jì)算過程中會(huì)發(fā)生類型轉(zhuǎn)換,這些類型轉(zhuǎn)換就是類型提升,類型提升規(guī)則如下:
所有 byte/short/char 的表達(dá)式都會(huì)被提升為 int
除以上類型,其他類型在表達(dá)式中,都會(huì)被提升為取值范圍大的那個(gè)類型,例如有一個(gè)操作數(shù)為double,整個(gè)表達(dá)式都會(huì)被提升為double
3)基本數(shù)據(jù)內(nèi)存中分配
基本數(shù)據(jù)類型它存放于“棧”中而不是存放于“堆”中。
4)值的初始化
當(dāng)基本數(shù)據(jù)類型作為類成員變量時(shí),java 會(huì)對(duì)其進(jìn)行初始化。且初始化的值分別為

而局部變量 在沒有被顯示初始化情況下,jdk 同樣也會(huì)自動(dòng)賦予他默認(rèn)值,可不同之處就在于,你無法引用他,因?yàn)榫幾g器會(huì)在你要引用的位置報(bào)錯(cuò)。

1、異常分類
異常:執(zhí)行中發(fā)生的不正常情況。
Throwable 是 Java 語言中所有錯(cuò)誤或異常的超類。下一層分為?
Error
?和?
Exception
Error:JVM系統(tǒng)內(nèi)部錯(cuò)誤、資源耗盡等嚴(yán)重情況。比如Stack OverflowError和 Out Of Memory。
Exception:空指針訪問、試圖讀取不存在的文件、網(wǎng)絡(luò)連接中斷、數(shù)組下標(biāo)越界等。
程序執(zhí)行過程,是先編譯后執(zhí)行。所以從程序執(zhí)行的過程可以將異常進(jìn)一步分為:
編譯時(shí)異常:執(zhí)行javac.exe命名時(shí),可能出現(xiàn)的異常
運(yùn)行時(shí)異常:執(zhí)行java.exe命名時(shí),出現(xiàn)的異常

2、異常的處理方式
1)遇到問題不進(jìn)行具體處理,而是繼續(xù)拋給調(diào)用者 (throw,throws)
拋出異常有三種形式,一是 throw,一個(gè) throws,還有一種系統(tǒng)自動(dòng)拋異常。
public static void main(String[] args) {
String s = "abc";
if(s.equals("abc")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
}
int div(int a,int b) throws Exception{
return a/b;}
2)try catch 捕獲異常針對(duì)性處理方式
3、Throw 和 throws 的區(qū)別
1)位置不同
throws 用在函數(shù)上,后面跟的是異常類,可以跟多個(gè);而 throw 用在函數(shù)內(nèi),后面跟的 是異常對(duì)象。
2)功能不同
throws 用來聲明異常,讓調(diào)用者只知道該功能可能出現(xiàn)的問題,可以給出預(yù)先的處理方式;throw 拋出具體的問題對(duì)象,執(zhí)行到 throw,功能就已經(jīng)結(jié)束了,跳轉(zhuǎn)到調(diào)用者,并將具體的問題對(duì)象拋給調(diào)用者。也就是說 throw 語句獨(dú)立存在時(shí),下面不要定義其他語句,因?yàn)閳?zhí)行不到。
throws 表示出現(xiàn)異常的一種可能性,并不一定會(huì)發(fā)生這些異常;throw 則是拋出了異常,執(zhí)行 throw 則一定拋出了某種異常對(duì)象。
兩者都是消極處理異常的方式,只是拋出或者可能拋出異常,但是不會(huì)由函數(shù)去處理異常,真正的處理異常由函數(shù)的上層調(diào)用處理。
五、== 和 equals 的區(qū)別是什么?
== 對(duì)于基本類型:比較的是值是否相同;
對(duì)于引用類型:比較的是引用是否相同;
關(guān)聯(lián)知識(shí)點(diǎn):
1、String的比較
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
原因:String 、Integer 等重寫了 Object 的 equals 方法,把引用比較改成了值比較。所以一般情況下 equals 比較的是值是否相等。
2、Integer的比較
Integer a1 = 1;
Integer a2 = 1;
Integer b1 = 128;
Integer b2 = 128;
System.out.println(al== a2); //true
System.out.println(b1== b2); //false
原因:Integer類內(nèi)部通過靜態(tài)內(nèi)部類提供了一個(gè)緩存池,范圍在-128~127之間,如果超過這個(gè)范圍 Integer值都是new出來的新對(duì)象。
Integer的valueOf方法的具體實(shí)現(xiàn):
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
其中IntegerCache類的實(shí)現(xiàn)為:
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
從這2段代碼可以看出,在通過valueOf方法創(chuàng)建Integer對(duì)象的時(shí)候,如果數(shù)值在[-128,127]之間,
便返回指向IntegerCache.cache中已經(jīng)存在的對(duì)象的引用;否則創(chuàng)建一個(gè)新的Integer對(duì)象。
3、兩個(gè)對(duì)象的 hashCode() 相同,則 equals() 也一定為 true,對(duì)嗎?
不對(duì)。我們兩個(gè)字符串的哈希值很可能一樣,但是反過來不一定成立。
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
六、創(chuàng)建對(duì)象的幾種方法
1、new關(guān)鍵字
使用new關(guān)鍵字創(chuàng)建對(duì)象,是最常見也是最簡(jiǎn)單的創(chuàng)建對(duì)象的方式。
2、Class 對(duì)象的 newInstance()
使用Class對(duì)象的newInstance()方法來創(chuàng)建該 Class 對(duì)象對(duì)應(yīng)類的實(shí)例,但是這種方法要求該Class對(duì)象對(duì)應(yīng)的類有默認(rèn)的空構(gòu)造器。
3、調(diào)用 Constructor 對(duì)象的 newInstance()
先使用 Class 對(duì)象獲取指定的 Constructor 對(duì)象,再調(diào)用 Constructor 對(duì)象的newInstance()方法來創(chuàng)建 Class 對(duì)象對(duì)應(yīng)類的實(shí)例,通過這種方法可以選定構(gòu)造方法創(chuàng)建實(shí)例。
//獲取 Person 類的 Class 對(duì)象
Class clazz=Class.forName("reflection.Person");
//使用.newInstane 方法創(chuàng)建對(duì)象
Person p=(Person) clazz.newInstance();
//獲取構(gòu)造方法并創(chuàng)建對(duì)象
Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class);
//創(chuàng)建對(duì)象并設(shè)置屬性
Person p1=(Person) c.newInstance("測(cè)試","男",10);
4、Clone
無論何時(shí)我們調(diào)用一個(gè)對(duì)象的clone方法,JVM就會(huì)創(chuàng)建一個(gè)新的對(duì)象,將前面的對(duì)象的內(nèi)容全部拷貝進(jìn)去,用clone方法創(chuàng)建對(duì)象并不會(huì)調(diào)用任何構(gòu)造函數(shù)。
5、反序列化
當(dāng)我們序列化和反序列化一個(gè)對(duì)象,JVM會(huì)給我們創(chuàng)建一個(gè)單獨(dú)的對(duì)象。在反序列化時(shí),JVM創(chuàng)建對(duì)象并不會(huì)調(diào)用任何構(gòu)造函數(shù)。
七、重載和重寫1、重寫(Override)
從字面上看,重寫就是重新寫一遍的意思。其實(shí)就是在子類中把父類本身有的方法重新寫一遍。子類繼承了父類原有的方法,但有時(shí)子類并不想原封不動(dòng)的繼承父類中的某個(gè)方法,所以在方法名, 參數(shù)列表,返回類型(除過子類中方法的返回值是父類中方法返回值的子類時(shí))都相同的情況下, 對(duì)方法體進(jìn)行修改或重寫,這就是重寫。但要注意子類函數(shù)的訪問修飾權(quán)限不能少于父類的。
public class Father {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.sayHello();
}
public void sayHello() {
System.out.println("Hello");
}
}
class Son extends Father{
@Override
public void sayHello() {
// TODO Auto-generated method stub
System.out.println("hello by ");
}
}
重寫總結(jié):
1.發(fā)生在父類與子類之間
2.方法名,參數(shù)列表,返回類型(除過子類中方法的返回類型是父類中返回類型的子類)必須相同
3.訪問修飾符的限制一定要大于被重寫方法的訪問修飾符(public>protected>default>private)
4.重寫方法一定不能拋出新的檢查異常或者比被重寫方法明更加寬泛的檢查型異常
2、重載(Overload)
在一個(gè)類中,同名的方法如果有不同的參數(shù)列表(參數(shù)類型不同、參數(shù)個(gè)數(shù)不同甚至是參數(shù)順序不同)則視為重載。同時(shí),重載對(duì)返回類型沒有要求,可以相同也可以不同,但不能通過返回類型是否相同來判斷重載。
public class Father {
public static void main(String[] args) {
// TODO Auto-generated method stub
Father s = new Father();
s.sayHello();
s.sayHello("wintershii");
}
public void sayHello() {
System.out.println("Hello");
}
public void sayHello(String name) {
System.out.println("Hello" + " " + name);
}
}
八、權(quán)限修飾符重載總結(jié):
1.重載Overload是一個(gè)類中多態(tài)性的一種表現(xiàn)
2.重載要求同名方法的參數(shù)列表不同(參數(shù)類型,參數(shù)個(gè)數(shù)甚至是參數(shù)順序)
3.重載的時(shí)候,返回值類型可以相同也可以不相同。無法以返回型別作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)
Java規(guī)定的4種權(quán)限 (從小到大排列) : private、缺省(default)、protected、 public
Java權(quán)限修飾符public、protected、default、private置于類的成員定義前,用來限定對(duì)象對(duì)該類成員的訪問權(quán)限。

對(duì)于class的權(quán)限修飾只可以用public和default(缺省)。
public類可以在任意地方被訪問。
default類只可以被同一個(gè)包內(nèi)部的類訪問。
4種權(quán)限可以用來修飾類及類的內(nèi)部結(jié)構(gòu): 屬性、方法、構(gòu)造器、內(nèi)部類
具體的,4種權(quán)限都可以用來修飾類的內(nèi)部結(jié)構(gòu),屬性、方法、構(gòu)造器、內(nèi)部類修飾類的話,只能使用default、 public。
九、String、String StringBuffffer 和 StringBuilder 的區(qū)別是什么?總結(jié)封裝性:Java提供了4種權(quán)限修飾符來修飾類及類的內(nèi)部結(jié)構(gòu),體現(xiàn)類及類的內(nèi)部結(jié)構(gòu)在被調(diào)用時(shí)的可見性
String和StringBuffer和StringBuilder的區(qū)別 因?yàn)镾tring是不可變的,StringBuffer 和 StringBuilder 它們都是可變的字符串。
String是只讀字符串,它并不是基本數(shù)據(jù)類型,而是一個(gè)對(duì)象。從底層源碼來看是一個(gè)fifinal類型的字符數(shù)組,所引用的字符串不能被改變,一經(jīng)定義,無法再增刪改。每次對(duì)String的操作都會(huì)生新的String對(duì)象。
private final char value[];
StringBuffffer和StringBuilder他們兩都繼承了AbstractStringBuilder抽象類,他們的底層都是可變的字符數(shù)組
/**
* The value is used for character storage.
*/
char[] value;
所以在進(jìn)行頻繁的字符串操作時(shí),建議使用StringBuffffer和StringBuilder來進(jìn)行操作。
StringBuffffer 對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是
線程安全
;
StringBuilder 并沒有對(duì)方法進(jìn)行加同步鎖,所以是
非線程安全
的。
1、Collection接口
Collection是集合類的上級(jí)接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、 Set;

2、Collections集合類
Collections是集合類的一個(gè)幫助類, 它包含有各種有關(guān)集合操作的靜態(tài)多態(tài)方法,用于實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。此類不能實(shí)例化(因?yàn)镃ollections的構(gòu)造方法被私有化處理了),就像一個(gè)工具類,服務(wù)于Java的Collection框架, Collections類中的方法都是被static修飾了,可以直接用類名調(diào)用。
Collections類常用方法:
-
public static void shuffle(List)。混亂排序
-
public static boolean addAll(Collection c, T… elements)。添加一些元素
-
public static void sort(List list,Comparator<? super T> )。排序,將集合中元素按照指定規(guī)則排序
-
public static <T extends Comparable<? super T>> void sort(List list)。排序,將集合中元素按照默認(rèn)規(guī)則排序
-
public static int binarySearch(List list, Object key)。查找,使用二分搜索法搜索指定的 List 集合,以獲得指定對(duì)象在 List 集合中的索引。如果要使該方法可以正常工作,則必須保證 List 中的元素已經(jīng)處于有序狀態(tài)。
-
public static void copy(List <? super T> dest,List<? extends T> src) 復(fù)制, 用于將指定集合中的所有元素復(fù)制到另一個(gè)集合中。
-
public static void replaceAll()。替換,替換集合中所有的舊元素為新元素。



