技术岗位 · Coding

机器人重复消息过滤:只更新最后展示时间

隐藏的接收消息不刷新10秒窗口,等号行为单独指定。

题目重点:隐藏的接收消息不刷新10秒窗口,等号行为单独指定。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 本文以message为去重键,若多个robot独立需改为(robotId,message)。事件时间单调,使用单调时钟。
  • 默认show条件elapsed>10;inclusive=True改为≥10。首次消息必展示,同键隐藏时不更新last_shown。

解题路线

  1. map保存最后真正展示的时间;不存在键直接展示。存在则与last_shown比较,超过阈值才展示并更新。
  2. 不能保存last_received:连续每3秒收到重复消息会不断延后到期,让本可再次展示的消息永久被抑制。
  3. 时间回退拒绝或按clock策略处理;超大键空间可清理老记录,但应只在清理后“缺键就允许展示”的结果与过期判断一致时移除。

手动走一遍

消息m在10/13/21到达:show/hide/show;21−10=11,隐藏13没有刷新基准。10后20到达:默认strict隐藏,inclusive展示;21随后结果取决于20是否已展示。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def filter_messages(events, gap=10, inclusive=False):
    if gap < 0 or any(events[i][0] > events[i+1][0] for i in range(len(events)-1)):
        raise ValueError("nonnegative gap and monotonic timestamps required")
    last_shown, result = {}, []
    for now, message in events:
        if message not in last_shown:
            show = True
        else:
            elapsed = now - last_shown[message]
            show = elapsed >= gap if inclusive else elapsed > gap
        result.append(show)
        if show:
            last_shown[message] = now
    return result

复杂度

n事件期望O(n)时间、O(d+n)空间含bool输出;stream接口可减少输出存储但last_shown仍O(d)。

易错点与追问

容易失分的边界

  • 把当前状态展示TTL和重复消息抑制混为一题,会错误地隐藏/显示。
  • 内容归一化如忽略大小写会合并不同消息,需明确业务同一性。

继续深挖

  • 消息时间不是接收顺序时,按哪个时间轴保证操作员体验?
  • 多个进程共享展示渠道如何原子比较并更新时间以免重复展示?
✓已复制微信号!