进阶之路之JAVA篇

📅 发布时间:2026/7/15 20:29:01 👁️ 浏览次数:
进阶之路之JAVA篇
这个世界不会是强者恒强后来者总能居上只要我们在路上就总会赢一、打包篇在 Spring Boot 项目中将resource/lib目录下的 JAR 包引入pom.xmldependency groupIdorg.apache.flink/groupId artifactIdflink-connector-clickhouse/artifactId version1.0/version !-- 或实际的版本号 -- scopesystem/scope systemPath${project.basedir}/src/main/resources/lib/flink-connector-clickhouse-1.0.0-SNAPSHOT.jar/systemPath /dependency二、算法篇2.1、标准Kahn算法拓扑排序这是一段基于 Kahn 拓扑排序算法的公式依赖解析工具专门解决多公式变量先后计算顺序问题 场景业务存在大量计算公式变量之间互相依赖不能随便乱算否则会出现「计算时依赖变量还没算出值」 作用自动算出一套合法的计算顺序同时检测循环依赖死环比如ab、ba这种无法计算的错误公式。package com.juxin.job; import java.util.*; public class FormulaTopologyDemo { // 邻接图key目标变量value它依赖的所有前置变量 private static MapString, SetString graph new HashMap(); // 入度key变量value当前还剩多少个依赖未计算 private static MapString, Integer inDegree new HashMap(); public static void main(String[] args) { // 模拟业务公式 // a b c // b d * 2 // c 10 // d 5 // 依赖关系a依赖b、cb依赖dc无依赖d无依赖 addDepend(a, b); addDepend(a, c); addDepend(b, d); System.out.println( 构建完成的邻接图 graph ); for (Map.EntryString, SetString entry : graph.entrySet()) { System.out.println(entry.getKey() 依赖 entry.getValue()); } System.out.println(\n 各变量初始入度 inDegree ); for (Map.EntryString, Integer entry : inDegree.entrySet()) { System.out.println(entry.getKey() 入度 entry.getValue()); } // 执行拓扑排序获取合法计算顺序 ListString calcOrder topologySort(); System.out.println(\n 变量正确计算顺序 ); if (calcOrder.isEmpty()) { System.out.println(检测到循环依赖无法计算); } else { System.out.println(calcOrder); System.out.println(执行规则按列表顺序依次计算公式不会出现变量未赋值问题); } } /** * 建立依赖关系target 依赖 pre 前置变量 * param target 待计算变量 * param pre 前置依赖变量 */ private static void addDepend(String target, String pre) { // 核心两行不存在则初始化防止null空指针 graph.putIfAbsent(target, new HashSet()); inDegree.putIfAbsent(target, 0); graph.putIfAbsent(pre, new HashSet()); inDegree.putIfAbsent(pre, 0); // 避免重复添加依赖 SetString preSet graph.get(target); if (!preSet.contains(pre)) { preSet.add(pre); // target入度1多了一个前置依赖 inDegree.put(target, inDegree.get(target) 1); } } /** * 标准Kahn算法拓扑排序 * return 拓扑有序的计算列表空代表存在环循环依赖 */ private static ListString topologySort() { ListString result new ArrayList(); QueueString queue new LinkedList(); // 1. 先把所有入度为0的变量入队无任何依赖可以直接计算 for (Map.EntryString, Integer entry : inDegree.entrySet()) { String var entry.getKey(); int degree entry.getValue(); if (degree 0) { queue.offer(var); } } // 2. 循环处理队列 while (!queue.isEmpty()) { String currVar queue.poll(); result.add(currVar); // 找到所有【依赖 currVar】的上层变量反向遍历图 for (Map.EntryString, SetString entry : graph.entrySet()) { String target entry.getKey(); SetString preList entry.getValue(); if (preList.contains(currVar)) { // 当前前置依赖计算完成上层变量入度-1 int newDegree inDegree.get(target) - 1; inDegree.put(target, newDegree); // 入度归零所有依赖全部算完可以进队列计算 if (newDegree 0) { queue.offer(target); } } } } // 3. 判断是否存在循环依赖 // 总变量数 ! 排序列表长度 → 有环 if (result.size() ! inDegree.size()) { return new ArrayList(); } return result; } }