I saw someone analyzing the logic of the 12306 background before. . Booking and unsubscribe of train tickets is different from ordinary shopping.
One problem is that train tickets can be sold at different stations. For example, there are many stations along the way for a train ticket from Beijing to Shanghai, such as Beijing-Jinan, Jinan-Nanjing... and so on. How to design a data model to access these tickets is a problem. Instead of a simple quantity +-1.
One idea is very good: use binary strings to represent a train ticket. For example, there are 10 stations from Beijing to Shanghai, and the initial status of a full ticket is expressed as: '111111111';
If a full ticket is sold, the ticket will become '000000000';
If you sell a half-way ticket, such as Beijing-Jinan three stations (first station-third station), the ticket will become '0011111111';
If you sell another half-way ticket, such as Xuzhou-Nanjing (Stop 6-Stop 9), then the previous ticket will become: '0011100011';
The logic of unsubscribed tickets is very simple. If I want to refund a ticket (Xuzhou-Nanjing), I will find the first one from the ticket pool and cannot buy it.
(Xuzhou-Nanjing) ticket, change it and it is OK (the reverse direction of buying tickets). For example, I found the above ticket '0011100011'.
After refunding the ticket, the ticket becomes (0011111111);
The basic logic is as above. 12306 must ensure multiple entrances, and the consistency of data at the same time requires very efficient logic to handle ticket checks.
It is said that there will be 200,000 requests per second for ticket purchase and refund of tickets at peak times. Save the ticket's data structure in memory. Not a database.
Small and efficient data junctions become important.
The code copy is 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());
}
};
//Direction whether a ticket can be bought, and it can be achieved through the AND or operation.
//For example: Order o is Beijing-Jinan (001111111), and a certain ticket is (0000000011) (sold Beijing-Nanjing), then return false
//For example: Order o is Beijing-Jinan (001111111), and a certain ticket is (1111100011) (Sold in 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;
};
//Implementation of selling tickets, changing the binary string, such as '11111111'->'00111111';
self.buy = function(t,o){
t.tic = (parseInt(t.tic,2) & parseInt(o,2)).toString(2);
//alert(t.tic);
};
//Inquiry of the remaining tickets
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: Tickets
function Ticket(){
var self = this;
//The ticket is the beginning of the 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 status, the ticket pool has 400 full tickets
Server._init(400);