Requirement description
- Supports configuration of multiple prizes and corresponding weights
- Ensure that the lottery results meet the weight probability distribution
- Prevent repeated winnings
- Provide a lottery result verification interface
Complete implementation code
package main import ( "crypto/rand" "encoding/json" "fmt" "math/big" "net/http" "sync" ) // Prize configurationtype Prize struct { ID int `json:"id"` Name string `json:"name"` Weight int `json:"weight"` // Weight value (non-percentage)} // Lottery systemtype LotterySystem struct { prizes []Prize totalWeight int issuedPrizes map[int]bool mu } // Initialize the lottery systemfunc NewLotterySystem(prizes []Prize) *LotterySystem { total := 0 for _, p := range prizes { total += } return &LotterySystem{ prizes: prizes, totalWeight: total, issuedPrizes: make(map[int]bool), } } // Safe random number generationfunc secureRandom(max int) (int, error) { n, err := (, (int64(max))) if err != nil { return 0, err } return int(n.Int64()), nil } // Execute the lotteryfunc (ls *LotterySystem) Draw() (*Prize, error) { () defer () if == 0 { return nil, ("no available prizes") } // Generate random numbers randomNum, err := secureRandom() if err != nil { return nil, err } // Weight selection current := 0 for _, p := range { current += if randomNum < current { if [] { continue // Skip the awards issued } [] = true return &p, nil } } return nil, ("draw failed") } // HTTP servicefunc main() { // Initialize the prize pool prizes := []Prize{ {ID: 1, Name: "First Prize", Weight: 1}, {ID: 2, Name: "Second Prize", Weight: 5}, {ID: 3, Name: "Third Prize", Weight: 20}, {ID: 4, Name: "Participation Award", Weight: 74}, } lottery := NewLotterySystem(prizes) ("/draw", func(w , r *) { prize, err := () if err != nil { (w, (), ) return } ().Set("Content-Type", "application/json") (w).Encode(prize) }) ("The lottery service has been started, listening port 8080") (":8080", nil) }
Core function description
Weighting algorithm:
// Weight selection logiccurrent := 0 for _, p := range { current += if randomNum < current { return &p } }
- Use the cumulative weight interval algorithm
- Ensure the accuracy of probability distribution
Safe random numbers:
// Generate safe random numbers using crypto/randfunc secureRandom(max int) (int, error) { n, err := (, (int64(max))) // ... }
- Avoid predictability of math/rand
- Meet the safety lottery needs
Concurrent control:
var mu func (ls *LotterySystem) Draw() { () defer () // ... }
- Use mutex locks to ensure thread safety
- Prevent data competition caused by concurrent lottery
Anti-repetition mechanism:
issuedPrizes map[int]bool
- Record awards issued using memory map
- The production environment can be replaced with persistent storage such as Redis
Extended feature suggestions
Probability visualization verification:
// Add test endpoint verification probability distribution("/test", func(w , r *) { results := make(map[int]int) for i := 0; i < 10000; i++ { tempLottery := NewLotterySystem(prizes) prize, _ := () results[]++ } (w).Encode(results) })
Distributed lock extension:
// Use Redis distributed lockfunc (ls *LotterySystem) DistributedDraw() { lock := ("lottery_lock") err := () // ...Raffle logic... () }
Prize inventory management:
type Prize struct { // ... Stock int // Add inventory field} func (ls *LotterySystem) Draw() { // Check inventory if <= 0 { continue } // Deduct inventory -- }
Run the test
Start the service:
go run
Test draw:
curl http://localhost:8080/draw # Example return:{"id":3,"name":"Third Prize","weight":20}
Probability verification test:
curl http://localhost:8080/test # Return to the distribution of the lottery results for tens of thousands of times
Key Optimization Points
Performance optimization:
- Use pre-calculated total weight values
- Memory-level lock granularity control
- Object pool reuse
Security enhancement:
- JWT User Authentication
- Lottery frequency limit
- Sensitive operation log
Business expansion:
- Support different lottery activities
- Prize validity period management
- List of winnings announced
This is the article about the project practice of Go's weight lottery system implementation. For more related Go's weight lottery system content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!