Clojure China

「分享」专访庄晓丹:Java 程序员眼中的 Clojure

share
clojure
#1

庄晓丹, LeanCloud 后端工程师,目前主要使用 Clojure 语言从事移动服务后端研发工作,曾经在企业信息、Web 游戏以及电子商务企业从事软件研发,主要关注分布式系统、移动后端架构和性能优化、Clojure 等函数式语言实践等领域。

近日,CSDN 采访了庄晓丹,请他分享基于 Clojure 开发的 LeanCloud 核心技术,以及丰富的 Clojure 开发经验。

“Java 语言相比,Clojure 的优势我愿意归纳为:生产效率的提升”,庄晓丹如是说。

CSDN:请先自我介绍下,目前所在的公司以及所负责的领域。

庄晓丹:我目前在 LeanCloud 公司负责产品研发,主要从事后端服务的开发工作。

CSDN:团队现在有多少人?你们是如何分工的?

庄晓丹:我们的研发团队总共有 17 个人,分成北京和苏州昆山两个办公室。一部分同事主要从事客户端 SDK 研发工作;一部分同事主要从事 LeanCloud 后端服务的研发,还有几位同事负责运维和部署等工作。

CSDN: LeanCloud 是个什么样的项目?主要功能有哪些?

庄晓丹: LeanCloud 提供一站式的后端云服务包,涵盖对象存储、文件存储、用户帐号系统、消息推送、移动统计以及聊天等移动开发需要用到的主要功能。此外还提供一些小组件,比如第三方平台登录、用户反馈组件等,来帮助开发者快速开发应用。我们的 SDK 也覆盖了 iOS、Android、Web、Unity3D 等主要平台。

CSDN:与其他云服务平台相比,它有哪些优势?

庄晓丹:作为 BaaS 服务,很重要的一点是以开发 API 的方式提供易于使用、稳定的后端服务,用户无需操心硬件、数据库软件、缓存、容灾、运维等等后端开发的“琐事”,而专注于利用 API 来完成所需要的业务逻辑,并且可以轻易地跨平台使用。此外,我们希望提供的是一站式的服务,打包整体开放给开发者,免于各式各样服务集成的痛苦。

CSDN:LeanCloud 是采用哪种语言开发的?它的核心技术架构有哪些?

庄晓丹:LeanCloud 采用了多种语言混合来构建整个后端系统,包括 Clojure、Java、Node.js、Scala 。其中 Clojure 构建了整个网站门户、存储开放 AP I、推送、聊天等核心服务,Node.js 构建了云端代码服务(类似应用代码托管),我们还使用 Scala 编写的 Spark 任务来处理离线数据分析,此外,还有大量的统计类 MapReduce 任务使用 Java 编写并运行在 Hadoop 集群上。不同服务之间使用 RESTful 协议、RPC 框架或者队列进行通信。

LeanCloud 的整个后端架构是一个水平可扩展的设计,所有服务都以集群的方式运行,我们可以轻易地通过添加节点来扩容整个服务的处理能力,得益于 Clojure 的 nREPL,我们也能做到核心代码的热替换。

CSDN:你之前是 Java 技术领域的实践者,为何选择弃 Java 转投 Clojure ?与 Java 相比,Clojure 有哪些优势?

庄晓丹:“放弃” Java 有点言过其实,在接触 Clojure 并学习之后,刚好有这样的机会可以在工作里使用和实践,自然而然地慢慢地脱离 Java 语言,而专注于使用 Clojure 语言进行开发工作。此外,Clojure 程序员无法真正的“放弃” Java ,因为Clojure语言本身乃至类库都是寄生于 Java 之上,换句话说,仍然是每天都在同 Java 平台打交道,只是用另一种语言。

与 Java 语言相比,Clojure 的优势我愿意归纳为:生产效率的提升。

从表面上看,相比 Java,同样的代码片段,Clojure 代码总会显得更简洁,我们做过估计,同样的项目,Java 的代码行数和 Clojure 代码行数是 5:1 甚至更高的比例。

其次,Clojure 的不可变数据结构,可以让你避免更多隐藏的修改带来的副作用 Bug,鼓励你编写无副作用的小函数组合起来,因为没有状态信息的干扰,这样的代码也将更易于测试。

内置 REPL 也方便你随时做各种代码尝试,nREPL 远程执行还可以实时查看应用的实时运行信息、变量当前状况甚至代码热替换修复 Bug 等。Clojure 的工具链都相当轻量,鼓励一种轻松编程的氛围。

Clojure 源自 Lisp 的强大的宏能力,可以让你方便地编写 DSL,包装各类领域问题,写出优雅的解决方案,一个简单的例子比如 korma 这个类库就是对于 JDBC 的 DSL 包装。

