博主是一个不是很聪明的码农。完美主义者,强迫症中期。这里会记录一些回忆和点滴,以博为镜。
武器库:
最近为了看storm的源码,开始了clojure的系统学习。clojure因为背负了Java这个历史大包袱,在语法上相对于其他Lisp方言,还是稍显复杂和罗嗦。JVM语言似乎都很难摆脱JAVA的身影,互操作是件很难做得优雅的事情。不过FP的魅力还是让我坚持下来,准备长期作战,不断学习和积累。本文不进一步讨论clojure,只简单介绍下使用lein进行clojure工程的构建,因为我个人对gradle很感兴趣(出于对groovy的好感)后续可能会再写一篇使用gradle的构建。
storm的源码就采用了lein构建,可以看下工程根目录下有project.clj文件。就目前看到的clojure开源项目,用lein的还是居多的。
##lein的安装##
查看lein的github主页:https://github.com/technomancy/leiningen,对于lein在*nix上的安装,比较简单的步骤是下载此脚本,放到PATH
里,并执行chmod 755 /path/to/lein
即可。首次执行该脚本会下载相关的文件并默认安装到~/.lein
。
##创建新工程##
这里我们创建一个简单的示例工程:
$ lein new app leinexample
控制台输出:
Generating a project called leinexample based on the 'app' template.
也就是说,app是工程的模板名,lein默认的模板是default。模板是插件化的,所以可以很容易扩展,这里就有很多模板。下图是我们用find .
列出的lein的默认目录结构。
|
|
重点是project.clj
|
|
默认只列出了lein project的一部分属性,包括工程名以及相关元信息、license、依赖等等。这里有最全面的工程定义样例可以参考。
##导入到IDE##
起初像学习erlang一样,我使用emacs进行clj的练习,但尽管我个人对emacs很有好感,不过对于阅读代码这种事情,还是使用IDE的好。
如果需要使用eclipse或IntellijIdea等支持maven的IDE,可以使用lein pom
来生成pom文件,然后直接使用IDE导入maven工程。个人感觉IntellijIdea真的是非常强悍的IDE,当然不仅仅是说对clojure的支持。
##管理依赖##
在project.clj中可以添加依赖包,比如,我们在project.clj的dependencies中添加一条:
:dependencies [[org.clojure/clojure "1.5.1"] [clj-http "0.6.5" :exclusions [crouton]]]
执行lein deps
,控制台输出:
|
|
你可能发现,下载的依赖包,并不在工程目录里,其实lein是整合了maven,上述包其实已经下载到maven的本地仓库了。
##运行测试用例##
lein会默认生成一个clj和对应的测试用例文件,打开leinexample/test/leinexample/core_test.clj
,修改a-test
函数的返回值为true,即修改最后一行为(is (= 0 0))
即可。然后执行:
lein test
控制台会打印出测试用例的运行结果:
|
|
##编译代码##
此时如果直接运行lein compile
,你会发现,target
目录里没有.class
文件。这个起初也让我很不解。查阅了相关文档发现需要开启aot
即compile Ahead Of Time
,在project.clj的defproject
函数添加metadata:
:aot [leinexample.core]
之后再执行lein compile
,即可在target/classes
里看到对应的.class
文件了。
注意,上述大多数目录,如target、classes等,都可以在project.clj中修改。
##打包##
lein支持jar、uberjar等等打包方式,具体可以使用lein -h
可以查看lein的其他子命令。应该也可以直接打出war包,这个我没有尝试过,有兴趣的充分发挥google的力量吧。
Coding了多年Java,自然早就听说过四种引用类型,不过偶尔也才浅浅的用一下,今天突然想看看这块的内部实现,读了读jdk源码,这篇文章就当做个笔记。先简单介绍下四种引用类型:
####Java的四种引用类型####
强引用。最常见的引用类型,用赋值号,即“=”来创建。GC不会回收强引用,即使内存不足,也是宁可抛OOM先。
软引用。关键看内存,在内存不足时,GC会把软引用的对象回收掉。适用于对内存敏感的缓存。
弱引用。和软引用的区别是,无论内存充足与否,GC扫描到弱引用所引用的对象不再具有强引用时,会将其回收。
虚引用,也称幽灵引用。其get()方法固定return null,看起来似乎没有什么大的用处,但在某些场景下结合ReferenceQueue,可以有意想不到的效果。
####ReferenceQueue####
站在coder的角度看,ReferenceQueue似乎更“有用”一些。其作用是追踪被gc的Reference对象,更多的是做一些统计或清理的工作。
####Reference的四种内部状态和ReferenceHandler####
Reference依赖内部的四种状态,和GC、ReferenceHandler配合来运作,包括:Active、Pending、Enqueued和Inactive,具体可以查看下Reference类的注释,鉴于笔者理解不足够深刻,就不误导大家了。
ReferenceHandler是个高优先级的线程,用于把gc处理的Reference对象enqueue到ReferenceQueue中。
近期使用SoftReference自己做了个缓存工具,用以缓存一定size的Hive查询结果,代码在这里。