Reactive编程框架与工具

news2025/4/17 21:33:17

在这里插入图片描述

文章目录

    • 6.2 后端 Reactive 框架
      • 6.2.1 Spring WebFlux
        • 核心架构
        • 核心组件
        • 实际应用
        • 高级特性
        • 性能优化
        • 适用场景与限制
      • 6.2.2 Akka(Actor模型)
        • Actor模型基础
        • 基本用法
        • 高级特性
        • 响应式特性实现
        • 性能优化
        • 实际应用场景
        • 优势与挑战
      • 6.2.3 Vert.x(事件驱动)
        • 核心概念
        • 基本架构
        • 基本用法
        • 核心组件
        • 响应式编程支持
        • 高级特性
        • 性能优化
        • 实际应用场景
        • 优势与挑战
      • 6.2.4 后端响应式框架比较
      • 6.2.5 响应式后端设计模式
      • 6.2.6 响应式后端最佳实践
      • 6.2.7 未来趋势

在这里插入图片描述

6.2 后端 Reactive 框架

随着现代应用对高并发、低延迟需求的增长,响应式编程在后端开发领域获得了广泛关注。后端响应式框架通过非阻塞I/O、异步处理和事件驱动架构,能够更高效地利用系统资源,处理大量并发请求。本节将深入探讨三种主流后端响应式框架:Spring WebFlux、Akka和Vert.x。

6.2.1 Spring WebFlux

Spring WebFlux是Spring Framework 5.0引入的响应式Web框架,它支持响应式流(Reactive Streams)规范,提供了一种非阻塞的编程模型来处理并发请求。

核心架构
  1. 响应式基础

    • 基于Project Reactor实现,提供Mono(0-1个元素)和Flux(0-N个元素)两种发布者类型
    • 完全非阻塞,支持背压(backpressure)
    • 可运行在Netty、Undertow或Servlet 3.1+容器上
  2. 与传统Spring MVC对比

特性Spring MVCSpring WebFlux
编程模型命令式声明式响应式
线程模型每个请求一个线程少量线程处理所有请求
阻塞支持
容器要求Servlet容器Servlet容器或Netty等
适用场景传统同步应用高并发、低延迟应用
核心组件

在这里插入图片描述

  1. Reactor类型
// Mono示例
Mono<String> mono = Mono.just("Hello")
                        .delayElement(Duration.ofSeconds(1))
                        .map(String::toUpperCase);

// Flux示例
Flux<Integer> flux = Flux.range(1, 10)
                         .delayElements(Duration.ofMillis(500))
                         .filter(i -> i % 2 == 0);
  1. WebHandler API

    • WebFilter:类似于Servlet Filter的响应式版本
    • WebExceptionHandler:处理异常的响应式方式
    • WebSessionManager:管理会话的响应式接口
  2. 响应式Repository

    public interface UserRepository extends ReactiveCrudRepository<User, Long> {
        Flux<User> findByLastName(String lastName);
        Mono<User> findFirstByUsername(String username);
    }
    
实际应用

在这里插入图片描述

  1. 创建响应式控制器
@RestController
@RequestMapping("/users")
public class UserController {
    private final UserRepository userRepository;
    
    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    @GetMapping
    public Flux<User> getAllUsers() {
        return userRepository.findAll();
    }
    
    @GetMapping("/{id}")
    public Mono<User> getUserById(@PathVariable Long id) {
        return userRepository.findById(id);
    }
    
    @PostMapping
    public Mono<User> createUser(@RequestBody User user) {
        return userRepository.save(user);
    }
}
  1. 响应式WebClient
WebClient client = WebClient.create("http://example.com");

Mono<User> userMono = client.get()
                           .uri("/users/{id}", 1L)
                           .retrieve()
                           .bodyToMono(User.class);

Flux<Order> ordersFlux = client.get()
                             .uri("/users/{id}/orders", 1L)
                             .retrieve()
                             .bodyToFlux(Order.class);
  1. 函数式端点
