通過了解JavaScript來更好的編寫代碼與程序

幾周前疏叨,我們開始寫旨在深入挖掘JavaScript及其工作機(jī)制的一系列文章:我們認(rèn)為大磺,通過了解JavaScript的構(gòu)造單元以及這些構(gòu)造單元如何組織在一起邓深,您就能夠編寫更好的代碼和應(yīng)用程序覆致。

該系列的第一篇文章重點(diǎn)是提供一個(gè)對(duì)引擎、運(yùn)行時(shí)和調(diào)用棧的概述蚌本。這第二篇文章將會(huì)深入Google V8 JavaScript引擎的內(nèi)部。我們還將提供如何編寫更佳 JavaScript 代碼的一些小技巧 - 這也是我們 SessionStack 開發(fā)團(tuán)隊(duì)在構(gòu)建產(chǎn)品時(shí)遵循的最佳實(shí)踐隘梨。

概述

JavaScript引擎是一個(gè)執(zhí)行JavaScript代碼的程序或解釋器程癌。JavaScript引擎可以被實(shí)現(xiàn)為標(biāo)準(zhǔn)解釋器,或者實(shí)現(xiàn)為以某種形式將JavaScript編譯為字節(jié)碼的即時(shí)編譯器轴猎。

下面是實(shí)現(xiàn)了JavaScript引擎的一個(gè)熱門項(xiàng)目列表:


V8 —?開源嵌莉,由Google開發(fā),用C++編寫的


Rhino —?由Mozilla基金所管理捻脖,開源锐峭,完全用Java開發(fā)


SpiderMonkey —第一個(gè)JavaScript引擎,最早用在Netscape Navigator上可婶,現(xiàn)在用在Firefox上沿癞。


JavaScriptCore —?開源,以Nitro銷售矛渴,由蘋果公司為Safari開發(fā)


KJS —KDE的引擎最初由Harri Porten開發(fā)椎扬,用于KDE項(xiàng)目的Konqueror瀏覽器


Chakra (JScript9) —?Internet Explorer


Chakra (JavaScript) —?Microsoft Edge


Nashorn— 開源為OpenJDK的一部分,由Oracle的Java語言和工具組開發(fā)


JerryScript —? 是用于物聯(lián)網(wǎng)的輕量級(jí)引擎


創(chuàng)建V8引擎的由來

Google構(gòu)建的V8引擎是開源的具温,用C++編寫的蚕涤。該引擎被用在Google Chrome中。不過铣猩,與其他引擎不同的是揖铜,V8還被用作很受歡迎的Node.js的運(yùn)行時(shí)。

V8最初是設(shè)計(jì)用來提升Web瀏覽器中JavaScript執(zhí)行的性能达皿。為了獲得速度蛮位,V8將JavaScript代碼轉(zhuǎn)換為更高效的機(jī)器碼较沪,而不是使用解釋器。它通過實(shí)現(xiàn)像很多現(xiàn)代JavaScript引擎(比如SpiderMonkey或Rhino)所用的JIT(即時(shí))編譯器失仁,從而將JavaScript代碼編譯成機(jī)器碼尸曼。這里主要區(qū)別在于V8不會(huì)產(chǎn)生字節(jié)碼或任何中間代碼。

V8曾經(jīng)有兩個(gè)編譯器

在V8 的5.9版(今年早些時(shí)候發(fā)布)出現(xiàn)之前萄焦,V8引擎用了兩個(gè)編譯器:


full-codegen - 一個(gè)簡(jiǎn)單而超快的編譯器控轿,可以生成簡(jiǎn)單而相對(duì)較慢的機(jī)器碼。


Crankshaft - 一個(gè)更復(fù)雜(即時(shí))的優(yōu)化的編譯器拂封,可以生成高度優(yōu)化的代碼茬射。


V8引擎還在內(nèi)部使用多個(gè)線程:


主線程執(zhí)行我們想讓它干的活:獲取代碼,編譯然后執(zhí)行它


還有一個(gè)單獨(dú)的線程用于編譯冒签,這樣在主線程繼續(xù)執(zhí)行的同時(shí)在抛,單獨(dú)的線程能同時(shí)在優(yōu)化代碼


一個(gè)Profiler線程,用于讓運(yùn)行時(shí)知道哪些方法花了大量時(shí)間萧恕,這樣Crankshaft就可以對(duì)它們進(jìn)行優(yōu)化


