项目初始化脚手架搭建

项目初始化脚手架搭建

仓库地址

easy-web: 一个快速初始化SpringBoot项目的脚手架 (gitee.com)

目前这个项目还是个单体项目,后续笔者有时间可能会改造成父子工程项目,将通用模块抽象出来,有兴趣的小伙伴也可以自行 CV 改造。

1、项目初始化

1.1 创建一个 Spring Boot 新项目

image-20230617153047260

1.2 选择项目版本和依赖

image-20230617152358958

1.3 该配置文件为 .yml 格式

image

2、数据库表设计

用户表(注:以下字符集是 MySQL 8 版本的)

CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',`user_account` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '登录账号',`user_password` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码',`user_name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '用户昵称',`user_avatar` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '用户头像',`gender` tinyint DEFAULT '0' COMMENT '性别:0 - 未知;1 - 男;2 -女',`phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '手机号码',`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '邮箱',`user_role` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'user' COMMENT '用户角色:user - 普通用户;admin - 管理员',`user_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '用户状态:0 - 正常;1 - 禁用',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`is_delete` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除:0 - 未删;1 - 已删',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `uni_userAccount` (`user_account`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='用户表';

3、Mybatis X 插件自动生成代码

1.1

image

1.2

image

1.3

取消勾选 toString

image

1.4 生成的结果

image

将需要的代码拖进对应的软件包即可,导入 mybatis-plus 依赖

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>

选项解释

image-20230423133832870

image-20230423133856231

4、定义统一错误码

这是一个枚举类,用于定义系统中可能出现的错误码和对应的错误信息。

枚举值必须是私有且不可变

可以参考下阿里巴巴 Java 开发手册:

https://github.com/alibaba/p3c

public enum ErrorCode {SUCCESS(0, "ok"),PARAMS_ERROR(40000, "请求参数错误"),NOT_LOGIN_ERROR(40100, "未登录"),NO_AUTH_ERROR(40101, "无权限"),NOT_FOUND_ERROR(40400, "请求的数据不存在"),FORBIDDEN_EEOR(40300, "禁止访问"),SYSTEM_ERROR(50000, "系统内部异常"),OPERTATION_ERROR(50001, "操作失败");/*** 状态码*/private final int code;/*** 信息*/private final String message;ErrorCode(int code, String message) {this.code = code;this.message = message;}/*** 获取错误状态码** @return int*/public int getCode() {return code;}/*** 获取错误响应信息** @return {@code String}*/public String getMessage() {return message;}}

5、创建通用返回类

@Data
public class BaseResponse<T> implements Serializable {private int code; // 状态码private T data; // 数据private String message; // 响应信息public BaseResponse(int code, T data, String message) {this.code = code;this.data = data;this.message = message;}public BaseResponse(int code, T data) {this(code, data, "");}public BaseResponse(ErrorCode errorCode) {this(errorCode.getCode(), null, errorCode.getMessage());}
}

6、异常处理

  1. 自定义异常类
public class BusinessException extends RuntimeException {private final int code;public BusinessException(int code, String message) {super(message);this.code = code;}public BusinessException(ErrorCode errorCode) {super((errorCode.getMessage()));this.code = errorCode.getCode();}public BusinessException(ErrorCode errorCode, String message) {super(message);this.code = errorCode.getCode();}public int getCode() {return code;}}
  1. 全局异常处理
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public BaseResponse<?> businessExceptionHandler(BusinessException e) {log.error("businessException: " + e.getMessage(), e);return ResultUtils.error(e.getCode(), e.getMessage());}@ExceptionHandler(RuntimeException.class)public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {log.error("runtimeException", e);return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage());}
}

@RestControllerAdvice 的作用:

它结合了 @ControllerAdvice@ResponseBody 两个注解的功能,用于全局异常处理和返回统一的格式化响应数据。

当控制器中抛出异常时,@RestControllerAdvice 会捕获这些异常,并根据异常类型返回相应的数据格式。我们可以在 @ExceptionHandler 注解下定义多个异常处理方法,每个方法处理一个或多个不同类型的异常。这些方法可以返回不同类型的数据,如 JSON、视图或其他对象。

