Learn by Making Notes.
Share by Posting Notes.

Sat, Aug 13, 2016

Eclipse在debug Java代码时,可以提前从当前方法中返回。 提前返回使得在debug时可以跳过某些代码的执行,或者强迫当前方法返回某个指定值。

如果要从void方法中提前返回,只需要鼠标右键弹出菜单,然后点击Force Return就可以,

force return from void method

如果要让当前方法返回某个指定值,则先打开“Display View”,输入并选中返回值,然后鼠标右键弹出菜单,点击Force Return

force return a specified value

另外,在debug web程序时,某些时候可能想要中止当前正在debugging的request,这时可以通过在“Display View”中抛出 一个异常来中止当前request。通过这种方式,可以避免继续执行当前request给server带来的副作用。

throw an exception

参考文档

Wed, Jul 13, 2016

Some tmux tips.

Make Two Panes Take Full Screen Side by Side

Scenario: I have one tmux session with one window opening, in which five panes takes the window’s screen. I finish my coding and try to commit the code to git. While submitting, I want to two panes occupy full tmux screen side by side – one is for git diff, the other is for git add.

Solution: Create a new temporary window. Use join-pane to move an existing pane into the new window. Now two panes are side by side in the new window, do your git diff and git add. When finish, use join-pane to move the pane back. And if you like, kill the newly created window.

All following commands should follow prefix key, C-b.

# create a new temp window 
c

# list all panes in the session
# you will find pane index in command output, like '0.0', 
#   which means the first pane of the first window                       
:list-panes -s     

# move a pane into another pane
# -h makes two pane position horizontally    
# -s specifies source pane, -t for dest pane
:join-pane -h -s 0.0 -t 1.0

# do your job ...

# move the pane back to previous window
:join-pane -s 1.1 -t 0.0

# kill the temp window
:kill-window -t 1

Wed, Jul 13, 2016

苹果系统上的网易云音乐在播放时默认会缓存歌曲。通过下面的方法可以找到缓存的路径。

打开网易云音乐,随便播放一首没有听过的歌曲。然后运行下面的命令,

>lsof | grep -e "[[:digit:]]\+w" | grep -i netease
NeteaseMu   866 hong   22w     REG                1,4       1198 3911953 /Users/hong/Library/Saved Application State/com.netease.163music.savedState/windows.plist
NeteaseMu   866 hong   34w     REG                1,4    4788183 4437551 /Users/hong/Library/Containers/com.netease.163music/Data/Caches/online_play_cache/186001-_-_128-_-_d08add8397181cefb1014a7b09ee4a92.uc!

186001-_-_128-_-_d08add8397181cefb1014a7b09ee4a92.uc!就是网易云音乐缓存的歌曲。 /Users/hong/Library/Containers/com.netease.163music/Data/Caches/online_play_cache/就是缓存歌曲的目录。 把后缀从.uc!改成.mp3就可以通过iTunes等播放了。

注:网易云音乐的版本是Mac版1.4.4 (470)。

Tue, Jul 05, 2016

tmux is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen.

上面的描述来自tmux的manual page (man tmux)。简单地说,tmux是一个可以在一个窗口里管理多个terminals的工具。

(环境:OS X 10.11.4, tmux 2.2,iTerm2 3.0.2)

为什么用tmux

  • 窗口管理
    比如做Ruby on Rails项目时,你可能需要一个终端窗口(不管是terminal window还是terminal tab)打开vim编辑源码, 一个窗口打开sqlite3查询数据库,一个窗口看本地server的log或者通过byebug来debug,一个窗口用来输入git、rake之类的命令。 用tmux就可以在一个“screen”内同时管理这些terminal,而不用开五个terminal窗口互相切换。
  • 远程工作
    通过ssh登录到远程主机上工作。通过tmux,你可以在断开ssh连接时,保留工作现场不丢失。
  • 上下文切换
    假如同时工作在两个不同类型的项目上,通过tmux可以用两个不同的tmux session来管理这两个项目的窗口。 通过切换session,可以很方便地切换到不同项目的工作现场。
tmux snapshot

安装

$ brew install tmux

基本概念

