0%

一、Guice简介

Google公司的Bob lee开发的轻量级IoC容器,其特点是:

  1. 速度快,号称是spring的100倍速度
  2. 无配置文件,实用JDK5.0的annotation描述组件依赖,简单,而且有编译器检查和重构支持
  3. 简单,代码量很少

二、简单样例

  1. 详细代码:https://github.com/hisenyuan/IDEAPractice/tree/master/src/main/Java/com/hisen/jars/guice
  2. 依赖
1
2
3
4
5
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.2</version>
</dependency>
  1. 测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HelloApp extends BaseServer {
@Inject
private HelloServiceImpl hello;

@Test
public void testSayHello() {
// 方式一
Injector injector = Guice.createInjector();
HelloService helloService = injector.getInstance(HelloService.class);
helloService.sayHello("hisen");

// 方式二 其实是在BaseServer中做了方式1的事情 【类似Spring的方式】
hello.sayHello("1");
}
}

三、解决问题

1
Java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLJava/lang/String;LJava/lang/Object;LJava/lang/Object;)V

github有人遇到同样的问题:https://github.com/SeleniumHQ/selenium/issues/3880

把本地的guava版本由19.0改为21.0成功解决问题

一、名词解释

1.1 同步与异步

同步与异步主要是针对CPU来说的

  1. 同步:CPU必须等着结果返回,这期间不能干别的;
  2. 异步:CPU不必等着结果返回,这期间可以干别的;

1.2 阻塞与非阻塞

阻塞与非阻塞主要是针对I/O来说的

  1. 阻塞:I/O线程会挂起,需等待结果;
  2. 非阻塞:I/O线程不必挂起,不等待结果;

1.3 伪异步I/O

本质上还是同步阻塞I/O
不过是在服务器把socket链接封装成Task提交给线程池处理
因为有队列,所以可以突破C:S=1:1的比例

1.4 I/O多路复用

通过把多个I/O的阻塞复用到一个阻塞上,从而使得系统在单线程情况下可以处理多个客户端的请求。
类似于linux的epoll、select

1.5 多路复用器

Selector,核心是通过Selector来轮询注册在其上的Channel
当发现有Channel就绪就返回Channel的选择键集合,进行I/O操作;

二、不同I/O模型对比表格

Read more »

这是之前的一个帖子:oracle - mysql - 数据库事务隔离级别介绍
写的不全面, 按现在的理解,重新写一个;

一、名词解释

脏读:在一个查询事务过程中,读到了其它事务没有提交的数据;
不可重复读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的更新事务提交了;
幻读:一个事务查询过程中,多次查询得到了不一致的结果,原因是:有别的删除事务/插入事务提交了;

二、数据库隔离级别

| name | 名称 | 脏读 | 不可重复读 | 幻读 | 加锁读 |
|:—–|:—–|:—–|:—–|:—–|:—–| :—–|
| Read uncommitted | 读未提交 | Yes | Yes | Yes | No |
| Read committed | 读已提交 | No | Yes | Yes | No |
| Repeatable read | 可重复读 | No | No | Yes | No |
| Serializable | 序列化 | No | No | No | Yes |

默认的隔离级别为:RR,原因:5.1之后版本,如果Binlogog开启语句级别,必须为RR,RC可能会导致Binlog数据错误(详情);

三、控制方式

读未提交:每次都是读数据最新的版本(包括事务未提交的数据);
读已提交:MVCC控制;
可重复读:MVCC控制;
序列化:在读取的每一行上加锁,只能按顺序进行读写;

四、InnoDB MVCC(多版本并发控制)原理

Read more »

一、命令组合

1
2
3
4
$ more sort.log | awk '{print $1}' | sort | uniq -c | sort -k1nr | head -3
4 5
3 1
2 2

二、命令详解

more:一次读取少量的数据,避免一次性载入大文件,比cat好些
awk ‘{print $1}’:以awk默认的分隔符,并且打印第一列
sort:把上一步的结果按ASCII排序
uniq -c:如果重复那么计数,uniq命令可以组合很多其它参数
sort -k1nr:根据第一列的数据进行排序,n是按数值大小排序,r是倒序排序
head -3:显示前面三行数据

三、原始数据

Read more »

某个文件夹下面有n个文件,需要移动大于10M的文件到/tmp/目录下

实现命令

1
find . -type f -size +100M -exec mv {} /tmp/ \;

find 查找
. 当前目录
-type 文件类型:f 文件,d 目录
-size 文件大小:+100M +:大于 -:小于 空:等于
-exec 管道命令,将前面的查询结果传递给后面的命令
{} 指前面传递过来的的查询结果
; 结束管道命令

一、出生过程

这里讲述的是第一次出生的过程,即之前class没有被加载。

1.1 类初始化

1.1.1 加载

1.1.1.1 通过类的全限定名获取定义此类的二进制字节流(可以从zip包、网络、运行时动态生成);
1.1.1.2 将这个字节流所代表的静态存储结构转化为方法去运行时数据结构;
1.1.1.3 在内存(方法区)中生成一个代表这个类的Java.lang.Class对象,作为方法区这个类各种数据访问的入口;

1.1.2 验证

1.1.2.1 文件格式验证

1.1.2.1.1 魔数是否以0xCAFEEBABE开头(咖啡宝贝)
1.1.2.1.2 主、次版本号是否在当前虚拟机处理的范围之内(不同的jdk版本编译出来的版本不一致,可向前兼容)
1.1.2.1.3 常量池是否有不被支持的类型(检查常量tag标志)
1.1.2.1.4 指向常量的各种索引值是否指向不存在或者不符合类型的常量
1.1.2.1.5 CONSTANT_Utf8_info型的常量中是否有不符合UTF-8编码的数据
1.1.2.1.6 Class文件中各个部分以及文件本身是否有被删除或者附加的其它信息

