作者:布衣云水客|2026-09-21
公开教学资料;不包含个人简历、客户项目名称或私人业绩清单。所有练习数据人工合成。技术说明按所用产品版本核实。
业务实体、结果粒度、时间口径、过滤范围、去重规则。例如“各区域每月净订单额”:一行=区域×自然月,按订单业务日期统计,金额为已确认订单金额减该订单退款,测试样例只处理单币种。真实财务收入不等于订单额;退款按发生月还是归属订单月要事先约定。
关联之前检查基数。订单对明细、支付、退款都可能一对多;直接同时JOIN会笛卡尔放大。先把每张子表聚合到订单粒度,再JOIN。COUNT(DISTINCT order_id)不能修复已经被放大的SUM(amount)。
WHERE在分组前筛行;HAVING对聚合后分组筛选;窗口函数保留明细粒度。多数关系数据库不能在同一层WHERE直接筛窗口函数别名,应套CTE/子查询;部分引擎支持QUALIFY,使用前确认方言。
ROW_NUMBER给唯一序号;RANK同分同名次且跳号;DENSE_RANK同分同名次不跳号。每组严格取3条用ROW_NUMBER并增加稳定次序键;取前三种金额并保留并列用DENSE_RANK<=3。没有次序键时并列选哪条可能不稳定。
环比=(本期-上期)/上期,同比=(本期-去年同口径同期)/同期。分母0返回NULL并标记“不可比”,不能显示0%或无穷大;负基期如何呈现需业务约定。LAG只取上一个存在的行,不保证是上个月,必须先补全日期×维度骨架。财务会计期不能默认等于自然月;MTD只能与可比截止天数对比。
右表字段的筛选放在WHERE会剔除右表为NULL的记录。保留左表所有行时,把右表过滤放到ON或预过滤子查询。NULL比较用IS NULL,不用= NULL。COUNT(*)包含空扩展行;COUNT(r.id)只数匹配记录。
子查询含NULL时,三值逻辑可能让整个NOT IN判断不是TRUE。常用NOT EXISTS表达反连接,同时明确关联键NULL含义。不要不加区分地把所有NULL替换成0或空串。
按业务键PARTITION,按updated_at DESC、可靠版本号/事件序号DESC排序,ROW_NUMBER=1。只有时间戳不一定能解决乱序或同毫秒更新;CDC应使用源端可比较的提交位点/版本,并明确跨分区排序边界。
按created_at DESC,id DESC稳定排序,下一页条件为created_at<:last_time OR (created_at=:last_time AND id<:last_id),结合匹配索引。它改善深页扫描,但不支持任意跳页;并发更新时要定义快照或允许轻微变化。排序列可为空时另设规则。
先明确同一批商机还是不同阶段的当期存量。分母为进入起始阶段的合格实体,分子为在规定观察窗口内完成目标阶段的实体;实体ID去重。不能拿本月成单数直接除以本月新线索数就称同批转化率。窗口未结束的样本存在右删失。
教学例:经常按tenant_id、region筛选paid订单,并按order_date范围取数。候选索引可以包含(tenant_id,region,status,order_date),但最佳顺序取决于等值条件、选择性、排序、数据倾斜和其他查询;不是机械地“区分度最高永远放第一”。范围条件后字段能否减少扫描或参与索引条件下推取决于引擎,不能说后面全部失效。
EXPLAIN要看:扫描方式、估计行数/实际行数、JOIN顺序与算法、索引命中、排序/哈希是否落盘、循环次数、过滤比例、buffer读取。EXPLAIN ANALYZE通常会真正执行查询,写语句或重查询不能在生产随手跑。
MySQL的type/rows/Extra不能原样套到PostgreSQL;PostgreSQL的ANALYZE/BUFFERS输出与MySQL不同。GaussDB不同产品形态、openGauss与PostgreSQL兼容性也有差异,必须确认具体版本、存储形态及执行计划语法。
常见优化顺序:定位链路→固定可比数据与负载→看计划与统计信息→修复错误关联/不必要扫描→索引或查询重写→合理预聚合与缓存→容量扩展。SQL更快但结果口径变了,不算成功。
日期过滤尽量用半开区间:order_date >= :start AND order_date < :end,避免对过滤列做日期函数导致索引利用受限。不要绝对说任何函数都会让索引失效,函数索引/表达式索引可能支持。
MVCC让读者看到某个可见版本,减少读写阻塞,但不保证没有锁,也不自动解决所有业务竞争。隔离级别包括读未提交、读已提交、可重复读、串行化,具体实现和异常边界因引擎不同。
MySQL InnoDB默认常为可重复读,PostgreSQL默认读已提交;以实际配置为准。InnoDB一致性读与锁定读语义不同,可重复读下部分范围锁定会出现next-key锁;不能据此推断所有数据库行为。串行化也可能事务失败,需要可重试设计。
库存扣减可用UPDATE stock SET qty=qty-:n WHERE sku=:sku AND qty>=:n,检查影响行数;跨多行约束还需锁/事务/其他一致性设计。乐观锁用version条件并检查更新结果;重试不能无限放大冲突。
长事务的风险:锁持有长、旧版本回收受阻、连接占用、复制延迟、回滚代价大。治理:外部HTTP调用移出事务、缩小事务范围、分批但保留业务原子性边界、设超时、避免用户交互中持锁。不能只“把事务注解删掉”。
死锁处理:固定访问顺序、合适索引、短事务、记录死锁图;失败后重试整个逻辑事务,带退避与次数上限。业务幂等键防止重试造成重复扣款/发单。
背景:哪类报表/接口、数据规模与负载;定位:Trace分解应用/数据库/外部依赖耗时;证据:计划、扫描行数、锁等待、线程池/连接池;措施:改SQL、索引、批量查询、拆外部调用;验证:同口径压测、正确性比对、错误率、P50/P95/P99;发布:灰度、回退、监控。
实际面试案例应来自本人真实经历。具体索引、线程数和耗时前后值需要原始验证记录,不能把教学措施都说成当时已经实施。
随包“练习/sql_lab.py”可直接运行任务1/2及重复JOIN陷阱、Top N、去重、幂等和SCD时间边界断言;其余任务在面试前手写。
定位说明:以下内容属于面试知识与教学设计。学习过概念或运行过演示,不等于具有相应平台的生产经验。
DDD模型服务交易规则和状态一致性;维度模型服务聚合分析。订单聚合根维护合法状态迁移,分析侧则可能有订单行事务事实表、日快照事实表和订单全流程累积快照表。
建模四步:选业务过程→声明粒度→识别维度→识别事实。粒度优先于字段。例如订单行事实一行=订单×行号,订单头金额不能重复放到每条行记录后直接SUM;共同维度可含客户、产品、区域、日历、币种。
事实类型:事务事实记录发生事件;周期快照按天/月反映状态;累积快照跟踪里程碑。金额通常可加,但必须同币种同口径;余额对账户可加、对时间通常不可加;比率通常不可直接相加或平均,应回到分子分母聚合。
星型模型查询简单、维度适度反规范化;雪花减少部分冗余但多JOIN;宽表便于消费但扩列、重刷、历史口径维护成本高。不能为了减少JOIN无限做一张大宽表。
命名因公司而异;关键是血缘、可重放、契约清晰和避免重复计算。小规模项目无需为了“四层齐全”复制四份数据。
SCD1覆盖最新属性,适合不需历史追溯的纠错;SCD2新建版本,保留valid_from/valid_to,用半开区间[from,to)避免切换瞬间双匹配。将事实业务发生时间与维度有效区间关联,防止用今天区域归属重写历史收入。current_flag便于查当前,但不能代替历史时间连接。
自然键来自业务、代理键来自仓库;同一自然键有多个历史版本。需要检查区间重叠、间隙、晚到维度、未知成员及跨时区边界。业务有效时间和系统入库时间不同,严格追溯可能需要双时间模型。
全量简单但资源消耗大;时间戳增量需处理精度、回写旧数据和删除;CDC通过日志或变更接口捕获插入/更新/删除,需管理位点、顺序、重复、Schema变更与保留期。
可靠全量+增量衔接:建立一致快照与对应日志位点→读取快照→持续接收衔接变更→按业务键和源版本幂等合并→对账→切读。具体先启动日志还是先建快照由连接器一致性协议决定,不能自行随意拼接两个时间点。CDC丢失位点后应明确回补/重建流程。
幂等不等于只做唯一键。若先收到版本3再收到版本2,普通UPSERT仍会旧值覆盖新值,需要版本条件。删除要传播delete标记或删除动作;软删除与硬删除取决于审计和保留政策。
消息重复投递很常见,端到端效果需要源位点、处理状态、提交协议和目标写入幂等/事务共同配合。某个计算引擎保证状态exactly-once,不代表调用外部HTTP发短信也exactly-once。常见可落地组合是at-least-once+业务幂等键+唯一约束+重试/补偿。
Outbox把业务变更和待发事件写同一数据库事务,再由独立进程/CDC投递;消费者Inbox/业务唯一键去重。它解决本地写库与发消息的原子性缺口,但仍需积压监控、事件版本、去重保留期和最终一致性管理。
步骤:源目标字段映射→枚举/单位/币种转换→试迁移→分层对账→增量追平→切换前检查→短窗口写入控制或约定双写策略→切读/切写→观察→回退门槛。
对账不能只比较行数。至少检查主键集合、总金额、按国家/状态聚合金额、关联完整性、抽样字段、拒绝记录。哈希对账需统一NULL、字符编码、排序、金额精度等规范,不能把不同规范生成的hash直接比较。
回退最大难点是新系统已产生新写入。必须约定停写、反向同步/补偿或前向修复,不能一句“切回老库”就认为安全。恢复演练要验证RPO/RTO目标;目标值应由业务批准,不编造项目已有标准。
质量六类:完整性、唯一性、有效性、一致性、及时性、准确性。规则必须绑定粒度、阈值、责任人、严重级别与处置。例如订单ID非空、源版本不回退、金额对账误差、业务日期分区到达延迟。
质量流程:规则执行→异常隔离→告警→根因定位→修复回补→复验关闭。阻断规则会影响可用性,因此P0财务口径不符可阻断发布,轻微非关键属性缺失可标记降级,但要事先约定。字段非空不证明业务数值准确。
数据契约包括字段类型、可空性、枚举、粒度、主键、更新时间、保留策略、兼容规则。血缘应能回答“这张报告为何有这个数、哪些源表变更会影响它”。Schema变更分兼容扩展与破坏变更,后者要版本与双读验证。
Kafka分区保证全局有序吗? 通常只在单分区日志内有序;同业务键路由同分区可维持局部顺序,扩分区可能改变映射;消息处理并发也可能打乱完成顺序。
Flink watermark是什么? 对事件时间进度的估计,决定窗口何时触发/清理的依据之一;不保证以后绝不会来迟到数据。需配置乱序容忍、空闲分区、迟到处理、状态TTL和更正输出。
Spark为什么慢? 先看执行计划与阶段指标,再看数据倾斜、shuffle、宽依赖、分区数、文件大小和序列化;广播小表要有可承受大小,不能对未知体积表强制广播。
批流如何选? 按新鲜度要求、准确性、规模、状态复杂度和运维成本。经营日报可能批处理足够;秒级预警才考虑流式路径。湖仓表格式解决表事务/元数据等问题,不会自动解决所有数据质量与权限。
需求:“为什么华南这个月销售不好?”先追问:销售指签约、订单、开票、收入还是回款?华南按客户归属、销售组织还是交付地?本月是自然月还是会计期?对比预算、上月、去年同期还是同行?包含哪些产品、币种和状态?数据截至何时?
形成指标契约:metric_id、中文名称、业务定义、计算公式、粒度、单位/币种、时间字段/会计日历、维度白名单、状态过滤、权限规则、数据源、刷新频率、负责人、版本、适用场景与不可比规则。
报告不能让LLM根据“销售额”自行猜定义。语义不明确时先澄清;无权限时拒绝或返回授权范围内的结果,不能转而展示缓存里的全量值。
净订单额=有效订单金额-订单归属退款;客单价=净订单额/有效订单数;商机转化率=合格商机队列中成单数/该队列合格商机数;预算达成率=同口径实际值/同口径预算。
订单、收入、回款属于不同业务事件和会计口径;不宜直接互相替代。利润率必须用同币种收入和成本计算。加权平均要回到原始分子分母:两区域转化率分别90%(9/10)、10%(10/100),整体是19/110≈17.27%,不是50%。
增长公式:同比=(本期-去年同期)/去年同期;环比=(本期-上期)/上期。基期为0、负数、缺失或口径变更时,要展示不可比原因。百分比变化与百分点变化区分清楚。
先检查数据延迟、去重、退款、汇率和组织调整,再分析总量变化。按区域/行业/产品拆分贡献,寻找主要变化来源;再看漏斗、价格、数量、结构等解释变量。
教学例:基期100单×10元=1000元,本期80单×12元=960元,总差额-40。 - 顺序替换法:数量效应(80-100)×10=-200,价格效应80×(12-10)=160,合计-40。 - 顺序不同会改变分摊。对称分解:数量效应(80-100)×(10+12)/2=-220,价格效应(12-10)×(100+80)/2=180,仍合计-40。
“主要由数量下降贡献”是算术分解;“由某政策导致”是因果结论,需要实验或更强证据。报告应区分事实、统计关联、解释假设和建议。净变化接近0时,各分项/净变化的贡献比例可能很大或不稳定,优先展示绝对值。
多代表处对标必须统一会计期、规模、币种、行业组合、生命周期及分母。不同行业结构造成的汇总差异可能出现辛普森悖论,应分层或标准化比较。不要只按绝对销售额给小区域判“差”。
推荐报告:执行摘要→核心指标及口径/截止时间→趋势与异常→维度拆解与对标→数据证据→解释假设→行动建议→限制与待验证问题。
图表选型:时间趋势折线;结构对比条形;贡献分解瀑布;分布用直方/箱线;关系用散点。避免双轴制造相关、截断纵轴夸大差异、饼图过多类别。表格必须带单位、空值说明和口径。
流程:加载→指定类型→校验→去重→连接→聚合→时间对齐→计算衍生指标→导出与质量报告。
# 教学片段,依赖pandas;完整无依赖练习见随包脚本。
import pandas as pd
orders = pd.read_csv('orders.csv', dtype={'order_id':'string','region':'string'})
orders['order_date'] = pd.to_datetime(orders['order_date'], errors='raise')
assert orders['order_id'].notna().all()
assert orders['order_id'].is_unique
refunds = pd.read_csv('refunds.csv', dtype={'order_id':'string'})
r = refunds.groupby('order_id', as_index=False)['refund_cents'].sum()
x = orders.loc[orders['status'].eq('paid')].merge(
r, on='order_id', how='left', validate='one_to_one')
x['refund_cents'] = x['refund_cents'].fillna(0).astype('int64')
x['net_cents'] = x['amount_cents'] - x['refund_cents']
x['month'] = x['order_date'].dt.to_period('M')
monthly = x.groupby(['region','month'])['net_cents'].sum()
# 先按已约定的月份范围补全region×month,再计算shift与环比。
注意:pandas merge中两边空键可能匹配,这与典型SQL NULL不相等的JOIN语义不同,应先拒绝/单独处理缺失主键。groupby默认可能丢弃空分组,需显式决定dropna。不要依赖隐式类型推断把带前导0的ID读成数字。
金融金额用整型最小货币单位或Decimal,避免二进制float累计舍入;跨币种应有币种、汇率日和换算规则。大CSV可分块读,但跨块去重/全局排序/分组要维护全局状态;数据很大时把聚合下推数据库或合适引擎,而不是把所有数据读入内存。
向量化通常比逐行apply高效,但表达清晰和正确优先;I/O并发与CPU计算并发分开考虑。常规CPython下线程不适合单纯加速Python字节码CPU密集任务,扩展库和解释器构建方式可能有差异。
均值对异常值敏感,中位数更稳健;P95表示95%的观测值不超过该值(具体样本分位数插值算法有差异)。方差/标准差描述离散程度,不能代替误差来源分析。
相关不等于因果:销售和广告同时上升可能都受节日影响。A/B实验需定义随机化单位、主要指标、护栏、样本量/最小检测效果、观察窗口,避免反复偷看后择机宣布成功。没有实验时,分层、前后对比、双重差分都有前提,不能包装为无条件因果证据。
评测集通过率是二项比例:若独立样本中95/100通过,点估计95%,但并不表示真实稳定下限95%;用Wilson等区间反映不确定性。开发反复调过的集合会高估泛化,需独立测试集和上线反馈。
题1:本月订单额下降20%,如何诊断?参考顺序:校验数据→统一时间与口径→拆数量/价格/产品结构→区域与行业贡献→漏斗/大单影响→提出待验证假设→行动建议。
题2:两张报告销售额不同怎么办?核对版本、统计截止时间、时间字段、组织映射、状态、币种、权限、去重、退款归属,再定位到可重现的最小实体集合;不能直接取平均。
题3:报告里“未取到数据”能写0吗?不能。0表示确认没有量,缺失表示未知,超时表示系统失败,无权限表示不可访问。API与前端必须区分这些状态。
推荐教学分层:接入层(鉴权/配额/请求校验)→语义层(指标口径/维度/会计期)→规划层(数据源/路由/依赖)→执行层(查询/聚合/衍生加工)→呈现层(表格/图表/格式)→审计与可观测性。
基础取数保留事实口径,中台沉淀共享衍生指标与规则;前端做呈现,不复制多套同比公式。边界应按复用性、性能和责任组织确定,不是任何计算都必须放中台。组织内部的数据服务协议与平台命名应以公开授权资料为准。
先说明解决什么:入口分散、调用模式重复、来源迁移困难。教学接口可包含metricId、维度过滤、period、requestedGrain、timeout、traceId;tenantId和权限范围必须来自可信登录上下文而不是让客户端随意传。
路由:注册数据源能力与支持指标→参数规范化→能力匹配→成本/优先级选择→构建依赖DAG→按依赖并行执行→合并结果→统一错误语义。动态路由规则要版本、灰度、回退和审计;不要在SDK里硬编码每个业务判断。
并行化只对无依赖节点有效。设全局并发上限、单依赖隔离舱、总截止时间;下游deadline<=请求剩余预算。某分支失败时,关键指标失败就失败,允许部分结果时清楚标记缺失,不能默默当0。
{
"metricId": "net_order_amount",
"metricVersion": "v1",
"period": {"calendar": "natural_month", "start": "2026-01", "end": "2026-03"},
"groupBy": ["region", "month"],
"filters": {"region": ["east", "west"]}
}
响应建议包含status、rows、unit/currency、dataAsOf、sourceVersion、metricVersion、qualityFlags、traceId。授权范围由服务端注入并审计。end是否包含当月必须写入接口契约;上面教学请求采用包含结束月的业务语义,执行时转成半开日期区间。
版本变化可能意味着数据不可直接比,不能只升级JSON字段。幂等导出/任务创建可接受请求幂等键,配合唯一约束避免重复任务。
缓存键包含租户/授权范围摘要、指标版本、标准化查询、时间/数据版本、币种/语言等影响结果的因素;摘要不能暴露秘密,权限变更需失效或重新鉴权。相同问句不等于相同权限和数据快照,不能直接按问句跨用户缓存。
穿透:输入校验、必要时缓存可信空结果;击穿:热点单飞/互斥刷新、TTL抖动;雪崩:错峰与限流。允许返回旧数据须有明确新鲜度标记和业务许可。Redis不能代替权威数据源和权限判断。
大导出用异步任务:QUEUED→RUNNING→SUCCEEDED/FAILED/CANCELLED。采用稳定快照或截止水位、keyset分批读取、流式写文件、重试检查点、权限复验、下载有效期、脱敏与审计;避免全量读进JVM内存。CSV中以=、+、-、@等起始的文本需防表格公式注入,按目标客户端规范转义,不改变数值语义。
Spring事务通常基于代理,类内部自调用可能绕过代理;异常回滚规则、传播行为、连接事务参与情况要核对。事务内调用外部服务无法通过本地数据库回滚撤销远端副作用。
线程池不能无限队列无限扩容:按下游容量、阻塞比例、内存和延迟预算配置,监控active/queue/reject。CompletableFuture并行要传递鉴权/Trace上下文,统一异常、取消和超时;不能把所有阻塞请求塞进默认公共池。
RabbitMQ消费者ack应在业务状态可持久恢复后确认;重投递按业务键幂等;失败进入受控重试/死信与人工补偿。生产者确认、持久化和消费者ack解决不同阶段的问题,不保证业务天然exactly-once。
DDD:领域层表达业务规则,应用层组织用例,基础设施层处理持久化与外部依赖,接口层适配输入输出。状态机控制合法转换,重复事件和乱序事件要定义行为;不要用数据库状态字段自由赋值绕过规则。
需求澄清:用户数/峰值并发、数据量、更新延迟、查询复杂度、权限、审计、可用性目标。没有实际数字时声明假设,不把它们当原项目指标。
教学假设:200个峰值在途请求、平均耗时2s,稳定状态下Little定律估算约100 QPS;这是同一系统边界的平均值,不是CPU选型的充分依据。若每次查询扇出4路,需考虑缓存命中、实际并行和下游放大,而非直接套单库100 QPS。
架构:API网关→语义服务→权限策略→查询规划→数据源适配器→聚合/衍生指标→结果缓存;旁路接元数据、数据质量、审计、Trace;重型报告和导出走队列与任务状态。
取舍:实时源保证新鲜但压力大,预聚合快但延迟且维度灵活性受限;可组合高频预聚合与低频明细查询。限制可查询维度与时间跨度,设置扫描量/执行时长预算,避免一个自然语言问句拖垮源库。
验收:同口径正确性、越权为0的目标测试、数据时效、P95/P99、错误率、并发退化曲线、成本、故障恢复。所有目标值须在设计时约定,没有证据的数值不应包装成历史SLA。
答题路径:领域边界→源目标映射→全量/增量一致性→幂等和版本→对账→灰度切流→回退与新写入处理→监控。高频追问:跨库事务如何处理?旧系统再次回写旧版本怎么办?组织/币种码变化怎么办?切流期间重复事件怎么去重?
不要直接选择分库分表。先判断瓶颈是查询、存储、锁还是单点容量。分片键决定跨片查询和热点;迁移、全局ID、二级索引、分布式事务都是成本。教学设计与订单中台真实实现必须分开。
即使核心模块行覆盖率很高,也不能单独证明业务正确,关键看关键分支、边界断言、契约测试、故障注入和回归。测试矩阵应覆盖空数据、重复、乱序、超时、限流、部分失败、权限交叉、版本变化与恢复。AI生成代码也必须通过独立审查和测试,不能用“Agent说通过了”作为验收。
NL2Card:把问题映射到受治理的指标卡片、筛选条件与页签。优势是语义边界和权限更可控,缺点是受卡片覆盖率限制。NL2SQL:生成可执行查询,灵活但存在错误口径、昂贵查询、越权和注入风险。智能诊断报告类型报告:编排多个分析步骤,输出表格、图表和解释。
卡片检索经验不能自动等同于生产Text-to-SQL经验。个人项目中的MCP、向量记忆和数据库工具,也不能直接表述为客户生产系统实现。
输入→可信鉴权上下文→意图识别→结构化槽位提取→术语/会计期标准化→权限内卡片召回→重排与匹配→参数校验→卡片/页签定位→必要澄清→结果与审计。
槽位示例:intent、metric、period、region、industry、comparison、metricVersion。缺必填字段或口径有歧义时先问用户。模型输出必须通过JSON Schema、枚举、日期范围和维度组合校验;模型置信度不是可信概率,阈值要靠标注集调优。
教学例:“华南本会计期管道同比如何?”必须识别“管道”对应哪个受治理指标、“会计期”来自哪个日历,并确定去年同期规则。不能自动把管道当收入、把会计期当自然月。
卡片元数据可含标题、业务释义、别名、适用维度、可用页签、数据口径、更新版本和ACL。切分应保留语义单元与来源ID,不按任意字符截断关键定义。
关键词检索适合精确代码/术语,向量检索适合语义近义,可混合召回后重排。top-k越大不一定越好,会带来噪声、延迟和上下文成本。离线分别看Recall@k、MRR/NDCG(需要相应相关性标注)、最终任务成功率,不用一个总通过率代替所有环节。
ACL过滤尽量进入检索计划,必要时重排后再复验;不能先把无权文档交给模型再只在最后遮挡。embedding/知识库版本变化应重建或兼容管理,避免新旧空间混用。
Function Calling是模型产生结构化工具选择和参数的机制;真正执行由应用控制。Skill可视作任务步骤、规则与工具组合的封装,不是某个模型天然保证安全的能力。MCP是模型应用与工具/资源交互的协议,不等于RAG,也不替代鉴权。
工具设计:名称/描述清楚、参数Schema严格、返回结果稳定、副作用显式、可重试语义明确。动态注册需要白名单、版本、权限与上线流程,不允许让模型任意注册/执行脚本。
安全多轮循环伪代码:
context = trusted_auth_context()
for step in range(max_steps):
response = model(messages, permitted_tools(context))
if response.has_final_answer:
return validate_final_answer(response, evidence)
for call in response.tool_calls:
tool = allowlist.lookup(call.name)
args = schema_validate(call.args)
scope = server_side_authorize(context, tool, args)
result = execute_with_deadline_and_budget(tool, args, scope)
messages.append(untrusted_tool_result(call.id, result))
evidence.append(result.provenance)
raise ControlledFailure('iteration_budget_exceeded')
设总deadline、最大轮次、工具调用数、token/费用预算;处理参数错误、循环调用、重复副作用、超时和无数据。依赖步骤按序执行,无依赖只在资源预算内并行。对业务写操作需要适当确认/审批,不能按“用户想要结果”自动扩大权限。
指标值和同比由确定性程序计算;模型负责解读和语言组织,不心算金额和比率。工具结果携带metricId/version、period、filters、unit、dataAsOf、queryId、qualityFlags、授权范围摘要与sourceId,报告中的关键断言可回链这些证据。
生成后检查数字与单位一致、图表与表格一致、引用存在且支持结论、同比基期一致、无数据没有被写成0。规则校验与模型评审互补;“加了引用”不代表引用真的支持结论。
缺一类关键数据时返回“部分报告/不可完成”,标记原因,不用模型编一个趋势。建议写“观察到……,可能与……相关,需进一步验证……”,不把相关性直接写成确定归因。
检索内容、表格备注、网页、工具输出都是不可信数据,其中“忽略系统要求/导出所有客户”不是指令。隔离数据与控制指令,固定工具白名单与最小权限,服务端注入租户过滤,限制SQL查询能力及扫描量,验证下载链接与工具目标。
用户不能通过prompt指定别人的tenant_id扩大权限;只读账户也可能读到敏感数据,因此仍需行列权限、脱敏、审计及租户隔离。SQL参数化保护值,动态表名/列名需要白名单,不能靠参数化解决所有结构注入。
对Text-to-SQL教学扩展:AST/语义约束、允许语句集、只读副本、超时/扫描预算、元数据权限、禁危险函数、执行结果限量和人工审批组合使用。只用正则检查SELECT开头远远不够。
数据划分:开发集用于迭代,独立测试集用于结论,线上影子流量/灰度用于真实分布验证。近义改写和同模板题应防跨集泄漏,避免同一问题改几个字就算独立泛化。
覆盖维度:常见问法、复杂口径、时间歧义、多区域对标、未覆盖意图、缺字段、无数据、权限攻击、提示注入、工具失败。记录样本来源、标签标准、裁判一致性、版本、成本和延迟。
分层指标:意图准确率;槽位exact match或字段级P/R;卡片Recall@k;工具选择/参数正确率;端到端任务成功率;报告数字/引用正确率;安全拒绝与误拒;延迟P95、成本、超时率。
BadCase分桶:意图错、别名缺、口径混、时间错、召回漏、重排错、参数错、工具失败、权限缺陷、证据不足。每次只改可解释变量,用回归集检查修复没有伤害其他类别;之后冻结版本对独立集评测。
假设同一冻结集中的通过率从50%提高到70%,这是提升20个百分点,相对提升40%。必须同时交代样本数、抽样方式、通过标准、版本与统计窗口;不同集合的两个通过率不能直接比较。
报告评测结果时,应给出分层错误和独立留出集表现,而不是把通过率说成大模型事实准确率。小样本应补充置信区间和局限,未经核实不要声称某个参数修改单独导致所有提升。
| 天 | 主题 | 必须产出/验收 |
|---|---|---|
| 1 | 经历证据、岗位定位 | 录90秒介绍;完成8项业绩的证据缺口列表 |
| 2 | 粒度、JOIN、去重 | 手写订单净额SQL;解释一对多金额膨胀 |
| 3 | 窗口函数、同比环比 | 补齐缺失月;通过0分母/并列名次测试 |
| 4 | 索引与执行计划 | 用自建数据库解释1条计划;不要把SQLite计划当MySQL计划 |
| 5 | MVCC、锁、长事务 | 画一个死锁/并发更新例子,讲完整事务重试 |
| 6 | Python数据处理 | 跑练习脚本;输出月度表与质量报告 |
| 7 | 第一轮复盘 | 30分钟SQL模拟,错题回归、修订介绍 |
| 8 | 事实/维度与数仓分层 | 画订单行事实星型模型,标每张表粒度 |
| 9 | SCD与会计期 | 解释跨月/组织变更;写半开区间关联 |
| 10 | CDC与幂等 | 运行版本去重测试,口述快照/位点衔接 |
| 11 | 数据迁移与质量 | 写切换对账清单和新写入回退方案 |
| 12 | 指标树与归因 | 做量价分解,区分算术贡献与因果 |
| 13 | 经营分析报告 | 用练习数据写1页报告,区分0/缺失/异常 |
| 14 | 第二轮复盘 | 45分钟数据工程模拟,给自己评分 |
| 15 | NL2Card与检索 | 画指标卡片检索流程;写5个歧义/无权限用例 |
| 16 | Function Calling与MCP | 解释工具循环,定义1个安全只读工具契约 |
| 17 | 评测与BadCase | 跑评测练习;列分层指标和测试集防泄漏方案 |
| 18 | 报告可信度/安全 | 列10条数字/引用/权限检查,演练注入攻击 |
| 19 | 系统设计 | 白板画经营分析平台,说明缓存和故障边界 |
| 20 | 并发、消息、可靠性 | 讲Outbox、幂等、超时预算、导出任务状态 |
| 21 | 第三轮复盘 | 60分钟AI应用+系统设计模拟 |
| 22 | 指标卡片检索深挖 | 2分钟项目讲稿+8追问,补真实BadCase |
| 23 | 智能诊断报告深挖 | 2分钟讲稿+8追问,分清已做与改进方向 |
| 24 | 运营中台深挖 | 补3个真实组件、1个实际性能优化证据 |
| 25 | 订单中台深挖 | 核实性能环境、迁移边界、个人贡献 |
| 26 | 行为题/职业沟通 | 6张真实STAR卡;准备转岗与空档原因 |
| 27 | 全真模拟 | 按下面90分钟脚本录音,不看答案 |
| 28 | 查缺补漏与面试包 | 错题二刷、JD映射、反问、设备/环境检查 |
可用时间不足7天:第1天定位/证据;第2天SQL;第3天建模与迁移;第4天指标与Python;第5天AI与评测;第6天四项目;第7天模拟。每天优先P0,不临时背大量未做过的框架。
0—5分钟:自我介绍与岗位匹配。要求明确外部服务项目关系、数据+AI定位。
5—25分钟:SQL题。订单表与多笔退款表,求连续三个月各区域净额与环比。追问:缺月怎么办、0分母怎么办、一单多退款为何放大、订单日与退款日口径差异。验收:正确粒度、先聚合、日期骨架、NULL语义、稳定排序。
25—40分钟:任选运营中台或订单中台深挖。至少讲一个本人实际改动;追问业绩分母、压测环境、回退与个人贡献。不能拿教学设计冒充历史实现。
40—60分钟:白板设计“多租户经营分析+智能报告”。讲需求→数据与指标→权限→查询执行→报告编排→缓存与限流→可观测性→验收与取舍。
60—75分钟:AI题。NL2Card与NL2SQL选择、卡片召回失败分析、工具循环、评测50%→70%含义、提示注入与越权。
75—85分钟:行为题。跨部门口径冲突、一次失败/故障、为什么选择数据方向。
85—90分钟:候选人反问,不只问技术栈。
=80可进入冲刺;65—79针对弱项补课;<65先补SQL和项目。该分数仅是练习标准,不预测真实录用。编造经历、严重越权设计或完全忽视数据正确性属于一票预警,先纠正再评分。
日期[ ];题目[ ];当时答案[ ];错误类型(知识/口径/代码/证据/表达)[ ];正确结论[ ];可验证例子[ ];关联项目[ ];次日复测[ ];一周复测[ ]。
进入本资料目录,运行:
python3 练习/sql_lab.py
python3 练习/analysis_lab.py
python3 练习/ai_eval_lab.py
只需Python 3.9+标准库和支持窗口函数的SQLite(3.25+)。不连接外部业务系统,不调用付费模型,不需要API密钥。数据全部为人工教学数据,不含客户资料,不代表任何项目实测成果。输出写入“练习/output”。脚本中的断言通过后还要解释原理,不能只展示绿色通过。
orders:order_id、region、order_date、amount_cents、status。refunds:refund_id、order_id、refund_cents。只计paid订单,退款回归原订单月份;单币种,金额为整数分。paid退款在教学中代表已完成退款。日期使用ISO字符串,真实库使用恰当日期类型与时区。
预期区域月净额:east 1月25000、2月0、3月30000;west 1月5000、2月10000、3月0。净额合计70000分=700元。east三月环比分母为0,因此NULL;west二月环比1.0即100%,三月为-1.0即-100%。east二月的0是教学假设“已确认源数据完整,确实无订单”,真实生产缺数时不能自动填0。
订单o1有两笔退款1000/2000分,订单金额10000分。错误直接JOIN后SUM(amount-refund)会得到17000而非7000;正确方法先汇总退款。这道题的重点不是记SQL,而是识别粒度变化。
脚本还演示:ROW_NUMBER与DENSE_RANK的并列边界;按更新时间和序号去重;源版本防旧事件覆盖;SCD2半开区间关联。SQLite不等于生产MySQL/PostgreSQL,日期函数、UPSERT、EXPLAIN都需转换方言。
analysis_lab.py读取同一合成数据CSV,以Decimal输出净额、平均订单金额、指标口径和数据质量报告。它校验主键、金额类型、日期、状态和退款引用,比较结果与SQL计算是否一致。依赖sql_lab.py先生成输入。
扩展:加入未知区域、重复订单、非法日期、跨币种、超额退款、订单取消后退款等数据,定义哪些阻断、哪些告警。不要仅删除异常行后说数据“清洗好了”,要保留隔离记录和原因。
ai_eval_lab.py使用12条人工构造的标签与预测,计算意图准确率、卡片Recall@3、可回答任务成功率、安全拒绝率和BadCase,并输出Wilson区间。它是评测流程演示,不是对任何真实模型/项目的测试。
端到端成功要求预测意图、卡片、指标、期间、区域均正确并正确调用只读工具。安全题是另外的拒绝评测,不把拒绝攻击题成功混进普通业务完成率。只有两条安全样本,不能据此声称系统安全。
扩展:补未覆盖意图、口径冲突、权限变化、空数据、工具超时;增加独立留出集;引入真实模型前先固定标签和验收标准,再按版本保存预测,避免边看测试集边调模板。
输入自然语言→确认指标/区域/月→从白名单指标服务取数→生成确定性表格→生成解释文本。可先用规则解析替代LLM,重点验证数据链路。工具只读,不开放任意SQL,不读取真实客户数据。
验收10项:1正常月度净额;2并列Top N;3缺月与真实0区分;4分母0;5重复退款记录处理;6无权限拒绝;7工具超时不造数;8提示注入不执行;9同一结果图表一致;10版本和数据时间可追溯。
交付:README、数据字典、指标契约、代码、测试报告、架构草图、3分钟演示和局限清单。该作品只能称“个人练习/演示”,不能改写为客户生产项目。
下面是稳定的官方入口,不代表已核实某个特定版本的最新行为。以面试岗位实际版本为准,优先阅读查询、事务和安全章节。
阅读策略:先完成本套练习,再按错题查相应官方章节;不要把所有文档从头背完。拿到具体JD后,将其每项职责映射为“简历证据、知识点、演示作品、缺口”四列即可继续定向加深。