Android 面試準(zhǔn)備進(jìn)行曲(Java基礎(chǔ)篇) v1.4

@TOC

update time 2019年12月5日 13:45:47

CSDN地址 (csdn暫時(shí)有目錄更方便 查找閱讀 -沈跨。-)

虛擬機(jī) 基礎(chǔ)

jvm 參考文章

JVM內(nèi)存管理

JVM執(zhí)行Java程序的過程:Java源代碼文件(.java)會(huì)被Java編譯器編譯為字節(jié)碼文件(.class),然后JVM中的類加載器加載各個(gè)類的字節(jié)碼文件兔综,加載完畢之后饿凛,交由JVM執(zhí)行引擎執(zhí)行。

在這里插入圖片描述

運(yùn)行時(shí)數(shù)據(jù)區(qū)被分為 線程私有數(shù)據(jù)區(qū)線程共享數(shù)據(jù)區(qū) 兩大類:

線程私有數(shù)據(jù)區(qū)包含:程序計(jì)數(shù)器软驰、虛擬機(jī)棧涧窒、本地方法棧
線程共享數(shù)據(jù)區(qū)包含:Java堆、方法區(qū)(內(nèi)部包含常量池)

線程私有數(shù)據(jù)區(qū)包含:

  • 程序計(jì)數(shù)器:是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器
  • 虛擬機(jī)棧:是Java方法執(zhí)行的內(nèi)存模型
  • 本地方法棧:是虛擬機(jī)使用到的Native方法服務(wù)

線程共享數(shù)據(jù)區(qū)包含:

  • Java堆:用于存放幾乎所有的對(duì)象實(shí)例和數(shù)組锭亏;是垃圾收集器管理的主要區(qū)域纠吴,也被稱做“GC堆”;是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊

  • 方法區(qū):用于存儲(chǔ)已被虛擬機(jī)加載的類信息慧瘤、常量戴已、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)锅减;Class文件中除了有類的版本糖儡、字段、方法怔匣、接口等描述信息外握联,還有一項(xiàng)信息是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號(hào)引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放

Java堆和棧的區(qū)別

  • 堆內(nèi)存
    用于存儲(chǔ)Java中的對(duì)象和數(shù)組金闽,當(dāng)我們new一個(gè)對(duì)象或者創(chuàng)建一個(gè)數(shù)組的時(shí)候纯露,就會(huì)在堆內(nèi)存中開辟一段空間給它,用于存放代芜。特點(diǎn): 先進(jìn)先出埠褪,后進(jìn)后出。堆可以動(dòng)態(tài)地分配內(nèi)存大小蜒犯,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存组橄,存取速度較慢。

  • 棧內(nèi)存
    主要是用來執(zhí)行程序用的罚随,比如:基本類型的變量和對(duì)象的引用變量玉工。特點(diǎn):先進(jìn)后出,后進(jìn)先出淘菩,存取速度比堆要快遵班,僅次于寄存器,棧數(shù)據(jù)可以共享潮改,但缺點(diǎn)是狭郑,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性

垃圾回收機(jī)制/ 回收算法

判定對(duì)象可回收有兩種方法:

  • 引用計(jì)數(shù)算法:給對(duì)象中添加一個(gè)引用計(jì)數(shù)器汇在,每當(dāng)有一個(gè)地方引用它時(shí)翰萨,計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí)糕殉,計(jì)數(shù)器值就減1亩鬼;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。然而在主流的Java虛擬機(jī)里未選用引用計(jì)數(shù)算法來管理內(nèi)存阿蝶,主要原因是它難以解決對(duì)象之間相互循環(huán)引用的問題雳锋,所以出現(xiàn)了另一種對(duì)象存活判定算法。

  • 可達(dá)性分析法:通過一系列被稱為『GC Roots』的對(duì)象作為起始點(diǎn)羡洁,從這些節(jié)點(diǎn)開始向下搜索玷过,搜索所走過的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈相連時(shí)筑煮,則證明此對(duì)象是不可用的辛蚊。其中可作為GC Roots的對(duì)象:虛擬機(jī)棧中引用的對(duì)象,主要是指棧幀中的本地變量真仲、本地方法棧中Native方法引用的對(duì)象嚼隘、方法區(qū)中類靜態(tài)屬性引用的對(duì)象、方法區(qū)中常量引用的對(duì)象

