Когда код становится legacy и как с ним жить

в 7:40, , рубрики: legacy, moscowpython, moscowpythonconf, python, Блог компании Конференции Олега Бунина (Онтико), Программирование, Проектирование и рефакторинг, рефакторинг, Совершенный код

Много лет назад, я пришел в один legacy-проект, который разрабатывал Владимир Филонов (pyhoster). Так я и познакомился с одним из организаторов MoscowPython, любителем копаться во внутренностях библиотек, а потом рассказывать об этом. Иронично, что теперь он собирается рассказывать, как выжить, если вам достался legacy. Это еще раз доказывает, что legacy порождают даже те, кто потом учит, как с этим жить. Мне очень хочется расспросить Владимира о том, что такое legacy, как им поменьше зарастать, как бороться, когда уже по уши в legacy, а когда всё бросать и писать заново (спойлер: никогда).

Но сперва посмотрите ролик, чтобы прочувствовать всю боль погружения в legacy…


— Давай для начала определим: когда код становится legacy?

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

Фактически legacy начинает появляться чуть ли не с первых месяцев жизни проекта, если в нём достаточно активная кодовая база. Дело не в том, что никто не продумывает наперёд полноценно архитектуру кода и вообще системы. Это просто невозможно сделать, если вы разрабатываете не что-то типовое, как интернет-магазин. Но на них уже и код сейчас не пишут, их делают из конструкторов.

Для всего, что сложнее интернет-магазина из коробки, формируют какое-то первичное представление, как-то его реализуют, а потом оказывается, что миру нужно было что-то немножко другое. Код начинает модифицироваться, но не весь, а только та часть, которая прямо соприкасается с миром. Начинается накручивание адаптеров, еще чего-то. Уже в этот момент появляется legacy.

Поначалу кажется, что это legacy достаточно безболезненное, его легко зарефакторить потом, а пока можно расставить TODO, возможно, даже завести тикеты на будущий рефакторинг. Такие задачи постепенно копятся, и появляется понятие технического долга.

Если попытаться на графике жизни проекта отметить точку возникновения legacy, то я бы сказал так: как только при взгляде на систему появляется ощущение, что есть технический долг — значит, legacy уже здесь.

— Ты затронул интересную проблему, что времени на рефакторинг некомпетентный менеджер либо выделяет очень мало, либо не выделяет совсем. Как ты думаешь, почему так происходит?

С точки зрения бизнеса, развитие продукта — это прирост функциональности или изменение требований, порождение артефактов для самого бизнеса. А рефакторинг в первом приближении не порождает ничего. Даже если имеющаяся система написана как попало, она как-то работает, иногда падает, но приносит бизнесу сносное количество проблем. Бизнесу непонятно, зачем рефакторить этот код и что это ему даст. Ответ, что в будущем при развитии это позволит избежать проблем, не удовлетворяет бизнес. Трудно увидеть проблему там, где их еще не существуют.

Будущие проблемы мало кого интересуют: упадет — будем разбираться, начнет тормозить — будем переделывать.

Аргумент снизить риски бизнес не понимает. Вот начнет тормозить, значит, будет больше клиентов и денег, а значит, можно будет купить больше серверов. Сложно донести технические аспекты, например, что далеко не всегда горизонтальное или вертикальное масштабирование даст прирост производительности. Кроме того большинство разработчиков не умеет говорить на языке бизнеса, тогда они вообще с трудом могут что-то донести. В итоге два департамента говорят на совершенно разных языках о разных вещах. Им никак не договориться, и поэтому обосновать, что рефакторинг что-то даст, зачастую очень сложно.

— На контрасте: как ты считаешь, как компетентный менеджер относится к этому вопросу? В чем разница двух крайностей?

Компетентный менеджер, скорее всего, уже имел опыт работы с legacy-системами и последствиями устаревания кодовой базы, разгребал проблемы, в том числе, с падением продаж, потому что сайт вдруг начинал отдавать «пятисотки» в 10 раз чаще, и клиенты не могли дойти до финальной стадии оплаты, например. Или просто не дожидались ответа от сервера и уходили в другой интернет-магазин.

Если менеджер однажды прочувствовал эти риски (или многократно, если он плохо учится на ошибках), ему уже не надо ничего объяснять. Когда ему снова скажут магические слова, которые он в прошлый раз не послушал, в первый раз по неопытности, скорее всего, начнет перегибать палку в другую сторону. И процесс разработки превратится в постоянный рефакторинг, начнутся гонки за непонятными показателями чистоты кода, покрытия тестами и т.д… В общем, баланс будет смещен в другую сторону.

И вот когда бизнес с другой стороны напорется на то, что развитие прекратилось, то придет к пониманию, что рефакторинг — это просто рутинный процесс, его нужно закладывать в процесс разработки. Если в компании в той или иной форме agile, то какой-то объем работы с техническим долгом нужно включать в каждый спринт.

Рефакторинг — это обязательная рутина. Когда она включена в процесс разработки, не возникает ни проблем, ни перерасходов на экстренное лечение накопившегося технического долга.

— Действительно, это, наверное, самый рабочий вариант. А какие есть практики, инструменты и подходы для того, чтобы как можно меньше зарастать legacy?

С точки зрения менеджмента это итеративная разработка. При плановой разработке, например, когда Waterfall сильно заранее спланирован, сложно выявить точки, когда и сколько нужно рефакторить, потому что непонятно, сколько компромиссов было произведено в процессе разработки. В итеративном случае проще: мы каждый раз видим, как прошел спринт, есть ретроспективы, и можно оценивать тот самый технический долг, порожденный в рамках предыдущих спринтов.

— Раз уж ты сказал «оценивать», то давай обсудим, а как оценивать технический долг?

Есть покрытие тестами, которое, конечно, не относится напрямую к рефакторингу и устареванию кода, но относится к качеству кода. Понятно, что в идеальном мире покрытие кода тестами должно быть 100%: разработчик что-то пишет и тут же полностью покрывает это тестами. Но на практике так не бывает, далеко не все покрывается тестами, тем более, тесты тестам рознь.

Мы все знаем, что 100% unit-тестирование еще ничего не доказывает. Особенно в современном мире, где гуляют микросервисы, нужны интеграционные тесты, end-to-end тестирование. Это точно делается отдельно от процесса разработки. Поэтому можно, например, оценивать прирост функционала не покрытого end-to-end тестированием, в каких частях есть ручные тесты и отсутствуют интеграционные. Это первое, что можно оценивать и на что сразу заводить тикеты как на технический долг.

Во-вторых, всё-таки нужно вкладывать больше времени в проектирование. Делая новый функционал, новый микросервис, нужно стараться использовать подход API first — сначала готовим схему взаимодействия (как вариант документацию в Swagger), а не начинаем писать код. Это снизит количество legacy, потому что позволит сначала понять, что должно быть на выходе, а потом к этому пониманию начать реализовывать код. Большая часть компромиссов, на которые требуется пойти, будут решены еще на уровне обсуждения этого контракта. Будущие зависимости от других частей сервисов будут предусмотрены сразу, и для них будут заложены входы и выходы.

Когда всё делается непосредственно в реализации кода, чаще всего это происходит так: сейчас воткнем костыль, потому что сроки горят, нужно закончить фичу в этот спринт. Если сначала делается дизайн и обнаруживаются проблемы на уровне проектирования, они решаются до того, как начали писать код и до того, как дали финальную оценку трудо и времязатрат. Многие проблемы можно разрешить на этапе проектирования, и меньше workarounds потребуется впоследствии.

Если вернуться к тестам, есть всем известный подход Test Driven Development. Я очень его люблю, но как у любого инструмента, у него есть своя сфера приложения. Я бы сказал, что действительно полезно использовать Acceptance test–driven development: когда мы описываем функционал, мы доставляем его с верхне-уровневыми тестами, которые проверяют, как он должен работать с точки зрения бизнеса на верхнем уровне, не касаясь реализации. Процесс формулирования этих тестов позволит лучше понять саму проблему. У конечного разработчика, в том числе, будет опорная точка, правильно ли он понял задачу.

Это один из моментов, когда появляется legacy: когда задача сформулирована неточно или не на том языке, который понимает разработчик.

Разработчик немного не так что-то понял, немного не так что-то сделал, подошло время релиза, оказывается, фича работает не совсем так, как было надо, это быстренько подпиливается напильником до того, что ожидал бизнес. При Acceptance test-driven development снижается риск, что мы напилим не то, что хотел бизнес, потому что есть тесты, которые показывают, что ожидалось.

— Мы уже затронули в нескольких вопросах эту тему, но о ней говорят намного реже, чем о проблемах с кодом. Как передавать знания, которые когда-то были, как-то отразились в коде, но естественно, не все и с искажениями? Что делать, если в команде не осталось ни одного человека, который знал что, где и зачем было сделано?

Это действительно очень большая проблема. В управлении даже есть такой антипаттерн SHOK — Single head of knowledge. Это одна из главных проблем с legacy, о которой я хочу рассказать в докладе на Moscow Python Conf++. Многие беды порождаются именно этой ошибкой, когда один человек, который сам всё разрабатывал и всё понимал, куда-то исчез. В более-менее мягких случаях он исчез частично, например, получил оффер и переехал в другую страну, но иногда отвечает на e-mail. Но встречается и действительно болезненные для бизнеса кейсы, когда такой человек никому ничего не сказал, на вопросы не отвечает и вообще ему плевать.

Тут есть две стороны: первая, о которой должен думать бизнес, вторая — о которой должен думать разработчик, если он планирует быть хорошим разработчиком. Бизнес должен формировать подходы к подготовке и принятию работы. Подойдут два простых механизма:Definition of Ready и Definition of Done.

Сначала договариваемся, как должна быть поставлена задача, чтобы считать ее пригодной к разработке. Это помогает разобраться, что же на самом деле нужно бизнесу, потому что бывает, заказчик просит одно, а на деле его боль может решить совсем другое. И, конечно, грамотно составленные задачи потом удобнее читать. Если приходит новый менеджер, он может прочитать тикеты нескольких последних спринтов и понять, что и как развивалось последнее время с точки зрения бизнеса.

Definition of Done в свою очередь о том, как у исполнителя потом принимать работу. К сожалению, часто менеджмент не понимает, как это правильно делать. Допустим, приходит разработчик, говорит, что закончил работу, что-то показывает, оно более-менее похоже на то, что у него просили. Но на практике всё внутри может быть сделано плохо или даже хорошо, но не документировано, тестов нет и т.д. Definition of Done помогает принимать работу просто используя список: например, если есть тикет типа баг, то нужно посмотреть шаги воспроизведения, проверить в CI системе есть ли регрессионный тест и т.д. Это, конечно, уже достаточно хороший кейс, когда есть CI-система и есть такой менеджер.

Но даже когда все гораздо хуже, и из менеджмента есть только руководитель стартапа, нет CI, нет ничего, а из исполнителей есть один программист, Definition of Ready и Definition of Done точно также помогают, просто становятся попроще.

Definition of Ready и Definition of Done с точки зрения передачи знаний очень удобный механизм. Он позволяет правильно обмениваться информацией.

Программист берет задачу только тогда, когда она отвечает Definition of Ready формально и по его субъективному впечатлению, а менеджер принимает готовую работу, когда она формально и субъективно соответствует Definition of Done. Если одна или вторая сторона в момент приемки задачи или результата объективно или субъективно не удовлетворена, начинается диалог, в ходе которого все что нужно уточняется.

Очень важно вести все эти диалоги в тех же самых тикетах. То есть если тикеты ставятся через Google-документ, используйте комментарии, если переписывайтесь по e-mail — пишите всё через e-mail. Никогда не меняйте механику. Если вы что-то обсудили по телефону, обязательно запишите follow up, иначе этот разговор потеряется. Даже можно записывать разговоры и выкладывать их в облако. Современные технологии коммуникаций позволяют фиксировать всё что угодно. Единственное, что мешает — это недостаток организованности.

Нужно добавить в процесс немного организации и передача знаний уже будет происходить. Она будет не идеальна, но она будет. Потому что самая большая проблема, когда разработчик исчез, приходит новый, спрашивает: «Что тут у вас?», а никто не знает, что у них. Но если есть вся история, пусть даже обширная, не очень упорядоченная, разобраться в ней может быть не быстро, но всё равно можно будет что-то понять.

Если позволяют ресурсы, есть время, идеальным вариантом будет ввести Вики и принять в качестве внутреннего регламента. Это тоже, кстати, относится к описанию Definition of Ready и Definition of Done. Если мы говорим о микросервисах или даже любых систем с API, то API обязательно должны идти через Swagger, то есть с документацией, описанием, моделями. Тогда сам API становится объектом документации.

В целом нагрузка на разработчика возрастает незначительно, потому что во всех современных фреймворках есть библиотеки, которые позволяют с помощью одного декоратора добавить документацию для автогенерации Swagger.

