微信号:infoqchina

介绍:有内容的技术社区媒体

从技术、平台、工具、语言&框架等四大方面,详解技术未来的趋势

2017-03-29 08:01 ThoughtWorks
作者|ThoughtWorks
编辑|小智
ThoughtWorks 已于昨日发布了最新一期的技术雷达,InfoQ 第一时间拿到了先手资料,提取了朋友们最感兴趣的内容整理成文,以飨广大读者。本文将从技术、平台、工具、语言&框架等四个方面,为你详解技术未来的趋势。
写在前面

ThoughtWorks 中一群资深技术领导组成的ThoughtWorks 技术顾问委员会 (TAB) 创建了该雷达。 他们定期开会讨论 ThoughtWorks 的全球技术战略以及对行业有重大影响的技术趋势。这个雷达以独特的形式记录技术顾问委员会的讨论结果,为从开发人员到 CIO 在内的各路利益相关方提供价值。 这些内容只是简要的总结, 我们建议您探究这些技术以了解更多细节。

这个雷达是图形性质的, 把各种技术项目归类为技术、 工具、 平台和语言及框架。 如果某个条目可以出现在多个象限, 我们选择看起来最合适的象限。 我们还进一步将这些技术分为四个环以反映我们目前对其的态度。要了解关于雷达的更多背景, 请参见 thoughtworks.com/radar/#/faq

注:公众号对话框回复关键词:「雷达」,下载完整版技术雷达!

这期技术雷达亮点
会话式用户界面和自然语言处理

人机对话——这种新的应用程序交互方式——伴随着苹果Siri 、 微软小娜和谷歌 Allo 这样的工具, 像风暴一样席卷了整个IT生态圈。 随后这股风暴继续延伸到了家用设备, 例如亚马逊的 Echo 和谷歌的 Home 。 虽然构建会话式自然语言用户界面会遇到许多新的挑战, 但是它所带来的益处是很显著的。 亚马逊 Echo 的研发团队故意在该产品上省去了屏幕, 从而迫使团队成员重新思考许多人机交互的场景。

这种 “会话式” 的趋势不仅限于语音。 随着消息应用已经增长到可以主导电话通话和工作场所, 我们看到了一些在智能聊天机器人协助下所发生的多人会话。 随着这些平台的不断改进, 它们将逐渐学会理解会话的上下文和会话意图,从而让人机交互更加逼真和引人入胜。市场和主流媒体对这个领域的兴趣激增, 增加了开发者对这种新的个人 “外部皮层” (exocortex) 交互模式的兴趣。

智能即服务

最近, 一系列被我们称之为 “智能即服务” (intelligence asa service) 的平台已经爆发。 这些平台都与各种强大的技术领域密切相关, 从语音处理到自然语言识别、 图像识别和深度学习。

几年前, 要想具备这些能力还需要花费很昂贵的资源, 但现在已经有开源或者基于 SaaS 平台的解决方案了。 这也意味着 “云计算之战” 逐渐从存储和计算能力向认知能力转变。

之前 Kubernetes 和 Mesos 这两个差异化工具的开源就是这场战争的见证。在这个领域的所有大型厂商都有自己的产品, 与此同时, 一些利基厂商的产品也值得尝试。 尽管我们对于这些服务在伦理和隐私方面的影响持保留态度, 但我们相信创新地使用这些强大工具会带来很好的前景。 我们的客户已经开始在新的视野上研究如何在他们的业务里把人工智能和商品的认知能力结合起来。

开发者体验成为新的差异化竞争优势

多年来, 用户体验设计一直是技术产品公司持续关注的关键差异化竞争优势。 而现在面向开发者的工具和产品的快速崛起, 加之工程人才的稀缺, 迫使这些公司也开始关注开发者体验。

越来越多的组织依据所减少的 “工程摩擦力” (engineeringfriction) 来评估云产品, 并将 API 视为产品来精心打磨, 且专注于工程生产力来提升团队效率。 在 ThoughtWorks , 我们一直执着于高效的工程实践, 以及那些能让开发者们轻松工作的工具和平台。 我们非常激动地看到业界开始采纳这些想法。

这些关键技术包括: 将内部基础设施作为一种产品, 令其具有足够的吸引力来与外部产品进行竞争; 专注于自助服务系统; 理解所开发的 API 的 “开发者人机工程学”(developer ergonomics) ; 对遗留系统进行封装; 以及对开发者的 “持续用户共情研究” (ongoing empathetic user research) 的投入。

