首页 > 其他分享 >百度面试题-海量日志,读取IP

百度面试题-海量日志,读取IP

时间:2023-04-03 19:09:00浏览次数:47  
标签:文件 面试题 映射 URL IP 内存 IP地址 日志



4、海量日志数据,提取出某日访问百度次数最多的那个IP。

回答:

如果日志文件足够的大,大到不能完全加载到内存中的话。


那么可以考虑分而治之的策略,按照IP地址的hash(IP)%1024值,将海量日志存储到1024个小文件中。每个小文件最多包含4M个IP地址。


对于每个小文件,可以构建一个IP作为key,出现次数作为value的hash_map,并记录当前出现次数最多的1个IP地址。



有了1024个小文件中的出现次数最多的IP,我们就可以轻松得到总体上出现次数最多的IP。



以上是题目,笔者对hash并不是很熟悉,所以借此机会能够练习一下哈希函数的作用吧:以上是hackbuteer1大神的解读,我想自己清理一遍希望能够获取一些新的感受:



1.对于海量日志,我们要将起分离开来,怎么分离呢,就是将同一个IP地址的记录分散到同一个日志文件当中去,这就是分离策略,这里面使用的是哈希值的方法



2.读取每一个小文件的最大的IP访问量,将该IP地址记录下来,然后将1024个记录进行比较,获得最大的那个,即是结果所在了



但是问题来了,既然内存不够,那么我们怎么读取文件的一部分呢?答案是使用文件映射,



看下FileMapping的使用建议



 File mapping is effective in the following situations:



    You have a large file whosecontents you want to access randomly one or more times.



    You have a small file whosecontents you want to read into memory all at once and accessfrequently. This technique is best for files that are no more thana few virtual memory pages in size.



    You want to cache specificportions of a file in memory. File mapping eliminates the need tocache the data at all, which leaves more room in the system diskcaches for other data.



   You should not use file mapping in the followingsituations:



    You want to read a filesequentially from start to finish only once.



    The file is several hundredmegabytes or more in size. (Mapping large files fills virtualmemory space quickly. In addition, your program may not have theavailable space if it has been running for a while or its memoryspace is fragmented.)



其含义就是



1.如果你有一个大文件,但是只是

随机读取其不同位置的内容,可以使用文件映射



2.你有一个小文件,并且想

快速的将其读入到内存当中,使用该技术是最适宜的,



3.如果你想缓存指定内容,在内存中,文件映射文件映射则可以使得不去专门去做该缓存操作,文件映射为其他的数据在系统中留下了更多的空间


也就是说,使用文件映射,文件在打开或者使用CreateFileMapping时,都没有将文件内容装入内存而是在读取内容的时候才会读取文件内容到内存中去,也就是说对一个很大的文件我们可以Mapping一部分,操作完成后然后Unmapping,再mapping下一部分,..以此类推,我们就可以解决文件过大,而内存不足的问题了首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。与之不同的是fstream文件流,该文件在打开时就已经将文件内容读入内存中,故而,如果文件内容过大,则会导致文件打开失败。好了,现在假设每一个IP记录独占一行,所以呢,我们应该怎么做呢,就是要将,IP地址映射到不同的小文件当中去,源代码如下

