【开源项目--稻草】Day03

【开源项目--稻草】Day03

  • 1. 续Spring-Security
    • 1.1 自定义登录界面
  • 2. 用户注册
    • 2.1 将注册页面显示
    • 2.2 编写控制器进行测试
    • 2.3 编写注册业务逻辑
    • 2.4 注册功能的收尾
  • 3. VUE
    • 3.1 VUE的基本使用
      • 3.1.1 什么是VUE
    • 3.2 使用VUE+Ajax完善稻草问答的注册功能

1. 续Spring-Security

1.1 自定义登录界面

如果想在用户登录时用我们自己的登录页面代替Spring-Security提供的登录页面

需要进行如下配置

步骤1:

登录页面是视图模板引擎生成的,所以需要引入Thymeleaf的依赖

子项目的pom.xml文件

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId></dependency>

步骤2:

将static文件夹中的login.html
复制到templates文件夹下
需要注意
现在login.html提交的路径是/login
用户名和密码输入框的name是username和password
这两个名字也是Spring-Security约定的不要改!!
我们需要写一个控制器来访问显示这个页面
这个控制器不输于任何实体类,新建一个SystemController

@RestController
public class SystemController {// 显示登录页面的方法@GetMapping("/login.html")public ModelAndView loginForm(){//ModelAndView("login");对应的是resources/templates/login.htmlreturn new ModelAndView("login");}
}

步骤3:
要对login.html进行放行

要配置登录时的各种信息

要配置登出时的各种信息

SecurityConfig类中编写

 @Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests()//对当前全部请求进行授权.antMatchers("/index.html","/img/*","/js/*","/css/*","/bower_components/**","/login.html")//设置路径.permitAll()//允许全部请求访问上面定义的路径//其它路径需要全部进行表单登录验证.anyRequest().authenticated().and().formLogin().loginPage("/login.html").loginProcessingUrl("/login").failureUrl("/login.html?error").defaultSuccessUrl("/index.html").and().logout().logoutUrl("/logout").logoutSuccessUrl("/login.html?logout");}

方法说明:

1.csrf().disable():关闭防跨域攻击功能,不关闭容易发生错误
2.loginPage:指定登录页面路径
3.loginProcessingUrl:指定表单提交的路径
4.failureUrl:指定登录失败时的路径
5.defaultSuccessUrl:指定登录成功时的路径
6.logout():表示开始配置登出时的内容
7.logoutUrl:指定出的路径(当页面有这个请求时,Spring-Security去执行用户登出操作)
8.logoutSuccessUrl:指定登出成功之后显示的页面

2. 用户注册

每个网站都需要用户注册的功能
页面如下图
在这里插入图片描述
1.获得邀请码(开发过程是从数据库获得,运营时向老师索取)
2.通过登录页上的注册连接显示注册页面
3.向服务器请求注册页并显示到浏览器
4.注册页面填写信息并提交表单
5.服务器接收到表单信息,控制层调用业务逻辑层执行注册操作
6.业务层执行连库操作新增之前验证邀请码
7.邀请码验证通过在执行数据库新增操作
8.返回新增操作的运行结果
9.根据结果反馈到控制层,有异常就报异常
10.控制器将注册结果信息使用JSON返回给浏览器
11.浏览器中局部刷新页面,将注册结果显示给用户

2.1 将注册页面显示

步骤1:

复制static文件夹中的register.html页面到templates文件夹

步骤2:

编写控制器SystemController类中添加方法

	// 显示注册页面的方法@GetMapping("/register.html")public ModelAndView register(){return new ModelAndView("register");}

步骤3:

SecurityConfig类中放行register.html

http.csrf().disable().authorizeRequests()//对当前全部请求进行授权.antMatchers("/index.html","/img/*","/js/*","/css/*","/bower_components/**","/login.html","/register.html"  //放行在这个!!!!!!)//设置路径.permitAll()//允许全部请求访问上面定义的路径//其它路径需要全部进行表单登录验证.anyRequest().authenticated().and().formLogin().loginPage("/login.html").loginProcessingUrl("/login").failureUrl("/login.html?error").defaultSuccessUrl("/index.html").and().logout().logoutUrl("/logout").logoutSuccessUrl("/login.html?logout");

2.2 编写控制器进行测试

我们先编写一个简单的控制器代码接收表单的信息,并返回内容
在页面上显示

步骤1:

表单提交的5个属性创建一个Vo类接收代码如下

