一辆车算 3000 张票
将每个站点都设置个标志位
0 为未出售 1 为已卖出
出 A-B 的票逻辑:
1.搜索有没有 A-B 标志位都为 0 的行
2.将该行 A-B 所有标志位设为 1
完全没难度啊,多一张票=多插入一行,大家看看这想法对不对
python 测试代码:
zhandian=['南通','如皋','泰州','江都','扬州','滁州北','蚌埠','合肥','庐江','桐城','安庆西','天柱山','太湖','南昌','吉安','信丰','龙川','河源','惠州','东莞东','深圳东'] #三千张票 tickets=[[0 for i in range(len(zhandian))] for x in range(3000)] def by_ticket(start,end): start_index=zhandian.index(start) end_index=zhandian.index(end) if end_index<=start_index: # 站点输入错误 return -3 for t in tickets: if t[start_index:end_index+1]==[0 for i in range(end_index-start_index+1)]: t[start_index:end_index+1]=[1 for i in range(end_index-start_index+1)] print('买到座位号{}的票 位置详情:{}'.format(t[0],t)) return t print('无票') return -1
1
ifxo 2020-01-22 17:25:50 +08:00
本来就没什么难度,说难的基本上都是菜鸟吧
|
2
zaima 2020-01-22 17:30:34 +08:00
一辆车 3000 个座位把
|
4
aurthur 2020-01-22 17:35:26 +08:00 via Android 14
没毕业吧?
|
5
kindjeff 2020-01-22 17:37:34 +08:00 via Android
收藏了
|
7
ayase252 2020-01-22 17:38:47 +08:00 via iPhone 4
空间复杂度 mn,时间复杂度 nm^2,m 是站数,n 是车票数。最 naive 的解法,想想还有没有可以优化的地方(面试感)
更别提还有区间锁票,每站预留这种操作了 |
11
kkkkkrua 2020-01-22 17:43:07 +08:00 via iPhone
线下售票,电话售票,要更新
|
12
Flobit 2020-01-22 17:44:02 +08:00
你这只是线上购票,线下购票的呢?
|
13
virusdefender 2020-01-22 17:45:22 +08:00 4
你说淘宝为啥这么复杂,想想不也就一个库存减 1 然后订单表插入一行么,放在实际的环境中,需要考虑的太多了,比如用户认证、风控、优惠券、缓存、锁表、持久化,消息队列、分布式事务等等等等。
|
14
zaima 2020-01-22 17:49:30 +08:00
@daboq 车能载多少是根据座位来决定的啊。我座位只有 2000 个,你怎么可以出 3000 张起点到终点的票呢?我座位有 4000 个,你根据什么情况来插入新行啊?
|
17
Qlccks2 2020-01-22 17:54:50 +08:00 via iPhone
也许很复杂,但是出票都是提前计算好的吧,并不是实时计算出票。
|
18
zaima 2020-01-22 18:06:25 +08:00
@daboq 你好好琢磨下把……为什么你的逻辑里,唯一确定的两个变量之一的 “座位” 这个变量没出现?另外,你只要假设是 3000 个座位而不是票的话,那么逻辑上并没有什么问题
|
19
newtype0092 2020-01-22 18:11:11 +08:00
确实简单,三流小电商站的水平,钱都被层层剥削贪污了。
建议你自己开发一套,卖给铁老大,要价 5 亿不接受还价,后半辈子吃穿不愁了。 |
20
Torpedo 2020-01-22 18:12:22 +08:00
你这只是单一的逻辑。当大量用户买票的时候,同步你这个票务信息、决定谁买到票复杂度会上升。
|
21
narfnas 2020-01-22 18:21:40 +08:00
难在开票时间点要接收大量用户的抢票,还有抢票软件的。
|
22
Raynard 2020-01-22 18:24:27 +08:00 via Android
推倒重建,会简单很多吧,相比当年
|
23
okjb 2020-01-22 18:28:24 +08:00 via Android
你这逻辑,上万辆车都不够你用🤣
|
24
shiran3f 2020-01-22 18:43:03 +08:00 via iPhone 5
唉,程序员不懂业务就是这么来的,脱离实际一个人在那边瞎猜,我手下的小弟不知道被我打脸多少次了,不要自己猜猜猜!这本质和键盘侠没区别。
|
25
andylsr 2020-01-22 19:16:34 +08:00 via Android
开一万个客户端跑下你的代码试试?
|
26
lance6716 2020-01-22 19:19:20 +08:00
宁这个没法并发?
|
27
xujinkai 2020-01-22 21:10:07 +08:00
看来 12306 后台也就百来行代码(滑稽
|
28
Helsing 2020-01-22 23:20:47 +08:00 via iPhone
优秀
|
29
Eleutherios 2020-01-23 00:06:43 +08:00 via iPad 2
“这是个出票逻辑,其他方面没考虑那么多,讨论逻辑方面,不是要做个 12306”
这句话笑死我了。 |
30
litmxs 2020-01-23 01:23:56 +08:00 via Android
讨论就好好讨论,上面一些阴阳怪气的,自己也说不出个所以然,就在那嘲讽
|
31
daimubai 2020-01-23 01:35:27 +08:00 via iPhone
单就最后一句只考虑出票逻辑,这玩意还用单独开个贴?会加减法都知道,只考虑出票逻辑有讨论的意义吗?最次也得有个并发吧,有个实时同步检测吧
|
32
ThirdFlame 2020-01-23 08:53:08 +08:00 1
假设此车 起点为'南通' 终点为'深圳东'。 没有任何限售限制。全列 1000 个座位(暂不考虑卧铺,全部为普通座位。)
如果有人买了 '南通' -'深圳东' 那么南通之后所有车站的可售车票-1。 如果有人买了 '东莞东'-'深圳东',东莞东之前的所有车站到深圳东的车票-1。 如果有人买了 '南通' -'天柱山',那么天柱山之前车站到天柱山的车票-1,天柱山 到 天柱山之后的车站车票+1。 如果有人买了 '合肥'-‘天柱山’,那么合肥之前车站到 ‘合肥’、‘天柱山’区间车票-1. 天柱山到天柱山之后车票+1. 复杂度 请考虑一下。 所以要有专门的客票组织部门,指定合理的车票限售和预留。 还要计算上座位复用。 |
33
daboq OP @ThirdFlame 大佬你看明白了没?复杂度 O(N),预留前面说了改标志位就行,卧铺无座加个字段
|
34
gamexg 2020-01-23 10:32:08 +08:00
这个方案并不方便,
感觉目前应该使用的这种方案: a-e 的线路,预先分配好 a-e、a-b、a-c、a-d、b-c、b-d、b-e 等的票数,kv 数据库都够了,查询余票直接 get 对应的 key 就行,买票直接-1,然后后台再去分配座位号。 可以预先给 a-e 多分配票,卖票时后台根据售票信息动态拆分。 |
35
daboq OP @gamexg 如果买了 a-e,那 a-b、a-c、a-d、b-c、b-d、b-e 都要减少一,如果是 30 个站点需要几百次修改,比这个方案复杂多了吧。
现在只需要查询 like ____00000__ 一步到位 |
36
gamexg 2020-01-23 10:53:51 +08:00
@daboq #35
根据业务经验及需求来预先分配,这样操作的: 比如共 3000 张票,多给 a-e 分配些,分配 a-e 1000 张, 另外 2000 张拆分配到详细区间,例如一张票可以拆分为 a-c、c-e 两个区间,放票时就固定拆分好。 查余票和买票时就比较简单了。 可以后台检查区间票,发现那个区间票低于预期值,可以决定是否后台拆分 a-e 的补区间票。 大体是这个意思,这个比较符合目前的区间无票,始发到终点的票却能够买到的情况。 |
37
gamexg 2020-01-23 11:03:35 +08:00 1
票池数据库大概这样:
key 是 线路-日期-车次-上车站点-下车站点-座位类型 ,value 就是座位数量。 买票操作就是直接对这行记录 -1,然后后台再分配座位号。 座位号可以用一个表保存,和票池对应,票池填充票时就生成座位表,每张票池的票对应一个座位记录。 大概这些字段:线路、日期、车次、上车站点、下车站点、座位类型、是否已使用、座位号 分配座位号时直接查找未使用的作为即可。 |
38
across 2020-01-23 11:23:27 +08:00 via iPhone 2
点开果然是新注册的 s b 小号,故意带节奏的
|
39
SjwNo1 2020-01-23 11:29:25 +08:00
别理了 你们理不明白的
|
40
est 2020-01-23 11:31:12 +08:00
反对 LZ 的也没提出反对的理由,就一个劲的喷。。。支持 LZ。我也觉得没多难。实际上 12306 最大的瓶颈就是查询。阿里云的解决办法就是上大内存机器。可以搜一下 zhihu 问答。
|
41
silencht 2020-01-23 12:47:41 +08:00 1
震惊! V 站出现大量图灵奖得主!
|
42
hyy1995 2020-01-23 13:28:40 +08:00
不愧是 V 站。我虽然说不出个所以然,但我不敢自大到“没觉得多难”,楼上几位要觉得自己有本事,可以去当 12306 CTO,我相信你们可以解决“12306 每次一到春节就抢不到票”的 bug。
另外,讨论就讨论,特意注册个小号,还憋了几天再发帖,至于吗。。。 |
43
firefox12 2020-01-23 13:28:45 +08:00
代码没问题, 但是就是结果未必是最优解。但是我也觉得可能就没有最优解。现在的规则也不是最优解。
但是业务 不是 O(n) 以 n 4000 个位子 m 30 站为例子, 你每次分票是需要扫描全数组的。 当然可以优化 但是扫描必须全表。 1 你需要扫描每个 n 的每个 m, 得出这个位子能不能出票 比如 有人要买 a-z, n=0 a...z 都是空的 符合买的条件 n=1 a...m 是空的 但是 l 不是空的,其实是不符合条件 得出一个符合要求的还不行 其次 你还需要做最优解 1, 3, 4, 6 , 7 符合要求,谁是里面最优的? a...z 是不用考虑的 如果是 m...t 的出票, 出在哪个位子上更好? 上中下铺需求?所以 高速的分票其实比这个复杂。 所以你描述的 O(n) 是不对的。 |
44
wangyzj 2020-01-23 13:59:49 +08:00
插眼收藏等撕逼
|
45
SlipStupig 2020-01-23 14:12:08 +08:00
你的代码确实可以完成简单售票,但是还是不能满足 12306 的变态需求,先说你这个代码一些问题吧:
1. 你这个设计车次是单向车次,实际情况一趟车会在起点<->终点反复开 2. 你从始发站开始卖票就一次性给卖完了,非始发站的用户上车怎么办?这样不是不能卖票而是成本比较高。 3. 还有一些情况是退改补,这个会影响整个票仓,结合你问题 2 的设计,就会出现火车上出现空座,但是别人也无法购买 4.团体票,团体票相当于批量确认且具有排他性,申请过后,会一次性占多个座位。 5. 票务类型座位不一致,不同等级的票务,座位数量是不一样的,你目前系统假设大家都是平等数量,谁优先抢占谁就有座位,实际情况并不是这样 目前只从票务角度上说,我觉得问题有这些,其它的风控和系统性能不再讨论范围内 |
46
wangxiaoaer 2020-01-23 14:45:06 +08:00 via Android
@ThirdFlame 楼主的意思每卖一张新增一条记录,不存在修改库存,但考虑到座位数有限,应该要限制这些记录的总条数不超。
|
47
iugo 2020-01-23 16:18:41 +08:00
难的不应该是最大收入吗?
说个简单的例子. 设有 3 个站点(A, B, C), 那么一个座位可能的收入是: A-C, 3 元 A-B, 2 元 B-C, 1.5 元 然后现在有人买 B-C 的票, 如果立刻卖了, 将来没人买 A-B 但有人买 A-C 就亏了 1.5 元, 如果不卖等 A-C, 将来有人买 A-B 就亏了 0.5 元. 排队是最好的办法, 先收钱, 符合最大利益就出票, 不符合就等着. 直到开车前不能等了, 就按照目前的最大利益出票. |
48
ThirdFlame 2020-01-23 16:27:52 +08:00
只考虑 买组织好的 一个座位 一条记录的票 ,这当然时间复杂度很低。 只需要遍历或者查询即可。
那这和库存减少 或者说 电影院的售票有何区别,没区别,静态的售票而已。 12306 难 不难在售出一个组织好的票。 而是一张票售出后 带来的其他票的调整和变化。 |
49
wysnylc 2020-01-23 17:41:19 +08:00 via Android
淘宝也不过就是个订单系统
|
50
whypool 2020-01-23 17:52:18 +08:00 via iPhone
大佬:不就是 crud 么,有啥难度?
|
51
hellov22ex 2020-01-23 18:08:32 +08:00
你是不是从来没有写过真正用于干活的代码?
12306 难的不是这个出票逻辑,而是让全国各地的代理、车站、个人准确的获取票,这个是最难的,出票逻辑是它的衍生。 假设北京到上海,票 3000 张,最高峰同时有 300 人退票、买票、刷新界面,这时候要保证他们如果下单买了,票是正确的,买到的票能上火车。 但是实际情况是,普通日子负载压力是 300,特殊日子负载压力是 500000。 |
52
hellov22ex 2020-01-23 18:09:36 +08:00
对了,我记得某一年有过负载数据的公布,你自己去看看,这种数据需要多少什么配置的硬件才能搞定。
|
53
yanheqi 2020-01-23 20:24:29 +08:00
回形针做过这方面的节目 <iframe src="//player.bilibili.com/player.html?aid=42125169&cid=73947630&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>
https://www.bilibili.com/video/av42125169/ |
54
leokino 2020-01-24 01:27:01 +08:00
没那么简单。必须要确保在最大程度上出票方案全程无空位,并不是单纯的抢占问题。假设 ABC 三个站点,BC 卖掉了,AC 就没法卖,而 AC 可能有 900 元的价值,BC 只有 50 元。12306 的出票方案必须是尽量达到每辆车的空置率都是最低的。
|
55
ebony0319 2020-01-24 09:59:16 +08:00 via Android
我比较赞同你的想法,我一直以为登月就三步骤 1 打开舱门,2 下去,3 拍照宣布自己登月成功。这个只要超过一岁小孩谁不会哇。
|
56
petelin 2020-01-24 10:59:06 +08:00 via iPhone
有什么好讨论的 连业务是什么都不清楚
所有人都是在臆想解决自己脑子里的问题 |
57
mysunshinedreams 2020-01-28 22:04:08 +08:00
坐井观天?
|
58
AllenHua 2020-09-26 14:31:55 +08:00
@ThirdFlame #32 居然看到了天柱山 阁下莫非潜山人
|
59
AllenHua 2020-09-26 14:33:18 +08:00
@ThirdFlame #32 不好意思 看错了 楼主的站点数组里 就有 天柱山
|
60
ThirdFlame 2020-09-26 18:59:57 +08:00
@AllenHua 天柱山爬过,在合肥出差的时候 租车去的。风景不错,不用缆车的话 一天行程刚刚好
|
61
AllenHua 2020-09-26 19:12:29 +08:00
@ThirdFlame #60 哈哈 谢谢谢谢
|