Node.js文檔

# 模塊機制

node采用模塊化結構,按照CommonJS規范定義和使用模塊,模塊與文件是一一對應關系,即加載一個模塊,實際上就是加載對應的一個模塊文件

node 的基礎中毫無疑問的應該是有關于模塊機制的方面的,也即require這個內置功能的一些原理,關于模塊互相引用的推薦先好好讀讀官方文檔,在

這里就不給大家詳細解釋了

# 熱更新

從面試官的角度看, 熱更新 是很多程序常見的問題,對客戶端而言,熱更新意味著不用換包,當然也包含著md5校驗/差異更新等。復雜問題:

對服務端而言,熱更新意味著服務不用重啟,這樣可用性較高。

在node中做熱更新代碼,牽扯到的知識點可能主要是require會有一個cache,有這個cache在,即使你更新了 .js文件,在

代碼中再次require還是會拿到之前的編譯好緩存在v8內存(code space)中的舊代碼,但是如果只是淡出的清除掉require中的cache,再次

require確實能拿到新的代碼,但是這時候很容易碰到各地維持舊的引用依舊跑的舊的代碼的問題。

不過熱更新json之類的配置文件的話,還是可以簡單的實現,更新require的cache就行,不會

有持有舊引用的問題,但是舊的引用一直被持有很容易出現內從泄露,而要熱更新配置的話,為什么不存數據庫?或者使用zookeeper之類

的服務?通過更新文件還要在發布一次,但是存數據庫直接寫個接口配個頁面多爽

# 上下文

對于node.js而言,正常情況下只有一個上下文,甚至于內置的很多方面例如 require的實現只是在啟動的時候運行了內置的函數

每個單獨的.js文件并不意味著單獨的上下文,在某個.js文件中污染了全局的作用域一樣能影響到其它的地方

而目前的node.js將VM的接口暴露了出來,可以讓你自己創建一個新的js上下文,這一點上跟前端還是區別挺大的,在執行外部代碼的

時候,通過創建新的上下文沙盒(sandbox)可以避免上下文被污染

'use strict';

const vm = require('vm');

let code =

`(function(require) {

const http = require('http');

http.createServer( (request, response) => {

response.writeHead(200, {'Content-Type': 'text/plain'});

response.end('Hello World\\n');

}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

})`;

vm.runInThisContext(code)(require);

問題:既然可以通過新的上下文來避免污染,那么為什么 node.js不給每一個.js文件以獨立的上下文來避免作用域被污染

問題其實有點下套,其實Node有給每個js文件獨立的上下文,但是這避免不了全局的作用域污染,實際上這是為了功能的妥協。

Node.js 模塊正常情況對作用域不會造成污染,意外創建全局變量是一種例外,可以采用嚴格模式來避免

# 包管理

------------------------------------------------------

1. a.js和b.js兩個文件互相require是否會死循環?雙方是否能導出變量?如何從設計上避免這種問題?

答:不會,先執行的導出空對象,通過導出工廠函數讓對方從函數去拿比較好避免。

模塊在導出的只是 var module = { exports: {}};中的exports,以從a.js啟動為例,a.js還沒執行完exports就是{} 在b.js的開頭拿到的就是 {} 而已。

另外還有非常基礎和常見的問題,比如:module.exports和exports的區別這里也能一并解決了,exports只是module.exports的一個引用

2. 如果a.js require了b.js,那么在b中定義的全局變量t=11能否在a中直接打印出來?

答:每個.js能獨立一個環境只是因為node幫你在外層包了一圈自執行,所以你使用 t=11 定義全局變量在其它地方當然能拿到,情況如下:

//b.js

(function (exports,require,module,__filename,__dirname){

t=11;

})();

//a.js

(function (exports,require,nodule,__filename,__dirname){

console.log(t);//11

})();

3. 如何在不重啟node進程的情況下熱更新一個js/json文件?這個問題本身是否有問題?

