Всем привет, меня зовут Михаил, я работаю senior Java/Kotlin разработчиком в ОТП Банке. В свободное от работы время я занимаюсь менторством. Ко мне приходят разные люди: кто-то уже работает на проекте, кто-то только учится.
Сейчас, в эпоху ИИ, найти информацию стало куда легче, чем раньше. Раньше ты гуглил и тыкал по ссылкам, а теперь все в одном приложении. Да еще и код можно не писать - ну красота же. Но что, если ты и до этого не умел писать код и решил "вкатываться в айтишку" (ненавижу эту фразу)?
Вроде бы у тебя на руках все материалы и знания всего интернета, которые нужно всего лишь положить себе в голову. На мок-собеседованиях ребята знают все, отвечают, будто они сами придумали этот термин или метод. Но как только дело доходит до самостоятельного кодинга - люди теряются.
Я написал небольшую задачу и попросил решить ее людей разного уровня - от стажера до сеньора. Кому-то разрешил пользоваться нейросетью, кому-то запретил.
Сегодня поговорим о том, как ИИ влияет на обучение с нуля и как им лучше пользоваться для обучения.

!!!ДИСКЛЕЙМЕР!!!
Я не буду говорить, что пользоваться ИИ это плохо и бросайте или что нужно по-максимуму пользоваться ИИ. Буду говорить свое мнение и наблюдение по этому поводу, оно может не совпадать с Вашим, но это абсолютно нормально.
Суть проблемы
Раньше, когда информация не лежала в одном месте, а код нейросеть не писала под твой проект, приходилось делать все руками. Ты гуглил, открывал 10 вкладок, читал статьи на Stack Overflow, смотрел примеры и думал: "А как это применить к моей задаче?" Иногда часами сидел над одним методом. Писал, переписывал, падал, вставал и снова писал.
Это было больно. Но это набивало опыт.
Ты запоминал решения, потому что добывал их потом и кровью. Ты понимал, почему код работает, потому что сам его написал и отладил. Ты умел читать чужой код, потому что без этого было никак.
Сейчас все по-другому.
Перед разработчиком стоит искушение: скормить задачу нейросети и через 30 секунд получить готовый код. Красота же. И многие поддаются. Особенно те, кто только учится. Зачем думать, если можно просто скопировать? Зачем ошибаться, если нейросеть выдаст правильный вариант?
И люди обленились. Честно. Они перестали набивать шишки. Они перестали думать. Они разучились читать чужой код, потому что нейросеть написала свой. Они не знают, почему их код работает - просто потому что "нейросеть сказала, что так правильно".
Проблема даже не в том, что мидлы или сеньоры делают все с нейросетями. Нет. Проблема именно в начинающих специалистах. И весь парадокс в том, что они боятся, что их полностью заменят нейросети. При этом пользуются только ими и доверяют им все. Сами себя заменяют.

