大数据面试总结(一)

HDFS

1.HDFS的写流程
答:在这里插入图片描述

详细步骤:
1.客户端向NameNode发出写文件请求
2.检查是否已存在文件、检查权限。若通过检查,直接先将操作写入EditLog,并返回输出流对象。
(注:WAL,write  ahead  log,先写Log,再写内存,因为EditLog记录的是最新的HDFS客户端执行所有的写操作。
如果后续真实写操作失败了,由于在真实写操作之前,操作就被写入EditLog中了,所以EditLog中仍会有记录,
不用担心后续Client读不到相应的数据块,因为在第五步中DataNode收到块后会有一些确认信息,
若没有写成功,发送端没收到确认信息,会一直重试,知道成功【涉及到检查点机制】)
3.client端将数据按128MB的块切分文件
4.Client将NameNode返回的分配的可写的DataNode列表和Data数据一同发送给最近的第一个DataNode节点,
此后client端和NameNode分配的多个DataNode构成pipeline管道,client向输出流对象中写数据。
client每向第一个DataNode写入一个packet,这个packet便会直接在pipeline管道中传给第二个、第三个DataNode。
(注:并不是写好一个块或一整个文件后才会向后分发。)
5.每个DataNode写完一个块后,会返回确认信息。
6.写完数据,关闭输出流。
7.发送完成信号给NameNode。

【也可以使用下图】
在这里插入图片描述
2.HDFS的读流程
答:
在这里插入图片描述

读详细步骤:
1.cliet访问NameNode,查询元数据信心,获得这个文件的数据块位置列表,返回输入流对象。
2.就近挑选一台datanode服务器,请求简历输入流
3.DataNode向输入流中写数据,以packet为单位来校验
4.关闭输入流

3.HDFS的Shuffle过程
答:在这里插入图片描述

shuffle过程是从map写数据到环形缓冲区到reduce读取数据合并
1.从map函数输出到reduce函数接受输入数据,这个过程称之为shuffle
2.map函数的输出,存储环形缓存区(默认大小100M,阈值80M[阈值80%])
(环形缓存区:其实是一个字节数组kvbuffer.有一个sequator标记,kv原始数据从左到右填充(顺时针),
kvmeta是对kvbuffer的一个封装,封装成int数组,用于存储kv原始数据的对应的元数据
(valstart,keystart,partition,vallen),从右向左(逆时针))
3.当达到阈值时,准备溢写到本地磁盘(因为时中间数据,因此没有必要存储在HDFS上)。
在溢写前要进行对元数据分区(partition)整理,然后进行排序(quick  sort,通过元数据找到key,
同一个分区的所有key进行排序,排序完,元数据就已经有序了,在溢写时,按照元数据的顺序寻找原始数据进行溢写)
4.如果有必要,可以在排序后,溢写前调用combiner函数进行运算,来达到减少数据的目的。
5.溢写文件可能产生多个,然后对这多个溢写文件进行再次合并(也要进行分区和排序)。
当溢写个数>=3时,可以再次调用combiner函数来减少数据。当溢写个数<=3时,默认不会调用combiner函数。
6.合并的最终溢写文件可以使用压缩技术来达到节省磁盘空间和减少向reduce阶段传输数据的目的(存储在本地磁盘中)
7.Reduce阶段通过HTTP抓取属于自己的分区的所有map的输出数据(默认线程数是5,因此可以并发抓取)
8.抓取到的数据存在内存中,如果数据量大,当达到本地内存的阈值时会进行溢写操作,在溢写前会进行合并和排序(排序阶段),然后写到磁盘中
9.溢写文件可能产生多个,因此在进入reduce之前会再次合并(合并因子是10),
最后一次合并要满足10这个因子,同时输入给reduce函数,而不是产生合并文件。reduce函数输出数据会直接存储在HDFS上。

4.数据复制规则(机架感知,心跳机制)

以3副本为例:
1.第一个副本放置在上传文件的DataNode服务器节点上,如果在集群外提交,则随机放置在一个DataNode上
2.第二个副本放置在于第一个DataNode不同的机架的一个节点上
3.第三个副本放置在与第二个DataNode相同的机架的不同节点上

在这里插入图片描述
在这里插入图片描述

Hive

1.数据从MySQL拉取到Hive中,利用Sqoop,是全量导入还是增量导入?
答:(针对不同类型的数据采取不同的导入策略)例如昨天一天的订单就全量导入,因为每一天的订单,全部都要汇总分析;新增用户就采用增量导入,新增用户数量不会出现很大的改变,所以采用增量导入的方式(增量导入方式分为两种:一是基于递增列的增量数据导入(Append方式)。二是基于时间列的增量数据导入(LastModified方式))。
2.导入过亿级别数据量的表么?出现过运行sqoop跑不动或者卡内存?
答:(Sqoop分批导入Mysql上亿条数据的表到HDFS,可以使用shell脚本,循环调用Sqoop导入数据,或者根据时间来导入)
3.数据倾斜怎么办
答:采用”加盐“的方法
4.手写SQL
(1)求每门课程成绩都在80分以上的学生姓名
方法1:先求出所有分数>80的信息,然后以学生姓名分组,如果分组后count(1)=课程门数,则显示学生姓名【这种方法有缺点,必须事先知道总的课程门数,否则得不到结果】
方法二:先按学生姓名分组,然后求出每组中的最低分>80,并且count(1)=总课程门数
【这里容易缺失”count(1)=总课程门数“这个条件,试想这样一种情景:总课程门数=4,但是表中任意一名学生的考试门数都小于4】
(2)每门课程的分数排序前10名
使用rank() over()开窗

spark

1.distinct怎么实现?
答:distinct(去除重复数据),这个算子是transform算子
在这里插入图片描述
在这里插入图片描述
2.coalesce和repartition的区别?
答:repartition是coalesce shuffle=true的特殊情况,coalesce默认是shuffle=false,在使用过程中,虽然都是调整分数数目,但是coalesce只能从大到小调整,repatition可以任意从大到小,也可以从小到大。
3.spark的宽窄依赖
4.spark的shuffle过程
5.RDD的缓存
6.job和stage的划分?有什么特殊情况?
7.人物画像中,指标的衰减
8.人物画像中,标签的体系结构
9.广播变量为什么好?
答:广播变量是将driver上的小表广播到每一个executor上,而不再需要每一个task运行时向driver抓取数据,避免了reduce join,实现了map join。

Scala

1.Object和class的区别

在Scala中,类名可以和对象名为同一个名字,该对象称为该类的伴生对象,类和伴生对象可以相互访问他们的私有属性,但是它们必须在同一个源文件中
Class:编译器会自动帮我们产生一个私有字段和2个公有方法get和set
类只会被编译,不能直接执行,类的声明和主构造器在一起被声明,在一个类中,主构造器只有一个。
类和它的伴生对象可以相互访问私有成员,class中的main方法没什么用
Oject:所有成员变量和方法默认都是static的,所以可以直接访问main方法。class和object的一个差别是,单例对象不带参数,而类可以。因为你不能用new关键字实例化一个单例对象,你没有机会传递给它参数
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值