leecodecode【区间DP+树形DP】【2026.6.10打卡-java版本】

最长回文子序列

要点:两个for维护区间?

java 复制代码
class Solution {
    public int longestPalindromeSubseq(String s) {
        char[] c =s.toCharArray();
        int n = s.length();
        int[][] f = new int[n][n];
        for(int i = n-1; i>=0; i--){
            f[i][i] =1;
            for(int j = i+1; j < n; j++){
                f[i][j] = c[i] == c[j] ? f[i+1][j-1] +2 : Math.max(f[i+1][j], f[i][j-1]);
            }
        }

        return f[0][n-1];
        
    }
}

多边形三角剖分的最低得分

要点:困难

java 复制代码
class Solution {
    public int minScoreTriangulation(int[] v) {
        int n = v.length;
        int[][] f = new int[n][n];
        for (int i = n - 3; i >= 0; i--) {
            for (int j = i + 2; j < n; j++) {
                f[i][j] = Integer.MAX_VALUE;
                for (int k = i + 1; k < j; k++) {
                    f[i][j] = Math.min(f[i][j], f[i][k] + f[k][j] + v[i] * v[j] * v[k]);
                }
            }
        }
        return f[0][n - 1];
    }
}

二叉树的直径

要点:left,right

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 {
    //dfs
    int ans =1;
    public int diameterOfBinaryTree(TreeNode root) {
        //int ans = 1;
        depth(root);
        return ans - 1;
        
    }

    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int left = depth(root.left);
        int right =depth(root.right);

        ans = Math.max(ans, left+right+1);

        return Math.max(left, right) + 1;


    }
}

二叉树中的最大路径和

要点:加上root。val

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 {
    int ans = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return ans;
        
    }

    public int dfs(TreeNode root){

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

        int left = dfs(root.left);
        int right = dfs(root.right);
        ans = Math.max(left+right+root.val , ans);
        return Math.max(root.val+Math.max(left, right), 0);
        
    }
}

相邻字符不同的最长路径

要点:多叉树

java 复制代码
class Solution {
    private List<Integer>[] g;
    private char[] s;
    private int ans;

    public int longestPath(int[] parent, String s) {
        this.s = s.toCharArray();
        int n = parent.length;
        g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for (int i = 1; i < n; i++) {
            g[parent[i]].add(i);
        }
        dfs(0);
        return ans + 1;
    }

    private int dfs(int x) {
        int maxLen = 0;
        for (int y : g[x]) {
            int len = dfs(y) + 1;
            if (s[y] != s[x]) {
                ans = Math.max(ans, maxLen + len);
                maxLen = Math.max(maxLen, len);
            }
        }
        return maxLen;
    }
}

随机知识

核心题**:你觉得怎么保证消息不丢?RabbitMQ 为此提供了哪些机制?

面试官为什么这么问?

消息丢失是生产事故。我问这个是要你从生产端、Broker 端、消费端三个环节完整阐述,每个环节都说到关键机制。能说全说明你至少有排查过问题的意识。

希望听到怎样的回答:

  • 生产端(Producer → Broker) :开启 Publisher Confirm 机制。生产者发消息后等待 Broker 返回确认,没收到就重发。
  • Broker 端
    • 队列持久化(durable = true)。
    • 消息持久化(deliveryMode = 2)。
    • 注意:持久化也不是绝对不丢,毕竟刚写完缓存还没刷盘可能宕机。更可靠可用镜像队列(Mirror Queue)。
  • 消费端(Broker → Consumer)
    • 关闭自动 ACK,采用手动确认basicAck)。
    • 处理成功才确认,失败则 basicNackbasicReject,消息重回队列或进入死信。
  • 总结:至少要提到Confirm + 持久化 + 手动 ACK 三者组合,才能做到消息可靠传递。

候选人

好的,这是一个生产环境中非常关键的问题。消息丢失可能发生在三个环节:生产端到 BrokerBroker 自身Broker 到消费端。要保证消息不丢,就必须在每个环节都做好防护,形成闭环。


第一,生产端:防止发送时消息丢失。

Producer 把消息发送给 Broker 的过程中,可能因为网络抖动或 Broker 宕机导致消息没有送达。RabbitMQ 提供了 Publisher Confirm(发布确认) 机制来解决这个问题。

开启 Confirm 模式后,生产者每发一条消息,Broker 收到并持久化后,会返回一个 ACK 告诉生产者"我收到了"。如果消息投递失败(比如找不到指定的交换机),Broker 会返回 NACK,或者在一定时间内没有任何回应。

生产端代码需要处理这两种情况:收到 ACK 就继续发下一条;收到 NACK 或超时,就重发这条消息。Confirm 是异步的,可以批量确认,性能比事务机制好得多,是生产环境的标配。


第二,Broker 端:防止消息在存储时丢失。

