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

Як створити реєстр ризиків та працювати з ним

$
0
0

Усім привіт! Мене звуть Андрій, і я маю власний досвід з особистого та корпоративного консультування з проєктного й продуктного менеджменту. В ІТ-галузі майже 15 років, 10 з яких — у царині менеджменту. Свого часу працював як PM, PDM, Agile Coach, VP Delivery та СТО.

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

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

Що таке ризики

Далі йтиметься про ризики та імпедименти, імпедимент-беклоги і реєстри ризиків, тож коротко висвітлимо ці питання та встановимо межі.

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

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

Імпедимент-беклог

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

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

Відповідно, імпедимент-беклог — дуже спрощена форма роботи з поточними ризиками у скрамі.

Імпедимент-беклог можна зорганізувати різними способами:

  1. Стикерами на окремій дошці (працює для доволі рідкісного випадку, коли вся команда перебуває в одній кімнаті).
  2. Віртуальними стикерами на віртуальній дошці, як-от RealtimeBoard (для повністю розподілених команд).
  3. Окремим проєктом у трекері завдань. Наприклад, TFS Online, Jira дають змогу побудувати окрему канбан-дошку для скрам-майстра. Можна навіть додати окремий лінк для будь-якого члена команди, щоб він міг створити імпедимент на розгляд.
  4. Будь-який інший інструмент, що підтримує списки й уможливлює спільну роботу.

Приклад RealtimeBoard (image sorce)

Я зазвичай створював окрему канбан-дошку (переважно в Jira чи TFS), де були виписані всі ризики та імпедименти, з підзавданнями, що містили конкретні дії для послаблення впливу чи усунення ризиків, проблем і перешкод. Для ліпшої організації я встановлював на дошках WIP (Work in Progress) обмеження для фокуса й пріоритизації та окремий swimlane для ймовірних пожеж. У такий спосіб або прогнозуємо роботу в разі проактивної позиції на випередження, або цілковито фокусуємо увагу, коли потрібні реактивні дії.

Усі наведені підходи дуже схожі за принципом, але якщо ви вже користуєтеся якимось трекером завдань для роботи, то просто створіть окремий проєкт для імпедиментів. Список пріоритетних ризиків / проблем треба винести як окремий елемент на dashboard (а це вже класичний функціонал таких інструментів), який у вас перед очима щодня. Якщо ні, то фізична дошка чи віртуальний інструмент візуалізації — один з основних інструментів еджайлу.

Реєстр ризиків

Якщо є досвід у керуванні ризиками (а також час, що насправді досить важливо), то можна створити цілий реєстр ризиків. Так варто робити кожному менеджерові проєктів, коли щоденна робота охоплює трохи більше обов’язків і відповідальності, ніж у скрам-майстра. Це перехід від реактивного підходу в проактивний. Я зазвичай робив їх у Google Sheets чи Excel. Тут можна просто встановити всі потрібні атрибути ризиків.

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

  • назва ризику (до 60 символів);
  • опис ризику: для простоти роботи з реєстром його можна ховати, коли знаєш, про що йдеться, і відкривати, коли показуєш реєстр тим, хто з ним стикається значно рідше (твітер-статус — 140 символів чи для любителів — 280 символів);
  • сфера впливу: випадний елемент (time, scope, budget, quality, team satisfaction, customer satisfaction);
  • опис впливу: аналогічно до опису самого ризику;
  • імовірність: оцінкова ймовірність за шкалою 1...3, 1...5, 1...10;
  • вплив: ідеться про вплив ризику на проєкт (як і ймовірність вище);
  • значущість ризику: добуток і ймовірності на вплив;
  • статус ризику: можна легко відфільтрувати закриті ризики;
  • стратегія: стратегія реакції на ризик (mitigate, omit, transfer, accept) — ці реакції варті окремого допису чи навіть статті;
  • тип: позитивний чи негативний — ризик чи можливість;
  • дата створення;
  • дата закриття;
  • власник ризику: відповідальна особа в роботі з ризиком (так, це не завжди скрам-майстер чи менеджер);
  • коментарі: тут можна дати волю письму, не обмежуючись 140 символами. Я пишу сюди всі оновлення й новини, які отримую щодо ризику з датами.

Ці атрибути ризиків лише базові, список можна сміливо корегувати, додаючи чи змінюючи самі атрибути. Наприклад, коли я працював делівері-директором для одного спільного шведсько-українсько-шриланкійського продукту, то додав ще Stakeholder Group, бо в продукту були чотири партнерські компанії, які над ним працювали, і чітко треба було розуміти, на чиїй «частині поля м’яч». Оскільки всі компанії мали свої підписки на Google My Business, то все, очевидно, було зорганізовано в Google Spreadsheet. Крім Stakeholder Group, під час обговорення ризиків на дзвінках C-Levelмені також дуже допомагали умовне форматування з підсвіткою критичних ризиків, словесне пояснення впливу ризику й графа Notes з повною історією новин і роботи з ризику.

Я створив шаблоні користуюся, якщо немає ліпших інструментів для наявного набору.

Самописні інструменти

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

Свого часу я брав участь в ініціативній групі розробки рішення на основі розширеного фреймворку роботи з ризиками Adriano (сам фреймворк вартий окремої серії дописів) на основі Jira. Здається (але це не точно), нам удалося вийти на Atlassian Marketplace і навіть продати кілька прикладів цього рішення.

В одній компанії, з якою я недавно співпрацював, був свій Project Management Tool, який мав вбудовану систему керування ризиками. Список властивостей ризиків приблизно відповідає тому, який описувався в розділі про реєстр ризиків у таблиці. Але перевагою такого інструменту є, наприклад, те, що активні ризики потрапляють у щотижневі звіти про проєкт автоматично. Відповідно до критичності ризиків можна сказати про ступінь здоров’я проєкту кожної із частин: часу, обсягу роботи, задоволеності команди й клієнта та навіть кошторису. А після закінчення проєкту ризики аналізують під час Post Mortem, а висновки (Lessons Learned) потрапляють до спеціального репозиторію. Їх можна використовувати й під час старту інших проєктів. У такий спосіб виконується остання стадія керування ризиками, про яку часто забувають, якщо користуються простими інструментами на кшталт Spreadsheets.

Готові рішення

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

Risk Gap

У мене був досвід користуватись одним з готових інструментів Risk Gap. Ми послуговувалися ним під час навчального проєкту Expedition PM (про нього я теж колись напишу окрему статтю). Перевагами інструменту було те, що його легко налаштувати, він містив оцінки від 1...10 для ймовірностей і впливів ризиків (зі зручними підказками), давав змогу оцінювати ризики кількісно, якщо встановити вартість у часі, грошах чи обсягу певного ризику. Користувачі оцінювали ідентифіковані ризики незалежно одне від одного, а отже, оцінка ставала об’єктивнішою. Також можна було створювати завдання для уникнення чи зменшення ризику. Якщо треба «підняти систему з нуля», то я раджу цей інструмент.

Image Source

Інші готові рішення

Ось ще кілька інструментів для роботи з ризиками, про які мені розповідали PM-колеги:

Висновки

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

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


Estimates or Guesstimates? Обираємо метод оцінювання задач

$
0
0

Стаття написана у співавторстві з Віталієм Шквирою.

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

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

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

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

  • Story Points;
  • Man/Days або Man/Hours;
  • No Estimate.

Story Points

Почнемо з простого й сучасного тренду — оцінювання в Story Points. Це один з абстрактних типів оцінювання, який показує складність, обсяг і рівень невизначеності елементів беклогу один щодо одного й більше підходить для Agile-проєктів. Story Points зазвичай використовують, коли немає чітких дедлайнів та фіксованого бюджету на весь проєкт, а вимоги зафіксовано на високому рівні. Детальне оцінювання виконують лише для найближчих ітерацій, тоді як інші етапи можна оцінювати абстрактніше (наприклад методом T-Shirt Sizes).

Одним з обов’язкових принципів оцінювання є те, щоб кожен член команди мав однакове розуміння, чому дорівнює 1 story point.

Story point — це найменша абстрактна величина, яка виражає зусилля, потрібні для виконання поставленої задачі.

Параметри, які враховують під час оцінювання:

  • Обсяг роботи для виконання поставленої задачі — наскільки великою є user story й скільки часу займає реалізація.
  • Складність роботи — наскільки складною буде реалізація завдання.
  • Ризики й невизначеність під час виконання задачі — які змінні та невідомі фактори можуть вплинути на цю user story.
  • Знання — як багато команді відомо про цю задачу.

Обов’язково враховуйте кожен із цих параметрів, коли вимірюєте роботу в Story Points.

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

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

Ключовий момент Agile-підходу до оцінювання та планування полягає в тому, що ми оцінюємо розмір і на основі цих даних визначаємо час виконання. Припустимо, що ми оцінили всі User Stories і сума цих оцінок становить 100 Story Points. Це розрахунковий розмір системи. До прикладу, з минулого досвіду нам відомо, що швидкість команди становить 10 Story Points за ітерацію, і ми можемо припустити, що команда працюватиме з такою самою швидкістю й у цьому проєкті. Коли нам відомі розрахунковий розмір і швидкість команди, ми можемо визначити строк виконання 10 ітерацій. Відрахуємо 10 ітерацій у календарі й отримаємо календарний графік.

Розгляньмо переваги й недоліки цього методу оцінювання:

ПеревагиНедоліки
  • Добре поєднується з Agile-практиками.
  • Адаптивний. Точність зростає з кожною ітерацією.
  • Не вимагає багато часу.
  • Досвід і навички окремих людей не важливі для оцінювання й реалізації.
  • Дає змогу приблизно оцінити строки виконання (підходить для оцінювання дати релізу або окремої фази).
  • Немає потреби переглядати зроблені оцінки після зміни членів команди.
  • Розміри елементів беклогу зіставні між собою.
  • Сприяють крос-функціональній взаємодії в команді.
  • Вимагає уваги (команди нерідко завищують оцінку роботи в гонитві за продуктивністю).
  • Складність розуміння story point для команди (точність оцінювання знижується).
  • Залежить від історичних даних (низька точність на перших ітераціях).
  • Знижується точність оцінювання концептуально нових елементів беклогу.
  • Швидкість виконання задач (Velocity) залежить від знань і досвіду команди розробників. Будь-які зміни в складі команди впливатимуть на швидкість, а відповідно, і на оцінювання на цьому етапі.
  • Не дає змоги точно оцінити строки (не підходить для оцінювання ітерації — докладніше в статті Mike Cohn).

Техніки оцінювання

Man/Days або Man/Hours

На відміну від попереднього методу Man/Days або Man/Hours використовуємо для оцінювання, коли в нас є визначений беклог і ми знаємо всі деталі проєкту й обіцяємо клієнту виконання роботи за конкретний відрізок часу. Ми не можемо написати клієнту, що його завдання оцінять у стільки-то Story Points, бо це буде непрофесійно й незрозуміло. Натомість слід показати результат у днях і годинах, які можна легко перевести в гроші.

У софтверному проєкті ідеальний час для виконання певної задачі відрізняється від загального витраченого часу через природні непродуктивні витрати, як-от час, витрачений на електронні листи, консультації колег, мітинги тощо. Також враховуємо фокус-фактор: незаплановані вихідні й лікарняні, різні часові зони, розподілені локації (перелік можна продовжувати). Коли ми говоримо про ідеальний час, то повинні розуміти, що хороший інженер може ефективно працювати від 5 до 6 годин на день. У результаті, коли бачимо, що член команди оцінив свою задачу в 8 годин, ми розуміємо, що ефективно він працюватиме від 62 до 75% того часу. Відповідно, коли ми визначаємо Capacity Per Day, то задача, яку ми початково оцінили у 8 годин, прораховуємо фактично як 10,7 години. Якщо ж для оцінювання використовувати ідеальні дні, то треба враховувати лише час, витрачений безпосередньо на реалізацію проєкту.

Переваги й недоліки цього методу оцінювання:

ПеревагиНедоліки
  • Поширений і зрозумілий метод для команди та стейкхолдерів.
  • Нескладно прорахувати вартість роботи.
  • Простий у використанні.
  • Можливе (навіть бажане) використання досвіду інших проєктів (аналогове оцінювання).
  • Використовується для планування точних дат ітерацій, фази й релізу (якщо вимоги достатньо точні та докладні).
  • Дає можливість контролювати хід виконання робіт, аналізуючи відхилення від плану (Plan vs Fact / Burndown Chart).
  • Зручніший для роботи з ризиками.
  • Знижує рівень стресу, що, врешті, позитивно впливає на якість виконання (за моїми спостереженнями, приблизно 40% помилок під час розробки програмного забезпечення зумовлені стресом команди внаслідок відсутності належного планування).
  • Точні оцінювання підвищують довіру до команди.
  • Вимагає істотних часових затрат.
  • Необхідність декомпозиції задач — задачі, виконання яких займає більше ніж 4 години, оцінити важко.
  • Передбачає наявність чітких та детальних вимог, розуміння продукту, домену й архітектури.
  • Оцінювання конкретної задачі актуальне лише коли її оцінює виконавець (зміна виконавця вимагає переоцінювання задачі).
  • Людям властиво оцінювати за ідеальних умов (Sunny Day Scenario), що, врешті, занижує оцінку.
  • Вимагає високого рівня компетентності та навиків команди.
  • Ідеальні години можуть бути різними в кожного з членів команди.

Техніки оцінювання

  • Експертне оцінювання (Expert Judgement)
  • Методи оцінювання за трьома точками (Three Point Estimation)
  • Аналогове оцінювання (Analogous Estimation)
  • Оцінювання за параметрами й моделювання (Parametric Model)
  • Оцінювання від окремих елементів до загального оцінювання (Bottom-up Estimation)

No Estimate

До цього методу варто вдаватися, коли ви не бачите сенсу витрачати час на оцінювання. З точки зору Lean-практик, зусилля варто спрямовувати лише на ті активності, які приносять користь (Value) — замовнику або клієнту. Найчастіше такий підхід використовують команди, що займаються тільки підтримкою або підтримкою і розробкою нового функціонала одночасно. Ми не фокусуємося на визначенні дати виконання тієї чи іншої задачі, працюємо за принципом just in time: задача буде виконана настільки швидко, наскільки це можливо.

Усе ж підхід No Estimate — не зовсім про відсутність оцінювання проєкту як такого, а більше про мінімізацію витрат часу на оцінювання. Тут з’являються інші метрики для команди — Work in Progress (WIP) та Idle Time (час затримки на кожному етапі).

Тепер оцінимо плюси й мінуси цього підходу.

ПеревагиНедоліки
  • Суттєво зменшує/наближає до нуля час на оцінювання, який у середньому становить 40% від загального часу планування.
  • Передбачає однакові або схожі за розміром задачі, що дає змогу ефективно вимірювати продуктивність.
  • Ефективний за умов високої невизначеності й частих змін (Cycle Time < Time for changing requirements).
  • Використовується, коли пропускна спроможність команди задовольняє потреби клієнта.
  • Залежить від етапу проєкту. NoEstimates — це не лише про розробку без використання оцінювання загалом, а про те, щоб проводити оцінювання якомога швидше з кожним новим етапом проєкту.
  • Прогнозування вимагає наявності історичних даних і базується на кореляціях та припущеннях.
  • Імовірність серйозних змін через відсутність попереднього досвіду або детальних вимог.
  • Не підходить для проєктів з фіксованим Scope, Schedule або Budget.

Метод оцінювання — Forecasting Based on Lead and Cycle Time.

Порівняння методів оцінювання

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

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

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

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

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

  • 5 розробників;
  • 2 тестувальники;
  • 1 DevOps-інженер;
  • 1 проєктний менеджер.

Story Points

Проєкт

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

Умови

Можливість часто й безболісно вносити зміни до вимог і існуючого функціонала. Регулярна доставка випущеного функціонала (наприкінці кожної ітерації). Product Owner володіє довгостроковим баченням продукту на високому рівні й детальним на рівні короткострокового планування (1-3 ітерації).Запити на зміни й пріоритети надходять регулярно, як правило, наприкінці ітерації. Випуск інкременту в кінці кожної ітерації.

Метрики

  • Velocity — швидкість роботи команди.
  • Accuracy — точність оцінювання.

Переваги

  • Достатньо точний прогноз на найближчі 1-3 ітерації.
  • Орієнтовний прогноз на найближчий реліз або весь проєкт.
  • Відносна гнучкість внесення змін.

Man/Hours

Проєкт

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

Умови

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

Метрики

  • Cost Performance Index (CPI) — індекс виконання бюджету.
  • Schedule Performance Index (SPI) — індекс виконання графіка.
  • Variances — відхилення від бюджету або графіка.

Переваги

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

No Estimate

Проєкт

Систему запущено в продакшен. Обсяг роботи й бюджет зафіксовано на високому рівні, і жорстких обмежень немає. Проєкт ґрунтується на Roadmap’і продукту.

Умови

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

Метрики

  • Work In Progress (WIP) — кількість задач, які одночасно перебувають у роботі.
  • Idle Time — час простою.
  • Lead Time — період між появою нової задачі у воркфлоу і її закриттям.
  • Cycle Time — час між початком роботи і доставкою результату роботи споживачеві.
  • Throughput — кількість робочих задач, які команда може виконати в заданий період часу (тиждень, місяць тощо).

Переваги

  • У роботі лише актуальні й пріоритетні завдання (коротке планування відбувається щодня).
  • Заощадження часу планування, який інвестовано в роботу над задачами.
  • Користувачі отримують Value у вигляді оновлень, які регулярно доставляють.

Висновки й рекомендації

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

  • Проєкти з обмеженнями завжди вимагають оцінювання. Якщо обмеження жорсткі, оцінювання виконуйте в Man/Hours або Man/Days.
  • Для проєктів, які передбачають підтримку (тим більше з фіксованою угодою про SLA-рівень послуг), є сенс застосовувати No Estimate.
  • Завжди враховуйте ризики, складність завдань і ступінь невизначеності. Залучайте до оцінювання команду і стейкхолдерів.
  • Уточнюйте, що важливо для спонсора проєкту. Як правило, прозорість і прогнозованість переважають над вартістю й строками.
  • Приділяйте час процесам незалежно від підходу до оцінювання, який ви використовуєте. Неконтрольований процес оцінити неможливо.
  • Враховуйте всі види робіт, а не лише кодування й тестування.
  • Залучайте експертів до перевірки оцінювань і не занижуйте оцінку роботи розробників без аргументації :)

Як бонус пропоную список рекомендованої літератури:

Сподіваюся, стаття буде корисною для вас. Буду радий вашим коментарям і запитанням.


Головне зображення: Thinking Techniques

DOU Hobby: Ironman – соревнования по триатлону на 225,8 км

$
0
0

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

Артем Павлов — менеджер по продукту в компании «Ноосфера» в Днепре. Он уже 20 месяцев готовится к полной дистанции гонки Ironman по триатлону. Чтобы финишировать, нужно проплыть 3,8 км, проехать на велосипеде 180 км и пробежать 42 км — и все это за 17 часов.

Артем рассказал DOU, с чего началось его увлечение триатлоном, как проходят тренировки и почему бюджет на подготовку к Ironman стартует от $5 тыс.

— Артем, как вы заинтересовались триатлоном? С чего все началось?

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

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

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

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

— А какие цели поставили?

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

На тренировках в бассейне я часто невольно слышал разговоры ребят о том, как они занимаются бегом, какие «работы» делают на тренировках. Отношения с бегом у меня были такие же, как и с плаванием. Я как бы умел, но терпеть его не мог. В школьные и университетские годы бегал 3-5 кмна праздники в центре, чтобы получить хорошую оценку. Скоростные зачеты мне давались неплохо: в университете бегал стометровку быстрее всех. А вот с длинными дистанциями просто не уживался.

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

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

Отвечая на ваш вопрос — да, я очень полюбил бег. Но объяснить, почему или за что — сложно. Это просто на уровне чувств. И да, это чувство пришло не через два-три месяца, а немного позже, когда 10-15 кмуже кажутся не страданием, а просто очередной длинной тренировкой. В ней невероятно много кайфа :)

К тому же я вообще люблю тренироваться сам. Это время медитативное. Люблю побыть наедине с собой, а если в лицо еще и рассвет — так вообще благодать!

— А как от плавания и бега перешли к триатлону? Почему захотели участвовать в Ironman?

Ребята в бассейне стали обсуждать уже не бег, а триатлон. Я заинтересовался. Читал, смотрел видео. Однажды на обеде сказал коллеге, что было бы очень интересно пройти половинку Ironman. Для этого нужно проплыть 1,9 км, проехать на велосипеде 90 км и пробежать 21 км. Помню, как от этих слов по телу пошла дрожь. Стало очень страшно... И интересно! А когда страшно и интересно, я редко могу себя удержать, чтобы не попробовать :)

Сейчас каждый год происходит 43 старта полной дистанции Ironman. На каждом старте — до 2,5 тыс. участников. Около 100 тыс. человек ежегодно — такая себе небольшая компания :) Мне хотелось быть причастным к чему-то эксклюзивному, непростому, со сложным порогом входа. Когда искал для себя подобный вызов, ничего сложнее придумать не мог. Да и куда сложнее, думал я? Я ни на секунду себе не мог представить, что это вообще возможно.

За 20 месяцев тренировок цель «быть одним из» сильно деформировалась. Да и цели как таковой я уже не ощущаю. Впереди есть точка, к которой я иду — старт в августе 2020 года в Копенгагене. Но сейчас для меня самая большая ценность — это сам путь, по которому я иду каждый день. Мне невероятно интересно, что будет дальше за той самой точкой в виде старта на Ironman. Но значительно важнее то, что есть сейчас :)

— Расскажите, как обычно проходит Ironman?

Гонка начинается рано утром, около шести часов. Как любят говорить организаторы на брифинге: «Хорошенько отдохните, завтра у вас самый длинный день в вашей жизни!» Лимит времени на прохождение дистанции — 17 часов. То есть, начав гонку в 6:00, часть участников финиширует вплоть до 21:00.

Все начинается с плавания в открытой воде. Это может быть озеро, море, река, океан. Дистанция — 3,8 км.

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

На велосипеде все просто, крути-балдей 180 км :) У спортсмена-любителя со средним уровнем подготовки этот этап занимает 5-7 часов.На трассе через каждые 20 км — пункты гидратации и питания. Там раздают изотоники, бананы, воду, энергетики.

После завершения велотрассы спортсмены попадают во вторую транзитную зону, где оставляют велосипед и переодеваются в беговую форму. Впереди — 42 км бега. После 3,8 км вплавь и 180 км вело — сомнительное удовольствие :) Говорят, Ironman на самом деле начинается на беге. Там спортсменам предстоит проявить настоящий характер, когда все системы организма уже работают на пределе. На беговом отрезке, конечно же, тоже организовано питание и пункты гидратации.

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

На финише спортсменов награждают медалью с долгожданными словами: «Congratulations! You are an IRONMAN!»

— Вы уже участвовали в нескольких соревнованиях. В каких именно? Какие результаты показали?

