百度智能云+SpringBoot=AI对话【人工智能】

百度智能云+SpringBoot=AI对话【人工智能】

  • 前言
  • 版权
  • 推荐
  • 百度智能云+SpringBoot=AI对话【人工智能】
    • 效果演示
      • 登录
      • AI对话
    • 项目结构
    • 后端开发
      • pom和properties
      • sql_table和entity
      • dao和mapper
      • service和impl
      • config和util
      • LoginController和ChatController
    • 前端开发
      • css和js
      • login.html和chat.html
    • 后言
  • 最后

前言

2024-3-20 19:41:47

使用百度千帆平台的大模型,完成一个简单的AI对话聊天

以下内容源自《【人工智能】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话

推荐

Gitee项目地址: 日星月云 / AI对话

GitHub项目地址:jsss-1/qianfan

百度千帆模型初次体验【人工智能】

百度智能云+SpringBoot=AI对话【人工智能】

通过上篇,我们成功地完成了初次对大模型的使用
本篇,我将带大家开发一个AI对话聊天框

效果演示

登录

输入用户名,点击登录
返回“登录成功”
在这里插入图片描述
查询状态
在这里插入图片描述

AI对话

页面
在这里插入图片描述

输入内容,点击回车即可提问

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

项目结构

在这里插入图片描述

后端开发

pom和properties

pom.xml

SpringBoot2.4.2+JDK8

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>qianfan</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>qianfan</name>
    <description>qianfan</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--        千帆大模型平台-->
        <dependency>
            <groupId>com.baidubce</groupId>
            <artifactId>qianfan</artifactId>
            <version>0.0.1</version>
        </dependency>

        <!--        thymeleaf 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--        lombok 依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--        mysql 依赖-->

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--        mybatis 依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties

spring.application.name=qianfan

# Qianfan
QIANFAN_ACCESS_KEY=你的AK
QIANFAN_SECRET_KEY=你的SK

# ServerProperties
server.port=8080
server.servlet.context-path=

# ThymeleafProperties
spring.thymeleaf.cache=false

# mysql
spring.datasource.url=jdbc:mysql://localhost:3306/ai?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.jsss.entity
# 生成主键
mybatis.configuration.useGeneratedKeys=true
# 驼峰命名
mybatis.configuration.mapUnderscoreToCamelCase=true

sql_table和entity

ai.sql

create table conversation
(
    id           int auto_increment
        primary key,
    username     varchar(16) null,
    user_message text        null,
    bot_message  text        null,
    create_time  varchar(32) null
);

**enntity.Conversation **

package com.jsss.qianfan.entity;



import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Conversation {

    private Integer id;

    private String username;

    private String userMessage;

    private String botMessage;

    private String createTime;

}

dao和mapper

**dao.ChatMapper **

package com.jsss.qianfan.dao;

import com.jsss.qianfan.entity.Conversation;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface ChatMapper {

    List<Conversation> getByUsername(String username);

    void insert(Conversation conversation);


}

**mapper/ChatMapper.xml **

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.jsss.qianfan.dao.ChatMapper">

    <!-- 定义SQL映射关系 -->


    <!-- 根据username查询conversation记录 -->
    <select id="getByUsername" resultType="com.jsss.qianfan.entity.Conversation" parameterType="string">
        SELECT * FROM conversation WHERE username = #{username}
    </select>



    <!-- 插入新的conversation记录 -->
    <insert id="insert" parameterType="com.jsss.qianfan.entity.Conversation">
        INSERT INTO conversation     (
            username, user_message, bot_message, create_time
        ) VALUES (
                     #{username},
                     #{userMessage},
                     #{botMessage},
                     #{createTime}
                 )
    </insert>




</mapper>




service和impl

service.ChatService

package com.jsss.qianfan.service;

import com.jsss.qianfan.entity.Conversation;

import java.util.List;

public interface ChatService {

    void addChat(Conversation conversation);

    List<Conversation> searchByUsername(String username);

}

impl.ChatServiceImpl

package com.jsss.qianfan.service.impl;

import com.jsss.qianfan.dao.ChatMapper;
import com.jsss.qianfan.entity.Conversation;
import com.jsss.qianfan.service.ChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    ChatMapper chatMapper;

    @Override
    public void addChat(Conversation conversation) {
        chatMapper.insert(conversation);
    }

    @Override
    public List<Conversation> searchByUsername(String username) {
        return chatMapper.getByUsername(username);
    }
}

config和util

configuration.QianfanConfig

package com.jsss.qianfan.configuration;


import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.core.auth.Auth;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QianfanConfig {

    @Value("${QIANFAN_ACCESS_KEY}")
    String ak;

    @Value("${QIANFAN_SECRET_KEY}")
    String sk;

    @Bean
    public Qianfan qianFan() {
        return new Qianfan(Auth.TYPE_OAUTH, ak, sk);
    }
}

util.QianfanUtil

package com.jsss.qianfan.util;

import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.model.chat.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class QianfanUtil {

    @Autowired
    Qianfan qianfan;

    public String addMessage(String content) {

        ChatResponse response = qianfan.chatCompletion()
                //.model("ERNIE-Bot-4")  //使用model指定预置模型 默认模型是ERNIE-Bot-turbo
                .addMessage("user", content) // 添加用户消息 (此方法可以调用多次,以实现多轮对话的消息传递)
                .temperature(0.7) // 自定义超参数
                .execute(); // 发起请求


        return response.getResult();

    }
    public void executeStream(String content) {

        qianfan.chatCompletion()
                .addMessage("user", content)
                .executeStream() // 发起流式请求
                .forEachRemaining(chunk -> System.out.print(chunk.getResult())); // 流式迭代,并打印消息


    }



}

LoginController和ChatController

controller.LoginController

package com.jsss.qianfan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class LoginController {

    @GetMapping("/login")
    public String login(){
        return "login";
    }

    @PostMapping("/login")
    @ResponseBody
    public String login(HttpServletRequest request,String username){
        HttpSession session = request.getSession();
        session.setAttribute("username",username);
        return "登录成功";
    }

    @GetMapping("/logout")
    @ResponseBody
    public String logout(HttpServletRequest request,String username){
        HttpSession session = request.getSession();
        session.removeAttribute("username");
        return "登出成功";
    }


    @GetMapping("/status")
    @ResponseBody
    public String status(HttpServletRequest request){
        HttpSession session = request.getSession();
        String username =(String)session.getAttribute("username");
        if (username!=null&&!username.isEmpty()){
            return username;
        }else {
            return "没有登录";
        }
    }
}

controller.ChatController

package com.jsss.qianfan.controller;

import com.jsss.qianfan.entity.Conversation;
import com.jsss.qianfan.service.ChatService;
import com.jsss.qianfan.util.QianfanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Controller
@RequestMapping("chat")
public class ChatController {




//    List<Conversation> conversations=new ArrayList<>();
//
//    static int id=1;
//
//    {
//        conversations.add(new Conversation(id++,"1","你好","抱歉,网络出现异常,请你重试或联系客服!TooManyRequests", format(new Date())));
//        conversations.add(new Conversation(id++,"1","你好","抱歉,网络出现异常,请你重试或联系客服!TooManyRequests", format(new Date())));
//    }

    @Autowired
    QianfanUtil qianfanUtil;

    @Autowired
    ChatService chatService;

    private String format(Date date){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }



    @GetMapping("/list")
    public String getChat(HttpServletRequest request,Model model){
        String username= (String) request.getSession().getAttribute("username");
        List<Conversation> conversations=chatService.searchByUsername(username);
        model.addAttribute("conversations",conversations);
        return "chat";
    }



    @PostMapping("/chat")
    public String chat(HttpServletRequest httpServletRequest,@RequestBody Map<String, String> request){
        String username= (String) httpServletRequest.getSession().getAttribute("username");

        String content = request.get("content");

        System.out.println(content);

//        String res="回复";
//        Conversation conversation = new Conversation(id++,username, content, res, format(new Date());
//        conversations.add(conversation);

         String res = qianfanUtil.addMessage(content);
        Conversation conversation = new Conversation(null, username, content, res, format(new Date()));
        chatService.addChat(conversation);

        return "redirect:list";
    }


}

前端开发

css和js

css/style.css


/* 设置用户发送消息的样式 */
.user-message {
    background-color: #4CAF50; /* 绿色背景 */
    color: white;
    padding: 10px;
    margin: 10px;
    border-radius: 10px;
    white-space: pre;
}

