大数据面试题题目2020年底总结(一)

大数据面试题集锦(一)

1. java

  1. JVM内存结构



方法区
程序计数器

  1. JVM内存回收机制
  • 哪些需要回收

判断算法

  1. 引用计数法
    每个对象创建的时候,会分配一个引用计数器,当这个对象被引用的时候计数器就加1,当不被引用或者引用失效的时候计数器就会减1。任何时候,对象的引用计数器值为0就说明这个对象不被使用了,就认为是“垃圾”,可以被GC处理掉。
    【优点】算法实现简单。
    【缺点】不能解决对象之间循环引用的问题。有垃圾对象不能被正确识别,这对垃圾回收来说是很致命的,所以GC并没有使用这种搜索算法。
  2. 根搜索算法
    以一些特定的对象作为基础原始对象,或者称作“根”,不断往下搜索,到达某一个对象的路径称为引用链。
    如果一个对象和根对象之间有引用链,即根对象到这个对象是可到达的,则这个对象是活着的,不是垃圾,还不能回收。
    例如,假设有根对象O,O引用了A对象,同时A对象引用了B对象,B对象又引用了C对象,那么对象C和根对象O之间的路径的可达的,C对象就不能当做垃圾对象。引用链为O->A->B->C。
    反之,如果一个对象和根对象之间没有引用链,根对象到这个对象的路径是不可达的,那么这个对象就是可回收的垃圾对象。
    【优点】可找到所以得垃圾对象,并且完美解决对象之间循环引用的问题。
    【缺点】不可避免地要遍历全局所有对象,导致搜索效率不高。
    可以当做GC roots的对象有以下几种:
    虚拟机栈中的引用的对象。(java栈的栈帧本地变量表)
    方法区中的类静态属性引用的对象。
    方法区中的常量引用的对象。(声明为final的常量对象)
    本地方法栈中JNI的引用的对象。(本地方法栈的栈帧本地变量表)
  • 在哪里回收
  1. 方法区也是有垃圾收集的,
    如果常量池中存在一个”abc”,而没有任何的String对象引用常量“abc”,那么我们需要对这个常量进行回收的
  2. 永久代的垃圾收集
    主要包括废弃常量和无用的类
    (判定一个无用的类:
    该类的所有实例都已经被回收,也就是java堆中不存在任何该类的实例
    加载该类的ClassLoader已经被回收
    该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过访问该类的方法。
    )
  • 什么时候回收
  • 怎么回收

回收算法

  1. 标记-清扫(Mark-and-sweep)
    对于“活”的对象,一定可以追溯到其存活在堆栈、静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。
    第一阶段:从GC roots开始遍历所有的引用,对有活的对象进行标记。
    第二阶段:对堆进行遍历,把未标记的对象进行清除。这个解决了循环引用的问题。 缺点:1、暂停整个应用;2、会产生内存碎片
  2. 复制(copying) 原理
    把内存空间划分为2个相等的区域,每次只使用一个区域。
    垃圾回收时,遍历当前使用区域,把正在使用的对象复制到另外一个区域。
    优点:不会出现碎片问题。
    缺点:1、暂停整个应用。2、需要2倍的内存空间。
  3. 标记-整理(Mark-Compact)
    第一阶段标记活的对象,
    第二阶段把为标记的对象压缩到堆的其中一块,按顺序放。即将所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
    优点:1、避免标记扫描的碎片问题;2、避免停止复制的空间问题。
    具体使用什么方法GC,Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率低的话,就切换到“标记-扫描”方式;
    同样,Java虚拟机会跟踪“标记-扫描”的效果,要是堆空间碎片出现很多碎片,就会切换回“停止-复制”模式。这就是自适应的技术
  4. 分代(generational collecting)
    基于对象生命周期分析得出的垃圾回收算法。把对象分为年轻代、年老代、持久代,对不同的生命周期使用不同的算法(2-3方法中的一个即4自适应)进行回收
    新生代:每次垃圾收集都有大量对象死去,只有少量存活,就选择复制算法
    老年代:对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”,或者“标记-整理”算法来进行回收。