除了异常处理,@RestControllerAdvice 还可以在控制器方法执行前或执行后执行一些操作,例如记录日志、数据验证等。

7、定义用户常量

避免使用魔法值

public interface UserConstant {/*** 用户登录态键*/String USER_LOGIN_STATE = "userLoginState";/*** 系统用户 id(虚拟用户)*/long SYSTEM_USER_ID = 0;//  region 权限/*** 默认权限*/String DEFAULT_ROLE = "user";/*** 管理员权限*/String ADMIN_ROLE = "admin";// endregion
}

8、返回结果工具类

public class ResultUtils {/*** 成功** @param data 数据* @return {@code BaseResponse<T>}*/public static <T> BaseResponse<T> success(T data) {return new BaseResponse<>(0, data, "ok");}/*** 失败** @param errorCode 错误码* @return*/public static BaseResponse error(ErrorCode errorCode) {return new BaseResponse<>(errorCode);}/*** 失败** @param code 状态码* @param message 信息* @return*/public static BaseResponse error(int code, String message) {return new BaseResponse(code, null, message);}/*** 失败** @param errorCode 错误码* @param message 信息* @return*/public static BaseResponse error(ErrorCode errorCode, String message) {return new BaseResponse(errorCode.getCode(), null, message);}
}

9、分层领域模型规约

  1. DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
  2. DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
  3. BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。
  4. Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。
  5. VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。

10、userAccount.intern()

userAccount.intern() 是 Java 中的字符串常量池方法,它的作用是将字符串对象添加到字符串常量池中,并返回该字符串对象在常量池中的引用。如果常量池中已经存在该字符串,则直接返回该字符串在常量池中的引用。

  • 当我们使用字符串字面量(例如:String userAccount = "admin")创建字符串时,Java 虚拟机会自动将其添加到字符串常量池中,因此这种方式创建的字符串对象在常量池中只会存在一份
  • 而当我们通过 new 关键字创建字符串时(例如:String userAccount = new String("admin")),则会在堆内存中创建一个新的字符串对象,该对象不会被添加到常量池中。

