Google Chrome浏览器漫画翻译

附英文漫画网址:https://www.google.com/googlebooks/chrome/big_00.html

P1

开源浏览器项目背后的故事

当今社会,我们每天使用的大多数网站已经不仅是页面,他们是应用

人们在网站上观看视频、上传视频、聊天、玩网页游戏,这在第一个浏览器创造出来时都无法实现。

现在正是个让我们从头设计符合当代网络应用和用户需求的浏览器的大好时机。

P2

首先,浏览器需要更加稳定。因为如果用户在撰写重要邮件或编辑文档时网页突然崩溃,将会出大问题。

浏览器也需要提高速度,更快启动,更快加载页面,对于网页应用程序来说,Javascript自身也可以更快。

它们需要更安全,基于现有的大量浏览器攻击事例,浏览器需要从结构进行改变以防止恶意软件获利。

浏览器拥有的特性不要冗余也不能过少,它们的用户交互界面应该简洁明了且高效。

谷歌chrome浏览器是一个完全开源的浏览器,谷歌希望他人可以采用它其中的观点,正如谷歌接纳别人的好想法一样。

P3

第一部分-稳定性、测试和多进程架构
当谷歌开始chrome项目时,工程师们一直在讨论:浏览器当前面对的问题之一就是它们内在是单线程的。

举个例子说明,当页面中有javascript正在执行,它会持续运行,而浏览器在这个javascript把控制权交回之前什么都干不了。

所以开发者们编写的API都是异步的(浏览器:你啥时候完事了告诉我一声 JS:没问题)——

——浏览器时不时就会因为javascript在某些地方持续运行而无法继续执行功能。(电话:哔!哔!所有线路正忙)

P4

谷歌工程师们开始考虑创造一种多线程的浏览器,这也使谷歌内部展开讨论——

——为何不用多进程来替代多线程呢?这样每个进程可以拥有属于自己的内存和全局数据架构副本。

chrome使用和现代操作系统相同的进程隔离技术。

这样,不同进程可以渲染不同的标签

P5

在多进程的环境下,你也拥有了独立的Javascript线程,当一个标签忙碌时,你可以切换到其他标签继续工作。

如果在渲染引擎上出现浏览器Bug(在以往的经验中,Bug几乎不可能被完全消除),chrome也只会失去这一个标签。

如果一个标签停止运行了,你会得到一个“哭脸标签”,但这不会使你的整个浏览器崩溃,而且它真的会显示“哭脸”哦。

一个多进程的设计意味着事先使用更多的内存,每个进程会有固定的额外内存使用,但随着时间流逝,这也意味着更少的内存膨胀。

传统的浏览器只拥有一个进程,和一个持续加载网页的地址空间。

当你打开过多的标签时,你可以关闭一些标签来释放内存。

当你打开一个新标签,它使用的是之前释放的内存。

P6

但随着使用时间的增长,内存会出现碎片——当标签关闭后,小部分的内存仍被占用无法释放。

要么是有内存无法被再次访问,要么有一部分被释放的内存仍被指针指向。

所以当浏览器想打开新标签时,现存空闲的地址没有足够的存储空间。

这使操作系统必须增加浏览器的地址空间,这个问题会随浏览器使用时间增长不断累加。(男:快点啊! 女:试试关掉一些标签。 男:我试过了!!)

但对于谷歌chrome浏览器,但你关掉一个标签,就相当于关闭了整个进程——

P7

——属于该进程的内存会被全部归还。

当你打开一个新标签,浏览器从头开始分配内存。

用户在使用浏览器的过程中,chrome浏览器会不停的创建和杀掉进程。如果出现了严重的内存泄漏,也不会长时间影响使用,因为用户可能早就在某个时刻关闭了内存泄漏的进程,将内存拿了回来。

chrome则更进一步,假设用户从站点A导航到站点B,这两个站点不必有任何关联——

——chrome浏览器会丢弃旧的渲染引擎、数据结构和进程。

这意味着,即使在一个标签中,chrome浏览器也可以收集并处理掉不用的“垃圾”,回收利用整个进程。

P8

就像查看操作系统一样,对于chrome浏览器,用户可以使用谷歌 chrome的任务管理器对后台数据一探究竟:哪些站点使用了最多的内存,下载了最多字节,持续“虐待”你的CPU。(女:这个应用程序怎么下载了整个互联网?)

