溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java常見的10道面試題是什么

發(fā)布時間:2022-01-04 16:43:38 來源:億速云 閱讀:231 作者:iii 欄目:編程語言

這篇文章主要講解了“Java常見的10道面試題是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java常見的10道面試題是什么”吧!

1.什么是并發(fā)修改異常?

什么是并發(fā)修改異常:
當(dāng)我們在遍歷實現(xiàn)了collection接口
與iterator接口的集合時(List、Set、Map), 
我們可以通過遍歷索引
也可以通過迭代器進行遍歷。
在我們使用迭代器進行遍歷集合的時候,
會獲取到當(dāng)前集合的迭代對象。
在里面有封裝了迭代器的remove方法
與集合自帶的remove方法,
如果我們調(diào)用迭代器對象的remove方法
是沒問題的,
但是當(dāng)我們調(diào)用集合自帶的remove方法時,
就會產(chǎn)生ConcurrentModificationException 
并發(fā)修改異常。
也就是說,
當(dāng)我們通過迭代器進行遍歷集合的時候,
是不允許集合本身在結(jié)構(gòu)上發(fā)生變化的。

2.什么是CopyOnWriteArrayList,它與ArrayList有何不同?

CopyOnWriteArrayList:
CopyOnWriteArrayList這是一個
ArrayList的線程安全的變體,
其原理大概可以通俗的理解為:
初始化的時候只有一個容器,
很常一段時間,
這個容器數(shù)據(jù)、
數(shù)量等沒有發(fā)生變化的時候,
大家(多個線程),都是讀取
假設(shè)這段時間里只發(fā)生讀取的操作
同一個容器中的數(shù)據(jù),
所以這樣大家讀到的數(shù)據(jù)都是
唯一、一致、安全的,
但是后來有人往里面增加了一個數(shù)據(jù),
這個時候CopyOnWriteArrayList 底層實現(xiàn)
添加的原理是先copy出一個容器
可以簡稱副本,
再往新的容器里添加這個新的數(shù)據(jù),
最后把新的容器的引用地址
賦值給了之前那個舊的的容器地址,
但是在添加這個數(shù)據(jù)的期間,
其他線程如果要去讀取數(shù)據(jù),
仍然是讀取到舊的容器里的數(shù)據(jù)。
Vector 
ArrayList 
CopyOnWriteArrayList 
這三個集合類都繼承List接口
1、ArrayList是線程不安全的;
2、Vector是比較古老的線程安全的,
但性能不行;
3、CopyOnWriteArrayList在兼顧了
線程安全的同時,
又提高了并發(fā)性,
性能比Vector有不少提高

3.迭代器和枚舉之間的區(qū)別?

在Java集合中,
我們通常都通過 “Iterator(迭代器)” 
或 “Enumeration(枚舉類)” 去遍歷集合。
Enumeration是一個接口,它的源碼如下:
package java.util;
public interface Enumeration<E> {
 boolean hasMoreElements()
 E nextElement();
}
Iterator也是一個接口,它的源碼如下:
package java.util;
public interface Iterator<E> {
 boolean hasNext();
 E next();
 void remove();
}
區(qū)別:
1 函數(shù)接口不同
Enumeration只有2個函數(shù)接口。
通過Enumeration,
我們只能讀取集合的數(shù)據(jù),
而不能對數(shù)據(jù)進行修改。
Iterator只有3個函數(shù)接口。
Iterator除了能讀取集合的數(shù)據(jù)之外,
也能數(shù)據(jù)進行刪除操作。
2.Iterator支持fail-fast機制,而Enumeration不支持。
Enumeration 是JDK 1.0添加的接口。 
使用到它的函數(shù)包括Vector、Hashtable等類,
這些類都是JDK 1.0中加入的,
Enumeration存在的目的
就是為它們提供遍歷接口。
Enumeration本身并沒有支持同步,
而在Vector、Hashtable實現(xiàn)Enumeration時,
添加了同步。
而Iterator 是JDK 1.2才添加的接口,
它也是為了HashMap、ArrayList等集合
提供遍歷接口。
Iterator是支持fail-fast機制的:
當(dāng)多個線程對同一個集合的內(nèi)容進行操作時,
就可能會產(chǎn)生fail-fast事件。
Java API規(guī)范建議,
對于較新的程序,
Iterator應(yīng)優(yōu)先于Enumeration,
因為“ Iterator在Java集合框架中
代替Enumeration?!?
64.Hashmap如何同步?
1、使用 synchronized 關(guān)鍵字,
這也是最原始的方法。
synchronized(anObject) 
{ 
 value = map.get(key); 
} 
2、使用 JDK1.5 提供的鎖
Java.util.concurrent.locks.Lock
lock.lock(); 
value = map.get(key); 
lock.unlock(); 
3.可以使用 JDK1.5 提供的讀寫鎖
java.util.concurrent.locks.ReadWriteLock
rwlock.readLock().lock(); 
value = map.get(key); 
rwlock.readLock().unlock(); 
4.使用 JDK1.5 提供的 
java.util.concurrent.ConcurrentHashMap 類
該類將 Map 的存儲空間分為若干塊,
每塊擁有自己的鎖,
大大減少了多個線程
爭奪同一個鎖的情況
value = map.get(key); 
1、不同步確實最快,與預(yù)期一致。 
2、四種同步方式中,
ConcurrentHashMap 是最快的,
接近不同步的情況。 
3、synchronized 關(guān)鍵字非常慢
4、使用讀寫鎖的讀鎖,比普通所稍慢。
1、如果 ConcurrentHashMap 夠用,
則使用 ConcurrentHashMap。 
2、如果需自己實現(xiàn)同步,
則使用 JDK1.5 提供的鎖機制,
避免使用 synchronized 關(guān)鍵字。