幾個(gè)線程用于處理垃圾收集器清掃


第一次執(zhí)行JavaScript代碼時(shí)刚梭,V8會(huì)利用full-codegen直接將解析的JavaScript翻譯為機(jī)器碼,而無需任何轉(zhuǎn)換票唆。這就讓它能非称佣粒快地開始執(zhí)行機(jī)器碼。請(qǐng)注意走趋,由于V8不會(huì)使用中間字節(jié)碼表示衅金,這樣就無需解釋器。

代碼運(yùn)行了一段時(shí)間后簿煌,Profiler線程已經(jīng)收集了足夠的數(shù)據(jù)來判斷應(yīng)該優(yōu)化哪個(gè)方法氮唯。

接下來,Crankshaft優(yōu)化從另一個(gè)線程中開始姨伟。它將JavaScript抽象語法樹翻譯為稱為Hydrogen的高級(jí)靜態(tài)單賦值(SSA)表示您觉,并嘗試優(yōu)化Hydrogen圖。大多數(shù)優(yōu)化都是在這一級(jí)完成的授滓。

內(nèi)聯(lián)

第一個(gè)優(yōu)化是提前內(nèi)聯(lián)盡可能多的代碼琳水。內(nèi)聯(lián)是用被調(diào)用的函數(shù)的函數(shù)體替換調(diào)用位置(調(diào)用函數(shù)所在的代碼行)的過程。這個(gè)簡(jiǎn)單的步驟讓以下優(yōu)化變得更有意義般堆。

隱藏類

JavaScript是一種基于原型的語言:它沒有類在孝,對(duì)象是用一種克隆過程創(chuàng)建的。JavaScript也是一種動(dòng)態(tài)編程語言淮摔,就是說在對(duì)象實(shí)例化之后私沮,可以隨意給對(duì)象添加或刪除屬性。

大多數(shù)JavaScript解釋器都使用類似字典的結(jié)構(gòu)(基于哈希函數(shù))和橙,將對(duì)象屬性值的位置存儲(chǔ)在內(nèi)存中仔燕。這種結(jié)構(gòu)使得在JavaScript中獲取屬性的值比在Java或C#這樣的非動(dòng)態(tài)編程語言中更昂貴造垛。在Java中,所有對(duì)象屬性都是由編譯前的固定對(duì)象布局確定的晰搀,并且不能在運(yùn)行時(shí)動(dòng)態(tài)添加或刪除(C#有動(dòng)態(tài)類型五辽,這是另一個(gè)話題了)。因此外恕,屬性的值(或指向這些屬性的指針)可以在內(nèi)存中存為連續(xù)緩沖區(qū)杆逗,每個(gè)緩沖區(qū)之間有固定偏移量。偏移量的長(zhǎng)度可以很容易根據(jù)屬性類型來確定鳞疲。而在JavaScript中罪郊,這是不可能的,因?yàn)閷傩灶愋涂赡軙?huì)在運(yùn)行期間發(fā)生變化尚洽。

由于用字典來查找內(nèi)存中對(duì)象屬性的位置是非常低效的悔橄,所以V8使用了不同的方法來替代:隱藏類。隱藏類的工作機(jī)制類似于像Java這樣的語言中使用的固定對(duì)象布局(類)腺毫,只不過隱藏類是在運(yùn)行時(shí)創(chuàng)建的癣疟。下面,我們來看看它們到底是什么樣子:

function Point(x, y) {
? ? this.x = x;
? ? this.y = y;
}

var p1 = new Point(1, 2);

一旦new Point(1, 2)調(diào)用發(fā)生了拴曲,V8就會(huì)創(chuàng)建一個(gè)稱為C0的隱藏類争舞。

因?yàn)檫€沒有給Point定義屬性凛忿,所以C0為空澈灼。

一旦執(zhí)行了第一條語句this.x = x(在Point函數(shù)中),V8就會(huì)創(chuàng)建一個(gè)基于C0的第二個(gè)隱藏類C1店溢。C1描述了內(nèi)存中的位置(相對(duì)于對(duì)象指針)叁熔,屬性x在這個(gè)位置可以找到。此時(shí)床牧,x存儲(chǔ)在偏移地址0處荣回,就是說闺魏,當(dāng)將內(nèi)存中的point對(duì)象作為連續(xù)緩沖器來查看時(shí)载佳,第一個(gè)偏移地址就對(duì)應(yīng)于屬性x奉呛。V8也會(huì)用“類轉(zhuǎn)換”來更新C0翅娶,指出如果將一個(gè)屬性x添加到點(diǎn)對(duì)象搔课,那么隱藏類應(yīng)該從C0切換到C1狭园。下面的point對(duì)象的隱藏類現(xiàn)在是C1概荷。

