51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在处理船舶AIS数据时,如何设计算法来过滤重复或异常数据,并优化查询性能?请举例说明数据清洗流程、去重方法及索引优化策略。

中国船舶集团有限公司第七六〇研究所数据库与软件开发难度:中等

答案

1) 【一句话结论】处理船舶AIS数据时,需通过数据清洗(异常/缺失处理)+ 时间窗口/哈希去重(保留有效数据)+ 复合B树索引优化(加速查询),以提升数据质量和查询性能。

2) 【原理/概念讲解】数据清洗流程分三步:

  • 异常值检测:检查时间戳、位置等字段是否在合理范围内(如时间戳在当前时间±10分钟内,位置坐标在合理海域内);
  • 缺失值处理:位置、速度等字段缺失时,用前一个有效记录填充或标记为未知;
  • 去重:采用时间窗口去重(基于时间戳的滑动窗口,保留每个MMSI的最新记录,窗口大小如5分钟)或哈希去重(通过哈希函数生成唯一标识,快速去重)。

去重方法中,时间窗口去重适合实时数据流(保留最新状态),哈希去重适合批量处理(高效去重)。索引优化:为时间戳和MMSI字段创建复合B树索引,因为查询常按时间范围和MMSI筛选,复合索引能加速范围查询(避免全表扫描)。

3) 【对比与适用场景】

方法定义特性使用场景注意点
时间窗口去重基于时间戳的滑动窗口,保留窗口内每个MMSI的最新记录保留最新状态,适用于实时流实时AIS数据流处理窗口大小需根据数据更新频率调整
哈希去重通过哈希函数生成唯一标识,相同标识合并为一条记录快速计算,适用于大数据量批量数据处理(如每日数据清洗)需要足够内存存储哈希表
基于主键去重直接利用数据库主键唯一性,删除重复记录简单直接,依赖主键定义关系型数据库中主键已定义的情况需要确保主键唯一,否则无效

4) 【示例】(伪代码,处理AIS数据表ais_data,字段:timestamp、mmsi、latitude、longitude):

# 数据清洗流程
def clean_ais_data(data):
    valid_data = []
    for record in data:
        if -10 < (record['timestamp'] - datetime.now()).total_seconds() < 10:  # 时间戳合理
            if -90 <= record['latitude'] <= 90 and -180 <= record['longitude'] <= 180:  # 位置合理
                valid_data.append(record)
        else:
            continue  # 异常时间戳丢弃
    # 缺失值处理(位置缺失用前一个有效记录填充)
    cleaned_data = []
    prev_record = None
    for record in valid_data:
        if record['latitude'] is None or record['longitude'] is None:
            if prev_record:
                record['latitude'] = prev_record['latitude']
                record['longitude'] = prev_record['longitude']
        cleaned_data.append(record)
        prev_record = record
    return cleaned_data

# 时间窗口去重(滑动窗口5分钟)
def deduplicate_by_time_window(data, window_size_minutes=5):
    from collections import deque
    deduped = []
    window = deque()
    for record in data:
        current_time = record['timestamp']
        # 移除过期记录
        while window and current_time - window[0]['timestamp'] > timedelta(minutes=window_size_minutes):
            window.popleft()
        # 检查是否已存在
        for r in window:
            if r['mmsi'] == record['mmsi']:
                r['latitude'] = record['latitude']
                r['longitude'] = record['longitude']
                break
        else:
            window.append(record)
            deduped.append(record)
    return deduped

# 索引优化(SQL示例)
# CREATE INDEX idx_ais_time_mmsi ON ais_data (timestamp, mmsi);
# 查询示例:SELECT * FROM ais_data WHERE mmsi = 123456 AND timestamp BETWEEN NOW() - INTERVAL 1 HOUR AND NOW();

5) 【面试口播版答案】
面试官您好,处理船舶AIS数据时,核心是通过数据清洗(异常/缺失处理)+ 时间窗口去重(保留最新状态)+ 复合B树索引优化(加速查询),以提升数据质量和查询性能。具体来说,数据清洗分三步:1. 异常值检测,比如时间戳是否在当前时间±10分钟内(船舶AIS更新频率通常较快,超出范围视为异常);2. 缺失值处理,位置坐标缺失时用前一个有效记录填充;3. 去重,采用时间窗口去重,滑动窗口5分钟,保留每个MMSI的最新记录(因为船舶位置会更新,保留最新状态更符合业务需求)。去重方法中,时间窗口去重适合实时数据流,哈希去重适合批量处理。索引优化方面,为时间戳和MMSI字段创建复合B树索引,因为查询常按时间范围和MMSI筛选,复合索引能加速范围查询(比如查询某个MMSI最近1小时内的数据,索引能快速定位到相关记录,避免全表扫描)。这样处理后,数据质量提升(异常/缺失数据减少),查询性能也优化了(索引加速查询)。

6) 【追问清单】

  • 问题1:如何处理数据中的缺失值?
    回答要点:根据业务场景,位置、速度等缺失值用前一个有效记录填充(如船舶位置连续更新,缺失时用上一个位置),或标记为未知(如速度缺失标记为0)。
  • 问题2:时间窗口去重中,窗口大小如何选择?
    回答要点:窗口大小需根据船舶移动速度和AIS更新频率调整,比如5分钟适合大多数情况(船舶移动速度约10-30节,5分钟内位置变化不大),避免窗口过小导致数据丢失,过大导致延迟。
  • 问题3:如果数据量很大,如何处理实时去重?
    回答要点:使用流处理框架(如Apache Flink),结合状态管理维护时间窗口的缓存,实时去重并写入清洗后的数据。
  • 问题4:复合索引的顺序如何影响性能?
    回答要点:索引顺序应与查询条件匹配,比如查询常按时间范围和MMSI筛选,复合索引为(时间戳,MMSI)比(MMSI,时间戳)更高效,因为时间戳是范围查询的关键字段。
  • 问题5:异常数据检测的具体方法?
    回答要点:使用统计方法(如Z-score,计算数据偏离均值的倍数,超过3倍视为异常)或基于规则(如位置变化速度超过合理阈值,如每秒超过10公里视为异常)。

7) 【常见坑/雷区】

  • 坑1:忽略数据清洗的必要性,直接去重可能导致错误结果(如异常数据被保留)。
  • 坑2:时间窗口去重窗口大小选择不当,过小导致数据丢失(如船舶移动时,窗口内无有效记录),过大导致延迟(如5分钟内多个记录被合并,延迟更新)。
  • 坑3:索引选择错误,比如用哈希索引处理范围查询(如按时间范围查询),导致性能下降(哈希索引不适用于范围查询)。
  • 坑4:未考虑数据实时性,静态去重方法不适用于实时数据流(如船舶AIS数据实时更新,需要实时去重)。
  • 坑5:去重后未更新索引,导致查询性能未提升(索引未重建,查询仍全表扫描)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1