ChatGpt基于第三方API2D服务封装的SpringBoot starter

news2024/12/28 20:56:08

前置条件:
看下API2D官网,第三方API2D服务对接流程:
其对接文档地址
https://api2d.com/wiki/doc

一:创建一个空的Maven项目
完成后整的项目层级图如下
在这里插入图片描述

1.pom.xml 中添加相关依赖包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>jinyi-chatgpt-api2d-starter</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <jinyi-up.version>1.0.0</jinyi-up.version>
        <lombok.version>1.18.22</lombok.version>
        <commons-lang3.version>3.12.0</commons-lang3.version>
        <fastjson.version>2.0.22</fastjson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <!--不设置optional或者optional是false,表示传递依赖.  此处表示两个项目之间依赖不传递-->
            <optional>true</optional>
             <version>2.6.11</version>
        </dependency>
		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
         <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool-all.version}</version>
        </dependency>
         <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
    </dependencies>

</project>

2.项目中涉及到的类

package com.jinyi.up.chatgpt.api2d.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "dbj.chatgpt.api2d")
public class ChatGptApi2dConfig {
    private String host;
    private String forwardKey;
}
package com.jinyi.up.chatgpt.api2d.constants;
import lombok.Getter;
/**
 * api2d常量
 *
 * @author zhiquan
 */
@Getter
public class Api2dConstant {
    /**
     * 正式接口,分布式部署
     */
    public static final String API2D_HOST_OFFICIAL = "https://openai.api2d.net";
    /**
     * 备用接口,如果上一个无法使用(比如因为域名包含 openai 被屏蔽)可以使用这个
     */
    public static final String API2D_HOST_STANDBY = "https://oa.api2d.net";

    /**
     * 临时域名,如果前两个都无法访问可以尝试这两个(过期时间 2024-06-15)
     */
    public static final String API2D_HOST_TEMPORARY_1 = "https://oa.api2d.site";
    public static final String API2D_HOST_TEMPORARY_2 = "https://oa.api2d.online";
    /**
     * 备用接口,如果前两个都无法使用,可以使用这个
     */
    public static final String API2D_HOST_BACKUP_1 = "https://stream.api2d.net";
    /**
     * 请求拼接模板
     */
    public static final String reqUrlTemplate = "%s%s";

    /**
     * OpenAI 聊天接口( /v1/chat/completions )
     */
    public static final String CHAT_COMPLETIONS_URL = "/v1/chat/completions";
    /**
     * OpenAI 内容补全接口( /v1/completions )
     */
    public static final String COMPLETIONS_URL = "/v1/completions";
    /**
     * OpenAI 文本编辑接口( /v1/edits )
     */
    public static final String EDITS_URL = "/v1/edits";
    /**
     * OpenAI 向量生成接口( /v1/embeddings )
     */
    public static final String EMBEDDINGS_URL = "/v1/embeddings";
    /**
     * OpenAI 图片生成接口( /v1/images/generations )
     */
    public static final String IMAGES_GENERATIONS_URL = "/v1/images/generations";
}
package com.jinyi.up.chatgpt.api2d.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * @author  zhiquan
 */
@AllArgsConstructor
@Getter
public enum Api2dModelTypeEnum {
    GPT_4(1, "gpt-4"),
    GPT_4_0314(2, "gpt-4-0314"),
    GPT_3_5_TURBO_0301(3, "gpt-3.5-turbo-0301"),
    GPT_3_5_TURBO(4, "gpt-3.5-turbo");

    private Integer status;

    private String describe;


    public static Api2dModelTypeEnum match(Integer status, Api2dModelTypeEnum defaultEnum) {
        if (status != null) {
            for (Api2dModelTypeEnum item : Api2dModelTypeEnum.values()) {
                if (item.status.equals(status)) {
                    return item;
                }
            }
        }
        return defaultEnum;
    }

    public static String getDescirbe(Integer status, String defaultStr) {
        if (status != null) {
            for (Api2dModelTypeEnum item : Api2dModelTypeEnum.values()) {
                if (item.status.equals(status)) {
                    return item.getDescribe();
                }
            }
        }
        return defaultStr;
    }
}

