2023年 Java 面試八股文初級篇(20w字)
Java基礎(chǔ)篇
1、你是怎樣理解OOP面向?qū)ο??? 難度系數(shù):?
面向?qū)ο笫抢谡Z言對現(xiàn)實(shí)事物進(jìn)行抽象。面向?qū)ο缶哂幸韵绿卣鳎?/p>
繼承:繼承是從已有類得到繼承信息創(chuàng)建新類的過程
封裝:封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對數(shù)據(jù)的訪問只能通過已定義的接口
多態(tài)性:多態(tài)性是指允許不同子類型的對象對同一消息作出不同的響應(yīng)
2、重載與重寫區(qū)別??? 難度系數(shù):?
重載發(fā)生在本類,重寫發(fā)生在父類與子類之間
重載的方法名必須相同,重寫的方法名相同且返回值類型必須相同
重載的參數(shù)列表不同,重寫的參數(shù)列表必須相同
重寫的訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低
構(gòu)造方法不能被重寫
3、接口與抽象類的區(qū)別??? 難度系數(shù):?
抽象類要被子類繼承,接口要被類實(shí)現(xiàn)
接口可多繼承接口,但類只能單繼承
抽象類可以有構(gòu)造器、接口不能有構(gòu)造器
抽象類:除了不能實(shí)例化抽象類之外,它和普通Java類沒有任何區(qū)別
抽象類:抽象方法可以有public、protected和default這些修飾符、接口:只能是public
抽象類:可以有成員變量;接口:只能聲明常量
4、深拷貝與淺拷貝的理解??? 難度系數(shù):?
深拷貝和淺拷貝就是指對象的拷貝,一個對象中存在兩種類型的屬性,一種是基本數(shù)據(jù)類型,一種是實(shí)例對象的引用。
淺拷貝是指,只會拷貝基本數(shù)據(jù)類型的值,以及實(shí)例對象的引用地址,并不會復(fù)制一份引用地址所指向的對象,也就是淺拷貝出來的對象,內(nèi)部的類屬性指向的是同一個對象
深拷貝是指,既會拷貝基本數(shù)據(jù)類型的值,也會針對實(shí)例對象的引用地址所指向的對象進(jìn)行復(fù)制,深拷貝出來的對象,內(nèi)部的類執(zhí)行指向的不是同一個對象
5、sleep和wait區(qū)別 ???難度系數(shù):?
sleep方法
屬于Thread類中的方法
釋放cpu給其它線程 不釋放鎖資源
sleep(1000) 等待超過1s被喚醒
wait方法
屬于Object類中的方法
釋放cpu給其它線程,同時釋放鎖資源
wait(1000) 等待超過1s被喚醒
wait() 一直等待需要通過notify或者notifyAll進(jìn)行喚醒
wait 方法必須配合 synchronized 一起使用,不然在運(yùn)行時就會拋出IllegalMonitorStateException異常
6、什么是自動拆裝箱? int和Integer有什么區(qū)別??? 難度系數(shù):?
基本數(shù)據(jù)類型,如int,float,double,boolean,char,byte,不具備對象的特征,不能調(diào)用方法。
裝箱:將基本類型轉(zhuǎn)換成包裝類對象
拆箱:將包裝類對象轉(zhuǎn)換成基本類型的值
java為什么要引入自動裝箱和拆箱的功能?主要是用于java集合中,List<Inteter> list=new ArrayList<Integer>();
list集合如果要放整數(shù)的話,只能放對象,不能放基本類型,因此需要將整數(shù)自動裝箱成對象。
實(shí)現(xiàn)原理:javac編譯器的語法糖,底層是通過Integer.valueOf()和Integer.intValue()方法實(shí)現(xiàn)。
區(qū)別:
1、Integer是int的包裝類,int則是java的一種基本數(shù)據(jù)類型
2、Integer變量必須實(shí)例化后才能使用,而int變量不需要
3、Integer實(shí)際是對象的引用,當(dāng)new一個Integer時,實(shí)際上是生成一個指針指向此對象;而int則是直接存儲數(shù)據(jù)值
4、Integer的默認(rèn)值是null,int的默認(rèn)值是0
7、==和equals區(qū)別??? 難度系數(shù):?
==
如果比較的是基本數(shù)據(jù)類型,那么比較的是變量的值
如果比較的是引用數(shù)據(jù)類型,那么比較的是地址值(兩個對象是否指向同一塊內(nèi)存)
? ? 2.equals
如果沒重寫equals方法比較的是兩個對象的地址值
如果重寫了equals方法后我們往往比較的是對象中的屬性的內(nèi)容
equals方法是從Object類中繼承的,默認(rèn)的實(shí)現(xiàn)就是使用==
8、String能被繼承嗎 為什么用final修飾??? 難度系數(shù):?
1、不能被繼承,因?yàn)镾tring類有final修飾符,而final修飾的類是不能被繼承的。
2、String 類是最常用的類之一,為了效率,禁止被繼承和重寫。
3、為了安全。String 類中有native關(guān)鍵字修飾的調(diào)用系統(tǒng)級別的本地方法,調(diào)用了操作系統(tǒng)的 API,如果方法可以重寫,可能被植入惡意代碼,破壞程序。Java 的安全性也體現(xiàn)在這里。
9、String buffer和String builder區(qū)別??? 難度系數(shù):?
1、StringBuffer 與 StringBuilder 中的方法和功能完全是等價的,
2、只是StringBuffer 中的方法大都采用了 synchronized 關(guān)鍵字進(jìn)行修飾,因此是線程安全的,而 StringBuilder 沒有這個修飾,可以被認(rèn)為是線程不安全的。
3、在單線程程序下,StringBuilder效率更快,因?yàn)樗恍枰渔i,不具備多線程安全而StringBuffer則每次都需要判斷鎖,效率相對更低
10、final、finally、finalize??? 難度系數(shù):?
1、final:修飾符(關(guān)鍵字)有三種用法:修飾類、變量和方法。修飾類時,意味著它不能再派生出新的子類,即不能被繼承,因此它和abstract是反義詞。修飾變量時,該變量使用中不被改變,必須在聲明時給定初值,在引用中只能讀取不可修改,即為常量。修飾方法時,也同樣只能使用,不能在子類中被重寫。
2、finally:通常放在try…catch的后面構(gòu)造最終執(zhí)行代碼塊,這就意味著程序無論正常執(zhí)行還是發(fā)生異常,這里的代碼只要JVM不關(guān)閉都能執(zhí)行,可以將釋放外部資源的代碼寫在finally塊中。
3、finalize:Object類中定義的方法,Java中允許使用finalize() 方法在垃圾收集器將對象從內(nèi)存中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在銷毀對象時調(diào)用的,通過重寫finalize() 方法可以整理系統(tǒng)資源或者執(zhí)行其他清理工作。
11、Object中有哪些方法??? 難度系數(shù):?
1、protected Object clone()--->創(chuàng)建并返回此對象的一個副本。
2、boolean equals(Object obj)--->指示某個其他對象是否與此對象“相等
3、protected void finalize()--->當(dāng)垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調(diào)用此方法。
4、Class<? extendsObject> getClass()--->返回一個對象的運(yùn)行時類。
5、int hashCode()--->返回該對象的哈希碼值。
6、void notify()--->喚醒在此對象監(jiān)視器上等待的單個線程。
7、void notifyAll()--->喚醒在此對象監(jiān)視器上等待的所有線程。
8、String toString()--->返回該對象的字符串表示。
9、void wait()--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll() 方法。
? ? ?void wait(long timeout)--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify() 方法或 notifyAll()方法,或者超過指定的時間量。
? ? ?void wait(long timeout, int nanos)--->導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify()
12、說一下集合體系??? 難度系數(shù):?

