Shiro概述

news2024/11/23 5:01:54

文章目录

  • 1.权限的管理
    • 1.1 什么是权限管理
    • 1.2 什么是身份认证
    • 1.3 什么是授权
  • 2.Shiro概述
    • 2.1 什么是Shiro
    • 2.2 Shiro 与 SpringSecurity 的对比
    • 2.3 基本功能
  • 3.shiro的核心架构
  • 4.shiro中的认证
    • 4.1 认证
    • 4.2 shiro中认证的关键对象
    • 4.3 身份认证流程
    • 4.4.登录认证实例
    • 4.5 自定义Realm
  • 5.角色、授权
    • 5.1 授权概念
    • 5.2 授权方式
    • 5.3 授权流程
    • 5.4 授权实例
  • 6.Shiro 加密
    • 6.1 Shiro自定义登录认证(带加密的)
  • 7.多个 realm 的认证策略设置
    • 7.1 多个realm实现原理
    • 7.2 多个代码实现
  • 8. remember me 功能
    • 8.2 1、基本流程
  • 9.授权、角色认证
    • 9.1 授权
    • 9.2 后端接口服务注解

1.权限的管理

1.1 什么是权限管理

(1)基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源。
(2)权限管理包括用户身份认证和授权两部分,简称认证授权。对于需要访问控制的资源用户首先经过身份认证,认证通过后用户具有该资源的访问权限方可访问。

1.2 什么是身份认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。对于采用指纹等系统,则出示指纹;对于硬件Key等刷卡系统,则需要刷卡。

1.3 什么是授权

授权,即访问控制,控制谁能访问哪些资源。主体进行身份认证后需要分配权限才可访问系统的资源,对于某些资源没有权限是无法访问的

2.Shiro概述

2.1 什么是Shiro

(1)Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。 Shiro 可以完
成:认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松
地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
(2)官网: https://shiro.apache.org/

2.2 Shiro 与 SpringSecurity 的对比

①Spring Security 基于 Spring 开发,项目若使用 Spring 作为基础,配合 Spring
Security 做权限更加方便,而 Shiro 需要和 Spring 进行整合开发;
②Spring Security 功能比 Shiro 更加丰富些,例如安全维护方面;
③Spring Security 社区资源相对比 Shiro 更加丰富;
④Shiro 的配置和使用比较简单, Spring Security 上手复杂些;
⑤Shiro 依赖性低,不需要任何框架和容器,可以独立运行;Spring Security 依赖Spring 容器;
⑥shiro 不仅仅可以使用在 web 中,它还可以工作在任何应用环境中。在集群会话时 Shiro最重要的一个
好处或许就是它的会话是独立于容器的。

2.3 基本功能

在这里插入图片描述
(1) Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
(2) Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即
判断用 户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证
某个用户 对某个资源是否具有某个权限;
(3) Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的
所有 信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
(4) Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存
储;
(5) Web Support: Web 支持,可以非常容易的集成到 Web 环境;
(6) Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这
样可 以提高效率;
(7) Concurrency: Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线
程,能把权限自动传播过去;
(8) Testing:提供测试支持;
(9) Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
(10)Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用
登 录了

3.shiro的核心架构

在这里插入图片描述
(1)Subject
Subject即主体,外部应用与subject进行交互,subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。 Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权
(2)SecurityManager
①SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。通过 SecurityManager可以完成subject的认证、授权等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。
②SecurityManager是一个接口,继承了Authenticator, Authorizer, SessionManager这三个接口。
(3)Authenticator
Authenticator即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。
(4)Authorizer
Authorizer即授权器,用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
(5)Realm
Realm即领域,相当于datasource数据源,securityManager进行安全认证需要通过Realm获取用户权限数据,比如:如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息。
​ 注意:不要把realm理解成只是从数据源取数据,在realm中还有认证授权校验的相关的代码。
(6)SessionManager
sessionManager即会话管理,shiro框架定义了一套会话管理,它不依赖web容器的session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性可使它实现单点登录。
(7)SessionDAO
SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session存储到数据库,可以通过jdbc将会话存储到数据库。
(8) CacheManager
CacheManager即缓存管理,将用户权限数据存储在缓存,这样可以提高性能。
(9)Cryptography
​ Cryptography即密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

4.shiro中的认证

