Я регулярно участвую в хакатонах и конкурсах для разработчиков. При всей прелести основной работы, в ней частенько не хватает творческой активности, поэтому меня спасают конкурсы с относительно свободными задачами. Там можно не только выиграть ценные призы, но и поделать что-то нестандартное. А это и приятно само по себе и полезно для программиста, как источник новых знаний и нового опыта.
В этот раз мы с командой приняли участие в хакатоне от Яндекса и Великого Новгорода. Цель была такая: создать навык (то есть голосового чат-бота) для «Алисы», который будет интересен гостям и жителям этого города. Подробнее в статье.
#dev#hacks
https://teletype.in/@clockstackwheels/novgorod-hack
Несколько лет назад на конференции TechTrain я впервые сыграл в Code in the Dark. Два разработчика параллельно садятся за компьютеры, запускается таймер. Дается картинка, которую нужно сверстать в HTML, но важный нюанс: ты не видишь результат до самого конца, пока не отправишь своё решение. Вёрстка вслепую. Если где-то поехало, можешь вообще всё сломать, но не узнаешь об этом. Мне очень понравилось, но я никак не мог придумать, как бы подобное соревнование выглядело для бэкенд-разработчиков.
А тут вот на стенде Контура была версия как раз для бэкендеров: даётся набор данных, отражающий валидные вводы и выводы для неизвестных юнит-тестов, и нужно закодить функцию, которая пройдёт эти тесты.
Сыграл дважды, один раз догадался о принципе, но не смог реализовать (видеть вывод твоей функции нельзя, вслепую я не учёл важный краевой случай), а второй раз решил с небольшой подсказкой от организаторов. В общем, это как задача с литкода уровня Easy, но саму задачу ты не видишь, только правильные кейсы.
Мне понравилось. Нужно на вечеринках с коллегами играть :)
#dev
Выступил на DotNext сегодня, уже второй раз в жизни. Вообще, во времена хайпа ML и нейросетей было любопытно подать доклад, который рассказывает о том, как обойтись БЕЗ нейросетей и сделать всё на привычных алгоритмах. Видимо, не один я устал от ИИ, народу было достаточно, прошло вроде хорошо.
Сходил на четыре других доклада, и, пожалуй, с точки зрения докладов этот год лично для меня один из лучших, потому что два прям очень зашли: увидел то, что хотел по темам, всеобъемлюще, с ответами на возникающие в процессе вопросы. Вообще, нередко авторы боятся показывать совсем азы и тривиальные вещи — возможно, чтобы доклад не казался слишком простым. Но вот мне при введении в любую новую технологию или новый подход часто не хватает как раз основ. Чтоб прям с фундамента разжевали. И тут наконец-то такое было.
А вот со стендами дела похуже, имхо — из известного бигтеха только Озон и Контур. Завтра второй день, пойду подробнее посмотрю, что там. И да, снова сама конференция не предложила никакие тематические наклейки, и непонятно, что клеить на ноутбук :)
#dev
Друг делал уборку у себя и обнаружил мою книжку. Двадцать лет у него хранилась. Именно с неё де-факто началось моё изучение программирования. Первые две части про то, как во флэше рисовать, а вот третья — о программировании на ActionScript 2 (тогда ещё), причем очень подробно, с самых основ.
До сих пор считаю убийство Флэша одним из наиболее деструктивных и вредных для человечества действий компании Apple.
Кстати, изучать программирование на движущихся графических объектах было прям очень вдохновляюще. Ничто не давало такую мотивацию, как созерцание того, как тела летают по экрану согласно заданному тобой принципу.
Еще в комплекте с Флэшем был набор демок, и, запуская каждую из них, я думал "Хочу уметь так делать!". Одна из мечт, которые сбылись полностью.
#dev
Программисты пока могут не бояться ИИ.
В Росатоме работать с ИИ-агентами было нельзя, а вот тут в 2ГИС это даже поощряется, и компания сама оплачивает нужные доступы и лицензии. Практически любые модели на выбор, чаты, Copilot и так далее. Поэтому я попробовал выполнять прям настоящую энтерпрайзную работу при поддержке ИИ, и вот что скажу.
Во всех рекламах нейросеток говорят о том, как вам эта сетка позволит создать программу по текстовому описанию без разработчиков. Пожалуй, если создавать программу с нуля и аккуратно итеративно описывать требования, это может сработать. Только дело в том, что в реальной разработке мало работы по созданию с нуля и много работы по внедрению фич и исправлению ошибок. А для этого ИИ-агенту нужно, кроме умения хорошо кодить, ещё и знать (и понимать!) предметную область.
И тут начинаются проблемы.
Во-первых, в большинстве компаний предметная область нигде целиком не формализована в виде какого-то текста, который можно было бы передать в контекст. Я бы сказал, что единственный более-менее полный документ, описывающий предметную область программы — исходный код этой программы. И хорошо, если она сделана по какому-нибудь DDD, а если там хаотичные процедуры с высоким зацеплением?
Во-вторых, и это более важно, мы используем свои человеческие навыки и опыт жизни в окружающем мире, чтобы правильно понимать предметную область. Нужно именно что пожить в мире, чтобы понимать, как пить из пресловутого перевёрнутого стакана. И пока моделькам не получается передать всё многообразие человеческого опыта, люди в относительной безопасности. Ну, кроме тех, чья работа это просто кодить без обдумывания.
#dev
Тут незаметно подъехала свежая статистика по разработчикам от Stackoverflow. Каждый год я думаю о том, что надо бы принять участие в опросе, и каждый год пропускаю его. Судя по всему, его не рекламируют по почте, не присылают никаких уведомлений, не продвигают. В итоге мы получаем абсурдную картину, когда в статистике по странам разработчики из России представлены на одном уровне с Нигерией. Хотя понятно, что айти сектор в России очень развит и влияет на глобальные процессы (взять тот же Kotlin).
Так что, на эту статистику стоит смотреть, как на данные по США и чуть-чуть Германии. Ещё довольно высоко стоит Индия, но мы-то знаем :)
Ладно. Принципиально нового по сравнению с предыдущими годами почти нет. Три года назад я делал анализ графиков, чтобы дать ответ на вопрос: «Какой язык программирования учить?». С тех пор общие тренды остались плюс-минус такими же: вся [американская] разработка до сих пор сидит на Винде и пишет на JavaScript, потому что нет выхода, много использует проприетарщины и коммерческих облаков от монополистов.
В статистике Web-фреймворков React вдвое популярнее у разработчиков, чем jQuery, хотя, вроде как, 73% сайтов до сих пор на jQuery. Вывод понятен: значительная часть этих сайтов в сети не поддерживается, никакой активной разработки по ним нет. Это, кстати, важная причина, по которой не стоит использовать аргументы вроде: «На PHP до сих пор весь интернет, поэтому язык востребован».
Стоит отметить, что среди профессионалов наконец C# стал самым популярным языком с нормальной системой типов, если не считать TypeScript. Позиции Java уверенно падают который год. А ASPNET Core самый популярный Web-фреймворк с нормальной системой типов (но так было и раньше, даже три года назад).
Остальное ожидаемо: PostgreSQL, Docker, VS Code в топах по использованию.
Ну, и большая секция про ИИ. Почти все используют LLM, но почти все просто общаются в чатах, а не применяют какой-нибудь агентный режим. 66% опрошенных сказали, что в ИИ их фрустрирует приближенность ответа к правильному, но всё-таки не до конца («AI solutions that are almost right, but not quite»). И почти половина отмечает, что дебаг нейросетевого кода отнимает больше времени. Хотя тут, мне кажется, эффект в том, что дольше дебажить код, который писал не ты, и не важно, ИИ там или другой разработчик.
Я кстати и сам после первых восторгов от Cursor немного поубавил свой пыл: реально большой проект на C# он не умеет правильно читать и понимает происходящее там довольно посредственно. DeepSeek, ChatGPT, Claude Sonnet — за всеми нужно внимательно следить и править их ошибки, ловить галлюцинации, не позволять творить дичь. Я бы сказал, что в моей рабочей практике ИИ это просто очень быстрый поиск и агрегация материала по тому, как что-то сделать. Но делать нужно самому.
#dev
Нейросеть очень не любит соблюдать DRY, поэтому её частенько нужно заставлять отдельной командой обернуть повторяющуюся логику в методы, вынести константы в конфиги итд.
Но вот еще забавная вещь. Я тут делаю софт для чтения данных по ModbusRTU, и кодом на питоне эмулирую устройство, чтобы читать его потом кодом на сишарпе. У устройства есть 16-битные регистры. Если нужно записать int32 или float, используются два последовательных регистра.
В общем, пишу в эмулятор, а при чтении какая-то чушь, все числа другие. Поменял порядок байт, всё равно чушь. Несколько часов отладки. Описываю нейросети проблему, она всякое пытается сделать, и нифига. В основном тоже байты местами меняет, то туда, то обратно. Нет результата.
Потом я вычитал сразу пару десятков регистров подряд и вижу, что они смещены на единицу. Проверил: и правда, в эмуляторе пишешь в регистр 2277, а при чтении это число в регистре 2278. Проверил внешней программой: ошибка именно в эмуляторе, читается правильно.
Лезу в гитхаб той питоновой библиотеки, которую нейросеть предложила. Нахожу старый закрытый issue с такой же жалобой, а там в ответ: "as intended due to historical reasons...".
Сетка даже предположить не могла, что кожаные мешки просто хрень сделали. Даже не смотрела в эту сторону, с её точки зрения библиотека должна была работать без ошибок. Так что пока нейронки не могут, так сказать, думать за пределами коробки, а мы можем.
Но когда-нибудь научатся, конечно.
#dev
В общем, была задача на оптимизацию плана работ: есть набор заказов, и в каждом N тасков. Таски могут зависеть друг от друга или нет, имеют длительность и тип. Ещё есть M работников, каждый из которых может выполнять таски только определённых типов, причём, у каждого своя скорость.
Если все таски в заказе выполнены, фирма получает сколько-то денег. У заказа есть дедлайн, за просрочку штраф (за каждый день просрочки), который вычитается из цены заказа. И ещё фирма тратит деньги за каждый день своей работы независимо от того, как загружены её сотрудники (то есть просто платит зарплаты по сути). Ещё важен учёт праздников и выходных.
Нужно заработать на определённом наборе заказов и работников как можно больше денег. Полный текст задачи и код программы проверки есть в репозитории. Эта задача является изменённым заказом, который мы с напарником решали в реальной жизни: оптимизация работы печатных станков для типографии. Правда, тогда и мы справились так себе, и заказчик в итоге сначала захотел всё вручную сам делать, а потом и вовсе похоронил проект при смене директора.
!!! Не читайте дальше, если хотите сначала попробовать решить самостоятельно, потому что я сейчас опишу эффективные подходы и результаты.
________________________________________
Так вот. Мы с другим экспертом Андреем сразу сели и написали разные варианты, чтобы задать шкалу, по которой будем оценивать решения команд. За пару часов я собрал примитивный жадный алгоритм, который сортировал заказы по прибыльности и укладывал в сетку кое-как, это дало нам нижнюю оценку. Мой алгоритм заработал ~75 млн виртуальных рублей, мы решили для оценки поставить нижней границей 40 млн. То есть всё, что ещё ниже, оценивалось в ноль баллов за качество оптимизации.
Затем Андрей закрылся дома на три дня и вышел на свет со сложным жадным алгоритмом, который очень хитро сортировал заказы и очень хитро укладывал их в сетку, попутно выбирая разные способы этой укладки в зависимости от конкретного заказа. Это позволило заработать ~275 млн рублей. Мы сделали верхней границей для оценки 280 млн.
К сожалению, в итоге только две команды из десяти прошли нижнюю границу, заработав, соответственно, ~91 и ~105 млн. К верхней границе не приблизился никто. И у четырёх команд алгоритм вообще не смог уложить без нарушений задачи в сетку (то есть, например, произвольно менял длительности, накладывал задачи друг на друга, давал одному работнику две задачи в один момент и так далее). Важной ошибкой команд, на мой взгляд, являлся тот факт, что никто не воспользовался возможностью запустить алгоритм на несколько минут и дать ему поработать. По условиям задания, можно было тянуть до 5 минут на одну оптимизацию, но по факту решения команд отрабатывали за единицы и десятки секунд.
На самом конкурсе, пока команды работали, я решил попробовать сделать быстрое (по времени написания) но эффективное решение. Сначала попробовал жадную сортировку + доведение до лучшего варианта методом имитации отжига. В качестве нового состояния я просто менял местами заказы целиком. Этот вариант работал пару минут и дал мне около ~200 млн дохода. К слову, команда-лидер использовала такой же подход, просто не докрутила число итераций и температуру.
Ну и потом я взял готовую либу по реализации классической генетики с особями и скрещиванием. Особью был массив с приоритетами заказов (которые конечно же нужно было аккуратно уложить чистым алгоритмом). Тип скрещивания: scattered. Всего 15 поколений по 20 особей, и это за минуту-полторы давало ~230-240 млн. Считаю, что для конкурса это самый лучший выбор: пишется одним человеком за день и даёт почти максимум, при этом легко настраивается на нужную длительность работы, легко параллелится.
Ну а потом уже дома я посидел и накодил свой вариант сложного жадного с плавающим окном перебора отсортированных заказов и плавающей же укладкой по работникам. Такая штука за две минуты зарабатывает ~281 млн. Но за три дня в условиях стресса я бы такое не сделал, скорее всего.
#dev
Ух, очень продуктивная была поездка. Наши взяли золото, причём, в этом году организаторы решили наградить в том числе экспертов по подготовке, чьи команды выиграли. Не надеялся я, что когда-нибудь ещё раз (после победы в 2022) поднимусь на эту сцену и получу медаль, а оно вот как сложилось.
Наверное, по эмоциям от AtomSkills один из самых сильных эффектов. С ним соперничают, разве что, мой первый хакатон VK Hack 2018, и крупнейший в мире хакатон «Цифровой Прорыв», сильно изменивший мою последующую жизнь.
В любом случае, каждый год AtomSkills это очень масштабное и классно срежиссированное мероприятие с большим количеством впечатлений, интереса, опыта. А сейчас вот был юбилейный чемпионат — десятый, и такой подгон. Два года не брали медалей, и никогда раньше в нашей компетенции не награждали тех, кто привёз команды. Видимо, мои хакатонные боги-покровители решили, что я засиделся.
В задание тоже удалось привнести некоторую новизну. В целом схема такая: эксперты совместно делают задание, придумывают шкалу оценки и критерии. Но при проверке решений каждую команду смотрят только те, кто к этой команде не имеет отношения. При этом критерии оценки это в большинстве своём объективные предикаты, на которые решение проверяется. Например, в критериях может быть фраза «Система позволяет создать нового пользователя: да (3 очка) / нет (0 очков)». Де-факто споров почти не возникает, коллегия экспертов почти всегда сразу видит и понимает, засчитывается тот или иной критерий или нет. Субъективные части в оценке тоже есть, но их влияние на результат в разы меньше, чем в обычных хакатонах. И да, важнейшее ключевое отличие: на AtomSkills решение каждой команды обязательно разворачивается независимо на пустом компьютере и прогоняется через бизнес-сценарии. Нельзя наврать в презентации, будто бы ты что-то сделал, чего нет. Нельзя сделать решение на моках или фейковое. Нельзя вытащить только на харизме и софт-скиллах.
В этом году мы, как авторы задания, к обычной энтерпрайз-части добавили алгоритмическую задачу. Стандартно командам предлагается сделать мини-CRM или нечто подобное в заданном домене, что увеличивает влияние заготовок. Если принести с собой слишком много подготовленных форм, CRUD'ов, конфигов и так далее, это экономит тебе много времени, и ты в итоге просто выигрываешь из-за форы. Сейчас же в мини-CRM была специальная функция: написать алгоритм оптимизации расписания работ. Детали задачи я расскажу завтра, но в целом никакие заготовки не помогали решить это эффективно, если не знать задачу заранее (а она до конкурса скрыта, и разглашение карается дисквалификацией).
В итоге лично на мой взгляд итоговый балл получился очень взвешенным:
— Если команда сделала хороший алгоритм и не провалилась при этом по обычной не-алгоритмической части, она набирала много баллов (как наши)
— Если команда сделала неэффективный, но работоспособный алгоритм, у неё был шанс вывезти за счёт супер идеального вылизанного исполнения не-алгоритмической работы (такие получили серебро и бронзу)
— Если алгоритм у команды не заработал вообще, то даже при супер идеальном остальном решении в тройку она не попала
— Если алгоритм у команды был хороший, но имелся сильный провал во всём остальном — она вообще оказывалась ниже середины
В общем, не знаю, попаду ли в следующий раз, но воспоминания и опыт невероятные.
#dev
Попробовал этот ваш Cursor. Мне прям несколько человек независимо советовали.
Ну, что могу сказать, да, вполне впечатляет. Точнее так: автокомплит хоть и хитрый, но лично у меня восторга не вызвал. Иногда угадывает очень круто, иногда очень плохо. А вот режим агента — это да. Я бы сказал, что это новый значительный качественный шаг в программировании. Большим моделям как раз и не хватало какой-то пристройки, которая позволяет им не только выдавать текст, но и совершать действия.
У вас как бы под рукой есть джун, который хорошо знает теорию и делает всё очень быстро. Он не понимает, зачем, не умеет проектировать, склонен к шаблонным решениям. Но всё равно теперь ваша работа состоит в том, чтобы аккуратно объяснять ему задачу обычной человеческой речью (в том числе на русском языке) и указывать на ошибки. Вся утомительная, но когнитивно простая рутина теперь делается за секунды вместо десятков минут. А рутины в разработке очень много, особенно если это продуктовая или заказная разработка на многословном энтерпрайз языке.
Стоит сказать, что Cursor, конечно, как и все форки VS Code, остаётся просто текстовым редактором, и ощущается соответственно. Если вы пишете настоящую программу на серьёзном языке, а не текстовый файл, то для надёжной работы вам всё равно параллельно нужно открыть взрослую IDE. Тем не менее, Cursor умеет читать структуру каталогов и учитывать устройство вашего проекта, а к контексту запроса в LLM можно вручную присоединять любое подмножество файлов.
Можно ли назвать это явным шагом к исчезновению работы программиста? Я искал информацию о том, какие профессии были уничтожены автоматизацией, и наткнулся на статью, где упоминались кучер и колёсник (тот, кто делал колёса для карет). Один из популярных комментариев: «Буквально вчера заказывал кучера, потому что свою карету отдал колесникам на ремонт помятого диска». Но это шутки, конечно. А так, есть профессии, где увеличение степени автоматизации в конце концов полностью исключает человека (расстановщик кеглей в боулинге, телефонистка, фонарщик), а есть те, где автоматика просто упрощает людям жизнь и помогает выполнять свою работу эффективнее (компьютер помогает математикам, экскаватор строителям, телескоп астрономам). В чём же отличие первых и вторых? Я бы сказал, что у вторых профессий есть факторы непредсказуемости, вызванные необходимостью создания нового. В расстановке кеглей новых задач не появляется, как и в переключении телефонных линий. А в программировании появляется, и вот почему: у человечества возникают как новые процессы, требующие автоматизации, так и видоизменяются старые. И это, по всей видимости, бесконечный процесс. Да, разумеется, сильный ИИ с сознанием и способностью принимать решения будет уметь всё, что умеет человек, и даже больше. Но до этой технологии нам далеко, и нейросети не являются тропинкой к ней.
Другое дело, что джуны теперь не нужны, простите. Там, где раньше требовалась команда из сеньора, пары мидлов и пары джунов, теперь справится один сеньор, ну может ещё с одним мидлом, и всё. Советую всем начинающим программистам учить не то, как делать, а то, почему нужно делать именно так. Архитектуру, паттерны, принципы, лучшие практики. Тогда в уходящий айти-поезд ещё можно заскочить.
#dev
Первоначально я очень скептически относился к написанию кода нейросетками. Но при этой оценке я допустил ошибку: пробовал технологию на сишарпе, который, во-первых, знаю хорошо, во-вторых, на котором пишут в основном всякий энтерпрайз, где важна архитектура.
Нейросети раскрываются, когда тебе нужно закодить чисто утилитарную вещь на малознакомом языке. Архитектуру ты всё равно строишь сам, да и проверить существующий код в большинстве случаев можешь без проблем. Но при этом не обязан помнить, как там в какой-то популярной библиотеке называется нужный метод, или какие есть в этом языке нюансы синтаксиса.
Программирование это разговор человека с компьютером на языке компьютера. Нейросети делают шаг в сторону языка человека, но не так, как думают авторы новостных заголовков. Пока ещё в основном нельзя сказать «Сделай мне программу, которая посчитает деньги». Ты всё ещё должен иметь представление о структурах данных, алгоритмах, и, в общем-то, должен быть способен за вменяемое время написать такую программу самостоятельно. Поэтому и с нейросетью ты общаешься соответственно: «Два метода, в первый на вход поступает словарь с таким-то ключом, вытащи из него значения и отсортируй вот этим вот лямбда-выражением, второй метод проверяет пересечение таких-то двух выборок на непустоту и возвращает булев ответ, затем...». И вот это работает очень круто, потому что ты труба шатал помнить, что в этих ваших питонах None вместо Null или как там в каком языке инициализируется список.
А так можно написать проект в два-три раза быстрее и с тем же уровнем качества, что и сам.
#dev
Подумал о том, что у сезонного бизнеса куча времени на техдолг. Вот что делают программисты какого-нибудь Whoosh с ноября по март? Увольнять их и искать новых каждый сезон неэффективно. Зарплату им тоже на эти месяцы не снизишь, так как сами сбегут тогда. Да, они могут заниматься исследованием новых фич, но всё равно остается уйма времени на шлифовку всего существующего и разбор техдолга. Они в этот период даже могут выпустить в прод кривой билд приложения, и это никак не ударит по бизнесу. Мало где есть такие условия с этой точки зрения. Тем страннее, конечно, наличие сырых неработоспособных фич, по которым запущен маркетинг.
#dev
Yandex Cup это феерическое унижение, конечно. Набрал 229 баллов из 500, понятно что в финал не выйду.
Думаю мой реальный предел где-то 350-400. Но потратил слишком много времени вот на что:
1. В задаче А (на хеширование) быстро придумал решение, но сотню баллов мне система не выдавала. На каких-то краевых случаях тесты валились, в итоге я набрал 70, потом 75, потом 88. Надо было бросать и идти дальше, в таблице у многих участников эта задача не на 100. Но потерял лишний час, то есть 20% времени.
2. Задача D заключалась в угадывании мыслей авторов. Я обсудил её позже с одним из участников, попавшим в топ-10, и он сказал то же самое. Просто он мысли угадал, а я нет, хотя концептуально я правильно решал. И тоже залип на ней, поскольку было ощущение, что я не учёл какую-то мелочь, и тесты падают из-за этого, а не потому, что она тупо сформулирована.
В итоге впопыхах взялся за задачу С на сложный SQL-запрос и не успел, хотя понимал, как. За частичное решение получил 21/100. Ну и задача B на алгоритм расстановки — единственное, что далось на максимум и без задержек, однако в ней я, как мне кажется, считерил, потому что придумал как захардкодить кейсы вместо алгоритмического перебора.
В целом, если исключить откровенно непродуманную задачу D, то, пожалуй, претензия у меня такая: в реальной жизни вы можете выяснить, по какой причине в конкретном случае программа не работает, а здесь не можете, и нужно гадать. И тут очень сильно решает опыт предыдущего участия, знание того, как мыслят авторы, и так далее.
Не знаю, буду ли пробовать в следующем году. По итогу впечатления скорее негативные, но и отыграться хочется.
#dev