Guava Collection Zero To Hero Part Two

第二部分主要展示Guava Collection的使用,从实际用例出发。

Guava Collection Use Case

在了解了Guava的Function和Predicate后,可以开始使用了。这篇文章里面不是文档的堆积,而是一些具体的使用场景,这些场景仅仅是我遇到的,觉得在一定程度上简化了操作,美化了代码的,希望对读者有所启发,开发自己的Best Practice。

测试用数据

测试使用一个自定义的数据结构,如下:

public class Node {
    private Integer id;
    private String title;
    private List<Integer> items;
}

1. 使用transform做抽取

很多时候我们手中会拿到一组复杂的模型,不论是从数据库还是从别人的什么接口。但是真正在我们的逻辑中需要用到的仅仅是Model种的一个或多个字段。在这种情况下,你可以尝试Lists或者Iterables工具集中的transform方法来抽取我们需要的部分。位于Lists包内的函数签名为:

public static <F, T> List<T> transform(List<F> fromList, Function< ? super F, ? extends T> function);
传入的参数分别为待处理的数据List,以及一个实现具体抽取逻辑的Function。加入我们希望抽取出Node中的id,获得所有Node的id数组。那么我们可以定义如下的Function:传入一个Node,返回该Node的Id。
Function<Node, Integer> idExtractor = new Function<Node, Integer>() {
        public Integer apply(Node input) {
            return input.getId();
        }
};
然后使用transform即可:
List<Node> nodes = Lists.newArrayList(
    Node.nodeGenerator(1), Node.nodeGenerator(2), Node.nodeGenerator(3));
List<Integer> nodeIds = Lists.transform(nodes, idExtractor);

使用的语法是非常简单的,但是这背后有一些注意的事项,甚至是隐藏的陷阱。

Read the rest of this article »

Guava Collection Zero To Hero Part One

好长时间都没有更新这里了。所以说学生时代还是最好的时间嘛,晚睡晚起,想写就写。闲话少说了,这篇博客主要介绍下最近使用Guava的一些特性,集中在最常使用的Collection部分,希望通过正确使用Google Guava,美化Java代码,提高可读性,可维护性。在Part One里面会主要介绍Guava的背景和顺畅使用Collection所必须的一些前置知识。

一些Guava的背景

众所周知,Guava是Google的一款开源库。他的前身是Google在2007年10月22日首发的Google Collection,随着2009年底Guava的正式开放,Google Collection变成了Guava的一个子集。有人认为是Java5发布引入的泛型(Generics)是Google最终决定停止维护Apache Commons,转而开发自己的类库的导火索。简单总结一下Google的初衷:

  • 当时的Apache Library基于Java 1.4,他们不喜欢1.4
  • Apache Library由于上面一点,不支持泛型,导致使用者的代码中出现大量的编译时warning
  • Apache Collections在实现上有不少和JDK本身集合行为相异的地方。Google认为完全没有必要引入这种风险

关于一个公司为什么开源一个软件,系统,或者工具,不同的人有不同的解读。除了上述的几点之外,Guava的主要贡献者kevinb9n在2014年Reddit上的答网友问中的观点让我觉得非常值得思考。他提到当Google在内部不断地囤积秘密代码库方便开发的时候,Google的程序员可能和外部的Java世界渐行渐远,Google希望自己的工程师依旧和主流站在一起,缩小Java Inside Google和Java Outside Google之间的区别。所以吾等,如果抱着身处Google之外就处在主流之中的错误想法,那么很有可能忽略Google等公司对主流的改造,最终的结果可能是我们变成了非主流。所以还是要发现变化,理解变化,忍受抑或享受变化。

Guava开放之后当然是收到了主流的欢迎。究其原因主要的有三,首当其冲的是良好的设计,Guava的开发由一群优秀的工程师担任,除此之外,还有Joshua Bloch的亲自指导,可能你忘了他是说,Effective Java,好了,你知道了。第二个原因是Guava是经过严格的测试,Google的诸多业务都有Guava的身影,所有外部commit(基本上)都是不被接受的,Google用Eat Your Own Dogfood的行为保证了Guava的稳定。第三就是品牌效应,活跃社区。综上,Guava成为了Java类库里面一款比较成功的产品。

Function是什么

在开始讨论之前如果对Guava的Function不了解,那么集合的操作也就不能发挥出最大的优势了。Functional Programming实在不是我目前了解的,但是这里还是跳不过去,不懂得函数是编程,但是至少需要知道什么是函数。这篇博客里面讲到了两条基本的原则,我认为可以很好的帮助我们对照理解Guava中的Function。他提到一个Functional的函数需要具备两个条件:

  • 不依赖函数外的数据
  • 不修改函数外部存在的数据

下面有两段Python的方法,可以用来体会他们的区别:

Guava的Function也满足这样的特质。在我自己的角度来看,我会把上面两段代码进行如下的拆解:

函数化的函数可以作为独立的组件,独立于要操作的数据,独立于数据与函数相互作用的场地而存在。当把函数作为一种组件而传递的时候,你会发现一种突然迎面而来的清晰感,数据,逻辑,场地,井然有序的排列开了。Guava为我们提供了一些场地,例如transform, index等都是Guava为我们提供好的场地,同时,Guava为我们提供了可自定义的Functional Function接口,可以将我们的逻辑封装为可传递的组件,最后不论是JDK的Collection还是Guava的Collection,都可以在Guava的场地中和Function发生作用,带给我们一种很不一样的编程感受。