一个session管理着一个或者多个terminal。一般来说,不同的项目、不同的工作主题等对应着不同的tmux session。 这样通过session就可以很方便地切换“工作环境”。一个session可以有一个或者多个window。 window可以进一步分成不同的pane。在一个时刻,整个“屏幕”只会被一个window占用。pane就是“屏幕”上的一块长方形区域。

tmux是基于server-client的。session信息放在server端,client连上server后可以显示、操作session。

基本使用

tmux后可以接一个命令,比如新建一个session的命令是new-session

阅读更多…

Mon, Jul 04, 2016

最近在CI上运行测试代码的时候遇到一个java.lang.VerifyError错误。

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.129 sec <<< FAILURE! - in com.example.CustomerTest
runTest(com.example.CustomerTest)  Time elapsed: 0.009 sec  <<< ERROR!
java.lang.VerifyError: (class: au/com/dius/pact/consumer/PactProviderRule, method: findPactVerification, signature: (Lau/com/dius/pact/consumer/PactVerifications;)Ljava/util/Optional;, offset: 12) Illegal type 262144 in constant pool
    at com.example.CustomerTest.<init>(CustomerTest.java:32)

JVM加载class文件时会做字节码校验(bytecode verification)。这篇文档非常详细地讲了JVM会做哪些校验。 如果你的class文件是由java源文件通过javac编译出来的,那么基本上不用担心bytecode verification。 如果class文件是由asm、cglib等动态生成出来的或者由其它编译器生成的,那么JVM在校验它的bytecode时就有可能失败。 失败的原因可能是你生成的bytecode有bug,也可能是由于新版本的JVM加入了新的验证条件后导致原来可以通过验证的bytecode现在不能通过了。

很多Java框架都会动态生成class文件,再加上JVM版本也会时不时地修改它的bytecode verification行为。 所以,运行代码时偶尔会遇到java.lang.VerifyError错误。 在不能修改框架代码或者切换JVM实现的情况下,JVM提供了一些选项可以让你改变或者绕过bytecode verification。

-XX:-UseSplitVerifier

-XX:-UseSplitVerifier可以让JVM不开启“type-checking verifier”。 这样就不强制要求class文件含有StackMapTable(所有Java 7 version 51之后的class文件默认要求含有StackMapTable)。

-noverify

-noverify选项可以关闭bytecode verification。

有的观点认为某些bytecode verification除了给动态生成bytecode增加麻烦之外,并没有什么大用。 但是这篇文章强烈建议不要关闭bytecode verification,特别是在生产环境里。 因为bytecode verification可以检测到恶意代码或者代码中的bug。 特别是代码中的bug,因为没有人可以保证(动态产生的)字节码是百分百bug free的。

回到我的问题,由于PactProviderRule类来自于外部依赖,CI上的JVM也不能替换 (CI上用的是非oracle的JVM实现,该测试代码在本地的官方JVM上是可以运行通过,所以CI上的失败有一定可能是其用的JVM实现的原因), 所以一个简单的方法是在maven跑测试代码时,给JVM加上-noverify选项。

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>-noverify</argLine>
    </configuration>
  </plugin>

更多的参考文档:

Wed, Jun 15, 2016

介绍一种git环境下的“轻量级”的“code review”方法。 “code review”加上引号是因为它只能算“查看代码改动”的一种方式。 如果由于某些原因导致像Gerrit这样的专业code review工具不能用时,可以考虑一下它。

简单的步骤如下:

  • Reviewee把代码改动输出到一个文件里。
  • 把上一步生成的文件发给reviewer。
  • Reviewer进行code review。

Reviewee

如果reviewee已经把代码改动提交到本地仓库, 假设commit的SHA-1是e3fbbbcfd(如果commit是最新的提交,那么e3fbbbcfd也可以用HEAD替代),

$ git show e3fbbbcfd --color > change-to-review

假设代码改动还没有提交,

$ git diff --color -- path/to/file-to-review-1 path/to/file-to-review-2 > change-to-review

--color选项会用颜色高亮代码的改动。

Reviewee通过邮件或者聊天工具等方式把change-to-review文件发给reviewer。

Reviewer

Reviewer检查代码改动,

$ cat change-to-review | less -R

-R选项使less可以显示颜色。

less -R

