zoukankan      html  css  js  c++  java
  • 写二进制,姿势一定要骚,省字段,省带宽,提效率...

    在这里插入图片描述

    介绍

    上一个礼拜和一个同事对接口,前端同事问我是不是接口文档写错了,一个订单的异常标签有多个,不应该返回一个数组吗?为啥只返回了一个数字。

    因为这个接口是调用别微服务,所以我也很疑惑,找同事确认,他只回了我一句用位表示状态。我立马就懂了,因为Linux下的权限也是这么干的,然后找到他们的代码确认了一番,果然和我想的一样,看看是怎么做的吧

    在这里插入图片描述
    其实很简单,就一个如下的枚举类

    public enum EXTEND_FLAG_ENUM {
    
        OVER_WEIGHT(1, "超重"),
        OVER_CUBAGE(1 << 1, "超方"),
        LATE(1 << 2, "晚点"),
        SLOW(1 << 3, "缓行");
    
        public int value;
        public String name;
    
        EXTEND_FLAG_ENUM(int value, String name) {
            this.value = value;
            this.name = name;
        }
    
        public static int addFlag(int org, EXTEND_FLAG_ENUM newFlag) {
            return org | newFlag.value;
        }
    
        public static int removeFlag(int org, EXTEND_FLAG_ENUM oldFlag) {
            return org & (~oldFlag.value);
        }
        public static boolean hasFlag(int org, EXTEND_FLAG_ENUM oldFlag) {
            return (org & oldFlag.value) > 0;
        }
    }
    

    用4个二进制为来表示订单的状态

    二进制 代表状态 十进制
    0001 超重 1
    0011 超重,超方 3
    1011 超重,超方,缓行 11
    1111 超重,超方,晚点,缓行 15

    简单解释一下与或非操作

    与操作(有0出0,全1出1)

    数字 二级制
    A 1 0 1 0
    B 1 1 0 0
    A & B 1 0 0 0

    或操作(有1出1;全0出0)

    数字 二级制
    A 1 0 1 0
    B 1 1 0 0
    A | B 1 1 1 0

    非操作(有1出0;有0出1)

    数字 二级制
    A 1 0 1 0
    ~A 0 1 0 1

    以下断言测试通过

    @Test
    public void showTest() {
    	// 订单的异常标签初始为0
    	int extendFlag = 0;
    	// 标记订单超重
    	extendFlag = EXTEND_FLAG_ENUM.addFlag(0, EXTEND_FLAG_ENUM.OVER_WEIGHT);
    	assertTrue(EXTEND_FLAG_ENUM.hasFlag(extendFlag, EXTEND_FLAG_ENUM.OVER_WEIGHT));
    	// 标记订单超方
    	extendFlag = EXTEND_FLAG_ENUM.addFlag(extendFlag, EXTEND_FLAG_ENUM.OVER_CUBAGE);
    	// 订单确实超重和超方了
    	assertTrue(EXTEND_FLAG_ENUM.hasFlag(extendFlag, EXTEND_FLAG_ENUM.OVER_WEIGHT));
    	assertTrue(EXTEND_FLAG_ENUM.hasFlag(extendFlag, EXTEND_FLAG_ENUM.OVER_CUBAGE));
    }
    

    前端拿到一个整数就能解析出相应的状态

    @Test
    public void showTest2() {
    	// [1]
    	System.out.println(getExtendFlag(1));
    	// [1, 2, 8]
    	System.out.println(getExtendFlag(11));
    	// [1, 2, 4, 8]
    	System.out.println(getExtendFlag(15));
    }
    
    public List<Integer> getExtendFlag(int num) {
    	List<Integer> numList = new ArrayList<>();
    	int temp = 1;
    	while (temp < 16) {
    		if ((num & temp) >= 1) {
    			numList.add(temp);
    		}
    		temp = temp << 1;
    	}
    	return numList;
    }
    

    你看,一个数字同时记录多种状态,节省数据库字段和带宽,程序可扩展性也变强了,增加新的状态只需要增加一个枚举属性即可。
    在这里插入图片描述

    二进制的其他骚操作

    普通操作 骚操作
    n * 2 n << 1
    n / 2 n >> 1
    n % 1 == 1 n & 1 == 1

    没别的,位操作就是快

    判断一个数是否是2的指数,我原来面试的时候被问到过

    bool isPowerOfTwo(int n) {
        if (n <= 0) return false;
        return (n & (n - 1)) == 0;
    }
    

    2的指数二进制的形式一定是1000,2的指数-1的二进制的形式一定是111,所以与操作一定是0

    二进制的骚操作还有很多,但是并不常用,这里只列举了一些常用的

    欢迎关注

    关注回复 pdf目录 有惊喜,海量视频资源访问 www.erlie.cc

    在这里插入图片描述

    参考博客

    一些有趣有用的位操作
    [1] https://mp.weixin.qq.com/s/Z37PpJ5ZuK3pwEvaFuBxBg
    技巧总结位运算装逼指南
    [2] https://blog.csdn.net/m0_37907797/article/details/103120886

  • 相关阅读:
    PSR-2 编码风格规范
    Git中删除冗余的分支
    linux下ssh连接缓慢详解
    pytest框架之fixture详细使用
    如何利用jenkins插件查看allure报告-----完整篇
    CentOS上安装配置Python3.7
    [Python]requests使用代理
    Selenium
    Python性能分析工具-cProfile
    subprocessf运行window程序
  • 原文地址:https://www.cnblogs.com/erlie/p/12302274.html
Copyright © 2011-2022 走看看