MQ基础概念面试题

Q1: 什么是消息队列?为什么要使用消息队列?

核心定义

消息队列(MQ)是应用程序之间的异步通信中间件,通过存储和转发消息实现系统解耦。

四大核心价值

1. 异步处理 - 提升响应速度

  • 用户注册:同步300ms → 异步60ms(提升5倍)
  • 非核心业务异步化(邮件、短信、积分)

2. 系统解耦 - 降低耦合度

  • 订单系统不直接调用库存、积分系统
  • 新增下游系统无需修改上游代码

3. 流量削峰 - 保护后端

  • 秒杀:10万QPS → MQ缓冲 → 1000TPS处理
  • 防止数据库被打垮

4. 数据分发 - 一对多通知

  • 一条消息被多个系统消费
  • 用户行为分析、推荐系统、风控系统

代价分析

  • 系统复杂度↑(需处理丢失、重复、顺序)
  • 一致性要求↓(强一致→最终一致)
  • 运维成本↑(部署、监控、维护)
  • 调试难度↑(异步链路追踪)

Q2: RabbitMQ、RocketMQ、Kafka详细对比

维度 RabbitMQ RocketMQ Kafka
开发语言 Erlang Java Scala/Java
开发公司 Pivotal 阿里巴巴 Apache
吞吐量 万级 10万级 百万级
延迟 微秒级 毫秒级 毫秒级
可用性 高(主从) 非常高(分布式) 非常高(分布式)
事务消息 支持(性能差) 原生支持 支持(0.11+)
延迟消息 插件支持 18级别 不支持
消息回溯 不支持 支持 支持
运维难度

详细特性对比

1. RabbitMQ

优点:

  • 消息延迟低(微秒级),适合实时性要求高的场景
  • 功能完善:支持消息确认、死信队列、延迟队列、优先级队列
  • 管理界面友好,易于监控
  • 支持多种语言客户端
  • 灵活的路由机制(Direct/Fanout/Topic/Headers Exchange)

缺点:

  • 吞吐量相对较低(万级)
  • Erlang语言小众,二次开发困难
  • 集群模式复杂(镜像队列会影响性能)
  • 消息堆积能力弱

适用场景:

  • 实时通讯系统
  • 任务调度系统
  • 消息量不大的企业应用
  • 对延迟敏感的场景

2. RocketMQ

优点:

  • 吞吐量高(10万级),支持高并发
  • 功能丰富:事务消息、顺序消息、延迟消息、消息过滤
  • 高可用性:支持主从切换、集群部署
  • 消息查询功能强大(按MessageId、Key查询)
  • Java开发,易于扩展和定制
  • 阿里生产环境验证

缺点:

  • 社区相对Kafka小
  • 需要部署NameServer
  • 配置项较多,学习曲线陡

适用场景:

  • 金融级应用(需要事务消息)
  • 电商平台(订单、支付等核心业务)
  • 需要顺序消息的场景
  • 大规模分布式系统

3. Kafka

优点:

  • 超高吞吐量(百万级),大数据场景首选
  • 分布式设计,水平扩展能力强
  • 消息持久化机制完善
  • 生态系统丰富(Kafka Connect/Streams/KSQL)
  • 高可用性,数据可靠性高
  • 支持消息回溯

缺点:

  • 不支持消息优先级
  • 不原生支持延迟消息
  • 单机超过64个分区性能会下降
  • 依赖ZooKeeper(2.8之前)
  • 运维复杂,参数调优困难

适用场景:

  • 大数据实时计算
  • 日志收集系统(ELK)
  • 用户行为追踪
  • 流式处理
  • 系统监控指标收集

选型决策树

复制代码
开始选型
│
├─ 消息量 > 10万/秒?
│  └─ 是 → Kafka
│
├─ 需要事务消息?
│  └─ 是 → RocketMQ
│
├─ 需要延迟消息?
│  ├─ 是 → RocketMQ 或 RabbitMQ
│  └─ 否 → 继续判断
│
├─ 消息量 < 1万/秒且追求低延迟?
│  └─ 是 → RabbitMQ
│
├─ 大数据/日志收集场景?
│  └─ 是 → Kafka
│
├─ 金融/电商等核心业务?
│  └─ 是 → RocketMQ
│
└─ 简单场景,已有Redis?
   └─ 是 → Redis Stream

Q3: Producer、Consumer、Broker、Topic、Queue核心概念详解

