Java 虛擬機(jī)詳解

一亮航、Java內(nèi)存模型(JMM)

堆(線程共享)

  • Java程序中通過創(chuàng)建出來的對象存放在堆內(nèi)存中汽煮,其成員變量和數(shù)據(jù)存放在對象的內(nèi)部济丘,堆內(nèi)存中的對象不可以共享,空間不是連續(xù)的生巡。
  • 堆是Java垃圾收集器管理的主要區(qū)域耙蔑,JVM會在CPU空閑時(shí)或內(nèi)存空間不足時(shí)會進(jìn)行垃圾回收,也可以通過代碼調(diào)用System.gc()方法請求JVM進(jìn)行垃圾回收孤荣,但JVM不一定立刻執(zhí)行垃圾回收甸陌,可以通過代碼調(diào)用System.runFinalization()方法強(qiáng)制調(diào)用失去引用的對象的finalize()方法,加速JVM垃圾回收速度盐股。
  • 堆由三部分組成钱豁,分別是新生區(qū)、老年區(qū)疯汁、永久區(qū)寥院,所有新建的對象都會存放在新生區(qū),隨著對象的創(chuàng)建越來越多涛目,新生區(qū)會執(zhí)行輕GC秸谢,清理掉大量失去引用的局部變量凛澎,當(dāng)新生區(qū)滿了時(shí)會把部分對象轉(zhuǎn)移到老年區(qū),老年區(qū)會執(zhí)行重GC估蹄,當(dāng)新生區(qū)塑煎、老年區(qū)同時(shí)滿了時(shí)會拋出OOM異常。

Java棧(線程私有)

  • Java棧的特點(diǎn)是先進(jìn)后出臭蚁,后進(jìn)先出最铁,生命周期和線程同步,線程結(jié)束時(shí)釋放棧內(nèi)存垮兑,不存在垃圾回收問題冷尉。
  • Java程序中的八大基本類型的數(shù)據(jù)、堆中實(shí)例對象的引用地址系枪、實(shí)例對象的方法調(diào)用都存放在棧中雀哨,引用是棧指向堆的過程,也稱Java的指針私爷。

本地方法棧(線程私有)

  • 本地方法棧主要存放被native關(guān)鍵字修飾的方法雾棺,本地方法可以調(diào)用本地方法接口JNI(JavaNativeInterface),可以實(shí)現(xiàn)對本地方法庫中底層語言C衬浑、C++方法的調(diào)用捌浩。

方法區(qū)(線程共享)

  • Java程序中已經(jīng)被虛擬機(jī)加載的類信息(構(gòu)造方法、接口)工秩、常量(final)尸饺、靜態(tài)變量(static)、運(yùn)行時(shí)常量池助币,都存放在方法區(qū)中侵佃,可被線程共享。
  • 運(yùn)行時(shí)常量池用來存放Java程序運(yùn)行時(shí)產(chǎn)生的字符串常量(String類的intern()方法)和八大基本數(shù)據(jù)類型的常量奠支,常量在編譯期以HashSet的形式放入常量池馋辈,常量可以實(shí)現(xiàn)對象共享。

程序計(jì)數(shù)器(線程私有)

  • 程序計(jì)數(shù)器占據(jù)非常小的內(nèi)存空間倍谜,用來存儲即將執(zhí)行指令的地址迈螟,便于執(zhí)行引擎讀取下一條指令,這樣就能理解代碼為何能有序地從上往下執(zhí)行尔崔。

JVM參數(shù)設(shè)置

-Xmx128m -> Java堆內(nèi)存的最大值答毫,默認(rèn)為物理內(nèi)存的1/4
-Xms64m -> Java堆內(nèi)存的初始值
-Xmn32m -> Java堆內(nèi)存新生代的大小
-Xss16m -> Java線程的棧內(nèi)存大小

二、Java垃圾回收算法

  • 標(biāo)記-清除算法:給對象中添加一個(gè)引用計(jì)數(shù)器季春,每當(dāng)有一個(gè)地方引用它時(shí)洗搂,計(jì)數(shù)器值就加1。當(dāng)引用失效時(shí),計(jì)數(shù)器值就減1耘拇。任何時(shí)刻計(jì)數(shù)器都為0的對象就是不再被使用的撵颊,垃圾收集器將回收該對象使用的內(nèi)存。
  • 復(fù)制-清除算法:將可用內(nèi)存按容量劃分為大小相等的兩塊惫叛,每次只使用其中一塊倡勇。當(dāng)這一塊的內(nèi)存用完了,就把還存活著的對象復(fù)制到另外一塊上面嘉涌,然后再把已使用過的內(nèi)存空間一次清理掉妻熊。這樣使得每次都是對整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)也就不用考慮內(nèi)存碎片等復(fù)雜情況仑最。
  • 標(biāo)記-壓縮算法:結(jié)合了標(biāo)記-清除算法和復(fù)制-清除算法扔役,通過標(biāo)記得到存活的對象,讓對象都緊挨在一起警医,從而避免內(nèi)存碎片的產(chǎn)生亿胸,同時(shí)保證內(nèi)存的高速分配。

三法严、對象的四種引用方式

  • 強(qiáng)引用损敷,只要引用存在葫笼,垃圾回收器永遠(yuǎn)不會進(jìn)行垃圾回收深啤,當(dāng)內(nèi)存開銷不足時(shí),拋出OutOfMemory運(yùn)行時(shí)異常路星,即常說的內(nèi)存泄漏或內(nèi)存溢出溯街。強(qiáng)引用是開發(fā)中最常用的方式,如:Object obj = new Object()洋丐,直到obj對象的引用被釋放后呈昔,new Object()才會被垃圾回收器回收,如:obj = null友绝,obj = new Object()堤尾,前者沒有指向任何引用,后者指向新的對象迁客。
  • 軟引用郭宝,當(dāng)內(nèi)存開銷不足時(shí),垃圾回收器會對該引用類型進(jìn)行回收掷漱。常用在內(nèi)存緩存的場景中粘室,內(nèi)存足夠時(shí)在軟引用對象中獲取數(shù)據(jù),內(nèi)存不足時(shí)從數(shù)據(jù)庫里獲取實(shí)時(shí)數(shù)據(jù)卜范。如:SoftReference<Object> softReference = new SoftReference<>(new Object())衔统,Object obj = softReference.get(),當(dāng)對象被回收后獲取的結(jié)果為Null。
  • 弱引用锦爵,垃圾回收器進(jìn)行垃圾回收時(shí)會對該引用類型進(jìn)行回收舱殿。如:
    WeakReference<Object> weakReference = new WeakReference<>(new Object()),Object obj = weakReference.get()棉浸,可以通過weakReference.isEnqueued()查詢對象是否被垃圾回收器標(biāo)記怀薛,當(dāng)對象被回收后獲取的結(jié)果為Null。
  • 虛引用迷郑,也被稱為幽靈引用或者幻影引用枝恋,不會對對象的生命周期造成任何影響刽虹,也無法獲取到對象的引用實(shí)例拐辽,常用于跟蹤垃圾回收的過程和監(jiān)聽回收的頻率,垃圾回收器進(jìn)行垃圾回收時(shí)會對該引用類型進(jìn)行回收梦鉴。
Object object = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>(); -> 保存對象被回收的虛引用
PhantomReference<Object> phantomReference = new PhantomReference<>(object,queue);

object = null; -> 切斷對象的引用
System.gc(); -> 請求垃圾回收
System.runFinalization(); -> 強(qiáng)制調(diào)用對象的finalize()方法

Reference<? extends Object> reference = queue.poll(); -> 取出虛引用
phantomReference == reference; -> true
  • 編譯期:編譯器是一種計(jì)算機(jī)程序霸妹,它能將程序的源碼(.java)編譯成計(jì)算機(jī)可以執(zhí)行的文件(.class)十电,在翻譯過程中會檢查代碼語法錯誤,不會把代碼放入內(nèi)存中運(yùn)行叹螟,從中會產(chǎn)生一些指令鹃骂,如:分配內(nèi)存大小、存放位置等罢绽。
  • 運(yùn)行期:程序編譯后的文件(.class)交由計(jì)算機(jī)執(zhí)行開始畏线,直至計(jì)算機(jī)不執(zhí)行結(jié)束,按照編譯期生成的指令運(yùn)行良价,類的加載也發(fā)生在該時(shí)期寝殴。
  • 類加載機(jī)制:加載階段,JVM將字節(jié)碼文件轉(zhuǎn)化為二進(jìn)制字節(jié)流加載到內(nèi)存中明垢,接為這個(gè)類在方法區(qū)創(chuàng)建對應(yīng)的 Class 對象蚣常,這個(gè)對象就是各種數(shù)據(jù)的訪問入口。驗(yàn)證階段痊银,包括JVM規(guī)范校驗(yàn)和代碼邏輯校驗(yàn)抵蚊。準(zhǔn)備階段,分配類變量內(nèi)存和變量類型的初始化溯革。解析階段贞绳,針對類、接口鬓照、方法熔酷、字段、限定符等解析豺裆。初始化階段拒秘,用戶的代碼執(zhí)行初始化号显。使用階段,程序啟動完成供用戶使用躺酒。卸載階段押蚤,程序的字節(jié)碼在JVM內(nèi)存中卸載停止使用。

四羹应、包裝與解包

