Python · 36 строк
Раз в минуту приходит пачка входящих SMS от коротких номеров и рассыльщиков, в пик до 2 млн. score — регулярки и подсчёт цифр в тексте, чистый CPU. В одном потоке пачка обрабатывается 160 секунд на 8-ядерном сервере, а нужно уложиться в 30.
Отправитель с 1000 спам-сообщений уходит в стоп-лист: blocklist.add делает HTTP-запрос и может бросить ConnectionError. Сервис на обычном CPython 3.12. Отметьте строки с ошибками.
В работе: Антиспам-фильтр SMS-шлюза оператора.
Как проверяем
Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 2 вопроса про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
Источник: наша задача на данных МТС: фильтрация спам-рассылок по SMS. Условие пересказано своими словами.
Давали на собеседовании?
import reimport threadingfrom concurrent.futures import ThreadPoolExecutorfrom antispam.blocklist import blocklistSPAM_PATTERNS = [re.compile(p, re.I) for p in (r"выигр\w+ приз", r"переходи по ссылке", r"назови код из смс", r"bit\.ly/\w+",)]stats: dict[str, int] = {}stats_lock = threading.Lock()def score(text: str) -> int:s = sum(len(p.findall(text)) * 10 for p in SPAM_PATTERNS)return s + sum(ch.isdigit() for ch in text)def handle(sms: dict) -> bool:sender = sms["sender"]if sender not in stats:stats[sender] = 0spam = score(sms["text"]) >= 30if spam:stats_lock.acquire()stats[sender] += 1if stats[sender] == 1000:blocklist.add(sender)stats_lock.release()return spamdef run(batch: list[dict]) -> int:with ThreadPoolExecutor(max_workers=16) as pool:return sum(pool.map(handle, batch))