Flink学习项目总结(flink-recommandSystem-demo、flink-streaming-platform-web、flink-learning)
[Flink入门教程](https://mp.weixin.qq.com/s/xa2iGrmyoXq3FtZeU9GU-w)
[Flink背压](https://mp.weixin.qq.com/s/Ttm9lCYxu7Wx0oE-LsjRlw)
[Flink的CheckPoint机制](https://mp.weixin.qq.com/s/-OY0VGDWUoOMgKg-xKjZRQ)
[Flink入门](https://mp.weixin.qq.com/s/Ey-oWpGO_QDo4DixiccVGg)
零、Flink 基础概念
Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。



我按当前工作区理解,你说的“这几个 Flink 项目”主要是 3 套:
- flink-recommandSystem-demo
- flink-streaming-platform-web
- flink-learning(这个不是单一项目,更像 Flink 样例/实战合集,里面又拆了很多子项目)
下面我按“Flink 做了什么 + 类路径 + 步骤/方案 + 面试怎么讲”来拆。
一、flink-recommandSystem-demo:Flink 做实时特征计算、热榜计算、日志入库
这套项目里,Flink 不是直接“做推荐结果排序的全部逻辑”,而是负责把实时日志变成推荐所需的事实表、画像表、兴趣表、热度榜。
com.demo.task.LogTask
com.demo.task.UserHistoryTask
com.demo.task.UserInterestTask
com.demo.task.UserPortraitTask
com.demo.task.ProductProtaritTask
com.demo.task.TopProductTask
对应做的事:
- com.demo.task.LogTask + com.demo.map.LogMapFunction
作用:Kafka 日志消费后,落 HBase 事实表 con
方案:Kafka -> 解析日志 -> 组装 rowKey -> 写 HBase - com.demo.task.UserHistoryTask + com.demo.map.UserHistoryMapFunction
作用:构建“用户看过哪些商品 / 商品被哪些用户看过”
方案:Kafka -> 解析日志 -> HBase u_history / p_history 双向写入 - com.demo.task.UserInterestTask + com.demo.map.GetLogFunction + com.demo.map.UserHistoryWithInterestMapFunction
作用:用 ValueState + TTL 判断短时间连续行为,沉淀用户兴趣强度
方案:Kafka -> 转 LogEntity -> keyBy(userId) -> 100 秒 TTL 状态 -> 写 HBase u_interest - com.demo.task.UserPortraitTask + com.demo.map.UserPortraitMapFunction
作用:把用户行为映射成用户标签画像
方案:Kafka 日志 -> 查 MySQL 商品属性 -> 累加 HBase user 的 country/color/style - com.demo.task.ProductProtaritTask + com.demo.map.ProductPortraitMapFunction
作用:把访问商品的用户属性沉淀成商品画像
方案:Kafka 日志 -> 查 MySQL 用户属性 -> 累加 HBase prod 的 sex/age - com.demo.task.TopProductTask + com.demo.map.TopProductMapFunction + com.demo.agg.CountAgg + com.demo.window.WindowResultFunction + com.demo.top.TopNHotItems + com.demo.sink.TopNRedisSink
作用:计算实时热榜
方案:Kafka -> EventTime -> keyBy(productId) -> 60s 窗口/5s 滑动 -> 聚合 -> keyBy(windowEnd) -> ListState + Timer 排序 -> Redis
这套项目完整推荐方案其实是:
Kafka 行为日志 -> Flink 实时计算用户历史/兴趣/画像/商品画像/热榜 -> HBase/Redis 存储 -> com.demo.scheduler.SchedulerJob 定时跑相关度计算
com.demo.scheduler.ItemCfCoeff:基于 p_history 做 ItemCF,相似度写 HBase px
com.demo.scheduler.ProductCoeff:基于商品画像做相似度,写 HBase ps
最后 web 模块里的 com.demo.service.impl.RecommandServiceImpl 组合 Redis 热榜 + HBase 相似度结果给前端。
面试里这项目建议你这样讲:
“Flink 在这个项目里主要承担实时特征工程,不是直接产出最终推荐排序。它从 Kafka 接日志,实时维护用户行为历史、兴趣状态、用户画像、商品画像和热榜;离线或准实时任务再基于这些中间结果算 ItemCF 和标签相似度,Web 层读取 Redis/HBase 做最终推荐展示。”
要注意别过度包装成“生产级推荐系统”。
这份代码更偏 demo,很多地方是 map 里直接写外部存储,也没明显看到完整 checkpoint/exactly-once 配置。面试可以说“核心亮点是状态、窗口、特征沉淀思路”,别硬吹高可用一致性。
二、flink-streaming-platform-web:Flink 被封装成一个 SQL 实时计算平台
这套项目里,Flink 不是做某个具体业务指标,而是作为“执行引擎”被平台化了。
关键类路径:
- com.flink.streaming.web.StartApplication
- com.flink.streaming.web.controller.api.JobConfigApiController
- com.flink.streaming.web.ao.impl.JobYarnServerAOImpl
- com.flink.streaming.web.ao.impl.JobBaseServiceAOImpl
- com.flink.streaming.web.common.util.CommandUtil
- com.flink.streaming.core.JobApplication
- com.flink.streaming.core.execute.ExecuteSql
- com.flink.streaming.sql.validation.SqlValidation
- com.flink.streaming.web.rpc.impl.CommandRpcClinetAdapterImpl
- com.flink.streaming.web.rpc.impl.FlinkRestRpcAdapterImpl
Flink 做的事:
- 承接用户提交的 Flink SQL / Table 任务
- 根据任务类型创建 StreamTableEnvironment 或 TableEnvironment
- 执行 DDL、DML、INSERT INTO
- 应用 checkpoint/savepoint 参数
- 返回 JobID,供平台记录和运维
- 配合平台完成启动、停止、savepoint、恢复
步骤/方案可以概括成:
- Web 页面录入 SQL、运行参数、checkpoint 参数、依赖 jar
- JobConfigApiController 接口接收任务配置
- SqlValidation 做 SQL 语法预校验
- JobBaseServiceAOImpl.writeSqlToFile() 把 SQL 写到本地文件或 URL
- CommandUtil 拼 flink run 命令
- 命令入口固定走 com.flink.streaming.core.JobApplication
- JobApplication 读取 SQL 文件,创建 TableEnvironment/StreamTableEnvironment
- ExecuteSql 逐条解析和执行 SQL,最终提交作业
- CommandRpcClinetAdapterImpl 解析 stdout 里的 JobID,更新任务状态
- 停止/Savepoint 通过 CLI 或 Flink REST 去操作集群
面试里这项目可以这么讲:
“这不是单个业务作业,而是一个 Flink SQL 平台。我的重点不是写几个算子,而是把 SQL 校验、作业参数管理、命令拼装、任务提交流程、savepoint 恢复、状态管理这些平台能力串起来,让业务方通过 Web 就能提交 Flink 任务。”
三、flink-learning:不是一个项目,而是一组 Flink 能力样例
这个仓库更适合你面试时回答“我用 Flink 做过哪些类型的事情”。
比较值得讲的子项目:
- 实时数仓
com.zhisheng.project.warehouse.OdsToKafkaJob
com.zhisheng.project.warehouse.DwsOrderStatsJob
方案:Kafka ODS -> Flink 清洗/脏数据侧输出 -> Kafka DWD -> 窗口聚合进 DWS - 实时风控
com.zhisheng.project.risk.FraudDetectionCepJob
com.zhisheng.project.risk.RiskScoreJob
方案:Kafka 交易流 -> CEP 模式识别欺诈 -> 或 ValueState/MapState 做风险评分 - 实时大屏
com.zhisheng.project.dashboard.RealTimeDashboardJob
com.zhisheng.project.dashboard.TopNHotPagesJob
方案:Kafka 页面流 -> PV/UV 聚合 -> 两阶段聚合 + ListState + Timer 做 TopN - 实时日志分析
com.zhisheng.project.log.LogAnalysisJob
com.zhisheng.project.log.ErrorLogAlertJob
方案:Kafka 日志 -> Side Output 分流 ERROR -> 窗口统计/定时器告警 - 海量去重
com.zhisheng.project.deduplication.KeyedStateDeduplication
com.zhisheng.project.deduplication.TuningKeyedStateDeduplication
方案:Kafka -> keyBy(id) -> RocksDB 状态 + TTL -> 判断是否已处理 - 实时计算平台 / SQL 化
com.zhisheng.project.platform.FlinkSqlPlatformJob
com.zhisheng.project.platform.TableApiExampleJob
方案:DDL 建表 -> SQL/Table API 聚合 -> 动态表输出 - Connector / SQL / 数据湖示例
com.zhisheng.connectors.kafka.Main
com.zhisheng.sql.blink.stream.example.SQLExampleKafkaData2Kafka
com.zhisheng.datalake.hudi.HudiCDCSyncExample
com.zhisheng.monitor.pvuv.MapStateUvExample
所以 flink-learning 面试里别说成“我做过一个完整项目”,更准确的说法是:
“这是我系统化练 Flink 的仓库,我分别实践过 Kafka 接入、窗口聚合、状态去重、CEP 风控、实时数仓、Flink SQL、数据湖同步这些典型场景。”
四、怎么回答面试官“你是怎么使用 Flink 的?”
这个问题不能泛泛回答“读 Kafka、写 Kafka”。最好按固定模板讲:
第一句先定性:
“我主要把 Flink 用在实时数据处理场景,核心是从 Kafka/CDC 接数据,基于事件时间、状态和窗口做计算,再把结果写到 Kafka、Redis、HBase 或数据湖里,同时配 checkpoint/savepoint 保证任务可恢复。”
然后按 5 步展开:
- 数据接入
Kafka、CDC、日志流是最常见 source - 时间语义
先定 Event Time、Watermark,明确乱序和延迟处理方式 - 业务处理
简单场景用 map/filter/keyBy/window
复杂场景用 ProcessFunction、Keyed State、CEP、Flink SQL/Table API - 结果输出
写 Kafka、Redis、HBase、MySQL、Hudi 这类外部系统 - 可靠性与运维
checkpoint、savepoint、状态后端、重启策略、监控告警、异常恢复
你可以直接背这个偏面试版回答:
“我用 Flink 一般会先根据场景判断用 DataStream 还是 Flink SQL。数据大多从 Kafka 或 CDC 进来,先做解析、清洗、Watermark 定义;如果是实时指标类,就用 keyBy + window + aggregate;如果是用户画像、去重、风控这类场景,就用 ValueState、MapState、ListState 或 CEP;算完后再把结果写到 Kafka、Redis、HBase 或数据湖。上线时会重点配 checkpoint、savepoint 和状态后端,保证任务失败后能恢复。像我看过的这些项目里,推荐系统主要是做实时特征和热榜,风控项目主要是做 CEP 和实时评分,平台项目则是把 Flink SQL 提交和运维能力做成平台。”
名词解释
keyBy
- 按某个业务字段分组,比如按 userId、productId、pageId 分组。
- 分组后,同一个 key 的数据会进入同一个逻辑分区,后面才能做“按用户统计”“按商品排序”“按页面去重”。
window
- 窗口就是把“无界流”切成一段一段的“小批次”来计算。
- 比如“每 1 分钟统计一次 PV”“最近 5 分钟 TopN”。
- 常见有滚动窗口、滑动窗口、会话窗口。
aggregate
- 聚合计算,常见如 count/sum/max/min。
- 在 Flink 里通常表示“增量聚合”,来一条算一条,不需要把整窗数据都攒齐再算,性能更好。
ValueState
- 每个 key 保存“一个值”的状态。
- 适合存“上一次行为”“当前计数”“上次时间戳”这类单值信息。
MapState
- 每个 key 保存“一个 Map”的状态。
- 适合存“用户访问过哪些页面”“某用户在各城市出现的次数”。
ListState
- 每个 key 保存“一个 List”的状态。
- 适合暂存一批数据,常见于 TopN 排行,先收集再排序输出。
CEP
- Complex Event Processing,复杂事件处理。
- 用来识别“事件序列模式”,比如“5 分钟内连续 3 次小额交易后接 1 次大额交易”。
你前面那句话可以理解成:
- 实时指标类:更偏“统计”
keyBy + window + aggregate - 用户画像、去重、风控类:更偏“记忆 + 模式识别”
State + ProcessFunction / CEP
这些 Flink 能力再顺手理解一下
Watermark
- 水位线,用来告诉 Flink:“某个时间点之前的数据基本到齐了。”
- 主要解决乱序和延迟到达问题。
Side Output
- 侧输出流。
- 主流之外,额外分一条支路出来。
- 常用于脏数据分流、超时事件分流、ERROR 日志分流。
-
![image]()
Checkpoint
- 运行中的“状态快照”。
- 任务失败后可以从 checkpoint 恢复,保证状态不丢。
Savepoint
- 人工或运维触发的“可迁移快照”。
- 常用于停机升级、换版本、任务迁移。
五、面试里最加分的说法
不要只说“用了 Flink”,要说清楚这 4 件事:
- 为什么用 Flink,不用离线或普通 MQ 消费程序
- 数据从哪来,到哪去
- 中间用了哪些 Flink 能力:窗口、状态、CEP、SQL、Side Output、Watermark
- 你怎么保证任务能长期稳定跑:checkpoint、savepoint、状态管理、告警
如果你愿意,我下一条可以继续帮你把这份内容整理成一版更适合面试背诵的“3 分钟口述稿”。
面试那 4 个问题怎么答
1. 为什么用 Flink,而不是离线或普通 MQ 消费程序?
可以这么答:
- 如果业务只看 T+1 报表,离线就够了;但如果要秒级/分钟级结果,就更适合 Flink。
- 普通 MQ 消费程序也能消费消息,但它更像“写业务代码逐条处理”,而 Flink 天然支持事件时间、窗口、状态、容错、扩缩容和一致性保障。
- 只要场景里有“实时统计、乱序处理、去重、TopN、用户画像、风控模式识别”,Flink 就比普通消费者更合适。
一句话总结:
“Flink 适合持续、实时、有状态、要容错的流式计算;普通 MQ 消费更适合简单转发或轻处理;离线更适合低频大批量分析。”
2. 数据从哪来,到哪去?
通用答法:
- 数据源一般来自 Kafka、MySQL CDC、业务日志、埋点流。
- Flink 中间做清洗、分流、聚合、状态计算、模式匹配。
- 结果通常写到 Kafka、Redis、HBase、MySQL、ES、Hudi/Iceberg,给推荐、告警、大屏、数仓下游使用。
你可以按项目说:
- 推荐系统:Kafka -> Flink -> HBase/Redis
- 实时数仓:Kafka ODS -> Flink 清洗聚合 -> Kafka DWD/DWS
- 风控:Kafka 交易流 -> Flink CEP/状态评分 -> 告警流或 Kafka
3. 中间用了哪些 Flink 能力?
不要只报名词,要带用途:
- Watermark:处理乱序数据
- window:做分钟级/5 分钟级统计
- aggregate:做增量聚合,提高性能
- ValueState/MapState/ListState:保存用户历史、去重标记、TopN中间结果
- CEP:识别复杂事件模式
- Side Output:把脏数据、超时数据、错误日志单独分流
- Flink SQL/Table API:提升开发效率,让实时任务更平台化
4. 怎么保证任务稳定运行?
这块很加分,建议答完整一点:
- 开启 checkpoint,让任务失败后可恢复
- 发布升级时用 savepoint
- 状态较大时用 RocksDB 或合适的状态后端
- 配置重启策略、并行度、资源参数
- 对接监控和告警,关注延迟、吞吐、失败次数、checkpoint 成功率、反压
- 对外部 sink 考虑幂等或事务语义,避免重复写
一句话版:
“稳定性主要靠 checkpoint/savepoint、状态后端、重启策略、监控告警,以及对 sink 的一致性控制。”
一个简洁的面试答题模板
你可以按这个顺序答:
- 先说业务目标
- 再说数据链路
- 再说 Flink 用了什么能力
- 最后说稳定性保障
模板如下:
“这个场景我用 Flink 主要是为了做实时计算。数据从 Kafka/CDC 进来,先做解析清洗,再基于 Watermark 处理事件时间和乱序。指标类场景我一般用 keyBy + window + aggregate;如果是去重、画像、风控,就会用 ValueState、MapState、ListState 或 CEP。算完之后把结果写到 Redis、HBase、Kafka 或数仓下游。为了保证任务稳定运行,我会配置 checkpoint、savepoint、状态后端、重启策略,并接监控告警来看延迟、反压和 checkpoint 状态。”
3 分钟口述稿
“我平时使用 Flink,主要是在实时数仓、实时指标、用户行为分析、风控告警这几类场景里。一般数据源会来自 Kafka、业务日志或者 MySQL CDC,Flink 负责把这些实时数据接进来做清洗、分流、聚合和状态计算,最后再把结果写到 Kafka、Redis、HBase、MySQL 或者数据湖里,给大屏、推荐、告警和下游系统使用。
如果是实时指标类场景,比如 PV、UV、订单量、销售额、TopN 这种,我通常会用 keyBy + window + aggregate。keyBy 是按业务字段分组,比如按用户、商品、页面分组;window 是把无限流按时间切成一段一段来算,比如 1 分钟或 5 分钟;aggregate 是增量聚合,性能比较好。
如果是更复杂一点的场景,比如用户画像、去重、风控,我会更多使用 Flink 的状态能力。像 ValueState 适合存单个值,比如上一次行为或者当前计数;MapState 适合存用户访问历史或标签明细;ListState 常用于 TopN 这种先收集再排序的场景;如果要识别复杂行为模式,比如短时间连续小额交易后再来一笔大额交易,我会用 CEP 做模式匹配。
另外我会比较关注事件时间和乱序问题,所以一般会配 Watermark。如果有脏数据、超时数据或者错误日志,我会通过 Side Output 把它们从主流里分出去单独处理。
在稳定性方面,我通常会开启 checkpoint,让任务失败后可以从最近一次状态恢复;版本升级或者任务迁移时会用 savepoint。如果状态比较大,会考虑合适的状态后端,比如 RocksDB。上线之后还会关注监控和告警,比如任务延迟、反压、checkpoint 成功率、失败重启次数这些指标。
所以如果面试官问我怎么使用 Flink,我一般不会只说‘我消费 Kafka 做计算’,而是会从数据来源、计算链路、Flink 能力点和稳定性保障这四个方面去讲,这样会更完整,也更像真实做过项目的人。”
如果你愿意,我可以下一条继续帮你把这份口述稿压缩成“1 分钟版”和“面试追问版”。
五、回答问题总结
-
如何去去计算出来数据指标
- 业务流转
- 水电费
- 业务流转


浙公网安备 33010602011771号