对Function有了一个基本的认识之后,可以开始编写和使用Guava的Function了。 只要实现下面的Guava提供的接口,便可以书写自己的Function。

Read the rest of this article »

Yarn开发技巧之脚本实现Log Archive

学习开发Yarn,在最初阶段会遇到一个较为陡峭的学习曲线。造成的这个的原因除了项目本身的复杂程度以外,还有不同于以往的调试方法会让人产生不适应。在以前,我从没有注意过任何的调试技巧,基本上都是断点啊,单步啊之类的,但是到了这次调试Hadoop这样大的项目才发觉原来的简单调试方法不给力了。

本文将会涉及:

  • 设置Hadoop的调试级别
  • 将每一次的日志记录保存在不同的文件中,形成一个Log Archive

♠  调整日至级别

调试Yarn,我采用的方式是开启Apache Log4j的DEBUG级别,这一工具在大型项目中具有很广泛的应用。如果我们需要打开Hadoop相关组件的DEBUG级别,获得调试输出。有一下三种途径:

  • 使用Hadoop Shell命令

查看当前的组件日志级别,以ResourceManager为例

/opt/yarn/hadoop-2.6.0/bin$ ./hadoop daemonlog -getlevel localhost:8042 org.apache.hadoop.yarn.server.resourcemanager
以上的代码会显示resourcemanager组件的整体日志级别,你也可以后面添上类名而查询更细粒度的日志级别。 注意,我的开发环境是Single-Node的配置,所以上面用了localhost,如果在真实集群中,需要使用${nodemanager-host},下同

  • 使用Web界面修改和查看

前往如下地址

localhost:8042/logLevel

使用以上两种方式获的效果是单次的,在Hadoop重启后将失效。

Read the rest of this article »

莫愁前路无知己

如果你的手中有一盏灯
请在黑暗中摇一摇
那看到的人
会带着眼泪,带着希望
冲破黑暗
与你紧紧相拥

今天我25岁了。今天我很开心,我在早上9.54收到了她的祝福,我的眼泪竟然毫无征兆的流了下来,让我吃惊,让我幸福。一直以为好朋友已经忘掉了,没想到都还记得,还为了组织一场小小的惊喜而弄出一点误会,感谢你们所做的一切,愿你们一切都好。

我喜欢2015,也喜欢未来即将开始的日子。“莫愁前路无知己”是我要给自己的第一句话,多么充满力量的诗句,光芒闪耀的前路,心意想通的那个人即将要出现了。“生活当亦理亦情亦趣”,这是第二句,永远不要忘记生活的趣味,性格和真善美是不同的。“自信来自于自制”这是第三句话,也是非常重要的一句,只有控制自己,才能控制未来。

爱你,世界。
祝我生日快乐。

Sincerely,
@stevenyfy

P.S 昨晚学了生日快乐吉他版,零点的时候给自己弹了一曲,场景看起来有点戚戚然。但是心是温暖的。

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

摩尔门教传教经历记

基本上是以流水账的形式记录的。14年底圣诞遇到两位长老,于是在15年的开头有了这次传教的经历。记录如下。

开场是长老介绍自己,两位都花大量时间介绍了其家庭的情况,大量家庭照片。之后是美国的长老做开场祷告,观看介绍视频。

根据短片,很久以前先知李海,奉主之名从欧洲携带家人跨越沙漠和大海,抵达美洲大陆,在上面发展了文明。在这之后1823年由一位先知少年(约瑟.斯密)在阅读圣经时发现一句话。(好像是,当一个人缺乏智慧时,要虔诚的向上帝祈祷),于是在一个树林中受到启发,得到了从金板上翻译摩尔门经的使命。从此获得了与旧约,新约相对的“另一本书”:摩尔门经。令人感到意外的是现任的主教先生是一位来自牙买加的黑人,非常年轻,至少看起来是这样的,笑容很多,手拿经书,整部宣传片更像是一本书的推介。说句实话,如果整套宣传片换做是另一个人和另一本书,也会认为是自然的。也有可能是一直以来我都迷信化了宗教一词。越进行到后面,我越发觉得摩尔门是一门入世的信仰。至少当时我是这样看的。

不少人都提到这部经书让他变得快乐,而我一直都想问一个问题:“How”。但是宗教似乎避免直接回答这个问题。转念一想,其实这并不是难以理解的事情,就像你问一个快乐的人你为什么快乐,而他只会回答你我就是感到很快乐。怎能指望直接赋予你快乐呢?不像金钱的传递,可以无中生有。我想对于灵魂层面的东西,必须心中有,才会被传递。选择相信,预留出信仰的心田,才能被传递某种信仰。对于宗教,或许应该卸下迷信的色彩,认为是一种玄妙的魔术,赋予人特异的功能,而是一种填充物,填充灵中尚空的地方。不经让我想起我的启蒙动漫,EVA,被不少人说是一部带有宗教色彩的漫画,其中大量提到人类补完计划,完成补完的人类方可成为神。人不论从肉,灵都会产生空虚的感觉,而对其的补完应该就是宗教最大的意义吧,因此,也可以说任何一种补完人类空虚的东西都是一种“宗教”。靠自己的苦修可以补完,需要的是自己,目的是剔除所有引发空虚的源;也可以相信,能补完自己的是别人,需要不断的去爱和被爱,因此会进入一个团体,人们彼此补完。我想摩尔门是后者(有待观察)。

Read the rest of this article »