λ

(conj clojurians me)

##How to generate java project with gradle

gradle1.7

Contains the build-setup plugin, supports declaring project type when setting up a build.

  • task-type
    • SetupBuild
  • plugin
    • build-setup
  • task
    • buildSetup

so, you can type

1
gradle setupBuild --type java-library

gradle1.9

  • task-type

    • SetupBuild -> InitBuild
  • plugin

    • build-setup -> build-init
  • task

    • buildSetup -> init

init project on gradle 1.9 or more greater

1
2
gradle init --type [java-library | scala-library | groovy-library | basic | pom]
gradle1.10 support *gradle help --task init* to show task usage details

skeleton of java project

introduce

  • Zeal is a offline API documentation browser for linux, just like Dash on Mac OS X
  • All documentation available for Dash is also available for Zeal.

how to install zeal on Ubuntu linux

1
2
3
4
sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
sudo add-apt-repository ppa:jerzy-kozera/zeal-ppa
sudo apt-get update
sudo apt-get install zeal

Just like

here

You can click here

Hibernate Secondary Tables

  1. Hibernate Secondary Table的应用场景

两张表有外键关联,主要应用于One-To-One或Many-To-One的两张表之间。

比如,以Many-To-One为例:

表一:

CREATE TABLE Person (
    id INT NOT NULL PRIMARY KEY,
    parent_id INT,
    num INT NOT NULL
);

表二:

CREATE TABLE Name (
   id INT NOT NULL PRIMARY KEY,
   name VARCHAR(20) NOT NULL,
   person_id INT NOT NULL,
   FOREIGN KEY(person_id) REFERENCES Person(id)
);
  1. 对应的映射实体

