当前位置: 首页 > news >正文

基于常用设计模式的业务框架

前言

做开发也有好几年时间了,最近总结和梳理自己在工作中遇到的一些问题,工作中最容易写出BUG的需求就是改造需求了。一个成熟的业务系统是需要经过无数次迭代而成的,也意味着经过很多开发人员之手,最后到你这里,大部分时间都是在梳理代码,理解别人的用意。有的业务功能里面一堆IF嵌套嵌套,耦合度太过,理解起来比较费劲,也容易改出BUG。

不同人有不同的编码习惯,这没有办法,但如果系统中能用一些常用的设计模式来编码,那多多少少能增加可读性,降低耦合度,所以想做出几种常用的设计模式工具类,开发时可以直接使用,让我们更加专注于业务代码开发。

正文

框架基于常用的设计模式,策略模式、模板方法模式、工厂模式、责任链模式等,结合Spring IOC,Spring AOP,Springboot自动装配;

Github地址:点击查看

主要有4个通用的设计模式处理器:

通用策略模式处理器

业务场景

购买保险产品的费用计算方法有多种,按日计算、按月计算、按费率表计算。不同产品可选择的计费选项可能不一样,如下:

日计算(01):支持 A产品、B产品

月计算(02):支持 A产品、C产品

费率表计算(03):支持 A产品、B产品、C产品

代码演示

        //计算类型String calculateType="01";//产品编号String productNo="A";if(calculateType.equals("01")){if ("A,B".contains(productNo)){//按日计算}}else if(calculateType.equals("02")){if ("A,C".contains(productNo)){//按月计算}}else if(calculateType.equals("03")){if ("A,B,C".contains(productNo)){//按费率表计算}}

上面这种场景如果使用 if…else…处理的话,随着代码不断迭代,其可读性、调整成本会变得越来越大;

下面使用策略模式来演示:

定义处理器,继承策略处理器接口

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.handle.strategy.AbstractBHandle;
import com.zdc.business.business.wrapper.CommonBName;import java.util.Arrays;/*** @Author:猪大肠* @Package:com.example.btest.strategy* @Date:2023/5/11 20:14* @Wechat:DDOS12345H* 按日计算*/
@BComponent
public class Calculate01Handle extends AbstractBHandle<RequestDto,ResponseDto> {@Overridepublic boolean before(RequestDto requestDto) {return true;}@Overridepublic boolean after(RequestDto requestDto) {return true;}@Overridepublic ResponseDto doExecute(RequestDto requestDto) {System.out.println("按日计算");return null;}@Overridepublic CommonBName getName() {//定义该处理器的类型名称,以及支持的别名集;执行时按这两个维度匹配处理器return new CommonBName<String>("01", Arrays.asList("A","B"));}
}
import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.handle.strategy.AbstractBHandle;
import com.zdc.business.business.wrapper.CommonBName;import java.util.Arrays;/*** @Author:猪大肠* @Package:com.example.btest.strategy* @Date:2023/5/11 20:14* @Wechat:DDOS12345H* 按日计算*/
@BComponent
public class Calculate02Handle extends AbstractBHandle<RequestDto,ResponseDto> {@Overridepublic boolean before(RequestDto requestDto) {return true;}@Overridepublic boolean after(RequestDto requestDto) {return true;}@Overridepublic ResponseDto doExecute(RequestDto requestDto) {System.out.println("按月计算");return null;}@Overridepublic CommonBName getName() {//定义该处理器的类型名称,以及支持的别名集;执行时按这两个维度匹配处理器return new CommonBName<String>("02", Arrays.asList("A","C"));}
}
import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.handle.strategy.AbstractBHandle;
import com.zdc.business.business.wrapper.CommonBName;import java.util.Arrays;/*** @Author:猪大肠* @Package:com.example.btest.strategy* @Date:2023/5/11 20:14* @Wechat:DDOS12345H* 按日计算*/
@BComponent
public class Calculate03Handle extends AbstractBHandle<RequestDto,ResponseDto> {@Overridepublic boolean before(RequestDto requestDto) {return true;}@Overridepublic boolean after(RequestDto requestDto) {return true;}@Overridepublic ResponseDto doExecute(RequestDto requestDto) {System.out.println("按费率表计算");return null;}@Overridepublic CommonBName getName() {//定义该处理器的类型名称,以及支持的别名集;执行时按这两个维度匹配处理器return new CommonBName<String>("03", Arrays.asList("A","B","C"));}
}

定义入参类、出参类;

/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
public class ResponseDto {//...
}
/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
public class ResponseDto {//...
}

运行用例

import com.zdc.business.business.context.StrategyBContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** @Author:猪大肠* @Package:com.example.btest.strategy* @Date:2023/5/10 19:21* @Wechat:DDOS12345H*/
public class StartApp {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext("com.example.btest");StrategyBContext strategyBContext = (StrategyBContext) applicationContext.getBean("strategyBContext");//计算类型String calculateType="01";//产品编号String productNo="A";RequestDto requestDto=new RequestDto();ResponseDto execute = strategyBContext.invoke(calculateType,productNo,requestDto,ResponseDto.class);}
}

在这里插入图片描述

通用适配器模式处理器

业务场景

现有公司A和公司B进行投保出单,出完单后需要通知相关人员。

公司A:需要邮件、短信通知投保人;

公司B:需要邮件、短信通知被保人,企信通知业务员;

代码演示

/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
@Data
public class RequestDto {//定义请求参数String companyType;}
/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
public class ResponseDto {//定义相应参数
}

定义A公司适配器

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.factory.IAdapterEnumBFactory;
import com.zdc.business.business.handle.adapter.AbstractHandlesAdapter;/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:46* @Wechat:DDOS12345H*/
@BComponent
public class NotifyCompanyA extends AbstractHandlesAdapter<RequestDto, ResponseDto> {@Overridepublic boolean isSupport(RequestDto context) {//该方法用于编写适配条件if (context.getCompanyType().equals("A")){return true;}return false;}@Overridepublic ResponseDto execute(RequestDto context) {System.out.println("发邮件通知投保人");System.out.println("发短信通知投保人");return null;}@Overridepublic IAdapterEnumBFactory getType() {//定义该适配器归属类型return ChannelIAdapterEnumBFactory.CHANNEL_NOTIFY;}
}

定义枚举参数

import com.zdc.business.business.factory.IAdapterEnumBFactory;
import lombok.AllArgsConstructor;
import lombok.Getter;/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 22:30* @Wechat:DDOS12345H*/
@Getter
@AllArgsConstructorpublic enum  ChannelIAdapterEnumBFactory implements IAdapterEnumBFactory {CHANNEL_NOTIFY("notify",10,"公司消息通知处理器"),;String type;int priorityOrder;String description;
}

定义B公司通知适配器

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.factory.IAdapterEnumBFactory;
import com.zdc.business.business.handle.adapter.AbstractHandlesAdapter;/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:46* @Wechat:DDOS12345H*/
@BComponent
public class NotifyCompanyB extends AbstractHandlesAdapter<RequestDto, ResponseDto> {@Overridepublic boolean isSupport(RequestDto context) {//该方法用于编写适配条件if (context.getCompanyType().equals("B")){return true;}return false;}@Overridepublic ResponseDto execute(RequestDto context) {System.out.println("发邮件通知投保人");System.out.println("发短信通知投保人");System.out.println("企信通知业务员");return null;}@Overridepublic IAdapterEnumBFactory getType() {//定义该适配器归属类型return ChannelIAdapterEnumBFactory.CHANNEL_NOTIFY;}
}

入口代码

import com.zdc.business.business.context.AdapterBContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 21:15* @Wechat:DDOS12345H*/
public class StratApp {public static void main(String[] args) {//SpringBoot环境下可直接使用@AutowireAnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext("com.example.btest");AdapterBContext adapterBContext = (AdapterBContext) applicationContext.getBean("adapterBContext");//假设当前是A公司投保RequestDto requestDto=new RequestDto();requestDto.setCompanyType("A");ResponseDto execute = adapterBContext.execute(ChannelIAdapterEnumBFactory.CHANNEL_NOTIFY.type, requestDto, ResponseDto.class);}
}

在这里插入图片描述

通用责任链模式处理器

业务场景

在录单系统中,录单员填写完资料,通常下一步需要提交审核,而在正式提交审核之前,系统需要校验数据是否符合要求。某些场景下不想完全卡主流程,通常会以软提示的方式在前端进行提醒;现有以下4种软提示校验(从上到下校验顺序):

在这里插入图片描述

为了提高体验,当系统抛出资料A校验后,录单员点击“是”进行重新提交,此时由于前面已经点击了“是”了,此时后端不应该再对点击”是“的校验器进行校验。通常这种需要给每个校验器都设置一个标识,当为“是”时,后端跳过校验,但如果校验场景较多时,那代码将难以维护。

现使用责任链模式来处理以上场景

代码演示

定义好请求参数类和相应参数类

import lombok.AllArgsConstructor;
import lombok.Data;/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
@Data
@AllArgsConstructor
public class RequestDto {String data;
/*** @Author:猪大肠* @Package:com.example.btest.adapter* @Date:2023/5/10 20:48* @Wechat:DDOS12345H*/
public class ResponseDto {
}
import com.zdc.business.business.factory.IChainsEnumBFactory;
import lombok.AllArgsConstructor;
import lombok.Getter;/*** @Author:猪大肠* @Package:com.example.btest.chain* @Date:2023/5/11 21:04* @Wechat:DDOS12345H*/
@Getter
@AllArgsConstructor
public enum OrderCheckEnumBFactory implements IChainsEnumBFactory {ORDER_CHECK_SOFT_A("order","checkA",0,"资料A校验器"),ORDER_CHECK_SOFT_B("order","checkB",1,"资料B校验器"),ORDER_CHECK_SOFT_C("order","checkC",2,"资料C校验器"),;//处理器类型,标记所属链String type;//处理器名称String name;//优先级顺序int priorityOrder;//描述String description;
}

自定义异常类

import lombok.AllArgsConstructor;
import lombok.Data;/*** @Author:猪大肠* @Package:com.example.btest.chain* @Date:2023/5/11 21:12* @Wechat:DDOS12345H*/
@AllArgsConstructor
@Data
public class SoftTipException extends RuntimeException{private String code;private String desc;}

定义校验器

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.factory.IChainsEnumBFactory;
import com.zdc.business.business.handle.chains.AbstractChainHandle;/*** @Author:猪大肠* @Package:com.example.btest.chain* @Date:2023/5/11 21:02* @Wechat:DDOS12345H*/
@BComponent
public class CheckAHandle extends AbstractChainHandle<RequestDto,ResponseDto> {@Overridepublic ResponseDto execute(RequestDto context) {System.out.println("校验器A");if (context.equals("A")){//抛出异常,返回下个处理器名称;下次携带这个名称来找到当前节点throw new SoftTipException(getNextNode()==null?"succeed":getNextNode().getHandleName(),"资料A可能存在风险,是否继续提交?");}else{//调用下个节点校验器executeNextNode(context);}return null;}@Overridepublic IChainsEnumBFactory getType() {return OrderCheckEnumBFactory.ORDER_CHECK_SOFT_A;}
}
import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.factory.IChainsEnumBFactory;
import com.zdc.business.business.handle.chains.AbstractChainHandle;/*** @Author:猪大肠* @Package:com.example.btest.chain* @Date:2023/5/11 21:02* @Wechat:DDOS12345H*/
@BComponent
public class CheckBHandle extends AbstractChainHandle<RequestDto,ResponseDto> {@Overridepublic ResponseDto execute(RequestDto context) {System.out.println("校验器B");if (context.equals("B")){//抛出异常,返回下个处理器名称;下次携带这个名称来找到当前节点throw new SoftTipException(getNextNode()==null?"succeed":getNextNode().getHandleName(),"资料B可能存在风险,是否继续提交?");}else{//调用下个节点校验器executeNextNode(context);}return null;}@Overridepublic IChainsEnumBFactory getType() {return OrderCheckEnumBFactory.ORDER_CHECK_SOFT_B;}
}
import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.factory.IChainsEnumBFactory;
import com.zdc.business.business.handle.chains.AbstractChainHandle;/*** @Author:猪大肠* @Package:com.example.btest.chain* @Date:2023/5/11 21:02* @Wechat:DDOS12345H*/
@BComponent
public class CheckCHandle extends AbstractChainHandle<RequestDto,ResponseDto> {@Overridepublic ResponseDto execute(RequestDto context) {System.out.println("校验器C");if (context.equals("C")){//抛出异常,返回下个处理器名称;下次携带这个名称来找到当前节点throw new SoftTipException(getNextNode()==null?"succeed":getNextNode().getHandleName(),"资料C可能存在风险,是否继续提交?");}else{//调用下个节点校验器executeNextNode(context);}return null;}@Overridepublic IChainsEnumBFactory getType() {return OrderCheckEnumBFactory.ORDER_CHECK_SOFT_C;}
}

运行用例

import com.zdc.business.business.context.ChainsBContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** @Author:猪大肠* @Package:com.example.btest.strategy* @Date:2023/5/10 19:21* @Wechat:DDOS12345H*/
public class StartApp {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext("com.example.btest");ChainsBContext chainsBContext = (ChainsBContext) applicationContext.getBean("chainsBContext");//校验标识String checkFlag="checkB";if (!"succeed".equals(checkFlag)){if ("start".equals(checkFlag)){chainsBContext.start("order",new RequestDto(checkFlag),null);}chainsBContext.execute("order",checkFlag,new RequestDto(checkFlag),null);}}
}

在这里插入图片描述

通用代理模式处理器

业务场景

与其它周边系统进行交互时,需要将请求报文和响应报文记录到ES中,方便后续排查,并对请求报文加密加签名,响应报文解密验签;

考虑到复用性等方面,所以这里使用代理模式来增强方法最合适不过了。

代码演示

定义ES日志记录增强器

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.handle.proxy.AbstractBEnhanceIntecepter;
import com.zdc.business.business.wrapper.IntecepterProceedWrapper;/*** @Author:猪大肠* @Package:com.example.btest.aop* @Date:2023/5/11 22:58* @Wechat:DDOS12345H*/
@BComponent
public class EnhanceEsHandle extends AbstractBEnhanceIntecepter {@Overridepublic Object execute(IntecepterProceedWrapper ipw) {//方法参数Object[] args = ipw.getArgs();System.out.println("请求参数:"+args[0].toString());//调用真正的执行方法Object result = ipw.proceed();System.out.println("响应参数:"+args[0].toString());return result;}
}

加解密增强器

import com.zdc.business.business.annotation.BComponent;
import com.zdc.business.business.handle.proxy.AbstractBEnhanceIntecepter;
import com.zdc.business.business.wrapper.IntecepterProceedWrapper;/*** @Author:猪大肠* @Package:com.example.btest.aop* @Date:2023/5/11 22:58* @Wechat:DDOS12345H*/
@BComponent
public class EnhanceEncryHandle extends AbstractBEnhanceIntecepter {@Overridepublic Object execute(IntecepterProceedWrapper ipw) {//方法参数Object[] args = ipw.getArgs();System.out.println("对请求报文加密:");System.out.println("对请求报文加签:");//调用真正的执行方法Object result = ipw.proceed();System.out.println("对请求报文解密:");System.out.println("对请求报文验签:");return result;}
}

被增强类

import com.zdc.business.business.annotation.InterceptorEnhance;
import org.springframework.stereotype.Component;/*** @Author:猪大肠* @Package:com.example.btest.aop* @Date:2023/5/11 23:06* @Wechat:DDOS12345H*/
@Component
public class HttpToCompanyA {//按顺利指定增强器@InterceptorEnhance(intecepter = {EnhanceEsHandle.class,EnhanceEncryHandle.class})public String sendInfo(String request){return  "{code:\"0\",text:\"成功\"}";}}

运行用例

在这里插入图片描述

依赖

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></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>//打包到本地仓库后,引入使用<dependency><groupId>com.zdc.business</groupId><artifactId>business</artifactId><version>0.0.1</version></dependency></dependencies>

总结

本人3年多开发经验,对于各方面认识有限。欢迎老师们指出改进之处,有好的建议或者有想法大家可以交流探讨,一起完善。

相关文章:

基于常用设计模式的业务框架

前言 做开发也有好几年时间了&#xff0c;最近总结和梳理自己在工作中遇到的一些问题&#xff0c;工作中最容易写出BUG的需求就是改造需求了。一个成熟的业务系统是需要经过无数次迭代而成的&#xff0c;也意味着经过很多开发人员之手&#xff0c;最后到你这里&#xff0c;大部…...

ubuntu重启ssh服务

一、开启ssh服务首先需要安装打开ssh服务的库&#xff1a; sudo apt-get install openssh-server 二、检查当前的ssh开启情况&#xff1a; ps -e |grep ssh 三、如果有sshd&#xff0c;则ssh-server已经启动&#xff1b;若仅有agent&#xff0c;则尚未启动&#xff1b; 开启ssh…...

【19】SCI易中期刊推荐——计算机 | 人工智能领域(中科院2区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…...

Vue.js条件、循环语句

文章目录 条件语句v-ifv-elsev-else-ifv-show 循环语句v-for 指令v-for 迭代对象valuevalue ,keyvalue ,key&#xff0c;index v-for 迭代整数 条件语句 v-if 在元素 和 template 中使用 v-if 指令 <div id"app"><p v-if"seen">现在你看到我…...

Go语言学习查缺补漏ing Day4

Go语言学习查缺补漏ing Day4 一、掌握iota的使用 请看下面这段代码&#xff1a; package mainimport "fmt"const (a iota_bc "ReganYue"dd1e iotaf iota )func main() {fmt.Println(a, b, c, d, d1, e, f) }思考一下输出结果会是什么&#xff1f; …...

说服审稿人,只需牢记这 8 大返修套路!

本文作者&#xff1a;雁门飞雪 如果说科研是一场修炼&#xff0c;那么学术界就是江湖&#xff0c;投稿就是作者与审稿人或编辑之间的高手博弈。 在这一轮轮的对决中&#xff0c;有时靠的是实力&#xff0c;有时靠的是技巧&#xff0c;然而只有实力和技巧双加持的作者才能长久立…...

Java 责任链模式详解

责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于将请求的发送者和接收者解耦&#xff0c;使得多个对象都有机会处理这个请求。在责任链模式中&#xff0c;有一个请求处理链条&#xff0c;每个处理请求的对象都是一个…...

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

文章目录 前言分析方案1:遗嘱消息演示遗嘱消息的使用实施流程 方案2:使用WebHook开启WebHook演示Webhook编写代码 前言 获取一个设备的在线和离线状态&#xff0c;是一个很关键的功能。我们对设备下发的控制指令&#xff0c;设备处于在线状态才能及时给我们反馈。这里的在线和…...

我的新书上架了!

talk is cheap&#xff0c;show you my book&#xff01; 新书《从0开始学ARM》终于在各大平台上架了&#xff01;&#xff01; 一、关于本书 1. 本书主要内容 ARM体系架构是目前市面上的主流处理器体系架构&#xff0c;在手机芯片和嵌入式芯片领域&#xff0c;ARM体系架构…...

语言与专业的奇迹:如何利用ChatGPT优化跨国贸易

贸易公司&#xff0c;在进行跨国贸易时&#xff0c;往往需要面对不同国家的甲方或者乙方&#xff0c;在与之沟通的过程中&#xff0c;语言和专业是必须要过的一关&#xff0c;顺畅的交流&#xff0c;往往会带来更好的收益。 今天以“茶”为例&#xff0c;给大家介绍一“知否AI…...

云服务器安装宝塔Linux面板命令脚本大全

阿里云服务器安装宝塔Linux面板&#xff0c;操作系统不同安装命令脚本也不同&#xff0c;支持CentOS、Alibaba Cloud Linux、Ubuntu/Deepin等Linux系统&#xff0c;阿里云服务器网分享阿里云服务器安装宝塔Linux面板命令脚本大全&#xff1a; 云服务器安装宝塔Linux面板命令 …...

zed2i相机中imu内参的标定及外参标定

zed2i中imu内参的标定 参考&#xff1a; https://blog.csdn.net/weixin_42681311/article/details/126109617 https://blog.csdn.net/weixin_43135184/article/details/123444090 值得注意&#xff0c;imu内参的标定其实不是那么重要&#xff0c;大致上给一个值应该影响不大…...

Java中的JUnit是什么?如何使用JUnit进行单元测试

JUnit是Java中最流行的单元测试框架之一。它可以帮助开发人员在代码编写过程中检测出错误和异常&#xff0c;从而提高代码的质量和可靠性。 什么是JUnit&#xff1f; JUnit是一个由Kent Beck和Erich Gamma创建的开源Java单元测试框架&#xff0c;它已经成为Java开发中最常用的…...

【seata的部署和集成】

seata的部署和集成 seata的部署和集成一、部署Seata的tc-server1.下载2.解压3.修改配置4.在nacos添加配置5.创建数据库表6.启动TC服务 二、微服务集成seata1.引入依赖2.修改配置文件 三、TC服务的高可用和异地容灾1.模拟异地容灾的TC集群2.将事务组映射配置到nacos3.微服务读取…...

uniapp学习日记之request自定义请求头

uniapp学习日记之request自定义请求头 在学习uniapp的过程中&#xff0c;由于笔者是从Vue项目转来学习uniapp&#xff0c;在使用uni.request时&#xff0c;发现在浏览器调试时&#xff0c;无法在请求头header中添加token字段&#xff0c;愤而弃之&#xff0c;便开始使用axios组…...

【Rust】速度入门---打印个螃蟹先

参考: 菜鸟教程 1 输出到命令行 这不得打印个螃蟹 // 代码来自官方入门教程 // ferris_say需要另外安装 use ferris_says::say; use std::io::{stdout, BufWriter};fn main() {let stdout: std::io::Stdout stdout();let msg: String String::from("Hello fellow Rusta…...

《Linux 内核设计与实现》12. 内存管理

文章目录 页区获得页获得填充为 0 的页释放页 kmalloc()gfp_mask 标志kfree()vmalloc() slab 层slab 层的设计slab 分配器的接口 在栈上的静态分配单页内核栈 高端内存的映射永久映射临时映射 每个 CPU 的分配新的每个 CPU 接口 页 struct page 结构表示系统中的物理页&#x…...

公司新来个卷王,让人崩溃...

最近内卷严重&#xff0c;各种跳槽裁员&#xff0c;相信很多小伙伴也在准备今年的面试计划。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必要的&#xff0c;它几乎涵盖了所有的软件测试技术栈&#xff0c;非常珍贵&#x…...

Docker 安全及日志管理

Docker 安全及日志管理 Docker 容器与虚拟机的区别隔离与共享性能与损耗 Docker 存在的安全问题Docker 自身漏洞Docker 源码问题Docker 架构缺陷与安全机制Docker 安全基线标准 容器相关的常用安全配置方法容器最小化Docker 远程 API 访问控制重启 Docker在宿主机的 firewalld …...

大厂面试必备 - MAC 地址 和 IP 地址分别有什么作用?

数据链路层 1、MAC 地址 和 IP 地址分别有什么作用&#xff1f; MAC 地址是数据链路层和物理层使用的地址&#xff0c;是写在网卡上的物理地址。MAC 地址用来定义网络设备的位置。IP 地址是网络层和以上各层使用的地址&#xff0c;是一种逻辑地址。IP 地址用来区别网络上的计…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...

GB/T 43887-2024 核级柔性石墨板材检测

核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标&#xff1a; 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...

第21节 Node.js 多进程

Node.js本身是以单线程的模式运行的&#xff0c;但它使用的是事件驱动来处理并发&#xff0c;这样有助于我们在多核 cpu 的系统上创建多个子进程&#xff0c;从而提高性能。 每个子进程总是带有三个流对象&#xff1a;child.stdin, child.stdout和child.stderr。他们可能会共享…...