欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

大数据开发面试题

程序员文章站 2022-06-13 12:37:54
...

1、HashMap 和 Hashtable 区别 

  1. Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
  2. 线程安全性不同,Hashtable 线程安全
  3. HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。

  4.  Hashtable中,key和value都不允许出现null值,HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。

  5. Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

  6.  哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

  7.  HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。

2、Java 垃圾回收机制和生命周期 

大数据开发面试题大数据开发面试题正在上传…重新上传取消大数据开发面试题

  1. 标记----清除算法:分为标记和清除两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收被标记的对象。这种算法有两个不足的地方,一个是效率问题,标记和清除两个过程效率都不高,另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片过多可能会导致以后程序运行过程中需要分配较大对象时,无法找到足够连续的内存而不得不提前触发另一次垃圾收集动作。
  2. 复制算法:为了解决效率问题,出现了复制算法,这种算法把内存分为大小相等的两块,每次只是用其中的一块。当这一块内存用完了,就将还存活的对象复制到另一块上面,然后把已经使用过的那一块内存整个清理掉,这样使得每次清理的只是半个内存区域,内存分配时就不用考虑内存碎片等复杂的情况,只要移动堆顶的指针,按顺序分配内存即可,实现简单,运行高效,但是缺点是,把内存缩小为原来的一半,代价有点高。目前商业虚拟机都采用这种收集算法来回收新生代,不过内存并不是按1:1这样的比例划分的,而是将内存分为较大的Eden空间和两块较小的Survivor空间,每次只使用Eden和其中的一块Survivor区,当回收时,将Eden和survivor区中还存活的对象复制到另一个Survivor区中,最后清理掉Eden和Survivor空间。
  3. 标记----整理算法:和标记清除算法类似,只不过后续步骤不是直接对可回收对象进行清理,而是让存活的对象都向一端移动,然后直接清理到边界以外的内存空间。
  4. 分代收集算法:当前商业虚拟机的垃圾收集都采用分代收集算法,根据对象存活周期的不同将内存划分为几块,一般把堆划分为新生代和老年代,这样就可以各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现大批对象死去,只有少量存活,就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集,而老年代中对象存活率高,就必须使用标记----清理或者标记----整理算法进行回收。

3、怎么解决 Kafka 数据丢失的问题 

1、数据丢失:

    acks=1的时候(只保证写入leader成功),如果刚好leader挂了。数据会丢失。

    acks=0的时候,使用异步模式的时候,该模式下kafka无法保证消息,有可能会丢。

2、brocker如何保证不丢失:

    acks=all : 所有副本都写入成功并确认。

    retries = 一个合理值。

    min.insync.replicas=2  消息至少要被写入到这么多副本才算成功。

    unclean.leader.election.enable=false 关闭unclean leader选举,即不允许非ISR中的副本被选举为leader,以避免数据丢失。

3、Consumer如何保证不丢失

    如果在消息处理完成前就提交了offset,那么就有可能造成数据的丢失。

    enable.auto.commit=false 关闭自动提交offset

    处理完数据之后手动提交。

4、zookeeper 是如何保证数据一致性的 

Zookeeper通过Paxos选举算法实现数据强一致性

5、hadoop 和 spark 在处理数据时,处理出现内存溢出的方法有哪些?

1.使用mapPartitions代替大部分map操作,或者连续使用的map操作
2.broadcast join和普通join:将小的RDD进行collect操作然后设置为broadcast变量
3.先filter在join
4.使用reduceBykey替换groupBykey
5.内存不足时可以降低cache级别使用rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)代替rdd.cache()
6.spark使用hbase的时候,spark和hbase搭建在同一个集群
7.spark.driver.memory (default 1g) 这个参数用来设置Driver的内存
8.spark.rdd.compress (default false)这个参数在内存吃紧的时候,又需要persist数据有良好的性能,就可以设置这个参数为true,这样在使用persist(StorageLevel.MEMORY_ONLY_SER)的时候,就能够压缩内存中的rdd数据。减少内存消耗,就是在使用的时候会占用CPU的解压时间。
9.spark.serializer (default org.apache.spark.serializer.JavaSerializer ) KryoSerializer比JavaSerializer快
10.spark.memory.storageFraction (default 0.5) 这个参数设置内存表示 Executor内存中 storage/(storage+execution),虽然spark-1.6.0+的版本内存storage和execution的内存已经是可以互相借用的了,但是借用和赎回也是需要消耗性能的,所以如果明知道程序中storage是多是少就可以调节一下这个参数。

