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

5.Redis 实现点赞 优化登陆(验证码 token..)

  1. Redis

(1)简介

  • Redis 是一个高性能的 key-value 数据库

  • 原子 – Redis的所有操作都是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

  • 非关系形数据库

  • 数据全部存在内存中,性能高。

(2)数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

  • string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

  • Redis hash 是一个键值(key=>value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

  • Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

  • Redis 的 Set 是 string 类型的无序集合,集合是通过hash实现的

  • Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

(3)基本操作

@Test
public void testStrings() {String redisKey = "test:count";redisTemplate.opsForValue().set(redisKey, 1);System.out.println(redisTemplate.opsForValue().get(redisKey));System.out.println(redisTemplate.opsForValue().increment(redisKey));System.out.println(redisTemplate.opsForValue().decrement(redisKey));
}@Test
public void testHashes() {String redisKey = "test:user";redisTemplate.opsForHash().put(redisKey, "id", 1);redisTemplate.opsForHash().put(redisKey, "username", "zhangsan");System.out.println(redisTemplate.opsForHash().get(redisKey, "id"));System.out.println(redisTemplate.opsForHash().get(redisKey, "username"));
}@Test
public void testLists() {String redisKey = "test:ids";redisTemplate.opsForList().leftPush(redisKey, 101);redisTemplate.opsForList().leftPush(redisKey, 102);redisTemplate.opsForList().leftPush(redisKey, 103);System.out.println(redisTemplate.opsForList().size(redisKey));System.out.println(redisTemplate.opsForList().index(redisKey, 0));System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2));System.out.println(redisTemplate.opsForList().leftPop(redisKey));System.out.println(redisTemplate.opsForList().leftPop(redisKey));System.out.println(redisTemplate.opsForList().leftPop(redisKey));
}@Test
public void testSets() {String redisKey = "test:teachers";redisTemplate.opsForSet().add(redisKey, "刘备", "关羽", "张飞", "赵云", "诸葛亮");System.out.println(redisTemplate.opsForSet().size(redisKey));System.out.println(redisTemplate.opsForSet().pop(redisKey));System.out.println(redisTemplate.opsForSet().members(redisKey));
}@Test
public void testSortedSets() {String redisKey = "test:students";redisTemplate.opsForZSet().add(redisKey, "唐僧", 80);redisTemplate.opsForZSet().add(redisKey, "悟空", 90);redisTemplate.opsForZSet().add(redisKey, "八戒", 50);redisTemplate.opsForZSet().add(redisKey, "沙僧", 70);redisTemplate.opsForZSet().add(redisKey, "白龙马", 60);System.out.println(redisTemplate.opsForZSet().zCard(redisKey));System.out.println(redisTemplate.opsForZSet().score(redisKey, "八戒"));System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey, "八戒"));System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey, 0, 2));
}多次访问同一个key
@Test
public void testBoundOperations() {String redisKey = "test:count";BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);operations.increment();operations.increment();operations.increment();operations.increment();operations.increment();System.out.println(operations.get());
}

(4)spring 配置 redis

引入依赖

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

在 application.properties 中声明:访问哪个库,host地址,端口号

# RedisProperties
spring.redis.database=11
spring.redis.host=localhost
spring.redis.port=6379

在 config 下实现 RedisConfig 类

注入连接工厂才能访问数据库 RedisConnectionFactory factory

实例化 bean new RedisTemplate<>();

设置工厂后有访问数据库能力 template.setConnectionFactory(factory);

指定序列化方式(数据转化方式)

//定义自定义的redis对象@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(factory);//主要配置 序列化的方式//设置key 的 序列化方式redisTemplate.setKeySerializer(RedisSerializer.string());//设置value的序列化方式redisTemplate.setValueSerializer(RedisSerializer.json());//设置hash 的 key序列化redisTemplate.setHashKeySerializer(RedisSerializer.string());//设置 hash 的 value 序列化redisTemplate.setHashValueSerializer(RedisSerializer.json());//出发 使其生效redisTemplate.afterPropertiesSet();return  redisTemplate;}

(5)Redis 事务 管理

事务内命令不会立即执行,提交后统一执行

使用编程式事务进行管理,声明式事务用的少

