打造自己专用的.vimrc

使用了一段时间的vim后,感觉越用越好用,它的操作完全颠覆了以往编辑文本的习惯,编辑文本不再枯燥,完全成了一种享受。尤其是它的可定制性真让人欲罢不能,下面我把自己目前用的.vimrc配置文件与大家分享,因为用Vim没多久,这份配置还有很多不足之处,但我还是希望大家能从中获益,做一个快乐的vimmer! 如有其它好的配置,还请不吝赐教 :)

"关闭与vi的兼容模式
set nocp "nocompatible
"搜索结果高亮
set hls "hlsearch
"增量搜索
set is "incsearch
"显示行号
set nu  "number
"退格删除indent,eol,start
set backspace=indent,eol,start
"按h,l时,如果到头,则跳到上一行或下一行
set whichwrap=h,l
"关闭备份
set nobackup
"高亮显示光标所在行
set cursorline
"禁用鼠标点击时的虚拟选中模式
set mouse-=a
"tab键对应的字符宽度
set tabstop=4 "ts
"自动缩进时的字符宽度
set shiftwidth=4 "sw
"自动将Tab转化为对应宽度的空格
set et "noexpandtab
"当使用et将Tab替换为空格之后,不用按Backspace多次, 按一下即可
set smarttab
"自动缩进
set autoindent
"防止特殊符号无法正常显示。 在 Unicode 中, 许多来自不同语言的字符, 如果字型足够近似的话, 会把它们放在同一个编码中。 但在不同编码中, 字符的宽度是不一样的。
set ambiwidth=double
"自动切换当前目录
set autochdir
"设置当前字符编码为 UTF-8
set encoding=utf-8
"设置菜单语言和编码
set langmenu=zh_CN.UTF-8
"设置提示信息的语言和编码
language messages zh_CN.utf-8
"设置编码的自动识别
set fileencodings=utf-8,gbk,chinese,latin-1
"语法高亮
syntax on
"开启文件类型自动识别, 启用文件类型插件, 启用针对文件类型的自动缩进
filetype plugin indent on

"设置tag list插件
let Tlist_Ctags_Cmd="E:/Vim/vim72/ctags.exe"
let Tlist_Use_Right_Window=1
let Tlist_Auto_Open=0

"关闭菜单和工具栏,以最大化可视范围
set guioptions-=m
set guioptions-=T

"使用主题
colorscheme	lucius 

"键绑定
map <F3> gg=G``
map <F4> ggvGy``
map <C-F5> "+y
map <C-F6> "+p

揭秘Java中的String

最近有人问我一个问题:String是什么?

是什么?脑子一片混乱。不可变?不是基本数据类型但又像基本数据类型?顿时很多模糊的理解涌入脑海,怎么都理不清,究其原因,还是对String在JVM里的实现原理不甚理解。为了彻底搞清究竟什么是String,今天特意看了很多相关的资料,终于有所感悟,感悟之余,记录于此,与大家共享。(部分内容抄摘自网上)

一、创建String

创建一个String对象,主要有两种方式:

  1. String s=”Hello world!”;
  2. String s=new String(“Hello world”);

两种方式虽然都实现了创建一个String对象的功能,但实现的原理却大不相同。在讨论这两种方法的不同之前,我们先来了解一下JVM里的常量池概念,对接下来的理解很有帮助。

相信大家都知道,Java程序在运行之前,编译器首先要把源代码编译成字节码文件(.class文件),然后JVM再解释执行.class文件。其中,在.class文件中有一个非常重要的项—常量池,我们上面代码中的”Hello world”字符串被编译之后,就被存放在class常量池中的字符串常量表中。改用网上一段话:

在Java源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号 为8(CONSTANT_String_info)的常量表 。 当JVM加载 class文件的时候,会为对应的常量池建立一个内存数据结构,并存放在方法区中。同时JVM会自动为CONSTANT_String_info常量表中 的字符串常量字面值 在堆中创建 新的String对象(intern字符串对象)。然后把CONSTANT_String_info常量表的入口地址转变成这个堆中String对象的直接地址(常量池解析)。

源代码中所有相同字面值的字符串常量只可能建立唯一一个intern字符串对象。另外,我们也可以调用String的intern()方法来使得一个常规字符串对象成为intern字符串对象。

好了,下面我们来讨论一下第一种方法,也是大家非常常用的方法:

String s=”Hello world!”

首先在编译期,也就是在运行这段指令之前,JVM就已经为”Hello world”在堆中创建了一个intern字符串,局部变量s存储的是早已创建好的intern字符串的堆地址。也就是说,不管有几条String s1=”Hello world”,堆中都只有1个值为”Hello world”的字符串。

