后端质料springboot

  • application.yml
  • util工具类
    • 2.1验证码生成工具CreateVerifiCodeImage
    • 2.2全局统一返回结果类Result
    • 2.3ResultCodeEnum
    • 2.4JwtHelper
    • 2.5AuthContextHolder对JwtHelper的封装
  • logback-spring.xml代码

application.yml

application.yml

server:port: 9001
spring:#解决SpringBoot2.6.0与swagger冲突问题【原因是在springboot2.6.0中将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser,导致出错,解决办法是切换回原先的AntPathMatcher】mvc:pathmatch:matching-strategy: ant_path_matcher#解决静态资源访问不到static-path-pattern: /static/**#配置数据源datasource:#配置数据源类型type: com.zaxxer.hikari.HikariDataSource#配置数据库连接属性driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/zhxy_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&userSSL=falseusername: rootpassword: 0615#url: jdbc:mysql://r2czkq1vewxat78mnyg60oisurj5h4dp.mysql.qingcloud.link:3306/ssg_zhxy_db?characterEncoding=utf-8&serverTimezone=GMT%2B8&userSSL=false#username: shangguigu#password: shangguigu@QY123#mybatis-plus内置连接池hikari:connection-test-query: SELECT 1connection-timeout: 60000idle-timeout: 500000max-lifetime: 540000maximum-pool-size: 12minimum-idle: 10pool-name: GuliHikariPoolthymeleaf:#模板的模式,支持 HTML, XML TEXT JAVASCRIPTmode: HTML5#编码 可不用配置encoding: UTF-8#开发配置为false,避免修改模板还要重启服务器cache: false#配置模板路径,默认是templates,可以不用配置prefix: classpath:/static/jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8servlet:#设置文件上传上限multipart:max-file-size: 10MBmax-request-size: 100MB
mybatis-plus:configuration:#添加日志支持log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath*:/mapper/**/*.xml

--------------------------------------------------------- ---------------------------------------------------------

util工具类

2.1验证码生成工具CreateVerifiCodeImage

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;/*** @project: ssm_sms* @description: 绘制验证码图片*/
public class CreateVerifiCodeImage {private static int WIDTH = 90;private static int HEIGHT = 35;private static int FONT_SIZE = 20; //字符大小private static char[] verifiCode; //验证码private static BufferedImage verifiCodeImage; //验证码图片/*** @description: 获取验证码图片* @param: no* @return: java.awt.image.BufferedImage*/public static BufferedImage getVerifiCodeImage() {verifiCodeImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_BGR);// create a imageGraphics graphics = verifiCodeImage.getGraphics();verifiCode = generateCheckCode();drawBackground(graphics);drawRands(graphics, verifiCode);graphics.dispose();return verifiCodeImage;}/*** @description: 获取验证码* @param: no* @return: char[]*/public static char[] getVerifiCode() {return verifiCode;}/*** @description: 随机生成验证码* @param: no* @return: char[]*/private static char[] generateCheckCode() {String chars = "0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";char[] rands = new char[4];for (int i = 0; i < 4; i++) {int rand = (int) (Math.random() * (10 + 26 * 2));rands[i] = chars.charAt(rand);}return rands;}/*** @description: 绘制验证码* @param: g* @param: rands* @return: void*/private static void drawRands(Graphics g, char[] rands) {g.setFont(new Font("Console", Font.BOLD, FONT_SIZE));for (int i = 0; i < rands.length; i++) {g.setColor(getRandomColor());g.drawString("" + rands[i], i * FONT_SIZE + 10, 25);}}/*** @description: 绘制验证码图片背景* @param: g* @return: void*/private static void drawBackground(Graphics g) {g.setColor(Color.white);g.fillRect(0, 0, WIDTH, HEIGHT);// 绘制验证码干扰点for (int i = 0; i < 200; i++) {int x = (int) (Math.random() * WIDTH);int y = (int) (Math.random() * HEIGHT);g.setColor(getRandomColor());g.drawOval(x, y, 1, 1);}}/*** @description: 获取随机颜色* @param: no* @return: java.awt.Color*/private static Color getRandomColor() {Random ran = new Random();return new Color(ran.nextInt(220), ran.nextInt(220), ran.nextInt(220));}
}