回收器

  1. Serial(串行GC)收集器
    Serial收集器是一个新生代收集器,单线程执行,使用复制算法。
    它在进行垃圾收集时,必须暂停其他所有的工作线程(用户线程)。
    是Jvm client模式下默认的新生代收集器。
    对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率
  2. ParNew(并行GC)收集器
    ParNew收集器其实就是serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial收集器一样。
    在单CPU工作环境内绝对不会有比Serial的收集器有更好的效果,随着可以使用的CPU的数量的增加,它对于GC时系统资源的有效利用还是很有好处的,它默认开启的收集线程数与CPU的数量下同,在CPU非常多的环境下,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数
  3. parallel Scavenge(并行回收GC)收集器
    Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的收集器,又是并行多线程收集器。
    parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。
    吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间),虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%。Parallel Scavenge提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数和直接设置吞吐量大小的-XXGCTimeRatio参数。
    这个收集器还有一个开关:-XX:+UseAdaptiveSizePolicy值得关注。这个开关打开后,虚拟机会根据当前系统的运行情况收集性能监控信息自动调整新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRation)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数。
    使用自适应策略,只需要设置最大堆(-Xmx),利用最大停顿时间或者吞吐量给虚拟机设置一个优化目标。
  4. Serial Old(串行GC)收集器
    Serial Old是Serial收集器的老年代版本,它同样使用一个单线程执行收集,使用“标记-整理”算法。
    主要使用在Client模式下的虚拟机。
    对于Server模式下有两个用途:
    1 - 在JDK1.5以及之前的版本中与Parallel Scavenge收集器搭配使用;
    2 - 作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用
  5. Parallel Old(并行GC)收集器
    Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。
  6. CMS(并发GC)收集器
  1. hashmap、hashtable、cocurrentHashMap的差异

2. 数据结构与算法

  1. 数组和链表优缺点
  2. 快排
  3. 整数倒置–对10求余,再除以10.然后循环下去。注意整数上下边界以及终止条件
  4. 链表倒置–核心思想就是先把头节点抽离出来,然后每一个步骤都是2个指针,这样就可以确保让第二个节点变成头节点时,后续节点不会丢失

linkList reverse(linkList head){
linkList p,q,pr;
p = head->next;
q = NULL;
head->next = NULL;
while§{
pr = p->next;
p->next = q;
q = p;
p = pr;
}
head->next = q;
return head;
}

3. 大数据框架

  1. 存储框架

mysql
hdfs
hbase
clickhouse
es
redis

  1. 计算框架

mapreduce
spark
flink
impala
presto
tez
clickhouse
snappydata

  1. 元数据管理框架

atlas
Metacat

  1. 资源管理和任务调度

yarn
mesos
spark自带
flink自带
mapreduce以前自带(后续拆出演化为yarn)
k8s结合docker

  1. 脚本管理

oozie
azkaban
airflow

  1. 数据质量

Griffin

  1. 数据采集

sqoop
datax
手写mapreduce或者spark
logstash
flume

  1. 数据缓冲

kafka

3.1重点

  1. hive
  2. spark
  1. spark core
  • 可变广播变量–将一个object广播出去,object内部提供需要广播数据访问,但会定时去更新这个数据
  • rdd血缘关系,方便流水线,可做数据复原
  1. spark sql
  2. spark streaming
  1. flink

4. 数仓建模

  1. 自上而下和自下而上,Bill Inmon和 Ralph Kimball的2种思路。这是整体架构设计
  2. 星型,雪花,星座,这是库表之间关系设计
  3. 三范式,这是表内部字段设计(列原子性,主键和非主键需要依赖,非主键之间不能互相依赖)。大数据很多时候反范式化,就是允许数据冗余为了查询快,不需要跨表join
  4. 缓慢变化维(一张表中字段缓慢变化,一般是五种思路,保持初始值,变为最新值,新加一行,新加一列,将变化维度单独抽出来);这里可以引申出拉链表
  5. 数仓分层–和代码分层好处和坏处是一样的,方便数据复用,方便问题定位,方便数据管理。坏处就是不同层级之间数据冗余,不同层级之间关系会变复杂

5. SQL

  1. 行列转置
select 
     case when 条件1  then 翻译值1  
     when 条件2  then 翻译值2  
     else  缺省值 
from tableName;
    select ... ,
        if(条件1,翻译值1,缺省值),
        if(条件2,翻译值2,缺省值)
        from tableNmae;
    select ... ,
        max(if(条件1,翻译值1,缺省值)),
        max(if(条件2,翻译值2,缺省值))
        from tableNmae group by 条件中的列; 

这里使用case when更合适,但注意部分场景需要group by

你可能感兴趣的:(大数据,面试,大数据,面试)