单点登录原理与实现方案探究(二)

本系列文章简介:

        本系列文章将深入探究Java中的单点登录原理与实现方案。首先,我们将介绍单点登录的基本原理,探讨其在多应用环境下的工作流程。然后,我们将详细讨论目前流行的三种单点登录实现方案我们将分析每种实现方案的优缺点,以及适用场景

        在实现方案探究的过程中,我们将结合具体的Java代码示例,以帮助读者更好地理解和应用这些解决方案。我们将介绍如何使用Spring Security和Spring Boot等开源框架来实现单点登录功能,并提供详细的步骤和注意事项。

        欢迎大家订阅《Java技术栈高级攻略》专栏,一起学习,一起涨分!

目录

1、前言

2、Java中的单点登录实现方案

2.1 使用Spring Security实现单点登录

2.2 使用CAS(Central Authentication Service)实现单点登录

2.3 使用Shiro实现单点登录

3、单点登录的实践案例

3.1 公司内部系统单点登录案例示例:

3.2 跨域单点登录案例

4、单点登录的发展趋势和未来展望

5、结语


1、前言

        单点登录(Single Sign-On,简称SSO)是一种通过集中的身份认证机制,使用户只需要一次登录就可以访问多个应用系统的解决方案。

        本文将跟随《单点登录原理与实现方案探究(一)》的进度,继续介绍单点登录。希望通过本系列文章的学习,您将能够更好地理解单点登录的内部工作原理,掌握单点登录的使用技巧,以及通过合理的设计完成最佳实践,充分发挥单点登录的潜力,为系统的高效运行提供有力保障。

2、Java中的单点登录实现方案

2.1 使用Spring Security实现单点登录

使用Spring Security实现单点登录的步骤如下:

  1. 创建一个基于Spring Boot的Java项目,并添加Spring Security依赖。
  2. 配置Spring Security,包括配置用户认证、授权、表单登录等。
  3. 实现一个认证服务,用于验证用户的登录凭证,并生成一个令牌。
  4. 在其他需要进行单点登录的应用中,配置Spring Security,使用相同的认证服务进行验证。
  5. 在需要进行单点登录的应用中,配置Spring Security,将认证成功后的令牌保存到Session中。
  6. 在其他需要进行单点登录的应用中,配置Spring Security,使用相同的认证服务进行验证,并判断Session中是否存在令牌。

下面是一个使用Spring Security实现单点登录的示例代码:

  1. 创建一个基于Spring Boot的Java Web项目,并添加以下依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

        2. 创建一个配置类,配置Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/login").permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login").defaultSuccessUrl("/home").permitAll().and().logout().permitAll();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");}
}

这个配置类配置了用户认证、授权和表单登录,所有请求都需要认证通过才能访问,登录成功后跳转到 "/home"。

        3. 创建一个认证服务,用于验证用户的登录凭证,并生成一个令牌:

@Service
public class AuthenticationService {public String authenticate(String username, String password) {// TODO: 验证用户名和密码// 生成一个令牌String token = UUID.randomUUID().toString();return token;}
}

        4. 在登录控制器中使用认证服务进行验证,并将认证成功后的令牌存储在Session中:

@Controller
public class LoginController {@Autowiredprivate AuthenticationService authenticationService;@PostMapping("/login")public String login(@RequestParam String username, @RequestParam String password, HttpSession session) {String token = authenticationService.authenticate(username, password);session.setAttribute("token", token);return "redirect:/home";}
}

        5. 在其他需要进行单点登录的应用中配置Spring Security,并检查Session中是否存在令牌:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/home").authenticated().anyRequest().permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/home").permitAll();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 配置认证服务}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/home").authenticated().anyRequest().permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/home").permitAll();}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/home").authenticated().anyRequest().permitAll().and().formLogin().loginPage("/login").defaultSuccessUrl("/home").permitAll();}
}

这样,当用户在一个应用中登录后,访问其他需要进行单点登录的应用时,会自动跳转到登录页面,并且登录成功后会根据配置的默认成功URL进行跳转。

