大数据面试大厂真题-附答案详细解析

第一题:大数据笔试题-Java相关(美菜网)
写出下列程序的输出:

运行结果:

分析:

这道程序题考察的是Java中的静态代码块、构造代码块、构造函数的概念。

静态代码块 static {}

随着类的加载而执行只执行一次优先级高于非静态的初始化块

非静态代码块,也称构造代码块 {}

在每个对象生成时都会被执行一次在构造函数主体代码执行之前被运行

构造函数

对象一建立,就会调用与之相应的构造函数一个对象建立,构造函数只运行一次

执行main()方法会先加载main()方法所在的类静态代码块只在类加载时执行一次构造代码块和构造函数在每次new的时候都会执行一次

第二题:大数据面试题-JVM相关(丰巢科技)
问:解释内存中的栈(stack)、堆(heap)和静态存储区的用法?

答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、“hello”和常量都是放在静态存储区中。栈空间操作最快但是也很小,通常大量的对象都是放在堆空间,整个内存包括硬盘上的虚拟内存都可以被当成堆空间来使用。

String str = new String(“hello”);

上面的语句中str放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态存储区。

补充:较新版本的Java中使用了一项叫“逃逸分析“的技术,可以将一些局部对象放在栈上以提升对象的操作性能。(在 Java SE 6u23+ 开始支持,并默认设置为启用状态,可以不用额外加这个参数。)

第三题:大数据面试题-海量数据相关(腾讯)
问:给 40 亿个不重复的 unsigned int 的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那 40 亿个数当中?

方案 1

方案 2

最高位为 0

最高位为 1

并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20 亿,而另一个>=20 亿(相当于折半);与要查找的数的最高位比较并接着进入相应的文件再查找 然后再把这个文件为又分成两类:

次最高位为 0

次最高位为 1

并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10 亿,而另一个>=10 亿(相当于折半);与要查找的数的次最高位比较并接着进入相应的文件再查找。…..以此类推,就可以找到了,而且时间复杂度为 O(logn)。

第四题:大数据面试题-Hadoop相关(阿里)
问:MapReduce 中排序发生在哪几个阶段?这些排序是否可以避免?为什么?

答:

一个 MapReduce 作业由 Map 阶段和 Reduce 阶段两部分组成,这两阶段会对数据排序,从这个意义上说,MapReduce 框架本质就是一个 Distributed Sort。

在 Map 阶段,Map Task 会在本地磁盘输出一个按照 key 排序(采用的是快速排序)的文件(中间可能产生多个文件,但最终会合并成一个),在 Reduce 阶段,每个 Reduce Task 会对收到的数据排序(采用的是归并排序),这样,数据便按照 Key 分成了若干组,之后以组为单位交给 reduce 处理。

如果没有 Reduce Task,则不会排序

由于这些排序是 MapReduce 自动完成的,用户无法控制,因此,在hadoop 1.x 中无法避免,也不可以关闭,但 hadoop2.x 是可以关闭的。

第五题:大数据面试题-Kafka相关(商汤科技)
问:kafka数据分区和消费者的关系,kafka的数据offset读取流程,kafka内部如何保证顺序

答:

kafka数据分区和消费者的关系:1个partition只能被同组的⼀一个consumer消费,同组的consumer则起到均衡效果

kafka的数据offset读取流程:

连接ZK集群,从ZK中拿到对应topic的partition信息和partition的Leader的相关信息

连接到对应Leader对应的broker

consumer将⾃自⼰己保存的offset发送给Leader

Leader根据offset等信息定位到segment(索引⽂文件和⽇日志⽂文件)

根据索引⽂文件中的内容,定位到⽇日志⽂文件中该偏移量量对应的开始位置读取相应⻓长度的数据并返回给consumer

kafka只能保证partition内是有序的,但是partition间的有序是没办法的

第六题:大数据面试题-分布式相关(阿里)
问:说几种实现分布式锁的方式?

答:

1、基于数据库实现分布式锁:(性能较差,锁表的风险,非阻塞,失败需要轮询耗CPU)

悲观锁

利用select … where … for update 排他锁

注意: 其他附加功能与实现基本一致,这里需要注意的是“where name=lock ”,name字段必须要走索引,否则会锁表。有些情况下,比如表不大,mysql优化器会不走这个索引,导致锁表问题。

乐观锁

所谓乐观锁与悲观锁最大区别在于基于CAS思想,是不具有互斥性,不会产生锁等待而消耗资源,操作过程中认为不存在并发冲突,只有update version失败后才能觉察到。我们的抢购、秒杀就是用了这种实现以防止超卖。乐观锁是通过增加递增的版本号字段实现的。

2、基于缓存(Redis等)实现分布式锁:(过期时间不好控制,非阻塞,失败需要轮询耗CPU)

获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。

获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

3、基于Zookeeper实现分布式锁:(高可用、可重入、阻塞锁)

判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个

优点:锁安全性高,zk可持久化,且能实时监听获取锁的客户端状态。一旦客户端宕机,则瞬时节点随之消失,zk因⽽而能第一时间释放锁。这也省去了用分布式缓存实现锁的过程中需要加入超时时间判断的这一逻辑。

