大数据面试题

大数据面试题

https://www.yuque.com/zhongguohaopangzi/igi4hb/kws4zv

京东

 

1、列举几种数据倾斜的情况,并解释为什么会倾斜,以及如何解决?

 

  1. Join的时候发生数据倾斜:
    join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.skewjoin.key=100000; 
set hive.optimize.skewjoin=false

 

广而告之

 

1、近期做得什么项目,你负责什么模块,什么技术难点让你影响深刻。

 

近期主要做的是数据挖掘相关的工作,之前在公司负责架构了实时数仓、用户画像系统。

 

2、Flume可不可以写数据到HDFS,架构中为啥要加kafka。

 

Flume可以直接写数据到Hdfs,可以配置100M 写一次 或者 10分钟写一次。但是要注意的是,我们都知道hdfs的默认块大小是128M,那么我们为什么不配置128M呢,因为flume 大概率会多一点点数据,所以一般我们都是设置100M 就行。

 

3、公司集群分布。

 

公司 集群有十几台都是混合部署的。

 

4、Zookeeper为啥做3台。

 

1、因为成本控制,3台允许1台宕机,4台允许一台宕机,为什么不用3台呢,当然是根据各个公司的业务场景以及数据量来定的

 

2、因为防止脑裂,因为 3台允许一台机器宕机 剩余两台机器大于半数,但是4台机器宕机两台,剩余2台无法选举,出现了脑裂。

 

5、公司人员分配。安卓开发多少人,iOS多少人。

 

研发那一边不清楚,有研发1组 2 组 和 3组  app专门一个组 。一个组大概10几个

 

JVM调优,具体参数

 

一般我会调整Xms和Xmx

 

RDD是什么

 

分布式弹性数据集。spark中最基本的数据抽象 就是rdd

 

RDD 有三个基本特点:

 

1、分区

 

分区 是什么意思呢,其实我们可以理解 一个RDD 中包含的数据被存储在不同的节点上,逻辑上我们也可以将RDD 认为是一个大的数据,一个RDD 中包含了多个分区,这些分区所指向的物理存储可能是在内存也可能是在硬盘。也就是说 spark的分区 并不会存储数据,数据是存储在不同的位置的,只是记录的数据的索引而已。数据都会尽可能的放在内存当中,只有当内存没有空间的时候才会放入硬盘存储,这样可以最大化的减少磁盘IO的开销。

 

2、不可变

 

不可变性是指每个RDD都是只读的,他所有的transform算子都会生成新的rdd,然后依赖这些rdd最终计算出我们的结果。这样做的好处是可以容错,可伸缩。

 

3、并行操作

 

因为rdd的分区特性,所以其天然支持并行处理的特性,即不同节点上数据可以分别被处理,然后生成一个新的RDD。

 

黑名单是什么策略,为啥要做黑名单。

 

hadoop节点下线可以使用黑名单策略,黑名单可以 一次下线多台机器,但是直接下线节点一次只能下一个。

 

正保教育

 

1、MySql什么情况下索引失效

 

  • 条件中带有or
  • like是以%开头的
  • 如果是组合索引,不是使用的第一部分

 

2、释以下Scala闭包,这样做有什么好处

 

闭包的实质就是代码与用到的非局部变量混合。

 

3、Hbase的二级索引是什么

 

hbase的二级索引讲的就是 例如我们有一个用户表,但是我们要查用户,例如我要按照城市查用户的所有属性,那么我们rowkey里面是没有的,我们需要全表扫描,那么我们就可以建立一个rowkey为 城市为前缀,后缀为 用户表的userid,column我们就存储 rowkey 和 城市名,拿到rowkey之后我们去到user表 查询 这样可以 大大的加速。一般有两种方案,一种是离线的,一种是实时的 利用协处理的方案

 

4、Java多线程状态(生命周期)

 

NEW: 新生

 

RUNNABLE:运行

 

BLOCKED:阻塞

 

WAITING:等待

 

TIME_WATING:等待一段时间

 

TERMINATED:线程终止状态

 

5、Sleep和wait有啥区别

 

sleep抱着锁睡

 

wait 释放锁,结束的时候 重新分配资源

 

6、多线程锁有几种

 

公平锁 非公平锁 可重入锁  读锁 写锁

 

7、Synchronize this和Synchronize Class那个力度大

 

Synchronize Class 力度比较大,因为 锁的是模板对象,同时可以锁 静态方法和非静态方法,那么 Synchronize this 锁的是当前对象,只能锁非静态方法

 

8、Synchronize this和Synchronize Class什么时候用合适

 

Synchronize this 用来修饰非静态方法的

 

Synchronize class 用来修饰静态方法的

 

巧达数据

 

1、Spark shuffle过程在哪些情况下会发生?为什么这些情况下需要进行shuffle?

 

例如 发生了reduce的时候会进行shuffle,在spark中有 reduceBykey groupBykey、distinct、sortbykey等这些算子执行的时候 会发生shuffle。为什么要进行shuffle呢,是因为shuffle的时候是数据重分布 ,也就是 在计算的时候,我们想到的就是数据在那里 我去哪里计算,这个想法是最好的,但是有些情况下,我的数据是分布在不同的节点上的,但是我要做一个distinct 去重 怎么办。这个时候肯定是需要把数据拉取到一个节点上来进行统一处理。

 

