问题
面试时经常被问到的一个问题:几万亿的数据分布到几千台网络连接的计算机中,怎么最少的数据交换,最快的速度找到这些数据的中位数?(备注:看看候选人是否愿意澄清题意,数据是什么类型?计算机是怎么连接的?顺便考考网络。)

首先,看看什么是中位数。通用的定义是,给出一个排序好的列表,中间的那个元素就是中位数。比如,对有11个元素的排序好的列表[1 1 2 3 3 4 5 5 5 6 9],中位数就是离左右各5个元素位置的中间的那个元素,它的值就是列表中的4。(备注:如果候 选人不知道中位数,通过简单的例子,看看候选人是否能够快速理解和学习。这儿,可以考考候选人,如果是偶数个元素时,他会怎么做。)

那么这道题为什么值得作为一道面试题呢?

让我们来进行一些简单的估算,一万亿(10^12)个整数,按每个整数4个字节,4x10^12字节=4x10^9KB=4x10^6MB=4x10^3GB,如果每个机器内存4GB的话,需要存放到1000台机器上。所以,不是简单的排序就好解决的问题。。。(备注:这些看是简单的估算,就可以用来考察候选人的计算机基础知识。)

算法

分区和支点

只是为了求中位数而做一个完全排序,毫不奇怪的有点浪费。我们所需要的只是找到中间点的一个元素,离左右都有同等数量的元素。

解决这种问题,常用的操作是分区(partition),是著名的排序算法快排(quicksort)的基础。(备注:可以问问候选人有关排序的基础问题和算法复杂度什么的。)

快排算法的过程是这样的(备注:让候选人回忆一下。),选择一个元素,称作支点(pivot),然后通过移动(shuffling/洗牌)周围的元素,将支点元素移动到到正确的排序后的位置。所有比支点小的元素移动到列表的前面,其它的,等于或是大于的元素,保持在原位,也就是列表的后面。分区之后,支点元素就在正确的排序位置了,尽管整个列表还是无序的。(备注:可以让候选人写一个partition函数看看代码功底。)接下来,可以递归的使用同样的分区方法,对支点前的元素列表,和支点后的元素列表,最后完成排序。(备注:写一个quicksort函数。)

对于找中位数,我们可以使用类似的思路:采用第一个支点分区的思路,但不用做完整排序所要求的额外工作。

顺序统计量

对于一个排序好的列表,第n个顺序统计量就是列表中的第n个位置的元素(备注:考考概率知识。)。比如,对于一个9个元素的列表,第1顺序统计量就是最小元素;对于一个m个元素的列表,第m顺序统计量就是最大元素;对于一个2m个元素的列表,第m顺序统计量就是中位数。

支点选择

完美支点

让我们来看一个例子,假如有一个列表

[4 3 1 1 5 9 2 6 5 3 5]

对于一个2m个元素的列表,我们用下划线来表示第m顺序统计量。

我们的目标是找中位数,也就是第6顺序统计量。如果我们用列表中的第一个元素,即4,来分区,列表如下

[3 1 1 2 3 4 5 9 6 5 5]

我们用红色来指示那些小于支点的元素,绿色来指示等于或大于支点的。

因为4移动到了第6个位置,我们说4是第6顺序统计量。很幸运,支点元素正好是我们寻找的中位数。所以这个支点元素4,就是中位数。

这比快排(quicksort)少了很多的工作量,因为我们不用排序子列表[3 1 1 2 3]和[5 9 6 5 5]。但是,这只是由于4碰巧是一个好的选择。但是如果分区后,支点元素不是第6顺序工作量,该怎么办?

支点在中位数位置右边

考虑支点在中位数位置右边的情形

L1 = [6 3 1 1 5 9 2 4 5 3 7]

如果用第一个元素6来分区,我们得到

L1 = [3 1 1 5 5 2 4 3 6 9 7]

这次,6移到了第9顺序统计量。因为我们找寻的是第6顺序统计量,我们知道6不是中位数。更因为第9顺序统计量在第6顺序统计量的右边,所以我们知道中位数必须小于6。因此,我们不但知道6不是中位数,中位数也不可能是9或者7。这很重要,因为我们可以完全扔掉这些值。