平台的崛起

技术雷达的主题来自于审查过程中的观察和交流。 在最近一次编辑技术雷达的过程中, 我们注意到了进入平台象限的新条目的数量。 我们认为这表明了平台在软件开发生态系统中有着更广阔的前景。

那些引人注目的硅谷公司向我们展示了构建一个合理的平台如何带来显著的效益。 他们成功的一部分原因来自于找到适用于自身的封装和能力水平。 从技术雷达所强调的高级功能 (如自然语言处理) 到基础设施平台 (如亚马逊) 来看, 越来越多的 “平台思维” 出现在整个技术生态系统中。

当要通过产品化的 API 提供一些精选的功能时, 企业开始考虑采用平台的方式。 开发团队在集成和提升开发人员体验方面有了更多的思考。 似乎业界终于走上了将 “打包、 便利和有用” 进行合理组合这样一条道路。

我们喜欢这样来定义平台: 平台应该提供一个自助服务 API, 并且使之在团队环境中容易配置和创建——这很好地与 “开发者体验” 这样一个新兴的主题相呼应。 我们期望在不久的将来, 平台的定义和功能将得到进一步的完善。

盛行的PYTHON

Python 这门语言总是不断出现在有趣的地方。 作为一门易用的通用编程语言, Python 在数学和科学编程领域具有坚实的基础。 这使得它一直以来都为草根阶层的学术研究社区所采用。 最近, 围绕人工智能商品化及其应用的行业趋势, 以及 Python 3 的成熟, 给 Python 社区注入了新的活力。

这一卷的雷达重点介绍了一些能够促进 Python 人工智能生态圈发展的库, 其中包括机器学习领域的 Scikit-learn ,采用智能数据流图的 TensorFlow 、 Keras 和 Airflow , 以及通过自然语言处理实现会话识别应用程序接口的 spaCy 。我们越来越多地看到 Python 正在缩小组织内科学家和工程师之间的距离, 并减弱了他们过去在最喜爱工具方面的偏见。

诸如微服务和容器的架构已经简化了 Python 在生产环境中的执行。 工程师现在可以通过与语言和技术无关的 API ,部署和集成由科学家们特别创建的 Python 代码。 相比将特定语言 (比如 R 语言) 翻译到生产环境上的现有做法, 这种流动性是朝构建研究人员和工程师之间一致的生态系统迈出的重要的一步。

一、技术
将 API 当做产品

企业已经全然接受通过 API 把业务能力暴露给内外部开发者。 API 通过重组核心能力承诺了快速试验商业创意的能力。 但 API 与普通企业集成服务有什么区别呢? 其中的一个区别就是将 API 当做产品 (APIs as a product) , 即使 API消费者是企业内部的系统或开发人员。 构建 API 的团队应该理解客户的诉求, 并且让产品始终能够满足这些诉求。 可用性测试 (Uasbility Tesing) 和用户体验研究有助于理解API的使用模式, 并将产品思维带入到 API 中, 从而得到更好的 API 设计。 API 应该有一个负责任, 负责关注用户并持续改进。 在我们的经验中, 缺乏产品导向会使普通企业集成和基于 API 平台构建的敏捷业务存在差异。

从代码中解耦秘密信息的管理

在往期的技术雷达里我们提到了诸如 git-crypt 和Blackbox 这样的工具可以帮我们保证源代码内部的秘密信息安全。 从代码中解耦秘密信息的管理是我们提醒技术人员存储秘密信息还有其他选项的另一种方式。 例如,HashiCorp vault 持续集成服务器和配置管理工具都提供了脱离应用程序代码的秘密信息存储机制。 这两种方法都切实可行, 我们推荐你在项目中至少使用一种。

构建 API 的团队应该理解客户的诉求, 并且让产品始终能够满足这些诉求。 可用性测试(Uasbility Tesing) 和用户体验研究有助于理解API的使用模式, 并将产品思维带入到 API中,从而得到更好的 API 设计。— APIs as a product

封装遗留系统