/* 设置ChatGPT发送消息的样式 */
.bot-message {
    background-color: #f2f2f2; /* 灰色背景 */
    padding: 10px;
    margin: 10px;
    border-radius: 10px;
    white-space: pre;
}

.question-container {
    display: flex;
    justify-content: flex-end;
}

.question {
    display: flex;
    flex-direction: row;
    align-items: center;
}

.question td:first-child {
    margin-left: auto;
}

.answer-container {
    display: flex;
    justify-content: flex-start;
}

.answer {
    display: flex;
    flex-direction: row;
    align-items: center;
}

.answer td:last-child {
    margin-left: auto;
}

/* 设置提问和回复消息的表格样式 */
.question, .answer {
    display: flex;
    align-items: center;
    padding: 10px;
    border-radius: 10px;
}

/* 设置输入框和发送按钮的样式 */
.form-container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: fixed;
    bottom: 0;
    width: 100%;
    padding: 10px;
    background-color: #f9f9f9;
    border-top: 1px solid #ccc;
}

.form-row {
    display: flex;
    flex: 1;
}

.form-group {
    flex: 1;
    margin-right: 10px;
}

.form-group input {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    outline: none;
}


.message-container {
    max-height: 700px; /* 设置最大高度,超出部分可滚动 */
    overflow-y: auto; /* 竖直方向溢出部分可滚动 */
}

.send-message-container {
    flex: 1; /* 占据剩余空间 */
    display: flex;
    align-items: center;
    background-color: #f5f5f5;
}

textarea {
    width: 1800px; /* 设置输入框的宽度为300像素,您可以根据需要调整这个值 */
    height: 100px; /* 设置输入框的高度为200像素,您可以根据需要调整这个值 */
    font-size: 16px; /* 设置输入框中文字的字体大小为16像素,您可以根据需要调整这个值 */
    resize: none; /* 禁止用户调整输入框的尺寸 */
}



js/onload.js

window.onload = function() {
    // 找到消息容器
    var messageContainer = document.querySelector(".message-container");

    // 找到消息容器中最后一个子元素
    var lastMessage = messageContainer.lastElementChild;

    // 将最后一个子元素滚动到可见区域
    lastMessage.scrollIntoView();
};

js/textarea.js

var textarea = document.getElementById("messageInput");

textarea.addEventListener("keydown", function(event) {
    if (event.key === "Enter" && !event.shiftKey) {
        event.preventDefault();

        var message = textarea.value.trim();
        textarea.value = "";

        // 发送 POST 请求
        fetch('/chat/chat', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ content: message })
        }).then(function(response) {
            // 刷新页面
            location.reload();
        });
    }
});

textarea.addEventListener("keydown", function(event) {
    if (event.key === "Enter" && event.shiftKey) {
        // 在 Shift+Enter 情况下允许换行
        textarea.value += "\n";
        event.preventDefault();
    }
});

login.html和chat.html

html/login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
	<head>
		<title>AI对话</title>
	</head>

	<body>
		<div class="chat-container">
			<h1 class="title">登录</h1>

			<div class="login-container">
				<form th:action="@{/login}" method="post">
					<div class="form-container">
						<div class="form-row">
                             <span class="form-group no-border">
                                <input id="username" name="username" placeholder="输入用户名">
                             </span>
							<button>登录</button>
						</div>
					</div>
				</form>
			</div>


		</div>
	</body>


</html>

html/chat.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
	<head>
		<link rel="stylesheet" th:href="@{/css/style.css}">
		<title>AI对话</title>
	</head>

	<body>
		<div class="chat-container">
			<h1 class="title">AI 对话</h1>

			<div class="message-container">
				<!-- 用户消息和ChatGPT消息显示部分 -->
				<div th:each="conversation:${conversations}">

					<div class="question-container">
						<table class="question">
							<td>
								<span th:utext="${conversation.createTime}"></span>
								<div class="user-message" th:utext="${conversation.userMessage}"></div>
							</td>
							<td type="text" th:text="${conversation.username}">提问</td>
						</table>
					</div>

					<div class="answer-container">
						<table class="answer">
							<td type="text">AI</td>
							<td>
								<span th:utext="${conversation.createTime}"></span>
								<div class="bot-message" th:utext="${conversation.botMessage}"></div>
							</td>
						</table>
					</div>
				</div>
			</div>


			<div class="send-message-container">
				<!-- 发送消息部分 -->
				<form th:action="@{/chat/chat}" method="post">
					<div class="form-container">
						<div class="form-row">
                             <span class="form-group no-border">
                                <textarea id="messageInput" placeholder="问我任何问题...(Shift + Enter 换行,按下Enter 发送)"></textarea>
                             </span>
						</div>
					</div>
				</form>
			</div>


		</div>
	</body>


	<script th:src="@{/js/onload.js}"></script>

	<script th:src="@{/js/textarea.js}"></script>

