【轉(zhuǎn)】Code Review 程序員的寄望與哀傷

Code Review 程序員的寄望與哀傷

2017-01-20 07:25

一個(gè)程序員妙啃,他寫(xiě)完了代碼肢藐,在測(cè)試環(huán)境通過(guò)了測(cè)試恕齐,然后他把它發(fā)布到了線上生產(chǎn)環(huán)境们衙,但很快就發(fā)現(xiàn)在生產(chǎn)環(huán)境上出了問(wèn)題踩官,有潛在的 bug却桶。

事后分析,是生產(chǎn)環(huán)境的一些微妙差異蔗牡,使得這種 bug 場(chǎng)景在線下測(cè)試中很難被發(fā)現(xiàn)肾扰。畢竟想要在測(cè)試環(huán)境完美的復(fù)制生產(chǎn)環(huán)境的所有情況也是不太可能的畴嘶,導(dǎo)致出現(xiàn)了疏漏。對(duì)于這類(lèi)情況集晚,我們?cè)谙胧欠窨梢酝ㄟ^(guò)在線下做一些 Code Review(代碼審查)假想線上的環(huán)境差異窗悯,通過(guò)在頭腦中的假想上線運(yùn)行來(lái)獲得一些概念驗(yàn)證,這樣是否能夠減少上線后出現(xiàn) bug 的概率呢偷拔?

感性

Code Review 是很多軟件工程理論和方法學(xué)中的重要一環(huán)蒋院,而且程序員們大多都感性的認(rèn)識(shí)到 Code Review 對(duì)于提升代碼質(zhì)量和減少 bug 有幫助,但在我過(guò)去工作的這些年里莲绰,經(jīng)歷了幾家公司欺旧,數(shù)個(gè)不同的團(tuán)隊(duì),卻幾乎沒(méi)有把 Code Review 作為必要的一環(huán)去執(zhí)行的團(tuán)隊(duì)蛤签。

過(guò)去辞友,總是在線上出現(xiàn)一些奇怪的疑難問(wèn)題后,我們一群程序員才圍坐一堆震肮,打開(kāi)相關(guān)代碼來(lái)逐行分析称龙,根據(jù)線上現(xiàn)場(chǎng)的尸檢來(lái)做事后分析和推導(dǎo),這樣的代碼審查和分析實(shí)際上根本不是 Code Review戳晌,也完全違背了 Code Review 的初衷鲫尊。Code Review 的初衷是在代碼進(jìn)入生產(chǎn)環(huán)境前經(jīng)過(guò)同行評(píng)審來(lái)減少代碼出現(xiàn) bug 的概率。這一點(diǎn)程序員都好理解沦偎,提前的 Code Review 就像雷達(dá)掃描我們重點(diǎn)關(guān)注的代碼領(lǐng)地疫向,以期發(fā)現(xiàn)或明顯或隱藏的威脅因素。

想必很多人都看過(guò)一部叫《火影忍者》的漫畫(huà)豪嚎,里面有一種忍術(shù)技能——白眼搔驼。根據(jù)忍者能力強(qiáng)弱白眼能觀察的距離不同,雖然白眼有近 360° 的觀察范圍侈询,依然存在觀察死角舌涨。不是所有的程序員都擁有類(lèi)似「白眼」的技能,我們?cè)趯?xiě)程序時(shí)力求思考的全面妄荔,不留死角或盲點(diǎn)泼菌,但實(shí)際死角或盲點(diǎn)總是存在谍肤,隨著程序員經(jīng)驗(yàn)或經(jīng)歷的成長(zhǎng)啦租,思考和認(rèn)識(shí)的越發(fā)全面(越發(fā)接近 360°),擁有了近乎「白眼」的能力荒揣,但像白眼一樣依然存在盲點(diǎn)篷角。

我們看不到自己的后腦勺,所以假如在我們的后腦勺放上一個(gè)伙伴的眼睛系任,他的視角就彌補(bǔ)了我們自己的盲點(diǎn)恳蹲。世上沒(méi)有兩片完全一樣的樹(shù)葉虐块,也許也不會(huì)有兩個(gè)認(rèn)知視角完全重疊的人。

像 Code Review 或結(jié)對(duì)編程這樣的實(shí)踐正是基于這樣的感性認(rèn)知嘉蕾,試圖找出盲點(diǎn)區(qū)域的 bug贺奠,但到底這樣的做法能降低多少出現(xiàn) bug 的概率呢?

