2018年9月29日星期六

Java 11正式发布,新特性解读,架构在APP和前端里的应用和演进 - InfoQ每周精要556期

 中文站「每周精要」
感谢您订阅每周精要第 556 期,本期内容截止于2018-09-30。
技术新闻   TECH NEWS
Electron 3.0正式版发布,新特性详解
新版本带来了众多升级选项、问题修复和新特性。本篇介绍了新版本的详细信息。
AI同传风波后:科大讯飞股价蒸发超400亿
你还愿意相信国产AI技术力量吗?
LinkedIn开源TonY:在Hadoop上运行TensorFlow的框架
本文介绍TonY的内部细节、在Hadoop上实现并利用的扩展分布式 TensorFlow 的特性以及实验结果。
FAIR重磅发布大规模语料库XNLI:解决跨15种语言理解难题
Facebook AI研究院和纽约大学研究团队的一项合作研究新成果。
阿里前CEO卫哲:寒冬又来了,不论你公司大小,要尽早看清这 3 个信号
经济寒冬又来了。
Java 11正式发布,新特性解读
最新发布的 Java11 将带来 ZGC、Http Client 等重要特性,一共包含 17 个 JEP(JDK Enhancement Proposals,JDK 增强提案)。
架构设计   ARCHITECTURE DESIGN
架构只能用在后端吗?谈谈架构在APP和前端里的应用和演进
前端工程师 + 程序员 + 系统管理员 + 对各种技术灵活搭配的能力 + 模式总结 = 架构师,架构师在一家公司、一个项目有多重要?
如何使TOGAF标准服务于企业架构
任何大型企业系统的架构师大概都会寻求如何管理复杂性及与各种利益干系人沟通的指导。这篇TOGAF标准的概述将介绍该框架的结构,并讨论使用企业架构管理复杂系统的好处。
重构到更深层的模型
Paul Rayner使用一个案例分析了如何重构代码到更深层的领域模型。通过代码重构,结合模式实现,代码库更加粘合,也更容易推断,将一些常用任务的完成时间从几周或几个月缩短到几小时。
运维 & DevOps   OPERATIONS & DEVOPS
以Chef和Ansible为例快速入门服务器配置
服务器配置(Server Provisioning):如何在我们的环境中安装和配置软件
如何定义日志消息的级别?详解日志的5个级别
日志级别如何划分?
MySQL是如何做容器测试的?
随着容器基础设施的出现,容器基础设施的测试变得与机器镜像的测试一样重要。
大前端   THE FRONT END
首屏时间从12.67s到1.06s,我是如何做到的?
本文是对之前同名文章的修正,将所有 webpack3 的内容更新为 webpack4,以及加入了笔者近期在公司工作中学习到的自动化思想,对文章内容作了进一步提升。
百度智能小程序月活破亿,正式开放申请
百度宣布智能小程序正式开放申请:即日起开发者只要通过搜索"百度智能小程序"或百度 App 语音搜索"智能小程序学院"就可以找到申请入口,申请成功便可以开发自己的智能小程序。
Stack Overflow预测:Python将在五年内超越JavaScript
本文从各种数据渠道探讨了 JavaScript 和 Python 未来 5 年的发展趋势及 Python 踏上统治地位的可能性。
人工智能   ARTIFICIAL INTELLIGENCE
海底捞1000亿上市,未来后厨只需两位工程师
对于普通人来说,海底捞的"变态级服务"可能更加熟悉,但是,你知道这家全国最大的火锅公司能有今天的成绩,还有背后大数据和人工智能黑科技的加持吗?
简化数据获取!Uber开源深度学习分布训练库Petastorm
Petastorm让研究人员更容易获得数据,从而可以专注于模型实验。
AI一周热闻:阿里成立半导体公司平头哥;亚马逊发布11款新产品;科大讯飞回应AI同传造假
新鲜事,简单报,一周热闻盘点准时到!
区块链   BLOCKCHAIN
百度区块链白皮书V1.0发布
区块链技术正处在高速发展的时期,它以颠覆传统技术的独有优势,让我们有理由 相信区块链将对现有经济社会产生巨大影响。
十年前端老兵:学习DApp开发,投身下一个浪潮
"CSS 魔法",08 年加入互联网,是一位有十年经验的前端老兵。他认为区块链将是下一个重要的节点,对区块链技术也有着自己的理解和有启示意义的看法。
如何选择适合你的区块链框架?
现在有这么多链和 DLT(分布式分类帐技术),你该如何选择使用哪一个?每个框架都有某些特点,适用于某些特定的应用程序。本文探索了其中的 5 个框架。
技术大会   CONFERENCE
QCon:Apache RocketMQ事务消息演进之路
作为一款具有低延时、高可靠、高性能、亿级消息堆积能力的分布式消息系统,Apache RocketMQ 目前已在阿里巴巴集团得到了极为广泛的应用,支撑着双十一万亿级消息流量洪峰。
CNUTCon:什么是Elasticsearch?
维基百科用它来进行全文搜索,英国卫报用它来处理访客日志,GitHub用它来检索超过1300亿行代码……如何改进Elasticsearch,来匹配日志分析场景?
ArchSummit:关于云原生平台架构设计,货车帮李昊带你深入浅出
虚拟化、超融合、云平台不是目的,只是手段,实现业务才是目标。满帮集团高级技术总监李昊从2016年进行基础设施建设的时候,就认准最核心的任务是提供一个云原生平台,为软件交付的过程提供服务。
AICon:机器学习在短视频商业化中如何应用?
近几年,短视频应用蓬勃发展,由于短视频场景下用户兴趣和广告内容更难以理解,短视频广告在用户内容理解、召回、排序和机制上都会遇到更大挑战。如何利用AI相关技术更好的解决这些问题?
极客时间App   GEEK TIME APP
如何用最简单的方式从0到1搭建Kubernetes集群?
Kubernete项目维护者带你深剖容器技术,几千字的分享即可搭建一个准生产级别的Kubernetes集群,轻松发布你的第一个容器化应用,戳此即可试读文章。
技术团队领导的核心是什么?
技术团队的领导需要在多种关键职责间进行平衡,最重要的一点,就是团队的支持。技术团队领导如何激励团队,如何以一种以流程为导向的方式组织团队的工作。100位 CTO激励团队的心法,走向优秀技术领导者之路。
推荐21本架构师必读书单,从成长、技术、业务3方面
资深技术专家、架构师李运华平均每年读50本书,坚持了8年。他推荐了21本书给你,经典中的经典,戳此马上开读。
活动推荐   POPULAR EVENTS
刷脸购物,不再是梦想
中国的在线零售巨头京东的无人商店和无人超市已经对外开放了。更有趣的是,在京东的无人商店和无人超市里,当你选好自己要买的东西之后,只需"刷脸"就能完成支付过程,钱包什么的,完全不用拿出来啦。
QCon上海限额免费专场:互联网新时代的进阶锦囊
机会丰富而又竞争激烈的创新时代,普通工程师该如何努力才能脱颖而出?互联网技术迭代迅速,如何高效学习,做到取舍自如,事半功倍?2018QCon上海解决方案专场,带你找到答案!
《从零开始学架构》新书特惠
最后 1 天!互联网资深技术专家李运华《从零开始学架构》首发优惠,84元包邮。作者12年架构经验无保留分享,大量的实战案例解析,已有超过26000人一起验证过的架构心法。跟着做,你也能成为架构师。
InfoQ中文站每周日针对会员发送每周内容精要邮件,
别人转发给你的邮件?现在注册获取您自己的 InfoQ每周精要邮件吧
InfoQ微博:@InfoQ
InfoQ微信:infoqchina
InfoQ手机客户端:极客时间