那么第二种方法呢?

String s=new String(“Hello world”)

同样在编译期,JVM也为”Hello world”在堆中创建了一个intern字符串,然后用这个intern字符串的值来初始化new出来的新String对象,局部变量s实际上存储的是new出来的堆对象地址。 此时在JVM管理的堆中,有两个相同字符串值的String对象:一个是intern字符串对象,一个是new新建的字符串对象。

最后,来段代码做个更形象的比较:

//代码1
String sa = "ab";
String sb = "cd";
String sab=sa+sb;
String s="abcd";
System.out.println(sab==s); // false
//代码2
String sc="ab"+"cd";
String sd="abcd";
System.out.println(sc==sd); //true

代码1中局部变量sa,sb存储的是堆中两个intern字符串对象的地址。而当执行sa+sb时,JVM首先会在堆中创建一个StringBuilder类,同时用sa指向的intern字符串对象完成初始化,然后调用append方法完成对sb所指向的intern字符串的合并操作,接着调用StringBuilder的toString()方法在堆中创建一个String对象,最后将刚生成的String对象的堆地址存放在局部变量sab中。而局部变量s存储的是常量池中”abcd”所对应的intern字符串对象的地址。 sab与s地址当然不一样了。这里要注意了,代码1的堆中实际上有五个字符串对象:三个intern字符串对象、一个String对象和一个StringBuilder对象。
代码2中”ab”+”cd”会直接在编译期就合并成常量”abcd”, 因此相同字面值常量”abcd”所对应的是同一个拘留字符串对象,自然地址也就相同。

二、String,StringBuffer和StringBuilder

  1. 通过查看源码可以发现,String中的value[]是常量(final)数组,只能被赋值一次;而StringBuffer中的value[]就是一个很普通的数组,而且可以通过append()方法将新字符串加入value[]末尾。
  2. StringBuffer和StringBuilder的区别是StringBuffer是线程安全的,而后者不是。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。另外,由于String是不可变的,也就是只读,自然也是安全的了。
  3. 因为String对象中的value[]是不能改变的,每一次合并后字符串值都需要创建一个新的String对象来存放。循环1000次自然需要创建1000个String对象和1000个StringBuilder对象,效率低就可想而知了;而StringBuffer/StringBuilder,只需要将自己的value[]数组不停的扩大来存放即可,循环过程中无需在堆中创建任何新的对象,效率自然就高了。

三、总结:

  1. 不停的创建对象是程序低效的一个重要原因。那么相同的字符串值能否在堆中只创建一个String对象?可以!除了程序中的字符串常量会被JVM自动创建拘留字符串之外,调用String的intern()方法也能做到这一点。当调用intern()时,如果常量池中已经有了当前String的值,那么返回这个常量指向intern对象的地址。如果没有,则将String值加入常量池中,并创建一个新的intern字符串对象。
  2. String的种种行为都来源于它的immutable性. 因为它是不变的,没有线程安全问题,可以无限共享,池化当然最节省时间空间; 也因为它是不变的,用”+”导致N多的新对象生成,才生的效率问题.

四、知识补充:

equals 和 == 的区别

  1. equals 方法(是String类从它的超类Object中继承的)被用来检测两个对象是否相等,即两个对象的内容是否相等。
  2. ==用于比较引用和比较基本数据类型时具有不同的功能:比较基本数据类型,如果两个值相同,则结果为true ; 在比较引用时,如果引用指向内存中的同一对象,结果为true

堆、栈与常量池:

  1. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
  2. 堆:存放所有new出来的对象。
  3. 静态域:存放静态成员(static定义的)
  4. 常量池:存放字符串常量和基本类型常量(public static final)。

栈和常量池中的对象可以共享,堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。

你不能错过的Eclipse插件