package com.jinyi.up.chatgpt.api2d.entitys;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * chat 调用 聊天接口( /v1/chat/completions )需要封装的请求对象
 *  @author zhiquan
 */
@Data
@Accessors(chain = true)
public class Api2dParamData {

    private String model;

    private List<Api2dParamSonData> messages;
}

package com.jinyi.up.chatgpt.api2d.entitys;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * chat 调用 聊天接口( /v1/chat/completions )需要封装的请求对象Api2dParamData的子对象
 * @author zhiquan
 */
@Data
@Accessors(chain = true)
public class Api2dParamSonData {

    private String role = "user";

    private String content;
}

package com.jinyi.up.chatgpt.api2d.entitys;


import lombok.Data;

import java.util.List;

/**
 * chat 调用 聊天接口( /v1/chat/completions )后返回的json
 *字段完全同步于第三方响应字段
 * @author zhiquan
 */
@Data
public class ChatCompletionsResponse {
    /**
     * 对话标识符,用于唯一标识此次聊天会话
     */
    private String id;
    /**
     * 对象类型,表示此响应是一个聊天完成事件
     */
    private String object;
    /**
     * 响应创建时间的时间戳
     */
    private int created;
    /**
     * 使用的模型名称,此处为“gpt-3.5-turbo-0301"
     */
    private String model;
    /**
     * 包含模型生成的选择回答的列表,这里只有一个选项
     */
    private List<Choices> choices;
    /**
     * API 的使用情况统计信息
     */
    private Usage usage;
}

package com.jinyi.up.chatgpt.api2d.entitys;

import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;

/**
 * chat 调用 聊天接口( /v1/chat/completions )后返回的json对象的子属性
 * 字段完全同步于第三方响应字段
 *
 * @author zhiquan
 */
@Data
public class Choices {
    /**
     * 回答的索引号。
     */
    private int index;
    /**
     * 表示模型生成的回答
     */
    private Message message;
    /**
     * 完成原因,这里是“stop",表示模型停止生成回答
     */
    @JSONField(name = "finish_reason")
    private String finishReason;
}

package com.jinyi.up.chatgpt.api2d.entitys;

import lombok.Data;

/**
 * chat 调用 聊天接口( /v1/chat/completions )后返回的json对象的子属性
 *字段完全同步于第三方响应字段
 * @author zhiquan
 */
@Data
public class Message {
    /**
     * 角色,这里是“assistant",表示助手角色生成的回答
     */
    private String role;
    /**
     * 回答的内容
     */
    private String content;
}

package com.jinyi.up.chatgpt.api2d.entitys;

import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;

/**
 * chat 调用 聊天接口( /v1/chat/completions )后返回的json对象的子属性
 * 字段完全同步于第三方响应字段
 *
 * @author zhiquan
 */
@Data
public class Usage {
    /**
     * 用于 prompt 的令牌数量
     */
    @JSONField(name="prompt_tokens")
    private int promptTokens;
    /**
     * 生成的回复的令牌数量
     */
    @JSONField(name="completion_tokens")
    private int completionTokens;
    /**
     * 请求的总令牌数量 (包括输入和输出)
     */
    @JSONField(name="total_tokens")
    private int totalTokens;
    /**
     * 截至此次请求时的令牌数
     */
    @JSONField(name="pre_token_count")
    private int preTokenCount;
    /**
     * 初始限制的令牌数。
     */
    @JSONField(name="pre_total")
    private int preTotal;
    /**
     * 根据模型的内部限制调整后的令牌数
     */
    @JSONField(name="adjust_total")
    private int adjustTotal;
    /**
     * 最终用于此次请求的令牌数。
     */
    @JSONField(name="final_total")
    private int finalTotal;
}

package com.jinyi.up.chatgpt.api2d.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.jinyi.up.chatgpt.api2d.config.ChatGptApi2dConfig;
import com.jinyi.up.chatgpt.api2d.constants.Api2dConstant;
import com.jinyi.up.chatgpt.api2d.entitys.Api2dParamData;
import com.jinyi.up.chatgpt.api2d.entitys.Api2dParamSonData;
import com.jinyi.up.chatgpt.api2d.entitys.ChatCompletionsResponse;
import com.jinyi.up.chatgpt.api2d.enums.Api2dModelTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * api2d 请求util
 */