</html>

后言

待完善的功能:

  1. 用户对话之后,需要等待回复,才能弹出对话内容

  2. 等待期间,还能输入聊天框

  3. 并且,没有终止生成

  4. 没有左边框-新建对话

  5. 没有md格式的复制

最后

2024-3-20 21:06:39

迎着日光月光星光,直面风霜雨霜雪霜。

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

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

相关文章

Java newInstance方法学习

用newInstance与用new是有区别的&#xff0c;区别在于创建对象的方式不一样&#xff0c;前者是使用类加载机制&#xff1b; newInstance方法要求该 Class 对应类有无参构造方法&#xff1b; 执行 newInstance()方法实际上就是使用对应类的无参构造方法来创建该类的实例&#x…

【prometheus-operator】k8s监控集群外redis

1、部署exporter GitHub - oliver006/redis_exporter: Prometheus Exporter for Redis Metrics. Supports Redis 2.x, 3.x, 4.x, 5.x, 6.x, and 7.x redis_exporter-v1.57.0.linux-386.tar.gz # 解压 tar -zxvf redis_exporter-v1.57.0.linux-386.tar.gz # 启动 nohup ./redi…

流畅的 Python 第二版(GPT 重译)(三)

第五章&#xff1a;数据类构建器 数据类就像孩子一样。它们作为一个起点是可以的&#xff0c;但要作为一个成熟的对象参与&#xff0c;它们需要承担一些责任。 马丁福勒和肯特贝克 Python 提供了几种构建简单类的方法&#xff0c;这些类只是一组字段&#xff0c;几乎没有额外功…

软件管理rpm与yum

源代码包下载 Compare, Download & Develop Open Source & Business Software - SourceForgehttps://sourceforge.net/ rpm包下载 Welcome to the RPM repository on fr2.rpmfind.nethttp://rpmfind.net/linux/RPM/ 软件包管理 1.rpm包管理: 1)查询: 安装…

蓝桥杯Python B组练习——完美的代价

一、题目 问题描述   回文串&#xff0c;是一种特殊的字符串&#xff0c;它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串&#xff0c;它不一定是回文的&#xff0c;请你计算最少的交换次数使得该串变成一个完美的回文串。   交换的定义是…

计算机网络相关

OSI七层模型 各层功能&#xff1a; TCP/IP四层模型 应用层 传输层 网络层 网络接口层 访问一个URL的全过程 在浏览器中输入指定网页的 URL。 浏览器通过 DNS 协议&#xff0c;获取域名对应的 IP 地址。 浏览器根据 IP 地址和端口号&#xff0c;向目标服务器发起一个 TCP…

电影aac是什么意思?如何播放、转换、编辑aac?

"电影AAC"这个术语可能是指电影中的音频编码格式。AAC&#xff08;Advanced Audio Coding&#xff09;是一种常见的音频编码格式&#xff0c;通常用于压缩音频文件&#xff0c;以在保持高质量的同时减小文件大小。在电影中&#xff0c;AAC格式的音频通常用于提供高质…

webpack5零基础入门-13生产模式

1.生产模式介绍 生产模式是开发完成代码后&#xff0c;我们需要得到代码将来部署上线。 这个模式下我们主要对代码进行优化&#xff0c;让其运行性能更好。 优化主要从两个角度出发: 优化代码运行性能优化代码打包速度 2.生产模式准备 我们分别准备两个配置文件来放不同的…

【RAG实践】基于 LlamaIndex 和Qwen1.5搭建基于本地知识库的问答机器人

什么是RAG LLM会产生误导性的 “幻觉”&#xff0c;依赖的信息可能过时&#xff0c;处理特定知识时效率不高&#xff0c;缺乏专业领域的深度洞察&#xff0c;同时在推理能力上也有所欠缺。 正是在这样的背景下&#xff0c;检索增强生成技术&#xff08;Retrieval-Augmented G…