Плюс, начиная с последних версий Python появились аннотации типов, которые тоже многое позволяют. Я пока не видел инструментов генерации документации по аннотациям типов, но это позволяет сопоставить код и аннотации, и тоже занимает не так много времени, если закладывать с самого начала. Если внедрять позже, то надо заводить тикеты на технический долг в этой области, и постепенно, а не с наскока, пытаться всё покрыть аннотациями типов.

— Долгие годы меня не покидает вопрос: почему все инструменты, которые выходят на рынок, не придерживаются legacy-first? MyPy предполагает, что в коде сразу все хорошо, и если у тебя все плохо, то у тебя все плохо, не пытайся пользоваться MyPy. Как ты думаешь, почему люди не толерантны к legacy-коду?

Этот вопрос меня тоже занимает, поскольку в legacy всегда больно внедрять механизмы современных инструментов для повышения читабельности и документированности кода. Мне кажется, это во многом идет от того, что большинство разработчиков имеет подсознательное, а иногда и сознательное мнение, что любой legacy проще переписать с нуля. Это касается любого проекта с достаточно обширным legacy, где эти боли действительно больные. Конечно, если речь не идет о совсем крошечном наследии, то там и MyPy внедрить не сложно.

Из-за того, что большинство считает, что надо всё переписывать, раз уже всё плохо и пытаться это исправить ни к чему, и появляется это отношение, что если у вас обширный legacy, то большие удобные инструменты вам уже не помогут. Других разумных объяснений я не вижу.

— Отсюда сразу следующий вопрос, а как на самом деле понять, лучше переписать или можно спасти?

Одному моему коллеге когда-то приснилась некая «точка Кирха». Он совершенно не помнил, что это значит, но нам так понравилось выражение, что мы начали прикидывать, к чему бы его приложить. И в итоге придумали, что точка Кирха — эта точка в проекте, когда попытка оживить мертвую лошадь становится дороже попытки переписать все с нуля.

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

Более того, если у вас в руках система, которая разрабатывалась и уже проработала существенное время, то значит разработчики прошли по разнообразным граблям, связанным и с бизнесом, и с техникой. Поскольку эта часть legacy чаще всего не документирована, то при переписывании придется пройти по этим граблям снова. Скорее всего, решение, которое получится в конце, будет сопоставимо: либо оно будет плюс-минус такое же, либо займет гораздо больше времени.

Доказать бизнесу, что что-то нужно переписать, можно, если убедить, что это будет проще, чем поддерживать, а значит, вас сильно ограничат в сроках, и в итоге вы принесете примерно то же самое. Поэтому с переписыванием нужно быть очень аккуратным.

Я считаю, переписывать полностью никогда ничего не надо. Единственный разумный вариант, который я вижу, — это постепенное замещение.

Если есть большая монолитная система, и которую невозможно больше поддерживать, стоит посмотреть в сторону перехода на мультисервисы. Я не говорю микро, потому что они могут быть очень немаленькие и их может быть мало.

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

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

Мне кажется, это единственный вменяемый для бизнеса и для разработчиков вариант, который можно использовать, чтобы переделать большую старую систему — не переписать, а именно переделать, постепенно заменяя отдельные её части и не попадая в капкан.

Потому что если пытаться прямо в том же коде все переписывать, то неизбежно столкнешься с проблемой, что если попал в определенный код, ты все равно там вязнешь, потому что тебя тянут за собой не только чисто внешние зависимости типа баз данных, но и зависимости от классов, от местной модели и технологии. Если код написан на Python 2.7, ты не можешь взять и частично перевести его на Python 3.

— Вот мы и подошли к следующей важной теме: что делать, если не просто код стал legacy, но и сама платформа стала legacy? Как это меняет техники работы с устаревшим кодом или с проектом?

Если платформа стала legacy, то это большой сигнал, что надо перестать развивать старый код. Поддержка обязательно остается, но развивать с точки зрения прироста новых фич нужно заканчивать. А так, использовать итеративный подход с частичной заменой на новые сервисы или новый сервис, который потом разрастается, но уже на базе новых современных технологий. Можем взять старую систему на Python 2, и когда понадобится переделать раздел, сделать это уже на Python 3. Естественно, вся обвязка вокруг останется. Или не останется та часть, которую тоже можно перенести. Например, если это не просто Python 2, а Python 2 на PostgeSQL 7, а везде уже нужен PostgreSQL 12.

