備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

一、Java基本語法面試題

1. 是否可以從一個static方法內部發出對非static方法的調用

不可以。因為非static方法是要與對象關聯在一起的,必須創建一個對象後,才可以在該對象上進行方法調用,而static方法調用時不需要創建對象,可以直接調用。也就是說,當一個static方法被調用時,可能還沒有創建任何實例對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立。

2. Integer與int的區別

int是java提供的8種原始數據類型之一,Integer是java為int提供的封裝類。int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。

在JSP開發中,Integer的默認為null,所以用el表達式在文本框中顯示時,值為空白字符串,而int默認的默認值為0,所以用el表達式在文本框中顯示時,結果為0,所以,int不適合作為web層的表單數據的類型。

在Hibernate中,如果將OID定義為Integer類型,那麼Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm映射文件中設置其unsaved-value屬性為0。

3. 抽象類和接口有什麼區別

  1. 抽象類可以有構造方法,接口中不能有構造方法。
  2. 抽象類中可以有普通成員變量,接口中沒有普通成員變量
  3. 抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的,不能有非抽象的普通方法。
  4. 抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,雖然eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,並且默認即為public abstract類型。
  5. 抽象類中可以包含靜態方法,接口中不能包含靜態方法
  6. 抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是publicstatic final類型,並且默認即為publicstatic final類型。
  7. 一個類可以實現多個接口,但只能繼承一個抽象類。

4. String、StringBuffer與StringBuilder的區別

  1. String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象
  2. StringBuffer和StringBuilder底層是 char[]數組實現的
  3. StringBuffer是線程安全的,而StringBuilder是線程不安全的

5. final,finally,finalize的區別

  1. final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。內部類要訪問局部變量,局部變量必須定義成final類型。
  2. finally是異常處理語句結構的一部分,表示總是執行。
  3. finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。但是JVM不保證此方法總被調用.

6. error和exception有什麼區別

  • Error(錯誤)表示系統級的錯誤和程序不必處理的異常,是java運行環境中的內部錯誤或者硬件問題。比如:內存資源不足等。對於這種錯誤,程序基本無能為力,除了退出運行外別無選擇,它是由Java虛擬機拋出的。
  • Exception(違例)表示需要捕捉或者需要程序進行處理的異常,它處理的是因為程序設計的瑕疵而引起的問題或者在外的輸入等引起的一般性問題,是程序必須處理的。
  • Exception又分為運行時異常,受檢查異常。運行時異常,表示無法讓程序恢復的異常,導致的原因通常是因為執行了錯誤的操作,建議終止程序,因此,編譯器不檢查這些異常。受檢查異常,是表示程序可以處理的異常,也即表示程序可以修復(由程序自己接受異常並且做出處理), 所以稱之為受檢查異常。

7. Java中,throw和throws有什麼區別

  • throw代表的是動作,throws是狀態
  • throw用在方法中,而throws用在方法聲明中
  • throw只能拋出一種異常,而throws可以拋出多個

8. &和&&的區別?

  • &運算符有兩種用法:(1)按位與;(2)邏輯與。
  • &&運算符是短路與運算。 >如果&&左邊的表達式的值是false,右邊的表達式會被直接短路掉,不會進行運算。

9. switch能否用String做參數?

在 Java 7 之前, switch 只能支持byte,short,char,int 或者其對應的封裝類,以及 Enum 類型。在JAVA 7中,String 支持被加上了。

10. finalize方法什麼時候被調用?

在釋放對象佔用的內存之前,且對象的finalize()還沒被垃圾收集器調用過,則垃圾收集器會調用對象的finalize()方法。

11. 用最有效率的方法計算2乘以8?

2 << 3(左移3位相當於乘以2的3次方,右移3位相當於除以2的3次方)。

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

二、面向對象面試題

1. 面向對象的特徵有哪些方面

  • 抽象:抽象是將一類對象的共同特徵總結出來構造類的過程,包括數據抽象和行為抽象兩方面。抽象只關注對象有哪些屬性和行為,並不關注這些行為的細節是什麼。
  • 繼承:繼承是從已有類得到繼承信息創建新類的過程。提供繼承信息的類被稱為父類(超類、基類);得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件系統有了一定的延續性,同時繼承也是封裝程序中可變因素的重要手段。
  • 封裝:通常認為封裝是把數據和操作數據的方法綁定起來,對數據的訪問只能通過已定義的接口。面向對象的本質就是將現實世界描繪成一系列完全自治、封閉的對象。我們在類中編寫的方法就是對實現細節的一種封裝;我們編寫一個類就是對數據和數據操作的封裝。可以說,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡單的編程接口(可以想想普通洗衣機和全自動洗衣機的差別,明顯全自動洗衣機封裝更好因此操作起來更簡單;我們現在使用的智能手機也是封裝得足夠好的,因為幾個按鍵就搞定了所有的事情)。
  • 多態性:多態性是指允許不同子類型的對象對同一消息作出不同的響應。簡單的說就是用同樣的對象引用調用同樣的方法但是做了不同的事情。多態性分為編譯時的多態性和運行時的多態性。如果將對象的方法視為對象向外界提供的服務,那麼運行時的多態性可以解釋為:當A系統訪問B系統提供的服務時,B系統有多種提供服務的方式,但一切對A系統來說都是透明的。方法重載(overload)實現的是編譯時的多態性(也稱為前綁定),而方法重寫(override)實現的是運行時的多態性(也稱為後綁定)。運行時的多態是面向對象最精髓的東西,要實現多態需要做兩件事:1). 方法重寫(子類繼承父類並重寫父類中已有的或抽象的方法);2). 對象造型(用父類型引用引用子類型對象,這樣同樣的引用調用同樣的方法就會根據子類對象的不同而表現出不同的行為)。