@Slf4j
@Component
public class ChartGptApi2dUtil {

    @Resource
    private ChatGptApi2dConfig chatGptApi2dConfig;

    /**
     * 调用POST请求类型(application/json)接口
     *
     * @param
     * @return
     */
    private String publicApi2dInterface(String jsonStr, String url) throws Exception {
        String authTemp = "Bearer %s";
        String HttpResponseBodyStr = HttpRequest.post(url)
                .header("Content-Type", "application/json")
                .header("Authorization", String.format(authTemp, chatGptApi2dConfig.getForwardKey()))
                .body(jsonStr)
                .timeout(60000)
                .execute().body();
        return HttpResponseBodyStr;
    }

    /**
     * ChartGPT聊天 返回响应的转换后的对象
     *
     * @param reqContent 输入的提问内容
     * @param modelType  chatgpt版本type{@link com.jinyi.up.chatgpt.api2d.enums.Api2dModelTypeEnum}
     * @return ChatCompletionsResponse
     */
    public ChatCompletionsResponse chatCompletionsEntity(Integer modelType, String reqContent) throws Exception {
        String resultJsonStr = chatCompletionsString(modelType, reqContent);
        log.info(resultJsonStr);
        if (!StringUtils.isBlank(resultJsonStr)) {
            ChatCompletionsResponse bean = JSONUtil.toBean(resultJsonStr, ChatCompletionsResponse.class);
            return bean;
        }
        return null;
    }

    /**
     * ChartGPT聊天返回原生响应的JSON STRING
     *
     * @param reqContent 输入的提问内容
     * @param modelType  chatgpt版本type{@link com.jinyi.up.chatgpt.api2d.enums.Api2dModelTypeEnum}
     * @return
     */
    public String chatCompletionsString(Integer modelType, String reqContent) throws Exception {
        Api2dParamSonData api2dParamSonData = new Api2dParamSonData()
                .setContent(reqContent);
        List<Api2dParamSonData> messages = Lists.newArrayList(api2dParamSonData);
        Api2dParamData api2dParamData = new Api2dParamData()
                .setModel(Api2dModelTypeEnum.getDescirbe(modelType, Api2dModelTypeEnum.GPT_3_5_TURBO.getDescribe())).setMessages(messages);
        String url = String.format(Api2dConstant.reqUrlTemplate, chatGptApi2dConfig.getHost(), Api2dConstant.CHAT_COMPLETIONS_URL);
        log.info("ChartGPT聊天 请求url:{},请求param:{}", url, api2dParamData);
        return publicApi2dInterface(JSONUtil.toJsonStr(api2dParamData), url);
    }
}

3.resources文件夹下添加META-INF/spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
 com.jinyi.up.chatgpt.api2d.utils.ChartGptApi2dUtil,\
com.jinyi.up.chatgpt.api2d.config.ChatGptApi2dConfig

4.使用说明

jinyi-chatgpt-api2d-starter

jinyi-chatgpt-api2d-starter

时间当前版本版本特性作者
2023.7.120.0.1-RELEASE1.初版仅提供chatGpt提问功能zhiquan

组件简介

  • 基于API2D的API封装的

1.Spring Boot 项目添加 Maven 依赖

  <dependency>
            <groupId>com.jinyi.up</groupId>
            <artifactId>jinyi-chatgpt-api2d-starter</artifactId>
            <version>1.0.0</version>
        </dependency>

2、在application.properties 或者 application.yml 等配置文件中增加如下配置

dbj.chatgpt.api2d.host=https://stream.api2d.net   #api2d对外提供的ChatGpt访问的Api Host
dbj.chatgpt.api2d.forwardKey=fk****************8  #api2d服务提供的Forward Key
dbj:
  chatgpt:
    api2d:
      host: https://stream.api2d.net  #api2d对外提供的api访问Host
      forwardKey: fk****************8 #api2d服务提供的Forward Key 

3、使用示例

@Slf4j
@RestController
@RequestMapping("/test")
public class StarterTestController {

    @Resource
    private ChartGptApi2dUtil chartGptApi2dUtil;