На Moscow Python Conf++ историй о том, как кто-то перешел со второй версии на третью, приличное количество. Но я не уверен, что все эти истории не ошибка выжившего. Неизвестно, сколько проектов попробовали, но не преуспели и откатились обратно или вообще никуда не прикатились. Боюсь, это как со стартапами — мы видим тысячи успешных, но не видим сотни тысяч мертвых. Кроме отдельных, основатели которых находят в себе силы выступить на Startup Fail Night и рассказать о том, как они эпично провалились. С проектами тоже такое бывает, но об этом почти никто не рассказывает.

— Как ты думаешь, является ли язык программирования сам по себе важным фактором, от которого зависит обрастет ли проект legacy?

Думаю, важным фактором является не столько сам язык, сколько экосистема. Разработчики Python действительно сделали многое, чтобы помочь разработчикам перейти с Python 2 а Python 3. Например, когда третья версия только появилась был даже выпущен специальный инструмент 2to3, который, конечно, не все решает, но помогает.

Переход со второго на третий Python был очень затяжной. Сколько лет существовала версия 2 и версия 3, и вторая достаточно неплохо поддерживалась, и какие-то фичи туда портировались. Разработчикам дали много времени, чтобы решить эту проблему. С точки зрения сообщества, по-моему, это был очень хороший процесс. Нас заранее предупредили, что не надо начинать новое на старой версии, что Python 2 все-таки перестанет быть поддерживаемым языком, пора переходить на Python 3.

Я уже много лет не встречал новых проектов, которые бы выбирали второй Python на старте. Так что эта механика сработала.

Но, с другой стороны, Python — язык с достаточно развесистым пакетным сопровождением. Есть много готовых библиотек, которые разработчики активно подключают в свои проекты. И часто бывает, что некоторые из них впоследствии не мигрируют на новую версию, то есть не поддерживаются адекватным образом. А у тебя, допустим, полсистемы на них стоит, и ты прибит гвоздями к этому фреймворку. И все — ты обречен.

Это как раз та ситуация, когда нужно постепенно переходить на новые фреймворки, и ничего не поделаешь, потому что нельзя ждать, что всё мигрирует.

То есть, конечно, экосистема влияет так или иначе. Я не уверен, что есть экосистемы, которые решают такие вещи более прозрачно. Но экосистема с тестами все-таки лучше выстроена в Ruby и, говорят, в Go. Если честно, я сам с Go работал очень мало и не могу говорить о том, что плохо знаю на практике.

А еще у меня в силу рабочих обстоятельств появился безумно неожиданный опыт с Clojure. Это очень академический язык, по сравнению с Python у него очень высокий порог вхождения. В Clojure качество инженерных подходов изначально выше, просто потому что разработчики выше уровнем. Я имею в виду, что инженеры, которые с ним работают, чаще всего уже с некоторым опытом. Джуны не пойдут в Clojure, а если пойдут, то мне их очень жаль.

В общем, у Python все не так уж плохо.

— А что самое дикое ты видел в коде?

Одна из самых диких вещей, которая есть в Python, она как привидение, дикое, но симпатичное — это метапрограммирование. Оно иногда порождает чудовищных гомункулов, тех самых хтонических чудовищ. А еще когда они не документированные, это становится адским адом: видишь код, читаешь его, но в рантайме его нет. То есть в рантайме происходит что-то совсем не то, и концов не найдешь, потому что мета-класс, мета-класс, мета-класс на мета-классе, они все друг друга порождают, и вообще не понятно, что же происходит. Единственный твой друг — это runtime debugging.

Еще достается много веселого кода, когда на Python пишет, например, бывший Java-разработчик. Приходишь в такой в проект и видишь по сути Java, всё совершенно не Python way. Сейчас еще многие JavaScript-разработчики начинают зачем-то писать код на Python и тоже творят бесчинства.

— Я собираю подобные примеры в коллекцию python-code-disasters. Кстати, вы можете добавить в неё и свой код, чтобы предостеречь других от ошибок.

На конференции корме доклада я проведу воркшоп, для которого обязательно найду какой-нибудь страшный-страшный код. Я воспользуюсь силой community для его поисков (если у вас как раз есть такие примеры, напишите в комментариях к статье или мне в facebook) и честно не буду смотреть до конференции. На воркшопе я открою legacy-код в первый раз, и в реальном времени попробую внести изменения так, чтобы гарантированно ничего не сломать. Задача воркшопа на практике разобраться, что к чему. Доклад будет более теоретический, и даже, возможно, капитанский, просто подкрепленный большим опытом. Но кроме рассказа о том, как не попасть в legacy или как выжить, когда уже попался, я хочу поделиться тем, как я разбираю legacy-код, потому что для этого в моем арсенале есть вполне портируемые инструменты.

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

