Sobes.tech
Senior

/* Вие сте писател, управлявате своя мини блог и там публикувате статии. Потребителите (читателите) на вашия блог, след като се впишат, могат да ги преглеждат/четат. Необходимо е да реализирате функционалност за броене на уникалните преглеждания за ден за всяка статия. Функционални изисквания: - Статистика за днес: Авторът може да види колко уникални потребители са прегледали статията му днес (данните се събират в реално време). - Статистика за изминалите дни: Авторът може да види статистиката за всеки изминал ден (например, вчера). Технически ограничения и условия: - Приложението работи на един сървър (един под) - В паметта - Време в UTC0 */

sobes.tech AI

Отговор от AI

За броене на уникалните прегледи на статии на ден, като се съхраняват данните в паметта и с един сървър, може да се използва следната структура:

  • За всеки ден (по дата UTC) съхранявайте карта: map[articleID]map[userID]bool, където ключовете са ID на статията и ID на потребителя.
  • При преглед на статия от оторизиран потребител, добавете userID към съответната карта за статията и текущата дата.
  • За получаване на статистика за днес или вчера, пребройте дължината на вътрешната карта на потребителите за статията.

Пример на Go:

type Stats struct {
    mu sync.RWMutex
    data map[string]map[string]map[string]bool // дата -> ID на статията -> ID на потребителя -> 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])
}

Този подход позволява в реално време събиране на уникални прегледи и получаване на статистика за всеки ден. При необходимост може да се добави периодично почистване на старите данни, за да се ограничи използването на памет.