    @GetMapping("/gptStarter")
    public R<Object> gptStarter() {
        try {
            ChatCompletionsResponse result = chartGptApi2dUtil.chatCompletionsEntity(4, "儿童节文案");
            return R.ok(result);
        } catch (Exception e) {
            log.error("gpt回话请求异常:", e);
        }
        return R.failed();
    }
}

4、ChartGptApi2dUtil能力

4.1 chatCompletionsEntity(Integer modelType, String reqContent)方法: OpenAI 聊天方法,返回封装的ChatCompletionsResponse对象

**4.2 chatCompletionsString(Integer modelType, String reqContent)**方法:OpenAI 聊天方法,返回的调用api2d openApi接口后返回的原生json字符串

chatCompletionsEntity() 和chatCompletionsString()请求参数相同,详见如下表格

参数字段类型是否必填描述备注
modelTypeInteger*api2d 对应的model版本枚举 ,1: GPT_4 4:gpt-3.5-turbo详见Api2dModelTypeEnum
reqContentString*向chatgpt提问的问题内容

ChatCompletionsResponse对象属性说明

{
    "id": "chatcmpl-7bgwmOfeGf14HkOrpMCJ4x9cvdArF", #对话标识符,用于唯一标识此次聊天会话
    "object": "chat.completion", #对象类型,表示此响应是一个聊天完成事件
    "created": 1689217580, #响应创建时间的时间戳
    "model": "gpt-3.5-turbo-0613",  #使用的模型名称,此处为gpt-3.5-turbo-0613
    "choices": [  #包含模型生成的选择回答的列表,这里只有一个选项
      {
        "index": 0, #回答的索引号。
        "message": {  #表示模型生成的回答
          "role": "assistant", #角色,这里是“assistant",表示助手角色生成的回答
          "content": "科比,全名科比·布莱恩特(Kobe Bryant),1978年8月23日出生于美国宾夕法尼亚州费城,2019年1月26日因直升机失事意外身亡,是一位美国职业篮球运动员。科比是NBA历史上最伟大的球员之一,被誉为“黑曼巴”,他在职业生涯期间效力于洛杉矶湖人队。\n\n科比在NBA生涯中获得了众多荣誉,包括5个NBA总冠军、2个NBA总决赛最有价值球员(MVP)、4个全明星赛最有价值球员(MVP),以及18次入选NBA全明星阵容等。他也是NBA历史得分榜上位列第4的球员,总得分超过了3万分。\n\n除了在NBA的成功之外,科比也是美国国家队的重要成员,并在2008年和2012年两届奥运会上帮助美国队夺得金牌。\n\n科比在场上以他的得分能力和个人进攻技巧著称,他是一位极具竞争力的球员,对胜利有着强烈的渴望。他的篮球智商和技术使他成为一个精准的得分手,同时他也是一位出色的防守球员。\n\n科比的突然离世使全球篮球界深感痛惜,他的篮球成就和影响力将永远铭记在人们心中。" #回答的内容
        },
        "finishReason": "stop"  #完成原因,这里是“stop",表示模型停止生成回答
      }
    ],
    "usage": { #API 的使用情况统计信息
      "promptTokens": 9, #用于 prompt 的令牌数量
      "completionTokens": 463, #生成的回复的令牌数量
      "totalTokens": 472, # 请求的总令牌数量 (包括输入和输出)
      "preTokenCount": 4096, # 截至此次请求时的令牌数
      "preTotal": 42, #初始限制的令牌数。
      "adjustTotal": 37, #根据模型的内部限制调整后的令牌数
      "finalTotal": 5   #最终用于此次请求的令牌数。
}

原生Json字符串返回说明:

{"id":"chatcmpl-7bh9aayOMAY9z0iFDR5P4kdLNIjW1","object":"chat.completion","created":1689218374,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"message":{"role":"assistant","content":"科比(Kobe),全名科比·布莱恩特(Kobe Bryant),是一位美国职业篮球运动员,出生于1978年8月23日,于2020年1月26日因直升机事故不幸去世。科比在NBA的职业生涯中效力于洛杉矶湖人队,被认为是最伟大的篮球运动员之一。\n\n科比从高中时期就开始展现出与众不同的篮球天赋,在1996年的NBA选秀中以第13顺位被夏洛特黄蜂队选中,但很快被湖人队用于交换筹码,成为NBA历史上最年轻的球员之一。\n\n科比在湖人队的职业生涯中取得了众多成绩,包括5次NBA总冠军、2次NBA总决赛MVP、1次常规赛MVP等荣誉。他是湖人队历史上得分最高的球员,并在职业生涯中共获得了4次得分王的称号。\n\n除了职业联赛中的成功,科比还是美国国家队的成员,参加了多次国际比赛,其中包括2008年北京奥运会和2012年伦敦奥运会,帮助美国获得金牌。\n\n科比以其出色的得分能力、技术精湛的投篮和极高的竞争意识而闻名,他被誉为NBA历史上最全能的得分手之一。科比对比赛有着非常高的热情和敬业精神,他的工作态度和专注度也给球迷们留下了深刻的印象。\n\n科比的突然离世给整个篮球界和广大球迷带来了巨大的震惊和悲伤。他将永远被人们铭记为一位伟大的篮球运动员,为他在篮球领域的贡献和对于比赛的热爱致以敬意与怀念。"},"finish_reason":"stop"}],"usage":{"prompt_tokens":9,"completion_tokens":619,"total_tokens":628,"pre_token_count":4096,"pre_total":42,"adjust_total":35,"final_total":7}}

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

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

