海量数据处理(面试)

题目:
1、海量日志数据,提取出某日访问百度次数最多的那个IP。
假设有一个大文件,里面以字符形式存储了IP与IP访问次数,这两数据按空格隔开,然后一行对应一个IP。
解决思路
算法思想:分而治之+Hash
1.IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;
2.可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
3.对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址;
4.可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;

解决过程中的问题:
(1)我的是FAT16文件系统,一个根目录下文件数量有限制,只能存放512个文件,我在批量创建的时候因为限制只有509个,所以我就按照509开始分文件
(2)
批量打开文件的函数
应当注意的是在写文件描述符关闭后才可以打开读的

void openFileOut(ofstream *out)
{
    for (int i = 0; i < 509; ++i)
    {
        char path[100] = "D:\\VS2015\\代码\\C++file\\C++file\\文件\\";
        char name[10] = { 0 };
        _itoa_s(i, name, 10);
        strcat_s(name, ".txt");
        strcat_s(path, name);
        out[i].open(path);
    }
}

void openFileIn(ifstream *in)
{
    for (int i = 0; i < 509; ++i)
    {
        char path[100] = "D:\\VS2015\\代码\\C++file\\C++file\\文件\\";
        char name[10] = { 0 };
        _itoa_s(i, name, 10);
        strcat_s(name, ".txt");
        strcat_s(path, name);
        in[i].open(path);
    }
}

对应的测试函数,起码创建和读取都没有问题

int main()
{
    ofstream out[509];
    ifstream in[509];
    openFileOut(out);


    //测试是否能够有效写入
    for (int i = 0; i < 509; ++i)
    {
        char name[4] = { 0 };
        _itoa_s(i, name, 10);
        out[i].write(name,strlen(name));
    }

    for (int i = 0; i < 509; ++i)
    {
        out[i].close();
    }

    openFileIn(in);
    //测试是否能够有效读取
    for (int i = 0; i < 509; ++i)
    {

    long size;
    char* buffer;
    in[i].seekg(0, ios::end);
    int l = in[i].tellg();

    in[i].seekg(0, ios::beg);
    int m = in[i].tellg();
    size = l-m;
//  cout << "size=" << size<
    buffer = new char[size+1];
    buffer[size] = '\0';
    in[i].read(buffer, size);
    in[i].close();
    cout << buffer << endl;
    delete[] buffer;
    }

    for (int i = 0; i < 509; ++i)
    {
        in[i].close();
    }
    return 0;
}

自己给的求哈希地址的函数(要让他均衡分布,我也不知道自己取法算不算优异)

int getHash(char* str)
{
    int result = 0;
    const char *d = ".";
    char *p=NULL;
    char* pNext = NULL;
    p = strtok_s(str, d, &pNext);
    while (p)
    {
        result = atoi(p)*(rand()%255)+result;//这个就是让计算随机化
        p=strtok_s(NULL, d,&pNext);
    }
    return result%1024;//获取哈希的值然后写到应有的文件中去
}

接下来就是读取一下大的文件,把每一行的数据按照哈希分布分布到它应当存储的那一号文件中去,分布完成,关闭所有写,开始按照内存取得方法,取出509个文件中的分别的最大值,然后再进行一次比较就好了

你可能感兴趣的:(面试)