调用 redisTemplate ,方法内部做匿名实现

SessionCallback() 里方法execute重写,内部实现事务逻辑

启用事务 operations.multi();

提交事务 operations.exec();

// 编程式事务
@Test
public void testTransactional() {Object obj = redisTemplate.execute(new SessionCallback() {@Overridepublic Object execute(RedisOperations operations) throws DataAccessException {String redisKey = "test:tx";operations.multi();operations.opsForSet().add(redisKey, "zhangsan");operations.opsForSet().add(redisKey, "lisi");operations.opsForSet().add(redisKey, "wangwu");System.out.println(operations.opsForSet().members(redisKey));return operations.exec();}});System.out.println(obj);
}

2.点赞

(1)业务层

生成redis key的工具 在 util 下实现 RedisKeyUtil,集合set存储谁给某个实体点的赞

public class RedisKeyUtil {private static final String SPLIT = ":";private static final String PREFIX_ENTITY_LIKE = "like:entity";private static final String PREFIX_USER_LIKE = "like:user";// 某个实体的赞// like:entity:entityType:entityId -> set(userId)public static String getEntityLikeKey(int entityType, int entityId) { //实体类型  实体IDreturn PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;}}

Service 下实现 LikeService

@Service
public class LikeService {@Autowiredprivate RedisTemplate redisTemplate;// 点赞public void like(int userId, int entityType, int entityId) {//获取keyString entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);//判断当前用户是否点过赞   即userid 是否在set中if(redisTemplate.opsForSet().isMember(entityLikeKey,userId)){redisTemplate.opsForSet().remove(entityLikeKey,userId);}else {redisTemplate.opsForSet().add(entityLikeKey,userId);}}// 查询某实体点赞的数量public long findEntityLikeCount(int entityType, int entityId){String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().size(entityLikeKey);}// 查询某人对某实体的点赞状态public int findEntityLikeStatus(int userId, int entityType, int entityId) {String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType,entityId);return redisTemplate.opsForSet().isMember(entityLikeKey,userId)? 1:0 ;}
}

(2)表现层

Controller 下实现 LikeController

  1. 获取当前用户

  1. 调用service点赞方法

  1. 获取数量和状态

  1. 放入map

  1. 返回json格式数据

@Controller
public class LikeController {@Autowiredprivate LikeService likeService;@Autowiredprivate HostHolder hostHolder;@RequestMapping(path = "/like", method = RequestMethod.POST)@ResponseBodypublic String like(int entityType, int entityId){User user = hostHolder.getUser();//点赞likeService.like(user.getId(), entityType,entityId);//更新点赞数量long likeCount = likeService.findEntityLikeCount(entityType,entityId);//查询状态int likeStatus = likeService.findEntityLikeStatus(user.getId(),entityType,entityId);Map<String,Object> map = new HashMap<>();map.put("likeCount", likeCount);map.put("likeStatus", likeStatus);return CommunityUtil.getJSONString(0, null, map);}
}

帖子详情页面赞的数量的显示

修改 DiscussPostController 下的 getDiscussPost

//根据 帖子id 查询帖子内容 评论 评论的回复@RequestMapping(path = "/detail/{discussPostId}",method = RequestMethod.GET)public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page){//根据帖子id查询帖子DiscussPost post = discussPostService.findDiscussPostById(discussPostId);model.addAttribute("post",post);//根据userid查询userUser user =userService.findUserById(post.getUserId());model.addAttribute("user",user);// 点赞数量long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeCount", likeCount);// 点赞状态int likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_POST, discussPostId);model.addAttribute("likeStatus", likeStatus);//查评论的分页信息page.setLimit(5);page.setPath("/discuss/detail/" + discussPostId);page.setRows(post.getCommentCount());//评论:给帖子的评论//回复:给评论的评论//获取所有评论List<Comment> commentList = commentService.findCommentsByEntity(ENTITY_TYPE_POST,post.getId(), page.getOffset(),page.getLimit());//用于封装 每条评论及每条评论的回复。。。List<Map<String,Object>> commentVoList = new ArrayList<>();//每一条评论 找到评论的作者。找到该评论的回复,回复的作者,回复的用户for (Comment comment:commentList) {Map<String,Object> commentVo = new HashMap<>();//存入评论内容commentVo.put("comment",comment);//放入 作者commentVo.put("user",userService.findUserById(comment.getUserId()));// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("likeStatus", likeStatus);//获取该评论的所有回复List<Comment> replyList = commentService.findCommentsByEntity(ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);//用于封装 每一条回复的 作者 回复咪表List<Map<String, Object>> replyVoList = new ArrayList<>();if(replyVoList != null){for (Comment reply: replyList) {Map<String,Object> replyVo = new HashMap<>();//回复replyVo.put("reply", reply);// 放入 回复的作者replyVo.put("user", userService.findUserById(reply.getUserId()));//回复目标User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());replyVo.put("target", target);// 点赞数量likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeCount", likeCount);// 点赞状态likeStatus = hostHolder.getUser() == null ? 0 :likeService.findEntityLikeStatus(hostHolder.getUser().getId(), ENTITY_TYPE_COMMENT, reply.getId());replyVo.put("likeStatus", likeStatus);//将 单条回复放入 此 评论 总的 回复表replyVoList.add(replyVo);}}//将回复总表 嵌入 单条评论commentVo.put("replys", replyVoList);//回复数量int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());commentVo.put("replyCount", replyCount);commentVoList.add(commentVo);}model.addAttribute("comments", commentVoList);return "/site/discuss-detail";}

3.使用Redis存储验证码

LoginController.getKaptcha

