工作中常用的工程写法
代码技巧
工作中常用的工程写法
① 栈 / 队列相关技巧(10 个)
minStack.push(Integer.MAX_VALUE);用于统一最小值比较逻辑maxStack.push(Integer.MIN_VALUE);用于最大值逻辑- 使用 dummy node(伪头结点)统一链表插入逻辑
- 队列先放一个
null哨兵元素,标志一轮结束(常见于 BFS) Deque.addLast(null)作为哨兵结点Queue.offer(dummyNode)用于层序遍历开头栈.push(Integer.MIN_VALUE + 1)保证后续任何值都比它大Deque<Node> path = new LinkedList<>(); path.push(null);用于路径标记- 初始化优先队列时
Comparator.comparingInt((x) -> 0)防止空值比较报错 - 使用
Collections.emptyList()代替 null
② 数组/矩阵处理技巧(15 个)
- 初始化数组元素为
Integer.MAX_VALUE,用于最小值 DP 比较 - 初始化为
-1表示“未访问”或“尚未计算” - 用
0x3f3f3f3f初始化数组表示“很大”(CP 比赛常用) - 初始化为
false表示未标记 visited[i][j] = true代替判断逻辑- 前后加一圈边界,比如
int[rows + 2][cols + 2],省去边界判断 - 用
Boolean[][] memo = new Boolean[n][m];来做记忆化搜索 - DP 初始时
dp[0] = 1,防止所有方案都为 0 dp[i][j] = dp[i-1][j] + dp[i][j-1],前提是初始化边界行列为 1- 前缀和数组
sum[0] = 0作为起始 - 滑动窗口中使用
left = 0起始保证不越界 - 用
Map.put("", 0)来初始化空串状态 - 使用
Object[][]初始化为null,统一处理 - 使用
Arrays.fill()统一初始化值 - 二维数组初始化后第一行/列单独填值作为基础状态
③ HashMap / Set 相关技巧(10 个)
map.getOrDefault(key, 0)避免 null 判断- 初始化时使用
HashMap<K, List<V>> map = new HashMap<>()并预填空列表 set.contains(x)前加set.add(x)来避免重复(集合去重)- 使用
defaultdict(Python)/ Guava 的Multimap实现 key 多值存储 - 初始化
frequencyMap.put(x, 0),然后直接加 - 避免
NullPointerException:先 put 后 get - 初始化
Map<String, Object>为 JSON 空对象 TreeMap.put(Integer.MIN_VALUE, value)做边界下限TreeSet.add(Integer.MAX_VALUE)占上界HashMap.putIfAbsent(key, new ArrayList<>()),防止 get 到 null
④ 链表与树结构技巧(10 个)
- 使用 dummy head(哨兵头)统一插入/删除逻辑
- 使用
while (cur.next != null)代替while (cur != null && cur.next != null) - 在叶子节点放一个
null标记,用于层序遍历 root.left = dummyNode防止空指针- 在前序/中序遍历中初始化一个栈顶部为根节点
- 树的递归处理:返回一个特殊节点表示“空”
- BST 初始化时插入
Integer.MIN_VALUE/Integer.MAX_VALUE作为界限 - AVL 树空节点高度为 -1 或 0
- 用
parent = new TreeNode(-1)初始化作为统一父节点 - 平衡树中哨兵节点 root.left/right 指向自身防止 null 判断
⑤ 动态规划 / 状态转移技巧(10 个)
- 初始化状态 dp[0][0] = true/1
- 状态转移时默认值设置为 false / Integer.MAX_VALUE
- 滚动数组优化:用
prev[]和cur[]分别保存状态 - 在状态转移前将不可能的值初始化为 -1
- 初始转移时设置 base case,如
dp[0] = 1 - 填充边界状态减少分支判断
- 使用 dummy 状态简化边界初始化
memo.put(state, result)即使 result 为 0,也要标记已处理- DP 状态转移时初始化为“不可达”状态:如
99999999 - 从
i=1开始循环,使i-1不越界
⑥ 多线程 / 并发相关技巧(10 个)
- 使用 volatile + 初始化值防止指令重排
AtomicInteger(0)初始化后可统一incrementAndGetCountDownLatch(1)起初拦住主线程ThreadLocal初始化默认值synchronized(this)中初始值必须提前设置ConcurrentHashMap.computeIfAbsent()避免多线程并发 put- 初始化对象后立刻用
final保证可见性 - 使用双重检查锁实现延迟初始化
ThreadPoolExecutor默认线程数设置成 CPU 核心数- 响应式编程中使用
CompletableFuture.completedFuture(null)作为默认返回
⑦ 算法类问题常用技巧(15 个)
- 滑动窗口用
left = 0; right = 0起始点统一 - 二分查找使用
left = 0, right = n,或者n-1,看闭区间情况 - 最短路径初始化为
Integer.MAX_VALUE - 最长路径初始化为
Integer.MIN_VALUE - BFS 用
dist[i][j] = -1表示未访问 - DFS 中使用
visited[][] = false - 回溯中初始化 path 为
new ArrayList<>() - 快速幂中 base = 1
- 扫描线算法初始状态为 0
- 单调栈初始时压入 -1 作为“虚拟栈底”
- 判断栈空时先压入特殊符号避免 if
- 合并区间前对区间按左边界排序
- 并查集初始化
parent[i] = i - Dijkstra 中起始点距离为 0,其他点为无穷大
- Prim 算法中初始化最小边权为最大值
⑧ Java 工程实践/代码风格技巧(10 个)
- Optional 初始化为
Optional.empty(),避免 null - 使用
Collections.emptyList()避免返回 null List<String> list = new ArrayList<>(Collections.nCopies(n, ""));- 抽象类中使用默认模板方法,避免子类遗漏初始化
- 使用
Enum.UNKNOWN表示默认值 - 配置类中设置默认值:
@Value("${xx:default}") - 配置读取失败默认用
Map.getOrDefault - 使用常量定义默认值,如
DEFAULT_TIMEOUT = 5000 - 响应体中预设 success=true,失败时再改
- 异常处理统一返回默认结构体,避免 null pointer
⑨ 其他零散技巧(10 个)
- 游戏开发中初始化 HP/MP = max
- 画图/网格中初始化背景色为白
- 二维图初始化
int[][] grid = new int[rows][cols],填 0 表示空地 - 电商库存系统中,商品数量初始化为 0
- 消息队列系统初始化偏移量为 -1
- 数据分析中初始平均值为 0.0
- 金额类系统中默认初始为 BigDecimal.ZERO
- 密码系统中默认值为空字符串,而非 null
- 日志系统默认级别设为 INFO
- 文件处理时默认打开方式为只读
本文由作者按照 CC BY 4.0 进行授权