1. Producer(生产者)

定义: 消息的产生者,负责创建并发送消息到消息队列。

职责:

  • 构造消息内容
  • 选择目标队列/Topic
  • 处理发送失败和重试
  • 确认消息发送成功

三种发送方式:

java 复制代码
// 1. 同步发送(可靠性高,性能低)
SendResult result = producer.send(message);
if (result.getSendStatus() == SendStatus.SEND_OK) {
    System.out.println("发送成功");
}

// 2. 异步发送(性能高,需要处理回调)
producer.send(message, new SendCallback() {
    @Override
    public void onSuccess(SendResult result) {
        System.out.println("发送成功");
    }
    @Override
    public void onException(Throwable e) {
        System.out.println("发送失败");
    }
});

// 3. 单向发送(性能最高,不关心结果)
producer.sendOneway(message);

2. Consumer(消费者)

定义: 消息的消费者,负责从消息队列中接收并处理消息。

消费模式:

  • Push模式:Broker主动推送消息给消费者(RabbitMQ)
  • Pull模式:消费者主动从Broker拉取消息(Kafka、RocketMQ)

消费者组(Consumer Group):

复制代码
Topic: order_topic
├─ Consumer Group1: order_service (订单服务消费)
│  ├─ Consumer 1
│  └─ Consumer 2
└─ Consumer Group2: logistics_service (物流服务也消费)
   ├─ Consumer 1
   └─ Consumer 2

特点:

  • 同一个Consumer Group内的消费者共同消费一个Topic
  • 每条消息只会被Group内的一个消费者消费
  • 不同Group可以重复消费同一条消息

3. Broker(消息代理服务器)

定义: 消息队列的核心服务器,负责接收、存储、转发消息。

核心功能:

  • 接收生产者的消息
  • 存储消息(内存/磁盘)
  • 投递消息给消费者
  • 消息持久化
  • 主从复制
  • 负载均衡

RocketMQ Broker架构:

复制代码
┌─────────────────────────┐
│     NameServer集群       │  (服务发现、路由)
└─────────┬───────────────┘
          │
    ┌─────┴─────┐
    │           │
┌───▼───┐  ┌───▼───┐
│Broker1│  │Broker2│
│Master │  │Master │
└───┬───┘  └───┬───┘
    │          │
┌───▼───┐  ┌───▼───┐
│Broker1│  │Broker2│
│ Slave │  │ Slave │
└───────┘  └───────┘

4. Topic(主题)

定义: 消息的逻辑分类,一个Topic可以包含多个Queue/Partition。

特点:

  • 发布/订阅模式
  • 一条消息可以被多个消费者组消费
  • 支持消息过滤

Kafka Topic结构:

复制代码
Topic: order_topic
├─ Partition 0  [Leader: Broker1, Replica: Broker2, Broker3]
│  └─ Offset: 0, 1, 2, 3...
├─ Partition 1  [Leader: Broker2, Replica: Broker1, Broker3]
│  └─ Offset: 0, 1, 2, 3...
└─ Partition 2  [Leader: Broker3, Replica: Broker1, Broker2]
   └─ Offset: 0, 1, 2, 3...

5. Queue(队列)

定义: 消息的存储单元,FIFO顺序。

特点:

  • 点对点模式
  • 每条消息只能被一个消费者消费
  • 消费后消息会被删除(或标记)

Queue vs Topic对比:

复制代码
Queue(点对点):
Producer → Queue → Consumer1
                 → Consumer2  (竞争消费,只有一个能消费到)
                 → Consumer3

Topic(发布订阅):
Producer → Topic → ConsumerGroup1 → Consumer1, Consumer2
                → ConsumerGroup2 → Consumer1, Consumer2
                (每个Group都能收到消息)

Q4: 什么是消费者组(Consumer Group)?

定义

同一个Consumer Group内的消费者共同消费一个Topic,实现负载均衡。

核心特性

  1. 消息只被消费一次

    • 一条消息只会被Group内的一个消费者消费
    • 实现了消息的负载均衡
  2. 不同Group独立消费

    • 不同Consumer Group可以重复消费同一条消息
    • 实现了消息的多播
  3. 自动负载均衡

    • 消费者动态增减时自动rebalance
    • 分区/队列自动分配给消费者

示例场景

复制代码
Topic: order_topic (订单创建事件)