13、ArrarList和LinkedList區(qū)別??? 難度系數(shù):?? ?
1、ArrayList是實(shí)現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
2、對于隨機(jī)訪問get和set,ArrayList效率優(yōu)于LinkedList,因?yàn)長inkedList要移動指針。
3、對于新增和刪除操作add和remove,LinkedList比較占優(yōu)勢,因?yàn)锳rrayList要移動數(shù)據(jù)。 這一點(diǎn)要看實(shí)際情況的。若只對單條數(shù)據(jù)插入或刪除,ArrayList的速度反而優(yōu)于LinkedList。但若是批量隨機(jī)的插入刪除數(shù)據(jù),LinkedList的速度大大優(yōu)于ArrayList. 因?yàn)锳rrayList每插入一條數(shù)據(jù),要移動插入點(diǎn)及之后的所有數(shù)據(jù)。
14、HashMap底層是 數(shù)組+鏈表+紅黑樹,為什么要用這幾類結(jié)構(gòu)??? 難度系數(shù):??
1、數(shù)組 Node<K,V>[] table ,哈希表,根據(jù)對象的key的hash值進(jìn)行在數(shù)組里面是哪個節(jié)點(diǎn)
2、鏈表的作用是解決hash沖突,將hash值取模之后的對象存在一個鏈表放在hash值對應(yīng)的槽位
3、紅黑樹 JDK8使用紅黑樹來替代超過8個節(jié)點(diǎn)的鏈表,主要是查詢性能的提升,從原來的O(n)到O(logn),
4、通過hash碰撞,讓HashMap不斷產(chǎn)生碰撞,那么相同的key的位置的鏈表就會不斷增長,當(dāng)對這個Hashmap的相應(yīng)位置進(jìn)行查詢的時候,就會循環(huán)遍歷這個超級大的鏈表,性能就會下降,所以改用紅黑樹
15、HashMap和HashTable區(qū)別??? 難度系數(shù):?
1、線程安全性不同
HashMap是線程不安全的,HashTable是線程安全的,其中的方法是Synchronized,在多線程并發(fā)的情況下,可以直接使用HashTable,但是使用HashMap時必須自己增加同步處理。
2、是否提供contains方法
HashMap只有containsValue和containsKey方法;HashTable有contains、containsKey和containsValue三個方法,其中contains和containsValue方法功能相同。
3、key和value是否允許null值
Hashtable中,key和value都不允許出現(xiàn)null值。HashMap中,null可以作為鍵,這樣的鍵只有一個;可以有一個或多個鍵所對應(yīng)的值為null。
4、數(shù)組初始化和擴(kuò)容機(jī)制
HashTable在不指定容量的情況下的默認(rèn)容量為11,而HashMap為16,Hashtable不要求底層數(shù)組的容量一定要為2的整數(shù)次冪,而HashMap則要求一定為2的整數(shù)次冪。
Hashtable擴(kuò)容時,將容量變?yōu)樵瓉淼?倍加1,而HashMap擴(kuò)容時,將容量變?yōu)樵瓉淼?倍。
16、線程的創(chuàng)建方式??? 難度系數(shù):?
繼承Thread類創(chuàng)建線程
實(shí)現(xiàn)Runnable接口創(chuàng)建線程
使用Callable和Future創(chuàng)建線程?? 有返回值
使用線程池創(chuàng)建線程
?
17、線程的狀態(tài)轉(zhuǎn)換有什么(生命周期)?? 難度系數(shù):?