@Entity
@Table(name = "Person")
@SecondaryTable(name = "Name", 
pkJoinColumns={ @PrimaryKeyJoinColumn(name="id", referencedColumnName="person_id") )
public class Person {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private int id;
   @Column(name = "num", nullable = false)
   private int num;
 
   @Column(name = "parent_id", nullable = false)
   private Person parent;
 
   @Column(name = "name", table = "Name")
   private String name;
}
  1. 业务需求

*现在要求查询固定的num=123下所有的孩子中名字叫做name=english_name的人(注意这里的num不是主键,但是唯一标识这个人)*

我们很轻易地写出下面这样的语句

SELECT a FROM person a WHERE a.parent.num='123' AND a.name='english_name';

但是结果出乎我们意料,假如这里我们的Name表中每个人都对应中文名,english_namejapanese_name,那么返回的就是连续的3组含有english_name的记录。

这个显然不符合我们的要求,那么到底什么地方出了错误呢?

我首先想到的解决方案是

SELECT DISTINCT(a) FROM person a WHERE a.parent.num='123' AND a.name='english_name';

添加了DISTINCT。此时,返回的结果果然正确。但是这不符合我的直觉,试想想每次平白无故地拿回许多不需要的数据,最后还要进行筛选,实在得不偿失。

  • 由于我选择的ORM框架是Hibernate,这其中有一个好处就是可以直接打印发送给数据库服务器的SQL语句。没有办法,为了解原因所在,不得不动手分析起万恶的SQL语句。

    语句是这样的,为了可读,我对Hibernate生成的SQL语句进行了一些调整,结构没有改变。

    select
    person_A.id as ID,
    person_A.num as NUM,
    person_A.parent_id as PARENT,
    name_A.name as NAME
    from
    Person person_A
    left outer join
    Name name_A
    on person_A.ID=name_A.person_id cross
    join
    Person person_B
    left outer join
    Name name_B
    on person_B.id=name_B.person_id
    where
    person_A.parent_id=person_B.id
    and person_B.num=123
    and name_B.name=’english_name’

起初,我以为是cross join的问题,cross join顾名思义,就是著名的笛卡尔乘积,即叉乘。但是cross join在这里的作用不过是一个逗号
这样的语句就和我们熟悉的联合两张表来查是一样的了。
举个例子, 即

SELECT * FROM A, B WHERE A.ID=B.a_id AND B.num=222;

因为有了B.num=222和A.Id=B.a_id的限制,就不会有叉乘的结果出现。

  • 那么为什么会出3组重复的数据呢?

    进一步分析,我发现where子句中

    person_A.parent_id=person_B.id
    and person_B.num=123

    已经限定了person_A的父Id,但是最重要的是,该父Id在两张联合表中不是唯一的!它对应了3条不同记录,这3条记录中的name字段取值不同。
    明确这点,我又进一步分析得出
    3条不同的父Id记录,分别派生出3组不同的子记录群,每组中的每条记录也不是唯一的,它们一样对应3种不同的名字。
    最后,分析where子句限定

    and name_B.name=’english_name’

    这条语句不过是将每组中名字是english_name的字段取出来,取出来的记录仍然是3组重复的记录。
    所以得出的结果是必然的。

  1. 解决方案

仔细分析之后我发现,其实只需要将限定person_A的Parent Person的名字先限制在english_name上,那么这样的Parent Person就是唯一的。通过这个唯一的Parent Person,就会得到了一组子记录,它们的名字还是会有不同(对应各自的中文名,英文名或者日文名),这样的结果还不是我所期望的,所以更进一步,我将这样一组子记录的名字也限定在english_name上。那么查出的结果就是唯一的了。

SELECT a FROM person a WHERE a.parent.num='123' AND 
a.parent.name = 'english_name' AND a.name = 'english_name';

以上就是我解决整个问题的过程。

  1. 总结

任何问题都有解决方案

不要想当然认为工具会按照你的想法去工作

SQL万恶,但是不熟悉它,你的代码会更邪恶。

  1. 确认系统中安装了Node.js, Git, 可选安装Ruby和Compass

  2. 如果系统未安装Node.js,使用PPA安装Node.js

    sudo apt-get install python-software-properties

    sudo add-apt-repository ppa:chris-lea/node.js

    sudo apt-get update

    sudo apt-get install nodejs

    ~$ node –version

  3. 安装npm(Node Package Manager)

    1. curl -L https://npmjs.org/install.sh | sudo sh
    2. $ npm –version
  4. 安装yo, grunt, bower

    1. 会自动安装grunt、bower

      sudo npm install -g yo

    2. 为了搭建一个web app,需要web app generator来自动生成

      sudo npm install -g generator-webapp

    3. 搭建web app的骨架, 即目录结构和某些必要的配置文件

      yo webapp

    4. 安装backbone.js,同时将其依赖写入到bower.json中的devDependencies

      bower install backbone –save-dev

    5. 安装underscore.js,backbone依赖之

      bower install underscore –save-dev

    6. 安装require.js

      bower install requirejs –save-dev

  5. 运行 grunt 启动服务

    grunt serve

    默认浏览器会自动打开,访问localhost:9000

    控制台会自动打出 ‘Allo, ‘Allo! 字符

这座城市

在成都。我想,看不到月亮,就看看灯光吧。正好住的房间有一扇大大的飘窗,差不多占据了一面墙,静坐在书桌前,稍微抬头就能将天华一路的高楼和街道尽收眼底。白天城市喧嚣,难得闲心看风景,加上连日来的雾霾天气实在影响观赏度,便将这份心情压在心底。倒是今天下起了小雨,稍稍降低了污染指标。在大口呼吸新鲜空气的同时,也便得了几分兴致看起夜景来。

成都的夜景美不美?我倒不敢妄论,只是从高楼一角,小窥城市一隅,斑斑点点的灯火就已经让我目眩了。街道还是白天的街道,人是不见了,只成对的路灯从这边排列到视野尽头,偶尔几辆汽车从尽头那边缓缓行驶过来,慢悠悠地如同冬眠。

夜深了,灯火也开始昏黄。城市开始慢慢地进入一种制衡点,像余音未止的古钟。街道还在有节奏地蠕动,送走疲劳的车和里面的人。一辆咆哮的跑车划过静谧的夜空,也不过是安眠曲里的高音,转瞬即逝。这样的夜晚,真的很适合睡眠。但是总有人不肯入眠。

白天,走过一段泥泞的街旁小道,惊喜的是路上铺满了银杏的落叶。夜雨过后,除了换了新鲜空气,也带来了冬日的冷气,这一年又近年末。脚下踩着松软的落叶,我瞬间明白了隔壁那条街一辆被银杏树叶盖的严严实实的车子的悲惨遭遇,也感受到清洁工阿姨工作的艰辛,更徒然生起一些时光容易把人抛,韶华不为少年留的感觉。

很多人的文章中,我常看到这样的描述:“虽然我已经开始工作了,但是大一的生活还历历在目,恍如昨日”。我也不只一次地听到学长、学姐说出这样的心声——直到我也变成学长,也不能免俗地对学弟、学妹语重心长地劝诫同样的心声。有时候,我们都懂得同样的道理,但总在潜意识里认定特别的自己,最后历尽坎坷,终于成了深沉的学长和学姐。其实,这也没什么大不了,你不可能因为不可信的未来,苛求现在的自己;因为珍惜未来的校园美好回忆,强迫自己喜欢食堂的饭菜;恐惧未来的生活,拼命让现在的自己活得有意义。本来,生活就是不被任何人定义的,你觉得有意义就够了。

远处的灯光卖着萌。高楼顶上忽闪忽闪两盏灯尽力保持着神秘,可叹人类终究还是有了知乎,连电梯为什么没有零层的难题都有近乎真理的答案,你的神秘也就掩耳盗铃铛儿响叮当了,顺带,我替穿红衣帽的白胡子老头向大家祝一句”Merry Christmas”。他老人家忙,铃铛刚被偷了,正在警局备案。

生活是需要回顾的,就好象每次迭代的Retro,做的好的,保持;做的不好,寻找解决方案;有疑问的,提出来。大体遵循这样的模式,你就能持续提高。实习有段时间了,对于成都这座城市,不可谓不熟了。半个来月,交了两三个好友,大家对技术一样狂热;混熟了java大牛级人物郑晔,见识了优秀代码的模样;和PM结对编程,被其高超的前端技术深深折服。也见识了客户的嚣张,感受到了不成长毋宁死的压力。除此之外,几乎每天公司都会组织各种不同主题的session,参与过一些后受益匪浅。还有每周二的Ruby on Rails义梦中国的善举,虽仍未有幸参与其中,但早已心驰神往了。

夜晚很漫长,既然无心睡眠,就操笔书就一篇乱七八糟吧。我如是想,这座城市,是我梦想的起源地……

好梦

关于敏捷

  1. 我们用TDD的方式验证代码的正确性
  2. 用CI验证自己开发的代码对于团队的影响
  3. 用迭代的方式快速地实现一部分需求放到相关人那里去验证
  4. 用持续交付的做法把实现尽早放到产品环境中去验证
  5. 用精益创业的理念把想法放到用户那里去验证

一段老手和菜鸟的对话

关于菜鸟期

每位入职的新手都有一段菜鸟期,我可以接受你在这段时期菜鸟的表现
你可以在菜鸟期间表现出任何愚蠢的行为,包括问愚蠢的问题
不要怕自己的问题愚蠢,不要担心自己因为愚蠢被看低。因为你不在菜鸟
期使劲地表现自己的愚蠢,你就没有机会表现了。

关于时间管理

我们的时间都一样,关键在于你怎么把握。我在你娱乐的时间来学习知识,
我在你熟睡的时候,起早敲代码、写博客,我把知识积累的优先级排到最高。
一切都只在于你,你不成长,不能怪别人,只能怪你自己。

关于新知识的学习

为什么我学得快,你不行?为什么我的代码看起来就是那么漂亮,你不行?
这都在于积累,因为我有积累,你没有,你的接收速度就不会快。所以你要积累。

关于坚持写博客

别告诉我你没时间,时间是挤出来的。你说你记了笔记,但是你没有把它用
自己的话写成博客,所以那些只是在那里,依旧不是你的。知识得理解了,得会用了,
那才是属于你的。

关于坚持提交代码

我把提交代码当作娱乐,更是在突破我的极限。你在自己的舒适区里待久了,就不会有任何提高。
所以你必须往前跨一步,逃离自己的舒适区。你已经不是学生了,你不能将自己继续孤立到团队之外,你需要
融入办公环境,接触更多的人,让自己不舒服起来。

Skill

合并两行技巧

普通模式下(n),光标在上一行,
使用 (J) : 合并有一个空格
使用 (gJ):合并没有空格

写文档,加行号

:%s/^/\=printf('%3d  ', line('.') )
 %s!nl ( nl 表示 number line )

替换一个单词

cw

编辑buffer或者文件

:bn(next)
:bp(prev)

重复命令

.   重复以上命令
N . 重复以上命令N次

录制宏

qa -> 进入宏录制
Yp -> 复制一行进行粘贴
<C-a> (这里我将其替换为<A-a> 实现递增,因为windows会使用惯用键) -> 实现递增
q  -> 退出宏录制
@a -> 将寄存器记录重发
@@ 重复上一个操作

关于tabedit使用

set guitablabel=%N/\ %t\ %M  -> tab上面会显示 1/ name.suffix 的格式
map <C-tab> gt -> gt表示切换tab标签

查找当前word对应的匹配项

% : 到对应的 (, {, [.
* (resp. #) : 到对应的 (resp. previous) 光标标识的单词

在当前行进行定位

0 → go to column 0
^ → go to first character on the line
$ → go to the last character on the line
fa → go to next occurrence of the letter a on the line.
, (resp. ;) will seek for the next (resp. previous) occurrence.
t, → go just before the character ,.
3fa → search the 3rd occurrence of a on this line.
F and T → like f and t but backward.

如何让Dos下编写的文件在*nix下正常显示

一般DOS的换行符是\r\n(CRLF),而*nix则是\n(LF)
也就是Ctrl-v Ctrl-l
:%s/^M//g 去除^M,记住^M不是字面上,而是通过输入Ctrl-v enter打出来的
0%