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

学习Java的日子 Day56 数据库连接池,Druid连接池

Day56

1.数据库连接池

理解:池就是容器,容器中存放了多个连接对象

使用原因:

1.优化创建和销毁连接的时间(在项目启动时创建连接池,项目销毁时关闭连接池)

2.提高连接对象的复用率

3.有效控制项目中连接的个数(连接对象占内存资源)

数据库连接池负责分配、管理和释放数据库连接对象,它允许应用程序重复使用一个现有的数据库连接,而

不是再重新建立一个

1.1 自定义连接池

自己写的连接池类 FastConnectionPool

public class FastConnectionPool {private String driverClassName;private String url;private String username;private String password;private int maxActive;//存储connection连接对象的资源容器(removeFirst)private LinkedList<Connection> list;//get,set方法(没有list的get、set方法)//初始化listpublic void init() throws SQLException {list = new LinkedList<>();try {Class.forName(driverClassName);//创建连接对象,并添加到连接池容器中for (int i = 0; i < maxActive; i++) {Connection connection = DriverManager.getConnection(url, username, password);list.add(connection);}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}public Connection getConnection() throws SQLException {if(list == null){init();}Connection connection = null;if(!list.isEmpty()){connection = list.removeFirst();}return connection;}//回收connection对象,使用完了不用close()方法关闭,而是回收到list中继续使用,提高复用率public void recovery(Connection connection){list.add(connection);}}

测试类

public class Test01 {public static void main(String[] args) throws SQLException {//创建数据库连接池FastConnectionPool pool = new FastConnectionPool();//设置参数pool.setDriverClassName("com.mysql.cj.jdbc.Driver");pool.setUrl("jdbc:mysql://localhost:3306/2403javaee?characterEncoding=utf8&serverTimezone=UTC&rewriteBatchedStatements=true");pool.setUsername("root");pool.setPassword("123456");pool.setMaxActive(20);//jdbc的查询代码Connection connection = pool.getConnection();String sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");float salary = resultSet.getFloat("salary");String course = resultSet.getString("course");System.out.println(id + " -- " + name + " -- " + sex + " -- " + age + " -- " + salary + " -- " + course);}resultSet.close();statement.close();pool.recovery(connection);//回收connection对象}
}

1.2 升级自定义连接池(重点重点关注)

DataSource:连接池各有各的实现方式,所以sun公司定义了一个标准,DataSource

注意:市面上有众多的数据库连接池(Druid、C3P0、DBCP),他们都实现Java提供的DataSource接口(简称数据源)

在这里插入图片描述

使用过程,重点是要实现close方法,连接资源 (connection对象) 怎么关闭:装饰模式来帮忙

装饰设计模式(包装模式):目的:改写已存在的类的某个方法或某些方法

数据库连接的包装类(需要实现很多方法)

定义Connection connection对象

定义LinkedList pool;

通过构造方法对上述两个值进行初始化

重写close方法

Public void close(){

pool.addLast(connection);

}

public class MyConnectionWrapper implements Connection {private Connection connection;private LinkedList<Connection> list;//连接池里的容器public MyConnectionWrapper(Connection connection, LinkedList<Connection> list) {this.connection = connection;this.list = list;}@Overridepublic Statement createStatement() throws SQLException {return connection.createStatement();}@Overridepublic PreparedStatement prepareStatement(String sql) throws SQLException {return connection.prepareStatement(sql);}@Overridepublic CallableStatement prepareCall(String sql) throws SQLException {return connection.prepareCall(sql);}@Overridepublic String nativeSQL(String sql) throws SQLException {return connection.nativeSQL(sql);}@Overridepublic void setAutoCommit(boolean autoCommit) throws SQLException {connection.setAutoCommit(autoCommit);}@Overridepublic boolean getAutoCommit() throws SQLException {return connection.getAutoCommit();}@Overridepublic void commit() throws SQLException {connection.commit();}@Overridepublic void rollback() throws SQLException {connection.rollback();}@Overridepublic void close() throws SQLException {System.out.println("将连接包装类对象回收到连接池里的容器");list.add(this);}@Overridepublic boolean isClosed() throws SQLException {return connection.isClosed();}@Overridepublic DatabaseMetaData getMetaData() throws SQLException {return connection.getMetaData();}@Overridepublic void setReadOnly(boolean readOnly) throws SQLException {connection.setReadOnly(readOnly);}@Overridepublic boolean isReadOnly() throws SQLException {return connection.isReadOnly();}@Overridepublic void setCatalog(String catalog) throws SQLException {connection.setCatalog(catalog);}@Overridepublic String getCatalog() throws SQLException {return connection.getCatalog();}//省略一些方法
}

自定义连接池类,需要实现DataSource接口

public class FastConnectionPool implements DataSource {private String driverClassName;private String url;private String username;private String password;private int maxActive;private LinkedList<Connection> list;//get,set方法(没有list的get、set方法)public void init() throws SQLException {list = new LinkedList<>();try {Class.forName(driverClassName);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}for (int i = 0; i < maxActive; i++) {Connection connection = DriverManager.getConnection(url, username, password);//获取连接的方法需要将原本的connection对象进行包装MyConnectionWrapper connectionWrapper = new MyConnectionWrapper(connection, list);list.add(connectionWrapper);}}@Overridepublic Connection getConnection() throws SQLException {if(list == null){init();}Connection connection = null;if(!list.isEmpty()){connection = list.removeFirst();}return connection;}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}
}

测试类,和上面的一样

public class Test01 {public static void main(String[] args) throws SQLException {//创建连接池对象FastConnectionPool pool = new FastConnectionPool();//设置参数//设置参数pool.setDriverClassName("com.mysql.cj.jdbc.Driver");pool.setUrl("jdbc:mysql://localhost:3306/2403javaee?characterEncoding=utf8&serverTimezone=UTC&rewriteBatchedStatements=true");pool.setUsername("root");pool.setPassword("123456");pool.setMaxActive(20);Connection connection = pool.getConnection();String sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");float salary = resultSet.getFloat("salary");String course = resultSet.getString("course");System.out.println(id + " -- " + name + " -- " + sex + " -- " + age + " -- " + salary + " -- " + course);}resultSet.close();statement.close();connection.close();}
}

1.3 Druid (德鲁伊) 连接池

通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。
也有一些开源组织提供了数据源的独立实现:

· DBCP 数据库连接池

· C3P0 数据库连接池

· Druid德鲁伊)数据库连接池

注意:市面上有众多的数据库连接池(Druid、C3P0、DBCP),他们都实现Java提供的DataSource接口(简称数据源)

在使用了数据库连接池之后,在项目的实际开发中就不需要编写连接数据库的代码了,直接从数据源获得数据库的连接。

需要导包

在这里插入图片描述

public class Test01 {public static void main(String[] args) throws SQLException {//创建连接池对象DruidDataSource pool = new DruidDataSource();//就只变化了这一句话//设置参数pool.setDriverClassName("com.mysql.cj.jdbc.Driver");pool.setUrl("jdbc:mysql://localhost:3306/2403javaee?characterEncoding=utf8&serverTimezone=UTC&rewriteBatchedStatements=true");pool.setUsername("root");pool.setPassword("123456");pool.setMaxActive(20);Connection connection = pool.getConnection();String sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");float salary = resultSet.getFloat("salary");String course = resultSet.getString("course");System.out.println(id + " -- " + name + " -- " + sex + " -- " + age + " -- " + salary + " -- " + course);}resultSet.close();statement.close();connection.close();}
}

1.4 Druid封装DBUtil

DBConfig.properties

driverClassName=com.mysql.cj.jdbc.Driverurl=jdbc:mysql://localhost:3306/2403javaee?characterEncoding=utf8&serverTimezone=UTC&rewriteBatchedStatements=trueuser
name=root
password=123456
maxActive=20

maxActive=20:最大连接对象个数

数据库工具类,修改DBUtil

package com.qf.utils;public class DBUtil {private static DruidDataSource pool;private static ThreadLocal<Connection> local;static{Properties properties = new Properties();try {properties.load(DBUtil.class.getClassLoader().getResourceAsStream("DBConfig.properties"));} catch (IOException e) {throw new RuntimeException(e);}String driverClassName = properties.getProperty("driverClassName");String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");int maxActive = Integer.parseInt(properties.getProperty("maxActive"));//初始化数据库连接池pool = new DruidDataSource();//设置参数pool.setDriverClassName(driverClassName);pool.setUrl(url);pool.setUsername(username);pool.setPassword(password);pool.setMaxActive(maxActive);local = new ThreadLocal<>();}/*** 获取连接对象*/public static Connection getConnection() throws SQLException {Connection connection = local.get();//获取当前线程的Connection对象if(connection == null){connection = pool.getConnection();//获取数据库连接池里的连接对象local.set(connection);//将Connection对象添加到local中}return connection;}/*** 关闭资源*/public static void close(Connection connection, Statement statement, ResultSet resultSet){if(resultSet != null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(statement != null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(connection != null){try {if(connection.getAutoCommit()){connection.close();local.set(null);}} catch (SQLException e) {throw new RuntimeException(e);}}}/*** 开启事务*/public static void startTransaction() throws SQLException {Connection connection = getConnection();connection.setAutoCommit(false);}/*** 提交事务*/public static void commit() throws SQLException {Connection connection = local.get();if(connection != null){connection.commit();connection.close();local.set(null);}}public static void rollback() throws SQLException {Connection connection = local.get();if(connection != null){connection.rollback();connection.close();local.set(null);}}/*** 更新数据(添加、删除、修改)*/public static int commonUpdate(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);int num = statement.executeUpdate();return num;}finally {close(connection,statement,null);}}/*** 添加数据 - 主键回填(主键是int类型可以返回)*/public static int commonInsert(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);paramHandler(statement,params);statement.executeUpdate();resultSet = statement.getGeneratedKeys();int primaryKey = 0;if(resultSet.next()){primaryKey = resultSet.getInt(1);}return primaryKey;}finally {close(connection,statement,resultSet);}}/*** 查询多个数据*/public static <T> List<T> commonQueryList(Class<T> clazz,String sql, Object... params) throws SQLException, InstantiationException, IllegalAccessException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//获取表数据对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int count = metaData.getColumnCount();List<T> list = new ArrayList<>();while(resultSet.next()){T t = clazz.newInstance();//获取字段名及数据for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}list.add(t);}return list;} finally {DBUtil.close(connection,statement,resultSet);}}/*** 查询单个数据*/public static <T> T commonQueryObj(Class<T> clazz,String sql, Object... params) throws SQLException, InstantiationException, IllegalAccessException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//获取表数据对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int count = metaData.getColumnCount();if(resultSet.next()){T t = clazz.newInstance();//获取字段名及数据for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}return t;}} finally {DBUtil.close(connection,statement,resultSet);}return null;}/*** 处理statement对象参数数据的处理器*/private static void paramHandler(PreparedStatement statement,Object... params) throws SQLException {for (int i = 0; i < params.length; i++) {statement.setObject(i+1,params[i]);}}/*** 获取当前类及其父类的属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/private static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置对象中的属性* @param obj 对象* @param name 属性名* @param value 属性值*/private static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}
}

封装学生类

public class Student {private int id;private String name;private String sex;private int age;private float salary;private String course;//无参构造,有参构造,get,set,toString方法省略
}

测试类

public class Test01 {public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException {String sql = "select * from student";List<Student> students = DBUtil.commonQueryList(Student.class, sql);//打印集合for (Student stu : students) {System.out.println(stu);}}
}

在这里插入图片描述

总结

1.连接池

​ 概念

​ 自定义连接池(两个版本,重点关注第二个版本)

​ Druid连接池

相关文章:

学习Java的日子 Day56 数据库连接池,Druid连接池

Day56 1.数据库连接池 理解&#xff1a;池就是容器&#xff0c;容器中存放了多个连接对象 使用原因&#xff1a; 1.优化创建和销毁连接的时间&#xff08;在项目启动时创建连接池&#xff0c;项目销毁时关闭连接池&#xff09; 2.提高连接对象的复用率 3.有效控制项目中连接的…...

如何实现PostgreSQL对某一张表的WAL日志进行记录

PostgreSQL 没有内置的 binlog&#xff08;binary log&#xff09;机制像 MySQL 那样。它使用 Write-Ahead Logging (WAL) 来记录数据库的变更。要将这些变更记录到某张表中&#xff0c;通常可以使用逻辑复制&#xff08;Logical Replication&#xff09;和触发器&#xff08;T…...

机器学习数学基础(2)--最大似然函数

声明&#xff1a;本文章是根据网上资料&#xff0c;加上自己整理和理解而成&#xff0c;仅为记录自己学习的点点滴滴。可能有错误&#xff0c;欢迎大家指正。 在机器学习和统计学领域中&#xff0c;似然函数&#xff08;Likelihood Function&#xff09;是一个至关重要的概念。…...

详解 @RequestHeader 注解在 Spring Boot 中的使用

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…...

C# 表达式树的简介与说明

文章目录 1. 表达式树是什么&#xff1f;2. 表达式树的基本组成3. 构建表达式树的步骤4. 表达式树的使用场景5. 示例代码6. 总结 在 C# 编程中&#xff0c;表达式树&#xff08;Expression Tree&#xff09;是一个强大的概念&#xff0c;它允许我们以代码的形式表示运行时的代码…...

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第六十三章 输入子系统实验

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...

[补题记录]Leetcode 15. 三数之和

传送门&#xff1a;三数之和 思路 为了去重&#xff0c;需要先排序。 排序之后&#xff0c;显然每一个 n u m s [ i ] nums[i] nums[i] 就可以作为三数之中的第一个数。 因此&#xff0c;对于每一个 i i i&#xff0c;第二、三个数只能在 [ i 1 , n ] [i 1, n] [i1,n]…...

什么是sql注入攻击,如何预防介绍一下mysql中的常见数据类型

什么是sql注入攻击&#xff0c;如何预防 sql注入攻击指的是应用程序对用户输入数据的合法性没有判断或者过滤不严格&#xff0c;在sql语句中插入任意的恶意语句进行非法操作。 预防方式1&#xff1a;使用预编译语句比如PrepareStatement&#xff0c;用户输入的所有数据都以参数…...

史上最全的Seata教学并且连接springcloudAlibaba进行使用

来都来了点个赞收藏一下在走呗~~&#x1f339;&#x1f339;玫瑰 一、Seata是什么 Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff0c;简单可扩展自治事务框架&#xff09;是一种分布式事务解决方案&#xff0c;旨在解决分布式系统中的事务…...

InternLM Git 基础知识

提交一份自我介绍。 创建并提交一个项目。...

【Unity模型】古代亚洲建筑

在Unity Asset Store上&#xff0c;一款名为"Ancient Asian Buildings Pack"&#xff08;古代亚洲建筑包&#xff09;的3D模型资源包&#xff0c;为广大开发者和设计师提供了一个将古代亚洲建筑风格融入Unity项目的机会。本文将详细介绍这款资源包的特点、使用方式以…...

木马后门实验

实验拓扑 实验步骤 防火墙 配置防火墙—充当边界NAT路由器 边界防火墙实现内部 DHCP 分配和边界NAT需求&#xff0c;其配置如下 登录网页 编辑接口 配置e0/0 配置e0/1 编辑策略 测试&#xff1a;内部主机能获得IP&#xff0c;且能与外部kali通信 kali 接下来开启 kali 虚…...

【React】useState:状态更新规则详解

文章目录 一、基本用法二、直接修改状态 vs 使用 setState 更新状态三、对象状态的更新四、深层次对象的更新五、函数式更新六、优化性能的建议 在 React 中&#xff0c;useState 是一个非常重要的 Hook&#xff0c;用于在函数组件中添加状态管理功能。正确理解和使用 useState…...

C#中的异步编程:Task、Await 和 Async

public async void DoSth() {await Task.Run(() > {//...DoSth...}); } ①函数的返回类型前加上&#xff1a; async ②函数内加上&#xff1a; await Task.Run(() > { }); ③在上面{ ... } 内添加要处理的程序代码&#xff0c; 这样运行到 DoSth() 函数就…...

SSRF-labs-master靶场

目录 file_get_content.php sql_connect.php download.php dns-spoofing.php dns_rebinding.php 访问链接 http://127.0.0.1/SSRF/# file_get_content.php 在编程语言中&#xff0c;有一些函数可以获取本地保存文件的内容。这些功能可能能够从远程URL以及本地文件 如果没…...

HBuilder X中配置vue-cli项目和UI库

目录 一.前端项目结构 二.在HBuilder X中搭建vue-cli项目 1. 安装node.js前端环境 2. HBuilder X创建一个vue-cli项目 3. vue-cli项目结构 4. 如何运行前端项目 5. 创建组件 6. 组件路由(页面跳转) 6.1 创建router目录 6.2 使用路由 6.3 在main.js中配置路由 6.4 路…...

如何用PostMan按照规律进行循环访问接口

①设置动态变量 步骤一: 设置环境变量 1. 创建环境变量集合 在 Postman 左上角选择 "环境"&#xff0c;然后点击 "添加" 来创建一个新的环境变量集合。给它起一个名称&#xff0c;比如 "uploadDemo". 2. 添加初始变量 在新创建的环境变量集…...

稳态准直太阳光模拟器仪器光伏电池组件IV测试

太阳能模拟器电池IV测试仪、单体测试仪&#xff0c;配备匹配标准的AAA Class稳态太阳能模拟器及相关测试附件&#xff0c;可对太阳能电池片的IV性能进行测量、分级分选等&#xff1b; 介绍 AAA class太阳光模拟器整合完整的IV测量系统&#xff0c;针对各种太阳能电池的性能&a…...

vue3 reactive原理(二)-代理Set和Map及ref原理

Set和Map类型的数据也属于异质对象&#xff0c;它们有特定的属性和方法用来操作自身。因此创建代理时&#xff0c;针对特殊的方法需要特殊的对待。 Vue 的ref 是基于reactive函数实现的&#xff0c;它在其基础上&#xff0c;增加了基本类型的响应性、解决reactive在解构时丢失…...

Python自然语言处理库之NLTK与spaCy使用详解

概要 自然语言处理(NLP)是人工智能和数据科学领域的重要分支,致力于让计算机理解、解释和生成人类语言。在Python中,NLTK(Natural Language Toolkit)和spaCy是两个广泛使用的NLP库。本文将详细介绍NLTK和spaCy的特点、功能及其使用方法,并通过具体示例展示如何使用这两…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...