您好,歡迎來到賦能網(wǎng)!

Java核心技術(shù)面試整理

賦能網(wǎng) 2023-06-11 249

1、.java源文件:

一個以”.java“為后綴的源文件:只能有一個與文件名相同的類,可以包含其他類。

2、類方法:

3、super和this關(guān)鍵字

在子類構(gòu)造器中使用super()顯示調(diào)用父類的構(gòu)造方法,super()必須寫在子類構(gòu)造方法的第一行,否則編譯不通過;

this:

屬性:this屬性表示找到本類的屬性,如果本類沒有找到則繼續(xù)查找父類;

方法:this方法表示找到本類的方法,如果本類沒有找到則繼續(xù)查找父類;

構(gòu)造:必須放在構(gòu)造方法的首行,不能與super關(guān)鍵字同時出現(xiàn);

特殊:表示當(dāng)前對象;

super:

屬性:super屬性直接在子類之中查找父類中的指定屬性,不再查找子類本身屬性;

方法:super方法直接在子類之中查找父類中的指定方法,不再查找子類本身方法;

構(gòu)造:必須放在構(gòu)造方法首行,不能與this關(guān)鍵字同時出現(xiàn)。

super和this關(guān)鍵字
1)調(diào)用super()必須寫在子類構(gòu)造方法的第一行,否則編譯不通過。每個子類構(gòu)造方法的第一條語句,都是隱含地調(diào)用super(),如果父類沒有這種形式的構(gòu)造函數(shù),那么在編譯的時候就會報錯。

2)super從子類中調(diào)用父類的構(gòu)造方法,this()在同一類內(nèi)調(diào)用其它方法。

3)super()和this()均需放在構(gòu)造方法內(nèi)第一行。

4)盡管可以用this調(diào)用一個構(gòu)造器,但卻不能調(diào)用兩個。

5)this和super不能同時出現(xiàn)在一個構(gòu)造函數(shù)里面,因為this必然會調(diào)用其它的構(gòu)造函數(shù),其它的構(gòu)造函數(shù)必然也會有super語句的存在,所以在同一個構(gòu)造函數(shù)里面有相同的語句,就失去了語句的意義,編譯器也不會通過。

6)this()和super()都指的是對象,所以,均不可以在static環(huán)境中使用。包括:static變量,static方法,static語句塊。

7)從本質(zhì)上講,this是一個指向本對象的指針, 然而super是一個Java關(guān)鍵字。

4、抽象類

1、抽象類不能被實例化,實例化的工作應(yīng)該交由它的子類來完成,它只需要有一個引用即可。

2、抽象方法必須由子類來進(jìn)行重寫。

3、只要包含一個抽象方法的類,該類必須要定義成抽象類,不管是否還包含有其他方法。

4、抽象類中可以包含具體的方法,當(dāng)然也可以不包含抽象方法。

5、子類中的抽象方法不能與父類的抽象方法同名。

6、abstract不能與final并列修飾同一個類。(abstract需要子類去實現(xiàn),而final表示不能被繼承,矛盾。)

7、abstract 不能與private、static、final或native并列修飾同一個方法。

A、final修飾的類為終態(tài)類,不能被繼承,而抽象類是必須被繼承的才有其意義的,因此,final是不能用來修飾抽象類的。

B、 final修飾的方法為終態(tài)方法,不能被重寫。而繼承抽象類,必須重寫其方法。

C、抽象方法是僅聲明,并不做實現(xiàn)的方法。

5、訪問權(quán)限:

(1)訪問權(quán)限修飾詞:

1)public(公共的):表明該成員變量或方法對所有類或?qū)ο蠖际强梢姷?,所有類或?qū)ο蠖伎梢灾苯釉L問;

2)protected(受保護的):表明成員變量或方法對該類本身&與它在同一個包中的其它類&在其它包中的該類的子類都可見;

3)default(默認(rèn)的,不加任何訪問修飾符):表明成員變量或方法只有自己&其位于同一個包內(nèi)的類可見;

4)private(私有的):表明該成員變量或方法是私有的,只有當(dāng)前類對其具有訪問權(quán)限。

由大到?。簆ublic(接口訪問權(quán)限)、protected(繼承訪問權(quán)限)、包訪問權(quán)限(沒有使用任何訪問權(quán)限修飾詞)、private(私有無法訪問)

protected表示就類用戶而言,這是private的,但對于任何繼承于此類的導(dǎo)出類或其他任何位于同一個包內(nèi)的類來說,卻是可以訪問的。(protected也提供了包內(nèi)訪問權(quán)限)

private和protected一般不用來修飾外部類,而public、abstract或final可以用來修飾外部類(如果用private和protected修飾外部類,會使得該類變得訪問性受限)。

(2)訪問權(quán)限注意點:

1、類的訪問權(quán)限,只能是包訪問權(quán)限(默認(rèn)無訪問修飾符即可)或者public。若把一個類中的構(gòu)造器指定為private,則不能訪問該類,若要創(chuàng)建該類的對象,則需要再該類的static成員內(nèi)部創(chuàng)建,如單例模式。

2、如果沒能為類訪問權(quán)限指定一個訪問修飾符,默認(rèn)得到包訪問權(quán)限,則該類的對象可以由包內(nèi)任何其他類創(chuàng)建,但是包外不可以。

3、訪問權(quán)限的控制,也稱為具體實現(xiàn)的隱藏。制定規(guī)則(如使用訪問權(quán)限,設(shè)定成員所遵守的界限),是防止客戶端程序員對類隨心所欲而為。

(3)控制對成員的訪問權(quán)限的兩個原因:

·       使用戶不要碰觸那些不該碰觸的部分,對類內(nèi)部的操作是必要的,不屬于客戶端程序員所需接口的一部分;

