melikhov.dev
@melikhov_dev·Разработчик·4.6K подписчиков
AI-саммари
Два месяца не пишет код руками — и доволен. Открыто говорит, что кодирование может исчезнуть «пугающе быстро», и воспринимает это с философским спокойствием: 30 лет писал код, а сам процесс написания никогда не был источником удовольствия — интереснее было комплексное решение задачи. При этом настаивает: тысячи строк нейронного кода надо вычитывать — иначе рискуешь потерять понимание кодовой базы и начать производить код, который пахнет правильно, но разваливается при первом же касании. Последовательно выпиливает сложность — выбросил LangChain, удалил memory banks и .roo, снёс все MCP-серверы, заменил curl-скиллами. Перешёл с Claude Code на Pi-харнесс и гоняет два чата параллельно: Opus/Sonnet пишет, GPT критикует; для дайджеста навайбкодил Python-стек: Telethon + feedparser + DeepSeek v3.2 через Yandex AI Studio + SpeechKit — всё по крону в Telegram.
А вот на фоне этих новостей, про опенсорсивание экстеншена Copilot. Меня тут не беспокоит потенциальная смерть Cursor (а как мы знаем давно строить бизнес поверх чужого продукта — штука опасная). Я так-то вообще курсором пока не проникся, мне хватает Roo + наш Code Assistant, который наконец-то заменил мне Codeium (TIL он теперь windsurf)
Мне стало интересно, а что там в мире JetBrains происходит? Вижу, что рядом ребята сидят и держат открытыми Idea и Cursor/Roo. Одно для кодинга, второе для вайбинга. Гуглёж подсказал, что пилится свой агент Junie, но что там под капотом? Какая моделька? И какая бы она прекрасная не была — хочется же менять и пробовать разное. И для NDA локальные модельки нужны.
В общем если кто в курсе — покидайте статьи/доклады, что там у JB, какой курс.
Все побежали и мы побежали
Ну как, выбор между Roo и Cline сделали? На Claude, небось? Мемори банки собрали? В своей продукт добавили агента? А моделька в продукте у вас какая — Qwen или DeepSeek? Как так нет локальной модели, а куда вы будете грузить пользовательские данные? А как тюнили под задачи, RAG? А MCP-сервер уже запилили? В опенсорс его закинули?
Что ж так быстро-то всё меняется, выдохнуть некогда. Архитектуркой бы позаниматься, долги позакрывать. Но некогда. Рынок требует AI. Надо пережить эту волну, но кто бы знал, какая будет следующая.
Все так хвалят Cursor, но почему-то никто не пишет про проблемы с Remote SSH.
Есть разный набор танцев с бубном, которые вроде как позволяют что-то завести (например, попробовать поставить версию постарше, до блокировок от Microsoft), но как-то оно попахивает.
Останусь пока на VSC + Roo + Codeium
Спасибо, гпт! А я годами сохранял во временный файл
Наверное самая впечатлившая (и даже пугающая) меня технология из 2024 — это нейропереводы видео в Яндекс Браузере. Да, в 2023 уже был у нас крутейший HeyGen, который даже оставлял голос и синхронизировал движение губ. За деньги. Но вот у нас массовый и бесплатный перевод закадровым голосом по кнопке. Всё ещё не могу отделаться от ощущения, что на самом деле это сидят синхронисты на зарплате и никакой технологии под капотом нет.
Вот открываю свежее видео от MPJ (да, он вернулся и запустил курс по D3.js и data visualization), хохмы ради жму кнопку перевода и меня взрывается голова, потому что так не может быть, потому что ещё вчера мы максимум могли получить только корявеший перевод субтитров, а сегодня робот читает с выражением и не пасует перед техническими терминами.
Думаю, что смотреть так англоязычные видео по кодингу пока не стоит, но вот когда этот пока закончится и дети даже не будут думать учить языки? Когда я сам сдамся и перестану слушать в оригинале, потому что ну зачем?
Технические итоги года
Мне в Яндексе повезло попасть в команду, которая живёт в Гитхабе. Редкий случай для компании, мы не держим код в огромном общем монорепозитории (но мне иногда хочется переехать в свой маленький). И всё то бесконечное количество работы, сделанное за год — вот оно, на зелёном ковре с серыми клеточками отпусков и выходных. Было много работы, было много кода.
Основным рабочим направлением в этом году стала изоляция пользовательских (чужих) скриптов в node.js и в браузере. Копал весь год, пробовал, собирал знания в доклады. Начал обкатывать тему ещё весной в Алматы, бета-версию прокатил в Уфе и финализировал уже как надо в Петербурге на юбилейном Субботнике. Редкий случай для меня, когда за доклад совершенно не стыдно.
В конце года пошёл закрывать пробелы в знаниях, прохожу на Практикуме курс по веб-пентестингу. Рядом лежит незаконченный курс на инженера облачных сервисов, надо и его добить. На следующий год у нас запланировано много Кубернетиса, фронтенд стал совсем не простым. И кто же его таким сложным сделал, кто, я спрашиваю?
Гаджеты года
В конце прошлого года купил стимдек. Железка очень прикольная, но игры опять меня не затянули. Продал. Уж не знаю, хорошо это или плохо, но игры скорее меня утомляют, чем дают удовольствие. Впрочем, Portal 2 был не плох и не забрал много времени.
Весной немного сломался айфон. Телефон уехал на пару месяцев в гарантийный ремонт и пришлось выбирать с чем теперь ходить. Выбрал Pixel 7 и стойко держался. Как только ремонт закончился — тут же перепрыгнул обратно. Причины: ну во-первых Pixel 7 это лопата. Большая и скользкая. А я люблю пользоваться телефонами без чехла (в чехле это какая-то мега-лопата уже). Во-вторых интерфейсы какие-то... ну вот чуть чуть не доделанные. Тут бы шрифт покрупней, тут бы отступы побольше, тут бы анимации плавнее — и другое дело было бы. Кажется, можно сделать ещё один заход, но нужно выбрать что-то поменьше и поприятнее. В том числе тактильно поприятнее (как же хорош простой айфон 15 без чехла: матовая спинка, алюминиевые боковинки).
Оставшись без телефона я тут же лишился и часов. Умные часы мне не нужны, а вот трекать физическую активность я люблю. Пришлось окунуться в мир Garmin и теперь у меня на полочке стоят ряды коробочек с велокомпьютером, нагрудным датчиком и часами. Часами — потому что начал с Vivomove Trend. Красивые, но достаточно бесполезные часы без GPS. Зато со стрелками, которые вечно сбиваются со своих позиций когда трясёшься на велосипеде по гравийным дорогам. Поменял на Forerunner 255 на MIP. Что хочу сказать: заряжать часы не каждый день, а иногда — это свобода почище скайпа. Реально классно. Кнопки на часах это тоже очень здорово. Из минусов — относительно красивые часы Garmin делает только за очень большие деньги, даже думать страшно. Красивые интерфейсы Garmin не делает никогда. Так что хочу посмотреть ещё на Suunto Race S. Финны, не подкачайте.
Купил в этом же году Kindle Scribe на замену вечно разряженному айпаду. Scribe хорош всем, кроме веса. Если вам не нужно читать PDF, то лучше смотреть на версии поменьше. Перо в комплекте прикольное, но с каждым днём я достаю его всё реже. Не стоит того.
Рюкзак года
Достал с антресолей старенький Pacsafe Vibe 40 и так он мне зашёл в поездках! Фактически это чемоданчик на лямках, без кучи карманов, но с очень удобным большим отделением, которое открывается как тот самый чемодан. А большего мне и не нужно.
Что по фитнесу?
Отчаянно борюсь с возрастным замедлением метаболизма. Несмотря на две тренировки в зале в неделю плюс велосипед/сноуборд по выходным, буксую на месте, медленно подползая к психологической отметке в 100 кг. В принципе-то нормально на мои 190 см роста, если бы это были мышцы. Успокаиваю себя, что без спорта было бы хуже. Не затягивайте до 40, с нашей-то сидячей работой и вечными переработками.
Ну вот кажется и всё. За кадром осталось куча важного, про которое вам знать не нужно, да и не место этому в технических итогах.
Всех с наступающим, остаёмся на связи, держимся!
Typescript теперь и в Node.js?
В свежем выпуске мы затронули нашумевший PR. Что случилось то? А случилось такое, что в Node.js подвезли в экспериментальном режиме загрузчик для ts файлов. Работает он очень просто (правда просто). В ноду вшивается SWC в виде скомпиленного для WASM бинаря. TS файлы прогоняются через SWC и из них отстреливаются типы. Всё. Enum и namespace не работают (о счастье). Никакие транспиляции трансформации не производятся. Просто отстреливаются типы.
Есть ли проблемы? Конечно есть. Например, нужно писать расширение файлов в импортах. Потому что импорт так работает бай дизайн.
Почему это круто и важно? Потому что транспиляция раздражает. Потому что хочется всё иметь из коробки и без настроект. Накидать ts-файлик и запустить.
В общем, неожиданно и очень приятно.
UPD Почитайте роадмап обязательно (спасибо @kravetsone, что напомнил)
Бэкстейдж, кстати. В этот раз сильно меньше недоволен результатом, получилось упихнуть в полтора часа больше полезного и гораздо меньше воды. Уже не медь, но до золота ещё пара итераций нужна.
Блуждающий ECONNRESET
Достаточно частый кейс в node.js-разработке, когда мы видим в логах блуждающую ошибку ECONNRESET при запросах в другой бэкенд. Начинаем искать, идём на вторую машинку, а там тишина, ошибок в логах нет. Как обычно отвечают — у нас всё хорошо, проблемы на вашей стороне.
Одна из причин это включенный keepalive. Идея keepalive в том, что мы можем переиспользовать коннекшены, не создавать новый коннекшн на каждый запрос. Клиент стучится на сервер, открывает коннекшн, удерживает его и при следующем заходе обращается к уже созданному коннекшену. А что произойдёт, если клиент удерживает коннекшн дольше, чем сервер? Т.е. сервер имеет например keepalive_timeout 4, а клиент создал http.Agent с timeout: 5? Мы и получим тот самый ECONNRESET.
И даже при равных значениях можно достаточно легко войти в состояние гонки:
import http from 'node:http';
const server = http.createServer((req, res) => { res.end('some stuff') });
server.keepAliveTimeout = 5000; //default
server.listen(1337, '127.0.0.1', startSendingRequests);
function startSendingRequests() { const keepAliveAgent = new http.Agent({keepAlive: true, timeout: 5000});
setInterval(() => { http.get('http://127.0.0.1:1337', {agent: keepAliveAgent}, (res) => { res.on('data', (chunk) => { console.log(`BODY: ${chunk}`); }); }).on('error', (e) => { console.error(`problem with request: ${e.message}`); }); }, 5000) }
Как решить проблему? Во-первых, если это возжно нужно покрутить таймауты. На клиенте таймаут должен быть меньше чем на сервере. Это даст возможность клиенту закрыть соединение самостоятельно, не дожидаясь ошибки.
Во-вторых, документация node.js предлагает такой паттерн ретрая:
.on('error', (err) => { // Check if retry is needed if (req.reusedSocket && err.code === 'ECONNRESET') { retriableRequest(); } });
UPD
И конечно важно помнить, что причины, по которым коннекшен может быть закрыт со стороны сервера — разные. Таймаут keepalive лишь один из случаев.