2018年9月28日星期五

当我们在谈论AI说话:语音合成

引言

近年来,随着 Amazon Echo 的蹿红,国内巨头们也纷纷开始布局智能音箱(百度 Raven 、阿里天猫精灵、腾讯听听、京东叮咚、小米 AI 音箱等等),相信不少同学都已经入手;同时,越来越多读书 APP 提供"听书"的功能,甚至出现将小说转有声小说的软件;手机里的语音助手、电脑里的 Cortana、车载导航中的"妹子们"说话越来越像真人,甚至感觉偶尔说话很有"感情"。这些应用背后都有用到了同一种技术——语音合成(TTS,Text To Speech)。

TTS 有着悠久的历史,在上个世纪就是热门课题,不过一直没有取得太大的突破。近些年,随着学者们开始将 TTS 与 Deep Learning 结合——毫无意外的——TTS 领域开始蒙眼狂奔,一次次突破 State of Art。在 TTS 与 Deep Learning 结合后的短短几年,出现了大量里程碑式的论文,如 Google 的 WaveNet、百度的 Deep Voice、Google 的 Tacotron 等等。其中,Tacotron 是迄今(2018年)在 End to End 的程度与 TTS 效果上做的最突出的模型,同时它还在"飞速"演进中。作为"飞速"的举证,Google Tacotron 主页列出了 Tacotron 的相关 Paper,我们可以看到在 2018 年六月、七月、八月每个月都有一篇新 Tacotron 的相关 Paper 发出,更新速度远超这个科普专栏。。。

