拿个offer - 开源&项目实战 拿个offer - 开源&项目实战
首页
后端技术
🚀大话面试
  • 校&社招实战项目

    • 12306(铁路购票平台)
    • 短链接(Sass平台)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动)
  • 基础架构项目

    • 幂等基础组件(支持接口及多种MQ)
    • 企业基础架构组件库
  • 校&社招实战项目

    • 12306(铁路购票平台) (opens new window)
    • 短链接(Sass平台) (opens new window)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动) (opens new window)
加入群聊
🔋知识星球
代码仓库 (opens new window)
首页
后端技术
🚀大话面试
  • 校&社招实战项目

    • 12306(铁路购票平台)
    • 短链接(Sass平台)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动)
  • 基础架构项目

    • 幂等基础组件(支持接口及多种MQ)
    • 企业基础架构组件库
  • 校&社招实战项目

    • 12306(铁路购票平台) (opens new window)
    • 短链接(Sass平台) (opens new window)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动) (opens new window)
加入群聊
🔋知识星球
代码仓库 (opens new window)
  • 项目介绍

    • 什么是12306
    • 校招更适合12306
    • 技术架构选型
    • 接口文档
    • 控制台手册
    • 如何学习12306
    • 项目真实面经
  • 快速开始

    • 环境搭建
    • 快速启动(后端项目)
    • 快速启动(前端项目)
    • 用户体系建设概要
    • 揭秘车票查询背后的复杂性
    • 探索座位分配的奥秘
      • 座位分配背景
      • 座位分配难点
      • 座位分配逻辑
    • 一张车票引发的连锁反应
    • 用户支付流程解析
  • 核心技术文档

    • 如何生成分布式ID
    • 如何使用Builder模式创建线程池
    • 责任链模式重构复杂业务场景
    • 死磕设计模式之抽象责任链模式
    • 策略模式在项目设计中用得最多
    • 死磕设计模式之抽象策略模式
    • 策略模式和简单工厂如何选
    • 注册用户防止缓存穿透
    • 为什么是Redisson分布式锁?
    • 缓存击穿不止是分布式锁
    • 缓存一致性如何解决?
    • 选择合适的缓存过期策略
    • 车站查询选ES还是Redis?
    • 物理&逻辑CPU信息查看
    • Java8并行流有坑!慎用
    • 如何使用线程池不容易出故障
    • 应用发布丢失线程池未完成任务
    • 详解雪花算法
    • 如何解决系统深分页问题
    • 查询千万数据避免内存溢出
    • 如何优雅记录操作日志
    • 后端应用返回实体统一
    • 尝试使用全局异常拦截器
    • 配置中心运行时动态变更
    • RocketMQ不支持SpringBoot3?
    • RocketMQ消息如何不丢失?
    • 如何做用户提交HTTP接口幂等
    • 消息队列正确使用姿势
    • 消息队列重复消费消息
    • 订单延时关闭功能技术选型
    • 如何防止配置文件敏感信息泄漏
    • 如何防止用户敏感数据泄露
    • 如何快速玩转最新版Apache ShardingSphere
    • 如何防止用户敏感数据泄露
    • 为什么分库分表前先尝试读写分离
    • Apache ShardingSphere Proxy 入门到实战
    • 用户和乘车人数据如何分库分表
    • 乘车人数据如何实现分片
    • 订单数据冷热分离还是分库分表
    • 为什么推荐你学学影子库
    • 熔断限流Hystrix还是Sentinel?
    • Sentinel限流配置持久化
    • 链路追踪只会SkyWalking?带你玩点不一样的
    • 分布式日志平台ELK
    • 监控平台采集应用运行时指标
    • 车票相关接口如何防刷?
  • 手摸手从零到一实现

    • 手摸手之梳理核心业务
    • 手摸手之学习数据库表结构信息
    • 手摸手之工程目录结构如何设计
    • 手摸手之创建SpringBoot单模块
    • 手摸手之创建SpringBoot多模块
    • 手摸手实现基础组件模块
    • 手摸手实现规约组件模块
    • 手摸手实现用户基础组件库
    • 手摸手实现设计模式组件库
    • 手摸手实现公共组件库
    • 手摸手实现缓存组件库
    • 手摸手实现持久层组件库
    • 手摸手实现分布式ID组件库
    • 手摸手实现日志组件库
    • 手摸手实现接口幂等组件库
    • 手摸手实现消息队列幂等组件库
    • 手摸手实现Web组件库
    • 手摸手之创建应用模块
    • 手摸手之掌握架构师的编程规范
    • 手摸手之代码格式化很重要
    • 手摸手之代码检查很重要
    • 手摸手之从创建用户接口开始
    • 手摸手之乘车人模块开发
    • 手摸手之车站模块开发
    • 手摸手之车票模块开发
    • 手摸手之初始化车站数据
    • 手摸手之初始化车票数据
    • 手摸手之订单模块开发
    • 手摸手之支付模块开发
    • 手摸手之网关模块开发
    • 手摸手之项目中设计模式详解
    • 手摸手之全局缓存使用概述
    • 手摸手之全局消息队列使用概述
  • 面试系列

    • 如何把12306写到简历上
    • 面试官问12306项目怎么来的?
    • 快手校招一面(12306面试真题)
    • 理想汽车一面(12306面试真题)
    • 小红书提前批(12306面试真题)
    • 宁德时代一面(12306面试真题)
    • 快手提前批一面(12306面试真题)
    • 百度秋招提前提一面
    • 微医校招一面(12306面试真题)
    • 阿里淘天ToB一面(12306面试真题)
    • 快手风控一二面(12306面试真题)
    • 用友网络秋招一面
    • 美团秋招一二面(12306面试真题)
    • 腾讯电竞一二面
    • 美团到家秋招一面(12306面试真题)
  • 面试常见问题解答

    • 列车数据查询为什么用Redis而不是ES
    • 列车数据查询有没有数据检索功能
    • 创建订单并支付后延时关闭订单消息怎么办?
    • 缓存击穿之双重判定锁如何优化性能?
    • 项目什么场景使用线程池?参数如何设置?
    • 购买列车余票如何防止库存超卖?
    • 节假日高并发购票Redis能扛得住么?
    • 用户注册布隆过滤器容量设置以及碰撞率问题
    • 购买列车中间站点余票如何更新?
    • 余票Binlog更新延迟问题如何解决?
    • 监听Binlog的RocketMQ如何保证顺序性?
    • 12306核心接口性能优化都做了什么?
  • 常见问题Q&A

    • 幂等组件HTTP应用场景是什么?
    • 线程池参数怎么配置比较合理?
    • 为什么采用构造器注入?
    • 高并发项目上线前如何进行压测?
    • 列车站点暂无余票?
    • 为什么分布式模式调用报错?
  • 发版记录

    • v1.0.0(2023-07-30)