        //  老方法 验证码 存入session//session.setAttribute("kaptcha", text);// 验证码的归属 一个验证码 绑定 一个 kaptchaOwnerString kaptchaOwner = CommunityUtil.generateUUID();Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner);cookie.setMaxAge(60);cookie.setPath(contextPath);response.addCookie(cookie);//存入redisString redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);

LoginController.login

// 检查验证码 String kaptcha = (String) session.getAttribute("kaptcha");//获取验证码String kaptcha =null;if(StringUtils.isNotBlank(kaptchaOwner)){//是否存在String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);kaptcha = (String) redisTemplate.opsForValue().get(redisKey);}//比对验证码if(StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equals(code)){model.addAttribute("codeMsg", "验证码不正确!");return "/site/login";}

4. 使用Redis存储登录凭证

UserService

  1. login 生成登录凭证

// 生成登录凭证LoginTicket loginTicket = new LoginTicket();loginTicket.setUserId(user.getId());loginTicket.setTicket(CommunityUtil.generateUUID());loginTicket.setStatus(0);loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));//loginTicketMapper.insertLoginTicket(loginTicket);String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());redisTemplate.opsForValue().set(redisKey, loginTicket);
  1. logout 退出登录,ticket取出来再存进去

public void logout(String ticket) {//loginTicketMapper.updateStatus(ticket, 1);String redisKey  = RedisKeyUtil.getTicketKey(ticket);LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);loginTicket.setStatus(1);redisTemplate.opsForValue().set(redisKey,loginTicket);}
  1. LoginTicket 查询凭证

public LoginTicket findLoginTicket(String ticket) {// return loginTicketMapper.selectByTicket(ticket);String redisKey  = RedisKeyUtil.getTicketKey(ticket);LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);return  loginTicket;}

5.使用Redis缓存用户数据

查用户时: 先查缓存 在查mysql

UserService

// 1.优先从缓存中取值
private User getCache(int userId) {String redisKey = RedisKeyUtil.getUserKey(userId);return (User) redisTemplate.opsForValue().get(redisKey);
}// 2.取不到时初始化缓存数据
private User initCache(int userId) {User user = userMapper.selectById(userId);String redisKey = RedisKeyUtil.getUserKey(userId);redisTemplate.opsForValue().set(redisKey, user, 3600, TimeUnit.SECONDS);return user;
}// 3.数据变更时清除缓存数据
private void clearCache(int userId) {String redisKey = RedisKeyUtil.getUserKey(userId);redisTemplate.delete(redisKey);
}public User findUserById(int id) {
//        return userMapper.selectById(id);User user = getCache(id);if (user == null) {user = initCache(id);}return user;
}public int activation(int userId, String code) {User user = userMapper.selectById(userId);if (user.getStatus() == 1) {return ACTIVATION_REPEAT;} else if (user.getActivationCode().equals(code)) {userMapper.updateStatus(userId, 1);clearCache(userId);return ACTIVATION_SUCCESS;} else {return ACTIVATION_FAILURE;}
}public int updateHeader(int userId, String headerUrl) {
//        return userMapper.updateHeader(userId, headerUrl);int rows = userMapper.updateHeader(userId, headerUrl);clearCache(userId);return rows;
}

相关文章:

5.Redis 实现点赞 优化登陆(验证码 token..)

Redis&#xff08;1&#xff09;简介Redis 是一个高性能的 key-value 数据库原子 – Redis的所有操作都是原子性的。多个操作也支持事务&#xff0c;即原子性&#xff0c;通过MULTI和EXEC指令包起来。非关系形数据库数据全部存在内存中&#xff0c;性能高。&#xff08;2&#…...

scscanner:一款功能强大的大规模状态码扫描工具

关于scscanner scscanner是一款功能强大的大规模状态码扫描工具&#xff0c;该工具可以帮助广大研究人员从一个URL列表文件中批量读取目标网站的状态码响应信息。除此之外&#xff0c;该工具还可以过滤出指定的状态码&#xff0c;并将结果存储到一个文件中以供后续深入分析使用…...

Word 和 LaTeX 文档相互转换

Word 和 LaTeX 文档相互转换 目前可以找到两种工具完成将 LaTeX\LaTeXLATE​X 文档向 Word 文档的转换, 分别为 Tex2Word和LaTeX-to-Word。 Tex2Word 安装Tex2Word后, 启动 Word, 打开你要转换的 LaTeX\LaTeXLATE​X 源文件 (注意,如果没有成功安装 Tex2Word,那么你无法读取…...

python自动发送邮件实现

目录1 前言2 准备工作2.1 电子邮件的基础知识。2.2 python邮件库2.3 邮箱设置3 python实现邮件自动发送3.1 SMTP()和send()方法介绍3.2 python实现实例参考信息1 前言 python功能强大&#xff0c;可以实现我们日常办公的很多任务。诸如批量处理word,excel,pdf等等文件&#xf…...

ccc-Classification-李宏毅(4)

文章目录Classification 概念Example ApplicationHow to do ClassificationWhy not RegesssionProbability from Class - FeatureProbability from ClassHow’s the results?Modifying ModelThree StepsProbability DistributionClassification 概念 本质是找一个函数&#x…...

Kubernetes + Docker 部署一个yolov5检测服务(基于FastDeploy)

Kubernetes Docker 从零部署一个yolov5检测服务&#xff0c;服务基于PaddlePaddle/FastDeploy的服务化部署&#xff1b;所有软件从零安装。 文章目录1.说明2.环境3.安装过程 3.1安装 Docker 3.2安装 minikube 3.3安装 Kubectl4.部署过程 4.1 Docker相关 4.2 k8s相关 4.3 启动服…...

【C++/QT】QT5.6解析Excel教程(qtxlsx)

这里写目录标题【背景】【下载qtxlsx】【安装perl】【编译qtxlsx】【添加模块】【使用qtxlsx】【背景】 新接触QT&#xff0c;很多东西都不会&#xff0c;刚接触一个解析Excel的demo&#xff0c;记录一下安装、编译、解析Excel的过程 【下载qtxlsx】 在解析之前&#xff0c;…...

C++之智能指针

前言普通指针的不足new和new门的内存需要用delete和delete[释放。程序员的主观失误&#xff0c;忘了或漏了释放程序员也不确定何时释放&#xff08;例如多个线程共享同一个对象&#xff0c;没办法确定什么时候释放&#xff09;普通指针的释放类内的指针&#xff0c;在析构函数中…...

Redis实战-session共享之修改登录拦截器

在上一篇中Redis实战之session共享&#xff0c;我们知道了通过Redis实现session共享了&#xff0c;那么token怎么续命呢&#xff1f;怎么刷新用户呢&#xff1f;本来咱们就通过拦截器来实现这两个功能。 登录拦截器优化&#xff1a; 先来看看现在拦截器情况&#xff1a; 拦截…...

数据可视化,流程化处理pycharts-

本文直接进入可视化&#xff0c;输入讲解输入列表生成图片&#xff0c;关于pandas操作看这篇pandas matplotlib 导包后使用 import matplotlib.pyplot as plt饼图 使用 plt.figure 函数设置图片的大小为 15x15 使用 plt.pie 函数绘制饼图&#xff0c;并设置相关的参数&…...

1626_MIT 6.828 lab1课程大纲学习过程整理

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 现在lab1的内容全都学习完了&#xff0c;该做的练习也都做了。接下来&#xff0c;整理一下自己看这一部分课程讲义的一些笔记。 整理之前&#xff0c;先把自己完成…...

12月无情被辞:想给还不会自动化测试的技术人提个醒

公司前段时间缺人&#xff0c;也面了不少测试&#xff0c;结果竟没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但是平均水平很让人失望。基本能用一句话概括就是&#xff1a;3年测…...

开发必备技术--docker(使用篇)

文章目录前言Docker的基本概念概念数据卷虚拟网络镜像操作镜像名称镜像命令容器操作基本操作容器创建数据卷操作创建和查看数据卷其他指令实战前言 续接上一篇博文&#xff1a; 开发必备技术–docker&#xff08;一&#xff09; 这也是开学了&#xff0c;假期的最后一篇博文&a…...

2023备战金三银四,Python自动化软件测试面试宝典合集(三)

马上就又到了程序员们躁动不安&#xff0c;蠢蠢欲动的季节~这不&#xff0c;金三银四已然到了家门口&#xff0c;元宵节一过后台就有不少人问我&#xff1a;现在外边大厂面试都问啥想去大厂又怕面试挂面试应该怎么准备测试开发前景如何面试&#xff0c;一个程序员成长之路永恒绕…...

TortoiseGit 使用教程

一、下载工具 这里给大家准备了所有安装包自取 链接&#xff1a;https://pan.baidu.com/s/1xrxxgyNXNQEGD_RjwKnPMg 提取码&#xff1a;qwer 也可在官网自行下载最新版 1.下载git&#xff0c;直接去官网下载Git - Downloads&#xff0c;根据自己的系统合理下载&#xff0c…...

Linux项目自动化构建工具make/Makefile

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 目录 前言 正文 makefile文件与语法规则 make指令与执行逻辑 makefile任务刷新策略 .PHONY修饰为伪目标 最后 前言 会不会写makefile&#xff0c;从一个侧面…...

M100嵌入式自动吞吐式读写器|电动读卡机如何通过C#程序读取社保卡号

M100嵌入式自动吞吐式读写器|电动读卡机是一款双保护门功能读卡器&#xff0c;第一层防尘防异物机械门&#xff0c;第二层电动门。 M100嵌入式自动吞吐式读写器|电动读卡机采用耐高温、耐磨擦、高强度、抗老化的复合型塑胶为主体&#xff0c;在走卡通道两侧镶有不锈钢金属&…...

STM32----搭建Arduino开发环境

搭建Arduino开发环境前言一、Arduino软件1.软件下载2.软件安装3.软件操作二、Cortex官方内核三、烧录下载四、其他第三方内核1.Libmaple内核2.Steve改进的LibMaple 内核3.STMicroelectronics(ST)公司编写的内核总结前言 本章介绍搭建STM32搭建Arduino开发环境&#xff0c;包括…...

华为OD机试 - 事件推送(Python),真机试题

事件推送 题目 同一个数轴 X 上有两个点的集合 A={A1, A2, …, Am} 和 B={B1, B2, …, Bn}, Ai 和 Bj 均为正整数,A、B 已经按照从小到大排好序,A、B 均不为空, 给定一个距离 R (正整数), 列出同时满足如下条件的所有(Ai, Bj)数对: Ai <= BjAi, Bj 之间的距离小于…...

论如何获取CSDN原力

0x00 前言 因为个人需求&#xff0c;所以需要增长原力值&#xff0c;故对原力值的增长方式进行探索和总结。 0x01 正文 参考&#xff1a;https://blog.csdn.net/SoftwareTeacher/article/details/114499372 1.举报了劣质内容&#xff08;博客&#xff0c;下载的资源&#x…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...