·       讓類庫設(shè)計者可以更改類的內(nèi)部工作方式,而不會對客戶端程序員產(chǎn)生重大影響;訪問權(quán)限控制可以確保不會有任何客戶端程序員依賴于類的底層實現(xiàn)的任何部分。

(4)對某成員的訪問權(quán)的唯一途徑:

·       1.該成員為public;

·       2.通過不加訪問權(quán)限修飾詞并將其他類放置在同一個包內(nèi)的方式給成員賦予包訪問權(quán)。

·       3.繼承技術(shù),訪問protected成員

·       4.提供訪問器和變異器(get/set方法),以讀取和改變數(shù)值。

6、值傳遞與引用傳遞

值傳遞:Java中原始數(shù)據(jù)類型都是值傳遞,傳遞的是值的副本,形參的改變不會影響實際參數(shù)的值;

引用傳遞: 傳遞的是引用類型數(shù)據(jù),包括String,數(shù)組,列表,map,類對象等類型,形參與實參指向的是同一內(nèi)存地址,因此形參改變會影響實參的值。

7、封裝:

把數(shù)據(jù)和方法包裝進(jìn)類中,以及實現(xiàn)的隱藏,共同稱作封裝。結(jié)果是一個同時帶有特征和行為的數(shù)據(jù)類型。

8、組合、繼承:

(1)組合:

定義:只需在新的類中產(chǎn)生現(xiàn)有類的對象,由于新的類是由現(xiàn)有類的對象所組成, 稱為組合。組合技術(shù)知識將對象引用置于新類中即可。

缺點:將一個成員對象置于所要構(gòu)造的類中(組合),在新類中暴露這個成員對象的所有方法(繼承),需要折中(代理),可以選擇只提供在成員對象中的方法的某個子集。

特點:

·       1.has-a關(guān)系用組合;

·       2.組合技術(shù)通常用于想在新類中使用現(xiàn)有類的功能而非它的接口這種情形。在新類中嵌入某個對象,讓其實現(xiàn)所需要的功能,但新類的用戶看到的只是為新類所定義的接口,而非所嵌入對象的接口。

(2)繼承:

定義:按照現(xiàn)有類的類型來創(chuàng)建新類 ,無需改變現(xiàn)有類的形式,采用現(xiàn)有類的形式并在其增加新代碼,稱為繼承。通過關(guān)鍵字extends實現(xiàn)。

特點:

·       1.當(dāng)創(chuàng)建一個類時,總在繼承。(除非明確指明繼承類,否則都是隱式第繼承根類Object)

·       2.為了繼承,一般將所有的數(shù)據(jù)成員都指定為private,將所有的方法指定為public。

·       3.可以將繼承視作是對類的復(fù)用;

·       4.is-a關(guān)系用繼承;

·       5.繼承允許對象視為自身的類型或其基類型加以處理;

·       6.如果向上轉(zhuǎn)型,不能調(diào)用那些新的方法(如Animal an = new Cat(),an是不能調(diào)用Cat中有的而Animal中沒有的方法,會返回一條編譯時出錯消息),所以向上轉(zhuǎn)型會丟失具體的類型信息;

注意:

1.構(gòu)造方法不能被繼承;方法和屬性可以被繼承;

2.子類的構(gòu)造方法隱式地調(diào)用父類的不帶參數(shù)的構(gòu)造方法;

3.當(dāng)父類沒有不帶參數(shù)的構(gòu)造方法時,子類需要使用super來顯示調(diào)用父類的構(gòu)造方法,super指的是對父類的引用

4.super關(guān)鍵字必須是構(gòu)造方法中的第一行語句。特例如下

當(dāng)兩個方法形成重寫關(guān)系時,可在子類方法中通過super.run()形式調(diào)用父類的run()方法,其中super.run()不必放在第一行語句,因此此時父類對象已經(jīng)構(gòu)造完畢,先調(diào)用父類的run()方法還是先調(diào)用子類的run()方法是根據(jù)程序的邏輯決定的。

總結(jié):

代理使用時,可以擁有更多的控制力,可以選擇只提供在成員對象中的方法的某個子集;

組合和繼承都允許在新的類中放置子對象,組合是顯式地放置,繼承是隱式的做;

組合和繼承都能從現(xiàn)有類型中生成新類,組合一般是將現(xiàn)有類型作為新類型底層實現(xiàn)的一部分加以復(fù)用,而繼承復(fù)用的是接口。優(yōu)先使用組合。

9、final關(guān)鍵字

1)使用范圍:數(shù)據(jù)、方法和類

2)final關(guān)鍵字:final可以修飾屬性、方法、類。

3)final修飾類:當(dāng)一個類被final所修飾時,表示該類是一個終態(tài)類,即不能被繼承。

4)final修飾方法:當(dāng)一個方法被final所修飾時,表示該方法是一個終態(tài)方法,即不能被重寫(Override)。

5)final修飾屬性:當(dāng)一個屬性被final所修飾時,表示該屬性不能被改寫。

(1)final數(shù)據(jù):

Java核心技術(shù)面試整理

·       1.編譯時常量:是使用static和 final修飾的常量,全用大寫字母命名,且字與字之間用下劃線隔開。(不能因為數(shù)據(jù)是final的就認(rèn)為在編譯時就知道值,在運行時也可以用某數(shù)值來初始化某一常量)

·       2.final修飾基本數(shù)據(jù)類型和對象引用:對于基本類型,final修飾的數(shù)值是恒定不變;而final修飾對象引用,則引用恒定不變(一旦引用被初始化指向一個對象,就不能改為指向另一個對象),但是對象本身的內(nèi)容可以修改。

