Около десяти лет тому назад я работал в паре вместе со своим тимлидом над разработкой штуки, которая кешировала данные из базы или чем-то похожим. Продукт, который мы пилили, было невозможно запустить локально. Процесс разработки был следующим: делаешь изменения, собираешь джарник, закидываешь его по FTP на сервер, рестартуешь сервис из веб-консоли веблоджика или через терминал, ждешь 5 минут, идешь проверять свой кусочек. Не очень удобно и очень долго, цикл обратной связи очень медленный, работа неэффективна. Дело осложнялось еще и тем что на нескольких разработчиков выдавали один сервер и приходилось синхронизироваться с коллегами.

И вот, у нас опять что-то не работает, и тимлид делает следующую вещь: добавляет в настройки веблоджика какую-то штуку, создает конфигурацию в IntelliJ и включает remote debug. После этого заходит на страничку с нашей функциональностью, нажимает кнопочку и дебаггер останавливается в нужном месте, позволяя нам понять, что вообще происходит. Я не помню, использовал ли я дебаг до этого, но факт того, что мы можем запустить что-то на удалённом сервере и остановить его, а потом получить себе в IDE контекст выполнения здорово взорвал мне мозг. Теперь можно было посмотреть, что происходит на сервере, какие объекты куда подгрузились и так далее и так далее.

Но самое интересное было потом. Оказывается, если подключиться дебаггером к серверу, потом сделать какие-то изменения в коде и перекомпилировать проект, то Idea предлагает сделать hotswap и заменить код на сервере свежесобранным. Вот тут я прозрел окончательно. Огромное количество девелоперов в той компании тратили время (часы, дни, недели!) на ребуты серверов, на пересборку и переподкладывание классов и джарников, на синхронизацию и тд и тд, а оказывается, что можно за секунду подсунуть JVM свои изменения и тут же смотреть на результаты.

Эта техника очень серьезно подняла мою продуктивность и первое, чему я учил свежеприбывших джунов — это как настраивать ремоут дебаг, как подключаться и как переподкладывать классы в рантайме, чтобы быстро вносить и проверять свои изменения. Кроме того, дебаггер был лучшим способом быстро понять, что вообще приходит тебе извне. Так как продукт был очень комплексным, то данные, перед тем, как прийти в точку назначения, проходили миллион слоёв платформы и других кусков бизнес-логики и функция evaluate expression здорово помогала посмотреть в потроха незнакомых объектов.

Интересно, что до сих пор я нечасто вижу людей, которые подключены к запущенному серверу приложений (даже локальному) и перекладывают там свои изменения. Вместо этого все предпочитают рестартовать код, или еще хуже, запускают CI/CD для того, чтобы протестировать свои изменения.

Интерактивность

Нередко можно услышать мнение что дебаг — вредная практика, отучающая программиста думать. Такое я слышал от своего босса на первой работе, такое можно прочитать у Егора Бугаенко, да много кто так говорит. Заместо дебага предлагают больше вникать в код, делать юнит-тесты на свои кусочки функциональности, которые этот самый баг воспроизводят, или обстоятельно логировать каждый чих своей программы.

И действительно, неоднократно я наблюдал своих джунов, пустым взглядом смотрящих в экран и механически нажимающих F8 (в IDEA). Однако для меня дебаг в первую очередь ценен не отслеживанием условных переходов и порядка выполнения команд, а интерактивностью и способностью динамически выполнять кусочки кода (Evaluate Expression). Например, работаю я с незнакомой библиотекой. Можно конечно, как приличный человек, упороться документацией и посмотреть примеры, а можно просто запустить дебаг сессию и потыкать методы с разными аргументами. Это я сейчас про компилируемые языки говорю (для простоты будем считать что это всё со статической типизацией и без встроенного REPL). На самом деле почти всегда я использовал дебаг сессию так — запустил, дернул метод какой-нибудь (иногда для таких целей просто писался тестовый эндпоинт который нужен был только для того, чтобы дать точку входа, а код внутри переписывался по многу раз, перегружаясь через hotswap), а дальше просто тыкаешь свои объекты и структуры туда-сюда, смотришь, как меняется состояние, где эксепшн а где все ок и так далее. В работе часто приходится иметь дело с беспорядочно структурированными чужими данными, особенно, если они приходят извне. Куда удобнее быстро повертеть их, понять где находится искомое, после чего уже спокойно писать боевой код.

Интерактивность есть самая недооцененная характеристика современных сред разработки. Для динамически типизированных языков всё просто — запустил REPL и пишешь там свои скриптики. В питон вот завезли Jupiter Notebook который это все дело превращает в мощнейший инструмент визуализации — Java-господам с зарплатой в 5k такое и не снилось! Только не надо говорить что в последнюю jdk добавили REPL — всё равно ним пользоваться никто не будет, потому что не научены правильной культуре разработки, привыкли на каждый чих приложение пересобирать да рестартовать, а самые молодые уже и не знают, что компилировать можно не градлом а идеей.

Вот на фронтенде казалось бы все хорошо — ведь там ничего не компилируется, JS прямо в браузере исполняется, бери пиши, да только успевай между IDE и браузером переключаться (самые умные умеют запускать браузер в IDE, поделив рабочее пространство пополам), но нет, и сюда добрались потные ручки инженеров из FAANG, и вот фронтендер, который еще вчера бойко писал динамические странички на jQuery, сегодня понуро слушает свист вентиляторов своего макбука, напрасно пытающихся умерить пыл не на шутку разгулявшегося вебпака, который транспайлит накорябанное на ES2018 засунутое внутрь JSX в то, что будет понимать каждый браузер.