2.2 使用CAS(Central Authentication Service)实现单点登录

使用CAS实现单点登录的基本步骤如下:

  1. 部署CAS服务器:首先需要部署一个CAS服务器,该服务器负责用户的认证和授权功能。CAS服务器会生成一个票据(ticket),并将该票据返回给客户端。

  2. 配置应用程序:在应用程序中配置CAS服务器的URL,并将应用程序注册到CAS服务器。

  3. 用户认证:用户访问应用程序时,应用程序重定向到CAS服务器进行用户认证。用户在CAS服务器上输入用户名和密码进行登录认证。

  4. 生成票据:CAS服务器认证成功后,生成一个票据,并将该票据返回给应用程序。

  5. 应用程序验证:应用程序收到票据后,将票据发送给CAS服务器进行验证。如果票据有效,CAS服务器会返回一个用户凭证(principal),应用程序可以使用该凭证获取用户信息。

下面是一个使用CAS实现单点登录的示例:

  1. 部署CAS服务器:首先需要部署一个CAS服务器,可以使用官方提供的CAS Server或者其他CAS服务器如Apereo CAS。

  2. 配置应用程序:在应用程序的web.xml配置文件中添加以下内容:

<filter><filter-name>CAS Single Sign Out Filter</filter-name><filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter><filter><filter-name>CAS Authentication Filter</filter-name><filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class><init-param><param-name>casServerLoginUrl</param-name><param-value>https://cas-server-url/login</param-value></init-param><init-param><param-name>serverName</param-name><param-value>https://your-app-url</param-value></init-param>
</filter><filter-mapping><filter-name>CAS Single Sign Out Filter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping><filter-mapping><filter-name>CAS Authentication Filter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

        3. 用户认证:当用户访问应用程序时,会自动重定向到CAS服务器进行用户认证。

        4. 应用程序验证:应用程序可以在需要验证用户身份的地方调用以下代码进行CAS票据验证:

import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;public class CasTicketValidator {public static void main(String[] args) {// CAS服务器URLString casServerUrl = "https://cas-server-url";// 应用程序URLString appUrl = "https://your-app-url";// 获取CAS票据String ticket = "cas-ticket";// 创建CAS票据验证器Cas20ProxyTicketValidator ticketValidator = new Cas20ProxyTicketValidator(casServerUrl);// 配置应用程序URLticketValidator.setService(appUrl);try {// 验证CAS票据ticketValidator.validate(ticket);// 获取用户凭证String principal = ticketValidator.getUser();System.out.println("User principal: " + principal);} catch (Exception e) {e.printStackTrace();}}
}

这个示例中,我们调用Cas20ProxyTicketValidator类来验证CAS票据。首先创建一个验证器对象,然后设置CAS服务器URL和应用程序URL。最后调用validate方法验证票据并获取用户凭证。

以上就是使用CAS实现单点登录的基本方案和示例。实际应用中,还需要根据具体情况进行一些调整和配置。

2.3 使用Shiro实现单点登录

在Java中使用Shiro实现单点登录有以下步骤:

  1. 引入Shiro依赖:在项目的pom.xml文件中添加Shiro的依赖。
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.7.1</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.7.1</version>
</dependency>

        2. 配置Shiro:在项目的shiro.ini文件中配置Shiro的认证和授权信息,以及设置单点登录的相关配置。

# 配置Realm,用于认证和授权
myRealm = com.example.MyRealm
securityManager.realms = $myRealm# 配置Session管理器,用于实现单点登录
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.globalSessionTimeout = 1800000   # 设置Session超时时间为30分钟
securityManager.sessionManager = $sessionManager# 配置Cookie管理器,用于实现单点登录
cookieManager = org.apache.shiro.web.servlet.SimpleCookie
cookieManager.name = sid   # 设置Cookie的名称为sid
securityManager.sessionManager.sessionIdCookie = $cookieManager

        3. 实现自定义Realm:创建一个自定义的Realm,用于实现用户认证和授权逻辑。

public class MyRealm extends AuthorizingRealm {@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 用户认证逻辑// 根据token中的用户名查询数据库,获取用户信息// 如果用户不存在,则抛出UnknownAccountException异常// 如果密码不正确,则抛出IncorrectCredentialsException异常// 如果认证通过,返回AuthenticationInfo对象}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 用户授权逻辑// 从PrincipalCollection中获取用户名// 根据用户名查询数据库,获取用户角色和权限信息// 构建AuthorizationInfo对象,并设置角色和权限信息// 返回AuthorizationInfo对象}
}

        4. 配置Web过滤器:在项目的web.xml文件中配置Shiro的Web过滤器,用于拦截需要认证和授权的请求。

<filter><filter-name>shiroFilter</filter-name><filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

        5. 编写登录页面:创建一个登录页面,用于用户输入用户名和密码进行认证。

<form method="post" action="/login"><input type="text" name="username" placeholder="Username" required><input type="password" name="password" placeholder="Password" required><button type="submit">Log In</button>
</form>

        6. 编写登录请求处理器:创建一个登录请求处理器,用于处理用户提交的登录请求,并进行认证。

@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");// 获取当前用户的认证主体Subject currentUser = SecurityUtils.getSubject();if (!currentUser.isAuthenticated()) {// 创建用户名密码TokenUsernamePasswordToken token = new UsernamePasswordToken(username, password);try {// 进行用户认证currentUser.login(token);} catch (AuthenticationException e) {// 认证失败,跳转到登录页,并显示错误消息request.setAttribute("errorMessage", "Invalid username or password.");request.getRequestDispatcher("/login.jsp").forward(request, response);return;}}// 认证成功,重定向到首页response.sendRedirect("/");}
}