回收算法

分代收集算法:是當(dāng)前商業(yè)虛擬機(jī)都采用的一種算法袒餐,根據(jù)對(duì)象存活周期的不同飞蛹,將Java堆劃分為新生代和老年代谤狡,并根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/p>

  • 新生代:多數(shù)對(duì)象死去,少量存活卧檐。使用『復(fù)制算法』墓懂,只需復(fù)制少量存活對(duì)象即可。
    • 復(fù)制算法:把可用內(nèi)存按容量劃分為大小相等的兩塊霉囚,每次只使用其中的一塊捕仔。當(dāng)這一塊的內(nèi)存用盡后,把還存活著的對(duì)象『復(fù)制』到另外一塊上面盈罐,再將這一塊內(nèi)存空間一次清理掉榜跌。
  • 老年代:對(duì)象存活率高。使用『標(biāo)記—清理算法』或者『標(biāo)記—整理算法』盅粪,只需標(biāo)記較少的回收對(duì)象即可钓葫。
    • 標(biāo)記-清除算法:首先『標(biāo)記』出所有需要回收的對(duì)象,然后統(tǒng)一『清除』所有被標(biāo)記的對(duì)象票顾。
    • 標(biāo)記-整理算法:首先『標(biāo)記』出所有需要回收的對(duì)象础浮,然后進(jìn)行『整理』,使得存活的對(duì)象都向一端移動(dòng)奠骄,最后直接清理掉端邊界以外的內(nèi)存豆同。

參考文章

Java基礎(chǔ)

Java 引用類型

  • 強(qiáng)引用(StrongReference):具有強(qiáng)引用的對(duì)象不會(huì)被GC;即便內(nèi)存空間不足含鳞,JVM寧愿拋出OutOfMemoryError使程序異常終止影锈,也不會(huì)隨意回收具有強(qiáng)引用的對(duì)象。

  • 軟引用(SoftReference):具有軟引用的對(duì)象蝉绷,會(huì)在內(nèi)存空間不足的時(shí)候被GC鸭廷;軟引用常用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存。

  • 弱引用(WeakReference):被弱引用關(guān)聯(lián)的對(duì)象潜必,無論當(dāng)前內(nèi)存是否足夠都會(huì)被GC;強(qiáng)度比軟引用更弱沃但,常用于描述非必需對(duì)象磁滚;常用于解決內(nèi)存泄漏的問題(Handle 中Context 部分)

  • 虛引用(PhantomReference):僅持有虛引用的對(duì)象,在任何時(shí)候都可能被GC宵晚;常用于跟蹤對(duì)象被GC回收的活動(dòng)垂攘;必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用,當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)淤刃,如果發(fā)現(xiàn)它還有虛引用晒他,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中逸贾。

類加載機(jī)制

類加載機(jī)制:是虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存陨仅,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)津滞、轉(zhuǎn)換解析和初始化,形成可被虛擬機(jī)直接使用的Java類型的過程灼伤。另外触徐,類型的加載、連接和初始化過程都是在程序運(yùn)行期完成的狐赡,從而通過犧牲一些性能開銷來換取Java程序的高度靈活性撞鹉。主要階段:

  • 加載(Loading):通過類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流;將該二進(jìn)制字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)颖侄,該數(shù)據(jù)存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)由虛擬機(jī)實(shí)現(xiàn)自行定義鸟雏;在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,它將作為程序訪問方法區(qū)中的這些類型數(shù)據(jù)的外部接口

  • 驗(yàn)證(Verification):確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求览祖,包括文件格式驗(yàn)證孝鹊、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證和符號(hào)引用驗(yàn)證

  • 準(zhǔn)備(Preparation):為類變量分配內(nèi)存穴墅,因?yàn)檫@里的變量是由方法區(qū)分配內(nèi)存的惶室,所以僅包括類變量而不包括實(shí)例變量,后者將會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一起分配在Java堆中玄货;設(shè)置類變量初始值皇钞,通常情況下零值

  • 解析(Resolution):虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過程

  • 初始化(Initialization):是類加載過程的最后一步,會(huì)開始真正執(zhí)行類中定義的Java字節(jié)碼松捉。而之前的類加載過程中夹界,除了在『加載』階段用戶應(yīng)用程序可通過自定義類加載器參與之外,其余階段均由虛擬機(jī)主導(dǎo)和控制