@Configuration
public class RouterConfig {
    @Bean
    public RouterFunction<ServerResponse> route(UserHandler userHandler) {
        return RouterFunctions.route()
            .GET("/users", userHandler::listUsers)
            .GET("/users/{id}", userHandler::getUser)
            .POST("/users", userHandler::createUser)
            .build();
    }
}

@Component
public class UserHandler {
    private final UserRepository userRepository;
    
    public UserHandler(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public Mono<ServerResponse> listUsers(ServerRequest request) {
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(userRepository.findAll(), User.class);
    }
    
    // 其他处理方法...
}
高级特性
  1. 响应式事务

    @Transactional
    public Mono<Void> transferMoney(Long fromId, Long toId, BigDecimal amount) {
        return userRepository.findById(fromId)
                .flatMap(from -> userRepository.findById(toId)
                .flatMap(to -> {
                    from.setBalance(from.getBalance().subtract(amount));
                    to.setBalance(to.getBalance().add(amount));
                    return userRepository.save(from)
                            .then(userRepository.save(to));
                })
                .then();
    }
    
  2. 服务器发送事件(SSE)

    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<StockPrice> streamStockPrices() {
        return Flux.interval(Duration.ofSeconds(1))
                .map(i -> new StockPrice("SYM", 100 + random.nextDouble() * 10));
    }
    
  3. WebSocket支持

    @Configuration
    @EnableWebFlux
    public class WebSocketConfig implements WebSocketHandlerConfigurer {
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            registry.addHandler(myHandler(), "/ws")
                    .setAllowedOrigins("*");
        }
        
        @Bean
        public WebSocketHandler myHandler() {
            return new MyWebSocketHandler();
        }
    }
    
性能优化
  1. 调度器配置

    • 默认使用弹性(elastic)调度器处理阻塞操作
    • 可配置并行(parallel)调度器用于CPU密集型任务
  2. 背压策略

    • onBackpressureBuffer:缓冲元素
    • onBackpressureDrop:丢弃无法处理的元素
    • onBackpressureLatest:只保留最新元素
  3. 响应式缓存

    CacheManager cacheManager = new ReactiveRedisCacheManager(redisTemplate);
    
    @Cacheable("users")
    public Mono<User> getUserById(Long id) {
        return userRepository.findById(id);
    }
    

在这里插入图片描述

适用场景与限制

适用场景

  • 高并发、低延迟的微服务
  • 流式数据处理应用
  • 实时通信系统
  • 需要水平扩展的服务

限制

  • 学习曲线较陡
  • 调试相对困难
  • 与传统JDBC的集成有限
  • 并非所有库都支持响应式

6.2.2 Akka(Actor模型)

Akka是一个基于Actor模型的响应式工具包和运行时,用于构建高并发、分布式、弹性、消息驱动的应用。

Actor模型基础
  1. 核心概念

    • Actor:计算的基本单元,包含状态、行为、邮箱和子Actor
    • 消息:Actor之间通信的唯一方式,不可变且异步发送
    • 邮箱:存储接收到的消息队列
    • Actor系统:Actor的层级容器,提供配置和调度
  2. Actor生命周期

    • preStart():Actor启动时调用
    • postStop():Actor停止时调用
    • preRestart()postRestart():Actor重启时调用
基本用法
  1. 定义Actor
public class Greeter extends AbstractActor {
    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Greet.class, g -> {
                System.out.println("Hello " + g.who);
                getSender().tell(new Greeted(g.who), getSelf());
            })
            .build();
    }
    
    public static class Greet {
        public final String who;
        public Greet(String who) { this.who = who; }
    }
    
    public static class Greeted {
        public final String who;
        public Greeted(String who) { this.who = who; }
    }
}
  1. 创建Actor系统