Сегодня я хочу показать, как доверие нейросетям без собственного опыта в программировании затащит вас в техдолговую яму и как оно влияет на разработку.
Именно об этом моя статья.
Задача и подопытные
Задача достаточно простая:
Задача
class NotificationRequest { private String requestId; private NotificationType type; private String recipient; private String message; } enum NotificationType { EMAIL, SMS, PUSH }
Реализовать программу, которая:
1. Принимает список запросов и обрабатывает данные по одному
2. Не отправляет дубликаты
Дубликатом считается запись с одинаковым requestId.То есть если запрос уже обрабатывался - повторно не отправляем.
3.Регистрация считается невалидной если:
requestId == null
recipient == null
message == null
Email невалидный если:
не содержит "@"
SMS невалидный если :
номер телефона не содержит "+" и не содержит ровно 11 символов после плюса.
PUSH невалидный если:
Сообщение пустое
4. Эмулирует отправку(просто вывод в лог информации)
Создать сервис:
NotificationService
Метод:
void send(NotificationRequest request)
Sending EMAIL to user1@mail.com
Sending SMS to +79990001122
Sending PUSH to device-123
После обработки вывести:
Processed: 3
Duplicates skipped: 2
Failed: 0
ВАЖНО! Используем только Java, ничего больше!
В качестве подопытных будут следующие лица:
Кто |
Пользование нейросетью |
Нейросеть (DeepSeek и ChatGPT, их самые доступные версии) |
Да |
Стажер |
Да |
Стажер |
Нет |
Мидл, который больше не пишет код сам (вайбкодер) |
Да |
Сеньор |
Как захочет (почему так, узнаем позже) |
Для нейросети я взял самые доступные - deepseek и chatgpt их самые доступные версии.
Нейросеть
Я сказал просто: «Реши задачу». Без сложного промта, получил следующее решение -
Решение нейросети
class NotificationService { private Set<String> processedIds = new HashSet<>(); private int processedCount = 0; private int duplicatesSkipped = 0; private int failedCount = 0; public void send(NotificationRequest request) { if (processedIds.contains(request.getRequestId())) { duplicatesSkipped++; return; } if (!isValidRegistration(request)) { failedCount++; return; } if (!isValidByType(request)) { failedCount++; return; } emulateSending(request); processedIds.add(request.getRequestId()); processedCount++; } private boolean isValidRegistration(NotificationRequest request) { return request.getRequestId() != null && request.getRecipient() != null && request.getMessage() != null; } private boolean isValidByType(NotificationRequest request) { switch (request.getType()) { case EMAIL: return request.getRecipient().contains("@"); case SMS: String phone = request.getRecipient(); return phone.startsWith("+") && phone.length() == 12; case PUSH: return !request.getMessage().trim().isEmpty(); default: return false; } } private void emulateSending(NotificationRequest request) { switch (request.getType()) { case EMAIL: System.out.println("Sending EMAIL to " + request.getRecipient()); break; case SMS: System.out.println("Sending SMS to " + request.getRecipient()); break; case PUSH: System.out.println("Sending PUSH to " + request.getRecipient()); break; } } public void printStatistics() { System.out.println("\nProcessed: " + processedCount); System.out.println("Duplicates skipped: " + duplicatesSkipped); System.out.println("Failed: " + failedCount); } }
Видим следующие решение - оно в лоб, ничего сложного, нет абстракций, паттернов или чего-то еще Видим следующие решение - оно в лоб, ничего сложного, нет абстракций, паттернов или чего-то еще
Оно в лоб. Ничего сложного. Нет абстракций, паттернов или чего-то еще. Оно работает, но нет гибкости. Нет архитектуры. Просто код, который делает то, что просили, и не более.
Дальше я не буду вставлять код каждого решения. Считаем, что этот код - основа, которую мы будем совершенствовать.
Стажер, который решал задачу с чатом.
Неудивительно, что его решение один в один, как и у нейросети. Он оставил как есть, не задумываясь ни о чем, значит у него такие же проблемы, как и у нейросети.
Стажер, который решает задачу сам.
Здесь для меня было удивление. Решение заняло куда больше времени, чем я ожидал. У стажера без ИИ ушло в районе 2-3 часов на решение.
И знаете что? Я горжусь его решением.
Гугля и находясь в поиске решения некоторых задач, он сделал покрытие паттернами проектирования:
Фабрика - для создания объектов NotificationService.
Синглтон - для создания одного экземпляра на каждый тип.
Фабричный метод - так как логика везде одинаковая, была сделана абстракция с одним абстрактным методом validate.
Возможно, это решение не считается идеальным. Да и нет идеальных решений. Но оно гораздо лучше. Гораздо гибче. В нем видна идея.
Человек, который подумал своей головой, поискал решения - получил хороший результат.
Да мы получили решение куда дольше, но зато его можно легко поддерживать!
Мидл - вайбкодер
Как он сюда попал? На самом деле совершенно случайно, это человек, который уже долго работает на реальном проекте и сейчас почти полностью пишет код с нейросетью. Мне показалось, что это идеальный кандидат. Впервые за долгое время он решал задачу сам и вот итог:
Есть NotificationService, который занимается отправкой и проверкой дубликатов. Есть отдельный ValidationService, который содержит методы smsValidation, pushValidation, emailValidation.
Оно лучше, чем у нейросети. Но не идеальное.
Что хорошо: есть разделение ответственности. NotificationService занимается отправкой, ValidationService - валидацией. Не все в одной куче. Есть разделение на подметоды в основном коде.
Что плохо: нет гибкости. Чтобы добавить новый тип уведомления (например Telegram), придется лезть в класс ValidationService и добавлять новый метод. И в NotificationService тоже. Нет абстракции, нет паттернов, нет расширяемости.
Это среднее решение. Оно работает. Но развивать его страшно.
Хотя при использовании ИИ и просмотра его кода качество было всегда куда лучше.
Сеньор
Почему я написал в таблице загадку - "Как захочет (почему так, узнаем позже)"?
Я попросил сеньора сделать так: сначала решить задачу самостоятельно, потом попросить нейросеть решить ее же, затем взять код нейросети и отревьювить его, дать замечания и править до тех пор, пока код не станет для него приемлемым.
Итоговое решение получилось коротким, четким. Использовались абстракции, паттерны. Предусмотрено логирование для каждого сценария. Вынесены константы.
На все про все у сеньора ушло 30-40 минут. Из них непосредственно ревью кода нейросети с правками заняло около 10 минут. Понадобилось 3 итерации правок. Все замечания были в основном архитектурные: добавление гибкости, расширение логирования.
Итоги конкурса
Давайте подведем небольшой итог в виде таблицы
Участник |
Время |
Качество кода |
Моя личная оценка решения(очень субъективно) |
Нейросеть |
30 сек |
Примитив, нет гибкости |
3/10 Работает - и ладно. Но развивать страшно. |
Стажер с чатом |
5 минут |
Тупая копипаста |
1/10 Даже не пытался что-то исправить |
Стажер без чата |
2-3 часа |
Паттерны, гибкость, абстракция |
8/10 Для стажера отличная оценка, он проделал хорошую работу и показал самостоятельность. Горжусь!! |
Мидл вайбкодер |
1-2 часа |
Разделение ответственности, но нет гибкости и расширяемости |
5/10 Оно лучше, чем у нейросети, но есть свои проблемы. |
Сеньор без нейросети |
30-40 минут |
Присутствует архитектура, разбиение на пакеты, логирование, константы, гибкий код. |
9/10 Код лаконичный, просто, гибкий, читаемый. 10 не ставлю - всегда есть куда стремиться |
Сеньор с нейросетью |
10 минут |
Все преимущества, что и без нейросетей |
9/10 Все преимущества, что и без нейросетей |
Итог
Нейросеть - это ускоритель. Он дает вам 5x к уму и скорости. Ваши знания, ваш опыт, ваше умение мыслить - это база. А нейросеть умножает эту базу.
Формула простая:
Ваш уровень * 5x = результат
Если ваш уровень - 0, то извините. 0 умножить на 5 равно 0. Профита вы не получите.
Если ваш уровень - 1 (вы новичок, который хочет разобраться), то 1 * 5 = 5. Уже что-то.
Если ваш уровень - 2 (вы уверенный джун), то 2 * 5 = 10. Вы уже далеко впереди.
А если ваш уровень - 10 (вы сеньор с горящими глазами), то 10 * 5 = 50. Вы бог.
Нейросеть не делает вас умнее. Она делает вас быстрее. Но если нечего ускорять - пользы особо не будет.
Проблема начинающих в том, что они пытаются заменить свой 0 на нейросеть. Но нейросеть не заменяет базу. Она умножает ее.
Так что сначала наберите свой уровень. Пишите код руками. Ошибайтесь. Ищите сами. А потом подключайте ускоритель.
Если вы только начинаете свой путь, используйте его по минимуму. Если вы приходите к нему за подсказкой, просите не выдавать готовое решение, а наставить на нужный путь.
Если вы уже давно в профессии, но в последнее время не пишете код руками - попишите, вспомните. Писать код - это классно. Особенно хороший код, который хочется поставить в рамочку.
А если вы пользуетесь нейросетью для помощи в нужные моменты или делегируете на нее рутину - велком в мой лагерь. Именно так я и пользуюсь нейросетью. Не так, что скармливаю все ТЗ и жду, откинувшись на стуле. Нет, я люблю писать код. Но писать DTO или миграции на создание таблиц я уже давно устал - пусть это сделает помощник. А что-то посложнее оставит мне!
Пользуйтесь нейросетями с умом. Всем спасибо!
Комментарии (22)