內(nèi)存模型

在這里插入圖片描述

主內(nèi)存是所有變量的存儲(chǔ)位置隘世,每條線程都有自己的工作內(nèi)存可柿,用于保存被該線程使用到的變量的主內(nèi)存副本拷貝。為了獲取更好的運(yùn)行速度丙者,虛擬機(jī)可能會(huì)讓工作內(nèi)存優(yōu)先存儲(chǔ)于寄存器和高速緩存中复斥。

并發(fā)過程中的原子性 時(shí)序性

  • 原子性

可直接保證的原子性變量操作有:read、load械媒、assign目锭、use、store和write纷捞,因此可認(rèn)為基本數(shù)據(jù)類型的訪問讀寫是具備原子性的痢虹。

若需要保證更大范圍的原子性,可通過更高層次的字節(jié)碼指令monitorenter和monitorexit來隱式地使用lock和unlock這兩個(gè)操作主儡,反映到Java代碼中就是同步代碼塊synchronized關(guān)鍵字奖唯。

  • 可見性(一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改)

通過在變量修改后將新值同步回主內(nèi)存糜值,在變量讀取前從主內(nèi)存刷新變量值這種依賴主內(nèi)存作為傳遞媒介的方式來實(shí)現(xiàn)丰捷。

提供三個(gè)關(guān)鍵字保證可見性:volatile能保證新值能立即同步到主內(nèi)存坯墨,且每次使用前立即從主內(nèi)存刷新;synchronized對(duì)一個(gè)變量執(zhí)行unlock操作之前可以先把此變量同步回主內(nèi)存中瓢阴;被final修飾的字段在構(gòu)造器中一旦初始化完成且構(gòu)造器沒有把this的引用傳遞出去畅蹂,就可以在其他線程中就能看見final字段的值。

  • 有序性(按照指令順序執(zhí)行)

如果在本線程內(nèi)觀察荣恐,所有的操作都是有序的液斜,指“線程內(nèi)表現(xiàn)為串行的語義”;如果在一個(gè)線程中觀察另一個(gè)線程叠穆,所有的操作都是無序的少漆,指“指令重排序”現(xiàn)象和“工作內(nèi)存與主內(nèi)存同步延遲”現(xiàn)象。

提供兩個(gè)關(guān)鍵字保證有序性:volatile 本身就包含了禁止指令重排序的語義硼被;synchronized保證一個(gè)變量在同一個(gè)時(shí)刻只允許一條線程對(duì)其進(jìn)行l(wèi)ock操作示损,使得持有同一個(gè)鎖的兩個(gè)同步塊只能串行地進(jìn)入。

設(shè)計(jì)模式 (使用過的)

  • 單一職責(zé)原則:一個(gè)類只負(fù)責(zé)一個(gè)功能領(lǐng)域中的相應(yīng)職責(zé)

  • 開放封閉原則:對(duì)擴(kuò)展開放嚷硫,對(duì)修改關(guān)閉

  • 依賴倒置原則:抽象不應(yīng)該依賴于細(xì)節(jié)检访,細(xì)節(jié)應(yīng)當(dāng)依賴于抽象。換言之仔掸,要針對(duì)接口編程脆贵,而不是針對(duì)實(shí)現(xiàn)編程

  • 迪米特法則:應(yīng)該盡量減少對(duì)象之間的交互,如果兩個(gè)對(duì)象之間不必彼此直接通信起暮,那么這兩個(gè)對(duì)象就不應(yīng)當(dāng)發(fā)生任何直接的相互作用卖氨,如果其中的一個(gè)對(duì)象需要調(diào)用另一個(gè)對(duì)象的某一個(gè)方法的話,可以通過第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用

  • 合成/聚合復(fù)用原則:要盡量使用合成/聚合负懦,盡量不要使用繼承

