Попробовал, наконец, разработку на Blazor. Это такой фреймворк под .NET, который позволяет писать фронтенд на C#. Работает он двумя способами: либо собирает весь проект в WebAssembly, и бедный пользователь грузит себе мегабайтную dll, либо устанавливает клиент-серверное соединение через SignalR и шлёт клиенту информацию об обновлённых DOM-элементах.
Вот вторую то я и пробовал. Казалось бы — каждое нажатие кнопки требует отправить на сервер запрос и получить ответ. Никогда такого не было! Но субъективно разницы во времени отклика нет (потому что веб и так достаточно медленный, хаха).
Фронтенд-часть пишется очень похоже на JSX: вёрстка реактивно вперемешку с кодом. Когда-то я очень ругал React за такой подход, потому что каша. Но нетипизированный JS по-умолчанию каша, а здесь же по факту получается очень удобно: статический анализ не даёт тебе делать ошибки и писать ерунду.
Но приятный полноценный язык программирования вместо JavaScript это лишь вишенка на торте. Самое крутое — вся сила серверного кода с полноценной возможностью обращения к базе данных, шеринг моделей данных между сервером и клиентом, и, наконец, Dependency Injection любого серверного модуля в «клиент»! То есть вы не просто пишете одно приложение вместо двух, вы ещё и получаете отсутствие ошибок при каком-нибудь изменении моделей API, когда сервер стал отдавать не то, что ожидает клиент. Вам вообще теперь не нужен API, достаточно закодить нужную функцию на серваке и инжектировать её в нужный фронтенд-модуль.
Это супер удобно, супер быстро, супер устойчиво к ошибкам. Теперь не хочется возвращаться даже на вполне крутой Vue 3. Но, система пока новая, она не обросла решениями от комьюнити, а браузерный API всё равно придётся дергать через JavaScript Interop. Для совсем кайфа нужно подождать годик, поскольку развитие идёт довольно быстро. Например, там нет очень нужного в таком деле hot reload, но в .NET 6 он уже анонсирован, и вроде как есть в превью, а релиз в ноябре.
#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
Поучаствовал в квалификации Yandex Cup в блоке Backend. Сдал первую и последнюю задачу на максимум баллов (последнюю вообще с первого раза). А остальные две принципиально не стал решать, потому что меня бесит, когда путают бэкенд-разработку и алгоритмы. У них есть отдельная секция "Алгоритмы", куда я не пошёл, потому что не люблю олимпиадное программирование (вот тут писал в конце причины). Но нет же, давайте в бэкенд тоже засунем душноту про модульную арифметику.
В общем, дальше как судьба распорядится. Если все поленились или плохо сделали, пройду в полуфинал, иначе нет.
#dev
В этом году снова ездил на AtomSkills. Решил написать подробнее на Хабре о том, что там и как, уже с точки зрения члена жюри.
https://habr.com/ru/companies/rosatom/articles/824888/
#dev