示例工程【免费下载链接】awesome-low-level-designLearn Low Level Design (LLD) and prepare for interviews using free resources.项目地址https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design点击查看免费下载本文以开源仓库 awesome-low-level-design 中 problems/movie-ticket-booking-system.md 为骨架系统讲解如何从零设计一个类似 BookMyShow 的电影票预订系统先厘清需求再构建类与枚举模型最后结合仓库中 Java、C、Go、C# 等五套真实实现深入剖析座位并发预订、支付确认、取消释放等核心流程帮助读者掌握 LLD 面试中高并发共享资源 状态机 设计模式的完整答题范式。需求分析一个电影票预订系统要解决什么原文档用 8 条需求勾勒出系统的完整能力边界它们是后续一切类设计、并发策略与扩展点的基础影片浏览系统应允许用户查看不同影院正在上映的电影列表选片选场用户能够选择电影、影院和场次时间来预订门票选座系统应展示所选场次的座位布局并允许用户选择座位支付确认用户应能完成支付并确认预订并发一致性系统应处理并发预订并确保座位可用性实时更新差异化定价系统应支持不同类型的座位如普通座、优选座及对应价格运营管理影院管理员应能新增、更新和移除电影、场次与座位布局可扩展性系统应能扩展到支撑大量并发用户和预订。其中第 5 条并发预订下的座位一致性是整个系统的技术难点也是 LLD 面试最常深挖的点。仓库的各语言实现为此给出了三种不同的并发解法详见后文并发设计一节可直接对照学习。UML 类图一张图看懂系统全貌原文档给出了系统的类图位于仓库 class-diagrams/movieticketbookingsystem-class-diagram.png完整呈现了 Movie、Theater、Show、Seat、Booking、User 等核心类以及 SeatType、SeatStatus、BookingStatus 等枚举之间的关联关系从类图可以直观看出系统遵循实体—状态—服务的经典 LLD 结构实体类Movie/Theater/Show/Seat描述静态数据状态枚举SeatStatus/BookingStatus驱动业务流转服务类MovieTicketBookingSystem对外提供预订编排入口。核心类、接口与枚举设计原文档用 13 条定义了系统的完整类模型这是面试中必须能默写出来的核心骨架。以下逐条展开并结合仓库源码给出字段级细节。1. Movie电影Movie类表示一部电影属性包括 ID、片名、简介和时长。C 实现中对应 Movie.hppJava 实现中对应 Movie.javaGo 实现的 movie.go 还会携带语言language字段Java README 中补充了String id, String title, int duration, String language的字段明细。2. Theater影院Theater类表示影院属性包括 ID、名称、位置以及场次列表。C 实现在 Theater.hpp通过getShows()对外暴露其场次集合Java 实现还引入了Cinema / City / Screen三级模型见 Cinema.java、City.java、Screen.java粒度更细、更贴近 BookMyShow 的真实层级。3. Show场次Show类表示某影院的电影场次属性包括 ID、电影、影院、开始时间、结束时间以及座位映射表。C 实现的 Show.hpp 用std::vectorbool seats记录座位占用true 表示已预订并提供isSeatAvailable(int)、bookSeat(int)、cancelSeatBooking(int)、getAvailableSeats()等座位操作Go 实现的 show.go 则以map[string]*Seat按座位 ID 索引。4. Seat座位Seat类表示场次中的一个座位属性包括 ID、行、列、类型、价格和状态。Go 实现的CreateSeats(rows, columns)见 movie_ticket_booking_system.go给出了一个非常实用的初始化范例按行号生成row-col形式的座位 ID前两排row 2设为优选座并定价 150其余为普通座定价 100——正好印证不同座位类型 差异化定价的需求 6。5. SeatType 枚举定义座位类型NORMAL普通或PREMIUM优选。见 Java 实现的 SeatType.java 与 C# 实现的 SeatType.cs。6. SeatStatus 枚举定义座位状态AVAILABLE可预订或BOOKED已预订。注意 Java 实现在此基础上扩展出了第三种状态LOCKED锁定中用于选座后、支付前的占位窗口期这一细节是并发设计的点睛之笔见 SeatStatus.java 与 SeatLockManager.java。7. Booking预订单Booking类表示用户的一笔预订属性包括 ID、用户、场次、所选座位、总价和状态。C 实现的 Booking.hpp 完整记录了customerName、customerPhone、seatNumbers、totalAmount与时间戳并通过calculateTotalAmount()汇总票价Java 实现则用Booking.BookingBuilder链式构造见 BookingManager.java体现了 Builder 模式在复杂对象构建上的价值。8. BookingStatus 枚举定义预订状态PENDING待确认→ CONFIRMED已确认→ CANCELLED已取消。C 实现见 Booking.hppGo 实现见 types.go这是一条典型的状态机流转链创建时处于 PENDING支付成功转为 CONFIRMED取消则转为 CANCELLED 并释放座位。9. User用户User类表示系统的使用者属性包括 ID、姓名和邮箱。见 User.java 与 Go 的 user.go。10. MovieTicketBookingSystem门面式主类MovieTicketBookingSystem是系统的主控类采用Singleton单例模式保证全局唯一实例。这一设计在 Go 实现中体现得最为典型movie_ticket_booking_system.go 使用sync.Once实现线程安全的懒加载单例var ( instance *MovieTicketBookingSystem once sync.Once ) func GetBookingSystem() *MovieTicketBookingSystem { once.Do(func() { instance MovieTicketBookingSystem{ ... } }) return instance }11. 主类的核心方法MovieTicketBookingSystem 提供两类操作管理操作添加电影、添加影院、添加场次addMovie/addTheater/addShow业务操作预订门票、确认预订、取消预订bookTicket/confirmBooking/cancelBooking。C 实现的 BookingSystem.hpp 方法签名如下可作为各语言版本的统一参考void addMovie(Movie* movie); void addTheater(Theater* theater); Booking* createBooking(std::string showId, std::string customerName, std::string customerPhone, const std::vectorint seats); bool cancelBooking(std::string bookingId); void displayMovies() const; void displayShows(std::string movieId) const;12. 并发数据结构多线程环境下系统使用ConcurrentHashMap等并发容器处理对 Show、Booking 等共享资源的并发访问。Java 的 SeatLockManager.java 正是这一策略的载体private final MapShow, MapSeat, String lockedSeats new ConcurrentHashMap(); private final ScheduledExecutorService scheduler Executors.newScheduledThreadPool(1);13. Demo 演示类MovieTicketBookingDemo类演示完整流程添加电影、影院、场次 → 预订座位 → 支付确认 → 取消预订。各语言入口分别为 BookingDemo.cpp、MovieBookingDemo.java、movie_ticket_booking_system_demo.go 与 C# 的 MovieBookingDemo.cs。预订主流程从选座到确认的调用链以 C 实现 BookingSystem.cpp 为例createBooking是一条清晰的五步调用链也是所有语言版本的公共骨架校验场次通过findShow(showId)定位场次且要求其状态为SCHEDULED否则直接返回空指针校验座位遍历用户选中的每个座位号调用show-isSeatAvailable(seatNumber)任一不可用即整体失败保证要么全选、要么全不选的原子语义占座全部通过后逐个调用show-bookSeat(seatNumber)锁定座位生成订单generateBookingId()自增生成B1、B2...形式的订单号构造 Booking 对象并统计总价确认入账将订单状态置为CONFIRMED并加入 bookings 列表返回。取消流程BookingSystem.cpp则是对称的找到订单 → 校验未取消 → 遍历订单座位调用show-cancelSeatBooking()释放 → 订单置为CANCELLED。Go 实现 movie_ticket_booking_system.go 采用先建 PENDING 订单、再显式确认的两阶段模型BookTickets只校验并占座、返回BookingStatusPending的订单ConfirmBooking再将状态推进为BookingStatusConfirmed——这与原文档预订 → 支付 → 确认的需求 4 完全对齐也更贴近真实支付网关异步回调的场景。并发设计三种语言的三种解法原文档第 12 条明确要求处理并发预订并实时更新座位可用性仓库三种语言实现给出了不同粒度的参考答案C单线程简化版 显式状态机C 版本Show.cpp以vectorboolSCHEDULED/RUNNING/COMPLETED/CANCELLED场次状态机保证逻辑正确性适合面试中先讲清原子选座的业务语义再谈加锁升级。Java座位级锁 定时解锁Java 版本的 SeatLockManager.java 是最值得精读的并发实现以Show 对象为锁粒度synchronized (show)保证同一场次的选座操作原子化引入LOCKED中间状态选座时先置SeatStatus.LOCKED并记录座位 → 用户的归属映射防止他人抢占引入锁超时自动释放LOCK_TIMEOUT_MS 500ms注释明确说明真实世界应为分钟级通过ScheduledExecutorService调度unlockSeats定时回滚防止用户支付超时造成死锁SeatLockManager.java解锁时校验仍由同一用户持有showLocks.get(seat).equals(userId)避免误释放他人已支付的座位。BookingManager.createBookingBookingManager.java将这段流程串成完整管线锁座 → 按定价策略算价 → 支付 → 支付成功则建单并确认mark BOOKED→ 清理锁支付失败则座位会在超时后自动回滚为 AVAILABLE。Go全局读写锁 原子计数Go 版本movie_ticket_booking_system.go用sync.RWMutex保护全系统状态BookTickets/CancelBooking/AddShow等写操作加写锁GetShow读操作加读锁订单号生成使用atomic.AddInt64原子递增配合时间戳生成BKG20060102150405000001风格的全局唯一订单号movie_ticket_booking_system.go。sync.Once单例与 RWMutex 的组合是 Go 面试中高并发安全的标准答案。设计模式在系统中的落点原文档虽只点名 Singleton但仓库实现实际用到了四类设计模式可在面试中作为加分项展开模式落点仓库证据Singleton全局唯一的 MovieTicketBookingSystemmovie_ticket_booking_system.go 的sync.OnceStrategy支付方式与定价策略可插拔PaymentStrategy.java、WeekdayPricingStrategy.java、WeekendPricingStrategy.java工作日/周末差异化定价正好承接需求 6Observer座位变动/影片状态变更通知用户MovieSubject.java、UserObserver.javaBuilder构造字段繁多的 Booking 对象BookingManager.java 的Booking.BookingBuilderC# 实现与 Java 实现结构高度对称Strategies/Payment 与 Strategies/Pricing 目录见 solutions/csharp/movieticketbookingsystem适合对照学习跨语言的模式迁移写法。扩展方向与运行方式原文档 README 给出了清晰的扩展路线见 solutions/java/src/movieticketbookingsystem/README.md接入真实支付网关、增加交互式选座 UI、按座位类型扩展定价档位、实现高级排片算法、增加订票确认与提醒通知、开放用户影评功能。Java 实现还预定义了SeatNotAvailableException、InvalidShowException、BookingFailedException、CancellationFailedException等异常体系README.md可作为生产化改造的起点。各语言实现的完整代码与运行入口Javasolutions/java/src/movieticketbookingsystem入口 MovieBookingDemo.javaCsolutions/cpp/movieticketbookingsystem入口 BookingDemo.cppGosolutions/golang/movieticketbookingsystem入口 movie_ticket_booking_system_demo.goC#solutions/csharp/movieticketbookingsystem入口 MovieBookingDemo.csPythonsolutions/python/movieticketbookingsystem面试答题要点总结基于原文档 13 条类设计与仓库五套实现回答设计一个 Movie Ticket Booking System时可依此展开先立需求复述浏览、选场、选座、支付、并发一致性、差异化定价、运营管理 8 条需求体现需求驱动设计再画类图以 Movie / Theater / Show / Seat / Booking / User 三个枚举为核心可对照 类图 说明关联关系然后讲流程describe 预订五步链校验场次 → 校验座位 → 占座 → 建单 → 确认与取消对称流程最后谈并发引用synchronized (show)座位锁 LOCKED状态 定时解锁Java、sync.RWMutexsync.OnceGo、ConcurrentHashMap需求 12 原文三套方案展示你不仅能画类图、还能解决抢同一张票这类真实工程问题。赞分享示例工程【免费下载链接】awesome-low-level-designLearn Low Level Design (LLD) and prepare for interviews using free resources.项目地址https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design点击查看免费下载相关推荐三步打造专属AI管家MiGPT让小爱音箱秒变ChatGPT语音助手三步打造专属AI管家MiGPT让小爱音箱秒变ChatGPT语音助手 你是否曾幻想过家里的智能音箱能像电影里的AI助手一样真正理解你的需求、记住你的喜好、陪示例工程Async核心API速览parallel、series与waterfall三大并发模式如何选择Async核心API速览parallel、series与waterfall三大并发模式如何选择 Async 是一个用于 Node.js 和浏览器的异步任务工具示例工程MarkItDown 复杂表单式 PDF 转 Markdown 实战解析以影院订场订单movie-theater-booking-2024为例MarkItDown 复杂表单式 PDF 转 Markdown 实战解析以影院订场订单movie theater booking 2024为例 MarkI人工智能AI 应用MCP 服务上一篇Data-Science-For-Beginners 执行 docsify serve 提示 command not found 怎么排查下一篇Yii 2数据导出功能完全指南Excel与PDF生成实用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考