閱讀936 返回首頁    go 阿裏雲 go 技術社區[雲棲]


收集Java麵試題知識點(Java基礎部分二)

1、用最有效率的方法算出2乘以8等於幾?

2 << 3
因為將一個數左移n位,就相當於乘以了2的n次方,那麼,一個數乘以8隻要將其左移3位即可,而位運算CPU直接支持的,效率最高,所以,2乘以8等於幾的最效率的方法是2 << 3。
但需要注意的是,如果這個數字本身已經很大,比如本身已經是2的30次方了,此時再用這種位移運算就可能導致“溢出”,這樣就得不到正確結果了。

2、使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?

使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。例如,對於如下語句:
final StringBuilder a=new StringBuilder (“immutable”);
執行如下語句將報告編譯錯誤:
a = new StringBuilder (“”);
但如下語句則是完全正確的
a.append(“fkjava.org”);
有人希望在定義方法的形參時,通過final修飾符來阻止方法內部修改傳進來的實參:
public void method(final StringBuilder param)
{
}
實際上這沒有用,在該方法內部仍然可以增加如下代碼來修改實參對象:
param.append(“fkjava.org”);

3、”==”和equals方法究竟有什麼區別?

==操作符的功能有兩個:
A.如果==的兩邊都是基本類型變量、包裝類對象所組成的表達式,==用於比較兩邊的表達式的值是否相等——隻要兩邊的表達式的值相等,即使數據類不同,該運算符也會返回true。
B.如果==的兩邊是引用類型的變量,==用於判斷這兩個引用類型的變量是否引用同一塊內存,隻有當它們引用同一塊內存時,==才會返回true。
而equals()則是一個Java.lang.Object類的一個方法,因此任何Java對象都可調用該方法與其他對象進行比較。java.lang.Object類的equals方法的實現代碼如下:
boolean equals(Object o)
{
return this==o;
}
從上麵代碼可以看出,如果一個類沒有重寫java.lang.Object的equals()方法時,此時equals()方法的比較結果與==的比較結果是相同的。
但Java允許任何類重寫equals()方法,重寫該方法就是讓程序員來自己決定兩個對象相等的標準。開發者重寫equals()方法就可以根據業務要求來決定兩個對象是否“相等”。

4、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應,例如,ceil的英文意義是天花板,該方法就表示向上取整,所以,Math.ceil(11.3)的結果為12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,所以,Math.floor(11.6)的結果為11,Math.floor(-11.6)的結果是-12;最難掌握的是round方法,它表示“四舍五入”,算法為Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,所以,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。

5、請說出作用域public,private,protected,以及不寫時的區別

這四個作用域的可見範圍如下表所示。

作用域 當前類 同一package 子類 全局
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √ × × ×

說明:如果在修飾的元素上麵沒有寫任何訪問修飾符,則表示default。
隻要記住訪問權限由小到大依次是private → default → protected → public,然後再記住Java存在的4個訪問範圍,就很容易畫出上麵的表格了。

6、外部類能用private、protected修飾嗎?內部類可以用private、protected修飾嗎?

外部類不能用private、protected修飾不能。內部類能用private、protected修飾不能。
外部類的上一級程序單位是包,因此它隻有兩個使用範圍:包內和包外,因此它隻能用public(表示可以在全局位置使用)和默認修飾符(default,表示隻能被同一個包的其他類使用)修飾。

7、GC是什麼? 為什麼要有GC?   

GC是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或係統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的。
Java的System類和Runtime類都提供了“通知”程序進行垃圾回收的方法,例如如下代碼:
Systme.gc();

Runtime.getInstance().gc();
但這兩個方法隻是“通知”Java進行垃圾回收,但實際上JVM何時進行垃圾回收,還是由JVM自己決定。

8、垃圾回收的優點和原理。並考慮2種回收機製。

