1. Java接口和抽象類的區(qū)別
語法上:
- 抽象類可以提供成員方法的實現(xiàn)細節(jié),而接口中只能存在public abstract 方法;
- 一個類只能繼承一個抽象類,而一個類卻可以實現(xiàn)多個接口。
- 抽象類可以在不提供接口方法的具體實現(xiàn)的情況下實現(xiàn)接口。
- 接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法,而抽象類可以有靜態(tài)代碼塊和靜態(tài)方法;
- 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;
設(shè)計層面:
- 抽象類是對一種事物的抽象,即對類抽象,而接口是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是接口卻是對類局部(行為)進行抽象。例如:設(shè)計一個鳥類Bird類,其中包括一些鳥類的公共屬性和方法,如:定義羽毛顏色,eat()方法等,再設(shè)計一個接口Fly接口,因為并不是所有的鳥都具有飛行的行為,所以只有能飛的鳥才去實現(xiàn)Fly接口。
- 設(shè)計層面不同,抽象類作為很多子類的父類,它是一種模板式設(shè)計。而接口是一種行為規(guī)范,它是一種輻射式設(shè)計。模板設(shè)計,A為抽象類,A1,A2都繼承A,如果公共部分需要修改,只需在A中進行改變,A1,A2都需要改變。但是接口如果改變,則所有實現(xiàn)都需要進行改變。
2. Java的值傳遞和引用傳遞
對象被值傳遞,意味著傳遞了對象的一個副本。因此,就算是改變了對象副本,也不會影響源對象的值。
對象被引用傳遞,意味著傳遞的并不是實際的對象,而是對象的引用。因此,外部對引用對象所做的改變會反映到所有的對象上。
- Java 應(yīng)用程序有且僅有的一種參數(shù)傳遞機制,即按值傳遞
- 原始類型就是傳值,但Java參數(shù)的引用傳遞并不是傳遞對象的引用,而是引用變量的副本
class person {
public String name = "Jack";
//定義一個改變對象屬性的方法
public void changeName(Person p) {
p.name = "Rose";
}
public static void main(String[] args) {
//定義一個Person對象,person是這個對象的引用
Person person = new Person();
//先顯示這個對象的name屬性
System.out.println(person.name);
//調(diào)用changeName(Person p)方法
changeName(person);
//再顯示這個對象的name屬性,看是否發(fā)生了變化
System.out.println(person.name);
}
輸出結(jié)果:
第一次顯示:“Jack”
第二次顯示:“Rose”

上述操作的內(nèi)存分配
- 實例化Person對象的時候,實際分配了兩個對象:新創(chuàng)建的Person類的實體對象和指向該對象的引用變量person。在堆中為Person對象分配內(nèi)存空間,但是引用變量在棧中分配內(nèi)存空間,其中person引用變量指向Person對象的首地址,指向Person對象。
- 調(diào)用changeName方法時,傳遞的值是person引用變量,因為Java只有值傳遞,所以方法中p變量為person引用變量的副本,重新為p分配地址空間。
- p為person應(yīng)用的變量的副本,p的值與person相同,也存放著Person對象的首地址,也指向Person對象,所以p的操作,會改變Person對象的值。
- 總結(jié):Java對象作為方法的參數(shù)進行傳遞的時候,其傳遞的是引用變量的副本,但兩個引用變量指向同一個地址空間(即對象的地址),但在方法中無法改變原引用變量。
重點注意:String,Integer, Double等immutable類型因為沒有提供自身修改的函數(shù),每次操作都是新生成一個對象,所以要特殊對待,可以認為是傳值。Integer 和 String 一樣,保存value的類變量是Final屬性,無法被修改,只能被重新賦值/生成新的對象。 當Integer 做為方法參數(shù)傳遞進方法內(nèi)時,對其的賦值都會導(dǎo)致 原Integer 的引用被指向了方法內(nèi)的棧地址,失去了對原類變量地址的指向。對賦值后的Integer對象做得任何操作,都不會影響原來對象。
3. 進程和線程
-
兩者的定義
進程是具有一定獨立功能的程序在數(shù)據(jù)集上的一次活動,它擁有操作系統(tǒng)分配給它獨自使用的系統(tǒng)資源,所以,進程也是操作系統(tǒng)進行資源分配和調(diào)度的一個獨立單元。
線程是進程中執(zhí)行運算的最小單位,是進程的實體,它是CPU調(diào)度和分派的基本單位,線程只擁有一點在運行中必不可少的資源(程序計數(shù)器,一組寄存器和棧),此外,線程和同屬進程的其他線程共享進程的資源。 -
兩者的關(guān)系
(1) 一個線程只能屬于一個進程,一個進程可以有多個線程,但至少有一個線程
(2) 操作系統(tǒng)把資源分配給進程,同一個進程的所有線程共享該進程的資源
(3) 線程是進程中的執(zhí)行單元,CPU執(zhí)行的是線程,此外,線程也是進程內(nèi)的可調(diào)度單元。 -
兩者的區(qū)別
(1) 調(diào)度執(zhí)行: 進程在操作系統(tǒng)中獨立運行,由操作系統(tǒng)進行調(diào)度,線程必須依賴進程存在,由進程進行調(diào)度。
(2) 并發(fā)性: 進程和線程都可以并發(fā)執(zhí)行,但是線程劃分更小,所以并發(fā)性更高
(3) 擁有資源 進程是擁有操作系統(tǒng)資源的基本單元,線程共享所屬進程的資源
(4) 系統(tǒng)開銷 創(chuàng)建和撤銷進程的開銷遠遠大于創(chuàng)建和撤銷線程的開銷。 -
兩者的通信方式
(1)進程間的通信方式- 管道(Pipe):管道可用于具有親緣關(guān)系進程間的通信,允許一個進程和另一個與它有共同祖先的進程之間進行通信。
- 命名管道(named pipe): 命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關(guān)系進程間的通信。命名管道在文件系統(tǒng)中有對應(yīng)的文件名。命名管道通過命令mkfifo或系統(tǒng)調(diào)用mkfifo來創(chuàng)建。
- 信號(Signal):信號是比較復(fù)雜的通信方式,用于通知接受進程有某種事件發(fā)生,除了用于進程間通信外,進程還可以發(fā)送 信號給進程本身;linux除了支持Unix早期信號語義函數(shù)sigal外,還支持語義符合Posix.1標準的信號函數(shù)sigaction(實際上,該 函數(shù)是基于BSD的,BSD為了實現(xiàn)可靠信號機制,又能夠統(tǒng)一對外接口,用sigaction函數(shù)重新實現(xiàn)了signal函數(shù))。
- 消息(Message)隊列:消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠權(quán)限的進程可以向隊列中添加消息,被賦予讀權(quán)限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字 節(jié)流以及緩沖區(qū)大小受限等缺
- 共享內(nèi)存:使得多個進程可以訪問同一塊內(nèi)存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設(shè)計的。往往與其它通信機制,如信號量結(jié)合使用,來達到進程間的同步及互斥。
- 內(nèi)存映射(mapped memory):內(nèi)存映射允許任何多個進程間通信,每一個使用該機制的進程通過把一個共享的文件映射到自己的進程地址空間來實現(xiàn)它。
- 信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。
- 套接口(Socket):更為一般的進程間通信機制,可用于不同機器之間的進程間通信。
(2)線程間的通信方式
- 共享內(nèi)存,可以通過內(nèi)部類來實現(xiàn)共享變量
- 管道 線程間建立流管道