代码之旅

I love Coding !

AOP Alliance 项目是许多对Aop和java有浓厚兴趣的软件开发人员联合成立的开源项目,旨在确定Aop的标准。面向切面编程是设计和开发应用程序的一个好方案,AOP 提供了一种通用方法来构建关注点(横切关注点),并将它们灵活地作为模块插入应用。但是,也带来了问题: 不同的AOP实现并不能适配所有环境。

大多数人不相信完美系统,我们认为一个系统总是能处理给定的一个问题和环境(不需要适配其他)。现在已经有了很多的AOP实现或AOP相关的技术,例如,通用代理,拦截器或字节码翻译工具。具体如下:

  • AspectJ: 面向切面的源码级和字节码级别的织入器。
  • AspectWerkz: 一个面向切面框架(字节码动态织入,支持XML配置)。
  • BCEL: 一个字节码翻译器
  • JAC: 一个面向切面框架(字节码动态织入,可配置切面)
  • Javassist: 字节码翻译器,有高级API。
  • JBoss-AOP: 拦截和基于元数据的AOP框架(支持独立运行和在JBoss应用服务器种运行)
  • JMangler: 一个字节码翻译器,支持兼容翻译
  • Nanning: 一个面向切面织入器框架
  • Prose: 一个面向切面动态字节码织入框架

对我们而言,这些实现没有好与坏的区别,都适合于某些问题或环境。AOP Alliance的目的不是提出新的AOP模型,也不是提供一个更好的AOP实现来解决所有场景的问题。其目的在于提炼所有AOP实现的共同核心能力:

  • 避免重复造轮子,尽量重用
  • 简化某个环境下现有AOP组件的适配
  • 简化开发工具集成AOP能力的工作
阅读全文 »

Shell 脚本(shell script),是一种为 shell 编写的脚本程序。Linux 的 Shell 种类众多,常见的有:

  1. Bourne Shell(/usr/bin/sh或/bin/sh)
  2. Bourne Again Shell(/bin/bash)
  3. C Shell(/usr/bin/csh)
  4. K Shell(/usr/bin/ksh)
  5. Shell for Root(/sbin/sh)
  6. Z Shell /usr/bin/zsh)

由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

阅读全文 »

之前有听说过 java 8 的 lambda 实现不再是java 1.5的匿名内部类语法糖。今天刚好有时间看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class App {

@FunctionalInterface
public interface LambdaDemo{
public void runLambda();
}
public static void doSomething(LambdaDemo demo){
demo.runLambda();
}

public static void main(String[] args) {
doSomething(()->System.out.println("hello world!"));
}
}
阅读全文 »

在java编程中我们偶尔能看到“时钟回拨”的现象:

1
2
3
4
5
6
7
8
//now() returns 2019-01-13T22:34:05.681Z
order.setCreationTime(Instant.now());

//... 执行一些其他工作

//now() returns 2019-01-13T22:34:03.123Z
//发现时间比创建时间提前了,仿佛时间被回拨
order.setCancelationTime(Instant.now());
阅读全文 »

先来看个最简 DEMO(双向通信):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// server端
public class SocketServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8080);

// 阻塞等待连接
Socket socket = server.accept();

// 从socket中获取输入流,并建立缓冲区进行读取
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("Received: " + sb);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello client".getBytes("UTF-8"));
outputStream.flush();

// 关闭流&连接
inputStream.close();
outputStream.close();
socket.close();
server.close();
}
}
// client 端
public class SocketClient {
public static void main(String args[]) throws Exception {
Socket socket = new Socket("127.0.0.1", 8080);
// 建立连接后获得输出流
OutputStream outputStream = socket.getOutputStream();
String message="hello server";
outputStream.write(message.getBytes("UTF-8"));
//通知server消息发送完成
socket.shutdownOutput();

// 读取消息
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("Received: " + sb);

// 关闭流&连接
inputStream.close();
outputStream.close();
socket.close();
}
}
阅读全文 »