傳統的C/C++等編程語言,需要程序員負責回收已經分配的內存。顯式進行垃圾回收是一件比較困難的事情,因為程序員並不總是知道內存應該何時被釋放。如果一些分配出去的內存得不到及時回收,就會引起係統運行速度下降,甚至導致程序癱瘓,這種現象被稱為內存泄漏。總體而言,顯式進行垃圾回收主要有如下兩個缺點:
A.程序忘記及時回收無用內存,從而導致內存泄漏,降低係統性能。
B.程序錯誤地回收程序核心類庫的內存,從而導致係統崩潰。
與C/C++程序不同,Java語言不需要程序員直接控製內存回收,Java程序的內存分配和回收都是由JRE在後台自動進行的。JRE會負責回收那些不再使用的內存,這種機製被稱為垃圾回收(Garbage Collection,也被稱為GC)。通常JRE會提供一條後台線程來進行檢測和控製,一般都是在CPU空閑或內存不足時自動進行垃圾回收,而程序員無法精確控製垃圾回收的時間和順序等。
實際上,垃圾回收機製不可能實時檢測到每個Java對象的狀態,當一個對象失去引用後,它也不會被立即回收,隻有等接下來垃圾回收器運行時才會被回收。
對於一個垃圾回收器的設計算法來說,大致有如下可供選擇的設計:
A.串行回收(Serial)和並行回收(Parallel):串行回收就是不管係統有多少個CPU,始終隻用一個CPU來執行垃圾回收操作;而並行回收就是把整個回收工作拆分成多部分,每個部分由一個CPU負責,從而讓多個CPU並行回收,並行回收的執行效率很高,但複雜度增加,另外也有其他一些副作用,比如內存碎片會增加。
B.並發執行(Concurrent)和應用程序停止(Stop-the-world):。Stop-the-world的垃圾回收方式在執行垃圾回收的同時會導致應用程序的暫停。並發執行的垃圾回收雖然不會導致應用程序的暫停,但由於並發執行垃圾回收需要解決和應用程序的執行衝突(應用程序可能會在垃圾回收的過稱中修改對象),因此並發執行垃圾回收的係統開銷比Stop-the-world更好,而且執行時也需要更多的堆內存。
C.壓縮(Compacting)和不壓縮(Non-compacting)和複製(Copying):為了減少內存碎片,支持壓縮的垃圾回收器會把所有的活對象搬遷到一起,然後將之前占用的內存全部回收。不壓縮式的垃圾回收器隻是回收內存,這樣回收回來的內存不可能是連續的,因此將會有較多的內存碎片。較之壓縮式的垃圾回收,不壓縮式的垃圾回收回收內存快了,而分配內存時就會更慢,而且無法解決內存碎片的問題。複製式的垃圾回收會將所有可達對象複製到另一塊相同的內存中,這種方式的優點是垃圾及回收過程不會產生內存碎片,但缺點也很明顯,需要拷貝數據和額外的內存。

9、什麼時候用assert。

assertion(斷言)在軟件開發中是一種常用的調試方式,很多開發語言中都支持這種機製。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值為true;如果該值為false,說明程序已經處於不正確的狀態下,assert將給出警告或退出。
Java的assert是關鍵字。
public class TestAssert
{
public static void main(String[] args)
{
int a = 5;
//斷言a>3
assert a > 3;
//斷言a<3,否則顯示a不小於3,且a的值為:” + a
assert a < 3 : “a不小於3,且a的值為:” + a;
}
}
從上麵代碼可以看出,assert的兩個基本用法如下:
assert logicExp;
asert logicExp : expr;
A.第一個直接進行斷言,
B.第二個也是進行斷言,但當斷言失敗失敗時顯示特定信息。
最後要指出:
雖然assert是JDK1.4新增的關鍵字,但有一點非常重要:
java命令默認不啟動斷言,
為了啟動用戶斷言,應該在運行java命令時增加-ea(Enable Assert)選項。
為了啟動係統斷言,應該在運行java命令時增加-esa(Enable System Assert)選項。

10、序列化接口的id有什麼用?

反序列化Java對象時必須提供該對象的class文件,現在的問題是隨著項目的升級,係統的class文件也會升級,Java如何保證兩個class文件的兼容性?
Java序列化機製允許為序列化類提供一個private static final的serialVersionUID值,該Field值用於標識該Java類的序列化版本,也就是說如果一個類升級後,隻要它的serialVersionUID Field值保持不變,序列化機製也會把它們當成同一個序列化版本。

最後更新:2017-08-28 09:03:44

  上一篇:go  View(視圖 MongoDB 文檔翻譯和解讀)
  下一篇:go  Java 25天基礎-DAY 04