给定一个10GB大小的文件,存储的都是数字,如何对文件中的数字进行排序,并输出新文件?限制内存只有1GB

news/2024/11/17 7:21:49/文章来源:https://www.cnblogs.com/xyuanzi/p/18351052

背景

这是一道面试题,可考察的点也不少。总结几个关键词去解决这个问题,1,文件拆分;2、排序算法;3、缓冲buffer性能优化。
啊,乍一看,这绝对不是一个初级程序员能够答出来,且能答得很好的问题,这个题目可以考察到我们的算法能力,性能优化经验。可万万不能马虎对待!

开始讲思路。第一步,

文件拆分

首先外部输入的文件,如果不出意外的话大文件,我们都不建议一次性地将其加载到我们的内存中,内存可是很宝贵的,它还要干其他很多很多的事情。不能因为一个文件的导入,而让内存陷入卡顿的危机。所以,针对这种大文件,我们首先就是给他做个拆分,即批量处理嘛,因为本质是给数字进行排序,那我就将这个大文件拆分为15个小文件。
然后依次将这些文件加载到内存中,经过我们的排序算法(可以是快速排序,堆排序,归并排序,等,当然你非要用冒泡我觉得也可以,不过大家应该还是比较喜欢快一点的排序算法), 输出一个新的有序文件。这样一通操作下来,我们就有个15个新的已经是有序的文件了。但是,我们最终需要输出一个大文件,大小还是10GB的有序文件。
所以,来到第二步。

多路归并

多路归并的意思就是说,将这个几个有序的文件中的数字,全部归在一起,做一个整体的排序。然后输出一个有序的大文件。
想必大家也听说过归并排序。那这里可以直接拿来用吗?不好意思,用不了。归并是针对两个数组,每次拿出数组中的两个元素进行比较,那如果是三个数组的话,不就不好比较了。
有一种办法是先取出两个文件进行二路归并,然后再将输出的有序文件和第三个无序文件进行归并,这样我们归并到后面,数字越来越多,有占满内存的风险。
本博文将讨论一种比较好的多路归并办法,也是通用的技术,就是使用堆排序。
针对15个有序文件,先新建一个最小堆,然后取这个15个文件中的第一个元素进行初始化。一定要一层一层取,这样不会乱序。

堆内会自动排序,最小堆的堆顶放置的是最小的元素。
然后,取出堆顶元素,使用一个数据结构list存放起来。接着,我们依次处理剩余文件中的数字,遍历15个文件,每次从文件中取出一个数字,放入堆中,此时堆内自动排序,就会将最小元素放置在堆顶, 我们移除堆顶元素放入list中。这样子,一个一个处理,最终遍历结束以后,List 中就会得到一个有序的数字集合。
最终我们将List中的数字输出到文件持久化存储就好了。
关于堆排序的过程,可以见其他博客。

性能优化

仔细看多路归并这个过程,发现list存储10GB的数字会不会有点太大了呢?而且,每次从文件中取数字,一层一层取,A文件第二个,B文件第二个,C文件第二个....A文件第三个,B文件第三个,C文件第三个, 这样与磁盘的交互是不是有点太频繁了。这个时候,考虑使用缓冲区优化吧,不然太消耗IO了。
放大招,使用Buffer。由于我们处理的是整型数字,所以可选择IntBuffer,容量可设置为8KB,这个根据需要处理的数据量来定。
这样,多路归并的过程就可以是,遍历文件,每次从各个文件中取出一个元素,放入buffer。取个几层以后,buffer要满了,我们再将buffer中的数据拿去做堆排序。
然后清空buffer, 继续遍历文件,取元素,重复以上过程。
同样的,对于List中这个数据结构,我们也使用一个输出buffer去接收已排序的元素。等buffer满了,将数据flush到输出文件中。
以上就是这个问题的整体思路啦。还有什么要补充的, 欢迎打在评论区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780405.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从「数据资产入表」到「数据资产运营管理」,成功的关键在于找到合适的数资服务提供商

