互聯網 Java 工程師面試題(Java 并發編程二)

1、并發編程三要素?

1、原子性

原子性指的是一個或者多個操作,要么全部執行并且在執行的過程中不被其他操 作打斷,要么就全部都不執行。

2、可見性

可見性指多個線程操作一個共享變量時,其中一個線程對變量進行修改后,其他 線程可以立即看到修改的結果。

3、有序性

有序性,即程序的執行順序按照代碼的先后順序來執行。

2、實現可見性的方法有哪些?

synchronized 或者 Lock:保證同一個時刻只有一個線程獲取鎖執行代碼,鎖釋放 之前把最新的值刷新到主內存,實現可見性。

3、多線程的價值?

1、發揮多核 CPU 的優勢

多線程,可以真正發揮出多核 CPU 的優勢來,達到充分利用 CPU 的目的,采用多 線程的方式去同時完成幾件事情而不互相干擾。

2、防止阻塞

從程序運行效率的角度來看,單核 CPU 不但不會發揮出多線程的優勢,反而會因 為在單核 CPU 上運行多線程導致線程上下文的切換,而降低程序整體的效率。但 是單核 CPU 我們還是要應用多線程,就是為了防止阻塞。試想,如果單核 CPU 使 用單線程,那么只要這個線程阻塞了,比方說遠程讀取某個數據吧,對端遲遲未返回又沒有設置超時時間,那么你的整個程序在數據返回回來之前就停止運行了。多線程可以防止這個問題,多條線程同時運行,哪怕一條線程的代碼執行讀取數據阻塞,也不會影響其它任務的執行。

3、便于建模

這是另外一個沒有這么明顯的優點了。假設有一個大的任務 A,單線程編程,那么 就要考慮很多,建立整個程序模型比較麻煩。但是如果把這個大的任務 A 分解成 幾個小任務,任務 B、任務 C、任務 D,分別建立程序模型,并通過多線程分別運 行這幾個任務,那就簡單很多了。

4、創建線程的有哪些方式?

1、繼承 Thread 類創建線程類

2、通過 Runnable 接口創建線程類

3、通過 Callable 和 Future 創建線程

4、通過線程池創建

5、創建線程的三種方式的對比?

1、采用實現 Runnable、Callable 接口的方式創建多線程。

優勢是:

線程類只是實現了 Runnable 接口或 Callable 接口,還可以繼承其他類。 在這種方式下,多個線程可以共享同一個 target 對象,所以非常適合多個相同線 程來處理同一份資源的情況,從而可以將 CPU、代碼和數據分開,形成清晰的模 型,較好地體現了面向對象的思想。

劣勢是:

編程稍微復雜,如果要訪問當前線程,則必須使用 Thread.currentThread()方法。

2、使用繼承 Thread 類的方式創建多線程

優勢是:

編寫簡單,如果需要訪問當前線程,則無需使用 Thread.currentThread()方法, 直接使用 this 即可獲得當前線程。

劣勢是:

線程類已經繼承了 Thread 類,所以不能再繼承其他父類。

3、Runnable 和 Callable 的區別

1、Callable 規定(重寫)的方法是 call(),Runnable 規定(重寫)的方法是 run()。

2、Callable 的任務執行后可返回值,而 Runnable 的任務是不能返回值的。

3、Call 方法可以拋出異常,run 方法不可以。

4、運行 Callable 任務可以拿到一個 Future 對象,表示異步計算的結果。它提供 了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結果。通過 Futur對象可以了解任務執行情況,可取消任務的執行,還可獲取執行結果。

6、線程的狀態流轉圖

線程的生命周期及五種基本狀態:

![img_2.png][img_2.png]

7、Java 線程具有五中基本狀態

1、新建狀態(New):當線程對象對創建后,即進入了新建狀態,如:Thread t = new MyThread();

2、就緒狀態(Runnable):當調用線程對象的 start()方法(t.start();),線即進入就緒狀態。處于就緒狀態的線程,只是說明此線程已經做好了準備,隨時 等待 CPU 調度執行,并不是說執行了 t.start()此線程立即就會執行;

