SpringBoot--中间件技术-4:整合Shiro,Shiro基于会话SessionManager实现分布式认证,附案例含源代码!
SpringBoot整合安全中间件Shiro
技术栈:SpringBoot+Shiro
代码实现
-
pom文件加坐标
Springboot版本选择2.7.14 ;java版本1.8 ; shiro做了版本锁定 1.3.2
<properties><java.version>1.8</java.version><!--shiro版本锁定--><shiro.version>1.3.2</shiro.version> </properties> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.16</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version></dependency><!--mp--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><!-- SECURITY begin --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>${shiro.version}</version></dependency><!-- SECURITY end --> </dependencies> -
主配置文件
#配置数据源 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring?serverTimezone=GMTusername: rootpassword: 123456#配置自动驼峰映射 mybatis:configuration:map-underscore-to-camel-case: truetype-aliases-package: com.dong.pojo #MP配置自动驼峰映射 mybatis-plus:configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mybatis所执行的sql输出控制台 -
POJO实体类
Permission
@NoArgsConstructor @AllArgsConstructor @Data @Component @TableName(value = "pe_permission") public class Permission {@TableField(value = "id")private String id;@TableField(value = "name")private String name;@TableField(value = "code")private String code;@TableField(value = "description")private String description; }Role
@NoArgsConstructor @AllArgsConstructor @Data @TableName(value = "pe_role") @Component public class Role {@TableField(value = "id")private String id;@TableField(value = "name")private String name;@TableField(value = "code")private String code;@TableField(value = "description")private String description;// 外部属性@TableField(exist = false)private List<Permission> permissions; }Users
@NoArgsConstructor @AllArgsConstructor @Data @TableName(value = "pe_user") @Component public class Users {@TableId(value = "id")private String id;@TableField(value = "username")private String username;@TableField(value = "password")private String password;@TableField(value = "salt")private String salt;// 外部属性@TableField(exist = false)private List<Role> rolesList;public Users(String id, String username, String password) {this.id = id;this.username = username;this.password = password;} } -
dao层
UsersMapper
@Mapper public interface UserMapper extends BaseMapper<Users> {@Insert("insert into pe_user(id,username,password,salt) values(#{id},#{username},#{password},#{salt})")public int save(Users users);// 级联查询@Results(id = "users",value = {@Result(column = "id",property = "rolesList",many = @Many(select = "com.dong.springboot_mp_shiro.com.dong.mapper.RoleMapper.findById"))})@Select("select * from pe_user where username=#{v}")public Users findUserDetail(String name);// 简单查询@Select("select * from pe_user where username=#{v}")public Users findBaseUser(String name); }RoleMapper
@Mapper public interface RoleMapper extends BaseMapper<Role> {@Results(id = "role",value = {@Result(column = "id",property = "permissions",many=@Many(select = "com.dong.springboot_mp_shiro.com.dong.mapper.PermissionMapper.findByPermissionId"))})@Select("select * from pe_role where id in (select role_id from pe_user_role where user_id =#{v} )")public Role findById(String id);}PermissionMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.dong.springboot_mp_shiro.com.dong.pojo.Permission; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @Mapper public interface PermissionMapper extends BaseMapper<Permission> {@Select("select * from pe_permission where id in (select permission_id from pe_role_permission where role_id =#{v})")public Permission findByPermissionId(String permissionId); } -
service层
接口:
IUserService
public interface IUserService {public int save(Users users);public Users baseFindUser(String name);public Users findUserDetail(String Name); }IRoleService
public interface IRoleService { }IPermissionService
public interface IPermissionService { }实现类:
UserServiceImp
@Service public class UserServiceImp implements IUserService {@Autowired(required = false)private UserMapper uMapper;@Overridepublic int save(Users users) {System.out.println("service:"+ users);// 获取salt字符串String salt = DigestsUtil.generateSalt();// 密码加密String password = DigestsUtil.generatePassword(users.getPassword(), salt);users.setPassword(password);users.setSalt(salt);int res = uMapper.save(users);return res;}@Overridepublic Users baseFindUser(String name) {Users baseUser = uMapper.findBaseUser(name);return baseUser;}@Overridepublic Users findUserDetail(String name) {Users userDetail = uMapper.findUserDetail(name);return userDetail;} } -
controller层
@RestController public class UserController {@Autowired(required = false)private UserServiceImp service;// 首页@RequiresPermissions("user-home")@RequestMapping("/user/home")public String home(){return "访问个人主页成功";}// 用户注册@RequiresPermissions("user-add")@RequestMapping("/user/{id}")public String save(@PathVariable String id){/*int res = service.save(users);if(res>0){return "添加成功";}else{return "添加失败";}*/return "新增成功";}@RequiresPermissions("user-delete")@RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)public String delete(@PathVariable String id){return "删除成功";}@RequiresPermissions("user-update")@RequestMapping(value = "/user/{id}",method = RequestMethod.PUT)public String update(@PathVariable String id){return "修改成功";}@RequiresPermissions("user-find")@RequestMapping(value = "/user",method = RequestMethod.GET)public String find(){return "查询成功";}// 登录认证@RequestMapping("/login")public String login(Users users){try {// 构造登录令牌UsernamePasswordToken token = new UsernamePasswordToken(users.getUsername(), users.getPassword());// 获取subjectSubject subject = SecurityUtils.getSubject();// 调用subject认证subject.login(token);return "登录成功";} catch (AuthenticationException e) {return "用户名或密码错误";}}// 未登录跳转@RequestMapping("/autherror")public String autherror(){return "未认证,请登录";} }==@RequiresPermissions(" "):==标注访问该资源需要的权限
-
执行subject.long登录方法,执行Reaml的AuthenticationException方法
-
鉴权授权,执行Reaml的AuthorizationInfo方法
-
-
MyRealm
public class MyRealm extends AuthorizingRealm {@Autowired(required = false)private UserServiceImp serviceImp;// 授权鉴权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {// 获取已经认证的用户数据Users users = (Users) principalCollection.getPrimaryPrincipal();// 查询用户的详细信息Users userDetail = serviceImp.findUserDetail(users.getUsername());HashSet<String> perms = new HashSet<>(); // 权限set集合HashSet<String> roles = new HashSet<>(); // 角色set集合for(Role role: userDetail.getRolesList() ){roles.add(role.getCode());for(Permission permission: role.getPermissions() ){perms.add(permission.getCode());}}SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.setStringPermissions(perms);info.setRoles(roles);return info;}// 认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {// 获取用户登陆输入的密码(token)UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;// 用户输入的账号String username = upToken.getUsername();Users users = serviceImp.baseFindUser(username);if(users != null){SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(users, users.getPassword(), ByteSource.Util.bytes(users.getSalt()), "MyRealm");return info;}// 账号查不到,返回null(抛出异常)return null;}@PostConstruct // 属性初始化public void initCredentialsMatcher(){// 指定密码算法HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);// 指定迭代次数hashedCredentialsMatcher.setHashIterations(DigestsUtil.COUNTS);// 生成密码比较器setCredentialsMatcher(hashedCredentialsMatcher);} }@PostConstruct注解,属性初始化
加密工具类
public class DigestsUtil {// 编码方式public static final String SHA1="SHA-1";// 加密次数public static final Integer COUNTS=369;// 获取salt字符串public static String generateSalt(){SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator();return secureRandomNumberGenerator.nextBytes().toHex();}// 生成密文密码public static String generatePassword(String input,String salt){return new SimpleHash(SHA1,input,salt,COUNTS).toString();}} -
Shiro配置类:ShiroConfiguration
@Configuration public class ShiroConfiguration {/*** 1.创建shiro自带cookie对象*/@Beanpublic SimpleCookie sessionIdCookie(){SimpleCookie simpleCookie = new SimpleCookie();simpleCookie.setName("ShiroSession");return simpleCookie;}//2.创建realm@Beanpublic MyRealm getRealm() {return new MyRealm(); //new 自定义的Reaml}/*** 3.创建会话管理器*/@Beanpublic DefaultWebSessionManager sessionManager(){DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setSessionValidationSchedulerEnabled(false);sessionManager.setSessionIdCookieEnabled(true);sessionManager.setSessionIdCookie(sessionIdCookie());sessionManager.setGlobalSessionTimeout(3600000);return sessionManager;}//4.创建安全管理器@Beanpublic SecurityManager defaultWebSecurityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(getRealm());securityManager.setSessionManager(sessionManager());return securityManager;}/*** 5.保证实现了Shiro内部lifecycle函数的bean执行*/@Bean(name = "lifecycleBeanPostProcessor")public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** 6.开启对shiro注解的支持* AOP式方法级权限检查*/@Bean@DependsOn("lifecycleBeanPostProcessor")public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);return defaultAdvisorAutoProxyCreator;}/*** 7.配合DefaultAdvisorAutoProxyCreator事项注解权限校验*/@Beanpublic AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}/** 8.配置shiro的过滤器工厂再web程序中,shiro进行权限控制全部是通过一组过滤器集合进行控制* */@Beanpublic ShiroFilterFactoryBean shiroFilter(){// 1.创建过滤工厂ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();// 2.设置安全管理器filterFactoryBean.setSecurityManager(defaultWebSecurityManager());// 3.通用配置(跳转登录页面,为授权跳转的页面)filterFactoryBean.setLoginUrl("/autherror");//4.设置过滤器集合//key = 拦截的url地址//value = 过滤器类型LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();filterMap.put("/login","anon");//当前请求地址可以匿名访问filterMap.put("/user/**","authc");// 当前请求地址必须认证之后才可以访问// 在过滤器工程内设置系统过滤器filterFactoryBean.setFilterChainDefinitionMap(filterMap);return filterFactoryBean;} } -
统一异常处理器
@ControllerAdvice public class UserControllerAdv {@ExceptionHandler(value = AuthorizationException.class)@ResponseBodypublic String tongyi(HttpServletRequest request , HttpServletResponse response, AuthorizationException e){return "未授权---统一异常处理器";}}
Shiro实现分布式会话SessionManager
代码结构:代码结构和SpringBoot整合Shiro中的案例相同
问题:如图

解决思路:将当前的session会话存到缓存Redis中

实现步骤:
- 创建RedisSessionDao extends AbstractSessionDAO
- 配置ShiroConfig
代码实现:
-
RedisSessionDao
public class RedisSessionDao extends AbstractSessionDAO {@Autowiredprivate RedisTemplate redisTemplate;//创建会话@Overrideprotected Serializable doCreate(Session session) {Serializable sessionId = generateSessionId(session);assignSessionId(session, sessionId);redisTemplate.opsForValue().set(sessionId,session);return sessionId;}@Overrideprotected Session doReadSession(Serializable sessionId) {return (Session) redisTemplate.opsForValue().get(sessionId);}@Overridepublic void delete(Session session) {redisTemplate.delete(session.getId());}@Overridepublic Collection<Session> getActiveSessions() {return Collections.emptySet();}@Overridepublic void update(Session session) {redisTemplate.opsForValue().set(session.getId(),session);}} -
需要操作Redis,整合Redis
-
导入redis坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> -
yaml主配置文件配置redis
server:port: 8080 #配置数据源 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring?serverTimezone=GMTusername: rootpassword: 123456redis:port: 6379#配置自动驼峰映射 mybatis:configuration:map-underscore-to-camel-case: truetype-aliases-package: com.dong.pojo #MP配置自动驼峰映射 mybatis-plus:configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mybatis所执行的sql输出控制台 -
ShiroConfig
向容器中注入一个SessionDao,把SessionDao绑定给会话管理器
@Configuration public class ShiroConfiguration {/*** 1.创建shiro自带cookie对象*/@Beanpublic SimpleCookie sessionIdCookie(){SimpleCookie simpleCookie = new SimpleCookie();simpleCookie.setName("ShiroSession");return simpleCookie;}//2.创建realm@Beanpublic MyRealm getRealm() {return new MyRealm();}// 向容器中注入一个SessionDao@Beanpublic SessionDAO redisSessionDao(){RedisSessionDao sessionDAO = new RedisSessionDao();return sessionDAO;}/*** 3.创建会话管理器*/@Beanpublic DefaultWebSessionManager sessionManager(){DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//把SessionDao绑定给会话管理器sessionManager.setSessionDAO(redisSessionDao()); sessionManager.setSessionValidationSchedulerEnabled(false);sessionManager.setSessionIdCookieEnabled(true);sessionManager.setSessionIdCookie(sessionIdCookie());sessionManager.setGlobalSessionTimeout(3600000);return sessionManager;}//4.创建安全管理器@Beanpublic SecurityManager defaultWebSecurityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(getRealm());securityManager.setSessionManager(sessionManager());return securityManager;}/*** 5.保证实现了Shiro内部lifecycle函数的bean执行*/@Bean(name = "lifecycleBeanPostProcessor")public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** 6.开启对shiro注解的支持* AOP式方法级权限检查*/@Bean@DependsOn("lifecycleBeanPostProcessor")public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);return defaultAdvisorAutoProxyCreator;}/*** 7.配合DefaultAdvisorAutoProxyCreator事项注解权限校验*/@Beanpublic AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}/** 8.配置shiro的过滤器工厂再web程序中,shiro进行权限控制全部是通过一组过滤器集合进行控制* */@Beanpublic ShiroFilterFactoryBean shiroFilter(){// 1.创建过滤工厂ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();// 2.设置安全管理器filterFactoryBean.setSecurityManager(defaultWebSecurityManager());// 3.通用配置(跳转登录页面,为授权跳转的页面)filterFactoryBean.setLoginUrl("/autherror");//4.设置过滤器集合//key = 拦截的url地址//value = 过滤器类型LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();filterMap.put("/login","anon");//当前请求地址可以匿名访问filterMap.put("/user/**","authc");filterFactoryBean.setFilterChainDefinitionMap(filterMap);return filterFactoryBean;} }
-
相关文章:
SpringBoot--中间件技术-4:整合Shiro,Shiro基于会话SessionManager实现分布式认证,附案例含源代码!
SpringBoot整合安全中间件Shiro 技术栈:SpringBootShiro 代码实现 pom文件加坐标 Springboot版本选择2.7.14 ;java版本1.8 ; shiro做了版本锁定 1.3.2 <properties><java.version>1.8</java.version><!--shiro版本锁定…...
【QT基础入门】QT中的容器类
QT中有多种容器类,它们可以用来存储和操作不同类型的数据。根据容器的特性和用途,可以分为以下几类: 序列容器 这些容器按照一定的顺序存储数据,可以通过下标或迭代器访问。QT中的序列容器有: QList: 这是最通用的序列容器,它在内部实现为一个数组列表,可以快速地在头…...
IDEA没有Add Framework Support解决办法
点击File—>Settings 点击第一个设置快捷键 点击apply和ok即可 我们要点击一下项目,再按快捷键ctrlk 即可...
《009.SpringBoot之汽车租赁系统》
《009.SpringBoot之汽车租赁系统》 项目简介 [1]本系统涉及到的技术主要如下: 推荐环境配置:DEA jdk1.8 Maven MySQL 前后端分离; 后台:SpringBootMybatisPlus; 前台:Layuivue; [2]功能模块展示: 前端门户 1.登录&a…...
第四代智能井盖传感器,万宾科技助力城市安全
在迈向更为智能化、相互联系更为紧密的城市发展过程中,智能创新产品无疑扮演了一种重要的角色。智能井盖传感器作为新型科学技术产物,不仅解决传统井盖管理难的问题,也让城市变得更加安全美好,是城市生命线的一层重要保障。这些平…...
ClickHouse 面试题
文章目录 什么是 ClickHouse?ClickHouse 有哪些应用场景?ClickHouse 列式存储的优点有哪些?ClickHouse 的缺点是是什么?ClickHouse 的架构是怎样的?ClickHouse 的逻辑数据模型?ClickHouse 的核心特性&#…...
Python代码运行速度提升技巧!Python远比你想象中的快~
文章目录 前言一、使用内置函数二、字符串连接 VS join()三、创建列表和字典的方式四、使用 f-Strings五、使用Comprehensions六、附录- Python中的内置函数总结关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项…...
P6入门:项目初始化11-项目详情之计算Calculations
前言 使用项目详细信息查看和编辑有关所选项目的详细信息,在项目创建完成后,初始化项目是一项非常重要的工作,涉及需要设置的内容包括项目名,ID,责任人,日历,预算,资金,分类码等等&…...
<MySQL> 查询数据进阶操作 -- 联合查询
目录 一、什么是笛卡尔积? 二、什么是联合查询? 三、内连接 3.1 简介 3.2 语法 3.3 更多的表 3.4 操作演示 四、外连接 4.1 简介 4.2 语法 4.3 操作演示 五、自连接 5.1 简介 5.2 自连接非必要不使用 六、子查询(嵌套查询) 6.1 简介 6.…...
centos 6.10 安装 svn1.14.2
安装 apr 和 apr-util 下载地址 我下载的分别是 apr-1.7.4 和 apr-unit-1.6.3 常规的安装步骤 ./configure --prefix/usr/local/xxx make && make install注意要先安装 apr 再安装 apr-unit-1.6.3 安装 lz4 下载地址 要配置好环境变量,不然可能还是找…...
Java实现俄罗斯方块
规则 1.方块会从上方缓慢下落,玩家可以通过键盘上的上下左右键来控制方块。 2.方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。 3.当区域中某一列横向格子全部由方块填满,…...
【计算思维】少儿编程蓝桥杯青少组计算思维题考试真题及解析B
STEMA考试-计算思维-U8级(样题) 1.浩浩的左⼿边是( )。 A.兰兰 B.⻉⻉ C.⻘⻘ D.浩浩 2.2时30分,钟⾯上时针和分针形成的⻆是什么⻆?( ) A.钝⻆ B.锐⻆ C.直⻆ D.平⻆ 3.下⾯是⼀年级同学最喜欢的《⻄游记》…...
第三章 栈和队列【24王道数据结构笔记】
1.栈 1.1 栈的基本概念 只允许在一端(栈顶top)进行插入或删除操作的受限的线性表。后进先出(Last In First Out)LIFO。或者说先进后出FILO。 进栈顺序:a1 > a2 > a3 > a4 > a5出栈顺序:a5 > a4 > a3 > a2 …...
保姆级教程之SABO-VMD-CNN-SVM的分类诊断,特征可视化
今天出一期基于SABO-VMD-CNN-SVM的分类诊断。 依旧是采用经典的西储大学轴承数据。基本流程如下: 首先是以最小包络熵为适应度函数,采用SABO优化VMD的两个参数。其次对每种状态的数据进行特征向量的求取,并为每组数据打上标签。然后将数据送入…...
跳跃游戏(贪心思想)
题解 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 输入样例 示例 1…...
【JavaSE语法】类和对象(二)
六、 封装 6.1 封装的概念 面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。 封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互…...
【SA8295P 源码分析 (三)】121 - MAX9295A 加串器芯片手册分析 及初始化参数分析
【SA8295P 源码分析】121 - MAX9295A 加串器芯片手册分析 及初始化参数分析 一、MAX9295A 芯片特性1.1 GPIO 引脚说明1.2 功能模块框图1.3 时序分析1.3.1 GMSL2 Lock Time:25 ms1.3.2 视频初始化延时:1.1ms + 17000 x t(PCLK)1.3.3 High-Speed Data Transmission in Bursts1.…...
Maya 2024 for Mac(3D建模软件)
Maya 2024是一款三维计算机图形软件,具有强大的建模、动画、渲染、特效等功能,广泛应用于影视、游戏、广告等行业。以下是Maya 2024软件的主要功能介绍: 建模:Maya 2024具有强大的建模工具,包括多边形建模、曲面建模、…...
9. 深度学习——GAN
机器学习面试题汇总与解析——GAN 本章讲解知识点 从 GAN 讲起本专栏适合于Python已经入门的学生或人士,有一定的编程基础。本专栏适合于算法工程师、机器学习、图像处理求职的学生或人士。本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。这才是一份面试题总结的正…...
BeanUtils中的copyProperties方法使用
一、Beanutils中的copyProperties是我们在日常开发中常用的一个方法。 作用: 将a实体类中的属性赋值到b实体类中相对于的字段上 1.我们前端传参的时候我们后端通常会用vo实体类来接收,但是更新数据库的时候需要用do去操作 2.我们将vo的属性copy到do中可…...
Yokogawa AAI835-H50/K4A00模拟输入/输出模块
Yokogawa AAI835-H50/K4A00 模拟输入/输出模块产品特点:通道配置:共8个通道,含4路模拟输入和4路模拟输出。信号类型:所有通道均支持4-20mA标准电流信号。HART通信:支持HART协议,可与智能现场设备双向数字通…...
翻译 GDB 官方文档
翻译 GDB 官方文档项目地址官方文档地址下载源码包编译html运行翻译程序项目地址 https://github.com/shootercheng/gdb-translate.git 项目结构 $ tree -L 1 . ├── cmd ├── go.mod ├── input ├── internal ├── LICENSE ├── output ├── README.md ├─…...
16个分片+2副本:pg_shard的master_create_worker_shards最佳实践
16个分片2副本:pg_shard的master_create_worker_shards最佳实践 【免费下载链接】pg_shard ATTENTION: pg_shard is superseded by Citus, its more powerful replacement 项目地址: https://gitcode.com/gh_mirrors/pg/pg_shard pg_shard作为PostgreSQL的分…...
我们公司全员把 Cursor 换成了自研的 全开源AtomCode
【引子】这是一篇实录——一位 CTO 用 28 天,用 Claude GLM 双模型调度,造出了一个让全公司放弃 Cursor 的工具。然后我意识到我们正在经历的事情,比"换工具"大得多。【读者承诺】接下来 15 分钟,你会拿到三件东西:一个真实案例(28 天 1,146 commits 是怎么做出来的…...
别让依赖毁了你的实验:记一次Vision Mamba复现中causal_conv1d与mamba-ssm的版本“打架”事件
Vision Mamba复现实战:破解依赖冲突的工程化解决方案在深度学习项目的复现过程中,依赖管理往往是最容易被忽视却又最常导致问题的环节。最近在复现Vision Mamba模型时,我遭遇了一场典型的Python依赖"战争"——causal_conv1d与mamba…...
Python strip 与 rstrip 函数区别
Python strip 与 rstrip 函数区别 文章目录Python strip 与 rstrip 函数区别一、核心作用二、基础语法三、基础使用示例四、指定删除特定字符五、常用业务场景一、核心作用 函数作用范围strip()移除字符串首尾空白字符rstrip()仅移除字符串右侧末尾字符,左侧保持不…...
独立开发者利用taotoken模型广场为不同任务选择性价比最优模型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者利用taotoken模型广场为不同任务选择性价比最优模型 对于独立开发者而言,在有限的预算内高效完成多样化的开…...
Windows 11终极优化指南:一键清理系统,释放51%性能潜力
Windows 11终极优化指南:一键清理系统,释放51%性能潜力 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to decl…...
yuzu模拟器:在PC上完美运行Switch游戏的终极解决方案
yuzu模拟器:在PC上完美运行Switch游戏的终极解决方案 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu 想要在电脑上体验任天堂Switch游戏的魅力吗?yuzu模拟器作为目前最成熟的开源Switch模拟…...
动物森友会岛屿设计终极指南:用Happy Island Designer打造梦想岛屿
动物森友会岛屿设计终极指南:用Happy Island Designer打造梦想岛屿 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Anim…...