@Data
public class RegisterVo implements Serializable {private String inviteCode;private String phone;private String nickname;private String password;private String confirm;
}

步骤2:

上面步骤1中的实体类能接收表单发送过来的信息

但是我们控制器处理完成后,想返回Json格式的对象给JS,也需要一个实体类

这个实体类最好能够通用于所有业务

现在行业中流行使用一个"R"类来返回JSON格式信息

这个R类中主要包含3个属性

1.状态码

2.状态消息

3.实体(控制器查询出的任何内容)

创建R类(代码无需掌握,会使用即可)

@Data
@Accessors(chain = true)
public class R<T> implements Serializable {/** 200 OK - [GET]:服务器成功返回用户请求的数据 */public static final int OK = 200;/** 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。 */public static final int CREATED = 201;/** 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务) */public static final int ACCEPTED = 202;/** 204 NO CONTENT - [DELETE]:用户删除数据成功。 */public static final int NO_CONTENT = 204;/** 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作。*/public static final int INVALID_REQUEST = 400;/** 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。 */public static final int UNAUTHORIZED = 401;/** 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。*/public static final int FORBIDDEN = 403;/** 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作。 */public static final int NOT_FOUND = 404;/** 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。*/public static final int GONE = 410;/** 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 */public static final int UNPROCESABLE_ENTITY = 422;/** 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。 */public static final int INTERNAL_SERVER_ERROR = 500;private int code;private String message;private T data;/*** 服务器成功返回用户请求的数据* @param message 消息*/public static R ok(String message){return new R().setCode(OK).setMessage(message);}/*** 服务器成功返回用户请求的数据* @param data 数据*/public static R ok(Object data){return new R().setMessage("OK").setCode(OK).setData(data);}/*** 用户新建或修改数据成功。*/public static R created(String message){return new R().setCode(CREATED).setMessage(message);}/*** 表示一个请求已经进入后台排队(异步任务)*/public static R accepted(String message){return new R().setCode(ACCEPTED).setMessage(message);}/*** 用户删除数据成功*/public static R noContent(String message){return new R().setCode(NO_CONTENT).setMessage(message);}/*** 用户发出的请求有错误,服务器没有进行新建或修改数据的操作。*/public static R invalidRequest(String message){return new R().setCode(INVALID_REQUEST).setMessage(message);}/*** 表示用户没有权限(令牌、用户名、密码错误)*/public static R unauthorized(String  message){return new R().setCode(UNAUTHORIZED).setMessage(message);}/*** 登录以后,但是没有足够权限*/public static R forbidden(){return new R().setCode(FORBIDDEN).setMessage("权限不足!");}/*** 用户发出的请求针对的是不存在的记录,服务器没有进行操作。*/public static R notFound(String message){return new R().setCode(NOT_FOUND).setMessage(message);}/*** 用户请求的资源被永久删除,且不会再得到的。*/public static R gone(String message){return new R().setCode(GONE).setMessage(message);}/*** 当创建一个对象时,发生一个验证错误。*/public static R unproecsableEntity(String message){return new R().setCode(UNPROCESABLE_ENTITY).setMessage(message);}/*** 将异常消息复制到返回结果中*/public static R failed(ServiceException e){return new R().setCode(e.getCode()).setMessage(e.getMessage());}/*** 服务器发生错误,用户将无法判断发出的请求是否成功。*/public static R failed(Throwable e){return new R().setCode(INTERNAL_SERVER_ERROR).setMessage(e.getMessage());}
}

步骤3:

上面两个步骤分别解决了控制器的参数和返回值的问题,

下面我们就测试一个控制器代码,观察是否能够获得参数信息,并返回

SystemController中编写代码

@RestController
@Slf4j//启动日志功能!
public class SystemController {//省略其它方法....@PostMapping("/register")public R registerStudent(RegisterVo registerVo){System.out.println(registerVo);log.debug("得到信息为:{}",registerVo);return R.created("注册成功!");}
}

步骤4:

配置/register请求的放行

SecurityConfig代码中

 http.csrf().disable().authorizeRequests()//对当前全部请求进行授权.antMatchers("/index.html","/img/*","/js/*","/css/*","/bower_components/**","/login.html","/register.html","/register"  //放行注册业务!!!!!!)//设置路径.permitAll()//允许全部请求访问上面定义的路径//其它路径需要全部进行表单登录验证.anyRequest().authenticated().and().formLogin().loginPage("/login.html").loginProcessingUrl("/login").failureUrl("/login.html?error").defaultSuccessUrl("/index.html").and().logout().logoutUrl("/logout").logoutSuccessUrl("/login.html?logout");

