这篇文章主要介绍了Erlang初学:Erlang的一些特点和个人理解总结,本文总结了函数式编程、一切都是常量、轻量进程、进程端口映射及典型缺点等内容,需要的朋友可以参考下

我对 Erlang 编程理念的理解:以分布式架构师的角度写代码。

函数式编程

Erlang 里面的函数是数学里面的函数:必须有返回值。 只要是函数必然有返回值,函数是一个过程,以英文的句号为函数结束符。 函数结束之前的表达式就是该函数的返回值。 所以这也是在 Erlang 里面的函数不会看到任何 return 语句的原因。 C++ 等其他语言的函数和函数之前可以通过共享变量来实现消息传递。 Erlang 里面的函数不可以,消息的传递通过函数的传入和传出。 也只是为什么 Erlang 号称天生之处并行处理的原因, 因为他们不共享变量,也就不需要加锁。

很多人听到函数式编程都会觉得高大上或者晦涩难懂。 因为函数是编程没有 for 循环语句, 但是在我看来,关键在于会使用【列表推倒】和【尾递归】来进行循环遍历。 说到函数式编程就会拿快速排序说事,下面这个示例是 Erlang 版本的快速排序:

代码如下:
-module(sort).
-export([qsort/1]).
qsort([]) -> [];
qsort([Pivot | T]) ->
    qsort([X || X <- T, X < Pivot]
         ++ [Pivot] ++
         qsort([X || X <- T, X >= Pivot]).

非常简洁,[Pivot | T] 就是拿列表的第一个元素当快排中的 Pivot 。

代码如下:
[X || X <- T, X < Pivot]

上式就是【列表推导】, 含义就是找出列表 T 中所有元素小于 Pivot 中的元素组成一个新的列表。 不过,这个例子显然性能不高,只是一个示例。

很多人一直在鼓吹函数式语言马上就要迎来朝阳, 但是在我看来,函数式编程永远只能是小众语言, 这就像当年的 lisp machine ,被鼓吹的天花乱坠还是夭折了。 现在主流的计算机架构都是冯诺依曼体系的,并不是最适合函数式语言的生存土壤。

一切都是常量

没有变量,也就没有通过变量共享状态导致的资源竞争,也就不需要加锁。 任何状态的变化都是通过函数的输入输出来进行改变, 轻量级进程的状态变化也是靠消息传递(函数的输入输出)来实现。 这也是为什么有人说函数式编程适合高并发的原因,因为他们没有变量, 一切都是常量。

轻量进程

Erlang 里面有 spawn 函数,可以快速的创建一个 process , 这里的 process 不是操作系统的进程,而是 Erlang 自己的轻量进程。 Erlang 轻量到超乎你想象, 构建 kv 数据库的时候,甚至可以对不同的 key 分配给不同的进程。 而且进程的表示单位是 Pid ,只要知道进程的 Pid, 哪怕该进程是在别的机器上面,都可以很轻易的发送给它。 原因是 Erlang 的【天生自带RPC通信】和【自带端口映射】

天生自带RPC通信

代码如下:
ToPid ! Data

ToPid 是接受方进程的id , Data 可以是 Erlang 的任何类型,比如

代码如下:
Pid ! {name, "wp.iirii.com"}.

也就是可以直接把任何数据结构当成消息发送,天生自带 RPC 通信。 (虽然本来 RPC 的含义是“远程过程调用”,不过其实反正就是帮你序列化了数据结构,Erlang 的 ! 操作符也是如此。)

进程端口映射

节点之间发消息在代码里面的表示也还是

代码如下:
ToPid ! Data

也就是在写代码的时候,根本不用考虑该进程是在哪台机器上面, 无论是本 Erlang 进程(这里的进程是操作系统级别的进程,不是 Erlang 的轻量进程) 内, 还是其他机器的进程,都不用管。 这是因为有 epmd 的存在。

Epmd是Erlang Port Mapper Daemon的缩写,在Erlang集群中相当于dns的作用,供给节点名称到端口的查询办事,epmd绑定在总所周知的4369端口上。

有了 epmd ,写分布式程序就好像写单机程序一样简单。

严密的模块化管理

Erlang 的模块类似 C++ 中的 namespace(命名空间),但是比命名空间更利于高效的软件工程管理。

在 Erlang 项目源码中处处可见如下代码。

代码如下:
-module(my_app).
-export([start/2, stop/1]).

-module 指明模块名,-export 指明导出的函数。 未被导出的函数都无法被外界调用。 从软件工程上看的话,这样使得模块功能和使用方法更加清晰。 使用者只需要关心如何 -export 里面的函数即可。 相比较之下 C++ 对这方面特别不规范,而 Java 通过对类声明为 public class 指明可以被外界使用, Node.js 也是使用 export 来显示声明可以被外界使用的函数。

行为模式

代码如下:
-module(ecomet_app).
-behaviour(application).
%% comment: Application callbacks
-export([start/2, stop/1]).
-behavior(application).

Erlang/otp 里面的【行为模式】概念等价于 OOP 里面的接口概念。 上面代码示例的意思就是该模块(ecomet_app)遵守的行为模式是(application)。 刚行为模式需要实现的两个接口函数就是 -export([start/2, stop/1]). 。

另一个示例如下是遵守监督者(supervisor)行为模式, 实现的一个接口函数是 -export([init/1]). 。

代码如下:
-module(ecomet_sup).
-behaviour(supervisor).
%% Supervisor callbacks
-export([init/1]).

监督者机制

Erlang/otp 的天生分布式特性在监督机制里面体现的很好, 每一个 otp 应用启动的时候,都是启动监督者(supervisor)和工作者(worker)。 他们的关系是树形结构,每个工作者的上级都会有监督者, 每个监督者的上级也可能有监督者。 当工作者异常退出的时候,监督者会根据相应的参数决定是否对工作者进行重启。 如果重启失败的话监督者也会退出,而更加上层的监督者收到信号后会对他们进行重启等处理。 这个监督者机制非常好理解,其实就是 OOP 编程里面的 try … catch 异常处理机制。 当出现异常的时候一层一层的往上抛出,直到有人重启。

otp平台

Erlang 最强大的地方也是最让我感觉难学的地方,就是它的 otp 平台。 各种行为模式, 让我感觉就像多年以前学习 MFC 的时候, 感觉很强大,但是却总是感觉自己被按死在一条特定的轨道上面奔跑, 有种不自由的疲惫感。

代码热切换

热切换也叫热升级,大部分情况下,如果需要对 C++/Java 程序进程版本升级, 则需要重启进程。 Erlang 支持热切换的意思就是可以在运行的时候进行代码升级。 升级过程不影响进程的运行, 而且在过渡阶段新旧版本还可以共存。 是不是碉堡了。这个功能对于那些需要 7×24 高可用的服务来说简直就是爽爆了。

Erlang 进程本身可以通过一个类似“后门”的控制台 erl 来实时的查看状态, 甚至直接使用控制台来修改配置等,非常方便,这对于大部分其他语言来说, 简直就是黑魔法般神奇的存在。

典型缺点

1.文档太少,出现问题搜索出来的答案也少。
2.Erlang 人才稀缺,招聘不易。
3.动态语言最典型的就是调试不易。
4.上手门槛较高。

Erlang初学的更多相关文章

  1. erlang工作前新手学习指引路线

    Erlang学习总结,新手指引 要具体的写erlang入门技术网上有非常多,我写的肯定没有那些大牛写的好,自己也实习了快一个月,也做一个总结,给后erlang初学兴趣者提供些拙见吧 第一步搭建学习环境 ...

  2. [Erlang 0119] Erlang OTP 源码阅读指引

      上周Erlang讨论群里面提到lists的++实现,争论大多基于猜测,其实打开代码看一下就都明了.贴出代码截图后有同学问这代码是哪里找的?   "代码去哪里找?",关于Erla ...

  3. notepad++ erlang开发环境设置

    初学erlang 网上有使用eclipse的,有使用emacs的,尝试了一下, 感觉太麻烦,来试试notepad++吧. 有什么新使用方法会再更新上来,for you for me. 1.语法高亮: ...

  4. Erlang语言学习入门

    这是一个命令行程序,可以直接在里面输入表达式进行计算,例如来一个简单的: Erlang R15B01 (erts-5.9.1) [smp:4:4] [async-threads:0] Eshell V ...

  5. 理解Erlang/OTP - Application

    http://www.cnblogs.com/me-sa/archive/2011/12/27/erlang0025.html 1>application:start(log4erl). 我们就 ...

  6. DDD初学指南

    去年就打算总结一下,结果新换的工作特别忙,就迟迟没有认真动手.主要内容是很多初学DDD甚至于学习很长时间的同学没有弄明白DDD是什么,适合什么情况.这世界上没有银弹,抛开了适合的场景孤立的去研究DDD ...

  7. gulp初学

    原文地址:gulp初学 至于gulp与grunt的区别,用过的人都略知一二,总的来说就是2点: 1.gulp的gulpfile.js  配置简单而且更容易阅读和维护.之所以如此,是因为它们的工作方式不 ...

  8. 初学seaJs模块化开发,利用grunt打包,减少http请求

    原文地址:初学seaJs模块化开发,利用grunt打包,减少http请求 未压缩合并的演示地址:demo2 学习seaJs的模块化开发,适合对seajs基础有所了解的同学看,目录结构 js — —di ...

  9. [Erlang 0129] Erlang 杂记 VI

    把之前阅读资料的时候记下的东西,整理了一下. Adding special-purpose processor support to the Erlang VM   P23 简单介绍了Erlang C ...

随机推荐

  1. 使用ehcache持久化数据到磁盘 并且在应用服务器重启后不丢失数据

    使用ehcache时如何持久化数据到磁盘,并且在应用服务器重启后不丢失数据1.如何持久化到磁盘使用cache.flush(),每次写入到cache后调用cache.flush() ,这样ehcache ...

  2. Entity Framework关联查询以及数据加载(延迟加载,预加载)

    数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...

  3. 布隆过滤器的概述及Python实现

    布隆过滤器 布隆过滤器是一种概率空间高效的数据结构.它与hashmap非常相似,用于检索一个元素是否在一个集合中.它在检索元素是否存在时,能很好地取舍空间使用率与误报比例.正是由于这个特性,它被称作概 ...

  4. 用JS实现的类似QQ密码的输入特效

    <input ID="_PSD"></input> <script> function passwordText(ID,pd,mark){ ma ...

  5. uploadfy api中文文档

    Uploadify是一款基于JQuery的优秀的文件/图片上传的插件,有基于Flash和HTML5两种版本. Uploadify/uploadifive主要特点有:1. 多文件上传2. 个性化设置3. ...

  6. jQuery高级编程

    jquery高级编程1.jquery入门2.Javascript基础3.jQuery核心技术 3.1 jQuery脚本的结构 3.2 非侵扰事JavaScript 3.3 jQuery框架的结构 3. ...

  7. English—句子

    1. So far so good.   目前为止,一切都好. 2. Be my guest.     请便.别客气. 3. You're the boss.    听你的. 4.I've heard ...

  8. linux开机启动mongodb

    方式一(不推荐) ubuntu编辑/etc/rc.local /home/wyt/bin/mongodb-linux-x86_64-ubuntu1404-3.2.8/bin/mongod --dbpa ...

  9. REPEATABLE-READ下批量更新数据的问题

    1. 当前mysql的隔离级别 REPEATABLE-READ 2. 用户读取的时候或者更改的时候(通过事务)   会对 更改的数据加行锁 和 gap锁 , 最终更改完毕后 去掉锁. (行锁表示这条数 ...

  10. 用RollViewPager实现Android滚动banner

    最近项目中要实现一个循环滚动的banner,效果如下图 这个自己写实在是不方便,而且写出来也很难保证没有bug和性能缺陷,好在网上有人开源了一个实现滚动banner的RollViewPager框架,亲 ...