Хеджирование успеха

Термин «хеджирование успеха» – довольно странный. Поиск по этой ключевой фразе в интернете ничего особо не дает. Откуда же он взялся?

Я его узнал от одного очень толкового собственника, на котором я и пытался применить этот метод. Он меня раскусил, и объяснил мне, что это – хеджирование успеха. Мне термин понравился, запомнился, и я его теперь с удовольствием применяю. Как и сам метод.

Суть метода проста: попросить чего-то для себя в момент достижения промежуточного успеха.

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

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

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

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

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

Но тут есть одна загвоздка. Если вы доведете изменения до конца – красиво, успешно – и после придете к начальнику за повышением, высока вероятность отказа, особенно если проект был длительный. Потому что сразу меняется тональность разговора – с «хочу попробовать сделать лучше» на «пора платить по счетам». Дело-то уже сделано – причем, безо всякого напряга со стороны начальника или собственника, и тут вы этот самый напряг приносите.

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

Получается, вы как бы говорите – смотри, как все здорово получается, то ли еще будет! Начальник радуется, попадает на волну успеха, хочет большего – в этот момент вы его и подлавливаете. Безо всяких ультиматумов, вроде «добавьте зарплату, иначе не буду продолжать» — ни в коем случае.

Лучше в разговоре как бы отвязать одно от другого, успех от повышения. Сначала, понятное дело, обсуждаете успех. Рассказываете во всех деталях, с цифрами (если они есть), и, главное, мягко добиваетесь признания этого успеха. Можно применять фразы вроде «как думаете, хороший результат?», «вот никак не могу найти примеры аналогичных проектов, чтобы сравнить, может вы знаете?», «мне так нравится этот проект, и вроде получаться начало, хочу продолжить» и т.д. Главное – подтолкнуть его к обсуждению успеха, к признанию, к построению дальнейших планов развития и т.д.

И тут – бац! – как бы невзначай, говорите о своем повышении. Зарплата, должность, новые сотрудники, новый ноутбук, новый станок – что там вам нужно, я не знаю. Не связываете просьбу с успехом, т.е. не говорите фраз вроде «ну раз вы согласны, что я молодец, дайте мне зарплату». Можно использовать фразы-разрывы, типа «отлично, есть еще один вопрос», или «так, что там еще… А, вот, вспомнил».

Не связывая одно с другим, вы, как говорят психологи, не вступаете в отношения зависимости. Успех – своей дорогой, карьера – другой. Вы не выглядите торгашом, нуворишем или карьеристом. Нормальный, здоровый интерес и мотивация успешного сотрудника.

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

Если он отказал, то в здоровой системе координат он будет злодеем. Как же, ведь успешный сотрудник, инициативный, результативный, самостоятельный, и попросил всего лишь… Ну, чего вы там попросили. Именно попросили, а не потребовали, не выторговывали, не ставили ультиматумов. У начальника отныне будет, что называется, сосать под ложечкой – ощущение вины, будто что-то не так, останется с ним.

Как вариант, он может сказать – ок, я понял твою просьбу, давай тогда согласуем критерии. То есть, он предложит вам договоренности.

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

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

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

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

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

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

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

Теперь несколько примеров.

Пример с моей первой работы, в фирме-партнере 1С. Как я уже рассказывал, зарплата там зависела от наличия сертификатов «1С: Специалист». Чем больше у тебя сертификатов, тем выше часовая ставка.

Кроме часовой ставки, был еще оклад. Если ты сделкой закрыл больше, чем оклад, то получаешь сделку. Если работы не было в должном объеме, получаешь оклад.

В первый месяц работы у меня, разумеется, никакой выработки не было. Я не знал 1С, т.к. это была моя первая работа, а в институте мы изучали Delphi, C++, Ассемблер, MatLab и т.д. Соответственно, задачи клиентов решать не мог.

Поэтому заботы было две – как можно быстрее научиться и получить все сертификаты (чтобы была большая выработка при высокой часовой ставке) и поднять оклад, чтобы пока не прозябать за копейки.

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

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

После этого состоялся разговор с директором. Я в красках, эмоционально, рассказал ему о прошедшем экзамене (там было о чем рассказать), и спросил – а как остальные сдают? Он посетовал, что никто особо не сдает, все сидят и не чешутся. Я спросил – а когда люди, обычно, идут на первую аттестацию? Директор сказал, что обычно – через несколько месяцев. Ну и сам догадался, что мой сертификат через месяц работы – это успех. Тут я и ввернул просьбу о повышении оклада. Пока он думал, я рассказал о планах на следующую аттестацию – через месяц.

Ему ничего не оставалось, как согласиться, и повысить мне оклад.

Второй пример связан с проектом по наведению порядка на складе, который стал основой событий бизнес-романа «Проще, чем кажется».

Целью проекта было снижение отклонений по результатам инвентаризаций – они доходили до 25 %, надо было довести хотя бы до… Никто точно не знал, до чего – короче, снизить хоть как-то.

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

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

Подгадав момент, я обратился к собственнику с просьбой о повышении зарплаты. Чтобы не мелочиться, сразу на 50 %.

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

Что ему было делать? Согласился.

Третий пример – тот самый, где появился термин «хеджирование успеха».

Когда я руководил внедрением стратегии компании, должность у меня была прежняя – ИТ-директор. Соответственно, в моем подчинении были программисты.

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

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

Так вот, я запулил одного программиста внедрять скрам в конструкторском отделе, а заодно – потоковый скрам в снабжении. Второго программиста отправил внедрять ТОС в обеспечении консигнационного склада. Руководил работой я, но значительная доля тяжелой работы досталась программистам, чему они были безмерно рады.

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

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

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

Сам, конечно, немного расстроился – в основном, за программистов. У меня-то мотивация была понятная, а они рисковали. Но, после нескольких разговоров про комплект увольнения, и видя мою искреннюю заинтересованность в их успехе, сказали «да забей, нам интересно, такой опыт, драйв, эгегей!». И мы продолжили внедрение стратегии.

Через какое-то время пришел директор, и сам предложил поднять зарплату.

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

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

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

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

А то, что он бегает по ним по всем, помогает документы в ворде редактировать – его личный выбор. С этим он постоянно спорил, говоря о критической важности помощи пользователям.

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

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

А мой бегал, и выдавал это за успех. При этом, очень многие были его работой недовольны, и вы понимаете, почему. Чем больше бегаешь, тем больше будешь бегать. Как пела старуха Шапокляк, кто людям помогает – тот тратит время зря.

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

Знаете, что отвечал сисадмин? «Да это все понятно! Но все-таки…», и дальше опять шло перечисление количества рабочих мест и других неуспешных успехов.

Резюме

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


ссылка на оригинал статьи https://habr.com/post/427523/

Обзор самых интересных докладов Joker 2018: версия EastBanc Technologies

Привет, хабровчане!

В этом посте хотим поделиться своими впечатлениями от конференции для Java-разработчиков Joker, что из услышанного нам запомнилось больше всего.

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

Day 1

Don’t walk away from complexity, run — Venkat Subramaniam

Agile — это способность подстроиться под изменения. Эффективно использовать Agile нам мешает нашими же руками созданная сложность систем.

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

Как мы сами делаем системы сложными:

  • Moving parts
    Делаем ненужную конфигурацию, создаем неиспользуемые компоненты, создаем слишком много слоев и т.п.
  • Нечитаемый код
    «Этот код работает, но выглядит так, что не должен». Сложный для восприятия код ведет к невидимости изменений. Непрозрачные изменения порождают баги и мешают пониманию, что происходит с объектом.
  • Слишком много зависимостей
    Зависимости быстро становятся несовместимыми, чем их больше, тем сложнее этим управлять.
  • Безрассудная страсть внедрять новые технологии
    Попробуйте ответить себе на вопросы:

    — Какова цена внедрения новой технологии?
    — Насколько легко будет отказаться от выбранной технологии?
    — Библиотека или фреймворк? Библиотеку вы используете, а фреймворк вас «окружает». От библиотеки значительно проще отказаться, чем от фреймворка. Поэтому решение об использовании фреймворка нужно принимать более взвешенно. Если будет легко вернуться на старый подход и если мы это сможем доказать, то нужно брать. Не скачивайте то, что вам действительно не нужно.
    — Resume Driven Development.

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

Transaction cascades, or how to build a transactional microservice architecture — Harald Wendel

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

