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

后端常见问题解答-位运算实际场景讲解

位运算

在计算机存储的世界中,一切都是二进制的,位运算就是对二进制位进行操作的一种运算。位运算是计算机中的一种常见运算,可以用来提高性能和提升代码的可读性。

位运算有很多种,比如与、或、非、异或等,这些运算可以用来实现很多高效的算法。在这里,我们根据Bitmap实现密码强度检查器的实例,讲解位运算的实际应用场景。

代码讲解

查看源码

上面的代码中,我们使用Bitmap来表示密码中的字符,然后用位运算来判断是否符合要求。

我们先说清楚Bitmap的构建,我们用一个长度为128的数组来表示ASCII码表中的字符,然后用1 << 1, 1 << 2, 1 << 3, 1 << 4来表示大小写字母、数字、特殊字符,然后用位运算来判断是否符合要求。

那么我们先看一下UPPER_CASE、LOWER_CASE、DIGIT、SPECIAL_CHAR这四个常量:

从上面的图可以看出来,1 << 1 就是2, 对应的二进制表示就是"00000010"

| 或运算

ALL 这个变量UPPER_CASE | LOWER_CASE | DIGIT | SPECIAL_CHAR的或运算:

二进制的或运算是将两个数的二进制表示对应位进行或运算,只要有一个为1,结果就是1,否则就是0。

也就是00000010 | 000000100 | 0000001000 | 00000010000,也就是00000011110 所以ALL就是表示每个位上的状态都是1,也就是密码中包含了大小写字母、数字、特殊字符。

|= 或运算

hints |= currentBit 这个语句是将hints和currentBit进行或运算,然后将结果赋值给hints。 等同于:

hints = hints | currentBit;

就是相当于将hints的每一位和currentBit的每一位进行或运算,然后将结果赋值给hints。

& 与运算

代码中,我们用(currentBit & ALL) == 0来判断是否符合要求,这里用到了与运算。 二进制的与运算是将两个数的二进制表示对应位进行与运算,只有两个数的对应位都是1,结果才是1,否则就是0。

也就是00000010 & 0000001110,也就是00000010, 因为只有第二位是1,其他位都是0。 这个值就不会等于0,就表示当前的字符是符合要求的。

~ 非运算

~ 非运算是将一个数的二进制表示取反,也就是0变成1,1变成0。 也就是~00000010,也就是11111101,这个值就是-3。

配合与运算,可以用来取消hints的某一位, 比如当前是 UPPER_CASE | LOWER_CASE, 我们想取消LOWER_CASE

可以用hints & ~LOWER_CASE来取消LOWER_CASE
也就是00000010 & ~00000100,—> 00000010 & 11111011,—> 00000010
这样就取消了LOWER_CASE

比如:

hints = hints &= ~currentBit;

等同于:

hints = hints & ~currentBit;

^ 异或运算

异或运算是将两个数的二进制表示对应位进行异或运算,只有两个数的对应位不相同,结果才是1,否则就是0。

也就是00000010 ^ 0000001110,也就是000000110, 因为只有第二位是1,其他位都是0。 这个值就不会等于0,就表示当前的字符是符合要求的。

总结
在实际的开发中,我们可以用位运算来实现很多高效的算法,比如Bitmap、布隆过滤器等,这些算法都是基于位运算的,可以提高代码的性能和可读性。

作为后端开发工程师,我们需要了解位运算的基本原理和应用场景,这样才能更好地优化代码,提高系统的性能。

所有的后端面试常见的问题,我们每天都会在我们的编程群里面讨论和Code review, 欢迎大家加入我们的编程群,一起学习和进步。

实战项目交流群

入职啦官方公众号,关注更多面试题分享

相关文章:

  • 【odoo | SQL】odoo使用sql语句操作数据库
  • 工具:安装R语言的R包的各种方法
  • 大腾智能正式入驻华为云
  • 未来已来:低代码平台如何重塑企业数字化策略?
  • 你知道花洒其实起源于中国古代吗?
  • 【我是产品经理_注册安全分析报告】
  • 制作翻页电子版画册攻略:轻松掌握数字创作技巧
  • Mysql开启查询日志(General Log)
  • docker环境中配置phpstorm php xdebug调试工具
  • 计算子网掩码
  • 多种传感器在钢铁工业安全风险监测预警中的应用
  • 硕士毕业论文《基于磁纹理的磁化动力学研究》
  • “探索机器学习的多面世界:从理论到应用与未来展望“
  • 充电学习—3、Uevent机制和其在android层的实现
  • RAG与Langchain简介
  • 【Leetcode】104. 二叉树的最大深度
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Angular数据绑定机制
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • java8-模拟hadoop
  • JavaScript 基础知识 - 入门篇(一)
  • java多线程
  • js继承的实现方法
  • Next.js之基础概念(二)
  • react 代码优化(一) ——事件处理
  • Redis 懒删除(lazy free)简史
  • Ruby 2.x 源代码分析:扩展 概述
  • Vue2 SSR 的优化之旅
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 分享一份非常强势的Android面试题
  • 复习Javascript专题(四):js中的深浅拷贝
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 聊聊redis的数据结构的应用
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前端js -- this指向总结。
  • 如何优雅地使用 Sublime Text
  • 实现菜单下拉伸展折叠效果demo
  • -- 数据结构 顺序表 --Java
  • 怎么把视频里的音乐提取出来
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • ​字​节​一​面​
  • # Kafka_深入探秘者(2):kafka 生产者
  • #git 撤消对文件的更改
  • #WEB前端(HTML属性)
  • (1)(1.13) SiK无线电高级配置(六)
  • (23)mysql中mysqldump备份数据库
  • (4)STL算法之比较
  • (C++17) std算法之执行策略 execution
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (pojstep1.3.1)1017(构造法模拟)