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

springBoot集成caffeine,自定义缓存配置 CacheManager

目录

springboot集成caffeine

Maven依赖

配置信息:properties文件

config配置

使用案例

Caffeine定制化配置多个cachemanager

springboot集成redis并且定制化配置cachemanager


springboot集成caffeine

Caffeine是一种基于服务器内存的缓存库。它将数据存储在应用程序的内存中,以实现快速的数据访问和高性能。

由于Caffeine缓存在服务器内存中存储数据,因此它适用于需要快速读取和频繁访问的数据,比如一些热门数据、配置信息、常用查询的结果等。但是它不适用于大规模数据或需要持久化存储的数据,因为服务器内存有限,无法存储大量数据,并且缓存数据在应用程序重启后会丢失

Maven依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- caffeine服务器本地缓存 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- caffeine --><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.8.1</version></dependency><!--   可以对自定义配置的信息进行提示 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>
</dependencies>

配置信息:properties文件

/*** Caffeine Cache自定义配置属性类*/
@Data   //lombok插件的  看自己需求是否引入
@Component
@ConfigurationProperties(prefix = "com.common.caffeine")  
//这个ConfigurationProperties是为了方便配置yaml文件,
//如果有需要的话可以在yaml文件中进行配置,需要与spring-boot-configuration-processor
//这个依赖搭配使用,
//然后再在resources目录下创建一个META-INF文件夹,该文件夹下存放一个配置文件提升信息(下面会贴出来的),
//这样的话在yaml文件中进行书写的时候就会有提升信息了
public class CaffeineCacheProperties {/*** 缓存初始容量  映射的话会很灵活  羊肉串写法与驼峰命名都可以和下面的属性进行映射* com.ifi.performance.common.caffeine.init-cache-capacity*/private Integer initCacheCapacity = 256;/*** 缓存最大容量,超过之后会按照recently or very often(最近最少)策略进行缓存剔除* com.ifi.performance.common.caffeine.max-cache-capacity*/private Long maxCacheCapacity = 10000L;/*** 是否允许空值null作为缓存的value* com.ifi.performance.common.caffeine.allow-null-value*/private Boolean allowNullValue = Boolean.TRUE;}

配置yaml文件提升信息:additional-spring-configuration-metadata.json

{"properties": [{"name": "com.ifi.performance.common.caffeine.init-cache-capacity","type": "java.lang.Integer","description": "Caffeine缓存的初始容量","defaultValue": 256},{"name": "com.ifi.performance.common.caffeine.max-cache-capacity","type": "java.lang.Long","description": "Caffeine缓存的最大容量","defaultValue": "10000L"},{"name": "com.ifi.performance.common.caffeine.allow-null-value","type": "java.lang.Boolean","description": "Caffeine缓存是否允许null作为value的属性","defaultValue": "true"}]
}

这样在yaml文件中输入com.common.caffeine的时候就会有提示信息了。

config配置

/*** 服务端公用缓存常量类*/
public interface CacheConstants {/*** 系统服务端公用缓存名称 默认缓存*/String CACHE_NAME = "server_cache";
}       

编写config配置文件:CaffeineCacheConfig.java

@SpringBootConfiguration
@EnableCaching  //开启注解扫描
@Slf4j
public class CaffeineCacheConfig {//刚刚编写的properties配置文件@Autowiredprivate CaffeineCacheProperties properties;/*** 默认的全局缓存管理器* @return*/@Bean("defaultCacheManager")public CaffeineCacheManager defaultCacheManager() {CaffeineCacheManager defaultCacheManager = new CaffeineCacheManager(CacheConstants.CACHE_NAME); //指定这个缓存的命名,这里我是使用了一个常量类defaultCacheManager.setAllowNullValues(properties.getAllowNullValue());Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()) //从配置文件中获取最大容量.expireAfterWrite(7, TimeUnit.DAYS); //过期时间defaultCacheManager.setCaffeine(caffeineBuilder);log.info("the caffeine cache manager is loaded successfully!");return defaultCacheManager;}
}

使用案例

这样配置好了之后就可以在controller、service中使用配置好的缓存了。

比如说我们要在service中进行使用,案例如下:

@Autowired
@Qualifier(value = "defaultCacheManager") //这里可以直接使用Autowired就行,Autowired默认是按照对象类型进行依赖注入,如果容器中有两个及以上的同一种类型的bean,那么就会报bean冲突的错误,后面的定制化配置会用到这个Autowired
private CaffeineCacheManager defaultCacheManager;Cache cache = defaultCacheManager.getCache(CacheConstants.CACHE_NAME); //配置类中对这个cachemanager设置的缓存名称
//下面就可以通过cache操作数据:存入缓存或者是从缓存中获取数据、删除数据了。
//存入缓存的数据是key-value形式的,key最好是一个唯一的标识,不然可能会出现缓存覆盖的情况,value可以是一个字符串也可以是自定义的对象,这里我是自定义了一个对象,比如UserCache对象,这个对象中有我需要缓存的数据,比如userid等自己需要的数据
UserCache usercache = new UserCache();
usercache.setuserId = "123456"; //实际业务场景中,比如用户登录成功,可以把用户id设置进来,方便其他业务进行获取  LOGIN_INFO 常量为自定义的一个标识符,方便在查询辨别缓存数据
cache.put(userId+CacheConstants.LOGIN_INFO,usercache);//特别注意:get缓存数据的时候,很大可能获取到的是null对象,因为比如有一些业务没有被触发从而导致没有填充你需要的数据到缓存,所以这里一定要加一个空指针判断!!!
UserCache usercache = cache.get( userId + CacheConstants.LOGIN_INFO, UserCache.class);
if(usercache == null){return null;
}//清除缓存中指定的数据  通过key来清除缓存中的数据,比如用户退出登录了可以把他的一些缓存信息给清除
cache.evict(userId + CacheConstants.LOGIN_INFO);

因为我们使用的缓存管理接口是spring-cache的,spring-cache中的操作api中并没有提供设置数据缓存的过期时间的,所以如果我们有这种业务需要(比如验证码信息需要5分钟才过期,用户登录信息30天才过期),那么就需要定制化配置cachemanager了,这样从源头上解决问题。

Caffeine定制化配置多个cachemanager

依赖与上面一致,只需要修改CaffeineCacheConfig类与使用方式就行。

@SpringBootConfiguration
@EnableCaching  //开启注解扫描
@Slf4j
public class CaffeineCacheConfig {@Autowiredprivate CaffeineCacheProperties properties;/*** 默认的全局缓存管理器* @return*/@Primary  //必须要加这个注解,用于标识一个Bean(组件)是首选的候选者。当有多个同类型的Bean(组件)时,使用了@Primary注解的Bean将会成为默认选择,如果没有其他限定符(如@Qualifier)指定具体要使用的Bean,则会优先选择带有@Primary注解的Bean。@Bean("defaultCacheManager")public CaffeineCacheManager defaultCacheManager() {CaffeineCacheManager defaultCacheManager = new CaffeineCacheManager(CacheConstants.ACHE_NAME);defaultCacheManager.setAllowNullValues(properties.getAllowNullValue());Caffeine<Object, Object> caffeineBuilder = Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()).expireAfterWrite(7, TimeUnit.DAYS);defaultCacheManager.setCaffeine(caffeineBuilder);log.info("the caffeine cache manager is loaded successfully!");return defaultCacheManager;}/***  用于管理验证码缓存,设置过期时间为300秒*/@Bean("verificationCodeCacheManager")public CaffeineCacheManager verificationCodeCacheManager() {CaffeineCacheManager verificationCodeCacheManager = new CaffeineCacheManager(CacheConstants.CODE_CACHE_NAME);verificationCodeCacheManager.setCaffeine(Caffeine.newBuilder().initialCapacity(properties.getInitCacheCapacity()).maximumSize(properties.getMaxCacheCapacity()).expireAfterWrite(300, TimeUnit.SECONDS));log.info("the verificationCodeCacheManager cache manager is loaded successfully!");return verificationCodeCacheManager;}}

使用方式,和上面的案例一致,不过这个时候就必须使用@Qualifier来指定相关的bean。其他使用方式都是一致的。

@Autowired
@Qualifier(value = "defaultCacheManager") 
private CaffeineCacheManager defaultCacheManager;@Autowired
@Qualifier(value = "verificationCodeCacheManager")
private CaffeineCacheManager verificationCodeCacheManager;

springboot集成redis并且定制化配置cachemanager

缓存使用到的Maven依赖:

<!-- 集成redis依赖  -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 提供Redis连接池 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

yaml文件:Redis部分的配置

spring:redis:database: 0host: localhostport: 6379password: abc123456  #这个看你的Redis版本,一些老的Redis用的是auth,一些比较新的用的是password配置timeout: 10slettuce:pool:# 连接池最大连接数max-active: 200# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: -1ms# 连接池中的最大空闲连接max-idle: 10# 连接池中的最小空闲连接min-idle: 3

config配置类:

@SpringBootConfiguration
@EnableCaching
@Slf4j
public class RedisCacheConfig {/*** 定制链接和操作Redis的客户端工具   配置一些序列化器,这样通过缓存管理工具看到的缓存数据就不是乱码了* @param redisConnectionFactory* @return*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);//配置序列化器Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setDefaultSerializer(genericJackson2JsonRedisSerializer);objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}/*** 默认的全局缓存管理器   配置一些序列化器,这样通过缓存管理工具看到的缓存数据就不是乱码了* @return*/@Primary  //关于这个相关的解释,上面的caffeine配置中都有说明,这里就不额外说明了@Bean("defaultCacheManager")public RedisCacheManager defaultCacheManager(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));RedisCacheManager defaultCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();log.info("the redis defaultCacheManager is loaded successfully!");return defaultCacheManager;}/***  用于管理验证码缓存,设置过期时间为300秒*/@Bean("verificationCodeCacheManager")public RedisCacheManager verificationCodeCacheManager(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer));RedisCacheManager verificationCodeCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();log.info("the verificationCodeCacheManager cache manager is loaded successfully!");return verificationCodeCacheManager;}}

使用方式,和上面的一致:

@Autowired
@Qualifier(value = "defaultCacheManager")
private CaffeineCacheManager defaultCacheManager;Cache cache = defaultCacheManager.getCache(CacheConstants.CACHE_NAME); //配置类中对这个cachemanager设置的缓存名称UserCache usercache = new UserCache();
usercache.setuserId = "123456"; 
//实际业务场景中,比如用户登录成功,可以把用户id设置进来,方便其他业务进行获取  LOGIN_INFO 常量为自定义的一个标识符,方便在查询辨别缓存数据
cache.put(userId+CacheConstants.LOGIN_INFO,usercache);//特别注意:get缓存数据的时候,很大可能获取到的是null对象
UserCache usercache = cache.get( userId + CacheConstants.LOGIN_INFO, UserCache.class);
if(usercache == null){return null;
}//清除缓存中指定的数据  通过key来清除缓存中的数据
cache.evict(userId + CacheConstants.LOGIN_INFO);

相关文章:

springBoot集成caffeine,自定义缓存配置 CacheManager

目录 springboot集成caffeine Maven依赖 配置信息&#xff1a;properties文件 config配置 使用案例 Caffeine定制化配置多个cachemanager springboot集成redis并且定制化配置cachemanager springboot集成caffeine Caffeine是一种基于服务器内存的缓存库。它将数据存储在…...

【瑞吉外卖】Git部分学习

Git简介 Git是一个分布式版本控制工具&#xff0c;通常用来对软件开发过程中的源代码文件进行管理。通过Git仓库来存储和管理这些文件&#xff0c;Git仓库分为两种&#xff1a; 本地仓库&#xff1a;开发人员自己电脑上的Git仓库 远程仓库&#xff1a;远程服务器上的Git仓库…...

如何阐述自己做了一个什么样的东西

线上qps2000&#xff0c;主要的性能瓶颈在于出现在数据库I/O上。另外&#xff0c;如果是一个正常部署的容器&#xff0c;qps能达到几百就不错了。资讯服务现在做了静态的底层页&#xff0c;所以热点新闻多数会命中底层页&#xff0c;即便没有命中底层页&#xff0c;也会走多层的…...

TC3XX - MCAL知识点(二十二):QSPI 同步与异步 Mcal配置及代码实战

目录 1、MCAL配置 1.1、配置目标 1.2、同步QSPI配置 1.2.1、SpiGeneral 1.2.2、SpiMaxChannel 1.2.3、SpiMaxJob...

led台灯哪些牌子性价比高?推荐几款性价比高的护眼台灯

作为学龄期儿童的家长&#xff0c;最担心的就是孩子长时间学习影响视力健康。无论是上网课、写作业、玩桌游还是陪伴孩子读绘本&#xff0c;都需要一个足够明亮的照明环境&#xff0c;因此选购一款为孩子视力发展保驾护航的台灯非常重要。为大家推荐几款性价比高的护眼台灯。 …...

什么情况下容易发生锁表及如何处理

目录 什么情况下容易发生锁表发生锁表怎么解决 什么情况下容易发生锁表 在数据库中&#xff0c;当多个事务同时竞争访问同一个表的资源时&#xff0c;可能会发生锁表现象&#xff0c;导致性能下降甚至阻塞。以下情况容易导致锁表问题&#xff1a; 大事务操作&#xff1a;如果一…...

elk开启组件监控

elk开启组件监控 效果&#xff1a; logstash配置 /etc/logstash/logstash.yml rootnode1:~# grep -Ev "^#|^$" /etc/logstash/logstash.yml path.data: /var/lib/logstash path.logs: /var/log/logstash xpack.monitoring.enabled: true xpack.monitoring.elasti…...

Java Random 类的使用

Java中的Random类是用来生成伪随机数的工具类。它可以用来生成随机的整数、浮点数和布尔值。以下是Java Random类的一些常见用法&#xff1a; 创建Random对象&#xff1a; Random random new Random();生成随机整数&#xff1a; int randomNumber random.nextInt(); // 生…...

完美的分布式监控系统——Prometheus(普罗米修斯)与优雅的开源可视化平台——Grafana(格鲁夫娜)

一、基本概念 1、之间的关系 prometheus与grafana之间是相辅相成的关系。作为完美的分布式监控系统的Prometheus&#xff0c;就想布加迪威龙一样示例和动力强劲。在猛的车也少不了仪表盘来观察。于是优雅的可视化平台Grafana出现了。 简而言之Grafana作为可视化的平台&#xff…...

pycharm的Terminal中如何设置打开anaconda3的虚拟环境

在pycharm的File -> Settings -> Tools -> Terminal下面&#xff0c;如下图所示 修改为红框中内容&#xff0c;然后关闭终端在重新打开终端&#xff0c;即可看到anaconda3的虚拟环境就已经会被更新...

Jmeter(四) - 从入门到精通 - 创建网络测试计划(详解教程)

1.简介 在本节中&#xff0c;您将学习如何创建基本的 测试计划来测试网站。您将创建五个用户&#xff0c;这些用户将请求发送到JMeter网站上的两个页面。另外&#xff0c;您将告诉用户两次运行测试。因此&#xff0c;请求总数为&#xff08;5个用户&#xff09;x&#xff08;2…...

Flowable-结束事件-空结束事件

目录 定义图形标记XML内容 定义 空结束事件是最常见的一种结束事件&#xff0c;也是最简单的一种结束事件&#xff0c;只要把结束任务置于流程 或分支的最后节点&#xff0c;流程实例运行到该节点的时候&#xff0c;流程引擎就会结束该流程实例或分支。前面提 到&#xff0c;结…...

Elasticsearch:如何创建 Elasticsearch PEM 和/或 P12 证书?

你是否希望使用 SSL/TLS 证书来保护你的 Elasticsearch 部署&#xff1f; 在本文中&#xff0c;我们将指导你完成为 Elasticsearch 创建 PEM 和 P12 证书的过程。 这些证书在建立安全连接和确保 Elasticsearch 集群的完整性方面发挥着至关重要的作用。 友情提示&#xff1a;你可…...

数仓架构模型设计参考

1、数据技术架构 1.1、技术架构 1.2、数据分层 将数据仓库分为三层&#xff0c;自下而上为&#xff1a;数据引入层&#xff08;ODS&#xff0c;Operation Data Store&#xff09;、数据公共层&#xff08;CDM&#xff0c;Common Data Model&#xff09;和数据应用层&#xff…...

RedisTemplate.opsForGeo()用法简介并举例

RedisTemplate.opsForGeo()是RedisTemplate类提供的用于操作Geo类型&#xff08;地理位置&#xff09;的方法。它可以用于对Redis中的Geo数据结构进行各种操作&#xff0c;如添加地理位置、获取距离、获取位置信息等。 下面是一些常用的RedisTemplate.opsForGeo()方法及其用法…...

Android OkHttp源码分析--拦截器

拦截器责任链&#xff1a; OkHttp最核心的工作是在 getResponseWithInterceptorChain() 中进行&#xff0c;在进入这个方法分析之前&#xff0c;我们先来了 解什么是责任链模式&#xff0c;因为此方法就是利用的责任链模式完成一步步的请求。 拦截器流程&#xff1a; OkHtt…...

docker:如何传环境变量给entrypoint

使用shell,不带中括号 ENTRYPOINT .\main -web -c $CONFIGENTRYPOINT [sh, -c, ".\main -web -c $CONFIG"]docker build --build-arg ENVIROMENTintegration // 覆盖ENTRYPOINT命令 使用shell脚本 ENTRYPOINT ["./entrypoint.sh"]entrypoint.sh 镜像是a…...

kuboard安装和使用

windows平台下使用docker和docker-compose部署Kuboard&#xff0c;并添加Docker Desktop for windows的k8s单机集群 使用docker安装 docker run -d \--restartunless-stopped \--namekuboard \-p 80:80/tcp \-p 10081:10081/tcp \-e KUBOARD_ENDPOINT"http://内网IP:80&…...

海外直播种草短视频购物网站巴西独立站搭建

一、市场调研 在搭建网站之前&#xff0c;需要进行充分的市场调研&#xff0c;了解巴西市场的消费者需求、购物习惯和竞争情况。可以通过以下途径进行市场调研&#xff1a; 调查问卷&#xff1a;可以在巴西市场上发放调查问卷&#xff0c;了解消费者的购物习惯、偏好、购买力…...

C#图像均值和方差计算实例

本文展示图像均值和方差计算实例,分别实现RGB图像和8位单通道图像的计算方法 实现代码如下: #region 方法 RGB图像均值 直接操作内存快/// <summary>/// 定义RGB图像均值函数/// </summary>/// <param name="bmp"></param>/// <retur…...

【动态规划】数字三角形

算法提高课课堂笔记。 文章目录 摘花生题意思路代码 最低通行费题意思路代码 方格取数题意思路代码 摘花生 题目链接 Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图)&#xff0c;从西北角进去&#xff0c;东南角出来。 地里每个道…...

【C++】开源:ceres和g2o非线性优化库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍ceres和g2o非线性优化库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…...

OCR学习

...

《练习100》56~60

题目56 M 5 a [1, 2, 3, 4, 5] i 1 j M - 1 while i < M:# print(f"第{i1}轮交换前&#xff1a;i {i}, j {j} , a[{i}] {a[i]} , a[{j}] {a[j]}")a[i], a[j] a[j], a[i]# print(f"第{i1}轮交换后&#xff1a;i {i}, j {j} , a[{i}] {a[i]} , a[…...

基于大数据为底层好用准确性高的竞彩足球比分预测进球数分析软件介绍推荐

大数据与贝叶斯理论在足球比赛分析与预测中的应用 随着科技的不断进步&#xff0c;大数据分析在各个领域的应用也越来越广泛&#xff0c;其中包括体育竞技。足球比赛作为全球最受欢迎的运动之一&#xff0c;也借助大数据和贝叶斯理论来进行模型分析和预测。本文将通过结合贝叶…...

Django进阶

1.orm 1.1 基本操作 orm&#xff0c;关系对象映射。 类 --> SQL --> 表 对象 --> SQL --> 数据特点&#xff1a;开发效率高、执行效率低&#xff08; 程序写的垃圾SQL &#xff09;。 编写ORM操作的步骤&#xff1a; settings.py&#xff0c;连…...

Linux系统服务管理

服务命令比较 操作 Linux 6 Linux7 服务开机自动启动 chkconfig --level 35 iptables on systemctl enable firewalld.service 服务器开机不自动启动 chkconfig --level 35 iptables off systemctl disable firewalld.service 加入自定义服务 chkconfig --add aaa s…...

C#之控制台版本得贪吃蛇

贪吃蛇小时候大家都玩过&#xff0c;具体步骤如下: 1.给游戏制造一个有限得空间。 2.生成墙壁&#xff0c;小蛇碰撞到墙壁或者咬到自己的尾巴&#xff0c;游戏结束。 3.生成随机的食物。 4.吃掉食物&#xff0c;增加自身的体长&#xff0c;并生成新的食物。 具体代码如下&…...

ffplay数据结构分析(一)

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 下面我们对ffplay的相关数据结构进行分析&#xff0c;本章主要是对PacketQueue的讲解 struct MyAVPacketList和PacketQueue队列 ffp…...

JavaWeb学习|JSP相关内容

1.什么是JSP Java Server Pages: Java服务器端页面&#xff0c;也和Servlet一样&#xff0c;用于动态Web技术! 最大的特点: 。写JSP就像在写HTML 。区别: 。HTML只给用户提供静态的数据 。JSP页面中可以嵌入JAVA代码&#xff0c;为用户提供动态数据 JSP最终也会被转换成为一…...

房门户网站如何做优化/app如何推广以及推广渠道

springboot mybatis项目&#xff0c;想要打印sql语句&#xff0c;可以直接下载Mybatis Log Plugin插件&#xff0c;下载后重启下idea&#xff0c;然后配置文件中添加logging.level.cndebug配置即可。注意&#xff0c;这里的cn&#xff0c;是个包名&#xff0c;如果你的包名是co…...

设立网站/百度开户推广多少钱

我明明 重定向了fputc 函数 但是无法在串口助手 输出内容 最后发现 不只是需要重定向fputc 函数 还需要配置魔术棒 需要勾选这个Use Micro LIB 然后重新编译 下载进去 串口助手就能正常显示我的数据了...

职业教育网站建设可行性报告/关键词筛选工具

在最上面的导航栏&#xff0c;点击“项目”—>“属性”—>“配置属性”—>“链接器”—>“系统”—>“子系统&#xff08;在窗口右边有一个下拉图标&#xff09;”—>下拉框选择“控制台(/SUBSYSTEM:CONSOLE)”—>最后“确定”—>点击右上角"文件…...

百度外推代发排名/seo产品优化免费软件

C指向函数的指针定义方式为&#xff1a; 返回类型 &#xff08;*指针名&#xff09;&#xff08;函数参数列表&#xff09;&#xff0c;例如 void &#xff08;*p&#xff09;&#xff08;int&#xff09;是指向一个返回值为void 参数为int类型的函数。 而若想定义一个指向类成…...

经典网站域名/网站seo文章该怎么写

1、服务端解析&#xff1a; 1&#xff09;使用BufferedReader 包装获得的数据&#xff0c;为了使连接长时间不断&#xff0c;必须使用while(true) 2&#xff09;另外开启一个新的线程用户回复客户端,这里使用了PrintWriter 包装数据&#xff0c;从键盘输入数据&#xff0c;结…...

个人如何建网站/自媒体是如何赚钱的

//logger.h/*//类名&#xff1a;CLogger//功能介绍&#xff1a;Win平台日志记录功能&#xff0c;多线程安全&#xff0c;支持写日志级别的设置&#xff0c;日志格式包含日志等级&#xff0c;日志时间&#xff0c;文件名&#xff0c;行号信息//作者&#xff1a;sunflover 2016-1…...