京东数据挖掘一面面经(真·内推)
面试时长90min(中间穿插着写SQL和算法题)
真·内推:
我一直准备的是Java后端开发,这个岗是因为一个朋友要离职了帮他leader找个人,然后就找到了我。刚开始和我说这个岗去了主要就是写写sql(因为他们是主要用hive做数据分析,而hive和sql非常类似,会写sql就会写hql(hive sql)),然后给我说面试时需要简单准备一点hive和spark八股,并且还给我划重点,哪些是一定会问的,着重准备哪块知识(文末附八股链接)。在北京,薪资是1.3W/月(算上房补和饭补),旁边也有公寓,整体条件还是很不错的,虽然说和我的方向不是很一致,但这毕竟是真正的内推(临时改了改简历发给他,他leader稍后就联系我了,并且约了面试,因为是不太熟悉的领域,所以我把时间稍微往后推了推,好让自己有个准备的过程),虽说京东不是互联网巨头,但耳熟能详(我秋招时准备去国企,有个知名企业的实习会更有说头),此外待遇也不差(1.3一个月算是比较多的了,说实话确实有点心动),旁边还有公寓,这都帮我提前打点好了,去了直接继承就行,于是就花了1.5周的时间好好准备了一下。
面试过程:
是我朋友的leader面的我,我们之前也在微信上聊过
开场:
1.先做下自我介绍吧(通常刚上来就自我介绍并不是真的在听你的介绍(不要想着介绍完会顺着问下去,除非说到面试官感兴趣的点),因为他大概率还没看过你的简历,这期间就是快速扫一遍简历的,所以没准备的话也无需太紧张,说慢一点,本科在哪儿读的,主修了课程(挑熟悉的说),自己的求职方向,做过啥项目。当然提前有准备的话更好,但如果上来先手撕代码,那这期间就把你简历看了,这种情况的自我介绍就又不一样了)
2.有参与过什么项目吗(我说做的是Java项目,他说:奥,那不问了)
3.诶,中北大学是在哪里的,是211吗(山西-太原-双非-一本)
4.看你的本科专业是数据科学与大数据技术,有没有学过什么大数据语言编程啊(hive、spark学过一些,也就准备的这俩)
5.研究生学的哪些课程呢(我说课比较杂,他也没再细问)
6.MySQL数据库学的还不错是吧,说一下有哪些存储引擎,以及它们的区别(常用的有InnoDB和MyISAM)
7.(见我答的还可以,进一步追问)他俩(InnoDB和MyISAM)的B+树有什么区别吗(这个就盲区了)
8.(场景题)mysql的场景下,假设有一张表,表的字段有id、姓名、年龄、性别、出生日期等,在做查询时有对性别、年龄、出生日期等多个字段的限定,那么对于出生日期字段的限定应该放在where语句的前面还是后面,为什么?
9.(一些数据结构的基本概念)栈和队列的特点、树的遍历方式,每种方式如何遍历
大数据:
1.Hive里面内外表的概念以及它们的区别
2.order by与sort by的区别(分别解释对比一下cluster by、sort by、distribute by、order by)
3.Hive SQL执行时会转成MapReduce去执行,MapReduce的执行过程一般是干嘛的,就是说Map阶段干了什么,Reduce阶段干了什么(这个我背的八股上没有,没答上来,但这确实是一个比较基础且核心的点了,这块都不知道在干嘛,其他的八股也只是空中楼阁。所以面试官判断我就是在背八股,对大数据框架的理解几乎为0,所以大家再准备的时候,一些基本的问题一定要透彻理解,一方面会帮助你理解其他高级知识,另一方面被面试问到的话如果你答得很详细就会显得你基本功很扎实)
4.数据倾斜有哪些处理方式(这个是八股的重点,要全面地回答它的的情形、危害、以及多种处理方式,内容还是蛮多的)(面试官:行,都差不多,但是你Map和Reduce就但不知道干了什么······)
5.Spark了解哪些?Spark任务提交模式有几种?(自己没有动手执行过,八股上也没留意,答不上来)
6.Spark并行度的概念了解吗?(这个我其实是知道,但是没法对号入座,也没说出个所以然,还是不扎实)(其实就是和Executor以及CPU核心数Core相关,默认情况下每个Executor分配一个CPU核,并行度就是1;如果有10个CPU核,2个Executor,那么并行度就是5)
7.上面的没答上来,然后面试官让我会啥说啥,我说(背)了个Spark的执行流程,背完后面试官调侃:你这是背下来的还是理解的(笑着说),我说有理解,但是背的成分多一些·······“你这个(Spark执行流程)说的倒也基本对,但你刚刚说到并行度的时候就不知道怎么说了,其实就是你不知道并行度和Schedule以及Task它具体怎样去执行的,最后要把任务放到Executor里面去,那你知道Task跟什么是对应的吗?是谁去执行它?Executor里面有多个核(Core),其实是Core,是CPU单元去执行任务(面试官自问自答)”然后面试官在这里给我解释了下并行度,“但是你刚才不太清楚,可是又能把执行流程说出来,所以我觉得你是背的,不是理解的”。
8.那Spark的语言编程了解多少?比如说Spark SQL,会用Scala写Spark SQL吗?就是Spark SQL用Scala的形式去写,这种可以一步一步去调试,如果我们写SQL,它是一个大语句,但是如果用Scala去写(后面他解释了一堆,总结来说就是通过在Scala中的链式编程细粒度的去调控整个SQL)
9.UDF和UDTF这两个有什么区别?(简历上有写,连着UDAF一起答了,但是只是粗略的知道UDF是一进一出,UDAF类似于聚集函数是多进一出(类似于count、max函数,多行转一行),UDTF是一进多出,但是详细问起来UDTF的一进多出是某一列可以拆开,拆成多行还是怎么,就不懂了)
数据结构:
1.之间说到了二叉树的遍历,那对于深度优先遍历和广度优先遍历,假如说用编程方式去实现的话,怎样去实现?(他这个问题吧,当时觉得有点问题,一棵树,干嘛要用图的遍历方式去说,虽说前序遍历和后序遍历也就是深搜,层次遍历对应广搜,但就很绕;层次遍历对应的广搜使用队列实现,这个我很熟:根节点入队,根节点出队,出队时让他的左右子节点入队,然后左子节点出队,再让左子节点的左右子树入队······,最终层次遍历的顺序为出队的顺序(出入队的顺序是一样的);深度优先遍历的话,当时没搞清是打印入栈顺序还是出栈顺序,现借用代码随想录里面的图来理解:
前序遍历:
初始状态根节点先入栈,由于前序遍历是根左右,而栈是先进后出,所以让一个节点出栈时,应该让其右子节点先入栈,然后左子节点入栈,然后打印顺序为出栈顺序。附迭代法代码:(重点在while循环里)
class Solution { public List<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); if(root == null) return list; stack.push(root); while(!stack.empty()) { root = stack.pop(); // root即当前node list.add(root.val); if(root.right != null) stack.push(root.right); if(root.left != null) stack.push(root.left); } return list; } }
后序遍历:我们可以沿用前序遍历的思路,遍历出“根右左”这样的顺序,然后反转下即可,“根左右”和“根右左”的区别无非是一个节点出栈时,让他的左子节点先入栈还是右子节点先入栈(初始状态根节点先入栈,由于遍历次序是根右左,而栈是先进后出,所以让一个节点出栈时,应该让其左子节点先入栈,然后右子节点入栈,然后打印顺序为出栈顺序)。附迭代法代码:(重点在while循环里)
class Solution { public List<Integer> postorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); if(root != null) stack.push(root); while(!stack.empty()) { root = stack.pop(); // root即当前node list.add(root.val); if(root.left != null) stack.push(root.left); if(root.right != null) stack.push(root.right); } Collections.reverse(list); return list; } }
中序遍历:(这个就既不是深搜也不是广搜了)中序遍历我总结了个口诀:root不为空,压栈、指左;root为空,弹栈、添加、指右。解释:当前节点不为空,将当前节点压栈,指针指向当前节点的左节点;若当前节点为空,弹出栈顶元素,添加到输出序列,指针指向栈顶元素的右子节点。结合动图来理解:
附迭代法代码:(重点在while循环里)
class Solution { public List<Integer> inorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if(root == null) return list; Deque<TreeNode> stack = new ArrayDeque<>(); while(stack.size() > 0 || root != null) { if(root != null) { // root即当前node stack.push(root); root = root.left; } else { root = stack.pop(); list.add(root.val); root = root.right; } } return list; } }
)
机器学习:
(全是自己给自己挖的坑,当时朋友说这边可能会用到gdbt,你在简历上也可以写下你会机器学习的东西,然后我就在网上找,一顿乱抄,最后搬起石头砸了自己的脚,文末附投递时的简历)
1.见你写了机器学习、决策树、逻辑回归什么的,你说说逻辑回归是线性模型还是非线性模型呢?(线性)那线性模型的优势和劣势是什么?那决策树是线性模型还是非线性模型?(非线性)那非线性模型的优缺点又是什么?
Python:
1.深拷贝和浅拷贝了解吗?(我主要学的还是Java,Java中也有这一概念,况且两者都是面向对象语言,所以我就答的Java里深拷贝与浅拷贝的概念)
算法题:
1.反转链表(不要求实现,写为代码就可以,主要体现逻辑)(真高频啊,一共面了两次,考了我两次反转链表,虽然是很简单很基础的题目,但是可考察的点还是很多的,远不止力扣上的核心代码模式。起码链表节点定义你得熟稔于心吧,再者能不能用递归和迭代分别实现,能不能自己编写输入输出测试用例来进行验证,详情可以看我上一篇帖子关于反转链表的考察腾讯WXG后端一面凉经)
2.爬楼梯(没错,是最基础的爬楼梯,直接默写)
SQL题:
1.sql考察,两张表
tb_student字段:student_id,student_name,score
tb_class字段:class_id,student_id
输出:每个班级top3的学生分数,字段:class_id,student_name,score
(很基础,考察的是:group by分组、join on表连接以及rank、dense_rank、row_number排序函数)
select class_id,student_name,score from ( select *, rank() over( partition by class_id order by score desc ) ranking from tb_class join tb_student using(student_id) ) t where ranking <= 3;
2.两个班级
tb_classA: student_name,score
tb_classB: student_name,score
(1)找出两个班里,姓名相同的学生,并输出考试分数
(2)找出A班里,排除B班姓名相同的学生,并输出排除后剩下的学生姓名以及考试分数
select a.student_name, a.score score_classA, b.score score_classB from tb_classA a join tb_classB b on a.student_name = b.student_name;
select a.student_name, a.score from tb_classA a left join tb_classB b on a.student_name = b.student_name where b.student_name is null;
(第一道写的还凑合,第二道就有点磕巴,之前把牛课上某东商城的SQL题,中等、较难都刷了又刷,感觉挺熟练的了,但面试官让我用他的编辑器(其实就是共享记事本),因为看不到每次的输出,这就给我调试代码带来很大的困扰,有时候明明都写对了,但是因为想不通,又会把结果改错掉。因为之前做训练都是根据每次输出去调整结果的,突然让在记事本上写,有点猝不及防,就那个名字相同就把我搞晕了,我都不知道最后是一个怎样的输出状态,那a和b都名字相同了,还怎么区分呢,感觉怎么输出都不对。第二道where条件我写的a.student_name != b.student_name,is null是面试官给我改的,它提示我用别的方式实现,我不会,最后他直接上手了)
尾声:
面试官:“总体来说答的还可以,对数据结构这块,还是掌握一些的,对Spark也有一些了解,但不多,而且更像是背出来的,背的八股能应付得了面试,但是在实际的工作中很难灵活应对。因为我们进来以后肯定是有很多数据处理的工作,不管是写SQL也好,还是写scala也好,当然这个也不是很难,也很容易学。但是你要对编程有一些系统性地理解,需要有一定的项目承压能力。········还要加强一些Hive、Spark它的执行过程,有什么区别”
一面过了,和我约了下周的二面,还得再好好准备,一些基本的问题像Map、Reduce阶段分别做了什么,Hive、Spark执行流程等不能单单只背八股,还是需要有一定深入的理解。
总结:
1.简历上写的一定要熟练掌握!!!不会的千万别写,写上就把它彻底搞懂,哪怕少写几条,哪怕写的很具体,面试官在这期间调侃了我好多次“你这个写的熟练,一问,感觉你又不太掌握”,这就很尴尬
2.一些起码的知识不能只背八股,一定查阅资料要熟练掌握,就比如说大数据这些框架分别是做什么的,执行流程是如何的。
3.平时练习算法题目和SQL时要脱离这些智能的编辑器去写,而且要综合考虑输入输出。
八股链接:
附面试时简历:
项目因为是Java项目(黑马苍穹外卖),面试官直接略过了就不贴了,想看的朋友可以点这里腾讯WXG后端一面凉经。
#我的实习求职记录##悬赏#