Dhwtj
19.06.2026 10:43Итоговое решение получилось коротким, четким. Использовались абстракции, паттерны.
Паттерны и нейросеть может, это её работа. А вот мыслить на нужном уровне абстракций может только человек.

Kot_na_klaviature
19.06.2026 10:43Сейчас, в эпоху ИИ, найти информацию стало куда легче, чем раньше
Не найти, а нагенерить. Найти это работа и обучение. А нагенерить это делегировать генератору. Уровень таких погромистов будет стремительно деградировать к нулю. А потом и нормальный бизнес (да и вообще люди) устанут от потока неконтролируемого нейрослопа и будут банить. Уже устают. Тот же Хабр после запрета нейроспама стало гораздо приятней читать.

MountainGoat
19.06.2026 10:43Потому что сейчас все начальники хотят, чтобы качесво как вручную, а объём как из ИИ без проверок.

apidev
19.06.2026 10:43Про архитектуру и абстракции - весьма спорно.
Задача небольшая, инкапсулирована внутри одного класса.
Засовывать N паттернов сразу считаю преждевременной оптимизацией, ибо работал с проектом, где таких абстракций накручено выше крыши и логики за кодом уже практически не видно.
ИМХО, абстракции нужно добавлять в код по мере необходимости. Т.е. как только потребовалась доработка: мелкий рефакторинг и добавил нужную абстракцию.
Особенно фиговым решением считаю своими руками писать синглтон и фабрику. Либо Guice, либо Spring IoC, либо jackarta.inject, ну или через ServiceLoader на худой конец, либо пинать сеньёра велосипедостроения. Иначе техдолговая яма наступит гораздо раньше.
А джун с нейросеткой не теряет возможности развиваться. Либо самостоятельно (читая литературу), либо методом летающего ежа, на каждом Code Review. Бизнесу он пользу принёс, причём быстро.