从另一个角度看,Java 语言及其模式是以对象为核心、以类型体系为基础来做方法派发,利用接口抽象和多态来隔离变化。比如桥接模式,变化有多少个维度,就用多少个接口将每个维度抽象起来,然后将变化隔离到接口实现类中,将业务逻辑表达在接口之间的联系上,将变化隔离在接口的实现上。对象是重中之重,封装了状态,隐藏了信息,附加上类型信息做动态派发,“不堪重负”,并且可变的状态也引入了难以并发和难以测试的痛点。

而在 Clojure 里,你更多会将变化表现在数据的变化上,数据从用户那里过来,经过每个“阶段”的处理,变化成最终想要的结果,然后返回给用户。每个“阶段”理想状态下都是无状态的、可以单独测试、可以并发执行的,变化的数据本身也是使用不可变数据结构“串联”起来,没有并发修改的隐患。本质上,将业务逻辑表达在数据的变化上。

CSDN:有人说,一个有 Java 背景的爱好者,学习 Clojure 具备得天独厚的优势,你怎么看?

庄晓丹:我非常认同这个观点,没有 Java 经验当然可以学好用好 Clojure,但是有丰富的 Java 经验,会让你更方便、更深入的使用 Clojure。就像前面提到的,Clojure 语言和类库都是基于 Java 平台,它的很多类库也是 Java 类库的直接封装。Clojure 提供了方便和快捷的操作Java类库的方式,如果你熟悉 Java,在使用 Clojure 的时候也将如鱼得水。

其次,Clojure 的应用也是运行在 JVM 之上,Java 性能优化特别是 GC 调优、VM 参数优化等知识也能帮助你去优化 Clojure 应用的性能。

最后,Java 语言的经验可以让你有针对性地比较两门语言、两种编程风格(面向对象 VS. 函数式)的优劣势,在未来学习其他语言的时候,这些编程语言方面的认识也将帮助你更快地上手。

CSDN:你最喜爱的开发工具有哪些?在日常工作中会用到哪些?

庄晓丹:工作中主要的开发工具是 GNUEmacs 。Emacs 刚开始的学习曲线比较陡峭,但是在强制自己使用一段时间后,你会方便这是一个非常强大的开发工具。

其次,Clojure 开发,Leiningen 是最主要的项目构建工具,利用它做依赖管理、构建、打包等日常构建任务。

Cider 是 Clojure 在 Emacs 里一个交互式的开发环境,结合其他插件,提供了编译、求值、测试、REPL、代码模板和代码自动完成等日常开发所需要的大多数功能。

此外,我很喜欢ack这个代码搜索命令,支持多种编程语言的搜索,提供丰富的搜索模式。在这些主要工具之外,日常更多的是使用Mac上一些优秀的App,比如Alfred、Dash、Mou.app等。

CSDN:给学习 Clojure 的开发者分享下经验吧。

庄晓丹:如果没有其他函数式语言编程的经验,Clojure 的学习将是先难后易,一开始会遇到很多新的概念和挑战,很多对 Clojure 感兴趣的人可能刚开始就被括号、各种奇怪的符号(特别是编写宏的时候)、函数式编程所吓跑,这时候就需要特别鼓励大家坚持看下去,先尝试用 Clojure 做一些实际的编程小任务,比如实现一些算法、编写一个 Web 小程序、增删改查数据库等,来慢慢找到感觉。在这里要推荐下 4clojure 这个做题网站,通过这些题目和其他人的解答,你可以更加迅速地熟悉 Clojure 语言、类库和函数式编程。

过了这个阶段,你会发 Clojure 的核心是极其简练的,所谓“奇怪符号”寥寥无几。接下来不妨阅读一些函数式编程方面的介绍性资料,或者 SICP 这样的系统性的书籍,来加深对函数式编程的理解,你对 Clojure 的使用将更加得心应手。

除了语言和类库之外,还需要加强对 Clojure 工具链的熟悉,寻找一个趁手的开发工具并坚持使用,了解各种快捷键和插件。订阅社区的邮件列表,及时了解社区动态。Clojure 中国社区欢迎各位加入。如果过去没有过 Java 开发的经验,你还需要去了解下 Java 平台的相关知识,有兴趣还可以深入学习下 JVM 方面的知识。

此外,非常鼓励大家从 Clojure.core 这个标准库入手阅读 Clojure 的源码,从中可以学习到很多语言的惯用法,在高阶函数、宏等漂亮外衣之下的运行机理,更深入地掌握 Clojure 语言。

以上是我对 Clojure 学习的一点粗浅交流,欢迎交流,谢谢。

本文为CSDN原创文章,原文发表于→CDSN

4赞
#2

好像是很久以前的讲话,很不错