Java Enum Design & Generic Utility
Java 枚舉設計與泛型工具類1. 問題背景在很多業務場景中,枚舉需要從 String 值進行轉換:
12```javaStudentStatus.from("enrolled");
如果沒有抽象,每個枚舉都會重複相同的邏輯:
12345for (StudentStatus s : StudentStatus.values()) { if (s.getValue().equals(value)) { return s; }}
這會導致代碼重複以及較差的可維護性。我們需要讓代碼保持 DRY(Don’t Repeat Yourself,不重複自己)。
2. 目標
消除重複的 from() 邏輯
保持類型安全
保持 API 簡潔清晰
讓方案可以在所有枚舉中複用
3. 最終設計(最佳實踐)3.1 基礎接口123public interface BaseEnum { String getValue();}
作用:
定義一個規範
確保所有枚舉都提供 getValue() 方法 ...
Python Intro
列表 (List)使用 join() 方法將列表中的所有元素連接成一個字串。list = ["this", "is", "an", "example", "of", "using", "join()", "method"]
seperator = " - "
new_list = seperator.join(list)
print(new_list)
# this - is - an - example - of - using - join() - method
使用 split() 方法將字串拆分為列表。print(new_list.split(seperator))
# ['this', 'is', 'an', 'example', 'of', 'using', 'join()', & ...
Leetcode review
399. Evaluate Division問題描述:
You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable.
You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?.
Return the answers to all queries. If a single answer cannot be determined, return -1.0.
Note: The in ...
Spring Boot全局異常處理
前言當我們用Spring Boot構建工程的時候,在處理各種複雜的業務需求時往往會涉及到各種各樣的異常,比如在進行文件的IO操作時會遇到IOException,FileNotFoundException,在編冩SQL語句或使用JDBC時會遇到SQLException,在編冩涉及反射相關的代碼時會遇到ClassCastException。除此之外還有許多常見的異常如空指針異常NullPointerException,數組下標越界異常ArrayIndexOutOfBoundsException,在使用迭代器遍曆集合時修改元素産生的異常ConcurrentModificationException,算數異常(如除0)ArithmeticException等等。
在處理這些異常時無非就是兩種選擇,最直接最省事的選擇是直接使用throws關鍵字拋出異常,讓上層的方法處理異常。另外一種方法就是用try-catch代碼塊捕捉異常。這兩種方法的缺點都很明顯,當工程量變大需要處理異常的地方逐漸變多時,如果一個一個的處理異常會顯得非常低效,而且也不方便進行統一管理。
那麼是否存在一種可以全局管理異常的方法 ...
Spring Boot整合Redis和Redis配置
前言説起Nosql數據庫,或者數據庫緩存,消息隊列,token認証等等應用時,Redis總是大家繞不開的話題。作爲一款由C語言開髮的運行在內存中進行數據讀冩的應用,它以高性能和易用性著稱。得益於單線程的設計,避免了多線程場景下的鎖競爭,從而能做到每秒數十萬次的讀冩操作。同時,Redis還實現了主從模式,哨兵模式和集群模式等分佈式解決方案,在保証高性能的前提下提高了可用性和擴展性,成爲了開髮時不可或缺的組件。
Spring Boot 整合 Redis由於Spring Boot中各種starter的存在,配置redis其實是簡單的事情。
首先在pom中導入依賴
1234567891011121314<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency> <groupI ...
Spring Boot 整合日誌
前言Java髮展至今已經形成了一套完整的日誌體繫,分爲日誌門麵和日誌具體實現。日誌門麵相當於一個接口,日誌各種實現其實就是日誌門麵的不同實現。
Java的日誌加載依賴於SPI,不同於API, SPI模式下接口處於調用者一側,開髮者一側隻擁有具體的實現。而API模式下接口和具體實現都處於開髮者一側,調用者無需關心具體實現,隻管調用開髮者提供的接口即可。
SPI機製給予了程序動態加載的能力,程序運行的過程中根據接口去動態掃描對應的接口實現類並加載。
舉個例子,Java的日誌門麵Slf4j對應的具體實現有Spring Boot自帶的也是默認的logback,還有log4j,log4j2等,在使用時會動態加載classpath中存在的slf4j對應的實現類並把它加載使用,這就是SPI機製。
Logbacklogback是Spring Boot默認使用的日誌實現,即使不配置也可以直接使用。
12345678910@SpringBootApplicationpublic class RedisUsageApplication { public static void main( ...
SQL注入和MyBatis對應措施
SQL注入作爲一個經典的網絡安全問題,sql注入是每一個學習過網絡安全課程的同學都多多少少接觸過的一個問題。
它的原理其實非常簡單,就是通過向sql語句中插入一些特殊的敏感字符,使得查詢條件變成恆等從而繞過密碼、用戶名等的檢查直接獲取數據庫的內容。更有甚者可以通過sql注入導緻數據庫內容損壞、丟失,産生一繫列非常可怕的影響。
下麵是一個sql注入的例子。
假如我有一個用於登錄的表單,客戶端可以輸入用戶名和密碼來提交表單,後端通過對用戶名和密碼的驗証返回數據。
1SELECT * FROM users WHERE username = ${} AND password = ${};
此時,如果一些噁意用戶試圖輸入一些特殊的符號來進行sql注入,如輸入用戶名爲
1'' OR ''1''=''1
原先的sql就會變成一個恆等式
1SELECT * FROM users WHERE username = '''' OR ' ...
hearthstone database項目總結
冩在前麵這是一個前後端分離的全棧開髮項目。後端採用的技術棧是SpringBoot + MyBatis + MySQL。前端採用的是vue3框架。在項目完成後部署在了AWS雲服務上,OS採用的是ubuntu並使用nginx進行了反向代理。
整個項目從收集數據集,清洗數據,整合數據庫開始,一直到最終部署在服務器上曆時大約10天。其實前後端開髮佔用時間並不是很長,也沒有用到很複雜的技術,主要的時間消耗在於數據庫的清洗和整合工作。元數據來自一個第三方的hearthstone網站提供的API(在此非常感謝),但在獲取元數據之後髮現並不能立刻投入使用,因爲存在很多髒數據和一些冗餘數據,並且一些數據還存在格式上的不匹配。把這些問題處理完畢耗費了大約3-4天的時間。
本文章用於總結和回顧整個項目開髮過程中遇到的問題和主要的工作量。
先貼一張IDEA的項目結構圖
整個後端項目採用的是經典的SpringMVC框架,即Controller-Service-Mapper三層。同時也設計了Pojo類以及自定義Typehandler,自定義TypeHandler用於處理數據庫查詢結果和Java實例之間的映射( ...
設計模式總結
設計模式裝飾器模式裝飾器模式(Decorator Pattern)是一種結構型設計模式,它允許你動態地爲對象添加新的行爲,而不改變其結構或影響其他對象。這種模式通過將對象放入一個“包裝器”(即裝飾器對象)中,以便在保持原始對象類型不變的情況下,擴展或修改其行爲。
對象組合:裝飾器模式依賴於對象組合(composition),而不是繼承(inheritance)。你可以將一個對象嵌套在另一個對象中,從而添加額外的功能。
遵循接口:裝飾器和被裝飾對象通常都實現相同的接口或繼承相同的父類,因此可以互換使用。
動態擴展:裝飾器模式可以在運行時爲對象添加新的功能,而不像繼承那樣在編譯時就固定了行爲。
下麵是一個裝飾器模式的示例代碼
12345// 咖啡的基礎接口interface Coffee { String getDescription(); double getCost();}
123456789101112// 具體的基礎咖啡實現(被修飾的對象)class SimpleCoffee implements Coffee { @Overr ...
Java集合原理和底層數據結構總結
先放一張集合的層級圖
ListList的特點是順序性,可重複性。
ArrayList允許任何元素包括null。和Vector相比不是線程安全的。在必要時可以用Collections.synchronizedList()來將ArrayList轉換成線程安全的List
1List list = Collections.synchronizedList(new ArrayList());
底層維護了一個Object數組用來存儲元素。
1transient Object[] elementData;
定義了一個grow()方法,當調用一繫列重載的add方法時,會根據是否到達capacity來調用grow()以保証ArrayList的容量滿足需求。
PriorityQueuePriorityQueue通過維護了一個小頂堆來保証首元素是所有元素中最小的元素,最小取決於元素實現的Comparator或者Comparable。它也提供了一個構造函數以便傳入自定義的Comparator來決定排序的順序。
1public PriorityQueue(Comparator<? super E&g ...









