背景 在實際開發(fā)中,數(shù)據(jù)的處理有五種:獲取、傳輸、存儲、分析、轉(zhuǎn)換。每種各對應(yīng)一些常用的技術(shù)。
序列化是將對象的信息轉(zhuǎn)換為可傳輸或可存儲形式的過程。反序列化就是反過來讓這些可傳輸?shù)?、可存儲的信息變回對象?br> 傳輸?shù)男蛄谢税踩缘目紤],因為涉及到和第三方通信,所以還有重要的一點是可讀性和不變性。而存儲的鏈路短,可控,所以更講究效率。 傳輸最常用的序列化手段是JSON這樣人眼可讀的。而存儲會使用protostuff這種將key值映射成編碼來傳輸?shù)?。因?,2,3比one、two、four更省空間更高效。但是傳輸中都用編碼,解析時就很難判斷它的意義。雙方還要進(jìn)行額外的約定。本來3代表four,中間加了一個three,3代表three的話,對方?jīng)]有及時被通知,那么解析傳輸過來的消息就是錯的。 Java反射是在運行時,對于任何一個類,都可以知道這個類有哪些方法和屬性。對于任何一個對象,都能對它的方法和屬性進(jìn)行調(diào)用。 常用數(shù)據(jù)轉(zhuǎn)換工具,比如Spring的RequestParam、RequestBody、ResponseBody內(nèi)部就用了反射機(jī)制。還有Jackson等工具類。甚至在業(yè)務(wù)代碼中直接使用反射也是很常見的。比如設(shè)計一個AI助手問答機(jī)。想實現(xiàn):小A:我要搜索美女"冰冰" AI助手:OK,搜索"冰冰" 小A:想知道她的"年齡" AI助手:21歲
上面這個JAVA實現(xiàn)是這樣的: Field field = 美女.class.getDeclaredField(年齡); field.setAccessible(true); return field.get(冰冰).toString();
動態(tài)代理
代理模式是為了提供增強(qiáng)的或不同的操作,而插入來替代實際對象的對象。這些操作涉及到與實際對象的通信,所以稱為代理。 Spring主要的兩大思想IoC和AOP。對于IoC,利用的是反射機(jī)制。而AOP使用了動態(tài)代理,當(dāng)然底層也是反射。 JDK動態(tài)代理只能給有接口的類代理。本質(zhì)是通過反射獲取要執(zhí)行的方法,并在執(zhí)行前或者后加入一些代理處理操作。cglib本質(zhì)上用繼承的方法實現(xiàn)的,是通過動態(tài)生成一個子類去覆蓋所要代理的類。用final修飾的不能被覆蓋的就不代理了。spring動態(tài)代理是優(yōu)先使用JDK動態(tài)代理,如果目標(biāo)沒有實現(xiàn)任何接口,則創(chuàng)建一個cglib代理。如果幾個類實現(xiàn)了都實現(xiàn)了一個通用接口,比如Runnable,并且加了Component請spring來負(fù)責(zé)其生命周期。這時候會拋出一個Proxy代理異常。說期望加載一個Bean,實際上實現(xiàn)卻不只一個。這時候可以在這個類上加下面標(biāo)簽強(qiáng)制使用cglib代理來解決。
@EnableAspectJAutoProxy(proxyTargetClass = true)
總結(jié) 我工作十幾年來,查找和排序算法一直被奉為經(jīng)典。而這兩項就是搜索技術(shù)的核心。大數(shù)據(jù)是建立在搜索技術(shù)基礎(chǔ)上的。AI又是建立在大數(shù)據(jù)基礎(chǔ)上的??梢姴檎液团判虻暮诵牡匚???此聘呱畹募夹g(shù)也是從最底層開始。
|