当前位置: 首页 > news >正文

【Redis07】Redis基础:Bitmap 与 HyperLogLog 相关操作

Redis基础学习:Bitmap 与 HyperLogLog 相关操作

继续进行 Redis 基础部分的学习,今天我们学习的是两种另外的数据类型。说是数据类型,但其实它们实际上使用的都是 String 类型做为底层基础,只不过是在存储的时候进行了一些特殊的操作。换句话说,这两种类型并不是真正意义上的“数据类型”,换成“数据操作”可能更合适一些。

Bitmap

先来看看 Bitmap ,这是个啥玩意?其实呀,这个就是 位图 ,Bit 就是 比特 的意思嘛。一提到 比特 是不是又得来二进制了?这个真没办法,学计算机的,任何工具都逃不掉的就是 二进制 相关的操作。不过在 Redis 中的操作还是比较简单的,毕竟我们主要的操作还是在程序业务端进行,Redis 只是一个数据库而已。

Bitmap 在 Redis 中可以存储大约 40 多亿条数据,或者说是40多亿个 0 和 1 位。估计不少小伙伴马上就能想到它的应用场景了,我们在最后再说。先来看看它的操作。

Bitmap 操作命令

设置和获取指定位置的位信息,直接使用 SETBIT 和 GETBIT。

127.0.0.1:6379> setbit a 8 1
(integer) 0
127.0.0.1:6379> setbit a 4 1
(integer) 0
127.0.0.1:6379> get a
"\b\x80"
127.0.0.1:6379> getbit a 4
(integer) 1
127.0.0.1:6379> getbit a 5
(integer) 0

注意到上面的例子,我们直接使用 GET 命令也可以获取到内容,前面就说过了,它本身就是使用 String 类型存储的。只不过使用位操作的话,我们要理解 8 位代表 1 个字节的问题。因此,设置一个 8 位的二进制代码才能表示出一个我们能看懂的字符。

127.0.0.1:6379> setbit b 1 1
(integer) 0
127.0.0.1:6379> setbit b 4 1
(integer) 0
127.0.0.1:6379> setbit b 5 1
(integer) 0
127.0.0.1:6379> setbit b 6 1
(integer) 0
127.0.0.1:6379> setbit b 7 1
(integer) 0
127.0.0.1:6379> get b
"O"
127.0.0.1:6379> setbit c 1 1
(integer) 0
127.0.0.1:6379> setbit c 2 1
(integer) 0
127.0.0.1:6379> setbit c 4 1
(integer) 0
127.0.0.1:6379> setbit c 6 1
(integer) 0
127.0.0.1:6379> setbit c 7 1
(integer) 0
127.0.0.1:6379> get c
"k"

看出上面的例子是什么意思了吗?第一个 b ,设置的其实是 01001111 ,转换成十进制是 79 ,对应的 ASC2 码就是大写英文 O 。另一个 c 也是一样的意思,01101011 的十进制是 107 ,表示的英文是 107 。如果要表示 Ok 这两个字母的话,就需要两个 8 位,也就是两个字节 01001111 01101011 。

127.0.0.1:6379> setbit d 1 1
(integer) 0
127.0.0.1:6379> setbit d 4 1
(integer) 0
127.0.0.1:6379> setbit d 5 1
(integer) 0
127.0.0.1:6379> setbit d 6 1
(integer) 0
127.0.0.1:6379> setbit d 7 1
(integer) 0
127.0.0.1:6379> get d
"O"
127.0.0.1:6379> setbit d 9 1
(integer) 0
127.0.0.1:6379> setbit d 10 1
(integer) 0
127.0.0.1:6379> setbit d 12 1
(integer) 0
127.0.0.1:6379> setbit d 14 1
(integer) 0
127.0.0.1:6379> setbit d 15 1
(integer) 0
127.0.0.1:6379> get d
"Ok"

好玩吧?中文也是一样的,只是三个字节的 UTF8 编码,需要三个 8 位的数据才能表示一个中文字,大家可以试试哦。

127.0.0.1:6379> set s 中
OK
127.0.0.1:6379> get s
"\xe4\xb8\xad"
127.0.0.1:6379> getbit s 0
(integer) 1
127.0.0.1:6379> getbit s 1
(integer) 1
127.0.0.1:6379> getbit s 2
(integer) 1
127.0.0.1:6379> getbit s 3
(integer) 0

