字节实习二面问题复盘,问的挺细的

二面的强度比较大,问的问题都很深刻,关于对上一段的实习经历的询问就暂时不放出来了,因为是用实习公司的实际运营内容去作答的,涉及到机密问题。

ok,让我们再复盘一下面试官问的技术细节问题吧。

1.Spark是怎么做内存管理的?(开头就有点涉及到我的知识盲区了)

因为Spark与MapReduce最大的区别就是Spark是在内存中做计算,中间数据几乎不落盘,所以Spark对内存的管理有一套它自己的规范,主要目的是平衡数据的存储(基本就是RDD 的缓存,注意:很多同学一想到RDD的缓存就也想将checkpoint说出来,但是checkpoint是把时间落盘了的,这点要尤其注意,说错了很减分)和执行计算(比如shuffle、排序等计算任务)的内存需求,同时减少磁盘IO和GC(垃圾回收)的开销。

Spark早期是做的静态内存管理,它将内存划分为固定大小的独立区域,这些区域的数据是不能交互共享的。Spark源码中默认是把内存的60%划给了存储内存,用来缓存RDD和广播变量,把内存的20%划给了执行内存,执行内存就是专门做计算的内存,剩余20%命名为other内存,存一些内部对象和用户代码的。

静态内存管理的缺陷很显而易见,各片区域不能动态共享,那势必会导致某些内存资源没有被充分利用,解决这种静态划分问题的办法已经很成熟了,就是做动态内存管理,允许存储内存和执行内存动态共享空间。(还记得之前学习队列之间相互共享资源吗?如果一个任务队列的内存资源不够,它可以使用另一个队列的内存资源,当然,如果另一个队列后面需要这部分被借走的内存资源,它会立即回收回来)

动态内存管理把内存也做了大致区分,它把总内存的75%用于“存储和执行”,存储内存和执行内存之间是可以动态调整的,也就是可以“借”。剩下25%作为其他内存。

2.Spark是怎么对RDD进行缓存的呢?

缓存RDD的数据时,并不是直接把这些数据放在内存中,比如我这个RDD中的数据是int数据,Spark不会以int型数据去存,而是把这些int型数据做序列化存储到内存中,因为内存是很有限的,序列化就可以降低缓存的内存需求,就像刚刚提到的,存储内存少了,执行内存就多了,就能省很多spill操作,计算速度就会快。当我们需要从缓存中读数据的时候,再反序列化回成int型数据就可以了。

3.RDD为什么设置成不可变的?

RDD不可变主要是为了解决分布式环境下数据的容错性、计算任务的并行性和数据的一致性问题。

首先我先解释一下RDD不可变是怎么保证数据的容错性的,我们知道,分布式计算的核心问题就是节点出现故障导致数据丢失,之前我们为了防止数据丢失和数据算错的问题,我们是对RDD做了RDD lineage的,通过RDD lineage就可以重新对丢失的这一分区数据进行计算,因为如果是窄依赖的话,这个丢失的分区数据其实只依赖与它的上游分区数据,所以我们拿到上游依赖分区数据重新算就好了,避免重新算整个数据集,节省计算资源。

第二,就是任务的并行性,如果RDD能进行修改,那我们多个任务如果修改同一个RDD,就会有并发修改冲突(比如覆盖,脏读),要想解决这种并发修改冲突,还要引入复杂的分布式锁机制,这样会导致计算效率不是很高。

第三就是数据的一致性了,我们在计算任务中会将RDD中的数据缓存或者使用checkpoint存储起来,如果中途RDD发生变化,那么我们存储的数据就失效了,白忙活一趟,为了保证存储的RDD数据和计算中的RDD一致,我们就不修改RDD。

再后面就是询问实习项目细节和手撕了,手撕题我已经发布,大家可以看看,字节招聘时我感觉会更关注解决实际问题和创新的能力,会更偏向工程一点,问的一些问题基本上都是在工作会遇到的一些小问题,解决这些问题需要比较强的Spark和Hive的执行流程理解。

全部评论
楼主牛逼,复盘到这个程度,一看就是干大事的
1 回复 分享
发布于 09-18 21:27 陕西
同学,瞅瞅我司,医疗独角兽,校招刚开,名额有限,先到先得,我的主页最新动态,绿灯直达,免笔试~
2 回复 分享
发布于 09-20 09:03 广东

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务