专栏名称: 石杉的架构笔记
专注原创、用心雕琢!十余年BAT一线大厂架构经验倾囊相授
目录
相关文章推荐
高分子科技  ·  封伟教授团队 Adv. ... ·  15 小时前  
高分子科学前沿  ·  中国科学院理化技术研究所王树涛/孟靖昕团队《 ... ·  18 小时前  
高分子科学前沿  ·  中国青年学者一作兼通讯!3D打印,最新Sci ... ·  2 天前  
高分子科技  ·  中科院纳米能源所张弛研究员团队 ACS ... ·  4 天前  
高分子科技  ·  华南师范大学胡小文 ... ·  3 天前  
51好读  ›  专栏  ›  石杉的架构笔记

为什么源码里经常出现这种骚操作?

石杉的架构笔记  · 公众号  ·  · 2021-03-23 09:35

正文

点击上方蓝色“ 石杉的架构笔记”,选择“设为星标”

回复“PDF”获取独家整理的学习资料!

长按扫描上方二维码 一元抢购


位运算这个概念并不陌生,大多数程序员在进入这个领域的时候或多或少都接触过位运算,估计当时都写过不少练习题的。

位运算本身不难,困难的是大家没有学会在系统设计时用上它,提高系统性能,增加你的不可替代性。

就不做太多铺垫了,直接说下今天讲述的干货内容:

位运算使用场景

面试经常问

比如我曾经在面试腾讯的时候

O(1) 时间如何检测整数 n 是否是 2 的幂次?

在看一道Google面试题:

有64瓶药,其中63瓶是无毒的,一瓶是有毒的。如果做实验的小白鼠喝了有毒的药,3天后会死掉,当然喝了其它的药,包括同时喝几种就没事。现在只剩下3天时间,请问最少需要多少只小白鼠才能试出那瓶药有毒?

这就不用龙su啰嗦了吧,稳稳的都是和位运算有关的。

类似面试题目还有很多,一个不注意就会被撂倒。

这部分的题目整体难度不大,本身不是一个很大的知识点,但是 「很容易被大家忽略」 ,今天龙su就拿出来好好说说,大家可要记住喔,不然...

系统设计经常用

喜欢看源码的同学就会注意到,经常在里面看到这样的代码。

「lucene源码」

「redis源码」

「龙叔的源码」

有没有发现这些代码惊人的相似, 「好的设计总是这样不谋而合」

看了这么多,想必大家已经知道这东西还是有些作用的,应该好好搞清楚他的原理。接下来就一起来盘他。

位运算原理

「位」 指的是比特位(bit),不是byte,所以位运算指的就是比特位计算。

CPU所有计算都是二进制的计算,一个高性能的服务一定是把CPU资源利用到极致,也就是用最少资源换取最大收益。

当然随着现代CPU的计算速度不断加快,很多人在设计系统的时候完全不会去考虑这些性能点,然而真正的高并发系统都是极致性能的。

看看我们日常开发都是啥样的,只要不涉及到 「高并发」 ,开发代码就算是一坨屎,也没关系,大多数人都是在这坨屎上继续CRUD,也就会变成了一大坨。

没办法,老板只看结果,懒得管你的代码是什么样的。哎呀,好像暴露了龙叔是个CRUD菜鸡选手。

等到有一天发现加机器加到扛不住了,这时候就是 「最幸运」 的一批程序员诞生的时候,必须开始重构系统。为什么最幸运,大家都知道了吧?机会不是天天有的,这就是千载难逢的良机啊。

哈,好像有点说远了。

在计算机世界里,万物皆0、1,0、1生万物。万物到0、1的过程叫做编码。

一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机中用一个数的最高位存放符号, 正数为0, 负数为1。

计算机中对数字的编码表示有三种方式: 「原码」 「反码」 「补码」

「原码」 :原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1。比如十进制3如果用8个二进制位来表示就是 00000011, -3就是 10000011。

「反码」 :反码表示方法:正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反。

「补码」 :补码表示方法:正数的补码是其本身;负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(即在反码的基础上+1)

这三种是编码方式,但是在计算机系统中,数值一律用补码来表示(存储)。

举个例子:

110
  原码           反码         补码
00001010  --> 00001010 --> 00001010
2. -15
10001111  --> 11110000 --> 11110001  

说完了数据编码,基本已经知道一个数据是怎么存储在计算机中的,接下来就看看数据比特位之间是如何计算的。

各种编程语言都提供了对补码的二进制位直接进行运算的方法,即 「位运算」

符号 描述 规则
& 相同位的两个数字都为1,则为1;若有一个不为1,则为0。
| 相同位只要一个为1即为1。
~ 0和1全部取反。
^ 亦或 相同位不同则为1,相同则为0。
<< 左移 a << b就表示把a转为二进制后左移b位(在后面添b个0)。
>> 右移 a >> b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。

举几个例子

10 & -15 = 00001010 & 11110001

按位进行相与,相同为1则为1,否则为0,最终算的结果为00000000 即0

10 & 15 = 00001010 & 00001111

按位进行相与,相同为1则为1,否则为0,最终算的结果为00001010 即10







请到「今天看啥」查看全文