По сути, в докладе есть одна идея – отказаться от транзакций при переходе на распределённую систему.

Как работает бывшая транзакционная операция:

  1. Она всё еще transactional, но только одна бизнес-операция (условно одна) коммитается в базу. Другие в рамках транзакции сохраняют в базу данные для Kafka.
  2. Также в рамках транзакции мы получаем новый State бизнес-операции. Это полностью корректный самодостаточный State.
  3. Специальный обработчик читает базу: либо polling, либо commit hook на сущности, если обработчик в том же месте, где сущность. Затем отправляет в Kafka сообщение.
  4. Подписчики Kafka обрабатывают сообщения. Тут нам полезен стандартный механизм гарантии доставки. Сообщения лежат в Kafka нужное время и когда-нибудь обработаются сервисом.
  5. При обработке подписчики могут коммитать в свои базы и менять свой State. При этом сервисы обмениваются State.
  6. Rollback бизнес-транзакции нет. И есть три варианта обработки проблем:
  • До победного конца ждать, чтобы корректно обработали сообщение из Kafka.
  • При ошибке (и нужного количества повторов) переводит заводить соответствующий «ошибочный» State.
  • Отправлять в Kafka сообщение, чтобы его обработал инициатор бизнес-транзакции (и другие участники), для проведения мер по откату своих локальных транзакций.

Память Java-процесса по полочкам – Андрей Паньгин

Доклад Андрея можно использовать как справочник и how-to по отладке проблем с утечкой нативной памяти на примере non-heap памяти.

Доклад полезен для понимания, кто и что съедает память. Андрей показывает инструменты для анализа памяти, в том числе AsyncProfiler, который встроен в Idea: «The upcoming IntelliJ IDEA 2018.3 integrates a low overhead sampling profiler that can profile JVM and Native code – Async profiler».

Мы рекомендуем всем посмотреть его и прогнать по тем же шагам свои модули и микросервисы.

Pattern matching и его воображаемые друзья – Тагир Валеев

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

Приключения Сеньора Холмса и Джуниора Ватсона в мире разработки ПО [Joker Edition] – Евгений Борисов и Барух Садогурский

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

Мы отметили в рассказе самые полезные моменты:

  • В Spring 5 можно добавлять бины и прочие штуки спринга во внешнем groovy файле. Т.е. не надо пересобирать, только перезапустить, например, чтобы добавить BeanPostProcessor.
  • Нужно помнить о наименовании бинов. Например, нельзя создать бин ConversionService, т.к. такой уже есть в кишочках спринга.
  • Нужно помнить о стандартах. Например, multipart разрешен только для post, и Spring за этим бдит.
  • Нужно читать документацию. Объясним на примере ломбок. AllArgsConstructor добавляет аннотацию java.beans.ConstructorProperties для конструктора. При этом если аннотации нет, Jacson использует конструктор по умолчанию и геттеры, т.к. имена параметров конструктора не сохраняются после компиляции. Если аннотация есть, в ней указаны имена параметров (в соответствии с конвенцией java beans), и Jacson использует конструктор.Lombok аннотация SneakyThrows меняет Checked исключения на Unchecked исключения.
  • Также в докладе озвучили интересный вопрос: «Нужны ли нам Checked exceptions в принципе?» Мы задумались.

Day 2

Реактивный хардкор: как построить свой Publisher<?> – Олег Докука

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

Machine learning in Java from nothing to production in one hour – Derek Ferguson

Можно послушать, если занимаешься Machine Learning. Хотя не очень понятно, для кого предназначался доклад. Если люди разбираются, то для них это уже не интересно. Если не разбираются, то по этому докладу и не разберутся, слишком мало информации на понимание.

Основной посыл таков: можно использовать гугловый TensorFlow для обучения моделей из Java, но поддержка обучения ограничена. Зато можно использовать обученные модели. Например, загрузить в TensorFlow-микросервис обученную модель и слать в неё запросы из Java или другого микросервиса для получения ответа. Например, распознай картинку, скажи по симптомам, что за болезнь…

А еще у команды TensorFlow есть Docker Image с TensorFlow, который можно использовать для загрузки туда моделей и отправки запросов на применения этих моделей. Sweet!

Micronaut vs Spring Boot, или Кто тут самый маленький? – Кирилл Толкачёв и Максим Гореликов

Кирилл и Максим сравнивали современные фреймворки по скорости запуска, по объему необходимой для запуска памяти и по сложности кодирования.

Наше внимание привлек один факт: Micronaut реализует DI во время компиляции, а Spring — во время запуска/работы. Это позволяет Micronaut запускаться быстрее. Но пока не вышла релизная версия Micronaut, приходится верить на слово.

Реактивный раздатчик ok.ru/music — Вадим Цесько

Вадим Цесько рассказывает про архитектуру раздатчика музыки в «Одноклассниках». В докладе есть описание серверов и их ролей, описание балансировки и как обеспечивается Fault Tolerance и High Availability. Отдельно — про реактивный подход на реальном кейсе без особых технических подробностей. OK показали рабочий пример использования реактивного подхода.

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

Reactive Spring — Josh Long

Доклад, ради которого мы ехали:) На самом деле нет, но Джош Лонг — одна из двух больших звезд конференции. Его доклад крут, совмещает в себе и юмор, и технику.

То, что мы называем докладом на деле было это live coding сессией по созданию реактивных микросервисов с использованием Spring WebFlux. Он даёт общее понимание, что такое Reactive API, предлагает пример использования в Spring 5, а бонусом идет весёлая подача материала. Еще был пример с Reactive Proxy как альтернатива Zuul. Советуем всем посмотреть.

Мир окончательно стал реактивным. Или общее впечатление от докладов Joker

Было много докладов об этом и ещё больше это обсуждали в дискуссионных зонах. На самом деле большой вопрос, cтал ли мир реактивным или он таким был давно, но теперь придумали новое название для старых паттернов и влили в них новую кровь.

Среди докладов о реактивности были на любой вкус: и чисто технические, например, Josh Long, который рассказал, как делать реактивность на спринге. И реальные кейсы применения реактивности — например, Вадим Цесько из Однокласников.

Наша основная технология — это Spring, поэтому доклад Josh Long считаем обязательным к просмотру. (Ссылка на репозиторий из доклада). Там есть пример реактивного сервиса, который реактивно работает с Mongo, и реактивного сервиса, который реактивно проксирует другой реактивный сервис. Нам было довольно полезно это узнать.


ссылка на оригинал статьи https://habr.com/company/eastbanctech/blog/427517/

CI/CD простого системного администратора

В процессе работы появилась идея автоматизировать доставку powershell скриптов, а также синхронизировать работу в команде среди системных администраторов со скриптами выполняемыми на разных серверах. Статья рассчитана на простых win администраторов незнакомых глубоко с git, gitlab, ci/cd и прочими devops заморочками, поэтому если интересно прошу под кат.

Начнем с проблем которые возникали при работе

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

Все эти проблемы на самом деле мелочны в единичных случаях, но когда все это уже находится в масштабах команды и кучи скриптов, то хотелось бы навести в этом порядок.
Для упрощения жизни я использовал замечательный продукт Gitlab, уже развернутый у нас и используемый кодерами. Я не буду рассматривать процесс установки gitlab и gitlab-runner, просто уточню что у нас уже есть настроенный gitlab с доменной авторизацией и отдельный runner на windows с powershell executor, который и будет выполнять наши задачи развертывания. Для написания скриптов я использую отличный Visual Studio Code.

Организуем работу в gitlab

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

создание группы

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

создание проекта

После создания проекта, на первой же страничке будут все подсказки на тему «что делать дальше». В нашем случае нужно запушить существующие файлы со своей рабочей станции в gitlab. Для примера все это лежит в каталоге «E:\scripts\powershellmegaproject». Воспользуемся соответствующей подсказкой и выполним на своем компьютере:

cd E:\scripts\powershellmegaproject git init git remote add origin http://gitlab.domain.net/sysadminsdev/powershellmegaproject.git git add . git commit -m "Initial commit" git push -u origin master

Бинго! Все наши файлики из каталога «E:\scripts\powershellmegaproject» теперь в нашем проекте.
Что дальше? Откроем VSCode и попробуем внести изменения в наш powershell скрипт, находящийся в этом каталоге. Сохранив файл, мы увидим в разделе «Source Control» уведомление, где можно посмотреть изменения и сделать коммит. Далее делаем пуш на сервер:

vscode git

Проверим на сайте проекта в gitlab, там будет актуальное содержимое файлов, а в истории коммитов можно отследить изменения.

Настройка CI/CD

Пора настроить доставку скриптов на сервер. Для работы CI/CD для вашего проекта должен быть доступен runner. Назначить его можно в админке gitlab — runners, либо использовать shared runner`ы.
А теперь к проекту. Что бы CI/CD заработало необходимо создать в каталоге с нашим проектом файл .gitlab-ci.yml с описанием действий (подсказку и help об этом можно так же увидеть при переходе в меню gitlab — CI/CD — Pipelines). Для доставки файлов можно выбрать различные способы, от просто копирования файлов, до rsync или git pull на нужный сервер. Так как мы рассматриваем самый простой сценарий, то будет просто копирование powershell`ом. Для этого необходимо сделать папку на целевом сервере со скриптом общедоступной в сети и предоставить доступ на изменение пользователю под которым запущена наша служба gitlab-runner.
Заполним .gitlab-ci.yml простым содержимым:

deploy_stage:   variables:     DEST_DIR: \\srv-megaserver\scripts\powershellmegaproject   script:     - remove-item -path $DEST_DIR\* -recurse     - gci -Recurse | Copy-Item -Destination $DEST_DIR

Тут мы запишем в переменную путь до нашего каталога (в других проектах можно просто копировать этот файл и менять целевой каталог) и простой powershell командой сначала удалим все содержимое каталога, а потом скопируем все из нашего проекта в эту папку.
Коммитим, пушим изменения и проверяем. В нашей папке на сервере должны обновится все файлы. Посмотреть статус и выполнение Pipeline можно в том же разделе нашего gitlab — ci/cd — pipelines, пример успешного выполнения:

 Running with gitlab-runner 11.3.1~beta.4.g0aa5179e (0aa5179e)   on gl-runner2-windows a24eda81 Using Shell executor... Running on SRV-GL-RUNNER2... Fetching changes... HEAD is now at e6e9a2c update ci file From http://gitlab.domain.net/sysadminsdev/powershellmegaproject    e6e9a2c..5f5cfce  master     -> origin/master Checking out 5f5cfceb as master... Skipping Git submodules setup $ remove-item -path $DEST_DIR\* -recurse $ gci -Recurse | Copy-Item -Destination $DEST_DIR Job succeeded

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

Что с коллегами?

Все просто, создаем папку для проектов, переходим в неё в ps/cmd и клонируем проект к себе.

 cd e:\projects git clone http://gitlab.domain.net/sysadminsdev/powershellmegaproject.git 

Всё, дальше просто работаем в VSCode открыв папку, делая коммиты и пуши.

Чего мы добились в итоге

  • все скрипты у нас хранятся в репозитарии;
  • вся группа администрирования может работать со скриптами;
  • все изменения видны в истории;
  • любой новоиспеченный администратор сразу видит все наработки и ему не нужно бегать по серверам и узнавать «где-что выполняется»;
  • все продуктивные изменения автоматически доставляются на «продуктивное место работы».

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

Бонусом

Добавьте файл README.md в каталог с проектом для описания что в этих скриптах вообще происходит.
Добавьте файл Changelog для описания изменений.

ps: что можно еще? Можно крутить runner в docker, можно конфигурить scheduler в ansible, можно еще много чего и по сложней, но целью статьи было упростить понимание данного инструментария для новичков.


ссылка на оригинал статьи https://habr.com/post/427377/

ДомоДанные: как анализ данных используется в архитектуре и урбанистике

Преподавали мы в GoTo свои нейроночки, XGBoos’ы, SVM’ы и прочие случайные леса, и тут до нас кое-что дошло — мы много говорим про технологии и почти ничего не рассказываем про области, в которых их можно применить.
Мы решили исправить эту оплошность циклом статей, в которых расскажем о разных областях с неожиданно большими объемами данных, возьмём интервью у аналитиков и разработчиков, расскажем про проекты, которые мы решили попробовать сделать на школе и так далее.

И начнём мы с немного экзотических сфер — урбанистики и архитектуры.

Если хотите узнать подробности, прочитать интервью с техническим директором аналитической компании Habidatum и куратором программистко-архитектурных проектов из МАРХИ — милости прошу под кат.

Урбанистика

Начнём с урбанистики.

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

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

Подробнее об этой области расскажет технический директор аналитической компании Habidatum Вадим Смахтин.

Интервью: Вадим Смахтин

Знакомство

Итак, начнём. Расскажите, пожалуйста, кто вы и чем занимаетесь?

Меня зовут Вадим, я технический директор компании Habidatum. Я занимаюсь проектированием различных систем, сервисов и устройств для работы с данными. Более пяти лет я разрабатываю софт для визуализации и аналитики данных, связанных с городской тематикой. Иногда напрямую участвую в аналитических проектах.
Фактически, в компании я являюсь «прослойкой» между программистами и урбанистами.

Расскажите про Habidatum. Чем вы занимаетесь?

Мы с друзьями основали Habidatum около пяти лет назад. Как тогда, так и сейчас мы занимаемся аналитикой данных для архитекторов и градостроителей, у которых есть вопросы относительно характеристик функционирования среды. Если они хотят узнать, как среда используется, как она отреагирует на нововведения (строительство новых зданий, переделка проезжей части в пешеходную зону…), как можно оптимизировать её использование и т.д., они приходят к нам. Также с недавних пор мы продаём свой аналитический софт.
Как технический директор, я отвечаю за архитектуру и спецификацию наших софтверных решений и курирую их разработку. Сейчас у нас есть целая линейка внутренних и внешних продуктов, одним из которых является система для визуализации данных “Хронотоп”.

Хронотоп

Что за Хронотоп?

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

Существуют ли аналоги Хронотопа?

Хронотоп — это достаточно нишевая система, поэтому очень сложно говорить про каких-то прямых конкуртентов. Есть GIS системы типа QGIS и ArcGIS, есть системы визуализации данных, как, например, “Tableau”; есть аналитические пакеты, у которых нет своей визуализации — а продуктов, которые бы соединяли обе функции практически нет. Есть конечно ArcGIS, которые даже выпустили свой пространственно-временной куб, но у них он статический, поэтому функционал крайне ограничен. Плюс у них это десктопное приложение, а у нас всё работает в облаке.

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

Есть ли в Хронотопе какие-то математические или статистические модели или он только про визуализацию?

Изначально да, он был только про визуализацию. Конечно, там были какие-то базовые подсчёты статистик, но ничего такого. Но теперь, после того, как удалось успешно запустить графический движок в облаке, мы прикрутили к нему систему детекции аномалий, которая указывает аналитику интересные места, на которые стоит обратить внимание. У системы также есть открытый API, который позволяет писать свои детекторы. Это пока достаточно экспериментальная штука, но релиз уже скоро.
Также сейчас мы пробуем использовать “Хронотоп” для моделирования поведения среды, анализа постэффектов и предсказательного построения пространственно-временного куба.

Постэффектов?

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

Можешь рассказать про ваш стэк?

Сам рендерный движок написан на плюсах, активно используем CUDA и OpenGL шейдеры, которые рисуют воксельный обьем. Бэк по большей части написан на Питоне (Django). Конечно, возможно, это не лучшее проектировочное решение, но, т.к. сначала мы стремились максимально снизить порог вхождения для новых разработчиков, Питон казался лучшим выбором. Конечно, Питон удобен для написания аналитических модулей, но всю инфраструктуру писать на нём достаточно странно. Сейчас мы используем микросервисную инфраструктуру, поэтому в скором времени скорее всего перепишем обслуживающие модули. На фронтенде всё достаточно стандартно, кроме, наверное, TypeScript’а, который мы внесли ещё в одной из первых релизных версий. Из фреймворков — React и Redux

Аналитический отдел

Какого рода исследования проводит аналитический отдел?

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

Можешь рассказать пару примеров?

В принципе все проекты есть на нашем сайте, там можно посмотреть подробнее.

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

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

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

Какие люди работают у вас аналитиками?

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

А программисты участвуют в работе аналитиков?

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

Например?

