阿里歷年經典Java面試題彙總

Volatile的特徵:html

A、禁止指令重排(有例外) 
B、可見性java

Volatile的內存語義:算法

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


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


Volatile的重排序數組

一、當第二個操做爲volatile寫操作時,無論第一個操做是什麼(普通讀寫或者volatile讀寫),都不能進行重排序。這個規則確保volatile寫以前的全部操做都不會被重排序到volatile以後;安全

二、當第一個操做爲volatile讀操做時,無論第二個操做是什麼,都不能進行重排序。這個規則確保volatile讀以後的全部操做都不會被重排序到volatile以前;微信

三、當第一個操做是volatile寫操做時,第二個操做是volatile讀操做,不能進行重排序。併發

這個規則和前面兩個規則一塊兒構成了:兩個volatile變量操做不可以進行重排序;app

除以上三種狀況之外能夠進行重排序。

好比:

一、第一個操做是普通變量讀/寫,第二個是volatile變量的讀; 
二、第一個操做是volatile變量的寫,第二個是普通變量的讀/寫;


內存屏障/內存柵欄

內存屏障(Memory Barrier,或有時叫作內存柵欄,Memory Fence)是一種CPU指令,用於控制特定條件下的重排序和內存可見性問題。Java編譯器也會根據內存屏障的規則禁止重排序。(也就是讓一個CPU處理單元中的內存狀態對其它處理單元可見的一項技術。)

內存屏障能夠被分爲如下幾種類型:

LoadLoad屏障:對於這樣的語句Load1; LoadLoad; Load2,在Load2及後續讀取操做要讀取的數據被訪問前,保證Load1要讀取的數據被讀取完畢。

StoreStore屏障:對於這樣的語句Store1; StoreStore; Store2,在Store2及後續寫入操做執行前,保證Store1的寫入操做對其它處理器可見。

LoadStore屏障:對於這樣的語句Load1; LoadStore; Store2,在Store2及後續寫入操做被刷出前,保證Load1要讀取的數據被讀取完畢。

StoreLoad屏障:對於這樣的語句Store1; StoreLoad; Load2,在Load2及後續全部讀取操做執行前,保證Store1的寫入對全部處理器可見。它的開銷是四種屏障中最大的。

在大多數處理器的實現中,這個屏障是個萬能屏障,兼具其它三種內存屏障的功能。

內存屏障阻礙了CPU採用優化技術來下降內存操做延遲,必須考慮所以帶來的性能損失。爲了達到最佳性能,最好是把要解決的問題模塊化,這樣處理器能夠按單元執行任務,而後在任務單元的邊界放上全部須要的內存屏障。採用這個方法可讓處理器不受限的執行一個任務單元。合理的內存屏障組合還有一個好處是:緩衝區在第一次被刷後開銷會減小,由於再填充改緩衝區不須要額外工做了。


happens-before原則


Java是如何實現跨平臺的?

跨平臺是怎樣實現的呢?這就要談及Java虛擬機(Java Virtual Machine,簡稱 JVM)。

JVM也是一個軟件,不一樣的平臺有不一樣的版本。咱們編寫的Java源碼,編譯後會生成一種 .class 文件,稱爲字節碼文件。Java虛擬機就是負責將字節碼文件翻譯成特定平臺下的機器碼而後運行。也就是說,只要在不一樣平臺上安裝對應的JVM,就能夠運行字節碼文件,運行咱們編寫的Java程序。

而這個過程當中,咱們編寫的Java程序沒有作任何改變,僅僅是經過JVM這一」中間層「,就能在不一樣平臺上運行,真正實現了」一次編譯,處處運行「的目的。

JVM是一個」橋樑「,是一個」中間件「,是實現跨平臺的關鍵,Java代碼首先被編譯成字節碼文件,再由JVM將字節碼文件翻譯成機器語言,從而達到運行Java程序的目的。

注意:編譯的結果不是生成機器碼,而是生成字節碼,字節碼不能直接運行,必須經過JVM翻譯成機器碼才能運行。不一樣平臺下編譯生成的字節碼是同樣的,可是由JVM翻譯成的機器碼卻不同。

因此,運行Java程序必須有JVM的支持,由於編譯的結果不是機器碼,必需要通過JVM的再次翻譯才能執行。即便你將Java程序打包成可執行文件(例如 .exe),仍然須要JVM的支持。

注意:跨平臺的是Java程序,不是JVM。JVM是用C/C++開發的,是編譯後的機器碼,不能跨平臺,不一樣平臺下須要安裝不一樣版本的JVM。


手機掃二維碼登陸是怎麼實現的?

參考:http://www.jianshu.com/p/7f072ac61763


Java 線程有哪些狀態,這些狀態之間是如何轉化的?

  1. 新建(new):新建立了一個線程對象。

  2. 可運行(runnable):線程對象建立後,其餘線程(好比main線程)調用了該對象的start()方法。該狀態的線程位於可運行線程池中,等待被線程調度選中,獲取cpu 的使用權 。

  3. 運行(running):可運行狀態(runnable)的線程得到了cpu 時間片(timeslice) ,執行程序代碼。

  4. 阻塞(block):阻塞狀態是指線程由於某種緣由放棄了cpu 使用權,也即讓出了cpu timeslice,暫時中止運行。直到線程進入可運行(runnable)狀態,纔有機會再次得到cpu timeslice 轉到運行(running)狀態。阻塞的狀況分三種:

