又是一季 「金三銀四」 ,你面試了嗎?java
Q1:String、StringBuffer、StringBuilder 有什麼區別?git
Tips:首先要整理出 String 的基本特性,Immutable、不可變等特性,其次是後二者與前者的區別,最後是 StringBuffer 與 StringBuilder 之間的區別,從安全和併發的角度去談程序員
Answer:String 是 Java 中基礎類型之一,它提供了咱們關於字符串構建和處理的大部分邏輯,本質上在內部就是一個 final 修飾的字符數組,一旦初始化就不在容許修改,因此咱們日常的手動字符串拼接其實都是生成了一個新的字符串對象,這個叫字符串的不可變性。StringBuilder 相比於 String,內部的字符數組再也不修飾爲 final,這也就方便了各類 append 操做,經過動態擴容內部字符數組避免每一次拼接都產生新的 String 對象(動態擴容每次會擴容一倍,至少保證必定時間內不須要從新分配內存),StringBuffer 相對於 StringBuilder,內部全部方法都加上了 synchronized 保證併發安全性,固然犧牲的就是性能。github
可能追問:String 爲何設計成不可變的?面試
一、jvm 中有常量池的概念,好比 String a = "abc",那麼 abc 編譯的時候會進入常量池,a 引用指向常量池,當我在別的地方定義 String b = "abc",你會發現 a 和 b 指向同一塊內存,若是字符串可變,那麼 a 變化後,b 就會發現本身的值變化了,這是不合理的數組
二、多線程操做字符串,每次都是建立新的字符串,不存在併發安全問題安全
Q2:強引用、軟引用、弱引用、虛引用有什麼區別?具體使用場景是什麼?微信
Tips:這道面試題,屬於既偏門又很是高頻的一道題目。說它偏門,是由於在大多數應用開發中,不多直接操做各類不一樣引用,雖然咱們使用的類庫、框架可能利用了其機制。它被頻繁問到,是由於這是一個綜合性的題目,既考察了咱們對基礎概念的理解,也考察了對底層對象生命週期、垃圾收集機制等的掌握。markdown
Answer:不一樣的引用類型,主要體現的是對象不一樣的可達性(reachable)狀態和對垃圾收集的影響。這些引用共同的父類是 ReferenceQueue多線程
強引用:咱們平常程序中使用的最多的引用,這種引用永遠不會被 GC 回收,好比存在一個強引用 a 指向一個數組,那麼只要 a 不被賦值 null,也就是不丟失這個強引用,此數組永遠不會被回收內存
軟引用:當系統發生 GC 時,若是內存仍然不夠新對象的分配,會收集掉這部分的引用對象
弱引用:當系統發生 GC 時,不論整理後的內存是否充足,依然會回收掉這部分引用對象
虛引用:虛引用指向的對象,甚至沒法再次獲取到該引用對象,每每和一個隊列共同使用,在引用的對象被回收的時候,GC 會添加該對象到隊列中,至關因而告知系統此對象是什麼時候回收掉的
Q3:談談 Java 反射機制,動態代理是基於什麼原理?
Tips:反射是一個比較底層的機制,涉及到 jvm 內存區,動態代理是須要使用到反射的,兩種不一樣的代理方式之間的區別與聯繫
Answer:jvm 堆內存中有一塊「方法區」,用於存放類的定義元數據,以及類的一些靜態字段的值,反射本質上就是根據類的全路徑名從方法區讀出類的基本定義,動態代理分兩種,jdk 自帶動態代理實現和 cglib 動態代理:
jdk 動態代理只能爲接口作代理,緣由是運行時會生成一個類,這個類繼承 Proxy,並在構造時傳入一個 InvocationHandler 實例保存在父類 Proxy protected字段中用於完成代理邏輯;jdk 這個代理的肯定很明顯,不能爲類作代理只能爲接口作代理,
cglib 其實也相似,有一個 MethodInterceptor 用於自定義代理邏輯,只不過 cglib 生成的代理類直接繼承被代理類,並基於 fastclass 而不是反射提高調用性能
fastclass 其實就是對類中方法索引化,每個方法對應一個索引,調用的時候不須要反射,直接根據索引知道調用哪一個方法
關注公衆不迷路,一個愛分享的程序員。 公衆號回覆「1024」加做者微信一塊兒探討學習! 每篇文章用到的全部案例代碼素材都會上傳我我的 github github.com/SingleYam/o… 歡迎來踩!
更多面試題以及做者的做答,關注公衆號,後臺回覆關鍵詞 「面試題」,免費領取!若是對你有用,記得點贊關注讚揚哦~
有不一樣的理解,也歡迎你加做者微信,一塊兒探討交流,後臺回覆 「1024」 獲取做者微信二維碼。