Есть сентимент анализ, word2vec для поиска синонимов, топик моделинг и прочий NLP. Это, конечно, не супер адвандст вещи, но наша работа не столько в разработке bleeding edge методов, сколько в использовании уже готовых алгоритмов для нужд города и строительства. Поэтому и разработчиков в дата сайнс отдел мы ищем таких, которым была бы интересна урбанистика и всё, что с ней связано. У нас было бы тяжело работать, например, людям, увлекающимся спортивным машинным обучением, в котором природа данных почти не важна. У нас задачи стоят не в выбивании лишних процентов из модели, а в понимании специфики данных, поэтому важным является именно интерес к теме и умение общаться с соответствующими специалистами.

Вообще насколько аналитикам нужно уметь программировать, если у вас есть специальные команды для этого?

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

Куда посоветуете пойти учиться будущему аналитику из мира урбанистики?

У нас работает большое количество ребят из Высшей Школы урбанистики. Не знаю, как там с точки зрения программирования, но с точки зрения урбанистического образования, это хорошее образование. Ну а для программирования существует огромное количество онлайн и просто курсов.
С точки зрения программиста мне кажется, что можно пойти в любую школу, которая занимается анализом данных (как ШАД, например), получить там основы машинного обучения и статистики и после этого начать делать какие-то проекты, связанные с городом.

Архитектура

Но не урбанистикой единой, товарищи.

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

Про это нам расскажет Доцент Учебно-Научного Центра Архитектуры и Компьютерных технологий МАРХИ Милан Станкевич.

Знакомство

Расскажите, пожалуйста, кто вы, и чем занимаетесь?

Архитектор, Магистр архитектуры,
Доцент Учебно-Научного Центра Архитектуры и Компьютерных технологий МАРХИ.
Член Союза Московских Архитекторов
Куратор Интенсивов-Про “Алгоритмическое проектирование и Цифровое производство” в МАРШ
Главный Архитектор проектов в Цимайло-Ляшенко и Партнеры.

В основном занимаюсь проектированием зданий и всего, что можно назвать архитектурой.
Руководитель Магистерских диссертаций в МАРХИ.

Все что выше — это формальности.

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

Почему вы стали архитектором?

Поступил в архитектурный по советам родственников, но только на третьем курсе понял, каким архитектором хочу стать, после поступления в группу к немецкому проф. Михаэлю Айхнеру.
Также, побывав в качестве гостя в Мюнхене, Барселоне, Роттердаме, Делфте, Лондоне, а именно в архитектурных школах, расположенных там, сильно проникся идеями и мировоззрением местных школ.

Почему вы решили заниматься IT в архитектуре? Что вас привлекает в этом?

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

Про АД в архитектуре

Мы выяснили, зачем программирование урбанистам. А зачем оно архитекторам?

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

Одни из примеров применения:
http://www.zha-code-education.org/
http://drl.aaschool.ac.uk/portfolio/osteobotics-3/

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

Понятней всего про программирование в архитектуре может скорее всего рассказать
Михаэль Хансмайер
или Марк Бурри.

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

Какая область исследований на стыке программирования и архитектуры интересует вас больше всего? Расскажите про интересные проекты в вашей области

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

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

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

Или проект для Лондона, в котором предлагается сделать его более пешеходным. Вся аналитическая часть позволила выявить конечный “паттерн” пешеходных зон в городе и найти неприглядные пространства для того, чтобы их улучшить.

Есть ли у вас идеи относительно применения IT технологий в архитектуре, до которых ещё не дошли руки?

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

Но в частности сейчас больше интересует тема, затронутая в моей диссертации, а именно реновация жилых малоэтажных кварталов и переход их к умной “регенерирующейся” среде. На практике — это эффективное использование архитектурных элементов в умном городе, связь Iot (internet of things, Индустрии 4.0 c возможностями существующих жилых домов, самоорганизацией общества, соучастия жителей в архитектуре реновации своих домов)

Могут ли обычные программисты помочь вам в ваших исследованиях?

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

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

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

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

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

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

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

Про архитекторов

Чем занимается ваша кафедра?

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

До сих пор у нас достаточно широкий профиль изучения разных задач.
В частности от нашей кафедры имеются 4 дисциплины для студентов МАРХИ, а также мы готовим своих собственных Магистров. Для Бакалавров 1,2 курса у нас — Компьютерно Композиционно Комбинаторный Курс. Там студенты через ряд заданий от составления абстрактных композиций переходят к архитектурным фантазиям. Они занимаются трехмерным моделированием в 3dsmax.
Для 3го курса — Компьютерная графика, там студенты знакомятся с большим количеством программного обеспечения, позволяющего анализировать проекты, и оформлять архитектурную документацию.
А для магистров — Цифровые Средства Параметрического формообразования и Градостроительные исследования при помощи ГИС.
В данных курсах студенты знакомятся с более широким спектром программного обеспечения и начинают использовать элементы визуального программирования.

Где учиться программированию архитекторам? Как? Куда бежать? Что изучить перед этим? Есть ли open-source проекты/исследования по этой тематике?

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

Во-вторых, конечно, есть специализация, и по каждой теме конечно тоже существуют open source проекты и исследования, но реже встречаются.
Временами они переходят в формат семинаров и воркшопов.
Если говорить про качественные ресурсы, то их проводят в основном зарубежные школы.
Правда, если это формат воркшопа а особенно тематического, то зачастую это переходит в коммерческую историю и стоит участникам денег.
А так в основном увидеть проекты в области архитектуры и IT технологий можно увидеть на разных фестиваялх как например https://www.smartgeometry.org/
или по направлениям можно на порталах технологических институтов
ETH Zurich
ITKE
SciArch
MIT департамент Архитектуры
AA School of Lonson, DRL
Эти же институты проводят многочисленные воркшопы, рассматривающие ту или иную тему в области архитектуры и IT.

Если говорить про РФ, то все исследовательские проекты, курсы по данной теме, а также мероприятия в основном являются инициативами локальными и не имеют институционального характера.
Есть немногочисленные направления, которые проводят:
Интенсивы PRO: Алгоритмическое проектирование в МАРШ, SimplexNoise, ShukhovLab, Softculture.
Либо связка IT и архитектуры проходит в рамках отдельных дисциплин внутри процесса обучения архитектуре в МАРХИ и в МАРШ.

Список онлайн ресурсов также невелик, т.к. относится больше к получению навыков и обучению работе в программах, таких как Grasshopper, Dynamo для Revit. В меньшей степени можно найти онлайн курсы в какой-то отдельной области архитектуры, в основном они общие.
Открытых исследовательских ресурсов достаточно мало. Один из таких в 2011 году работал — Точка ветвления.

Что касается онлайн курсов зарубежных, то можно вспомнить
https://thinkparametric.com/
http://www.grasshopper3d.com/page/tutorials-1
и там же ссылки
http://designalyze.com/software/grasshopper
http://digitaltoolbox.info/ и т.д.
www.lynda.com
они направлены больше на изучение навыков.
Есть такие ресурсы, которые запускают отдельные компании
https://provingground.io
https://kierantimberlake.com/
http://www.carloratti.com
http://www.co-de-it.com
https://theverymany.com/

Насколько быстро архитекторы осваивают программирование?

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

А наоборот? Тяжело ли влиться программисту в область архитектуры? Стоит ли?

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

Есть ли что-то общее между программистом и архитектором.

Каких программистов и архитекторов рассматривать.
Но если мы говорим о тех которые работают в сфере “проектирования” новых “продуктов”, то их объединяет системный подход.
Разница в том что работа архитектора имеет другой временной и пространственный масштаб. От задумки до исполнения может проходить от двух трех дней до пара десятков лет. В среднем год-два.
Программист в этом плане раньше видит результат своей работы.
Но и один и второй являются как частью больших комплексных задач, так и могут быть самостоятельными творцами.
И также их работа “масштабируемая”, у программиста чуть больше, возможностей, правда, потому что, если архитектуру как физическую среду воспринимать, то она имеет существенные ограничения, пока результат программиста может выходить на планетарный масштаб.

Ну и напоследок — что можно почитать, чтобы понять, что такое архитектура на самом деле и почему это важно. Такой себе научпоп Architecture 101.

Наверное, можно начать от общих онтологических вещей, к примеру, любой книжки про историю архитектуры.
Или к тем, которые чуть более философские
Но я бы начал сразу с
“От постмодернизма — к нелинейной архитектуре. Архитектура в контексте современной философии и науки. Добрицына И.А. 2006
Чарлза Дженкса — Язык архитектуры постмодернизма
Вилияма Митчелла — “Я ++”,
Parametricism 2.0: Rethinking Architecture’s Agenda for the 21st Century