4.1 认证

身份认证,就是判断一个用户是否为合法用户的处理过程。最常用的简单身份认证方式是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确。

4.2 shiro中认证的关键对象

(1)Subject:主体
访问系统的用户,主体可以是用户、程序等,进行认证的都称为主体;
(2)Principal:身份信息
是主体(subject)进行身份认证的标识,标识必须具有唯一性,如用户名、手机号、邮箱地址等,一个主体可以有多个身份,但是必须有一个主身份(Primary Principal)。
(3)credential:凭证信息
是只有主体自己知道的安全信息,如密码、证书等。

4.3 身份认证流程

在这里插入图片描述
(1)首先调用 Subject.login(token) 进行登录,其会自动委托给 SecurityManager
(2)SecurityManager 负责真正的身份验证逻辑;它会委托给 Authenticator 进行身份
验证;
(3)Authenticator 才是真正的身份验证者, Shiro API 中核心的身份 认证入口点,此
处可以自定义插入自己的实现;
(4)Authenticator 可能会委托给相应的 AuthenticationStrategy 进 行多 Realm 身份
验证,默认 ModularRealmAuthenticator 会调用 AuthenticationStrategy 进行多 Realm
身份验证;
(5)Authenticator 会在shiro中会把身份信息以及凭证信息打包成一个令牌即Token 传入
Realm,从 Realm 获取 身份验证信息,如果没有返回/抛出异常表示身份验证失败了。
此处 可以配置多个Realm,将按照相应的顺序及策略进行访问

4.4.登录认证实例

(1)环境准备

<dependencies>
	<dependency>
		<groupId>org.apache.shiro</groupId>
		<artifactId>shiro-core</artifactId>
		<version>1.9.0</version>
	</dependency>
</dependencies>

(2)INI 文件
Shiro 获取权限相关信息可以通过数据库获取,也可以通过 ini 配置文件获取
在这里插入图片描述
(3) 开发认证代码

public class TestAuthenticator {
    public static void main(String[] args) {
        //1.创建securityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        defaultSecurityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        //2.将安装工具类中设置默认安全管理器
        SecurityUtils.setSecurityManager(defaultSecurityManager);
        //3.获取主体对象
        Subject subject = SecurityUtils.getSubject();
        //4.创建token令牌
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "13");
        try {
        //5.用户登录
            subject.login(token);
            System.out.println("登录成功~~");
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误!!");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码错误!!!");
        }
    }
}

①DisabledAccountException(帐号被禁用)
②LockedAccountException(帐号被锁定)
③ExcessiveAttemptsException(登录失败次数过多)
④ExpiredCredentialsException(凭证过期)

4.5 自定义Realm

(1)上边的程序使用的是Shiro自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。
(2)创建自定义的 Realm 类,
方式①:继承 org.apache.shiro.realm.AuthenticatingRealm类,
方式②:继承AuthorizingRealm (AuthorizingRealm extends AuthenticatingRealm)
重写方法

/**
 * 自定义realm
 */
public class CustomerRealm extends AuthorizingRealm {
    //认证方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }
    //授权方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if("xiaochen".equals(principal)){
            return new SimpleAuthenticationInfo(principal,"123",this.getName());
        }
        return null;
    }
}

(4)使用自定义Realm
方式①:设置为自定义realm获取认证数据

        //创建securityManager
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //IniRealm realm = new IniRealm("classpath:shiro.ini");
        //设置为自定义realm获取认证数据
        defaultSecurityManager.setRealm(new CustomerRealm());

方式二:在shiro.ini中添加配置信息

[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.shiro.realm.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm
[users]
zhangsan=7174f64b13022acd3c56e2781e098a5f,role1,role2
lisi=l4
[roles]
role1=user:insert,user:select

5.角色、授权

5.1 授权概念

(1)授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作等)。
在授权中需了解的几个关键对象:主体( Subject)、资源( Resource)、权限( Permission)、
角色( Role)。
(2) 主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权 后
才允许访问相应的资源。
(3)资源(Resource): 在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑某些
数据、访问某个业务方法、打印文本等等都是资源。用户只有授权后才能访问。
(4)权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户
有没有操作某个资源的权力。 即权限表示在应用中用户能不能访问某个资源,如:访问用 户
列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控 制)等。
权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许。
( 5) Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权
限, 即实例级别的)
( 6) 角色(Role): 权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可
以拥有 一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、 CTO、开发工
程师等 都是角色,不同的角色拥有一组不同的权限

