Shiro学习(三):shiro整合springboot

一、Shiro整合到Springboot步骤

1、准备SpringBoot 环境,这一步省略

2、引入Shiro 依赖

     因为是Web 项目,所以需要引入web 相关依赖 shiro-spring-boot-web-starter,如下所示:

     

3、准备Realm

     因为实例化 ShiroFilterFactoryBean 时需要注入  SecurityManager 的bean,而 

     SecurityManager 实例化时需要绑定Realm。

      在真正工作中,我们一般需要从数据库中查询用户信息、角色信息和用户权限信息,

      即一般自定义Relam,自定义Realm如下:

@Component
public class CustomRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;@Autowiredprivate RoleService roleService;@Autowiredprivate PermissionService permissionService;{//用于密码加密和比对HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("MD5");matcher.setHashIterations(1024);this.setCredentialsMatcher(matcher);}/*** 授权* todo 注意:*    1、授权是在认证之后的操作,授权方法需要用到认证方法返回的 AuthenticationInfo  中的用户信息*    2、该方法是在父类 AuthorizingRealm.getAuthorizationInfo() 方法中调用的,在 getAuthorizationInfo()*          方法中,回先从缓存中查询权限信息,若缓存中数据不存在,再执行改当前方法从数据库中查询权限数据*          针对这个逻辑,我们可以扩展Shiro 把数据放到缓存中(一般放到redis 中)*** @param principals  即 doGetAuthenticationInfo 方法返回的 AuthenticationInfo 中的用户信息(这里是User )* @return*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {System.out.println("查询数据库,根据用户信息查询角色和权限信息~~~~~~~~~~~~~~~~~~~~~~~~");//0、判断是否完成认证Subject subject = SecurityUtils.getSubject();if(subject == null || subject.isAuthenticated())return null;//1. 获取认证用户的信息User user = (User) principals.getPrimaryPrincipal();//2. 基于用户信息获取当前用户拥有的角色。Set<Role> roleSet = roleService.findRolesByUid(user.getId());Set<Integer> roleIdSet = new HashSet<>();Set<String> roleNameSet = new HashSet<>();for (Role role : roleSet) {roleIdSet.add(role.getId());roleNameSet.add(role.getRoleName());}//3. 基于用户拥有的角色查询权限信息Set<Permission> permSet = permissionService.findPermsByRoleSet(roleIdSet);Set<String> permNameSet = new HashSet<>();for (Permission permission : permSet) {permNameSet.add(permission.getPermName());}//4. 声明AuthorizationInfo对象作为返回值,传入角色信息和权限信息SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.setRoles(roleNameSet);info.setStringPermissions(permNameSet);//5. 返回return info;}/*** 认证 用户执行认证操作传入的用户名和密码* 只需要完成用户名校验即可,密码校验由Shiro内部完成** @param token* @return* @throws AuthenticationException*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//1、获取用户名称String userName = (String) token.getPrincipal();//2、判断用户名称是否为空if(StringUtils.isEmpty(userName)){// 返回null,会默认抛出一个异常,org.apache.shiro.authc.UnknownAccountExceptionreturn null;}//4、如果用户名称不为空,则基于用户名称去查询用户信息//这一步一般是自己的UserService 服务//模拟查询用户信息User user = userService.findByUsername(userName);if(user == null){return null;}//5、构建 AuthenticationInfo 对象,并填充用户信息/*** todo 注意:*    SimpleAuthenticationInfo 第一个参数是用户信息,第二个参数是用户密码,第三个参数是Realm名称(这个参数没有意义)*/SimpleAuthenticationInfo info =  new SimpleAuthenticationInfo(user,user.getPassword(),"CustomRealm!!!");//设置盐info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));//返回 AuthenticationInfo 对象return info;}}

4、准备Shiro相关的配置文件

      定义Shiro 配置文件,用于实例化 SecurityManager 对象 与 配置拦截器链。

      虽然SpringBoot 自动装配机制会自动装配 SecurityManager,但自动装载 SecurityManager 时