每當(dāng)向?qū)ο筇砑右粋€(gè)新屬性時(shí)攒射,舊的隱藏類就被用一個(gè)轉(zhuǎn)換路徑更新為新的隱藏類踏堡。隱藏類轉(zhuǎn)換很重要猎唁,因?yàn)樗鼈兛梢宰岆[藏類在以相同方式創(chuàng)建的對(duì)象之間共享。如果兩個(gè)對(duì)象共享一個(gè)隱藏類顷蟆,并且將相同的屬性添加到這兩個(gè)對(duì)象中诫隅,那么轉(zhuǎn)換會(huì)確保兩個(gè)對(duì)象都接收到相同的新隱藏類和它附帶的所有優(yōu)化過的代碼腐魂。

當(dāng)執(zhí)行語句this.y = y(同樣是在Point函數(shù)內(nèi)部,this.x = x語句之后)時(shí)逐纬,會(huì)重復(fù)此過程蛔屹。

這時(shí),又創(chuàng)建一個(gè)名為C2的新隱藏類风题,類轉(zhuǎn)換被添加到C1判导,表示如果將屬性y添加到Point對(duì)象(已包含屬性x),那么隱藏類應(yīng)更改為C2沛硅,同時(shí)point對(duì)象的隱藏類被更新為C2眼刃。

隱藏類轉(zhuǎn)換取決于將屬性添加到對(duì)象的順序∫〖。看下面的代碼片段:

function Point(x, y) {
? ? this.x = x;
? ? this.y = y;
}

var p1 = new Point(1, 2);
p1.a = 5;
p1.b = 6;

var p2 = new Point(3, 4);
p2.b = 7;
p2.a = 8;

現(xiàn)在擂红,你可能會(huì)認(rèn)為p1和p2會(huì)使用相同的隱藏類和轉(zhuǎn)換。嗯围小,這是錯(cuò)的昵骤。對(duì)于p1,首先是添加屬性a肯适,然后是屬性b变秦。不過,對(duì)于p2框舔,先是給b賦值蹦玫,然后才是a。因此刘绣,由于轉(zhuǎn)換路徑不同樱溉,p1和p2最終會(huì)有不同的隱藏類。在這種情況下纬凤,以相同的順序初始化動(dòng)態(tài)屬性要更好福贞,這樣隱藏類才可以被重用。

內(nèi)聯(lián)緩存

V8利用另一種稱為內(nèi)聯(lián)緩存(inline caching)的技術(shù)來優(yōu)化動(dòng)態(tài)類型語言停士。內(nèi)聯(lián)緩存來自于觀察的結(jié)果:對(duì)同一方法的重復(fù)調(diào)用往往發(fā)生在同一類型的對(duì)象上挖帘。關(guān)于內(nèi)聯(lián)緩存的深入解釋可以在這里找到。

下面我們打算談?wù)剝?nèi)聯(lián)緩存的一般概念(如果您沒有時(shí)間閱讀上面的深入解釋的話)恋技。

那么它是如何工作的呢拇舀?V8維護(hù)在最近的方法調(diào)用中作為參數(shù)傳遞的對(duì)象類型的緩存,并使用該信息對(duì)將來作為參數(shù)傳遞的對(duì)象類型做出假設(shè)猖任。如果V8能夠?qū)鬟f給方法的對(duì)象類型做出一個(gè)很好的假設(shè)你稚,那么它可以繞過算出如何訪問對(duì)象的屬性的過程,轉(zhuǎn)而使用先前查找對(duì)象的隱藏類時(shí)所存儲(chǔ)的信息。

