登录
首页大数据时代如何回答数据科学编码面试问题
如何回答数据科学编码面试问题
2022-02-18
收藏


你应该如何回答数据科学编码面试问题,这是没有秘诀的。没有一种方法总是有效的。但是,在大多数情况下,有一些指导原则将帮助您更好地回答编码问题。

这些指导方针是根据参加面试和回答编码问题的经验形成的。我们将这些指导方针分为四个部分。您可以使用这些指南作为核对表,特别是如果您没有数据科学编码面试问题的经验。以后,你当然可以找到自己的方法,也许忽略一些要点,甚至包括一些对你更有效的方法。

但是不管你的经验如何,如果你遵循这个清单,你就会增加你对编码问题给出一个好答案的机会。

由四部分组成的核对表

  1. 问题分析
  2. 解决办法
  3. 编写代码
  4. 检查您的代码

现在您已经有了检查表大纲,我们将研究每一节,并解释其中包含的检查表要点。

1.问题分析


清单中的问题分析部分是花几分钟彻底思考你刚刚得到的问题。就像您在处理实际业务问题时会看到的那样,最好先考虑问题,然后“浪费”一些时间从各个角度来看问题。记住,思考永远不是浪费时间!

这几分钟以后会有回报的。如果您立即开始编写解决方案,那么一旦您意识到您的方法并不能产生所需的解决方案,就很有可能不得不从头开始。或者您必须不断地更改和重写代码。

帮助你练习思考问题的要点是:

  1. 理解问题
  2. 分析正在使用的表和数据
  3. 考虑代码结果

i。理解问题

为了确保你理解这个问题,你必须非常仔细地阅读这个问题。慢慢读。并且读2-3遍以确保你没有遗漏任何东西。这适用于所有数据科学面试问题,无论它们有多容易或多难。关键是,你不会知道你得到的问题是难还是容易。有些问题可能看起来很简单,但它们有一些陷阱,这正是为了消除那些不够彻底和倾向于肤浅的考生。

如果问题没有写出来,也可以让面试官重复一遍,如果你没有听懂的话。在这种情况下,一旦你理解了这个问题,最好把它重复给面试官。这样,你就可以确保你写得很好,并允许面试官在没有给你所有必要信息的情况下纠正自己。

ii。分析正在使用的表和数据

一旦您理解了这个问题,下一个合乎逻辑的步骤就是分析给出的表。这意味着您需要分析有多少表以及它们之间的连接方式(外键和主键)。

您还希望查看这些表中的数据。表示每个表中有哪些列。每列中的数据类型。这很重要,因为您的代码将取决于您处理的是字符串数据、整数、货币还是任何其他类型的数据。也许您甚至需要将一种数据类型转换为另一种数据类型以获得所需的结果。

除了数据类型之外,理解数据的组织、排序和粒度也很重要。意思是,表中是否有重复的值?数据是否按客户级别、事务级别等表示?

iii。考虑代码结果

在开始编码之前,您应该知道您希望得到的结果是什么样子。当然,这也取决于你想要回答的问题。

但想想结果文学意味着,会不会是一行只有一个值,还是一个有几列的表。如果是一个表,那么您还必须考虑如何对数据进行聚合和排序,必须显示多少列,等等。


问题分析-示例

为了向您展示如何应用检查列表的第一部分,我们将使用Dropbox编码问题。问题是这样的:


“写一个查询,计算市场营销部门和工程部门最高工资之间的差异。产出只是工资的差异。“


如果你仔细阅读这个问题,你就会意识到你必须找到最高的薪水。好的,但不是每个部门的最高工资,而是两个部门的最高工资:市场营销和工程。一旦你发现这两个部门的工资最高,你就需要计算出两者之间的差异。

既然您理解了问题,您就可以分析其中的表和数据了。您将使用的表是db_employee和db_dept。表db_employee包含有关公司员工的数据。它有五列:

id int
first_name varchar
last_name varchar
salary int
department_id int

您可以看到,name列是varchar数据类型,而salary是一个整数。知道工资值中没有小数可能很重要。如果使用此处的预览选项,您将看到此数据是唯一的:每个员工只有一个薪资值分配给他们。还有,一件重要的事情要知道;它也可以是历史数据,在那里你会有每个员工过去几年的所有工资。有一个列department_id,它是一个外键,将该表与表db_dept链接起来:

id int
department varchar

此表中只有两列。这只是一个部门的列表,没有重复,表中显示了六个部门。

