跳转到内容

17. Twitter/X 短内容平台

你想做一个个人微博,记录日常想法。280字限制,按时间线展示。

用纯前端实现发推、时间线展示、字数限制,数据存localStorage。

帮我用纯HTML+CSS+JavaScript实现一个Twitter风格微博:
1. 发推功能:
- 文本输入框,280字符限制
- 实时显示剩余字数(最后20字变黄,最后0字变红)
- 超过280字禁止发送
- 发送按钮在有内容时才可点击
2. 时间线展示:
- 按时间倒序显示所有推文
- 每条推文显示:头像(默认)、用户名、内容、发布时间、点赞数、转发数
- 时间显示:"刚刚""5分钟前""2小时前""昨天""3月15日"
3. 互动:
- 点赞:心形图标切换
- 转发:计数+1(仅模拟计数)
- 删除自己的推文
4. 数据存储:localStorage持久化所有推文
5. 简单统计:页面显示总推文数、总获赞数
6. UI细节:
- 推文之间分割线
- hover时显示操作按钮
- 发送后输入框清空,新推文出现在顶部(有动画)
纯原生JS,CSS模仿Twitter简洁风格。
  • 超过280字无法发送
  • 时间线按时间倒序
  • 时间显示为人性化格式
  • 点赞状态刷新后保留
  • 删除推文正常工作
  • 字符计数和输入限制 → Module: 表单处理
  • 人性化时间格式化 → Module: 日期处理
  • localStorage的容量限制(约5MB) → Module: 浏览器存储

10个朋友要一起用,需要后端支持多用户、关注关系和个人时间线。

Go后端实现发推、关注、时间线查询,SQLite存储。

帮我用Go+Gin+SQLite实现Twitter后端:
1. 数据模型:
- users: id, username, display_name, bio, created_at
- tweets: id, user_id, content(280字限制), reply_to_id(可null), created_at
- likes: user_id, tweet_id, created_at
- follows: follower_id, following_id, created_at
2. 核心API:
- POST /api/tweets — 发推(校验280字)
- DELETE /api/tweets/:id — 删除(只能删自己的)
- POST /api/tweets/:id/like — 点赞/取消
- POST /api/tweets/:id/reply — 回复(也是一条tweet,reply_to_id指向原推)
3. 时间线:
- GET /api/timeline — 首页时间线(自己+关注的人的推文)
- GET /api/users/:id/tweets — 某用户的推文列表
- 分页:cursor-based,基于tweet ID倒序
4. 关注:
- POST /api/users/:id/follow — 关注
- DELETE /api/users/:id/follow — 取关
- GET /api/users/:id/profile — 用户资料+推文数+粉丝数+关注数
5. 回复链:
- GET /api/tweets/:id/thread — 获取一条推文及其所有回复(树形)
- 递归查询reply_to_id构建回复链
SQLite单文件,不需要额外服务。注意280字限制是UTF-8字符数而非字节数。
  • 280个中文字符可以发送,281个被拒绝
  • 首页时间线只显示自己和关注的人
  • 回复链正确形成树形结构
  • 用户资料统计数据准确
  • cursor分页正确
  • 字符数 vs 字节数的区别 → Module: 字符编码
  • 自引用关系(tweet回复链) → Module: 树形数据结构
  • 社交关系的SQL查询 → Module: SQL进阶

100人的时间线查询开始变慢(JOIN follows + tweets),需要预计算时间线。用Redis缓存加速。

实现推模式(Fan-out on write),发推时预写入粉丝的时间线缓存。

在V2基础上实现Fan-out推送:
1. 存储升级:SQLite → PostgreSQL
2. 推模式实现:
- 用户发推时:
a. 写入tweets表
b. 查询所有粉丝ID
c. 异步把tweet_id写入每个粉丝的Redis List: timeline:{user_id}
- 异步分发用goroutine + channel
- 每个用户的时间线保留最近1000条
3. 时间线读取:
- 从Redis List获取tweet_id列表
- 批量查询tweet详情(Redis缓存:tweet:{id} → JSON)
- 缓存未命中回查DB
4. 写入优化:
- 批量写入:一次LPUSH多个粉丝的timeline
- 分发失败重试(最多3次)
5. 数据一致性:
- 删推时从所有粉丝timeline中移除(异步)
- 新关注时回填最近20条推文到timeline
- 取关时清理timeline中该用户的推文
6. 降级:Redis不可用时降级为DB查询
提供docker-compose.yml包含PostgreSQL和Redis。
  • 发推后粉丝timeline中立即出现
  • timeline读取<50ms(Redis命中时)
  • 删推后从粉丝timeline中消失
  • 新关注后回填了历史推文
  • Redis不可用时仍能查看timeline
  • Fan-out on write模式 → Module: Feed系统
  • 写扩散的成本分析(粉丝越多写越多) → Module: 系统权衡
  • Redis List作为时间线存储 → Module: Redis数据结构
  • 异步分发和最终一致性 → Module: 异步架构

用户开始讨论热门话题,需要Trending热搜功能。支持#Hashtag标签,实时统计热度。

实现Trending热搜算法(带时间衰减),Hashtag索引和话题页。

