1. 程式人生 > >java面試題基礎篇

java面試題基礎篇

static特點

隨著類的載入而載入;優先於物件存在;被所有物件所共享;可以直接被類名呼叫。
靜態方法只能訪問靜態成員,非靜態方法既可以訪問靜態也可以訪問非靜態。
靜態方法中不可以定義this super關鍵字,因為靜態優先於物件存在,所以靜態方法中不可以出現this。

多型

多型可以理解為事物存在的多種體現形式,父類的引用指向了自己的子類物件;父類的引用也可以接收自己子類的物件
好處:提高了程式碼的擴充套件性。
弊端:父類的引用只能訪問父類中有的成員(父類引用無法呼叫子類中特有的方法)。

陣列和集合的區別

陣列可以儲存基本資料型別和物件,它是一個線性佇列,可以快速訪問其中的元素,陣列建立之後,長度固定,不可改變。

容器只用於儲存物件,集合的長度是可變的,集合可以儲存不同型別的物件,集合的長度並不是固定的,可以便捷的新增刪除,功能更加強大。

Java垃圾回收機制

Java程式記憶體主要分兩部分,堆和非堆。一般new的物件和陣列都是在堆中的,而GC主要回收的記憶體也是這塊堆記憶體。

堆記憶體模型

堆記憶體由垃圾回收器的自動記憶體管理系統回收。

堆記憶體分為兩大部分:新生代和老年代。比例為1:2。

老年代主要存放應用程式中生命週期長的存活物件。

新生代又分為三個部分:一個Eden區和兩個Survivor區,比例為8:1:1。

Eden區存放新生的物件。

可回收物件的判定

1. 引用計數演算法

給物件中新增一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的物件就是不可能再被使用的。

優點是簡單,高效

缺點是很難處理迴圈引用,比如相互引用的兩個物件則無法釋放。

2. 可達性分析演算法(根搜尋演算法)

為了解決上面的迴圈引用問題,Java採用了一種新的演算法:可達性分析演算法。

從GC Roots(每種具體實現對GC Roots有不同的定義)作為起點,向下搜尋它們引用的物件,可以生成一棵引用樹,樹的節點視為可達物件,反之視為不可達。

什麼是事務?事務有那些特點?

事務:

單個邏輯單元執行的一系列操作,要麼全部執行,要麼全部不執行。

特點:

原子性(Atomicity):事務中各元素不可分割,全部執行成功或者撤銷所有的操作

一致性(Consistency):事務完成後資料保持一致的狀態

隔離性(Isolation):事務是相對獨立的,對某資料進行修改時,其他事務不變

永續性(Durability):事務完成後對系統的影響是永久性的。

事務的使用場景在什麼地方?

當一個業務邏輯包括多個數據庫操作的時候,而且需要保證每個資料表操作都執行的成功進行下一個操作,這個時候可以使用事務

Overload 和 Override 的區別。

Overload 是過載的意思,Override 是覆蓋的意思,也就是重寫。

過載 Overload 表示同一個類中可以有多個名稱相同的方法,但這些方法的引數列表各不相同(即引數個數或型別不同)。

重寫 Override 表示子類中的方法可以與父類中的某個方法的名稱和引數完全相同,通過子類建立的例項物件呼叫這個方法時,將呼叫子類中的定義方法,這相當於把父類中定義的那個完全相同的方法給覆蓋了,這也是面向物件程式設計的多型性的一種表現。子類覆蓋父類的方法時,只能比父類丟擲更少的異常,或者是丟擲父類丟擲的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問許可權只能比父類的更大,不能更小。如果父類的方法是 private 型別,那麼,子類則不存在覆蓋的限制,相當於子類中增加了一個全新的方法。

面向物件的特徵有哪些?

​ 抽象:抽象是將一類物件的共同特徵總結出來構造類的過程,包括資料抽象和行為抽象.抽象只關注物件有哪些屬性和行為,並不關注這些行為的細節是什麼。

​ 繼承:繼承是從已有類得到繼承資訊建立新類的過程.提供繼承資訊的類叫父類(超類,基類),得到資訊的類叫子類(派生類)。

​ 封裝:通常認為封裝是把資料和操作資料的方法繫結在一起,對資料的訪問只能通過已經定義的介面.面向物件的本質就是將現實世界描繪成一系列完全自治封閉的物件.我們在類中編寫的方法就是對實現細節的一種封裝;我們編寫一個類就是對資料和資料操作的封裝.可以說,封裝就是隱藏一切可以隱藏的東西,只向外界提供最簡單的程式設計介面。

​ 多型性:多型性是指孕育不同子型別的物件對同一訊息作出不同的響應.簡單來說就是用同樣的物件向外界呼叫同樣的方法但是做了不同的事情.多型分為編譯時多型和執行時多型.如果將物件的方法視為物件向外界提供的服務,那麼執行時多型可以理解為:當A系統訪問B系統提供的服務時,B系統有多種提供服務的方式,但一切對A系統來說都是透明的.方法過載(overload)實現的是編譯時的多型,而方法重寫(override)實現的是執行時的多型.執行時的多型是面向物件最精髓的東西,要實現多型需要做兩件事:1)方法重寫(子類繼承父類並重寫父類中已有的或抽象的方法),2)物件造型(用父型別引用子型別物件,這樣同樣的引用呼叫同樣的方法就會根據子類物件的不同而表現出不同的行為)