Или более прикладные — Кристофер Александер — Язык шаблонов.
Branko Kolarevic Architecture in the Digital Age: Design and Manufacturing

Для осведомленности о том что происходит в мире IT и архитектуры, следует скрее обращаться к журналам AD.

А при чем тут GoTo?

Недавно очередной шабаш GoTo прошел в стенах МАрхИ.

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

Из архитекторов в программисты.

На школе у нас было несколько ребят из МАрхИ, которые в первый раз окунулись в мир циклов, ифов и прочих goto (извините). Впечатлений было много.

Маша

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

Оля

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

Использовали сервис Face API от Microsoft, чтобы сделать фильтры для фотографий. Научились получать данные о пользователях социальной сети vk.com и попробовали анализировать эту информацию на выборке студентов мархи, визуализируя её разными способами: в виде круговых, столбчатых, пузырьковых диаграмм.

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

Проекты

Также мы сделали несколько проектов, связанных с архитектурной тематикой или направленных на нужды МАрхИ. Вот описания некоторых из них .

Изменение и генерирование фасадов.

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

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

Для этого мы натренировали VAE на фотографиях фасадов, натренировали классификатор, который бы предсказывал стиль фасада, и затем с помощью градиентного спуска изменяли вектор Hidden State’а с целевой функцией в виде кроссэнтропии по целевому распределению стилей и по фактическому.

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

Мы генерировали новые буквы (аля смесь B c H) и изменяли одну букву в сторону других (например сделать F из E). Да, это задача кажется далекой от целевой, но здесь у нас были хорошие данные (notMNIST), и сама специфика задачи ничуть не отличается. Соответственно, после сборки хорошего датасета с фотографиями фасадов, можно будет эту же модель натравить на первую задачу.
Реализацию Proof of concept можно посмотреть здесь.

Сейчас мы планируем ещё несколько проектов по урбанистике. Так что stay tuned!

Генерирование чертежей по эскизам

Архитектура — творческая профессия.

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

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

Архитектура сети: CycleGAN. Обучающую выборку мы сделали удалив целевые детали с готовых чертежей.

На проект можно посмотреть здесь.

РасписаниеБот

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

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

Принцип работы бота можно прочитать здесь, а на реализацию посмотреть вот тут.

Прощание

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

Мы в свою очередь будем открывать для себя новые области, в которых нужны аналитики и data scientist’ы, клепать на коленке проекты и рассказывать об этом вам.


ссылка на оригинал статьи https://habr.com/company/goto/blog/427489/

Как анализировать Thread Dump

В программе курса Разработчик Java довольно много тем,посвященных внутренностям работы JVM. Мы разбираемся в механизмах работы коллекций, байт-кода, сборщика мусора и т.д.
Сегодня предлагаем Вашему внимаю перевод довольно интересной статьи о thread dump-е. Что это такое, как его получить и как использовать.

Хотите узнать, как анализировать thread dump (дамп потоков)? Заходите под кат, чтобы узнать больше о том как в Java получить thread dump и что с ним потом делать.

Большинство современных Java-приложений являются многопоточными. Многопоточность может существенно расширить функционал приложения, в то же время она вносит существенную сложность.В однопоточном приложении все ресурсы (разделяемая память, операции ввода/вывода и т.д.) могут использоваться без синхронизации, т.к. в любой момент времени только один поток пользуется ресурсом.

В случае многопоточных приложений необходимо найти компромисс между усложнением программы и возможным повышением производительности, когда несколько потоков могут использовать все доступные (часто больше одного) ядра центрального процессора (CPU). Если сделать все правильно, то используя многопоточность (формализована в Amdahl’s Law), можно добиться существенного прироста производительности приложения. Однако при этом надо помнить об обеспечении синхронного доступа нескольких потоков к разделяемому ресурсу. В большинстве случаев, фреймворки, такие как Spring, инкапсулируют работу с потоками и скрывают от пользователей многие технические детали. Однако и в случае применения современных сложных фреймворков что-то может пойти не так, и мы, как пользователи, столкнемся со сложно решаемыми багами многопоточности.

К счастью, Java оснащена специальным механизмом для получения информации о текущем состоянии всех потоков в любой момент времени — это thread dump (своего рода моментальный снимок). В этой статье мы изучим, как получить thread dump для приложения реалистичных размеров и как этот dump проанализировать. Предполагается, что читатель владеет базовой информацией о многопоточном программировании и знает о проблемах синхронизации потоков и использовании совместных ресурсов. Тем не менее будет не лишним освежить в памяти некоторые основные термины и понятия.

Основная терминология

С первого взгляда Java thread dump-ы могут показаться «китайской грамотой», ключом к ее понимаю являются следующие понятия. В общем, давайте, повторим основные термины многопоточности, которые будем использовать для анализа дампов.

  • Thread или поток — дискретная единица многопоточности, управляемая Java Virtual Machine (JVM). Потоки JVM соответствуют потокам в операционной системе (OS) — native threads («естественные потоки»), которые и реализуют механизм выполнения кода.
    У каждого потока есть уникальный идентификатор и имя. Потоки могут быть «демонами» и «не демонами».Программа завершает свою работу, когда завершаются все потоки «не демоны» или вызывается метод Runtime.exit. Работающие «демоны» не влияют на завершение работы программы. Т.е. JVM ждем когда доработают все «не демоны» и завершает работу, на «не демонов» не обращает внимание.
    За более подробной информацией обращайтесь к документации класса Thread.
    Поток может находится в одном из следующих состояний:
    • Alive thread или «живой» — поток, который выполняет некоторую работу (нормальное состояние).
    • Blocked thread или «заблокированный» — поток, который попытался зайти в секцию синхронизации (synchronized), однако другой поток уже успел зайти в этот блок первым, и все следующие потоки, которые попытаются зайти в этот же блок оказываются заблокированными.
    • Waiting thread или «ожидающий» — поток, который вызвал метод wait (возможно, с указанием таймаута) и сейчас ждет, когда другой метод выполнит notify или nonifyAll на этом же объекте.
      Обратите внимание, поток не считается «ожидающим», если он вызвал wait с таймаутом и этот таймаут истек.
    • Sleeping thread или «спящий» — поток, который сейчас не выполняется, т.к. выполнил метод Thread.sleep (с указанием длительности «сна»).
  • Monitor — это механизм, используемый в JVM для обеспечения многопоточного доступа к одному объекту. Механизм запускается при помощи специального ключевого слова synchronized.Каждый объект в Java имеет монитор, при помощи которого поток может синхронизоваться, т.е. выставить блокировку, которая гарантирует, что ни один другой поток не получит доступ к этому объекту, пока блокировка не будет снята, т.е. поток — владелец блокировки не выйдет из блока synchronized.
    Более подробную информацию смотрите в Synchronization section (17.1) of the Java Langauge Specification (JLS).
  • Deadlock — это ситуация, в которой поток, скажем А, блокирует ресурс, ему нужен другой ресурс, который заблокирован другим потоком, скажем Б. Поток Б не отпускает этот ресурс, т.к. для завершения некой операции ему нужен ресурс, который заблокирован потоком А. Получается, что поток А ждет разблокировки ресурса потоком Б, который ждет разблокировку другого ресурса потоком А. И, таким образом, потоки ждут друг друга. В итоге, вся программа «висит» и ждет, когда потоки как-то разблокируются и продолжат работу. Во взаимной блокировке может быть много потоков. Эта проблема хорошо известна как «Проблема обедающих философов».
  • Livelock — это ситуация, когда поток A заставляет поток В выполнить некое действие, которое в свою очередь приводит в выполнению поток А первоначального действия, которое в очередной раз вызывает действие потока В. Получается циклическая зависимость. Это можно представить, как собаку, бегающую за своим хвостом. Аналогично Deadlock, в ситуации Livelock программа не совершает прогресс, т.е. не выполняет полезное действие, однако в этой ситуации потоки не блокируются.

Представленная терминология не является исчерпывающей для описания мира многопоточности, однако этого достаточно, чтобы начинать анализировать thread dump-ы.
Более детальную информацию можно найти в этих источниках: Section 17 of the JLS и Java Concurrency in Practice

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

Создание примера программы