L2 = L1 - [6 9 7]

L2 = [3 1 1 5 5 2 4 3]

L1的第6顺序统计量,也就是中位数,这时变成了L2的第6顺序统计量。因为我们扔掉了中间值之后的所有值,我们可以继续寻找同样的顺序统计量。注意了,L2的第6顺序统计量并不是L2的中位数。L2的中位数应该是第4顺序统计量。

支点在中位数位置的左边

考虑下面的情况,支点落到了中位数位置的左边。(备注:看看候选人是否能按照前面的分析来分析。)

L1 = [2 3 1 1 5 9 3 6 5 3 5]

同样,我们寻找中位数,第6顺序统计量。 围绕着第一个元素2来分区,我们得到

L1 = [1 1 2 3 5 9 3 6 5 3 5]

这时,支点元素是第3顺序统计量,但是我们需要的是第6顺序统计量。因为第3顺序统计量在第6顺序统计量的左边,同样,1也不是中位数,可以安全的扔掉所有小于支点的元素。

L2 = L1 - [1 1]

L2 = [2 3 5 9 3 6 5 3 5]

L1的第6顺序统计量,也就是中位数,到了L2,变成了第4顺序统计量。因为我们扔掉了中间值之前的元素,我们需要调整找寻的顺序统计量。

小结

如果我们找寻第k顺序统计量,且我们选择了一个支点正好就是,那么我们找到了中位数。否则我们扔掉一些值,调整我们寻找的顺序统计量,然后继续同样操作。

边角情形一

(备注:面试时,对于高级的,我们可以考察他们是否能发现这种情形。这同样也适用于测试,或是发现bugs。)

假如列表是

L1 = [2 3 1 1 5 9 3 6 5 3 5]

我们选择了第一个元素2,作为支点且扔掉了一些元素(所有的1),得到

L2 = [2 3 5 9 3 6 5 3 5]

现在继续,选择第一个元素2,作为支点,我们没有扔掉任何元素,又得到

L3 = [2 3 5 9 3 6 5 3 5]

我们被卡住了,不能有任何进展。所以,如果支点元素又是第一个元素,我们需要转动列表,也就是将第一个元素移到最后,然后继续。

边角情形二

(备注:候选人能发现这种情况吗?)

如果所有的元素都是一样的,转动列表也不能解决问题。比如,

L1 = [3 3 3 3 3]

对于这种情况,需要特殊处理。这也简单,看看列表的最大元素是不是和最小元素一样大。如果一样,第一个元素就是中位数。

几个快捷情形

如果是找寻列表的第1顺序统计量,只要扫描最小元素。如果是找寻k个元素列表的第k顺序统计量,只要扫描最大元素。

分布式

刚才设计的算法可以做些小的修改就能工作在分布式环境中。(备注:候选人怎么推广到分布式环境中?)

实际上,将列表中的元素移动到支点之前是不必要的,我们所感兴趣的是支点在分区后在列表中所在的位置。这个可以通过计数多少元素小于支点元素,然后加1,就得到最后的位置。

我们重新回顾一下之前的例子。

支点在中位数位置的右边

L1 = [6 3 1 1 5 9 2 4 5 3 7]

如果计数有多少个元素小于6,我们得到8。所以6是第9顺序统计量,又因为第9大于第6(中位数位置),我们需要扔掉所有值大于等于6(第一个元素)的元素。

L2 = [3 1 1 5 2 4 5 3]

然后继续寻找第6顺序统计量。

支点在中位数位置的左边

L1 = [2 3 1 1 5 9 3 6 5 3 5]

如果我们计数小于2的元素的个数,得到2。所以2是第3顺序统计量,又因第3小于第6,我们需要扔掉所有小于2的元素。

L2 = [2 3 5 9 3 6 5 3 5]

在这个情况下,支点元素在完成分区后仍然是第一个位置,我们需要轮转列表。

L2 = [3 5 9 3 6 5 3 5 2]

然后继续寻找第4(6 - 2)顺序统计量。

计数但没有移动

我们看到,算法不再要求移动任何元素。那么,我们到底对列表的元素做了什么?