3、運行狀態(Running):當 CPU 開始調度處于就緒狀態的線程時,此時線程 才得以真正執行,即進入到運行狀態。注:就 緒狀態是進入到運行狀態的唯一入 口,也就是說,線程要想進入運行狀態執行,首先必須處于就緒狀態中;

4、阻塞狀態(Blocked):處于運行狀態中的線程由于某種原因,暫時放棄對 CPU 的使用權,停止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再 次被 CPU 調用以進入到運行狀態。

根據阻塞產生的原因不同,阻塞狀態又可以分為三種:

1、等待阻塞:運行狀態中的線程執行 wait()方法,使本線程進入到等待阻塞狀態;

2、同步阻塞:線程在獲取 synchronized 同步鎖失敗(因為鎖被其它線程所占用), 它會進入同步阻塞狀態;

3、其他阻塞:通過調用線程的 sleep()或 join()或發出了 I/O 請求時,線程會進入 到阻塞狀態。當 sleep()狀態超時、join()等待線程終止或者超時、或者 I/O 處完畢時,線程重新轉入就緒狀態。

5、死亡狀態(Dead):線程執行完了或者因異常退出了 run()方法,該線程結束生命周期。

8、什么是線程池?有哪幾種創建方式?

線程池就是提前創建若干個線程,如果有任務需要處理,線程池里的線程就會處 理任務,處理完之后線程并不會被銷毀,而是等待下一個任務。由于創建和銷毀 線程都是消耗系統資源的,所以當你想要頻繁的創建和銷毀線程的時候就可以考慮使用線程池來提升系統的性能。

java 提供了一個 java.util.concurrent.Executor 接口的實現用于創建線程池。

9、四種線程池的創建:

1、newCachedThreadPool 創建一個可緩存線程池

2、newFixedThreadPool 創建一個定長線程池,可控制線程最大并發數。

3、newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執 行。

4、newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工 作線程來執行任務。

10、線程池的優點?

1、重用存在的線程,減少對象創建銷毀的開銷。

2、可有效的控制最大并發線程數,提高系統資源的使用率,同時避免過多資源競 爭,避免堵塞。

3、提供定時執行、定期執行、單線程、并發數控制等功能。

11、常用的并發工具類有哪些?

1、CountDownLatch

2、CyclicBarrier

3、Semaphore

4、Exchanger

12、CyclicBarrier 和 CountDownLatch 的區別

1、CountDownLatch 簡單的說就是一個線程等待,直到他所等待的其他線程都執 行完成并且調用 countDown()方法發出通知后,當前線程才可以繼續執行。

2、cyclicBarrier 是所有線程都進行等待,直到所有線程都準備好進入 await()方 法之后,所有線程同時開始執行!

3、CountDownLatch 的計數器只能使用一次。而 CyclicBarrier 的計數器可以使 用 reset() 方法重置。所以 CyclicBarrier 能處理更為復雜的業務場景,比如如果 計算發生錯誤,可以重置計數器,并讓線程們重新執行一次。

4、CyclicBarrier 還提供其他有用的方法,比如 getNumberWaiting 方法可以獲 得 CyclicBarrier 阻塞的線程數量。isBroken 方法用來知道阻塞的線程是否被中斷。 如果被中斷返回 true,否則返回 false。

13、synchronized 的作用?

在 Java 中,synchronized 關鍵字是用來控制線程同步的,就是在多線程的環境 下,控制 synchronized 代碼段不被多個線程同時執行。 synchronized 既可以加在一段代碼上,也可以加在方法上。

14、volatile 關鍵字的作用

對于可見性,Java 提供了 volatile 關鍵字來保證可見性。

當一個共享變量被 volatile 修飾時,它會保證修改的值會立即被更新到主存,當 有其他線程需要讀取時,它會去內存中讀取新值。

從實踐角度而言,volatile 的一個重要作用就是和 CAS 結合,保證了原子性,詳 細的可以參見 java.util.concurrent.atomic 包下的類,比如 AtomicInteger。

15、什么是 CAS

CAS 是 compare and swap 的縮寫,即我們所說的比較交換。

cas 是一種基于鎖的操作,而且是樂觀鎖。在 java 中鎖分為樂觀鎖和悲觀鎖。悲 觀鎖是將資源鎖住,等一個之前獲得鎖的線程釋放鎖之后,下一個線程才可以訪問。而樂觀鎖采取了一種寬泛的態度,通過某種方式不加鎖來處理資源,比如通 過給記錄加 version 來獲取數據,性能較悲觀鎖有很大的提高。

