《java in action》2的一些記錄

java迭代的趨勢(shì)

更好的并發(fā)

流的引入,lambda,一切都是在為了適應(yīng)現(xiàn)在的硬件架構(gòu): 多核,分布式網(wǎng)絡(luò)架構(gòu)。即期望給用戶(hù)提供“輕松”,“安全”的并發(fā)編程接口。 流處理,幾乎免費(fèi)的并行,用戶(hù)在高層次寫(xiě)邏輯代碼,具體的執(zhí)行由底層的lib來(lái)選擇最合適的執(zhí)行方式,比如把計(jì)算分布到不同的cpu核上。吸取函數(shù)式語(yǔ)言里高階函數(shù),增加了lambda表達(dá)式和函數(shù)Function,增強(qiáng)了java語(yǔ)言的抽象能力,表達(dá)能力,“把行為作為參數(shù)傳遞給函數(shù)”,即高階函數(shù)的能力,又稱(chēng)為“行為參數(shù)化“(與此對(duì)應(yīng)的還有”類(lèi)型參數(shù)化“,即泛型),自此函數(shù)也成為了java語(yǔ)言的一等公民,但是還有方法和類(lèi)仍然是二等公民,不過(guò)提供了一些設(shè)施,將二等公民轉(zhuǎn)化為一等公民。
基于Stream的并發(fā),很少使用synchronized關(guān)鍵字,因?yàn)槭遣煌闹笇?dǎo)思想,stream的并發(fā)關(guān)注數(shù)據(jù)分塊 而不是 協(xié)調(diào)訪問(wèn) , 這樣就像函數(shù)式編程在靠齊,“無(wú)共享可變數(shù)據(jù)” + “高階函數(shù)” ,不使用synchronized,來(lái)協(xié)調(diào)共享數(shù)據(jù)的訪問(wèn)(互斥與并發(fā)),而是將數(shù)據(jù)拆分,不共享。

image.png

流的與集合的一個(gè)差異是: 流用于表達(dá)計(jì)算,集合的元素是計(jì)算完之后添加進(jìn)來(lái)或者刪除的,但是流是在固定的數(shù)據(jù)結(jié)構(gòu)上,不能直接刪除和增加,按需計(jì)算,定義流的時(shí)候計(jì)算并不發(fā)生,且只能遍歷一次生成新的流(Java里是這樣,scala里面的流可以多次使用)。
使用流的好處,是能寫(xiě)出具有如下特點(diǎn)的代碼:

  • 聲明式:
  • 可復(fù)合:
    • 抽象度高
  • 免費(fèi)并行:

流的定義是: 從支持?jǐn)?shù)據(jù)處理的源生成特定的元素序列。定義決定設(shè)計(jì)


image.png

如果自己設(shè)計(jì)一條流,也應(yīng)該按照這樣的思路來(lái)。

所以,流的使用一般就是三件事:

  • 定義數(shù)據(jù)源
  • 定義中間操作鏈 形成一條流水線
  • 終端操作 執(zhí)行流水線(按需計(jì)算)生成結(jié)果

無(wú)狀態(tài)流有狀態(tài)流的區(qū)別
有:流內(nèi)部的算子有用戶(hù)提供的lambda, 或者 方法引用(方法不是純函數(shù))
無(wú):沒(méi)有內(nèi)部狀態(tài),沒(méi)有用戶(hù)提供的lambda或者方法引用,沒(méi)有內(nèi)部可變狀態(tài)。
無(wú)狀態(tài)流對(duì)并行友好,無(wú)縫切換到parallel,而有狀態(tài)的流不行,比如求和,如果用外部變量進(jìn)行累加,則parallel很容易出錯(cuò),但是如果是利用reduce的分開(kāi)累加,最終將每個(gè)累加結(jié)果再累加,就不會(huì)有并發(fā)問(wèn)題。

數(shù)值流存在的原因不是流的復(fù)雜性,而是 基本類(lèi)型和對(duì)應(yīng)的對(duì)象類(lèi)型 之間的裝箱和拆箱性能。

流的生成: 萬(wàn)物皆可流