在遗留代码上工作, 特别是大型的单体应用, 是最糟糕的开发体验之一。 尽管我们警告不要扩展和积极维护遗留单体应用, 但它们仍然是各种环境中的依赖。 开发人员往往低估了这些依赖开发所需的成本和时间。 为了减少摩擦, 开发人员采用虚拟机镜像或 Docker 容器来创建遗留系统及其配置的镜像。 其目的是为了封装遗留系统并供开发人员在本地运行。 从而消除重新构建、 重新配置和共享环境时候对遗留系统的需要。

在理想情况下, 团队通过流水线生成相应的遗留系统镜像。 开发人员可以通过更可靠的方式在自己的沙盒环境中编排并运行这些遗留系统。 虽然这种方法可以减少每个开发人员花费的总时间, 但是当拥有下游依赖的团队不愿意创建遗留系统镜像供他人使用时, 这种方法的成效会很有限。

渐进式 Web 应用

渐进式 Web 应用 (PROGRESSIVE WEB PPLICATIONS)(PWAs)的增长是把用户带回 Mobile Web 以回应 “移动应用疲劳” 的最新一次尝试。 它最初由 Google 在2015年提出, PWA 是利用了最新技术的优势来组合出最好的 Web和原生移动应用程序的 Web 应用程序。 它使用了一系列的开放标准技术, 比如 service workers , app manifest 以及缓存和推送API 。 我们可以通过这些技术创建出与平台无关的移动应用以及原生应用的用户体验。 这平衡了 Web 应用和原生应用各自的优缺点, 并帮助移动应用开发者打破了应用商店的限制去接触用户。 你可以把 PWA 想作是具备原生应用功能和观感的 Web 站点。

无服务器架构

无服务器架构这种方法通过短暂存在的计算能力来替代长期运行的虚拟机。 这种计算能力会根据服务请求而存在, 并在服务完成后立即消失。 我们的团队非常喜欢无服务架构这种方法。 这种方法工作良好, 我们认为它是一种有效的架构选择。 值得注意的是这种方法并不是一种 “要么全部采用,要么全部不用” 的方法。 我们的一些团队已经使用无服务器架构来部署新的系统模块, 而对于其他模块则仍然使用传统的架构。 虽然 AWS Lambda 几乎是 无服务器的代名词,但是其他的云计算服务商都提供了相似的产品。 我们也建议评估一些利基玩家, 例如 webtask 。

会话感知 API

诸如 Amazon Alexa , Google 语音服务和Siri 这样的技术已经大大降低了基于语音的软件交互的门槛。 然而, 想要在许多现有的API 之上构建更多的会话式输入 (语音或文本) 还很困难。— Conversationally aware APIs

诸如 Amazon Alexa , Google 语音服务和 Siri 这样的技术已经大大降低了基于语音的软件交互的门槛。 然而, 想要在许多现有的 API 之上构建更多的会话式输入 (语音或文本)还很困难。 特别是在涉及到有状态的交互场景, 且后续的交互又需要知晓整个会话上下文时。 在这种风格的交互中, 如果我们想要询问从曼彻斯特到格拉斯哥的火车, 就可以直接问 “首班列车何时出发? ” , 而不必再次给出会话的上下文。

通常这个上下文将出现在我们发送回浏览器的初始响应中。 但在语音接口的情形下, 我们需要在其他地方处理这个上下文。 会话感知 API 是后端为前端服务模式的示例, 其中前端是语音聊天平台。 这种类型的 API 可以在代表语音前端呼叫底层服务时, 通过管理会话的状态来处理这种交互方式的细节。

游戏领域之外的 VR 应用

虚拟现实的想法已经存在了50多年了, 随着计算技术的不断进步, 许多想法都已被炒作和探索过。 我们相信该领域目前已经达到了临界点。 去年, 市场上已经发布了价格适宜的、 面向消费者的 VR 头戴式设备, 再加上现代的图形显卡为这些设备提供了足够的性能以创造身临其境的体验。 虽然这些头戴式设备目前主要还是针对视频游戏爱好者, 但我们相信, 它们在游戏领域之外的 VR 应用上还存在许多的可能性。 但是, 没有制作视频游戏经验的团队不应低估创建一个好的3D模型和纹理所需要的时间和技能。

二、平台
LINUX 安全模块