6、java 实现快速排序 

  1. 假设我们对数组{7, 1, 3, 5, 13, 9, 3, 6, 11}进行快速排序。
  2. 首先在这个序列中找一个数作为基准数,为了方便可以取第一个数。
  3. 遍历数组,将小于基准数的放置于基准数左边,大于基准数的放置于基准数右边
  4. 此时得到类似于这种排序的数组{3, 1, 3, 5, 6, 7, 9, 13, 11}。
  5. 在初始状态下7是第一个位置,现在需要把7挪到中间的某个位置k,也即k位置是两边数的分界点。
  6. 那如何做到把小于和大于基准数7的值分别放置于两边呢,我们采用双指针法从数组的两端分别进行比对
  7. 先从最右位置往左开始找直到找到一个小于基准数的值,记录下该值的位置(记作 i)。
  8. 再从最左位置往右找直到找到一个大于基准数的值,记录下该值的位置(记作 j)。
  9. 如果位置i<j,则交换i和j两个位置上的值,然后继续从(j-1)的位置往前(i+1)的位置往后重复上面比对基准数然后交换的步骤。
  10. 如果执行到i==j,表示本次比对已经结束,将最后i的位置的值与基准数做交换,此时基准数就找到了临界点的位置k,位置k两边的数组都比当前位置k上的基准值或都更小或都更大。
  11. 上一次的基准值7已经把数组分为了两半,基准值7算是已归位(找到排序后的位置)
  12. 通过相同的排序思想,分别对7两边的数组进行快速排序,左边对[left, k-1]子数组排序,右边则是[k+1, right]子数组排序
  13. 利用递归算法,对分治后的子数组进行排序。
public class Test {
    public static void main(String[] args) {
        int[] arr = {7, 2, 1, 3, 8, 6, 4, 5};
        quickSort(arr, 0, arr.length - 1);
        for (int anArr : arr) {
            System.out.println(anArr);
        }

    }

    private static void quickSort(int[] arr, int low, int high) {
        int i, j, temp, t;
        if (low > high) {
            return;
        }
        i = low;
        j = high;
        //temp就是基准位
        temp = arr[low];

        while (i < j) {
            //先看右边,依次往左递减
            while (temp <= arr[j] && i < j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp >= arr[i] && i < j) {
                i++;
            }
            //如果满足条件则交换
            if (i < j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
        }
        //最后将基准为与i和j相等位置的数字交换
        arr[low] = arr[i];
        arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j - 1);
        //递归调用右半数组
        quickSort(arr, j + 1, high);
    }
}

9、Spark如何调优 

  1. 诊断内存的消耗
  2. 高性能序列化类库
  3. 优化数据结构
  4. 对多次使用的RDD进行持久化或Checkpoint
  5. 使用序列化的持久化级别
  6. GC调优
  7. 提高并行度
  8. 广播共享数据
  9. 数据本地化
  10. reduceByKey和groupByKey的选择
  11. shuffle性能优化

10、Flink和spark的通信框架有什么异同 

Flink使用netty,spark使用Akka

11、Java的代理 

静态代理:
1.可以做到在不修改目标对象的功能前提下,对目标功能扩展.
2.缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

动态代理:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

Cglib代理

Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.

JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.

Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)

Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.

12、Java的内存溢出和内存泄漏 

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

13、hadoop 的组件有哪些?Yarn的调度器有哪些?

 hadoop组件:common(工具类)、HDFS、MapReduce、YARN

Yarn中有三种调度器可以选择:FIFO Scheduler (队列调度器),Capacity Scheduler(容器调度器),FairS cheduler(公平调度器)

14、hadoop 的 shuffle 过程 

大数据开发面试题

15、简述Spark集群运行的几种模式 

Local 模式是最简单的一种Spark运行方式,它采用单节点多线程(cpu)方式运行

Spark可以通过部署与Yarn的架构类似的框架来提供自己的集群模式,该集群模式的架构设计与HDFS和Yarn大相径庭,都是由一个主节点多个从节点组成,在Spark 的Standalone模式中,主,即为master;从,即为worker

Spark on Yarn 模式就是将Spark应用程序跑在Yarn集群之上,通过Yarn资源调度将executor启动在container中,从而完成driver端分发给executor的各个任务。将Spark作业跑在Yarn上,首先需要启动Yarn集群,然后通过spark-shell或spark-submit的方式将作业提交到Yarn上运行

