Meta DE 面经 | Python + Code 时间非常紧 Meta DS Senior面经

28Times read
No Comments
Meta DS 面经 | Python + Code 时间非常紧 Meta DS Senior面经

Meta de 主要考察简单和聚合查询、分组、排序、CTE、过滤逻辑、时间窗口等。这次面的senior level的,5个sql+5个python题,时间非常紧,一般做3+3比较保险,4+4肯定能进loop面试,分享下前两天的 Meta DE 面经 。

Meta DE 面经:SQL

Meta DS 面经:SQL Q1

Q1

  • num_copies_not_returned:处于 “good” 状态,且当前借阅还没归还的书本副本数
  • pct_renewed:在上面这批副本里,当前这次借阅 renewal_count > 2 的比例,范围 0~100
SELECT
    COUNT(*) AS num_copies_not_returned,
    CASE
        WHEN COUNT(*) = 0 THEN 0
        ELSE 100.0 * SUM(CASE WHEN ch.renewal_count > 2 THEN 1 ELSE 0 END) / COUNT(*)
    END AS pct_renewed
FROM copies c
JOIN checkouts ch
    ON c.copy_id = ch.copy_id
WHERE c.condition = 'good'
  AND ch.returned_date IS NULL;

Q2

lifetime_value的定义:一本书被借出的总天数。需要满足约束条件:未归还的借阅记录(returned_date IS NULL)不计入和只考虑拥有超过10个副本的书,找出 lifetime_value 最高的 前3本书。

SELECT 
    b.book_id,
    SUM(ch.returned_date - ch.checkout_date) AS lifetime_value
FROM books b
JOIN copies c ON b.book_id = c.book_id
JOIN checkouts ch ON c.copy_id = ch.copy_id
WHERE ch.returned_date IS NOT NULL
GROUP BY b.book_id
HAVING 
    (SELECT COUNT(*) FROM copies c2 WHERE c2.book_id = b.book_id) > 10
ORDER BY lifetime_value DESC
LIMIT 3;

Q3

图书馆会员可以预约书籍副本(排队等候借阅),找出预约数量与其邀请人差异最大的那个会员。

SELECT
    m.member_id,
    m.invited_by_member_id,
    ABS(
        COUNT(c.copy_id) -
        COUNT(ic.copy_id)
    ) AS diff_num_reserved_copies
FROM members m
LEFT JOIN copies c
    ON c.reserved_by_member_id = m.member_id
LEFT JOIN members im
    ON im.member_id = m.invited_by_member_id
LEFT JOIN copies ic
    ON ic.reserved_by_member_id = im.member_id
GROUP BY
    m.member_id,
    m.invited_by_member_id
ORDER BY diff_num_reserved_copies DESC, m.member_id
LIMIT 1;

Q4

找在2024年连续两个完整周都借过书的会员,然后从这些人中找出第一周借书数量最多的那个。

WITH member_week_checkouts AS (
    SELECT
        member_id,
        EXTRACT(WEEK FROM checkout_date)::INT AS week_idx,
        COUNT(*) AS num_copies
    FROM checkouts
    WHERE EXTRACT(YEAR FROM checkout_date) = 2024
      AND EXTRACT(WEEK FROM checkout_date) BETWEEN 1 AND 52
    GROUP BY
        member_id,
        EXTRACT(WEEK FROM checkout_date)
),
consecutive_weeks AS (
    SELECT
        w1.member_id,
        w1.week_idx AS first_week_index,
        w1.num_copies AS first_week_num_copies
    FROM member_week_checkouts w1
    JOIN member_week_checkouts w2
        ON w1.member_id = w2.member_id
       AND w2.week_idx = w1.week_idx + 1
)
SELECT
    member_id,
    first_week_index,
    first_week_num_copies
FROM consecutive_weeks
ORDER BY first_week_num_copies DESC, member_id, first_week_index
LIMIT 1;

Meta DE 面经:Code