1、新建狀態(tài)(New) :線程對象被創(chuàng)建后,就進(jìn)入了新建狀態(tài)。例如,Thread thread = new Thread()。
2、就緒狀態(tài)(Runnable): 也被稱為“可執(zhí)行狀態(tài)”。線程對象被創(chuàng)建后,其它線程調(diào)用了該對象的start()方法,從而來啟動該線程。例如,thread.start()。處于就緒狀態(tài)的線程,隨時可能被CPU調(diào)度執(zhí)行。
3、運(yùn)行狀態(tài)(Running):線程獲取CPU權(quán)限進(jìn)行執(zhí)行。需要注意的是,線程只能從就緒狀態(tài)進(jìn)入到運(yùn)行狀態(tài)。
4、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時停止運(yùn)行。直到線程進(jìn)入就緒狀態(tài),才有機(jī)會轉(zhuǎn)到運(yùn)行狀態(tài)。阻塞的情況分三種:
? ? ? 1.等待阻塞 -- 通過調(diào)用線程的wait()方法,讓線程等待某工作的完成。
? ? ? 2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(因?yàn)殒i被其它線程所占用),它會進(jìn)入同步阻塞狀態(tài)。
? ? ? 3.其他阻塞 -- 通過調(diào)用線程的sleep()或join()或發(fā)出了I/O請求時,線程會進(jìn)入到阻塞狀態(tài)。當(dāng)sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入就緒狀態(tài)。
5、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。
18、Java中有幾種類型的流??? 難度系數(shù):?