你甚至可以查询标签页内的插件,它们在chrome任务管理器中显示为独立的进程。

所以当页面出现异常时,你就可以了解到是谁出了问题、问题的根源在哪,

并且除掉它。

找到真正的罪魁祸首。

P9

谷歌chrome浏览器是一个大型、复杂的产品,它需要加载百万计的不同网页,所以对它的测试至关重要。

幸运的是,在谷歌有一个同样大型的基础设施去爬取网页信息。

在一个新浏览器建成的20-30分钟内,谷歌可以使用千百万个不同网页去测试它。

每周,“chrome 机器人”会测试上百万个网页,并将原本开发者需要等到外部beta结束才能获得的结果尽早给出。

成功的关键是尽可能早地查询到问题,进而低廉高效地解决问题。随着时间推移,想要查找问题源头的难度也会提升。

更早地查出问题也可以帮助工程师们书写更优质的代码。他们会说:“哦,这个错误是我的习惯导致的”,那下一次他们就会降低这样写的可能性。

P10

当然,现在社会上有百万种,甚至万亿种网页。如果需要在每个浏览器版本上测试一百万个站点,那要选取哪些站点进行测试呢?

幸运的是,谷歌有针对该问题的解决方法。

网页 图片

谷歌已经就“普通用户最常访问哪些网页”对网页进行了分级。

浏览器至少需要做到不会在人们每天都要访问的站点上崩溃。

我们有不同的方法去测试每个登入页面的操作,从对代码的单元测试—到对脚本化的用户操作的自动化UI测试,比如“点击后退按钮...前往网页...”—到模糊测试:向你的应用程序发送随机输入。

P11

在布局测试中,WebKit(chrome使用的浏览器内核)发现,创造一个浏览器思维框架的概要图表,要比直接进行屏幕截图并产生一个加密哈希值更能准确地展示布局间的差别。

一开始进行测试时,chrome通过了23%的WebKit布局测试,从23%到99%的进阶过程是个十分有趣的挑战,也是测试驱动设计的生动例子。

对于自动化测试,我们能做的是有局限的。比如,它无法对需要密码的网站进行测试。

这种测试也不像人工一样可以肆无忌惮地错误操作,浏览器是根据工程师设计的步骤被操作的。

虽然100%的通过测试是很困难的,但谷歌正在为此努力。

谷歌对于在浏览器中添加一些新奇特性不感兴趣,只想让这个产品足够稳定可信赖。

P12

第二部分-WebKit和V8
WebKit是谷歌chrome浏览器目前使用的开源渲染引擎。

谷歌开发者们震惊于它的运行速度如此之快。

谷歌内部有个团队在开发安卓系统,浏览器团队的工程师曾问他们:“为什么你们选择使用WebKit?”

他们的回答是,WebKit可以高效地利用内存,可以轻松适应嵌入式设备,并且新浏览器开发者容易学习使用它的代码。

浏览器是很复杂的,而WebKit成功的关键之一就是它让一切保持简洁。

P13

因为对现在的Web项目来说,JavaScript十分重要。

谷歌决定编写一个Javascript的虚拟机。

这正是在丹麦的V8团队正在做的事情.

V8团队中都是虚拟机专家,无论你想在虚拟机中编入什么语言,他们都能指导你如何编写程序。

虚拟机可以提供安全的环境,并且不需要依赖平台。

但是之前存在的Javascript虚拟机是为小项目设计的,对这些项目来说,系统的性能和交互能力并不重要。

它们只需要在网页上运行一些很基础的东西。

P14

现在,很多web应用,比如GMail,将浏览器对DOM操作和Javascript使用的能力压榨到了极致,那种过分简单的Javascrip引擎已经不能满足应用的需要。

工程师们开始考虑如何让JS引擎运行速度加快,他们产生了很多新点子,比如引入隐藏类型过渡。

Javascript自身是无类别的(classless),你可以创建一个新对象,在其中动态添加属性并执行。

但是在V8,随着执行的时长增加,拥有相同属性的对象会共享一个相同的隐藏类型,我们就可在此基础上应用动态优化。

另一个影响V8速度的因素是动态代码生成。

当其他的Javascript引擎运行时,他们会分析javascript的源代码并且生成一个可以解析的内部表现形式。

P15

但当浏览器需要进行解析,它需要不断回看之前生成的内部表现形式。

