Java版事件与委托实现自动创建工厂并热加载

news2024/12/23 18:50:34
本文已收录于专栏
《Java》

目录

  • 概念说明
    • 事件与委托
    • 工厂方法
    • 热加载
  • 需求介绍
  • 代码实现
    • 1.整体结构
    • 2.工厂方法中已经存在的类
      • 工厂接口
      • 运算类工厂(其他工厂基本上是一样的):目前没有加法类的工厂我们后面会添加加法类工厂然后热加载运行
      • 运算父类
      • 运算子类
    • 3.工厂方法之外的其他业务类
      • 编译类:将java文件编译成class文件,方便创建出来反射的时候使用
      • 自动创建工厂和客户端类
      • 创建类的模板:当前使用的是txt文件,也可以使用其他文件例如mv等
      • 监听类
      • 委托类
      • 事件类
      • 两个线程类,一个只负责监听有没有新类的加入,一个只负责让用户输入运算
    • 4.运行结果
  • 总结提升

概念说明

事件与委托

  • 事件是程序中发生的特定动作或状态的通知,可以是用户操作、系统事件或其他触发条件。
  • 委托是一种引用方法的类型,可以将方法作为参数传递、存储和调用。
  • 通过事件与委托的机制,可以实现一种松耦合的方式,使不同的组件之间能够进行通信和交互。
  • 当事件发生时,会调用注册的委托方法来处理事件,从而实现相应的逻辑。

工厂方法

  • 工厂方法是一种创建对象的设计模式,将对象的创建过程封装在一个工厂类中。
  • 工厂方法通过提供一个公共的接口来创建对象,隐藏了具体对象的创建细节。
  • 工厂方法可以根据不同的需求,返回不同的对象实例,提供了一种灵活的对象创建方式。
  • 在Java中,可以使用工厂方法模式来创建对象,例如使用工厂类、抽象工厂接口等。

热加载

  • 热加载是指在应用程序运行期间,动态地替换、添加或删除代码,而无需重启应用程序。
  • 热加载可以提高开发效率,因为不需要每次修改代码后都重新启动应用程序。
  • 在Java中,可以使用工具或框架实现热加载,例如使用JRebel、Spring Boot DevTools等。

需求介绍

  我们在学习设计模式的时候都接触过事件与委托,也都学习过工厂三兄弟:简单工厂、 工厂方法和抽象工厂。我们就拿工厂方法来说,每个运算类的工厂百分之八十的内容都是一样的。这样就引起了我们通过模板动态的生成工厂类, 想用哪个运算就生成哪个运算对应的工厂然后执行就可以了。实现的方式有很多种,我们今天通过使用事件与委托的形式进行实现,也就是当我们有一个类添加进来之后我们就会触发自动创建工厂的方法。也就相当于我们把自动创建工厂的方法通过委托注册到了事件当中。

代码实现

1.整体结构

在这里插入图片描述

2.工厂方法中已经存在的类

工厂接口

package AutomaticCreateFactoryzhuce;
 
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: FactoryMethod
 * @Author: Administrator
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-03-08 22:36
 * @Version: 1.0
 */
public interface IFactory {
 
    Operation createOperation();
}

运算类工厂(其他工厂基本上是一样的):目前没有加法类的工厂我们后面会添加加法类工厂然后热加载运行

package AutomaticCreateFactoryzhuce.OperationFactory;
 
import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationSubclass.OperationDiv;
 
public class DivFactory implements IFactory {
 
    /**
    * @Author:Wuzilong
    * @Description: 除法运算类
    * @CreateTime: 2023/4/7 8:22
    * @param: 
    * @return: 
    **/
    @Override
    public Operation createOperation() {
        return new OperationDiv();
    }
}

运算父类

package AutomaticCreateFactoryzhuce;
 
import lombok.Data;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: SimpleFactory
 * @Author: Wuzilong
 * @Description: 运算父类
 * @CreateTime: 2023-03-07 11:12
 * @Version: 1.0
 */
@Data
public class Operation {
    private double numberA=0;
    private  double numberB=0;
 
    public  double getResult() throws Exception {
        double result=0;
        return result;
    }
}

运算子类

package AutomaticCreateFactoryzhuce.OperationSubclass;
 
 
import AutomaticCreateFactoryzhuce.Operation;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: SimpleFactory
 * @Author: Wuzilong
 * @Description: 除法类
 * @CreateTime: 2023-03-07 11:20
 * @Version: 1.0
 */
 
public class OperationDiv extends Operation {
    @Override
    public  double getResult() throws Exception {
        double result=0;
        result=getNumberA()/getNumberB();
        return result;
    }
}```
## 3.工厂方法之外的其他业务类
### 编译类:将java文件编译成class文件,方便创建出来反射的时候使用

```java
package AutomaticCreateFactoryzhuce;
 
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
 
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryV2
 * @Author: Wuzilong
 * @Description: 将java文件编译成class文件
 * @CreateTime: 2023-03-18 22:15
 * @Version: 1.0
 */
 
public class Compiler extends ClassLoader {
    public void compiler(String compilerPath,String javaPath){
 
        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        int status = javac.run(null, null, null, "-d",
                compilerPath,javaPath);
        if(status!=0){
            System.out.println("没有编译成功!");
        }
    }
}

3.工厂方法之外的其他业务类

编译类:将java文件编译成class文件,方便创建出来反射的时候使用

package AutomaticCreateFactoryzhuce;
 
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
 
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryV2
 * @Author: Wuzilong
 * @Description: 将java文件编译成class文件
 * @CreateTime: 2023-03-18 22:15
 * @Version: 1.0
 */
 
public class Compiler extends ClassLoader {
    public void compiler(String compilerPath,String javaPath){
 
        JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
        int status = javac.run(null, null, null, "-d",
                compilerPath,javaPath);
        if(status!=0){
            System.out.println("没有编译成功!");
        }
    }
}

自动创建工厂和客户端类

package AutomaticCreateFactoryzhuce;
 
 
 
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactory
 * @Author: Wuzilong
 * @Description: 自动创建工厂和客户端类
 * @CreateTime: 2023-03-15 16:57
 * @Version: 1.0
 */
 
public class CreateClass {
 
    public  void createClass() throws Exception {
        // 工厂文件模板
        String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//FactoryTemplate";
        //客户端文件模板
        String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//ClientTemplate";
        //运算子类的抽象类名
        String className = "FactoryTemplate";
        //运算子类中要实例化的类的抽象类名
        String reClass="OperationClass";
        //客户端的抽象类名
        String clientName="Client";
        //客户端中要实例化的类的抽象类名
        String newName="OperFactory";
        //创建工厂的方法
        createFile(factoryTemplate,className,reClass);
        //创建客户端的方法
        createFile(clientTemplate,clientName,newName);
    }
 
    public  void createClass(String newClassName) throws Exception {
        // 工厂文件模板
        String factoryTemplate = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//FactoryTemplate";
        //客户端文件模板
        String clientTemplate ="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//Template//ClientTemplate";
        //运算子类的抽象类名
        String className = "FactoryTemplate";
        //运算子类中要实例化的类的抽象类名
        String reClass="OperationClass";
        //客户端的抽象类名
        String clientName="Client";
        //客户端中要实例化的类的抽象类名
        String newName="OperFactory";
        //创建工厂的方法
        createFile(factoryTemplate,className,reClass,newClassName);
        //创建客户端的方法
        createFile(clientTemplate,clientName,newName,newClassName);
    }
 
    private static void createFile(String filePath,String className,String reClass) throws Exception {
        String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";
        //反射的类路径
        List<String> classPath=new ArrayList();
        //要创建的java类的名字
        List<String> target=new ArrayList<>();
        File file = new File(packagePath);
        //判断是不是文件夹
        if (file.isDirectory()){
            File[] files = file.listFiles();
            for (int i=0; i<files.length;i++){
                String fileNamePath=files[i].getAbsolutePath();
                if (files[i].getAbsolutePath().endsWith(".java")){
                    String operClassPath = fileNamePath.substring(fileNamePath.indexOf("OperationSubclass"), fileNamePath.indexOf(".java"));
                    String createClassName = operClassPath.replace("OperationSubclass\\", "");
                    target.add(createClassName);
                    classPath.add("AutomaticCreateFactoryzhuce.OperationSubclass."+createClassName);
                }
            }
        }
 
 
        // 创建java类的存放路径
        String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationFactory//";
        //存放class文件的路径
        String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";
 
        int isClient=0;
        for (int i = 0; i < target.size(); i++) {
            try {
                BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件
                //StringBuffer动态的字符串数组
                StringBuffer strBuffer = new StringBuffer();
                //将java编译成class的类
                Compiler compiler = new Compiler();
                //截取计算类的后三位
                String substring = target.get(i).substring(target.get(i).length() - 3);
                String classNameStr=substring+"Factory";
                for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {
                    //判断当前行是否存在想要替换掉的字符
                    if(temp.contains(className)){
                        if (className.contains("Client")){
                            //替换类名
                            temp = temp.replace(className, classNameStr+"Client");
                        }else{
                            //替换类名
                            temp = temp.replace(className, classNameStr);
                        }
                    }else if(temp.contains(reClass)){
                        if (reClass.contains("Factory")){
                            //替换返回需要实例化的类名
                            temp = temp.replace(reClass, classNameStr);
                            isClient+=1;
                        }else{
                            Class classObject=null;
                            try{
                                classObject = Class.forName(classPath.get(i));
                            }catch (Exception e){
                                compiler.compiler(classURL,packagePath+target.get(i)+".java");
                                classObject = Class.forName(classPath.get(i));
                            }
                            //反射获取计算类的名称
 
                            //替换返回需要实例化的类名
                            temp=temp.replace(reClass, classObject.getSimpleName());
                        }
                    }
                    //把读取的每一行添加到数组中
                    strBuffer.append(temp);
                    //换行符
                    strBuffer.append(System.getProperty("line.separator"));
                }
                bufReader.close();
                PrintWriter printWriter = null;
                String createClassName=null;
                if (isClient>0){
                    //创建java对象并存放在对应的路径当中
                    printWriter = new PrintWriter(targetURL+classNameStr+"Client"+".java");
                    createClassName=targetURL+ classNameStr+"Client"+".java";
                }else{
                    printWriter = new PrintWriter(targetURL+classNameStr+".java");
                    createClassName=targetURL+ classNameStr+".java";
                }
                //将获取数据的数组写入到创建的java对象中
                printWriter.write(strBuffer.toString().toCharArray());
                printWriter.flush();
                printWriter.close();
                compiler.compiler(classURL,createClassName);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
    }
 
    private static void createFile(String filePath,String className,String reClass,String newClassName)  {
        String packagePath="D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";
 
        // 创建java类的存放路径
        String targetURL = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationFactory//";
        //存放class文件的路径
        String classURL="D://项目//设计模式//Java//DesignPattern//target//classes//";
 
        int isClient=0;
            try {
                BufferedReader bufReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));//数据流读取文件
                //StringBuffer动态的字符串数组
                StringBuffer strBuffer = new StringBuffer();
                //将java编译成class的类
                Compiler compiler = new Compiler();
                //截取计算类的后三位
                String substring =newClassName.substring(newClassName.length() - 3);
                String classNameStr=substring+"Factory";
                for (String temp = null; (temp = bufReader.readLine()) != null; temp = null) {
                    //判断当前行是否存在想要替换掉的字符
                    if(temp.contains(className)){
                        if (className.contains("Client")){
                            //替换类名
                            temp = temp.replace(className, classNameStr+"Client");
                        }else{
                            //替换类名
                            temp = temp.replace(className, classNameStr);
                        }
                    }else if(temp.contains(reClass)){
                        if (reClass.contains("Factory")){
                            //替换返回需要实例化的类名
                            temp = temp.replace(reClass, classNameStr);
 
                            isClient+=1;
                        }else{
                            newClassName=newClassName.replace("//",".");
                            Class classObject=null;
                            try{
                                classObject = Class.forName(newClassName);//新创建出来的类的相对路径
                            }catch (Exception e){
                                compiler.compiler(classURL,packagePath+newClassName+".java");
                                classObject = Class.forName(newClassName);
                            }
                            //反射获取计算类的名称
 
                            //替换返回需要实例化的类名
                            temp=temp.replace(reClass, classObject.getSimpleName());
                        }
                    }
                    //把读取的每一行添加到数组中
                    strBuffer.append(temp);
                    //换行符
                    strBuffer.append(System.getProperty("line.separator"));
                }
                bufReader.close();
                PrintWriter printWriter = null;
                String createClassName=null;
                if (isClient>0){
                    //创建java对象并存放在对应的路径当中
                    printWriter = new PrintWriter(targetURL+classNameStr+"Client"+".java");
                    createClassName=targetURL+ classNameStr+"Client"+".java";
                }else{
                    printWriter = new PrintWriter(targetURL+classNameStr+".java");
                    createClassName=targetURL+ classNameStr+".java";
                }
                //将获取数据的数组写入到创建的java对象中
                printWriter.write(strBuffer.toString().toCharArray());
                printWriter.flush();
                printWriter.close();
                compiler.compiler(classURL,createClassName);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
 
}

创建类的模板:当前使用的是txt文件,也可以使用其他文件例如mv等

运算子类

package AutomaticCreateFactoryzhuce.OperationFactory;
 
import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationSubclass.OperationClass;
 
public class FactoryTemplate implements IFactory {
 
    @Override
    public Operation createOperation() {
        return new OperationClass();
    }
}

每个运算类对应的客户端模板

package AutomaticCreateFactoryzhuce.OperationFactory;
 
import AutomaticCreateFactoryzhuce.IFactory;
import AutomaticCreateFactoryzhuce.Operation;
import AutomaticCreateFactoryzhuce.OperationFactory.OperFactory;
 
public class Client {
    public  void createMethod() throws Exception {
        IFactory operFactory=new OperFactory();
        Operation operation = operFactory.createOperation();
        operation.setNumberA(3);
        operation.setNumberB(2);
        double result=operation.getResult();
        System.out.println("自动生成工厂方法的运行结果:"+result);
    }
}

监听类

package AutomaticCreateFactoryzhuce;
 
import java.nio.file.*;
import java.util.EventListener;
import java.util.EventObject;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryzhuce
 * @Author: Wuzilong
 * @Description: 监听是否有新的类
 * @CreateTime: 2023-03-27 09:29
 * @Version: 1.0
 */
 
public class Listener  {
 
    public void run() {
        WatchKey key;
        try {
            String path = "D://项目//设计模式//Java//DesignPattern//src//main//java//AutomaticCreateFactoryzhuce//OperationSubclass//";
            //创建一个watchservice对象,用于监听目录事件
            WatchService watchservice = FileSystems.getDefault().newWatchService();
            //监控目录下是否有创建的文件
            Paths.get(path).register(watchservice, StandardWatchEventKinds.ENTRY_CREATE);
            while (true) {
                key = watchservice.take();//没有文件增加时,阻塞在这里
                //key.pollEvents()用于获取文件变化事件
                for (WatchEvent<?> event : key.pollEvents()) {
                    //返回触发事件的文件或目录的路径(相对路径)
                    String filename = path  + event.context();
                    System.out.println("增加文件的文件夹路径" + filename);
                    String newClassName = filename.substring(filename.indexOf("AutomaticCreateFactoryzhuce"), filename.indexOf(".java"));
                    Event eventObject = new Event();
                    eventObject.addDelegate(new Delegate(new CreateClass(),"createClass",newClassName));
                    eventObject.addClass();
                }
                if (!key.reset()) {
                    break; //中断循环
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

委托类

package AutomaticCreateFactoryzhuce;
 
import java.lang.reflect.Method;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryzhuce
 * @Author: Wuzilong
 * @Description: 委托类
 * @CreateTime: 2023-03-29 08:48
 * @Version: 1.0
 */
 
public class Delegate {
    private Object obj;
    private String methodName;
    private Object[] methodParameter;
    private Class<?>[] methodType;
 
    public Delegate(Object obj, String methodName, Object... methodParameter) {
        this.obj = obj;
        this.methodName = methodName;
        this.methodParameter = methodParameter;
        int len = methodParameter.length;
        this.methodType = new Class[len];
        for (int i = 0; i < len; i++) {
            methodType[i] = methodParameter[i].getClass();
        }
    }
 
    public void eventHandler() throws Exception {
        Method method = obj.getClass().getDeclaredMethod(methodName, methodType);
        method.invoke(obj, methodParameter);
    }
}

事件类

package AutomaticCreateFactoryzhuce;
 
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryzhuce
 * @Author: Wuzilong
 * @Description: 事件类
 * @CreateTime: 2023-03-27 09:40
 * @Version: 1.0
 */
 
public class Event  {
 
    private List<Delegate> objects=new ArrayList<>();
 
 
    public void addDelegate(Delegate source) {
        objects.add(source);
    }
 
    public void addClass() throws Exception {
        if (objects.size()!=0){
            for (Delegate object:objects){
                object.eventHandler();
            }
        }
    }
}

两个线程类,一个只负责监听有没有新类的加入,一个只负责让用户输入运算

监听线程

package AutomaticCreateFactoryzhuce;
 
 
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactory
 * @Author: Wuzilong
 * @Description: 触发监听的线程
 * @CreateTime: 2023-03-21 08:31
 * @Version: 1.0
 */
 
public class RegularService implements Runnable{
    public void run() {
        CreateClass createClass=new CreateClass();
        Listener listener = new Listener();
        // 需要定时执行的任务
        Runnable runnable = () -> {
            try {
                createClass.createClass();
                listener.run();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        //立即执行,并且每5秒执行一次
        ses.scheduleAtFixedRate(runnable, 0, 10000, TimeUnit.MILLISECONDS);
    }
}

用户输入运算线程

package AutomaticCreateFactoryzhuce;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
/**
 * @BelongsProject: DesignPattern
 * @BelongsPackage: AutomaticCreateFactoryzhuce
 * @Author: Wuzilong
 * @Description: 定时触发用户想要的运算
 * @CreateTime: 2023-03-27 21:14
 * @Version: 1.0
 */
 
public class RegularClient {
    public void run() {
        // 需要定时执行的任务
        Runnable runnable = () -> {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入要执行的算法工厂");
                String operation = br.readLine();
                Class aClass = Class.forName("AutomaticCreateFactoryzhuce.OperationFactory." + operation + "Client");
                Object object = aClass.newInstance();
                Method mainMethod = aClass.getMethod("createMethod");
                mainMethod.invoke(object);
            } catch (Exception e) {
                System.out.println("暂不支持该运算");
            }
        };
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
        //立即执行,并且每5秒执行一次
        ses.scheduleAtFixedRate(runnable, 0, 8000, TimeUnit.MILLISECONDS);
    }
}

4.运行结果

在这里插入图片描述
在这里插入图片描述

总结提升

  只要我们把最基础的内容学会了其他的内容就是我们通过基础的内容组合而成的。实现这个例子的时候一开始觉得实现起来比较困难。但是把整个过程拆分一下,都是之前学习过的内容:反射、事件与委托、工厂方法等。对于一个比较大的任务颗粒化就十分的重要。把每个小的颗粒逐个击破大问题也就没有了。


🎯 此文章对你有用的话记得留言+点赞+收藏哦🎯

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

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

相关文章

Java 运行jar包变更配置文件与变量

文章目录 前言实现原理不同环境的配置文件变更配置变量 前言 为实现快速搭建和开发&#xff0c;项目以Springboot框架搭建&#xff0c;springboot搭建的项目可以将项目直接打成jar包并运行&#xff0c;无需自己安装配置Tomcat或者其他服务器&#xff0c;是一种方便快捷的部署方…

PDF怎么转换成Excel?两个实用的方法给你!

如何将PDF文件转换成Excel表格的格式呢&#xff1f;在日常办公中&#xff0c;我们经常会遇到需要将PDF文件转换成Excel表格的情况。由于PDF文件具有稳定的格式特征&#xff0c;很多时候我们下载或接收到的文件都是以PDF格式呈现。那么&#xff0c;当我们需要使用Excel表格格式时…

数据结构--字符串的KMP算法

数据结构–字符串的KMP算法 朴素模式匹配算法&#xff1a; 一旦发现当前这个子串中某个字符不匹配&#xff0c;就只能转而匹配下一个子串(从头开始) 但我们可以知道&#xff1a; 不匹配的字符之前&#xff0c;一定是和模式串一致的 \color{red}不匹配的字符之前&#xff0c;一…

C++中内存拷贝函数memcpy函数使用

函数原型&#xff1a;void *memcpy(void *dest, const void *src, size_t n); 头文件&#xff1a;#include<string.h> 功能&#xff1a; 从源 src 所指的内存地址的起始位置开始拷贝 n 个字节到目标 dest 所指的 内存地址的起始位置中&#xff08;将一个 内存块 的内容…

哪种类型耳机不伤耳朵,分享几款佩戴无需入耳的骨传导耳机

骨传导耳机是目前在运动领域最火热的产品&#xff0c;也是最适合运动的耳机&#xff0c;它的原理是通过颅骨将声音转化为神经冲动&#xff0c;通过内耳传至听觉中枢&#xff0c;因此不会对耳朵造成任何损伤&#xff0c;它同时也可以让耳朵更好地听到周围的声音。能够很好的提高…

100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

&#x1f337; 博主 libin9iOak带您 Go to Golang Language.✨ &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &#x1f30a; 《I…

Linux0.11内核源码解析-char_dev.c

目录 概述 串口终端设备 控制台终端 内存 调用接口 概述 char_dev.c文件包括字符设备文件访问函数&#xff0c;主要是有rw_ttyx(),rw_tty(),rw_memory()和rw_char()函数&#xff0c;另外还有一个设备读写函数指针表 串口终端设备 rw_ttyx()是串口终端设备读写函数&#x…

Process Explorer高级使用

工具描述 Process Explorer使用个轻量级的进程管理器&#xff0c;是由Sysinternals出品的免费工具&#xff0c;请猛击这里下载最新版本使用。 以下是官方介绍的翻译&#xff1a; “想知道是那个程序打开了某个文件或者目录么&#xff1f;现在可以找出它了。PorcessExplorer将…

三、pycharm开发PyQt6 开发环境一键生成

一、环境 windows 10Pycharm 社区版 - PyCharm 2022.1.3 二、设置模板 1、打开模板 File -> Settings… (ctrl alt s) -> Editor -> File and Code Templates 2、创建模板 1&#xff09;点击 Files 2&#xff09;点击 3、填写第一个脚本文件 Name : My PyQt…

ReentrantLock源码解析 | 京东云技术团队

并发指同一时间内进行了多个线程。并发问题是多个线程对同一资源进行操作时产生的问题。通过加锁可以解决并发问题&#xff0c;ReentrantLock是锁的一种。 1 ReentrantLock 1.1 定义 ReentrantLock是Lock接口的实现类&#xff0c;可以手动的对某一段进行加锁。ReentrantLock…

hadoop高校固定资产管理系统-计算机毕设 附源码74965

hadoop高校固定资产管理系统 摘 要 在信息飞速发展的今天&#xff0c;网络已成为人们重要的信息交流平台。高校部门每天都有大量的信息需要通过网络发布&#xff0c;为此&#xff0c;高校固定资产管理系统开发的必然性&#xff0c;所以本人开发了一个基于Tomcat&#xff08;服务…

SpringBoot整合Schedule详解和优化实战

文章目录 前言为什么选择Spring ScheduleCron表达式简单示例测试结果优化方案 前言 Spring Schedule是Spring框架提供的一种简单的定时任务解决方案。它是基于Java的Scheduled注解&#xff0c;可以让我们在不影响主线程的情况下&#xff0c;定时、周期性地执行任务。 为什么选…

vue+ant design vue实现搜索区域form

1.要实现的效果&#xff1a; form部分form-item自动铺开&#xff0c;间距适当&#xff0c;屏幕大小不同能根据屏幕大小变化。 2.vue组件中的代码示例 重点html代码&#xff1a; <!-- 搜索区域 --><div class"table-page-search-wrapper"><a-form la…

vue 七款低代码平台对比

vue 七款低代码平台对比 摘要平台表单设计form-generatorLowCodeEngine 可视化设计OpenDataVGoView 门户设计AgileBPM轻流云程低代码平台 摘要 调研低代码平台时看了很多网站&#xff0c;被我大概分为了三种&#xff1a;页面设计、可视化设计、门户设计&#xff0c;其中功能也…

【vue3中使用swiper组件】

【vue3中使用swiper组件】超详细保姆级教程 效果展示简介版本安装Swiper用法完整代码展示html静态展示js逻辑展示&#xff08;vue3 --- ts&#xff09;官方文档导入模块 css样式展示 &#xff08;自行更改所需&#xff09;官方文档样式 效果展示 简介版本 安装Swiper 项目终端中…

Observability:Synthetic monitoring - 合成监测入门

从我们的全球测试基础设施监控关键用户旅程&#xff0c;并了解网络和前端性能对用户体验的影响。 全面了解你的网站性能、功能和可用性&#xff08;从开发到生产&#xff09;&#xff0c;并在客户之前发现问题。合成监测&#xff08;synthetic monitoring&#xff09;使你能够模…

关于表单提交

一、表单实例 <!-- 把表单信息放入到表格当中&#xff0c;显示的内容更加整齐 --><form action"" method"get"><h1 align"center">用户注册</h1><input type"hidden" name"action" value"l…

正则表达式 - 语法 | 一看就懂!!!(二)

目录 一、正则表达式 - 语法 二、普通字符 三、非打印字符 四、特殊字符 五、限定符 &#xff08;一&#xff09;限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。 &#xff08;二&#xff09;正则表…

Eureka注册失败解决

根据查看网上资料发现是服务端自己自己注册了&#xff0c;所以需要自己关闭服务端注册 加上两行代码 fetch-registry: false register-with-eureka: false 即可注册成功

初级保育员专业知识生活管理考试题库及答案

​本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题…