Dron007
19.06.2026 10:43Тут, в целом может быть и так, но вообще многое зависит от устоявшихся привычек, которые не факт, что будут полезны с приходом нейросетей. Например, одним из важных требований выдвигают поддержание кода. Очень хорошо это понимаю, отзывается болью от изменения плохо написанных проектов, неоптимальных решений. Когда кто-то быстренько написал что-то вроде работающее, а тебе потом надо что-то по мелочи изменить и ты тратишь в 10 раз больше времени, всё переписывая, это неприятно. Но это при условии что весь код пишет человек. Если код написала нейросеть и поддерживать тоже будет нейросеть, а если что, так и зарефакторит, то так ли уже важен этот критерий? Важны другие - производительность, стабильность. Они часто бывают связаны с поддерживаемостью. А иногда и наоборот - пишется что-то лучше поддерживаемое, но хуже в плане производительности. Руководителю же важны скорость разработки и просто выполнение задачи без сюрпризов в будущем. Но и с сюрпризами будет бороться нейросеть. Так что тут многое надо ещё переосмысливать в восприятии. Как многие до сих пор ожидают, что нейросети должны сразу писать идеальный код с первого промпта и такие "Ага-а-а, не может. На помойку её. Вот человек бы..." забывая, что любые сложные задачи итеративны и поэтапны.

Kot_na_klaviature
19.06.2026 10:43то так ли уже важен этот критерий?
Это самый главный критерий. Ллм точно также нужен понятный и поддерживаемый код, как и человеку. Иначе она начнет путаться, исправлять одно и ломать другое. Для нее код это контекст. Если там лапша и тупость, она и будет продолжать писать лапшу и тупость. + неподдерживаемый нейрокод это сложное или даже невозможное ревью.

Dron007
19.06.2026 10:43Частично согласен. Если значение задано 20 раз в разных файлах, то более высока вероятность для современных моделей, что что-то упустит, хотя уже лучше справляется чем раньше. Но часто под поддерживаемостью понимается, что логика попроще, пусть и за счёт эффективности, наглядность повыше. То есть код строится в угоду именно ограничений интеллекта, а не из соображений эффективности. Даже вот выделение в функцию кода требует накладных расходов как правило - работа со стеком и прочее. Где-то можно и повторить пару раз с разными параметрами. Но человеку проще формировать модель восприятия так, а модели может быть и всё равно. В конце концов главная метрика - эффективность решения поставленной задачи. И если она решает эффективнее человека, то какая разница какой там код? Если он для эффективного решения объективно выгоднее когда структурирован, так он и будет становиться таким по мере улучшения обучения моделей.

Kot_na_klaviature
19.06.2026 10:43эффективность решения поставленной задачи
Поддерживаемый код является существенной частью эффективности.
если она решает эффективнее человека, то какая разница какой там код?
Не знаю кто что решает и эффективнее какого человека, но зачем нужен читаемый код написал выше (путается ллм, невозможность в лапше делать ревью итд).

Dron007
19.06.2026 10:43Поддерживаемый код является существенной частью эффективности.
Это не более чем технический параметр, мало кому интересный. Более того, если написание поддерживаемого кода стоит дороже, а на качество продукта это никак не влияет, только на степень понимания кода программистами, то этот параметр быстренько оптимизируется в сторону игнорирования. Сильно кто-то заботится о поддерживаемом машинном коде скомпилированной программы, например?
LLM может запутаться и в хорошо поддерживаемом коде и неподдерживаемый это не обязательно лапша, это может быть просто сильно оптимизированное решение как раз.

Matvey0808
19.06.2026 10:43с нейросетью учиться вроде и тупо, а вроде и вся информация на ладони, но плюс искать все вручную в том, что мы еще 100 решений найдем которые нам не нужны и 100 раз прочитаем чужой код. И вот когда наступит момент когда мы наконец-то нашли решение своей проблемы, мы попутно собрали и многое другое, которое возможно, пригодится в будущих задачах.
Но все же нужно приспособиться к нейронкам ибо это будущее, и без них никак уже в мире, как бы не было обидно.
Ну вот даже когда мы готовимся к собесу с помощью ИИ и он нам выдает паттерны якобы самые частые, и в итоге мы по сути только запомнили шаблонные решения, наш мозг ничего нового не усвоил. Это деградация как по мне.
Обучение не должно быть легким, если обучение легкое - это не обучение.
Хотя кому я это говорю, я сам еще мал и глуп) полтора года мобилки изучаю от силы.
Я кстати удивился, когда увидел решение мидла, не думал, что он OCP нарушит, раз он дошел до такого уровня.

Snaret
19.06.2026 10:43С посылом статьи на 100% согласен, к оформлению доказательств вопросы...
КОД каждого участника в студию!
А так субъективному оценочному суждению привык не доверять, уж извините.
И мидла незаслуженно унизили) Ему задачки закрывать надо, быстро и более менее качественно. Ну нет у него 2-3 часа на неспешные раздумия, на таких как он IT держится.
И по соотношениям время исполнения/качество/цена работы в час он явно будет впереди.
А этому в принципе не верю (Сеньор с нейросетью 10 минут Все преимущества, что и без нейросетей 9/10 Все преимущества, что и без нейросетей).
Нейросеть то та же. А значит выдаст тот же примитив. Ну и если сеньор за 9 минут 30 секунд реализовал все как боженька, то я Жанна Дарт Вейдер))))
MishaBucha Автор
19.06.2026 10:43Тут именно про то, что сеньор не просто увидел код и принял решение, а доводил его до приемлемого формата)
Я со всеми созванивался и все смотрел, попрошу скинуть код всех, если интересует )

