- 相關(guān)推薦
經(jīng)常被遺忘的Java面試題
通常,在面試中,會遇到面試官提一些比較“偏冷”的基礎(chǔ)知識,因此,本文對一些容易被遺忘的問題進行歸納,希望可以幫助廣大程序員輕松應(yīng)對面試官的技術(shù)問題,以及提升編碼效率。
靜態(tài)類和靜態(tài)方法
如果一個類要被聲明為static的,只有一種情況,就是靜態(tài)內(nèi)部類。
靜態(tài)內(nèi)部類實際上與普通類(即類名必須與文件名一樣的頂級類)一樣,只是靜態(tài)內(nèi)部類在某一類的內(nèi)部定義了而已,既然是類,要想使用就必須實例化。概念上與靜態(tài)變量、靜態(tài)方法是不一樣的,不要被“靜態(tài)”兩個字迷惑了(不要以為凡是靜態(tài)的東西就不需要實例化就可以直接使用,靜態(tài)內(nèi)部類是有區(qū)別),而且只有靜態(tài)內(nèi)部類,而沒有靜態(tài)類(頂級類)的概念。
public class Singleton{
private Singleton(){}
private static class SingletonHolder{
private final static Singleton instance;
}
public Singleton getInstance(){
return SingletonHolder.instance;
}
}
public class Singleton{
private Singleton(){}
private static class SingletonHolder{
private final static Singleton instance;
}
public Singleton getInstance(){
return SingletonHolder.instance;
}
}
靜態(tài)方法只能訪問靜態(tài)成員,實例方法可以訪問靜態(tài)和實例成員。之所以不允許靜態(tài)方法訪問實例成員變量,是因為實例成員變量是屬于某個對象的,而靜態(tài)方法在執(zhí)行時,并不一定存在對象。靜態(tài)方法中也不能使用關(guān)鍵字this。
倒排索引
Inverted Index
如果翻譯成轉(zhuǎn)置索引可能更好懂,它就相當于做了矩陣轉(zhuǎn)置。
倒排索引是一種索引方法,被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射。
反射
反射API中提供的動態(tài)代理也是非常強大的功能,可以原生實現(xiàn)AOP中 的方法攔截功能。正如英文單詞reflection的含義一樣,使用反射API的時候就好像在看一個Java類在水中的倒影一樣。知道了Java類的內(nèi)部 結(jié)構(gòu)之后,就可以與它進行交互,包括創(chuàng)建新的對象和調(diào)用對象中的方法等。
這種交互方式與直接在源代碼中使用的效果是相同的,但是又額外提供了運行時刻的靈活性。使用反射的一個最大的弊端是性能比較差。相同的操作,用反射API所需的時間大概比直接的使用要慢一兩個數(shù)量級。不過現(xiàn)在的JVM實現(xiàn)中,反射操作的性能已經(jīng)有了很大的提升。
Java 反射API的第一個主要作用是獲取程序在運行時刻的內(nèi)部結(jié)構(gòu)。
多路歸并算法
歸并排序也是一種使用分治法來實現(xiàn)的有效排序算法,它是現(xiàn)代計算機創(chuàng)始人John von Neumann于1945年發(fā)明的。
歸并排序在眾多排序算法中既是穩(wěn)定排序,又有不錯的效率,同時,歸并排序不僅可以用于內(nèi)排序,還可以用于外排序。
歸并排序的思路如下(以二路歸并為例):
將數(shù)組劃均分為兩個子數(shù)組;
對兩個字數(shù)組進行排序;
將排序好的兩個字數(shù)組歸并。
所謂 N路歸并 是指將數(shù)組均分為N個子數(shù)組,將字數(shù)組排序后再歸并。因此二路歸并是歸并排序的最一般的情況。
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]
result.append(min(lone, rone))
if lone < rone:
lcur += 1
else:
rcur += 1
result += left[lcur:]
result += right[rcur:]
return result
枚舉類型
Enumerated Type
enum 類型不支持 public 和 protected 修飾符的構(gòu)造方法,因此構(gòu)造函數(shù)一定要是 private 或 friendly 的。也正因為如此,所以枚舉對象是無法在程序中通過直接調(diào)用其構(gòu)造方法來初始化的。
由于 enum 類型的值實際上是通過運行期構(gòu)造出對象來表示的,所以在 cluster 環(huán)境下,每個虛擬機都會構(gòu)造出一個同義的枚舉對象。因而在做比較操作時候就需要注意,如果直接通過使用等號 ( ‘ == ’ ) 操作符,這些看似一樣的枚舉值一定不相等,因為這不是同一個對象實例。
多線程
Java中實現(xiàn)多線程有兩種方法:繼承Thread類、實現(xiàn)Runnable接口,在程序開發(fā)中只要是多線程,肯定永遠以實現(xiàn)Runnable接口為主,因為實現(xiàn)Runnable接口相比繼承Thread類有如下優(yōu)勢:
1、可以避免由于Java的單繼承特性而帶來的局限;
2、增強程序的健壯性,代碼能夠被多個線程共享,代碼與數(shù)據(jù)是獨立的;
3、適合多個相同程序代碼的線程區(qū)處理同一資源的情況。
下面是通過實現(xiàn)Runnable接口實現(xiàn)的多線程程序,代碼如下:
lass MyThread implements Runnable{
private int ticket = 5;
public void run(){
for (int i=0;i<10;i++)
{
if(ticket > 0){
System.out.println("ticket = " + ticket--);
}
}
}
}
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
}
}
【經(jīng)常被遺忘的Java面試題】相關(guān)文章:
Java面試題(精選)12-04
Java 問答面試題12-04
Java原理面試題03-19
Java基礎(chǔ)面試題集錦12-02
Java基礎(chǔ)語法面試題03-19
最新2016年Java精選面試題11-17
Java開發(fā)崗位面試題匯總03-18
華為Java程序員面試題12-04
高級Java多線程面試題及回答11-30