19、請寫出你最常見的5個RuntimeException??? 難度系數(shù):?
1、java.lang.NullPointerException
空指針異常;出現(xiàn)原因:調(diào)用了未經(jīng)初始化的對象或者是不存在的對象。
2、java.lang.ClassNotFoundException
指定的類找不到;出現(xiàn)原因:類的名稱和路徑加載錯誤;通常都是程序試圖通過字符串來加載某個類時可能引發(fā)異常。
3、java.lang.NumberFormatException
字符串轉(zhuǎn)換為數(shù)字異常;出現(xiàn)原因:字符型數(shù)據(jù)中包含非數(shù)字型字符。
4、java.lang.IndexOutOfBoundsException
數(shù)組角標(biāo)越界異常,常見于操作數(shù)組對象時發(fā)生。
5、java.lang.IllegalArgumentException
方法傳遞參數(shù)錯誤。
6、java.lang.ClassCastException
數(shù)據(jù)類型轉(zhuǎn)換異常。
20、談?wù)勀銓Ψ瓷涞睦斫??? 難度系數(shù):?
1、反射機(jī)制
所謂的反射機(jī)制就是java語言在運(yùn)行時擁有一項(xiàng)自觀的能力。通過這種能力可以徹底了解自身的情況為下一步的動作做準(zhǔn)備。
2、Java的反射機(jī)制的實(shí)現(xiàn)要借助于4個類:class,Constructor,F(xiàn)ield,Method;其中class代表的時類對 象,Constructor-類的構(gòu)造器對象,F(xiàn)ield-類的屬性對象,Method-類的方法對象。通過這四個對象我們可以粗略的看到一個類的各個組成部分。
3、Java反射的作用
在Java運(yùn)行時環(huán)境中,對于任意一個類,可以知道這個類有哪些屬性和方法。對于任意一個對象,可以調(diào)用它的任意一個方法。這種動態(tài)獲取類的信息以及動態(tài)調(diào)用對象的方法的功能來自于Java 語言的反射(Reflection)機(jī)制。
4、Java 反射機(jī)制提供功能
在運(yùn)行時判斷任意一個對象所屬的類。
在運(yùn)行時構(gòu)造任意一個類的對象。
在運(yùn)行時判斷任意一個類所具有的成員變量和方法。
在運(yùn)行時調(diào)用任意一個對象的方法
21、什么是 java 序列化,如何實(shí)現(xiàn) java 序列化??? 難度系數(shù):?
1、序列化是一種用來處理對象流的機(jī)制,所謂對象流也就是將對象的內(nèi)容進(jìn)行流化??梢詫α骰蟮膶ο筮M(jìn)行讀寫操作,也可將流化后的對象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決在對對象流進(jìn)行讀寫操作時所引發(fā)的問題。
2、序 列 化 的 實(shí) 現(xiàn) : 將 需 要 被 序 列 化 的 類 實(shí) 現(xiàn) Serializable 接 口 , 該 接 口 沒 有 需 要 實(shí) 現(xiàn) 的 方 法 , implements Serializable 只是為了標(biāo)注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構(gòu)造一個ObjectOutputStream(對象流)對象,接著,使用 ObjectOutputStream 對象的 writeObject(Object obj)方法就可以將參數(shù)為 obj 的對象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。
22、Http 常見的狀態(tài)碼??? 難度系數(shù):?
200 OK? ? ? //客戶端請求成功
301? ? ? Permanently Moved (永久移除),請求的 URL 已移走。Response 中應(yīng)該包含一個 Location URL, 說明資源現(xiàn)在所處的位置
302? ? ? Temporarily Moved? 臨時重定向
400? ? ? Bad Request //客戶端請求有語法錯誤,不能被服務(wù)器所理解
401? ? ? Unauthorized //請求未經(jīng)授權(quán),這個狀態(tài)代碼必須和 WWW-Authenticate 報頭域一起使用
403? ? ? Forbidden //服務(wù)器收到請求,但是拒絕提供服務(wù)
404? ? ? Not Found //請求資源不存在,eg:輸入了錯誤的 URL
500? ? ? Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯誤
503? ? ? Server Unavailable //服務(wù)器當(dāng)前不能處理客戶端的請求,一段時間后可能恢復(fù)正常
23、GET 和POST 的區(qū)別??? 難度系數(shù):?
1、GET 請求的數(shù)據(jù)會附在URL 之后(就是把數(shù)據(jù)放置在 HTTP 協(xié)議頭中),以?分割URL 和傳輸數(shù)據(jù),參數(shù)之間以&相連,如:login.action?name=zhagnsan&password=123456。POST 把提交的數(shù)據(jù)則放置在是 HTTP 包的包體中。
2、GET 方式提交的數(shù)據(jù)最多只能是 1024 字節(jié),理論上POST 沒有限制,可傳較大量的數(shù)據(jù)。其實(shí)這樣說是錯誤的,不準(zhǔn)確的:“GET 方式提交的數(shù)據(jù)最多只能是 1024 字節(jié)",因?yàn)?GET 是通過 URL 提交數(shù)據(jù),那么 GET 可提交的數(shù)據(jù)量就跟URL 的長度有直接關(guān)系了。而實(shí)際上,URL 不存在參數(shù)上限的問題,HTTP 協(xié)議規(guī)范沒有對 URL 長度進(jìn)行限制。這個限制是特定的瀏覽器及服務(wù)器對它的限制。IE 對URL 長度的限制是2083 字節(jié)(2K+35)。對于其他瀏覽器,如Netscape、FireFox 等,理論上沒有長度限制,其限制取決于操作系統(tǒng)的支持。
3、POST 的安全性要比GET 的安全性高。注意:這里所說的安全性和上面 GET 提到的“安全”不是同個概念。上面“安全”的含義僅僅是不作數(shù)據(jù)修改,而這里安全的含義是真正的 Security 的含義,比如:通過 GET 提交數(shù)據(jù),用戶名和密碼將明文出現(xiàn)在 URL 上,因?yàn)?1)登錄頁面有可能被瀏覽器緩存,(2)其他人查看瀏覽器的歷史紀(jì)錄,那么別人就可以拿到你的賬號和密碼了,除此之外,使用 GET 提交數(shù)據(jù)還可能會造成 Cross-site request forgery 攻擊。
4、Get 是向服務(wù)器發(fā)索取數(shù)據(jù)的一種請求,而 Post 是向服務(wù)器提交數(shù)據(jù)的一種請求,在 FORM(表單)中,Method
5、默認(rèn)為"GET",實(shí)質(zhì)上,GET 和 POST 只是發(fā)送機(jī)制不同,并不是一個取一個發(fā)!
24、Cookie 和Session 的區(qū)別??? 難度系數(shù):?
1、Cookie 是 web 服務(wù)器發(fā)送給瀏覽器的一塊信息,瀏覽器會在本地一個文件中給每個 web 服務(wù)器存儲 cookie。以后瀏覽器再給特定的 web 服務(wù)器發(fā)送請求時,同時會發(fā)送所有為該服務(wù)器存儲的 cookie
2、Session 是存儲在 web 服務(wù)器端的一塊信息。session 對象存儲特定用戶會話所需的屬性及配置信息。當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去
3、Cookie 和session 的不同點(diǎn)
無論客戶端做怎樣的設(shè)置,session 都能夠正常工作。當(dāng)客戶端禁用 cookie 時將無法使用 cookie
在存儲的數(shù)據(jù)量方面:session 能夠存儲任意的java 對象,cookie 只能存儲 String 類型的對象

高級篇下次分享,整理不易,感謝三連支持~!