--------------------------------------------------------- ---------------------------------------------------------

2.2全局统一返回结果类Result


import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** 全局统一返回结果类**/
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {@ApiModelProperty(value = "返回码")private Integer code;@ApiModelProperty(value = "返回消息")private String message;@ApiModelProperty(value = "返回数据")private T data;public Result(){}// 返回数据protected static <T> Result<T> build(T data) {Result<T> result = new Result<T>();if (data != null)result.setData(data);return result;}public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {Result<T> result = build(body);result.setCode(resultCodeEnum.getCode());result.setMessage(resultCodeEnum.getMessage());return result;}public static<T> Result<T> ok(){return Result.ok(null);}/*** 操作成功* @param data* @param <T>* @return*/public static<T> Result<T> ok(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.SUCCESS);}public static<T> Result<T> fail(){return Result.fail(null);}/*** 操作失败* @param data* @param <T>* @return*/public static<T> Result<T> fail(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.FAIL);}public Result<T> message(String msg){this.setMessage(msg);return this;}public Result<T> code(Integer code){this.setCode(code);return this;}public boolean isOk() {if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {return true;}return false;}
}

2.3ResultCodeEnum

package com.xbfinal.myzhxy.util;import lombok.Getter;/*** 统一返回结果状态信息类**/
@Getter
public enum ResultCodeEnum {SUCCESS(200,"成功"),FAIL(201, "失败"),SERVICE_ERROR(2012, "服务异常"),ILLEGAL_REQUEST( 204, "非法请求"),PAY_RUN(205, "支付中"),ARGUMENT_VALID_ERROR(206, "参数校验错误"),LOGIN_ERROR(207, "用户名或密码错误"),LOGIN_AUTH(208, "未登陆"),PERMISSION(209, "没有权限"),SECKILL_NO_START(210, "秒杀还没开始"),SECKILL_RUN(211, "正在排队中"),SECKILL_NO_PAY_ORDER(212, "您有未支付的订单"),SECKILL_FINISH(213, "已售罄"),SECKILL_END(214, "秒杀已结束"),SECKILL_SUCCESS(215, "抢单成功"),SECKILL_FAIL(216, "抢单失败"),SECKILL_ILLEGAL(217, "请求不合法"),SECKILL_ORDER_SUCCESS(218, "下单成功"),COUPON_GET(220, "优惠券已经领取"),COUPON_LIMIT_GET(221, "优惠券已发放完毕"),//2022-02-22LOGIN_CODE(222,"长时间未操作,会话已失效,请刷新页面后重试!"),CODE_ERROR(223,"验证码错误!"),TOKEN_ERROR(224,"Token无效!");private Integer code;private String message;private ResultCodeEnum(Integer code, String message) {this.code = code;this.message = message;}
}

2.4JwtHelper

package com.xbfinal.myzhxy.util;
import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;import java.util.Date;
public class JwtHelper {private static long tokenExpiration = 24*60*60*1000;private static String tokenSignKey = "123456";//生成token字符串public static String createToken(Long userId, Integer userType) {String token = Jwts.builder().setSubject("YYGH-USER").setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).claim("userId", userId)
//                .claim("userName", userName).claim("userType", userType).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}//从token字符串获取useridpublic static Long getUserId(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();Integer userId = (Integer)claims.get("userId");return userId.longValue();}//从token字符串获取userTypepublic static Integer getUserType(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (Integer)(claims.get("userType"));}//从token字符串获取userNamepublic static String getUserName(String token) {if(StringUtils.isEmpty(token)) return "";Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String)claims.get("userName");}//判断token是否有效public static boolean isExpiration(String token){try {boolean isExpire = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getExpiration().before(new Date());//没有过期,有效,返回falsereturn isExpire;}catch(Exception e) {//过期出现异常,返回truereturn true;}}/*** 刷新Token* @param token* @return*/public String refreshToken(String token) {String refreshedToken;try {final Claims claims = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody();refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));} catch (Exception e) {refreshedToken = null;}return refreshedToken;}public static void main(String[] args) {//        String token = JwtHelper.createToken(1L, "lucy");
//        System.out.println(token);
//        System.out.println(JwtHelper.getUserId(token));
//        System.out.println(JwtHelper.getUserName(token));}
}