·       3.空白final:空白final是指被聲明為final但又未給定初值的域,無論什么情況,編譯器都保證空白final在使用被初始化。必須在域的定義處或每個構(gòu)造器中用表達(dá)式對final進(jìn)行賦值。

·       4.final參數(shù):final修飾參數(shù)后,在方法體中不允許對參數(shù)進(jìn)行更改,只可以讀final參數(shù)。主要用于向匿名類傳遞數(shù)據(jù)。

(2)final方法:

·       1.使用final修飾方法原因:將方法鎖定以及效率問題。將方法鎖定:防止任何繼承類修改final方法的含義,確保該方法行為保持不變,且不會被覆蓋;效率:早期Java實現(xiàn)中同意編譯器將針對該方法的所有調(diào)用轉(zhuǎn)為內(nèi)嵌調(diào)用。

·       2.類中所有的private方法都隱式地指定為final的。

(3)final類:

·       1.將某個類整體定義為final時,則不繼承該類,不能有子類。

10、初始化及類的加載

1.加載的含義:通常,加載發(fā)生在創(chuàng)建類的第一個對象時,但訪問static域或static方法時,也會發(fā)生加載。static的東西只會初始化一次。

2.加載過程:加載一個類的時候,首先去加載父類的靜態(tài)域,然后再加載自身的靜態(tài)域,之后去初始化父類的成員變量,后加載父類的構(gòu)造方法,最后初始化自身的成員變量,后加載自身的構(gòu)造方法。(先初始化成員變量,后加載構(gòu)造函數(shù)的原因是,構(gòu)造函數(shù)中可能要用到這些成員變量)

父類靜態(tài)塊——子類靜態(tài)塊——父類塊——父類構(gòu)造器——子類塊——子類構(gòu)造器

最終版本:父類靜態(tài)域——父類靜態(tài)塊——子類靜態(tài)域——子類靜態(tài)塊——父類成員變量及代碼塊——父類構(gòu)造器——子類成員變量及代碼塊——子類構(gòu)造器。

3.加載次數(shù):加載的動作只會加載一次,該類的靜態(tài)域或第一個實體的創(chuàng)建都會引起加載。

4.變量的初始化:變量的初始化總是在當(dāng)前類構(gòu)造器主體執(zhí)行之前進(jìn)行的,且static的成員比普通的成員變量先初始化。

11、多態(tài)

1.多態(tài)只發(fā)生在普通方法中,對于域和static方法,不發(fā)生多態(tài)。子類對象轉(zhuǎn)化為父類型引用時,對于任何域的訪問都是由編譯器解析。靜態(tài)方法是與類相關(guān)聯(lián),而不與單個對象相關(guān)聯(lián);

2.在繼承時,若被覆寫的方法不是private,則父類調(diào)用方法時,會調(diào)用子類的方法,常用的多態(tài)性就是當(dāng)父類引用指向子類對象時。

3.多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量到底指向哪個類的實例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實現(xiàn)的方法,必須在由程序運行期間才能決定。

4.多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。

5.多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作,多態(tài)性是對象多種表現(xiàn)形式的體現(xiàn)。

12、構(gòu)造器

1.為什么強制每個導(dǎo)出類部分都必須調(diào)用構(gòu)造器的原因?(基類的構(gòu)造器總是在導(dǎo)出類的構(gòu)造過程中被調(diào)用)

只有基類的構(gòu)造器才具有恰當(dāng)?shù)闹R和權(quán)限對自己的元素進(jìn)行初始化,因此必須令所有的構(gòu)造器都得到調(diào)用。導(dǎo)出類只能訪問自己的成員,不能訪問基類中的成員(通常是private類型)。

2.編寫構(gòu)造器原則:用盡可能的簡單的方法使對象進(jìn)入正常狀態(tài);如果可以的話,避免調(diào)用其他方法,因為調(diào)用這些方法,有可能會導(dǎo)致初始化未進(jìn)行,調(diào)用的是0值,在構(gòu)造器內(nèi)唯一能夠安全調(diào)用的方法是基類中的final方法(調(diào)用不能被覆蓋的方法)。

13、基本數(shù)據(jù)類型與包裝類

所有的包裝類(8個)都位于java.lang包下,分別是Byte,Short,Integer,Long,F(xiàn)loat,Double,Character,Boolean

基本數(shù)據(jù)類型:byte:8位;short:16位;int:32位;long:64位;float:32位;double:64位;char:16位;boolean:8位。

14、==與equals方法的區(qū)別:

(1)基本數(shù)據(jù)類型與引用數(shù)據(jù)類型

1.基本數(shù)據(jù)類型的比較:只能用==;

2.引用數(shù)據(jù)類型的比較:==是比較棧內(nèi)存中存放的對象在堆內(nèi)存地址,equals是比較對象的內(nèi)容是否相同;

(2)特殊:String作為一個對象

例子一:通過構(gòu)造函數(shù)創(chuàng)建對象時。對象不同,內(nèi)容相同,”==”返回false,equals返回true

String s1 = newString(“java”);

String s2 = new String(“java”);

System.out.println(s1==s2);            //false

System.out.println(s1.equals(s2));   //true

例子二:同一對象,”==”和equals結(jié)果相同

String s1 = newString(“java”);

String s2 = s1;  //兩個不同的引用變量指向同一個對象

System.out.println(s1==s2);            //true

System.out.println(s1.equals(s2));   //true

如果值不相同,對象就不相同,所以”==”和equals結(jié)果一樣

String s1 = “java”;

String s2 = “java”;   //此時String常量池中有java對象,直接返回引用給s2;

System.out.println(s1==s2);            //true

System.out.println(s1.equals(s2));    //true

字面量形式創(chuàng)建對象時:

如果String緩沖池內(nèi)不存在與其指定值相同的String對象,那么此時虛擬機將為此創(chuàng)建新的String對象,并存放在String緩沖池內(nèi)。