Consumer Group1: order_service
├─ Consumer1: 消费 Partition 0, 1
└─ Consumer2: 消费 Partition 2, 3
(订单服务处理订单创建)

Consumer Group2: logistics_service
├─ Consumer1: 消费 Partition 0, 1, 2
└─ Consumer2: 消费 Partition 3
(物流服务也需要处理同样的订单事件)

Consumer Group3: data_analysis_service
└─ Consumer1: 消费所有 Partition
(数据分析服务分析订单数据)

最佳实践

  1. 合理设置消费者数量

    • 消费者数 ≤ 分区数(超过会浪费)
    • Kafka: 消费者数 = 分区数时效率最高
  2. Group命名规范

    • 使用有意义的名称:{service_name}_consumer_group
    • 例如:order_service_consumer_group
  3. 监控消费进度

    • 监控每个Group的消费Lag
    • 及时发现消费延迟

Q5: Push模式 vs Pull模式详解

Push模式(推送模式)

原理: Broker主动推送消息给Consumer

复制代码
┌──────────┐                  ┌──────────┐
│  Broker  │ ──推送消息────▶  │ Consumer │
│          │ ◀──ACK确认────  │          │
└──────────┘                  └──────────┘

优点:

  • 实时性高,消息到达即推送
  • 使用简单,无需轮询
  • 自动消息分发

缺点:

  • 可能压垮消费者(流量过大)
  • 消费者无法控制消费速率
  • 不易实现批量处理

适用场景:

  • RabbitMQ默认模式
  • 实时性要求高的场景
  • 消息量可控的场景

代码示例(RabbitMQ):

java 复制代码
@Component
public class OrderConsumer {
    @RabbitListener(queues = "order.queue")
    public void onMessage(Order order) {
        // Broker主动推送,直接处理
        processOrder(order);
    }
}

Pull模式(拉取模式)

原理: Consumer主动从Broker拉取消息

复制代码
┌──────────┐                  ┌──────────┐
│ Consumer │ ──拉取请求────▶  │  Broker  │
│          │ ◀──返回消息────  │          │
└──────────┘                  └──────────┘

优点:

  • 消费者控制消费速率,不会被压垮
  • 可以批量拉取,提高效率
  • 可以重复消费(回溯到指定offset)
  • 消费者可以根据自身处理能力拉取

缺点:

  • 可能产生空轮询(消息不存在时)
  • 实时性取决于拉取频率
  • 代码相对复杂

适用场景:

  • Kafka、RocketMQ默认模式
  • 大数据批量处理
  • 需要控制消费速率的场景

代码示例(Kafka):

java 复制代码
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("order_topic"));

while (true) {
    // 主动拉取消息,超时时间100ms
    ConsumerRecords<String, String> records = 
        consumer.poll(Duration.ofMillis(100));
    
    for (ConsumerRecord<String, String> record : records) {
        processOrder(record.value());
    }
    
    // 手动提交offset
    consumer.commitSync();
}

长轮询优化(RocketMQ):

java 复制代码
// RocketMQ的Push实际是基于Pull的长轮询封装
// 如果没有消息,Broker会hold住请求,直到有消息或超时
@RocketMQMessageListener(topic = "order_topic")
public class OrderListener implements RocketMQListener<Order> {
    @Override
    public void onMessage(Order order) {
        // 看起来像Push,实际是长轮询Pull
        processOrder(order);
    }
}

对比总结

维度 Push模式 Pull模式
实时性 高(立即推送) 取决于拉取频率
消费速率 Broker控制 Consumer控制
系统压力 可能压垮Consumer Consumer可控
批量处理 不易实现 容易实现
消息回溯 不支持 支持
空轮询 可能存在
实现复杂度 简单 相对复杂
代表产品 RabbitMQ Kafka, RocketMQ

Q6: 集群模式 vs 广播模式

集群模式(Clustering / Shared Subscription)

定义: 同一Consumer Group内的消费者负载均衡消费消息

特点:

  • 一条消息只被Group内的一个消费者消费
  • 实现负载均衡
  • 提高消费吞吐量

示例:

复制代码
Topic: order_topic
Consumer Group: order_service

Message1 → Consumer1 ✓
Message2 → Consumer2 ✓
Message3 → Consumer3 ✓
Message4 → Consumer1 ✓

RocketMQ配置:

java 复制代码
@RocketMQMessageListener(
    topic = "order_topic",
    consumerGroup = "order_service",
    messageModel = MessageModel.CLUSTERING  // 集群模式(默认)
)
public class OrderConsumer implements RocketMQListener<Order> {
    @Override
    public void onMessage(Order order) {
        // 消息被Group内的某一个Consumer消费
        processOrder(order);
    }
}

适用场景:

  • 业务消息处理
  • 需要负载均衡
  • 提高消费能力

广播模式(Broadcasting)

定义: 每个消费者实例都接收所有消息

特点:

  • 每个Consumer实例都收到相同的消息
  • 实现消息广播
  • 用于全局通知

示例:

复制代码
Topic: config_update
Consumer Instances: app1, app2, app3

ConfigUpdate Message →  app1 ✓
                     →  app2 ✓
                     →  app3 ✓

RocketMQ配置:

java 复制代码
@RocketMQMessageListener(
    topic = "config_update",
    consumerGroup = "app_instance_" + UUID.randomUUID(),  // 每个实例唯一
    messageModel = MessageModel.BROADCASTING  // 广播模式
)
public class ConfigListener implements RocketMQListener<Config> {
    @Override
    public void onMessage(Config config) {
        // 每个实例都会收到消息
        refreshLocalConfig(config);
    }
}

Kafka实现广播:

java 复制代码
// Kafka通过让每个消费者使用不同的Group ID实现广播
String uniqueGroupId = "config_consumer_" + UUID.randomUUID();
props.put("group.id", uniqueGroupId);

KafkaConsumer<String, Config> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("config_topic"));

适用场景:

  • 配置更新通知
  • 缓存刷新
  • 系统广播通知
  • 服务器状态同步

对比总结

维度 集群模式 广播模式
消息消费 一个Group内只有一个Consumer消费 每个Consumer都消费
负载均衡
消费重复 是(每个实例都消费)
吞吐量 高(多Consumer分担) 低(每个都要处理)
适用场景 业务处理 全局通知
Offset管理 Broker统一管理 各Consumer独立管理

Q7: 什么是Exchange?(RabbitMQ特有概念)

Exchange定义

Exchange(交换机)是RabbitMQ特有的概念,接收生产者的消息,根据路由规则分发到队列。

四种Exchange类型

1. Direct Exchange(直连交换机)

特点: 根据routing key精确匹配

复制代码
Producer → Exchange(direct) 
           ├─ routing_key="order.create" → Queue1
           ├─ routing_key="order.pay"    → Queue2
           └─ routing_key="order.cancel" → Queue3

代码示例:

java 复制代码
@Configuration
public class DirectExchangeConfig {
    
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange("order.direct.exchange");
    }
    
    @Bean
    public Queue createQueue() {
        return new Queue("order.create.queue");
    }
    
    @Bean
    public Binding createBinding() {
        return BindingBuilder
            .bind(createQueue())
            .to(orderExchange())
            .with("order.create");  // routing key精确匹配
    }
}

// 发送
rabbitTemplate.convertAndSend("order.direct.exchange", "order.create", order);

适用场景: 需要精确路由的场景

2. Fanout Exchange(扇出交换机)

特点: 广播给所有绑定的队列,忽略routing key

复制代码
Producer → Exchange(fanout) → Queue1
                             → Queue2
                             → Queue3

代码示例:

java 复制代码
@Configuration
public class FanoutExchangeConfig {
    
    @Bean
    public FanoutExchange notifyExchange() {
        return new FanoutExchange("notify.fanout.exchange");
    }
    
    @Bean
    public Binding emailBinding() {
        return BindingBuilder.bind(emailQueue()).to(notifyExchange());
    }
    
    @Bean
    public Binding smsBinding() {
        return BindingBuilder.bind(smsQueue()).to(notifyExchange());
    }
}

// 发送(routing key无效)
rabbitTemplate.convertAndSend("notify.fanout.exchange", "", notification);

适用场景: 消息广播、群发通知

3. Topic Exchange(主题交换机)