Q1

最多选 3 本书,每本书必须来自不同 category,每本书有 (category, points),求最大总分

def get_max_score(books):
    # 每个category保留最高分
    best = {}

    for category, score in books:
        if category not in best or score > best[category]:
            best[category] = score

    # 取所有category的最高分
    scores = sorted(best.values(), reverse=True)
    # 最多取3个
    return sum(scores[:3])

Q2

图书馆每次借书或还书都会产生一条日志,日志包含书的ID和操作类型(借出/归还)。验证日志序列是否合法,遇到以下两种非法情况返回 False

Meta DS 面经:Code Q2
from dataclasses import dataclass

@dataclass
class LogEntry:
    book_id: int
    is_checkout: bool  # True = checkout, False = return

def are_log_entries_valid(log_entries):
    checked_out = set()

    for entry in log_entries:
        book_id = entry.book_id

        if entry.is_checkout:
            # checkout
            if book_id in checked_out:
                return False
            checked_out.add(book_id)

        else:
            # return
            if book_id not in checked_out:
                return False
            checked_out.remove(book_id)

    return True

Q3

图书馆有4个分馆(A/B/C/D),某些分馆关闭时,员工会去备用分馆或在家工作。给定一组关闭的分馆,返回每个开放分馆的实际员工总数。

以A为例:”A”: {“A”: 80, “B”: 10, “C”: 15, “D”: 5}

  • A馆共有80人
  • 如果A关闭:10人去B,15人去C,5人去D,剩余50人在家(80-10-15-5=50,不计入任何馆)
Meta DS 面经:Code Q3
def get_num_employees(location_employees: dict[str, dict[str, int]],
                      closed_locations: set[str]) -> dict[str, int]:
    result = {}

    # 先给所有未关闭办公室初始化为 0
    for loc in location_employees:
        if loc not in closed_locations:
            result[loc] = 0

    # 遍历每个“员工原属办公室”
    for src, dist in location_employees.items():
        if src in closed_locations:
            # src 关闭:员工分流到其他未关闭办公室
            for dst, cnt in dist.items():
                if dst != src and dst not in closed_locations:
                    result[dst] += cnt
        else:
            # src 未关闭:本办公室员工仍在原办公室上班
            result[src] += dist[src]

    return result

Q4

original_name 中删掉若干字母,能否得到 new_name?如果能,返回删掉了多少个字母;不能则返回 -1。忽略空格和大小写,new_name必须是original_name的子序列。

Meta DS 面经:Code Q3
def get_num_letters(original_name: str, new_name: str) -> int:
    # 忽略大小写 + 去掉空格
    original = original_name.replace(" ", "").lower()
    new = new_name.replace(" ", "").lower()

    i = 0
    j = 0

    # 双指针检查 subsequence
    while i < len(original) and j < len(new):
        if original[i] == new[j]:
            j += 1
        i += 1

    # 如果 new 没完全匹配
    if j != len(new):
        return -1

    # 删除字符数
    return len(original) - len(new)

总体都还可以,就是一小时内,时间非常的紧张,刚开始没多问直接开始SQL环节,总共做了4+4个问题,给的提示很到位了,也做完了,面试官还是非常肯定学生的能力的,Meta最近的SDE面的多,DS的也没问题,搞不定的。

整场面试下来可以发现,Meta 的题更多的考基础,时间非常有限,一般很难完成4个sql+4个code。如果你也担心在 Meta 或其他大厂面试中遇到类似情况,不如了解一下我们的 VO远程助攻服务 ,目前已经帮助数百名学员顺利拿下 offer,让面试不再慌乱,思路清晰,成功率大大提升。

author avatar
Jack Xu MLE | 微软人工智能技术人员
Princeton University博士,人在海外,曾在谷歌、苹果等多家大厂工作。深度学习NLP方向拥有多篇SCI,机器学习方向拥有Github千星⭐️项目。
End of text
 0