消息到了 Broker 之后,如果 Broker 突然宕机重启,内存中的消息会全部丢失。所以 RabbitMQ 提供了持久化 能力,但持久化不是单一开关,需要同时满足两个条件

  • 队列持久化 :声明队列时设置 durable = true。这样即使 Broker 重启,队列本身不会被删除,积压的消息还在。
  • 消息持久化 :发送消息时设置 deliveryMode = 2,消息属性标记为持久化。这样消息会被写入磁盘,而不是只存在内存里。

但注意,持久化也不是绝对安全。 RabbitMQ 并不是每收到一条消息就立刻刷盘,而是间隔一段时间批量写入,如果在刷盘间隔内 Broker 宕机,最近几条消息仍然可能丢失。所以有了更进一步的方案------镜像队列

镜像队列把队列数据同步到集群中的多个节点上。消息写入主节点后,同步复制到从节点。主节点宕机,从节点自动接管,消息不会丢。代价是性能下降和网络开销增加。现在更推荐的是 Quorum Queue(仲裁队列),基于 Raft 协议保证多数节点一致,比老式镜像队列更可靠。


第三,消费端:防止处理时消息丢失。

Broker 把消息投递给消费者,如果消费者刚收到消息还没处理就挂了,消息也会丢。所以 RabbitMQ 在消费端提供了手动 ACK 机制

默认是自动 ACK:消息投递给消费者,Broker 立刻删掉消息。消费者宕机导致消息没处理完,这条消息就永丢了。

生产上必须关掉自动 ACK,开启手动确认 :消费者处理完业务逻辑后,调用 basicAck 告诉 Broker 可以安全删除消息。如果业务处理失败,调 basicNackbasicReject,让消息重新入队或进入死信队列排队后续处理。

手动 ACK 是整个可靠性链的最后一道防线,处理成功才确认,失败就重试或补偿。

第四,用具体场景串联。

用户注册为例:注册成功后触发发短信。注册成功要保证短信至少投递一次。用的是 Confirm + 持久化 + 手动 ACK 的组合。生产者先发消息到 Broker,用 Publisher Confirm 确认消息已送达;消息和队列都持久化防止重启丢失。

消费端关掉自动 ACK,手动确认。如果消费端拿到消息后调短信服务失败,可以有两种处理方式:一是返回 NACK 把消息重新入队等待重试,需要做好幂等处理;二是超过重试上限后将消息转存到死信队列,后续人工或定时任务补偿处理,避免无限制重试对系统的冲击。

同时为了防止消息积压,可以配合死信队列加上监控告警,当积压超过阈值时能立刻发现并人工介入。

总结一句话:保证消息不丢,需要在生产端用 Publisher Confirm、Broker 端用持久化和镜像/仲裁队列、消费端用手动 ACK,三者组合形成可靠传输闭环。另外还有两个重要补充:一是声明 Exchange 和 Queue 时开启持久化,并通过管理界面确认 D 标识已经生效,因为切换配置后若不重建队列,旧的队列属性不会自动变化,需要物理删除再重新声明;二是即使消息不会丢失,也可能会重复,服务链路必须实现幂等,结合业务唯一键或消费记录去重表来保证数据的最终一致性。

碎碎念:后续会更新每天学习的八股和算法 题,开始准备秋招的第31天。努力连续更新100天!以后每天就按,秋招项目【java+agent】,科研,必做项目,算法,八股,锻炼身体来总结。

总结:得多动脑子

1.算法要系统过一遍【灵神】23/27【早上】1h

2.秋招项目,【java】开始实际看业务,1/6;无

【agent】还在学,整理cc,无,

3.科研要跑一下,【下午】3h+【晚上】3h

4.检测项目也得总结文档,无1h

6.背八股,无

7.锻炼身体,1h

反思:得用脑子多想,不能老依靠ai


相关推荐
小刘|1 小时前
Spring WebFlux + AI 流式输出深度解析:Spring AI 与 LangChain4j 效果差异溯源
java·后端·spring
Arvin.Angela2 小时前
Maven 的基本配置操作
java·maven
夕除2 小时前
Spring Security 配置类(SecurityConfig)
java·后端·spring
weixin199701080162 小时前
[特殊字符] 1688开放平台API Sign签名算法详解(Java / Python / PHP 实现)
java·python·算法
武子康2 小时前
Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理
java·后端
未若君雅裁2 小时前
JVM 垃圾回收算法与分代回收机制
java·jvm·算法
智者知已应修善业2 小时前
【51单片机初始化D5-D8亮,每按键按下D1到D4全亮,再按下恢复,如此循环】2024-3-26
c++·经验分享·笔记·算法·51单片机
摇滚侠2 小时前
SpringMVC 入门到实战 简介和入门案例 01-13
java·后端·spring·intellij-idea