2.5AuthContextHolder对JwtHelper的封装

package com.xbfinal.myzhxy.util;
import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;import java.util.Date;
public class JwtHelper {private static long tokenExpiration = 24*60*60*1000;private static String tokenSignKey = "123456";//生成token字符串public static String createToken(Long userId, Integer userType) {String token = Jwts.builder().setSubject("YYGH-USER").setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).claim("userId", userId)
//                .claim("userName", userName).claim("userType", userType).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}//从token字符串获取useridpublic static Long getUserId(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();Integer userId = (Integer)claims.get("userId");return userId.longValue();}//从token字符串获取userTypepublic static Integer getUserType(String token) {if(StringUtils.isEmpty(token)) return null;Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (Integer)(claims.get("userType"));}//从token字符串获取userNamepublic static String getUserName(String token) {if(StringUtils.isEmpty(token)) return "";Jws<Claims> claimsJws= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String)claims.get("userName");}//判断token是否有效public static boolean isExpiration(String token){try {boolean isExpire = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getExpiration().before(new Date());//没有过期,有效,返回falsereturn isExpire;}catch(Exception e) {//过期出现异常,返回truereturn true;}}/*** 刷新Token* @param token* @return*/public String refreshToken(String token) {String refreshedToken;try {final Claims claims = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody();refreshedToken = JwtHelper.createToken(getUserId(token), getUserType(token));} catch (Exception e) {refreshedToken = null;}return refreshedToken;}public static void main(String[] args) {//        String token = JwtHelper.createToken(1L, "lucy");
//        System.out.println(token);
//        System.out.println(JwtHelper.getUserId(token));
//        System.out.println(JwtHelper.getUserName(token));}
}

logback-spring.xml代码

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds"><!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --><!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --><contextName>logback</contextName><!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --><property name="log.path" value="D:/guli_1010/edu" /><!-- 彩色日志 --><!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 --><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/><!--输出到控制台--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--><!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!--输出到文件--><!-- 时间滚动输出 level为 INFO 日志 --><appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_info.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 WARN 日志 --><appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_warn.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 时间滚动输出 level为 ERROR 日志 --><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_error.log</file><!--日志文件输出格式--><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern><charset>UTF-8</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy><!-- 此日志文件只记录ERROR级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--<logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。<logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性。name:用来指定受此logger约束的某一个包或者具体的某一个类。level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,如果未设置此属性,那么当前logger将会继承上级的级别。--><!--使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:--><!--开发环境:打印控制台--><springProfile name="dev"><!--可以输出项目中的debug日志,包括mybatis的sql日志--><logger name="com.guli" level="INFO" /><!--root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG可以包含零个或多个appender元素。--><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="WARN_FILE" /><appender-ref ref="ERROR_FILE" /></root></springProfile><!--生产环境:输出到文件--><springProfile name="pro"><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="DEBUG_FILE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="ERROR_FILE" /><appender-ref ref="WARN_FILE" /></root></springProfile></configuration>