“中”这个字直接 GET 返回的是16进制数据,将 e4b8ad 转换成二进制是 11100100 10111000 10101101 ,然后我们就可以使用 GETBIT 来验证是不是和我们手动转换出来的是一样的结果。

大家有兴趣的可以再多了解一下字符编码相关的知识,比如在 Redis 中使用的 UTF8 ,为什么单个字节第一位只能是 0 ,必须是 0xxxxxxx 这样的,中文也都是固定的 1110xxxx 10xxxxxx 10xxxxxx 这种格式,很有意思哦。

位操作

既然是位操作,那么 与、或、异或、非 操作肯定要有啦。

127.0.0.1:6379> bitop or dd b c
(integer) 1
127.0.0.1:6379> get dd
"o"
127.0.0.1:6379> bitop and dd b c
(integer) 1
127.0.0.1:6379> get dd
"K"
127.0.0.1:6379> bitop xor dd b c
(integer) 1
127.0.0.1:6379> get dd
"$"
127.0.0.1:6379> bitop not dd b
(integer) 1
127.0.0.1:6379> get dd
"\xb0"

查询第一个bit位位置

通过 BITPOS 命令,可以查询到指定的 key 中,第一个出现的位数据的位置。

127.0.0.1:6379> BITPOS a 1
(integer) 4
127.0.0.1:6379> BITPOS a 0
(integer) 0

第一条命令是查询第一个 1 出现的位置,第二条命令是查询第一个 0 出现的位置。它还有第二个参数,这个参数是一个偏移量,不过需要注意的是,它指的是字节的偏移量,不是位的偏移量。

127.0.0.1:6379> BITPOS d 1 0
(integer) 1
127.0.0.1:6379> BITPOS d 1 1
(integer) 9
127.0.0.1:6379> BITPOS d 1 2
(integer) -1

统计数量

BITCOUNT 可以统计指定 key 中 1 出现的次数。

127.0.0.1:6379> BITCOUNT d
(integer) 10
127.0.0.1:6379> BITCOUNT d 1 0 2
(error) ERR syntax error
127.0.0.1:6379> BITCOUNT d 1 0 1
(error) ERR syntax error
127.0.0.1:6379> BITCOUNT d 1 2
(integer) 5
127.0.0.1:6379> BITCOUNT d 0 2
(integer) 10
127.0.0.1:6379> BITCOUNT d 2 3
(integer) 0

它还有两个参数,同样也是字节偏移量和长度。

位域操作

位域这个东西我就不太懂了,只是给个例子,这一块深入学过 C 的同学应该会比较了解。

127.0.0.1:6379> setbit e 1 1
(integer) 0
127.0.0.1:6379> get e
"@"
127.0.0.1:6379> BITFIELD e incrby i5 100 1 get u4 0
1) (integer) 1
2) (integer) 4
127.0.0.1:6379> get e
"@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80"

Bitmap 经典例子

好了,Bitmap 的基本操作就是上面那些,介绍的比较简单,不过也确实都不复杂。但前提是要对二进制和进制之间的转换以及字符编码要有一定的了解。如果我们只是为了去显示字符串的位,那就有点大材小用了,其实 Bitmap 有个非常强悍的能力,也就是运用 BITCOUNT 去进行数据统计。

包括官网上给出的也是类似这样的例子,统计登录用户数。

最开始我们已经知道,一个 key 可以保存40多亿个位,那么我们可以把用户id当作位索引,然后某个用户今天登录了,就给它的位设置为 1 ,然后就可以 BITCOUNT 快速统计出今天有多少用户登录了系统,速度相当快哦。

127.0.0.1:6379> setbit user_login_20220509 100010 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 25525 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 8782 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 9846526547 1
(error) ERR bit offset is not an integer or out of range
127.0.0.1:6379> setbit user_login_20220509 98465265 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 399999999 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 3999999999 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 4294967295 1
(integer) 0
127.0.0.1:6379> setbit user_login_20220509 4294967296 1
(error) ERR bit offset is not an integer or out of range
127.0.0.1:6379> BITCOUNT user_login_20220509
(integer) 7

HyperLogLog

既然说到统计了,那么 HyperLogLog 这个操作类型就不得不提了。它是一种概率数据结构,用于计算唯一事物的集合数量。同时,它是以内存换精度的,也就是说,它能极大的节约内存,但是会有精度丢失的问题。最坏情况下,也就是内存占用最大的情况下,它也只需要 12K 的内存容量就可以存储非常巨大的数据量,精度的丢失会在 1% 以内。它也可以实现上面 Bitmap 中统计的例子,我们先来看看相关的操作命令。

127.0.0.1:6379> pfadd hll a b c d e f g
(integer) 1
127.0.0.1:6379> pfcount hll
(integer) 7
127.0.0.1:6379> pfadd hll a b c d e f g h i j k
(integer) 1
127.0.0.1:6379> pfcount hll
(integer) 11

PFADD 添加数据,PFCOUNT 获取数量。基本的操作命令就这两个,是不是无敌了。除了这两个外,还有一个合并的命令,类似于集合的并集操作。

127.0.0.1:6379> PFADD pfa a b c d e f
(integer) 1
127.0.0.1:6379> PFADD pfb d c a e g i
(integer) 1
127.0.0.1:6379> pfadd pfc b d f i l m n o
(integer) 1
127.0.0.1:6379> PFMERGE pfmerge pfa pfb pfc
OK
127.0.0.1:6379> pfcount pfmerge
(integer) 12

另外,它也是以 String 为基本存储类型的,所以用 GET 也能看到内容。

127.0.0.1:6379> get hll
"HYLL\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00Fm\x80I\xe8\x80L\"\x80D<\x848\x80B=\x80K\x83\x80B\xed\x84A\xfc\x8cG\x8e\x80Bm\x80BZ"

好了,接下来说下 HyperLogLog 和其它方式统计的对比,以下是网上找到的相关文章获取到的资料。

如果我们使用 SET 来进行基数统计,那么假设每一个元素的 32Bit(2^24 ≈ 1600万; 2^32 ≈ 42亿) , 假设存储1亿个不重复的元素那么我们需要 100 000 000 * 32 /8/1024/1024 ≈ 381MB。

如果我们用 Bitmap 来进行基数统计,每个元素对应一位(bit),假设我们存储1亿个不重复的元素那么我们需要 100 000 000 /8/1024/1024 ≈ 12MB。

然而我们使用 HyperLogLog ,一个键占用的内容空间是12KB,并且这个键可以处理海量数据。

它们三个都可以应用在统计不重复元素的场景:

  • HyperLogLog:海量数据,可以忍受 0.81% 误差的场景,其实大数据处理的时候都会有误差。

  • Bitmap:数据量不大,不能忍受误差,元素连续的(自增的用户主键id)。

  • SET:数据量不大,不能忍受误差,元素没有规律,并且需要返回实际的单个元素。

总结

今天的内容挺好玩吧,Bitmap 和 HyperLogLog 最常用的其实都是一个不重复数据统计的场景,但是又各有优势。在日常的工作中如果有类似的应用场景,完全就可以使用这两种数据操作来试试了。

扩展知识:布隆过滤器

布隆过滤器(Bloom Filter),听说过没?面试有没有被坑过?跟你说,布隆过滤器的基础知识就是 Bitmap ,HyperLogLog 也是它的类似实现之一。啥叫布隆过滤器?就是能够快速地查找某一个元素是否存在于指定的集合中,最典型的做法就是使用二进制位来进行操作,这不就是 Bitmap 嘛。

当然,完整的布隆过滤器的实现还是要更复杂一些,它一般会有三个 Hash 函数,生成三个不同位置,只有当三个位置全部命中时,才会认为指定的数据已经存在。从这一点上来说,其实就是在有限的空间内可以存放更多的数据。但它也会出现不同的数据三个 Hash 函数计算结果一致的概率,但我们可以增加更多的 Hash 函数,不过相应地性能也会降低。同样,它也会有精度问题,反正大概原理就是这样。布隆过滤器有一个非常经典的名言,那就是“我说你不在,那你一定不在;我说你存在,你有可能存在(也可能不存在)!”。在 packgist 上也能搜到纯 PHP 实现布隆过滤器的 Composer 包,大家可以自己下载源码学习一下哦!