理性

有人對(duì) Code Review 的作用進(jìn)行了更理性且量化的分析错忱,來(lái)自 Wikipedia(維基百科)儡率。

卡珀斯·瓊斯(Capers Jones)分析了超過(guò) 12,000 個(gè)軟件開(kāi)發(fā)項(xiàng)目,其中使用正式代碼審查的項(xiàng)目以清,發(fā)現(xiàn)潛在缺陷率約在 60-65% 之間儿普,若是非正式的代碼審查,發(fā)現(xiàn)潛在缺陷率不到 50%掷倔。大部份的測(cè)試眉孩,發(fā)現(xiàn)的潛在缺陷率會(huì)在 30% 左右。

一般的代碼審查速度約是一小時(shí) 150 行程式碼勒葱,對(duì)于一些關(guān)鍵的軟體(例如安全關(guān)鍵系統(tǒng)的嵌入式軟體)浪汪,一小時(shí)審查數(shù)百行程式碼的審查速度太快,可能無(wú)法找到程式中的問(wèn)題错森。代碼審查一般可以找到及移除約 65% 的錯(cuò)誤吟宦,最高可以到 85%。

也有研究針對(duì)代碼審查找到的缺陷類(lèi)型進(jìn)行分析涩维。代碼審查找到的缺陷中殃姓,有 75% 是和計(jì)算機(jī)安全隱患有關(guān)。對(duì)于產(chǎn)品生命周期很長(zhǎng)的軟件公司而言瓦阐,代碼審查是很有效的工具蜗侈。

從上面的實(shí)驗(yàn)分析結(jié)果看,Code Review 對(duì)于發(fā)現(xiàn)潛在缺陷很有用(相比測(cè)試能發(fā)現(xiàn)的缺陷率高一倍)睡蟋,但也需要投入巨大的時(shí)間成本(一小時(shí)審查 150 行代碼踏幻,再快就不利于發(fā)現(xiàn)潛在缺陷了),而且更適用于長(zhǎng)生命周期的產(chǎn)品戳杀。

所以该面,有個(gè)現(xiàn)象就容易理解了。我發(fā)現(xiàn)在同一家公司做 Code Review 較多的都是研發(fā)通用底層技術(shù)產(chǎn)品或中間件的團(tuán)隊(duì)信卡,而做業(yè)務(wù)開(kāi)發(fā)的團(tuán)隊(duì)則較少做 Code Review隔缀。一方面是底層技術(shù)產(chǎn)品或中間件的需求較穩(wěn)定,且生命周期長(zhǎng)傍菇,而業(yè)務(wù)項(xiàng)目(特別是嘗試性的新業(yè)務(wù))需求不穩(wěn)定猾瘸,時(shí)間要求緊迫,而生命周期很多都偏短。

困難

通過(guò)了理性的分析我們可以看出 Code Review 是有很大好處的牵触,但適用的場(chǎng)景和花費(fèi)的成本也需要去平衡淮悼。除了這點(diǎn),也許還有一些關(guān)于如何實(shí)施 Code Review 的困難揽思。

如果把 Code Review 作為一個(gè)必要環(huán)節(jié)引入到研發(fā)流程中袜腥,也許會(huì)引發(fā)下面一些問(wèn)題:項(xiàng)目 deadline 已定,時(shí)間緊迫钉汗,天天加班忙成狗了瞧挤,誰(shuí)還愿意搞Code Review?這是一個(gè)最常見(jiàn)的客觀阻礙因素儡湾,因?yàn)?deadline 很多時(shí)候都不是我們自己確定的特恬。

即使強(qiáng)推下去,團(tuán)隊(duì)認(rèn)識(shí)不到其好處徐钠,也不夠重視癌刽,每次走個(gè)過(guò)場(chǎng),Code Review 的效果如何能保障尝丐?如果你是一個(gè)父親显拜,為自己的孩子制定一個(gè)最簡(jiǎn)單的規(guī)則,比如說(shuō):飯前洗手爹袁。你如何保障這個(gè)規(guī)則的實(shí)施效果远荠,你當(dāng)然可以每次吃飯前檢查下孩子的手是否干凈,但你也很難每頓飯都和孩子一塊兒吃失息,所以你就檢查不到了譬淳。要是孩子有個(gè)智能的碗,當(dāng)孩子吃飯時(shí)手一接觸到碗就能檢測(cè)細(xì)菌是否超標(biāo)盹兢,然后發(fā)出提醒和拒絕措施邻梆,這樣是否就保障了這個(gè)規(guī)則與你在或不在的實(shí)施有效性。而 Code Review 顯然是個(gè)更復(fù)雜的規(guī)則绎秒,需要的智能工具支持也更復(fù)雜浦妄。

