2024 美國地獄模式上岸DS/MLE經驗分享(參) — 如何準備SQL, Python Coding Interview

Bert Lee // 李慕家
20 min readJun 5, 2024

--

這篇主要分享不同Data崗位在面試上會遇到什麼樣的Coding Problem以及相關的準備的方式。

本文Outline:

參、如何準備SQL、Python Coding Interview

* 一、DA, DS, MLE都會在面試中遇到什麼SQL, Python問題?
* 二、如何準備SQL面試
* 三、如何準備Pandas面試
* 四、如何準備Leetcode演算法面試
* 五、如何準備Practical Python Coding面試

一、DA, DS, MLE都會在面試中遇到什麼SQL, Python問題?

我在系列文第一篇有提到我此次求職面試過程中遇到過的各種考察面向,關於Coding的部分主要分為SQL coding和Python Coding:

  1. SQL coding: 7 (Kafene, Expedia, Meta*2, CVS, Shopify, Warner Bros)
  2. Python coding: 10 (①Leetcode: Expedia, AppLovin ②Pandas: Home Depot(Offline), CVS ③PyTorch Modeling: Walmart ④ML Implementation: Expedia ⑤OOP: Shopify ⑥Practical Coding: DataVisor*2, Warner Bros)

在這篇文章中我會一一介紹題型以及分享準備方向(③, ④會放在另一篇)。

首先無論是SQL or Python,我遇到的Coding大部分都是面試現場的Live Coding,就是面試官會透過Coderpad或類似的平台跟你即時共享一個Coding環境,也就是面試官可以即時看到你寫的Code,這種面試需要同時跟面試官溝通並寫出Code;少部分的情況會遇到Offline Assessment/Take-Home Challenge,就是發一份題目給你,限定一段時間,也許一小時或一天做完回傳。

對於美國的DA & DS來說,SQL幾乎是必考的。Python通常也會考,只是每家考Python的題型差異比較大,也許是LeetCode類的算法題,也許是Pandas,也可能是比較貼近實際工作遇到的Practical Coding題,對DS來說甚至可能會遇到OOP、Modeling題。對於MLE來說,LeetCode基本上是免不了的,Modeling/ML Implementation也是很有可能遇到的。

LeetCode生涯目前累積刷了318題
318題當中不同語言的分佈

二、如何準備SQL面試

先貼上我在2021年求職準備計畫中所分享的SQL準備方法:

我在2021年當時是快速過了一遍Mode SQL Tutorial,接著就刷當時SQL Leetcode最高頻的50題(現在的高頻題跟以前已經相當不一樣了,一些比較偏、比較難的題目頻率幾乎都下降了),對於第一次不會的題目會特別標注,多加複習。最後就是刷DS Take-Home Challenge書裡的SQL 6大題和公司面經。這次再準備基本上也是差不多的流程,只是因為過去準備和工作的經驗讓複習時間更短了。