鉴于 TTS 工作的悠久与复杂程度,本文将仅仅、并详细介绍上述的里程碑之一 —— 初代 Tacotron,以此见微知著,或者说管中窥豹地一探如今 TTS 的进展。

预备知识

从我的角度看,Tacotron 是一个极其复杂的模型:首先,它需要一定的领域知识(多亏它几乎 End to End 的特性,跟其他 TTS 模型相比,理解成本已经大幅降低);其次,它的模型结构非常复杂,体现在 Layer 的种类多且组合方式不直观(NLP 出身的同学可能更容易理解)。因此,这里先具体介绍其中用到的成熟模块,降低后续理解成本,对这些模块很熟悉的同学可以跳过。

Seq2Seq

在机器翻译领域有这么一种需求,即输入输出的数量不相等。比如:中文"苹果真是贵",英文译为"APPLE is really expensive",从五个字变成了四个单词。在"当我们在谈论 Deep Learning:RNN 其常见架构"中我们介绍了经典的 RNN,其输入输出数量必须是相等的。K.Cho 在"Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation, 2014"中提出一种方式来解决此类 Many to Many 的问题。假设此时需要将"x序列"转换为"y序列",则网络示意图如下

简单说来,其序列产生过程为:先将 \{(x_i, h^x_{i-1})|i=1,2...\} 依次输入给 RNN_1 ,得到隐层输出 C 。接下来依次将 \{(C, s^y_{i-1}, y_{i-1})|i=1,2...\} 输入 RNN_2 ,并期待输出 \{y_i\} 。其中, h,s 分别表示 RNN_1, RNN_2 隐层输出。

在这个模型中, RNN_1, RNN_2 分别可以被看作 Encoder,Decoder:Encoder 将 \{x_i\} 编码成隐向量 C ,再通过 Decoder 解码出输出 \{y_i\} 。此时,输出序列的长度与输入长度无关,即实现了 Many to Many 的转换。

还有另外一种相似的形式,是 Google 在"Sequence to Sequence Learning with Neural Networks. 2014"中提出的,区别仅在于此文章中 C 仅用于预测 y_1 ,后续不再使用,示意图如下

但是,上述这种 Encoder-Decoder 模型也存在问题:无论多长的输入序列,都必须编码成一个语义特征 C 用于解码,即要求 C 必须包含输入序列的完整信息,此时 C 的长度就成了此项任务最大的瓶颈。如果输入序列太长, C 长度不足则可能严重制约输出的效果。于是,Seq2Seq with Attention Model 应运而生。

Seq2Seq with Attention

Seq2Seq with Attention 最早是 Bahdanau 在"Neural Machine Translation by Jointly Learning to Align and Translate, 2014"中为了解决机器翻译中的 Align 问题提出的,其结构近似于现在大家说的 Soft Attention(因为后来各种 Attention 的方式被提出,为了区分所以有了各种命名)。

Seq2Seq with Attention 与 Seq2Seq 最大的区别就在于 Decoder,其输出

p \left( y _ { i } | y _ { 1 } , \ldots , y _ { i - 1 } , \mathbf { x } \right) = g \left( y _ { i - 1 } , s _ { i } , c _ { i } \right)

可以看出,这里关键就是 C 被替换成了 c_i 。这里 c_i 可以理解为对输入序列关注的分布,也就是输入的哪些信息对当前的输出是有意义的;而以前的 C 是对所有信息的汇总,有同学也戏称为"注意力不集中",这就是 Attention 命名的由来。Attention Model 的示意图如下

Attention Model 的完整公式如下

