equals和==有什么區(qū)別
"=="是是不是指向同一個(gè)內(nèi)存空間友存。
"equals"是判斷所指向的內(nèi)存空間的值是不是相同。
"equals"是方法陶衅。
"=="是運(yùn)算符合屡立。
"=="比"equals"運(yùn)行速度快,因?yàn)?=="只是比較引用搀军。
權(quán)限修飾符
抽象類和接口區(qū)別
- 定義和實(shí)現(xiàn)功能的限制不同膨俐。在接口中只允許定義勇皇,不允許對方法進(jìn)行實(shí)現(xiàn),并且接口中定義的屬性不可改變焚刺;在抽象類中可以有一般方法的實(shí)現(xiàn)敛摘,也可以有抽象方法,可以定義變量乳愉。
- 一個(gè)類只能繼承一個(gè)父類兄淫,但是一個(gè)類可以實(shí)現(xiàn)多個(gè)接口
修飾的關(guān)鍵字有區(qū)別。在接口中蔓姚,所有方法都只能用public拖叙,abstract這兩個(gè)關(guān)鍵字來修飾,所有定義的成員變量為public赂乐,static,final咖气。而在抽象類中挨措,可以有自己的成員變量和方法,也可以有非抽象的成員方法崩溪;而且浅役,在抽象類中,抽象類的成員變量默認(rèn)為default伶唯,當(dāng)然也可以自行定義為public觉既,protected,private乳幸,這些成員變量在子類中可以重新被定義也可以重新被賦值瞪讼;但是抽象類中的抽象方法(方法前有abstract修飾)不能用private,static粹断,synchronized和native等訪問修飾符來修飾符欠。 - 應(yīng)用的功能場景不同。接口被用于實(shí)現(xiàn)比較常用的功能瓶埋,便于日后維護(hù)或者添加刪除方法希柿,而抽象類更傾向于公共類的角色,不適用于日后重對里面的代碼進(jìn)行修改养筒。
深拷貝和淺拷貝
淺拷貝只復(fù)制指向某個(gè)對象的指針曾撤,而不復(fù)制對象本身,新舊對象還是共享同一塊內(nèi)存晕粪。但深拷貝會(huì)另外創(chuàng)造一個(gè)一模一樣的對象挤悉,新對象跟原對象不共享內(nèi)存,修改新對象不會(huì)改到原對象兵多。
&和&& (|和||同理)
1.運(yùn)算符性質(zhì)不同尖啡。
&是一個(gè)位運(yùn)算符橄仆。
&&是一個(gè)邏輯運(yùn)算符。
2.作用不同衅斩。
&是將兩個(gè)二進(jìn)制的數(shù)逐位相與盆顾,結(jié)果是相遇之后的結(jié)果。
&&就是判斷兩個(gè)表達(dá)式的真假性畏梆,只有兩個(gè)表達(dá)式同時(shí)為真才為真您宪,有一個(gè)為假則為假,具有短路性質(zhì)奠涌。
線程產(chǎn)生死鎖的四個(gè)必備條件及解決方法
產(chǎn)生死鎖的四個(gè)必要條件
(1) 互斥條件:該資源任意一個(gè)時(shí)刻只由一個(gè)線程占用宪巨。
(2)請求與保持條件:一個(gè)進(jìn)程因請求某資源而堵塞時(shí),對已獲得的資源保持不放溜畅。
(3)不剝奪條件:線程已獲得的資源在未使用完之前不能被其他線程強(qiáng)行掠奪捏卓,只有自己使用完之后才能釋放資源。
(4)循環(huán)等待條件:**若干進(jìn)程之間形成的一種頭尾相接的循環(huán)等待資源關(guān)系慈格。
解決方法
(1)破壞請求與保持條件:一次性申請所有需要用到的資源怠晴。
(2)破壞不剝奪條件:占用部分資源的線程進(jìn)一步申請不到其他的資源時(shí),可以主動(dòng)釋放它占有的資源浴捆。
(3)破壞循環(huán)等待條件:按某種序申請資源蒜田,釋放資源則反序釋放,破壞循環(huán)等待條件选泻。
強(qiáng)軟弱虛引用
1冲粤,強(qiáng)引用
強(qiáng)引用是使用最多的引用,如果一個(gè)對象具有強(qiáng)引用页眯,那么在該對象時(shí)不會(huì)被gc所回收的梯捕。
Object object = new Object(); //強(qiáng)引用
當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤餐茵,使程序異常終止科阎,也不會(huì)靠隨意回收具有強(qiáng)引用的對象來解決內(nèi)存不足的問題。如果不使用時(shí)忿族,要通過如下方式來弱化引用锣笨,如下:
object = null //將該對象弱化,這樣一來gc才能夠成功回收該數(shù)據(jù)
在一個(gè)方法的內(nèi)部有一個(gè)強(qiáng)引用道批,這個(gè)引用保存在棧中错英,而真正的引用內(nèi)容(Object)保存在堆中。當(dāng)這個(gè)方法運(yùn)行完成后就會(huì)退出方法棧隆豹,則引用內(nèi)容的引用不存在椭岩,這個(gè)Object會(huì)被回收。
但是如果這個(gè)object是全局的變量時(shí),就需要在不用這個(gè)對象時(shí)賦值為null判哥,因?yàn)閺?qiáng)引用不會(huì)被垃圾回收献雅。
2、軟引用(SoftReference)
如果一個(gè)對象只具有軟引用塌计,則內(nèi)存空間足夠挺身,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了锌仅,就會(huì)回收這些對象的內(nèi)存章钾。只要垃圾回收器沒有回收它,該對象就可以被程序使用热芹。
String str=new String(“abc”); // 強(qiáng)引用
SoftReference softRef=new SoftReference(str); // 軟引用
3贱傀、弱引用(WeakReference)
弱引用與軟引用的區(qū)別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過程中伊脓,一旦發(fā)現(xiàn)了只具有弱引用的對象府寒,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存报腔。不過椰棘,由于垃圾回收器是一個(gè)優(yōu)先級很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對象榄笙。
String str=new String(“abc”);
WeakReference abcWeakRef = new WeakReference(str);
str=null
當(dāng)垃圾回收器進(jìn)行掃描回收時(shí)等價(jià)于:
str = null;
System.gc();
如果這個(gè)對象是偶爾的使用,并且希望在使用時(shí)隨時(shí)就能獲取到祷蝌,但又不想影響此對象的垃圾收集茅撞,那么你應(yīng)該用 WeakReference 來記住此對象。
下面的代碼會(huì)讓str再次變?yōu)橐粋€(gè)強(qiáng)引用:
String abc = abcWeakRef.get();
弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用巨朦,如果弱引用所引用的對象被垃圾回收米丘,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
當(dāng)你想引用一個(gè)對象糊啡,但是這個(gè)對象有自己的生命周期拄查,你不想介入這個(gè)對象的生命周期,這時(shí)候你就是用弱引用棚蓄。
package reference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
public class ReferenceTest {
private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>();
public static void checkQueue() {
Reference<? extends VeryBig> ref = null;
while ((ref = rq.poll()) != null) {
if (ref != null) {
System.out.println("In queue: "
+ ((VeryBigWeakReference) (ref)).id);
}
}
}
public static void main(String args[]) {
int size = 3;
LinkedList<WeakReference<VeryBig>> weakList = new LinkedList<WeakReference<VeryBig>>();
for (int i = 0; i < size; i++) {
weakList.add(new VeryBigWeakReference(new VeryBig("Weak " + i), rq));
System.out.println("Just created weak: " + weakList.getLast());
}
System.gc();
try { // 下面休息幾分鐘堕扶,讓上面的垃圾回收線程運(yùn)行完成
Thread.currentThread().sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
checkQueue();
}
}
class VeryBig {
public String id;
// 占用空間,讓線程進(jìn)行回收
byte[] b = new byte[2 * 1024];
public VeryBig(String id) {
this.id = id;
}
protected void finalize() {
System.out.println("Finalizing VeryBig " + id);
}
}
class VeryBigWeakReference extends WeakReference<VeryBig> {
public String id;
public VeryBigWeakReference(VeryBig big, ReferenceQueue<VeryBig> rq) {
super(big, rq);
this.id = big.id;
}
protected void finalize() {
System.out.println("Finalizing VeryBigWeakReference " + id);
}
}
結(jié)果為
Just created weak: reference.VeryBigWeakReference@570f80a9
Just created weak: reference.VeryBigWeakReference@3ac803e6
Just created weak: reference.VeryBigWeakReference@21780f30
Finalizing VeryBig Weak 0
Finalizing VeryBig Weak 2
Finalizing VeryBig Weak 1
In queue: Weak 0
In queue: Weak 1
In queue: Weak 2
4、虛引用(PhantomReference)
“虛引用”顧名思義梭依,就是形同虛設(shè)稍算,與其他幾種引用都不同,虛引用并不會(huì)決定對象的生命周期役拴。如果一個(gè)對象僅持有虛引用糊探,那么它就和沒有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動(dòng)科平。虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用褥紫。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對象時(shí),如果發(fā)現(xiàn)它還有虛引用瞪慧,就會(huì)在回收對象的內(nèi)存之前髓考,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
Java4種引用的級別由高到低依次為:
強(qiáng)引用 > 軟引用 > 弱引用 > 虛引用
TCP 和 UDP
1汞贸、TCP 面向連接(如打電話要先撥號建立連接); UDP 是無連接的绳军,即發(fā)送數(shù)據(jù)之前不需要建立連接。
2矢腻、TCP 提供可靠的服務(wù)门驾。也就是說,通過 TCP 連接傳送的數(shù)據(jù)多柑,無差錯(cuò)奶是,不丟失,不重復(fù)竣灌,且按序到達(dá)聂沙;UDP 盡最大努力交付,即不保證可靠交付初嘹。
3及汉、TCP 面向字節(jié)流,實(shí)際上是 TCP 把數(shù)據(jù)看成一連串無結(jié)構(gòu)的字節(jié)流屯烦;UDP 是面向報(bào)文的坷随。UDP 沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會(huì)使源主機(jī)的發(fā)送速率降低(對實(shí)時(shí)應(yīng)用很有用驻龟,如IP電話温眉,實(shí)時(shí)視頻會(huì)議等)
4、每一條 TCP 連接只能是點(diǎn)到點(diǎn)的翁狐;UDP支持一對一类溢,一對多,多對一和多對多的交互通信露懒。
5闯冷、TCP 首部開銷 20 字節(jié);UDP 的首部開銷小懈词,只有 8 個(gè)字節(jié)窃躲。
6、TCP 的邏輯通信信道是全雙工的可靠信道钦睡,UDP 則是不可靠信道蒂窒。
單例模式的實(shí)現(xiàn)有多種方式躁倒,如下所示:
1、懶漢式洒琢,線程不安全
是否 Lazy 初始化:是
是否多線程安全:否
實(shí)現(xiàn)難度:易
描述:這種方式是最基本的實(shí)現(xiàn)方式秧秉,這種實(shí)現(xiàn)最大的問題就是不支持多線程。因?yàn)闆]有加鎖 synchronized衰抑,所以嚴(yán)格意義上它并不算單例模式象迎。
這種方式 lazy loading 很明顯,不要求線程安全呛踊,在多線程不能正常工作砾淌。
實(shí)例
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
接下來介紹的幾種實(shí)現(xiàn)方式都支持多線程,但是在性能上有所差異谭网。
2汪厨、懶漢式,線程安全
是否 Lazy 初始化:是
是否多線程安全:是
實(shí)現(xiàn)難度:易
描述:這種方式具備很好的 lazy loading愉择,能夠在多線程中很好的工作劫乱,但是,效率很低锥涕,99% 情況下不需要同步衷戈。
優(yōu)點(diǎn):第一次調(diào)用才初始化,避免內(nèi)存浪費(fèi)层坠。
缺點(diǎn):必須加鎖 synchronized 才能保證單例殖妇,但加鎖會(huì)影響效率。
getInstance() 的性能對應(yīng)用程序不是很關(guān)鍵(該方法使用不太頻繁)破花。
實(shí)例
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3拉一、餓漢式
是否 Lazy 初始化:否
是否多線程安全:是
實(shí)現(xiàn)難度:易
描述:這種方式比較常用,但容易產(chǎn)生垃圾對象旧乞。
優(yōu)點(diǎn):沒有加鎖,執(zhí)行效率會(huì)提高磅氨。
缺點(diǎn):類加載時(shí)就初始化尺栖,浪費(fèi)內(nèi)存。
它基于 classloader 機(jī)制避免了多線程的同步問題烦租,不過延赌,instance 在類裝載時(shí)就實(shí)例化,雖然導(dǎo)致類裝載的原因有很多種叉橱,在單例模式中大多數(shù)都是調(diào)用 getInstance 方法挫以, 但是也不能確定有其他的方式(或者其他的靜態(tài)方法)導(dǎo)致類裝載,這時(shí)候初始化 instance 顯然沒有達(dá)到 lazy loading 的效果窃祝。
實(shí)例
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
4掐松、雙檢鎖/雙重校驗(yàn)鎖(DCL,即 double-checked locking)
JDK 版本:JDK1.5 起
是否 Lazy 初始化:是
是否多線程安全:是
實(shí)現(xiàn)難度:較復(fù)雜
描述:這種方式采用雙鎖機(jī)制,安全且在多線程情況下能保持高性能大磺。
getInstance() 的性能對應(yīng)用程序很關(guān)鍵抡句。
實(shí)例
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}