安全登录系统完整教程

📋 目录

  1. 项目概述
  2. 技术栈
  3. 安全特性
  4. 项目结构
  5. 核心组件详解
  6. 安全实现原理
  7. 部署和运行
  8. 安全最佳实践
  9. 常见问题解答
  10. 进阶扩展

🎯 项目概述

这是一个基于Spring Boot和Spring Security的完整安全登录系统,专为初学者设计,展示了如何实现一个安全、可靠的用户认证系统。

主要功能

  • ✅ 用户注册和登录
  • ✅ 密码安全加密存储
  • ✅ 会话管理和自动登出
  • ✅ CSRF攻击防护
  • ✅ 点击劫持防护
  • ✅ 响应式Web界面
  • ✅ RESTful API接口

测试账户

  • 用户名: admin
  • 密码: admin123

🛠 技术栈

后端技术

  • Spring Boot 3.5.5 - 主框架
  • Spring Security 6.5.3 - 安全框架(注意:6.x版本API有重大变化)
  • Thymeleaf - 模板引擎
  • BCrypt - 密码加密算法(强度12)
  • Maven - 依赖管理
  • Java 17+ - 运行环境(Spring Boot 3.x要求)

前端技术

  • HTML5 - 页面结构
  • CSS3 - 样式设计
  • Bootstrap 5 - UI框架
  • Font Awesome - 图标库
  • JavaScript - 交互逻辑

🔒 安全特性

1. 密码安全

  • BCrypt加密: 使用强度为12的BCrypt算法
  • 随机盐值: 每次加密生成不同的盐值
  • 密码强度检查: 前端实时验证密码复杂度

2. 会话安全

  • 单点登录: 每个用户只能有一个活跃会话
  • 自动超时: 会话自动过期机制
  • 安全登出: 完全清除会话和认证信息

3. 攻击防护

  • CSRF保护: 防止跨站请求伪造
  • 点击劫持防护: 防止页面被嵌入到其他网站
  • XSS防护: 输入验证和输出转义

4. 传输安全

  • HTTPS强制: 强制使用安全传输协议
  • 安全头设置: 配置各种安全HTTP头

📁 项目结构

src/
├── main/
│   ├── java/com/example/demo/
│   │   ├── config/
│   │   │   └── SecurityConfig.java          # Spring Security配置
│   │   ├── controller/
│   │   │   ├── LoginController.java         # 登录控制器
│   │   │   └── ApiController.java           # API控制器
│   │   ├── model/
│   │   │   └── User.java                    # 用户实体类
│   │   ├── service/
│   │   │   ├── PasswordService.java         # 密码服务
│   │   │   └── UserService.java             # 用户服务
│   │   └── Demo6Application.java            # 主应用类
│   └── resources/
│       ├── templates/                       # Thymeleaf模板
│       │   ├── login.html                   # 登录页面
│       │   ├── register.html                # 注册页面
│       │   ├── dashboard.html               # 仪表板
│       │   └── profile.html                 # 个人资料
│       └── application.properties           # 应用配置
├── test/                                    # 测试代码
└── pom.xml                                  # Maven配置

🔧 核心组件详解

1. 密码服务 (PasswordService)

@Service
public class PasswordService {private final PasswordEncoder passwordEncoder;public PasswordService() {// 使用BCrypt算法,强度为12this.passwordEncoder = new BCryptPasswordEncoder(12);}// 加密密码public String encodePassword(String rawPassword) {return passwordEncoder.encode(rawPassword);}// 验证密码public boolean matches(String rawPassword, String encodedPassword) {return passwordEncoder.matches(rawPassword, encodedPassword);}
}

安全要点:

  • BCrypt强度12是推荐值,平衡了安全性和性能
  • 每次加密都会生成不同的盐值
  • 验证时自动提取盐值进行比较

2. 用户服务 (UserService)

@Service
public class UserService {@Autowiredprivate PasswordService passwordService;// 使用ConcurrentHashMap保证线程安全private final Map<String, User> users = new ConcurrentHashMap<>();public UserService() {// 构造函数中不要使用@Autowired的依赖!// 使用@PostConstruct确保依赖注入完成后再初始化}/*** 初始化测试用户* 使用@PostConstruct确保在所有依赖注入完成后执行*/@PostConstructprivate void initializeTestUser() {User testUser = new User();testUser.setId(1L);testUser.setUsername("admin");testUser.setEmail("admin@example.com");testUser.setEnabled(true);testUser.setCreatedAt(LocalDateTime.now());// 现在可以安全使用passwordService了testUser.setPassword(passwordService.encodePassword("admin123"));users.put(testUser.getUsername(), testUser);System.out.println("测试用户已创建: admin / admin123");}// 验证用户密码public boolean validatePassword(String username, String rawPassword) {User user = findByUsername(username);if (user == null || !user.isEnabled()) {return false;}return passwordService.matches(rawPassword, user.getPassword());}
}

安全要点:

  • 使用线程安全的ConcurrentHashMap
  • 检查用户是否存在和是否启用
  • 密码验证失败不泄露用户存在信息

3. Spring Security配置 (SecurityConfig)

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http// 配置认证提供者.authenticationProvider(authenticationProvider())// 配置访问权限.authorizeHttpRequests(authz -> authz// 允许所有人访问登录页面和静态资源.requestMatchers("/login", "/register", "/css/**", "/js/**", "/images/**", "/favicon.ico").permitAll()// 其他所有请求都需要认证.anyRequest().authenticated())// 配置表单登录 - 重要:登录页面和处理URL要分开!.formLogin(form -> form.loginPage("/login")                    // 显示登录页面的URL (GET).loginProcessingUrl("/perform_login")   // 处理登录请求的URL (POST).usernameParameter("username")          // 用户名参数名.passwordParameter("password")          // 密码参数名.successHandler(successHandler())       // 登录成功处理器.failureHandler(failureHandler())       // 登录失败处理器.permitAll())// 配置登出.logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/login?logout=true").invalidateHttpSession(true)            // 使HTTP会话失效.clearAuthentication(true)              // 清除认证信息.deleteCookies("JSESSIONID")            // 删除会话Cookie.permitAll())// 配置会话管理.sessionManagement(session -> session.maximumSessions(1)                     // 每个用户最多一个会话.maxSessionsPreventsLogin(false)        // 不阻止新登录,而是踢掉旧会话.sessionRegistry(sessionRegistry()))// 启用CSRF保护.csrf(csrf -> csrf.ignoringRequestMatchers("/api/**")     // API请求忽略CSRF)// 配置HTTP安全头 - 使用新的API.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.deny())  // 防止点击劫持.contentTypeOptions(contentTypeOptions -> {})       // 防止MIME类型嗅探.httpStrictTransportSecurity(hstsConfig -> hstsConfig.maxAgeInSeconds(31536000)          // HSTS有效期1年.includeSubDomains(true)            // 包含子域名));return http.build();}
}

安全要点:

  • 配置访问权限规则
  • 自定义登录成功/失败处理器
  • 启用CSRF保护
  • 设置安全HTTP头

🔐 安全实现原理

1. 密码加密流程

用户输入密码
前端验证
发送到后端
BCrypt加密
生成随机盐值
存储加密密码
用户登录
输入密码
BCrypt验证
提取盐值
比较哈希值
返回验证结果

2. 会话管理流程

用户登录
创建会话
生成JSESSIONID
存储到服务器
返回Cookie
后续请求
携带Cookie
验证会话
会话有效?
允许访问
重定向登录
用户登出
清除会话
删除Cookie
重定向登录页

3. CSRF防护机制

用户访问页面
生成CSRF Token
嵌入表单
用户提交表单
验证CSRF Token
Token有效?
处理请求
拒绝请求

🚀 部署和运行

1. 环境要求

  • Java 17+
  • Maven 3.6+
  • 现代浏览器

2. 运行步骤

# 1. 克隆项目
git clone <项目地址>
cd demo6# 2. 编译项目
mvn clean compile# 3. 运行应用
mvn spring-boot:run# 或者使用Maven Wrapper(推荐)
./mvnw spring-boot:run        # Linux/Mac
./mvnw.cmd spring-boot:run    # Windows

⚠️ 新手注意事项

  1. 确保Java版本: Spring Boot 3.x需要Java 17+

    java -version  # 检查Java版本
    
  2. 确保Maven可用:

    mvn -version   # 检查Maven版本
    
  3. 启动成功标志: 看到以下信息表示启动成功

    Started Demo6Application in 2.xxx seconds
    
  4. 端口占用: 如果8080端口被占用,可以修改application.properties:

    server.port=8081
    

