题目重点:依据 Oracle Health OOD 电面,先澄清治疗频率、锚点、时间边界和时区,再生成范围内全部安排。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版每个 treatment 有名称、首次时间和正整数 everyDays;频率固定为每 N 个 24 小时,不含按月、工作日、跳过节假日或临时停药。
- 所有时间使用同一时区,开始和结束都包含;同一时刻多个 treatment 都保留并按时间、名称排序。医疗生产系统必须确认本地时间、夏令时和临床规则。
解题路线
- 先从需求建模:Treatment 定义锚点、频率、有效期与临床状态;Occurrence 是一次实际执行时间,不能把“频率”只存为字符串。
- 对每个治疗计算不早于范围起点的首个 occurrence:若锚点更早,用时间差整除周期跳过整段历史,再检查是否还需加一周期。
- 逐周期生成直到超过结束时刻;合并所有治疗结果并按时间稳定排序。若按月或每周特定星期,必须使用日历推进而非固定秒数。
- 在 OOD 中把递推规则封装为策略接口,使每日、每周、按工作日方案可替换;时间窗口、取消和重排都通过领域事件记录。
手动走一遍
治疗 A 于 1 月 1 日 09:00 开始每 2 天一次,查询 1 月 4 日至 1 月 8 日,得到 1 月 5 日与 7 日 09:00。治疗 B 若也在 5 日 09:00 执行,两条记录均保留。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Training recurrence: fixed whole-day intervals anchored at each treatment."""
from dataclasses import dataclass
from datetime import datetime, timedelta
@dataclass(frozen=True)
class Treatment:
name: str
first_at: datetime
every_days: int
def treatment_times(
treatments: list[Treatment], start: datetime, end: datetime
) -> list[tuple[datetime, str]]:
if end < start:
return []
output: list[tuple[datetime, str]] = []
for treatment in treatments:
if treatment.every_days <= 0:
raise ValueError("every_days must be positive")
if treatment.first_at.tzinfo != start.tzinfo or start.tzinfo != end.tzinfo:
raise ValueError("all datetimes must use the same timezone")
period = timedelta(days=treatment.every_days)
if treatment.first_at < start:
elapsed = start - treatment.first_at
steps = elapsed // period
current = treatment.first_at + steps * period
if current < start:
current += period
else:
current = treatment.first_at
while current <= end:
output.append((current, treatment.name))
current += period
return sorted(output, key=lambda item: (item[0], item[1]))
复杂度
T 个 treatment、结果 R 条:跳至范围起点每项 O(1),生成 O(R),最终排序 O(R log R),额外输出空间 O(R)。若每个来源已按时间有序,可用小根堆归并到 O(R log T)。
易错点与追问
容易失分的边界
- 把“每月一次”简化为每 30 天,或把当地 09:00 简化为固定 UTC 秒差。
- 从首次治疗逐项扫描多年历史,而非跳到查询起点。
- 治疗频率、首次时间或时间窗边界未澄清就编造完整原题。
继续深挖
- 夏令时切换时“每天 09:00”如何保持本地时钟语义?
- 临时取消、补做和频率变更如何影响已生成的未来计划?
- 若查询结果上百万,怎样分页且保持稳定顺序?