萬(wàn)物都可以作為流的元素,也可以作為流的源頭生成流元素。

  • 數(shù)值
  • 集合
  • 文件
  • 空對(duì)象
  • 函數(shù) (比如無(wú)限流,Stream.iterate(0, n -> n + 2)偶數(shù)的無(wú)限流, Stream.iterate(new int[]{0,1}, t-> new int[]{t[1], t[0] + t[1]}) 斐波那契流, Stream.generate(Math::random) 隨機(jī)流

流收集:最終計(jì)算: 歸約

流水線是lazy的數(shù)據(jù)集的計(jì)算迭代器,最終的計(jì)算由 terminal action出發(fā),通用的操作即collect,collect接受一個(gè)參數(shù)Collector來(lái)表示最終的流元素去往何處。
Collectors工具類(lèi)提供了許多直接的預(yù)定義的歸約器,也提供了一些高階方法生成歸約器,而這一切都離不開(kāi)背后的基本歸約方法:java.util.stream.Collectors#reducing(U, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>)
U 歸約的初始元素
Function是將流內(nèi)元素轉(zhuǎn)化為待歸約的元素
BinaryOperator是待歸約元素的計(jì)算

歸約計(jì)算的一個(gè)目的,收集,也可由歸約完成。這就涉及到范疇論的理論來(lái),以數(shù)組的收集舉例:

reducing(new List<>(),
                    (l, e) -> { l.add(e); return l;}, 
                  (l1, l2) -> { List l = new List(); 
                                    l.addAll(l1);
                                    l.addAll(l2); 
                                    return l;} }

并且上面的歸約屬于“無(wú)狀態(tài)”,可以輕松的用來(lái)做 并行。
reducing這個(gè)方法之所以能夠作為基本方法是它提供了兩個(gè)基本能力:

  1. 元素到范疇的映射
  2. 范疇到范疇的映射

代碼實(shí)際實(shí)現(xiàn)是Collector類(lèi),另外Stream提供了一個(gè)collect方法,接受三個(gè)參數(shù)- supplier, accumulator 和 combiner,來(lái)自定義收集,其語(yǔ)義和Collector接口相應(yīng)方法返回的函數(shù)完全相同。

分組: Collector的連接 : groupingBy( , [ toList toSet]), collectAndThen,

復(fù)雜的歸約,可以通過(guò)groupingBy以及partitioningBy完成,并且他們之間可以通過(guò)多個(gè)Collector的連接完成
如:

Map<Type, List<String>>  = 
   collect(groupingBy(Dish::getType,
                              mapping(Dish:getName, toList())));

或者多級(jí)分組

Map<Type, Map<CaloricLevel, List<Dish>>>  = 
.collect( groupingBy(Dish::getType,
                  groupingBy( dish -> {
                              if (dish.getCateGory <= 400 ) return CaloricLevel.DIET;
                              ......
                              })
                              ));

或者分組統(tǒng)計(jì)

Map<Dish.Type, Long>  = .collect( groupintBy(Dish::getType, counting() ));

或者分組統(tǒng)計(jì)后計(jì)算

Map<Dish.Type, Optional<Dish>> = .collect(groupingBy(Dish::getType, maxBy(comparingInt(Dish::getCalories))));

groupingBy(Dish::getType, collectAndThen( maxBy(comparingInt(Dish::getCalories)), Optional::get));

分區(qū) partitioningBy

將流的元素,利用一個(gè)謂詞做分類(lèi)。分區(qū)可以理解為產(chǎn)生了兩個(gè)流,并且由 partitioningBy實(shí)現(xiàn)的Map實(shí)現(xiàn)(特殊map)更高效,緊湊,因?yàn)橹话瑑蓚€(gè)鍵: true 和 false

分區(qū)和分組一樣,可以多級(jí)分區(qū),只要 連接 partitioningBy 就可以

收集器性能對(duì)比

實(shí)現(xiàn)自定義的Collector的目的是為了獲得 比 ’使用內(nèi)置工廠方法創(chuàng)建的收集器‘ 更好的性能,但是也可能讓性能更拉垮,只能說(shuō):提供了設(shè)置,讓有能力的同學(xué)可以自由發(fā)揮。
JMH框架來(lái)測(cè)試。

并行