今天晚上估计要在公司待的很晚了,趁着一些任务在自动运行的间隙,抽空整理一下自己喜欢的一些eclipse插件:

  1. spket:   http://www.spket.com/update
    一款很好用的JS、XML编辑器, 有着很体贴的intellisense
  2. vrapper(imitate vim): http://vrapper.sourceforge.net/update-site/stable
    模拟VIM的一款插件,虽然和真正的VIM相比还少一些功能,但基本上一些常用的功能都有了,而且相比与eclim这个直接内嵌VIM的插件,它显得更为轻量,而且保留eclipse自身一些好用的快捷键。提示一下,在老版本的eclipse(ganymede)里,好像装不上。
  3. subclipse: http://subclipse.tigris.org/update_1.6.x
    相信用过SVN的人都会用过这款插件,有了这个,在eclipse操作SVN不但更方便,而且更直观。
  4. eclemma: http://update.eclemma.org/
    用于统计测试代码的覆盖率,可以帮助你找出遗漏的测试部分 。
  5. veloeclipse:http://veloeclipse.googlecode.com/svn/trunk/update/
    用velocity进行页面开发的话,那么eclipse自带的编辑器肯定满足不了你的需要,不但没着色,也没提示。而这款插件正好弥补了上述的不足,用过你就会喜欢上的。相比另一款velocity编辑插件, http://veloedit.sourceforge.net/updates/,它更为好用,并且不会像后者那样经常出现无法正常打开的现象。
  6. findbugs:http://findbugs.cs.umd.edu/eclipse
    顾名思义,是帮助你更快地找出代码里的Bugs的。用一下,你就能感受到它的神奇。
  7. spring IDE: http://springide.org/updatesite/
    大名鼎鼎的spring IDE,就不用多说了。

这次就先介绍这几个了,以后有发现更好的,我会及时与大家分享的。

终于成为本本一族!

前几天由于自己的不小心,把跟了自己多年的台式机的主板给弄坏了,本来想去保修的,结果看了一下标签,保修期居然刚过了2个月,杯具啊…

其实早就想买本本了,只不过对那台式机有深厚的感情,而且一直工作地非常稳定,也不忍心将它打入冷宫.这一次虽然它受伤了,但我还是会把它救回来的,只不过接下来它要退居二线了.

小Y!一次不经意地懈逅,让我深深地爱上了它.它那时尚的外表,再加上强劲的配置,真让人欲罢不能.虽然它侧边那条橙色的条纹让我有点别扭,但瑕不掩瑜,仍然非常值得拥有.

昨天,y460被我收入囊中…特写篇博文记念一下:)

买来后,迫不及待试了一下它的卖点之一:JBL专业音响.果然名不虚传,比我那个创新的2.1还要好,音质清晰浑厚.大喜之外,还体验了一下许多酷酷的功能:slidebar的拉链式的锁屏效果与win7的aero效果相得益彰;双显卡一键切换的功能让我在性能和节能上能自由选择….太多太多了,更多的功能还要在以后慢慢发掘.

其实买本本最主要的目的还是为了方便工作,由于今后的工作平台更多的会在linux下,于是,在体验了y460的几个主要功能后,我开始装上了久闻大名的lucid lynx(ubuntu 10.04 LTS),这只清醒的猞猁作为LTS版本,其重要性可见一斑.一改之前的土黄色,这一次用上了更为悦目清新的紫色,其特效丝毫不逊色于win7.而且与社区的结合非常紧密,像Twitter和Facebook都无缝地整合在里面,不过由于国情,这些功能就有点打折扣了.由于本篇博文是为了记念本本的到来,ubuntu的功能我就不详细介绍了。

我相信我会充分利用好如此优秀的装备,开启事业的新篇章,迎接更美好的未来。

《Maven权威指南》学习笔记(三)

  1. 构建生命周期
    1. Maven使用POM描述项目,将其建模成一些名词.在Maven中这些“动词”是由Maven插件包装的一些目标,它们绑定到一个构建生命周期的阶段中.当你让Maven构建一个项目的时候,你其实是让它一步步通过那些预定义的有序的阶段,并且运行所有注册到某个特定阶段的目标
    2. Maven中有三种标准的生命周期:清理(clean),默认(default)(有时候也称为构建),和站点(site)
      1. 清理生命周期 (clean):它包含了三个生命周期阶段pre-clean,clean,post-clean
        1. 简单的运行clean:clean目标不会完整的执行该生命周期,但是指定clean阶段就能使用clean生命周期,并且逐个的经过生命周期阶段,直到到达clean阶段(可能未到post-clean阶段就停了)
        2. 指定post-clean阶段能经过完整的clean生命周期,直到post-clean阶段.
        3. 直接运行pre-clean阶段会提示:[INFO] No goals needed for project – skipping.可以在它的构建配置中,绑定了某个目标至pre-clean阶段
        4. 可以自定义Clean插件的行为去删除构建输出目录以外的文件
      2. 默认生命周期 (default):它是一个软件应用程序构建过程的总体模型。第一个阶段是validate,最后一个阶段是deploy
      3. 站点生命周期 (site):它包含了四个阶段:1. pre-site 2. site  3. post-site  4. site-deploy  默认绑定到站点生命周期的目标是:1. site – site:site  2. site-deploy -site:deploy
      4. 在上述这些生命周期里,如果某个生命周期阶段没有目标绑定在其上,运行该阶段会提示[INFO] No goals needed for project – skipping
        » Read more…
Page 1 of 41234