首页 > 编程语言 >不谈源码,聊聊位运算的实际应用

不谈源码,聊聊位运算的实际应用

时间:2022-11-08 17:07:36浏览次数:63  
标签:运算 val int 不谈 private public 源码 聊聊 options

Hello,这里是爱 Coding,爱 Hiphop,爱喝点小酒的 AKA 柏炎。

位运算是java中比较基础的知识,位运算的计算速度很快,jdk中不少源码都是使用位运算​​(例如ArrayList,HashMap)​​。

但是在日常开发的过程中,我们很少会使用位运算。相比较它的计算速度的优点,它可读性不高的”缺点“似乎对于普通的业务开发来说更加突出。

我们更加乐意直接使用 ​​+,-,*,/​​这些直接的运算符。

本文将给大家介绍一种位运算在业务中的应用场景,希望能给大家带来帮助,如有不对之处,欢迎指正。

本位不对位运算的基础做展开介绍,如果不熟悉位运算的基础概念的,请先自行google了解。

不谈源码,聊聊位运算的实际应用_Java

一、常规业务打标思路

日常业务开发的过程中,经常会有对业务模型打标 (true/false) 的需求。

例如:

true表示男生,false表示女生

true表示参与活动优惠,false表示无法参与活动优惠

true表示超级管理员,false表示普通用户

.....

一般情况下针对这种需求,我们通常会使用一个独立的字段去表示Domain的状态。随着业务的发展,需要打标的逻辑越来越多。对应到Domain/表结构中标识的字段也会不断的上升。

@Data
public class User {
private Long userId;
private String userName;
private boolean canLogin;
private boolean isMale;
private boolean isAdmin;
....
}

二、位运算优化逻辑

为了解决这种非A即B的字段标识的膨胀问题,我们可以使用位运算去整合这些字段。

例如上文展示的User Domain,我们整合canLogin,isMale,isAdmin为一个字段,认为是一个feature标识(设置字段为​​featureTag​​)。

@Data
public class User {
private Long userId;
private String userName;
private int featureTag;
}

我们可以定义一个feature的枚举定义每一位标识什么

public enum UserFeatureEnum{

CAN_LOGIN(0),
IS_MALE(1);
IS_ADMIN(2);

private int bit;

UserFeatureEnum(int bit) {
this.bit = bit;
}

public int getValue() {
return this.bit;
}

}

然后我们可以通过一下的BitUtil来check当前用户某个特性的状态

public class BitUtil {
public static int setBit(int options, int bitIndex) {
int val = 1 << bitIndex;
return options | val;
}

public static int unsetBit(int options, int bitIndex) {
int val = 1 << bitIndex;
return options & (~ val);
}

public static boolean isBitSetted(int options, int bitIndex) {
int val = 1 << bitIndex;
return (options & val) == val;
}

public static boolean isBitUnSetted(int options, int bitIndex) {
int val = 1 << bitIndex;
return (options & val) == 0;
}
}

这样我们如果去校验user是否为男性就可以这么操作

boolean isMale = BitUtil.isBitSetted(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue());

设置当前用户为女性

user.setfeatureTag(BitUtil.unsetBit(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue()))

设置当前用户为男性

user.setfeatureTag(BitUtil.setBit(user.getfeatureTag(),UserFeatureEnum.IS_MALE.getValue()))

这样我们将日益膨胀的标志字段给合并了,数据库也能够只用一个字段就能够标识Domain的多个feature。

后续如果需要增加一个feature时,就不需要修改表结构了,只需要增加一个枚举值及设置、判断逻辑就行。

像线上项目,改个表结构还要走一道道的DBA审批流程

三、优劣势对比

  • 相比较常规的业务设计,位运算在空间节省与扩展性上更加突出,但是可读性就比较差。
  • 在DB检索上,常规设计可以直接将字段作为条件进行过滤,位运算需要在条件上进行一下位运算。
  • 在ES检索上,常规设计可以直接将字段作为条件进行过滤,位运算就不支持了,需要冗余出一个字段,如果Domain的存储结构是ES,并且feature字段有检索需求,那还是按照常规设计比较好。
  • 如果涉及到与客户端交互的功能,版本A的client支持的功能,在版本B就不能支持了。由于客户端是安装在用户本地的,不可能一直强制用户做升级。因此这种时候可以在使用一个feature字段,标识当前客户端支持的一些特性,服务端去解析返回结果。请求参数清晰简单,动态性比较高。

不谈源码,聊聊位运算的实际应用_位运算_02

四、最后

文中如有不正确之处,欢迎指正,写文不易,点个赞吧,么么哒~

微信:baiyan_lou

公众号:柏炎大叔

小册:​​深入浅出DDD​​

转载请在文章开头显眼位置贴上原文链接与作者。

不谈源码,聊聊位运算的实际应用_位运算_03

标签:运算,val,int,不谈,private,public,源码,聊聊,options
From: https://blog.51cto.com/u_12763931/5833745

相关文章

  • 手撕Gateway源码,今日撕工作流程、负载均衡源码
    SpringCloudGateway源码剖析通过前面的学习,我们知道SpringCloudGateway是一个微服务网关,主要实现不同功能服务路由,关于SpringCloudGateway的实战使用我们就告一段落,我们......
  • Kubelet源码分析(一):工作原理以及启动流程分析
    一、概要kubelet是运行在每个节点上的主要的“节点代理”,每个节点都会启动kubelet进程,用来处理Master节点下发到本节点的任务,按照PodSpec描述来管理Pod和其中的容......
  • Redisson源码解读-公平锁
    前言我在上一篇文章聊了Redisson的可重入锁,这次继续来聊聊Redisson的公平锁。下面是官方原话:它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线......
  • SQLite源码安装部署
    1.下载下载地址:https://www.sqlite.org/download.html我这里下载的是:sqlite-autoconf-3390400.tar.gz 2.解压编译[root@localhostsoft]#yuminstallgcc[root@localh......
  • log4go使用及源码解析
    1.功能模块1.1配置文件日志输出支持:控制台、log文件、xml、分级日志:FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR 2.源码解析  2.1文件结构    2.2 ......
  • vue源码分析-v-model的本质
    双向数据绑定这个概念或者大家并不陌生,视图影响数据,数据同样影响视图,两者间有双向依赖的关系。在响应式系统构建的上,中,下篇我已经对数据影响视图的原理详细阐述清楚了。而......
  • vue源码中的渲染过程是怎样的
    4.1VirtualDOM4.1.1浏览器的渲染流程当浏览器接收到一个Html文件时,JS引擎和浏览器的渲染引擎便开始工作了。从渲染引擎的角度,它首先会将html文件解析成一个DOM树,与此......
  • vue源码分析-diff算法核心原理
    这一节,依然是深入剖析Vue源码系列,上几节内容介绍了VirtualDOM是Vue在渲染机制上做的优化,而渲染的核心在于数据变化时,如何高效的更新节点,这就是diff算法。由于源码中关于d......
  • 【深入浅出 Yarn 架构与实现】1-2 搭建 Hadoop 源码阅读环境
    本文将介绍如何使用idea搭建Hadoop源码阅读环境。(默认已安装好Java、Maven环境)一、搭建源码阅读环境一)idea导入hadoop工程从github上拉取代码。https://gith......
  • QT5-打开源码中的所有打印信息
    移植QT时,可能要查看QT的源码中的打印日志,以便确定问题。修改方法如下:/etc/profile文件exportQT_DEBUG_PLUGINS=1exportQT_LOGGING_RULES="*=false;*=true"规则如下:关闭所......