那么隱藏類和內(nèi)聯(lián)緩存的概念是如何關(guān)聯(lián)的呢刁赖?無論何時(shí)在特定對(duì)象上調(diào)用方法搁痛,V8引擎必須對(duì)該對(duì)象的隱藏類執(zhí)行查找,以確定訪問特定屬性的偏移地址宇弛。在對(duì)同一個(gè)隱藏類的同一方法進(jìn)行了兩次成功的調(diào)用之后鸡典,V8就省掉了隱藏類查找,只將屬性的偏移地址添加到對(duì)象指針本身上枪芒。對(duì)于所有將來對(duì)該方法的調(diào)用彻况,V8引擎都會(huì)假定隱藏類沒有改變,并使用先前查找中存儲(chǔ)的偏移地址直接跳轉(zhuǎn)到特定屬性的內(nèi)存地址舅踪。這會(huì)大大提高執(zhí)行速度纽甘。

內(nèi)聯(lián)緩存也是為什么同一類型的對(duì)象共享隱藏類非常重要的原因。如果您創(chuàng)建相同類型的兩個(gè)對(duì)象抽碌,但是用的是不同的隱藏類(如前面的示例)悍赢,那么V8將無法使用內(nèi)聯(lián)緩存,因?yàn)榧词箖蓚€(gè)對(duì)象的類型相同货徙,但是它們的對(duì)應(yīng)隱藏類也會(huì)為其屬性分配不同的偏移地址左权。

兩個(gè)對(duì)象基本相同,但是“a”和“b”屬性是按照不同的順序創(chuàng)建的痴颊。

編譯到機(jī)器碼

一旦Hydrogen圖被優(yōu)化赏迟,Crankshaft將其降低到一個(gè)稱為L(zhǎng)ithium的較低級(jí)別表示。大多數(shù)Lithium實(shí)現(xiàn)都是針對(duì)架構(gòu)的蠢棱。寄存器分配發(fā)生在這一級(jí)锌杀。

最后,Lithium被編譯成機(jī)器碼裳扯。然后其他事情抛丽,也就是OSR(當(dāng)前棧替換谤职,on-stack replacement)饰豺,發(fā)生了。在我們開始編譯和優(yōu)化一個(gè)明顯要長(zhǎng)期運(yùn)行的方法之前允蜈,我們可能會(huì)運(yùn)行它冤吨。V8不會(huì)蠢到忘記它剛剛慢慢執(zhí)行的代碼,所以它不會(huì)再用優(yōu)化版本又執(zhí)行一遍饶套,而是將轉(zhuǎn)換所有已有的上下文(棧漩蟆、寄存器),以便我們可以在執(zhí)行過程中間就切換到優(yōu)化版本妓蛮。這是一個(gè)非常復(fù)雜的任務(wù)怠李,請(qǐng)記住,除了其他優(yōu)化之外,V8最開始時(shí)已經(jīng)內(nèi)聯(lián)了代碼捺癞。V8并非唯一能夠做到這一點(diǎn)的引擎夷蚊。

有一種稱為去優(yōu)化的保護(hù)措施,會(huì)作出相反的轉(zhuǎn)換髓介,并恢復(fù)為非優(yōu)化代碼惕鼓,以防引擎的假設(shè)不再成立。

垃圾回收

對(duì)于垃圾回收來說唐础,V8采用的是標(biāo)記箱歧、清掃這種傳統(tǒng)分代方式來清除舊一代。標(biāo)記階段應(yīng)該停止執(zhí)行JavaScript一膨。為了控制GC成本呀邢,并使執(zhí)行更加穩(wěn)定,V8使用增量式標(biāo)記:不是遍歷整個(gè)堆豹绪,嘗試標(biāo)記每一個(gè)可能的對(duì)象驼鹅,而是只遍歷一部分堆,然后恢復(fù)正常執(zhí)行森篷。下一個(gè)GC停止會(huì)從之前的堆遍歷停止的地方繼續(xù)输钩。這就允許在正常執(zhí)行期間有非常短的暫停。如前所述仲智,清掃階段是由單獨(dú)的線程處理买乃。

Ignition 和 TurboFan

隨著2017年早些時(shí)候版本5.9的發(fā)布,V8引入了一個(gè)新的執(zhí)行管道钓辆。這個(gè)新的管道在真實(shí)的JavaScript應(yīng)用程序中實(shí)現(xiàn)了更大的性能提升和顯著的內(nèi)存節(jié)省剪验。

這個(gè)新的執(zhí)行管道建立在V8的解釋器Ignition 和V8的最新優(yōu)化編譯器TurboFan之上。

您可以在這里查看V8團(tuán)隊(duì)關(guān)于這個(gè)主題的博文前联。