相关文章:

【Redis07】Redis基础:Bitmap 与 HyperLogLog 相关操作

Redis基础学习&#xff1a;Bitmap 与 HyperLogLog 相关操作继续进行 Redis 基础部分的学习&#xff0c;今天我们学习的是两种另外的数据类型。说是数据类型&#xff0c;但其实它们实际上使用的都是 String 类型做为底层基础&#xff0c;只不过是在存储的时候进行了一些特殊的操…...

华为路由器 VRRP主备配置

组网需求 如下图所示&#xff0c;PC1通过SW1双归属到R1和R2。为保证用户的各种业务在网络传输中不中断&#xff0c;需在R1和R2上配置VRRP主备备份功能。 正常情况下&#xff0c;主机以R1为默认网关接入Internet&#xff0c;当R1故障时&#xff0c;R2接替R1作为网关继续进行工作…...

docker容器安装ES

1.拉取镜像 docker pull elasticsearch:6.5.42.修改别名 docker tag [容器ID] es65:6.5.42.启动应用 docker run -it -d -p 9200:9200 -p 9300:9300 --name es -e ES_JAVA_OPTS"-Xms128m -Xmx128m" es65:6.5.43.拷贝配置文件到宿主机 docker cp es:/usr/share/ela…...

Python Module — prompt_toolkit CLI 库

目录 文章目录目录prompt_toolkit示例化历史记录热键自动补全多行输入Python 代码高亮自定义样式prompt_toolkit prompt_toolkit 是一个用于构建 CLI 应用程序的 Python 库&#xff0c;可以让我们轻松地构建强大的交互式命令行应用程序。 自动补全&#xff1a;当用户输入命令…...

springboot mybatis-plus 调用 sqlserver 的 存储过程 返回值问题

问题&#xff1a; 在使用 mybatis-plus 调用sqlserver 存储过程 没有返回值 经过资料查找 注意点 此处使用Map传参&#xff0c;原因在于存储过程的返回值&#xff0c;通常在参数定义中实现&#xff0c;如In 入参、out 出参。 这样当执行后有结果返回时&#xff0c;则可以将结…...

【0180】PG内核读取pg_hba.conf并创建HbaLine记录(1)

文章目录 1. pg_hba.conf文件是什么?2. postmaster何时读取pg_hba.conf?2.1 pg内核使用pg_hba.conf完成客户端认证的原理2.2 读取pg_hba.conf的几个模块3. pg内核读取pg_hba.conf过程3.1 VFD机制获取文件描述符3.2 根据fd读取文件内容相关阅读: 【0178】DBeaver、pgAdmin I…...

【原型设计工具】​​上海道宁为您提供Justinmind,助力您在几分钟内形成原型,并现场测试,无需编写任何代码

Justinmind是用于 Web和应用程序的原型制作工具 在几分钟内形成原型 并在现场进行测试 无需编写任何代码 单击一下即可轻松在线获取您的设计 并与整个团队共享 享受高效的沟通和快速反馈 以实现持续改进和利益相关者的支持 开发商介绍 JustinMind是由西班牙JustinMind公…...

计算机网络中---HDLP协议和PPP协议

目录 HDLC协议PPP协议HDLC协议和PPP协议HDLC协议 HDLC协议【高级数据链路控制协议】是一种数据链路层协议,用于在两个节点之间传输数据。以下是HDLC协议的重点知识: HDLC协议定义了一种标准的帧格式,包括起始标志、地址字段、控制字段、信息字段、校验字段和结束标志。HDLC…...

k8s之节点kubelet预留资源配置

k8s之kubelet预留资源配置1 前言2 预留资源Kube-reservedSystem-reservedEviction Thresholds实施节点可分配约束3 Pod优先级4 生产应用配置文件重启kubelet服务查看节点资源1 前言 最近k8s在使用过程中遇到这样一个问题 由于Pod没有对内存及CPU进行限制&#xff0c;导致Pod在…...

机器学习笔记之前馈神经网络(四)反向传播算法[数学推导过程]

