携程 10.13 数据开发笔试:最大子数组变体、left join 与 AI Coding
- 轮次
- 笔试
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 算法题:最大连续子数组和的变体(暴力解法会超时)。
- SQL 题:用 left join 保留计划旅行的路线数据,没有访问景点的游客数要用 ifnull / coalesce 兜底,并注意按景点 id 正确关联。
- AI Coding 题:把 readme 与测试样例结果喂给 AI,在既有代码上继续优化得分。
《参考解析》
最大子数组和变体拿不到满分:先分清楚是复杂度问题还是边界问题。笔试里这类题常见的失分点有三个。一是规模判断错了:n 到 1e5 以上,O(n²) 的枚举区间必然超时,必须用 Kadane 线性 DP 或前缀和加单调队列处理「区间长度受限」的版本(限制长度在 [L, R] 内时,用前缀和加双端队列维护窗口最小值)。二是边界没覆盖:全负数、全零、单个元素、答案区间在首尾,这些都容易漏;题目再叠加「区间长度最长」「左端点最小」这类并列取优条件时,比较器优先级写错会静默丢分。三是溢出:区间和用 int 累加会在大数据上翻车,统一用 long long / int64 承接。通过率停在 60%~80% 这个区间,基本就是「算法方向对、边界或数据范围没处理干净」,改题前先把暴力版本在小数据上对拍一遍,比盯着代码空想有效得多。
left join 的失分:几乎都出在「关联键」和「条件位置」两件事上。需求是保留计划旅行的路线数据(即以计划表为左表),统计没有访问景点的游客数,这类题的标准写法是:左表是所有计划路线,右表是访问记录,LEFT JOIN ... ON 计划.景点id = 访问.景点id AND 其他关联条件,然后用 COUNT(访问.游客id) 或 SUM(CASE WHEN 访问.游客id IS NULL THEN 1 ELSE 0 END) 统计缺失;聚合后如果还有缺失值再用 IFNULL / COALESCE 兜底成 0。两个关键点:一是关联键必须写对(本题作者没考虑景点 id 的关联,只过了 60%),只按游客 id 关联会把不同景点的访问记录混在一起,结果偏小或偏大;二是过滤条件放 ON 还是 WHERE 决定外连接会不会退化成内连接——写在 WHERE 里的 右表.字段 = x 会把右表为 NULL 的行过滤掉,等同于内连接,写在 ON 里才能保留左表全量行。另外注意 COUNT(*) 会统计 NULL 行而 COUNT(列名) 不会,IFNULL 是 MySQL 方言而 COALESCE 是标准 SQL、还能接受多个参数,答题时优先用 COALESCE 更通用。
SQL 复查清单:写完之后按列自问一遍。一是口径(去重口径、时间范围、是否包含未完成订单);二是连接(每张表的关联键是不是唯一键,多对多会不会造成笛卡尔积放大);三是聚合(分组键与 SELECT 里的非聚合列是否一致,NULL 参与比较与排序的行为);四是空值(除法前 NULLIF(分母,0)、拼接前 COALESCE);五是排序与分页(并列时是否有稳定的第二排序键,深分页是否需要游标);六是方言(日期函数、字符串函数、窗口函数在各数据库的差异)。数据开发岗的笔试题往往故意把「必须用外连接 + 空值兜底」作为考点,看到「所有」「没有的也要列出来」这类措辞就要条件反射地想外连接;看到「求比例」就要想分母会不会为 0、分子分母的口径是否一致。把这些自问做成习惯,比多刷十道题更能提高通过率。
AI Coding 的提分思路:让 AI 有明确的验收信号。这类题的评分通常是跑一批隐藏用例,所以别指望「让它再优化一下」能自动涨分。可行流程是:第一步把 readme 里的接口契约、输入输出格式、边界说明完整喂进去,让它先复述一遍确认理解;第二步自己先跑一遍公开用例,把「输入、期望输出、实际输出」三条一起给它,明确指出差在哪一步,必要时贴上报错栈;第三步要求它一次只改一个点,并保持可运行——本次 79% 与 60% 的通过率,多半是某类边界或某条关联逻辑整体缺失,而不是整体思路错,需要做的是定位而不是重写;第四步留出时间做交叉验证,用小规模手造数据对拍。作者最后拿到 4763/4776,说明大部分用例已经过了,剩下的十几分通常就藏在空值兜底、极端输入和格式细节里,与其反复让 AI 泛泛优化,不如自己把这些角落逐一列出来交给它定点修。