首頁  >  文章  >  Java  >  常被遺忘的Java面試題總結

常被遺忘的Java面試題總結

黄舟
黄舟原創
2017-03-23 10:43:461407瀏覽

靜態類別和靜態方法

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

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

e.g.

public class Singleton{
    private Singleton(){}

    private static class SingletonHolder{
        private final static Singleton instance;
    }

    public Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

靜態方法只能存取靜態成員,實例方法可以存取靜態和實例成員。之所以不允許靜態方法存取實例成員變量,是因為實例成員變數是屬於某個物件的,而靜態方法在執行時,不一定存在物件。靜態方法中也不能使用關鍵字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)

非遞歸

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 修飾符的建構方法,因此建構子一定要是private 或friendly 的。也因為如此,所以枚舉物件是無法在程式中透過直接呼叫其構造方法來初始化的。

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

多線程

Java中實作多線程有兩種方法:繼承Thread類別、實作Runnable接口,在程式開發中只要是多線程,肯定永遠以實作Runnable介面為主,因為實作Runnable介面相比繼承Thread類別有以下優勢:

1、可以避免由於Java的單一繼承特性而帶來的限制;

2.增強程式的健全性,程式碼能夠被多個執行緒共享,程式碼與資料是獨立的;

3、適合多個相同程式碼的執行緒區處理同一資源的情況。

以下是透過實作Runnable介面實現的多執行緒程序,程式碼如下:

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();  
    }  
}

以上是常被遺忘的Java面試題總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn