智能SQL生成:后端技术与LLM的完美结合

文章目录

  • 引言
  • 一、什么是大模型
  • 二、为什么选择LLM
  • 三、开发技术说明
  • 四、系统架构说明
  • 五、编码实战
    • 1. Maven
    • 2. 讯飞大模型配置类
    • 3. LLM相关的封装
    • 4. 编写LLM的service
    • 5. 编写controller
    • 6. 运行测试
  • 六、总结

引言

本篇文章主要是关于实现一个类似Chat2DB的根据自然语言生成SQL的简单Demo,根据此Demo可以入门大模型应用开发,结合大模型开发出属于自己的大模型应用,让自己的应用智能化,可以根据用户不同问题做出不同的回答。

image-20240225175115184

一、什么是大模型

如果各位有关注一些技术文章,难免会注意到这几年有一个词非常火,没错这就是“大模型”!

那大模型是什么?有什么用呢?

“大模型”是可以指任何规模较大、参数众多的机器学习模型,不仅限于自然语言处理(NLP),也可以包括计算机视觉、语音识别等其他领域的模型。大模型的特点是它们通常需要大量的数据来训练,以及相对较大的计算资源。

大模型的用途十分广泛,在很多领域都有不错的应用价值:

  1. 自然语言的生成和理解:大模型可以根据用户的问题生成连贯的文本回答、或是总结某些文章。ChatGPT就是一个不错的例子。
  2. 图像的处理:例如OpenAI的DALL·E模型,它可以根据用户问题,生成新的图像。
  3. 语言的识别和生成:大模型可以将文本信息转化为人类的语言。
  4. 推荐系统:大模型可以根据用户的行为或某些数据,推测用户的行为爱好,实现个性化推荐。

大模型的应用十分广泛,除了上面举的例子外,还有很多例子,这里就不一一举例了。

61b63d3c-3.png

下面我会使用大模型的其中一种**大型语言模型(Large Language Model,简称LLM)**开发出一些简单的应用Demo,读者可以根据这样的思路进一步完善。

在此之前,先来介绍一下LLM是何物。LLM是指专门用来处理和理解自然语言的大型机器学习模型,LLM通常通过在大量文本数据上进行预训练来学习语言的结构和语义,从而能够执行各种语言处理任务,如文本生成、翻译、摘要、问答和情感分析等。


二、为什么选择LLM

LLM大模型是一款专注于理解和生成自然语言的大模型,那我们系统中无论是Redis还是MySQL的数据,都是文本形式的,将这些文本信息的数据交与大模型处理,能够有针对性地获取到我们想要的数据。

其次,LLM的使用成本较低,国内的大模型无论是讯飞星火大模型还是其他互联网厂商自研的大模型都为开发者提供了不少的免费Token,使得学习成本大大降低。

LLM大模型也是我们大部分人群目前接触最多的大模型,学习成本大幅度降低,只需要知道如何和大模型进行聊天即可懂得如何开发,不需要任何额外的学习成本。

img


三、开发技术说明

本文使用的大模型为讯飞星火大模型,但是咱们不限于任何厂商的大模型,有能力的ChatGPT也可以,作者只是觉得讯飞星火大模型送的Token比较多,非常适合初学者。

读者需要自行前往讯飞星火认知大模型-AI大语言模型-星火大模型-科大讯飞 (xfyun.cn)进行领取免费Token,领取教程这里就不多讲了,网上大把教程,不懂的可以下面留言。

其次,该教程后端方面需要懂得使用SpringBoot进行开发,也就是简单的一个接口开发,没有任何的前端。

最后,开发出来的Demo只是一个抛砖引玉的作用,开发过程中不会考虑太多的规范和其他一些限制,只是单纯把一个小功能实现,代码量也不多,一千行不到。

如果这些都准备好了,那么下面开始发车。


四、系统架构说明

本篇文章会带大家结合后端技术与讯飞星火大模型实现实现根据用户的自然语言问题生成SQL的工具。

自然语言生成SQL?是不是很熟悉,没错,这里是参考了阿里开源的Chat2DB数据库管理功能,不过这里是作者对这个功能自主实现的Demo,没有翻阅过Chat2DB源码,故这里的实现可能并不是Chat2DB的底层实现原理

有能力的可以自己去看看源码:Chat2DB: Chat2DB 是一款有开源免费的多数据库客户端工具,支持windows、mac本地安装,也支持服务器端部署,web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2DB集成了AIGC的能力,能够将自然语言转换为SQL,也可以将SQL转换为自然语言,可以给出研发人员SQL的优化建议,极大的提升人员的效率,是AI时代数据库研发人员的利器,未来即使不懂SQL的运营业务也可 (gitee.com)

怎么根据用户的自然语言描述生成用户想要的SQL呢?下面我们来分析分析

image-20240225172301437

  1. 首先,用户发送一个包含数据库host、user、password、table、用户问题的请求给后端
  2. 后端根据用户提供的数据库信息,连接数据库查询出该表的DDL
  3. 后端与LLM建立连接,将DDL、用户问题、prompt发送给LLM
  4. LLM根据后端提供的数据以及问题,推测分析并生成SQL,将SQL返回给后端
  5. 后端将SQL返回响应给用户

也就是说,后端需要获取并整理数据,然后与LLM建立连接,将数据发送给LLM,LLM再根据数据做出回答,返回给后端SQL,这样就实现了自然语言生成SQL


五、编码实战

了解了整体架构是如何之后,我们进入了编码实战阶段,编码整体来说比较简单,重要的理解整体的架构


1. Maven

构建SpringBoot项目,引入一些我们需要的Maven依赖

    <dependencies>

        <!-- SpringBoot Web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.12.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--okhttp3-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.43</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version> <!-- 根据你需要的版本进行调整 -->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2. 讯飞大模型配置类

为了方便维护,需要将讯飞星火大模型配置成一个类,方便日后维护

并根据接口文档的内容生成鉴权信息

星火认知大模型Web API文档 | 讯飞开放平台文档中心 (xfyun.cn)

@ConfigurationProperties("xun-fei.xing-huo")
@Component
@Data
public class XFLlmConfig {

    private String appId;

    private String domain;

    private String wsUrl;

    private String role;

    private String host;

    private String path;

    private String apiSecret;

    private String apiKey;

    private Long maxResponseTime;

    private String prompt;

    public String getWsUrl() {
        try {
            String httpUrl = wsUrl.replaceAll("wss", "https");
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            String formatData = sdf.format(date);
            String tmp = "host: " + host + "\n";
            tmp += "date: " + formatData + "\n";
            tmp += "GET " + path + " HTTP/1.1";
            Mac mac = Mac.getInstance("hmacsha256");
            SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
            mac.init(spec);
            byte[] hexDigits = mac.doFinal(tmp.getBytes(StandardCharsets.UTF_8));
            // Base64加密
            String sha = Base64.getEncoder().encodeToString(hexDigits);
            String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
            // 拼接地址
            HttpUrl url = Objects.requireNonNull(HttpUrl.parse(httpUrl)).newBuilder().
                    addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).
                    addQueryParameter("date", formatData).
                    addQueryParameter("host", host).
                    build();
            return url.toString().replace("http://", "ws://").replace("https://", "wss://");
        } catch (Exception e) {
            throw new RuntimeException("getWsUrl 发生异常");
        }
    }

}

application.yml

xun-fei:
  xing-huo:
    appId: 你的appId
    domain: xxxx
    wsUrl: wss://${xun-fei.xing-huo.host}${xun-fei.xing-huo.path}
    role: user
    apiSecret: xxxx
    apiKey: xxxx
    host: spark-api.xf-yun.com
    path: /v3.5/chat
    #  30s
    maxResponseTime: 30000
    prompt: '下面是一些表的DDL语句, 请严格根据这些DDL语句结合用户的问题为用户生成所需的SQL: \n%s \n用户问题是: %s\n注意只需要回复SQL即可!'