在实际开发中,我们可以使用 intern() 方法在运行时将堆中的字符串对象添加到常量池中,以便更有效地利用内存。但需要注意的是,由于常量池是在运行时被创建的,因此在使用 intern() 方法时需要注意字符串的生命周期,以避免不必要的内存消耗。

        synchronized (userAccount.intern()) {// 3. 加密String encryptPassword = DigestUtils.md5DigestAsHex((SALT + newPassword).getBytes());// 4. 更新数据user.setUserPassword(encryptPassword);boolean result = this.updateById(user);if (!result) {throw new BusinessException(ErrorCode.SYSTEM_ERROR, "密码找回失败,数据库错误");}// 5. 返回用户idreturn user.getId();}

11、分页查询

userVOPage.setRecords(userVOList)

这段代码是将一个 List 列表中的元素设置到一个分页对象(Page)中的记录(records)属性中。

通过调用 userVOPagesetRecords 方法,将 userVOList 列表中的元素设置到 userVOPage 的记录属性中,从而实现了将查询结果封装成一个分页对象的功能。这样,就可以将分页查询结果返回给前端展示,方便用户进行浏览和操作。

public Page<UserVO> listUserByPage(UserQueryRequest userQueryRequest, HttpServletRequest request) {long current = 1; // 默认当前页为第一页long size = 10; // 默认每页查询10条数据User userQuery = new User(); // 创建用户查询对象if (userQueryRequest != null) { // 如果查询请求参数不为空BeanUtils.copyProperties(userQueryRequest, userQuery); // 将请求参数拷贝到用户查询对象中current = userQueryRequest.getCurrent(); // 获取当前页数size = userQueryRequest.getPageSize(); // 获取每页查询记录数}LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); // 创建Lambda查询条件对象Page<User> userPage = this.page(new Page<>(current, size), lambdaQueryWrapper); // 分页查询用户信息Page<UserVO> userVOPage = new PageDTO<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal()); // 创建用户VO分页对象List<UserVO> userVOList = userPage.getRecords().stream().map(user -> {UserVO userVO = new UserVO(); // 创建用户VO对象BeanUtils.copyProperties(user, userVO); // 将用户信息拷贝到用户VO对象中return userVO;}).collect(Collectors.toList()); // 将用户VO对象转化为List集合// 将userVOList列表中的元素设置到userVOPage的记录(recodes)属性中userVOPage.setRecords(userVOList);return userVOPage;
}

12、分页插件配置

@Configuration
@MapperScan("com.chenmeng.project.mapper")
public class MyBatisPlusConfig {/*** 拦截器配置** @return*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

13、Knife4j 接口文档配置

knife4j 是为 Java MVC 框架集成 Swagger 生成 Api 文档的增强解决方案,前身是 swagger-bootstrap-ui,取名 knife4j 是希望它能像一把匕首一样小巧、轻量,并且功能强悍。其底层是对 Springfox 的封装,使用方式也和 Springfox 一致,只是对接口文档 UI 进行了优化

参考博客:

Swagger与Knife4j的学习

1、导入依赖

        <!-- https://doc.xiaominfo.com/knife4j/documentation/get_start.html--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.3</version></dependency>

2、指定 MVC 匹配路径 - yml 文件中

  mvc:pathmatch:# 指定URL路径匹配的策略--Ant--风格,默认的URL路径匹配的策略是AntPathMatchermatching-strategy: ANT_PATH_MATCHER

不指定的话会报错:Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

原因:在配置 Swagger 后,

springBoot 处理映射匹配的默认策略发生了变化,Spring MVC 处理映射匹配的默认策略已从 AntPathMatcher 更改为 PathPatternParser

参考博客:

https://blog.csdn.net/Shipley_Leo/article/details/129100908

3、写配置文件

@Configuration
@EnableSwagger2
@Profile("dev")
public class Knife4jConfig {@Beanpublic Docket defaultApi2() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(new ApiInfoBuilder().title("project-backend").description("后端接口项目文档").version("1.0").build()).select()// 指定 Controller 扫描包路径.apis(RequestHandlerSelectors.basePackage("com.chenmeng.project.controller")).paths(PathSelectors.any()).build();}
}

4、显示以下页面表示配置成功

image

14、全局跨域配置

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {// 覆盖所有请求registry.addMapping("/**")// 允许发送 Cookie.allowCredentials(true)// 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突).allowedOriginPatterns("*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").exposedHeaders("*");}
}

15、自定义权限校验注解

@Target(ElementType.METHOD) // 表示该注解只能添加在方法上
@Retention(RetentionPolicy.RUNTIME) // 表示该注解在运行时可用
public @interface AuthCheck {/*** 有任何一个角色** @return {@code String[]}*/String[] anyRole() default "";/*** 必须有某个角色** @return {@code String}*/String mustRole() default "";}

16、AOP

首先需要导入 AOP 依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

1、权限校验拦截器 AOP

@Aspect
@Component
public class AuthInterceptor {@Resourceprivate UserService userService;/*** 执行拦截** @param joinPoint 连接点,即被拦截到的方法* @param authCheck 自定义注解 - 身份验证检查* @return {@code Object}*/@Around("@annotation(authCheck)")public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {// 获取 @AuthCheck 注解的 anyRole 属性值,并将 非空字符串 添加到列表中。List<String> anyRole = Arrays.stream(authCheck.anyRole()).filter(StringUtils::isNotBlank).collect(Collectors.toList());// 获取 @AuthCheck 注解的 mustRole 属性值String mustRole = authCheck.mustRole();// 获取当前请求的属性RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();// 获取当前请求对象HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();// 获取当前登录用户User user = userService.getLoginUser(request);// 拥有任意权限即可通过if (CollectionUtils.isNotEmpty(anyRole)) { // 判断 anyRole 列表是否非空String userRole = user.getUserRole();if (!anyRole.contains(userRole)) {throw new BusinessException(ErrorCode.NO_AUTH_ERROR);}}// 必须拥有所有权限才可通过if (StringUtils.isNotBlank(mustRole)) { // 判断 mustRole 列表是否非空String userRole = user.getUserRole();if (!mustRole.equals(userRole)) {throw new BusinessException(ErrorCode.NO_AUTH_ERROR);}}// 通过权限校验,放行return joinPoint.proceed();}
}

@Aspect 注解和 @Around 注解,用于拦截带有 @AuthCheck 注解的方法,进行身份验证校验。

  • @Aspect 注解表示这是一个切面类,用于定义切点和通知。
  • @Component 注解表示这个类是一个 Spring 组件,需要被 Spring 容器管理。
  • @Around("@annotation(authCheck)") 表示它拦截带有 @AuthCheck 注解的方法,并在方法执行前进行身份验证校验。

AuthCheck authCheck 表示被拦截方法上的 @AuthCheck 注解对象。

2、请求响应日志拦截器 AOP

@Aspect
@Component
@Slf4j
public class LogInterceptor {/*** 执行拦截** @param point 连接点* @return {@code Object}* @throws Throwable throwable*/@Around("execution(* com.chenmeng.project.controller.*.*(..))")public Object doInterceptor(ProceedingJoinPoint point) throws Throwable {// 计时StopWatch stopWatch = new StopWatch();stopWatch.start();// 获取请求路径RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();// 生成请求唯一 idString requestId = UUID.randomUUID().toString();String url = httpServletRequest.getRequestURI();// 获取请求参数Object[] args = point.getArgs();String reqParam = "[" + StringUtils.join(args, ", ") + "]";// 输出请求日志log.info("request start,id: {}, path: {}, ip: {}, params: {}", requestId, url,httpServletRequest.getRemoteHost(), reqParam);// 执行原方法Object result = point.proceed();// 输出响应日志stopWatch.stop();long totalTimeMillis = stopWatch.getTotalTimeMillis();log.info("request end, id: {}, cost: {}ms", requestId, totalTimeMillis);return result;}
}

依赖解析

<?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.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.chenmeng</groupId><artifactId>easy-web</artifactId><version>0.0.1-SNAPSHOT</version><name>easy-web</name><description>Spring Boot 后端项目脚手架</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><!--commons-lang3工具类--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><!--hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency><!-- swagger + knife4j 接口文档--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- gson解析库 --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.9.0</version></dependency><!--AOP--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><!-- devtools热部署依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><!-- 防止将依赖传递到其他模块中 --><optional>true</optional><!-- 只在运行时起作用,打包时不打进去(防止线上执行打包后的程序,启动文件监听线程File Watcher,耗费大量的内存资源) --><scope>runtime</scope></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

1、热部署依赖

spring-boot-devtools 提供以下功能:

  1. 自动应用程序重启:在开发应用程序时,当我们对代码进行更改并保存后,应用程序将自动重新启动,以便更快地查看更改的结果,而无需手动重启应用程序。
  2. LiveReload 支持:当我们更改 HTML、CSS、JavaScript 文件时,LiveReload 将自动重新加载浏览器页面,以便更快地查看更改的结果。
  3. 全局默认属性设置:在开发期间,我们可能需要设置一些默认属性,例如开启调试模式,禁用缓存等。spring-boot-devtools 提供了一种简单的方式来设置这些属性,以便在整个应用程序中生效。

需要注意的是,spring-boot-devtools 只应该在开发环境中使用,不应该在生产环境中使用。因为在生产环境中,自动重启和 LiveReload 可能会导致应用程序的性能下降,甚至可能会引起一些安全问题。

热部署:https://www.jianshu.com/p/de544b13b9d5

注册器参数设置解析

首先在 IDEA 中,按 Ctrl + Alt + Shift + /(或 Cmd + Option + Shift + / on macOS)打开 Registry。

  1. compiler.automake.build.while.idle.timeout 是 IntelliJ IDEA 的注册表(Registry)中的一项设置。这个设置项控制的是在系统空闲状态下,IDEA 自动构建项目的等待时间。
  2. compiler.automake.postpone.when.idle.less.than 是 IntelliJ IDEA 注册表(Registry)中的另一个设置项,它控制了在系统空闲时间小于特定值时是否延迟自动构建。

注意事项

请注意,这种自动构建可能会对系统的资源使用产生影响,尤其是在大型项目中。如果你发现系统响应变慢或者 CPU 使用率过高,可以尝试调低这个设置值或关闭自动构建功能。

2、gson 解析依赖库

Gson 是 Google 提供的一个 Java 库,用于将 Java 对象和 JSON 数据相互转换。它可以将一个 Java 对象序列化为 JSON 格式的字符串,也可以将一个 JSON 格式的字符串反序列化为一个 Java 对象。

Gson 支持 Java 中的基本数据类型、集合类型和自定义对象类型,并且可以对 Java 对象进行自定义序列化和反序列化操作。

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.9.0</version></dependency>

可以看看下面这篇文章:

Gson的基本使用

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

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

相关文章

【重点】【BFS】542.01矩阵

题目 法1&#xff1a;经典BFS 下图中就展示了我们方法&#xff1a; class Solution {public int[][] updateMatrix(int[][] mat) {int m mat.length, n mat[0].length;int[][] dist new int[m][n];boolean[][] used new boolean[m][n];Queue<int[]> queue new Li…

Spring Boot 3 集成 Thymeleaf

在现代的Web开发中&#xff0c;构建灵活、动态的用户界面是至关重要的。Spring Boot和Thymeleaf的结合为开发者提供了一种简单而强大的方式来创建动态的Web应用。本文将介绍如何在Spring Boot项目中集成Thymeleaf&#xff0c;并展示一些基本的使用方法。 什么是Thymeleaf&#…

未来已来,Ai原生应用与人高度结合!学习就在现在?

原生应用&#xff1a;OpenAI™ChatGPT、Baidu.Inc™文心一言 也可以体验CSDN的INSCODE AI&#xff0c;集成多个国内GPT内容。 文章目录 前言----编程语言的未来&#xff1f;一、编程语言的教育1.1 学校所见所闻1.2 开启我们的Ai行程~io&#xff01;1.3 Ai结果评论 二、Ai编程教…

Linux环境vscode clang-format格式化:vscode clang format command is not available

问题现象 vscode安装了clang-format插件&#xff0c;但是使用就报错 问题原因 设置中配置的clang-format插件工具路径不正确。 解决方案 确认本地安装了clang-format工具&#xff1a;终端输入clang-format&#xff08;也可能是clang-format-13等版本&#xff0c;建议tab自…

[NISACTF 2022]popchains

[NISACTF 2022]popchains wp 题目代码&#xff1a; Happy New Year~ MAKE A WISH <?phpecho Happy New Year~ MAKE A WISH<br>;if(isset($_GET[wish])){unserialize($_GET[wish]); } else{$anew Road_is_Long;highlight_file(__FILE__); } /**********************…

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…

Android Studio 报错Failed to find Build Tools revision 28.0.3

目录 前言 一、报错信息 二、报错原因 三、解决方案 四、更多资源 前言 当Android Studio报错提示"Failed to find Build Tools revision 28.0.3"时&#xff0c;通常意味着您的项目需要使用28.0.3版本的构建工具&#xff0c;但系统中并没有找到对应的版本。这可…

西电期末1020.寻找同数

一.题目 二.分析与思路 其实就是寻找字串的个数&#xff0c;以前好像是有类似的题&#xff0c;先找到子串的首字符&#xff0c;再判断 三.代码实现 #include<bits/stdc.h>//万能头 bool f(char* s,char* sub,int i,int l){for(int j0;j<l;j){if(s[ji]!sub[j])retu…

计算机组成原理复习

一、计算机系统概论 计算机由硬件和软件两大部分组成 软件分系统软件和应用软件翻译程序有两种&#xff1a;编译程序和解释程序冯诺依曼计算机的特点&#xff1a; 计算机由运算器、存储器、控制器、输入设备和输出设备五大部分组成。指令和数据以同等地位存放于存储器内&#…

如何成为ChatGPT 优质Prompt创作者

如何提问&#xff1f; 我想让你成为我的Prompt创作者。你的目标是帮助我创作最佳的Prompt&#xff0c;这个Prompt将由你ChatGPT使用。你将遵循 以下过程&#xff1a;1.首先&#xff0c;你会问我Prompt是关于什么&#xff1f;我会告诉你&#xff0c;但我们需要 通过不断的重复来…

brew 安装使用 mysql、redis、mongodb

在 Mac 生态中 brew 真是个万能神器&#xff0c;今天就来介绍一下怎么使用 brew 安装 mysql、redis、mongodb&#xff0c;以及如何使用 brew 启动、关闭、重启这些服务。 前言 brew 常用命令 # 查看brew的版本 brew -v# 更新homebrew自己&#xff0c;把所有的Formula目录更新…

索引类型-哈希索引

一. 前言 前面我们简单介绍了数据库的B-Tree索引&#xff0c;下面我们介绍另一种索引类型-哈希索引。 二. 哈希索引的简介 哈希索引(hash index) 基于哈希表实现&#xff0c;只有精确匹配索引所有列的查询才有效。对于每一行数据&#xff0c;存储引擎都会对所有索引列计算一个…

华为 1+X《网络系统建设与运维(初级)》 认证实验上机模拟试题

华为 1X《网络系统建设与运维&#xff08;初级&#xff09;》认证实验上机模拟试题 一、考试背景二、考试说明2.1考试分数说明2.2考试要求2.3考试环境介绍2.4启动考试环境2.5保存答案 三、考试正文3.1考试内容3.1.1任务 1&#xff1a;设备连接3.1.2任务 2&#xff1a;设备命名3…

Centos7静态网络配置

在vmware中打开&#xff0c; 点击虚拟网络编辑器&#xff0c;修改以下配置 网关IP最后一位固定为2&#xff0c;这个160根据下图中vmnet8的ip地址来的 打开网络控制面板>打开vmnet8查看 接着打开linux&#xff0c;有桌面版的使用桌面版更加方便 箭头这么乱&#xff0c;但是你…

【数据结构】二叉树(二)——顺序结构

前言 本篇博客讲解数组实现二叉树的顺序结构 文章目录 一、二叉树的顺序结构及实现1.1 二叉树的顺序结构1.2 堆的概念1.3 堆的实现1.3.1 初始化堆1.3.2 向堆中插入元素1.3.3 从堆顶删除1.3.4 其他操作1.3.5 完整代码Heap.hHeap.c 1.4 堆的应用1.4.1 堆排序1.4.2 TOP-K问题 一、…

web服务器nginx和Apache有什么区别?

随着互联网的快速发展&#xff0c;Web服务器在互联网应用中扮演着越来越重要的角色。其中&#xff0c;Nginx和Apache是两种广泛使用的Web服务器软件。尽管它们都可以实现Web服务器的功能&#xff0c;但Nginx和Apache在许多方面存在一些重要的区别。本文将探讨Nginx和Apache之间…

大数据技术在民生资金专项审计中的应用

一、应用背景 目前&#xff0c;针对审计行业&#xff0c;关于大数据技术的相关研究与应用一般包括大数据智能采集数据技术、大数据智能分析技术、大数据可视化分析技术以及大数据多数据源综合分析技术。其中&#xff0c;大数据智能采集数据技术是通过网络爬虫或者WebService接…

Docker无法启动Postgresql容器

目录 问题描述解决问题 问题描述 拉取了一个Postgresql14.2的镜像&#xff0c;在docker run创建并运行容器之后使用docker ps发现容器没有跑起来&#xff0c;再次使用docker start也没跑起来。 docker run -d --name mypg -v psql-data:/var/lib/postgresql/data -e POSTGRES…

Python random模块(获取随机数)常用方法和使用例子

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 random.random random.random()用于生成一个0到1的随机符点数: 0 < n < 1.0 random.uniform random.uniform(a, b)&#xff0c;用于生成一个指定范围内的随机符点数&#xff0c;两个参数其中一个是上限&#xff0c;一…

2023-我的CSDN创作之旅

1.博客内容与数量 2023年共发表博客59篇&#xff0c;内容主要集中在GIS&#xff0c;空间分析等领域 主要内容有&#xff1a; networkx学习 Geospatial Data Science Geocomputation ESDA in PySal SHAP Spatial Data Analysis BikeDNA 以下是对这几个章节主要内容的简…