文章

工作中常用的工程写法

代码技巧

工作中常用的工程写法

① 栈 / 队列相关技巧(10 个)

  1. minStack.push(Integer.MAX_VALUE); 用于统一最小值比较逻辑
  2. maxStack.push(Integer.MIN_VALUE); 用于最大值逻辑
  3. 使用 dummy node(伪头结点)统一链表插入逻辑
  4. 队列先放一个 null 哨兵元素,标志一轮结束(常见于 BFS)
  5. Deque.addLast(null) 作为哨兵结点
  6. Queue.offer(dummyNode) 用于层序遍历开头
  7. 栈.push(Integer.MIN_VALUE + 1) 保证后续任何值都比它大
  8. Deque<Node> path = new LinkedList<>(); path.push(null); 用于路径标记
  9. 初始化优先队列时 Comparator.comparingInt((x) -> 0) 防止空值比较报错
  10. 使用 Collections.emptyList() 代替 null

② 数组/矩阵处理技巧(15 个)

  1. 初始化数组元素为 Integer.MAX_VALUE,用于最小值 DP 比较
  2. 初始化为 -1 表示“未访问”或“尚未计算”
  3. 0x3f3f3f3f 初始化数组表示“很大”(CP 比赛常用)
  4. 初始化为 false 表示未标记
  5. visited[i][j] = true 代替判断逻辑
  6. 前后加一圈边界,比如 int[rows + 2][cols + 2],省去边界判断
  7. Boolean[][] memo = new Boolean[n][m]; 来做记忆化搜索
  8. DP 初始时 dp[0] = 1,防止所有方案都为 0
  9. dp[i][j] = dp[i-1][j] + dp[i][j-1],前提是初始化边界行列为 1
  10. 前缀和数组 sum[0] = 0 作为起始
  11. 滑动窗口中使用 left = 0 起始保证不越界
  12. Map.put("", 0) 来初始化空串状态
  13. 使用 Object[][] 初始化为 null,统一处理
  14. 使用 Arrays.fill() 统一初始化值
  15. 二维数组初始化后第一行/列单独填值作为基础状态

③ HashMap / Set 相关技巧(10 个)

  1. map.getOrDefault(key, 0) 避免 null 判断
  2. 初始化时使用 HashMap<K, List<V>> map = new HashMap<>() 并预填空列表
  3. set.contains(x) 前加 set.add(x) 来避免重复(集合去重)
  4. 使用 defaultdict(Python)/ Guava 的 Multimap 实现 key 多值存储
  5. 初始化 frequencyMap.put(x, 0),然后直接加
  6. 避免 NullPointerException:先 put 后 get
  7. 初始化 Map<String, Object> 为 JSON 空对象
  8. TreeMap.put(Integer.MIN_VALUE, value) 做边界下限
  9. TreeSet.add(Integer.MAX_VALUE) 占上界
  10. HashMap.putIfAbsent(key, new ArrayList<>()),防止 get 到 null

④ 链表与树结构技巧(10 个)

  1. 使用 dummy head(哨兵头)统一插入/删除逻辑
  2. 使用 while (cur.next != null) 代替 while (cur != null && cur.next != null)
  3. 在叶子节点放一个 null 标记,用于层序遍历
  4. root.left = dummyNode 防止空指针
  5. 在前序/中序遍历中初始化一个栈顶部为根节点
  6. 树的递归处理:返回一个特殊节点表示“空”
  7. BST 初始化时插入 Integer.MIN_VALUE / Integer.MAX_VALUE 作为界限
  8. AVL 树空节点高度为 -1 或 0
  9. parent = new TreeNode(-1) 初始化作为统一父节点
  10. 平衡树中哨兵节点 root.left/right 指向自身防止 null 判断

⑤ 动态规划 / 状态转移技巧(10 个)

  1. 初始化状态 dp[0][0] = true/1
  2. 状态转移时默认值设置为 false / Integer.MAX_VALUE
  3. 滚动数组优化:用 prev[]cur[] 分别保存状态
  4. 在状态转移前将不可能的值初始化为 -1
  5. 初始转移时设置 base case,如 dp[0] = 1
  6. 填充边界状态减少分支判断
  7. 使用 dummy 状态简化边界初始化
  8. memo.put(state, result) 即使 result 为 0,也要标记已处理
  9. DP 状态转移时初始化为“不可达”状态:如 99999999
  10. i=1 开始循环,使 i-1 不越界

⑥ 多线程 / 并发相关技巧(10 个)

  1. 使用 volatile + 初始化值防止指令重排
  2. AtomicInteger(0) 初始化后可统一 incrementAndGet
  3. CountDownLatch(1) 起初拦住主线程
  4. ThreadLocal 初始化默认值
  5. synchronized(this) 中初始值必须提前设置
  6. ConcurrentHashMap.computeIfAbsent() 避免多线程并发 put
  7. 初始化对象后立刻用 final 保证可见性
  8. 使用双重检查锁实现延迟初始化
  9. ThreadPoolExecutor 默认线程数设置成 CPU 核心数
  10. 响应式编程中使用 CompletableFuture.completedFuture(null) 作为默认返回

⑦ 算法类问题常用技巧(15 个)

  1. 滑动窗口用 left = 0; right = 0 起始点统一
  2. 二分查找使用 left = 0, right = n,或者 n-1,看闭区间情况
  3. 最短路径初始化为 Integer.MAX_VALUE
  4. 最长路径初始化为 Integer.MIN_VALUE
  5. BFS 用 dist[i][j] = -1 表示未访问
  6. DFS 中使用 visited[][] = false
  7. 回溯中初始化 path 为 new ArrayList<>()
  8. 快速幂中 base = 1
  9. 扫描线算法初始状态为 0
  10. 单调栈初始时压入 -1 作为“虚拟栈底”
  11. 判断栈空时先压入特殊符号避免 if
  12. 合并区间前对区间按左边界排序
  13. 并查集初始化 parent[i] = i
  14. Dijkstra 中起始点距离为 0,其他点为无穷大
  15. Prim 算法中初始化最小边权为最大值

⑧ Java 工程实践/代码风格技巧(10 个)

  1. Optional 初始化为 Optional.empty(),避免 null
  2. 使用 Collections.emptyList() 避免返回 null
  3. List<String> list = new ArrayList<>(Collections.nCopies(n, ""));
  4. 抽象类中使用默认模板方法,避免子类遗漏初始化
  5. 使用 Enum.UNKNOWN 表示默认值
  6. 配置类中设置默认值:@Value("${xx:default}")
  7. 配置读取失败默认用 Map.getOrDefault
  8. 使用常量定义默认值,如 DEFAULT_TIMEOUT = 5000
  9. 响应体中预设 success=true,失败时再改
  10. 异常处理统一返回默认结构体,避免 null pointer

⑨ 其他零散技巧(10 个)

  1. 游戏开发中初始化 HP/MP = max
  2. 画图/网格中初始化背景色为白
  3. 二维图初始化 int[][] grid = new int[rows][cols],填 0 表示空地
  4. 电商库存系统中,商品数量初始化为 0
  5. 消息队列系统初始化偏移量为 -1
  6. 数据分析中初始平均值为 0.0
  7. 金额类系统中默认初始为 BigDecimal.ZERO
  8. 密码系统中默认值为空字符串,而非 null
  9. 日志系统默认级别设为 INFO
  10. 文件处理时默认打开方式为只读
本文由作者按照 CC BY 4.0 进行授权