计数总的元素个数;
确定最小和最大元素;
计数小于某个值的元素的个数;
扔掉小于某个值的所有元素;
扔掉大于或是等于某个值的所有元素;
轮换列表的头到尾
所有这些操作都能很容易的应用到分布式环境中,此时,我们不只是处理一个列表,二是一系列列表,而且是分布着很多的机器上。唯一不容易的是轮换列表,下面我们能看到也不是那么难。

多个列表/多处理器/多机网络下实现

列表的列表

在多处理器环境实现时,我们将一个列表分拆成多个子列表(类似于一台机器上一个列表),每个子列表可以由一个处理器处理,潜在可能跨越多台机器。注意,列表的大小可能不一样。

单个列表:[1 2 3 4 5 6 7 8 9]

多个列表:[[1 2 3 4],[5 6],[7 8 9]]

回忆一下在分布式环境下的那些操作,比如计数总的元素个数;确定最小和最大元素;等等。每个这种操作会先单独作用于每个子列表,然后将结果聚合。比如,确定总的元素个数。

单个列表:length([1 2 3 4 5 6 7 8 9])=9

多个列表:sum(length([1 2 3 4]),length([5 6]),length([7 8 9]))=sum([4 2 3])=9

再比如,

单个列表:min([1 2 3 4 5 6 7 8 9])=1

多个列表:min(min([1 2 3 4]),min([5 6]),min([7 8 9]))=min([1 5 7])=1

其它必要的改变

轮换列表

单个列表时,取第一个元素作为支点。多个列表时,取第一个子列表的第一个元素。

在多个列表时,我们还需要一些修改,为了保证所有可能的支点元素都探索了。所以,在有多个子列表时,要做两个层次的轮换:首先轮换第一个子列表,然后轮换列表的列表。

轮换前:[[1 2 3],[4 5 6],[7 8 9]]

轮换后:[[2 3 1],[4 5 6],[7 8 9]]-》[[4 5 6],[7 8 9][2 3 1]]

空子列表清理

算法需要扔掉值大于或是小于某个值的元素,在单个列表时,列表不会为空,但多个列表时就有可能了。

考虑单个列表情形

[3 1 2 2 2 4 5]

支点为3,小于3的个数为4,所以3是第5顺序统计量,需要扔掉大于3的元素

结果 [3 1 2 2 2]

现在考虑多个子列表的情形

[[3 1 2],[2 2],[4 5]]

支点为3,小于3的个数为4,所以3是第5顺序统计量,需要扔掉大于3的元素

结果 [[3 1 2],[2 2],[]]

这时,我嗯需要排除空列表接着处理。

到此,针对单个列表,多个列表,分布式环境,等各种情况,思路和算法都已经完善。从解决的过程,和中间我们给出的备注,我们明白了这个为什么是一个好的面试题。

本文转载自:http://www.vccoo.com/v/841287

