认识并使用Shiro技术

认识并使用Shiro

  • 一、对Shiro的基本认知
    • 1、Shiro是什么?
    • 2、Shiro的核心组件是?
      • 2.1 Subject
      • 2.2 UsernamePasswordToken
      • 2.3 Realm(重点是:AuthorizingRealm用于授权、AuthenticatingRealm用于认证)
      • 2.4 SecurityManager
      • 2.5 ShiroFilterFactoryBean(重点)
  • 二、使用Shiro(通过Spring Boot整合Shiro)
    • 0、需求与思路
      • 0.1 需求
      • 0.2 思路
    • 1、通过脚手架快速创建Spring Boot项目
    • 2、构造db表,为用户登录做准备
    • 3、Spring Boot整合MySQL数据库
      • 3.1 添加依赖
      • 3.2 实现简单的DAO
        • 3.2.1 配置MySQL和mybatis-plus
        • 3.2.2 entity
        • 3.2.3 mapper
        • 3.2.4 单测
    • 4、实现Service层
    • 5、实现Controller层
      • 5.1 用户输入127.0.0.1:8080/main,服务端返回main.html
        • 5.1.1 实现
        • 5.1.2 效果
      • 5.2 同理,编写剩余的html
    • 5、重点:如何使用Shiro安全框架实现认证和授权?
      • 5.1 思路与实现
        • 5.1.1 定义xxxRealm
        • 5.1.2 定义ShiroConfig
            • 5.1.2.1 ShiroFilterFactoryBean (设置过滤器)
            • 5.1.2.2 过滤效果
            • 5.1.2.2 不想用官方的login.jsp来登录,怎么办?
        • 5.1.3 登录(认证)
          • 5.1.3.1 实现
          • 5.1.3.1 效果
        • 5.1.4 授权
      • 5.2 补充:登出
        • 5.2.1 修改index.html
        • 5.2.2 修改UserContoller.java
        • 5.2.3 效果
    • 6、Shiro整合Thymeleaf
      • 6.1 pom.xml中引入依赖
      • 6.2 提供ShiroDialect组件
      • 6.3 修改index.html
      • 6.4 效果
  • 三、[学习资料](https://www.bilibili.com/video/BV16C4y187S9/?p=1&vd_source=4e39b07bacf3530cded08060a2567e22)

一、对Shiro的基本认知

1、Shiro是什么?

  • Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. 【Apache Shiro是一个强大且易用的Java安全框架,它用于认证、授权、加密、对话管理。】官方文档

咱目前主要关注如何通过Shiro实现认证、授权和对话管理。

  • Spring MVC通过DispachServlet来控制请求(/xxx/yyy)路由到xxxController中的哪个方法。类似地,Apache Shiro的核心通过Filter来实现。 先将请求拦截,然后判断是否要认证(要的话,就让用户输入用户名和密码)、是否需要权限(有权限才能访问)。

2、Shiro的核心组件是?

2.1 Subject

  • Subject是安全领域的抽象概念,暂且可以简单理解为当前用户。

官方文档:实际上,我们想把它称为 “User”,因为这样 “更合理”,但我们决定不这么做:太多应用程序的现有 API 已经有了自己的 User 类/框架,我们不想与它们发生冲突。【但实际上叫Subject,依然会有冲突:)】

  • 服务端收到一个请求,xxxController中的对应方法会来处理。
// 当前用户,在整个Shiro框架运作的过程中,通过拿到subject就能拿到用户信息
Subject subject = SecurityUtils.getSubject();

2.2 UsernamePasswordToken

  • 见名知意,封装用户的username和password。
subject.login(new UsernamePasswordToken(username, password));

2.3 Realm(重点是:AuthorizingRealm用于授权、AuthenticatingRealm用于认证)

  • Shiro安全框架为了实现认证和授权,定义了2个抽象方法:
// AuthorizingRealm是授权Realm
public abstract class AuthorizingRealm extends AuthenticatingRealm implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware {......protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1);......
}
// AuthenticatingRealm是认证Realm
public abstract class AuthenticatingRealm extends CachingRealm implements Initializable {......protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
}
  • 很显然,这就需要用户去定义xxxRealm,并实现这两个抽象方法。

2.4 SecurityManager

  • 将自定义的xxxRealm组件交给DefaultWebSecurityManager,从而实现认证和授权。

2.5 ShiroFilterFactoryBean(重点)

  • 拦截请求,做一系列处理。例如,某请求要获取xxx.html页面,前提是先登录,那么就跳转到登录页面。