很好,你已经分析了数据。现在,回到问题,读第二句。是的,这是关于你的解决方案需要是什么的说明。您不需要在一栏中显示一个部门的最高工资,然后在第二栏中显示另一个部门的最高工资,然后在第三栏中显示两者之间的差异。不,输出将只差:


没有关于该输出列应命名的说明。所以不管你给它起什么名字,或者你根本不给它起名字,都不会出错。重要的是你得到了这个结果,别无他法。

这样,您就有了编写高质量代码的基础。现在是关于策略的时候了:你将如何编写代码?

2.解决办法


在开始编写代码之前,对代码的外观有一个清晰的概念也很重要。编码应该只翻译你的(清除!)编程语言的解决方案。

当您考虑如何处理您的解决方案(或编写代码)时,请考虑以下事项:


  1. 有几种写代码的方法吗?
  2. 陈述你的假设
  3. 将解决方案分解为步骤
  4. 开始编码

i。有几种编写代码的方法吗?

在思考解决方案时,首先想到的有时是最好的解决方案。但有时并非如此。你怎么会知道?一旦你有了第一个想法,诀窍就是考虑是否有其他方法解决这个问题。编程语言,更多的时候,有几种可能的解决方案。

记住这一点。这很重要有几个原因。首先,可能有一些简单的技巧或函数可以轻松地解决您认为需要用冗长代码才能解决的问题--例如,使用Window functionsor CTEs,而不是编写带有无尽子查询的代码。

Always go with what’s easier to write, with as few lines of code as possible. When you’re at the interview, you also have to manage time at your disposal. This is one of the ways.
当然,如果有几个或多或少同样复杂的解决方案,请考虑代码将如何执行。对于大量数据,不同的代码执行起来可能比其他代码占用更多的时间和内存。

简而言之,您应该从两个方面考虑代码效率。一个是个人效率,或者说你写代码的速度有多快。第二个是代码效率,或者代码执行所需内容的速度有多快。

ii。陈述您的假设

陈述你的假设很重要,有几个原因。第一个是大声说出来并写出来,这将帮助你看到你的方法的潜在问题。

第二个重要的原因是它邀请你的面试官与你交流,甚至提供一些帮助,他们通常会这样做。如果他们不知道你想做什么和为什么,他们就帮不了你。正如我们已经提到的,通常有几个解返回相同的结果。传达你的假设可以让面试官根据你选择的方法引导你朝着正确的方向前进。或者甚至引导你远离完全错误的假设,这些假设会使你的解决方案一团糟。

第三个原因是,有时这个问题可能被故意设置得含糊其辞。这些问题不是与正确的解决方案有关,而是与你如何思考有关。因此,如果你陈述你的假设,这将向面试官展示你的想法,他们通常对此非常感兴趣。

陈述假设的第四个也是最后一个原因是,即使你得到了完全错误的答案,但在你陈述的假设中是正确的,你仍然有可能得到一些分数。在这种情况下,我们的思路是这样的:好吧,也许候选人完全误解了所问的问题,但在他们理解的背景下,解决方案实际上是正确的。

这一切都导致tomaking一定会对面试问题给出正确的答案。

iii。将解决方案分解为步骤

这也是很有帮助的一点,它将使您更容易有一个明确的解决方案想法,并在以后编写一个干净的代码。

在这种情况下,分解意味着写下来。是的,写下你的解决方案的所有关键步骤和功能。考虑是否应该联接表、有多少表以及将使用哪些联接。您应该编写子查询还是CTE?写下你的选择。考虑必须使用哪些聚合函数,是否必须转换数据类型,是否应该以特定的方式对数据进行排序,是否应该对其进行筛选和分组,等等。

所有这些都是不同的步骤,所以把它们写下来,以及在每一步中使用的主要关键字。

iv。开始编码

在某种程度上,这是一个紧急点。如果您确实考虑了解决方案的方法,但您根本看不到完整的解决方案,那么您应该简单地开始编写代码。

这背后的想法是,即使您给出了一个不完整的解决方案,它肯定比不编写一行代码更有价值。此外,有些问题可能真的很难,即使是最有经验的人也很难立即看到整个解决方案。开始编写代码,你有机会在这个过程中想出一个主意。如果没有,再说一遍,你至少有东西可以展示。

你应该记住的另一个原因是:有些问题甚至不打算被回答。其中有些是简单的(而且是故意的!)太难了,在面试的时间里解决不了。没有人能完全解决问题。局部解决方案是任何人都能得到的最好方案。因此,你会被标记出与其他不完全解相比,你走了多远。


