Quantcast
Channel: Найцікавіше на DOU
Viewing all 8776 articles
Browse latest View live

Predictive Software Engineering как шанс для аутсорса повысить качество услуг

$
0
0

[Сергей Кизян — СТО Intetics. 15 лет опыта в разработке ПО, магистр компьютерных наук в Винницком национальном техническом университете. Прошел путь от младшего инженера-программиста до СТО. Автор книги «Управление, ориентированное на людей», ставшей основой для новой дисциплины в ВНТУ. Соавтор книги о Predictive Software Engineering]

Многие компании отдают разработку программного обеспечения на аутсорс. От своих партнеров они ожидают высоких результатов и надежной работы, но в то же время постоянно находятся в неуверенности относительно сроков, качества и стоимости разработки софта. Чтобы снять это напряжение, аутсорсинговые компании должны предложить новый подход к оказанию услуг. В компании Intetics мы создали и используем фреймворк под названием Predictive Software Engineering (PSE), который устраняет «узкие места» в работе аутсорсеров.

Идея PSE

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

  • коммуникация с заказчиком на уровне компании.Весьма часто заказчик оставался один на один с командой и не чувствовал, что он работает с большой компанией, которой мы являемся. Пример: у нас были заказчики, которые приходили и прямым текстом говорили: «Мы не чувствуем, что вы заботитесь о нас как компания. Мы стакиваемся с проблемами и остаемся с ними один на один». Это приводило к весьма неприятным последствиям, которые было сложно устранить и вернуть доверие заказчика.
  • правильный репортинг от команды.У нас было много случаев, когда заказчик не совсем понимал или вообще не понимал, чем занимается команда. Он только надеялся, что все будет хорошо. Хороший результат в таких случаях тоже был не всегда. Обычно команда, которая плохо репортит, плохо и работает. Пример: у нас были менеджеры, которые оказались некомпетентны в своих проектах, и они сами были уверены, что дела на проекте идут отлично, даже в тех случаях, когда проект был на грани провала или был уже провален. Они на словах убеждали наш менеджмент и заказчика, что все отлично. Если бы они вели правильный репортинг с метриками, мы бы поймали проблему еще в самом начале, когда она только возникла.
  • отсутствие стандартных подходов.Мы увидели, что, невзирая на то что мы задекларировали определенные правила разработки и управления проектами в компании, не все менеджеры следовали им и не все понимали их правильно. Пример: знаком всем без исключения людям в нашей индустрии — внедрение Agile-процессов. Добиться, чтобы каждый человек понимал и делал так, как все сотрудники компании — очень сложно. Так и с другими процессами: их внедрение и стандартизация очень сложны, но результат того стоит, как и в случае с Agile-подходами.

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

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

Как работает PSE

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

Это пример формирования новой команды. До внедрения PSE у нас не было никаких метрик по найму для инжиниринг-департамента. Мы измеряли, как работает рекрутинг, но никогда не ставили никаких условий для инжиниринга. Что у нас получалось? Наши менеджеры старались выбирать лучших из лучших, и таким образом мы перебирали 40-50кандидатов на одну позицию! У нас возникла культура тщательного подбора, которая поначалу была весьма неплохой. Но по мере роста компании и усиления конкуренции на рынке труда и в работе с заказчиком (заказчики стали работать с несколькими компаниями одновременно) мы начали проигрывать нашим конкурентам. Конкуренты были более гибкие, нанимали быстрее, работали эффективнее, а наши менеджеры продолжали искать идеальных кандидатов. Проблему надо было решать быстро и кардинально.

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

Это один из небольших аспектов, которые мы решали в рамках PSE, но его влияние на бизнес компании трудно переоценить. Таких процессов мы создали десятки, и они сформировали фреймворк под названием Predictive Software Engineering.

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

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

PSE не стал первой и единственной методологией для нашей компании — наоборот, это, можно сказать, дополнение к существующим мировым практикам. Для проектов мы используем методологии Agile. Это Scrum, Kanban, Lean SD — смотря что лучше подходит для конкретного проекта. Для управления компанией мы выбрали методику Disciplined Agile. Она дает рекомендации, что делать на высоких уровнях, чтобы быть Agile Enterprise. Ее мы приняли за основу, но потом поняли, что этого недостаточно. Недостаточно именно в условиях аутсорсинга, когда мы постоянно собираем команды, нанимаем новых людей, когда у нас меняются проекты, меняются заказчики, когда нам приходится каждый раз убеждать заказчика в том, что мы способны это сделать, что мы лучше конкурентов и т. д. Тогда мы поняли, что нам надо создать дополнительный фреймворк (надстройку над disciplined agile), который будет сфокусирован на проблемах и боли аутсорсинга. Мы начали работать над ним. И в результате сформировали свод правил о том, как руководить и как правильно создать порядок в аутсорсинге.

Это и есть PSE: мы показываем и себе, и заказчику, что благодаря этому своду правил мы с большей вероятностью закончим проект вовремя, в рамках бюджета, с тем же количеством людей, и проект будет качественным. PSE — это попытка не пускать все на самотек, ожидая, что хорошие и талантливые менеджеры сами придумают, как все делать. Мы создали работающий фреймворк, как когда-то создали Scrum, который сейчас по всему миру позволяет миллионам команд качественно делать продукт, причем вообще без менеджеров.

В чем ценность PSE для клиентов, компании, команды

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

С точки зрения компании, PSE привнес стандарты, лучшие практики, измерения и порядок. Конечно, мы не считаем, что PSE — это панацея. Есть много моментов, которые фреймворк не описывает или не затрагивает. Также, я думаю, многие наши процессы не идеальны. Поэтому мы всегда говорим, что PSE — не статичный фреймворк, мы его все время дополняем и адаптируем. Другим компаниям, которые начинают использовать PSE или думают об этом, мы рекомендуем адаптировать процессы PSE под себя. Наш личный результат таков: у нас уже не бывает, что работа на проекте зависит от одного человека или группы людей. Второй плюс от внедрения PSE — это разгрузка топ-менеджмента компании и возможность обратить взор вне компании, вместо того чтобы постоянно смотреть внутрь и «тушить пожары». Сейчас, если у нас возникает какая-то трудность, и ее можно решить правильным выполнением процессов PSE, мы просто направляем людей по процессам и учим их делать работу правильно. Мы учим людей решать проблемы системно и стараемся не внедрять частных решений.

Вот пример подобного решения: у нас был проект, где у клиента возникали постоянные жалобы на качество работы команды. Каждый раз, когда клиент жаловался, мы общались с ним по частному случаю и пытались понять, кто прав, а кто виноват. Параллельно у клиента была вторая команда, которую он считал сильнее нашей. В PSE есть целое направление, посвященное качеству и продуктивности. Мы пришли на проект, внедрили всевозможные метрики качества и продуктивности и начали измерять работу команды. На подобные измерения понадобились определенные ресурсы, но оно того стоило. После того как мы получили системные результаты, мы увидели, что наша команда работает весьма качественно и быстро, и что проблемы возникают, в основном, когда идет интеграция. Дальше заказчик попросил нас измерить его вторую команду. И мы увидели, что люди из нашей компании почти в полтора раза продуктивнее. Как результат, мы выделили ресурс в команде на постоянное измерение и поддержание метрик, и проблема была улажена раз и навсегда. Теперь заказчик видит все показатели работы и делает выводы из метрик, а не субъективных суждений.

Что дает PSE для сотрудников?Ответ очевиден. Давайте представим, что вы работаете в коллективе, где каждый за себя и нет четкой организации. Кто-то делает что-то правильно, кто-то — не очень. Через некоторое время вы понимаете, что такой коллектив не прогрессирует, и вы не развиваетесь в нем как профессионал. В целом, ситуация выглядит бесперспективно. Другое дело, когда вы приходите в команду профессионалов с четкими процессами. Каждый день вы учитесь у них и видите, что они тоже не стоят на месте и постоянно развиваются. PSE — это процессы, процессы — это порядок и законы нашей фирмы. Так же, как законы в государстве, мы меняем наши процессы и адаптируем их под реалии конкретного времени. Но основа остается той же. Все же хотят жить в государстве, где верховенствует право и граждане законопослушны. Это применимо и к компании. Первое применение PSE — фреймворк устанавливает правила и заставляет их выполнять.

Второе применение фреймворка — взаимодействие с людьми. Процессы, описанные в нем, помогают сотрудничать эффективнее. Это повышает качество работы и увеличивает удовлетворенность сотрудников.

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

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

Как происходит внедрение PSE в компании

Это достаточно сложный и трудоемкий процесс. Думаю, многие сталкивались с переходом компании на Agile-методологии. Те, кому пришлось пережить это, помнят, как было тяжело. Самое главное в таком переходе — заставить людей мыслить по-новому и отойти от устоявшихся стереотипов. Это очень сложная задача, требующая усилий на всех уровнях управления компанией включая топ-менеджмент и СЕО. Если у менеджмента нет такого желания, процесс будет провальным с самого начала. PSE — это, можно сказать, надстройка над Agile-процессами, и его внедрение не так уж сильно отличается. В первую очередь, нужно иметь решение руководства компании о внедрении новых процессов. Дальше необходимо адаптировать PSE-процессы для нужд конкретной компании. Мы стараемся писать обобщенные процессы, которые могут быть адаптированы для конкретной компании с большей эффективностью.

Хороший пример — наш процесс и метрики по рекрутингу. Нам подошли цифры 10 резюме и один найм, а у кого-то будут другие цифры. В нашем случае мы описываем, что ответственность за найм несет деливери-менеджер, у другой компании это может быть специальный отдел или рекрутинг компании. Специфика разная, но найм есть в любой компании. И этот процесс необходимо стандартизировать. Иначе результата не будет. Вот об этом PSE. Мы выделяем стандартные моменты в деятельности аутсорсинговой компании и создаем процессы, которые их стандартизируют и делают эффективными.

В нашей компании все началось с импульса от руководства. Основатель и глава Intetics является идеологом PSE, так что он в первую очередь был заинтересован в его практической имплементации. Я продолжил начатое президентом, и вместе с командой коллег мы дописали и довели до конца идеологию PSE вместе со всей библиотекой процессов. Следующим шагом был тренинг для всех сотрудников компании о том, что же такое PSE. Я несколько месяцев объезжал все наши офисы и собирал сотрудников на тренинги по PSE. Мы должны были убедиться, что все в компании понимают, какие наши процессы и как им следовать. Это очень нелегкая задача, но совместными усилиями мы справились. У нас было много сессий и итераций, как и в любом другом Agile-процессе. В принципе, работа над PSE не останавливается никогда. Мы постоянно доделываем процессы, дополняем библиотеку процессов новыми и т.д.

Решает ли PSE все проблемы аутсорсинга

Ответ — однозначно нет. Все проблемы решить невозможно, и сколько ни строй теорий и фреймворков, будут новые вызовы и новые проблемы. Созданием PSE мы старались решить типичные и стандартные проблемы, которые возникают у многих компаний и повторяются на многих проектах. Также нашей целью было создать процессы, которые можно взять за основу для компании, которая до них доросла и у которой они отсутствуют. Мы хотим делиться нашим опытом с другими опытными и начинающими компаниями, чтобы они могли использовать PSE и дополнять его своими достижениями.

Мы создали веб-сайт, где будут опубликованы все статьи и процессы по PSE. Их можно будет прочесть в публичном доступе и начинать внедрять описанное в них в своих компаниях. Также мы сделали открытое комьюнити, куда приглашаем всех желающих. Наша коллега Сандра Шнейдер — лидер этого комьюнити. Все желающие специалисты и компании могут добровольно присоединиться к созданию и развитию PSE. Этому фреймворку нужна реклама и поддержка не только одной компании для того, чтобы он стал стандартом индустрии. Это наша цель, мы хотим, чтобы все больше и больше компаний начинали использовать принципы и процессы PSE.

Что дальше

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


8 правил для ML-проектов на каждый день: как найти и удержать нужный фокус

$
0
0

Меня зовут Игорь Кауфман, и последние 4 года я занимаюсь проектами, связанными с Machine Learning и Data Science, лидируя это направление в компании DataArt. Исследую проблемы в разных индустриях, нахожу параллели, вместе с командой предлагаю технические решения и контролирую их внедрение. До этого 7 лет занимался менеджментом инжиниринговых команд.

Разнообразный опыт участия в R&D-проектах позволил мне составить краткий список того, чему я научился, что нужно и чего не стоит делать, занимаясь ML. Забегая вперед, скажу, что эти правила не исключительно для машинного обучения, они работают в целом для подавляющего большинства исследовательских проектов.

1. Не изобретайте колесо

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

Однако реалии рынка таковы, что провайдеры облачных решений стремительно осваивают сферу машинного обучения — так же, как раньше освоили Big Data. То же относится и к открытому ПО, и в 99% случаев с ML вам не нужно изобретать новую библиотеку. Скорее всего, вы найдете на рынке продукт или технологию, которые при наличии фантазии можно адаптировать под вашу задачу.

Покажу это на примере экстракции данных из PDF-документов — допустим, из purchase orders (когда одна компания заказывает товары у другой). Как правило, они имеют смешанную структуру и состоят из:

  • шапки со слабо структурированным текстом, содержащим информацию о заказчике и поставщике, номер заказа и прочие детали;
  • таблицы со списком товаров, часто с кучей деталей, которые мешают распознать структуру.
Можно разбивать такой документ на части, по отдельности проводить распознавание таблицы и полей NER (named entity recognition) из шапки. Альтернатива — Amazon Textract, который хорошо распознает номер заказа и дату, а также структуру таблиц. Детали можно распознавать с помощью regular expressions. Для старта необходима всего пара дней, и в результате людям, которые обрабатывают такие документы вручную, сразу станет легче, а компания сможет сэкономить. Дальше вы сможете спокойно решить, стоит дописывать правила или в долгосрочной перспективе оправдан другой подход. Это приводит нас к следующему пункту.

Not invented here syndrome. Image: DrinkBird

2. Оценивайте ROI (возврат инвестиций)

Business value first — принцип, особенно важный в R&D-проектах. На любом этапе работы вы должны быть готовы привести реальный пример юзкейса, которым занимаетесь. Если не можете оценить потенциальную пользу в числах, скорее всего, вы занимаетесь либо выдуманной проблемой, либо экстремальным случаем.

В случае с ML потребуется изменить методологию расчета ROI. Ведь машинное обучение, в отличие от классического программирования, никогда не дает 100%-ной точности. Поэтому всегда следует оценивать, окупится ли повышение точности на 2, 5, 10 или 20%.

Вернемся к примеру с purchase orders. Мы работаем с компанией, в которой больше тысячи человек заняты преимущественно извлечением данных из PDF. Улучшив точность результатов на 5–10%,можно каждый год экономить миллионы долларов. Но если необходимо вложить сотни тысяч долларов, чтобы увеличить точность всего на 1-2% —обычная ситуация для компьютерного зрения, — возможно, имеет смысл оставить на этом участке человека и потратить деньги на решение более срочных задач.

Not invented here syndrome. Image: Deloitte

3. Не начинайте работу, не сформулировав гипотезы

Иногда бизнес формулирует запрос так: «У нас есть куча данных. Как мы можем извлечь из них пользу?» Либо обратная ситуация со стороны инжиниринга: «У нас есть куча данных. Давайте попробуем на них алгоритмы x, y и z — и посмотрим, что получится».

От поиска иголки в стоге сена спасает формирование гипотезы. Попробуйте начать с вопросов:

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

Приведу пример. В одном из проектов мы ищем возможности роста для компаний на рынке среди текстовых данных: описаний стартапов, пресс-релизов, отчетов по индустриям и т. д. Например, райдшеринг Lyft стал партнером авиакомпании Delta и теперь имеет возможность возить людей из одного города в другой end-to-end. А его конкурент — Uber — возит пациентов на заранее назначенные приемы у докторов. При этом и тот и другой усиленно инвестируют в автопилоты. Идея, в общем-то, понятна человеку — аналитику конкретной индустрии. Но, пока вы не опишете, как решал бы такую задачу специалист (в каких источниках и какую информацию он ожидал бы найти, как определял бы искомые формулировки и каким образом агрегировал бы знания), построить масштабируемую систему практически невозможно. Такой этап планирования и формирования гипотезы — ручное моделирование — может сэкономить много времени и денег в будущем.

4. Думайте об интеграции заранее

Новое ML-решениепридется интегрировать с существующей системой. Технически в этом нет ничего страшного, но для бизнес-пользователей этот процесс может выглядеть пугающе. Если у компании есть прозрачная система принятия решений, основанная на правилах, то новое решение, базирующееся на ML-алгоритмах,может казаться абсолютным черным ящиком. Поэтому крайне важно иметь четкий план миграции, учитывающий человеческое восприятие и ручную обработку false positives / false negatives. Люди должны понимать, кто и на каком этапе будет это делать и какие риски существуют.

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

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

Более того, по крайней мере 10% билетов все равно придется покупать по старому алгоритму, основанному на правилах. Это позволит и дальше обновлять знания ML-системыи избежать ситуации переобучения (состояния, когда AI думает, что знает все на свете).

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

5. Версионирование экспериментов

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

В ML, кроме самого кода, не следует забывать об используемых датасетах, параметрах модели и результатах экспериментов. Здесь могут помочь специальные инструменты, такие как DVC — система контроля версий для машинного обучения. Несмотря на ряд недочетов, мы все же используем ее, кроме версионирования, в небольших проектах, например, для ускорения построения дата-пайплайнов.

Image: DVC

6. Помните о цели, но не забывайте о «низковисящих фруктах»

В исследованиях легко увязнуть. Одна проблема тянет за собой другую, и в конце концов начинаешь тратить время на задачи, неприоритетные для конечного продукта (привет, рефакторинг!). Поэтому так важно сохранять концентрацию на основных целях продукта и не распыляться. Однако если вы видите, что есть задача, возможно, не слишком важная, но с которой можно быстро разобраться и показать результат, не проходите мимо. Вспомните, какое удовольствие приносят пользователям небольшие, но приятные обновления приложений. Часто такое случается в момент визуализации данных. Внезапная находка может выглядеть незначительной, но впоследствии оказаться ценной для бизнеса.

7. Будьте изобретательны

Всегда существует дорогой и «правильный» способ решения любой задачи. Но первый вопрос, который стоит себе задать: можно ли добиться 80%-ного результата, приложив 20% усилий?

В одном из проектов нам нужно было среди материалов, скопившихся за 20 лет, определить, какие из них актуальны. Это были десятки тысяч документов, содержащих логотипы Mastercard. В какой-то момент мы обнаружили, что последнее изменение логотипа Mastercard произошло в 2016 году. День на маркировку и обучение облачного сервиса распознавания изображений — и вуаля, мы отобрали только свежие документы.

Image: Design Chambers

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

8. Управляйте ожиданиями

Machine Learning и Data Science — черный ящик для большинства людей, поэтому в случае с ними ценность управления ожиданиями выше, чем где-либо еще.

Не забывайте обучать людей, количественно оценивать результаты вашей работы (сколько времени/денег вы сэкономили, стало ли быстрее и лучше, и если стало, то насколько) и сравнивать ответы с изначальными целями. Заранее продумывайте процесс интеграции вашего сервиса в существующую систему как с технической, так и с человеческой точки зрения.

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

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

Надеюсь, мой опыт окажется кому-то полезен. Вероятно, вы сможете дополнить этот список собственными правилами (непосредственно связанными с ML или универсальными).

Один проект и два PM: возможно ли эффективное управление

$
0
0

Меня зовут Влад Самойлов. Последняя компания, в которой я занимал позицию IT portfolio manager, — «Киевстар». В проектном и продуктовом менеджменте на рынках СНГ, Европы, США и Азии я уже более 6 лет. Последние два года активно преподаю IT project management в нескольких школах и центрах IT-образования, а также являюсь тренером по командообразованию.

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

Однако обо всем по порядку.

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

Статью на эту тему я решил написать по материалам своего докладана Project Management Day 2019, в рамках которого мы смогли очень глубоко изучить эту тему и подискутировать с аудиторией, оптимизируя инструменты и подходы для работы с подобными кейсами в будущем.

Цель любой современной IT-конференции сегодня — нетворкинг. За последние 6–7лет я посетил внушительное количество конференций, чтобы сегодня четко формулировать задачи. Выполнение этих задач поможет мне вынести максимум, будучи спикером или участником. Цели, поставленные на этот год в роли спикера на PM Day, можно считать достигнутыми.

Принципы построения команд

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

Вопрос «Что самое главное в построении команд?» довольно сложный. Деньги? Мотивация? Высококвалифицированные специалисты? Возможно. Но я для себя вынес иные ценности.

Продукт

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

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

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

Для кого и зачем

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

Последняя компания, в которой я очередной раз на практике убеждался в важности не просто создавать продукты, а создавать ценность от этих продуктов, это «Киевстар». Рынок телеком-услуг, конечно, не сильно велик в Украине, но выбрать есть из чего. Поэтому нам в каждой, даже самой мелкой, инициативе приходилось тщательно изучать потребности, боли и желания конечных пользователей, чтобы именно у тебя не возникло желание «попробовать более удобное приложение оператора АВС» или «поставить вторую симку только для инета».

Для более наглядного понимания важности создания ценности можно привести пример возможного распределения бюджета проекта по разработке простейшего API (что позволит пользователю избежать необходимости прохождения дополнительного шага при оплате пакета услуг), которое может составлять 90/10. А именно: 90% затрат бюджета — на маркетинговые исследования, customer success experience, пилотный запуск, А/Б тесты и т. д. и всего 10% — на фактическое выполнение проекта (полный SDLC).

Вы же пользуетесь чем-то конкретным из месяца в месяц не одолжения ради, а потому что для тебя это представляет определенную ценность... Стоит задуматься.

Понимание, кем вы управляете

Команда — это что такое? Какой тип команды формируется у вас? Управлять или направлять? Важно понять одно: каждый случай уникален. И ваш тоже. Поэтому каждый должен ответить на эти вопросы для себя и только потом обсуждать их вслух.

Три самых важных аспекта, понимание которых поможет вам с первого раза успешно построить эффективные процессы менеджмента:

  1. Что хотим создать.
  2. Для кого хотим создать.
  3. Зачем хотим создать.

После получения ответа на эти вопросы мы определяем/корректируем/меняем почти все:

  • структуру команды;
  • ролевую модель;
  • методологию управления;
  • план адаптации к изменениям;
  • набор инструментов и подходов управления;
  • цели и road maps развития;
  • метрики, KPIs, OKR.

Список может быть столь продолжительным, сколько понадобится в конкретном кейсе.

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

Двое у руля

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

Сегодня можно придумывать различные методологии/фреймворки (Waterfall, Agile, Scrum, Kanban, Lean...), инструменты (RACI, WBS, Gantt chart diagram, матрица требований/рисков/стейкхолдеров...), ссылаясь на профессиональные источники (PMI, ScrumAlliance, DOU и др.). Но иногда встречаются кейсы, которые противоречат не только классическим подходам в проектном менеджменте, но и здравому смыслу. Один из них — управление одним проектом при равноправной ролевой модели двух проджект-менеджеров. И даже в этом случае у вас есть все шансы на успех. Не опускаем руки, для начала необходимо разобраться, законно ли это.

Это весьма нетипичная модель, но она часто встречается в современной практике, когда идет этап реструктуризации проекта или его передача от одного к другому PM (ведь этап передачи highload-проекта может достигать 2–3 месяцев,и на протяжении всего этого времени проектом управляют два человека). Очень важно вовремя идентифицировать, что проект начал какую-либо трансформацию, например из проекта в программу или портфель, ведь эти структурные изменения требуют пересмотра ролевой и поведенческой модели в команде, в том числе — количества проджект-менеджеров (возможно, функциональных).

Также наличие двух проджект-менеджеров возможно в мультистримовых проектах, где, кроме направления разработки ПО, есть стримы маркетинга, продаж/логистики и прочее. И в каждом направлении может быть свой менеджер.

Мой любимый кейс, с которым я сам однажды столкнулся на практике, когда на проекте появляются два проджект-менеджера, это вопрос-хотелка заказчика «А давай усилим твой проект?»; хотя фактически это никогда не является вопросом, а скорее: «Я умнее, поэтому решил, что теперь вас двое». И даже если вы использовали все свои хард-, софт- и мегасупер-скилы для ухода от данного «решения», с этим можно эффективно работать. Поговорим детальнее как.

Что нужно учесть в первую очередь

Каждому на новом этапе жизни проекта важно знать, какие первые шаги нужно сделать. Я подскажу какие.

Итак, на очередной встрече с руководителем/клиентом вам озвучивают: «Ты молодец. Но мы решили усилить твой проект, и завтра к тебе присоединяется еще один PM». Вы, конечно, попытались изменить условия игры, вытереть холодный пот. Но что же делать, учитывая, что данного кейса не избежать? Поехали.

Причина.Определите, какой из вышеперечисленных кейсов у вас сложился и по какой причине у вас в проекте добавился второй PM. Ведь трансформация проекта или организационной структуры компании — далеко не единственная причина. Еще одной причиной я бы хотел назвать ваше собственное решение как менеджера проекта. Добавление второго человека не всегда «плохое, притянутое за уши решение». И если вы как менеджер решили вырасти (до Program/Portfolio manager), чтобы тем самым принести пользу проекту, то имеете все инструменты для этого; главное, не забудьте подготовить под такие изменения бюджет.

Проблема/задача.Что именно мы или не мы хотим решить и чего добиться добавлением нового проджект-менеджера в команду.

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

Понять это весьма просто. В большинстве случаев новый PM может помочь с решением задач из области ресурсного перераспределения (проще говоря, примет на себя часть функций в проекте), внедрением внешней экспертизы в реализацию проекта или решение точечных проблематичных кейсов. Формулировка «Мы постоянно проваливаем даты новых релизов, поэтому нам нужен второй PM, чтобы все более качественно заменеджерить» может стать губительной, если, разбирая каждый отдельный случай, выясните, что не в недостатке ресурса проджект-менеджера проблема, а в банально не прописанных Definition of Ready и Definition of Done. Этот пример — не плод неординарной фантазии, а примеры из одного моего проекта. В момент первого знакомства с одним из главных стейкхолдеров проекта я и услышал подобную формулировку. Хорошо, что спустя несколько продолжительных встреч и множество ночей, проведенных в процессе аудита проекта, мне удалось убедить его в том, что тут не решить проблему даже 10 проджект-менеджерами, если не прописать вышеназванные критерии.

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

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

Допустим, первые шаги вы выполнили и уже даже смогли как-то для себя обстановку очертить. Теперь мы знаем, почему, зачем и кто. Но что же делать дальше и как с этим быть на практике?

Инструментарий

Я за всю свою практику вынес два самых важных и эффективных инструмента, которые просто необходимы для эффективного управления проектом вдвоем:

  • карта коммуникаций;
  • многоуровневая RACI-матрица.

Карта коммуникаций — это инструмент, который визуализирует функциональное и линейное взаимодействие между участниками команды (в многочисленных командах — между функциями/подразделениями/отделами) без определения иерархической структуры, но с правилами прямого или косвенного контакта. Прямой контакт — когда может напрямую вести коммуникацию с разработчиками по приоритизации задач например; косвенный — сейлз-менеджер не может напрямую вести коммуникацию с разработчиками, а должен это делать только через проджект-менеджера.

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

Вы только представьте (или вспомните) свои ощущения, когда приходите на проект, в котором 10–50 (неважно сколько) человек, и вам необходимо всем этим как-то управлять. И что еще важнее, управлять, достигая определенной цели.

Согласен, за один день вся эта сложная паутина не распутается, но первое, что вы сделаете, — попытаетесь консолидировать информацию о проекте (мы надеемся, что предыдущий PM использовал конфигурационное управление, но надежды остаются надеждами). Для планомерного сбора данных вам потребуется синхронизировать потоки коммуникаций в проекте между участниками и взять их под контроль. Карта коммуникаций в этом точно поможет.

Многоуровневая RACI-матрица, конечно же, остается инструментом формирования ролевой модели на проекте, но ключевое слово — «многоуровневая», что позволяет нам формировать RACI в нескольких «измерениях». Максимально применима в матричных организационных структурах компаний.

Я для себя вывел два типа многоуровневой RACI-матрицы:

  1. Кросс-функциональная, или «RACI на RACI». Выше проговаривали, что несколько проджект-менеджеров возможно на мультистримовых проектах. Так вот мы на каждый стрим / функциональное направление создаем отдельную RACI, где ответственным за бюджет, к примеру каждого из стримов, будет свой проджект-менеджер, но при этом нам еще необходимо создать глобальную матрицу, в которой определить одного ответственного за глобальный бюджет.
  2. Многоуровневая RACI. Это классическая визуализация RACI-матрицы, только включает она не просто одного ответственного за бюджет например, а 3 уровня (ну или сколько у вас там проджект-менеджеров на проекте образовалось), правила, которые мы задаем. И они нам могут говорить о том, что:
    • R (Responsible) 3 — ответственный за бюджет бизнеса;
    • R2 — ответственный за бюджет IТ;
    • R1 — ответственный за бюджет всего проекта/продукта.
При таком подходе формирования многоуровневой RACI-матрицы мы сохраняем важное правило: не может быть двух ответственных за одну задачу. Просто ответственность мы декомпозируем и фиксируем в наших правилах внутри команды.

Пример классической карты коммуникаций, которая применима для многочисленных команд; поэтому структурируем карту по функциям, а не по людям и проставляем связи проектного и функционального взаимодействия:

➕ лаконичность, доступность широкому кругу стейкхолдеров, легко вносить динамические изменения, идеально подходит для команд с более, чем 20 участников.

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

Рассмотрим еще один вариант визуализации карты коммуникаций, но теперь уже для немногочисленных команд; и эта карта, в отличие от предыдущей, визуализирует взаимодействие между ролями в команде:

➕ визуально доступна для восприятия, правила понятны без дополнительной презентации/пояснений/комментариев, формат применим в командах до 12–15 человек.

➖ может содержать до 3–4 правил,не учитывает исключительных кейсов, неприменима в матричных структурных организациях.

Альтернативно-креативным вариантом карты коммуникаций может быть и такой формат. Данная карта визуализирует не ролевое взаимодействие, а маршруты коммуникации в команде/организации/группе:

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

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

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

Есть и другие возможные варианты поведенческо-ролевых моделей в зависимости от структурного типа компаний, что является основополагающим фактором формирования карты коммуникаций и многоуровневой RACI. В Киеве на Project Management Day 2019 мы успели не только поговорить об этом, но и сформировать несколько детальных моделей.

P. S.

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

Также полезно говорить с коллегами и формулировать свои взгляды и гипотезы. Так рождается истина. Надеюсь, я смог принести пользу менеджерам, с которыми поделился этими знаниями. Все вышесказанное я успешно применяю в процессе создания нашего нового продукта Connectable (проект в разработке).

Общение, общение и еще раз общение. И даже управляя командой вдвоем, вы начнете перформить на максимум.

А теперь попробуйте заглянуть за борт...

.NET дайджест #31: релиз .NET Core 3.1, партнёрство Azure и Salesforce, прекращение поддержки .NET Core 2.2

$
0
0

Привет! Меня зовут Андрей Губский, и теперь я буду готовить выпуски .NET дайджеста вместо Андрея Литвинова, благодаря которому этот дайджест и появился на просторах ДОУ.

Расскажу в двух словах о себе. Коммерческой разработкой на .NET я занимаюсь с 2008 года, с 2017 года являюсь Microsoft MVP в категории Developer Technologies, в рамках проекта //devdigest поддерживаю несколько телеграм-каналов посвященных .NET Core, Azure, Xamarin, в 2016 создал сообщество .NET Core Ukrainian User Group, модератором и администратором которого являюсь. Я постараюсь сохранить уровень наполненности и динамики дайджеста, заданный моим тезкой.

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

Очевидно, что главным событием декабря в мире .NET можно по праву считать выход в релиз .NET Core 3.1. Это не просто новый минорный релиз, это еще и LTS (Long Term Support) версия, которую Майкрософт будет поддерживать как минимум три года. А это значит, что именно до этой версии стоит обновиться всем, кто сейчас работает на версии 2.2 (поддержка этой версии заканчивается как раз 23 декабря, и, скорее всего, когда вы читаете этот текст, поддержка версии 2.2 уже завершилась).

Вторым событием, которое мне показалось, весьма важным, я бы назвал стратегическое партнерство между Salesforce и Microsoft, которое было подписано еще в ноябре. Azure теперь становится облачным провайдером для Salesforce Marketing Cloud. Microsoft все активнее откусывает кусочки от облачного пирога Amazon.

С остальными событиями и материалами декабря предлагаю ознакомиться ниже.

.NET

The Architecture behind the nopCommerce eCommerce Platform — nopCommerce — система управления интернет-магазинами с открытым исходным кодом, разработанная на ASP.NET Core. В этом видео вам предлагается узнать, как реализована архитектура этой системы.

Introducing the AWS Toolkit for Rider — JetBrains представила набор инструментов для работы с AWS в Rider.

Building Full-stack C# Web Apps with Blazor in .NET Core 3.0 — видео, в котором подробно рассматривается создание full stack приложения на базе Blazor.

Announcing .NET Core 3.1 — анонс .NET Core 3.1 в официальном блоге Microsoft. Стоит обратить внимание на изменения в Windows Forms для .NET Core, из-за которых часть кода может быть несовместима с новой версией. Это касается в первую очередь компонентов DataGrid и MainMenu.

Pulumi: Cloud Infrastructure with .NET Core — Pulumi — это инструмент, который позволяет описывать инфраструктуру, как код. В статье множество примеров использования на C#.

.NET Core 2.2 will reach End of Life on December 23, 2019 — 23 декабря заканчивается жизненный цикл .NET Core 2.2. Не забудьте обновиться до LTS-версии .NET Core 3.1.

Microsoft emits long-term support .NET Core 3.1, Visual Studio 16.4 — а вот для .NET Core 3.1 и Visual Studio 16.4 поддержка продлится гораздо дольше.

ASP.NET Community Standup — Dec 3rd, 2019 — Blazor Update with Daniel Roth — в новом выпуске ASP.NET Community Standup ведущие наглядно рассказали о процессе разработки Blazor-приложения.

We made Windows Server Core container images >40% smaller — если вы все еще не перешли на .NET Core, но вам нужна контейнеризация, то у Майкрософт для вас хорошие новости. Команда разработки Windows Server смогла уменьшить размер docker образов Windows Server на 40%.

What’s New in Rider — вышла новая версия Rider 2019.3 В релизе: поддержка профилирования .NET Core проектов под macOS и Linux, улучшена общая производительность IDE, поддержка Xamarin и C# 8, да в общем все в новой версии улучшено. Качайте и устанавливайте!

Implementing Microservices with gRPC and .NET Core 3.0 — в .NET Core 3.0 на уровне платформы появилась поддержка gRPC. В блоге Auth0 по этому поводу вышла отличная статья с наглядным примером реализации простой системы с использованием gRPC и объяснением основ работы этого фреймворка.

Evolution Software improves hazelnut quality with ML.NET — история успеха: как ML.NET в выращивании фундука помог.

.NET Conf: Focus on Blazor — не пропустите следующую онлайн-конференцию .NET Conf, которая будет посвящена Blazor. Конференция пройдет 14 января 2020 года.

ConfigureAwait FAQ — разбор вопросов про async/await в C#, а также полезные нюансы работы SynchronizationContext, TaskScheduler, ConfigureAwait и многое другое.

jamesmh/coravel — интересный проект, который позволяет значительно облегчить запуск задач по расписанию. Радует удобное декларативное описание запуска задач. Естественно, все на C#.

Gamlor’s Blog: C# Loves Code Patterns — статья, из которой вы узнаете применение паттернов в LINQ, foreach и асинхронных методах.

Avalonia UI Framework — Avalonia 0.9.0 Release — состоялся релиз кросс-платформенного .NET UI-тулкита AvaloniaUI 0.9.

Optimizing garbage collection in a high load .NET service — история отладки сервиса Pyrus и особенности сборки мусора, которые выяснили разработчики во время дебага.

Delegates And Events In C#— тонкости применения делегатов, событий и лямбда выражений в C#.

An Introduction to System.Threading.Channels — введение в System.Threading.Channels — набор структур данных, позволяющий реализовать схему взаимодействия producer/consumer в вашей системе.

Xamarin

The competitive landscape of cross-platform development: Xamarin, Flutter and React Native — cравнение эффективности использования Xamarin, Flutter и React Native с точки зрения бизнеса.

Reactive UI and Reactive Extensions for Xamarin.Forms — обучающее видео про использование Reactive UI и Reactive Extensions в Xamarin.Forms.

Azure

Salesforce announces it’s moving Marketing Cloud to Microsoft Azure — новости почти месяц, но как-то на наших просторах она осталась почти без внимания. Salesforce — компания, которая с 2012 года является мировым лидером рынка CRM-систем. Salesforce Marketing Cloud — ее дочерняя компания, которая теперь переезжает в Azure.

Azure Functions 3.0 go-live release is now available — Azure Functions 3.0 теперь поддерживают .NET Core 3.1.

Effective DevOps—Building a DevOps Culture at Scale — книга Effective DevOps доступна для бесплатного скачивания с сайта Майкрософт.

AWS Lambda vs. Azure Functions: 10 Major Differences — сравнение сервисов Azure Function и AWS Lambda.

Machine Learning, Data Science, Big Data, etc.

Azure Quantum — квантовые вычисления доступны в Azure уже сегодня.

Microsoft scientist accepts Hamburg Prize for Theoretical Physics for quantum contributions — Microsoft Quantum — доктор Маттиас Тройер, исследователь квантовых вычислений в Microsoft, получил одну из самых престижных наград в области теоретической физики в Германии — Гамбургскую премию — за значительный вклад в развитие квантового метода Монте-Карло.

9 Advanced Tips for Production Machine Learning — девять советов для тех, кто начинает работать над проектом, в котором планируется использование машинное обучение, с примерами использования сервисов Azure.

Вместо послесловия

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

А чтобы не пропустить ничего до выхода следующего выпуска — следите за новостями про .NET, Azure, Xamarinв телеграме. Все главные публикации ДОУ читайте здесь. До встречи в новом, 2020 году, да пребудет с вами Сила!


← Предыдущий выпуск: .NET Дайджест #30

Ruby дайджест #34: итоги года, Ruby 2.7.0, актуальность Ruby on Rails в 2020

$
0
0

Дайджест был создан в соавторстве с Мариной Завийбородой, Copywriter в RubyGarage.

Всем привет! Завершаем год с нашим традиционным Ruby/Rails дайджестом. 2019 запомнился нам грандиозным релизом Rails 6.0 с Action Mailbox, Action Text, поддержкой параллельного тестирования, Webpacker из коробки и другими полезными вещами. Летом вышла preview1 версия Ruby 2.7.0, включающая улучшения JIT и экспериментальный Pattern Matching. Еще в июне Ruby обзавелся тайпчекером Sorbet, который разработала команда Stripe. А чем запомнился этот год вам?🥳

Релизы

Ruby 2.7.0 — на Рождество вышла новая версия, в которой представлены новые фичи: pattern matching, улучшение REPL, Compaction GC, разделение позиционных и именованных аргументов.

Ruby 2.7.0-rc2 Released — данная версия была выпущена для сбора обратной связи перед финальным релизом Ruby 2.7.0. В ней будут представлены новые фичи: pattern matching, улучшение REPL, Compaction GC, разделение позиционных и именованных аргументов.

Почитать

RSpec metadata — what they are and how to use them — разбираемся в RSpec metadata: что это, как это работает и как использовать.

Proxying Outbound HTTP Requests Through Static IP Addresses on Heroku — учимся проксировать исходящие HTTP-запросы через статичные IP-адреса на Heroku.

Software Philosophy Quotes and Memes — просто подборка мемов и смешных цитат о программировании, Agile, и этом всем :)

Martian Chronicles

Pulling the trigger: How to update counter caches in your Rails app without Active Record callbacks — Evil Martians экспериментируют с триггерамикак средством поддержания согласованности агрегированных данных при использовании Active Record и любой базы данных SQL. Вместо того, чтобы использовать сложные инструменты вроде ElasticSearch для фильтрации и поиска, авторы демонстрируют простой подход, который достигает того же результата с некоторыми готовыми функциями базы данных.

Persisted queries in GraphQL: Slim down Apollo requests to your Ruby application — разбираемся, как уменьшить размер сетевых запросов от клиента Apollo к GraphQL Ruby. В статье показывается, как работают эти запросы и как их настроить как на клиенте, так и на сервере с помощью Ruby-гема graphql-ruby-persisted_queries.

BigBinary

Традиционная подборка от BigBinary по обновлениям в Ruby 6:

Rails 6 adds rails db:prepare to migrate or setup a database

Rails 6.1 adds *_previously_was attribute methods

Rails 6 adds guard against DNS Rebinding attacks

Semaphore

How to Easily Modernize Older Applications With Docker — интервью с Elton Stoneman, Docker Architect и автором книги Learn Docker in a Month of Lunches о том, как новичкам обучиться Docker, оптимизации энтерпрайз-систем без переписывания кода и его новой книге.

CI/CD for Spring Boot Microservices — туториал по созданию и тестированию образа Docker с помощью непрерывной интеграции. Также в статье объясняется, как расширить CI/CD с непрерывным развертыванием на кластер Kubernetes.

In Continuous Integration, Run Fast and Fundamental Tests First — оптимизируем CI/CD пайплайн с помощью некоторых уловок.

Benchmark Report: Docker Builds with Semaphore vs. Docker Hub — результаты бенчмарка Semaphore и Docker Hub с настоящим use case.

Thoughtbot

Token Authentication with Rails — имплементим простую аутентификацию пользователей (без инструментов вроде OAuth 2) с помощью встроенного функционала Rails.

Faking External Services in Tests with Adapters — учимся генерировать фейковые внешние сервисы в тестах с адаптерами.

Arkency

Unexpected benefits of storing commands — хранение команд в Rails Event Store.

OOP Refactoring: from a god class to smaller objects — примеры рефакторинга по принципам OOP.

Ruby — raise Exception.new or raise Exception — they’re both the same — TLDR: Можно использовать raise Exception и raise Exception.new — результат идентичен и на 4 символа меньше.

Netguru

We Asked the Industry: «Is Ruby on Rails Dead?» — Netguru спросили разных экспертов из Ruby-сообщества про актуальность Ruby on Rails. Мнение единогласное: Ruby on Rails продолжает радовать разработчиков своей стабильностью, разнообразием готовых решений и уникальным, дружелюбным сообществом.

Using Cypress and Screener to Automate Testing for Keller Covered — учимся использовать Cypress и Screener для автоматизации тестирования Keller Covered.

All You Need to Know to Start with Ruby — полезная статья для новичков, которые хотят начать изучать Ruby: базовые принципы языка, как установить Ruby и полезные ресурсы для изучения.

Appfolio

More Fiber Benchmarking — продолжение бенчмаркинга Fiber в Ruby.

JIT and Ruby’s MJIT — авторы разбирают разницу между JIT в Ruby и MJIT.

Ruby’s Roots and Matz’s Leadership — Matz об истоках Ruby и под влиянием каких языков был создан Ruby, а также о лидерстве Ruby среди языков программирования.

Книги

В издательстве The Pragmatic Bookshelf вышло две новых книги, которые можно купить в электронном формате: Software Estimation Without Guessingи Designing Elixir Systems with OTP.

Туториалы

How to Maintain Performance with Big Datasets Using Highcharts.js and Vue — оптимизируем производительность проектов с большим массивом данных с инструментом Highcharts.

Decluttering Translations in Rails Apps — интернационализация (i18n) — неотъемлемая часть приложения, которым пользуются по всему миру. В туториале рассказывается о том, как увеличивать файлы с переводом по мере того, как приложение масштабируется и избежать беспорядка и дублирования.

Filtering with GraphQL and Prisma: What NOT to do — автор делится опытом создания фильтрации более чем одного запроса с GraphQL и Prisma и проблемами, с которыми столкнулся в процессе.

Create AWS S3 bucket as a static website with AWS CLI — краткий туториал по созданию статичных веб-сайтов на AWS S3 bucket и AWS CLI.

Послушать

RWpod

50 выпуск 07 сезона. Bundler 2.1.0, JIT and Ruby’s MJIT, JavaScript component-level CPU costs, Snabberb, FX и прочее

49 выпуск 07 сезона. What’s new in Ruby 2.7, Rubyfmt with Atom, ImageProcessing, NanoNeuron, Creepyface и прочее

48 выпуск 07 сезона. Rails 5.2.4, reverted Ruby 2.7 new feature, Scaling SVG Elements, Matestack, NeatJS и прочее

47 выпуск 07 сезона. 10 New Things in Active Record, Ruby Next, Postwoman, Chatwoot, GraphQuill, SiriwaveJS и прочее

46 выпуск 07 сезона. Bytecode Alliance, Scalable Concurrency, Front-End Tooling Survey 2019, Top-level await, Ky и прочее

45 выпуск 07 сезона. Rails 6.0.1, TypeScript 3.7, ANTLR, Prism, Skunk, FFmpeg.js, Sharp, Tenko, Proton и прочее

Remote Ruby

Concerns, Interactors, and Ruby 2.7 Features (Ruby 2.7 Christmas Day 🎉)— в подкасте идет речь об использовании Concerns в Rails по сравнению с сервисными объектами (с использованием Interactors) и возможностях, которые появятся в Ruby 2.7.

Introducing Nate Hopkins, Working with ActionCable’s API, Webpacker in Rails Engines, and Stimulus Reflex Updates — в этом эпизоде Нейт Хопкинс рассказывает об API-интерфейсе ActionCable, обсуждает с ведущими подкаста проблемы использования JavaScript в новом движке Rails и делится опытом управления OSS-проектами GitHub Action.

Introducing Andrew Mason, CI Tooling, Ruby 2.7 Features, Rails 6.1 on the Radar — один из ведущих программы, Джейсон, делится способами использования GitHub Actions за пределами CI, новых функциях в Ruby 2.7 и некоторых функциях на радаре для Rails 6.1.

Building Chat Applications, GitHub Actions, HatchBox Features, and Mistakes — Джейсон рассказывает о том, каково было работать с ActionCable и React над последней функцией Podia — обменом сообщениями. Ведущие также обсуждают действия GitHub и некоторые функции HatchBox (включая использование DigitalOcean Spaces в качестве замены S3).

5by5 Ruby on Rails Podcast

#297: The Functional Rubyist with Joe Leo — подкаст посвящен функциональному программированию в Ruby и Ruby-сообществу после RubyConf 2019.

#296: Conscious Coding Practice with Noah Gibbs — подкаст с Noah Gibbs, членом Ruby Core Team, о его книге Mastering Software Technique: Conscious Practice for Writing Softwareи многом другом.

#295: Power the World with Rails with Bindiya Mansharamani & Andrew Dereng — подкаст о выборе GraphQL для проекта RigUp, культуре разработчиков и карьерном пути для достижения уровня Senior.

Всем Ruby-обнимашки и с Новым Годом🎄


← Предыдущий выпуск: Ruby дайджест #33

Найкращі статті 2019 року

$
0
0

2019-йминув, і цього року, окрім переліку найкращих статей, трішки розкажу про підсумки редакції DOU.

Минулого року ми опублікували 560 статей від 325 авторів. Цей рік був рекордним за кількістю технічних статей — 83 матеріали (потім не кажіть, що DOU — це лише «про сири»). І ще ми розмістили колонки від 27 колумністів, підготували 24 інтерв’ю та стільки ж аналітичних матеріалів. За рік ви переглянули Стрічку понад 12 мільйонів разів і залишили 30 тисяч коментарів.

Із цікавого:

  • Минулого року редакція DOU розширилася — ми знайшли нового редактора Марію, яка разом з Альоноюпрацює з новими авторами та готує редакційні статті. Загалом за 2019-йми сконтактували більш ніж із тисячею ІТ-спеціалістів щодо публікації статей на DOU.
  • Ми запровадили процес рецензування технічних статей — ІТ-спеціалісти читають текст до публікації та залишають свою думку і пропозиції щодо покращення матеріалу. У 2019-мулише частина технічних статей проходила рецензування, цього року ми плануємо всі технічні й частину нетехнічних відправляти рецензентам. Тож, якщо ви не проти почитати статтю до публікації — заповніть невеличку анкету, і редактори будуть із вами зв’язуватися.
  • Одне з найважливіших нововведень минулого року — це зірочки для контенту, який вам сподобався і який ви хочете не загубити. Цього року ми продовжимо вдосконалювати цю функцію, але ви вже зараз можете ставити зірочки статтям і топікам на Форумі.
  • Ми, нарешті, почали вести свої Лінкедін сторінки. На сторінці DOUз’являються всі статті зі Стрічки, а в групі на 38 тис. підписниківуже немає спаму і, сподіваємося, будемо обговорювати теми кар’єри та професійного розвитку. Підписуйтеся!
  • Ми закрили дві рубрики — DOU Labsі Проектор. Для подальшого зростання нам потрібно оптимізувати контент, тому відтепер усі матеріали щодо стартапів ми будемо розміщувати на Форумі. На їхньому місці обов’язково з’явиться щось нове й більш цікаве нашій аудиторії.

На 2020-йу нас безліч планів, і починаємо ми його з розширення — шукаємо випускового редактора. Нам потрібна людина, яка візьме на себе редагування, вичитку та публікацію статей. І разом із нею ми реалізуємо все заплановане швидше та якісніше.

Ну а тепер згадаймо найкращі статті минулого року. Якщо чесно, обрати було важко, бо публікували багато гарних матеріалів. У переліку не тільки найпопулярніші статті за переглядами, деякі тексти ви читали не так активно, але вони однозначно були варті вашої більшої уваги. Поїхали!

Найкраща аналітика

Зарплати українських розробників — червень 2019.В 2019-муми оновили візуалізацію та розділили зарплатну аналітику на три окремі матеріали. Найбільше переглядів очікувано в зарплат розробників. Але ви ще подивіться зарплати тестувальниківта зарплати інших технічних і нетехнічних спеціалістів.

Топ-50 ІТ-компаній України, липень 2019: 60 тисяч спеціалістів і подолання відмітки «7000 фахівців».Кількість спеціалістів у топ-50 за півроку виросла майже до 63 тисяч. У рейтингу з’явилися нові обличчя, а EPAM і SoftServe перетнули позначку в «7000 спеціалістів». На ці дві компанії припадає 37% росту липневого топ-50.

Де, як і скільки: аналізуємо найм джуніорів у 2018 році.Щороку ми питаємо в ІТ-компаній про потребу в trainee/junior-спеціалістах і джерела пошуку молодих співробітників. В опитуванні взяли участь 45 ІТ-компаній. 4 з них не співпрацювали з новачками у 2018 році, а інші за минулий рік найняли майже 4 300 молодих фахівців.

Рейтинг мов програмування 2019: JavaScript майже зрівнялася з Java, популярність Go знижується.Частка Java продовжує знижуватися і вже майже зрівнялася з JavaScript. А найбільш поширеною першою мовою скоро стане С++ замість Pascal/Delphi. Якщо дивитися на динаміку останніх років, то Kotlin, з огляду на свій вибуховий ріст, витисне Java у розробці під Android.

Рейтинг шкіл за результатами ЗНО-2019.Традиційно Сергій Городецький склав рейтинг шкіл. Перевірте, чи входить ваша школа в ТОП по регіону і країні і прослідкуйте динаміку її результатів із року в рік.

Портрет ІТ-спеціаліста — 2019. Інфографіка.Кожного року ми з Popel Agency ламаємо голови щодо тематики Портрету. Візуалізацію для минулорічного матеріалу дизайнери складали вручну з конструктора LEGO. Подивіться обов’язково, а ми вже міркуємо над цьогорічною стилістикою. Є ідеї?

Рейтинг вишів DOU 2019: у Могилянки з’явився конкурент за перше місце, а КПІ за межами 10-килідерів.Із цікавого: оновлена трійка лідерів, КПІ і Львівська політехніка, як і минулого року, погіршили свої позиції. А ще ми визначили, що більшість ІТ-спеціалістів рекомендує отримувати вищу освіту, незважаючи на те, що програма навчання — поки що найслабший аспект української ВО.

Чим незадоволені українські програмісти? Глас народу 2018.Цього року ми не публікуємо підсумкову статтю щодо рейтингу роботодавців, але глас народу, напевно, зробимо. Проте давайте поки що згадаємо, на що бідкалися розробники у 2018-му.

Ринок праці 2019: ріст 20% й ажіотаж навколо податків.За нашими підрахунками, кількість зайнятих спеціалістів в українському ІТ досягла позначки в 190 тисяч. Загалом цього року темпи зростання трішки пригальмувались порівняно з рекордним 2018 роком.

Що має знати Senior Front-end Developer. Результати аналізу вакансій в Україні та Каліфорнії.Наш постійний читач та друг Дмитро Скороход узяв і проаналізував вакансії на DOU та інших майданчиках і з’ясував, чого очікують від Senior-спеціалістів роботодавці. Найпопулярнішим був матеріал про Front-end, проте радимо почитати й інші статті цієї серії.

Скільки ІТ-спеціалістів в Україні: +29 000 за рік згідно з Мін’юстом.За відкритими даними реєстру фізичних осіб-підприємців, кількість ІТ-спеціалістів, зареєстрованих як ФОП, у 2018 році зросла на 23% і склала 154 тис. осіб. Зростання відбулося за всіма видами діяльності й майже у всіх регіонах України.

Вступна кампанія 2019: КПІ лідирує за кількістю заяв, а УКУ — за найвищим середнім балом абітурієнтів.Ми взяли дані з ЄДЕБО щодо кількості заяв вступників та дізналися, які ІТ-спеціальності та виші були найбільш популярними й куди вступити було найскладніше. Тож, дивимося, ким поповниться ІТ-ринок за 5 років.

LinkedIn, рекомендації та Джин — найефективніші канали пошуку роботи. Результати опитування ІТ-спеціалістів.Наприкінці серпня ми провели опитування щодо пошуку роботи і зібрали 4 тис. анкет від ІТ-фахівців. Окрім найефективніших каналів пошуку, ми ще дізналися, що незалежно від того, шукають опитані наразі роботу чи вже мають постійне місце, вони досить активно стежать за ринком праці. 16% програмістів зазначили, що відвідують співбесіди, аби бути у формі.

Корупція в ІТ-вишах 2019: хабарництво при вступі зменшилося втричі після введення ЗНО.Останнє дослідження про корупцію ми робили у 2016 році, і ось у 2019-мувирішили повторити. Практично відсутня корупція в НаУКМА та УКУ. А ось близько половини студентів та випускників КПІ стикалися з фактами корупції під час навчання.

Найкращі колонки

50 серьезных ошибок в программировании и дизайне, которые стоили жизней, времени и денег.Колись Діма Малєєв зацікавився питанням відповідальності в IT. До фінансових втрат ми вже звикли. Непроданий товар, помилка в розрахунку і незадоволений клієнт — це ті наслідки, про які ми в курсі. Але якщо наші помилки призведуть до невиправних наслідків?

Консервация проблем вместо реформ. Что не так с инициативой Кабмина.2019-йоднозначно запам’ятається нам дискусіями щодо податків. На DOU вийшло багато матеріалів на цю тему, але найбільш популярною стала колонка саме Макса Іщенка, в якій він доволі зрозуміло та аргументовано пояснює, чому ідея Кабміну, м’яко кажучи, неідеальна.

Історія одного саббатікалу, або Як ми стали першими українцями, які обігнули Африку на власному авто.Ця колонка могла б зібрати більше ваших переглядів, бо вона дійсно захоплююча. Наважитися на таку подорож зможуть одиниці, але прочитати статтю потрібно всім. Епічна мандрівка Слави Кравчука на авто з Хмельницького до Кейптауна і назад — 44 країни і 51 300 кілометрів.

Денежный бонус за чтение книг: как мы мотивируем сотрудников развиваться.Уже 5 років в YouScan працює програма «Бонус за книгу»: співробітник отримує грошову винагороду за прочитану книгу і написану на неї рецензію. За словами Олексія Орапа, завдяки ініціативі співробітники почали більше читати — 2,2 прочитаних книги в 2015-мупроти 7,2 в 2018-муна одного співробітника.

Кризис перепроизводства джунов.Доволі суперечлива колонка: Іван Клешнін вважає, що сучасні джуни мають дещо завищені очікування — як от $1000 зарплата зі старту, водночас не маючи ні досвіду, ні достатньо знань. Але в коментарях з автором далеко не всі погодилися: кажуть, що і джунів розумних багато, і зарплату все ж таки їм потрібно платити.

Почему я против тестов на собеседованиях для IT-специалистов. Взгляд рекрутера.Ірина Топіліна проти використання тестування як методу оцінки кандидатів на співбесідах — воно не показує реальний рівень фахівців в Україні. Адже українці не звикли до формату тестів під час навчання і дуже стресують.

Agile по-бандитски, регулярная армия, фуражиры и спецназ.Що спільного між армією та IT-командою? Наприклад, спосіб організації роботи та виконання завдань. Денис Рижих вважає, що самоорганізованою може бути та команда, яка довго робить серію недовгих завдань. Залишаючись в тонусі, цілісною, тренованою, добре забезпеченою і оплачуваною.

Программист разумный.Одна з головних проблем під час розробки ПЗ — складність. Людині властиво помилятися, їй складно тримати в голові всю архітектуру проекту, і це нормально. Руслан Дмитракович розглянув способи, які зменшать складність при розробці.

История одного предновогоднего релиза.Дмитро Меньшиков докладно описав хід своїх думок і вектор пошуку рішення проблеми в одному релізі. Історія покликана послужити гайдлайном при вирішенні завдань.

«Вот сокровище...», или Переговоры на грани фантастики.Денис Братчук зачитувався фантастикою в юнацькі роки. А тепер, маючи 15-річнийменеджерський досвід в IТ, він розповів про основні принципи ведення переговорів і провів паралель з літературним твором Роберта Сілверберга.

Найкращі інтерв’ю

«І в кар’єрі, й у фінансах тут — серйозний дауншифтінг». Як це — бути системним адміністратором на антарктичній станції.Олександр Квятковський поїхав як системний адміністратор зв’язку у складі 24-їантарктичної експедиції українців на станцію «Академік Вернадський». В інтерв’ю для DOU він розповів про відбір та підготовку до експедиції, повсякденне життя на станції та про те, чого не вистачає на острові.

Наталья Денисенко — как в 17 лет стать Software Solutions Architect, а в 19 получить работу в Amazon.У 2015 році на DOU вийшло інтерв’ю з Оленою Денисенко — про кар’єру програміста і посаду Team Lead в 19 років. Минулого року ми поспілкувалися з її сестрою Наталею, яка у 14 років вступила до університету, в 17 працювала на позиції Software Solutions Architect, а в 19 — отримала роботу в Amazon в Сіетлі.

Lead Software Developer из Монреаля — о работе на YouPorn, главных уроках переезда за границу и том, как любовь привела в IT.Костянтин Артемов працює в компанії MindGeek в канадському Монреалі на позиції Lead Software Developer. Нам він розповів, як любов допомогла йому стартувати в IT, про життя програміста в Монреалі і роботу в «індустрії для дорослих», а також про те, що потрібно для успішного переїзду за кордон.

Олег Рогинский, CEO People.ai: «Проще поднять $60 млн инвестиций, чем нанять 10 инженеров».Стартап з українським корінням People.ai минулого року отримав черговий інвестиційний раунд в $60 млн. Ми обговорили з його засновником Олегом Рогинським виклики, з якими стикається стартап на стадії швидкого зростання, складності найму інженерів і принципи корпоративної культури.

«Цифровая экономика — это худшее, что случилось с человечеством за последние сто лет». Константин Петров о спекуляциях на теме AI и работе ученого в США и Европе.В інтерв’ю Костянтин Петров розповів про те, як стажувався в CERN, робив суперкомп’ютер в Нью-Йорку, працював в Данії і Німеччини, і чому вважає французьку модель суспільства більш гуманною. У героя дійсно цікаві, хоч іноді й суперечливі думки, над якими однозначно варто замислитися.

Java-розробниця Тая Холодова — про те, як зважитись на свій стартап і подолати страх невизначеності завдяки саббатікалу.Тая Холодова — засновниця освітнього порталу Voopty. 5 років вона жила в Німеччині й згодом повернулася в Україну. Вона розповіла, як подолала страх першого кроку на шляху до своєї справи, що не так з професією вчителя в Україні та про німецький сексизм.

Влюбиться в Африку: пара украинских программистов — о релокации и жизни в Кейптауне.Програмісти Дмитро Хмара і Катерина Тертіенко переїхали в ПАР три роки тому. В інтерв’ю вони поділилися своїми враженнями про життя в цій екзотичній країні, роботу в місцевих стартапах та культурні особливості.

На пути к мечте: инженер Сергей Якимов — о том, как прошел отбор в колонизаторы Марса и работе в Калифорнии.У 2013 році Сергій Якимів подав заявку на участь у проекті Mars One і потрапив в список 100 перших людей, які будуть населяти планету. В інтерв’ю він розповів, як проходив відбір, а також про роботу в українських НДІ та аерокосмічній індустрії США.

IT-волонтери: як харків’янка привернула увагу до «Розстріляного відродження».Якщо в Харкові звернути з проспекту Науки на вулицю Культури, можна натрапити на п’ятиповерховий житловий будинок, в якому в 20-хроках мешкали Хвильовий, Вишня, Тичина та багато інших діячів культури. Веб-розробниця Анастасія Ковальова розказала, чому українцям важливо знати й пам’ятати про цей будинок, навіщо вона взялася за проект, і як «Слово» змінило її власне життя.

«Я просто роблю те, що мені подобається». Як 18-річнийстудент навчає дітей програмуванню та видає підручники з Python.Євгену Козолупу лише 18 років, а він вже викладає програмування в київському ліцеї, видає власні підручники з навчання Python та працює над розробкою онлайн-курсів. Чому юний вік — не перешкода програмуванню, реалізації амбітних цілей та веденню всеукраїнського проекту з навчання програмуванню — в інтерв’ю з Євгеном.

Найкращі статті

Для програмістів

Разбираемся в алгоритмах и структурах данных. Доступно и понятно.Це дійсно цікава, грунтовна та корисна стаття. Адам Леос розповів про складність алгоритму, нотації Big O, сортування, найпопулярніші структури даних та їхнє використання для оптимізації проекту. Ви все ще вважаєте, що алгоритми — це складно і не важливо? Автор переконає вас у зворотному.

Типові помилки в англійській у IT-спеціалістів і як їх виправляти: поради викладачів.Ми звернулися до викладачів англійської в IT-компаніях з питаннями: в чому саме виникають проблеми з англійською в IT-спеціалістів, які типові помилки трапляються, як їх виправляти й уникати надалі. У цій статті зібрали поради викладачів з 20 IT-компаній.

Как программист зарабатывал $13 тыс. в месяц в Украине и дорос до $23 тыс. в США.Минулого року ми опублікували декілька анонімних історій ІТ-спеціалістівщодо їхнього кар’єрного шляху. Саме ця виявилася найбільш популярною: за 15 років наполегливої праці український програміст досяг прибутку $23K на місяць після податків.

Про Soft Skills в отдельно взятой европейской стране.Через декілька «гордих одинаків» в компанії може трапитися всяке — від зниження настрою у команди до масових звільнень. У Нідерландах немає культу терпимості. Ніхто не буде ходити на роботу, на якій йому некомфортно. У чому різниця в понятті soft skills в Україні та Європі розповідає Таня Зінченко.

ІТ-спеціалісти на початку нульових: СЕО на «Жигулях», розробка «змійки», зарплата 600 грн. Фотоогляд.ІТ-спеціалісти показують і розказують, як починали свій шлях у професії: яким був перший комп’ютер, як вчилися програмувати, якою була перша робота в ІТ... Розробники і не тільки поділилися своїми спогадами і світлинами з дев’яностих та двотисячних.

Нужны ли программисту алгоритмы и структуры данных.Вічний холівар на тему «чи потрібна програмісту математика» піддається зміні і перетворюється в більш небезпечну для індустрії суперечку. Все частіше з’являється думка: «Чи потрібно програмісту знати алгоритми і структури даних?». На питання відповів Денис Цьоменко, Software Engineer в Data Robot.

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

Как стать full stack разработчиком, зная back-end. Пошаговая инструкция.Влад Фурдак сформував загальне розуміння сучасної front-end екосистеми для людей, які вже мають досвід в розробці на back-end технологіях. І надав базові рекомендації тим, хто хотів би розширити своє коло компетенцій.

Здоров’я ІТ-спеціаліста: сон, харчування, фізична активність.Хотілось би, щоб ця стаття стала мотивацією стежити за власним здоров’ям: перевіряти зір, займатись спортом або хоча б влаштовувати піші прогулянки, відвідувати масажний кабінет, вимикати всі девайси за годину до сну тощо.

Как я резюме обновлял, или ML-экспериментс базой ФОПов.У тестувалньика Володимира Шумари з’явилася вільна хвилина на те, щоб не востаннє змахнути пил зі свого резюме і видалити абревіатури, розшифровки яких він вже не пам’ятаю, а замість них додати чогось сучаснішого. Що там зараз в тренді? Data Science, ML, AI? Цікавий вийшов експеримент.

Для менеджерів

14 типов менеджеров, которые бесят разработчиков.Історії з практики, коли рішення PM-ів здавалися дуже дивними або навіть заважали працювати. У статті — 14 деструктивних моделей поведінки менеджерів. До речі, поки що так і не прийшла відповідь PM-ів щодо дратівливих типів розробників.

10 шишек на одном проекте. Опыт PM’а.Мало хто погодиться розказати про свої фейли, тому навіть просто за сміливість Костянтину Болотіну можна віддати всі нагороди та подяки. Він розповів про свій досвід на реальному проекті — як з’ясовувати бажання клієнта, орієнтуватися на те, що краще для нього, пояснювати те, що йому не є очевидним, і не допускати подвійного підпорядкування.

Встречи 1:1. Почему не работает такой простой и понятный инструмент.Стаття буде корисна всім, хто хоче включити зустрічі сам на сам в роботу зі співробітниками компанії. Дмитро Горін розповів, з чого почати, як їх проводити і якими можуть бути результати.

Навіщо ІТ-компанії пропонують нематеріальні бонуси працівникам. HR-відділи успішніших компаній IT-сфери дбають про створення «додаткових благ» для своїх працівників, аби вмотивувати працювати в конкретній компанії. Юлія Шишенко розповідає про те, які бувають бонуси, для чого і чи дійсно є ефективними.

Почему я выбрала Project Management и не ошиблась. Советы тем, кто раздумывает.Перехід в менеджери — не єдиний шлях розвитку кар’єри. Буває, що люди навіть повертаються в розробку. Але і цікавого тут чимало. Ольга Твардовська розповіла, що її драйвить в професії і що чекає на тих, хто хоче в неї прийти.

Як прокачати емоційний інтелект, щоб спілкуватися з колегами результативно.Емоційний інтелект (EQ) — це здатність людини розуміти та керувати емоціями, які відчуває вона і ті, хто поруч. Христина Яблонська ділиться своїми знаннями на цю тему.

5 книг, которые посоветовал бы своей дочке Роман Прокофьев, основатель Jooble.Кожен раз, коли хтось просить порекомендувати йому цікаву книгу, Роман мимоволі здригається. Навіть близьким друзям порекомендувати книгу — непроста справа, не кажучи вже про велику аудиторії. І саме цьому він вирішив написати про книжки, які б радив своїй дитині.

Что делать, когда Scrum трещит по швам.Після нещодавнього проекту Agile-трансформації для одного клієнта Роман Резніков вирішив структурувати знання щодо scaled-підходів. У цій статті — результат.

Как научить команду общаться. Прием для менеджеров.Ця стаття про те, як в Dev-Pro навчили велику команду писати коментарі в таск-трекер, а разом з тим поліпшили комунікацію на проекті. Матеріал буде корисний менеджерам проектів, CEO невеликих компаній, HR-менеджерам і всім, хто хоч раз скаржився на політиків в офісній курилці.

«Ну ма-а-ам... я більше так не буду», або Про веселе життя PM’а.У цій статті — досвід, набутий у звичайних трудових буднях ПМ’а. П’ятничні релізи, порожні тікети, усне проговорювання «очевидних» речей, приблизні естімейти і єдиний розробник на проекті, який іде у відпустку.

Для новачків

Как украинские IT-компании встречают новичков в первый рабочий день.Огляд велкам-паків українських IT-компаній. Велкам-пак — це жест гостинності і турботи від імені компанії, можливість справити перше враження. Часто це дозволяє новачкові швидше познайомитися з компанією, її традиціями і полегшує старт робочого шляху.

Как провести тестирование на безопасность: руководство для Manual QA.Ця стаття націлена на підростаюче покоління QA і розробників, яким цікаво дізнатися щось про уразливість: з чого почати, якими інструментами можна користуватися початківцю в цій справі (практичні поради).

«Я не хочу так работать». Как медик освоила IT и почему ушла через 3 года.Анна Чернишова працювала педіатром, згодом з нуля освоїла тестування, а потім — і Front-end розробку. Але світ IT виявився для неї не таким вже чарівним: старий проект, робота за жорстким графіком. Тому, навіть витративши стільки зусиль на навчання, вона вирішила піти зі сфери.

Советы для начинающего Java-разработчика. Подготовка к собеседованию — часть 1.Цей цикл статей адресований людям, які перебувають на першій сходинці під назвою «Корпоративна розробка на мові Java». Перша частина присвячена плануванню процесу навчання, а також визначенню тем і питань для самооцінки.

Путь стажера: Ubisoft.Вадим Білецький вважає комп’ютерні ігри видом мистецтва. Він стажувався в Ubisoft і поїхав працювати до Франції. Раніше хлопець робив тільки невеликі гри на телефоні, а на стажуванні йому вперше доручили робити великий повноцінний проект. У статті він розповів, як це було.

От джуниора к лидеру. Какие навыки нужны для роста в профессии.Чи варто намагатися бути «в темі» всіх сучасних технологій в галузі? Або ж варто зосередитися на одній конкретній області і бути в цьому експертом? Влад Федосов пропонує T-shaped набори навичок для різних етапів в кар’єрі розробника.

З данських теплиць до харківської IT-компанії. Історія механіка, який став програмістом.Євген Сагач працював в теплицях, доглядав квіти. Коли постало питання пошуку майбутньої професії, звернув увагу на програмування. На другому місяці навчання на ІТ-курсах він знайшов роботу. У хлопця було шість співбесід, в результаті яких отримав три офери.

Советы сеньоров: как прокачать знания junior HR/Recruiter.Зібрали поради від найдосвідченіших рекрутерів / ейчарів в українському ІТ — загальні лайфхаки з навчання, які книги і ресурси читати, які навички освоювати і багато іншого.

Реальность начинающего продакт-менеджера: как выучить всё и выжить.Наталка працює продакт-менеджером. У цій статті вона поділилася з потенційними продакт-менеджерами своїм підходом до навчання і висновками з навчальних невдач. Подивіться, навіть якщо ви не продакт-менеджер. Буде корисно всім, хто хоче вчитися системно.

С чего начать работу с ML и DL. Обзор лучших библиотек.У цій статті старалися полегшити вибір для новачків. Розглянули найпопулярніші і необхідні бібліотеки, які покривають усі базові потреби для початку роботи з Machine Learning і Deep Learning.

Технічні статті

12 ошибок при построении архитектуры ПО.Одна з найпопулярніших технічних статей року — майже 40 тисяч переглядів. Олег Шаститко розглядає проблеми в архітектурі на основі реального проекту, з якими йому довелося зіткнутися. Ці аспекти, якщо і не виявляються критичними, то істотно впливають на подальшу розробку програмного продукту.

Машинное обучение в повседневной жизни: типы ML и способы их применения.Машинне навчання поділяють на навчання з учителем (supervised), навчання без учителя (unsupervised) і навчання з підкріпленням (reinforcement learning). Дивимося, як вони працюють і в яких випадках застосовуються.

Архитектура видеосервиса Megogo: варианты решений и переход от монолита к микросервисам.Дмитро Мєлков, CIO в Megogo, розповів про досвід переходу від монолітної до мікросервісной архітектури продукту і про вибір, який згодом зробив розробку і підтримку системи простішою.

Эволюция .NET-стека: что изменилось за последние несколько лет.Ця стаття для людей, які вже мають досвід у комерційній розробці на .NET і бажають апгрейдити знання у зв’язку з останніми релізами технологій від Microsoft. А також для тих, хто роками сидить на старих версіях ASP.NET / C# і хоче бути в курсі, що нового в світі .NET-технологій.

Chrome DevTools: налаштування, можливості та способи перевірки коду. Chrome DevTools — один з найпотужніших інструментів веб-розробника. Його слід опанувати, щоб у разі потреби швидко з’ясувати, у чому проблема з кодом й ефективно її розв’язати. Стаття — must read для початківців та всіх, хто займається веб-розробкою і переймається своєю ефективністю.

Стоит ли инвестировать во Flutter. Сравнение Flutter и React Native.Василь Дицяк розповідає про особливості роботи Flutter — фреймворка для кросплатформеної мобільної розробки. Він вважає, що його успіх — це питання часу, помножене на зусилля ком’юніті і підтримку Google з написання production-ready ембедерів для всіх найпопулярніших платформ.

Микросервисный подход в веб-разработке: micro frontends.Фронтенд-розробка перетворилася з простого набору доповнень, призначеного для користувача інтерфейсу, в складну екосистему з великою кількістю інструментів і високим порогом входу. Алекс Зіневич розповів про мікросервісний підхід в веб-розробці користувацьких інтерфейсів.

Как использовать Hibernate: основные проблемы и их решения.Андрій Слободяник вже понад 10 років працює в Java Enterprise проектах. У кожному з них були дані в базі, а доступ до них здійснювався з допомогою JPA / Hibernate. Водночас фреймворк використовувався, як автору здається, не зовсім правильно: код міг бути компактнішим, а продуктивність вищою.

Про котів і математику, або Магія Computer Vision.Олександр Маковейчук показав, як «непотрібні» шкільні знання можуть суттєво допомогти в Computer Vision проектах. У цій статті говорили про сингулярний розклад і псевдобернення матриць.

Делаем простой и надежный микросервис рассылки пушей на компонентах AWS.Андрій Товстоног поділився досвідом побудови маленького мікросервіса з використанням безсерверної архітектури AWS. А ще розповів, як працюють push-повідомлення і з якими проблемами зіткнулися під час реалізації цього рішення.

Про релокацію

Канада для IT-шника.Володимир Железняк минулого року переїхав до Канади і написав справжній лонгрід про перші враження життя в цій країні та взагалі про релокацію. Як написали в коментарях: «Цікаво і по справі».

Как переехать из Киева в Лондон и не прекращать жить.Сашко Ємельянов почав свій шлях у менеджменті з того, що відкрив власний стартап. Далі було стажування в Гонконзі, робота в продуктових (і не дуже) українських компаніях. У квітні в стрічці Facebook промайнула вакансія продакт-менеджера в лондонському офісі Badoo. І ось він вже майже рік живе і працює в Лондоні.

«Здається, я живу не в Швеції, а в Spotify»: історія про комфортний релокейт.Роксолана Косів — уже рік працює iOS-розробницею в стокгольмському офісі Spotify. В інтерв’ю для DOU вона розповіла про те, як проходила співбесіди в компанію, про переїзд та умови роботи там.

Брюссель глазами инженера — о жизни в Бельгии и сложностях релокации.Олександр з 2016 року живе і працює в Бельгії. У статті мова піде про життя в цій країні, перипетії в отриманні документів, побутові питання. Текст буде цікавий тим, хто вирішив пошукати роботу за кордоном і замислюється про переїзд.

Країна сієсти: подружжя українських програмістів про переїзд на Мальту й причини повернення додому.Андрій працює Senior Developer у компанії Global Mediator, Ольга — Senior Developer в Infopulse. В інтерв’ю для DOU Андрій та Ольга розповіли, як жили й працювали на Мальті та чому зрештою вирішили повернутися в Україну.

Страна, где уместен торг на собеседовании. Как живется программисту в Израиле.Сергій Шелехов у 2017 році з дружиною переїхав жити до Ізраїлю, де вони влаштувалися працювати в різних IT-компаніях. У цьому матеріалі він розповів про особливості життя айтішника в цій країні. В Ізраїлі є свої плюси і мінуси, але, на суб’єктивний погляд автора, плюсів все-таки більше.

Кремнієва долина Європи. Український програміст про життя в Естонії та роботу в Bolt (Taxify).Артем Верещака нещодавно закінчив НАУ. Торік із серпня почав працювати інженером у Естонії у компанії Bolt (до ребрендингу — Taxify). У цій статті — про переїзд до Естонії, роботу в компанії, побут та особливості життя в країні.

Якщо зміни, то глобальні, або Як я опинився в Люксембурзі.Люксембург зацікавлений у розвитку ІТ-технологій, тож створює максимально комфортні умови для релокейту ІТ-фахівців з інших держав. Та є мінуси: дороге житло, відсутність поняття «перегляд зарплатні», довготривалість побутових процесів. Про свій досвід роботи розповідає розробник Ігор Шуляр, що півтора роки тому переїхав у Люксембург.

Кремнієва долина Китаю. Як програмісту живеться у Шеньчжені.Нік Турунов після закінчення КПІ влаштувався комп’ютерним майстром на всі руки. Згодом відкрив для себе журналістику і певний час працював редактором на DOU, аж поки доля не привела в EPAM. Там він вирішив повернутися до свого початкового фаху і підівчився на програміста. П’ять років тому переїхав до офісу компанії в місті Шеньчжень, що сусідить із Гонконгом. У статті розповів, що спонукало змінювати фахи та як наразі живеться у Китаї.

Подорожі, розвиток та рівні права всім: web-аналітик Галина Харківська про роботу в Booking та життя в Амстердамі.Галина Харківська уже рік працює web-аналітиком у Booking.comу Амстердамі. Для DOU вона розповіла, як потрапила в компанію і як це зробити іншим, а також про умови роботи й плюси, які одержує кожен працівник найбільшої технологічної компанії у сфері подорожей.

Форум та читачі

В 2019-муви опублікували 1895 топіків, які зібрали 227 тисяч коментарів. Майже 12,5 тисяч користувачів DOU залишили хоча б один коментар.

Як і минулого року, найактивнішим став Viktor Chyzhdzenka — у нього понад 10 тисяч коментарів в 2019-му.Найчастіше ви підримували думки Дениса Ювженкоі Beaver Green (серед користувачів з 300+ коментарями за рік) — кожен їхній коментар в середньому збирав 5 лайків, а найпопулярнішим став коментар Artem Tkachuk — 269 лайків.

Ось 15 тем, які ви обговорювали найактивніше минулого року, кожна зібрала понад 30 тисяч переглядів і сотні (а іноді тисячі) коментарів:

  1. Когда подорожает доллар? Сил нет уже
  2. Володимир Зеленський стане шостим президентом України (серед популярних топіків було ще 8, що присвячені виборам президента, ми не будемо їх дублювати у цій добірці)
  3. Айтишники 30y.o., где вы находите адекватную пару?
  4. В чем смысл миграции?
  5. 24 онсайти у Долині, або Тореадор із Заточки (Update 2019/12/18 — 2)
  6. Что вам не нравится в текущей стране пребывания?
  7. Про расходы в Калифорнии
  8. А что если ОНА зарабатывает больше?
  9. Минсоцполитики «покращивает» Предпринимателей — законопроект
  10. Стоит ли забирать военный билет?
  11. Что вам не нравится в Украине? Почему столько тем про трактор?
  12. 31 летний техлид: мы живём не туда, на вершине IT ничего нет, только мысли о скором выпиле
  13. ФОП новая группа и новые налоги
  14. Квартира, ипотека 2019
  15. Майдан 3.0?


Вітаємо спільноту з Новим роком! Спасибі вам, що були з нами — писали статті, давали коментарі, вели дайджести, рецензували тексти і просто читали, критикували та робили нас кращими. Також запрошуємо як постійних, так і нових авторів надсилати статті. І приєднуйтеся до телеграм-каналу редакції DOU — публікуємо тільки найважливіше, лише декілька постів на тиждень.

Как ЛУН совершенствует карту новостроек: технический путь к 3D-моделям и AR

$
0
0

Всем привет! Я Тарас, Front-end developer в ЛУН. С первого своего дня в компании я выбрал работу над картой новостроек. В этой статье я расскажу о том, как от самой простой 2D-карты мы пришли к трехмерным моделям на основе видео с дронов.

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

Карта 1.0. Пины, полигоны, тормоза

Два года назад наша карта представляла собой Google Maps, пины по координатам ЖК и полигоны (территория ЖК), которые мы наносили с помощью Кадастровой карты.

Версия карты всех новостроек, 2017

Изначально у нас были две проблемы и одна мечта.

Первая проблема — мы не могли быстро отобразить несколько тысяч ЖК Украины на Google Maps. Данные, которые надо было передать клиенту (id + геометрия) для пинов и полигонов, занимали ~10 МВ. Это стало причиной деления карты по городам: «Новостройки Киева», «Новостройки Харькова» и т. д.

Вторая проблема — карта была похожа на одинокого новогоднего зайчика Roshen, которого никто не купил и который до марта лежит на прилавке. Скорость рендера, инерция при drag and drop, плавность zoom — все хотелось сделать круче.

И мечта — как-то отрисовать дома будущего ЖК в 3D. Так, чтобы застройщик еще только поставил забор, показал генплан, а у нас на карте уже есть этот ЖК в 3D.

Карта 2.0. Тысяча и одна новостройка сразу

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

Кластеризация работает быстро, но это неспортивно :)

Изначально показать все и сразу нам помог KML (Keyhole Markup Language). Разбираться с KML нескучно: отдаем KML-файл, а в ответ — ничего. Никаких ошибок от Google Maps, работающий валидатор KML тоже нашли, но почти всегда решает простая валидация на XML. Получилось вот так:


KLM неплох, но эффект испорчен задержками


Круто, ЖК по всей Украине теперь отдаются тайлами. Объем передачи данных минимален — несколько png-картинок. Однако мерцание слоя с данными, пока не будет закеширован каждый зум, конечно, бесит. Немного меньше бесит замыленность пинов: в KML нельзя применить стандартный прием со сжатием картинки в 2 раза.

В поисках улучшений периодически читали документацию по API и SO, как-то даже нашли рабочий пример 3D-дома на Google Maps (примера больше нет, но статья жива). Тогда же и вышли на Mapbox.

Попробовав сервис от Mapbox, как альтернативу Google Maps, мы поняли, что есть смысл оставить клиентскую часть на mapbox-gl-js, а остальное — self-hosted. Для компании, сравнимой с ЛУН по трафику, экономия составляет около $100 000 в год. Экспериментировали с Mapbox по-разному, в итоге вот на чем остановились:

  1. Подняли в UA-IX tile server на базе nginxдля подложки карты.
  2. Создали свой стиль.
  3. Включили сжатие nginx + brotli.

Это не только дало нам финансовую выгоду, но и увеличило скорость отдачи тайлов в Украине. Для динамических данных (точки, контуры) у нас подход немного иной:

  1. Раз в 30 минут с MySQL генерируем GeoJSON.
  2. GeoJSON упаковываемв mbtiles.
  3. mbtiles раздается тайлами с помощью tileserver-gl.

В будущем есть желание и здесь уйти от tileserver-gl и делать нарезку сразу же после выгрузки из базы. Результат удовлетворил наши ожидания:


1000 точек без тормозов!


C переходом от тайлов Mapbox к self-hosted мы также решили проблему длительной модерации и обновления данных из Open Street Map. Например, чтобы убрать на карте надпись «тут цигани», у нас уходило несколько месяцев на переписку с Mapbox Support.

Остались задачи модерации (зашквар OSM с картой Крымане особо актуален, так как мы удалили все ЖК полуострова) и вандализма в OSM, которым в Mapbox, скорее всего, уделяется огромное внимание.

Карта 2.1. Контуры домов на карте

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

Контуры всех домов и секций новостроек Украины на карте. Год жизни команды контента

Карта 3.0. Теперь в 3D!

Переход на Mapbox не только помог нам сделать более приятными в использовании уже существующие наработки (не говоря уж о том, насколько расширил наши знания о картах в целом), но и стал площадкой для осуществления давних желаний. Для 3D-домов у нас не было контуров, однако для некоторых ЖК нашлись в базе контуры секций (остались от размещения плана этажа на карте), которые в итоге оказались более удобными при отрисовке дома из-за возможной разности этажности в многосекционном доме. Умножив этажность секции на 3 метра и применив fill-extrusion, мы получаем 3D-дома на генплане:

Еще не построенный Unit.Home теперь в 3D согласно официальному генплану

Paint, render, фильтрация, анимации — все реализовано хорошо. На карту стало приятно заходить не только потому, что вот-вот надо инвестировать, но и просто вместо Facebook — полистать, узнать, что там новенького, не покраснели ли случайно дома корпорации «Укрбуд». Красным цветом мы начали кодировать замороженные и проблемные стройки.

Карта 4.0. Реконструкция настоящего

Первое знакомство с 3D-реконструкцией у нас произошло на совершенно другой задаче. В ЛУН-поиске (сейчас Flatfy), где пользователям предоставляется информация об уже готовых квартирах на вторичном рынке, мы различными способами решали задачу обогащения контента. Однажды пришла идея создать простую 3D-реконструкцию квартиры из имеющихся в объявлении фотографий интерьера и вспомогательной картинки планировки.

Мы были базово знакомы с OpenMVGи в целом с подходом Structure from Motion. Намного больше экспертизы у нас накопилось в обработке изображений, в частности для задачи дедупликации фоток. В совокупности это дало нам понимание, что сначала надо построить point cloud.

Сделав несколько десятков снимков кабинета, мы впервые запустили pipeline-реконструкции. Результат был невпечатляющим:


3D-реконструкция кабинета AI/ML-разработки ЛУН


Спустя две недели прототипирования у нас получилось более качественно:


3D-реконструкция переговорки ЛУН из сотни фотографий


Но даже для такого результата требовалось больше сотни снимков (или видео) помещения и часы обработки.

Пару лет назад мы начали облетать дронами новостройки для «Аэрооблетов 360». Как результат, для большинства новостроек было видео с дрона в 4К. Начали экспериментировать с подходом Structure from Motion, в этот раз использовали по назначению. В результате удалось получить point cloud, а затем и mesh практически фотографического качества:


Mesh 3D-реконструкции с видео аэрооблета дроном, от 200 MB


Размеры моделей были от 200 МВ, что исключало их размещение на карте. Представить дома минимальным количеством полигонов нам помог Mixa Anderson, которого мы нашли по крутымреконструкциямна sketchfab. В процессе используются Metashape, ContextCaptureи Meshroomдля 3D-реконструкции модели и blenderдля упрощения геометрии и экспорта результата. Сжав текстуры и конвертировав в glb, мы добились уменьшения модели в ~20 раз.

К этому времени в Mapbox появилась возможность создавать Custom Layer. Для загрузки, камеры и освещения модели выбрали threejs (как альтернативу рассматривали luma.glот Uber). И вот на карте тот же ЖК Tetris Hall, но уже объемом 2.2 MB:

3D-реконструкция построенного ЖК Tetris Hall на карте ЛУН, 2.2 MB

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

Карта 5.0. Реконструкция дизайнерских рендеров

Когда дом в начальной стадии строительства, снимать с дрона нечего. Данных для 3D-реконструкции нет, а хочется наглядно показать, что планируется в финале. В таком случае берем для визуализации модель ЖК. Подключили ребят из FrontVisual, совместно создаем 3D-генпланы для ЖК, например Unit.Home (3.7 MB):

3D-модель строящегося ЖК Unit.Home на карте ЛУН, 3.7 MB

Карта Х. Еще больше 3D

Теперь, собрав оптимизированную реконструкцию или модель ЖК в USDZ, можно отобразить их у себя на столе в AR и скинуть другу через iMessage.

AR-модель ЖК Unit.Home для iPhone, 3.7 MB

Бонусный уровень — Godzilla Mode, когда AR-модель увеличена до роста человека:) Детализации текстуры хватает для просмотра окон в домах комплекса.

Godzilla Mode :)

ToDo: выбор квартиры будущего

После выбора ЖК логичным следующим шагом пользователя будет выбор квартиры. Так как интерактив glb-модели реализовать сложнее (надо создать связь между сущностями в glb и MySQL, поддерживать их актуальность), в качестве baby step мы выбрали построение модели на клиенте. Сейчас наша визуализация квартиры на карте ограничивается зеленым полигоном:

С переводом планировок в VR (а сейчас еще и с панорамными окнами ^__^) мы стали получать не только более точные контуры планировок, но и межкомнатные стены. Несложно построить полноценную модель планировки:

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

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

Выводы

  • Переход к векторным картам добавил к скорости рендера: тайлы зачастую легче, со способностью к overzoom.
  • Векторные карты проще кастомизировать. Например, в Mapbox Studioили maputnik.
  • Переезд от данных Google к OSM добавил гибкости (проще контрибьютить) и особо не потерял в качестве.
  • Поддерживать Google-карту в качестве fallback для тех, у кого не работает WebGL, вышло затратно. Генерируем просто скриншот (placeholder) генплана с помощью Puppeteer.
  • Поднять свой tileserver с ходу показалось сложным, но шаг за шагом все сводится к простой раздаче статики через nginx. Тайлы спутника недорого можно взять у HERE.
  • Для визуализации большого объема данных лучше использовать тайлы.
  • Количество данных, которые хранятся в GeoJSON Feature, сводим к минимуму: меньше вес, меньше потребность в обновлении.
  • Рендерить GeoJSON удобно, когда данных мало, а также когда на клиенте нужна точная геометрия (например, продублировать полигон). Из-за того что геометрия одной Feature может быть разрезана между несколькими тайлами, собрать ее обратно сложнее.
  • Представление 3D-модели минимальным количеством примитивов (например, одна грань дома — 2 треугольника) дает выигрыш в размере и упрощает AR render.
  • Будущее визуализации карт в вебе за mapbox-gl-js.

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

Як українські IT-компанії святкували Новий рік 2020

$
0
0

Початок 2020 року — традиційнийфотоогляд святкування Нового року в українських ІТ-компаніях.

AB Games

Новорічний корпоратив у стилі Like Home Party: піжами, кігурумі, капці з оленями і домашній затишок. Команда чудово повеселилася, адже святкували цілих два дні. Кожен зміг знайти активності до душі: катання на конях і квадроциклах, стрільба з лука, квести, конкурси, танцювальні батли і просто відпочинок в СПА. На фото — святкування команд з Києва, Харкова, Рівного та Дніпра.





AB Soft

Зимова вечірка пройшла в тематиці Casino Royale. Майже 400 гостей свята занурились в атмосферу сучасного казино: зіграли у покер та рулетку, спробували вдачу біля Колеса Фортуни, побачили справжнє бурлеск-шоу, а також святкове світлодіодне шоу. Найкращих перформерів компанії привітали в рамках церемонії нагородження AB Soft Winter Awards’19.

AgileEngine

Харківський офіс компанії провів корпоратив у стилі Disco. Влаштували танцювальний челендж, мали нагоду позмагатися у співі, танцях та спритності у великій ігровій зоні. У Києві співробітники розмістилися в 3-поверховому party house, за кожну активність учасники отримували лампочки, з яких створили ракету й опівночі запалили її.




Agiliway

Champaign party, чи венеціанський карнавал? Компанія вирішила не обирати та влаштувати новорічний корпоратив в обидвох стилях. Шампанська вечірка — у Львові, а духом Венеції перейнявся новий офіс в Чернівцях.




AMC Bridge

Вечірки були у стилі Різдвяного ярмарку або маскараду. Колеги активно проводили час: ковзани, bumper ball, лазертаг, боулінг та мастеркласи, а також щирі розмови з глінтвейном. Відбулася церемонія нагородження тих, хто працює з AMC Bridge вже 10 та 15 років. Команда висловила подяку колегам за безцінний внесок у розвиток компанії.







appflame

Влаштували вечірку в стилі «Лас-Вегас», під час якої була можливість одружитися та виграти цінні призи.

Astound Commerce

Відсвяткували новорічний корпоратив у стилі «Infinity Space Night 2091». У Парковому зібралось більше 600 людей з усіх 5-тилокацій в Україні. Офіційну частину свята розпочали з нагородження найкращих спеціалістів, після якої під драйвові танці запалював український електронний гурт Onuka.

Beetroot

У кожному місті новорічна вечірка Beetroot мала свою тему: у Києві зібрались зірки Голлівуду, в Одесі — карнавальні маски, у Франику — любителі курки гриль та огидних светрів, а в Полтаві — супергерої, що окрім світів DC та Marvel об’єднала і ще дві команди Beetroot — з Кременчука та Харкова.






Binary Studio

Команда побувала в щорічному різдвяному «Євротріпі». Цього року відвідали теплий Лісабон, кольорову Сінтру та бурхливий Кашкайш в Португалії; казковий замок Нойшванштайн та затишний Меммінген в Німеччині, і альпійський Інсбрук в Австрії.

Blackthorn Vision

Цьогоріч у компанії відбулось два гучних новорічних святкування. У Львові влаштували вечірку у форматі «Golden Night» у атмосферному BANK Hotel. Головним мотивом вечору стали блискітки та сяючі образи колег. Колеги з Хмельницького офісу влаштували свято у стилі фільму «Хрещений батько». Свято супроводжували мафіозні конкурси та шалені танці. Родзинкою двох святкувань стало нагородження колег у рамках Recognition Program за відмінні особисті якості.




Brightgrove

Команда опинилась у справжній казці — у замку самого Cанта Клауса. Поки Санта відвідував маленьких діточок, на співробітників чекали його помічники — ельфи, разом із якими колектив Brightgrove казково провів час: були танці, новорічні конкурси та пісні, майстер-класи хендмейд подарунків від ельфів та декілька тематичних фотозон. P. S. Казка закінчилась щасливо і жоден єнот не постраждав!

bvblogic

Компанія святкувала новорічну вечірку у стилі Кіногероїв. Кожен мав змогу перевтілитись та перебувати в образі свого улюбленого персонажа. Доповненням була червона доріжка та тематична фотозона. Працівники, котрі мали найцікавіші костюми, отримали нагороду Короля та Королеви вечора.

CHI Software

Компанія провела вечірку в стилі Cyber. На майданчику був широкий спектр інтерактивів: Dance kinnect, робобої, Bulletime, розпис імбирних пряників, Cyberpunk Arena та майстер-клас з гри на барабанах, які світяться. Усі команди було нагороджено сертифікатами з відзнакою.

Clockwise Software

Дніпровська компанія Clockwise Software провела шостий новорічний корпоратив, виїхавши за місто на вікенд. Команда разом із половинками та дітьми за два дні побували у Британії, Греції та Джунглях. Справа в тому, що з півсотні хлопців та дівчаток зупинилися у готелі «Британія» у Харкові. Там і влаштували вечірку із богами та міфічними істотами у грецькому стилі, а наступного дня відвідали харківський аква-парк «Джунглі».

CodeIT

Codeminders

Команда відсвяткувала новорічний корпоратив у Єгипті без офіціозу та смокінгів. 45 завзятих мандрівників впродовж 3-охднів відривалися на повну: каталися на верблюдах, ганяли на квадроциклах, пірнали в морську безодню, танцювали до знемоги на дискотеці, а вранці на пробіжці зустрічали схід сонця.

Codemotion

Компанiя провела корпоратив в стилi «Схiдна нiч». Були східні танцi вiд girls band, запальна гра на барабанах, багато непередбачуваних конкурсiв i подарункiв. Драйвова атмосфера, танцi до ранку і ще багато чого цікавого залишилося в спогадах у команди!

Codica

Рік, що минає, компанія Codica провела в стилі #НайКращі. У програмі вечора були привітання від Олега Винника, гроші від Юкіхіро Мацумото, веселі конкурси та танцювальні батли.

Competera

Компанія цього року провела новорічне свято під гаслом «Competera goes British!». Традиційними елементами вечірки стали подарунки від Secret Santa, нагорода «Competera Hero» для кращих співробітників та різноманітні тематичні розваги.

Conscensia

Новорічна Movie Stars Party у Conscensia цього року зібрала багато кіногероїв. Консенціанці були у образах Леона, Тора, місіс Попкорн, Джокера, Джесі Пінкмана та інших. Спеціалісти розважались під пісні запального кавер-бенду, робили багато фотографій у селфі-дзекралі, віар-окуляри зібрали не один десяток охочих відчути круті емоції. А на завершення обмінялись листівками подяки, відзначили кращих колег та розіграли круті призи.

CS

Daxx

Київський офіс Daxx зустрів зимові свята яскравою вечіркою New Year Rock Party: з музичними конкурсами на знання жанру, танцювальним флешмобом та нагородженням колег, котрі найдовше працюють у компанії. У Дніпрі відбувся корпоратив у стилі «маскарад»: вбрання кожного гостя доповнювала маска, усі охочі власноруч розмальовували різдвяні смаколики та декорували лого компанії у техніці стрінг-арт. Харківська команда запалювала на вечірці «Time to New Year!» у форматі стімпанк. Було багато логічних ігор, цікавий квест, а також віртуальний джедай AR.





Delphi Software

Відсвяткували вишуканою вечіркою в стилі Big Jazz Night.

Depositphotos

Окрім традиційної зустрічі Нового Року Depositphotos відмітили десять років існування компанії на вечірці з символічною назвою TanAgers Party в Stereo Plaza. На святкуванні згадали з чого починався світовий фотобанк, відмітили найдавніших та самих нових співробітників, а своїм виступом компанію привітав Pianoбой.

Devart

Компанiя влаштувала шалену вечiрку у стилi 90-х:старi iгри на телевізорах з кінескопом, кавер-бенд Take Five з улюбленними пiснями, конкурси та призи за найкращi образи на двох тематичних фотозонах.

Digicode

Новорічні вечірки Digicode традиційно прошли яскраво, з драйвовими та запальними танцями, конкурсами від ведучих та купою подарунків. У київському офісі святкували у стилі Neon Party, а команда із Полтави організувала Silver Party. Вечірки проходили одночасно і завдяки космічним технологіям команди в режимі реального часу могли бачити один одного та обмінюватись привітаннями :)




Digitally Inspired

Цього року усі офіси зібралися в Одесі, щоб відсвяткувати новий рік у стилі рок! Яскраві образи, гучна музика та тематичні конкурси створили по справжньому драйвову атмосферу. Головною несподіванкою вечора став виступ колег, що виконали один з найкрутіших рок-хітів!

Drudesk

Відгуляли в кращих традиціях «Star Wars» і навіть обрали костюм переможця, хоча всі персонажі були неймовірно круті.

EasyPay

Новий 2020 рік українська fintech-компанія відсвяткувала у стилістиці «Аліси в країні див». Під час вечірки, під головуванням справжнього Капелюшника, співробітники компанії перетворилися на героїв казки, змагаючись у численних конкурсах за головний приз святкування. У фіналі програми відбулось нагородження команди переможців.

Edvantis

Зустріли 2020 рік на костюмованій вечірці-маскараді з класичними танцями, предивними персонажами, інтелектуальними конкурсами і нестримним карнавальним драйвом. А традиційна лотерея принесла щасливцям призи зі справжніми пригодами.

EIS Group

Компанія відсвяткувала Новий Рік в iрландскому стилі. Запальний ірландський степ, народні та сучасні пісні у виконанні группи Jollys band, і, звичайно, традиційні ірландські напої зробили цей вечір атмосферним та незабутнім!

ELEKS

Цього року офіси ELEKS занурились у справжню зимову казку під час корпоративної вечірки Winter Wonderland. Львів, Тернопіль, Київ та Івано-Франківськ поринули у запальні музичні ритми кавер-гуртів та діджеїв, а також насолоджувались класичним новорічним джазом. Глінтвейн та сморси, ялинки і шапки Санта Клауса, фокусники та перфоманси, і тепла атмосфера навколо — було круто!






Ergonized

Провели чудовий вечір, згадали про досягнення, обговорювали плани на майбутнє, та просто розважалися!

Eska

Exadel

Exadel Ukraine відсвяткували початок 2020 року на вечірці в стилі 90-их.Запалював Вінницький театр вогню Fiery Dream, дівчата — наче зійшли з екранів улюблених серіалів «Beverly Hills 90210», «Friends», «Hélène et les Garçons», круті хлопці — як із дворів та з-за гаражів наших міст. І весь вечір класної музики та драйвових танців, конкурсів та душевних пісень.

Ezlo

Харківський офіс компанії провів новорічну вечірку у затишному барi Yankee. Ніяких тем та правил — лише дружня атмосфера, веселі конкурси та запальні танці.

FlexMade

Компанія влаштувала новорічну вечірку у стилі «Техно». Підвели підсумки 2019 року та згадали найкращі моменти. Подякували співробітникам компанії за чудову роботу і поставили нові цілі на 2020 рік. Зустріли Діда Мороза з танцювальною програмою, подивилися на світових роботів, попробували танцювати сальсу та бачату, зіграли у квест, веселились та спілкувались.

Forbytes

«Let’s Art Party» — під таким девізом компанія проводжала 2019-й.Відзначали найкращих «митців» року, створювали логотип компанії у техніці стрінґ-арт, а найсміливіші, озброївшись мольбертами та пензлями, малювали портрети коллег. Вечір доповнили величезна джанґа та найкращі різдвяні хіти у виконанні кавер-гурту, адже найважливіше мистецтво — проживати кожень день наповну.

Forma Pro

На один вечір співробітники компанії переткнули кордон з Мексикою та опинилися в центрі гучної вечірки. Текіла, сомбреро, такос і це тільки невелика частина тієї шаленої мексиканської фієсти.

Global Mediator

Для новорічної вечірки компанія обрала тему Space & Galaxy, а вся команда перетворилась на астронавтів, прибульців далеких планет та улюблених героїв фільмів на космічну тематику.

Grid Dynamics

Гучно та весело відгриміли новорічні корпоративи в українських офісах Grid Dynamics. У Львові вечірка пройшла у форматі гри «Що? Де? Коли?», також у програмі було шоу з танцями та конкурсами. Харків’яни повеселилися на спеціальному вечірньому ток-шоу, а у київському офісі відбулась вечірка у етностилі. У всіх локаціях відбулось урочисте нагорождення переможців щорічної премії RockStar Award.





G5 Games

Команди офісів G5 Games святкували новорічні корпоративи у різних тематиках. У Харкові була діджиталізована казкова вечірка з насиченою шоу-програмою та виступом кавер-гурту. А Львів обрав для себе яскраву вечірку з ламповою атмосферою та грою у більярд.




Honeycomb Software

Колектив львівського офісу компанії зустрічав новий рік у ресторані «PatyFon», а уРівному — в стилі героїв фільмів Тарантіно у ресторані «Географія».




HYS Enterprise

Компанія провела різдвяну вечірку за мотивами фільму MIB. Вечір із живою музикою, конкурсами, нагородженнями і можливістю відчути себе справжніми спец агентами, від яких залежить існування планети.

Infopulse

Цього року спеціалісти компанії стали глядачами Infopulse Night Show, яке відбулося в Києві (була організована пряма трансляція в інші міста). Глядачі дізнавалися про досягнення компанії за останні роки, раділи за здобутки колег та стали свідками зародження нової стратегії розвитку компанії. Після офіційної частини всі поринули у розваги та відпочинок: басейн із кульками, аркадні автомати, аерохокей, настільний футбол, баскетбол, 25-метровафотозона-розмальовка, зони PlayStation та запальні танці під dj-set Дар’ї Коломієць.







Inoxoft

Новорічний корпоратив компанія Inoxoft відсвяткувала в стилі справжнього детективного квесту. Свято традиційно почалось з підсумкового Yearly Digest , продовжилось конкурсами і завершилось запальними танцями та караоке!

Компанія розважилася на Synergy Party. Відзначали цінності компанії, грали на хангу, влаштовували дегустацію вин та танцювальні батли. Закінчили вечір кольоровим метафаном та запальною танцювальною вечіркою.

InternetDevels

Вечірка відбулася в стилі «Зоряні війни». На корпоративі було посвячення в Джедаї та Падавани.

Itera

Влаштували тематичну кіновечірку — Light, Camera, Party! Гості перевтілились в улюблених кіноперсонажів та приміряли образи кіноакторів. Протягом вечора відзначили найкращих, потанцювали під оскароносні саундреки та відчули себе кінозірками. Кульмінацією вечора став традиційний святковий торт та розіграш призів.

Itera Research

Компанія відсвяткувала Новий рік і 15 років компанії одночасно. Свято для всієї команди вийшло яскраве і дуже емоційне, влаштували безліч конкурсів, отримали подарунки, заспівали сотню пісень в караоке. Нас прийшли привітати друзі та партнери з інших компаній, панувала атмосфера святкування у великій дружній сім’ї!

Jelvix

JustAnswer

Влаштували запальну дискотеку в стилі 90х.

Kevuru Games

Напередодні Нового року Kevuru Games та Mangosoft провели вечірку у стилi «Hollywood Stars», щоб відсвяткувати завершення 2019 року разом. Під час вечірки провели церемонію нагородження найактивніших співробітників подарунками, познайомили усіх ближче через квест «ТОП-3 таємниці твого колеги» та вiдiрвались на танцполі.

Leobit

Провели новорічний корпоратив у стилі костюмованої вечірки «Герої та Лиходії». Окрім конкурсів, танців та розваг відбулось нагородження працівників року.

Levi9

Голосно відсвяткували новорічні вечірки: Київ гуляв у стилі голандського хаус-фестивалю Sensation White, а Львів твістив на яскравій рокабільній вечірці.




Light IT

Помічник Паспарту, старець Фура, тигри та золото — цього року компанія святкувала Новий рік у стилі популярної телегри «Fort Boyard».

Maklai

26 грудня ровели світський коропоратив, шармом якого стали вечірні образи IT-інтелігенції. Програму було розписано під кожну команду. Спостерігаючи за атмосферою, було видно, що зусилля не залишились марними. Вишукані страви, тематичні фотозони, витончений інтер’єр та багато веселощів від ведучого зробили вечір незабутнім. Усі отримали заряд позитиву на цілий рік вперед і навіть більше.

Mobilunity

Проводжали 2019 рік як трушні рокери: на байку, в крутих луках та з дебютним лайвом від Mobilunity Band. Разом згадали визначні події року, грали в квізи, переглянули відеопривітання від клієнтів, танцювали і обіймалися з тими клієнтами, які завітали до нас, та на повну використали можливість провести час у колі колег.

Netcracker

2020 рік сумський офіс компанії Netcracker зустрічав у стилі американського серіалу «Friends».

Київський офіс влаштував не схожу на традиційні вечірки — BBQ party. Все відбувалося просто неба у внутрішньому дворі бізнес-центру. Атмосфера в стилі х’юге: розмістили багато теплого світла від гірлянд та фінських свічок по периметру майданчику, оформили яскраву фотозону з фьорками, спостерігали за фантастичним кріо-шоу, створили лого Netcracker за допомогою стрінг-арту. А святковому настрою сприяли смачне барбекю-меню з гарячим глінтвейном під музику, яка лунала з велетенського Хамера посеред майданчика. Також у грудні провели традиційний обмін подарунками «Secret Santa» та присвятили цей місяць благодійності — зробили день донора, закупили речі у дитячий будинок та зібрали ліки у притулок безхатніх тварин.

Новорічні святкування в одеському офісі розпочались з гри обміну подарунками «Secret Santa». А вже наступного дня відбулась основна святкова подія цієї зими — корпоратив у клубі True Man Club. Це була вечірка в стилі Ugly Sweater Party з активними та інтелектуальніми конкурсами, запальними танцями та смачними стравами. Була дуже весела атмосфера свята, яку вдалося створити всім разом.





Netpeak Group

Одна з місій компанії — надихнути своєю діяльністю на боротьбу з банальністю, несмаком і дурістю. Саме тому цього року на зимовий корпоратив компанія влаштувала справжнє весілля в стилі 90-хз нареченим і нареченою, церемонією одруження, виступом народного ансамблю, киданням букета і зняттям підв’язки; з холодцем і голубцями, короваєм і святковим тортом. Кажуть, що був навіть Андрій Губін. Це було комічне зображення архаїчного весілля, в якому взяло участь понад п’ятсот людей з України, Болгарії, Росії та Казахстану.

Newxel

Відсвяткували новорічну вечірку в сучасному заміському комплексі, в атмосфері тепла й затишку. Яскравим елементом розважальної програми та однією з родзинок свята став виступ відомого кавер гурту Chica-Band. Бармен-шоу зі складними трюками та авторськими коктейлями, подарували незабутні емоції, і запальний настрій усім присутнім!

OpenGeeksLab

У компанії влаштували новорічну барбекю-паті з конкурсами, танцями та караоке. До кожного гіка завітав таємний Санта з подарунком.

PioGroup

«Неону забагато не буває!» — під таким девізом зустрічала Новий рік компанія PioGroup Software. Сліпучо яскраві кольори аксесуарів, тематична драйвова музика, запальні танці та палаючі коктейлі, енергічний ведучий, а також трохи магії від справжнього ілюзіоніста — ніхто не зміг встояти перед святковим настроєм та шаленою новорічною енергією неонової вечірки.

Plarium

Plexteq

Компанія влаштувала Space Party з коктейльним майстер-класом, інтелектуальними іграми та конкурсами від співробітників.

PMLAB

1500 гостей зібрались у КВЦ «Парковий», щоб відсвяткувати новорічний корпоратив. Це була вечірка Family & trust, де кожен охочий міг прийти з близькою людиною. У програмі — паті з Добрим та Поганим Сантою, справжніми ельфами та велетнями-ведмедями для обіймів; геймінг-зона і кінозал, а також сімейні фотозони для найтепліших спогадів. Ведучим свята був Вова Остапчук, а хедлайнером стали запальні та драйвові Hardkiss!

PNN

Компанія зустріла Новій 2020 рік у колі друзів та колег. Обрали «Містера і Міс» вечора, обмінялись подарунками та провели церемонію нагородження за найкумедніше фото.

Poster

Компанія з автоматизації ресторанів Poster підвела підсумки року у художній галереї «Артсвіт» та влаштувала рейв-вечірку у клубі «Модуль» з DJ Vladimir Sivash та Lime Kid. Цього року до новорічного святкування приєдналися і друзі з нового офісу компанії у Мексиці.

Preply

Провели корпоратив для співробітників іспанського та київського офісів компанії в Art Prichal. Вечірка почалася з обговорення результатів 2019 року та виступів кофаундерів компанії й барселонської команди. Потім в Preply перейшли до святкування, уроків сальси та конкурсу фотографій з хештегом # 2020PreplyNYparty.

Provectus

Цьогорічна тематика корпоративу була присвячена космосу. На вечірці «No rules in space» ми згенерували колосальну космічну енергію, на якій збираємось летіти весь 2020 на зустріч зіркам!

Rails Reactor

Ідея вечірки в космічному неоновому стилі — це відображення взаємодії у Всесвіті. Напої у стилі брендів компанії, неоновий мейк, відповідний музичний супровід. Бо кожна людина — це цілий Всесвіт!

RiverSoft

Roobykon Software

Roobykon Software зустрічав 2020 рік у файному ресторані у стилі панк. Та традіційно з Таємним Сантою та душевними подарунками, у программі були танці з зайцями, новорічні співанки, які завершились святковими мандаринами з шампанським.

RubyGarage

Підбили підсумки року та влаштували запальну вечірку із виступом рок-групи і яскравою фотозоною.

SBTech

Цього року український офіс SBTech відсвяткував Новий рік під гаслом «Home NOT Alone». Нагороджували найкращих співробітників, танцювали, дуріли, дарували Iphone 11, PlayStation PRO + VR bundle і дякували один одному за підтримку у році, що минає.

Scalarr

Ця новорічна вечірка була присвячена солодким спогадам з дитинства. Команда ділилась веселими спогадами та розповідала про свої дитячі мрії. У цей казковий вечір до компанії завітало чимало персонажів! Що чекати у наступному році від Scalarr, залишається тільки здогадуватись, але ми обов’язково будемо тримати вас в курсі.

Skelia

Новорічні вечірки відбулись у львівському та київському офісах Skelia. Команда Львова поринула у 20-тіроки минулого століття, куди усіх магічно переніс новорічний експрес. Вечірка пройшла у ретро-стилі з традиційним для того часу аукціоном та під ритми запального чарльстону. Команда Києва брала участь у кулінарному майстер-класі у професійній кулінарній школі Євгена Чернухи. Учасники мали змогу повправлятися у приготуванні стейків та деяких страв з італійської кухні у веселій та святковій атмосфері.




Sigma Software

Офіси компанії так зросли, що було вирішено вперше святкувати новорічні свята по своїх містах. Щоб бути ближче один до одного, на вечірці організували телеміст, і всі змогли привітати колег зі своїх команд. Темою вечірки обрали загадку та містерію, так і назвали: Sigma Secret Night. Атрибутами свята стали загадкові маски та вишукане вбрання. Всі розважалися фокусами, проходили квести, поринали в віртуальну реальність, танцювали та співали.






Sirin Software

Провели корпоратив в креативному просторі iZONE, граючи на етнічних барабанах. Після заряджаючого Drum Circle були командні змагання і вікторини та нагородження найкращих співробітників «Оскарами».

Sitecore

Цього року нам вдалося вiдтворити справжнiй знiмальний майданчик. Завдяки цьому працiвники мали змогу прийняти участь в популярних телевiзiйних шоу та вiдчути на собi справжнє свiтло яскравих софiтiв.

Softengi

SoftServe

Компанія цьогоріч мала корпоративи у всіх семи українських розробницьких центрах. Однак не 7, а значно більше. У Львові, де працює понад 3000 працівників, не було єдиного свята через відсутність локації, яка б могла вмістити аж таку велику компанію :) Тому тут софтсервівці мали цілий фестиваль командних корпоративів упродовж грудня. Київський офіс запалював неоновими кольорами на вечірці Light IT up, яку відвідали понад 650 людей. У Дніпрі наповну відривались під ритми диско, та хіти 80-хта 90-х.Танцювали та веселились у одному знайбільших розробницьких центрів компанії до упаду. Івано-Франківська «80 vs 90s Party» відбулася в стилі американської вечірки: яскраві образи та музика тогочасних хітів. Новорічна вечірка чернівецького офісу «You Rock Party» поєднала виступ рок-гурту, яскраві вогняні спецефекти, виїзну тату-студію, установку для зйомки відео-роликів у форматі 360°, бармен-шоу, запальні конкурси на рок-тематику та нестримні танці під рок-хіти. У рівненському офісі влаштували #SoftServe Hero Party — колеги справді підготувалися і вразили одне одного класними образами та костюмами. Харківський офіс опинився за межами нашого всесвіту на вечірці The Other Side, яку відвідали понад 460 людей.









Software Development Hub

Команда влаштувала фотосесію у харківському офісі, до якої також приєдналися розробники з Луцька. Вдвічі збільшилася кількість подарунків від Таємного Санти, оскільки за рік компанія виросла в два рази. Святкування продовжилися у затишному кафе.

Sombra

Компанія провела корпоратив в стилі рок вечірки: Let’s Sombra Rock. На вечірці для створення досконалого рок образу діяла майстерня тимчасових татуювань та зачісок. На святі відбулося традиційне нагородження працівників за підсумками голосування колективу та менеджменту. Окрім рок-гурта на сцені виступив дует — співробітники компанії Вадим і Катя, котрі підготували особливу пісню для Sombra.

SPD-Ukraine

Якісно працює та від душі відпочиває команда SPD-Ukraine. Відгриміли зимові святкування команд — SPD-Awards та feel free party.

S-PRO

Провели новорічну вечірку в стилі Hip-Hop, запросили кавер-бенд і танцюристів breakdance, а потім і самі влаштували танцювальні та пісенні батли.

Sparkybit

У Днiпрi провели спільну святкову вечерю. Родзинкою вечора стала активність «Таємний Санта» з дитячими фотографіями всіх учасників. Крім подарунків від «Санти», всi отримали унікальні брендовані худі та екосумки. Колеги в Харкові відзначили зимовi свята разом з родинами за містом, з басейном і барбекю.




Synebo

Влаштували костюмований корпоратив у стилі «Стёб/Art/Rock’n’roll», провели різноманітні конкурси, розіграли багато призів, а також відзначили робітників, які найкраще втілили в своїх костюмах стиль вечірки.

TATEEDA

TBWA\MOBILE

Харківськi пірати TBWA\MOBILE провели новорiчну вечiрку у стилi Рок-Метал-Патi. Зустрічали гостей рарiтетнимі платiвками, гучнимі акордами, набивали дранк-тату та спiвали разом iз кавер-бендом.

Technorely

Компанія провела передноворічну вечірку в стилі ComiCon. Капітан Марвел, Жінка-Кішка, Багряна Відьма, Маліфісента, граф Дракула, Герміона та професор Квірелл з «Гаррі Потера», Ельза з «Крижаного Серця», Пікачу — і це ще далеко не всі гості вечірки. Програма ComiCon’у була досить різноманітною, і кожен із гостей знайшов собі розвагу до смаку: Міні Маус та Пікачу «запалювали» у танцювальних конкурсах, Капітан Марвел співала у караоке, Джесіка Ребіт занурювалась у віртуальну реальність в VR-зоні. У фіналі вечірки був обраний переможець конкурсу «Кращий костюм», якому вручили особливий зігріваючий подарунок. А усі інші гості вечірки отримали новорічні подарунки від компанії.

Terrasoft

До різдвяних та новорічних свят влаштували благодійну акцію: співробітники виставляли лоти — послуги чи handmade-товари, а 20 грудня їх розпродавали на благодійному ярмарку в офісі. Зібрану суму компанія подвоїла та передала у БФ «Tabletochki». Надвечір на терасі офісу відбулась розважальна частина ярмарку: з ді-джеєм, грилем та глінтвейном.

Virtuace

Новорічний корпоратив пройшов в стилі епатаж на врученні премії Греммі. Магія вечора була в тому, що самі співробітники з чотирьох офісів (Київ, Рівне, Житомир, Харків) активно брали участь у його підготовці. Кожна команда заздалегідь зняла кліп. У когось вийшла найкраща пісня, у когось найкращий ремейк, у когось найкраще рок-виконання. Жанри не повторювались. Команди отримали статуетки Греммі, кожна у своїй номінації. Після церемонії вручення був концерт із запрошеною акторкою у ролі леді Гаги, торт і гран-прі, який був вручений команді, котра отримала найбільшу кількість голосів від гостей. Головним призом були окуляри віртуальної реальності. Після отримання головного приза була дискотека та працювало 5 станцій віртуальної реальності, щоб всі мали зогу ознайомитися з такою «іграшкою».





Waverley Software

Холодної зимової ночі команда Waverley Software перетворилася на справжній циганський табір: ромале майоріли квітчастими спідницями і барвистими сорочками, дзвеніли намистом, танцювали з ведмедем під звуки бубна, золотили руку ворожці, співали заморських пісень і крали золото.

WorkNest

Цьогорічний передноворічний корпоратив компанія провела в тематиці TV-show. Активні конкурси та круті танцювальні батли в суміші з корпоративними комфортними худі, що підсилили сімейну теплу атмосферу, залишили по собі незабутні емоції та приємні спогади в серці кожного співробітника.

Ubisoft

Ubisoft Kyiv та Ubisoft Odesa відсвяткували Новий рік на запальній вечірці в стилі Диско.

UKEESS Software House

Компанія влаштувала вечірку із запальними танцями, конкурсами і паперовим шоу. Родзинкою вечора став привітальний виступ хорової капели «Дударик».

UNIT

Проовели корпоратив у форматі: Супергерої VS Офісний десант. Весь вечір колеги в улюблених образах змагалися з тими, хто прийшов в костюмі айтішніка. Було дуже креативно і весело!

Uptech

Відсвяткували новорічний корпоратив в домашній атмосфері з настільними іграми та Secret Santa.

Uvoteam

Новорічна вечірка пройшла в стилі казино. Професійні круп’є запропонували співробітникам зіграти в покер, рулетку, Black Jack. Фотобудка з моментальними фото, бармени зі смачними коктейлями та гра в «Мафію» чудово доповнили основну тематику свята.

Yael Acceptic

Співробітники компанії поринули в атмосферу гумору та невимушеності: кожен мав змогу впливати на програму вечірки.

YouScan

Відсвяткували Новий Рік у Буковелі: три дні катались і відпочивали разом. А на святковій вечірці в стилі Crazy hair/Crazy hat була синя борода, малинове волосся і багато кумедних головних уборів.

Yukon Software


CI/CD для фронтенда: обзор инструментов и практик для автоматизации разработки

$
0
0

Меня зовут Тит Коваленко. Уже почти 6 лет я занимаюсь фронтенд-разработкой, а сейчас работаю со стеком React & TypeScript & Apollo. Вы можете спросить: «Ты ведь не девопс, почему же собираешься рассказывать о CI/CD?» Отвечаю: потому что эта статья в первую очередь ориентирована на других фронтенд-разработчиков, а не девопсов. Но я буду рад прочесть корректировки и комментарии от девопсов, потому что именно общение с ними позволяет лучше разобраться в теме и в итоге получить еще более совершенную систему.

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

Мне кажется, это хорошая идея — разобраться, как ваше приложение будет автоматически собираться и деплоиться. Тем более сейчас (на самом деле всегда) тренд на T-shaped people — спецов в своей области, которые немного разбираются в смежных.

Что такое CI/CD

Для начала небольшой ликбез. CI/CD расшифровывается как Continuous Integration и Continuous Delivery aka Deployment — то есть непрерывная интеграция и непрерывная доставка. Зачем это нужно?

Чаще всего конечная цель разработки — приложение. Чтобы им пользоваться, люди должны получить к нему доступ: либо скачать из стора и установит. Если это сайт — вбить в адресную строку URL и открыть страничку. Чтобы мобильное приложение попало в стор, его нужно туда загрузить. В случае с сайтами нужно загрузить наши HTML/JS/CSS-файлы.

Вроде бы все просто. Но загружать файлы вручную как минимум неудобно:

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

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

Голубая петля, CI, — это то, что мы делаем после того, как доработали новый функционал, и перед тем, как он пойдет в деплой, чтобы стать доступным пользователям.

Что входит в CI

  • линтеры;
  • тесты;
  • подготовка продакшен-билда.

Линтеры

Зачем

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

Как

  • ESLlint — де-факто стандартный линтер для JavaScript.
  • TSLint — был основным линтером для TypeScript, однако разработчики отказываютсяот его поддержки в пользу ESLint.
  • Prettier — не совсем линтер, скорее, форматтер, который следит за единой стилистикой кода; без проблем интегрируется с ESLint и TSLint.
  • stylelint — линтер для CSS и самых популярных его диалектов (SASS, LESS), для которых у него есть плагины.

Тесты

Зачем

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

Как

  • Jest, Mocha, Jasmine — фреймворки для организации и запуска тестов; в последнее время наиболее популярен Jest, так как он идет из коробки с Create React App.
  • Testing Library, Enzyme — утилиты, в первую очередь нацеленные на тестирование веб-приложений (рендеринг, симуляция кликов и т. п.).
  • selenium-webdriver, Cypress — инструменты для тестирования end-to-end, то есть когда будет действительно запускаться браузер и туда будут отправляться команды, эмулирующие действия пользователя (клики, нажатия клавиш и т. п.).

Подготовка продакшен-сборки

Что и зачем

Сборка — это преобразование исходных файлов так, чтобы их можно было раздавать сервером как веб-сайт (то есть как набор HTML-/JS-/CSS-файлов, которые понимает браузер), публиковать в менеджере пакетов (если вы пишете библиотеку, фреймворк или утилиту), использовать как расширения для браузера, приложение на Electronи др.

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

Условно продакшен-сборка состоит из таких процессов:

  • Разрешение импортов. Браузеры начали понимать модульность только недавно, и то до сих пор не все. Необходимо разобраться, в каком порядке запускать скрипты и как передавать результаты их исполнения другим скриптам.
  • Минификация и обфускация. Собранный код весит меньше, чем исходники, и его сложнее анализировать. Этим мы усложняем реверс-инжиниринг.
  • Вшивание переменных окружения. Одно и то же приложение может работать в разных средах. Простейший пример — на тестовом сервере и на продакшене: в этом случае необходимо сбилдить приложения два раза, один раз — когда в окружении задан адрес апи тестового сервера, второй раз — продакшен-сервера.

Как

  • webpack, Parcel, Rollup, SystemJS, gulp, Grunt — основные сборщики приложений, которые решают большинство упомянутых задач.
  • Dotenv, dotenv-cli — npm-пакеты, которые упрощают работу с переменными окружения, особенно при разработке.

Дополнительно

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

Храните этот файл таким образом, чтобы он был легко доступен рядом с веб-приложением. Например, по адресу: https://your-site.com/version.json.

Такое простое действие поможет вам и другим членам команды (в первую очередь тестировщикам) быстро определять версию приложения, которая запущена в данном окружении, и отслеживать деплои.

Итог. Npm Scripts

Все эти процессы — это integration из CI, но пока что не очень continuous. Чтобы их автоматизировать, необходимо потратить время (один раз) и сконфигурировать их так, чтобы они запускались одной командой в командной строке.

Для этого отлично подходят npm-скрипты. В итоге все 3 предыдущих процесса можно свести к запуску трех команд, который будет похож на что-то вроде:

npm run lint
npm run test
npm run build

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

Бонус. Git Hooks

Зачем

Чтобы не забывать запускать линтеры и тесты. Их запуск можно автоматизировать с помощью Git Hooks, то есть линтеры и тесты будут запускаться, например, перед каждым коммитом.

Как

  • Husky — позволяет привязывать npm-скрипты к Git Hooks внутри package.json.
  • lint-staged — позволяет запускать линтеры только для тех файлов, которые подготовлены для коммита.

Что входит в CD

  • версионирование и релиз;
  • деплоймент.

Версионирование и релиз

Зачем

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

  1. Маркеры стабильных ревизий. Упрощают поиск последней стабильной ревизии при необходимости откатить версию приложения (если, например, критический баг попал в продакшен).
  2. Именования для коммуникации. У вас появляется возможность обсуждать заливки, не называя их «то, где мы добавили профиль» или «то, где мы пофиксили регистрацию», а используя номера версий — емкие и однозначные, писать более точные ченжлоги, более эффективно исследовать и воспроизводить баги.

Как

  • Semantic Versioning — методология для формирования номера версии. Одна из многих, но именно эта используется для версионирования npm-пакетов (ее удобно совмещать с версией в package.json).
  • Npm version, yarn version — команды, которые увеличивают версию вашего приложения. Они автоматически меняют версию в package.json, делают коммит с соответствующим сообщением и ставят тег, в котором будет имя новой версии.

Деплоймент

Деплоймент — это доставка и выгрузка файлов в место, откуда они будут раздаваться. То, как происходит деплой в значительной мере зависит от того, как именно хостится ваше приложение. Это может быть один из многих вариантов, например: AWS S3 Bucket / AWS CloudFront / другой сервис AWS, коих множество, Heroku/Dokku, VPS/VPH.

Зачем

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

Как

Деплоймент — это просто выгрузка файлов на другой сервер. Разница лишь в протоколе, по которому она будет происходить:

  • SSH — с некоторыми оговорками можно представить как пуш в некий удаленный (в смысле находящийся далеко) репозиторий.
  • HTTP — простой и знакомый фронтендерам способ, когда каждый файл отправляется в теле соответствующего HTTP-запроса.
  • FTP — самый старый из перечисленных протоколов, для которого можно найти клиент на Node.js, но, возможно, придется попотеть, настраивая его.

Операция выгрузки файлов может быть свернута до единого npm script, который будет запускать файл Node.js. Большинство API работают на Node.js (к примеру AWS).

Итог

По аналогии с CI мы получим несколько простых npm-скриптов, которые позволят запускать более сложные и ответственные процессы.

Пайплайны

Если переводить слово pipeline с английского в контексте computer science, одним из переводов будет «конвейер». И это слово хорошо описывает ситуацию.

Зачем

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

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

Именно здесь вступают в дело пайплайны — как инструмент, который описывает и запускает конвейер для процессов CI/CD.

Как

Почти все, что я привел в списке, — это хостинги репозиториев, кроме Jenkins’а (который я добавил для полноты картины, чтобы было ясно, что такие инструменты не обязательно являются частью хостинга репозиториев).

Далее я приведу несколько примеров, как это выглядит в GitLab Pipelines. Для примеров я взял именно GitLab по нескольким причинам. У меня есть опыт плотной работы с этим сервисом. Бесплатный аккаунт на GitLab предоставляет хороший пакет, связанный с пайплайнами, которого с головой хватит, чтобы потренироваться на пет-проекте. То же относится к standalone GitLab-серверу. Также он дает общее понимание, как настраиваются пайплайны. Лично мне было нетрудно по аналогии с GitLab разобраться с тем, что предлагали Bitbucket Pipelines.

GitLab CI/CD

Как это выглядит. Для каждого запушенного коммита запускается пайплайн. Ниже можно увидеть список пайплайнов, которые запускались для разных коммитов.

Рис. 1. Успешно завершенные пайплайны

Пайплайн состоит из шагов (steps). Степы, в свою очередь, состоят из задач (jobs). Ниже можно увидеть развернутую структуру пайплайна. Колонки Setup, Code_quality и далее — это steps. Каждый блок с зеленой иконкой — это отдельная job.

Рис. 2. Декомпозиция пайплайна

Если одна из джоб падает, пайплайн останавливается. В этот момент ясно видна выгода от связки хостинг-репозитория и пайплайна: если для последнего коммита в мерж-реквесте упал пайплайн, смержить такой реквест не удастся. Это не допустит попадания в стабильные ветки кода, который, например, не проходит проверку линтеров или тестов.

Рис. 3. Пайплайн, завершившийся неудачей, так как линтеры упали

.gitlab-ci.yml

Как это настраивать. Пайплайн описывается в файле .gitlab-ci.yml, который должен лежать в корневой папке репозитория.

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

image: node:8

variables:
 REACT_APP_ENV_NAME: $CI_ENVIRONMENT_NAME

stages:
 - setup
 - code_quality
 - testing
 - semver
 - deployment

Строки 1-11 .gitlab-ci.yaml

image — указывает, в каком докер-контейнере должен запускаться пайплайн. Если очень коротко, докер — это технология, позволяющая получить предсказуемую среду выполнения. В данном случае мы хотим запускаться в условном Linux, на котором установлена 8-яверсия Node.js.

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

stages — описывает очередность выполнения задач. Ставим зависимости, линтим скрипты и стили, потом тестируем, после чего уже можем деплоить. Выглядит это как массив строчных значений, которые используются для маркировки задач. Эти же стадии изображены на рис. 2.

Jobs & Scripts

dependencies:installation:
 stage: setup
 cache:
   paths:
     - node_modules/
 script:
   - yarn --prefer-offline --no-progress --non-interactive --frozen-lockfile
 tags:
   - web-ci

lint:scripts:
 stage: code_quality
 cache:
   paths:
     - node_modules/
 script:
   - yarn run lint:scripts:check --max-warnings 0
 only:
   changes:
     - src/**/*.{ts,tsx}
 tags:
   - web-ci

lint:styles:
 stage: code_quality
 cache:
   paths:
     - node_modules/
 script:
   - yarn run lint:styles:check
 only:
   changes:
     - src/**/*.{css,scss}
 tags:
   - web-ci


unit:testing:
 stage: testing
 cache:
   paths:
     - node_modules/
 only:
   changes:
     - src/**/*.{ts,tsx}
 script:
   - yarn test
 tags:
   - web-ci

Строки 13-60 .gitlab-ci.yaml

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

script — набор команд, которые будут выполнены в процессе работы джобы. Для dependencies installation мы видим, что это всего одна команда — yarn — c аргументами, которые говорят не качать лишнего, если оно есть в кеше.

Подобным образом это работает с линтом скриптов и стилей. Обратите внимание, что и скрипты, и стили привязаны к одному стейджу. Это значит, что по возможности они будут идти параллельно.

onlyи exludeпозволяют определить, когда джоба должна работать, а когда нет. Например, мы видим, что линтинг скриптов происходит только при изменениях в рамках .ts- и .tsx-файлов, CSS- и SCSS-стилей.

Таким же образом можно сделать джобу деплоя доступной только для мастер-ветки.

Версионирование

Версионирование — одна из путающих задач при построении пайплайна. Пайплайн запускается на одном из коммитов, а версионирование само по себе провоцирует создание нового коммита, в котором будет изменена версия package.json и проставлен новый тег. Нам придется запушить в репозиторий из пайплайна и, таким образом, один пайплайн спровоцирует другой пайплайн.

.semver_script: &semver_script
 stage: semver
 when: manual
 only:
   - master
 except:
   refs:
     - /^v\d+\.\d+.\d+$/
 tags:
   - web-ci
 script:
   - mkdir -p ~/.ssh && chmod 700 ~/.ssh
   - ssh-keyscan $CI_SERVER_HOST >> ~/.ssh/known_hosts && chmod 644 ~/.ssh/known_hosts
   - eval $(ssh-agent -s)
   - ssh-add <(echo "$SSH_PRIVATE_KEY")
   - git remote set-url --push origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
   - git config --local --replace-all user.email "noreply@yourmail.com"
   - git config --local --replace-all user.name "Gitlab CI"
   - git checkout $CI_COMMIT_REF_NAME
   - git reset --hard origin/$CI_COMMIT_REF_NAME
   - npm version $SEMVER_LEVEL
   - git push -u origin $CI_COMMIT_REF_NAME --tags

semver:minor:
 <<: *semver_script
 variables:
   SEMVER_LEVEL: minor

semver:patch:
 <<: *semver_script
 variables:
   SEMVER_LEVEL: patch

Строки 62-93 .gitlab-ci.yaml

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

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

Чтобы не копировать этот фрагмент для минорной и патч-версий, здесь используется фича YAML-файлов, которая называется YAML anchor. Благодаря подобным фичам YAML-файлы становятся лучшим форматом для описания конфигураций.

Деплоймент и переменные окружения

Рис. 4. Веб-интерфейс гитлаба для управления окружениями

На рис. 4 показан веб-интерфейс гитлаба для создания и редактирования деплоймент-окружений. После того как они созданы здесь, их можно использовать в .gitlab-ci.yaml.

Ниже приведен фрагмент конфигурации деплоймента на примере выгрузки результатов билда в AWS S3 Bucket. Здесь также использован YAML anchor для исключения дублирования кода.

.deploy_script: &deploy_script
  cache:
    paths:
      - node_modules/
  stage: deployment
  script:
    - yarn run build
    - yarn run deploy
  tags:
    - web-ci

deploy:dev:
  <<: *deploy_script
  variables:
    AWS_S3_HOST_BUCKET_NAME: $AWS_S3_HOST_BUCKET_NAME__DEV
    REACT_APP_API_BASE: $REACT_APP_API_BASE__DEV
  environment:
    name: dev
    url: http://$AWS_S3_HOST_BUCKET_NAME.s3-website.us-east-1.amazonaws.com/
  only:
    - develop


deploy:qa:
  <<: *deploy_script
  when: manual
  variables:
    AWS_S3_HOST_BUCKET_NAME: $AWS_S3_HOST_BUCKET_NAME__QA
    REACT_APP_API_BASE: $REACT_APP_API_BASE__QA
  environment:
    name: qa
    url: http://$AWS_S3_HOST_BUCKET_NAME.s3-website.us-east-1.amazonaws.com/
  only:
    refs:
      - /^v\d+\.\d+.\d+$/
    changes:
      - package.json

Строки 95-131 .gitlab-ci.yaml

Обратите внимание, как используются переменные окружения. Команды yarn run build и yarn run deploy используют имена переменных без постфиксов, которые определяются на уровне конкретной джобы из значений, находящихся в переменных с постфиксами.

Рис. 5. Веб-интерфейс гитлаба для управления переменными окружения

На рис. 5 показан веб-интерфейс, в котором можно описать переменные окружения. Они будут доступны внутри пайплайна, когда он запустится. Тут можно определить адреса апи бэкенда, ключи апи для сервисов, которые вы используете: например, Google API key, SSH-ключи для версионирования и другие данные, коммитить которые небезопасно.

Заключение

Даже при рассмотрении CI/CD в рамках специфики фронтенда обнаруживается много деталей и нюансов. Файл конфигурации пайплайнов из моего примера — рабочий, вы можете использовать его для своих проектов, подставив соответствующие npm- или yarn-скрипты. Надеюсь, эта статья станет отправной точкой для дискуссий и погружения в тему.

iOS дайджест #35: курс по Combine, Redux + SwiftUI, Vapor 4

$
0
0

В выпуске: продолжаем изучать SwiftUI, настраиваем GitHub Actions для Swift-проектов и смотрим видео с конференций.

SwiftUI

SwiftUI
Если вы пропустили все про SwiftUI, то вот неплохое начало.

SwiftUI Is Still the Future
SwiftUI — это уже настоящее или все же будущее?

Integrating SwiftUI with UIKit and Developing Xcode Previews for UIKit’s ViewController
Просмотр отрендеренных SwiftUI вьюх — для меня это прям киллер фича. И ее можно использовать для привычных вью контроллеров.

SwiftUI for Mac
Казалось бы, SwiftUI должен работать одинаково на всех платформах, но под мак различия все же есть.

The power of @ViewBuilder in SwiftUI
Если вы уже во всю используете SwiftUI и вьюшки начинают разрастаться, то стоит посмотреть на @ViewBuilder, чтобы разнести создание и отображение.

SwiftUI Animation
Лонгрид про анимации в SwiftUI. Хоть и непривычно писать, но даже анимации выглядят в итоге элегантней.

Building a Custom App Using SwiftUI
И еще про анимации — делаем подобие breath app на Apple Watch.

Data Driven SwiftUI
Делать вьюшки на SwiftUI это хорошо, но ведь хочется разобраться, как использовать их с данными в реальном приложении.

Redux-like state container in SwiftUI. Basics.
Redux-like state container in SwiftUI. Container Views.
И еще про SwiftUI и Redux.

Общее

Haptrix — Core Haptics Designer
Всего лишь API для вибрации, а ребята сделали приложение, чтобы играть музыку с помощью этого!

What’s New in Vapor 4
Вышел Vapor 4. Ради интереса пошел посмотреть, что там Perfect, а у них последний коммит был 8 мая. Грустненько.

A Crash Course in Combine
У Point Free вышел бесплатный курс по Combine. Видео, текстовая версия, код, вот это все.

Opaque Return Types and The ’Some’ Keyword in Swift
Разбираемся, что за новое ключевое слово some и что такое opaque type в Swift.

Dependency injection with Storyboards and Xcode 11
У сторибордов появилась вторая жизнь? Теперь можно нормально использовать initializer injection.

Testing App Launch Time
Уже много было сказано о том, как оптимизировать время запуска приложения, но что-то я не нигде особо не видел, как делать регрессию для этого. И вот пример как сделать тест с помощью XCTOSSignpostMetric.

Github Actions CI for Swift Projects
Пример того, как настроить Github Actions для iOS проекта.

Discover Side Tables — Weak Reference Management Concept in Swift
Как были устроены слабые ссылки в Swift 4+ и до этого.

On Code Reviews
Код ревью — это не место, чтобы проявить своим эго или унизить коллегу. Это место, где ты помогаешь сделать код твоего коллеги лучше с наилучшими намерениями.

No space left on device: Testing low storage scenarios
А как вы тестируете, что на устройстве нет свободного места?

Quick tip: clearing your app’s launch screen cache on iOS
Ох, помню, как только появились XIB’ы для сплеш скринов и сколько было с этим проблем.

Библиотеки

7 Awesome Open Source SwiftUI Projects To Inspire You
Набор крутых приложений, написанных на SwiftUI.

BetterCodable
Начинаем использовать Property Wrappers полным ходом. Например, чтобы упросить работу с Codable

Gallery App for Harvest
Если просто примеры приложений со SwiftUI надоели, то вот Elm Architecture + SwiftUI.

John Sundell наконец-то опубликовал библиотеку для создания статических сайтов.

Видео

Главное на сегодня: пока все праздники не закончились и еще есть время посмотреть видео с конференций.

MobileOptimized 2019 Minsk

#Pragma Conference 2019

iOSDevCampDC 2019

ServerSide.swift 2019


← Предыдущий выпуск: iOS дайджест #34

Міст до Піднебесної: як український програміст виживав у китайському виші

$
0
0

Мене звати Станіслав Феденко, я здобув ступінь магістра у Китайській Народній Республіці у 2018-муроці, а з 2019-гопрацюю там розробником. У статті розповім про переїзд, навчальний процес і облаштування в незвичному середовищі, бюрократичні процедури, побут і дозвілля в КНР. Сподіваюсь, стаття буде корисною як для тих, хто лише починає свій шлях в ІТ, так і для тих, хто замислюється про переїзд.

Приємного читання!

Status quo

У вересні 2013-гороку я був третьокурсником Сумського державного університету (який, до речі, успішно закінчив у 2017 році). Одного дня, відсидівши дві пари, я традиційно пішов до найближчого буфету, аби купити піцу з ковбасою, як по студентському радіо пролунало оголошення про набір на курси китайської мови. Така радість коштувала триста гривень на місяць, а заняття починалися у жовтні. З моєю схильністю до вивчення мов та повною відсутністю здатності тверезо оцінити навантаження, я пішов «пітчити» новий проєкт до свого головного інвестора. Бабуся завжди підтримувала навіть найсумнівніші мої починання зі словами: «Що вмієш — за плечима не носити». Тож восьмого жовтня у класі Конфуція СумДУ я вимовив своє перше «ні хао».

Мої нові однокласники були, мов ті «Месники»: до другого заняття дійшла лише половина. Уп’ятьох ми пройшли три рівні підготовки з шести і склали іспити HSK2 (письмовий) та HSKK1 (розмовний). Для цього довелося їхати до Харкова, до Університету імені Каразіна, де знаходиться головний офіс інституту Конфуція в Україні. Я складав третій рівень іспитів, тож знати ієрогліфи не мав, достатньо було розуміти піньїн — латинізований запис мандаринських складів. Цей піньїн, до речі, було розроблено для введення піктограм до комп’ютера. Якщо хтось гадав, що китайська клавіатура відрізняється великим розміром, маю розчарувати: це все ще QWERTY. Взагалі четвертий рівень вищезазначеного іспиту дає право навчатися і працювати із застосуванням китайської мови, а все, що нижче, відчутних привілеїв не надає.

Трішки згодом, у тому ж класі, нас поміж іншим сповістили про можливість навчання у магістратурі китайських університетів за підтримки місцевого уряду. Тієї миті я шкодував лише про те, що навчався тільки на третьому курсі.

Рік потому

2 лютого 2015-гороку. Весь потік знає, що я націлився на Піднебесну, хоча не сказати, що я якось поширював цю інформацію. Втім, цікавість виявив лише один мій товариш, незважаючи на те що вступити до китайських вишів простіше, ніж до українських: навіть на бюджет не потрібно складати жодних іспитів, у тому числі і мовних. Тож ми разом з ним зайнялися підготовкою документів. Ми обрали Software Engineering як бажаний напрям підготовки. Він був логічним продовженням спеціальності «Інформаційні та комунікаційні технології», яку ми здобули по завершенні бакалавріату.

Вступна кампанія завершилася 31-гоберезня, а вже на початку квітня нам надійшли електронні листи про успішне одержання наших пакунків: закордонний паспорт з копіями, чотири фотознімки на документи, три (зараз дві) рекомендації від викладачів курсів бакалавріату, план дослідження на 800 слів англійською, диплом та виписка з оцінками, медична довідка китайського зразка.

У липні вищезгаданому колезі надіслали повідомлення про зарахування, а мені — ні. Я почекав ще кілька днів і написав їм сам. Жіночка чемно вибачилась переді мною і відповіла, що конкурс на вказану спеціальність дуже великий. Питати, як так сталося, що мого співвітчизника з нижчим середнім балом зарахували, я не став з етичних міркувань. Пізніше з’ясувалося, що той помилково подався не на ту спеціальність. Ще пізніше я отримав пропозицію пройти той самий курс, Information and Communication Engineering, але замість Нанкіна я мав їхати до Чанчжоу.

Після поверхневого порівняння навчальних планів я зрозумів, що ця спеціальність більше зосереджена на апаратному забезпеченні, а бажана мною — на програмному. Проте ще технікумівська (спеціальність «Обслуговування комп’ютерних систем та мереж») підготовка дозволила мені прийняти цей виклик. Занадто довго я планував цю поїздку, аби зараз відмовитися.

Університет надіслав нам документи, необхідні для подання на студентські візи. Їх ми отримали без проблем.

Ми взяли найдешевші квитки за маршрутом: Київ-Москва-Пекін-Шанхай. Сумарно дорога забрала у нас три дні. Пересадка в Пекіні заслуговує на окрему увагу. На території аеропорту тхнуло забрудненим повітрям (на той момент мені здавалося, що приблизно так пахне низькоякісна китайська їжа) протягом усіх дев’яти годин, що ми там провели. Я пообіцяв собі того дня: якщо така ситуація характерна для всієї країни, то я скористаюся зворотнім квитком з датою у середині січня і більше не повернуся. Побоювання не справдилися, і вже в Шанхаї ми спокійно сіли на швидкісний потяг, що за годину доставив нас до пункту призначення.

Університет

По приїзді до університету Хохай, що недослівно я переклав би як «Університет водного господарства» нас зустріла жіночка середнього віку, що представилася «міс Янг». Вона перевірила всі документи і люб’язно відвела нас до місця дислокації. Побачене нас приємно здивувало: те, що називалося гуртожитком, де-факто було повноцінною двокімнатною квартирою зі спільними вітальнею, вбиральнею та кухнею на двох осіб. Приміщення мебльоване, в наявності бойлер і по кондиціонеру на кожну кімнату, але решту побутової техніки довелося купувати самостійно.

Увечері ми вперше завітали до місцевої їдальні. Працівник з малолітнім сином на колінах смачно потягував цигарку, просто за столом, доки його дружина накладала нам обрані страви. Їжа виглядала незвично. Приклавши кампусну картку до сканера, ми розплатилися і понесли наші таці подалі від палія. На смак тутешня їжа здавалася не менш дивною, ніж на вигляд. Втім, їсти було можна.

З першого по сьоме жовтня у Китаї святкують День заснування КНР, або просто Національний день. Того року на той самий період випало ще й Свято середини осені, коли їдять «місячні тістечка». Тут варто пояснити, що традиційні китайські свята прив’язані до місячного календаря, а тому у григоріанському вони мають плаваючі дати. Таким чином, заняття почалися аж 12-гожовтня. Нам мимоволі довелося перелаштуватися на місцевий лад. Навчальний процес не надто напружував: одна-дві пари до обіду, ще одна — після. І так чотири рази на тиждень. П’ятницю зробили вихідним на прохання мусульманських студентів, які цього дня ходили до мечеті. Тривалість перерви могла перевищувати дві години, тож частенько я дозволяв собі ще й покемарити.

За час навчання ми прослухали наступні курси:

  • методи оптимізації (Optimization Methods);
  • числовий аналіз (Numerical Analysis);
  • обробка цифрових сигналів (Digital Signal Processing);
  • сенсорні мережі (Sensor Networks);
  • програмування мовою MatLab (MatLab Programming).

А також кілька загальноосвітніх дисциплін:

  • китайська мова (Chinese I, II);
  • крос-культура (Cross-culture);
  • представлення Китаю (China Introduction).
*для запобігання непорозумінь наводжу назви предметів двома мовами.

Назви предметів лякали. В лабіринтах аудиторій мені не одразу вдалося знайти потрібну, але на лекцію все ж не спізнився. Там уже чекали одногрупники з Африки та Південної Азії. Дехто дозволив собі прийти вже після мелодії, що замінювала звичний нам дзвоник. Викладач — дорослий дядько-китаєць — доброзичливо привітався і написав своє ім’я на дошці: Джан Бінву; а нижче підписав: Боб. Китайці часто беруть собі англійські імена, щоб представлятися у англомовному середовищі. Одну годину двадцять хвилин потому рука боліла від переписування формул та прикладів з дошки, тому звістка про домашнє завдання цього разу була доброю. Доручення викладачів виконувались колективно, хто на що здавсь. Для складання деяких дисциплін вимагалося лише підготувати презентацію і прочитати доповідь з папірця, що ми успішно і робили.

Я волів би навчатися китайською (з попередньою річною мовною підготовкою), але, на жаль, у нашому кампусі для іноземців були доступні лише англомовні курси.

На щастя, пари тривали лише один рік. Наступні два було виділено під фінальну роботу — такий собі дипломний проєкт. У цей період є два варіанти поведінки: засідати у лабораторії свого коледжу з ранку до ночі — або жити власним життям. Китайських студентів прямо змушують перебувати там з восьмої ранку до десятої вечора. З іноземцями все не так суворо.

П’ятого числа кожного місяця надходила стипендія у розмірі 1700 юанів (~6800 грн) (для магістрів). Програму я проходив університетську. Якщо якимось дивом потрапити на урядову, то можна отримувати всі 3000 юанів (~12000 грн). Для PhD, відповідно, 2000 юанів (8000 грн) і 3600 юанів (~14400 грн). На ті гроші я примудрявся виживати протягом усього першого семестру. Це була саме та «романтика» студентського життя, про яку часто кажуть в Україні. Отримуючи поточне нарахування, я вже знав, на що витрачу наступне. Втім, я не голодував і навіть потроху оновлював свій гардероб.

Трійка переможців університетського конкурсу китайської мови «Chinese bridge»

Складнощі

Одна з головних незручностей для «прибульців» у КНР відома на весь світ. Ім’я їй — «Великий китайський фаєрвол». Google, YouTube, Facebook, Instagram, Twitter, а також ресурси з контентом для дорослих одразу відпали, як яйця від продподатку. Мобільний телефон з операційною системою Android, придбаний не в Китаї, а це саме мій випадок, за функціоналом мало в чому перевершував мою стареньку Nokia 6230i. Російські і українські сайти працювали, але значно повільніше, ніж я звик. Більше того, швидкість корелювала з часом доби. Наприклад, якщо встати о шостій ранку, то можна було дивитися серіали прямо в режимі онлайн. За таких умов відбувалося моє знайомство з «Джесікою Джонс», що тільки-но вийшла тієї осені. Протягом дня відеоконтент потрібно було завантажувати трішки наперед, а після п’ятої вечора навіть текстові сторінки могли відмовляти. Безкоштовні VPN-застосунки давали доступ, але не швидкість.

Серце обливалося кров’ю, але за збереження психічного здоров’я довелося платити. Першим короткостроковим рішенням була програма для VPN «Kepard». Ціна не вельми кусалася, та й підписка була усього на три місяці. Серверів багато, але іноді доводилося витрачати по кілька хвилин на те, щоб знайти один дієвий. Та й питання з розподілом швидкості протягом дня вона не вирішувала. Втім, перебирати я не міг.

Перші зимові канікули стали найсумнішим періодом за весь час мого перебування на чужині і найдовшим з таких за все моє життя. Сусіди роз’їхалися по домівках святкувати китайський новий рік, перетворивши Чанчжоу на місто-привид. Температура зрідка опускалася нижче нуля, але пронизливі вітри змушували сумувати за українськими морозами. В кімнаті було ще гірше: ми заощаджували як могли, але ліміт на електроенергію все одно вичерпався, і довелося доплачувати з власної кишені. Я вмикав кондиціонер на кілька хвилин, аби прогріти приміщення, а потім вимикав. Утім, алюмінієві вікна швидко виводили все тепло на вулицю. Особливо смішно було слухати скиглення африканців про те, що кондиціонер не рятує від холоду вночі. Я вночі його навіть не вмикав. До того ж, у той період у мене з’явилася купа вільного часу. На тлі всього вищесказаного, мене охопила ностальгія: почав дивитися «Баффі», а перед сном мріяв прогулятися «Сотнею» (народна назва вулиці Соборної у Сумах). У такому хаосі минали мої дні, а ночами я сідав за іспити і курсові для рідного «політеха». Так, забув сказати: я навчався у двох університетах одночасно. Це на той випадок, якщо мій екзотичний диплом не матиме ваги в Україні.

У 2016-муНовий рік припав на 8-мелютого. Я щиро сподівався розвіяти журбу, відвідавши традиційні заходи. Ну, знаєте, танці драконів, феєрверки... Цього всього не було. Тут це свято зустрічають у родинному колі, за столом і з «Блакитним вогником» по телевізору. Проте одна китаянка, студентка нашого університету, запросила мене до Нанкіна — її рідного міста і столиці нашої провінції.

У «південній столиці» було людно. Дівчина повела мене на вулицю з традиційними будівлями і червоними ліхтарями (не ту, про яку ви подумали). Перед храмом Конфуція човни з драконячими головами плавали вздовж річки, а з неба їх вітали салюти.

Канал поблизу храму Конфуція у Китайський новий рік, м. Нанкін

Третій початок

У березні життя заграло по-новому. Мій сусід зробив собі портфоліо і почав підробляти моделлю, що швидко покращило його матеріальне становище. Знайти таку роботу взагалі не важко, якщо ви є щасливим власником обличчя європеоїдного типу. Я вже і собі почав розмірковувати про власну модельну карту (аналог портфоліо) і пошуки коштів на фотосесію, як нагода сама мене знайшла. На одному з університетських заходів я зустрів випускника, що був вражений моєю вимовою та запропонував мені її монетизувати. З того часу якість мого життя стала стрімко зростати.

Виконання китайського народного танцю на новорічному концерті у центральному кампусі університету «Хохай»

Наші співвітчизники переважно працюють вчителями англійської мови, моделями, танцівниками. Проте офіційно працевлаштовані одиниці. Час від часу чую новини про те, що нашого брата десь упіймали за нелегальною роботою. Зважаючи на це, у 2018-муукраїнцям значно ускладнили процедуру отримання бізнес-віз. Таким чином залишилися варіанти з туристичною, студентською та, власне, робочою візами.

Працювати під час навчання, звісно, також не дозволено. Винятком може стати виробнича практика (Internship). Декому навіть вдається оформити викладання англійської як практику і підпрацьовувати легально. Але, як правило, цього не трапляється, і тоді студенти йдуть на ризик. Несподівана перевірка може закінчитися депортацією.

Що мені подобалося у моєму соціальному становищі, то це те, що й британці, й американці, й німці, й французи — всі приймали мене за свого. Тут ти або місцевий, або «лаовай». Китайці — ті взагалі шукали нагоди зі мною познайомитися, завести дружбу, попрактикувати англійську. Часто запрошували на обід чи вечерю. Я пропонував розділяти витрати, але вони відмовлялися.

Разом з тим, як покращувалося матеріальне становище, з’являлися і нагоди інколи виїжджати за межі міста. Допомагало ще й те, що я сам визначав власний графік роботи, головне — завчасно його затвердити.

Шанхай я одразу вподобав. І досі люблю гуляти його просторими вулицями, де класична китайська архітектура поєднується з європейськими будівлями початку ХХ століття та сучасними скляними офісами. Було цікаво дивитися на місто з висоти Східної Перлини — символу Шанхая, а потім вже на саму Перлину з новозведеної Шанхайської вежі. Попри те що араби вже перевершили висоту цього хмарочоса, його оглядовий майданчик все ще лишається найвищим у світі.


data-caption=На тлі «Забороненого міста», м. Пекін«>



Найбільша незручність, як на мене, — це розташування міжнародного аеропорту «Пудун», з якого мені завжди доводиться літати додому. Він знаходиться аж на березі моря. Таким чином, мені спочатку потрібно проїхати годину потягом з Чанчжоу, а потім ще півтори години на метро з «Хунцяо» до «Пудун». Альтернативний варіант — вийти на станції Longyang Road і сісти на Maglev (залізнична лінія на магнітній підвісці). Такий хід зменшить час поїздки вдвічі. Вартість квитка — 50 юаней (~200 грн).

Наступного разу було заплановано подорож на північ країни: Пекін — Хух-Хото — Сіань. Хоча Велика китайська стіна, Теракотове військо та решта історичних пам’яток — це дуже цікаво, загальний мій висновок такий, що північніше річки Янцзи мешкати мені не хотілося б. Загалом там набагато більше старих і недоглянутих будівель, на диво, інші порядки користування громадським транспортом і, загалом, відчувається відбиток комуністичного минулого.

Щоб бути справедливим, у столиці є і сучасний район: з хмарочосами, нічними вогнями і рештою ознак міста XXI сторіччя. А також є олімпійське містечко, зведене спеціально до Олімпіади 2008-гороку. Мені навіть пощастило переглянути матч улюбленої футбольної команди у «Пташиному гнізді». Її розклад літнього турне вдало збігся з моєю поїздкою.

Набагато кращими були мої враження після відвідин провінції Сичуань. У Ченду мені довелося жити у новому районі, розбудова якого якраз тривала. Апартаменти, знайдені на Airb’n’b, приємно вражали і прикрашали моє перебування у місті. Щоранку я виходив з дому, чимчикував близько п’яти хвилин до станції метро, з якої вже вільно їхав, куди було потрібно. Там я відвідав: будівлю, у якій ще за часів династій Тан мешкав поет Ду Фу; Храм зеленого барана — перший даоський храм на моїй пам’яті; кілька парків. А потім почав дослідження околиць міста: Дуцзяньянь — іригаційної системи і єдиної пам’ятки ЮНЕСКО, що досі функціонує; статуї Будди в Лешані, викарбуваної у скелі на березі річки, а разом з нею — і «Міста 10 тисяч Будд», про яке мало що можна знайти в інтернеті; а також «Золотої вершини» на горі Емей. На останню довелося витратити цілих два дні замість запланованого одного. Я сходив на неї сім годин, заночував у буддійському монастирі, а потім витратив ще п’ять годин наступного дня. Через це я так і не відвідав найбільшу будівлю у світі, повз яку проходив щодня, прямуючи до метро.




Сусідній населений пункт Чунцін, до речі, найбільший у світі, мені також дуже сподобався. Про себе я нарік його «3D-містом», через те що воно знаходиться на горах і пагорбах і своїм візуалом інколи ламає мозок. Наприклад, одного разу я побачив на даху двоповерхової будівлі традиційну альтанку і піднявся сходами. Коли ж я дістався іншого краю, то дивився на дрібні автівки вже з висоти десятого поверху.

Або відома принада для туристів — Hongya Cave. Я б охарактеризував це місце як багатоярусний ринок. Ти спускаєшся сходами чи ліфтом все нижче і нижче, і все одно залишаєшся під відкритим небом.

Випускний

Захист диплома, орієнтовно, мав відбутися у травні. У березні я перейшов до активної фази написання так званої «тези» — пояснювальної записки до дипломної роботи. До цього я мав певні напрацювання за моїм проєктом, «Розробка системи розпізнавання облич із застосуванням гістограм направлених градієнтів», але з того моменту наді мною став висіти мій керівник, і довелося дуже швидко скуйовдити робочий прототип. Цей «монстр Франкенштейна» навіть працював, але, як з’ясувалося, то було не найбільшою моєю проблемою.

Першою перепоною на шляху до успіху стали відомі багатьом вимоги до мінімальної кількості сторінок та списку джерел інформації. За ними слідували правила оформлення. Цим українського студента я також не здивую. Потім згадалися три книжечки, що видавалися нам ще на першому році навчання, і на них я зупинюся детальніше.

Перша з них була призначена для лекцій, що не входили до основного навчального плану. До нас інколи приїздили викладачі з інших університетів, в тому числі й іноземних, для одноразових виступів. Були й німці, й американці, навіть один китайський емігрант, що викладає у США. Але, на жаль, більшість гостей таки читала китайською мовою. Я відсидів такий захід заради заповітного підпису.

Друга була абсолютно безкорисною бюрократичною знахідкою, адже там я скорочено дублював ту інформацію, яку надав у основному тексті диплому, а також вкотре заповнив анкету, аналогічну десятку інших.

Сенс третьої мені ніхто не міг пояснити аж до останнього моменту. Я питав у нашої міс Янг, і вона посилала мене до супервайзера. Питав у того, а він вказував у зворотному напрямку. Врешті-решт я дізнався, що той журнал призначався для семінарів, про які, на відміну від вищезгаданих лекцій, нам ніхто не повідомляв. Воно й зрозуміло, бо вони, всі до єдиного, були китайською. Вимоги залишили, а шляхів, як їх задовольнити, не передбачили. Ба більше, ніхто навіть не спромігся пояснити ці вимоги. Зрештою, я тупо передрав план семінарів у своїх китайських сусідів з лабораторії, а зміст лекцій навіть не став і переписувати. Здав навмання.

Тим часом почалася вступна кампанія. Я не мав наміру залишати країну, тож знову був змушений пройти всі кола документообігу. Цього разу я не став повторювати власні помилки і подався одразу до трьох університетів. Можна було б і більше, але майже всі виші вимагали обов’язкові внески у розмірі 400 юанів (~1600 грн), незалежно від результатів. Шанхайські заклади — так і зовсім до 800 юанів (~3200 грн) загнули. А ще на сайті кожного універу потрібно було заповнювати анкети. Деякі з них обов’язково вимагали міжнародного сертифікату володіння англійською мовою. Таким чином, між іншим я ще й змотався до Сучжоу, аби скласти TOEFL. Готуватися до нього часу не було взагалі, тож їхав з тим, що мав. Навіть перейшов прохідний поріг, залишивши там місячну стипендію на згадку про себе. На результати довелося чекати близько восьми тижнів, а тому і з поданням я затягнув.

Є така цікавинка, що на одну й ту саму стипендію у різних ВНЗ різні терміни подання. У деяких до червня можна телитися, у інших — в середині березня припиняють приймати. Дуже багато варіантів відсіялись лише через цей один фактор.

Найбільше я хотів вступити до Сяминьського університету. Він і у рейтингу значно вищий за мій, і за фотознімками вражає. Саме місто я вже давно мріяв відвідати. Ну, і у «краю вічного літа» жити доки не доводилося. Єдиний недолік — гуртожитки більш традиційні: по два ліжка на кімнату.

Діаметрально протилежні враження отримав від Нанкінського університету науки і технологій. Я вичитав, що останній день прийому документів — «завтра». На пошту розраховувати вже не доводилося, тож ми разом з товаришем навідали його особисто. Виглядало, м’яко кажучи, не дуже. Університетське містечко з низкою дрібних будівель радянського зразку. Що зовні, що всередині все просякнуте старістю. На вході стоять декорації у вигляді шлагбаумів, що пропускають всередину всіх охочих. Тієї миті я ще більше упевнився, наскільки цивільно облаштовано наш рідний Хохай. Мій друг по нещастю переконував мене, що це не має значення — головне, аби взяли. Третій же варіант був очевидним, бо перевіреним.

Повернімося до наших «баранів». На початку травня одногрупники почали питати, коли у мене захист. Їм усім було призначено на 21-ше,мій педагог мовчав. Усі вже захистилися, а він казав, що то мене не стосується. Я нагадав про себе за тиждень, та все ще не отримав відповіді на своє запитання. Ще за тиждень я запитав знову, і він нарешті... відправив мене на розмову зі своїм студентом. Той мене «обрадував», запросивши на захід найближчої середи. Найстрашнішим було те, що плани на той день було узгоджено завчасно, а тепер мені довелося терміново все скасовувати.

Всі академічні вимоги я виконав, залишилось тільки дочекатися вручення дипломів. Так мені здавалося. По факту ж, мене щодня хтось кудись викликав: то до адміністрації, то до супервайзера, то до його студентів-китайців.

Літо непомітно підкралося з-за стосів макулатури, у яких я ховався з березня. Однокласниці запросили мене на одну з вечірок, які «Фонд іноземних домогосподарок м. Чанчжоу» організовує доволі часто. Дійство відбувалося у дворі готельного комплексу «Марко Поло», де нам було організовано шведський стіл. Вино, пиво та вода з м’ятою та лимоном лилися ріками. Знайома німкеня представила мене своєму чоловікові. Той повідомив, що працює у місцевому філіалі компанії Bosch, і запитав, чим я займаюсь. Я мав дипломи магістра у галузі менеджменту та інженерії, до того ж останній дозволяв мені обіймати ледве не будь-яку посаду, що стосується електроніки. Того вечора я отримав запрошення на співбесіду. А я завжди гадав, що мені не щастить.

Співбесіда відбулася наприкінці червня. Я йшов туди з приємним відчуттям і без хвилювання. Глибоко всередині я розумів, що мене не візьмуть, тож і втрачати було нічого. HR написала, що гроші за таксі мені відшкодують, тому я відкрив Didi (місцевий Uber) і викликав автівку до іншого краю міста. 80 юанів (~320 грн) як показник віддаленості заводу від моєї оселі.

Під час співбесіди мені довелося поговорити з рекрутеркою і з директором R&D-відділу. Деталей розкривати не можу, скажу лише, що я поводився, на диво, впевнено. Розгорнуто відповідав на їхні запитання, не соромився задавати свої. Насамкінець мені провели невеличку екскурсію і відправили додому. Своєму сусідові я сказав: знаєш, таке враження, що можуть взяти.

HR таки подзвонила рівно за тиждень з гарними новинами, а потім почала зачитувати усі умови, пільги й бонуси. Запам’ятати усе було несила. Все, чого я бажав, — це мати достатньо коштів, аби можна було кинути викладання і просто програмувати, а тут таке.

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

Нагородження кращих студентів університету перед Новим, 2017-м,роком

Особисті висновки про навчання у КНР

Те, що я не покинув навчання на півшляху і залишився у країні по його закінченні, отримав ступінь магістра, свідчить, що про свій вибір я не шкодую. Втім, якщо ви мене запитаєте, чи порадив би я цей шлях комусь іншому... З одного боку, самі заняття не дали мені жодних нових знань і радше заважали, аніж допомагали. З іншого — я отримав цілих два роки забезпечення моїх базових потреб від китайського уряду для самонавчання, подорожей і пошуку відповіді на запитання, ким я хочу стати, коли виросту. Така собі альтернатива «gap year», ще й з дипломом на фініші.

Зважаючи на ту позицію, яку посідає Китай у сучасному світі, є сенс бодай розглянути можливість вивчення його державної мови. А комп’ютерні науки можна опанувати і самотужки.

Питання наявності бажаної спеціальності взагалі не стоїть. Пошук навчальних закладів за розташуванням, напрямом підготовки чи обраною стипендією можна здійснити на сайті.

Те, що відбувалося зі мною з моменту влаштування на роботу і по сьогодні, за обсягом ледве поступається даному матеріалові. Тому про це вже іншим разом. Якщо є питання, відповіді на які вам хотілося б прочитати у другій частині, — ласкаво прошу до коментарів.

Далі буде...

DOU Hobby: авіамоделювання - від розробки моделі літака до запуску у небо

$
0
0

[DOU Hobby — рубрика про нетехнічні проекти IT-фахівців: творчість, цікаві хобі та інші lifestyle-досягнення. Якщо вам є про що розповісти — пишіть на valentina@dou.ua]

Василь Максимчук — Software Engineer в львівському офісі компанії N-iX. Він захоплюється авіамоделюванням: збирає моделі літаків та запускає їх у небо. В інтерв’ю Василь розповів, як він зацікавився своїм хобі, які бувають авіамоделі та чому важливо уважно обирати місце для запуску.

— Василь, як і коли ви зацікавились авіамоделюванням? З чого все почалося?

Років п’ять тому у Львові стали популярними робототехніка та усіляка електротехніка. Набули популярності розумні будинки на базі Raspberry Pi та Arduino, почали поширюватися квадрокоптери, з яких умільці робили гарні фотографії з нових ракурсів. Коротко кажучи, з’явилося багато доступної та дешевої мікроелектроніки, яка давала поштовх створенню чогось нового — машин, контролерів, схем управління. Застосування обмежувались лише уявою.

Інформацією про нові розробки у цій сфері спеціалісти охоче ділилися на тематичних конференціях та семінарах. На такій зустрічі — Rob0talk — я познайомився з одним із доповідачів, Сергієм Мерзляковим. Він розповідав про польоти на літаках за допомогою камери (first person view). Сергій запросив мене приєднатись до групи з авіамоделювання у Центрі творчості дітей та юнацтва Галичини «Погулянка». Там мені допомогли вибрати першу радіокеровану модель літака-тренера, на якому я й навчився літати.

Разом зі мною авіамоделюванням зацікавилось ще декілька моїх друзів. З’явилося оточення, якому ця тема була настільки ж цікавою, як і мені. Адже авіамоделювання — це перш за все спілкування. Також важливі інженерна складова і навички керування, які розвивають просторову уяву та орієнтацію.

Моє хобі — чудове емоційне розвантаження. Коли ти їдеш за місто, аби покерувати літаком, ти опиняєшся подалі від щоденних проблем. Змінюється оточення, голова перемикається на те, що тобі подобається, від чого отримуєш задоволення і адреналін.

— Які бувають види авіамоделей? Чим вони відрізняються — можливо, розміром, технікою керування?

Авіамоделі поділяються за розміром: малі — до 80 см, середні — у межах 1-1,4 мта великі — від 1,5 м. Також є групування за призначенням: моделі для початківців та досвідчених пілотів. Початківцям варто починати з моделей середнього розміру з верхнім розміщенням крила або планерів (це моделі з більшим розміром крила) завбільшки до 2 м. Вони краще планують, і ними простіше керувати. Їхня конструкція пристосована до падінь та ударів. Часто вони зроблені з матеріалів, які добре та швидко ремонтуються — наприклад, з пінопласту.

Малих моделей я раджу уникати. На перший погляд здається, ніби керувати ними простіше. Проте вони дуже швидко літають, тож реагувати на політ такої моделі складно. Краще обирати просту у керуванні модель — а не ту, яка гарно виглядає.

Досвідчені пілоти обирають моделі для вищого пілотажу, швидкісні, моделі великого розміру або ті, що сконструйовані як зменшена копія справжнього літака. Керувати ними набагато складніше, тож спершу обов’язково треба пройти через моделі початкового рівня.

Також слід брати до уваги вибір місця для перших польотів. Це мають бути відкриті майданчики, віддалені від житлових будинків та місць скупчення людей.





— Які моделі ви зібрали першими? Як це було, скільки часу потребувало?

Першою моєю моделлю був пінопластовий мотопланер з розмахом крил 2 м. Це була дуже гарна і проста у керуванні модель. Можна сказати, що цей планер і «затягнув» мене до моделювання.

Наступну модель — також літак-тренер — я зібрав власноруч за кресленнями мого колеги. Я дуже надихнувся тоді, хотів зробити все власноруч від початку до кінця. Модель мала пінопластові крила, профіль яких я вирізав за допомогою гарячої струни та обклеїв їх скотчем. Також розробив 3D-модель фюзеляжу та потім вирізав її з фанери на фрезерному станку. Фюзеляж я склеїв звичайним клеєм для дерева. Ця модель — дуже проста та дешева у виготовленні. На її побудову витратив близько п’яти днів. Навчатися було справжнім задоволенням. До речі, ця модель ще досі літає та тішить вже нового власника.

Коли я вже опанував мотопланери, запрагнув більшого. Я зупинився на моделі Multiplex Funcub. Це гарна модель середнього розміру, вона проста в управлінні для початківців. Я вивчив на ній базові фігури вищого пілотажу: навчився робити бочку та мертву петлю.

До речі, Funcub легко модифікувати. Я встановив на неї світло та поплавки. Ми їздили на озеро Задорожнє, що біля Львова, щоб злітати і саджати літак на воду. Це було дуже весело. Аби електроніка не замокала, всі важливі модулі герметизували від потрапляння води. Коли ми вперше приїхали на озеро з літаком, навколо нас зібралося багато людей, аби подивитися, що діється. Я вперше злітав з води, тож попросив рибалок, які підійшли до нас, дістати літак човном у разі падіння — в обмін на авіашоу.

Я не поспішав купувати нові моделі — тренувався на тому, що мав. Моделі Funcub мені вистачило на два сезони тренувань. Кажуть, що перший сезон до моделі звикаєш, а на другий вже літаєш.

— А які моделі використовуєте зараз? Де ви зазвичай літаєте? Скільки часу на тиждень присвячуєте хобі?

Зараз маю італійську пілотажну модель — SebArt Katana. Вона є складнішою в управлінні та вимагає більше налаштувань, і тим цікавіша для мене. Один зайвий рух — і можна розбити її об землю. Це вже не модель-тренер: на ній можна досить точно виконувати фігури вищого пілотажу.

Посеред тижня після робочого дня я не маю змоги їхати кудись далеко. Тому для тренувань ми обираємо так звані паркфлаєри — невеликі моделі, які можуть літати на відкритих майданчиках чи парках у місті. На вихідних, коли є більше часу, літаємо за містом на нашому модельному аеродромі. А взимку тренуємося у спортзалі. Для спортзалу маємо інші моделі з розмахом крил 80 см, придатні до запуску в обмеженому просторі.

Отже, в середньому я запускаю літаки 3-4рази на тиждень: 2-3рази в межах міста та один раз на вихідних на модельному аеродромі.

Модель Multiplex Funcub

— Що складніше — конструювати модель чи керувати нею в польоті?

Найскладніше, мабуть, піднятися з дивану і почати щось робити :) На долю авіамоделіста випадає важкий шлях — від конструювання до перших польотів.

Сказати, що я сам роблю свої моделі, буде не зовсім коректно. Я їх купляю як набір, який потрібно зібрати. Зазвичай це вже готові крила, зібраний та обтягнутий плівкою фюзеляж (якщо мова йде про дерев’яну модель). За собою я залишаю процес збірки та доопрацювання моделі, вибір електроніки та її встановлення, відлагодження моделі в польоті.

Проте іноді я роблю модель від стадії креслень до готового до польоту літака. Наприклад, зараз працюю над моделлю для вищого пілотажу, яка буде побудована зі спеціальної породи дерева бальза та моделювальної фанери. Фанера для креслення розрізана на фрезерному станку, а бальза нарізана лазером. Коли весь каркас буде зібрано, я обтягну його спеціальною легкою плівкою.

Креслення можна зробити власноруч або придбати готові. Існує багато відкритих джерел, звідки їх можна завантажити та роздрукувати на папері. А от етапу навчання не уникнеш. Моделлю не так просто керувати, як може здатися на перший погляд. Аби опанувати політ по колу, потрібно всього кілька тренувань — бажано під наглядом досвідчених пілотів. Прогрес буде очевидним.

Коли політ по колу гарно дається, можна пробувати політ в інверті або вивчити фігури вищого пілотажу. Це все дуже індивідуально і залежить від успіхів з практикою.

Шлях до успіху лежить через невдачі. Наприклад, мені доводилося і губити, і розбивати літаки. Одного разу літак віднесло вітром до лісу. Ми його не знайшли, проте повернулися з опеньками :)

Авіамоделювання — це, насамперед, відповідальність за себе і за навколишніх. Уявіть, що на вас падає літак вагою близько кілограма зі швидкістю 70 км/год. Падіння літака може серйозно травмувати. Тож перед початком польоту ми робимо перевірку усіх систем та прискіпливо вибираємо місце для польоту.

— Ви брали участь у змаганнях з авіамоделювання? Як проходять такі змагання, за якими критеріями там оцінюють учасників?

Минулої весни біля Львова я брав участь у чемпіонаті світу «Вілга» серед планерів. А цього літа — у любительському Кубку Європи з гідропланів у Польщі. Там я посів друге місце з вищого пілотажу у класі літаків до 2,5 кг.

Різних видів змагань — дуже багато, адже існує багато різних класів літаків. Наприклад, кордовий бій — це бій між двома літаками, які намагаються гвинтом відрізати шматок стрічки, прикріпленої до літака-опонента. Це дуже видовищні змагання. Ще є змагання серед вільнолітаючих моделей, якими ніхто не керує, а моделі літають за заданою програмою. Також є змагання радіокерованих планерів.

Взагалі в Україні авіамоделювання не таке популярне, як у тих же Німеччині чи Чехії. Але якщо люди починають цим займатися, то вже все роблять на високому рівні. Крім того, маємо дуже сильних спортсменів, які займаються авіамоделюванням професійно. Наприклад, представник львівської команди торік виборов титул чемпіона світу у кордовій гонці.

Модель Edge 540 Volkswagen

— Що можете порадити новачкам? З чого почати? На які витрати розраховувати?

Як я вже згадував, найкраще починати з моделей-тренерів. Коли першу модель вибрано, її треба «облітати». Цей термін означає правильне відлагодження моделі до і під час польоту. Такий процес потрібно зробити лише один раз, аби зрозуміти, чи правильно модель реагує на команди з пульта керування. Наприклад, варто перевірити, чи немає крену під час польоту. Якщо є, то потрібно його усунути за допомогою тримера. Також важливо правильно встановити центр мас, його початкове значення вказане в інструкції. А ще не завадить кілька годин попрактикуватись на симуляторі.

Перед тим як модель облітати, рекомендую звернутись до місцевого авіаклубу. Наш авіаспортивний клуб називається «АСК „Віраж“ Львів». Якщо виникнуть питання, ми охоче допоможемо.

Щодо витрат: авіамоделювання — не дешеве хобі, але й не захмарно дороге. На початку найбільшою статтею витрат є пульт керування — гарний пристрій коштує приблизно 5 тис. грн. Що стосується літака, то новачку достатньо простої моделі, яку можна зробити за кресленнями з інтернету. Зараз є дуже багато гарних креслень у вільному доступі. Інший варіант — купити відразу готову модель до польоту. Це обійдеться приблизно у 2 тис. грн — трохи дорожче, ніж робити самотужки. Також необхідно придбати щонайменше дві батареї і зарядний пристрій до них — це ще 2 тис. грн. Отже, комплект для початківця обійдеться у 8-10 тис.грн.

— Які маєте подальші плани щодо хобі?

Зараз я працюю над новою моделлю, з якою хочу взяти участь у наступному Чемпіонаті Україниз копій та напівкопій радіокерованих моделей. Чемпіонат України відбудеться 11 липня 2020 року на новому аеродромі Underhill у селі Підгір’я біля Івано-Франківська.

Советы сеньоров: как прокачать знания junior Product Manager

$
0
0

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

Андрей Радич, Head of Product в YouScan

10 лет в продакт-менеджменте, 20 лет в IT

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

Работа продакта в аутсорсинговой компании, обслуживающей потребности нескольких крупных корпоративных клиентов и в B2C стартапе, работающего по SaaS-модели, имеют между собой мало общего. Более того, даже в однотипных, на первый взгляд, продуктовых компаниях работа продакта может сильно отличаться из-за различий в структуре компании, стратегии и корпоративной культуре.

Но, несмотря на это все, есть основные навыки, которые, по моему мнению, нужно развивать абсолютно любому продакту:

  1. Учитесь понимать принципы работы бизнеса, «откуда берутся деньги».Так же, как инженеру, проектирующему двигатели, важно понимать законы физики, для продакт-менеджера важно понимать законы бизнеса: принципы работы маркетинга, продаж, удержания клиентов. Также постоянно исследуйте продукты, которые вас окружают, и задавайте себе вопрос, что сделало одни из них успешными, а другие привело к банкротству.
  2. Развивайте статистическое мышление.Перестаньте использовать фразы типа «Люди всегда делают так» или «Никто так не делает». Вообще перестаньте думать о любых событиях, что они точно или произойдут, или не произойдут. Всегда думайте категориями вероятностных распределений, когорт и персентилей. Не только на работе, а постоянно, в любых ситуациях. Например, вы пригласили 10 друзей на праздничный ужин, а удалось забронировать стол только на 8, но вы спокойны, поскольку по опыту знаете, что, скорее всего, придут человек 6-7,а вероятность того, что придут хотя бы 9, — не более 10 процентов. Если у вас гуманитарное образование, то я крайне рекомендовал бы освоить азы матстатистики.
  3. Учитесь оценивать риски и управлять ими.Этот навык напрямую связан с предыдущим. В любой ситуации вы должны постоянно думать о том, что может пойти не так, а также быстро оценивать, какая вероятность того, что это произойдет, и насколько разрушительными будут последствия. Опять-таки, не только на работе. В описанной выше ситуации вы осознаете, что вероятность того, что придут все, все же ненулевая, и у вас должен быть план «Б» на этот случай, например, перейти в «фуршетный» формат.
  4. Постоянно ищите возможности.Этот навык напрямую связан со статистическим мышлением и управлением рисками. Самые интересные возможности обычно находятся в области, где вероятность невелика, и если вы будете исходить из того, что «это невозможно», то все самое «вкусное» будет проходить мимо вас. Учитесь преобразовывать «это невозможно» в «есть такой-то шанс, есть такие-то риски, их можно адресовать так и так».
  5. Прокачивайте навыки коммуникации.То, насколько хорошо вы продумали какую-то идею, не будет иметь никакого значения, если никто этого не поймет. У хорошего же продакта задача сложнее: идея должна быть не просто понятна, команда должна ею «загореться» и хорошо понимать, зачем они это делают.
  6. Развивайте любопытство.Практикуйте принцип «5 почему», но я бы сказал больше — не переставайте задавать вопрос «Почему?» или «Зачем?» столько раз, сколько потребуется. Никогда не останавливайтесь. Пользователь хочет такую-то кнопку. Зачем? — Чтобы подготовить отчет. Зачем? — Чтобы отправить «руководству». Зачем? — Чтобы проконтролировать ключевые показатели. Зачем? — Чтобы принять решение о распределении ресурсов... Понимая всю эту цепочку, вы сможете помогать пользователю решить его настоящую проблему оптимальным образом.
  7. Посещайте продуктовые «тусовки»:конференции и митапы, благо их становится все больше и больше. Это самый верный способ увидеть всю широту подходов к продакт-менеджменту, а также быть в курсе всех свежих веяний. Могу рекомендовать конференции Confidence Conf и Growth Marketing Stage, организуемые Ярославом Степаненко и Павлом Педенко, митапы, которые они организовывают, ProductTank, митапы в Unit.City.

Евгений Цветухин, Product Manager в Railsware

12 лет опыта в профессии

Сильная базовая экспертиза

Из моего опыта, глубокие знания хотя бы в одной из функций бизнеса помогают стать успешным продактом гораздо больше, чем поверхностные широкие знания во всех направлениях сразу, так как получается Jack of all trades and master of none. На практике такие широкие специалисты хорошо владеют словарем, но не могут заделиверить качественный результат. И сильная команда (особенно разработчики) это чувствуют. Теряется уважение, становится невозможно работать.

Потому начинайте с прокачивания своей базовой экспертизы: став крутым в чём-то одном, намного легче познавать остальное. С 2015 года Alpha HQ проводит ежегодный опрос 200-300продактов и выкладывают «Product Management Insights Report», из года в год в продакт-менеджеры чаще всего переходят специалисты из Business Analytics, Engineering, Marketing & Sales (заполнив их опрос, можно получить репорт в PDF). Интересно, что только 8% из тех, кто стартовал как продакт, развиваются в этой функции, разумеется, непонятно, с каким успехом.

Эго мешает в работе

С одной стороны, амбиции помогают добиваться результатов. C другой — эго приобретает негативный оттенок. Если из-за своего мнения ты не слышишь пользователей, страдает продукт, команда и приоритизация. Ты теряешь связь с реальностью. Самая сложная задача продакта — смотреть на ситуацию непредвзято, вживаться в роль юзера. Customer Development должен стать стилем жизни.

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

Качай дополнительные скилы — T-Shaped

Если ты маркетолог, в себе нужно развивать скилы инженера, BA, продавца. И наоборот. Я в свое время перешел в Product Management из QA c инженерным образованием. В начале учился бизнес-анализу, операционке, финансам и потом маркетингу. Каждая новая функция — как новый мир. Оказывается, я никогда до этого не смотрел на вещи с этой точки зрения. Успешному продакту нужны сразу несколько пар глаз, это большой шаг в product vision. Но большинство смотрят только одним глазом :) Например, 4 года назад в Mailtrap.io мы недооценивали силу рекламы и маркетинга. Хороший продукт был практически без пользователей — всего 38 000. Когда мы наконец запустили рекламу, продукт начал быстро расти и уже собрал 550 000+ пользователей.

Методологии рулят

Существует невероятно много продуктовых методологий, которые экономят время и структурируют мозги. Звучит банально, но вот вам пример: год назад мы получили 350+ заявок на позицию Product Manager, но не смогли нанять специалиста. У кандидатов не было минимальных знаний подходов к созданию продуктов, а стратегия строилась на интуиции или опыте 2-3 кейсов.Вот вам минимальный набор подходов для старта: Lean Startup, Lean Canvas, Value Proposition, Customer Development, Roadmap, MVPи набор продуктовых метрик. Недавно был на воркшопе у продакт-менеджера Uber — основной посыл был как раз о базовых продуктовых методологиях.

Адвайзер/ментор сэкономит 10 лет

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

Олег Свірський, Product Manager в Matic

7 років у Product Management

Чи існує junior Product Manager в українських реаліях? Бачив холівар із висновком, мовляв, ні, продакт-менеджер не може бути junior. Як не буває junior CEO. Моя особиста думка: так, існує, але з певними особливостями.

На відміну від USA, в Україні не розповсюджена практика Internship/Associate PM програм, на які можуть подаватися випускники універів.

Згадаємо картинку Мартіна Еріксона: «хто такий продакт-менеджер».

© Martin Eriksson

Він пояснює, що хороший продакт — це той, хто має глибоку експертизу хоча б в одній сфері, цікавиться усіма трьома, і може вільно спілкуватися з експертами кожної з цих галузей. Часто до продактів підвищують бізнес-спеціалістів, дизайнерів чи інженерів, які проявляли ініціативу у розвитку продуктів компанії.

Відповідно, людина вже є досвідченою в основній спеціальності, але новою у продакт-менеджменті. Це і є junior Product Manager.

Рівні відповідальності і сіньйорності продактів

Щоб якнайкраще адаптуватися до нової ролі, раджу, в першу чергу, зробити три речі:

  1. Визначте очікування ключових стейкхолдеріввід вас. Адже на різних стадіях розвитку продукту й компанії перед вами стоятимуть різні виклики.
  2. Зважаючи на ці очікування, складіть разом із вашим менеджером план дій на ramp up період.Ми у Matic для цього використовуємо 30/60/90 Plan — перелік питань, які потрібно з’ясувати, і задач до виконання на перший, другий і третій місяць роботи. Обов’язково чітко пропишіть deliverables, які ви повинні зробити!
  3. Знайдіть ментора. Колега чи експерт із зовні — не важливо, головне — ваше обопільне бажання працювати разом.

Окей, ви трохи адаптувалися у новій ролі і хочетерозвиватися далі. Продактам доводиться качати hard і soft скіли одночасно й рівномірно. Тому рекомендую зробити gap analysis себе як спеціаліста, оцінити (разом з ментором), чого вам критично бракує, і скласти action plan, як себе розвивати.

Універсальними й обов’язковими для продакта є наступні скіли.

Vision — уміння уявити ваш ідеальний продукт, порівняти з current state і сформувати роадмапу, яка приведе вас до світлого майбутнього.

Analytics & Metrics — як ви міряєте успішність продукту, процесу, фічі, бізнесу?

Prioritization — навколо сотні ідей, яку ж із реалізувати в першу чергу? Підказка: ту, що має найкраще співвідношення impact/costs :)

Communications — уміння чітко, зрозуміло, вчасно і проактивно комунікувати зі стейкхолдерами, командою, клієнтами — усно й письмово.

Management — загальні навички управління.

Domain knowledge — як глибоко ви розумієте бізнес, у якому працюєте.

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

Pro tips:

  1. Спілкуйтеся якомога більше з користувачами (спасибі, Кеп). 5 днів поруч із нашими сейлами дали мені для розуміння процесів більше, ніж 2 тижні вивчення документації.
  2. Качайте доменну експертизу.Говоріть з бізнесом однією мовою, розумійте, як компанія заробляє.
  3. Побудуйте зв’язки зі стейкхолдерами.З одного боку, ваш продукт буде успішним у випадку, коли задоволені клієнти і користувачі. З іншого ж, кар’єра менеджера залежить від того, наскільки задоволені вашою роботою ключові стейкхолдери: команда та керівництво.
  4. Спілкуючись зі стейкхолдерами, намагайтеся знайти відповідь у фреймворку Problem — Impact — Solution.Чи це є проблемою? Яка величина проблеми? Як вона вирішується зараз і як ми можемо покращити це?
  5. Оцінюючи проблему чи feature request, переконайтеся, чи не є ця проблема частиною більшої проблеми.Якщо є, тоді не спішіть кидатися на вирішення початкової проблеми. Часто трапляється, що, розібравшись в root cause, ви прийдете до зовсім іншого рішення початкової проблеми чи взагалі нівелюєте її, одразу вирішивши проблему вищого рівня.
  6. Будьте лідером.Адже у продакта, як правило, немає формальних важелів впливу на команду, тому неформальне лідерство — ваш єдиний спосіб отримати бажане.
  7. Не бійтеся братися за складні задачі, шукайте проблеми проактивно.Найкрутішими є ті продакти, які реалізують ініціативи 10х, а не +10%.

Корисні ресурси

brianbalfour.com — блог фаундера Reforge i ex-VP Growth @HubSpot. Тематика — growth, acquisiotion, strategy.

ShiftThinking — не про продукт, а про спосіб мислення. Обов’язково для розвитку big picture view.

A16Z — блог Andreesen Horowitz про тренди у технологіях.

Intercom Blog — Інтерком має власні круті продуктові, дизайн і growth фреймворки, чудово описані у блозі.

FoldingBurritos Blog — основні техніки пріоритизації в одному гайді.

ProductMan by IAMPM — онлайн-курс. Його особливість у закріпленні ментора за студентом, фокусі на практичних завданнях і наявності випускного іспиту, який систематизує весь курс.

Cracking the PM interview — книга допоможе не тільки підготуватися до інтерв’ю, а й зрозуміти потрібний ПдМу скілсет й очікування від нього.

Александр Емельянов, Chief Product Officer в Bioniq, Лондон

8 лет в профессии

Как прокачивать знания? Только практикой. Теория продакт-менеджмента достаточно проста и понятна. После прочтения второй, третьей, четвертой книги вы не узнаете ничего нового.

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

Всем начинающим продакт-менеджерам я бы рекомендовал одно — делайте свой продукт. Хороший продакт-менеджер должен обладать скилами питчинга и просто уметь общаться с людьми. Используйте это качество для того, чтоб привлечь в свою команду разработчиков, которые смогут за долю в продукте (на самом деле их мотивация похожа на вашу — улучшить свои скилы и сделать что-то «свое») помочь вам выпустить продукт на рынок.

Уже на моменте проектирования функционала вы можете вникать в настоящий продакт-менеджмент: проводите пользовательские интервью для выяснения потребностей рынка, изучайте конкурентов и их юнит-экономику, формируйте гипотезы функционала продукта, расписывайте Go To Market план с prediction конверсий acquisition, retention, ревенью, настраивайте системы аналитики, обвязывайте все ивентами, управляйте разработкой.

После выхода продукта на рынок находите минимальный бюджет на acquisition, общайтесь с аффилиатными сетями, проводите сплит-тестирование креативов, продуктовой страницы, делайте продуктовые эксперименты и считайте реальную юнит-экономику. В условиях ограниченного бюджета вам придется задуматься о еще одной важной составляющей — реферальном трафике и viral loops, делайте и их. Звучит как неплохая практика, да? Скорее всего, ваш продукт провалится на рынке, но и это вам только на пользу. Анализируйте, чего именно вам не хватило для построения sustainable business model и какие именно расчеты оказались нереалистичными.

Я не буду рекомендовать курсы по продакт-менеджменту (не факт, что они вам помогут, и всю теоретическую информацию вы можете бесплатно найти в ютубе). Из полезного, порекомендую смотреть кейсы реальных продуктовых экспериментов, например здесь. Лично мне всегда полезно и интересно наблюдать за тем, как например Uber Eats использует дефицит для увеличения продаж, Hopper использует фиксирование установки (priming) для погружения пользователя в соответствующее настроение перед покупкой билетов и разбирать chekout flow Zapier. Я увлекаюсь еще и поведенческой экономикой для того, чтобы лучше понимать, какие факторы влияют на принятие решением пользователем, и формировать более качественный value proposition, но это уже личное дело каждого.

Маркіян Мацех, Senior Product Manager в Vimeo

9 років в ІТ, 5 років в PdM

Коротко для тих, хто ще не отримав роботу ПдМ (продукт-менеджера):

  1. Найшвидший спосіб:отримати підвищення в межах вашої компанії. Якщо ви дев, QA, дизайнер, супорт, маркетолог, ви вже знаєте користувачів, індустрію, продукт, колег. Щоб вам довірили роль продакта, вам потрібно її де-факто виконувати. Уявіть, що ви вже ПдМ, виконуйте ПдМські практики, ухвалюйте ПдМські рішення і аргументовано пропонуйте їх менеджменту.
  2. Альтернатива н1:якщо вам хтось пропонує хоч якусь роботу продактом — беріть, вчіться, не перебирайте нецікавою індустрією.
  3. Альтернатива н2:зробіть власний продукт, навіть якщо зафейлитесь. Дорожче, страшніше, але дієвіше.
  4. Крайній варіант:почитайте теорію, підготуйтесь до співбесід і сподівайтесь, що вас хтось прийме. Це буде важко.

Для тих, хто вже почав роботу,для початку, якщо ви не впевнені, чи робите те, що треба, перевірте, чи вас не віднесло кудись поза життєвий цикл роботи продакт-менеджера:

  • Знайшов проблеми користувачів.
  • Вибрав проблеми з найбільшим business impact.
  • Задизайнив найпростіше реалістичне вирішення проблеми (MVP).
  • Заменеджив реалізацію рішення і його вихід на ринок.
  • Прослідкував, чи це рішення дало очікуваний business impact.
  • Почав все спочатку з тою ж або новими проблемами.

Щоб робити це якісно у вашій щоденній роботі, вам треба дуже добре знати команду, користувачів, продукт і ринок.

Команда.Ви маєте розуміти, хто і як причетний до вашого продукту, хто впливає на рішення і який протокол співпраці з кожним. До прикладу, супорту може бути потрібен тиждень, щоб написати help center article і натренувати всю команду, маркетингу може бути потрібно два місяці для підготовки релізу, дизайнери можуть хотіти брати участь в дискусії на етапі формування ідеї, валідації проблеми або дизайну рішення і т. д.

Користувачі. Ви маєте знати відповіді на питання, чому вони люблять ваш продукт, чим користувались до нього, чому ваш продукт кращий за альтернативи, яку проблему він їм вирішує, як вони ним користуються, чим вони займаються в житті, чого їм бракує в продукті і т. д.

Продукт. Ви маєте знати, якої форми крива retention, скільки у вас активних користувачів щотижня, який щотижневий приріст нових юзерів, який NPS, які фічі найпопулярніші, скільки $$$ ви генеруєте в місяць і скільки тратите, який CAC (і в ідеалі LTV), які acquisition-канали найефективніші і т. д. (в деяких продуктах це непросто порахувати, і це ок, але ви маєте думати про це).

У цій статтія розказую детальніше про те, як отримувати відповіді на питання вище.

Ось ще декілька рандомних порад, бо всього неможливо втиснути в цю статтю.

Не починайте роботу над фічами/продуктами, не розуміючи користувачів і їхніх проблем.Випишіть факти у короткому форматі: звідки ви знаєте, що така проблема існує, що вона поширена і важливіша за інші проблеми. Цей же документ ви можете показати будь-кому в компанії.

Упевніться, що проблема, яку ви вибрали, збігається з бізнес-цілями компанії. У світі багато проблем, і ми, як ПдМи, можемо дозволити собі вирішувати тільки ті, що дають business impact. Чи це генерація нового прибутку (чи користувачів), чи втримання поточного, чи зменшення витрат і т. д. Тільки розуміючи очікуваний business impact, ви можете вирішити (і довести іншим), чи ця проблема важливіша за інші.

Думайте про стратегію.Які unfair advantage або defensible differentiators (беззаперечні конкурентні переваги — ред.)у вас є під час побудови нових фіч/продуктів? Доступ до користувачів (нижчий CAC), партнери, бренд, технологія тощо.

Перед початком ресерчу визначтеся, на які питання ви шукаєте відповідь.Ще до старту уявіть, що у вас уже є відповіді, і сплануйте, як поміняються ваші дії залежно від відповідей.

Балансуйте short-term / long-term goals. Вам потрібно показувати результати і співробітникам, і клієнтам. Тому потрібні релізи кожного місяця or so, навіть невеликі. Але реальні прориви зазвичай вимагають зусиль на півроку-рік і більше. Це балансування — ціле мистецтво.

Не бійтеся ухвалювати рішення на основі інтуїції, якщо інвестиція не велика. Один з найбільших гріхів ПдМа — прокрастинація рішень. Краще ухваліть погане рішення швидко, ніж правильне рішення через місяць (якщо інвестиція не велика).

Наостанок:

  • Раджу почитати мою улюблену книжку з продакт-менеджменту Inspired by Marty Cagan. Імхо, вона найкраще розбиває по поличках роботу продакта і best practices.
  • Якщо відчуєте, що в книжці для вас немає нічого нового, раджу записатися на один з курсів Reforge — імхо, найкраща школа для продактів у світі. Тоді ви зрозумієте, як багато треба ще вчитися (як недавно зрозумів я :) ).

Успіхів!

Володимир Мірненко, Product Manager в Wix

11 років в IT, 5-6років у продакт-менеджменті

Окей, тобто ти — продакт-менеджер-початківець, і хочеш знати, у що ти вляпалася (або вляпався) і що робити далі? Пропоную для початку відкоркувати пляшку ігристого вина і підняти келих за твій успіх. Адже на ринку праці пропозиція ПдМів без досвіду значно перевищує попит. Тож таки можеш влаштуватися, якщо хочеш. Звісно, це не привід розслабляти булочки, але можливість порефлексувати на тему того, що тебе сюди привело: від мотивації до досвіду й особистих якостей.

Почнемо з мотивації. Якщо ти, як і я 7 років тому, не хочеш більше вислуховувати вказівки менеджера по той бік екрана, а натомість хочеш самостійно керувати продуктом, то в мене до тебе є серйозна розмова. Ти вже доросла дівчинка (або хлопчик) і маєш знати, що діточки самі по собі не заводяться в мами в животику. Так само й вимоги до продукту в голові продакт-менеджера. Шлях, який проходить фіча від ідеї до джира-тікета, складний і відбувається за участю багатьох людей: маркетологів, агентів саппорту, дизайнерів, інженерів, інколи ще й юристів, фінансистів, топ-менеджерів, інвесторів, які хочуть зробити власний внесок у розвиток продукту, бачення пріоритетів і фіч. Ось тобі моя порада #1: подумай, що тебе насправді мотивує. Якщо це бажання бути decision maker’ом, то я тут бачу два варіанти: почати власний бізнес або переглянути своє ставлення до ролі ПдМа і замінити «той, хто ухвалює рішення» на «той, хто допомагає знайти найкраще рішення».

Так, робота продакт-менеджера — це аж ніяк не про одноосібне управління продуктом. Це про процес збору й аналізу інформації та ідентифікацію найболючішої проблеми. І це про обмін думками і вибір найкращого рішення, навіть якщо воно належить не тобі. Як пошук проблеми, так і пошук найліпшого рішення передбачають багато спілкування. Часом продакт-менеджер витрачає весь свій день на усні й письмові комунікації. Моя порада #2:оціни свої комунікативні здібності і схильність до спілкування або рівень стресу, який воно приносить.

Якщо спілкування в цілому приносить задоволення або хоча б не завдає страждань, то можна рухатися далі до наступного питання: наскільки ти вміло комунікуєш із оточенням? Я неодноразово споглядав ситуацію, коли людина, яка вміє ефективно доносити свою думку і ще непогано говорить англійською, просувається кар’єрними сходинками. Моя порада #3:вчи англійську. Хоча б до рівня Upper-Intermediate. Наш внутрішній ринок не настільки розвинений, щоб на ньому працювала істотна кількість продуктових компаній.

В цілому, хоча ти ще недосвідчений продакт-менеджер, імовірно, англійська в тебе вже на пристойному рівні. Тому порада #4:качай лідерство. Західний світ усе більше говорить про менеджмент у контексті лідерства. А hi-tech компанії крокують в авангарді цього руху. Ця тема безмежна, і, напевне, існують пристойні тренінги і курси, які вчать цьому. Я раджу для початку почитати «Соціальну психологію»Д. Маєрса і «Емоційний інтелект»Д. Гоулмана.

Певно, ти хочеш спитати про hard skills? Для початку давай розставимо крапки над «і» щодо технічних скілів. Вони не є суттєвими для ПдМа за деякими винятками, наприклад, продукти для розробників, інфраструктурні продукти і платформи, платежі. Тих, хто працює з цим, часто називають технічними продакт-менеджерами. Так-от для звичайного продакт-менеджера глибоке розуміння технологій не є необхідним. Хоча є нюанси.

По-перше, якщо в компанії не побудована продуктова культура або взагалі немає продакт-менеджерів і наймом займаються СТО і проджект-менеджер, то вони будуть шукати людину, з якою вміють працювати. Тобто технічно обізнаного спеціаліста. Тому моя порада #5:пройди кілька курсів з web development на codecademy.com, просто щоб розібратися в загальних засадах розробки.

По-друге, від продакт-менеджера інколи очікується знання SQL. У деяких компаніях, особливо невеликих, немає позиції дата-аналітика, який би допомагав ПдМу розбиратися в даних і будувати репорти. А навіть якщо є, то ПдМу все одно треба розуміти, звідки беруться дані, що можна порахувати і як. Тому знання SQL не буде зайвим. Порада #6:аби отримати певний базовий рівень SQL, іди на той самий codecademy.com.

Утім набагато важливіше для продакта — вміти працювати з аналітикою системно, формулювати воронки і когорти, продуктові метрики і KPI бізнесу, на етапі проектування фічі закладати, які дані збирати і аналізувати, щоб визначити її успішність. Тому моя порада #7 буде:навчитися працювати з аналітикою. У Mind The Product блозі є хороший допис, який все розкладає по поличках. До речі, там багато цікавих статей — раджу. Також постарайся пройти безкоштовні курси з Google Analytics.

Окрім аналітики, тобі ще знадобляться навички дослідження ринку і конкурентів, проектування інтерфейсів і UX, виявлення потреб користувачів через роботу з саппортом та власні інтерв’ю і багато чого іншого. Непогані підсумки практичного досвіду зробили Intercom у своїй методичці. До речі, якщо слухаєте подкасти, у них є свій. Я сам на нього підписаний, і тобі рекомендую.

Але знаєш, найголовніше — це знайти компанію, яка заохочує всі ці практики. Ти можеш читати статті і книжки, слухати подкасти і дивитися відео, та важливіше пробувати все власноруч: рахувати бізнес-кейси, говорити з користувачами, тестувати гіпотези і все інше. Якщо в твоїй компанії немає змоги це робити, шукай нову. Досвід вирішує.

Окрім зміни роботи, є ще два варіанти, хоча не знаю, який з них буде простішим.

Одне місце, яке вчить і водночас дає практичний досвід — це річний курс Product Management Professium в проджекторі. Курс платний, вимагає багато часу, конкурсний набір раз на рік, але дає структурні знання і допомагає закріпити їх практично.

Друге місце — це власний продукт (стартап або пет-проект). Вимагає ще більше часу, потребує технічного ко-фаундера, дає надзвичайно практичний досвід, але структурувати його доведеться самостійно.

У будь-якому випадку, видали нарешті з телефона застосунки соціальних мереж і почни робити хоч щось. Зараз вже маю бігти, якщо що — пиши.

Альона Возна, менеджерка продукту в EVO

13 років в IT, 5 з них в ролі Product manager

Менеджер продуктів — у першу чергу менеджер. А головне для менеджера — високий рівень soft skills. Мій топ-3 soft skills для продакта такий:

1. Емпатія

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

Як тренувати.Я вірю, що основа емпатії — розуміння і захоплення людьми та світом у всій його різноманітності. А відкриває нам це мистецтво. Отже порада від мене: читайте не тільки професійні статті та бізнес-книги, а й художню літературу. Я думаю, що художня література та живопис зробили не менший внесок у мій професійний розвиток, ніж The mom testта курси з SQL (які я теж раджу).

2. Критичне мислення

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

Як тренувати. Вивчати, як працює людський мозок та вчитися помічати когнітивні упередження. Тут моя найперша порада — «Мислення швидке і повільне»Деніела Канемана.

А друга — завжди пам’ятати про сенс. У нас в команді навіть є спеціальне питання: «Щоб що?». Його задають, коли всі дуже захопилися якоюсь ідеєю і треба зупинитися та переконатися, що ідея справді варта реалізації. Звичка постійно питати «чому?», «навіщо?», «щоб що?» і давати на ці запитання чесну відповідь — дуже бісить довколишніх, але допомагає ухвалювати зважені рішення.

3. Комунікативні навички

Ми з колегами часто жартуємо, що головний інструмент менеджера продуктів — проповіді. Тобі потрібно «продати» команді нові фічі, вмовити стейкхолдерів відмовитися від якоїсь ідеї та переконати колег, що експеримент — не даремне витрачання часу. Вміти логічно викладати суть та зрозуміло пояснювати — критично необхідні продакту.

Як тренувати: говорити. Піти на курси ораторської майстерності, ходити на ProductCoffee, виступати перед колегами, готуватися перед тим, як щось говорити, та слухати інших спікерів.

Дві вправи для розвитку продуктового мислення

Залежно від компанії та на різних етапах життєвого циклу продукту змінюється важливість практичних навичок. Наприклад, таких як UX-дизайн (раджу цей курс, він допоможе зрозуміти, що ще треба вивчати), робота з даними, вміння проводити дослідження та тестувати гіпотези, рівень технічних знань, розуміння бізнесу та вміння прорахувати модель монетизації.

Але є одна незмінна річ — це продуктове мислення. Така собі професійна деформація менеджерів продуктів. Я свій product mindset треную двома вправами.

Першу я для себе називаю: «А що вони знають?» (інші продакт-менеджери — ред.). Це такий розумовий експеримент та спроба дійти до суті. Щоразу, коли продукт, яким я користуюся, оновлюється, я намагаюся зрозуміти, чому вони зробили саме таке оновлення. Що вони знають, аби зробити саме це? Які метрики хочуть покращити? Звісно, я ніколи не дізнаюся, чи була я права, але звичка думати про сенс та аналізувати добре тренується.

Друга вправа — це бібліотека референсіву голові. Коли я пробую якийсь новий продукт (дуже раджу робити це постійно), я подумки підбираю референси до того, що бачу. Це відбувається приблизно так: «О, гарний пошук. А де ще класний пошук?» — і перебираю продукти, в яких бачила цікаву реалізацію. Отже, де можна підглянути пошук? У пошукових системах, у продуктах для трекінгу згадок ключових слів, у Slack, у Google drive. А де ви бачили класний пошук?

Дмитрий Тимченко, Product Manager в AB Soft

5 лет в профессии

Впервые пишу такого рода User Story. Свой путь менеджера по продукту я начал после 6 лет работы в логистики. Тогда я понимал, что вот так с наскока прийти и стать менеджером продукта, не имея понимания методологий разработки, развития клиента (customer development), без опыта сбора и анализа данных, знаний лучших практик в UX/UI у меня не получится. Единственное, что у меня было — это знание английского языка, что, безусловно, важно в ИТ-сфере в целом, независимо от роли и опыта управления командой.

Первое, что необходимо понять — это наиболее важные навыки для работы продакт-менеджера, так сказать must have skills. Как это сделать? Самый простой способ — ознакомиться с требованиями к вакансиям на данную позицию. Сразу скажу, что менеджеры по продуктам не обязательно должны быть программистами или инженерами, но они должны быть технически подкованы.

Для прокачки технических скилов я закончил курсы Manual QA и Python и какое-то время проработал Manual QA. В совокупности это дало понимание цикла разработки продукта, технических ограничений, опыт оценки задач и т. д.

Со временем у меня сложился набор hard & soft skills, которые по моему мнению, необходимы менеджеру продукта:

Hard skills

  • Продуктовая стратегия (анализ целевой аудитории, определение продуктовой и ценовой стратегии, анализ конкурентов).
  • Аналитика (определение и понимание метрик, знание методологий тестирования).
  • Процесс разработки продукта (тесты гипотез, построение стратегии роста и оптимизации).
  • Исследование (качественные и количественные исследования, Customer development, исследование рынка, исследование и создание customer journey map).
  • Дизайн (понимание лучших практик в UX/UI, совместная работа над дизайном продукта).
  • Экономика (понимание микроэкономики, юнит-экономики, бизнес-модели).

Soft skills

  • Коммуникация и презентация (практики переговоров, предоставление и получение отзывов, делиться знаниями, работа с командой, презентация видения).
  • Лидерство (понимание и взаимодействие с типами лидерства).
  • Time management (работа с приоритетами, умение делегировать).
  • Стремление (на уровне себя, команды, компании).
  • Критическое мышление (развивать умение думать out of the box).
  • Ответственность.
  • Работа с заинтересованными сторонами.

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

Как устроиться на работу Product manager

Когда вам будет казаться, что вы уже готовы и ваши навыки соответствуют тому списку must have skills, который вы для себя составили, смело начинайте поиски, откликайтесь на вакансии и ждите собеседований. Скорее всего, первые пару собеседований, вы провалите с треском, по крайней мере, так было у меня. Но в этом есть огромный плюс, я смог понять, какие еще остались слабые стороны, требующие развития. Так как зачастую мы крайне редко можем честно признаться себе в своих слабостях, особенно после того, как уже было потрачено определенное количество времени для прокачки себя. Кто бы что ни говорил, собеседование — это стресс. Поэтому опыт прохождения собеседований поможет чувствовать себя увереннее, и здесь, к слову, еще поможет ваш soft skill — коммуникация и презентация.

Свою первую позицию в роли junior Product Manager я получил после удачного знакомства с одним из собственником компании на какой-то ИТ-конференции. Я рассказал (презентовал) ему идею для приложения. Скажу сразу, приложение мы не реализовали, но ему понравилось мое видение продукта, анализ рынка, customer development, который я проделал. И в итоге после еще нескольких собеседований с сотрудниками компании, мне предложили позицию ассистента Product Manager в одном из проектов.

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

Курсы:

Книги:

Мария Шевченко, Product Manager в SoftServe

4 года в профессии

Одно из ключевых правил развития (неважно — в продуктовом менеджменте, шоссейнойм велоспорте или в трейловом беге) — это выход из зоны комфорта. Обожаю выражение: You need to be comfortable being uncomfortable.

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

В марафоне главное — пробежать первые 40 км, а в своем развитии — не прекращать пробовать что-то новое.

Люди

Окружите себя теми, кого считаете профессионалами. Физически — посещая митапы, лекции, конференции и другие офлайн-мероприятия. Я доверяю всем событиям Projector, Growth Marketing Stage и Grammarly — пока что они лидеры в продуктовых ивентах.

Диджитально — подписываясь на людей в соцсетях, читая их блоги и/или рассылки, слушая вебинары и/или онлайн-лекции. Слушайте, слышьте, расширяйте свой словарь и круг общения. Люди — ключ ко всему. Вот малая часть людей, на которых советую подписаться: Олег Якубенков (GoPractice курс и блог), Родион Сорокин (service design), Женя Клепа (стартапы и вот это вот все), Саша Трегуб (главный в Projector), Дима Миндра (человек-вдохновение и человек-постоянная-учеба), Вова Смирнов (дизайн-директор в spiilka design buro), Ваня Замесин (META, custdev.me), Дима Лисицкий (influ2), Миша Нестор (CPO Kyivstar), Алена Возная (EVO company).

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

Кейсы

Это может быть дополнительная задача на вашей текущей работе или параллельный проект вместе с коллегой. Ваш собственный онлайн-магазин чего угодно или благотворительный пет-проект. Пройдя весь путь от возникновения идеи до первых\десятых продаж, вы на себе опробуете то, о чем читали и прокачаете и hard skills, и soft skills.

Можно долго учить теорию, но пока вы не наделаете своих ошибок на практике — вы не научитесь должным образом. Спросите у вашего окружения, кому нужен продакт-джун, и вам точно что-то посоветуют. Тем более, если бесплатно (хотя я свято верю в то, что любая работа должна оплачиваться). Идите на хакатоны, практикумы и другие мероприятия, где сможете быстро наделать много ошибок. Берите на себя больше ответственности на работе и вне работы — комитмент перед авторитетными для вас людьми окрыляет и дает тот самый пинок под зад, которого не хватало.

Контент

В любом виде, который вам ближе — видео, аудио, блоги, книги, статьи. Тогда, когда вам комфортно — по пути на работу, на пробежке, утром или перед сном. На том языке, который ближе (английский в идеале, но лично мне не весь контент поддается пока что). С радостью делюсь своей подборкойи надеюсь, что она будет полезной.

Ключевой момент в том, чтобы потреблять информацию осознанно. Это значит не читать ради поста в фейсбуке о том, что ты прочла/прочел, а читать вдумчиво, сфокусированно, пребывая в состоянии потока. Мне помогают заметки на полях (буквально), телефон экраном вниз с flight mode, конспектирование и написание мини-обзора книги/статьи после прочтения/прослушивания.

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

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

Когда в сутках достаточно часов, или Почему стоит научиться грамотному планированию

$
0
0

[Павел Обод — основатель Growth Factory — обучающей платформы для IT-предпринимателей, организатор конференции Outsource People, CEO Sloboda Studio — RoR agency]

Тайм-менеджментом я интересуюсь очень давно. Изучал много материалов, пробовал разные методики, рассказывал о них знакомым. Первые тренинги проводил еще будучи студентом в 2005 году, в том числе для моих же преподавателей.

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

Планирование: почему и зачем

Мне кажется, есть два основных типа личности по отношению к тайм-менеджменту. Первые склонны все структурировать, планировать, не любят импровизацию и любят предсказуемость. Вторые — более хаотичные, со множеством идей и вечной нехваткой времени для их реализации. Я отношу себя ко второму, более хаотичному типу.

Как хаотичному человеку, мне очень нужно планирование. Соотношение удовлетворенностью результатами спланированного и хаотичного дня по ощущениям — примерно 10:1. Часто план даже не обязательно записывать — достаточно, что он есть в голове и задает структуру будущего дня.

Почему, на мой взгляд, люди не планируют:

  • Не умеют и не знают, как это делать.
  • Не понимают, как это использовать.
  • Не хотят себя напрягать, ограничивать.
  • Заменяют результат процессом: «Я буду что-то делать, и что-то получится». Потом вы полдня проверяете почту, а денег все так же нет.
  • Наша человеческая природа — отчасти против планирования. Миллионы лет существования человечества никаких планов мы не составляли.

Есть мнение, что только 10% людей пишут планы, но 90% из них — самые успешные и богатые. Мне кажется важным, что планирование коррелирует с достатком. Наверняка есть богатые люди, которые не планируют свое время. Но тем, кто добивается успеха своими усилиями, в том числе с помощью бизнеса — очень полезно планировать.

Зачем я планирую свое время:

  • 10 минут планирования экономят мне несколько часов работы за счет расстановки приоритетов.
  • Спокойствие и фокус — иногда я тревожусь, что забыл что-нибудь важное. Выписать все свои задачи по приоритету на обычном листе А4 очень успокаивает и упорядочивает.
  • Планирование помогает явно расставить приоритеты, например, по принципу Парето 20 на 80.

Планирование на день

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

Поэтому у меня договоренность с Сашей Гаврилюк (моим партнером по проекту Growth Factory Academy), что до 10 утра я скидываю ей свой план на день. Гораздо легче придерживаться дисциплины, когда другой человек помогает ее контролировать. Если не присылаю план вовремя — то перечисляю деньги в пользу благотворительной организации.

Мой план на день выглядит примерно так:

Задачи я распределяю по приоритетам A, B, C.

Buffer — время на те задачи, которые появляются в течение дня.

Watchdog — задачи, выполнение которых нужно проконтролировать за другими людьми.

Entertainment — разные веселые ссылки, которые мне присылают.

Small — мелкие таски, которые нужно не забыть сделать, тоже с приоритетами A, B, C.

Итак, мои принципы составления списка:

  • Не привязываться ко времени.
  • Заполнять до 10:00 ежедневно.
  • Заносить в него задачи, которые занимают порядка 30 минут. Более крупные — делить, мелкие — укрупнять.
  • 40% времени оставлять свободным на случай непредвиденных дел.

Такой подход называется гибкое планирование — мои задачи не привязаны ко времени.

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

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

Можно оставить пустые окна на случай срочных задач.

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

Если в течение дня все же случилась какая-то фигня и забрала у вас полдня — то вы просто садитесь и снова переставляете блоки времени.

А главное — иметь немного буддистскую уверенность в том, что все равно всё ты не успеешь, и главное — успеть сделать важное.

Карта жизни

Один из инструментов, которым я активно пользуюсь — это карта жизни. Я делаю ее примерно с 2009 года. Никакой мистики, она просто работает как элемент целеполагания. Такой картой вы ставите себе наглядные цели — чего бы вы хотели достичь в течение 2-3-5-10 лет.

В классическую карту жизни включают такие пункты:

  1. Бизнес/работа — лучше писать конкретные цифры/показатели, которые отражают желаемое состояние, например: количество сотрудников, новый офис, направление или бизнес.
  2. Духовное развитие — не обязательно речь о мистике или религиозных целях. Это внутреннее состояние, которого вы стремитесь достичь.
  3. Семья ваших родителей и что бы вы хотели для них сделать.
  4. Путешествия и учителя/менторы — страны, в которых вы хотите побывать. Менторы, с которыми хотите пообщаться — тоже здесь.
  5. Обучение — это и классическое образование, и языки, и бизнес-образование.
  6. Творчество и дети. Они объединены в один раздел. Это любое творческое развитие, например театр или музыка. Тут же — что бы вы хотели сделать для своих детей и любые социальные проекты в помощь детям.
  7. Личная жизнь — дети и родители уже были в предыдущих пунктах, а здесь — ваша супруга/супруг, отношения, понимание, путешествия вдвоем. Даже если у вас есть дети — отдых без них тоже иногда нужен.
  8. Материальные вещи — такие как машина, дом, квартира, гаджеты.
  9. Здоровье — разные виды спорта, активности, в которых вам бы хотелось участвовать.

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

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

Посчитаем затраты времени

У нас есть ограниченное количество времени, и его не может хватить на все. Вся наша жизнь — это разные роли, которые мы выполняем. Время на них надо распределять и планировать. Вот мой пример:

ВсегоСобственник бизнесаСотрудник своего бизнесаСпортсмен/Здоровый человекМуж и отецСынСтудент
100%10%40%15%15%10%10%
часов936141499

Количество свободных часов в неделю я считал исходя из 7 часов сна в сутки плюс 4 часа на текущие дела — еда, транспорт и т.д. У меня остался 91 час, которым я реально могу распоряжаться. В вашем случае эта цифра, вероятно, будет другой, зависящей от индивидуальной ситуации.

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

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

Как это работает для меня

Сейчас у меня порядка 6 проектов, которыми я активно занимаюсь. Больше всего времени уходит на Growth Factory Academy, в частности, сейчас очень много времени требует подготовка к январскому Growth Factory Academy Camp.

Второй мой проект — своя IT-компания Sloboda Studio. Сейчас она требует не так много времени — там прекрасный операционный директор.

Третий — учу немецкий язык.

Четвертый — спорт — бег, альпинизм, раз-два в неделю йога и иногда плавание.

Пятый — активно занимаюсь инвестированием.

И шестой — семья. С дочкой я обязательно провожу 2-3вечера в неделю, но, как и у многих родителей, у меня есть чувство, что я уделяю ей слишком мало времени.

Родителям мы с братом купили дом, я навещаю их 2-3раза в неделю и раз в неделю обязательно ужинаю с ними. Раз в год-два организую большое семейное путешествие с родителями — моими и жены.

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

В целом жизнь выглядит как жонглирование: уделяешь время детям — не хватает на здоровье, уделяешь здоровью — забираешь у работы или образования.

Мне очень нравится идея, которую, я надеюсь, вы вынесете из этой статьи: не говорить «У меня нету на это времени», а говорить «У меня другие приоритеты».

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

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

Итог

Если вы решили попробовать планирование, советую подход «от крупного к мелкому» по такой схеме:

  1. Подумайте, что вы хотите видеть в жизни через 3-5лет и любым способом визуализируйте это. Мне удобно пользоваться структурой «Карты жизни» — она разносторонняя и наглядная.
  2. Посчитайте, сколько времени в неделю у вас занимают разные роли и подумайте, как вы хотели бы распределить это время через 2-3 года.Запишите желаемое распределение.
  3. Составляйте план на каждый день с распределением задач по приоритетам и старайтесь выполнить хотя бы самые важные дела.
  4. Нельзя успеть всё, но можно успеть очень многое — гораздо больше, чем без планирования.

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

Опитування: рейтинг мов програмування


Чи є життя після macOS, або Як я переїхав на Linux десктоп і не шкодую

$
0
0

Ось уже третій місяць поспіль для щоденної роботи я використовую Linux. Як людина, що до останнього їла кактус Тіма Кука, але змогла зіскочити, я ділюсь з вами досвідом переїзду з macOS на Linux та заохочую робити те саме.

Початок

З 2007 по 2015 я працював на Windows. На роботі в мене спершу був десктоп з Windows NT 2003, здається. Потім я переїхав на ноутбук ThinkPad. NT 2003 оновили до Windows 7. На той час я 100% працював з Java, тому проблем у мене не виникало.

У 2015 я змінив роботу, і там отримав MacBook Pro 13″ 2015 у мінімальній комплектації, з 128 GB SSD та 8 GiB RAM. Я досить швидко освоївся та нарешті збагнув, чому всі розробники на конференціях використовували макбуки та писали про них в статтях, туторіалах тощо. Це ж юнікс для людей! Жодних проблем зі встановленням усіляких SDK, бібліотек, інструментів. Жодних проблем з компіляцією того, що для Windows потребувало б якого-небудь Cygwin або MinGW. Чудовий UI, наявність усіх необхідних програм. Усе круто, я був задоволений, мені подобалось користуватися моїм ноутбуком. Особливо тачпадом — він не люфтив, точно передавав усі рухи та жести. Спочатку я продовжував за старою звичкою користуватися мишею, та потім відмовився від неї взагалі.

Минали роки. Пам’ять SSD засмічувалася XCode, образами емуляторів, кешами Gradle та npm. Швидкодія знижувалась, оперативної пам’яті для IntelliJ майже завжди не вистачало, система йшла у своп, але я це все терпів. Тому що зручно, тому що звик і тому що тачпад.

Раз на декілька місяців я запускав ncdu та розчищав авгієві стайні на диску. З часом я навіть придбав SD-карту зменшеного розміру, спеціально для макбуків, яка вставляється у слот та не випирає з корпусу. На неї переніс старі проекти та медіафайли.

У 2017 я почав замислюватися про апгрейд, адже вже тоді стало очевидно, що 8 гігабайт пам’яті абсолютно недостатньо для комфортної розробки та існування. Проте Apple почала подавати тривожні знаки: макбук 2016 року випустили без портів, без MagSafe та, як виявилося за певний час, ще й з поганою клавіатурою. Функціональні клавіші замінили на беззмістовний тачбар.

Незважаючи на те що я був готовий витратити 2k+ баксів за оверпрайснутий шматок алюмінію з нульовою ремонтопридатністю та апгрейдабельністю, зламані клавіатури мене зупинили, тож я вирішив чекати. Спочатку покладав надії на 2017 рік, потім на 2018, потім на 2019.

Сумніви

У роки очікування я щомісяця читав на HN пости про те, як все погано у нових моделях, клавіатурине покращуються, процесори перегріваються та тротлять, порти вбивають пристрої, шлейфи переламуються, тачбар не потрібен — і взагалі, схоже, що Apple більше не цікаво виробляти якісну техніку. Люди скиглили, проте продовжували їсти кактуси. Хтось писав про свій досвід переїзду на Linux або Windows, хтось наважувався купити новий ноутбук та страждав. Я ж продовжував абияк існувати зі своїм улюбленим, але таким повільним макбуком та мріяти про той день, коли за три куски я зможу придбати якісну техніку.

У цей час я створив декілька тем на форумі DOU — «лінукс на ноутбуці»та «хакінтош», намагаючись скласти уявлення про актуальний стан альтернативних рішень. Відгуки були дуже різними: хтось вже сто років як сидить на лінуксах і йому ок, хтось стверджував, що я маю залишитися з макбуком, інші казали, що вінда та WSL готові для роботи.

Увесь цей час у мене під столом стояв десктоп із Windows. Нічого особливого — core i7 4770, 16 GiB RAM, AMD RX 570. Там я грав у Counter Strike, писав гітару та голос (адже macOS не підтримує мою досить стару звукову картку, а Windows 7 — підтримує). Час від часу мене накривало, і я думав про те, щоб оновити цей десктоп новим залізом і поставити туди хакінтош, але всі ці рухи якось не надихали. Замолоду я полюбляв порпатися з кряками та іншим варєзом, але зараз хотілося просто натиснути одну кнопку та отримати робочу систему.

Я навіть розглядав придбання старого відра (Mac Pro), але абсолютно неадекватна вартість ($3k) купи застарілого брухту мене зупинила. Моноблоки теж не радували вартістю, mac mini — швидкодією. До macOS я вже звик, та змінювати щось не хотілось абсолютно. Проте регулярне користування вінодвсодекстопом, де все працювало дуже швидко, почало мене підточувати, і зерна сумнівів дали серйозний урожай.

Я замислився про те, щоб поставити на десктоп лінукс і працювати за ним. Люди ж якось живуть? Та й 2019 рік надворі, прогрес не стоїть на місці. Коли моя шхуна ще ходила океанами аутсорсу, всі наші розробники працювали за лінукс десктопами — в когось Mint, в когось Ubuntu — і почували себе чудово. Урешті-решт я вирішив спробувати. Вирішальним фактором виявилось те, що для хакінтоша потрібна була флешка на 16 гігабайт, а в мене була тільки на 4. Шукати чи купувати нову флешку я не хотів, тож пішов на DistroWatchі почав роздивлятися, що там зараз у тренді.

Муки вибору

Я звузив коло дистрибутивів до deb-based, адже, на мій суб’єктивний погляд, вони значно популярніші за RPM та інші арчлінукси і генту. З CentOS я працював багато, та, як правило, імовірність знайти вирішення своєї проблеми на Stack Overflow для CentOS нижча. Тож я навіть не дивився у бік не Debian-based дистрибутивів (окрім Manjaro). Отож, наслухавшись мудрих порад з DOU та ще раз переглянувши рейтинги DistroWatch, я вирішив почати з MX.

Завантажив дистрибутив з офіційного сайту, завантажився з флешки, за 5 хвилин встановив. Я вже не пам’ятаю точно, що не запрацювало, можливо, застарілі версії деяких потрібних мені пакетів (MX базується на Debian), але з якоїсь причини MX мене не влаштував. Далі я перейшов до активно рекомендованого на DOU Manjaro. Завантажив варіант з Xfce, встановив. Після старту виявилося, що не працює Wi-Fi — ніяк не хотів підключатися до моєї домашньої мережі. Порпатися з пошуком необхідних драйверів не було жодного бажання, тож я перезавантажився у Windows та пішов шукати інший дистрибутив.

Я дещо засмутився, адже мені здавалося, що периферія 10-річноїдавності мала б 100% працювати. На секунду я подумав, що насправді лінукс на десктопі такий самий, яким був раніше — без колупання в конфігах нічого не працюватиме, і нічого не змінилося. Тож я вирішив взяти найпопулярніший дистрибутив, тобто Ubuntu.

Ubuntu було завантажено та встановлено, здається, все запрацювало, і я навіть почав налаштовувати SDK, оточення і таке інше, але потім зненацька зрозумів, що GNOME або ж Unity, чи як в них називається графічна оболонка, мені зовсім не до вподоби. Тобто взагалі не подобається. Вони там ще напхали якихось зондів, рекламу і місцевий апстор, коротше кажучи, якось воно взагалі не зайшло, і хоча я вже встановив IntelliJ, налаштував RVM та викачав проекти, все одно вирішив відмовитися.

Я знову засмутився. Невже доведеться купувати флешку на 16 гігабайт та ставити хакінтош? Чи апгрейдити макбук? Але щойно я його відкрив та запустив IntelliJ, то знову сповнився рішучості спробувати лінукс ще раз. Загадавши, що у трьох розробників з моєї шхуни було встановлено Mint, я вирішив дати йому шанс. Як завжди, інсталяція закінчилася за 5 хвилин, і тут — о диво! — під час старту системи я почув звуки привітання!

Невеличке пояснення — чому це мене так здивувало? Річ у тому, що колонки та навушники в мене під’єднано до звукової картки M-Audio Fast Track Ultra. Виробника вже давно купив AVID, картку не підтримують з 2012 року, драйверів на новий Windows та macOS вище Snow Leopard нема і не буде. А тут Mint підхопив її, більш-менш коректно сконфігурував входи-виходи і встановив як аудіопристрій за замовчуванням. Моє серце розтануло. Автоконфігурація звукової картки означала, що я тепер можу жити в одному оточенні — працювати, грати на гітарі та в CS:GO, без перезавантажень, реєстрації та СМС.

Зовнішній вигляд оболонки Cinnamon мене теж дуже потішив — із всіх протестованих (GNOME, KDE, i3) ця виявилась найгарнішою.

Робоче оточення

Коли я ще ходив під вітрилами на своїй шлюпці, то бачив, що один з кофаундерів, який працював якраз на Mint, мав проблеми зі Skype — MS чи то не підтримував десктопну версію, чи підтримував її погано, одним словом, йому доводилося працювати у Web-клієнті.

Виявилося, що зараз завдяки тому що весь софт Electron-ізовано та запаковано, проблем з програмами для лінуксу немає жодних. Майже в усіх виробників, програмами яких я користуюсь, є версія для Linux, яка функціонально нічим не відрізняється від інших платформ. Тож з точки зору програм переїзд був простим та безболісним. Зупинюся на задачах, аби було приблизне розуміння, що мені потрібно: щодня я займаюся розробкою на Java, Ruby on Rails, Python, Node.js та трішки фронтендом. Отож, що я використовував на macOS та що так само використовую на Linux:

  • IntelliJ IDEA — основний інструмент, який годує мене вже десяток років. Працює, звісно, без проблем, тому що JVM.
  • Telegram, Skype, Slack, Viber, Zoom — месенджери та відеоконференції теж всі працюють без проблем, що нативні, що з-під електрону.
  • Браузери — Firefox, Firefox Developer Edition, Firefox Beta, Firefox Nightly, Iridium. Я навіжений і для кожного замовника чи проекту тримаю окремий браузер, щоб не перетиналась пошта, акаунти для браузерів тощо. Тут теж все зрозуміло — працює як треба. На macOS я теж користувався Firefox. Так, я знаю про профілі, але вони мені не подобаються.
  • Steam — пограти в Counter Strike: Global Offensive (який працює під лінуксом нативно).
  • Discord — працює ок, але крашиться раз на годину. Проблему маю не лише я. Жити можна.
  • Postman, VS Code (майже не використовую) — абсолютно аналогічні тому, що є під Windows aбо macOS. Слава електрону.

Ось і весь десктопний софт, який я використовую щоденно. Міграція минула без проблем, буквально за один вечір. MS Office в мене не встановлено, вистачало Numbers. Натомість в Linux є LibreOffice, ніби норм, але я ним не дуже користуюсь — немає потреби. Фотошоп мені не потрібен та не був встановлений на macOS. iTerm успішно був замінений місцевим терміналом. Я не користувався особливостями iTerm, тому мені норм. Зверху поставив Oh My Zshз такими самими плагінами та темами, як і на macOS. Крім того, звісно, було встановлено купу софту для розробки: перш за усе RVM, потім Node, Pyenv, Docker, нативні бібліотеки для PG/MySQL/Redis і т. д., те, що під macOS не завжди встановлюється без нюансів (хоча команда brew працює круто, тут жодних заперечень).

До речі, Docker я практично не використовую саме як робочий інструмент (знаю, що дехто піднімає собі базу даних або інші сервіси) — так, інколи перевірити, що контейнери коректно збираються. На macOS докер я не встановлював (тому що немає місця та тому що раніше він потребував додаткових програм для віртуалізації — не впевнений, як зараз з цим справи), але під лінуксом все працює дуже швидко. І білд, і запуск.

Минуло декілька днів, і я відчував себе майже як риба у воді. З робочими питаннями я розібрався, залишилося лише дещо підлаштувати: хоткеї та інші системні речі.

Система

Найболючішим питанням при зміні оточення для мене виявилася зміна хоткеїв, до яких я звик. На лінуксах вони, звісно, досить сильно відрізняються від macOS. Я вирішив спробувати переналаштувати клавіші під ті, які мав на macOS. Для цього я замінив місцями клавіші Win та Alt (клавіатура у мене з Windows-розкладкою, HyperX Alloy FPS на MX Red), перебив Alt+Tab на Win+Tab, вихід з програм на Win+W, одним словом — влаштував собі macOS для бідних :) Все це можна було зробити через UI, без редагування конфігурації.

Також вирішив питання з розкладкою. На macOS я користувався модифікованою розкладкою Іллі Бірмана, яка містила третій шар для російських букв ы э ъ ё, таким чином для набору текстів кирилицею мені не доводилося переключатися між українським та російським варіантами клавіатури. Приблизно тиждень я не поспішаючи шукав таке ж рішення, врешті-решт знайшовта підправив від себе (тут довелося трішки попоратися з конфігами). Переключення локалі по Caps Lock налаштовується через UI.

Аналог f.luxназивається Redshift, хоча виглядає він не так гарно (а радше — взагалі не виглядає, для GUI треба встановлювати окрему програму). Для музики є досить адекватний Rhytmbox. Система оновлює себе нашим улюбленим apt-get update && apt-get upgrade — взагалі без проблем. Ті, хто мали справу з побудовою докер-образів, не пропадуть. Томи з NTFS автоматично підхоплюються на запис без додаткових налаштувань. Wi-Fi працює як треба, хоча деколи (раз на тиждень, або ще рідше) відвалюється та потребує перезапуску. Профілі для VPN можна встановлювати відразу у .ovpn форматі і відкривати через мережеві налаштування — не потрібно ставити ніяких TunnelBlick!

На жаль, не всі програми можуть підхопити мою круту звукову картку з не менш крутим конденсаторним мікрофоном як пристрій введення. Виведення — так, тут без проблем. А ось введення — ні. Я гадаю, що це якось вирішується, але поки що не хотів витрачати на це час. У мене є веб-камера з хорошим мікрофоном (яка, до речі, теж запрацювала з коробки). Але на macOS звукова картка взагалі не працювала, тому до лінуксу тут в мене претензій жодних. Хоча може якось знайду час, зберу докупи всі ці Jack, ALSA, PulseAudio та інші штуки — і радуватиму співбесідників оксамитовим голосом.

Зі шрифтами та згладжуванням у мене проблем немає. Працюю я за тим самим екраном, який підключав до макбука як зовнішній (Dell U2415, 16:10, 1920×1200), тож різниці не помічаю. Додаткових налаштувань я не робив. Suspend/resume працює без проблем. Кажуть, що на ноутах з цим негаразди, підтвердити чи спростувати не можу. На десктопі аптайм кілька тижнів стабільно. Перезавантажуюсь у Windows лише для звукозапису.

Ось як виглядає мій десктоп. Основні інструменти — IntelliJ IDEA та купка браузерів. CS:GO у віконному режимі, щоб розбавити воллпапер, граю я у фулскріні, звісно.

Проблеми

Декілька проблем з софтом та системою, які я так і не зміг вирішити або вирішив не інвестувати в них час:

  1. Відсутність ⌘+c/⌘+v. За роки роботи я вже настільки до цього звик, що змінити м’язову пам’ять було складно. В терміналі можна налаштувати цю комбінацію, але для всієї системи — зась. Доводиться пам’ятати, де ти зараз знаходишся, та натискати відповідні клавіші.
  2. Cinnamon чомусь вважає ок вішати на F10 системний хоткей (виклик меню). Довго не міг зрозуміти, чому в мене не закривається mc. Як відключити цю поведінку для всієї системи, не лише для терміналу, не знайшов.
  3. Те саме, тільки для Alt+клац мишкою. На macOS в IntellIJ таким чином працювало блочне виділення, а тут викликається якийсь системний менеджер вікон — абищо, коротше кажучи.
  4. Неможливо нормально відрегулювати швидкість миші. У мене миша Razer Deathadder, там досить висока роздільна здатність та, відповідно, висока швидкість курсору. Мінімальна швидкість для мене все одно занадто висока. Спробував щось там конфіжити через XInput, проте не допомогло. Урешті-решт просто змирився і забив, проблем руками буде менше. CS:GO вміє читати сирий потік з миші, тож там можна відрегулювати все як треба.
  5. В IntelliJ не працює мапінг клавіші win для хоткеїв, тобто не можна собі зробити ⌘+n для пошуку класу, потрібно CTRL+N натискати. Вже звик.
  6. Середня кнопка миші працює як CTRL+V, ще не знаю, як це відключити, але й не надто шукав.
  7. Спелчекер в FF якось дивно перемикає мови. Іноді не перемикає взагалі та детектить англійську як кирилицю і навпаки.
  8. За відчуттями, FPS в CS:GO дещо нижче, ніж під Windows, 100 проти 150-200,десь так. Хоча я все одно не перезавантажуюся та катаю з хлопцями під лінуксом. Драйвери на відекарту AMDшні.

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

Ітогі падведьом ©

Уже три місяці Linux Mint є моїм основним середовищем. Макбук я відкриваю надзвичайно рідко, щоб скопіювати якусь конфігурацію або секрет, які не переніс раніше, щоб подивитися відосик у ліжку та деколи — щоб попрацювати на кухні. Також, поки я не купив новий ноутбук, макбук залишається тревел-девайсом. Зараз я нікуди особливо не їжджу, сиджу вдома, але розмірковую потроху про покупку ноуту, щоб поставити туди лінукс. Кажуть, що Thinkpad’и для цієї справи гарні, і я б залюбки придбав щось на кшталт такого.

Доки писалася та версталася ця стаття, Apple випустила 16″ макбук з фізичною кнопкою Esc та виправленою клавіатурою, що не ламається від крихт та пилу. Носити такого велетня у рюкзаку я не хочу, та й за macOS я, чесно кажучи, не надто сумую. Тачбар не потрібен, USB-C не потрібні — ну ви зрозуміли.

Також запропонували новий Mac Pro за космічним прайсом (з люто оверпрайснутою RAM), але віддавати $6k за залізо, яке, за відчуттями, навряд буде швидшим за мій десктоп, щось не хочеться. Та й, загалом, $6k для мене — це надто багато за залізо (навіть якщо це не включало оверпрайс за яблуко, а було лише ціною власне комплектних деталей). Я, на жаль, ще не маю такого рівня статків.

Зараз ще й AMD випустила Threadripper’ів купу, тож можна недорого докупити 24 ядра і непогано себе почувати. Утім, мені цілком вистачає чотирьох інтелівських, навіть з патчами на Meltdown та інші дірки камінців Intel.

...

Лише півроку тому я гадав, що нікуди не дінусь з macOS. Хоткеї, софт, звички здавалися мені непохитними. Утім, людина швидко адаптується. Буквально за два тижні після переїзду я вже почував себе комфортно та збирався писати цей матеріал, але вирішив почекати ще трошки, аби відловити усі проблеми та переконатися, що я дійсно можу працювати під лінуксом на довгій дистанції.

Тепер я можу зробити однозначний висновок — лінукс на десктопі живе. Можливо, ви маєте свої вимоги до софту, який є винятково під Windows або macOS, але я особисто вважаю, що для бекендера/дата-саєнтіста/фронтендера/андроїд-розробника Linux є відмінним вибором та повноцінною заміною macOS.

Тепер що стосується саме макбука. Уважний читач помітить, що весь матеріал присвячений саме десктопу і софту, а не тачпаду та блискучому алюмінієвому корпусу. Я не писав про вибір ноутбука, тому що ще цим не займався. Але найімовірніше дивитимуся у бік ремонтопридатних ноутів. Якщо все працює на десктопі — значить, можна завести на ноуті.

Швидкість та апгрейдабельність

А ось що мене тішить у новій робочій станції понад усе — то це швидкість її роботи. Я неодноразовописавпро важливість хорошого робочого заліза, швидкості збірок та компіляцій для щоденної роботи. У мене старий процесор — core i7 4770, лише 16 гігабайт пам’яті, дешевий SSD Crucial (адже матплата в мене теж стара та не вміє завантажувати систему NVMe, до того ж немає m.2 слоту), і все це працює суб’єктивно просто в рази швидше за макбук (на якому, між іншим, процесор на кілька поколінь старший та й SSD, напевно, не гірший). Настільки швидше, що я не чекаю, доки відкриється проект в IntelliJ, браузери відкриваються моментально, збірка Webpack навіть не встигає підняти оберти штатного вентилятора, і взагалі все гаразд.

Я майже не дивлюся в htop і не цікавлюсь, що ж з’їло всю оперативну пам’ять. Я припинив користуватися ncdu та індиферентний до оновлень системи, кешів, логів та іншого мотлоху, який залишають за собою програми у процесі життєдіяльності.

В перші тижні у мене було відчуття, наче до цього п’ять років бігав з вантажем на ногах — настільки швидше все почало працювати. Я навіть відчував легку ейфорію та бажання попрацювати (чого зазвичай зі мною не трапляється). Тепер організм уже звик до високої швидкості та сприймає це як належне. Кілька днів тому відкрив макбук подивитися кіно і був вражений, наскільки той повільний.

Тепер я знаю, що якщо завтра мені потрібно буде додати потужності, то я зможу просто купити новий процесор або матплату + процесор. Поставити одне замість іншого, і життя знову заграє швидкістю. Не потрібно думати про мотлох на диску — якщо треба буде збирати товсті образи або перемелювати бігдату, я просто прикуплю SSD за $50 і буду щасливий.

Я ніби повернувся назад у дитинство, коли за браком коштів доводилось лише дивитися на прайс-листи, огляди та рекламні проспекти у журналах «Компьютерное обозрение» та CHIP, тільки тепер можна купити все, що там продають, і зовсім не потрібно чекати, доки Apple поверне модель 2015 року, з нормальними портами, магсейфом та можливістю проапгрейдити або відремонтувати пристрій.

Якщо ти, читачу, все ще сидиш за старим макбуком, я гадаю, що ти тепер знаєш: за межами macOS життя є.

Fin.

Якщо вам сподобалося, як я пишу, то долучайтеся до мого телеграм-каналу.

«Зарплата інженера-програміста в оборонній сфері — $600-700». Як працюють військові розробники в Україні

$
0
0

Наскільки схожа робота IT-фахівця у приватному секторі й робота того, хто працює в лавах Збройних сил? Чи можливо застосовувати новітні підходи в розробці у сфері, яка доволі забюрократизована й закрита для цивільних спеціалістів? Чи можуть наші військові програмісти конкурувати з закордонними?

Про те, як це — бути розробником програмних рішень, які безпосередньо впливають на обороноздатність країни в умовах війни, військовослужбовці з підрозділу розробки Міністерства оборони України Єлизавета Бойко та Сергій Гальчинський розповіли в інтерв’ю DOU.

Сергій Гальчинський та Єлизавета Бойко (по центру) на Хакатоні НАТО у 2017 році, де українська команда виборола два перших місця

Баланс між навчанням і фізпідготовкою

Єлизавета Бойко:Після школи я захотіла стати програмістом і подала документи до різних вишів включно з Військовим інститутом телекомунікацій та інформатизації, на той час — Військовим інститутом при КПІ. Він, зокрема, набирав абітурієнтів за напрямком «Комп’ютерні науки». Я вступила й туди, й на кілька факультетів Київського політехнічного інституту, але обрала військовий, адже він мав непоганий рейтинг і фізичну підготовку на рівні.

Я пройшла шлях від курсанта з першого по п’ятий рік та підписала свій перший контракт зі Збройними силами України. Через те що нині діє особливий період, ти не можеш розірвати контракт за власним бажанням. Якщо до цього, не в умовах війни, ти міг піти раніше, ніж за п’ять років, то наразі маєш у будь-якому разі відслужити.

Я вважаю, що підрозділ, в якому я зараз перебуваю, є унікальним, адже ми дійсно працюємо за тим напрямком, який вивчали в університеті: я п’ять років вчилася програмувати й зараз свій час на роботі присвячую саме програмуванню.

Жодного дауншифтингу, я є таким самим розробником, як і ті, хто працює у недержавній сфері.

У своєму підрозділі відчуваю себе на рівні, утисків немає. Але якщо ти виходиш за наш підрозділ і комусь кажеш, що не просто папери перебираєш, а вмієш писати код, на тебе можуть подивитися з недовірою. Це, мабуть, залежить від адекватності людей, яких ти зустрічаєш. В армії є стереотипи, дуже жорсткі стосовно жінки загалом, не обов’язково програміста. Але в моєму оточенні такого немає.

Сергій Гальчинський:Мій життєвий шлях доволі схожий. Все розпочалося зі вступу до Військового інституту. Я орієнтувався на те, аби був баланс між освітою і фізичним вихованням, адже не хотілося просто сидіти за монітором.

Вчився ще до того, як почалася війна. Після випуску я та колеги мали варіант піти з військової сфери до цивільної і займатися професійною розробкою, бо тоді не існувало достатньої кількості посад у війську, де ти міг би професійно реалізуватися. Але ми розуміли, що можна за допомогою своїх знань допомогти країні в секторі оборони, якимось чином конвертувати це у військовий потенціал. Тож почали займатися розробкою.

Хоча насправді це велике щастя, якщо ти вчився на розробника у Військовому інституті і потрапив на посаду, яка передбачає розробку, адже у сфері оборони тебе називатимуть не військовим розробником, а зв’язківцем. І зазвичай ти обіймаєш посаду, яка передбачає роботу із засобами зв’язку. А перспективи зростання взагалі жодної.

Єлизавета Бойко у 2018 році на Coalition Warrior Interoperability eXercise — щорічних багатонаціональних навчаннях НАТО та країн-партнерів

Специфіка роботи й зарплата тих, хто служить

Сергій:Зараз відбувається переворот. Якщо раніше військова сфера диктувала технологічні інновації у світі, зараз бізнес диктує правила того, як має жити IT, як повинні розвиватися технології, оптимізуватися процеси тощо. Сьогодні приходить розуміння того, що оборона, державна сфера, має адаптуватися до цих змін.

Найбільша проблема полягає в тому, що рівень фінансового забезпечення IT-фахівців тут доволі низький. І якщо виникає вибір — залишитися у військовій сфері чи піти до цивільної, — більшість кваліфікованих спеціалістів вирішують піти. Вони розуміють, що їм потрібно забезпечувати свої сім’ї, покращувати власне матеріальне становище, тож ситуація доволі сумна.

Бути військовим IT-фахівцем набагато складніше, ніж працювати у цивільній сфері. Тут є низка речей, які мають високий поріг входження. Для того аби почати розробку специфічних військових систем, ти маєш розуміти специфічні технології, знати специфічні протоколи, які використовуються. Крім цього, ти ще маєш працювати згідно зі стандартами НАТО. Знайти такого фахівця на ринку доволі складно. Якщо він уже виріс у військах і розуміє цю предметну галузь, важливе завдання для держави — втримати його, аби він і надалі працював у цьому напрямку і передавав знання наступним поколінням спеціалістів, які приходитимуть.

Наш стек технологій варіюється від низькорівневих речей, де потрібно інтегрувати специфічні рішення, до розробки на Spring Framework для наших сервісів. І через це доводиться читати величезну кількість ресурсів. Плюс — специфіки додає те, що ми працюємо з речами, які в принципі можуть бути не задокументовані. Це, наприклад, натівські розробки, які передбачають, що ти підписуєш NDA з вендором, який її винайшов. Він ділиться внутрішньою документацією під своїм грифом, а тому, коли ти стикаєшся з проблемами в реалізації, банальний пошук в Google тебе не врятує, адже така інформація взагалі не циркулює в мережі.

Поки що, на жаль, існує значний відтік кадрів — люди, які залишаються після випуску військових вишів, бачать зарплату і йдуть. Але ситуація змінюється. Зараз ми бачимо, що є прагнення створити нові підрозділи, які матимуть краще фінансове забезпечення.

Наразі середня заробітна плата, наприклад, інженера-програміста в оборонній сфері — це приблизно 600-700 доларів.Тобто можна зрости до Senior developer’a й все одно отримувати ці гроші.

Проблема в тому, що для того аби стати військовим розробником, потрібно обов’язково мати звання військового й бекграунд Computer Science. У нашому випадку ми беремо на службу курсантів — студентів військових вишів. Та лише одиниці з них ідейно мотивовані, залишаються і продовжують роботу.

Існує значний відтік кадрів — люди, які залишаються після випуску військових вишів, бачать зарплату і йдуть.

На щастя, зараз є тенденція до зміни умов найму — згодом не потрібно буде мати звання військового, аби потрапити до команди розробників в оборонній сфері. Тобто з’явиться можливість найму розробників з приватного сектору. Будемо сподіватися, що це станеться найближчим часом. Чи це небезпечно для ЗСУ? Ні, адже існують процедури, які регулюють такі речі. За таким принципом, до слова, працюють і наші західні колеги-союзники. Компанії-вендори чи конкретних розробників може перевіряти, наприклад, СБУ. З часом вибудується довіра з цими людьми, й можна буде легко працювати.

Всі ті недоліки, які сьогодні існують в оборонній сфері в секторі розробки — це комплексна проблема, де кожен фактор породжує наступний, а все разом призводить до тієї ситуації, яка є наразі. Низьке фінансове забезпечення зумовлює низький конкурс, до військових вишів вступають переважно люди з меншим потенціалом тощо. Це комплексна проблема, вирішення якої, можливо, взагалі варто було б починати з патріотичного виховання в школі.

Хоча, наприклад, якихось проблем з точки зору обладнання ми взагалі не відчуваємо — якщо йдеться про «залізо», софт тощо.

Робочі завдання та переможні хакатони НАТО

Сергій:Досвіду ведення комерційних проєктів ми не маємо, проте щодня працюємо над вирішенням складних і специфічних завдань.

Концептуально один з проєктів, яким ми займалися, мав на меті ситуаційну обізнаність. Його завданням було інтегрувати всі можливі сенсори, дати можливість працювати на цифровій мапі, вносити інформацію про обстановку, а найскладнішим моментом була реалізація протоколу MIP, який регламентує обмін інформацією між двома інформаційними системами. В межах цього протоколу описується модель даних і метод обміну. Це було доволі складно втілити у життя, але цього року під час міжнародних навчань ми протестували рішення й отримали позитивний експертний висновок. Тестування відбувалося за схожою системою з боку Канади, і за всіма кейсами ми успішно провели його. Це була перемога, до якої ми йшли рік.

Ще у 2017 — 2018 роках брали участь у хакатонах від НАТО, де через консолідацію численних націй, більшість процесів доволі забюрократизовані. І коли стоїть питання спробувати щось інноваційне — це затягується на кілька років, адже потрібно довести, що це дійсно необхідно, вибити бюджет, зібрати команду, яка це реалізовуватиме, тощо. Вони розуміють проблему, тож шукали нові методи пошуку й реалізації інноваційних ідей. В результаті вирішили створити такий варіант збору фахівців, як хакатон, де протягом короткого часу можна зібрати висококваліфікованих спеціалістів і отримати результат: чи то концепт, чи апробацію ідей тощо.

Українська команда комбінованого змагання Хакатону 2018

Єлизавета:У 2017 році Україну як партнера НАТО вперше запросили на Лондонський хакатон, де команди змагалися у трьох напрямках: «Програмування», «Моделювання» та «Комбінація». Україна брала участь у двох напрямках: «Програмування» та «Комбінація». Це був прецедент — ми поїхали на натівський хакатон вперше і вибороли два перших місця.

Нашим завданням було вирішити два проблемні питання. НАТО щоліта проводить спільні навчання на базі в Польщі, й щороку вони готують звіти щодо взаємосумісності різних країн з точки зору програмного забезпечення. Тобто з’ясовують, чи можуть країни обмінюватися інформацією. Щороку ці звіти генерували різним чином та не могли «збити» статистику. Тож у напрямку «Програмування» потрібно було зібрати ці дані докупи й візуалізувати — ми представили міні-макет. Друге проблемне питання полягало в нових підходах до збору інформації з різних сенсорів. Наприклад, з камер дронів, з камер відеоспостереження. Необхідно було знайти нові підходи до розпізнавання облич, сканування тощо. Наша команда за допомогою натівських вендорів змогла представити макет для розпізнавання облич у пропускних пунктах НАТО.

А у 2018 нас запросили до Чорногорії на наступний хакатон. Там ми представили три команди, але розподіл місць був трохи інший: перше, друге і третє відповідно.

Команда, яка брала участь у напрямку «Моделювання», посіла третє місце. Їм треба було проаналізувати вимоги до об’єднаних місій НАТО та запропонувати варіант застосування хмарних обчислень усіма учасниками місії. Для прикладу, питання, які поставали в межах челенджу:

  • Що краще: Cloud On Premise на рівні місії чи використати IaaS/PaaS?
  • Якщо якась з націй надає IaaS, то як здійснювати регулювання?
  • Якщо декілька націй надають IaaS, то як керувати цим?

Рівень цього хакатону був набагато вищим за попередній. Було багато представників з індустрії, а також з державного сектору європейських країн (Великобританії, Данії). Наша команда хоч і посіла третє місце, але я вважаю, що цим можна пишатися, бо, наприклад, друге місце посіла команда від Microsoft.

У моєму напрямку, комбінованому змаганні, потрібно було створити з використанням платних або безкоштовних технологій інструмент, який допоміг би обмінюватися документами всередині структур НАТО, редагувати їх, а також налаштувати інтеграцію, наприклад, у чаті, відео- або телеконференції. Така необхідність виникла, оскільки в НАТО, як не дивно, досі використовують лише імейл. Якщо потрібно, наприклад, знайти якусь стару копію документів, це стає проблемою, адже вони надсилають документ, завантажують його, редагують, надсилають знову... І фахівці не можуть користуватися чимось на кшталт Google Docs — їм потрібно було щось не на базі відкритих ресурсів, а таке, що можна просто розгорнути, а всі нації змогли б користуватися. Наше рішення вибороло перше місце. Команда представила макет. Ми використали open source модливості й створили на базі Nextcloud рішення, яке є ізольованим і закриває усі потреби.

Команда, яка займалася програмуванням, посіла друге місце. Їм потрібно було вирішити проблему інтеграції сенсорів, які існують на полі бою, формування ситуаційної картинки й передачі цих даних до командира, який приймає рішення. І також завданням було репрезентувати на цифровій мапі ті речі, які були інтегровані.

Сергій:Дуже цікаво, коли фахівці з різних країн, які займаються розробкою, збираються на одній локації, спілкуються. Здебільшого такі хакатони не мають на меті змагання. Бо якщо дивитися на ті хакатони, які проводять у сфері IT, переважно там є дух змагання, адже люди борються за кращу ідею, інвестор чи меценати полюють на них та вкладають кошти в розробку продуктів. А НАТО це проводить переважно з метою нетворкінгу. Ти зустрічаєш команду однодумців, обмінюєшся ідеями і намагаєшся зберегти цей горизонтальний зв’язок, аби у міру виконання службових обов’язків зв’язуватися з фахівцями для обговорення тих чи інших питань.

Хакатони фактично подарували шанс поспілкуватися з людьми, які присвятили останні 15-20років життя розвитку інформаційних систем НАТО. Це спеціалісти, які були авторами протоколів обміну міжнаціональних інформаційних систем, і вони мають надзвичайний досвід, яким готові ділитися. Вони мотивують, зміцнюють патріотизм і бажання дати все найкраще своїй нації. З технологічної точки зору — це люди, які зекономили нам дуже багато часу, вказавши на можливі проблеми та шляхи їхнього уникнення, і подарували бачення кращих практик. Ми доволі обмежені в ресурсі, у нас невелика команда, яка займається розробкою, тож за це їм велика подяка.

Українські програмісти отримали нагороди за перемогу в Хакатоні 2018 від Начальника Генерального штабу

Підготовка послідовників

Сергій:Після двох хакатонів ми спробували адаптувати натівську модель проведення змагань між фахівцями оборонного сектору й провести Національний оборонний хакатон. Туди запросили експертів з НАТО в ролі суддів. Самі ж не брали участі, бо в тих напрямках, в яких він проводиться, вже були експертами. Зараз наші вихованці з Військового інституту беруть участь у хакатоні, а ми виконуємо роль менторів.

Такі заходи насправді дуже потрібні, оскільки існує певна проблема — навчальна програма застаріла і не надто адаптована до реалій. А хакатони, лекції від провідних спеціалістів, знайомства з ними дозволяють зрозуміти, як все працює. Ми зі свого боку також намагаємося курсантів забирати до нас на стажування, щоби вони могли працювати на проєктах, якими займається Міністерство, подивитися, як застосовуються технології. Власне, таким чином ми й здійснюємо менторство над ними.

Єлизавета:Загалом проєктам, якими ми займаємося, 3-4 роки,тобто вони побудовані на найновіших технологіях. Тож маємо можливість давати курсантам щось актуальне, а не те, що викладають 20 років в інституті.

Хоча програма Військового інституту не надто відрізняється від КПІ. Вони вчили Pascal, C++, і ми його вчили. Я не вважаю, що наші курсанти не такі розвинуті, як студенти КПІ. Вони отримують той самий набір знань, але мають розуміти, в якому напрямку вони себе бачать, і шукати доступ до новіших технологій.

Сергій:Тут питання особистісне. Вища освіта — це, в тому числі, самоосвіта. Ті, хто хочуть знати, випускаються кваліфікованими. За час навчання знайти те, що тобі подобається, присвятити час глибшому пізнанню — не проблема. Якщо виникають питання, курсанти розуміють, що можуть звернутися до нас, аби проконсультуватися. Якщо ти достатньо мотивований, розумієш, для чого ти це вчиш, то будеш кваліфікованим фахівцем.

Мотивація йти далі

Єлизавета:Як правило, ми працюємо з 8:00 до 17:00. Але я вважаю, що робочий день у нас плюс-мінус схожий на день звичайного програміста, того, який знаходиться поза армією. Оскільки ми працюємо за Agile, спрінти розраховані на два тижні. У понеділок ми плануємо завдання, щодня маємо мітинг, а в п’ятницю, коли дедлайн, презентуємо демо.

Сергій:Реалії такі, що якщо не працювати за сучасними технологіями та практиками, неможливо буде взагалі побудувати роботу. Тому, з одного боку, можливо, ми обмежені певними військовими речами, але з іншого — все виглядає так, як у звичайному IT-секторі. Ми працюємо за Scrum і цілком побудували на цій базі роботу, інакше вона б зіпсувалася.

В армії кожен військовий має службові обов’язки, а тому тут неможливо забезпечити проєктний підхід до ведення тих чи інших процесів. Тож фактично з власної ініціативи ми побудували підхід до ведення нашої роботи. Власне, він себе виправдав за останні кілька років.

Єлизавета:Ми зібрали класичну команду: Front-end розробників, які працюють з React, Back-end, які пишуть на Java, тестувальника, DevOps, системних адміністраторів, тобто маємо стандартний набір. Крім того, налаштований CI/CD. Звичайно, не одразу все стало гаразд, ми довго до цього йшли, але зараз, з постійним зворотним зв’язком від користувачів, маємо реліз, як правило, кожні два тижні, хоча іноді трапляється і рідше.

Я не впевнена, що підписуватиму наступний контракт, але впевнена, що ці п’ять років не минуть даремно.

Сергій:Відмінність у тому, що немає нормального процесу підтримки кінцевих користувачів програмного продукту, певного підходу для його впровадження і решти. Тож якісь завдання лягають на розробників. І вони паралельно надають підтримку користувачам, беруть участь у військових навчаннях, займаються розгортанням цих рішень тощо.

Я довго аналізував, чому працюю в оборонній сфері. Проблема мотивації, мабуть, найбільша з наявних. В цивільному секторі найбільша мотивація грошова: навіть якщо тебе не мотивує проєкт, те, чим займаєшся, ти розумієш, що тобі регулярно надходить сума, яка дозволяє щасливо жити, часто подорожувати тощо. У нас питання особистісне. По-перше, важливе усвідомлення, що ти робиш речі, які впливають на твою державу, її обороноздатність, тобто допомагаєш країні. По-друге — це можливість отримати унікальний досвід, який ніколи в житті ти б не отримав у будь-якій іншій сфері, а також шанс познайомитися з людьми, з якими ти ніколи б за інших розкладів не познайомився. За це я вдячний тим обставинам, в яких опинився.

Фактично ми перші, хто професійно на такому рівні займається розробкою та застосовує сучасні технології і практики. Але це підхід персоналій: існувала певна група людей, які вирішили залишитися, присвятити частину життя цій справі. І якщо не перетворити це на системний підхід, рано чи пізно все зникне. Ми цю думку намагаємося доносити до керівництва. Щоби був життєвий цикл, спеціалісти зростали професійно і потім перетворювалися на сталих архітекторів, які зможуть будувати складні архітектури різних військових систем. Бо наразі це все ситуативне і тримається на окремих особистостях.

Єлизавета:Я тут зайду трохи з іншого боку. Здається, що наше фінансове становище посереднє, якщо порівнювати зі звичайним програмістом. Проте, наприклад, 30 днів своєї відпустки на рік я завжди проводжу в іншій країні. Якщо вміти розпоряджатися фінансами, то все можливо. Мені 24, і я вже знаю, що зробила для своєї країни, бо моя робота вплинула на її рівень. Наша команда виграла хакатон — це 100% не минуло просто так. Люди поглянули на Україну інакше!

Я не впевнена, що підписуватиму наступний контракт, але впевнена, що ці п’ять років не минуть даремно. Зі мною працює дуже гарний колектив, і я знаю, що з ними можна робити класний продукт.

Асинхронность в C#. Разрушение легенд

$
0
0

Всем привет! Меня зовут Влад, я — старший разработчик в компании DataArt. Статья будет посвящена асинхронному программированию на C#, а именно — нюансам работы с TAP (Task-based Asynchronous Pattern) — паттерном асинхронного программирования, основанным на задачах. Статья довольно обширная и разбита на пять разделов:

I. Асинхронность: как и зачем это использовать.

II. Взгляд вовнутрь через популярные заблуждения.

III. Проблемный код и лучшие практики.

IV. Сторонние библиотеки и тулинг.

V. Что еще почитать/посмотреть.

I. Асинхронность: как и зачем это использовать

Что такое асинхронность и зачем она нужна?

Все внешние устройства, не работающие на одной шине с микропроцессором, — сетевые адаптеры, видеокарты, хранилища данных — возвращают результат своей работы не сразу. Следовательно, нам выбирать: либо наш поток выполнения будет останавливаться и ожидать результат операции, либо выполнять какой-то другой код. Таким образом, код, написанный с неблокирующим (асинхронным) ожиданием результата, потребляет меньше ресурсов и является более производительным на дистанции.

Часто начинающие разработчики путают асинхронность и многопоточность. Это разные вещи. Многопоточность — параллельное выполнение, асинхронность — логическая оптимизация выполнения, которая может работать и в одном, и во многих потоках.

Однако многопоточность и асинхронность можно также классифицировать по типам многозадачности, как ее формы:

  • Вытесняющая (Preemptive)многозадачность — вид многозадачности, когда система выделяет каждой задаче некоторый квант времени — реализуется через механизм потоков и Task, выполняющий свой код в многопоточных контекстах.
  • Кооперативная (Cooperative)многозадачность — вид многозадачности, когда система выделяет задаче время до тех пор, пока задача не завершится. Похоже на асинхронные вызовы в однопоточном контексте синхронизации, например UI-поток WinForms или работу движка V8 для выполнения JavaScript.

Изучая асинхронные подходы в .NET, я плохо понимал, как все устроено изнутри. Это не позволяло решать ряд проблем, связанных с асинхронностью.Также слышал разные истории коллег, которые сталкивались с аналогичными проблемами и не всегда знали, как их решить: например, дедлоки или «нелогичное» поведение асинхронного кода. В статье рассмотрим механику работы и лучшие практики TAP: как это устроено изнутри и какие ошибки лучше не совершать.

В .NET-фреймворке исторически сложилось несколько более старых паттернов организации асинхронного кода:

  • APM (IAsyncResult, они же коллбеки) (.NET 1.0).
  • EAP — события, этот паттерн все видели в WinForms (.NET 2.0).
  • TAP (Task Asynchronous Pattern) — класс Task и его экосистема (.NET 4.0).

Сейчас рекомендованный и самый мощный паттерн — TAP. В C# 5 он был дополнен механизмом async/await, помогающим избежать блокирующего исполнения кода, в более новых версиях языка появилось еще несколько нововведений.

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

  • CPU Bound — блокировка, когда поток занят непосредственно вычислениями. Здесь необходимо позаботиться о том, чтобы длинная операция не блокировала потоки пула потоков .NET (ThreadPool), а работала отдельно и синхронизировала возврат результата.
  • IO Bound — блокировка, ожидание результата от устройств ввода-вывода — тут асинхронный подход имеет максимальный эффект, так как, по сути, мы занимаемся ожиданием, и наши потоки могут выполнять пустую работу.

Async/Await идеально решает проблему IO Bound, с CPU Bound можно использовать средства Parallel или неявного создания отдельных потоков, но об этом позже.

Какая бывает асинхронность?

Лично я для себя условно разбил асинхронные подходы на три группы, включив реализации из JavaScript и Golang для примеров.


Классификация подходовПаттерныИмплементация в JSИмплементация в GolangИмплементация в C#
Императивные Saga и ее вариации, коллбеки Redux-saga
ES7 async/await,
передача колбеков
Передача коллбеков,

Select + Channels
async/await, передача коллбеков
ОбъектныйDTO
Объектно-ориентированное представление статуса о выполненной задаче
Promise-Task
РеактивныеObserver/Observable
(pub/sub), Builder
RxJS
Observable
EventEmitter
MobX
ChannelsEvents
Rx.NET

JavaScript, как язык, еще имеет дополнительные средства, генераторы, которых нет в C#, для организации асинхронных операций.

В C# бэкенд разработке нативно меньше реактивных подходов. Основными методами являются либо запуск и менеджмент объектов Task и их неблокирующего ожидания с помощью await, либо коллбеки. Реактивность же чаще используется в UI-разработке.

Однако можно использовать и имплементацию библиотеки Rx под C# для работы с источником событий как с потоком (стримом) и реакций на них.

В этой же статье мы поговорим о нативных способах работы с асинхронностью в C#.

TAP (Task Asynchronous Pattern)

Сам паттерн состоит из двух частей: набора классов из пространства имен System.Threading.Tasks и конвенций написания своих асинхронных классов и методов.

Что нам дает асинхронный подход в контексте TAP:

  1. Реализации фасадов по согласованной работе с задачами, а именно:
    • Запуск задач.
    • Отмена задач.
    • Отчет о прогрессе.
    • Комбинация цепочек задач, комбинаторы.
    • Неблокирующие ожидания (механизм async/await).
  2. Конвенции по именованию и использованию асинхронных методов:
    • В конец добавляем постфикс Async.
    • В аргументы метода можем передавать или не передавать CancellationToken & IProgress имплементацию.
    • Возвращаем только запущенные задачи.

Если хотите подойти к изучению более фундаментально, посмотрите whitepaper на 40 страниц от Microsoft, как это работает. Скачать документ можно тут.

Как создать и запустить задачу

Условно я разделил возможные пути создания задач на четыре группы:

1. Фабрики запущенных задач

Task.Run(Action/Func)
Task.Factory.StartNew(Action/Func)
3. Конструктор

var t = new Task(Action/Func);
t.Start();
2. Фабрики завершенных задач

Task.FromResult(Result)
Task.FromCanceled(CancellationToken)
Task.FromException(Exception)
Task.CompletedTask
4. Фабрики-таскофикаторы

Task.Factory.FromAsync (APM)
TaskCompletionSource (EAP, APM, etc)
  1. Фабрики запущенных задач. Run — более легкая версия метода StartNew с установленными дополнительными параметрами по умолчанию. Возвращает созданную и запущенную задачу. Самый популярный способ запуска задач. Оба метода вызывают скрытый от нас Task.InternalStartNew. Возвращают объект Task.
  2. Фабрики завершенных задач.Иногда нужно вернуть результат задачи без необходимости создавать асинхронную операцию. Это может пригодиться в случае подмены результата операции на заглушку при юнит-тестировании или при возврате заранее известного/рассчитанного результата.
  3. Конструктор. Создает незапущенную задачу, которую вы можете далее запустить. Я не рекомендую использовать этот способ. Старайтесь использовать фабрики, если это возможно, чтобы не писать дополнительную логику по запуску.
  4. Фабрики-таскофикаторы.Помогают либо произвести миграцию с других асинхронных моделей в TAP, либо обернуть логику ожидания результата в вашем классе в TAP. Например, FromAsync принимает методы паттерна APM в качестве аргументов и возвращает Task, который оборачивает более ранний паттерн в новый.

Кстати, библиотеки в .NET, в том числе и механизм async/await, организуют работу по установке результата либо исключения для таск с помощью TaskCompletionSource.

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

Как отменить задачу

За отмену задач отвечает класс CancellationTokenSource и порождаемый им CancellationToken.
Работает это приблизительно так:

  1. Создается экземпляр CancellationTokenSource (cts).
  2. cts.Token отправляется параметром в задачу (ассоциируется с ней).
  3. При необходимости отмены задачи для экземпляра CancellationTokenSource вызывается метод Cancel().
  4. Внутри кода задачи на токене вызывается метод ThrowIfCancellationRequested(), который выбрасывает исключение в случае, если в CancellationTokenSource произошла отмена. Если токен был ассоциирован с задачей при создании, исключение будет перехвачено, выполнение задачи остановлено (так как исключение), ей будет выставлен статус Cancelled. В противном случае задача перейдет в статус Faulted.

Также возможно прокинуть cts в методы, уже реализованные в .NET, у них внутри будет своя логика по обработке отмены.

Кстати, конструктор CancellationTokenSource может принимать значение таймаута, после которого метод Cancel будет вызван автоматически.

Асинхронные контроллеры в ASP.NET могут инжектить экземпляр CancellationToken прямо в метод контроллера, вызываться же отмена токена будет по разрыву соединения с сервером. Это позволит значительно упростить инфраструктуру поддержки обрыва ненужных запросов. Если этот токен будет вовремя обрывать операции, результата которых уже не ждут, производительность может заметно повыситься. Далее два примера согласованной отмены.

Пример #1 кода согласованной отмены:

//Подготовка
var cts = new CancellationTokenSource();
var token = cts.Token;
token.Register(() => Console.WriteLine("Token works"));

//Получаем задачу
var t = Task.Run(async () =>
{
      //производим отмену на CancellationTokenSource
      cts.Cancel();
      //в Delay попадет уже отмененный токен, что выбросит исключение
      await Task.Delay(10000, token);

      //Возвратом задачи делаем из async void метода -> async Task метод
      return Task.CompletedTask;
}, token);

try
{
    //неблокирующее ожидание задачи
await t;
}
//В данном случае выбросится TaskCanceledException
catch (TaskCanceledException e)
{
      Console.WriteLine(e.Message + " TaskCanceledException");
}

В этом случае мы получаем в консоль:

Token works
A task was canceled. TaskCanceledException

Пример #2

В случае же работы с опросом токена исключение будет иное

(такой же код инициализации, как и выше)

//Получаем задачу
var t = Task.Run(async () =>
{
      //производим отмену на CancellationTokenSource
      cts.Cancel();
      //выбрасываем исключение на отмененном токене
      token.ThrowIfCancellationRequested();

     return Task.CompletedTask;
}, token);

try
{
     await t;
}
//В данном случае выбросится OperationCanceledException
catch (OperationCanceledException e)
{
     Console.WriteLine(e.Message + " OperationCanceledException");
}

В этом случае мы получаем в консоль:

Token works
The operation was canceled.OperationCanceledException

Обратите внимание, что Task.Delayвыбросит TaskCanceledException, а не OperationCanceledException.

Более детально о согласованной отмене можно почитать тут.

Как следить за прогрессом выполнения

TAP содержит специальный интерфейс для использования в своих асинхронных классах — IProgress<T>, где T — тип, содержащий информацию о прогрессе, например int. Согласно конвенциям, IProgress может передаваться как последние аргументы в метод вместе с CancellationToken. В случае если вы хотите передать только что-то из них, в паттерне существуют значения по умолчанию: для IProgress принято передавать null, а для CancellationToken — CancellationToken.None, так как это структура.

//Не используйте такой код в продакшене :) написано с целью демонстрации
//Код считает до 100 с определенной задержкой репортуя прогресс
public async Task RunAsync(int delay, CancellationToken cancellationToken, IProgress<int> progress)
{
      int completePercent = 0;

      while (completePercent < 100)
      {
        await Task.Run(() =>
        {
            completePercent++;

             new Task(() =>
             {
                 progress?.Report(completePercent);
             }, cancellationToken, 
                TaskCreationOptions.PreferFairness).Start();

        }, cancellationToken);

        await Task.Delay(delay, cancellationToken);
      }
}

Как синхронизировать задачи

Существуют такие способы объединять задачи в логические цепочки друг за другом или же ожидать группы задач по определенному принципу:

Комбинаторы задач

Task.WaitAll (list of tasks) -> Task
Task.WaitAny (list of tasks) -> Task
Task.WhenAll (list of tasks) -> Task
Task.WhenAny (list of tasks) -> Task
Метод расширения ContinueWith для экземпляров задач с опциями реакции на исключения, отмену или удачное завершение предыдущей задачи

t.ContinueWith( res=>{ код продолжения }, TaskContinuationOptions )
Метод расширения ContinueWith для экземпляров задач с опциями продолжения синхронно или асинхронно, установкой другого планировщика задач

t.ContinueWith( res=>{ код продолжения }, TaskContinuationOptions )
Метод расширения ContinueWith для экземпляров задач с опциями присоединения к времени выполнения родительской задачи (дочерняя задача не сможет завершиться до завершения родительской)

t.ContinueWith( res=>{ код продолжения }, TaskContinuationOptions )

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

Всего у TaskContinuationOptions 15 значений, и они могут комбинироваться.ContinueWith оборачивает задачу еще в одну задачу, создавая Task<Task<... >>. Но не стоит злоупотреблять или имплементировать сложную логику, основанную на этом методе.

Более подробно об особенностях такого поведения и подводных камнях можно почитать в блоге Stephen Cleary.

Как извлечь результат из задачи

До появления await извлекать результат из задач можно было такими блокирующими способами:

  • t.Result(); — возврат результата / выброс исключения AggregateException.
  • t.Wait(); — ожидание выполнения задачи, выброс исключения AggregateException.
  • t.GetAwaiter().GetResult(); — возврат результата / выброс оригинального исключения — служебный метод компилятора, поэтому использовать его не рекомендуется. Используется механизмом async/await.

После появления async/await рекомендованной техникой стал оператор await, производящий неблокирующее ожидание. То есть если await добрался до незавершенной задачи, выполнение кода в потоке будет прервано и продолжится только с завершением задачи.

await t; — возврат результата / выброс оригинального исключения.

Следует заметить, что для t.GetAwaiter().GetResult(); и await будет выброшено только первое исключение, аналогично манере поведения обычного синхронного кода.

Выброс исключения в вызывающий поток тоже результат.

Почему исключения задач завернуты в AggregateException? Допустим, задача стала результатом работы комбинатора задач (например, Task.WhenAll). Он вернет задачу, которая станет завершенной только после завершения всех переданных ей задач. Значит, исключений может быть много, поэтому они будут завернуты в AggregateException.

Философия async/await

Основная идея async/await в том, чтобы писать асинхронный код в синхронной манере и не задумываться, как это работает. Но в этом и основной подводный камень — незнание начинки может породить неожиданные сайд-эффекты, о которых мы не задумывались.

Следующий код:

async Task<ResultType> funcAsync()
            {
                var result1 = await LongOperation1(null);
                var result2 = await LongOperation2(result1);
                var result3 = await LongOperation3(result2);
                return result3;
            }

ResultType funcResult = await funcAsync();

Логически представляет собой следующий код:

public static void CallbackFunc(Action<ResultType> resultCallback)
{
   LongOperation1(arg: null, onCompleted: (result1) =>
   {
      LongOperation2(arg: result1,  onCompleted: (result2) =>
      {
          LongOperation3(arg: result2,onCompleted: (result3) =>
           {           
               resultCallback(result3); 
           });
      });
    });
 }

CallbackFunc(result =>
{
   ResultType funcResult = result;
 });

где LongOperation1, LongOperation2, LongOperation3 — принимают аргумент и коллбек-функцию, выполняющуюся по завершении и принимающую результат операции.

Добавив немного инфраструктуры, мы бы изобрели самый старый асинхронный паттерн, APM.

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

Как использование async/await дополняет работу с TAP

Все, что могло ожидаться, блокируя поток, теперь может ожидаться, не блокируя поток, например:


БылоСталоЗачем нужно
task.Waitawait taskОжидать завершения Task’а
task.Resultawait taskПолучить результат завершенного Task’а
Task.WaitAnyawait Task.WhenAnyОжидать завершения одного (любого) Task’a из коллекции
Task.WaitAllawait Task.WhenAllОжидать завершения всех (последнего) Task’a из коллекции
Thread.Sleepawait Task.DelayЖдать заданный период времени

Что нового появилось в TAP начиная с C# 5

C# 5.0 / .NET 4.5

  • async/await;
  • Progress<T>.

C# 6.0

  • await в Catch/Finally блоках, в C# 5 так делать было нельзя;
  • Упрощенный синтаксис Task.Run(DoThings) вместо Task.Run(() => DoThings()).

C# 7.0 — 7.3

  • ValueTask<T> — структура-таск, повышающая производительность в некоторых случаях;
  • async Main method для консольного приложения.

C# 8 / .NET Standard 2.1 — (.NET Core 3, Mono 6.4)

  • AsyncStreams — асинхронные стримы, пока недоступны в .NET Framework, только для платформ, входящих в .NET Standard 2.1 +. Если вкратце — дают возможность на уровне языка реализовывать неблокирующие ожидания между чтениями из потока.

II. Взгляд вовнутрь через популярные заблуждения

Людям свойственно выбирать для сложных вещей самое простое объяснение, часто в реальной жизни это статистически оправдано. Однако технологии не всегда построены очевидным для нас способом, и «простое» объяснение может ввести нас в заблуждение.

Task — это облегченный Thread

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

  • Обслуживание статуса (выполнена, выполняется, отменена, ошибка) логической задачи — списка инструкций, объединенного в метод либо анонимный метод.
  • Фабричные статические методы по запуску логических задач с установкой параметров исполнения, также конструктор, позволяющий вручную создать задачу и затем ее запустить.
  • Создание инфраструктуры по согласованной отмене логической задачи, поддержки цепочек вызова задач.
  • Извлечение результата либо исключения в вызывающий поток.

Если вы программировали на JavaScript, то аналогом Task является объект Promise.

Лично я вижу класс Task как реализацию таких паттернов.

Фасад: Task не управляет выполнением задач и не имеет стратегии их планирования в потоки, это скорее интерфейс-абстракция, имеющая билдеры (ContinueWith), статические методы-фабрики создания задач и вариант создания задачи с помощью конструктора.

DTO (Data transfer object): Task отвечает за перенос состояния выполнения и результата связанного с ним кода. Причем установкой результата или исключения Task на низком уровне занимается TaskCompletionSource.

За планирование выполнения кода в потоках отвечает класс TaskScheduler, который имеет две реализации:

  • ThreadPoolTaskScheduler (неявно установлен для всех задач);
  • SynchronizationContextTaskScheduler.

Вы вправе написать собственный TaskScheduler, реализовав стратегию использования потоков и планирования в них кода, переданного в задачи.

  • ThreadPoolTaskScheduler выполняет код в потоках из ThreadPool. В виде исключения существует использование опции при создании задачи LongRunningTask — для таких задач ThreadPoolTaskScheduler создает отдельный поток.
  • SynchronizationContextTaskScheduler использует поведение текущего контекста синхронизации (установленного для потока либо по умолчанию). Контекст синхронизации является наследником класса SynchronizationContext. Получить этот TaskScheduler можно с помощью вызова TaskScheduler.FromSynchronizationContext(); в текущем потоке.

Async await — синтаксический сахар

Это утверждение отчасти верно, но только отчасти. Механизм async/await действительно не имеет реализации в CLR и разворачивается компилятором в довольно сложную конструкцию, указывающую, какую именно часть метода вызывать (стейт машина). Но вы не сможете реализовать async/await через механизм, например, тасок. Async/await — не синтаксический сахар вокруг тасок, это отдельный механизм, использующий класс Task для переноса состояния выполняющегося куска кода.

Await запускает операцию асинхронно

Оператор Await не запускает операцию асинхронно, он либо:

  • вызывает метод синхронно, если возвращенная им задача уже была завершена;
  • производит неблокирующее ожидание (отпускает поток) результата задачи, возвращая управление из метода вверх по иерархии await’ов, когда мы дошли до вложенного await, который возвращает незавершенную Task.

Результатом операции await может быть либо возврат результата из связанной с ним задачи, либо выброс исключения. Кстати, в случае с задачами, порожденными комбинаторами задач, будет выброшено только первое исключение, даже если результирующая задача накопила их несколько. Это обусловлено природой оператора await — сделать асинхронный код таким же простым, как синхронный. Если вы хотите получить все исключения — обратитесь к переменной типа Task, которую вы эвейтили.

Кстати, Task не единственный класс, который может работать с оператором await. С ним может работать любой класс, реализующий метод GetAwaiter(), в случае с Task — TaskAwaiter.

Продолжение метода после await будет выполнено в пуле потоков

Это утверждение верно, но не всегда. Я выше упомянул класс SynchronizationContext, так вот, он необходим для механизма работы async/await. Наследники класса SynchronizationContext устанавливаются той средой, где выполняется код, в свойствах потока.

Для ASP.NET Core, Console Application, созданных вручную потоков — SynchronizationContext не будет выставлен явно. Это означает, что async/await будет использовать ThreadPool SynchronizationContext (контекст по умолчанию), запуская продолжение методов в случае, если возвращаемая ими задача не завершена, в ThreadPool.

В ASP.NET (старом) установлен однопоточный AspNetSynchronizationContext, присоединяющий продолжение методов в тот же поток, из которого выполнялась их первая часть.

То же самое и для WinForms-приложений: UI-поток имеет установленный WindowsFormsSynchronizationContext, планирующий продолжение только в единственный UI-поток.

Можете провести простой тест. Если вы запустите Task из метода-обработчика события UI-контрола в WinForms-приложении, он выполнится в пуле потоков. Однако если вы сделаете это с помощью Task.Factory.StartNew и передадите ему в параметр TaskScheduler — TaskScheduler.FromCurrentSynchronizationContext, то задача выполнится в UI-потоке.

Кстати, метод configureAwait, вызываемый на классе Task, возвращает пропатченный TaskAwait’er, в котором сбрасывается текущий контекст синхронизации и заново устанавливается по умолчанию. В этом случае продолжение отработает в пуле потоков.

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

Будет очень неожиданно, если кто-нибудь додумается синхронно (t.Result / t.Wait() ) получить результат из асинхронного метода вашей библиотеки в однопоточном контексте синхронизации (WinForms, ASP.NET). Единственный поток будет заблокирован незаконченной задачей, а закинуть в него продолжение задачи и завершить эту же самую задачу вы не сможете. И получите классический дедлок.

Все вышеописанное можно подытожить в таблице:


ПотокКонтекст синхронизации по умолчаниюГде выполнится продолжение метода после await в случае возврата незавершенного Task
Собственный потокSynchronizationContextThreadPool
Console ApplicationSynchronizationContextThreadPool
ASP.NET Core SynchronizationContextThreadPool
Original ASP.NETAspNetSynchronizationContextТот же поток
WinFormsWindowsFormsSynchronizationContextЕдинственный UI-поток
WPFDispatcherSynchronizationContext Единственный UI-поток

Флаг async без вызовов await внутри никак не поменяет метод

Это не так. Async — флаг компиляции, он — не часть сигнатуры метода и может не быть объявлен в интерфейсах. Видя метод как async, компилятор уже все равно создаст из него state-машину, пускай даже с одним состоянием. Исходя из этого оставлять методы с async без await внутри — плохая практика.

Async await и ContinueWith у Task — одно и то же

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

await Task.Run(() => { })
                .ContinueWith(async prev =>
                {
                    Console.WriteLine("Continue with 1 start");
                    await Task.Delay(1000);
                    Console.WriteLine("Continue with 1 end");
                })
                .ContinueWith(prev =>
                {
                    Console.WriteLine("Continue with 2 start");
                });

В консоли мы получим:

Continue with 1 start
Continue with 2 start
Continue with 1 end

Такое поведение обусловлено особенностью механизма async/await — после прерывания метода из него возвращается незавершенная задача, что интерпретируется механизмом ContinueWith как завершение метода.

Далее стартует следующий метод цепочки, однако после возврата результата — стейт-машина первого метода запустит вторую часть метода, и оба метода продолжат выполнение параллельно.

Если хотите другие объяснения, то я поднимал этот вопрос на Stack Overflow.

TaskScheduler — то же самое, что SynchronizationContext, только новее

На самом деле, SynchronizationContext был представлен в .NET гораздо раньше, чем TaskScheduler.

  • Наследники обоих классов отвечают за планирование асинхронных операций.
  • Оба наследника работают с пулом потоков (класс ThreadPool) в реализациях по умолчанию.
TaskScheduler

  • Появился в .NET 4.0.
  • Высокоуровневая абстракция для работы с Task.
  • Позволяет планировать выполнение Task и продолжений.
  • Имеет две реализации по умолчанию:
    ThreadPoolTaskScheduler
    и SynchronizationContextTaskScheduler.
Где используется:

  • Любые операции с Task API, явно или неявно.
SynchronizationContext

  • Появился в .NET 2.0.
  • Низкоуровневый класс, позволяет запускать делегаты в нужных потоках.
  • Используется для работы await.
  • Имеет множество реализаций в зависимости от типа окружения.
Где используется:

  • Продолжение метода после await.
  • TaskScheduler.FromCurrentSynchronizationContext().
  • Запуск обработчиков в WinForms.

III. Проблемный код и лучшие практики

Проблемный код

Async void problem

Не используйте void вместе с async, если только это не написание обработчиков WinForms/WPF. Метод, отмеченный как async, будет запущен в пуле потоков, но у него нет механизма отлова исключений. Также вы не сможете отследить прогресс его выполнения, так как объекта Task, отвечающего за статус, здесь нет. Опасность отсутствия механизмов отлова исключений в том, что в случае падения такой метод завершит работу домена приложения, а если он единственный — то и работу всего приложения.

Кстати, анонимный лямбда-метод — async Action, а Action имеет результат void. Поэтому, вернув в async лямбде результат Task, компилятор автоматически выберет нужную перегрузку метода Task.Run, возвращающий async Task — и проблем не будет.

Deadlock problem

В однопоточных контекстах синхронизации (Original asp.net, WinForms, WPF) возможны дедлоки из-за необходимости добавлять продолжение метода в уже занятый поток. При этом освободить поток нельзя из-за незаконченности задачи. Чтобы было проще понять, о чем я, давайте посмотрим на такой код:

public static async Task<JObject> GetJsonAsync(Uri uri)
{
  using (var client = new HttpClient())
  {
	//await ожидает освобождения потока, чтобы запланировать запуск продолжения метода
    var jsonString = await client.GetStringAsync(uri); 
    return JObject.Parse(jsonString);
  }
}

public string Get(){
    var jsonTask = GetJsonAsync(...);
//поток заблокирован с помощью Result, ожидается завершение Task
    return jsonTask.Result.ToString();
}

Если он будет вызван на старом ASP.NET или на WinForms/WPF-приложении, результатом будет дедлок.

По порядку:

  1. Выполнение заходит в метод GetJsonAsync.
  2. Выполнение доходит до оператора await, возвращая вверх по вызову незаконченную Task.
  3. На незаконченной Task запускается блокирующее ожидание результата свойством Result.
  4. После прихода await однопоточный контекст синхронизации планирует продолжение в единственно возможный поток, который ждет окончания Task. Но Task не закончится, пока не отработает продолжение.

Еще один пример:

Блокирующие операции

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

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

Потерянные исключения

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

Запустите этот код в ASP.NET Core консольном приложении:

#if DEBUG
            Console.WriteLine("Please, switch to Release mode");
#endif
#if RELEASE
            TaskScheduler.UnobservedTaskException += (s, e) =>
            {
                Console.WriteLine("Unobserved exception");
            };
#endif

  Task.Factory.StartNew(() => throw new ArgumentNullException());
  Task.Factory.StartNew(() => throw new ArgumentOutOfRangeException());

  Thread.Sleep(100);
  GC.Collect();
  GC.WaitForPendingFinalizers();
      
  await Task.Delay(10000);

Вы увидите, что после сборки мусора два раза сработает событие UnobservedTaskException, при этом никакой проблемы в работе приложения не будет.

В .NET 4.0 поведение по умолчанию было иным: в случае необработанного исключения (оно считается необработанным, если Task, в котором оно произошло, попадает под сборку мусора, при этом мы не обратились к свойству Exception явно или неявно) будет выброшено исключение в пул потоков, что приведет к краху приложения.

Ambient objects

  • Никогда не используйте ThreadLocal-хранилище в асинхронном коде, вместо этого был создан класс AsyncLocal.
  • При использовании TransactionScope помните об опции AsyncFlow, без нее работа транзакций не будет корректной. Я не сторонник использования TransactionScope в своих приложениях, однако при рефакторинге строго кода — вы вполне можете все сломать.

Работа асинхронных методов и IDisposable

В следующем коде:

public async Task<Result> GetResult()
{
      return await service.get();
}

public Task<Result> GetResultWrapper()
{
      using(var serviceContext = new ServiceContext())
      {
            return serviceContext.GetResult();
      }
}

Если вызывать async метод конструкцией await внутри в синхронном using, то Dispose для serviceContext отработает перед тем, как завершится метод GetResult.

Причина такого поведения в том, что после первого же await внутри метода GetResult нам вернется Task, исполнение кода продолжится, и по выходу из using будет вызван Dispose.

Затем придет продолжение после await внутри метода GetResult, но будет поздно.

Производительность

await в цикле

Если у вас есть код, где каждому элементу необходимо независимо от других сделать await, выполнение в цикле будет очень долгим. С логической точки зрения, если в основе вызываемых методов лежит IO Bound блокировка ожидания, то нет смысла вызывать их последовательно. С точки зрения конечного автомата внутри механизма async/await, это будет некоторый оверхед.

Гораздо лучше собрать все таски — и вызвать Task.WhenAll для всех сразу. ThreadPool сам поймет, как лучше оптимизировать их работу.

Dynamic & try/catch в async-методах

Если в вашем приложении каждая миллисекунда имеет значение, помните, что использование try/catch внутри async-метода значительно его усложнит. То же самое — с await dynamics-результата. Стейт-машина станет в разы сложнее, что замедлит выполнение кода.

ValueTask

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

Лучшие практики

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

Если упростить:

  • Не используйте async void, за исключением обработчиков WinForms/WPF.
  • Если начали, делайте все приложение асинхронным.
  • Не используйте блокирующие конструкции, используйте await.
  • Выбирайте неблокирующее ожидание await > ContinueWith.
  • Используйте ConfigureAwait(false) в коде вашей библиотеки.
  • Возвращайте только запущенные задачи.
  • Используйте конвенции именований.
  • Используйте флаги задач, если это необходимо.
  • Используйте асинхронную версию SemaphoreSlim для синхронизации доступа к ресурсу.

IV. Библиотеки и тулинг

Неблокирующие коллекции

Non-blocking dictionary — усовершенствованный по перфомансу словарь.

Immutable collections — стандартный набор неизменяемых коллекций. Примеры использования и кейс можно найти в этой статье.

Анализаторы кода

AsyncFixer — анализатор-расширение для Visual Studio для проблемных мест, связанных с асинхронностью. Ненужные await, async void методы, использование async & using, места, где можно использовать async-версии методов, обнаружение явных кастов Task<T> к Task.

Ben.BlockingDetector — библиотека-помощник обнаружения блокировок в вашем коде.

Демистифаеры стек-трейса

Ben.Demystifierпозволяет получить более приятный стек-трейс в вашем приложении.

V. Что почитать/посмотреть

Можете глянуть мой доклад «Асинхронность в .NET — от простого к сложному»по этой теме. По структуре материала он похож на эту статью.

Довольно интересный доклад Игоря Фесенкопро работу асинхронности и многопоточности, скрытые проблемы и методы их решения.

Блог Stephen Cleary, автора Concurrency in C# Cookbook (2nd ed).

Блог непосредственно разработчиков асинхронных средств Pfx team: async/await, Tasks in-depth.

TAP Pattern whitepaper.

ILSpy/DotPeek, чтобы посмотреть все самому :) Если хотите посмотреть код, генерируемый для async-методов — в настройках вашей reverse-engineering tool необходимо включить соответствующую настройку.

Еще пара книг по этой теме, которые мне показались вполне понятными: Алекс Дэвис «Асинхронное программирование в C# 5.0», Richard Blewett, Andrew Clymer Pro Asynchronous Programming with .NET.


Если у вас есть вопросы, замечания или пожелания, можете писать мне на Facebook.

Также если вы начинающий или опытный разработчик в поиске работы/в процессе изучения технологий, можете вступить в мое комьюнити в Telegram. Участвуйте в обсуждениях, задавайте вопросы — или просто поговорим с вами за жизнь!

Синхронізація в Go: горутини, тести, варіанти

$
0
0

Привіт, мене звати Ярослав, займаюсь розробкою в компанії Evrius. Ця стаття про синхронізацію результатів від паралельно виконаних підзадач, призначена для спеціалістів-початківців та тих, хто планує перейти на Go.

На початку 2019 року, маючи досвід з Go, шукав нову роботу. Під час більшості співбесід ставили запитання, як розпаралелити виконання завдання. Приблизний опис завдання: є список посилань, треба за ними перейти, отримати результат та синхронізувати. Вирішення було достатньо для проходження технічної частини в пару аутсорс-компаній.

Вартість горутини

Кожен розробник, який використовує Go, знає, що горутини дешеві. Трохи менше знають, що розмір мінімального стека горутинизмінювали в ранніх версіях Go, у версії 1.13.

_StackMin = 2048

А щоб перевірити горутини на швидкодію, напишемо тест, у якому запустимо N горутин з простим завданням, дочекаємося завершення й подивимося результати:

package benchmarks

import (
	"sync"
	"sync/atomic"
	"testing"
)

func BenchmarkGoroutineCost(b *testing.B) {
	var value uint32
	var wg sync.WaitGroup

	wg.Add(b.N)

	for i := 0; i < b.N; i++ {
		go func() {
			atomic.AddUint32(&value, 1)

			wg.Done()
		}()
	}

	wg.Wait()

	if value != uint32(b.N) {
		b.Errorf("expected %d, got %d", b.N, value)
	}
}

go version

go version go1.13.3 linux/amd64

go test./benchmarks/... -v -bench=BenchmarkGoroutineCost -benchmem

BenchmarkGoroutineCost-4 3437931 351 ns/op 0 B/op 0 allocs/op
PASS
ok gitlab.com/go-yp/go-sync/benchmarks 1.563s

~350 наносекунд на створення, виконання, завершення горутини.

Спершу я в це повірив, але потім вирішив написати ще один тест, щоб перевірити відсутність оптимізації такої простої операції, а також те, що чисельність горутин під час виконання збільшується.

package benchmarks

import (
	"runtime"
	"sync"
	"sync/atomic"
	"testing"
)

type goRuntimeMaxCount struct {
	mu    sync.Mutex
	value int
}

func (c *goRuntimeMaxCount) update() {
	var value = runtime.NumGoroutine()

	c.mu.Lock()
	if value > c.value {
		c.value = value
	}
	c.mu.Unlock()
}

func (c *goRuntimeMaxCount) get() int {
	return c.value
}

func BenchmarkGoroutineCostDump(b *testing.B) {
	var (
		value          = uint32(0)
		wg             = new(sync.WaitGroup)
		goRuntimeCount = new(goRuntimeMaxCount)
	)

	b.Logf("before goroutine count %d", goRuntimeCount.get())

	wg.Add(b.N)

	for i := 0; i < b.N; i++ {
		go func() {
			atomic.AddUint32(&value, 1)

			goRuntimeCount.update()

			wg.Done()
		}()
	}

	wg.Wait()

	if value != uint32(b.N) {
		b.Errorf("expected %d, got %d", b.N, value)
	}

	b.Logf("after goroutine count %d for b.N = %d", goRuntimeCount.get(), b.N)
}

go test ./benchmarks/... -v -bench=BenchmarkGoroutineCostDump -benchmem

BenchmarkGoroutineCostDump-4 3223651 366 ns/op 0 B/op 0 allocs/op
before goroutine count 0
after goroutine count 904 for b.N = 1000000
before goroutine count 0
after goroutine count 3160 for b.N = 3223651
PASS
ok gitlab.com/go-yp/go-sync/benchmarks 1.562s

Тест показав, що горутини справді створюються. А тепер змінимо тест так, щоб на кожній ітерації циклу горутина створювалася і завершувалася:

func BenchmarkGoroutineCostOne(b *testing.B) {
	var value uint32
	var wg sync.WaitGroup

	for i := 0; i < b.N; i++ {
		wg.Add(1)
		go func() {
			atomic.AddUint32(&value, 1)

			wg.Done()
		}()
		wg.Wait()
	}

	if value != uint32(b.N) {
		b.Errorf("expected %d, got %d", b.N, value)
	}
}

func BenchmarkGoroutineCostOneOverhead(b *testing.B) {
	var value uint32
	var wg sync.WaitGroup

	for i := 0; i < b.N; i++ {
		wg.Add(1)
		atomic.AddUint32(&value, 1)
		wg.Done()
		wg.Wait()
	}

	if value != uint32(b.N) {
		b.Errorf("expected %d, got %d", b.N, value)
	}
}

go test ./benchmarks/... -v -bench=BenchmarkGoroutineCostOne -benchmem

BenchmarkGoroutineCostOne-4 1488328 841 ns/op 0 B/op 0 allocs/op
BenchmarkGoroutineCostOneOverhead-4 32435746 34.6 ns/op 0 B/op 0 allocs/op
PASS
ok gitlab.com/go-yp/go-sync/benchmarks 3.229s

Тести проводив на домашньому Intel® Core™ i5-4210U CPU @ 1.70GHz, що показали вартість горутини ~800 наносекунд.

Для порівняння: знаходження максимального елементу в масиві з 1024 елементів ~1400 наносекунд.

Атомарність

Ми вже використовували пакет atomic, потрібний для паралельних операцій, щоб гарантувати їхню успішність.

Якщо з попередніх тестів забрати atomicі використовувати просте додавання:

func TestParallelPureIncrement(t *testing.T) {
	const n = 1000000

	var (
		value uint32
		wg    = new(sync.WaitGroup)
	)

	wg.Add(n)
	for i := 0; i < n; i++ {
		go func() {
			value++ // same sa "value = value + 1"

			wg.Done()
		}()
	}

	wg.Wait()

	if value != n {
		t.Errorf("expected %d, got %d", n, value)
	}
}

Отримаємо:

=== RUN TestParallelPureIncrement
--- FAIL: TestParallelPureIncrement (0.35s)
expected 1000000, got 851804
FAIL
FAIL gitlab.com/go-yp/go-sync/benchmarks 0.353s

Очікували 1 000 000, отримали 851 804, через відсутність синхронізації між горутинами.

На основі пакета atomicґрунтуються інші структури в Go, що використовують для синхронізації. Так, у тесті замість WaitGroup.Wait, ми можемо використати циклічну перевірку:

func TestParallelPureAtomic(t *testing.T) {
	const n = 1000000

	var value uint32

	for i := 0; i < n; i++ {
		go func() {
			atomic.AddUint32(&value, 1)
		}()
	}

	for atomic.LoadUint32(&value) < n {
		// NOP
	}
}

=== RUN TestParallelPureAtomic
--- PASS: TestParallelPureAtomic (0.42s)
PASS
ok gitlab.com/go-yp/go-sync/benchmarks 0.425s

і додати перемикання на інші горутини runtime.Gosched()

for atomic.LoadUint32(&value) < n {
		runtime.Gosched()
	}

Проте ліпше використовуйте sync.WaitGroup.

Синхронізація результатів від горутин і перегони даних (data race)

Якщо ви початківець у Go, а вам треба розпаралелити завдання, то ліпше напишіть тест для цього завдання, розпаралельте й запустіть з флагом -race, щоб перевірити наявність data race.

Data race — помилка проектування, стан програми, коли один або більше потоків змінюють дані без блокування й один або більше читають ці дані без блокування, у результаті програма працює інакше, ніж очікуємо.

Знайдемо функціонал, що розробили в однопотоковому варіанті й зі збільшенням завдань — розпаралелили.

Наприклад, візьмемо сторінку bestofjs.org/projects, де навпроти кожного проекту бачимо число зірок на GitHub-і.

Раз на день ці числа треба оновлювати, а в базі всього 20 репозиторіїв.

Є функція, щоб отримати число зірок за ID репозиторію:

func fetchRepositoryStarByID(id int) int {
	// emulate slow http request by sleep
	time.Sleep(100 * time.Millisecond)

	// emulate response
	var stars = id % 32

	return stars
}

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

package main

import (
	"fmt"
	"time"
)

const repositoryCount = 20

type repository struct {
	id        int
	starCount int
}

func main() {
	var startTime = time.Now()

	var ids = getRepositoryIDs()
	var repositories = fetchRepositoryStarsByIDs(ids)

	updateRepositoryStars(repositories)

	var duration = time.Since(startTime)

	fmt.Printf("fetch %d from %d repositories by %d \n", len(repositories), repositoryCount, duration)
}

func getRepositoryIDs() []int {
	return make([]int, repositoryCount)
}

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var result = make([]repository, 0, len(ids))

	for _, id := range ids {
		result = append(result, repository{
			id:        id,
			starCount: fetchRepositoryStarByID(id),
		})
	}

	return result
}

func fetchRepositoryStarByID(id int) int {
	// emulate slow http request by sleep
	time.Sleep(100 * time.Millisecond)

	// emulate response
	var stars = id % 32

	return stars
}

func updateRepositoryStars(repositories []repository) {
	// NOP
}

Програма виконується за 2 секунди.

Опублікували React, Vue, Svelte й розширення до них, тепер у базі 100 репозиторіїв і програма виконується за 10 секунд.

З цим треба щось робити, бо чекаємо, що в проекті буде ще більше репозиторіїв, а отже, оновлення займатиме ще більше часу.

Вирішили розпаралелити з використанням горутин і WaitGroup.

Тепер fetchRepositoryStarsByIDsмає такий вигляд:

package main

import (
	"fmt"
	"sync"
	"time"
)

const repositoryCount = 100

// ... same

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, 0, length)
		wg     = new(sync.WaitGroup)
	)

	wg.Add(length)

	for _, id := range ids {
		go func() {
			result = append(result, repository{
				id:        id,
				starCount: fetchRepositoryStarByID(id),
			})

			wg.Done()
		}()
	}

	wg.Wait()

	return result
}

виконується за 100 мілісекунд, але в консолі бачимо, що тільки частину репозиторіїв оновлено:

fetch 81 from 100 repositories by 112999451

Запустимо з флагом -race

go run -race main.go

й отримаємо повідомлення, у яких рядках коду є помилки (вивів тільки частину повідомлення):

WARNING: DATA RACE
Read at 0×00c00009a020 by goroutine 8:
main.fetchRepositoryStarsByIDs.func1()
gitlab.com/go-yp/go-sync/main.go:41 +0×91

У цьому коді відразу дві помилки з data race.

Перша помилка data race:змінна id змінюється в основній горутині, де виконується цикл for і читається зі створених горутин.

Ось приклад, що покаже цю помилку:

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var ids = []int{1, 2, 3}
	var wg = new(sync.WaitGroup)

	wg.Add(3)
	for _, id := range ids {
		go func() {
			time.Sleep(time.Millisecond)

			fmt.Printf("id is %d\n", id)

			wg.Done()
		}()
	}

	wg.Wait()
}

id is 3
id is 3
id is 3

Варіанти розв’язання:

for _, id := range ids {
		go func(id int) {
			time.Sleep(time.Millisecond)

			fmt.Printf("id is %d\n", id)

			wg.Done()
		}(id)
	}
for _, id := range ids {
		id := id

		go func() {
			time.Sleep(time.Millisecond)

			fmt.Printf("id is %d\n", id)

			wg.Done()
		}()
	}

Друга помилка data race:це append, що змінює SliceHeaderчерез append з багатьох горутин.

Є три відомі мені варіанти розв’язання проблеми data race під час збереження результатів від горутин.

У першому: ми ініціалізуємо slice, і кожна горутина пише у свій індекс:

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, length)
		wg     = new(sync.WaitGroup)
	)

	wg.Add(length)

	for i, id := range ids {
		go func(i, id int) {
			result[i] = repository{
				id:        id,
				starCount: fetchRepositoryStarByID(id),
			}

			wg.Done()
		}(i, id)
	}

	wg.Wait()

	return result
}

Після запуску отримаємо очікуваний результат 100 зі 100 й без помилки data race.

fetch 100 from 100 repositories by 113026518

Якщо переглянути документацію — кожний елемент масиву як окрема змінна і в цьому прикладі з fetchRepositoryStarsByIDs кожна горутина працює зі своїм індексом (змінною), а отже, немає data race:

Structured variables of array, slice, and struct types have elements and fields that may be addressed individually. Each such element acts like a variable.

Це саме питання про запис у різні індекси є на stackoverflow.

Другий: обернути append в sync.Mutex:

package main

import (
	"fmt"
	"sync"
	"time"
)

const repositoryCount = 100

// ... same

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, 0, length)
		wg     = new(sync.WaitGroup)
		mu     = new(sync.Mutex)
	)

	wg.Add(length)

	for _, id := range ids {
		go func(id int) {
			var starCount = fetchRepositoryStarByID(id)

			mu.Lock()
			result = append(result, repository{
				id:        id,
				starCount: starCount,
			})
			mu.Unlock()

			wg.Done()
		}(id)
	}

	wg.Wait()

	return result
}

Після запуску отримаємо очікуваний результат 100 зі 100 й без помилки data race (так само).

Жодної переваги перед першим варіантом.

Діє таке саме правило, що й у циклах:

  • Якщо дію можна винести за цикл, так ліпше й зробити.
  • Якщо дію можна винести за mutex, так ліпше й зробити.

Наприклад, написавши такий код:

go func(id int) {
	mu.Lock()
	var starCount = fetchRepositoryStarByID(id)

	result = append(result, repository{
		id:        id,
		starCount: starCount,
	})
	mu.Unlock()

	wg.Done()
}(id)

Програма буде заблокована під час виконання важкої операції fetchRepositoryStarByID і стане послідовною з часом виконання 10 секунд.

Третій: писати результати в канал, це стандартне рішення, бо канали створені для можливості писання й читання з багатьох горутин, без помилки data race:

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var length = len(ids)
	// can also use channel with length, in this case result will be same
	// var resultChan = make(chan repository, length)
	var resultChan = make(chan repository)
	var wg = new(sync.WaitGroup)

	wg.Add(length)

	for _, id := range ids {
		go func(id int) {
			resultChan <- repository{
				id:        id,
				starCount: fetchRepositoryStarByID(id),
			}

			wg.Done()
		}(id)
	}

	go func() {
		wg.Wait()
		// close chan and break read loop
		close(resultChan)
	}()

	var repositories = make([]repository, 0, length)
	// read loop, while resultChan is open
	for result := range resultChan {
		repositories = append(repositories, result)
	}

	return repositories
}

Перевага цього варіанта в тому, що замість збереження в slice ми можемо відразу починати опрацьовувати результати й навіть розпаралелити читання, якщо потрібно.

Є ще один варіант — комбінація першого й другого:

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, length)
		wg     = new(sync.WaitGroup)
		index  = int32(-1)
	)

	wg.Add(length)

	for _, id := range ids {
		go func(id int) {
			newIndex := atomic.AddInt32(&index, 1)

			result[newIndex] = repository{
				id:        id,
				starCount: fetchRepositoryStarByID(id),
			}

			wg.Done()
		}(id)
	}

	wg.Wait()

	return result
}

Throttling (rate limiting)

Проект із зірочками зростає і вже має 1000 репозиторіїв.

GitHub (або інший сервіс) починає повертати HTTP status 429 (too many requests)або HTTP Timeout замість зірок, коли є багато одночасних запитів.

У нашому прикладі ми додамо додатковий time.Sleep(time.Second)у fetchRepositoryStarByID, щоб емулювати затримку HTTP Timeout:

package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

const repositoryCount = 1000

// ... same

func fetchRepositoryStarByID(id int) int {
	// emulate timeout
	if runtime.NumGoroutine() > 250 {
		time.Sleep(time.Second)
	}

	// emulate slow http request by sleep
	time.Sleep(100 * time.Millisecond)

	// emulate response
	var stars = id % 32

	return stars
}

Запустимо:

go run main.go

fetch 1000 from 1000 repositories by 1232180912

Як бачимо, тепер код виконується за секунду.

Тепер обмежмо число одночасних запитів за раз до 200.

Розгляньмо теж 3 варіанти (якщо комбінувати з попередніми, то, звісно, буде більше).

Найпростіший варіант — через канали (можна також пошукати за словом semaphore):

package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

const (
	repositoryCount = 1000
	requestLimit    = 200
)

// ... same

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, length)
		wg     = new(sync.WaitGroup)

		// WE ADD THIS
		throttler = make(chan struct{}, requestLimit)
	)

	wg.Add(length)

	for i, id := range ids {
		// WE ADD THIS
		throttler <- struct{}{}

		go func(i, id int) {
			result[i] = repository{
				id:        id,
				starCount: fetchRepositoryStarByID(id),
			}

			// WE ADD THIS
			<-throttler
			wg.Done()
		}(i, id)
	}

	wg.Wait()
	close(throttler)

	return result
}

go run -race main.go

fetch 1000 from 1000 repositories by 535724238

За півсекунди.

Ми пишемо в канал 200 разів і запускаємо 200 горутин, запустити наступну зможемо тоді, коли хтось прочитає з каналу.

Варіант через запуск воркерів (workers).

Запускаємо N воркерів (де N — наша константа request Limit), що з одного каналу читають завдання, а в інший пишуть результат:

package main

// ... same

func workerFetchRepositoryStarByID(wg *sync.WaitGroup, requestIdChannel <-chan int, responseRepositoryChannel chan<- repository) {
	// read while requestIdChannel open
	for id := range requestIdChannel {
		var starCount = fetchRepositoryStarByID(id)

		responseRepositoryChannel <- repository{
			id:        id,
			starCount: starCount,
		}
	}

	wg.Done()
}

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length      = len(ids)
		result      = make([]repository, 0, length)
		workerCount = requestLimit
	)

	if workerCount > length {
		workerCount = length
	}

	var (
		requestIdChannel          = make(chan int, workerCount)
		responseRepositoryChannel = make(chan repository, workerCount)

		workerComplete = new(sync.WaitGroup)
		readComplete   = new(sync.WaitGroup)
	)

	workerComplete.Add(workerCount)
	for i := 0; i < workerCount; i++ {
		go workerFetchRepositoryStarByID(workerComplete, requestIdChannel, responseRepositoryChannel)
	}

	readComplete.Add(1)
	go func() {
		for responseRepository := range responseRepositoryChannel {
			result = append(result, responseRepository)
		}
		readComplete.Done()
	}()

	for _, id := range ids {
		requestIdChannel <- id
	}

	close(requestIdChannel)
	workerComplete.Wait()

	close(responseRepositoryChannel)
	readComplete.Wait()

	return result
}

go run -race main.go

fetch 1000 from 1000 repositories by 540738968

Так багато коду для синхронізації, бо ми визначили розміри каналів, що менше загальної чисельності репозиторіїв.

Цей код працюватиме навіть з каналами без буфера:

var (
	requestIdChannel          = make(chan int, 0)
	responseRepositoryChannel = make(chan repository, 0)
)

Якщо ж використовувати ресурси пам’яті сповна, то код матиме простіший вигляд:

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length      = len(ids)
		result      = make([]repository, 0, length)
		workerCount = requestLimit
	)

	if workerCount > length {
		workerCount = length
	}

	var (
		requestIdChannel          = make(chan int, length)
		responseRepositoryChannel = make(chan repository, length)
		workerComplete            = new(sync.WaitGroup)
	)

	workerComplete.Add(workerCount)
	for i := 0; i < workerCount; i++ {
		go workerFetchRepositoryStarByID(workerComplete, requestIdChannel, responseRepositoryChannel)
	}

	for _, id := range ids {
		requestIdChannel <- id
	}
	close(requestIdChannel)

	workerComplete.Wait()

	close(responseRepositoryChannel)
	for responseRepository := range responseRepositoryChannel {
		result = append(result, responseRepository)
	}

	return result
}

і якщо потім захочемо змінити:

var (
	requestIdChannel          = make(chan int, 0)
	responseRepositoryChannel = make(chan repository, 0)
)

то заблокуємо виконання назавжди, коли воркери почнуть писати в responseRepositoryChannel, а читання вже після завершення.

Останній варіант — розділити початковий slice на пачки й для кожної розпаралелити виконання.

Ми використаємо зовнішній пакет, що поділить на діапазони:

package main

import (
	"fmt"
	"github.com/gopereza/packer"
	"runtime"
	"sync"
	"time"
)

const (
	repositoryCount = 1000
	requestLimit    = 200
)

// ... same

func fetchRepositoryStarsByIDs(ids []int) []repository {
	var (
		length = len(ids)
		result = make([]repository, length)
		wg     = new(sync.WaitGroup)
	)

	var packs = packer.Pack(length, requestLimit)

	for _, pack := range packs {
		for i := pack.From; i < pack.To; i++ {
			wg.Add(1)

			go func(i int) {
				var id = ids[i]

				result[i] = repository{
					id:        id,
					starCount: fetchRepositoryStarByID(id),
				}

				wg.Done()
			}(i)
		}

		wg.Wait()
	}

	return result
}

Схожий приклад бачив у реальному проекті.

Недолік такого рішення — одна тривала операція затримає виконання всієї пачки, тому переписував на варіант з воркерами.

Епілог

Ми в проекті вибрали варіант з воркерами, що відправляють пачками.

Репозиторій, у якому тестував варіанти.

Далі буде.

Разворачиваем AWS для разработки локально на базе LocalStack

$
0
0

Сейчас все больше компаний уходит в облака для запуска своих приложений. Мы в компании Namecheapне стали исключением и уже довольно долго используем сервисы AWS. В связи с этим перед нами встала задача упростить работу с сервисами AWS в условиях локальной разработки. Как приблизить локальное окружение к условиям прода?

В этой статье мы с вами поднимем небольшой проект, который будет взаимодействовать со стабами сервисов AWS, таких как: DynamoDB, SNS/SQS и S3.

Одним из самых распространённых решений для стабов сервисов AWS является LocalStack. Ранее этот проект разрабатывался Atlassian, но теперь брошен в дикий open-source и монетизируется за поддержку ряда дополнительных сервисов и саппорт.

TL; DR

  1. Поднимаем LocalStack при помощи docker-compose.
  2. Переключаем проект на эндпоинт сервиса LocalStack.

Холодный старт на Windows

Самый простой путь развернуть LocalStack локально — запустить его при помощи Docker Compose.

Для начала нам нужно установить рабочую среду разработчика Docker for Windows. Установка и настройка этого инструмента выходит за пределы статьи, так что оставлю вам ссылочку на хороший официальный мануал.

В содержимое docker-compose-файла запишем такой код:

version: '2.1'
services:
localstack:
image: localstack/localstack:latest
ports:
- "4567-4584:4567-4584"
- "8080:8080"
volumes:
- "//var/run/docker.sock:/var/run/docker.sock"
environment:
- SERVICES=dynamodb
- PORT_WEB_UI=8080
- DOCKER_HOST=unix:///var/run/docker.sock

Осталось только поднять docker-compose-сервис:

docker-compose -f docker-compose.yml up -d localstack

Обратите внимание на установленную переменную окружения SERVICES. С ее помощью сейчас включён сервис DynamoDB. Чтобы включить другие сервисы, настроить Debug-трейсы и кое-что ещё, настоятельно рекомендую взглянуть в мануал.

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

docker: Error response from daemon: driver failed programming external connectivity on endpoint localstack_main (a156a7ce6d590937504c17b1f37f4634e7eaec09a9f8ba20cdf37b94424db39f): Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.

На одной из испытуемых систем это выглядело как-то так:

...
ports:
- "4567-4584:4567-4584"
- "9090:8080"
...
environment:
- PORT_WEB_UI=9090
...

Можно попробовать запустить LocalStack, как по мануалу — localstack start —docker. Но есть ряд минусов. Во-первых, вам придётся установить окружение Python, для того чтобы при помощи pip установить LocalStack. А во-вторых, вам понадобится либо установить докер, либо установить Java-окружение, для того чтобы заработали некоторые стабы сервисов.

Работа с DynamoDB

Итак, у нас уже запустился и работает LocalStack. Теперь мы можем проверить работоспособность и заодно подготовить сервисы, с которыми будем работать. Для настройки этих сервисов придётся использовать AWS CLI. Надеюсь, он уже у вас установлен. Для того, чтобы подключиться к нашим сервисам, нужно будет указать в конце команды кастомный эндпоинт при помощи следующего параметра —endpoint-url=http://localhost:4578, где номер порта мы можем взять из таблицы официального мануала.

Для начала проверим, что скажет LocalStack о состоянии таблиц:

aws dynamodb list-tables --endpoint-url=http://localhost:4569
{
    "TableNames": []
}

После чего создадим таблицу:

aws dynamodb create-table --table-name Todo \
--key-schema AttributeName=Id,KeyType=HASH --attribute-definitions AttributeName=Id,AttributeType=N AttributeName=Name,AttributeType=S \
--provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 --endpoint-url=http://localhost:4569 

И ещё раз взглянем в lLocalStack на список. Он покажет только что созданную таблицу:

aws dynamodb list-tables --endpoint-url=http://localhost:4569
{
    "TableNames": [
        "Todo"
    ]
}

Ну что же поздравляю, теперь у вас есть свой первый локальный сервис амазона.

HINT:Для тех, кому нужно сетапать инфраструкту не в ручном режиме, а с помощью терраформ, есть отличный механизм сделать это, задав маппинг ендпоинтов в модуле AWS:

provider "aws" {
    skip_credentials_validation = true
    skip_metadata_api_check = true
    s3_force_path_style = true
    access_key = "mock_access_key"
    secret_key = "mock_secret_key"
    endpoints {
        dynamodb = "http://localhost:4569"
    }
}

Чуть больше инфы по этому вопросу можно взятьздесь.

Теперь давайте попробуем подключиться к DynamoDB из нашего тестового приложения. В любимой IDE создаём консольное dotnet core приложение. И сразу же устанавливаем пакет AWSSDK.DynamoDBv2. Общие правила для большинства подключения к сервисам LocalStack:

  1. Переключаемся на использование HTTP-протокола (LocalStack из коробки работает через HTTP,хотя и поддерживает https).
  2. Устанавливаем ServiceURL на порт этого стаба.

Давайте настроим подключение:

var clientConfig = new AmazonDynamoDBConfig()
{
    UseHttp = true,
    ServiceURL = "http://localhost:4569"
};

_dynamoClient = new AmazonDynamoDBClient(clientConfig);

После этого мы можем положить в нашу таблицу первое значение:

var putItemRequest = new PutItemRequest()
{
    TableName = TableName,
    Item = 
    {
        {
            "Id", new AttributeValue() { N = "42"}
        },
        {
            "Name", new AttributeValue() {S = "Get Up Early"}
        }
    }
};
await _dynamoClient.PutItemAsync(putItemRequest);

Можем проверить, что же сохранилось в LocalStack следующей командой:

aws dynamodb get-item --table-name Todo --key '{"Id":{"N":"42"}}' --endpoint-url=http://localhost:4569
{
    "Item": {
        "Id": {
            "N": "42"
        },
        "Name": {
            "S": "Get Up Early"
        }
    }
}

Добавляем SNS & SQS

Представим, что теперь нам нужно добавить SNS и SQS. Начнём с SNS. Для начала включим сервис и создадим топик. Для этого в compose-файле добавим в переменную окружения SERVICES разделённые запятой имена сервисов, как это сделано ниже:

...
environment:
- SERVICES=dynamodb,sns,sqs,s3
...

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

docker-compose -f docker-compose.yml restart localstack

В проект добавим nuget-пакеты AWSSDK.SimpleNotificationServiceи AWSSDK.SimpleNotificationService, для того чтобы получить возможность взаимодействовать с этими сервисами.

Как и для предыдущего случая настраиваем подключения:

var snsConfig = new AmazonSimpleNotificationServiceConfig()
{
    UseHttp = true,
    ServiceURL = "http://localhost:4575"
};

snsClient = new AmazonSimpleNotificationServiceClient(snsConfig);

var sqsConfig = new AmazonSQSConfig()
{
    UseHttp = true,
    ServiceURL = "http://localhost:4576"
};

sqsClient = new AmazonSQSClient(sqsConfig);

Теперь мы можем работать с этими двумя сервисами локально. Давайте сразу же создадим очередь и топик и подпишемся очередью на него:

private void CreateQueue()
{
    var queueCreationResult = await sqsClient.CreateQueueAsync("MyQueue");
    var queueUrl = queueCreationResult.QueueUrl;
    var topicCreationResult = await snsClient.CreateTopicAsync(new  CreateTopicRequest("TopicName"));
    var topicArn = topicCreationResult.TopicArn;
    var subscribeRequest = new SubscribeRequest(topicArn, "sqs", queueUrl);
    var subscribeResponse = await snsClient.SubscribeAsync(subscribeRequest);
}

В тестовых целях отправим в топик оповещение и вычитаем его из очереди:

...
// Publish message to topic
var request = new PublishRequest
{
    TopicArn = topicArn,
    Message = "Test Message"
};

await snsClient.PublishAsync(request);

...
// Read message from queue
var result = await sqsClient.ReceiveMessageAsync(queueUrl);
foreach (var message in result.Messages)
{
    Console.WriteLine(message.Body);
}
...

В консоли мы видим следующее:

{"MessageId": "e4e6ef59-107a-479d-952d-2a9b9e2da15c", "Type": "Notification", "Timestamp": "2019-10-05T13:27:36.397Z", "Message": "hello", "TopicArn": "arn:aws:sns:eu-west-3:000000000000:test"}

Это говорит о том, что всё успешно работает.

Сервис S3

Давайте примемся за самый используемый сервис — S3. Так как ранее мы его уже включили, можем оставить compose-файл в покое.

Устанавливаем nuget AWSSDK.S3и создаём следующий конфиг для использования LocalStack-овского S3. Ничего нового — HTTP и кастомный порт, на котором крутится сервис:

var clientConfig = new AmazonS3Config()
{
    UseHttp = true,
    ServiceURL = "http://localhost:4572"
};
s3Client = new AmazonS3Client(clientConfig);

Давайте посмотрим, как этот сервис работает. Для этого создадим ведёрко и зальём на него файл.

await s3Client.PutBucketAsync(BucketName);
var putRequest = new PutObjectRequest()
{
    BucketName = BucketName,
    Metadata = { ["x-amz-meta-title"] = "Title" },
    FilePath = Path.GetFileName(FileName),
    ContentType = "text/plain"
};
await s3Client.PutObjectAsync(putRequest);

Можем взглянуть на его содержимое:

var result = await s3Client.ListObjectsAsync(BucketName);
foreach (var s3Object in result.S3Objects)
{
    Console.WriteLine(s3Object.Key);
}

Попробуем скачать:

using (GetObjectResponse response = await s3Client.GetObjectAsync(BucketName, FileName))
using (Stream responseStream = response.ResponseStream)
using (StreamReader reader = new StreamReader(responseStream))
{
    Console.WriteLine("Object metadata, Title: {0}", response.Metadata["x-amz-meta-title"]);
    Console.WriteLine("Content type: {0}", response.Headers["Content-Type"]);
    Console.WriteLine(reader.ReadToEnd());
}

Осталось только подчистить за собой состояние сервиса:

await s3Client.DeleteObjectAsync(BucketName, FileName);
await s3Client.DeleteBucketAsync(BucketName);

Выводы

Это всё! Вот так мы подключили приложение, настроили и поработали со стабами трёх сервисов AWS — DynamoDB, SNS/SQS и S3. Теперь, зная, как пользоваться этим инструментом, мы можем вести разработку приложения локально, а не реальный демо-аккаунт AWS. Это даёт нам возможность с самого начала разработки задать высокий уровень development experience. Всем, кому интересно чуть больше поиграться с LocalStack и попробовать взаимодействие с ним в тестовом проекте, прошу в репозиторий.

Viewing all 8776 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>