延伸:Android 中源碼使用的設(shè)計(jì)模式筒捺,自己使用過的設(shè)計(jì)模式

View事件分發(fā): 責(zé)任鏈模式
BitmapFactory加載圖片: 工廠模式
ListAdapter: 適配器模式
DialogBuilder: 建造者模式
Adapter.notifyDataSetChanged(): 觀察者模式
Binder機(jī)制: 代理模式

平時(shí)經(jīng)常使用的 設(shè)計(jì)模式

單例模式

初級(jí)版

public class Singleton {
    private static Singleton instance;
    private Singleton (){}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

進(jìn)階版

public class Singleton {
    private volatile static Singleton singleton;//代碼1
    private Singleton (){}
    public static Singleton getSingleton() {
        if (singleton == null) {//代碼2
            synchronized (Singleton.class) {
                if (singleton == null) {//代碼3
                    singleton = new Singleton();//代碼4
                }
            }
        }
        return singleton;
    }
}

??在多線程中 兩個(gè)線程可能同時(shí)進(jìn)入代碼2, synchronize保證只有一個(gè)線程能進(jìn)入下面的代碼,
??此時(shí)一個(gè)線程A進(jìn)入一個(gè)線程B在外等待, 當(dāng)線程A完成代碼3 和代碼4之后,
線程B進(jìn)入synchronized下面的方法, 線程B在代碼3的時(shí)候判斷不過,從而保證了多線程下 單例模式的線程安全,
??另外要慎用單例模式,因?yàn)閱卫J揭坏┏跏蓟?只有進(jìn)程退出才有可能被回收,如果一個(gè)對(duì)象不經(jīng)常被使用,盡量不要使用單例,否則為了幾次使用,一直讓單例存在占用內(nèi)存

優(yōu)點(diǎn):

  • 內(nèi)存中只存在一個(gè)對(duì)象,節(jié)省了系統(tǒng)資源纸厉。
  • 避免對(duì)資源的多重占用系吭,例如一個(gè)文件操作,由于只有一個(gè)實(shí)例存在內(nèi)存中颗品,避免對(duì)同一資源文件的同時(shí)操作肯尺。

缺點(diǎn):

  • 單例對(duì)象如果持有Context,那么很容易引發(fā)內(nèi)存泄露抛猫。
  • 單例模式一般沒有接口蟆盹,擴(kuò)展很困難孩灯,若要擴(kuò)展闺金,只能修改代碼來實(shí)現(xiàn)。

Builder 模式

參考文章

在這里插入圖片描述

具體的產(chǎn)品類

public class Computer {
    private String mCPU;
    private String mMemory;
    private String mHD;

    public void setCPU(String CPU) {
        mCPU = CPU;
    }

    public void setMemory(String memory) {
        mMemory = memory;
    }

    public void setHD(String HD) {
        mHD = HD;
    }
}

抽象建造者

public abstract class Builder {
    public abstract void buildCPU(String cpu);//組裝CPU

    public abstract void buildMemory(String memory);//組裝內(nèi)存

    public abstract void buildHD(String hd);//組裝硬盤

    public abstract Computer create();//返回組裝好的電腦
}

創(chuàng)建者實(shí)現(xiàn)類

public class ConcreteBuilder extends Builder {
    //創(chuàng)建產(chǎn)品實(shí)例
    private Computer mComputer = new Computer();

    @Override
    public void buildCPU(String cpu) {//組裝CPU
        mComputer.setCPU(cpu);
    }

    @Override
    public void buildMemory(String memory) {//組裝內(nèi)存
        mComputer.setMemory(memory);
    }

    @Override
    public void buildHD(String hd) {//組裝硬盤
        mComputer.setHD(hd);
    }