PC 端 LVGL 模拟器之 Visual Studio

LVGL&#xff08;Light and Versatile Graphics Library&#xff09;是一个轻量化的、开源的、在嵌入式系统中广泛使用的图形库&#xff0c;它提供了一套丰富的控件和组件&#xff0c;只需要少量的内存和计算资源&#xff0c;使得在资源受限的设备上创建高端的图形界面成为可能…

pycorrector检测OCR错字实践

参考&#xff1a;https://github.com/shibing624/pycorrector/tree/master/examples/macbert stopwords.txt 添加专业停用词&#xff0c;避免错误 设置自定义词典&#xff0c;避免将正确的词错误检测成错误的词 from pycorrector import Corrector m Corrector() m.set_cus…

Mysql——基础命令集合

目录 前期准备 先登录数据库 一、管理数据库 1.数据表结构解析 2.常用数据类型 3.适用所有类型的修饰符 4.使用数值型的修饰符 二、SQL语句 1.SQL语言分类 三、Mysql——Create,Show,Describe,Drop 1.创建数据库 2.查看数据库 3.切换数据库 4.创建数据表 5.查看…

ELK快速搭建图文详细步骤

目录 一、下载地址二、安装docker-compose(已安装则跳过)三、初始化ELK1. 赋予/setup/entrypoint.sh执行权限2. 初始化 docker-elk 所需的 Elasticsearch 用户和组3. 重置默认用户的密码4. 替换配置文件中的用户名和密码5. 重启 Logstash 和 Kibana&#xff0c;使用新密码重新连…

改进粒子群优化算法||粒子群算法变体||Improved particle swarm optimization algorithm

粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种基于群体智能的优化算法&#xff0c;其思想来源于鸟群寻食和鱼群捕食等自然现象。PSO算法通过模拟群体智能的行为&#xff0c;以一种启发式的方式寻找最优解&#xff0c;因此具有全局搜索能…

【FAQ】BSV区块链代码库常见问题解答

​​发表时间&#xff1a;2024年2月27日 BSV区块链协会上线了JavaScript和TypeScript SDK&#xff08;即“标准开发工具包”&#xff09;。TypeScript SDK旨在为开发者提供新版统一核心代码库&#xff0c;让开发者可以在BSV区块链上便捷地进行开发&#xff0c;尤其是开发那些可…

C语言中的联合和枚举(未完)

1、联合体 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫&#xff1a;共⽤体。因为所有变量公用…

echart多折线图堆叠 y轴和实际数据不对应

当使用 ECharts 绘制堆叠折线图时&#xff0c;有时会遇到 y 轴与实际数据不对应的问题。 比如明明值是50&#xff0c;但折线点在y轴的对应点却飙升到了二百多 解决办法&#xff1a; 查看了前端代码发现在echart的图表中有一个‘stack’的属性&#xff0c;尝试把他删除之后y轴的…

流畅的 Python 第二版(GPT 重译)(八)

第十五章&#xff1a;关于类型提示的更多内容 我学到了一个痛苦的教训&#xff0c;对于小程序来说&#xff0c;动态类型很棒。对于大型程序&#xff0c;你需要更加纪律严明的方法。如果语言给予你这种纪律&#xff0c;而不是告诉你“嗯&#xff0c;你可以做任何你想做的事情”&…

航顺车规级SoC全新亮相,助推汽车智能化发展

受益于汽车电动化、智能化和网联化的推进&#xff0c;汽车车身域和座舱域MCU市场规模持续扩大。据统计&#xff0c;2021年中国车载芯片MCU市场规模达30.01亿美元&#xff0c;同比增长13.59%&#xff0c;预计2025年市场规模将达42.74亿美元。 在技术要求方面&#xff0c;对…

DXP学习1-使用DXP软件创建工程并熟悉相关操作

目录 实验内容&#xff08;任务&#xff09; PCB项目文件及原理图文件的创建及保存&#xff1a; 熟悉窗口界面、主菜单、各工具栏及图纸参数的设置&#xff1a; 首先先通过"纸张选择"做如下修改 修改纸张大小&#x1f447; 修改标题栏的格式&#x1f447; 修改…