ActorSystem system = ActorSystem.create("MySystem");
ActorRef greeter = system.actorOf(Props.create(Greeter.class), "greeter");

greeter.tell(new Greeter.Greet("World"), ActorRef.noSender());
高级特性
  1. 路由(Routing)
ActorRef workerRouter = system.actorOf(
    Props.create(Worker.class).withRouter(new RoundRobinPool(5)));
  1. 持久化(Persistence)
public class PersistentActor extends AbstractPersistentActor {
    private List<Object> events = new ArrayList<>();
    
    @Override
    public String persistenceId() { return "sample-id-1"; }
    
    @Override
    public Receive createReceiveRecover() {
        return receiveBuilder()
            .match(Event.class, events::add)
            .build();
    }
    
    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Cmd.class, c -> {
                persist(new Event(c.getData()), evt -> {
                    events.add(evt);
                    getSender().tell(evt, getSelf());
                });
            })
            .build();
    }
}
  1. 集群(Cluster)
akka {
  actor {
    provider = cluster
  }
  remote {
    artery {
      canonical.hostname = "127.0.0.1"
      canonical.port = 2551
    }
  }
  cluster {
    seed-nodes = [
      "akka://MySystem@127.0.0.1:2551",
      "akka://MySystem@127.0.0.1:2552"]
  }
}
  1. 流处理(Akka Streams)
Source<Integer, NotUsed> source = Source.range(1, 100);
Flow<Integer, String, NotUsed> flow = Flow.of(Integer.class).map(i -> i.toString());
Sink<String, CompletionStage<Done>> sink = Sink.foreach(System.out::println);

RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);
runnable.run(system);

在这里插入图片描述

响应式特性实现
  1. 弹性(Resilience)

    • 监督策略(Supervision):定义Actor失败时的恢复策略
    • 断路器(Circuit Breaker):防止级联失败
  2. 响应性(Responsive)

    • 基于事件的消息驱动模型
    • 非阻塞通信
  3. 弹性(Elastic)

    • 运行时动态调整Actor数量
    • 集群自动负载均衡
  4. 消息驱动(Message Driven)

    • 完全基于异步消息传递
    • 位置透明性(Location Transparency)
性能优化
  1. 调度器配置

    • 为不同类型任务配置不同调度器
    • 隔离阻塞操作
  2. 邮箱选择

    • 无界邮箱(默认)
    • 有界邮箱
    • 优先级邮箱
  3. 序列化优化

    • 使用高效的序列化机制(如Protobuf)
    • 避免发送大型消息
实际应用场景
  1. 交易处理系统

    • 每个交易作为一个Actor
    • 实现高并发处理
    • 确保事务隔离
  2. 实时分析系统

    • 使用Akka Streams处理数据流
    • 实现复杂事件处理(CEP)
  3. 物联网平台

    • 每个设备对应一个Actor
    • 处理设备消息
    • 实现设备状态管理
优势与挑战

优势

  • 高并发处理能力
  • 分布式原生支持
  • 弹性设计
  • 成熟的生态系统

挑战

  • 思维模式转变(从面向对象到Actor模型)
  • 调试困难
  • 学习曲线陡峭
  • 某些场景下性能不如专有解决方案

6.2.3 Vert.x(事件驱动)

在这里插入图片描述
Vert.x是一个轻量级、高性能的响应式应用框架,基于事件总线和非阻塞I/O模型。

核心概念
  1. Verticle

    • Vert.x的基本部署单元
    • 类似Actor,但更轻量级
    • 可以有多种类型(Standard, Worker, Multi-threaded)
  2. Event Bus

    • 应用内部的分布式消息系统
    • 支持点对点、发布/订阅模式
    • 支持集群通信
  3. 非阻塞API

    • 所有I/O操作都是异步非阻塞的
    • 基于回调、Future或RxJava