要让Shiro框架运转起来,先要定义出需要的组件,然后按要求组装起来,这就需要ShiroConfig.java。详见:5、重点:如何使用Shiro安全框架实现认证和授权?

二、使用Shiro(通过Spring Boot整合Shiro)

0、需求与思路

0.1 需求

  • 假设我们的网站有4个页面,分别是index.html(首页)、main.html、manage.html、administrator.html
  • 并且,我们需要对用户的访问进行限制:
    (1)用户必须登录才能访问main.html
    (2)用户必须拥有manage权限才能访问manage.html
    (3)用户必须拥有administrator角色才能访问administrator.html

0.2 思路

  • 首先,用户登录时,会给服务端传递username和password信息。服务端拿到这些信息后,就要校验username和password(和当初注册时,落入db表的username、password进行比对)。这就要用到Shiro提供的认证服务。
  • 认证完成后,用户顺利登录咱们的网站,接下来,他会去访问一些页面,而用户能不能访问,就要看用户具有哪些权限以及何种角色。这就要用到Shiro提供的授权服务。例如,授权manage.html页面,要求“用户必须拥有manage权限才能访问manage.html”。

开干吧!

1、通过脚手架快速创建Spring Boot项目

在这里插入图片描述
在这里插入图片描述

  • 添加shiro依赖:
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.7.1</version>
</dependency>

2、构造db表,为用户登录做准备

这里假设db表里面已经有一些用户信息了,当用户登录时,会将传入的username和password和db表里的信息进行比对。

  • 利用IDEA的Database连一下本地的MySQL
    在这里插入图片描述
    在这里插入图片描述
  • 连上以后,咱先新建一个database:CREATE DATABASE learn_shiro_mysql;
  • 使用该database,并新建User表:
use learn_shiro_mysql;
CREATE TABLE User (id INT PRIMARY KEY,username VARCHAR(32),password VARCHAR(64),permission VARCHAR(32),role VARCHAR(32)
);
  • 插入3条记录:
INSERT INTO User (id, username, password)
VALUES (1, '张飞', '123');INSERT INTO User (id, username, password, permission)
VALUES (2, '关羽', '456', 'manage');INSERT INTO User (id, username, password, permission, role)
VALUES (3, '刘备', '789', 'manage', 'administrato`在这里插入代码片`r');
  • 查看db表:
    在这里插入图片描述
  • 这张表的设计是不合理的。原因在于,一个用户可能拥有多个permission,即username和permission不是一对一的关系,不适合放一张表里。
  • 但本文重点在于“认识并使用Shiro技术”,所以暂且不在db表的设计上花费功夫。

3、Spring Boot整合MySQL数据库

3.1 添加依赖

<!-- MySQL驱动依赖 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency><!-- mybatis-plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version>
</dependency>

引入了DAO层框架:mybatis-plus

3.2 实现简单的DAO

3.2.1 配置MySQL和mybatis-plus
# 数据库配置
spring:datasource:# Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'.driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/learn_shiro_mysqlusername: rootpassword: xxx# mybatis-plus配置
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

learn_shiro_mysql是上面建好的database。

3.2.2 entity

与User表一一对应

@Data
@TableName("User")
public class User {private Integer id;private String username;private String password;private String permission;private String role;
}
3.2.3 mapper

通过mybatis-plus进行增删改查

/*** 不添加@Repository注解,当通过@Autowired注入时:<br>* <p>*    @Autowired <br>*    private UserMapper userMapper; <br>* </p>* IDEA会给userMapper打上红色下划线,提示:Could not autowire. No beans of 'UserMapper' type found. <br>* 这是因为UserMapper是接口,不能被实例化。但实际上,运行时会生成一个代理对象,代理对象会继承UserMapper接口,所以可以被@Autowired注入。<br>* 为了消除红色下划线,所以添加@Repository注解。* @Autowired* private UserMapper userMapper;*/@Repository
public interface UserMapper extends BaseMapper<User> {}
3.2.4 单测
@SpringBootTest
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelectAllUser() {userMapper.selectList(null).forEach(System.out::println);}}
User(id=1, username=张飞, password=123, permission=null, role=null)
User(id=2, username=关羽, password=456, permission=manage, role=null)
User(id=3, username=刘备, password=789, permission=manage, role=administrator)

4、实现Service层

  • 接口
public interface IUserService {User selectByUsername(String username);
}
  • 实现类
@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate UserMapper userMapper;@Overridepublic @Nullable User selectByUsername(String username) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username", username);return userMapper.selectOne(queryWrapper);}
}
  • 单测