目录

探索座位分配的奥秘

# 座位分配背景

当一家四口人出去玩在 12306 进行购票时,假定四个人都选择了商务座,你是想一家人被安排到各个不同的车厢还是在一个车厢不同座位还是一个车厢相邻座位?想都不用想,肯定是后者最好对不对。那如果要实现这个座位分配算法,却不是这么容易。

先放一张高铁商务座的座位分布图,复兴号商务座两排三座,一个车厢排除空座位,共 5 个可用座位,如下所示:

大家也可以去看下 12306 上实际购买复兴号高铁试试,一排三个座位,分别是 ACF。咱们系统都是严格按照原系统逻辑设计的。

# 座位分配难点

座位如果要想分配的合理,需要考虑的情况比较多,比如:

  • 单个车厢可能容纳不下购票乘车人数;
  • 单排座位可能容纳不下购票乘车人,需要根据不同座位类型拆成多排分配;
  • 单个车厢可能容纳的下购票乘车人,但没有相邻座位;
  • 选中座位类型车厢余量加一起都容纳不下购票乘车人的情况。

# 座位分配逻辑

考虑到种种情况,咱们的高铁座位分配算法流程如下,还是以商务座举例。

为了让咱们能更专注基本的座位分配算法,以下流程不包含购票人数大于等于三人(大于等于三人就要进行拆座位)以及在线选座等流程。

  • 如果购票人数为两人,购买同一车厢,座位优先检索两人相邻座位并排分配。
  • 假设当前正在检索的车厢不满足两人并排,就执行搜索全部满足两人并排的车厢。
  • 如果搜索了所有车厢还是没有两人并排做的座位,那么执行同车厢不相邻座位。
  • 如果所有车厢都是仅有一个座位,就开始执行最后降级操作,不同车厢分配。

这里生动形象的演示了几组用户购票对应的座位分配顺序,结合咱们流程查看理解更顺畅。

单一账号同时为两个乘车人购买车票,多个账号购票流程如下。

单一账号同时为两个以上乘车人购买车票,多个账号购票流程如下。

实际上的座位分配算法远比描述上要复杂的多,上面讲的是用户购买高铁座在没有人为选择座位的情况下逻辑。如果用户选择了座位后,算法又是不同的逻辑了。

考虑到大家的中心不需要放到这里,所以文章就没有详细描述算法的细节。感兴趣的同学可以通过 Debug 源代码的形式,掌握默认分配座位以及选座算法。

开源不易,文档库仅对已 Star 12306 项目的用户开放

仅需两步即可完成:

  • 1. 打开 12306 项目 开源仓库主页,右上角点个 Star

  • 2. 点击下方【同意授权检测】按钮,同意获取 API 权限进行检测

本章节文档,将在 Star 12306 仓库后正常开放展示

  • ✅ 同意授权检测
  • 🚀 面试常见问题

🚀 系统提示:访问文档失败 🚀

原因:开源不易,文档仅对已 Star 12306 项目的用户开放。

  • https://gitee.com/nageoffer/12306
  • https://github.com/nageoffer/12306

操作步骤:点击下方「Gitee 项目」和「GitHub 项目」按钮 Star 项目即可。 12306 所有端的代码都会完全开源,为了更好地完善这个框架,希望大家多多支持。

  • ✅ Gitee项目
  • ✅ GitHub项目
  • 🥳 加入交流群
上次更新: 2023/10/06, 19:56:18
揭秘车票查询背后的复杂性
一张车票引发的连锁反应

← 揭秘车票查询背后的复杂性 一张车票引发的连锁反应→

Theme by Vdoing | Copyright © 2022-2023 马丁玩编程 | Apache2 License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式