答:可以清除掉require的緩存? 重新require(),視具體情況還可以用VM模塊重新執行。當然這個問題可能是典型的X-Y Problem,使用js實現熱更新很容易碰到v8優化之后各地拿到緩存的引用導致熱更新js沒意義,當然熱更新json還是可以簡單一點比如用讀取文件的方式來熱更新,但是這樣也不如從redis之類的數據庫中讀取比較合理

4. 比較 AMD, CMD, CommonJS 三者的區別?

AMD,CMD,CommonJS是目前最常用的三種模塊化書寫規范。

commonjs是用在服務器端的,同步的,如nodejs

amd, cmd是用在瀏覽器端的,異步的,如requirejs和seajs

其中,amd先提出,cmd是根據commonjs和amd基礎上提出的。

根據CommonJS規范,一個單獨的文件就是一個模塊。加載模塊使用require方法,該方法讀取一個文件并執行,最后返回文件內部的exports對象。 CommonJS 加載模塊是同步的,所以只有加載完成才能執行后面的操作。像Node.js主要用于服務器的編程,加載的模塊文件一般都已經存在本地硬盤,所以加載起來比較快,不用考慮異步加載的方式,所以CommonJS規范比較適用。但如果是瀏覽器環境,要從服務器加載模塊,這是就必須采用異步模式。所以就有了 AMD? CMD 解決方案。

AMD 是 RequireJS 在推廣過程中對模塊定義的規范化產出

AMD異步加載模塊。它的模塊支持對象 函數 構造器 字符串 JSON等各種類型的模塊。

適用AMD規范適用define方法定義模塊。

CMD是SeaJS 在推廣過程中對模塊定義的規范化產出

CMD和AMD的區別有以下幾點:

1.對于依賴的模塊AMD是提前執行,CMD是延遲執行。不過RequireJS從2.0開始,也改成可以延遲執行(根據寫法不同,處理方式不通過)。

2.CMD推崇依賴就近,AMD推崇依賴前置。

3.AMD的api默認是一個當多個用,CMD嚴格的區分推崇職責單一。例如:AMD里require分全局的和局部的。CMD里面沒有全局的 require,提供 seajs.use()來實現模塊系統的加載啟動。CMD里每個API都簡單純粹。

5. 關于 node 中 require 的實現原理等

答:require原生入口代碼里面調用了__load方法用于加載文件,繼續看__load方法原生代碼里面調用了_resolveFilename方法,顧名思義,這應該是一個解析需要require的文件名的方法,繼續看_resolveFilename方法中又調用了_findPath方法。

可以看到,這里完整的顯示了node是如何根據require傳入的名稱來定位具體的文件的,他們的順序依次是:

1、先從緩存中讀取,如果沒有則繼續往下

2、判斷需要模塊路徑是否以/結尾,如果不是,則要判斷

a. 檢查是否是一個文件,如果是,則轉換為真實路徑

b. 否則如果是一個目錄,則調用tryPackage方法讀取該目錄下的package.json文件,把里面的main屬性設置為filename

c. 如果沒有讀到路徑上的文件,則通過tryExtensions嘗試在該路徑后依次加上.js,.json和.node后綴,判斷是否存在,若存在則返回加上后綴后的路徑

3、如果依然不存在,則同樣調用tryPackage方法讀取該目錄下的package.json文件,把里面的main屬性設置為filename

4、如果依然不存在,則嘗試在該路徑后依次加上index.js,index.json和index.node,判斷是否存在,若存在則返回拼接后的路徑。

5、若解析成功,則把解析得到的文件名cache起來,下次require就不用再次解析了,否則若解析失敗,則返回false

------------------------

# Promise

Promise是異步編程的一種解決方案,比傳統的解決方案--回調函數和事件--更合理和更前大

所謂Promise,簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果,從語法上說,Promise是一個對象,從他可以獲取異步操作的消息,Promise提供統一的API,各種異步操作都可以用同樣的方法進行處理