分布式集群中大数据的中位数相关推荐

  1. Hadoop基础-HDFS集群中大数据开发常用的命令总结

    Hadoop基础-HDFS集群中大数据开发常用的命令总结 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本盘博客仅仅列出了我们在实际生成环境中常用的hdfs命令,如果想要了解更多, ...

  2. 大数据开发技术课程报告(搭建Hadoop完全分布式集群操作集群)

    文章目录 大数据开发技术课程报告内容及要求 一. 项目简介和实验环境 二. 虚拟机的各项准备工作 三. 安装JDK并配置环境变量 四. 安装Hadoop并配置环境变量 五. 配置Hadoop完全分布式 ...

  3. 【大数据】Hadoop—— 三大核心组件理论入门 | 完全分布式集群搭建 | 入门项目实战

    文章目录 前言 大数据概述 时代背景 4V特点 大数据思维 核心技术 储存 计算 相关技术 云计算 物联网 Hadoop简介 简介 版本之分 项目生态结构 安装和部署 HDFS 简介 集群结构 实现目 ...

  4. 大数据开发·关于虚拟机Hadoop完全分布式集群搭建教程

    hadoop完全分布式集群搭建 一.搭建准备 1.安装VMware虚拟机 2.Xshell 7 远程客户端及Xftp 7安装 3.搭建模板虚拟机hadoop100 配置虚拟机网络 为虚拟机普通用户配置 ...

  5. 王家林的“云计算分布式大数据Hadoop实战高手之路---从零开始”的第五讲Hadoop图文训练课程:解决典型Hadoop分布式集群环境搭建问题

    王家林的"云计算分布式大数据Hadoop实战高手之路---从零开始"的第五讲Hadoop图文训练课程:解决典型Hadoop分布式集群环境搭建问题 参考文章: (1)王家林的&quo ...

  6. [大数据技术与应用省赛学习记录二]——模块一(HADOOP完全分布式集群搭建)

    **在操作前,先梳理一下HADOOP完全分布式需要做些什么,不然像无头的苍蝇一样,永远不知道做什么.因为我本人比赛是一台服务器Centos 7,与三台客户端Ubuntu 18.04,所以以物理机的角度 ...

  7. 现学现用大数据分布式集群环境部署

    导读:        随着大数据时代的到来,传统的GIS分析工具越来越难以满足对超大体量空间数据的分析需求.SuperMap iServer 9D(本文简称iServer)实现了地理信息服务的分布式集 ...

  8. 大数据调度平台Airflow(八):Airflow分布式集群搭建及测试

    目录 Airflow分布式集群搭建及测试 一.节点规划 二.airflow集群搭建步骤 1.在所有节点安装python3.7 2.在所有节点上安装airflow 三.初始化Airflow 1.每台节点 ...

  9. 大数据分布式集群搭建(1)

    在学习了几天的hadoop分布式集群搭建之后想写写文章记录一下一路以来遇到的困难和解决方案. 闲话不多说,进入正题. 一.环境及准备 因为只有一台电脑,所以需要用虚拟机来模拟环境. 本地机器用到软件: ...

  10. 【干货】Dask快速搭建分布式集群(大数据0基础可以理解,并使用!)

    非常开心,解决了很久都没有解决的问题 使用的语言: Python3.5 分布式机器: windows7 注意到,其实,通过这工具搭建分布式不需要管使用的电脑是什么系统. 分布式使用流程 Created ...

最新文章

  1. C++编程易范的错误
  2. Machine Learning实验3】SoftMax regression
  3. 设计模式总结之Composite Pattern(组合模式)
  4. php如何连接wsdl,PHP如何调用wsdl
  5. filter过滤后重新添加_每天记一个单词(第3518)filter
  6. Hibernate基本概念 (2)
  7. 【leetcodeMySQL每周一练】- 5道题带你练习mysql
  8. 二十多岁不信,三十多岁却深信不疑的道理
  9. php xlsx里插入图片_常见的 PHP 面试题和答案分享
  10. Hibernate -- hibernate.cfg.xml 核心配置文件
  11. 阿尔法平台C语言编程题答案
  12. php获取毫秒级别时间戳及转换日期
  13. 普渡大学计算机图形,普渡大学西拉法叶校区之计算机图形技术系
  14. 怎么用wps抽签_如何使用wps表格进行分班
  15. Excel教程:必会的大数据录入技巧|Excel入门
  16. 邮箱附件钓鱼常用技法
  17. 郑州共享美容院小程序开发如何操作?
  18. one 主格 复数 宾格_代词专练(名词性物主代词,形容词性物主代词,宾格,主格,复数)...
  19. 魔百盒cm311-1a yst 青龙
  20. mtk flash配置

热门文章

  1. 【python爬虫】http.cookiejar库之CookieJar,模拟登录与访问
  2. 新城易居程伟健:民宿集群,正在走向产业标准化的趋势!
  3. 网易云课堂-缓存介绍
  4. 手绘板计算机技术,手绘板怎么用 手绘板和数位板的差别区别【详解】
  5. 家有千金之冰糖绿豆汤
  6. Python股票量化交易(一)
  7. FDD LTE对称吗?
  8. MSP430CPU介绍
  9. MSP430 MSP430单片机输入/输出模块 通用I/O端口GPIO
  10. 51单片机学习历程(一)单片机入门