当前位置:首页 > 行业动态 > 正文

爱奇艺大数据开发笔试题

基于用户行为与内容特征,通过数据清洗、特征工程构建推荐模型,采用ALS或Spark MLlib进行协同过滤训练,结合

实时用户行为分析系统设计

系统架构设计

组件 功能描述
数据源 Kafka集群:接收用户行为日志(含用户ID、时间戳、行为类型)
流处理层 Flink/Spark Streaming:实时消费Kafka数据,窗口计算UV、购买转化率
状态管理 Flink Keyed State:维护用户活跃状态和购买标记
结果存储 MySQL:存储每分钟计算结果(活跃用户数、转化率)
监控层 Prometheus+Grafana:监控系统延迟、吞吐量、错误率

核心处理逻辑(Flink示例)

// 定义水位线允许的事件延迟
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val watermarkStrategy = WatermarkStrategy[UserBehavior]
  .withTimestampAssigner((event, timestamp) => event.timestamp)
  .withIdleness(Duration.ofMinutes(1))
// 主流处理逻辑
kafkaSource.assignTimestampsAndWatermarks(watermarkStrategy)
  .keyBy(_.userId)
  .window(TumblingEventTimeWindows.of(Time.minutes(1)))
  .process(new WindowFunction {
    def process(key, window, input, out): Unit = {
      val activeUsers = input.map(_.userId).distinct(_.userId).size
      val purchaseCount = input.filter(_.action == "purchase").size
      out.collect((window.getEnd, (activeUsers, purchaseCount)))
    }
  })
  .addSink(mysqlSink)

关键优化点

优化方向 实施方案
状态后端 使用RocksDB管理状态,设置stateBackend = new RocksDBStateBackend()
检查点 启用Checkpoint(每分钟一次),配置checkpointStorage = new FsStateBackend("hdfs://...")
并发控制 根据Kafka分区数设置parallelism = kafkaPartitions 2
反压处理 开启backpressure.enabled=true,调整max.parallelism参数

离线数据仓库建模(星型模型)

维度表设计

维度表 字段示例 存储周期
用户维度 user_id, gender, age, city, create_time 永久存储
商品维度 item_id, category, price, brand 永久存储
时间维度 date, hour, week, month, quarter 最近2年数据

事实表设计

CREATE TABLE fact_order_detail (
  order_id BIGINT,
  user_id BIGINT,
  item_id BIGINT,
  amount DECIMAL(10,2),
  order_time TIMESTAMP,
  -外键关联维度
  PRIMARY KEY (order_id)
) PARTITIONED BY (dt STRING) STORED AS ORC;

ETL流程设计

graph TD
    A[原始订单数据] --> B[数据清洗]
    B --> C[关联用户维度表]
    C --> D[关联商品维度表]
    D --> E[按日期分区]
    E --> F[存储至Hive]

常见问题与解答

Q1: Flink状态后端选择RocksDB还是内存?何时需要切换?

A1:

爱奇艺大数据开发笔试题  第1张

  • 内存状态后端:适合小状态场景(如简单计数器),重启后状态丢失。
  • RocksDB状态后端:适合大状态场景(如复杂用户画像),支持状态持久化和恢复。
  • 切换时机:当状态数据量超过数百MB或需要故障恢复时,必须使用RocksDB。

Q2: Hive分区表设计时如何选择分区字段?

A2:

  • 高频查询字段:优先选择WHERE条件中高频出现的字段(如date)。
  • 基数控制:避免高基数字段(如user_id),建议使用组合分区(如year=2023/month=10/day=15)。
  • 业务意义:按自然时间周期或业务周期划分(如电商大促期间
0