这些操作是为了确保Class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身安全

1.1.2.2 元数据验证

1.1.2.2.1 是否有父类(Object除外)
1.1.2.2.2 是否继续了不允许继承的类(被final修饰的)
1.1.2.2.3 如果当前不是抽象类,是否实现了其父类或接口中要求实现的所有方法
1.1.2.2.4 类中的字段、方法是否与父类产生矛盾(如覆盖父类final字段、不合法的重载)
这些操作是对字节码进行语义分析,确保符合Java语言规范要求

1.1.2.3 字节码验证

1.1.2.3.1 确保操作数栈的数据类型与指令代码序列能完美配合(反例:操作数栈为int,使用的时候按long加载)
1.1.2.3.2 确保跳转指令不会跳转到方法体以外的字节码指令上
1.1.2.3.3 确保方法体重点类型转换是有效的
这些操作主要是通过数据流和控制流分析,确定程序的语义是合法的、符合逻辑的。
JDK1.6之后有一个优化,利用StackMapTable来验证是否合法

1.1.2.4 符号引用验证

1.1.2.4.1 符号引用中通过字符串描述的全限定名是否能找到对应的类
1.1.2.4.2 符号引用中的类、字段、方法是否可以被当前类访问
在将符号引用转化为直接引用的时候触发符号引用验证

Read more »

一、背景

题意:一个数组有奇数个元素,其中只有一个元素出现一次,其它都出现了2次

方案A:利用hashMap存储出现的次数,然后遍历,复杂度O(3/2N)=O(N);
方案B:利用bitmap,根据数组元素的大小确定位置,做取反(0->1->0);
方案C:利用异或的特性快速找出,最简单,高效;

二、异或

a^a=0
0^a=a
异或支持:交换率、结合率
因此:
a^b^c^b^c=a^(b^b)^(c^c)=a

三、代码

Read more »

一、代理简介

1.1 代理是什么

举个例子:快到吃饭的点了,你有两种选择:1)自己做,2)叫外卖
1.1.1 自己做你嫌麻烦,那就叫外卖,只管收外卖其它不关注(解耦);
1.1.2 自己做的不好吃,那厨师上门,厨师给你增强菜的味道(增强);

官方定义:对其他对象提供一种代理以控制对这个对象的访问。

1.2 使用场景是什么

1.2.1 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。

1.2.2 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。

1.2.3 Spring的AOP机制就是采用动态代理的机制来实现切面编程。

二、CGlib VS JDK 两种方式实现代理

2.1 差异

2.1.1 JDK:只能代理接口
2.1.2 CGlib:直接代理类

2.2 简单demo

Read more »

一、背景

今天中午一个朋友问我一个问题没来得及回,现在折腾一下;
问题:有一个包含以N个空格分割的字符串,求最大子串的长度,要求时间空间复杂度最优;

二、方案:

  1. 朋友给人方案:直接split分割遍历数组,找出最大值;
  2. 面试官的方案:使用StringTokenizer,找出最大值;
  3. 我想到的方案:indexOf计算index差值,找出最大值;

三、结果:

封装的代码比较复杂,目前来看不在么好分析时间复杂度和空间复杂度;
于是就直观得对比了一下时间;

1
2
3
4
//        output
// use(nano): 15486049, by 方案3
// use(nano): 66060102, by 方案2
// use(nano): 80844275, by 方案1

有时间再深入了解下StringTokenizer的源码

四、代码对比

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
String oriStr = "aa aa aaaa aaa a a a aa aa a";
int times = 100000;
// 自定义实现
final long start1 = System.nanoTime();
for (int i = 0; i < times; i++) {
String splitStr = " ";
findMaxLength(oriStr, splitStr);
}
final long end1 = System.nanoTime();

// 利用 StringTokenizer
final long start2 = System.nanoTime();
for (int i = 0; i < times; i++) {
findMaxLength4StringTokenizer(oriStr);
}
final long end2 = System.nanoTime();

// 利用 Split
final long start3 = System.nanoTime();
for (int i = 0; i < times; i++) {
String splitStr = " ";
findMaxLength4Split(oriStr, splitStr);
}
final long end3 = System.nanoTime();

System.out.println("use(nano): " + (end1 - start1) + ", by findMaxLength");
System.out.println("use(nano): " + (end2 - start2) + ", by findMaxLength4StringTokenizer");
System.out.println("use(nano): " + (end3 - start3) + ", by findMaxLength4Split");
// output
// use(nano): 15486049, by findMaxLength
// use(nano): 66060102, by findMaxLength4StringTokenizer
// use(nano): 80844275, by findMaxLength4Split

五、完整代码

Read more »

一、为什么要学Dubbo

近几年一直在使用dubbo进行支付系统的开发;
作为国内比较受欢迎的一个SOA框架,Dubbo使用简单设计优雅;
里面用到的思想和技术,基本上涵盖大部分互联网公司用到的技术;
记得直属领导说过一句话,看完Dubbo他觉得设计者简直就是天才;
而且看完dubbo的源码,对他的影响很大,处处模仿dubbo的思想;

二、文档地址

中文文档:用户文档、开发者指南、源码导读、运维管理
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
用户手册(比较完整):
https://dubbo.gitbooks.io/dubbo-user-book/demos/routing-rule.html
官方博客:
http://dubbo.apache.org/zh-cn/blog/index.html

三、Dubbo创始人博客

最后更新于2014年
https://Javatar.iteye.com/