騰訊 43 億 QQ 號碼用完后怎么辦?
大家好,我是道哥。
最近有讀者提問:聽說騰訊QQ號碼的理論最大值是43億左右,那么用完后會怎樣呢?
今天,來聊一聊與騰訊QQ號碼相關的三個問題,相信大家會有一個比較完整的認識。
QQ號的范圍是多少?
QQ號用完后會怎樣?
QQ號和bitmap淵源?

一. QQ號的范圍是多少?
相信多數朋友都用過QQ,不過估計有些人很久沒登錄過了。你還記得自己的QQ號碼嗎?你知道QQ號碼有多少位數嗎?你知道QQ號碼的大小范圍嗎?
別著急,我們會一一來解答。大家的微信號是字符串形式的,帶有一些數字和字母,但QQ號是純數字。在騰訊QQ后臺的程序中,經??吹竭@樣的代碼:
unsigned?int?uin?=?getFromCookie(cookie, "uin")?;if?( uin?10001 ){???log.Error("invalid?uin?%u",?uin)?;???return?INVALID_UIN ;}
不管怎樣,uin表示的就是QQ號碼,且是unsigned int類型,故QQ號就是4字節(jié)無符號整數,共32bit, 也就是說,QQ號的取值范圍是:[0, 2^32 - 1]
然而,這只是理論情況,從上面代碼的判斷可知,QQ號碼的最小值是10001, 為什么騰訊要做這種限制呢?其實沒有為什么,僅僅是早期的一個設定而已。
對于QQ號碼而言,從10001開始,號越小,就大致表明申請時間越早,是一個尊貴號。那么,10001是誰的QQ號呢?很容易猜,不過他實際不用這個號。
2^32 - 1 的值是4294967295, 是一個10位的整數,大約是43億,這就是QQ號碼的理論最大值,你肯定沒有見過11位的QQ號,至少目前是不可能存在的。
到目前為止,大家肯定就能理解下圖中的數字含義了。在后續(xù)面試騰訊時,如果再問到QQ號碼相關的問題,一定要意識到QQ號碼的大小范圍,會有幫助的。

二. QQ號用完后會怎樣?
既然QQ號碼的值是有范圍的,那么自然有疑問:如果這么多QQ號碼都被申請完后,結果會怎樣呢?這是一個有趣的問題,但別替騰訊擔心這些根本問題。
對于很多互聯(lián)網公司而言,賬號體系就是生命線,對騰訊尤其如此。最近幾年,微信的勢頭超過QQ, QQ的月活遠低于10億,注冊了的QQ也遠小于43億個。
所以,完全不用擔心QQ號會超過43億,在相當長的一段時間內,43億是達不到的。而且,騰訊現在做了各種限制,并不會允許一個人無限地注冊QQ號碼。
另外,如果一個QQ號被注冊了,但長期不登錄,那么就相當于占著茅坑不拉屎,浪費資源。此時,騰訊也會考慮對QQ號進行回收,具體的邏輯就不說了。
然而,凡事總有萬一,如果有一天QQ號碼突破了43億,那也可以,對騰訊來說,意味著業(yè)務蓬勃發(fā)展,也是好事。那么,QQ后臺很多代碼就需要重構了。

三. QQ號和bitmap淵源
在騰訊的面試題中,經常以QQ號碼為背景進行考察。比如典型題目:文件中有40億個QQ號碼,如何進行去重?

unsigned char共8位,取值范圍是[0, 255],這個unsigned char的數值是255,能標識0~7這些數字都存在。
同理,如下這個unsigned char類型的值是254,它對應的含義是:1~7這些數字是存在的,而數字0是不存的:

一個unsigned int類型數據可以標識0~31這32個整數的存在與否。
兩個unsigned int類型數據可以標識0~63這64個整數的存在與否。
說白了,也就是4B的內存,可以標識32個整數的存在與否。如果還不清楚的話,我來畫個表格,逐步推演一下:
| 內存大小 | 標識數的范圍 |
| 4B | 0~31 |
| 8B | 0~63 |
| 16B | 0~127 |
| ... | ... |
| 512MB | 0~2^32 - 1 |
using namespace std;unsigned int a[1 + N / 32] = {0};// 設置第i位為1, 讓它處于點亮狀態(tài)void setOne(int i){a[i >> SHIFT] |= (1 << (i & MASK));}// 設置第i位為0, 讓它處于熄滅狀態(tài)void setZero(int i){a[i >> SHIFT] &= ~(1 << (i & MASK));}// 獲取第i位的狀態(tài)int getState(int i){return (a[i >> SHIFT] & (1 << (i & MASK))) && 1;}int main(void){// 把1,3,1,4,9,9,9這幾個值的狀態(tài)點亮,即狀態(tài)為1setOne(1);setOne(3);setOne(1);setOne(4);setOne(9);setOne(9);setOne(9);int i = 0;for(i = 0; i < N; i++){????cout?<"對應的狀態(tài)為:--->"?<endl;?//?獲取狀態(tài)}cout << endl;return 0;}
編譯運行一下,結果為:
0對應的狀態(tài)為:--->01對應的狀態(tài)為:--->12對應的狀態(tài)為:--->03對應的狀態(tài)為:--->14對應的狀態(tài)為:--->15對應的狀態(tài)為:--->06對應的狀態(tài)為:--->07對應的狀態(tài)為:--->08對應的狀態(tài)為:--->09對應的狀態(tài)為:--->110對應的狀態(tài)為:--->011對應的狀態(tài)為:--->012對應的狀態(tài)為:--->013對應的狀態(tài)為:--->014對應的狀態(tài)為:--->015對應的狀態(tài)為:--->016對應的狀態(tài)為:--->017對應的狀態(tài)為:--->018對應的狀態(tài)為:--->019對應的狀態(tài)為:--->0
QQ號碼和bitmap的淵源就是如此,以后在面試時,不可忽視bitmap的妙用哦,也希望大家看完這篇文章后,有所收貨,心情愉快。最后,來畫一張動圖玩玩,希望大家喜歡。


歡迎加入技術交流群