V8引擎则不同,它会解析JS源代码并生成可以在运行浏览器的CPU上直接执行的机器代码。

当V8引擎解析并编译出机器代码,这个代码就是JS源代码的表现,并且它不需再次解析便可直接执行。

目前JS引擎最严重的设计缺陷是糟糕的垃圾回收机制。

Javascript和其他面向对象的现代编程语言一样,拥有自动内存管理机制。

如果对一个对象没有继续提及,那属于它的内存就会被系统收回,这就叫内存回收机制,并且是颇为微不足道的步骤。

但在现存的Javascript虚拟机中,它使用的是保守型内存回收机制。

P16

这意味着,因为无法确定所有指针的位置——

——虚拟机会查询整个执行栈来寻找哪些字看上去像指针。

但这些看上去像指针的字也有可能是整数,它们只是碰巧和对象堆中的对象有同一个地址值。

在V8引擎中,使用的是精准垃圾回收机制,这使虚拟机可以准确知道栈中所有指针的位置,也带来了很多优势。

优势之一就是,把一个对象迁移到其他位置时,只需要更改指针。

并且,因为知晓了所有指针的准确位置,V8引擎也可以执行增量式垃圾回收机制。

比起需要处理全部100MB数据并可能导致次长停顿的垃圾回收机制,这是一种循环往复的快速垃圾回收机制,时间单位可缩短至毫秒。

P17

这种垃圾回收机制也会提高Web应用的交互性能,比如更为顺滑的拖拽功能。

V8拥有一个为谷歌chrome浏览器提供的特定API,但这个V8引擎最核心的其实是它并不依赖浏览器。

所以,其他浏览器也可以包含它——

——或者,当出现Javascript可以处理的项目时,开发者们可以使V8全权处理。

我们希望V8的性能可以设定一个新的标准,而其他的开发者团队可以在此基础上更进一步。

因为当你观察那些随时间速度不断提升的系统时,你会发现它们会让你获得更大、更好、更有创造性的app。

P18

第三部分:查询和用户体验
在谷歌chrome浏览器中,用户界面的主件是标签栏。

当工程师们开始将标签栏设想为主件时,设计也自然的发生改变。

工程师们重新构建了UI设计,使标签栏移到了顶部。

因为浏览器和标签进程之间的独立性,用户就可以轻易地分离标签。

将单独标签从一个窗口移动到另一个窗口,标签本身的状态也会随之移动。

P19

因为标签栏是UI设计中最重要的部分,所以没有标签都拥有属于它的控制键和URL框,在谷歌它叫作“全方位框”。

因为这个全方位框不只能处理URL,它还可以对查询提出建议,将你之前浏览过的页面、你没有浏览过但是非常流行的页面排在顶部显示。

它拥有你之前浏览历史的完整文字查询功能。比如,你昨天找到了一个关于数码相机的好网站,你并不用将它加入收藏夹,只需要在“全方位框”中输入“数码相机”,就可以回到那个网站。

P20

当开发团队建议增加内嵌的自动补全机制的时候,我明确表示我恨这个机制,因为每个浏览器都坚持在地址栏使用这个蠢东西,而在我输入时,它补全的东西总不是我想要的。

但是,开发团队说这次是没问题的,请相信我们——他们继续开发,最终将这个补全机制变得让人无法拒绝。

内嵌补全的结果不会闪烁不定,也不会稍纵即逝,它拥有审美且不会使人分心。

并且,它只会补全你之前精准输入过的东西,比如,当你按下C和return键,它可能直接补全为cnn.com,它永远不会帮你补全成cc.com/2008/politics/07/27/campaign.warp/index.html?ref=mps

当你在像亚马逊、维基百科或者谷歌这种网站上进行搜索时——

——这些页面中的搜索框会被本地系统捕捉——

——所以你可以在这些网站中通过地址栏直接进行搜索,使用方法是:输入网站的名字并按下tab键,之后输入搜索关键词。

P21

对于现代大部分浏览器,打开一个新标签后你会看到用户设定的网站首页。

有些用户将其设定为空白页,因为它可以快速打开。

但这种打开标签的行为本身是有具体意向的:你想要去某个页面。

可能你知道具体网址,可能你不知道,这就需要查询。

chrome浏览器展示的则是一种为了快速运行设计的页面,它也可以帮助你到达想去的网页。

