大家好呀,小編今天給大家分享一些 Java 常見的基礎(chǔ)知識(shí)面試題,為即將要面臨春招,以及正在尋找工作的小伙伴們提前支支招。
推薦好課:Java基礎(chǔ)入門到框架實(shí)踐、深入解析Java面向?qū)ο?/a>
一、八種基本數(shù)據(jù)類型的大小,以及他們的封裝類
數(shù)據(jù)類型 | 封裝類 | 大小 |
---|---|---|
byte | Byte | 1 字節(jié) |
short | Short | 2 字節(jié) |
int | Integer | 4 字節(jié) |
long | Long | 8 字節(jié) |
float | Float | 4 字節(jié) |
double | Double | 8 字節(jié) |
boolean | Boolean | / |
char | Character | 2 字節(jié) |
二、switch 能否用 string 做參數(shù)?
switch 語(yǔ)句中的變量類型可以使 byte,short,int,char。從 jdk1.7 后可以使用 String 類型,是通過 switch 中的 String.hashcode 將 String 轉(zhuǎn)換成 int 進(jìn)行判斷。
三、equals 與 == 的區(qū)別
== 操作符是用來比較兩個(gè)變量的值是否相等,即就是比較變量在內(nèi)存中的存儲(chǔ)地址是否相同,equals()方法時(shí) String 類從 Object 類中繼承的,被用來檢測(cè)兩個(gè)對(duì)象的內(nèi)容是否相同。
四、String s = new String(‘a(chǎn)bc’);創(chuàng)建了幾個(gè) object 對(duì)象?
會(huì)創(chuàng)建一個(gè) String 類型的變量 s。在類加載到此處之前沒有出現(xiàn)“abc”字面量的話,加載此處會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)“abc”的 String 常量對(duì)象。在符合規(guī)范的 JVM 上,執(zhí)行到此處 new 關(guān)鍵字會(huì)創(chuàng)建一個(gè) String 對(duì)象。
五、 Object有哪些公用方法?
- clone() 創(chuàng)建斌返回此對(duì)象的副本
- equals() 判斷
- getclass() 返回 object 的運(yùn)行類
- hashcode() 返回對(duì)象的哈希碼值
- notify() 喚醒正在等待對(duì)象監(jiān)聽器的單個(gè)進(jìn)程
- notifyAll() 喚醒正在等待對(duì)象監(jiān)聽器的所有進(jìn)程
- wait() 導(dǎo)致當(dāng)前線程等待,直到另一個(gè)線程調(diào)用該對(duì)象的 notify() 方法或 notifyAll() 方法
- toString() 返回此對(duì)象的字符串表示形式
- finalize() 當(dāng)垃圾收集確定不需要該對(duì)象時(shí),垃圾回收器調(diào)用該方法
六、Java的四種引用,用到的場(chǎng)景
- 強(qiáng)引用:垃圾回收器不會(huì)回收
- 軟引用:如果內(nèi)存空間足夠,垃圾回收器就不會(huì)進(jìn)行回收,如果內(nèi)存空間不足,垃圾回收器就會(huì)進(jìn)行回收
- 弱引用:一旦發(fā)現(xiàn)了只有弱引用的對(duì)象,垃圾回收器就會(huì)進(jìn)行回收。
- 虛引用:如果發(fā)現(xiàn)該對(duì)象還具有虛引用,就會(huì)在回收該對(duì)象之前,吧這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
七、靜態(tài)變量和實(shí)例變量的區(qū)別
靜態(tài)變量前要加上關(guān)鍵字 static,實(shí)例變量則不會(huì)。
實(shí)例變量是屬于某個(gè)對(duì)象的屬性,必須創(chuàng)建了實(shí)例對(duì)象,其中的實(shí)例變量才會(huì)分配空間,才能使用這個(gè)實(shí)例變量。靜態(tài)變量不屬于任何的實(shí)例對(duì)象,而是屬于類,也稱為類變量,只要程序加載了類的字節(jié)碼,不用創(chuàng)建任何實(shí)例對(duì)象,就會(huì)被分配空間。總之就是,靜態(tài)變量不需要?jiǎng)?chuàng)建任何的對(duì)象就可以直接使用,而實(shí)例變量需要先創(chuàng)建實(shí)例對(duì)象才能被使用。
八、 Overload 和 Override 的區(qū)別
重載 Overload 表示的是同一個(gè)類中可以有多個(gè)相同名稱的方法,但這些方法的參數(shù)列表不同,即就是參數(shù)參數(shù)或參數(shù)類型不同。重載時(shí)返回值當(dāng)然可以不一樣,但是如果參數(shù)列表完全一致時(shí),不能通過返回類型不一致而實(shí)現(xiàn)重載,這是不可以的。
重寫 Override 表示子類中的方法可以與父類中的方法名稱和參數(shù)完全相同,通過子類創(chuàng)建的對(duì)象來調(diào)用這個(gè)方法時(shí),將調(diào)用子類中定義的方法,即就是子類中的該方法將父類的該方法覆蓋了。子類覆蓋父類方法時(shí)只能拋比父類更少或者更小的異常。重寫的方法其返回必須和被覆蓋的方法返回一致。
九、抽象類和接口的區(qū)別
抽象類可以有默認(rèn)的方法進(jìn)行實(shí)現(xiàn),可以有構(gòu)造器,可以有 main 方法進(jìn)行運(yùn)行,可以直接在該類中添加實(shí)現(xiàn)的方法接口沒有默認(rèn)的方法進(jìn)行實(shí)現(xiàn),沒有構(gòu)造器,不可以使用 main 方法進(jìn)行運(yùn)行,在接口中添加方法時(shí)需要在具體實(shí)現(xiàn)的類中添加方法。
十、 Java面向?qū)ο蟮奶卣髋c含義
- 封裝:封裝的目的在于實(shí)現(xiàn)程序的“高內(nèi)聚,低耦合”,防止程序相互依賴而帶來的變動(dòng)影響。封裝是保證是把對(duì)同一事物進(jìn)行操作的方法和相關(guān)的方法放在同一個(gè)類中,把方法和他操作的數(shù)據(jù)放在同一個(gè)類中;
- 抽象:抽象就是找出事物的相似和共性,然后將這些事物歸為同一類,這個(gè)類只考慮這些事物的相似和共性,忽略和當(dāng)前主題不相關(guān)的因素;
- 繼承:子類繼承父類的內(nèi)容作為自己的內(nèi)容,可以加入新的內(nèi)容或者是修改父類的內(nèi)容而更加適合特殊的需要。提高了額程序的可重用性和可擴(kuò)張性;
- 多態(tài):多態(tài)是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量倒底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。
十一、java多態(tài)的實(shí)現(xiàn)
接口實(shí)現(xiàn),繼承父類進(jìn)行方法重寫,
同一個(gè)類中進(jìn)行方法重載。
十二、運(yùn)行時(shí)異常和一般異常的區(qū)別
異常表示程序運(yùn)行過程中可能出現(xiàn)的非正常狀態(tài)。運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見的運(yùn)行錯(cuò)誤。java 編譯器要求方法必須聲明拋出可能出現(xiàn)的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的異常。
十三、Java語(yǔ)言如何進(jìn)行異常處理,throws,throw,try catch finally 代表什么意義,try 塊中可以拋出異常嗎?
Java 通過面向?qū)ο蟮姆椒ㄟM(jìn)行異常處理,把各種不同的異常進(jìn)行分類,并提供了良好的接口。在 Java 中,每個(gè)異常都是一個(gè)對(duì)象,它是 Throwable 類或其它子類的實(shí)例。當(dāng)一個(gè)
方法出現(xiàn)異常后便拋出一個(gè)異常對(duì)象,該對(duì)象中包含有異常信息,調(diào)用這個(gè)對(duì)象的方法可以捕獲到這個(gè)異常并進(jìn)行處理。Java 的異常處理是通過 5 個(gè)關(guān)鍵詞來實(shí)現(xiàn)的:try、catch、throw、throws 和 finally。一般情況下是用 try 來執(zhí)行一段程序,如果出現(xiàn)異常,系統(tǒng)會(huì)拋出(throws)一個(gè)異常,這時(shí)候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理。
用try來指定一塊預(yù)防所有”異?!钡某绦?。緊跟在 try 程序后面,應(yīng)包含一個(gè) catch 子句來指定你想要捕捉的”異?!钡念愋?。
throw 語(yǔ)句用來明確地拋出一個(gè)”異?!?;
throws 用來標(biāo)明一個(gè)成員函數(shù)可能拋出的各種”異?!?;
Finally 為確保一段代碼不管發(fā)生什么”異?!倍急粓?zhí)行一段代碼;
可以在一個(gè)成員函數(shù)調(diào)用的外面寫一個(gè) try 語(yǔ)句,在這個(gè)成員函數(shù)內(nèi)部寫另一個(gè) try 語(yǔ)句保護(hù)其他代碼。每當(dāng)遇到一個(gè) try 語(yǔ)句,”異?!钡目蚣芫头诺蕉褩I厦?,直到所有的 try 語(yǔ)句都完成;
如果下一級(jí)的 try 語(yǔ)句沒有對(duì)某種”異?!边M(jìn)行處理,堆棧就會(huì)展開,直到遇到有處理這種”異?!钡?try 語(yǔ)句。
十四、 try catch finally,try里有return,finally還執(zhí)行么?
- finally 語(yǔ)句總會(huì)執(zhí)行;
- 如果 try、catch 中有 return 語(yǔ)句,finally 中沒有 return,那么在 finally 中修改除包裝類型和靜態(tài)變量、全局變量以外的數(shù)據(jù)都不會(huì)對(duì) try、catch 中返回的變量有任何的影響(包裝類型、靜態(tài)變量會(huì)改變、全局變量);
- 盡量不要在 finally 中使用 return 語(yǔ)句,如果使用的話,會(huì)忽略 try、catch 中的返回語(yǔ)句,也會(huì)忽略 try、catch 中的異常,屏蔽了錯(cuò)誤的發(fā)生;
- finally 中避免再次拋出異常,一旦 finally 中發(fā)生異常,代碼執(zhí)行將會(huì)拋出 finally 中的異常信息,try、catch 中的異常將被忽略。
十五、 Java 中 final、finally 和 finalize 的區(qū)別
- final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承;內(nèi)部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼……
- finally 是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行;
- finalize 是 Object 類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。JVM 不保證此方法總被調(diào)用。
十六、String、StringBuffer與StringBuilder的區(qū)別
- String 表示內(nèi)容不可修改的字符串,StringBuffer 表示內(nèi)容可以修改的字符串;
- String 覆蓋了 equals()方法和 hashcode()方法,而 StringBuffer 沒有覆蓋兩個(gè)方法,,所以 StringBuffer 對(duì)象存儲(chǔ)到 java 集合類中時(shí)會(huì)出現(xiàn)問題;
- StringBulider 也表示內(nèi)容可以修改的字符串,但是其線程是不安全的,運(yùn)行效率高。
十七、error和exception區(qū)別
- error 表示有可能恢復(fù)但比較困難的的一種嚴(yán)重問題,程序是不能進(jìn)行處理的;
- exception 表示一種設(shè)計(jì)或者實(shí)現(xiàn)問題。
十八、Java 中的異常處理機(jī)制和簡(jiǎn)單原理和應(yīng)用
JAVA 程序違反了 JAVA 的語(yǔ)義規(guī)則時(shí),JAVA虛擬機(jī)就會(huì)將發(fā)生的錯(cuò)誤表示為一個(gè)異常。違反語(yǔ)義規(guī)則包括 2 種情況:
一種是JAVA類庫(kù)內(nèi)置的語(yǔ)義檢查。例如數(shù)組下標(biāo)越界,會(huì)引發(fā) IndexOutOfBoundsException; 訪問 null 的對(duì)象時(shí)會(huì)引發(fā) NullPointerException。
另一種情況就是 JAVA 允許程序員擴(kuò)展這種語(yǔ)義檢查,程序員可以創(chuàng)建自己的異常,并自由選擇在何時(shí)用 throw 關(guān)鍵字引發(fā)異常。所有的異常都是 java.lang.Thowable 的子類。
十九、 常見的運(yùn)行時(shí)異常
系統(tǒng)異常是 RuntimeException 的子類,常見的系統(tǒng)異常有:
- ArrayIndexOutOfBoundsException - 數(shù)組越界訪問
- ClassCastException - 類型轉(zhuǎn)換異常
- NullPointerException - 試圖訪問一空對(duì)象的變量、方法或空數(shù)組的元素
- IllegalArgumentException - 方法的參數(shù)無效
- NoClassDefFoundException - JAVA運(yùn)行時(shí)系統(tǒng)找不到所引用的類
二十、 Set 里面的元素不能重復(fù),用什么方法區(qū)分重復(fù)與否?
- Set里的元素是唯一不能重復(fù)的,元素是否重復(fù)使用 equals() 方法進(jìn)行判斷。
- equals() 方法和 == 方法決定引用值是否指向同一對(duì)象 equals() 在類中被覆蓋,為的是兩個(gè)分離的對(duì)象的內(nèi)容和類型相匹配的話,返回真值。
二十一、HashMap 和 Hashtable 的區(qū)別
- Hashtable 是基于 Dictionary 類的,HashMap 是 Map 接口的一個(gè)實(shí)現(xiàn)類;
- Hashtable 是線程安全的,即是同步的;HashMap 線程不是安全的,不是同步的;
- HashMap 可以將空值作為 key 或 value。
二十二、 HashMap、LinkedHashMap、TreeMap的區(qū)別
- HashMap 是根據(jù)鍵的 hashcode 值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問速度,取得的數(shù)據(jù)完全是隨機(jī)的;
- LinkedHashMap 保存了記錄的插入順序,在使用 Iterator 進(jìn)行遍歷的時(shí)候,先得到的肯定是先插入的數(shù)據(jù),可以在構(gòu)造時(shí)帶參數(shù),按照應(yīng)用次數(shù)來進(jìn)行排序;
- TreeMap 實(shí)現(xiàn) SortMap 接口,能夠把它保存的記錄根據(jù)鍵排序。默認(rèn)的是升序排序,也可以指定排序的比較器,進(jìn)行遍歷的時(shí)候得到的是排序過的記錄。
二十三、HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底層實(shí)現(xiàn)。
- HashMap 是 java 數(shù)據(jù)結(jié)構(gòu)中兩大結(jié)構(gòu)數(shù)組和鏈表的組合。HashMap 底層數(shù)組,數(shù)組中的每一項(xiàng)又是一個(gè)鏈表。程序會(huì)先根據(jù)key的hashcode()方法返回值決定該 Entry 在數(shù)組中的存儲(chǔ)位置,如果該位置上沒有元素,就會(huì)將元素放置在此位置上,如果兩個(gè) Entry 的 key 相同,會(huì)調(diào)用 equals,返回值是 true 則覆蓋原來的value值,返回 false 則會(huì)形成 Entry 鏈,位于頭部。
- ArrrayList 的底層實(shí)現(xiàn)是數(shù)組,在執(zhí)行 add 操作時(shí),會(huì)先檢查數(shù)組大小是否可以容納新的元素,如果不夠就會(huì)進(jìn)行擴(kuò)容。然后會(huì)將原來的數(shù)據(jù)拷貝到新的數(shù)組中。
- LinkedList 底層是一個(gè)鏈表,其實(shí)現(xiàn)增刪改查和數(shù)據(jù)結(jié)構(gòu)中的操作完全相同,而且插入是有序的。
- LinkedHashMap 的底層結(jié)構(gòu)式是雙鏈表,其他的邏輯處理與 HashMap 一致,同樣沒有鎖保護(hù),多線程使用時(shí)存在風(fēng)險(xiǎn)。
- ConcurrentHashMap 是 segment 數(shù)組結(jié)構(gòu)和 HashEntry 數(shù)組結(jié)構(gòu)組成的,segment 在 ConcurrentHashMap 中充當(dāng)鎖的角色,HashEntry 用于存儲(chǔ)鍵值對(duì)數(shù)據(jù)。segment 的結(jié)構(gòu)是數(shù)組和鏈表,一個(gè)segment中有一個(gè) HashEntry,每個(gè) HashEntry 是一個(gè)鏈表結(jié)構(gòu)的元素。對(duì) HashEntry 中的數(shù)據(jù)進(jìn)行修改時(shí),需要先獲得它所對(duì)應(yīng)的 segment 鎖。每個(gè) ConcurrentHashMap 默認(rèn)有 16 個(gè) segment。
二十四、迭代器Iterator
Iterator 提供了統(tǒng)一遍歷操作集合元素的統(tǒng)一接口,Collection 接口實(shí)現(xiàn) Iterator 接口。每個(gè)集合都通過實(shí)現(xiàn) Iterator 接口中的iterator() 方法返回實(shí)例,然后對(duì)元素進(jìn)行迭代操作,但是在迭代元素的時(shí)候不能使用集合的方法刪除元素,否則會(huì)拋出異常,可以使用 Iterator 接口中的 remove() 方法進(jìn)行刪除。
二十五、Map、Set、List、Queue、Stack的特點(diǎn)與用法。
1、Map 是以鍵值對(duì)的形式進(jìn)行存儲(chǔ)的,其中 key 是唯一不可重復(fù)的,value 的可以重復(fù),當(dāng)插入的值是 key 相同,后加入的會(huì)將已有的覆蓋。他有幾個(gè)具體的實(shí)現(xiàn)類,包括 Treemap 和 HashMap,TreeMap 是有序的,HashMap 是無序的。
2、List 有序,可重復(fù)
|–ArrayList
底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢,線程不安全,效率高
|–Vector
底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢,線程不安全,效率高
|–LinkedList
底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪塊,線程安全,效率低
3、Set 無序,唯一
|–HashSet
底層數(shù)據(jù)結(jié)構(gòu)是哈希表
如何保證元素的唯一性:
依賴兩個(gè)方法,hashCode() 和 equals()
|–LinkedHashSet
底層數(shù)據(jù)結(jié)構(gòu)是鏈表和哈希表,由鏈表保證元素有序,由哈希表保證元素唯一
|–TreeSet 底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹,
如何保證元素的排序:
自然排序:讓元素所屬的類實(shí)現(xiàn) Comparable 接口
比較器排序:讓集合接收一個(gè) Comparator 的實(shí)現(xiàn)類對(duì)象
如何保證元素的唯一性:
根據(jù)比較的返回值是否是 0 來決定的
4、Query 隊(duì)列遵循先進(jìn)先出的原則,不允許插入null值,其中提供了相應(yīng)的進(jìn)隊(duì)和出隊(duì)的方法,建議使用offer() 方法來添加元素,使用poll() 方法刪除元素
5、Stack遵從后進(jìn)先出的原則,繼承自 Vector。他通過 5 個(gè)操作對(duì) Vector 類進(jìn)行擴(kuò)展,它提供了 push 和 pop 操作,以及去堆棧頂點(diǎn)的peek() 方法,測(cè)試堆棧是否為空的 empty 方法
6、使用方法:
如果涉及到堆棧,隊(duì)列等操作,建議使用 List
對(duì)于快速插入和刪除元素建議使 用LinkedList
需要快速隨機(jī)訪問元素建議使用 ArrayList
二十六、Collection 包結(jié)構(gòu)
Collection 是集合類的上級(jí)接口,是單列集合。繼承他的接口主要有 Set 和 List.
Set接口的子接口有:HashSet,TreeSet
List接口的子接口有:Arraylist,LinkedList,Vector
二十七、Collection 與 Collections 的區(qū)別。
Collection 是集合類的上級(jí)接口,繼承他的接口有 Set 和 List;
Collections 是針對(duì)集合類的一個(gè)幫助類,它提供一系列的靜態(tài)方法實(shí)現(xiàn)集合的搜索,排序,線程安全等操作。
二十八、 Colection 框架中實(shí)現(xiàn)比較要實(shí)現(xiàn)什么接口?
comparable:只包含 compareTo() 方法
comparator:compare() 和 equals()
二十九、Collection框架的結(jié)構(gòu)
集合框架(Collection Framework)泛指 java.util 包的若干個(gè)類和接口。如 Collection, List, ArrayList, LinkedList, Vector( 自動(dòng)增長(zhǎng)數(shù)組), HashSet, HashMap 等;
集合框架中的類主要封裝的是典型的數(shù)據(jù)結(jié)構(gòu),如動(dòng)態(tài)數(shù)組,鏈表,堆棧,集合,哈希表等;
集合框架類似編程中經(jīng)常用到的工具類,使得編碼這專注于業(yè)務(wù)層的實(shí)現(xiàn),不需要從底層實(shí)現(xiàn)相關(guān)細(xì)節(jié)—“數(shù)據(jù)結(jié)構(gòu)的封裝”和”典型算法的實(shí)現(xiàn)”。
三十、 快速失?。╢ail-fast)和安全失?。╢ail-safe)的區(qū)別。
Iterator 的安全失敗是基于對(duì)底層集合做拷貝,因此它不受源集合修改的影響。util 包下的所有集合類都是快速失敗的,util.concurren包下面的所有類都是安全失敗的。
推薦好課:Java開發(fā)實(shí)例:坦克大戰(zhàn)游戲、Java零基礎(chǔ)之io流詳解