如何从包含列表的大日志文件中查找特定用户的访问过的页面 每个单独行中的sessionId和PageId组合?
文件足够大,不适合内存。这意味着找出在同一会话(用户)中访问最多的页面。
例如。
我的文件是(订单是sessionId,PageID)
usera page1
userb page2
userb page1
usera page3
....
应打印
usera visits page1 most followed by page3.
如果页数 访问是平等的,由你决定如何处理案件(既可以打印,也可以打印任何 其中之一)
您将使用哪种数据结构/算法?由于这是一个访谈问题,因此可以理解有效的算法/数据结构。面试官没有说明他正在寻找的算法顺序。
我想出了std::map<string,std::pair<string,int> >
解决方案。面试官问我是否可以做比这更好的事情,或者如果密钥集如此之大,将无法通过地图有效处理,应该做些什么?
答案 0 :(得分:2)
我认为第一步是删除所有“非usera”行,因为你正在进行每用户解析。这将是一次性将所有用户分成不同文件的工作。之后,您可以进行逐行分析,只保留“历史记录”中的几行。您可以使用简单的行解析器执行此操作,而无需将整个文件存储在内存中。
如果它需要类似于数据结构的东西,你可能想要研究map-reduce范例 - Hadoop对于10GB +等级的文件来说是理想的。
答案 1 :(得分:0)
就我而言,我看到关键字为:同一会话。 在这种情况下,我们需要做的是不读取整个日志文件,而是尝试猜测这个特定的会话。
我们需要记住,会话将在特定时间段内保持活跃状态。定时由服务器设定,例如20分钟。 因此,在我们发现用户何时登录后,我们需要做的是在用户注销或上次活动会话时获取指向文件上特定位置的指针。
答案 2 :(得分:0)
您可以首先考虑使用外部排序对文件进行排序(将文件分解为适合内存的块并对每个块进行排序并将它们合并),您可以将已排序的文件再次分解为相同数量的块,但要跟踪范围每个块对应。有了这个,可以进行二进制搜索以找到相关的块,加载它并搜索任何用户。
由于它是一个已排序的文件,类似的用户条目将是连续的,实际上还可以在合并块期间计算出现的次数并写入附加到该行的值,供以后使用。