chrome的默认设置是:在新标签页中,你最常访问的九个网页展示在左边,你最常用的搜索网站展示在右边。

P22

这些网页是你之前输入进URL框、可能这次也想跳转到的网址,谷歌chrome浏览器使用用户在全方位框中的输入来填充这个页面。

你可能在打开新标签的时候十分疑惑:我的东西怎么跑到这里来了?之后你会发现,这就是你会打开的网站,这是为你设计的浏览器。

谷歌chrome浏览器有一个隐私模式,你可以创建一个“无痕”窗口,所有在这个窗口中发生的事都不会记录在你的电脑中。

在这个标签中发生的事只存在于这里

这个模式是只读的:你仍可以进入书签中的网站,但你的浏览历史不会被浏览器保存——

——当你关闭该窗口后,这次会话的cookies值会被清除。

P23

怎样在搜索惊喜礼物时不被人发现呢?

只需要换到另一个窗口进行正常浏览。

chrome浏览器中不存在突然出现或弹出的信息,它会避免Javascript将弹出信息显示在你的视野中。

那些弹出信息会被它们所在的标签页仔细检查,并且困在那里。

如果里面有你想查看的信息——

——你可以把它拖拽出来,浏览器会给它提供一个属于它自己的窗口。

P24

开发者们将浏览器的UI框架称为“chrome”。

工程师们希望减少chrome浏览器中的chrome,web app做到了这一点,你可以在它们自己的精简窗口中启动,这些窗口中不存在url框和浏览器工具栏。

chrome浏览器不希望打扰用户干他们想干的事,如果用户在做事时可以忽略浏览器,那就成功了。

P25

第四部分:保密性、沙盒模式和安全浏览
恶意软件和钓鱼网站对用户来说是巨大的隐患,它们影响了网页的可靠性。

当工程们开始设计chrome浏览器时,他们面临的是跟其他浏览器起步时相比十分不同的场景。

在其他浏览器设计之初,一切工作都为了渲染页面、让新奇东西在页面上可用。那时并没有金钱上的利益驱使人们在用户机器上添加恶意软件。

现在,恶意软件背后均有金钱驱使。它们所做的就是偷取他人密码,进而窃取金钱。

考虑到保密性,开发者们假定浏览器最终会被攻破,用户也会遇到恶意软件的攻击。

P26

chrome使用沙盒机制的目标是避免恶意软件在用户计算机上自主安装或从一个标签传染到另一个标签。

所以开发人员剥夺了标签进程的所有权利。

这些进程依然可以计算,但它们不能在用户的硬件或敏感区域(比如用户文件夹或桌面)内写入文件。

或者引用沙盒小组的话来说,开发者们将现有的进程限制起来,并将它们放入监狱里。

P27

这意味着进程不会在用户输入密码时进行监视、不会干扰用户鼠标行为、不会阅读用户的纳税申报单、不会让窗口在启动时运行可执行文件。

当标签中出现安全隐患时,用户只需关闭该标签就可以解决问题,这不会对用户的机器或其他进程造成影响。

沙盒的范围是由权限规定的。

VISTA使用的是BIBA安全模型的一种改良版本,它拥有三个级别。

高级别——十分信任
中级别——部分信任
低级别——完全不信任

P28

高级别
这个级别的使用者是后备系统和可更新的软件等等。

中级别
这个级别的使用者是用户日常使用的所有程序,比如:notepad、纸牌游戏、计算器等等

读取行为可以从低级别过渡到高级别

但写入行为只允许从高级别到低级别。

一般情况下,应用程序从网络接收/处理数据的行为会分入底部两个级别。

问题是,不同于高级别,中级别也会出现很多敏感信息,那么这个级别就不应该允许被读取。

P29

在chrome使用的模型中,上边是用户,下边是沙盒。任何通信都必须是由用户发起的。

从沙盒到用户也可以有答复,但是这种答复只能接触到被用户明确提供的信息。

chrome可以做到这一点是因为其代码是全新的,开发者们编写了所有代码,所以chrome浏览器对它们有完全的掌控权。

但这也有一个例外——插件。

因为现在的网页不再局限于只有HTML和Javascript。

P30

根据系统的权限体系,谷歌chrome浏览器的渲染引擎可能在很低的权限下工作,于此同时,一些插件可能在同一级别的权限或比浏览器更高的权限下运行。