相关文章

《C语言初阶篇》听说你还不会for循环的变种写法?一文教你彻底搞懂循环语句!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言&#x1f4ac; for 语句的介绍&#x1f4ad; for循环默认可以控制几条语句&#xff1f;&#x1f4ad; for语…

vite基于vue3项目,打包之后的文件夹增加一个额外的文件夹

vite将项目打包之后&#xff0c;自动会生成一个dist文件&#xff0c;里边只有/assets,index.html,favicon.ico.这三个文件。 现在需求是打包之后&#xff0c;dist文件夹下多怎加一个healthcheck的文件夹。 功能实现&#xff1a; 使用复制的方法&#xff0c;将healthcheck文件…

[C++] 为什么头文件最好只做声明

文章目录 问题阐述问题分析和解决方法参考 问题阐述 问题描述&#xff1a; 当编译大的复杂的工程时&#xff0c;经常会遇到一个函数在头文件定义的时候&#xff0c;会导致冲突的问题&#xff1b;下图给出显性原因分析&#xff1b; 问题分析和解决方法 参考 C/C中在头文件中定义…

我爱学QT-把QT程序打包成windows文件

学习链接&#xff1a; 把QT程序打包成Windows软件_哔哩哔哩_bilibili 什么是打包和部署&#xff1f; 因为我们要把写好的程序发给用户来用&#xff0c;我们写好的源码也不能随便给别人。 怎么打包和部署&#xff1f; 1.把工程切换到release模式 这样点 &#xff0c;然后编译…

阿里大模型——通义千问

目录 前段时间世界人工智能大会在上海举行&#xff0c;我去参观感受了一下&#xff0c;整个感受是有点名不副实的&#xff0c;参展的有各种银行、车企、还有中国电信、联通三个运营商都来凑热闹了。 但是也有Google、华为、阿里、腾讯、商汤这样的大厂。现场也可以体验一些大厂…

ESP32开发板引脚介绍【附有引脚使用实例】

ESP32开发板引脚介绍 文章目录 ESP32开发板引脚介绍&#x1f468;‍&#x1f3eb;内容1&#xff1a;背景&#x1f468;‍⚖️内容2&#xff1a;限制类引脚&#x1f468;‍&#x1f4bb;内容3&#xff1a;ESP32 周边设备&#x1f349;文末备注 &#x1f468;‍&#x1f3eb; &am…

shell编程基础(第11篇:重定向)

前言 编写shell脚本程序时&#xff0c;总会使用重定向技术&#xff0c;用来永久保存程序的输出到文件中&#xff0c;或者用来从文件中提取文本到程序中&#xff0c;都支持哪些重定向呢&#xff1f; 温习3个文件描述符 1、标准输入&#xff0c;标准规定通常是键盘&#xff0c;数…

【Ajax】笔记-POST请求(原生)

POST请求 html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>AJAX POST 请求</title><…

PFD 鉴相器设计