3. 访问应用

  • 应用地址: http://localhost:8080
  • 登录页面: http://localhost:8080/login
  • 注册页面: http://localhost:8080/register

4. 测试API

# 获取当前用户信息
curl -u admin:admin123 http://localhost:8080/api/user/current# 健康检查
curl http://localhost:8080/api/health

🛡 安全评估和改进建议

🔍 当前方案安全性分析

安全优势
  • BCrypt密码加密(强度12)- 业界标准
  • CSRF攻击防护
  • 会话管理和单点登录
  • 基础的HTTP安全头设置
⚠️ 主要安全风险
  1. 数据存储风险(高风险)

    • 使用内存存储,数据易丢失
    • 无法水平扩展
    • 缺乏数据备份
  2. 传输安全风险(高风险)

    • 使用HTTP传输,密码可被截获
    • 缺乏HTTPS强制跳转
  3. 访问控制风险(中风险)

    • 无登录失败次数限制
    • 无账户锁定机制
    • 容易遭受暴力破解
  4. 审计和监控风险(中风险)

    • 缺乏登录日志记录
    • 无异常行为检测
    • 难以追踪安全事件

🚀 安全改进方案

1. 立即改进(高优先级)

A. 启用HTTPS

# application.properties
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=your-password
server.ssl.key-store-type=PKCS12

B. 数据库持久化

// 替换内存存储
@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(unique = true, nullable = false)private String username;// ...
}

C. 登录限制

@Service
public class LoginAttemptService {private final Map<String, Integer> attemptsCache = new ConcurrentHashMap<>();public void loginFailed(String username) {int attempts = attemptsCache.getOrDefault(username, 0);attemptsCache.put(username, attempts + 1);}public boolean isBlocked(String username) {return attemptsCache.getOrDefault(username, 0) >= 5;}
}
2. 中期改进

A. 输入验证增强

@Component
public class InputValidator {public boolean isValidEmail(String email) {String emailRegex = "^[A-Za-z0-9+_.-]+@([A-Za-z0-9.-]+\\.[A-Za-z]{2,})$";return email.matches(emailRegex);}public boolean isStrongPassword(String password) {// 至少8位,包含大小写、数字、特殊字符return password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$");}
}

B. 审计日志

@Entity
public class SecurityLog {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String action; // LOGIN_SUCCESS, LOGIN_FAILED, LOGOUTprivate String ipAddress;private LocalDateTime timestamp;private String userAgent;
}
3. 长期改进

A. 双因素认证

@Service
public class TwoFactorService {public String generateQRCode(String username) {String secret = generateSecret();return QRCodeGenerator.generate(username, secret);}public boolean verifyTOTP(String secret, String code) {return TOTPGenerator.verify(secret, code);}
}

B. 密码策略

@Service
public class PasswordPolicyService {public void enforcePasswordPolicy(User user, String newPassword) {// 检查密码历史// 强制定期更换// 检查常见密码字典}
}

🛡 安全最佳实践

1. 密码安全

  • ✅ 使用强密码策略
  • ✅ 密码长度至少8位
  • ✅ 包含大小写字母、数字、特殊字符
  • ✅ 定期更换密码
  • ❌ 不要在代码中硬编码密码
  • ❌ 不要使用弱密码

2. 会话安全

  • ✅ 使用HTTPS传输
  • ✅ 设置合理的会话超时时间
  • ✅ 登出时清除所有会话信息
  • ✅ 实现单点登录
  • ❌ 不要在URL中传递敏感信息
  • ❌ 不要使用可预测的会话ID

3. 输入验证

  • ✅ 前端和后端双重验证
  • ✅ 使用白名单验证
  • ✅ 转义特殊字符
  • ✅ 限制输入长度
  • ❌ 不要信任用户输入
  • ❌ 不要直接输出用户输入

4. 错误处理

  • ✅ 记录安全相关错误
  • ✅ 不泄露敏感信息
  • ✅ 使用通用错误消息
  • ❌ 不要在错误中暴露系统信息
  • ❌ 不要记录密码等敏感信息

❓ 常见问题解答

Q1: 为什么登录后页面只是刷新,没有跳转?

A: 这是最常见的新手问题!原因通常是:

  • 错误做法: 直接打开HTML文件(file:// 协议)
  • 正确做法: 通过Spring Boot应用访问(http://localhost:8080)
  • 解决方案:
    1. 启动Spring Boot应用:mvn spring-boot:run
    2. 在浏览器访问:http://localhost:8080/login
    3. 不要双击打开HTML文件!

Q2: 为什么登录页面和处理URL要分开?

A: 这是Spring Security的重要概念:

  • /login (GET请求) - 显示登录页面
  • /perform_login (POST请求) - 处理登录逻辑
  • 如果两个URL相同会导致冲突,登录失败
  • HTML表单的action必须指向处理URL

Q3: 为什么要使用BCrypt而不是MD5或SHA?

A: BCrypt是专门为密码哈希设计的算法,具有以下优势:

  • 内置盐值生成,防止彩虹表攻击
  • 可调节计算成本,适应硬件发展
  • 抗暴力破解能力强
  • MD5和SHA是快速哈希算法,不适合密码存储

Q2: 如何选择合适的BCrypt强度?

A: 强度选择建议:

  • 开发环境:8-10
  • 生产环境:10-12
  • 高安全要求:12-14
  • 强度越高越安全,但计算时间也越长

Q3: 为什么需要CSRF保护?

A: CSRF攻击原理:

  • 攻击者诱导用户访问恶意网站
  • 恶意网站向目标网站发送请求
  • 浏览器自动携带用户的认证Cookie
  • 目标网站误认为是用户操作

Q4: 启动时出现"Cannot invoke passwordService.encodePassword because this.passwordService is null"错误?

A: 这是依赖注入时机问题:

  • 原因: 在构造函数中使用了@Autowired的依赖
  • 错误做法:
    public UserService() {// 此时passwordService还未注入initializeTestUser(); // 会报错
    }
    
  • 正确做法: 使用@PostConstruct注解
    @PostConstruct
    private void initializeTestUser() {// 此时所有依赖都已注入完成
    }
    

Q5: 如何防止会话劫持?

A: 防护措施:

  • 使用HTTPS传输
  • 设置HttpOnly Cookie
  • 实现会话超时
  • 使用安全的会话ID生成算法

Q6: 出现"程序包javax.servlet.http不存在"编译错误?

A: 这是Spring Boot 3.x的包迁移问题:

  • 原因: Spring Boot 3.x使用Jakarta EE,不再使用Java EE
  • 错误做法: import javax.servlet.http.HttpServletRequest;
  • 正确做法: import jakarta.servlet.http.HttpServletRequest;
  • 解决方案: 将所有javax.servlet改为jakarta.servlet

Q7: 前端验证是否足够?

A: 前端验证只是第一道防线:

  • 可以被绕过或禁用
  • 主要用于用户体验
  • 后端验证是必须的
  • 两者结合使用最佳

🚀 进阶扩展

1. 数据库集成

// 使用JPA替换内存存储
@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(unique = true, nullable = false)private String username;@Column(nullable = false)private String password;// 其他字段...
}

2. 角色权限管理

// 添加角色和权限
@Entity
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@ManyToMany(mappedBy = "roles")private Set<User> users;
}

3. 双因素认证

// 集成TOTP双因素认证
@Service
public class TwoFactorService {public String generateSecretKey() {return new GoogleAuthenticator().createCredentials().getKey();}public boolean verifyCode(String secret, int code) {return new GoogleAuthenticator().authorize(secret, code);}
}

4. 登录日志

// 记录登录活动
@Entity
public class LoginLog {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String ipAddress;private LocalDateTime loginTime;private boolean success;private String userAgent;
}

5. 密码重置功能

// 实现密码重置
@Service
public class PasswordResetService {public void sendResetEmail(String email) {String token = generateResetToken();// 发送邮件}public void resetPassword(String token, String newPassword) {// 验证token并重置密码}
}

📚 学习资源

官方文档

  • Spring Security官方文档
  • Spring Boot官方文档
  • BCrypt算法说明

安全标准

  • OWASP Top 10
  • NIST密码指南
  • RFC 7519 JWT标准

推荐书籍

  • 《Spring Security实战》
  • 《Web应用安全权威指南》
  • 《密码学与网络安全》

🎉 总结

这个安全登录系统展示了现代Web应用安全的核心概念和最佳实践:

  1. 密码安全: 使用BCrypt加密存储
  2. 会话管理: 安全的会话创建和销毁
  3. 攻击防护: CSRF、XSS、点击劫持防护
  4. 传输安全: HTTPS和安全头设置
  5. 用户体验: 响应式界面和友好提示

通过学习这个项目,你将掌握:

  • Spring Security的基本配置和使用
  • 密码加密和验证的最佳实践
  • Web安全攻击的防护方法
  • 前后端安全协作的实现

记住:安全是一个持续的过程,不是一次性的配置。随着威胁的不断演变,我们需要持续学习和改进我们的安全措施。


📞 技术支持

如果你在学习过程中遇到问题,可以:

  1. 查看项目代码注释
  2. 阅读Spring Security官方文档
  3. 参考OWASP安全指南
  4. 在开发者社区寻求帮助

祝你学习愉快! 🎓

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

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

相关文章

星辰诞愿——生日快乐

前言 今天这篇博客并非技术文章&#xff0c;而是庆祝我可爱的妹妹18岁生日以及介绍我半年以来的学习经历 祝生网站&#xff1a;星辰诞愿(用户列表里第一位就是我妹妹&#xff0c;希望大家能献上自己的祝福&#xff0c;能分享转发更好&#xff0c;我在此感谢大家。如果使用手机&…

基于STM32单片机的智能粮仓温湿度检测蓝牙手机APP设计

基于STM32单片机的智能粮仓温湿度检测蓝牙手机APP设计 1 系统功能介绍 本系统是一款基于STM32单片机的智能粮仓环境监测与控制装置&#xff0c;核心目标是通过传感器实时采集粮仓内的温度和湿度信息&#xff0c;并结合蓝牙通信模块将数据传输至手机端&#xff0c;实现对粮仓环境…

简单视频转换器 avi转mp4

直接上代码package com.example.videoconverter;import ws.schild.jave.Encoder; import ws.schild.jave.EncoderException; import ws.schild.jave.MultimediaObject; import ws.schild.jave.encode.AudioAttributes; import ws.schild.jave.encode.EncodingAttributes; impor…

Kafka 与 RocketMQ 核心概念与架构对比

Kafka 与 RocketMQ 核心概念与架构对比DeepSeek生成&#xff0c;便于记忆大概逻辑核心概念对比图 #mermaid-svg-dEbo1XpAjfzOjvUW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dEbo1XpAjfzOjvUW .error-icon{fill…

30分钟深度压测cuBLAS:从FP64到INT8全精度性能剖析

在深度学习和高性能计算领域&#xff0c;GPU的矩阵运算性能是衡量系统算力的核心指标之一。NVIDIA的cuBLAS库作为CUDA平台上最基础的线性代数计算库&#xff0c;其性能表现直接影响着上层应用的运行效率。本文将详细介绍如何使用cublasmatmulbench工具对多GPU进行全面的性能基准…

超越模仿:探寻智能的本源

引言&#xff1a;超越模仿&#xff0c;探寻智能的本源近年来&#xff0c;以大语言模型&#xff08;LLM&#xff09;为代表的自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;在模仿人类语言生成方面取得了令人瞩目的成就。从流畅的对话到精炼的文本摘要&#xff0c;机…

ROS/ROS2课程笔记00-大纲-25-26-1

大纲 AI版 以下是基于第四代高校课程核心理念设计的《ROS2机器人程序设计&#xff08;ROS2 Jazzy版&#xff09;》课程大纲&#xff0c;突出智能互联、跨学科融合、终身学习等特征&#xff0c;并融入技术赋能、生态重塑、素养导向等要求&#xff1a; 课程名称&#xff1a;ROS…

Linux内核进程管理子系统有什么第四十六回 —— 进程主结构详解(42)

接前一篇文章&#xff1a;Linux内核进程管理子系统有什么第四十五回 —— 进程主结构详解&#xff08;41&#xff09; 本文内容参考&#xff1a; Linux内核进程管理专题报告_linux rseq-CSDN博客 《趣谈Linux操作系统 核心原理篇&#xff1a;第三部分 进程管理》—— 刘超 《…

Linux网络连接不上?NetworkManager提示“device not managed“!

#操作系统 #Linux #NetworkManager适用环境kylin v10Centos 8Redhat 8一、故障现象在CentOS/RHEL(同样适用于kylin v10&#xff09;系统中&#xff0c;管理员执行 nmcli connection up ens160 命令尝试激活名为 ens160 的网络连接时&#xff0c;遇到以下错误&#xff1a;[roo…

【系统分析师】第2章-基础知识:数学与工程基础(核心总结)

更多内容请见: 备考系统分析师-专栏介绍和目录 文章目录 一、数学统计基础 1.1 概率论基础 1.2 数理统计基础 1.3 常用统计分析方法 二、图论应用 2.1 基本概念 2.2 核心算法与应用 三、预测与决策 3.1 预测方法 3.2 决策方法 四、数学建模 4.1 建模过程 4.2 常用模型类型 五、…

StrUtil.isBlank()

这段代码是一个条件判断&#xff0c;用于检查变量 shopJson 是否为空或空白&#xff0c;如果是&#xff0c;就直接返回 null。我们来逐句讲解&#xff1a;原始代码&#xff1a; if(StrUtil.isBlank(shopJson)) {// 3.存在&#xff0c;直接返回return null; }逐句解释&#xff1…

mysql 回表查询(二次查询,如何检查,如何规避)

h5打开以查看 “回表查询”通常发生在使用二级索引&#xff08;Secondary Index&#xff09;的查询中。当查询所需的数据列并不全部包含在二级索引中时&#xff0c;即使使用了索引&#xff0c;MySQL 也需要根据索引记录中的主键值&#xff0c;回到聚簇索引&#xff08;Cluster…

深度学习(二):神经元与神经网络

在人工智能的浪潮中&#xff0c;神经网络&#xff08;Neural Networks&#xff09;无疑是驱动核心技术的引擎&#xff0c;它赋予了计算机前所未有的学习和识别能力。而这一切的起点&#xff0c;是受到生物大脑中基本单元——神经元&#xff08;Neurons&#xff09;的深刻启发。…

JavaScript 行为型设计模式详解

1. 观察者模式1.1. 使用场景观察者模式用于对象间的一对多依赖关系&#xff0c;当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都能收到通知并自动更新。常用于事件处理、通知系统。在前端中&#xff0c;观察者模式用于实现事件监听、数据绑定等功能。1.2. 代码实现…

指令查找表LUT

本文整理自22. FlexSPI—读写外部SPI NorFlash — [野火]i.MX RT库开发实战指南——基于i.MXRT1052 文档 用作个人学习和分享 指令查找表LUT 访问FLASH存储器通常包含一些读写功能的的控制指令&#xff0c;主控设备可通过这些指令访问FLASH存储器。 为了适应这种需求&#…

uv使用指南

&#x1f680; Python 打包工具 UV 使用指南 UV 是一个用 Rust 编写的极速 Python 包管理器和解析器&#xff0c;旨在成为 pip、pip-tools、virtualenv 等工具的单一替代方案。 &#x1f4cb; 目录 核心概念与设计哲学安装与配置基础使用方法项目管理与工作流高级功能与技巧…

安卓学习 之 图片控件和图片按钮

今天学习的是ImageView 和 ImageButton这两个控件还是比较简单的&#xff1a;先来看看最后的样式图片吧&#xff1a;从图片中可以看到ImageView中的图片要大很多&#xff0c;这是因为中的ImageView中的图片跟ImageView控件的大小而自动调整。Imag…

动态规划-学习笔记

这是一份动态规划&#xff08;Dynamic Programming, DP&#xff09;完整学习笔记。笔记将从一星难度&#xff08;入门&#xff09;到五星难度&#xff08;进阶&#xff09;&#xff0c;循序渐进&#xff0c;涵盖核心思想、经典模型和解题方法论。 本来打算今天更新背包问题的题…

Linux 可信启动深度解析:从UEFI到操作系统的信任链

文章目录引言一、 可信根基&#xff1a;TPM与核心概念1.1 什么是“度量” (Measurement)&#xff1f;1.2 信任链与TPM PCR二、 阶段一&#xff1a;固件的可信启动 (UEFI)2.1 引导的起点&#xff1a;从SEC到DXE的初始化2.2 引导设备选择 (BDS)&#xff1a;UEFI如何找到GRUB2.3 S…

61-python中面向对象三大特性

前言&#xff1a; 面向对象编程&#xff0c;是许多编程语言都支持的一种编程思想。简单理解是&#xff1a;基于模板&#xff08;类&#xff09;去创建实体&#xff08;对象&#xff09;&#xff0c; 使用对象完成功能开发。面向对象包含三大主要特性&#xff1a; 封装 继承 多态…