有了Promise對象,就可以將異步操作以同步操作的方式表達出來,避免層層嵌套的回調函數

Promise對象的兩個特點:

1.對象的狀態不受外界影響

Promise對象代表一個異步操作,有三種狀態:pending(進行中),fulfilled(已成功),rejected(已失敗),只有異步操作的結果,可以決定當前是哪一種狀態,任何其它操作都無法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其它手段無法改變

2.一旦狀態改變,就不會再變,任何時候都可以得到這個結果

resolved(已定型)

promise對象的狀態改變只有兩種可能:從pending變為fulfilled和從pending變為rejected,只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時稱為已定型

缺點:

首先,無法取消Promise,一旦新建它就會立即執行,無法中途取消。

其次,如果不設置回調函數,promise內部拋出的錯誤,不會反應到外部

當處于pending狀態時,無法得知目前進展到哪一個階段

# Events(事件)

# Timers(定時器)

# 阻塞/異步

# 并行/并發

1. Promise 中 .then的第二個參數與.catch 有什么區別?

沒什么多大的區別,全都是用來處理錯誤函數的

詳情可參考:http://es6.ruanyifeng.com/#docs/promise

2. Eventemitter的emit是同步還是異步

Node.js 中 Eventemitter 的 emit 是同步的

按監聽器的注冊順序,同步地調用每個注冊到名為 eventName 事件的監聽器,并傳入提供的參數。

如果事件有監聽器,則返回 true ,否則返回 false。

3. 如何判斷接口是否異步?是否只要有回調函數就是異步?

異步:發出指令,然后去做別的事情了,所有操作完成后再執行回調

異步I/O:異步的發出I/O請求

看文檔

console.log 打印看看

看是否有 IO 操作

單純使用回調函數并不會異步, IO 操作才可能會異步, 除此之外還有使用 setTimeout 等方式實現異步.

4. nextTick,setTimeout以及setImmediate三者的區別?

5. 如何實現一個sleep函數?

function sleep(ms) {

var start = Date.now(), expire = start + ms;

while (Date.now() < expire) ;

return;

}

6. 如何實現一個異步的reduce?(在Es5中出現的數組方法)

需要了解 reduce 的情況, 是第 n 個與 n+1 的結果異步處理完之后, 在用新的結果與第 n+2 個元素繼續依次異步下去

# 進程

## Process(進程)

## Child Processes(子進程)

## Cluster(集群)

## 進程間通信

## 守護進程

1. 進程的當前工作目錄是什么?有什么作用?

2. child_process.fork與POSIX的fork有什么區別?

cluster是常見的node利用多核的方法,它是基于child_process.fork()實現的,所以cluster產生的進程之間是通過IPC來通信的,并且它也沒有拷貝父進程的空間,而是通過加入cluster.isMaster這個標識,來區分父進程以及子進程,達到類似POSIX的fork效果

3. 父進程或子進程的死亡是否回影響對方?什么是孤兒進程?

子進程的死亡不會影響父進程,不過子進程死亡時(線程組的最后一個線程,通常是‘領頭線程死亡時’)會向他的父進程發送死亡信號。反之父進程死亡,一般情況下子進程也會隨之死亡,但如果此時子進程處于可運狀態,僵死狀態等等的話,子進程將被進程1(init進程)收養,從而成為孤兒進程。

子進程死亡的時候(處于‘終止狀態’),父進程沒有及時調用wait()或waitpid()來返回死亡進程的相關信息,此時子進程還有一個PCB殘留在進程表中,被稱為僵尸進程。

4. cluster是如何保證負載均衡的?

5. 什么是守護進程?如何實現守護進程?

守護進程,是服務端方面一個很基礎的概念。很多人只知道通過pm2之類的工具可以將進程以守護進程的方式啟動,卻不了解什么是守護進程,為什么要使用守護進程