— Раз уж заговорили о конференции, скажи, ты был гостем и активистом сообщества, членом Программного комитета, и сейчас докладчик: что меняется при посещении конференции в разных ролях?

Это все очень разный опыт.

Когда я первый раз пошел на митап, это был как раз самый первый Moscow Django Meetup. Это был 2012 год, я к тому моменту уже 9 лет занимался коммерческой разработкой и не был ни на одном мероприятии. Я вообще никуда не ходил, общался только в сети и видел вживую других разработчиков только в офисе.

Впервые придя на митап, я поразился ощущению, что вокруг меня люди, у которых болит то же самое, что и у меня.

Но только одни эту уже боль прошли и могут мне подсказать, как они с этим справлялись. А у других болит то, что у меня болело полгода назад, и я уже это полечил и могу сам поделиться рецептом.

Это было тем, что по-английски называется Wake Up Call — большое открытие. Я понял, что это очень классно, когда можно поговорить с людьми с похожими проблемами о том, как их решать, обменяться опытом. Собственно, после посещения первого митапа на следующем я уже выступал, потому что увидел, что у меня есть полезные другим знания. Конечно, это выступление сейчас смотреть мне было бы смешно и странно, но я делился своим опытом.

Потом я выступал еще несколько раз, и постепенно понял, что мой опыт исчерпывается. Для того чтобы сделать хороший доклад, нужно накопить приличное количество опыта, а накапливается он медленно. За одно выступление реализуется пара лет накоплений.

Но мне хотелось продолжать помогать людям в сообществе, поскольку когда я начинал программировать, не было ни сообщества, ни нормальных туториалов — почти ничего не было. Я помнил ту боль, когда ты ничего не понимаешь, всё, что у тебя есть, –форум, на котором какие-то индусы на непонятном английском что-то обсуждают. Я что-то знал, умел и хотел помогать другим, поэтому я стал помогать Валентину Домбровскому с сообществом MoscowPython с построением процессов: проведением митапов, организацией других мероприятий, в том числе несколько лет спустя принес в Россию Django Girls.

Первый раз в качестве члена программного комитета я участвовал в первом PiterPy. Там я открыл еще кое-что интересное и новое для себя: спикеры, чаще всего, это люди с гораздо более обширным опытом, чем у тебя, и в качестве члена ПК у тебя масса возможностей прочувствовать этот опыт, пообщаться, задать дополнительные вопросы. В отличие от простого участника конференции, который послушал доклад, немножко початился, и имеет 10 минут контакта, и то не персонального, потому что вокруг много других людей, которые тоже хотят общаться со спикером.

— Вот как мы с тобой уже час интересно общаемся.

Общение с программным комитетом, конечно, важно и для потенциального спикера, потому что это помогает точнее сформулировать идеи. Но и для меня в роли члена ПК это классный опыт, гораздо более глубокий, чем просто общение на конференции. Он драйвит вперед, потому дает гораздо более детализированную информацию и, как в разработке, дает её итеративно. Я могу задать несколько вопросов, потом подумать, осмыслить то, что услышал, вернуться за уточнениями.

Самое главное, мне по-прежнему нравится участвовать в конференциях во всех ипостасях.

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

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

Например, в этом году я первый раз заранее с помощью Гриши Петрова готовил фактуру. Раньше всю подготовительную часть была я пытался держать в голове, потом из этого писал план и делал слайды. Сейчас у меня есть документ с фактурой, в котором много слов. Он совершенно хаотичный по своей форме, его нельзя разложить на слайды, но в нем вся информация, и ее гораздо больше, чем я смогу вспомнить в любую единицу времени. Я просто его открою и начну составлять план. Это очень здорово.

— Спасибо, что поделился этим ценным опытом, увидимся на конференции.

Конференция Moscow Python Conf++ всего через два месяца. К сожалению, уже нельзя подать доклад или примкнуть к программному комитету, если вас воодушевили слова Владимира. Но можно, во-первых, запланировать участие в нашем мероприятии и внести в личное расписание доклад и воркшоп о legacy, во-вторых, подписаться на рассылку или telegram-канал, чтобы не пропустить Call for Papers в следующий раз, в-третьих, написать мне или Григорию (eyeofhell), чтобы обсудить другие варианты.

Автор: Никита Соболев

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js