统一响应,自定义校验器,自定义异常,统一异常处理器

文章目录

    • 1.基本准备(构建一个SpringBoot模块)
        • 1.在A_universal_solution模块下创建新的子模块unified-processing
        • 2.pom.xml引入基本依赖
        • 3.编写springboot启动类
        • 4.启动测试
    • 2.统一响应处理
        • 1.首先定义一个响应枚举类 RespBeanEnum.java 每个枚举对象都有code和message
        • 2.然后定义一个响应的Bean RespBean.java ,可以调用响应枚举类,进行响应
        • 3.测试使用
          • 1.目录结构
          • 2.ResponseTest.java
          • 3.浏览器测试
            • 1.成功响应,不携带数据。
            • 2.成功响应,携带数据。
            • 3.失败响应,不携带数据。
            • 4.失败响应,携带数据。
            • 5.测试withData方法。
            • 6.测试withMessage方法。
    • 3.自定义校验器
        • 1.首先编写一个Bean测试使用,LoginVo.java
        • 2.需求分析
          • 自定义校验器来校验手机号和密码
        • 3.通用校验器模板
          • 1.定义通用校验器接口 GenericValidatorInterface.java
          • 2.自定义校验注解 GenericValidation.java
          • 3.通用校验器实现类 GenericValidatorImpl.java
          • 4.使用方式
            • 1.需求分析
            • 2.将模板复制一份,放到validator包下,准备进行修改
            • 3.要校验的字段为Integer类型,也就是修改value类型
            • 4.注解中的value是int数组类型,也就是修改annotationValue的类型
            • 5.修改三个类的名字前缀为Test,直接修改然后alter +enter 让IDEA自动修改
            • 6.TestValidatorImpl.java编写校验逻辑
            • 7.修改LoginVo.java 添加测试校验字段
            • 8.编写controller加上@Valid字段进行校验
            • 9.测试
    • 4.统一异常处理器整合自定义校验器
        • 1.编写自定义异常携带响应枚举对象 CustomException.java
        • 2.编写全局异常处理器 GlobalExceptionHandler.java
        • 3.最佳实践
          • 1.当需要响应error时直接抛出自定义异常对象,指定响应枚举对象
          • 2.此时当出现参数绑定异常时也会交给统一异常处理解决
          • 3.当出现其他异常时,就会响应服务端异常,控制台也会打印错误信息

1.基本准备(构建一个SpringBoot模块)

1.在A_universal_solution模块下创建新的子模块unified-processing

image-20240506125441280

2.pom.xml引入基本依赖
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 继承spring-boot父模块 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.4</version><relativePath/> <!-- 如果交给父模块统一管理,但是又要继承springboot的父模块,就必须加这个 --></parent><artifactId>unified-processing</artifactId><packaging>jar</packaging><name>unified-processing</name><url>http://maven.apache.org</url><!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 --><properties><java.version>1.8</java.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!--validation 参数校验--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>2.4.5</version></dependency><!-- springboot两个常规配置 --><!-- spring-boot-starter-web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- spring-boot-starter-test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- lombok也是常规配置 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- jupiter测试 --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.7.2</version><scope>compile</scope></dependency></dependencies><!-- maven打包插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
3.编写springboot启动类
package com.sun.solution;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** Description:** @Author sun* @Create 2024/5/6 13:00* @Version 1.0*/
@SpringBootApplication
public class UnifiedApplication {public static void main(String[] args) {SpringApplication.run(UnifiedApplication.class, args);}
}
4.启动测试

image-20240506130251247

2.统一响应处理

