??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
@Override
public User unmarshal(TO to) throws Exception {
return (User)to;
}
@Override
public TO marshal(User user) throws Exception {
return (TO)user;
}
}
public interface TypeConvert {
@WebMethod
@XmlJavaTypeAdapter(UserTOAdapter.class)
User addUser(User user);
}
]]>
15原码: 00000000 00000000 00000000 00001111 //32?二进?br />
反码Q? 11111111 11111111 11111111 11110000 //0?,1变O
补码Q? 11111111 11111111 11111111 11110001 //最后位?,-15二进?br />
右移2位: 11111111 11111111 11111111 11111100 //双丢弃2?前面30位保?左边?
取反Q?nbsp; 00000000 00000000 00000000 00000011 //0?,1变O
Q1: 3+1
l果: Q-Q?//负号保留,十进?/p>
带符号左U?? 10 << 2 = 40
10 补码: 00000000 00000000 00000000 00001010 //32?二进?br />
左移2? 00000000 00000000 00000000 00101000 //左边丢弃2?双?
l果: 40 //十进?/p>
无符号右U?题:Q?321 >>> 30 = 3
4321原码: 00000000 00000000 00010000 11100011 //32?二进?br />
反码Q? 11111111 11111111 11101111 00011100 //0?,1变O
补码Q? 11111111 11111111 11101111 00011101 //最后位?,-4321二进?br />
无符号右U?0位: 00000000 00000000 00000000 00000011 //双丢弃30?前面二位保留,左边?
l果: 3 //十进?/p>
& 位逻辑?题:44 & 21 = 4
44 补码: 00000000 00000000 00000000 00101100 //32?二进?br />
21 补码: 00000000 00000000 00000000 00010101 //32?二进?br />
& q算: 00000000 00000000 00000000 00000100 //对应的两个二q制位均??l果位才? 否则?
l果: 4 //十进?nbsp;
| 位逻辑?题:9 | 5 = 13
9 补码: 00000000 00000000 00000000 00001001 //32?二进?br />
5 补码: 00000000 00000000 00000000 00000101 //32?二进?br />
| q算: 00000000 00000000 00000000 00001101 //对应的二个二q制位有一个ؓ1Ӟl果位就?
l果: 13 //十进?
^ 位逻辑异或 ? 9 ^ 5 = 12
9 补码: 00000000 00000000 00000000 00001001 //32?二进?br />
5 补码: 00000000 00000000 00000000 00000101 //32?二进?br />
| q算: 00000000 00000000 00000000 00001100 //对应的二q制位相异时Q结果ؓ1
l果: 12 //十进?/p>
~ 位逻辑?? ~9 = -10
9 补码: 00000000 00000000 00000000 00001001 //32?二进?br />
~ q算: 11111111 11111111 11111111 11110110 //最高位?表示Z个负?则进行取反加1
取反: 00000000 00000000 00000000 00001001 //32?二进?br />
Q1: 9+1 //32?二进?br />
l果: -10 //十进?/p>
在计机pȝ中,数g律用补码来表C(存储Q?br />
主要原因Q用补码,可以符号位和其它位l一处理Q同Ӟ减法也可按加法来处理。另外,两个用补
码表C的数相加时Q如果最高位Q符号位Q有q位Q则q位被舍弃?br />
补码与原码的转换q程几乎是相同的?br />
数值的补码表示也分两种情况Q?br />
Q?Q正数的补码Q与原码相同?br />
例如Q?9的补码是00001001?br />
Q?Q负数的补码Q符号位?Q其余位数绝对值的原码按位取反Q然后整个数??br />
例如Q?7的补码:因ؓ是负敎ͼ则符号位?#8220;1”,整个?0000111Q其?位ؓ-7的绝对?7的原?br />
0000111按位取反?111000Q再?Q所?7的补码是11111001?br />
已知一个数的补码,求原码的操作分两U情况:
Q?Q如果补码的W号位ؓ“0”Q表C是一个正敎ͼ所以补码就是该数的原码?br />
Q?Q如果补码的W号位ؓ“1”Q表C是一个负敎ͼ求原码的操作可以是:W号位ؓ1Q其余各位取反,然后再整个数??br />
例如Q已知一个补码ؓ11111001Q则原码?0000111Q?7Q:因ؓW号位ؓ“1”Q表C是一个负敎ͼ所以该位不变,仍ؓ“1”Q其??111001取反后ؓ0000110Q再?Q所以是10000111?
转蝲Q?a >http://blog.csdn.net/zjp8023/archive/2009/05/29/4224121.aspx
float
?double
Q以及与它们对应的包装类 Float
?Double
。它们都依据 IEEE 754 标准Q该标准?32 位Q点和 64 位双_ֺ点二进制小数定义了二进制标准?
IEEE 754 用科学记数法以底Cؓ 2 的小数来表示点数。IEEE 点数用 1 位表C数字的W号Q用 8 位来表示指数Q用 23 位来表示数Q即数部分。作为有W号整数的指数可以有正负之分。小数部分用二进Ӟ底数 2Q小数来表示Q这意味着最高位对应着??(2 -1)Q第二位对应着 ?(2 -2)Q依此类推。对于双_ֺ点敎ͼ?11 位表C指敎ͼ52 位表C尾数。IEEE 点值的格式如图 1 所C?
因ؓ用科学记数法可以有多U方式来表示l定数字Q所以要规范化QҎQ以便用底数?2 q且数点左边ؓ 1 的小数来表示Q按照需要调节指数就可以得到所需的数字。所以,例如Q数 1.25 可以表示为尾Cؓ 1.01Q指Cؓ 0Q?(-1) 0*1.01 2*2 0
?10.0 可以表示为尾Cؓ 1.01Q指Cؓ 3Q?(-1) 0*1.01 2*2 3
一个十q制数能否用二进制QҎ_表示Q关键在于小数部分。我们来看一个最单的数能否_表示。按照乘?取整C的方法,有:
得到一个无限@环的二进制小?img title="Q{QIEEE754" border="0" alt="Q{QIEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image020.gif" width="177" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image020.gif" />Q用有限位无法表C无限@环小敎ͼ因此Q?img title="Q{QIEEE754" border="0" alt="Q{QIEEE754" src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016%5B1%5D.gif" width="44" height="24" real_src="http://www.cnblogs.com/images/cnblogs_com/bossin/WindowsLiveWriter/IEEE754_B489/clip_image016%5B1%5D.gif" />无法用IEEE 754点数精表C。从中也可以看到Q由?/p>
Q?/p>
q四个数也无法精表C。同理:
也无法用IEEE 754点数精表C?/p>
在以0.1~0.9l尾?个小CQ只?.5可以_表示Q(如)Q而其他均无法q行_转换?/p>
上次只测试查询的性能Q而且都是在最优的情况下进行,没有考虑条他情况Q这ơ重C改了试用例Q把整个试的各个过E描q出来(加蝲Q排序,查找的效率)?/span>
场景Q?/span>随机生成5百万条不同的记录Q而每条记录不存在相同的情c现在将q?/span>5百万条记录在不同的情况下q行试。测试结果如?/span>
1?/span>5百万条记录,d查询50万次Q查询前50万条记录Q?/span>
数组性能试加蝲p:6.11
U?/span>数组性能试排序p:18.313
U?/span>数组性能试查找p:3.297
U?/span>数组性能试p?/span>:27.72U?/span>
数组性能试d?/span>:100005888 字节
RBTree性能试加蝲p:53.644
U?/span>RBTree性能试查找p?/span>:2.86U?/span>
RBTree性能试p?/span>:56.504U?/span>
RBTREE性能试共占?/span>:240004864 字节
MAP性能试加蝲p:7.282
U?/span>MAP性能试查找p:0.11
U?/span>MAP性能试p?/span>:7.392U?/span>
MAP性能试 共占?/span>:173554048 字节
2?/span>5百万条记录,d查询5百万ơ(每条记录查询一ơ)
数组性能试加蝲p:6.078
U?/span>数组性能试排序p:17.642
U?/span>数组性能试查找p:33.049
U?/span>数组性能试p?/span>:56.769U?/span>
数组性能试d占用 = 100005552
字节RBTree性能试加蝲p:54.8U?/span>
RBTree性能试查找p?/span>:34.581U?/span>
RBTree性能试p?/span>:89.381U?/span>
RBTREE性能试共占?/span> = 240005024 字节
MAP性能试加蝲p:6.501U?/span>
MAP性能试查找p:0.937U?/span>
MAP性能试p?/span>:7.438U?/span>
MAP性能试 共占?/span>=173553888 字节
3?/span>5百万条记录,d查询5千万ơ(每条数据查询10ơ)
数组性能试加蝲p:6.11U?/span>
数组性能试排序p:17.861U?/span>
数组性能试查找p:331.224U?/span>
数组性能试p?/span>:355.195U?/span>
数组性能试d占用:99990456字节
RBTree性能试加蝲p:53.097U?/span>
RBTree性能试查找p?/span>:345.866U?/span>
RBTree性能试p?/span>:398.963U?/span>
RBTREE性能试共占?/span> = 240005248 字节
MAP性能试加蝲p:7.235U?/span>
MAP性能试查找p:9.375U?/span>
MAP性能试p?/span>:16.61U?/span>
MAP性能试共占?/span>:173554048字节
试文g地址Q?nbsp; /Files/aoneany/search2.rar
================================================================
前面的测试算法中Q有一个地方偷懒(直接使用String.CompareToҎq行比较Q导致查询效率很差,现在对其q行优化Q测试后的数据ؓQ?/span>
5百万条记录,d查询5百万ơ(每条记录查询一ơ)
数组性能试加蝲p:1.016U?/span>
数组性能试排序p:14.485U?/span>
数组性能试查找p:0.703U?/span>
数组性能试p?/span>:16.204U?/span>
RBTree性能试加蝲p:20.705U?/span>
RBTree性能试查找p?/span>:3.75U?/span>
RBTree性能试p?/span>:24.455U?/span>
MAP性能试加蝲p:3.875U?/span>
MAP性能试查找p:1.516U?/span>
MAP性能试p?/span>:5.391U?/span>
场景一
?/span>1Q?/span>2Q?/span>3Q?/span>4Q?/span>5个整敎ͼ分别Ҏ个一数遍?/span>2亿次Qd10亿次Q在不同用例试p的时间如?/span>
Switch试
dp:20.329U?/span>
IF试
dp:20.437U?/span>
Array试
dp:20.703U?/span>
Map试
dp:56.719U?/span>
场景?/span>
?/span>5百万条数据,分别Ҏ一个数据访?/span>10ơ,d查找5千万ơ,在不同用例测试花费的旉如下Q?/span>
Map试
dpQ?/span>4.047U(自己对这l果很怀疑,但是试几次都是q样Q?/span>
内存占用Q?/span>273579872字节
CPU占用Q?/span>50%左右
Array Comparable试
dp: 45.312U?/span>
内存占用Q?/span>160025376字节
CPU占用Q?/span>50%左右
RBTree试
dpQ?/span>63.485U?/span>
内存占用Q?/span>320030976字节
CPU占用Q?/span>50%左右
试文g地址Q?a href="http://www.tkk7.com/Files/aoneany/search.rar">http://www.tkk7.com/Files/aoneany/search.rar
forName是取得Class引用的一U方法,q回一个Class对象的引用?/p>
如果Gumc还没有被加载就加蝲它,在加载过E中QGum的静态子句被执行?/p>
可能产生的异常:ClassNotFoundException
Class.getInterfaces("Gum")
q回对象是ClasscdQ表C类Gum包含的接?/p>
如类Gum implements interface1,
则会获取到interface1的类对象
Class.newInstance()
实现“虚拟构造器”的一U途径
cd面常?/strong>
obj.Class生成对Class对象的引用,它比forName更加安全Q因为它在编译时接受检查?/p>
注意:当?Class来创建Class对象的引用时Q不会自动初始化Class对象?/p>
输出l果为:
Initialzing Initable
After creating Initable ref
47
258
Initialzing Initable2
147
Initialzing Initable3
After creating Initable3 ref
74
l论Q?/strong>如果一个static final值是"~译期常?Q就象Initable.staticFinal那样Q那么这个g需要对Initablecd使化可以读取,但是如果只是一个域讄为static和final的,如对Initable.staticFinal2的访问将q行强制的初使化Q因为它不是一个编译型帔R?/p>
如果一个static而不是final的,那么在它讉KӞL要求q行链接Qؓq个域分配存储空_和初始化Q初始化该存储空_Q就像对Initable2.staticNonFinal那样?/p>
泛化的Class引用 Class<Integer> iniClass=int.class 新的转型语法 case() InstanceOf 反射 getMethods()q回Method对象的数l?/p>
getConstructors()q回Contructor对象的数l?/p>
动态代?/strong> 实现InvocationHandler接口 public Object invoke(Objct proxy,Method method,Object[] args)throws Throwable{}Ҏ 通过Proxy.newProxyInstance(ClassLoader,Class[],InvocationHandler)创徏动态代?/p>
具体CZ参见: http://www.tkk7.com/aoneany/articles/271019.html
]]>
Scanner扫描字符串对象?/p>
备注Q?/p>
在java~译好的class文g?有个区域UCؓConstant Pool,他是一个由数组l成的表,cd
为cp_info constant_pool[],用来存储E序中用的各种帔R,包括Class/String/Integer{各
U基本Java数据cd,详情参见The Java Virtual Machine Specification 4.4章节.
对于Constant Pool,表的基本通用l构?
cp_info {
u1 tag;
u1 info[];
}
tag是一个数?用来表示存储的常量的cd,例如8表示Stringcd,5表示Longcd,info[]Ҏ
cd码tag的不同会发生相应变化.
对于Stringcd,表的l构?
CONSTANT_String_info {
u1 tag;
u2 string_index;
}
tag固定?,string_index是字W串内容信息,cd?
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
tag固定?,length为字W串的长?bytes[length]为字W串的内?
代码样例
(以下代码在jdk6中编?
Z详细理解Constant Pool的结?我们参看一些代?
String s1 = "sss111";
String s2 = "sss222";
System.out.println(s1 + " " + s2);
׃"sss111"?/span>"sss222"都是字符串常?在编译期已l创建好了存储在class文g?
在编译后的class文g中会存在q?个常量的对应表示:
08 00 11 01 00 06 73 73 73 31 31 31 08 00 13 01 ; ......sss111....
00 06 73 73 73 32 32 32 ; ..sss222
Ҏ上面说的String帔Rl构,我们分析一?br />
开始的08为CONSTANT_String_infol构中的tag,?1应该是它的相对引?01?br />
CONSTANT_Utf8_info的tag,06为对应字W串的长?73 73 73 31 31 31为字W串?br />
应的~码,接着分析,会发现后面的是对?/span>"sss222"的存储结?
l过上面分析,我们知道?1?3是两个字W串的相对引?可以修改class文g
来修Ҏ印的内容,把class文g中的
00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 12 4D
Ҏ
00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 10 4D
E序׃输出sss111 sss111,而不是和原程序一栯出sss111 sss222,因ؓ?br />
们把?/span>"sss222"的相对引?2Ҏ了对"sss111"的相对引?0.
------------分割U?br />
public class Test {
public static void main(String[] args) {
String s1 = "sss111";
String s2 = "sss111";
}
}
在上面程序中存在2个相同的帔R"sss111",对于n个值相同的String帔R,在Constant Pool?br />
只会创徏一?所以在~译好的class文g?我们只能扑ֈ一个对"sss111"的表C?
000000abh: 08 00 11 01 00 06 73 73 73 31 31 31 ; ......sss111
在程序执行的时?Constant Pool会储存在Method Area,而不是heap?
另外,对于""内容为空的字W串帔R,会创Z个长度ؓ0,内容为空的字W串攑ֈConstant Pool?
而且Constant Pool在运行期是可以动态扩展的.
关于Stringcȝ说明
1.String使用private final char value[]来实现字W串的存?也就是说String对象创徏之后,׃?br />
再修Ҏ对象中存储的字符串内?是因ؓ如此,才说Stringcd是不可变?immutable).
2.StringcL一个特D的创徏Ҏ,是使用""双引h创徏.例如new String("i am")实际创徏??br />
String对象,一个是"i am"通过""双引号创建的,另一个是通过new创徏?只不q他们创建的时期不同,
一个是~译?一个是q行?/span>!
3.java对Stringcd重蝲?/span>+操作W?可以直接使用+对两个字W串q行q接.
4.q行期调用Stringcȝintern()Ҏ可以向String Pool中动态添加对?
String的创建方?/strong>
一般有如下几种
1.直接使用""引号创徏.
2.使用new String()创徏.
3.使用new String("someString")创徏以及其他的一些重载构造函数创?
4.使用重蝲的字W串q接操作W?/span>+创徏.
面试?
String s1 = new String("s1") ;
String s2 = new String("s1") ;
上面创徏了几个String对象?
{案:3?,~译期Constant Pool中创??q行期heap中创??
Jpxx.forceLogout()Ҏ通过AJAX技术来强制注销用户Q即调用session.invalidate()Ҏ?
转蝲:http://www.jpxx.org/?tid=54文g?/th> | 说明 |
---|---|
AopInvocationHandlerImpl.java | 该类实现了java.lang.reflect.InvocationHandler接口Q我们通过它记录LOG信息 |
AopContainer.java | 单的AOP容器Q通过它把IDoBusiness与AopInvocationHandlerImpl兌h |
IDoBusiness.java | 逻辑处理接口 |
DoBusiness.java | 逻辑处理实现c?/td> |
TestAop.java | 试c?/td> |
转蝲:http://hi.baidu.com/e9151/blog/item/9c8d772be0319d305243c130.html
"A dynamic proxy class (simply referred to as a proxy class below) is a class that implements a list of interfaces specified at runtime when the class is created, with behavior as described below. A proxy interface is such an interface that is implemented by a proxy class. A proxy instance is an instance of a proxy class. Each proxy instance has an associated invocation handler object, which implements the interface InvocationHandler
."
Proxycȝ设计用到代理模式的设计思想QProxycd象实C代理目标的所有接口,q代替目标对象进行实际的操作。但q种替代不是一U简单的替代Q这h有Q何意义,代理的目的是在目标对象方法的基础上作增强Q这U增强的本质通常是对目标对象的Ҏq行拦截。所以,Proxy应该包括一个方法拦截器Q来指示当拦截到Ҏ调用时作何种处理。InvocationHandler是拦截器的接口?/p>
InvocationHandler接口也是在java.lang.reflec
Object invoke(Object proxy, Method method, Object[] args)
q个接口有三个参敎ͼ其中W二和第三个参数都比较好理解Q一个是被拦截的ҎQ一个是该方法的参数列表。关键是W一个参数。按照doc文档的解析,
proxy - the proxy instance that the method was invoked on
也就是说Qproxy应该是一个代理实例,但ؓ什么要传入q个参数呢?
带着q个问题Q自q了个程序作了一点试验?/p>
///////////////////////////////////////
public interface IAnimal {
void info();
}
////////////////////////////////////
public class Dog implements IAnimal
{
public void info() {
System.out.println("I am a dog!");
}
}
///////////////////////////////////////
import java.lang.reflect.*;
public class ProxyTest {
public static void main(String[] args) throws InterruptedException {
final IAnimal animal = new Dog();
Object proxyObj =Proxy.newProxyInstance(
animal.getClass().getClassLoader(),
animal.getClass().getInterfaces(),
new InvocationHandler()
{
public Object invoke(Object proxy, Method method, Object[] args)
{
try {
System.out.println("被拦截的Ҏ:" + method.getName());
return method.invoke(animal, args);
}
catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
});
if(proxyObj instanceof IAnimal)
{
System.out.println("the proxyObj is an animal!");
}
else
{
System.out.println("the proxyObj isn't an animal!");
}
if(proxyObj instanceof Dog)
{
System.out.println("the proxyObj is a dog!");
}
else
{
System.out.println("the proxyObj isn't a dog!");
}
IAnimal animalProxy = (IAnimal)proxyObj;
animalProxy.info();
animalProxy.hashCode();
System.out.println(animalProxy.getClass().getName().toString());
}
}
E序执行的结果如下:
the proxyObj is an animal!
the proxyObj isn't a dog!
被拦截的Ҏ:info
I am a dog!
被拦截的Ҏ:hashCode
$Proxy0
从结果可以看Z下几点:
1. proxyObj 是一个实C目标对象接口的对象,而不同于目标对象。也是_q种代理机制是面向接口,而不是面向类的?/p>
2. infoҎ(在接口中)被成功拦截了QhashCodeҎ也成功被拦截了,但意外的是,getClassҎ(l承自Object cȝҎ)q没有被拦截Q!
3. 应用调试q可以看出Invocation接口中invokeҎ的传入的proxy参数实是代理对象实例proxyObj
ZgetClass()没有被拦截?proxy参数又有何用呢?
先不,做一个试验看看。既然这个proxy参数是代理实例对象Q它理所当然和proxyObj是一LQ可以调用info{方法。于是我们可以在invokeҎ中加上如下一条语句:
((IAnimal)proxy).info();
l果是:
the proxyObj is an animal!
the proxyObj isn't a dog!
被拦截的Ҏ:info
被拦截的Ҏ:info
.......
被拦截的Ҏ:info
被拦截的Ҏ:info
然后是栈溢?/p>
l果是很明显的,在invokeҎ中调用proxy中的Ҏ会再一ơ引发invokeҎQ这陷入了d@环,最l结果当然是栈溢出的?/p>
可以在invokeҎ中调用proxy.getClass(), E序可以正常q行。但如果调用hashCode()Ҏ同样会导致栈溢出?/p>
通过上面的试验,可以得出一些初步结论,invoke 接口中的proxy参数不能用于调用所实现接口的方法。奇怪的是hashCode()和getClass()Ҏ都是从Object中承下来的ҎQؓ什么一个可以另一个不可以呢?带首疑问到doc文档看一下Object中这两个ҎQ发现getClass()是定义ؓfinal的,而hashCode()不是。难道是q个原因Q于是找C个非finalҎQ如equals试了一下,真的又会D栈溢出;扑֏一个finalҎ如wait(),试了一下,invoke又不拦截了。final N是关键之处Q?/p>
q有一个问题就是proxy有什么用Q既然proxy可以调用getClass()ҎQ我们就可以得到proxy的Classc象Q从而可以获得关于proxy代理实例的所有类信息Q如Ҏ列表QAnnotation{,q就为我们提供的一个分析proxy的有力工P如通过分析Annotation分析Ҏ的声明式事务需求。我想传入proxy参数应该是这样一个用意吧?/p>
InvocationHandler的资?/strong>
public interface InvocationHandler
InvocationHandler
是代理实例的调用处理E序 实现的接口?
每个代码实例都具有一个关联的调用处理E序。对代理实例调用ҎӞ对Ҏ调用q行~码q将其指zֈ它的调用处理E序?invoke
Ҏ?/p>
Object proxy,
Object[] args)
throws Throwable - 从代理实例上的方法调用抛出的异常。该异常的类型必d以分配到在接口方法的throws
子句中声明的M异常cd或未l检查的异常cdjava.lang.RuntimeException
?java.lang.Error
。如果此Ҏ抛出l过查的异常Q该异常不可分配到在接口Ҏ?throws
子句中声明的M异常cdQ代理实例的Ҏ调用抛出包含此Ҏ曾抛出的异常?
]]>