Spring02——bean基础配置、bean实例化——构造方法/静态工厂/实例工厂与FactoryBean、bean的生命周期

news2024/11/13 4:37:18

IOC相关内容

通过前面两个案例,我们已经学习了bean如何定义配置,DI如何定义配置以及容器对象如何获取的内容,接下来主要是把这三块内容展开进行详细的讲解。

  • bean基础配置
  • bean实例化——构造方法
  • bean实例化——静态工厂
  • bean实例化-实例工厂与FactoryBean
  • bean的生命周期

06-bean基础配置

对于bean的配置中,主要会讲解

  • bean基础配置
  • bean的别名配置
  • bean的作用范围配置(重点)

bean的基础配置—id与class

对于bean的基础配置,在前面的案例中已经使用过:

<bean id="" class=""/>

其中,bean标签的功能、使用方式以及id和class属性的作用,我们通过一张图来描述下
在这里插入图片描述

bean的name属性

我们可以在bean标签中配置name属性,来充当别名,下面我们演示一下

  1. 配置别名
    打开spring的配置文件applicationContext.xml
<!--<bean id="bookDao" class="com.yolo.dao.impl.BookDaoImpl"/>-->
    <bean id="bookDao" name="bookDao2" class="com.yolo.dao.impl.BookDaoImpl"/>
    
    <!--<bean id="bookService" class="com.yolo.service.impl.BookServiceImpl">-->
    <bean id="bookService" name="bookService2 service servicetwo" class="com.yolo.service.impl.BookServiceImpl">
        <!--<property name="bookDao" ref="bookDao"/>-->
        <property name="bookDao" ref="bookDao2"/>
    </bean>
  1. 根据名称容器中获取bean对象
public class AppForName {
    public static void main(String[] args) {
        // 获取IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean对象
//        BookService bookService = (BookService) ac.getBean("bookService");
        BookService bookService = (BookService) ac.getBean("bookService2");
        
        // 获取到对象后就调用对象方法
        bookService.save();
    }
}
  1. 运行结果
    与之前一致
    在这里插入图片描述
    即:相当于id中的与name中的等价,都代表相应的bean对象

注意事项: bean依赖注入的ref属性指定bean,必须在容器中存在,而ref的值也可以是name里的别名,不过还是建议用id值来注入

如果我们在调用getBean(String name)方法时,传入了一个不存在该名称的bean对象,则会报错NoSuchBeanDefinitionException,此时我们要检查一下是哪边写错了(例如bean的id和name都没有service100,而getBean的参数却写了service100)

bean别名配置总结:

在这里插入图片描述

bean作用范围scope配置

关于bean的作用范围是bean属性配置的一个重点内容。
bean的scope有两个取值:

  • singleton:单例(默认)
  • prototype:非单例

验证IOC容器中对象是否为单例

  • 验证思路
    对同一个bean创建两个对象,然后打印二者的地址值,看看是否一致
  • 代码实现
public class AppForScope {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ac.getBean("bookService");
        BookService bookService2 = (BookService) ac.getBean("bookService");
        System.out.println(bookService);
        System.out.println(bookService2);
    }
}

输出结果如下,地址值一致,确实是单例的
在这里插入图片描述

  • 那如果我想创建出来非单例的bean对象,该如何实现呢?
    配置bean的scope属性为prototype

配置bean为非单例

在Spring配置文件中,配置scope属性来实现bean的非单例创建
在Spring的配置文件中,修改 的scope属性

<bean id="bookService" class="com.yolo.service.impl.BookServiceImpl" scope="prototype">
        <property name="bookDao" ref="bookDao2"/>
    </bean>

运行结果如下,地址值不一致
在这里插入图片描述

bean作用范围scope配置总结

在这里插入图片描述

scope使用后续思考

介绍完scope属性以后,我们来思考几个问题:

  1. 为什么bean默认为单例?
    • bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
    • bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
  2. 哪些bean对象适合交给spring管理?
    • 表现层对象(controller)
    • 业务层对象(service)
    • 数据层对象(dao)
    • 工具对象(util)
      上述这些造一次就可以反复使用的对象
  3. 哪些bean对象不适合交给spring管理?
    • 封装实体的域对象(domain,pojo)
      即:有状态的对象不适合交给spring管理,有状态指里边记录了它的成员变量的一些属性值。会造成线程不安全
  4. bean在容器中是单例的,会不会产生线程安全问题?
    • 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
    • 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。

07-bean实例化——构造方法

对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?
就需要研究下bean的实例化过程,在这块内容中主要解决两部分内容,分别是

  • bean是如何创建的
  • 实例化bean的三种方式
    • 构造方法(常用)
    • 静态工厂(了解)
    • 实例工厂(了解)
      • FactoryBean(实用)

在讲解这三种创建方式之前,我们需要先确认一件事:

  • bean本质上就是对象,对象在new的时候会使用构造方法完成,那创建bean也是使用构造方法完成的
  • 基于这个知识点出发,我们来验证spring中bean的三种创建方式

构造方法实例化

  1. 在之前的BookDaoImpl类中添加一个无参构造函数,并打印一句话,方便观察结果。
public class BookDaoImpl implements BookDao {
    public BookDaoImpl() {
        System.out.println("book dao constructor is running");
    }

    @Override
    public void save() {
        System.out.println("book dao save");
    }
}
  1. 运行程序
    输出结果如下
    在这里插入图片描述
  2. 接下来我们将构造器私有化继续测试
public class BookDaoImpl implements BookDao {
    private BookDaoImpl() {
        System.out.println("book dao constructor is running");
    }

    @Override
    public void save() {
        System.out.println("book dao save");
    }
}
  1. 运行程序,能执行成功,与公有方法运行结果一致,说明内部走的依然是构造函数,类中的私有、公有构造方法均能访问到,显而易见Spring底层用的是反射
    在这里插入图片描述
  2. 我们在构造函数中添加一个参数试试
public class BookDaoImpl implements BookDao {
    private BookDaoImpl(int i) {
        System.out.println("book dao constructor is running");
    }

    @Override
    public void save() {
        System.out.println("book dao save");
    }
}

运行程序,程序会报错 NoSuchMethodException ,说明Spring底层使用的是类的无参构造方法
同时,由于无参构造方法不存在,所以会报错 BeanCreationException
完事儿之后记得将空参构造器还原回去,把其中的输出语句也删了,方便我们进行下一步的测试

08-bean实例化——静态工厂

(了解)

  1. 创建一个新的类OrderDao及其实现类
public interface OrderDao {
    public void save();
}
public class OrderDaoImpl implements OrderDao {
    @Override
    public void save() {
        System.out.println("order dao save");
    }
}
  1. 创建工厂类OrderDaoFactory并提供一个static静态方法
public class OrderDaoFactory {
    public static OrderDao getOrderDao() {
        return new OrderDaoImpl();
    }
}
  1. 在类中通过工厂获取对象
public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
        OrderDao orderDao = OrderDaoFactory.getOrderDao();
        orderDao.save();
    }
}
  1. 运行结果如下
    在这里插入图片描述
    那我们如何将上述方式交给Spring来管理呢?
    这就要用到Spring中的静态工厂实例化的知识了,具体实现步骤为:
  2. spring的配置文件applicationContext.xml
<!--方式1:构造方法实例化bean-->
<!--    <bean id="bookDao" class="com.yolo.dao.impl.BookDaoImpl"/>-->

    <!--方式2:静态工厂实例化bean-->
    <!--
        class:工厂类的类全名
        factory-mehod:具体工厂类中创建对象的方法名
    -->
    <bean id="orderDao" class="com.yolo.factory.OrderDaoFactory" factory-method="getOrderDao"/>
  1. 在AppForInstanceOrder运行类中,使用从IOC容器中获取bean的方法进行运行测试
public class AppForInstanceOrder {
    public static void main(String[] args) {
        /*
        //通过静态工厂创建对象
        OrderDao orderDao = OrderDaoFactory.getOrderDao();
        orderDao.save();*/

        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
        orderDao.save();
    }
}
  1. 运行后,结果如下,与我们自己直接new对象没太大区别,而且还麻烦了,那这种方式的意义是什么呢?
    在这里插入图片描述
  2. 工厂方式的意义
public class OrderDaoFactory {
    public static OrderDao getOrderDao() {
        System.out.println("order factory setup ...");//模拟必要的业务操作
        //使用工厂方法这里还可以加一大堆业务逻辑
        return new OrderDaoImpl();
    }
}
在工厂的静态方法中,我们除了new对象还可以做其他的一些业务操作,而之前new对象的方式就无法添加其他的业务内容。
在 AppForInstanceOrder 类中,使用 OrderDaoFactory.getOrderDao() 来创建 OrderDao 对象,而不是直接使用 new 关键字  `OrderDao orderDao = OrderDaoFactory.getOrderDao();` 。
这样做的好处是,getOrderDao() 方法可以包含一系列的业务逻辑,而不是仅仅创建对象。因此,工厂方法为我们提供了一个中心化的地方来控制和管理对象的创建过程。这种模式在大型应用程序中尤其有用,可以让代码更具可维护性和可扩展性。

静态工厂实例化方式一般是用来兼容早期的一些老系统,所以了解为主。

09-bean实例化-实例工厂与FactoryBean

实例工厂实例化

  1. 创建一个新的类UserDao及其实现类
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("user dao save");
    }
}
  1. 创建UserDaoFactory工厂类,注意此处和静态工厂的工厂类不一样的地方是方法不是静态方法
public class UserDaoFactory {
    public UserDao getUserDao() {
        return new UserDaoImpl();
    }
}
  1. 创建AppForInstanceUser运行类,在类中通过工厂获取对象,由于不是静态方法了,所以我们需要先创建实例工厂对象,然后再用实例工厂对象调用方法
public class AppForInstanceUser {
    public static void main(String[] args) {
        // 创建实例工厂对象
        UserDaoFactory userDaoFactory = new UserDaoFactory();
        // 通过实例工厂对象创建对象
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();
    }
}
  1. 运行结果如下
    在这里插入图片描述

上述实例工厂的方式如何交给Spring管理呢

  1. applicationContext.xml中配置
<!--方式2:静态工厂实例化bean-->
<!--    <bean id="orderDao" class="com.yolo.factory.OrderDaoFactory" factory-method="getOrderDao"/>-->

    <!--方式3:实例工厂实例化bean-->
    <bean id="userDaoFactory" class="com.yolo.factory.UserDaoFactory"/>
    <!--
        factory-bean:工厂的实例对象
        factory-method:工厂对象中的具体创建对象的方法名
    -->
    <bean id="userDao" factory-method="getUserDao" factory-bean="userDaoFactory"/>

实例化工厂运行的顺序是:

  • 1.创建实例化工厂对象,对应的是上述第一行配置
  • 2.调用对象中的方法来创建bean,对应的是第二行配置
  1. 在运行类中,使用从IOC容器中获取bean的方法进行运行测试
public class AppForInstanceUser {
    public static void main(String[] args) {
        /*
        // 创建实例工厂对象
        UserDaoFactory userDaoFactory = new UserDaoFactory();
        // 通过实例工厂对象创建对象
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();*/
        
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.save();
    }
}
  1. 运行结果
    在这里插入图片描述

FactoryBean

实例工厂实例化的方式上述已经介绍完了,配置的过程还是比较复杂,要写两行配置,而且这两行还是高耦合的,所以Spring为了简化这种配置方式就提供了一种叫FactoryBean的方式来简化开发。
在这里插入图片描述
具体使用步骤为:

  1. 创建一个UserDaoFactoryBean类,实现FactoryBean接口,重写接口方法
    在这里插入图片描述
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    // 代替原始实例工厂UserDaoFactory中创建对象的方法
     /*public UserDao getUserDao() {
        return new UserDaoImpl();
    }*/
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    // 创建的对象的类型 .class
    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}
  1. 在Spring的配置文件中修改userDao的bean
<!--方式3:实例工厂实例化bean-->
    <!--<bean id="userDaoFactory" class="com.yolo.factory.UserDaoFactory"/>
    <bean id="userDao" factory-method="getUserDao" factory-bean="userDaoFactory"/>-->

    <!--方式4:使用FactoryBean实例化-->
    <bean id="userDao" class="com.yolo.factory.UserDaoFactoryBean"/>
  1. 运行结果如下
    与实例工厂方法运行结果一致
    在这里插入图片描述
    FactoryBean方式在Spring去整合其他框架的时候会被用到,所以这种方式需要我们理解掌握。

FactoryBean接口的三个方法

查看源码会发现,FactoryBean接口其实会有三个方法,分别为

    T getObject() throws Exception;

    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
  1. 方法一: getObject(),被重写后,在方法中进行对象的创建并返回
  2. 方法二: getObjectType(),被重写后,主要返回的是被创建类的Class对象
  3. 方法三: 没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true,一般不重写

10-bean的生命周期

  1. 什么是生命周期?
    • 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。
  2. bean生命周期是什么?
    • bean对象从创建到销毁的整体过程。
  3. bean生命周期控制是什么?
    • 在bean创建后到销毁前做一些事情。
      现在我们面临的问题是如何在bean的创建之后和销毁之前把我们需要添加的内容添加进去。

生命周期设置

具体的控制有两个阶段:
1. bean创建之后,想要添加内容,比如用来初始化需要用到资源
2. bean销毁之前,想要添加内容,比如用来释放用到的资源

  1. 添加初始化和销毁方法
    针对这两个阶段,我们在BookDaoImpl类中分别添加两个方法,方法名随便取
public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println("book dao save");
    }

    // bean初始化对应的操作
    public void init() {
        System.out.println("init ...");
    }

    // bean销毁前对应的操作
    public void destroy() {
        System.out.println("destroy ...");
    }
}
  • 配置生命周期
    修改bookDao的配置
<bean id="bookDao" class="com.yolo.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>
  • 运行程序
    输出结果如下
    在这里插入图片描述

从结果中可以看出,init方法执行了,但是destroy方法却未执行,这是为什么呢?

  • Spring的IOC容器是运行在JVM中
  • 运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行
  • main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了
  • 所以没有调用对应的destroy方法

知道了出现问题的原因,具体该如何解决呢?继续往下看

close关闭容器

  • ApplicationContext接口中没有close方法,它的子类中有close方法
  • 所以需要将 ApplicationContext 更换成 ClassPathXmlApplicationContext,然后调用close方法
public class AppForLifeCycle {
    public static void main(String[] args) {
        // 获取IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean对象
        BookDao bookDao = (BookDao) ac.getBean("bookDao");
        // 获取到对象后就调用对象方法
        bookDao.save();
        // 关闭容器
        ac.close();
    }
}

运行程序,输出如下,可以看到destroy正常输出
在这里插入图片描述

注册钩子关闭容器

上述方式属于比较暴力的关闭方法,还有另一种方法

  • 在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
  • 调用ClassPathXmlApplicationContext的 registerShutdownHook() 方法
public class AppForLifeCycle {
    public static void main(String[] args) {
        // 获取IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 注册关闭钩子
        ac.registerShutdownHook();
        // 获取bean对象
        BookDao bookDao = (BookDao) ac.getBean("bookDao");
        // 获取到对象后就调用对象方法
        bookDao.save();
    }
}

注意:registerShutdownHook在ApplicationContext中也没有
运行结果如下:
在这里插入图片描述

  • 那两种方式介绍完后,close和registerShutdownHook选哪个?
    • 相同点:这两种都能用来关闭容器
    • 不同点:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用使容器关闭。
      那么registerShutdownHook()方法可以在任意位置调用,下面的代码中将其放在了第二行,仍能正常输出,但要是将其换成close()方法,则会报错BeanFactory not initialized or already closed,这里就是already close
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        context.registerShutdownHook();
        BookDao bookDao = (BookDao) context.getBean("bookDao");
        bookDao.save();
    }
  • 开发中到底用哪个呢?
    答案是两个都不用
    分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多也比较乱。

Spring给我们提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置init-method和destroy-method

  • 接下来在BookServiceImpl完成这两个接口的使用
    1. 修改BookServiceImpl类,添加两个接口InitializingBean, DisposableBean并实现接口中的两个方法afterPropertiesSet和destroy
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {

    private BookDao bookDao;

    @Override
    public void save() {
        System.out.println("book service save");
        bookDao.save();
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("service destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init...");
    }
}
2. BookServiceImpl的bean配置如下
<bean id="bookService" class="com.yolo.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>
3. 重新运行App类,输出结果如下

在这里插入图片描述
可能存在的疑问:明明我们没调用bookService,但为什么上面的输出结果中有service呢?
解惑:所有IOC容器中的bean的初始化和销毁都会运行,所以service也会运行

bean生命周期小结

  1. 关于Spring中对bean生命周期控制提供了两种方式:
    • 在配置文件中的bean标签中添加init-method和destroy-method属性
    • 类实现InitializingBean与DisposableBean接口(了解)
  2. 对于bean的生命周期控制在bean的整个生命周期中所处的位置如下
    • 初始化容器
      1. 创建对象(内存分配)
      2. 执行构造方法
      3. 执行属性注入(set操作)(set…)
      4. 执行bean初始化方法(service init…)
    • 使用bean
      1. 执行业务操作(book dao save …)
    • 关闭/销毁容器
      1. 执行bean销毁方法(service destroy …)
  3. 关闭容器的两种方式:
    ConfigurableApplicationContext是ApplicationContext的子类,子类才有下面两种方法
    • close()方法
    • registerShutdownHook()方法

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

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

相关文章

笔记整理—内核!启动!—uboot部分(3)uboot启动内核传参

uboot会以tag的方式给内核传递参数&#xff0c;tag是一个数据结构&#xff0c;在uboot中与linux_kernel中都有相同的结构。 kernel接收到的传参由若干个tag构成&#xff0c;从tag_start到tag_end之间的数据构成&#xff0c;读到start时开始传参&#xff0c;end结束传参。 CON…

算法专利复现_基于ngboost和SHAP值可解释预测方法

大家好&#xff0c;我是重庆未来之智的Toby老师&#xff0c;最近看到一篇专利&#xff0c;名称是《基于NGBoost和SHAP值的可解释地震动参数概率密度分布预测方法》。该专利申请工日是2021年3月2日。 专利复现 我看了这专利申请文案后&#xff0c;文章整体布局和文字内容结构不错…

算法基础-区间合并

1、按照区间的左端点排序 2、 左端点小于等于ed&#xff0c;只需要更新ed和右端点的最大值 左端点大于ed&#xff0c;存入res中&#xff0c;并更新st和ed&#xff0c;最后一组数据手动插入res public class Main {public static void main(String[] args) {Scanner in new S…

Pinterest账号被封?试试这几种解封方法

Pinterest作为一个充满创意与灵感的视觉社交平台&#xff0c;吸引着大量用户和企业前来展示、收藏和分享他们的作品。然而&#xff0c;如同其他社交媒体平台一样&#xff0c;Pinterest也设立了一套严格的使用规则和监测机制&#xff0c;以保障平台内容的质量和用户的良好体验。…

景联文科技提供运动数据采集服务

运动数据的重要性 运动数据的收集与分析对于提升个人健康管理和运动表现具有重要意义。 通过收集心率、步态、速度等生理和运动参数&#xff0c;不仅可以为运动员提供个性化的训练方案&#xff0c;帮助其优化表现&#xff0c;还能早期发现并预防伤病。对于普通健身者而言&…

MVC架构模式

MVC(ModelView Controller)是软件工程中的一种软件架构模式 &#xff0c;它把软件系统分为模型、 视图和 控制器 三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码&#xff0c;将业务逻辑聚集到一个部件里面&#xff0c;在改进和个性化定制界面及用户交互的同时…

华为OD机试真题 - 字符成环找偶数O - 滑动窗口(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、…

KTV结算源码--SAAS本地化及未来之窗行业应用跨平台架构

一、代码 function 未来之窗_人工智能_KTV结账(title,桌台id,类型id,类型名称){if(room_status0){alert("空房不可操作");return "空房";}if(room_status1){alert("空房不可操作");}else if(room_status2){//alert("结账");var 未来之…

图像识别智能垃圾桶项目开发

一、项目思维导图 二、语音模块配置信息 三、项目程序 main.c garbage.c garbage.h uartTool.c //串口发送数据 uartTool.h

4款pdf在线编辑工具,带你搞定PDF

作为一个在办公室里日夜奋斗的文案策划人员&#xff0c;我深知在工作中&#xff0c;效率和工具的重要性。PDF文件的编辑是我们工作中不可或缺的一部分&#xff0c;而选择一款合适的PDF编辑器&#xff0c;就像是找到了一把打开效率之门的钥匙。今天&#xff0c;我就来和大家分享…

深度学习-HW3(CNN)卷积神经网络-图像分类-【Datawhale X 李宏毅苹果书 AI夏令营】

分类实际上是一个回归问题。 登录阿里云的账号&#xff0c;才发现有3个账号&#xff0c;要认证学生身份&#xff0c;试遍了3个账号后才试出学生认证号。打开看了一下&#xff0c;居然还有高校教师优惠申请&#xff0c;努力搞一个&#xff08;最近是想薅一把教师资格证的福利&a…

中仕公考怎么样?省考笔试成绩什么时候出?

根据往年的经验&#xff0c;省考笔试的成绩通常在考试后的大约一个月左右公布&#xff0c;但具体日期会根据各省份的公告而有所差异&#xff0c;不同省份具体时间不同&#xff0c;以2024年的为例&#xff1a; 广东省预计于笔试后约30天发布、山东省预计于笔试后约35天发布、浙…

操心没小课堂第一节 协同过滤算法

协同过滤算法 协同过滤算法&#xff08;Collaborative Filtering&#xff09;是推荐系统中一种广泛应用的技术&#xff0c;它主要依赖于用户的行为数据来预测用户可能感兴趣的内容。协同过滤算法可以分为两大类&#xff1a;基于用户的协同过滤&#xff08;User-Based Collabor…

【论文阅读】LJP法律判决预测论文笔记

[大模型 | 类案检索] Precedent-Enhanced Legal Judgment Prediction with LLM and Domain-Model Collaboration key point 会议&#xff1a;EMNLP2023 贡献&#xff1a;提出了一个结合领域模型和大模型的先例增强的LJP框架&#xff0c;其实主要是用到的大模型&#xff0c;比…

Python画笔案例-024 绘制八圆围正方

1、绘制八圆围正方 通过 python 的turtle 库绘制八圆围正方的图案&#xff0c;如下图&#xff1a; 2、实现代码 绘制一个八圆围正方&#xff0c;以下为实现代码&#xff1a; """八圆围正方.py """ from turtle import Turtle # 从海龟模块导入…

阶段二 - 小程序反编译及调试

在打开小程序后&#xff0c;小程序的apkg会放在以下目录中&#xff1a; 使用解包工具对小程序进行解包&#xff1a; 解包工具&#xff1a;链接: https://pan.baidu.com/s/1KLDbivGPCPhqt1nbLVbhXA?pwdkckq 提取码: kckq 解包后会生成一个这样的文件&#xff1a; 在这里输…

【Netty】FastThreadLocal比ThreadLocal快之源码解析

ThreadLocal 【并发设计模式】聊聊线程本地存储模式如何实现的线程安全 【Java并发】从simpleDateFormart聊聊threadlocal原理机制 前两篇中已经从源码角度进行剖析&#xff0c;本篇主要从设计角度剖析。 在并发中为了保证数据安全&#xff0c;可以采用数据隔离的方式 也就是…

微信视频号 点赞+关注+喜欢+发布评论

微信视频号 点赞关注喜欢发布评论 微信视频号 点赞关注喜欢发布评论

3127. 构造相同颜色的正方形(24.8.31)

题目 给你一个二维 3x3 的矩阵 grid&#xff0c;每个格子都是一个字符&#xff0c;要么是 B &#xff0c;要么是 W。字符 W 表示白色&#xff0c;字符 B 表示黑色。 你的任务是改变至多一个格子的颜色&#xff0c;使得矩阵中存在一个 2x2 颜色完全相同的正方形。 如果可以得到…

这位沉默寡言忠厚老实的商人遇到了哪位神奇女子搭救?

这位沉默寡言忠厚老实的商人遇到了哪位神奇女子搭救&#xff1f; 接下来&#xff0c;我将为你讲述一个关于侠女的故事&#xff0c;她救助了一个落难之人&#xff0c;并发表了许多关于剑侠的独特见解&#xff0c;这些都是前所未有的&#xff0c;简直精彩绝伦。有诗为证&#xff…