在Java8之前的并行流,需要主動(dòng)的拆分?jǐn)?shù)據(jù),分配給不同的線程,然后還要進(jìn)行協(xié)調(diào)和同步以避免可能發(fā)生的競(jìng)爭(zhēng)條件,等到每個(gè)線程都完成后,再合并結(jié)果。并且java7引入了一個(gè) “分支/合并”的框架,可以更穩(wěn)定,更不容易出錯(cuò)的完成這一件事。
不過(guò),相對(duì)于java8的并行流還是落后了些,Java8的Stream接口讓用戶(hù)免費(fèi)使用并行,一個(gè)指令就可以將順序流轉(zhuǎn)化為并行流(當(dāng)然,前提是你的數(shù)據(jù)能夠接受并行處理),控制數(shù)據(jù)切分的過(guò)程主要是: Spliterator (splitable , iterator)

someStream.parallel() 方法并不會(huì)改變實(shí)際的流,而是設(shè)置了一個(gè)flag,表示 parallel之后的所有操作都是可以并行執(zhí)行的,指需要再調(diào)用 sequential 就可以再變回順序流。

并行流內(nèi)部使用的還是:ForJoinPool,默認(rèn)的個(gè)數(shù)等于cpu的個(gè)數(shù)。

java.util.concurrent.ForkJoinPool. common.parallelism 來(lái)修改線程池大小, 缺點(diǎn)是jvm級(jí)別的,會(huì)修改所有并行流的線程池大小,所以一般不修改,如下所示:
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism","12");

并行流的思想是:數(shù)據(jù)分塊,任務(wù)分塊,然后利用Fork/Joinpool, 實(shí)現(xiàn)任務(wù)的計(jì)算。
任務(wù)的分塊由Spliterator實(shí)現(xiàn)。

Fork/Join Pool框架

思想分治,將任務(wù)拆分,最后合并。

  • 可拆分的任務(wù)抽象ForkJoinTask<T> <= RecursiveTask<T>, 或者 ForkJoinTask<Void> <= RecursiveAction
    • 任務(wù)執(zhí)行: compute, 任務(wù)在compute內(nèi)部再次拆分,不能拆的計(jì)算然后返回結(jié)果,將之前的拆分都合并。
  • 執(zhí)行任務(wù)的框架: work stealing。由于任務(wù)拆分的子任務(wù)的計(jì)算負(fù)載不均衡,導(dǎo)致雖然每個(gè)線程的隊(duì)列都只有兩個(gè)任務(wù),但是其中一個(gè)隊(duì)列的任務(wù)特別簡(jiǎn)單,瞬間完成,而另一個(gè)隊(duì)列的任務(wù)可能特別耗時(shí),第二個(gè)任務(wù)就在等待第一個(gè)完成,不能并發(fā)。steal能夠讓空閑/或者負(fù)載低的線程偷取忙碌線程的雙端隊(duì)列的task來(lái)幫助執(zhí)行,這也是為什么 任務(wù) 要分細(xì)的原因。

流的拆分: Spliterator

參考:

interface Spliterator<T> {
  boolean tryAdvance(COnsumer< ? super T> action);

Spliterator<T> trySplit();

long estimateSize(); // 不是很準(zhǔn)確

int characteristics();

}

trySplit會(huì)遞歸調(diào)用,調(diào)用的時(shí)候,它會(huì)劃分一些元素給它返回的第二個(gè)Spliterator,讓他們兩個(gè)并行處理。

遞歸的拆分,拆分的過(guò)程會(huì)影響整個(gè)的執(zhí)行效率,在自定義Spliterator的時(shí)候,注意效率,采用物理分割,比如將數(shù)據(jù)復(fù)制一份,顯然沒(méi)有邏輯分割保存原數(shù)據(jù)引用,修改數(shù)據(jù)范圍來(lái)的效率高。另外,拆分的過(guò)程收到了 “特性”影響(characteristics方法聲明)


image.png

如果當(dāng)前的Spliterator實(shí)例X是可分割的,trySplit()方法會(huì)分割X產(chǎn)生一個(gè)全新的Spliterator實(shí)例Y,原來(lái)的X所包含的元素(范圍)也會(huì)收縮,類(lèi)似于X = [a,b,c,d] => X = [a,b], Y = [c,d];如果當(dāng)前的Spliterator實(shí)例X是不可分割的,此方法會(huì)返回NULL),具體的分割算法由實(shí)現(xiàn)類(lèi)決定

todo: 對(duì)于無(wú)限流的并發(fā),是怎么split的?

集合與lambda帶來(lái)的高效編程和改變