abstract class 和 interface 有什麼區別?

含有 abstract 修飾符的 class 即為抽象類,abstract 類不能建立的例項物件。含有 abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義為 abstract型別。

介面(interface)可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的。介面中的方法定義預設為 public abstract 型別,介面中的成員變數型別預設為 public static final。

下面比較一下兩者的語法區別:

1.抽象類可以有構造方法,介面中不能有構造方法。

2.抽象類中可以有普通成員變數,介面中沒有普通成員變數。

3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4. 抽象類中的抽象方法的訪問型別可以是 public,protected 和(預設型別,雖然eclipse 下不報錯,但應該也不行),但介面中的抽象方法只能是 public 型別的,並且預設即為 public abstract 型別。
5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法。
6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是 public static final 型別,並且預設即為 public static final 型別。
7. 一個類可以實現多個介面,但只能繼承一個抽象類。

面向物件

面向物件是基於面向過程的,在開發過程中,要完成特定的功能就去找對應的物件,如果找不到就建立相應的物件,使用物件,維護完善物件。

面向過程是一件事"該怎麼做",面向物件是一件事"該讓誰來做",把一個物件抽象成類,具體上就是把一個物件的靜態特徵和動態特徵抽象成屬性和方法,也就是把一類事物的演算法和資料結構封裝在一個類之中,程式也就是多個物件和互相之間的通訊組成的。

面向物件具有封裝性,繼承性,多型性,封裝隱藏了物件內部不需要暴露的細節,使得內部細節的變動跟外界脫離,只依靠介面進行通訊,封裝性降低了程式設計的複雜性,通過繼承,使得新建一個類變得容易,一個類從派生類那裡獲得其非私有的方法和公有屬性。

總之,面向物件的特性提高了大型程式的重用性和可維護性

闡述靜態變數和例項變數的區別。

靜態變數是被static修飾符修飾的變數,也稱為類變數,它屬於類,不屬於類的任何一個物件,一個類不管建立多少個物件,靜態變數在記憶體中有且僅有一個拷貝;例項變數必須依存於某一例項,需要先建立物件然後通過物件才能訪問到它.靜態變數可以實現讓多個物件共享記憶體.

Error和Exception有什麼區別?

Error表示系統級的錯誤和程式不必處理的異常,是恢復不是不可能但是很困難的情況下的一種嚴重問題,比如記憶體溢位,不可能指望程式能處理這樣的情況;Exception表示需要捕捉或者需要程式進行處理的異常,是一種設計或實現問題;也就是說,他表示如果程式正常執行,從不會發生的情況.

斷言(assert)

斷言是在軟體開發中的一種除錯方法,在實現中,assertion就是在程式中的一條語句,它對一個boolean表示式進行檢查,一個正確程式必須保證這個boolean表示式的值為true,如果為false,說明程式已經處以不正確的狀態,assert將給出警告或退出.assertion檢查通常在開發和測試中開啟,為了提高效能,在軟體釋出後,assertion檢查通常是關閉的.

String和StringBuilder StringBuffer的區別?

Java平臺提供了兩種型別的字串,String和StringBuffer/StringBuilder,他們可以儲存和操作字串,其中String是隻讀字串,也就意味著String引用的字串內容是不能被改變的,而StringBuffer/StringBuilder類表示的字串物件可以直接進行修改,StringBuilder是java5引入的,它和StringBuffer的方法完全相同,區別就在於它是單執行緒環境下使用的,因為它的所有方面都沒有synchronized修飾,因此它的效率也比StringBuffer要高.

怎樣將GB2312編碼的字串轉換為ISO-8859-1編碼的字串?

String s1 = “你好”;

String s2 = new String (s1.getBytes(“GB2312”),”ISO-8859-1”);

JVM的記憶體區域劃分

1.程式計數器

指CPU中的暫存器,它儲存的是程式當前執行的指令的地址(也可以說儲存下一條指令的所在儲存單元的地址),當CPU需要執行指令時,需要從程式計數器中得到當前需要執行的指令所在儲存單元的地址,然後根據得到的地址獲取到指令,在得到指令之後,程式計數器便自動加1或者根據轉移指標得到下一條指令的地址,如此迴圈,直至執行完所有的指令。

2.Java棧

存放基本型別的變數資料和物件的引用,但物件本身不存放在棧中。

3.堆(heap)

存放所有new出來的物件。

4.本地方法棧

本地方法棧與Java棧的作用和原理非常相似。區別只不過是Java棧是為執行Java方法服務的,而本地方法棧則是為執行本地方法(Native Method)服務的。

5.方法區

方法區在JVM中也是一個非常重要的區域,它與堆一樣,是被執行緒共享的區域。在方法區中,儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、常量以及編譯器編譯後的程式碼等。