Jedis(一)与Redis的关系

一、Jedis介绍:
1、背景:

Jedis是基于Java语言的Redis的客户端,Jedis = Java + Redis。Redis不仅可以使用命令来操作,现在基本上主流的语言都有API支持,比如Java、C#、C++、PHP、Node.js、Go等。在官方网站里有一些Java的客户端:Jedis、Redisson、Jredis、JDBC-Redis等,其中官方推荐使用Jedis和Redisson。简言之Jedis是Redis的Java版本API,通过使用Jedis可以操作Redis中的数据。

2、Jedis连接池介绍:

jedis连接资源的创建与销毁是很消耗程序性能,所以jedis为我们提供了jedis的连接池技术,jedis

连接池在创建时初始化一些连接对象存储到连接池中,使用jedis连接资源时不需要自己创建jedis对

象,而是从连接池中获取一个资源进行redis的操作。使用完毕后,不需要销毁该jedis连接资源,

而是将该资源归还给连接池,供其他请求使用。

二、Jedis API:
1、连接池API

JedisPoolConfig配置类

功能说明

JedisPoolConfig()

创建一个配置对象,使用无参构造方法就可以了

void setMaxTotal()

设置连接池最大的连接数

void setMaxWaitMillis()

设置得到连接对象Jedis最长等待时间

JedisPool连接池类

说明

JedisPool(配置对象,服务器名,端口号)

创建连接池

Jedis getResource()

从连接池中得到一个Jedis连接对象

void close()

连接池关闭方法,通常不关闭连接池

2、其他常用API: 

方法

功能

new Jedis(host, port)

创建Jedis的连接,参数:主机名,端口号

set(key,value)

添加一个字符串的键和值

get(key)

得到指定键的值

del(key)

删除指定键和值

hset(key,field,value)

添加一个hash类型的键-字段-值

hget(key,field)

通过hash键-字段得到它的值

lpush(key,values)

从左边添加一个list类型的键和元素

lpop(key)

从左边弹出一个元素

rpop(key)

从右边弹出一个元素

close()

关闭连接

三、SpringBoot集成Jedis: 

pom依赖:加上redis、jedis依赖

 <!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>

实际应用一般采用Redis集群,这里重点看下集群模式下的集成方式。

1、Redis集群模式:
(1)配置文件:配置redis、jedis属性信息
#redis配置
my.redis.server.jedis.pool.maxTotal=500
my.redis.server.jedis.pool.maxIdle=10
my.redis.server.jedis.pool.maxWaitMillis=5000
my.redis.server.jedis.pool.min-idle=5
my.redis.server.timeout=5000 
#哨兵配置
my.redis.sentinel.nodes=xxx.xx.xxx.111:26379,xxx.xx.xxx.222:26379,xxx.xx.333:26379
my.redis.sentinel.password=wtyy
my.redis.sentinel.master-name=mymaster
my.redis.sentinel.database=10
my.redis.sentinel.pool.max-total=10
my.redis.sentinel.pool.max-idle=5
my.redis.sentinel.pool.min-idle=5
(2)Jedis连接池配置类,连接Redis:
@Configuration
public class JedisConfig {private Logger logger = LoggerFactory.getLogger(JedisConfig.class);@Value("${my.redis.server.jedis.pool.maxTotal}")private int maxTotal;@Value("${my.redis.server.jedis.pool.maxIdle}")private int maxIdle;@Value("${my.redis.server.jedis.pool.maxWaitMillis}")private int maxWaitMillis;@Value("${my.redis.server.timeout}")private int timeout;@Value("${my.redis.sentinel.nodes}")private String redisSentinelNodes;@Value("${my.redis.sentinel.pool.max-total}")private int redisSentinelMaxTotal;@Value("${my.redis.sentinel.pool.max-idle}")private int redisSentinelMaxIdle;@Value("${my.redis.sentinel.pool.min-idle}")private int redisSentinelMinIdle;@Value("${my.redis.sentinel.master-name}")private String redisSentinelMasterName;@Value("${my.redis.sentinel.password}")private String redisSentinelPassword;@Value("${my.redis.sentinel.database}")private int dataBase;@Bean(name = "jedisPool")public JedisSentinelPool jedisPool() {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(maxTotal);jedisPoolConfig.setMaxIdle(maxIdle);jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);//sentinelString[] hosts = redisSentinelNodes.split(",");Set<String> sentinels = new HashSet<>(Arrays.asList(hosts));GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();poolConfig.setMaxTotal(redisSentinelMaxTotal);poolConfig.setMaxIdle(redisSentinelMaxIdle);poolConfig.setMinIdle(redisSentinelMinIdle);JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(redisSentinelMasterName,sentinels, jedisPoolConfig,timeout,redisSentinelPassword,dataBase);return  jedisSentinelPool;}
}
(3)Jedis工具类:
@SuppressWarnings("unused")
@Component
public class RedisClient {private static boolean BORROW = true; // 在borrow一个事例时是否提前进行validate操作private static Logger logger = Logger.getLogger(RedisClient.class);@Autowiredprivate JedisSentinelPool pool;/*** 获取连接*/public  synchronized Jedis getJedis() {try {if (pool != null) {return pool.getResource();} else {return null;}} catch (Exception e) {logger.info("连接池连接异常");return null;}}/*** @Description: 关闭连接* @param @param jedis* @return void 返回类型*/public static void getColse(Jedis jedis) {if (jedis != null) {jedis.close();}}/*** 格式化Key*/public static String format(String formatKey, String... keyValues) {if (keyValues == null || keyValues.length == 0) {return formatKey;}StringBuilder key = new StringBuilder();char[] chars = formatKey.toCharArray();int index = -1;boolean inmark = false;boolean firstinmark = false;for (int i = 0; i < chars.length; i++) {char ch = chars[i];if (ch == '{') {index++;inmark = true;firstinmark = true;} else if (ch == '}') {inmark = false;} else if (inmark) {if (firstinmark) {firstinmark = false;key.append(keyValues[index]);}} else {key.append(chars[i]);}}return key.toString();}/********************************** 针对key的操作 **************************************//*** 删除一个key** @param keyFormat*            key标识* @param keyValues*            key变量* @return 被删除的keys的数量*/public Long del(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.del(key);} finally {if (jedis != null) {jedis.close();}}}/*** 查询一个key是否存在** @param keyFormat*            key标识* @param keyValues*            key变量* @return key是否存在。*/public boolean exists(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.exists(key);} finally {if (jedis != null) {jedis.close();}}}/*** 设置一个key的过期的秒数** @param keyFormat*            key标识* @param seconds*            过期的秒数* @param keyValues*            key变量* @return 1表示设置成功, 0 表示设置失败或者无法被设置*/public Long expire(String keyFormat, int seconds, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.expire(key, seconds);} finally {if (jedis != null) {jedis.close();}}}/*** 设置一个UNIX时间戳的过期时间** @param keyFormat*            key标识* @param expireDate*            过期时间* @param keyValues*            key变量* @return 1表示设置成功, 0 表示设置失败或者无法被设置*/public Long expireAt(String keyFormat, Date expireDate, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.pexpireAt(key, expireDate.getTime());} finally {if (jedis != null) {jedis.close();}}}/*** 移除给定key的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。** @param keyFormat*            key标识* @param keyValues*            key变量* @return 当生存时间移除成功时,返回 1 . 如果 key 不存在或 key 没有设置生存时间,返回 0 .*/public Long persist(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.persist(key);} finally {if (jedis != null) {jedis.close();}}}/*** 设置一个key的过期的毫秒数** <pre>* 这个命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。* </pre>** @param keyFormat*            key标识* @param milliSeconds*            过期的毫秒数* @param keyValues*            key变量* @return 设置成功,返回 1,不存在或设置失败,返回 0*/public Long pexpire(String keyFormat, long milliSeconds,String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.pexpire(key, milliSeconds);} finally {if (jedis != null) {jedis.close();}}}/*** 获取key的有效毫秒数** <pre>* 这个命令类似于 TTL 命令,但它以毫秒为单位返回 key 的剩余生存时间,而不是像 TTL 命令那样,以秒为单位。* </pre>** @param keyFormat*            key标识* @param keyValues*            key变量* @return 当 key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。否则,以毫秒为单位,返回 key*         的剩余生存时间。*/public Long pttl(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.pttl(key);} finally {if (jedis != null) {jedis.close();}}}/*** 获取key的有效时间(单位:秒)** <pre>* 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。* </pre>** @param keyFormat*            key标识* @param keyValues*            key变量* @return 当 key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。否则,以秒为单位,返回 key*         的剩余生存时间。*/public Long ttl(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.ttl(key);} finally {if (jedis != null) {jedis.close();}}}/********************************** 针对字符串(string)的操作 **************************************//*** 追加一个值到key上** <pre>* 如果 key 已经存在,并且值为字符串,那么这个命令会把 value 追加到原来值(value)的结尾。* 如果 key 不存在,那么它将首先创建一个空字符串的key,再执行追加操作,这种情况 APPEND 将类似于 SET 操作。* </pre>** @param keyFormat*            key标识* @param value*            要追加的值* @param keyValues*            key变量* @return 返回append后字符串值(value)的长度。*/public Long append(String keyFormat, String value, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.append(key, value);} finally {if (jedis != null) {jedis.close();}}}/*** 整数原子减1** <pre>* 对key对应的数字做减1操作。如果key不存在,那么在操作之前,这个key对应的值会被置为0。* 如果key有一个错误类型的value或者是一个不能表示成数字的字符串,就返回错误。* 这个操作最大支持在64位有符号的整型数字。* </pre>** @param keyFormat*            key标识* @param keyValues*            key变量* @return 数字:减小之后的value*/public Long decr(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.decr(key);} finally {if (jedis != null) {jedis.close();}}}/*** 原子减指定的整数** <pre>* 将key对应的数字减decrement。如果key不存在,操作之前,key就会被置为0。* 如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。* 这个操作最多支持64位有符号的正型数字。* </pre>** @param keyFormat*            key标识* @param integer*            要减小的数值* @param keyValues*            key变量* @return 返回一个数字:减少之后的value值。*/public Long decrby(String keyFormat, long integer, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.decrBy(key, integer);} finally {if (jedis != null) {jedis.close();}}}/*** @param keyFormat*            key标识* @param keyValues*            key变量* @return key对应的value,或者null(key不存在时)*/public String get(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.get(key);} finally {if (jedis != null) {jedis.close();}}}/*** 设置一个key的value,并获取设置前的值** <pre>* 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串,就返回错误。* exp:* GETSET可以和INCR一起使用实现支持重置的计数功能。* 举个例子:每当有事件发生的时候,一段程序都会调用INCR给key mycounter加1,但是有时我们需要获取计数器的值,并且自动将其重置为0。* 这可以通过GETSET mycounter "0"来实现:* </pre>** @param keyFormat*            key标识* @param value*            要设置的值* @param keyValues*            key变量* @return 设置之前的值*/public String getSet(String keyFormat, String value, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.getSet(key, value);} finally {if (jedis != null) {jedis.close();}}}/*** 执行原子加1操作** <pre>* 对key对应的数字做加1操作。如果key不存在,那么在操作之前,这个key对应的值会被置为0。* 如果key有一个错误类型的value或者是一个不能表示成数字的字符串,就返回错误。这个操作最大支持在64位有符号的整型数字。* 提醒:这是一个string操作,因为Redis没有专用的数字类型。key对应的string都被解释成10进制64位有符号的整型来执行这个操作。* Redis会用相应的整数表示方法存储整数,所以对于表示数字的字符串,没必要为了用字符串表示整型存储做额外开销。* </pre>** @param keyFormat*            key标识* @param keyValues*            key变量* @return 增加之后的value*/public Long incr(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.incr(key);} finally {if (jedis != null) {jedis.close();}}}/*** 执行原子加1操作,并且设置过期时间(单位:s)** <pre>* 本操作是在{@linkplain RedisClient#incr(String, String...)}之上增加了一个设置过期时间的操作* </pre>** @param keyFormat*            key标识* @param expireTime*            过期时间(单位:s)* @param keyValues*            key变量* @return 增加之后的value*/public Long incr(String keyFormat, int expireTime, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();long result = jedis.incr(key);jedis.expire(key, expireTime);return result;} finally {if (jedis != null) {jedis.close();}}}/*** 执行原子增加一个整数** <pre>* 将key对应的数字加increment。如果key不存在,操作之前,key就会被置为0。* 如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。这个操作最多支持64位有符号的正型数字。* 查看方法{@linkplain RedisClient#incr(String, String...)}了解关于增减操作的额外信息。* </pre>** @param keyFormat*            key标识* @param increment*            要增加的数值* @param keyValues*            key变量* @return 增加后的value*/public Long incrBy(String keyFormat, long increment, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.incrBy(key, increment);} finally {if (jedis != null) {jedis.close();}}}/*** 执行原子增加一个浮点数** <pre>* 将key对应的数字加increment。如果key不存在,操作之前,key就会被置为0。* 如果key的value类型错误或者是个不能表示成数字的字符串,就返回错误。* </pre>** @param keyFormat*            key标识* @param increment*            要增加的数值* @param keyValues*            key变量* @return 增加后的value*/public Double incrByFloat(String keyFormat, double increment,String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.incrByFloat(key, increment);} finally {if (jedis != null) {jedis.close();}}}/*** 设置一个key的value值** <pre>* 警告:如果key已经存在了,它会被覆盖,而不管它是什么类型。* </pre>** @param keyFormat*            key标识* @param value*            要设置的值* @param keyValues*            key变量** @return 总是"OK"*/public String set(String keyFormat, String value, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.set(key, value);} finally {if (jedis != null) {jedis.close();}}}/*** 设置key-value并设置过期时间(单位:秒)** <pre>* 设置key对应字符串value,并且设置key在给定的seconds时间之后超时过期。* 该命令相当于执行了{@link #set(String, String, String...) SET} + {@link #expire(String, int, String...) EXPIRE}.并且该操作是原子的* </pre>** @param keyFormat*            key标识* @param seconds*            超时时间(单位:s)* @param value*            设置的值* @param keyValues*            key变量* @return 状态码*/public String setex(String keyFormat, int seconds, String value,String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.setex(key, seconds, value);} finally {if (jedis != null) {jedis.close();}}}/*** 设置key-value并设置过期时间(单位:毫秒)** <pre>* 跟{@link #setex(String, int, String, String...)}效果差不多,唯一区别是超时时间是ms* </pre>** @param keyFormat*            key标识* @param milliseconds*            超时时间(单位:ms)* @param value*            设置的值* @param keyValues*            key变量* @return 状态码*/public String psetex(String keyFormat, int milliseconds, String value,String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.psetex(key, (long) milliseconds, value);} finally {if (jedis != null) {jedis.close();}}}/*** 设置的一个关键的价值,只有当该键不存在** <pre>* 如果key不存在,就设置key对应字符串value。在这种情况下,该命令和SET一样。* 当key已经存在时,就不做任何操作。SETNX是"SET if Not eXists"。* </pre>** @param keyFormat*            key标识* @param value*            设置的value* @param keyValues*            key变量* @return 1 如果key被set,0 如果key没有被set*/public Long setnx(String keyFormat, String value, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.setnx(key, value);} finally {if (jedis != null) {jedis.close();}}}/*** 设置hash里面一个字段的值** @param keyFormat*            key标识* @param field*            字段* @param value*            值* @param keyValues*            key变量* @return 含义如下:1如果field是一个新的字段 0如果field原来在map里面已经存在**/public Long hset(String keyFormat, String field, String value,String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.hset(key, field, value);} finally {if (jedis != null) {jedis.close();}}}/******************************* SET 操作 *************************//*** 添加一个元素到集合(set)里** <pre>* 添加一个指定的member元素到集合的 key中.* 如果已经在集合key中存在则忽略.如果集合key 不存在,则新建集合key,并添加member元素到集合key中.* 如果key 的类型不是集合则返回错误.* </pre>** @param keyFormat*            key标识* @param value*            元素* @param keyValues*            key变量* @return 返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素.*/public Long sadd(String keyFormat, String value, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.sadd(key, value);} finally {if (jedis != null) {jedis.close();}}}/*** 获取集合里面的元素数量** @param keyFormat*            key标识* @param keyValues*            key变量* @return 集合的基数(元素的数量),如果key不存在,则返回 0.*/public Long scard(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.scard(key);} finally {if (jedis != null) {jedis.close();}}}/*** 获取集合里面的所有key** @param keyFormat*            key标识* @param keyValues*            key变量* @return 集合中的所有元素.*/public Set<String> smembers(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.smembers(key);} finally {if (jedis != null) {jedis.close();}}}/*** 删除并获取一个集合里面的元素** <pre>* 移除并返回一个集合中的随机元素* 该命令与 {@link #srandmember(String, String...)}相似,不同的是srandmember命令返回一个随机元素但是不移除.* </pre>** @param keyFormat*            key标识* @param keyValues*            key变量* @return 被移除的元素, 当key不存在的时候返回 null .*/public String spop(String keyFormat, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.spop(key);} finally {if (jedis != null) {jedis.close();}}}/*** 从集合里删除一个元素** @param keyFormat*            key标识* @param member*            要删除的元素* @param keyValues*            key变量* @return 从集合中移除元素的个数,不包括不存在的成员.*/public Long srem(String keyFormat, String member, String... keyValues) {String key = format(keyFormat, keyValues);Jedis jedis = null;try {jedis = getJedis();return jedis.srem(key, member);} finally {if (jedis != null) {jedis.close();}}}/**省略 其他不常用操作**/}
2、Redis单机模式:

配置方式有两种:

(1)代码配置Redis连接:省略jedis的一些属性配置

my.redis.server.host=xxx.xx.xxx
my.redis.server.port=6379
my.redis.server.password = wtyy
my.redis.server.jedis.pool.maxTotal=500
my.redis.server.jedis.pool.maxIdle=10
my.redis.server.jedis.pool.maxWaitMillis=5000
my.redis.server.jedis.pool.min-idle=5
my.redis.server.timeout=5000 
@Configuration
public class JedisConfig {private Logger logger = LoggerFactory.getLogger(JedisConfig.class);@Value("${my.redis.server.host}")private String host;@Value("${my.redis.server.port}")private int port;@Value("${my.redis.server.password}")private String password;@Value("${my.redis.server.jedis.pool.maxTotal}")private int maxTotal;@Value("${my.redis.server.jedis.pool.maxIdle}")private int maxIdle;@Value("${my.redis.server.jedis.pool.maxWaitMillis}")private int maxWaitMillis;@Value("${my.redis.server.timeout}")private int timeout;@Bean(name = "jedisPool")public JedisPool jedisPool() {JedisPoolConfig config = new JedisPoolConfig();config.setMaxTotal(maxTotal);config.setMaxIdle(maxIdle);config.setMaxWaitMillis(maxWaitMillis);return new JedisPool(config, host, port, timeout,password);}
}

(2)在配置文件中配置redis连接:不建议使用

spring.redis.database=1
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=500
spring.redis.pool.min-idle=0
spring.redis.timeout=0

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

密码学的100个基本概念

密码学作为信息安全的基础&#xff0c;极为重要,本文分为上下两部分&#xff0c;总计10个章节&#xff0c;回顾了密码学的100个基本概念&#xff0c;供小伙伴们学习参考。本文将先介绍前五个章节的内容。 一、密码学历史 二、密码学基础 三、分组密码 四、序列密码 五、哈希…

【产品交互】超全面B端设计规范总结

不知不觉已经深耕在B端这个领域3年有余&#xff0c;很多人接触过B端后会觉得乏味&#xff0c;因为B端的设计在视觉上并没有C端那么有冲击力&#xff0c;更多的是结合业务逻辑&#xff0c;设计出符合业务需求的交互&#xff0c;以及界面排版的合理性&#xff0c;达到产品的可用性…

ARMv8-AArch64 的异常处理模型详解之异常类型 Exception types

异常类型详解 Exception types 一&#xff0c; 什么是异常二&#xff0c;同步异常&#xff08;synchronous exceptions&#xff09;2.1 无效的指令和陷阱异常&#xff08;Invalid instructions and trap exceptions&#xff09;2.2 内存访问产生的异常2.3 产生异常的指令2.4 调…

2024区块链应用趋势,RWA实物资产化

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 实物资产通证化&#xff0…

PyTorch内置损失函数汇总 !!

文章目录 一、损失函数的概念 二、Pytorch内置损失函数 1. nn.CrossEntropyLoss 2. nn.NLLLoss 3. nn.NLLLoss2d 4. nn.BCELoss 5. nn.BCEWithLogitsLoss 6. nn.L1Loss 7. nn.MSELoss 8. nn.SmoothL1Loss 9. nn.PoissonNLLLoss 10. nn.KLDivLoss 11. nn.MarginRankingLoss 12. …

微信小程序(十二)在线图标与字体的获取与引入

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.从IconFont获取图标与文字的样式链接 2.将在线图标配置进页面中&#xff08;源码&#xff09; 3.将字体配置进页面文字中&#xff08;源码&#xff09; 4.css样式的多文件导入 获取链接 1.获取图标链接 登入…

如何自己制作一个属于自己的小程序?

在这个数字化时代&#xff0c;小程序已经成为了我们生活中不可或缺的一部分。它们方便快捷&#xff0c;无需下载安装&#xff0c;扫一扫就能使用。如果你想拥有一个属于自己的小程序&#xff0c;不论是为了个人兴趣&#xff0c;还是商业用途&#xff0c;都可以通过编程或者使用…

搭建k8s集群实战(一)系统设置

1、架构及服务 Kubernetes作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失效状态自动在其他Node拉起Pod,实现了应用层的高可用性。 针对Kubernetes集群,高可用性还应包含以下两个层面的…

回归预测 | Matlab基于OOA-SVR鱼鹰算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于OOA-SVR鱼鹰算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于OOA-SVR鱼鹰算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于OOA-SVR鱼鹰算法优化支持向量机的数据…

IS-IS:01 ISIS基本配置

这是实验拓扑&#xff0c;下面是基本配置&#xff1a; R1: sys sysname R1 user-interface console 0 idle-timeout 0 0 int loop 0 ip add 1.1.1.1 24 int g0/0/0 ip add 192.168.12.1 24 qR2: sys sysname R2 user-interface console 0 idle-timeout 0 0 int loop 0 ip add …

05.Elasticsearch应用(五)

Elasticsearch应用&#xff08;五&#xff09; 1.目标 咱们这一章主要学习Mapping&#xff08;映射&#xff09; 2.介绍 Mapping是对索引库中文档的约束&#xff0c;类似于数据表结构&#xff0c;作用如下&#xff1a; 定义索引中的字段的名称定义字段的数据类型&#xff…

HarmonyOS鸿蒙学习基础篇 - 基本语法概述

书接上文 HarmonyOS鸿蒙学习基础篇 - 运行第一个程序 Hello World 基本语法概述 打开 entry>src>main>ets>pages>index.ets 代码如下代码详细解释如下&#xff1a; Entry //Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中&#xff0c;最多可以使用…

<蓝桥杯软件赛>零基础备赛20周--第16周--GCD和LCM

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

OpenCV第 1 课 计算机视觉和 OpenCV 介绍

文章目录 第 1 课 计算机视觉和 OpenCV 介绍1.机器是如何“看”的2.机器视觉技术的常见应用3.图像识别介绍4. 图像识别技术的常见应用5.OpenCV 介绍6.图像在计算机中的存储形式 第 1 课 计算机视觉和 OpenCV 介绍 1.机器是如何“看”的 我们人类可以通过眼睛看到五颜六色的世界…

MySQL InnoDB 底层数据存储

InnoDB 页记录Page Directory记录迁移 页 是内存与磁盘交互的基本单位&#xff0c;16kb。 比如&#xff0c;查询的时候&#xff0c;并不是只从磁盘读取某条记录&#xff0c;而是记录所在的页 记录 记录的物理插入是随机的&#xff0c;就是在磁盘上的位置是无序的。但是在页中…

一文讲透Redis的LRU与LFU算法实现

深入解析Redis的LRU与LFU算法实现 一、前言 Redis是一款基于内存的高性能NoSQL数据库&#xff0c;数据都缓存在内存里&#xff0c; 这使得Redis可以每秒轻松地处理数万的读写请求。 相对于磁盘的容量&#xff0c;内存的空间一般都是有限的&#xff0c;为了避免Redis耗尽宿主…

【Linux工具篇】编辑器vim

目录 vim的基本操作 进入vim(正常模式&#xff09; 正常模式->插入模式 插入模式->正常模式 正常模式->底行模式 底行模式->正常模式 底行模式->退出vim vim正常模式命令集 vim插入模式命令集 vim末行模式命令集 vim操作总结 vim配置 Linux编译器…

小米浏览器打开H5页面表格无法滑动,如何解决?

问题&#xff1a; 小米浏览器打开H5页面表格无法滑动&#xff0c;出现此问题时&#xff0c;第一时间怀疑是代码的css样式适配问题&#xff0c;也做了很多样式适配的尝试&#xff0c;最后测试均没有解决无法滑动的问题。 转变思维&#xff1a; 脑海中突然闪现是否可以使用其他…

【Python进阶编程】python编程高手常用的设计模式(持续更新中)

Python编程高手通常熟练运用各种设计模式&#xff0c;这些设计模式有助于提高代码的可维护性、可扩展性和重用性。 以下是一些Python编程高手常用的设计模式&#xff1a; 1.单例模式&#xff08;Singleton Pattern&#xff09; 确保一个类只有一个实例&#xff0c;并提供全局…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)-大模型、扩散模型、视觉导航

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 分类: 大语言模型LLM视觉模型VLM扩散模型视觉…