Yarn的两种模式:一种为 client;一种为 cluster,可以通过- -deploy-mode 进行指定,也可以直接在 - -master 后面使用 yarn-client和yarn-cluster进行指定
俩种模式的区别:在于driver端启动在本地(client),还是在Yarn集群内部的AM中(cluster)

16、RDD 中的 reducebyKey 与 groupByKey 哪个性能高?

  1. 返回值类型不同:reduceByKey返回的是RDD[(K, V)],而groupByKey返回的是RDD[(K, Iterable[V])],举例来说这两者的区别。比如含有一下数据的rdd应用上面两个方法做求和:(a,1),(a,2),(a,3),(b,1),(b,2),(c,1);reduceByKey产生的中间结果(a,6),(b,3),(c,1);而groupByKey产生的中间结果结果为((a,1)(a,2)(a,3)),((b,1)(b,2)),(c,1),(以上结果为一个分区中的中间结果)可见groupByKey的结果更加消耗资源
  2. 作用不同,reduceByKey作用是聚合,异或等,groupByKey作用主要是分组,也可以做聚合(分组之后)
  3. map端中间结果对键对应的值得聚合方式不同

17、简述 HBase 的读写过程 

【写过程】

1、Client先从缓存中定位region,如果没有缓存则需访问zookeeper,从.META.表获取要写入的region信息

2、找到小于rowkey并且最接近rowkey的startkey对应的region

3、将更新写入WAL中。当客户端发起put/delete请求时,考虑到写入内存会有丢失数据的风险,因此在写入缓存前,HBase会先写入到Write Ahead Log(WAL)中(WAL存储在HDFS中),那么即使发生宕机,也可以通过WAL还原初始数据。

4、将更新写入memstore中,当增加到一定大小,达到预设的Flush size阈值时,会触发flush memstore,把memstore中的数据写出到hdfs上,生成一个storefile。

5、随着Storefile文件的不断增多,当增长到一定阈值后,触发compact合并操作,将多个storefile合并成一个,同时进行版本合并和数据删除。

6、storefile通过不断compact合并操作,逐步形成越来越大的storefile。

7、单个stroefile大小超过一定阈值后,触发split操作,把当前region拆分成两个,新拆分的2个region会被hbase master分配到相应的2个regionserver上。

【读过程】

1、Client先从缓存中定位region,如果没有缓存则需访问zookeeper,查询.-ROOT-.表,获取.-ROOT-.表所在的regionserver地址。

2、通过查询.-ROOT-.的region服务器 获取 含有.-META-.表所在的regionserver地址。

3、clinet会将保存着regionserver位置信息的元数据表.META.进行缓存,然后在表中确定待检索rowkey所在的regionserver信息。

4、client会向在.META.表中确定的regionserver发送真正的数据读取请求。

5、先从memstore中找,如果没有,再到storefile上读。

18、在 2.5亿个整数中,找出不重复的整数,注意:内存不足以容纳 2.5亿个整数。

采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存 2^32 * 2 bit=1 GB内存,还可以接受。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持 不变。扫描后,查看bitmap,把对应位是01的整数输出即可。

19、CDH 和 HDP 的区别 

  1. CDH支持的存储组件更丰富
  2. HDP支持的数据分析组件更丰富
  3. HDP对多维分析及可视化有了支持,引入Druid和Superset
  4. HDP的HBase数据使用Phoenix的jdbc查询;CDH的HBase数据使用映射Hive到Impala的jdbc查询,但分析数据可以存储Impala内部表,提高查询响应
  5. 多维分析Druid纳入集群,会方便管理;但可视化工具Superset可以单独安装使用
  6. CDH没有时序数据库,HDP将Druid作为时序数据库使用

20、Java原子操作 

 

21、Java封装、继承和多态 

22、JVM 模型 

23、Flume taildirSorce 重复读取数据解决方法 

24、Flume 如何保证数据不丢 

25、Java 类加载过程 

26、Spark Task 运行原理 

27、手写一个线程安全的单例 

28、设计模式 

29、impala 和 kudu 的适用场景,读写性能如何 

30、Kafka ack原理 

31、phoenix 创建索引的方式及区别 

32、Flink TaskManager 和 Job Manager 通信 

33、Flink 双流 join方式 

34、Flink state 管理和 checkpoint 的流程 

35、Flink 分层架构 

36、Flink 窗口 

37、Flink watermark 如何处理乱序数据 

