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

Spring项目使用Redis限制用户登录失败的次数以及暂时锁定用户登录权限

文章目录

    • 背景
    • 环境
    • 代码实现
      • 0. 项目结构图(供参考)
      • 1. 数据库中的表(供参考)
      • 2. 依赖(pom.xml)
      • 3. 配置文件(application.yml)
      • 4. 配置文件(application-dev.yml)
      • 5. UserLoginDTO
      • 6. DemoConstant
      • 7. User(后来才用的lombok,没有统一写法)
      • 8. UserMapper
      • 9. UserService(供参考)
      • 10. UserController
      • 11. RedisConfig
      • 12. 统一返回结果
      • 13. 启动类LoginDemoApplication
    • 测试登录接口(一分钟内五次密码全错,触发账号锁定登录权限)
      • 第一次测试(300ms)
      • 第二次测试(32ms)
      • 第三次测试(22ms)
      • 第四次测试(12ms)
      • 第五次测试(8ms)
    • 总结

背景

前两天被面试到这个问题,最初回答的不是很合理,登录次数这方面记录还一直往数据库上面想,后来感觉在数据库中加一个登录日志表,来查询一段时间内用户登录的次数,现在看来,自己还是太年轻了,做个登录限制肯定是为了防止数据库高并发,加一个表来记录登录日志,这就把请求都打到数据库了,后来看了前辈们的解决方案,可以用Redis来实现,包括登录次数和账号锁定,我最开始在回答这个问题的时候只回答到了账号锁定用Redis做管理,前者登录次数回答的比较差劲,后来我也及时复盘了这次面试,就标题的内容做出基本实现

环境

Java8、MySQL8、Redis、IDEA,环境支持的同学可以参考这份代码实现以下

代码实现

0. 项目结构图(供参考)

在这里插入图片描述

