Sobes.tech
Senior
82

/* Η εταιρεία παρέχει υπηρεσία μαζικής αποστολής ειδοποιήσεων σε άλλες επιχειρήσεις. Ένας ιδιοκτήτης προϊόντος ανέθεσε τη δημιουργία ενός συστήματος φιλτραρίσματος ειδοποιήσεων λαμβάνοντας υπόψη τις προτιμήσεις των χρηστών. ## Ορισμοί Ειδοποίηση: - id ειδοποίησης - τύπος ειδοποίησης (EMAIL, SMS, PUSH) - παραλήπτης (id χρήστη) - κείμενο μηνύματος Ο παραλήπτης μπορεί να έχει ρυθμίσεις προτιμήσεων: - επιτρεπτά κανάλια ειδοποιήσεων (λίστα τύπων) - αποκλεισμένοι αποστολείς (λίστα id αποστολέων) Ιστορικό αποστολής ειδοποιήσεων: - λίστα ειδοποιήσεων που έχουν σταλεί στον χρήστη ## Σημαντικό Οι ρυθμίσεις χρηστών και το ιστορικό αποστολής παρέχονται από άλλα συστατικά του συστήματος. Πρέπει να σχεδιάσετε συμβάσεις για την απόκτησή τους. Δεν απαιτείται υλοποίηση αποθήκευσης. ## Εργασία Γράψτε ένα σύστημα φιλτραρίσματος ειδοποιήσεων που: - λαμβάνει μια λίστα ειδοποιήσεων για φιλτράρισμα και το id αποστολέα - αποκλείει ειδοποιήσεις που δεν ταιριάζουν με τις προτιμήσεις του χρήστη - υλοποιεί προστασία από διπλότυπα μηνύματα, συμπεριλαμβανομένων αυτών που έχουν σταλεί τις τελευταίες 24 ώρες. Τα διπλότυπα θεωρούνται μηνύματα με το ίδιο id, που απευθύνονται στον ίδιο χρήστη - επιστρέφει τη φιλτραρισμένη λίστα ειδοποιήσεων, έτοιμη για αποστολή. Η αποστολή ειδοποιήσεων δεν αποτελεί μέρος της εργασίας σας - μια άλλη ομάδα θα αναλάβει την αποστολή της φιλτραρισμένης λίστας. Η εργασία σας είναι μόνο η φιλτράρισμα. */ class NotificationFilter { UserSettingsService userSettingsService; NotificationHistoryService notificationHistoryService; public ??? filter(??? senderId, List<???> msgs) { // TODO implement } } interface UserSettingsService { // TODO any functions } interface NotificationHistoryService { // TODO any functions }

Εταιρείες όπου ρωτήθηκαν
Яндекс

Απάντηση από AI

sobes.tech AI

java import java.time.Instant; import java.time.Duration; import java.util.*; import java.util.stream.Collectors;

class Notification { String id; NotificationType type; String recipientId; String text;

// Конструктор, геттеры, сеттеры

}

enum NotificationType { EMAIL, SMS, PUSH }

interface UserSettingsService { /** * Возвращает разрешённые каналы уведомлений для пользователя. */ Set<NotificationType> getAllowedChannels(String userId);

/**
 * Возвращает список заблокированных отправителей для пользователя.
 */
Set<String> getBlockedSenders(String userId);

}

interface NotificationHistoryService { /** * Возвращает список уведомлений, отправленных пользователю за последние 24 часа. */ List<Notification> getNotificationsLast24h(String userId); }

class NotificationFilter { private final UserSettingsService userSettingsService; private final NotificationHistoryService notificationHistoryService;

public NotificationFilter(UserSettingsService userSettingsService, NotificationHistoryService notificationHistoryService) {
    this.userSettingsService = userSettingsService;
    this.notificationHistoryService = notificationHistoryService;
}

/**
 * Фильтрует список уведомлений по предпочтениям пользователей и исключает дубликаты.
 * 
 * @param senderId id отправителя
 * @param msgs список уведомлений для фильтрации
 * @return отфильтрованный список уведомлений
 */
public List<Notification> filter(String senderId, List<Notification> msgs) {
    // Группируем уведомления по получателям
    Map<String, List<Notification>> byRecipient = msgs.stream()
        .collect(Collectors.groupingBy(n -> n.recipientId));

    List<Notification> result = new ArrayList<>();

    for (Map.Entry<String, List<Notification>> entry : byRecipient.entrySet()) {
        String userId = entry.getKey();
        List<Notification> userNotifications = entry.getValue();

        Set<NotificationType> allowedChannels = userSettingsService.getAllowedChannels(userId);
        Set<String> blockedSenders = userSettingsService.getBlockedSenders(userId);

        // Если отправитель заблокирован, пропускаем все уведомления для этого пользователя
        if (blockedSenders.contains(senderId)) {
            continue;
        }

        // Получаем историю уведомлений за последние 24 часа
        List<Notification> history = notificationHistoryService.getNotificationsLast24h(userId);
        Set<String> recentNotificationIds = history.stream()
            .map(n -> n.id)
            .collect(Collectors.toSet());

        // Для защиты от дубликатов учитываем также текущие уведомления
        Set<String> currentNotificationIds = new HashSet<>();

        for (Notification n : userNotifications) {
            // Фильтрация по разрешённым каналам
            if (!allowedChannels.contains(n.type)) {
                continue;
            }

            // Проверка на дубликаты (id + пользователь)
            if (recentNotificationIds.contains(n.id) || currentNotificationIds.contains(n.id)) {
                continue;
            }

            currentNotificationIds.add(n.id);
            result.add(n);
        }
    }

    return result;
}

}


**Объяснение:**
- Интерфейсы `UserSettingsService` и `NotificationHistoryService` предоставляют методы для получения настроек пользователя и истории уведомлений.
- В методе `filter` уведомления группируются по получателям.
- Для каждого пользователя проверяется, разрешён ли канал уведомления и не заблокирован ли отправитель.
- Исключаются дубликаты, учитывая историю за последние 24 часа и текущие уведомления.
- Возвращается список уведомлений, соответствующих предпочтениям и без дубликатов.