吾本轻狂|全网首发:12306抢票算法大曝光?(十张图搞定)


你好 , 我是彤哥 , 一个每天爬二十六层楼还不忘读源码的硬核男人 。
相信大家都有过抢票、刷票的经验 , 每年年底 , 这都是一场盛宴 。
然而 , 你有没有想过12306的抢票算法是怎么实现的呢?
没有吧 , 想过 , 还是没有头绪?
今天 , 我们就来曝光让人又爱又恨的12306是如何实现抢票的 。
位运算回顾我们知道计算机只能识别0和1 , 要操作这些0和1 , 只能通过位运算来进行 , 那么 , 一共有几种位运算呢?
让我们来回顾一下:
运算符号举例结果与&1101&01100100或|1101&01101111异或^1101^01101011取反~11010010左移<<1101<<111010带符号右移>>1101>>11110不带符号右移>>>1101>>>10110
以上位运算以Java为例 , 其他语言中可能没有>>>操作 。
OK , 位运算的简单回顾就到这里 , 还有不懂的同学可以自行百度一下 。
位图虽然大部分语言都有提供位运算 , 但是 , 并没有提供一种类似于位数组的类型 , 要使用这些位运算 , 我们只能通过数字类型来实现 , 比如Java中的int/long等类型 。
而这些数字类型的数组 , 我们一般可以称之为“位图”(BitMap) 。
比如 , 我们需要使用128位的内存 , 可以申请包含两个long类型的数组long[]bitmap=newlong[2]; 。
不过 , 位图有什么用呢?
有大用处哦 , 比如 , 我们要统计某个用户一年的活跃度 , 就可以使用位图来实现 。
一年有365天 , 一个long类型可以表示64位 , 365/64=6 , 只需要6个long类型就可以记录一个用户一年的活跃情况 , 怎么记录呢?
很简单 , 初始时 , 位图中所有位都是0 , 当这个用户某天登录了 , 就在位图中找到这天 , 把其位变成1 , 一年下来 , 这张位图就记录了这个用户哪些天登录了 , 统计这个位图中1的数量 , 除以365 , 就得到了他的活跃度 。
12306抢票算法我们知道 , 一列火车 , 有很多个座位 , 可以到很多站 , 以北京到广州的一列火车G67为例:
那么 , 如何实现合理的抢票策略 , 才能保证这趟列车能够坐最多的人?(没有站票)
什么叫做“坐最多的人”呢?假设针对10号位置 , 一个人从北京到武汉 , 另一个人从武汉到长沙 , 再一个人从长沙到广州 , 那针对这个位置全程可以坐3个人;针对另一个位置 , 一个人从北京到广州 , 那这个位置全程只能坐一个人 。 简单点说 , 就是针对一个特定的位置 , 两个人之间不能有交集 , 比如一个人从北京到长沙 , 另一个人从武汉到广州 , 那这两个人不能安排到同一个位置上 。


推荐阅读