使用idea集成的springboot实现注册接口

news2024/11/15 18:39:07

跟黑马程序员学pringboot3+vue3,代码都是黑马程序员视频里的代码

实战篇-03_注册接口_哔哩哔哩_bilibili

本文仅仅用于学习记录

开发用户接口

注册接口

开发流程:明确需求>>阅读接口文档>>思路分析>>开发>>测试

分析:

这个图是截黑马ppt的图:

问题(今天在注册这个接口这里都搞不定!!!遇到很多问题!!!)

问题1:

因为有写依赖与springboot项目依赖版本号不兼容

快速的解决方法:

直接新建springboot项目,并且勾选这些需要用到的依赖,就是自动生成兼容的依赖,复制生成的pom.xml文件替换原来的pom.xml文件,修改一下pom的名字即可。

所以本菜鸟更喜欢一开始就建立springboot项目,哭了。。。。。。。

新建项目

创建实体类

首先先在启动类的包下创建以下几个包:(项目结构)

controller包

service包

(service包下再新建一个Impl包)

mapper包

pojo包

utils包

根据数据库表结构,在 pojo 包下创建 User.java 实体类

package com.example.demo.pojo;



import lombok.Data;

import java.time.LocalDateTime;

@Data
public class User {
    private Integer id;//主键ID
    private String username;//用户名
    private String password;//密码
    private String nickname;//昵称
    private String email;//邮箱
    private String userPic;//用户头像地址
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间
}

自动给实体类生成Geeter和Setter方法

  1. 在pom.xml中添加lombok依赖

2.在实体类中添加@Data

        

在application.yml文件配置配置数据库连接信息

废话来了:我们开发的是注册接口,需要往数据库里添加用户数据,所以一开始就把数据库连接信息配置好

路径:src/main/resources/application.properties

先把application.properties文件改造为application.yml 

(如何修改 ,这里有:配置文件application.properties-CSDN博客 中的yml部分)

配置数据库信息:

server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/big_event
    username: root
    password: 123456

查看接口文档,了解注册接口post请求长这样

http://localhost:8080/user/register?username=user1&password=123456

创建控制器

在 src/main/java/com/example/demo/controller 包下创建 UserController.java 控制器。

定义注册接口 /register 并实现注册逻辑

package com.example.demo.controller;


import com.example.demo.pojo.Result;
import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/*
@Resource注解用于自动注入依赖的 Bean。它是一个泛型注解,可以自动按类型注入,
也可以通过指定 name 属性来注入特定的 Bean。
*/

@Resource

/*@RestController注解用于将类标记为控制器,主要用来处理 HTTP 请求。
它相当于 @Controller 和 @ResponseBody 注解的组合,表示类中的方法返回的数据直接写入 HTTP 响应体中,而不是返回一个视图名称。
*/

@RestController

/*
@RequestMapping("/user")注解用于映射 HTTP 请求到控制器的处理方法。
这里指定了所有以 "/user" 开头的请求都会被这个控制器处理。
*/
@RequestMapping("/user")


public class UserController {

/*
@Autowired注解也是用于自动注入依赖的 Bean,
通常用于字段、构造函数、设置方法和普通方法参数。
它通过类型来自动注入 Bean,如果存在多个同类型的 Bean,
则需要通过 @Qualifier 注解指定具体的 Bean 名称
*/
    @Autowired
    private UserService userService;

/*
@PostMapping("/register")注解用于映射 HTTP POST 请求到特定的处理方法。
这里指定了当接收到 "/user/register" 的 POST 请求时,会调用 register 方法
*/
    @PostMapping("/register")
    public Result register(String username, String password){
        //查询用户名是否已存在
        User user =userService.findByUserName(username);
        if(user == null){
            userService.register(username,password);
            return Result.success();
        }else{
            //占用
            return Result.error("用户名已经被占用");
        }
    }



}

“不知道Bean注入的,看一下Bean部分的内容”

创建服务层接口和实现(实验查询用户是否存在和注册用户的业务逻辑)