集合工廠的增強(qiáng),對(duì)于List,Set,map等,SomeCollection.of() 方法會(huì)生成 小規(guī)模的高性能的不可變集合類(lèi),即集合常量 ,雖然生成的數(shù)據(jù)結(jié)構(gòu)不可變,但是效率更高,就類(lèi)似于: Arrays.asList() 方法一樣,生成的是視圖。
另外,對(duì)于大家常用集合類(lèi)時(shí)候,用到的一些常用操作,都增加了相應(yīng)語(yǔ)義的方法:

  • removeIf: list 和set提供,可以刪除滿(mǎn)足條件的元素,而不會(huì)觸發(fā)ConcurrentModificationException,不然就要顯式的使用迭代器和迭代器的刪除方法;


    image.png

    正確的代碼如下


    image.png
  • replaceAll: 替換集合的元素,而不用新生成集合。

  • remove: 刪除map里面指定的 key和value 對(duì)

  • merge: 把兩個(gè)map對(duì)元素進(jìn)行合并的邏輯

  • computeIfXXXX,compute:高效的計(jì)算和填充

ConcurrentHashMap

  • set視圖:一個(gè)可以時(shí)刻同步map的set視圖,xxx.keySet()方法,隨時(shí)在set里看到map的變化。
  • 基礎(chǔ)類(lèi)型的歸約:使用對(duì)應(yīng)的基礎(chǔ)類(lèi)型方法會(huì)更快,少去了裝箱拆箱的步驟 : reduceValuesToInt、reduce-KeysToLong

lambda重構(gòu)設(shè)計(jì)模式

新的語(yǔ)言特性常常讓現(xiàn)存的編程模式或設(shè)計(jì)黯然失色,對(duì)設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)陳稱(chēng)為“設(shè)計(jì)模式”。
lambda之所以可以重構(gòu)設(shè)計(jì)模式,是因?yàn)椋簩⑿袨閰?shù)化,傳遞給高階函數(shù)。而策略模式,模板模式的核心就是封裝了不同的行為; 觀察者模式,是在發(fā)生一些事件之后,觸發(fā)一些行為的執(zhí)行;責(zé)任鏈模式本質(zhì)是對(duì)數(shù)據(jù)多次的操作,完全可以用函數(shù)式編程的組合模式完成;工廠模式,也只是某種特定的函數(shù)罷了:Function<someParameter, SomeClassInstance>;

基于lambda的DSL todo

精讀此章節(jié)內(nèi)容后,最好搭配:
英文版本的: Domain-Specific Languages Martin的書(shū),中文翻譯賊拉垮
DSLs in Action,有引進(jìn)的話,先看中文看看
還有 antlr4的兩本,因?yàn)?martin的書(shū)是設(shè)計(jì)思想,指導(dǎo)原則,用的工具還是 antlr4 做解析。

Optional,時(shí)間 : 非常簡(jiǎn)單,略

默認(rèn)方法和模塊系統(tǒng)

默認(rèn)方法

模塊系統(tǒng)

模塊系統(tǒng)比較復(fù)雜: 搭配:Nicolai Parlog《 The Java Module System 》

設(shè)計(jì)的高層次(軟件架構(gòu)層次)設(shè)計(jì)模式:
關(guān)注點(diǎn)分離(separation of concern,SoC)和信息隱藏(information hiding)

  • 關(guān)注點(diǎn)分離 推崇的是將:?jiǎn)误w的計(jì)算機(jī)程序分解為一個(gè)個(gè)相互獨(dú)立的特性

采用關(guān)注點(diǎn)分離,可以將軟件的功能,作用等劃分到名為“模塊“的獨(dú)立組成部分中去,所以,模塊是具有“內(nèi)聚”特質(zhì)的一組代碼,它與其他模塊的代碼很少耦合;通過(guò)模塊組織類(lèi),可以清晰地描繪出應(yīng)用程序類(lèi)與類(lèi)之間的可見(jiàn)性關(guān)系。
Java的包機(jī)制并為從本質(zhì)上支持模塊化,它的粒度太粗。而模塊化的粒度更細(xì),且控制檢查是編譯期的。帶來(lái)的好處就是:可以使得各項(xiàng)工作獨(dú)立開(kāi)展,減少組件之間的依賴(lài),便于團(tuán)隊(duì)合作,有利于推動(dòng)組建重用,系統(tǒng)整體的維護(hù)性更好。

  • 信息隱藏: 隱藏信息能夠減少局部變更對(duì)其他部分程序的影響,從而避免“變更傳遞”。