5.2 授权方式

(1)编程式:通过写if/else 授权代码块完成
在这里插入图片描述
( 2) 注解式:通过在执行的Java方法上放置相应的注解完成,没有权限将抛出相应的异常
在这里插入图片描述

(3) JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成
在这里插入图片描述

5.3 授权流程

(1)首先调用Subject.isPermitted*/hasRole*接口,其会委托给SecurityManager,而
SecurityManager接着会委托给 Authorizer;
(2)Authorizer是真正的授权者,如果调用如isPermitted(“user:view”),其首先会通过
PermissionResolver把字符串转换成相应的Permission实例;
(3)在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入
的角色/权限;
(4)Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托
给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted*/hasRole* 会返回true,
否则返回false表示授权失败

在这里插入图片描述

5.4 授权实例

(1) 获取角色信息
①给shiro.ini增加角色配置
[users]
zhangsan=13,role1,role2
②给例子添加代码,通过hasRole()判断用户是否有指定角色

	 subject.login(token);
     System.out.println("登录成功");
	// 判断角色
     boolean hasRole = subject.hasRole("role1");
     System.out.println("是否拥有此角色"+hasRole);

(2)判断权限信息信息
①给shiro.ini增加权限配置
[users]
zhangsan=13,role1,role2
[roles]
role1=user:insert,user:select
②给例子添加代码,判断用户是否有指定权限

 //判断权限
 boolean isPermitted = subject.isPermitted("user:insert");
 System.out.println("是否拥有此权限: "+isPermitted);
//也可以用 checkPermission 方法,但没有返回值,没权限会抛 AuthenticationException
// subject.checkPermission("user:select");

6.Shiro 加密

(1)实际系统开发中,一些敏感信息需要进行加密,比如说用户的密码。 Shiro 内嵌很多
常用的加密算法,比如 MD5 加密。 Shiro 可以很简单的使用信息加密。
(2)使用Shiro进行密码加密

public class ShiroMD5 {
	public static void main(String[] args) {
		//密码明文
		String password = "z3";
		//使用 md5 加密
		Md5Hash md5Hash = new Md5Hash(password);
		System.out.println("md5 加密: "+md5Hash.toHex());
		//带盐的 md5 加密,盐就是在密码明文后拼接新字符串,然后再进行加密
		Md5Hash md5Hash2 = new Md5Hash(password,"salt");
		System.out.println("md5 带盐加密: "+md5Hash2.toHex());
		//为了保证安全,避免被破解还可以多次迭代加密,保证数据安全
		Md5Hash md5Hash3 = new Md5Hash(password,"salt",3);
		System.out.println("md5 带盐三次加密: "+md5Hash3.toHex());
		//使用父类实现加密(MD5是加密方式)
		SimpleHash simpleHash = new SimpleHash("MD5",password,"salt",3);
		System.out.println("父类带盐三次加密: "+simpleHash.toHex());
} }

6.1 Shiro自定义登录认证(带加密的)

Shiro 默认的登录认证是不带加密的,如果想要实现加密认证需要自定义登录认证,需要自定义 Realm。
(1)自定义登录认证

public class MyRealm extends AuthenticatingRealm {
	//自定义的登录认证方法, Shiro 的 login 方法底层会调用该类的认证方法完成登录认证
	//想要配置自定义的 realm 生效,要在ini 文件中配置,或 Springboot 中配置
	//该方法只是获取进行对比的信息,认证逻辑还是按照 Shiro 的底层认证逻辑完成认证
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)throws AuthenticationException {
	//1 获取身份信息
	String principal = authenticationToken.getPrincipal().toString();
	//2 获取凭证信息
	String password = new String((char[])authenticationToken.getCredentials());
	System.out.println("认证用户信息:"+principal+"---"+password);
	//3 获取数据库中存储的用户信息
	if(principal.equals("zhangsan")){
		//3.1 数据库中存储的加盐 3 次迭代的密码
		String pwdInfo = "7174f64b13022acd3c56e2781e098a5f";
		//3.2 创建封装了校验逻辑的对象,把要比较的数据给该对象
		AuthenticationInfo info = new SimpleAuthenticationInfo(
			authenticationToken.getPrincipal(),//身份信息
			pwdInfo,	//密码信息
			ByteSource.Util.bytes("salt"), //盐信息 
			authenticationToken.getPrincipal().toString()); //身份信息对应的字符串
		return info;
	}
	return null;
	}