基本架构
  1. 多语言支持

    • 核心API支持Java、Kotlin、Scala、Groovy等
    • 通过语言扩展支持JavaScript、Ruby等
  2. 模块系统

    • 通过Vert.x Module System管理模块
    • 支持服务发现和动态加载
  3. 垂直扩展与水平扩展

    • 单机多核利用(Event Loop)
    • 集群模式支持
基本用法
  1. 创建Verticle
public class MyVerticle extends AbstractVerticle {
    @Override
    public void start() {
        // 创建HTTP服务器
        vertx.createHttpServer()
            .requestHandler(req -> req.response().end("Hello Vert.x!"))
            .listen(8080);
        
        // 事件总线示例
        vertx.eventBus().consumer("news.uk.sport", message -> {
            System.out.println("Received news: " + message.body());
        });
    }
}
  1. 部署Verticle
public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    vertx.deployVerticle(new MyVerticle());
}
核心组件
  1. Web组件
Router router = Router.router(vertx);

router.get("/api/users").handler(ctx -> {
    ctx.response()
       .putHeader("content-type", "application/json")
       .end(new JsonArray().add("user1").add("user2").toString());
});

vertx.createHttpServer()
     .requestHandler(router)
     .listen(8080);
  1. 数据访问
// JDBC
JDBCClient jdbc = JDBCClient.createShared(vertx, config);
jdbc.getConnection(res -> {
    if (res.succeeded()) {
        SQLConnection connection = res.result();
        connection.query("SELECT * FROM users", ar -> {
            if (ar.succeeded()) {
                // 处理结果
            }
        });
    }
});

// Redis
RedisClient redis = RedisClient.create(vertx);
redis.get("key", res -> {
    if (res.succeeded()) {
        String value = res.result();
    }
});
  1. 服务发现
ServiceDiscovery discovery = ServiceDiscovery.create(vertx);
discovery.getRecord(r -> r.getName().equals("my-service"), ar -> {
    if (ar.succeeded()) {
        Record record = ar.result();
        // 使用服务
    }
});

在这里插入图片描述

响应式编程支持
  1. RxJava集成
// 创建Rxified Vertx实例
Vertx vertx = io.vertx.reactivex.core.Vertx.vertx();

// Rx风格的HTTP服务器
vertx.createHttpServer()
     .requestHandler(req -> req.response().end("Hello Rx Vert.x!"))
     .rxListen(8080)
     .subscribe(server -> System.out.println("Server started"));
  1. 响应式流处理
// 从HTTP请求读取数据流
router.post("/upload").handler(ctx -> {
    ctx.request().toFlowable()
       .flatMap(buffer -> {
           // 处理每个buffer
           return processBuffer(buffer);
       })
       .subscribe(
           result -> {/* 处理成功 */},
           error -> {/* 处理错误 */}
       );
});
  1. Future/Promise
Promise<String> promise = Promise.promise();

vertx.fileSystem().readFile("data.txt", ar -> {
    if (ar.succeeded()) {
        promise.complete(ar.result().toString());
    } else {
        promise.fail(ar.cause());
    }
});

Future<String> future = promise.future();
future.compose(content -> {
    // 处理内容
    return processContent(content);
}).onSuccess(result -> {
    // 最终成功处理
}).onFailure(err -> {
    // 错误处理
});
高级特性
  1. 集群模式
Vertx.clusteredVertx(new VertxOptions(), res -> {
    if (res.succeeded()) {
        Vertx vertx = res.result();
        // 集群模式运行
    }
});
  1. 微服务支持

    • 服务发现与注册
    • 断路器(Circuit Breaker)
    • 配置中心集成
  2. 事件总线桥接

    • 连接浏览器与后端事件总线
    • 支持SockJS
  3. Metrics监控

    • 内置Micrometer支持
    • 提供JVM、事件总线、HTTP等指标