CAS 操作包含三個操作數 —— 內存位置(V)、預期原值(A)和新值(B)。如 果內存地址里面的值和 A 的值是一樣的,那么就將內存里面的值更新成 B。CAS 是通過無限循環來獲取數據的,若果在第一輪循環中,a 線程獲取地址里面的值被 b 線程修改了,那么 a 線程需要自旋,到下次循環才有可能機會執行。

java.util.concurrent.atomic 包下的類大多是使用 CAS 操作來實現的 ( AtomicInteger,AtomicBoolean,AtomicLong)。

16、CAS 的問題

1、CAS 容易造成 ABA 問一個線程 a 將數值改成了 b,接著又改成了 a,此時 CAS 認為是沒有變化,其實 是已經變化過了,而這個問題的解決方案可以使用版本號標識,每操作一次 version 加 1。在 java5 中,已經提供了 AtomicStampedReference 來解決問題。

2、不能保證代碼塊的原子性 CAS 機制所保證的知識一個變量的原子性操作,而不能保證整個代碼塊的原子性。 比如需要保證 3 個變量共同進行原子性的更新,就不得不使用 synchronized 了。

3、CAS 造成 CPU 利用率增加 之前說過了 CAS 里面是一個循環判斷的過程,如果線程一直沒有獲取到狀態,cpu 資源會一直被占用。

17、什么是 Future?

在并發編程中,我們經常用到非阻塞的模型,在之前的多線程的三種實現中,不 管是繼承 thread 類還是實現 runnable 接口,都無法保證獲取到之前的執行結果。 通過實現 Callback 接口,并用 Future 可以來接收多線程的執行結果。

Future 表示一個可能還沒有完成的異步任務的結果,針對這個結果可以添加 Callback 以便在任務執行成功或失敗后作出相應的操作。

18、什么是 AQS

AQS 是 AbustactQueuedSynchronizer 的簡稱,它是一個 Java 提高的底層同步 工具類,用一個 int 類型的變量表示同步狀態,并提供了一系列的 CAS 操作來管 理這個同步狀態。

AQS 是一個用來構建鎖和同步器的框架,使用 AQS 能簡單且高效地構造出應用廣 泛的大量的同步器,比如我們提到的 ReentrantLock,Semaphore,其他的諸如 ReentrantReadWriteLock,SynchronousQueue,FutureTask 等等皆是基于AQS 的。

19、AQS 支持兩種同步方式:

1、獨占式

2、共享式

這樣方便使用者實現不同類型的同步組件,獨占式如 ReentrantLock,共享式如 Semaphore,CountDownLatch,組合式的如 ReentrantReadWriteLock。總之, AQS 為使用提供了底層支撐,如何組裝實現,使用者可以自由發揮。

20、ReadWriteLock 是什么

首先明確一下,不是說 ReentrantLock 不好,只是 ReentrantLock 某些時候有局 限。如果使用 ReentrantLock,可能本身是為了防止線程 A 在寫數據、線程 B 讀數據造成的數據不一致,但這樣,如果線程 C 在讀數據、線程 D 也在讀數據, 讀數據是不會改變數據的,沒有必要加鎖,但是還是加鎖了,降低了程序的性能。 因為這個,才誕生了讀寫鎖 ReadWriteLock。ReadWriteLock 是一個讀寫鎖接口, ReentrantReadWriteLock 是 ReadWriteLock 接口的一個具體實現,實現了讀寫的分離,讀鎖是共享的,寫鎖是獨占的,讀和讀之間不會互斥,讀和寫、寫和讀、 寫和寫之間才會互斥,提升了讀寫的性能。

21、FutureTask 是什么

這個其實前面有提到過,FutureTask 表示一個異步運算的任務。FutureTask 里面 可以傳入一個 Callable 的具體實現類,可以對這個異步運算的任務的結果進行等 待獲取、判斷是否已經完成、取消任務等操作。當然,由于 FutureTask 也是 Runnable 接口的實現類,所以 FutureTask 也可以放入線程池中。