\begin{align} & p \left( y _ { i } | y _ { 1 } , \ldots , y _ { i - 1 } , \mathbf { x } \right) = g \left( y _ { i - 1 } , s _ { i } , c _ { i } \right) \\ & s _ { i } = f \left( s _ { i - 1 } , y _ { i - 1 } , c _ { i } \right) \\ & c _ { i } = \sum _ { j = 1 } ^ { T _ { x } } \alpha _ { i j } h _ { j } \\ & \alpha _ { i j } = \frac { \exp \left( e _ { i j } \right) } { \sum _ { k = 1 } ^ { T _ { x } } \exp \left( e _ { i k } \right) } \\ & e _ { i j } = a \left( s _ { i - 1 } , h _ { j } \right) \\ \end{align}

其中, h,s 分别表示 Encoder、Decoder 的隐状态。 h_j 被称为 annotations,包含了部分输入序列的信息,并主要是 x_j 的信息。 c_i 称为 context vector,是 h_i 的加权和,表示为了得到当前输出状态 s_i ,输入序列按照注意力 \alpha 加权提取后的结果。 \alpha_{ij} 表示为了得到 s_i ,每个 h_j 所对应的归一化后的注意力,这里使用 softmax 的方式归一,原始的权重是 ee_{ij} 即为了得到 s_i ,每个 h_j 所对应的注意力,如上述公式,它跟 s _ { i - 1 } , h _ { j } 相关,具体计算可以自己定义。在本文中,作者的定义如下,并使用一个小型神经网络来优化

a \left( s _ { i - 1 } , h _ { j } \right) = v _ { a } ^ { \top } \tanh \left( W _ { a } s _ { i - 1 } + U _ { a } h _ { j } \right)

在"Approaches to Attention-based Neural Machine Translation"中,Luong 还提出了其他几种权重计算方式