如果String緩沖池內(nèi)存在與其指定值相同的String對象,那么此時虛擬機將不為此創(chuàng)建新的String對象,而直接返回已存在的String對象的引用。

(3)String的字面量形式和構(gòu)造函數(shù)創(chuàng)建對象

1)String s = “aaa”;采用字面值方式賦值

1.查找StringPool中是否存再“aaa”這個對象,如果不存在,則在StringPool中創(chuàng)建一個“aaa”對象,然后將String Pool中的這個“aaa”對象的地址返回來,賦給引用變量s,這樣s會指向String Pool中的這個“aaa”字符串對象;

2.如果存在,則不創(chuàng)建任何對象,直接將String Pool中的這個“aaa”對象地址返回來,賦給s引用。

2)String s = new String(“aaa”);

1.首先在StringPool中查找有沒有”aaa”這個字符串對象,如果有,則不在String Pool中再去創(chuàng)建”aaa”這個對象,直接在堆中創(chuàng)建一個”aaa”字符串對象,然后將堆中的這個”aaa”對象的地址返回來,賦給s引用,導(dǎo)致s指向了堆中創(chuàng)建的這個”aaa”字符串對象;

2.如果沒有,則首先在String Pool中創(chuàng)建一個”aaa”對象,然后再去堆中創(chuàng)建一個”aaa”對象,然后將堆中的這個”aaa”對象的地址返回來,賦給s引用,導(dǎo)致s指向了堆中所創(chuàng)建的這個”aaa”對象。

15、Object類的公有方法

clone()(protected的)、toString()、equals(Object obj)、hashCode()、getClass()、finialize()(protected的)、notify()/notifyAll()、wait()/wait(long timeout)、wait(long timeout,intnaos)

16、try-catch-finally

·       1.finally里面的代碼一定會執(zhí)行的;

·       2.當(dāng)try和catch中有return時,先執(zhí)行return中的運算結(jié)果但是先不返回,然后保存下來計算結(jié)果,接著執(zhí)行finally,最后再返回return的值。

·       3.finally中最好不要有return,否則,直接返回,而先前的return中計算后保存的值得不到返回。

17、面向?qū)ο蟮娜蠡咎卣?/h2>

封裝、繼承和多態(tài)

(1)封裝

隱藏一切可以隱藏的消息,只向外界提供最簡單的編程接口;類就是對數(shù)據(jù)和方法的封裝;方法就是對具體實現(xiàn)細(xì)節(jié)的封裝;

(2)繼承

從已有的類繼承得到繼承信息,創(chuàng)建新類的過程,并無需重新編寫與原來的類相同的方法或成員變量情況下就可以對這些功能進(jìn)行擴展。

(3)多態(tài)

允許父類型的引用指向子類型的對象。

實現(xiàn)方式:方法重載(編譯器綁定,前綁定)和方法重寫(運行期綁定,后綁定)

18、靜態(tài)類和非靜態(tài)類

(1)靜態(tài)類

靜態(tài)類中的字段與方法都必須是static的,靜態(tài)類不需要實例化就可以使用;

(2)非靜態(tài)類

非靜態(tài)類中可以有static的字段與方法,也可以由非static的字段與方法,訪問static的字段與方法不需要實例化,但是訪問非static的字段與方法時需要實例化。

19、for和foreach循環(huán)效率:

for可以不逐個遍歷,如每隔一個遍歷;也可以從前向后遍歷,從后向前遍歷;有條件判斷,使用已知次數(shù)的循環(huán)遍歷;

foreach只能逐個遍歷;只能從前向后遍歷;沒有執(zhí)行條件限制,不能向迭代變量賦值;適合集合的遍歷;

如果遍歷集合或數(shù)組時,如果需要訪問集合或數(shù)組的下標(biāo),則最好使用舊式的方式來實現(xiàn)循環(huán)或遍歷,而不要使用增強的for循環(huán),因為它丟失了下標(biāo)信息。

20、JNIjava native interface

設(shè)計作用:主要實現(xiàn)和其他語言的通信,c和c++。標(biāo)準(zhǔn)的Java類庫中可能不支持程序所需的特性,或已經(jīng)有了一個用其他語言編寫的庫或程序,但是現(xiàn)在希望用到Java程序中,則需要使用JNI。

使用場景:JDBC實現(xiàn)連接數(shù)據(jù)庫,Thread.sleep()方法。

21、pach和classpath的區(qū)別

path是windows的環(huán)境屬性,用于指定可執(zhí)行命令的路徑;classpath是指在Java程序執(zhí)行的時候,用于指定類的加載路徑。

22、final、finally、finalize的區(qū)別

final是Java的一個關(guān)鍵字,用于定義不能被繼承的類,不能被覆寫的方法,不能修改的常量。

finally是Java的一個關(guān)鍵字,是異常處理操作的統(tǒng)一出口。

finalize是Object類中所提供的一個方法,用于在對象回收之前進(jìn)行收尾操作。

final