后端质料springboot相关推荐

  1. AFNetworking 4.x高版本上传图片,后端采用springBoot测试

    AFNetworking 4.x高版本上传图片,后端采用springBoot测试 Pod加入 pod 'AFNetworking', '~> 4.0.1' -(void)sendStatusWi ...

  2. 【两万字图文详解】 运动会管理系统-前后端分离-项目开发:【后端】SpringBoot, SpringMVC, MyBatis【前端】Vue.js,ElementUI

    项目名称:运动会管理系统  技术栈:      后端:SpringBoot,SpringMVC,MyBatis,tkmapper,Maven聚合工程等      前端:Vue.js,Element-u ...

  3. 前后端分离(SpringBoot+Vue)-基础的权限管理系统

    前后端分离(SpringBoot+Vue)-基础的权限管理系统 简介 前端项目代码地址:前端代码 后端项目代码地址:后端代码 最后的附录记录了自己在开发过程遇到问题及实现.部分文件的介绍 采用前后端分 ...

  4. 后端学习 - SpringBoot

    SpringBoot 是整合 Spring 技术栈的一站式框架,是简化 Spring 技术栈的快速开发脚手架 约定大于配置 文章目录 一 概述 1 第一个 SpringBoot 项目 2 Spring ...

  5. 推荐9个大气美观的前后端分离项目:前端react,vue,ts,ElementUI,Angular等,后端mysql,springBoot,myBatis,springSecurity,cloud等

    文章目录 1. 引言 2. 微人事 2. 前后端分离博客项目 3. V部落博客管理平台 4. 基于SpringBoot的微信点餐系统 5. eladmin后台管理系统 6. NiceFish(美人鱼) ...

  6. 网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站

    作者主页:编程千纸鹤 作者简介:Java.前端.Python开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.面试技术整理.最新技术分享 收藏点赞不迷路  关注作者有好处 ...

  7. 创建一键部署的前后端(SpringBoot+Vue+nginx)项目镜像

    创建一键部署的前后端项目镜像 该方法时将spring-boot项目改造为一个镜像,其底层逻辑,是创建一个Cent Os镜像,然后将项目所需的所有环境安装到该镜像上,最后通过一个脚本启动所有服务,从而达 ...

  8. Web后端框架Springboot创建和基础讲解(一)

    Springboot是一款底层由java编写的web后端框架,前身是spring框架,相较于前身框架而言,继承了其良好的兼容性以及扩展性,并且舍弃了大量繁杂的xml文件,将其改为依赖注入spirngb ...

  9. 后端:SpringBoot集成Swagger-Bootstrap-UI,界面美观!

    SpringBoot集成Swagger-Bootstrap-UI,界面美观.下面给大家介绍一下! 该开源项目GitHub地址: https://github.com/xiaoymin/Swagger- ...

最新文章

  1. 表单form类型数据转换为数组array
  2. 补第一阶段冲刺站立会议1(应发表日期5月13日)
  3. HDU - 5514 Frogs(容斥原理)
  4. 为什么我们会拖延? (TED)
  5. nio~view buffer
  6. MATLAB代码实现射线追踪的快速方法
  7. 深圳市南山区派出所地址和电话列表
  8. mysql查询临时表是否存在_[转]SQL判断临时表是否存在
  9. (MATLAB)使用梯度下降进行一元线性回归
  10. 为什么要重写hashCode()
  11. 北大中文核心期刊目录2021年 无线电电子学、电信技术
  12. PowerBuilder 开发的游戏(建房子)
  13. cad会员共享_CAD迷你画图共享版下载
  14. 三个月追求金牛全过程(图
  15. SaaS 系统的应用与架构
  16. xls与csv文件区别
  17. java jfreechart 饼图_JFreeChart 使用一 饼图之高级特性
  18. 剑指 Offer 61-68
  19. Lined List 链表总结 Reverse链表 - 反转(python) leetcode 206 92
  20. Linux内核分析2:一个简单的时间片轮转多道程序内核代码分析

热门文章

  1. python循环语句和跳出语句详解
  2. 《一万年以后》一段充满癫狂想象力的奇幻之旅
  3. 【建站教程】万网域名使用万网\QQ企业邮箱,设置解析方法
  4. matlab三个自变量一个因变量拟合
  5. JS元素的提取,删除 ,添加,修改
  6. oracle篮球,篮球小王子!任嘉伦打篮球也不来赖,超爱11号
  7. vscode设置中文字体
  8. 计算机网络-应用层-Web和HTTP
  9. 马里兰大计算机专业学phd博士,亚利桑那州立大学计算机CS博士PHD全奖录取
  10. 数字化的终局:赛博朋克?社会主义?