包裝類 基礎(chǔ)類型 包裝 解包 緩存
Byte byte Byte b = (byte) 1 b.byteValue() -128~127
Boolean boolean Boolean b = true b.booleanValue() TRUE FLASE
Short short Short s = (short) 1 s.shortValue() -128~127
Character char Character c = (char) 1 c.charValue() 0~127
Integer int Integer i = 1 i.intValue() -128~127
Long long Long l = Long.valueOf(1L) l.longValue() -128~127
Float float Float f = Float.valueOf(1f) f.floatValue()
Double double Double d = Double.valueOf(1d) d.doubleValue()
int int1 = 10,int2 = 10;
Integer in1 = 127,in2 = 127;
Integer out1 = 128,out2 = 128;
Integer integer1 = new Integer(10);
Integer integer2 = new Integer(10);
Integer integer3 = new Integer(127);

int1 == int2; -> true,基本類型比較數(shù)值
int1 == integer1; -> true,包裝類自動拆包,本質(zhì)是基本類型相比較
integer1 == integer2; -> false,兩個(gè)引用對象比較的是堆內(nèi)存的地址
integer3 == in1; -> false,引用對象和常量的存放地址不同
in1 == in2; -> true,數(shù)值在包裝類的緩存區(qū)間中
out1 == out2; -> false,數(shù)值不在包裝類的緩存區(qū)間中,本質(zhì)是兩個(gè)引用對象相比較
  • 當(dāng)基本類型和包裝類型比較時(shí)揽碘,包裝類型會自動拆包生成其對應(yīng)的基本類型,基本類型之間的比較园匹,使用"=="即可雳刺。
  • 當(dāng)包裝類型的對象是通過new關(guān)鍵字創(chuàng)建,對象實(shí)例存在放堆內(nèi)存中裸违,引用對象持有堆內(nèi)存的指針掖桦,兩個(gè)對象之間通過"=="比較的是對象的堆內(nèi)存地址,比較結(jié)果不會相等供汛,兩個(gè)對象之間通過equals()方法比較的是它們的值枪汪,數(shù)據(jù)存放在棧內(nèi)存中,棧的特點(diǎn)是數(shù)據(jù)共享怔昨,所以相同的數(shù)據(jù)僅有一份雀久,比較結(jié)果可能相等也可能不相等。
  • 當(dāng)包裝類型中的一個(gè)對象是直接賦予確定的數(shù)值趁舀,另一個(gè)對象是通過new關(guān)鍵字創(chuàng)建時(shí)赖捌,直接定義的對象屬于常量,存放在常量池中赫编,new關(guān)鍵字創(chuàng)建的對象屬于實(shí)例對象巡蘸,存放在堆內(nèi)存中奋隶,兩個(gè)對象通過"=="比較的結(jié)果顯然是不相等的擂送,需要比較它們的值是否相等可以通過equals()方法。
  • 當(dāng)包裝類型中的兩個(gè)對象同時(shí)直接賦予確定的數(shù)值唯欣,以Integer為例子嘹吨,包裝類會默認(rèn)緩存 -128~127區(qū)間中的數(shù)值,當(dāng)直接賦予的常量值在此區(qū)間內(nèi)境氢,兩個(gè)對象通過"=="比較結(jié)果會相等蟀拷,反之超出區(qū)間通過"=="比較結(jié)果不會相等。
String name = new String("wjx"); -> 這個(gè)過程會創(chuàng)建1~2個(gè)對象(堆內(nèi)存和常量池)
String wjx = "wjx";
String w = "w";
String j = "j";
String x = "x";

name == wjx; -> false,引用對象和常量比較,內(nèi)存地址不一樣
wjx == "w"+"j"+"x"; -> true,常量在編譯期已經(jīng)確定
wjx == w+j+x; -> false,變量在運(yùn)行期才能確定
wjx == (w+j+x).intern(); -> true,運(yùn)行期設(shè)置常量

五萍聊、常見面試題

運(yùn)算符“==”和equals()方法的區(qū)別

  • “==”在比較Java基本數(shù)據(jù)類型(byte问芬、int、long寿桨、short此衅、double强戴、float、boolean挡鞍、char)時(shí)是比較它們的值骑歹,在比較引用對象類型時(shí)是比較它們在堆內(nèi)存中的地址。
  • equals的本質(zhì)是==墨微,Object類中的equals()方法默認(rèn)是比較兩個(gè)對象在堆內(nèi)存中的地址道媚,重寫后比較它們兩個(gè)的值是否相等。

equals()和hashCode()的區(qū)別

  • equals()相等的兩個(gè)對象其hashCode()肯定相等翘县。
  • hashCode()相等的兩個(gè)對象其equals()不一定相等最域。
  • equals()的本質(zhì)是==,比較的是對象在棧中的引用地址锈麸。
  • hashCode()的本質(zhì)是對象在哈希表中的索引羡宙,通過索引找到對象。
  • 在自定義比較兩個(gè)對象時(shí)需要重寫equals()和hashCode()方法掐隐。

變量命名規(guī)范

  • 首字母為英文(a~z)狗热、美元符($)、下劃線(_)虑省。
  • 英文匿刮、美元符、下劃線探颈、數(shù)字隨機(jī)搭配熟丸,單詞間建議駝峰格式。
  • 命名直至中文伪节,但不建議使用光羞。
  • 不允許使用java中的關(guān)鍵字命名。

定義 float怀大、double纱兑、long 變量的規(guī)范

  • JVM的小數(shù)默認(rèn)解析為double類型。
  • float單精度化借,double雙精度潜慎,double可以接收float。
  • float和double都可以接收任意長度的小數(shù)并截取指定精度蓖康。
  • 以float铐炫、double、long的形式接收整型值時(shí)不需添加后綴蒜焊。

String倒信、StringBuffer、StringBuilder的區(qū)別

  • String修飾不可變的對象泳梆,每次操作都會生成新的對象鳖悠,指針也隨之發(fā)生改變唆迁。
  • StringBuffer、StringBuilder修飾可變的對象竞穷,可以對原有的對象進(jìn)行操作唐责。
  • StringBuffer是線程安全的,其內(nèi)部的所有方法都添加了synchronized關(guān)鍵字進(jìn)行修飾瘾带,而StringBuilder是非線程安全的鼠哥。
  • 三者性能間比較:StringBuilder > StringBuffer > String 。

普通類和抽象類的區(qū)別

  • 普通類不含有抽象方法看政,可以直接實(shí)例化對象朴恳,可被final關(guān)鍵字修飾。
  • 抽象類可以含有抽象方法允蚣,不可以直接實(shí)例化對象于颖,不可被final關(guān)鍵字修飾。

接口和抽象類的區(qū)別

  • 抽象類的子類通過extends關(guān)鍵字繼承嚷兔,一個(gè)實(shí)體類只能繼承一個(gè)抽象類森渐,抽象類可以有構(gòu)造方法、普通成員方法冒晰、任意類型的成員變量同衣,抽象類的設(shè)計(jì)目的是代碼復(fù)用。
  • 接口的子類通過implements關(guān)鍵字實(shí)現(xiàn)壶运,一個(gè)實(shí)體類可以繼承多個(gè)接口耐齐,接口沒有構(gòu)造方法,只有抽象普通成員方法蒋情、final和static修飾的成員變量埠况,接口的設(shè)計(jì)目的是約束類的行為。

深拷貝和淺拷貝的區(qū)別

  • 淺拷貝只是復(fù)制了對象的引用地址棵癣,兩個(gè)對象指向同一個(gè)內(nèi)存地址辕翰,修改其中一個(gè)對象的值,另一個(gè)對象的值也會隨之發(fā)生改變浙巫。
String s1 = "wjx";
String s2 = s1;
  • 深拷貝實(shí)現(xiàn)Cloneable接口金蜀,重寫clone()方法的畴,把對象和屬性值都復(fù)制了,兩個(gè)對象間互不影響尝胆,都是獨(dú)立的對象丧裁。
public class Node implements Cloneable {
    private String name;
    private Node next;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Node node = (Node) super.clone();
        if (this.next != null) {
            node.next = (Node) next.clone(); -> 手動拷貝對象成員
        }
        return node;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

線性表、B-Tree含衔、B+Tree

  • 線性表是最基本煎娇、最簡單二庵、最常用的一種數(shù)據(jù)結(jié)構(gòu),一個(gè)線性表包含n個(gè)相同特性的數(shù)據(jù)元素缓呛,存儲結(jié)構(gòu)是鏈?zhǔn)酱鎯Υ呦恚谝粋€(gè)元素沒有頭,最后一個(gè)元素沒有尾哟绊,中間的元素都是首尾連接的因妙,有序。
  • B-Tree是多路平衡查找樹票髓,一棵m階層的B樹攀涵,每個(gè)節(jié)點(diǎn)里最多存放(m-1)個(gè)關(guān)鍵字,關(guān)鍵字以key和value形式存儲洽沟,每個(gè)節(jié)點(diǎn)最多有m個(gè)子節(jié)點(diǎn)以故,結(jié)點(diǎn)中包含多個(gè)關(guān)鍵字、父結(jié)點(diǎn)的指針裆操、子結(jié)點(diǎn)的指針怒详,關(guān)鍵字不可重復(fù)出現(xiàn)在不同的結(jié)點(diǎn)中,左子結(jié)點(diǎn)的值會比右子結(jié)點(diǎn)的值小踪区,B樹會把關(guān)鍵字添加到最底層的非葉子結(jié)點(diǎn)中棘利,如果不破壞m階層樹的結(jié)構(gòu)則結(jié)束,反之結(jié)點(diǎn)會進(jìn)行分裂使之恢復(fù)到m階層樹的結(jié)構(gòu)朽缴。


    分裂步驟1.jpg

    分裂步驟2.jpg

    分裂步驟3.jpg

    分裂步驟4.jpg

    刪除方式1.jpg

    刪除方式1.jpg

    刪除方式2.jpg

    刪除方式2.jpg

    刪除方式3

    刪除方式3
  • B+Tree是在B-Tree基礎(chǔ)上的一種優(yōu)化善玫,非葉子結(jié)點(diǎn)不存放value,使之可以存放更多的key密强,降低樹的高度茅郎,最底層的葉子結(jié)點(diǎn)包含所有的key和value,key從小到大從左往右排列或渤,相鄰的兩個(gè)結(jié)點(diǎn)通過指針關(guān)聯(lián)系冗。