这样,当用户访问受保护的资源时,Shiro会拦截请求并跳转到登录页面,用户输入用户名和密码后,Shiro会进行认证并跳转回原来请求的资源。

示例代码仅提供了基本的实现,实际项目中还需根据具体需求进行完善和调整。

3、单点登录的实践案例

3.1 公司内部系统单点登录案例示例:

公司内部系统单点登录案例: 假设公司有三个内部系统:人力资源管理系统(HRM),财务管理系统(FMS)和客户关系管理系统(CRM)。为了提高员工的工作效率,公司决定实施单点登录(SSO),员工只需要登录一次,就可以访问所有系统。

以下是一个示例场景:

  1. 员工张三登录公司的员工门户网站。
  2. 张三在员工门户网站的针对每个系统的链接上单击,例如“HRM系统”。
  3. 员工门户网站将张三的登录凭证发送给SSO认证服务器进行验证。
  4. SSO认证服务器验证张三的凭证,并将一个加密的令牌返回给员工门户网站。
  5. 员工门户网站将该令牌传递给HRM系统。
  6. HRM系统收到令牌后,将其发送给SSO认证服务器进行验证。
  7. SSO认证服务器验证令牌的有效性,并将验证结果返回给HRM系统。
  8. 如果令牌有效,HRM系统将允许张三登录,并显示张三的HRM系统首页。
  9. 张三可以在HRM系统内进行工作,无需再次登录。
  10. 如果张三想访问FMS系统,他只需要单击员工门户网站上的FMS系统链接。
  11. 员工门户网站将张三的令牌传递给FMS系统。
  12. FMS系统收到令牌后,将其发送给SSO认证服务器进行验证。
  13. SSO认证服务器验证令牌的有效性,并将验证结果返回给FMS系统。
  14. 如果令牌有效,FMS系统将允许张三登录,并显示张三的FMS系统首页。
  15. 张三可以在FMS系统内进行工作,无需再次登录。
  16. 同样的流程也适用于CRM系统和其他内部系统。

通过单点登录,公司可以提高员工的工作效率,减少登录次数和密码管理的负担。同时,也可以提高系统的安全性,通过集中的认证服务器来验证用户的身份,减少了对每个内部系统的登录认证过程。

