當前位置:才華齋>計算機>java語言>

經常被遺忘的Java面試題

java語言 閱讀(2.76W)

通常,在面試中,會遇到面試官提一些比較“偏冷”的基礎知識,因此,本文對一些容易被遺忘的問題進行歸納,希望可以幫助廣大程式設計師輕鬆應對面試官的技術問題,以及提升編碼效率。

經常被遺忘的Java面試題

  靜態類和靜態方法

如果一個類要被宣告為static的,只有一種情況,就是靜態內部類。

靜態內部類實際上與普通類(即類名必須與檔名一樣的頂級類)一樣,只是靜態內部類在某一類的內部定義了而已,既然是類,要想使用就必須例項化。概念上與靜態變數、靜態方法是不一樣的,不要被“靜態”兩個字迷惑了(不要以為凡是靜態的東西就不需要例項化就可以直接使用,靜態內部類是有區別),而且只有靜態內部類,而沒有靜態類(頂級類)的概念。

public class Singleton{

private Singleton(){}

private static class SingletonHolder{

private final static Singleton instance;

}

public Singleton getInstance(){

return ance;

}

}

public class Singleton{

private Singleton(){}

private static class SingletonHolder{

private final static Singleton instance;

}

public Singleton getInstance(){

return ance;

}

}

靜態方法只能訪問靜態成員,例項方法可以訪問靜態和例項成員。之所以不允許靜態方法訪問例項成員變數,是因為例項成員變數是屬於某個物件的,而靜態方法在執行時,並不一定存在物件。靜態方法中也不能使用關鍵字this。

  倒排索引

Inverted Index

如果翻譯成轉置索引可能更好懂,它就相當於做了矩陣轉置。

倒排索引是一種索引方法,被用來儲存在全文搜尋下某個單詞在一個文件或者一組文件中的儲存位置的對映。

  反射

反射API中提供的動態代理也是非常強大的功能,可以原生實現AOP中 的方法攔截功能。正如英文單詞reflection的含義一樣,使用反射API的時候就好像在看一個Java類在水中的倒影一樣。知道了Java類的內部 結構之後,就可以與它進行互動,包括建立新的物件和呼叫物件中的方法等。

這種互動方式與直接在原始碼中使用的效果是相同的,但是又額外提供了執行時刻的靈活性。使用反射的.一個最大的弊端是效能比較差。相同的操作,用反射API所需的時間大概比直接的使用要慢一兩個數量級。不過現在的JVM實現中,反射操作的效能已經有了很大的提升。

Java 反射API的第一個主要作用是獲取程式在執行時刻的內部結構。

  多路歸併演算法

歸併排序也是一種使用分治法來實現的有效排序演算法,它是現代計算機創始人John von Neumann於1945年發明的。

歸併排序在眾多排序演算法中既是穩定排序,又有不錯的效率,同時,歸併排序不僅可以用於內排序,還可以用於外排序。

歸併排序的思路如下(以二路歸併為例):

將陣列劃均分為兩個子陣列;

對兩個字陣列進行排序;

將排序好的兩個字陣列歸併。

所謂 N路歸併 是指將陣列均分為N個子陣列,將字陣列排序後再歸併。因此二路歸併是歸併排序的最一般的情況。

e.g.

def msort(array):

length = len(array)

if length == 1:

return array

else:

mid = length / 2

left = msort(array[0: mid])

right = msort(array[mid: length])

return merge(left, right)123

def msort(array):

length = len(array)

step = 1

while step < length:

for left in range(0, length - step, 2 * step):

result = merge(array[left:left + step],

array[left + step: min(left + 2 * step,

length)])

array = array[0:left] + result + array[min(left + 2 *

step, length)]

step = step * 2

return array

def merge(left, right):

llen = len(left)

lcur = 0

rlen = len(right)

rcur = 0

result = []

while lcur < llen and rcur < rlen:

lone = left[lcur]

rone = right[rcur]

nd(min(lone, rone))

if lone < rone:

lcur += 1

else:

rcur += 1

result += left[lcur:]

result += right[rcur:]

return result

  列舉型別

Enumerated Type

enum 型別不支援 public 和 protected 修飾符的構造方法,因此建構函式一定要是 private 或 friendly 的。也正因為如此,所以列舉物件是無法在程式中通過直接呼叫其構造方法來初始化的。

由於 enum 型別的值實際上是通過執行期構造出物件來表示的,所以在 cluster 環境下,每個虛擬機器都會構造出一個同義的列舉物件。因而在做比較操作時候就需要注意,如果直接通過使用等號 ( ‘ == ’ ) 操作符,這些看似一樣的列舉值一定不相等,因為這不是同一個物件例項。