\begin{align} \operatorname { a} \left( \boldsymbol { h } _ { t } , \overline { \boldsymbol { h } } _ { s } \right) = \left\{ \begin{array} { l l } { \boldsymbol { h } _ { t } ^ { \top } \overline { \boldsymbol { h } } _ { s } } & { \text { dot } } \\ { \boldsymbol { h } _ { t } ^ { \top } \boldsymbol { W } _ { a } \overline { \boldsymbol { h } } _ { s } } & { \text { general } } \\ { \boldsymbol { W } _ { a } \left[ \boldsymbol { h } _ { t } ; \overline { \boldsymbol { h } } _ { s } \right] } & { \text { concat } } \end{array} \right. \end{align}

Highway

在"当我们在谈论 Deep Learning:CNN 其常见架构(下)"中我们介绍了 ResNet,它其实就是 Highway 演进出来的,不过当时并没有具体介绍,这里补充下。Highway Network 出自"Training Very Deep Networks",其表达式为

\mathbf { y } = H \left( \mathbf { x } , \mathbf { W } _ { \mathbf { H } } \right) \cdot T \left( \mathbf { x } , \mathbf { W } _ { \mathbf { T } } \right) + \mathbf { x } \cdot C \left( \mathbf { x } , \mathbf { W } _ { \mathbf { C } } \right)

类似 LSTM 中 gate 的概念,这里 T,H 分别被称为 transform gate、carry gate,分别表示输出多少是从变换来得,多少是从原始输入来的。为了减少参数,同时可以理解为归一化,文中令 C = 1 -T ,于是有

\mathbf { y } = H \left( \mathbf { x } , \mathbf { W } _ { \mathbf { H } } \right) \cdot T \left( \mathbf { x } , \mathbf { W } _ { \mathbf { T } } \right) + \mathbf { x } \cdot \left( 1 - T \left( \mathbf { x } , \mathbf { W } _ { \mathbf { T } } \right) \right)

其中, T ( \mathbf { x } ) = \sigma \left( \mathbf { W } _ { \mathbf { T } } ^ { T } \mathbf { x } + \mathbf { b } _ { \mathbf { T } } \right)\sigma 为 sigmoid 函数, \sigma ( x ) \in ( 0,1 )

Mel Spectrogram

做信号处理的同学都知道一般不会直接处理时域信号,而是会综合时频域分析,甚至频域分析更常用。语音信号处理同样,也会将时域信号变换到时频域提取特征,比如提取 Mel Spectrogram(梅尔频谱)。鉴于我只是语音的门外汉,大家可以参考"[STFT和声谱图,梅尔频谱(Mel Bank Features)",其中对 Mel Spectrogram 的概念及生成有较详细的介绍。

下面正式开始 Tacotron 的介绍。

Tacotron 简介

这里先简单介绍下 Tacotron 模型的输入输出:

  • 输入、输出:如英语,输入即一句文本数据;输出是对应的语音信号的频谱,此文章中输出了两种频谱,Mel Spectrogram 与 Linear Spectrogram
  • Loss Function:很符合直觉的,本文中 Loss 即 Mel Spectrogram Loss 、Linear Spectrogram Loss 的加权和

对于 Tacotron 模型的结构,主要由三个模块组成:Feature Extraction,Encoder-Decoder,Post-Process。其流程图如下

  1. Feature Extraction:如它名字所说,用于提取特征。首先对输入文本数据做 Character Embedding,然后通过 Pre-Net、CBHG 两个作者定义的网络,得到特征数据;
  2. Encoder-Decoder:本阶段是利用 Seq2Seq with Attention 网络,重构出频谱;
  3. Post-Process:这个阶段主要是优化重构出的频谱,并将频谱转换回时域。首先将 RNN 生成的 Mel Spectrogram 通过 CBHG 网络,生成 Linear Spectrogram(这样重复生成 Spectrogram 的原因我们下面再分析)。最后将 Linear Spectrogram 通过经典 Griffin-Lim 算法变换回时域得到语音信号。可以看到这里频域转时域的步骤已经跟网络没任何关系了,所以 Griffin-Lim 的细节下面不会讨论,有兴趣的同学可以自行查阅资料。

接下来,我们具体介绍这些模块。

Feature Extraction

这里主要包括 Character Embedding、 Pre-Net、CBHG 三个结构。为了方便后续理解,我们假设输入文本长度为 [charLen]

Character Embedding

Character Embedding 即字符级别的 Embedding,毕竟 word 的词库太大,而且意义也不大。此步骤输出大小为 [charLen, embedingSize]

Pre-Net

Pre-Net 也能一句话讲完,就是两层 Fully Connected 的网络罢了。但是需要注意的是,此时 Fully Connected 只针对 embedding 维,而非我们平时理解的"跟所有上一层元素都连接",所以此变换后输出为 [charLen, preNetUnitLen]

CBHG

这个阶段中比较复杂是作者定义的 CBHG 结构,它包含了一系列结构,示意图如下

  1. Conv1D Bank: 这里 Bank 指的是 K 个一维卷积核,每个卷积核区别仅仅是大小不同,因此这里模拟的其实是抽取 1-Gram、2-Gram...、K-Gram 的特征,每个 filter 都能到 [charLen, cnnChannel] 大小的 Feature Map。然后将结果 stack 到一起,得到 [charLen * K, cnnChannel] 输出。
  2. Max-Pool along Time: 这跟普通 Pooling 也没什么区别,Pooling 的区域大小为 [poolSize, 1] ,在每个 Channel 上分别沿着时间的方向平移,于是输出依然是 [charLen * K, cnnChannel] 。这里作者强调了,他使用 stride=1,为的是保留时间上的分辨率
  3. Conv1D projections: 这是一层 Conv1D 的卷积
  4. Conv1D layers: 这依然是一层 Conv1D 的卷积
  5. Residual connections: 这是一层 Residual Block,即 H(x) = F(x) + x ,其具体解释与优点可以参考"当我们在谈论 Deep Learning:CNN 其常见架构(下)"
  6. Highway Layers: 接下来是一个多层的 Highway Layer,用于提取高维特征

最后,终于抽取了输入文本的特征。

Encoder-Decoder

Encoder

在 Encoder 阶段,作者将特征输入到一个 bidirectional GRU RNN 中。

Decoder

在 Decoder 阶段,利用 Attention RNN 得到 Mel Spectrogram。需要注意的是,在训练阶段,Attention RNN 的输入是 Ground Truth,仅在测试阶段是上一个 time step 的输出。其中 Attention RNN 输入需再次利用 Pre-Net 提取特征。

Attention 的结构上面已经介绍过,就不再赘述了。不过这里要吐槽一下 Google 的节操,在文中解释 Attention 引用的居然是自己公司的"Grammar as a Foreign Language,2015"而非更原始出处"Neural Machine Translation by Jointly Learning to Align and Translate, 2014",让人有种商业互吹、刷引用的既视感。

此外,此处 RNN 用的是多层的 GRU,与普通 GRU 稍微有些不同:这里 Layer 之间加入了 Residual Connections,按照文中的说法是能加速收敛,当然与此同时 Residual Block 的其他优点如稳定性更高、更易学习等是原因。关于 Residual Connections GRU 的具体介绍可以参考原文或"Google's Neural Machine Translation System: Bridging the Gap between Human and Machine Translation. 2016"。

Post-Process

这一步中,作者先用 CBHG 将 Decoder 产生的 Mel Spectrogram 转换为 Linear Spectrogram。文中提到增加这么一步的原因是,在 Decoder 中,产生的 frame 都是从前往后,而每个 frame 看到的信息也是从左往右的;而这一步中,每个 frame 能看到整句话的信息,可以帮助修正某些 frame 的错误。

最后,如上所述,就是利用 Griffin-Lim 算法得到时域语音信号,由于与整个网络结构无关,就不再赘述了。

上文提到,Tacotron 的 Loss Function 并非只是最终的 Linear Spectrogram 的 Loss,而是 Mel Spectrogram Loss、Linear Spectrogram Loss 的加权和。原因猜测跟 Mel Spectrogram 更符合人类的听觉特征有关,在 Loss 中加入 Mel Spectrogram 对产生的声谱是否符合人类听觉习惯增加了一定约束,提升听觉效果。

Tacotron 结构总结

最后,下图列出 Tacotron 具体网络结构参数,有兴趣的可以对照着上文的介绍一起看看加深理解。

Tacotron 实验结果

为了一探如今 TTS 实际的效果,我最初毫无畏惧地用我的老爷 PC 跑起来 Tacotron 的训练代码。在运行了3天3夜才 20000 step,我听了听此时的效果,默默关掉了训练程序。。。不过我并没有死心,还强行尝试训练了日语,效果依然惨不忍睹。。。

后来我咨询了同事 (此处应@Max),才知道他们以前在微软都是用几十个GPU跑两天才出结果。怪不得网络上 TTS 的文章远少于 CV、NLP 的,看起来门槛高也是一个原因。

下面以英文为例,我给出 github 中有同学训练出的 Tacotron 效果,顺便也配上我自己的鬼畜音频,博大家一笑。日语的实在是太鬼畜,这里就不放了。下面每段视频的前半段是 Tacotron 正确的效果,后半段是我训练出来的鬼畜效果。

例句1:Scientists at the CERN laboratory say they have discovered a new particle.

例句2:There's a way to measure the acute emotional intelligence that has never gone out of style.

其他的例子就不再列举了,从上文两个示例也能看出,当前 Tacotron 的实际效果已然是非常惊艳,相信假以时日 TTS 真的能够做到以假乱真。

尾巴

这篇文章里提到了 Attention,这里顺便唠个八卦。记得去年曾经去听过一场 Chris Manning 的报告,他提到他们团队的工作现在也都基本标配 Attention,我当时还问了一句,大概是:在你们的实验中,Attention 的效果总是优于没有 Attention 吗?Chris Manning 回答:YESALWAYS。所以感觉有条件的,可以无脑上 Attention 了,当然学术界早已如此。

另外,恰好最近"命运石之门0"完结,倒数第二集真是把 Amadesu 的美丽和声音表现的太棒了!而回到现实,Amadesu 这种真-AI 短期不一定能实现,但是其中令她说话如真人一般自然且有感情的 TTS 模块的到来,相信不会太遥远了。

REFERENCE

  1. tacotron 开源代码

本系列其他文章:

专栏总目录(新)



via 当我们在谈论数据挖掘 - 知乎专栏 https://ift.tt/2In3YP8
RSS Feed

RSS6


Unsubscribe from these notifications or sign in to manage your Email Applets.

IFTTT

JavaScript 之父联手近万名开发者集体讨伐 Oracle:给 JavaScript 一条活路吧!- InfoQ 每周精要848期

「每周精要」 NO. 848 2024/09/21 头条 HEADLINE JavaScript 之父联手近万名开发者集体讨伐 Oracle:给 JavaScript 一条活路吧! 精选 SELECTED C++ 发布革命性提案 "借鉴"Rust...