(2)在shiro.ini中添加配置信息

[main]
md5CredentialsMatcher=org.apache.shiro.authc.credential.Md5CredentialsMatcher
md5CredentialsMatcher.hashIterations=3
myrealm=com.shiro.realm.MyRealm
myrealm.credentialsMatcher=$md5CredentialsMatcher
securityManager.realms=$myrealm
[users]
zhangsan=7174f64b13022acd3c56e2781e098a5f,role1,role2
lisi=l4
[roles]
role1=user:insert,user:select

7.多个 realm 的认证策略设置

7.1 多个realm实现原理

(1)当应用程序配置多个 Realm 时,例如:用户名密码校验、手机号验证码校验等等。Shiro 的 ModularRealmAuthenticator会使用内部的 AuthenticationStrategy 组件判断认证是成功还是失败。
(2)AuthenticationStrategy 是一个无状态的组件,它在身份验证尝试中被询问 4 次(这4 次交互
所需的任何必要的状态将被作为方法参数):
①在所有 Realm 被调用之前
②在调用 Realm 的 getAuthenticationInfo 方法之前
③在调用 Realm 的 getAuthenticationInfo 方法之后
④在所有 Realm 被调用之后
(3)认证策略的另外一项工作就是聚合所有 Realm 的结果信息封装至一个
AuthenticationInfo 实例中,并将此信息返回,以此作为 Subject 的身份信息。
(4)Shiro 中定义了 3 种认证策略的实现:
在这里插入图片描述
ModularRealmAuthenticator 内置的认证策略默认实现是AtLeastOneSuccessfulStrategy 方式。可以通过配置修改策略

7.2 多个代码实现

//配置 SecurityManager
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(){
	//1 创建 defaultWebSecurityManager 对象
	DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
	//2 创建认证对象,并设置认证策略
	ModularRealmAuthenticator modularRealmAuthenticator = new ModularRealmAuthenticator();
    modularRealmAuthenticator.setAuthenticationStrategy(new AllSuccessfulStrategy());
	defaultWebSecurityManager.setAuthenticator(modularRealmAuthenticator);
	//3 封装 myRealm 集合
	List<Realm> list = new ArrayList<>();
	list.add(myRealm);
	list.add(myRealm2);
	//4 将 myRealm 存入 defaultWebSecurityManager 对象
	defaultWebSecurityManager.setRealms(list);
	//5 返回
	return defaultWebSecurityManager;
}

8. remember me 功能

Shiro 提供了记住我(RememberMe)的功能,比如访问一些网站时,关闭了浏览器,
下次再打开时还是能记住你是谁, 下次访问时无需再登录即可访问。

8.2 1、基本流程

(1)首先在登录页面选中 RememberMe 然后登录成功;如果是浏览器登录,一般会
把 RememberMe 的 Cookie 写到客户端并保存下来;
(2)关闭浏览器再重新打开;会发现浏览器还是记住你的;
(3)访问一般的网页服务器端,仍然知道你是谁,且能正常访问;
(4)但是,如果我们访问电商平台时,如果要查看我的订单或进行支付时,此时还
是需要再进行身份认证的,以确保当前用户还是你。

9.授权、角色认证

9.1 授权

用户登录后, 需要验证是否具有指定角色指定权限。 Shiro也提供了方便的工具进行判断。这个工具
就是Realm的doGetAuthorizationInfo方法进行判断。触发权限判断的有两种方式:
(1) 在页面中通过shiro:属性判断
(2) 在接口服务中通过注解@Requires
进行判断

9.2 后端接口服务注解