修飾符(關(guān)鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法不可以重寫(父子類繼承關(guān)系),但是可以重載(同一個類中)。

finally

異常處理時提供 finally 塊來執(zhí)行任何清除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執(zhí)行,然后控制就會進(jìn)入 finally 塊(如果有的話)。一般異常處理塊需要。

finalize

·       方法名,Java技術(shù)允許使用 finalize() 方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調(diào)用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調(diào)用的。

·       Java中所有類都從Object類中繼承finalize()方法。

·       當(dāng)垃圾回收器(garbage colector)決定回收某對象時,就會運行該對象的finalize()方法。值得C++程序員注意的是,finalize()方法并不能等同與析構(gòu)函數(shù)。Java中是沒有析構(gòu)函數(shù)的。C++的析構(gòu)函數(shù)是在對象消亡時運行的。由于C++沒有垃圾回收,對象空間手動回收,所以一旦對象用不到時,程序員就應(yīng)當(dāng)把它delete()掉。所以析構(gòu)函數(shù)中經(jīng)常做一些文件保存之類的收尾工作。但是在Java中很不幸,如果內(nèi)存總是充足的,那么垃圾回收可能永遠(yuǎn)不會進(jìn)行,也就是說filalize()可能永遠(yuǎn)不被執(zhí)行,顯然指望它做收尾工作是靠不住的。

·       那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申請的內(nèi)存。Java程序有垃圾回收器,所以一般情況下內(nèi)存問題不用程序員操心。但有一種JNI(JavaNative Interface)調(diào)用non-Java程序(C或C++),finalize()的工作就是回收這部分的內(nèi)存。

23、Java實現(xiàn)可移植性的原理

Java程序最終通過字節(jié)碼文件運行,運行的時候字節(jié)碼需要JVM支持,但是在不同的操作系統(tǒng)中有不同的JVM,程序不用關(guān)心操作系統(tǒng),只關(guān)心JVM,只要JVM不改變,程序可以在操作系統(tǒng)間任意移植。

24、Java的數(shù)據(jù)類型劃分

1)當(dāng)若干個變量參與運算時,結(jié)果類型取決于這些變量中表示范圍最大的那個變量類型,如有整型int,有雙精度浮點型double,有短整型short,則最后的結(jié)果類型為double。

2)取模

數(shù)據(jù)類型 默認(rèn)值
基本數(shù)據(jù)類型
數(shù)值型:整型:byte、short、int、long

浮點型:float、double

0
字符型:char ‘\u0000’
布爾型:boolean false
引用數(shù)據(jù)類型
數(shù)組、類、接口 null

25、&和&&、|和||的區(qū)別

·       &(普通與)和|(普通或)是指所有條件都需要判斷;

·       &&稱為邏輯與(短路與)是如果前面的條件不滿足false,則后面的不再進(jìn)行判斷;||稱為邏輯或(短路或)如果前面的條件滿足true則后面的不再判斷;

·       在開發(fā)之中為了性能的提高,不需要所有條件進(jìn)行判斷,所以使用短路與和短路或操作;

·       &和|除了用于邏輯運算以外,還進(jìn)行位運算的操作。

·

26、String對象的兩種實例化方式的區(qū)別

1.首先String對象的實例化有兩種:直接賦值和構(gòu)造方法完成。

2.直接賦值:在常量池中創(chuàng)建該字符串;

3.構(gòu)造方法:先判斷在字符串常量池中是否包含該字符串,若包含該字符串,則在堆中直接創(chuàng)建這個字符串對象并返回該對象引用;若不包含,則先在堆上創(chuàng)建,然后在字符串常量池中也創(chuàng)建,最后把返回堆上對象引用。

27、throw和throws區(qū)別

1.throw是語句拋出一個異常。

語法:throw (異常對象);

throw e;

throws是方法可能拋出異常的聲明。(用在聲明方法時,表示該方法可能要拋出異常)

語法:[(修飾符)](返回值類型)(方法名)([參數(shù)列表])[throws(異常類)]{……}

public void doA(int a) throws Exception1,Exception3{……}

2.throw語句用在方法體內(nèi),表示拋出異常,由方法體內(nèi)的語句處理;throws語句用在方法聲明后面,表示再拋出異常,由該方法的調(diào)用者來處理。

3.throw是具體向外拋異常的動作,已經(jīng)發(fā)生異常,被捕獲到,要拋出該異常,所以它是拋出一個異常實例;throws主要是聲明這個方法會拋出這種類型的異常,使它的調(diào)用者知道要捕獲這個異常,傾向于發(fā)生,但不一定發(fā)生。

28、枚舉(Enums)

1.當(dāng)使用“enum”定義枚舉類型時,實質(zhì)上是繼承java.lang.Enum類型;

2.每個枚舉的成員其實就是定義的枚舉類型的一個實例,他們都被預(yù)設(shè)為final,所以無法改變他們,也是static成員,所以可以通過類型名稱直接使用它們,且他們是公開的public的。

3.特性:final static public的。

4.在編譯時期就確定該枚舉類型具有幾個實例,分別是什么。在運行期間我們無法再使用該枚舉類型創(chuàng)建新的實例,這些實例在編譯期間就已經(jīng)完全確定下來。

29、遞歸

Recursion,就是方法調(diào)用自身,對于遞歸來說,一定有一個出口,讓遞歸結(jié)束,只有這樣才能保證不出現(xiàn)死循環(huán)。

30、可變參數(shù)

1.可變參數(shù)本質(zhì)上就是一個數(shù)組,對于某個聲明了可變參數(shù)的方法來說,既可以傳遞離散的值,也可以傳遞數(shù)組對象。

2.如果將方法中的參數(shù)定義為數(shù)組,則只能傳遞數(shù)組對象而不能傳遞離散的值。

3.可變參數(shù)必須要作為方法參數(shù)的最后一個參數(shù),即一個方法不可能具有兩個或以上的可變參數(shù)。

31、靜態(tài)導(dǎo)入

1.使用靜態(tài)導(dǎo)入import static時,要一直導(dǎo)入到類中的靜態(tài)成員變量或靜態(tài)方法。

如:

import static com.ljy.exercise.Person.age;

import staticcom.ljy.exercise.Person.printlnPersonName;

32、集合的元素

Java核心技術(shù)面試整理

集合中存放的依然是對象的引用,而不是對象本身。