    @Override
    public Computer create() {//返回組裝好的電腦
        return mComputer;
    }
}

調(diào)用者

public class Director {
    private Builder mBuild = null;

    public Director(Builder build) {
        this.mBuild = build;
    }

    //指揮裝機(jī)人員組裝電腦
    public void Construct(String cpu, String memory, String hd) {
        mBuild.buildCPU(cpu);
        mBuild.buildMemory(memory);
        mBuild.buildHD(hd);
    }
}

調(diào)用


 Director direcror = new Director(new ConcreteBuilder());//創(chuàng)建指揮者實(shí)例峰档,并分配相應(yīng)的建造者败匹,(老板分配任務(wù))
direcror.Construct("i7-6700", "三星DDR4", "希捷1T");//組裝電腦

Builder 模式 優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 封裝性良好寨昙,隱藏內(nèi)部構(gòu)建細(xì)節(jié)。
  • 易于解耦掀亩,將產(chǎn)品本身與產(chǎn)品創(chuàng)建過程進(jìn)行解耦舔哪,可以使用相同的創(chuàng)建過程來得到不同的產(chǎn)品。也就說細(xì)節(jié)依賴抽象槽棍。
  • 易于擴(kuò)展捉蚤,具體的建造者類之間相互獨(dú)立,增加新的具體建造者無需修改原有類庫的代碼炼七。
  • 易于精確控制對(duì)象的創(chuàng)建缆巧,由于具體的建造者是獨(dú)立的,因此可以對(duì)建造過程逐步細(xì)化豌拙,而不對(duì)其他的模塊產(chǎn)生任何影響陕悬。

缺點(diǎn)

  • 產(chǎn)生多余的Build對(duì)象以及Dirextor類。
  • 建造者模式所創(chuàng)建的產(chǎn)品一般具有較多的共同點(diǎn)按傅,其組成部分相似捉超;如果產(chǎn)品之間的差異性很大,則不適合使用建造者模式唯绍,因此其使用范圍受到一定的限制

源碼中使用的 比如: Dialog.Builder

工廠模式

在這里插入圖片描述

抽象產(chǎn)品類

    public abstract class Product {
        public abstract void show();
    }

具體產(chǎn)品類

    public class ProductA extends Product {
        @Override
        public void show() {
            System.out.println("product A");
        }
    }
    //具體產(chǎn)品類B
    public class ProductB extends Product {
        @Override
        public void show() {
            System.out.println("product B");
        }
    }

創(chuàng)建抽象工廠類

     //抽象工廠類
    public abstract class Factory {
        public abstract Product create();
    }

創(chuàng)建具體工廠類拼岳,繼承抽象工廠類

    public class FactoryA extends Factory {
        @Override
        public Product create() {
            return new ProductA();//創(chuàng)建ProductA
        }
    }
    //具體工廠類B
    public class FactoryB extends Factory {
        @Override
        public Product create() {
            return new ProductB();//創(chuàng)建ProductB
        }
    }

測(cè)試代碼

        Factory factoryA = new FactoryA();
        Product productA = factoryA.create();
        productA.show();
        //產(chǎn)品B
        Factory factoryB = new FactoryB();
        Product productB = factoryB.create();
        productB.show();

優(yōu)點(diǎn):

  • 符合開放封閉原則。新增產(chǎn)品時(shí)推捐,只需增加相應(yīng)的具體產(chǎn)品類和相應(yīng)的工廠子類即可裂问。
  • 符合單一職責(zé)原則。每個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的產(chǎn)品牛柒。

缺點(diǎn):

  • 增加新產(chǎn)品時(shí)堪簿,還需增加相應(yīng)的工廠類,系統(tǒng)類的個(gè)數(shù)將成對(duì)增加皮壁,增加了系統(tǒng)的復(fù)雜度和性能開銷椭更。

源碼中 使用的 比如 ThreadFactory

觀察者模式

參考文章

含義: 定義對(duì)象間的一種一個(gè)對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)送改變時(shí)蛾魄,所以依賴于它的對(duì)象都得到通知并被自動(dòng)更新虑瀑。