“最小权限原则” 鼓励我们限制软件只访问他们需要的资源。 然而在通常情况下, Linux进程可以执行其运行的用户可以做的任何操作, 包括绑定端口和执行脚本。 LINUX 安全模块 (LSM) 框架允许将安全性扩展至内核, 例如 Linux 使用该模块来实现 MAC 。 SELinux 和 AppArmor 是最著名的 LSM 兼容实现, 它们随 Linux 内核一起发布。 我们建议团队学习使用这些安全框架 (这就是为什么我们将其放置在采用) , 它可以帮助团队评估谁可以访问共享主机上的哪些资源 (包括其中的服务) 。 这种保守的访问管理方法将帮助团队在其SDLC流程中建立更好的安全性。

AMAZON API GATEWAY

AMAZON API GATEWAY 允许开发者把 API 服务暴露给互联网的用户。 它提供了 API 网关的常见功能: 流量管理,监控, 认证和授权。 我们的团队在把它和 AWS Lambda 集成作为无服务器架构的一部分上有很积极的评价。 另一方面, 我们在把它用作一个运行在 EC2 上的 HTTP/HTTPS 端点之前的更通用的前置网关时遇到了更多挑战, 对我们造成了阻碍的是 VPC 的缺乏互动性和在网关上建立客户端证书验证的困难。 基于这种混合的使用体验, 我们建议团队结合使用 AWS API Gateway 和 Lambda 。 但在更通用的配置里使用它时要评估其适用性。

OPENTRACING

随着单体应用被更复杂的 (微) 服务生态系统所取代, 跨越多个服务的请求追踪正成为常态。 幸运的是OPENTRACING 正在迅速成为分布式追踪的事实上的标准。 它由Uber, 苹果, Yelp和各种其他大厂商开发, 它支持多种分布式追踪系统, 如 Zipkin , Instana 和 Jaeger 。OpenTracing 标准目前提供厂商中立的六种语言实现: Go, JavaScript , Java , Python , Objective-C , 以及 C++ 。

MESOSPHERE DCOS

MESOSPHERE DCOS 是一个基于 Mesos 构建的平台。它将底层基础设施抽象出来, 适用于容器化的以及没有运行在 Docker 内的应用程序。 这可能对更多 “适量部署”(modest deployments) 而言是过度的, 但是我们开始看到它在商业版本和开源版本中的成功。 我们尤其喜欢它在不同的云计算供应商和专用硬件之间的可移植性, 因此可以使你摆脱对于单一容器编排框架的依赖。 虽然升级可能会比我们想要的更复杂一点, 但整个技术栈正在变得更加稳定。

Tango

由于对硬件的要求和构造虚拟世界的复杂度门槛较高, 除了虚拟现实 (VR) 之外, 替代现实 (AR) 和混合现实 (MR) 也在去年进入主流。 Pokémon Go 的风靡则证明了: 普通的智能手机也足以创造引人瞩目的 AR/MR 体验。 TANGO 是一种用于手机的新型硬件传感器技术, 进一步增强了在手机上实现 AR / MR 的可能性。 它允许应用程序获取用户周围的详细的 3D 测量数据, 以便在摄像头输入流中放置和呈现更有说服力的虚拟对象。 第一批使用 Tango 技术的手机现已上市。

语音平台

诸如 Amazon Alexa 和 Google Home 这样的语音平台目前处在技术界的风口浪尖 技术成熟度曲线 (hype cycle) 的炒作顶峰, 甚至有人预言, 未来会话式的语音接口会无处不在。 我们已经有把对话式UI集成到产品中的经验, 并且看到了这种新的交互方式对接口设计的影响。 Alexa 则全部从头设计, 他们舍弃了屏幕并将会话式用户界面视为一等公民。 但现在要相信这样的炒作还为时过早, 我们期待更多的大厂商进入这个领域。

WEBVR

WEBVR 是一组可让你通过浏览器访问 VR 设备的实验性JavaScript API 。 它已经获得了技术社区的支持, 并有正式版本和每日构建的版本可用。 如果你想在浏览器中构造VR 体验, 那么 WebVR 将会是一个不错的开始。 此项技术以及相关补充工具, 例如 Three.js , A-Frame , ReactVR ,Argon.js 和 Awe.js 都能够为浏览器带来 AR 体验。 除了互联网委员会标准以外, 该领域中的各种工具也将有助于促进 AR 和 VR 更广泛的应用。

三、工具
FASTLANE

