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.aygfsteel.com/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策略決定.