Прежде, чем создать thread dump, нам надо разработать Java-приложение. Традиционный «hello, world!» для нашей цели слишком прост, а дамп среднего размера приложения может оказаться слишком сложным для демонстрации. Исходя из этого, мы создадим достаточно простое приложение, в котором создаются два потока. Причем потоки попадают в deadlock:

public class DeadlockProgram {     public static void main(String[] args) throws Exception {         Object resourceA = new Object();         Object resourceB = new Object();         Thread threadLockingResourceAFirst = new Thread(new DeadlockRunnable(resourceA, resourceB));         Thread threadLockingResourceBFirst = new Thread(new DeadlockRunnable(resourceB, resourceA));         threadLockingResourceAFirst.start();         Thread.sleep(500);         threadLockingResourceBFirst.start();     }     private static class DeadlockRunnable implements Runnable {         private final Object firstResource;         private final Object secondResource;         public DeadlockRunnable(Object firstResource, Object secondResource) {             this.firstResource = firstResource;             this.secondResource = secondResource;         }         @Override         public void run() {             try {                 synchronized(firstResource) {                     printLockedResource(firstResource);                     Thread.sleep(1000);                     synchronized(secondResource) {                         printLockedResource(secondResource);                     }                 }             } catch (InterruptedException e) {                 System.out.println("Exception occurred: " + e);             }         }         private static void printLockedResource(Object resource) {             System.out.println(Thread.currentThread().getName() + ": locked resource -> " + resource);         }     } } 

Эта программа создает два ресурса: resourceA и resourceB, и стартует два потока: threadLockingResourceAFirst и threadLockingResourceBFirst, которые блокируют ресурсы друг друга.Причиной возникновения deadlock-а является «перекрестная» блокировка ресурсов потоками.Причиной возникновения deadlock является попытка «взаимного» захвата ресурсов, т.е. поток threadLockingResourceAFirst захватывает ресурс resourceA, поток threadLockingResourceBFirst захватывает ресурс resourceB. После этого поток threadLockingResourceAFirst, не отпуская свой ресурс, пытается захватить resourceB, а поток threadLockingResourceBFirst, не отпуская свой ресурс, пытается захватить ресурс resourceA. В результате потоки блокируются. Задержка в 1с добавлена, чтобы гарантировать возникновение блокировки. Потоки ждут освобождение нужных ресурсов, но это никогда не случится.

Вывод программы будет таким (числа после java.lang.Object@ будут разные для каждого запуска):

Thread-0: locked resource -> java.lang.Object@149bc794Thread-1: locked resource -> java.lang.Object@17c10009

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

Генерация Thread Dump

На практике, Java-программа может аварийно завершиться и при этом создать thread dump. Однако в ряде случаев (например в случае deadlock-ов), программа не завершается и thread dump не создает, она просто зависает. Для создания дампа таких зависших программ, прежде всего надо выяснить идентификатор процесса программы, т.е. Process ID (PID). Для этого можно воспользоваться утилитой JVM Process Status (JPS), которая начиная с версии 7, входит в состав Java Development Kit (JDK). Чтобы найти PID процесса нашей зависшей программы, мы просто выполним jps в терминале (Windows или Linux):

$ jps11568 DeadlockProgram15584 Jps15636

Первая колонка — это идентификатор локальной виртуальной машины (Local VM ID, т.е. lvmid) для выполняемого Java-процесса. В контексте локальной JVM, lvmid указывает на PID Java-процесса. Надо отметить, что это значение, скорее всего, будет отличаться от значения выше. Вторая колонка — это имя приложения, которое может указывать на имя main-класса, jar-файла или быть равно «Unknown». Все зависит от того, как приложение было запущено.

В нашем случае имя приложения DeadlockProgram — это имя main-классы, который был запущен при старте программы. В примере выше PID программы 11568, этой информации достаточно для генерации thread dump’а. Для генерации дампа мы воспользуемся утилитой jstack, которая входит в состав JDK, начиная с версии 7. Чтобы получить дамп мы передадим в jstack в качестве параметра PID нашей программы и укажем флаг -l (создание длинного листинга). Вывод утилиты перенаправим в текстовый файл, т.е. thread_dump.txt:

jstack -l 11568 > thread_dump.txt

Полученный файл thread_dump.txt содержит thread dump нашей зависшей программы и содержит важную информацию для диагностики причин возникновения deadlock-а.
Если используется JDK до 7 версии, то для генерации дампа можно воспользоваться утилитой Linux — kill с флагом -3. Вызов kill -3 отправит программе сигнал SIGQUIT.
В нашем случае вызов будет такой:

kill -3 11568

Анализ простого Thread Dump

Открыв файл thread_dump.txt, мы увидим примерно следующее содержание:

  2018-06-19 16:44:44 Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.1+10 mixed mode): Threads class SMR info: _java_thread_list=0x00000250e5488a00, length=13, elements={ 0x00000250e4979000, 0x00000250e4982800, 0x00000250e52f2800, 0x00000250e4992800, 0x00000250e4995800, 0x00000250e49a5800, 0x00000250e49ae800, 0x00000250e5324000, 0x00000250e54cd800, 0x00000250e54cf000, 0x00000250e54d1800, 0x00000250e54d2000, 0x00000250e54d0800 } "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000250e4979000 nid=0x3c28 waiting on condition  [0x000000b82a9ff000]    java.lang.Thread.State: RUNNABLE     at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.1/Native Method)     at java.lang.ref.Reference.processPendingReferences(java.base@10.0.1/Reference.java:174)     at java.lang.ref.Reference.access$000(java.base@10.0.1/Reference.java:44)     at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.1/Reference.java:138)    Locked ownable synchronizers:     - None "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000250e4982800 nid=0x2a54 in Object.wait()  [0x000000b82aaff000]    java.lang.Thread.State: WAITING (on object monitor)     at java.lang.Object.wait(java.base@10.0.1/Native Method)     - waiting on <0x0000000089509410> (a java.lang.ref.ReferenceQueue$Lock)     at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:151)     - waiting to re-lock in wait() <0x0000000089509410> (a java.lang.ref.ReferenceQueue$Lock)     at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:172)     at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.1/Finalizer.java:216)    Locked ownable synchronizers:     - None "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000250e52f2800 nid=0x2184 runnable  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    Locked ownable synchronizers:     - None "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000250e4992800 nid=0x1624 waiting on condition  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    Locked ownable synchronizers:     - None "C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x00000250e4995800 nid=0x4198 waiting on condition  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    No compile task    Locked ownable synchronizers:     - None "C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x00000250e49a5800 nid=0x3b98 waiting on condition  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    No compile task    Locked ownable synchronizers:     - None "C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x00000250e49ae800 nid=0x1a84 waiting on condition  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    No compile task    Locked ownable synchronizers:     - None "Sweeper thread" #9 daemon prio=9 os_prio=2 tid=0x00000250e5324000 nid=0x5f0 runnable  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    Locked ownable synchronizers:     - None "Service Thread" #10 daemon prio=9 os_prio=0 tid=0x00000250e54cd800 nid=0x169c runnable  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    Locked ownable synchronizers:     - None "Common-Cleaner" #11 daemon prio=8 os_prio=1 tid=0x00000250e54cf000 nid=0x1610 in Object.wait()  [0x000000b82b2fe000]    java.lang.Thread.State: TIMED_WAITING (on object monitor)     at java.lang.Object.wait(java.base@10.0.1/Native Method)     - waiting on <0x000000008943e600> (a java.lang.ref.ReferenceQueue$Lock)     at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:151)     - waiting to re-lock in wait() <0x000000008943e600> (a java.lang.ref.ReferenceQueue$Lock)     at jdk.internal.ref.CleanerImpl.run(java.base@10.0.1/CleanerImpl.java:148)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)     at jdk.internal.misc.InnocuousThread.run(java.base@10.0.1/InnocuousThread.java:134)    Locked ownable synchronizers:     - None "Thread-0" #12 prio=5 os_prio=0 tid=0x00000250e54d1800 nid=0xdec waiting for monitor entry  [0x000000b82b4ff000]    java.lang.Thread.State: BLOCKED (on object monitor)     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465b0> (a java.lang.Object)     - locked <0x00000000894465a0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)    Locked ownable synchronizers:     - None "Thread-1" #13 prio=5 os_prio=0 tid=0x00000250e54d2000 nid=0x415c waiting for monitor entry  [0x000000b82b5ff000]    java.lang.Thread.State: BLOCKED (on object monitor)     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465a0> (a java.lang.Object)     - locked <0x00000000894465b0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)    Locked ownable synchronizers:     - None "DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x00000250e54d0800 nid=0x2b8c waiting on condition  [0x0000000000000000]    java.lang.Thread.State: RUNNABLE    Locked ownable synchronizers:     - None "VM Thread" os_prio=2 tid=0x00000250e496d800 nid=0x1920 runnable   "GC Thread#0" os_prio=2 tid=0x00000250c35b5800 nid=0x310c runnable   "GC Thread#1" os_prio=2 tid=0x00000250c35b8000 nid=0x12b4 runnable   "GC Thread#2" os_prio=2 tid=0x00000250c35ba800 nid=0x43f8 runnable   "GC Thread#3" os_prio=2 tid=0x00000250c35c0800 nid=0x20c0 runnable   "G1 Main Marker" os_prio=2 tid=0x00000250c3633000 nid=0x4068 runnable   "G1 Conc#0" os_prio=2 tid=0x00000250c3636000 nid=0x3e28 runnable   "G1 Refine#0" os_prio=2 tid=0x00000250c367e000 nid=0x3c0c runnable   "G1 Refine#1" os_prio=2 tid=0x00000250e47fb800 nid=0x3890 runnable   "G1 Refine#2" os_prio=2 tid=0x00000250e47fc000 nid=0x32a8 runnable   "G1 Refine#3" os_prio=2 tid=0x00000250e47fd800 nid=0x3d00 runnable   "G1 Young RemSet Sampling" os_prio=2 tid=0x00000250e4800800 nid=0xef4 runnable   "VM Periodic Task Thread" os_prio=2 tid=0x00000250e54d6800 nid=0x3468 waiting on condition   JNI global references: 2 Found one Java-level deadlock: ============================= "Thread-0":   waiting to lock monitor 0x00000250e4982480 (object 0x00000000894465b0, a java.lang.Object),   which is held by "Thread-1" "Thread-1":   waiting to lock monitor 0x00000250e4982380 (object 0x00000000894465a0, a java.lang.Object),   which is held by "Thread-0" Java stack information for the threads listed above: =================================================== "Thread-0":     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465b0> (a java.lang.Object)     - locked <0x00000000894465a0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844) "Thread-1":     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465a0> (a java.lang.Object)     - locked <0x00000000894465b0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844) Found 1 deadlock. 

