Java基礎常見面試題
- 2019 年 10 月 5 日
- 筆記
- 什麼是類與對象?類和對象實例之間的關係?
答∶ 類具有繼承、數據隱藏和多態三種主要特性。類是同一類對象實例的共性的抽象,對象是類的實例化;類是靜態的,對象是動態的,對象可以看作是運行中的類。類負責產生對象,可以將類當成生產對象的工廠
- 構造函數的特點有哪些?
答∶
1)構造函數的方法名與類名相同。
2)構造函數沒有返回類型。
3)構造函數的主要作用是完成對類對象的初始化工作。
4)構造函數不能由編程人員顯式地直接調用。
5)在創建一個類的新對象的同時,系統會自動調用 該類的構造函數為新對象初始化。
構造函數不可以被繼承
默認構造函數指沒有參數的構造函數
如果編寫的類沒有構造函數,系統會自動提供一個默認構造函數,它把所有的屬性設為默認值(比如一些基本數據類型)。
- 是否可以從一個static方法內部發出對非static方法的調用?
答∶
不可以。因為非static方法是要與對象關聯在一起的,必須創建一個對象後,才可以在該對象上進行方法調用,而static方法調用時不需要創建對象,可以直接調用。
- JAVA中怎樣去識別方法?
答∶ 根據方法名、參數列表、參數類型、參數順序去識別的
- 創建對象的方法?
答∶
1、用new語句創建對象,這是常見的創建對象的方法
2、運用反射手段,調用java.lang.Class 或者 java.lang.reflect.Construct類的newInstance()實例方法
3、調用對象的clone方法
4、運用反序列化手段,調用java.io.ObjectInputStream對象的readObject()方法
- 面向對象的特徵有哪些方面?
答∶
1.抽象:
抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象包括兩個方面,一是過程抽象,二是數據抽象。
2.繼承:
繼承是一種聯結類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那裡繼承方法和實例變數,並且類可以修改或增加新的方法使之更適合特殊的需要。
3.封裝:
封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的介面。面向對象計算始於這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的介面訪問其他對象。
- 抽象類和介面有什麼區別?
答∶
一 介面和抽象類的相似性
1 介面和抽象類都不能被實例化,它們都位於繼承樹的頂端,用於被其他類實現和繼承。
2 介面和抽象類都可以包含抽象方法,實現介面或繼承抽象類的普通子類都必須實現這些抽象方法。
二 介面和抽象類的區別
1 介面里只能包含抽象方法,靜態方法和默認方法,不能為普通方法提供方法實現,抽象類則完全可以包含普通方法。
2 介面里只能定義靜態常量,不能定義普通成員變數,抽象類里則既可以定義普通成員變數,也可以定義靜態常量。
3 介面不能包含構造器,抽象類可以包含構造器,抽象類里的構造器並不是用於創建對象,而是讓其子類調用這些構造器來完成屬於抽象類的初始化操作。
4 介面里不能包含初始化塊,但抽象類里完全可以包含初始化塊。
5 一個類最多只能有一個直接父類,包括抽象類,但一個類可以直接實現多個介面,通過實現多個介面可以彌補Java單繼承不足。
- final 、finally、finallize區別?
答∶
final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
finally是異常處理語句結構的一部分,表示總是執行。
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。
- OverLoading 和OverRiding的區別?
答∶ 是Java多態性的不同表現。重寫是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫 。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被「屏蔽」了。如果在一個類中定義了多個同名的方法,它們或有不同的參數個數或有不同的參數類型,則稱為方法的重載。重載的方法是可以改變返回值的類型。
- JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什麼意義?在try塊中可以拋出異常嗎?
答∶ Java通過面向對象的方法進行異常處理,把各種不同的異常進行分類,並提供了良好的介面。在Java中,每個異常都是一個對象,它是Throwable類或其它子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常資訊,調用這個對象的方法可以捕獲到這個異常並進行處理。
Java的異常處理是通過5個關鍵詞來實現的:try、catch、throw、throws和finally。一般情況下是用try來執行一段程式,如果出現異常,系統會拋出(throws)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最後(finally)由預設處理器來處理。
用try來指定一塊預防所有「異常」的程式。緊跟在try程式後面,應包含一個catch子句來指定你想要捕捉的「異常」的類型。
throw語句用來明確地拋出一個「異常」。
throws用來標明一個成員函數可能拋出的各種「異常」。
Finally為確保一段程式碼不管發生什麼「異常」都被執行一段程式碼。
可以在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另一個try語句保護其他程式碼。每當遇到一個try語句,「異常」的框架就放到堆棧上面,直到所有的try語句都完成。如果下一級的try語句沒有對某種「異常」進行處理,堆棧就會展開,直到遇到有處理這種「異常」的try語句。
- 列舉常見的5個運行時異常?
答∶ 運行時異常,父類是RuntimeException 例如有:
ClassCastException |
|---|
NullPointException |
AirthmeticException |
IndexOutOfBoundsException |
JMRuntimeException |
- error 和 exception區別?
答∶
error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說記憶體溢出。不可能指望程式能處理這樣的情況。
exception 表示一種設計或實現問題。也就是說,它表示如果程式運行正常,從不會發生的情況。
- int 和 Integer 有什麼區別?
答∶ Java 提供兩種不同的類型:引用類型和原始類型(或內置類型)。Int是java的原始數據類型,Integer是java為int提供的封裝類。Java為每個原始類型提供了封裝類。
原始類型封裝類
boolean | Boolean |
|---|---|
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
引用類型和原始類型的行為完全不同,並且它們具有不同的語義。引用類型和原始類型具有不同的特徵和用法,它們包括:大小和速度問題,這種類型以哪種類型的數據結構存儲,當引用類型和原始類型用作某個類的實例數據時所指定的預設值。對象引用實例變數的預設值為 null,而原始類型實例變數的預設值與它們的類型有關。
- 「==」 和 equals區別?
答∶
第一種比較的是兩個字元串對象的記憶體地址是否相同,如果是基本數據類型則對比的是值。
第二種比較的是兩個字元串對象的值是否相同,equals繼承Object類,比較的是否是同一個對象,如果沒有對equals方法進行重寫,則比較的是引用類型的變數所指向的對象的地址;諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容。
- String 與StringBuffer的區別,實際項目中什麼情況下用String什麼情況下用StringBuffer?
答∶
String的長度是不可變的
StringBuffer的長度是可變的。如果你對字元串中的內容經常進行操作,特別是內容要修改時,那麼使用StringBuffer,如果最後需要String,那麼使用StringBuffer的toString()方法
- String s = new String("xyz");創建了幾個String Object?
答∶ 兩個對象,一個是「xyx」,一個是指向「xyx」的引用對象
- 說出ArrayList,Vector, LinkedList的存儲性能和特性?
答∶ ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等記憶體操作,所以索引數據快而插入數據慢,Vector由於使用了synchronized方法(執行緒安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或後向遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入速度較快。
- List、Map、Set三個介面,存取元素時,各有什麼特點?
答∶
List介面
ArrayList:一個可增長的數組,提供快速遍歷和快速隨機訪問,當需要快速遍歷時而不是做大量刪除和插入時,用ArrayList
Vector(Hashtable)為了執行緒安全,Vector方法被同步,通常使用ArrayList 而不用Vector
Set介面
重在數據的唯一性,不允許重複,set介面通過equals()方法確定兩個對象是否相等,重複時只能有一個放在set中
Map介面:
按 「鍵-值」對進行插入,(鍵、值都是對象)可以按照鍵來搜索值對象,可以查找值的集合,也可以查找鍵的集合, key 不可重複,value可重複。
- 什麼是java序列化,如何實現java序列化?
答∶
序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。可以對流化後的對象進行讀寫操作,也可將流化後的對象傳輸於網路之間。
序列化的實現:將需要被序列化的類實現Serializable介面
ObjectOutputStream(對象流)對象,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以將參數為obj的對象寫出(即保存其狀態),要恢復的話則用輸入流
- java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
答:位元組流,字元流。位元組流繼承於InputStream OutputStream,字元流繼承於InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便
- HashTable和HashMap區別?
答∶ HashMap是Hashtable的輕量級實現(非執行緒安全的實現),他們都完成了Map介面,主要區別在於HashMap允許空(null)鍵值(key),由於非執行緒安全,效率上可能高於Hashtable。
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個執行緒訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap 就必須為之提供外同步。
Hashtable和HashMap採用的hash/rehash演算法都大概一樣,所以性能不會有很大的差異。
- 怎麼遍歷HashMap集合?
答∶ 首先要通過keySet()方法得到鍵的集合,再得到鍵集合的迭代器,進行迭代,通過get(key)得到值
- Collection與Collections區別?
答∶Collection是集合類的上級介面,繼承與他的介面主要有Set 和List.
Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、執行緒安全化等操作。
- 什麼叫單例模式?
答∶ 私有化構造方法,只有在本類中才可以new 那個對象,通過一個方法返回出去
public class Singleton {
private static Singleton instance = null
private Singleton(){
}
public static synchronized Singleton getInstance() {
//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次使用時生成實例,提高了效率!
if (instance==null){
instance=new Singleton();
return instance;
}
}
- 什麼叫工廠模式?
答∶ 工廠模式是一種經常被使用到的模式,根據工廠模式實現的類可以根據提供的數據生成一組類中某一個類的實例,通常這一組類有一個公共的抽象父類並且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作。首先需要定義一個基類,該類的子類通過不同的方法實現了基類中的方法。然後需要定義一個工廠類,工廠類可以根據條件生成不同的子類實例。當得到子類的實例後,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。
- 創建執行緒的方式,以及分別怎麼啟動執行緒?
答∶ 有兩種實現方法,分別是繼承Thread類與實現Runnable介面。繼承Thread 可直接用對象.start()方法啟動執行緒,實現Runnable介面的可以定義一個Thread類的對象,通過構造方法把實現Runnable介面的類的對象初始化進去,用Thread類對象.start()方法啟動執行緒。
- 通訊的方式有幾種,以及區別?
答∶ UDP 和 Tcp/Ip UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是面向非連接的協議,它不與對方建立連接,而是直接就把數據包發送過去!通訊效果高,但也正因為如此,它的可靠性不如TCP協議高。 UDP適用於一次只傳送少量數據、對可靠性要求不高的應用環境。 TCP(Transmission Control Protocol,傳輸控制協議)是基於連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接,適用於一次傳輸大量數據,對可靠性要求高的應用環境。
- 什麼是多態,舉例在程式碼那些地方用到了?
答∶ 相同的操作不同的實現,例如在方法重載重寫及介面的實現。
- list與普通數組的區別?
答∶ 前者的長度是動態的,類型為object,後者在申明是需確定長度且類型是一致的。
- string stringbuffer StringBuilder 有什麼區別?
答∶
String是「字元串常量」,也就是不可改變的對象。
StringBuffer與StringBuilder,他們是字元串變數,是可改變的對象,每當我們用它們對字元串做操作時,實際上是在一個對象上操作的,不像String一樣創建一些對象進行操作,所以速度就快了。
StringBuffer:執行緒安全的,StringBuilder:執行緒非安全的
1.如果要操作少量的數據用 = String
2.單執行緒操作字元串緩衝區 下操作大量數據 = StringBuilder
3.多執行緒操作字元串緩衝區 下操作大量數據 = StringBuffer
- 流按方向劃分分為?按傳送的內容劃分分為?
答∶ 方向劃分:輸入輸出流。 內容分為:位元組流,字元流,對象流
- 訪問修飾符有哪些?分別的作用?
答∶
public | 能被所有的類(介面、成員)訪問。 |
|---|---|
protected | 只能被本類、同一個包中的類訪問;如果在其他包中被訪問,則必須是該成員所屬類的子類。 |
private | 成員變數和方法都只能在定義它的類中被訪問,其他類都訪問不到。對成員變數的進行獲取和更改,一般用get(),set() ,public 方法。實現了Java面向對象的封裝思想。 |
預設 | 訪問許可權與protected相似,但修飾類成員時不同包中的子類不能訪問。 |