團(tuán)隊(duì)人員結(jié)構(gòu)搭配不合理,新人沒(méi)經(jīng)驗(yàn)的多见芹,有經(jīng)驗(yàn)的少剂娄。天天安排經(jīng)驗(yàn)多的少數(shù)人幫助 review 多數(shù)新人的代碼,新人或有收獲玄呛,但對(duì)高級(jí)或資深程序員又有多大裨益阅懦?一個(gè)好的規(guī)則或制度總是需要既符合多方參與者的個(gè)體利益又能滿(mǎn)足組織或團(tuán)隊(duì)的共同利益,這樣的規(guī)則或制度才能順暢的實(shí)施和運(yùn)轉(zhuǎn)把鉴。

若你的團(tuán)隊(duì)中存在一些自信超強(qiáng)大的程序員故黑,覺(jué)得自己的寫(xiě)的代碼絕對(duì)沒(méi) bug,不需要?jiǎng)e人來(lái)給我 review庭砍。這樣的人未必就很差场晶,他寫(xiě)的代碼甚至確實(shí)出 bug 的概率比普通人更低,但肯定依然存在潛在 bug怠缸。這樣團(tuán)隊(duì)成員的存在诗轻,也會(huì)成為 Code Review 的一個(gè)障礙。

路徑

Code Review 確實(shí)存在很多各種各樣的困難揭北,導(dǎo)致很多團(tuán)隊(duì)都能認(rèn)識(shí)到它的好處卻實(shí)施不下去扳炬。尤其在國(guó)內(nèi),我?guī)缀鯖](méi)聽(tīng)說(shuō)過(guò)嚴(yán)格把 Code Review 作為一項(xiàng)研發(fā)制度或規(guī)則要求的公司搔体。

但在大洋的另一端恨樟,無(wú)論是老牌大公司如 Google 或是新近崛起的創(chuàng)業(yè)公司如 Airbnb 都把 Code Review 作為上線進(jìn)入生產(chǎn)環(huán)境前強(qiáng)制且必須的一環(huán)。在一篇介紹 Google Code Review 的實(shí)踐文章中說(shuō)道疚俱,在 Google 任何產(chǎn)品劝术,任何工程的代碼,在被進(jìn)行嚴(yán)格或者明確的審查(Code Review)之前呆奕,是不允許提交的养晋。你看,Google 通過(guò)工具控制在進(jìn)行 Code Review 前甚至是無(wú)法提交代碼的梁钾。

Google 以一種強(qiáng)硬的姿態(tài)來(lái)制定關(guān)于 Code Review 的且應(yīng)用于全公司范圍內(nèi)的規(guī)則绳泉,對(duì)任何人都不例外。即使面對(duì)團(tuán)隊(duì)中超自信且強(qiáng)大的程序員也無(wú)例外姆泻,要么遵守規(guī)則零酪,要么離開(kāi)組織。這一點(diǎn)從 C 語(yǔ)言和 Unix 的發(fā)明者拇勃、圖靈獎(jiǎng)得主蛾娶、最具傳奇性的程序員 Ken Thompson 在 Google 的趣事——作為 C 語(yǔ)言發(fā)明者之一因?yàn)闆](méi)有參加 Google 的編程語(yǔ)言能力測(cè)試所以無(wú)法在 Google 提交 C 代碼——從中可以一窺 Google 規(guī)則的強(qiáng)硬性。

所以像 Google 這樣的公司對(duì)于 Code Review 屬于高度認(rèn)可且有公司制度和規(guī)則的強(qiáng)硬支持潜秋,再輔助自動(dòng)檢測(cè)和控制工具的嚴(yán)格執(zhí)行蛔琅,方能如此。這也屬于一種嚴(yán)格的同步 Code Review峻呛,所謂同步就是必須要等待 Code Review 有了結(jié)果并無(wú)異議后方能提交或上線代碼罗售。