2. 如何實現對象克隆?

有兩種方式:

  • 實現Cloneable接口並重寫Object類中的clone()方法;
  • 實現Serializable接口,通過對象的序列化和反序列化實現克隆,可以實現真正的深度克隆。

注意:基於序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優於使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來總是優於把問題留到運行時。

3. 講講類的實例化順序,比如父類靜態數據,父類構造函數,父類字段,子類靜態數據,子類構造函數,子類字段,當new的時候,他們的執行順序。

類的實例化順序:先靜態再父子

父類靜態數據->子類靜態數據->父類字段->子類字段->父類構造函數->子類構造函數

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

三、集合面試題

1. Collection和Collections的區別?

  • Collection是一個接口,它是Set、List等容器的父接口;
  • Collections是個一個工具類,提供了一系列的靜態方法來輔助容器操作,這些方法包括對容器的搜索、排序、線程安全化等等。

2. ArrayList和LinkedList有什麼區別

區別

  • ArrayList是實現了基於動態數組的數據結構,LinkedList是基於鏈表結構。
  • 對於隨機訪問的get和set方法,ArrayList要優於LinkedList,因為LinkedList要移動指針。
  • 對於新增和刪除操作add和remove,LinkedList比較佔優勢,因為ArrayList要移動數據。

性能差異

  • 對ArrayList和LinkedList而言,在列表末尾增加一個元素所花的開銷都是固定的。對ArrayList而言,主要是在內部數組中增加一項,指向所添加的元素,偶爾可能會導致對數組重新進行分配;而對LinkedList而言,這個開銷是統一的,分配一個內部Entry對象。
  • 在ArrayList集合中添加或者刪除一個元素時,當前的列表所所有的元素都會被移動。而LinkedList集合中添加或者刪除一個元素的開銷是固定的。
  • LinkedList集合不支持 高效的隨機隨機訪問(RandomAccess),因為可能產生二次項的行為。
  • ArrayList的空間浪費主要體現在在list列表的結尾預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗相當的空間

3. HashMap,怎麼擴容,怎麼處理數據衝突?

HashMap底層數據結構是基於數組+鏈表的(1.8之後還引入了紅黑樹),Node數組的初始化長度為16,負載因子為0.75,HashMap所能容納的最大數據量的Node(鍵值對)個數=Node數組初始化長度負載因子,當HashMap所能容納的最大數據量的Node個數大於Node數組初始化長度負載因子的時候,會調用resize()方法進行擴容,擴容後的HashMap容量是之前容量的兩倍。擴容的方法是創建一個新的數組替換原來的小數組,並把數據放入新數組。

HashMap通過對key的hash值進行高位運算和取模來定位鍵值對的存儲位置,有時兩個key會定位到相同的位置,表示發生了Hash碰撞。比較兩個key是否相等,如果相等直接覆蓋原來key的值。

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

四、多線程面試題

1. volatile關鍵字是否能保證線程安全?

否,volatile變量自身具有下列特性:

  • 可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最後的寫入。
  • 禁止進行指令重排序
  • 不保證原子性:對任意單個volatile變量的讀/寫具有原子性,但類似於volatile++這種符合操作不具有原子性。 多線程共享變量的讀寫是通過主內存進行復制到線程本地內存中和把本地內存中值寫入主內存中來實現的。

當寫一個volatile變量時,JMM(Java內存模型)會把該線程對應的本地內存中的共享變量值刷新到主內存。

當讀一個volatile變量時,JMM會把該線程對應的本地內存置為無效。線程接下來將從住內存中讀取共享變量。

2. Java中sleep和wait的區別

  • 來自不同的類 : sleep來自Thread類,是Thread類的靜態方法。而wait來自於object類。sleep是Thread的靜態方法,那個線程調用的了sleep,那個線程就會休眠.
  • 持有鎖:這一點很重要,sleep是沒有釋放鎖的,使得該線程仍然佔用這系統資源,wait方法則會釋放鎖,使得其他線程可以使用同步控制塊或者方法。sleep 不釋放系統資源並且有時間限制,需要調用sleep(milliseconds)來指定休眠時間 wait會釋放資源,並且進入線程等待池等待,這個時候其他線程可以佔用CPU,直到其他線程調用notify/notifyAll喚醒等待池中的線程,然後進入就緒隊列等待系統分配資源
  • 使用範圍: wait,notify,notifyAll只能在synchronized塊中或者synchronied控制的方法中調用。而sleep可以在任何地方調用