性能优化
  1. Event Loop优化

    • 避免在Event Loop中执行阻塞操作
    • 使用Worker Verticle处理阻塞任务
  2. 配置调优

    • 调整Event Loop线程数
    • 优化Worker线程池大小
  3. 序列化优化

    • 使用高效的序列化机制
    • 避免发送大型消息
实际应用场景
  1. 实时API网关

    • 高并发请求处理
    • 动态路由
    • 认证授权
  2. 微服务架构

    • 轻量级服务实现
    • 服务间事件通信
    • 弹性设计
  3. 物联网后端

    • 处理设备事件
    • 实时数据处理
    • 设备管理

在这里插入图片描述

优势与挑战

优势

  • 极高性能
  • 轻量级设计
  • 多语言支持
  • 丰富的模块生态系统
  • 易于扩展

挑战

  • 回调地狱风险(需配合RxJava/Future解决)
  • 调试复杂性
  • 与传统框架集成有限
  • 学习曲线

6.2.4 后端响应式框架比较

特性Spring WebFluxAkkaVert.x
编程模型响应式流Actor模型事件驱动
基础技术Project ReactorActor模型实现Netty事件循环
主要语言Java/KotlinJava/Scala多语言支持
学习曲线中等陡峭中等
分布式支持需额外组件原生支持原生支持
微服务适用性优秀优秀优秀
性能很高极高
社区生态非常丰富丰富较丰富
适用场景传统企业应用现代化分布式复杂系统高性能实时系统

6.2.5 响应式后端设计模式

  1. 事件溯源(Event Sourcing)

    • 存储状态变化事件而非最终状态
    • 结合CQRS(命令查询职责分离)
  2. 反应式微服务(Reactive Microservices)

    • 服务间异步通信
    • 弹性设计模式(断路器、重试、超时)
  3. 数据流处理(Stream Processing)

    • 使用响应式流处理连续数据
    • 实现复杂事件处理
  4. 背压处理(Backpressure Handling)

    • 消费者控制生产者速率
    • 防止系统过载

6.2.6 响应式后端最佳实践

  1. 避免阻塞操作

    • 识别并隔离所有阻塞调用
    • 使用专用线程池处理阻塞操作
  2. 资源管理

    • 确保所有资源(连接、文件等)正确释放
    • 使用响应式方式管理资源
  3. 错误处理

    • 为所有异步操作提供错误处理
    • 实现弹性模式
  4. 测试策略

    • 使用StepVerifier测试响应式流
    • 模拟高负载场景
    • 验证背压行为
  5. 监控与调优

    • 监控关键指标(延迟、吞吐量、资源使用)
    • 根据性能测试结果调整配置
      在这里插入图片描述

6.2.7 未来趋势

  1. 服务网格集成

    • 与Istio、Linkerd等服务网格技术深度整合
    • 增强可观察性和弹性
  2. 云原生支持

    • 更好的Kubernetes集成
    • 自动伸缩能力增强
  3. 多语言统一API

    • 跨语言一致的响应式API
    • 更简单的多语言服务开发
  4. 响应式SQL

    • 更多数据库支持真正的响应式访问
    • 标准化响应式数据访问接口
  5. Wasm集成

    • WebAssembly在服务端的应用
    • 高性能响应式计算

响应式编程已成为现代后端开发的范式转变,它使开发者能够构建更具弹性、可扩展性和响应性的系统。无论是选择Spring WebFlux、Akka还是Vert.x,理解响应式原则并掌握相应工具,对于构建面向未来的后端系统至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python爬虫第7节-requests库的高级用法

目录 前言 一、文件上传 二、Cookies 三、会话维持 四、SSL证书验证 五、代理设置 六、超时设置 七、身份认证 八、Prepared Request 前言 上一节&#xff0c;我们认识了requests库的基本用法&#xff0c;像发起GET、POST请求&#xff0c;以及了解Response对象是什么。…

Maven的安装配置-项目管理工具

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习&#xff1a;Maven的安装配置-项目管理工具 目录 1.什么是Maven&#xff1f;Maven用来干什么的&#xff1f…

