海量数据面试题(位图、布隆过滤器、哈希切割)

对于处理海量数据,内存中放不下的数据一般有两种方法:
1.考虑特殊数据结构(位图、布隆过滤器)
2.切割(哈希切割、平均切割)
对于这类问题可以画图+文字+伪代码说明问题。
一:哈希切割topK问题:
给一个超过100G大小的log file,log中存放着IP地址,设计算法找到出现次数最多的IP地址?如何找到top K的IP?
对于本题采用哈希切割:
这里写图片描述
二:位图应用:
**给定100亿个整数,设计算法找到只出现一次的整数?
一个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的整数?**
本题利用数据结构位图:
这里写图片描述
解释如何设置次数:
这里写图片描述
代码如下:

#include<stdio.h>
#include<assert.h>
#include<windows.h>

typedef struct TwoBitSet
{
    size_t *bts;//数组
    size_t range;//数据的范围
}TwoBitSet;

void TBSInit(TwoBitSet *tbs,size_t range)
{
    assert(tbs);
    //需要两位表示一个数据,所以除以16,(range >> 4) + 1计算需要多少个整型
    tbs->bts = (size_t *)malloc(((range >> 4) + 1) * sizeof(size_t));
    assert(tbs->bts);
    memset(tbs->bts, 0,((range >> 4) + 1) * sizeof(size_t));
    tbs->range = range;
}
int TBSGetValue(TwoBitSet *tbs, size_t x)//
{
    assert(tbs);
    size_t index = x >> 4;//计算x在数组里下标
    size_t num = x % 16 * 2;//因为两位表示一位,需要乘2
    int value = tbs->bts[index];//不能改变tbs->bts[index],所以设置value
    value >>= num;//将value向右移
    return value & 3;//任何数和3(11)&为任何数
}
void TBSSetVaule(TwoBitSet *tbs, size_t x, size_t value)//设置值
{
    assert(tbs);
    size_t index = x >> 4;//计算x在数组里下标
    size_t num = x % 16 * 2;//因为两位表示一位,需要乘2
    if (value == 0)//设置为00
    {
        //先将3左移到要设置的位,然后取反,保证在这两位为0,然后&,这两位为0,其他为不变
        tbs->bts[index] &= ~(3 << num);
    }
    else if (value == 1)//要设置为01
    {
        tbs->bts[index] |= (1 << num);//设置1 
        tbs->bts[index] &= ~(1 << (num + 1));
    }
    else if (value == 2)//要设置为10
    {
        tbs->bts[index] |= (1 << (num + 1));//设置1
        tbs->bts[index] &= ~(1 << num);//设置0
    }
    else if (value == 3)//要设置为11
    {
        tbs->bts[index] |= (3 << num);
    }       
}
void BTSDestory(TwoBitSet *tbs)//销毁
{
    assert(tbs);
    free(tbs->bts);
    tbs->bts = NULL;
    tbs->range = 0;
}

给两个文件,分别有100亿个整数,只有1G内存,如何找到两个文件的交集?
本题利用数据结构位图:
如上个题:一个文件500M,文件A中数据出现一次将位图1中该位设置为1,再出现不用设置;文件B中数据出现一次将位图2中该位设置为1,再出现不用设置(一个整型32位,存32个数据),然后位图1&位图2,&结果为1的位则是两个文件的交集。
三:布隆过滤器:
给两个文件,分别有100亿个query,只有1G内存,如何找到两个文件的交集?分别给出精确算法和近似算法。
我们知道,布隆过滤器算法可以存储任意类型数据,尤其适用字符串,所以对于近似算法可以直接利用布隆过滤器,将query利用哈希函数放到布隆中,但这样误判率较大,可能该位置是其他字符串。所以,精确算法如下:
100亿个query,假设平均每个query占30字节,100亿个query占300G(10亿字节=1G,100亿*30字节=3000亿字节=300G)
这里写图片描述
*如何扩展BloomFilter使得它支持删除元素的操作?
如何扩展BloomFilter使得它支持计数操作?*
因为一个布隆过滤器的Key对应多个位,冲突的概率较大,所以不支持删除,因为删除有可能影响其他元素,如果要对其元素进行删除,就不得不对每一个位进行引用计数:
这里写图片描述
四:倒排索引
给上千个文件,每个文件大小为1K—100M。给n个词,设计算法对每个词找到包含它 的文件,只有100K内存?

这里写图片描述
输入需要查询的key:先找到映射位置,然后会根据key在每个文件出现次数将出现次数多的文件放在前面。
以上为海量数据如何处理的分析。

猜你喜欢

转载自blog.csdn.net/sophia__yu/article/details/80483541
今日推荐