在V3基础上实现热搜和话题系统:
1. Hashtag系统:
- hashtags表:id, name, tweet_count
- tweet_hashtags表:tweet_id, hashtag_id
- 发推时正则提取#标签,写入关联表
- 标签页:GET /api/hashtags/:name/tweets — 该标签下的推文
2. Trending热搜算法:
- 时间窗口:最近4小时
- 热度公式:score = tweet_count / (hours_since_start + 2)^1.5
- 也就是:新出现且增长快的话题排在前面
- 每5分钟重新计算一次Top 30热搜
- 存入Redis Sorted Set: trending → {hashtag: score}
3. Trending API:
- GET /api/trending — Top 30热搜列表
- 每条包含:标签名、热度分数、最近1小时推文数
4. 热搜详情页:
- GET /api/trending/:tag — 该话题的推文流(按热度或时间排序)
- 话题统计:参与人数、推文总数、趋势图数据
5. 搜索增强:
- GET /api/search?q=xxx — 搜索推文内容(PostgreSQL全文搜索)
- 支持中文(pg_trgm或zhparser)
- 搜索结果按相关度+时间排序
6. 敏感词过滤:
- 热搜上榜前检查敏感词列表
- 管理员可手动下架热搜
重点实现Trending算法的衰减公式和定时计算。
  • 发推中的#标签被正确提取
  • 热搜排序合理(新热话题靠前)
  • 冷门旧话题随时间衰减下落
  • 搜索能找到中文推文
  • 管理员能手动下架热搜
  • 热度排序算法(Hacker News/Reddit风格) → Module: 排序算法
  • 时间衰减函数设计 → Module: 数学在工程中的应用
  • PostgreSQL全文搜索 → Module: 数据库全文搜索
  • 正则提取Hashtag → Module: 文本处理

出现了粉丝过万的”大V”,纯推模式发一条推要写入上万个粉丝timeline,太慢。普通用户推模式够用,大V需要拉模式。

实现推拉混合模式:大V用拉模式,普通用户用推模式,兼顾性能和实时性。

在V4基础上实现推拉混合Feed:
1. 用户分级:
- 普通用户(粉丝<1000):推模式
- 大V用户(粉丝>=1000):拉模式
- 阈值可配置
2. 推模式(不变):
- 发推时写入所有粉丝的timeline(粉丝少,写入快)
3. 拉模式:
- 大V发推只写入自己的推文列表,不扇出
- 读取timeline时:
a. 从Redis获取推模式推文
b. 查询所关注的大V的最新推文
c. 合并排序,取最新N条
4. 合并排序优化:
- 每个大V最多拉最近20条
- 用归并排序合并多个有序列表
- 结果缓存5分钟
5. 实时搜索(近实时):
- 新推文写入Elasticsearch(异步,延迟<5秒)
- 搜索支持:内容、用户名、标签
- 实时搜索和历史搜索分开(最近1小时用实时索引)
6. 性能对比测试:
- 模拟:1个1万粉丝大V发推
- 对比纯推模式 vs 混合模式的耗时
- 对比读取timeline的延迟
提供docker-compose.yml增加Elasticsearch。
  • 大V发推不写入粉丝timeline
  • 粉丝读timeline时拉取大V推文并正确合并
  • 合并后的timeline按时间有序
  • 搜索延迟<5秒
  • 混合模式下大V发推耗时显著减少
  • 推拉混合模式的设计取舍 → Module: Feed系统高级
  • 多路归并排序 → Module: 算法应用
  • 用户分级策略 → Module: 系统分层设计
  • Elasticsearch近实时索引 → Module: 搜索引擎

平台走向国际化,用户遍布多个国家。需要多区域部署降低延迟,同时引入广告变现。

多区域部署方案、时间线分片策略、广告投放引擎。

设计并实现全球化Twitter架构:
1. 多区域部署架构:
- 区域:亚洲(新加坡)、北美(弗吉尼亚)、欧洲(法兰克福)
- 每个区域完整的服务栈(API+Redis+ES)
- 用户就近接入(GeoDNS或Anycast)
- 写入路由到用户归属区域,跨区域异步同步
2. Timeline分片:
- 按user_id范围分片
- 分片策略:consistent hashing
- 每个分片独立的Redis实例
- 跨分片查询(关注了不同分片的用户)的合并策略
3. 跨区域数据同步:
- 推文写入:先写本区域,异步复制到其他区域
- 关注关系:全局一致(用主区域作为source of truth)
- 冲突处理:last-write-wins
- 容忍延迟:跨区域同步<2秒
4. 广告投放引擎:
- 广告库:ads表(id, content, target_audience, budget, bid_price, status)
- 投放逻辑:timeline中每N条插入一条广告
- 定向:按地区、兴趣标签、设备类型
- 竞价排序:eCPM = bid_price * 预估CTR
- 预算控制:实时扣减,余额不足下线
5. 反作弊:
- 检测刷推行为:短时间大量发推、内容高度相似
- 检测刷赞行为:同一IP大量点赞
- 风控规则引擎:匹配规则 → 标记风险 → 人工审核/自动处罚
6. 数据分析管道:
- 用户行为日志 → Kafka → 实时处理(Flink) → 指标计算
- 日报:DAU、推文量、互动量、广告收入
重点设计多区域同步方案和timeline分片策略,代码实现核心逻辑。
  • 不同区域用户发推在本地<100ms
  • 跨区域推文同步<2秒
  • 分片后timeline查询正确
  • 广告按eCPM排序投放
  • 反作弊检测到刷推行为
  • 多区域部署和数据同步 → Module: 全球化架构
  • Consistent Hashing分片 → Module: 分片策略
  • 广告系统的eCPM竞价模型 → Module: 广告系统
  • 反作弊和风控系统 → Module: 安全工程