1. 数据库中的表(供参考)

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for login_demo_user
-- ----------------------------
DROP TABLE IF EXISTS `login_demo_user`;
CREATE TABLE `login_demo_user`  (`id` bigint NOT NULL COMMENT '主键',`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密码',PRIMARY KEY (`id`, `username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of login_demo_user
-- ----------------------------
INSERT INTO `login_demo_user` VALUES (1, 'hh', 'hh');SET FOREIGN_KEY_CHECKS = 1;

2. 依赖(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version><relativePath/></parent><groupId>com.openallzzz</groupId><artifactId>logindemo</artifactId><version>0.0.1-SNAPSHOT</version><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

3. 配置文件(application.yml)

server:port: 8080spring:profiles:active: devmain:allow-circular-references: truedatasource:druid:driver-class-name: ${datasource.driver-class-name}url: jdbc:mysql://${datasource.host}:${datasource.port}/${datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=trueusername: ${datasource.username}password: ${datasource.password}redis:host: ${redis.host}port: ${redis.port}database: ${redis.database}mybatis:#mapper配置文件mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.openallzzz.logindemo.entityconfiguration:#开启驼峰命名map-underscore-to-camel-case: truelogging:level:com:openallzzz:mapper: debugservice: infocontroller: info

4. 配置文件(application-dev.yml)

datasource:driver-class-name: com.mysql.cj.jdbc.Driverhost: localhostport: 3306database: testdbusername: rootpassword: root
redis:host: localhostport: 6379database: 1

5. UserLoginDTO

package com.openallzzz.logindemo.dto;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLoginDTO {private String username;private String password;}

6. DemoConstant

package com.openallzzz.logindemo.constant;public class DemoConstant {// 每分钟限制登录的最大次数public static final int MAX_LOGIN_TIMRS_PER_MINUTE = 5;
}

7. User(后来才用的lombok,没有统一写法)

package com.openallzzz.logindemo.entity;public class User {private Long id;private String username;private String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

8. UserMapper

package com.openallzzz.logindemo.mapper;import com.openallzzz.logindemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserMapper {@Select("select id, username, password from login_demo_user where username = #{username}")User selectByUsername(String username);}

9. UserService(供参考)

package com.openallzzz.logindemo.service;import com.openallzzz.logindemo.constant.DemoConstant;
import com.openallzzz.logindemo.dto.UserLoginDTO;
import com.openallzzz.logindemo.entity.User;
import com.openallzzz.logindemo.mapper.UserMapper;
import com.openallzzz.logindemo.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service
@Slf4j
public class UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate RedisTemplate redisTemplate;public Result<String> login(UserLoginDTO userLoginDTO) {if (userLoginDTO == null || userLoginDTO.getUsername() == null || userLoginDTO.getPassword() == null) {return Result.error("用户信息不完整!");}String username = userLoginDTO.getUsername();String password = userLoginDTO.getPassword();boolean lockStatus = getLockStatus(username);if (lockStatus) {return Result.error("失败次数过多,请稍后重试");}User user = userMapper.selectByUsername(username);if (user.getPassword().equals(password)) {clearLastCount(username);clearLockStatus(username);return Result.success();} else {int lastCount = getLastCount(username);if (lastCount + 1 == DemoConstant.MAX_LOGIN_TIMRS_PER_MINUTE) {setLockStatus(username);return Result.error("失败次数过多,请稍后重试");} else {setLastCount(username);return Result.error("登录失败,请检查用户名或密码,再重试");}}}private void clearLockStatus(String username) {log.info("清除用户锁定状态:{}", username);String key = "Lock" + ":" + username;redisTemplate.delete(key);}private void clearLastCount(String username) {log.info("将用户登录次数还原:{}", username);String key = "Count" + ":" + username;redisTemplate.delete(key);}private int getLastCount(String username) {log.info("获取用户一分钟内已经失败登录了多少次:{}", username);String key = "Count" + ":" + username;Integer count = (Integer) redisTemplate.opsForValue().get(key);return count == null ? 0 : count;}private void setLastCount(String username) {log.info("设置用户一分钟内已经失败登录了多少次:{}", username);String key = "Count" + ":" + username;redisTemplate.opsForValue().set(key, getLastCount(username) + 1, 1, TimeUnit.MINUTES);}private void setLockStatus(String username) {log.info("锁定用户,限制其登录:{}", username);String key = "Lock" + ":" + username;redisTemplate.opsForValue().set(key, "lock", 2, TimeUnit.HOURS);}private boolean getLockStatus(String username) {log.info("获取用户是否被限制其登录:{}", username);String key = "Lock" + ":" + username;String o = (String) redisTemplate.opsForValue().get(key);if ("lock".equals(o)) return true;return false;}}

10. UserController

package com.openallzzz.logindemo.controller;import com.openallzzz.logindemo.dto.UserLoginDTO;
import com.openallzzz.logindemo.result.Result;
import com.openallzzz.logindemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/login")public Result<String> login(@RequestBody UserLoginDTO userLoginDTO) {log.info("用户登录:{}", userLoginDTO);return userService.login(userLoginDTO);}}

11. RedisConfig

package com.openallzzz.logindemo.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
@EnableCaching
public class RedisConfig {@Bean(name = "redisTemplate")public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object> template = new RedisTemplate<>();//配置连接工厂template.setConnectionFactory(factory);//使用jackson序列化和反序列value的值,Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper mapper = new ObjectMapper();//指定需要序列化的范围,All表示field、get和set,以及修饰符范围,ANY表示所有范围,包括privatemapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);jacksonSerializer.setObjectMapper(mapper);//设置template中value使用Jackson2JsonRedisSerializer序列化template.setValueSerializer(jacksonSerializer);//设置template中key使用StringRedisSerializer序列化template.setKeySerializer(new StringRedisSerializer());//这是hash中key和value的序列化方式,key采用StringRedisSerializer,value采用Jackson2JsonRedisSerializertemplate.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(jacksonSerializer);//使template属性生效template.afterPropertiesSet();return template;}
}

12. 统一返回结果

package com.openallzzz.logindemo.result;import lombok.Data;import java.io.Serializable;/*** 后端统一返回结果* @param <T>*/
@Data
public class Result<T> implements Serializable {private Integer code; //编码:1成功,0和其它数字为失败private String msg; //错误信息private T data; //数据public static <T> Result<T> success() {Result<T> result = new Result<T>();result.code = 1;return result;}public static <T> Result<T> success(T object) {Result<T> result = new Result<T>();result.data = object;result.code = 1;return result;}public static <T> Result<T> error(String msg) {Result result = new Result();result.msg = msg;result.code = 0;return result;}}

13. 启动类LoginDemoApplication

package com.openallzzz.logindemo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class LoginDemoApplication {public static void main(String[] args) {SpringApplication.run(LoginDemoApplication.class, args);}}

测试登录接口(一分钟内五次密码全错,触发账号锁定登录权限)

第一次测试(300ms)

在这里插入图片描述

第二次测试(32ms)

在这里插入图片描述

第三次测试(22ms)

在这里插入图片描述

第四次测试(12ms)

在这里插入图片描述

第五次测试(8ms)

在这里插入图片描述

总结

登录业务预先判断了该账号是否被锁定,如果短期内有大量登录请求(用户不断试错、被恶意攻击),压力只会给到Redis,从而避免DB被大量请求打中。

相关文章:

Spring项目使用Redis限制用户登录失败的次数以及暂时锁定用户登录权限

文章目录 背景环境代码实现0. 项目结构图&#xff08;供参考&#xff09;1. 数据库中的表&#xff08;供参考&#xff09;2. 依赖&#xff08;pom.xml&#xff09;3. 配置文件&#xff08;application.yml&#xff09;4. 配置文件&#xff08;application-dev.yml&#xff09;5…...

2023.8 - java - 变量类型

在Java语言中&#xff0c;所有的变量在使用前必须声明。声明变量的基本格式如下&#xff1a; type identifier [ value][, identifier [ value] ...] ; 格式说明&#xff1a; type -- 数据类型。identifier -- 是变量名&#xff0c;可以使用逗号 , 隔开来声明多个同类型变量…...

【Kubernetes】Kubernetes的Pod控制器

Pod控制器 一、Pod 控制器的概念1. Pod 控制器及其功用2. Pod 控制器有多种类型2.1 ReplicaSet2.2 Deployment2.3 DaemonSet2.4 StatefulSet2.5 Job2.6 Cronjob 3. Pod 与控制器之间的关系 二、Pod 控制器的使用1. Deployment2. SatefulSet2.1 为什么要有headless&#xff1f;2…...

Ubuntu20.04安装Nvidia显卡驱动教程

1、禁用nouveau 1、创建文件&#xff0c;如果没有下载vim编辑器&#xff0c;将vim换成gedit即可 $ sudo vim /etc/modprobe.d/blacklist-nouveau.conf 2、在文件中插入以下内容&#xff0c;将nouveau加入黑名单&#xff0c;默认不开启 blacklist nouveau options nouveau m…...

视频汇聚/视频云存储/视频监控管理平台EasyCVR添加萤石云设备详细操作来啦!

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

AI 绘画Stable Diffusion 研究(十二)SD数字人制作工具SadTlaker插件安装教程

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 想必大家经常看到&#xff0c;无论是在产品营销还是品牌推广时&#xff0c;很多人经常以数字人的方式来为自己创造财富。而市面上的数字人收费都比较昂贵&#xff0c;少则几…...

数据结构——链表详解

链表 文章目录 链表前言认识链表单链表结构图带头单循环链表结构图双向循环链表结构图带头双向循环链表结构图 链表特点 链表实现(带头双向循环链表实现)链表结构体(1) 新建头节点(2) 建立新节点(3)尾部插入节点(4)删除节点(5)头部插入节点(6) 头删节点(7) 寻找节点(8) pos位置…...

(学习笔记-进程管理)什么是悲观锁、乐观锁?

互斥锁与自旋锁 最底层的两种就是 [互斥锁和自旋锁]&#xff0c;有很多高级的锁都是基于它们实现的。可以认为它们是各种锁的地基&#xff0c;所以我们必须清楚它们之间的区别和应用。 加锁的目的就是保证共享资源在任意时间内&#xff0c;只有一个线程访问&#xff0c;这样就…...

actuator/prometheus使用pushgateway上传jvm监控数据

场景 准备 prometheus已经部署pushgateway服务&#xff0c;访问{pushgateway.server:9091}可以看到面板 实现 基于springboot引入支持组件&#xff0c;版本可以 <!--监控检查--><dependency><groupId>org.springframework.boot</groupId><artifa…...

Linux设置临时目录路径的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

19-普通组件的注册使用

普通组件的注册使用-局部注册 一. 组件注册的两种方式:1.局部注册:只能在注册的组件内使用 (1) 创建 vue 文件(单文件组件) (2) 在使用的组件内导入,并注册 components:{ 组件名: 组件对象 } // 导入需要注册的组件 import 组件对象 from.vue文件路径 import HmHeader from ./…...

Java基础篇:抽象类与接口

1、抽象类和接口的定义&#xff1a; &#xff08;1&#xff09;抽象类主要用来抽取子类的通用特性&#xff0c;作为子类的模板&#xff0c;它不能被实例化&#xff0c;只能被用作为子类的超类。 &#xff08;2&#xff09;接口是抽象方法的集合&#xff0c;声明了一系列的方法…...

面对对象编程范式

本文是阅读《设计模式之美》的总结和心得&#xff0c;跳过了书中对面试和工作用处不大或不多的知识点&#xff0c;总结总共分为三章&#xff0c;分别是面对对象编程范式、设计原则和设计模式 现如今&#xff0c;编程范式存在三种&#xff0c;它们分别是面向对象编程、面向过程编…...

“深度学习”学习日记:Tensorflow实现VGG每一个卷积层的可视化

2023.8.19 深度学习的卷积对于初学者是非常抽象&#xff0c;当时在入门学习的时候直接劝退一大班人&#xff0c;还好我坚持了下来。可视化时用到的图片&#xff08;我们学校的一角&#xff01;&#xff01;&#xff01;&#xff09;以下展示了一个卷积和一次Relu的变化 作者使…...

146. LRU 缓存

题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否…...

Unity框架学习--场景切换管理器

活动场景 用脚本实例化的游戏对象都会生成在活动场景中。 哪个场景是活动场景&#xff0c;则当前的天空盒就会使用该场景的天空盒。 只能有一个场景是活动场景。 在Hierarchy右击一个场景&#xff0c;点击“Set Active Scene”可以手动把这个场景设置为活动场景。也可以使用…...

Kotlin Lambda和高阶函数

Lambda和高阶函数 本文链接&#xff1a; 文章目录 Lambda和高阶函数 lambda输出&#xff08;返回类型&#xff09;深入探究泛型 inline原理探究 高阶函数集合、泛型自己实现Kotlin内置函数 扩展函数原理companion object 原理 > 静态内部类函数式编程 lambda 1、lambda的由…...

ELKstack-Elasticsearch配置与使用

一. 部署前准备 最小化安装 Centos 7.x/Ubuntu x86_64 操作系统的虚拟机&#xff0c;vcpu 2&#xff0c;内存 4G 或更多&#xff0c; 操作系统盘 50G&#xff0c;主机名设置规则为 es-server-nodeX &#xff0c; 额外添加一块单独的数据磁盘 大小为 50G 并格式化挂载到/data/e…...

Kotlin 基础教程二

constructor 构造器一般情况下可以简化为主构造器 即: class A constructor(参数) : 父类 (参数) 也可以在构造器上直接声明属性constructor ( var name) 这样可以全局访问 init { } 将和成员变量一起初始化 susped 挂起 data class 可以简化一些bean类 比如get / set ,自动…...

K8S deployment挂载

挂载到emptyDir 挂载在如下目录&#xff0c;此目录是pod所在的node节点主机的目录&#xff0c;此目录下的data即对应容器里的/usr/share/nginx/html&#xff0c;实现目录挂载&#xff1b;图1红框里的号对应docker 的name中的编号&#xff0c;如下俩个图 apiVersion: apps/v1 k…...

类之间的比较

作者简介&#xff1a; zoro-1&#xff0c;目前大一&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 类之间的比较 固定需求式比较器 固定需求式 通过…...

设计模式之备忘录模式(Memento)的C++实现

1、备忘录模式的提出 在软件功能开发过程中&#xff0c;某些对象的状态在转换过程中&#xff0c;由于业务场景需要&#xff0c;要求对象能够回溯到对象之前某个点的状态。如果使用一些共有接口来让其他对象得到对象的状态&#xff0c;便会暴露对象的实现细节。备忘录模式是在不…...

学习笔记230804---restful风格的接口,delete的传参方式问题

如果后端提供的删除接口是restful风格&#xff0c;那么使用地址栏拼接的方式发送请求&#xff0c;数据放在主体中&#xff0c;后端接受不到&#xff0c;当然也还有一种可能&#xff0c;后端在这个接口的接参设置上是req.query接参。 问题描述 今天遇到的问题是&#xff0c;de…...

STM32使用IIC通信的引脚配置问题

STM32使用IIC通信的引脚配置问题 在使用IIC通信时&#xff0c;遇到引脚配置问题&#xff0c;记录一下&#xff1a; IIC的两个引脚SDA和SCL都要求既能输入又能输出。 问题&#xff1a; SDA线是由不同的器件分时控制的&#xff0c;这样就会有一个问题&#xff1a;当一个器件主动…...

题解 | #K.First Last# 2023牛客暑期多校10

K.First Last 签到题 题目大意 n n n 个人参加 m m m 场比赛&#xff0c;每场比赛中获得名次得概率均等 问针对某一人&#xff0c;他在所有场次比赛中都获得第一或倒数第一的概率 解题思路 如果人数 n > 1 n>1 n>1 &#xff0c;每场比赛的概率是 p 2 n p\dfra…...

Python 程序设计入门(025)—— 使用 os 模块操作文件与目录

Python 程序设计入门&#xff08;025&#xff09;—— 使用 os 模块操作文件与目录 目录 Python 程序设计入门&#xff08;025&#xff09;—— 使用 os 模块操作文件与目录一、操作目录的常用函数1、os 模块提供的操作目录的函数2、os.path 模块提供的操作目录的函数 二、相对…...

excel逻辑函数篇1

1、AND(logical1,[logical2],…)&#xff1a;用于测试所有条件是否均为TRUE 检查所有参数均为true&#xff0c;如果是则返回true 2、OR(logical1,[logical2],…)&#xff1a;用于测试是否有为TRUE的条件 如果任意参数值为true&#xff0c;即返回true&#xff1b;只有当所有参数…...

前端基础(Vue的模块化开发)

目录 前言 响应式基础 ref reactive 学习成果展示 Vue项目搭建 总结 前言 前面学习了前端HMTL、CSS样式、JavaScript以及Vue框架的简单适用&#xff0c;接下来运用前面的基础继续学习Vue&#xff0c;运用前端模块化编程的思想。 响应式基础 ref reactive 关于ref和react…...

SystemVerilog interface使用说明

1. Interface概念 System Verilog中引入了接口定义&#xff0c;接口与module 等价的定义&#xff0c;是要在其他的接口、module中直接定义&#xff0c;不能写在块语句中&#xff0c;跟class是不同的。接口是将一组线捆绑起来&#xff0c;可以将接口传递给module。 2. 接口的优…...

机器人制作开源方案 | 送餐机器人

作者&#xff1a;赖志彩、曹柳洲、王恩开、李雪儿、杨玉凯 单位&#xff1a;华北科技学院 指导老师&#xff1a;张伟杰、罗建国 一、作品简介 1. 场景调研 1.1项目目的 近年来&#xff0c;全国多地疫情频发&#xff0c;且其传染性极高&#xff0c;食品接触是传播途径之一。…...

Gradio部署应用到服务器不能正常访问

用Gradio部署一个基于ChatGLM-6B的应用&#xff0c;发布到团队的服务器上&#xff08;局域网&#xff0c;公网不能访问&#xff09;&#xff0c;我将gradio应用发布到服务器的9001端口 import gradio as gr with gr.Blocks() as demo:......demo.queue().launch(server_port90…...

数据暴涨时代,该如何数据治理?_光点科技

随着信息技术的迅猛发展&#xff0c;数据已经成为现代社会的核心资源。在这个被称为"数据暴涨时代"的时代里&#xff0c;大量的数据源源不断地被产生和积累&#xff0c;但如何有效地管理、分析和利用这些数据成为了一个迫切需要解决的问题。数据治理&#xff0c;作为…...

2021年03月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;找和为K的两个元素 在一个长度为n(n < 1000)的整数序列中&#xff0c;判断是否存在某两个元素之和为k。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 第一行输入序列的长度n和k&#xff0c;用空格分开。 第二行输入序列中的n个整数&#xff…...

GPT-5出世?OpenAI GPT-5商标已注册

OpenAI的GPT已经成为了业界标杆&#xff0c;升级速度之快让人瞠目&#xff0c;别人追GPT-3.5的时候GPT-4横空出世&#xff0c;差距被拉开了&#xff0c;现在GPT-5就要来了。 据商标律师泄露的消息&#xff0c;OpenAI已于7月18日注册了GPT-5商标。虽然注册商标并不罕见&#xf…...

优雅的使用 Dockerfile 定制镜像

一、使用 Dockerfile 定制镜像 1.1、Dockerfile 定制镜像 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本&#xff0c;用这个脚本来构建、定制镜像&#xff0c;无法重复的问题、镜像构建透明性的问题、…...

limit的用法mysql

当你在 MySQL 数据库中使用 LIMIT 语句&#xff0c;它可以用于限制查询结果的行数。这在分页查询或者限制返回的数据量时非常有用。下面是一些示例&#xff1a; 返回前几行数据&#xff1a; SELECT * FROM Customers LIMIT 5;这将返回 Customers 表中的前 5 行数据。 分页查…...

clickhouse Checksum doesn‘t match: 问题修复

1. 问题描述 SQL 错误 [40] [07000]: Code: 40. DB::Exception: Checksum doesnt match: corrupted data. Reference: 50e8c1efa78de2881b725d44b04be1fe. Actual: 161c99eb681ec36b83540ecdd65ad8c9. Size of compressed block: 32846. The mismatch is caused by single bit…...

企业如何开展个人信息安全影响评估(PIA)二

基本概念 根据《信息安全 技术个人信息安全影响评估指南》&#xff08;GB/T 39335—2020&#xff1b;personal information security impact assessment&#xff0c;简称“PIA”&#xff09;&#xff0c;个人信息安全影响评估是指针对个人信息处理活动&#xff0c;检验其合法合…...

android TextView 超出长度使用省略号

在Android中最常见的需求&#xff0c;就是在在外部展示信息时&#xff0c;需要简要展示内容。TextView仅需在静态布局文件中设置以下几个属性&#xff1a; android:maxWidth“100dp” // 宽度是多少才算超出 android:maxLines"2" // 高度多少才算超出 android:elli…...

c++ | 字节转换 | 字长 | 机器位数

为什么有的时候脑子转不过来&#xff1f;&#xff1f; 为什么要对字节、机器长啊、位啊都要门清 位数 一般的就是指计算机的位数&#xff0c;比如64位/32位&#xff0c;更简单的理解&#xff0c;计算机就是在不停的做二进制的计算&#xff0c;比如32位计算机&#xff0c;在长…...

7-4 交换最小值和最大值

分数 15 全屏浏览题目 切换布局 作者 C课程组 单位 浙江大学 本题要求编写程序&#xff0c;先将输入的一系列整数中的最小值与第一个数交换&#xff0c;然后将最大值与最后一个数交换&#xff0c;最后输出交换后的序列。 注意&#xff1a;题目保证最大和最小值都是唯一的。…...

解决Pycharm的Settings中Project不见了也无法选择Python Interpreter的方法

目录 一、问题如下二、解决方法 一、问题如下 突然打开项目没有python解释器&#xff0c;也无法重新配置python Interpreter&#xff0c;而且整个文件夹是黄色高亮的形式&#xff0c;如下显示&#xff0c;而且重新安装了pycharm也没用甚至说打开File–>Setting–>Projec…...

AWS EKS 集群自动扩容 Cluster Autoscaler

文章目录 一&#xff0c;需求工作需求说明 二&#xff0c;部署精简命令执行1&#xff0c;要求2&#xff0c;查看EC2 Auto Scaling groups Tag3&#xff0c;创建Serviceaccount需要的Policy&#xff0c;Role4&#xff0c;部署Cluster Autoscaler5&#xff0c;验证6&#xff0c;常…...

excel中有哪些通配符、excel配置问题,数学函数篇1之sum系列

学习excel前需要明确的是事&#xff1a;   在学习excel函数之前&#xff0c;大家需要明确一件事&#xff0c;excel现在设计到了一些新函数&#xff0c;这些新函数只能存在于office365、office2019及更 新版本之中&#xff0c;所以建议大家在学习时安装较新的版本&#xff0c;…...

工控行业需要熟悉的工业级通信协议

1. Modbus RTU Modbus RTU 是一种串行通信协议&#xff0c;常用于工控行业。它具有以下特点和优势&#xff1a; 采用二进制编码&#xff0c;数据传输更加高效。支持多种传输介质&#xff0c;如RS-232、RS-485等。容易实现和使用&#xff0c;适用于各种设备。具备强大的错误检…...

力扣题解(1030. 距离顺序排列矩阵单元格),带注释

题目描述 链接:点我 注意&#xff1a;多看几遍题目&#xff0c;开始没看懂…相当于计算矩阵网格里面的点&#xff08;不要计算边界&#xff09; 我开了题解才明白题的意思 orz… 题解 class Solution {public int[][] allCellsDistOrder(int rows, int cols, int rCenter, …...

每天一道leetcode:剑指 Offer 34. 二叉树中和为某一值的路径(中等图论深度优先遍历递归)

今日份题目&#xff1a; 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例1 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…...

利用POM完成脚本分离实现企业级自动化(POM设计模式+页面的框架封装+测试报告截图)

利用POM完成脚本分离实现企业级自动化&#xff08;POM设计模式页面的框架封装测试报告截图&#xff09; 项目-测试-手工测试 项目-测试-手工测试 1.了解需求&#xff1b; 2.编写测试用例&#xff08;开始&#xff09;——功能测试组会去做的事情 3.执行测试用例——发送测试报…...

嵌入式设计中对于只有两种状态的变量存储设计,如何高效的对循迹小车进行偏差量化

前言 &#xff08;1&#xff09;在嵌入式程序设计中&#xff0c;我们常常会要对各类传感器进行数据存储。大多时候的传感器&#xff0c;例如红外光传感器&#xff0c;返回的数据要么是0&#xff0c;要么是1。因此&#xff0c;只需要一bit就能够存储。而很多人却常常使用char型数…...

day53 第九章 动态规划part14● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

1143. 最长公共子序列 class Solution {public int longestCommonSubsequence(String text1, String text2) {int m text1.length();int n text2.length();int[][] dp new int[m 1][n 1];for (int i 1; i < m; i) {for (int j 1; j < n; j) {if (text1.charAt(i …...