但要實(shí)施如此嚴(yán)格的同步 Code Review 似乎對(duì)大部分國(guó)內(nèi)公司又感覺(jué)過(guò)于無(wú)奈,這需要公司制度钩述、團(tuán)隊(duì)文化和技術(shù)工具三方面的支持寨躁。而在大部分以業(yè)務(wù)目標(biāo)、KPI和績(jī)效導(dǎo)向的公司牙勘,不說(shuō)在制度和文化方面得到支持职恳,能不被反對(duì)就不錯(cuò)了所禀。關(guān)于這一點(diǎn)陳皓(@左耳朵耗子)寫(xiě)過(guò)一篇文章《從 Code Review 談如何做技術(shù)》其中寫(xiě)到了在阿里實(shí)施 Code Review 遇到的各種文化上的阻礙和反對(duì)。而阿里已是國(guó)內(nèi)頂級(jí)互聯(lián)網(wǎng)公司放钦,可見(jiàn)實(shí)施同步 Code Review 的路徑并不簡(jiǎn)單色徘。

如果實(shí)施同步 Code Review 如此困難,那么是否可以退而求其次操禀,設(shè)計(jì)一種異步的 Code Review 方式呢褂策?就像我們提升系統(tǒng)性能一樣,把一些同步的串行調(diào)用變成異步的并行調(diào)用颓屑,按這個(gè)思路 YY 了以下場(chǎng)景斤寂。

程序員完成編碼,提交測(cè)試揪惦,測(cè)試通過(guò)后就去上線發(fā)布遍搞,另一方面也組織并行的 Code Review。畢竟測(cè)試通過(guò)只能證明測(cè)試覆蓋的場(chǎng)景無(wú) bug器腋,但可能代碼實(shí)現(xiàn)并不優(yōu)化和合理尾抑,而并行的 Code Review 即使發(fā)現(xiàn)了潛在問(wèn)題依然來(lái)不及阻止本次上線,但可以為下次上線提供優(yōu)化點(diǎn)或方向蒂培。另外在制度上把 Code Review 作為工程師的日常 KPI再愈,比如:要求每周對(duì)其他同事的代碼變動(dòng)做 1~2 次 Review。

而 Review 的方式除了閱讀代碼护戳,也可以為 Review 的代碼提供 Unit Test 間接達(dá)到了結(jié)對(duì)編程的目的翎冲。為了確保代碼確實(shí)被 Review 過(guò)需要工具支持,對(duì) Review 過(guò)的代碼進(jìn)行簽名媳荒,對(duì)不同的 Review 形式(簽名表示讀過(guò)抗悍,Unit Test 表示不僅讀過(guò)還白盒測(cè)試過(guò))進(jìn)行分類(lèi)統(tǒng)計(jì),發(fā)布 Code Review 統(tǒng)計(jì)排行榜和覆蓋分析钳枕。

以類(lèi)似這樣的方式缴渊,逐步培養(yǎng)起交叉 Code Review 的文化和氛圍,同時(shí)也顯性將 Code Review 納入了程序員的工作業(yè)績(jī)之中鱼炒。一開(kāi)始不必像同步 Code Review 一樣對(duì)所有上線進(jìn)行了阻塞衔沼,帶來(lái)巨大的陣痛。當(dāng)然這也依然是一個(gè)理想化的 YY 場(chǎng)景昔瞧,實(shí)施起來(lái)依然需要克服不少困難和準(zhǔn)備前提工具指蚁。

在另外在一篇叫《谷歌是如何做代碼審查的》文章中,一位 Google 的工程師對(duì) Code Review 的認(rèn)識(shí)是:

代碼審查的最大的功用是純社會(huì)性的自晰。

還有一個(gè)非常重要的好處凝化,代碼審查能傳播知識(shí)。

而防止 bug 混入酬荞,這反倒是它最不重要的一點(diǎn)搓劫。

第一點(diǎn)是這么理解的瞧哟,如果你在編程,而且知道一定將會(huì)有同事檢查你的代碼枪向,那么你編程的姿勢(shì)和態(tài)度都會(huì)完全不同勤揩。之間的微妙差異可類(lèi)比于你是在為公司的內(nèi)部系統(tǒng)編程,還是在給開(kāi)源軟件貢獻(xiàn)代碼遣疯。這是一個(gè)很有趣的視角,它其實(shí)反應(yīng)了公司的制度和文化凿傅。

現(xiàn)實(shí)

以前嘗試過(guò)要在團(tuán)隊(duì)內(nèi)部做 Code Review缠犀,聽(tīng)說(shuō)兄弟團(tuán)隊(duì)搞得不錯(cuò),然后就一起交流經(jīng)驗(yàn)聪舒,最后交流的重心就落在了應(yīng)該選個(gè)什么好用的 Code Review 工具來(lái)做辨液,如今想來(lái)這完全是舍本逐末了。

