(1) 如何实现亿级数据的全排序
其实考察的就是merge思想,内存不够时候的解决方案。现在的成熟解决框架,就是hadoop,storm这些。以hadoop为例,记录下什么阶段会排序。
==如果单机:
1.先将数据切片,遍历所有的切片,让他们各自都有序。(内存可以接受的程度,做得绝一点,就是一行数据一个文件)。
2. 所有切片两两merge,如果内存不够了,将归并后的队列的前半段存入磁盘, 然后三指针继续操作。
3.重复两两merge操作。
==Hadoop过程中的默认排序阶段:
1.map最后阶段进行partition分区,一般使用job.setPartitionerClass设置的类,如果没有自定义Key的hashCode()方法进行分区。在map阶段写出到环形缓冲区,在环形缓冲区溢写时会进行一次排序,每个分区内部调用job.setSortComparatorClass设置的key的比较函数类进行排序,如果没有则使用Key的实现的compareTo方法。
2.在归并每一个maptask的环形缓冲区的所有溢写文件的时候也会再次进行排序
3.当reduce接收到所有map传输过来的数据之后,对每一个分区的数据进行merge并排序,调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序,如果没有则使用Key的实现的compareTo方法。
4.紧接着使用job.setGroupingComparatorClass设置的分组函数类,进行分组,同一个Key的value放在一个迭代器里面。如果未指定GroupingComparatorClass则则使用Key的实现的compareTo方法来对其分组。
Hadoop1.0中不可避免 hadoop2.0中可以关闭,将reducetask设置为0
(2) 如何使用多线程来实现对一个接口的多次查询后进行数据整合,或者定时任务如何加快数据库数据处理速度?
1.其实理念都是用了多线程,如何以什么维度,或者什么字段来切分数据,不同维度不同字段的数据由不同线程接管处理数据,
2.然后整合方式可以通过CountDownLatch或者CycleBarrier来知道什么时候大家都结束任务,然后做一个整合并输出。
(3) 思考一个在线教室的场景,每个用户进来都会分配到一个教室,然后每个教室只容纳10人,如何做到不多申请一个教室?
1. 其实弄个原子类来每次++操作,或者互斥锁,每当人数%10==1的时候,那就创建数量即可。
2. 另外可以用分段锁,ConcurrentHashMap作为容器,key作为教室序号,val是队列来存储对应的人和对应信息。
==> 根据每个人的顺序标号%10获取所在的段序号,然后锁住对应的队列,然后再进行队列的操作,保证线程安全。
(4) 如何做到游戏排行榜的实现?
可以用Redis 的zset结构存储,但是当读写请求量过大了,怎么办??
解决方案:
1.规划一段区间为一个级别,形成多级,每一级对应一个Redis实例。
2.每个Redis实例排序
==> 这样子读写请求可以分散。
(5) 棋盘长M,宽N,从左上角走到右下角,只能往右走和往下走,问有多少种走法 ?
从m+n-2个数中,选择出n-1个。。
Cm+n-2 (n-1)
(6) 如何能够设计40亿QQ号的用户状态存储,我想找到都是90后(状态1)且是男的(状态2)的所有qq号?
1.倒排索引思想,状态1 对应 用户集合1,状态2 对应 用户集合2 。。。。。
2.用户集合用bitmap存储,如果是Long的话,能节省64倍的空间。且找交集和并集很方便,90后是 1000 1111,男的是 1110 0000,那么交集就是1000 0000只有1号都符合。
3.考虑到一个问题,bitmap可能存在很稀疏的问题。所以有个压缩bitmap算法。假设每个Long分成普通Word和RunningWord,
==> 3.1.普通Word就正常存储,按照顺序下来每个能存64个数。
==> 3.2. RunningWord就设置规则,高32位存储后面连续的普通Word数,低32位存储自己横跨(或者说是隐藏)了多少个Word。
==> 基于以上能节省空间,后面RunningWord会分裂,这种结构能实现动态扩容。
(7) 分布式唯一ID生成算法
雪花算法:
给大家举个例子吧, 64 bit 的 long 型数字:
-
第一个部分,是 1 个 bit:0,这个是无意义的。 (主要原因是因为ID都是正数,所以默认是0)
-
第二个部分是 41 个 bit:表示的是时间戳。
-
第三个部分是 5 个 bit:表示的是机房 id,10001。
-
第四个部分是 5 个 bit:表示的是机器 id,1 1001。
-
第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,0000 00000000。