题目
编程题:⼀个⽂件(url_path_statistics.txt)中存储了本站点下各路径被访问的次数
- 请编程找出被访问次数最多的10个路径
- 时间复杂是多少,是否可以优化(假设路径数量为n)
- 如果路径访问次数⽂件很⼤(GB级别),如何优化内存?
- 【可选】如何从Nginx原始⽇志⽇志(access.log,TB级别)中⽣成路径访问⽂件
(url_path_statistics.txt,GB级别),需要考虑优化内存(可以只写思路)
⽂件样本示例:url_path_statistics.txt
第一题答案
1.1 文件内容
/url/path1:185
/url/path2:198
/url/path3:704
/url/path4:137
/url/path5:909
/url/path6:68
/url/path7:51
/url/path8:450
/url/path9:275
/url/path10:605
/url/path11:782
/url/path11:182
/url/path11:82
/url/path11:999
/url/path11:55
/url/path11:1042
1.2 编码实现
public static void main(String[] args) {
//文件路径
String fileName="D:\\test\\url_path_statistics.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
//字典存储文件中的路径和访问次数信息
TreeMap<Integer,Map<String,Integer>> resultMap=new TreeMap<>();
while ((line = reader.readLine()) != null) {
if(StringUtils.isNotBlank(line)){
String[] split = line.split(":");
if(split!=null){
int key = Integer.parseInt(split[1]);
Map<String,Integer> tempMap=new HashMap<>();
tempMap.put(split[0],key);
resultMap.put(key,tempMap);
}
}
}
//map倒叙
NavigableMap<Integer, Map<String, Integer>> sortedMap = resultMap.descendingMap();
AtomicInteger i= new AtomicInteger();
//取前10个
sortedMap.forEach((k,v)->{
if(i.get() <10){
System.out.println(v);
i.set(i.get() + 1);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
运行结果:
第二题答案
读取文件并将数据存储到字典中的时间复杂度为O(n),其中n为路径数量。 对字典进行排序的时间复杂度为O(nlogn)。 总的时间复杂度为O(nlogn)。是否可以优化取决于具体的情况,如果数据规模很大,可以考虑优化排序算法或者采用其他数据结构。
第三题答案
如果路径访问次数文件很大(GB级别),可采用缓冲池的形式进行数据的读取,可以避免内存飙高,以及OOM的问题。
还可以进行分块读取:将文件分成多个小块,逐块读取并处理,减少同时加载大文件带来的内存压力。
还可以采用基于磁盘的外部排序:将文件划分为多个较小的临时文件,对每个临时文件进行排序,然后合并排序结果。
第四题答案
逐行读取Nginx原始日志文件。 解析每一行日志,提取出路径信息。 统计每个路径被访问的次数,可以使用字典结构存储路径和对应的访问次数。 将统计结果写入文件中。为了优化内存,可以使用分块写入,避免一次性将所有数据存储在内存中。