昨天去笔试阿里巴巴,觉得附加题有些意思,具体想法写了个大概
题目大概是:
1亿个用户,200w商品,每个用户喜欢一些商品 ,求每个用户与其他用户的相同喜好度,所谓相同喜好度就是A喜欢的商品,B有多少是喜欢的
用户ID是32位整数 商品ID也是32位整数
输入文件:
用户ID 喜欢的商品1的ID 喜欢的商品2的ID .......
输出:
用户ID 用户AID 相同的喜好度 用户BID 相同的喜好度..........
思路:
由于数据量很大,一亿个用户两两比较显然不现实,而且是200w个商品,如果每个商品用一个位,也需要200w/8*1024~250k,时间和空间都不太满意
我认为还比较靠谱的解法如下:
第一步:
这里我考虑到按商品先建索引:GOODS_MAP<GOOD_ID,LIST_OF_USERID>
GOOD_ID是key,LIST_OF_USERID是喜欢该商品的用户首先将输入文件逐条读入,
eg 假设用户甲 喜欢A,B,C,D
读入后的效果是这样的,key为A的list中包含甲,key为B的list中加入甲,key为C的list中加入甲,key为D的list中加入甲
这样处理完毕后,就建立了按商品ID为KEY,喜欢该商品的USER的LIST为值的MAP数据索引
第二步:
建一个USER_MAP<USER_ID,LIST_OF_USERID>
USER_ID是key,LIST_OF_USERID放入的是和该用户有相同喜好商品的用户ID
遍历一遍GOODS_MAP,然后建索引:
假设goods_map的一行数据如下:key=A, list={甲乙丙丁}
这时候,根据list中的甲乙丙丁分别作为key加入到USER_MAP,他们的list都加入甲乙丙丁
继续这个过程,直到遍历完GOODS_MAP
第三步:
这时候USER_MAP中存放的数据可能是这样:
key = 甲, list= {甲乙丙丁甲丙丁戊甲乙丙甲丁戊........}
其中乙出现的次数就是甲乙同时喜欢的商品的个数,由于userID就是一个32为整数
因此接下来可以将list排序,list可能为{甲甲甲甲甲甲甲....乙乙乙乙....丁丁丁....丙丙丙... .........}这个样子
这样只需要统计一下每个用户ID出现的个数,就可以得到相同喜好度了
对每一列进行排序统计,直到结束
整个过程大概就是这样
PS:由于1亿用户有些大,刚开始可以将它分成20个500w用户的文件,然后交给20个机器去建GOODS_MAP
然后将它们按key合并成一个GOODS_MAP
接下来生成USER_MAP后,也可以按用户ID分成很多的部分去做排序统计,然后直接合并,或者直接输出成很多文件