代理模式概述

1.代理模式概述

学习内容

1)概述

为什么要有 “代理” ?

  • 生活中就有很多例子,比如委托业务,黄牛(票贩子)等等
  • 代理就是被代理者没有能力或者不愿意去完成某件事情,需要找个人代替自己去完成这件事,这才是“代理”存在的原因。
  • 例如要租房子,房产中介可以在我们住房前代理我们找房子。中介就是代理,而自己就是被代理了。

在代码设计中,代理模式作用主要就是让 “被代理对象” 的某个方法执行之或者执行之加入其他增强逻辑。

前增强 : 例如获取当前时间

被代理对象调用方法

后增强 : 例如获取当前时间

计算方法执行的时间

2)代理的前提条件 : 掌握 !

  • 抽象角色 :声明功能
  • 代理角色 :实现抽象功能 , 完成代理逻辑
  • 被代理角色 :实现抽象功能

意味着被代理角色和代理角色有着共同的父类型(既抽象角色) , 例如我要租房子, 我只能找房产中介, 不能找票贩子
在这里插入图片描述

  • 代理模式存在两种实现方式:

    • 静态代理
    • 动态代理

知识小结

  1. 请说出代码中代理模式的作用?

    代理角色对 被代理就角色某个方法执行的前或者后进行 功能增强
    
  2. 请说出代理模式中的三个角色?

    抽象角色
    代理角色
    被代理角色
    

==============================================================================================================

1.1 静态代理

学习目标

  • 能够写出静态代理模式代码

内容讲解

  • 静态代理是由程序员创建 或 工具生成代理类的源码,再编译代理类。

    在程序运行前就已经存在代理类的字节码文件,代理类和被代理类的关系在运行前就确定了。

    简单理解 : 在程序运行之前 , 代理类就存在了,这就是静态代理 ; 动态代理是程序运行时动态生成代理类

  • 静态代理实现的步骤 :

    • 存在一个抽象角色
    • 定义被代理角色
    • 定义代理,增强被代理角色的功能

案例实践 :

  • 以现实中经纪人代理明星

已知存在接口:

// 1.抽象角色
interface Star {
    // 真人秀方法
    double liveShow(double money);

    void sleep();
}

定义被代理类:

  • 定义王宝强类,实现Star方法
// - 定义被代理角色(宝强)
class BaoQiang implements Star {

    @Override
    public double liveShow(double money) {
        System.out.println("宝强参加了一个真人秀活动赚了" + money + "钱");
        return money;
    }

    @Override
    public void sleep() {
        System.out.println("宝强累了 , 睡觉...");
    }
}

定义代理类:

  • 定义宋喆经纪人类
// - 定义代理角色(宋喆),增强被代理角色的功能
class SongZhe implements Star {
    private BaoQiang baoQiang;

    public SongZhe(BaoQiang baoQiang) {
        this.baoQiang = baoQiang;
    }

    @Override
    public double liveShow(double money) {
        // 前增强
        System.out.println("宋喆帮宝强拉了一个真人秀的活动,获取佣金" + money * 0.8 + "元");
        // 被代理角色的功能
        double result = baoQiang.liveShow(money * 0.2);
        // 后增强
        System.out.println("宋喆帮宝强把赚的钱存了起来...");
        return result;
    }

    @Override
    public void sleep() {
        // 前增强
        System.out.println("宋喆帮宝强定了一家五星级大酒店");
        baoQiang.sleep();
        // 后增强
        System.out.println("宋喆帮宝强退房...");
    }
}

定义测试类进行测试

/*
    静态代理实现的步骤  :
        - 存在一个抽象角色
        - 定义被代理角色(宝强)
        - 定义代理角色(宋喆),增强被代理角色的功能
 */
public class StaticAgentDemo {
    public static void main(String[] args) {
        // 创建被代理角色 , 没有任何增强
        BaoQiang baoQiang = new BaoQiang();
        double result = baoQiang.liveShow(1000);
        System.out.println(result);
        baoQiang.sleep();

        System.out.println("===========================");

        // 创建代码角色对象 , 可以对被代理角色功能做前后增强
        SongZhe songZhe = new SongZhe(baoQiang);
        double result2 = songZhe.liveShow(1000);
        System.out.println(result2);

        songZhe.sleep();
    }
}

关系图 :

在这里插入图片描述
宋喆和宝强都有共同的父类型。他们的业务方法都是一样。

静态代理和装饰模式的对比 :

​ BufferedRead(FileRead)

​ 1 装饰设计模式是功能扩展功能,在原有的功能基础之上增加了新的功能

​ 2 而代理主要对功能的前后做了增强

知识小结

  • 请问什么叫做静态代理?

    代码执行前,已经确定了代理的代码逻辑。

2. 动态代理

学习目标

  • 能够知道什么是动态代理
  • 能够熟悉动态代理相关API
  • 能够熟悉动态代理代码执行流程

内容讲解

1)概述

在实际开发过程中往往我们自己不会去创建代理类而是通过JDK提供的Proxy类在程序运行时,运用反射机制动态创建而成

这就是我们所谓的动态代理

与静态代理之间的区别,在于不用自己写代理类

虽然我们不需要自己定义代理类创建代理对象

但是我们要定义对被代理对象直接访问方法的拦截,原因就是对拦截的方法做增强

动态代理技术在框架中使用居多,例如:很快要学到的数据库框架MyBatis框架等一些主流框架技术(Spring,SpringMVC)中都使用了动态代理技术。

2)API学习

Proxy类
  • java.lang.reflect.Proxy类提供了用于创建动态代理类和对象的静态方法

​ 它还是由这些方法创建的所有动态代理类的超类(代理类的父类是Proxy)。

public static Object newProxyInstance (
  ClassLoader loader, 
  Class<?>[] interfaces,  
  InvocationHandler h ) 获取代理对象的方法 

- 返回值:该方法返回就是动态生成的代理对象
- 参数列表说明:
  1. ClassLoader loader 	- 定义代理类的类加载器
  2. Class<?>[] interfaces 	- 代理类要实现的接口列表,要求与被代理类的接口一样。
  3. InvocationHandler h 	- 就是具体实现代理逻辑的接口
InvocationHandler接口

源码 :

interface InvocationHandler{
	public Object invoke(Object proxy, Method method, Object[] args);  //代理逻辑
}

java.lang.reflect.InvocationHandler是代理对象的实际处理代理逻辑的接口,具体代理实现逻辑在其 invoke 方法中。所有代理对象调用的方法,执行是都会经过invoke。因此如果要对某个方法进行代理增强,就可以在这个invoke方法中进行定义。

方法说明如下:

public Object invoke(Object proxy, Method method, Object[] args);
  
1. 返回值:方法被代理后执行的结果。
2. 参数列表:
   1. proxy  - 就是代理对象
   2. method - 代理对象调用的方法
   3. args   - 代理对象调用方法传入参数值的对象数组.

3)代码实践

将经纪人代理明星的案例使用动态代理实现

  1. 把父接口定义
  2. 定义被代理类:宝强
  3. 动态生成代理类
  4. 定义代理逻辑
package com.itheima.dynamicproxy_demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 测试类
/*
    1 Proxy类 :
        public static Object newProxyInstance (
              ClassLoader loader,
              Class<?>[] interfaces,
              InvocationHandler h ) 获取代理对象的方法

            - 返回值:该方法返回就是动态生成的代理对象
            - 参数列表说明:
              1. ClassLoader loader 	- 定义代理类的类加载器
              2. Class<?>[] interfaces 	- 代理类要实现的接口列表,要求与被代理类的接口一样。
              3. InvocationHandler h 	- 就是具体实现代理逻辑的接口

    2 InvocationHandler接口
        public Object invoke(Object proxy, Method method, Object[] args);
        1. 返回值:方法被代理后执行的结果。
        2. 参数列表:
           1. proxy  - 就是代理对象
           2. method - 代理对象调用的方法
           3. args   - 代理对象调用方法传入参数值的对象数组.
 */
public class DynamicProxyDemo {
    public static void main(String[] args) {

        // Proxy.newProxyInstance(被代理角色的类加载器 , 被代理角色实现的所有接口 , 处理器);
        // 被代理角色的类加载器
        ClassLoader classLoader = BaoQiang.class.getClassLoader();
        // 被代理角色实现的所有接口
        Class<?>[] interfaces = BaoQiang.class.getInterfaces();
        // 创建被代理角色对象
        BaoQiang baoQiang = new BaoQiang();
        // 代理角色 , 动态生成
        Star songZhe = (Star) Proxy.newProxyInstance(classLoader, interfaces, new MyInvocationHandler(baoQiang));
        // 代理角色调用liveShow方法
        songZhe.liveShow(1000);
        songZhe.sleep();
    }
}

// 定义InvocationHandler接口的实现类
class MyInvocationHandler implements InvocationHandler {
    private BaoQiang baoQiang;

    public MyInvocationHandler(BaoQiang baoQiang) {
        this.baoQiang = baoQiang;
    }

    // invoke什么时候会执行????
    // 代理对象调用功能 , 就会触发invoke方法
    // 此方法对被代理角色的功能做增强

    // method : 代理对象调用功能就会触发invoke方法 , invoke方法中的method代表的就是调用的方法对象
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("liveShow")) {
            // 代理角色对象调用liveShow方法 , 此位置会拦截
            // 前增强
            System.out.println("宋喆帮宝强拉了一个真人秀的活动,获取佣金" + (double) args[0] * 0.8 + "元");
            Object result = method.invoke(baoQiang, (double) args[0] * 0.2);
            // 后增强
            System.out.println("宋喆帮宝强把赚的钱存了起来...");

            return result;
        } else if (method.getName().equals("sleep")) {
            // 代理角色对象调用sleep方法 , 此位置会拦截
            method.invoke(baoQiang);
        } else {
            // 除了liveShow和sleep方法 , 会执行else代码块中的内容
        }

        return null;
    }
}

//  1 抽象角色
interface Star {
    double liveShow(double money);

    void sleep();
}

// 2 定义被代理角色(宝强)
class BaoQiang implements Star {

    @Override
    public double liveShow(double money) {
        System.out.println("宝强参加了一个真人秀活动赚了" + money + "钱");
        return money;
    }

    @Override
    public void sleep() {
        System.out.println("宝强累了 , 睡觉...");
    }
}

动态代理调用流程:

在这里插入图片描述

小结

  1. 什么是动态代理?
    在代码执行前,没有代理类,代理类是在程序运行的时候动态生成.

    Proxy.newProxyInstance
    
  2. 动态代理有什么好处?
    动态代理可以为 “被代理对象” 的所有接口的所有方法做代理,动态代理可以在不改变方法源码的情况下,实现对方法功能的增强。

  3. 动态代理相关的API有哪些?

    Proxy
    	public static Object newProxyInstance(类加载器,接口列表,调用处理器)
    	类加载器 = 被代理对象.getClass().getClassLoader();
    	接口列表 = 被代理对象.getClass().getInterfaces();
    	调用处理器 = new InvocationHandler(){   实现  invoke 方法 };
    
    InvocationHandler
    	public Object invoke(代理对象,方法对象,方法的实参类别) 该方法执行时机是,代理对象调用方法时触发执行
    
  4. 动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。

  5. 缺点 :只能针对接口的实现类做代理对象,普通类是不能做代理对象的。

    后面框架学习的时候会接触到CGLib(Code Genneration Library ): 可以实现对类的代理。

    数据库连接池与JDBC Template

数据库连接池

1. 概念:其实就是一个容器(集合),存放数据库连接的容器。
	    当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

2. 好处:
	1. 节约资源
	2. 用户访问高效

3. 实现:
	1. 标准接口:DataSource   javax.sql包下的
		1. 方法:
			* 获取连接:getConnection()
			* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接

	2. 一般我们不去实现它,有数据库厂商来实现
		1. C3P0:数据库连接池技术
		2. Druid:数据库连接池实现技术,由阿里巴巴提供的


4. C3P0:数据库连接池技术
	* 步骤:
		1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
			* 不要忘记导入数据库驱动jar包
		2. 定义配置文件:
			* 名称: c3p0.properties 或者 c3p0-config.xml
			* 路径:直接将文件放在src目录下即可。

		3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
		4. 获取连接: getConnection
	* 代码:
		 //1.创建数据库连接池对象
        DataSource ds  = new ComboPooledDataSource();
        //2. 获取连接对象
        Connection conn = ds.getConnection();
5. Druid:数据库连接池实现技术,由阿里巴巴提供的
	1. 步骤:
		1. 导入jar包 druid-1.0.9.jar
		2. 定义配置文件:
			* 是properties形式的
			* 可以叫任意名称,可以放在任意目录下
		3. 加载配置文件。Properties
		4. 获取数据库连接池对象:通过工厂来来获取  DruidDataSourceFactory
		5. 获取连接:getConnection
	* 代码:
		 //3.加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //4.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.获取连接
        Connection conn = ds.getConnection();
	2. 定义工具类
		1. 定义一个类 JDBCUtils
		2. 提供静态代码块加载配置文件,初始化连接池对象
		3. 提供方法
			1. 获取连接方法:通过数据库连接池获取连接
			2. 释放资源
			3. 获取连接池的方法


	* 代码:
		public class JDBCUtils {

		    //1.定义成员变量 DataSource
		    private static DataSource ds ;
		
		    static{
		        try {
		            //1.加载配置文件
		            Properties pro = new Properties();
		            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
		            //2.获取DataSource
		            ds = DruidDataSourceFactory.createDataSource(pro);
		        } catch (IOException e) {
		            e.printStackTrace();
		        } catch (Exception e) {
		            e.printStackTrace();
		        }
		    }
		
		    /**
		     * 获取连接
		     */
		    public static Connection getConnection() throws SQLException {
		        return ds.getConnection();
		    }
		
		    /**
		     * 释放资源
		     */
		    public static void close(Statement stmt,Connection conn){
		       /* if(stmt != null){
		            try {
		                stmt.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		        if(conn != null){
		            try {
		                conn.close();//归还连接
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }*/
		
		       close(null,stmt,conn);
		    }

		    public static void close(ResultSet rs , Statement stmt, Connection conn){

		        if(rs != null){
		            try {
		                rs.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }

		        if(stmt != null){
		            try {
		                stmt.close();
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		
		        if(conn != null){
		            try {
		                conn.close();//归还连接
		            } catch (SQLException e) {
		                e.printStackTrace();
		            }
		        }
		    }
		
		    /**
		     * 获取连接池方法
		     */
		
		    public static DataSource getDataSource(){
		        return  ds;
		    }
		
		}

Spring JDBC

* Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
* 步骤:
	1. 导入jar包
	2. 创建JdbcTemplate对象。依赖于数据源DataSource
		* JdbcTemplate template = new JdbcTemplate(ds);

	3. 调用JdbcTemplate的方法来完成CRUD的操作
		* update():执行DML语句。增、删、改语句
		* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
			* 注意:这个方法查询的结果集长度只能是1
		* queryForList():查询结果将结果集封装为list集合
			* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
		* query():查询结果,将结果封装为JavaBean对象
			* query的参数:RowMapper
				* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
				* new BeanPropertyRowMapper<类型>(类型.class)
		* queryForObject:查询结果,将结果封装为对象
			* 一般用于聚合函数的查询

	4. 练习:
		* 需求:
			1. 修改1号数据的 salary 为 10000
			2. 添加一条记录
			3. 删除刚才添加的记录
			4. 查询id为1的记录,将其封装为Map集合
			5. 查询所有记录,将其封装为List
			6. 查询所有记录,将其封装为Emp对象的List集合
			7. 查询总记录数

		* 代码:
			
			import cn.itcast.domain.Emp;
			import cn.itcast.utils.JDBCUtils;
			import org.junit.Test;
			import org.springframework.jdbc.core.BeanPropertyRowMapper;
			import org.springframework.jdbc.core.JdbcTemplate;
			import org.springframework.jdbc.core.RowMapper;
			
			import java.sql.Date;
			import java.sql.ResultSet;
			import java.sql.SQLException;
			import java.util.List;
			import java.util.Map;
			
			public class JdbcTemplateDemo2 {
			
			    //Junit单元测试,可以让方法独立执行

			    //1. 获取JDBCTemplate对象
			    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
			    /**
			     * 1. 修改1号数据的 salary 为 10000
			     */
			    @Test
			    public void test1(){
			
			        //2. 定义sql
			        String sql = "update emp set salary = 10000 where id = 1001";
			        //3. 执行sql
			        int count = template.update(sql);
			        System.out.println(count);
			    }
			
			    /**
			     * 2. 添加一条记录
			     */
			    @Test
			    public void test2(){
			        String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
			        int count = template.update(sql, 1015, "郭靖", 10);
			        System.out.println(count);
			
			    }
			
			    /**
			     * 3.删除刚才添加的记录
			     */
			    @Test
			    public void test3(){
			        String sql = "delete from emp where id = ?";
			        int count = template.update(sql, 1015);
			        System.out.println(count);
			    }
			
			    /**
			     * 4.查询id为1001的记录,将其封装为Map集合
			     * 注意:这个方法查询的结果集长度只能是1
			     */
			    @Test
			    public void test4(){
			        String sql = "select * from emp where id = ? or id = ?";
			        Map<String, Object> map = template.queryForMap(sql, 1001,1002);
			        System.out.println(map);
			        //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
			
			    }
			
			    /**
			     * 5. 查询所有记录,将其封装为List
			     */
			    @Test
			    public void test5(){
			        String sql = "select * from emp";
			        List<Map<String, Object>> list = template.queryForList(sql);
			
			        for (Map<String, Object> stringObjectMap : list) {
			            System.out.println(stringObjectMap);
			        }
			    }
			
			    /**
			     * 6. 查询所有记录,将其封装为Emp对象的List集合
			     */
			
			    @Test
			    public void test6(){
			        String sql = "select * from emp";
			        List<Emp> list = template.query(sql, new RowMapper<Emp>() {
			
			            @Override
			            public Emp mapRow(ResultSet rs, int i) throws SQLException {
			                Emp emp = new Emp();
			                int id = rs.getInt("id");
			                String ename = rs.getString("ename");
			                int job_id = rs.getInt("job_id");
			                int mgr = rs.getInt("mgr");
			                Date joindate = rs.getDate("joindate");
			                double salary = rs.getDouble("salary");
			                double bonus = rs.getDouble("bonus");
			                int dept_id = rs.getInt("dept_id");
			
			                emp.setId(id);
			                emp.setEname(ename);
			                emp.setJob_id(job_id);
			                emp.setMgr(mgr);
			                emp.setJoindate(joindate);
			                emp.setSalary(salary);
			                emp.setBonus(bonus);
			                emp.setDept_id(dept_id);
			
			                return emp;
			            }
			        });

			        for (Emp emp : list) {
			            System.out.println(emp);
			        }
			    }
			
			    /**
			     * 6. 查询所有记录,将其封装为Emp对象的List集合
			     */
			
			    @Test
			    public void test6_2(){
			        String sql = "select * from emp";
			        List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
			        for (Emp emp : list) {
			            System.out.println(emp);
			        }
			    }
			
			    /**
			     * 7. 查询总记录数
			     */
			
			    @Test
			    public void test7(){
			        String sql = "select count(id) from emp";
			        Long total = template.queryForObject(sql, Long.class);
			        System.out.println(total);
			    }
			
			}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

micropython SSD1306/SSD1315驱动

目录 简介 代码 功能 显示ASCII字符 ​编辑 画任意直线 画横线 画竖线 画矩形 画椭圆 画立方体 画点阵图 翻转 反相 滚动 横向滚动 纵向滚动 奇葩滚动 简介 我重新写了一个驱动&#xff0c;增加了一些功能&#xff0c;由于我的硬件是128*64oled单色I2C&#xff0c;我只…

Android Shape 的使用

目录 什么是Shape? shape属性 子标签属性 corners &#xff08;圆角&#xff09; solid &#xff08;填充色&#xff09; gradient &#xff08;渐变&#xff09; stroke &#xff08;描边&#xff09; padding &#xff08;内边距&#xff09; size &#xff08;大小…

视频高效剪辑,轻松平均分割视频,生成高质量M3U8

您是否在处理视频剪辑时常常面临繁琐的切分工作&#xff1f;是否希望能够快速而精准地平均分割视频&#xff0c;并生成适用于在线播放的高质量m3u8文件&#xff1f;现在&#xff0c;我们的智能视频剪辑大师为您提供了一种简便而高效的解决方案&#xff01;无需复杂操作&#xf…

【MySQL系列】--初识数据库

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

软件报错msvcr90.dll丢失的解决方法,亲测可以修复

我曾经遇到过一个令人头疼的问题&#xff1a;msvcr90.dll丢失。这个问题导致了我的程序无法正常运行&#xff0c;让我感到非常苦恼。然而&#xff0c;在经过一番努力后&#xff0c;我终于成功地修复了这个问题&#xff0c;这让我感到非常欣慰和满足。 msvcr90.dll丢失的原因可能…

大模型基础03:Embedding 实战本地知识问答

大模型基础:Embedding 实战本地知识问答 Embedding 概述 知识在计算机内的表示是人工智能的核心问题。从数据库、互联网到大模型时代,知识的储存方式也发生了变化。在数据库中,知识以结构化的数据形式储存在数据库中,需要机器语言(如SQL)才能调用这些信息。互联网时代,…

117页数字化转型与产业互联网发展趋势及机会分析报告PPT

导读&#xff1a;原文《》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以点赞评论转发本文&#xff0c;了解更多内容请私信&#xff1a;方…

__format__和__del__

目录 一、__format__ 二、__del__ python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm1001.2014.3001.5502 一、__format__ 自定制格式化字符串 date_dic {ymd: {0.year}:{0.month}:{0.day},dmy: {0.day}/{0.month}/…

力扣 198. 打家劫舍

题目来源&#xff1a;https://leetcode.cn/problems/house-robber/description/ C题解&#xff1a;因为是间接偷窃&#xff0c;所以偷nums[i]家前&#xff0c;一定偷过第i-2或者i-3家&#xff0c;因为i-1不能偷。 例如12345共5家&#xff0c;先偷第1家&#xff0c;那么2不能偷…

Oracle切割字符串的方法,SQL语句完成。

Oracle用正则的方式循环切割字符串 需求&#xff1a;有一个这样子的 Str “‘CNJ-520-180500000001|CNJ-520-181200000001|CNJ-520-190300000001|CNJ-520-190100000001|CNJ-520-181200000002’” &#xff0c;然后我需要拿到每一个单号&#xff0c;每一个单号都要走一遍固定的…

神经网络基础-神经网络补充概念-03-逻辑回归损失函数

概念 逻辑回归使用的损失函数通常是"对数损失"&#xff08;也称为"交叉熵损失"&#xff09;或"逻辑损失"。这些损失函数在训练过程中用于衡量模型预测与实际标签之间的差异&#xff0c;从而帮助模型逐步调整权重参数&#xff0c;以更好地拟合数…

vue3小知识点汇总——基础积累

下面的小知识点比较零散&#xff0c;但是脑子不太好使&#xff0c;只能先记录一下啦&#xff0c;后面知识丰富起来后&#xff0c;慢慢就懂了。 1.最新版node.js已经不兼容vue2的项目了&#xff0c;学习vue3势在必行 node.js的安装及vue的搭建详细步骤&#xff1a;http://t.cs…

知识继承概述

文章目录 知识继承第一章 知识继承概述1.背景介绍第一页 背景第二页 大模型训练成本示例第三页 知识继承的动机 2.知识继承的主要方法 第二章 基于知识蒸馏的知识继承预页 方法概览 1.知识蒸馏概述第一页 知识蒸馏概述第二页 知识蒸馏第三页 什么是知识第四页 知识蒸馏的核心目…

冠达管理:哪里查中报预增?

中报季行将到来&#xff0c;投资者开端重视公司的成绩体现。中报预增是投资者最关心的论题之一&#xff0c;因为这意味着公司未来成绩的增加潜力。但是&#xff0c;怎么查找中报预增的信息呢&#xff1f;本文将从多个视点分析这个问题。 1.证券交易所网站 证券交易所网站是投资…

如何用输入函数为数组赋值

在编写程序时我们经常使用数组&#xff0c;而数组的大小可能是很大的但是我们并不需要为每个元素都自己赋值&#xff0c;我们可能会自定义输入数组元素个数&#xff0c;我们应该如何实现通过输入函数为数组赋值呢&#xff1f; 目录 第一种&#xff1a; 第二种&#xff1a; 第一…

【Vue-Router】导航守卫

前置守卫 main.ts import { createApp } from vue import App from ./App.vue import {router} from ./router // import 引入 import ElementPlus from element-plus import element-plus/dist/index.css const app createApp(App) app.use(router) // use 注入 ElementPlu…

8.文件存储空间管理

第四章 文件管理 8.文件存储空间管理 空闲表法&#xff1a;   空闲盘块表和在内存管理的动态分区分配中学习过的空闲分区表是类似的&#xff0c;空闲盘块表记录了每一个空闲区间的起始位置和这个空闲区间的长度这两个信息。像第一个空闲区间是0&#xff0c;1这两个空闲块&am…

成集云 | 电子签署集成腾讯云企业网盘 | 解决方案

源系统成集云目标系统 方案介绍 电子签署是通过电子方式完成合同、文件或其他文件的签署过程。相较于传统的纸质签署&#xff0c;电子签署具有更高效、更便捷、更安全的优势。 在电子签署过程中&#xff0c;使用电子签名技术来验证签署者的身份并确保签署文件的完整性。电子…

万宾燃气管网监测解决方案,守护城市生命线安全

方案背景 城市燃气管网作为连接天然气长输管线与天然气用户的桥梁&#xff0c;担负着向企业和居民用户直接供气的重要职责。随着城市燃气需求的急剧增加&#xff0c;城市燃气管网规模日趋庞大&#xff0c;安全隐患和风险也随之增加。目前&#xff0c;我国燃气管网的运行仍存在…

AWS EKS 集群自动扩容 Cluster Autoscaler

文章目录 一&#xff0c;需求工作需求说明 二&#xff0c;部署精简命令执行1&#xff0c;要求2&#xff0c;查看EC2 Auto Scaling groups Tag3&#xff0c;创建Serviceaccount需要的Policy&#xff0c;Role4&#xff0c;部署Cluster Autoscaler5&#xff0c;验证6&#xff0c;常…