资深面试官眼中的SQL面试

随着世界上的数据越来越多,对于处理数据的需求也日益增加,越来越多的岗位对于SQL有了更多的要求,以至于很多面向数据的岗位都会在面试中对SQL进行考察。SQL的面试可能会让很多未曾接触过编程的人望而却步,而我希望通过这篇文章能够让更多的求职者了解SQL的面试和一些基本的思路。

我在工业界工作多年,一直从事数据库和SQL相关开发工作,想作为相关领域的从业者和面试官来聊一聊我对SQL面试和学习的一些看法和思考,下面会先以一道面试真题来介绍SQL的面试,之后会回答7个常见的SQL问题

1. SQL面试真题解析

[Social Network] A user(user_id) could write a comment(content_id, type) to a post(target_id) or post(content_id, type) by him/herself. Table schema is shown as below.
date user_id content_id content_type (comment/post) target_id
Q: What is the comment distribution?

这是一道很典型的SQL面试题目,从这道题出发我们可以总结出很多做题的思路和技巧。

  • 首先我们要去理解题目的context。当你对题目所讨论的题目背景不是很熟悉的时候,要多跟面试官讨论。这道题目的背景是social network,用户会post或者对post进行comment,网站记录下来用户的action存入数据库。

  • 在此之后我们要了解所提供的table(s)。这里我们只有一个table,但多个table的情况也不少见,这个时候需要注意各个table之间的关系(primary key/foreign key)。在此之后我们可以开始观察每个table里面的columns有什么(甚至需要你知道每个column的data type),很多时候面试官不会给你具体数据,只会给你提供table schema,就像这道题目一样,这个时候你可以自己添上一些数据作为example,但是一定要仔细思考corner case,即使面试官给你具体数据了,也不要被限制住,很多时候面试官就是想去考察你在写SQL的时候能否把corner case考虑周全。 
  • 这道题目只有一个table,table schema也比较直接简单,里面是date: 日期,user_id: 用户的id,content_id: 该用户所发内容的id,content_type: 内容的type,这里是post或者comment,target_id: 如果内容的type是comment,那target_id就是被评论的post,如果type是post,那target_id就是NULL。根据这些信息,在不看问题的情况下,需要注意的可能有以下几点: 关于date的操作,对NULL的处理,一个user可能会对某个post进行多次comment(might be duplicates)。这些都是我在看到这个table的时候一些直觉反应,具体会不会有帮助,我们需要继续去看题目。

  • 读懂并正确理解问题。一定要正确理解题意,当你不是很确定的时候,一定要跟面试官确认,有时候题目稍微模糊一点,可能你的理解和面试官想要的就天差地别了。
  • 这道题是问comment distribution,就是一个相对模糊的题目了,用中文翻译一下就是评论的分布,但其实它想问的是评论数量的分布,每个post都会有一些评论,题目希望能够把每个post的评论数量统计一下,然后看一下每个评论数量的post都有多少个,例如0条评论的post数量是10个,1条评论的post数量是5个。

  • 正确的书写SQL。当你正确理解题目之后,大部分情况下你已经知道这个SQL该如何写了,可以先把框架搭出来,再一点点的去填充,请记住一定不要出现低级错误,一个是因为很容易被发现,另外也很致命。
  • 我们这道题已经知道需要一个subquery先group by和count()来得到每一个post的comment的数量,之后再group by和count()上面得到的数量就得到了comment distribution。

  • Follow-up questions。现在这个题目还是相对简化的,有的时候面试官会针对这个题目进行一些follow-up,有可能是SQL的延展,也有可能是针对别的知识点的考察。例如:content type拓展,增加like, etc; 题目上面加一些变化,如comment distribution per day; comment distribution会是一个什么distribution(统计相关),以及为什么。

2. SQL面试和学习的常见问题

Q1: 什么样的职位会在面试中遇到SQL题目?
  • Short answer: 几乎所有面向数据的职位
  • Long answer: 面向数据的岗位大致有以下几个:business analyst, data analyst, data scientist, data engineer, machine learning engineer。machine learning engineer会考到SQL的概率比较低,但其他的岗位都很有可能会考察SQL,不同的岗位对于SQL掌握程度的要求也会有所不同,甚至涉及的方面也会有一些差异,具体情况需要根据特定公司和岗位的job description再去进一步的分析。例如data analyst的SQL面试可能需要你写出一些SQL query就好了,但是data engineer可能需要你对数据库,table schema design也有所涉足。
Q2: SQL的面试考察的内容有哪些?