在 src/main/java/com/example/demo/service 包下创建 UserService.java 接口

package com.example.demo.service;


import com.example.demo.pojo.User;

public interface UserService {
    // 根据用户名查询用户
     User findByUserName(String username) ;
//注册
     void register(String username, String password) ;
}

在 src/main/java/com/example/demo/service /Impl包下创建 UserServiceImpl.java 实现 UserService 接口

package com.example.demo.service.impl;


import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import com.example.demo.utils.Md5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/*
@Service注解用于标记服务层的组件,它指示 Spring 容器将这个类作为一个 Bean 进行管理。
通常用于业务逻辑层,但不限于此
*/
@Service
public class UserServiceImpl implements UserService {

/*
@Autowired注解用于自动注入依赖的 Bean。
在这个例子中,它被用来自动注入 UserMapper 类的实例,
这是数据访问层的一个组件
*/
    @Autowired
    private UserMapper usermapper;
    @Override
    public User findByUserName(String username){
       User user = usermapper.findByUserName(username);
       return user;
    }
    @Override
    public void register(String username, String password){
        //加密
       String md5String= Md5Util.getMD5String(password);
       //添加
        usermapper.add(username,md5String);

    }
}

创建 MyBatis Mapper 接口(与数据库交互,进行数据库操作就写在这里)

在 src/main/java/com/example/demo/mapper 包下创建 UserMapper.java 接口

package com.example.demo.mapper;

import com.example.demo.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserMapper {
    //根据用户名查询添加
    @Select("select * from user where username = #{username}")
    User findByUserName(String username) ;
    //添加用户
    @Insert("insert into user(username,password,create_time,update_time) values(#{username},#{password},now(),now())")
    void add(String username, String password);
}
/*
@Mapper这是 MyBatis 提供的一个注解,用于标记 Mapper 接口。
当 Spring 扫描到这个注解时,它会为这个接口创建一个代理对象,
这个代理对象会实现接口中定义的所有方法,并处理 SQL 映射。

@Select这是 MyBatis 的注解,用于标记执行查询操作的方法。
在这个例子中,@Select 用于定义一个 SQL 查询语句,该语句根据提供的用户名查询用户。

@Insert这是 MyBatis 的注解,用于标记执行插入操作的方法。
在这个例子中,@Insert 用于定义一个 SQL 插入语句,该语句将新用户的信息插入到数据库中。
*/

/*
@Select("select * from user where username = #{username}")
User findByUserName(String username) ;
当 Spring 容器中的 MyBatis 代理对象调用 findByUserName 方法时,
MyBatis 框架会执行以下步骤:
将方法的 username 参数替换 SQL 语句中的 #{username} 占位符。
执行生成的 SQL 查询。
将查询结果(如果有的话)映射到 User 类的实例上。
返回 User 对象给调用者。
*/

创建 MD5 工具类

数据库密码一般都不使用明文,要进行加密

在 src/main/java/com/example/demo/utils 包下创建 Md5Util.java 工具类,用于密码加密。

package com.example.demo.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Util {
    /**
     * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
     */
    protected static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    protected static MessageDigest messagedigest = null;

    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsaex) {
            System.err.println(Md5Util.class.getName() + "初始化失败,MessageDigest不支持MD5Util。");
            nsaex.printStackTrace();
        }
    }

    /**
     * 生成字符串的md5校验值
     *
     * @param s
     * @return
     */
    public static String getMD5String(String s) {
        return getMD5String(s.getBytes());
    }

    /**
     * 判断字符串的md5校验码是否与一个已知的md5码相匹配
     *
     * @param password  要校验的字符串
     * @param md5PwdStr 已知的md5校验码
     * @return
     */
    public static boolean checkPassword(String password, String md5PwdStr) {
        String s = getMD5String(password);
        return s.equals(md5PwdStr);
    }


    public static String getMD5String(byte[] bytes) {
        messagedigest.update(bytes);
        return bufferToHex(messagedigest.digest());
    }

    private static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }

    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>>
        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }

}

创建统一响应结果类

查看接口文档:得到响应的数据类型

在 src/main/java/com/example/demo/pojo 包下创建 Result.java 类,用于封装 HTTP 响应

package com.example.demo.pojo;


import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

//统一响应结果
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> {
    private Integer code;//业务状态码  0-成功  1-失败
    private String message;//提示信息
    private T data;//响应数据

    //快速返回操作成功响应结果(带响应数据)
    public static <E> Result<E> success(E data) {
        return new Result<>(0, "操作成功", data);
    }

    //快速返回操作成功响应结果
    public static Result success() {
        return new Result(0, "操作成功", null);
    }

    public static Result error(String message) {
        return new Result(1, message, null);
    }
}
/*
 @NoArgsConstructor是Lombok 库提供的注解,用于自动为类生成无参构造函数。
如果类中没有其他构造函数,使用这个注解可以避免手动编写无参构造函数。

@AllArgsConstructor是 Lombok 库提供的注解,用于自动为类生成包含所有字段作为参数的构造函数。
这在需要通过构造函数初始化所有属性时非常有用。

@Data是 Lombok 库提供的注解,用于自动为类生成 getters、setters、
equals()、hashCode() 和 toString() 方法。这可以显著减少样板代码。

*/
  • 当调用 success(E data) 方法时,会创建一个新的 Result 对象,其 code 设置为 0message 设置为 "操作成功"data 设置为传入的 data 参数。
  • 当调用 success() 方法时,会创建一个新的 Result 对象,其 code 和 message 与 success(E data) 方法相同,但 data 设置为 null
  • 当调用 error(String message) 方法时,会创建一个新的 Result 对象,其 code 设置为 1message 设置为传入的错误信息,data 设置为 null

Result<T> 是一个使用了泛型的Java类。让我们逐步解析一下:

Result: 这是一个类名,它被设计为一个容器或载体,用于封装从后端服务到前端或其他服务的数据传输结果。它通常包含了业务操作的状态、错误信息以及实际的数据。

<T>: 这是泛型的标记。T 是 Type 的缩写,它是一个占位符,代表任何类型的对象。当我们在定义 Result 类时,我们并不知道将来会存储哪种类型的数据,因此使用泛型 T 来表示可以存储任意类型的数据。

Result<T>: 当你看到 Result<T>,这意味着你可以创建一个 Result 类的对象,其中的 data 属性可以是任何类型的数据。例如,你可以有 Result<String>、Result<Integer> 或者 Result<List<User>> 等等。

实例化与使用:

如果你创建一个 Result<String> 对象,那么 T 就会被替换为 String 类型,意味着 data 属性将只能存储字符串。

如果你创建一个 Result<List<User>> 对象,T 将被替换为 List<User> 类型,意味着 data 属性将只能存储用户列表。

泛型的好处:

类型安全:编译器会在编译时检查类型,确保你不会把错误类型的对象放入 Result 中。

重用性:Result<T> 可以被用于多种类型的数据,提高了代码的灵活性和重用性。

所以,当你在代码中看到 Result<T>,它表示的是一个可以携带任意类型数据的结果对象。

在Java中,<E> Result<E> 是一个泛型方法的声明,它与泛型类的使用方式类似,但作用于方法级别。让我们详细解释一下这个声明:

<E>: 这个尖括号内的 E 定义了一个类型参数,它可以在方法内部作为类型占位符使用。E 通常代表“Element”或“Entity”,但它可以是任何合法的标识符。

Result<E>: 这是方法的返回类型,其中 <E> 表示返回的 Result 对象将具有一个名为 data 的字段,该字段的类型将由调用此方法时传入的实际类型决定。这里的 E 必须与前面的 <E> 相匹配,确保方法返回的 Result 对象的 data 字段类型与方法参数 data 的类型相同。

public static <E> Result<E> success(E data): 整体来看,这是一个静态泛型方法,它接收一个类型为 E 的参数 data,并返回一个类型为 Result<E> 的对象。这意味着无论你传递什么类型的参数给这个方法,返回的 Result 对象的 data 字段都将具有相同的类型。

例如,如果你这样调用该方法:

Result<String> result = Result.success("Hello, World!");

这里,E 被实例化为 String 类型,所以 result 将是一个 Result<String> 类型的对象,它的 data 字段将存储一个字符串 "Hello, World!"。

再比如

Result<Integer> result = Result.success(42);

这次,E 被实例化为 Integer 类型,所以 result 将是一个 Result<Integer> 类型的对象,它的 data 字段将存储整数 42。

通过使用泛型方法,你可以编写更加灵活且类型安全的代码,而无需为每种数据类型都编写一个专门的方法。

写在最后:搞了好久还遇到问题,难鼠了

出现HTTP 406 错误

原因:服务器无法满足请求者(客户端)所接受的响应内容类型。在这个情况下,客户端发送了一个 POST 请求到 /user/register 接口,期望接收 application/json 类型的数据,但是服务器没有正确处理这个请求,或者没有返回正确的 Content-Type

解决方法:在返回结果的实体类里添加@Data

最后的最后,成功了

使用 Lombok 的 @Data 注解可以自动生成必要的 getter 和 setter 方法,从而解决因缺少访问器方法而导致的 JSON 序列化问题。

为什么使用 @Data 注解可以解决问题?

  1. 对象序列化:在 Spring Boot 应用中,返回的对象通常需要被序列化为 JSON 格式。这通常是通过 Spring Boot 默认的 HttpMessageConverter 实现的,比如 MappingJackson2HttpMessageConverter

  2. Lombok 注解:Lombok 是一个 Java 库,它通过注解处理器在编译时自动生成常见的 Java 代码,如 getter、setter、构造函数、toString 方法等。@Data 注解是 Lombok 提供的一个强大注解,它等价于同时使用 @Getter@Setter@ToString@EqualsAndHashCode@RequiredArgsConstructor

  3. 自动生成访问器:当你在一个类上使用 @Data 注解时,Lombok 会自动为该类的所有字段生成 getter 和 setter 方法。这对于 JSON 序列化非常重要,因为 JSON 库(如 Jackson)需要通过这些访问器方法来访问对象的属性。

  4. 解决序列化问题:如果没有 getter 方法,JSON 序列化库可能无法访问对象的属性,从而导致序列化失败。这可能间接导致 Spring 返回 406 错误,因为客户端期望的是 JSON 响应,但服务器没有正确生成。

  5. 简化代码:使用 Lombok 可以大大减少样板代码,使开发者能够专注于业务逻辑。

参数校验

上面的代码并没有进行参数校验

一般使用Spring Validation

Spring Validation是Spring提供的一个参数校验框架,使用预定义的注解完成参数校验

1.引入Spring Validation起步依赖

记得刷新!!!

2.在需要校验的参数前面添加@Pattern注解

5~16位非空字符用正则表达式为 \S{5,16},由于"\"是转义字符,在前面再加一个\,如图:

3.在类上加上@Validated注解

不符合参数要求的请求失败了,但是返回结果格式不符合要求

解决方法:可以使用全局异常处理器处理参数校验的异常

在启动类下新建一个exception包,定义一个类GlobalExceptionHandler

 

这个处理器使用@RestControllerAdvice注解来声明它将作为全局的异常处理控制器,并且@ExceptionHandler(Exception.class)注解表明它将处理所有类型的Exception

handleException方法中,首先调用e.printStackTrace()来打印堆栈跟踪信息,这有助于开发过程中定位问题。然后,使用StringUtil.notNullNorEmpty方法检查异常消息是否为空或非空,如果非空则直接返回异常消息,否则返回默认的错误信息“操作失败”。最后,返回一个Result对象,用于封装响应体和状态码

 

结果:

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

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

相关文章

使用SDL库以及C++实现的简单的贪吃蛇:AI Fitten生成

