LAX-1 仓库数据分析 · 候选人指南
欢迎!接下来的时间里,你将作为 YQN 海外仓数据团队的一员,分析一座正在运转的美国仓库 LAX-1(洛杉矶,3PL 第三方仓) 的作业数据。
这座仓库的数据是活的:订单、拣货、打包、入库每分钟都在发生,数据库里的数据会随时间持续增长。现有数据覆盖最近约两周。
我们关注的不只是结果,更是你怎么思考:如何理解业务、如何怀疑数据、如何用证据支撑结论、如何把结论讲清楚。遇到不确定的地方,写下你的假设,继续往前走。
1. 访问方式
三种方式访问的是同一份数据,任选、可混用。在自己的电脑上或下面的工作机器上访问都可以。
| 方式 | 地址 | 说明 |
|---|---|---|
| Web 页面 | https://playground.yqnlink.us | 看板、订单、库存、库位图、人员。适合先建立直观认识 |
| Open API | https://playground.yqnlink.us/api/docs | REST + OpenAPI(Swagger),无需鉴权。规范文件:/api/openapi.json |
| 数据库直连 | 见下方 | PostgreSQL 16,只读账号 |
数据库连接信息
Host: playground.yqnlink.us
Port: 5432
Database: wms
User: candidate
Password: lax1-readonly
psql "host=playground.yqnlink.us port=5432 dbname=wms user=candidate password=lax1-readonly"
- 只读账号,单条查询超时 60 秒。
- 也可以用 DBeaver / DataGrip / Python / R 等任何客户端。
- API 列表接口使用游标分页:把响应中的
next_cursor原样传给下一次请求的cursor参数;limit最大 1000;请控制并发(≤ 5)。
2. 你的工作机器
我们为你准备了一台独立的 Linux 机器,可以在上面写代码、跑需要长时间运行的程序。
| 项目 | 值 |
|---|---|
| 地址 | player.yqnlink.us |
| 用户名 | ubuntu(有 sudo 权限,可以自行安装软件) |
| 登录密钥 | ⬇ 下载 yqn_player.pem |
| 系统 | Ubuntu 26.04 · 2 vCPU · 4 GB 内存 |
| 已安装 | python3 (3.14) · pip / venv · git · psql · jq |
macOS / Linux
# 1. 下载密钥(或点击上面的链接),并把权限改为只有自己可读——否则 ssh 会拒绝使用这个密钥
curl -O https://playground.yqnlink.us/downloads/yqn_player.pem
chmod 400 yqn_player.pem
# 2. 登录
ssh -i yqn_player.pem ubuntu@player.yqnlink.us
Windows(PowerShell,Windows 10/11 自带 OpenSSH)
# 1. 下载密钥后,去掉其他用户的访问权限
icacls .\yqn_player.pem /inheritance:r /grant:r "$($env:USERNAME):(R)"
# 2. 登录
ssh -i .\yqn_player.pem ubuntu@player.yqnlink.us
常用操作
# 在工作机器上连数据库(psql 已装好)
psql "host=playground.yqnlink.us dbname=wms user=candidate password=lax1-readonly"
# Python:系统 Python 不允许全局 pip install,请用虚拟环境
python3 -m venv ~/venv && source ~/venv/bin/activate
pip install pandas "psycopg[binary]" requests
# 长时间运行的程序:用 tmux / nohup,断开 SSH 也不会停
tmux new -s work # 断开后重新登录:tmux attach -t work
# 在本机浏览器里用 Jupyter:登录时加端口转发,然后在机器上启动 jupyter,浏览器打开 http://localhost:8888
ssh -i yqn_player.pem -L 8888:localhost:8888 ubuntu@player.yqnlink.us
- 也可以用 VS Code 的 Remote - SSH 插件直接在这台机器上写代码(主机填
ubuntu@player.yqnlink.us,密钥选yqn_player.pem)。 - 首次连接会提示确认主机指纹,输入
yes即可。 - 遇到
Permission denied (publickey):检查用户名是否为ubuntu、-i后面的密钥路径是否正确;遇到UNPROTECTED PRIVATE KEY FILE:按上面的步骤修改密钥权限。 - 面试结束后机器会被回收,请不要在上面存放个人信息。
3. 你需要知道的约定
- 时间:数据库与 API 中所有时间字段都是 UTC。仓库位于洛杉矶,当地时区
America/Los_Angeles(夏令时 PDT = UTC-7,冬令时 PST = UTC-8,11 月第一个周日切换;请用时区名换算,不要写死偏移量)。涉及"哪一天""几点"的问题,请按仓库当地时间回答。 Web 页面显示的是当地时间。 - 班次(当地时间):
| 班次 | 时间 |
|---|---|
| DAY | 06:00 – 14:30 |
| SWING | 14:00 – 22:30 |
| NIGHT | 22:00 – 次日 06:30 |
- 时间戳来源:
pick_records、pack_records、putaway_records中的作业时间由现场作业设备(RF 枪、打包台)上报;outbound_orders/inbound_receipts中的状态时间由 WMS 服务端记录。 - 库位编码:
区-排-列-层,例如A-03-07-2= A 区第 3 排第 7 列第 2 层。层号 1 最低、4 最高。 - A / B / C 区:地面拣货区(
PICK) - D 区:夹层(Mezzanine)拣货区,需要走楼梯上下,仅持
MEZZANINE资质的人员可进入 - R 区:托盘存储区(
RESERVE),存放整箱 / 整托库存,用于补货到拣货位 DOCK-IN-xx:收货月台locations.pos_x_m / pos_y_m是库位的平面坐标(米),可用于估算行走距离。
4. 业务流程
入库: 入库单(ASN) 创建 ──► 到货(ARRIVED) ──► 上架(putaway,系统给出建议库位) ──► 全部上架(PUTAWAY_DONE)
库内: 存储位(R) ──补货(REPLEN)──► 拣货位 盘点(cycle count):按计划抽盘 + 拣货报短后触发复盘
出库: 订单创建 ──► 库存分配 ──► 拣货 ──► 复核打包 ──► 承运商揽收发运
│ │ 库存不足 → BACKORDER(定期重试,72 小时仍无货则 CANCELLED)
│ └ 成功 → ALLOCATED
│ 拣货:标准单每 15 分钟一个波次释放,加急单立即释放 → PICKING → PICKED
│ 拣货员在库位发现货不够时,上报"短拣"(SHORT),系统会从其他库位重新分配补拣(REPICK)
│ 复核:打包台逐件扫描核对,一致 → PACKED;不一致 → EXCEPTION,问题行重新拣货后再次复核
└──────► 承运商(UPS / FEDEX / USPS)每天在固定时间来仓揽收 → SHIPPED
- 每个订单都有
sla_due_at:必须在此时间之前发运(以shipped_at为准)。 - 订单状态:
CREATEDBACKORDERALLOCATEDPICKINGPICKEDEXCEPTIONPACKEDSHIPPEDCANCELLED
5. 数据字典
主数据
| 表 | 说明 | 关键字段 |
|---|---|---|
owners |
货主(仓库的客户) | owner_code, owner_name, industry |
skus |
商品 | owner_id, sku_code, sku_name, category, barcode, unit_weight_kg, 尺寸, is_fragile, unit_value_usd(单件货值) |
locations |
库位 | location_code, zone, aisle, bay, level, location_type(PICK/RESERVE/DOCK), capacity_units(最多可放件数), pos_x_m, pos_y_m |
workers |
作业人员 | worker_code, role(PICKER/PACKER/RECEIVER), shift, certifications, hired_at |
devices |
作业设备 | device_code, device_type(RF_GUN/PACK_STATION), station_code |
入库
| 表 | 说明 | 关键字段 |
|---|---|---|
inbound_receipts |
入库单 | receipt_no, owner_id, status, created_at, expected_at, arrived_at, completed_at, updated_at |
inbound_receipt_lines |
入库单明细 | receipt_id, sku_id, lot_no(批次), expected_qty, received_qty(到货后回填) |
putaway_records |
上架记录(一次搬运一行) | receipt_id, sku_id, lot_no, qty, suggested_location_id(系统建议), to_location_id(实际放置), worker_id, device_id, started_at, completed_at |
库存
| 表 | 说明 | 关键字段 |
|---|---|---|
inventory |
库存快照:当前系统账面,一行 = 库位 × SKU × 批次 | qty_on_hand(在库), qty_allocated(已分配给订单、尚未拣走), updated_at |
inventory_transactions |
库存流水:账面的每一次变化 | txn_type, location_id, sku_id, lot_no, qty_delta(正 = 增加), ref_type + ref_id(来源单据), worker_id, created_at |
cycle_counts |
盘点记录 | system_qty(盘点时账面), counted_qty(实盘), reason(SCHEDULED / SHORT_PICK_TRIGGERED), worker_id, counted_at |
txn_type 取值:
| txn_type | 含义 | ref |
|---|---|---|
INITIAL |
数据起点时的期初库存 | — |
PUTAWAY |
上架入账 | PUTAWAY → putaway_records.putaway_id |
PICK |
拣货出账(负数) | PICK → pick_records.pick_id |
REPLEN_OUT / REPLEN_IN |
补货:从存储位移出 / 移入拣货位 | REPLEN |
CYCLE_COUNT_ADJ |
盘点差异调整(账面调整为实盘数) | CYCLE_COUNT → cycle_counts.count_id |
出库
| 表 | 说明 | 关键字段 |
|---|---|---|
outbound_orders |
出库订单 | order_no, owner_id, channel(AMAZON/SHOPIFY/TIKTOK/WALMART), priority(STANDARD/EXPEDITED), carrier, status, created_at, sla_due_at, allocated_at, picked_at, packed_at, shipped_at, tracking_no, updated_at |
outbound_order_lines |
订单明细 | order_id, line_no, sku_id, qty_ordered |
pick_records |
拣货记录:RF 枪每上报一次 = 一行 | order_id, order_line_id, sku_id, location_id, lot_no, qty_requested, qty_picked, pick_type(NORMAL/REPICK), status(DONE/SHORT), worker_id, device_id, task_assigned_at, picked_at |
pack_records |
复核打包记录:每次复核一行 | order_id, attempt_no(第几次复核), station_code, worker_id, device_id, expected_units, scanned_units, result(PASS/MISMATCH), box_type, package_weight_kg, started_at, completed_at |
pack_exceptions |
复核不一致的明细 | pack_id, order_line_id, exception_type(WRONG_ITEM 扫到了别的商品 / MISSING_ITEM 数量不够), expected_sku_id, scanned_sku_id, expected_qty, scanned_qty |
一个订单行可能对应多条拣货记录(从多个库位/批次拣、报短后补拣、复核不一致后重拣)。
6. 题目与作答
题目由面试官在面试开始时单独发给你,并会告诉你本场的重点和时间安排。不要求全部完成。
作答要求:
- 工具与语言不限,可以在自己的电脑上做,也可以在上面的工作机器上做。
- 每道题请给出:结论 + 支撑结论的查询 / 代码 + 你做了哪些假设。
- 鼓励质疑数据:如果你觉得某些数据"不对劲",说出来,并说明你是怎么发现的。
- 代码请保留在工作机器的家目录(
~/)下,或者在面试结束前发给面试官。
祝顺利!有任何关于题意或数据的问题,随时问面试官。