XVCoder / CustomerScoreRank

0 stars 0 forks source link

Thanks for joining our test #1

Open wangjia184 opened 2 years ago

wangjia184 commented 2 years ago

Thanks for joining our test.

https://github.com/XVCoder/CustomerScoreRank/blob/b0485b046e34596ab192066ab5eee8b500c8dcdf/CustomerScoreRank/Services/CustomerService.cs

Thread Safety

        private static readonly List<Customer> _customers = new();

        public async Task<decimal> UpdateScore(long customerId, decimal score)
        {
            decimal finalScore;
            lock (_customers)
            {
                if (_customers.Any(x => x.Id == customerId))
                {// Update
                    var customer = _customers.First(x => x.Id == customerId);
                    customer.Score += score;
                    finalScore = customer.Score;
                }
                else
                {// Add
                    var customer = new Customer { Id = customerId, Score = score };
                    _customers.Add(customer);
                    finalScore = customer.Score;
                }
            }
            return await Task.FromResult(finalScore);
        }

The above code can result in unexpected result when handling simultaneous requests. For example

Besides this one, the other two retrieval methods are not safe neither. The list is being accessed without synchronization.

Performance

The retrieval operations (GetCustomersByRank / GetCustomersByCustomerId) sort the entrie list before each query, which is very low efficient. The proper approach is to keep the customers in order, rather than sorting it everytime before each query.

Here are some suggested approaches.

Approach UpdateScore GetCustomersByRank GetCustomersByCustomerId
SortedSet + Dictionary O(n) O(n) O(log(n))
BinarySearch + Dictionary O(n) O(1) O(log(n))
SkipList+ Dictionary O(log(n)) O(log(n)) O(log(n))

The above table lists the expected time complexity for each approach. You may choose an approach to refactor your code.

Br.

XVCoder commented 2 years ago

@wangjia184 refactored.