3.2 跨域单点登录案例

跨域单点登录是指在多个子域名或不同域名之间实现单一身份认证,用户只需要登录一次,即可在不同的子域名或不同域名下访问受保护的资源。

以下是一个使用Java实现跨域单点登录的示例:

  1. 创建一个公共的用户认证系统(例如认证中心),负责用户的登录认证。

  2. 在认证中心中设置一个接口进行用户认证,例如/auth接口。

  3. 在其他子域名或不同域名的应用中,用户访问受保护的资源时,首先检查用户是否登录。

  4. 如果用户没有登录,将用户重定向到认证中心的登录页面。

  5. 用户在认证中心登录成功后,认证中心会生成一个令牌(token),保存用户的信息,并将令牌返回给应用。

  6. 应用在收到令牌后,将令牌保存在Cookie中,并发送给用户。

  7. 用户在访问其他子域名或不同域名下的资源时,每次请求都会带上Cookie。

  8. 应用在收到请求时,从Cookie中获取令牌。

  9. 应用将令牌发送给认证中心进行验证,验证通过后,应用可以根据令牌中的用户信息,判断用户是否已经登录。

以下是示例代码:

在认证中心中的Controller中,处理用户登录请求:

@RestController
public class AuthController {@RequestMapping("/auth")public String auth(@RequestParam("username") String username, @RequestParam("password") String password) {// 验证用户名和密码是否正确if (checkUsernameAndPassword(username, password)) {// 生成令牌String token = generateToken(username);// 保存令牌saveToken(token);return token;} else {return "登录失败";}}// 验证用户名和密码是否正确private boolean checkUsernameAndPassword(String username, String password) {// ...}// 生成令牌private String generateToken(String username) {// ...}// 保存令牌private void saveToken(String token) {// ...}}

在其他子域名或不同域名的Controller中,处理受保护资源的请求:

@RestController
public class ResourceController {@RequestMapping("/resource")public String getResource(@CookieValue(value="token", required=false) String token) {// 检查是否存在令牌if (token != null) {// 发送令牌给认证中心进行验证boolean validToken = checkToken(token);if (validToken) {// 验证通过,返回受保护的资源return "受保护的资源";}}// 用户未登录或令牌验证失败return "请先登录";}// 发送令牌给认证中心进行验证private boolean checkToken(String token) {// ...}}

以上示例代码仅是一个简单的跨域单点登录实现示例,实际应用中可能还涉及更多复杂的业务逻辑和安全性考虑。

4、单点登录的发展趋势和未来展望

随着互联网应用的不断增加和用户对便利性和安全性的不断追求,单点登录技术正逐渐成为企业和用户的首选。

以下是单点登录发展的趋势和未来展望:

  1. 云计算和移动设备的普及:随着云计算和移动设备的普及,用户越来越多地使用多个不同的应用程序。单点登录能够提供跨平台和跨设备的身份验证,为用户提供更好的用户体验和便利性。

  2. 多因素身份验证的增强安全性:随着网络安全问题的日益严峻,多因素身份验证(MFA)正逐渐成为一种常见的安全措施。未来的单点登录系统将会集成MFA功能,进一步提高用户的身份验证安全性。

  3. 社交媒体和第三方认证:越来越多的应用程序允许用户使用社交媒体账号进行登录,这种方式简化了用户的注册和登录过程。未来的单点登录系统将更加适应这种趋势,提供与社交媒体和第三方认证的集成。

  4. 面向用户的个性化体验:未来的单点登录系统将更加注重用户体验,提供个性化的登录和身份验证方式。例如,用户可以选择使用指纹、面部识别或声音识别等生物特征进行登录。

  5. 区块链技术的应用:区块链技术具有去中心化、安全性高等特点,未来的单点登录系统可能会采用区块链技术来存储用户的身份验证信息,提供更高的安全性和防篡改能力。

综上所述,单点登录技术将会在未来继续发展,为用户提供更好的身份验证体验和安全性保障。同时,随着技术的不断进步,单点登录系统将会与其他先进技术集成,提供更加智能和个性化的用户体验。

5、结语