集合無法放置原生數(shù)據(jù)類型,所以需要使用原生數(shù)據(jù)類型的包裝類將其轉(zhuǎn)換為真正的類型。

33、一個類不能既是final的,又是abstract的

因為abstract的主要目的是定義一種約束:讓子類去實現(xiàn)這種約定,而final表示該類不能被繼承,這樣abstract希望該類可以被繼承與之矛盾。

34、靜態(tài)方法

1.static修飾方法,可以通過類名.靜態(tài)方法名的方式訪問,靜態(tài)方法只能繼承,不能重寫(Override)。

2.不能在靜態(tài)方法中使用this關(guān)鍵字;

3.靜態(tài)的只能訪問靜態(tài)的(因為靜態(tài)的代碼塊在構(gòu)造方法之前就已經(jīng)開始初始化,而此時非靜態(tài)的還未開始初始化,如果靜態(tài)能訪問非靜態(tài)的就會出現(xiàn)發(fā)生錯誤),非靜態(tài)的可以訪問一切。

35、局部變量和成員變量

局部變量使用前必須聲明并賦初值;成員變量使用前必須要聲明,但可以不賦初值。

 

36、引用類型

reference type,引用類型用在對象上,一個對象可以被多個引用所指向,但同一時刻,每個引用只能指向唯一的對象,如果一個對象被多個引用所指向,那么無論哪個引用對對象的屬性進(jìn)行修改,都會反映到其他的引用中去。

37、方法和類的定義

(1)類的定義

修飾符 class 類的名字{

//類的內(nèi)容(包含了屬性與方法)

}

(2)方法的定義

修飾符 返回類型 方法名稱([參數(shù)1,參數(shù)2,參數(shù)3…]){

//方法體

}

1)方法定義不能嵌套,一個方法中不能定義另一個方法,方法只能定義在類中。

2)形式參數(shù):方法定義時的參數(shù)。

3)實際參數(shù):方法調(diào)用時所賦予的具體值。

38、break和continue

1)break語句:經(jīng)常用在循環(huán)語句中,用于跳出整個循環(huán),執(zhí)行循環(huán)后面的代碼。(如果雙重循環(huán),在內(nèi)循環(huán)中使用break,跳出內(nèi)循環(huán))

2)continue語句:經(jīng)常用在循環(huán)語句中,用于跳出本次循環(huán),開始下一次循環(huán)的執(zhí)行。

3)break與continue可以搭配標(biāo)簽使用。

39、變量的自增與自減運算

1)關(guān)于int b = a++,作用:先將a賦給b,然后再讓a自增1。

2)關(guān)于int b = ++a,作用:先將a的值自增1,然后再將自增后的a賦給b。

總結(jié):哪個在前,就先做哪一步。

40、Arrays.sort底層實現(xiàn)

基本類型:采用調(diào)優(yōu)的快速排序:當(dāng)待排序元素小于7個的時候,采用插入排序。

對象類型:采用改進(jìn)的歸并排序;

41、什么是跨平臺性?原理是什么?

 

1)跨平臺性:通過Java語言編寫的應(yīng)用程序在不同的系統(tǒng)平臺上都可以運行。

2)原理:只要在需要運行Java應(yīng)用程序的操作系統(tǒng)上,先安裝一個Java虛擬機(JVM Java Virtual Machine)即可,由JVM來負(fù)責(zé)Java程序在該系統(tǒng)中的運行。因為有了JVM,所以同一個Java程序在三個不同的操作系統(tǒng)中都可以執(zhí)行,這樣實現(xiàn)Java程序的跨平臺性,也稱為Java具有良好的可移植性。

42、JRE與JDK

1)JRE:Java Runtime Environment,Java運行環(huán)境,包括JVM和Java程序所需的核心類庫等。

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

3)如果是命令行模式:編譯器javac進(jìn)行編譯:javac 源文件名.java——編譯通過后,對class字節(jié)碼文件運行:java 類名

4)運行與工作原理

 

5)path環(huán)境變量配置的作用:程序開發(fā)過程中,不能將源代碼寫入JDK的安裝目錄,因此需要將源程序保存到任意位置的指定目錄(英文目錄),所以需要使javac指令在任意目錄下可以運行。通過配置path環(huán)境變量,將javac指令所在目錄及JDK安裝目錄下的bin目錄配置到path變量下,即可使javac指令在任意目錄下運行。

6)使classpath目錄中的.class文件可以在任意目錄運行。

7)path和classpath的區(qū)別:path環(huán)境變量里面記錄的是可執(zhí)行性文件,如.exe文件,對可執(zhí)行文件先在當(dāng)前路徑去找,如果沒找到就去path環(huán)境變量中配置的路徑去找。而classpath環(huán)境變量里記錄的是java類的運行文件所在的目錄。

43、反射

(1)反射機制

1)定義:JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。要想解剖一個類,必須先要獲取到該類的字節(jié)碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個字節(jié)碼文件對應(yīng)的Class類型的對象.

2)獲取Class對象的三種方式

第一種方式:

Person p = new Person();

Class c = p.getClass();

第二種方式:任意類都具備一個class靜態(tài)屬性

Class c2 = Person.class;

第三種方式:將類名作為字符串傳遞給Class類的靜態(tài)方法forName

Class c3 =Class.forName(“Person”);

(2)動態(tài)代理

1)在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler接口,通過使用這個類和接口就可以生成動態(tài)代理對象。JDK提供的代理只能針對接口做代理。我們有更強大的代理cglib

2)Proxy類中的方法創(chuàng)建動態(tài)代理類對象

public static Object newProxyInstance(ClassLoaderloader,Class<?>[] interfaces,InvocationHandler h)

最終會調(diào)用InvocationHandler的方法

Proxy類中創(chuàng)建動態(tài)代理對象的方法的三個參數(shù);