Introductory Information

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

2018-06-19 16:44:44Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.1+10 mixed mode):

В этой секции нет информации о потоках. Тут задается общий контекст системы, в которой был собран дамп.

Общие сведенья о потоках

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

 Threads class SMR info: _java_thread_list=0x00000250e5488a00, length=13, elements={ 0x00000250e4979000, 0x00000250e4982800, 0x00000250e52f2800, 0x00000250e4992800, 0x00000250e4995800, 0x00000250e49a5800, 0x00000250e49ae800, 0x00000250e5324000, 0x00000250e54cd800, 0x00000250e54cf000, 0x00000250e54d1800, 0x00000250e54d2000, 0x00000250e54d0800 } 

В следующей секции приводится список Safe Memory Reclamation (SMR) information.В нем содержится информация о потоках за пределами JVM, т.е. это не потоки виртуальной машины и не потоки сборщика мусора. Если посмотреть на адреса этих потоков, то можно заметить, что они соответствуют значению tid — «естественному, железному» (native) адресу в операционной системе, а не Thread ID. Троеточия используются для сокрытия излишней информации:

 "Reference Handler" #2 ... tid=0x00000250e4979000 ... "Finalizer" #3 ... tid=0x00000250e4982800 ... "Signal Dispatcher" #4 ... tid=0x00000250e52f2800 ... "Attach Listener" #5 ... tid=0x00000250e4992800 ... "C2 CompilerThread0" #6 ... tid=0x00000250e4995800 ... "C2 CompilerThread1" #7 ... tid=0x00000250e49a5800 ... "C1 CompilerThread2" #8 ... tid=0x00000250e49ae800 ... "Sweeper thread" #9 ... tid=0x00000250e5324000 ... "Service Thread" #10 ... tid=0x00000250e54cd800 ... "Common-Cleaner" #11 ... tid=0x00000250e54cf000 ... "Thread-0" #12 ... tid=0x00000250e54d1800 ... "Thread-1" #13 ... tid=0x00000250e54d2000 ... "DestroyJavaVM" #14 ... tid=0x00000250e54d0800 ... 

Потоки

Сразу после блока SMR следует список потоков. Первый поток в нашем списке — Reference Handler:

 "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000250e4979000 nid=0x3c28 waiting on condition  [0x000000b82a9ff000]    java.lang.Thread.State: RUNNABLE     at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.1/Native Method)     at java.lang.ref.Reference.processPendingReferences(java.base@10.0.1/Reference.java:174)     at java.lang.ref.Reference.access$000(java.base@10.0.1/Reference.java:44)     at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.1/Reference.java:138)    Locked ownable synchronizers:     - None 

Краткое описание потока

В первой строке для каждого потока приводится общее описание. Описание содержит следующие пункты:

Раздел Пример Описание
Name «Reference Handler» Человеко-читаемое имя потока. Имя можно задать, вызвав метод setName объекта Thread. А получить через вызов getName
ID #2 Уникальный ID, присвоенный каждому объекту класса Thread. ID генерируется для потоков в системе. Первоначальное значение 1. Каждому вновь созданному потоку присваивается свой ID, предварительно увеличенный на 1. Это свойство потока «только для чтения», может быть получено с помощью функции getId объекта класса Thread.
Daemon status daemon Флаг является признаком того, что поток является демоном. Если это демон, то флаг будет выставлен. Например, поток Thread-0 не демон
Priority prio=10 Числовой приоритет Java-потока. Обратите внимание, что этот приоритет не обязательно соответствует приоритету связанного потока в операционной системе. Для установки приоритета можновоспользоваться методом setPriority объекта класса Thread, а для полученияметодом getPriority.
OS Thread Priority os_prio=2 Приоритет потока в операционной системе. Этот приоритет может отличаться от того, который присвоен связному Java-потоку.
Address tid=0x00000250e4979000 Адрес Java-потока. Этот адрес представляет собой указатель на Java Native Interface (JNI) нативный объект класса Thread (объект C++ Thread который связан с Java-потоком через JNI). Это значение получается путем приведения указателя на this(объекта C++, который связан с этим Java-потоком) к integer. См. строку 879 в hotspot/share/runtime/thread.cpp:

 st->print("tid=" INTPTR_FORMAT " ", p2i(this)); 

Хотя ключ для этого объекта (tid) может быть похож на ID-потока,на самом деле, это адрес связного объекта JNI C++ Thread, и это не то значение, котороевозвращает метод getId Java-объекта Thread.

OS Thread ID nid=0x3c28 Уникальный идентификатор потока операционной системы, к которому привязан Java-поток.
Это значение выводится следующим кодом:
строка 42 в hotspot/share/runtime/osThread.cpp:

 st->print("nid=0x%x ", thread_id()); 
Status waiting on condition Человеко-читаемый статус текущего потока.Эта строка выводит дополнительную информацию к простому статусу потока (см.ниже), которая может бытьиспользована для понимания, что поток собирался делать (т.е. пытался ли поток получить блокировкуили ждал выполнения условия разблокирования).
Last Known Java Stack Pointer [0x000000b82a9ff000] Последний известный указатель на стек (SP), ассоциированный и данным потоком. Это значение получается с использованием нативного кода С++, перемешанного с кодом Java с использованием JNI. Значение возвращает функция last_Java_sp(), строка 2886 в hotspot/share/runtime/thread.cpp:

   st->print_cr("[" INTPTR_FORMAT "]",      (intptr_t)last_Java_sp() & ~right_n_bits(12)); 

Для простых thread dump-ов эта информация практически бесполезна. Однако в сложных случаях SP можетбыть использован для отслеживания блокировок.

Состояние потока

Вторая строка — это текущее состояние потока. Возможные состояния потока приведены в enum:Thread.State: NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATEDБолее подробную информацию смотрите вдокументации.

Thread Stack Trace