      只会注入 Shiro 自身默认提供的Relam,这里需要把自定义的Realm注入到 SecurityManager

     ,所以需要我们手动装载 SecurityManager 去覆盖Springboot 自动装载的 SecurityManager。

     另外在 shiro-spring-boot-web-starter 包下的文件 spring.factores 中的配置类

     ShiroWebAutoConfiguration中 springboot自动装配的拦截器链中只配置了一种请求,

     如图所示:

           

     所以我们也需要在自定义的shiro配置文件中,手动配置我们需要的拦截器链。

     shiro配置文件如下:

     

/***************************************************** Shiro 配置类* 由前边 Shiro 与Spring Web 整合可以发现,Shiro与Spring 整合的核心是向spring中注入* ShiroFilterFactoryBean;但在spring boot 中,spring boot 会自动将 ShiroFilterFactoryBean* 注入到spring 中(在 AbstractShiroWebFilterConfiguration 中完成的)* 在 AbstractShiroWebFilterConfiguration 中发现,实例化 ShiroFilterFactoryBean 时需要* 提供 SecurityManager(使用的是  DefaultWebSecurityManager) 和 ShiroFilterChainDefinition(拦截器链)* SecurityManager 实例化需要提供 Realm ,** 定义 Shiro 配置类,用于实例化  DefaultWebSecurityManager 和 ShiroFilterChainDefinition** @author lbf* @date ****************************************************/
@Configuration
public class ShiroConfig {/*** 注入* 实例化 WebSecurityManager 时需要用到Releam bean,所以在这之前 Releam 一定要存在* @param realm* @return*/@Beanpublic DefaultWebSecurityManager securityManager(CustomRealm realm, SessionManager sessionManager){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm);return securityManager;}/*** 添加拦截器链* @return*/@Beanpublic ShiroFilterChainDefinition filterChainDefinition(){DefaultShiroFilterChainDefinition filterChainDefinition = new DefaultShiroFilterChainDefinition();//添加拦截器信息Map<String, String> filterChainDefinitionMap = new LinkedHashMap();/*** anon 和 authc 都是Shiro 自带的过滤器* Shiro 自带的过滤器可以在枚举 DefaultFilter 中查看*///anon: 放行filterChainDefinitionMap.put("/login.html","anon");filterChainDefinitionMap.put("/user/**","anon");//authc:认证之后放行filterChainDefinitionMap.put("/**","authc");filterChainDefinition.addPathDefinitions(filterChainDefinitionMap);return filterChainDefinition;}}

    

5、测试

      

二、Shiro 授权方式

       Shiro 常用的授权方式有2种,即

           1)基于连接器链的权限角色校验,就是上边配置拦截器链的方式;将需要校验的请求

                 配置到拦截器链 ShiroFilterChainDefinition 种,如下图所示:

                     

           2)基于注解的权限角色校验

   

    2、基于注解的权限角色校验

          Shiro 提供了基于注解的方式来简化权限和角色的校验,可以在类或方法上直接声明所需要

          的角色或权限;

          注解进行权限或角色校验时,是基于对Controller类进行代理,在前置增强中对请求进行权限

          校验,是在拦截器链方式的后边执行。

          Shiro 提供了如下几个注解用于权限和角色校验

                 1)@RequiresAuthentication

                       要求当前 Subject 已经通过认证(即用户已登录)

                 2)@RequiresUser

                       要求当前 Subject 是一个应用程序用户(已认证或通过记住我功能登录)

                 3)@RequiresGuest

                       要求当前 Subject 是一个"访客",即未认证或未通过记住我登录

                 4)@RequiresRoles

                      要求当前 Subject 拥有指定的角色,即角色校验,常用

                 5)@RequiresPermissions

                      要求当前 Subject 拥有指定的权限,即权限校验,常用

          示例代码如下:

@RestController
@RequestMapping("/item")
public class ItemController {/*** 基于过滤器链的角色、权限校验* @return*/@GetMapping("/select")public String select(){return "item Select!!!";}@GetMapping("/delete")public String delete(){return "item Delete!!!";}/*** 基于注解的角色校验* @return*/@GetMapping("/update")//默认多个角色是and 的关系@RequiresRoles(value = {"超级管理员","运营"})public String update(){return "item Update!!!";}@GetMapping("/insert")@RequiresRoles(value = {"超级管理员","运营"},logical = Logical.OR)public String insert(){return "item Update!!!";}/*** 基于注解的权限校验* logical=用于指定多个权限是同时满足,还是满足其中一个,默认是and* Logical.OR含义是:只有用于 admin 权限或del权限的用户才能执行删除操作* @return*/@GetMapping("/update")@RequiresPermissions(value =  {"item:admin","item:del"},logical = Logical.OR)public String del(){return "item del !!!";}
}

         

3、基于注解方式的权限角色校验要注意的点

     1)基于注解的方式与基于配置链的方式是可以配合使用的,并不冲突,基于配置的方式在

           拦截器链之后执行。

     2)注解只能用在 Spring 管理的 Bean 上(如 Controller、Service 等),对于静态方法

           或非 Spring 管理的类,注解不会生效

     3)当权限校验失败时,Shiro 会抛出相应的异常,我们需要自己配置异常处理器处理这些异常

          ,如:通过 @RestControllerAdvice,@ControllerAdvice

             示例代码如下:

@RestControllerAdvice(basePackages = "com.msb.controller") //指定要处理异常的包路径
public class AuthExceptionHandler {//处理授权异常@ExceptionHandler(AuthorizationException.class)public ResponseEntity<String> handleAuthorizationException(AuthorizationException e) {return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无权访问: " + e.getMessage());}//处理认证异常@ExceptionHandler(AuthenticationException.class)public ResponseEntity<String> handleAuthenticationException(AuthenticationException e) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("认证失败: " + e.getMessage());}
}

    

三、RolesAuthorizationFilter 分析

       以默认的角色拦截器 RolesAuthorizationFilter 分析下 Shiro 种是如何进行角色认证的

       1)角色校验方法 RolesAuthorizationFilter.isAccessAllowed

//mappedValue: 需要校验的角色列表,即在连接器链种指定的角色列表
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {//获取请求主体 Subject,即用户Subject subject = this.getSubject(request, response);//需要校验的角色列表String[] rolesArray = (String[])((String[])mappedValue);if (rolesArray != null && rolesArray.length != 0) {Set<String> roles = CollectionUtils.asSet(rolesArray);//调用 Subject.hasAllRoles 校验用户是否具有所有的 mappedValue 角色return subject.hasAllRoles(roles);} else {return true;}}

        2)AuthorizingRealm.hasAllRoles

              从Subject.hasAllRoles 方法一直点进去 ,如下所示:

                    Subject—>DelegatingSubject.hasAllRoles —> Authorizer.hasAllRoles

                     —> AuthorizingRealm.hasAllRoles

              一直到 AuthorizingRealm.hasAllRoles 方法,在该方法种调用了getAuthorizationInfo 

             方法来获取 AuthorizationInfo,如下图所示:

                  

        3)AuthorizingRealm.getAuthorizationInfo 方法

             在 getAuthorizationInfo 方法种,我们重点看下 doGetAuthorizationInfo 方法;

             到这里是不是有点眼熟,doGetAuthorizationInfo是一个抽象方法,它有多个实现,

            其中有一个实现就是上边我们自定义的CustomRealm中的方法

             如下图所示:

                

四、自定义拦截器

       在工作中Shiro 默认提供的校验拦截器往往不能满足我们实际的需要,这就需要我们自定义

       Shiro拦截器,如:上边RolesAuthorizationFilter 是校验用户具有角色列表中的所有角色才

       校验通过,而在工作中常常有 “存在一个角色在角色列表中就行” 的场景;

1、自定义Shiro拦截器解决 “存在一个角色在角色列表中就行” 的场景

      自定义过滤器需要继承类 AuthorizationFilter,并重写 isAccessAllowed 方法

      示例代码如下:

      