·       ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進(jìn)行加載;

·       Interface對象的數(shù)組,表示的是我將要給我需要代理的對象提供一組什么接口,如果我提供了一組接口給它,那么這個代理對象就宣稱實現(xiàn)了該接口(多態(tài)),這樣我就能調(diào)用這組接口中的方法了;

·       InvocationHandler對象,表示的是當(dāng)我這個動態(tài)代理對象在調(diào)用方法的時候,會關(guān)聯(lián)到哪一個InvocationHandler對象上。

3)InvocationHandler

Object invoke(Object proxy,Method method,Object[] args)

每一個動態(tài)代理類都必須要實現(xiàn)InvocationHandler這個接口,并且每個代理類的實例都關(guān)聯(lián)到了一個handler,當(dāng)我們通過代理對象調(diào)用一個方法的時候,這個方法的調(diào)用就會被轉(zhuǎn)發(fā)為由InvocationHandler這個接口的invoke 方法來進(jìn)行調(diào)用。

InvocationHandler接口中invoke方法的三個參數(shù):

·       proxy:代表動態(tài)代理對象

·       method:代表正在執(zhí)行的方法

·       args:代表調(diào)用目標(biāo)方法時傳入的實參

4)Proxy.newProxyInstance

創(chuàng)建的代理對象是在jvm運行時動態(tài)生成的一個對象,它并不是我們的InvocationHandler類型,也不是我們定義的那組接口的類型,而是在運行是動態(tài)生成的一個對象,并且命名方式都是這樣的形式,以$開頭,proxy為中,最后一個數(shù)字表示對象的標(biāo)號。System.out.println(u.getClass().getName());

44、異常

(1)異常介紹

1)編譯時異常

除了RuntimeException及其子類,Exception中所有的子類都是,這種異常必須要處理,要不編譯通不過

2)運行時異常

RuntimeException及其子類都是,這種異常不用處理,編譯會通過,不過這樣的程序會有安全隱患,遇到這種異常是需要改代碼的

3)嚴(yán)重錯誤問題

用Error進(jìn)行描述,這個問題發(fā)生后,一般不編寫針對代碼進(jìn)行處理,而是要對程序進(jìn)行修正.通常都是由虛擬機拋出的問題

(2)Throwable中方法

getMessage()

獲取異常信息,返回字符串。

toString()

獲取異常類名和異常信息,返回字符串。

printStackTrace()

獲取異常類名和異常信息,以及異常出現(xiàn)在程序中的位置。返回值void。

printStackTrace(PrintStream s)

通常用該方法將異常內(nèi)容保存在日志文件中,以便查閱。

(3)throws和throw的區(qū)別

1)throws

·       用在方法聲明后面,跟的是異常類名;

·       可以跟多個異常類名,用逗號隔開;

·       表示拋出異常,由該方法的調(diào)用者來處理;

·       throws表示出現(xiàn)異常的一種可能性,并不一定會發(fā)生這些異常。

2)throw

·       用在方法體內(nèi),跟的是異常對象名;

·       只能拋出一個異常對象名;

·       表示拋出異常,由方法體內(nèi)的語句處理;

·       throw則是拋出了異常,執(zhí)行throw則一定拋出了某種異常 。

(4)try和throws區(qū)別

如果該功能內(nèi)部可以將問題處理,用try,如果處理不了,則交由調(diào)用者處理,用throws進(jìn)行拋出異常。

區(qū)別:后序程序需要運行,則用try;后序程序不需要繼續(xù)運行,則用throws;

45、面向?qū)ο螅?/h2>

1)思想:是站在現(xiàn)實世界的角度去抽象和解決問題,把數(shù)據(jù)和行為都看作是對象的一部分,可以讓程序員以符合現(xiàn)實世界的思維方式來編寫和組織程序。

2)原則:

單一職責(zé):一個類只做它該做的事(高內(nèi)聚);

開放封閉:對擴展開放,對修改關(guān)閉;

里氏替換:任何時候都可用子類型替換父類型;

依賴倒置:面向接口編程(抽象類型可被任何一個子類所替代);

合成聚和復(fù)用:優(yōu)先使用聚合或合成關(guān)系復(fù)用代碼;

接口隔離:一個接口只應(yīng)描述一種能力,接口應(yīng)該是高內(nèi)聚的(小而專一);

迪米特法則:最少知識原則,一個對象應(yīng)對其他對象盡可能少的了解。

46、數(shù)組和容器的區(qū)別

1)效率:數(shù)組是一種效率最高的存儲和隨機訪問對象引用序列的方式,數(shù)組就是一個簡單的線性序列,這使得元素訪問非??焖?,可以通過整型索引值訪問元素;

2)大?。簲?shù)組對象的大小被固定,并且在其生命周期中不可改變;容器如ArrayList可以動態(tài)擴容,通過創(chuàng)建一個新實例,然后把舊實例中所有的引用移到新實例中,從而實現(xiàn)更多空間的自動分配;

3)數(shù)據(jù)類型:數(shù)組可以持有基本類型,數(shù)組持有某種具體類型,通過編譯器檢查,防止插入錯誤類型和抽取不當(dāng)類型;容器通過泛型,指定并檢查它們所持有對象的類型,并且有了自動包裝機制,好像是能夠持有基本數(shù)據(jù)類型。

注意:數(shù)組的比較是是通過equals()方法,用來比較整個數(shù)組,同樣,此方法針對所有基類類型與Object都做了重載,數(shù)組相等的條件是元素個數(shù)必須相等,并且對應(yīng)位置的元素也相等,這可以通過對每一個元素使用equals()作比較判斷。

47、Arrays的方法

java.util類庫中的Arrays類,有一套用于數(shù)組的static實用方法。有6個基本方法+1個asList()方法。

