想起几年前刚毕业有一道面试题。

讨论 未结 12 39
frank1256
frank1256 会员 2022年9月17日 03:12 发表
<p>语言限制 Java 吧,内存 4g 。</p> <p>效率最高 从 Msql 里读取 50W 条数据,写入 execl 的方法。</p> <p>现在想想这个题目,我给的答案是游标读取 mysql ,randomAccess 或者 nio 写入 execl ?各位大佬指点指点,感觉好像怪怪的。</p>
收藏(0)  分享
相关标签: 灌水交流
注意:本文归作者所有,未经作者允许,不得转载
12个回复
  • wangyiyi10
    2022年9月17日 04:14
    感觉应该是顺序写 csv 文件吧? EXCEL 可以打开是不是就满足写入 excel 了。
    0 0
  • makdon
    2022年9月17日 04:43
    读 mysql 可以并行分页拉,这样瓶颈在网络带宽 /MySQL 性能 写文件如果是 xlsx 的话可能比较慢,如果是 csv ,用 mmap 写应该会快一点? 题目信息有点少,应该是展开聊的开放题吧
    0 0
  • VensonEEE
    2022年9月17日 06:42
    各位大佬,50W 很多么?能写 excel 的,估计也没有大字段吧,4G 内存还不够?
    0 0
  • az467
    2022年9月17日 08:13
    多线程提效率,减少 CPU 浪费,流式处理防止 OOM 。 不过五十万这数据量也太小了。
    0 0
  • mylifcc
    2022年9月17日 08:13
    其实就是考一个数据几 k 一次读满 4g 多少条 这种思维 感觉没啥卵用
    0 0
  • berg223
    2022年9月17日 10:45
    假设一行数据有 50 个字段,每个字段 8 字节,一行占用 50*8=400B ,大约 2.5 分之一 KB ,50w 除以 2.5 大概 200MB ,数据量不算大,4g 内存大概是这个规模的 20 倍,不算大的,也就是说每个字段 8 字节,1000 个字段才会在内存上有瓶颈。瓶颈是在 io 上,假设数据是写到同一块机械硬盘上,仅考虑性能的话,在写的时候实际上都不需要并发和 nio 啥的,直接拼接成一个 csv 格式的字符串往硬盘上怼,最大化利用磁盘顺序写的特性,这样速度理论上应该最快。但是实际工作中考虑扩展性不应该这么干。事实上这块的 io 应该是 ms 级别的。 假设要读取的 mysql 数据是同一块硬盘,多线程也不一定比单线程快,因为瓶颈在于 io 上,读取的 io 分两类,一个是程序和 mysql 之间的网络连接,另一个是 mysql 读取磁盘的 io 。对于第二类肯定单线程比多线程快,对于第一类来说多连接应该比单连接要快,假设机房带宽是 100Mbps=12.5MB ,那么单连接传输 200MB 数据大概需要 200/12.5=16 秒,假设磁盘速度是 100MB/s 的话,单次读取所有数据就只需要 200/100=2 秒,加在一起就是 18 秒,开 x 个连接读取等量数据大概需要 16+2/x 秒,优化空间是秒级别的,最大优化空间不超过 2s ,当然不是 x 越大越好。 综上,这题最多优化 2s ,未优化前速度大概是 20s 左右,确实没多大优化空间。
    0 0
  • berg223
    2022年9月17日 10:45
    更正下,事实上这块的 io 应该是 ms 级别的更正为 “事实上这块的 io 的优化空间应该是 ms 级别的”。
    0 0
  • berg223
    2022年9月17日 11:13
    回头看了下直接拼接成字符串往磁盘上怼应该是有问题的,需要把 jvm 的常量池设置大一些。。
    0 0
  • berg223
    2022年9月17日 11:13
    还是不对,字符串常量是在堆中的,只有字面量才会在常量池中,所以应该注意的不应该是常量池的大小。
    0 0
  • noparking188
    2022年9月17日 14:12
    #7 老哥解答的很棒 我 Java 不熟悉,不过稍微熟悉一点 Spark ,Spark 读 JDBC 的时候有一些参数设置提供范围分区并发读取,不过需要一个数字类型主键。对于文件 IO ,这个也许可以参考 Kafka 写优化的特点
    0 0