22、synchronized 和 ReentrantLock 的區別

synchronized 是和 if、else、for、while 一樣的關鍵字,ReentrantLock 是類, 這是二者的本質區別。既然 ReentrantLock 是類,那么它就提供了比 synchronized 更多更靈活的特性,可以被繼承、可以有方法、可以有各種各樣的 類變量,ReentrantLock 比 synchronized 的擴展性體現在幾點上:

1、ReentrantLock 可以對獲取鎖的等待時間進行設置,這樣就避免了死鎖

2、ReentrantLock 可以獲取各種鎖的信息

3、ReentrantLock 可以靈活地實現多路通知

另外,二者的鎖機制其實也是不一樣的。ReentrantLock 底層調用的是 Unsafe 的 park 方法加鎖,synchronized 操作的應該是對象頭中 mark word,這點我不能確定。

23、什么是樂觀鎖和悲觀鎖

1、樂觀鎖:就像它的名字一樣,對于并發間操作產生的線程安全問題持樂觀狀態, 樂觀鎖認為競爭不總是會發生,因此它不需要持有鎖,將比較-替換這兩個動作為一個原子操作嘗試去修改內存中的變量,如果失敗則表示發生沖突,那么就應 該有相應的重試邏輯。

2、悲觀鎖:還是像它的名字一樣,對于并發間操作產生的線程安全問題持悲觀狀 態,悲觀鎖認為競爭總是會發生,因此每次對某資源進行操作時,都會持有一個 獨占的鎖,就像 synchronized,不管三七二十一,直接上了鎖就操作資源了。

24、線程 B 怎么知道線程 A 修改了變量

1、volatile 修飾變量

2、synchronized 修飾修改變量的方法

3、wait/notify

4、while 輪詢

25、synchronized、volatile、CAS 比較

1、synchronized 是悲觀鎖,屬于搶占式,會引起其他線程阻塞。

2、volatile 提供多線程共享變量可見性和禁止指令重排序優化。

3、CAS 是基于沖突檢測的樂觀鎖(非阻塞)

26、sleep 方法和 wait 方法有什么區別?

這個問題常問,sleep 方法和 wait 方法都可以用來放棄 CPU 一定的時間,不同點 在于如果線程持有某個對象的監視器,sleep 方法不會放棄這個對象的監視器, wait 方法會放棄這個對象的監視器

27、ThreadLocal 是什么?有什么用?

ThreadLocal 是一個本地線程副本變量工具類。主要用于將私有線程和該線程存 放的副本對象做一個映射,各個線程之間的變量互不干擾,在高并發場景下,可 以實現無狀態的調用,特別適用于各個線程依賴不通的變量值完成操作的場景。 簡單說 ThreadLocal 就是一種以空間換時間的做法,在每個 Thread 里面維護了 一個以開地址法實現的 ThreadLocal.ThreadLocalMap,把數據進行隔離,數據 不共享,自然就沒有線程安全方面的問題了。

28、為什么 wait()方法和 notify()/notifyAll()方法要在同步塊 中被調用

這是 JDK 強制的,wait()方法和 notify()/notifyAll()方法在調用前都必須先獲得對象的鎖

29、多線程同步有哪幾種方法?

Synchronized 關鍵字,Lock 鎖實現,分布式鎖等。

30、線程的調度策略

線程調度器選擇優先級最高的線程運行,但是如果發生以下情況,就會終止線程的運行:

1、線程體中調用了 yield 方法讓出了對 cpu 的占用權利

2、線程體中調用了 sleep 方法使線程進入睡眠狀態

3、線程由于 IO 操作受到阻塞

4、另外一個更高優先級線程出現

5、在支持時間片的系統中,該線程的時間片用完

31、ConcurrentHashMap 的并發度是什么

ConcurrentHashMap 的并發度就是 segment 的大小,默認為 16,這意味著最 多同時可以有 16 條線程操作 ConcurrentHashMap,這也是 ConcurrentHashMap 對 Hashtable 的最大優勢,任何情況下,Hashtable 能同 時有兩條線程獲取 Hashtable 中的數據嗎?

32、Linux 環境下如何查找哪個線程使用 CPU 最長

