什么是缓存穿透、缓存雪崩、缓存击穿?
什么是缓存?
缓存就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。
怎么防止缓存穿透?
缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,给数据库带来巨大压力。
常见的解决方案有两种:
缓存空对象
客户端第一次请求是,发现数据库中数据不存在,在缓存中设置该值为空串,后面的请求中若发现缓存中存储的值为空串直接返回空串,不在查询数据库。(缓存需要设置一定时间内过期,防止数据库中有数据后缓存仍然为空。或者在插入数据时,清空缓存)
- 优点:实现简单,维护方便
- 缺点:额外的内存消耗,可能造成短期的不一致
/*** 设置空值解决缓存穿透*/public Shop queryWithPassThrough(Long id){//先从redis查询商铺缓存,若存在,从redis中返回,否则查询数据库,存在写入redis,并返回String shopJson = stringRedisTemplate.opsForValue().get("cache:shop:" + id);if(StringUtils.isNotBlank(shopJson)){Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//判断命中的是否为空,防止缓存穿透if(shopJson==null){ //若为null,说明redis中数据为空字符串,说明mysql数据库也没有数据return null;}//redis不存在,查询数据库Shop shop = getById(id);if(shop==null){//将空值写入redisstringRedisTemplate.opsForValue().set("cache:shop:"+id,"",30, TimeUnit.MINUTES);return null;}stringRedisTemplate.opsForValue().set("cache:shop:"+id,JSONUtil.toJsonStr(shop));return shop;}
布隆过滤
- 优点:内存占用较少,没有多余key
- 缺点:实现复杂、存在误判可能
其他方案:
•增强id的复杂度,避免被猜测id规律
•做好数据的基础格式校验
•加强用户权限校验
•做好热点参数的限流
为什么会出现缓存雪崩?
缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
解决方案:
- 给不同的Key的TTL添加随机值
- 利用Redis集群提高服务的可用性
- 给缓存业务添加降级限流策略
- 给业务添加多级缓存
如何解决缓存击穿?
缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。
常见的解决方案有两种:
互斥锁
在高并发环境下,当有一个线程获得锁访问数据库时,其他线程等待。假如业务A需要获取缓存A和缓存B,而业务B需要获取缓存B和缓存A。此时业务A已经获取了缓存A的锁正在等待缓存B,而业务B获取了缓存B的锁等待缓存A,就出现了互相等待的情况,产生死锁。
优点:没有额外的内存消耗,保证一致性,实现简单
缺点:线程需要等待,性能受影响,可能有死锁风险
/*** 在设置空值,已经解决缓存穿透的基础上,添加互斥锁解决缓存击穿*/public Shop queryWithMutex (Long id){//先从redis查询商铺缓存,若存在,从redis中返回,否则查询数据库,存在写入redis,并返回String shopJson = stringRedisTemplate.opsForValue().get("cache:shop:" + id);if(StringUtils.isNotBlank(shopJson)){Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//判断命中的是否为空,房子缓存穿透if(shopJson==null){ //部位null,说明redis中数据为空字符串,说明mysql数据库也没有数据return null;}//redis不存在,失效缓存重建//获取互斥锁,每个店铺创建一个锁String LockKey = "lock:shop:"+id;Shop shop = null;try {boolean isLock = tryLock(LockKey);//获取锁失败,休眠重试if(!isLock){Thread.sleep(50);return queryWithMutex(id);}//获取到锁,查询数据库shop = getById(id);if(shop==null){//将空值写入redisstringRedisTemplate.opsForValue().set("cache:shop:"+id,"",30, TimeUnit.MINUTES);return null;}stringRedisTemplate.opsForValue().set("cache:shop:"+id,JSONUtil.toJsonStr(shop));}catch (InterruptedException e){throw new RuntimeException("系统异常");}finally {//释放锁unLock(LockKey);}return shop;}/***获取锁*/private boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);}/*** 释放锁*/private void unLock(String key){stringRedisTemplate.delete(key);}
逻辑过期:
优点:线程无需等待,性能较好
缺点:不保证一致性,有额外内存消耗,实现复杂
//线程池
private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);/*** 使用逻辑过期解决缓存击穿(实际上数据不会过期,故不需要考虑缓存穿透问题),使用时需要先缓存热点数据*/public Shop queryWithLogicalExpire (Long id){//先从redis查询商铺缓存,若存在,从redis中返回,否则查询数据库,存在写入redis,并返回String shopJson = stringRedisTemplate.opsForValue().get("cache:shop:" + id);//缓存中不存在,直接返回null。(热点数据,通过一般需要自行初始化到redis缓存中,一般不会出现null的情况)if(StringUtils.isBlank(shopJson)){return null;}RedisData redisData = JSONUtil.toBean(shopJson, RedisData.class);Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);//获取缓存数据LocalDateTime expireTime = redisData.getExpireTime();//获取缓存过期时间//判断是否过期if(expireTime.isAfter(LocalDateTime.now())){//未过期,直接返回return shop;}//过期,需要缓存重建//获取互斥锁String LockKey = "lock:shop:"+id;if(tryLock(LockKey)){//获取锁成功,开启独立线程,实现缓存重建CACHE_REBUILD_EXECUTOR.submit(() ->{//重建缓存try{this.saveShop2Redis(id,20L);}catch (Exception e){throw new RuntimeException(e);}finally {//释放锁unLock(LockKey);}});}return shop;}public void saveShop2Redis(Long id,Long expireSeconds){//查询店铺数据Shop shop = getById(id);//封装逻辑过期时间RedisData redisData = new RedisData();redisData.setData(shop);redisData.setExpireTime(LocalDateTime.now().plusMinutes(expireSeconds));//写入redisstringRedisTemplate.opsForValue().set("cache:shop:"+id,JSONUtil.toJsonStr(redisData));}/***获取锁*/private boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);}/*** 释放锁*/private void unLock(String key){stringRedisTemplate.delete(key);}
全局ID生成器
如果使用数据库自增ID就存在一些问题:
- id的规律性太明显
- 受单表数据量的限制
全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:
为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其它信息:
ID的组成部分:
- 符号位:1bit,永远为0
- 时间戳:31bit,以秒为单位,可以使用69年
- 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID
Redis自增ID策略:
- 每天一个key,方便统计订单量
- ID构造是 时间戳 + 计数器
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;@Component
public class RedisIdWorker {private StringRedisTemplate stringRedisTemplate;public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}// 2022年开始时间戳private static final long BEGIN_TIMESTAMP = 1640995200L;// 序列号位数private static final int COUNT_BITS = 32;public long nextId(String KeyPrefix) {// 1.生成时间戳LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond-BEGIN_TIMESTAMP;// 2.生成序列号String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));//自增长,返回自增序列号,key不存在会自动创建一个keylong count = stringRedisTemplate.opsForValue().increment("icr:" + KeyPrefix + ":" + date);// 3.拼接并返回// 时间戳左移32位,通过|运算,拼接序列号return timestamp << COUNT_BITS | count;}
}
相关文章:
什么是缓存穿透、缓存雪崩、缓存击穿?
什么是缓存? 缓存就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。 怎么防止缓存穿透? 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到…...
洛谷题单3-P4956 [COCI 2017 2018 #6] Davor-python-流程图重构
题目描述 在征服南极之后,Davor 开始了一项新的挑战。下一步是在西伯利亚、格林兰、挪威的北极圈远征。 他将在 2018 年 12 月 31 日开始出发,在这之前需要一共筹集 n 元钱。 他打算在每个星期一筹集 x 元,星期二筹集 xk 元,……...
解决浏览器报错Mixed Content
前端代码写死了访问后端的请求为:http://service.xxx.com:8080/api/,前端代码中混合内容(Mixed Content) 导致的。浏览器使用https访问站点时,这个请求会被拦截,并且浏览器打印 login.vue:151 Mixed Conten…...
HCIP【BGP协议(详解)】
目录 1 BGP协议产生背景 2 BGP协议特性 2.1 自治系统间路由传播 2.2 路由矢量协议 2.3 防环机制 2.4 基于TCP传输 2.5 路由更新机制 2.6 丰富的路由属性 2.7 支持CIDR和路由聚合 2.8 路由过滤和策略控制 2.9 动态对等体功能 3 BGP基本术语 4 BGP规划问题 4.1 路…...
集合与容器:List、HashMap(II)
一、ArrayList 是集合框架中最核心的动态数组实现,高频使用的容器之一。 1. 核心数据结构 基于数组实现,维护elementData数组存储元素: transient修饰的elementData不会被默认序列化(通过自定义序列化逻辑优化存储)…...
mac 安装MySQL
1、打开官网,点击Downloads 2、在downloads页面选择MySQL Community Server 3、选择对应的设备和版本,点击下载 4、下载选择 5、下载完成后,点击安装 6、next 到Configguration 时要输入密码(千万别忘记) 7.最后输…...
Pascal语言的软件开发工具
使用Pascal语言的软件开发工具 引言 随着计算机科学的发展,编程语言层出不穷,程序员们在开发时可以选择多种多样的工具。而Pascal语言作为一种历史悠久的程序设计语言,尽管在当今编程语言的生态中已不再是主流,但其优雅的语法和…...
vue组件开发:什么是VUE组件?
什么是VUE组件 在我们实际开发过程中你也许会发现有很多代码是重复的,它们可能是一个按钮、一个表单、一个列表等等,其中最为显著的应该是列表。 以CSDN的首页为例: 上述截图中的文章列表可能会在多处出现,比如此截图是精选博客…...
如何在Springboot的Mapper中轻松添加新的SQL语句呀?
在如今的软件开发界,Spring Boot可是非常受欢迎的框架哦,尤其是在微服务和RESTful API的构建上,真的是让人爱不释手!今天,我们就来聊聊如何为Spring Boot项目中的Mapper添加新的SQL语句吧!说起来࿰…...
微服务架构: SpringCloud服务注册与发现详解
# 微服务架构: SpringCloud服务注册与发现详解 一、什么是微服务架构 微服务架构简介 微服务架构(Microservices Architecture)是一种以一组小型服务应用程序构建系统的软件架构风格。每个服务运行在自己的进程中,通过精简的HTTP API进行通信…...
现代简约杂志海报包装网页设计无衬线英文字体安装包 Seriusans – Condensed Sans Display Font
Seriusans 是一种 Condensed Sans Display 字体,将现代简约与大胆融为一体。其狭窄而醒目的字体营造出强大的存在感,使其成为有影响力设计的绝佳选择,例如海报、杂志标题、品牌、包装、网页设计、运动图形、社论布局、广告活动、企业演示&…...
C/C++的条件编译
一、什么是条件编译? 条件编译是指在编译阶段根据某些条件来决定是否编译某段代码。这通常通过预处理指令来实现,比如 #if、#ifdef、#ifndef、#else、#elif 和 #endif。 二、为什么使用条件编译? 跨平台开发:不同的操作…...
视野,,地面覆盖,重叠需求,FPS,飞行速度等的计算公式
一、计算相机视野与重叠需求 1. 相机参数 IDS UI-5280CP: 分辨率:2456x2054 像素。传感器:假设为 1/1.8" CMOS(常见型号),尺寸约 6.78 mm(宽) 5.67 mm(高…...
ARXML文件解析-1
目录 1 摘要2 ARXML文件2.1 作用及典型应用场景2.2 **ARXML文件的结构树**2.3 TAG(XML元素)2.4 ARXML文件关键元素解析2.4.1 XML声明与处理指令2.4.2 XML注释2.4.3 ADMIN-DATA元素2.4.3 语言相关元素2.4.5 AR-PACKAGE体系结构2.4.6. 数据转换框架2.4.7 S…...
传统开发者视角:智能合约与区块链数据库探秘
前言 在上一篇文章:探秘区块链开发:智能合约在 DApp 中的地位及与传统开发差异中我为大家从传统开发者的角度讲解了一下什么是智能合约。 简单的来说智能合约对于传统前端开发者可以说是API接口,而后端开发者则可以说是负责接口逻辑的程序。 然而从传统的开发意识跳跃到D…...
游戏引擎学习第204天
回顾并为今天的内容做铺垫 好,现在开始这一集。今天我们将进行一些用户界面编程,觉得这是一个展示如何编写这类代码的好时机。很多人对如何做用户界面代码都很好奇,所以展示一下如何编写是非常有意义的。 我之所以在现在的这个地方做这些工…...
蓝桥杯2024年第十五届省赛真题-R 格式
题目链接: 思路: 通过数组模拟d的每一位,逐位进行计算,从而实现对d的精确处理。 代码: #include<bits/stdc.h> #define int long long using namespace std; const int N 2020;int n; string s; vector<i…...
Haskell语言的区块链安全
Haskell语言在区块链安全中的应用 引言 随着区块链技术的发展,它已经成为金融、供应链管理、身份认证等多个领域的重要基础设施。然而,区块链的安全性问题一直是行业关注的焦点。为了确保区块链的安全性,开发者需要选择合适的编程语言来编写…...
BUUCTF-web刷题篇(11)
20.admin 这道题很可能用admin或者伪造admin进行登录,用admin进行登录,随便填写密码进不去,发现页面有register、login,用admin注册提示已经被注册。 方法一:(burp爆破) 进入登陆界面&#x…...
TensorFlow
TensorFlow 是一个由 Google 开发并开源的机器学习和深度学习库,被广泛应用于各类机器学习项目。以下为你详细介绍: 概述 TensorFlow 最初是为了满足 Google 内部大规模机器学习需求而研发,后于 2015 年开源。它提供了一个强大且灵活的生态…...
分子生成的深层次层次变分自编码器 - DrugHIVE 测评
一、背景介绍 DrugHIVE 来源于南加州大学定量与计算生物学系的 Remo Rohs 为通讯作者的文章:《Structure-Based Drug Design with a Deep Hierarchical Generative Model》。文章链接:https://pubs.acs.org/doi/10.1021/acs.jcim.4c01193。该文章在 202…...
54.大学生心理健康管理系统(基于springboot项目)
目录 1.系统的受众说明 2.相关技术 2.1 B/S结构 2.2 MySQL数据库 3.系统分析 3.1可行性分析 3.1.1时间可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.1.4 技术可行性 3.1.5 法律可行性 3.2系统流程分析 3.3系统功能需求分析 3.4 系统非功能需求分析 4.系统设计…...
Linux文件特殊权限管理及进程和线程
acl 权限优先级 拥有者 > 特殊指定用户 > 权限多的组 >权限少的组 > 其他 mask阈值 mask是能够赋予指定用户权限的最大阀值 当设定完毕文件的acl列表之后用chmod缩小了文件拥有组的权力 mask会发生变化 恢复: setfacl -m m: 权限 :rwx 文件/…...
Vue2+Vue3 45-90集学习笔记
Vue2Vue3 45-90集学习笔记 小兔鲜首页 页面开发思路: 分析页面,按模块拆分组件,搭架子(局部注册或全局注册) 局部注册:App.js中 导入(import),注册(compon…...
【Web 服务器】的工作原理
🌐 Web 服务器的工作原理 Web 服务器的主要作用是 接收客户端请求(通常是浏览器发出的 HTTP/HTTPS 请求),处理请求,并返回相应的数据(如网页、图片、API 响应等)。 📌 工作流程 1️…...
LeetCode 5 -- 区间DP | 中心拓展算法
题目描述 最长回文子串 数据规模为 5e5,必须 manacher 算法 1. DP 由于 r e v e r s e ( ) reverse() reverse() 的时间复杂度是 O ( N ) O(N) O(N),因此暴力肯定是不行的。 d p dp dp 的思路:如果 s [ l . . r ] s[l..r] s[l..r] 是一个…...
IntelliJ IDEA中Spring Boot 3.4.x+集成Redis 7.x:最新配置与实战指南
前言 Spring Boot 3.4.x作为当前最新稳定版本,全面支持Java 17与Jakarta EE 10规范。本文以Spring Boot 3.4.1和Redis 7.x为例,详解如何在IDEA中快速接入Redis,涵盖最新依赖配置、数据序列化优化、缓存注解及高…...
数仓建模中计算累计销量
在数仓建模中计算累计销量,通常需要结合时间维度和业务逻辑设计合理的模型与计算逻辑。以下是分步骤的实现思路和示例: 1. 模型设计 累计销量的计算通常基于星型模型或雪花模型,核心结构包括: 事实表:记录每一笔销售…...
(多看) CExercise_05_1函数_1.2计算base的exponent次幂
题目: 键盘录入两个整数:底(base)和幂指数(exponent),计算base的exponent次幂,并打印输出对应的结果。(注意底和幂指数都可能是负数) 提示:求幂运算时,基础的思路就是先无脑把指数转…...
Pollard‘s Rho 算法
Pollard’s Rho 算法:一场数学与计算机科学的巧妙结合 在现代计算机科学中,素数分解、整数因子化问题有着广泛的应用,尤其是在密码学领域。然而,当面对一个大合数时,寻找其因子仍然是一个非常复杂的问题。我们常常依赖…...
8款分形长虹玻璃科幻渐变海报设计JPG背景素材 The Gradient Backgrounds Pack
天空从未如此美好 — 直到有人将日落洒在您的屏幕上。这些渐变是带有心跳的液体颜色,从熔化的金色转变为深紫色,就像地平线一样。 8 个背景中的每一个都以 45003000 像素和 300dpi 的速度脉冲,清晰到足以让您感觉自己可以直接踏入光芒中。但这…...
AIGC9——AIGC时代的用户体验革命:智能交互与隐私保护的平衡术
引言:当AI成为交互主角 2024年,淘宝AI客服"阿里小蜜"日均处理20亿次咨询,日本虚拟偶像"初音未来"演唱会门票3秒售罄——这些现象标志着AIGC已深度融入人机交互场景。但与此同时,过度个性化的推荐引发"信…...
vm虚拟机虚拟出网卡并ping通外网
在 Linux 和 Windows 系统中,即使不使用网络命名空间(namespace),也能实现虚拟网卡上网。以下是不同场景下的实现方法: 一、Linux 系统(不使用网络命名空间) 1. 直接创建虚拟网卡对(…...
基于时间卷积网络TCN实现电力负荷多变量时序预测(PyTorch版)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…...
ESXi8的部署过程
目录 一、系统安装 二、ESXI8的序列号 三、挂载硬盘和新建VMFS数据分区 四、通过数据存储浏览器上传下载文件 五、Windows远程桌面端口隐射 六、导出虚机 一、系统安装 1、使用UtrIOS系统制作ESXI8的启动盘; 2、服务器启动F8按键进入Popup启动选项,选择U盘启动; 3、安…...
IntelliJ IDEA 2020~2024 创建SpringBoot项目编辑报错: 程序包org.springframework.boot不存在
目录 前奏解决结尾 前奏 哈!今天在处理我的SpringBoot项目时,突然遇到了一些让人摸不着头脑的错误提示: java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…...
Windows 权限配置文件解析与安全分析(GPP,GPO,LSA)
在 Windows 网络环境中,权限配置文件用于管理用户权限、密码策略和访问控制,涵盖组策略首选项(GPP)、本地安全策略(LSA)、注册表以及 Active Directory 组策略(GPO) 等。这些配置文件…...
【微服务】基础概念
1.什么是微服务 微服务其实就是一种架构风格,他提倡我们在开发的时候,一个应用应该是一组小型服务而组成的,每一个服务都运行在自己的进程中,每一个小服务都通过HTTP的方式进行互通。他更加强调服务的彻底拆分。他并不是仅局限于…...
MYOJ_4342:(洛谷P1087)[NOIP 2004 普及组] FBI 树(二叉树实操,递归提高)
题目描述 我们可以把由 “0” 和 “1” 组成的字符串分为三类:全 “0” 串称为 B 串,全 “1” 串称为 I 串,既含 “0” 又含 “1” 的串则称为 F 串。 FBI 树是一种二叉树,它的结点类型也包括 F 结点,B 结点和 I 结点三…...
LLM(13):词编码后的位置
原则上,token 嵌入是大型语言模型(LLM)的合适输入。然而,LLM 的一个小缺点是它们的自注意力机制无法指导序列中 token 的位置或顺序。在前面介绍的嵌入层的工作方式中,无论 token ID 在输入序列中的位置如何࿰…...
MINIQMT学习课程Day4
聚宽的模拟/实盘跟单系统,已经全部介绍完毕,上传完毕了,相信大家已经可以进行聚宽的miniqmt的交易了。如果还有疑问,私信我进行沟通。 现在开始进入新的课题,如何学习python,我不教那些乱七八糟的ÿ…...
AWS云服务:大数据公司实现技术突破与商业价值的核心引擎
在数据驱动决策的时代,大数据公司面临着海量数据存储、实时计算、复杂分析及安全合规等核心挑战。如何高效构建弹性、可扩展且低成本的技术架构,成为企业能否在竞争中胜出的关键。亚马逊云科技(AWS)作为全球云计算领域的领导者&am…...
Openpyxl使用教程(包含处理大数据量案例)
文章目录 一、简介功能特性应用场景使用优势 二、常用方法1、工作簿wb2、工作表ws 三、案例1、创建新工作簿2、将Excel数据存入list中3、按行读取文件(适合大文件)4、按指定行读取文件(适合大文件) 一、简介 在 Python 数据处理领域,openpyxl 凭借其卓越的功能与易…...
蓝桥杯15届 宝石组合
问题描述 在一个神秘的森林里,住着一个小精灵名叫小蓝。有一天,他偶然发现了一个隐藏在树洞里的宝藏,里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状,但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝…...
THE UNIVERSITY OF MANCHESTER-NUMERICAL ANALYSIS 1-3.4数值积分-复合积分公式
3.4.1 复合梯形法则 梯形法则仅使用两个点来近似积分,显然对于大多数应用来说,这不足够。为了提高精度,有多种方法可以利用更多的点和函数值。正如我们刚才在Newton-Cotes方法和辛普森法则中所看到的,一种方法是使用更高阶的插值函数。另一种方法是将区间划分为更小的区间…...
嵌入式系统应用-拓展-相关开发软件说明
这里以STM32的系列产品为例子,利用MDK的集成开发平台进行开发过程中,所有相关软件安装说明。 1 集成开发环境安装 1.1 MDK 下载 1.1.1 官网下载 官方下载地址: https://www.keil.com/download/product/ 选择MDK-ARM ,填写一些…...
react实现上传图片到阿里云OSS以及问题解决(保姆级)
一、优势 提高上传速度:前端直传利用了浏览器与 OSS 之间的直接连接,能够充分利用用户的网络带宽。相比之下,后端传递文件时,文件需要经过后端服务器的中转,可能会受到后端服务器网络环境和处理能力的限制,…...
嵌入式学习笔记——ARM-中断与异常
文章目录 中断与异常的区别中断与 DMA 的区别中断能否睡眠?下半部能否睡眠?1. 中断处理程序不能睡眠2. 下半部(SoftIRQ、Tasklet、Workqueue) 中断处理注意点1. 快进快出2. 避免阻塞3. 正确返回值4. 如何处理大量任务5. 避免竞态问…...
OpenHarmony子系统开发 - 安全(十二)
OpenHarmony SELinux开发指导(五) 一、OpenHarmony SELinux常见问题 neverallow编译报错处理 现象描述 编译SELinux时会进行neverallow检查,当配置的策略不合理时,可能出现违反neverallow编译报错。 neverallow check failed…...
深入解析ARM与RISC-V架构的Bring-up核心流程
深入解析ARM与RISC-V架构的Bring-up核心流程 作者:嵌入式架构探索者 | 2023年10月 引言 在嵌入式开发中,处理器的Bring-up(启动初始化)是系统运行的第一道门槛。ARM和RISC-V作为两大主流架构,其Bring-up流程既有共性…...