Web 应用程序开发者在简化和自动化各种应用程序的工作流程时很容易, 他们可以从各种成熟的解决方案中选择最合适的方案来自动化发布流程。 但是, 当在开发移动应用程序时, 我们需要处理两个不同的操作系统, 处理两种完全不同的构建, 测试, 分发, 生成屏幕截图, 签名和发布应用程序的方式。 为了解决这个痛点, 我们的团队采用了FASTLANE 作为自动化 iOS 和 Android 应用的发布流程的工具。 通过一些简单的配置和多个发布流水线, 他们就实现了移动开发的持续交付。

AIRFLOW

AIRFLOW 是一个用来通过编程创建、 调度和监控数据流水线的工具。 通过将有向无环图 (DAG) 以代码形式表现, 它主张可维护、 可版本化并且可测试的数据流水线。 我们在项目中利用这一配置来创建动态流水线, 使得数据工作流更加高效和清晰。 Airflow 可以很容易的定义你自己的操作符和执行器来扩展库, 以适配符合你的环境的抽象层次。

CAKE 和 FAKE

MSBuild 自从2005年推出以来一直是 .NET生态系统中的主要构建系统。 但是, 它遇到了我们以前在 Maven 中提到的许多相同的问题。 .NET社区已经开始开发MSBuild的替代品, 它更容易维护且更加灵活, 并能随着项目的增长更自然的演化。 CAKE 和 FAKE 是其中的两个备选方案。 Cake使用一种 C# 内置的 DSL, 而 Fake 使用 F# 。 在过去的一年里这两个项目都取得了显著的增长, 足以证明在 .NET 项目中它们是替代 MSBuild 编排常见构建任务的可行方案。

SERVERLESS FRAMEWORK

非常流行的 SERVERLESS FRAMEWORK 为无服务器风格架构的应用程序提供了项目脚手架和部署工具。 它的大部分使用场景都是基于 AWS Lambda 以及相关 AWS 产品。 Serverless Framework 为 JavaScript, Python, Java 和C# 语言提供了项目模板, 并拥有有一个活跃的社区为其贡献扩展插件。 此外, 它也向作为 AWS Lambda 替代品的Apache 孵化器项目 OpenWhisk 提供支持。

MOLECULE

MOLECULE 旨在帮助开发和测试 Ansible 的 Role 。 通过在虚拟机或容器上为正在运行的 Ansible Role 的测试构建脚手架, 我们无需再手工创建这些测试环境。 Molecule利用 Vagrant , Docker 和 OpenStack 来管理虚拟机或容器, 并支持 Serverspec 、 Testinfra 或 Goss 来运行测试。 在sequence facility model中的默认步骤包括: 虚拟机管理,Ansible 语法静态检查, 幂等性测试和收敛性测试。 虽然这是一个相当年轻的项目, 但我们看到了其蕴含的巨大潜力。

SPINNAKER

Netflix 把旗下的 Spinnaker 开源了。 它是一个微服务的持续交付平台。 相比其他的 CI/CD 平台, SPINNAKER 将集群管理和烘培镜像部署当作头等功能来实现。 它支持开箱即用的部署和多种云平台 (例如 Google Cloud Platform,AWS和 Pivotal Cloud Foundry ) 的集群管理功能。 可以把Spinnaker 集成到 Jenkins 里来执行构建任务。 我们喜欢Spinnaker 在云端部署微服务的率性做法, 可惜它的流水线只能通过用户界面而不是代码来创建。

YARN

YARN 是一个新的包管理工具, 它可替换现有 npm 客户端的机制, 同时兼容 npm 注册表。 如果使用 npm 客户端, 根据依赖库的不同安装顺序, 它会在 node_modules下得到一个不同的树结构。 这种非确定性的特点可能导致 “在我的机器上能工作” 的问题。 通过将安装步骤分解为解析、 获取和链接, Yarn 使用确定性算法和 lockfiles避免了这些问题, 从而确保重复安装的一致性。 因为它对已经下载的包进行缓存, 我们还看到在持续集成 (CI) 环境中的构建速度明显更快。

四、语言&框架
Python 3

PYTHON 3 引入了很多有用的特性, 这些特性和 Python2.x 不兼容。 它还移除了大量 Python 2.x 中用于向后兼容的功能, 这让 Python 3 更容易学习和使用, 而且和语言的其他部分更加一致。 根据我们在机器学习和 web 应用开发这样的领域中使用 Python 3 的经验显示, 语言本身以及大多数支持库都已经成熟到可被采用的程度。 我们可以 fork 已有的库并为其存在的小问题打补丁, 或者避免使用已经被放弃的不兼容的 Python 2.x 库。 如果你在使用 Python 做开发, 我们强烈鼓励你使用 Python 3。