1、獲取項目的 pid,jps 或者 ps -ef | grep java,這個前面有講過

2、top -H -p pid,順序不能改變

33、Java 死鎖以及如何避免?

Java 中的死鎖是一種編程情況,其中兩個或多個線程被永久阻塞,Java 死鎖情況 出現至少兩個線程和兩個或更多資源。

Java 發生死鎖的根本原因是:在申請鎖時發生了交叉閉環申請。

34、死鎖的原因

1、是多個線程涉及到多個鎖,這些鎖存在著交叉,所以可能會導致了一個鎖依賴 的閉環。

例如:線程在獲得了鎖 A 并且沒有釋放的情況下去申請鎖 B,這時,另一個線程 已經獲得了鎖 B,在釋放鎖 B 之前又要先獲得鎖 A,因此閉環發生,陷入死鎖循環。

2、默認的鎖申請操作是阻塞的。

所以要避免死鎖,就要在一遇到多個對象鎖交叉的情況,就要仔細審查這幾個對 象的類中的所有方法,是否存在著導致鎖依賴的環路的可能性。總之是盡量避免 在一個同步方法中調用其它對象的延時方法和同步方法。

35、怎么喚醒一個阻塞的線程

如果線程是因為調用了 wait()、sleep()或者 join()方法而導致的阻塞,可以中斷線 程,并且通過拋出 InterruptedException 來喚醒它;如果線程遇到了 IO 阻塞, 無能為力,因為 IO 是操作系統實現的,Java 代碼并沒有辦法直接接觸到操作系統。

36、不可變對象對多線程有什么幫助

前面有提到過的一個問題,不可變對象保證了對象的內存可見性,對不可變對象 的讀取不需要進行額外的同步手段,提升了代碼執行效率。

37、什么是多線程的上下文切換

多線程的上下文切換是指 CPU 控制權由一個已經正在運行的線程切換到另外一個 就緒并等待獲取 CPU 執行權的線程的過程。

38、如果你提交任務時,線程池隊列已滿,這時會發生什么

這里區分一下:

1、如果使用的是無界隊列 LinkedBlockingQueue,也就是無界隊列的話,沒關 系,繼續添加任務到阻塞隊列中等待執行,因為 LinkedBlockingQueue 可以近乎 認為是一個無窮大的隊列,可以無限存放任務

2、如果使用的是有界隊列比如 ArrayBlockingQueue,任務首先會被添加到 ArrayBlockingQueue 中,ArrayBlockingQueue 滿了,會根據 maximumPoolSize 的值增加線程數量,如果增加了線程數量還是處理不過來, ArrayBlockingQueue 繼續滿,那么則會使用拒絕策略 RejectedExecutionHandler 處理滿了的任務,默認是 AbortPolicy

39、Java 中用到的線程調度算法是什么

搶占式。一個線程用完 CPU 之后,操作系統會根據線程優先級、線程饑餓情況等 數據算出一個總的優先級并分配下一個時間片給某個線程執行。

40、什么是線程調度器(Thread Scheduler)和時間分片(Time Slicing)?

線程調度器是一個操作系統服務,它負責為 Runnable 狀態的線程分配 CPU 時間。 一旦我們創建一個線程并啟動它,它的執行便依賴于線程調度器的實現。時間分 片是指將可用的 CPU 時間分配給可用的 Runnable 線程的過程。分配 CPU 時間可 以基于線程優先級或者線程等待的時間。線程調度并不受到 Java 虛擬機控制,所 以由應用程序來控制它是更好的選擇(也就是說不要讓你的程序依賴于線程的優 先級)。

41、什么是自旋

很多 synchronized 里面的代碼只是一些很簡單的代碼,執行時間非常快,此時等 待的線程都加鎖可能是一種不太值得的操作,因為線程阻塞涉及到用戶態和內核 態切換的問題。既然 synchronized 里面的代碼執行得非常快,不妨讓等待鎖的線程不要被阻塞,而是在 synchronized 的邊界做忙循環,這就是自旋。如果做了多 次忙循環發現還沒有獲得鎖,再阻塞,這樣可能是一種更好的策略。

42、Java Concurrency API 中的 Lock 接口(Lock interface) 是什么?對比同步它有什么優勢?