解决方案的方法-示例

既然你知道了你应该如何思考你的解决方案,让我们用一个面试问题来演示它在实践中是如何工作的。我们将使用Amazon编码面试问题:


“查找每个客户订单的总成本。输出客户的id、名字和订单总成本。按客户名字字母顺序排列的订单记录。“


在这个问题中,我们必须使用来自两个表的数据:表customers和表orders。我们可以编写一个带有子查询的代码来克服这个问题。但是,您可能知道,如果查询和子查询使用来自多个表的数据,那么也可以使用联接编写解决方案。记住了编写尽可能少的代码行的建议,最好使用join。

这个解决方案的假设是什么?一种假设是,可能有客户没有订单。这意味着表customers中的客户可能不会出现在表Orders中。第二个假设是,我们不会显示零订单的客户,因为问题没有明确地说。

现在,这已经导致我们解决方案崩溃。我们必须输出两个已经存在的列,所以我们一定要使用SELECT。我们需要找到每个客户订单的总数。我们必须使用sum()聚合函数对其求和。好的,桌子必须连接起来。我们将使用JOIN关键字来实现这一点。为什么不让其他人加入呢?因为我们的假设是,我们只想要至少有一个订单的客户。使用JOIN将给我们提供这样的结果:它将连接两个表,并且只查找两个表中的值(客户)。接下来呢?我已经使用了聚合函数,所以我必须使用GROUP by。结果必须按字母顺序排列,所以我将使用ORDER BY和ASC。

由此产生的解决方案分解可能如下所示:

  • 选择
  • 总和(total_order_coste)
  • 加入
  • 按分组
  • ASC命令

在您的情况下,这并不是紧急情况,因为您理解了所有内容,所以您可以进入下一个检查列表部分,或者您也可以在这里找到最多的commonSQL JOIN面试问题。

3.编写代码


在评估了问题并为代码制定了策略之后,是时候开始编写它了。


  1. 坚持一种选定的方言
  2. 编码时逐行进行
  3. 边编码边说话
  4. 使其具有可读性
  5. 与选定的惯例一致

i。坚持所选方言

如果您参加SQL编码面试,这一点尤其重要。正如您已经知道的,有一个ANSI/ISO SQL标准,并且有许多SQL方言。实际上,每个RDBMS都使用自己的SQL方言。当然,你不可能都知道。你面试的公司可能使用的是其中一种方言。

如果面试官不在乎你使用哪种方言,那就选择你最喜欢的一种。如果你不是很擅长用SQL方言编码,不要试图通过选择他们使用的SQL方言来吸引面试官。最好选择你最熟悉的方言来解决问题,而不是使用其他一些你不太确定的方言。如果你选择后一种,你可能会比必要的更紧张。此外,不熟悉特定的SQL方言可能会使您搞砸解决方案。

一旦选择了SQL方言,请坚持使用。例如,如果您选择用PostgreSQL编写,不要将其与T-SQL混在一起。

ii。逐行进行

有一个明确的解决方案分解将帮助您检查这一点几乎没有注意到。由于您已经概述了代码的功能和部分,您只需要保持冷静,按照解决方案大纲系统地编写代码。代码只不过是你思想的编程语言版本。如果你的想法和你的解决方案大纲是清晰的,你的代码也将是清晰的。

如果你开始从一行跳到另一行,你会让自己和面试官感到困惑。这可能会导致不能编写正确的代码。

iii。边编码边说话

当您一行一行地编写代码时,您还应该谈论您正在做什么。这很重要,因为当大声说出你在做什么时,你更容易看出你是否做错了什么。一切在你的脑海里听起来都很棒。但是当你大声说出来的时候,那些不太好的想法真的很突出!这使您有机会在执行过程中更正代码。否则,您可以完成代码,甚至没有意识到您做错了什么。

为什么在你写的时候解释每一行都很重要,原因之一是它再次邀请面试官参与你的解决方案。这让他们有可能理解你在做什么,并给你一些提示。如果你只是写了一个代码,并对自己在做什么保持沉默,面试官也可能会停下来,只是等你完成代码,让你知道你做得如何。

iv。使其具有可读性

简单地从美学的角度来看,拥有一个结构良好的代码是一种乐趣。不仅如此,它还使您和面试官更容易阅读您的代码。

使您的代码具有可读性的主要因素在上面的一个要点中提到:尽可能简单地编写代码。然而,有些解决方案不能简单。如果您不努力使其具有可读性,那么即使是几行代码读起来也可能是一场噩梦。