我在準備SQL時有用Notion整理一份SQL Cheatsheet,內容包含:

  1. 基本的SQL運作原理:e.g. SQL Execution Order, SQL Data Types, Keys in SQL, How to do Data Quality Assessment in SQL…
  2. SQL重要的Functions:可能會附上簡單的examples,Leetcode題號。
  3. 常考的SQL題型和可能解法:e.g. Top N problem (https://leetcode.com/problems/second-highest-salary/solutions/1168444/Summary-Five-ways-to-solve-the-top-n-nth-problems/), Find Median (569, 571), Continuous Ranges (1285, 1225…), Pivot/Unpivot, Variations of joins with Where clause (180, 579…), CTE/Recursive CTE.

我個人是邊刷題邊Update這份Cheatsheet,有什麼不熟悉的、不會的部分就加到Cheatsheet裡附上相關的題目,建議同學在準備的時候也可以參考類似的模式為自己準備一份Cheatsheet。

這次有點不同的是,在刷面經的時候,可以借助ChatGPT將題目更完整的還原,請它設想出Schema, Sample Data, Possible Questions, and Solutions,如此以來,我們也可以在自己的SQL環境下Create Table,然後Write Query練習。

最後分享一道CVS的SQL面經題和參考答案讓沒有SQL面試經驗的同學有更具象的了解:

Let’s assume we have the following table structures:

  1. Users Table: Contains user information including user ID and gender.
    Columns: UserID, Gender
  2. Transactions Table: Contains transaction details including user ID, transaction category, paid amount, and transaction date.
    Columns: TransactionID, UserID, Category, PaidAmount, TransactionDate
  3. Location Table: Contains information about the transaction locations.
    Columns: TransactionID, LocationID, LocationName

Given these structures, let’s address the problems:

1. Top 2 Categories by Paid Amount for Each User

WITH RankedCategories AS (
SELECT
t.UserID,
t.Category,
SUM(t.PaidAmount) AS TotalPaidAmount,
RANK() OVER(PARTITION BY t.UserID ORDER BY SUM(t.PaidAmount) DESC) AS Rank
FROM
Transactions t
GROUP BY
t.UserID, t.Category
)
SELECT
UserID,
Category,
TotalPaidAmount
FROM
RankedCategories
WHERE
Rank <= 2;

2. Gender Ratio

SELECT
Gender,
COUNT(*) * 100.0 / (SELECT COUNT(*) FROM Users) AS Percentage
FROM
Users
GROUP BY
Gender;

3. Growth in Paid Amount by Category for a Region from 2018 to 2019

Let’s assume we are interested in LocationName = 'SpecificRegion' and Category = 'SpecificCategory'.

WITH YearlySums AS (
SELECT
YEAR(t.TransactionDate) AS Year,
SUM(t.PaidAmount) AS TotalPaidAmount
FROM
Transactions t
JOIN Location l ON t.TransactionID = l.TransactionID
WHERE
l.LocationName = 'SpecificRegion'
AND t.Category = 'SpecificCategory'
AND YEAR(t.TransactionDate) IN (2018, 2019)
GROUP BY
YEAR(t.TransactionDate)
)
SELECT
(SELECT TotalPaidAmount FROM YearlySums WHERE Year = 2019) -
(SELECT TotalPaidAmount FROM YearlySums WHERE Year = 2018) AS Growth

三、如何準備Pandas面試

我這次只有在CVS的面試和Home Depot的Take-Home Challenge遇到Pandas題目,針對Pandas準備的時間相當的短。

我的準備過程大致上是:

  1. 非常快速地過了一遍以前DBS發的Python講義,是郭耀仁老師編的(https://hahow.in/@tonykuoyj),同學可以找以前自己學過的Python Notes。
  2. 看了一些Pandas Cheatsheet,網上能找到很多。
  3. 複習了Medium文章:How to rewrite your SQL queries in Pandas, and more
  4. 刷了Leetcode的Introduction to Pandas
  5. 用Pandas刷了一些Leetcode高頻題。
  6. 練習了一遍YouTube上的一個Problem Set: Link
  7. 自己找一個dataset練習不熟悉的語法,比如說group by、aggregate、apply、pivot、melt、indexing相關的一系列操作。

同樣附上一題Pandas面經題分享給同學:

import pandas as pd

data = {
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Ella', 'Fiona', 'George'],
'Age': [34, 47, 28, 33, 29, 41, 38],
'City': ['New York', 'Los Angeles', 'New York', 'Los Angeles', 'Chicago', 'Chicago', 'New York'],
'Income': [100000, 120000, 70000, 90000, 80000, 95000, 110000]
}

Problem Set

  • Problem 1: Reading Data- Create a Pandas DataFrame from the data dictionary provided above.
  • Problem 2: Viewing Data
    - Display the first 3 rows of the DataFrame.
  • Problem 3: Adding a Column
    - Add a new column named ‘Age_40_or_older’ to the DataFrame. This column should contain ‘Y’ if the person’s age is 40 or older, and ’N’ otherwise.
  • Problem 4: Data Manipulation
    - Sort the DataFrame by the ‘Income’ column in descending order and display the first 5 rows.
  • Problem 5: Pivot Table
    - Create a pivot table from the DataFrame. The table should show the average income by city, with cities as rows.

Solutions

# Problem 1: 
df = pd.DataFrame(data)

# Problem 2: Viewing Data
print(df.head(3))

# Problem 3: Adding a Column
df['Age_40_or_older'] = df['Age'].apply(lambda x: 'Y' if x >= 40 else 'N')
print(df)

# Problem 4: Data Manipulation
sorted_df = df.sort_values(by='Income', ascending=False)
print(sorted_df.head())

# Problem 5: Pivot Table
pivot_table = pd.pivot_table(df, values='Income', index='City', aggfunc='mean')
print(pivot_table)

四、如何準備LeetCode Algorithms面試

看了一下才意識到這次找工作的過程只遇到了兩次LeetCode Algorithms Like的題目,但是其實在這個部分的準備時間跟其他部分比起來相對算多的了(當然跟找SDE的大神比不了⋯)。我生涯累積刷了220題Python,而這次準備期間總共刷了108題,絕大部分都是以前刷過的題。對於以DS為主要找工目標的話,我認為熟悉高頻熱門題要比累積大量題數要來得重要許多,通常DS面試考LeetCode的話還是以那些介於Easy-Medium的高頻題為主的。MLE的話每間公司要求可能不一定,有的可能只要求做出Medium,有的就完全依照大廠SDE的標準在考,比如Meta的MLE就是35分鐘兩道Medium-Hard吧。

網上有一個知名的Problem List叫做Blind 75,是網友精選的75道LeetCode題,後來同一個作者又發表的一個擴增版叫做Grind 169。可以在這個網站找到:Grind 169,這個網站可以根據你預計花幾週、每週幾個小時、偏好的排序方式來制定計畫。我這次原本計畫就是在寒假期間先刷一遍Grind 169作為初步準備,並且依照Topic排序來刷(Array, String, Matrix…),不過因為追劇的關係進度拖延,最後目標題數越減越少,因此前幾個Topic刷得比較多,後面的比較少⋯。

關於準備LeetCode Algorithms的建議,我覺得如果沒有好好學過Data Structure & Algorithms的最好還是先補一下,學過的也可以複習一下,接著第一遍刷題可以先按照Topics來刷,速度會快不少,做完題目記得紀錄下來並且簡單Mark一下做題的狀況,比如我會用:「DIY輕鬆」、「DIY不順」、「看Hint」、「看Sol😭」、「可優化」、「最優解」等Tag來標注,就跟背單字的方法差不多。另外現在有了ChatGPT,我在做完每一題都會跟它討論我的complextity以及是否有優化的空間。第一輪刷完所有Topics後,也就是進到求職中期、拿到許多面試的階段,這個時候就可以按照公司來刷題,不再依賴Topic,畢竟在面試的時候你也不知道題目是屬於什麼Topic。在這個階段可以多看面經都考了些什麼題,去刷那些題。

跟SQL一樣,對於LeetCode的Python題我也有一個Cheatsheet,基本是按照Topic來寫的。

五、如何準備Practical Python Coding面試

有些Python Live Coding面試考的既不是Pandas也不是常規的LeetCode題,可能更接近現實應用的問題,比如:function modification, data processing, data compressing;或著像是Shopify的DS特別愛考OOP、Unit Testing,算是相當不常規的。

這一類的題目可能就沒有特別高效的練習題庫,當然OOP、Unit Testing肯定都能找到很多相關的學習資源,但是那不是一般DS, DA方向的考察重點、甚至MLE方向都不一定會考,對於找DS相關工作我不認為特別準備OOP、Unit Testing是很必要的。這一類題目關鍵主要在於平時寫Python的經驗累積,對於數據結構具有基本的理解,尤其是Hash Table、Dictionary的熟悉度,最後就是多刷面經。

這裡分享Shopify的面經題的簡略改版,之後有機會再提供更多細節:

import random

class ContentRecommender:
def __init__(self):
# Initialize with an empty dictionary to hold analytical data
self.analytics = {} # For example, this might hold click-through rates or user interaction stats

def select_content(self):
"""
Determines which content (Option A, B, or C) to recommend to a user based on weighted probabilities.
This function demonstrates the implementation of a probability-based content selection mechanism.
"""
content_options = ['Option A', 'Option B', 'Option C']
probabilities = [0.5, 0.3, 0.2] # These probabilities can be adjusted depending on strategy
# Placeholder for content selection logic

def compile_metrics(self, interactions):
"""
Compiles and summarizes user interaction data.
This function is crucial for understanding how to aggregate and interpret user data efficiently.
"""
# Placeholder for data compilation logic

def analyze_performance(self):
"""
Analyzes and identifies the content with the best performance based on metrics like click-through rates.
This function is essential for evaluating A/B testing results and optimizing content delivery.
"""
# Placeholder for performance analysis logic

# Additional methods can be designed to enhance functionality such as error handling, scalability to handle more content types, and advanced data analysis techniques.

def extend_to_various_content(self, details):
"""
Adapts the system to manage a broader range of content types, each with unique characteristics.
"""
# Placeholder for adapting system logic

def refine_data_handling(self, details):
"""
Proposes and implements refinements in data handling and processing to enhance system efficiency and accuracy.
This includes ensuring unique identification of user interactions across different content types.
"""
# Placeholder for data handling improvements

# Example of how this class could be utilized
content_system = ContentRecommender()
# Example function call to select content
print(content_system.select_content())
# Implementation for these methods would need to be completed by developers
# user_data = {'interactions': ...}
# content_system.compile_metrics(user_data)
# best_content = content_system.analyze_performance()
# content_system.extend_to_various_content(details)
# content_system.refine_data_handling(details)

六、結語

整體來說一般美國DS、DA Live Coding難度還是比較簡單的,LeetCode最多就是考到Medium中偏易的程度,SQL通常也不會考到太刁鑽,扎實地準備的話大部分的Live Coding應該能過,心態放平、仔細審題、保持跟面試官溝通、Ask clarification question、解釋你的思路和考量,常常面試官甚至都不用我解釋寫完就說OK沒問題,但是最好都問一下面試官要不要做更多的解釋。自信是很重要的,我在Meta SQL一度卡住的時候,心裡想說,我寫不出來別人也寫不出來吧,Live Coding就要有這樣的自信,不能慌,然後我就掛了⋯(不過因為沒有feedback也不知道具體掛在哪就是了。)

七、Appendix

對於每一種題型、每一間我面試過的公司我都整理了相當多的面經,由於內容太多就不放在這篇文章裡了,之後也許再分幾篇分享,這裡就分享地裡網友整理的Meta SQL面經題:

--

--

Bert Lee // 李慕家

Seek & Find | DS @WBD | Former DS @Disney+ & @DBS Bank | Yale & NTU Alumni | LinkedIn: https://www.linkedin.com/in/bertmclee/