智能 SQL 优化工具 PawSQL 月度更新 | 2025年3月

&#x1f4cc; 更新速览 本月更新包含 21项功能增强 和 9项问题修复&#xff0c;重点提升SQL解析精度与优化建议覆盖率。 一、SQL解析能力扩展 ✨ 新增SQL语法解析支持 SELECT...INTO TABLE 语法解析&#xff08;3/26&#xff09; ALTER INDEX RENAME/VISIBLE 语句解析&#…

Ubuntu虚拟机编译安装部分OpenCV模块方法实现——保姆级教程

Ubuntu虚拟机的安装过程可以查看另一篇文章&#xff1a;VMware安装Ubuntu虚拟机实现COpenCV代码在虚拟机下运行教程-CSDN博客 目前我们已经下载好了OpenCV&#xff0c;这里以OpenCV4.5.2为例。 在内存要求尽可能小的情况下&#xff0c;可以尝试只编译安装代码中使用到的OpenC…

spring mvc @ResponseBody 注解转换为 JSON 的原理与实现详解

ResponseBody 注解转换为 JSON 的原理与实现详解 1. 核心作用 ResponseBody 是 Spring MVC 的一个注解&#xff0c;用于将方法返回的对象直接序列化为 HTTP 响应体&#xff08;如 JSON 或 XML&#xff09;&#xff0c;而不是通过视图解析器渲染为视图&#xff08;如 HTML&…

skynet.rawcall使用详解及应用场景

目录 核心特性函数原型使用场景场景 1&#xff1a;高性能二进制传输&#xff08;如文件转发&#xff09;场景 2&#xff1a;自定义序列化协议&#xff08;如 Protocol Buffers&#xff09;场景 3&#xff1a;跨服务共享内存&#xff08;避免拷贝&#xff09; 配套接收方实现与 …

使用SpringSecurity下,发生重定向异常

使用SpringSecurity下&#xff0c;发生空转异常 环境信息&#xff1a; Spring Boot 3.4.4 &#xff0c; jdk 17 &#xff0c; springSecurity 6.4.4 问题背景&#xff1a; 没有自定义controller &#xff0c;改写了login 页面&#xff0c;并且进行了成功后的跳转处理&#xf…

Elasticsearch | ES索引模板、索引和索引别名的创建与管理

关注&#xff1a;CodingTechWork 引言 在使用 Elasticsearch (ES) 和 Kibana 构建数据存储和分析系统时&#xff0c;索引模板、索引和索引别名的管理是关键步骤。本文将详细介绍如何通过 RESTful API 和 Kibana Dev Tools 创建索引模板、索引以及索引别名&#xff0c;并提供具…

力扣hot100_回溯(2)_python版本

一、39. 组合总和&#xff08;中等&#xff09; 代码&#xff1a; class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:ans []path []def dfs(i: int, left: int) -> None:if left 0:# 找到一个合法组合ans.append(pa…

LPDDR4内存颗粒命名规则全解析:三星、镁光、海力士、南亚、长鑫等厂商型号解码与选型指南

由于之前DDR的系列选型文章有很好的反馈&#xff0c;所以补充LPDDR4低功耗内存的选型和命名规则&#xff0c;总结了目前市面上常用的内存&#xff0c;供硬件工程师及数码爱好者参考。 在智能手机、平板电脑和低功耗设备中&#xff0c;LPDDR4 SDRAM凭借其高带宽、低功耗特性成为…

【杂谈】Godot4.4导出到Android平台(正式导出)

学博而后可约&#xff0c;事历而后知要。 目录 一、准备二、Gradle构建三、配置Java SDK四、配置Android SDK五、配置密钥 一、准备 本文在前文【杂谈】Godot4.4导出到安卓平台&#xff08;调试导出&#xff09;的基础上&#xff0c;进行正式导出。调试导出并不是真正的编译导…