普通的進程,在用戶退出終端之后就會直接關閉,通過&啟動到后臺的進程,之后會由于會話(session組)被回收而終止進程,守護進程是不依賴終端(tty)的進程,不會因為用戶退出終端而停止運行的進程

# IO

# Buffer

# String Decoder(字符串解碼)

# Stream (流)

# Console (控制臺)

# File System (文件系統)

# Readline

# REPL

1.Buffer一般處理什么數據?其長度能否動態變化?

Buffer是node.js中用于處理二進制數據的類,其中與IO相關的操作(網絡/文件等)均基于Buffer,Buffer類的實例非常類似整數數組

但其大小是固定不變的,并且其內存在V8堆棧外分配原始內存空間。Buffer類的實例創建之后,其所占用的內存大小不能再進行調整

2.Stream的highWaterMark與drain事件是什么?二者之間的關系是?

3.Stream的pipe的作用是?在pipe的過程中數據是引用傳遞還是拷貝傳遞?

將一個可寫流附到可讀流上,同時將可寫切換到流模式,并把所有數據推給可寫流,在pipe傳遞數據的過程中,objectMode是傳遞引用,非objectMode則是拷貝一份數據傳遞下去

4.什么是文件描述符?輸入流,輸出流,錯誤流是什么?

5.console.log是同步還是異步?如何實現一個console.log?

console.log正常情況下是異步的,除非你使用new Console(stdout[,stderr])指定了一個文件的目的地

let print = (str) =>? process.stdout.write(str + '\n')

print('hello world')

6.如何同步的獲取用戶的輸入?

node中,獲取用戶的輸入其實就是讀取node進程中的輸入流的數據

而要同步讀取,則是不用異步的read接口,而是用同步的readSync接口去讀取stdin的數據可實現

7.Readline是如何實現的?

readline模塊提供了一個用于從Readble的stream中一次讀取一行的接口,當然你也可以用于讀取文件或net,http,stream.

實現上,readline在讀取TTY的數據時,是通過input.on('keypress','onkeypress')時發現用戶按下了回車鍵來判斷是新的line的,而讀取一般的stream時,則是通過緩存數據然后用正則,test來判斷是否為new line

8.REPL

Read--Eval--Print--Loop(交互式解釋器)

repl模塊提供了一種‘讀取--求值-輸出-循環的實現’它可以作為一個獨立的程序或嵌入到其它應用中

9.Cluster模塊

node默認單線程進行,對于32位系統最高可以使用512MB內存,對于64位最高可以使用1GB內存。對于多核CPU的計算機來說,這樣做效率很低,因為只有一個核在運行,其它核都在閑置。cluster模塊就是為解決這個問題而提出的

Cluster模塊允許建立一個主進程和若干個worker進程,由主進程監控和協調worker進程的運行,worker之間采用進程間通信交換信息,cluster模塊內置一個負載均衡器,采用Round-robin算法協調各個worker進程之間的負載,運行時,所有新建立的鏈接都有主進程完成,然后主進程再把TCP連接分配給指定的worker進程

10. Events模塊

回調函數模式讓node可以處理異步操作,但是,為了適應回調函數,異步操作只能有兩個狀態:開始和結束。對于那些多狀態的異步操作,回調函數就會無法處理,你不得不將異步操作拆開,分成多個階段,每個階段結束時,調用下一個回調函數。

為了解決這個問題,node提供Event Emitter接口。通過事件,解決多狀態異步操作的響應問題

11. child_process模塊

用于新建子進程,子進程的運行結果儲存在系統緩存之中(最大200KB),等到子進程運行結束后,主進程在調用回調函數讀取子進程的運行結果

#小題型

1. 什么是error-first回調模式?

錯誤優先處理回調函數,應用error-first回調模式是為了更好的進行錯誤和數據的傳遞,第一個參數保留給一個錯誤error對象,一旦出現錯誤,錯誤將通過第一個參數error返回。其余的參數將用作數據的傳遞。