对象的创建和销毁在一定程度上会消耗系统的资源,虽然jvm的性能在近几年已经得到了很大的提高,对于多数对象来说,没有必要利用对象池技术来进行对象的创建和管理。但是对于有些对象来说,其创建的代价还是比较昂贵的,比如线程、tcp连接、数据库连接等对象。对于那些创建耗时较长,或者资源占用较多的对象,比如网络连接,线程之类的资源,通常使用池化来管理这些对象,从而达到提高性能的目的。

apache-common-pool提供了一个通用的对象池技术的实现。可以很方便的基于它来实现自己的对象池。比如DBCP和Jedis他们的内部对象池的实现就是依赖于apache-common-pool(本文分析的是apache common pool2)。

阅读全文 »

SOCKS是一种网络传输协议,主要用于客户端与外网服务器之间通讯的中间传递。当防火墙后的客户端要访问外部的服务器时,就跟SOCKS代理服务器连接。这个代理服务器控制客户端访问外网的资格,允许的话,就将客户端的请求发往外部的服务器。根据OSI模型,SOCKS是会话层的协议,位于表示层与传输层之间。

阅读全文 »

CSV 格式的定义

  1. 每条记录都位于一条单独的行上,由行分隔符(CRLF)分开。例如:
1
2
aaa,bbb,ccc CRLF
zzz,yyy,xxx CRLF
  1. 文件中的最后一条记录可能有也可能没有结束符标志,例如:
1
2
aaa,bbb,ccc CRLF
zzz,yyy,xxx
  1. 第一行可能存在标题行,包含记录字段的对应名称,标题行的标题数与记录字段数相同。例如:
1
2
3
field_name,field_name,field_name CRLF
aaa,bbb,ccc CRLF
zzz,yyy,xxx CRLF
  1. 在标题和记录中,可能有一个或多个字段,使用,号分隔,最后一个字段记录后面不能有分隔符。例如:
1
AAA,BBB,CCC
  1. 每个字段可能包含在双引号,也可能不包含在内(microsoft excel 没有使用双引号)。如果字段没有用双引号括起来,那么双引号可能不会出现在字段内。例如:
1
2
"aaa","bbb","ccc"CRLF
ZZZ,YYY,XXX
  1. 如果字段包含换行符(CRLF),双引号,和逗号,那么字段值应该被包含在双引号中,例如:
1
2
"aaa","b CRLFbb","ccc" CRLF
zzz,yyy,xxx
  1. 如果使用双引号括起字段,要在一个字段内使用双引号必须通过在前面添加另一个双引号的方式进行转义。例如:
1
"aaa","b""bb","ccc"

ABNF 语法

1
2
3
4
5
6
7
8
9
10
11
12
13
file = [header CRLF] record *(CRLF record) [CRLF]
header = name *(COMMA name)
record = field *(COMMA field)
name = field
field = (escaped / non-escaped)
escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
non-escaped = *TEXTDATA
COMMA = %x2C
CR = %x0D ;as per section 6.1 of RFC 2234 [2]
DQUOTE = %x22 ;as per section 6.1 of RFC 2234 [2]
LF = %x0A ;as per section 6.1 of RFC 2234 [2]
CRLF = CR LF ;as per section 6.1 of RFC 2234 [2]
TEXTDATA = %x20-21 / %x23-2B / %x2D-7E

java命令用于启动JVM虚拟机。Java启动参数分为3种:

  1. 标准参数: 所有的JVM实现都必须实现这些参数的功能,而且向后兼容。JVM的标准参数都是以”-“开头。
  2. 非标准参数: 默认JVM(HotSpot虚拟机)实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容.JVM的非标准参数都是以”-x“开头。
  3. 非stable参数:此类参数通常具有特定的系统要求,并且可能需要对系统配置参数的特权访问。各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用。JVM的非stable参数都是以”-xx“开头。
阅读全文 »