在這里插入圖片描述

備注:

  • Subject(抽象主題):又叫抽象被觀察者,把所有觀察者對(duì)象的引用保存到一個(gè)集合里滴须,每個(gè)主題都可以有任何數(shù)量的觀察者舌狗。抽象主題提供一個(gè)接口,可以增加和刪除觀察者對(duì)象扔水。

  • ConcreteSubject(具體主題):又叫具體被觀察者痛侍,將有關(guān)狀態(tài)存入具體觀察者對(duì)象;在具體主題內(nèi)部狀態(tài)改變時(shí)魔市,給所有登記過的觀察者發(fā)出通知主届。

  • Observer (抽象觀察者):為所有的具體觀察者定義一個(gè)接口赵哲,在得到主題通知時(shí)更新自己。

  • ConcrereObserver(具體觀察者):實(shí)現(xiàn)抽象觀察者定義的更新接口君丁,當(dāng)?shù)玫街黝}更改通知時(shí)更新自身的狀態(tài)枫夺。

代碼實(shí)現(xiàn)

抽象觀察者

    public interface Observer {//抽象觀察者
        public void update(String message);//更新方法
    }

具體觀察者

public class Boy implements Observer {

        private String name;//名字
        public Boy(String name) {
            this.name = name;
        }
        @Override
        public void update(String message) {//男孩的具體反應(yīng)
            System.out.println(name + ",收到了信息:" + message+"屁顛顛的去取快遞.");
        }
    }

創(chuàng)建抽象主題

    public interface  Observable {//抽象被觀察者
         void add(Observer observer);//添加觀察者
 
         void remove(Observer observer);//刪除觀察者
    
         void notify(String message);//通知觀察者
    }

創(chuàng)建具體主題

    public class Postman implements  Observable{//快遞員
        
        private List<Observer> personList = new ArrayList<Observer>();//保存收件人(觀察者)的信息
        @Override
        public void add(Observer observer) {//添加收件人
            personList.add(observer);
        }

        @Override
        public void remove(Observer observer) {//移除收件人
            personList.remove(observer);

        }

        @Override
        public void notify(String message) {//逐一通知收件人(觀察者)
            for (Observer observer : personList) {
                observer.update(message);
            }
        }
    }

測(cè)試代碼

        Observable postman=new Postman();
        
        Observer boy1=new Boy("路飛");
        Observer boy2=new Boy("喬巴");
        postman.notify("快遞到了,請(qǐng)下樓領(lǐng)取.");

優(yōu)點(diǎn):

  • 解除觀察者與主題之間的耦合。讓耦合的雙方都依賴于抽象绘闷,而不是依賴具體橡庞。從而使得各自的變化都不會(huì)影響另一邊的變化。
  • 易于擴(kuò)展印蔗,對(duì)同一主題新增觀察者時(shí)無需修改原有代碼毙死。

缺點(diǎn):

  • 使用觀察者模式時(shí)需要考慮一下開發(fā)效率和運(yùn)行效率的問題,程序中包括一個(gè)被觀察者喻鳄、多個(gè)觀察者扼倘,開發(fā)、調(diào)試等內(nèi)容會(huì)比較復(fù)雜除呵,而且在Java中消息的通知一般是順序執(zhí)行再菊,那么一個(gè)觀察者卡頓,會(huì)影響整體的執(zhí)行效率颜曾,在這種情況下纠拔,一般會(huì)采用異步實(shí)現(xiàn)。
  • 可能會(huì)引起多余的數(shù)據(jù)通知泛豪。

Android 源碼中的觀察者模式:Listener

其他設(shè)計(jì)模式

由于本人涉獵較少稠诲,有些只能說簡(jiǎn)單了解。這里分享一個(gè) 不錯(cuò)的 系列博客诡曙,感謝前人栽樹臀叙。

設(shè)計(jì)模式系列教程 !<勐薄劝萤!

源碼設(shè)計(jì)

