黄子韬送车,抖音却出现重大bug,又有一个人的年终奖泡汤了
1月10日下午4点,黄子韬发布视频,称晚上7点将直播送车,并再次声明规则:“你只要来了都可以参与。”此前,黄子韬曾在直播中承诺,其短视频账号超过1500万粉丝将赠送国产汽车10台。消息一出,黄子韬的评论区立马成为了网友的许愿池,大家纷纷在评论区留言自己想要的车型。
当晚,黄子稻进行直播,在线观看人数达到了1100多万人,点赞数更是爆了!
抖音重大bug
点赞数持续上涨,最终更是超过了Int的最大值2147483647
。也就是超过了231 - 1。
接下来,神奇的一幕发生了,点赞数变成了负数!

大家知道这是怎么回事吗?
在Java中,只存在有符号整数,而没有无符号整数。具体各个类型的大小如下表所示。
什么是有符号整数
和无符号整数
呢?
有符号整数(Signed Integer)
有符号整数是指可以表示正数、负数和零的整数类型。在计算机中,有符号整数通常使用最高位(即最左边的位)作为符号位来表示正负。最高位为0表示正数,最高位为1表示负数。
示例
8位有符号整数(byte)
范围:-128 到 127 二进制表示: 0000 0000 表示 0 0000 0001 表示 1 0111 1111 表示 127 1000 0000 表示 -128 1000 0001 表示 -127 1111 1111 表示 -1
32位有符号整数(int)
范围:-2,147,483,648 到 2,147,483,647 二进制表示: 0000 0000 0000 0000 0000 0000 0000 0000 表示 0 0000 0000 0000 0000 0000 0000 0000 0001 表示 1 0111 1111 1111 1111 1111 1111 1111 1111 表示 2,147,483,647 1000 0000 0000 0000 0000 0000 0000 0000 表示 -2,147,483,648 1000 0000 0000 0000 0000 0000 0000 0001 表示 -2,147,483,647 1111 1111 1111 1111 1111 1111 1111 1111 表示 -1
无符号整数(Unsigned Integer)
无符号整数是指只能表示非负数(即零和正数)的整数类型。无符号整数没有符号位,所有位都用于表示数值,因此其范围是从0到最大值。
示例
8位无符号整数
范围:0 到 255 二进制表示: 0000 0000 表示 0 0000 0001 表示 1 0111 1111 表示 127 1000 0000 表示 128 1111 1111 表示 255
32位无符号整数
范围:0 到 4,294,967,295 二进制表示: 0000 0000 0000 0000 0000 0000 0000 0000 表示 0 0000 0000 0000 0000 0000 0000 0000 0001 表示 1 0111 1111 1111 1111 1111 1111 1111 1111 表示 2,147,483,647 1000 0000 0000 0000 0000 0000 0000 0000 表示 2,147,483,648 1111 1111 1111 1111 1111 1111 1111 1111 表示 4,294,967,295
| 范围 | ||
| 最高位 | ||
| 8位 | ||
| 16位 | ||
| 32位 | ||
| 64位 |
在Java中,没有原生的无符号整数类型,但可以使用BigInteger类来模拟无符号整数。
import java.math.BigInteger;
publicclassIntegerExample{
publicstaticvoidmain(String[] args){
// 有符号整数
bytesignedByte=127;
shortsignedShort=32767;
intsignedInt=2147483647;
longsignedLong=9223372036854775807L;
System.out.println("有符号 byte 最大值: "+ signedByte);
System.out.println("有符号 short 最大值: "+ signedShort);
System.out.println("有符号 int 最大值: "+ signedInt);
System.out.println("有符号 long 最大值: "+ signedLong);
// 无符号整数(使用 BigInteger 模拟)
BigIntegerunsignedByte=BigInteger.valueOf(255);
BigIntegerunsignedShort=BigInteger.valueOf(65535);
BigIntegerunsignedInt=BigInteger.valueOf(4294967295L);
BigIntegerunsignedLong=BigInteger.valueOf(18446744073709551615L);
System.out.println("无符号 byte 最大值: "+ unsignedByte);
System.out.println("无符号 short 最大值: "+ unsignedShort);
System.out.println("无符号 int 最大值: "+ unsignedInt);
System.out.println("无符号 long 最大值: "+ unsignedLong);
}
}
输出结果。
有符号 byte最大值:127
有符号short最大值:32767
有符号int最大值:2147483647
有符号long最大值:9223372036854775807
无符号byte最大值:255
无符号short最大值:65535
无符号int最大值:4294967295
无符号long最大值: 18446744073709551615
有符号整数溢出
有符号整数溢出是指在进行算术运算时,结果超出了该整数类型所能表示的范围。由于有符号整数有固定的范围,当运算结果超过这个范围时,就会发生溢出。溢出会导致结果“回绕”到范围的另一端,这可能会导致一些意外的行为。
下图展示了有符号整数的整个范围,将范围看作一个圆,我特意切开了这个圆,左边表示正数
,右边表示负数
。从这里可以看到,当正数的最大值再加上1,就会变成负数的最大值。

这个是为什么呢,可以从二进制看到答案。
32位最大值是2147483647
,用二进制表示如下,也就是符号为是0表示正数,剩下31位是1.
01111111111111111111111111111111
这个数再加1是多少呢,二进制加法和十进制加法是一样的,逢2进1
。那么一直进位,二进制结果如下。
10000000000000000000000000000000
可以看到结果是符号位是1,剩下31位是0.这个结果就是-2147483648
。
真实点赞数
接下来,我们可以算一下,真实的点赞数到底是多少呢?
假设当前的点赞数是-1671321474
。
已知:
1. 当前是有符号整数 2. 当前是Int类型 3. 当Int类型达到最大值 2147483647
以后再加1就会溢出。
所以真实的点赞数 = 0 + Int最大值 + 1(溢出到最小值) + x = -1671321474 = -2147483648 + x = -1671321474
因此 x = -1671321474 + 2147483648 = 476162174
也就是说真实的点赞数 = 2147483647 + 1 + 476162174 = 2623645822
也就是26亿。千分位表示:2,623,645,822
总结
有人说服务端是好的,只是安卓端的老代码使用的是Int,因此造成了这个Bug,这不就是传说中的屎山代码吗?
也不知道又有哪些人要倒霉的没有年终奖啦,大家也要注意这个问题啊~
我相信最开始的程序员也没有想到一场直播的点赞数能干爆Int吧~