简单使用AI代码生成器做了一个贪吃蛇游戏 设计的基本逻辑都是正确的&#xff0c;能流畅运行 免费准确率高&#xff0c;非常不错&#xff01;支持Visual Studio系列 Fitten&#xff1a;https://codewebchat.fittenlab.cn/ SDL 入门指南&#xff1a;安装配置https://blog.csdn.n…

高效数据抓取:Scrapy框架详解

一、Scrapy框架简介 Scrapy是一个为了爬取网站数据、提取结构性数据而编写的爬虫框架。它支持异步处理&#xff0c;能够快速抓取大量网页&#xff0c;并且易于扩展。Scrapy使用Twisted这个事件驱动的网络引擎&#xff0c;可以处理大量的并发请求&#xff0c;从而提高数据抓取的…

C语言分支结构作业

作业 输入你的身高和体重&#xff0c;测试你的健康状况。 计算bmi的值&#xff0c; bmi &#xff08;体重/身高的平方) 如果bmi 小于18.5&#xff0c;则显示“偏瘦&#xff0c;注意加强营养” 如果bmi 在18.5和23.9之间&#xff0c;则显示“体重指数良好&#xff0c;注意保持…

【全栈实战】大模型自学:从入门到实战打怪升级,20W字总结(二)

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本栏讲解【全栈实战】大模型自学&#xff1a;从入门到实战打怪升级。 &#x1f514;专栏持续更新&#xff0c;适合人群&#xff1a;本科生、研究生、大模型爱好者&#xff0c;期…

基于单片机的电梯控制系统的设计

摘 要: 本文提出了一种基于单片机的电梯控制系统设计 。 设计以单片机为核心&#xff0c;通过使用和设计新型先进的硬件和控制程序来模拟和控制整个电梯的运行&#xff0c;在使用过程中具有成本低廉、 维护方便、 运行稳定 、 易于操作 、 安全系数高等优点 。 主要设计思路是…

聚焦全局应用可用性的提升策略,详解GLSB是什么

伴随互联网的快速发展和全球化趋势的深入&#xff0c;企业对网络应用的需求日渐增长。为满足全球范围内用户大量的访问需求&#xff0c;同时解决容灾、用户就近访问以及全球应用交付等问题&#xff0c;GLSB&#xff08;全局负载均衡&#xff09;也因此应运而生。那么GLSB是什么…

Axure RP:打造动态交互的大屏可视化设计利器

Axure大屏可视化是指使用Axure RP这款原型设计工具来创建具有视觉冲击力和数据展示功能的大屏幕界面。Axure以其强大的交互设计和丰富的组件库&#xff0c;成为了实现大屏可视化的重要工具之一。以下是对Axure大屏可视化的详细阐述&#xff1a; 一、Axure在大屏可视化中的优势 …

​易能医药董事长易跃能博士荣获“湖湘药学领航奖”

近日&#xff0c;湖南省药学会主办的“湖南省药学会70周年庆典暨第六届湖南药学大会”在湖南长沙隆重召开。易能医药董事长易跃能博士荣获由湖南省药学会颁发的“湖湘药学领航奖”。此次“湖湘药学领航奖”由湖南药学大会学术委员会组织评选&#xff0c;湖南省全省仅有八个名额…

六、3 PWM 舵机代码

目录 1、通道选择 2、参数计算 3、代码部分 1、通道选择 PA1对应通道2 注意&#xff1a;同一个定时器不同通道输出PWM的特点 同一个定时器的不同通道输出的PWM&#xff0c;频率相同&#xff08;因为它们共用一个计数器&#xff09;&#xff0c;占空比可以各自设定&#xff…

Kubernetes 学习记录

https://note.youdao.com/ynoteshare/index.html?idbc7bee305611b52d6900ba209a92bd4d&typenote&_time1694072007342 概览 K8S官网文档&#xff1a;https://kubernetes.io/zh/docs/home/ K8S 是Kubernetes的全称&#xff0c;源于希腊语&#xff0c;意为“舵手”或“…

ITSS:IT服务工程师

证书亮点&#xff1a;适中的费用、较低的难度、广泛的应用范围以及专业的运维认证。 总体评价&#xff1a;性价比良好&#xff01; 证书名称&#xff1a;ITSS服务工程师 证书有效期&#xff1a;持续3年 培训要求&#xff1a;必须参加培训&#xff0c;否则将无法参与考试 发…

Aboboo一些操作

常用快捷键⌨ 快捷键/操作方式 功能 鼠标中键/Esc 进入/退出全屏 空格/Tab 暂停/恢复播放 左/右箭头 快退/快进 Ctrl-左/右箭头 30秒快退/快进 Alt-左/右箭头 60秒快退/快进 Ctrl-Alt-左/右箭头 播放速率调节 PageUp/PageDown 上一句/下一句 上下箭头/滚轮 …

WSL配置镜像网络使用本地端口调试Linux程序

一、安装WSL 二、配置WSL为镜像 在C:\Users\XXUser目录下添加.wslconfig文件 [wsl2] networkingModemirrored # 开启镜像网络 dnsTunnelingtrue # 开启 DNS Tunneling firewalltrue # 开启 Windows 防火墙 autoProxytrue # 开启自动同步代理重启WSL wsl --shutdown wsl三、…

计算机毕业设计选题推荐-音乐播放系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

计算机网络04

文章目录 IP 基本认识**IP 地址的基础知识****IP 地址的分类**无分类地址 CIDR公有 IP 地址与私有 IP 地址IP 地址与路由控制IP 分片与重组IPv6 基本认识IPv4 首部与 IPv6 首部 IP 协议相关技术DNS 域名解析ARP 与 RARP 协议DHCP 动态获取 IP 地址NAT 网络地址转换ICMP 互联网控…

NACOS保姆笔记(5)——Nacos的集群教程

前面我们介绍过: NACOS保姆笔记(1)——NACOS的安装和启动NACOS保姆笔记(2)——Spring Cloud Alibaba Nacos服务注册与发现以及负载均衡NACOS保姆笔记(3)——Spring Cloud Alibaba Nacos配置中心NACOS保姆笔记(4)——Spring Cloud Alibaba Nacos鉴权本篇主要介绍下Na…

5种IO模型简述

文章目录 前言什么是IO模型&#xff1f;阻塞IO非阻塞IO多路复用IO信号驱动IO异步IO 结语 前言 最近学netty&#xff0c;当然无法避免IO模型这部分知识。 我尽量用最简洁的语言来讲清楚这个东西。 什么是IO模型&#xff1f; 既然最近学netty&#xff0c;就拿它来举例子。 比如…

ITPUB专访 | 张宏波:一场关于编程语言速度与效率的深度对话

ITPUB专访 | 张宏波&#xff1a;一场关于编程语言速度与效率的深度对 随着 AI 大语言模型&#xff08;LLM&#xff09;不断突破和开源社区活跃程度达到前所未有的高度&#xff0c;以 OpenAI 的 GPT-4、Meta-LLaMA 等为代表的重量级产品和服务相继发布&#xff0c;AI 技术的蓬勃…

视频VIP收费会员播放帝国CMS模板HTML5自适应手机多种运营模式

采用帝国CMS最新版核心制作&#xff0c;自适应响应式手机平板浏览&#xff0c;手机浏览器非常舒服哦&#xff01;多种运营模式。用户中心逻辑和页面&#xff0c;都已经制作完整&#xff0c;可以搭建后稍微修改即可使用&#xff01; 模板特点&#xff1a; 支持多集和单集播放&…

【2024】Datawhale AI夏令营 Task2笔记——Baseline代码详细解读

【2024】Datawhale AI夏令营 Task2笔记——Baseline代码详细解读 本文对可完成赛事“逻辑推理赛道&#xff1a;复杂推理能力评估”初赛的baseline代码进行详细解读&#xff0c;该baseline代码由Datawhale AI夏令营提供&#xff0c;核心内容是调用灵积模型服务平台的大语言模型…