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

SpringBoot使用Hbase

SpringBoot使用Hbase

文章目录

  • SpringBoot使用Hbase
  • 一,引入依赖
  • 二,配置文件添加自己的属性
  • 三,配置类注入HBASE配置
  • 四,配置Hbase连接池
  • 五,配置操作服务类

一,引入依赖

		<dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.3.2</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency>

二,配置文件添加自己的属性

hbase:zookeeper:quorum: 10.xxx.xx.153,10.xxx.xx.154,10.xxx.xx.155property:clientPort: 2181master:port: 9001

三,配置类注入HBASE配置

package com.hbase.config;import org.apache.hadoop.hbase.HBaseConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @ClassName: HBaseConfig* @author: Leemon* @Description: TODO* @date: 2023/4/12 18:06* @version: 1.0*/
@Configuration
@RefreshScope
public class HBaseConfig {@Value("${hbase.zookeeper.quorum}")private String zookeeperQuorum;@Value("${hbase.zookeeper.property.clientPort}")private String clientPort;@Value("${hbase.master.port}")private String masterPort;@Beanpublic org.apache.hadoop.conf.Configuration hbaseConfiguration() {org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.quorum", zookeeperQuorum);conf.set("hbase.zookeeper.property.clientPort", clientPort);// 如果hbase是集群,这个必须加上// 这个ip和端口是在hadoop/mapred-site.xml配置文件配置的conf.set("hbase.master", zookeeperQuorum + ":" + masterPort);conf.set("hbase.client.keyvalue.maxsize", "20971520");conf = HBaseConfiguration.create(conf);return conf;}}

四,配置Hbase连接池

这里没有使用懒加载模式,减少启动后第一次访问时访问时间过长

package com.hbase.config;import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;/*** @ClassName: HbaseConnectionPool* @author: Leemon* @Description: TODO* @date: 2023/4/13 9:45* @version: 1.0*/
@Component
@Slf4j
public class HbaseConnectionPool {/*** 连接池最大的大小*/private int nMaxConnections = 20;/*** 连接池自动增加的大小*/private int nIncrConnectionAmount = 3;/*** 连接池的初始大小*/private int nInitConnectionAmount = 3;/*** 存放连接池中数据库连接的向量,初始时为null*/private Vector vcConnections = null;@Resourceprivate Configuration hbaseConfiguration;@PostConstructpublic void init() {try {vcConnections = new Vector();createConnections(nInitConnectionAmount);} catch (Exception e) {e.printStackTrace();}}public synchronized Connection getConnection() {// 确保连接池己被创建if (vcConnections == null) {// 连接池还没创建,则返回nullreturn null;}// 获得一个可用的数据库连接Connection conn = getFreeConnection();// 如果目前没有可以使用的连接,即所有的连接都在使用中while (conn == null) {// 等一会再试try {wait(250);} catch (InterruptedException e) {e.printStackTrace();}// 重新再试,直到获得可用的连接,如果getFreeConnection()返回的为null,则表明创建一批连接后也不可获得可用连接conn = getFreeConnection();}// 返回获得的可用的连接return conn;}/*** 本函数从连接池向量 connections 中返回一个可用的的数据库连接,如果* 当前没有可用的数据库连接,本函数则根据 incrementalConnections 设置* 的值创建几个数据库连接,并放入连接池中。* 如果创建后,所有的连接仍都在使用中,则返回 null* @return* 		返回一个可用的数据库连接*/private Connection getFreeConnection() {// 从连接池中获得一个可用的数据库连接Connection conn = findFreeConnection();if (conn == null) {// 如果目前连接池中没有可用的连接// 创建一些连接try {createConnections(nIncrConnectionAmount);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();log.error("create new connection fail.", e);}// 重新从池中查找是否有可用连接conn = findFreeConnection();if (conn == null) {// 如果创建连接后仍获得不到可用的连接,则返回 nullreturn null;}}return conn;}/*** 创建由 numConnections 指定数目的数据库连接 , 并把这些连接* 放入 connections 向量中* @param _nNumConnections 要创建的数据库连接的数目* @throws Exception*/private void createConnections(int _nNumConnections) throws Exception {// 循环创建指定数目的数据库连接for (int x = 0; x < _nNumConnections; x++) {// 是否连接池中的数据库连接的数量己经达到最大?最大值由类成员 maxConnections// 指出,如果 maxConnections 为 0 或负数,表示连接数量没有限制。// 如果连接数己经达到最大,即退出。if (this.nMaxConnections > 0  && this.vcConnections.size() >= this.nMaxConnections) {log.warn("已达到最大连接数,不能再增加连接");throw new Exception("已达到最大连接数"+ nMaxConnections+",不能再增加连接");}// 增加一个连接到连接池中(向量 connections 中)vcConnections.addElement(new ConnectionWrapper(newConnection()));log.info("HBase数据库连接己创建 ...... " + x);}}/*** 查找池中所有的連接,查找一个可用的數據庫連接,* 如果没有可用的連結,返回null* @return* 		返回一個可用的數據庫連接*/private Connection findFreeConnection() {Connection conn = null;ConnectionWrapper connWrapper = null;//獲得連接池向量中所有的對象Enumeration enumerate = vcConnections.elements();//遍歷所有的对象,看是否有可用的連接while (enumerate.hasMoreElements()) {connWrapper = (ConnectionWrapper) enumerate.nextElement();if (!connWrapper.isBusy()) {//如果此對象不忙,則獲得它的數據庫連接并把它設為忙conn = connWrapper.getConnection();connWrapper.setBusy(true);// 己经找到一个可用的連接,退出break;}}// 返回找到的可用連接return conn;}/***创建一个新的数据库连接并返回它* @return* 		返回一个新创建的数据库连接*/private Connection newConnection() {/** hbase 连接 */Connection conn = null;// 创建一个数据库连接try {conn = ConnectionFactory.createConnection(hbaseConfiguration);} catch (IOException e) {log.error("创建HBase数据库连接失败!");e.printStackTrace();}// 返回创建的新的数据库连接return conn;}public synchronized void releaseConnection(Connection conn) {if (this.vcConnections == null) {log.info("连接池不存在,无法返回此连接到连接池中!!");} else {ConnectionWrapper connWrapper = null;Enumeration enumerate = this.vcConnections.elements();while(enumerate.hasMoreElements()) {connWrapper = (ConnectionWrapper) enumerate.nextElement();if (conn == connWrapper.getConnection()) {connWrapper.setBusy(false);break;}}}}class ConnectionWrapper {/*** 数据库连接*/private Connection connection = null;/*** 此连接是否正在使用的标志,默认没有正在使用*/private boolean busy = false;/*** 构造函数,根据一个 Connection 构告一个 PooledConnection 对象*/public ConnectionWrapper(Connection connection) {this.connection = connection;}/*** 返回此对象中的连接*/public Connection getConnection() {return connection;}/*** 设置此对象的连接*/public void setConnection(Connection connection) {this.connection = connection;}/*** 获得对象连接是否忙*/public boolean isBusy() {return busy;}/*** 设置对象的连接正在忙*/public void setBusy(boolean busy) {this.busy = busy;}}}

init()方法实现在初始化连接池的时候创建默认数值的连接。

五,配置操作服务类

操作类接口 HbaseService.java

package com.hbase.service;import org.apache.hadoop.hbase.client.Scan;import java.util.Map;/*** @InterfaceName: HbaseService* @author: Leemon* @Description: TODO* @date: 2023/4/12 18:11* @version: 1.0*/
public interface HbaseService {Map<String,Map<String,String>> getResultScanner(String tableName, String startRowKey, String stopRowKey);Map<String,String> getRowData(String tableName, String rowKey);Map<String,String> getFamilyValue(String tableName, String rowKey, String familyName);String getColumnValue(String tableName, String rowKey, String familyName, String columnName);Map<String,Map<String,String>> queryData(String tableName, Scan scan);}

接口实现类 HbaseServiceImpl.java

package com.hbase.service.impl;import com.hbase.config.HbaseConnectionPool;
import com.hbase.service.HbaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;/*** @ClassName: HbaseServiceImpl* @author: Leemon* @Description: TODO* @date: 2023/4/12 18:13* @version: 1.0*/
@Slf4j
@Service
public class HbaseServiceImpl implements HbaseService {@Resourceprivate HbaseConnectionPool pool;@Overridepublic Map<String,Map<String,String>> getResultScanner(String tableName, String startRowKey, String stopRowKey){Scan scan = new Scan();if(StringUtils.isNotBlank(startRowKey) && StringUtils.isNotBlank(stopRowKey)){scan.withStartRow(Bytes.toBytes(startRowKey));scan.withStopRow(Bytes.toBytes(stopRowKey));}return this.queryData(tableName,scan);}public Map<String,Map<String,String>> getResultScannerPrefixFilter(String tableName, String prefix){Scan scan = new Scan();if(StringUtils.isNotBlank(prefix)){Filter filter = new PrefixFilter(Bytes.toBytes(prefix));scan.setFilter(filter);}return this.queryData(tableName,scan);}@Overridepublic Map<String,Map<String,String>> queryData(String tableName, Scan scan){Map<String,Map<String,String>> result = new HashMap<>();ResultScanner rs = null;// 获取表Table table= null;Connection connection = null;try {connection = pool.getConnection();table = getTable(connection, tableName);rs = table.getScanner(scan);for (Result r : rs) {//每一行数据Map<String,String> columnMap = new HashMap<>();String rowKey = null;for (Cell cell : r.listCells()) {if(rowKey == null){rowKey = Bytes.toString(cell.getRowArray(),cell.getRowOffset(),cell.getRowLength());}columnMap.put(Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()), Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));}if(rowKey != null){result.put(rowKey,columnMap);}}}catch (IOException e) {log.error(MessageFormat.format("遍历查询指定表中的所有数据失败,tableName:{0}",tableName),e);}finally {close(null, rs, table, connection);}return result;}@Overridepublic Map<String,String> getRowData(String tableName, String rowKey){//返回的键值对Map<String,String> result = new HashMap<>();Get get = new Get(Bytes.toBytes(rowKey));// 获取表Table table= null;Connection connection = null;try {connection = pool.getConnection();table = getTable(connection, tableName);Result hTableResult = table.get(get);if (hTableResult != null && !hTableResult.isEmpty()) {for (Cell cell : hTableResult.listCells()) {result.put(Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()), Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));}// 某些应用场景需要插入到数据库的时间if (hTableResult.listCells().size() > 0) {result.put("Timestamp", hTableResult.listCells().get(0).getTimestamp() + "");}}}catch (IOException e) {log.error(MessageFormat.format("查询一行的数据失败,tableName:{0},rowKey:{1}",tableName,rowKey),e);}finally {close(null,null, table, connection);}return result;}@Overridepublic Map<String,String> getFamilyValue(String tableName, String rowKey, String familyName){//返回的键值对Map<String,String> result = new HashMap<>(2);Get get = new Get(Bytes.toBytes(rowKey));get.addFamily(Bytes.toBytes(familyName));// 获取表Table table= null;Connection connection = null;try {connection = pool.getConnection();table = getTable(connection, tableName);Result getResult = table.get(get);if (getResult != null && !getResult.isEmpty()) {for (Cell cell : getResult.listCells()) {result.put(Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()), Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));}}} catch (IOException e) {log.error(MessageFormat.format("查询指定单元格的数据失败,tableName:{0},rowKey:{1},familyName:{2}", tableName, rowKey, familyName), e);}finally {close(null,null, table, connection);}return result;}@Overridepublic String getColumnValue(String tableName, String rowKey, String familyName, String columnName){String str = null;Get get = new Get(Bytes.toBytes(rowKey));// 获取表Table table= null;Connection connection = null;try {connection = pool.getConnection();table = getTable(connection, tableName);Result result = table.get(get);if (result != null && !result.isEmpty()) {Cell cell = result.getColumnLatestCell(Bytes.toBytes(familyName), Bytes.toBytes(columnName));if(cell != null){str = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());}}} catch (IOException e) {log.error(MessageFormat.format("查询指定单元格的数据失败,tableName:{0},rowKey:{1},familyName:{2},columnName:{3}",tableName,rowKey,familyName,columnName),e);}finally {close(null,null, table, connection);}return str;}private Table getTable(Connection connection, String tableName) throws IOException {Table table = connection.getTable(TableName.valueOf(tableName));return table;}private void close(Admin admin, ResultScanner rs, Table table, Connection connection){if(admin != null){try {admin.close();} catch (IOException e) {log.error("关闭Admin失败",e);}}if(rs != null){rs.close();}if(table != null){try {table.close();} catch (IOException e) {log.error("关闭Table失败",e);}}// 释放连接if (Objects.nonNull(connection)) {pool.releaseConnection(connection);}}}

ok,现在就可以操作使用了。

以前都是在非Spring环境下使用Hbase的,一开始会出现:当服务使用时间过久,某些会使用hbase的接口调用次数过多的时候,会报【已超过最大的连接数】,只能每一次调用接口后最后一行加上释放连接。(以前的做法每次调用都要在代码里手动获取一个连接)

这次将释放连接都集成在操作服务类的实现方法中,避免了开发接口可能遗漏的错误,可能不会再出现这个问题。

相关文章:

SpringBoot使用Hbase

SpringBoot使用Hbase 文章目录 SpringBoot使用Hbase一&#xff0c;引入依赖二&#xff0c;配置文件添加自己的属性三&#xff0c;配置类注入HBASE配置四&#xff0c;配置Hbase连接池五&#xff0c;配置操作服务类 一&#xff0c;引入依赖 <dependency><groupId>org…...

SQL优化总结

SQL优化总结 1. MySQL层优化五个原则2. SQL优化策略2.1 避免不走索引的场景 3. SELECT语句其他优化3.1 避免出现select *3.2 避免出现不确定结果的函数3.3 多表关联查询时&#xff0c;小表在前&#xff0c;大表在后。3.4 使用表的别名3.5 调整Where字句中的连接顺序 附录 1. My…...

【python学习】基础篇-字典的基本操作 获取当前日期时间

1.字典的定义与创建 定义字典时&#xff0c;每个元素都包含两个部分“键”和“值”&#xff0c;在“键”和“值”之间使用冒号(:)分隔&#xff0c;相邻两个元素使用逗号分隔&#xff0c;所有元素放在一个大括号“{}”中。语法格式如下: dictionary (‘key1’:‘value1’, &quo…...

Python FreeCAD.Vector方法代码示例

Python FreeCAD.Vector方法代码示例 本文整理汇总了Python中FreeCAD.Vector方法的典型用法代码示例。如果您正苦于以下问题&#xff1a;Python FreeCAD.Vector方法的具体用法&#xff1f;Python FreeCAD.Vector怎么用&#xff1f;Python FreeCAD.Vector使用的例子&#xff1f;那…...

HDFS 梳理

HDFS客户端 客户端作用 管理文件目录文件系统操作读写 客户端生成 配置项 配置 客户端状态 缓冲相关参数&#xff0c;读写缓冲 失败切换操作 推测执行?? NN引用 NNProxy 客户端关闭 关闭IO流 修改状态 关闭RPC连接 是否有多个RPC连接&#xff1f; HDFS读 打开文件构…...

ChatGPT团队中,3个清华学霸,1个北大学霸,共9位华人

众所周知&#xff0c;美国硅谷其实有着众多的华人&#xff0c;哪怕是芯片领域&#xff0c;华为也有着一席之地&#xff0c;比如AMD 的 CEO 苏姿丰、Nvidia 的 CEO 黄仁勋 都是华人。 还有更多的美国著名的科技企业中&#xff0c;都有着华人的身影&#xff0c;这些华人&#xff…...

通过工具生成指定 类型 大小 文件

今天给大家介绍一个神器 首先 大家在开发过程中或许经常需要涉及到文件上传类的功能 需要测试文件过大 空文件等等清空 不同大小的文件 而这种文件大小是比较不好控制的 但大家可以下载我的资源 文件生成工具(可生成指定大小 类型文件) 下载下来里面就有一个 fileGeneration…...

超外差收音机的制作-电子线路课程设计-实验课

超外差收音机的制作 一、原理部分&#xff1a; 超外差收音机&#xff1a;超外差式收音机是将接收到的不同频率的高频信号全部变成一个固定的中频信号进行放大&#xff0c;因而电路对各种电台信号的放大量基本是相同的&#xff0c;这样可以使中放电路具有优良的频率特性。 超…...

TensorFlow 深度学习实战指南:1~5 全

原文&#xff1a;Hands-on Deep Learning with TensorFlow 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…...

【数据结构】队列的实现

白日去如箭&#xff0c;达者惜今阳。 --朱敦儒目录 &#x1f681;前言&#xff1a;​ &#x1f3dd;️一.队列的概念及结构 &#x1f33b;二.队列各种功能的实现 &#x1f34d;1.队列的初始化 &#x1f3dd;️2.队列…...

【数据库】— 无损连接、Chase算法、保持函数依赖

【数据库】— 无损连接、Chase算法 Chase算法Chase算法举例一种简便方法&#xff1a;分解为两个模式时无损连接和函数依赖的一个简单例子 Chase算法 形式化定义&#xff1a; 构造一个 k k k行 n n n列的表格&#xff0c;每行对应一个模式 R i ( 1 ≤ i ≤ k ) Ri (1≤i ≤ k)…...

用英语翻译中文-汉字英文翻译

中文转英语翻译 作为一款高效、准确的中文转英语翻译软件&#xff0c;我们的产品可以帮助全球用户更好地沟通和合作&#xff0c;实现跨文化交流。 在全球化的今天&#xff0c;中英文翻译已经成为商务、学术、娱乐等各个领域不可或缺的一部分。我们的中文转英语翻译软件是为了…...

瑞吉外卖项目——缓存优化

用户数量多&#xff0c;系统访问量大 频繁访问数据库&#xff0c;系统性能下降&#xff0c;用户体验差 环境搭建 maven坐标 在项目的pom.xml文件中导入spring data redis的maven坐标: <dependency><groupId>org.springframework.boot</groupId><arti…...

从头创建一个新的浏览器,这合理吗?

从头构建一个新浏览器&#xff1f;这如果是不是个天大的“伪需求”&#xff0c;便是一场开发者的噩梦&#xff01; 要知道&#xff0c;如果没有上百亿的资金和数百名研发工程师的投入&#xff0c;从头开始构建一个新的浏览器引擎&#xff0c;几乎是不可能的。然而SerenityOS系统…...

TypeScript泛型类型和接口

本节课我们来开始了解 TypeScript 中泛型类型的概念和接口使用。 一&#xff0e;泛型类型 1. 前面&#xff0c;我们通过泛型变量的形式来存储调用方的类型从而进行检查&#xff1b; 2. 而泛型也可以作为类型的方式存在&#xff0c;理解这一点&#xff0c;先了解下函数的…...

docker命令

1.运行 docker-compose up 2.查看命令 docker images 3.删掉docker镜像: docker rmi -f [id] docker卸载 1.杀死docker有关的容器&#xff1a; docker kill $(docker ps -a -q) 2.删除所有docker容器&#xff1a;docker rm $(docker ps -a -q) 3.删除所有docker镜像&…...

2023 年 3 月 NFT 月度报告

作者&#xff1a;Danielfootprint.network 数据来源&#xff1a;NFT Monthly Report 三月份的 NFT 市场上出现了两个有趣的趋势。一方面&#xff0c;Polygon 链尽管在二月份有所突破&#xff0c;达到了 NFT 总交易量的 4.2%&#xff0c;但于三月再次跌至 1% 以下&#xff0c;…...

【http】 get方法和Post方法区别;http和https

get方法和Post方法 get方法&#xff1a;通过url传参&#xff0c;回显输入的私密信息&#xff0c;不够私密 Post方法&#xff1a;通过正文传参&#xff0c;不会回显&#xff0c;一般私密性有保证。 一般如果上传的图片&#xff0c;音频比较大&#xff0c;推荐Post方法&#x…...

第三章 法的渊源与法的分类

目录 第一节 法的渊源的分类 一、法的渊源释义二、法的渊源种类 第二节 正式法源 一、正式法源的含义二、当代中国的正式法源三、正式法源的一般效力原则 第三节 非正式法源 一、当代中国的非正式法源 第四节 法的分类 一、法的一般分类二、法的特殊分类 第一节 法的渊源的…...

在Ubuntu18.04或者20.04下搭建edk2运行环境

#更新完之后依次执行下面两条命令 1.apt-get update 2.apt-get upgrade 如果执行之后出现源不能更新的问题,到/etc/apt/sources.list.d 下删除对应的ppa源重新更新即可解决 git clone https://github.com/tianocore/edk2.git cd edk2 git submodule update --init 如果git cl…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...