公众号(五分钟学大数据)将推出大数据面试系列文章—五分钟小面试,此系列文章将会深入研究各大厂笔面试真题,并依据笔面试题扩大相干的知识点,助力大家都可能胜利入职大厂!
大数据笔面试系列文章分为两种类型:混合型(即一篇文章中会有多个框架的知识点—死记硬背);专项型(一篇文章针对某个框架进行深刻解析—专项演练)。
此篇文章为系列文章的第一篇(混合型)
第一题:大数据口试题-Java相干(美菜网)
写出下列程序的输入:
class Father{ static { System.out.println("Static Father"); } { System.out.println("Non-static Father"); } public Father(){ System.out.println("Constructor Father"); }}public class Son extends Father{ static { System.out.println("Static Son"); } { System.out.println("Non-static Son"); } public Son(){ System.out.println("Constructor Son"); } public static void main(String[] args) { System.out.println("First Son"); new Son(); System.out.println("Second Son"); new Son(); }}
运行后果:
Static FatherStatic SonFirst SonNon-static FatherConstructor FatherNon-static SonConstructor SonSecond SonNon-static FatherConstructor FatherNon-static SonConstructor Son
剖析:
这道程序题考查的是Java中的动态代码块、结构代码块、构造函数的概念。
- 动态代码块 static {}:
随着类的加载而执行,即JVM加载类后就执行,而且只执行一次,执行优先级高于非动态的初始化块,它会在类初始化的时候执行一次,执行实现便销毁,它仅能初始化类变量,即static润饰的数据成员。
- 非动态代码块,也称结构代码块 {}:
执行的时候如果有动态代码块,先执行动态代码块再执行非动态代码块,在每个对象生成时都会被执行一次,它能够初始化类的实例变量。非动态代码块会在构造函数执行时,在构造函数主体代码执行之前被运行。
- 构造函数:
对象一建设,就会调用与之相应的构造函数,也就是说,不建设对象,构造函数是不会运行的。
一个对象建设,构造函数只运行一次,而个别办法能够被该对象调用屡次。
再来看本题,程序运行,执行main()办法会先加载main()办法所在的类,加载 Son 类,然而 Son 类继承自 Father 类,所以先加载父类,同时父类的动态代码块执行,而后加载 Son 类自身,Son 类本人的动态代码块开始执行,类加载实现之后执行main()办法外部的语句,打印 First Son,而后 new Son(),在创建对象时先结构父类的对象,因为动态代码块只在类加载时执行一次,所以不再执行,而后执行父类的结构代码块,构造函数,结构代码块的优先级大于构造函数。而后在执行 Son 对象自身。实现之后打印 Second Son,接着又 new Son(),反复以上步骤。结构代码块和构造函数在每次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:申请 512M 的内存,512M是42亿多 bit,一个 bit 位代表一个 unsigned int 值。读入 40 亿个数,设置相应的 bit 位,读入要查问的数,查看相应 bit 位是否为 1,为 1 示意存在,为 0 示意不存在。
计划 2:这个问题在《编程珠玑》里有很好的形容,大家能够参考上面的思路,探讨一下: 因为 2^32 为 42 亿多,所以给定一个数可能在,也可能不在其中; 这里咱们把 40 亿个数中的每一个用 32 位的二进制来示意 ,假如这 40 亿个数开始放在一个文件中。 而后将这 40 亿个数分成两类:
- 最高位为 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 解决。
- 很多人的误会在 Map 阶段,如果不应用 Combiner 便不会排序,这是谬误的,不论你用不必 Combiner,Map Task 均会对产生的数据排序(如果没有 Reduce Task,则不会排序,实际上 Map 阶段的排序就是为了加重 Reduce端排序负载)。
- 因为这些排序是 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外部如何保障程序:kafka只能保障partition内是有序的,然而partition间的有序是没方法的。爱奇艺的搜寻架构,是从业务上把须要有序的打到同一个partition。
第六题:大数据面试题-分布式相干(阿里)
问:说说三种分布式锁?
答:
基于数据库实现分布式锁:(性能较差,锁表的危险,非阻塞,失败须要轮询耗CPU)
- 乐观锁
利用select … where … for update 排他锁
留神: 其余附加性能与实现基本一致,这里须要留神的是“where name=lock ”,name字段必须要走索引,否则会锁表。有些状况下,比方表不大,mysql优化器会不走这个索引,导致锁表问题。
- 乐观锁
所谓乐观锁与乐观锁最大区别在于基于CAS思维,是不具备互斥性,不会产生锁期待而耗费资源,操作过程中认为不存在并发抵触,只有update version失败后能力觉察到。咱们的抢购、秒杀就是用了这种实现以避免超卖。
乐观锁是通过减少递增的版本号字段实现的。
基于缓存(Redis等)实现分布式锁:(过期工夫不好管制,非阻塞,失败须要轮询耗CPU)
- 获取锁的时候,应用setnx加锁,并应用expire命令为锁增加一个超时工夫,超过该工夫则主动开释锁,锁的value值为一个随机生成的UUID,通过此在开释锁的时候进行判断。
- 获取锁的时候还设置一个获取的超时工夫,若超过这个工夫则放弃获取锁。
- 开释锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁开释。
- 基于Zookeeper实现分布式锁:(高可用、可重入、阻塞锁)
大抵思维:每个客户端对某个性能加锁时,在zookeeper上的与该性能对应的指定节点的目录下,⽣生成⼀个惟一的刹时有序节点。判断是否获取锁的形式很简略,只须要判断有序节点中序号最小的一个。当开释锁的时候,只需将这个刹时节点删除即可。同时,其能够防止服务宕机导致的锁无奈开释,⽽而产生的死锁问题。
- 长处:锁安全性高,zk可长久化,且能实时监听获取锁的客户端状态。一旦客户端宕机,则刹时节点随之隐没,zk因⽽而能第一工夫开释锁。这也省去了用分布式缓存实现锁的过程中须要退出超时工夫判断的这一逻辑。
- 毛病:性能开销⽐比拟高。因为其须要动静产生、销毁刹时节点来实现锁性能。所以不太适宜间接提供给高并发的场景应用。
- 实现:能够间接采纳zookeeper第三方库curator即可不便地实现分布式锁。
- 实用场景:对可靠性要求十分高,且并发水平不高的场景下应用。如外围数据的定时全量/增量同步等。
第七题:大数据面试题-Hadoop、Spark相干(京东金融)
问:Hadoop 和 Spark 的相同点和不同点?
答:
Hadoop底层应用MapReduce计算架构,只有map和reduce两种操作,表达能力比拟欠缺,而且在MR过程中会反复的读写hdfs,造成大量的磁盘io读写操作,所以适宜高时延环境下批处理计算的利用;
Spark是基于内存的分布式计算架构,提供更加丰盛的数据集操作类型,次要分成转化操作和口头操作,包含map、reduce、filter、flatmap、groupbykey、reducebykey、union和join等,数据分析更加疾速,所以适宜低时延环境下计算的利用;
spark与hadoop最大的区别在于迭代式计算模型。基于mapreduce框架的Hadoop次要分为map和reduce两个阶段,两个阶段完了就完结了,所以在一个job外面能做的解决很无限;spark计算模型是基于内存的迭代式计算模型,能够分为n个阶段,依据用户编写的RDD算子和程序,在解决完一个阶段后能够持续往下解决很多个阶段,而不只是两个阶段。所以spark相较于mapreduce,计算模型更加灵便,能够提供更弱小的性能。
然而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种取值状况,所以不能齐全加载到内存中解决;
- 能够思考采纳分而治之的思维,依照IP地址的Hash(IP) % 1024值,把海量IP日志别离存储到1024个
小文件中,这样每个小文件最多蕴含4MB个IP地址; 这里解释一下为什么用Hash(IP) % 1024值,如果不必,而间接分类的话,可能会呈现这样一种状况,就是有个IP在每个小文件中都存在,而且这个IP并不一定在那个小文件中是数量最多的,那么最终可能抉择的后果会有问题,所以这里用了Hash(IP)%1024值,这样的话,通过计算IP的Hash值,雷同IP必定会放到一个文件中,当然了不同的IP的Hash值也可能雷同,就存在一个小文件中。
- 对于每一个小文件,能够构建一个IP为key,呈现的次数为value的HashMap,同时记录以后呈现次数最多的那个IP地址;
- 能够失去1024个小文件中的呈现次数最多的那个IP,再根据惯例的排序算法得出总体上呈现次数最多的IP。