38、Flink time 

39、Flink支持exactly-once 的 sink 和 source 

40、Flink 提交作业的流程 

41、Flink connect 和 join 区别 

42、重启 task 的策略 

43、hive 的锁 

44、hive sql 优化方式 

45、hadoop shuffle 过程和架构 

46、如何优化 shuffle过程 

47、冒泡排序和快速排序 

48、讲讲Spark的stage 

49、spark mkrdd和Parrallilaze函数区别 

50、Spark checkpoint 过程 

51、二次排序 

52、如何注册 hive udf 

53、SQL去重方法 

54、Hive分析和窗口函数 

55、Hadoop 容错,一个节点挂掉然后又上线 

56、掌握 JVM 原理 

57、Java 并发原理 

58、多线程的实现方法 

59、RocksDBStatebackend实现(源码级别) 

60、HashMap、ConcurrentMap和 Hashtable 区别 

61、Flink Checkpoint 是怎么做的,作用到算子还是chain 

62、Checkpoint失败了的监控 

63、String、StringBuffer和 StringBuilder的区别 

64、Kafka存储流程,为什么高吞吐?

65、Spark优化方法举例 

66、keyby的最大并行度 

67、Flink 优化方法 

68、Kafka ISR 机制 

69、Kafka partition的4个状态 

70、Kafka 副本的7个状态 

71、Flink taskmanager的数量 

72、if 和 switch 的性能及 switch 支持的参数 

73、kafka 零拷贝 

74、hadoop 节点容错机制 

75、HDFS 的副本分布策略 

76、Hadoop面试题汇总,大概都在这里(https://www.cnblogs.com/gala1021/p/8552850.html) 

77、Kudu 和Impala 权限控制 

78、Time_wait状态?当server处理完client的请求后立刻closesocket此时会出现time_wait状态

79、三次握手交换了什么?(SYN,ACK,SEQ,窗口大小) 3次握手建立链接,4次握手断开链接。

80、hashmap 1.7和1.8 的区别 

81、concurrenthashmap 1.7和1.8?

82、Kafka 的ack 

83、sql 去重方法(group by 、distinct、窗口函数) 

84、哪些 Hive sql 不能在 Spark sql 上运行,看这里:https://spark.apache.org/docs/2.2.0/sql-programming-guide.html#unsupported-hive-functionality 

85、什么情况下发生死锁 

86、事务隔离级别?可重复读、不可重复读、读未提交、串行化 

87、Spark shuffle 和 Hadoop shuffle的异同 

88、Spark静态内存和动态内存 

89、mysql btree 和 hash tree 的区别。btree 需要唯一主键,hash tree 适合>= 等,精确匹配,不适合范围检索 

90、udf、udtf和 udaf 的区别 

91、hive sql 的执行过程 

92、spark sql 的执行过程 

93、找出数组中最长的top10字符串 

94、Flink 数据处理流程 

95、Flink 与 Spark streaming 对比 

96、Flink watermark 使用 

97、窗口与流的结合 

98、Flink 实时告警设计 

99、Java:面向对象、容器、多线程、单例 

100、Flink:部署、API、状态、checkpoint、savepoint、watermark、重启策略、datastream 算子和优化、job和task状态 

101、Spark:原理、部署、优化 

102、Kafka:读写原理、使用、优化 

103、hive的外部表 

104、spark的函数式编程 

105、线性数据结构和数据结构 

106、Spark映射,RDD

107、java的内存溢出和内存泄漏

108、多线程的实现方法 

109、HashMap、ConcurrentMap和 Hashtable 区别 

110、Flink Checkpoint 是怎么做的,作用到算子还是chain 

111、Checkpoint失败了的监控 

112、String、StringBuffer和 StringBuilder的区别 

113、Kafka存储流程,为什么高吞吐 

114、Spark 优化方法举例 

115、keyby 的最大并行度 

116、Flink 优化方法 

117、Kafka ISR 机制 

118、kafka partition 的状态 

119、kafka 副本的状态 

120、taskmanager 的数量 

121、if 和switch的性能区别

122、Hdfs读写流程(结合cap理论讲) 

123、技术选型原则 

124、Kafka组件介绍 

125、g1和cms的区别 

126、讲讲最熟悉的数据结构 

127、spark oom处理方法 

128、看了哪些源码 

129、Spark task原理 

130、解决过的最有挑战的问题 

131、Hbase读写流程

相关标签: 面试题 大数据