什么是面向過程,什么是面向?qū)ο?/p>

  • 面向過程會把任務(wù)拆解為一系列的動作薪鹦,比如洗衣服掌敬,包含步驟:1、打開洗衣機(jī)池磁;2奔害、往里面放衣服;3地熄、往里面放洗衣粉华临;4、清洗端考;5雅潭、烘干揭厚;
  • 面向?qū)ο髶碛忻嫦蜻^程的特點(diǎn),會更注重于任務(wù)的參與者以及各自需要完成的步驟扶供,比如洗衣服筛圆,包含參與者:人、洗衣機(jī)椿浓,包含步驟:1顽染、人打開洗衣機(jī);2轰绵、人往洗衣機(jī)里面放衣服粉寞;3、人往洗衣機(jī)里面放洗衣粉左腔;4唧垦、洗衣機(jī)對衣服進(jìn)行清洗;5液样、洗衣機(jī)對衣服進(jìn)行烘干振亮;
  • 面向過程直接高效,面向?qū)ο笠子趶?fù)用鞭莽、擴(kuò)展坊秸、維護(hù)。

JDK澎怒、JRE褒搔、JVM三者的區(qū)別和聯(lián)系

  • JDK(Java Development Kit)是開發(fā)Java程序的工具。
  • JRE(Java Runtime Environment)是運(yùn)行Java程序的環(huán)境喷面。
  • JVM(Java Virtual Machine)是Java的虛擬機(jī)星瘾。
  • *.java文件通過JDK的javac命令編譯成 *.class文件,JRE通過ClassLoader加載 *.class文件解析到JVM里惧辈,JDK中包含JRE琳状,JRE中包含JVM。

final的作用

  • 修飾的類不可被繼承盒齿,修飾的方法不可被覆蓋念逞。
  • 修飾基本類型的變量不可更改值,修飾引用類型的變量不可更改對象边翁,引用值可以改變翎承。
  • 局部內(nèi)部類和匿名內(nèi)部類只能訪問final修飾的變量。

重載和重寫的區(qū)別

  • 重載:在同一個(gè)類中倒彰,方法名相同审洞,方法修飾符、方法返回值待讳、參數(shù)類型芒澜、參數(shù)個(gè)數(shù)不同,發(fā)生在編譯期创淡。
  • 重寫:在子類中痴晦,方法名、參數(shù)列表必須相同琳彩,返回值誊酌、拋出異常小于等于父類,修飾符大于等于父類(private除外)露乏。

ArrayList和LinkList的區(qū)別

  • ArrayList基于動態(tài)數(shù)組碧浊,數(shù)組的特點(diǎn)是內(nèi)存存儲空間連續(xù),適合使用下標(biāo)訪問數(shù)組里的元素瘟仿,查詢速度快箱锐,新增、修改劳较、刪除速度慢驹止,每次擴(kuò)容空間的量為原來的1.5倍,把原數(shù)組的元素遷移到新數(shù)組上观蜗。
  • LinkList基于鏈表臊恋,鏈表的特點(diǎn)是內(nèi)存儲存空間不連續(xù),只能通過iterator迭代器去遍歷墓捻,查詢速度慢抖仅,新增、修改砖第、刪除速度快岸售,不適合使用下標(biāo)訪問數(shù)組里的元素。

HashMap和HashTable的區(qū)別

  • 底層原理:數(shù)組+鏈表+紅黑樹厂画,當(dāng)數(shù)組的長度超過64凸丸,鏈表的長度達(dá)到8轉(zhuǎn)變成紅黑樹,紅黑樹的長度小于等于6轉(zhuǎn)變成鏈表袱院,取出key的hashCode進(jìn)行二次hash屎慢,然后對數(shù)組的長度進(jìn)行取模,得到數(shù)組的存放下標(biāo)忽洛,如果沒有產(chǎn)生hash沖突(數(shù)組下標(biāo)的位置為空)腻惠,則創(chuàng)建節(jié)點(diǎn)存入數(shù)組,如果產(chǎn)生hash沖突(數(shù)組下標(biāo)的位置存在鏈表)欲虚,則遍歷鏈表通過equals()方法判斷元素是否在鏈表中集灌,如果存在就覆蓋原來的元素,如果不存在就創(chuàng)建節(jié)點(diǎn)添加到鏈表的尾部。
  • HashMap是線程不安全的欣喧,key和value都允許為null腌零,key為null時(shí),元素存放在數(shù)組的第一個(gè)位置唆阿,即下標(biāo)是0益涧。
  • HashTable是線程安全的,其內(nèi)部的所有方法都添加了synchronized關(guān)鍵字進(jìn)行修飾驯鳖,key和value都不允許為null闲询。

Thread.sleep(0)的作用

  • 由于大部分操作系統(tǒng)采用的是搶占式線程調(diào)度算法,因此可能會出現(xiàn)某條線程經(jīng)常獲取到CPU控制權(quán)的情況浅辙,為了讓某些優(yōu)先級低的線程也能獲取到CPU的控制權(quán)扭弧,可以通過調(diào)用Thread.sleep(0)來手動觸發(fā)操作系統(tǒng)重新給線程分配時(shí)間片。
  • 在大循環(huán)里寫上Thread.sleep(0)记舆,間歇地給其他線程獲取CPU的控制權(quán)鸽捻,避免優(yōu)先級低的線程出現(xiàn)假死的情況,是一種平衡CPU控制權(quán)的操作氨淌。

什么是字節(jié)碼泊愧,采用字節(jié)碼有什么好處

  • 不同操作系統(tǒng)(Windows、Linux盛正、Mac)的解析器實(shí)現(xiàn)是不一樣的删咱,但它們的虛擬機(jī)實(shí)現(xiàn)是一致的,Java中引入了虛擬機(jī)的概念豪筝,Java編譯器面向的對象是虛擬機(jī)痰滋,通過把源文件(*.java)編譯成虛擬機(jī)可以理解的字節(jié)碼( *.class),虛擬機(jī)中的解析器將每一條需要執(zhí)行的字節(jié)碼翻譯成特定機(jī)器上的機(jī)器碼续崖,然后在機(jī)器上執(zhí)行敲街,這也解析了Java的編譯與解析共存的特點(diǎn)。
  • 在一定程度上解決了傳統(tǒng)解析型語言執(zhí)行效率低的問題严望,同時(shí)又保留了解析型語言可移植的特點(diǎn)多艇,而且字節(jié)碼只面向虛擬機(jī),所以Java程序只需要編譯一次就可以在不同的操作系統(tǒng)上運(yùn)行使用像吻。

Java中的類加載器有哪些

  • BootStrapClassLoader峻黍,負(fù)責(zé)加載%JAVA_HOME%/lib文件夾下的*.jar文件和 *.class文件。
  • ExtClassLoader拨匆,是BootStrapClassLoader的子類姆涩,負(fù)責(zé)加載%JAVA_HOME%/lib/ext文件夾下的*.jar文件和 *.class文件。
  • AppClassLoader惭每,是ExtClassLoader的子類骨饿,用于實(shí)現(xiàn)自定義的類加載,負(fù)責(zé)加載開發(fā)人員編寫的文件。

Java中的異常體系

  • 異常的頂級父類是Throwable宏赘,下面有Exception和Error兩個(gè)子類绒北。
  • Error是程序無法處理的錯誤,一旦出現(xiàn)則會終止程序的運(yùn)行置鼻,如內(nèi)存溢出(OutOfMemoryError)镇饮、線程死鎖(ThreadDeath)蜓竹、虛擬機(jī)錯誤(VirtualMachineError)等等箕母。
  • Exception不會終止程序的運(yùn)行,它可以分為CheckedException和RuntimeException兩種俱济,CheckedException發(fā)生在程序編譯過程中嘶是,導(dǎo)致程序編譯不通過,RuntimeException發(fā)生在程序運(yùn)行過程中蛛碌,導(dǎo)致程序線程執(zhí)行失敗聂喇。

什么是線程安全

  • 多個(gè)線程對同一個(gè)對象進(jìn)行訪問,如果對象不需要進(jìn)行同步控制或者其他協(xié)調(diào)操作蔚携,調(diào)用該對象的行為都可以獲得正確的結(jié)果希太,就證明是線程安全。
  • 棧是每個(gè)線程獨(dú)有的酝蜒,生命周期和線程同步誊辉,線程切換時(shí)棧也會隨之切換,所以棧是線程安全的亡脑。
  • 堆是線程共享的堕澄,多個(gè)線程可以對堆中的同一個(gè)對象進(jìn)行訪問,所以堆是線程不安全的霉咨。

串行蛙紫、并行、并發(fā)的區(qū)別

  • 串行在時(shí)間上不會出現(xiàn)重疊途戒,前一個(gè)任務(wù)完成才會執(zhí)行后一個(gè)任務(wù)坑傅。
  • 并行在時(shí)間上會出現(xiàn)重疊,兩個(gè)任務(wù)獨(dú)立完成喷斋,互不干擾唁毒。
  • 并發(fā)在時(shí)間上會出現(xiàn)重疊,兩個(gè)任務(wù)間存在干擾继准,干擾階段串行執(zhí)行枉证。

