Before seeing someone analyze 12306 backstage logic. The booking and withdrawal of train tickets is different from ordinary shopping.
One problem is that train tickets can be sold in separate stations. For example, a Beijing to Shanghai train ticket, along the way can have many stations, can Beijing-Jinan, Jinan-Nanjing ... Wait a minute. How to design a data model to access these tickets is a problem. Rather than a simple number of +-1.
One of the ideas is very good: a binary string to represent a train ticket, for example, Beijing to Shanghai, a total of 10 stations, then a full ticket initial state as: ' 1111111111 ';
If a full ticket is sold, the ticket becomes ' 0000000000 ';
Sell a half ticket, such as Beijing-Jinan three stations (the first stop-the third station), the ticket into ' 0011111111 ';
Sell another half way ticket, such as Xuzhou-Nanjing (6th station-9th station), then the last ticket into: ' 0011100011 ';
The logic of the ticket back is very simple, I want to return a (Xuzhou-Nanjing) ticket, then find the first ticket from the pool can not buy
(Xuzhou-Nanjing) ticket, change it on OK (the reverse of the ticket). For example, find the top ticket ' 0011100011 ',
After the refund, the ticket becomes (0011111111);
The basic logic as above, 12306 to ensure that multiple access, while the consistency of data, requires very efficient logic to deal with the ticket,
Buy tickets, refund business, the peak is said to be 200,000 requests per second. The data structure of the ticket is saved in memory. Rather than a database.
Small and efficient data knots become important.
Copy Code code as follows:
if (jQuery) {}else{
document.write
}
function Server () {
var self = this;
Self.ticketspool = [];
self._init= function (number) {
if (typeof (number)!= ' number ')
Throw (' type error ');
for (i=0;i<number;i++) {
Self.ticketsPool.push (New Ticket ());
}
};
To determine whether a ticket can be bought, through the and or operation to achieve.
For example: Order O for Beijing-Jinan (001111111), a ticket for (0000000011) (has sold Beijing-Nanjing), then return false
For example: Order O for Beijing-Jinan (001111111), a ticket for (1111100011) (had sold Xuzhou-Nanjing), then return True
Self.canbuy = function (o,t) {
var _o = '
For (j=0 j<o.length; j + +) {
_o + = o[j]== ' 0 ' 1:0;
}
var r1 = (parseint (t.tic,2) | parseint (o,2)) & parseint (_o,2);
var r2 = parseint (_o,2);
return R1 = = R2;
};
Sell a ticket
Self.pop1ticket = function (o) {
For (I=0;i < self.ticketspool.length;i++) {
if (Self.canbuy (O,self.ticketspool[i])) {
Self.buy (Self.ticketspool[i],o);
return i;
}
};
return-1;
};
The realization of the selling ticket, change the binary string, such as ' 111111111 '-> ' 001111111 ';
Self.buy = function (t,o) {
T.tic = (parseint (t.tic,2) & parseint (o,2)). toString (2);
alert (t.tic);
};
Check the remaining votes
Self.remaintics = function (o) {
var count=0;
For (I=0;i < self.ticketspool.length;i++) {
Count + = Self.canbuy (O,self.ticketspool[i])? 1:0;
};
return count;
}
Refund, or operation
Self.refund = function (o) {
For (I=0;i < self.ticketspool.length;i++) {
if (!self.canbuy (O,self.ticketspool[i])) {
var _o = '
For (j=0 j<o.length; j + +) {
_o + = o[j]== ' 0 ' 1:0;
}
Self.ticketspool[i].tic = (parseint (self.ticketspool[i].tic,2) | parseint (_o,2)). toString (2);
return i;
}
};
return-1;
}
}
Data Model: Ticket
function Ticket () {
var self = this;
The original ticket is the full ticket.
self.tic = ' 1111111111 ';
}
Data Model: Order
function order (from, to) {
var self = this;
var s = ';
for (i=0;i<10;i++) {
S + + (I>=from && i<to) 0:1;
}
return s;
}
12306 Backstage
Server = new server ();
Initial state, ticket pool has 400 full tickets
Server._init (400);