自從5.9版本發(fā)布以來功戚,V8不再用full-codeget 和 Crankshaft(自2010年以來V8所用的技術(shù))執(zhí)行JavaScript,因?yàn)閂8團(tuán)隊(duì)一直在努力跟上新的JavaScript語言特性似嗤,而這些特性需要優(yōu)化啸臀。

這意味著V8整體下一步會(huì)有更簡(jiǎn)單和更易維護(hù)的架構(gòu)。

在Web和Node.js基準(zhǔn)測(cè)試上的提升

這些提升僅僅是開始烁落。新的Ignition和TurboFan管道為進(jìn)一步優(yōu)化鋪平了道路乘粒,這將在未來幾年內(nèi)促進(jìn)JavaScript性能提升,并縮小V8在Chrome和Node.js中所占比重伤塌。

最后灯萍,這里有一些關(guān)于如何編寫良好優(yōu)化、更佳的JavaScript的訣竅每聪。當(dāng)然旦棉,從上面的內(nèi)容不難得到這些訣竅齿风,不過,為了方便起見绑洛,這里還是給出一個(gè)摘要:

如何編寫優(yōu)化的JavaScript


對(duì)象屬性的順序:始終以相同的順序?qū)嵗瘜?duì)象屬性聂宾,以便可以共享隱藏類和隨后優(yōu)化的代碼。


動(dòng)態(tài)屬性:在實(shí)例化后向?qū)ο筇砑訉傩詴?huì)強(qiáng)制修改隱藏類诊笤,減慢為之前的隱藏類優(yōu)化了的方法系谐。所以應(yīng)該在構(gòu)造函數(shù)中指定對(duì)象的所有屬性。


方法:重復(fù)執(zhí)行相同方法的代碼將比只執(zhí)行一次的代碼(由于內(nèi)聯(lián)緩存)運(yùn)行得快讨跟。


數(shù)組:避免鍵不是增量數(shù)字的稀疏數(shù)組纪他。元素不全的稀疏數(shù)組是一個(gè)哈希表,而訪問這種數(shù)組中的元素更昂貴晾匠。另外茶袒,盡量避免預(yù)分配大數(shù)組。最好隨著發(fā)展而增長(zhǎng)凉馆。最后薪寓,不要?jiǎng)h除數(shù)組中的元素。它會(huì)讓鍵變得稀疏澜共。


標(biāo)記值:V8用32位表示對(duì)象和數(shù)字向叉。它用一位來判斷是對(duì)象(flag = 1)還是整數(shù)(flag=0)(這個(gè)整數(shù)稱為SMI(SMall Integer,小整數(shù))嗦董,因?yàn)樗?1位)母谎。然后,如果一個(gè)數(shù)值大于31位京革,V8將會(huì)對(duì)數(shù)字裝箱奇唤,將其轉(zhuǎn)化為 double,并創(chuàng)建一個(gè)新對(duì)象將該數(shù)字放在里面匹摇。所以要盡可能使用31位有符號(hào)數(shù)字咬扇,從而避免昂貴的轉(zhuǎn)換為JS對(duì)象的裝箱操作。


我們?cè)赟essionStack中試圖在編寫高度優(yōu)化的JavaScript代碼中遵循這些最佳實(shí)踐廊勃。原因是一旦將SessionStack集成到產(chǎn)品web應(yīng)用程序中懈贺,它就開始記錄所有內(nèi)容:所有DOM更改、用戶交互供搀、JavaScript異常隅居、棧跟蹤钠至、失敗的網(wǎng)絡(luò)請(qǐng)求和調(diào)試消息葛虐。用SessionStack,您可以將Web應(yīng)用中的問題重放為視頻棉钧,并查看用戶發(fā)生的一切屿脐。而所有這些都是在對(duì)您的web應(yīng)用程序的性能不會(huì)產(chǎn)生影響的情況下發(fā)生的。

好了同學(xué)們,我能介紹的也都全部介紹完給你們了的诵,如果下獲得更多JAVA教學(xué)資源万栅,可以選擇來我們這里共同交流,群:24044837西疤,很多大神在這里切磋學(xué)習(xí)烦粒,不懂可以直接問,晚上還有大牛免費(fèi)直播教學(xué)代赁。

注:加群要求

1扰她、具有一定工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手芭碍,需要突破技術(shù)瓶頸的可以加徒役,有些應(yīng)屆生和實(shí)習(xí)生也可以加。

