Springboot使用事件流调用大模型接口

news2025/5/12 18:21:28

什么是事件流

事件流(Event Stream) 是一种处理和传递事件的方式,通常用于系统中的异步消息传递或实时数据流。在事件驱动架构(Event-Driven Architecture)中,事件流扮演着至关重要的角色。

事件流的概念:

  1. 事件(Event)
    事件是指系统中的某个状态变更或者操作的发生。例如,用户点击按钮、订单创建、传感器检测到的温度变化等都可以视为事件。

  2. 事件流(Event Stream)
    事件流是指一系列有序的事件,这些事件按照时间顺序传输并可能被处理。事件流是一个数据流,它将事件按顺序传递给系统中的不同组件或服务。

  3. 流的特性

    • 时间序列:事件流通常按照时间顺序传递,也就是说,先发生的事件会先传递。
    • 异步性:事件流通常是异步的,意味着事件的生产者和消费者之间不一定同步工作,消费者可以在稍后的时间消费事件。
    • 连续性:事件流是一个连续的过程,事件会不断地产生并被处理。

事件流的应用场景:

  1. 日志流
    在现代分布式系统中,日志通常会以事件流的形式处理和传输。例如,系统的操作、错误或者状态变更会作为事件记录下来,并通过事件流传输到日志收集和分析系统中。

  2. 实时数据处理
    事件流在实时数据处理场景中非常重要,比如流式处理框架(例如Apache Kafka、Apache Flink等)就是用于处理不断产生的事件流。这些流可以表示实时的交易、用户活动、传感器数据等。

  3. 消息传递
    在消息队列系统中,消息也可以被视为事件流的一部分。生产者发布消息(事件),消费者接收并处理这些消息。

  4. 事件驱动架构(EDA)
    在事件驱动架构中,系统的各个组件通过事件进行通信。每当一个事件发生时,系统的某个部分会被触发并响应这些事件。

事件流与传统流的不同:

  • 传统流:通常是指一系列数据或任务的流转,它通常是在一定的顺序和时间点进行处理。
  • 事件流:是一种更加灵活的流动方式,侧重于异步传递、处理和反应的模式。事件流中的每个事件通常是独立的、无状态的,并且具有明确的触发条件。

事件流的优势:

  • 解耦:生产者和消费者之间通过事件流进行通信,从而降低了系统组件之间的耦合度。
  • 扩展性:可以通过增加事件消费者来横向扩展系统处理能力。
  • 实时性:适合处理实时数据流,事件流可以实时反映系统中的变化。

事件流的实现方式

(1) Servlet 编程中的响应对象:HttpServletResponse

HttpServletResponse 是经典的 Servlet 编程中的响应对象,可以用于向客户端实时推送数据。主要适用于简单的事件流场景。

实现方式

  • 使用 HttpServletResponse 来直接写数据到客户端。
  • 通常通过长连接保持客户端和服务器之间的连接,以便持续推送事件数据。