REACTIVEX

分布式系统经常利用多线程、 基于事件的通信和非阻塞 I/O来提高整体系统效率。 这些编程技术提出了诸如低级线程、同步、 线程安全、 并发数据结构和非阻塞 I/O 等挑战。 开源的 REACTIVEX 库优雅地解决了这些问题, 提供了所需的应用程序管道, 并扩展了异步事件流之上的观察者模式。ReactiveX 还拥有一个活跃的开发者社区, 支持的编程语言越来越多, 最近支持的是 RxSwift 。 它还实现了绑定到移动和桌面平台的功能。

AVRO

AVRO 是一个数据序列化的框架。 它通过将 schema 与消息内容共同存放的方式来鼓励 schema 演进。 生产者可以编辑字段名称, 添加新字段或删除现有字段, 而 Avro 确保客户端可以继续消费消息。 Schema 允许每个数据被写入而没有额外开销, 促成了紧凑的数据编码和更快的数据处理。 尽管生产者和消费者之间无结构消息的交换形式可以很灵活, 但我们已经看到团队在部署期间遇到队列中出现无法处理的不兼容消息的问题。 我们在许多项目中使用了Avro , 并且建议仅在发送非结构化消息时使用它。

VUE.JS

在日新月异的前端 JavaScript 框架世界里, VUE.JS 作为AngularJS 的轻量级替代品占据了一席之地。 它是一个非常灵活——且没有预设主张——的库。 它围绕着模块化、 组件和响应式数据流等概念, 为构建交互式 Web 界面提供了一套工具集。 它的学习门槛很低, 这让初级开发者和新手很感兴趣。 Vue.js 本身并不是一套大而全的框架。 它仅专注在视图层, 因而可以轻松地和其他库或现有项目做集成。

CAFFE

CAFFE 是一个用于深度学习的开源库, 由伯克利视觉和学习中心开发。 它主要专注于计算机视觉应用的卷积网络。 对于计算机视觉相关的任务, Caffe 是一个可靠并且流行的选择, 而且可以从 Caffe Model Zoo 下载很多Caffe用户创建的开箱即用的成功模型。 与 Keras 一样,Caffe也是一个基于 Python 的 API 。 它们的不同之处在于, Keras 中的模型和组件是在 Python 代码中直接被创建的对象, 而 Caffe的模型是用 Protobuf 配置文件描述的。 这两种方式各有其优缺点, 并且可以相互转换。

POSTCSS 是一个基于 Node.js 的 JavaScript 框架, 它有繁荣的插件生态圈, 能够操作基于抽象语法树的 CSS 文件。 PostCSS 常常被误认为是一种预处理器 (如 SaaS 或者 Less ) , 然而我们发现, 它的实力来源于其丰富多样的插件所提供的功能, 包括语法检查 stylelint 插件、 交叉编译sugarss 插件) 、 命名改编以避免选择器冲突 ( modules 插件 ) 、 模板 CSS 代码生成 ( autoprefixer 插件 ) 、 文件压缩等等。 尽管插件的成熟度各不相同, PostCSS 本身仍然是一个简洁而强大的前端开发框架, 它能够像对待一个完整前端开发语言一样处理 CSS 。

注:公众号对话框回复关键词:「雷达」,下载完整版技术雷达!

今日荐文

点击下方图片即可阅读

从VS 2017谈起,解析微软技术生态进化之道


 
InfoQ 更多文章 从Visual Studio 2017谈起,解析微软技术生态进化之道 70%以上业务由H5开发,手机QQ Hybrid 的架构如何优化演进? 六问CTO,程序员的个人、职业成长如何抉择? Q新闻丨吴恩达宣布从百度离职,将开启在AI领域新篇章;Google开源新算法;RedMonk 2017 Q1 基础架构、终端优化、新玩法实现:QQ红包技术方案全解密
猜您喜欢 2015年微信公众号媒体价值研究 【Tip来8发】在Storyboard中去除UITableView多余的分割线 115个Java面试题和答案——终极列表(下) expfe技术周刊第1000期 浅谈领导力之二 - 授权与放权