还可以用diff-highlight来进一步高亮代码改动,方便review代码。 下载diff-highlight脚本,放到系统的PATH目录下。然后运行如下命令,

$ cat change-to-review | diff-highlight | less -R

效果如图,

diff-highlight

Mon, Jun 06, 2016

介绍一下如何利用Node.js搭建一个简单的静态文件server。 这里用到了Express,Express是Node.js世界的web framework。

新建工程

创建工程目录,

$ mkdir my-app
$ cd my-app

为自己的工程建一个package.json文件,

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (my-app)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to E:\tmp\my-app\package.json:

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this ok? (yes)

npm init会问你一些问题,直接回车表示接受默认值。package.json的更多信息见此文档

安装依赖

安装Express,--save选项会在package.json文件里加上对express的依赖。

$ npm install express --save

编写代码

如果在执行npm init时没有指定新的名字,那么程序的“main”文件就是index.js。编辑index.js文件如下,

var express = require('express');
var app = express();

app.listen(3000, function() {
  console.log('i am alive on port 3000');
});

app.use(express.static(__dirname + '/public'));

把静态文件放到public目录下面。 假设public目录下面有个index.html文件,那么就可以通过http://localhost:3000/index.html来访问文件了。

如果想给静态文件指定URL前缀,可以这样(详见文档),

app.use('/static', express.static(__dirname + '/public'));

现在可以通过http://localhost:3000/static/index.html来访问文件。

Thu, Apr 21, 2016

Working in process

Vim的命令需要经常使用才不会忘记。 把Vim打造成适合日常工作的“轻量级IDE”可以有助于熟悉和记忆Vim命令。

一些基本的Vim配置

设置mapleader

先在.vimrc文件里设置一下mapleader,

let mapleader = ',' 

然后就可以用快捷键,+a来快速地输入命令:Ack!

nmap <leader>a :Ack! 

安装一个插件管理系统

装一个插件管理系统可以更好地管理Vim的插件。我选了pathogen.vim作为Vim的插件管理。

搜索文件内容

ack.vim插件可以用来搜索文件内容。

nmap <leader>a :Ack!  

按快捷键,a就可以进行文件内容搜索了。比如输入“sku”就会列出所有含“sku”的文件,效果见下面的截图。

diff-highlight

ack.vim插件是借助第三方的程序来进行搜索的,然后把搜索结果展示在Vim里。 默认情况下,ack.vim使用ack来进行搜索。ack相比grep要更快、更好用The Silver Searcher(ag)是一个类似ack的搜索工具,号称比ack还要快。 OS X下可以用homebrew方便地安装它们,

brew install ack
brew install ag

ack和ag也可以在Windows下安装。 ag在Windows下可通过Cygwin方式来安装,详见ag的官方Wiki

让ag成为ack.vim的搜索工具,

let g:ackprg = 'ag --nogroup --column'  " 让ack.vim使用ag作为搜索工具

更快地搜索

基本上,ag和ack能接受的参数是类似的。

默认情况下,ack和ag会搜索当前工作目录。可以通过限制搜索目录来提高搜索速度,比如,

:Ack! text-to-search some_dir

也可以限制搜索的文件类型,比如

:Ack! --java text-to-search 

ack默认会忽略.git目录。也可以使用--ignore-dir=name选项来指定要忽略的目录。 对于ag,默认会忽略.gitignore中指定的文件。 也可以在.agignore文件里加上想忽略的文件。比如,忽略maven工程下的target目录。 .agignore的语法和.gitignore类似。

ack的更多选项见其官方文档。 如果某个工程需要经常使用某些选项,可以把这些选项放到工程目录下的.ackrc文件中。

文件系统导航

文件系统的导航可以借助NERDTree插件来实现。

nmap <leader>d :NERDTreeToggle<CR>

按下快捷键,d,效果见如下截图,

diff-highlight

在NERDTree窗口按?键可以显示帮助信息。

:NERDTreeFind命令可以在NERDTree窗口中显示当前文件的位置,类似于Eclipse的”Link with Editor”功能。

nmap <leader>df :NERDTreeFind<CR>

现在输入快捷键,df就可以在NERDTree窗口中显示当前文件。

快速打开文件

借助command-t插件可以实现文件的快速打开。

阅读更多…