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.pswp.cn/web/74620.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74620.shtml
英文地址,請注明出處:http://en.pswp.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(…