@SpringBootTest
public class UserServiceImplTest {@Autowiredprivate IUserService userService;@Testpublic void testSelectByUsername() {String username = "刘备";System.out.println(userService.selectByUsername(username));}
}
User(id=3, username=刘备, password=789, permission=manage, role=administrator)

5、实现Controller层

5.1 用户输入127.0.0.1:8080/main,服务端返回main.html

5.1.1 实现
@Controller
public class UserController {@GetMapping("/{url}")public String redirect(@PathVariable String url) {// 例如,如果url的值为"main",就返回"main"视图return url;}
}
  • 在Spring MVC中,如果一个xxxController方法返回一个字符串,那么这个字符串通常被解析为一个视图名(View Name),Spring MVC会基于这个视图名来选择相应的视图(例如一个JSP页面或者一个HTML页面)进行渲染。
  • 在Spring Boot项目的"src/main/resources/templates"目录下创建一个"main.html"文件。这个文件就是要返回的Thymeleaf模板。
  • 当访问"/main"时,Spring MVC就会找到并渲染名为"main"的Thymeleaf模板文件(即"main.html"),并用它来渲染响应。
5.1.2 效果

在这里插入图片描述

  • 服务端有异常:org.thymeleaf.exceptions.TemplateInputException: Error resolving template [favicon.ico], template might not exist or might not be accessible by any of the configured Template Resolvers
  • 解决办法:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
</head>
<body>
<h1>I am main.html !</h1>
</body>
</html>

如上所述,补上<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
参考资料

5.2 同理,编写剩余的html

  • manage.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
</head>
<body><h1>I am manage.html !</h1>
</body>
</html>
  • administrator.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
</head>
<body><h1>I am administrator.html !</h1>
</body>
</html>
  • index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
</head>
<body><h1>I am index.html !</h1><a href="/main">main</a> | <a href="/manage">manage</a> | <a href="/administrator">administrator</a></body>
</html>

每个html中都要补上<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>,着实很离谱。

// 其实还可以这么做:
@GetMapping("favicon.ico")
@ResponseBody
void favicon() {// 方法体为空即可
}

当然了,正常情况下, 是会提供resources/favicon.ico。所以,不如去网上找一个favicon.ico。

5、重点:如何使用Shiro安全框架实现认证和授权?

目前,用户没有登录,便可以访问上述所有html,这显然是不安全的。因此,我们要使用Shiro技术来认证和授权。

5.1 思路与实现

  • 我理解,任何框架的使用思路都是,主流程交给框架,配置交给开发者。
5.1.1 定义xxxRealm
  • Shiro安全框架为了实现认证和授权,定义了2个抽象方法:
// AuthorizingRealm是授权Realm
public abstract class AuthorizingRealm extends AuthenticatingRealm implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware {......protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1);......
}
// AuthenticatingRealm是认证Realm
public abstract class AuthenticatingRealm extends CachingRealm implements Initializable {......protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException;
}
  • 很显然,这就需要用户去定义xxxRealm,并实现这两个抽象方法。