插件拥有没有公共标准的功能,所以chrome浏览器当前无法对它们使用沙盒机制。

尽管插件开发者们带来了很多小挑战,chrome浏览器仍可以让插件在权限较低的环境中运行,这样更为安全。

与此同时,chrome浏览器对插件易损性的表面积进行大缩减。

P31

当网页中同时有HTML、Javascript和插件,它们会在同一个进程中运行。

如果其中一个部分崩溃或使内存受损,它们都会受影响。

所以开发者们将插件从渲染进程中单独抽出来,为它们建立了一个属于自己的新进程。

这样一来,即使插件无法加入沙盒,剩余部分的网页仍然可使用沙盒机制。

P32

沙盒机制可以保护用户远离恶意软件的侵害,但它们仍可能被钓鱼网站欺骗。

有一个经典钓鱼策略是:一个攻击者向用户发送邮件,上边写道:“这边是你使用的银行,你的帐户已经被泄露,现在需要你的社保号进行认证,等等......”

接着攻击者会向用户发送一个山寨的银行网站,进而窃取用户的信息。

很多这种网站会在24小时左右被关闭,也有一些会坚持7天或更久。

而最难的部分就是在钓鱼网站开站的时候就找到它们。

P33

谷歌chrome浏览器会持续下载恶意网站的列表,一个列表存放钓鱼网站,一个列表存放恶意软件。

如果用户访问的网站在这些列表中,浏览器就会警告。

这个服务是免费使用的,它是一个公用接口,谷歌也十分欢迎别人对其进行调用。

这是第二个包含恶意软件网站的列表,当用户访问这些网站,它们就会对用户的计算机造成安全隐患。

当chrome发现恶意信息时,一般会通知网站拥有者,因为他们可能并不是有意为之,他们也可以将这些恶意信息拿掉并清理自己的网站。

P34

第五部分:设备、标准和开源
开发者在谷歌chrome浏览器中内建的另一项内容是“GEARS”

所谓GEARS,基本上是在浏览器中添加一个接口——一个可提高自身能力的扩展。

从开发者的观点来说,谷歌chrome和gears是从两个方向管理网页,浏览器项目是让网页更好地服务用户,Gears则是让网页更好地服务开发者。

P35

现在对开发者可以在网页浏览器中创建应用的类型有很多限制,而且不同浏览器中开发者可以使用的子设备也是不同的。如果一个浏览器中有一个新奇的特性,这并不能改变什么——

——因为这个特性需要在所有浏览器中都存在,开发者们才能使用它。

Gears旨在尝试提高所有浏览器的基本功能性,包括谷歌chrome。

我们希望在Gear中重现在web app上建立本地app时获得的优势,并努力将它们变成web项目中的新式标准。

P36

开放的标准是提高所有浏览器运行效果的方法之一,开发团队也同样做出了很多努力,包括速度方面、稳定性方面和UI方面,比如新的标签页。

这些努力中的一部分可能会变成新的标准,而一部分可能不会。

但是,因为chrome是开源的,其他浏览器的开发者们可以在其中获取他们需要的部分。

P37

他们不需要支付费用,也不需要征求chrome的同意,更不需要分享补丁或者反馈缺陷。(如果他们想要分享,谷歌也有相关系统供他们使用)

他们能做的,是在chrome开发团队的基础上,将自身的创造力加入其中。

毫无疑问,谷歌可以将chrome申请专利并将它保护起来。

但是谷歌立足于网络,目标即是将网络世界变得更好,如果没有竞争只会得到一潭死水。

这也是为什么chrome是开源的,谷歌需要网络成为一个公平、智能和安全的地方。

P38

像创建谷歌chrome浏览器一样,帮助所有浏览器变得更高效也使开发者们激动不已。

浏览器需要与网页一同进步,并且为成为现代web应用程序的坚实地基不断努力。

chrome开发者们也是在其他开源项目的基础上进行创作的,特别是Mozilla和Webkit,谷歌对此十分感激。

chrome作为谷歌的回报,开发者们希望人们也可以在其中获取观点,挑战它们、以它们作为地基,推动网络不断向前进步。

注释:

1)The Gear Guys:这个词组在文中多次出现,直接翻译为“机械维修师”显然不妥,目前没有查到具体解释,先译为“工程师们”
2)po非英语专业,部分地方为了通顺使用了意译,如遇问题请提出,大家商量着看吧

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343