public class RolesOrAuthorizationFilter extends AuthorizationFilter {/*** 用户角色校验* @param request* @param response* @param mappedValue   指定的角色列表,* @return* @throws Exception*/@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {//获取校验主题,可以认为就是用户信息Subject subject = this.getSubject(request, response);/*** 获取用户指定的角色列表,就是在 初始化 ShiroFilterChainDefinition过程中指定的角色列表* (如:roles[超级管理员,运营],[]中的内容)*/String[] rolesArray = (String[])((String[])mappedValue);if(rolesArray != null && rolesArray.length > 0){for (String role:rolesArray){//有一个角色校验通过,则表示校验通过,返回trueif(subject.hasRole(role)){return true;}}}else {return true;}return false;}
}

2、将自定义Filter 交给Shiro 管理

      自定义的角色校验器(过滤器)如何交给Shiro管理?

      由 配置类 ShiroWebFilterConfiguration 初始化 ShiroFilterFactoryBean 时可以发现,过滤器

      是在 ShiroFilterFactoryBean 实例化时交给 ShiroFilterFactoryBean 管理的;到这里就明白

      了,我们可以手动初始化 ShiroFilterFactoryBean 来覆盖springboot 的自动初始化

      ShiroFilterFactoryBean,并把自定义的 RolesOrAuthorizationFilter 过滤器交给

      ShiroFilterFactoryBean 管理。

      在配置类ShiroConfig 中手动注入ShiroFilterFactoryBean 代码如下:

//手动注入  ShiroFilterFactoryBean,覆盖 Springboot 自动装载ShiroFilterFactoryBean;/*** 初始化一些url* ShiroFilterFactoryBean 实例化需要的url,这些url可以在配置文件中配置*///登录url@Value("#{ @environment['shiro.loginUrl'] ?: '/login.jsp' }")protected String loginUrl;//登录成功后跳转url@Value("#{ @environment['shiro.successUrl'] ?: '/' }")protected String successUrl;//校验失败的url@Value("#{ @environment['shiro.unauthorizedUrl'] ?: null }")protected String unauthorizedUrl;/*** 手动注入 ShiroFilterFactoryBean,覆盖 Springboot 自动装载ShiroFilterFactoryBean;* 用于把自定义的过滤器交给 Shiro 管理* @param securityManager* @param filterChainDefinition  过滤器链* @return*/@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,ShiroFilterChainDefinition filterChainDefinition){//创建 ShiroFilterFactoryBeanShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();//设置大量的urlfilterFactoryBean.setLoginUrl(this.loginUrl);filterFactoryBean.setSuccessUrl(this.successUrl);filterFactoryBean.setUnauthorizedUrl(this.unauthorizedUrl);//设置安全管理器filterFactoryBean.setSecurityManager(securityManager);//设置过滤器链filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinition.getFilterChainMap());//设置自定义过滤器 ,// todo 注意:这里一定要手动的new出来这个自定义过滤器,如果使用Spring自动注入自定义过滤器,//                    会造成无法获取到Subject//         因为spring 自动注入 自定义过滤器 RolesOrAuthorizationFilter 初始化太早了,而RolesOrAuthorizationFilter//        初始化时需要做一些Shiro处理后,RolesOrAuthorizationFilter 实例才能拿到SubjectfilterFactoryBean.getFilters().put("roleOr",new RolesOrAuthorizationFilter());return filterFactoryBean;}

3、在拦截器链 ShiroFilterChainDefinition 配置使用自定义过滤器

     由上边可以知道 自定义Shiro 过滤器 RolesOrAuthorizationFilter 的名称是 “roleOr”;