5.IdentityHashMap和HashMap的區(qū)別?

前者比較key時是
“引用相等”
而后者是
“對象相等”,
即對于
k1和k2,當(dāng)k1==k2時, 
IdentityHashMap認(rèn)為兩個key相等,
而HashMap只有在k1.equals(k2) == true 時
才會認(rèn)為兩個key相等。 
2.IdentityHashMap 允許使用null作為key和value. 
不保證任何Key-value對的之間的順序, 
更不能保證他們的順序
隨時間的推移不會發(fā)生變化。 
3.IdentityHashMap有其特殊用途,
比如序列化或者深度復(fù)制?;?
者記錄對象代理。 
舉個例子,
jvm中的所有對象都是獨一無二的,
哪怕兩個對象是同一個class的對象 
而且兩個對象的數(shù)據(jù)完全相同,
對于jvm來說,
他們也是完全不同的, 
如果要用一個map來記錄這樣jvm中的對象,
你就需要用IdentityHashMap,
而不能使用其他Map實現(xiàn)

6.如何獲取某個日期是當(dāng)月的最后一天?

import java.util.Calendar;
public class Test {
public static void main(String[] args) {
 System.out.println(daysCount(2010, 2));
}
public static int daysCount(int year, int month) {
 Calendar cal = Calendar.getInstance();
 cal.set(Calendar.YEAR, year);
 cal.set(Calendar.MONTH, month);
 cal.set(Calendar.DATE, 0);
 return cal.get(Calendar.DATE);
}
}

7.java中會存在內(nèi)存泄漏嗎,請簡單描述

所謂內(nèi)存泄露就是指
一個不再被程序使用的對象或變量
一直被占據(jù)在內(nèi)存中。
Java中有垃圾回收機制,
它可以保證一對象不再被引用的時候,
即對象編程了孤兒的時候,
對象將自動被垃圾回收器
從內(nèi)存中清除掉。
由于Java 使用有向圖的方式
進行垃圾回收管理,
可以消除引用循環(huán)的問題,
例如有兩個對象,相互引用,
只要它們和根進程不可達的,
那么GC也是可以回收它們的。
java中的內(nèi)存泄露的情況:
長生命周期的對象持有
短生命周期對象的引用
就很可能發(fā)生內(nèi)存泄露,
盡管短生命周期對象已經(jīng)不再需要,
但是因為長生命周期對象
持有它的引用而導(dǎo)致不能被回收,
這就是java中內(nèi)存泄露的發(fā)生場景,
通俗地說,
就是程序員可能創(chuàng)建了一個對象,
以后一直不再使用這個對象,
這個對象卻一直被引用,
即這個對象無用
但是卻無法被垃圾回收器回收的,
這就是java中可能出現(xiàn)
內(nèi)存泄露的情況,
例如,緩存系統(tǒng),
我們加載了一個對象放在緩存中(例如放在一個全局map對象中),
然后一直不再使用它,
這個對象一直被緩存引用,
但卻不再被使用。 
檢查java中的內(nèi)存泄露,
一定要讓程序?qū)⒏鞣N分支情況
都完整執(zhí)行到程序結(jié)束,
然后看某個對象是否被使用過,
如果沒有,
則才能判定這個對象屬于內(nèi)存泄露。
如果一個外部類的實例對象的方法
返回了一個內(nèi)部類的實例對象,
這個內(nèi)部類對象被長期引用了,
即使那個外部類實例對象不再被使用,
但由于內(nèi)部類持久外部類的實例對象,
這個外部類對象將不會被垃圾回收,
這也會造成內(nèi)存泄露。
內(nèi)存泄露的另外一種情況:
當(dāng)一個對象被存儲進HashSet集合中以后,
就不能修改這個對象中的
那些參與計算哈希值的字段了,
否則,對象修改后的哈希值
與最初存儲進HashSet集合中時的哈希值
就不同了,
在這種情況下,
即使在contains方法使用該對象的
當(dāng)前引用作為的參數(shù)去HashSet集合中
檢索對象,
也將返回找不到對象的結(jié)果,
這也會導(dǎo)致無法從HashSet集合中
單獨刪除當(dāng)前對象,
造成內(nèi)存泄露
68.java中實現(xiàn)多態(tài)的機制是什么?
靠的是父類或接口的
引用指向子類或?qū)崿F(xiàn)類的對象,
調(diào)用的方法是內(nèi)存中
正在運行的那個對象的方法。
Java實現(xiàn)多態(tài)有三個必要條件:
繼承、
重寫、
向上轉(zhuǎn)型。
繼承:
在多態(tài)中必須存在
有繼承關(guān)系的子類和父類。
重寫:
子類對父類中某些方法進行重新定義,
在調(diào)用這些方法時
就會調(diào)用子類的方法。
向上轉(zhuǎn)型:
在多態(tài)中需要將子類的引用
賦給父類對象,
只有這樣該引用才能夠具備
技能調(diào)用父類的方法和子類的方法。
只有滿足了上述三個條件,
我們才能夠在同一個繼承結(jié)構(gòu)中
使用統(tǒng)一的邏輯實現(xiàn)代碼處理不同的對象,
從而達到執(zhí)行不同的行為。
多態(tài)機制遵循的原則概括為
當(dāng)超類對象引用變量引用子類對象時,
被引用對象的類型
而不是引用變量的類型
決定了調(diào)用誰的成員方法,
但是這個被調(diào)用的方法
必須是在超類中定義過的,
也就是說被子類覆蓋的方法,
但是它仍然要根據(jù)繼承鏈中
方法調(diào)用的優(yōu)先級來確認(rèn)方法,
該優(yōu)先級為:
this.method(O)、
super.method(O)、
this.method((super)O)、
super.method((super)O)。