通过给接口服务方法添加注解可以实现权限校验,可以加在控制器方法上,也可以加
在业务方法上,一般加在控制器方法上。常用注解如下:
(1) @RequiresAuthentication
验证用户是否登录,等同于方法subject.isAuthenticated()
(2) @RequiresUser
验证用户是否被记忆:
登录认证成功subject.isAuthenticated()为true
登录后被记忆subject.isRemembered()为true
(3) @RequiresGuest
验证是否是一个guest的请求,是否是游客的请求
此时subject.getPrincipal()为null
(4) @RequiresRoles
验证subject是否有相应角色,有角色访问方法,没有则会抛出异常
AuthorizationException。
例如: @RequiresRoles(“aRoleName”)
void someMethod();
只有subject有aRoleName角色才能访问方法someMethod()
(5) @RequiresPermissions
验证subject是否有相应权限,有权限访问方法,没有则会抛出异常AuthorizationException。
例如: @RequiresPermissions (“file:read”,”wite:aFile.txt”)
void someMethod();
subject必须同时含有file:read和wite:aFile.txt权限才能访问方法someMethod()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422453.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python标记数组的连通域

文章目录连通域标记structure参数操作连通域定位连通域连通域标记 通过label函数&#xff0c;可以对数组中的连通区域进行标注&#xff0c;效果如下 from scipy.ndimage import label import numpy as np a np.array([[0,0,1,1,0,0],[0,0,0,1,0,0],[1,1,0,0,1,0],[0,0,0,1,0…

虚拟机里安装ubuntu-23.04-beta-desktop-amd64,开启SSH(换源、备份),配置中文以及中文输入法

一、下载 官网 清华镜像站(推荐) 二、配置虚拟机 【自定义】 点击“下一步”&#xff0c;此处【默认】&#xff0c;再点击“下一步”。 点击“稍后安装操作系统”&#xff0c;再点击“下一步”。 点击“Linux(L)”&#xff0c;版本选择【Ubuntu 64 位】&#xff0c;再点击…

轻量级网页RSS阅读器selfoss

什么是 selfoss &#xff1f; selfoss 是一个多用途的 RSS 阅读器和提要聚合 Web 应用程序。它使您可以在一个地方轻松关注来自不同网站、社交网络和其他平台的更新。它是用 PHP 编写的&#xff0c;基本上可以让您在任何地方运行它。 安装 在群晖上以 Docker 方式安装。 在注…

【前沿技术】问答pk【ChatGPT Vs Notion AI Vs BAT AI 】

目录 写在前面 问题&#xff1a; 1 ChatGPT 1.1 截图 ​1.2 文字版 2 Notion AI 2.1 截图 2.2 文字版 3 BAT AI 3.1 截图 3.2 文字版 总结 序言 所有幸运和巧合的事&#xff0c;要么是上天注定&#xff0c;要么是一个人偷偷的在努力。 突发奇想&#xff0c;问三个…

机器学习---聚类算法

目录【写在前面】1、确认安装有scikit-learn库2、使用 make _ classification ()建立数据集3、使用模型进行分类头文件汇总亲和力传播聚合聚类BIRCH 聚类DBSCAN【本人的毕业设计系统中有用到】K-均值高斯混合模型【写在最后】【写在前面】 sklearn和scikit-learn&#xff1a; …

软件测试需要学什么

软件测试近些年也是比较热门的行业&#xff0c;薪资高、入门门槛低&#xff0c;让很多开发人员想纷纷加入软件开发这个行业&#xff0c;想要成为这一岗位的一员&#xff0c;想要进入软件测试行业&#xff0c;他们需要学习什么呢&#xff1f; 软件测试需要学习的还挺多的&#…

Flowable开源版和Flowable商业版有什么区别?

Flowable除了提供开源版本flowable-engine&#xff0c;它还提供了一系列基于Flowable引擎的快速、现代和完全可定制的企业产品&#xff08;商业收费&#xff09;&#xff1a;Flowable Work、Flowable Orchestrate和Flowable Engage。Flowable的开源版本和商业版本有什么区别&am…

【产线事故】分享生产线事故发生的一次OOM

文章目录前言OutOfMemoryError出现的原因常见堆内存溢出的几种情况现象分析Mybatis源码分析情景复现总结前言 继上次线上CPU出现了报警&#xff0c;这次服务又开始整活了&#xff0c;风平浪静了没几天&#xff0c;看生产日志服务的运行的时候&#xff0c;频繁的出现OutOfMemor…

