1. 程式人生 > 其它 >面試彙總7.9

面試彙總7.9

1. 請你講講Java裡面的final關鍵字是怎麼用的?

當用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變數可以根據需要設為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。

“使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現版本中,會將final方法轉為內嵌呼叫。但是如果方法過於龐大,可能看不到內嵌呼叫帶來的任何效能提升。在最近的Java版本中,不需要使用final方法進行這些優化了。“

對於一個final變數,如果是基本資料型別的變數,則其數值一旦在初始化之後便不能更改;如果是引用型別的變數,則在對其初始化之後便不能再讓其指向另一個物件。

2. 請你談談關於Synchronized和Lock?

synchronized是Java的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。JDK1.5以後引入了自旋鎖、鎖粗化、輕量級鎖,偏向鎖來有優化關鍵字的效能。

Lock是一個介面,而synchronized是Java中的關鍵字,synchronized是內建的語言實現;synchronized在發生異常時,會自動釋放執行緒佔有的鎖,因此不會導致死鎖現象發生;而Lock在發生異常時,如果沒有主動通過unLock()去釋放鎖,則很可能造成死鎖現象,因此使用Lock時需要在finally塊中釋放鎖;Lock可以讓等待鎖的執行緒響應中斷,而synchronized卻不行,使用synchronized時,等待的執行緒會一直等待下去,不能夠響應中斷;通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。

3. 請你介紹一下volatile?

volatile關鍵字是用來保證有序性和可見性的。這跟Java記憶體模型有關。比如我們所寫的程式碼,不一定是按照我們自己書寫的順序來執行的,編譯器會做重排序,CPU也會做重排序的,這樣的重排序是為了減少流水線的阻塞的,引起流水阻塞,比如資料相關性,提高CPU的執行效率。需要有一定的順序和規則來保證,不然程式設計師自己寫的程式碼都不知帶對不對了,所以有happens-before規則,其中有條就是volatile變數規則:對一個變數的寫操作先行發生於後面對這個變數的讀操作;有序性實現的是通過插入記憶體屏障來保證的。可見性:首先Java記憶體模型分為,主記憶體,工作記憶體。比如執行緒A從主記憶體把變數從主記憶體讀到了自己的工作記憶體中,做了加1的操作,但是此時沒有將i的最新值重新整理會主記憶體中,執行緒B此時讀到的還是i的舊值。加了volatile關鍵字的程式碼生成的彙編程式碼發現,會多出一個lock字首指令。Lock指令對Intel平臺的CPU,早期是鎖匯流排,這樣代價太高了,後面提出了快取一致性協議,MESI,來保證了多核之間資料不一致性問題。

4. 請你介紹一下Syncronized鎖,如果用這個關鍵字修飾一個靜態方法,鎖住了什麼?如果修飾成員方法,鎖住了什麼?

synchronized修飾靜態方法以及同步程式碼塊的synchronized (類.class)用法鎖的是類,執行緒想要執行對應同步程式碼,需要獲得類鎖。
synchronized修飾成員方法,執行緒獲取的是當前呼叫該方法的物件例項的物件鎖。