2、有哪些方法可以对spark任务进行调优

 

  1. 一份数据就创建一个RDD
  2. 对多次使用的rdd进行持久化
  3. 尽量不使用shuffle算子,改用mapjoin,就是将小数据广播出去在进行shuffle。
  4. 如果必须要进行shuffle 使用优化算子 例如 reducebykey、aggreatebykey 替代 groupbykey算子
  5. 使用mapParitions 、foreacheParitions
  6. 在filter 之后进行重分区,因为没有fitler之后数据量会变少,这样重分布一下数据 让程序run的更好。
  7. 使用 repartitionsandsortwithinparitions算子 替代sort 也就是边分区 边排序 比分区后排序效率要高很多
  8. 使用序列化。

 

3、哪些情况会发送数据倾斜,如何解决?

 

我们公司有很多的分公司,例如北京卖的比杭州要多很多。

 

  1. 提前用hive解决,直接聚合好,spark直接拉
  2. 在shuffle算子上设置大一些的并行度,因为并行度调大 每个rdd的数据可能会分散到不同地方。
  3. reduce join 转换为 map join 也就是广播机制
  4. 增加随机前缀,也就是将key加上一个随机数,让他去往不同的task ,进行聚合,当聚合结束后,把key拆开,然后再进行一次聚合,大概率会解决问题,如果不是join的话可行。
  5. 自定义 Partitioner
  6. 扩容rdd 加随机前缀进行join。

 