     在拦截器链 ShiroFilterChainDefinition 中的配置如下:

@Beanpublic ShiroFilterChainDefinition filterChainDefinition(){DefaultShiroFilterChainDefinition filterChainDefinition = new DefaultShiroFilterChainDefinition();//添加拦截器信息,LinkedHashMap有序Map<String, String> filterChainDefinitionMap = new LinkedHashMap();/*** anon 和 authc 都是Shiro 自带的过滤器* Shiro 自带的过滤器可以在枚举 DefaultFilter 中查看*///anon: 放行filterChainDefinitionMap.put("/login.html","anon");filterChainDefinitionMap.put("/user/**","anon");//使用自定义的过滤器,有一个角色在[超级管理员,运营] 中就校验通过filterChainDefinitionMap.put("/item/select","rolesOr[超级管理员,运营]");//filterChainDefinitionMap.put("/item/select","roles[超级管理员,运营]");filterChainDefinitionMap.put("/item/delete","perms[item:delete,item:insert]");//authc:认证之后放行filterChainDefinitionMap.put("/**","authc");filterChainDefinition.addPathDefinitions(filterChainDefinitionMap);return filterChainDefinition;}

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

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

相关文章

【图形API】片段着色器自动计算LOD

片段着色器中的自动 LOD 计算详解 在图形渲染中&#xff0c;Level of Detail (LOD) 用于优化纹理采样的性能和视觉质量。片段着色器&#xff08;Fragment Shader&#xff09;能够自动计算 LOD&#xff0c;而顶点着色器&#xff08;Vertex Shader&#xff09;则不行。以下是详细…

24、 Python Socket编程:从协议解析到多线程实战

Python Socket编程&#xff1a;从协议解析到多线程实战 一、文章概述 本文深入讲解Python网络编程核心技术&#xff0c;涵盖TCP/UDP协议底层原理、Socket API全流程解析、高并发服务端开发实践&#xff0c;以及网络通信中的典型问题解决方案。通过3个递进式代码案例和协议设计…

LabVIEW 中数字转字符串常用汇总

在 LabVIEW 编程环境里&#xff0c;数字与字符串之间的转换是一项极为基础且重要的操作&#xff0c;广泛应用于数据处理、显示、存储以及设备通信等多个方面。熟练掌握数字转字符串的方法和技巧&#xff0c;对编写高效、稳定的程序起着关键作用。接下来&#xff0c;我们将全面深…

轨迹速度聚类 实战

根据轨迹把速度聚类为3个类别,速度快的那部分不用平滑,速度慢的部分需要平滑。 速度聚类3个类别: kmeans++ import numpy as np import cv2 from sklearn.cluster import KMeans from matplotlib.colors import hsv_to_rgb from scipy.ndimage import gaussian_filter1d# …

vulkanscenegraph显示倾斜模型(5.6)-vsg::RenderGraph的创建

前言 上一章深入分析了vsg::CommandGraph的创建过程及其通过子场景遍历实现Vulkan命令录制的机制。本章将在该基础上&#xff0c;进一步探讨Vulkan命令录制中的核心封装——vsg::RenderGraph。作为渲染流程的关键组件&#xff0c;RenderGraph封装了vkCmdBeginRenderPass和vkCmd…

第二十八章:Python可视化图表扩展-和弦图、旭日图、六边形箱图、桑基图和主题流图

一、引言 在数据可视化领域&#xff0c;除了常见的折线图、柱状图和散点图&#xff0c;还有一些高级图表类型可以帮助我们更直观地展示复杂数据关系。本文将介绍五种扩展图表&#xff1a;和弦图、旭日图、六边形箱图、桑基图和主题流图。这些图表在展示数据关系、层次结构和流量…

大模型-爬虫prompt

爬虫怎么写prompt 以下基于deepseek r1 总结&#xff1a; 以下是为大模型设计的结构化Prompt模板&#xff0c;用于生成专业级网络爬虫Python脚本。此Prompt包含技术约束、反检测策略和数据处理要求&#xff0c;可根据具体需求调整参数&#xff1a; 爬虫脚本生成Prompt模板1 …

Vue中将pdf文件转为图片

平时开发中,我们经常遇到的场景应该是调用后端接口返回给前端pdf格式的文件流,然后我们可以通过URL.createObjectURL的方式转为object url临时路径然后可以通过window.open的方式来打开一个新的浏览器页签来进行预览,效果如下图: 但有时候这样满足不了的需求,它不想这样预…

物联网安全技术:守护智能世界的防线

最近研学过程中发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…

kubernetes安装部署k8s

kubernetes https://github.com/kubernetes/kubernetes.git go mod tidy go mod vendor go build -o .\bin -v ./… //手动创建bin文件夹 使用 minikube&#xff1a;https://gitee.com/mirrors/minikube.git 使用minikube启动本地化的集群服务 minikube start 启动集群&…

JT/T 1078 协议基本介绍与解析

文章目录 一、JT/T 1078 协议基本介绍二、JT/T 1078 与 JT808 的关系三、JT1078 协议核心功能四、JT1078 数据结构概览4.1、消息结构&#xff1a;4.2、消息类型&#xff08;部分&#xff09;&#xff1a; 五、Java 中如何解析 JT1078 协议数据&#xff1f;5.1、JT1078 消息 ID …

手机为电脑提供移动互联网络的3种方式

写作目的 在当今数字化时代,电脑已成为人们日常工作和生活中不可或缺的工具,而网络连接更是其核心功能之一。无论是处理工作任务、进行在线学习、还是享受娱乐资源,稳定的网络环境都是保障这些活动顺利开展的关键。然而,在实际使用过程中,电脑网络驱动故障时有发生,这可…

Linux的 /etc/sysctl.conf 笔记250404

Linux的 /etc/sysctl.conf 笔记250404 /etc/sysctl.conf 是 Linux 系统中用于 永久修改内核运行时参数 的核心配置文件。它通过 sysctl 工具实现参数的持久化存储&#xff0c;确保系统重启后配置依然生效。以下是其详细说明&#xff1a; &#x1f4c2; 备份/etc/sysctl.conf t…

deepseek v3-0324 Markdown 编辑器 HTML

Markdown 编辑器 HTML 以下是一个美观的 Markdown 编辑器 HTML 页面&#xff0c;支持多种主题切换和实时预览功能&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&q…

Linux make 检查依赖文件更新的原理

1. 文件的时间戳 make 主要依靠文件的时间戳来判断依赖文件是否有更新。每个文件在文件系统中都有一个时间戳&#xff0c;记录了文件的三种重要时间&#xff1a; ​​访问时间&#xff08;Accesstime&#xff09;​​&#xff1a;文件最后一次被访问的时间。​​修改时间&…

HDEBits中组合逻辑类的部分题目练习

文章目录 1. More logic gates2. Truth tables3. 256-to-1 4-bit multiplexer4. 3-bit binary adder5. Signed addition overflow6. 4-digit BCD adder7. Minimum SOP and POS8. Karnaugh map9. K-map implemented with a multiplexer总结 1. More logic gates 题目&#xff1…

Apache httpclient okhttp(2)

学习链接 Apache httpclient & okhttp&#xff08;1&#xff09; Apache httpclient & okhttp&#xff08;2&#xff09; okhttp github okhttp官方使用文档 okhttp官方示例代码 OkHttp使用介绍 OkHttp使用进阶 译自OkHttp Github官方教程 SpringBoot 整合okHttp…

【git项目管理】长话短说

目录 主要分为三种使用情况 安装git后第一次使用创建新仓库并管理克隆仓库并管理 初次使用git 首先确定电脑的用户名是纯英文&#xff0c;没有中文和奇怪的符号&#xff0c;如果不满足这个条件&#xff0c;参考这个 链接 修改用户名 git config --global user.name "…

算法刷题记录——LeetCode篇(3.2) [第211~212题](持续更新)

更新时间&#xff1a;2025-04-04 算法题解目录汇总&#xff1a;算法刷题记录——题解目录汇总技术博客总目录&#xff1a;计算机技术系列博客——目录页 优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注&#xff01; 215. 数组中的第K个最大元素 给…

【linux学习】linux系统调用编程

目录 一、任务、进程和线程 1.1任务 1.2进程 1.3线程 1.4线程和进程的关系 1.5 在linux系统下进程操作 二、Linux虚拟内存管理与stm32的真实物理内存区别 2.1 Linux虚拟内存管理 2.2 STM32的真实物理内存映射 2.3区别 三、 Linux系统调用函数 fork()、wait()、exec(…