要记住的一个技巧是使用空格、制表符和Enter。并且经常使用它!这些键可以将代码分成几个部分,从而更容易理解代码的功能。把它想象成你说的或写的任何东西。空格、制表符和enter将使代码具有逗号、句子和段落。

如果可能,请为表使用别名。但试着让它们变得不言自明。避免使用单个字母的别名,但也不要使别名过于冗长和描述性。变量名也是如此。

虽然SQL不区分大小写,但最好用大写来编写SQL关键字。这也会使它们在代码中突出,特别是如果所有列和表名都是小写的。

查看我们的文章“编写SQL查询的最佳实践:如何构造您的代码”,它关注如何改进SQL查询,特别是在性能和可读性方面。

V。与选定的约定保持一致

没有规则让你写大小写;没有规定的命名惯例,所以它取决于你和你喜欢它。但无论你做什么,都要与之保持一致。

如果你想用小写来写所有的新列名,并用下划线分隔单词,请这样做并保持这种方式。将列命名为salary_per_employee看起来相当不错。但是尽量避免将一个列命名为salary_per_employee,另一个列命名为SalaryPerDepartment,第三个列命名为“total salary”,第四个列命名为max_salaryperdeparment。当你试图阅读代码时,你会伤害自己,尤其是最后一个代码。

在编写表名、使用别名等时也是如此。保持一致性也会增加代码的可读性。

谈到一致性,我们将向您展示此核对表部分在实践中是如何工作的。


编写代码示例

以下是脸书的一个编码问题:


“当用户试图2FA(2因子身份验证)进入平台登录时,脸书会发送短信。为了成功2FA,他们必须确认他们收到了SMS短信。确认文本仅在发送日期有效。不幸的是,数据库中存在一个ETL问题,其中朋友请求和无效的确认记录被插入到日志中,这些日志存储在'FB_SMS_SENTS'表中。这些消息类型不应在表中。幸运的是,'fb_confirmers'表包含有效的确认记录,因此您可以使用该表来识别用户确认的SMS文本消息。

计算2020年8月4日确认短信短信的百分比。“

如果您编写这样的代码,它将涵盖我们在本检查列表一节中提到的所有内容:

SELECT  cust_id,
        SUM(total_order_cost) AS revenue
FROM orders
WHERE EXTRACT('MONTH'
              FROM order_date :: TIMESTAMP) = 3
       AND
       EXTRACT('YEAR'
              FROM order_date :: TIMESTAMP) = 2019
GROUP BY cust_id
ORDER BY revenue DESC

让我们假设Facebook使用SQL Server,但它让您自己决定用哪种SQL方言编写代码。您不熟悉T-SQL,因此决定使用PostgreSQL编写。

例如,EXTRACT()和双冒号(::)是PostgreSQL的典型函数。第一个从datetime数据类型中提取日期的部分。它不存在于T-SQL中!所以如果你对面试官说你是用T-SQL写的,然后使用这个函数,你就犯了一个错误。在T-SQL中,应该使用DATEPART()函数。您应该知道PostgreSQL中的这个函数称为DATE_PART()。一个下划线可能意味着代码工作和不工作之间的差异。

类似地,PostgreSQL中的双冒号(::)用于数据类型转换。在T-SQL中,它不起作用;您必须使用CAST()或CONVERT()。

对于这段代码有一个解决方案分解将使您很容易一行一行地编写它。其实很容易。首先,您必须从表中选择一些数据,对其进行筛选、分组,最后对其进行排序。不要先编写WHERE子句,然后转到SELECT语句,然后转到数据类型转换或任何其他处理代码的奇怪方式。

在编写代码时,可以像这样与面试官交谈:我使用SUM()函数选择cust_id列来计算表订单的收入。然后,我使用WHERE子句根据ORDER_DATE列中的月份和年份筛选数据。之后,我在客户级别上对数据进行分组,并按降序对结果进行排序。

您可以看到这段代码有缩进,代码的每个关键部分都有一个新行,并且命名约定是一致的。你想看看如果我们不遵循这个代码会是什么样子吗?在这里:

SELECT cust_id,SUM(total_order_cost) AS REVENUE FROM ORDERS WHERE EXTRACT('MONTH' FROM order_date :: TIMESTAMP) = 3 AND EXTRACT('YEAR' FROM order_date :: TIMESTAMP) = 2019
GROUP BY cust_id order BY Revenue DESC


4.检查代码


编写完代码后,是时候在它成为最终答案之前对它进行审查了。如果到目前为止您已经遵循了清单上的所有项目,那么您将很容易检查它。