在低層次(代碼層次) 的表現(xiàn)就是封裝。雖然我們具有private,protected,public 關(guān)鍵字,但是就語(yǔ)言層面而言,Java 9 出現(xiàn)之前, 編譯器無(wú)法依據(jù)語(yǔ)言結(jié)構(gòu)判斷某個(gè)類(lèi)或者包僅供某個(gè)特定目標(biāo)訪問(wèn)。

Java9之前的Java內(nèi)置模塊化的問(wèn)題:

  1. 有限的可見(jiàn)性控制:三個(gè)描述符只能控制包級(jí)別的類(lèi)訪問(wèn),無(wú)法描述 包之間的訪問(wèn)。比如:“希望一個(gè)包中的某個(gè)類(lèi)或接口可以被另外一個(gè)包中的類(lèi)或接口訪問(wèn),那么只能將它聲明為 public。這樣一來(lái),任何人都可以訪問(wèn)這些類(lèi)和接口了”。這樣就可能讓代碼被隨意使用,給開(kāi)發(fā)者演進(jìn)自己的代碼帶來(lái)困難。
  2. 類(lèi)路徑的問(wèn)題:Java編譯器把所有的類(lèi)都打入一個(gè)扁平的jar包中,并且把jar包放到class path上,jvm可以動(dòng)態(tài)一句類(lèi)的路徑從中定位并且加載相關(guān)的類(lèi)。然后,這樣存在了幾個(gè)嚴(yán)重的問(wèn)題:
  • 無(wú)法通過(guò)路徑指定版本。比如如果類(lèi)路徑上存在同一個(gè)庫(kù)的兩個(gè)版本,會(huì)發(fā)生什么。而大型項(xiàng)目中很常見(jiàn),它的不同組件使用同一個(gè)庫(kù)的不同版本:解決方法有
    1. 使用自定義ClassLoader來(lái)隔離: http://www.blogjava.net/landon/category/54860.html(值得注意的兩點(diǎn)是:公有接口可以由系統(tǒng)類(lèi)加載器加載,舊的類(lèi)的實(shí)例和class很難被卸載)。比如: elasticsearch中的插件加載機(jī)制,實(shí)現(xiàn)了自定義的classLoader 。 甚至可以用ClassLoader來(lái)實(shí)現(xiàn)熱部署:https://cloud.tencent.com/developer/article/1915650
    2. 或者是OSGI
    3. sofa-ark是動(dòng)態(tài)熱部署和類(lèi)隔離框架,支付寶開(kāi)源
  • 類(lèi)路徑不支持顯式的依賴(lài):


    image.png

Java9提供了一個(gè)新的單位: 模塊。通過(guò) module聲明,緊接著的是模塊的名字和主體的內(nèi)容,定義在特殊的文件:module-info.class, 下圖可知,module的層級(jí)是高于package的。

image.png

image.png

使用命令可以指導(dǎo)哪些目錄和類(lèi)文件會(huì)被打包進(jìn)入生成的JAR文件中:
javac module-info.java xxx/yyyy/zzz.java -d target
jar cvfe xxxxx.jar xxx.yyy.zzz -C target
然后運(yùn)行執(zhí)行命令:
java --module-path xxxxx.jar --module moduleName.xxx.yyy.zzz

image.png

并發(fā)性

無(wú)論是基于 Future 的異步 API 還是反應(yīng)式異步 API,被調(diào)方法的概念體(conceptual body) 都在另一個(gè)線程中執(zhí)行,調(diào)用方很可能已經(jīng)退出了執(zhí)行,不在調(diào)用異常處理器的作用域內(nèi)。很明顯,這種非常規(guī)行為觸發(fā)的異常需要通過(guò)其他的動(dòng)作來(lái)處理。

CompletableFuture

和Scala的Future很類(lèi)似

反應(yīng)式編程

直接看《反應(yīng)式設(shè)計(jì)模式》就好了

函數(shù)式

個(gè)人了解較多,忽略。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評(píng)論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,980評(píng)論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 64,064評(píng)論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,779評(píng)論 6 414
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,109評(píng)論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,287評(píng)論 0 291
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評(píng)論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,515評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,750評(píng)論 1 375
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,933評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,327評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,667評(píng)論 1 296
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,492評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,703評(píng)論 2 380