缺点:性能开销⽐比较高。因为其需要动态产生、销毁瞬时节点来实现锁功能。所以不太适合直接提供给高并发的场景使用。

实现:可以直接采用zookeeper第三方库curator即可方便地实现分布式锁。

适用场景:对可靠性要求非常高,且并发程度不高的场景下使用。如核心数据的定时全量/增量同步等。

第七题:大数据面试题-Hadoop、Spark相关(京东金融)
问:Hadoop 和 Spark 的相同点和不同点?

答:

Hadoop底层使用MapReduce计算架构,只有map和reduce两种操作,表达能力比较欠缺,而且在MR过程中会重复的读写hdfs,造成大量的磁盘io读写操作

Spark是基于内存的分布式计算架构,提供更加丰富的数据集操作类型,主要分成转化操作和行动操作

spark与hadoop最大的区别在于迭代式计算模型

但是spark也有劣势,由于spark基于内存进行计算,虽然开发容易,但是真正面对大数据的时候,在没有进行调优的情况下,可能会出现各种各样的问题,比如OOM内存溢出等情况,导致spark程序可能无法运行起来,而mapreduce虽然运行缓慢,但是至少可以慢慢运行完。

第八题:大数据面试题-Yarn相关(特斯拉)
问:一个应用程序是如何在 Yarn 集群上执行的?

答:

当 jobclient 向YARN提交一个应用程序后,YARN将分两个阶段运行这个应用程序:一是启动ApplicationMaster;第二个阶段是由ApplicationMaster创建应用程序,为它申请资源,监控运行直到结束。

具体步骤如下:

用户向YARN提交一个应用程序,并指定ApplicationMaster程序、启动ApplicationMaster的命令、用户程序。

RM为这个应用程序分配第一个Container,并与之对应的NM通讯,要求它在这个Container中启动应用程序ApplicationMaster。

ApplicationMaster向RM注册,然后拆分为内部各个子任务,为各个内部任务申请资源,并监控这些任务的运行,直到结束。

AM采用轮询的方式向RM申请和领取资源。

RM为AM分配资源,以Container形式返回。

AM申请到资源后,便与之对应的NM通讯,要求NM启动任务。

NodeManager为任务设置好运行环境,将任务启动命令写到一个脚本中,并通过运行这个脚本启动任务。

各个任务向AM汇报自己的状态和进度,以便当任务失败时可以重启任务。

应用程序完成后,ApplicationMaster向ResourceManager注销并关闭自己。

第九题:大数据面试题-数据质量相关(蚂蚁金服)
问:数据质量怎么监控?

答:

如一张表的记录数在一个已知的范围内,或者上下浮动不会超过某个阈值:

SQL结果:var 数据量 = select count(*)from 表 where 时间等过滤条件

报警触发条件设置:如果数据量不在[数值下限, 数值上限], 则触发报警

同比增加:如果((本周的数据量 -上周的数据量)/上周的数据量*100)不在 [比例下线,比例上限],则触发报警

环比增加:如果((今天的数据量 – 昨天的数据量)/昨天的数据量*100)不在 [比例下线,比例上限],则触发报警

报警触发条件设置一定要有。如果没有配置的阈值,不能做监控日活、周活、月活、留存(日周月)、转化率(日、周、月)GMV(日、周、月)复购率(日周月)

单表空值检测

某个字段为空的记录数在一个范围内,或者占总量的百分比在某个阈值范围内

目标字段:选择要监控的字段,不能选“无”

SQL结果:var 异常数据量 = select count(*) from 表 where 目标字段 is null

单次检测:如果(异常数据量)不在[数值下限, 数值上限],则触发报警

单表重复值检测

一个或多个字段是否满足某些规则

目标字段:第一步先正常统计条数;select count(*) form 表;

第二步,去重统计;select count(*) from 表 group by 某个字段

第一步的值和第二步的值做减法,看是否在上下线阀值之内

单次检测:如果(异常数据量)不在[数值下限, 数值上限], 则触发报警

跨表数据量对比

主要针对同步流程,监控两张表的数据量是否一致

SQL结果:count(本表) – count(关联表)

阈值配置与“空值检测”相同

第十题:大数据面试题-海量数据相关(百度)
问:在海量日志数据中,提取出某日访问百度次数最多的那个IP

答:这类问题都归为求Top K的问题,解决方法都差不多。

将这一天访问百度的日志的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。同样可以采用映射的方法,比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用 HashMap 进行频率统计,然后再找出频率最大的几个)及相应的频率。然后再在这1000个最大的IP中找出那个频率最大的IP,即为所求。

算法思想:分而治之+Hash

IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;

为什么用Hash(IP) % 1024值相同IP肯定会放到一个文件中

对于每一个小文件,可以构建一个IP为key,出现的次数为value的HashMap,同时记录当前出现次数最多的那个IP地址;

可以得到1024个小文件中的出现次数最多的那个IP,再依据常规的排序算法得出总体上出现次数最多的IP。

docx image

学习从来都不是件容易得事,唯有用心,坚持!

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容