并發(fā)編程的三要素

  • 原子性:不可分割的操作,多個(gè)步驟要保證同時(shí)成功或者同時(shí)失敗移必。
  • 有序性:程序執(zhí)行的順序和代碼的順序保持一致室谚。
  • 可用性:一個(gè)線程對共享變量的修改,另一個(gè)線程能馬上看見。

線程池的線程復(fù)用原理是什么

  • 線程池把線程和任務(wù)進(jìn)行解耦秒赤,擺脫了直接創(chuàng)建線程猪瞬,線程和任務(wù)一對一的綁定限制。
  • 線程池中的線程會不斷輪詢堵塞隊(duì)列入篮,不斷地檢查和獲取新的任務(wù)來執(zhí)行妈候。
  • 直至堵塞隊(duì)列的任務(wù)全部執(zhí)行完欠肾,調(diào)用線程的wait()方法,釋放出CPU。

談?wù)勀銓OP的理解

  • 系統(tǒng)由諸多不同的組件構(gòu)成陷谱,每個(gè)組件都負(fù)責(zé)特定的功能兢卵,除此以外還經(jīng)常承擔(dān)著額外的職責(zé)匙隔,例如操作日志琼懊、事務(wù)管理、權(quán)限控制等等的核心服務(wù)肮帐,當(dāng)需要為分散的對象引入公共行為時(shí)咖驮,OOP則顯得乏力,它導(dǎo)致大量重復(fù)的代碼训枢,不利于給各個(gè)組件復(fù)用公共行為托修。
  • 將公共行為封裝成一個(gè)切面,然后注入到每個(gè)組件中恒界,目的是增強(qiáng)組件的功能睦刃,常見的用法是在組件調(diào)用某個(gè)方法前、后做些額外的事情仗处,例如:在操作前校驗(yàn)權(quán)限眯勾、在操作后記錄日志等等。

談?wù)勀銓OC的理解

  • 控制反轉(zhuǎn)婆誓,在沒有IOC容器之前吃环,對象A依賴對象B(A a = new B();),A必須主動創(chuàng)建對象B洋幻,控制權(quán)在A手里郁轻,在引入IOC容器之后,對象A和對象B失去了直接聯(lián)系文留,當(dāng)對象A需要依賴對象B時(shí)好唯,IOC容器會主動創(chuàng)建對象B提供給對象A,控制權(quán)在容器手里燥翅。
  • 依賴注入骑篙,對象A和對象B的依賴關(guān)系由IOC容器動態(tài)地注入,使用到簡單工廠設(shè)計(jì)模式和Java反射技術(shù)森书,原理是動態(tài)創(chuàng)建對象靶端。

談?wù)勀銓ξ⒎?wù)的理解

  • 微服務(wù)是一種架構(gòu)風(fēng)格谎势,通過將大型的單體應(yīng)用劃分為比較小的服務(wù)單元,從而降低整個(gè)系統(tǒng)的復(fù)雜度杨名。
  • 優(yōu)點(diǎn)是每個(gè)微服務(wù)都是獨(dú)立的脏榆,應(yīng)用性能提高,技術(shù)選擇靈活台谍,耦合性降低须喂,代碼復(fù)用強(qiáng)。
  • 缺點(diǎn)是微服務(wù)之間的通信難度提高了趁蕊,如負(fù)載均衡坞生、熔斷降級、分布式鎖介衔、分布式事務(wù)等等恨胚。

如何實(shí)現(xiàn)一個(gè)IOC容器

  • 配置文件中指定需要掃描的包路徑骂因。
  • 定義一些注解炎咖,分別表示訪問控制層、業(yè)務(wù)服務(wù)層寒波、數(shù)據(jù)持久層乘盼、依賴注入、獲取配置俄烁。
  • 遞歸掃描包下面的文件夾及文件信息绸栅,用Set集合存放所有以class結(jié)尾的文件。
  • 遍歷Set集合页屠,獲取在類上有指定注解的類交給IOC容器粹胯,并在容器內(nèi)部定義一個(gè)安全的Map集合來存放這些被容器管理的類。
  • 遍歷Map集合辰企,獲取到每個(gè)類的實(shí)例對象风纠,判斷里面是否有依賴其他類的實(shí)例對象,然后進(jìn)行遞歸的依賴注入牢贸。

BeanFactory和ApplicationContext的區(qū)別

  • BeanFactory采用懶加載的形式注入Bean竹观,即只有調(diào)用getBean()方法時(shí)才會實(shí)例化,這樣就不能及時(shí)發(fā)現(xiàn)Spring配置的問題潜索,直到實(shí)例化的時(shí)候才拋出異常臭增。
  • ApplicationContext在容器啟動時(shí)會一次性創(chuàng)建好所有的Bean,這樣能在容器啟動時(shí)及時(shí)發(fā)現(xiàn)Spring配置的問題竹习,在需要Bean對象時(shí)可以直接獲取誊抛,無需等待。不足的是占用內(nèi)存空間大整陌,容器啟動速度慢拗窃。
  • BeanFactory和ApplicationContext都支持BeanPostProcessor昔园、BeanFactoryPostProcessor的使用,區(qū)別是BeanFactory需要手動注冊并炮,而ApplicationContext是自動注冊默刚,ApplicationContext是BeanFactory的子接口,提供了更完成的功能逃魄,還可以訪問資源文件荤西、獲取系統(tǒng)變量、支持國際化伍俘、注冊事件發(fā)布等等邪锌。

Spring容器的啟動流程

  • 首先掃描得到所有的BeanDefinition對象,并存放在Map中癌瘾。
  • 篩選出非懶加載的單例Bean進(jìn)行創(chuàng)建觅丰,步驟包括推斷構(gòu)造方法、實(shí)例化妨退、屬性填充妇萄、初始化前、初始化中咬荷、初始化后冠句,其中AOP就發(fā)生在初始化后這一步驟里。
  • 所有的單例Bean創(chuàng)建完成后幸乒,Spring會發(fā)布一個(gè)容器啟動事件懦底。

Spring Bean的生命周期

  • Spring容器啟動時(shí)解析類得到BeanDefinition,它主要存儲Bean的定義信息罕扎,決定Bean的生產(chǎn)方式聚唐。
  • 當(dāng)類存在多個(gè)構(gòu)造方法時(shí),需要推斷用哪個(gè)構(gòu)造方法實(shí)例化得到對象腔召。
  • 對類中添加了@Autowired注解的成員變量進(jìn)行依賴注入杆查。
  • 回調(diào)Aware方法,例如BeanNameAware宴咧、BeanFactoryAware等等根灯。
  • 調(diào)用BeanPostProcessor初始化前(AOP)、初始化掺栅、初始化后(AOP)的方法烙肺。
  • 如果Bean是單例,則放進(jìn)單例池中氧卧,使用Bean桃笙。
  • Spring容器關(guān)閉前調(diào)用DisposableBean中的destory()方法。

Spring框架中的單例Bean線程安不安全

  • 不安全沙绝,Spring加載Bean默認(rèn)使用單例模式搏明,并沒有對Bean進(jìn)行多線程封裝處理鼠锈。
  • Controller層、Service層星著、Dao層购笆,本身并不是線程安全的,如果需要定義實(shí)例變量虚循,就需要用ThreadLocal把變量設(shè)為線程私有同欠,如果需要多線程之間共享,就需要使用Lock實(shí)現(xiàn)同步横缔。
  • 可以修改Bean的作用域铺遂,使每次請求Bean都重新實(shí)例化對象,保證線程安全茎刚。

Spring Bean有幾種作用域

  • singleton:默認(rèn)創(chuàng)建方式襟锐,由BeanFactory來維護(hù),生命周期和IOC容器一樣膛锭。
  • prototype:每次請求Bean都重新注入一個(gè)新的對象粮坞。
  • request:每個(gè)HTTP請求中都創(chuàng)建一個(gè)單例對象。
  • session:每次會話中都創(chuàng)建一個(gè)單例對象泉沾。
  • application:ServletContext生命周期中創(chuàng)建一個(gè)單例對象捞蚂。
  • websocket:WebSocket生命周期中創(chuàng)建一個(gè)單例對象。