Snaret
19.06.2026 10:43Поразмышлял над вашей статьей еще раз.
Оформил экспериментус. Дипсику скормил хороший промпт и вашу задачу.
Вот что он мне выдалСкрытый текст
import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; // ---------- Request DTO ---------- class NotificationRequest { private final String requestId; private final NotificationType type; private final String recipient; private final String message; private NotificationRequest(Builder builder) { this.requestId = builder.requestId; this.type = builder.type; this.recipient = builder.recipient; this.message = builder.message; } public String getRequestId() { return requestId; } public NotificationType getType() { return type; } public String getRecipient() { return recipient; } public String getMessage() { return message; } public static class Builder { private String requestId; private NotificationType type; private String recipient; private String message; public Builder requestId(String requestId) { this.requestId = requestId; return this; } public Builder type(NotificationType type) { this.type = type; return this; } public Builder recipient(String recipient) { this.recipient = recipient; return this; } public Builder message(String message) { this.message = message; return this; } public NotificationRequest build() { return new NotificationRequest(this); } } } // ---------- Enum ---------- enum NotificationType { EMAIL, SMS, PUSH } // ---------- Validator ---------- interface Validator { boolean isValid(NotificationRequest request); } class EmailValidator implements Validator { @Override public boolean isValid(NotificationRequest request) { return request.getRecipient() != null && request.getRecipient().contains("@"); } } class SmsValidator implements Validator { private static final int EXPECTED_DIGITS_AFTER_PLUS = 11; @Override public boolean isValid(NotificationRequest request) { String recipient = request.getRecipient(); if (recipient == null) return false; if (!recipient.contains("+")) return false; int plusIndex = recipient.indexOf('+'); String afterPlus = recipient.substring(plusIndex + 1); return afterPlus.length() == EXPECTED_DIGITS_AFTER_PLUS; } } class PushValidator implements Validator { @Override public boolean isValid(NotificationRequest request) { String msg = request.getMessage(); return msg != null && !msg.trim().isEmpty(); } } // ---------- Validator Factory ---------- class ValidatorFactory { private static final Map<NotificationType, Validator> VALIDATORS = new EnumMap<>(NotificationType.class); static { VALIDATORS.put(NotificationType.EMAIL, new EmailValidator()); VALIDATORS.put(NotificationType.SMS, new SmsValidator()); VALIDATORS.put(NotificationType.PUSH, new PushValidator()); } public static Validator getValidator(NotificationType type) { Validator validator = VALIDATORS.get(type); if (validator == null) { throw new IllegalArgumentException("Unsupported notification type: " + type); } return validator; } } // ---------- Sender ---------- interface Sender { void send(NotificationRequest request); } class EmailSender implements Sender { @Override public void send(NotificationRequest request) { System.out.println("Sending EMAIL to " + request.getRecipient()); } } class SmsSender implements Sender { @Override public void send(NotificationRequest request) { System.out.println("Sending SMS to " + request.getRecipient()); } } class PushSender implements Sender { @Override public void send(NotificationRequest request) { System.out.println("Sending PUSH to " + request.getRecipient()); } } // ---------- Sender Factory ---------- class SenderFactory { private static final Map<NotificationType, Sender> SENDERS = new EnumMap<>(NotificationType.class); static { SENDERS.put(NotificationType.EMAIL, new EmailSender()); SENDERS.put(NotificationType.SMS, new SmsSender()); SENDERS.put(NotificationType.PUSH, new PushSender()); } public static Sender getSender(NotificationType type) { Sender sender = SENDERS.get(type); if (sender == null) { throw new IllegalArgumentException("Unsupported notification type: " + type); } return sender; } } // ---------- Main Service ---------- class NotificationService { private static final Logger LOGGER = Logger.getLogger(NotificationService.class.getName()); private final Set<String> processedIds = ConcurrentHashMap.newKeySet(); private int processedCount = 0; private int duplicateCount = 0; private int failedCount = 0; /** * Processes a single request: validates, checks for duplicates, and sends if valid. */ public void send(NotificationRequest request) { // 1. Duplicate check if (request.getRequestId() == null) { // requestId null is considered invalid (will be counted as failed) // but we still need to process? We'll treat as failed, but not as duplicate. // However, duplicate check requires requestId; if null, we cannot track it. // According to spec: requestId == null is invalid, so we skip duplicate check. // We'll directly mark as failed. LOGGER.log(Level.WARNING, "Request with null requestId – marking as failed"); failedCount++; return; } if (!processedIds.add(request.getRequestId())) { // Already processed duplicateCount++; LOGGER.log(Level.INFO, "Duplicate request skipped: {0}", request.getRequestId()); return; } // 2. Common null checks (as per spec: requestId, recipient, message must not be null) if (request.getRecipient() == null || request.getMessage() == null) { failedCount++; LOGGER.log(Level.WARNING, "Request {0} failed: recipient or message is null", request.getRequestId()); return; } // 3. Type‑specific validation Validator validator = ValidatorFactory.getValidator(request.getType()); if (!validator.isValid(request)) { failedCount++; LOGGER.log(Level.WARNING, "Request {0} failed validation", request.getRequestId()); return; } // 4. Send Sender sender = SenderFactory.getSender(request.getType()); sender.send(request); processedCount++; LOGGER.log(Level.INFO, "Request {0} processed successfully", request.getRequestId()); } /** * Processes a list of requests. */ public void processAll(List<NotificationRequest> requests) { for (NotificationRequest req : requests) { send(req); } } /** * Prints the final statistics. */ public void printStats() { System.out.println("Processed: " + processedCount); System.out.println("Duplicates skipped: " + duplicateCount); System.out.println("Failed: " + failedCount); } } // ---------- Main Demonstration ---------- public class Main { public static void main(String[] args) { NotificationService service = new NotificationService(); List<NotificationRequest> requests = Arrays.asList( // Valid requests new NotificationRequest.Builder() .requestId("1") .type(NotificationType.EMAIL) .recipient("user1@mail.com") .message("Hello email") .build(), new NotificationRequest.Builder() .requestId("2") .type(NotificationType.SMS) .recipient("+79990001122") .message("Hello sms") .build(), new NotificationRequest.Builder() .requestId("3") .type(NotificationType.PUSH) .recipient("device-123") .message("Hello push") .build(), // Duplicate of requestId "1" new NotificationRequest.Builder() .requestId("1") .type(NotificationType.EMAIL) .recipient("duplicate@mail.com") .message("Duplicate") .build(), // Invalid: null requestId new NotificationRequest.Builder() .requestId(null) .type(NotificationType.EMAIL) .recipient("nullid@mail.com") .message("null id") .build(), // Invalid: recipient null new NotificationRequest.Builder() .requestId("4") .type(NotificationType.EMAIL) .recipient(null) .message("no recipient") .build(), // Invalid: email without '@' new NotificationRequest.Builder() .requestId("5") .type(NotificationType.EMAIL) .recipient("invalid-email") .message("bad email") .build(), // Invalid: SMS without '+' new NotificationRequest.Builder() .requestId("6") .type(NotificationType.SMS) .recipient("79990001122") .message("no plus") .build(), // Invalid: SMS with wrong length after '+' new NotificationRequest.Builder() .requestId("7") .type(NotificationType.SMS) .recipient("+123456") .message("short") .build(), // Invalid: PUSH empty message new NotificationRequest.Builder() .requestId("8") .type(NotificationType.PUSH) .recipient("device-456") .message("") .build() ); service.processAll(requests); service.printStats(); } }
Теперь вывод: у сеньора промпт лучше. За 10 минут он еще кофе с сигаретой прикончить успел.Полюбому