8.java中實現(xiàn)多態(tài)的機制是什么?

靠的是父類或接口的
引用指向子類或?qū)崿F(xiàn)類的對象,
調(diào)用的方法是內(nèi)存中
正在運行的那個對象的方法。
Java實現(xiàn)多態(tài)有三個必要條件:
繼承、
重寫、
向上轉(zhuǎn)型。
繼承:
在多態(tài)中必須存在
有繼承關(guān)系的子類和父類。
重寫:
子類對父類中某些方法進行重新定義,
在調(diào)用這些方法時
就會調(diào)用子類的方法。
向上轉(zhuǎn)型:
在多態(tài)中需要將子類的引用
賦給父類對象,
只有這樣該引用才能夠具備
技能調(diào)用父類的方法和子類的方法。
只有滿足了上述三個條件,
我們才能夠在同一個繼承結(jié)構(gòu)中
使用統(tǒng)一的邏輯實現(xiàn)代碼處理不同的對象,
從而達到執(zhí)行不同的行為。
多態(tài)機制遵循的原則概括為
當(dāng)超類對象引用變量引用子類對象時,
被引用對象的類型
而不是引用變量的類型
決定了調(diào)用誰的成員方法,
但是這個被調(diào)用的方法
必須是在超類中定義過的,
也就是說被子類覆蓋的方法,
但是它仍然要根據(jù)繼承鏈中
方法調(diào)用的優(yōu)先級來確認(rèn)方法,
該優(yōu)先級為:
this.method(O)、
super.method(O)、
this.method((super)O)、
super.method((super)O)。

9.局部變量和成員變量的區(qū)別?

成員變量與局部變量的區(qū)別
1、在類中的位置不同
成員變量:
在類中方法外面
局部變量:
在方法或者代碼塊中,
或者方法的聲明上
2、在內(nèi)存中的位置不同,
成員變量:在堆中(方法區(qū)中的靜態(tài)區(qū))
局部變量:在棧中
3、生命周期不同
成員變量:
隨著對象的創(chuàng)建而存在,
隨著對象的消失而消失
局部變量:
隨著方法的調(diào)用或者代碼塊的執(zhí)行
而存在,
隨著方法的調(diào)用完畢或者
代碼塊的執(zhí)行完畢而消失
4、初始值
成員變量:
有默認(rèn)初始值
局部變量:
沒有默認(rèn)初始值,
使用之前需要賦值,
否則編譯器會報錯

10.什么是匿名類,有什么好處?

簡單地說:
匿名內(nèi)部類就是沒有名字的內(nèi)部類。
什么情況下需要使用匿名內(nèi)部類?
如果滿足下面的一些條件,
使用匿名內(nèi)部類是比較合適的:
 
只用到類的一個實例。 
類在定義后馬上用到。 
類非常?。⊿UN推薦是在4行代碼以下) 
給類命名并不會導(dǎo)致你的代碼更容易被理解。 
在使用匿名內(nèi)部類時,要記住以下幾個原則: 
匿名內(nèi)部類不能有構(gòu)造方法。 
匿名內(nèi)部類不能定義任何靜態(tài)成員、方法和類。 
匿名內(nèi)部類不能是
public,protected,private,static。 
只能創(chuàng)建匿名內(nèi)部類的一個實例。 
一個匿名內(nèi)部類一定是在new的后面,
用其隱含實現(xiàn)一個接口或?qū)崿F(xiàn)一個類。 
因匿名內(nèi)部類為局部內(nèi)部類,
所以局部內(nèi)部類的所有限制都對其生效。

感謝各位的閱讀,以上就是“Java常見的10道面試題是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java常見的10道面試題是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI