Redis一些常用的技术
文章目录
- 第1关:Redis 事务与锁机制
- 第2关:流水线
- 第3关:发布订阅
- 第4关:超时命令
- 第5关:使用Lua语言
第1关:Redis 事务与锁机制
编程要求
根据提示,在右侧编辑器Begin-End补充代码,根据以下要求完成一个模拟一次银行卡支付扣款的流程:
1、当余额不足时,放弃所有被监控的键,返回false。
2、在余额扣除消费的金额,在支付金额里加上消费的金额。
测试说明
我会对你编写的代码进行测试:
测试输入:无;
预期输出:
支付成功
本次扣款10元,余额为90元
开始你的任务吧,祝你成功!
示例代码如下:
package com.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
public class TestRedis {private static String host = "127.0.0.1";private static int port = 6379;private static Jedis jedis = new Jedis(host, port);public static boolean payMent(int deduction) throws InterruptedException {int balance; // 余额//设置余额金额jedis.set("balance", "100");jedis.set("deduction", "0");//监控扣款和余额jedis.watch("balance", "deduction");/***********Begin***********/balance = Integer.parseInt(jedis.get("balance"));// 余额不足if (balance < deduction) {jedis.unwatch(); // 放弃所有被监控的键System.out.println("对不起,你的余额不足");return false;}Transaction transaction = jedis.multi();// 扣钱transaction.decrBy("balance", deduction);Thread.sleep(5000); // 在外部修改 balance 或者 debttransaction.incrBy("deduction", deduction);// list为空说明事务执行失败List<Object> list = transaction.exec();return !list.isEmpty();/***********End***********/}public static void main(String[] args) throws InterruptedException {boolean resultValue = payMent(10);if (resultValue==true){System.out.println("支付成功");int balance = Integer.parseInt(jedis.get("balance"));int deduction = Integer.parseInt(jedis.get("deduction"));System.out.printf("本次扣款"+deduction+"元,余额为"+balance+"元");}else{System.out.println("支付失败");}jedis.close();}
}
第2关:流水线
编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求开启一次流水线技术:
开启流水线。
测试十万条读写操作,设置 key 值为 key0 、 key1 、 key2 …key99998、key99999,对应 value 值为 value0 、value1、value2…value99998、value99999。
结束流水线。
测试说明
我会对你编写的代码进行测试:
测试输入:无;
预期输出:
开启流水线
消耗时间:XXX毫秒
关闭流水线
流水线成功完成!
开始你的任务吧,祝你成功!
示例代码如下:
package com.test;
import redis.clients.jedis.*;
import java.util.List;
public class RedisPipeline {public boolean pipeline() {String redisHost = "127.0.0.1";int redisPort = 6379;Jedis jedis = new Jedis(redisHost, redisPort);jedis.flushDB();/**********Begin**********/long start = System.currentTimeMillis();// 开启流水线Pipeline pipeline = jedis.pipelined();System.out.println("开启流水线");// 测试十万条读写操作for (int i = 0; i < 100000; i++) {pipeline.set("key"+i,"value"+i);pipeline.get("key"+i);}long end = System.currentTimeMillis();//关闭流水线pipeline.close();System.out.println("消耗时间:"+(end-start)+"毫秒");System.out.println("关闭流水线");/**********End**********/return true;}
}
第3关:发布订阅
编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求:
在SubThread类中订阅指定频道redis。
测试说明
我会对你编写的代码进行测试:
测试输入:quit;
预期输出:
订阅redis, 订阅频道为 redis, 线程将被阻塞
订阅redis频道成功, 频道为 redis, 订阅频道为 1
请输入传输的信息:
关闭程序
开始你的任务吧,祝你成功!
示例代码如下:
package com.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class SubThread extends Thread {private final JedisPool jedisPool;private final Subscriber subscriber = new Subscriber();private final String channel = "redis";public SubThread(JedisPool jedisPool) {super("SubThread");this.jedisPool = jedisPool;}@Overridepublic void run() {System.out.println(String.format("订阅redis, 订阅频道为 %s, 线程将被阻塞", channel));Jedis jedis = null;try {/************* Begin ***************/jedis = jedisPool.getResource();jedis.subscribe(subscriber, channel);/************* End ***************/} catch (Exception e) {System.out.println(String.format("订阅频道错误, %s", e));} finally {if (jedis != null) {jedis.close();}}}
}
第4关:超时命令
编程要求
根据提示,在右侧编辑器Begin-End补充代码,按照以下要求使用 Spring 操作 Redis 超时命令过程:
创建键值对:key 值为“今天你吃了吗?”
获取 key 值
设置 key 的过期时间为 5 秒
测试说明
我会对你编写的代码进行测试:
测试输入:无;
预期输出:
今天你吃了吗?
null
开始你的任务吧,祝你成功!
示例代码如下:
package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.concurrent.TimeUnit;
public class OverTimeRedisTest {@SuppressWarnings({ "unchecked", "rawtypes", "resource" })public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");RedisTemplate redisTemplate=applicationContext.getBean(RedisTemplate.class);redisTemplate.execute((RedisOperations ops) -> {/************Begin************/ops.boundValueOps("key").set("今天你吃了吗?");System.out.println(ops.boundValueOps("key").get());ops.expire("key",5L, TimeUnit.SECONDS);/************End************///睡眠6秒,使得key值过期try {Thread.sleep(6000);}catch (InterruptedException e){e.printStackTrace();}//获取key值System.out.println(ops.boundValueOps("key").get());//结束所有线程,退出系统System.exit(0);return null;});}
}
第5关:使用Lua语言
编程要求
根据提示,在右侧编辑器 Begin - End 处补充代码,根据以下要求完成一次手机销售库存的操作:
编写 ItemRedisTest.lua 文件,判断销售量是否比库存数量多,如果库存数量大于这次销售量,将新的库存数量更新到原来的 key 值上。
编写 ItemRedisTest.java 文件,使用 BufferedReader 读取ItemRedisTest.lua 文件,使用 eval 命令执行文件里的字符串,设置手机销售量为10。
ItemRedisTest.lua 地址为:/data/workspace/myshixun/step5/ItemRedisTest.lua
测试说明
我会对你编写的代码进行测试:
测试输入:无;
预期输出:
手机库存剩余:90
开始你的任务吧,祝你成功!
代码示例如下:
package com.redis;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.Jedis;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ItemRedisTest {public static void main(String[] args) throws IOException {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");RedisTemplate redisTemplate=applicationContext.getBean(RedisTemplate.class);Jedis jedis=(Jedis)redisTemplate.getConnectionFactory().getConnection().getNativeConnection();jedis.set("phone_item_stock", "100");/************Begin************/BufferedReader in= new BufferedReader(new FileReader("/data/workspace/myshixun/step5/ItemRedisTest.lua"));String context =null;String script="";while (null != (context = in.readLine())){script+=context+"\n";}Object obj = jedis.eval(script, 1,"phone_item_stock","10");/************End************/System.out.println("手机库存剩余:"+obj);//关闭连接jedis.close();System.exit(0);}
}
之后在命令行中输入下列代码:
vim /data/workspace/myshixun/step5/ItemRedisTest.lua
编辑该文件内容
local count = redis.call('get', KEYS[1])
local a=tonumber(count)
local b=tonumber(ARGV[1])
---Begin
if a>=b thenredis.call('set',KEYS[1],count-b)return redis.call('get', KEYS[1])
end
---End
相关文章:

Redis一些常用的技术
文章目录 第1关:Redis 事务与锁机制第2关:流水线第3关:发布订阅第4关:超时命令第5关:使用Lua语言 第1关:Redis 事务与锁机制 编程要求 根据提示,在右侧编辑器Begin-End补充代码,根据…...
基于QPainter 绘图图片绕绘制设备中心旋转
项目地址:https://gitcode.com/m0_45463480/QPainter/tree/main 获取途径:进入CSDN->GitCode直接下载或者通过git拉取仓库内容。 QPainter是Qt框架中的一个类,用于在QWidget或QPixmap等设备上进行绘图操作。它提供了丰富的绘图功能,可以用于绘制线条、图形、文本等。Q…...

计算机网络(4):网络层
网络层提供的两种服务 虚电路服务(Virtual Circuit Service)和数据报服务(Datagram Service)是在网络层(第三层)提供的两种不同的通信服务。它们主要区别在于建立连接的方式和数据传输的方式。 虚电路服务…...

动态内存分配(malloc和free、calloc和realloc)
目录 一、为什么要有动态内存分配 二、C/C中程序内存区域划分 三、malloc和free 2.1、malloc 2.2、free 四、calloc和realloc 3.1、calloc 3.2、realloc 3.3realloc在调整内存空间的是存在两种情况: 3.4realloc有malloc的功能 五、常见的动…...

C语言---井字棋(三子棋)
Tic-Tac-Toe 1 游戏介绍和随机数1.1 游戏介绍1.2 随机数的生成1.3 棋盘大小和符号 2 设计游戏2.1 初始化棋盘2.2 打印棋盘2.3 玩家下棋2.4 电脑下棋2.5 判断输赢2.6 game()函数2.7 main()函数 3 完整三子棋代码3.1 Tic_Tac_Toe.h3.2 Tic_Tac_Toe.c3.3 Test.c 4 游戏代码的缺陷 …...

[Kubernetes]3. k8s集群Service详解
在上一节讲解了k8s 的pod,deployment,以及借助pod,deployment来部署项目,但会存在问题: 每次只能访问一个 pod,没有负载均衡自动转发到不同 pod访问还需要端口转发Pod重创后IP变了,名字也变了针对上面的问题,可以借助Service来解决,下面就来看看Service怎么使用 一.Service详…...
C++ 指定范围内递增初始化一个vector<int> | Python: list(range(31, 90))
通过lambda表达式 std::iota()实现: template <typename Tp> inline void print_vec(const std::vector<Tp>& vec) {fmt::print("[{}]\n", fmt::join(vec, ", ")); }// 相当于Python的lst list(range(31, 90))const std::ve…...
【Java之数据结构与算法】
选择排序 package Code01;public class Code01_SelectionSort {public static void selectionSort(int[] arr) {if(arrnull||arr.length<2) {return;}for(int i0;i<arr.length;i) {int minIndex i;for(int ji1;j<arr.length;j) {minIndex arr[minIndex] > arr[j…...
爬虫scrapy中间件的使用
爬虫scrapy中间件的使用 学习目标: 应用 scrapy中使用间件使用随机UA的方法应用 scrapy中使用代理ip的的方法应用 scrapy与selenium配合使用 1. scrapy中间件的分类和作用 1.1 scrapy中间件的分类 根据scrapy运行流程中所在位置不同分为: 下载中间件…...
普冉(PUYA)单片机开发笔记 [完结篇]:使用体会
失败的移植:FreeRTOS 当使用了 PY32F003 的各种接口和功能后,手痒痒想把 FreeRTOS 也搬到这个 MCU 上,参考 STM32 和 GD32 对 FreeRTOS 的移植步骤,把 FreeRTOS v202212.00 版本的源码搬到了 Keil 工程中,编译倒是通过…...

Elasticsearch:生成 AI 中的微调与 RAG
在自然语言处理 (NLP) 领域,出现了两种卓越的技术,每种技术都有其独特的功能:微调大型语言模型 (LLM) 和 RAG(检索增强生成)。 这些方法极大地影响了我们利用语言模型的方式,使它们更加通用和有效。 在本文…...
ip静态好还是dhcp好?
选择使用静态 IP 还是 DHCP(动态主机配置协议)取决于您的网络需求和环境。下面是它们的一些特点和适用场景: 静态 IP: 固定的 IP 地址:静态 IP 是手动配置在设备上的固定 IP 地址,不会随时间或网络变化而改…...

PolarDB-X、OceanBase、CockroachDB、TiDB二级索引写入性能测评
为什么要做这个测试 二级索引是关系型数据库相较于NoSQL数据库的一个关键差异。二级索引必须是强一致的,因此索引的写入需要与主键的写入放在一个事务当中,事务的性能是二级索引性能的基础。 目前市面上的分布式数据库中,从使用体验的角度看…...

Convolutional Neural Network(CNN)——卷积神经网络
1.NN的局限性 拓展性差 NN的计算量大性能差,不利于在不同规模的数据集上有效运行若输入维度发生变化,需要修改并重新训练网络容易过拟合 全连接导致参数量特别多,容易过拟合如果增加更多层,参数量会翻倍无法有效利用局部特征 输入…...

鸿蒙开发基本概念
1、开发准备 1.1、UI框架 HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架可为开发者提供应用UI开发所必需的能力,比如多种组件、布局计算、动画能力、UI交互、绘制等。 方舟开发框架针对不同目的和技术…...
Open CV 图像处理基础:(二)从基本概念到实践操作
Open CV 图像处理基础:从基本概念到实践操作 一、引言 图像处理是计算机视觉领域的一个重要分支,它涉及对图像的各种操作和处理。了解图像的基本概念、读取和显示方法以及基本操作是图像处理的基础。本文将通过示例文章的形式,帮助初学者逐…...

【MAC】M2 安装docker 与 mysql
一、docker下载地址 下载地址 二、安装docker完成 罗列一下docker常用命令 # 查看docker版本 docker --version# 拉取镜像 docker pull 镜像名# 查看当前所有镜像 docker images# 查看运行中的容器 docker ps -a docker ps grep| 镜像名#镜像启动操作: sudo dock…...

轻量级web开发框架Flask本地部署及无公网ip远程访问界面
文章目录 前言1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 前言 本篇文章讲解如何在本地安装Flask,以及如何将其web界面发布到公网上并进行远程访问。 Flask是目前十分流行的web框架,采用P…...

用最通俗的语言讲解 TCP “三次握手,四次挥手”
目录 一. 前言 二. TCP 报文的头部结构 三. 三次握手 3.1. 三次握手过程 3.2. 为什么要三次握手 四. 四次挥手 4.1. 四次挥手过程 4.2. 为什么要四次挥手 五. 大白话说 5.1. 大白话说三次握手 5.2. 大白话说四次挥手 六. 总结 一. 前言 TCP 是一种面向连接的、可靠…...

使用RedisCacheWriter#clean在线异步地批量扫描匹配删除缓存数据-spring-data-redis
1.背景 生产环境,某云的某个业务Redis实例,触发内存使用率,连续 3 次 平均值 > 85 %告警。 运维同学告知,看看需要怎么优化或者升级配置?分享了其实例RDB的内存剖析链接。 通过内存剖析详情发现,存在某…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...

未授权访问事件频发,我们应当如何应对?
在当下,数据已成为企业和组织的核心资产,是推动业务发展、决策制定以及创新的关键驱动力。然而,未授权访问这一隐匿的安全威胁,正如同高悬的达摩克利斯之剑,时刻威胁着数据的安全,一旦触发,便可…...