通过位运算,实现单字段标识多个状态位
可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课.
这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加.
考虑只用一个状态标志位,利用位运算,来标识多门课的通过或否.
这与Linux的文件权限思路一致
Linux文件和目录的权限
设计及实现
-
左移(<<):
-
右移(>>):
-
|(或运算):只要当一方为 true 时,结果就是 true,否则为 false。 (有1就为1,全0才为0)
-
&(与运算):只有当两方都为 true 时,结果才是 true,否则为 false。(全1才为1,有0就为0)
对于正数和负数,左移一位就相当于乘以2的1次方,左移n位就相当于乘以2的n次方
如xxxxxx<<2即左移2位,右边空出的位用0填补,高位左移溢出则舍弃该高位
步骤一:
如语文成绩率先出来,我们约定,以这个字段(记为
attr)的第一位,来代表该学生语文有没有通过测评(0否1是)
attr为当前该属性字段的值(从数据库里取出来的值). index为约定的第几位来标识当前业务,index从0开始计数
package main
import "fmt"
func main() {
// 记录阶段
//如果语文成绩测评通过,调一个写接口,初始attr值为0,约定的表示位置为第1位,又因为从0开始计数,故而index=0
setRs := set(0, 0) //将attr字段的最新值,记录进数据库的attr字段
// 查询阶段
//当需要获知该学生的语文是否通过时. 查数据库,获取上面记录进的值(此时setRs即attr=1); 进而get方法,可知道是否通过(如果rs结果为1,则通过)
rs := get(setRs, 0)
_ = rs
}
func set(attr, index int) int {
tmp := 1 << index
// 1左移0位,即原地没动,还是1
fmt.Printf("1 << index %d 值为%d:\n", index, tmp)
// 1 | 0,或运算,有1就为1,故而setRs=1
setRs := tmp | attr
fmt.Println(setRs)
return setRs
}
func get(attr, index int) int {
tmp := attr >> index
// 1右移0位,即原地不动,还是1
fmt.Printf("attr %d >> index %d 值为 %d:\n", attr, index, tmp)
// 0001 & 0001,与运算,全1才为1,故而为0001,即为十进制数1
getRs := tmp & 1
fmt.Println(getRs)
return getRs
}
输出为:
1 << index 0 值为1:
1
attr 1 >> index 0 值为 1:
1
假设孙山语文及格, 张继语文落榜(则不调用写接口,只有通过才调),则二人当前attr的值为1和0.
这样就完成了语文科目的处理
步骤二:
几天后数学测评结果也出来了,继续用attr,约定以这个字段的
第二位,来代表该学生数学有没有通过测评(0否1是)
同样用之前的代码,
记录阶段:
package main
import "fmt"
func main() {
// 记录阶段
//如果数学成绩测评通过,调写接口,约定的表示位置为第1位,又因为从0开始计数,故而index=1
// 对于孙山,从数据库取出其attr值,为1; 张继的attr值为0
// 加入二人都通过了数学测评,都需调用如下写接口
setRsSun := set(1, 1) //将attr字段的最新值,记录进数据库的attr字段
fmt.Println("-----------")
setRsZhang := set(0, 1)
}
func set(attr, index int) int {
tmp := 1 << index
// 1左移1位,即由"0001"变为"0010",即为十进制数2
fmt.Printf("1 << index %d 值为%d:\n", index, tmp)
// 对于语文通过带孙山,0010 | 0001,或运算,有1就为1,故而setRs=0011,即十进制数3
// 对于语文未通过带张继,0010 | 0000,或运算,有1就为1,全0才为0, 故而setRs=0010,即十进制数2
setRs := tmp | attr
fmt.Println(setRs)
return setRs
}
1 << index 1 值为2:
3
-----------
1 << index 1 值为2:
2
查询阶段:
package main
import "fmt"
func main() {
// 查询阶段
//当需要获知该学生的语文/数学是否通过时. 查数据库,获取其attr的值; 进而get方法,index字段为该科目约定的位置(语文为1,其index为0; 数学为2,其index为1),即可知道是否通过(如果rs结果为1,则通过)
sunMath := get(setRsSun, 1) //setRsSun=3
fmt.Println("-----------")
zhangChinese := get(setRsZhang, 0)//setRsZhang=2
fmt.Println("sunMath is:",sunMath)
fmt.Println("zhangChinese is:",zhangChinese)
}
func get(attr, index int) int {
tmp := attr >> index
fmt.Printf("attr %d >> index %d 值为 %d:\n", attr, index, tmp)
getRs := tmp & 1
fmt.Println(getRs)
return getRs
}
// 对于孙山,十进制数3即二进制0011,右移1位,即0001,即十进制数1
attr 3 >> index 1 值为 1:
// 0001 & 0001,与运算,全1才为1,故而为1. 即孙山通过了数学
1
-----------
// 对于张继,十进制数2即二进制0010,右移0位,即原地不动,还是0010,十进制数2
attr 2 >> index 0 值为 2:
// 0010 & 0001,全1才为1,否则为0. 即张继没有通过语文
0
sunMath is: 1
zhangChinese is: 0
步骤三:
过了几天,英语结果也出来了.假如孙山没通过,张继通过,爽哥三门都通过,则有
写入和读取过程同上
步骤四:
假如现在第60个科目'信息技术'的测评出炉, 爽哥前面59门课程全部通过,则attr字段的值为 ,
即
2的n次方对照表
第60门课'信息技术'也高分通过, 则对于最新的attr值,即 1 << index | attr,
即1 << 59 | 576460752303423487 = 1152921504606846975,将这个值计入数据库.
如需获取爽哥有无通过第60门课程,1152921504606846975 >> 59 & 1 = 1,即通过
如果将数据库这个attr字段设置为有符号的bigint类型,则最多可标识 60几个不同业务的状态
更通用的代码:
func main(){
index := uint8("约定的位置" - 1)
attr := "来自数据库"
}
func SetAttrBit(attr int, index uint8) int {
return 1 << index | attr
}
func GetAttrBit(attr int, index uint8) int {
return attr >> index & 1
}
参考:
用位运算来标识状态
番外
"光学电报"
本文由 mdnice 多平台发布
相关文章:
通过位运算,实现单字段标识多个状态位
可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课. 这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加. 考虑只用一个状态标志位,利用位运…...
ALSA pcm接口的概念解释
PCM(数字音频)接口 PCM缩写: Pulse Code Modulation脉冲调制编码,我们理解为通过一定连续时间周期产生数字音频并带有音量样本的处理过程. 模拟信号被记录通过模拟到数字转换器,数字值(也就是某个特定时刻的音量值)获得来自ADC可以进一步处理,接下的图片展示的是个sine wavefor…...
logging的基本使用教程
logging的基本使用教程 一、简介: logging模块是Python的标准库,用于记录应用程序运行时的日志信息。使用logging模块可以帮助您在开发过程中调试代码、追踪问题和监控应用程序的运行状况。 二、使用教程 1、logging模块的基本使用方法: …...
ds套dp——考虑位置转移or值域转移:CF1762F
https://www.luogu.com.cn/problem/CF1762F 分析性质,就是我们选的数要么递增,要么递减(非严格)然后很明细是ds套dp, f i f_i fi 表示以 i i i 开头的答案然后考虑如何转移(ds套dp难点反而在转移而不是…...
stm32的GPIO寄存器操作以及GPIO外部中断,串口中断
一、学习参考资料 (1)正点原子的寄存器源码。 (2)STM32F103最小系统板开发指南-寄存器版本_V1.1(正点) (3)STM32F103最小系统板开发指南-库函数版本_V1.1(正点&a…...
生成对抗网络入门案例
前言 生成对抗网络(Generative Adversarial Networks,简称GANs)是一种用于生成新样本的机器学习模型。它由两个主要组件组成:生成器(Generator)和判别器(Discriminator)。生成器尝试…...
多头注意力机制
1、什么是多头注意力机制 从多头注意力的结构图中,貌似这个所谓的多个头就是指多组线性变换,但是并不是,只使用了一组线性变换层,即三个变换张量对 Q、K、V 分别进行线性变换,这些变化不会改变原有张量的尺寸…...
Qt + FFmpeg 搭建 Windows 开发环境
Qt FFmpeg 搭建 Windows 开发环境 Qt FFmpeg 搭建 Windows 开发环境安装 Qt Creator下载 FFmpeg 编译包测试 Qt FFmpeg踩坑解决方法1:换一个 FFmpeg 库解决方法2:把项目改成 64 位 后记 官方博客:https://www.yafeilinux.com/ Qt开源社区…...
[网鼎杯 2020 白虎组]PicDown python反弹shell proc/self目录的信息
[网鼎杯 2020 白虎组]PicDown - 知乎 这里确实完全不会 第一次遇到一个只有文件读取思路的题目 这里也确实说明还是要学学一些其他的东西了 首先打开环境 只存在一个框框 我们通过 目录扫描 抓包 注入 发现没有用 我们测试能不能任意文件读取 ?url../../../../etc/passwd …...
SDL2绘制ffmpeg解析的mp4文件
文章目录 1.FFMPEG利用命令行将mp4转yuv4202.ffmpeg将mp4解析为yuv数据2.1 核心api: 3.SDL2进行yuv绘制到屏幕3.1 核心api 4.完整代码5.效果展示6.SDL2事件响应补充6.1 处理方式-016.2 处理方式-02 本项目采用生产者消费者模型,生产者线程:使用ffmpeg将m…...
决策树C4.5算法的技术深度剖析、实战解读
目录 一、简介决策树(Decision Tree)例子: 信息熵(Information Entropy)与信息增益(Information Gain)例子: 信息增益比(Gain Ratio)例子: 二、算…...
LLMs Python解释器程序辅助语言模型(PAL)Program-aided language models (PAL)
正如您在本课程早期看到的,LLM执行算术和其他数学运算的能力是有限的。虽然您可以尝试使用链式思维提示来克服这一问题,但它只能帮助您走得更远。即使模型正确地通过了问题的推理,对于较大的数字或复杂的运算,它仍可能在个别数学操…...
【12】c++设计模式——>单例模式练习(任务队列)
属性: (1)存储任务的容器,这个容器可以选择使用STL中的队列(queue) (2)互斥锁,多线程访问的时候用于保护任务队列中的数据 方法:主要是对任务队列中的任务进行操作 &…...
Python之函数、模块、包库
函数、模块、包库基础概念和作用 A、函数 减少代码重复 将复杂问题代码分解成简单模块 提高代码可读性 复用老代码 """ 函数 """# 定义一个函数 def my_fuvtion():# 函数执行部分print(这是一个函数)# 定义带有参数的函数 def say_hello(n…...
SQL创建与删除索引
索引创建、删除与使用: 1.1 create方式创建索引:CREATE [UNIQUE – 唯一索引 | FULLTEXT – 全文索引 ] INDEX index_name ON table_name – 不指定唯一或全文时默认普通索引 (column1[(length) [DESC|ASC]] [,column2,…]) – 可以对多列建立组合索引 …...
网络协议--链路层
2.1 引言 从图1-4中可以看出,在TCP/IP协议族中,链路层主要有三个目的: (1)为IP模块发送和接收IP数据报; (2)为ARP模块发送ARP请求和接收ARP应答; (3…...
HDLbits: Count clock
目前写过最长的verilog代码,用了将近三个小时,编写12h显示的时钟,改来改去,估计只有我自己看得懂(吐血) module top_module(input clk,input reset,input ena,output pm,output [7:0] hh,output [7:0] mm,…...
【1day】用友移动管理系统任意文件上传漏洞学习
注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...
【c++】向webrtc学习容器操作
std::map的key为std::pair 时的查找 std::map<RemoteAndLocalNetworkId, size_t> in_flight_bytes_RTC_GUARDED_BY(&lock_);private:using RemoteAndLocalNetworkId = std::pair<uint16_t, uint16_t...
SpringBoot+Vue3外卖项目构思
SpringBoot的学习: SpringBoot的学习_明里灰的博客-CSDN博客 实现功能 前台 用户注册,邮箱登录,地址管理,历史订单,菜品规格,购物车,下单,菜品浏览,评价,…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
