Java 日志從入門到精通:告別日志混亂。本文將從日志的基礎概念講起,深入剖析 Java 日志體系的核心組件,詳解 SLF4J 的正確使用方式,帶你掌握日志框架的配置技巧,揭秘日志實踐中的最佳實踐與避坑指南,讓你的日志系統從 “混亂不堪” 升級為 “精準高效”,從此排查問題不再頭疼。3.3 SLF4J 與日志實現的綁定。避免在日志中執行耗時操作日志參數中的方法調用應避免包含耗時操作,因為即使日志級別未啟用,這些方法也會被執行。
// DO里有個子對象@Datapublic class UserDO { private String name; private Department dept; // 部門子對象}@Datapublic class Department { private String deptName;}用起來賊簡單,一行代碼搞定:// 單個對象轉換UserVO vo = MyBeanUtils.copyBean(userDO, UserVO.class );// List轉換List<UserVO> voList = MyBeanUtils.copyList(doList, UserVO.class );2. 深拷貝:處理嵌套對象。
@Servicepublic class OrderService { // 注入名稱為alipayPayment的Bean @Autowired @Qualifier("alipayPayment") private PaymentService paymentService;}// 實現類1@Service("alipayPayment")public class AlipayPayment implements PaymentService { ...}// 實現類2@Service("wechatPayment")public class WechatPayment implements PaymentService { ...}
= null && !public boolean isValid(User user) { if (user == null) return false;// 錯誤示范public List<String> getTags() { if (tags == null) return null; return tags;}public List<String> getValidUserNames(List<User> users) { return users.stream() .filter(Objects::nonNull) .filter(u -> u.getStatus() == 1) .map(User::getName) .collect(Collectors.toList());
public User get(Long id) { return userMapper.selectById(id);UserMapper mapper = (UserMapper) Proxy.newProxyInstance( UserMapper.class.getClassLoader(), new Class[]{UserMapper.class}, new MapperProxy(sqlSession));UserMapper mapper = (UserMapper) Proxy.newProxyInstance( UserMapper.class.getClassLoader(), new Class[]{UserMapper.class}, new MyMapperProxy(conn));
內存大小在類加載階段就已確定(Object類的實例占用 16 字節,包括對象頭和實例數據),分配過程就像給商品找合適的貨架位置,有兩種常見方式:指針碰撞法:如果 JVM 的堆內存是連續的(就像一排整齊的貨架),已使用內存和空閑內存之間有一個指針。對于Object對象,其對象頭占用 12 字節(64 位 JVM 默認配置),加上 4 字節的對齊填充(JVM 要求對象大小必須是 8 字節的整數倍),總共占用 16 字節內存。
請馬上停止使用JWT?。?!JSON Web Tokens,又稱 JWT。無狀態 JWT(Stateless JWT):包含 Session 數據的 JWT Token。有狀態 JWT(Stateful JWT):包含 Session 引用或其 ID 的 JWT Token。實際上,簽名后的 Cookies 比未簽名的 Cookies 同樣更加安全,但這絕不是 JWT 獨有的,優秀的 Session 實現均使用簽名后的 Cookies(譯者注:例如 Laravel)。若將JWT Tokens 存儲到 Cookies 內,那么安全性與其他 Session 機制無異。
-- 創建索引CREATE INDEX idx_age_name ON users(age, name);-- 索引優化排序SELECT * FROM users ORDER BY age, name; -- √ 使用索引避免排序-- 索引優化分組SELECT age, COUNT(*) FROM users GROUP BY age; -- √ 使用索引優化分組-- 無法使用索引排序的情況SELECT * FROM users ORDER BY name, age; -- × 不符合最左前綴SELECT * FROM users ORDER BY age DESC, name ASC; -- × 排序方向不一致8.如何發現索引失效的場景?
/bin/bash# nginx_monitor.sh - Nginx性能監控腳本echo"=== Nginx連接狀態 ==="ss -secho"=== 活躍連接數 ==="netstat -n | awk ''''''''/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}''''''''echo"=== Nginx進程狀態 ==="ps aux | grep nginx | grep -v grepecho"=== 系統負載 ==="uptimeecho"=== 內存使用情況 ==="free -hecho"=== Nginx訪問統計 ==="curl -s http://localhost/nginx_status2、性能測試命令。
甲骨文嚴查Java授權,公司連夜刪除JDK。。而僅僅只有 14% 的受訪者計劃繼續使用 Oracle Java 訂閱,所以這么一看,Oracle Java 的處境似乎也有一些嚴峻。。其實之前就看到過“甲骨文開始嚴查 Java 許可,有公司連夜刪除 JDK”的新聞媒體報道,當時的主要操作就是開始將 Java 納入其軟件許可審查中,并且對一些公司的 Java 使用情況開啟審計,目的是找出那些處于不合規邊緣或已經違規的客戶。
Tomcat本身有一個Tomcat類,沒錯就叫Tomcat,全路徑是org.apache.catalina.startup.Tomcat,我們想啟動一個Tomcat,直接new Tomcat(),之后調用start()就可以了。tomcat.init();tomcat.start();SpringBoot并不像上面Tomcat的例子一樣簡單的通過tomcat.addServlet把DispatcherServlet傳遞給Tomcat,而是通過個Tomcat主動回調來完成的,具體的回調通過ServletContainerInitializer接口協議,它允許我們動態地配置Servlet、過濾器。
@AutoMappers({ @AutoMapper(target = UserDto.class), @AutoMapper(target = UserVO.class)})// 或者@AutoMapper(target = UserDto.class)// 使用User user= Converter.convert(UserDto, User.class);/** * <li>ClassName: UserDto </li> * <li>Author: OakWang </li> */@Data@AutoMapper(target = User.class)public class UserDto { private Integer id;
MyBatis流式查詢詳解MyBatis 流式查詢詳解:ResultHandler 與 Cursor.@Transactional@Transactionalpublic void getUsersByAge(int minAge) throws IOException { try (Cursor<User> cursor = userMapper.scanUsersByAge(minAge)) { for (User user : cursor) { System.out.println(user);Cursor 踩坑:A Cursor is already closed.Cursor<User> cursor = userMapper.scanAllUsers();Cursor(迭代器模式):
Nginx要涼涼,被這款工具取代。Cloudflare 公司去年宣布棄用 nginx,轉用自研的新一代方向代理服務 Pingora,并號稱比nginx更快、更高效、更安全,下面通過 Cloudfare 官方網站的一篇文章來了解下 Pingora 比 Nginx 強在哪里?雖然Nginx的應用邏輯可以通過Lua語言來實現。例如,在 NGINX/OpenResty 中,當 Lua 代碼想要訪問 HTTP 頭時,它必須從 NGINX C 結構中讀取它,分配一個 Lua 字符串,然后將其復制到 Lua 字符串中。
map1.put("name", "張三");map1.put("age", 25);Map<String, Object> map2 = new HashMap<>();map2.put("age", 26);map2.put("score", 95.5);// 合并兩個Map(map2的鍵會覆蓋map1的同名鍵)Map<String, Object> merged = MapUtils.merge(map1, map2);// merged結果:{name=張三, age=26, score=95.5}(2)提取子 Map.
Apache Commons ObjectUtils:讓對象操作告別冗余代碼的工具類?// 若對象為null,返回默認值String str = ObjectUtils.defaultIfNull(null, "default"); // "default"String str2 = ObjectUtils.defaultIfNull("value", "default"); // "value"// 嵌套對象的默認值處理(避免NPE)User user = null;String username = ObjectUtils.defaultIfNull( user != null ? user.getUsername() : null, "guest"); // "guest"
Apache Commons NumberUtils:讓數字處理代碼減少 60% 的工具類?// NumberUtils:一行代碼完成轉換int num = NumberUtils.toInt(str, 0);// 字符串轉int,默認值0int a = NumberUtils.toInt("123"); // 123int b = NumberUtils.toInt("abc", 0); // 0(轉換失敗用默認值)int c = NumberUtils.toInt(null, -1); // -1(null值用默認值)// 字符串轉long,默認值-1long d = NumberUtils.toLong("123456789", -1); // 123456789.
Apache Commons RandomStringUtils:讓隨機字符串生成效率提升 10 倍的工具類。// 生成10位隨機字符串(默認字符集:大小寫字母+數字)String str1 = RandomStringUtils.random(10);// 從指定字符集中生成8位字符串(僅包含a、b、c和數字)String str2 = RandomStringUtils.random(8, "abc123");// 從字符數組中生成6位字符串char[] chars = {''''''''x'''''''', ''''''''y'''''''', ''''''''z''''''''};String str3 = RandomStringUtils.random(6, chars);
Apache Commons ReflectionUtils:讓 Java 反射從 “勸退” 到 “真香” 的工具類?// 獲取字段值(支持私有字段)String name = (String) ReflectionUtils.getFieldValue(user, "name");// 設置字段值(自動處理私有字段)ReflectionUtils.setFieldValue(user, "name", "Tom");// 操作靜態字段(第一個參數傳Class對象)ReflectionUtils.setFieldValue(User.class, "staticField", "value");
Apache Commons ReflectionUtils:讓 Java 反射從 “勸退” 到 “真香” 的工具類?// 獲取字段值(支持私有字段)String name = (String) ReflectionUtils.getFieldValue(user, "name");// 設置字段值(自動處理私有字段)ReflectionUtils.setFieldValue(user, "name", "Tom");// 操作靜態字段(第一個參數傳Class對象)ReflectionUtils.setFieldValue(User.class, "staticField", "value");