特点: 根据routing key模式匹配

  • * 匹配一个单词

  • # 匹配0个或多个单词

    Producer → Exchange(topic)
    ├─ "order.create.success" → Queue1 (order..success)
    ├─ "order.pay.failed" → Queue2 (order.#)
    └─ "user.register.success" → Queue3 (
    .*.success)

代码示例:

java 复制代码
@Configuration
public class TopicExchangeConfig {
    
    @Bean
    public TopicExchange logExchange() {
        return new TopicExchange("log.topic.exchange");
    }
    
    @Bean
    public Binding errorLogBinding() {
        return BindingBuilder
            .bind(errorQueue())
            .to(logExchange())
            .with("log.error.*");  // 匹配 log.error.xxx
    }
    
    @Bean
    public Binding allLogBinding() {
        return BindingBuilder
            .bind(allQueue())
            .to(logExchange())
            .with("log.#");  // 匹配 log.xxx.xxx.xxx
    }
}

// 发送
rabbitTemplate.convertAndSend("log.topic.exchange", "log.error.database", logMsg);

适用场景: 灵活的消息路由、日志分级处理

4. Headers Exchange(头交换机)

特点: 根据消息头属性匹配,不常用

java 复制代码
@Bean
public Binding headersBinding() {
    Map<String, Object> headers = new HashMap<>();
    headers.put("format", "pdf");
    headers.put("type", "report");
    
    return BindingBuilder
        .bind(reportQueue())
        .to(headersExchange())
        .whereAll(headers).match();  // 所有header都匹配
}

Exchange对比

类型 路由方式 性能 适用场景
Direct routing key精确匹配 精确路由
Fanout 忽略routing key,广播 最高 消息广播
Topic routing key模式匹配 灵活路由
Headers 消息头匹配 复杂条件

Q8-Q15: 更多基础概念

Q8: 什么是消息的持久化?

三层持久化(RabbitMQ)

1. Exchange持久化

java 复制代码
DirectExchange exchange = new DirectExchange("order.exchange", true, false);
// 第二个参数 true 表示持久化

2. Queue持久化

java 复制代码
Queue queue = new Queue("order.queue", true);
// 第二个参数 true 表示持久化

3. Message持久化

java 复制代码
MessageProperties props = MessageProperties.PERSISTENT_TEXT_PLAIN;
Message message = new Message(body, props);

重要: 三层都持久化才能保证消息不丢失

RocketMQ/Kafka持久化

  • 默认持久化到磁盘
  • 通过刷盘策略控制:同步刷盘 vs 异步刷盘

Q9: 什么是消息的优先级?

RabbitMQ实现

队列设置最大优先级:

java 复制代码
Map<String, Object> args = new HashMap<>();
args.put("x-max-priority", 10);  // 支持0-10优先级
channel.queueDeclare("priority.queue", true, false, false, args);

消息设置优先级:

java 复制代码
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .priority(5)  // 设置优先级5
    .build();
channel.basicPublish("", "priority.queue", props, message.getBytes());

限制

  • 队列为空时优先级无效
  • 影响性能
  • RocketMQ/Kafka不原生支持

替代方案

使用多个Topic/Queue模拟不同优先级:

  • high_priority_topic
  • normal_priority_topic
  • low_priority_topic

Q10: 什么是消息的过期时间(TTL)?

两种设置方式

1. 队列级别TTL(所有消息统一过期时间)

java 复制代码
@Bean
public Queue orderQueue() {
    return QueueBuilder.durable("order.queue")
        .ttl(60000)  // 60秒
        .build();
}

2. 消息级别TTL(单条消息独立过期时间)

java 复制代码
MessageProperties props = new MessageProperties();
props.setExpiration("30000");  // 30秒
rabbitTemplate.convertAndSend("order.exchange", "order.key", order, message -> {
    message.getMessageProperties().setExpiration("30000");
    return message;
});

过期后处理

RabbitMQ:

  • 进入死信队列(如果配置了DLX)
  • 或直接删除

RocketMQ:

  • 不会立即删除
  • 消费时判断是否过期

Q11: 什么是消息确认机制(ACK)?

自动ACK

java 复制代码
@RabbitListener(queues = "order.queue", ackMode = "AUTO")
public void onMessage(Order order) {
    // 消息发送给消费者就自动确认
    // 风险:处理失败消息丢失
}

手动ACK(推荐)

java 复制代码
@RabbitListener(queues = "order.queue", ackMode = "MANUAL")
public void onMessage(Order order, Channel channel, 
                     @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
    try {
        processOrder(order);
        channel.basicAck(tag, false);  // 手动确认
    } catch (Exception e) {
        channel.basicNack(tag, false, true);  // 拒绝并重新入队
    }
}

NACK/Reject

java 复制代码
// basicNack(可批量)
channel.basicNack(tag, false, true);  // requeue=true重新入队

// basicReject(单条)
channel.basicReject(tag, false);  // requeue=false不重新入队,进死信

Q12: 什么是预取(Prefetch)?

定义

Consumer一次从Broker预取多少条消息

设置方法

java 复制代码
// RabbitMQ
channel.basicQos(100);  // 预取100条

// Kafka
props.put("max.poll.records", 500);  // 一次拉取500条

设置建议

场景 建议值 原因
处理快 100+ 提高吞吐量
处理慢 1-10 避免消息积压在Consumer
顺序消费 1 保证顺序

Q13: 什么是消息路由?

RabbitMQ路由

通过 Exchange + Routing Key 实现

java 复制代码
// 发送时指定routing key
rabbitTemplate.convertAndSend("order.exchange", "order.create", order);

// 绑定时指定routing key
BindingBuilder.bind(queue).to(exchange).with("order.create");

Kafka路由

通过 Partition Key 实现

java 复制代码
ProducerRecord<String, Order> record = new ProducerRecord<>(
    "order_topic",
    order.getUserId().toString(),  // Partition Key
    order
);
// 相同Key的消息进入同一分区
producer.send(record);

RocketMQ路由

通过 MessageQueueSelector 选择Queue

java 复制代码
producer.send(message, new MessageQueueSelector() {
    @Override
    public MessageQueue select(List<MessageQueue> mqs, 
                              Message msg, Object arg) {
        Long userId = (Long) arg;
        int index = (int) (userId % mqs.size());
        return mqs.get(index);
    }
}, order.getUserId());

Q14: 什么是NameServer?(RocketMQ特有)

作用

  • 服务注册与发现:Broker注册到NameServer
  • 路由信息管理:维护Topic与Broker的映射关系
  • 轻量级设计:无状态,易于扩展

vs ZooKeeper

维度 NameServer ZooKeeper
一致性 最终一致性 强一致性(CP)
性能 相对低
复杂度
功能 专注于路由 分布式协调

架构

复制代码
Producer/Consumer 
    ↓ 查询路由
NameServer集群(任意一台)
    ↑ 注册
Broker集群

Q15: 消息队列的应用场景有哪些?

1. 异步处理

  • 用户注册(发邮件、短信)
  • 订单处理(通知物流、财务)
  • 图片/视频处理(上传后异步转码)

2. 系统解耦

  • 订单系统与库存、积分系统解耦
  • 支付系统与订单系统解耦
  • 新增下游系统无需修改上游

3. 流量削峰

  • 秒杀活动
  • 抢购场景
  • 防止数据库被打垮

4. 日志收集

  • ELK架构(Elasticsearch + Logstash + Kafka)
  • 应用日志收集
  • 系统监控指标收集

5. 数据同步

  • 主从数据库同步
  • 缓存与数据库同步
  • 跨系统数据同步

6. 事件驱动

  • 微服务事件总线
  • 领域事件发布订阅
  • CQRS架构

7. 任务调度

  • 异步任务处理
  • 定时任务触发
  • 批量任务处理

8. 消息通知

  • 邮件批量发送
  • 短信批量发送
  • APP推送通知
复制代码
相关推荐
树若逝花若殇几秒前
基于Spring AOP优雅记录请求响应日志
java·spring boot
Yyyyyy~27 分钟前
【java】数组的定义和使用
java
麻辣布丁28 分钟前
java集合篇面试模拟
java·开发语言·面试
niucloud-admin30 分钟前
JAVA V6 多商户商城 开发文档——插件开发规范
java·开发语言
嘟哩DuliDuli43 分钟前
创作 Agent 的任务状态该如何保存
android·java·javascript
wdfk_prog1 小时前
lely-canopen-rtt:为什么推荐在 RT-Thread 上使用 Lely CANopen 构建主站
java·运维·缓存·docker·容器
Token掘金室1 小时前
JSON模式结构化输出报错
java·服务器·json
秋饼1 小时前
Spring AI 2.0 接入 DeepSeek V4.1 Flash 生产级实战
java·ai·技术分享·后端开发
IT枫斗者枫哥1 小时前
Java 分批导出仍然 OOM?用 32 MiB 堆复现三种 CSV 写法
java
shehuiyuelaiyuehao1 小时前
算法43,外观数列,模拟算法+双指针
java·算法