3. LLM相关的封装

下面的request以及response都是参考的接口文档封装的,需要自己看看文档。

请求LLM的Request封装

@Data
public class XFLlmRequest {
    @JsonProperty("header")
    private Header header;
    @JsonProperty("parameter")
    private Parameter parameter;
    @JsonProperty("payload")
    private Payload payload;

    @Data
    @Builder
    public static class Header {
        @JsonProperty("app_id")
        private String appId;
        @JsonProperty("uid")
        private String uid;
    }

    @Data
    @Builder
    public static class Parameter {
        @JsonProperty("chat")
        private Chat chat;
    }

    @Data
    @Builder
    public static class Chat {
        @JsonProperty("domain")
        private String domain;
        @JsonProperty("temperature")
        private Double temperature;
        @JsonProperty("max_tokens")
        private Long maxTokens;
    }

    @Data
    @Builder
    public static class Payload {
        @JsonProperty("message")
        private Message message;
    }

    @Data
    @Builder
    public static class Message {

        @JsonProperty("text")
        private List<Text> text;
    }

    @Data
    @Builder
    public static class Text {
        @JsonProperty("role")
        private String role;
        @JsonProperty("content")
        private String content;
    }
}

响应体封装

@Data
public class XFLlmResponse {

    @JsonProperty("header")
    private Header header;
    @JsonProperty("payload")
    private Payload payload;

    @Data
    public static class Header {
        @JsonProperty("code")
        private Long code;
        @JsonProperty("message")
        private String message;
        @JsonProperty("sid")
        private String sid;
        @JsonProperty("status")
        private Long status;
    }

    @Data
    public static class Payload {

        @JsonProperty("choices")
        private Choices choices;
    }

    @Data
    public static class Choices {

        @JsonProperty("status")
        private Long status;
        @JsonProperty("seq")
        private Long seq;
        @JsonProperty("text")
        private List<Text> text;
    }

    @Data
    public class Text {
        @JsonProperty("content")
        private String content;
        @JsonProperty("role")
        private String role;
        @JsonProperty("index")
        private Long index;
    }
}

WebSocketListener的具体实现,用于收集llm返回的结果

@Slf4j
public class XFWebSocketListener extends WebSocketListener {

    /**
     * 断开websocket标志位
     */
    @Getter
    private volatile boolean wsCloseFlag = false;

    /**
     * 锁
     */
    @Getter
    private final Object lock = new Object();

    /**
     * 语句组装buffer,将大模型返回结果全部接收,在组装成一句话返回
     */
    private StringBuilder answer = new StringBuilder();

    public String getAnswer() {
        return answer.toString();
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        log.info("讯飞星火大模型连接成功!");
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        synchronized (lock) {
            super.onMessage(webSocket, text);
            XFLlmResponse response = JSON.parseObject(text, XFLlmResponse.class);
            log.info("response:{}", JSON.toJSONString(response));
            if (response.getHeader().getCode() != 0) {
                log.error("发生错误,错误信息为:{}", JSON.toJSONString(response.getHeader()));
                answer.append("大模型响应异常,请联系管理员");
                // 关闭连接标识
                wsCloseFlag = true;
                lock.notify();
                return;
            }
            List<XFLlmResponse.Text> textList = response.getPayload().getChoices().getText();
            for (XFLlmResponse.Text temp : textList) {
                log.info("讯飞大模型返回结果信息为:{}", JSON.toJSONString(temp));
                answer.append(temp.getContent());
            }
            log.info("result:{}", answer.toString());
            if (response.getHeader().getStatus() == 2) {
                wsCloseFlag = true;
                log.info("wsCloseFlag为:{}", wsCloseFlag + " result: " + answer);
                webSocket.close(1000, "Closing WebSocket connection");
                lock.notify();
            }
        }
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
        super.onFailure(webSocket, t, response);
        try {
            if (null != response) {
                int code = response.code();
                assert response.body() != null;
                log.error("onFailure body:{}", response.body().string());
                if (101 != code) {
                    log.error("讯飞星火大模型连接异常");
                }
            }
        } catch (IOException e) {
            log.error("IO异常:" + e);
        }
    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        super.onClosing(webSocket, code, reason);
        wsCloseFlag = false;
        answer = new StringBuilder();
    }
}