#include "stdafx.h"   
#include<iostream>   
#include<fstream>   
#include<Windows.h>   
using namespace std;  
char* strURL[200];  
bool isEnd=false;  
//根据URL值,获得该URL的哈希值,分配到不同的小文件当中   
int getHash(char*URL)  
{  
    int index=0;  
    int nCount=0;  
    while(URL[index]!='\0')  
    {  
        nCount+=URL[index];  
        index++;  
    }  
    return nCount%1024;  
}  
//根据文件句柄获和文件偏移量获得当前位置的下一个URL   
//该函数主要是根据文件当前的位置,开始一个一个读取字符,知道遇到换行符,即可说明,该URL已经结束,返回该URL的内容即可   
//其实就是自己实现.getLine函数   
char* getSingleURL(LONG offset,LONG &curPos)  
{  
    char* strFilePath="D:\\out.txt";  
    HANDLE hFile=CreateFileA(strFilePath,FILE_ALL_ACCESS,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  
    if(hFile==INVALID_HANDLE_VALUE)  
    {  
        cout<<"文件打开失败:"<<GetLastError();  
        return 0;  
    }      
    int nFileSize=GetFileSize(hFile,NULL);    
    curPos=offset;  
    //首先移动文件指针     
    LONG midVal=0;
    DWORD nowPos=SetFilePointer(hFile,offset,&midVal,FILE_BEGIN);      
    if(nowPos>nFileSize)
    {
        isEnd=true;
        return NULL;
    }
    char tmp=1;  
    DWORD ByteRead=0;  
    while(tmp!='\n')  
    {  
        if(ReadFile(hFile,&tmp,1,&ByteRead,NULL))  
        {

            if(ByteRead!=1)
            {                
                isEnd=true;
                break;
            }
            else
                offset++;
        }
        else
        {
            cout<<GetLastError()<<endl;
        }

    }  
    DWORD urlLen=offset-curPos;  
    if(urlLen==0)
    {
        cout<<"文件读取结束\n";
        return NULL;
    }
    char* curURL=new char[urlLen+1];  
    memset(curURL,0,urlLen+1);    
    SetFilePointer(hFile,curPos,&midVal,FILE_BEGIN);  
    ReadFile(hFile,curURL,urlLen,&ByteRead,NULL);  
    curPos=offset;  
    CloseHandle(hFile);  
    return curURL;    
}  
//将URL写入对应的文件当中去   
bool WriteToFile(char* URL,int nFileMark)  
{  
    ofstream out;  
    
    char tmpName[20]={0};    
    sprintf(tmpName,"%s%d.txt","D:\\result",nFileMark);
    out.open(tmpName,ios::app);  
    if(URL[strlen(URL)-1]=='\n')
    {
        URL[strlen(URL)-1]='\0';
    }
    out.write(URL,strlen(URL));      
    return true;    
}  
int main()  
{  
    //读取文件中的URL值   
    LONG nOffset=0,nCurPos=0;
    while(true)  
    {  
        char* curUrl=getSingleURL(nOffset,nCurPos);    
        if(isEnd)  
        {  
            break;  
        }  
        WriteToFile(curUrl,getHash(curUrl));  
        delete[]curUrl;  
        nOffset=nCurPos;  
    }  

    return 0;  
}


PS:笔者在调试这程序的时候本没什么问题,但是在SetFilePointer总是返回0,花费了我整整一天的时间,结果是参数填写错误!!还是希望以后的初学者慎重啊...


标签:文件,面试题,映射,URL,IP,内存,IP地址,日志
From: https://blog.51cto.com/u_15995156/6167061

相关文章

  • MySQL 关闭 binlog 日志
    【关闭binlog日志】1、vim/etc/my.cnf注释如下内容:#log-bin=mysql-bin#binlog_format=mixed#server-id=1#expire_logs_days=102、重启mysql服务/etc/init.d/mysqlrestart......
  • NetBeans VS Eclipse,新一轮的争端
    www.theserverside.com,www.javalobby.org,dev2dev论坛等多个Java论坛上争论着一个非常激烈的话题:WhyEclipseDevelopersAreMovingToNetBeans(为什么Eclipse开发者正在转向NetBeans)。不知道是什么原因,如此简单的争端到了后来也会有些发霉的味道。不能否认,这些言论最......
  • ubuntu eclipse 下驚醒GTK的配置(全)
    偶然的想法想玩玩GTK,因为Qt就是对gtk的C++封装,想着gtk应该比qt更高的执行效率吧,下面分享下自己搭建的过程。 1、我的ubuntu虚拟机是安装了eclipse+cdt的,如果是安装了eclipse没有安装CDT,则要安装CDT:     .可以在Eclipseupdate中输入以下地址来安装:http://download.eclipse......
  • DHCP自动获取IP地址
    拓扑图:推荐步骤:Centos01安装dhcp服务器,配置地址池范围192.168.100.100~192.168.199,默认网关为192.168.100.10,首选和备用DNS地址为202.106.0.10,8.8.8.8,Win10配置保留指定IP地址配置Centos02为自动获取IP地址,Wiin10查看保留IP地址实验步骤:Centos01安装dhcp服务器设置为开机自动启动配......
  • springboot 日志
    <loggername="com.sinoservices.chainwork.bms"level="INFO"/><loggername="org.hibernate.orm.deprecation"level="error"/><loggername="druid"additivity="true"><levelval......
  • Python常见面试题015.请实现一个如下功能的函数
    015.请实现一个如下功能的函数来自python黑魔法题目实现一个add函数,可以"反复"调用,得到累加的结果defadd(num):...add(1)#输出1add(2)#输出2add(1)(2)#输出3(即1+2)add(1)(2)(3)#输出6思考一开始我想到的是用一个参数,类型是list,能保存用户的传......
  • IPMI添加用户
    1、查看用户清单ipmitooluserlist12、创建用户ipmitooluser setname3test3、设置密码ipmitoolusersetpassword3Test@1234、给用户权限ipmitoolchannelsetaccess13callin=onipmi=onlink=onprivilege=45、查看权限ipmitoolchannelgetaccess136、比较用......
  • 力扣---面试题 02.01. 移除重复节点
    编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。示例1:输入:[1,2,3,3,2,1]输出:[1,2,3]示例2:输入:[1,1,1,1,2]输出:[1,2]提示:链表长度在[0,20000]范围内。链表元素在[0,20000]范围内。进阶:如果不得使用临时缓冲区,该怎么解决?来源:力扣(LeetC......
  • ipmitool详解
    1、ipmitool(IPMITool)是一个开源的命令行实用程序,用于与基于IPMI(IntelligentPlatformManagementInterface)协议的远程管理控制器(RMC)通信。IPMI是一种硬件标准,它定义了一组接口和协议,用于管理和监控服务器等计算机系统。通过IPMI,管理员可以使用远程控制台、Web界面或命令行接口来......
  • iptables 跳板机转发策略
    1、中转机执行策略。iptables-tnat-IPREROUTING-s10.*.*.125/30(对端过来地址出口)-ptcp-mtcp--dport28070-jDNAT--to-destination10.15.2.10:28070对端过来的流量转到到内网另一台机器iptables-tnat-IPREROUTING-s10.15.2.10-ptcp-mtcp--dport80-jD......