每日一个设计模式之【代理模式】

news2025/8/16 15:23:26

文章目录

  • 每日一个设计模式之【代理模式】
    • ☁️前言🎉🎉🎉
    • 🌻模式概述
    • 🌱代理模式的实现
      • 🍀静态代理
      • 🍀动态代理
        • 🐳JDK代理
        • 🐳CGLib代理
      • 🍀拓展
        • 🐳虚拟代理
        • 🐳远程代理
        • 🐳访问代理
        • 🐳缓冲代理
        • 🐳智能引用代理
        • 🐳Javassist动态代理
        • 🐳ByteBuddy动态代理
    • 🌲总结

每日一个设计模式之【代理模式】

☁️前言🎉🎉🎉

  大家好✋,我是知识汲取者😄,今天给大家带来一篇有关代理模式的学习笔记。众所周知能够熟练使用设计模式是一个优秀程序猿的必备技能,当我们在项目中选择一个或多个合适的设计模式,不仅能大大提高项目的稳健性可移植性可维护性,同时还能让你的代码更加精炼,具备艺术美感

推荐阅读

  • 设计模式导学:🚪传送门
  • 每日一个设计模式系列专栏:🚪传送门
  • 设计模式专属Gitee仓库:✈启程
  • 设计模式专属Github仓库:🚀上路
  • 知识汲取者的个人主页:💓点我哦

🌻模式概述

  • 什么是代理模式

    代理模式(Proxy Pattern)也称委托模式,是一种结构型模式,

  • 代理模式的作用:通过增加一个中间层,增强方法

    增强方法是指增强方法的功能,让原本被代理类的方法具有更多其它的功能,这个类似于装饰器模式,只需要再代理类中增加代码逻辑,以此让被代理类的方法增添许多新功能

  • 代理模式的优缺点

    • 优点

      • 扩展性高。想要改动功能,可以再保留原有类的同时增加一个代理类,从而无需修改原有代码,符合开闭原则
      • 安全性高。通过代理类,可以控制被委托对象的访问控制,提高系统的安全性
      • 耦合度低。客户端只需要和代理类进行交互,不需要和具体功能的实现类进行交互,降低了系统的耦合度

      ……

    • 缺点

      • 增加了系统的复杂度,因为多添加一个中间层,而且一些代理模式实现起来也较为复杂(例如远程代理)

      ……

  • 代理模式的适用场景

    • 当客户端对象需要访问远程主机中的对象时可以使用远程代理
    • 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理
    • 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理
    • 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理
    • 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理
    • 想要实现AOP编程,可以使用动态代理
  • 代理模式的角色划分

    • 抽象主题(Subject):声明了真实主题和代理主题的共同接口
    • 真实主题(RealSubject):具体的被代理类(被委托类),是被代理的具体对象,实现了真实的业务操作,当Proxy都无法胜任工作时,RealSubject就会出场
    • 代理主题(Proxy):具体的代理类(委托类),它包含了真实主题的引用,代理对象也可以有自己的一些附属操作,帮助真实主题更好地处理请求
    • 请求者(Client):系统的外部交互类,与代理对象进行交互,对应本文中的测试类
  • 代理模式的分类

    代理模式各种各样,且应用范围很广,常见的可以大致将代理模式分为两大类:静态代理和动态代理。此外,还存在虚拟代理、远程代理和访问代理

    • 虚拟代理(Virtual Proxy):虚拟代理只有当正真需要实例时,它才会生成和初始化实例对象。它能够很大程度节约内存,类似于懒加载
    • 远程代理(Remote Proxy):远程让我们可以让我们完全不必在意RealSubject角色是否在远程网络上,可以如同它自己身体一样(透明地)调用它的方法。它能够很大程度提高系统分布式应用的能力,Java的RMI(RemoteMethodInvocation,远程方法调用)就相当于Remote Proxy
    • 访问代理(Access Proxy):也称保护代理(Protect Proxy),访问代理用于在调用RealSubject角色的功能时设置访问权限,只允许指定的用户调用方法,而当其它用户调用方法时则直接报错
    • 缓冲代理(Buffer Proxy):为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间
    • 智能引用代理(Smart Proxy):为某一个对象的引用提供额外操作
    • 静态代理(Static Proxy):代理类和被代理类的关系在运行前(也就是编译阶段)就确定了
    • 动态代理(Dynamic Proxy):代理类和被代理类的关系在运行时确定

🌱代理模式的实现

🍀静态代理

在静态代理中,代理类和被代理类的关系在编译阶段就已经确定了,它们都需要实现一个相同的接口

温馨提示:静态代理是对目标对象的方法进行手动增强,不灵活又麻烦,因此开发过程中基本用不到。(静态代理是理解动态代理的基础,因此也很有必要进行学习)

  • 静态代理的优点:相较于动态代理实现起来较为简单

  • 静态代理存在的弊端

    • 存在代码冗余。代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复
    • 可维护性差。不易维护,一旦接口更改,代理类和目标类都需要更改,在实际项目中应用较少
    • 灵活度低。一旦确定了代理关系就很难进行更改

实例

问题描述:对于明星,某一个地方想请明星去开演唱会唱歌,它的请求会先被明星的经纪人收到,得到经纪人的同意后,才会让明星去那个地方开演唱会,演唱结束后再由经纪人安排到其它地方进行延长

问题分析:上诉问题中的明星(Star)就可以看作是一个Subject,而经纪人(Broker)就可以看作是应该Proxy,它负责帮助明星处理日常的事物,而地方就是Client(也就是下文中的Test类)

image-20221117201623170

创建抽象主题
创建真实主题
创建代理主题
编写测试类
  • Step1:创建抽象主题

    package example1;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 
     * @description 所有明星的抽象类
     */
    public interface Star {
    
        /**
         * 唱歌
         * @param name 歌名
         */
        void sing(String name);
    }
    
  • Step2:创建真实主题

    package example1;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title
     * @description 具体的某一个明星
     */
    public class StarImp implements Star{
        private String name;
    
        public StarImp() {
            this.name = "薛之谦";
        }
    
        /**
         * 唱歌
         * @param name 歌名
         */
        @Override
        public void sing(String name) {
            System.out.println(this.name + "正在唱" + name);
        }
    }
    
  • Step3:创建代理主题

    package example1;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 经纪人
     * @description 明星的静态代理类
     */
    public class Broker implements Star{
    
        //委托对象
        private Star target;
    
        public Broker() {
            this.target = new StarImp();
        }
    
        /**
         * 唱歌方法的代理方法
         * @param name 歌名
         */
        @Override
        public void sing(String name) {
            System.out.println("经纪人同意明星去演唱");
            target.sing(name);
            System.out.println("演唱结束,经纪人安排明星前往另一个地方开演唱会");
        }
    }
    
  • Step4:编写测试类

    package example1;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 测试类
     * @description 用于测试静态代理
     */
    public class Test {
        public static void main(String[] args) {
            Star broker = new Broker();
            broker.sing("天后");
        }
    }
    

    测试结果:

    image-20221117201801060

🍀动态代理

在动态代理中,代理类和被代理类之间的关系是在运行阶段确定的,常见的动态代理有JDK代理和CGLIB代理

  • JDK代理基于接口进行动态代理,使用反射技术

    JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的,只能对该类所实现接口中定义的方法进行代理,同时代理类需要实现目标类的接口(基于这种特性,可以趣称JDK代理方式为”拜把子模式“),否则报java.lang.ClassCastException: com.sun.proxy.$Proxy4 cannot be cast to com.hhxy.proxy.Calculator异常,这在实际编程中有一定的局限性,而且使用反射的效率也不高,生成的代理类在com.sun.proxy包下,类名为$proxy数字

  • CGLib代理基于类进行动态代理,使用字节码技术

    比使用反射的效率要高,但CGLib不能对final修饰的方法进行代理,因为CGLib原理是动态生成被代理类的子类,生成的代理类和目标类在同一包下且为被代理类的子类(基于这种特性,可以趣称CGLib代理方式为“认干爹模式”)

  • 两者的比较:JDK代理是使用反射实现,效率相对较低,但是由于它是Java封装好了的,使用起来相对简单,但是只能对该类所实现接口中定义的方法进行代理;而CGLib是使用字节码技术,效率相对高很多,并且几乎可以代理任意的方法(除了final修饰的方法),但是实现起来较为复杂

🐳JDK代理

JDK1.3开始支持JDK动态代理

示例

接着以静态代理的示例来实现

创建抽象主题
创建具体主题
创建代理主题
编写测试类
  • Step1:创建抽象主题

    和静态代理的代码一致,详情请参考Github或Gitee仓库,略……

  • Step2:创建具体主题

    和静态代理的代码一致,详情请参考Github或Gitee仓库,略……

  • Step3:创建代理主题

    package example2.jdk;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 经纪人
     * @description 明星的代理类
     */
    public class Broker{
    
        //委托对象
        private Star target;
    
        public Broker() {
            this.target = new StarImp();
        }
    
        /**
         * 获取代理对象
         */
        public Star getProxy(){
            /**
             * 参数一: loader表示目标类的类加载器
             * 参数二: interfaces表示对象实现的所有接口对象的Class对象的数组
             *  参数三: h表示匿名内部类对象,它是JDK动态代理类实现的核心代码
             */
            return (Star) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        /**
                         * 唱歌方法的代理方法
                         * @param proxy 代理类对象,即Broker对象
                         * @param method 要执行的代理方法,即StarImp的sing方法
                         * @param args args为代理方法的参数列表,即StarImp的sing方法的所有参数
                         * @return
                         */
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("经纪人同意明星去演唱");
                            Object result = method.invoke(target, args);
                            System.out.println("演唱结束,经纪人安排明星前往另一个地方开演唱会");
                            return result;
                        }
                    });
        }
    }
    
  • Step4:编写测试类

    package example2.jdk;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 测试类
     * @description 用于测试JDK动态代理
     */
    public class Test {
        public static void main(String[] args) {
            Broker broker = new Broker();
            Star proxy = broker.getProxy();
            proxy.sing("丑八怪");
        }
    }
    

    测试结果:

    image-20221117220711785

🐳CGLib代理

Spring在5.X之前默认的动态代理实现一直是JDK动态代理。但是从5.X开始,Spring就开始默认使用CGLib来作为动态代理实现。并且SpringBoot从2.X开始也转向了CGLib动态代理实现

什么导致了Spring体系整体转投CGLib呢,JDK动态代理又有什么缺点呢?

CGLib是一个开源项目,它的底层是字节码处理框架ASM,CGLib提供了比JDK更为强大的动态代理。主要相比JDK动态代理的优势有:

  1. CGLib动态代理的应用范围更广。JDK动态代理只能基于接口,是“拜把子模式”,只能对该类所实现接口中定义的方法进行代理,得到的代理对象只能赋值给接口变量;CGLib动态代理是基于类,是“认干爹模式”,CGLib是通过生成子类来实现的,代理对象既可以赋值给实现类变量,又可以赋值给接口变量

  2. CGLib的性能更高。JDK底层使用反射技术(通过解释执行),而CGLib底层是使用字节码技术(通过编译执行),,解释执行的代码要比编译执行的代码要慢

    关于反射可以参考这篇文章:一文带你快速了解Java中的反射机制

示例

接着以静态代理的示例来实现

创建抽象主题
创建具体主题
创建代理主题
编写测试类
导包
  • Step1:导包

    • 方式一:CGLib所依赖的Jar包如下所示,使用Maven导包

              <!--cglib依赖的jar包-->
              <dependency>
                  <groupId>cglib</groupId>
                  <artifactId>cglib-nodep</artifactId>
                  <version>3.3.0</version>
              </dependency>
              <dependency>
                  <groupId>cglib</groupId>
                  <artifactId>cglib</artifactId>
                  <version>3.3.0</version>
              </dependency>
      
    • 方式二:直接下载jar包

      image-20221117231908536

  • Step2:创建抽象主题

    和静态代理的代码一致,详情请参考Github或Gitee仓库,略……

  • Step3:创建具体主题

    和静态代理的代码一致,详情请参考Github或Gitee仓库,略……

  • Step4:创建代理主题

    package example2.cglib;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 经纪人
     * @description 明星的代理类
     */
    public class Broker implements MethodInterceptor {
    
        //字节码增强器对象
        private Enhancer enhancer;
    
        //委托对象
        private Star target;
    
        public Broker() {
            this.target = new StarImp();
            this.enhancer = new Enhancer();
        }
    
        public Star getProxy(){
            //将被代理的类设置为父类
            enhancer.setSuperclass(StarImp.class);
            //设置拦截器
            /*
            当前这个Broker类本质是一个拦截器,在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,
            来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口
             */
            enhancer.setCallback(this);
            //返回代理类对象
            return (Star) enhancer.create();
        }
    
        /**
         * 唱歌方法的代理方法
         * @param o 被代理对象,即StarImp对象
         * @param method 被代理的方法,即StarImp的sing方法
         * @param objects 被代理的方法的参数列表,即StarImp的sing方法的所有参数
         * @param methodProxy 代理对象
         * @return
         */
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("经纪人同意明星去演唱");
            Object result = methodProxy.invokeSuper(o, objects);
            System.out.println("演唱结束,经纪人安排明星前往另一个地方开演唱会");
            return result;
        }
    }
    
  • Step5:编写测试类

    package example2.cglib;
    
    /**
     * @author ghp
     * @date 2022/11/17
     * @title 测试类
     * @description 用于测试JDK动态代理
     */
    public class Test {
        public static void main(String[] args) {
            Broker broker = new Broker();
            Star proxy = broker.getProxy();
            proxy.sing("天外来物");
        }
    }
    

    测试结果:

    image-20221117232145437

🍀拓展

先占坑,未完待续……相信未来的我一定会完成下面这一部分的内容的😈

🐳虚拟代理

🐳远程代理

🐳访问代理

🐳缓冲代理

🐳智能引用代理

🐳Javassist动态代理

Javassist是一个开源的分析、编辑和创建Java字节码的类库,可以直接编辑和生成Java生成的字节码。相对于BCEL、ASM等这些工具,开发者不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。

在日常使用中,javassit通常被用来动态修改字节码。它也能用来实现动态代理的功能。

详情请参考:动态代理大揭秘,带你彻底弄清楚动态代理!

🐳ByteBuddy动态代理

ByteBuddy(字节码伙计),是一个大名鼎鼎的开源库,和Cglib一样,也是基于ASM实现。还有一个名气更大的库叫Mockito,相信不少人用过这玩意写过测试用例,其核心就是基于ByteBuddy来实现的,可以动态生成mock类,非常方便。另外ByteBuddy另外一个大的应用就是java agent,其主要作用就是在class被加载之前对其拦截,插入自己的代码。

ByteBuddy非常强大,是一个神器。可以应用在很多场景。

详情请参考:动态代理大揭秘,带你彻底弄清楚动态代理!

🌲总结

  • 相关设计模式
    • Adapter 模式:Adapter模式适配了两种具有不同接口(API)的对象,以使它们可以一同工作。而在Proxy模式中,Proxy角色与RealSubject角色的接口(API)是相同的(透明性)
    • Decorator 模式:Decorator模式与Proxy模式在实现上很相似,不过它们的使用目的不同。Decorator模式的目的在于增加新的功能。而在Proxy模式中,与增加新功能相比,它更注重通过设置代理人的方式来减轻本人的工作负担

自此,文章就结束了,如果觉得本文对你有一丢丢帮助的话😄,欢迎点赞👍+评论✍,您的支持将是我写出更加优秀文章的动力O(∩_∩)O


上一篇

下一篇

参考文章

  • Spring学习笔记
  • 代理模式 | 菜鸟教程 (runoob.com)
  • 保护代理模式-Access Proxy(Java实现)
  • 代理模式的使用总结
  • 代理模式(三):远程代理,虚拟代理,缓冲代理
  • [什么是代理模式_编程设计_IT干货网 (itgh.cn)](https://www.itgh.cn/post/7962.html#:~:text=智能引用 (Smart,Reference)代理的作用是,当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来等。 比如,小帅作为代理商,肯定是要赚钱的,客户下了一个10000元的订单,小帅就和刘望星谈好提成10%,就可以在代理类中把金额扣掉。)
  • 动态代理大揭秘,带你彻底弄清楚动态代理!

在次致谢🌹🌹🌹

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

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

相关文章

UE 5.1正式发布,有哪些值得一试的新功能?

UE 5.1正式发布&#xff0c;所以今天咱们就来看看最新版都具体更新和改进了哪些功能吧—— Nanite和Lumen Nanite和Lumen是UE 5.0版本更新的两个主要内容&#xff0c;UE 5.1则是对其进行进一步的改进。 Nanite添加了对双面材质和新的可编程光栅化程序的支持&#xff0c;可以通…

认识前端闭包

1、前言&#xff1a;&#xff08;先介绍一下函数的存储原理&#xff09; &#xff08;1&#xff09;基本函数存储原理&#xff1a; 首先我们定义一个函数&#xff0c;然后调用&#xff0c;如下&#xff1a; <script>function test(){let name yiyiconsole.log(name)}t…

未来的产品经理,需要什么样的原型设计工具?

我和原型工具的往事 作为一只工龄十年的产品汪&#xff0c;我一直在使用原型设计工具——摹客 &#xff0c;对于摹客可谓耳熟能详。 初次听说&#xff0c;是产品社群里的点赞安利&#xff1a;做移动端&#xff0c;用摹客。 当时正值2015年&#xff0c;移动端热到不行&#x…

【动态规划】字串中回文的个数

一、题目描述 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 注&#xff1a; 回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符…

Matlab论文插图绘制模板—水平三维柱状图(渐变)

在之前的文章中&#xff0c;分享了Matlab水平三维柱状图的绘制模板。 高度赋色的水平三维柱状图&#xff1a; 这次再来分享一下渐变赋色的水平三维柱状图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;Matlab论文插图绘制模板系列&#xff0c;旨在降低大家…

CellMarker 2.0 | 鼠标点一点就完成单细胞分析的完美工具~

1写在前面 本期我们介绍一下CellMarker 2.0上更新的6个网页工具&#xff0c;主要是用于scRNA-seq数据的分析与可视化。&#x1f970; 网址如下&#xff1a;&#x1f447; &#x1f4cd;http://bio-bigdata.hrbmu.edu.cn/CellMarker/index.html 2Single cell web tools 概览 作者…

“幂等”不等于“分布式锁”,也不得不考虑返回值

. 概览 在分布式系统中&#xff0c;幂等是一个非常重要的概念&#xff0c;常常与“重试”一起出现。当调用一个远程服务发生超时&#xff0c;调用方并不知道请求是否执行成功&#xff0c;这就是典型的“第三态”问题。对于这个问题最常见的解决方案便是进行主动重试&#xff0…

20道前端高频面试题(附答案)

setTimeout 模拟 setInterval 描述&#xff1a;使用setTimeout模拟实现setInterval的功能。 实现&#xff1a; const mySetInterval(fn, time) {let timer null;const interval () > {timer setTimeout(() > {fn(); // time 时间之后会执行真正的函数fninterval()…

2022年NPDP新版教材知识集锦--【第三章节】(4)

【敏捷开发】 8.1敏捷开发模型的定义 门径和敏捷方法的特点&#xff1a;门径流程适用于开发硬件产品&#xff0c;而敏捷方法适用于开发软件产品。这两种方法是相对独立的。敏捷方法和门径流程不是互相取代的关系。相反敏捷方法是一种有效的微观规划工具或项目管理工具&#x…

如何使用远程控制软件并将用途最大化?4款国内外优质应用测评解析

说起远控软件&#xff0c;大家的第一印象是什么&#xff1f;是能实现电脑控制电脑、手机平板控制电脑、或手机电脑控制另外手机的操作需求&#xff0c;还是TeamViewer、ToDesk、向日葵、微软桌面这类的产品名称&#xff1f; 在三年疫情下&#xff0c;我们或多或少都经历了居家…

VMware安装Centos

此教程版本使用的是 VMware 16 、Centos 7 虚拟机安装 Centos安装 注: win10下vmware 15 可能会有蓝屏现象 排查:自行检查是否安装有 KB4601319 补丁,如果有请卸载,或者安装 vmware 16 官网下载地址 跳转 控制面板 — 程序与功能 — 查看已安装的更新 虚拟机安装 打开vmware…

【快速上手系列】使用阿里云发送测试短信超简单教程

【快速上手系列】使用阿里云发送测试短信超简单教程 步骤 一、阿里云配置 1、进入阿里云首页点击短信服务 2、短信服务界面 3、点击快速学习&#xff0c;然后绑定测试手机号&#xff0c;绑定好后点击调用API发送短信 4、左侧可以看到一些参数设置&#xff0c;右面是可以选择…

基于Ryu 防火墙的检测和解决异常入侵的流量

基于Ryu 防火墙的检测和解决异常入侵的流量基于Ryu 防火墙的检测和解决异常入侵的流量防火墙规则实验仿真环节&#xff1a;1.下载代码到本地2.安装相关依赖库3.设置openflow1.34.启动控制器异常检测&#xff1a;异常解决&#xff1a;规则合并&#xff1a;防火墙规则树&#xff…

(一)EasyExcel的使用(读取数据到实体类即绑定实体类)

最近遇到了一个excel简单的导入导出的需求&#xff0c;因此就对easyexcel第三方插件的使用做一点总结&#xff0c;大家可以看一看&#xff0c;可能会对你有点帮助。 目录 前言&#xff1a; 1、引入easyexcel相关依赖 2、创建对应excel的实体类 3、导入excel&#xff0c;并…

mac照片肖像美容ON1 Portrait AI 2023

人像照片怎么美容编辑呢&#xff1f;使用 ON1 Portrait AI 2023只需点击一下即可完美修饰。它使用机器学习来查找照片中的每一张脸&#xff0c;并自动使它们看起来很棒。它分析每张脸&#xff0c;并为皮肤、眼睛和嘴巴添加适量的修饰&#xff0c;立即为您提供专业的效果。 软件…

目标检测算法——工业缺陷数据集汇总1(附下载链接)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f680;近期&#xff0c;小海带在空闲之余&#xff0c;收集整理了一批自动驾驶开源数据集供大家参考。 整理不易&#xff0c;小伙伴们记得一键三连喔&#xff01;&#xff01;&#xff01;&#x1f91e…

计算机毕业设计:基于html制作大学生网上报到系统响应式模板项目源码

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

UNet - 预测数据predict(多个图像的分割)

目录 1. 介绍 2. predict 预测分割图片 3. 结果展示 4. 完整代码 1. 介绍 之前已经将unet的网络模块、dataset数据加载和train训练数据已经解决了&#xff0c;这次要将unet网络去分割图像&#xff0c;下面是之前的链接 unet 网络&#xff1a;UNet - unet网络 dataset 数…

chineseocr测试具体部署步骤(不用web界面)

源项目地址&#xff1a; https://github.com/chineseocr/chineseocr 由于chineseocr需要在web上展示检测结果&#xff0c;还需要安装web相关内容&#xff0c;我的硬件是nvidia agx orin只需要在本地查看检测结果&#xff0c;做如下操作 找到源码项目中的test.ipynb,改写成test.…

天津教育杂志天津教育杂志社天津教育编辑部2022年第30期目录

卷首语 构建精准资助模式 保障经济困难学生安心求学 本刊编辑部; 1 本刊视线_关注 中学生行为习惯养成教育的策略——基于福州第十五中学学生行为习惯养成教育的实践 贺玉亮;林瑶; 4-6 本刊视线_特殊教育《天津教育》投稿&#xff1a;cn7kantougao163.com 面向听障…