Lock 接口比同步方法和同步塊提供了更具擴展性的鎖操作。他們允許更靈活的結 構,可以具有完全不同的性質,并且可以支持多個相關類的條件對象。

它的優勢有:

1、可以使鎖更公平

2、可以使線程在等待鎖的時候響應中斷

3、可以讓線程嘗試獲取鎖,并在無法獲取鎖的時候立即返回或者等待一段時間

4、可以在不同的范圍,以不同的順序獲取和釋放鎖

43、單例模式的線程安全性

老生常談的問題了,首先要說的是單例模式的線程安全意味著:某個類的實例在 多線程環境下只會被創建一次出來。單例模式有很多種的寫法,我總結一下:

1、餓漢式單例模式的寫法:線程安全

2、懶漢式單例模式的寫法:非線程安全

3、雙檢鎖單例模式的寫法:線程安全

44、Semaphore 有什么作用

Semaphore 就是一個信號量,它的作用是限制某段代碼塊的并發數。Semaphor有一個構造函數,可以傳入一個 int 型整數 n,表示某段代碼最多只有 n 個線程可 以訪問,如果超出了 n,那么請等待,等到某個線程執行完畢這段代碼塊,下一個線程再進入。由此可以看出如果 Semaphore 構造函數中傳入的 int 型整數 n=1, 相當于變成了一個 synchronized 了。

45、Executors 類是什么?

Executors 為 Executor,ExecutorService,ScheduledExecutorService, ThreadFactory 和 Callable 類提供了一些工具方法。 Executors 可以用于方便的創建線程池

46、線程類的構造方法、靜態塊是被哪個線程調用的

這是一個非常刁鉆和狡猾的問題。請記住:線程類的構造方法、靜態塊是被 new 這個線程類所在的線程所調用的,而 run 方法里面的代碼才是被線程自身所調用 的。

如果說上面的說法讓你感到困惑,那么我舉個例子,假設 Thread2 中 new 了 Thread1,main 函數中 new 了 Thread2,那么:

1、Thread2 的構造方法、靜態塊是 main 線程調用的,Thread2 的 run()方法是 Thread2 自己調用的

2、Thread1 的構造方法、靜態塊是 Thread2 調用的,Thread1 的 run()方法是 Thread1 自己調用的

47、同步方法和同步塊,哪個是更好的選擇?

同步塊,這意味著同步塊之外的代碼是異步執行的,這比同步整個方法更提升代 碼的效率。請知道一條原則:同步的范圍越小越好。

48、Java 線程數過多會造成什么異常?

1、線程的生命周期開銷非常高

2、消耗過多的 CPU 資源

如果可運行的線程數量多于可用處理器的數量,那么有線程將會被閑置。大量空 閑的線程會占用許多內存,給垃圾回收器帶來壓力,而且大量的線程在競爭 CPU 資源時還將產生其他性能的開銷。

3、降低穩定性

JVM 在可創建線程的數量上存在一個限制,這個限制值將隨著平臺的不同而不同, 并且承受著多個因素制約,包括 JVM 的啟動參數、Thread 構造函數中請求棧的 大小,以及底層操作系統對線程的限制等。如果破壞了這些限制,那么可能拋出 OutOfMemoryError 異常

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • 一、線程狀態轉換新建(New)可運行(Runnable)阻塞(Blocking)無限期等待(Waiting)限期等...
    達微閱讀 592評論 1 2
  • Java并發編程 來自Java并發編程的藝術個人博客: http://blog.csdn.net/qq_22329...
    越長越圓閱讀 3,247評論 4 54
  • 相關概念 面向對象的三個特征 封裝,繼承,多態.這個應該是人人皆知.有時候也會加上抽象. 多態的好處 允許不同類對...
    東經315度閱讀 1,966評論 0 8
  • 臭丫頭最近瘋狂的著迷數學,而且今早主動玩,給我出來一道1+2+3+.......31=?我的老天。我說這...
    靜雨逸橋閱讀 367評論 0 4
  • 前一陣和老師在群里布置了個作業,讓大家寫寫對哪篇分享印象最深。一直記在心里想寫點東西,各種各樣的原因遲遲沒動。 今...
    jewelliu閱讀 199評論 0 0