示例代码

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/event-stream")
public class EventStreamServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置响应头,告知客户端这是一个事件流
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");

        // 获取输出流
        PrintWriter out = response.getWriter();

        // 模拟一个简单的事件流
        int endIndex = 100;
        while (true) {
        	endIndex--;
        	if( endIndex <= 0 ){
        		break;
        	}
            out.println("data: " + System.currentTimeMillis());
            out.println(); // 事件的分隔符
            out.flush();

            try {
                Thread.sleep(1000); // 每秒推送一次事件
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

特点

  • 基本实现:简单地使用 HttpServletResponse 输出流来推送数据。
  • 客户端与服务器之间通过长连接保持数据传输。
  • 没有事件的流控或背压处理,适用于低负载、简单的应用场景。

客户端代码(HTML + JavaScript)

<!DOCTYPE html>
<html>
<head>
    <title>SSE Example</title>
    <script>
        const eventSource = new EventSource("/sse-stream");

        eventSource.onmessage = function(event) {
            console.log("Received event: ", event.data);
            document.getElementById("output").innerText = event.data;
        };
    </script>
</head>
<body>
    <h1>Server Sent Events Example</h1>
    <div id="output"></div>
</body>
</html>

(2) SseEmitter‌

仅需spring-boot-starter-web即可实现基本SSE功能
SSE(Server-Sent Events)是一种基于HTTP的单向通信协议,允许服务器主动推送实时数据到客户端。其核心特点包括轻量级协议、自动重连机制和浏览器原生支持

实现方式

  • 使用 SseEmitter 长连接保持客户端和服务器之间的连接,以便持续推送事件数据。
  • 注意事项
      • ‌超时设置‌:SSE连接默认无超时限制,需显式设置SseEmitter超时参数以避免资源泄漏。
      • ‌‌响应格式‌:确保响应头包含Content-Type: text/event-stream,事件数据需遵循data: \n\n格式。
      • ‌‌连接管理‌:使用ConcurrentHashMap管理客户端连接,及时清理断开或超时的SseEmitter实例。
      • ‌‌异常处理‌:捕获IOException并调用completeWithError()释放资源,避免内存泄漏

示例代码

@RestController
public class SseController {
    // 使用线程安全集合管理连接
    private static final ConcurrentHashMap<String, SseEmitter> emitters = new ConcurrentHashMap<>();

    // 建立SSE连接
    @GetMapping(value = "/sse/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter connect(@RequestParam String clientId) {
        // 设置30秒超时(根据业务调整)
        SseEmitter emitter = new SseEmitter(30_000L);
        emitters.put(clientId, emitter);

        // 注册连接清理回调
        emitter.onCompletion(() -> emitters.remove(clientId));
        emitter.onTimeout(() -> emitters.remove(clientId));
        emitter.onError(e -> {
            log.error("SSE Error: {}", e.getMessage());
            emitters.remove(clientId);
        });

        // 立即发送初始化握手信号
        try {
            emitter.send(SseEmitter.event()
                .name("INIT")
                .data("{\"status\": \"CONNECTED\"}")
            );
        } catch (IOException e) {
            emitter.completeWithError(e);
        }
        
        return emitter;
    }

    // 消息推送方法(可从其他服务调用)
    public void pushMessage(String clientId, String message) {
        SseEmitter emitter = emitters.get(clientId);
        if (emitter != null) {
            try {
                emitter.send(SseEmitter.event()
                    .id(UUID.randomUUID().toString())
                    .name("MESSAGE")
                    .data(message)
                );
            } catch (IOException e) {
                emitter.completeWithError(e);
                emitters.remove(clientId);
            }
        }
    }
}

特点

  • SseEmitter: 这是一个用于发送事件流的类。每次调用 emitter.send() 时,都会向客户端推送一个新的事件。
  • 线程: 在新线程中模拟事件流的生成,每1秒发送一个事件。你可以根据需要调整事件的生成方式。
  • complete() 和 completeWithError(): 这两个方法分别用于表示事件流的正常结束和错误结束。

客户端代码(HTML + JavaScript)

// 建立连接
const eventSource = new EventSource('/sse/connect?clientId=123');

// 监听消息
eventSource.addEventListener('MESSAGE', (e) => {
    console.log('Received:', JSON.parse(e.data));
});

// 错误处理
eventSource.onerror = (err) => {
    console.error('SSE Error:', err);
    eventSource.close();  // 手动关闭连接
};

(3) WebFlux 实现事件流

在使用 Spring WebFlux 构建事件流时,可以通过响应式编程的方式实现高效的事件推送。WebFlux 是 Spring 5 引入的响应式编程模块,主要用于构建异步和非阻塞的应用程序。WebFlux 通过 MonoFlux 来表示异步的数据流,可以非常方便地实现事件流推送。

1. WebFlux 实现事件流的核心概念

  • Mono: 表示一个单一的异步值,通常用于返回单个对象或空值。
  • Flux: 表示多个异步值的流,通常用于返回多个对象。

WebFlux 是基于非阻塞 I/O 的,能够在高并发的环境下进行高效的事件流处理。它允许服务器以流的方式向客户端推送数据,特别适用于实时应用,如实时通知、事件推送等。

2. 实现事件流的步骤

下面是如何通过 WebFlux 实现事件流的一个简单示例。

示例:通过 WebFlux 推送事件流
  1. 创建 Spring Boot 项目并添加 WebFlux 依赖
    首先,确保你有一个 Spring Boot 项目,并且在 pom.xml 中包含 WebFlux 依赖:
<dependencies>
    <!-- WebFlux 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <!-- Spring Boot 启动器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>
  1. 创建事件流控制器

在 WebFlux 中,我们可以使用 Flux 来构建一个事件流。Flux 可以通过不同的方式发出多个数据流。在下面的例子中,我们通过每秒钟发出一个新的时间戳来模拟一个事件流。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import java.time.Duration;

@RestController
public class EventStreamController {

    @GetMapping("/events")
    public Flux<String> streamEvents() {
        // 使用 Flux.interval 每秒钟发送一次事件
        return Flux.interval(Duration.ofSeconds(1))
                   .map(sequence -> "Event at: " + System.currentTimeMillis());
    }
}
解释:
  • Flux.interval(Duration.ofSeconds(1)) 创建一个每秒产生一个事件的流。
  • .map() 方法用来将每个时间戳转换成字符串,表示事件数据。
  • 这个流会一直持续下去,直到客户端关闭连接。
  1. 创建客户端来接收事件流
    在客户端,您可以使用 JavaScript 的 EventSource 来接收服务器推送的事件。以下是一个简单的 HTML 页面,展示了如何接收并显示服务器推送的事件:
<!DOCTYPE html>
<html>
<head>
    <title>WebFlux Event Stream</title>
    <script>
        const eventSource = new EventSource("/events");

        eventSource.onmessage = function(event) {
            document.getElementById("event-data").innerText = event.data;
        };
    </script>
</head>
<body>
    <h1>WebFlux Event Stream</h1>
    <div id="event-data"></div>
</body>
</html>
解释:
  • EventSource("/events") 会建立一个长连接,接收从 /events 路径推送的事件流。
  • 每次收到事件时,onmessage 事件处理程序会将事件内容显示在页面上。
  • WebFlux 是实现事件流的理想选择,特别是当需要处理高并发、高吞吐量的事件流时。
  • 通过 FluxMono 可以简洁地构建异步事件流。
  • 客户端可以通过 EventSource 实现与服务器的事件流通信,提供实时的推送体验。

3. 运行和测试

  1. 启动 Spring Boot 应用。
  2. 访问 http://localhost:8080/ 查看实时事件流。
  3. 每秒钟,页面会显示当前的时间戳,表示从服务器推送的事件。

4. WebFlux 特点

  • 异步和非阻塞: WebFlux 使用响应式编程模型,处理请求时不会阻塞线程,适合高并发场景。
  • 低延迟: 通过 FluxMono,服务器可以高效地处理多个客户端的事件流。
  • 高可扩展性: 适合构建大规模的实时应用(如实时数据分析、推送通知、直播系统等)。
  • 与传统 Servlet 的区别: WebFlux 与传统的 Servlet API 不同,它支持响应式和非阻塞操作,能够更好地应对高负载和高并发的场景。

实战用法(AI流式问答)

!!!!!更推荐使用WebFlux !!!!

Springboot以智普AI的免费AI问答接口为例

配置webclient

package com.gt.quality.ai;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;

/**
 * 万里悲秋常作客,百年多病独登台
 *
 * @author : makeJava
 */
@Component
public class AiLocalConfig {

    HttpClient httpClient = HttpClient.create().
            // 设置连接超时时间为60秒
                    option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000).
            //  设置响应超时时间为60秒
                    responseTimeout(Duration.ofMillis(60000)).
            doOnConnected(con -> con.addHandlerLast(
                    // 设置读取超时时间为60秒
                    new ReadTimeoutHandler(60)
                    // 设置写入超时时间为60秒
            ).addHandlerLast(new WriteTimeoutHandler(60)));

    /**
     * 智普AI对话使用接口的处理器
     * 设置为 5MB缓冲区
     *
     * @param builder Builder
     * @return WebClient
     */
    @Bean(name = "useDialogue")
    public WebClient useDialogue(WebClient.Builder builder) {
        return builder
                .baseUrl("https://open.bigmodel.cn/api/paas/v4/chat/completions")
                // 设置为 5MB
                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(5 * 1024 * 1024))
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

接口使用


    /**
     * 事件流---式调用问答
     */
    @RequestMapping(value = "/zhi_pu_say", method = {RequestMethod.GET, RequestMethod.POST}, produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @Operation(summary = "流式问答")
    public Flux<String> testSseInvoke(@RequestParam(value = "question", defaultValue = "2025年国家GPD第一季度的详细情况?", required = false) String question) {
        log.info("question:{}", question);
        return zhiPuAiProxyService.streamInvoke(question);
    }

    /**
     * 事件流---式调用问答
     */
    @RequestMapping(value = "/jsonToSay", method = RequestMethod.POST, produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @Operation(summary = "流式问答")
    public Flux<String> jsonToSay(@RequestBody String question) {
        return zhiPuAiProxyService.streamInvoke(question);
    }

业务http的流是调用智普AI


    @Override
    public Flux<String> streamInvoke(String question) {
        // Create a map to store the request body
        Map<String, Object> body = new HashMap<>();
        // Set the model to "glm-4-flash"
        body.put("model", "glm-4-flash");
        // Create a list to store the questions
        List<Map<String, Object>> questionList = getAiRoleAndUserBody(question);
        // Add the list of questions to the request body
        body.put("messages", questionList);
        // Set the request_id to a random UUID
        body.put("request_id", UUID.randomUUID().toString());
        // Set the do_sample to true
        body.put("do_sample", true);
        // Set the temperature to 0.95
        body.put("temperature", 0.95);
        // Set the stream to true
        body.put("stream", true);
        // Set the max_tokens to 4095
        body.put("max_tokens", 4095);
        // Create a map to store the response format
        Map<String, Object> responseFormat = new HashMap<>();
        // Set the type of the response format to "json_object"
        responseFormat.put("type", "json_object");
        // Add the response format to the request body
        body.put("response_format", responseFormat);
        // function、retrieval、web_search。
        body.put("type", "web_search");
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);
            headers.set("Accept", MediaType.TEXT_EVENT_STREAM_VALUE);
            headers.set("Accept-Encoding", "gzip, deflate, br");
            headers.set("Connection", "keep-alive");
            headers.set("Authorization", "Bearer " + ZhiPuAIConstant.ZHI_PU_AI_API_KEY);
            // 数据库对话分析
            return webClient.post()
                    .headers(httpHeaders -> httpHeaders.putAll(headers))
                    .bodyValue(JSONUtil.toJsonStr(body))
                    .retrieve().bodyToFlux(String.class)
                    .map(s -> s.replaceAll("data:", ""));
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            return Flux.error(new BusinessSelfException("系统走神了,请稍后再试..."));
        }
    }

    /**
     * 获取ai角色和用户信息
     * @param question question
     * @return
     */
    private List<Map<String, Object>> getAiRoleAndUserBody(String question) {
        List<Map<String, Object>> questionList = new ArrayList<>();
        // Create a map to store the first question
        Map<String, Object> questionMap = new HashMap<>();
        // Set the role of the first question to "system"
        questionMap.put("role", "system");
        // Set the content of the first question
        questionMap.put("content", "你是一个乐于回答各种问题的小助手,你的任务是提供专业、准确、有洞察力的建议。");
        // Add the first question to the list
        questionList.add(questionMap);
        // Create a map to store the second question
        Map<String, Object> questionMap2 = new HashMap<>();
        // Set the role of the second question to "user"
        questionMap2.put("role", "user");
        // Set the content of the second question
        questionMap2.put("content", question);
        // Add the second question to the list
        questionList.add(questionMap2);
        return questionList;
    }

测试接口

在这里插入图片描述

Over

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

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

相关文章

计算机网络--2

TCP三次握手 TCP连接为什么需要三次握手 1. 由于网络情况复杂,可能会出现丢包现象,如果第二次握手的时候服务器就认为这个端口可用,然后一直开启,但是如果客户端未收到服务器发送的回复,那么就会重新发送请求,服务器就会重新开启一个端口连接,这样就会浪费一个端口。 三…

尤雨溪宣布:Vue 生态正式引入 AI

在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…

蓝桥杯第十六届c组c++题目及个人理解

本篇文章只是部分题目的理解&#xff0c;代码和思路仅供参考&#xff0c;切勿当成正确答案&#xff0c;欢迎各位小伙伴在评论区与博主交流&#xff01; 题目&#xff1a;2025 题目解析 核心提取 要求的数中至少有1个0、2个2、1个5 代码展示 #include<iostream> #incl…

硬件工程师笔记——电子器件汇总大全

目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能&#xff08;将电能转化为热能&#xff09; 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 &#xff08;…

微软推动智能体协同运作:支持 A2A、MCP 协议

今日凌晨&#xff0c;微软宣布 Azure AI Foundry 和 Microsoft Copilot Studio 两大开发平台支持最新 Agent 开发协议 A2A&#xff0c;并与谷歌合作开发扩大该协议&#xff0c;这一举措对智能体赛道意义重大。 现状与变革意义 当前智能体领域类似战国时代&#xff0c;各家技术…

Linxu实验五——NFS服务器

一.NFS服务器介绍 NFS服务器&#xff08;Network File System&#xff09;是一种基于网络的分布式文件系统协议&#xff0c;允许不同操作系统的主机通过网络共享文件和目录3。其核心作用在于实现跨平台的资源透明访问&#xff0c;例如在Linux和Unix系统之间共享静态数据&#…

20242817李臻《Linux⾼级编程实践》第9周

20242817李臻《Linux⾼级编程实践》第9周 一、AI对学习内容的总结 第十章 Linux下的数据库编程 10.1 MySQL数据库简介 MySQL概述&#xff1a;MySQL是一个开源的关系型数据库管理系统&#xff0c;最初由瑞典MySQL AB公司开发&#xff0c;后经SUN公司收购&#xff0c;现属于O…

开源分享:TTS-Web-Vue系列:SSML格式化功能与高级语音合成

&#x1f3af; 本文是TTS-Web-Vue系列的第十二篇文章&#xff0c;重点介绍项目新增的SSML格式化功能以及SSML在语音合成中的应用。通过自动格式化和实时预览&#xff0c;我们显著提升了SSML编辑体验&#xff0c;让用户能够更精确地控制语音合成的细节&#xff0c;实现更自然、更…

FAST-LIO笔记

1.FAST-LIO FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器&#xff08;IEKF&#xff09;将激光雷达特征点与IMU数据进行融合&#xff0c;使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。 1…

软考中级软件设计师——UML(统一建模语言)篇

UML的词汇表包含3种构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。 一、事物 UML 事物是模型中的基本元素&#xff0c;分为 结构事物、行为事物、分组事物、注释事物。 1. 结构事物 类&#xff08;Class&#x…

TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题

一、引言 1.1 研究背景与意义 在现代煤矿生产中&#xff0c;井下电力系统作为整个煤矿生产的动力核心&#xff0c;其重要性不言而喻。煤矿井下的各类机械设备&#xff0c;如采煤机、刮板输送机、通风机、排水泵等&#xff0c;都依赖稳定的电力供应才能正常运行。电力系统的稳定…

SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码

在解码RoCEv2数据包&#xff08;包括TCP RDMA和RoCE RDMA&#xff09;时&#xff0c;若捕获的跟踪数据无法正确解码&#xff0c;通常需要执行特定的解码步骤。对于RoCE RDMA跟踪数据的处理&#xff0c;分析器主要采用两种方式获取必要信息以实现数据包解码&#xff1a; 首先&am…

信号处理基础

一、目的 掌握信号处理的基本思想&#xff0c;理解采样信号的频谱特性,加强信号采样与重建的有关基本概念的理解&#xff0c;深入理解线性时不变系统输出与输入的关系&#xff0c;了解数字信号采样率转换前后信号频谱的特征。 二、内容与设计思想 1、给定序列&#xff0c;绘…

小刚说C语言刷题—1058 - 求出100至999范围内的所有水仙花数

1.题目描述 2.参考代码(C语言版) #include <stdio.h> int main(void) { int i; int bai,shi,ge; for( i100;i<999;i) { baii/100; shii/10%10; gei%10; if((bai*bai*bai)(shi*shi*shi)(ge*ge*ge)i) printf("%d\n",i); } return 0; } 今天内容到此结束&…

深入解析Docker:核心架构与最佳实践

文章目录 前言一、Docker 解决了什么问题&#xff1f;二、Docker 底层核心架构2.1 Docker 引擎的分层架构2.2 镜像的奥秘&#xff1a;联合文件系统&#xff08;UnionFS&#xff09;2.3 容器隔离的核心技术2.3.1 命名空间2.3.2 控制组&#xff08;Cgroups&#xff09;2.3.3 内核…

Edge浏览器PDF字体显示错误

Edge浏览器PDF字体显示错误 软件版本信息 Edge Version: 136.0.3240.50 Word Version: Microsoft Office 专业增强版2021问题描述 在Word中使用多级列表自动编号, 并使用Word软件自带的导出为PDF文件功能, 在Word中显示正常的数字, 在Edge中查看PDF将会出现渲染错误的现象,…

Python训练营打卡——DAY22(2025.5.11)

复习日 学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号——来自灾难的机器学习 数据来源&#xff1a; kaggle泰坦里克号人员生还预测 挑战 泰坦尼克号沉没是历史上最臭名昭著的海难之一。 1912年4月15日&#xff0c;在被普…

实战项目4(05)

​目录 任务场景一 【sw1配置】 任务场景二 【sw1配置】 【sw2配置】 任务场景一 按照下图完成网络拓扑搭建和配置 任务要求&#xff1a; 1、在交换机SW1的E0/0/1端口进行设置&#xff0c;实现允许最多两个电脑可以正常进行通信。 2、在交换机SW1的E0/0/2端口进行设置&…

C++学习之STL学习

在经过前面的简单的C入门语法的学习后&#xff0c;我们开始接触C最重要的组成部分之一&#xff1a;STL 目录 STL的介绍 什么是STL STL的历史 UTF-8编码原理&#xff08;了解&#xff09; UTF-8编码原理 核心编码规则 规则解析 编码步骤示例 1. 确定码点范围 2. 转换为…

3. 仓颉 CEF 库封装

文章目录 1. capi 使用说明2. Cangjie CEF2. 1实现目标 3. 实现示例 1. capi 使用说明 根据上一节 https://blog.csdn.net/qq_51355375/article/details/147880718?spm1011.2415.3001.5331 所述&#xff0c; cefcapi 是libcef 共享库导出一个 C API, 而以源代码形式分发的 li…