1)Arrays.asList():接收任意的序列或數(shù)組作為其參數(shù),并將其轉(zhuǎn)變?yōu)長ist容器;

2)equals():用于比較兩個數(shù)組是否相等(deepEquals()用于多維數(shù)組);

3)fill():是用同一個數(shù)值進(jìn)行填充數(shù)組的各個位置,針對對象而言,就是復(fù)制同一個引用進(jìn)行填充;

4)sort():用于對數(shù)組排序;(對于數(shù)值排序,小于8的使用插入排序,大于等于8個元素使用快速排序;對于對象排序,使用合并排序);

5)binarySearch():用于在已經(jīng)排序的數(shù)組中查找元素;

6)toString():差生數(shù)組的String表示;

7)hashCode():產(chǎn)生數(shù)組的散列碼;

48、equals()方法的5個條件

1)自反性。對任意x,x.equals(x)一定返回true;

2)對稱性。對任意x和y,如果y.equals(x)返回true,則x.equals(y)也返回true;

3)傳遞性。對任意x、y、z,如果有x.equals(y)返回true,y.equals(z)返回true,則x.equals(z)一定返回true;

4)一致性。對任意x和y,如果對象中用于等價比較的信息沒有改變,那么無論調(diào)用x.equals(y)多少次,返回的結(jié)果應(yīng)該保持一致,要么一直是true,要么一直是false;

5)對任何不是null的x,x.equals(null)一定返回false。

默認(rèn)的Object.equals()只是比較對象的地址。

49、public staticvoid main(String[] args)方法的必要性

1)是Java程序的入口方法,JVM在運行程序時,會首先查找main()方法;

2)public是權(quán)限修飾符,表明任何類或?qū)ο蠖伎梢栽L問這個方法;

3)static表明main()方法是一個靜態(tài)方法,即方法中的代碼是存儲在靜態(tài)存儲區(qū)的,只要類加載后,就可以使用該方法而不需要通過實例化對象來訪問,可以直接通過類名。

4)main()不能用abstract修飾,但可以用final和synchronized修飾,且public與static的順序可以顛倒。

50、Java程序初始化的順序

(1)遵循3個原則:

1)靜態(tài)對象(變量)優(yōu)先于非靜態(tài)對象(變量)初始化;

2)父類優(yōu)先于子類進(jìn)行初始化;

3)按照成員變量的定義順序進(jìn)行初始化,

(2)初始化順序

父類靜態(tài)變量、父類靜態(tài)代碼塊、子類靜態(tài)變量、子類靜態(tài)代碼塊、父類非靜態(tài)變量、父類非靜態(tài)代碼塊、父類構(gòu)造函數(shù)、子類非靜態(tài)變量、子類非靜態(tài)代碼塊、子類構(gòu)造函數(shù)

51、Java變量類型

Java核心技術(shù)面試整理

(1)變量類型

靜態(tài)變量、成員變量、局部變量

(2)變量類型的范圍

1)靜態(tài)變量:被static修飾的成員變量稱為靜態(tài)變量,靜態(tài)變量不依賴于特定的實例,而是被所有實例所共享,只要一個類被加載,JVM就會給類的靜態(tài)變量分配存儲空間,可以通過類名和實例變量名訪問靜態(tài)變量。

2)成員變量:作用范圍與類的實例化對象的作用范圍相同,當(dāng)類被實例化時,成員變量就會在內(nèi)存中分配空間并初始化,直到這個被實例化對象的生命周期結(jié)束時,成員變量的聲明周期才結(jié)束。

3)局部變量:作用域與可見性為它所在的花括號內(nèi)。

52、ArrayList和linkedList

1)實現(xiàn)接口:都實現(xiàn)了List接口;

2)底層:ArrayList底層是由數(shù)組支持;linkedList底層是由雙向鏈表實現(xiàn);

3)內(nèi)存:ArrayList比linkedList申請少的內(nèi)存,因為linkedList中的每個對象包含數(shù)據(jù)的同時還包含指向鏈表中前一個與后一個元素的引用;

4)操作:ArrayList不適合插入或刪除,需要移動后面的元素,但適合快速訪問;而linkedList適合插入和刪除,因為開銷是固定的;

53、快速報錯機制

1)出現(xiàn)原因:在迭代遍歷某個容器的過程中,另一個進(jìn)程介入其中,并且插入、刪除或修改此容器內(nèi)的某個對象,則會出現(xiàn)問題:也許迭代過程已經(jīng)處理過容器中得到該元素了,也許還沒處理,也許在調(diào)用size()之后容器的尺寸收縮了。

2)快速報錯(fail-fast)機制:探查容器上除了你的進(jìn)程所進(jìn)行的操作以外的所有變化,一旦發(fā)現(xiàn)其他進(jìn)程修改容器,立即拋出ConcurrentModificationException異常,即不是使用復(fù)雜的算法在事后來檢查問題。

想要了解更多java培訓(xùn)面試題歡迎關(guān)注小編!

標(biāo)簽:java面試題

本文鏈接:

本文章“Java核心技術(shù)面試整理”已幫助 249 人

免責(zé)聲明:本信息由用戶發(fā)布,本站不承擔(dān)本信息引起的任何交易及知識產(chǎn)權(quán)侵權(quán)的法律責(zé)任!

本文由賦能網(wǎng) 整理發(fā)布。了解更多培訓(xùn)機構(gòu)》培訓(xùn)課程》學(xué)習(xí)資訊》課程優(yōu)惠》課程開班》學(xué)校地址等機構(gòu)信息,可以留下您的聯(lián)系方式,讓課程老師跟你詳細(xì)解答:
咨詢熱線:4008-569-579

如果本頁不是您要找的課程,您也可以百度查找一下: