放弃了C和Java,我为什么选择了JavaScript
发布时间:2017-06-20 17:19:33.0


万物互联时代,很多人仍然会有这样一个疑问:“为何物联网概念与技术提出并发展了多年,却感觉离我们仍很遥远?”。解惑这个问题之前,我们不妨先探讨智能手机为何会成为人们生活不可或缺的一部分。智能手机可基于 Android 或 iOS 操作系统,承载运行多款 App,嫁接起技术与用户之间的桥梁。

反观物联网之所以迟迟无法走进人们的生活,究其根本原因之一——应用的缺乏。在现如今这个软件吞噬硬件的趋势之下,作为一名开发者,该如何更为快捷简单的上手硬件应用开发?如何进行适合的工具选型?面对更为严峻的挑战,需要具备哪些新技能?

基于此,我们邀请了 Ruff CTO 郑晔和其他六位专家一起从物联整体架构、技术栈、应用开发平台到实战经验与安全方案进行「一天掌握物联网全栈开发之道」的技术分享,希望通过一天的时间,帮助开发者快速掌握物联网全栈开发之道( 在公众号后台回复“Ruff”参与活动 )。在此之前,我们特别采访了郑晔老师,请他从如何快速实现物联网应用的实战角度为我们答疑解惑。

Ruff CTO 郑晔

个人从业经历和团队背景

在 IT 行业沉浸十几年,我的职业生涯分成三个阶段:

在东软,学会了做软件,而不仅仅是写程序,但对于制作软件的过程,我产生一个疑问,怎么做软件才是合理的。

在 ThoughtWorks,我学会了敏捷/精益软件开发方法,能用一个非常顺畅的过程制作软件。在那段经历的后期,我也开始思考,希望能够做一些能够对行业有影响力的事,Moco 就是我在那个阶段开始的一个作品。

在 Ruff,就是我现在所供职的公司,我希望用自己这些年对技术的理解,改变 IoT 应用开发的现状,打造一个 IoT 版本的 Android。

从个人的经历上来看,貌似跨度比较大,从软件到硬件,但本质上,我有一个核心关注点,提高开发者的效率。

通过软件过程,把事情做对,节省时间,比如对敏捷软件开发方法的推广;

打造工具,简化开发者的工作,比如 Moco;

编写框架,为开发者提供新的抽象,比如 Ruff。

在我心目中有一个偏执的印象,只有为程序员提供支持,无论是工具,还是基础库,才算得上高手,例如开发了 Linux 和 Git 的 Linus Torvalds、开发了 MapReduce 的 Jeff Dean 等技术大牛。

我们团队囊括了各方面的人才,有从 Intel、NVIDA 这样大公司出来的底层技术高手,也有一些为开源操作系统做过贡献的人,还有一些在云服务厂商工作的技术者等。

Ruff 的技术团队现在大约有30人左右的规模:

硬件团队,负责 Ruff 的开发套件,以及一些合作项目中,硬件的设计与生产;

Ruff SDK 团队,负责硬件端 Ruff 的设计与维护;

云端团队,负责云平台的建设,甚至包括手机 App 的开发。

Ruff 设计宗旨及特点

Ruff 从始至终有一个理念:让 IoT 应用开发变得更简单。

Ruff 旨在让软件开发者能够进入到硬件开发的领域,因为软件开发者不懂硬件,Ruff 设计就是将底层的硬件概念隔离开,基于此,我们引入了设备抽象的概念,让开发者像用程序库一样操作硬件。

在我们看来,IoT 一定是未来重要的组成部分,但 IoT 发展得实在太慢,究其根源在于,能够在这个领域中开发应用的人太少,懂硬件的开发者稀缺,而懂硬件又懂应用的开发者更是少之又少。移动互联网领域已经为我们演示了如何为手机应用开发领域带来新的开发者,就是让软件开发者进入这个领域。对于属于未来的 IoT,我们希望看到同样的故事再次上演。

Ruff 现阶段解决的最重要的问题是,让软件开发者能够编写硬件应用,这等于为软件开发者打开一道新的大门。

与此同时,Ruff 还对研发效率非常关注。从入门开始,我们的开发者通常几分钟就能完成“Hello,world”级别的开发,而传统的方式中,开发者仅仅搭建环境这一项就需要很长时间。

再有,众所周知,测试驱动开发是更好的写代码方式,而这种方式的重点是小步快跑。在传统的硬件开发中,几乎是不可能的,主要是受下面几点所限:

传统硬件开发中,开发者必须把代码部署到硬件上,才能知道代码运行是否正常。

镜像烧写是一个比较漫长的过程,每次部署代码到硬件都需要很长时间。

所以,嵌入式开发者的习惯是,编写一段很长的代码,然后再部署到硬件上,慢慢调试,从研发效率的角度来说,这种做法效率极低。

在 Ruff 应用开发中,测试驱动开发是能做到的,因为 Ruff 有应用抽象,可以把硬件驱动和软件接口隔离开来,应用开发者只要保证软件接口正确的调用,硬件驱动开发者来保证驱动编写的正确性。这样,应用开发者只要保证应用逻辑的正确性即可,而 Ruff 提供了测试框架,让应用开发者可以在没有硬件的前提下,运行应用测试。应用在具体硬件上的测试,就成了集成测试,而不是开发者每步都要做的事情。

即便是硬件上的测试,因为 Ruff 分离了应用与系统,每次部署到硬件只要部署应用即可,系统无需重新部署,部署效率就大幅度提高了。

Ruff 物联网操作系统特点

侧重点的差异,现在各大公司出品的物联网操作系统大多是在原有的领域不断拓展,比如,华为的 LiteOS 是希望操作系统占用内存更少,ARM 的 mbed 希望让原来硬件工程师的工作稍微简单一点,所以,根本上来说,他们比拼的是存量市场,而 Ruff 要做的是增量市场,让软件工程师进入到硬件应用领域中来。

做增量市场的事情,谷歌是有经验的,因为他们做过 android。但在 IoT 领域的探索,谷歌现在做得还不够,之前他们曾经做过 Brillo,后面变成了 Android Things,但他们没有解决的问题是一样的,这两个框架采用依然是硬件开发者的语言(比如:GPIO、I2C),软件开发者不会用,硬件开发者很难从 C 改成 C++或 Java。

基于 Javascript 开发硬件应用优势及难点

优势

首先,C/C++ 是硬件开发者相对熟悉的语言,但是,以基础设施的角度来看,C/C++ 有些老了,对于现代软件工程的支持存在天然的缺陷,比如,C/C++ 至今没有一个好的包管理工具。对于硬件开发人员来说,可移植性是个永远的痛,每次拿到一款新硬件,让程序跑起来都是件痛苦的事情。

对于其它非 C/C++ 的语言,要应用在硬件上,主要面临两个问题:

运行时,能不能把这个语言跑在硬件上,尤其是内存很小的单片机上,像 Java 这样的语言,就被排除了。

流行程度,有一些语言运行时很小,比如 Lua,但对大多数程序员而言,这些语言都是陌生的。

综合这些因素,在我们开始 Ruff 的时候,JavaScript 是当时看来最好的选择,社区蓬勃发展,各种配套工具很丰富,有各种运行时实现可供选择。随后的发展也可以看出,后来在其它公司在这方面的探索,也选择了 javascript 这条路。

难点

用 JavaScript 开发硬件,第一步就是让硬件能够运行 JavaScript。大多数开发者可能不理解这里的难度,很多人以为我们就是把 Node.js 移植到硬件上,其实不然。node.js 能够运行 JavaScript 的基础是 V8,而 V8是一个为浏览器设计的 js 引擎,在 PC 上运行时,它几乎可以完全不顾虑资源进行性能优化,所以,V8占用的资源非常多,而硬件领域,资源是受限的,V8引擎根本运行不起来,也就是 Node.js 根本不能在资源受限的硬件上运行。所幸,JavaScript 社区发展足够好,有很多 JS 可供选择。所以,我们前期的工作等于基于一个引擎构建了一个另一个 Node.js。

以 Ruff 的设计目标而言,有一个重点是,如何设计一个面向应用开发者的抽象,把硬件设计细节全部隐藏起来。直到我们找到了下面这段代码:

$('#led').turnOn();

很多第一次看到 Ruff 的软件开发者,尤其是 Web 开发者看到这段代码时,第一反应通常是这和 jQuery 很像。这就是我们想要的感觉,开发者面对的是他们有些熟悉的东西,而不是完全地陌生,心里负担会一下子降下来,有兴趣进一步了解。

Ruff 前期遇到的问题,大多是这种“表达”层面的难题,比如,怎么写驱动。对我们来说,把驱动实现出来并不难,难的是怎么表达成开发者们熟悉的模式。我们也参考了大量已有的框架,最终选定了现在的做法,