java 面试宝典总结
面試寶典總結(jié):
java 基礎(chǔ)
Java 中的八種數(shù)據(jù)類型
| 整型 | byte | 1 | -128··127 |
| 整型 | short | 2 | -32768··32767 |
| 整型 | int | 4 | |
| 整型 | long | 8 | -2^63 ·· 2^63-1 |
| 浮點型 | float | 4 | |
| 浮點型 | double | 8 | |
| 字符型 | char | 2 | |
| 布爾型 | boolean | 1 | true,false |
一個byte類型在計算機中占一個字節(jié),那么就是8個bit,就是8位,那么最 大就是11111111,
就是說能表示255個不同的值,那么以0作為中心點,范圍就是-128到127
計算機中負數(shù)的存儲方式是補碼。
方法為:對負數(shù)的絕對值的二進制值取反,再加一,即為負數(shù)的二進制 碼。
如:-1的絕對值1的二進制碼為00000001,取反得到11111110,再加一為11111111。
而-128的絕對值128的二進制碼為10000000,取反得到01111111,再加一為10000000,
正好是Byte的最大表示范圍
計算機是如何來區(qū)分有無符號數(shù)的?
有符號數(shù)和無符號數(shù)在計算機里表示都是一樣的,二進制的補碼形式。
是有符號還是無符號,是編譯器來辨認的。
例如:
unsigned char uch, char ch;
如何查看一個二進制是否是正數(shù)還是負數(shù)?
看一個二進制是否是正數(shù)還是負數(shù),需要先說明其是存儲在計算機中,然后要搞清楚其在計算機中是以有符號進行存儲還是無符號進行存儲。
(補碼存儲)需要看其最高位,最高位為0,為正數(shù); 反之,為負數(shù)。
面向?qū)ο蟮乃拇筇卣?#xff1a;
訪問權(quán)限修飾符的區(qū)別
| public | √ | √ | √ | √ |
| protected | √ | √ | √ | × |
| default | √ | √ | × | × |
| private | √ | × | × | × |
對象的克隆
克隆出來的對象是一個新的對象。
深拷貝和淺拷貝的區(qū)別:
當(dāng)對象的中的對象是引用數(shù)據(jù)類型時,淺拷貝指向的時對象的引用,深拷貝才是新的創(chuàng)建。(Clone方法是淺拷貝)
如何實現(xiàn)深拷貝?
如果想深拷貝一個對象(對象中含有引用對象),這個對象非必須要實現(xiàn)Cloneable 接口,實現(xiàn)Clone方法,并且在clone方法內(nèi)部,把該對象的引用的其他對象也要clone一份,這也意味者這個其他對象內(nèi)部也要實現(xiàn)Cloneable接口,重寫clone方法。
深克隆的方法驗證
static class Body implements Cloneable {public Head head;public Body() {}public Body(Head head) {this.head = head;}@Overrideprotected Object clone() throws CloneNotSupportedException {Body newBody = (Body) super.clone();newBody.head = (Head) head.clone();return newBody;} }static class Head implements Cloneable {public Face face;public Head() {}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();} }public static void main(String[] args) throws CloneNotSupportedException {Body body = new Body(new Head(new Face()));Body body1 = (Body) body.clone();System.out.println("body == body1 : " + (body == body1));System.out.println("body.head == body1.head : " + (body.head == body1.head)); } /*** 程序執(zhí)行結(jié)果:* body == body1 : false* body.head == body1.head : false*/& 和 && 的區(qū)別:
& :
&&:短路與
雖然& 和 && 運算符都要求左右兩端的布爾值都是 true,整個表達式的結(jié)果才為true,但是短路與&& 運算符只有當(dāng)左邊的表達式為true時才會繼續(xù)進行有右邊等式的運算,右邊為false時,會直接短路掉,右邊的表達式不會執(zhí)行。
java 中如何跳出當(dāng)前的多重嵌套循環(huán)?
break關(guān)鍵字,在最外層循環(huán)加一個標(biāo)記A,通過breakA;可以跳出多重循環(huán)
兩對象的HashCode值比較。
如果兩個對象equals方法返回true,那么它們的 hashCode 值一定相同。
兩個對象的 hashCode 值相同,它們的equals方法不一定返回 true。(hash沖突)
A==B判斷的兩個對象的地址值是否相同,A.equals(B) 比較的是兩個對象的值是否相同。
instanceOf 判斷的是兩個對象是否是同一個類型。
String 是否可以被繼承?(final 修飾的類)
由于String 是被final修飾的類,所以不能被繼承。
當(dāng)一個對象被當(dāng)作參數(shù)傳遞到一個方法后,方法可以改變這個對象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引用傳遞?
//基礎(chǔ)類型作為值傳遞 public class test {public static void main(String[] args) {int i = 1;System.out.println("before change, i = "+i);change(i);System.out.println("after change, i = "+i);}public static void change(int i){i = 5;} } /*** 輸出的結(jié)果是 before change i = 1;* 輸出的結(jié)果是 after change i = 1;* 當(dāng)基本數(shù)據(jù)類型作為參數(shù)傳遞時,傳遞的是實參值的副本,即傳的是值,無論在函數(shù)中怎么操作這個副本, * 實參的值是不會被改變的。*///對象(引用類型)作為值傳遞 public class test {public static void main(String[] args) {StringBuffer sb = new StringBuffer("Hello ");System.out.println("before change, sb is "+sb.toString());change(sb);System.out.println("after change, sb is "+sb.toString());}public static void change(StringBuffer stringBuffer){stringBuffer.append("world !");} } /*** before change, sb is Hello* after change, sb is Hello world !*//*** 從輸出結(jié)果中我們可以發(fā)現(xiàn),sb所指向的對象的值被改變了,那么是否我們可以推論出,在Java中,當(dāng) * 對象作為參數(shù)傳遞時,傳遞的是該對象的引用呢?我們再來看下面這個例子*/public class test {public static void main(String[] args) {StringBuffer sb = new StringBuffer("Hello ");System.out.println("before change, sb is "+sb.toString());change(sb);System.out.println("after change, sb is "+sb.toString());}public static void change(StringBuffer stringBuffer){stringBuffer = new StringBuffer("Hi ");stringBuffer.append("world !");} }/*** 如果上面的推論是正確的,即Java中對象作為參數(shù)傳遞,實際傳遞的是該對象的引用,那么在調(diào)用change * 函數(shù)之后,原對象的值應(yīng)該是會改變的,變?yōu)椤癏i world !”,但是,當(dāng)我們運行程序后,結(jié)果卻是如下所示:* before change, sb is Hello* after change, sb is Hello** 原對象的值并沒有被改變,這與上面的推論相矛盾!*//*** 總結(jié)就是基本數(shù)據(jù)類型傳遞的是形參,形參不影響實參;引用數(shù)據(jù)類型傳遞的是地址,形參在方法內(nèi)被改變,實 * 參也會改變,若在方法內(nèi)實例化了同名對象,即產(chǎn)生了新的地址,對這個同名對象的改變,由于地址不一樣, * 所以不影響原來的對象*/總結(jié):
當(dāng)基本數(shù)據(jù)類型作為參數(shù)傳遞時,傳遞的是實參值的副本,即值的傳遞;無論在函數(shù)中怎么操作這個副本,實參的值是不會被改變的。
引用數(shù)據(jù)類型傳遞的是地址,形參在方法內(nèi)被改變,實參也會改變,若在方法內(nèi)實例化了同名對象,即產(chǎn)生了新的地址,對這個同名對象的改變,由于地址不一樣,所以不影響原來的對象
方法重載和方法重寫的區(qū)別
方法的重載和方法的重寫都是實現(xiàn)多態(tài)的方式。方法的重載是編譯時的多態(tài)性,而方法的重寫是運行時的多態(tài)性。
**方法重載的規(guī)則**- 方法名一致- 請求參數(shù)不同(個數(shù)不同,參數(shù)類型不同)- 和方法的返回值無關(guān)。- 可以拋出不同的異常,可以有不同的修飾符**方法的重寫**- 方法名,請求參數(shù),返回值相同- 構(gòu)造方法不能被重寫,static 和 final 修飾的方法不能被重寫- 重寫的方法不能拋出被重寫方法更廣泛的異常。抽象類 Abstract 和 interface 的區(qū)別?
相同: 都不能被實例化。
不同:
抽象類中可以定義構(gòu)造器,接口中不能定義構(gòu)造器。
接口中的成員全是public 的。抽象類中的成員可以是任何。
抽象類中可以有成員變量,接口中沒有。
抽象類中可以有抽象方法和具體方法。接口中只有抽象方法。
有抽象方法的類必須被聲明成抽象類,但是抽象類中可以沒有抽象方法 ,接口中的成員變量就是常量(接口中的成員變量默認是public staic final修飾的)。抽象類中可以有靜態(tài)方法。
抽象類只能夠單繼承。接口可以多繼承。
在 Jdk8 之后,接口中可以有默認方法和靜態(tài)方法。不僅僅止于抽象方法了。
== 和 equal 的區(qū)別
一個是方法一個是運算符, == 如果比較的是基本類型的變量,則比較的是數(shù)值是否相等。如果比較的是引用類型,那么比較的是引用類型的地址值是否相等。 equal是用來比較兩個對象的內(nèi)容是否相等。equal是不能用來比較基本類型的(基本數(shù)據(jù)類型沒有equals() 方法,可以做裝箱處理然后再使用equals()方法)。如果對象沒有對equal 方法進行重寫,那么equal方法比較的是對象的地址值;
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 // new String() 方法是重寫開辟了空間,所以 == 的結(jié)果為 falseequal 默認情況下是引用的比較(也就是 == 比較),不過很多的類都重寫了 equal 方法,比如 String,Integer 等內(nèi)部將equal 方法變成了 值 得比較。
break 和 continue 的區(qū)別
都是用來控制循環(huán)語句的。break 是用來結(jié)束一個循環(huán)的。continue 是用來跳過此次循環(huán),執(zhí)行下次循環(huán)。
throw 和 throws 的區(qū)別
throw 是用在方法體中的,用來拋出異常。執(zhí)行throw 一定是拋出了某種異常。
throws 是用在方法聲明后面的,表示可能會跑出某種異常。表示了某種異常的可能性,不一定會拋出異常。
final ,finally,finalize 的區(qū)別
final 修飾類,方法,屬性,表示為最終態(tài)不可變。finally 異常處理語句結(jié)構(gòu)的一部分,表示最終一定會被執(zhí)行。finalize : Object 的一個方法,在垃圾回收器執(zhí)行的時候會調(diào)用被回收對象的這個方法。更像是一個對象生命周期的臨終方法,當(dāng)此方法被調(diào)用代表著該對象的死亡。
final 修飾的類叫最終類,該類不能被繼承 final 修飾的方法不能被重寫 final 修飾的變量叫常量,常量必須初始化,初始化后不能再被修改Math.round()方法
數(shù)據(jù)軸向右取整。 -11.5==》-11 11.5 ==》 12
switch 中可使用的類型
java 5 以前只能使用 byte,short,int ,char 。 java5 開始 引入了 enum 。 java7 后,引入了 String ,但是 Long 類型一直都是不可以的。
String,StringBuffer ,Stringbuild 的區(qū)別
String 是被final 修飾的。不能被修改,Stringbuild 的值是可以被修改的。 StringBuffer 是線程安全的類。被 Synchronized 修飾。
String 聲明的是不可變的變量,每次操作都會生成新的String對象,而Stringbuild 和 Stringbuffer 都是在原字符串上進行操作的。
StringBuild 是線程不安全的,推薦在單線程下使用,而StringBuffer 是線程安全的推薦在多線程下使用。
String str="i"與 String str=new String(“i”)一樣嗎?
不一樣,因為內(nèi)存的分配方式不一樣。String str="i"的方式,java 虛擬機會將其分配到常量池中;而 String str=new String(“i”) 則會被分到堆內(nèi)存中。
BIO,AIO,NIO 有什么區(qū)別?
BIO:同步阻塞式IO,簡單方便,并發(fā)處理效率低
NIO:同步非阻塞IO,客戶端和服務(wù)器通過channel 信道,實現(xiàn)了多路復(fù)用
AIO:NIO的升級,也叫NIO2。異步非阻塞IO
?
泛型
泛型類型用于類的定義中,被稱為泛型類。通過泛型可以完成對一組類的操作對外開放相同的接口。最典型的就是各種容器類,如:List、Set、Map。
public interface List<E> extends Collection<E> { ........ }//泛型的最基本寫法:classs 類名稱<泛型標(biāo)識:可以隨便寫任意標(biāo)識符,標(biāo)識指定的泛型的類型>{private 泛型標(biāo)識 /* (成員變量類型) */ var ;}public void showKeyValue1(Generic<?> obj){Log.d("泛型測試","key value is " + obj.getKey()); } ?總結(jié)
以上是生活随笔為你收集整理的java 面试宝典总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring学习(11):使用配置类
- 下一篇: git pull 报错:Untracke