1.首先定义一个响应枚举类 RespBeanEnum.java 每个枚举对象都有code和message
package com.sxs.seckill.vo;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;/*** Description: 响应枚举类** @Author sun* @Create 2024/5/5 15:15* @Version 1.0*/@Getter
@AllArgsConstructor
@ToString
public enum RespBeanEnum {// 通用SUCCESS(200, "SUCCESS"),ERROR(500, "服务端异常"),//登录模块LOGIN_ERROR(500210, "用户名或者密码错误"),MOBILE_ERROR(500211, "手机号码格式不正确"),BING_ERROR(500212, "参数绑定异常"),MOBILE_NOT_EXIST(500213, "手机号码不存在"),PASSWORD_UPDATE_FAIL(500214, "更新密码失败");//其他模块。。。// 响应码和响应信息private final Integer code;private final String message;
}
2.然后定义一个响应的Bean RespBean.java ,可以调用响应枚举类,进行响应
package com.sxs.seckill.vo;import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;/*** 通用响应数据封装类。* 提供了构造函数和静态方法来创建响应对象,支持链式调用来设置属性。*/
@Getter
@Setter
@Accessors(chain = true) // 支持链式调用
public class RespBean {private long code;private String message;private Object data;/*** 默认构造函数。*/public RespBean() {}/*** 构造函数,初始化响应码和消息。* @param code 响应码。* @param message 响应消息。*/public RespBean(long code, String message) {this.code = code;this.message = message;}/*** 构造函数,初始化响应码、消息和数据。* @param code 响应码。* @param message 响应消息。* @param data 响应数据。*/public RespBean(long code, String message, Object data) {this.code = code;this.message = message;this.data = data;}/*** 成功响应,携带数据。* @param data 响应数据。* @return 生成的成功响应对象。*/public static RespBean success(Object data) {return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), data);}/*** 成功响应,不携带数据。* @return 生成的成功响应对象。*/public static RespBean success() {return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), null);}/*** 错误响应,只携带错误枚举。* @param respBeanEnum 错误枚举,包含错误码和消息。* @return 生成的错误响应对象。*/public static RespBean error(RespBeanEnum respBeanEnum) {return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), null);}/*** 错误响应,携带错误枚举和额外数据。* @param respBeanEnum 错误枚举,包含错误码和消息。* @param data 额外数据。* @return 生成的错误响应对象。*/public static RespBean error(RespBeanEnum respBeanEnum, Object data) {return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), data);}/*** 设置响应数据。* @param data 响应数据。* @return 当前对象,支持链式调用。*/public RespBean withData(Object data) {this.data = data;return this;}/*** 设置响应消息。* @param message 响应消息。* @return 当前对象,支持链式调用。*/public RespBean withMessage(String message) {this.message = message;return this;}
}
3.测试使用
1.目录结构

image-20240506131857665

2.ResponseTest.java
package com.sun.solution.conroller;import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.unified_response_processing.RespBeanEnum;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** Description:** @Author sun* @Create 2024/5/6 13:07* @Version 1.0*/
@RestController
public class ResponseTest {/*** 成功响应,不携带数据。** @return*/@RequestMapping("/success1")public RespBean success1() {return RespBean.success();}/*** 成功响应,携带数据。** @return*/@RequestMapping("/success2")public RespBean success2() {return RespBean.success("成功响应,携带数据。");}/*** 失败响应,不携带数据。** @return*/@RequestMapping("/error1")public RespBean error1() {return RespBean.error(RespBeanEnum.ERROR);}/*** 失败响应,携带数据。** @return*/@RequestMapping("/error2")public RespBean error2() {return RespBean.error(RespBeanEnum.ERROR, "失败响应,携带数据。");}/*** 测试withData方法** @return*/@RequestMapping("/withData")public RespBean withData() {return RespBean.error(RespBeanEnum.ERROR).withData("测试withData方法");}/*** 测试withMessage方法** @return*/@RequestMapping("/withMessage")public RespBean withMessage() {return RespBean.error(RespBeanEnum.ERROR).withMessage("测试withMessage方法");}}
3.浏览器测试
1.成功响应,不携带数据。

image-20240506132159483

2.成功响应,携带数据。

image-20240506132322584

3.失败响应,不携带数据。

image-20240506132344487

4.失败响应,携带数据。

image-20240506132403115

5.测试withData方法。

image-20240506132427551

6.测试withMessage方法。

image-20240506132447397

3.自定义校验器

