JAVA資料處理的常用技術
背景
在實際開發中,資料的處理有五種:獲取、傳輸、儲存、分析、轉換。每種各對應一些常用的技術。
序列化和反序列化
序列化是將物件的資訊轉換為可傳輸或可儲存形式的過程。反序列化就是反過來讓這些可傳輸的、可儲存的資訊變回物件。
傳輸的序列化除了安全性的考慮,因為涉及到和第三方通訊,所以還有重要的一點是可讀性和不變性。而儲存的鏈路短,可控,所以更講究效率。
傳輸最常用的序列化手段是JSON這樣人眼可讀的。而儲存會使用protostuff這種將key值對映成編碼來傳輸的。因為1,2,3比one、two、four更省空間更高效。但是傳輸中都用編碼,解析時就很難判斷它的意義。雙方還要進行額外的約定。本來3代表four,中間加了一個three,3代表three的話,對方沒有及時被通知,那麼解析傳輸過來的訊息就是錯的。
反射
Java反射是在執行時,對於任何一個類,都可以知道這個類有哪些方法和屬性。對於任何一個物件,都能對它的方法和屬性進行呼叫。
常用資料轉換工具,比如Spring的RequestParam、RequestBody、ResponseBody內部就用了反射機制。還有Jackson等工具類。甚至在業務程式碼中直接使用反射也是很常見的。比如設計一個AI助手問答機。想實現:
小A:我要搜尋美女"冰冰"
AI助手:OK,搜尋"冰冰"
小A:想知道她的"年齡"
AI助手:21歲
上面這個JAVA實現是這樣的:
Field field = 美女.class.getDeclaredField(年齡);
field.setAccessible(true);
return field.get(冰冰).toString();
動態代理
代理模式是為了提供增強的或不同的操作,而插入來替代實際物件的物件。這些操作涉及到與實際物件的通訊,所以稱為代理。
Spring主要的兩大思想IoC和AOP。對於IoC,利用的是反射機制。而AOP使用了動態代理,當然底層也是反射。
JDK動態代理只能給有介面的類代理。本質是通過反射獲取要執行的方法,並在執行前或者後加入一些代理處理操作。cglib本質上用繼承的方法實現的,是通過動態生成一個子類去覆蓋所要代理的類。用final修飾的不能被覆蓋的就不代理了。spring動態代理是優先使用JDK動態代理,如果目標沒有實現任何介面,則建立一個cglib代理。如果幾個類實現了都實現了一個通用介面,比如Runnable,並且加了Component請spring來負責其生命週期。這時候會丟擲一個Proxy代理異常。說期望載入一個Bean,實際上實現卻不只一個。這時候可以在這個類上加下面標籤強制使用cglib代理來解決。
@EnableAspectJAutoProxy(proxyTargetClass = true)
總結
我工作十幾年來,查詢和排序演算法一直被奉為經典。而這兩項就是搜尋技術的核心。大資料是建立在搜尋技術基礎上的。AI又是建立在大資料基礎上的。可見查詢和排序的核心地位。看似高深的技術也是從最底層開始。苦練基本