4. 编写LLM的service

LLMService提供两个方法,一个是sendMsg用于给LLM发送数据,getResult则是获取LLM的响应结果

@Service
@Slf4j
public class LlmServiceImpl implements LlmService {

    @Resource
    private XFLlmConfig xfLlmConfig;

    @Override
    public WebSocket sendMsg(String text, WebSocketListener webSocketListener) {
        String wsUrl = xfLlmConfig.getWsUrl();
        Request request = new Request.Builder().url(wsUrl).build();
        OkHttpClient client = new OkHttpClient.Builder().build();
        String body = buildBody(text);
        log.info("llm request body: {}", body);
        WebSocket webSocket = client.newWebSocket(request, webSocketListener);
        webSocket.send(body);
        return webSocket;
    }

    @SneakyThrows
    @Override
    public String getResult(XFWebSocketListener webSocketListener) {
        synchronized (webSocketListener.getLock()) {
            Long maxResponseTime = xfLlmConfig.getMaxResponseTime();
            long start = System.currentTimeMillis();
            if (!webSocketListener.isWsCloseFlag()) {
                log.info("Thread ID: {}, wsCloseFlag:{}, 线程等待", Thread.currentThread().getId(), webSocketListener.isWsCloseFlag());
                webSocketListener.getLock().wait(maxResponseTime);
            }
            long end = System.currentTimeMillis();
            log.info("Thread ID: {}, wsCloseFlag:{}, 等待时长:{} 线程被唤醒", Thread.currentThread().getId(), webSocketListener.isWsCloseFlag(), (end - start));
            if ((end - start) > maxResponseTime) {
                throw new RuntimeException("响应超时,请联系相关人员");
            }
            return webSocketListener.getAnswer();
        }
    }

    private String buildBody(String content) {
        XFLlmRequest request = new XFLlmRequest();
        XFLlmRequest.Header header = XFLlmRequest.Header.builder()
                .appId(xfLlmConfig.getAppId())
                .build();
        request.setHeader(header);

        XFLlmRequest.Chat chat = XFLlmRequest.Chat.builder()
                .domain(xfLlmConfig.getDomain())
                .build();
        XFLlmRequest.Parameter parameter = XFLlmRequest.Parameter.builder()
                .chat(chat)
                .build();
        request.setParameter(parameter);

        XFLlmRequest.Text text = XFLlmRequest.Text.builder()
                .content(content)
                .role(xfLlmConfig.getRole())
                .build();
        XFLlmRequest.Message message = XFLlmRequest.Message.builder()
                .text(Collections.singletonList(text))
                .build();
        XFLlmRequest.Payload payload = XFLlmRequest.Payload.builder()
                .message(message)
                .build();
        request.setPayload(payload);
        return JSON.toJSONString(request);
    }
}

5. 编写controller

用户发起请求的request封装

@Data
public class GenerateSqlRequest {

    /**
     * 端口号
     */
    private String port;

    /**
     * 主机
     */
    private String host;

    /**
     * 密码
     */
    private String password;

    /**
     * 用户名
     */
    private String userName;

    /**
     * 数据库名字
     */
    private String databaseName;

    /**
     * 表的名字
     */
    private String tableName;

    /**
     * 用户的问题
     */
    private String problem;
}
@RequestMapping("generate-sql")
@RestController
@RequiredArgsConstructor
public class GenerateSqlController {

    private final static String URL = "jdbc:mysql://%s:%s/%s";

    private final XFLlmConfig xfLlmConfig;

    private final LlmService llmService;