(一). 等待阻塞:運行(running)的線程執行o.wait()方法,JVM會把該線程放入等待隊列(waitting queue)中。

(二). 同步阻塞:運行(running)的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池(lock pool)中。

(三). 其餘阻塞:運行(running)的線程執行Thread.sleep(long ms)或t.join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入可運行(runnable)狀態。

  1. 死亡(dead):線程run()、main() 方法執行結束,或者因異常退出了run()方法,則該線程結束生命週期。死亡的線程不可再次復生。


List接口、Set接口和Map接口的區別

參考:http://blog.csdn.net/zcg_java/article/details/43232251


Cookie和Session的區別?

參考:http://blog.csdn.net/axin66ok/article/details/6175522


Java中的equals和hashCode方法詳解

參考:http://www.cnblogs.com/Qian123/p/5703507.html


Java中CAS算法

參考:http://www.kancloud.cn/seaboat/java-concurrent/117870


TimSort原理

參考:http://suo.im/532OHc


comparable與comparator的區別?

參考:http://www.cnblogs.com/szlbm/p/5504634.html


手寫單例模式(線程安全)

參考:http://www.cnblogs.com/hupp/p/4487521.html


Java線程間的通訊方式?

參考1:http://www.cnblogs.com/mengdd/archive/2013/02/20/2917956.html

參考2:http://www.jb51.net/article/84213.htm


Java8的內存分代改進

參考:http://blog.csdn.net/chlu113/article/details/51890469


對Java內存模型的理解以及其在併發當中的做用?

參考:http://www.cnblogs.com/_popc/p/6096517.html


Arrays和Collections 對於sort的不一樣實現原理?

一、Arrays.sort() 
該算法是一個通過調優的快速排序,此算法在不少數據集上提供N*log(N)的性能,這致使其餘快速排序會下降二次型性能。

二、Collections.sort() 
該算法是一個通過修改的合併排序算法(其中,若是低子列表中的最高元素效益高子列表中的最低元素,則忽略合併)。此算法可提供保證的N*log(N)的性能,此實現將指定列表轉儲到一個數組中,而後再對數組進行排序,在重置數組中相應位置處每一個元素的列表上進行迭代。


Java中object經常使用方法

一、clone() 
二、equals() 
三、finalize() 
四、getclass() 
五、hashcode() 
六、notify() 
七、notifyAll() 
八、toString()


對於Java中多態的理解

所謂多態就是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量到底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。由於在程序運行時才肯定具體的類,這樣,不用修改源程序代碼,就可讓引用變量綁定到各類不一樣的類實現上,從而致使該引用調用的具體方法隨之改變,即不修改程序代碼就能夠改變程序運行時所綁定的具體代碼,讓程序能夠選擇多個運行狀態,這就是多態性。

多態的定義:指容許不一樣類的對象對同一消息作出響應。即同一消息能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。(發送消息就是函數調用)

Java實現多態有三個必要條件:繼承、重寫、父類引用指向子類對象。

繼承:在多態中必須存在有繼承關係的子類和父類。

重寫:子類對父類中某些方法進行從新定義,在調用這些方法時就會調用子類的方法。

父類引用指向子類對象:在多態中須要將子類的引用賦給父類對象,只有這樣該引用纔可以具有技能調用父類的方法和子類的方法。

實現多態的技術稱爲:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。

多態的做用:消除類型之間的耦合關係。


Session機制?

參考 :http://justsee.iteye.com/blog/1570652


Java序列化與反序列化是什麼?爲何須要序列化與反序列化?如何實現Java序列化與反序列化?

參考 : http://blog.csdn.net/wangloveall/article/details/7992448/


Spring AOP 實現原理?

參考 :http://blog.csdn.net/moreevan/article/details/11977115/


Servlet 工做原理?

參考:http://www.ibm.com/developerworks/cn/java/j-lo-servlet/


Java NIO和IO的區別?

參考:http://www.jb51.net/article/50621.htm


Java中堆內存和棧內存區別?

參考:http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html


反射講一講,主要是概念,都在哪須要反射機制,反射的性能,如何優化?

反射機制的定義:

是在運行狀態中,對於任意的一個類,都可以知道這個類的全部屬性和方法,對任意一個對象都可以經過反射機制調用一個類的任意方法,這種動態獲取類信息及動態調用類對象方法的功能稱爲java的反射機制。

反射的做用:

一、動態地建立類的實例,將類綁定到現有的對象中,或從現有的對象中獲取類型。

二、應用程序須要在運行時從某個特定的程序集中載入一個特定的類。


如何保證RESTful API安全性 ?

參考: http://blog.csdn.net/ywk253100/article/details/25654101


如何預防Mysql注入?

參考:http://www.jb51.net/article/87948.htm

我有一個微信公衆號,常常會分享一些Java技術相關的乾貨;若是你喜歡個人分享,能夠用微信搜索「Java團長」或者「javatuanzhang」關注。

相關文章
相關標籤/搜索