Spring事務(wù)的實(shí)現(xiàn)方式跷究、原理、隔離級別

  • 類和方法上添加@Transactional注解便可以使用Spring的事務(wù)敲霍。
  • Spring的事務(wù)基于數(shù)據(jù)庫的事務(wù)進(jìn)行了擴(kuò)展俊马,為啟用事務(wù)的Bean創(chuàng)建代理對象,代理對象會取消事務(wù)的自動提交肩杈,再執(zhí)行原來的邏輯柴我,過程沒有異常再把事務(wù)提交,反之進(jìn)行邏輯回滾扩然,默認(rèn)回滾RuntimeException和Error艘儒,也可以通過注解的rollbackFor屬性自定義回滾的異常。
  • 未提交讀(read uncommitted):事務(wù)的最低隔離等級夫偶,AB兩個(gè)事務(wù)都開啟的前提下界睁,A方對表數(shù)據(jù)進(jìn)行了修改,在未提交事務(wù)的情況下兵拢,B方對表進(jìn)行查詢時(shí)能讀取到A方修改后的數(shù)據(jù)翻斟,存在臟讀現(xiàn)象,安全性最低说铃。
  • 已提交讀(read committed):事務(wù)隔離等級比未提交讀的高访惜,AB兩個(gè)事務(wù)都開啟的前提下嘹履,A方在未提交事務(wù)的情況下對表做的任何修改B方都不會看到,A方提交事務(wù)后债热,B方在未提交事務(wù)的情況下能看到A方對表做的修改砾嫉,A方對表數(shù)據(jù)進(jìn)行更新則B方出現(xiàn)不可重復(fù)讀的現(xiàn)象(相同的查詢語句查出來的數(shù)據(jù)值不一樣),A方對表數(shù)據(jù)進(jìn)行新增窒篱、刪除則B方出現(xiàn)幻讀的現(xiàn)象(相同的查詢語句查出來的數(shù)據(jù)行不一樣)焰枢。
  • 可重復(fù)讀(repeatable read):事務(wù)隔離等級比已提交讀的高,AB兩個(gè)事務(wù)都開啟的前提下舌剂,各自會生成一個(gè)數(shù)據(jù)表的快照济锄,A方對表數(shù)據(jù)進(jìn)行了修改并提交了事務(wù),B方在未提交事務(wù)的情況下霍转,仍然看不到A方做的任何修改荐绝,解決了不可重復(fù)讀的現(xiàn)象,B方提交事務(wù)后避消,如果A方做的操作是新增或刪除低滩,則此時(shí)會出現(xiàn)幻讀現(xiàn)象。
  • 可串行化(serializable):事務(wù)的最高隔離等級岩喷,AB兩個(gè)事務(wù)都開啟的前提下恕沫,A方對表數(shù)據(jù)進(jìn)行了修改,在未提交事務(wù)的情況下表會加鎖纱意,B方對表進(jìn)行查詢時(shí)會被堵塞婶溯,直到A方提交事務(wù)或者超時(shí)為止。

Spring事務(wù)的傳播機(jī)制

  • REQUIRED:如果沒有事務(wù)偷霉,則創(chuàng)建一個(gè)事務(wù)迄委,反之加入當(dāng)前事務(wù)。
  • SUPPORTS:當(dāng)前存在事務(wù)类少,則加入事務(wù)叙身,反之以非事務(wù)形式執(zhí)行。
  • MANDATORY:當(dāng)前存在事務(wù)硫狞,則加入事務(wù)信轿,反之拋出異常。
  • REQUIRES_NEW:創(chuàng)建一個(gè)事務(wù)残吩,如果已存在事務(wù)财忽,則掛起當(dāng)前事務(wù)。
  • NOT_SUPPORTED:以非事務(wù)方式執(zhí)行世剖,如果已存在事務(wù)定罢,則掛起當(dāng)前事務(wù)。
  • NEVER:不使用事務(wù)旁瘫,如果已存在事務(wù)祖凫,則拋出異常琼蚯。
  • NESTED:當(dāng)前存在事務(wù),則創(chuàng)建一個(gè)子事務(wù)進(jìn)行嵌套惠况,子事務(wù)發(fā)生異常不提交遭庶,但不會影響到父事務(wù)的提交,反之創(chuàng)建一個(gè)事務(wù)稠屠。

Spring事務(wù)的隔離級別

  • ISOLATION_DEFAULT:使用數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級別峦睡。
  • ISOLATION_READ_UNCOMMITTED:讀未提交,允許事務(wù)執(zhí)行過程中讀取其它事務(wù)未提交的數(shù)據(jù)权埠。
  • ISOLATION_READ_COMMITTED:讀已提交榨了,允許事務(wù)執(zhí)行過程中讀取其它事務(wù)已提交的數(shù)據(jù)。
  • ISOLATION_REPEATABLE_READ:可重復(fù)讀攘蔽,在同一個(gè)事務(wù)內(nèi)龙屉,任意時(shí)刻查詢的數(shù)據(jù)結(jié)果都是一樣的。
  • ISOLATION_SERIALIZABLE:可串行化满俗,所有事務(wù)按順序
    依次執(zhí)行转捕。

Spring事務(wù)什么時(shí)候會失效

  • 類方法的自調(diào)用,Spring事務(wù)的原理是AOP唆垃,自調(diào)用方法的對象不是代理類五芝。
  • @Transactional注解只作用于public修飾的方法,非public修飾的方法不支持事務(wù)辕万。
  • 數(shù)據(jù)庫不支持事務(wù)枢步、類沒有被Spring容器管理、手動捕獲處理了異常蓄坏。

Spring使用到哪些設(shè)計(jì)模式

  • 單例模式:Bean對象默認(rèn)的創(chuàng)建方式是Singleton价捧。
  • 觀察者模式:Spring的事件監(jiān)聽和訂閱。
  • 代理模式:AOP的實(shí)現(xiàn)涡戳,為不同的功能引入公共行為。
  • 簡單工廠模式:BeanFactory和ApplicationContext都是創(chuàng)建Bean的工廠脯倚。
  • 工廠方法模式:FactoryBean是一個(gè)工廠接口渔彰,需要通過不同具體的Bean來實(shí)現(xiàn),對象初始化采用的是懶加載方式推正,Spring管理BeanFactory恍涂,BeanFactory根據(jù)使用場景創(chuàng)建FactoryBean。
  • 裝飾設(shè)計(jì)模式:DataSource可以是不同的數(shù)據(jù)庫植榕,根據(jù)客戶端請求動態(tài)更改屬性達(dá)到連接不同數(shù)據(jù)源的目的再沧。
  • 適配器模式:AOP的增強(qiáng)通知,如前置通知尊残、后置通知炒瘸、環(huán)繞通知等等淤堵。
  • 模板方法模式:定義流程的算法骨架,把一些步驟延遲到子類中執(zhí)行顷扩,使得子類在不改變算法骨架的情況下重寫算法拐邪。
  • 策略模式:定義一系列的算法并封裝起來,使得算法獨(dú)立也可以相互替換隘截。

Spring扎阶、SpringMVC、SpringBoot的區(qū)別

  • Spring是一個(gè)IOC容器婶芭,用來集中管理Bean东臀,支持餓漢式初始化和懶加載,通過依賴注入實(shí)現(xiàn)控制反轉(zhuǎn)犀农,降低了代碼的耦合度惰赋,通過AOP面向切面編程為不同的功能引入公共行為,彌補(bǔ)了OOP面向?qū)ο蟠a冗余的問題井赌,用最小的侵入性實(shí)現(xiàn)松散耦合谤逼,可以很方便整合各種框架。
  • SpringMVC是Spring對Web框架的一種解決方案仇穗,提供了前端控制器接收請求流部,通過定義的路由策略和視圖解析技術(shù)展現(xiàn)給前端。
  • SpringBoot是Spring提供的快速開發(fā)工具纹坐,內(nèi)置了Web容器枝冀,可以直接啟動運(yùn)行Web應(yīng)用,管理了常用的第三方依賴包的版本耘子,減少了版本依賴的沖突果漾,提供了Java配置的方式,減少了大量的Xml配置谷誓,提供了很多的Starter結(jié)合自動配置绒障,對主流框架無配置集成,提供了監(jiān)控功能捍歪,可以查看應(yīng)用程序的運(yùn)行狀況户辱,如內(nèi)存、線程池糙臼、網(wǎng)絡(luò)請求統(tǒng)計(jì)等等庐镐。

SpringMVC的工作流程

  • 用戶發(fā)送請求至前端控制器DispatcherServlet,DispatcherServlet調(diào)用HandlerMapping映射器变逃,HandlerMapping通過XML配置必逆、注解(@Controller)的方式找到后端控制器和攔截器,并返回給DispatcherServlet。
  • DispatcherServlet通過HandlerAdapter處理適配器執(zhí)行Controller并返回結(jié)果ModelAndView名眉。
  • DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器粟矿,通過解析生成View視圖,DispatcherServlet根據(jù)View進(jìn)行渲染璧针,響應(yīng)用戶嚷炉。

CAP 理論

  • Consistency:一致性,即更新操作成功返回給客戶端后探橱,所有節(jié)點(diǎn)在同一時(shí)間的數(shù)據(jù)完全一致申屹。
  • Availability:可用性,即服務(wù)一直可用隧膏,而且是正常響應(yīng)時(shí)間哗讥。
  • Partition Tolerance:分區(qū)容錯性,即分布式系統(tǒng)在遇到某節(jié)點(diǎn)或網(wǎng)絡(luò)分區(qū)故障的時(shí)候胞枕,仍然能夠?qū)ν馓峁M足一致性和可用性的服務(wù)杆煞。
  • CP是強(qiáng)一致性,AP是可用性腐泻,分區(qū)容錯時(shí)只能二選一决乎。

BASE 理論

  • Basically Avaliable:基本可用,響應(yīng)時(shí)間上的損失和系統(tǒng)功能上的損失派桩。
  • Soft State:軟狀態(tài)构诚,數(shù)據(jù)同步允許一定的延時(shí)。
  • Eventually Consistent:最終一致性铆惑,系統(tǒng)中所有的數(shù)據(jù)副本范嘱,在經(jīng)過一段時(shí)間的同步后,最終能夠達(dá)到一致的狀態(tài)员魏。

