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

Day49

Day49

代理模式proxy

概念: 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式,即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

代理模式分为静态代理和动态代理两种 。

静态代理

思路:对于同一个接口,代理类和被代理类都实现了这个接口,代理类中将被代理类对象持有为自己的属性,这样在使用方法的时候就可以在被代理类的方法前后加上增强,即自己的方法逻辑。

以Speaker接口、ChineseSpeaker、AmericaSpeaker、ChinsesSpeakerProxy、AmericaSpeakerProxy为例,其中ChinsesSpeakerProxy、AmericaSpeakerProxy分别是ChineseSpeaker、AmericaSpeaker的代理类:

Speaker:

public interface Speaker {void speak();
}

ChineseSpeaker:

public class ChineseSpeaker implements Speaker{public void speak() {System.out.println("中文演讲");}
}

ChinsesSpeakerProxy:

public class ChineseSpeakerProxy implements Speaker{private ChineseSpeaker speaker;public ChineseSpeakerProxy(ChineseSpeaker speaker) {this.speaker = speaker;}@Overridepublic void speak() {System.out.println("增强处理");speaker.speak();System.out.println("增强处理");}
}

可以看出,这种写法每代理一个真实类就需要写一个代理类,对于AmericaSpeaker,同样要写一个AmericaSpeakerProxy。如果对于功能增强的内容完全相同,就可以使用一个对于Speaker接口通用的代理类CommonSpeakerProxy,利用多态完成代理。

public class CommonSpeakerProxy implements Speaker {private Speaker speaker;public CommonSpeakerProxy(Speaker speaker) {this.speaker = speaker;}@Overridepublic void speak() {System.out.println("前置功能增强");speaker.speak();System.out.println("后置功能增强");}
}

除了这种写法外,还可以利用反射的思想来写,利用多态通过接口实现类拿到方法,通过有参传入的类对象,用method.invoke()方法完成代理。

假设这时再添加了Seller接口、ChineseSeller、AmericaSeller类及其代理类CommonSellerProxy

public class CommonSellerProxy implements Seller{private static Method method;private  Object seller;public CommonSellerProxy(Object seller){this.seller = seller;}static {try {method = Seller.class.getMethod("sell");} catch (NoSuchMethodException e) {e.printStackTrace();}}@Overridepublic void sell() {try {System.out.println("前置功能增强");method.invoke(seller);System.out.println("后置功能增强");} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}
}

可以看出,静态代理每实现一个真实类的代理就需要写一个代理类,如果代理的功能不同,就需要针对代理功能编写多个类,十分复杂。那么有没有一种方式使得在使用到代理的时候再去编写代理的逻辑功能,而不是每次都去多写一个类呢?这就是动态代理的思想。

动态代理

动态代理又根据代理对象进行划分:

为接口做代理:JDK动态代理

为类做代理:CGLIB动态代理

JDK动态代理

由于动态代理和静态代理差别较大,这里从静态代理开始进阶优化,直到达到动态代理的范畴。

**静态代理进阶:**思路:写一个接口,接口中定义了代理重写的方法,在代理类中以匿名内部类的方式创建一个类对象作为自己持有的属性,并用全参构造要求使用时创建这个匿名内部类(即重写代理方法内容),而代理类中就只需要调用接口的实现类的方法就行,不需要再写明方法逻辑。

这个接口是jdk自带的接口,在这里自己写一遍,以更好地明白逻辑:

MethodInvocationHandler接口:

public interface MethodInvocationHandler {Object handle(Object target, Method method,Object[] args) throws Exception;
}

注意:这个方法的本质是反射,利用method.invoke()方法进行调用真实类的方法,再加上代理类的方法,因此参数为method.invoke()的参数。

ChineseSpeakerProxy代理类:

public class ChineseSpeakerProxy implements Speaker{private Speaker speaker;private MethodInvocationHandler handler;private static Method method;static {try {method = Speaker.class.getMethod("speak");} catch (NoSuchMethodException e) {throw new RuntimeException(e);}}public ChineseSpeakerProxy(Speaker speaker, MethodInvocationHandler handler) {this.speaker = speaker;this.handler = handler;}//如果有多个需要代理的方法就都要进行重写@Overridepublic void speak() {try {handler.handle(speaker,method,null);//由于真实类中的方法是无参的,所以这里的参数数组为空} catch (Exception e) {throw new RuntimeException(e);}}
}

使用:

public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();ChineseSpeakerProxy chineseSpeakerProxy = new ChineseSpeakerProxy(chineseSpeaker, new MethodInvocationHandler() {@Overridepublic Object handle(Object target, Method method, Object[] args) throws Exception {System.out.println("功能增强");method.invoke(target,args);System.out.println("功能增强");return null;}});chineseSpeakerProxy.speak();}

至此,对于同一个代理类的多个功能,实现了让用户自己写增强方法的目的。但是对于一个真实类,如果要实现其代理,那还是要写一个代理类,如果真实类很多,那就需要写很多的代理类,代理繁多的问题依然存在。

如果这些代理类能够使用代码来生成,然后再编译,再加载至 JVM 中,那么再多的代理也就不是问题了。

动态代理

手动写一个能够自动创建代理类源码的类,然后手动完成编译、加载的过程。(这些功能jdk的接口都实现了,这里只手写一个自动创建代理类源码的类以便深刻理解)

因此,可以手动写一个能够自动创建代理类源码的类,然后手动完成编译、加载的过程。(这些功能jdk的接口都实现了,这里只手写一个自动创建代理类源码的类以便深刻理解)

package com.qf.proxy;import com.qf.proxy.dynamic.MethodInvocationHandler;import java.lang.reflect.Method;
import java.lang.reflect.Parameter;public class MyProxy {private static String generateProxyClass(Class<?> clazz){if(!clazz.isInterface()) throw new IllegalArgumentException(clazz.getName() + " 不是接口");StringBuilder builder = new StringBuilder();builder.append("package ").append(clazz.getPackage().getName()).append(";\n");builder.append("import ").append(Method.class.getName()).append(";\n");builder.append("import ").append(MethodInvocationHandler.class.getName()).append(";\n");builder.append("import ").append(MyProxy.class.getName()).append(";\n");builder.append("public class $proxy0 extends MyProxy implements ").append(clazz.getSimpleName()).append("{\n");StringBuilder staticBuilder = new StringBuilder();staticBuilder.append("static {\n");staticBuilder.append("try {\n");StringBuilder overrideMethodBuilder = new StringBuilder();Method[] methods = clazz.getMethods();for(int i=0; i<methods.length; i++){builder.append("private static Method m").append(i).append(";\n");staticBuilder.append("m").append(i).append("=Class.forName(\"").append(clazz.getName()).append("\").getMethod(\"").append(methods[i].getName()).append("\",");overrideMethodBuilder.append("\n@Override\n");overrideMethodBuilder.append("public ").append(methods[i].getReturnType().getSimpleName()).append(" ").append(methods[i].getName()).append("(");Parameter[] parameters = methods[i].getParameters();for(Parameter parameter : parameters){staticBuilder.append(parameter.getType().getSimpleName()).append(".class,");overrideMethodBuilder.append(parameter.getType().getSimpleName()).append(" ").append(parameter.getName()).append(",");}staticBuilder.deleteCharAt(staticBuilder.length()-1);staticBuilder.append(");\n");if(parameters.length > 0)overrideMethodBuilder.deleteCharAt(overrideMethodBuilder.length()-1);overrideMethodBuilder.append("){\n");Class returnType = methods[i].getReturnType();if(returnType != Void.class && returnType != void.class)overrideMethodBuilder.append("return (").append(methods[i].getReturnType().getSimpleName()).append(")");overrideMethodBuilder.append("handler.handle(m").append(i).append(",new Object[]{");for(Parameter parameter : parameters){overrideMethodBuilder.append(parameter.getName()).append(",");}if(parameters.length > 0)overrideMethodBuilder.deleteCharAt(overrideMethodBuilder.length()-1);overrideMethodBuilder.append("});\n}");}staticBuilder.append("} catch (NoSuchMethodException e) {\ne.printStackTrace();\n}catch (ClassNotFoundException e) {\ne.printStackTrace();\n}\n");staticBuilder.append("}\n");builder.append(staticBuilder);builder.append("protected $proxy0(MethodInvocationHandler handler) {\nsuper(handler);\n}\n");builder.append(overrideMethodBuilder);builder.append("\n}");System.out.println(builder);return builder.toString();}//    public static void main(String[] args) {
//        generateProxyClass(Seller.class);
//    }
}

这个类完成了自动创建类源码的功能,其实现的思路就是将一个代理类中的特定类利用反射和object去替换,然后将整个类写成字符串放进StringBuilder中。

然后是编译代理类源文件、加载编译好的代理类(利用类加载器)、编写创建代理实例的方法。这些底层就不手写了。

接下来对比一下两种写法的区别(这里都实现jdk自带的InvocationHandler接口,接口内容和上面手写的MethodInvocationHandler一致,只是方法名字为invoke,我写的是handle):

手动创建ChineseSpeakerProxy(此时仍然为静态代理,因为代理类是在编译时明确定义的,并且代理类的代码是手动编写的。相对于动态代理,静态代理类在运行时不会自动生成,而是在编译时就已经存在。 ):

public class ChineseSpeakerProxy implements Speaker{private Speaker speaker;private InvocationHandler handler;private static Method method;static {try {method = Speaker.class.getMethod("speak");} catch (NoSuchMethodException e) {throw new RuntimeException(e);}}public ChineseSpeakerProxy(Speaker speaker, InvocationHandler handler) {this.speaker = speaker;this.handler = handler;}@Overridepublic void speak() {try {handler.invoke(speaker,method,null);} catch (Throwable e) {throw new RuntimeException(e);}}
}public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();ChineseSpeakerProxy chineseSpeakerProxy = new ChineseSpeakerProxy(chineseSpeaker, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {method.invoke(proxy,args);System.out.println("方法增强");return null;}});chineseSpeakerProxy.speak();}

使用jdk自带的Proxy类静态方法创建(动态代理):

public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();Speaker ChineseSpeakerProxy = (Speaker) Proxy.newProxyInstance(ChineseSpeaker.class.getClassLoader(), ChineseSpeaker.class.getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法增强");method.invoke(chineseSpeaker,args);return null;}});ChineseSpeakerProxy.speak();}

注意:使用Proxy类实现动态代理的时候,method.invoke()的第一个参数不是形参给的,而是被代理的类对象! 因为使用 Proxy.newProxyInstance动态生成的代理类会把代理实例本身传递给 InvocationHandler.invoke方法的 proxy 参数。因此,如果在 invoke 方法中再次调用 method.invoke(proxy, args),就会导致递归调用形成死循环。

总结

静态代理

写法一:真实类和代理类实现同一个接口,代理类持有真实类对象作为属性,并在重写接口方法的时候调用其方法,再添加方法增强。

写法二:如果多个真实类需要进行的方法增强相同,则可以写一个通用的代理类,实现和写法一相同。

写法三:利用反射的思想,代理类持有真实类对象属性,并利用反射拿到方法,重写的时候用invoke(),并添加方法增强。

写法四(进阶):利用接口(这里自己写的是MethodInvocationHandler)定义重写的方法,在代理类中创建接口的实现类(匿名内部类),并通过全参构造让用户自己传入真实类对象和接口实现类(并重写代理方法),调用实现类的方法。

动态代理:自动创建代理类源码,然后完成编译、加载。 代理类在运行时根据目标对象和增强逻辑动态生成。 在使用的时候利用Proxy类的静态方法newProxyInstance()创建代理类,并 通过 InvocationHandler 接口的 invoke 方法在运行时拦截方法调用,执行增强逻辑。

RESTful风格

RESTful风格不是标准,但是在企业中经常使用RESTful风格来完成功能的开发。

REST = Representational State Transfer(表属性状态转移)

简单来说就是在编写Servlet的时候重写doGet,doPost,doPut,doDelete实现增查改删功能。

Spring IOC

Spring简介

Spring 是目前主流的 Java 开发框架,是 Java 世界最为成功的框架。其目的是用于简化企业级应用程序开发的难度和周期,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。

什么是框架? 框架是一个半成品,提供了基本的运行功能,但具体业务实现需要我们去编写。

Spring体系结构

在这里插入图片描述

IOC概念:

IOC全称为 Inverse Of Control,表示控制反转。指的是程序员使用硬编码创建的对象转为由Spring容器来创建,对于对象生命周期的控制交给Spring容器来管理。控制反转解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健

依赖注入

DI全称为Dependency Injection,表示依赖注入。指的是在Spring创建对象的同时,为其属性赋值

设值注入:

创建一个类:

@Data
public class Student {private String name;private String sex;private int age;private Date birthday;
}

在xml配置文件中利用设值注入创建对象:

常见数据类型:

<!--application.xml-->
<bean name="stu" class="com.qf.spring.ioc.model.Student"><property name="name" value="张三" /><property name="age" value="20" /><property name="sex" value="" /><!--这里需要注意:日期类型的默认格式yyyy/MM/dd--><property name="birthday" value="2021/10/10" />
</bean>

使用:

@Test
public void studentTest(){//应用上下文使用的是类路径下XML文档作为当前应用上下文ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");//从上下文中根据bean的名称或者ID获取bean对象Student stu = context.getBean("stu", Student.class);System.out.println(stu);
}

注意:这里的name虽然是user,但是并不是指的user这个类,而是指向set方法!(理解为去掉set后的名字)设值注入本质就是通过set方法为属性注入值。设值注入必须保证存在无参构造,否则将报错。

注入数组类型:

spring 提供了 array 标签来进行数组类型的属性值的注入。

@Data
public class Clazz {private int id;private String name;private Student[] students;
}
<bean name="clazz" class="com.qf.spring.ioc.model.Clazz"><property name="id" value="1" /><property name="name" value="张三" /><property name="students"><array><!--引用数据类型 可以使用bean标签创建bean对象注入值--><!--<bean class=""></bean>--><!--引用数据类型 可以使用ref标签引用bean对象注入值--><ref bean="s" /><ref bean="stu" /><!--常用数据类型 可以使用value标签直接注入值--><!-- <value></value>--></array></property>
</bean>

注入集合类型:

List集合

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private String name;private String sex;private int age;private Date birthday;private List<Double> scores;
}
<bean name="stu" class="com.qf.spring.ioc.model.Student"><property name="name" value="张三" /><property name="age" value="20" /><property name="sex" value="" /><!--这里需要注意:日期类型的默认格式yyyy/MM/dd--><property name="birthday" value="2021/10/10" /><property name="scores"><list><value>80.0</value><value>90.0</value><value>81.0</value><value>82.0</value></list></property>
</bean><bean name="s" class="com.qf.spring.ioc.model.Student"><!--这里按照顺序为属性注入值--><constructor-arg index="0" value="李四" /><constructor-arg index="1" value="" /><constructor-arg index="2" value="22" /><constructor-arg index="3" value="2020/05/05" /><constructor-arg index="4"><list><value>80.0</value><value>90.0</value><value>81.0</value><value>82.0</value></list></constructor-arg>
</bean>
Set集合
@Data
public class Person {private String name;private Set<String> friendNames;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李刚" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property>
</bean>
注入Map
@Data
public class Person {private String name;private List<String> friendNames;private Map<String, Object> map;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李刚" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property><property name="map"><map><entry key="hobby" value="聊天" /><entry key="clazz" value-ref="clazz"/></map></property><property name="props"><props><prop key="desc">我很帅</prop><prop key="secret">我有两个女朋友</prop></props></property>
</bean>
注入Properties
@Data
public class Person {private String name;private List<String> friendNames;private Properties props;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李刚" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property><property name="props"><props><prop key="desc">我很帅</prop><prop key="secret">我有两个女朋友</prop></props></property>
</bean>
构造注入

构造注入指的是通过构造放入为属性注入值。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private String name;private String sex;private int age;private Date birthday;
}
<!--application.xml-->
<bean name="s" class="com.qf.spring.ioc.model.Student"><!--这里按照顺序为属性注入值--><constructor-arg index="0" value="李四" /><constructor-arg index="1" value="" /><constructor-arg index="2" value="22" /><constructor-arg index="3" value="2020/05/05" />
</bean>
@Test
public void studentConstructorTest(){//应用上下文使用的是类路径下XML文档作为当前应用上下文ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");//从上下文中根据bean的名称或者ID获取bean对象Student stu = context.getBean("s", Student.class);System.out.println(stu);
}

相关文章:

Day49

Day49 代理模式proxy 概念&#xff1a; 代理(Proxy)是一种设计模式&#xff0c;提供了对目标对象另外的访问方式&#xff0c;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能. 代理模式分为静态代理和动态代理…...

OpenCV 车牌检测

OpenCV 车牌检测 级联分类器算法流程车牌检测相关链接 级联分类器 假设我们需要识别汽车图像中车牌的位置&#xff0c;利用深度学习目标检测技术可以采取基于锚框的模型&#xff0c;但这需要在大量图像上训练模型。 但是&#xff0c;级联分类器可以作为预训练文件直接使用&…...

机器学习/pytorch笔记:time2vec

1 概念部分 对于给定的标量时间概念 t&#xff0c;Time2Vec 的表示 t2v(t)是一个大小为 k1的向量&#xff0c;定义如下&#xff1a; 其中&#xff0c;t2v(t)[i]是 t2v(t)的第 i 个元素&#xff0c;F是一个周期性激活函数&#xff0c;ω和 ϕ是可学习的参数。 以下是个人理解&am…...

降低开关电源噪声的设计总结

开关电源的特征就是产生强电磁噪声&#xff0c;若不加严格控制&#xff0c;将产生极大的干扰。下面介绍的技术有助于降低开关电源噪声&#xff0c;能用于高灵敏度的模拟电路。 电路和器件的选择 一个关键点是保持dv/dt和di/dt在较低水平&#xff0c;有许多电路通过减小dv/dt和…...

rust嵌入式开发2024

老的rust embedded book 其实过时了. 正确的姿势是embassy 入手. 先说下以前rust写嵌入怎么教学小白的. 第一步,从这里 svd2rust 工具,自己生成库第二部,有了这个库,相当于就有了pac外设访问文件,然后其实就可以搞起来了. 那么为啥不好搞了. 因为太乱了. 小白喜欢你告我咋弄…...

字符串

对应练习题&#xff1a;力扣平台 14. 最长公共前缀 class Solution { public:string longestCommonPrefix(vector<string>& strs) {string strs1strs[0];//初始前缀字符串for (int i 1; i < strs.size(); i) {while(strs[i].find(strs1)!0)//遍历找到共同最长前…...

mysql8 锁表与解锁

方法1不行&#xff0c;就按方法2来执行&#xff1b; (一) 解锁方法1 连接mysql &#xff0c;直接执行UNLOCK TABLES&#xff0c;细节如下&#xff1a; – 查询是否锁表 SHOW OPEN TABLES WHERE in_use >0 ; – 查询进程 show processlist ; – 查询到相对应的进程&#xf…...

第2篇 区块链的历史和发展:从比特币到以太坊

想象一下&#xff0c;你住在一个小镇上&#xff0c;每个人都有一个大账本&#xff0c;记录着所有的交易。这个账本很神奇&#xff0c;每当有人买卖东西&#xff0c;大家都会在自己的账本上记一笔&#xff0c;确保每个人的账本都是一致的。这就是区块链的基本思想。而区块链的故…...

从理论到实践的指南:企业如何建立有效的EHS管理体系?

企业如何建立有效的EHS管理体系&#xff1f;对于任何企业&#xff0c;没有安全就谈不上稳定生产和经济效益&#xff0c;因此建立EHS管理体系是解决企业长期追求的建立安全管理长效机制的最有效手段。良好的体系运转&#xff0c;可以最大限度地减少事故发生。 这篇借着开头这个…...

内网和外网的区别及应用

内网和外网的区别及应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨一下计算机网络中的内网和外网&#xff0c;它们的区别以及在实际应用中的…...

电驱失效类型和风险分析,如何用精益思维提升电驱可靠性?

在电动车日益普及的今天&#xff0c;电驱系统作为电动车的“心脏”&#xff0c;其可靠性直接关系到整车的性能与用户体验。然而&#xff0c;电驱失效问题却一直困扰着电动车行业&#xff0c;如何提升电驱可靠性成为了业内关注的焦点。今天&#xff0c;深圳天行健精益管理咨询公…...

自动扫描范围在减少剂量多相CT肝脏成像中的应用:基于CNN和高斯模型| 文献速递-深度学习自动化疾病检查

Title 题目 Automatic scan range for dose-reduced multiphase CT imaging of theliver utilizing CNNs and Gaussian models 自动扫描范围在减少剂量多相CT肝脏成像中的应用&#xff1a;基于CNN和高斯模型 01 文献速递介绍 肝癌是全球癌症死亡的第四大原因&#xff0c;每…...

【机器学习】基于层次的聚类方法:理论与实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于层次的聚类方法&#xff1a;理论与实践引言1. 层次聚类基础1.1 概述1.2 距离…...

C# 验证PDF数字签名的有效性

数字签名作为PDF文档中的重要安全机制&#xff0c;不仅能够验证文件的来源&#xff0c;还能确保文件内容在传输过程中未被篡改。然而&#xff0c;如何正确验证PDF文件的数字签名&#xff0c;是确保文件完整性和可信度的关键。本文将详细介绍如何使用免费.NET控件通过C#验证PDF签…...

2小时动手学习扩散模型(pytorch版)【入门版】【代码讲解】

2小时动手学习扩散模型&#xff08;pytorch版&#xff09; 课程地址 2小时动手学习扩散模型&#xff08;pytorch版&#xff09; 课程目标 给零基础同学快速了解扩散模型的核心模块&#xff0c;有个整体框架的理解。知道扩散模型的改进和设计的核心模块。 课程特色&#xf…...

Centos7网络配置(设置固定ip)

文章目录 1进入虚拟机设置选中【网络适配器】选择【NAT模式】2 进入windows【控制面板\网络和 Internet\网络和共享中心\更改适配器设置】设置网络状态。3 设置VM的【虚拟网络编辑器】4 设置系统网卡5 设置虚拟机固定IP 刚安装完系统&#xff0c;有的人尤其没有勾选自动网络配置…...

英伟达被“压制”的25年

十九世纪中叶的美国西部&#xff0c;掀起了一场轰轰烈烈的淘金热&#xff0c;但最终赚到钱的&#xff0c;并不是拿命去赌的淘金者。一个名叫萨姆布瑞南的商人&#xff0c;通过向淘金者出售铲子&#xff0c;成了加州历史上第一位百万富翁。 每一次风口出现时&#xff0c;总有企…...

windows安装Gitblit还是Bonobo Git Server

Gitblit 和 Bonobo Git Server 都是用于托管Git仓库的工具&#xff0c;但它们是基于不同平台的不同软件。 Gitblit 是一个纯 Java 写的服务器&#xff0c;支持托管 Git&#xff0c;Mercurial 和 SVN 仓库。它需要 Java 运行环境&#xff0c;适合在 Windows、Linux 和 Mac 平台…...

仪器校准的概念与定义,计量校准是什么?

仪器校准的定义&#xff0c;在之前所颁布的《国际计量学词汇 基础和通用概念及相关术语》文件中&#xff0c;已经有了明确说明&#xff0c;而该文件做了修改以后&#xff0c;在后续新的定义中&#xff0c;仪器校准具体被分为两部分&#xff0c;第一步是将被计量仪器和计量校准的…...

Vue3+Pinia

1.单纯调接口(安装pinia及引入如下第一张图) 1.npm install pinia2.在main.js里引入即可import { createPinia } from piniaapp.use(createPinia()) 1.stores建立你文件的ts、内容如下&#xff1a;1-1 import { defineStore } from pinia1-2 import { findPageJobSet } from …...

label studio数据标注平台的自动化标注使用

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/data-infra/cube-studio 做图文音项目过程中&#xff0c;我们通常会需要进行数据标注。label studio是一个比较好上手的标注平台&#xff0c;可以直接搜索…...

高并发场景下的热点key问题探析与应对策略

目录 一、问题描述 二、发现机制 三、解决策略分析 &#xff08;一&#xff09;解决策略一&#xff1a;多级缓存策略 客户端本地缓存 代理节点本地缓存 &#xff08;二&#xff09;解决策略二&#xff1a;多副本策略 &#xff08;三&#xff09;解决策略三&#xff1a;热点…...

学习一下C++中的枚举的定义

目录 普通枚举 强类型枚举 普通枚举 枚举类型在C中是通过关键字enum来定义的。下面是一个简单的例子&#xff1a; enum Color { RED, GREEN, BLUE }; 在这个例子中&#xff0c;我们定义了一个名为Color的枚举类型&#xff0c;它包含了三个枚举值&#xff1a;RED、GRE…...

开发一套java语言的智能导诊需要什么技术?java+ springboot+ mysql+ IDEA互联网智能3D导诊系统源码

开发一套java语言的智能导诊需要什么技术&#xff1f;java springboot mysql IDEA互联网智能3D导诊系统源码 医院导诊系统是一种基于互联网和3D人体的智能化服务系统&#xff0c;旨在为患者提供精准、便捷的医院就诊咨询服务。该系统整合了医院的各种医疗服务资&#xff1b;智慧…...

C++| STL之string

前言&#xff1a;最近在做LeetCode算法题&#xff0c;C字符串通常都是string作为输入&#xff0c;所以补充一下STL里面string。在介绍的具体使用的时候&#xff0c;会补充char字符串相关的进行对比。 string 创建大小和容量遍历字符串比较插入字符拼接字符串分配内存查找截取分…...

[数据集][目标检测]游泳者溺水检测数据集VOC+YOLO格式4599张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4599 标注数量(xml文件个数)&#xff1a;4599 标注数量(txt文件个数)&#xff1a;4599 标注…...

JAVA实现麦克风说话同声传译

一、能力与场景说明 同声传译&#xff0c;又称同步口译或同声翻译&#xff0c;是一种专业的口译形式&#xff0c;指的是在讲话者发言时&#xff0c;口译员几乎同时将讲话内容翻译成目标语言。这种翻译方式通常用于国际会议、高级别政治或商业会谈、研讨会和其他需要即时多语言…...

LabVIEW与PLC通讯方式及比较

LabVIEW与PLC之间的通讯方式多样&#xff0c;包括使用MODBUS协议、OPC&#xff08;OLE for Process Control&#xff09;、Ethernet/IP以及串口通讯等。这些通讯方式各有特点&#xff0c;选择合适的通讯方式可以提高系统的效率和稳定性。以下将详细介绍每种通讯方式的特点、优点…...

2024/6/30 英语每日一段

Years of economic and political turbulence have brought stagnation.“In a world where there is more risk and uncertainty, people become reluctant to voluntarily move jobs and find better jobs,” says Manning. At the same time, businesses have cut back on i…...

Postman接口测试工具的原理及应用详解(五)

本系列文章简介&#xff1a; 在当今软件开发的世界中&#xff0c;接口测试作为保证软件质量的重要一环&#xff0c;其重要性不言而喻。随着前后端分离开发模式的普及&#xff0c;接口测试已成为连接前后端开发的桥梁&#xff0c;确保前后端之间的数据交互准确无误。在这样的背景…...