基于AI设计开发出来的业务系统是什么样的?没有菜单?没有表格?

基于AI设计开发出的业务系统仍然会包含菜单、表格等传统UI元素&#xff0c;但AI技术会显著改变它们的实现方式和交互逻辑。以下是具体分析&#xff1a; 一、传统元素的持续存在 功能刚需性 • 菜单承担着系统导航的核心功能&#xff0c;表格则是结构化数据展示的基础载体。根…

数字足迹管理(DFM):你的网络隐身指南

数字足迹管理&#xff08;DFM&#xff09;&#xff1a;你的网络隐身指南 ‌你可能不知道&#xff0c;你的姓名、电话、住址正在网上被“明码标价”‌ ——而这一切&#xff0c;可能只是因为你点过外卖、寄过快递&#xff0c;甚至注册过一个网站。 一、什么是数字足迹管理&#…

如何避免“过度承诺”导致的验收失败

如何避免“过度承诺”导致的验收失败&#xff1f;关键在于&#xff1a; 评估可行性、设置合理目标、高频沟通反馈、阶段性验收、做好风险管理。其中设置合理目标至关重要&#xff0c;很多团队往往在项目初期为迎合客户或领导而报出“最理想方案”&#xff0c;忽略了资源、技术及…

紧跟数字人热潮:123 数字人分身克隆系统源码部署与风口洞察

在当今数字化浪潮中&#xff0c;数字人技术无疑已成为最具活力与潜力的领域之一&#xff0c;正以迅猛之势席卷多个行业&#xff0c;重塑着人们的交互方式与商业运作模式。C 站作为技术交流的前沿阵地&#xff0c;汇聚了众多关注前沿科技的开发者与技术爱好者&#xff0c;今天来…

QT控件 修改QtTreePropertyBrowser自定义属性编辑器源码,添加第一列标题勾选,按钮,右键菜单事件等功能

头阵子遇到一个需要修改QtTreePropertyBrowser控件的需求&#xff0c;QT开发做这么久了&#xff0c;这个控件倒是第一次用&#xff0c;费了点时间研究&#xff0c;在这里做个简单的总结。 QtTreePropertyBrowser控件 是 Qt 解决方案 (Qt Solutions) 中的一个组件&#xff0c;用…

开源模型应用落地-模型上下文协议(MCP)-从数据孤岛到万物互联(一)

一、前言 当开发者还在为每个AI工具编写臃肿的API适配器时&#xff0c;一场关于「连接」的技术革命已悄然降临。模型上下文协议&#xff08;MCP&#xff09;正在用一套全新的交互语法&#xff0c;重新定义人工智能与物理世界的对话方式。MCP协议如同为AI系统装上了“万能接口”…

【区块链安全 | 第三十八篇】合约审计之获取私有数据(二)

文章目录 前言漏洞代码代码审计攻击步骤修复建议审计思路 前言 在【区块链安全 | 第三十七篇】合约审计之获取私有数据&#xff08;一&#xff09;中&#xff0c;介绍了私有数据、访问私有数据实例、Solidity 中的数据存储方式等知识&#xff0c;本文通过分析具体合约代码进行…

mac 苍穹外卖 后端初始 SkyApplication 报错

报错内容 java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field com.sun.tools.javac.tree.JCTree qualid deepseek 解决 打开 File > Project Structure > Project SDK, 选择 JDK17。我没有 JDK17就下载了一…

Proximal Policy Optimization (PPO)

2.1 策略梯度方法 策略梯度方法计算策略梯度的估计值并将其插入到随机梯度上升算法中。最常用的梯度估计器的形式如下&#xff1a; g ^ E t [ ∇ θ log ⁡ π θ ( a t ∣ s t ) A ^ t ] (1) \hat{g} \mathbb{E}_t \left[ \nabla_{\theta} \log \pi_{\theta}(a_t | s_t) \h…