MishaBucha Автор
19.06.2026 10:43Оценку по времени давал не я, а они, так что чем он занимался остальное время, я не знаю))
И там же был смысл в том, чтобы добить нейронку до хорошего решения, я же не сказал, что там был 1 запрос)

Wosk1947
19.06.2026 10:43С посылом статьи согласен, но вот с аргументацией как будто бы неочень. Я по бумагам синьор-помидор, и на жабе уже лет 10 пишу в энтерпрайзах различной величины и степени кровавости. Если бы я сейчас получил такую задачу, то я написал бы решение как в самом первом листинге. Потому что уже не раз видел, до чего доходит вся ваша "архитектура" с чистым кодом. На проектах 10+ лет оно превращается в бесконечное месиво из абстракций, у некоторых сущностей десятки уровней наследования, фабрики фабрик и прочее чистокодовое нечитаемое говно. Вот когда надо будет масштабировать (спойлер, в 99% случаев оказывается не надо), вот тогда отмасштабирую. А сейчас - самое простое и тупое школьное решение, которое можно легко окинуть взглядом и понять за секунду имея одну извилину.

EskakDolar
19.06.2026 10:43А куда джунам деваться ? От них требуют умение пользоваться ИИ, иначе на работу не возьмут.

FixicusMaximus
19.06.2026 10:43На мок-собеседованиях ребята знают все, отвечают, будто они сами придумали этот термин или метод. Но как только дело доходит до самостоятельного кодинга - люди теряются.
Зазубрить не значит знать, а знать не значит понимать. А что-то понимать в программировании без навыка работы с кодом очень сложно.

Seyr
19.06.2026 10:43Увы. Все всегда хотят побольше и подешевле. До ИИ это было невозможно.
Сейчас ситуация изменилась. Один тратит 4 часа на задачу, второй справляется за 5 минут. Кого наймут? Даже если решение плохое, оно работает. Оно приносит деньги прямо сейчас.
Даже если есть желание учиться и делать качественно, без коммерческого опыта реальной разработки этого достичь невозможно. Не тяжело, невозможно.
До ИИ не было джунов, способных решать задачи за 5 минут. Поэтому бизнес процесс был подстроен под осознание этого факта.
Очень часто джун был бы рад, будь у него место в настоящей команде, где платят минимальные деньги (речь не о 30 000, а чтобы был свет, интернет и пачка сосисок с чаем) и ставили адекватные джуну задачи. Но он будет делать задачу 4 часа и практически всегда бизнесу выгоднее нанять оператора клода, а не классического джуна старого поколения. Классический джун со стороны бизнеса-это как платить за обучение студента без гарантии, что он останется работать у тебя. Вайбкодерский джун-это прото лоу грейд кодер, закрывающий задачи уже сейчас.
Dhwtj
План по валу?
Вал по плану©
Больше говнокода богу говнокода! ©
MishaBucha Автор
Хуяк хуяк и в продашкн)