璞华科技在数据服务领域深耕细作,不断突破创新,近来荣膺多项重要认证与荣誉。 璞华易表数据资产运营管理平台正式获得国家计算机软件著作登记证书。这一殊荣不仅是对璞华科技研发团队技术实力的肯定,更是对璞华易表产品原创性和创新性的高度认可。它标志着璞华易表在软件开发…

基于米尔芯驰MY-YD9360商显板的神经网络推理库测试

本篇测评由优秀测评者“短笛君”提供。 本文将介绍基于米尔电子MYD-YD9360商显板(米尔基于芯驰D9360国产开发板)的TinyMaxi轻量级的神经网络推理库方案测试。 算力测试 TinyMaix 是面向单片机的超轻量级的神经网络推理库,即 TinyML 推理库,可以让你在任意单片机上运行轻量级…

Qwen2-Math 开源 AI 模型发布;阿里云推出首个域名 AI 大模型应用丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内…

ssh连接失败,排错经验

一、场景描述 ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通。 场景:[root@yl-web ~]# ssh root@10.1.101.35 ssh_exchange_identification: read: Connection reset by peer [root@yl-web ~]# ping 10.1.101.35 PING 10.1.101.35 (10.1.101.35) 56(84) bytes o…

面向忙碌的-Java-开发者的-Python-教程-全-

面向忙碌的 Java 开发者的 Python 教程(全)原文:Python for the Busy Java Developer 协议:CC BY-NC-SA 4.0一、语言 让我们从了解 Python 与 Java 的不同之处开始我们的 Python 之旅。在下一章深入研究 Python 的语法之前,我将帮助你设置 Python。 Python 是什么? Pytho…

maven搭建的springboot项目,引用了其他moudle的类,明明有这个类,install的时候确报错找不到这个类

其实这个问题是maven打包插件引起的,正常配置,install后包内首层会出现BOOT-INF这个目录,导致别的moudle打包install引用时找不到正确的目录 正常配置 打包后看引用的jar包就会有一层BOOT-INF目录包括着。 修改配置为下图,重新打包就没有了BOOT-INF目录了。再次引用并insta…

vue+iview-table点击展开展示内容,表格嵌套

实现如下效果的表格嵌套: 点击展开,展示tabs。 table的columns里设置展示的属性,然后属性里设置返回一个组件,然后在组件里写嵌套的内容。 <Table :columns="tableColumns" :data="tableData" style="width:100%" @on-selection-change=&…

Python-和-PowerShell-协作教程-全-

Python 和 PowerShell 协作教程(全)原文:PowerShell and Python Together 协议:CC BY-NC-SA 4.0一、面向调查人员的 PowerShell 简介 PowerShell 提供了一个强大的获取引擎,可以从实时系统、服务器、外围设备、移动设备和数据驱动的应用程序(如 Active Directory)中获取大…

Blender-Python-API-教程-全-

Blender Python API 教程(全)原文:The Blender Python API 协议:CC BY-NC-SA 4.0一、Blender 界面 本章讨论并定义 Blender 界面的组件。它作为我们在整个文本中讨论界面时使用的词汇的参考。我们将关注 Python 开发中最常用的接口组件,并为高效的 Python 脚本设置自定义接…

2024暑期学习(一)

摸鱼~2024暑期学习(一) 非常非常非常感谢ve1kcon!^ ^✌️2024年暑期学习 (1) - ve1kcon - 博客园 (cnblogs.com) 学习内容: 1.复现了一点点题目 2.了解了C++异常处理 3.学习了Tmux的使用 cqb2024x ctf stdout 前置内容(copy): setvbuf() 函数的原型如下 int setvbuf(FILE *s…

数字样机:惯性导航系统控制单元仿真

01.简介 惯性导航系统 (INS,Inertial Navigation System) 基于惯性原理建立,而惯性是物体自身的固有属性,因此其工作时既不依赖于外部信息,也不向外部辐射能量,优于卫星导航与无线电导航,是一种具备隐蔽性、自主性的导航系统,被广泛应用于航空航天、无人机、智能交通等各…