Следующая секция содержит stack trace потока в момент снятия дампа. Этот stack trace очень похож на stack trace, который формируется не перехваченным исключением.И содержит имена классов и строк, которые выполнялись в момент формирования дампа.В случае потока Reference Handler мы не видим ничего интересного.Однако в трассировке потока Thread-02 есть кое-что интересное, отличное от стандартного трейса:

 "Thread-0" #12 prio=5 os_prio=0 tid=0x00000250e54d1800 nid=0xdec waiting for monitor entry  [0x000000b82b4ff000]    java.lang.Thread.State: BLOCKED (on object monitor)     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465b0> (a java.lang.Object)     - locked <0x00000000894465a0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)    Locked ownable synchronizers:     - None 

В трассировке мы видим, что добавилась информация о блокировке. Этот поток ожидает блокировкуна объекте с адресом 0x00000000894465b0 (тип объекта java.lang.Object). Более того поток сам удерживает блокировку с адресом 0x00000000894465a0 (тоже объект java.lang.Object). Эта информация нам пригодится далее для диагностики deadlock-а.

Захваченные примитивы синхронизации (Ownable Synchronizer)

В последней секции приводится список примитивов синхронизации (synchronizers), захваченных потоком. Это объекты, которые могут быть использованы для синхронизации потоков, например, защелки (locks).В соответствии с официальной документацией Java, Ownable Synchronizer — этонаследники AbstractOwnableSynchronizer (или его подкласса), которые могут быть эксклюзивно захвачены потоком для целей синхронизации.ReentrantLock и write-lock, но не read-lock класса ReentrantReadWriteLock — два хороших примера таких «ownable synchronizers», предлагаемых платформой.
Для получения более подробной информации по этому вопросу можно обратиться к этому посту.

Потоки JVM

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

 "VM Thread" os_prio=2 tid=0x00000250e496d800 nid=0x1920 runnable   "GC Thread#0" os_prio=2 tid=0x00000250c35b5800 nid=0x310c runnable   "GC Thread#1" os_prio=2 tid=0x00000250c35b8000 nid=0x12b4 runnable   "GC Thread#2" os_prio=2 tid=0x00000250c35ba800 nid=0x43f8 runnable   "GC Thread#3" os_prio=2 tid=0x00000250c35c0800 nid=0x20c0 runnable   "G1 Main Marker" os_prio=2 tid=0x00000250c3633000 nid=0x4068 runnable   "G1 Conc#0" os_prio=2 tid=0x00000250c3636000 nid=0x3e28 runnable   "G1 Refine#0" os_prio=2 tid=0x00000250c367e000 nid=0x3c0c runnable   "G1 Refine#1" os_prio=2 tid=0x00000250e47fb800 nid=0x3890 runnable   "G1 Refine#2" os_prio=2 tid=0x00000250e47fc000 nid=0x32a8 runnable   "G1 Refine#3" os_prio=2 tid=0x00000250e47fd800 nid=0x3d00 runnable   "G1 Young RemSet Sampling" os_prio=2 tid=0x00000250e4800800 nid=0xef4 runnable   "VM Periodic Task Thread" os_prio=2 tid=0x00000250e54d6800 nid=0x3468 waiting on condition 

Глобальные ссылки JNI

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

 JNI global references: 2 

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

Взаимно заблокированные (Deadlocked) потоки

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

 Found one Java-level deadlock: ============================= "Thread-0":   waiting to lock monitor 0x00000250e4982480 (object 0x00000000894465b0, a java.lang.Object),   which is held by "Thread-1" "Thread-1":   waiting to lock monitor 0x00000250e4982380 (object 0x00000000894465a0, a java.lang.Object),   which is held by "Thread-0" Java stack information for the threads listed above: =================================================== "Thread-0":     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465b0> (a java.lang.Object)     - locked <0x00000000894465a0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844) "Thread-1":     at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34)     - waiting to lock <0x00000000894465a0> (a java.lang.Object)     - locked <0x00000000894465b0> (a java.lang.Object)     at java.lang.Thread.run(java.base@10.0.1/Thread.java:844) Found 1 deadlock. 

В первом подразделе описывается сценарий взаимной блокировки (deadlock):Поток Thread-0 ожидает возможность захватить монитор(это обращение к блоку synchronized(secondResource) в нашем приложении), в то же времяэтот поток удерживает монитор, который пытается захватить поток Thread-1 (это обращение ктому же фрагменту кода: synchronized(secondResource) в нашем приложении). Эта циклическая блокировка по другому называется deadlock. На рисунке нижеэта ситуация представлена в графическом виде:

Во втором подразделе для обоих заблокированных потоков приведен stack trace.Этот stack trace позволяет нам проследить за работой каждого потока до появления блокировки.В нашем случае, если мы посмотрим на строку: at DeadlockProgram$DeadlockRunnable.run(DeadlockProgram.java:34), то увидим проблемный участок кода:

 printLockedResource(secondResource); 

Эта строка является первой строкой блока synchronized, который является причиной блокировки,и подсказывает нам, что синхронизация на secondResource и является причиной взаимной блокировки.

Чтобы исправить ситуацию, мы должны обеспечить в обоих потоках одинаковый порядок синхронизации на ресурсах resourceA и resourceB. Если мы сделаем это, то придем к следующему приложению:

public class DeadlockProgram {     public static void main(String[] args) throws Exception {         Object resourceA = new Object();         Object resourceB = new Object();         Thread threadLockingResourceAFirst = new Thread(new DeadlockRunnable(resourceA, resourceB));         Thread threadLockingResourceBFirst = new Thread(new DeadlockRunnable(resourceA, resourceB));         threadLockingResourceAFirst.start();         Thread.sleep(500);         threadLockingResourceBFirst.start();     }     private static class DeadlockRunnable implements Runnable {         private final Object firstResource;         private final Object secondResource;         public DeadlockRunnable(Object firstResource, Object secondResource) {             this.firstResource = firstResource;             this.secondResource = secondResource;         }         @Override         public void run() {             try {                 synchronized (firstResource) {                     printLockedResource(firstResource);                     Thread.sleep(1000);                     synchronized (secondResource) {                         printLockedResource(secondResource);                     }                 }             } catch (InterruptedException e) {                 System.out.println("Exception occurred: " + e);             }         }         private static void printLockedResource(Object resource) {             System.out.println(Thread.currentThread().getName() + ": locked resource -> " + resource);         }     } } 

Это приложение завершится без взаимной блокировки, и в качестве результата мы получим следующий вывод (обратите внимание на то, что адреса экземпляров класса Object изменились):

 Thread-0: locked resource -> java.lang.Object@1ad895d1 Thread-0: locked resource -> java.lang.Object@6e41d7dd Thread-1: locked resource -> java.lang.Object@1ad895d1 Thread-1: locked resource -> java.lang.Object@6e41d7dd 

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

Анализ более сложных Thread Dump-ов

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

Для анализа больших дампов предназначены специальные утилиты-анализаторы — Thread Dump Analyzers (TDAs). Эти утилиты парсят Java thread dump-ы и выводят информацию в человеко-читаемом виде, часто с применением графических средств. Более того, некоторые из них могут выполнить статический анализ и найти причину проблемы. Конечно, выбор конкретной утилиты зависит от целого ряда обстоятельств.Тем не менее приведем список наиболее популярных TDA:

Это далеко не полный список утилит подобного рода. Каждая утилита из этого списка выполняет достаточно качественный анализ и упрощает ручной труд анализа дампов.

Заключение

Thread dump-ы — это отличное средство анализа состояния Java-приложения, особенно в случаях неожиданного поведения многопоточных приложений. Однако без надлежащего багажа знаний, дампымогут внести дополнительную сложность и в без того сложную ситуацию.
В этой статье мы разработали приложение с deadlock, сформировали дамп зависшего приложения.Проанализировали дамп и нашли причину блокировки и исправили её. Это не всегда так просто,для анализа большинства реальных приложений очень полезно использовать специальные утилиты — анализаторы.

Тем не менее, каждый профессиональный Java-разработчик должен понимать основы анализа thread dump-ов. Должен ориентироваться в их структуре, знать какую информацию можно извлечь и как ее использоватьдля решения проблем многопоточности.
Хотя, thread dump — это не «серебряная пуля» в мире многопоточности, тем не менее это важное средстводиагностирования сложных, но довольно распространенных проблем многопоточных Java-приложений.

В программе курса Разработчик Java вопросы многопоточности занимают заменую часть. Мы детально рассматриваем как разрабатывать программы так, чтобы не приходилось по ночам разбираться с deadlock-в продакшене.


ссылка на оригинал статьи https://habr.com/company/otus/blog/427513/