public class UserRealm extends AuthorizingRealm {/*** 授权* @param principalCollection* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {// 暂时 return null;return null;}/*** 认证,即校验用户的用户名和密码* @param authenticationToken* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {// 暂时 return null;return null;}
}
  • 定义好了UserRealm,Shiro怎么感知到呢?–> 当然是配置UserRealm啊,有Spring的帮助下,我们靠ShiroConfig来配置。
5.1.2 定义ShiroConfig
@Configuration
public class ShiroConfig {@Beanpublic UserRealm userRealm() {return new UserRealm();}@Beanpublic DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();defaultWebSecurityManager.setRealm(userRealm);return defaultWebSecurityManager;}@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}
}
5.1.2.1 ShiroFilterFactoryBean (设置过滤器)
  • 满足需求的代码:
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);// 设置过滤器Map<String, String> filterChainDefinitionMap = new HashMap<>();filterChainDefinitionMap.put("/main", "authc");filterChainDefinitionMap.put("/manage", "perms[manage]");filterChainDefinitionMap.put("/administrator", "role[administrator]");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;
}
  • 理论补充:
    (1)认证过滤器:
    1)anon: 无需认证
    2)authc: 必须认证
    3)authcBasic: 需要通过HTTP Basic认证
    4)user: 只要曾经被Shiro记录即可,比如:记住我

    (2)授权过滤器
    1)perms: 必须拥有某个权限才能访问
    2)roles: 必须拥有某个角色才能访问
    3)port: 请求的端口必须是指定值才可以
    4)rest: 请求必须基于RESTful (POST、PUT、GET、DELETE)
    5)ssl: 必须是安全的URL请求(协议HTTPS)

5.1.2.2 过滤效果

在这里插入图片描述

不登录,就没法看有限制的页面了!

5.1.2.2 不想用官方的login.jsp来登录,怎么办?
  • 设置登录页面
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {......// 设置登录页面shiroFilterFactoryBean.setLoginUrl("/login");......
}
  • 提供login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><form action="/login" method="post"><input type="text" name="username" placeholder="username"><input type="password" name="password" placeholder="password"><input type="submit" value="login"></form>
</body>
</html>
  • 效果:
    在这里插入图片描述
5.1.3 登录(认证)
5.1.3.1 实现
  • Controller层
@PostMapping("/login")
public String login(String username, String password, Model model) {// 将用户登录的认证过程交给ShiroSubject subject = SecurityUtils.getSubject();try {subject.login(new UsernamePasswordToken(username, password));return "index";} catch (UnknownAccountException | IncorrectCredentialsException e) {// 重新返回登录页面model.addAttribute("error", "用户名不存在 或者 密码错误");return "login";} catch (Exception e) {// 重新返回登录页面model.addAttribute("error", "登录出错");return "login";}
}

使用Model对象将错误信息传递给前端显示。Model是Spring MVC中一个非常重要的对象,它封装了视图显示所需要的数据,在视图中可以很方便的取出Model中的数据。

  • 完善“5.1.1 定义xxxRealm”中的UserRealm类的doGetAuthenticationInfo方法
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {if (authenticationToken instanceof UsernamePasswordToken) {UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;User user = userService.selectByUsername(upToken.getUsername());if (user != null) {return new SimpleAuthenticationInfo(user, user.getPassword(), getName());}}return null;}

当执行 subject.login(new UsernamePasswordToken(username, password));时,会执行到doGetAuthenticationInfo方法中。

根据用户传入的username去查User表,
(1)没查到,返回null
(2)查到了,但用户传入的密码和User表中的密码不匹配,抛异常
(3)查到了,密码也匹配上了,登录成功

5.1.3.1 效果
  • 登录失败
    在这里插入图片描述
  • 登录成功后,点击“manage”
    在这里插入图片描述

接下来,说明还未授权,接下来就要准备授权了。

  • 这里先做一下优化,当未授权时,返回一个用户易读的信息。

(1)ShiroConfig.java

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {......// 设置未授权页面shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");return shiroFilterFactoryBean;
}

(2)UserController

@GetMapping("/unauthorized")
@ResponseBody
public String unauthorized() {return "您没有权限访问该页面!";
}

(3)效果
在这里插入图片描述

5.1.4 授权
  • 实现:
/*** 授权* @param principalCollection* @return*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {Subject currentUser = SecurityUtils.getSubject();Object tmpUser = currentUser.getPrincipal();if (tmpUser instanceof User) {User user = (User) tmpUser;// 角色Set<String> roles = new HashSet<>();roles.add(user.getRole());// 权限Set<String> perms = new HashSet<>();perms.add(user.getPermission());SimpleAuthorizationInfo saInfo = new SimpleAuthorizationInfo();saInfo.setRoles(roles);saInfo.setStringPermissions(perms);return saInfo;} else {return null;}
}

5.2 补充:登出

(1)登录时,我需要知道当前页面是谁在访问,此需求可以简化为:登录后,显示“欢迎xxx回家~”
(2)然后,要提供登出的按钮。

5.2.1 修改index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>I am index.html !</h1><div th:if="${session.user != null}"><p>Welcome, <span th:text="${session.user.username}"></span>!</p></div><a href="/main">main</a> | <a href="/manage">manage</a> | <a href="/administrator">administrator</a><div><a href="/logout">logout</a></div>
</body>
</html>

IDEA会在user下标注黄色波浪线,看着真难受啊~

5.2.2 修改UserContoller.java
@PostMapping("/login")
public String login(String username, String password, Model model) {// 将用户登录的认证过程交给ShiroSubject subject = SecurityUtils.getSubject();try {subject.login(new UsernamePasswordToken(username, password));subject.getSession().setAttribute("user", subject.getPrincipal());return "index";} catch (UnknownAccountException | IncorrectCredentialsException e) {...} catch (Exception e) {...}
}@GetMapping("/logout")
public String logout() {// 退出登录SecurityUtils.getSubject().logout();return "login";
}

(1)当执行subject.login(new UsernamePasswordToken(username, password));时,会执行UserRealm类的doGetAuthenticationInfo方法,如果登录成功,那么return new SimpleAuthenticationInfo(user, user.getPassword(), getName());此时,user赋予了principal。
(2)因此subject.getPrincipal()取出的便是user。

5.2.3 效果

在这里插入图片描述

6、Shiro整合Thymeleaf

刘备拥有main.html、manage.html、administrator.html的权限,所以可以看到3个main、manage、administrator的链接,那么对于没有权限的人,咱希望他不要看到对应的链接。

6.1 pom.xml中引入依赖

<!-- Thymeleaf整合Shiro -->
<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.1.0</version>
</dependency>

6.2 提供ShiroDialect组件

@Bean
public ShiroDialect shiroDialect() {return new ShiroDialect();
}

6.3 修改index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>I am index.html !</h1><div th:if="${session.user != null}"><p>Welcome, <span th:text="${session.user.username}"></span>! <a href="/logout">logout</a></p></div><a href="/main">main</a><div shiro:hasPermission="manage"><a href="/manage">manage</a></div><div shiro:hasRole="administrator"><a href="/administrator">administrator</a></div>
</body>
</html>

6.4 效果

在这里插入图片描述

三、学习资料

讲得真不错~ 感谢老师~

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

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

相关文章

OpenCV-Python(49):图像去噪

目标 学习使用非局部平均值去噪算法去除图像中的噪音学习函数cv2.fastNlMeansDenoising()、cv2.fastNlMeansDenoisingColored等 原理 在前面的章节中我们已经学习了很多图像平滑技术&#xff0c;比如高斯平滑、中值平滑等。当噪声比较小时&#xff0c;这些技术的效果都是很好…

基数(桶)排序

目录 基数排序 实现步骤 完整代码 基数排序 核心思想&#xff1a;统计原数组中某个元素在该数组中出现的次数 优点&#xff1a;效率极高&#xff0c;时间复杂度为O&#xff08;aN countN(范围)&#xff09; 缺点&#xff1a;不适合分散的数据&#xff0c;更适合集中数据…

[全连接神经网络]Transformer代餐,用MLP构建图像处理网络

一、MLP-Mixer 使用纯MLP处理图像信息&#xff0c;其原理类似vit&#xff0c;将图片进行分块(patch)后展平(fallten)&#xff0c;然后输入到MLP中。理论上MLP等价于1x1卷积&#xff0c;但实际上1x1卷积仅能结合通道信息而不能结合空间信息。根据结合的信息不同分为channel-mixi…

知识图谱KG+大模型LLM

LLM-based KG KnowLM OpenSPGKG-based RAG 基本原理 从query出发的语义解析 pre-LLM方法 思想&#xff1a;直接将问题解析为对应的逻辑表达式&#xff0c;然后到知识图谱中查询。 方法&#xff1a;通常包含逻辑表达式、语义解析算法、语义解析模型训练三部分。一般步骤是将问句…

【Kafka】Linux本地和Docker安装Kafka

目录 Linux本地安装kafkajava环境配置Zookeeper的安装配置Kafka的安装与配置生产与消费 Docker安装kafkaZookeeper安装Kafka安装 Linux本地安装kafka java环境配置 1、上传jdk-8u261-linux-x64.rpm到服务器并安装&#xff1a; rpm -ivh jdk-8u261-linux-x64.rpm2、配置环境变…

深度学习(4)--Keras实战

一.Keras基础概念 1.1.Keras是什么 Keras是深度学习中的一个神经网络框架&#xff0c;是一个高级神经网络API&#xff0c;用Python编写&#xff0c;可以在TensorFlow&#xff0c;CNTK或Theano之上运行。 Keras优点&#xff1a; (1). 允许简单快速的原型设计&#xff08;用户…

【C++】用wxWidgets实现多文档窗体程序

一、基本步骤和示例代码 在wxWidgets中&#xff0c;要实现多文档窗体程序&#xff0c;通常会使用wxMDIParentFrame和wxMDIChildFrame类来创建一种标准的MDI&#xff08;多文档接口&#xff09;应用。以下是基本步骤和示例代码&#xff0c;演示如何使用wxWidgets创建多文档界面…

Pycharm详细安装 配置教程

继上次安装完Anaconda之后&#xff0c;现在更新最新版本的pycharm的安装和使用教程~~~ Anaconda&#xff1a;是一个开源的Python发行版本&#xff0c;其中包含了conda、Python等180多个科学包及其依赖项。【Anaconda和Pycharm详细安装 配置教程_anconda安装时clear the packag…

SpringMVC简介和SpringMVC的HelloWorld

一、SpringMVC简介 1、什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体类Bean&#xff1a…

web渗透安全学习笔记:2、HTML基础知识

目录 前言 HTML的标题 段落链接与插入图片 HTML元素 HTML属性 HTML头部 HTML与CSS HTML与JavaScript 表格与列表 HTML区块 布局 HTML表单 HTML与数据库 音频与视频 HTML事件 前言 HTML的标题 <!DOCTYPE html> <html> <head> <meta chars…

yum配置文件及NFS共享

一 yum配置文件及命令 1 /etc/yum.conf //主配置文件 2 /etc/yum.repos.d/*.repo //yum仓库文件位置 写错一个字母就不行&#xff0c;可以ping www.google.com 测试网络 3 /var/log/yum.log //日志文件 二 yum命令 1 [rootlocalhost ~…

分布式锁的产生以及使用

日常开发中&#xff0c;针对一些需要锁定资源的操作&#xff0c;例如商城的订单超卖问题、订单重复提交问题等。 都是为了解决在资源有限的情况限制客户端的访问&#xff0c;对应的是限流。 单节点锁问题 目前针对这种锁资源的情况采取的往往是互斥锁&#xff0c;例如 java 里…

【LeetCode: 295. 数据流的中位数 + 堆】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

list列表可编辑状态

有时候list需要修改或选择属性,mfc自带的只能显示内容,基本上是不可以修改,为了实现这个功能需求,需要完成一下步骤转换. 第一步记录选择的单元格. 第二步创建一个编辑框CComboBox对象, 设置字体,窗口属性. 第三步获取选中单元格的位置信息. 第四步获取单元格内容信息. 第五步…

Leetcode3005. 最大频率元素计数

Every day a Leetcode 题目来源&#xff1a;3005. 最大频率元素计数 解法1&#xff1a;遍历 哈希 遍历数组 nums&#xff0c;统计各元素 num 的出现次数&#xff0c;存储在哈希表 cnt 中。 初始化 sum 0&#xff0c;max_freq 0。 遍历哈希表 cnt&#xff1a; 如果当前…

v34.运算符的优先级 和 结合性

1.优先级 优先级高的运算符会首先被评估。 2.结合性 当运算符的优先级相同时&#xff0c;结合性就会发挥作用。 3.优先级很重要 &#xff08;&#xff09;的优先级大于&#xff0c;所以操作数fun属于&#xff08;&#xff09; 而不是 &#xff0c;所以这个表达式看做是将函数…

基于蒙特卡洛模拟的家用电动汽车充电负荷预测(MATLAB实现)

采用蒙特卡洛模拟法&#xff0c;对家用电动汽车充电负荷进行预测&#xff0c;电动汽车分为快、中、慢三种充电功率&#xff0c;且分为一天一充、一天两充、一天三充三种类型。全部MATLAB代码在下方给出&#xff0c;可以直接运行。 %%%%%%%%%%%%%%%%%%%%%%%%输入电动汽车相关原…

Spark读取kafka(流式和批数据)

spark读取kafka&#xff08;批数据处理&#xff09; # 按照偏移量读取kafka数据 from pyspark.sql import SparkSessionss SparkSession.builder.getOrCreate()# spark读取kafka options {# 写kafka配置信息# 指定kafka的连接的broker服务节点信息kafka.bootstrap.servers: n…

集美大学“第15届蓝桥杯大赛(软件类)“校内选拔赛 D矩阵选数

经典的状态压缩DP int dp[15][(1<<14)10]; int a[15][15]; void solve() {//dp[i][st]考虑到了第i行 并且当前考虑完第i行以后的选择状态是st的所有方案中的最大值for(int i1;i<13;i)for(int j1;j<13;j)cin>>a[i][j];for(int i1;i<13;i){for(int j0;j<…

宝塔 ftp 服务器发回了不可路由的地址/读取目录列表失败

ftp连接不上&#xff1a; 1.注意内网IP和外网IP 2.检查ftp服务是否启动 &#xff08;面板首页即可看到&#xff09; 3.检查防火墙20端口 ftp 21端口及被动端口39000 - 40000是否放行 &#xff08;如是腾讯云/阿里云等还需检查安全组&#xff09; 4.是否主动/被动模式都不能连接…