在某种程度上,检查代码就是对照清单上的一些要点检查代码:

  1. 检查一下你还剩多少时间
  2. 对照所需的输出进行检查
  3. 对照所述假设进行核对
  4. 检查其可读性
  5. 带领面试官通过解决方案
  6. 优化代码

i。检查您还剩多少时间

核对表这一部分的所有其他要点都依赖于这一点。如果你没有时间了,那么你什么都做不了。你做了你所做的,你的代码就是你得到的答案,不管你喜欢与否。

时间管理很重要,所以您应该有意识地为检查代码留出一些时间。理想情况下,您将有时间执行以下三个检查。

ii。对照所需的输出检查代码

您应该回到您的问题,看看您的代码是否真的返回所需的内容。你是不是忘了包括一些必需的列?你真的按要求订购了结果吗?这些和其他类似的问题是你应该问自己的。

如果你有时间,改正你所犯的错误。如果没有时间,保持代码原样,但写下你做错了什么。

iii。根据声明的假设检查代码

您基于一些假设编写了代码。回到你的假设列表,检查你是否遵循了它们。

如果你这么做就太完美了。但是在编写更复杂的代码时,您可能会放弃一些假设或引入新的假设。也写下来。如果您没有遵循所有的假设,但您认为您应该遵循,并且您有时间更改代码,那么就这样做。如果没有,就保持原样。

iv。检查代码可读性

在这里你应该检查一下你是否理解你刚刚写的东西。回到您的代码,再次检查每一行的语法和逻辑。在逐行执行时,评估代码可读性是否可以提高。您在命名约定上是否一致?你的别名清楚吗?有什么歧义吗?代码是否以逻辑的方式构造并分成逻辑的部分?

同样,如果有时间,提高代码的可读性。如果没有时间,试着写下来,或者简单地记住你本可以做得更好的事情。

V。引导面试官完成解决方案

如果你做了上面所有的步骤,这一个应该会很自然地对你来说。最重要的是,当你解释你的代码时,你是诚实的。

无论您在检查代码时发现了什么错误,都要显式地声明它们。不要指望你的面试官不会注意到他们。别想把他们藏起来。承认你的错误,并表明你知道自己做错了什么。每个人都会犯错,但不是每个人都能意识到自己犯了错并承认错误。它表明即使你犯了错误,你也知道自己在做什么。说到错误,以下是人们在数据科学采访中最常见的错误。

如果您在输出中包含了一个不必要的列,请这样说,并继续解释您的输出。你偏离了你最初的假设还是加入了新的假设?这么说并解释原因。如果你做错了,说这不是故意的,但你看到你的解决方案应该包括一些额外的假设。说明它们应该是什么,以便您的代码工作。可读性也是如此:如果您认为可以使代码更好,请解释如何使代码更好。

通过完成所有这些,您不仅可以显示您的编码能力,还可以显示您的思考速度,您的责任感和诚实性。这些都是所有公司都非常重视的特点。

vi。优化代码

编码面试中的最后一个问题通常是要求您优化代码的问题。这样,面试官将测试你的SQL理论知识。例如,如果您知道联接可能在计算上耗时?您将被要求找出是否有消除联接或子查询的方法。例如,如果试图找到最大值,通常可以使用某个函数(如排序函数)删除WHERE子句中的子查询。

或者如果您知道对某些数据类型执行操作的速度有多快。例如,字符串比较比整数比较慢,那么也许有一种方法可以在字符串数据上做到这一点?

结论


所有这些都总结到:如果你能很好地构建你的方法,编写代码几乎应该是一个技术性的问题。重点是更多地思考,而不是编码。编写代码应该以非常有条理的方式进行。

你应该仔细考虑问题、你面前的数据、可能的解决方案、你的假设和你需要的功能。只有在那之后,你才应该开始编码。一旦你开始编写代码,你应该能够让面试官了解你正在做的事情,并让他们知道你所做的每一步。像在实际生活中一样,在开始在生产中使用代码之前,您必须检查和优化代码。这次采访是你的制作;管理好您的时间,以便能够审阅您的解决方案。

这些是你应该做的事情。在我们的帖子中还有更多的准备技巧:准备数据科学面试的5个技巧。

这一切都不容易。它需要经验和实践;没人能伪造这个。但不管你的经历如何,遵循这份清单肯定会给你的思维和面试表现增加一个坚实的结构。只能让你表现得更好。


数据分析咨询请扫描二维码

客服在线
立即咨询