2窖壕、在公司待久了忧勿,過得很安逸,但跳槽時(shí)面試碰壁瞻讽。需要在短時(shí)間內(nèi)進(jìn)修鸳吸、跳槽拿高薪的可以加。

3速勇、如果沒有工作經(jīng)驗(yàn)层释,但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制快集,常用設(shè)計(jì)思想贡羔,常用java開發(fā)框架掌握熟練的,可以加个初。

4乖寒、覺得自己很牛B,一般需求都能搞定院溺。但是所學(xué)的知識(shí)點(diǎn)沒有系統(tǒng)化楣嘁,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。

5.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn)珍逸,分享知識(shí)逐虚,多年工作經(jīng)驗(yàn)的梳理和總結(jié),帶著大家全面谆膳、科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知叭爱!

PS:現(xiàn)在主要講解的內(nèi)容是(反射原理、枚舉原理與應(yīng)用漱病、注解原理买雾、常用設(shè)計(jì)模式把曼、正規(guī)表達(dá)式高級(jí)應(yīng)用、JAVA操作Office原理詳解漓穿、JAVA圖像處理技術(shù)嗤军,等多個(gè)知識(shí)點(diǎn)的詳解和實(shí)戰(zhàn))

6.小號(hào)或者小白之類加群一律不給過,謝謝晃危。

最后叙赚,每一位讀到這里的網(wǎng)友,感謝你們能耐心地看完僚饭。覺得對(duì)你有幫助可以給個(gè)喜歡纠俭!希望在成為一名更優(yōu)秀的Java程序員的道路上,我們可以一起學(xué)習(xí)浪慌、一起進(jìn)步


資源

https://docs.google.com/document/u/1/d/1hOaE7vbwdLLXWj3C8hTnnkpE0qSa2P--dtDvwXXEeD0/pub

https://github.com/thlorenz/v8-perf

http://code.google.com/p/v8/wiki/UsingGit

http://mrale.ph/v8/resources.html

https://www.youtube.com/watch?v=UJPdhx5zTaw

https://www.youtube.com/watch?v=hWhMKalEicY

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冤荆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子权纤,更是在濱河造成了極大的恐慌钓简,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汹想,死亡現(xiàn)場(chǎng)離奇詭異外邓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)古掏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門损话,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人槽唾,你說我怎么就攤上這事丧枪。” “怎么了庞萍?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵拧烦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我钝计,道長(zhǎng)恋博,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任私恬,我火速辦了婚禮债沮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘本鸣。我一直安慰自己疫衩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布永高。 她就那樣靜靜地躺著隧土,像睡著了一般提针。 火紅的嫁衣襯著肌膚如雪命爬。 梳的紋絲不亂的頭發(fā)上曹傀,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音饲宛,去河邊找鬼皆愉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艇抠,可吹牛的內(nèi)容都是我干的幕庐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼家淤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼异剥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起絮重,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤冤寿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后青伤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體督怜,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年狠角,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了号杠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰歌,死狀恐怖姨蟋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情立帖,我是刑警寧澤芬探,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站厘惦,受9級(jí)特大地震影響偷仿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宵蕉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一酝静、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羡玛,春花似錦别智、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳窟。三九已至,卻和暖如春敞恋,著一層夾襖步出監(jiān)牢的瞬間丽啡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工硬猫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留补箍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓啸蜜,卻偏偏與公主長(zhǎng)得像坑雅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衬横,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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

  • JavaScript絕對(duì)是最火的編程語言之一裹粤,一直具有很大的用戶群,隨著在服務(wù)端的使用(NodeJs)蜂林,更是爆發(fā)了...
    不去解釋閱讀 2,416評(píng)論 1 16
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,162評(píng)論 25 707
  • 2月份遥诉,2月份 2.29交論文初稿,老娘到現(xiàn)在還沒憋出幾個(gè)字呢悉尾,頭好大突那。 前段日子安慰自己在過年中,現(xiàn)在終于過完年...
    王白白閱讀 417評(píng)論 0 0
  • 就像是吃黃連一樣的感覺构眯,苦苦的 就是半夜睡覺醒來愕难,突然發(fā)現(xiàn),旁邊沒有了溫度 懷念兩個(gè)人的點(diǎn)滴惫霸,都是澀澀的 好想回去...
    奕奕閱讀 207評(píng)論 0 1