На сегодня я проплыл половину дистанции Oceanman в Одессе (5 км) и сделал три полумарафона. Лучшее время — 1:32:55. Плавательные и беговые старты помогают проверить физическую готовность и работу сердца на длинных дистанциях.

Что касается триатлона, на Dnipro Triathlon Fest я прошел олимпийскую дистанцию (плавание — 1,5 км, велосипед — 40 км, бег — 10 км) за 2 часа 40 минут. Также финишировал на половинке Ironman 70.3 Gdynia (плавание — 1,9 км, велосипед — 90 км, бег — 21 км) за 5:32:32.

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

Вот список экипировки, по которому я собирался на Triathlon Dnepr Fest и на Ironman 70.3 Gdynia:

Плавание:

  • стартовый костюм;
  • запасной стартовый костюм;
  • гидрокостюм;
  • датчик ЧСС;
  • часы;
  • шапочка;
  • очки;
  • запасные очки;
  • вазелин;
  • антифог;
  • кроксы.

Вело:

  • велосипед;
  • запасная камера;
  • запасная покрышка;
  • смазка цепи;
  • насос;
  • сумочка на раму;
  • сумочка под сиденье;
  • крем для загара (перед стартом);
  • пантенол (после старта);
  • спортпит: 10 гелей, 2 батончика (зависит от старта);
  • бутылочка;
  • шлем;
  • очки;
  • велотуфли;
  • носки для вело;
  • ремкомплект;
  • теплая велокофта;
  • веложилетка на случай плохой погоды.

Бег:

  • кроссовки;
  • 2xu лонгслив — на случай холодной погоды;
  • поясная сумка для гелей;
  • козырек;
  • беговые шорты;
  • беговая футболка.

После старта:

  • шорты;
  • куртка.

А вот план гонки, который у меня был на Triathlon Dnepr Fest:

Плавание.На плавании я в стартовом костюме, шапочке, очках, с часами на руке и нагрудным ЧСС под стартовым. Буду доволен собой, даже если проплыву по 2:15 на 100 м.

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

Вело.В сумочке на раме лежит три геля и один батончик. Сразу съедаю батончик и немного запиваю водой. Пульс держу до 155. На подъемах — до 160. Через каждые 20 минут съедаю по одному гелю и пью немного воды. Каждые 5 км — пара глотков воды. Если в момент, когда нужно есть гель, начинается подъем — съедаю гель на спуске. Через шесть кругов останавливаюсь перед Dismount in line. Слезаю с велосипеда. Отбиваю начало второй транзитки на часах.

Вторая транзитная зона.Часы все еще на руле. Бегу с велосипедом к своему месту. Возле него сразу снимаю часы с руля, кладу их в беговые кроссовки. Вешаю велосипед. Снимаю шлем и очки. Кладу их в корзину. Снимаю велотуфли. Надеваю часы. Из бегового кроссовка вытаскиваю один гель и кладу его в задний карман стартового костюма. Надеваю кроссовки и бегу на выход. Смотрю на доску возле Penalty Box. Если мой номер есть (849), то отдыхаю от 10 секунд (зависит от штрафов, которые собрал). Если моего номера нет, бегу на старт. Отбиваю на часах начало бега.

Бег.Через 2 км бега съедаю гель. На ближайшем пункте гидратации выпиваю стакан воды. Через два круга — еще стакан воды. Пульс держу до 165. Будет очень здорово, если удастся бежать по 4:25 мин за километр или быстрее.

Финиш.Счастье, радость, улыбки.

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

— Как вы готовитесь к гонкам? С чего начинали?

Начал с поиска тренера, который смог бы меня подготовить. Одно дело — готовиться к одному виду спорта, но когда их сразу три, возникает много вопросов. К примеру, как часто тренироваться в каждом из них? Какой длительности должны быть тренировки? С какой интенсивностью? Какие именно тренировки? Как правильно восстанавливаться? Массажи? Бани? Как выбрать велосипед? И множество других моментов, которые просто не укладываются и не структурируются в голове без перелопачивания горы информации и общения с опытными любителями.

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

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

— Сколько времени тратите на тренировки? Как удается совмещать их с офисной работой?

В среднем при подготовке к половинке Ironman тренировки занимали от шести до восьми часов в неделю. В пиковые недели — до 12 часов. Сейчас я уже тренируюсь по плану для полного Ironman, который пройдет в августе в Копенгагене, и трачу на это от восьми часов в неделю с пиками до 17 часов. Если с бегом и велоспортом все просто — оделся и побежал или поехал, то с бассейном приходится терять дополнительное время на дорогу. Если учесть все расходы времени, то получается до 20-22часов в пиковую неделю.

Тренируюсь я в 90% случаев рано утром. На пробежку выхожу в 6:30. На велосипедную тренировку выезжаю в 5:40-6:00.Бассейн работает с 7:00 — к этому времени я и прихожу.

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

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

— Сколько денег тратите на подготовку? Отличаются ли затраты в разные месяцы?

За 20 месяцев подготовки я потратил $5342. В эту сумму не входят расходы на поездку на Ironman, но входит сумма покупки слота.

Самые ощутимые покупки за это время:

  • $1000 — велосипед;
  • $400 — часы Garmin Forerunner 935;
  • $300 — гидрокостюм;
  • $288 — абонемент в зал;
  • $240 — стартовый костюм;
  • $211 — слот на половинку Ironman в Гдыне;
  • $200 — тренировочный план;
  • $150 — настройка посадки на велосипеде;
  • $150 — нагрудный датчик ЧСС;
  • $100 — беговые кроссовки.

Все остальное — мелочи. Но их оказалось намного больше, чем я думал :)

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

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

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

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

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

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

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

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

— Что бы вы посоветовали новичкам? С чего начать?

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

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

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

— Как уберечься от травм во время подготовки и самого соревнования?

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

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

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

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

— О чем нужно знать во время соревнования, чтобы дойти до финиша?

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

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

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

Я рассчитываю свое питание так. На вело — 70-90 гуглеводов в час, на беге — 60-70 гв час. Солевые таблетки — по 1-2 гв час.

— Помогают ли вам качества, приобретенные благодаря спорту, в работе?

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

Триатлон учит меня отделять зерна от плевел. Хорошие колеса на велосипед помогут мне сэкономить около 20 минут на 180 км. Стоят колеса примерно $1000. Правильно настроенная посадка за $100, анализ техники с тренером и работа над слабыми местами потенциально может сэкономить 60 минут. Не подумайте, что, рассуждая об экономии во времени, я стремлюсь показать лучшее время — я стремлюсь оптимизировать задачу для своего организма. В работе это помогает смотреть на задачи в долгосрочной перспективе.

— Какая у вас цель? Есть ли определенные цифры, которые хотите показать на Ironman?

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

Що має знати Senior C++ Developer. Аналіз вакансій в Україні та Каліфорнії

$
0
0

Це вже п’ята стаття серії «Що має знати Senior». В попередніх випусках було розглянуто iOS/macOS, PHP, Javaта Front-end. Тепер настала черга C++.

Станом на 18 жовтня на DOU було 26 вакансій Senior C++ Developer. 7 січня — ще 18 нових. У Каліфорнії в LinkedIn 19 січня — 24 вакансії, зокрема від Walt Disney, DreamWorks, Unity, Adobe,AMD та Samsung.

Розробників шукають на абсолютно різні проєкти: Artificial Intelligence, Automotive, Blockchain, Embedded, Game Development, Robotics, Windows Apps Development, 3D Printing. Не дивно, що десятки технологій трапилися лише один чи два рази. Тим не менше, вдалося знайти багато спільного для вакансій Senior C++ з різних предметних галузей.

В Україні — англійська та Linux, в Каліфорнії — освіта та комунікаційні навички

Освітадля C++ розробника відіграє помітно важливішу роль, ніж для інших спеціалізацій. В Україні профільну вищу освіту від Senior C++ вимагає 21% вакансій проти 11% від Senior Front-end та 16% від Senior Java. А в Каліфорнії цей показник для C++ взагалі зашкалює: 63%.

Знання Linuxв Україні вимагають 40% вакансій проти 21% в Каліфорнії. За океаном цінують не стільки hard, скільки soft skills. Так, комунікаційні навичкизгадують загалом 58% вакансій Каліфорнії проти 30% в Україні. Знання технологій, на думку американських роботодавців, можна і наздогнати: знання того самого Linux 13% вакансій в CA згадали лише як плюс. В Україні це зазвичай must have.

Англійськавже звично стала навичкою номер один в Україні. Хоча вимога знання англійської на цей раз траплялася дещо рідше: 50% для C++ проти 61% для Java. Але ці цифри загалом є близькими і можна вже говорити про тенденцію, актуальну для різних IT-спеціалізацій: приблизно кожна друга вакансія в Україні вимагає знання англійської, що явно пов’язано з домінуванням аутсорсингу в структурі IT країни. О, це тягне на відкриття Америки! :D

Віджет з усіма вимогами у вакансіях Senior C++ Developer

Сірим кольором виділені додаткові вимоги. Щоб подивитися їх, натисніть у віджеті на чекбокс «Врахувати додаткові побажання»

Рівень володіння англійською: Advanced нікому не потрібен

Але який рівень володіння англійською вимагається? Насправді невисокий. Загалом рівень уточнено в 38% вакансій, з них по 18% вимагають Intermediate та Upper-Intermediate. Вимога знати на Advanced — велика рідкість, і це вже теж тенденція, яка повторюється від спеціалізації до спеціалізації.

Традиційно наведу конкретні цифри зарплат згідно з альтернативним віджетом:

  • Intermediate. 23 анкети. $3683 на місяць чистими.
  • Upper-Intermediate. 44 анкети. $3862.
  • Advanced. 6 анкет. $3766.

Зростання рівня англійської може дати Senior C++ розробнику $2148 на рік проти 7-10тисяч для інших IT-спеціалізацій. Схоже, що від плюсовика очікується, що він буде більше писати код і менше говорити :D

Правило 5 років досвіду

Отримати личку Senior теоретично можна вже з 2 роками досвіду, але таких вакансій дуже мало та вони, як правило, мають формулювання Middle/Senior C++ Software Engineer. Частіше за все роботодавці спираються на так зване правило 5 років. Причому в Каліфорнії це ще більш виражено, ніж в Україні. Маєш за плечима 5 років досвіду — можеш претендувати на роль Senior. Більший поріг, як-то 6 чи 7 років, мало хто встановлює, але буває.

Розподіл вимог до досвіду роботи Senior C++ Developer в Україні й Каліфорнії

Буде плюсом: Python

Python згадує кожна четверта вакансія як в Україні, так і в Каліфорнії. Причому 21% українських вакансій називають його як додаткове побажання. Це означає, що знайти досвідченого C++ розробника з належним рівнем знання Python — непросто, але він всім потрібен. Саме знання Python стає конкурентною перевагою на ринку праці в умовах, коли машинне навчання відіграє все більшу роль. Вчіть Python!

Цікавинки, знайдені у вакансіях

Україна

EnvisionTEC GmbH маєв офісі шість 3D-принтерів.

XCDS готова платитидо 4 200 в Харкові. В компанії існує традиція The Game Day.

Career Art шукаєпрацівника для WowApp. На нього чекає віддалена робота зі спеціалізацією на Qt, компенсація до 5 000 та 2-3-тижневий онбординг в Бухаресті (Румунія).

Brightgrove пропонуєрелокацію до Канади у разі успішного проходження випробувального періоду.

Ukr.netобіцяєроботу з C++17, спортзал в офісі та медичне страхування, що покриває всі види захворювань. Цікаво, чи означає це, що страховка покриє навіть лікування раку?

Delphi Software пропонуєне лише індивідуальне страхування здоров’я, але і сімейне.

Каліфорнія

Stealth Startup пропонуєдо 250k доларів на рік.

Apogee Electronics шукає Senior Software Engineer, який має 2 роки досвіду в якості скрам-мастера.

Omron запрошує працюватинад роботами майбутнього.

Думка технічних експертів

Оксана Ярошко, Senior C++ Developer в Symphony Solutions

Безперечно, це технічно підкована людина. Сучасні стандарти С++, бібліотека STL, багатопотоковість та concurrency — це безумовний скупий мінімум.​

Для Senior-розробника перш за все важливим вмінням є проектування та дизайн програмного продукту. Тому знання структур даних, алгоритмів, шаблонів проектування є необхідними.​

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

Важливо розуміти, що кожний проект диктує свої правила і вимоги.​

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

Вадим Гулаков, С++ Engineering Lead в Intellias

Для того, щоб стати Senior C++ розробником у пересічній українській компанії потрібно відносно небагато. Мінімальні вимоги — це кілька років комерційного досвіду, уміння розповісти про віртуальні деструктори та відмінності вектора від ліста, таке-сяке знання англійської і «успіх» гарантований. За моїми спостереженнями майже усі Junior’и й Middle’и так чи інакше стають Senior’ами. Це стосується не лише С++, а і будь-якої іншої мови програмування. Причому я б не називав це «девальвацією» Senior’ів: виглядає, що так було завжди.

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

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

Час від часу стикаюся з думкою, що знання того чи іншого фреймворку робить тебе кращим інженером. Але у світі С++ подібні ілюзії трапляються не надто часто. Адже тут досі немає єдиного універсального фреймворку, який усі використовують. Звісно, є boost, С++11 значною мірою змінив ситуацію, однак навіть зараз постійно доводиться мати справу з дуже специфічними інструментами, часто спроектованими неналежним чином.

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

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

Андрій Крамаренко, Senior C++ Software Engineer в Symphony Solutions

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

  • Хоча досі можна ще знайти проекти, де C++11 не використовується в повному обсязі, сьогодні він є де-факто стандартом. Звісно, в ідеалі необхідно знати, що додавали в наступних редакціях стандарту (і очікувати з нетерпінням С++20), але не завжди є можливість мати комерційний досвід з глибоким вивченням нових можливостей.
  • Попередній пункт містить знання стандартної бібліотеки, але зазвичай він розширюється іншими інструментами (наприклад Boost або Qt) залежно від сфери використання.
  • Добре розуміння на концептуальному рівні таких речей з комп’ютерних наук, як: алгоритми, структури даних, патерни, операційні системи, комп’ютерні мережі, архітектура комп’ютера.
  • Concurrency я б виділив окремо, оскільки проектувати систему або модуль, де все виконується паралельно — важка справа, навіть при використанні task-based підходу.
  • Звісно, від С++ розробника очікують витискати в певних обставинах максимум в плані продуктивності. Як правило, добрих знань і досвіду з попередніх пунктів вистачає, але окремо я б хотів зазначити, що для Senior’a такі речі, як Data Oriented Design або CPU cache friendly structures не є порожнім звуком.

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


Візуалізація даних: Ігор Яновський

Як зробити тестові завдання ефективними. Алгоритм дій для працедавців і кандидатів

$
0
0

Досить багато роботодавців просять своїх кандидатів виконати тестове завдання. Це — один з етапів співбесід на певну посаду. Давайте сьогодні поговоримо про найпоширеніші запитання та проблеми. Моє ім’я Юлія Шишенко, працюю IT-рекрутером та кар’єрним консультантом. Тож з практики знаю питання з обох боків: 1) для чого роботодавцям тестові завдання від кандидатів; 2) та як кандидати готуються, хвилюються і виконують ці завдання. Стаття стане у пригоді роботодавцям та здобувачам як джерело ідей, які допоможуть організувати процес роботи з тестовими завданнями ефективніше.

Для чого потрібні тестові завдання

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

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

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

Ілюстрації: Каталіна Маєвська

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

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

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

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

Рекрутер К. отримав від компанії-клієнта замовлення на закриття трьох вакансій Python програмістів. Одним із етапів було тестове завдання, на виконання якого витрачалося 3-4 години.Половина кандидатів відмовилася виконувати. Через це термін закриття вакансій збільшився майже вдвічі.

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

Індивідуальна ситуація кандидата.Людина приходить на роботу, щоб мати можливість заробляти собі на життя. Якщо ви бачите, що кандидат вже пів року, а то й більше, без роботи, якщо він забезпечує свою сім’ю або покриває якісь регулярні витрати (наприклад, через хворобу чи навчання) — скоротіть процедуру та дайте шанс швидше стати до роботи, щоб кандидат зміг заробляти знову. Пам’ятайте, що попереду три місяці випробувального терміну, і якщо здобувач не впорається з роботою, його можна буде звільнити. Взагалі на процедуру прийому на роботу мають впливати в тому числі певні економічні показники регіону, де працює компанія. Чим ситуація гірша, ти простішим має бути процес винаймання, аби люди могли швидше влаштовуватися на роботу.

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

Бажання самого кандидата.Мрію про те, щоб роботодавці не робили з тестових завдань перепону. Якщо у кандидата немає часу чи можливості виконати тестове завдання, це не має позбавляти його можливості й далі брати участь у конкурсі на певну вакансію. «На цю посаду ми пропонуємо всім кандидатам виконати тестове завдання. Вже два кандидати зробили це. Чи бажаєте й ви виконати тестове завдання? Це не є обов’язковим, але також враховується при прийнятті рішення». Кожен кандидат — це потенційний співробітник. Невже думка вашого майбутнього колеги не важлива?

Як можна раціональніше використовувати тестові завдання

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

Завдання.Розробляючи тестове завдання, попросіть співробітників, які вже працюють у компанії, його виконати. Якщо з цієї спеціалізації в компанії ніхто не працює, можна зібрати певну фокус-групу з підрядників, колишніх співробітників (ось навіщо залишатися в гарних стосунках з усіма співробітниками) чи групи фриланс-спеціалістів. Тут задача HR-фахівця — визначити час на виконання та рівень завдання. Програмісти рівня Senior іноді дивуються, отримуючи завдання для рівня Junior. Або витрачають на завдання по 6-8 годин,а роботодавець навіть на співбесіду може не запросити і не дати жодної відповіді. HR-фахівець чи рекрутер може не бути вузьким спеціалістом в іншій професії, але він може і повинен організувати процес так, щоб бути впевненим, що тестове завдання не марнує час кандидатів і допомагає визначити найкращого.

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

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

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

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

Відповідькандидату треба давати, навіть якщо він виконав завдання гірше за інших і не проходить на наступний етап співбесіди. Для рівня Junior було б ідеально, якби кандидати отримували пояснення, що саме не так, на що їм звернути увагу, що вивчити тощо. Давайте своїм кандидатам можливість розвиватися і навчатися, навіть під час відбору. Земля кругла: сьогоднішній здобувач з рівнем Junior колись стане вашим кандидатом з рівнем Senior.

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

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

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

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

Релевантність.Будь-яке тестування перевіряйте на релевантність професії кандидата. Так кандидату буде цікавішим і зрозумілішим саме завдання.

Як кандидату успішніше виконати тестові завдання

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

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

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

Компанія Y. відкривала офіс в Україні і винайняла локального рекрутера Ю., щоб знайти технічного керівника офісу, якому б підпорядковувалися програмісти. Але компанія вирішила дати всім кандидатам тестове завдання. Через значну зайнятість та високий професійний рівень певні кандидати відмовилися виконувати технічні завдання вдома. Ю. запропонувала компанії провести технічну співбесіду і обговорити на ній вирішення технічних задач з використанням готового коду, який мали кандидати. Формат був настільки ефективним та вдалим, що компанія вирішила відмовитися від тестового завдання на користь обговорення та вирішення задач під час співбесіди.

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

Тести.До технічних завдань, які знають і виконують фахівці IT-сфери, великі міжнародні компанії можуть додати тести на IQ чи EQ, поведінкові тести, кейсові завдання, математичні тести, відеотести, тести на логіку тощо. Їх дуже багато, і переважно такі тести оцінюють не вузькі професійні знання кандидата, а загальний рівень мислення, уважності чи особистісного розвитку людини. Я бачу, що на європейському ринку праці такі тести зараз знову стали популярними. Компанії купують доступ до спеціалізованих сайтів і просять кандидатів виконати певні завдання на останніх етапах відбору. Готуватися до таких тестів можна. Найголовніша порада — запитайте назву платформи, з якою працює компанія, і знайдіть на цьому сайті тестову версію для кандидатів. Майже всі платформи для тестування, з якими я мала справу, мають спеціальний розділ, де кандидати можуть потренуватися.

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

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

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

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

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

Підсумовуючи

Покроковий алгоритм дій для роботодавців:

  1. Визначте, чи потрібне взагалі тестове завдання для цієї посади.
  2. Протестуйте власне тестове завдання.
  3. Визначте умови і ресурси для його проведення. Оформіть завдання у зручному та доступному форматі. Підготуйте заздалегідь інформацію, яку можна надати кандидату для виконання завдання.
  4. Чітко визначте час, потрібний на виконання тестового завдання.
  5. Повідомляйте про наявність тестового завдання серед етапів співбесіди під час зустрічі-знайомства з кандидатом.
  6. Повідомте кандидату, які етапи співбесіди він має пройти, аби отримати доступ до тестового етапу.
  7. Організуйте однакові умови для всіх кандидатів у офісі або за бажанням кандидата надайте завдання у якості домашнього.
  8. Намагайтеся мінімізувати стрес під час проведення співбесід. Впевніться, що кандидат має воду, доступ до вбиральні та контактну особу, якій можна задати питання. Тестове завдання — це не екзамени в школі, тут не обов’язково стежити за кожним рухом здобувача і створювати напругу. Організуйте звичайну робочу атмосферу.
  9. Повідомте кандидату, хто перевірятиме завдання та у які терміни нададуть відповідь.
  10. Організуйте, щоб наймаючі менеджери мали час та ресурси на перевірку цих завдань.
  11. Якщо це можливо, запросіть кандидата на наступний етап співбесіди, навіть якщо завдання виконане не на найвищому рівні. Якщо кандидат пройшов попередні етапи, але завдання виконане погано, запитайте, чи не мав він того дня причин, які могли б завадити: погане самопочуття, сварка з рідними, непередбачувана ситуація вдома.
  12. Обов’язково дайте кандидату відповідь про успішність виконання завдань. Краще, щоб відповідь була мотивуючою, детальною та дозволяла здобувачу використати її для власного професійного розвитку.

Покроковий алгоритм дій кандидата:

  1. Найкраще готуватися до співбесід ще до їхнього проведення. Шукайте та колекціонуйте способи оцінювання професіоналізму для вашої професії. Вважайте це частиною професіоналізму — знати, як оцінити свої навички. Періодично ходіть на співбесіди. Просіть у своїх колег приклади тестових завдань, які вони складали в інших компаніях.
  2. Користуйтеся онлайн-платформами, де є тести на логіку, математику, загальні знання та психологічні тести. Гарного результату таких тестів інколи можна досягти тренуваннями, а не завдяки спеціальним навичкам чи знанням. Це як спорт, де майстерність здобувається з часом, незалежно від фізичних даних людини. Починайте тренуватися за 2-3місяці до пошуку роботи.
  3. Визначте свою стратегію та умови щодо тестових завдань: час, типи завдань, оплата.
  4. Запитуйте рекрутера на перших етапах співбесіди, чи будуть тестові завдання і якого вони типу, щоб мати декілька запасних днів для тренувань.
  5. Якщо є можливість, проходьте тестування в офісі роботодавця. Завжди раджу своїм кандидатам відвідувати офіс роботодавця, щоб отримати більше інформації про компанію. Так і час на завдання буде обмеженим. Крім того, ви оціните робоче середовище офісу: гамір, освітлення, обладнання, зручність меблів.
  6. Якщо берете тестове завдання додому, скористайтеся допомогою друга.
  7. Не відкладайте виконання надовго — від цього стрес тільки збільшується.
  8. Оформлюйте завдання так, як би це робили у звичайних робочих умовах.
  9. Запитайте у рекрутера, хто перевірятиме завдання. І виконуйте його так, щоб не витрачати марно час цієї людини. Можливо, це ваш майбутній керівник, якого не варто обтяжувати вичитуванням великого обсягу пояснень і деталей, які не вимагаються у завданні.
  10. Погодьте з рекрутером конкретну дату фідбеку: «Отже, я чекатиму на відповідь про результати тестового завдання до п’ятниці 21 лютого. Запишу собі, і, якщо потрібно, я можу вам нагадати про це».
  11. Звісно, ніхто не гарантує, що компанія детально розписуватиме, де кандидат припустився помилок, але спробувати запитати варто: «Якщо наймаючий менеджер матиме час, будь ласка, я б хотів дізнатися, які з відповідей були неправильними. Для мене важливо зробити роботу над помилками».
  12. Якщо відповідь від компанії не надійшла, роботу над помилками зробити все одно варто. Наприклад, з колегою, ментором, консультантом чи психологом. Якщо вже і виділяти час на певну роботу, то з користю для себе та задля зростання свого професіоналізму.

Vue-типізація legacy Vuex Store: вирішення проблеми

$
0
0

Вітаю! Мене звати Микола Коваль, я Front-end Team Lead компанії SocialTech, і це моя коротка історія про те, як ми Vuex типізували. У статті я розповім, як просто й безболісно здружити типи компонентів з Vuex за допомогою кількох рядків коду. Для тих, хто добре дружить з TS — тут результат. А кому цікаво, у чому була проблема, — далі більш детально.

Задача

Наша задача полягала в переведенні старого коду проєкту на TypeScript. Це потрібно було робити ітеративно, поступово, оскільки необхідно доставляти й нові фічі. Якщо з components, helpers і services усе зрозуміло, то зі store на Vuex виникли проблеми.

Для початку треба було додати типи, аби зрозуміти, які дані ми отримуємо та як з ними працювати:

const mutations: MutationTree<ProfileState> = {    PROFILE_ADD(state, profiles: iProfile[]) {        // ...    },
} 

Усе виглядало досить просто, але виникали проблеми. Кожна задача має свою гілку на Git, перед заливкою на прод усі вони зливаються в stage. Багато розробників, багато гілок системи контролю версій, і часто виникає mergehell. Наприклад, поки задача #1 дійде до проду, уже задеплоїться задача #2. А в ній розробник вирішив видалити непотрібні дані зі стора, на які спирався розробник задачі #1. Під час code review цього не помітили. У результаті це виявив мануальний тестувальник під час тестування, оскільки до мерджа фічі в stage витку все працювало. Такі випадки повинна ловити статична типізація під час збірки проєкту на CI-платформі.

Нативний варіант типізації, що надавався типами Vuex, полягав тільки в описі state. Це дозволяло мати статичну перевірку state в mutations та actions, але при цьому не було таких моментів:

  • типи даних, що передаються в mutation з компонента й store;
  • типи даних, що передаються в action з компонента чи іншого action;
  • типи геттерів;
  • типи даних зі store, що використовуються в компоненті.

Шукаючи варіанти вирішення проблеми, я знайшов декілька цікавих рішень, що їх пропонували розробники. Але більшість не підтримувалася, мала мізерну кількість завантажень або взагалі були написані як експеримент. А от що було найбільш production ready solution, то це vuex-smart-module, хоча тоді воно мало 100 завантажень на тиждень у npm. Але нам потрібно було обрати щось просте, що не гальмуватиме роботу команди, не додасть зайвої складності. До того ж вихід Vue 3 з кращою підтримкою TypeScript не за горами, і Vuex має давно спланований roadmap, де пишуть про можливу зміну api. Тому не хотілося б усе переписувати, а потім знову це проходити. До цього всього store містить більшість бізнес-логіки, а ще велику legacy кодову базу, тому чіпати їх зайвий раз не хотілося. Отож, я вирішив хакнути Vuex.

Вирішення

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

Далі наведені кроки для повної типізації викликів commit і dispatch з усіма можливими підказками від TypeScript та їхнім зв’язком з компонентом.

Для початку опишемо файл з типами, це буде єдине джерело правди про store (types/Store.ts):

import { Profile, User } from '@/types'
import { CommonState, ProfileState } from '@/store'

export type State = {    profile: ProfileState    common: CommonState
}

export type MutationTypes = {    COMMON_INIT_USER: User    COMMON_CLEAR: undefined    PROFILE_ADD: Profile[]
}

export type ActionTypes = {    LOGIN: User    LOGOUT: undefined
}

export interface Getters {    isAuthenticated: boolean
}

export type ActionTypesResult = {    LOGIN: void    LOGOUT: void
}

У файлі shims-tsx.d.tsрозширюємо інтерфейс Vue, додаючи свій $store й перевизначаємо нові інтерфейси для commit і dispatch:

import { Store as VuexStore, CommitOptions, DispatchOptions } from 'vuex'
import { Store } from './types/Store'

declare module 'vue/types/vue' {    type CustomStore = Omit<VuexStore<Store.State>, 'getters' | 'commit' | 'dispatch'>    interface Vue {        $store: CustomStore & {            getters: Store.GettersTypes            commit<Key extends keyof Store.MutationTypes>(                type: Key,                payload: Store.MutationTypes[Key],                options?: CommitOptions,            ): void            dispatch<Key extends keyof Store.ActionTypes>(                type: Key,                payload: Store.ActionTypes[Key],                options?: DispatchOptions,            ): Promise<Store.ActionTypesResult[Key]>        }    }
}

Потім буде доступний автокомпліт і перевірка даних у сторі з компонента, а також помилка, що $store вже задекларовано.

Якщо ви використовуєте об’єктну нотацію, то тут інакший вигляд:

dispatch<Key extends keyof Store.ActionTypes>(    payloadWithType: { type: Key } & Store.ActionTypes[Key],    options?: DispatchOptions
): Promise<Store.ActionTypesResult[Key]>

Але в цьому випадку для типу ActionTypes потрібно залишати порожній об’єкт, оскільки змерджити об’єкт з undefined немає можливості.

export type ActionTypes = {    LOGIN: iUser    LOGOUT: {}
}

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

Щоб заміна інтерфейсу Vue працювала правильно, потрібно видалити з node_modules/vuex/types/vue.d.tsопис $store в інтерфейсі Vue. Просто перевизначити конструкцію $store: Store<any> не можна, оскільки тип any повністю вбиває типізацію.

Також потрібно з node_modules/vuex/types/index.d.tsвидалити декларації сommit і dispatch, оскільки в них використовується тип any й нічого типізувати не вдасться. Щоб це реалізувати, можна форкнути Vuex, а можна запуститипростий скрипт на postinstall хук.

Після цього потрібно описати нові інтерфейси, оскільки в store action не матимуть сигнатур сommit і dispatch.

//file shims-tsx.d.ts
declare module 'vuex/types/index' {    interface Commit {        <Key extends keyof Store.MutationTypes>(            type: Key,            payload: Store.MutationTypes[Key],            options?: CommitOptions,        ): void    }    interface Dispatch {        <Key extends keyof Store.ActionTypes>(            type: Key,            payload: Store.ActionTypes[Key],            options?: DispatchOptions,        ): Promise<Store.ActionTypesResult[Key]>    }
}

Далі в сторі також будуть типізовані commit та dispatch, але щоб це працювало, не можна використовувати деструктуризацію параметрів, як наприклад ({ commit }) (глюк TypeScript). Нижче результат:

Якщо ви хочете лаконічний вигляд і ладні вирішити це більш складним кодом, є такий варіант. При цьому вам не потрібно передавати undefined, коли не потрібно передавати дані під час виклику commit або dispatch.

Що в результаті

Отримуємо зручні виклики store в компоненті з усіма можливими підказками.

У компоненті при виклику commit або dispatch ви бачите доступні виклики й дані, що потрібно передати.

Невирішеними залишилися:

  • результат виклику dispatch потрібно декларувати вручну this.$store.dispatch('LOGIN').then((data: Store.ActionTypesResult['LOGIN']) => {}), вирішили домовленістю, що типи для даних з actions брати зі Store.ActionTypesResult;
  • в actions незадекларовані змінні getters і rootGetters — для цього так само треба декларувати type Getter в декларації, зайвий код, але легко вирішується (довільний приклад, у репозиторії такого не наведено):
const actions: ActionTree<CommonState, Store.State> = {    FOO(context): Store.ActionTypesResult[FOO] {        const { rootGetters }: { rootGetters: Store.Getters } = context        return rootGetters.bar    },
}
  • не було типізовано Vuex mapState й подібні хелпери в об’єктному стилі компонента, тому їх доведеться замінити автозаміною.

Додали обмежень у тому, що можемо використовувати тільки одну Vuex-нотацію виклику dispatch і commit, і зробили костиль з перебиванням параметрів залежності.

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

О чем вновь договорились ІТ и государство. Коротко об итогах встречи

$
0
0

[Об авторе: Эдуард Рубин, сооснователь харьковского ІТ-кластера, депутат Харьковского облсовета, инициатор ряда независимых образовательных проектов]

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

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

Дискуссию начал замминистр Минцифры Александр Борняков. Страсти в сети накалилась, и мы договорились встретиться у министра экономики Тимофея Милованова. И 6 февраля эта встреча состоялась. Со стороны ІТ-отрасли были представители ІТ-комитета ЕБА, ІТ Украины, Спілки українських підприємців, AmCham и Харьковского ІТ-кластера.

Со стороны государства — министр Министерства экономразвития, замминистра Минцифры, замминистры Минэкономразвития, представители офиса БРДО.

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

Амбициозные цели

Александр Борняков сделал довольно детальную презентацию тех цифр, которые сегодня есть в министерстве. В Украине сегодня около 200 тыс. программистов, оборот за первое полугодие 2019 вырос на 30% и составляет 1,64 млрд долларов. Налогов в бюджет было уплачено 6,1 млрд гривен, а рост составил около 30%. Казалось бы, солнце всходит и заходит, и главное его не трогать.

Но цели у государства амбициозные: доход от экспорта довести до 13 млрд долларов, количество ІТ-специалистов до 650 тыс. человек, а долю ІТ в ВВП государства довести до 10%.

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

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

Что входит в этот план

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

Украинская система налогов для IT работает более 20 лет. Именно она позволила IT-индустрии вырасти с нуля до таких объемов, что стала третьей по экспортному потенциалу в стране. Украина также занимает 5 место по объему аутсорсинга в мире. В этой системе есть много своих проблем. Одна из них — устаревшие инстанции, например, инспекция по труду, которой не дают покоя ФОПы. Эта ситуация надоела всем: и компаниям, и государству. Поэтому создание 5 группы ФОП даст возможность легально выстроить для ФОПов контрактную систему и дать им право работать хоть с одной фирмой, хоть с десятком.

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

Будет переход на ФОП-5 и будет IPbox для продуктовых компаний. При этом люди могут оставаться и на ФОП-3 и иметь трудовые отношения.

Смена трудового законодательства,которое узаконит контрактную форму сотрудничества. На сегодняшний день мы работаем с законодательством бывшего СССР, которое не отвечает современным темпам развития. Современный тренд Gig Economy, который уже используется во многих странах, а у нас работает почти 20 лет (но мы не знали, как это называется :), перехватили западные экономисты и внедряют у себя. Именно поэтому нам теперь необходимо привести законодательную базу к современному тренду. И в этом плане мы сравняемся с мировыми экономиками.

Введена квота на иммиграцию высококвалифицированных ІТ-специалистов.Первый год на 5 тыс. человек. По аналогии с Green и Blue-картами, я бы назвал нашу «жовто-блакитною картою» :) Этот закон позволит легко получать вид на жительство и право на работу высококвалифицированным специалистам, которых наши компании могут приглашать на работу. Также стартапы смогут создавать и граждане Украины, и зарубежные специалисты. Они смогут находиться в Украине, здесь вести инновационную деятельность в течении необходимого времени, платить налоги. Я считаю, что это очень интересный шаг. Квота на 5 000 человек — это эксперимент на первый год, чтобы отработать процессы.

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

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

Дорогу здолає той, хто йде, а гуртом і державу змінювати легше.

Ruby дайджест #35: подкасты с DHH и Sandi Metz, интервью с Matz, Ruby-гемы для ML

$
0
0

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

Всем привет! Январь — традиционное затишье. О новых версиях Ruby/Ruby on Rails ничего не слышно. Но есть что послушать и обсудить. Например, свежий подкаст DHHс Corecursive (транскрипт беседы — по ссылке), подкаст с Санди Метци подборку 16 ML Ruby-гемов. И, как всегда, мы собрали большое количество туториалов и статей🙌🏼

Релизы

Like I’m Five help you to create a complex testing context in a few seconds — гем Like I’m Five генерирует файл с фабриками, которые нужны для тестирования конкретного объекта.

Kno Ruby — гем реализует аутентификацию без пароля и позволяет настроить аутентификацию без повторных отправок имейла.

Attr-filters gem by Syndicode for filtering object attributes — гем для фильтрации атрибутов PORO (Plain old Ruby objects) с нулевыми зависимостями.

vergilet/monobank: Monobank API Ruby — релиз неофициального API для Monobank.

Почитать

Yukihiro Matsumoto interview for Evrone company — интервью Матца для Evrone после конференции Ruby Russia 2019: о том, что чаще всего спрашивают у Матца, назначении Ruby и работе над Ruby 3.

Best practices for modernizing build pipelines & logging — удобная подборка статей и лучших практик по модернизации build-пайплайнов и логгинга.

The Complete Guide to Blazing-Fast Performance in Rails — разгоняем Ruby с советами из статьи🚀

Pros and Cons of Using structure.sql in Your Ruby on Rails Application — рассматриваем «за» и «против» использования structure.sql для сложных, растущих RoR-приложений.

A Rubyist’s Introduction to Character Encoding, Unicode and UTF-8 — интересный гайд по кодировке: от кода Морзе до Unicode и UTF-8. Также в статье рассматривается пример кодировки в Ruby.

Parallelising ETL workflows with the Jongleur gem — паралеллизируем ETL-процессы с помощью гема Jongleur.

Exploring Big-O Notation With Ruby — рассматриваем асимптоматические значения в Ruby на подробных примерах.

Why the Sorbet typechecker is fast — нашумевший Sorbet, тайпчекер для Ruby, — действительно мощный инструмент. Пришло время посмотреть под капот Sorbet и понять, что делает его таким быстрым и производительным.

Evaluating Ruby in Ruby — статья о последовательностях инструкций и их оценке на чистом Ruby.

Rails is Fast: Optimize Your View Performance — улучшаем производительность Rails-приложения через оптимизацию баз данных и кэширование.

The Complete Guide to Migrate to Strong Parameters — как безболезненно и слаженно мигрировать с Protected Attributes на Strong Parameters.

Continuous deployment Ruby application to Minikube with Google’s Skaffold — настраиваем непрерывное развертывание простого Ruby-приложения на Minikube с помощью Skaffold.

Optimize Your Debugging Process With Object-Oriented Tracing and tapping_device — оптимизируем процесс дебаггинга с помощью объектно-ориентированного трейсинга и tapping_device.

Reverse Coverage: Find which tests execute which lines of code — иногда полезно знать, как тестируется / выполняется / документируется (в виде тестов, как живая документация) строка (или набор строк) приложения. Гайд как раз посвящен данной проблеме.

Let’s talk about that 15% Ruby claim — разбираем стоимость управления Rails-приложением (статья вдохновлена статьей DHH о том, что Basecamp тратит всего 15% бюджета на поддержание Ruby-систем).

Rails Flaky Spec Solutions — разбор flaky tests на legacy-проектах: подводные камни и как их избежать.

3 ways Webpack surprises web developers — автор рассматривает три распространенные проблемы, с которыми сталкиваются веб-разработчики при изучении Webpack: почему использование глобальных переменных ведет себя не так, как вы думаете; как Webpack воспринимает все, как модуль JavaScript и большое количество времени, которые требуется для эффективной настройки Webpack.

Cache Crispies — Fast, Flexible Rails Serializer — гем Cache Crispies немного напоминает Active Model Serializers с чистым DSL на основе классов. При этом Cache Crispies поддерживает высокий уровень производительности и позволяет включить кэширование при необходимости.

Migrate Your Rails App from Heroku to AWS Lambda — мигрируем Rails-приложение с Heroku на AWS Lambda с помощью Aurora Serverless — конфигурацией для Amazon Aurora с автоматическим масштабированием по требованию, в которой база данных автоматически запускается, закрывается и масштабируется в зависимости от потребностей вашего приложения.

Ruby on Rails Sentry logger installation and configuration — устанавливаем и настраиваем Sentry — ПО для мониторинга и отслеживания ошибок.

Working with Capistrano: Environment Variables and Remote Commands — подробный гайд по Capistrano с примерами модификации переменных окружения, обновления файла запуска оболочки и установкой утилиты rbenv.

Ruby 2.7 compatible gems — список гемов, совместимых с Ruby 2.7: Sinatra, Devise, Capybara и другие.

BigBinary

Традиционно Big Binary выпустили несколько статей об обновлениях в Rails 6:

Rails 6.1 introduces class_names helper

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

Rails Multiple Polymorphic Joins

Туториалы

How to use React with Ruby on Rails 6 — подключаем гемы webpacker, react-rails, react_on_rails.

Testing signed and encrypted cookies in Rails — короткий гайд по тестированию подписанных и зашифрованных куки.

Rails 6.1 adds query method missing to find orphan records — автор рассматривает новый метод запроса в Rails 6.1 для поиска потерянных записей.

Encrypted Secrets (Credentials) in Rails 6, Rails 5.1/5.2, older versions and non-Rails applications — туториал по хранению encrypted secrets в репозитории Rails-приложения.

Optimization Techniques by Benchmark Winners — пост по мотивам одноименной презентациина Ruby Kaigi 2019.

Name the Abstraction, Not the Data — туториал по неймингу абстракций в Rails.

How to migrate large database tables without a headache — название туториала говорит само за себя: мигрируем большие таблицы баз данных без головной боли :)

И несколько туториалов по рефакторингу от Josh Thompson: избавляемся от `attr_accessors` in `ogre.rbи рефакторим wizard.rb.

Послушать

RWpod

04 выпуск 08 сезона. Deno, Timestamp Truncation, 16 New ML Gems for Ruby, ResizeObserver, Vacuum и прочее

03 выпуск 08 сезона. Yarn 2, MIR, Playwright, Web in 2020, Ruby ML for Python Coders, React Nice Dates и прочее

02 выпуск 08 сезона. Microsoft Edge, Git 2.25, Deep dive into Did You Mean, Snowpack, Pxi, Postgres.js, Nano ID и прочее

01 выпуск 08 сезона. Goodbye, Clean Code, Developer Roadmaps, Rails PG Extras, Asdf-vm, IsoCity и прочее

Remote Ruby

Mental Health, Rails Upgrades, Jason’s New Project, Bootstrap Shift, and More — подкаст с неизменными ведущими Крисом и Джейсоном: об опыте Криса по обновлению GoRails до Ruby 2.7 и Rails 6, нового проекта Джейсона ChurchChat и нового инструмента Bootstrap до TailwindCSS от Laravel Shift, который позволяет обновить подписки Stripe с одного плана на несколько планов.

New Jumpstart Features, Postponing Southeast Ruby 2020, and (Possibly) a New Online Ruby Conference — эпизод о добавлении мультитенантности в Jumpstart Pro, использовании ActiveStorage и Uppy, об отложении Southeast Ruby 2020 и потенциальной онлайн-конференции по Ruby в 2020 году.

«Just Keep Hitting Tab» — подкаст, посвященный разговору о таких типизированных языках, как TypeScript и Crystal, об инструментах вокруг типизированных языков и немного о видеоиграх :)

5by5 Ruby on Rails Podcast

Ruby on Rails Podcast #304: Legacy Code Wisdom with Alexey Chernov — подкаст с Алексеем Черновым — консультантом по Ruby on Rails в JetThoughts. На протяжении многих лет он создавал MVP и консультировал бизнес по улучшению legacy-кода, масштабированию удаленной команды и достиженю эффективного процесса разработки. Он и ведущая подкаста Бриттани обсуждают legacy-проекты на RoR.

Ruby on Rails Podcast #303: Site Reliability at DEV with Molly Struve — Молли Струве — ведущий Site Reliability Engineer в DEV, компании, которая управляет блогом dev.to. Она и Бриттани говорят о том, что означает надежность сайта, любовь Молли к Elasticsearch и то, как у Молли получается создавать остроумный и образовательный контент.

Ruby on Rails Podcast #302: Ruby Autoformatter! with Penelope Phippen — подкаст с Пенелопой Фиппен (Rubyfmt), экс-ведущим разработчиком RSpec. Опыт в Ruby — около десяти лет. Она и Бриттани обсуждают Rspec, Ruby Central и ее мысли о сообществе Ruby.

Ruby Rogues

RR 448: How To Avoid Catastrophes with Jon Druse — подкаст с Jon Druse, Rails-разработчиком с 15-тилетним опытом о важности code review, случаях, когда рефакторинг приложения целесообразен и многом другом.

RR 447: All About Kafka and Oracle with Bob Quillin and Karthik Gaekwad — тема подкаста — безопасность в Kafka, а также совместимость Kafka и Docker.

RR 446: Development Environments — подкаст посвящен теме окружения разработки, использованию Docker в качестве окружения разработки, а также сравнению таких СУБД, как MySQL, MariaDB и Postgres.

RR 445: Location Services with Mithun Dhar — в подкасте ведущие и участник Mithun Dhar затрагивают тему перехода от веб-разработки к мобильной разработке, проблему безопасности и услуг определения местоположения, механизмы защиты данных пользователей и их конфиденциальность.

События

Воркшоп: Web UI Automation with Ruby + RSpec + Сapybara — львовский оффлайн-воркшоп по автоматизации тестирования с помощью RSpec и Capybara. Дата — 18 февраля.

Web crowd 5.0: Ruby — днепровский митап по Ruby от компании Yalantis. Темы митапа: Component-based architecture as a way to microservices; Mastering HIPAA project infrastructure within AWS ecosystem. Дата — 28 февраля.


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


C++ дайджест #24: Code cleanup, VR, з чого почати вивчення С++ та створюємо валентинку

$
0
0

Привіт, мої любі сішники! В цьому випуску пропоную ознайомитися з VR, видалити dead code з legacy та почати вивчати С++, якщо раптом ви ще не сішник. Почнімо? :)

Code cleanup

З розширенням кодової бази збільшується ймовірність залишку коду, який ніде не використовується. Щоб його швиденько позбутися, спробуємо інструменти:

VR

Наразі ми маємо досить велику кількість VR-систем (Vive, Oculus, Google тощо). До VR можна підійти з двох бокiв: кроссплатформенно — за допомогою ігрових движків, таких як Unreal Engine, — та через використання SDK (oculus SDK, VIVE, Google VR SDK for Android NDK).

Додатково пропоную ознайомитися з ресурсами:

Вивчаємо С++: з чого почати?

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

C++ Getting Started;

C++ Tutorial.

А експериментувати можна взагалі без будь-яких налаштувань в онлайн-компіляторах.

Лiтература для вивчення:

Modern C++

C++20 Concepts

C++ — Initialization of Static Variables

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

Що має знати Senior C++ Developer. Аналіз вакансій в Україні та Каліфорнії

The C++ Lifetime Profile: How It Plans to Make C++ Code Safer

How to Short-Circuit a Sequence of Operations with a Boolean Value

Various Ways of Applying a Function to the Elements of a Collection in C++

Mikado Refactoring with C++ Feature Macros

The Hunt for the Fastest Zero

5 Signs that your C++ build times are too slow!

Top 7 Gaming Engines You Should Consider for 2020

Copy-paste drive development and other innovative techniques for speedy programming(antipattern)

A Universal I/O Abstraction for C++

Cost of a thread in C++ under Linux

Optimizing Game Development with GPU Performance Events

QML Engine Deletes C++ Objects Still In Use — Revisited with Address Sanitizers

Allocating large blocks of memory: bare-metal C++ speeds

Інструменти

C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5

Code Navigation for CMake Scripts in Visual Studio

Improve Parallelism in MSBuild

Easily Add, Remove, and Rename Files and Targets in CMake Projects in Visual Studio

C++ Modules conformance improvements with MSVC in Visual Studio 2019 16.5

Хоткеи для VS Code: гифки с демонстрацией и шпаргалка

CLion starts 2020.1 Early Access Program: improvements to Clang-based tools and debugger, new font and editor theme, and more

CLion 2020.1 EAP: CUDA Support & Clang on Windows

Using nRF52 with CLion

Using Docker with CLion

Qt for MCUs 1.0 is now available

Porting Qt Applications to Qt MCUs 1.0

Watching for software inefficiencies with Valgrind

Оновлення

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

Хвилиночка флуду — cтворюємо валентинку!

Geeks For Geeks

C++17 — Draw a Valentine’s Day heart shape

Happy Valentine’s Day на GitHub


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

Топ-50 ІТ-компаній України, січень 2020: плюс чотири продуктові компанії та подолання відмітки «8000 фахівців»

$
0
0

У 2019-мутоп-50 виріс з 58 тисяч до 67 тисяч фахівців. За рік EPAM збільшив кількість спеціалістів на 1700 осіб і перетнув позначку «8 тисяч фахівців». А ще в рейтингу чотири нові та ще й продуктові компанії, із них три — українські.

Розпочнемо з нових облич, у рейтингу з’явилося одразу три українські продуктові компанії: Ajax System — 800 спеціалістів і 27 місце, PMLAB — 621 і 35, MEGOGO — 456 і 50. А також одна іноземна: WIX.com — 533 і 41.

Натомість у цей рейтинг не потрапили — Tickets.ua, Wargaming.net, CS Ltd і Delphi Software.

+8700 спеціалістів у топ-50 за 2019-йрік

З липня 2019 по січень 2020 кількість спеціалістів збільшилася на 2340 (7,5%) у топ-25 та на 4167 (6,6%) у топ-50 порівняно з першим півріччям 2019-го. Кількість фахівців у 25 найбільших ІТ-компаніях перетнула відмітку 50 тисяч, і наразі частка цих компаній становить 76% серед топ-50.

Зростання загальної кількості спеціалістів в 25 найбільших ІТ-компаніях України

Відносні показники темпів зростання

Якщо дивитися на річні показники, то темпи зростання призупинилися. У 2019-мукількість спеціалістів в топ-25 зросла на 13% порівняно з 2018 роком, і це на 5 п.п. менше, ніж темпи росту 2018-годо 2017-гороку. Що стосується темпів зростання топ-50, то за рік показники трішки кращі — майже +15% у 2019-му.

Якщо порівнювати кількісні показники, то у топ-25 кількість спеціалістів за минулий рік збільшилася на 5750 осіб проти 6983 у 2018-му.А у топ-50 — на 8671 у 2019-мупроти 8710 у 2018-му.

Річні показники темпів зростання

Цікаво, що темпи зростання технічних спеціалістів у топ-25 трішки вищі, ніж загальної кількості — майже на 16% виросла їх кількість у 2019 році порівняно з 2018-м.Усього ж минулого року кількість технічних спеціалістів у топ-50 збільшилася на 7337 осіб.

Зростання загальної кількості технічних спеціалістів в 25 найбільших ІТ-компаніях України

Зростання «великої п’ятірки» у другому півріччі 2019-госклало майже 6% (1455 фахівців). Усього в топ-5 працює 26 937 спеціалістів, що складає 40% від загальної кількості топ-50.

За 2019 рік кількість спеціалістів у топ-5 збільшилася на 13% (3072 фахівці).

Динаміка росту топ-5 компаній за період з серпня 2011 по січень 2020

Що пів року лідер рейтингу EPAMдолає нову відмітку по кількості спеціалістів: тільки у січні 2019-гоми писали про 6 тисяч, у липні він вже подолав 7 тисяч, і ось січень 2020-гоі подолано відмітку «8000 фахівців». Кількість спеціалістів в EPAM виросла на 800 осіб з липня по січень і на 1700 осіб за 2019 рік. За минулий рік на цю компанію припадає 55% зростання топ-5 та майже 30% — топ-25.

В EPAM таку активність пояснюють постійним збільшення частки складних end-to-end проєктів та розширенням співпраці з уже існуючими партнерами. Водночас компанія продовжує розвивати і напрямок навчання EPAM University Program — це співпраця з вишами, відкриття лабораторій, створення спеціальних освітніх програм. Основні спеціальності фахівців, які почали співпрацю з EPAM: Java/Big Data, Front-End, Automated Testing, .NET, Cloud/DevOps.

Компанія SoftServeвиросла на 363 спеціалісти за друге півріччя і на 1112 за минулий рік. За останні пів року на фоні традиційно великого стафінгу інженерів базового технологічного стеку, в компанії суттєво наростили BigData та Data Science команду, активно наймали system integration engineers, BA, QC, SAR, Ruby і Apple спеціалістів. Цікаво, що за цей час команда РМ-ів SoftServe в Україні зросла більше ніж на 60 осіб.

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

На четвертій і п’ятій сходинці — Luxoftі Ciklumвідповідно. В обох компаній відбувалися важливі і цікаві зміни минулого року. Почнемо з Luxoft, на початку 2019-гороку їх викупив DXC Technology за $2 млрд. В липні стало відомо, що кількість спеціалістів Luxoft в Україні зменшилася на 250 осіб (із них технічних — 35). У компанії зазначили, що це не стосується угоди. А пов’язано з тим, що у першому півріччі відбулося виведення операційних функцій на зовнішніх сервісних провайдерів. За підсумками другого півріччя кількість спеціалістів у Luxoft майже не змінилася (+5 осіб).

Щодо Ciklum, то за рік компанія зросла на 54 спеціалісти. У вересні стало відомо про банкрутствоодного з ключових клієнтів компанії Thomas Cook — на проєкті працювали близько 150 спеціалістів. Тоді Ciklum запевнив, що забезпечить інженерам перерозподіл на інші проєкти. І, судячи зі зростання кількості спеціалістів на 50 осіб саме у другому півріччі, компанії вдалося пережити закриття Thomas Cook без великих втрат.

Окрім EPAM, SoftServe і GlobalLogic, за пів року на 100 спеціалістів збільшилися ще 7 компаній: DataArt (326 спеціалістів), EVOPLAY (206), NIX (154), Ubisoft (153), Innovecs (135), ELEKS (127), ZONE3000 (101).

Лідери росту, липень 2019 — січень 2020 (топ-10)

Продовжує активно зростати DataArt — на 326 спеціалістів на останні пів року і на 499 спеціалістів за рік, що дозволило компанії піднятися на 8 сходинку рейтингу з 10-їна початку 2019-го.У DataArt ріст пов’язують зі зростанням бізнесу з США, Великобританії і ЄС в індустріях finance, media and entertainment, insurance і retail. Здебільшого наймали технічних фахівців за такими технологіями: JavaScript, Java, .NET, Python, DevOps і QAA. За цими ж технологіями відкривали школи і взяли кілька десятків trainee.

Динаміка зростання п’яти компаній-лідерів росту

Цікаво, що у другому півріччі суттєво зменшилися темпи зростання Intellias — останні два роки компанія демонструвала приріст не менше 160 спеціалістів що пів року. А ось з липня по січень кількість спеціалістів виросла на 79 осіб. Припускаємо, що це пов’язано із закриттям одного чи декількох проєктів, про що свідчать відгуки спеціалістів у профілі компанії.

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

Окрім Intetics, негативну динаміку продемонстрували Star (-2 спеціалісти), Intecracy Group (-9) і Miratech (-177). Суттєве зменшення спеціалістів у останній пов’язане з виділенням українського напрямку спеціалізованих служб підтримки користувачів (EUS) в окрему структуру.

11 компаній з топ-50 відкрили нові офіси у першому півріччі

З липня 2019 по січень 2020 року 11 компаній відкрили нові офіси як в Україні, так і за її межами. Щодо українських локацій — нові офіси з’явилися в Києві, Львові та Харкові. За кордоном — у Польщі, Німеччині, Швейцарії, Естонії, Індії, В’єтнамі та США.

45 компаній із топ-50 мають офіси у Києві, 23 — у Львові та 21 — у Харкові. В цілому у 23 українських містах є офіс хоча б однієї компанії із топ-50.

Плани щодо росту й релокації на перше півріччя 2020-го

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

Плани компаній щодо розширення персоналу на найближчі пів року

Графік побудовано на основі відповідей 40 компаній з топ-50

Плани щодо релокації спеціалістів за межі України в найближчі пів року

Графік побудовано на основі відповідей 40 компаній з топ-50


Повна версія топ-50 і дані минулих рейтингів доступні на сторінці jobs.dou.ua/top50.

Інфографіку підготував Ігор Яновський.


Підписуйтеся на Telegram-канал про українське IT «Редакція DOU», щоб не пропустити цікаві новини, статті, обговорення.

$2000 за рекомендацію та робота в оточенні друзів. Як працюють реферальні програми в ІТ

$
0
0

За даними опитування DOU, фахівці ІТ-сфери активно користуються реферальними програмами: 26,5% шукачів знаходять роботу завдяки рекомендаціям знайомих. Це найпопулярніший канал пошуку. І це не дивно.

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

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

Ілюстрації Уляни Морозової

Що передбачає реферальна програма

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

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

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

Здебільшого компанії потребують рекомендації спеціалістів рівня Middle/Senior, Software Engineer, Test Engineer, Test Lead, Technical Lead, Architect, Project Manager, Business Analyst, UX Designer.

В iDeals Solutions сума винагороди може становити до $2000. Щокварталу в компанії визначають п’ять найефективніших рефералів (незалежно від того, чи підписано внаслідок офер), і відзначають їхню активність додатковою винагородою. У перший тиждень після оголошення вакансії працівники компанії мають змогу отримати Hot Bonus — до $1000 за успішну рекомендацію.

Innovecs за влучну рекомендацію преміює на суму від $300 до $1000 залежно від позиції. В окремих випадках бонус може становити $1500 або $2000. Зокрема, на момент написання цієї статті, компанії для проєкту у сфері геймінгу потрібен Senior Fullstack Developer, а компенсація за допомогу в закритті цієї вакансії становить $2000. Рекомендувати кандидата може будь-хто.

Переваги для компаній

Постійна конкуренція за «таланти» ускладнює рекрутерам закриття всіх вакансій. Реферальні програми допомагають успішно наймати працівників.

Створити середовище однодумців, у якому комфортно працювати

В Intellias реферальна програма — це не просто інструмент рекрутингу, а важливий складник корпоративної культури. Рекомендації дають змогу створювати компанію однодумців, які поділяють спільні цінності.

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

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

Закривати «високорівневі вакансії»

60% спеціалістів компанії N-IX — рівня Senior, і вакансії переважно такого ж рівня. Відповідно рекомендації колег — найцінніше джерело висококваліфікованих кандидатів. Здебільшого всі вони успішно проходять співбесіди. За останній квартал 2019 року 12% вакансій N-IX закрито завдяки реферальним рекомендаціям.

У Boosta завдяки реферальним програмам закрито 16% вакансій за 2019 рік, а в перші роки функціювання компанії, на етапі активного розвитку, цей показник становив близько 50%. У MGID за рік закривають 30%, в EPAM — 25% вакансій, у Terrasoft — близько 20% (а це понад 300 релевантних кандидатів), в Innovecs — 19%, у NeoGames — 12% таких вакансій, як NET developers та QAs, у JetSoftPro — 8%.

Відсоток успішного проходження випробувального терміну, за даними MGID, становить 97%. У Boosta позиції Senior SEO Specialist закривають за рекомендаціями майже у 100% випадків.

«Реферальні програми — це наступний за результативністю інструмент після LinkedIn. Раніше цей показник становив 8–10%,але за останній рік активність зросла. Рекомендують як колег, так і друзів, знайомих», — зауважує Наталія Шулепа, Head of Talent Acquisition Department в Innovecs.

Розвиток бренду компанії

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

Переваги для працівників

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

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

Крім того, реферали допомагають «новачкам» легше вливатися в новий колектив. На умовах анонімності, редакції DOU розповіли історію, що це засвідчує: «Я шукала нову роботу впродовж трьох місяців. Коли в компанії відкрилася вакансія Project Manager, подруга, яка там працювала, надіслала моє CV. Хоча ми працюємо в різних офісах, але почали більше спілкуватися. Адаптуватися в компанії було дуже легко, оскільки подруга мені багато розповіла про процеси і познайомила з командами в перший же тиждень».

Звісно, один з мотивів рекомендувати когось — отримати фінансову винагороду.

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

Щоправда, не всіх цікавлять матеріальні бонуси. Delivery Manager з N-iX, що став «реферал-чемпіоном» у компанії, зазначає: «Мені легко продавати те, що до вподоби. А оскільки мені подобається працювати в N-iX, то я із задоволенням розповідаю про нові можливості в компанії своїм знайомим та ексколегам. У будь-якому разі це завжди люди, на яких я можу покластися. Головна мотивація для мене — не матеріальний бонус від компанії, а можливість запропонувати своїм друзям і добрим знайомим цікаву вакансію, і як наслідок — стати колегами. Рішення про прийняття на роботу від мене не залежить, але я завжди почуваюся відповідальним за фахівця, якого рекомендую в проєкт. Саме тому, перш ніж загітувати когось до нашого колективу, я запитую себе: „Чи поділятиме ця людина цінності компанії?“ і „Чи буде їй/йому цікаво саме на цьому проєкті?“ Якщо на обидва запитання відповідаю ствердно, то заохочую до команди, надсилаю покликання на опис вакансії та розповідаю те, що особисто знаю про команду/проєкт. Якщо людині це цікаво — передаю інформацію відповідальному рекрутерові і більше не втручаюся у процес. Дізнаюся вже фінальний результат. Торік п’ять моїх рекомендацій були успішними».

Загалом ІТ-фахівці ставляться до реферальних програм позитивно.

«Шукати роботу за реферальною програмою — круто, від цього всі виграють. Колега, що вас рекомендує, отримає бонус, якщо це можливо в компанії. Ви зможете докладніше дізнатися про проєкт ізсередини і, звісно ж, отримати рекомендацію. А роботодавець заощаджує ресурси. До компаній, у яких давно працюють ваші знайомі, більше довіри. Бо якщо знайомий задоволений роботою, то і вам буде комфортно там працювати. Але, крім матеріального плюса у вигляді бонусу, великою перевагою є також можливість зібрати на проєкті „dream team“ з ваших друзів. Саме так, ще навіть не пройшовши випробувальний термін, я вже встиг зарефералити 5 знайомих», — говорить Михайло Харист, Front-end Developer в PMLAB.

До речі, що відоміша компанія, то більше шансів потрапити до неї саме через рефералку.

«Користь від реферальних програм я реально відчув, перебуваючи у США. Надіславши своє резюме в Amazon, Facebook або Apple, на відповідь можеш чекати вічність або й узагалі не дочекаєшся, не зважаючи на твою кваліфікацію і „крутість“. Чому? Бо твоє резюме просто може загубитися з-поміж безлічі інших. Натомість за наявності бодай одного контакту в компанії з тобою можуть нереально швидко зв’язатися і запросити на інтерв’ю. Ба більше, деякі компанії не відкривають вакансії на своїх сторінках, а шукають перспективних кандидатів через своїх працівників», — розповідає Владислав Вчерашній, iOS Developer у Softwarium.

Цікаві кейси

Попри шаблонність реферальних програм, ІТ-компанії змагаються в креативності та підходах до побудови процесів. Редакція DOU зібрала найцікавіше.

Анастасія Хома, PR & Marketing Specialist в Skelia

Нещодавно ми вирішили видати комікс про пригоди Captain Referral, супергероя, що допомагає нашим колегам взяти участь у програмі. Комікс створили для нагадування про реферальну програму та для її популяризації. Простими словами з ілюстраціями роз’яснено, як працює ця програма.

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

Марія Лисюк, Recruiter в Astound Commerce

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

Якщо під час Hot Referral Week рекомендований кандидат успішно пройшов технічну співбесіду, але не впорався на фінальному інтерв’ю, колега з Astound, який надіслав резюме кандидата, отримує подарунок і сертифікат.

Упродовж останнього Hot Referral Week наприкінці минулого року ми отримали близько сотні рекомендацій кандидатів, з яких 7% успішно пройшли фінальну співбесіду та приєдналися до команди.

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

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

Буває хтось із подружжя вже влаштований у компанії і рекомендує свою другу половину. Лідером за такими рекомендаціями є наш вінницький офіс. Досить часто запрошують своїх друзів. І такі випадки є фактично в усіх офісах компанії.

Людмила Макаренко, координатор з маркетингу в EPAM Lviv

В EPAM Ukraine є кілька типів реферальних програм: постійна програма, всеукраїнські щоквартальні реферальні кампанії та локальні кампанії.

With a friend you can achieve more! — таке гасло має реферальна програма EPAM з рекомендації друзів і знайомих. Окрім грошового бонусу, ця програма передбачає збір і накопичення балів за кожен етап рекомендації (власне рекомендація, резюме, інтерв’ю, офер, вихід на проєкт, успішне проходження випробувального терміну), які згодом можна обміняти на сувенірну брендовану продукцію (стикери, браслети, горнятко/термос, наплічник, штормівка, павербанк тощо).
Щокварталу за кількістю балів визначають лідера. Це особа, що запропонувала найбільше кандидатів, і її рекомендації виявилися якісними. Лідер кварталу на свій вибір отримує заохочувальний приз. Зокрема, цього кварталу йдеться про Playstation, Apple Air Pods або робота-пилосмока.

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

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

Олена Якимчук, Communications Manager в N-iX

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

Цікаво, що завдяки одному із цих чемпіонів в N-iX успішно стартували два проєкти. Delivery Manager порекомендував двох лід-дивелоперів, з якими N-iX спочатку вдалося виграти тендер у клієнта, а потім — успішно запустити проєкти.

Марія Войно-Данчишина, PR / Event manager в в CodeIT

Якось двоє спеціалістів-чоловіків прилучили до співпраці з CodeIT своїх дружин. Одна із цих подружніх пар тепер як технічні ліди опікується двома різними відділами в компанії.

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

Оскільки в нашій компанії є своя програма навчання (для початківців розробників, тестувальників, бізнес-аналітиків і дизайнерів), то найбільше рекомендацій рекрутери отримують саме на позиції Trainee. Адже через програму навчання найлегше почати свою кар’єру в IT.

Анастасія Говорун, PR Manager в Boosta

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

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

Наталья Шулепа, Head of Talent Acquisition Department в Innovecs

Кроме материального вознаграждения, для сотрудников Innovecs есть специальный приз за активное участие в программе. Последние пару раз это были горные велосипеды Merida и Cannondale. Итоги реферальной программы подводим в среднем два раза в год. Так, в 2019 году вручение призов приурочили к зимнему и летнему корпоративам.

Марта Дуда, Employee Relations Specialist в ELEKS

Одного разу під час звичайного small talk у кімнаті колега, яка випадково почула про те, що рекрутери шукають керівника для одного з центрів компетенцій, згадала про фахівця, який, на її думку, ідеально підійшов би на цю посаду. Дівчина просто озвучила свою ідею вголос, а вже за 3 місяці була здивована повідомленням про нарахований бонус. Вона не скористалася вебсторінкою реферальної програми, не надсилала CV, однак рекрутери вирішили відзначити цю рекомендацію, адже вакансія була складна, важко було знайти потрібного кандидата, і саме випадковий коментар допоміг розв’язати проблему.

Ирина Харациди, Wargaming

Есть интересные случаи, когда несколько сотрудников долгое время работали в одном отделе страховой компании. Один из них уволился, закончил курсы по 3D-графике и попал к нам. Остальные по его примеру тоже пошли на курсы, переучились и пришли на собеседование в Wargaming. Теперь все они продолжают работать в одном отделе, но уже у нас.

Один сотрудник порекомендовал девушку, с которой они вскоре поженились. Теперь у нас в коллективе на одну семейную пару больше.

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

Были случаи, когда сразу несколько человек рекомендовали одного кандидата почти одновременно, так как очень уж хотелось работать в одной команде. Но у нас честная политика: кто первый внес резюме кандидата в ATS (Applicant Tracking System), тот и получает бонус.

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

Обмеження та недоліки

Рекрутер Astound Commerce Марія Лисюкзазначає, що реферальні програми добре працюють, якщо компанія розвивається й росте у звичайному темпі. У такому разі є можливість без особливого поспіху запросити до команди справді впевнених і досвідчених спеціалістів. Однак якщо плани з наймання різко зростають, з’являється більше замовлень від клієнтів і є дефіцит інженерів у команді, тоді варто вже додатково залучати інші канали та способи пошуку кандидатів.

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

Как измерить программиста

$
0
0

[Об авторе: Руслан Дмитракович — разработчик ПО и предприниматель, в ИТ-индустрии с 1994 года. Пионер интернет-рекламы в Украине: основатель Украинской баннерной сети, рекламного агенства «Интернет-эксперт». Создатель проекта Code X-ray —повышение эффективности работы команд разработчиков на основании статического анализа кода]

Решил свой рост узнать удав!
И в этом он, конечно, прав.
Ведь это важно очень!
Возможно, он длиннее всех!
Во много раз длиннее всех!
«38 попугаев» Г. Остер


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

Иллюстрация Ульяны Морозовой

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

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

Не все программисты «одинаково полезны»

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

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

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

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

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

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

Оцениваем качество работы

Оценить действия ближнего своего люди пытаются с давних времён. Решая эту проблему, индусы придумали понятие «карма»: последствия твоих действий влияют на твоё будущее. Та же идея применима к программисту, работающему над проектом. И в данном случае кармой является та сложность, которую программист привносит в проект. За это он и его коллеги будут расплачиваться в последующих итерациях потерянным временем и ошибками.

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

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

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

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

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

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

Пример

Наконец удав почувствовал, что его дёргают за хвост!
«Ага! — подумал удав. — Начали измерять!»


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

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

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

Для построения графиков использовались цикломатическая сложность, средний размер метода (в строчках кода), композитные метрики: weighted methods per classи сопровождаемость кода (maintainability).

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

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

Измеряем производительность

А как насчёт производительности? Есть мнение, что измерить ее в масштабах всего бизнеса невозможно, и с этим я спорить и не буду. Однако если оперировать не деньгами, полученными от работы ПО, а артефактами внутри программного проекта, то кое-что измерить можно. Корреляция между объёмом кода (строк, классов, методов и т. д.), написанного программистом, и функциональностью программы есть. Однако значимость кода в проекте не одинакова.

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

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

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

Однако как определить формально, какой код имеет больший вес? В своё время похожую задачу решали создатели Google по отношению к документам в интернете. И если мы можем использовать Page Rank для определения важности документа, то почему бы не применить его к коду?

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

Пример

И снова посмотрим, как это выглядит на примере нашего проекта.

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

Диаграмма ниже отображает суммарный вклад разработчиков в проект.

Те же данные в виде таблицы:

РазработчикиСтрок кодаСтрок кода, %ПакетовВклад, %
DEV-150К9366.94
DEV-236К7288.37
DEV-323К4156.2

Больше всего пишет DEV-1 (50 тысяч строк, или 9% кода проекта), но его средняя ценность почти в два (!) раза меньше, чем у DEV-3. Если учесть, что этот код ещё и более сложный, то можно понять, откуда берётся легаси — чем сложнее код и чем его больше, тем тяжелее его сопровождать. В какой-то момент может оказаться, что лучше такой код вообще не трогать...

И напоследок посмотрим, как выглядит вклад разных команд (по три разработчика в каждой).

Как видим, команды более-менее сбалансированы, вклад в проект у них примерно одинаковый.

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

Ну, и любопытный вывод для команды 2. Очень похоже, что техлид в ней действует по принципу «Хочешь сделать хорошо — сделай это сам»...

Выводы

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


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

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

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

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

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

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

$
0
0

It ain’t what you don’t know that gets you into trouble. It’s what you know for sure that just ain’t so.
Mark Twain

Вступление

Привет, меня зовут Ян, и я стараюсь применять свой более чем 10-летнийопыт работы с данными и системами в ИТ к своим проектам и бизнес-начинаниям. Это вторая статья из серии «Манипулируем пользователями». В первой публикациимы рассмотрели манипуляции с помощью логики и эмоций, здесь же мы спустимся на уровень ниже и уделим внимание триггерам и инстинктам — святому Граалю манипуляций и искаженного восприятия.

Решив посвятить свой проект AI.Deciderулучшению качества принимаемых пользователями решений с помощью NLP-технологий (не путать с НЛП) и специализированных инструментов для улучшения производительности, я столкнулся с огромной проблемой — ленью рода человеческого. Миллионы людей подбрасывают монетку, трясут шар-предсказатель 8 ball, крутят барабаны Decision Wheels в онлайне и на мобильниках и явно заинтересованы в сторонней помощи, принимая те или иные ежедневные решения. Но очень немногие из них готовы потратить пару дополнительных минут и существенно улучшить качество решения с помощью логики и интеллекта. Так что же их останавливает?

Самым очевидным ответом будет утверждение, что 95% людей не готовы напрягаться. Есть и более интеллектуальный ответ от Спольски — о проблеме курицы и яйца в продакт-менеджменте (Joel Spolsky: Chicken and Egg problem). Однако ни тот ни другой не поможет в продвижении к нашим целям.

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

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

Инстинкты

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

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

Итак, самое важное в этом определении — два утверждения: нам присуще сложное автоматическоеповедение, и оно меняется под влиянием приобретенного с годами опыта. Отлично, это именно то, что нам, коварным манипуляторам, и нужно!

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

Манипулятивная модель АРЕТ в Системе 1

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

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

  • Аctivating agent — это то, над чем вам предстоит поработать в своем продукте после прочтения этой статьи, триггер для воздействия на позитивное решение пользователя. Этот триггер может быть нацелен на одну (или на все) из последующих подсистем модели мозга пользователя.
  • Рattern matching — инстинктивный поиск паттерна на основании предыдущего опыта пользователя. Описание этого этапа полностью соответствует определению инстинктов.
  • Еmotions + Тhoughtsмы уже рассмотрели в первой статье о манипуляциях с помощью логики и эмоций.

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

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

Have you ever crossed the road, and looked the wrong way? A car’s nearly on you? So what do you do? Something very silly. You freeze. You just freeze and pull a stupid face. Snatch (Turkish)

Когнитивные иллюзии

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

Множество когнитивных иллюзий классифицированы и изучены. Вот некоторые из них:

  • эффект Да́ннинга — Крю́гера, ошибка выжившего (внезапно — тоже когнитивные искажения);
  • Bandwagon effect — миллионы мух не могут ошибаться («а если все с крыши прыгнут, ты тоже прыгнешь?!» — твоя мама);
  • склонность к подтверждению (факты, подтверждающие нашу точку зрения, кажутся более достоверными);
  • позитивный исход (преувеличиваем вероятность позитивного исхода и преуменьшаем — негативного);
  • ретроспективное искажение («я все это знал или подозревал ранее [на самом деле нет], но вспомнил об этом только сейчас»).

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

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

Ничего не делать, ничего не платить

Choose your Default Option wisely, Luke!

В странах, где в медицинской карточке стоит опция «отписаться от донорства органов» (модель opt-out, по умолчанию ты становишься донором), донорский рейт достигает 90%. Государства, где принята модель opt-in (опция «стать донором» по умолчанию отключена), рейт донорства составляет около 15%. Такая гигантская разница достигается всего лишь благодаря формулировке этого пункта в карточке и искусной манипуляции ленью пользователя.

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

WISIATI

What I see is all there is. Что я вижу — это все, что есть.

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

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

Иногда система 1 создает логически обоснованную неправдивую историю и скармливает ее системе 2 как правдоподобную. И тогда мы не просто принимаем решение, но и на 101% уверены, что оно верно!

Все, кто принимает неправильные решения, никогда не знают, в чем именно они неправы. Big Short

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

Приманка

Рассмотрим три опции подписки на газету:

только веб-версия — $5, только бумажная версия — $15, бумажная и веб-версии — $15.

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

Хотите неожиданное применение этой манипулятивной техники?

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

Прайминг

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

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

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

  • Ян: умный — старательный — импульсивный — требовательный — упрямый — завистливый.
  • Ян: завистливый — упрямый — требовательный — импульсивный — старательный — умный (ну явно два разных человека!).

Якоря

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

Донейшен с предустановленными цифрами — это классический микс якоря и WISIATI: вы были готовы пожертвовать доллар, а тут вам сразу подсовывают предустановленные варианты $5, $10, $20 — не будь жлобом!

HumbleBundle — чемпион по количеству якорей на странице чекаута.

Suggested price — $25. Top Contributors: В. Кожаев — $100.

Метафоры

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

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

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

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

Краткая классификация метафор для дальнейшего изучения:

  • Персонификация — он сердце нашей компании, у холмов есть глаза, плевок в лицо нашей нации, душа нации, лес шептал наши имена, nothing hugs like Huggies, курс акций подпрыгнул сегодня.
  • Путешествие — у нашей компании впереди длинный путь, нас не остановят крутые склоны, мы находимся на перекрестке.
  • Климат/природа — мы должны пережить этот шторм, ветер перемен, мы дождемся рассвета, арабская весна.
  • Еда — Apple, Blackberry, это оскорбление тяжело проглотить, мне надо переварить эту идею.
  • Семья и друзья — отцы-основатели, наш коллектив — дружная семья, мы переживем этот развод.
  • Инженерный — мчался на всех парах, ключ к твоему сердцу, шестеренки в голове, двигатель вместо сердца.

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

Персонификация

Did you know the human eye can see more shades of green than any other color? Do you know why? Fargo

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

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

Фрейминг

Этот стакан наполовину пуст. Нет, этот стакан наполовину полон.

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

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

Один из самых сложных концептов, в вопросе UX и продакт-менеджмента требует серьезного опыта.

Рефрейминг

Ну как же не упомянуть скандально известное НЛП в теме о манипуляции? =)

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

Самым известным примером принципа рефрейминга в современном мире я бы назвал играть в короткую/против рынка. Спросите 95% людей, как можно заработать, если рынок падает, и вы не получите ответа, только ждать дна и там покупать дешевле. Но для трейдеров это не секретные знания, а просто азбука работы на рынке: используя предпосылку рефрейминга о том, что любую ситуацию можно свести к своей выгоде, трейдеры открывают short position и потенциально на этом зарабатывают (если коротко: сегодня цена за яблоко 100 баксов, и падает; ты одалживаешь у соседа яблоко за 5, сразу же его продаешь за 100, ждешь дна цены, покупаешь яблоко за 90 и отдаешь его соседу, твой выигрыш — 100 — 90 — 5 = 5).

Конформизм, monkey see monkey do

You can’t be a nonconformist if you don’t drink coffee. South Park

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

Гиперболическое дисконтирование

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

Можете спросить у своих детей на примере конфет/торта, правдиво ли это утверждение.

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

Повторение, повторение, повторение

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

Чем чаще вы встречаете одно и то же событие/утверждение/объект, тем более знакомым, близким и привычным оно будет вам представляться.

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

Имя и стиль

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

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

Разве я смогу забыть название комплекса «Бані є бані» на Харьковском шоссе? Да и бренду Perdue не стоит выходить на рынок Украины без ребрендинга. Так что, дорогой читатель, к имени своего продукта надо относиться с уважением и учитывать региональные и другие особенности, представляя, как в разных ситуациях могут упомянуть именно ваш продукт, тем самым распространяя виральную рекламу.

Батончик «Марс»: получил прирост продаж на 5% во время высадки первого зонда на Марсе (реклама за счет бюджета НАСА).

Подростковая виральная песня Friday: 200 000 000 просмотров на YouTube с пиками просмотров по... пятницам!

Стиль коммуникации с пользователем также важен, он должен быть интегрирован в общий имидж вашего бренда (не прошло и двух статей, как я начал изъясняться как прожженный маркетолог, я ведь эксперт [ТМ]).

Пример стиля коммуникации, который может понравиться пользователям: короткие слова и предложения, неформальный стиль, KISS (keep it simple, stupid), одна идея на каждое предложение, активный залог, меньше наречий и прилагательных.

Юмор и эмпатия

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

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

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

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

Сравнение и безопасность

Ваша задача — реализовать safe space в своем продукте для пользователей-снежинок.

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

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

Дыхание

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

Я чувствовал вину. Ответственность. Как будто я виноват. Грязный. Посрамленный.

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

Секс

Да-да, это именно о вас, грудастые инста-хо-инфлюенсеры!

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

Манипулятивный продакт-менеджмент (вместо выводов)

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

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

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

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

Bonjour і Au revoir. 8 років у французькому ІТ, або Чому ця країна не для мене

$
0
0

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

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

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

[Назви підрозділів статті збігаються з назвами визначних творів французської літератури]

Таємничий острів

Туристична Тулуза. Джерело

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

Завдяки щедрому французькому урядові й диплому DALF C1 із французької мови 2010 року отримала статус BGF (Boursier de Gouvernement Francais) та продовжила навчання в L’institut national des sciences appliquées de Toulouse (INSA Toulouse) на 4-мута 5-мукурсах (еквівалент магістерки). Упродовж двох років отримувала стипендію, а також урядова програма сплатила внесок за навчання. Виш вибирала через програму N+I, де студенти можуть вступати до французьких навчальних закладів на основі онлайнового досьє. Щоб здобути стипендію, довелося піти на співбесіду в посольство й поспілкуватися з авторитетним журі.

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

Приїхала до Тулузи 1 вересня з величезною валізою, а навчання почалося через тиждень. Більшість студентів у групі були французи, що або вчилися там з першого курсу, або прийшли після підготовчого класу (classe preparatoire) чи після бакалавра (licence) в університеті. Переважна частина була на рік за мене молодша. Студенти до 30 років — це навряд чи про Францію. Не чула ніколи, щоб хтось брав gap year чи вступив після кількох років роботи. Навчання було дуже інтенсивне, починалося зазвичай о 8-йранку й тривало до 18-їмайже щодня.

Завдяки диплому з «клінгонської» мови мене звільнили від її вивчення, натомість вивчала семестр іспанську. У цій школі вимагали взагалі офіційно рівень DELF B2 для іноземців, щоб отримати диплом магістра. Усі предмети викладали французькою мовою і без перескладань, англійською я говорила тільки на уроках англійської. Треба було скласти 20 предметів з 24, щоб потрапити на 5 курс. Інженерні школи у Франції дуже спрямовані на практичний досвід, а це потребує пройти два стажування тривалістю 3 та 5 місяців після 4-гота 5-гокурсу відповідно. Це аналог написання диплому в Україні.

Також були й гуманітарні предмети. Не можна не згадати про місцевий варіант охорони праці (qualite, securité, environment), а також особливо меметичний предмет ейчар (ressources humaines). Там пояснюють усю суть французької меритократії: якщо ви не закінчили Ecole Polytechnique, Ecole Centrale Paris та ще кілька топів, то більшість заманливих позицій для вас закрита. Тобто не стати вам «зайчикам» великими чиновниками або швидко злетіти кар’єрною драбиною у французьких корпораціях. І справді, зарплати залежать від вишу, часто навіть на пізніх етапах кар’єри.

Коли ви не цікавитеся політикою, то вона обов’язково зацікавиться вами. Завжди стежила за європейською політикою, але саме президентські вибори 2012-гобули досить критичним моментом у житті. Простажуватися впродовж останнього семестру було необхідною умовою для здобуття диплома. 2011 року уряд Франції за розпорядженнямміністра внутрішніх справ Клода Ґеанафактично «заборонив» змінювати статус іноземних студентів не з ЄС після закінчення навчання. Сам Клод Ґеан — рідкісний мудак, корупціонер, поціновувач лівійської готівки, готівки загалом і полотен фламандців, але моя стаття, на жаль, не про нього. Оскільки більшість компаній зацікавлена брати людей на постійну роботу після проходження стажування, то це дуже ускладнювало його пошук. А також означало, що мені довелося б покинути країну. Вибори 2012-гозакінчилися гепі-ендом: на середині мого стажування переміг над злом Олланд і негайно скасував закон...

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

Втрачені ілюзії

Зрештою мені вдалося знайти стажування в компанії Capgemini, де я пропрацювала майже шість років фулстек-девелопером. Це еталонний бодишоп, який має щасливу 50-річнуісторію у Франції, а також успіхи в розширенні своєї мережі в інших країнах через acquisition. Більшість французьких компаній, особливо за межами Парижа, — це консалтингові компанії, що працюють або на публічний сектор, або на деякі великі компанії.

За всю свою феєричну кар’єру в Бордо я працювала на проєктах для різних міністерств. Їх об’єднувало використання французької в коді для назв змінних і функцій, навіть якщо це суперечило programming language naming convention. У кожному міністерстві був свій домашній (inhouse) фреймворк для розв’язання стандартних завдань, і використовувати його було основною вимогою. Зазвичай його підтримувала група досвідчених розробників, які будували свою кар’єру тільки в тому одному міністерстві, накопичуючи довгі відпустки.

Job security — вона така job security. Ще інколи міністерство могло нав’язати якусь third-party бібліотеку чи систему, бо її розробляє французька компанія. Прикладами такого підтримання вітчизняного виробника є CMS Spip, Jahia, мапи Mappy тощо.

Мені досить пощастило з проєктами з-поміж того, що могло трапитися. Першим моїм проєктом був Tipi — геоінформаційна система моніторингу трафіку на території Франції, інформацію з якої, наприклад, повідомляють по радіо Bison Futé. Цю систему встановлено в усіх регіональних центрах, там диспетчери вводять інформацію про якісь події або дані надходять у різних форматах, як-от Datex 1 і Datex 2.

Ще одним проєктом, який допоміг мені зрозуміти місцеве життя, був Pole Emploi, або служба зайнятості. Понад чотири роки я своєю щоденною працею намагалася зменшити безробіття у Франції. Це один з найвідвідуваніших сайтів у країні, над його створенням працює дуже багато команд. У цій державній компанії використовують Safe, а також Scrum на рівнях команд.

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

Життя і безробіття. Джерело

Собор Паризької Богоматері

ІТ-ринок країни, на мою думку, можна поділити на ринок Парижа й решти країни. У Парижі є продуктові компанії, і про деякі з них уже, мабуть, були статті раніше (сферичний Criteo чи BlaBlaCar). На решті території процвітають консалтингові компанії — аналог аутсорсу чи аутстафу. Інколи великі начальники з паризького офісу називають офіси в провінції nearshore, що багато про що свідчить. Паризькі офіси сидять на потоках перерозподілення проєктів, які потім «спускають» у регіони. Є також контрактори, що продають свої послуги або одразу клієнтам, або через посередників, тобто через ті самі консалтингові компанії. Є також невеликі стартапи чи продуктові компанії, про які рідко хто чув навіть на території певного регіону. Хоча деякі локації мають свою специфіку, наприклад у Тулузі сектор розвивається навколо Airbus, Thales та інших компаній, пов’язаних з оборонкою, космосом, авіапромисловістю.

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

Нотр-Дам у вогні. Джерело

Знедолені

2019 рік подарував дивовижне протистояння жовтих жилетів та Юпітера Макрона. Вони своїми зусиллями заважали будувати йому startup nation приблизно півроку. У поточному сезоні (тобто 2020-го)на передній план знову вийшли профспілки та інші представники пролетаріату: борються за збереження 42 різних пенсійних режимів. Що характерно, у країні ще часто використовується марксистська термінологія...

Юпітер. Джерело

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

«За нашими оцінками, поріг бідності становить 781 євро на місяць для однієї людини, 1518 євро для сім’ї з двох людей без дітей і 1999 євро для сім’ї з двома дітьми. До категорії малозабезпечених (30% найбільш скромних доходів) належать люди, для яких ці цифри будуть відповідно 1265, 2468 та 3302 євро. Середній клас — це дохід у діапазоні між 1265 і 2275 євро для однієї людини, між 2468 і 4423 євро для сім’ї без дітей, а також між 3302 і 5743 євро для сім’ї з двома дітьми. До категорії забезпечених входять сім’ї з доходами, вищими за вказані. Якщо вибрати поріг багатства як подвійний медіанний дохід, то багатою можна вважати людину з доходом 3125 євро щомісяця, 6072 євро для сім’ї без дітей та 7995 євро для сім’ї з двома дітьми».

А ще французи оцінюють, що потрібно 1760 євро на місяць, щоб жити.

Не писатиму багато про флуктуації цін на круасан, бо чимало з вас і так подорожували Францією. Оскільки тепер я живу в Лондоні, то залишу це тут. І справді, McDonald’s дорогий у Франції...

Стосовно витрат на життя, то, мабуть, половину їх становитиме рента. Ось варіантиоренди трикімнатної квартири.

Ще життя в переважній частині провінційних міст передбачає наявність авто в кожного члена сім’ї. Без нього неможливо дістатися до роботи й не тільки. У Бордо більшість ІТ-компаній розміщені не в центрі.

Якщо візьмемо абстрактну сім’ю з двох айтішників без дітей, які отримують по 2К євро щомісяця як середній клас, платять у Бордо 1К євро за ренту й комуналку, віднімемо вартість двох машин у кредит, вартість бензину 1,45 євро/л, їжу, одяг на розпродажі, розваги час від часу, — то залишиться небагато.

Мабуть, тепер зрозуміліше, проти чого протестували жовті жилети...

Народний бунт. Джерело

Щодо зарплат у галузі, то вони розподіляються на зарплати в Парижі та регіонах.

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

Здрастуй, печаль

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

Бюрократія у Франції відома на весь світ, тому, щоб розв’язати маленьке адміністративне питання, треба часто витратити багато енергії.

Можу навести приклад з отримання водійських прав. До того ще ніколи цього не робила, тому записалася до школи водіння. 20 уроків водіння + теорія коштували трохи більше як 1000 євро. Екзамен з практики полягає в 30-хвилиннійїзді містом та паркуванні двома способами. За незначні помилки екзамен не зараховували. І проблема полягала ось у чому: щоб перескласти його, треба було ставати в чергу, бо «в них нема місць», і наступна спроба була за 6 місяців. Щоразу доводилося брати додаткові 10 уроків, щоб згадати їзду (вартість 1 години — 41 євро). Я склала з четвертого (!) разу, тому вартість навчання майже зрівнялася з вартістю моєї автівки.

Уявний хворий

Мабуть, одним з небагатьох плюсів життя у Франції є її медицина. Недорога страховка покриває як звичайні, так і складні випадки, а також стоматологію. Більшість ліків за рецептом безплатні. Очевидно, завдяки цьому чинникові Франція і є однією з топових країн до виходу на пенсію. (Британські пенсіонери це знають, то й скупають «хрущезамки» XVIII сторіччя в провінції, насолоджуючись до кінця життя буржуазним лайфстайлом...) Хоча, як і скрізь у Європі, щоб потрапити до фахівців, треба чекати.

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

Навколо світу за 80 днів

Щоб зрозуміти французів і їхній погляд на світ, напевно, слід поцікавитися, як у середній школі викладають гуманітарні предмети (мови — рідну та іноземні, історію, географію, літературу). Уся освіта дуже франкоцентрична. Історія з географією — єдиний предмет: інколи вивчають історію, інколи — географію. Галльські племена, королі Франції та події Другої світової війни вивчають без хронологічного порядку. Світову історію — фрагментарно, якщо її сторінки не мають прямого стосунку до французької держави того періоду. Основ фізичної географії (геологія, орографія, кліматологія) або немає взагалі, або їх не засвоїла більшість місцевого населення. Про це свідчать рекурентні фрази, що їх згенерували різні представники:

  • «У нашій країні є гори і море». (Щоб підкреслити її унікальність).
  • «У Лондоні завжди дощ». (У цьому контексті малося на увазі, що сумарна кількість опадів у Лондоні більша, ніж на Атлантичному узбережжі Франції, але це твердження хибне: In Bordeaux, France, during the entire year, the rain falls for 124.2 days, and collects up to 944.1mm (37.2«) of precipitation vs London averages approximately 106 rainy days each year and receives a total of 22.976 inches (583.6 millimeters) of precipitation annually).
  • «В Україні у вас завжди холодно». (Якщо просто порівнювати сумарну сонячну радіацію, що залежить від географічної широти, то Київ не набагато північніше за Париж — 50.4501° N, 30.5234° E та 48.8566° N, 2.3522° E відповідно).

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

Найпопулярніший напрямок — Іспанія, країна відпустки (pays des vacances). Доступні ціни та лінгвістична спорідненість мов роблять свою справу.

Ще місцеве населення цікавиться країнами-сусідами, США, Канадою, Австралією, Японією та країнами Азії (див. Східна Європа). Особливим успіхом у молоді є досвід життя в названих вище країнах, куди вона їде за довгим доларом або його аналогом. Нова тенденція серед французьких експатів полягає у відправленні дітей на навчання у виші не в рідні краї (France metropolitaine), а в Канаду, США тощо. «Відіслала доню в Мак-Ґілл, бо він ліпше котується з нейронауки» (французька «жона» експата). Це справді початок кінця, а здавалося б...

Узагалі французи часто пишаються своєю країною. Одразу згадують всесвітньо відому кухню — спадщину ЮНЕСКО та багату історію. Це країна, де, за її термінологією, французам «добре жити» і «вони дуже привілейовані», але не втрачають нагоди поскаржитися на все підряд. Медіа нагнітають атмосферу висловлюваннями, нібито «ваші діти житимуть гірше, ніж ви».

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

Пані Боварі

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

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

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

Франція — країна менеджерів. Бувши просто експертом з технологій, важко просуватися кар’єрною дорогою. Є спеціальний термін cadre (вимовляється «кадр»). У дипломованих інженерів, зокрема й у мене, був цей статус, що зобов’язував encadrer інших людей (не «кадрити», а керувати та наставляти). Ще в нашому бодишопі деякі кадри вважали, що кодити зможе кожен, а бути менеджером — ні. Як ми знаємо, у кожному жарті є частка жарту...

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

Епілог

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

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

Додам тільки трівіа...

Коли отримала офер у JPMorgan, я мала відбути марафон у стартап Synthace. Ніде з ФААНГів, банків та інших компаній не застосовували такий апарат тортур. Після двох співбесід на розділяй та володарюй i ДП водили оглядати лабораторію.

На одній з них був присутній у ролі спостерігача сам гуру ютубу з підготовки до співбесід Джекссссооооннн Ґабббббаааарддддд. Тоді я подумала: «Як добре, що все закінчилося!»

Как подружить разработчика и менеджера

$
0
0

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

В любой статье на DOU о менеджерах легко найдется хотя бы один из следующих комментариев:

  • «Scrum не нужен, ведь деды пятилетками нейросети на перфокартах писали».
  • «Менеджеры — дармоеды. Только требования дайте, а дальше мы сами».
  • «Митинги — зло. Договаривайтесь без меня, но чтоб по-моему решили».
  • «Софт-скилы для софт-людей. Лучше про код думайте».
  • «JavaScript не язык, Front-End не программист».

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

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

Иллюстрации Каталины Маевской

Война миров

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

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

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

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

— Друг, нужна таблица с котятами!
— Не вопрос. А сколько планируется котят в системе?
— Ну 5–10...А может, и 1000.
— Хм, 1000 котят... Надо прикрутить пагинацию, сделать ленивую подгрузку, проверить на разных девайсах и скоростях... Нужен месяц.

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

Во-первых, огромный разброс по исходным данным в требованиях. Так пара десятков котят или пара тысяч? Откуда эти цифры? Поскольку менеджер живет в вероятностном мире, он видит возможность того, что котят будет именно 1000. Даже если такой человек будет один, а у остального миллиона пользователей будет от 5 до 10 котят. Почему бы не сделать продукт хорошим для всех?

А что услышал программист? Он услышал о лимите в 1000. Но ведь когда он будет писать код, то не сможет только чуть-чуть поддерживать определенный кейс. Его надо будет либо поддерживать, либо нет. Соответственно, он проектирует решение под 1000 котят, хотя в 99% случаев их будет на несколько порядков меньше. Отсюда и месяц.

При этом стоит лишь немного поменять диалог, и эта проблема исчезнет сама собой:
— Нужны котята в таблице!
— О’кей, сколько их?
— От 5 до 10. А если 1000, то насколько дольше будет?
— Ну для 5–10 ясделаю за 3 дня, а для 1000 — за месяц.
— Много котов в одной таблице к беде. Делай для 5–10,а там посмотрим.

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

Приведенный пример демонстрирует очевидную вещь: в большинстве проблем виновата коммуникация. О ней далее.

Мисс коммуникация

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

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

Детали имплементации

Разработчики, внимание: далее следует жестокая правда! Менеджерам абсолютно, тотально, невероятно и глубоко фиолетово плевать на то, как вы реализуете фичу в техническом плане. Их интересует другое: насколько быстро, качественно и надежно вы ее сделаете. И эта осознанная невежественность — не капризы или лень, а необходимость. Это ваша работа, а им зачем влезать в нее? У них своей хватает. Ведь вы и сами беситесь, когда к вам лезут с советами.

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

Синкапы

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

Отсюда эти вечные вопросы:

— «На каком ты этапе?»
— «Успеваешь уложиться в эстимейт?»
— «Получится залить сегодня на стейдж?»

Чаще всего эти вопросы задаются не с целью давления, как кажется разработчикам, просто менеджеры искренне не знают! Помню, как меня напрягало, когда в течение дня мне писала ПМ: «Привет! Как дела? Успеваешь доделать?» Сейчас я ее понимаю: есть обязательства и встречи с клиентами, на которых она должна либо показать, что обещали, либо объяснить, почему не успели. Это ее работа. Но для меня это выглядело как постоянный прессинг, особенно когда понимаешь, что с эстимейтом промахнулся.

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

Назад в будущее

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

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

Так возникают ситуации, в которых каждый пытается перетянуть другого в свою временную линию:

  • тестировщики дергают программистов в прошлое («Можешь глянуть? Я тут кликаю задачу, которую ты неделю назад двинул в QA, и...»);
  • программисты тянут менеджеров в настоящее («Я тут читаю acceptance-критерии, и это какая-то дичь. Почему...»);
  • а менеджеры тянут программистов в будущее («Нужно, чтобы ты взглянул на эту фичу и примерно оценил. И что значит дичь?!»).

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

«Эй, ты не занят?»

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

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

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

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

Cloud microservice blockchain multi-tenant AI solution

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

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

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

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

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

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

Мир, труд, скрам

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

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

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

Помимо всего этого, есть довольно простая причина жить дружно: так приятней. Ведь круто работать в дружном коллективе, где все друг друга понимают, поддерживают и помогают? Может, я и наивен, но стремиться к этому стоит.

Поэтому закончу цитатой Джима Джеффриса, которая в своей простоте прекрасно суммирует то, к чему я так долго веду: «Try not to be a cunt, and if you do that every day, you’ll be a good person».

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

Классных вам проектов и легких апрайзалов! До новых виртуальных встреч!


Зачем и как UX-дизайнеру быстро визуализировать данные

$
0
0

Я в дизайне 6 лет, и когда меня спрашивают, чем я занимаюсь, я обычно говорю: User Experience. Сложнее ответить, когда спрашивает мама. Тогда получается что-то вроде этого: «Я работаю с инженерами-нефтяниками уже 4 года и создаю для них интерфейсы, автоматизирующие их работу: например, визуализирую данные или разрабатываю интерфейс управления оборудованием, которое они с помощью лебедки погружают в нефтяную скважину». Для веб-дизайнера это может звучать пугающе, для инженера — непонятно и размыто.

Хотя самое приятное в моей работе — это видеть восторг на лице инженера, когда по результатам проведения интервью и подготовки технических спецификаций в процессе тестирования они видят цельный и простой интерфейс, приговаривая: «I love it». В этой статье я расскажу о своих принципах работы с данными, о том, как я строю графики и продумываю их интерактивность, поделюсь чек-листами, кейсами и лайфхаками визуализации инженерных данных. Эти приемы я использую в своей работе каждый день и проверила с помощью регулярных сессий пользовательского тестирования.

Что не так с дашбордом

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

А ведь хороший график должен обладать рядом особенностей, которые великолепно описаны в книге Эдварда Тафти «Visual Display of Quantitative Information»под общим названием «Графическое совершенство» (Graphical Excellence).

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

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

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

Одни дизайнеры часто копируют структуру дашборда, повторяя визуальные решения и пытаясь вписать поток бесконечных правок в резиновый дашборд. Вторые безропотно перерисовывают в UI наброски барчартов и пайчартов, полученные от Product Owner. Но реальные данные заказчика не статичны и порой непредсказуемы. А что, если они будут обновляться в реальном времени? А что, если будет 20 колонок в таблице с таким форматом чисел: 99.123,1234? А что, если за прошлый год будут нулевые продажи?

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

О данных в дизайне

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

Чаще всего в интерфейсах попадаются такие типы данных:

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

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

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

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


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


101 по типам графиков

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


Bar chart (столбчатая диаграмма) показывает категории. С его помощью можно показать, что за прошлый год менеджер продал 16 машин на бензине, 4 дизельных автомобиля и 30 электрокаров. Тут важна только одна ось (в моем случае Y), а ось X условна и существует только для того, чтобы разместить лейблы категорий. Барчарт легко спутать с гистограммой. Чтобы проверить, барчарт это или нет, поменяйте столбики местами — смысл графика не потеряется.


Stacked bar chart (столбчатая диаграмма) позволяет показать те же данные, но уже с разбивкой внутри категории. Например, можно увидеть, что из 16 бензиновых авто 4 продали в базовой комплектации, а остальные 10 — в полной.


Box and whisker plot («ящик с усами» — это не то же самое, что биржевые свечи). Один ящик — это одна категория, например электрокары. Допустим, по оси Y мы анализируем цену продажи этих авто. Ящик покажет нам, какова была средняя цена продажи в этой категории (медиана), а также каков был разброс цен внутри этой категории, минимальные и максимальные значения (усы).


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


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

Анатомия графика и чек-лист дизайнера

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

А также отвечаю на вопросы из этого чек-листа по настройкам, потому что дизайн напрямую зависит от ответов:

  • График статический или динамический?
  • Данные исторические или real-time?
  • Сколько осей? Можно ли менять их количество? Скрывать оси? Number of Axis.
  • Сколько переменных? Можно ли менять их количество? Скрывать переменные? Number of Variables.
  • Какие используются единицы измерения? Units of Measure.
  • Какова плотность сетки? Gridlines Density.
  • Нужны ли фильтры? Filters.
  • Нужны ли настройки масштаба шкал? Scale Adjustment.
  • Нужна ли легенда? Кликабельна ли она? Key.
  • Какая интерактивность поддерживается? Interaction.

Почти все современные библиотеки визуализации (например, ECharts) используют встроенные инструменты взаимодействия с графиком, которые я включаю в отдельный чек-лист Interaction:

  • фильтры;
  • индикаторы;
  • сравнение;
  • переключатели;
  • toggles;
  • ховеры;
  • манипуляции (масштабирование, жесты).

Для real-time в дизайне особое внимание я обращаю на такие моменты:

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

Кейсы, примеры, заготовки

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

Цели

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

Средние значения

Если данных много, они меняются в определенном промежутке времени, а пользователю нужно провести анализ за выбранный диапазон, чтобы принять четкое и понятное решение, то помогут средние значения. Хорошими примерами вывода средних значений служат приложение «Здоровье» в iOS и статистика в Instagram:

Светофор

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

Что такое хорошая визуализация

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

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

Подытожу

Работая с финансовыми или инженерными системами, B2B- или B2C-продуктами, дизайнер все время показывает данные в интерфейсе. Даже самые громоздкие и высоконагруженные интерфейсы можно разложить на смысловые блоки и оптимизировать представление. Для этого я рекомендую:

  1. Придерживаться принципов Graphical Excellence.
  2. Понимать основные типы данных и применять к ним базовые типы визуализации.
  3. Пользоваться чек-листом по анатомии графика.
  4. Пользоваться чек-листом по интерактивности.
  5. Создать свои заготовки для наиболее типичных кейсов и применять их.
Если выйти за рамки UI и научиться понимать данные, которые стоят за ним, можно усилить интерфейс и улучшить юзабилити, приходя к элегантным и понятным графическим дизайн-решениям.

Розробка opensource- та приватних Composer-пакетів: як це робити і навіщо

$
0
0

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

Composer

Майже кожен PHP-розробник знає про Composer. Це менеджер пакетів, який революціонував PHP і дав дуже потужний поштовх для розвитку цієї мови.

Тепер для того, щоб використати у своєму проєкті напрацювання інших девів, розробникам не треба завантажувати PHP-файли, копіювати код і робити інші, дивні для сучасної розробки, налаштування. Достатньо просто знайти потрібний пакет на packagist.orgі виконати команду composer require author/package-nameабо composer install, якщо потрібно встановити пакети з попередньо сконфігурованого файлу composer.json.

Самі пакети створила велика спільнота розробників, кожен з яких робить свій внесок у opensource-спільноту і розвиток мови.

Для чого розробляти пакети

Давайте розберемося, для чого розробники створюють composer-пакети — яка в них мотивація?

Ось декілька головних чинників для opensource-пакетів:

  • відчуття внеску в спільноту, тому що таким чином розвивається технологія;
  • покращення свого резюме, тому що opensource-проєкти — це дуже хороше доповнення до портфоліо;
  • удосконалення якості свого коду, бо знаючи, що код потенційно може подивитися велика кількість людей, програміст автоматично намагається написати якісний і продуманий код;
  • just for fun, просто тому що це весело. Також це перевірка пул реквестів, розвиток чогось свого, фідбек від колег.

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

Кожен пакет починається з composer init. Щоб створити пакет, потрібно виконати команду composer init у директорії пакету.

Composer запропонує вам декілька стандартних запитань. Поки що можемо просто пропустити їх.

Composer також запропонує вам інтерактивно обрати залежності — вибираємо no, бо пакет, який створюємо, не матиме залежностей на цьому етапі.

У результаті, створиться файл composer.json — файл з конфігурацією.

composer.json
{   "name": "igorrebega/uawords",   "authors": [       {           "name": "Igor Rebega",           "email": "example@bvblogic.com"       }   ],   "require": {}
}

Autoloading

Щоб Composer міг працювати з namespace й правильно підключати файли, нам потрібне автозавантаження за форматом PSR-4. Будемо складати наш код в папку /src.

Відредагуємо composer.jsonтаким чином, додавши секцію autoload:

{ "name": "igorrebega/uawords", "authors": [   {     "name": "Igor Rebega",     "email": "example@bvblogic.com"   } ], "require": {}, "autoload": {   "psr-4": {     "IRebega\\UaWords\\": "src/"   } }
}

Виконаємо команду composer dump, яка створить файл для автозавантаження.

На цьому етапі ми готові робити наш перший клас:

src/WordFactory.php<?php

namespace IRebega\UaWords;

class WordFactory
{   public function hello()   {       return 'Привіт!’;
   }
}

Для тестування створимо файл index.php:

index.php<?php

include 'vendor/autoload.php';

echo (new \IRebega\UaWords\WordFactory())->hello() . PHP_EOL;

І запустимо скрипт за допомогою команди php index.php.

Як бачите, автозавантаження працює.

Тестування

Якщо ви хочете, щоб вашим пакетом користувалися інші розробники, вам потрібні тести.

Для цього використаємо фреймворк PHPUnit. З урахуванням того, що він нам потрібен тільки для розробки, додамо його як dev-залежність, виконавши команду composer require --dev phpunit/phpunit (це змінить composer.json-файл).

Тепер давайте створимо папку для тестів і назвемо її tests. Також додамо автозавантаження для неї (секція autoload-dev):

composer.json

Перший тест

Код тесту:

tests/WordFactoryTest.php<?php

namespace IRebega\UaWords\Tests;

use IRebega\UaWords\WordFactory;
use PHPUnit\Framework\TestCase;

class WordFactoryTest extends TestCase
{   public function test_it_is_not_null()   {       $this->assertNotNull((new WordFactory())->hello());   }
}

Щоб його запустити, нам потрібен файл з налаштуваннями phpunit — phpunit.xml:

<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="vendor/autoload.php"        backupGlobals="false"        backupStaticAttributes="false"        colors="true"        verbose="true"        convertErrorsToExceptions="true"        convertNoticesToExceptions="true"        convertWarningsToExceptions="true"        processIsolation="false"        stopOnFailure="false">   <testsuites>       <testsuite name="bvblogic test suite">           <directory>tests</directory>       </testsuite>   </testsuites>   <filter>       <whitelist>           <directory suffix=".php">src/</directory>       </whitelist>   </filter></phpunit>

Можете використовувати цей код як шаблон своїх пакетів. У більшості випадків вам потрібно буде змінити тільки testsuite name параметр.

Детальніше можна прочитати тут.

Тепер давайте запустимо наш тест командою ./vendor/bin/phpunit:

Вітаю! Наш перший тест пройшов успішно.

Використовуємо пакет локально

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

Для демонстрації створюємо новий проєкт й ініціалізуємо його за допомогою composer init.

Далі спробуємо виконати команду composer require igorrebega/uawords.

Пакет не буде знайдено, тому що composer за замовчуванням використовує сервіс Packagistдля пошуку пакетів.

Але ми можемо вказати йому свій локальний репозиторій. Для цього додаємо в composer.json тестового проєкту такий код:

"minimum-stability": "dev",
"repositories": [ {   "type": "path",   "url": "../uawords" }
]

Де url — це відносний або абсолютний шлях до папки з пакетом. А minimum-stability вказаний для того, щоб мати змогу використовувати dev-версії пакетів.

Знову виконаємо composer require igorrebega/uawords:

Далі створимо файл index.php:

index.php <?php

require 'vendor/autoload.php';

echo (new \IRebega\UaWords\WordFactory)->hello() . PHP_EOL;

Запустимо його командою php index.php і отримаємо «Привіт!» у консолі.

Додаємо пакет у Git

Виконуємо команду git init. Додаємо файл .gitignore з таким вмістом:

.gitignore

vendor
composer.lock

Додаємо всі інші файли в Git і пушимо на GitHub.

Додаємо пакет у Packagist

Переходимо за цією адресою, реєструємося і вказуємо посилання на GitHub. Далі підтверджуємо створення пакету.

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

Додаємо версії

Для версій ми будемо використовувати Semantic Versioning. Докладніше можна прочитати тут — semver.org.

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

  1. MAJOR — ті зміни, які можуть зламати код користувача, якщо він використає вищу версію пакету, ніж у нього був.
  2. MINOR — удосконалення, які додають функціонал, але не ламають код, який використовує старий функціонал.
  3. PATCH — зазвичай для багфіксів.

Отже, заходимо в GitHub, потім releases:

Натискаємо create a new release, вводимо інформацію про реліз і тиснемо Publish release.

Тепер переходимо на сторінку свого пакету в Packagist, тиснемо оновити і маємо побачити, що версія змінилася на 1.0.0. Саме вона буде використана за замовчуванням:

Рекомендуємо декілька змін заливати в одну версію, щоб ваш пакет був стабільний і ви мали досить часу протестувати новий код.

Travis CI

Тепер зробімо так, щоб тести запускалися автоматично. Для цього використаємо сервіс Travis CI.

Реєструємося, синхронізуємося з GitHub і вибираємонаш репозиторій:

Додаємо до проєкту файл з налаштуваннями travis:

.travis.yml

language: php

php:
 - 7.2 - 7.3 - 7.4

env:
 matrix:   - COMPOSER_FLAGS="--prefer-lowest"

before_script:
 - travis_retry composer update ${COMPOSER_FLAGS}

script:
 - vendor/bin/phpunit

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

Після того як ви запушите, Travis автоматично виконає тести й сповістить вас про результат.

StyleCI

Тепер давайте подбаємо про єдиний формат написання коду. У цьому нам допоможе сервіс StyleCI.

Після реєстрації переходьте на сторінку Repos і включіть StyleCI для свого репозиторію.

Також пропонуємо перейти до Repositories setting та обрати бажаний рівень автоматизації. Для opensourсe-проєктів часто підходить Automatically send and merge fix pull requests:

Він буде автоматично надсилати і мержити пул реквести із змінами code style.

Тепер нам потрібно додати файл конфігурації в проєкт:

.styleci.yml

preset: laravel

Таким чином ми будемо використовувати code style фреймворку Laravel. Після пушу ви маєте побачити, як StyleCi автоматично пофіксить усі проблеми з code style.

Ліцензія

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

Тутможна прочитати більше про MIT і скопіювати текст ліцензії.

Пропонуємо так і зробити, створивши файл LICENCE.md, змінивши [year] [fullname] секції та вставивши текст ліцензії туди.

Далі ви маєте побачити на GitHub іконку MIT-ліцензії:

Readme

Якщо ви хочете, щоб про ваш пакет дізналися більше, вам обов’язково треба створити readme-файл.

Пропонуємо скористатися сервісом Makereadme.

Далі додаємо завантажений файл README.mdдо репозиторію.

Додаткові ресурси

Як бачите, процес створення пакету справді займає чимало часу. Щоб вирішити цю проблему, було створено багато сервісів, які можуть згенерувати вам порожній проєкт, який ви потім можете використовувати. Наприклад, Laravel Package Boilerplate.

Приватні пакети

Нещодавно Packagist запустив комерційну версію, яка дозволяє створювати приватні пакети — Packagist.

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

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

Наступні кроки

Сподіваюся, ця стаття надала вам потрібні для створення пакетів інструменти. А якщо треба додаткові приклади, то рекомендуємо вам переглянути найпопулярніші PHP-пакети на GitHub.

Как сделать мобильное приложение с помощью JS. Путь React Native

$
0
0

Привет! Я работаю с Front-end уже 4 года, люблю JavaScript и современный рэп. Если вам это кажется странным, то, пожалуйста, не читайте дальше.

Свою карьеру в IT я начал с PHP и верстки, потом мне на пути повстречалась поддержка серверов на nginx и Apache, работа с SQL-базами данных, Yii 2 и Symfony. Затем увидел jQuery и мне показалось, что это магия (в этом месте фронтенд-разработчики должны надорвать животики). С того момента начал больше времени уделять фронтенду и со временем решил стать JS-разработчиком. Сейчас я умею в ReactJS, Redux, React Native (как вы поняли), имел опыт с монструозной CMS на Java и лидингом других разработчиков. Именно во время работы в AB Soft я максимально погрузился в мир Front-end и JS.

Если вы хотите связать свою жизнь с разработкой приложений, то лучше обратиться к Swift, Kotlin, Objective-C, Java. В общем, к чему-то более нативному. Ну и выбрать приоритетную для себя платформу для разработки (потому что дешевле будет писать для того же Android). Но! Если вы уже и так плывете по IT-миру на волне JS и его хайповых фреймворков, то велкам! Почему бы не попробовать React Native?

Дисклеймер.Спешу расстроить: Snapchat вы на нем не напишете :)

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

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

Самый легкий путь — юзать Expo

Expo — это фреймворк (фреймворк для фреймворка, прикинь о_0) и платформа, которая во многом облегчает жизнь начинающему разработчику или разработчице на React Native:

  1. Дает возможность разрабатывать и тестировать приложение без использования Xcode или Android SDK и их экосистем.
  2. Дает стартовый кит с готовым приложением и парой экранов. Здесь вы можете поковыряться и закрасить пробел в резюме.
  3. Имеет обширную и понятную документацию (на английском).
  4. Дает очень удобную систему тестирования своего кода и UI-приложения без необходимости создавать установочный файл. Можно даже открывать свое приложение по ссылке.
  5. Предоставляет огромное количество уже готовых инструментов и АПИ для работы с модулями устройств (акселерометр, камера, файловая система, уведомления и т. д). Полный список можно посмотреть здесь.
  6. Предоставляет свои сервера и окружение для сборки приложения и компиляции его в нативный исполняемый файл.
  7. Автоматически менеджерит ваши сертификаты и подписи Play Market и Apple Store.

Ограничения Expo:

  1. Не поддерживает много нативных библиотек (написанных на Objective-C, Swift, Kotlin и т. д.).
  2. Жестко привязан к определенной версии React Native.
  3. Ваше приложение будет иметь относительно большой размер.
  4. Если захотите отсоединить свое приложение от Expo (например, чтобы использовать парочку нативных модулей), то готовьтесь просидеть над этой задачей не один час.

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

Прежде чем начать

Необходимо иметь предустановленное ПО:

  • последнюю стабильную версию Node.js (скачать);
  • систему контроля версий Git (скачать).

Далее устанавливаем интерфейс командной строки для Expo.

npm install -g expo-cli

Если вы счастливый обладатель компьютера от Apple, то лучше установить в придачу watchman. Хотите тестировать свое приложение на физическом девайсе — установите на него приложение Expo: iOSили Android. Также можно использовать в качестве тестовой платформы эмуляторы. С их установкой разбирайтесь сами: iOS (для эмулятора iOS понадобится macOS) и Android.

«Ну давайте уже кодить!» — скажет нетерпеливый читатель, и будет прав

Напишем небольшое приложение наподобие Pinterest. В нем будет разбивка по категориям, галереи, картинки и API-коллы.

Запускаем команду expo cli для создания пустого проекта.

expo init

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

При выборе шаблона начального приложения выбираем blank template. Если вы знакомы с TS, то можете применять шаблон на TypeScript. Но мы же тут собрались не для того, чтобы что-то типизировать!

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

Дальше Expo создаст папку с проектом под тем названием, которые вы указали в slug, и сам установит необходимые зависимости. Если вы все сделали правильно, то при запуске команды npm run start у вас в консоли отобразится информация о том, что приложение сбилдилось, и появится QR-код для открытия его в приложении Expo. В браузере откроется соответствующая страница, в которой также будет консоль live reload и UI для запуска эмуляторов.

Если хотите запустить приложение сразу на эмуляторе, то можно воспользоваться командами npm run iosи npm run android соответственно.

Полный список команд можно просмотреть в ./package.json и здесь.

В симуляторе вы должны будете увидеть что-то типа этого:

Экраны

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

В нашем приложении будет 2 экрана:

  1. Главный со списком всех категорий картинок.
  2. Галерея картинок соответствующей категории.

Создаем папку Screens. В нее будем класть файлы с компонентами экранов.

Перед тем как начнем писать код для UI-компонентов, хочу рассказать вам о самом лучшем букмекере (шутка!)... о библиотеке с кросс-платформенными компонентами для RN.

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

npm install native-base

Первым будет заглавный экран CategoriesList.

Он будет выводить список категорий картинок. В реальном приложении вы будете запрашивать этот список у своего API. Мы же храним его, как и прочие утильные файлы, в папке ./data.

data/categories.js

const list = [   {       name: 'Architecture',       alias: 'architecture',       collection: 'https://firebasestorage.googleapis.com/v0/b/learn-rn-bb59c.appspot.com/o/architecture.json?alt=media&token=b5583dd0-2dbd-4cb9-a91f-76f8e7a0538a'   },   {       name: 'Food',       alias: 'food',       collection: 'https://firebasestorage.googleapis.com/v0/b/learn-rn-bb59c.appspot.com/o/food.json?alt=media&token=8b97fcc5-b802-459a-9080-9bd3d49032a6'   },   {       name: 'Abstract',       alias: 'abstract',       collection: 'https://firebasestorage.googleapis.com/v0/b/learn-rn-bb59c.appspot.com/o/abstract.json?alt=media&token=c7012570-af3f-4f9b-acd9-ad1a9827d837'   },   {       name: 'Pets',       alias: 'pets',       collection: 'https://firebasestorage.googleapis.com/v0/b/learn-rn-bb59c.appspot.com/o/pets.json?alt=media&token=f866e7c7-ed4b-46e9-b7c7-ef4b2242b245'   }
]; 
export default list;

Свойство collection — это ссылка на JSON-файл с набором картинок с сайта. Позже мы будем к нему обращаться по API и выводить эти прекрасные картинки.

screens/CategoriesList.js

import React from 'react';
import { List, ListItem, Text } from 'native-base';
import { ScrollView } from 'react-native';
import list from '../data/categories'; 
class Categorieslist extends React.Component {   constructor(props) {       super(props);       this.state.categories = list;   }    state = {       categories: []   }    render() {       return (           <ScrollView>               <List>                   {                       this.state.categories.map((item) => {                           return (                               <ListItem key={item.alias}>                                   <Text>{item.name}</Text>                               </ListItem>                           )                       })                   }               </List>           </ScrollView>       );   }
} 
export default Categorieslist; 

Как видите, главное отличие от React’а, на первый взгляд, заключается в тегах jsx. Здесь мы не используем теги HTML (из которых в большинстве случаев состоят наши реактовские компоненты). Вместо них применяем нативные компоненты, предоставленные библиотекой React Native, которые компилируются в нативные представления платформ.

Несколько слов о готовых компонентах, которые мы использовали в основе UI.

<ScrollView /> — контейнер для отображения контента, который, возможно, необходимо скроллить.

 <List />и <ListItem /> — список и элемент списка соответственно из библиотеки Native Base. Они уже имеют стилизацию в соответствии с iOS- и Android-гайдами.

Думаю, название тега <Text />говорит само за себя.

Список категорий

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

import React from 'react';
import CategoriesList from './screens/CategoriesList'; 
export default function App() { return (     <CategoriesList /> );
}

Если вы не выключали команду npm run, то уже можете лицезреть результат на экране эмулятора. Выключали? Тогда запустите еще раз: npm run iosили npm run android.

Если вы установили на свой девайс Expo client и хотите открыть приложение в нем, просто отсканируйте QR-код из терминала. На экране вы должны увидеть это:

У вас все так и выглядит? Я вас поздравляю! А если нет, то просто сравните свой код с тем, который написан в статье.

Делаем сетку картинок

У Pinterest очень интересная сетка с картинками. Ее аналог в простонародье известен под названием Masonry. Добрые люди уже запилили его в виде npm-пакета. Но пока мы с ним заморачиваться не будем, лучше погрузимся в работу и стилизацию нативных компонентов и компонентов NativeBase.

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

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

components/ImageGrid.js

import React from 'react';
import {Card, CardItem} from 'native-base';
import {View, ScrollView, StyleSheet, Dimensions, Image} from 'react-native'; 
/**
* Получаем объект экрана через API RN
* чтобы в дальнейшем использовать для расчетов ширину
*/
const window = Dimensions.get('window');
const imagesWidth = window.width - 20; 
export default class ImageGrid extends React.Component {   render() {       const { list } = this.props;        return (           <ScrollView>               {list.map((item) => {                   const imageRatio = imagesWidth/item.width;                    return(                       <View key={item.url} style={styles.cardWrapper}>                           <Card style={styles.card}>                               <CardItem style={styles.cardItem}>                                   <Image source={{uri: item.url}}                                       style={{                                           ...styles.image,                                           height: item.height * imageRatio                                       }}                                   />                               </CardItem>                           </Card>                       </View>                   );               })}           </ScrollView>       );   }
} 
const styles = StyleSheet.create({   cardWrapper: {       borderRadius: 20,       marginBottom: 10   },   card: {       borderRadius: 20,       marginLeft: 10,       marginRight: 10   },   cardItem: {       paddingLeft: 0,       paddingRight: 0,       paddingTop: 0,       paddingBottom: 0   },   image: {       height: 300,       width: '100%',       borderRadius: 20,       width: imagesWidth   }
});

Стилизация

Из react-native мы здесь импортируем StyleSheet. Это класс, который обеспечивает доступ к абстракции стилизации (как CSS). С помощью метода Createсоздаем объект, содержащий ссылки на конкретные наборы стилей. Имена ссылок соответствуют названиям свойств объекта. Сами же стили присваиваем компоненту с помощью пропса style. Также мы можем передавать в styleпросто объект.

<Text style={{color: #ccc}}>Some text</Text>

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

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

Также вы наверняка обратили внимание на компоненты Cardи CardItem. Это компоненты из библиотеки NativeBase, которые мы берем для того, чтобы не заморачиваться со стилизацией и позиционированием элементов картинок. Также в этих компонентах можно размещать множество разных наборов контента: текст, заголовки, кнопки, фоновые изображения и т. д. За подробностями идите в доку. В CardItem мы передаем параметр button={true}, что позволит карточке вести себя как кнопка.

Картинки

Теперь необходимо отдельно упомянуть компонент Image. Он стилизуется так же, как и остальные компоненты, имеет обязательный параметр source, с помощью которого указываем путь картинки, которую хотим вывести. Есть два способа это сделать:

  1. В sourceпрокидывать require (‘image/path.png’) для локальных картинок. Однако если вы попытаетесь динамически генерировать строку внутри require, у вас ничего не получится: RN будет в этом месте ломаться.
  2. Указывать объект типа {uri: ‘https://remote.image/path.png’}. В этом случае вы указываете URL удаленной картинки, которую ваше приложение должно будет подгрузить. Также в uriможно передавать строку формата base64, однако если у вас там большая строка, то на этапе компиляции сервер Expo может просто отказаться компилировать ваше приложение, сославшись на слишком большой размер js-файла.

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

Навигация

Для реализации навигации между экранами воспользуемся пакетом react-navigation.

npm install react-navigation

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

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
npm install react-navigation-stack

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

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

  1. Screen — компонент экрана для роута;
  2. navigationOptions — настройки навигатора, в которых можно указать заголовок, название для кнопки «Назад» и прочие настройки. Также в качестве этого свойства можно указывать callback, который принимает параметры из навигатора, динамически формирует и возвращает нужные нам значения (этим мы будем активно пользоваться).

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

Вообще единственным обязательным значением для элемента коллекции является свойство screen.

./navigation.js

import { createStackNavigator } from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation'; 
import CategoriesList from './screens/CategoriesList';
import GridScreen from './screens/GridScreen'; 
const Stack = createStackNavigator({   MainList: {       screen: CategoriesList,       navigationOptions: {           title: 'Photo Categories'       }   },   ImagesGrid: {       screen: GridScreen,       navigationOptions: ({ navigation }) => {           return {               title: navigation.state.params.title           };       }   }
},
{   initialRouteName: 'MainList'
}); 
export default createAppContainer(Stack);

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

Роут MainListбудет вызывать компонент CategoriesList, а с помощью navigationOptions мы укажем заголовок для экрана. Роут ImagesGrid будет, в свою очередь, вызывать компонент экрана GridScreen.

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

createStackNavigatorвозвращает компонент. Но мы не можем просто взять и использовать его в приложении. Для этого необходим createAppContainer, который связывает все, что мы можем сотворить с помощью реакт-навигации, с нативными API платформ. createAppContainerвозвращает компонент, который будем использовать как корневой в своем проекте. Для этого немного изменим файл App.js.

./App.js

import React from 'react';
import Navigator from './navigation'; 
export default function App() { return (     <Navigator/> );
}

Внедряем навигацию в компоненты.

./screens/CategoriesList.js

import React from 'react';
import { List, ListItem, Text } from 'native-base';
import { ScrollView } from 'react-native';
import categories from '../data/categories'; 
class CategoriesList extends React.Component {   constructor(props) {       super(props);       this.state.categories = categories;   }    state = {       categories: []   };    render() {       const { navigation: { navigate } } = this.props;        return (           <ScrollView>               <List>                   {                       categories.map((item) => {                            const { collection, alias, name } = item;                            return (                               <ListItem                                   key={alias}                                   onPress={() => navigate('ImagesGrid', { collection, title: name })}                               >                                   <Text>{name}</Text>                               </ListItem>                           )                       })                   }               </List>           </ScrollView>       );   }
} 
export default CategoriesList;

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

Когда мы в файле navigation.jsпередали в качестве аргумента экран CategoriesList, то создали вокруг него HOC (компонент высшего порядка), который в пропсы этого компонента передал некоторые данные и методы для реализации навигации. Нас интересует в первую очередь метод navigation.navigate(). Как вы уже поняли по его названию, он осуществляет навигацию между разными экранами; какой именно экран нужно использовать, определяем в первом аргументе. Название экрана совпадает с названиями объектов в коллекции, которую мы передавали в createStackNavigator (navigation.js); вторым параметром можем передать объект с дополнительными данными, которые будут передаваться в createStackNavigatorи на следующий открытый экран. Сейчас с помощью второго аргумента мы передаем идентификатор коллекции (collection) и заголовок экрана (title).

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

Дисклеймер.Я знаю, что с точки зрения современного модного молодежного фронтенда, в котором в основном используется redux и какая-нибудь saga для манипуляций с состоянием приложения, обращения к АПИ находятся в коде подальше от представлений. Поэтому если вы вдруг решили создавать серьезное приложение, то лучше отнестись к его архитектуре максимально серьезно (насколько вообще можно говорить о серьезности в контексте приложения на JS :). Прочитайте об однонаправленном потоке данных, Flux, Redux и прочем.

./screens/GridScreen.js

import React from 'react';
import { ActivityIndicator, StyleSheet, View } from 'react-native';
import ImageGrid from '../components/ImageGrid'; 
export default class GridScreen extends React.Component {    state = {       isLoaded: false,       imagesList: []   }    async componentDidMount() {       /**        * navigation - прокидвывает react-navigation в пропсы.
        * В navigation.state.params находятся наши дополнительные данные,
        * которые мы передавали в главном экране
        */       const { navigation } = this.props;        try {           const response = await fetch(               navigation.state.params.collection,               { method: 'GET', redirect: 'follow'}           );           const data = await response.json();           this.setState({               imagesList: data,               isLoaded: true           });       } catch (e) {           console.log(e);       }   }    render() {       if (!this.state.isLoaded) {           return (               <View style={styles.loaderContainer}>                   <ActivityIndicator size="small" style={styles.loader} />               </View>           );       }        return (<ImageGrid list={this.state.imagesList}/>);   }
} 
const styles = StyleSheet.create({   loader: {       flex: 1,       justifyContent: "center",       alignItems: "center"   },   loaderContainer: {       flex: 1   }
});

Немного выше в экране CategoriesList мы передавли через метод navigate параметр collection. Теперь в этом экране мы достаем его из props. Collectionявляется урлом для получения массива в json. Его мы будем парсить, получать картинки и выводить их на экран.

Метод componentDidMount у нас асинхронный. В нем мы будем подгружать json с информацией и ссылками на картинки, обрабатывать его и уже на основе данных в нем выводить контент. Тут для людей, которые работают с реактом, ничего нового нет, но на всякий случай поясню. Когда только открывается экран и мы еще не запросили данные по API, у нашего приложения состояние загрузки state.isLoading = true. В этом случае компонент выводит спинер загрузки (он же нативный компонент ActivityIndicator). Когда же загрузка заканчивается, мы обновляем state распарсенным массивом картинок и свойством isLoaded = false, компонент перерисовывается, но на этот раз у него уже есть массив, который можно передать в компонент ImageGrid, чтобы он отрисовал нам картинки. Обратите внимание на стили loader и loaderContainer — да, в RN есть всеми нами любимый flex. Такая комбинация стилизаций дает возможность отображать объекты строго посередине экрана.

Если вы все сделали правильно, то после запуска npm run ios или npm run android в эмуляторе вы должны увидеть что-то похожее на это:

Метод componentDidMount у нас асинхронный. В нем мы будем подгружать json с информацией и ссылками на картинки.

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

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

Дебагинг

Наверняка вы заметили, что в консоли приложение показывает различный вывод. Мы можем пользоваться привычным console.log()для вывода там значений переменных.

Помимо этого, Expo предоставляет мощную (как сын маминой подруги) утилиту для дебагинга в тестовом режиме. На mac в эмуляторе нужно нажать сочетание клавиш Command + D. Откроется окно, в котором нужно нажать Toggle Element Inspector.

Перейдем в режим дебага, который функционально похож на инспектор в Chrome: там можно просмотреть структуру компонентов и примененные к ним стили, подсветить touchable-элементы и т. д.

Используйте нижнюю панель для переключения между режимами инспектора. Чтобы закрыть его, нажмите сочетание клавиш Command + D и снова — Toggle Element Inspector.

Компиляция в установочный файл

Затронем тему компиляции в установочный файл и подготовку к релизу на платформы App Store и Google Play. Для начала нужно будет подготовить конфигурационный файл app.json. В нем надо указать данные для релиза: ID бандла, ссылку на иконку приложения, версию и прочее. После этого нужно будет лишь запустить команду Expo для билда expo build:android или expo build:ios, в процессе он запросит у вас необходимую для компиляции информацию. В случае с приложениями для iOS Expo предлагает заменеджерить сертификаты и электронные подписи, которые используются в процессе дистрибуции, что довольно удобно (думаю, не надо бояться, что разработчики Expo украдут ваши креды (лично я побаивался!)).

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

Ура, это все!

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

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

В общем, как-то так. Жду ваших вопросов, проклятий и шуток в комментариях. Кому интересен процесс релиза в Apple Store, тоже пишите: если желающих будет много, превозмогу себя и расскажу о подготовке к релизу.

Використання Defer у Go

$
0
0

Привіт, мене звуть Ярослав. Уже рік я займаюся Go-розробкою в компанії Evrius. У цій статті опишу добре відомі приклади використання команди defer у Go та покритикую, коли defer зайвий. Відповідно, початок статті буде розрахований на початківців, а продовження — на вже досвідчених.

Defer і порядок у коді

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

Популярний приклад, це закриття файлу або закриття з’єднання до БД:

func FileOperationsExample() error {
	f, err := os.Create("/tmp/defer.txt")
	if err != nil {
		return err
	}
	defer f.Close()

	// запис у файл або інші операції

	return nil
}

Ще один приклад для блокування та розблокування:

import "sync"

type CurrencyRateService struct {
	data map[string]map[string]float64
	m    sync.RWMutex
}

func (s *CurrencyRateService) Update(data map[string]map[string]float64) {
	s.m.Lock()
	defer s.m.Unlock()

	s.data = data
}

func (s *CurrencyRateService) Get(fromCurrencyCode, toCurrencyCode string) float64 {
	s.m.RLock()
	defer s.m.RUnlock()

	return s.data[fromCurrencyCode][toCurrencyCode]
}

Це актуально в прикладах, складніших за CurrencyRateService, де ліпше:

func (s *CurrencyRateService) Update(data map[string]map[string]float64) {
	s.m.Lock()
	s.data = data
	s.m.Unlock()
}

func (s *CurrencyRateService) Get(fromCurrencyCode, toCurrencyCode string) float64 {
	s.m.RLock()
	rate := s.data[fromCurrencyCode][toCurrencyCode]
	s.m.RUnlock()

	return rate
}

Defer та доступ до результату функції

Для прикладу візьмімо просту функцію, в якої є іменована результатна змінна (named return values):

func ReturnOne() (result int) {
	result = 1

	return
}

використаємо defer, щоб змінити результат:

func RewriteReturnOne() (result int) {
	defer func() {
		result = 2
	}()

	result = 1

	return
}

func TestRewriteReturnOne(t *testing.T) {
	assert.Equal(t, 2, RewriteReturnOne())
}
func RewriteReturnOneWithoutAssign() (result int) {
	defer func() {
		result = 3
	}()

	return 1
}

func TestRewriteReturnOneWithoutAssign(t *testing.T) {
	assert.Equal(t, 3, RewriteReturnOneWithoutAssign())
}

Ці приклади зрозумілі, також defer має доступ до значення, що було встановлене перед поверненням:

func ModifyReturnOneWithoutAssign() (result int) {
	defer func() {
		result = result * 5
	}()

	return 2
}

func TestModifyReturnOneWithoutAssign(t *testing.T) {
	assert.Equal(t, 10, ModifyReturnOneWithoutAssign())
}

Порядок виконання defer у функції

Зазвичай у прикладах, щоб показати порядок виконання, використовують fmt.Printlnдля легкого запуску в playground.

Та буде простіше показати порядок виконання, використовуючи тести. Ось приклад:

func OneDeferOrder() (result []string) {
	result = append(result, "first")

	defer func() {
		result = append(result, "first defer")
	}()

	result = append(result, "second")

	return result
}

І тест покаже очікуваний результат:

func TestOneDeferOrder(t *testing.T) {
	var actual = OneDeferOrder()

	assert.Equal(
		t,
		actual,
		[]string{
			"first",
			"second",

			"first defer",
		},
	)
}

Допишемо ще один defer:

func DoubleDeferOrder() (result []string) {
	result = append(result, "first")
	defer func() {
		result = append(result, "first defer")
	}()

	result = append(result, "second")
	defer func() {
		result = append(result, "second defer")
	}()

	result = append(result, "third")

	return result
}

І тест, який покаже, що порядок виконання defer зворотний до їх додавання в список на виконання:

func TestDoubleDeferOrder(t *testing.T) {
	var order = DoubleDeferOrder()

	assert.Equal(
		t,
		order,
		[]string{
			"first",
			"second",
			"third",

			"second defer",
			"first defer",
		},
	)
}

Це як розмотування клубка ресурсів, які залежать від попередніх, або ж LIFO.

Defer та ланцюг викликів методів

Підготуємо структуру для збереження стану:

type State struct {
	values []string
}

func (s *State) Append(value string) *State {
	s.values = append(s.values, value)

	return s
}

func (s *State) Values() []string {
	return s.values
}

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

func OnlyLastHandleDefer(state *State) {
	state.Append("first")

	defer state.
		Append("first defer — first call").
		Append("first defer — second call").
		Append("first defer — last call")

	state.Append("second")
}

Тест покаже, що тільки останній виклик буде відкладеним:

func TestOnlyLastHandleDefer(t *testing.T) {
	var state = new(State)

	OnlyLastHandleDefer(state)

	assert.Equal(
		t,
		state.Values(),
		[]string{
			"first",
			"first defer — first call",
			"first defer — second call",
			"second",
			"first defer — last call",
		},
	)
}

Обернувши у функцію, зробимо відкладено для всіх викликів у ланцюжку:

func OnlyLastHandleDeferWrap(state *State) {
	state.Append("first")

	defer func() {
		state.
			Append("first defer — first call").
			Append("first defer — second call").
			Append("first defer — last call")
	}()

	state.Append("second")
}

func TestOnlyLastHandleDeferWrap(t *testing.T) {
	var state = new(State)

	OnlyLastHandleDeferWrap(state)

	assert.Equal(
		t,
		state.Values(),
		[]string{
			"first",
			"second",
			"first defer — first call",
			"first defer — second call",
			"first defer — last call",
		},
	)
}

Defer і розрахунок аргументів

Підготуємо лічильник:

import (
	"strconv"
)

type StringCounter struct {
	value uint64
}

func (c *StringCounter) Next() string {
	c.value += 1

	var next = c.value

	return strconv.FormatUint(next, 10)
}

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

func CallInside(state *State) {
	var counter = new(StringCounter)

	state.Append("first call " + counter.Next())

	defer state.Append("first defer call " + counter.Next())

	state.Append("second call " + counter.Next())
}

func TestCallInside(t *testing.T) {
	var state = new(State)

	CallInside(state)

	assert.Equal(
		t,
		[]string{
			"first call 1",
			"second call 3",
			"first defer call 2",
		},
		state.Values(),
	)
}

Дія counter.Next()була виконана відразу, тому «first defer call 2».

Якщо обернути у функцію, то отримаємо очікуваний результат:

func CallInsideWrap(state *State) {
	var counter = new(StringCounter)

	state.Append("first call " + counter.Next())

	defer func() {
		state.Append("first defer call " + counter.Next())
	}()

	state.Append("second call " + counter.Next())
}

func TestCallInsideWrap(t *testing.T) {
	var state = new(State)

	CallInsideWrap(state)

	assert.Equal(
		t,
		[]string{
			"first call 1",
			"second call 2",
			"first defer call 3",
		},
		state.Values(),
	)
}

Повернення помилок і panic

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

У стандартних Golang-бібліотеках повно прикладів повернення помилок, створення файлу чи запис у файл, або найпростіший приклад:

package strconv

func ParseBool(str string) (bool, error) {
	switch str {
	case "1", "t", "T", "true", "TRUE", "True":
		return true, nil
	case "0", "f", "F", "false", "FALSE", "False":
		return false, nil
	}
	return false, syntaxError("ParseBool", str)
}

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

Як приклад, спроба викликати метод до ініціалізації:

import (
	"database/sql"
	"github.com/stretchr/testify/assert"
	"testing"
)

func PanicNilPointer(connection *sql.DB) {
	_ = connection.Ping()
}

func TestPanicNilPointer(t *testing.T) {
	var connection *sql.DB

	PanicNilPointer(connection)
}
panic: runtime error: invalid memory address or nil pointer dereference

Також panic можна викликати в коді за допомогою команди panic.

Як приклад, у стандартному пакеті bytesфункція Repeatвикликає panic під час перевірки аргументів на коректність.

package bytes

func Repeat(b []byte, count int) []byte {
	if count == 0 {
		return []byte{}
	}
	// Since we cannot return an error on overflow,
	// we should panic if the repeat will generate
	// an overflow.
	// See Issue golang.org/issue/16237.
	if count < 0 {
		panic("bytes: negative Repeat count")
	} else if len(b)*count/count != len(b) {
		panic("bytes: Repeat count causes overflow")
	}

	nb := make([]byte, len(b)*count)
	bp := copy(nb, b)
	for bp < len(nb) {
		copy(nb[bp:], nb[:bp])
		bp *= 2
	}
	return nb
}

Також є функції, що починаються зі слова Must і перетворюють повернення помилки на panic:

package regexp

func MustCompile(str string) *Regexp {
	regexp, err := Compile(str)
	if err != nil {
		panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
	}
	return regexp
}

Recover, або відновлення після panic

Recover is a built-in function that regains control of a panicking goroutine. Recover is only useful inside deferred functions. During normal execution, a call to recover will return nil and have no other effect. If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution. Source

Recover — вбудована функція для відновлення поточної горутини під час panic, корисна тільки в парі з defer.

Recover повертає значення, передане під час виклику panicабо nil.

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestRecover(t *testing.T) {
	var expect interface{}

	var actual = recover()

	assert.Equal(t, true, expect == actual)
}

Ось приклад, який покаже, що під час panic у поточній горутині будуть виконані всі defer, та перший defer зі списку виконання, який має recovery, забере значення, передане в panic.

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func WrapRecovery(state *State) {
	state.Append("first")
	defer func() {
		if err := recover(); err != nil {
			if errorMessage, ok := err.(string); ok {
				state.Append("first defer — recover string panic: " + errorMessage)
			} else {
				state.Append("first defer — recover panic")
			}
		} else {
			state.Append("first defer — without panic")
		}
	}()

	state.Append("second")
	defer func() {
		if err := recover(); err != nil {
			if errorMessage, ok := err.(string); ok {
				state.Append("second defer — recover string panic: " + errorMessage)
			} else {
				state.Append("second defer — recover panic")
			}
		} else {
			state.Append("second defer — without panic")
		}
	}()

	state.Append("third")
	defer func() {
		state.Append("third defer — without recover")
	}()

	panic("catch me")
}

func TestWrapRecovery(t *testing.T) {
	var state = new(State)

	WrapRecovery(state)

	assert.Equal(
		t,
		[]string{
			"first",
			"second",
			"third",
			"third defer — without recover",
			"second defer — recover string panic: catch me",
			"first defer — without panic",
		},
		state.Values(),
	)
}

Щоб ви знали, у panic можна передати nil, але ліпше передавати stringабо error.

package main

func main() {
	defer func() {
		if recover() != nil {
			panic("non-nil recover")
		}
	}()
	panic(nil)
}

У разі виникнення panic, усередині вкладених функцій deferвідпрацює сподівано, приклад:

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func NestedPanic(state *State) {
	state.Append("0 level")
	defer func() {
		if err := recover(); err != nil {
			if errorMessage, ok := err.(string); ok {
				state.Append("0 level — recover string panic: " + errorMessage)
			} else {
				state.Append("0 level — recover panic")
			}
		} else {
			state.Append("0 level — without panic")
		}
	}()

	NestedPanic1Level(state)
}

func NestedPanic1Level(state *State) {
	state.Append("1 level")
	defer func() {
		state.Append("1 level — defer")
	}()

	NestedPanic2Level(state)
}

func NestedPanic2Level(state *State) {
	state.Append("2 level")
	defer func() {
		state.Append("2 level — defer")
	}()

	panic("2 level — panic")
}

func TestNestedPanic(t *testing.T) {
	var state = new(State)

	NestedPanic(state)

	assert.Equal(
		t,
		[]string{
			"0 level",
			"1 level",
			"2 level",
			"2 level — defer",
			"1 level — defer",
			"0 level — recover string panic: 2 level — panic",
		},
		state.Values(),
	)
}

Panic усередині defer

Розгляньмо, що буде, коли під час відновлення після panicзнову відбудеться panic:

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func PanicInsideRecover(state *State) {
	state.Append("first")
	defer func() {
		if err := recover(); err != nil {
			if errorMessage, ok := err.(string); ok {
				state.Append("first defer — recover string panic: " + errorMessage)
			} else {
				state.Append("first defer — recover panic")
			}
		} else {
			state.Append("first defer — without panic")
		}
	}()

	state.Append("second")
	defer func() {
		if err := recover(); err != nil {
			if errorMessage, ok := err.(string); ok {
				state.Append("second defer — recover string panic: " + errorMessage)
			} else {
				state.Append("second defer — recover panic")
			}
		} else {
			state.Append("second defer — without panic")
		}

		panic("inside defer")
	}()

	panic("catch me")
}

func TestPanicInsideRecover(t *testing.T) {
	var state = new(State)

	PanicInsideRecover(state)

	assert.Equal(
		t,
		[]string{
			"first",
			"second",
			"second defer — recover string panic: catch me",
			"first defer — recover string panic: inside defer",
		},
		state.Values(),
	)
}

Сподівано буде відновлений на наступному defer з recover у поточній горутині.

Panic і сигнатура функції

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

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

func ReturnSignatureIntEmptyBody() int {

}

func ReturnSignatureNamedIntEmptyBody() (result int) {

}

func ReturnSignatureEmptyIntBody() {
	return 0
}

А цей приклад з panicуспішно компілюється:

func ReturnSignatureIntPanicBody() int {
	panic("implement me")
}

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

Епілог та особливості

Усе, що описано — приклади коду, тести — сподіване для тих, хто вже розробляє на Go, і питання: «А навіщо писати цю статтю?» теж очікуване. Перша причина: приклади з panic, defer, recoverчасто поверхневі, тому я захотів зібрати їх разом і протестувати. Друга причина в тому, що забувають про слабкі сторони.

Recover тільки для поточної горутини

Якщо взяти приклад, де panicвідбудеться в іншій горутині без recover, то програма завершить своє виконання (та повідомить про panic):

package go_defer_reserach

import (
	"sync"
	"time"
)

type PanicFunctionState struct {
	Completed bool
}

func InsideGorountinePanic(state *PanicFunctionState, n, after int) {
	var wg = new(sync.WaitGroup)

	for i := 1; i <= n; i++ {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()

			panicAfterN(i, after)
		}(i)
	}

	wg.Wait()

	state.Completed = true

	return
}


func panicAfterN(i, after int) {
	time.Sleep(time.Millisecond)

	if i%after == 0 {
		panic("i%after == 0")
	}
}
package main

import (
	"fmt"
	go_defer_reserach "gitlab.com/go-yp/go-defer-reserach"
)

func main() {
	var state = new(go_defer_reserach.PanicFunctionState)

	defer func() {
		fmt.Printf("panic state `%t` after\n", state.Completed)
	}()

	fmt.Printf("panic state `%t` before\n", state.Completed)

	go_defer_reserach.InsideGorountinePanic(state, 25, 20)
}

Запустивши цей приклад 10+ разів, переважно отримував:

panic state `false` before
panic: i%after == 0

і 1-2рази отримував

panic state `false` before
panic state `true` after
panic: i%after == 0

У цьому прикладі коду з defer:

wg.Add(1)

go func(i int) {    defer wg.Done()    panicAfterN(i, after)
}(i)

жодної значної переваги, порівнюючи з кодом без defer:

wg.Add(1)
go func(i int) {    panicAfterN(i, after)    wg.Done()
}(i)

І навпаки, хоч код з defer і виконується повільніше (до версії Go 1.14), але виграш у ~100 наносекунд — малий, порівнюючи з тим, що завдання, які розпаралелили, може виконуватися мілісекунди.

os.Exitзавершує програму відразу та ігнорує defer:

package main

import (
	"fmt"
	"os"
)

// os.Exit ignore defer, output will "first call"
func main() {
	fmt.Println("first call")

	defer fmt.Println("first defer call")

	os.Exit(0)
}

Як і очікували first call

Коли recover не працюєв поточній горутині:

go func(i int) {
	defer wg.Done()
	defer recover()

	panicAfterN(i, after)
}(i)

А так працює, як і сподіваємося:

go func(i int) {
	defer wg.Done()
	defer func() {
		recover()
	}()

	panicAfterN(i, after)
}(i)

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

P. S. Ця стаття написана як продовження вже відомої Defer, Panic, and Recover. Якщо захочете перевірити приклади й тести, то заходьте до репозиторію.

.NET дайджест #32: приложения на Blazor, Azure побеждает AWS, gRPC в .NET, ReSharper и Rider обновились

$
0
0

Январь ожидаемо оказался относительно тихим месяцем — никаких крупных релизов и громких анонсов не было замечено. Тем не менее, некоторые из весьма интересных проектов успели подготовить кое-что новое к началу года. Так, например, вышла новая версия Microsoft Orleans 3.1 RC1. (Для тех, кто не знает, Orleans — это кроссплатформенный фреймворк для создания распределенных приложений с использованием .NET, разработанный командой Microsoft Research). После долгого перерыва обновилась мажорная версия Autofac v5.0 (версия 4.0 была выпущена еще в августе 2016 года). А JetBrains подготовили обновлениядля Rider и ReSharper.

Интересно отметить, что по мнению Sergei Klebnikov из Forbes, Microsoft Azure выигрывает облачную войну против AWS. Это безусловно хорошая тенденция, так борьба вендоров за клиентов всегда выгодна именно клиентам. А подобная перестановка сил на облачном рынке безусловно подстегнет к всех участников к поиску новых способов привлечения клиентов.

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

.NET

Tracing .NET Core applications — после выхода .NET Core команда RedHat очень сильно заинтересовалась этой платформой и теперь регулярно готовит публикации на тему .NET разработки. В этой статье они расскажут о возможностях трейсинга в .NET Core.

MagicOnion — сетевой движок реального времени, такой же как SignalR или Socket.io. MagicOnion построен на базе gRPC и при этом не требует создания .proto файлов. Вышла третья версия библиотеки.

.NET Docker Cheat Sheet — шпаргалка по Docker для .NET разработчика: ссылки на все docker-образы для .NET Framework и .NET Core.

Building Custom Tools into .NET Core — .NET Core позволяет создавать и использовать расширения для командной строки. В статье показывается, как сделаеть такое расширение самостоятельно.

5 Reasons You Should Stop Using System.Drawing from ASP.NET — 5 причин, почему вы должны прекратить использовать System.Drawing в ASP.NET Core.

Event Sourcing with Orleans Journaled Grains — реализация CQRS архитектуры с использованием Microsoft Orleans.

Why ASP.NET Core is the best choice to build enterprise web applications — почему ASP.NET Core — лучший выбор для создания корпоративных веб-приложений, рассказывает Кеннет Фукизи, автор книги «Learn ASP.NET Core 3.0, Second edition».

The Dream of C# 9.0 — очередная порция новых фич, которые возможнобудут включены в девятый релиз C#.

How To Deploy an ASP.NET Core Application with MySQL Server Using Nginx on Ubuntu 18.04 — DigitalOcean подвёл итоги года, определив самые популярные руководства на своём сайте. В список публикаций-победителей вошло руководство по развертыванию ASP.NET Core.

dahomey—technologies/Dahomey.Json — обратите внимание на эту библиотеку. Она добавляет функционал в новый System.Text.Json сериализатор, доводя его практически до уровня Newtonsoft.

Memory Leak C#— любите утечки памяти? Если нет, то прочтите руководство, которое поможет их избежать.

Flow of immutable messages with Akka.Net — если вы еще не работали с Akka.NET, стоит как минимум ознакомиться с возможностями этой библиотеки, а если знакомы, то эта статья может быть вам весьма интересна.

Exploring the new Assembly unloading feature in .NET Core 3.0 by building a simple plugin system running on ASP.NET Core Blazor — новая возможность выгрузки сборок в .NET Core 3.0 на примере создания простой системы плагинов, работающей на ASP.NET Core Blazor.

How to make internal members visible to other assemblies with the new CSPROJ format — иногда (например, для написания юнит-тестов) необходимо, чтобы какой-то из проектов имел доступ к internal классам другого проекта. Автор статьи предлагает ознакомиться с тем, как это можно сделать, используя возможности формата CSPROJ.

vanbukin/Uuids — попытка сделать генерацию UUID быстрее. Достойно внимания, но вот стоит ли использовать в реальных проектах — пока не ясно.

Announcing Experimental Mobile Blazor Bindings — экспериментальный проект по разработке мобильных приложений с использованием Blazor. Теперь разработчики смогут использовать программную модель Blazor и синтаксис Razor для определения компонентов пользовательского интерфейса и поведения приложения. Компоненты пользовательского интерфейса основаны на собственных элементах управления пользовательского интерфейса Xamarin.Forms.

.NET Core 3.1.1 — January 14, 2020 — вышло январское обновление .NET Core, которое включает ряд исправлений, связанных с безопасностью. А именно были закрыты такие уязвимости: CVE—2020—0602: ASP.NET Core Denial of Service Vulnerability, CVE—2020—0603: ASP.NET Core Remote Code Execution Vulnerability, CVE—2020—0605: .NET Core Remote Code Execution Vulnerability, CVE—2020—0606: .NET Core Remote Code Execution Vulnerability.

Entity Framework Best Practices — Should EFCore Be Your Data Access of Choice?— рекомендации по работе с Entity Framework.

Optimizing string.Count all the way from LINQ to hardware accelerated vectorized instructions — немного воскресного хардкора. Оптимизация метода String.Count(). От LINQ до аппаратно ускоренных векторизованных инструкций.

.NET Core on Red Hat platforms — RedHat опубликовали мануал по установке .NET на все их официальные дистрибутивы: Fedora, Red Hat Enterprise Linux (RHEL), CentOS и CentOS Stream. Правда почему-то в примере используется .NET Core 2.1, а не 3.1, который является актуальной LTS версией.

Getting Started with DynamoDB and .NET Core  —  How to Build a Leaderboard — простой пример работы с Amazon DynamoDB в .NET Core.

The Reunification of .NET 5 — уже в конце этого года запланирован релиз .NET 5. Безусловно, это будет следующая большая веха в истории .NET, после релиза .NET Core, ведь .NET 5 объединит в себе две ветви: .NET Core и .NET Framework. Что нас ждет в .NET? Точно в историю уйдут: ASP.NET Web Forms, WCF и WWF. Получат дальнейшее развитие: WPF and WinForms и Visual Basic. Подробнее — в публикации от Matthew MacDonald.

Autofac v5.0 — не так давно вышел в свет новый релиз Autofac под версией 5.0! Это первый мажорный релиз, который вышел спустя три года — Autofac 4.0 был выпущен в августе 2016.

How Blazor Is Going to Change Web Development — Blazor — технология, которая способна изменить привычный подход к веб—разработке.

UTF—8 BOM adventures in C#— приключения UTF-8 BOM в C#: как определить BOM и что с этим делать.

IDisposable: What Your Mother Never Told You About Resource Deallocation — лонгрид 2014 года, который однако не теряет своей актуальности и сегодня. В статье рассматриваются тонкости использования Idisposable.

.NET Core 3.0 Preview behaviour for ——output differs — проблема, с которой можете столкнуться вы, или ваши девопсы после обновления на .NET Core 3.0 и выше. Microsoft поменял логику обработки опции ——output. Теперь, если вы используете абсолютный путь, активной директорией будет считаться директория, из которой была запущена команда dotnet, а не директория, в которой находится csproj файл. Из—за этого могут перестать корректно работать CI/CD.

10 Visual Studio Tips & Tricks You Probably DON’T KNOW — некоторые из возможностей Visual Studio, о которых вы вероятно не догадывались.

Building Microservices with gRPC and .NET — из этого видео вы узнаете о том, как сделать систему на базе микросервисной архитектуры с использованием gRPC. Также вы узнаете о том, какие перспективы у gRPC в .NET и как эта технология будет развиваться дальше.

C# Futures: Covariant Return Types — предложение включить в следующую версию С# поддержку ковариантных типов возврата. Это может позволить переопределенному методу иметь другой (более высокий по иерархии наследования) тип, чем метод, который он переопределяет.

10 Performance—Improvement Tips for ASP.NET Core 3.0 Applications — десять советов, которые помогут сделать ваше ASP.NET Core приложение быстрее.

Writing network proxies for development purposes in C#— создание сетевого прокси на C#.

Xamarin

Cognitive Services in Xamarin Applications — использование Microsoft Cognitive Services в мобильных приложениях.

What’s New, Hot, & Awesome for Xamarin Developers!— презентация с митапа Seattle Mobile Developers.

Don’t mention the seam! Microsoft releases Surface Duo Android SDK, more on Windows 10X — Microsoft выпустили предварительную версию SDK для Surface Duo. Напомним, что Surface Duo — это новый смартфон с двумя экранами, который был представлен на Microsoft’s 2019 Surface Event.

How to implement data validation with Xamarin.Forms — подробное руководство по реализации валидации в Xamarin Forms.

Azure

How to Learn Microsoft Azure in 2020 — количество сервисов Azure увеличивается чуть ли не каждый день. В статье собраны и структурированы материалы, которые помогут в их изучении. Также есть информация по различные сертификации Azure.

Azure Container Service will retire on 31 January 2020 — поддержка службы контейнеров Azure будет прекращена 31 января 2020 года.

Integrate ASP.NET Core with Azure Key Vault — в этом видео будет показано, как интегрировать сервис хранилища ключей Azure с веб-приложением ASP.NET Core.

Microsoft Is Winning The ‘Cloud War’ Against Amazon: Report — похоже, что AWS все активнее сдаёт позиции и уступает Azure. По результатам исследования Goldman Sachs, именно Microsoft является самым популярным поставщиком облачных сервисов.

Azure is now certified for the ISO/IEC 27701 privacy standard — Azure теперь сертифицирован по стандарту конфиденциальности ISO / IEC 27701. Что это и зачем нужно? Принятие GDPR в Евросоюзе стало важным этапом в развитии требований в области

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

How Azure Event Grid is different from logs, alerts, change feeds and webhooks — Антон Бойко во время поиска информации по абсолютно другой и не связанной теме, наткнулся на отличную статью про Event Grid. В статье описывается, чем Event Grid отличается от других, казалось бы, аналогичных сервисов или возможностей Azure. Статья не сильно большая, но она покрывает основные моменты на 5+.

Microsoft to launch new cloud datacenter region in Israel — Microsoft News Centre Europe — Microsoft запускает новый дата-центр в Израиле.

Machine Learning, Data science, Big Data, etc.

Tutorial: Detect objects using deep learning with ONNX and ML.NET — классификация изображений с использованием ONNX модели и ML.NET.

Microsoft Research 2019 reflection — a year of progress on technology’s toughest challenges — итоги года от команды Microsoft Research: релиз модели MT—DNN, релиз SEAL для .NET, множество награждений исследователей из Microsoft Research, участие в конференции ACM FAT в Атланте и многое другое.

События

F# Ukraine 2020 — 28 марта пройдёт первая в Украине конференция, посвящённая разработке на F#. Главный критерий отбора докладов — темы базируются на реальном опыте применения F#. Большинство докладов касаются не только F#, но и архитектуры (actor model, event sourcing, streaming).

Azure Hybrid Virtual Event — 31 марта состоится Azure Hybrid Virtual Event — бесплатное онлайн-мероприятие, на котором вы сможете узнать о последних инновациях в Azure Arc и Azure Stack, двух инновационных решениях гибридного облака от Microsoft.

Visual Studio for Mac: Refresh(); event — 24 февраля присоединяйтесь бесплатному виртуальному мероприятию, чтобы узнать, как сделать разработку мобильных приложений, веб-приложений и игр легкой и продуктивной на вашем Mac.

MS Stage — 21 начнется конференция, посвященная технологическому стеку Microsoft: C#, F#, .NET, ASP.NET, MS SQL Server, Internet information server, Microsoft Visual Studio, MS Azure, Cosmos DB и многое другое.


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


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

Viewing all 8919 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>