接口和抽象類

  • 抽象類可以提供成員方法的實(shí)現(xiàn)細(xì)節(jié),而接口中只能存在 public 抽象方法,沒有實(shí)現(xiàn)慎璧,(JDK8以后可以有)
  • 抽象類中的成員變量可以是各種類型的床嫌,而接口中的成員變量只能是 public static final 類型的;
  • 接口的成員變量只能是靜態(tài)常量胸私,沒有構(gòu)造函數(shù)厌处,也沒有代碼塊,但抽象類都可以有岁疼。
  • 一個(gè)類只能繼承一個(gè)抽象類阔涉,而一個(gè)類卻可以實(shí)現(xiàn)多個(gè)接口;
    抽象類訪問速度比接口速度要快,因?yàn)榻涌谛枰獣r(shí)間去尋找在類中具體實(shí)現(xiàn)的方法洒敏;
  • 如果你往抽象類中添加新的方法,你可以給它提供默認(rèn)的實(shí)現(xiàn)疙驾。因此你不需要改變你現(xiàn)在的代碼凶伙。如果你往接口中添加方法,那么你必須改變實(shí)現(xiàn)該接口的類它碎。

所以:抽象類強(qiáng)調(diào)的是重用函荣,接口強(qiáng)調(diào)的是解耦。

最后更新時(shí)間:2019年12月5日 13:45:40

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扳肛,一起剝皮案震驚了整個(gè)濱河市傻挂,隨后出現(xiàn)的幾起案子副砍,更是在濱河造成了極大的恐慌刊苍,老刑警劉巖奠货,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哪替,死亡現(xiàn)場(chǎng)離奇詭異蝉揍,居然都是意外死亡窘行,警方通過查閱死者的電腦和手機(jī)莹捡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門怕犁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來电禀,“玉大人幢码,你說我怎么就攤上這事〖夥桑” “怎么了症副?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長政基。 經(jīng)常有香客問我贞铣,道長,這世上最難降的妖魔是什么沮明? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任咕娄,我火速辦了婚禮,結(jié)果婚禮上珊擂,老公的妹妹穿的比我還像新娘圣勒。我一直安慰自己,他們只是感情好摧扇,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布圣贸。 她就那樣靜靜地躺著,像睡著了一般扛稽。 火紅的嫁衣襯著肌膚如雪吁峻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音用含,去河邊找鬼矮慕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛啄骇,可吹牛的內(nèi)容都是我干的痴鳄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼缸夹,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼痪寻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虽惭,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤橡类,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后芽唇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體顾画,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年匆笤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亲雪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疚膊,死狀恐怖义辕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寓盗,我是刑警寧澤灌砖,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站傀蚌,受9級(jí)特大地震影響基显,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜善炫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一撩幽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧箩艺,春花似錦窜醉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至静汤,卻和暖如春琅催,著一層夾襖步出監(jiān)牢的瞬間居凶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工藤抡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侠碧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓缠黍,卻偏偏與公主長得像弄兜,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嫁佳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 所有知識(shí)點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,450評(píng)論 1 4
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,109評(píng)論 1 32
  • 第二部分 自動(dòng)內(nèi)存管理機(jī)制 第二章 java內(nèi)存異常與內(nèi)存溢出異常 運(yùn)行數(shù)據(jù)區(qū)域 程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行的字節(jié)...
    小明oh閱讀 1,174評(píng)論 0 2
  • 一谷暮、運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)管理的內(nèi)存包括幾個(gè)運(yùn)行時(shí)數(shù)據(jù)內(nèi)存:方法區(qū)蒿往、虛擬機(jī)棧、本地方法棧湿弦、堆瓤漏、程序計(jì)數(shù)器,...
    luhanlin閱讀 545評(píng)論 0 0
  • 一颊埃、運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)管理的內(nèi)存包括幾個(gè)運(yùn)行時(shí)數(shù)據(jù)內(nèi)存:方法區(qū)蔬充、虛擬機(jī)棧、本地方法棧班利、堆饥漫、程序計(jì)數(shù)器,...
    加油小杜閱讀 1,522評(píng)論 1 15