3. synchronized和lock的區別?

  • 主要相同點:Lock能完成synchronized所實現的所有功能。
  • 主要不同點:Lock有比synchronized更精確的線程予以和更好的性能。
  1. synchronized會自動釋放鎖,但是Lock一定要求程序員手工釋放,並且必須在finally從句中釋放。
  2. synchronized修飾方法時,表示同一個對象在不同的線程中,表現為同步隊列,如果實例化不同的對象,那麼synchronized就不會出現同步效果了。

4. 創建線程有幾種不同的方式?你喜歡哪一種?為什麼?

四種方式可以用來創建線程:

  • 通過繼承Thread類,優點:可以直接調用start方法啟動。缺點:繼承一個類後,不能再繼承別的類。需要重寫run方法。無返回值。
  • 實現Runnable接口,優點:可以實現多個接口或繼承一個類;缺點:不能直接啟動,要通過構造一個Thread把自己傳進去。需要重寫run方法,無返回值。
  • 實現Callable接口,優點:可以拋出異常,有返回值;缺點:只有jkd1.5以後才支持。需要重寫call方法。結合FutureTask和Thread類一起使用,最後調用start啟動。
  • 應用程序可以使用Executor框架來創建線程池,優點:非常高效的,很容易實現和使用。

5. 什麼是線程?

線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。程序員可以通過它進行多處理器編程,你可以使用多線程對運算密集型任務提速。

6. 線程和進程有什麼區別?

線程是進程的子集,一個進程可以有很多線程,每條線程並行執行不同的任務。不同的進程使用不同的內存空間,而所有的線程共享一片相同的內存空間。別把它和棧內存搞混,每個線程都擁有單獨的棧內存用來存儲本地數據。

7. Thread類中的start()和run()方法有什麼區別?

start()方法被用來啟動新創建的線程,而且start()內部調用了run()方法,這和直接調用run()方法的效果不一樣。當你調用run()方法的時候,只會是在原來的線程中調用,沒有新的線程啟動,start()方法才會啟動新線程。

8. Java中Runnable和Callable有什麼不同?

Runnable和Callable都代表那些要在不同的線程中執行的任務。Runnable從JDK1.0開始就有了,Callable是在JDK1.5增加的。它們的主要區別是Callable的 call() 方法可以返回值和拋出異常,而Runnable的run()方法沒有這些功能。Callable可以返回裝載有計算結果的Future對象.

9. Java中CyclicBarrier和CountDownLatch有什麼不同?

CyclicBarrier 和 CountDownLatch 都可以用來讓一組線程等待其它線程。與 CyclicBarrier 不同的是,CountdownLatch 不能重新使用。 CountDownLatch :允許一個或多個線程等待其他線程完成操作。 CyclicBarrier :同步屏障,它可以讓一組線程到達一個屏障(也可以叫做同步點)時被阻塞,直到最後一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續運行。

10. Java中interrupted和isInterrupted方法的區別?

interrupted() 和 isInterrupted()的主要區別是前者會將中斷狀態清除而後者不會。Java多線程的中斷機制是用內部標識來實現的,調用Thread.interrupt()來中斷一個線程就會設置中斷標識為true。當中斷線程調用靜態方法Thread.interrupted()來檢查中斷狀態時,中斷狀態會被清零。而非靜態方法isInterrupted()用來查詢其它線程的中斷狀態且不會改變中斷狀態標識。簡單的說就是任何拋出InterruptedException異常的方法都會將中斷狀態清零。無論如何,一個線程的中斷狀態有有可能被其它線程調用中斷來改變。

11. 為什麼wait和notify方法要在同步塊中調用?

主要是因為Java API強制要求這樣做,如果你不這麼做,你的代碼會拋出IllegalMonitorStateException異常。還有一個原因是為了避免wait和notify之間產生競態條件。

寫在最後

本次面試題分享到此為止,限於篇幅,沒法在這裡給大家分享更多的面試題; 之前很多粉絲一直私信我讓我整理一些面試題,近些天終於整理好了,筆者整理了一份包含Kafka、Mysql、Tomcat、Docker、Spring、MyBatis、Nginx、Netty、Dubbo、Redis、Netty、Spring cloud、分佈式、高併發、性能調優、微服務等架構技術的面試題和部分視頻學習資料;

需要的朋友請幫助轉發一些,然後私信我 【學習】 即可免費領取!

需要的朋友請幫助轉發一些,然後私信我 【學習】 即可免費領取!

需要的朋友請幫助轉發一些,然後私信我 【學習】 即可免費領取!

以下是部分面試資料截圖

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程

備戰雙十一,京東Java開發崗面試題:語法+面向對象+集合+多線程


分享到:


相關文章: