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

«Живий» прогноз погоди, або Як використати генеративне мистецтво у вебі

$
0
0

У рубриці DOU Проекторвсі охочі можуть презентувати свій продукт (як стартап, так і ламповий pet-проект). Якщо вам є про що розповісти — запрошуємо взяти участь. Якщо ні — можливо, серія надихне на створення власного made in Ukraine продукту. Питання і заявки на участь надсилайте на editors@dou.ua.

Мене звуть Мар’яна, я випускниця програми Computer Science в УКУ. У цій статті я хотіла б розповісти про свій дипломний проект. Його суть у тому, щоб зробити веб-застосунок, який зображатиме реальні погодні умови на прикладі природного пейзажу, створеного за допомогою генеративного мистецтва. Ідея полягає в тому, щоб створити новий підхід до зображення погодних умов, що має спростити сприйняття інформації користувачем.

Що таке генеративне мистецтво

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

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

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

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

Дерево

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

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

Крона дерева неоднорідна, як куля, а складається з груп, наче кілька кульок. Це впливає на колір листочків, де одні більш затінені, а другі світліші. Для визначення цього кольору крона дерева ділиться на групи, де кожна група замальовується зліва направо в палітрі від найсвітліших до найтемніших кольорів і назад. Функція divide(start, finish, intervalsAmount, n)розділяє числовий проміжок між start та finish на задану кількість інтервалів intervalsAmount і визначає, в якому проміжку перебуває n.

const branchGroupDepth = 10;
const leavesGroupSize = 2 ** (branchGroupDepth-1);
let groupCounter = 0;

function generate(angle, depth, arr) {
 let leafColor = colors[divide(0, leavesGroupSize, colors.length, groupCounter)];
  arr.push({
   angle,
   branchArmLength: random(minBranchLenght, maxBranchLenght),
   color: leafColor
 });
 if (depth === branchGroupDepth) { groupCounter = 0; }
 if (depth === 0) { groupCounter++; }
 if (depth != 0) {
   if (depth > 1) {
     generate(angle - random(minAngle, maxAngle), depth - 1, arr);
     generate(angle + random(minAngle, maxAngle), depth - 1, arr);
   } else {
     generate(angle, depth - 1, arr);
   }
 }
}

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

windSideWayForce — прорахування напрямку гілки залежно від напрямку вітру.

bendabiityOfCurrentBranch — прорахування коефіцієнта сили нахилу гілки від вітру залежно від товщини гілки.

calcX(angle, r)/calcY(angle, r) — функції, що виконують r * cos(angle)/r * sin(angle)для того, щоб знайти координати точки закінчення гілки.

let branchCounter = 0;
const bendability = 2;
const leafBendability = 17;

function branch(x1, y1, arr, depth, windConfig) {
 if (depth != 0) {
   const xx = calcX(dir, depth * branchArmLength);
   const yy = calcY(dir, depth * branchArmLength);
   const windSideWayForce = windX * yy - windY * xx;
  const bendabiityOfCurrentBranch = (1 - (depth * 0.7) / (maxDepth * 0.7)) **        bendability;
   dir = angle + wind * bendabiityOfCurrentBranch * windSideWayForce;
   let x2 = x1 + calcX(dir, depth * branchArmLength);
   let y2 = y1 + calcY(dir, depth * branchArmLength);
   lines[depth].push([x1, y1, x2, y2]);
  
   if (depth > 1) {
     branch(x2, y2, arr, depth - 1, windConfig);
     branch(x2, y2, arr, depth - 1, windConfig);
   } else {
     branch(x2, y2, arr, depth - 1, windConfig);
   }
 } else {
   const leafAngle = angle + wind * windSideWayForce * leafBendability;
   leaves[color].push([x1, y1, leafAngle]);
 }
}

Малювання гілок відбувається простою lineTo()функцією в канвасі. Кожна гілочка — це проста лінія.

Кожен листочок намальований за допомогою двох кривих Безьє, а саме функцією bezierCurveTo() в канвасі. Кожна крива має три точки: початок (блакитна точка), кінець (блакитна точка) і контрольна точка (жовта). Саме контрольна точка формує вигин кривої.

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

Земля

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

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

function generate(number) {
 for (var i = 0; i < number; i++) {
   var y = random(fieldTopStart, h + fieldBottomDeviation);
   var x = random(0, w);
  var colorGroup = divide(fieldTopStart, h + fieldBottomDeviation  + 1,  fieldAreas, y);                                             
   var color = colors[colorGroup][random(0, colors[colorGroup].length)];
   var angle = random(-maxAngleDeviation, maxAngleDeviation);
   var speed = random(minSpeed, maxSpeed);
   dots.push([x, y, color, angle, speed]);
 }
 dots.sort();
}

Кожна травинка малюється за допомогою двох кривих Безьє, як це було у випадку з листочками на дереві. Щоб змусити травинку реагувати на вітер, координати контрольних (жовтих) точок і координата кінчика травинки залежать від значення вітру.

Небо й опади

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

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

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

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

Результат

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

Трішки гри з кольорами для різних пір року, застосування реальної погоди — і рік крізь це «живе вікно» на відео матиме такий вигляд:

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

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

Дякую за увагу!


Тестирование Big Data: вызов принят

$
0
0

Всем привет! Меня зовут Дмитрий Собко, и я занимаюсь тестированием больше 7 лет. Начинал свою карьеру с должности Junior Manual QA на проекте по разработке Android-приложения. Также был Automation Lead команды, которая разрабатывает приложение big data на стеке GCP (Google Cloud Platform). И именно эти опытом хотел бы поделиться.

В статье рассмотрены особенности тестирования именно приложений big data, которое немного отличается от тестирования REST API, UI и тем более Android/iOS. В то же время, зная основные моменты, можно построить достойный процесс контроля качества даже таких, на первый взгляд, нетестируемых решений.

Что такое big data

I keep saying that the sexy job in the next 10 years
will be statisticians, and I’m not kidding.

Hal Varian, chief economist at Google

Big data — это понятие, о котором, наверное, слышали уже все. Google Trends показывает, что интерес к big data возник примерно в 2012 году и не стихает до сих пор.

Чтобы определиться, что же такое big data, используем Google и находим следующие объяснения:

  • это просто много данных (> 10 Тбайт);
  • это настолько большие таблицы, что их невозможно открыть и проанализировать в Excel;
  • это неструктурированные данные из разных источников, разного объема, которые показывают, как ведут себя наши кастомеры и т. д.

Мне больше всего нравится определение из Википедии:

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

Существует и так называемая 3V-теорема, раскрывающая суть термина big data с другой стороны.

Volume — объем данных. Он действительно большой. Обычно это больше 50 Тбайт и до бесконечности.

Velocity — данные регулярно обновляются, поэтому требуется их постоянная обработка (от batch processing, когда данные загружаются пакетами, например раз в сутки, до real time streaming, когда данные в реальном времени попадают на графики / в отчеты и даже влияют на системы принятия решений на основе ML).

Variety — разнообразные данные могут иметь абсолютно разные форматы, быть неструктурированными или структурированными частично (от CSV/Avro-файлов с четкой структурой до логов в потоке).

Путь в Cloud

Со временем хранить такие объемы данных на собственных или арендованных серверах становится все сложнее и дороже. И когда в 2006-мпоявился AWS (Amazon Web Services), лишь немногие догадывались, к каким глобальным инфраструктурным изменениям это приведет.

В 2019 году достаточно взглянуть на этот график:

В 2020-мпримерно половина всех серверов будет в клауде, и с этим необходимо считаться.

Одной из компаний, которая наиболее подробно описывала путь от собственной инфраструктуры к Google Cloud, является Spotify. В ее блогеподробно рассказывается, почему были выбраны те или иные решения. Рекомендую почитать всем, кто интересуется этой темой.

И немного о Cloud-провайдерах:

Каждое третье приложение в клауде приходится на AWS. Azure от Microsoft и Google Cloud Platform соответственно лидеры оставшегося сегмента. Сопоставив эти два графика, можно сделать вывод, что изучение Cloud-технологий в целом и AWS в частности для тех, кто пока далек от этого, в том числе для QA-инженеров, становится скорее необходимостью, чем возможным желанием.

Как вообще выглядит проект big data

Обычный проект big data выглядит (очень упрощенно) следующим образом:

  1. На вход приложения попадают разные данные из разных источников. Обычно таких источников два:
    • streaming (потоковые) данные — любая message queue (Kafka, Google PubSub, Amazon SNS и пр.);
    • batch (пакетные) данные — обычно CSV, TXT, Avro, JSON-файлы.
  2. Данные извлекаются и складываются в Staging-таблицы. На этом этапе также возможна дедубликация, отдельная обработка записей, которые мы не смогли распарсить, и т. д. По сути, это настоящие source-данные as is.
  3. Дальше данные из Staging-таблиц трансформируются, группируются, фильтруются, дополняются метаданными и попадают в DWH (Data Warehouse), или в так называемый Target layer. Эти данные уже структурированы (например, имеют одинаковый формат полей с датой), и таблицы также имеют структурные связи между собой. Подробнее можно почитать здесь. В случае Google Cloud Platform это может быть BigQuery. У Amazon это Redshift. Но также это может быть Oracle, PostgreSQL и т. д.
  4. На основе данных в DWH формируются аналитические отчеты / принимаются решения ML-системами.В самом простом случае на выходе у нас:
    • набор данных, на основе которых уже строится визуализация (Tableau, Power BI, Zoomdata и пр.);
    • отчеты в виде CSV-файлов, которые отправляются, например, на SFTP-сервер или на S3-бакет.

Пример data pipeline на Google Cloud Platform

На входе данные поступают в виде batch-файлов или потоков (stream).

С помощью фреймворка Cloud dataflow данные извлекаются, трансформируются, обрабатываются и загружаются в DWH. В данном примере в основе DWH лежит BigQuery.

На основе полученных данных строится аналитика Cloud Machine Learning, Data Studio, возможная визуализация (Third-Party Tools) и т. д. Также в данном примере для кеширования данных используется Cloud Bigtable.

А как это протестировать

Как видно, здесь нет в чистом виде ни back-end- (API), ни front-end-частей. То есть у нас есть:

  • входные данные, которые мы практически не можем проконтролировать;
  • data processing (программная часть, которая отвечает за ETL — extract, transform, load);
  • таблицы/файлы/визуализация на выходе.

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

Подходы к тестированию

Тестирование на моках/стабах

В этом случае мы проверяем корректность трансформаций, выгрузки на mocked-данных. Например, используем CSV с несколькими строками на входе. Отдельно проводим негативное тестирование (XML-файлс незакрытыми тегами и пр.). Таким образом, мы сможем покрыть практически весь функционал data flow, но при этом у нас не будет уверенности, что все корректно и правильно работает на проде (а это самое важное!).

Тестирование на реальных данных

В таком случае мы пишем тесты для реальных данных, только догадываясь, сколько их будет и какими они будут. Допустим, мы знаем, что все кастомеры из CSV Customers на входе из страны Ukraine должны попасть в staging-таблицу customers_stage с кодом страны UA, а уже оттуда — в таблицу super_customers в Target-слой. Соответственно, мы и пишем такие тесты, опираясь на те данные, которые к нам пришли реально, и отталкиваясь от них.

Микс двух подходов

Unit/Integration-тесты пишем с использованием mocks/stubs. Также пару функциональных (end-to-end) тестов пишем для проверки реальной ситуации на энвайронменте с реальными данными. По моему мнению, этот подход является самым оптимальным, поскольку позволяет получить уверенность, что все хорошо идет на проде. И при этом при разработке новых фич он позволяет с помощью Unit/Integration-тестов быстро убедиться, что нет регрессии и вся логика построена правильно. Кроме того, на проде, конечно же, должна работать система мониторинга со сбором разнообразных метрик и отправкой нотификаций/алертов и пр.

Виды тестирования

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

Metadata Testing

Проверяем метаданные собственно данных (длину, тип) и таблиц (дату изменения, дату создания, количество строк, индексы и пр.).

Data Validation Testing

Проверяем, корректно ли данные прошли все трансформации. В качестве примера можно использовать преобразование Unix-тайм-стампа к дате.

Completeness (Reconciliation) Testing

Проверяем, все ли source-данные корректно обработаны. (Данные, которые успешно распарсились, попали в staging-слой, а если нет, то в error-таблицы или просто записались в логи.)

Accuracy Testing

Проверяем корректность логики трансформаций таблиц по пути от staging до analytics-слоя. (Обычно это делается путем создания с помощью SQL соответствующих проверочных view.)

А как это все автоматизировать

Для Unit/Integration-тестов можно легко использовать JUnit/TestNG (в случае Java-кода). Для Scala и GCP интересной альтернативой может быть библиотека Scioот того же Spotify.

Для функциональных тестов в нашем случае оптимальной была связка Kotlin + Spring + Cucumber BDD.

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

Почему Kotlin? Как мне кажется, это сейчас один из самых интересных JVM-языков для использования в том числе в автотестах. Есть много фишек, отличающих его от Java в лучшую сторону. Для тестировщиков, знающих Java/Groovy, переход будет очень легким. Ну и по состоянию на 2019 год можно уже смело утверждать, что этот язык перерос большинство детских болезней и продолжает развиваться.

Spring использовали для Dependency injection и еще нескольких приятных особенностей.

Позитивные итоги

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

Тестирование приложения big data непривычно, ставит перед QA много вызовов, которые нужно принимать и можно уверенно решать. И вместе с тем это интересно.

Спасибо за внимание!

DOU Hobby: кікбоксинг – ефектне поєднання боксу і східних бойових мистецтв

$
0
0

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

Віталій Шквира — Sr. Project Manager в компанії SoftServe. Він вже три роки займається кікбоксингом. В інтерв’ю для DOU Віталій розповів, як він захопився цим видом єдиноборства, як минають тренування та чим отримані у спорті навички можуть виявитися корисними в роботі й у житті.

Люблю «бій із тінню», бо тут ніхто не дає здачі :)

— Віталію, що таке кікбоксинг? З чого почалося твоє захоплення?

Кікбоксинг — це вид контактних єдиноборств, який виник у США в 1966 році. Один з його засновників — японець Ноґуті Осаму. В кікбоксингу поєднуються техніка і правила боксу, але додаються удари ногами. Зазвичай кількість раундів у поєдинку менша, ніж у боксі — від 3 до 5 в залежності від версії або турніру. Проте кікбоксинг за рахунок ударів ногами та більшої кількості нокаутів вважається більш видовищним.

Тренуватись я почав три роки тому. Основна причина захоплення досить банальна — придбавши автівку, почав менше рухатись і, відповідно, втрачати форму. До того я активно займався спортом у студентські роки: грав у футбол і хокей на траві, з останнього навіть здобув звання кандидата в майстри спорту.

Чому саме кікбоксинг? Мені він здається одним з найбільш інтенсивних і ефектних єдиноборств. Мабуть, не останню роль зіграли фільми, якими всі хлопці мого віку захоплювались у дитинстві: «Кривавий спорт», «Подвійний удар», «Уокер — техаський рейнджер». До речі, наші відомі на весь світ боксери Віталій і Володимир Клички починали саме з кікбоксингу.

— Чи пам’ятаєш, якими були перші тренування? Що найбільше вразило? Що здавалось найбільш складним?

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

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

Найскладнішою частиною тренування, як не дивно, була розминка, яка тривала приблизно 40 хвилин. Ти маєш бути добре розігрітий, щоб розтяжки і решта заняття минули ефективно і без травм. Спочатку вони здавались настільки важкими, що іноді темніло в очах або нудило. Та згодом я адаптувався і звик, набрав форму. Цікаво, що за шість перших місяців моя вага зменшилась з 90 до 82 кілограмів, що було для мене суперовим результатом.

Приблизно за два-три місяці тренер почав випускати мене в ринг на спаринги. Але спочатку то був не вільний бій, а відпрацювання конкретних завдань. Найважчими виявились розтяжки. Мабуть, давалась взнаки робота в офісі — 10-12годин сидіння за комп’ютером не кращим чином впливають на гнучкість.

— А як минають тренування зараз? І як часто тренуєшся?

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

Набивка — це відпрацювання ударів ногами по ногах і корпусу. Робота доволі різнопланова — з використанням захисту та без нього, на блок або ж по корпусу. Головна мета — навчитись тримати удар.

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

Функціонал — це, в основному, кросфіт, дуже популярна штука в багатьох видах спорту. Ми використовуємо від 8 до 10 снарядів: канати, штангу, молот, гирі, степ тощо. Проходимо три кола по 60, 40 і 20 секунд відповідно. На кожному снаряді потрібно відпрацювати максимальну кількість повторень за відведений час і перейти на інший снаряд.

Зазвичай я маю три тренування на тиждень по дві години.

Дуже популярний останнім часом кросфіт підвищує витривалість

— Чи потрібне якесь екіпірування? Що скільки коштує? Як новачкові вибрати правильні речі?

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

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

Новачкам радив би для початку не витрачати значні кошти на екіпірування. Початковий бюджет приблизно такий: рукавиці — від 500 грн, захист ніг — від 400 грн, бинти — від 200 грн. Наприклад, рукавиці топових брендів можуть коштувати 8 тис. грн і більше. Але доки не зрозумієш, що це «твоє», такі кошти витрачати не варто.

— Чи брав участь у якихось змаганнях, чемпіонатах? Якщо так, розкажи, як все минуло.

Свого часу тренер пропонував виступати в лізі «Б» Києва — це аматорські змагання із середнім рівнем підготовки. В лізі «А» виступають спортсмени достатньо пристойного рівня. Також запрошували виступити на турнірі білих комірців — це регулярні змагання з правил боксу серед новачків. Головна умова — щоб учасник ніколи до того не брав участі у змаганнях.

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

— За ким з професійних кікбоксерів або боксерів стежиш? За кого зазвичай вболіваєш? Кого вважаєш взірцем для наслідування?

Гадаю, не лише я, а й більшість хлопців стежить за виступами наших топових боксерів — Василя Ломаченка, Олександра Усика та Олександра Гвоздика. Втім, цей список можна продовжувати безкінечно, адже українська школа боксу — одна з найкращих у світі. Українські кікбоксери також входять до світової еліти — наприклад, Артур Кишенко, Роман Крикля. Якщо казати про змішані єдиноборства (ММА), то з нулем поразок Україну в найпрестижнішому промоушені світу UFC представляє Ярослав Амосов. Тож існує ціла низка українців, за якими варто стежити і наслідувати.

Щодо представників інших країн, особисто для мене кумирами є Buakaw Banchamek, Saenchai, Andy Souwer, Badr Hari, Gokhan Saki.

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

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

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

Вулична бійка — це взагалі абсолютно інше явище у порівнянні зі спарингом або поєдинком за правилами. Відсутність будь-якої амуніції (рукавиць, шолому, капи тощо) збільшує ймовірність травм до 100%, бій триває не більше 20-30 секунд,і для його завершення достатньо одного-двох влучних ударів. Треба користуватися будь-якою можливістю уникнути бійки, якщо тільки йдеться не про життя, здоров’я або честь близьких.

Що ж стосується мене особисто, такий випадок за останні роки трапився лише раз: доводилось захищати товариша. Можу сказати, що без підготовки наслідки були б для мене дуже сумними. Але, на щастя, все закінчилось добре.

— Наскільки взагалі в Україні розвинута спільнота з кікбоксингу? Які є клуби, турніри?

Мені складно проаналізувати якісь тренди розвитку кікбоксингу за багато років, але відколи я почав займатись, кількість осіб, що приходять на тренування, постійно збільшується. Україна має високий авторитет на міжнародній арені, в різних вікових і вагових категоріях, у різних версіях є чемпіони світу і Європи, багато професійних спортсменів. Одесит Артур Кишенко визнаний одним із найсильніших кікбоксерів світу незалежно від вагової категорії. Такий собі Ломаченко в світі кікбоксингу.

Клубів в Україні дуже багато. Лише в одному Києві, за моїми підрахунками, їх понад 15. Мабуть, не пораджу щодо вибору клубу, адже я весь час займаюся в одному місці — Fight Family. Його можу рекомендувати без вагань: крутий склад тренерів, класна локація, гарні умови, різноманіття напрямків. Відчувається, що керівництво серйозно займається його розвитком — тут відбуваються регулярні майстер-класи від відомих чемпіонів та інші заходи в клубі та поза його межами.

Якщо казати про турніри, то один із відомих, що проходить у Києві, — «Арка». Він проводиться у травні на день міста біля арки Дружби Народів.

Front middle-kick — гарний спосіб тримати суперника на дистанції

— Що порадиш початківцям? Якою має бути фізична підготовка для цього спорту? Як уберегтися від травм?

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

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

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

Легкі травми (гематоми або розтягнення) в будь-якому разі час від часу траплятимуться, адже це контактний вид спорту. Дуже важливо не допустити серйозних травм — переломів чи розривів тканин. За цим уважно стежить тренер. Проте одна з найефективніших превентивних мір — інтенсивна розминка. В процесі роботи також потрібно прислухатись до свого організму. Він завжди підкаже, коли треба знизити темп або зробити паузу.

— Які спортивні цілі ставиш собі на майбутнє?

Найближчим часом планую збільшувати кількість тренувань на тиждень до чотирьох — почну індивідуальні заняття, аби виправити деякі технічні помилки. Можливо, спробую виступити в якомусь аматорському турнірі. Це завдання максимум на поточний рік. Завдання мінімум — продовжити тренування і тримати форму. Всім спорту!

Это работает: как эффективно управлять процессами в продуктовой IT-компании

$
0
0

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

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

Что-то здесь не так

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

Восемь лет назад мы были заняты жизненно важными, с точки зрения разработки, задачами: строили свою инфраструктуру, создавали сайт megogo.net и писали приложения для Smart TV. И всем этим занимались около 20 человек, поэтому структура всего отдела разработки была максимально простой и плоской. Нам не нужны были проджекты и тимлиды, сложные процессы взаимодействия были бы избыточными.

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

Сначала у нас не было деления на команды, а задачи передавались «первому свободному разработчику». Мы ввели Road map, а директор разработки, по сути, выполнял функции главного project manager: самостоятельно распределял задачи и следил за ходом всей разработки. Тем не менее до идеала было далеко: у нас не существовало процесса передачи задач, техническую документацию готовили условные product owners в лучшем случае в Google Docs. Кроме того, что этот подход сильно замедлял всю разработку, project manager тратил огромное количество времени, чтобы из такого документа вычленить и организовать только важную для разработки информацию. В итоге из-за отсутствия согласованности выполнение даже «маленьких» задач в разы затягивалось по срокам.

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

А с чего начать?

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

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

Первый шаг — общение с командами. Мы собирали «боль» разработчиков во время работы над задачами с точки зрения процессов. Именно обратная связь от команд стала важнейшим рычагом для внедрения изменений.

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

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

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

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

Еще одним слабым звеном в процессе взаимодействия отдела разработки и бизнес-юнита было отсутствие порядка и стадий задач, то есть не существовало прозрачности. Без понятных всем участникам ступеней, по которым нужно пройти, чтобы выполнить задачи, слишком много времени тратилось на согласование, всевозможные встречи и проверки статусов. Поэтому мы ввели воронку требований, которая строго определяет стадии: первичный анализ, определение бизнес-метрик, определение MVP, параметры конфигурации, дизайн и Team Review. Вместе с определением приоритетов в Road map, основанном на оценке ожидаемых результатов по каждой задаче, это позволило сделать ход разработки прозрачным для всех участников процесса.

Тестирование продуктовых идей

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

Новые принципы работают

Естественно, мы не остановились на внедрении Agile. Например, мы усложнили структуру команд, но смогли упростить взаимодействие между различными отделами. Теперь в каждой из команд кроме разработчиков и QA-инженеров есть project manager, который занимается планированием и обсуждением требований к функциональностям, управляет релизами и их развертыванием, следит за выполнением задач. И обязательно есть team lead, отвечающий за распределение задач, code review, выбор технологий и архитектурные решения.

Структура отдела разработки

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

Отдел системных аналитиков получает бизнес-задачи, каждая из которых проходит через воронку требований. Воронка включает идеи, Road Map с приоритетами и улучшения. Мы получаем некий обозримый набор задач, поэтому важно определить приоритеты и оценить, что улучшит пользовательский опыт и что сможет улучшить сервис. Затем аналитики описывают задачи детальнее, идет подготовка дизайнов и полной спецификации для команд Smart TV, Mobile (Android, iOS, Android TV и Apple TV), Web (desktop и mobile). Далее продуктовые команды передают задачу сервисным командам, которые разрабатывают логику на Back-end. Именно в таком взаимодействии актуально выбранное нами разделение — большее число продуктовых команд создает условную конкуренцию за ресурсы сервисных команд. Эта проблема решается выбором разных методологий (Scrum и Kanban) и однозначным Road Map, явно указывающим на новые функции или особенности, которые необходимо реализовать каждой из команд.

Еще один важный этап в нашем flow — MVP-анализ для тестирования объемных функций и неочевидных идей. Часто он позволяет существенно сократить Time to market для новых продуктов, что, в свою очередь, дает нам существенную фору по сравнению с конкурентами. Когда появляется гипотеза, мы формируем минимальный scope задач, достаточных для релиза и тестирования.

Вот один из последних примеров. У нас была классическая на медиарынке задача — увеличить Retention пользователей на мобильных устройствах. Мы предположили, что популярный в мобильном сегменте формат Stories может нам помочь. В качестве гипотезы для тестирования мы решили использовать наиболее интересные фрагменты из телепередач, сериалов и фильмов. Создавались короткие ролики до 10 минут с возможностью перехода к полной версии. Суммарно над задачей работало около 20 специалистов в течение 3 месяцев. Мы разработали новый инструмент для iOS и Android, настроили метаданные и создали новые профили транскодинга.

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

Время важных вопросов

После всех оптимизаций и ретроспектив мы поставили себе вполне логичный вопрос: как понять, что процессы работают? Объективно это сделать сложно. У нас нет классических KPI. Мы выбрали для себя главный показатель — выдача готового проекта в кратчайшие сроки с допустимым минимумом багов и максимумом функциональности. На каждом члене команды лежит ответственность за процесс. Для большой задачи мы оцениваем, сколько на нее уйдет времени и ресурсов. Но если в итоге не попали в цель, разбираем на ретроспективах, что пошло не так. Во многих случаях Jira наглядно показывает, почему и на каком этапе зависла задача. Ко всему прочему для оценки серьезных проблем в команде есть Incident Manager.

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

Мы четко видим, куда нам двигаться, чтобы и далее улучшать свой flow. Во-первых, следует принимать решения на основании данных, A/B-тестов и строгих метрик — здесь нам не обойтись без алгоритмов Data Science. Во-вторых, построить масштабный Idea Backlog, в основе которого будет глубокая статистика, чтобы убрать субъективные метрики и руководствоваться цифрами.

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

Выплачиваем технический долг с пользой для бизнеса

$
0
0

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

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

Митинг

Менеджмент(радостно): мы согласовали все детали и запускаем новую фичу!

Девелопмент(недовольно): у нас устарела либа для отрисовки графиков, ужасная сортировка в старом модуле. И мы уже полгода не можем привести в порядок структуру проекта, после того как маркетингу срочно понадобилось переименовать тему.

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

На таких митингах кажется, что у всех разные цели. Бизнес уже наступал на грабли инвестиций в девелопмент без видимого результата. Тимлид знает, что накопленные костыли рано или поздно выстрелят ему в ногу. А QA на прошлой неделе 10 минут рассказывал на ретроспективе «what we should start doing», после того как ключевые юзеры зарепортили баги напрямую CEO.

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

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

— Я так не могу, мне стыдно, что в продукте такой код. У меня в субботу будет время, пойду наведу порядок, хотя бы где успею.

— Тима очень настаивала, мы выделили один спринт под рефакторинг, смогли согласовать с клиентом, но вчера после демо он остался недоволен и попросил сфокусироваться на business priorities.

Мы за все хорошее

То, что кажется разными проблемами, на самом деле является одной и той же. И бизнес, и QA хотят, чтобы как можно меньше значимых юзероввстретили баги. Бизнес заинтересован развивать продукт с наименьшими затратамии как можно быстрее. Девелопмент заинтересован иметь качественный codebase, который легко поддерживатьи куда можно наращивать фичибез опасения наткнуться на хрупкий, загадочный и немасштабируемый legacy. Что соответствует бизнес-целям тоже:

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

На примере одного беклога

Давайте посмотрим на практике (баги техническим долгом не считаются, но часто фигурируют где-то рядом, поэтому глянем и на них). В беклоге лежит:

IssueDescription
update PrettyCharts libraryЛиба, которую используют для отрисовки графиков, устарела на две версии.
an error when trying to setup custom themeУ всех юзеров, которые пытаются настроить кастомный UI, прилетает 500 с сервера, и настройки не сохраняются.
payment fails when upgrading with AmEx cardНе проходит апгрейд, если карточка — AmEx.
apply new sorting logic to the old moduleВ новых модулях сделали элегантную сортировку, а в старом оставили изначальное корявое решение, сделанное наспех.
duplicate folders theme and theme_goldenКогда-то тема в приложении была одна, потом добавились другие темы, и дефолтную переименовали в Golden. В коде часть файлов от нее осталась лежать в папке theme, часть перенеслась в theme_golden.

Все айтемы заслуживают внимания, баги серьезные. В соответствии с best practices либы надо вовремя обновлять, сортировка должна быть consistent везде, а с папками вообще фейспалм. Окей.

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

Добавляем к нашим айтемам контекст и описываем, почему это проблема.

IssueDescriptionContext
update PrettyCharts libraryЛиба, которую используют для отрисовки графиков, устарела на две версии.В последней версии либы лучше производительность и есть два новых типа графиков.
Если нужен будет экспорт ежедневных отчетов, старая либа с ним не справится.
an error when trying to setup custom themeУ всех юзеров, которые пытаются настроить кастомный UI, прилетает 500 с сервера, и настройки не сохраняются.Фича доступна только платным юзерам. По статистике, из платных юзеров 10% пробуют ставить кастомный UI.
payment fails when upgrading with AmEx cardНе проходит апгрейд, если карточка — AmEx.Применимо для платных юзеров, чьи подписки созданы до 2019 года. Таких 1%.
apply new sorting logic to the old moduleВ новых модулях сделали элегантную сортировку, а в старом модуле оставили изначальное корявое решение, сделанное наспех.В старом модуле сортировка работает очень медленно, если записей больше 5000.
Добавить сортировку по еще одному столбцу очень сложно.
duplicate folders theme and theme_goldenКогда-то тема в приложении была одна, потом добавились другие темы, и дефолтную переименовали в Golden. В коде часть файлов от нее осталась лежать в папке theme, часть перенеслась в theme_golden.В эти папки приходится заглядывать в среднем два раза в неделю каждому фронтэндщику, и уходит лишних 20 минут, потому что непонятно, что где искать.

Дальше узнаем, что по роадмапе нужно делать:

  • onboarding for corporate clients;
  • generate annual reports in the old module, use CoolAPI.

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

IssueDescriptionContextDecision
update PrettyCharts libraryЛиба, которую используют для отрисовки графиков, устарела на две версии.В последней версии либы лучше производительность и есть два новых типа графиков.
Если нужен будет экспорт ежедневных отчетов, старая либа с ним не справится.
С текущей производительностью проблем нет, новые типы графиков и ежедневные отчеты пока не нужны. Старая либа не будет ни для кого головной болью. (Конечно, если апдейт — дело получаса, он просто берется и делается, но, допустим, это не наш случай)
an error when trying to setup custom themeУ всех юзеров, которые пытаются настроить кастомный UI, прилетает 500 с сервера, и настройки не сохраняются.Фича доступна только платным юзерам. По статистике, из платных юзеров 10% пробуют ставить кастомный UI.10% платных юзеров — повод задуматься, но это не core feature, юзерам работать баг не мешает, продукт они не забросят, разочарованные в саппорт писать не будут, и QA тоже может быть спокоен. Однако в роадмапе есть onboarding for corporate clients, а все корпоративные клиенты будут использовать кастомные темы, поэтому нужно чинить.
payment fails when upgrading with AmEx cardНе проходит апгрейд, если карточка — AmEx.Применимо для платных юзеров, чьи подписки созданы до 2019 года. Таких 1%.Очень маленькая вероятность, что кто-то попадет на этот баг, и даже если это произойдет, саппорт может сделать апгрейд вручную. Можно оставлять как есть.
apply new sorting logic to the old moduleВ новых модулях сделали элегантную сортировку, а в старом модуле оставили изначальное корявое решение, сделанное наспех.В старом модуле сортировка работает очень медленно, если записей больше 5000.
Добавить сортировку по еще одному столбцу очень сложно.
Максимальное количество записей у текущих пользователей — 3000, добавления сортировки по еще одному полю в планах нет. Фича generate annual reports с сортировкой не связана. Значит, с проблемой тоже никто не столкнется.
duplicate folders theme and theme_goldenКогда-то тема в приложении была одна, потом добавились другие темы, и дефолтную переименовали в Golden. В коде часть файлов от нее осталась лежать в папке theme, часть перенеслась в theme_golden.В эти папки приходится заглядывать в среднем два раза в неделю каждому фронтэндщику, и уходит лишних 20 минут, потому что непонятно, что где искать.С проблемой сталкиваются регулярно, поэтому здесь можно явно выиграть в скорости и поддерживаемости (если наведение порядка не потребует месяца, конечно).

По закрытии этих айтемов бизнес получает свой профит, потому что починили критический баг для corporate clients onboarding и сэкономили 5 часов девелопмента ежемесячно.

Контекст для рефакторинга/багфикса

При обсуждении важности айтемов спрашивайте себя (и других):

  • каких компонентов/фичей касается;
  • какую конкретно проблему создает текущая реализация;
  • какое преимущество дает переделка (например, будет легче вносить изменения, или можно будет переиспользовать код, или вынести в отдельный компонент, и тогда добавление новой такой же сущности будет занимать минуту);
  • планируется ли в ближайшее время разработка в этих компонентах;
  • какого сегмента пользователей коснется (скажем, нужна оптимизация под мобильные устройства, а с мобильных сидят только пользователи из региона Х, и они не являются target audience);
  • для багов — как часто встречается, для какого use case, есть ли workaround.

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

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

«Продаем» рефакторинг

Зная контекст и бизнес-цели на ближайшее время, девелопменту становится просто «продать» рефакторинг. И, с другой стороны, зная, какой именно impact будет от рефакторинга, менеджмент может выставить правильный приоритет. Грубо говоря, мы что-то улучшаем не для его самоулучшения, а чтобы упростить дальнейшее развитие продукта.

Например, «продадим» апдейт фреймворка, который займет существенное время (если апдейт быстрый, то он обычно делается без вопросов):

А. We need to update the framework because the longer we use the old one, the harder it will be to update it in the future.Ценности для бизнеса нет.

В. We need to update the framework. The new version has the methods to receive data in X format and this will allow us to sent instant messages to the customers. Also the performance of pdf exports will improve by 20%. Если бизнесу важны мгновенные сообщения и скорость экспорта, то апдейт фреймворка у вас «купят».

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

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

TL;DR

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

  • Само наличие legacy или багов не страшно: важно понимать, что из этого является реальной проблемой на данный момент.
  • Понимая бизнес-приоритеты и направление развития продукта, можно «продать» нужный рефакторинг/багфикс, от чего выиграют обе стороны. Бизнес получит быструю разработку, девелопмент — легко поддерживаемый продукт, а ключевые кастомеры будут иметь smooth experience.
  • Возвращайтесь к тому, что именно улучшится предлагаемым изменением. Важно ли это?
  • Если вы владелец бизнеса, делитесь своими планами с командой как можно чаще. Это поможет принимать более подходящие архитектурные решения и избежать накопления технического долга, а при его наличии — выплатить самый критический.
  • Если вы менеджер, добывайте и делитесь информацией о планах и о контексте рефакторинга/багфикса, но сначала сами убедитесь, что поняли, о чем речь =)
  • Если вы девелопер, спрашивайте о том, что сейчас важно продукту, помогайте сделать технический долг видимым и облегчайте понимание правильного контекста.

Готовый к продакшену Vue SSR: 5 простых шагов

$
0
0

Я работаю в компании Namecheap на позиции Senior Software Engineer. В нашей компании мы используем Vue.js с серверным рендерингом для некоторых наших страниц. Настроить SSRможет быть не так легко, поэтому я попытался описать этот процесс простыми шагами. Также, читая официальную документацию, можно подумать, что было бы полезно увидеть как приложение должно выглядеть в итоге. Поэтому я создал репозиторий с примером.

В этой статье мы рассмотрим, как настроить готовый к продакшену SSR для Vue-приложения, используя:

  • Webpack 4;
  • Babel 7;
  • Node.js Express сервер;
  • webpack-dev-middleware и webpack-hot-middleware для удобной разработки;
  • Vuex для управления состоянием приложения;
  • плагин vue-meta для управления метаданными.

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

Шаг 1. Настройка webpack

Сейчас у вас, вероятно, уже есть какое-то Vue-приложение, а если нет, то можете использовать мой репозиторий в качестве отправной точки. Для начала взглянем на структуру наших папок и файлов:

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

  • есть два отдельных webpack-конфига для клиентского и серверного билдов: webpack.client.config.jsи webpack.server.config.js;
  • есть две соответствующие точки входа: client-entry.jsи server-entry.js.

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

С клиентским конфигом, вероятно, вы уже имели дело. Он предназначен для сборки нашего приложения в простые JS- и CSS-файлы.

Серверный конфиг более интересен. С его помощью мы создадим специальный json-файл, который будет использоваться на стороне сервера для рендеринга простого HTML-кода нашего Vue-приложения. С этой целью мы используем vue-server-renderer/server-plugin.

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

Как вы могли догадаться, все общие настройки клиентского и серверного конфигов мы вынесли в базовый конфиг.

Шаг 2. Создание точек входа

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

Обратите внимание: вместо создания экземпляра приложения мы экспортируем фабричную функцию createApp(). Если бы приложение работало только в браузере, то нам не пришлось бы беспокоиться о том, чтобы пользователи получали новый экземпляр Vue для каждого запроса. Но поскольку мы создаем приложение в Node.js процессе, наш код будет инициализирован один раз и останется в памяти того же контекста. Поэтому если мы будем использовать один экземпляр Vue для нескольких запросов, это может привести к ситуации, когда один пользователь получит состояние приложения другого. Чтобы избежать этого, мы должны создавать новый экземпляр приложения для каждого запроса. По этой же причине не рекомендуется использовать синглтоны с состоянием во Vue-приложении.

Каждое приложение, скорее всего, будет иметь какие-то метаданные, например title или description, которые должны отличаться на разных страницах. Вы можете реализовать это с помощью плагина vue-meta. Чтобы узнать, почему мы используем параметр ssrAppId, перейдите по этой ссылке.

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

Серверная точка входа в значительной степени описана в комментариях. Единственное, что я хотел бы добавить в отношении коллбэка router.onReady(): если мы используем хук serverPrefetchдля предварительного получения данных в каких-то компонентах, он ждет, пока не зарезолвится промис, возвращаемый из хука. Мы увидим пример его использования чуть позже.

Хорошо, теперь мы можем добавить в package.jsonскрипты для сборки нашего приложения:

Шаг 3. Запуск Express-сервера с Bundle Renderer

Чтобы преобразовать наше приложение в простой HTML на стороне сервера, мы будем использовать модуль vue-server-rendererи файл ./dist/vue-ssr-server-bundle.json, который мы сгенерировали, запустив скрипт build:server. Давайте пока не будем думать о режиме разработки, обсудим это на следующем шаге.

Сначала нам нужно создать рендерер, вызвав метод createBundleRenderer()и передав два аргумента: бандл, сгенерированный нами ранее, и следующие параметры:

  • runInNewContext
  • Помните проблему с общим состоянием между несколькими запросами, которую мы обсуждали на предыдущем шаге? Эта опция решает проблему, но создание нового контекста V8 и повторное построение бандла для каждого запроса является дорогостоящей операцией, поэтому рекомендуется установить этот флаг в значение false из-за возможных проблем с производительностью и остерегаться использования в приложении синглтонов с состоянием.
  • template

Специальный комментарий <!--vue-ssr-outlet-->будет заменен на HTML, сгенерированным рендерером. И кстати, используя опцию template, рендерер автоматически добавит скрипт с объявлением глобальной переменной __INITIAL_STATE__, которую мы используем в client-entry.jsпри создании своего приложения.

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

Шаг 4. Настройка dev-окружения

Что нам нужно для комфортной разработки Vue-приложения с SSR? Я бы сказал, следующее:

  • запускать только один Node.js сервер без использования дополнительного webpack-dev-server;
  • регенерировать vue-ssr-server-bundle.jsonфайл при каждом изменении исходного кода;
  • hot reloading.

Чтобы реализовать все эти вещи, можно воспользоваться функцией setupDevServer() в server.jsфайле (см. предыдущий шаг).

Эта функция принимает два аргумента:

  • app — наше Express-приложение;
  • onServerBundleReady() — callback, который вызывается каждый раз при изменении исходного кода и создании нового vue-ssr-server-bundle.json. Он принимает бандл в качестве аргумента.

В файле server.js мы передаем callback onServerBundleReady() в виде стрелочной функции, которая принимает новый бандл и заново создает рендерер.

Обратите внимание: мы рекваерим все зависимости внутри функции setupDevServer(), нам не нужно, чтобы они занимали память процесса в production-моде.

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

"dev": "cross-env NODE_ENV=development nodemon ./server.js",

Шаг 5. Использование serverPrefetch()

Скорее всего, вам потребуется получать какие-то данные с сервера во время инициализации приложения. Вы можете сделать это, просто вызвав API-эндпойнт после маунта рутового компонента, но в этом случае ваш пользователь должен будет наблюдать спиннер — не самый лучший UX. Вместо этого мы можем получить данные во время SSR, используя хук компонента serverPrefetch(), который был добавлен в версии 2.6.0 во Vue. Давайте добавим тестовый эндпойнт в наш сервер.

Мы вызовем этот эндпойнт в экшене getUsers. Теперь давайте рассмотрим пример использования хука serverPrefetch() в компоненте:

Как видите, мы используем serverPrefetch()вместе с хуком mounted(). Нам это нужно в тех случаях, когда пользователь переходит на эту страницу с другого роута на стороне клиента, поэтому массив usersбудет пуст и мы вызываем API.

Также обратите внимание, как определяются title- и description-метаданные для конкретной страницы в свойстве metaInfo, предоставляемом плагином vue-meta.

Ну вот и все. Я думаю, что основные моменты настройки SSR для Vue.js рассмотрены, и надеюсь, что эти шаги помогли вам лучше понять весь процесс.

Применение GameplayKit Randomization и State Machine в iOS-проектах

$
0
0

В предыдущей статьебыло описано, как применять игровой 2D-движок SpriteKit для быстрого создания простых анимаций в iOS. В новой статье я хочу поделиться, как использовать GameplayKit в неигровых приложениях.

GameplayKit — это набор инструментов, который Apple представляет для быстрого конструирования игровых процессов и алгоритмов. Рассмотрим инструменты, которые применимы даже в UIKit/Appkit-проектах.

Randomization

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

Раньше чаще всего многие применяли метод random() или arc4random(), построенный на ARC4-алгоритмеи генерирующий числа между 0 и 4294967295. После выхода Swift 4.2 появились новые методы для генерации рандома:

let randomInt = Int.random(in: 0..<10)
let randomDouble = Double.random(in: 5.71838...6.15249)
let randomBool = Bool.random()

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

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

Именно для этого и применяется Randomizationиз GameplayKit, позволяя сделать генерацию более детерминированной.

Random Source

Собственно, весь процесс рандома состоит из объекта-суперкласса GKRandomSource, который является источником рандомных чисел (Random Source), а также наследования от протокола GKRandom.

Сам протокол GKRandomпредставляет минимальный интерфейс для генерации случайных чисел и состоит всего из 4 методов:

let randomSource = GKRandomSource.sharedRandom()
// возвращает случайное значение Int32.min и Int32.max
// диапазон чисел от -2 147 483 648 до 2 147 483 647 
randomSource.nextInt()
// возвращает случайное значение Int между 0 и 9
randomSource.nextInt(upperBound: 10)
// возвращает случайное Float значение в диапазоне от 0.0 до 1.0
randomSource.nextUniform()
// возвращает случайное Bool
randomSource.nextBool()

GameplayKit предлагает один базовый и 3 альтернативных Random Source, которые являются детерминированными и могут быть сериализованы с использованием NSCoding, чтобы, к примеру, была возможность сохранить текущее состояние последовательности.

  • GKRandomSource — базовый генератор случайных чисел, от которого наследуются все последующие Random Source классы.
  • GKARC4RandomSource — генератор случайных чисел, реализующий уже привычный в iOS алгоритм ARC4 (arc4random). Особенность также состоит в том, что у этого источника есть метод dropValues(_:), который помогает отбросить определенное количество первых последовательностей, чтобы было сложнее предугадать вероятное следующее значение.
let arc4 = GKARC4RandomSource()
// Минимальное рекомендуемое количество отбрасываемых значений в последовательности
arc4.dropValues(768)
// Генерация случайного числа от 0 до 10
arc4.nextInt(upperBound: 11)
  • GKLinearCongruentialRandomSource — генератор чисел, реализующий алгоритм линейного конгруэнтного генератора, который быстрее, но менее случайный, чем стандартный ARC4. Основное преимущество его в том, что этот алгоритм есть в стандартных библиотеках некоторых языков программирования. Поэтому иногда его можно применять для создания одинаковой последовательности случайных чисел на разных платформах. К примеру, в Java этот алгоритм используется в java.util.Random. Также его стоит применять в том случае, если вы действительно делаете десятки или сотни генераций в секунду, иначе разница в производительности будет практически незаметна.
let linearCongruential = GKLinearCongruentialRandomSource()
// Генерация случайного числа от 0 до 10
linearCongruential.nextInt(upperBound: 11)
  • GKMersenneTwisterRandomSource — генератор случайных чисел, реализующий алгоритм вихрь Мерсенна, разработанный японскими учеными, который является более случайным, но и менее производительным, чем ARC4. Реализован в стандартных библиотеках: C++, Python, Ruby, PHP.
let mersenneTwister = GKMersenneTwisterRandomSource()
mersenneTwister.nextInt(upperBound: 11)

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

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

Random Distribution

Еще одним важным преимуществом рандомизации через GameplayKit является возможность формировать Random Source вместе с Random Distribution (методом случайного распределения).

Всего нам представлено 3 класса для Random Distribution:

  • GKRandomDistribution — распределение, где равномерная вероятность генерации любого числа в указанном диапазоне приблизительно равнозначна. Таким образом, исключается предвзятость в отношении любого возможного результата. Что приятно, этот класс имеет удобный интерфейс, чтобы сразу инициализировать аналог 6-гранногокубика, или 20-гранногокубика, или даже 100-гранногокубика.
// Это также можно сделать через GKRandomDistribution.d6()
let 🎲 = GKRandomDistribution(forDieWithSideCount: 6)
(1...10).forEach { _ in print(🎲.nextInt()) }
// 5 1 6 2 1 4 3 1 4 6
// Реализация 20 гранного кубика
let d20 = GKRandomDistribution.d20()
d20.nextInt() 
 
// Реализация 100 гранного кубика
let d100 = GKRandomDistribution(lowestValue: 1, highestValue: 100)
d100.nextInt()

Такой подход очень похож на использование Int.random(in:), но здесь основное отличие в том, что можно заранее инициализировать GKRandomDistribution, а затем заново использовать его сколько угодно, не задавая каждый раз необходимый диапазон чисел. В текущем примере при реализации распределения будет использоваться алгоритм ARC4 для генерации последовательности. Чтобы переопределить Random Source, достаточно просто инициализировать Random Distribution с указанием нужного источника.

let linearCongruential = GKLinearCongruentialRandomSource()
let 🎲 = GKRandomDistribution(randomSource: linearCongruential,
                                        lowestValue: 1,
                                        highestValue: 6)🎲.nextInt()
  • GKGaussianDistribution — генератор, который реализует распределение Гаусса (нормальное распределение) по множественным выборкам. Если коротко, то такой алгоритм рандома позволяет чаще получать средние значения в указанном вами интервале минимального и максимального значения. Например, в приложении нужно пользователю ежедневно выдавать бонус за использование, и такой алгоритм подойдет, чтобы всегда предоставлять усредненное значение. Или в играх, когда необходимо генерировать юниты, которые почти всегда будут с усредненными характеристиками.
let random = GKRandomSource()
// В этом примере, представим что у нас 10 гранный кубик, чтобы лучше было видно разброс чисел
let 🎲 = GKGaussianDistribution(randomSource: GKRandomSource(),
                                  lowestValue: 1,
                                  highestValue: 10)
(1...10).forEach { _ in print(🎲.nextInt()) }  // Бросаем кубик 10 раз
// 7 8 5 4 5 7 6 5 5 4

Также здесь мы можем влиять на рандомизацию, изменяя ожидаемое среднее значение meanи шаг интервала deviation. Возьмем пример, где среднее ожидаемое значение кубика будет 3, а шаг интервала 1:

let 🎲 = GKGaussianDistribution(randomSource: GKRandomSource(),
                                  mean: 3,
                                  deviation: 1)
(1...10).forEach { _ in print(🎲.nextInt()) }
// 2 3 3 3 2 2 3 4 2 2

В итоге получается, что около 68% сгенерированных чисел находятся в пределах одного отклонения от значения mean, 95% — в пределах 2 отклонений и почти 100% — в пределах 3 отклонений.

  • GKShuffledDistribution — генератор чисел, которые равномерно распределены по множеству выборок, но где короткие последовательности схожих значений исключены. Таким образом, если у нас будет указана генерация чисел от 1 до 5, то значение 5 выпадет во второй раз только после того, как все остальные числа от 1 до 4 точно так же выпадут по одному разу. Чаще всего подобную реализацию мы можем встретить в плей-листах современных аудиоплееров.
// Альтернативная инициализация диапазона чисел как у 6 гранного кубика
let 🎲 = GKShuffledDistribution.d6()
(1...7).forEach { _ in print(🎲.nextInt()) }  // Бросаем кубик 7 раз
// 4 5 3 1 2 6 4

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

Что интересно, метод shuffle()распределения элементов в массиве, который был добавлен в Swift только в версии 4.2, все это время был доступен в GameplayKit Randomization еще с iOS 9: arrayByShufflingObjects(in:). Работают они, естественно, на одном алгоритме Фишера — Йетса. Но основное отличие между ними только в том, что GameplayKit возвращает новый массив, в то время как реализация в Swift перемешивает оригинальный.

Контроль последовательности рандома

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

Это может понадобиться, когда необходимо сделать одинаковую последовательность рандома на разных платформах или когда тестировщикам требуется повторить определенную последовательность. Все показанные мною GKRandomSource-классы (кроме базового) используют свойство seed, которое доступно для изменения. Зная значение seed, вы можете узнать всю последовательность рандома.

let seed: UInt64 = 123
let randomSource1 = GKMersenneTwisterRandomSource(seed: seed)
let 🎲1 = GKRandomDistribution.d6()
(1...7).forEach { _ in print(🎲1.nextInt()) }
// 6 2 5 3 2 3 6
let randomSource2 = GKMersenneTwisterRandomSource(seed: seed)
let 🎲2 = GKRandomDistribution.d6()
(1...7).forEach { _ in print(🎲2.nextInt()) }
// 6 2 5 3 2 3 6

State Machine

В iOS уже давно была реализована State Machine, которую вполне можно применять, даже в обычных UIKit-проектах. И при этом не потребуется использовать Rx, NotificationCenter, OperationQueue или создавать огромные Enum’s.

State Machine в GameplayKit имеет простой интерфейс и состоит всего из 2 классов:

  • GKState — абстрактный класс, от которого мы наследуемся, чтобы создать отдельный объект конкретного состояния. Каждый такой класс определяет новое другое State-состояние, в которое он можете перейти.
  • GKStateMachine — сама State-машина, содержащая в себе объекты состояний, которые наследуются от GKState.

Создаем свою State Machine

В качестве примера использования UIKit в приложении я покажу, как это можно применить, например при загрузке какого-либо файла на сервер.

Всего будет 3 состояния: Uploading, Success, Failure.

Uploading State

final class UploadingDataState: GKState {
    private let viewController: UploadViewController
    init(_ viewController: UploadViewController) {
        self.viewController = viewController
    }
    override func isValidNextState(_ stateClass: AnyClass) -> Bool {
        // Здесь мы указываем, каким может быть следующий State
        return stateClass == SuccessfulState.self ||
            stateClass ==  FailureState.self
    }
 
// Метод который вызывается когда State Machine успешно перешла к этому состоянию
    override func didEnter(from previousState: GKState?) {
        // отображаем анимацию загрузки пока находимся в этом состоянии
        viewController.activityIndicator.startAnimating()
        
        // пример вызова какой-то реализации API запроса 
        API.fetchData { result in
            switch result {
            case .success:
                stateMachine?.enter(SuccessfulState.self)
            case .failure:
                stateMachine?.enter(FailureState.self)
            }
        }
    }
 
// Метод который вызывается когда State Machine переходит к другому состоянию
    override func willExit(to nextState: GKState) {
        // убираем анимацию загрузки когда покидаем состояние
        viewController.activityIndicator.stopAnimating()
    }
}

Successful and Failure State

final class SuccessfulState: GKState {
    private let viewController: UploadViewController
    init(_ viewController: UploadViewController) {
        self.viewController = viewController
    }
    override func isValidNextState(_ stateClass: AnyClass) -> Bool {
        return stateClass == UploadingDataState.self
    }
    override func didEnter(from previousState: GKState?) {
// Действия которые необходимо сделать когда успешно получили данные
    }
    
    override func willExit(to nextState: GKState) {
// Действия когда закончилось действие этого состояния
    }
}
 
final class FailureState: GKState {
 
    private let viewController: UploadViewController
    
    init(_ viewController: UploadViewController) {
        self.viewController = viewController
    }
 
    override func isValidNextState(_ stateClass: AnyClass) -> Bool {
        return stateClass == UploadingDataState.self
    }
    override func didEnter(from previousState: GKState?) {
// Действия которые необходимо сделать когда не удалось получить данные
    }
    
    override func willExit(to nextState: GKState) {
// Действия когда закончилось действие этого состояния
    }
}

В итоге получилась такая простая схема:

Чтобы запустить все эти состояния, достаточно инициализировать GKStateMachine и передать туда все созданные State-классы.

final class UploadViewController: UIViewController {
    @IBOutlet private(set) var activityIndicator: UIActivityIndicatorView!
    override func viewDidLoad() {
        super.viewDidLoad()
        let uploadingDataState = UploadingDataState(self)
        let successfulState = SuccessfulState(self)
        let failureState = FailureState(self)
        let stateMachine = GKStateMachine(states:
            [uploadingDataState, successfulState, failureState])
        // Сразу запускаем Uploading State
        stateMachine.enter(UploadingDataState.self)
    }
}

После запуска в UploadingDataState будет вызван метод didEnter(from:), активирован activityIndicator и отправлен запрос на сервер. В зависимости от ответа с сервера будет вызван переход к следующему состоянию, где мы уже сможем реализовать какую-либо другую логику. К примеру, можно будет легко написать реализацию, чтобы из состояния Failure мы вернулись в Uploading и повторили операцию. Также можно создать еще больше состояний, которые могли бы делать другие операции перед успешной загрузкой или после, например закешировать ее в файловой системе или сделать предварительно компрессию, прежде чем отправить на сервер. Таким образом, это может быть альтернативным вариантом, чтобы создать хорошую последовательность действий, которые будут существовать как отдельные классы, и тем самым избежать Callback Hell’a.

Посмотреть пример, предлагаемый Apple по применению GKStateMachine в виде игры, можно в архиве: Dispenser.

Заключение

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

Если же вам интересно, как можно задействовать большую часть инструментов GameplayKit, то рекомендую посмотреть WWDC 2015 session 609, Deeper into GameplayKit with DemoBots.

Исходный код проекта, показанного на WWDC, вы может взять в Documentation Archiveили у меня в репозитории, где код полностью сконвертирован до Swift 5.

.NET дайджест #30: что нового в .NET Core 3.0, Async demystified

$
0
0

В выпуске: Microsoft REST API Guidelines, How to run a Public Docker Registry in Kubernetes, How Microsoft Uses Stack Overflow for Teams.

.NET

Running async tasks on app startup in ASP.NET Core 3.0
Там вообще довольно хорошая серия статей о том, что нового в .NET Core 3.0

You don’t need to be a rocket-scientist to contribute to .NET Core!

Performance Profiling of .NET Core 3 applications on Linux with dotnet-trace and PerfView

Async demystified
Часто встречаюсь на собеседованиях с тем, что люди все еще не понимают, как работает async/await.

Announcing .NET Core 3.0

Microsoft REST API Guidelines

Разное

Kubernetes Academy

How to run a Public Docker Registry in Kubernetes
В итоге для локальной разработки я просто захостил registry:2 на одном из нод.

Java is one of the most energy-efficient languages, Python among least energy efficient

Strange Loop
Довольно интересные записи выступлений на конференции.

Cascadia Code
MS разработали новый шрифт с лигатурами для Window Terminal и вообще для редакторов. Довольно неплохой.

Slack dark mode comes to desktop
Я два года ждал.

CNCF Cloud Native Interactive Landscape
Довольно любопытный ресурс, стоит заглянуть.

Build your own X
Репозиторий с примерами, как построить разного плана приложения, например свой поисковик.

How Microsoft Uses Stack Overflow for Teams
Любопытно. И я думаю, это может отлично работать в компаниях. Стоит попробовать, наверное. А то в слаке знания теряются, а вики скучны.

DevOps Guide from basic to advanced with Interview Questions and Notes

Researchers hack Siri, Alexa, and Google Home by shining lasers at them


Еще я ездил на ProgNET London и спонтанно выступил там c коротким докладом. Там оказался свободный слот, а у меня была идея, о чем рассказать: Lightning Talk: Disposable xUnit Tests with AutoFixture. Нужно залогиниться через Twitter или GitHub, чтобы посмотреть. Вроде, неплохо получилось. Идею и сам подход я потом немного детальнее раскрыл на .NET Fest, но видео будет доступно только в январе, в следующем дайджесте добавлю. Напишите в комментариях, как вам идея. Мне интересно ваше мнение.


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


C++ дайджест #21: дебаг у Visual Studio та Visual Studio Code

$
0
0

Привіт, мої любі сішники! Сьогодні випуск буде присвячено відладці у Visual Studio та Visual Studio Code. Тож почнімо? :)

Debug у Visual Studio та Visual Studio Code

Visual Studio:

Visual Studio Code:

Події

Embedded Fest — 30 листопада, Київ — найбільша в Східній Європі конференціядля Embedded & Linux розробників. Для читачів дайджесту знижка 10% за промокодом: D-DIGEST-10.

LoGeek Night — 12 листопада, Київ.

Software Architecture Meet-Up — 21 листопада, Харків.

GlobalLogic Kharkiv Embedded TechTalk #5 — 22 листопада, Харків.

Games Gathering 2019 Kiev — 7-8 грудня,Київ — найбільша в Східній Європі конференція, присвячена розробці ігор.

Modern C++

We don’t need no stinking expression templates

C++20 span tutorial

A Universal Async Abstraction for C++

C++20’s Conditionally Explicit Constructors

Eliminating the Static Overhead of Ranges

Корисні посилання

Обзор С++ фреймворков для внедрения зависимостей: kangaru и [Boost].DI

Why PE need Original First Thunk(OFT)?

Access tuple-like container by type to return an index

How to Merge Consecutive Elements in a C++ Collection

Phantom lambda type, partially applied class template, and deduction guides to support dependency injection

C/C++ Include Guidelines

Don’t Use unique_ptr for PIMPL

Efficient QString concatenation with C++17 fold expressions

Інструменти

AddressSanitizer (ASan) for Windows with MSVC

Introducing C++ Build Insights

Usability Improvements for CMake in Visual Studio 2019 version 16.4: Launch Target Selection and Overview Pages

Support for C++20’s Concepts in CLion

Deterministic builds with clang and lld

Оновлення

Цього місяця маємо такі оновлення:

Хвилиночка флуду


← Попередній випуск: C++ дайджест #20

Канада для IT-шника

$
0
0

Я хочу уместить всё в одну статью, так что будет лонгрид:

  • Почему я уехал? И почему Канада?
  • Бытовые зарисовки, Монреаль преимущественно.
  • Как уехать в Канаду айтишнику и не только?
  • Вопросы.

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

Почему я уехал?

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

Волонтерство

Помните, раньше говорили, что Майдан финансируется из Америки? В какой-то мере я и был этой самой «рукой Госдепа» — я брал (зарабатывал) деньги в США и отдавал волонтерам.

Отдал... много. Без цифр.

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

Для тех, кто «всё или ничего» — я отдал мало, ведь я мог не ездить в отпуска, да и вообще без машины жить можно.

Для тех, кто отдал жизнь или здоровье — я отдал ничего.

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

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

Почему нет?

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

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

  • Экономика. Та вы шо, айтишник в Украине живет весьма хорошо. А если случится дефолт, то пока ФЛП и Payoneer не перекроют, то каждый синьор сможет себе позволить личных телохранителей. Если честно, то чем хуже экономика, тем больше денег остаётся айтишникам на игрушки. Сейчас на мою зарплату живет шесть человек. Были моменты, когда жило 11. Да, я тут передергиваю и многое упускаю.
  • Менты, суды, бандиты. Я с ними почти не сталкивался, и есть шанс, что и не столкнусь. Меня даже грабили последний раз аж в 2007.
  • Образование детей. Есть онлайн, и они тоже могут уехать, если захотят, позже.
  • Об армии для старшего я стараюсь не думать. Сидеть в тылу — глупо, на фронт мне страшно его отпускать. К моему внутреннему удовольствию, он меня не будет спрашивать, то есть ответственность будет не на мне. На мне будет поддержка его выбора.
  • Медицина. Можно страховаться за рубежом, это поможет от половины случаев. Конечно, с каждым клещом и переломом в Израиль не налетаешься. С другой стороны — есть общий прогресс медицины. Лично я ожидаю в ближайшие десять лет доступной ранней диагностики массовых болезней сердца и еще пачки болезней, которые на ранних этапах лечатся просто. Желающие могут посмотреть лекцииРослинга.
  • Погромы. Мой папа считал, что когда евреи оказываются у власти, это всегда заканчивается юдофобией и погромами. Как мне кажется, по нынешним временам будет достаточно долгая накачка, главное — не сидеть на месте, как это сделали мои родственники перед наступлением фашистов. Тогда из всей большой семьи осталось два человека — блокадный Ленинград и Курская дуга дали больше шансов выжить, чем «пересидеть на месте».
  • Широкомасштабное наступление РФ, с авиацией, тяжелыми ракетами и «химзавод в Харькове взорван Правым Сектором». Кмк, момент упущен, да и смысла теперь особого нет. Впрочем, для меня здесь будут триггером крупные теракты в РФ с визиткой Яроша. Иначе без большой накачки населения я не вижу, как это всё начать.
  • Тотальная зрада. Коломойский умный, и чтобы не стать рабом Путина — ему нужно будет балансировать между Западом и РФ. То есть да, результат несимпатичный, но и не хуже Януковича и Беларуси, причем гайки будут закручиваться постепенно.

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

Почему да?

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

  • Техногенные катастрофы. От атомной энергетики я их больше не ожидаю — там, я думаю, Европа тщательно следит, так как и ее накроет. А вот какой-нибудь аммиачный завод, или полимеры, или дамбы — это запросто. Это всё требует мозгов в обслуживании, а сейчас все с хоть какими-то мозгами идут в IT. Мало кто хочет идти на опасное место на 5-7тысяч гривен. А вообще, больше всего я опасаюсь отключения обогрева зимой — это сложная централизованная система, за которой нужно квалифицированно ухаживать. Сюда же — эпидемии.
  • Вся семья зависит от меня. Если я потеряю возможность зарабатывать деньги, то моей семье будет охренительно плохо. Выбор профессий — исключительно айтишный, а выучиться даже на джуна требует времени. И если для старшего сына я вполне вижу такое будущее, то для младших дочек... мне кажется, им будет неинтересно. Вообще фигово, когда весь выбор — только в IT. За пределами — это уже редкие исключения, как доход Роналду по сравнению с доходами большинства футболистов из районных команд.
  • Демографический кризис. Через 20 лет на одного работника будет приходиться очень много пенсионеров. И если работать некому, то неважно сколько будет денег в заначке и в какой валюте. «Бесплатные роботы для всех даром», «вечная молодость для всех даром», «инопланетяне» — это самые реалистичные сценарии. Есть еще «мигранты из более бедных стран Африки и Азии», но для этого им должно хотеться к нам приехать. Тут я надеялся на реформы и делал что мог. А, да, есть еще более оптимистичный персональный вариант — «умереть внезапно, до прихода дряхлости».
  • Когда я шесть лет назад смотрел на популярность партий и политиков, я мог списывать всё на «соцопросы купленные». Сейчас — уже никак не могу. Опросы таки показывают реальные настроения, и выборы это подтвердили. И эти настроения показывают современные ценности — патернализм и инфантилизм. Детская позиция — «я веду себя условно хорошо, а за это меня кормят и не сильно наказывают. Какое-то жилье, еду и медицину мне должны». Проблема не в том, что живем плохо — проблема в том, что хотим жить именно так.
  • Толчком к моему решению были опросыв декабре 2017. Среди кандидатов в президенты не было ни одного, кто мне сильно бы нравился. Максимум — были те, которые вызывали наименьшее отвращение. И для меня проблема была не в том, что мы выбирали себе феодала, а в том, что большинство именно феодала и хотело. Почти нет спроса на нефеодала.

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

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

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

Note 3:я бы предпочел построить «Канаду» в Украине, но не смог. Кто сможет — пусть продолжит. У меня уже нет времени на эксперименты.

Выбор страны

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

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

Юго-Восточная Азия — обалденный вариант для здоровых бездетных синьоров. За год-другой можно хорошо денег накопить.

Австралия и Новая Зеландия — можно, хотя и далековато. Проблема в том, что далеко от мировых денег.

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

Израиль — был под вопросом, но культура всё-таки не совсем моя, да и для евреев я очень сомнительный еврей.

Почему Канада?

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

Супругам можно работать, а детям — бесплатно учиться.

Все крупные партии выступают за увеличение иммиграции.

Для справки — трэкер сроков.

Политика

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

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

Здесь почти нет зрады, см. ниже.

Язык

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

Погода

Торонто по погоде — примерно как Харьков. В Торонто ветер сильнее. Желающие могут поизучать мои таблицы as is.

Монреаль на широте Симферополя. На практике, как говорят, в Монреале зимы снежнее и холоднее, чем в Киеве, март и частично апрель мерзкие — все стараются двинуть в тёплые страны. Летом жара бывает только пару недель.

В Канаде водятся колибри. Пять видов. Северная страна.

7:00-10:00 —весна
10:00-15:00 —лето
15:00-19:00 —осень
19:00-7:00 —зима
© прогноз погоды на завтра. Одевайтесь соответствующе!
© типичный канадский юмор

Погода меняется стремительно. На 20 градусов за день — запросто. Понятно, почему канадцы часто одеты не по погоде — просто нет смысла переодеваться, проще подождать. Человек в зимних ботинках и шортах — норм. Человек в пуховике и шлёпках на босу ногу — норм. Все весьма закаленные. Видел афроканадца, неспешно прогуливающегося в шортах и футболке под лёгким снежком, с широкими жестами общающегося по телефону. Видел детей, которые при +15 обливались холодной водой в фонтанах-стрелялках на детской площадке.

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

Медицина

После того как я неудачно переболел грипп-пневмония-плеврит, я уже не могу закрывать на это глаза. Рано или поздно, все с медициной столкнутся, даже ЗОЖники. Когда-то давно я проводил сравнение медицинских систем разных стран. Израиль, Германия, США, Канада, Швеция, Польша, Австралия...

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

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

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

Про качество жизни можно посмотреть тут.

Кстати, я привыкаю к тому, что мой размер с моими 182 см роста — это M. И кошки по 7 кг — это норма. Здоровая еда и медицина решают.

Недостатки

Я опрашивал множество людей на улицах, таксистов и т. п. о недостатках страны. Все хвалили медицину, образование, политику. Ругали погоду: «У нас зимой −30ºС бывает!» (ха, удивили). Ругали ремонты на дорогах.

Однажды я спросил компанию подвыпивших бизнесменов, что им не нравится в Канаде. «Как и у Украины, у нас долбанутый сосед». А если серьезно, то дух соревнования тут слабее, чем в США, а социализма намного больше. Так что молодым-амбициозным-бизнес-ориентированным тут будет не очень. Ну-у-у, разве что в GTA (Торонто+).

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

Бытовые зарисовки

Этот раздел больше о моих впечатлениях и наблюдениях, чем о чем-то практичном. Собран из слегка подрихтованных постов в моем FB.

Первое впечатление: год назад, с дополнениями

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

По обзорам я был уверен, что нам меньше всего понравится Монреаль, а больше всего — Торонто. Как я ошибался.

Я советую выбирать город по принципу «а есть ли здесь кто-то, к кому я могу напроситься попить чаю и потрындеть?» Потрясающе облегчает адаптацию. Даже люди, с которыми знаком только по фейсбуку — оказывают огромную поддержку. Кстати, ко мне можно напрашиваться :)

Оттава / Гатино

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

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

Природа/погода как в Харькове, Пятихатки.

Заборы от животных, а не от людей. То есть ограблений и педофилов не боятся, в отличие от медведей.

17 сентября, Оттава, +30 °С, снег настоящий и без фотошопа, но это фейк

Монреаль

Только столкнувшись с французским, понимаешь, как хорошо знаешь английский.

Город очень разный. Шаг в сторону — и небоскребы сменяются «трущобами». Мало рекламы.

Нет бродячих кошек и собак. Вообще. Зато очень много белок.

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

Я снял Airbnb, как выяснилось, в дешевом столетнем здании в самом конце Gay Village. Чисто, но бедно. Представьте советскую общагу, ужмите коридоры вдвое, помойте и покрасьте. Из квартиры (20 м2) при этом есть пожарный выход, закрытый на дохлую щеколду. И на этом выходе есть работающие лампочки.

Upd:потрясающая архитектура. Небоскребы вперемешку с историческими зданиями. Фасад и холл — от здания 18 века, а выше — небоскреб.

Upd 2:очень приятный work/life баланс. Это важно для такого трудоголика, как я.

Эдмонтон

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

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

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

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

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

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

Вахтер прибежала помочь разобраться с системой управления лифтами. Там же один пассажир автобуса бросился догонять второго, так как тот забыл мобильник на сидении. Upd: перечитываю сейчас, в голове удивление: «А что, может быть иначе? Это же норма!»

Эдмонтон строился по схеме, привычной в Северной Америке: очень удобная прямоугольная сетка стрит/авеню, исторический центр в центре и более современные малоэтажные районы по окраинам.

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

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

А потом как-то вот «внезапно» стало понятно, что если обновление трущоб в небоскребы идет волной, то на пути волны возникают краевые эффекты.

То есть в бизнес-центрах днём кипит жизнь, а ночью они вымирают. А вечером засидевшиеся на работе трудоголики выносят свои толстые кошельки в кольцо трущоб, где их ждут местные Робин Гуды. Бизнес такие вопросы решать не умеет. Точнее, мог бы решить бронированными автобусами с автоматчиками сопровождения, но это всё же Канада, а не Голливуд. Они же налоги платят и власть избирают!

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

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

Торонто

Кого ни спросишь, как тут живется, ответ один: «Хорошо, но дорого».

Пресное озеро размером с маленькое море. Вода чистая. Говорят, бывают шторма.

В Торонто айтишнику будет бедно. Кмк, GTA превращается в вариант Долины: много работы, большие зарплаты, чудовищные цены на жилье и т. д.

В Торонто культура ПДД похуже, чем в Оттаве/Монреале/Эдмонтоне: видел человека, который входил в поворот на высокой скорости и не пропустил пешехода, видел перебегающих пешеходов, видел бредущее по осевой тело. Слышал громкий мотоцикл и один раз бибиканье.

Вода из крана явно хуже, чем в Оттаве-Монреале-Эдмонтоне. Но лучше, чем в Харькове.

Много белок. В Эдмонтоне было непривычно без них.

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

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

Перелет одиночный

Я летел в начале июня-2019 без семьи, в Монреаль, рабочая виза. Из всех городов Монреаль понравился больше всего, Торонто — меньше всего.

Протестировал сдачу авиабагажа в картонных коробках «Новой почты» плюс пленка. Всё норм.

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

Меня завернули таможенники в Борисполе. Нельзя вывозить вот так монеты старше 1961, только по разрешению. Поэтому — марш-бросок на «Новую почту», благо, время я заложил с запасом.

Бюрократия в аэропорту заняла полчаса-час в сумме на обоих дополнительных пунктах.

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

От дома до дома — 33 часа.

Сразу же получил Главный Канадский Документ — Карту Греха. Так и называется — SIN form. Тоже полчаса на всё.

Сборная солянка

Таксисты любят правительство.

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

Секрет убранной канадский квартиры — встроенные шкафы.

Везде, где есть многоэтажки, Wi-Fi-диапазон забит. Полсотни точек одновременно, скайп работает проблемно.

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

Обувь. В Канаде я наконец-то увидел множество обуви, подходящей под украинскую зиму.

Супермаркеты и прочие магазины по выходным часто работают по сокращенному графику. Это лучше, чем в Берлине, но всё равно — шок.

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

Слышу сирену на улице. Потом снова. И еще. По улице на сумасшедшей скорости в 20 км/ч гоняет красный микроавтобус с надписью «Закрытие воды» («Fermeture d’eau»). Я так и не понял — это просят не пользоваться водопроводом? Ну, воду не отключили. По итогу отремонтировали гейзер воды из люка.

За первые десять дней видел две ржавые машины, гниющие на вечной стоянке.

Асфальт под дождиком кладут.

Я месяц жил на первом этаже, так вот шаги над головой — как рядом. Голосов не слышно.

Везде какие-то концерты и толпы народа. Несколько раз ощущал запах травки, год назад её разрешили.

Активировал новый номер, и через три часа на него уже пошел scam-звонок.

Был в условно русском магазине. Увидел, к примеру, «Квас Тарас» — редкая фигня. Еще всякие травяные настойки и т. д. Первая мысль: какую херню люди покупают от ностальгии. Вторая: а что буду покупать я? Чай?

Всё зеленое.




Много китайцев. Как говорят, пошла новая волна иммигрантов. Upd: я вижу волну русских+украинцев, китайцев, иранцев.

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

Три дня назад кто-то выкинул старый носок рядом с тротуаром. С интересом жду, когда его уберут. Нового мусора рядом не появляется, но и носок пока на месте.

Детей здесь выгуливают на поводке и в специальной форме.

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

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

Кстати, вот как раз с монетами мне языка и не хватило. Понадобилось мне постираться, пошел в подвал, нашел стиральную машину, нашел инструкцию. Налил на дно тайд. Высыпал одежду. Начал вставлять деньги. Не получается, монеты должны быть строго один доллар плюс два по четверти, и никак иначе. Итого, у меня в открытом общественном подвале гора вещей, подмоченных стиральной жидкостью, и нужно срочно разменять деньги. В соседнем подземном гараже нашел какого-то парня, попросил разменять. Он мне предложил дать два доллара. Объяснить ему, что у меня два доллара есть, не удалось. Так он, похоже, и решил, что я бомж, просящий милостыню. Хотелось ему оставить визитку «VP of engineering», но он всё равно по-английски не понимает. В общем, парень уехал, а я побежал в местный аналог Макдональдса (Tim Hortons). Там меня тоже не поняли, но я уже был умнее и заранее в гугл-транслейте перевел на французский.

Мне говорили, что с неба тут падает какая-то белая пакость. Ну вот июнь, выпала.

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

Заключал договор на интернет в дом. В Харькове я платил 400 грн за гигабит, тут я плачу 1100 грн за 60 мегабит. 60, Карл!

А в Airbnb-квартире инет падает. Как только люди не на работе — всё, пинги по 3 секунды, и каждую минуту разрывы по 10 секунд. Под конец месяца выяснилось, что нужно перегружать роутер раз в несколько часов. Ну и вообще, стабильный инет на 2,4 ГГц — это для деревни, а не мегаполиса.

Помните Задорнова — земля стекловатой? Шутил он и про выключатель за шкафом, и «ну, тупые!» Так вот, в квартире, где я жил — выключатель за шкафом.

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

Трупиал

Красноплечий чёрный трупиал долбанул меня по затылку.

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

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

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

Курильщики

Курящие в Канаде есть. За два месяца мне дважды приходилось отходить от них в сторону.

В открытой продаже сигарет нет, рекламы тоже нет, в том числе скрытой «Мальбара — известный производитель леденцов». Чтобы купить сигареты, нужно подойти к продавцу, и за $20 он тебе достанет из-под прилавка пачку. Другие покупатели её не увидят. И да, $20 — это много.

Белки

Покормить белку в Монреале стоитот 300 до 600 долларов. Прибить, например, отгоняя от своего цветника — примерно столько же.

Это в первый раз, во второй будет дороже. В третий — еще дороже.

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

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

Естественно, все эти штрафы — если, например, соседи пожалуются. При желании можно поиграть в рулетку.

Кошки

Обеих кошек мы подобрали с улицы.

Старшая, Броня, считает, что с нее хватит, и на улицу — ни ногой.

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

А белки кроют матом понаехавших.

А я думаю, во сколько обойдется, если Пуша таки поймает белку на глазах у соседей.

И еще, как объяснить Пуше, что ночью её на дороге не видно.

И что делать, когда Пуша испугает скунса.

Вода

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

Ну и вода чистая, холодная, мокрая.





Видел серферов, которые оседлали бурун на доске и катятся на одном месте по несколько минут. Кстати, тонут люди, уж очень шустрое течение.

Улицы

Почему сложно сфоткать типичную улицу в Монреале? Или в кадр попадает только один дом, или ты видишь зеленую улицу. Как я понимаю, местные правила требуют перед домом посадить дерево (или несколько). И городские власти что-то о кронировании не знают. Я напедалил больше 30 км по улицам в районе... ну, в Харькове это был бы кинотеатр Довженко или Троянда: вроде и метро не очень далеко, и жилье дорогое, но уже и совсем не центр.

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

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

Я долго искал прыщ на ухоженном лице Монреаля. Нашел. В прошлый раз мы остановились здесь — это самый конец Gay Village. Этим домам по сто лет, они внутри тесные и неудобные.

Маленькие тротуары, почти нет зелени. Если бы я не знал с сентября о существовании этой улочки — я бы не нашел.

И у меня предположение, что я съел что-то из арсенала Кэрролла.

Борщ

Я полтора месяца жил вдали от жены. Да, мы созванивались, но не всё можно сделать через интернет.

И вот, я не утерпел и решил сварить борщ.

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

Итого. Примерно 30 USD на продукты, час на порезку и прочее, и у меня есть кастрюля «борща». Ну-у-у... я это ем. Без удовольствия. Как выяснилось, в борщ входит ингредиент, о котором я не подумал совсем. Вода. Вода из-под крана. В чае она хоть как-то терпима, но в борще... жуть.

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

UPD: 30 USD — это я специй купил. И вообще, теперь я знаю, что магазин был совсем неправильный.

Язык

Как я понимаю ситуацию с языками в Монреале на основании услышанного и подслушанного и без глубокого анализа статистики.

Английский — язык международных компаний.

Французский — родной язык большинства тут.

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

Из школы выпускаются последние лет десять-двадцать вполне двуязычные.

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

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

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

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

То есть французский в теории важен и необходим, и на практике важен и полезен. Но общение всё больше происходит на английском.

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

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

Официальная статистика отсюда.

Зрада политическая

Подобрал бегло самые скандальные новости Монреаля.

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

Киты запутываются в веревках и тонут.

Правительство плющит англоязычные школы, те идут в суд.

В дальней деревне на севере собаки загрызли годовалого ребенка.

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

Из-за множественных ремонтов на мостах и дорогах много пробок. Всё время что-то ремонтируют и строят, причем очень быстро. Местные говорят, что дорожные работы — это способ откатов.

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

Два года назад два мужика избили пожилую женщину. Сегодня их поймали.

Налоги на богатых, какой формулой их описать?

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

Владельцы жилья сдают его через Airbnb и не платят налоги. Цены на жилье растут, рынок не успевает строить новые дома.

Школы переполнены, детей много.

Правительство тянет нефтепровод из Альберты. Он окупится, только если нефть будет дорогой.

----
Это самое скандальное, за что я зацепился в местных новостях.

«Газеты в идеальной Утопии были бы нестерпимо скучны» © А. Кларк, «2001: Космическая Одиссея»

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

И еще о зраде. Действующий премьер-министр, тот самый Трюдо, которого мы знаем по носками Мелании, победил в выборах. Несмотря на то, что на него нашли страшный компромат: 18 лет назад он использовал блэкфейс. Всем бы такой компромат :)

Зрада бытовая

В супермаркетах часто дурят с ценниками. То есть на кассе оказывается, что товар стоит не столько, сколько ты думал. Есть и законы, которые должны такое предотвращать — но нет, сталкивались неоднократно. Чеки нужно хранить.

Банки мошенничают с новоприбывшими по поводу курса и скрытых платежей.

Полиция кражи расследует лениво и неохотно, «меньше 1000 баксов? Ну-у-у...» Может левый штраф выписать.

В локальной группе жалоба: «Сосед курит на балконе, ко мне затягивает, ничего сделать не смогли, вынуждены переехать». Там же жалоба: «В этом году в парке много диких гусей, всё засрали, ходить невозможно» и тут же «Понаехавшие дети гоняют гусей, как так можно с живой природой!»

Арендодатели жалуются, что не могут ставить рыночную цену на жилье для тех, кто арендовал давно.

При покупке мягкой мебели есть хороший шанс купить с насекомыми.

При покупке б/у техники запросто могут продать нерабочую. Лотерея.

Культура

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

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

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

Адаптация

За интеграцией в сообщество следят очень четко. То есть китайский квартал — запросто, но все будут говорить на английском или французском. И соблюдать местные законы. Был конфликт между «присягу на гражданство нужно произносить так, чтобы было видно движущиеся губы» + «судья, принимающий гражданство, может быть мужчиной» + «некоторые религии требуют скрывать женское лицо перед посторонними мужчинами». Так вот, толерантные канадцы решили, что закон важнее. Не можешь соответствовать закону — не принимай гражданство. В Квебеке госслужащим запрещено надевать религиозные символы в школу. То есть учитель с крестиком на шее в школе невозможен.

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

Чего мне не хватает: сравнительно сложно купить сало, пельмени, хлеб привычный. Нет «Пузатой хаты». Uber работает хуже OnTaxi/Уклона. Нет щавеля и творога.

Семейная экономика

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

Одинокая женщина может содержать ребенка. Но при этом домохозяйничать жене айтишника может не удаться. Механизм я пока не понимаю.

«Сколько остается на руки?» — пока не знаю достаточно точно. При одном работающем в семье, скорее всего, хватит на жизнь в квартире в средненьком районе и на б/у машину. Голодать не будете, и медицина тоже будет. Но на несколько лет придется забыть про «Я привык к топовому макбуку» и «Раз в год слетать в жаркие страны». Джуниором быть тяжело, да.

Если примерно, то у меня сейчас из зарплаты 35% уходит на налоги. И к большинству ценников в супермаркете нужно добавлять 5% федеральных + 10% провинциальных. Последнее — кроме Альберты/Эдмонтона, у них таких налогов нет.

Вилка зп для приехавших синьоров — от 70 до 100 тыс. канадских долларов в год до налогов (1 CAD = 0,76 USD).

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

Еда — ну пусть будет 10 CAD на человека в день. Это невероятно примерно. Явно можно и 5, и 25. Очень важно научиться пользоваться скидками. К примеру, мясо стоит 10-30 CAD,а по скидке — от 6.

Вещи, которые я привык покупать дешево, от хлеба до билета на автобус — будут стоить дорого. Вообще цены начинаются от 3-5 CAD,человеко-час слишком дорог. Вещи, которые я привык, что они дороги, — тут дешевле: машины, одежда, бытовая техника и т. д.

Остальное лучше посчитать на numbeo.

Улыбки

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

Итак, очередная черно-белая метрика превратилась в функцию от количества встреч за единицу времени. «Если я последний раз видел другого человека больше 15 минут назад, то следующему можно кивнуть или поздороваться».

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

Note 1:Числа приблизительные и не подтверждены научно достоверными методами.

Note 2:Правила сложнее и должны зависеть от количества людей в моей и встречной группе, освещенности, репутации района и т. д.

LGBT

В Монреале целующиеся парни — не редкость, и это никого не цепляет. Есть даже исторический район Gay Village вблизи от центра города.

Во многих анкетах видны следы адаптации под современные требования «М» + «Ж» + «скажу потом».

Здесь это воспринимается как норма. Я вспомнил об этом, так как фейсбук подсунул статью со ссылкой на научное исследованиес выводом: «В тех штатах, где разрешили однополые браки, количество суицидов среди подростков упало на 7%».

Логистика по городу

Арендовал вел bixi. Неубиваемый малоудобный танк. Непривычно, когда машины тебе уступают. Особенно с учетом правила «кто первый подъехал к нерегулируемому перекрёстку, тот первый и стартует». Пока я жду, что сейчас они проедут, они ждут меня.

Если я, как пешеход, подошел к переходу, то машины остановятся. То есть если я НЕ хочу переходить вот прямо сейчас, то нужно остановиться в полутора метрах от проезжей части. Upd: с точки зрения водителя пешеход, машущий «проезжай» с края тротуара, предлагает рискнуть сотней баксов ради 20 секунд экономии.

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

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

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

Тяжелое

Есть в Канаде тяжелые для меня явления.

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

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

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

Преступность

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

Кстати, сравнил статистику по изнасилованиямв Канаде/США/Украине, все показатели на 100 тыс. населения:

1,7 / 27,3 / 1,4

По исследованию Statistics Canada in 1992, только 6% женщин обратились в полицию. В США Bureau of Justice Statistics 2004 — 34,8%. Что касается Украины: думаю, что 1,4 — это не из-за малого количества, а от недоверия правоохранителям.

В общем, везде фиговато.

Для сравнения, уровень убийств. Его скрыть куда сложнее:

1,8 / 5,30 / 6,20

Ну и до кучи, количество заключенных:

114 / 655 / 157

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

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

Банки

— Хочу у вас счет открыть и деньги положить.
— Хорошо, сейчас посмотрю, в какой день мы сможем вас принять.
— А можно сейчас?
— Нет.
© Диалог в банке

Босс показал мне фокус: «Смотри, я карточкой расплатился, и уже через пять секунд у меня СМС об этом!» Э-э-э... ну... а какой украинский банк так не делает уже лет семь?

Банки в Канаде по украинским меркам — дикари.

К примеру, запросто есть лимиты типа «10 операций в месяц» и «не больше трех повышений лимита в месяц».

Еще для логина нельзя использовать SMS. И о «левых» списаниях ты узнаешь не по SMS, а по выписке в конце месяца. Ага, вы эту выписку читали у активного пользователя? Количество записей, расшифровка торговой точки?

И если у тебя скопировали дебитную карточку — это твоя проблема. Кстати, booking.com слал все данные карточки отелю в открытом виде.

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

Но мне кредитку в RBC не дали, т.к. work permit всего на год.

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

Тут, кажется, всего семь банков, и им хорошо. Слабая конкуренция. Revolut тоже пока не зашел.

— Хочу получить кредитку, у меня рабочая виза на год.
— Ок, вот вам кредитка на 500 CAD. Но мы заблокируем 500 с вашего основного счета на год.
— В смысле вы берете мои деньги, отдаете их мне в кредит и штрафуете, если я свои деньги себе отдам не вовремя?
— Да.
© диалог в банке

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

3D Secure нет нигде.

Логин в онлайн-банкинг через СМС — в одном из трех банков.

Везде упор на мобильное приложение, но мой note 9 три из четырех банков не поддерживают. Они вообще, кажись, только до Android 7 умеют.

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

Паспорт для получения туалетной бумаги

Всё просто:

  1. Заказываешь кучу всякого на Амазоне.
  2. Вспоминаешь, что бумага заканчивается и что на веле её везти от супермаркета неудобно. Докидываешь в заказ с формулировкой «Привезти всё одной коробкой».
  3. Получаешь письмо «Одной не получилось, будет двумя».
  4. Получаешь первую коробку и письмо «Для получения второй нужно подойти на почту с паспортом».
  5. Идешь на почту в супермаркет, показываешь паспорт, получаешь коробку с туалетной бумагой.
  6. На веле везёшь её из супермаркета. Неудобно.

Бонус: коробка!

Сто дней одиночества

Я получил визу в мае, и тут же улетел — так было нужно. В июле моей семье в визе отказали: если коротко, то «мы не понимаем, почему вы не оформляли визу вместе». Ок, из-за ошибки юриста я потерял примерно 2500 USD на билетах. В сентябре подтвердили апелляцию. Зато я прожил сто дней в одиночестве. Это мой первый опыт жизни в отрыве от тесных контактов и самостоятельного ведения хозяйства долгое время.

Что я заметил:

  • Эмоциональные перепады у меня есть сами по себе. Их нельзя однозначно списать на семейные и рабочие отношения. Может быть — на погоду, еду, сбитый график сна и т. д. И депрессия, и тревожность — это мои внутренние процессы. Это знание поможет мне дальше в семейных конфликтах.
  • На расстоянии семейные конфликты у нас не возникали. А вот в Париже, где мы встретились на несколько дней в августе, на второй день вспыхнуло на ровном месте. Больше раскрываемся и подставляем уязвимые места. И это правильно. А еще лучше — уметь конфликты конструктивно решать. Это куда лучше, чем «не показывай свои эмоции».
  • Я себя считал устойчивым к одиночеству и интровертом, так нифига. Одному плохо. Как сейчас плохо маме — страшно подумать.
  • Вкус в одежде скакал очень неожиданно. Была футболка, которая мне очень понравилась на АлиЭкспрессе, заказал. Я её очень ждал, чуть ли не каждый день трекинг смотрел. А потом пришло сообщение об отказе в визе для семьи, и всё — эта футболка мне нафиг не нужна.
  • Я теперь совершенно точно знаю тот баланс уборки-разборки, в котором мне комфортно. Заодно знаю, сколько я продуцирую пыли и волос :)
  • Посудомойка для одного человека — скорее не нужна, чем нужна.

Воссоединение

Через пару недель после прилета дети пошли в школу. Все трое — в разные французские welcome classes: это такие классы, в которых 15 детей, говорящих на 10 языках. Я читал, что такая практика в каждой школе — только в Канаде и Израиле. Как я понимаю, в США и Австралии это тоже есть, но не так массово.

Итак, дети.

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

Лена, почти 10. Французский — десять занятий, английский — около нуля. Обзавелась подружками, преимущественно русскоязычными.

Катя, 6. Ей школа дается со скрипом, в её возрасте обязательность задач еще внове.

В младшей школе запрещены мобильные телефоны. В старшей — ограниченно.

В Квебеке школа отделена от религии. В других провинциях хорошие школы обычно католические.

Учебная программа явно слабее по математике и точным наукам. Везде, где есть формулы, Лена и Игорь имеют несколько лет форы.

Для родителей тоже есть бесплатные курсы французского, мы уже были на нескольких занятиях. Обещают довести до B2 примерно за год. Хотя я не уверен, что вытяну. Особенно с учетом того, что курсы заканчиваются в 21, а мне к 5 на работу.

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

Ботинки

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

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

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

Времени не было, так что взял так.

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

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

Второе решение: я же инженер. Ладно, «инженер минус программист» — примерно так в дипломе написано. Я могу сжечь эту схему в микроволновке.

Ок, ботинок в кулек, и десятком импульсов по паре секунд обработал. Ботинок даже не нагрелся.

Второй ботинок обработал импульсом в семь секунд.

Теперь я знаю, что:

  • схема вшита в левую подошву;
  • схема боится микроволн;
  • даже с такой дырой хорошие ботинки остаются водонепроницаемы.

Я получил новый квест по засиликониванию дыры и покупке новых стелек. Что увеличило цену в 45 CAD (860 UAH) еще процентов на 10.

Вело и дороги

По трекеру, я за полгода накатал больше 1000 км по Монреалю на велосипеде. На фото — самый жуткий участок самой плохой дороги, я специально искал. Там глубина ямы — сантиметров семь, и машины объезжают. На второй фотке — просто плохая дорога. Плохая — это значит в трещинах. Я бы сказал, что таких километров пять я видел в сумме за все поездки. Это не сравнить с выездом из нашего двора в «элитной» Алексеевке, и уж тем более — с трассой на Казачью Лопань, где я на горном веле выше 7 км/ч разогнаться не мог.

Местные жители на дороги жалуются. И на дорожников жалуются: «У нас два сезона — снег и ремонт». Реально, дороги непрерывно перекрываются в самых неожиданных местах. Навигатор не всегда успевает обновиться, а ездить по местным дорогам без навигатора — верный способ найти приключения.

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

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

Вот этот кусок велодорожки меня раздражает. Шесть бордюрчиков на сто метров! Ну кто так строит!

Вообще велоинфраструктура заслуживает отдельного лонгрида. Здесь ездят на всём — от велоприцепов для тех, кто еще не ходит, до электрокресел для тех, кто уже не ходит. Многие, но не все, станции метро и автобусов адаптированы под «человека на колесах». И да, я понимаю, что лет через 20-30мне запросто что-то такое тоже может пригодиться.

Машины

Что я знаю про владение автомобилем в Канаде?

Б/у машины заметно дешевле, чем в Украине. Со всеми налогами нам полноприводная Toyota Venza 2011 обошлась в 11 тыс. USD. В Украине было бы примерно от 17 до 20 до налогов.

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

А вот работа механика будет стоить от 30 до 80 USD в час. И менять какой-нибудь ШРУС они захотят только в сборе. Поэтому мелкие фиксы часто не делают.

Техосмотра нет.

По словам жены, правила очень четко гнут линию «в любой сомнительной ситуации — уступи, пропусти, замедлись». В реальной жизни всё не так радужно, но всё равно имеет место быть.

В Монреале пробок почти нет, а вот тянучки со скоростью пешехода — частенько.

Отношение к машине очень потребительское, сломалась — в гарантию/сервис/гараж. Мало кто возится с машиной сам. Поэтому приезжие из второй четверти 20-говека вполне хакают систему, выполняя мелкий ремонт самостоятельно. Или крупный — в гараже.

Пробег вполне скручивают, и чем старше машина — тем больше шансов. Зато если в Украине машины с заявленным пробегом больше 150 — редкость, то тут и 400+ вполне бывает.

Проверка машины на СТО перед продажей — экзотика.

Большинство б/у машин продается по схеме «я покупаю новую, а старую отдаю дилеру, пусть он продает».

Страховка обязательна, и все страховые случаи попадают в базу. То есть все более-менее двухсторонние аварии в истории машины легко отслеживаются. А вот кейсы «стукнул столб», «утонул» или «поймал лося» — совсем не факт. Лось — смертельно опасен из-за длинных ног, тушка в 300-500+ кгна хайвэйной скорости как раз в лобовое влетает.

Нам опять здорово помог CarFinder.

Рекомендую:

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

При покупке машины очень редко кто платит наличкой. Но как у недавно приехавших, у нас только наличка и была. Оформили все бумаги, нас поздравили, попрощались и показали, где выход. Я: «Ребята, вы забыли у нас деньги взять». Они: O_o. Непривычно им с налом.

На КПДВ — счастье детей, нашедших панорамную крышу и люк.

Как уехать в Канаду айтишнику и не только

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

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

Масса консультантов по иммиграции. Большинство заточено на «а мы вам за несколько тысяч баксов подскажем универ, куда поступать, и поможем заполнить анкету». В общем, сомнительная услуга, как по мне.

Возраст — лет этак до 35 без проблем. С моими 42 — нужно уже сильно изворачиваться и набивать отличные языки, job offer и т. д.

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

Переезд

Этапы:

  1. Если есть возможность — лучше получить туристическую визу и слетатьпосмотреть заранее, походить по собеседованиям. Кмк, это окупится.
  2. Рабочая визана конкретного работодателя. Это не обязательно, особенно для тех, у кого хорошие языки, возраст до ~35, синьор, и есть запас в несколько тысяч долларов на человека. Работодателю нужно на каждого человека исписать пачку бумаги, так что это удел крупных компаний. Ну, или уникальных специалистов.
  3. Вид на жительство — Квебеки остальная Канада. Проще получить с канадским опытом на рабочей визе, но можно и так податься. Заранее можно подсчитать шансы. И да, скорее всего, поиск первой канадской работы займет несколько месяцев, которые нужно на что-то жить.
  4. Гражданство. Это через несколько лет работы и после сдачи экзаменов и присяги.

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

Шаги:

  1. Перевести документы: свидетельства о рождении, браке и т. д.
  2. Подтвердить диплом: это несколько месяцев и включает в себя два министерства образования, фирму-прокладку в Киеве, ну и на почту.
  3. Сдать экзамен по языкам (IELTS). Экзамен здорово отличается от реальной жизни, лучше к нему готовиться заранее с преподавателем. Например, я погорел на скорости письма ручкой по бумаге. Тупо времени не хватило. В этом году уже можно и на компе сдавать.
  4. Податься на разрешение на обучение детей. Тут я не уверен, в каком порядке с визой.
  5. Податься на визу. Если всё хорошо, то со временем придут запросы:
    • Медкомиссия. Канада хочет быть уверена, что новоприбывшие не повиснут на шее бесплатной медицине дорогим грузом. Медкомиссию зачастую проще сдать в Стамбуле, чем в Киеве и Львове.
    • Биометрика. Лично нужно явиться, Киев или Львов.
    • Штампы в паспортах.
  6. Купить билеты. Обычно AirFrance Киев-Монреаль-Киев стоит 720 USD с человека в обе стороны, между рейсами туда и обратно может пройти год. А вот летом билеты в Канаду безумно дороги, могут быть раз эдак в пять дороже. Кстати, агрегаторы этот рейс не находят, и искать его нужно строго на airfrance.ua.
  7. Забронировать Airbnb на первое время. Квартиры обычно сдают с 1-гоиюля либо с 1-гоянваря, в другие месяцы дороже, и в любом случае с 1-гочисла.
  8. Купить медстраховку на три месяца. Я брал тут.
  9. Перелет.
  10. Купить проездной и местную симку.
  11. Получить «карту греха» (SIN card).
  12. Оформить счет в банке. CIBC сейчас самый дружественный для свежеприехавших.
  13. Оформить RAMQне позже двух недель после прилета, иначе медстраховку придется докупать.
  14. Купить машину.

Если верить историям, которые я слышал — от начала активных действий (диплом, IELTS, собеседования) и до отъезда проходит от года до пяти лет.

Вебинар

Мне в личку упала пачка вопросов про Канаду, самых разных. Расписывать их все — это медленно и долго. Поэтому я сделаю вебинар в воскресенье 17 ноября в 14:00 по Киеву, часа на полтора. Такой вебинар потребует от меня каких-то усилий по организации и оплаты Zoom.us. Цена билета — переведите немного денег проверенным волонтерам или на благотворительность. Выкладывать запись вебинара не планирую. Регистрация на вебинар тут.

Культурный код

Это уже не про Канаду, хотя близко.

© не моя

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

Или, к примеру, такой диалог:

Исполнитель>я предлагаю вот такую фичу.
Американцы>интересная идея, но сейчас, пожалуйста, сфокусируйся на вот этом и этом.

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

Пример реальный, приведен в сокращении из-за NDA.

Со стороны исполнителей все были уверены, что дела идут классно.

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

Я поймал это общение слишком поздно. Я проанализировал все треды переписки и чатов, звонков до взрыва не было. Я расставил хронологию каждого события. Я нашел слова-триггеры, которые вызвали детонацию. Там не было ничего особенного, просто общение без понимания эмоционального и культурного контекстов с обеих сторон. И... было слишком поздно. С тех пор прошло несколько месяцев, мне не удалось исправить ситуацию. В результате, бизнес-команда решила уволить двух классных UI/UX дизайнеров, которые еще и в маркетинг могут. Проактивных сотрудников, задающих вопросы, генерирующих идеи и говорящих на беглом английском. Кто будет делать работу вместо них — я хз.

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

vk>Я всем товарищам говорю: чувак, я не из вашей страны, поэтому не в курсе обычаев. Если что-то важно для тебя, говори мне об этом прямо, без намёков. Максимально просто.
vz>Для них это звучит как просьба выражать свои мысли матом и унижать собеседника. «Я пойму это ТЗ, только если ты привяжешь меня к столу и хорошенько отхлещешь прямо на митинге».

Прошлое не изменишь, а вот в будущем я советую обращать внимание не только на дословный перевод!

Ну и если вдруг у вас есть вакансия/работа для UI/UX/маркетинг с программистским бэкграундом — обращайтесь.

Як правильно поїдати чуже печиво: GDPR-аспект

$
0
0

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

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

Чому? Тому що юристи-GDPRники знають, як важко буває переконувати клієнта:

«Так, потрібно, щоб користувачі погодилися на використання кукі!»
«Так, така згода має бути надана ПЕРЕД установленням файлів кукі на комп’ютер користувача!»
«Ні, недостатньо лише дати знати, що кукі просто збираються».

І ще ж треба відбиватися від слушних зауважень клієнта про те, що «інші ж компанії такий „дикий“ банер, як ви радите, не публікують!».

Слава горішкам, авторитетний орган із захисту персональних даних у Великій Британії Information Commissioner’s Office (ICO) чи не вперше кинув світло на ці чутливі питання й додав горе-юристам трохи впевненості, яку вони часто втрачали, побачивши подив клієнта на рекомендації перебудувати звичний процес використовування кукі.

Розберімося в тому, які здогади юристів підтвердив ICO у своїх рекомендаціях.

Що таке кукі?

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

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

Бувають наполегливі кукі (такий переклад ґуґл-транслейту дуже влучно передає суть їхньої дії) — «persistent cookies», що зберігаються на комп’ютері користувача кілька хвилин, годин або днів і для використання яких майже завжди потрібна згода користувача.

Бувають також сесійні кукі («session cookies»), що видаляються, коли користувач закриває свій браузер.

Бувають кукі, які встановлює сам власник веб-сайту, а бувають такі, що належать третім особам і якими наш власник просто нашпиговує свій веб-сайт (для реклами, збирання аналітики, безпеки тощо). Наприклад, кукі player і vuid, що уможливлюють Vimeo одержувати інформацію про те, скільки часу користувач переглядав відос).

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

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

А можна без тої згоди якось обійтися?

Загальне правило надавання згоди для встановлення кукі звучить так: згода потрібна тільки тоді, коли збираються кукі, що не є на 100% обов’язковими для функціонування сервісу. Для тих кукі, які а) є необхідними для технічної мети передання інформації електронними мережами та б) є життєво важливими для функціонування сервісу, попередня згода на встановлення не потрібна.

Щоб використати підставу пункту а), треба, щоб передання інформації було неможливим без використання таких кукі.

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

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

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

Багато популярних онлайн-видань мають функцію залишання коментарів під статтями. Так, під актуальними статтями «Української правди» або The Guardian можуть розвинутися справжні холівари, а деякі не менш поважні видання не надають своїм читачам можливості коментувати статті (гляньте на The New Yorker).

Як гадаєте, можливість коментувати матеріал є необхідним компонентом інформаційної послуги, що її надає онлайн-видання, чи ні?

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

Аналітичні кукі

Окреме питання становлять аналітичні кукі (наприклад, ґуґлівські Universal Analytics Cookies _ga,_gali,_gat,_gid). Вони не є необхідними для надавання будь-яких інформаційних послуг, а мають лише допоміжне значення. Такі кукі показують власникові кількість відвідувачів; частини та вкладки сайту, що їх найбільше відвідують користувачі; час, протягом якого відвідувачі залипають на сайті. Якщо ж обробка інформації, що збирається через такі кукі, має низький рівень ризику для користувачів і якщо такі кукі не є кукі третіх осіб, то згоду одержувати не потрібно.

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

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

Форма згоди

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

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

Тобто для того, щоб правомірно використовувати інформацію, яку збирають кукі, треба:

  • повідомити користувача, які саме кукі встановлюються та для чого;
  • одержати згоду на їх установлення (якщо вони не підпадають під визначення тих кукі, згода на встановлення яких не потрібна).

При цьому для опису видів кукі не потрібно зазначати:

NamePurpose and DescriptionLifespan
_hjIncludedInSampleSession-based cookie set to let Hotjar know whether that visitor is included in the sample which is used to generate funnelsExpires in 365 days

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

І ніяких там наперед проставлених галочок! Але про це правило ви вже, мабуть, знаєте.

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

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

Якщо ви прихильник мінімалізму та ергономічності сайту, вас також чекає дизайн-розчарування: банер з куками кислотно-зеленого кольору з додаванням миготіння — «самоє оно» в очах творців GDPR. Маленька стильна кнопочка у кутку сторінки не підходить, банер має бути помітним для користувача, — це вимога GDPR.

Разом з тим, творці GDPR та захисники privacy знають про проблему з банерами та про те, що, ніде правди діти, дуже мало хто робить ці банери «як має бути». З одного боку, їх зв’язують вимоги захисту приватності, з іншого — потреби бізнесу, яким ці вимоги щодо кук точно як кістка в горлі. Триває обговорення нової ePrivacy Regulation, яка має детально врегулювати встановлення кук на пристроях користувачів та обробки отриманої від них інформації. Цей документ усі чекають як звільнення від тягаря невизначеності кукіз-банерів. Зокрема, у цьому регламенті «мужі й панни» європейського data protection задумуються, а чи не закинути м’яч на поле цих користувачів інтернету. І нехай це вже буде їхня відповідальність за уміння користуватися браузерами (ну і самих браузерів, які будуть думати, що робити, якщо їх зобов’яжуть надавати користувачеві зручненький доступ до панелі управління всіма видами необов’язкових кук). Можливіть видаляти куки або забороняти їх встановлення уже є, однак ePrivacy Regulation може зробити, наприклад, так, що Chrome буде пропонувати нам позначати галочки про певні види кук перед кожним його запуском, або ж встановить цю миготливу кислотно-зелену кнопку про налаштування кук десь на його панелі.

Що ж буде, якщо не заморочуватися над цим банером?

Поки вказане вище звільнення у вигляді ePrivacy Regulation не зійшло на бізнес (а воно уже не перший рік не приймається, а тільки обговорюється), відповідь залежить від декількох факторів:

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

А який той розмір? Не хочеться прив’язувати 20 млн євро або 4% від річного обороту в статті про правильний банер для кукі, але саме такий верхній поріг відповідальності встановлює GDPR для неналежно одержаної згоди на оброблення даних. Звісно ж, такий штраф за поганий банер ніхто не встановлюватиме, а будуть братися до уваги чинники, наведені вище. Ну і варто згадати, що банер — це тільки верхівка айсберга всіх заходів, які покладає на контролера чи оброблювача даних GDPR.

А тепе-е-ер — нумо, усі зацікавлені, на сайт ICO, бо там для новоприбулих користувачів якраз і розміщено новий банер для кукі! І — о боги!  — банер не дає користуватися сайтом, допоки ти не зробиш свій вибір.

Энциклопедия увольнений: 8 неочевидных причин ухода программистов

$
0
0

Я Валерия Козлова, автор технологии EQ Boost, преподаватель LvBS и основатель компании Corporate EQ. В своей работе мне часто приходится обучать тому, как создавать синергию в команде. Используя один из методов наблюдения за неочевидными вещами в поисках lean-решений к продуктивности команд, я увидела: многие командные процессы, которые нам видны, на самом деле лишь верхушка айсберга. То, что определяет решения и результат, часто скрыто глубоко «под водой». Уход из команды ключевых сотрудников — хорошая иллюстрация этого явления. Некоторыми из таких случаев я хочу поделиться с вами.

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

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

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

Иллюстрации Дарины Скульской

1. Ошибка лидера

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

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

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

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

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

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

Этот кейс — один из примеров того, как лидер разваливает команду.

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

2. Изменение культуры компании

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

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

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

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

3. Тайные эмоции

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

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

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

Рекомендация для топ-менеджеров и собственников.Стыд — эмоция сложная. Я исследовала ее около 15 лет у клиентов с разными ситуациями и в жизни, и в карьере. Чтобы не переживать стыд, мы подменяем его другой эмоцией. Об этом я писала ранее в своей книге «Технологія EQ Boost: як використовувати емоційний інтелект у бізнесі та житті». Знание этих защит и само предположение, что провал может вызывать стыд, помогут предвосхитить увольнение сотрудника, помочь ему и дать возможность переосмыслить свой провал (например, получив какой-то проект, где он может реабилитировать себя). И вместо того, чтобы отпускать прекрасного сотрудника, который может принести компании много пользы, можно изменить стратегию и поддержать его, помогая решить эту проблему. Дело в том, что стыд — настолько токсичная эмоция, что справиться с ней одному очень и очень трудно.

4. Отсутствие современных технологий

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

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

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

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

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

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

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

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

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

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

6. Стагнация компании

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

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

Рекомендация.Необходимые действия связаны с поисками новых возможностей в мышлении самого собственника. Это та точка, в которой нужно остановиться и изменить себя и свое поведение. Применять мышление для компании численностью 100 человек во время строительства компании в 1000 человек не эффективно. Собственники часто не осознают, что причина заключается именно в этом. Что мешает? Иногда — страх, что «не потяну». Иногда — отсутствие собственного ресурса при том же количестве часов в сутки, ведь надо успевать сделать больше, потому что компания растет.

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

7. Разрыв видения собственника и его команды

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

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

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

  1. Обсуждение стратегии собственника с топами для ее лучшего понимания и формулирования.
  2. Помощь в поиске конкретной точки на карте будущего для каждого члена команды.

Именно это я называю преодолением разрыва между видением собственника и его команды.

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

8. Конфликт ценностей

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

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

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

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

Подводя итог

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

Советы для начинающего Java-разработчика. Подготовка к собеседованию — часть 3

$
0
0

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

Алгоритмы

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

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

Что спрашивают часто:

  • Что такое сложность алгоритма? Практический вариант: сравните сложность двух решений одной задачи.

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

  • Какие знаете сортировки, которые используются в стандартных механизмах Java?

Вопрос про QuickSort и TimSort, и их применение. Быструю сортировку желательно уметь реализовать в простом варианте для саморазвития.

  • Бинарный поиск. Мастхэв, элементарный алгоритм, много кто спрашивает. Сложность знать обязательно, так же как и уметь объяснить, почему она такая.
  • Структуры данных в Java, которые умеют сортировать под капотом. Для чего чаще всего используются? Что внутри, как происходит сортировка? При каком условии объекты, положенные внутрь, будут отсортированы правильно?
  • Почему иногда выбор худшей по сложности сортировки выгоднее?

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

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

Паттерны проектирования

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

Спрашивать любят про разделение паттернов на категории, по каждой из которых обычно просят назвать 2-3известных паттерна и рассказать о них. Есть сайтдля изучения основ на абстрактных примерах. Я не очень хорошо отношусь к абстрактным примерам после своей первой книги Head First Design Patterns, но refactoring guru неплохо поясняет теоретические аспекты и необходимость использования того или иного шаблона. Практику же можно параллельно просматривать вот здесь. Хороший ресурс для добавления в закладки и постепенного изучения после трудоустройства.

Если сроки поджимают, то вот небольшой список на изучение по каждой категории:

  • порождающие: фабричный метод, абстрактная фабрика, билдер, синглтон;
  • структурные: фасад, прокси, декоратор;
  • поведенческие: шаблонный метод, наблюдатель, стратегия;
  • дополнительно (но не менее важно): DAO, repository, MVC.

Из GRASP-паттернов можно ознакомиться с Low Coupling и High Cohesion как основополагающими принципами. Тем более, что в отличие от GoF, их можно интуитивно понять после первого же прочтения.

Системы контроля версий

Изучение VCS (на примере Git) очень рекомендую делать на практике по принципу «прочитал — выполнил — проверил результат». На первых порах достаточно будет выучить список основных команд и для чего они нужны: push (с опциями), pull, fetch, commit, merge, rebase, squash, revert. После проверки на практике вопросы вроде «как отменить несколько коммитов» или «как собрать несколько коммитов в один» должны перестать беспокоить. Хотя последние спрашивают уже от уровня крепкого джуна и выше. Тогда же спросят про Git workflow или жизненный цикл разработки. Недоджуну достаточно понимать общие принципы совместной работы с кодом и уметь подтягивать чужие изменения, коммитить свои и делать merge. Остальное рекомендую изучать уже после трудоустройства.

Сборка проекта

Самые популярные сборщики сегодня: Maven и Gradle. Вторым воспользоваться на реальном проекте мне так и не довелось, поэтому все дальнейшее будет относиться к мавену.

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

Что хотят услышать на собеседовании:

  • Что вообще такое процесс сборки проекта на Java? Для чего нужна сборка? Что имеем на выходе?
  • За что отвечает pom.xml и какая у него структура?
  • Как организована сборка многомодульных проектов?
  • Назовите стандартные жизненные циклы мавена и несколько фаз, которые к ним относятся.
  • Как мавен решает проблемы с транзитивными зависимостями?

Веб-технологии

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

  • Что такое HTTP? какие у него альтернативы?
  • Какие есть HTTP-запросы? (назвать 4 основных будет достаточно) Какая между ними разница? Любимый вопрос у всех: чем GET отличается от POST?
  • Что такое REST? какие особенности RESTful-сервисов знаете? Про SOAP сегодня практически не спрашивают.
  • Назовите пару контейнеров для запуска веб-приложений на Java. Что они из себя представляют? Для сравнения можно рассмотреть популярные Tomcat и Jetty.

Тестирование

Требования к тестированию очень сильно отличаются от проекта к проекту. Где-то разделяют принципы TDD, где-то выделяют время только на минимальное покрытие тестами в силу приоритетов по другим задачам. Бизнесу виднее (почти сарказм). Знать заранее, как будет на следующем вашем проекте нельзя, поэтому сфокусируемся на базовых моментах. Самые распространенные для тестирования фреймворки на сегодня: JUnit для юнит-тестов и Mockito для имплементации заглушек. Оба элементарно подключаются к проекту и предельно просты в вопросе понимания необходимости их использования.

Что часто спрашивают:

  • Какие виды тестирования знаете и чем они отличаются? Разработчику достаточно назвать модульное, интеграционное и функциональное. Если назовете нагрузочное, то необходимо заранее посмотреть в сторону такого инструмента, как JMeter, чтобы было что отвечать на дополнительные вопросы без серьезного погружения в тему.
  • Основные аннотации в JUnit (test, before, after, beforeClass, afterClass, ignore) и их особенности.
  • Чем отличается Mock от Spy в мокито? Приведите пример использования первого и второго (крепкий джун+).
  • Что, если ожидаем от метода выброшенного исключения? Что, если метод не должен выполняться дольше определенного количества времени?
  • Какие модификаторы доступа у тестовых методов в JUnit?

У крепкого джуна могут также спросить про параметризированное/категоризированное тестирование (@RunWith аннотация). Или про нюансы тестирования методов, которые обращаются к БД.

Логирование

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

ALLЛогируются все сообщения
TRACEМелкое сообщение при отладке
DEBUGВажные сообщения при отладке
INFOПросто сообщение
WARNПредупреждение
ERRORОшибка
FATALФатальная ошибка

Если выставить уровень логирования в WARN, то все менее важные, чем WARN сообщения, будут отброшены (TRACE, DEBUG, INFO). Если нужно настроить, чтобы какие-то логи писались в файл, настраивается с помощью Appenders.

Дебаг

К сожалению, огромное количество претендентов на позицию джуна сильно недооценивают значимость такого инструмента разработчика, как отладчик. А уровень владения дебагом у среднестатистического стажера лежит в плоскости «вы знаете, я обычно просто добавляю System.out, чтобы посмотреть значение переменной». И очень мало, где пишут, что джун по факту проводит за отладкой и поиском ошибок не намного меньше времени, чем за разработкой. Отсюда рекомендация: обязательно разобраться в дебаге.

На примере IntelliJ IDEA: знать, какие функции в режиме отладки выполняют F7, F8, F9. Как посмотреть содержимое обрабатываемой коллекции в конкретный момент выполнения. Как изменить значение, которое передается в метод прямо в момент отладки. Попробуйте все это на практике: сложного ничего нет, а практической пользы очень много.

Методологии разработки

Так как работать разработчику приходится в команде, то и взаимодействие внутри нее всегда организовано в виде конкретного системного подхода. Сегодня балом правит Agile — набор гибких принципов, на основе которых строятся популярные методологии. Достаточно знать две самых распространенных из них: Scrum и Kanban.

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

У Kanban в основе визуализация процесса выполнения задач в виде трех колонок таблицы: To do, Doing, Done. Основная идея — уменьшать количество запланированных задач (куда уж банальнее) и постепенно перемещать их из колонки «To do» в «Done». Очень подходит для проектов, находящихся в стадии поддержки, где основной функционал уже разработан и остались минимальные доработки и багфиксинг.

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

Подготовка и процесс собеседования

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

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

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

На джава-форумах и каналах иногда просят оценить структуру готового домашнего проекта, чтобы понять, насколько все плохо/хорошо. Я считаю это хорошим подходом. Также неплохая книга для понимания таких основ — Thinking in JavaЭккеля.

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

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

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

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

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

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

В завершение

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

Дорогу осилит идущий. Удачи!


При возникновении вопросов, пообщаться со мной можно в телеграме: @liohamitec

14 типов менеджеров, которые бесят разработчиков

$
0
0

Статья написана в соавторстве с Дмитрием Ховричеми Мэри Ротарь, Co-Founder IAMPM.

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

Сперва пару слов о нас. Я Front-end Developer в DataArt, в профессии 7+ лет. Дмитрий Ховрич также больше 5 лет работает в коммерческой Front-end разработке.

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

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

1. Митинг-мэн

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

С таким менеджером времени на работу просто не остается. Ежедневно как минимум пару часов уходит на всевозможные митинги, на которых присутствует вся команда, хотя по факту нужны 1-2 человека.Митинг-мэн считает своим долгом выслать инвайты всем членам команды, собрать их в переговорке и начать говорить с каждым по отдельности.

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

Утром мы собрались, обсудили на стендапе задачи на день, выпили кофе, пообщались, сели за работу — и спустя час-два получаем инвайт на митинг. На митинге спрашивают: «Ну, что ты успел сделать? А что тебе мешало сделать больше? Может, тебе что-то нужно от коллег?» Так и хочется сказать: «Ну если нужно, то я подойду к коллеге и спрошу!» Если каждого в команде 5+ человек поспрашивать на митинге — уже, считай, минус час-полтора времени, которое можно было потратить на разработку.

Бывали случаи, когда кто-то работал удаленно по причине плохого самочувствия. И даже если конкретно сейчас вопросов к коллеге не было, а его присутствие на митинге было излишне, такой менеджер все равно дозванивался до человека и заставлял зайти в скайп и включить камеру: «Чтобы мы тебя видели!» Это выглядит немного странно, но это тоже особенность Митинг-мэна — достать даже мертвого из могилы и добавить его на колл.

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

2. Инкогнито

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

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

В итоге смысл феномена проектного менеджмента проявляется, только если на проекте что-то идет совсем не по плану — часто как раз из-за невключенности PM. В этом случае Инкогнито еще и недоумевает, почему с ним никто не советовался раньше. Да потому что работа стоит, тебя нет на связи, а ее надо делать! При знакомстве с менеджерами типа Инкогнито возникает вопрос: зачем они вообще нужны, если можно назначить главным лида, и все будет хорошо?

3. ХЗ-мэн

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

Практически каждый разработчик сталкивался с таской, которая состоит из одного title, например, «implement login». Смотришь на этот title и не понимаешь: что вообще нужно сделать?! Менеджер подразумевал фронтенд, бэкенд или вообще дизайн? Работа над такими задачами — это гадание по хрустальному шару.

К сожалению, ХЗ-мэны достаточно распространены. Поэтому, чтобы разработчики не впадали в ступор, когда они видят задачу, существуют такие проверенные временем подходы, как написание Acceptance Criteria и Definition of Done.

Кто-то может сказать, что DoD — это общие требования к качеству, а не обязанность менеджера, и тем не менее, позаботиться о том, чтобы этот список DoD был хотя бы прикреплен к задаче и формализован, а разработчик об этом попросту не забыл — все-таки должен PM. Если в компании DoD-a нет, PM-у стоит позаботиться об его организации. Менеджер может, как минимум, пнуть самого умного разработчика, чтобы он это сделал. Как бы то ни было, DoD на проекте должен быть, иначе работать сложно.

4. Задрот-мэн

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

Есть проект, довольно крупное мобильное приложение (количество пользователей исчисляется сотнями тысяч). Разработка ведется по Scrum: стандартные двухнедельные спринты, планирование, эстимейты — все, как положено в лучших домах Лондона и Парижа.

Внезапно в середине спринта ломается логин. Заказчик прибегает к менеджеру: «У меня 100К пользователей, и никто не может войти в систему, что делать? Давайте, ребята, почините». Менеджер: «У нас скрам! Все распланировано, мы не можем просто так взять и починить логин! Если ты хочешь, чтобы мы его починили, то давай сперва сядем, посмотрим бэклог, выберем задачу, которую выкинем из этого спринта, а вместо нее поставим задачу по фиксу логина».

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

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

5. Эстимейт-мэн

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

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

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

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

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

6. А давайте так-мэн

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

Всю прелесть работы с таким персонажем испытал на своей шкуре. Я тогда был новичком в компании и выполнял одну из своих первых тасок. Менеджер подошел ко мне и попросил показать конкретно в коде, что я сделал. Я показал код и объяснил, что мне нужно было создать еще одну таблицу в базе данных для хранения этих новых сущностей. Он мне говорит: «А почему ты создал новую таблицу? У нас же есть другая таблица». Я ответил, мол, эта таблица не подходит, потому что здесь немножко разные сущности. Менеджер начал утверждать, что сущности одинаковые. Спорили полчаса, пока я его не переубедил. Зачем я тратил свое время на этот спор, так и останется загадкой.

У моего товарища была ситуация, когда они полгода писали CRM-ку на Angular, в проекте были некоторые проблемы, которые менеджер планировал решить переписыванием всего на Vue через полгода разработки! Как это может решить проблему — непонятно, но команда была «в восторге».

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

У моих коллег был опыт с адекватным менеджером. Разработчики стояли перед выбором, как развивать проект, написанный на старом Angular. Пришел новый PM, предыдущий опыт которого был с командой, которая использовала Vue, поэтому он предложил: «Ребята, у нас в прошлой команде достаточно неплохо работал Vue. Давайте, может быть, тоже попробуем?» Общение шло в дружеском ключе, своего мнения он не навязывал. Разработчики подумали, попробовали и решили продолжать проект на Vue.

7. Криворукий джира-мэн

Практически в любом проекте есть какой-то таск-трекер (Jira, Trello), который за счет определенных инструментов позволяет выстроить flow разработки, тестирования и учета задач.

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

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

8. Да, конечно-мэн

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

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

9. Таска-мэн

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

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

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

10. Додо-мэн

Однажды я работал в компании, у которой есть свой офлайн-бизнес, допустим, по производству тапочек. В один прекрасный момент они решают построить IT-отдел. Раз есть отдел — нужен РМ. Руководство чешет репу и решает назначить Васю, который до этого был начальником в ООО «Рога и копыта».

Вася проект не менеджил от слова «совсем». Не потому, что он — плохой человек, а оттого, что в душе не ведал, что такое IT и как с ним быть. Так и «работали» до момента, когда мне надоело, что человек не понимает, где он, что здесь делает, и фактически мешает нашей работе. Я напечатал на листике пункты, по которым мы принимаем в работу задачи, положил Васе на стол и ушел. После этого у нас с ним состоялся непродолжительный диалог-разъяснение содержимого листика. Благо, Вася понимал, что ни черта не разбирался в разработке, и после беседы решил алгоритмом воспользоваться. Но такие «менеджеры» сильно демотивируют, и это приводит к утечке кадров.

11. Excel-мэн

Историю рассказал мой товарищ, который работал в достаточно крупной компании со своим внутренним IT-отделом. Программисты разрабатывали для компании интернет-магазин, внутренние CRM-ки и прочие программные штуки, которые упрощают продажу и дистрибуцию товара.

Был у них в команде PM, который в силу каких-то своих убеждений не мог пользоваться Jira, Trello и другими таск-трекерами. Он создал Excel-ку, в которой были расписаны задачи и исполнители. А вместо того чтобы в Jira перенести таску в колонку «In Progress», нужно было подойти к менеджеру и попросить его внести изменения в таблицу.

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

12. Копипаст-мэн

Менеджер не заморачивается с описанием стори/тасок. Просто копирует текст от клиента из письма/мессенджера и вставляет в описание в Jira. Разработчики сами разберутся.

Одна из ролей менеджера — услышать клиента и привести услышанное в понятный для разработчиков вид, а этот менеджер не проверяет текст на понятность, выполнимость и отсутствие бреда. И конечно, снова никаких тебе acceptance criteria.

13. Контроль-фрик

В отличие от Эстимейт-мэна, заморачивается на предмет того, на что вообще разработчик тратит время.

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

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

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

14. Потому что-мэн

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

Реальный кейс: в компанию прособеседовали семерых кандидатов. В результате разработчики выдвигают свою кандидатуру, которая, по их мнению, больше всего подходит на указанную должность. А в один прекрасный момент менеджер непонятно почему (бюджет/диалог с клиентом/интуиция) предлагает взять другого. Почему? Потому что!

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

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

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

В завершение

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

Union-find: алгоритм, применение и анализ сложности

$
0
0

Всем привет! Меня зовут Данил, и я Java-разработчик в компании TeamDev, занимаюсь написанием ПО для сетевых устройств.

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

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

Введение

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

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

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

Немного из теории множеств

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

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

Рассмотрим следующую задачу: имеется набор из N объектов, которые связаны между собой каким-то образом. Необходимо определить, существует ли путь, соединяющий выбранные объекты A и B через другие объекты. В теории графовданная задача определена как «задача о динамической связности» (dynamic connectivity).

Задача о динамической связности

Теперь предположим, что связанные между собой объекты — это элементы одного множества. Тогда, чтобы узнать, связаны ли выбранные объекты A и B, достаточно определить, принадлежат ли они одному множеству.

Такую структуру данных, где элементы распределены на непересекающиеся множества, называют системой непересекающихся множеств (union-find data structure).

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

Правила и ограничения

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

  1. Не имеет значения, что из себя представляют объекты. Для простоты можно сопоставить N объектам числа от 0до N  −  1.
  2. Не нужно определять, каким образом объекты связаны между собой, достаточно будет определить, принадлежат ли сопоставляемые им элементы одному множеству.
  3. Когда элементы непересекающихся множеств образуют связь, их множества объединяются.

Интерфейс

Итак, согласно первому правилу элементами множества будут числа от 0до N − 1. Для решения любых задач, использующих структуру данных union-find, будет достаточно определить следующие операции (здесь и далее примеры кода приводятся на языке Java):

    public interface UnionFind {
        void union(int p, int q);
        boolean connected(int p, int q);
    }

Немного подробнее о каждой из них:

  1. void union(int p, int q) — объединяет элементы pи q, а также множества, которым они принадлежат (правило 3).
  2. boolean connected(int p, int q) — проверяет, принадлежат ли элементы pи qодному множеству.

Жадный алгоритм

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

Структура данных, используемая в алгоритме, — простой массив целых чисел (nodes[]) размера N, где индексы от 0до N  −  1сопоставляются элементам множеств, которые могут впоследствии объединяться. Два элемента с индексами pи qбудут принадлежать одному множеству, если их значения по индексу совпадают (nodes[p] == nodes[q]). Значением может быть любой элемент множества, поэтому его еще называют представителем множества.

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

Конструктор выглядит следующим образом:

    public class QuickFind implements UnionFind {
        private int[] nodes;
        public QuickFind(int N) {
            nodes = new int[N];
            for (int i = 0; i < N; i++) {
                nodes[i] = i;
            }
        }
        public void union(int p, int q) { ... }
        public boolean connected(int p, int q) { ... }
     }

Возьмем для примера N = 10:

Вначале каждый элемент представляет собой синглтон

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

Алгоритм Quick-find

Теперь для того, чтобы определить, принадлежат ли два выбранных элемента одному множеству, достаточно сравнить значения по индексу: nodes[p] == nodes[q].

Ниже приведена реализация unionи connected:

    public void union(int p, int q) {
        int pNode = nodes[p];
        int qNode = nodes[q];
        for (int i = 0; i < nodes.length; i++) {
            if (nodes[i] == qNode) {
                nodes[i] = pNode;
            }
        }
    }
    public boolean connected(int p, int q) {
        return nodes[p] == nodes[q];
    }

Оценка сложности Quick-find

Очевидно, что поиск связи между элементами (операция connected) осуществляется за константное время: O(1).

Однако при объединении множеств нам придется пройти весь массив. В таком случае для Nэлементов операция union имеет линейную сложность: O(N).

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

Алгоритмы с квадратичной сложностью редко находят применение на практике. Уже при N = 109поиск решения занимает часы, а при N = 1012 — годы.

Представление в виде деревьев

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

В предыдущей реализации мы представляли каждый элемент в качестве индекса i в массиве, а его принадлежность конкретному множеству — в качестве значения по индексу nodes[i]. У такого подхода есть недостаток: необходимо проходить массив каждый раз при объединении множеств.

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

Структура данных определяется следующим образом:

  1. Каждый элемент представляется в виде индекса массива nodes[]длины N.
  2. Родитель элемента i — это nodes[i].
  3. Корень iнаходится последовательной индексацией элемента: nodes[nodes[...nodes[i]...]] (пока nodes[i] ≠ i).

Операция union выполняется следующим образом: nodes[root(q)] = root(p). Визуально это можно представить, как будто корень элемента qподвязывается к корню элемента p.

Представление связей в виде дерева

Код алгоритма прост и лаконичен. Ниже приведена реализация root, unionи connected.

    public void union(int p, int q) {
        int pRoot = root(p);
        int qRoot = root(q);
        nodes[qRoot] = pRoot;
    }
    public boolean connected(int p, int q) {
        return root(p) == root(q);
    }
    private int root(int p) {
        while (p != nodes[p]) {
            p = nodes[p];
        }
        return p;
    }

Оценка реализации Quick-union

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

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

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

Взвешенные деревья

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

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

Объединение деревьев с учетом их размера

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

Возможна ли ситуация, когда дерево с меньшим размером (количеством элементов) будет выше дерева с большим размером?

Оказывается, что при таком подходе высота самого высокого дерева будет не более log(N), или, другими словами, ранг любого узла дерева не превышает log(N). Рангом узла будем называть расстояние (число ребер) от данного узла до корня дерева.

Итак, введем новую эвристику:

  1. Структура данных такая же, как и в алгоритме Quick-union.
  2. Вводится дополнительный массив sz[]для подсчета количества элементов дерева с корнем i.

Код операций rootи connectedостается прежним, меняется только union:

    public void union(int p, int q) {
        int pRoot = root(p);
        int qRoot = root(q);
        if (pRoot == qRoot)
            return;
        if (sz[pRoot] < sz[qRoot]) {
            nodes[pRoot] = qRoot;
            sz[qRoot] += sz[pRoot];
        } else {
            nodes[qRoot] = pRoot;
            sz[pRoot] += sz[qRoot];
        }
    }

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

Доказательство сложности log(N)

Утверждение.Ранг любого узла x не превышает log(N), где N — количество узлов.

Доказательство.Рассмотрим, при каких условиях ранг x возрастает.

Ранг xпосле слияния увеличивается на 1

Слияние двух деревьев всегда происходит за счет подвязывания корня меньшего дерева к корню большего. Это означает, что ранг любого элемента x, принадлежащего дереву T1, после слияния с деревом T2всегда увеличивается на 1, при этом |T2| ≥ |T1|. В результате слияния получим дерево с мощностью |T2| + |T1|.

В крайнем случае, когда |T2| = |T1|, мощность результирующего дерева после слияния увеличится вдвое. Другими словами, ранг xувеличивается на 1, когда количество элементов дерева растет не более чем вдвое. А это значит, что ранг x не превышает log(N).

Сжатие путей

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

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

Сжатие путей

Код connectedи unionостается прежним. В реализации root мы добавляем всего одну строчку.

    private int root(int p) {
        while (p != nodes[p]) {
            nodes[p] = nodes[nodes[p]];
            p = nodes[p];
        }
        return p;
    }

Обратите внимание на строчку 3: мы поднимаем узел на уровень выше на каждой итерации цикла.

Финальная оценка сложности

Сложность операции unionпосле применения сжатия путей ограничивается функцией итерированного логарифма — O(log*(N)).

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

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

nlog*(n)
(—∞, 1]0
(1, 2]1
(2, 4]2
(4, 16]3
(16, 65536]4
(65536, 265536]5

Это означает, что для объема данных, встречающегося на практике, операция unionвыполняется за константное время, и это было достигнуто всего одной строчкой кода!

Подытожим сложности всех операций для каждого алгоритма:

initializationunionconnected
Quick-findNN1
Quick-unionNNN
Weighted QUNlog(N)log(N)
Weighted QU + path compressionNlog*(N)log*(N)

Применение

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

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

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

Сколько надо добавить медных опилок в ящик с песком, чтобы смесь начала проводить ток?

Смоделируем задачу в 2D для простоты вычислений и реализации:

  1. Представим материал в виде решетки N на N.
  2. Каждая ячейка может быть открыта с вероятностью pили закрыта с вероятностью 1 − p. Ток, соответственно, может проходить только через открытые ячейки.
  3. Протекание возникает тогда и только тогда, когда верх и низ решетки соединены открытыми ячейками.

Закрытые ячейки помечены черным цветом, открытые — белым, ток — синим

Обозначим открытую ячейку s0, а закрытую — s3. Тогда соотношение открытых ячеек к закрытым и есть вероятность p = s0 / s3.

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

Очевидно, что при p = 1ток будет протекать с вероятностью 100%, а при p = 0 — не будет. Однако нам необходимо определить более точное значение p, при котором решетка начинает проводить ток.

Самое интересное, что данная задача не решается математически. Определить приблизительное значение p, при котором ток будет просачиваться с вероятностью p* > 1/2, можно лишь эмпирическим путем.

Число pтакже называют порогом протекания, минимальной концентрацией элементов перколяционного кластера (в нашем случае — s0), при которой возникает протекание.

При каком pрешетка начнет проводить ток

На рисунке показано, что вероятности p = 0,4недостаточно для возникновения перколяции, а при p = 0,7можно уверенно сказать, что ток будет протекать через решетку. Сомнения возникают при p = 0,6, когда не всегда можно дать положительный ответ.

Реализация Percolation

Рассмотрим, как можно представить нашу задачу в виде системы непересекающихся множеств:

  1. Решетку N на N можно представить в виде массива размерности .
  2. Обозначим закрытую ячейку как 0, а открытую — 1. Изначально все ячейки закрыты.
  3. Последовательно открываем случайные ячейки.
  4. Если соседняя ячейка (сверху, снизу, справа или слева) также открыта, выполняем операцию union с каждой из них.
  5. Повторяем шаги 3–4,пока любая верхняя ячейка не будет связана с любой нижней. Проверка осуществляется с помощью знакомой нам операции connected.

Представление решетки N на N в виде массива элементов

Как видите, алгоритм предельно прост, однако шаг 5-йдостаточно ресурсоемкий. Нам придется выполнять connectedпоследовательно для каждой верхней ячейки с каждой нижней, то есть сложность этих вычислений составит O(N²).

Чтобы упростить последний шаг, можно пойти на небольшую хитрость. Мы введем 2 виртуальных элемента, pTopи pBottom, и свяжем их с верхней и нижней строкой соответственно. Тогда на 5-мшаге мы будем просто проверять connected(pTop, pBottom).

Виртуальные элементы pTopи pBottom

Вычисление порога протекания

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

Традиционно для изучения случайных процессов воспользуемся методом Монте-Карло:

  1. Инициализируем решетку N на N закрытыми ячейками.
  2. Выбираем случайную ячейку и открываем ее.
  3. Повторяем шаг 2-й,пока решетка не будет в состоянии перколяции.
  4. Вычисляем порог протекания как отношение открытых ячеек к закрытым: p = s3 / s0.
  5. Повторяем шаги 1–4-й T раз.

Точность результата зависит от размера решетки Nи количества экспериментов T. В конце значения порогов усредняются и вычисляется среднеквадратичное отклонение. Пусть, xt — значение порога протекания в эксперименте t, тогда среднее значение xи среднеквадратичное отклонение определяются так:

В результате получаем заветное число — 0,593. Это означает, что концентрация медных опилок в ящике с песком должна превышать 50%, чтобы смесь была токопроводящей.

График вероятности перколяции

Выводы

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

Верхняя граница сложности O(f(N))отвечает на вопрос, с какой скоростью растет число операций алгоритма при увеличении N. То есть, к примеру, если мы удвоим количество элементов в алгоритме Quick-find, то объем работы для операции unionтакже удвоится.

Позднее мы доказали, что сложность unionможно свести к O(log*(N)), а это означает, что при любых объемах данных, применяемых на практике, операция unionбудет выполняться одинаковое время.

Безусловно, для важных научных исследований можно воспользоваться мощностью суперкомпьютера, производительность которого измеряется экзафлопсами (1012). Однако, если посчитать, это всего на 6 порядков выше производительности домашнего ПК (1018). Когда мы имеем дело с алгоритмом квадратичной сложности, суперкомпьютер обеспечит прирост объема входных данных всего в 1000 раз, чего может быть недостаточно для решения поставленной задачи за допустимое время.

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

Благодарность

Выражаю благодарность профессору Принстонского университета Роберту Седжвику и доктору технических наук Кевину Уэйну за составление исчерпывающего курсапо алгоритмам «Algorithms, Part I, II» на сайте coursera.org. Также в свободном доступе можно найти их книгу Algorithms, 4th Edition.

Источники

  1. Sedgewick, Robert; Wayne, Kevin (2011). Algorithms. 4th ed. Addison-Wesley Professional. ISBN 978-0-321-57351-3.
  2. Sedgewick, Robert (2012). Union Find. Coursera.
  3. Disjoint-set data structure (2019) in Wikipedia: The Free Encyclopedia, Wikimedia Foundation Inc.

Станут ли микросервисы архитектурой будущего

$
0
0

Меня зовут Михаил Бродский, я Lead Software Engineer, Consultant в GlobalLogic (Харьков). В сфере IT уже более 7 лет. Занимался проектированием, разработкой информационных систем и их внедрением. Сейчас возглавляю проект, связанный с сетевой безопасностью. Занимаюсь повышением эффективности процесса разработки с помощью виртуализации, разработкой и анализом архитектурных решений, а также реализацией программной функциональности.

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

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

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

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

Микросервисы

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

Высокоуровневая схема микросервисной архитектуры

Почему мы использовали именно микросервисы?

В первую очередь из-за повышения скорости работы модели. При разделении монолитной системы на независимые элементы такую систему становится легче разрабатывать, ее можно «расскейлить», распараллелить: несколько команд смогут работать над разными микросервисами, при этом каждый микросервис будет иметь свой pipeline, continuous integration, continuous delivery. Таким образом, скорость работы системы повышается.

Безопасность и стабильность. После распределения модели на несколько микросервисов появляются некоторые дополнительные возможности. Например, представим себе скоростной суперкар. Что произойдет, если мы не будем контролировать его скорость? Он разобьется. Если мы имеем дело с «умной» машиной, ее датчики и контроллеры помогут нам отследить скорость, контролировать ее, управлять транспортным средством. Это позволяет повысить безопасность работы.

Это же относится и к работе с микросервисами: мы можем применять некоторые паттерны стабильности. Например, паттерн Timeout: если один из микросервисов не отвечает, мы можем быстро отключиться по тайм-ауту, показав пользователю, что этот сервис недоступен. Можно также применить паттерн Circuit Breaker («Предохранитель») — здесь уместна аналогия с домашней сетью электроприборов: при резком скачке напряжения барьер, контролирующий сетевое напряжение, отключает систему на некоторое время и после тайм-аута проверяет, вернулось ли напряжение в норму, можем ли мы подключить устройства к сети. Если нет, после определенного периода покоя проверка выполняется снова. Также возможно применение паттерна переборок. При распределении монолита между несколькими микросервисами становится возможным независимое применение таких паттернов.

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

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

Три основные группы микросервисов

Существует три основные группы микросервисов:

  • Stateless — сервисы без сохранения состояния.
  • Persistence — сервисы, которые сохраняют свое состояние.
  • Aggregators — агрегаторы.

Stateless

Такие микросервисы не имеют никакой зависимости от storage (cache и прочее) и определяют очень простые действия. Пример — конвертация из одной валюты в другую. Очень быстрое действие, нет зависимости от других сервисов и от дискового пространства. Их легко заменить и легко масштабировать.

Persistence

Другой тип микросервисов — сохраняющие свое состояние. К ним относятся сервисы, которые сохраняют зависимость от storage, у них есть операции записи/чтения, их точно так же легко масштабировать, если есть зависимость от диска, если разделены операции, применив паттерн CQRS. В двух словах: у нас есть запрос на чтение и запрос на запись. Мы можем распределить эти модели — за каждую модель будет отвечать определенный микросервис. Таким образом, мы можем масштабировать такую модель на независимые микросервисы. В первую очередь при этом мы зависим от других сервисов. Если взять Amazon или Netflix, один сервис вызывает огромное количество других сервисов. Кроме зависимости от других сервисов, есть зависимость от сети. Появляется запись в базу данных и, конечно же, Disk I/O Dependence.

Aggregators

Рассмотрим пример архитектуры, которую мы применяли для реализации группы паттерна микросервиса «Агрегатор».

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

Изначально наша архитектура выглядела так:

Микросервис-агрегатор с блокирующим (синхронным) запросом

Было устройство — брандмауэр, использовался микросервис, ответственный за сбор телеметрии (Device Data Collector MS), микросервис, ответственный за обработку полученной информации (Device Data Processor), а также микросервис, ответственный за генерацию уведомлений (Alert Generator).

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

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

Изначально мы должны были поддерживать 5000 устройств. Каждые 5 минут — не очень часто — каждое из этих устройств отправляло какую-то информацию о своей работе, и это составляло 17 запросов в секунду (тоже не очень много). За два часа работы собиралось 35 мегабайт, эту информацию мы сохраняли в базу данных, хранили ее 2 часа, и, если что-то произошло, запускалось задание, анализировалась информация, вызывался следующий микросервис, генерирующий уведомление, которое отображалось на доске уведомлений.

Все было отлично, пока не поменялись требования. Вместо 5000 устройств от нас потребовалось подключение 50 000. И тут мы поняли, что возникнут проблемы. Собрали все метрики, проанализировали информацию — проблема заключалась в том, что устройство блокировалось на время обработки всей цепочки сообщения. Как можно было решить эту проблему?

Микросервис-агрегатор с асинхронным ответом

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

И тут возникает несколько вопросов.

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

  • Заблокировать отправителя до того момента, пока не будет обработано сообщение.
  • Блокировать очередь либо при увеличении сохранять ее часть на жесткий диск.
  • Применить метод контролирования обратного потока (используется в TCP-протоколе): создается буфер складирования сообщений, при переполнении которого поступление сообщений блокируется.

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

Третий.Что произойдет, если Device Data Processor не сможет выбирать сообщения (как мы описывали ранее)? А что, если устройству будет необходим результат обработки сообщения?

Один из вариантов решения: устройство отправило сообщение с ID, сообщение было обработано, и микросервис создает вторую очередь для ответа, о существовании которой будет «знать» только это устройство. Когда будет обработано сообщение из второй очереди (ответ), эта очередь будет удалена.

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

Системы обработки сообщений

Рассмотрим основные понятия.

Message

Первое — сообщение. Можно провести аналогию: HTTP-запрос.

Message Broker & Message Queue

«Посредники» — брокер сообщений или очередь. К ним относятся TIBCO Enterprise Message Service, WebSphere, webMethods, RabbitMQ, ActiveMQ, HornetQ, NATS, Apache Kafka. Это нечто среднее между RPS и реляционной базой данных. Другими словами, это базы данных, адаптированные исключительно для работы с очередью.
Приведу несколько различий между этими двумя подходами.

Direct Communication

TCP, one-to-one

Один продюсер и один подписчик. Пример — TCP-протокол. Используется обработка контроля обратного потока. Посредник не используется. Если сообщение вдруг не было обработано, мы можем переслать пакет еще раз и обработать его.

UDP, ZeroMQ (over TCP), Webhooks (HTTP Callbacks)

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

Message Brokers

JMS, AMQP, RabbitMQ, ActiveMQ, HornetQ, Qpid, TIBCO Enterprise Message Service, IBM MQ, Azure Service Bus, Google Cloud Pub/Sub, SQS — их особенность в том, что при необходимости сообщить подписчику о нештатной ситуации (например, сообщение не было обработано, доставлено) используются посредники. Далее я расскажу, чем отличается Kafka от остальных существующих подходов.

Logs-Based Message Brokers

Посредники, работающие на основании логов.

HTTP Callbacks with Payload

Схема паттерна HTTP Callbacks with Payload

Этот метод объединяет посредника (Hub), подписчика (Subscriber), создающего сообщение, и издателя (Publisher). Например, подписчик заявляет, что хочет получать новости от определенного сервиса, и запрашивает ссылку на посредника (Hub): отправляет запрос, получает ссылку, отправляет подзапрос посреднику, происходит валидация подписчика. После этого, когда создаются дополнительные новости, посылается запрос на Hub о появлении новой информации, и посредник идентифицирует нового подписчика. Это стандартный паттерн — вы можете применить его, если нет необходимости использовать какого-то определенного посредника (например, Kafka).

Logs-Based Message Storage

Рассмотрим системы отправки сообщений на основании логов. К ним относятся Kafka, Distribute Logs от Twitter и реализация от Azure.

Схема работы систем сообщений на основе логов

У нас есть несколько очередей, несколько топиков, несколько разделов (Partitions). Есть продюсеры, которые создают сообщения и сохраняют их в очереди. Какую проблему решает этот подход?

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

Итак, у нас имеются очереди, добавляются продюсеры и потребители (Consumers). Когда какой-то из потребителей считывает сообщение, присваивается сдвиг (Offset): сколько сообщений было прочитано и какое сообщение было прочитано. Допустим, если мы прочитали определенное количество сообщений в разделе 0, мы записываем, чему равен сдвиг для этого раздела (например, 6):

Offset for P0 = 6

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

Объем релиза

В теории графов существует интересная формула, которая подсчитывает оптимальное число изменений в релизе: n — количество изменений (количество ребер в графе; соединения между ребрами — это изменения, зависимости) (рисунок 6). Политика Netflix — минимизировать число изменений, повысив частоту релизов. Если вы включаете в релиз большое число изменений, растет число дефектов, которые необходимо будет обнаружить и исправить. Например, при числе изменений n = 5 мы получаем 10 зависимостей. Минимизируя число изменений, мы уменьшаем число дефектов в системе.

Расчет оптимального релиз-скоупа

Выводы

В итоге на базе микросервисов мы создали асинхронный компонент, основная задача которого — сбор телеметрии от IoT-девайсов и создание необходимых оповещений (алертов) для уведомления пользователя. Каждые 2 часа мы получаем и сохраняем до 400 мегабайт информации.

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

  • получили практику предварительной оценки и разработки прототипов микросервисов;
  • с нуля создали асинхронный компонент, который позволил оптимизировать работу всей системы для большего количества подключенных устройств (до 50 000 устройств в одном регионе).
Что дальше? Мы смотрим в будущее с оптимизмом: переход от монолитной системы к микросервисам не только даст бизнесу и пользователям лучший user experience, но и позволит создавать целый набор различных сервисов, которые облегчат работу и жизнь.

Сейчас перед нами стоит задача поддержки и развития этого компонента, впереди еще много работы!

Хотите узнать больше или есть вопросы? Пишите в комментарии, в LinkedInи подписывайтесь на YouTube-канал.

Як у SoftServe втілили концепцію Mixed Reality, у якій віртуальні об’єкти можна відчути на дотик

$
0
0

У рубриці DOU Labsми запрошуємо IT-компанї ділитись досвідом власних цікавих розробок та внутрішніх технологічних ініціатив.

Привіт, я Тед Романус, Research Engineer у SoftServe в напрямку Human-сomputer interactions (HCI). Наша група в R&D працює над новими технологіями, що змінюють взаємодію людини з цифровими медіа — від віртуальної (Virtual) і доданої (Augmented) реальності до ефектів дотику (Haptics) та взаємодії через мову тіла й емоції (Affective computing).

Сьогодні я розповім про наш проект Touch My Heart — першу у світі голограму, якої можна торкнутися, яку можна штовхнути і яка передає такі легкі модуляції як серцебиття людини. Це демо, яке ми вже презентували на кількох найбільших HCI-конференціях у Великій Британії, США, Японії, Іспанії та Китаї, відкриває нові можливості природнішої й інтимнішої взаємодії з віртуальними об’єктами та дозволяє вже тепер почуватися героєм Blade Runner.

Виставка IoT World Expo 2018 в Барселоні

У цьому проекті ми поєднали:

  • AR-голограму, яку можна побачити через окуляри Magic Leap;
  • ефект дотику через ультразвукові хвилі (Ultrahaptics);
  • трекінг рук сенсором Leap Motion;
  • біосенсори.

Як наслідок, ми зреалізували концепцію Mixed Reality, у якій віртуальні об’єкти зливаються з реальним світом.

Ідея

Усе почалося з нашого знайомства з технологією Ultrahaptics, яка передає ультразвуковий імпульс у певну точку простору, що створює відчуття, схоже на фізичний дотик. Микола Максименко, R&D Director у SoftServe, давно знайомий з Орестісом Георгіу, Research Director в Ultrahaptics, і кілька разів запрошував його в Україну на конференцію IT Weekend Ukraine та виступити в Українському католицькому університеті. Орестіс Георгіу погодився на наше запрошення.

Під час спілкування в нас виникло багато спільних ідей. Тому невдовзі, 2018 року, SoftServe уклав партнерство з Ultrahaptics. Так ми отримали нову версію девайсу за півроку до офіційного релізу.

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

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

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

Робота над проектом

Спочатку розробляв проект (писав код, тестував) під окуляри Meta я, консультуючись з іншими R&D-фахівцями. У схожих дослідницьких проектах немає чіткого розуміння, чи вийде зреалізувати задумане, тож ми поступово розв’язували окремі технічні проблеми й розширювали кейс.

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

Спочатку ми мали зрозуміти, як саме відтворити дотик — які точки на руках стимулювати, яким чином, з якою інтенсивністю й з якою частотою. Моє початкове завдання полягало в тому, щоб дуже швидко (у межах кількох тижнів) зробити прототип і показати, у якому напрямку ми рухаємося та чи має це сенс. Це стандартний ресерч-процес у R&D. Коли це вдалося, можна було рухатися далі.

У комплекті з пристроєм Ultrahaptics іде SDK для розробки під Windows/Mac. Використовуючи його, ми змогли вивести анімацію серця на екран комп’ютера й створити відчуття дотику в просторі, тобто людина могла фізично відчувати те, що бачить на екрані комп’ютера.

Ми пішли далі й додатково використали окуляри Magic Leap, до яких розробили віртуальну модель серця (таку саму, яка відображається на екрані комп’ютера). Щоб користувач міг бачити серце через Magic Leap і одночасно торкатися його через ультразвукові хвилі, згенеровані Ultrahaptics, треба було поєднати системи координат цих двох пристроїв.
Це вже був значний крок уперед у використанні технології Haptic Feedback — доповнену реальність тепер можна було відчути фізично.

Ми вирішили не зупинятися й поставили собі наступну мету — зробити так, щоб серце здавалося живим. Для цього треба було створити коливання інтенсивності імпульсів, що передаються на шкіру. За основу взяли STM_Circle (один зі скриптів, які йдуть разом з Ultrahaptics SDK). Саме відчуття складається з точок, які бігають по колу радіусом 3 см з частотою 100 Гц (зважаючи на затримку опрацювання сигналів людським мозком, воно сприймається як ціле коло). Щоб одержати відчуття серцебиття на базі цього статичного відчуття, ми запропонували два підходи:

  • зміну інтенсивності імпульсу відповідно до нормалізованої сили даних про серцебиття, яку отримують з годинників Apple Watch чи MAWI;
  • зміну радіуса кола синхронно зі серцебиттям.

Насамкінець для яскравішої демонстрації ми взяли не якісь статичні дані, а відтворили ритм серцебиття реальної людини. Для цього я використав Apple Watch, підходить також годинник українського бренду MAWI, який дозволяє не лише міряти пульс (PPG), а й знімати кардіограму (ECG). Дослідженняпоказують, що Apple Watch вимірює пульс найточніше з усіх доступних на ринку фітнес-трекерів. MAWI практично міряє кардіограму, у якій значно більше даних, ніж у PPG (дослідження). Використовуючи такий метод, пульс визначаємо якнайточніше (саме з цим методом порівнюють усі інші).

Схема застосунку

Розробку вели в середовищі Unity, оскільки я маю найбільше досвіду роботи з ним і в ньому можна швидко прототипувати. А коли PoC було готове, вирішили не переписувати на інші платформи, а продовжити з Unity. Під час роботи використовували такі бібліотеки:

  • OpenCV вибрали саме тому, що на всіх нових платформах популярні image tracking фреймворки не мають імплементації, і ми не маємо доступу до параметрів камер. А в OpenCV є методи, з якими можна провести 3D-реконструкцію (тобто розпізнати прості патерни в 3D) на будь-яких камерах. Недавно в Magic Leap SDK додали свою імплементацію розпізнавання зображень, і ми переписали все на неї.
  • Ultrahaptics plugin, Leap motion plugin, Lumin SDK для інтеграції окулярів Magic Leap в Unity3D — потрібні речі для роботи, які не мають аналогів.
  • http-сервер для передачі даних про серцебиття — простий і кросплатформний спосіб для передачі інформації.

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

Ми поділилися результатом з Орестісом і виявилося, що таких рішень у світі ще немає, окрім відеоконцепту Ultrahaptics і дизайн-студії Nike. Тож уже разом з Ultrahaptics ми написали кілька матеріалів для конференцій з human-computer interaction.

З технічного погляду цей проект — насправді 3 окремі програми (для ноутбука, для Magic Leap, для Apple Watch), які треба запустити й протестувати. Бібліотеки, які ми використовували, мали досить скромну документацію, на StackOverflow узагалі порожньо (останнім часом для Magic Leap ця ситуація виправилася, для Ultrahaptics досі нічого загуглити не вийде). Щоб правильно засинкати всі системи координат, перетворення тощо, треба було ще розібратись у лінійній алгебрі й математиці 3D-перетворень, що теж забрало багато часу.

Перспективи

Перші версії демо Touch My Heart ми показували на маркетингових стендах, щоб побачити реакцію людей і, відповідно, удосконалити проект. Люди дуже емоційно реагують на такий новий спосіб взаємодії, найчастіше, це емоції захоплення й здивування. Цього року ми презентували його на кількох спеціалізованих міжнародних конференціях з Human-Computer Interaction, зокрема на CHI2019 у Ґлазґо й World Haptics Conference в Токіо, де дістали позитивний фідбек щодо новизни нашої ідеї та реалізації. Зокрема, наше демо в Японії помітив навіть засновник Magic Leap Роні Абовіц, а на Augmented World Expo ми потрапили до фіналу Auggie Awards в номінації Best Interactive Software.

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

Загалом ця технологія має потенціал для практичного застосування в таких напрямках:

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

Путешествие на планету Java. Мой опыт прохождения cертификации Java 11 Developer (часть 2)

$
0
0

Меня зовут Евгений Бережной, я — Java Developer в AB Soft, и речь в этой статье пойдёт о втором экзамене Java 11 Programmer II (1Z0-816). О первом экзамене и в целом о Professional: Java 11 Developer certificationчитайте первую часть. Второй экзамен существенно отличается от первого, но хочу вас порадовать: как по мне, в лучшую сторону.

Во-первых, экзаменаторы больше не пытаются подловить вас на невнимательности. Вы либо знаете, как работает код, либо нет.

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

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

Иллюстрации: Дмитрий Яценко

Чтобы получить сертификат, нужно сдать оба экзамена. К сдаче Java 11 Programmer II (1Z0-816) я советую подходить после сдачи Java 11 Programmer I (1Z0-815), хотя экзаменаторы этого не требуют и сдавать экзамены можно в любом порядке.

Если вы являетесь обладателем титула OCP 6...8, то вам надо сдать только один экзамен — Upgrade OCP Java 6, 7 & 8 to Java SE 11 Developer 1Z0-817, который очень похож на Java 11 Programmer II (1Z0-816) по затронутым в нем темам, поэтому информация вам тоже будет полезна.

Кстати, конкретно по этому экзамену коллега из дружественной Беларуси написал очень неплохой Study Guide.

Если же вы являетесь обладателем титула OCA 7, 8 то сдавать экзамен Java 11 Programmer I (1Z0-815) вам не надо, можете сразу покорять Java 11 Programmer II (1Z0-816).

Хорошая новость: у вас есть право на одну бесплатную пересдачу каждого экзамена. Детальнее об этом можно прочесть тут.

Темы экзамена

Java 11 Programmer II (1Z0-816) основан на старом экзамене OCP 8 (1Z0-809), список тем и сравнительная таблица приведены здесь.

Для подготовки я советую использовать книгу «OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide: Exam 1Z0-809» Boyarksy/Selikoffлибо «OCP Java SE 8 Programmer II Exam Guide (Exam 1Z0-809)» Sierra/Bates, в них детально описаны темы, которые перекочевали из OCP 8. В этой же статье я подробно расскажу о новшествах Java 9...11 и темах, которых раньше не было на экзамене.

Прошу обратить внимание, что некоторые темы из книг не будут подниматься на экзамене, но все равно пригодятся в повседневной работе. К примеру, вопросов по Fork/Join Framework и паттернам проектирования на экзамене уже нет.

Итак, начнем наш обзор новинок :)

Модульность

Модули — наше все! Разделяй и властвуй! Под этим девизом Oracle усиленно продвигает нововведение. Вопросов о модулях будет порядка 10, и, в отличие от первой части, эти вопросы будут практического характера.

Вас спросят, правильно ли написан module-info.java, включая корректное использование Service Provider Interface (SPI), который с появлением модульности обрел вторую жизнь. Зададут вопрос, правильно ли сделаны импорты и экспорты, должен ли быть хоть один провайдер сервиса во время компиляции и выполнения, а также массу других вопросов, узнать ответы на которые вам поможет только практика.

Поэтому я рекомендую взять книгу Шилданачиная с десятого издания, где приведены емкие примеры с пояснениями (всего 25 страниц). Освоив их на практике, вы получите ответы на 90% вопросов о модульности. Но помните: главное — «запачкать свои руки», а не просто полистать книгу.

Если есть желание окунуться в модульность с головой, советую книгу «Java 9 Modularity Book». В ней есть отличные примеры практического использования и стратегии миграции.

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

Вопросов о jmodи jlinkна экзамене не было.

Сериализация и безопасность

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

  • что надо сделать в коде, чтобы он считался безопасным;
  • когда нужно делать deep copy объекта для мутабельных классов;
  • когда надо делать copy constructor.
Кроме обязательного чтения нудных и сухих руководств Secure Coding Guidelinesи Chapters 1, 2, and 3 of Serialization Specification, рекомендую почитать горячо любимую мною «Effective Java»Джошуа Блоха. Там есть один раздел, посвященный сериализации, где рассматриваются вопросы безопасности.

Аннотации

Аннотация — одна из старых возможностей Java, которой раньше не было на экзамене, но без которой трудно представить современную разработку. На экзамене от вас потребуется знание базовых встроенных аннотаций, таких как @SuppressWarnings и @SafeVarargs, будут вопросы и по аннотациям @Repeatable.

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

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

JDBC

В разделе JDBC есть одна новая тема — использование CallableStatement. Мне вопросы по ней не попадались, но все остальные вопросы по JDBC были. Выше я советовал книги, где они хорошо описаны. О CallableStatement и их отличии от PreparedStatement можно почитать здесь.

Интерфейсы

Нововведение, о котором надо помнить: начиная с Java 9 методы в интерфейсах могут быть приватными. Приватные методы могут быть статическими и нестатическими. Методы не могут быть одновременно приватными и дефолтными. Эти методы используются в дефолтных и статических методах самого интерфейса, т. е. они введены как вспомогательные методы, позволяющие переиспользовать код, общий для других методов внутри интерфейса.

Эти методы подчиняются правилам, аналогичным для приватных методов класса:

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

Темы, перекочевавшие из OCP 8, и в целом о подготовке

Выберите одну из книг: Boyarksy/Selikoffлибо Sierra/Bates. Переключаться между ними не стоит. Возьмите себе за правило каждую неделю читать главу и проходить один мок-экзамен в конце главы. В результате через 2 с половиной месяца вы будете готовы по перекочевавшим из OCP 8 темам (IO, NIO 2.0, Concurrency и т. д.). Подготовиться по новым темам вам помогут советы из этой статьи.

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

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

Особое внимание стоит уделить Stream API и лямбдам. На экзамене их будет очень много. Выучите наизусть методы, аргументы и возвращаемые значения базовых функциональных интерфейсов (Consumer, Supplier, Function, Predicate, UnaryOperator). Обязательно нужно понимать, как получаются производные интерфейсы. Также вы должны знать, как написать собственный функциональный интерфейс.

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

public class TestClass{
    public static int operate(IntUnaryOperator iuo){
        return iuo.applyAsInt(5);
    }
    public static void main(String[] args) {  
        IntFunction<IntUnaryOperator> fo = a->b->a-b; 
        int x = operate(fo.apply(20)); //2
        System.out.println(x);
    }
}

Первое, что пугает и бросается в глаза, — это выражение a->b->a-b, но недоумение немного поутихнет, если переписать фрагмент в таком виде: a->(b->a-b).

IntFunction — это функциональный интерфейс, который получает intи возвращает то, к чему он типизирован. В данном случае он приведен к IntUnaryOperator. Следовательно, IntFunction<IntUnaryOperator>принимает intи возвращает IntUnaryOperator.

Теперь, если вы посмотрите на fo = a->b->a-b, то увидите, что a — это аргумент типа int (т. к. он используется, чтобы получить IntFunction), а b->a-bформируют тело метода этого IntFunction, которое вернет IntUnaryOperator.

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

То есть, когда вы вызываете fo.apply(20), вы устанавливаете a=20. Отсюда b->a-bвозвращает как IntUnaryFunction iuoравной b->20-b.

Затем вы вызываете iuo.applyAsInt(5), в которой значение bустанавливается равным 5, и в результате возвращается 20-5, т. е. 15.

Со стримами также очень много громоздких конструкций. Хорошо разберитесь с использованием методов groupingByи particioningBy, merge. Попрактикуйтесь, научитесь пользоваться ссылками на метод.

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

Если после выполнения всех рекомендаций у вас останутся сомнения в собственных силах, попробуйте мок-тесты Enthuware, посмотрите форум о сертификации на CodeRanch.

Итог

Как я ранее писал, экзамен длится 3 часа. Всего 80 вопросов, времени вполне хватает. Проходной балл — 63%.

Результаты экзамена придут в течение 15 минут на вашу почту.

В случае успешной сдачи (в которой не стоит сомневаться, если вы подготовились) через 48 часов появится возможность скачать с OracleCertViewсертификат и получить электронный бейдж, проверенный с использованием блокчейна (удивительно, как сюда AI еще не подкрутили :)

Электронный бейдж

При желании можно заказать бумажную копию, которая придет через 2-3недели по почте. Лично я не стал убивать еще одно дерево, думаю, в современном мире это будет лишним.

Так выглядит сертификат

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

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

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

Да пребудет с вами сила! Удачи!

Security Sandwich: инструкция по приготовлению

$
0
0

Привет! Меня зовут Таня, и я все еще тестировщик. За то время, что мы с вами не виделись, я успела основать митап QA Amsterdam и дать интервью о том, как докатилась до такой жизни. А сегодня я хочу рассказать о Security Sandwich.

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

Что же представляет из себя классический бутерброд безопасности

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

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

Go-Live-стадия, включающая код ревью и тестирование на проникновение.

Начальная стадия: все хотят от чего-то защититься. Но от чего?

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

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

Но в целом, если кто-то получит доступ к нашим данным, то он получит все. Включая номера кредиток, имя и домашний адрес. И покупки, конечно же.

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

От кого. Враг может быть как внешним (взломщики всех мастей), так и внутренним (например, обиженный сотрудник).

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

Например, пару месяцев назад они отправляли e-mail в стиле «Привет! Сижу на совещании, не могу говорить, срочно пришли такую-то информацию. Рудольф». Отправлено с айфона.

Вроде бы ничего такого, вот только указанный Рудольф — это наш СЕО. Он в тот момент действительно сидел на совещании, и он действительно время от времени присылает с совещаний такие письма, используя свой айфон.

Когда мы выяснили вот это все, то решили определить стоимость провала: во сколько нам обойдется то, что мы «профакапим» то или иное действие. Обычно это оценивается с точки зрения вероятности, критичности и рисков.

Итак, что у нас должно быть результатом работы на первом этапе

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

Сценарий«А что, если?..»: что произойдет, если наши поставленные цели будут нарушены?

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

Разработка: когда же «происходит» безопасность

Традиционно путь к продакшену включает:

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

На этапе анализамы устанавливаем Definitions of Ready.

Для этого нам нужно:

  • проанализировать имеющиеся активы: что именно мы затронем изменениями, какие новые компоненты будут в этом затрагивании участвовать, насколько критично то, что у нас сейчас есть и как все это вместе повлияет на текущую ситуацию;
  • смоделировать угрозы. Эта часть самая интересная. Она базово включает в себя вопросы о том, как мы можем быть взломаны и что будет при этом задето. Но моделирование угроз само по себе — один из моих любимых этапов. Модели бывают простые и известные типа STRIDE, а есть прикольные и замысловатые типа Persona non Grata. Я очень хочу с этой темой выступить на следующем митапе, но перед этим потренироваться. Если вы хотите присоединиться и послушать про моделирование угроз, то приходите на вебинар 27 ноября, в 20.00 (по Киеву) . N. B. Материал будет читаться на английском языке!
  • предусмотреть действия при взломах. Смягчить? Перенаправить? Избежать? Или принять?
  • предусмотреть обратную связь. Как мы защищались? Как отвечали на взлом? Как восстанавливалась система? Какие у нас могли бы быть альтернативы?

И конечно, теперь у нас появляется новый долг — security debt, за ним теперь тоже надо тщательно следить.

На этапе разработкимы облегчаем себе жизнь с помощью автоматизации, а также:

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

Go-Live: знай свою систему!

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

  1. Визуализируем текущее состояние системы. Это всяческие метрики и статистика в реальном времени, по одному взгляду на которые можно сделать вывод, хорошо ли все идет. Например, у нас в компании в комнате каждой команды установлены большие мониторы (а у менеджеров их и вовсе по несколько штук), на которые выведены дашборды с метриками системы. В любой момент каждый член команды может достоверно сказать, все ли идет как надо. Для этого достаточно поднять голову и посмотреть на монитор на стене.
  2. Делаем структурированные и понятные логи. Хорошим тоном тут считается не засовывать логи в стринги, а логировать нормальные, индексируемые данные. В идеале система логирования должна быть легко инспектируемой и коррелировать со всей системой.
  3. Определяем нормальное и не очень поведение. Мы должны уметь быстро фиксировать, что что-то пошло не так, и иметь стандартную процедуру поведения в таких ситуациях. Например, у нас один раз «кое-что» случилось. Это «кое-что» быстро устранили, но нервов потрепали немало, потому что, во-первых, «кое-что» случилось около полуночи, а во-вторых, процедуры на случай «кое-что» не было. Поэтому действовали по наитию и достаточно хаотично. После устранения «кое-что» провели работу над ошибками и сделали строго определенный регламент поведения на случай повторения, который разослали всем работникам компании: кому звонить первому, кому второму, по каким телефонам, каких клиентов и каким образом информировать и так далее.
  4. Применяем методологию безопасности Shift Left. Эта (и схожая с ней Shift Right) методология набирает все больше популярности, и вот она доползла до безопасности. Суть ее проста: если мы представим процесс разработки как прямую с планированием в точке ноль и выпуском готового функционала в крайней правой точке, то Shift Left — это сдвиг влево. То есть начинаем делать что-то как можно раньше. Так теперь и с безопасностью: раньше начнешь — меньше потеряешь. Поэтому стоит следить за Security Debt, внедрять коллективную ответственность за дыры безопасности в коде и прочие приятные штуки.

В качестве заключения

Security Sandwich кажется простой и незамысловатой вещью, тем не менее в процессе постоянно что-то теряется.

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

Когда же убираем верхний слой хлебушка (планирование требований, учет соглашений и пр.), то все вроде бы работает. Но если съесть колбасу с сыром недостаточно быстро, они обветрятся и будет уже не тот кайф.

Ну а убрав середину (анализ, разработка, тестирование), получим не сэндвич, а вообще какое-то хлебное недоразумение.

Готовьте ваш Security Sandwich правильно.

И приятного аппетита!

DevOps дайджест #27: Docker Enterprise, Helm 3.0, ClusterAPI и дайте свой email

$
0
0

В выпуске: скандалы-интриги-расследования о Docker Enterprise, почему лучше не использовать очереди в PostgreSQL, как получить первый опыт работы с клаудами, почему у Gitlab скоро будет больше вакансий, как быстро запустить что угодно на Google Cloud Run, посмотреть доклад Envoy as TCP Proxy и много-много интересностей.

Docker Enterpsise теперь Mirantis

Что случилось с Docker Enterprise?

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

Mirantis Acquires Docker Enterprise Platform Business

Docker new direction

Docker’s Next Chapter: Advancing Developer Workflows for Modern Apps

В двух словах:

  • Mirantis купил Docker Enterprise, для того чтобы развивать свой Kubernetes-as-a-Service. Даже учитывая то, что треть компаний из Fortune 100 использовала Docker Enterprise, — он был не особо прибыльным.
  • Docker Inc. продала Docker Enterprise и сразу получила $35 Million инвестиций для рекапитализации и усиления своей финансовой позиции.
  • Docker’s Next Chapter: они сфокусируются на улучшении взаимодействия с программистами, будут строить новые процессы и улучшения в области сборки контейнеров, их дистрибуции и запуска.
  • У Docker Inc. теперь новый СЕО.

Мнения и интересности

Сказ о PostgreSQL и сложности инфраструктуры
Новая статья в блоге Всеволода Полякова о том, как не нужно решать инженерные задачи на примере «просто решения» с очередями в PostgreSQL. Какие проблемы после этого появляются? Можно ли использовать PostgreSQL как message queue? Ответы в статье.

Modern applications at AWS
CTO из Amazon делится своим подходом и виденьем о том, как делать приложения. Интересные моменты, которые я заметил: one DB per microservice и безопасность — it’s not SecOps job, it’s everyone’s job. В статье есть чему поучиться, рекомендую к прочтению.

Stop Bashing Bash — Pattern for Sharing Bash
Признавайтесь, что вы тоже пишете bash-скрипты. И да, их достаточно много, и большая часть из них — это ужас. Эта библиотека — попытка вынести общие проблемы всех bash developers в общую библиотеку. Сейчас пока что функций маловато: покрыт Git, Kubernetes, тестирование скриптов и еще по мелочи. Думаю, в будущем туда добавят побольше удобностей, и можно будет инклудить в каждую тулу. Обратите внимание на Bash Links в статье — там перечислены классные мануалы, на них опирались создатели библиотеки.

В Netflix по пятницам принято не деплоить

Deploy on Fridays, or Don’t.
Если вы деплоите по пятницам — почитайте. А если не деплоите — тоже почитайте. Мое мнение: деплой в пятницу — это норма. Автоматизированный, покрытый тестами, предсказуемый деплой. Обычный, который вы запускаете три раза каждый день, к которому вы привыкли. Деплой, который меняет схему самой большой таблички в БД, деплой с фичей, которая разрабатывалась параллельно с проектом пару месяцев, миграция стореджа или какие-то большие изменения — не норм. Потому что при таком подходе выходных не будет, результат — овертайм, выгорание, смена компании. Зачем?

How do you get cloud experience?
В основном работаете с bare metal и очень хочется пощупать Cloud? Или постоянно работаете с AWS, но очень интересно посмотреть, как оно там в Google Cloud или Azure? Вы не одни такие. В этой теме на Reddit автору дают советы о том, как получить этот самый опыт с Cloud. Конечно же, основной совет — бери и пробуй :) Но есть еще много советов, например: где можно взять Free Cloud credits, какие есть Education предложения у Cloud провайдеров.

GitLab hiring ban by Country
GitLab рассматривает вопрос о прекращении найма SRE и Support инженеров в России и Китае. Аргументируют обеспокоенностью некоторых Enterprise клиентов и геополитическим климатом. HackerNews сообщество отреагировалоочень по-разному. Если вы SRE из других стран — посмотрите вакансии Gitlab, думаю, в скорости их может стать больше.

The (real) 11 reasons I don’t hire you
Что делать с этими причинами: вывернуть наоборот, обработать и сделать так, чтобы наняли.

kube-proxy iptables «nat» control flow
Tim Hockinиз Google cделал шпаргалку по kube-proxy iptables nat таблице, когда kube-proxy работает в iptables режиме. Хардкор!

New from Universe 2019: GitHub
Недавно прошел Github Universe, на котором объявили о создании мобильного приложения, возможности архивации open-source проектов на 1000 лет (лол), секьюрити фичи. Больше можно прочитать здесь.

The SSO Wall of Shame: выбираем провайдера
Список сервисов и цены, за которые они продают SSO. Местами за базовую секьюрити фичу цены отличаются до 5 раз. И сюда же сразу небольшой гайд: An Illustrated Guide to OAuth and OpenID Connectот Okta с картинками, все как вы любите.

The importance of soft skills in IT

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

Видео с конференций

Devops Enterprise Summit 2019: Keynotes
Если вы не в Los Angeles, то это не беда — видео с местного Devops Enterprise Summit можно посмотреть на YouTube. По ссылке будет плейлист с Keynotes.

Monitorama 2019: видео с конференции
Опять же, если не удалось попасть в США на Monitorama — всегда можно посмотреть видео. По ссылке — плейлист и 17 докладов.

PromCon Munich 2019: онлайн трансляция
Два дня видео с PromCon в Munich. Очень радует этот месяц обильным количеством классных доступных конференций.

YAML Is Better than Your Favorite Language: Fightin’ words about Infrastructure as code
Видео о YAML: почему он лучше всех остальных DSL для IaC, по мнению автора, и как правильно готовить, чтобы не больно было.

Руководства и инструкции

Deploy Traefik as Ingress Controller
Туториал о том, как задеплоить Traefik в качестве ingress в DO Kubernetes кластере.

Serverless Go application in Google Cloud Run

Running a serverless Go web application in Google Cloud Run
Интересный туториал о том, как легче всего запустить serverless приложение. Автор показывает пример постой Go программы, упаковывает ее в Docker и запускает в Google Cloud Run. И действительно, выглядит очень быстро и просто.

ClusterAPI — A Guide on How to Get Started
ClusterAPI — это проект для Kubernetes, который призван объединить все варианты инсталляций Kubernetes в одном API и позволять управлять ими через один интерфейс. У нас в компании за эту штуку очень топит Саша Милушев, и даже есть вакансияв его команду. Если вы хотите в Pango — лучше напишите мне в личку, чтобы мне дали бонус. А в статье рассматриваются основы ClusterAPI.

Continuously enforce policies on your configs with Conftest and CircleCI
Если вы задумывались, как делать unit-тестирование ваших Kubernetes манифестов с помощью Open Policy Agent — статья будет полезной, новой и интересной. Если вы о таком задумывались, напишите, пожалуйста, в личку — вероятно, я бы взял интервью у такого человека.

Как мониторить Amazon MQ и какие метрики собирать в Amazon MQ
Две очень хорошие комплексные статьи о том, как правильно мониторить и какие метрики собирать в Amazon MQ. Datadog очень хорошо умеют делать качественные tutorials.

BLESSing away SSH worries
Netflix Bless — это SSH Certificate Authority, запущенный на AWS Lambda и его задача — подписывать SSH ключи в вашей компании. В целом это уже давно популярная практика — не переписывать authorized_keys, а настроить хост, чтобы он доверял вашей SSH CA. Резюмируя, если вы все еще патчите authorized_keys — перестаньте так делать и сделайте Netflix Bless по этому мануалу.

Обзор DevOpsStage 2019

DevOpsStage Kyiv 2019: какие доклады посмотреть

Посмотрите эти доклады сейчас, а если не сейчас, то на выходных (полезно и с пользой):

  1. Envoy as TCP proxy — конечно, это мой доклад, который я анонсировал немногим ранее. История о том, как мы решили проблему трафика между сервисами в небезопасном интернете, обзор решений + еще хайринг к нам в Pango :)
  2. Kubernetes Navigation Stories — интересно о Kubernetes в thredUP (большой онлайн-секонд с разработкой в Украине).
  3. Hacking Terraform for fun and profit — Антон Бабенко о Terraform, много хороших рекомендаций по этому докладу.
  4. Make Architects aligned with business needs — Дима Лавриненко о том, как стать архитектором (мы с ним выступали параллельно, и он в шутку порекомендовал мой трек :))
  5. Premature automatization — Сева Поляков о том, как не нужно делать автоматизацию. Я попал под конец доклада, и очень даже зашло.

Конференция HAProxyConf 2019 (Amsterdam)

12-13ноября в Амстердаме проходила HAProxyConf, где выступал один из наших соавторов. Было очень много интересных тем: GitHub, Booking.com, Vimeo делились опытом создания своих отказоустойчивых систем и какую роль в них играет HAProxy.

Анонсировали и рассказывали о HAProxy One — CDN + ADN + Firewall + WAF + красивый UI. Ребята хотят предоставлять клиентам All in One решение и потеснить... Судя по описанию фич выше, вы, думаю, сами поняли, кто конкуренты ;)

Забавный факт о докладах про Kubernetes: все production-решения пока используют HAProxy как Standalone solution, а на Ingress Controller только посматривают, пробуют.

К следующему дайджесту опубликуем ссылки на самые интересные доклады.

Наконец-то Helm 3.0

Helm 3.0.0 has been released!

И это большая, очень хорошая новость. Вот основные изменения:

  1. Removal of Tiller — его больше нет, и устанавливать его в кластер не нужно. Его функции распределили: рендерингом темплейтов занимается клиент, а релиз конфигурация и информация хранится в Kubernetes API. Tiller теперь просто не нужен.
  2. Improved Upgrade Strategy — теперь Helm понимает и видит больше изменений как в upgrade, так и в rollback. Покрыто много кейсов, в которых раньше было больно.
  3. Release Names — теперь можно делать релизы с одинаковым названием в разных неймспейсах.

Все DevOps-related идут на XP Days

XP Days Ukraine 2019 (22-23 ноября)

Я как раз вернусь с отдыха, чтобы послушать Ярослава Молочко с докладом Self-healing in prod do you really need AI for that?— уверен, будет пушка. По инсайдерской информации знаю, что будет реальный опыт, как очень просто развалить супер-хай-авейлбл-селф-хилинг Hashicorp Vault кластер в Kubernetes с Etcd бекендом (выглядит так, что это невозможно, а на самом деле — карточный домик).

И еще там будут такие известные личности как Paul Stack, Philipp Krenn, Vsevolod Poliakov, Igor Borodin, Dmytro Lavrinenko — очень хороший набор спикеров. И классное завершение осени таким звёздным составом!

Кстати, в телеграм канале ДевОпс инженересть промо на −10%, а сюда код попросили не выкладывать. Не знаю почему так, все равно кому нужно — перейдут в канал и без проблем найдут.

В этом выпуске также участвовали:

Дайте свой email

В общем, я подумал, что круто было бы сделать The DevOps Digest Monthly с email-рассылкой. Да, это прямо как DevOps Weekly, Monitoring Weekly, etc weekly, только monthly. Польза очевидна: вы точно не пропустите новый релиз Helm, не забудете обновить Grafana и абсолютно точно будете знать, что можно вкрутить Netflix Bless, и будет круто. И акцент на англоязычный сегмент. Суть — сделать worldwide дайджест, для всех DevOps Engineer’s in the whole world.

Сначала я думал сделать лендос для сбора email и вкрутить SendGrid. Прокрастинировал на этой идее пару недель и понял: нужно действовать по концепции Lean Startup.

Для этого я придумал сделать самую простую форму.

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


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

Viewing all 8439 articles
Browse latest View live