4、Java代码实现快速排序算法

 

 public static void main(String[] args) {
        int[] arr = {9,8,7,6,5,4,4,3,2};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void sort(int[] arr) {
        quickSort(arr,0,arr.length-1);
    }

    private static void quickSort(int[] arr, int left, int right) {
        if (left >= right){
            return ;
        }
        int base = arr[left];
        int i = left;
        int j = right;
        while ( i < j){
            while (arr[j]>= base && i 
  

 

5、Java代码实现二分查找算法

 

    private static int binarrySearch(int [] arr,int target){
        int l = 0;
        int r = arr.length-1;
        while (l<=r){
            int mid = l + (r-l)/2;
            if (arr[mid]== target){
                return mid;
            }else if (arr[mid]>target){
                r = mid -1;
            }else{
                l = mid +1;
            }
        }
        return -1;
    }

 

北京开拓天际

 

1、hadoop集群怎么配

 

  1. 设计架构
  2. 准备机器
  3. 机器环境准备
  4. 选型 开源 、CDH  or  ambari
  5. 搭建。

 

2、Kafka为什么读写效率高

 

写:

 

  1. 内存池的设计
  2. 批量发送数据默认200ms发送一次
  3. 强势的网络架构 Reactor网络设计模式
  4. 一直写的是队列,也就是内存写入,后续根据三层网络架构进行分发多线程处理
  5. 顺序写磁盘
  6. 零拷贝机制。减少了网络IO

 

读:

 

  1. 跳表设计
  2. 日志存储是稀疏索引设计,也就是双重定位都有索引。

 

4、spark job划分

 

在Spark中一个用户提交的程序我们叫做一个Application,一个Application有多个job组成,这些job可以并行也可以串行执行,job是由action算子来进行划分的。一个job里面有多个stage,stage是由算子之间的shuffle中由rdd关系通过stage scheduler 划分的。一个stage中有多个 task ,组成taskset,通过taskscheduler分发到不同的executor 中进行执行。

 

5、flume和Kafka有序吗

 

flume单实例可以保证有序,但是多实例无法保证。

 

kafka分区内有序,分区间无序。

 

6、flume和Kafka区别

 

flume是一个数据采集组件,kafka是一个消息中间件,应用场景不同。

 

7、linklist和arraylist那个效率高,存同一个对象那个更占内存

 

arraylist 底层是采用的 数组结构,插入时间的均摊复杂度是o(logn)的 查询时 索引查询是O(1)

 

linkedlist 采用的是链表数据结构 插入时间复杂度是 O(1)删除也是o(1),但是查询是O(n)的

 

一般情况下,LinkedList的占用空间更大,因为每个节点要维护指向前后地址的两个节点,但也不是绝对,如果刚好数据量超过ArrayList默认的临时值时,ArrayList占用的空间也是不小的,因为扩容的原因会浪费将近原来数组一半的容量。

 

8、Kafka调度

 

采用的是时间轮机制。kafka内部没有用java的定时器而是采用了自己的设计 ,时间轮的概念。在一个时间轮中 有跨度,大小还有当前时间的指针,例如我要执行8ms后的任务,那么就再当前位置添加8的位置上增加任务就好了。那么要是110ms之后呢,kafka内部的时间轮不只是一个,还有更大的,例如20ms的大小,20个格子的,也就是可以定时110ms内的。那首先会将他放入当前时间加5个格子的位置,然后执行到的时候,会把任务放入到小任务时间轮格子里进行执行。

 

9、spark流程

 

  1. 我们一般是在Yarn模式下跑的spark
  2. 编写spark提交的shell脚本
  3. 脚本启动的时候,会执行sparksubmit类中的main方法,也就是java sparksubmit
  4. 在main方法中有一个方法叫做submit方法,这个方法会反射调用client类中的方法
  5. 在Client中就会封装指令发送给RM,启动ApplicationMaster
  6. NM会找到一台nodemanager来进行启动container,并且将applicationmaster启动起来
  7. applicationmaster启动之后,会将引用交给applicationmaster
  8. applicationmaster向rm进行请求资源
  9. rm响应给所有可以启动的container节点给他,application会对这些container进行本地化选择,和机架优化策略,会告诉nm启动container
  10. 当封装完毕的时候,会封装一条指令启动CoarseGrainedExectorBackend,并启动exector
  11. 当exector启动之后会向driver反向注册,当注册完成的时候开始运行driver,首先开始启动的是sparkcontext,他会将dagscheduler,taskscheduler启动起来
  12. dagescheduler会将任务根据shuffle为界划分为stage,并把每一个stage封装为taskset交给taskschedule
  13. taskschedule会根据启动的shufflemapstage和resultstage生成shufflemaptask和resulttask,并提交给corsegraidexecterbackend进行执行
  14. 执行过程中exector一直与driver保持心跳交互
  15. 执行完成后,注销sparkcontext

 

10、Hbase的region怎么划分,每次划分大小都一样吗

 

Hbase默认的切分阈值是10G,如果region个数是一个的话,那么就会flush size * 2 否则就是按照10G的切分策略。

 

11、rowkey设计及大小范围

 

  1. 散列原则
  2. 唯一原则
  3. 长度原则(最多16个字节)

 

12、zookeeper选举机制

 

假设有三台机器依次启动

 

启动第一台:

 

  1. 还没有选举出来leader之前,所有的节点都是LOOKING的状态,也就是找leader的状态
  2. 首先会构造自己的选票,然后把自己的选票发送给所有参与选举的机器,然后就会一直去接收外部队列的外部选票,因为此时是场景驱动,其他的机器都没有机器获取到选票,只能获取到自己的选票。
  3. 然后依次进行判断,当前选票和外部接收的选票的epoch是否一直,此时肯定是一样的,然后会判断zxid,发现zxid还是一样的这个时候判断myid,发现还是一样的,这个时候就发现了我的选票就是我自己的,然后就会把自己的选票加入到合法队列里面
  4. 然后就判断合法队列中的这个选票是否大于半数,如果不大于就一直循环,并且发现别的机器一直连不上 就处于了等待状态

 

启动第二台:

 

  1. 第二台机器启动的时候还是LOOKING的状态,也就是找leader的状态
  2. 还是会构建自己的选票,然后发送给所有参与选举的机器
  3. 这个时候 第一台机器发现第二台机器起来了,然后发送了自己认为正确的选票给其他机器,然后再进行判断
  4. 第二台机器也会发送自己的选票,第二台机器先收到的是自己的选票,然后把自己的选票更新为最优的,然后发现唱票不足半数。
  5. 然后第二胎机器收到了第二台机器发来的选票以此判断epoch、zxid、myid 然后发现myid不如我啊,什么都不做
  6. 第一台机器发现有新选票了,我要看看,然后进行对比,然后发现,我靠 我没有它厉害,我认为他是最好的,然后把自己的选票更新为他的选票
  7. 然后发送给所有机器,第二台机器也就收到了和这个选票,然后对于epoch、zxid、myid对比,然后发现这不就是我吗。然后添加到选票集合中。发现唱票成功也就是大于半数了
  8. 这个时候进行发送一次,看看是否还是认为他是leader
  9. 如果是就开始更新状态为leader然后第一台发现有leader了,然后就开始更新自己的状态为follower开始同步数据
  10. leader也会开始开放端口对外进行服务

 

启动第三台:

 

  1. 发现有leader 也就成为了follower

 

水滴互助

 

1、HDFS文件系统中,fsimage 和edit的区别

 

命名空间镜像FSImage: 保存了某一时刻集群元数据信息的快照,并持久化到了磁盘中

 

镜像编辑日志EditLog: 元数据编辑日志,将每次的改动都保存在日志中,如果namenode 机器宕机或者namenode进程挂掉后可以使用FSImage和EditLog联合恢复内存元数据。

 

2、请描述MR中shuffle的过程以及作用。

 

Read阶段:MapTask通过用户编写的RecordReader,从输入InputSplit中解析出一个个的key/value

 

Map阶段:将read阶段读取过来的key/value交给map()方法执行,产生一系列新的kv值

 

Collect阶段:在用户编写的map()函数中,当数据处理完成之后,一般会写出这些数据,写出的过程中会调用OuputCollector.collect()方法输出结果,在函数内部,会调用默认的分区器来进行数据的分区,接着写入到环形缓冲区中

 

溢写阶段:当写入环形缓冲区中的数据满了之后,会将数据溢写到磁盘上,在溢写之前会对数据进行一次快速排序,并在必要的时候进行Comber或者压缩操作,并生成临时文件。

 

合并阶段:当所有数据处理完了后,maptask会将所有的临时文件进行合并成一个大文件,同时生成对应的索引文件,合并的时候采用的是归并排序,这样避免小文件问题。

 

copy阶段:reducetask从每个maptask上将数据远程拷贝过来,先拷贝到缓冲区中,缓冲区不够的时候,溢写到磁盘

 

merge阶段:在远程拷贝数据的同时,reducetask启动了两个后台线程对内存和磁盘上的文件进行合并,防止内存使用过多,和磁盘占用太大

 

排序阶段:在传入reduce方法之前,传入的数据是按照key聚集的数据,mapreduce为了实现这样的数据结构,因为maptask传过来的时候都是有序的,所以我们仅仅需要将进行一次归并排序就将这些数据聚集在一起了

 

reduce阶段:在reduce方法中对数据进行操作之后,会将数据写入hdfs中。

 

3、YARN的配置文件中,yarn.resourcemanager.scheduler.class ,yarn.nodemanagerresource.cpu-vcores两个参数分别有什么用?

 

class 是用来配置 yarn的调度策略 可以分配三种 中的一种 有 FIFO 、CAPACITY 、FAIR

 

cpu-vcores 是用来表示yarn可以使用节点的核心数,默认是8个 一般配置 cpu核心数据的 2-3倍

 

4、请实现二分查找。(不限开发语言)。

 

    private static int binarrySearch(int [] arr,int target){
        int l = 0;
        int r = arr.length-1;
        while (l<=r){
            int mid = l + (r-l)/2;
            if (arr[mid]== target){
                return mid;
            }else if (arr[mid]>target){
                r = mid -1;
            }else{
                l = mid +1;
            }
        }
        return -1;
    }

 

5、Linux中,如何调整文件最大打开数

 

1、临时设置 ulimit -a 65535

 

2、永久更新那么就更改limits文件

 

6、请列举几个常用到Linux命令?

 

ps -ef 、 rz -be 、rsync等

 

7、Hive SQL中,left outer join和left semi join的区别

 

left outer join 也就是左表有的数据 都拿出来,右表假如和join键 有多条的话 也都会展示出来

 

left semi join 是把左表中join键 在右表中有的数据都拿出来没有就算了,并且不会展示右表数据

 

微钛科技

 

1、二分查找法

 

    private static int binarrySearch(int [] arr,int target){
        int l = 0;
        int r = arr.length-1;
        while (l <= r){
            int mid = l + (r-l)/2;
            if (arr[mid] == target){
                return mid;
            }else if (arr[mid] >target){
                r = mid-1;
            }else {
                l = mid +1;
            }
        }
        return -1;
    }

 

2、二叉树后序遍历

 

    public void lastOrder() {
        lastOrder(root);
    }

    private void lastOrder(Node node) {
        if (node == null)
            return;
        lastOrder(node.left);
        lastOrder(node.right);
        System.out.println(node.e);
    }

 

3、找出数组中重复最多的元素

 

    public static  int getMaxCountNum(int[] arr){
        HashMap map = new HashMap<>();
        for (int i : arr) {
            if (map.containsKey(i)){
                map.put(i,map.get(i)+1);
            }else {
                map.put(i,1);
            }
        }
        Set> entries = map.entrySet();
        int max = Integer.MIN_VALUE ;
        int max_key = Integer.MIN_VALUE ;
        for (Map.Entry entry : entries) {
            Integer value = entry.getValue();
            if (value >max){
                max = value;
                max_key = entry.getKey();
            }
        }
        return max_key;
    }

 

国信博飞

 

1、Map或者HashMap的存储原理

 

hashmap是一个存储键值对的集合,也就是常说的key value。其中每一个键值对叫做一个 entry对象,这些对象存储在一个数组当中。这个数组也就是我们hashmap的一个主干,初始的默认值都是Null。

 

那么怎么put进去数据呢。假如我们要插入的数据是 那么这个时候 会对 helloworld进行一个hash,hash其实就是将一个值映射为另一个值。假如 对helloworld 的结果是2,那么就会在数据索引为2 的位置 插入这个entry对象。因为数组的长度是有限的,哪怕你的hash函数再好再均匀,当插入的entry对象越来越多的时候,那么肯定会发生hash冲突,当有hash冲突的时候 hashmap是采用链表的方式解决的,每个插入对象不只是一个entry同时还是一个链表的头结点。当有冲突的时候会把数据挂接到数据的后面,当链表的长度小于8的时候还是用链表,当链表的长度大于8的时候会进行转换成红黑树。当数组中的元素大于原数组的0.75倍的时候,会进行扩容 扩容为原来的两倍 并且数据会进行重排。同时数组的长度一定是2的幂次方,因为幂次方会让所有的数组元素都用上 让分布更加均匀减少hash冲突。

 

2、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?

 

单独使用A索引 有索引效果 但是使用B索引 没有索引效果。

 

3、HTTP协议,GET和POST的区别?

 

get请求是将参数写到url里面,post是把参数写入到请求体里面。

 

天虹商场

 

1、如果canal传入kafka的数据无序应该怎么办?

 

  1. 配置canal的数据 分区数为 下游kafka的分数区 和 配置表的 主键 为hash
  2. 在消费的时候进行数据比对,如果已经消费了 那么就比对数据
  3. 消费的时候单线程消费会比较慢,用多线程加队列的方式 是比较好的。

 

2、Flink实时和spark的区别?

 

从宏观上理解,flink是实时处理,spark是微批处理,因为当初他俩的设计理念就是不一样的。

 

第二点呢,flink的批处理没有spark的批处理要强 ml 没有spark的ml厉害 第三点呢,就是flink 在实时处理方面要强过sparkstreming 因为flink 有状态  并且可以保证精确一次性语义。窗口操作也比spark多。

 

3、你们的数据存在hdfs上还是hbase,格式是什么

 

如果是现在这个公司的话,数据是存储在hdfs当中的 是parquet格式。

 

4、你们公司的数据量有多少

 

一天30-40G 左右 但是会出现膨胀,大概一天100G左右

 

5、你在公司项目中起到什么作用

 

主要负责架构和主程

 

6、Join和left join

 

join 返回两个表中都有的数据

 

left join 返回 左表中全部数据,右表中 在左表中存在的数据

 

袋鼠云

 

1、Spark怎么做到Exactly-once?

 

做到这个有三点:就是要采用direct模式消费kafka的数据;自己保存和维护offset;将计算和 更新偏移量放到一个事务中。

 

步骤是这样的:

 

  1. 启动后先从mysql中获取偏移量数据,也就是一个分区一个便宜量
  2. 使用获取到的offset创建directstream
  3. 将结果处理和偏移量处理放到一个事务当中,要么都成功要么都失败

 

2、flink的怎么和rocksDB交互的。画一个流程图。

 

大数据面试题_第1张图片

 

3、flink怎么实现Exactly-once?

 

一般Flink进行消费的时候大概率都是kafka,Flink保证精确一次性消费有几种机制来共同保证的,状态机制,checkpoint,二阶段提交。状态机制是flink 的核心,也就是flink自称流状态计算的根本原因,flink中的状态分为两种,operator state、keyed state,其中kafka的source端采用的是operatore state 来进行记录的偏移量,flink的checkpoint是最核心的部分,也就是将状态持久化。这个持久化,其实就是将我们内存中的状态写入到状态后端中进行持久化,有三种内存后端、HDFS后端、和RocksDB后端,这个是保证状态数据不会丢失。那么二阶段提交的意思是,jobmanager会定期的发送执行checkpoint的命令,当source端收到执行指令之后,就会插入一条barrier消息到input队列中,当处理barrier的时候会执行本地checkpoint,也就是把当前task的状态给保存起来,并且将barrier发送到下一个结点,当checkpoint完成之后会发送一条ack信息给jobmanager。

 

当所有节点都完成了checkpoint的时候,jobmanager收到了所有的ack这个时候,就会进行提交事务。

 

其实就是在状态存储完成后,会进行预提交操作,也就是将offset写入到kafka中,但是并不提交事务,在状态全部都完成后就会提交事务。

 

4、flink on yarn 的任务提交流程?

 

大数据面试题_第2张图片

 

  1. 任务提交后,client向hdfs上传flink的jar包以及配置
  2. 向yarn的resourcemanager提交任务
  3. resoucemanager分配container资源并通知对应的nodemanager启动applicationmaster
  4. applicationmaster启动后加载flink的jar包和构建环境 启动jobmanager
  5. applicationmaster向resourcemanager申请资源启动taskmanager
  6. nodemanager加载flink的jar包和配置环境启动taskmanager
  7. jobmanager就会分配任务 直到任务结束

 

5、rocksDB为什么可以存储那么大的数据量。

 

rocksdb会将业务数据存储于多个sst文件中,业务数据的存储量依赖于当前peer节点的磁盘大小。

 

6、使用eventtime+watermark的时候,如果数据到6点结束了。怎么保证最后一条数据能计算。

 

用CountTrigger 来一条触发一次窗口计算,但是他不是等窗口关闭才触发计算,是来一条触发一次。或者自定义trigger

 

7、你理解的什么样的数仓是一个好的数仓。

 

被业务所认可,第二他的扩展性要好,运行稳定,数据质量有保证。

 

8、你们有做过数据的结果的校验吗?怎么校验的

 

我们是实时和业务库进行对账,因为我们关心的是销售额,只要差异在百分之3以下就可以接受。

 

9、Flink topN的实现

 

10、使用状态后端的时候与hdfs/rocksdb的交互

 

 

11、用原生api创建线程池和调用

 

        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(
                        5,
                        10,
                        0L,//永不过期
                        TimeUnit.SECONDS,
                        new LinkedBlockingDeque<>(3),
                        Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.DiscardOldestPolicy());
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("heheh");
            }
        });
        threadPoolExecutor.shutdown();

 

12、map和list的各实现类的用法与区别

 

list的实现类一般有 Arraylist 和linkedlist,Arraylist底层采用的数组,插入时间复杂度是logn,索引查找的时间复杂度是1,linkedlist插入时间复杂度是1,查找是1

 

map的实现类一般有hashmap和hashtable,hashmap插入时间复杂度是1的

 

13、数仓各层的理解

 

ODS:直接加载的是采集到的原始数据,数据保存原貌不做处理,就一个字段(一行就是一个日志字符串),使用天作为分区表,一般为json数据

 

DWD:对ods的数据进行展开

 

例如:如果采集的日志分类型的,可以根据事件的类型分为多个表

 

电商的比如:点赞、启动、评论、点击、广告、消息通知等事件

 

my公司的:以行业类型分割为各个阵地表,对json数据进行解析,获取简历、滴滴行程单、邮件落款、http等数据

 

DWS: (数据服务层): 基于ADS需要统计的主题,创建宽表

ADS: (应用数据层): 基于DWS的宽表,计算出结果

 

14、怎么把hdfs上的数据导到hive,内部和外部表

 

load data inpath '/hivedata1.txt' into table rdcuser; # 外部表

1.hive无论是内部表还是外部表,无非就是往对应的hdfs目录复制文件,再以定义的表结构来读取数据。
2.hive删除内部表时,会连同数据文件、元数据一起删除,而外部表仅删除表里的元数据,数据文件不会删除。

 

15、星型模型和雪花模型,事实表维度表

 

大数据面试题_第3张图片

 

在多维分析的商业智能解决方案中,根据事实表和维度表的关系,又可将常见的模型分为星型模型和雪花型模型。在设计逻辑型数据的模型的时候,就应考虑数据是按照星型模型还是雪花型模型进行组织。

 

当所有维表都直接连接到“ 事实表”上时,整个图解就像星星一样,故将该模型称为星型模型,如图 1 。

 

星型架构是一种非正规化的结构,多维数据集的每一个维度都直接与事实表相连接,不存在渐变维度,所以数据有一定的冗余,如在地域维度表中,存在国家 A 省 B 的城市 C 以及国家 A 省 B 的城市 D 两条记录,那么国家 A 和省 B 的信息分别存储了两次,即存在冗余。

 

大数据面试题_第4张图片

 

星型模型因为数据的冗余所以很多统计查询不需要做外部的连接,因此一般情况下效率比雪花型模型要高。星型结构不用考虑很多正规化的因素,设计与实现都比较简单。雪花型模型由于去除了冗余,有些统计就需要通过表的联接才能产生,所以效率不一定有星型模型高。正规化也是一种比较复杂的过程,相应的数据库结构设计、数据的 ETL、以及后期的维护都要复杂一些。因此在冗余可以接受的前提下,实际运用中星型模型使用更多,也更有效率。

 

事实表:

 

事务事实表

 

官方定义是:发生在某个时间点上的一个事件。比如以订单为例:下单是一个事实、付款是一个事实、退款是一个事实,所有事实的累计就是事务事实表

 

周期快照事实表

 

如果需要对某一天或者某个月的数据进行分析,那么可以使用周期快照事实表,比如:以天举例,财务报表一般都是周期快照事实表,它的最细粒度主键就是:日期+订单

 

累计快照事实表

 

累计快照表,具有确定的开始和结束事件,并且记录关键事件或者过程的里程碑,它因此包含了很多日期的外键

 

16、namenode的内存结构

 

namenode 里面存储目录树,也就是INODE的抽象模仿的是linux,在底层实现上 对于文件有InodeFile 和InodeDirecdory。存储目录数的是arraylist

 

17、数据质量监控

 

1、完整性:

 

是否有丢失数据问题、有可能行丢了 也可能列丢了,一般会在数据接入的时候做完整性校验,例如从hive导入 clickhouse数据 会做校验

 

2、准确性:

 

准确性我们校验的,是每日的日活和销售额。是否和平时会有很大的差异。

 

3、一致性:

 

一致性是指同一指标在不同地方的结果是否一致。也就是一个指标对外展示的数据是否一致,就像销售额,和促后毛利,到分公司累加是否可以得到总数

 

4、及时性

 

也就是要监控大数据平台是否有数据积压,例如实时数仓中的flink和kafka的监控 夜晚的 etl监控

 

18、kafka的数据重复在数仓怎么处理的

 

因为我们是有clickhouse实时数仓的,会在clickhouse用replicing mergetree 引擎 去重。

 

19、存储格式及对比

 

大数据面试题_第5张图片

 

大数据面试题_第6张图片

 

大数据面试题_第7张图片

 

总结:如果仅仅是在HIve中存储和查询,建议使用ORC格式,如果在Hive中存储,而使用Impala查询,建议使用Parquet

 

飞贷金融

 

1、Java常用的设计模式,适用场景

 

模板方法,工厂模式,单例模式,策略模式。

 

2、Java多线程,多线程的状态

 

大数据面试题_第8张图片

 

3、Impala运行机制,架构,优化机制

 

Impala运行

 

  1. 客户端通过ODBC、JDBC、或者Impala shell向Impala集群中的任意节点发送SQL语句,这个节点的impalad实例作为这个查询的协调器(coordinator)。
  2. Impala解析和分析这个查询语句来决定集群中的哪个impalad实例来执行某个任务。
  3. HDFS和HBase给本地的impalad实例提供数据访问。
  4. 各个impalad向协调器impalad返回数据,然后由协调器impalad向client发送结果集。

 

Impala架构

 

大数据面试题_第9张图片

 

4、CDH怎么增加,删除一个节点

 

在主机页面中下线和上线

 

5、堆排序

 

代学

 

7、Sqoop的应用场景

 

主要是从业务数据库中将数据抽取到hive数仓中 或者从数仓中将数据抽取到 业务库。也就是看板库 或者指标库。

 

五矿证券

 

1、hive半天跑不出任务。也没有报错,你咋办?实际工作中就是会出现。你怎么分析

 

  1. 首先会看是否发生了数据倾斜
  2. 查看hive执行日志
  3. 查看mr执行页面
  4. 是否资源不足在等待执行

 

2、spark和hive shuffle的区别

 

首先个人任务spark被称为是基于内存的计算框架,其最初的设计目标是想把数据域结果存放在内存中,这样可以对数据进行快速的存取,但是由于数据量大的话,内存是远远不够的,那么就会和磁盘进行大量的交互,这个时候效率就会低。还有一个问题是,内存容易崩溃也就是掉电,我遇到过一次redis 内存坏了,这个时候是一件很糟心的事情,数据是存储在内存中的,可能会频繁的调用java gc机制,对于gc压力很大,容易出现垃圾回收不急导致性能问题。单节点不能处理很大的数据,如果单节点的内存超出本身内存大小,会出现问题,就像clickhouse分布式join的时候结果集大于一台机器内存的时候会有问题,所以一般采用allowjoin。mapreduce 任务是基于hdfs的,本身硬盘存储数据的可靠性就很高,其次hdfs对于文件结果有自己的备份与恢复机制,一个文件存储在多个副本,他可能会慢一些,但是,他稳定,尤其是在夜维的过程中,1-2个小时的时间,真的不是那么太重要。

 

3、spark提交任务的流程

 

  1. 我们一般是在yarn模式下跑的spark
  2. 编写spark提交的shell脚本
  3. 脚本启动的时候会执行sparksubmit类中的main方法,也就是java sparksubmit
  4. 在main方法中有一个方法叫做submit方法,这个方法会反射调用client类中的方法
  5. 在client中就会封装指令发送给rm,启动applicationmaster
  6. rm会找到一台节点启动 container,并且将applicationmaster启动起来
  7. applicationmaster启动之后,会将引用交给applicationmaster
  8. applicationmaster向rm进行请求资源
  9. rm响应给applicationmaster可以启动container节点给他,application会对这些conatiner进行本地化选择和机架优化策略,会告诉nm启动container。
  10. 当封装完毕的时候,会封装一条指令启动coarsegrinedexctorbackend并启动exector
  11. 当exector启动之后会向driver反向注册,当注册完成的时候 开始运行driver。首先开始启动的是sparkcontext,他会将dagscheduler和taskscheduer启动起来。
  12. dagscheduler会将任务以shuffle为界划分为stage,并把每个stage封装为taskset交给taskscheduler
  13. taskscheduler 就会吧划分的号的shufflemapstage和resultstage生成shufflemaptask 和resulttask 并其交给csbackend进行执行
  14. 执行过程中exector一直与driver保持心跳交互,执行完成后,注销sparkcontext

 

4、mapreduce的shuffle原理

 

read阶段:maptask通过用户编写的recordreader,从输入inputsplit中解析出一个个的key、value

 

map阶段:将read阶段的数据key value交给 map方法执行,执行结束后生成新的keyvalue

 

collect阶段:在用户编写的map函数中,当数据处理完成之后,一般会写出这些数据,写的过程中会在函数内部调用分区器对数据进行分区,然后写入到环形缓冲区中。

 

溢写阶段:当写入环形缓冲区中的数据满了之后,会将数据溢写到磁盘上,在溢写之前会对数据进行一次快速排序并在必要的时候进行comber或者压缩操作,并生成临时文件。

 

合并阶段:当所有数据处理完了后,maptask会将所有的临时文件进行合并成一个大文件,同时生成对应的索引文件,合并的时候采用的是归并排序,这样避免小文件问题。

 

copy阶段:reducetask从每个maptask上将数据远程拷贝过来,先拷贝到缓冲区中,缓冲区不够的时候,溢写到磁盘

 

merge阶段:在远程拷贝数据的同时,reducetask启动了两个后台线程对内存和磁盘上的文件进行合并,防止内存使用过多,和磁盘占用太大

 

排序阶段:在传入reduce方法之前,传入的数据是按照key聚集的数据,mapreduce为了实现这样的数据结构,采用了归并排序来进行数据聚集。

 

reduce阶段:在reduce方法中对数据进行操作之后,会将数据写入hdfs中。

 

5、hive优化

 

  1. mapjoin
  2. 行列过滤
  3. 列式存储
  4. 合理的分区策略
  5. 合理设置map数
  6. 合理设置reduce数
  7. reduce中间结果压缩
  8. 小文件解决
  9. jvm重用
  10. 采用tez 和spark引擎

 

6、你怎么保证数据的准确性

 

  1. 控制业务的修改逻辑
  2. 保证理解业务
  3. 数据质量监控

 

边锋科技

 

1、关系型数据库和非关系型数据库的区别和应用场景?

 

OLTP和OLAP主要区别有:

 

1、基本含义不同:OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,记录即时的增、删、改、查,比如在银行存取一笔款,就是一个事务交易。OLAP即联机分析处理,是数据仓库的核心部心,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。典型的应用就是复杂的动态报表系统。

 

2、实时性要求不同:OLTP实时性要求高,OLTP 数据库旨在使事务应用程序仅写入所需的数据,以便尽快处理单个事务。OLAP的实时性要求不是很高,很多应用顶多是每天更新一下数据。

 

3、数据量不同:OLTP数据量不是很大,一般只读/写数十条记录,处理简单的事务。OLAP数据量大,因为OLAP支持的是动态查询,所以用户也许要通过将很多数据的统计后才能得到想要知道的信息,例如时间序列分析等等,所以处理的数据量很大。

 

4、用户和系统的面向性不同:OLTP是面向顾客的,用于事务和查询处理。OLAP是面向市场的,用于数据分析。

 

5、数据库设计不同:OLTP采用实体-联系ER模型和面向应用的数据库设计。OLAP采用星型或雪花模型和面向主题的数据库设计。

 

2、MySQL事务和隔离级别

 

mysql的事务呢,我理解就是事务是多个操作数据库的动作集合,要么全部成功,要么全部失败

 

事务的四大特性(ACID)

 

  • 原子性:意思就是在一个事务中,事务是不可分隔的,也就是说不能一半成功,要么全部成功要么全部失败
  • 一致性:事务操作会确保数据库状态保持一致性,事务提交前和事务提交后数据库状态会发生变化,但是会保持一致。
  • 隔离性:隔离性指的是事务间是相互独立的,不会互相影响,例如点餐过程为一个事务。从电话订购到做出饭菜送餐完成结算所有这些操作假如为一个事务。不同的人进行点餐操作都是互相独立的,并不会互相影响,这就是事务的隔离性,如果一个事务影响了其他的事务,其他的事务会进行回滚,就如上面的点餐例子,如果饭菜已经卖完了,最后点餐的事务将会影响后面的事务,因为没有餐可点了,那么后面的事务将会进行回滚
  • 持久性:事务提交的结果,假如成功的话,那么永远不变。

 

事务的四大隔离级别(ACID)

 

  • 读未提交:也就是别人未提交的事务你也可以读取到
  • 读已提交:是读取别人已经提交的事务
  • 可重复度:可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。
  • 串行化:读取操作会使用共享锁,可以保证不同事务的互斥,也就是锁表。

 

3、HDFS读写流程

 

写流程:

 

  1. 往hdfs目录树中添加INodeFile
  2. 添加契约,也就是当前仅有一个客户端可以操作这个文件(后台会有一个线程一直进行扫描契约是否过期)
  3. 启动DataStreamer来进行写数据的操作
  4. 进行启动线程进行续约操作
  5. 将chuck写到packet然后将packet加入到dataQueue
  6. 向namenode去申请block,也就是返回可用的datanode节点(数据的负载均衡,也就是机架感知和其他的一些策略·)
  7. 建立datanode之间的数据管道
  8. 先把要写出的数据添加到ackQueue里面,然后写数据,移除dataQueue中的package,假如此时写数据失败了,就把ack队列里面的package添加到dataQueue中重新写
  9. 然后datanode会初始化一个PacketResonder的线程,进行将我们的数据写入到ack队列,然后把数据写入其他的datanode同时获取其他datanode的处理结果,将数据写入磁盘,然后依次层层上报给我们的客户端,写失败了,还是会用ack机制。
  10. 假如数据管道建立失败了,就删除向namenode申请的block然后重新建立block和建立数据数据管道
  11. 假如在datanode写数据流程中出现问题,那么这个会分为两个流程,先判断写几个副本写失败了,如果是三个副本的情况下,>=2的时候。这个时候重新去申请建立管道,如果只有一个的话,那么这个时候没事,重新建立管道,这个时候管道此时就两个节点,失败的踢出,等namenode的心跳来处理他的问题。

 

4、MapReduce流程

 

read阶段:maptask通过用户编写的recordreader,从输入inputsplit中解析出一个个的key、value

 

map阶段:将read阶段的数据key value交给 map方法执行,执行结束后生成新的keyvalue

 

collect阶段:在用户编写的map函数中,当数据处理完成之后,一般会写出这些数据,写的过程中会在函数内部调用分区器对数据进行分区,然后写入到环形缓冲区中。

 

溢写阶段:当写入环形缓冲区中的数据满了之后,会将数据溢写到磁盘上,在溢写之前会对数据进行一次快速排序并在必要的时候进行comber或者压缩操作,并生成临时文件。

 

合并阶段:当所有数据处理完了后,maptask会将所有的临时文件进行合并成一个大文件,同时生成对应的索引文件,合并的时候采用的是归并排序,这样避免小文件问题。

 

copy阶段:reducetask从每个maptask上将数据远程拷贝过来,先拷贝到缓冲区中,缓冲区不够的时候,溢写到磁盘

 

merge阶段:在远程拷贝数据的同时,reducetask启动了两个后台线程对内存和磁盘上的文件进行合并,防止内存使用过多,和磁盘占用太大

 

排序阶段:在传入reduce方法之前,传入的数据是按照key聚集的数据,mapreduce为了实现这样的数据结构,采用了归并排序来进行数据聚集。

 

reduce阶段:在reduce方法中对数据进行操作之后,会将数据写入hdfs中。

 

5、HIVE和Hadoop的关系

 

hive是一个数据仓库组件sql化查询引擎,底层引擎是可插拔的,可以依赖于spark、mapreduce、tez。底层存储是依赖于hadoop的hdfs。计算引擎是跑在 yarn上面的。

 

6、数仓分层,每层都做了什么;都有什么事实表

 

分层:

 

ODS:贴源层

 

DWD:明细层

 

DWS:聚合宽表层

 

ADS:数据集市层

 

事实表有库存、销售、用户行为、用户等级等。

 

7、分析的指标有什么?

 

实时线上分析、实时销售明细、实时预售、实时促销、实时用户等

 

8、数据倾斜的处理?

 

1、set hive.groupby.skewindata=true

 

2、看看是否可以过滤一个表成为小表,变成mapjoin

 

3、如果是count操作的话,那么就采用group by sum的操作,使用sum...group by代替。如select a,sum(1) from (select a, b from t group by a,b) group by a;

 

4、大表和大表join的话,如果join键是固定的,可以用分桶

 

比客

 

1、Java的熟不熟,常见的Java集合说一下

 

ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap

 

2、spark streaming消费kafka,怎么样保证数据消费唯一性

 

做到这个有三点:就是要采用direct模式消费kafka的数据;自己保存和维护offset;将计算和 更新偏移量放到一个事务中。

 

步骤是这样的:

 

  1. 启动后先从mysql或者redis中获取偏移量数据,也就是一个分区一个便宜量
  2. 使用获取到的offset创建directstream
  3. 将结果处理和偏移量处理放到一个事务当中,要么都成功要么都失败

 

3、spark shuffle过程

你可能感兴趣的:(spark,Flink,数据库,数据库,spark,flink)