2. 如何避免回調地獄?

模塊化設計:將回調函數拆分成幾個獨立的函數

使用流程控制庫,比如async

組合使用generators和Promises

使用async/await函數

3. 什么是Promises?

在 then 后沒有 catch ,沒有捕捉異常。這樣做會造成故障沉默,不會拋出異常。

如果你調試一個巨大的代碼庫,并且比不知道哪個 Promise 函數有潛在的問題, 你可以使用

unhandledRejection 這個工具。它將會打印出所有未處理的 reject 狀態的 Promise。

4. 什么工具統一團隊的代碼風格?為什么統一的代碼風格很重要?

ESLint和Standard可以用來統一代碼

因為團隊協作時,代碼風格一致,團隊成員可以更輕松的構建項目,可以通過靜態分析排除代碼問題

5. 什么時候用npm?什么時候應當用yarn?

6. 什么是樁代碼(stub)?請描述一下應用場景?

樁代碼就是在某些組件或模塊中,模擬某些功能的代碼。樁代碼的作用是占位,讓代碼在測試過程中順利進行,測試時,stub可以為函數調用返回模擬的結果,比如,當我們寫文件時,實際上并不需要真正去寫

7. 什么是測試金字塔?請舉例說明?

測試金字塔反映了單元測試,集成測試,端到端測試在測試中占的比例

8. 你最欣賞的HTTP框架是什么?為什么?

9. 如何保證你的cookie安全?如何阻止XSS攻擊?

XSS攻擊是指攻擊者向html頁面里面插入惡意JavaScript代碼

HttpOnly 這個屬性幫助防止跨站腳本攻擊,它禁止通過JavaScript訪問cookie

為了防止攻擊,可以對HTTP header里的set-cookie進行處理set-cookie:sid=;HttpOnly.

如果使用express框架,可以使用express-cookie session,它會默認做出上述防止XSS攻擊的設置

10. 如何確認項目的相關依賴安全?

自動的更新你的依賴: npm outdated

NSP

11. 什么時候應該在后臺進程中使用消息服務,怎樣處理工作想成的任務/怎么給worker安排任務?

消息隊列適用于后臺數據傳輸服務,比如發送郵件和數據圖像處理

消息隊列有很多解決方案,比如RabbitMQQ

12. 這段代碼有什么問題?

new? Promise((resolve,reject) => {

throw new Error('error')

})

.then(console.log)

then之后沒有catch。這樣的話,錯誤會被忽略,會造成故障沉默

后邊跟上 .catch(console.error)

調試一個大型項目時,可以使用監控unhandleRejection事件來捕獲所有未處理的Promise錯誤

process.on('unhandledRejection',(err) => {

console.log(err)

})

13. 這段代碼輸出什么?

Promise.resolve(1)

.then((x) => x + 1)

.then((x) => { throw new Error('My Error') })

.catch(() => 1)

.then((x) => x + 1)

.then((x) => console.log(x))

.catch(console.error)

答案是2,逐行解釋如下:

1.創建promise,resolve的值為1

2.x 的值為1,加1 返回2

3.x 的值為2,但是沒有用到,拋出一個錯誤

4.捕獲錯誤,但是沒有處理,返回1

5.x 的值為1,加1 返回2

6.x 的值為2,打印為2

7.不會執行,因為沒有錯誤拋出

14.為什么要用node?

簡單強大,輕量可擴展

簡單體現在node使用JavaScript,json來進行編碼,人人都會

強大體現在非阻塞IO,可以適應分塊傳輸數據,較慢的網絡環境,尤其擅長高并發訪問。

輕量體現在node本身既是代碼,又是服務器,前后端使用統一語言。

可擴展體現在可以輕松應對多實例,多服務架構,同時有海量的第三方應用組件

node的優點:I/O密集型處理是node的強項,因為node的I/O請求都是異步的

