首页 > 代码库 > [Erlang]前人挖坑,后人还要进坑?(3)

[Erlang]前人挖坑,后人还要进坑?(3)

??

21.在生成随机数过程中一直使用:

random:seed(erlang:now()).

erlang:now()是可以一直递增的数,从不重复,但是不适合用于随机算法,最好使用下面这种

-spec get_random_num(integer()) -> integer().
get_random_num(Max) ->
    <<A:32, B:32, C:32>> = crypto:rand_bytes(12),
    random:seed({A,B,C}),
    random:uniform(Max).

22.Pid的那3位数字<A,B,C>代表着什么?

  • A, 对应是哪一个节点 (0 代表是本地节点 ,其它数字代表远程节点) ;
  • B, 低15字节代表进程唯一记数(一个进程表的索引)
  • C, 16~18字节也是进程唯一记数(和B一样)

http://stackoverflow.com/questions/243363/can-someone-explain-the-structure-of-a-pid-in-erlang

验证如下:

打开一个终端test1

打开终端test2

23.gen_server进程如果长期不需要处理其它消息,可以使用返回值{noreply,hibernate}进入休眠状态:使用场景:

比如使用者知道在处理完一个特定的消息后这个进程在很长一段时间内不会再有消息处理,可以设定这个消息的返回后进入hibernate状态!

这可以减少内存和cpu消耗。

24.Record这么好用,为什么还是有很多大神吐槽record非常不好?

缺点:

%%1.只能使用原子作为index元素;

%% 2.编译前就确定了结构,不能动态的增加index,比如person要增加一个phone属性,record是做不到的。

所以17后就有了Map这个数据结构,可以突破上面的限制,真正的Map.

http://www.cnblogs.com/zhengsyao/p/erlang_map_brief.html

但是目前的mnesia只支持record的。不支持map,那Record的升级麻烦还会在mneisa中继续存在的。

25. receive 里面after的妙用:

进程阻塞时,用于清空进程信箱消息

receive 
 Msg ->
           do_something(Msg);
after 0 ->
      do_something2)
end.

关键看清楚那个after 0 ,调用这个函数就会把这个进程以前旧的消息都用do_something(Msg)处理掉:(当然你的do_something/1里面会尾递归调用回这个函数啦)

25.ETS 的默认限制个数为1400个,你可以通过:

erl -env ERL_MAX_ETS_TABLES Number

来改变这个默认值,但是这个限制也提示了一个非常重要的信息:不要尝试每一个进程都建立一个ets表!

26. 不要跨节点连接或监控(link,monitor)很多进程:

因为如果节点由于网络故障通信断了,那么所有link或monitor的进程会被马上触发,产生超大量的消息分给超多的进程,这就会给系统增加非常大的负担。

27.使用receive 嵌套实现接收消息的先后关系

receive
       {first_deal_msg,Msg} ->
                 do_someting(Msg),
                  receive
                        {second_deal_msg,Msg2} ->
                              do_someting2(Msg2)
                  end
end.

28.Erlang为什么叫Erlang?(哈哈,乱入一通):

erlang

n.厄兰(话务单位),占线小时;

名副其实的为通信而先的语言哇…

29.begin end语句块的简洁使用:
问题描述:
将一堆人随机平均分开2组,,怎样去平均?

当然效率不高,但是!看上去很cool…

30. split_binary/2

It is usually more efficient to split a binary using matching instead of calling the split_binary/2 function. Furthermore, mixing bit syntax matching and split_binary/2 may prevent some optimizations of bit syntax matching.

使用比特语法来分离二进制比用split_binary/2更加高效,更进一步来讲,混合使用比特语法和split_binary/2会把编译器弄sb的(不会进行相关的优化任务了)

DO

<<Bin1:Num/binary,Bin2/binary>> = Bin,

DO NOT

{Bin1,Bin2} = split_binary(Bin, Num)

[Erlang]前人挖坑,后人还要进坑?(3)