大数据开发面试题

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 垃圾回收机制和生命周期 

1335504117_6784.jpguploading.4e448015.gif正在上传…重新上传取消

  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. 通过
  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值