鉴相器一般用两个D触发器&#xff0c;一个与非门和一个延迟单元 假设两个D触发器脉冲信号完全相同&#xff0c;查看D触发器输出端可以看到&#xff0c;在脉冲信号到来之后&#xff0c;D触发器输出端电压随脉冲信号升高&#xff0c;两个DFF输出同时为高时&#xff0c;与非门输出…

国科生活小程序使用须知

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、子账号是什么&#xff1f;二、子账号怎么用&#xff1f;三、怎么创建子账号&#xff1f;四、账单怎么看&#xff1f;使用须知联系开发者 前言 国科生活小程…

代码随想录算法学习心得 44 | 309.最佳买卖股票的时机含冷冻期、714.买卖股票的最佳时机含手续费、最近买卖股票时机总结...

一、最佳买卖股票的时机含冷冻期 链接&#xff1a;力扣 描述&#xff1a;给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买…

【Java】一篇文章彻底吃透抽象类和接口 |超详细,建议收藏

博主简介&#xff1a;努力学习的预备程序媛一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: Java岛冒险记【从小白到大佬之路】 文章目录 一、抽象类1.1&#xff1a;抽象类的概念1.2&#xff1a;抽象类的定义1.3&#xff1a;抽象类的特性1.4&#xff1a;抽象类的作用和意义 二、…

捕获FormData实现极简的上传图片到服务器-实战

1.postman设置请求和查看响应结果 说明&#xff1a;上图中通过传入参数名为avatar,参数值为file格式&#xff0c;请求方式为post,采用form-data格式传入服务器。响应结果。 2.html5网页实现 <input type"file" class"upload_inp" /><button cla…

java堆溢出和栈溢出

一、堆溢出 import java.util.ArrayList; import java.util.List;public class Demo_071202 {public static void main(String[] args) {List<Test> listnew ArrayList<>();while (true){list.add(new Test());}}static class Test{} }设置JVM初始堆空间和最大堆…

告别传统MQ:Kafka是一个分布式事件流平台,这到底意味着什么呢?

1、引言 在大数据时代&#xff0c;实时数据处理和流式数据分析变得越来越重要。为了应对大规模数据的高吞吐量和低延迟处理需求&#xff0c;出现了各种分布式流处理平台。其中&#xff0c;Apache Kafka作为一种高性能、可扩展的分布式消息系统&#xff0c;成为了广泛应用于实时…

并发编程 - EDA 实操

文章目录 需求CodeUser定义不同类型的EventChat Channel(Handler)Chat User线程小结需求 借助我们开发的EDA小框架,模拟一个简单的聊天应用程序。 Code User 我们定义一个User对象,代表聊天室的参与者 package com.artisan

【每日一题】931 . 最小下降路径总和

【每日一题】931 . 最小下降路径总和 931 . 最小下降路径总和题目描述解题思路 931 . 最小下降路径总和 题目描述 给你一个n x n方形队列&#xff0c; matrix请你找出并返回matrix下降路径 的最小和。 下降路径可以从第一行中的任意元素开始&#xff0c;并从每一行中选择一个…

函数基础

一、初识函数 函数&#xff0c;可以当做是一大堆功能代码的集合。 def 函数名():函数内编写代码......函数名()例如&#xff1a; # 定义名字叫info的函数 def info():print("第一行")print("第二行")print("第n行...")info()运用函数的场景&a…

uniApp之同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示、adb、shell、package、uninstall

文章目录 背景解决思路执行查找第三方应用的指令执行卸载指令 背景 一开始正常编译运行&#xff0c;由于应用页面有些许奇怪的错误&#xff0c;便想着卸载&#xff0c;重新运行安装调试基座。卸载后&#xff0c;运行还是会出现&#xff0c;明明已经把应用卸载了&#xff0c;还是…

C++在线五子棋对战(网页版)项目:实用工具类模块代码实现

在线五子棋项目中需要用到的实用工具模块&#xff1a; 1.日志宏&#xff1a;实现程序日志打印 2.mysql_util:数据库的连接和初始化&#xff0c;句柄的消耗&#xff0c;语句的执行 3.json_util&#xff1a;封装实现json的序列化和反序列化 4.string_util&#xff1a;封装实现字符…