GC如何判斷對象可以被回收

  • 引用計(jì)數(shù)法:每個(gè)對象都有一個(gè)引用計(jì)數(shù)屬性丑蛤,新增一個(gè)引用時(shí)計(jì)數(shù)加一,釋放一個(gè)引用時(shí)計(jì)數(shù)減一撕阎,計(jì)數(shù)為零時(shí)可以回收受裹。
  • 可達(dá)性分析法:從GC的Roots開始向下搜索,當(dāng)一個(gè)對象不存在引用鏈時(shí)可以回收虏束,常見的GC Roots對象有虛擬機(jī)棧的引用對象名斟、方法區(qū)的靜態(tài)引用對象和常量引用對象、本地方法棧的JNI引用對象魄眉、正在運(yùn)行的線程。不可達(dá)對象需要經(jīng)過兩次標(biāo)記過程闷袒,第一次是不存在引用鏈時(shí)坑律,第二次是執(zhí)行對象的finalize()方法。

消息隊(duì)列有哪些作用

  • 解耦:系統(tǒng)間的通訊依賴消息隊(duì)列,單個(gè)系統(tǒng)獨(dú)立晃择。
  • 異步:上游不受下游執(zhí)行結(jié)果影響時(shí)冀值,下游操作放在消息隊(duì)列中執(zhí)行,提高上游返回的效率宫屠。
  • 流量削峰:在高并發(fā)的環(huán)境中列疗,系統(tǒng)在同一時(shí)間點(diǎn)接收大量的網(wǎng)絡(luò)請求容易引起宕機(jī),把網(wǎng)絡(luò)請求放在消息隊(duì)列中排隊(duì)消費(fèi)浪蹂,減輕了服務(wù)器承受的壓力抵栈。
  • 使用場景:業(yè)務(wù)審批流的消息推送、系統(tǒng)功能錯誤日志的記錄坤次。

消息隊(duì)列如何保證消息的可靠傳輸

  • 生產(chǎn)者不能重復(fù)生產(chǎn)消息古劲,消費(fèi)者不能重復(fù)消費(fèi)消息。
  • 生產(chǎn)者發(fā)送成功的消息缰猴,消費(fèi)者一定能消費(fèi)成功产艾。

死信隊(duì)列和延時(shí)隊(duì)列分別是什么

  • 死信隊(duì)列中存放著消費(fèi)失敗的消息,可用來消息的消費(fèi)重試滑绒。
  • 延時(shí)隊(duì)列中存放著需要延時(shí)消費(fèi)的消息闷堡,可用來處理具有過期性的業(yè)務(wù),如訂單在十分鐘內(nèi)未完成支付則取消訂單疑故。

Kafka吞吐量高的原因

  • 生產(chǎn)者采用異步發(fā)送消息機(jī)制杠览,消息緩存起來后就直接返回成功的操作提示。
  • 當(dāng)緩存的消息量達(dá)到某個(gè)閾值時(shí)焰扳,批量發(fā)送給Broker處理倦零,減少了網(wǎng)絡(luò)的IO,從而提高了吞吐量吨悍。
  • 但生產(chǎn)者宕機(jī)會導(dǎo)致消息丟失扫茅,通過降低可靠性來提高性能。

Netty和Tomcat的特點(diǎn)和區(qū)別

  • Netty是基于NIO的異步網(wǎng)絡(luò)通訊框架育瓜,關(guān)注網(wǎng)絡(luò)數(shù)據(jù)的傳輸葫隙,不關(guān)注傳輸?shù)木W(wǎng)絡(luò)協(xié)議,可用于開發(fā)各種高效的網(wǎng)絡(luò)服務(wù)器躏仇。
  • Tomcat是Web服務(wù)器恋脚,內(nèi)部只運(yùn)行Servlet的程序和處理http請求。

數(shù)據(jù)庫的事務(wù)ACID是怎么保證的

  • A:原子性(Atomicity)焰手,事務(wù)需要回滾時(shí)從undo log中獲取信息糟描。
  • C:一致性,由其他三大特征保證书妻,程序保證業(yè)務(wù)上的一致性船响。
  • I:隔離性(Isolation),由多版本并發(fā)控制(Multi-Version Concurrency Control)保證。
  • D:持久性(Duration)见间,事務(wù)需要前滾時(shí)從redo log中獲取信息聊闯。

MySQL中binlog、redolog米诉、undolog的區(qū)別和作用

  • binlog是MySQL Service層的邏輯日志菱蔬,記錄了數(shù)據(jù)庫事務(wù)提交后的增刪改操作語句,日志文件寫滿后史侣,會寫入到另一個(gè)新的文件拴泌,適合用于備份,如主從復(fù)制抵窒。
  • redolog和undolog是InnoDB引擎的日志弛针,用于支持事務(wù)。
  • 事務(wù)執(zhí)行的完整過程李皇,執(zhí)行器先查詢數(shù)據(jù)是否在InnoDB存儲引擎的內(nèi)存中削茁,不在則從磁盤加載到內(nèi)存去,有則直接返回?cái)?shù)據(jù)掉房,然后把數(shù)據(jù)的舊值寫入undolog中茧跋,再把值更新到InnoDB存儲引擎的內(nèi)存中,再把數(shù)據(jù)的新值寫入redolog中卓囚,此時(shí)狀態(tài)為prepare瘾杭,當(dāng)事務(wù)發(fā)生回滾,先刪除prepare狀態(tài)的redolog哪亿,再根據(jù)undolog將數(shù)據(jù)還原粥烁,當(dāng)事務(wù)提交后,先把redolog的狀態(tài)改為commit蝇棉,再把binlog日志寫入磁盤讨阻。

MySQL 主從同步原理

  • binlog是數(shù)據(jù)庫服務(wù)從啟用起記錄所有修改操作的文件。
  • 當(dāng)主節(jié)點(diǎn)的binlog發(fā)生改變篡殷,log-dump線程會向從節(jié)點(diǎn)發(fā)送變化的binlog钝吮。
  • 從節(jié)點(diǎn)的IO線程接收到binlog后,寫入到relaylog中板辽。
  • 從節(jié)點(diǎn)的SQL線程讀取relaylog文件對數(shù)據(jù)更新進(jìn)行重放奇瘦,確保了數(shù)據(jù)的一致性。

Redis過期鍵的刪除策略

  • 惰性過期:只有訪問key時(shí)劲弦,才判斷是否過期耳标,過期則刪除,該策略可以節(jié)省CPU資源邑跪,但對內(nèi)存不友好麻捻,如果大量的key沒有被再次訪問纲仍,就不會被刪除,占用大量內(nèi)存贸毕。
  • 定期過期:每隔一段時(shí)間就去掃描expires字典剖煌,字典中保存了所有的key和expire-time端姚,從中清除已過期的key。

Redis內(nèi)存不足的淘汰策略

  • volatile-lru:從設(shè)置了過期時(shí)間的數(shù)據(jù)集中篩選出最近使用最少的數(shù)據(jù)進(jìn)行淘汰牵啦。
  • volatile-ttl:從設(shè)置了過期時(shí)間的數(shù)據(jù)集中篩選出即將要過期的數(shù)據(jù)進(jìn)行淘汰寇僧。
  • volatile-random:從設(shè)置了過期時(shí)間的數(shù)據(jù)集中隨機(jī)篩選出數(shù)據(jù)進(jìn)行淘汰摊腋。
  • allkeys-lru:從數(shù)據(jù)集中篩選出最近使用最少的數(shù)據(jù)進(jìn)行淘汰。
  • allkeys-random:從數(shù)據(jù)集中隨機(jī)篩選出數(shù)據(jù)進(jìn)行淘汰嘁傀。
  • noeviction:默認(rèn)配置兴蒸,禁止驅(qū)逐數(shù)據(jù),所有申請內(nèi)存的命令都引起報(bào)錯细办。

Redis單線程速度快的原因

  • 核心基于非堵塞的IO多路復(fù)用機(jī)制橙凳。
  • 單線程避免了多線程頻繁切換上下文的性能開銷。
  • 純內(nèi)存操作笑撞。

Redis集群方案

  • 哨兵模式:sentinel是redis集群非常重要的組件岛啸,本身就是分布式系統(tǒng)。
  • 集群監(jiān)控:負(fù)責(zé)監(jiān)控主(master)從(slave)結(jié)構(gòu)中的每臺服務(wù)器是否正常工作茴肥。
  • 消息通知:當(dāng)某個(gè)redis實(shí)例發(fā)生故障坚踩,哨兵會向其它哨兵和redis實(shí)例發(fā)送通知。
  • 故障轉(zhuǎn)移:當(dāng)master服務(wù)掛掉后瓤狐,哨兵會選舉一個(gè)slave服務(wù)作為master服務(wù)瞬铸,告知其它slave服務(wù)新的連接地址并重新連接。

zookeeper和eureka的區(qū)別

  • zookeeper的設(shè)計(jì)是強(qiáng)一致性础锐,是分布式的協(xié)調(diào)系統(tǒng)嗓节,用于資源的統(tǒng)一管理,當(dāng)節(jié)點(diǎn)crash后郁稍,需要進(jìn)行l(wèi)eader的選舉赦政,這期間zookeeper的服務(wù)是不可用的。
  • eureka的設(shè)計(jì)是高可用性耀怜,是服務(wù)注冊發(fā)現(xiàn)系統(tǒng)恢着,用于微服務(wù)的注冊和發(fā)現(xiàn),各個(gè)節(jié)點(diǎn)都是平等的财破,當(dāng)一個(gè)節(jié)點(diǎn)crash后掰派,剩余的節(jié)點(diǎn)依然可以提供服務(wù)。

