为什么我们要尝试Kotlin

技术雷达:对Android的完美支持为迅速发展的Kotlin语言提供了额外的推动力,我们也正在密切关注Kotlin / Native(基于LLVM,可以将Kotlin代码编译为原生可执行文件)的进展。在使用Anko库开发Android应用时,我们已经尝到了空指针安全、数据类和易于构建DSL的甜头。尽管初始编译速度慢,且只有IntelliJ才提供一流的IDE支持,但我们仍然建议尝试一下这种新颖简洁的现代语言。

由于最近在客户项目上有机会使用了Kotlin这门今年大热的语言,所以在好几个不同的场合都被要求做一些Kotlin相关的分享,在这个过程中被问到的最多的一个问题便是——我们为什么要尝试Kotlin?

(图片来自:http://suo.im/4hXHdp

实际上客户早在去年年初的时候便已经完成了他们的后端技术选型,而Kotlin在那个时候便已经成为了项目构建后端微服务的主要语言。所以在这些分享中我并没能给出一个很好的答案,而这个问题本身也引起了我的思考。

首先我们看看Kotlin语言的特点,官方罗列了4个显著的特点:

  • 简洁 Consice
  • 安全 Safe
  • 友好的开发工具 Tool-friendly
  • 和Java的互操作性 Interoperable

简洁 Concise

Kotlin的简洁体现在很多方面,对于Java程序员来说,最直接的体现便是在Kotlin语法中直接省略了分号,并且在构造一个类的实例时省略了new关键字,下面便是一段标准的Kotlin代码:

fun sayHi(name: String): String {
    val sb = StringBuilder(str = "Hi ")
    sb.append(name)
    return sb.toString()
}

让我们再看一个Kotlin官网的示例代码,来体会一下Kotlin的简洁:

data class Customer(val name: String, val email: String, val company: String)

简单的一行代码便实现了一个包含了constructor以及默认getters, toString, equals, hashCode和copy实现的Pojo,而同样的java实现需要大概50多行代码, 即便是在Lombok的帮助下仍然需要十几行代码。

Kotlin还在Java集合类的基础上进行了封装,并提供了非常丰富的集合操作。同时结合非常简洁的Lambda表达式,使得调用更加精简。

val numbers = 1..10
val doubles = numbers.map {it * 2}
val sumOfSquares = doubles.fold(0) {x,y -> x+y}

除了这些,Kotlin还提供了很多类似字符串模板、标准函数库、运算符重载的特性,这些特性使得代码可以非常简洁易读,极大提升了开发者的体验。

从实际项目来看,Kotlin的简洁在代码量上表现的非常明显,一个提供了24个API的Spring Boot微服务,通过Kotlin编写的代码量在8000行左右(含测试代码)。同样规模的微服务用Java编写的情况下代码量将远大于这个数字。

安全 Safe

许多编程语言(包括 Java)中最常见的陷阱之一是访问空的指针,导致空指针异常。Kotlin的安全性主要体现在它对Null-Safety的支持上。能够使代码在编译期间就察觉到可能的NullPointerException,让Java developer能够轻松摆脱NullPointerException。

var output: String
output = null // Compilation error

val name: String? = null // Nullable type
println(name.length()) // Compilation error

同时Kotlin还提供了一些自动转型及类型推断的特性,在提供安全检查的同时也带来了便捷。

下面也是一个来自官网的样例,Kotlin在类型检查得到true后,自动完成了Any到Invoice类型的转换:

fun calculateTotal(obj: Any) {
    if (obj is Invoice)
        obj.calculateTotal()
}

友好的开发工具 Tool-friendly

这个特点就不用多说了,引用官网那句傲娇的原话就是 “It’s what we do best!”

和Java的互操作性 Interoperable

简单来说这个特性就是Kotlin和Java是可以相互调用的。

这意味着我们可以利用任何已有的Java libraries来构建我们的应用,让我们无需放弃我们所熟悉的一切便可以享受Kotlin给我们带来的愉快的编程体验。

...
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
...

interface AreaRepository : JpaRepository<AreaEntity, Long>, JpaSpecificationExecutor<AreaEntity> {
    fun existsByAreaId(id: UUID): Boolean
    fun findOneByAreaId(areaId: UUID): AreaEntity?
}

例子中是项目上一个用Kotlin编写的基于Spring JPA的Repository,可以看到得益于Interoperable的特性,在尝试使用Kotlin时我们可以依赖的是一个完整的Java生态圈。我们依然可以使用我们所熟悉的框架、构建工具、开发工具和测试工具。

如何开始?

看了这么吸引人的语言特性,或许你已经忍不住想要尝试Kotlin了。但是实际情况可能是项目已经开始了一段时间,我们已经用Java为项目构建了很多功能。这个时候引入一个新的语言可能会给项目带来一定的风险。那么我们可以如何开始呢?

使用Kotlin编写单元测试

如果你比较保守,那么你可以开始尝试在项目中仅通过Kotlin来编写单元测试,同样得益于Interoperable这个特性,我们可以轻松的使用Kotlin来为Java类编写单元测试。这样你可以不用担心尝试Kotlin为你的业务代码带来风险,同时也可以在编写单元测试的过程中尝试Kotlin语言的各种特性。

使用Kotlin来扩展

你还可以使用Kotlin来丰富项目中所用到的Library,使用Kotlin Extensions来在不需要继承的情况下完成对原有类型的扩展。或者直接通过Kotlin来编写工具类为项目服务。

//Extensions.kt
fun String.lastChar() = this.get(this.length - 1)
fun KPerson.fullName() = "${this.firstName} ${this.lastName}" //String template
//Java JUnit test
Test
public void lastChar() throws Exception {
 assertEquals('n', Extensions.lastChar("Kotlin"));
}

Test
public void fullName() throws Exception {
  KPerson k = new KPerson("Foo", "Bar", Gender.MALE, 18);
  assertEquals("Foo Bar", Extensions.fullName(k));
}

使用Kotlin来重写微服务

如果你在使用基于Spring Boot的微服务,那么完全可以挑选一个优先级较低的服务逐步通过Kotlin进行改写。你会发现这个转变会发生的无比顺滑。因为Kotlin不会改变你之前通过Spring Boot构建微服务的方式。

这三个方法都可以让你在风险可控的情况下尝试Kotlin。让你在感受Kotlin语言带来的美好编程体验的同时,使整个团队逐渐熟悉Kotlin语言。你将会发现对于一个Java程序员来说,学习Kotlin真的是一件非常容易的事情,可以说一旦开始你就再也回不去了。

技术雷达

正在我们还在犹豫是否要尝试Kotlin的时候,最新一期技术雷达上Kotlin的表现又给了我们一个难以抗拒Kotlin的理由。虽然在雷达的描述中,我们更关注的是Kotlin在Android Native领域的影响力,但是随着Spring社区对Kotlin的支持和更过成功项目的出现,相信Kotlin会继续向雷达的圆心迈进。

最后在这里分享一些我在学习Kotlin过程中觉得不错的相关资源:


更多精彩洞见,请关注微信公众号:思特沃克

Share

技术雷达是如何创建的?

ThoughtWorks一年发布两次技术雷达,在每次雷达的准备期,TAB(ThoughtWorks技术顾问委员会)成员都会全力以赴的投入其中,以至连睡觉都会变成一件奢侈的事情。

言归正传,到目前为止我已经参与了几次技术雷达的构建。在这之前我曾疑惑于一个问题——“技术雷达是如何建立的?”这也是如今我常常被他人询问的问题,在本篇文章中,我将从内部人员的视角就技术雷达的产生机制、准备方式和决策方式给予一些介绍。文章从一次为期四天的会议开始。

第一天

为了制定下一期技术雷达,来自全球的ThoughtWorks TAB成员一大早就汇集在了一起。每次我们都会从四个办事处中选择一处碰面——这次我们定在了去年刚成立的巴塞罗那办事处。如果你觉得初来乍到和时差问题会拖慢进程,那就错了。团队一旦聚在一起,稍作提神后,立马就投入战斗了。

首先给大家介绍一下我们的技术顾问委员会,它是由来自全球的ThoughtWorks资深技术人员组成的,其中包括首席科学家Martin Fowler。此次线下会议由我们的全球CTO Rebecca Parsons主持。

开始的第一天,技术顾问委员会的每一位成员都准备了不少他们认为可以纳入下一期雷达的想法——也就是我们在技术雷达中看到的具体条目。

这次在巴塞罗那,团队要对180个备选条目进行投票表决。这就意味着要达成共识,大家需要进行审慎的考虑和热烈的讨论。

候选条目按雷达象限(技术、工具、平台、语言与框架)归类,再分为几个环(暂缓、评估、试验和采用)。这便于提醒我们每个环所表示的意思,有助于决定条目的归属范畴。

  • 暂缓。这一环包含我们认为客户应当放弃或者需要等待时机成熟的条目。
  • 评估。我们认为有希望且值得研究一番的事物。
  • 试验。强烈推荐的技术,仅当我们预见能成功部署于生产时,才会将条目归于这一环——非常罕见的情况除外。
  • 采用。对于特定应用情形,我们认为这是唯一最好的方案。

为了确定最终能够登上本期雷达的100个条目,我们每次分析一个象限,每个象限从采用到暂缓由内而外地进行。条目的推荐人负责向团队进行介绍,然后展开讨论和表决。每个人有三张不同颜色的牌子:绿色表示“是,我希望将其纳入雷达”;红色表示“不,不可能将其纳入雷达”;黄色则表示他们有疑问或意见。这四天会议上将大量用到这些牌子。

红牌用完后,用橙牌表示新的红牌。

这次我们从技术象限开始——不仅因为这是我最喜欢的方式,也因为这样讨论将更加细致。如此一来,下一期技术雷达就有了起点。

第二天

直到第二天凌晨,雷达墙才略微显露出一些秩序——但区别也不是很大。一名团队成员负责逐一检查雷达墙,而我则负责确保跟踪所有决定——到后来几乎不可能记住所有的东西。检查雷达墙时,他们明确我们下一步即将探讨的提议,并将便利贴移到团队表决的位置。有些情况下,要将便利贴置于指定的环内——但后来可能移到其他环或象限,或者完全遭到拒绝。

偶尔我们会遇到一些条目,迸发激烈的争论,甚至会由于一些细微差别而陷入僵局。这些问题我们视为“太过复杂而无法成为条目”——这并不表示它们会被抛诸脑后;这些问题仍然很重要而且值得注意。只是不适合在技术雷达上探讨。

有这么多条目需要讨论和表决,让讨论继续进行才是关键。Rebecca负责监督程序的进展。介绍条目时,她会留意黄牌的出现,并告诉团队下一个发表意见或提问的人是谁。期间没有人会插嘴。每个人必须在轮到自己的时候才能发言。

第一轮表决进度很快。先介绍条目,再快速讨论,最后表决。这里有一个棘手的问题。已经有一些人发表了一些意见,但团队里仍有不少人举黄牌。为了保持程序正常进行,Rebecca拟制了发表意见的名单并提示我们:“乔尼发言后开始表决。”

表决票数经常比较接近,所以要一直举着牌直至统计完所有绿/红牌。当有黄牌出现时,讨论继续。达成决定后,进入下一步。这里不掺杂任何个人因素,我们进行地很快。

第三天

到了第三天,我们基本已经完成了新条目最主要的部分。但离完成还相差甚远。从许多方面而言,艰难的工作才刚开始。

之前,每一次表决都将决定是否将某个新条目纳入雷达。现在,我们得回顾上一期雷达的条目,加起来通常会有100个左右。他们是否仍然关系重大?哪些应当去掉?哪些条目需要重写?如果我们对一个条目的看法连续两期雷达都没有发生改变,就让其“淡出”。因为还有很多有趣的事情值得探讨!有些时候,为了腾出雷达空间,我们必须强制淡出一些条目——即提前删除这些条目。

即便如此,我们还有大量的条目。现在的讨论就变得激烈了。技术雷达诞生于全球充满热情的技术人员所组成的ThoughtsWorks社区。它基于我们的客户工作经验。我们认为这是我们的优势之一。但只要大家对技术怀抱热情,难免会存在异议。我们的雷达讨论也不例外。

接下来,我们检查所有人一致同意理应纳入雷达但不如其他条目价值高的条目。这种剔除过程非常艰难,好几次我们不得不停下来问自己:团队有没有什么建议?如果团队对某个条目没有明确的建议或一致的意见,那这个条目便不会被纳入雷达。

第四天

连续三天的讨论——除了雷达,偶尔下班消遣时也会与同事互动,挑起技术谈话——大伤元气。现在会议室里几乎每个人都很疲惫了,但仍需进行最后调整,落实到位。

为了确保在计划时间内结束,我们采用了许多方式。例如,Rebecca确保不让讨论无休止地继续。我们也明白有时候个别人会不同意团队的决定。这时候,有一个可以改变团队的决定机会——我们称之为救生艇。一旦雷达基本落实到位,各技术顾问委员会成员可选择一个条目恢复——但他们必须说服团队该条目值得纳入雷达。或者说服大部分人即可,无需所有人一致同意。

最后,只有所有人尊重其他人的意见时,会议才能顺利开展。Rebecca协调会议时确保所有人都具有发言权,能表达自己的想法、经验和关注点。看到一群热情的人以相互尊重的方式表达有力的观点,展开高质量的讨论,这是令人高兴的事。所以即使团队出现分裂,表决票数相当,我们也能进入下一轮讨论。

到第四天结束时,我们对雷达的内容做出了最终决定。每次参加技术雷达会议,现场的讨论都令我折服——有幸参加会议让我深感荣耀,我一直惊叹于大家的技术意见、意见产生的过程、意见的评估方式以及团队谈论的各种背景。

这仅仅是雷达建立过程的起点。随后我们必须详细编写每一个条目、讨论产生的主题及主要报告。敬请期待——新一期雷达将于11.30日与你见面!点击这里提前订阅。

Share

无障碍性测试工具 Pa11y

2017.3 技术雷达 Trial

A11y(Accessibility)指的是用来帮助身心障碍者(残疾人)更加便利的使用先进技术的能力。目前世界上主要由各种人权组织和政府通过一些民间规则和政府规则来保障这方面权益。以Web Content为例,比较常见的规则有W3C组织在2008年出台的WCAG2.0,和美国国家标准的Section508等等。

这些规则数量比较多,涉及的检查范围从规定网页元素的颜色对比度,到元素的属性是否缺失等,内容十分丰富。对一个网站的内容进行完整的A11y检查,通常需要针对网站的每一个页面的每一个元素走查,这样的检查几乎是手工无法办到的。

Pa11y是基于HTML codeSinffer以及PhantomJS制作而成的网站内容A11y自动化检查工具。它利用PhantomJS的headless模式运行需要被测试的网站,然后把网页源文件和指定的规则(比如WCAG2AAA)做对比,自动检查出网页内容是否符合规范,同时会把检查结果输出成指定格式的报告。

ThoughtWorks技术雷达VOL.16将其放在试验阶段,鼓励大家对它进行尝试和使用。

Pa11y本身运行在node环境下,通过npm install安装。安装成功后,可以使用命令行来执行对目标网页的检查。同时它也支持从JavaScript直接调用。Pa11y工具支持选择WCAG2.0 A/AA/AAA标准和Section508标准,也支持忽略这些标准中某些特定的项。通过设置参数,还可以改变输出报告的格式,比如输出CSV或者HTML格式的报告。

对比之前需要在手动进入到网站的每个页面、点开每个隐藏元素,再把当前网页源代码拷进自动化工具的检查方式。Pa11y提供了Actions方式来自动化操作页面元素,使得网站操作和规则对比可以完全自动化进行。

另外和其他A11y测试工具相比,除了免费和开源之外,Pa11y还衍生出了许多不同目的的、基于核心工具Pa11y的Pa11y-X工具。比如支持并发多线测试和测试/生产环境隔离,而且可以存储每次执行结果的Pa11y-Webservice;又比如支持非技术用户使用、操作配置简单易懂、集成了Pa11y-Webserivce的前后端一体工具Pa11y-Dashboard(如下图)。

Pa11y-Dashboard还提供可视化图表,协助分析质量趋势。

另外,基于Pa11y这个核心工具还衍生出了专为CI准备和优化过的命令行工具Pa11y-CI等工具。 随着需求的增加,这个平台里面的工具也在Pa11y team的维护下逐渐增多,逐渐形成了一个A11y测试工具全家桶。

然而在目前的版本中,仍然有一些可以继续关注的地方,比如:

  1. 目前所支持的标准仅有WCAG2.0和Section508,将来是否会扩展新的规则支持方案。
  2. 2017年的WCAG2.1标准已经发布β版本,Pa11y应该如何做相应更新值得期待。
  3. 如何提升对不同浏览器的检查支持。
  4. 当前版本依赖的PhantomJS本身还有一些问题,例如对ES6的支持性不完等,如何使Pa11y在ES6开发的网站上完美运行善。

另外值得注意的是,由于Chrome59宣布开始支持Headless,PhantomJS2.x的主要开发者之一Vitaly Slobodin已经宣布不再继续开发新的功能。那么依赖PhantomJS的Pa11y是否也会迎来一次大的改版换“芯”成Chrome呢?


更多技术雷达信息,请点击这里

Share

技术雷达的安全实践

安全事故

2014年乌云网发布了某旅行网站(以下简称X网站)的安全支付漏洞,X网站因长时间打开支付服务调试接口,导致用户信用卡信息面临泄露风险;在针对其进行进一步的扫描后,乌云发现X网站的分站源代码可打包下载,其数据库配置和支付接口因此被直接泄露。

(图片来自:http://t.cn/Rt7siGq)

在X网站所泄漏的数据中,最引人关注的当属信用卡的CVV码。由于大量国外网站可以直接通过CVV码进行支付验证,用户直接面临盗刷的风险;X网站的行为也公然违反了《银联卡收单机构账户信息安全管理标准》:

各收单机构系统只能存储用于交易清分、差错处理所必需的最基本的账户信息,不得存储银行卡磁道信息、卡片验证码、个人标识代码(PIN)及卡片有效期。

混用测试环境与产品环境、明文记录用户敏感数据、违反相关技术标准、公网暴露数据库密码。X网站的安全事故对很多企业的IT部门都是警示,它提醒我们,随着互联网的发展,软件安全和信息安全不再是安装防火墙所能保障的,它需要企业从软件开发的第一分钟就开始关注安全并积极采取行动,把软件安全内建到研发过程中。

技术雷达的安全概念

技术雷达是ThoughtWorks的定期发表物,它包含了ThoughtWorks对于前沿技术和实践的观察与理解,是软件工程实践的风向标之一,在2016年4月期技术雷达中,与安全相关的技术与实践有13项,占到总数的13%(采用2项,实验5项,评估6项),从软件开发生命周期的角度去观察这十三项安全实践:

  • 分析阶段:1项
  • 开发阶段:8项
  • 测试阶段:2项
  • 运维阶段:2项

通过这个趋势我们可以观察到,软件的安全问题已经不仅仅存在于开发结束后,对于安全的管理已经开始贯穿软件开发的全生命周期,内建安全正在成为一种趋势。

如何理解安全实践

仅仅在项目启动的时候提出安全的要求,在项目结束前做渗透测试和审查,在现有的技术环境中已经不够了,X网站就是很好的反例。那么是不是越安全越好?

(图片来自:http://t.cn/R6Kkcag)

安全措施应该被看作是“必要的浪费”,关键是与商业目标做好平衡,我们认为其中的关键是安全问题从出现在代码/配置里到被发现之间的时间,即MTTD时间(Mean-Time-to-Detect),IT所追求的目标是将MTTD降到一个比较合理的水平, 且达到这一目标的成本是能够被开发团队所接受的。

基于这一理念,我们可以在软件开发流程的各个阶段内,在MTTD目标的牵引下,充分引入各种实践、工具、流程制度等等,不管表现形式是什么, 核心的目标都是在成本的限制下降低MTTD时间,我们看看从需求分析、开发、测试、运维几个阶段的角度入手,有哪些关于安全的工具、实践可以采用。

需求分析阶段

威胁建模,其主要目标是分析系统可能遭受的潜在攻击、识别出风险并制定应对措施。威胁建模提供了一系列技术,可以帮助团队在开发阶段就能够对潜在威胁进行识别和分类,其主要分为三步:

  • 解构应用:庖丁解牛般的解构软件,比如网络、用户数据存储、其它数据、应用层等,分析攻击者可能对哪些信息感兴趣以及他们最可能的侵入方式。
  • 分析风险:对于上述风险,在参考了攻击的可能性、损失和成本因素后,进行优先级排序。
  • 决定对策:对于高优先级的风险在软件开发的不同阶段采取不同的措施进行防范。

当然威胁建模只是安全战略的一部分,当它和其他技术(如建立跨团队的安全专家,采取自动化安全扫描器)结合使用时,威胁建模才可以真正减轻企业面临的安全风险。

开发阶段

Let’s Encrypt,早些年SSL Labs公布的2010年互联网SSL调查报告(PDF)指出超过半数的Web服务器没能正确使用证书,主要的问题有证书不被浏览器信任、证书和域名不匹配、证书过期、证书信任链没有正确配置、使用已知有缺陷的协议和算法等。而且证书过期后的续签和泄漏后的吊销仍需进行繁琐的人工操作。Let’s Encrypt就是为了解决这个痛点而诞生。它基于自动证书管理环境(Automated Certificate Management Environment),至少做到了两件事:免费发放证书自动化更新证书

(图片来自:http://t.cn/R6CoUXB)

Let’s Encrypt由ISRG(Internet Security Research Group,互联网安全研究小组)提供服务并得到了Mozilla、Cisco、Akamai、Electronic Frontier Foundation和Chrome等众多公司和机构的支持。从2015年12月开始,Let’s Encrypt项目从封闭测试阶段转向公开测试阶段,也就是说用户不再需要收到邀请才能使用它了,这促使安全和隐私向前进了一大步。

OWASP Dependency Check,堡垒最容易从内部攻破,现代软件开发少不了用到第三方的库和插件,这些库是否安全呢?OWASP Dependency-check就是一款自动识别Java和.Net项目中所使用的第三方库中是否有已知安全问题的软件,通过第三方插件,它也支持Ruby, Node.js, Python和C/C++。

HSTS,新的HTTP头,可以用于强制要求浏览器与系统之间采取HTTPS通信,目前新版浏览器都支持这一头文件,Internet Explorer从Windows10技术预览版开始支持。

iFrames for sandboxing,HTML5标准的一部分,在<iframe>标签中插入了sandbox属性,开发团队可以建立一种新的开发实践。通过将第三方的组件放到iframe里,并且使用iframe的sandbox属性,只给iframe开放最小的权限,避免第三方的组件访问主页面的信息(比如DOM)。

Content Security Policies,新的HTTP头,CSP的目的是减少跨站脚本攻击。比如通过指定Content-Security-Policy的default-src属性为‘self’,强制要求只能使用本站资源,避免恶意脚本在payload中加入恶意代码,下载和上传信息。CSP需要浏览器的支持。

(图片来自:http://t.cn/R69APfE)

Gitrob,用于检测是否有员工不小心把某些敏感信息放到了Github公开库里。目前Gitrob只支持Github的组织级帐号,并只能扫描最近一次提交。

HashiCorp Vault,微服务架构需要管理大量服务器和各种密钥(秘钥、API key、证书),“如何安全管理这些信息”逐渐成为项目的一大挑战。之前通过文件或者环境变量存储机密信息的方式已经变得难以控制。HashiCorp Vault就是用于解决这一问题的,它可以作为开发的一个最佳实践采用。

Repsheet,一个类似于防火墙的工具,下一代安全防护产品(作为第三方库,在应用的源代码里使用)。可以分析和可视化来自黑客的攻击流量,使之只对正常流量放行。

测试阶段

OWASP Application Security Verification Standard ProjectASVS是一个针对应用程序安全性的检查清单,目前包括了22篇实践,比如《不要在敏捷开发中忘记黑客用户》,官方认为它可以作为:

  • 清单:用于开发人员自查。
  • 原则:作为安全人员和开发人员的桥梁。
  • 采购标准:用于企业采购软件时进行技术打分的标准。

Sleepy Puppy,Netflix出品的一个用于追踪、分析、 管理跨站脚本攻击的工具, 测试人员也可以利用这个工具进行跨站脚本攻击的测试。

运维阶段

Linux security modules,一个框架,可以支持多种不同的安全框架

Deflect,对抗分布式、拒绝服务攻击的服务

2017技术雷达

互联网企业所采用业务模式往往是“以隐私换服务”,这间接促成了庞大的隐私黑产、伤害了个人的权益。2017年的技术雷达也体现了业界在隐私问题上的思考。本期雷达上,身份数据欧洲托管从“评估”进阶为了“尝试”,差分隐私开始进入雷达。

差分隐私,从源头抓起

在2016年的WWDC大会上,苹果宣布自己加入了AI大战,同时宣布了不会走Facebook和谷歌的道路,在对于用户数据的收集上采取了差分隐私技术,简单来说,差分隐私是通过算法对个体用户数据添加噪音,让任何人都不能凭此追踪到具体的某一名用户,但又可以允许机构成批分析数据以获得大规模的整体趋势。其目标是在保护用户身份和数据详情的同时,仍能提炼出一些基本信息用于机器学习。

差分隐私的实施也将影响软件架构,比如(部分)计算将重新回到本地(而非云端),(夜间)批量处理可能成为移动端的最佳实践。

身份数据托管,减少干预

由于互联网企业拥有的数据越来越多,政府也在通过各种渠道渗透互联网公司,试图获取数据的控制权,棱镜门所暴露的政府文件让全球都意识到了这个问题。而欧洲是对于PII数据管控最为严格、立法最为完善的区域。比如:

在这样的监管下,Amazon这样的巨头也不得不推出相关服务,以响应这样的监管措施。

在可行的情况下,尽量考虑通过欧洲的数据中心进行托管是进一步减少干扰、增强隐私的方法。


更多精彩洞见,请关注微信公众号:思特沃克

Share

从2016年11月期《技术雷达》看前端的未来

本文仅代表作者个人观点,来听听一个前端程序员的YY。

新一期的技术雷达有点出乎意料,使用new标签的框架、工具、技术、语言等等超过了一半——Vue.js、ES2017上榜,Three.js凭着VR的火又上榜了,还有熟悉的Electron,以及微前端的概念。

让我们先看看一些技术亮点。

前端在可见的未来

在那篇《最流行的编程语言JavaScript能做什么?》的文章里,我们看到了JavaScript在各个领域的应用。在这一期里,仍然有很多亮点(new):

Vue.js

Vue.js,如果你在使用Vue.js,那么你应该更加自信了,现在它已经被列入评估期。Vue.js是一个简单易上手的框架,并且相当的轻量,在最近的这段时间里,它发挥的相当的出色。

可惜,笔者现在在用Angular.js 和 Angular 2,毕竟我现在的所做的事情是开发混合应用。不过相信在半年后,Angular 2 和 Ionic 2是会上榜的。

Ember.js,我现在对这个框架还缺乏深入的了解,而且还没有证据表明它会在国内火起来。

ECMAScript 2017,尽管我现在已经倾向于使用TypeScript,不过ES2017还是会用到的,只是我觉得Babel对我来说就是个坑。

PWA

Electron,我在很多场合中都使用过这个框架,从NodeWebkit开始写编辑器,再到用Electron完成Growth 1.0的桌面版。

Physical Web,现在我们可以通过蓝牙低功耗技术在浏览器上控制真实世界。

不过与此相比,我更看好 Progressive Web App,毕竟他可以让Web应用接触到更多的底层API,而不是局限于蓝牙,还可以是Push Notification等等。

VR

Three.js,它上榜的原因是WebVR的流行。这一点可以从我去年写的那篇《Oculus + Node.js + Three.js 打造VR世界》中可以看到一些趋势。这些就和现在的单页面应用一样,虽然运行起来不是那么流畅,但还是行得通。因而在可见的未来使用Web技术来开发VR也有一点苗头,未来浏览器上应该是可以运行编译过后的代码,而不是在运行时。

WebRTC,它可以让我们在浏览器端实现实时视频聊天。第一次接触到这个视频流技术是在两年多以前,上一次接触则是在半年多以前使用WebRTC + Oculus,你可以在我博客的那篇《JavaScript在VR世界的应用》中了解到更多的详细信息。当然如雷达所说,WebRTC将会形成未来在Web上进行AR/VR协作的基础。

接着再让我们看看一些架构上的变化吧。

前端引起的架构变化

在过去的两三年里,前端火得一塌糊涂——对于后端程序员来说,这有点winter is coming 的感觉。我在那篇《前端演进史》对前端的演进做了相当多的介绍,并在《后台即服务演进史》里对”后台即服务”开了个头,在这篇文章里让我们根据《技术雷达》来继续补几刀。

前后端分离

我们可以看到,很多中大型团队已经分解为前端和后台两个小组,沟通可以通过接口、契约等方式来进行。但是这一点儿也不精益,沟通在这时仍然是一个问题,让我有点怀念起之前前、后端都做的项目了——自己可以创建自己想要的接口。

不过,这意味着前端和后台在技术选型上更加独立了。

臃肿的前端——微前端

前端单体应用

在上一个项目里,我们一步步地将一个有近10年历史的系统替换掉。起初这是一个传统的Spring + JSP网站,然后我们用JSP创建了JSON API,后来创建了一个新的API来服务移动应用和单页面应用,再后来这个API被拆分成了几个API。我们的后台已经从一个单体应用变成了一个微服务架构的应用,但是这一点并没有在前端上应用——前端应用正在变得难以维护。

因此在这一期的雷达里,你可以看到微前端的概念(micro frontends)。这也是在上一个项目里,我们尝试做的一部分,遗憾的是并没有完全成功实施。这是一个搜索类型的网站,网站的首页承担着大部分的访问量,而详情页的主要流量来源则是搜索引擎。我们在首页上使用jQuery + Require.js技术栈,而在其他页面(搜索结果页 + 详情页)使用 React.js,我们在最初的时候考虑过将详情页静态化——因为需要SEO的缘故,这样可以让我们降低SEO带来的复杂度。

MicroServices

后来,我也在我的博客上解耦了两部分,为了更快的访问首页——将首页独立出来,不使用JS,直接使用Pure.css来担重任;在其他页面里使用Material Design Lite作为UI部分。

有一点值得考虑的是:对于微服务架构来说,在一个系统的不同部分使用不同的技术栈是一种不错的体验;而对于一个前端团队来说,在同一个系统中使用不同的技术栈就不是一种不错的体验。

API设计——应该变得简单

Backend

如我们所见的Spring Boot已经变成推荐采用的程度了,按雷达上的习惯用语:“我们已经在多个项目上使用这个框架”——反正我最近的项目都是用这个框架。如果你考虑使用 Java,那么一定不要错过这个框架,以及使用这个框架来实施前后端分享。

对于大部分不需要考虑SEO的应用来说,将后台变成一系列RESTful的API并不是一件复杂的事,但是在后台API上的设计就变成一件麻烦的事。因此尽管在实践的过程中有契约作为保证,但是不一定是可靠的。作为一个前端程序来说,我们在调用后台API的过程中,总会遇到这样、那样的问题。除此,还有接口不好用的问题——“要是你可以在这里使用超媒体API,那么我的代码就会更加简单了”。

因此在 API 设计上,雷达上给出了两个不错的案例:

强化后台查询

GraphQL

代表例子就是Facebook的GraphQL,它是在Facebook内部应用多年的一套数据查询语言和 runtime。原本为了请求一个用户及其好友信息,需要发起多个API请求。现在,我们只需要在客户端拼装好对应的Query语句,在这个语句里将大部分需要查询的东西写好,即 JSON格式的数据,然后发给服务端来处理。而在我们客户端上,我们所获取到的结果都是我们所需要的,不需要再做特殊处理了。

这一切,看上去很美好——除了,在客户端上拼查询语句。

过去,我们使用搜索引擎来搜索数据,就需要在前端拼好对应的Query,再传给后台API,由后台API返回我们需要的结果。在这个过程里,我们在Query做一些对应的数据处理。

反正,他们都是使用查询语言来搜索结果。如果你考虑使用QL的话,不妨做一层Wrapper,以后好做迁移。

前后端同时优化

Falcor

Netflix在这样复杂的API请求下,创建了自己的库Falcor——它可以从多个数据源获取数据,并在服务端上汇总成一个JSON model;在客户端上,请求时我们只需要加上对应的参数即可——可以将多个请求合并到一起,也可以只针对某一个部分发出请求。这样可以降低发出多个请求所带来的复杂度。

我想,一种最实用的做法:就是将一些更新频率较低的API合并成一个大的API(大部分人都会这样做吧)。

简化的后台——无服务器架构

ServerLess

除了上面的这些内容,后台还有一些东西蛮好玩的,其中一个就是Serverless架构,即无服务器架构。不过,这种架构目前在国内运行起来还是有点难度的,缺少一系列的配套措施。如在这期的雷达上,Auth0可以为我们提供一个授权服务,以及AWS Lambda可以直接使用 AWS系列云服务来对数据进行处理。

关于这期技术雷达我就不多说了,读者可以自己去看。点击原文就可以获取最新一期ThoughtWorks技术雷达。

那么未来,你想玩哪种技术。

Share