Annotation
题记:建议关于spring问题,请记得查看spring reference。
一、annotation前生后世
Annotations do not directly affect program semantics, but they do affect the way programs are treated by tools and libraries, which can in turn affect the semantics of the running program. Annotations can be read from source files, class files, or reflectively at run time.
译:annotation不会直接影响程序的语义,xxx。Annotation可以从源文件、class文件、通过反射在运行时读取。
参考:http://www.developer.com/print.php/3556176
1. 定义
Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the interface keyword. Each method declaration defines an element of the annotation type. Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. Methods can have default values.
Annotation声明与普通的interface非常相似,在关键字interface前加@。每一个方法的声明定义一个annotation的元素。方法不能有任何的参数或throws异常。返回类型被限制为:原始类型、String、Class、enum、annotation、前面描述的类型组成的数组。method定义允许有默认值。
2. Java annotation
There are two types of annotations available with JDK5:
1) Simple annotations: These are the basic types supplied with Tiger, which you can use to annotate your code only; you cannot use those to create a custom annotation type.
三个基本的annotation,如:Override、Deprecated、Suppresswarnings,不能使用它去定义新的annotation。
2) Meta annotations: These are the annotation types designed for annotating annotation-type declarations. Simply speaking, these are called the annotations-of-annotations.
元annotation,定义annotation的类型。如:Target、Retention、Documented、Inherited。
A. Target:声明annotation注解的目标类型。如@Target(ElementType.TYPE)、@Target(ElementType.METHOD)
B. Retention:声明annotation被保留的长度。如:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME
C. Documented:声明被注解的target生成doc是否需要显示annotation信息。
D. Inherited:xxx
3. annotation作用
a. 不影响程序原本语义的情况下,增加信息+工具=声明式编程。如:spring aop
b. 编译检查 ?
二、利用annotation实现aop
1. 思路
A.自定义注解定义规则(何时执行)
B.标记行为(执行什么)
C.通过反射生成代理,在对象执行任何方法时,进行拦截判断是否符合规则;若符合,执行对应的行为。
2. 例子
场景:一个表演家,表演节目后,观众拍手鼓掌
原始:表演家拥有所有观众的引用,在自己表演完后,通知观众鼓掌
问题:表演家应该关注表演自身的事情,有哪些观众、观众是否鼓掌,不是其所关注的
改进:AOP方式,表演家仅关注表演,观众鼓掌由其它人负责
总结:
面向切面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)。 面向对象将应用程序分解成各个层次的对象,而AOP将程序分解成各个切面或者说关注点。这使得可以模块化诸如事务管理等这些横切多个对象的关注点。
三、spring aop如何使用annotation
1. 基本方式,通过ProxyFactoryBean
a.通知
b.切入点
b.通知+切入点 à 切面
c.实际对象+接口+切面 à 接口代理()
2. 自动代理方式:
基本方式的问题是,xml配置文件繁琐。
1)基于spring上下文的通知者Bean的自动代理(利用PostBeanProcessor ?)
BeanNameAutoProxyCreator,有属性:beanNames(被代理对象)、interceptorNames(通知)。自动代理beanNames指定的bean,此时interceptorNames指定通知,但interceptor需要实现特定的接口,如:MethodBeforeAdvice。
2) 基于aspectJ注解驱动
使用aspectJ风格的注解。原理:生成代理,仅方法级别。使用AspectJ 提供的一个库来做切点(pointcut)解析和匹配。
4. <aop:config>,优点:任何类都能转化为切面,不需要特殊接口或注解,原始pojo对象
5. aop参数传递,见:spring reference 6.3.3.6 通知参数
a. around切点,必须传递ProceedingJoinPoint参数,通过ProceedingJoinPoint取得方法的所有信息。
b. 其它切点,利用JoinPoint取得方法的所有参数。
c. 通过参数名绑定传递参数,未理解。
四、annotation相关技术
1. cglib
它的原理就是用Enhancer生成一个原有类的子类,并且设置好callback到proxy, 则原有类的每个方法调用都会转为调用实现了MethodInterceptor接口的proxy的intercept() 函数。
2. asm
ASM is an all purpose Java bytecode manipulation and analysis framework. It can be used to modify existing classes or dynamically generate classes, directly in binary form. Provided common transformations and analysis algorithms allow to easily assemble custom complex transformations and code analysis tools.
ASM offer similar functionality as other bytecode frameworks, but it is focused on simplicity of use and performance.
简单理解asm是比cglib更高级的code generate lib。
五、others问题
1. Generics
Generics - This long-awaited enhancement to the type system allows a type or method to operate on objects of various types while providing compile-time type safety. It adds compile-time type safety to the Collections Framework and eliminates the drudgery of casting. See theGenerics Tutorial. (JSR 14)
泛型提供了编译时类型检查安全。这点很重要吗 ?
2. 为什么spring aop aspectJ anonotation的pointcut声明,必须注解在方法上 ?通过方法唯一标识一个pointcut ?
猜测:@Pointcut的Target属性指定仅为method。方法签名成为pointcut的id。
主要参考:构建高性能web站点
一、网卡
网卡使用一个特定的物理层和数据链路层标准,例如以太网来实现通讯所需要的电路系统。这为一个完整的网络协议栈提供了基础,使得在同一局域网中的小型计算机组以及通过路由协议连接的广域网,例如IP,都能够进行通讯。
1.
作用:
a)
唯一的mac地址,定位机器(局域网/以太网mac寻址)
b)
数据接收和发送。拥有物理缓存区。
i.
接收:接收物理层数据,通过DMA方式访问内存。
ii.
发送:接收上层数据,分解为适当大小的数据包发送。
转载:
数据的封装与解封:发送时将上一层交下来的数据加上首部和尾部,成为以太网的帧。接收时将以太网的帧剥去首部和尾部,然后送交上一层。
链路管理:主要是CSMA/CD(Carrier Sense Multiple Access with Collision Detection ,带冲突检测的载波监听多路访问)协议的实现。
编码与译码:即曼彻斯特编码与译码。
2. 协议
以太网(Ethernet)是一种计算机局域网组网技术。
ARP协议(Address Resolution Protocol),或称地址解析协议。ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址。
http://zh.wikipedia.org/zh/%E5%9C%B0%E5%9D%80%E8%A7%A3%E6%9E%90%E5%8D%8F%E8%AE%AE
3. 传输速率
网卡速率是指网卡每秒钟接收或发送数据的能力,单位是Mbps(兆位/秒)。由于存在多种规范的以太网,所以网卡也存在多种传输速率,以适应它所兼容的以太网。目前网卡在标准以太网中速度为10Mbps,在快速以太网中速度为100Mbps,在千兆以太网中速度为1000Mbps等。
主流的网卡主要有10Mbps网卡、100Mbps以太网卡、10Mbps/100Mbps自适应网卡、1000Mbps千兆以太网卡以及最新出现的万兆网卡五种。对于一般家庭用户选购10M或者10Mbps/100Mbps自适应网卡即可,对于企业用户建议购买100Mbps以太网卡或者1000Mbps千兆以太网卡或者万兆网卡。
以太网卡和交换设备都支持多速率,设备之间通过自动协商设置最佳的连接速度和双工方式。如果协商失败,多速率设备就会探测另一方使用的速率但是默认为半双工方式。10/100以太网端口支持10BASE-T和100BASE-TX。
2.
特点
a)
全双工
b)
传输速率
c)
总线类型:PCI总线架构日益成为网卡的首选总线
d)
MAC地址
二、数据如何发送
1.
将数据写入用户进程的内存地址空间,其实实际的开发过程只需对运行时变量赋值即可
2.
应用程度调用系统函数,将数据从用户态内存区复制到由内核维护的一段称为内核缓冲区的内存地址空间。
a)
内核缓存区大小有限,要发送的数据以队列的形式进入
b)
每次复制一定的数据大小,这个大小取决于网络数据包的大小以及内核缓存区的承载能力
3.
当数据写入内核缓存区,内核会通知网卡控制器来读取数据,cpu转而处理其它任务
a)
网卡将发送的数据从内核缓存区复制到网卡缓存区
b)
数据的复制始终按照内部总线的宽度复制(如32位总线,每次复制32bit信息)
4.
网卡发送数据到物理线路
a)
需要对数据进行字节到位的转换(即将数据按照位的顺序发出)
b)
网卡内部使用特定的物理装置,来生成可以传播的各种信息,如铜线,网卡会根据位信息“0/1的变化产生不同的电信号;光线,网卡会生成光信号。
三、电磁波速度
不管是电信号,还是光信号,进入物理介质后,其传输速度仅依赖其传播介质,铜线中电信号的传输速度大约2.3*10(8)m/s,光纤中光信号的传播速度大约是2.0*10(8)m/s。光在真空中的传播速度是3.0*10(8)m/s,为什么光纤中的传播速度要慢呢
?因为光在光纤中的传播利用全反射原理,所以传播距离要大于光纤长度。
由此看见,不同的传播介质中信号的传播速度几乎是常量。也就是说,不论数据发送装置以多快的发送速度让数据以信号的形式进入路线,在线路中信号的传播速度几乎可以认为是一样快的。
光纤与铜线相比?光纤采用全反射原理,因此光信号衰减底,因此传播距离远。
四、带宽概念
从上面分析来看,数据的传输包括:发送端发送数据进入线路 + 线路传输,线路传输的速度在各种传输介质几乎是相同的。
带宽定义:每秒传播bit数,bit/s。
这样看,影响带宽的因素仅为“发送端发送数据进入线路”,如何提升:a、提升发送速度 b、数据传输的并行度
1.
发送速度
数据发送装置将二进制信号传送至线路的能力。关键是,如果接收能力跟不上,发送能力不可能提高。原理:接收速度决定发送速度。
也就是“流控机制”,保证接收方能够接收数据,不会丢失数据。如Tcp滑动窗口(滑动窗口协议的基本原理,任意时刻发送方、接收方都保持一个连续的允许发送、接收的帧的序号http://blog.csdn.net/yujun00/archive/2006/03/23/636495.aspx)。
2. 并行度,等价于计算机总线的概念。比如:32位,任意同一时刻能传输32位数据。
总结:显然,网卡影响性能结果。
题记:在淘宝广告技术部工作快1年,写点自己对广告的认识
目前在淘宝主要存在这样几种形式广告 :CPT、CPC、CPS
1.CPT
cost per time 按时长计费。大部分属于品牌广告,主要着重于品牌形象的宣传。比如:淘宝中屏滚动广告,如“dell、九牧王”。特点:a、价格非常贵 b、位置少。
CPM (Cost Per
ThousandImpression)按千次展现次数计费。能够为广告主带来稳定的“广告展现”,但效果是未知数,具体要看投放的媒体,以及场景的相关性。能为有流量的站点带来稳定的收入。
2.CPC
cost per click 按点击计费。如:google ads、淘宝直通车,都是根据词的竞价排名,决定展示那个广告主的广告。
目前淘宝大部分收入来自于直通车。
如:在淘宝,搜“诺基亚 N73”,首先做“搜索词归一化”,匹配为与竞价词相关的词,再根据竞价词去搜索。谁出价高,并根据用户的信誉度等因素,决定出谁的广告。
站在长远的发展,淘宝直通车的目的:1.增加淘宝收入 2.促进成交。如果仅仅是点击最大化,增加淘宝的收入,但并没有为卖家带来成交,则卖家的出价必然会降低,对于双方来说都是“双输”的局面。所以必须站在促进成交的前提下,通过直通车不断提升淘宝自身的收入增加。
3.CPS
cost per Sales 按成交计费。据说:某淘宝广告去日本时在一家书店看到的营销模式,回到淘宝后,决定做"淘宝客"。
cps模式更加关注的是“长尾流量”,因为长尾publisher,流量质量一般来说不是很高,如果按照前面说到的3种方式计费,对广告主来说是不公平的。但根据成交,分成给长尾publisher,既能保证广告主的利益,也满足广告主营销、推广的目的。同时也能够给publisher带来收入。
小思考:
目前淘宝有8亿商品,仅淘宝自身的广告位置,完全不能满足卖家推广、营销的目的。所以淘宝会去买外部广告位(如优酷),或者与外部网站以“分成”的模式合作(google)。
其实,淘宝也在建立自己的广告联盟,类似于“圈地运动”,去累积足够多的流量、渠道,到时怎么玩,都是由自己决定。其实目前的淘宝广告外投,对于客户来说是不透明的,卖家不知道自己的广告是否被外投,与淘宝站内的广告相比,站外的广告效果还是要差很多(会基于成交效果给予广告主打折),准确的说“淘宝的广告主是被外投”。
其实,目前淘宝联盟,对于广告主与网站主自主选择仅有CPT计费模式,当广告位无广告时淘宝联盟会自动推送CPS模式广告。CPC模式广告,在淘宝联盟目前的网站主管理模式下,无法推广CPC广告。原因是,目前网站主没有明确的层级结构,对于CPC广告,流量好坏决定最后的成交率,相比CPT模式CPC更加赚钱,大量流量差的投放CPC广告,会导致cpc(单次点击消耗)降低,肯定对淘宝广告的收入会有非常大的影响。淘宝如果要开放CPC模式给外部网站主,必须有明确的层级结构、站内&站外竞价区分。
外投每天能为淘宝带来大约300万收入,但对于主动获取广告的publisher来说没有智能匹配模式、没有灵活的定制化界面、多样的创意。当站内CPC趋于饱和时,如何开拓好外投,对于淘宝直通车则是必然的趋势。而CPS自然去占据长尾流量,CPC如何占据主外部中型网站,则是至关重要的。
摘要: 一、Java数据类型
数据类型就是对内存位置的抽象表达
(很多编程语言都依赖于特定的计算机类型和对数据类型属性的具体编译实现,比如word和integer数据类型的大小等;Java通过JVM保证数据所占存储空间的大小不会随硬件的改变发生变化)。
1. Primitive data type :A primiti...
阅读全文
题记:很长都没有学到这个时间啦,怀念大三。
一、摘要
1.
什么是“代理”
2.
代理模式与适配器模式、装饰者模式的区别,适用场景
3.
手工代理
4.
动态代理的原理
二、什么是“代理”
如:一个CEO,会有一个助理,任何需要CEO处理的事情,都会经过助理过滤、整理后交给CEO。助理就是CEO的代理。
自己理解,代理就是为帮实际的执行者,做数据的过滤和控制,为实际执行者屏蔽掉外部其它因素的影响,专心去做应该做的事情。
三、代理模式与适配器模式、装饰者模式的区别,适用场景
1、代理模式
HeadFirst 定义:为另一个对象提供一个替身或占位符以控制对这个对象的访问。
如上图,代理模式的结构。
适用的场景,如:远程访问、访问权限控制、日志记录等。
装饰者模式,IO类图结构如下:
可以从OutputStream
à FileOutputStream à BufferedOutputStream,功能依次增强,为对象增加更多的行为。
自己理解:目的不一样,代理是为控制对被代理对象的访问;装饰者,是对被装饰者功能的增强,避免过度使用继承实现不同的功能。
适配器模式,其区别从类图即可分辨出来,如下 :
Client请求ExecuteClass,但ExecuteClass暴露的接口不符合client的要求,在双方系统都不修改的情况下,利用适配器模式解决此问题。
三、手工代理
场景:根据id,获取Item;代理检查用户的权限是否有权限查看Item,已经记录log日志。具体代码很容易实现。
四、动态代理
对上面的场景,如果使用动态代理,步骤:
1. 根据interface,通过loader,生成Class对象
Class clazz = Proxy.getProxyClass(ItemService.class.getClassLoader(),
ItemService.class);
2. 通过反射,获取Class对象的Construct对象(注意:Construct对象需要的参数类型)
Constructor c = clazz.getConstructor(InvocationHandler.class);
3. 调用Construct对象 newInstance()生成实例对象
proxy = (ItemService)c.newInstance(this); //this是InvocationHandler实例
思考问题:实现原理是什么 ?
对于上面场景,实际动态生成的代理的类图。对代理的任何调用都会,super.handle.invoke(),用户实现InvocationHandler,覆写invoke方法,实现基于方法的控制。
从类图,也解释了为什么只能实现“接口”的动态代理,因为代理本身需要继承Proxy,如果实现“类”的代理,意味着要同时继承两个类,与Java不支持多继承相违背。
附代码是从网上摘抄过来的,代理的源码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements Manager {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("com.ml.test.Manager").getMethod("modify",
new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString",
new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
.booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}
题记:一直对ThreadLocal疑惑,听完facebook大牛演讲后,总结点东西。
一、ThreadLocal的作用,整体结构
二、源代码简单分析
1.set方法
2.get方法
三、使用场景实例 ibatis SqlMapClientImp
后记:折腾半天,文章的样式也调整不好,打包上传。但愿能帮到别人。
http://www.blogjava.net/Files/shijian/ThreadLocal.rar [请用“web版式视图”阅读]
遗留问题:
1.Thread的ThreadLocalMap threadLocals 属性什么时候实例化 ? 线程实例化时吗 ?
答:第一次set时,会判断是否为null,若为null,初始化。
2.ThreadLocalMap replaceStaleEntry(key,
value, i); 做了什么 ?
答:全清洗stale对象;存放当前对象在发现的第一个stale位置。因为Entry是继承WeakRerfence,任何一次的垃圾收集,都会导致其引用的对象被回收。
4.与Map方式的一些区别 ?
Map策略:a、相同hash&key,覆盖value; b、相同hash,key不同,当前元素做为单向链的第一个元素,原来第一个元素做为当前元素的下一个。
ThreadLocalMap策略:a相同,是不存在b情况;以ThreadLocal作为key,ThreadLocal的threadLocalHashCode由原子AtomicInteger计算getAndAdd(0x61c88647)得到;在Entry[]数组的位置,通过threadLocalHashCode
& (length-1)计算;对于b情况,继续查找Entry[]数组的下一个位置,是否可存放(key相同或null);当size>=threshold(len*2/3)做resize=oldLen*2.
3.ThreadLocalMap getEntryAfterMiss(ThreadLocal key, int i, Entry e);
答:作用,查找没有存放在hash计算出index位置的元素。为什么出现此情况?见4,由ThreadLocalMap策略决定.