步骤5:

配置日志等级

在控制器的代码中我们启用了日志

需要配置debug等级才能显示在控制台

application.properties文件

logging.level.cn.tedu.straw.portal.mapper=trace
logging.level.cn.tedu.straw.portal=debug

2.3 编写注册业务逻辑

步骤1:

注册业务逻辑属于User表

所以在IUserService接口中新建注册方法

// 用户注册的方法(现在是针对学生注册)
void registerStudent(RegisterVo registerVo);

步骤2:

在IUserService的实现类UserServiceImpl类中重写接口的方法

在方法中排定业务逻辑顺序

 @Overridepublic void registerStudent(RegisterVo registerVo) {//判断registerVo非空//根据输入的邀请码查询班级,验证邀请码有效性//验证数据库中是否已经注册过输入的用户名(手机号)//User对象的赋值(将表单中的值和一些默认值确定后)//执行User新增//验证新增结果//将新增的用户赋予学生的角色(新增user_role的关系表)//验证关系表新增结果}

步骤3:

编写判定以及验证时需要的自定义业务异常类

这个类和R类相同也不需要掌握代码,只需要掌握用法

package cn.tedu.straw.portal.service;import cn.tedu.straw.portal.vo.R;public class ServiceException extends RuntimeException{private int code = R.INTERNAL_SERVER_ERROR;public ServiceException() { }public ServiceException(String message) {super(message);}public ServiceException(String message, Throwable cause) {super(message, cause);}public ServiceException(Throwable cause) {super(cause);}public ServiceException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public ServiceException(int code) {this.code = code;}public ServiceException(String message, int code) {super(message);this.code = code;}public ServiceException(String message, Throwable cause,int code) {super(message, cause);this.code = code;}public ServiceException(Throwable cause, int code) {super(cause);this.code = code;}public ServiceException(String message, Throwable cause,boolean enableSuppression, boolean writableStackTrace, int code) {super(message, cause, enableSuppression, writableStackTrace);this.code = code;}public int getCode() {return code;}/** 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作。*/public static ServiceException invalidRequest(String message){return new ServiceException(message, R.INVALID_REQUEST);}/** 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作。 */public static ServiceException notFound(String message){return new ServiceException(message, R.NOT_FOUND);}/** 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。*/public static ServiceException gone(String message){return new ServiceException(message, R.GONE);}/** 422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。 */public static ServiceException unprocesabelEntity(String message){return new ServiceException(message, R.UNPROCESABLE_ENTITY);}
}

步骤4:

完成UserServiceImpl类的编写

@Service
@Slf4j//添加了log4j的支持
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@AutowiredUserMapper userMapper;@Overridepublic UserDetails getUserDetails(String username) {// 此方法代码略}@AutowiredClassroomMapper classroomMapper;@AutowiredUserRoleMapper userRoleMapper;BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();@Overridepublic void registerStudent(RegisterVo registerVo) {//判断registerVo非空if(registerVo==null){//如果信息是空则发生异常//这里的异常逻辑是我们编写的项目发生的,不是系统异常//所以这里以及以后的方法中都需要抛出自定义的异常throw ServiceException.unprocesabelEntity("表单数据为空");}//根据输入的邀请码查询班级,验证邀请码有效性QueryWrapper<Classroom> queryWrapper=new QueryWrapper<>();queryWrapper.eq("invite_code",registerVo.getInviteCode());Classroom classroom=classroomMapper.selectOne(queryWrapper);log.debug("邀请码对应的班级为:{}",classroom);if(classroom==null){throw ServiceException.unprocesabelEntity("邀请码错误!");}//验证数据库中是否已经注册过输入的用户名(手机号)//用户名查询用户对象User u=userMapper.findUserByUsername(registerVo.getPhone());if(u!=null){//用户已存在throw ServiceException.unprocesabelEntity("手机号已经注册!");}//User对象的赋值(将表单中的值和一些默认值确定后)User user=new User();user.setUsername(registerVo.getPhone());user.setPhone(registerVo.getPhone());user.setNickname(registerVo.getNickname());//用户输入的是明文密码,数据库保存的是带算法ID的加密结果!user.setPassword("{bcrypt}"+passwordEncoder.encode(registerVo.getPassword()));user.setClassroomId(classroom.getId());user.setCreatetime(LocalDateTime.now());user.setEnabled(1);user.setLocked(0);//执行User新增int num=userMapper.insert(user);//验证新增结果if(num!=1) {throw new ServiceException("服务器忙,稍后再试");}//将新增的用户赋予学生的角色(新增user_role的关系表)UserRole userRole=new UserRole();userRole.setUserId(user.getId());userRole.setRoleId(2);num=userRoleMapper.insert(userRole);//验证关系表新增结果if(num!=1) {throw new ServiceException("服务器忙,稍后再试");}}
}

步骤5:

编写测试类

@AutowiredIUserService userService;@Testpublic void testUserService(){RegisterVo registerVo=new RegisterVo();registerVo.setPhone("13333113131");registerVo.setNickname("大树");registerVo.setInviteCode("JSD1912-876840");registerVo.setPassword("123456");registerVo.setConfirm("123456");userService.registerStudent(registerVo);System.out.println("complate!");}

2.4 注册功能的收尾

    @AutowiredIUserService userService;@PostMapping("/register")public R registerStudent(RegisterVo registerVo){System.out.println(registerVo);log.debug("得到信息为:{}",registerVo);try{userService.registerStudent(registerVo);return R.created("注册成功!");}catch (ServiceException e){log.error("注册失败",e);return R.failed(e);}}

3. VUE

3.1 VUE的基本使用

3.1.1 什么是VUE

也是一个js为基础的前端框架

提供了一套前端信息和服务器信息交互的一种方式

这种方式要比以前的信息交互方式简单

一般情况下,程序要结合JQuery的ajax操作和Vue的功能完成前后端信息交互

使用准备

Idea添加插件
在这里插入图片描述
编写html文件

static文件夹下创建一个测试Vue的页面vue.html

这个页面项目中不使用,就是测使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!-- 添加VUE的支持 --><script src="bower_components/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"><p v-text="message">VUE演示</p><input type="text" v-model="content"><button type="button" v-on:click="hello">按钮</button>
</div>
</body>
<script>//使用Vuelet app=new Vue({el:"#app",data:{message:"Vue发送的文字!",content:"输入框的内容"},methods:{hello:function(){console.log(this.content);//this.content=this.content+"!";}}});
</script>
</html>

Vue功能的强大之处在于信息实时同步的双向绑定

在这里插入图片描述

3.2 使用VUE+Ajax完善稻草问答的注册功能

修改register.html代码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>稻草FAQ注册</title><link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"><link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css"><link rel="stylesheet" href="bower_components/plugins/css/vueAlert.css"><link rel="stylesheet" href="css/login.css"><script src="bower_components/jquery/dist/jquery.min.js" ></script><script src="bower_components/bootstrap/dist/js/bootstrap.min.js" ></script><script src="bower_components/vue/dist/vue.js"></script>
</head>
<body class="bg-light"><div class="container-fluid"><div class="row"><div class="mx-auto mt-5" style="width: 400px"><div class="alsrtInfo" style="display: none"><div class="profPrompt_test" ></div></div><h2 class="text-center">达内稻草问答系统</h2><div class="bg-white p-4" id="app"><p class="text-center"><b>注册新用户</b></p><div id="error" class="alert alert-danger" style="display: none"><i class="fa fa-exclamation-triangle"></i> <span >邀请码错误!</span></div><!--v-on:submit.prevent表示绑定一个方法 ,.prevent阻止表单提交 --><form action="/register" method="post"v-on:submit.prevent="register"><div class="form-group has-icon"><input type="text" name="inviteCode" class="form-control" placeholder="请输入邀请码"required="required" v-model="inviteCode"><span class="fa fa-barcode form-control-icon"></span></div><div class="form-group has-icon"><input type="tel" name="phone" class="form-control" placeholder="请输入手机号"pattern="^\d{11}$" required="required" v-model="phone" ><span class=" fa fa-phone form-control-icon"></span></div><div class="form-group has-icon"><input type="text" name="nickname" class="form-control" placeholder="请设置昵称,字数为2-20之间"pattern="^.{2,20}$" required="required" v-model="nickname" ><span class="fa fa-user form-control-icon"></span></div><div class="form-group has-icon"><input type="password" name="password" class="form-control" placeholder="设置密码6-20个字母、数字、下划线"required="required" pattern="^\w{6,20}$" v-model="password"  ><span class="fa fa-lock form-control-icon"></span></div><div class="form-group has-icon"><input type="password" name="confirm" class="form-control" placeholder="请再次输入密码"required="required"  v-model="confirm"><span class="fa fa-lock form-control-icon"></span></div><button type="submit" class="btn btn-primary btn-block btn-flat" >注册</button></form><a href="login.html" class="text-center d-inline-block mt-3">已有账号,立即登录</a></div><!-- /.form-box --></div></div>
</div>
</body>
<script src="js/utils.js"></script>
<script src="js/register.js"></script>
</html>

修改static/js/register.js代码

let app = new Vue({el:'#app',data:{inviteCode:'',phone:'',nickname:'',password:'',confirm:''},methods:{register:function () {console.log('Submit');let data = {inviteCode: this.inviteCode,phone: this.phone,nickname: this.nickname,password: this.password,confirm: this.confirm}console.log(data);if(data.password !== data.confirm){return;}$.ajax({url:"/register",method: "POST",data: data,success: function (r) {console.log(r);if(r.code == CREATED){console.log("注册成功");console.log(r.message);}else{console.log(r.message);}}});}}
});

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

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

相关文章

Kubespray-offline v2.21.0-1 下载 Kubespray v2.22.1 离线部署 kubernetes v1.25.6

文章目录 1. 目标2. 预备条件3. vcenter 创建虚拟机4. 系统初始化4.1 配置网卡4.2 配置主机名4.3 内核参数 5. 打快照6. 安装 git7. 配置科学8. 安装 docker9. 下载介质9.1 下载安装 docker 介质9.2 下载 kubespray-offline-ansible 介质9.3 下载 kubernetes 介质 10. 搬运介质…

6.物联网操作系统信号量

一。信号量的概念与应用 信号量定义 FreeRTOS信号量介绍 FreeRTOS信号量工作原理 1.信号量的定义 多任务环境下使用&#xff0c;用来协调多个任务正确合理使用临界资源。 2.FreeRTOS信号量介绍 Semaphore包括Binary&#xff0c;Count&#xff0c;Mutex&#xff1b; Mutex包…

【2种方法,jmeter用一个正则提取器提取多个值!】

jmeter中&#xff0c;用json提取器&#xff0c;一次提取多个值&#xff0c;这个很多人都会。但是&#xff0c;用正则提取器一次提取多个&#xff0c;是否可以呢&#xff1f; 肯定&#xff0c;很多人都自信满满的说&#xff0c;可以&#xff01;形如&#xff1a;token":&q…

Jenkins触发器时间、次数设定

触发器触发条件介绍 触发器触发条件公式&#xff1a;由5颗星组成 * * * * * 分别代表&#xff1a;分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6) 企业项目中常用场景介绍 场景1&#xff1a;接口脚本部分测试通过&#xff0c;部分还在进行&#xff0c;回归测试脚本执行…

Windows上安装 jdk 环境并配置环境变量 (超详细教程)

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

torchvision.datasets数据加载失败

torchvision.datasets数据加载失败 如何使用torchvision.datasets进行自动下载数据失败&#xff0c;可以使用手动下载数据 Ctrl点击可以进入相关包文件&#xff0c;查找下载地址&#xff1a;https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 手动下载之后解压&#x…

企业微信小程序在调用wx.qy.login时返回错误信息qy.login:fail

原因是大概是绑定了多个企业但是在开发者工具中没有选择正确的企业 解决方法&#xff1a; 重新选择企业后即可成功获取code

RabbitMQ(一) - 基本结构、SpringBoot整合RabbitMQ、工作队列、发布订阅、直接、主题交换机模式

RabbitMQ结构 Publisher &#xff1a; 生产者 Queue: 存储消息的容器队列&#xff1b; Consumer:消费者 Connection&#xff1a;消费者与消息服务的TCP连接 Channel:信道&#xff0c;是TCP里面的虚拟连接。例如&#xff1a;电缆相当于TCP&#xff0c;信道是一条独立光纤束&…

web开发中的安全和防御入门——csp (content-security-policy内容安全策略)

偶然碰到iframe跨域加载被拒绝的问题&#xff0c;原因是父页面默认不允许加载跨域的子页面&#xff0c;也就是的content-security-policy中没有设置允许跨域加载。 简单地说&#xff0c;content-security-policy能限制页面允许和不允许加载的所有资源&#xff0c;常见的包括&a…

原型链污染

文章目录 1. javascript 原型链2. 原型链变量的搜索3. prototype 原型链污染4. 原型链污染例题4.1 题1&#xff1a;4.2.题2&#xff1a; 1. javascript 原型链 js在ECS6之前没有类的概念&#xff0c;之前的类都是用funtion来声明的。如下 可以看到b在实例化为test对象以后&…

【C语言进阶】指针的高级应用(下)

文章目录 一、指针数组与数组指针1.1 指针数组与数组指针的表达式 二、函数指针2.1 函数指针的书写方式 三、二重指针与一重指针3.1 二重指针的本质3.2 二重指针的用法3.3 二重指针与数组指针 总结 一、指针数组与数组指针 (1)指针数组的实质是一个数组&#xff0c;这个数组中存…

Linux进程(二)

文章目录 进程&#xff08;二&#xff09;Linux的进程状态R &#xff08;running&#xff09;运行态S &#xff08;sleeping&#xff09;阻塞状态D &#xff08;disk sleep&#xff09;深度睡眠T&#xff08;stopped&#xff09;状态X&#xff08;dead&#xff09;状态Z&#x…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--搭建Vue 前端工程[一]

文章目录 SSM--搭建Vue 前端工程--项目基础界面实现功能01-搭建Vue 前端工程需求分析/图解代码实现搭建Vue 前端工程下载node.js LTS 并安装: node.js 的npm创建Vue 项目使用idea 打开ssm_vue 项目, 并配置项目启动 Vue3 项目目录结构梳理Vue3 项目结构介绍 配置Vue 服务端口El…

Dockerfile构建mysql

使用dockerfile构建mysql详细教学加案例 Dockerfile 文件 # 使用官方5.6版本&#xff0c;latest为默认版本 FROM mysql:5.6 #复制my.cof至容器内 ADD my.cnf /etc/mysql/my.cof #设置环境变量 密码 ENV MYSQL_ROOT_PASSWORD123456my.cof 文件 [mysqld] character-set-server…

IDEA SpringBoot Maven profiles 配置

IDEA SpringBoot Maven profiles 配置 IDEA版本&#xff1a; IntelliJ IDEA 2022.2.3 注意&#xff1a;切换环境之后务必点击一下刷新&#xff0c;推荐点击耗时更短。 application.yaml spring:profiles:active: env多环境文件名&#xff1a; application-dev.yaml、 applicat…

【MATLAB第63期】基于MATLAB的改进敏感性分析方法IPCC,拥挤距离与皮尔逊系数法结合实现回归与分类预测

【MATLAB第63期】基于MATLAB的改进敏感性分析方法IPCC&#xff0c;拥挤距离与皮尔逊系数法结合实现回归与分类预测 思路 考虑拥挤距离指标与PCC皮尔逊相关系数法相结合&#xff0c;对回归或分类数据进行降维&#xff0c;通过SVM支持向量机交叉验证得到平均指标&#xff0c;来…

基于CentOS 7构建LVS-DR集群

DIPVIPRIPClient192.169.41.139 LVS 192.168.41.134192.169.41.10RS1192.168.41.135RS2192.168.41.138 要求&#xff1a; node4为客户端&#xff0c;node2为LVS&#xff0c;node3和node4为RS。 1.配置DNS解析&#xff08;我这里使用本地解析&#xff09; 192.168.41.134 www.y…

一、8.分页

当物理内存不够时就把不常用的内存暂时存入磁盘&#xff0c;并且描述符的P位置0&#xff0c;把要使用的段放入内存&#xff0c;描述符P位置1 但是这种方式会产生大量内存碎片&#xff0c;影响内存分配效率 设想一个虚拟内存&#xff0c;每隔任务都有他独立的虚拟内存&#xf…

golang pprof 监控系列—— cpu 占用率 统计原理

经过前面的几节对pprof的介绍&#xff0c;对pprof统计的原理算是掌握了七八十了&#xff0c;我们对memory,block,mutex,trace,goroutine,threadcreate这些维度的统计原理都进行了分析&#xff0c;但唯独还没有分析pprof 工具是如何统计cpu使用情况的&#xff0c;今天我们来分析…

[Pytorch]卷积运算conv2d

文章目录 [Pytorch]卷积运算conv2d一.F.Conv2d二.nn.Conv2d三.nn.Conv2d的运算过程 [Pytorch]卷积运算conv2d 一.F.Conv2d torch.nn.functional.Conv2d()的详细参数&#xff1a; conv2d(input: Tensor, weight: Tensor, bias: Optional[Tensor]None, stride: Union[_int, _s…