CEO要学习写代码吗?

法国兴业银行的CEO在努力学习Python

偶然间看到一篇文章,法国兴业银行的CEO Frederic Oudea,说54岁的自己正在学习写代码

“数字市场瞬息万变,必须努力学习来适应变化。我们正在认真对待这一挑战,并认识到有必要改变模式,并在文化上接受新技术。对于我来说,了解编码手段的确切性也非常重要,所以我花了几个小时用Python编写代码,这是数据技术的两种语言之一。”

——法国兴业银行的CEO Frederic Oudea

Frederic Oudea并不是唯一主张学习写代码的CEO。Mana AHL的CEO Sandy Rattray,通用电气公司的前CEO Jeff Immelt,苹果的CEO Tim Cook,都持有此主张。

(图片来自:http://t.cn/R3uvOwL

技术出身的CEO们还将领衔下一个十年的技术发展

当今科技巨头的CEO们,微软的比尔盖茨与现任纳德拉,Google的拉里佩奇和现任皮查伊,Facebook的扎克伯格,Amazon的贝佐斯, Adobe的纳拉延,SpaceX的埃隆马斯克, 中国的雷军、李彦宏、马化腾,都是技术背景,能卷起袖子解决问题。

《软件随想录》中这样记录比尔盖茨,“你不要糊弄他,哪怕是一分钟,因为他是一个程序员,一个真正、现实的程序员”。作为十大巨头里唯一不是技术出身的马云,则在公开演讲中表示:“因为我不是技术出身,所以我对待技术的态度更严谨认真。”

这些工程师出身的CEO们,不仅仅在过去的10年中创造了商业奇迹,更重要的是,在未来10年的演进式交互、增强人类、平台兴起、安全和隐私、智能机器人等重要科技领域,这些科技巨头更是遥遥领先。在Google I/O 2018大会上,靠预约订座“语惊四座”的Google语音助手、应用AI+AR的提供智能推荐的Google地图导航,都令人惊叹不已。

非技术背景、没碰过代码的传统CEO们,面临难题

科技公司技术大会的狂欢,皮查伊们的风度翩翩侃侃而谈,不免让过去未学过技术、没碰过代码的传统CEO们,坐立难安。

除了意识上的焦虑和强烈的危机感,欠缺技术认知的CEO常常也会面临以下难题:

  • 无法评估创意风险,错失创新时机或者被人忽悠。传统公司深知创新的重要性,但当面临一些新创意时,因为不懂技术无法评价技术风险、判断可行性。要么被忽悠——“伟大的创意就差一个程序员了”,实际结果也许是这伟大创意只能写个科幻小说;要么“我们再看看吧”,错过最好的市场时机。
  • 无法做出新业务的成本核算,进行业务决策。很多传统企业里面IT很弱或者原来IT都是外包。自己也不懂的情况下,很难评估研发工作量、技术要求、研发节点,导致人员规模,成本核算都不靠谱。因而无法做出决策,指导战略项目的进行。
  • 无法构建业务必须的团队和能力。想建立一个符合要求的研发团队,可招人都不知道怎么招;想找一个懂技术的来当合伙人解决上述问题,却没有能力评估他是否有能力干这事。

CEO是否要学习写代码?扎克伯格说YES

虽然大多数人倾向于“CEO对技术有良好直觉和敏感性”就够了,但Facebook的CEO扎克伯格,却坚持CEO应该向开头提到的Frederic Oudea一样学习写代码。其中有三个理由值得深思:

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

  • 学写代码,能够提出好问题,“防忽悠”。“如果你聘请某人为你建造房屋,但你从未试图自己建造房屋,你将不知道合理的成本和应该花多长时间。任何涉及编码的项目都是如此。如果你没有知识基础,那么你有被误导的风险。花时间学习基础知识可以帮助你提出正确的问题,并确定你知道他们在做什么。”
  • 理解市场上的技术。阅读技术理论是一回事,辨别其是真正创新还是市场炒作是另一回事。任何一个新技术从提出到创造商业价值会经历一个烟斗曲线。在AI大火的2017年和全民热捧区块链的2018年,ThoughtWorks技术雷达则指出“太火的东西,我们往往需要克制对待”。技术商业化的时机是否真地来到?只有“亲手实践”一下才能领悟。
  • 学编程会迫使我们将自己置于“学习者”模式。过去线性逻辑的思维,在AI的时代,似乎不适用了。比如,过去谈起预测,大家就觉得应该预测得准确;当CEO想启动采纳机器学习技术时,出于惯性思维会问:“这个预测的准确率可以达到多少呢”。然而,这却是个错误的命题。“机器学习是一种优化任务。优化任务的目标不是找到‘正确’的答案,而是找到一个‘看起来不错’的答案。” 单看书很难理解,只有动手去了解背后的算法逻辑,动手让代码跑一跑结果,才能理解从此切换思维模式。将来类似的技术还会有很多,必须通过实践体验来学习适应新的思维模式。

对技术拥有好奇心、拥抱学习新技术,已经是CEO们的共识

是否真地要去写代码,可能是一个问号,但毫无疑问,“对技术保持好奇心、拥抱学习新技术,跟上技术趋势”已经是CEO们的共识。 麻省理工学院的研究科学家斯蒂芬妮沃纳说:“技术就是一切。”在她的研究结果中,数字技术深深扎根于业务中,其影响非常广泛,是CEO必须明确关注的问题。

商业云通信公司Vonage,不断发展的技术促使消费者的语音互联网协议(VoIP)平台在短短几年内发生了巨大的转变。该公司的CEO Alan Masarek,也是前谷歌高管,表示:“我们绝对需要去了解科技的任何变迁,了解如何最好地采用科技来改进我们的工作。”

麦肯锡的一份CEO指南中,则建议CEO应该深入了解软件开发的技术,学习软件产品的依赖的基础设施、如何开发和如何管理的具体实践。

我们曾看到一位传统公司的CEO,在他的案头,放着亚马逊的Echo语音设备,并很习惯地和语音助手Alexa时不时聊个天。

与其焦虑,不如“Just Do It”

未来就像一盒巧克力,不尝试怎么知道?如果你是有胆识的CEO:

1. 转变心态,勇于“承认自己的未知”

Celia Pronto是Casual Dining Group的CDO。他表示:“真正接受技术的人往往会问很多问题。他们知道‘承认自己无知’,并不可耻。”

硅谷著名数字营销公司SparkToro的CEO Rand Fishkin,在他的博客中也坦承:

我至今仍在为缺乏工作中的某些知识而极度的难为情。在做决策时,会问一些很傻丢面子的问题。但关键是,至少是对我,要承认自己是个无知,正确的看待这种批评,不再恐惧,敢于说“我不知道,但我会弄清楚。”

2. 以初学者心态,持续跟踪技术动态,发展对技术的良好直觉

对于精通技术的人来说,最大的好处就是在一个特定的商业环境中,围绕什么是战略性的,什么是非战略性的,有敏锐、良好的直觉。这需要强烈的好奇心,并养成通过技术雷达去了解技术趋势,持续跟踪技术动态的习惯,长期积累。了解大的技术板块,关键技术的现状、所处烟斗曲线的位置、商业场景、对自己组织的影响、自身需要什么样的人才和构建什么样能力等。即使不能真正动手实现技术,也能保证在需要决策时,可以提出正确的问题。

3. 深入了解技术,通过动手去体验建立“未来”思维

了解一个技术是如何从默默无闻发展到全民热炒,只有理清发展脉络,知道它目前所处的状态、技术成熟度以及市场支持度,才能不被泡沫所迷惑。

千闻不如一试,如小扎所说,抱着好奇心,不妨和身边的技术Geek一起,6月2日,来深圳技术雷达峰会,动手写写代码亲自体验下区块链、机器学习解决问题的过程,重构“学习”思维,获得最新技术洞察,增强对未来的信心。

Share

2018年5月期技术雷达正式发布!

ThoughtWorks每年都会出品两期技术雷达,这是一份关于技术趋势的报告,由 ThoughtWorks 技术战略委员会(TAB)经由多番正式讨论给出,它以独特的雷达形式对各类最新技术的成熟度进行评估并给出建议,为从程序员到CTO的利益相关者提供参考。

它比那些我们能在市面上见到的其他技术行情和预测报告更加具体、更具可操作性,因为它不仅涉及到新技术大趋势,更有细致到类库和工具的推荐和评论,因此更容易落地。经过半年的追踪与沉淀,ThoughtWorks TAB(ThoughtWorks技术咨询委员会)根据我们在多个行业中的实践案例,为技术者产出了第十八期技术雷达,对百余个技术条目进行分析,阐述它们目前的成熟度,并提供了相应的技术选型建议。

本期四大主题

浏览器增强,服务端式微

为了实现应用逻辑,浏览器在持续扩展成为部署目标的能力。当平台能照顾好横切关注点和非功能性需求的同时,我们注意到后端逻辑的复杂性有逐步降低的趋势。 WebAssembly 的引入为web应用创建逻辑提供了新的语言选择,同时把处理过程更加推向金属侧(以及GPU)。 Web Bluetooth让浏览器能够处理那些原本是本地应用才能处理的功能,而且我们看到越来越多像 CSS Grid Layout和 CSS Modules这样的开发标准正在替换掉自定义的库。对更好用户体验的追求,正在持续地把功能装进浏览器里,许多后端服务因此变得越来越薄,复杂性也因而降低。

不断蔓延的云环境复杂性

虽然AWS继续凭借令人眼花缭乱的新服务保持领先,但我们逐渐看到 Google Cloud Platform (GCP)和 Microsoft Azure 已经成为可行的替代方案。像 Kubernetes 这样的抽象层以及持续交付和基础设施即代码这样的实践,能支持更容易的演进式变化,从而促进云环境之间的过渡。但随着 PolyCloud (这允许组织根据差异化的功能在多个供应商之间进行挑选)以及越来越多的监管和隐私问题的出现,云策略必然会变得更加复杂。例如,许多欧盟国家现在依法对数据所在地做出要求。这使得数据存储的管辖权和其主机的管理策略成为评估云计算环境的新维度。云计算环境的可选范围也在扩大,比如在“函数即服务”和“管理更长寿命集群”这两者之间,就可以选择提供了“容器即服务”(CaaS) 的 AWS Fargate 这个有趣的选项。虽然各个组织对云技术的应用日臻成熟,但伴随使用这些新技术构建真实解决方案的,是逐渐蔓延又无法避免的复杂性。

信任但要验证

对于几乎所有的软件开发来说,安全问题仍然是至关重要的。当前我们观察到传统的“全局权限管理”的安全策略正在转变为更为细致的本地化方法。现在许多系统会在更小的领域内管理信任,并在不同系统之间使用一些新的机制创建可传递的信任。其理念正在由“永远不信任领域外所有东西”以及“从不验证领域内任何东西”转变为“信任但是需要验证领域内外任何东西”——也就是说可以假设和系统其它部分有本意良好的互动,但一定要在本地验证这份信任。这使得团队可以对自己的基础设施、设备和应用程序栈有高度的权限控制,从而实现高度可视化,并可以在必要时候提供高级访问护栏。类似 Scout2的工具以及 BeyondCorp 这样的技术反映了关于信任更成熟的视角。我们欢迎这种向本地化管理的转变,特别是当工具和自动化策略可以确保同等或更好的合规性时。

物联网的发展

物联网(IoT)生态系统持续稳步发展,关键成功因素包括安全和成熟的工程实践。我们看到了整个物联网生态系统的增长,从设备上的操作系统到连接标准,尤其是基于云服务的设备管理和数据处理。我们看到了一些成熟的工具和框架,支持良好的工程实践,比如持续交付、部署以及为实现最终广泛使用的大量其他必要实践。除了主要的云服务提供商——包括 Google IoT Core ,AWS IoT 和 Microsoft Azure IoT Hub ——像阿里巴巴和阿里云这样的公司也在大力投资物联网 PaaS 解决方案。可以从我们的 EMQ 和Mongoose OS 条目一瞥当今物联网生态系统的主流功能,它们也例证了 物联网 的良好的发展状态。

象限亮点抢先看

要记住,就像适用于其他软件领域一样,封装也同样适应于事件和事件驱动的体系结构。特别是,我们需要考虑一个事件的范围,以及我们是否期望它在同一个应用程序、同一个领域或整个组织中被消费。DOMAIN-SCOPED EVENT将在其发布的同一个领域内被消费,因此我们期望消费者能够访问特定的上下文、资料或引用,进而对事件进行处理。如果这个事件的消费在组织内更广泛地发生,且事件的内容需要有所不同,我们就要注意不要“泄漏”其他依赖领域的实现细节。

身份管理是平台的关键组件之一。外部用户在使用移动应用的时候,需要对其身份进行验证,开发人员需要被授权才能访问基础设施组件,而微服务也需要向彼此证明自己的身份。你应该考虑的是,身份管理是否真的有必要自己来搭建和维护。根据我们的经验,HOSTED IDENTITY MANAGEMENT AS A SERVICE( SaaS)这种解决方案更为可取。我们相信,像Auth0和Okta这样的顶级托管商可以在“正常运行时间”和“安全”两方面提供更好的SLA。也就是说,虽然有时候自行搭建和维护身份管理解决方案是一个现实的选择,特别是对于那些有操作规范和资源的企业来说,这个选择更为安全。但大型企业的身份解决方案通常包含更广泛的功能,例如集中授权、治理报告和职责分离管理等等。不过,这些担忧通常与员工身份更相关,特别是那些受遗留系统限制的企业,尤其如此。

在实践微服务的过程中,为了将后端资源进行聚合,我们实践了一个又一个的模式。之前,我们经常使用类似于Netflix Falcor这样的工具帮助我们实现BFF(Backend for Frontend ),现在很多项目已经开始使用GRAPHQL FOR SERVER-SIDE RESOURCE AGGREGATION。GraphQL可以让客户端直接使用特定的查询语句去访问BFF以获取数据。使用这项技术时,后端服务可以继续暴露 RESTful API,而GraphQL可以轻易的将这些服务所提供的资源聚合在一起,并且对客户端十分友好。我们推荐GraphQL是因为其简化了BFF和其他聚合服务的实现。

在高度分布式的微服务架构中,其可观察性有一个两难问题 —— 要么记录一切,代价是巨量的存储空间;要么随机抽样记录,代价是有可能丢失某些重要事件。最近我们注意到一项技术,它在这两种方案之间提供了一个折衷方案。通过跟踪请求头中传入的某个参数来LOG LEVEL PER REQUEST。使用跟踪框架(可能基于OpenTracing标准),你可以在一次事务中的多个服务之间传递一个相关的ID。还可以在开始事务时注入其它数据(比如期望的日志级别),并且与跟踪信息一起传递它。这样可以确保这些额外数据在系统中总是和相应的单个用户事务一起流动。这在调试时也是个很有用的技巧,因为服务可能会暂停或以逐个事务的方式进行修改。

Headless CMS( Content Management Systems, 内容管理系统) 正在成为数字化平台的常见组件。CONTENTFUL是一个现代化的 headless CMS。我们的团队已经成功把它集成到开发工作流中。我们特别喜欢其“API 优先”的特点,及其CMS as Code的实现。它支持强大的内容建模原语代码和内容模型演化脚本,并允许将其视为其他数据存储的schema,并将演进式数据库设计实践应用到 CMS 开发中。我们所喜欢的其他特性包括:默认包含两个 CDN以提供多媒体资源和 JSON文档,本地化的良好支持和与Auth0集成的能力(尽管需要做出一些努力)。

EMQ是一个可伸缩的开源多平台 MQTT代理。为了追求高性能,它使用Erlang/OTP语言编写,能处理数百万的并行连接。它能支持多种协议,包括MQTT、MQTT传感器网络、CoAP以及WebSockets,使其适用于物联网和移动设备。我们已经开始在项目中使用 EMQ,很享受其安装以及使用的便捷性,以及它能将消息路由到不同目的地(包括Kafka和PostgreSQL)的能力,还有它在监控和配置上所采用API驱动的策略。

TICK STACK是一个由开源组件组成的平台。使用它就可以轻松地收集、存储、绘制基于时间序列的数据(如度量和事件)来触发告警。TICK Stack 的组件包括:收集和报告各种指标的服务器代理telegraf、高性能时间序列数据库InfluxDB、平台的用户界面 Chronnograf,以及可以处理来自 InfluxDB 数据库的流式数据和批量数据的数据处理引擎Kapacitor。不像基于“拉”模型的Prometheus,TICK Stack是基于“推”模型来收集数据的。InfluxDB 组件是该系统的核心,同时也是目前最好的时间序列数据库。虽然这套组件栈基于 InfluxData ,而且需要使用诸如数据库集群这样的 InfluxData 企业版的功能,但在监控方面它仍然是一个不错的选择。我们正在一些生产环境上使用该平台,并且获得了一些很好的体验。

WEB BLUETOOTH能够直接从浏览器控制任意低功耗蓝牙设备。这样以前只能通过原生手机应用来处理的场景,现在也可以适用了。该规范由 Web Bluetooth Community Group 发布,并且定义了一个 API,通过蓝牙 4.0 无线标准发现设备并在设备间通信。 当前,Chrome 是唯一支持这个规范的主流浏览器。借助Physical Web和 Web Bluetooth,现在有了其他途径来让用户与设备进行交互, 且无需让他们在手机上安装另一个应用。这是一个令人兴奋的领域, 值得密切关注。

我们很开心使用 BACKSTOPJS 来做 web 应用的可视化回归测试。作为可视化比较工具,它的可配置视窗和可调节容错能力可以很容易定位到细微差别。它有很优秀的脚本功能,并且可以选择在无界面Chrome、PhantomJS 和SlimerJS 中运行。我们还发现,它在实时组件样式规范的基础上运行时尤其有帮助。

世界上有数不清的问题都可以用数学优化问题来表达,而其中可以用凸问题来描述的那部分常常能够得到有效解决。CVXPY便是一种针对凸优化问题所开发的开源Python嵌入式建模语言。它由斯坦福大学的学者维护,已经为数个开源和商业解决方案提供了功能齐备的安装套件。它的文档中也包含了许多能够引起开发者使用兴趣的例子。尽管有些时候,我们仍然需要类似Gurobi和IBM CPLEX这类商业解决方案,但CVXPY在原型设计阶段可以说所向披靡。在多数情况下,有CVXPY就足够了。同时,基于最近的优化进展,其开发者一直在为我们提供更多的扩展包(例如DCCP)和相关软件(例如CVXOPT)。

HELM是Kubernetes的包管理器。共同定义某个应用的Kubernetes资源集合被打包成图表。这些图表可以描述单个资源,例如Redis pod,或者全栈的Web应用程序:HTTP服务器、数据库和缓存。Helm 默认带有一些精选的 Kubernetes应用,维护在官方的图表仓库里。想要为内部用途搭建私有的图表仓库也很容易。Helm有两个组件:一个是称为Helm的命令行工具,另一个是称为Tiller的集群组件。保护Kubernetes集群是一个宽泛而微妙的话题,但我们强烈建议在基于角色的访问控制(RBAC)环境中搭建Tiller。我们在很多客户的项目中使用了Helm,它的依赖管理、模板和钩子机制极大地简化了Kubernetes中应用程序的生命周期管理。

ARCHUNIT是用来检查架构特征的Java测试库,比如包与类的依赖关系、注解验证、甚至层级一致性。它可以在你现有的测试方案中,以单元测试的方式运行,但目前只能用于Java架构。ArchUnit测试套件可以合并到C(I 持续集成)环境或部署流水线,使我们很容易地以演进式架构的方式实现适应度函数。

Hyperledger项目现在已经发展成包含一系列子项目的大工程。针对不同业务需求,可以支持不同的区块链实现方式。例如,Burrow专门用来实现带权限控制的Ethereum,而Indy更专注于数字身份。在这些子项目中,Fabric是最成熟的一个。当开发者们谈到使用 Hyperledger 技术时,实际上大多数时候是在考虑 Hyperledger Fabric。然而,chaincode的编程抽象相对底层,因为它直接处理账本的状态数据。此外,在编写第一行区块链代码之前,搭建基础设施也经常耗去很多时间。HYPERLEDGER COMPOSER 构建于Fabric基础之上,加速了将想法实现为软件的过程。Composer 提供 DSLs 来建立业务资源模型、定义访问控制和构建业务网络。使用 Composer,可以在不搭建任何基础设施的情况下,仅通过浏览器来验证我们的想法。需要明确的是,Composer 本身并不是区块链,仍然需要把它部署在 Fabric 上。

RASA是聊天机器人领域的新成员。 它并非使用简单的决策树,而是通过神经网络将用户意图和内部状态映射到回应上。Rasa 集成了自然语言处理解决方案(spaCy)。与技术雷达中的其他同类工具不同,Rasa是开源软件,可以自行托管,对于担心数据所有权的使用者来说 Rasa 是一个可行的方案。我们在内部应用中使用了Rasa Stack,效果良好。

RIBs即路由器(Router)、交互器(Interactor)和构建器(Builder)的缩写, 是来自 Uber 的跨平台移动架构框架。RIBs的核心思想是将业务逻辑从视图树中分离出来,从而确保应用程序由业务逻辑驱动。 可以将其看作是Clean Architecture模式在移动应用程序开发领域的一次应用。通过在原生 Android 和 iOS 应用上使用一致的架构模式,RIBs为应用提供了清晰的状态管理模式和良好的可测试性。尽管我们一直建议尽量将业务逻辑放在后端服务,不要将其泄漏到前端视图中,但移动应用程序非常复杂,RIBs可以帮助管理这种复杂性。

REACTOR是一个基于Reactive Streams规范的、用于开发非阻塞式应用程序的 JVM 库,支持 JVM 8 及以上版本。响应式编程强调将命令式逻辑转换成异步、非阻塞和函数式风格的代码,特别是在处理外部资源时。Reactor 实现了 Reactive Streams 规范,并且提供了两个不同的发布者API:Flux (0 到 N 个元素) 和 Mono( 0 或 1 个元素),可以高效地对基于推送的流处理进行建模。Reactor 项目非常适合微服务架构,并且为HTTP、WebSockets、TCP和UDP等提供了支持背压(backpressure)的网络引擎。

以上是我们在最新一卷技术雷达中随机摘取的几个Blips,欲获取整版技术雷达,请点击这里

Share

为什么我们要尝试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