這就像以為有了好的編輯器(或 IDE)就能寫(xiě)出好的代碼一樣箱残,事實(shí)就是有很多好用的 Code Review 工具我們依然做不好 Code Review滔迈。古龍小說(shuō)《陸小鳳》中有一段描述,記憶尤深:

西門(mén)吹雪:此劍乃天下利器被辑,劍鋒三尺七寸燎悍,凈重七斤十三兩。

葉孤城:好劍盼理。

西門(mén)吹雪:的確是好劍谈山。

葉孤城:此劍乃海外寒劍精英,吹毛斷發(fā)宏怔,劍鋒三尺三奏路,凈重六斤四兩。

西門(mén)吹雪:好劍臊诊。

葉孤城:本就是好劍鸽粉。

劍是好劍,但最好先成為像西門(mén)吹雪或葉孤城這樣的好劍客抓艳,再來(lái)居高俯視触机、吹毛斷發(fā)的談劍是否是好劍。

即使在最差的環(huán)境下玷或,完全沒(méi)有人關(guān)心 Code Review 這件事威兜。一個(gè)有追求的程序員依然可以做到一件事,自己給自己 review庐椒。就像寫(xiě)文章椒舵,我寫(xiě)完一篇文章從來(lái)不會(huì)立刻發(fā)布,而是從頭腦中放下(unload)约谈,過(guò)上一段時(shí)間(也許是幾小時(shí)笔宿、也許是幾天)再自己重新細(xì)讀一遍犁钟,改掉其中必然會(huì)出現(xiàn)的錯(cuò)別字或文句不通暢之處,甚或論據(jù)不充分或不準(zhǔn)確的地方泼橘,因?yàn)槲抑啦还芪覍?xiě)了多少文字涝动,總還會(huì)有這些 bug,這就是給自己的 review炬灭。

即使如此醋粟,有時(shí)發(fā)出去的文章還是依然存在 bug,但總會(huì)比不 review 少了些重归。程序員在估算開(kāi)發(fā)任務(wù)時(shí)也最好加上自己給自己 review 的時(shí)間米愿,給自己 review 是一種自省,自我的成長(zhǎng)總是從自省開(kāi)始鼻吮。

...

我提交了一段代碼育苟,卻沒(méi)人給我 review,稍后我自己給自己 review 了椎木,得到了一段更好的代碼和一個(gè)更好的自己违柏。

寫(xiě)點(diǎn)程序世間的文字,畫(huà)點(diǎn)生活瞬間的畫(huà)兒香椎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漱竖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子畜伐,更是在濱河造成了極大的恐慌闲孤,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烤礁,死亡現(xiàn)場(chǎng)離奇詭異讼积,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)脚仔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)勤众,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鲤脏,你說(shuō)我怎么就攤上這事们颜。” “怎么了猎醇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵窥突,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我硫嘶,道長(zhǎng)阻问,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任沦疾,我火速辦了婚禮称近,結(jié)果婚禮上第队,老公的妹妹穿的比我還像新娘。我一直安慰自己刨秆,他們只是感情好凳谦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著衡未,像睡著了一般尸执。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缓醋,一...
    開(kāi)封第一講書(shū)人閱讀 49,850評(píng)論 1 290
  • 那天如失,我揣著相機(jī)與錄音,去河邊找鬼改衩。 笑死岖常,一個(gè)胖子當(dāng)著我的面吹牛驯镊,可吹牛的內(nèi)容都是我干的葫督。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼板惑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼橄镜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起冯乘,我...
    開(kāi)封第一講書(shū)人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洽胶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后裆馒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體姊氓,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年喷好,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翔横。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梗搅,死狀恐怖禾唁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情无切,我是刑警寧澤荡短,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站哆键,受9級(jí)特大地震影響掘托,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜籍嘹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一烫映、第九天 我趴在偏房一處隱蔽的房頂上張望沼本。 院中可真熱鬧,春花似錦锭沟、人聲如沸抽兆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)辫红。三九已至,卻和暖如春祝辣,著一層夾襖步出監(jiān)牢的瞬間贴妻,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工蝙斜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留名惩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓孕荠,卻偏偏與公主長(zhǎng)得像娩鹉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子稚伍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

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