1.首先编写一个Bean测试使用,LoginVo.java
package com.sun.solution.vo;import lombok.Data;/*** Description:** @Author sun* @Create 2024/5/6 13:29* @Version 1.0*/
@Data
public class LoginVo {private String mobile;private String password;
}
2.需求分析
自定义校验器来校验手机号和密码
3.通用校验器模板
1.定义通用校验器接口 GenericValidatorInterface.java
package com.sun.solution.validator;/*** Description: 通用校验器接口,用于重新定义校验方法,使其更加灵活** @Author sun* @Create 2024/5/6 13:34* @Version 1.0*/public interface GenericValidatorInterface {/*** 校验接口* @param value 待校验的值,根据情况自定义类型* @param annotationValue 注解中的value值,根据情况自定义类型* @param required 是否必填* @return*/boolean isValid(String value, String annotationValue, boolean required);
}
2.自定义校验注解 GenericValidation.java
package com.sun.solution.validator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;/*** Description: 自定义校验注解** @Author sun* @Create 2024/5/6 13:38* @Version 1.0*/
@Documented
@Constraint(validatedBy = GenericValidatorImpl.class) // 1.这里是校验器的实现类
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface GenericValidation {// 2.这里是注解的属性// message是校验失败时的提示信息String message() default "校验失败!";// value是注解的值,可以根据情况自定义类型,类型改变则校验器也需要改变String value() default "";// required是是否必填boolean required() default true;// 下面这两个属性必须添加,是默认属性Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
3.通用校验器实现类 GenericValidatorImpl.java
package com.sun.solution.genericvalidator;import org.springframework.util.StringUtils;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;/*** Description: 通用校验器实现类,ConstraintValidator<TestValidation, String>中的两个参数分别是注解和校验的值类型** @Author sun* @Create 2024/5/6 13:42* @Version 1.0*/
public class GenericValidatorImpl implements ConstraintValidator<GenericValidation, String>, GenericValidatorInterface {// 注解中的value值,根据情况自定义类型private String annotationValue;// 注解中的required值,表示是否必填private boolean required;/*** 初始化方法,获取注解中的value值和required值* @param annotation*/@Overridepublic void initialize(GenericValidation annotation) {this.annotationValue = annotation.value();this.required = annotation.required();}/*** 初始的校验方法* @param value* @param context* @return*/@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {return isValid(value, annotationValue, required);}/*** 增强的校验方法* @param value 待校验的值* @param annotationValue 注解中的value值,根据情况自定义类型* @param required 是否必填* @return*/@Overridepublic boolean isValid(String value, String annotationValue, boolean required) {// 校验逻辑编写,根据三个参数进行校验return false;}
}
4.使用方式
1.需求分析

假设,要校验的字段类型是Integer类型,注解中的value是int数组类型

2.将模板复制一份,放到validator包下,准备进行修改

image-20240506142134488

3.要校验的字段为Integer类型,也就是修改value类型

GenericValidatorInterface.java

image-20240506142712265

GenericValidatorImpl.java

image-20240506142756701

4.注解中的value是int数组类型,也就是修改annotationValue的类型

GenericValidation.java

image-20240506143335834

GenericValidatorImpl.java

image-20240506143407645

GenericValidatorInterface.java

image-20240506143434441

5.修改三个类的名字前缀为Test,直接修改然后alter +enter 让IDEA自动修改

image-20240506143656011

6.TestValidatorImpl.java编写校验逻辑
    /*** 增强的校验方法* @param value 待校验的值* @param annotationValue 注解中的value值,根据情况自定义类型* @param required 是否必填* @return*/@Overridepublic boolean isValid(Integer value, int[] annotationValue, boolean required) {// 如果不是必填项,且值为空,则直接返回trueif (!required && value == null) {return true;}// 如果是必填项,且值为空,则直接返回falseif (required && value == null) {return false;}// 如果注解中的value值不为空,且待校验的值不在value值中,则返回falseif (annotationValue.length > 0) {for (int i : annotationValue) {if (value == i) {return true;}}return false;}return true;}
7.修改LoginVo.java 添加测试校验字段
package com.sun.solution.vo;import com.sun.solution.validator.TestValidation;
import lombok.Data;/*** Description:** @Author sun* @Create 2024/5/6 13:29* @Version 1.0*/
@Data
public class LoginVo {private String mobile;private String password;@TestValidation(value = {1, 2, 3}, required = true)private Integer test;
}
8.编写controller加上@Valid字段进行校验
package com.sun.solution.conroller;import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.vo.LoginVo;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;/*** Description:** @Author sun* @Create 2024/5/6 14:56* @Version 1.0*/
@RestController
public class ValidationTest {@PostMapping("/test")public RespBean test(@Valid @RequestBody LoginVo loginVo) {return RespBean.success("success!");}
}
9.测试

image-20240506150821623

image-20240506150835102

4.统一异常处理器整合自定义校验器

1.编写自定义异常携带响应枚举对象 CustomException.java
package com.sun.solution.exception;import com.sun.solution.unified_response_processing.RespBeanEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** Description: 自定义异常类,具有响应枚举的属性。** @Author sun* @Create 2024/5/6 15:15* @Version 1.0*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomException extends RuntimeException{private RespBeanEnum respBeanEnum;
}
2.编写全局异常处理器 GlobalExceptionHandler.java
package com.sun.solution.exception;import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.unified_response_processing.RespBeanEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** Description:** @Author sun* @Create 2024/5/6 15:16* @Version 1.0*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {// 处理所有的异常@ExceptionHandler(Exception.class)public RespBean exceptionHandler(Exception e) {// 日志记录异常信息及堆栈log.error("Exception caught: ", e); // 如果得到的是自定义异常的对象,那么直接返回这个异常的响应枚举类信息if (e instanceof CustomException) {CustomException ex = (CustomException) e;return RespBean.error(ex.getRespBeanEnum());} else if (e instanceof BindException) {// 如果是绑定异常,就获取绑定异常的message信息,返回给前端// 需要获取改异常 BindException,进行打印BindException ex = (BindException) e;// 获取绑定异常的信息RespBean respBean = RespBean.error(RespBeanEnum.BING_ERROR).withMessage("参数校验异常:" +ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());return respBean;}// 如果不是自定义异常,那么返回服务端异常return RespBean.error(RespBeanEnum.ERROR);}
}
3.最佳实践
1.当需要响应error时直接抛出自定义异常对象,指定响应枚举对象

image-20240506153836780

image-20240506153848112

2.此时当出现参数绑定异常时也会交给统一异常处理解决

image-20240506154042389

3.当出现其他异常时,就会响应服务端异常,控制台也会打印错误信息

image-20240506154219232

image-20240506154225690

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

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

相关文章

信息学奥赛初赛天天练-20-完善程序-vector数组参数引用传递、二分中值与二分边界应用的深度解析

PDF文档公众号回复关键字:20240605 1 2023 CSP-J 完善程序1 完善程序&#xff08;单选题&#xff0c;每小题 3 分&#xff0c;共计 30 分&#xff09; 原有长度为 n1,公差为1等升数列&#xff0c;将数列输到程序的数组时移除了一个元素&#xff0c;导致长度为 n 的开序数组…

云原生架构案例分析_5.某体育用品公司云原生架构的业务中台构建

1.背景和挑战 某体育用品公司作为中国领先的体育用品企业之一&#xff0c;在2016年&#xff0c;某体育用品公司启动集团第三次战略升级&#xff0c;打造以消费者体验为核心的“3”&#xff08;“互联网”、“体育”和“产品”&#xff09;的战略目标&#xff0c;积极拥抱云计算…

NeuralForecast TokenEmbedding 一维卷积 (Conv1d) 与矩阵乘法

NeuralForecast TokenEmbedding 一维卷积 (Conv1d) 与矩阵乘法 flyfish TokenEmbedding中使用了一维卷积 (Conv1d) TokenEmbedding 源码分析 在源码的基础上增加调用示例 下面会分析这段代码 import torch import torch.nn as nn class TokenEmbedding(nn.Module):def __i…

SEO 与 PPC 之间的区别

按点击付费 &#xff08;PPC&#xff09;&#xff1a; PPC 是一种网络营销技术&#xff0c;广告商在每次点击广告时向网站支付一定金额&#xff0c;广告商只为符合条件的点击付费。Google 广告、Bing 和 Yahoo 广告基于按点击付费的概念。PPC是用于在搜索引擎首页上列出的最快方…

鸿蒙开发接口安全:【@system.cipher (加密算法)】

加密算法 说明&#xff1a; 本模块首批接口从API version 3开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import cipher from system.ciphercipher.rsa rsa(Object): void RSA 算法加解密。 系统能力&#xff1a; SystemCapabil…

K8S==ingress配置自签名证书

安装openssl Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions 生成证书 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.local.key -out example.local.crt -subj "/CNexample.local/Oexample.local"创建K8S secr…

【简单讲解TalkingData的数据统计】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Vue3中的常见组件通信之mitt

Vue3中的常见组件通信之mitt 概述 ​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refs、parent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。 组件关系传递方式父传子1. props2. v-model3. $refs…

用例篇03

正交表 因素&#xff1a;存在的条件 水平&#xff1a;因素的取值 最简单的正交表&#xff1a;L4(2) 应用 allpairs 来实现正交表。 步骤&#xff1a; 1.根据需求找出因素和水平 2.将因素和水平写入到excel表格中&#xff08;表格不需要保存&#xff09;&#xff08;推荐用…

SpaceX 首席火箭着陆工程师 MIT论文详解:非凸软着陆最优控制问题的控制边界和指向约束的无损凸化

上一篇blog翻译了 Lars Blackmore(Lars Blackmore is principal rocket landing engineer at SpaceX)的文章&#xff0c;SpaceX 使用 CVXGEN 生成定制飞行代码,实现超高速机载凸优化。利用地形相对导航实现了数十米量级的导航精度,着陆器在着陆过程中成像行星表面并将特征与机载…

PHP序列化、反序列化

目录 一、PHP序列化&#xff1a;serialize() 1.对象序列化 2.pop链序列化 3.数组序列化 二、反序列化&#xff1a;unserialize() 三、魔术方法 ​四、NSSCTF相关简单题目 1.[SWPUCTF 2021 新生赛]ez_unserialize 2.[SWPUCTF 2021 新生赛]no_wakeup 学习参考&#xff1…

解决MAC M1 Docker Desktop启动一直在starting

问题描述&#xff1a; 今天使用docker buildx 构建Multi-platform&#xff0c;提示如下错误&#xff1a; ERROR: Multi-platform build is not supported for the docker driver. Switch to a different driver, or turn on the containerd image store, and try again. 于是按…

EasyRecovery2024破解版本下载,电脑数据恢复新突破!

在当今数字化时代&#xff0c;数据安全和软件版权已成为全球关注的热点。EasyRecovery&#xff0c;作为一款广受欢迎的数据恢复软件&#xff0c;因其强大的数据恢复功能而深受用户喜爱。然而&#xff0c;随着“EasyRecovery2024 crack”关键词的流行&#xff0c;我们不得不面对…

电子电气架构 —— 刷写模式:并行刷写

电子电气架构 —— 刷写模式:并行刷写 我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人们会在生活中不断攻击你。他们的主要武器是向你灌输对自己的怀疑:你的价值、你的能力、你的潜力。他们往往会将此…

【深度学习入门篇一】阿里云服务器(不需要配环境直接上手跟学代码)

前言 博主刚刚开始学深度学习&#xff0c;配环境配的心力交瘁&#xff0c;一塌糊涂&#xff0c;不想配环境的刚入门的同伴们可以直接选择阿里云服务器 阿里云天池实验室&#xff0c;在入门阶段跑个小项目完全没有问题&#xff0c;不要自己傻傻的在那配环境配了半天还不匹配&a…

【ARM Cache 系列文章 2.1 -- Cache PoP 及 PoDP 介绍】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 PoP 及 PoDPCache PoDPCache PoP应用和影响PoP 及 PoDP Cache PoDP 点对深度持久性(Point of Deep Persistence, PoDP)是内存系统中的一个点,在该点达到的任何写操作即使在系统供电…

石油行业的数字化转型与智能化发展:新技术综合运用助力业务提升

引言 石油行业面临的挑战与机遇 石油行业是全球能源供应的重要支柱&#xff0c;然而&#xff0c;随着资源枯竭、环境压力增加以及市场竞争加剧&#xff0c;石油企业面临着前所未有的挑战。传统的勘探和生产方式已经难以满足当前高效、安全、环保的要求。同时&#xff0c;能源转…

用幻灯片来解释C/C++指针及运算

在互联网上发现了一个很好的C入门学习网站&#xff0c;用各种图表和幻灯片来学习C知识&#xff0c;非常直观&#xff0c;一目了然&#xff0c;比看文字更容易理解。做个搬运工用中文分享一下C/C最难懂的的内存指针的讲解&#xff0c;由浅入深的将指针解释的很清楚易懂&#xff…

web刷题记录(3)

[NISACTF 2022]checkin 简单的get传参,好久没做过这么简单的题了 王德发&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff01;&#xff0c;看了源代码以后&#xff0c;本来以为是js脚本的问题&#xff0c;但是禁用js脚本没用&#xff0c;看了大佬的wp以后…

鸿蒙轻内核M核源码分析系列六 任务及任务调度(2)任务模块

任务是操作系统一个重要的概念&#xff0c;是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它任务运行。鸿蒙轻内核的任务模块可以给用户提供多个任务&#xff0c;实现任务间的切换&#xff0c;帮助用户管理业务程序流程。…