机器学习笔记之前馈神经网络——反向传播算法[数学推导过程]引言回顾&#xff1a;感知机算法非线性问题与多层感知机反向传播算法(BackPropagation,BP\text{BackPropagation,BP}BackPropagation,BP)场景构建求解各权重更新量图示描述反向传播过程总结引言 上一节介绍了M-P\tex…...

vscode+elementui校园跑腿系统 nodejs+vue

本系统从用户的角度出发&#xff0c;结合当前的校园环境而开发的&#xff0c;在开发语言上是使用的Java语言&#xff0c;在框架上我们是使用的Vue框架&#xff0c;数据库方面使用的是MySQL数据库&#xff0c;开发工具为IDEA。 基于Vue的校园跑腿管理系统中的管理员配送用户都可…...

[蓝桥杯单片机8]定时器的简单应用

1、本实验内容 利用51单片机的定时/计数器T0的模式1实现间隔定时&#xff0c;每隔1秒L1指示灯闪烁一下&#xff0c;也就是点亮0.5秒&#xff0c;熄灭0.5秒&#xff1b;每隔2秒L8指示灯闪烁一下&#xff0c;即点亮1秒&#xff0c;熄灭1秒。2、基础知识 定时/计数器&#xff0c;是…...

node-HTTP协议

文章目录一. 概念二. 请求报文的组成三.HTTP请求行四.HTTP请求头五.HTTP的请求体六.响应报文的组成七.创建HTTP服务八.获取HTTP请求报文九.HTTP设置响应十.GET和POST请求的区别一. 概念 HTTP协议. 中文叫超文本传输协议; 是一种基于TCP/IP的应用层通信协议; 这个协议详细规定了…...

基于springboot+vue的地方美食分享网站

081-springboot基于vue的地方美食分享网站开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&am…...

【Android】之【Aplication】

一、Application简介 Application和Activity&#xff0c;Service一样是Android框架的一个系统组件&#xff0c;当Android程序启动时系统会创建一个Application对象&#xff0c;用来存储系统的一些信息。 Android系统自动会为每个程序运行时创建一个Application类的对象且只创建…...

社区之声|Grant Program支持Moonbeam生态壮大

在本次社区之声会议中&#xff0c;Moonbeam基金会解释生态系统Grant流程、一个由社区成员组成的圆桌讨论表达各自对此次Grant的看法&#xff0c;Moonbeam开发者关系工程师演示了如何在Snapshot对申请生态系统Grant项目的投票。观看视频回顾 请注意&#xff0c;内容仅供参考&am…...

GO实现Redis:GO实现Redis协议解析器(2)

本文实现Redis的协议层&#xff0c;协议层负责解析指令&#xff0c;然后将指令交给核心database执行echo database用来测试协议层的代码https://github.com/csgopher/go-redis RESP协议 RESP是客户端与服务端通信的协议&#xff0c;格式有五种&#xff1a;正常回复&#xff1…...

Geoserver 发布wmts服务,以及cesium加载发布的wmts服务

WMTS提供了一种采用预定义图块方法发布数字地图服务的标准化解决方案。WMTS弥补了WMS不能提供分块地图的不足。WMS针对提供可定制地图的服务&#xff0c;是一个动态数据或用户定制地图&#xff08;需结合SLD标准&#xff09;的理想解决办法。WMTS牺牲了提供定制地图的灵活性&am…...

【微信小程序】selectComponent(#id)失败得到是null分析

小程序中无法像网页中轻易的获取DOM元素&#xff0c;需要依靠 this.selectComponent(#id)this.selectAllComponents(#id) 本文主要针对 this.selectComponent 获取DOM元素失败的原因 下面开始正文 上图为我的业务代码&#xff0c;由图可知&#xff0c;通过for循环遍历渲染ca…...

JVM中引用计数法与可达性分析

目录 概要 如何判断对象已死&#xff1f; 引用计数算法 优点 缺点 举例说明 可达性分析 图例说明 GC Roots的对象包括以下几种 可达性分析回收过程 四大引用 回收方法区 方法区的垃圾收集主要回收两部分内容&#xff1a; 1. 废弃的常量 2. 不再使用的类型。 JVM是…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...