hot100【查缺补漏+打印线程abc】【2026.7.30打卡-java版本】

12. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

叶子节点 是指没有子节点的节点。

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        
         return dfs(root,targetSum);
    }

    public boolean dfs(TreeNode root,int targetSum){

        if(root == null){
            return false;
        }

        //是从根节点到子节点,要判断等于0的点是不是子节点
        if(root.val == targetSum && root.left == null && root.right ==null){
            return true;
        }

        

        boolean left = dfs(root.left,targetSum - root.val);
        boolean right = dfs(root.right, targetSum - root.val);

        return left || right;
    }
}

轮流打印abc

java 复制代码
package hot100;

public class ThreadPrintingABC {

    public static class PrintABC{
        private final int max;
        private int state = 0;

        PrintABC(int max){
            this.max = max;
        }

        public void Print(String letter, int num){
            for(int i = 0; i < max; i++){
                synchronized (this){
                    while(state%3 != num){
                      try{
                          this.wait();
                      }catch(InterruptedException e){
                          e.printStackTrace();
                      }
                    }

                    System.out.println(Thread.currentThread().getName() + "->" + num);
                    state++;
                    notifyAll();;
                }
            }
        }
    }

    public static void main(String[] args) {
        PrintABC printABC = new PrintABC(5);

        Thread a = new Thread(() -> printABC.Print("A",0),"Thread-A");
        Thread b = new Thread(() -> printABC.Print("B",1),"Thread-B");
        Thread c = new Thread(() -> printABC.Print("C",2),"Thread-c");
        a.start();
        b.start();
        c.start();

    }

}

基于我们整个对话,我把所有核心知识点为你浓缩成一套"总结笔记"。看完这篇,面试问到这个题你就能对答如流了。


1. 核心结论:你的代码完全正确

你写的 synchronized + wait/notifyAll 方案是标准且满分 的面试答案。唯一要改的是输出语句,把 num 换成 letter,否则打印的是数字 0/1/2 而不是 A/B/C。


2. 终于弄懂的对象与内存(房子与遥控器)

  • 对象 = 堆内存里的实体(房子) :执行 new PrintABC(5) 就是在堆里盖了一栋房子,里面放着 max=5state=0

  • 引用 = 栈里的遥控器(变量)printABC 存储在栈中,指向堆里的房子。

  • 三个线程共享的前提 :A、B、C 三个线程的 Lambda 表达式,捕获的都是同一个遥控器 printABC ,所以它们操作的是同一栋房子

  • static 的真相

    • 你问的 public static class PrintABC静态嵌套类 ,意思是不持有外部类 ThreadPrintingABC 的遥控器(独立图纸),这跟"类变量"完全是两码事

    • state 不需要加 static 。因为是三个线程操作同一个对象 ,所以 state 天然共享。如果加了 static,虽然也能跑,但不利于以后创建多个独立打印机(会互相干扰)。


3. 线程到底是怎么按顺序跑的?(锁与等待池)

  • 唯一锁对象 :三个线程争抢的锁,是堆里那栋 printABC 房子自带的一把"大门锁"(Monitor,存储在对象头里)。

  • 运行流程

    1. A 线程抢到锁,发现 state%3 == 0,打印 A,state++ 变成 1,notifyAll() 唤醒大家,退出同步块。

    2. B 抢到锁,发现 state%3 == 1,打印 B,state++ 变 2,唤醒大家。

    3. C 抢到锁,发现 state%3 == 2,打印 C,state++ 变 3(即 0),唤醒大家。

    4. 下一轮,A 再次抢到锁(或者 B 抢到但检查不通过,乖乖 wait 让出),如此循环。

  • wait() 的妙用 :调用 wait() 时,线程会释放锁 并进入"等待室"(WaitSet),把锁让给下一个线程;被唤醒后,它必须先重新抢到锁,才能从 wait() 处继续往下执行。


4. 两个写法的区别(面试官可能会追问)

你的写法(synchronized + notifyAll) 我给的写法(ReentrantLock + Condition)
唤醒所有线程(惊群效应),不满足条件的再次阻塞等待,CPU 稍有消耗但代码更简单。 精准唤醒下一个线程(如只唤 B),性能更高,但代码稍复杂。
面试回答技巧 :如果面试官问缺点,你就说"如果用 notifyAll,线程会全部醒来抢锁,造成不必要的上下文切换,但用 while 检查条件可以确保安全,在简单场景下完全够用。" 如果面试官问优化,你就说"可以用 Lock + Condition 精准唤醒,避免惊群。"

5. 终极避坑口诀(背下来,面试稳了)

  1. while 不用 if:防止虚假唤醒,醒来后必须再检查一遍是否轮到我了。

  2. wait() 必须释放锁:否则别的线程进不来,程序就死锁了。

  3. 共享的根源是"同一个对象" ,不是 static 关键字。

sql

复制代码
select name from Customer where  referee_id IS NULL or referee_id != 2;

碎碎念:后续会更新每天学习的八股和算法题,开始准备秋招的第81天。努力连续更新100天!

总结:加油吧

相关推荐
实验如有神祝女士16 小时前
不同参数规模大模型在医学翻译场景的适配差异
论文阅读·人工智能·深度学习·学习·算法·语言模型·论文笔记
风中芦苇啊16 小时前
Java EasyExcel 导入通用工具类:自定义注解映射字段 + 反射机制
java·开发语言
家有娇妻张兔兔17 小时前
Java 对接 PLC 主流型号最合适的方案:Apache PLC4X 实战指南
java·开发语言·plc·modbus·数据缓存·西门子s7·apache plc4x
windliang17 小时前
Claude Code 源码分析(三):一次模型回答如何流进 Agent
前端·算法·ai编程
摇滚侠18 小时前
Codebuddy 官网 Codebuddy IntelliJ IDEA 插件 阅读笔记 2
java·笔记·intellij-idea
gugucoding18 小时前
24. 【Java】枚举:更安全的常量
java·开发语言
Kyrie_kk18 小时前
Java--BigInteger 超大整数计算
java·算法
汽车网络安全爱好者18 小时前
Public Key Infrastructure(二)— 深入理解 X.509 证书:从 RFC 5280 到 OpenSSL 实践
运维·服务器·算法·网络安全·汽车·密码学·可信计算技术
开发者联盟league19 小时前
Java 通过 JNA 调用 C++ DLL:关键流程总结
java·c++·jna
tkevinjd19 小时前
力扣131-分割回文串
算法·leetcode·深度优先