1.final 關(guān)鍵字的作用?
final可以修飾類流译,變量真竖,方法
* 被 final 修飾的類不可以被繼承
*? 被 final 修飾的方法不可以被重寫
*? 被 final 修飾的變量不可以被改變.如果修飾引用,那么表示引用不可變,引用指向的內(nèi)容可變.
*? 被 final 修飾的方法,JVM 會嘗試將其內(nèi)聯(lián),以提高運行效率汪榔,被 final 修飾的變量,在編譯階段會存入常量池中.
2.abstract class 和 interface 有什么區(qū)別?
抽象類(abstract)
聲明方法的存在而不去實現(xiàn)它的類被叫做抽象類(abstract class),
抽象類不能創(chuàng)建的實例對象。
含有abstract方法的類必須定義為abstract class团甲,abstract class類中的方法不必是都是抽象的馅而。
如果的子類沒有實現(xiàn)抽象父類中的所有抽象方法,那么子類也必須定義為abstract類型譬圣。
接口(interface)
interface 可以說成是抽象類的一種特例瓮恭,接口中的所有方法都必須是抽象的。
接口中的方法定義默認為public abstract類型厘熟,接口中的成員變量類型默認為public static final屯蹦。
下面比較一下兩者的語法區(qū)別:
1.抽象類可以有構(gòu)造方法,接口中不能有構(gòu)造方法绳姨。
2.抽象類中可以有普通成員變量登澜,接口中沒有普通成員變量
3.抽象類中可以包含非抽象的普通方法,接口中的所有方法必須都是抽象的飘庄,不能有非抽象的普通方法脑蠕。
\4. 抽象類中的抽象方法的訪問類型可以是public,protected和(默認類型,雖然eclipse下不報錯跪削,但應(yīng)該也不行)谴仙,但接口中的抽象方法只能是public類型的,并且默認即為public abstract類型碾盐。
\5. 抽象類中可以包含靜態(tài)方法晃跺,接口中不能包含靜態(tài)方法
\6. 抽象類和接口中都可以包含靜態(tài)成員變量,抽象類中的靜態(tài)成員變量的訪問類型可以任意毫玖,但接口中定義的變量只能是public static final類型掀虎,并且默認即為public static final類型。
\7. 一個類可以實現(xiàn)多個接口付枫,但只能繼承一個抽象類烹玉。
* 聲明方法的存在而不去實現(xiàn)它的類被叫做抽象類(abstract class),它用于要創(chuàng)建一個體現(xiàn)某些基本行為的類励背,并為該類聲明方法春霍,但不能在該類中實現(xiàn)該類的情況。不能創(chuàng)建 abstract 類的實例叶眉。然而可以創(chuàng)建一個變量址儒,其類型是一個抽象類,并讓它指向具體子類的一個實例衅疙。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法莲趣。Abstract 類的子類為它們父類中的所有抽象方法提供實現(xiàn),否則它們也是抽象類為饱溢。取而代之喧伞,在子類中實現(xiàn)該方法。知道其行為的其它類可以在類中實現(xiàn)這些方法。
* 接口(interface)是抽象類的變體潘鲫。在接口中翁逞,所有方法都是抽象的。多繼承性可通過實現(xiàn)這樣的接口而獲得溉仑。接口中的所有方法都是抽象的挖函,沒有一個有程序體。接口只可以定義 static final 成員變量浊竟。接口的實現(xiàn)與子類相似怨喘,除了該實現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實現(xiàn)特殊接口時振定,它定義(即將程序體給予)所有這種接口的方法必怜。然后,它可以在實現(xiàn)了該接口的類的任何對象上調(diào)用接口的方法后频。由于有抽象類梳庆,它允許使用接口名作為引用變量的類型。通常的動態(tài)聯(lián)編將生效卑惜。引用可以轉(zhuǎn)換到接口類型或從接口類型轉(zhuǎn)換, instanceof 運算符可以用來決定某對象的類是否實現(xiàn)了接口
#### 3. Java 集合類:list靠益、set、queue残揉、map胧后、stack 的特點與用法?
* Map
? * Map 是鍵值對抱环,鍵 Key 是唯一不能重復(fù)的壳快,一個鍵對應(yīng)一個值,值可以重復(fù)镇草。
? * TreeMap 可以保證順序眶痰,HashMap 不保證順序,即為無序的梯啤,
? * Map 中可以將 Key 和 Value 單獨抽取出來竖伯,其中 KeySet()方法可以將所有的 keys 抽取成一個 Set,而 Values()方法可以將 map 中所有的 values 抽取成一個集合因宇。
* Set
? * 不包含重復(fù)元素的集合七婴,set 中最多包含一個 null 元素,只能用 Iterator 實現(xiàn)單項遍歷察滑, Set 中沒有同步方法打厘。
* List
? * 有序的可重復(fù)集合,可以在任意位置增加刪除元素贺辰,用 Iterator 實現(xiàn)單向遍歷户盯,也可用ListIterator 實現(xiàn)雙向遍歷嵌施。
* Queue
? * Queue 遵從先進先出原則,使用時盡量避免 add()和 remove()方法,而是使用 offer()來添加元素莽鸭,使用 poll()來移除元素吗伤,它的優(yōu)點是可以通過返回值來判斷是否成功,LinkedList實現(xiàn)了 Queue 接口硫眨,Queue 通常不允許插入 null 元素牲芋。
*? Stack
? * Stack 遵從后進先出原則,Stack 繼承自 Vector捺球,它通過五個操作對類 Vector 進行擴展允許將向量視為堆棧,它提供了通常的 push 和 pop 操作夕冲,以及取堆棧頂點的 peek()方法氮兵、測試堆棧是否為空的 empty 方法等。
* 用法
? * 如果涉及堆棧歹鱼,隊列等操作泣栈,建議使用 List。
? * 對于快速插入和刪除元素的弥姻,建議使用 LinkedList南片。如果需要快速隨機訪問元素的,建議使用ArrayList庭敦。
#### 4.說出 ArrayList,Vector, LinkedList 的存儲性能和特性疼进?
* ArrayList 和 Vector 都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素數(shù)大于實際存儲的數(shù)據(jù)以便增加和插入元素秧廉,它們都允許直接按序號索引元素伞广,但是插入元素要涉及數(shù)組元素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢疼电,Vector 由于使用了 synchronized 方法(線程安全)嚼锄,通常性能上較 ArrayList 差,而 LinkedList 使用雙向鏈表實現(xiàn)存儲蔽豺,按序號索引數(shù)據(jù)需要進行前向或后向遍歷区丑,但是插入數(shù)據(jù)時只需要記錄本項的前后項即可,所以插入速度較快修陡。
#### 5.內(nèi)存泄漏和內(nèi)存溢出沧侥?
* 內(nèi)存泄漏(memoryleak),是指應(yīng)用程序在申請內(nèi)存后魄鸦,無法釋放已經(jīng)申請的內(nèi)存空間正什,一次內(nèi)存泄漏危害可以忽略,但如果任其發(fā)展最終會導(dǎo)致內(nèi)存溢出(outofmemory)号杏。如讀取文件后流要進行及時的關(guān)閉以及對數(shù)據(jù)庫連接的釋放婴氮。
* 內(nèi)存溢出(outofmemory)是指應(yīng)用程序在申請內(nèi)存時斯棒,沒有足夠的內(nèi)存空間供其使用。如我們在項目中對于大批量數(shù)據(jù)的導(dǎo)入主经,采用分批量提交的方式荣暮。
#### 6. 反射中,Class.forName()和 ClassLoader.loadClass()的區(qū)別罩驻?
* Class.forName(className) 方 法 穗酥, 內(nèi) 部 實 際 調(diào) 用 的 方 法 是 Class.forName(className,true,classloader); 第 2 個 boolean 參數(shù)表示類是否需要初始化, Class.forName(className)默認是需要初始化,
* 一旦初始化惠遏,就會觸發(fā)目標(biāo)對象的 static 塊代碼執(zhí)行砾跃, static 參數(shù)也也會被再次初始化 ,ClassLoader.loadClass(className) 方 法 , 內(nèi) 部 實 際 調(diào) 用 的 方 法 是ClassLoader.loadClass(className,false);第 2 個 boolean 參數(shù)节吮,表示目標(biāo)對象是否進行鏈接抽高, false 表示不進行鏈接,由上面介紹可以透绩,不進行鏈接意味著不進行包括初始化等一些列步驟翘骂,那么靜態(tài)塊和靜態(tài)對象就不會得到執(zhí)行
#### 7. int 和 Integer 的區(qū)別?
* Integer 是 int 的包裝類型,在拆箱和裝箱中,二者自動轉(zhuǎn)換.int 是基本類型,直接存數(shù)值;而 integer 是對象;用一個引用指向這個對象.由于 Integer 是一個對象,在 JVM 中對象需要一定的數(shù)據(jù)結(jié)構(gòu)進行描述,相比 int 而言,其占用的內(nèi)存更大一些.
#### 8. String帚豪、StringBuilder碳竟、StringBuffer 區(qū)別?
| String? ? ? ? ? ? ? ? ? | 字符串常量 | 不可變? ? | 使用字符串拼接時是不同的 2 個空間 |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| ------------------------ | ---------- | ---------- | --------------------------------- | ---------------------------- |
| StringBuffer? ? ? ? ? ? | 字符串變量 | 可變? ? ? | 線程安全? ? ? ? ? ? ? ? ? ? ? ? ? | 字符串拼接直接在字符串后追加 |
| StringBuilder 字符串變量 | 可變? ? ? | 非線程安全 | 字符串拼接直接在字符串后追加? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
* StringBuilder 執(zhí)行效率高于 StringBuffer 高于 String.
* String 是一個常量狸臣,是不可變的莹桅,所以對于每一次+=賦值都會創(chuàng)建一個新的對象,StringBuffer 和 StringBuilder 都是可變的烛亦,當(dāng)進行字符串拼接時采用 append 方法统翩,在原來的基礎(chǔ)上進行追加,所以性能比 String 要高此洲,又因為 StringBuffer是線程安全的而 StringBuilder 是線程非安全的厂汗,所以 StringBuilder 的效率高于 StringBuffer.
* 對于大數(shù)據(jù)量的字符串的拼接,采用 StringBuffer,StringBuilder.
#### 9. Hashtable 和 Hashmap 的區(qū)別呜师?
* HashTable 線程安全娶桦,HashMap 非線程安全
2、Hashtable 不允許 null 值(key 和 value 都不可以)汁汗,HashMap 允許 null 值(key 和 value 都可以)衷畦。
? 兩者的遍歷方式大同小異,Hashtable 僅僅比 HashMap 多一個 elements 方法知牌。
#### 10. 說幾個常見的編譯時異常祈争?
* SQLException 提供有關(guān)數(shù)據(jù)庫訪問錯誤或其他錯誤的信息的異常。
? IOexception 表示發(fā)生了某種 I / O 異常的信號角寸。此類是由失敗或中斷的 I / O 操作產(chǎn)生的
? 一般異常類 FileNotFoundException 當(dāng)試圖打開指定路徑名表示的文件失敗時菩混,拋出此異常忿墅。
? ClassNotFoundException 找不到具有指定名稱的類的定義。
? EOFException (讀取到文件尾部的時候)當(dāng)輸入過程中意外到達文件或流的末尾時沮峡,拋出此異常疚脐。
方法重載的規(guī)則?
同一個類中邢疙,方法名一致棍弄,參數(shù)列表不同(順序,類型疟游,個數(shù))呼畸。可以拋出不同的異常,可以有不同修飾符颁虐。重載與方法的返回值無關(guān)蛮原,存在于父類和子類,同類中聪廉。
方法重寫的規(guī)則?
參數(shù)列表故慈、方法名板熊、返回值類型必須完全一致,構(gòu)造方法不能被重寫察绷;
聲明為 final 的方法不能被重寫干签;
聲明為 static 的方法不存在重寫(重寫和多態(tài)聯(lián)合才有意義);
訪問權(quán)限不能比父類更低;
重寫之后的方法不能拋出更寬泛的異常
子類無法重寫父類的私有方法
throw 和 throws 的區(qū)別?
throw:throw 語句用在方法體內(nèi),表示拋出異常拆撼,由方法體內(nèi)的語句處理容劳。throw 是具體向外拋出異常的動作,所以它拋出的是一個異常實例闸度,執(zhí)行 throw 一定是拋出了某種異常竭贩。
throws:throws 語句是用在方法聲明后面,表示如果拋出異常莺禁,由該方法的調(diào)用者來進行異常的處理留量。throws 主要是聲明這個方法會拋出某種類型的異常,讓它的使用者要知道需要捕獲的
異常的類型哟冬。throws 表示出現(xiàn)異常的一種可能性楼熄,并不一定會發(fā)生這種異常。
抽象類和接口的區(qū)別?
接口中所有的方法隱含的都是抽象的浩峡。而抽象類則可以同時包含抽象和非抽象的方法可岂。
類可以實現(xiàn)很多個接口,但是只能繼承一個抽象類
類如果要實現(xiàn)一個接口翰灾,它必須要實現(xiàn)接口聲明的所有方法缕粹。但是稚茅,類可以不實現(xiàn)抽象類聲明的所有方法,當(dāng)然致开,在這種情況下峰锁,類也必須得聲明成是抽象的。
抽象類可以在不提供接口方法實現(xiàn)的情況下實現(xiàn)接口双戳。
Java 接口中聲明的變量默認都是 final 的虹蒋。抽象類可以包含非 final 的變量。
Java 接口中的成員函數(shù)默認是 public 的飒货。抽象類的成員函數(shù)可以是 private魄衅,protecte或者是 public 。
接口是絕對抽象的塘辅,不可以被實例化(java 1.8 已支持在接口中實現(xiàn)默認的方法)晃虫。抽象類也不可以被實例化,但是扣墩,如果它包含 main 方法的話是可以被調(diào)用的哲银。
Java 的基礎(chǔ)類型和字節(jié)大小? bit 8個 = 1 個 byte
四個訪問修飾符合訪問級別?
public呻惕、protected荆责、默認的(沒有訪問修飾符)、private
String 和 StringBuffer 的區(qū)別?
String 和 StringBuffer 主要區(qū)別是性能:String 是不可變對象,每次對 String 類型進行操作都等同于產(chǎn)生了一個新的 String 對象,然后指向新的 String 對象.所以盡量不要對 String 進行大量的拼接操作,否則會產(chǎn)生很多臨時對象,導(dǎo)致 GC 開始工作,影響系統(tǒng)性能.StringBuffer 是對象本身操作,而不是產(chǎn)生新的對象,因此在有大量拼接的情況下,我們建議使用 StringBuffer(線程安全).
HashSet 的底層實現(xiàn)是什么亚脆?
HashSet 的實現(xiàn)是依賴于 HashMap 的做院,HashSet 的值都是存儲在 HashMap 中的。在 HashSet 的構(gòu)造方法中會初始化一個 HashMap 對象濒持,HashSet 不允許值重復(fù)键耕。因此,HashSet 的值是作為 HashMap 的 key 存儲在 HashMap 中的柑营,當(dāng)存儲的值已經(jīng)存在時返回 false屈雄。
抽象類的意義?(定義規(guī)則官套,提高代碼復(fù)用性)
抽象類的意義可以用三句話來概括:
1棚亩、為其他子類提供一個公共的類型
2、封裝子類中重復(fù)定義的內(nèi)容
3虏杰、定義抽象方法,子類雖然有不同的實現(xiàn),但是定義時一致的
你為什么重寫 equals 時必須重寫 hashCode 方法讥蟆?
hashCode() 的作用是獲取哈希碼,也稱為散列碼纺阔;它實際上是返回一個 int 整數(shù)瘸彤。這個哈希碼的作用是確定該對象在哈希表中的索引位置。如果兩個對象相等笛钝,則 hashcode 一定也是相同的质况,如果兩個對象相等,對兩個對象分別調(diào)用 equals 方法都返回 true 如果兩個對象有相同的 hashcode 值愕宋,它們也不一定是相等的因此,equals 方法被覆蓋過结榄,則 hashCode 方法也必須被覆蓋中贝。hashCode()的默認行為是對堆上的對象產(chǎn)生獨特值。如果沒有重寫 hashCode()臼朗,則該 class 的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數(shù)據(jù)).