接口自动化测试如何做?测试老鸟总结,接口测试数据构造大全......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 接口参数的数据获取…

Linux复习 / 线程相关----线程概念与控制 QA梳理

文章目录前言Q&A线程概念Q&#xff1a;线程和进程的区别&#xff1f;&#xff08;为什么要有线程&#xff0c;从进程的角度说明这个问题&#xff09;Q&#xff1a;Linux是如何设计线程的&#xff1f;Q&#xff1a;学习了线程后&#xff0c;你能说说进程和线程最大的区别是什…

博客系统(后端编程)

这里还是这四个页面: 博客列表页 博客详情页 登录页 博客编辑页 一、准备工作: 1.引入依赖 引入mysql,servlet,jackson的依赖,并且把之前的前端页面拷贝进去. 2.创建目录 并且把相关代码复制进去. 此时目录就完成了!!! 3.复制前端代码 直接ctrlv我们之前的前端代码到web…

目标检测YOLO系列-YOLOV7运行步骤(推理、训练全过程)

下载源代码&#xff1a;点击下载 进入项目根目录并执行以下命令安装requirements.txt中的相关依赖 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple官网下载权重yolov7.pt&#xff08;测试使用&#xff09;、yolov7-tiny.pt&#xff08;训练使用…

【C++】哈希表:开散列和闭散列

&#x1f4dd; 个人主页 &#xff1a;超人不会飞)&#x1f4d1; 本文收录专栏&#xff1a;《C的修行之路》&#x1f4ad; 如果本文对您有帮助&#xff0c;不妨点赞、收藏、关注支持博主&#xff0c;我们一起进步&#xff0c;共同成长&#xff01; 目录前言一、基于哈希表的两个…

Spring MVC请求处理流程分析

Spring MVC请求处理流程分析一 Spring MVC 请求处理流程二 Spring MVC 请求处理流程源码分析2.1架构图解2.2 重要时机点分析2.3核心步骤分析2.3.1 getHandler⽅法剖析2.3.2 getHandlerAdapter⽅法剖析2.3.3 ha.handle⽅法剖析2.3.4 processDispatchResult⽅法剖析三 Spring MVC…

Ruby2D总结

Ruby学习心得 学了几天&#xff0c;Ruby2D这个项目我差不多把教程里面的东西做完了&#xff0c;感觉还好&#xff0c;只要每天一有空的话就去做的话就可以快速做好一个项目&#xff0c;不过还是会有一点虚浮感&#xff0c;但学习也是一个不能拖的事情&#xff0c;所以为了平衡…

【SpringBoot2】SpringBoot运维实用篇

SpringBoot运维实用篇 YW-1.SpringBoot程序的打包与运行 ​ 刚开始做开发学习的小伙伴可能在有一个知识上面有错误的认知&#xff0c;我们天天写程序是在Idea下写的&#xff0c;运行也是在Idea下运行的。 ​ 但是实际开发完成后&#xff0c;我们的项目是不可能运行在自己的电…

Java——树的子结构

题目链接 牛客在线oj题——树的子结构 题目描述 输入两棵二叉树A&#xff0c;B&#xff0c;判断B是不是A的子结构。&#xff08;我们约定空树不是任意一个树的子结构&#xff09; 假如给定A为{8,8,7,9,2,#,#,#,#,4,7}&#xff0c;B为{8,9,2}&#xff0c;2个树的结构如下&am…

【C++】引用(上)【深度全面解析】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

stm32cubemx IAP升级(三)

stm32cubemx IAP升级- UARTDMA实现不定长收发数据 板卡&#xff1a;Nucleo-L412 平台&#xff1a;macbook pro 工具&#xff1a;vscode stm32cubemx stm32cubeProgramer cmake toolchain Stm32CubeMx的配置 选择开启一路串口并配置成DMA&#xff0c;并使能中断&#xff0c;配…

优思学院|质量改进必备技能:克罗斯比的14步骤全面解析

菲利普克罗斯比&#xff08;Philip Crosby&#xff09;是一位著名的质量管理专家&#xff0c;被誉为"零缺陷之父"、“现代质量运动之父”。他于1926年出生于美国俄亥俄州&#xff0c;曾在美国空军服役。后来他在ITT公司和马丁-马里埃塔公司等企业担任质量管理师和高级…