日志文件中特定用户访问过的页面

Visited pages for particular user from log file

本文关键字:访问 用户 文件 日志      更新时间:2023-10-16

如何从包含list的大日志文件中找到特定用户访问过的页面sessionId和PageId的组合在每一个单独的行?

文件大到内存无法容纳。它的意思是找出在同一会话(用户)中访问次数最多的页面。

例如

My file is (order is sessionId, PageID)

usera  page1
userb  page2
userb  page1
usera  page3
....

应该打印

usera visits page1 most followed by page3.

如果是页数访问是相等的,这取决于你如何处理的情况下(可以打印两个,或可以打印任何其中之一)

您将使用哪种数据结构/算法?由于这是一个面试问题,有效的算法/数据结构将受到赞赏。面试官没有说明他在寻找什么顺序的算法。

我提出了std::map<string,std::pair<string,int> >解决方案。面试官问我是否可以做得更好,或者如果键集太大,map无法有效处理,该怎么办?

我认为第一步是删除所有"非用户"行,因为您正在进行每个用户的解析。这将是一次性作业,将所有用户分隔到不同的文件中。之后,您可以逐行分析,只保留"历史记录"中的几行。您可以使用简单的行解析器来实现这一点,而不必将整个文件存储在内存中。

如果需要数据结构之类的东西,你可能想看看map-reduce范式——Hadoop将是10GB以上规模的文件的理想选择。

对于我来说,我看到关键字是:相同的会话。在这种情况下,我们需要做的不是读取整个日志文件,而是尝试对这个特定的会话进行猜测。

我们需要记住,会话将在特定的时间段内存活。时间由服务器设置,如20分钟。因此,在我们发现用户何时登录之后,我们需要做的是获取指向文件中用户何时注销或最后一次活动会话的特定位置的指针。

您可以首先考虑使用外部排序(将文件分成适合内存的块,并对每个块进行排序并将它们合并回来)对文件进行排序,您可以将排序后的文件再次分成相同数量的块,但要跟踪每个块对应的范围。这样,就可以进行二进制搜索来找到相关的块,加载它并搜索任何用户。

由于它是一个已排序的文件,类似的用户条目将是连续的,事实上,人们也可以在合并块期间计算出现的次数,并将值附加到该行,以供以后使用。