SQL的面试内容大致分为以下几种:

  • 数据库和SQL的基础知识的问答,例如什么是left join,什么是关系型数据库。
  • 提供数据信息(table), 给你一些问题,让你写出一些SQL query,基本以select query为主,很少会去考察你create table这些。这种考察是最为常见的。
  • 最后一种我称为SQL case study,基于一个case和面试官交流,可能会经历数据部分的头脑风暴,table schema design,以及根据面试官的一些要求写出一些query。这类考察在很多大公司渐渐推广开来。
Q3: 面试中的SQL和工作的SQL有什么区别?
  • 面试中的具体场景的context不是很强,更多的是考察你的基本功,或者说做题能力,不会有特别复杂的query让你去写。
  • 工作中你可能面对更为庞大的数据,更复杂的schema,例如10+个table的join,和更为严格的要求,例如performance的要求,你的query必须要在多少秒之内返回结果。
  • 总结一下,面试中的SQL更侧重你能不能把一个query简洁,快速,bug-free的写出来,而工作中更多的是需要你写出一个能解决问题的query,query要能快速正确的返回结果,同时需要一定的readability。
Q4: 如何开始学习SQL?
  • 首先,你需要明确你学习SQL的目的,你是希望在工作中有更大的impact,还是你之后的面试会考察SQL,这样你才能更有效率的去学习。
  • 如果工作中能够接触到一些面向数据的工具,如Spark, Snowflake,那最好的方式就是learn by doing,甚至可以去看别人怎么使用这些工具,去读别人的代码。其实这就跟学一门外语一样,如果把你放到那个环境中,你自然会成长的更快。当然你也要去学习基本的知识,与此同时,具体生产环境中的案例能帮助你更好的去理解和学习。
  • 如果没有这种环境,那我们就需要一些课堂式的学习,例如上课看视频读书,从SQL的基本语法到一些高级用法,一个一个知识点的来学习。辅助以一些练习,例如Leetcode, hackerrank上面的题目。
  • SQL的入门不是很难,甚至可以说是相对简单,这也让SQL成为了一个非常popular的语言。但是想要深入学习SQL也不是一件容易的事情,你需要学习更多计算机知识,了解更多的算法细节,对公司的商务逻辑也要有清晰的认识。
Q5: 市面上面很多SQL,应该选哪个开始学?
  • 首先,如果你知道公司在用的数据库,直接学那个就好了。
  • 其次,科技公司最常使用的是MySQL和PostgreSQL,但是MySQL给你提供了很多语法糖,有的时候可能会违背一些你学习的基本知识,有的时候会比较困惑。如果是第一门语言入门的话,我比较推荐PostgreSQL。但是如果你想去面试一些传统行业的公司,很有可能他们有一套Microsoft stack,所以SQL Server应该是你的首选。
  • 最后,其实精通一个SQL就好,基本语法都差不多,可能在处理timestamp和null value的时候会有一些区别,除此之外,更多的区别基本上是感受不到的。而且你精通了一门以后,即使有区别,你也会很快的catch up,都是殊途同归的。
Q6: 需要掌握哪些SQL知识?

[基础]

  • Basic syntax: SELECT, FROM, WHERE, HAVING, GROUP BY, ORDER BY, etc.
  • Aggregation: SUM(), MAX(), MIN(), AVG(), etc.
  • JOIN: Inner/Left/Right/Outer/Cross
  • Subquery, CTE
  • Query Execution Order

[进阶]

  • Window Function
  • CASE WHEN
  • NULL value
  • TIMESTAMP

上面的这些内容基本上涵盖了面试中95%的知识点,当然还有很多其他内容在这面没有提及,例如query plan,query optimization,database schema design,primary/foreign key, etc.

Q7: 如何在SQL和职业上进阶?
  • 有的时候我们会听到这么个词,叫做SQL boy,有些人会解读成为写SQL的流水线工人,写着写着SQL就只写SQL了,每天就是跑跑写好的SQL,看看结果,report一下,职业发展看不到什么希望,这其实是很多从业者的担忧和困惑。在我看来,SQL boy也不是那么好当的,我们很多时候对于SQL query的要求很高,如果你写的query质量不达标,十分影响整个团队的工作进程,所以如果你觉得没有希望了,可能不是SQL boy的问题,更多的是你需要换公司或者team了。
  • 关于职业的进阶,除了能把SQL写好以外,你更需要考虑的是个人的职业规划,你希望未来向什么方向发展,是更偏product和bussiness,还是去做data scientist,还是说在数据和SQL处理这部分更进一步去做data engineer,这个可能是更重要的事情,因为你除了SQL还需要学习更多其他的技能才能让你走的更远。