    @SneakyThrows
    @PostMapping
    public R generateSql(@RequestBody GenerateSqlRequest request) {
        String url = getUrl(request);
        String userName = request.getUserName();
        String password = request.getPassword();
        Class.forName("com.mysql.cj.jdbc.Driver");
        try (Connection conn = DriverManager.getConnection(url, userName, password)) {
            String tableName = request.getTableName();
            String query = "SHOW CREATE TABLE " + tableName;
            try (Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(query)) {
                if (rs.next()) {
                    String ddl = rs.getString(2);
                    String prompt = getPrompt(ddl, request);
                    XFWebSocketListener webSocketListener = new XFWebSocketListener();
                    llmService.sendMsg(prompt, webSocketListener);
                    String result = llmService.getResult(webSocketListener);
                    return R.success(result);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return R.fail();
    }

    public String getUrl(GenerateSqlRequest request) {
        return String.format(URL, request.getHost(), request.getPort(), request.getDatabaseName());
    }

    public String getPrompt(String ddl, GenerateSqlRequest request) {
        return String.format(xfLlmConfig.getPrompt(), ddl, request.getProblem());
    }

6. 运行测试

image-20240225174110107


六、总结

按照这样的一套流程,我们就把LLM接入到系统中,将我们的一个系统实现了智能化,让我们的系统有了自主思考的能力,这是一个不错的Demo。

对此,大家可以根据这种思想,将自己的项目改造,不再是简单的CRUD功能,这也是不错的亮点。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

产品经理应该具备的基本意识(3)团灭意识(字幕)

1 00:00:01,040 --> 00:00:02,440 下一个基本意识 2 00:00:02,450 --> 00:00:05,310 我们就要有一个团灭意识 3 00:00:06,320 --> 00:00:09,070 我们在软件方法第二章的时候也说过 4 00:00:09,080 --> 00:00:11,580 就是说&#xff0c;我们做需求的时候 5 00:0…

【Java程序设计】【C00307】基于Springboot的基Hadoop的物品租赁管理系统(有论文)

基于Springboot的基Hadoop的物品租赁管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的基于 Hadoop的物品租赁系统的设计与实现&#xff0c;本系统有管理员、用户二种角色权限&#xff1b; 前台首页&#…

输电线路微波覆冰监测装置助力电网应对新一轮寒潮

2月19日起&#xff0c;湖南迎来新一轮寒潮雨雪冰冻天气。为做好安全可靠的供电准备&#xff0c;国网国网湘潭供电公司迅速启动雨雪、覆冰预警应急响应&#xff0c;采取“人巡机巡可视化巡视”的方式&#xff0c;对输电线路实施三维立体巡检。该公司组织员工对1324套通道可视化装…

[力扣 Hot100]Day38 翻转二叉树

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 出处 思路 先序遍历&#xff0c;无脑翻转。 代码 class Solution { private:void invert(TreeNode* root){if(!root) return;TreeNode* p root->left;root->left …

自动化部署证书 acme.sh 使用教程

简介 acme.sh 是一个开源的 ACME 协议的客户端工具&#xff0c;用于自动化申请、更新和部署 SSL/TLS 证书。通过使用 acme.sh&#xff0c;用户可以轻松地在服务器上设置 HTTPS 加密连接&#xff0c;而无需手动操作。它支持多种 DNS 接口和证书颁发机构&#xff0c;可以与各种 …

逆向茶话会笔记

安卓逆向 用用burp设置代理或者用charles抓包 windows httpopen 类比web站点渗透测试 推荐书 飞虫 安卓大佬不怎么打ctf 喜欢在看雪和吾爱破解 提问环节 q websocket grpc抓包有什么推荐的工具&#xff1f; a 不太了解 游戏安全和llvm 既要逆游戏也要逆外挂 逆游戏入…

机器学习——线性代数中矩阵和向量的基本介绍

矩阵和向量的基本概念 矩阵的基本概念&#xff08;这里不多说&#xff0c;应该都知道&#xff09; 而向量就是一个特殊的矩阵&#xff0c;即向量只有一列&#xff0c;是个n*1的矩阵 注&#xff1a;一般矩阵用大写字母表示&#xff0c;向量用小写字母表示 矩阵的加减运算 两个…

SpringCloud-Docker原理解析

Spring Cloud和Docker的结合为微服务架构的部署和管理提供了强大的支持。本文深入剖析Spring Cloud与Docker的集成原理&#xff0c;从服务注册与发现、配置管理、负载均衡到容器化部署等方面展开详细解析。探讨Spring Cloud如何利用Docker容器技术实现服务的弹性伸缩&#xff0…

GitHub上的GCN

在GitHub上下载GCN代码&#xff0c;可以跑通 https://github.com/tkipf/pygcn

力扣用例题:2的幂

此题的解题方法在于根据用例调整代码 bool isPowerOfTwo(int n) {if(n1){return true;}if(n<0){return false;}while(n>2){if(n%21){return false;}nn/2; }if(n1){return false;}return true;}

Windows系统搭建Elasticsearch引擎结合内网穿透实现远程连接查询数据

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

SQL Server添加用户登录

我们可以模拟一下让这个数据库可以给其它人使用 1、在计算机中添加一个新用户TeacherWang 2、在Sql Server中添加该计算机用户的登录权限 exec sp_grantlogin LAPTOP-61GDB2Q7\TeacherWang -- 之后这个计算机用户也可以登录数据库了 3、添加数据库的登录用户和密码&#xff0…

Docker安装MS SQL Server并使用Navicat远程连接

MS SQL Server简介 Microsoft SQL Server&#xff08;简称SQL Server&#xff09;是由微软公司开发的关系数据库管理系统&#xff0c;它是一个功能强大、性能卓越的企业级数据库平台&#xff0c;用于存储和处理大型数据集、支持高效查询和分析等操作。SQL Server 支持广泛的应…

回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机…

MySQL认证方法介绍

阅读本文之前请参阅----MySQL 数据库安装教程详解&#xff08;linux系统和windows系统&#xff09; MySQL数据库的认证方法对于确保数据安全和维护系统完整性至关重要。在MySQL中&#xff0c;有多种认证方法可供选择&#xff0c;每种方法都有其特定的用途和配置方式。本文将详细…

10 款数据恢复软件功能和有效性对比(2024 年更新)

数据丢失可能是一种痛苦的经历&#xff0c;无论是由于意外删除、硬件故障还是软件损坏。值得庆幸的是&#xff0c;数字时代带来了强大的数据恢复解决方案。 随着我们进入 2024 年&#xff0c;市场上充斥着旨在有效检索丢失数据的先进软件。在本文中&#xff0c;我们将探讨 2024…

Sentinel 动态规则扩展

一、规则 Sentinel 的理念是开发者只需要关注资源的定义&#xff0c;当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则&#xff1a; 通过 API 直接修改 (loadRules)通过 DataSource 适配不同数据源修改 手动通过 API 修改比较直观&#xff0c;…

概率基础——均匀分布

概率基础——均匀分布 介绍 均匀分布是最简单的概率分布之一&#xff0c;它描述了一个随机变量在一定范围内的取值概率均等的情况。在均匀分布中&#xff0c;每一个数值区间的概率密度都相同&#xff0c;因此它也被称为等概率分布。 理论及公式 在区间 [ a , b ] [a, b] [a…

CSS 的盒模型

CSS 的盒模型 在HTML里&#xff0c;每一个元素就相当于是一个矩形的 “盒子” &#xff0c;这个盒子由以下这几个部分构成&#xff1a;1.边框border&#xff0c;2.内容content&#xff0c;3.内边距padding&#xff0c;4.外边距margin 边框border 基础属性描述border-width粗…

ARM Cortex-X5 传言表现不佳,高功率浪涌和低多核分数影响即将推出的核心设计

ARM 的新 Cortex-X5 设计似乎遇到了问题&#xff0c;有新的传言称&#xff0c;超级核心在提高时钟速度时会经历严重的高功耗&#xff0c;并且当最大功率限制降低时&#xff0c;多核性能会下降。虽然这对高通来说可能不是问题&#xff0c;因为据说其 Snapdragon 8 Gen 4 采用定制…