Senior
/* Jeste pisarzem, prowadzisz swój mini blog i tam publikujesz artykuły. Użytkownicy (czytelnicy) twojego bloga, po zalogowaniu się, mogą je przeglądać/czytać. Należy zaimplementować funkcjonalność liczenia unikalnych wyświetleń dziennie dla każdego artykułu. Wymagania funkcjonalne: - Statystyki za dzisiaj: Autor może zobaczyć, ilu unikalnych użytkowników obejrzało jego artykuł dzisiaj (dane są zbierane w czasie rzeczywistym). - Statystyki za minione dni: Autor może zobaczyć statystyki za dowolny miniony dzień (np. wczoraj). Ograniczenia techniczne i warunki: - Aplikacja działa na jednym serwerze (jednym podzie) - Przechowywanie w pamięci - Czas w UTC0 */
sobes.tech AI
Odpowiedź od AI
Aby zliczyć unikalne wyświetlenia artykułów dziennie, przechowując dane w pamięci i korzystając z jednego serwera, można użyć następującej struktury:
- Dla każdego dnia (według daty UTC) przechowywać mapę:
map[articleID]map[userID]bool, gdzie klucze to ID artykułu i ID użytkownika. - Przy oglądaniu artykułu przez zalogowanego użytkownika, dodać userID do mapy dla odpowiedniego artykułu i bieżącej daty.
- Aby uzyskać statystyki na dziś lub wczoraj, policzyć długość wewnętrznej mapy użytkowników dla artykułu.
Przykład w Go:
type Stats struct {
mu sync.RWMutex
data map[string]map[string]map[string]bool // data -> ID artykułu -> ID użytkownika -> bool
}
func NewStats() *Stats {
return &Stats{data: make(map[string]map[string]map[string]bool)}
}
func (s *Stats) AddView(articleID, userID string) {
s.mu.Lock()
defer s.mu.Unlock()
date := time.Now().UTC().Format("2006-01-02")
if s.data[date] == nil {
s.data[date] = make(map[string]map[string]bool)
}
if s.data[date][articleID] == nil {
s.data[date][articleID] = make(map[string]bool)
}
s.data[date][articleID][userID] = true
}
func (s *Stats) GetUniqueViews(articleID, date string) int {
s.mu.RLock()
defer s.mu.RUnlock()
if s.data[date] == nil || s.data[date][articleID] == nil {
return 0
}
return len(s.data[date][articleID])
}
Ten sposób pozwala na zbieranie unikalnych wyświetleń w czasie rzeczywistym i uzyskiwanie statystyk dla dowolnego dnia. W razie potrzeby można dodać okresowe czyszczenie starych danych, aby nie zużywać zbyt dużo pamięci.