        文章至此,已接近尾声!希望此文能够对大家有所启发和帮助。同时,感谢大家的耐心阅读和对本文档的信任。在未来的技术学习和工作中,期待与各位大佬共同进步,共同探索新的技术前沿。最后,再次感谢各位的支持和关注。您的支持是作者创作的最大动力,如果您觉得这篇文章对您有所帮助,请分享给身边的朋友和同事!

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

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

相关文章

WARNING: No output specified with docker-container driver

这个警告信息是说 docker build 出现的&#xff0c;指出你没有指定任何输出目的地&#xff0c;因此构建后的镜像不会被持久保存&#xff0c;只会存留在构建缓存中。以至于后面 docker tag 命令会找不到镜像&#xff0c;从而导致build 和push流程失败. 两种解决的做法&#xff…

JDBC远程连接mysql报错:NotBefore: Sat Mar 30 16:37:41 UTC 2024

虚拟机docker已经部署了mysql&#xff0c;用navicat可以直接远程连接&#xff0c;datagrip却不能&#xff0c;如图&#xff1a; 需要在最后加上 ?useSSLfalse , 如&#xff1a;jdbc:mysql://192.168.30.128:3306?useSSLfalse navicat不用加的原因是没有使用jdbc连接&#x…

java数据结构与算法刷题-----LeetCode1091. 二进制矩阵中的最短路径

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 广度优先双分裂蛇 广度优先双分裂蛇 双分裂蛇&#xff1a;是求二…

Linux 学习之路--工具篇--yum

前面介绍了权限有关的内容&#xff0c;这里继续介绍有关Linux里面常用的工具之一yum 目录 一、简单介绍 <1> 源代码安装 <2>rpm 包安装 <3>yum / apt-get(ubuntu) 安装 二、简单使用 <1>安装包介绍 <2> yum 的基本指令 -- install <…

C++:数据类型—布尔(12)

布尔类型代表就是真和假&#xff08;bool&#xff09; 真就是1&#xff08;true&#xff09; 假就是0&#xff08;false&#xff09; 也可以任务非0即为真 bool 直占用1个字节大小 语法&#xff1a;bool 变量名 (true | false&#xff09; 提示&#xff1a;bool在后期判断也是…

2024年150道高频Java面试题(十)

19. 解释一下 Java 中的封装、继承和多态。 封装、继承和多态是面向对象编程&#xff08;OOP&#xff09;的三个核心概念&#xff0c;在Java中得到了广泛应用。 封装&#xff1a; 概念&#xff1a;封装是指隐藏一个对象的内部细节&#xff0c;仅对外暴露需要公开的部分。这可以…

Capture One Pro 23中文---颠覆性的图像编辑与色彩配置

Capture One Pro 23是一款功能强大且专业的RAW图像编辑处理软件。它拥有全球领先的色彩管理技术和精细的图像编辑工具&#xff0c;可以对图片进行多种精细调整&#xff0c;包括曝光、色温、对比度、锐度等&#xff0c;以满足用户特定的后期处理需求。此外&#xff0c;Capture O…

第二百三十一回

文章目录 1. 概念介绍2. 符号和平台2.1 符号2.2 平台 3. 问题与解决3.1 常见问题3.2 解决方法 4.内容总结 我们在上一章回中介绍了"关于intl报错的问题"相关的内容&#xff0c;本章回中将介绍不同平台上换行的问题.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1…

Excel函数-总

目录 1.概述 2.数组公式 2.1.数组的类别 2.2.数组的构成元素 2.3.数组运算时需要用到的运算符 3.数学与三角函数 3.1.RANDBETWEEN 3.2.ABS 3.3.MOD 3.4.PI ​​​​​​​3.5.PRODUCT ​​​​​​​3.6.RADIANS ​​​​​​​3.7.DEGREES ​​​​​​​3.8.POWER ​​​​​…

FastAPI+React全栈开发17 让我们创建一个React应用

Chapter04 Setting Up a React Workflow 17 Let’s Create a React App FastAPIReact全栈开发17 让我们创建一个React应用 As I mentioned earlier, create-react-app takes away much of the heavy work when starting a project, and we will be using it throughout this…

Python中对象的创建于使用

创建对象 在Python中&#xff0c;创建对象是通过实例化类来完成的。一个类是一个包含属性和方法的蓝图&#xff0c;它定义了一种对象的行为和特征。我们可以使用class关键字来定义一个类&#xff0c;然后使用类的名称和括号来实例化对象。 以下是一个创建对象的例子&#xff…

使用Docker搭建Sonarr

Sonarr是一款用于自动化管理电视节目的开源应用程序。它能够根据用户设定的规则自动搜索、下载并整理电视剧集&#xff0c;支持多用户、多队列管理&#xff0c;并且可以与下载客户端如SABnzbd、NZBGet等集成&#xff0c;以及与媒体服务器如Plex、Emby等配合使用&#xff0c;为用…

【3】3道链表力扣题:删除链表中的节点、反转链表、判断一个链表是否有环

3道链表力扣题 一、删除链表中的节点&#x1f30f; 题目链接&#x1f4d5; 示例&#x1f340; 分析&#x1f4bb; 代码 二、反转链表&#x1f30f; 题目链接&#x1f4d5; 示例&#x1f340; 分析① 递归② 迭代 三、判断一个链表是否有环&#x1f30f; 题目链接&#x1f4d5; …

ES6 模块化操作

ES6模块化主要有两个操作&#xff1a;import 和 export 如果在html文件的script中引用模块的话&#xff0c;要设置<script type"module"> 一种导入导出方法&#xff1a; a.js//分别暴露 export let num 1 export function compute(a, b){return a b }//统…

C++中使用虚函数实现多态

虚函数是C中用于实现多态&#xff08;Polymorphism&#xff09;的重要特性。下面是关于虚函数的讲解和代码示例&#xff1a;### 虚函数的定义&#xff1a; 虚函数是在基类中声明为 virtual 的成员函数。 在派生类中重写&#xff08;override&#xff09;这个虚函数&#xff0c;…

数据结构与算法 循环双链表基本运算与对称算法

一、实验内容 1、实现循环双链表的各种基本运算的算法 &#xff08;1&#xff09;初始化循环双链表h &#xff08;2&#xff09;依次采用尾插法插入a,b,c,d,e元素 &#xff08;3&#xff09;输出循环双链表h&#xff1b; &#xff08;4&#xff09;输出循环双链表h长度&am…

物联网学习1、什么是 MQTT?

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、基于发布-订阅模式的消息传输协议&#xff0c;适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎&#xff0c;能够实现传感器、执行器和其它设备之间的高效通…

HSP_04章_扩展: 进制、位运算

文章目录 10. 扩展: 进制11. 位运算11.1 二进制在运算中的说明11.2 原码 反码 补码11.3位运算符11.3.1 ~按位取反11.3.2 &按位与11.3.3 ^按位异或11.3.4 |按位或11.3.5 << 左移11.3.6 >> 右移 10. 扩展: 进制 进制介绍 进制的转换 2.1 其他进制转十进制 二进…

面试八股——redis——集群

0. redis集群的方案 1.主从复制&#xff08;高并发读&#xff09; 一个主节点负责写操作&#xff08;增删改&#xff09;&#xff0c;多个从节点负责查操作。 主从复制是让主节点修改数据之后&#xff0c;将对应数据同步到从节点中。 2.哨兵模式&#xff08;实现高可用&#x…

Redis命令请求的执行过程(一)

命令请求的执行过程 概述 一个命令请求从发送到获得回复的过程中&#xff0c;客户端和服务器需要完成一系列操作。 例子 举个例子。如果我们使用客户端执行以下命令: 127.0.0.1:6379> SET KEY VALUE OK那么客户端发送SET KEY VALUE命令到获得回复OK期间&#xff0c;客户…