SpringCloud和Dubbo的區(qū)別

  • 底層協(xié)議:SpringCloud基于http協(xié)議左痢,Dubbo基于tcp協(xié)議靡羡,決定了dubbo性能更好一些系洛。
  • 注冊中心:SpringCloud使用的是eureka,Dubbo使用的是zookeeper略步。
  • 模型定義:SpringCloud將一個(gè)應(yīng)用定義為服務(wù)描扯,Dubbo將一個(gè)接口定義為服務(wù)。SpringCloud是一個(gè)生態(tài)趟薄,而Dubbo是SpringCloud生態(tài)中關(guān)于服務(wù)治理的一種方案绽诚。

ThreadLocal的原理

  • ThreadLocal是Java中所提供的線程本地存儲機(jī)制,可以把數(shù)據(jù)緩存到線程內(nèi)部杭煎。
  • 每個(gè)Thread對象中都包含ThreadLocalMap恩够,key為ThreadLocal對象,value為緩存數(shù)據(jù)羡铲,在線程池中使用ThreadLocal會造成內(nèi)存泄漏蜂桶,原因是線程池的線程不會回收,ThreadLocal的引用也不會釋放也切,因此使用完需要手動調(diào)用ThreadLocal的remove方法扑媚。
  • ThreadLocal的應(yīng)用場景是數(shù)據(jù)庫連接管理,線程之間不共享連接對象贾费,如Spring的事務(wù)管理就是基于單線程的钦购,Connection存放在線程內(nèi)部,因此Spring無法保證多線程事務(wù)的一致性褂萧。

ReentrantLock中的公平鎖和非公平鎖的原理

  • 公平鎖:線程調(diào)用lock()方法時(shí)押桃,先檢查AQS隊(duì)列中是否存在線程在排隊(duì),如果有則排隊(duì)等待导犹,沒有則獲取到鎖唱凯。
  • 非公平鎖:線程調(diào)用lock()方法時(shí),直接和AQS隊(duì)列的線程競爭鎖谎痢,如果獲取到鎖就結(jié)束了磕昼,沒有則加入AQS隊(duì)列等待。

類加載器的雙親委派模型节猿,有什么好處

  • JVM中存在三個(gè)類加載器:BootstrapClassLoader > ExtClassLoader > AppClassLoader票从。
  • JVM在加載一個(gè)類時(shí)會調(diào)用AppClassLoader的loadClass()方法,這里面又會調(diào)用ExtClassLoader的loadClass()方法滨嘱,這里面又會調(diào)用BootstrapClassLoader的loadClass()方法峰鄙,加載成功則直接返回,反之則往下執(zhí)行加載太雨。
  • 好處在于加載安全吟榴,避免用戶編寫的類覆蓋了Java的核心類,也避免了類的重復(fù)加載囊扳。

Sychronized的偏向鎖吩翻、輕量級鎖兜看、重量級鎖

  • 偏向鎖:Sychronized會在對象頭存放當(dāng)前線程的ID作為鎖的信息,當(dāng)線程下次再來訪問對象時(shí)狭瞎,可以直接獲得鎖细移,是可重入的概念。
  • 輕量級鎖:由偏向鎖升級而來脚作,當(dāng)一個(gè)線程來獲取對象鎖時(shí)葫哗,對象頭已經(jīng)存在另一個(gè)線程的鎖信息時(shí),會進(jìn)行自旋來等待鎖球涛,這時(shí)不會堵塞線程。
  • 重量級鎖:當(dāng)輕量級鎖自旋次數(shù)達(dá)到一定次數(shù)時(shí)仍沒有獲取到鎖時(shí)校镐,會升級成重量級鎖亿扁,這時(shí)會堵塞線程。

CopyOnWriteArrayList的實(shí)現(xiàn)原理

  • 底層是對數(shù)組的封裝鸟廓,當(dāng)需要add元素時(shí)从祝,添加ReentrantLock鎖。
  • 新增時(shí)通過復(fù)制舊數(shù)組來創(chuàng)建新數(shù)組引谜,新數(shù)組比舊數(shù)組的長度多一牍陌,再把新元素放到新數(shù)組的末位。
  • 刪除時(shí)先找出被移除元素的下標(biāo)员咽,然后把該元素后面的元素下標(biāo)全部都往前進(jìn)一毒涧,再通過復(fù)制舊數(shù)組來創(chuàng)建新數(shù)組,新數(shù)組比舊數(shù)組的長度少一贝室。
  • 當(dāng)需要get元素時(shí)契讲,不會添加鎖。

ConcurrentHashMap的實(shí)現(xiàn)原理

  • 底層是Segment對象的數(shù)組滑频,Segment對象的結(jié)構(gòu)是數(shù)組+鏈表捡偏。
  • 實(shí)現(xiàn)了鎖分段技術(shù),JDK7中鎖的粒度為Segment對象峡迷,JDK8中鎖的粒度為Segment對象的鏈表银伟,降低了鎖的粒度。
  • put()方法和get()方法都需要調(diào)用二次hash()方法绘搞,第一次是定位到Segment對象彤避,第二次是定位到Segment對象的鏈表。

SpringMVC的九大核心組件

  • HandlerMapping:用于接收用戶的請求看杭,根據(jù)訪問的url來找到對應(yīng)的Handler作出響應(yīng)忠藤。
  • HandlerAdapter:用于Handler適配Servlet的請求,Servlet相當(dāng)固定楼雹,分為request和response模孩,Handler則形式多樣化尖阔。
  • HandlerExceptionResolver:異常處理解析器,通過捕獲解析異常榨咐,返回ModelAndView對象介却。
  • LocaleResolver:區(qū)域解析器,從request請求中解析出Locale對象块茁,用于配置國際化資源以及結(jié)合ViewResolver解析視圖齿坷。
  • ViewResolver:視圖解析器,結(jié)合Local對象使用数焊,把String類型的視圖名解析成View類型的視圖永淌,用于渲染頁面。
  • MultipartResolver:文件解析器佩耳,把request請求封裝為MultipartHttpServletRequest請求遂蛀,用于接收文件上傳請求并清理上傳過程產(chǎn)生的臨時(shí)資源。
  • ThemeResolver:主題解析器干厚,用于解析*.properties文件李滴,同時(shí)支持國際化。
  • FlashMapManager:用于管理FlashMap蛮瞄,F(xiàn)lashMap主要用在redirect中傳遞參數(shù)所坯。
  • RequestToViewNameTranslator:從request請求中獲取ViewName,交由ViewResolver查找View視圖挂捅。

分布式事務(wù)的解決方案有哪些

  • 2PC(Prepare Commit):第一階段芹助,事務(wù)管理器(協(xié)調(diào)者)會執(zhí)行SQL腳本,但不會提交事務(wù)籍凝,此時(shí)數(shù)據(jù)庫資源被鎖定周瞎,資源管理器(參與者)將undo和redo寫入事務(wù)日志,第二階段饵蒂,資源管理器根據(jù)操作結(jié)果提交事務(wù)或者回滾事務(wù)声诸,釋放資源。缺點(diǎn)是協(xié)調(diào)者或者參與者宕機(jī)會引起數(shù)據(jù)不一致退盯。
  • 3PC(Prepare Commit):第一階段CanCommit彼乌,協(xié)調(diào)者詢問參與者是否可以提交事務(wù),第二階段PreCommit渊迁,協(xié)調(diào)者執(zhí)行SQL腳本但不提交事務(wù)慰照,第三階段DoCommit,如果二階段中參與者宕機(jī)或者預(yù)提交操作失敗則執(zhí)行回滾琉朽,反之執(zhí)行事務(wù)的提交毒租,釋放資源。優(yōu)點(diǎn)是加入超時(shí)機(jī)制箱叁,解決2PC宕機(jī)時(shí)遇到的問題墅垮。
  • TCC(Try Confirm Cancel):通過系統(tǒng)提供的業(yè)務(wù)邏輯流程調(diào)度惕医,分為三個(gè)步驟,首先是try(entity)算色,這個(gè)過程會鎖定資源抬伺,給所有服務(wù)提供更新的預(yù)校驗(yàn),如庫存更新時(shí)分為即時(shí)庫存和可用庫存灾梦,此階段將會凍結(jié)部分可用庫存峡钓,同時(shí)會記錄即時(shí)庫存、凍結(jié)庫存若河、可用庫存的日志能岩,滿足條件時(shí)再執(zhí)行Confirm(entity),此階段將會實(shí)際更新即時(shí)庫存萧福,同時(shí)會記錄即時(shí)庫存捧灰、凍結(jié)庫存、可用庫存的日志统锤,當(dāng)所有服務(wù)提交成功時(shí)釋放資源,當(dāng)某個(gè)服務(wù)提交失敗時(shí)炭庙,再執(zhí)行所有服務(wù)的Cancel(entity)饲窿,把數(shù)據(jù)統(tǒng)一回滾,此階段將會反凍結(jié)部分可用庫存焕蹄,同時(shí)會記錄即時(shí)庫存逾雄、凍結(jié)庫存、可用庫存的日志腻脏,保證了數(shù)據(jù)的一致性鸦泳。
  • AT(Auto Transcation):業(yè)務(wù)無侵入二階段提交,在一階段中Seata會攔截業(yè)務(wù)SQL永品,解析其語義并找到需要更新的業(yè)務(wù)數(shù)據(jù)做鹰,在更新前把數(shù)據(jù)保存為前鏡像(before-image),再執(zhí)行業(yè)務(wù)SQL更新數(shù)據(jù)鼎姐,在更新后把數(shù)據(jù)保存為后鏡像(after-image)钾麸,最后生成行鎖(避免臟讀),保證了一階段的原子性炕桨。在二階段提交時(shí)饭尝,只需將一階段的鏡像和行鎖刪除即可。在二階段回滾時(shí)献宫,先對比數(shù)據(jù)庫當(dāng)前的業(yè)務(wù)數(shù)據(jù)和后鏡像的業(yè)務(wù)數(shù)據(jù)是否相同钥平,如果相同則說明沒有臟寫,通過前鏡像的業(yè)務(wù)數(shù)據(jù)還原到數(shù)據(jù)庫姊途,最后把一階段的鏡像和行鎖刪除涉瘾,反之需要人工處理知态。
  • Seata框架:提供了AT 模式、TCC 模式睡汹、Saga 模式和 XA 模式四種分布式事務(wù)解決方案肴甸。