node的缺點:不擅長CPU密集型的操作

CPU密集型操作(復雜的運算,圖片的操作)

15. node的架構是什么樣子的?

主要分為三層,應用app >> v8及node內置架構 >> 操作系統

v8是node運行的環境,可以理解為node虛擬機

node內置架構又可分為三層:

核心模塊(javascript實現) >> c++綁定 >> libuv + CAes + http

16. node有哪些核心模塊?

EventEmitter,Stream,FS,Net和全局對象

17. node在企業中常用到?

靜態資源服務器,代碼本地構建,單元測試,UI測試

工作中應該注意:精確版本號,測試,使用debug,保持代碼精簡

多請教,保持獨立思考,使用現有的庫,保持簡單

良好的文檔,配置文件,使用pm2

libuv:提供異步功能的C庫。它在運行是負責一個事件循環(Event loop),一個線程池,文件系統I/O,DNS相關和網絡I/O,以及其它一些功能

18. node異常處理

node是單線程運行環境,一旦拋出的異常沒有被捕獲就會引起整個進程的崩潰。

使用throw語句拋出一個錯誤對象,即拋出異常

將錯誤對象傳遞給回調函數,由回調函數負責發出錯誤

通過EventEmitter接口,發出一個error事件

try...catch結構無法捕獲異步運行的代碼拋出的錯誤

19. node關于高并發問題?

原理:非阻塞事件驅動實現異步開發,通過事件驅動的I/O來操作完成跨平臺數據密集型實時應用

傳統的server每個請求生成一個線程,node是一個單線程的,使用libuv保持數萬并發

libuv原理:

c語言編寫的基礎庫實現主循環,文件,網絡即可

libuv的改進:

回傳上下文信息

其它線程不能訪問缺省主循環,loop不支持多線程

數據庫高并發實現

var proxy = new EventProxy();

var status = "ready";

var select = function(callback){

proxy.once("selected",callback);

if(status == "ready"){

status = "pending";

db.select("SQL", function(results){

proxy.emit("selected",results);

status = "ready";

});

}

20. 什么是異步?

異步就是發出操作指令(把回調函數加入異步隊列),然后就可以去做別的事情去了,所有操作完成后再執行回調

異步I/O就是異步的發出I/O請求

雖然node可以異步發出I/O請求,但nodejs不支持多線程,為啥就可以支持高并發呢?

因為nodejs的I/O操作,底層是開啟了多線程的

當同時有多個I/O請求時,主線程會創建多個eio線程,以提高IO請求的處理速度

雖然nodeJS的IO操作開啟了多線程,但是所有線程都是基于主線程開啟的只能跑在一個進程當中還是不能充分利用CPU資源

pm2進程管理器可以解決這個問題,pm2是一個帶有負載均衡功能的node應用的進程管理器

cluster模塊

21. 代碼可讀性維護改進

async:async.waterfall([getcatalog,getaticle,getTigle])

promise的方法

koa寫法

es6寫法使用yield

22.優化問題

前端優化問題:移除iscorll,合并請求,tcp優化,HTTP優化,localstorate,html5離線緩存

api優化:restfulapi,標準輸入輸出

ui優化:使用同一的框架,前端組件化

異常處理:log監控,避免大文件處理,retry處理

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

推薦閱讀更多精彩內容

  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,102評論 0 1
  • 1.幾種基本數據類型?復雜數據類型?值類型和引用數據類型?堆棧數據結構? 基本數據類型:Undefined、Nul...
    極樂君閱讀 5,555評論 0 106
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    w_zhuan閱讀 3,626評論 2 41
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    Myselfyan閱讀 4,080評論 2 58
  • 前兩天在家看奧運,看得熱血沸騰。我太愛看奧運了,會讓人產生一種神秘的激情,這種激情曾經讓我希望從事體育工作,...
    wowo實驗室閱讀 807評論 0 50