泛型中extends和super的區(qū)別

  • <? extends T> 表示包括T在內(nèi)的任何子類。
  • <? super T> 表示包括T在內(nèi)的任何父類囚巴。

TCP的三次握手和四次揮手

  • TCP協(xié)議是七層網(wǎng)絡(luò)協(xié)議中的傳輸層協(xié)議原在,負(fù)責(zé)數(shù)據(jù)的可靠傳輸。
  • 在建立TCP連接時(shí)彤叉,需要通過三次握手庶柿,首先是客戶端向服務(wù)端發(fā)送SYN(Synchronize Sequence Numbers),其次是服務(wù)端接收到SYN后給客戶端返回SYN_ACK秽浇,最后是客戶端接收到SYN_ACK后給服務(wù)端發(fā)送一個(gè)ACK(Acknowledge character)浮庐。
  • 在斷開TCP連接時(shí),需要通過四次揮手柬焕,首先是客戶端向服務(wù)端發(fā)送FIN(finish)审残,其次是服務(wù)端接收到FIN后向客戶端發(fā)送ACK,意味著服務(wù)端接收到斷開連接的請求斑举,客戶端可以不發(fā)送數(shù)據(jù)了搅轿,但服務(wù)端可能還有數(shù)據(jù)在處理,待數(shù)據(jù)完成處理后富玷,服務(wù)端向客戶端發(fā)送FIN璧坟,表示當(dāng)前可以斷開連接,最后是客戶端接收到FIN后向服務(wù)端發(fā)送ACK赎懦,表示當(dāng)前也可以斷開連接雀鹃。

HTTPS如何保證安全傳輸

  • 通過使用對稱加密、非對稱加密励两、數(shù)字證書等方式來保證數(shù)據(jù)的安全傳輸黎茎。
  • 客戶端向服務(wù)端發(fā)送數(shù)據(jù)前,需要先建立TCP連接伐蒋,建立完成后服務(wù)端會向客戶端發(fā)送公鑰工三,客戶端通過公鑰來對傳輸數(shù)據(jù)進(jìn)行加密,服務(wù)端接收到傳輸數(shù)據(jù)后通過私鑰進(jìn)行解密先鱼,這種就是非對稱加密俭正。
  • 服務(wù)端向客戶端發(fā)送非對稱公鑰時(shí),可以先把非對稱公鑰和服務(wù)端相關(guān)信息通過hash算法生成消息摘要焙畔,再通過數(shù)字證書提供的私鑰對消息摘要進(jìn)行加密生成數(shù)字簽名掸读,再把服務(wù)端相關(guān)信息和數(shù)字簽名一起形成數(shù)字證書發(fā)送到客戶端,客戶端通過數(shù)字證書提供的公鑰進(jìn)行解密,從而得到非對稱加密的公鑰儿惫。
  • 在服務(wù)端給客戶端傳輸?shù)倪^程中澡罚,數(shù)據(jù)包可能會被中間人截獲,同時(shí)被解密出非對稱的公鑰肾请,但是中間人是沒辦法偽造數(shù)字證書發(fā)送給客戶端的留搔,生成數(shù)字證書需要私鑰,網(wǎng)站如果需要支持HTTPS铛铁,就需要申請數(shù)字證書的私鑰隔显,這樣就確保安全了。

Dubbo的工作流程

  • Spring容器啟動時(shí)饵逐,Dubbo的Provider會同時(shí)啟動括眠,向Zookeeper服務(wù)中心注冊相關(guān)信息,如IP倍权、端口掷豺、接口、版本薄声、協(xié)議等当船。
  • Dubbo的Consumer啟動時(shí),會去Zookeeper中獲取已注冊服務(wù)的信息默辨,當(dāng)Provider的信息發(fā)生變化時(shí)生年,Zookeeper會向Consumer推送通知。
  • Consumer通過RPC的方式調(diào)用Provider的方法廓奕,每隔兩分鐘,Provider和Consumer都會向Monitor發(fā)送訪問次數(shù)档叔,由Monitor進(jìn)行統(tǒng)計(jì)桌粉。

如何進(jìn)行自我介紹

  • 基本信息,姓名衙四、年齡铃肯、學(xué)校、學(xué)歷传蹈。
  • 工作經(jīng)驗(yàn)押逼,最近一段時(shí)間開發(fā)的最熟悉、最有價(jià)值惦界、技術(shù)棧最豐富的項(xiàng)目挑格,在項(xiàng)目中承擔(dān)的主要職責(zé)以及解決項(xiàng)目的主要問題。
  • 企業(yè)背調(diào)沾歪,說下對這家面試公司的了解漂彤,行業(yè)解決方案。
  • 面試官,上面就是我的個(gè)人簡介挫望,您看您有什么想了解的立润。

如何陳述自己的項(xiàng)目

  • 用一個(gè)最近且最熟悉的項(xiàng)目進(jìn)行陳述。
  • 描述項(xiàng)目的核心價(jià)值和包含的功能以及參與的核心模塊和使用到的技術(shù)棧媳板。
  • 描述項(xiàng)目開發(fā)過程中存在的技術(shù)問題以及解決思路和方案桑腮。
  • 面試官,上面就是我的項(xiàng)目經(jīng)驗(yàn)的簡單介紹蛉幸,您看您有什么想問的破讨。

如何回答自己會的問題

  • 按照總分的思想,分步驟來說明實(shí)現(xiàn)的機(jī)制巨缘,結(jié)合實(shí)際項(xiàng)目經(jīng)驗(yàn)談怎么解決添忘。
  • 面試官,我已經(jīng)回答完了若锁,剛剛是我對于這個(gè)知識的理解搁骑,您看一下哪里有問題,可以幫我指點(diǎn)下又固。

如何回答自己不會的問題

  • 有一點(diǎn)了解或者接觸過類似的仲器,按照知道的表述出來。
  • 一點(diǎn)都不會仰冠,可以問面試官乏冀,這個(gè)技術(shù)在項(xiàng)目中有什么作用。

如何回答自己的缺點(diǎn)

  • 把優(yōu)點(diǎn)說成缺點(diǎn)洋只,如個(gè)人執(zhí)著辆沦、代碼潔癖等等。

如何回答自己的職業(yè)規(guī)劃

  • 我從不做三年以上的職業(yè)規(guī)劃识虚,但我的終極目標(biāo)是系統(tǒng)架構(gòu)師肢扯。
  • 如果我有幸入職貴公司的話,我會從本職工作做起担锤,爭取讓自己先做到高級開發(fā)工程師蔚晨。
  • 我相信在貴公司的平臺下,我能獲得更好的發(fā)展肛循,取得更高的成就铭腕,給公司創(chuàng)造更大的價(jià)值。
  • 如果我有幸入職的話多糠,貴公司對我的安排是怎樣的累舷。

如何回答離職原因

  • 千萬不要說上家公司的不好,這是禁忌夹孔。
  • 公司倒閉笋粟、不發(fā)工資怀挠、仲裁。
  • 之前的項(xiàng)目一直在改動害捕,沒有新項(xiàng)目绿淋。
  • 個(gè)人發(fā)展問題。

如何回答你有什么想問的

  • HR尝盼,公司福利吞滞、晉升機(jī)制、加班情況等等盾沫。
  • 面試官裁赠,公司內(nèi)部有沒有技術(shù)培訓(xùn)或者技術(shù)分享,開發(fā)團(tuán)隊(duì)的規(guī)模赴精,行業(yè)解決方案中使用到的技術(shù)佩捞,如果有幸入職公司對自己的安排。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蕾哟,一起剝皮案震驚了整個(gè)濱河市一忱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谭确,老刑警劉巖帘营,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逐哈,居然都是意外死亡芬迄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門昂秃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來禀梳,“玉大人,你說我怎么就攤上這事肠骆〕龌剩” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵哗戈,是天一觀的道長。 經(jīng)常有香客問我荷科,道長唯咬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任畏浆,我火速辦了婚禮胆胰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刻获。我一直安慰自己蜀涨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著厚柳,像睡著了一般氧枣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上别垮,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天便监,我揣著相機(jī)與錄音,去河邊找鬼碳想。 笑死烧董,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胧奔。 我是一名探鬼主播逊移,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼龙填!你這毒婦竟也來了胳泉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤觅够,失蹤者是張志新(化名)和其女友劉穎胶背,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喘先,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钳吟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窘拯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片红且。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖涤姊,靈堂內(nèi)的尸體忽然破棺而出暇番,到底是詐尸還是另有隱情,我是刑警寧澤思喊,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布壁酬,位于F島的核電站,受9級特大地震影響恨课,放射性物質(zhì)發(fā)生泄漏舆乔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一剂公、第九天 我趴在偏房一處隱蔽的房頂上張望希俩。 院中可真熱鬧,春花似錦纲辽、人聲如沸颜武。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳞上。三九已至这吻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間因块,已是汗流浹背橘原。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涡上,地道東北人趾断。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像吩愧,于是被迫代替她去往敵國和親芋酌。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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