Quantcast
Channel: Категорія [Статьи] — DOU
Viewing all 2504 articles
Browse latest View live

Технології комп’ютерного зору в UI-тестуванні. Частина 1

$
0
0

Всім привіт! Мене звати Дмитро, я працюю AQA інженером в компанії Intellias на automotive проєкті. У цій статті я хочу розказати про технології комп’ютерного зору, які допомогли вирішити багато складних задач у тестуванні UI автомобільної навігаційної системи.

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

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

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

Проблематика

Зазвичай в аплікаціях UI елементи описуються мовою розмітки (HTML чи XML) у поєднанні з таблицею стилів. У цьому випадку тестування UI зводиться до пошуку елементу в розмітці і перевірці його характеристик. За необхідності можемо емулювати дії користувача, щоб автоматизувати сценарії та різноманітні user flow. Для кожної платформи (веб, мобайл, десктоп) існує достатньо інструментів, які дозволяють організувати автоматизоване тестування (Webdriver, Appium, Ranorex тощо). Вибір того чи іншого фреймворку часто залежить від уподобань і досвіду спеціаліста, який відповідає за автоматизацію на проєкті.

Кнопка «Restaurants» у додатку Google Maps — гарний приклад елементу, який легко знайти в горстці та отримати вичерпну інформацію про розмір, колір, розміщення на екрані, статус та інші характеристики. Але бувають UI елементи, які представлені не за допомогою горстки, а іншим способом. Анімація, мапа, об’єкти на мапі, різноманітні діаграми і графіки не доступні в HTML/XML. Автоматизувати перевірку цих елементів досить важко — вибір інструментів невеликий i більшість з них розповсюджується на платній основі.

Усі елементи мапи Google (міста, вулиці, площі, будинки, ріки, мости і т.д.) «намальовані» всередині елементу canvas. Очевидно, що інформації, отриманої з горстки, недостатньо навіть для простого тесту отриманої локації на мапі.

Кнопка Restaurants і мапа в HTML Google Maps

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

UI типової навігаційної системи

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

  • не змінюють свого положення на екрані, тобто відображаються статично;
  • не спотворені іншими елементами.

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

Порівняння зображень за допомогою pHash

Існує багато інструментів, які дозволяють порівняти картинки з допустимим рівнем спотворень. Наприклад, для Ruby — це Imatcher, RMagick, Vips тощо. На проєкті ми використовували pHash — популярну бібліотеку, доступну для різних платформ. Демо pHash можна переглянути онлайн.

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

Демоверсія сайту з алгоритмом pHash

Ми використовували pHash у тестах позиціонування автомобіля — порівнювали ту частину екрану, яка містить current car position (на картинці нижче закрита чорним квадратом). Різні версії мапи та додатку, затори, інциденти на дорозі, нові заклади і т. д. призводили до появи додаткових спотворень: зміщення позиції напрямку руху, перекриття назви вулиці з іконкою машини тощо.

Ось приклад фрагментів екрану, які порівнюються в тесті. З правої сторони наведена різниця в байтах кожного фрагменту у порівнянні з першим. Бачимо, що різниця першої і другої картинки — 8 байт, першої і третьої — 17 байт, далі — 16, 14 та 6 байт. Тобто для тесту цієї локації, встановлення порогового значення у 20 байт забезпечує високу ймовірність проходження тесту, якщо на картинках правильна локація (помилка 2-городу — хибний fail — мінімальна). Так само цей поріг дає високу ймовірність, що картинки з іншою локацією не пройдуть тест (помилка 1-городу — хибний pass — мінімальна).

Різниця в байтах між фрагментами рисунків з однаковим положенням автомобіля на вулиці

Але в іншому тесті, де перевіряється функціонал збільшення (Zoom In test), вже зовсім інші цифри: haming distance від 0 до 27. Тобто, якщо встановити порогове значення на рівні 20, то у 2-мута 3-мутесті ми б отримали fail, хоча насправді Zoom In спрацював нормально (виникла помилка 2-городу).

Різниця в байтах між фрагментами рисунків з однаковим положенням автомобіля в разі збільшення (Zoom In)

Щоб зменшити ймовірність таких помилок, можна зберегти декілька еталонних зображень і використовувати їх, якщо попереднє порівняння було невдалим. У моїй практиці, для деяких локацій кількість зображень сягала 8-миштук. Таким чином, зменшується ймовірність помилки 2-городу (хибний fail), але збільшується ймовірність помилки 1-городу (хибний pass), бо одна із збережених еталонних картинок може збігтися з неправильною локацією.

Нижче наведені картинки з різними локаціями та haming distance при порівнянні їх між собою. Через те, що наша система має сіру тему оформлення (сірі будівлі, сірі вулиці), іноді результат порівняння зовсім різних картинок дорівнює 18 (менше за поріг у 20 байт). Порівнюючи 3-ймалюнок (повністю пусту вулицю) з 4-м (вулиця з написом), отримуємо 21, що дуже близько до порогового значення.

Різниця в байтах між фрагментами рисунків з різними положеннями автомобіля

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

Computer Vision та OpenCV

Computer Vision — це технології та методи для виявлення, відстеження та класифікування об’єктів на зображенні. Однією з найпопулярніших бібліотек, в якій реалізовані алгоритми Computer Vision, є OpenCV. Існує реалізація на Python, С++ та інших мовах. Через зручність встановлення і написання скриптів ми будемо використовувати реалізацію на Python 2. OpenCV має широкі можливості у роботі з зображеннями — пошук об’єктів, сегментація, трекінг і т. д. Це «швейцарський ніж» у комп’ютерному зорі, однак, нас цікавить саме те, що допоможе нам у тестуванні. У 90% випадках тестування зображень нам допоможе метод Template Matching.

Метод Template Matching

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

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

Template Matching в Python реалізований через метод machTemplate модуля cv2, який приймає три параметри — тестове зображення, темплейт і назву алгоритму порівняння. На виході отримуємо набір пікселів, які формують результуюче зображення. Знайти положення та яскравість найсвітлішої та найтемнішої точки на результуючому зображенні можна за допомогою методу minMaxLoc.

Template Matching: шаблон, тестове зображення й підсумкове зображення

Існує три алгоритми матчингу темплейту. Деякі алгоритми результатом найкращого матчингу повертають найсвітлішу точку (TM_CCOEFF, TM_CCORR), деякі — найтемнішу (TM_SQDIFF). Їхня ефективність варіюється для різних категорій зображень, тому щоб отримати найкращий результат, їх треба підбирати. За замовчуванням використовується алгоритм TM_CCOEFF, який дає непогані результати для багатьох типів зображень.

Методи порівняння зображень

Також, для кожного алгоритму існує нормована версія, коли найкращий результат матчингу приводиться до значення від 0 до 1 (0% і 100% матчинг). Це зручно для прийняття рішення щодо якості матчингу. При ненормованому методі в найкращому місці матчингу яскравість пікселя буде довільної величини (скажімо 1428 одиниць). Цієї інформації недостатньо, щоб прийняти рішення. У випадку з нормованим методом ми знаємо, що 100% матчинг має результат, який дорівнює 1, і ми можемо ввести порогове значення (скажімо 0.8) для визначення прийнятного результату. Більш того, нормований метод допомагає при визначенні кількості об’єктів на картинці. Застосувавши фільтр, ми можемо вибрати ті точки, де результат вищий за порогове значення, і порахувати ці точки.

Наприклад, у нас є картинка з гри Супер Маріо і наша задача порахувати кількість монеток у підземеллі. Темплейт — це монетка. Застосовуємо метод, знаходимо найсвітліші точки, фільтруємо точки, де результат більший від порогового значення (0.8) і отримуємо позиції, де розташовані монетки.

Template Matching. Пошук декількох об’єктів

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

Наприклад, спробуємо перевірити правильність позиціонування адреси в Google Maps через Template Matching. Якщо ми введемо в пошук адресу офісу Intellias — «Intellias Kyrylivska 39», підготуємо з нього темплейт і спробуємо порівняти його із зображенням, на якому інша локація (інший офіс Intellias «Intellias Kyrylivska 15/1») , то ми отримаємо результат, вищий за порогове значення (0.85 при порозі 0.8). Тобто для алгоритму ці дві локації схожі з результатом 85%.

Template Matching у Google Maps

Очевидно, що Template Matching не підходить для перевірки локацій.

Пошук об’єктів на зображеннях зі спотворенням

У Computer Vision існує набір методів, які дозволяють організувати пошук об’єктів на мапі. Але для того, щоб зрозуміти як ними користуватися, необхідно трохи заглибитись в теорію, зокрема, згадати, як ми складаємо пазли.

Уявімо, що наша картинка — це великий пазл. Які частини пазлу складати найважче? Зазвичай, це частини, які створюють фон: небо, хмари, море, земля, стіни будинків і т.д. Щоб скласти таку чистину, потрібно багато шматочків пазлу, які мало відрізняються один від одного. На картинці знизу ці елементи позначені літерами A і В. Трохи легше складати картинку, де є переходи кольору або границі об’єктів. Вони мають прив’язку до горизонталі чи вертикалі (позначені літерами C і D). Тут вже можемо визначити, що С — лінія даху правої будівлі, а D — лівої. Але все ще залишається невизначеність, в якому саме місці мають бути ці частинки. Якщо ж подивитися на елементи E і F, то ми побачимо, що це кутики, які можна встановити тільки в одному місці на картинці. Ці кутики дають найбільше інформації про характеристики об’єкту.

Об’єкти на картинці, які ми описали (площини, границі і кутики), в Computer Vision називаються Features. Пошук цих об’єктів називається Feature Detection, а опис і знаходження їхніх характеристик — Feature Description.

Пошук та опис об’єктів на зображенні

Одна з найважливіших задач, яку треба вирішити при порівнянні об’єктів, — це пошук кутиків на картинках. Алгоритми, які займаються цим, називаються Corner Detectors. Чи не найперший алгоритм був описаний Крісом Харрісом у 1988-муроці. Він запропонував розбивати зображення на фрагменти і, рухаючи їх по горизонталі і вертикалі, порівнювати з сусідніми фрагментами. Спостерігаючи, як змінюються (чи не змінюються) характеристики, можна зробити висновок, що фрагмент містить плаский об’єкт (якщо характеристики не змінюються), границю (якщо характеристики різко змінюються при русі в одну із сторін) або кутик (якщо характеристики різко змінюються при русі в будь-яку зі сторін). На малюнку представлена модель алгоритму Гарріса.

Модель Гарріса

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

Детектор Гарріса в OpenCV

Наступним кроком після знаходження кутиків є обчислення їхніх характеристик. В алгоритмі SIFT (Scale-Invariant Feature Transform), описаному у 2004 році, Девід Лоу уточнив пошук кутиків за рахунок додаткових перевірок на різних масштабах зображення. При збільшенні виявляється, що кутик складається з кількох границь і точки перетину, яку нам і треба визначити якомога точніше. Також він запропонував розбивати фрагмент з кутиком на менші фрагменти (128 фрагментів) і обчислювати вектор збільшення яскравості для кожного з них. Таким чином, для кожної точки з кутиком обчислюється 128 бітове значення (дескриптор), яке використовується у порівнянні.

Обчислення дескрипторів у SIFT

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

Обчислення дескрипторів для кольорового й чорно-білого зображень

В OpenCV алгоритм обчислення дескрипторів (а також точок з кутиками) реалізований через метод detectAndCompute об’єкту SIFT. За допомогою методу drawKeypoints можна позначити на картинці знайдені точки.

SIFT в OpenCV

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

Feature Matching

Після того як ми знайшли ключові точки порівняння (кутики) і обчислили їх характеристики (дескриптори), можна переходити до їх порівняння. Існує два основних методи порівняння об’єктів — Cross Check та тест Девіда Лоу. Наприклад, ми маємо один і той самий трикутник, зображений на 2-хкартинках під різними кутами. Як відбувається порівняння? Припустимо, що різниця між дескрипторами обчислюється простим відніманням, і чим менша по модулю величина, тим більше точки подібні одна до одної. Тобто у 2-ходнакових точок різниця дорівнює 0.

У методі Cross Check ми обчислюємо різницю між кожною точкою першого зображення і кожною точкою другого, а потім обчислюємо різницю для кожної точки другого зображення з кожною точкою першого (перехресна перевірка). Після цього ми робимо висновки щодо отриманих результатів. Дві точки вважаються відповідними (позначено зеленою лінією), коли у двох напрямках різниця між ними менша за різницю з іншими точками. Так, для верхньої точки першого трикутника найменша різниця дорівнює 3, але для верхньої точки другого трикутника, найменша різниця дорівнює 2, тож ці точки не відповідні (червона лінія). У цьому випадку серед 3-хзнайдених ключових точок ми отримали 1 точку з матчингом (33%).

Метод Cross Check

Інший метод був запропонований Девідом Лоу, який також є автором SIFT. У ньому ми визначаємо різницю в одному напрямку: для кожної точки першого зображення з кожною точкою другого зображення. Ідея полягає в тому, що якщо два зображення містять один об’єкт, то для кожної точки першого зображення існує тільки одна точка на другому зображенні, різниця з якою буде прагнути до нуля. Різниці з іншими точками будуть суттєво відрізнятися в більшу сторону. Тому щоб матчинг був прийнятий, його результат має бути набагато кращим за всі інші результати матчингів для цієї точки. Можна задати параметр цього порівняння, наприклад, найменша різниця має бути на 75% менша за всі інші різниці. Маємо ті самі 2 трикутники і обчислені різниці для кожної точки. Для найвищої точки першого трикутника результати — 3, 7 і 8. Найкращий результат 3, що становить 42% від 7, і 37% від 8. Це набагато менше за 75%, тому цей матчинг приймається. Для середньої точки маємо результати 5, 4 і 6. Найкращий результат 4, що є 80% від 5 і 66% від 6. Це більше за 75%, тому чей матчинг вибраковується. Бачимо, що доцільно порівнювати тільки 2 найкращих результати, бо якщо хоча б один з результатів буде більший за 75%, матчинг вибраковується. У даному прикладі серед 3-хзнайдених точок ми отримали 2 точки з матчингом (66%)

Тест Девіда Лоу

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

В OpenCV існує класс BFMatcher (Brute-Force), який використовується для порівняння дескрипторів. Відповідно до того, яким методом були обчислені дескриптори (SIFT чи інші), та який метод буде використано для порівняння (Cross-Check чи тест Девіда Лоу), створюється об’єкт bf класу BFMatсher. Якщо використовується Cross-Check, то метод bf.match приймає два масиви дескрипторів (для першої і другої картинки) і повертає масив з об’єктами типу match. Кожен об’єкт match містить координати, дескриптори і результат порівняння для двох точок які пройшли Cross-Check.

Якщо використовується тест Девіда Лоу, то метод bf.knnMatch приймає два масиви дескрипторів і параметр k — кількість порівнянь для кожної точки, які будуть приймати участь у тесті Девіда Лоу. На прикладі вище ми бачили, що 2 найкращих результати для кожної точки достатньо для порівняння, тому k=2. Метод повертає масив масивів з результатами для кожної точки (результати сортовані від меншого). Далі застосовується тест, де у циклі перевіряється, чи з двох найкращих результатів один менший за другий на 75%. З тих результатів, що пройшли тест, формується масив good. Метод drawMatches дозволяє намалювати лінії між картинками, які порівнюються.

Brute Force matching в OpenCV

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

Висновки

Ми розглянули деякі елементи теорії Computer Vision та познайомилися з бібліотекою OpenCV. Це дуже мала частина усіх знань про обробку зображень, але вона дозволяє створити інструменти, які будуть корисними у тестуванні.

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


Как мы оптимизировали деплой и льем код в любое время суток

$
0
0

Привет! Я работаю CTO в компании Poster, облачной системе автоматизации для кафе и ресторанов. За шесть лет мы из днепровского стартапа выросли до второй по величине планшетной POS-системы в Европе.

В статье я поделюсь нашим опытом и расскажу о том, как мы перестраивали процессы, стремясь к удобному и качественному деплою. Когда-то давно СТО (раньше эту должность занимал нынешний CEO Родион Ерошек) заходил на единственный сервер и вручную делал git pull origin master. Сейчас же наш серверный парк перевалил за 100, причем любой программист, прошедший испытательный срок, может задеплоить свой код на продакшен в любое время дня и ночи, и даже CTO обязан прислать соответствующей гильдии код на ревью перед деплоем на первых клиентов.

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

Немного контекста

Poster — это высоконагруженный продукт: с помощью системы ежемесячно пробивается 17 млн чеков в 11 тыс. ресторанах в 90 странах мира. Система состоит из POS-терминала для официантов и админпанели для владельцев. Программа работает на iPad- и Android-планшетах, desktop-версии запускаются под Windows и macOS, есть и веб-версия.

Ядро системы работает на JS + PHP. Нативные приложения используют Objective-C и Swift, Java и Kotlin, Electron и React Native. Часть микросервисов написаны на Python и Node.js. Вся инфраструктура размещается примерно на 75 dedicated и 25 виртуальных и cloud-серверах. В Dev-команде 40 человек.

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

  • API с веб-хуками;
  • кастомные страницы в админпанели;
  • отдельные JS-приложения, внедренные в POS-терминал и перехватывающие различные события;
  • другие iOS- и Android-приложения на иных планшетах, взаимодействующие c POS-терминалом внутри локальной сети по отдельному протоколу.

Сегодня в маркетплейсе находится порядка 40 сторонних приложений, плюс еще примерно 400 закрытых личных интеграций.

Техническая автоматизация деплоя

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

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

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

Сейчас же тесты стали стандартом и входят в Definition of Done практически во всех командах. Хотя мы все еще против бездумного покрытия тестами ради самих тестов.

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

Ручной деплой

В первый год жизни компании, когда в ней работало лишь несколько программистов, CTO выливал код банальным git pull origin master. Этого было достаточно, ведь деплой чего-то нового происходил не каждый день.

Первой ласточкой стала автоматизация миграций. Данные каждого клиента Poster хранятся в отдельной базе. В первый год работы компании, чтобы провести миграцию баз, программисты писали новый метод в контроллере :) Затем происходило переподключение по всем базам и выполнение какого-то SQL-ника или куска PHP-кода. А передача изменений между разработчиками, которым также надо было локально обновить у себя базу, осуществлялась через Skype.

Эта схема накрылась примерно тогда, когда я пришел в компанию. Кто-то забыл скинуть в Skype один из SQL-запросов, и после деплоя система начала работать совсем не так, как надо. Я выбил неделю для устранения этой проблемы и написал библиотеку, которая могла бы гибко мигрировать все базы клиентов или какую-то конкретную.

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

Capistrano

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

Deployer

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

Со временем мы начали использовать параллельный деплой на все app-серверы одновременно. Это позволяет выливать новый код на десятки серверов в среднем за 5-7 минут.Конечно, бывает и дольше, особенно если есть миграции или же в коде было очень много изменений (но теперь это мало кого беспокоит, так как все выполняется уже без участия разработчиков).

/*
 * Deploy task
 */
task('deploy', [
    'deploy:info',
    'deploy:lock',
    'deploy:prepare',
    'deploy:release',
    'deploy:update_code',
    'deploy:last_commit',
    'deploy:copy_dirs',
    'deploy:copy_files',
    'deploy:npm_install',
    'deploy:build',
    'deploy:shared',
    'deploy:shared_local',
    'deploy:check_migrate_pos',
    'deploy:check_migrate',
    'deploy:symlink_previous',
    'deploy:appcache_generate_data',
    'deploy:prepare_migrate',
    'deploy:symlink',
    'deploy:generate_webp',
    'deploy:reset_opcache',
    'deploy:migrate_pos',
    'deploy:migrate',
    'deploy:update_appcache',
    'cleanup',
    'deploy:unlock',
]);

После перехода на Deployer мы деплоили примерно два года с локальных машин. На тот момент у нас толком не было тестов, поэтому такой процесс нас хоть и с натяжкой, но устраивал. Когда же мы наняли первого Automation QA, то вариантов не создавать полноценный CI-/CD-процесс уже не было. У нас появился выделенный DevOps-инженер, который этим и занялся.

GitLab

CI-/CD-процесс мы организовали в рамках своего GitLab-сервера. Сначала создали pipeline для прохождения тестов, а после этого добавили отдельный pipeline непосредственно для деплоя после принятия MR.

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

4 часа, die(); и 11 514 чеков

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

Три года назад после окончания отлова одной из ошибок разработчик забыл <? die();?> в библиотеке, отвечающей за синхронизацию POS-терминалов с бэкендом. Благодаря дикой случайности этот код не ушел на серверы и не поломал нашим клиентам синхронизацию.

В тот же год наш будущий DevOps-инженер вылил код, который за 20 минут поломал закрытие 11 514 чеков. Мы потратили 12 часов, чтобы достать детали клиентских данных из логов и починить их.

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

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

Клонирование баз

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

QA-инженер

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

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

Stage-сервер

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

Когда запросы на stage-серверы превысили десять штук, в poster-core-tools была добавлена возможность разворачивать их автоматически. Сейчас у нас 40 серверов для ручного тестирования и еще 10 для прогона автоматических тестов. При необходимости можем добавить еще пару десятков запуском одной утилиты.

AQA-инженер

Два года назад мы наняли первого AQA-инженера. Нам понадобилось примерно 8 месяцев, чтобы покрыть все основные функции E2E-тестами и создать свой первый pipeline для проверки работоспособности системы.

Параллельно с E2E-тестами мы начали писать API-тесты и развивать культуру написания unit-тестов. Нельзя сказать, что все идет гладко, но практически ежеквартально у нас происходят какие-то изменения в процессе тестирования.

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

Канареечный деплой

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

Сначала такой деплой состоял из beta- и production-веток. Со временем к ним добавились testing, а примерно год назад stable-ветки. В итоге сейчас у нас следующая схема разлива кода:

Beta 5% → Testing 10% → Production 15% → Stable 70%

Все разработчики ежедневно льют свой код в beta, на следующий день он переливается из beta в testing, а еще через день — из testing в production. Каждый понедельник код меняет распложение — из production в stable.

Клиенты находятся в постоянной ротации между ветками согласно простому алгоритму: остатку от деления их ID на 5. При этом на ветки ниже stable стараемся переносить клиентов с наибольшим ID, чтобы «старики» оставались на stable. На beta находится примерно 5% клиентов с остатком, равным 1; на testing — 10% с остатком, равным 2; на production — 15% с остатком, равным 3; а все остальные — на stable.

У нас есть еще три ветки — beta 2, beta 3 и beta 4. На них выливаются большие или сложные изменения, которые требуют неопределенного времени тестирования в боевых условиях на работающих лояльных клиентах. После этого код переносится в стандартную beta-ветку.

Доверяй, но проверяй

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

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

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

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

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

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

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

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

Примерно три месяца назад на собрании Dev-отдела, я, CEO и Head of Engineering получили запрет на деплой кода без ревью соответствующей гильдии... Так и живем, создавая отдел по бирюзовой методологии.

Подведем итог

Сейчас из инструментов мы используем GitLab (для хранения репозитория) и Continuous Integration. Для Continuous Deployment применяем Deployer, а стартует все также из GitLab.

Каждый раз, когда разработчик пушит свой код в репозиторий, мы прогоняем unit-тесты и проверяем code style для JS и PHP.

После того как ветка готова, разработчик ставит MR. В этот момент запускается расширенный pipeline вместе с деплоем ветки на stage-серверы, зарезервированные под автотесты. В качестве тестов сейчас гоняем API-тесты, приемочные на Codeception и E2E-тесты на Selenium.

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

Как только все виды тестов и ревью пройдены, в GitLab принимается MR и код автоматически выливается на клиентов, находящихся на beta-ветке. На следующий день код будет перемещен на testing, а затем на production. С наступлением ближайшего понедельника код из production попадет на stable.

При необходимости разработчик может вылить код не на beta, а на beta 2 / beta 3 / beta 4 и перевести туда нескольких заинтересованных клиентов, чтобы они какое-то время потестили фичу. Но потом она все равно будет влита в beta.

Что дальше

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

  1. Добавить в pipeline SonarQube, чтобы ускорить и упростить дальнейшее ревью кода.
  2. Сделать автоматический, а не ручной ежедневный перелив кода между ветками beta ⟶ testing ⟶ production ⟶ stable в рамках канареечного деплоя. Сейчас MR создаются автоматически, но после прохождения всех тестов подтверждаются вручную.
  3. Улучшить алгоритм и автоматизировать выбор клиентов для канареечного деплоя. Уйти от «глупого» остатка от деления и начать использовать более качественное распределение. Например, чтобы на beta, testing и production были клиенты как с большим, так и маленьким количеством чеков, с большим и маленьким меню, клиенты, работающие со всеми типами оборудования, и так далее. Это позволит находить неточности в новом коде раньше, не дожидаясь их попадания на всех клиентов.
  4. Деплоить только после получения определенного количества лайков со стороны гильдии.
  5. Автоматизировать выбор тех, кто будет ревьюить код.

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


Main image by Jonathan Segal


Читайте также: Щоденні релізи: досвід продуктових ІТ-компаній

Open source: що це, для чого і як розпочати

$
0
0

Понад 8 років я працюю у сфері розробки програмного забезпечення, переважно з JavaScript і RoR, і всі 8 років беру участь в open source. Серед проєктів, участю в яких пишаюся найбільше — Botpressта Spree.

Уперше з open source мені довелося мати справу ще в школі, коли я пробував запускати Linux замість чергового «перевстановлення Windows» у себе й своїх близьких. Згодом почав використовувати його й у роботі, проте не наважувався брати участь. Свій перший PRя відкрив до Spree, з яким саме тоді працював і якому бракувало перекладу українською. Його прийняли, і ось тоді я зрозумів, що, виявляється, це не лише не так і складно, а й можна поєднувати роботу із задоволенням.

Але цю статтю пишу не для того, щоб розповісти, що в Open Source робив я. Моя мета — пояснити, чому open source потрібні ви. Чи можна заробити на open source, як почати й для чого це все треба?

Що таке open source і community

Open source — це рух, що підтримує розробку й просування відкритого програмного забезпечення. Простіше кажучи, open source — це, наприклад, безліч проєктів на GitHub, куди ви точно не раз заходили, щоб знайти потрібне вам рішення. Open source — це ще й Linux, улюблена ОС більшості розробників програмного забезпечення.

За кожним проєктом open source стоїть спільнота, тобто community, яка його розробляє, підтримує і просуває. Community — це різні люди з різними намірами: хтось хоче розвинути програмний продукт, наприклад тому, що використовує його в роботі або навіть виконує завдання, яке оплачує кінцевий замовник; хтось хоче вдосконалити власні навички — так люди, які тривалий час працюють в одному проєкті, хочуть урізноманітнити свій досвід, перевірити знання й уміння та отримати фідбек від ком’юніті; хтось робить внесок в open source заради різних community-заходів — вони й додають фану в роботу; а комусь просто цікаво, можна сказати з дослідницького погляду, зрозуміти, як працює щось складне (той самий Virtual DOM у реакті).

Неважливо, які цілі ці люди мають на прикметі. Важливо те, що, з одного боку, без спільноти проєкт Open Source не зможе довго існувати, а з іншого, для реалізації цих цілей, нам і самим потрібен open source!

Учасники Lviv Hacktoberfest

Як community може вести розробку продукту

Ми вже з’ясували, що за розробку, підтримку, документацію і просування проєктів відповідає спільнота. Але як? Кому належить проєкт? Хто ним керує?

Є два способи, за допомогою яких можна зорганізувати роботу над проєктом open source.

1. Проєкт повністю контролює спільнота

Тут принцип простий: кожен учасник спільноти може повідомити про проблему або розв’язати її, створити pull request і з’єднати його з певною гілкою. У таких проєктах open source є один або кілька адміністраторів, що переглядають кожен pull request, кожне зареєстроване issue і наводять лад.

Адміністратори — це розробники програмного забезпечення, зазвичай засновники тих проєктів, які вони адмініструють. Наприклад, Стів Клабнік (Steve Klabnik) — це один з авторів мов програмування Ruby on Rails і Rust. Більшість з вас знають його як надактивного користувача твіттеру, але, крім того, він ще й адміністратор такого проєкту open source як Rust. Колись він писав, що понад місяць займався лише тим, щоб навести лад у списку issues, про які повідомляли учасники спільноти — видалити повторювані, закрити розв’язані або зібрати вимоги до незрозуміло пояснених проблем. Уже згаданий раніше Linux — це також проєкт, який повністю контролює спільнота. Лінус Торвальдс (Linus Torvalds), засновник цього проєкту, віддав його на повну опіку спільноті open source, хоча він і досі лишається тією людиною, що найактивніше розробляє, підтримує й адмініструє Linux.

2. Спільнота контролює проєкт лише частково

Над проєктом працює спільнота розробників, але є певна команда — центр спільноти, core, який ухвалює основні рішення щодо проєктів. Наприклад, популярний JavaScript-фреймворк Reactпідтримує спільнота, але керують ним розробники з компанії Facebook. Інший приклад — платформа для створення чатботів Botpress. Чимало людей працюють над цим проєктом, і я пишаюся бути серед них. Проте керівник проєкту — компанія Botpress.

Чи можна заробити на open source

Заробити реально, але невиправдано важко. Як звичайний малоактивний учасник певної спільноти ви не зможете одержати прибуток. Як власник проєкту або ентузіаст open source — можливо, хоча й малоймовірно. Ось кілька способів, щоб монетизувати цю ініціативу:

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

Для власників проєктів і деяких учасників спільноти:

  • Bug Bounty — це ініціатива, яка дає змогу розробникам програмного забезпечення отримати нагороду від власника проєкту за знаходження і розв’язання помилок у коді. Таку ініціативу підтримують, наприклад, Google, Microsoft, Reddit, Yahoo й Facebook. Доволі часто такі ініціативи перетинаються з проєктами open source.
  • Bountysource — це платформа, де люди пропонують грошову винагороду, якщо ви розв’язуєте певну програмну проблему. Як це пов’язано з open source? У деяких GitHub-проєктах ви можете зауважити таке речення: «Want to back this issue? Post a bounty on it! We accept bounties via Bountysource». Ось це і є ваш шанс заробити!
  • Крім того, можна спробувати знайти спонсорів, які підтримуватимуть власників проєкту, найактивніших учасників спільноти або програмістів, які розв’язуватимуть найскладніші проблеми.

Хай там як, а заробіток — не основна мета участі в open source. Тоді виникає запитання: навіщо?

Для чого брати участь в open source

Усі знають, як важко знайти роботу людині без досвіду. Open source — це досвід, який ви можете сміливо згадати у своєму CV. Якщо HR запитає вас, чи знаєте ви React, то вразьте його й скажіть, що належите до спільноти розробників цього фреймворку! Або ж реалістичніший приклад: сконтактуйтеся з кимось з community й прилучіться до підтримки менш розкрученого проєкту (наприклад, Svelte) на місяць. Ви й користь зможете принести проєкту, й цікаві знайомства здобути, і, звісно, у резюме зможете це згадати.

Open source — це чудова нагода вдосконалити свої знання й навички програмування без курсів і без книжок. Коли ваш pull request перевіряє Ден Абрамов (Dan Abramov) або той самий Стів Клабнік (Steve Klabnik), то ви думаєте про якість коду й про зауваження до нього куди більше, ніж коли пишете код для себе або на курсах. І повірте, ці хлопці знають «трохи» більше за пересічного тимліда з вашого міста, а отже, є і більше речей, яких можна й повчитися в них.

Open source — це соціальна відповідальність. Ви розв’язуєте один баг в проєкті open source й автоматично розв’язуєте його для всіх, хто використовує цей продукт. Наприклад, розв’язуючи одну проблему в Botpress, я ще додав підтримку української мови на платформі.

Як можна долучитися до Open Source

Прилучитися до open source просто. Зробити це добре — трохи важче, але цілком реально. Правила гри доволі прості:

  1. Якщо ви використовуєте певний продукт open source (бібліотеку, фреймворк, операційну систему, програму...), підтримайте мотивацію людей, які до нього докладають зусилля. Поставте їм зірочку, лишіть декілька дописів до наявних issue, висловіть подяку комусь із розробників. Не уявляєте, скільки відкритих проєктів це могло б урятувати від занепаду.
  2. Якщо ви знаходите помилку в проєкті open source, що його ви використовуєте, — відкрийте GitHub проєкту й повідомте про проблему. Повідомити про проблему можна добре, а можна погано. Щоб повідомити погано, напишіть, що проблема є, але не описуйте її, не розповідайте деталі й не додавайте зображень. Ба більше, напишіть це «на емоціях» і звинуватьте адміністратора в поганій підтримці проєкту: «ВАША ПРОГРАМА НЕ ПРАЦЮЄ!!! ЗРОБІТЬ ЩОСЬ!!!» Так ви, звісно ж, «підвищите» мотивацію людей, які працюють над проєктом (зазвичай у вільний від роботи час на безоплатній основі) й змусите їх потренувати свої детективні навички в розумінні ваших натяків на існування проблеми. Щоб повідомити про помилку добре, зробіть навпаки — додайте ідеальний опис того, що сталося та за яких умов, а ще ліпше, зробіть знімки екрана, на яких проблему буде видно. Ось гарний приклад того, як створювати опис помилок, з якими розробниками приємно працювати:

  3. Якщо можете розв’язати проблему, яку знайшли ви або хтось інший, то розв’яжіть її і зробіть pull request. Pull request теж можна зробити добре й погано. Щоб виконати його погано, проігноруйте всі інструкції та гайди, зробіть багато невмотивованих або непояснених змін, ігноруйте стиль коду, не пишіть тестів і не ведіть документацію. У результаті ваш PR висітиме місяцями й відбиратиме енергію на спілкування й пояснення потреби в дотриманні стандартів у команді. І, можливо, так і не буде прийнятий. Щоб зробити pull request добре, уважно прочитайте й використайте Contribution Guidelines — опис основних принципів і правил роботи з певним проєктом, а також зважайте на те, у яку гілку ви мерджите свій pull request.

Ще один спосіб стати частиною спільноти open source — це відвідувати заходи, що вона проводить. Наприклад, Hacktoberfest — це рух, що підтримує open source й щороку проводить жовтневі хакатони в усьому світі. У Львові ця подія вже відбувалася 2018 і 2019 роках за підтримки компанії KeenEthics. Читайте в пресрелізіпро те, як це було.

Як розпочати

Багато хто думає: «Я не такий кваліфікований, щоб викладати щось на GitHub». З чого ж розпочати в такому разі?

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

Крім того, можете зорганізувати собі імпровізовану менторську програму. Серед друзів або колег знайдіть когось досвідченішого, хто вже підтримує open source, і попросіть його поділитися досвідом. Попросіть оцінити ваші технічні навички, попрацюйте пліч-о-пліч з ними й разом зробіть ваш перший pull request на GitHub.

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

Підсумуємо

Участь в open source навряд принесе вам фінансову вигоду. Однак вона подарує щось більше — задоволення собою, нестандартні головоломки для тренування мозку, спілкування з цікавими людьми й безцінний досвід. Якщо хочете дізнатися більше про те, як і навіщо ставати учасником цієї спільноти, пишіть на oleksiy.pletnov@keenethics.com. Якщо переконувати вас більше не треба, відкривайте GitHub, повідомляйте про issue і робіть ваш перший pull request.

Reverse Engineering — необходимый инструмент “заимствования” для Game Designer

$
0
0

Всем привет! Меня зовут Юра Сысоев, и вот уже 7-йгод я занимаюсь в индустрии задачами разного плана — от создания концептов новых проектов до детализации гейм-дизайн-документа (ГДД) и пострелизного анализа продуктов. Долгое время анализировал входящие запросы на создание продукта, и благодаря порой «очень качественным» из них был вынужден найти решение, которое позволяло бы получать результат за короткий промежуток времени.

Таким подходом стал «обратный инжиниринг» (Reverse Engineering) — исследование некоторого готового устройства (или программы), а также документации на него с целью понять принцип его работы © Wiki. Используя данный подход, я начал тратить меньше времени на запросы, выдавать качественный результат в короткие сроки, и проект получил финансирование. Для удобства далее я буду называть обратный инжиниринг реверсом.

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

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

Что такое Reverse Engineering

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

Некоторые слова в цитате пришлось заменить, так как в Лурке обычно пишут более экстравагантно — мат через мат.

Так вот, Reverse Engineering (ревёрсинг, обратная разработка) — это процесс «заимствования», восстановления исходников из конечного продукта инженерной и/или научной деятельности с интуитивным конструированием внутренней механики по принципу «а какие процессы должны вызвать такое внешнее поведение этого продукта?». Ориентируясь на нюх, так сказать. Иногда приводит к написанию собственного дока. Много их, ибо ваистену... © Lurkmore

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

Совет:никогда не пишите документы «просто, чтобы написать документы». Поставьте конкретную видимую цель и конкретный результат, которого хотите достичь. К примеру, вы хотите, чтобы прыжок вашего героя отлично ощущался с точки зрения контроля, например как в Super Mario Bros. Вы начинаете долгую разработку документации с тестированием с прототипами и т. д. Но что вы можете сделать вместо этого? Включить «Супер Марио» и проанализировать механику прыжка, выписать это все в документ и отдать в разработку. Важно понимать, что реверс нужно делать только тогда, когда вы точно понимаете, зачем он нужен, и только в случае, когда вы не делаете артхаус инди Death Stranding для эмуляторов андроид-устройств...

То есть, если вы делаете «Матч-3», то не выдумываете велосипед, вы идете играть в Candy Crush Sagaили Homescapesи смотрите, как у них все работает. В данных проектах аудитория давно известна, и она привыкла к некоторым стандартным механикам игр «Матч-3». Если им предложить что-то «слишком уникальное», есть шанс, что вы отпугнете свою целевую аудиторию (ЦА). Я не говорю о том, что нужно создавать клоны, речь о грамотном анализе с целью сокращения вашего же времени при написании или создании общеизвестных игровых механик.

Зачем нужен Reverse Engineering

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

Разберем на примере. Вы делаете продукт из серии «Матч-3». Вам нужно понять, какие М3-элементы-«блокеры» необходимо вставить в начальный игровой цикл (самые важные для продукта 20–30минут игровой сессии). Чтобы не отпугнуть пользователя и не сделать игру слишком простой или сложной, делать это нужно очень аккуратно. Поэтому вы можете потратить кучу ресурсов и человеко-часов на создание документации, прототипирование и анализ или «выписать» задачу для гейм-дизайнера на реверс-инжиниринг 3–5топ-игр данного жанра. Впоследствии вы получите небольшую выборку по элементам типа «М3-блокер» для первых 30 минут игровой сессии и сможете на основании этих данных либо принять решение об интеграции какого-то из «блокеров» в свой продукт на ранних стадиях, либо будете анализировать дальше. В любом случае такой подход даст быстрый результат и сэкономит время.

Следующий пункт, который я хотел бы отметить, — «наигранность». В моем понимании этот термин означает то, насколько хорошо вы знаете продукты схожего жанра и рынок в целом, а также, как хорошо вы ориентируетесь в игровых механиках. Приведу пример из личного опыта. Мой телефон выглядит как игровая приставка, на нем установлены на текущий момент порядка 100–150 игр,все они отсортированы по жанрам, типам и т. д. Что я делаю каждую неделю, так это иду в App Store или Play Market, захожу в фичер и скачиваю все игры, которые показались мне интересными. Дальше минимум 30–60минут играю в каждую из них. Во время игровой сессии я делаю быстрый поверхностный реверс. В случае, если нахожу интересную или уникальную, не известную мне до сих пор механику, начинаю углубляться в ее изучение.

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

Типы Reverse Engineering

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

Глобально реверс можно разделить на софтовый (Software), «ощущения» (How does it feel) и железо (Hardware). Последний нас не интересует, поскольку в рамках данной статьи мы затрагиваем только софт. Возможно, некоторые из вас могут разрабатывать новый Nintendo Switch, но реверс железа — это тема для другой статьи. Мы же остановимся на софтовом реверсе и реверсе «ощущений».

  • Software.
    • Code and technical approaches.
    • Core and meta mechanics.
    • Balance.
    • Interface.
    • Art style and animations.
    • Lvl design.
  • How does it feel.
    • User experience.
    • Sounds and music.
    • Narrative.
    • Overall impression.
  • Hardware.

Софт-реверс — это реверс, направленный на поиск интересных гейм-дизайнерских и технических решений. Тот же пример с «Супер Марио», о котором было написано ранее, — это софтовый реверс. Другой пример: как ведет себя звук на экране загрузки в Death Stranding (далее DS). Те из вас, кто уже успел оценить игру, могли заметить, что при полной загрузке уровня или главы в DS есть звук, который проигрывается на экране загрузки уровня. Дело в том, что загрузки в игре достаточно продолжительные, поэтому может случиться так, что игрок попросту уйдет, а то и вовсе забудет, что он ждет загрузку уровня. Я лично, пока идет загрузка в DS, играю на мобильном телефоне. Как этот вопрос решили гейм-дизайнеры? Через несколько секунд после полной загрузки звук на экране становится громче! :)

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

Реверс «ощущений».Называю я его так потому, что слово «ощущения» наиболее полным образом описывает то, что входит в задачу: описать ощущения от игры или игрового элемента. Возьмем в пример тот же DS. В игре, особенно в самом ее начале, имеются большие локации. На этих больших локациях Хидео Кодзима, на мой взгляд, хотел показать одиночество, и у него это получилось, потому что делать там реально нечего. И чтобы локация вызывала у вас именно «нужное ощущение», был применен ряд технических моментов, например: отдаление камеры в нужные моменты, звуки ветра и т. д. Помимо этого, была добавлена очень грустная музыка, которая подчеркивает одиночество игрока в данный момент. Если вы выключите звук и захотите пройти начальные локации DS без музыкального сопровождения, игра покажется вам очень скучной. Это и есть реверс «ощущений»: когда вы подмечаете эмоциональную составляющую игровой механики или элемента либо понимаете, какой опыт пользователя (user experience) создается в данный момент.

Далее, в софтовой части, идет реверс механик.С помощью реверса вы можете быстро получить информацию по интересующей вас игровой механике, скажем по прыжку главного героя (ГГ). Например: если вы хотите достичь идентичного результата, как в игре «Х», можно расчертить поле и считать по пунктам, пикселям или как вам будет удобнее расстояние прыжка, приземление, скольжение и прочие параметры механики. В Super Smash Brothers Ultimate, кстати, есть тренировочная локация, где разметка уже есть. Все, что вам необходимо, выписать это в документ в удобной для вас и ваших разработчиков форме. Также одним из решений «готового реверса» механик являются постмортемы и дневники разработчиков, в которых описываются приемы, методологии и другие подходы, с помощью которых создавались игровые механики.

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

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

Далее к софтовому реверсу я отношу интерфейсы (UI),но не опыт пользователя при их использовании (UX). Дело в том, что при софтовом реверсе вы подмечаете технические детали интерфейса, такие как зона или область нажатий — место, куда игрок достает пальцем и жмет чаще всего. Очень простой пример. Ваш продукт — Idle/Clicker (например, Tap Titans 2) в вертикальной ориентации, наиболее часто нажимаемая кнопка — улучшить ГГ. Вы берете и ставите данную кнопку в левый верхний угол, а 95% вашей ЦА — правши, которые играют на устройствах Android с 7-йдиагональю...

Как вы думаете, как скоро к вам прилетят «благодарственные» письма разъяренных игроков за такое «удобное» расположение кнопки? Уверен, очень быстро.

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

К последнему также я причисляю анимации,поведение кнопок или (ВАЖНО!) самого устройства. Приведу пример. Некоторые игры, в частности мобильная Call of Duty, для взаимодействия с пользователем и привлечения его внимания используют вибрации (доступны в большинстве современных мобильных устройств) — Haptic technology. Такие вибрации дают вам знать, когда игра найдена или стартует, когда вашего героя убили и так далее. Или, скажем, вы можете найти игры, в которых применяются красивые анимации и звуки при появлении окон, и они гармонично вписаны в игровой процесс. Все это я отношу к реверсу «ощущений» опыта игрока от использования интерфейсов.

На самом деле граница очень размыта, порой она и вовсе может исчезать, поэтому выбор, куда относить и как объединять элементы реверса, зависит только от вас. Если ваш продукт — игра, основанная на повествовании, к примеру красочная визуальная новелла, скорее всего, нужно будет сделать лаконичные окна, которые подчеркнут все прелести геймплея, а не миллион кнопок, как, например, в ММОРПГ-проектах.

Как итог, реверс «ощущений» — это то, как игрок чувствует происходящее на экране устройства, какие эмоции испытывает и какой опыт получает; и неважно, какой это будет тип реверса.

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

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

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

Я выделяю следующие типы реверса «ощущений»:

  • опыт пользователя от использования интерфейсов и игровых элементов (User Experience), об этом мы уже поговорили;
  • звуки и музыка (Sounds and music);
  • повествование (Narrative);
  • общее впечатление (Overall impression).

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

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

Представленный выше список типов реверса не статичен, вы можете без труда добавлять к нему те типы реверса и то количество пунктов, которые считаете необходимыми. Возьмем тот же нарратив, начитку диктора; они ведь тоже содержат технические параметры, например длину звуковой дорожки; если это текст, то его размеры и стиль шрифта, то есть, по сути, можно добавить нарратив в софтовый раздел. Я веду к тому, что все продукты разные («Спасибо, Капитан Очевидность!»); и в зависимости от жанра игры и содержащихся в ней элементов вы можете варьировать типы реверса, добавляя или удаляя ненужные куски. Нет же смысла делать реверс «ощущения» по звукам для продукта, в котором их не будет?

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

Reverse Engineering по тетраде элементов

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

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

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

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

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

Reverse Engineering с помощью AERM-таблицы

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

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

AERM-таблица состоит из стадий: A — Acquisition/привлечение; E — Engagement/вовлечение; R — Retention/возвращаемость; M — Monetization/монетизация. Именно в этом порядке пользователь в вашем проекте в идеале должен проходить стадии. Например: мы не сможем заработать на проекте (M), если не купили или не привлекли органический трафик на первой стадии (А). Помимо стадий, AERM-таблица разделена на столбцы согласно основным составляющим игры — Core, Meta, Social. Полагаю, все читающие уже знакомы с перечисленными базовыми понятиями.

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

Простой пример. Вы выпустили игру, к вам приходит пользователь. Первое, что должна делать хорошая игра, конечно же, сунуть пользователю под нос 5 красивых баннеров «Купи все за 99,99»... Конечно же, это не так :) Первое, что должна делать игра, это вовлекать пользователя в процесс (E), чтобы он остался в игре так долго (R), чтобы впоследствии заплатить (M). Как и в случаях с предыдущими подходами, вы сами вольны выбирать, какой из участков нуждается в реверсе.

AERM-таблица хороша не только на ранних стадиях проекта, когда вы начинаете разрабатывать первичную документацию, но и для анализа конкурентов. Как и в случае с тетрадой, здесь все просто: выберите необходимую стадию/составляющую и сделайте по выбранной части реверс. Например, вы скачали новую игру, и core-геймплей вас настолько увлек, что были готовы даже заплатить. Вы думаете: «Ничего себе, я тоже хочу, чтобы в моей игре Engagement работал так же хорошо!» И садитесь за реверс Core — Engagement. Или же, к примеру, вы делаете «Матч-3» и хотите, чтобы социальные взаимодействия ежедневно возвращали ваших пользователей в игру. Вы берете несколько игр жанра и делаете реверс Social — Retention. И так далее. Плюс реверса по AERM-таблице в том, что она покрывает все аспекты игры и при всей своей простоте является понятным, простым и очень эффективным инструментом. Дальше все зависит только от вас и жанра вашего проекта.

Советы по применению Reverse Engineering

Далее я хотел бы дать несколько советов по применению реверс-инжиниринга и подвести итог.

  1. Прежде чем приступить, решите для себя, нужно ли это вам? Как уже говорилось выше, не делайте реверс, только чтобы сделать его. Он должен иметь смысл.
  2. Реверс будет полезен не только в жанре своей игры, но и в других жанрах. Это поможет развивать наигранность, будет ориентировать в других жанрах. Да и кто знает, какой «клад» вы найдете в другой игре :)
  3. Выберите тип и установите правила реверса. Сформулируйте правила игры: чем конкретнее будет поставлена задача, тем лучше вы получите результат.
  4. Всегда записывайте то, что показалось вам стоящим. Все запомнить невозможно, и, увы, иногда случается так, что новая интересная механика, которую вы нашли в одной из сотен игр, просто забудется. Поэтому настоятельно рекомендую делать даже минимальные записи элементов, которые вы сочли интересными.
  5. Делайте скриншоты, а еще лучше — видео интересующих вас элементов. Визуальные референсы отлично подкрепляют описанную механику, вашей команде будет намного проще ориентироваться в документе, а вам — лучше понимать, какого результата ждете и о чем идет речь.
  6. Не стоит реализовывать функционал, который вы зареверсили, только потому, что в другой игре он работает. То, что работает в референс-игре, необязательно подойдет вашей; поэтому никогда не спешите с реализацией функционала. Обсудите с командой или посоветуйтесь со старшими коллегами.
  7. Старайтесь оперировать цифрами и непредвзятым фидбэком. Данный совет связан с предыдущим. Если вам кажется, что вы «нащупали» что-то интересное, лучше потратить еще немного времени на поиск дополнительной информации и подтверждения эффективности найденной механики.
  8. Сделав реверс, покажите его коллеге и получите фидбэк. Всегда старайтесь получать фидбэк по выполненной работе, это позволит вам расти как профессионалу.
  9. Давая задачу по реверсу начинающему ГД, не забывайте о качественном фидбэке. Если вы ведущий гейм-дизайнер или продюсер и запросили джуна сделать реверс, непременно дайте своему коллеге фидбэк: это поможет вам быть на одной волне и качественно улучшит создаваемые реверс-документы.

В заключение

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

Бонус

P. S. Обещанные бонусы всем, кто дочитал до конца. По данным ссылкам вы найдете мою личную базу знаний, которая пополняется интересными материалами: Knowledge Base, а также доклады и выступления с прошедших конференций: Conference Reports.

Slim Docker image, или Как уменьшить вес Java-приложения

$
0
0

Приветствую, дорогой читатель DOU! Меня зовут Ростислав, я Java-разработчик в DGN Games, где работаю уже третий год. Это продуктовая международная компания, где большая команда занимается созданием онлайн-игр. Здесь я получил огромный опыт как в поддержке и доработке высоконагруженной системы, так и в построении микросервисной архитектуры приложения с нуля с использованием современного Spring Boot стека (включая всеми любимый Kubernetes).

В этой статье не будет информации о сборке кастомной ОС, сравнения существующих ОС, версий Java, документации по работе с Docker, так как подразумевается, что ты умеешь написать свой Dockerfile и собрать образ на его основе. Зато будет рассказ о том, как мне удалось построить Docker-образ весом всего ~100-200 MB, базирующийся на Debian Buster slim, с использованием Java (версия 13.0.2).

В чем проблема

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

Все Java-разработчики знают, что приложение может весить, например, 100 MB (вместе с зависимостями), но, чтобы оно успешно запустилось и выполняло свою задачу, ему нужен еще JRE (Java Runtime Environment), который весит в среднем 200 MB. Сюда же нужно добавить операционную систему (далее — ОС), где будет исполняться JRE, а это еще ~50-100 MB (если использовать slim-сборку). Итого получается 350-400 MB.

Размещая Docker-образы (images) в каком-нибудь удаленном хранилище (Container Registry), например ECR, можно значительно сократить время, потраченное на передачу (загрузку или скачивание) данных, чтобы размер образа занимал всего ~100-200 MB. Помимо времени, сокращается также и плата за тарификацию удаленного хранилища: например, ECR берет плату за объем хранилища и количество переданных данных (Data Transfer). Поэтому, экономя деньги компании и время на доставку образов, я написал эту статью, которая покажет, как уменьшить вес Java-приложения с использованием готовых инструментов JDK.

Напишем простое приложение

Я буду использовать Spring Boot версии 2.2.4.RELEASE, куда подключу базовые зависимости:

  • spring-boot-starter-web — для написания простого REST-эндпоинта и запуска приложения в embedded Tomcat.
  • spring-boot-starter-log4j2 — для работы с логированием от Apache Log4j 2.
  • jackson-dataformat-yaml — чтобы Spring смог проинициализировать конфигурацию логирования из YAML-файла.

Собирать приложение будет Maven, поэтому опишем для него POM-файл следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>slim-docker-image</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>13</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-websocket</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-yaml</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Само приложение не представляет из себя ничего интересного, поэтому не буду уделять ему много внимания, а просто покажу класс контроллера:

package com.example.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import static java.lang.String.format;

@Slf4j
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(@RequestParam(required = false) String name) {
        if (name == null) {
            name = "World!";
        }
        String response = format("Hello, %s", name);
        log.info("Created response '{}'", response);
        return response;
    }
}

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

После запуска вызовем эндпоинт GET запросом по адресу: localhost:8801/hello?name=Rostyslav

В итоге увидим в консоли примерно следующие логи:

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

А что получается по размеру Jar?

Размер получился маленький (всего 17,43 MB), за счет того, что были подключены только базовые зависимости; ничего особенного и слишком тяжелого не используется. Но в любом другом большом проекте, где используется много различных библиотек и фреймворков, итоговый размер может достигать 100 MB и даже больше.

Сборка Docker-образа

Возьмем за основу openjdk:13.0.2-slim-buster. Его размер составляет 409 MB:

Напишем простой Dockerfile:

FROM openjdk:13.0.2-slim-buster
RUN mkdir -p /jar
COPY ./target/slim-docker-image.jar /jar/app.jar
ENTRYPOINT ["java","-jar","/jar/app.jar"]

и соберем образ. Итоговый размер получился 427 MB:

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

Теперь проанализируем, сколько занимает установленный туда JDK 13.0.2:

Как видно на скриншоте, JDK занимает 316 из 409 MB размера всего образа.

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

Модули, jdeps и jlink

Для сборки кастомного slim JRE я буду использовать модульную систему, которая введена с 9-йверсии Java. Полное ее название — Java Platform Module System, или JPMS. На помощь также придут инструменты jlink и jdeps, которые поставляются вместе с JDK.

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

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

jdeps -cp "java -jar target/slim-docker-image.jar --thin.classpath" target/slim-docker-image.jar

Получается такой результат:

Как видим, есть модули not found, что не дает понимания, каких модулей в итоге не хватает. Изучая вопрос сборки JRE, я так и не смог добиться успешного вывода всех модулей из JAR, поэтому решил, что если даже после использования jdeps может броситься ClassNotFoundException, то почему бы самостоятельно не перебрать недостающие модули, запуская приложение на собранном JRE и анализируя stack trace? Тем более это не отнимает много времени, да и вообще, я уверен, что для других проектов не придется пересобирать новый JRE каждый день и даже каждый месяц. Это нужно будет сделать только в случае добавления новых зависимостей, да и то если они используют какой-то другой модуль, которого нет в сборке.

Итак, абсолютно для любого приложения требуется модуль java.base. Поэтому берем его и запускаем команду:

jlink --no-header-files --no-man-pages --compress=2 --strip-java-debug-attributes --add-modules java.base --output slim-jre

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

Пробуем запустить приложение на собранном JRE:

Бросился ClassNotFoundException: java.beans.PropertyChangeEvent. Идем сюда, в строку поиска вводим java.beans.PropertyChangeEvent и смотрим на имя модуля:

Добавляем его к команде jlink:

jlink --no-header-files --no-man-pages --compress=2 --strip-java-debug-attributes --add-modules java.base,java.desktop --output slim-jre

В этот раз бросается ClassNotFoundException: javax.naming.NamingException.

Снова идем в поиск и ищем javax.naming.NamingException, добавляем его модуль java.naming. Повторяем манипуляции до тех пор, пока приложение не запустится.

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

В итоге получился такой список модулей:

java.base,java.desktop,java.naming,java.management,java.security.jgss,java.instrument

Можем запустить приложение на собранном JRE и убедиться, что оно успешно работает, как и раньше:

Docker-образ с кастомным JRE

Берем за основу Dockerfile, который используется в openjdk, и модифицируем его таким образом, чтобы вместо установленного JDK использовался кастомный JRE. Ниже представлен уже готовый к использованию файл:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
FROM debian:buster-slim

RUN set -eux; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
# utilities for keeping Debian and OpenJDK CA certificates in sync
		ca-certificates p11-kit \
	; \
	rm -rf /var/lib/apt/lists/*

# Default to UTF-8 file.encoding
ENV LANG C.UTF-8

ENV JAVA_HOME /usr/java/openjdk-13
ENV PATH $JAVA_HOME/bin:$PATH

# backwards compatibility shim
RUN { echo '#/bin/sh'; echo 'echo "$JAVA_HOME"'; } > /usr/local/bin/docker-java-home && chmod +x /usr/local/bin/docker-java-home && [ "$JAVA_HOME" = "$(docker-java-home)" ]

# https://jdk.java.net/
# > Java Development Kit builds, from Oracle
ENV JAVA_VERSION 13.0.2
ENV JAVA_URL https://download.java.net/java/GA/jdk13.0.2/d4173c853231432d94f001e99d882ca7/8/GPL/openjdk-13.0.2_linux-x64_bin.tar.gz
ENV JAVA_SHA256 acc7a6aabced44e62ec3b83e3b5959df2b1aa6b3d610d58ee45f0c21a7821a71

RUN set -eux; \
	\
	savedAptMark="$(apt-mark showmanual)"; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
		wget \
	; \
	rm -rf /var/lib/apt/lists/*; \
	\
	wget -O openjdk.tgz "$JAVA_URL"; \
	echo "$JAVA_SHA256 */openjdk.tgz" | sha256sum -c -; \
	\
	mkdir -p "$JAVA_HOME"; \
	tar --extract \
		--file openjdk.tgz \
		--directory "$JAVA_HOME" \
		--strip-components 1 \
		--no-same-owner \
	; \
	rm openjdk.tgz; \
	\
	jlink --no-header-files \
          --no-man-pages \
          --compress=2 \
          --strip-java-debug-attributes \
          --add-modules java.base,java.desktop,java.naming,java.management,java.security.jgss,java.instrument \
          --output /usr/java/slim-jre \
    ; \
    rm -r $JAVA_HOME; \
    mv /usr/java/slim-jre $JAVA_HOME; \
	\
	apt-mark auto '.*' > /dev/null; \
	[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
	apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
	\
# update "cacerts" bundle to use Debian's CA certificates (and make sure it stays up-to-date with changes to Debian's store)
# see https://github.com/docker-library/openjdk/issues/327
#     http://rabexc.org/posts/certificates-not-working-java#comment-4099504075
#     https://salsa.debian.org/java-team/ca-certificates-java/blob/3e51a84e9104823319abeb31f880580e46f45a98/debian/jks-keystore.hook.in
#     https://git.alpinelinux.org/aports/tree/community/java-cacerts/APKBUILD?id=761af65f38b4570093461e6546dcf6b179d2b624#n29
	{ \
		echo '#!/usr/bin/env bash'; \
		echo 'set -Eeuo pipefail'; \
		echo 'if ! [ -d "$JAVA_HOME" ]; then echo >&2 "error: missing JAVA_HOME environment variable"; exit 1; fi'; \
# 8-jdk uses "$JAVA_HOME/jre/lib/security/cacerts" and 8-jre and 11+ uses "$JAVA_HOME/lib/security/cacerts" directly (no "jre" directory)
		echo 'cacertsFile=; for f in "$JAVA_HOME/lib/security/cacerts" "$JAVA_HOME/jre/lib/security/cacerts"; do if [ -e "$f" ]; then cacertsFile="$f"; break; fi; done'; \
		echo 'if [ -z "$cacertsFile" ] || ! [ -f "$cacertsFile" ]; then echo >&2 "error: failed to find cacerts file in $JAVA_HOME"; exit 1; fi'; \
		echo 'trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$cacertsFile"'; \
	} > /etc/ca-certificates/update.d/docker-openjdk; \
	chmod +x /etc/ca-certificates/update.d/docker-openjdk; \
	/etc/ca-certificates/update.d/docker-openjdk; \
	\
# https://github.com/docker-library/openjdk/issues/331#issuecomment-498834472
	find "$JAVA_HOME/lib" -name '*.so' -exec dirname '{}' ';' | sort -u > /etc/ld.so.conf.d/docker-openjdk.conf; \
	ldconfig; \
	\
# https://github.com/docker-library/openjdk/issues/212#issuecomment-420979840
# https://openjdk.java.net/jeps/341
	java -Xshare:dump; \
	\
# basic smoke test
#	javac --version; \
	java --version

# "jshell" is an interactive REPL for Java (see https://en.wikipedia.org/wiki/JShell)
CMD ["jshell"]

В строке 47 я добавил создание кастомного JRE, в строках 54 и 55 удалил установленный JDK и вместо него поместил собранный.

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

Теперь самое интересное. Собираем образ и смотрим на его размер:

Получилось 141 MB вместо 409 MB, что не может не радовать.

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

Модифицируем Dockerfile-приложения

1
2
3
4
FROM rostyslavm/slim-jre:1.0.0
RUN mkdir -p /jar
COPY ./target/slim-docker-image.jar /jar/app.jar
ENTRYPOINT ["java","-jar","/jar/app.jar"]

В строке 1 я использую образ, который отправил в Docker Hub.

После сборки образа, используя вышеуказанный файл, получаем slim-вариацию, которая весит 159 MB вместо 427 MB:

Создаем контейнер и убеждаемся, что приложение успешно работает:

Спасибо за внимание! Буду рад получить фидбэк, это будет мотивировать меня писать и на другие темы.

Если остались какие-то вопросы, можно писать в комментариях к статье и стучать мне в Telegram.

На Шри-Ланку за досягнення цілей та в Нью-Йорк за 10 років у компанії. Як організовано закордонні подорожі ІТ-команд

$
0
0

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

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

Знайшлося кілька кейсів, коли співробітники отримують поїздку як винагороду. Наприклад, команди appflame та BetterMe вирушають у подорож (Балі, Шри-Ланка, Іспанія тощо), щойно досягнуть визначених бізнес-результатів, Tranzzo організувала подорож до Франції за перемогу у внутрішньому хакатоні, а Symphony Solutions винагороджує найлояльніших співробітників: за 5 років роботи в компанії вони їдуть до Амстердама, а за 10 — до Нью-Йорка.

Найчастіше компанії покривають перельоти, проживання та активності, які самі організовують. У деяких випадках оплачують навіть харчування. Цікавий кейс у Binary Studio. Компанія оплачує екскурсії, роботу гідів, чайові, фуд- та паб-краули, а ось перельоти і проживання — за кошт учасників (крім джуніорів, їм покривають 50%). Судячи з того, що в компанії відбулося вже 6 поїздок у такому форматі, він цілком дієвий.

Щодо того, чи можна брати в подорож членів родини та дітей — кожна компанія вирішує по-своєму. Хтось наголошує на тому, що подорож організовують передусім для того, щоб співробітники спілкувалися між собою, тож «+1» не беруть у будь-якому разі. Деякі компанії беруть, але члени родини самі сплачують подорож, а є й ті компанії, що покривають і їхні витрати повністю. У SMART business подорож була з самого початку задумана як об’єднувальний сімейний відпочинок — компанія бере в поїздку та покриває витрати всіх членів родини. І таким чином поки що б’є рекорд (принаймні в цьому огляді) з кількості осіб, які брали участь в одній поїздці — 320 людей їздили до Вільнюса (Литва)!

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

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

Astound Commerce

Закордонні поїздки проводять кілька років поспіль. Найпопулярніші напрямки: Угорщина, Туреччина, Єгипет, Греція та Словаччина. Були й поїздки в Індію.

Серед цілей закордонних тимбілдингів:

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

Зазвичай у поїздці беруть участь від 10 до 30 спеціалістів.

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

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

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

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






SMART business

Здійснили 3 закордонні подорожі: до Угорщини, Словаччини й Литви.

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

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

Поїздка триває 4 дні. У програмі є колективні активності (байдарки, тролей, гольф), екскурсії, квізи, забіги на 1, 3, 5 км, конференція, вечірка й дискотека, є вільний час на розсуд співробітників. До загальних активностей не примушують долучатися, але в компанії кажуть, що беруть участь майже всі.

Для кожної подорожі продумують головну ідею. Востаннє це була Grand White Party: 300+ учасників біля озера на тлі великого готелю білого кольору. Усі, включно з дітьми, одягнені відповідно до дрес-коду.

SPD-Ukraine

Провели дві закордонні поїздки в Туреччину (2011) та Єгипет (2015). Тепер їх не організовують, оскільки компанія значно виросла й складно везти в подорож усіх. Зараз співробітники об’єднуються в групи за бажанням і подорожують самостійно.

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

Під час поїздки в Єгипет компанія оплачувала 60% від вартості туру. Могли приєднатися й члени родин, вони оплачували свій тур самостійно.

Поїздка тривала 5 днів. У програмі пропонували екскурсії на вибір, настільні та спортивні ігри. Кожен обирав те, що йому до вподоби.

Symphony Solutions

Здійснили 4 поїздки. Відвідали Амстердам і Нью-Йорк.

Мета — винагородити найлояльніших співробітників компанії. Поїздка в Амстердам — для тих, хто з компанією 5 і більше років; до Нью-Йорка їдуть ті, хто в компанії понад 10 років. Наразі понад 50 людей відвідали Амстердам, а двоє побували в Нью-Йорку.

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

Поїздки дають змогу спеціалістам побачити, що саме стало натхненням для створення Symphony Solutions. Усі офіси в різних локаціях оформлено в стилі Зансе-Сханс, невеликого села-музею просто неба поблизу Амстердаму, яке співробітники відвідують під час поїздки. Наприклад, воно надихнуло додати в інтер’єр офісу вітряки й дерев’яні будинки, що виконують роль офіс-румів.

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

Поїздка в Амстердам зазвичай триває 3 дні, їдуть групами по 12-15 осіб;у Нью-Йорк — 1 тиждень, 1-2 особи.Компанія надає певну суму коштів на поїздку, якими спеціаліст може розпорядитися самостійно. За бажанням можна докласти свої кошти та залишитися в Нью-Йорку на 2 тижні. Так співробітниця, що відвідала Нью-Йорк, окрім музеїв і визначних пам’яток, подивилася мюзикл «Чикаго» на Бродвеї та потрапила на концерт Мадонни.

В Амстердамі в програмі багато музеїв і прогулянки містом.

appflame

За кордон подорожували 6 разів. Відвідали Чехію, Єгипет, Кіпр, Шри-Ланку та двічі Іспанію.

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

Компанія оплачує переліт, п’ятизіркові готелі All Inclusive, екскурсії, трансфер, солодощі в дорогу, страхування.

Подорож зазвичай триває 3-4 дні,до Шри-Ланки їздили на 7 днів. Під час планування подорожі вибирають декілька варіантів екскурсій, опитують команду та бронюють те, що вибрала більшість. Під час подорожі завжди заплановано одну екскурсію, яку просять відвідати всіх. Щовечора компанія разом вечеряє, обмінюючись враженнями.

BetterMe

Мандрували за кордон двічі: 2018 року до Шри-Ланки, 2019-го —на Балі.

Поїздки організовують як винагороду співробітникам за бізнес-досягнення. У компанії впевнені, що подорожі підвищують згуртованість і рівень довіри в команді. Запрошують усю команду (наприклад, на Балі їздили 65 осіб без членів родин).

Компанія оплачує дорогу, проживання, їжу, заплановані активності.

Подорож на Балі тривала 4 дні. У програмі були різні види активностей: відвідали культурні та природні пам’ятки (древні храми, вулкан, ліс мавп), навчалися серфінгу, спостерігали за заходом сонця, спробували снорклінг тощо.





Binary Studio

Усього поїздок було 6. Щоразу це 2-3країни та 3-4 міста.За цей час відвідали Німеччину, Францію, Італію, Нідерланди, Португалію, Угорщину, Польщу, Австрію, Бельгію, Словаччину.

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

Здебільшого за одну поїздку компанія оплачує 3-4 екскурсії,роботу гідів, чайові, фуд- та паб-краули. Джуніор-девелоперам покривають 50% витрат на дорогу та проживання. Решта учасників оплачують вартість перельотів і проживання самостійно.

Як правило, поїздка триває 5-6 днів.Найдовша тривала 7 днів. People Operations команда розробляє декілька варіантів маршрутів, з яких вибирають оптимальний за вартістю та цікавістю. Як кажуть у компанії, маршрут планують ретельно й складають похвилинний розклад. Зазвичай програма містить велотур містом, відвідування музеїв, різдвяних ярмарків, спільні ланч і вечерю. В основному всі учасники дотримуються програми та майже весь час проводять разом.

Сodeminders

Здійснили 2 поїздки — до Словаччини та Єгипту.

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

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

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

iDeals Solutions

Здійснили 3 поїздки — до Словаччини (Татранська Ломниця), Греції (Халкідіки) й Туреччини (Каппадокія).

Позаяк офіси компанії є у 8 країнах, мета подорожі — не лише відпочинок, а й знайомство між собою всіх членів команди. Їздять починаючи з 2018 року (на той рік також припало 10-річчякомпанії, тому поїздок було навіть дві). Поки що подорожі організовують постійно з однаковою періодичністю, але в компанії зазначають, що думають над тим, як пов’язати закордонні тимбілдінги з досягнутими результатами. До участі запрошують усю команду (у Туреччині, наприклад, побувало 120 людей), однак без членів родини. Якщо в останню мить хтось через особисті обставини не може поїхати в подорож, його місце пропонують новачкам, що вже підписали офер, але ще не вийшли на роботу.

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

Середня тривалість поїздок — 3-4 дні.Програму складають так, що майже завжди є можливість вибрати з кількох активностей. У Каппадокії, наприклад, літали на повітряних кулях, каталися на лижах і сноубордах на гірськолижному курорті, ходили на екскурсію до печер і провели тематичну вечірку. Як зазначають у компанії, тимбілдінг у Каппадокії посів друге місце на конкурсі Best Event Awards World 2019 у категорії «Найкращий тимбілдінг», що проходив у Мілані.

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

InterLink

Здійснили 4 поїздки, з них 3 до Туреччини й 1 до Єгипту.

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

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

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

Yukon Software

Здійснили 5 подорожей. Відвідали Угорщину, Польщу, Австрію, Словаччину, Німеччину, Латвію, Литву, Естонію, Чехію, Румунію, Молдову й Нідерланди (по кілька країн за раз).

Мета — заохочення співробітників, пізнання світу, відпочинок. Корпоративні подорожі проводять з 2014-гороку постійно раз на рік. Спершу їздили взимку, тепер у травні. Запрошують усіх співробітників. Бере участь приблизно 50-60осіб + 50-60«половинок» / братів / сестер / дітей. Наприклад, 2019 року їхало близько 120 людей — два туристичні автобуси.

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

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





P-Product

Здійснили 7 подорожей. Відвідали Грузію, Ізраїль, Нідерланди, Чехію, Італію, Іспанію, Кіпр, Грецію.

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

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

У середньому поїздка триває 5-7 днів.Іноді це одне місто, де команда проводить усі дні, а іноді мінітур декількома містами або країнами. Країну вибирають методом колективного голосування. Під час поїздки передбачено колективні заходи (екскурсії, естафети, дегустації) й один вільний день для особистого відпочинку.




Railsware

Усього здійснили 4 поїздки. Перша була до австрійських Альп 2016 року. Згодом вирішили спробувати літній формат і вже побували в Греції, Італії та Хорватії.

Понад третина співробітників Railsware працює віддалено, тож поїздка — це спосіб познайомитися, поспілкуватися, дізнатися новини компанії й отримати нові враження. Подорожують постійно, раз на рік. Участь беруть усі без винятку full-time-співробітники, які пройшли випробний термін на час подорожі. Можна брати із собою членів сімей включно з дітьми. 2019 року їздило 130 осіб, якщо враховувати й членів сімей.

Компанія оплачує витрати співробітника та його/її партнера: перельоти, проживання в готелі, медичне страхування, харчування (сніданок і вечеря), а також організацію командоутворювальних заходів. Витрати на дітей і додаткові «плюшки» (номер з краєвидом на море, екскурсії, додаткове харчування) співробітники покривають самостійно.

Подорож триває 7 днів. У програмі 2-3бізнес-конференції (презентація результатів команд і стратегії подальшого розвитку, робота в групах над удосконаленням різних аспектів життя компанії), майстер-класи й тренінги з hard і soft skills, спільні сніданки й вечері з використанням рандомайзеру (розробили тул для випадкового вибору сусідів за столиком, щоб команда змогла краще роззнайомитися), великі командоутворювальні заходи (pool party, похід в аквапарк, квести тощо), спортивні заходи (волейбол, футбол, баскетбол), заходи, організовані співробітниками (наприклад, ранкова йога під керівництвом одного з інженерів), екскурсії та особистий час.

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

Synebo

Здійснили 2 поїздки — до Туреччини та Єгипту.

Подорожують з метою тимбілдингу раз на рік з ініціативи СЕО компанії. Перша спільна поїздка відбулася 2017 року до Карпат, 2018-гопоїхали до Туреччини (35 осіб), а 2019-го —до Єгипту (45 осіб). Запрошують усіх охочих співробітників.

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

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





Tranzzo

Усього було 4 подорожі. Відвідали Францію, Польщу, Німеччину й Нідерланди.

Поїздки — це частина постійного плану з тимбілдингів, а також винагорода. Зазвичай це пригода для невеликої частини команди — 1-3відділи (від 4 до 15 осіб).

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

Подорож як винагорода — це приз за перемогу у внутрішніх хакатонах. Таку традицію започаткували минулого року. Суть хакатону в тому, що співробітники об’єднуються в команди (за бажанням) й розробляють продукт, що так чи інакше пов’язаний зі сферою фінансових технологій. Для реалізації мають 2 місяці. Потім кожна команда презентує своє рішення журі. До журі входять учасники команди Tranzzo. У хакатоні 2019 винагородою стала подорож до Франції. Журі сподобалися обидва проєкти, тому поїхали дві команди. Подорож тривала 7 днів. 13 осіб проїхали майже 3000 км і побували в понад 10 містах Франції.

Компанія завжди оплачує дорогу й проживання. Інші пункти — варіативно — у кожній поїздці по-різному. Опції «+1» немає, оскільки поїздки розглядають як нагоду провести час з колегами.

У програмі може бути відвідування конференцій, екскурсії.

ViSoft

Здійснили 5 закордонних подорожей. Відвідали Німеччину, Італію, Чехію, Словенію, Нідерланди.

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

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

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

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





YouScan

Відбулося 2 подорожі — в Болгарію й Чорногорію.

Компанія YouScan має декілька локацій (Київ, Харків, Дніпро, Москва, Лондон). Поїздка дає змогу всім перезнайомитися, отримати спільні враження і, найголовніше, відпочити. Подорожують раз на рік, переважно влітку. Запрошують усіх співробітників, навіть тих, хто нещодавно приєднався до команди. Болгарію відвідало 43 співробітники, Чорногорію — 80.

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

Поїздка в Болгарію тривала 3 дні, у Чорногорію — 5 днів. У підготовці активно беруть участь топменеджери: щодо вибору напрямку, бюджету, програми й партнерів. На всіх етапах діляться інформацією з командою. У програмі лише відпочинок: жодних презентацій, стратегічних сесій або звітів не планують. У компанії зазначають, що намагаються не перегинати з плануванням, щоб відпочинок не був вимушеним. Зазвичай організовують не більше ніж 1-2загальних активності, на кшталт катання на яхті, поїздки до аквапарку або вечірки, але участь у жодній з них не обов’язкова. Решта часу — на власний розсуд людей.

Здоров’я ІТ-спеціаліста: біль у спині та проблеми з хребтом

$
0
0

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

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

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

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

Чому болить спина

Як розповів Антон Білостоцький, лікар ортопед-травматолог, кандидат медичних наук, керівник медичного центру КІНЕЗІО, причин для болю в спині може бути багато. Щоб відповісти на запитання, чому ж болить спина, варто почати з анатомії.

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

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

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

Захворювання опорно-рухового апарату

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

Викривлення хребта: сколіоз та сколіотична постава

Сколіоз діагностується у 2% пацієнтів і характеризується зсувом хребців відносно вертикальної осі, що призводить до патологічних змін усього організму. Перекіс кісток тазу — головна ознака.

Сколіоз у дорослих виникає внаслідок:

  • захворювання нервової та м’язової систем;
  • порушення метаболізму;
  • патології сполучних тканин;
  • травм.

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

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

Симптоми обох хвороб схожі. Для сколіозу та сколіотичної постави характерні такі прояви:

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

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

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

Остеохондроз: міф чи справжня хвороба

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

Зауважимо, що даний стан ніяк не пов’язаний з відкладенням солей, хоча така ідея вельми популярна.

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

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

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

Симптоми остеохондрозу:

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

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

Грижі та протрузії: операція — не єдиний вихід

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

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

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

Частіше за все проблеми виникають у поперековому відділі хребта. Слід уважно поставитися до таких симптомів:

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

Грижа — серйозне ускладнення протрузії

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

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

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

Не відкладайте лікування на потім!

Лікування спини базується на комплексному послідовному підході. Мета — зміцнення суглобів та хребта. Для цього сучасна медицина використовує такі методи:

  • корекція хребта — методика під назвою «короткий важіль»;
  • міофасціальний (глибинний) масаж;
  • фізіотерапія (включно з магнітотерапією, електротерапією, терапією лазером);
  • ЛФК — лікувальна фізкультура;
  • кінезіотерапія — заняття на медичних тренажерах, завдяки яким можна оцінити стан організму пацієнта та підібрати оптимальне дозоване навантаження.

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

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

«Швидка допомога» при болю в спині

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

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

Стояти чи сидіти

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

Як організувати робоче місце

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

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

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

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

Правильне положення:

  • кут нахилу спинки — від 100 до 110°;
  • руки треба покласти на рівну поверхню і зігнути у ліктях під кутом 90°;
  • ноги мають стояти на підлозі під кутом 90°.
Висота стола підбирається так, аби верхній край монітора був трішки вищий рівня очей. Відстань до нього коливається в межах від 45 до 70 см. Якщо стегна упираються в стільницю, шукайте нові меблі.

Пам’ятаємо, стілець підлаштовується під людину, а не навпаки!

Корсет як панацея

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

Фізична активність для тих, хто в IT

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

Розглянемо один з варіантів, що вважається найкращим для подолання болю в спині — плавання. Якщо існують протипоказання до інших видів спорту, Слава Баранський, співзасновник LIVE.LOVE, радить саме цей вид фізичної активності. Ну хоча б тому, що це відмінна форма аеробного навантаження з низьким рівнем впливу на спину і хребет зокрема, на відміну від бігу або інших тренувань з ударними навантаженнями. Вода у режимі 3D підтримує тіло, розслабляє та знімає напруження з усіх суглобів та м’язів. Разом з цим плавання допомагає зміцнити м’язовий корсет (особливо м’язи спини та кора). Результат — надійна опора та підтримка вашого хребта, тобто відсутність затисків та перекосів, які є причиною больових відчуттів.

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

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

Як плавання допомагає при болях в спині:

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

Масаж

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

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

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

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

Масаж допомагає впоратися з:

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

Досвід ІТ-компаній та фахівців

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

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

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

У Dev-Pro діє доповнення до медичної страховки — HealthCare Kit. Мета цього бонусу — покрити витрати фахівців на офтальмологію, стоматологію, відвідування спортзалу, вітаміни або спортивне харчування. Сума в HealthCare Kit збільшується з часом роботи в компанії, і працівники активно користуються пільгами. Якщо фахівцеві рекомендований лікарем ортопедичний стілець — його надають. А щоб попереджати будь-які захворювання або проблеми зі здоров’ям, для профілактики фахівці щорічно проходять курс масажу в офісі (також він доступний і за страховкою).

Масажне крісло в Yukon



А ось що кажуть ІТ-фахівці про власний досвід.

Віталій Маренков, Back-end developer в eTravel S.A.

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

А ще на роботі ходжу не до найближчої кухні, а до віддаленої — розминаю ноги ;)

Анна Топчій, Geocoder в Intetics

Я уже полтора года хожу на работу в корсете для корректировки осанки.

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

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

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

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

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

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

Олександр Литвиненко, Developer, Lead, Mentor в ProCode IT School

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

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

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

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

Соблюдайте несколько простых правил:

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

Вікторія Музичко, SSE в GlobalLogic

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

В какой-то момент я решила, что надо что-то предпринимать. Пошла к невропатологу в районную поликлинику, он назначил МРТ поясничного отдела позвоночника и направил меня к заведующему отделением в областной травматологии на Медкомплексе (Харьков). По результату МРТ, у меня латеральная протрузия L2 6 мм. Доктор назначил мне массаж (кабинет массажа прямо там, в отделении), стандартный набор Терафлекс+Хондроцерин и объяснил, что нужно снять спазм мышц спины и далее укреплять мышцы спины и кора. Упрощенно, поза сидя — самая убийственная для спины, а ходьба — самая полезная. Я начала курс массажа, и после первых сеансов область поясницы начала гореть огнём, причём массаж был не слишком интенсивный, буквально кончиками пальцев. Массажистка сказала, что такие ощущения — нормальны для первых дней. В конце курса я почувствовала облегчение. Продолжала пить лекарства и возобновила давно заброшенные занятия фитнесом. Тут мне очень повезло с тренером, я ей объяснила свои проблемы со спиной. Через несколько месяцев я перестала пить таблетки и стала регулярно заниматься спортом, боли в спине ушли.

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

На Форумі DOU можна знайти теми, присвячені здоров’ю опорно-рухового апарату.

  1. Грижа.
  2. Ортопедичний матрац.
  3. Протрузії.

Перевірено на людях, або Як і для чого починати A/B-тестування

$
0
0

Привіт, мене звуть Павло, я інжиніринг-менеджер у JustAnswer. Раніше — лід, перед тим — розробник. UMC, МТС, далі Conscensia й JustAnswer. Загалом уже майже 15 років в IT. Але маю дещо незвичний для розробника бекграунд: за освітою я соціолог. І це сильно допомагає під час роботи з продуктом — маркетинг, споживацька поведінка, розуміння бізнес-потреб. Останні чотири роки працюю в середовищі, де бізнес-рішення ухвалюються винятково після висування гіпотез та перевірки їх за допомогою A/B-тестування. Прилучився на стадії, коли складність гіпотез, які бізнес хотів перевірити, уперлася в стелю можливостей комерційної платформи A/B-тестування, що була в ужитку. І компанія постала перед вибором, куди рухатися далі.

Якщо ви задумалися про A/B-тестування на своєму ресурсі, то, імовірно, для вашого проєкту вже сформовано базові показники, які б ви хотіли поліпшити. Конверсія, фінансові метрики, поведінкові чинники — те, що актуально для вашого продукту або сервісу. Якщо таких метрик ще немає, то правильним кроком буде почати з їхнього визначення.

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

Трошки конспірології

Чи бувало таке, що ви побачили дуже привабливу пропозицію на сайті перевізника, а коли наважилися бронювати квитки, пропозиція випарувалася? Або дуже вигідно взяли пробну підписку на музичний сервіс, а того ж дня ваші друзі не бачать такої опції. Чи, можливо, ви просто тепер бачите, що сайт Amazon на комп’ютері вашого колеги має інший вигляд, ніж на вашому? Можна припустити, що за вами стежить Старший Брат (як в Орвелла), що є велика змова проти простих користувачів Інтернету і ви стали її жертвою.

Але ймовірніше, ви просто стали учасником A/B-тестування. І так, за вами стежать!

A/B-тестування. Що це таке

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

А можна простіше

Якщо зовсім просто, то для того, щоб дізнатися, чи насправді нову червону кнопку натискатимуть частіше, ніж стару синю, треба в той самий період часу одній половині відвідувачів показувати червону кнопку, а іншій — синю. І спостерігати. У такому разі контрольною групою будуть люди, які бачили стару синю кнопку (варіацію А). Мета тесту — порівняти їхню поведінку з поведінкою тих, хто бачив нову червону кнопку (варіацію B). Звідси й назва — A/B-тестування. Якщо одночасно хочуть перевірити більше варіантів змін, варіацій може бути більше. Тоді тест можуть позначати A/B/C/D/../N. Хоча найтиповішим усе ж є A/B. Кому показувати, які варіації та скільки спостерігати, теж не зі стелі беруть, але про це згодом.

Навіщо ті всі складності

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

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

На противагу традиційному підходу A/B-тестування дає змогу:

  1. Змінімізувати ризики, тому що гіпотетичне поліпшення буде доступне мінімальній кількості відвідувачів, достатній для ухвалення рішення щодо корисності гіпотези. Тут стає в пригоді математична статистика, яка дає змогу підрахувати розмір вибірки. На ці теми не одну дисертацію захистили, але формули відлякують читачів, тому просто скажу, що в онлайні є чимало калькуляторів, за допомогою яких можна це підрахувати. Наприклад, можна почати з простого: A/B Test Sample Size Calculator.
  2. Заощадити десятки людино-годин, бо є змога перевірити гіпотезу, опускаючи певні кейси або не імплементуючи фічу сповна. Наприклад, для тесту щось можна захардкодити на фронтенді, не імплементуючи колів на бекенд або не витягаючи якісь дані з бази, або не впроваджувати підтримку якихось екзотичних браузерів. Приклад:щоб перевірити гіпотезу, що продажі зростуть, якщо додати підтримку нової платіжної системи, перш ніж інвестувати саме в розробку такої можливості, можна додати саму кнопку «Заплатити через Х» і рахувати, скільки людей її натискають, щоб зрозуміти, чи це матиме попит. А тим, хто її натиснув, показувати повідомлення з вибаченням. Такий підхід ще називають Demand Test, або перевірка попиту.

А, B та їхні друзі

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

  • Поняття A/B-тестування й експеримент взаємозамінні в контексті цієї статті.
  • Вигляд сторінки до застосування змін називають контрольним (control) або нормальним (normal). Саме з ним порівнюватимуть тестовий, змінений вигляд (test).
    І control, і test — варіації (variation), що заведено позначати літерним індексом. Контрольна варіація А й тестова варіація B.
  • Якщо гіпотезу підтверджено, і ми хочемо повністю замінити оригінальний вигляд сторінки виглядом варіації, що виграла, цей процес називають нормалізацією.
  • Збір інформації про взаємодію користувача з елементами сторінки називають трекінгом (tracking). Наприклад, ми хочемо зафіксувати, якщо користувач натиснув кнопку. Нам треба зареєструвати унікальний ідентифікатор, пов’язаний із цією подією. Простими словами — додати трекінг.

Готуємо A/B-тест власноруч

Але досить голої теорії. Починаймо з’ясовувати.

На ринку є чимало достойних комерційних рішень зі своїми перевагами й недоліками для тих чи інших випадків і з різною ціновою політикою: Optimizely, VWO, Google Optimize, Adobe Targetтощо. Проте, якщо A/B-тестування стають невіддільною частиною процесу розробки й ухвалення бізнес-рішень компанії, згодом її потреби, безумовно, переростуть будь-який наявний продукт і потребуватимуть власних підходів. Тому в цьому матеріалі ми спробуємо з’ясувати, як воно працює, тримається купи та як можна розробити прототип платформи A/B-тестування, щоб ухвалити поінформоване рішення про вибір платформи.

Інгредієнти

Проаналізуймо складові процесу тестування й підготовлення експерименту.

Трафік

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

Випадковість

Важливо рівномірно й випадково поділити трафік між варіаціями. Кому дістанеться досвід А, а кому — B (або C, або D тощо, залежно від кількості варіацій)?

Трансформація

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

Відтворюваність

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

Відстеження активності

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

Гнучкість

Серед переваг A/B-тестування — гнучкість і динамічність. Запуск або зупинка тесту мали б відбуватися незалежно від релізу змін у продукті. Бажано навіть без участі інженерів. У процесі експерименту можуть виникнути обставини, коли тест тимчасово треба поставити на паузу або скоректувати параметри аудиторії.

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

Що під капотом

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

Ці підходи можна умовно поділити на Client Side (або Postload) і Server Side (або Preload).

Client Side

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

Архітектура

Є цільова сторінка. Сторінка завжди завантажує і намагається виконати JavaScript-файл, що хоститься окремо й може містити код A/B-тесту. Якщо ми тепер нічого не тестуємо, то файл просто буде порожнім.

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

Код A/B-тесту робить таке:

  1. Фільтрує трафік (опційно) — ухвалює рішення, чи є поточний відвідувач нашою цільовою аудиторією. Пристрій, браузер, розмір вікна, країна користувача, залогінений, історія покупок, чи вже є щось в кошику, на якому тарифному плані, які сторінки бачив перед тим тощо. На практиці це просто ifCondition, який виконує ряд перевірок і вирішує, чи застосовувати трансформації. Можна навіть додатковий запит на бекенд від імені користувача надіслати, щоб отримати деталі, потрібні для ухвалення цього рішення. Це може суттєво затримати виконання трансформацій, але деколи це єдиний спосіб перевірити гіпотезу.
  2. Визначає, чи користувач уже був на нашому тесті і йому слід показати відповідні зміни, чи це новий користувач, і треба призначити варіацію. Робимо це через cookie і рандомізацію.
  3. Виконує потрібні трансформації. Тобто перефарбовує, змінює розміри й положення елементів, усуває їх чи замінює на інші.
  4. Додає трекінг (опційно). Тут варто наголосити, що як до експерименту ми не цікавилися взаємодією користувачів із цільовими елементами, то доведеться додавати трекінг цих елементів і до оригінальної варіації також, щоб мати змогу ці варіації порівняти.

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

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

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

На JsFiddle можна побавитися із прикладом A/B-тесту, побудованого за цим підходом.

У цьому прикладі, якщо потрапити на варіацію B, то повторне натискання кнопки Run наочно продемонструє побічний ефект, як перемальовуються елементи за складних змін. Щоб змінити варіацію, треба почистити cookie.

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

Підсумки за Client Side

Pros:

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

Cons:

  • Залежно від серйозності змін у варіації, можуть бути побічні ефекти, коли користувач встигає побачити оригінальну сторінку й «дискотеку», коли все перемальовується. Для конкретних випадків можуть бути свої техніки боротьби з цим, але загалом це негативно впливає на швидкодію сторінки, і для користувачів на варіації сторінка відчуватиметься повільнішою, що вплине на їхню поведінку і, відповідно, на результати A/B-тестування.
  • Повільні сторінки гірші для SEO.
  • Якщо гіпотезу підтверджено, і ми готові застосувати зміни варіації-переможця для всіх, код тесту перевикористати не вдасться — доведеться правити код оригінальної сторінки.

Server Side

Тут, на відміну від Client Side, треба підготувати всі (у разі А/B їх буде 2) кінцеві варіанти сторінки (варіації) з можливістю доступу за окремими посиланнями. Варіацію визначають ще в процесі оброблення http-запиту, і користувач відразу отримує потрібний варіант сторінки без накладання змін поверх. Тоді вся архітектура А/B-тесту зведеться до раутингу й установлення cookie. Опційно, але бажано для швидкодії, сторінку можна кешувати.

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

Який вигляд у такому разі має архітектура A/B-тесту

  1. Користувач робить запит на URL і потрапляє на CDN Edge server, де крутиться наш Service Worker.
  2. Передусім ми перевіряємо наявність cookie в заголовках, щоб зрозуміти: він уже був на певній варіації і йому слід показати ту ж саму чи це новий користувач і варіацію треба вибрати випадково.
  3. Визначивши варіацію, прокидаємо запит на відповідний route. Якщо сторінка є в кеші, CDN віддає її звідти, якщо ні — запит надсилається на origin (наш web-server), а дорогою назад response кешується. Нагадаю, для кожної варіації повинна бути попередньо підготовлена сторінка.
  4. Перш ніж віддати response на клієнт, додаємо до нього Set-Cookie-заголовок з ідентифікатором варіації, щоб наступні запити потрапляли на ту саму варіацію.
  5. Вертаємо response з розміткою і cookie-варіації.

Приклад коду й пісочниця Cloudflare:

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

Щоб стартувати, зупинити або внести зміни в розподіл трафіку, ми просто передеплоюємо наш JavaScript у Service Worker доступними нам засобами — з адмінки або через API.

Як ми пам’ятаємо, трафік A/B-тесту потрібно таргетувати (фільтрувати). У разі Server Side ми можемо використати лише ту інформацію, що є в оригінальному запиті. Наприклад:

  • User Agent допоможе визначити браузер або пристрій;
  • Cookie;
  • IP дає змогу фільтрування за геолокацією;
  • Host. A/B-тест зазвичай розробляють для однієї/кількох сторінок сайту, для решти експериментального раутингу робити не треба.

Підсумки за Server Side

Pros:

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

Cons:

  • Оскільки для таргетування A/B-тесту ми можемо використовувати лише дані з оригінального http-запиту, у нас нема достатньої гнучкості у визначенні аудиторії тесту.
  • Для побудови простих A/B-тестів накладні затрати на розробку вищі, бо навіть мінімальна зміна потребує дублювання цілої сторінки для потреб варіації і внесення в неї змін.
  • Така методика добре підходить для лендинг-сторінок, адже вони однакові для всіх. Якщо сторінку кастомізують під конкретного користувача або вона містить багато динамічного контенту, переваги нівелюють.

Відстеження активності

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

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

Маючи такі дані на руках, можна дійти висновку, наприклад, що червона кнопка працює ліпше для користувачів 4k-екранів з Техасу вночі.

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

Архітектура

Як це можна організувати технічно? Знову ж таки на ринку є великі гравці, як-от: Google Analytics чи Facebook Analytics — кожний зі своїм API, набором правил й аналітичних інструментів. І навряд чи хтось зможе конкурувати з ними на полі даних й аналітики. Проте організовано це всюди приблизно однаково.

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

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

На підставі якогось набору анонімних й унікальних даних, доступних на клієнті (IP, session, agent), генерують GUID, до якого ці всі події прив’язуватимуть, щоб дані можна було правильно агрегувати.

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

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

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

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

Замість висновків

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

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


Как провести тестирование на безопасность Android-приложения

$
0
0

Всем привет! Меня зовут Святослав, работаю QA gangsta lead в EVO, а в тестировании уже более 8 лет. Ищу уязвимости свыше 4 лет, веду тренинги по тестированию безопасности, провожу независимые аудиты security и QA. Также у меня есть security QA-блогдля начинающих и Telegram-канал.

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

Вступление

В предыдущей статьея писал о том, как с Manual QA перешел к поиску веб-уязвимостей. К чему это я?! Когда занимаешься чем-то одним длительное время, оно надоедает, и я решил попробовать разобраться, как же происходят проверки на уязвимости в мобильных приложениях. Топик взял из списка OWASP TOP 10, только для мобайла. OWASP переехал, поэтому не смогу скинуть ссылку на официальный топик.

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

После того как я открыл список и ознакомился с мобильными топ-уязвимостями, понял, что половина из них полностью похожи на вебовские, то есть OWASP TOP 10 классический, который мы все так привыкли видеть. Так как, по сути, у нативных и веб-приложений один и тот же способ работы — по типу клиент-серверной архитектуры. То есть в мобайле клиентом является нативное приложение, а в вебе — браузер, но и у того, и у другого запросы поступают на сервер. Это и приводит к выводу, что половину техник можно взять из веб-уязвимостей, чтобы применить поиски дыр в нативных приложениях...

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

Что нам понадобится

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

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

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

В принципе все.

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

А теперь, думаю, пора перейти к разбору каждой из категорий. Начнем рассматривать их не по порядку, а с M9 — Reverse Engineering, так как пентест начинается именно с нее.

M9 — Reverse Engineering

Реверс-инжиниринг мобильного кода — обычное явление. Это процесс простого и несанкционированного анализа:

  • исходного кода приложения;
  • библиотек;
  • алгоритмов;
  • таблиц и т. д.

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

Выполняем команду unzip -d diva-beta base.apk. Как вы догадались, она разархивирует приложение и все файлы положит в папку, которую мы назвали diva-beta.

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

Для того чтобы открыть этот файл и начать изучать код приложения, нам понадобится приложение Jadx, которое также установлено в нашем дистрибутиве Linux. Выполняем команду jd-gui classes-dex2jar.jar.

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

M1 — Improper Platform Usage

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

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

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

M2 — Insecure Data Storage

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

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

То есть нужно помнить о двух моментах:

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

Как пример возьмем форму регистрации в мобильном приложении.

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

M3 — Insecure Communication

M3 — это еще один распространенный риск, о котором разработчики мобильных приложений забывают. Передача данных в мобильное приложение и из него обычно осуществляется через оператора связи или Wi-Fi. Известно, что злоумышленники добиваются успеха в раскрытии личной информации пользователей, если эта передача не защищена. Хакеры перехватывают данные пользователей в локальной сети через скомпрометированную сеть Wi-Fi, подключаясь к ней через маршрутизаторы, вышки сотовой связи, прокси-серверы либо используя зараженное приложение с помощью вредоносного ПО. При отправке запросов на сервер с данными, которые отправляет пользователь, некоторые из них иногда посылают по протоколу HTTP вместо HTTPS.

Пример эксплуатации такой уязвимости: злоумышленник создает скомпрометированную сеть Wi-Fi, к которой подключится пользователь. Затем этот man in the middle начинает анализировать весь трафик, который будет ходить через него. Соответственно, данные пользователя, которые отправляются к серверу по HTTP-протоколу, могут перехватываться. Злоумышленник будет видеть его креды в перехваченном пакете. Ниже приведены примеры, как передавать данные плохо и как — хорошо. Также можно посмотреть этот видосо перехвате трафика.

Плохо:

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

M5 — Insufficient Cryptography

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

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

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

На картинке выше видим, что разработчик применил метод хеширования MD5, который прям так и кричит: «Ломай меня полностью!» Это один из самых легких методов.

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

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

M4 — Insecure Authentication

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

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

Для примера: злоумышленник может использовать просто какой-то анализатор приложения, допустим тот же Burp Suite. Ему достаточно проанализировать, какие есть страницы у этого приложения.

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

В этом запросе можно:

  • обратить внимание на урлы;
  • обратить внимание на тип юзера;
  • попробовать подменить токен, подобрав нужный (с доступом к админским функциям), и т. д.

О том, как настраивать анализатор к мобильному приложению, я писал в статье о M3 — Insecure Communication.

M6 — Insecure Authorization

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

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

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

M7 — Client Code Quality

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

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

Не стоит использовать функции, которые могут переполнить буфер, вот так:

M8 — Code Tampering

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

  • к другим приложениям в вашем телефоне;
  • к поведению пользователя.
Помните, в M9 мы сделали реверс-инженерию приложения и знаем исходный код? Теперь можем его подправить (залить туда какого-то червя, который будет получать доступ к данным на других приложениях), затем заново скомпилировать и выложить APK на какой-то сайт с примечанием, что здесь его можно скачать бесплатно :)

M10 — Extraneous Functionality

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

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

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

Подытожим

Теперь вы знаете:

  • об OWASP Mobile Top 10;
  • инструменты, с помощью которых можно искать уязвимости;
  • программах, в которых можно попрактиковаться в поиске уязвимостей.

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

Машинное обучение против финансовой математики: проблемы и решения

$
0
0

Всем привет! Так получилось, что я уже около семи лет занимаюсь машинным обучением. В последние несколько из них я как исследователь и CTO Neurons Lab часто работаю с финансовыми данными в рамках проектов, связанных с инвестиционным менеджментом и алгоритмическим трейдингом. Чаще всего клиенты приходят с текущими стратегиями, которые нужно оптимизировать, или идеями с альтернативными данными, которые потенциально могут прогнозировать рынок. Конечно же, анализ данных в таких задачах — наше все. Наряду с большой ответственностью за капитал инвесторов :)

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

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

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

Проблемы эконометрики

Реальные данные сложнее, чем «цены, спрос и предложение»

Стандартная процедура в финансовой математике — взять временной ряд каких-то цен, обработать его с помощью time series differentiation, после чего построить какие-то модели распределения и показать, что эта модель описывает эти данные (безотносительно того, будь это ARIMA или стохастическое дифференциальное уравнение Фоккера-Планка).

В чем тут проблема?

  • Данные на рынках изначально не структурированы (отдельные заявки на торги, упоминания в новостях, финансовые отчетности), а эконометрические модели используют красивую последовательность цен (интересно, откуда они взялись?).
  • Очень низкое отношение сигнала к шуму.
  • Удаление памяти временных рядов (да-да, это про дифференциацию временных рядов, см. книгу).

Финансовые модели в большинстве своем работают с максимально неинформативными данными, еще и обрабатывая их неправильно и объясняя паттерны in-sample (об этом — дальше).

Корреляции и линейные зависимости ничего не объясняют

Из университета мы знаем, что корреляция объясняет меру линейной зависимости между двумя случайными величинами. Более того, мы даже слышали о том, что корреляция != причинно-следственной связи.

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

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

Самый простой пример того, как корреляция «лажает», виден на картинке ниже: очевидная нелинейная зависимость справа показывает корреляцию −0.008.

Image Source

Эконометрические модели объясняют прошлое, но ничего не предсказывают

Преимущественная часть финансовых моделей основана на объяснении вариативности данных внутри выборки. Мы привыкли в машинном обучении всегда считать ошибку на out-of-sample данных, и об этом создано много мемов, но в эконометрике, которая изначально позаимствовала свои методы из биологии, это просто не принято!

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

Только не показывайте этот мем эконометрикам

«Статистическая достоверность» недостоверна

Опять-таки, из университетского курса статистики мы знаем, что если мы получили p-value, достаточно низкое для какой-то переменной, то это значит, что мы отбрасываем нулевую гипотезу о неважности этой переменной и считаем ее «достоверной». Для того чтобы увеличить уровень достоверности, мы можем ставить границу для этого p-value. Часто оно равно 0.01 или 0.05.

Вот только это не совсем то, что нам нужно.

  • P-values требуют сильных предположений о данных и моделях (не коррелированные переменные, residuals распределены нормально, и так далее), которые практически не встречаются в реальном мире.
  • Нам вообще-то не так интересно опровержение гипотезы H0 in-sample, нас больше интересует подтверждение H1 out-of-sample.

Если что, то даже американская ассоциация статистиков не так-то положительно относитсяк этим p-values. Но расскажите об этом у себя на кафедре :)

Бэктестинг как способ исследований

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

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

Более того, бэктестинг — это все один большой и красивый набор данных in-sample. Сделать модель, которая хорошо заработает в прошлом, — проще простого, вопрос только в том, как она отработает на живых деньгах.

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

Чем больше экспериментируем — тем лучше результат. Как удобно, да? (см. книгу)

Машинное обучение поможет?

С эконометрикой и финансовым моделированием вроде разобрались, понятны проблемы и как машинное обучение может помочь. Почему же тогда у многих попытки обучить модели на исторических данных ни к чему не приводят? Пройдемся по тем же пунктам, но уже с указанием проблем машинного обучения в них. Кому интересно углубиться в тему, 14 марта я буду проводить воркшоп по этой теме на конференции Data Science UA Conference.

Сложные данные надо еще приготовить

Неструктурированные данные сами по себе — еще не панацея. Даже с сырыми данными с рынка (ticks) или с альтернативными данными как sentiment нужно еще серьезно поработать.

Правильный семплинг данных

Зачем вы считаете свечи каждые N минут? Рынок ведь работает не по часам, а по ивентам: намного логичнее делать свечи каждые X долларов торгов или похожим образом (см. Bars).

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

Примеры сырых цен, временных, «объемных» и «долларовых» свечей

Также можно увидеть, что свечи, созданные на основе периодов времени, имеют намного меньше вариативности, чем другие:

Вариативность цен внутри разных свеч

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

Правильная нормализация данных

Известное нам дифференцирование временного ряда напрочь удаляет всю память об эволюции цен (см. Fractional differentiation).

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

Пример работы fractional differentiation. Image Source

Анализ ADF-статистики (о стационарности временных рядов) и разные параметры fractional differentiation: от 0 до 1. Как видим, оптимальные параметры всегда меньше или равны 0.5!

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

Поправка на IID-гипотезу

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

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

Скорее всего, получится так, что большая часть примеров в выборке будет «не уникальными».

Правильный выбор таргета для прогнозирования

В мире с stop losses и take targets прогнозировать цену через N часов — глупость. Наш таргет должен быть максимально похожим на принятие решения (см. Triple barrier labeling).

Техника triple barrier labeling позволяет размечать данные на основе «окна будущего». Например, если мы хотим открыть сделку в следующий час, нам нужно прогнозировать не что произойдет ровно через час, а каким будет максимальное движение цены и в какую сторону в течение этого часа (а вдруг ровно через час цена пойдет вверх на 1%, но в течение этого часа будет бОльший скачок на 5%?). Визуально эта техника представлена на иллюстрации ниже:

Пример того, как надо размечать данные в пределах одного окна «в будущем», Image source

Что делать с зависимостями?

Раз мы решили, что корреляция (или, что еще хуже, какие-то околоэвклидовые метрики) не подходит для определения зависимостей или меры схожести, что мы можем тут использовать? Я вижу два пути:

  • «Литературный»: использовать меры на основе теории информации (например, mutual information ratio) или статистические расстояния (KL divergence, EMD и так далее).
  • «ИИ-шный»: использовать подходы metric learning, возможно, на основе автоэнкодеров или сиамских нейронных сетей.

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

Как мы видим, метрики как information variation и max correlation, о которых можно детальнее прочесть тут, справляются намного лучше с выявлением нелинейных паттернов.

Кросс-валидацию тоже надо сделать правильно

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

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

Image Source

Значимость факторов out-of-sample

Да, feature importance — это выход для замены p-values. Но его тоже нужно использовать out-of-sample. В идеале — совместить с вышеописанными методами кросс-валидации и считать распределение важностей на кусочках кросс-валидации. Таким образом мы сможем понять предсказательную значимость фич «по-настоящему». Более детально метод можно изучить и запустить код в этой статье.

Пример важности факторов для настоящего датасета с несколькими искусственными шумами для валидации метода

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

Бэктестинг — это не способ исследований

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

Мы поговорили о том, как выбирать переменные, между которыми может быть зависимость, как ее считать и как проверять out-of-sample. Где-то посерединке будет алгоритм машинного обучения, который при адекватной постановке задачи и данных будет что-то прогнозировать. Бэктестинга в исследованиях нет!

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

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

Выводы

Я надеюсь, что теперь немного понятнее, почему машинное обучение «в лоб» в финансах не работает, но легче от этого точно не стало.

С другой стороны, вполне очевиден вектор исследований и улучшения компетенций.

Правильная «финансовая» постановка задачи:

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

Более глубокое понимание входных и выходных данных и выбор метрик:

  • Когда делаете изначальный exploratory data analysis, визуализируйте зависимости не на основе корреляций, а на основе более сложных метрик: корреляции не отображают ничего сложнее простых линейных взаимосвязей, которые в реальной жизни практически не встречаются.
  • Эта же идея важна и в других задачах, связанных с временными рядами: корреляция и эвклидовы метрики не оптимальны, попробуйте другие метрики, указанные в этой статье, или же специализированные, такие как dynamic time warping.

Детальный анализ обученных моделей:

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

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

  • Не делайте ошибки эконометрического моделирования: ваши модели должны прогнозировать будущее, а не объяснять прошлое. Объяснение ваших моделей оставьте feature importance и детальному анализу обученных моделей.
  • Правильная кросс-валидация: она должна учитывать IID-семплингвыборок и реалистичность постановки эксперимента (не предсказываем прошлое, и так далее). Обязательно попробуйте combinatorial cross-validation в других задачах, она дает более точную оценку точности сравнительно с K-Fold.
  • Бэктестинг вообще не входит в исследование. Если ваши модели не могут торговать в плюс — не экспериментируйте с бэктестингом, проверяйте все описанные выше шаги, которые касаются только машинного обучения.

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

Список литературы

Базовая литература:

Прикладная литература:

5 базових книжок про DevOps для початківців та досвідчених спеціалістів

$
0
0

Від редакції: у рубриці DOU Booksспеціалісти розповідають про 5 своїх улюблених книжок — ті, які змінюють світогляд та корисні читачам-колегам.

[Про автора: Володимир Щербінін — голова київського офісу компанії Tradecloud, яка займається розробкою supply chainплатформи. За понад 20 років кар’єри розвивався в різних напрямках: від портування GNU ПЗ на комерційні Unix-платформи й керування центром мережевих операцій до впровадження практик DevOps (з 2015 року) та SRE (з 2019 року)].

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

The Phoenix Project by Gene Kim, et al.

Російською — Джин Кин «„Феникс“. Роман о том, как DevOps меняет бизнес к лучшему»

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

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

The DevOps Handbook by Gene Kim, et al.

Російською — Джин Кин «Руководство по DevOps. Как добиться гибкости, надежности и безопасности мирового уровня в технологических компаниях»

Ця книжка — продовження The Phoenix Project, де ті самі автори розвивають тему, цього разу пояснюючи DevOps як три Шляхи (Ways): Потік (Flow), Зворотний зв’язок (Feedback), Безперервне навчання (Continuous Learning) та реалізацію їх на практиці. Розділ «Потік» (Flow) фокусується на Continuous Integration і Continuous Delivery (CI/CD). Далі йдуть, як на мене, найважливіші частини книжки. Розділ «Зворотний зв’язок» (Feedback) присвячено телеметрії, тестуванню й аналізу цих даних для покращення якості програмних продуктів і раннього виявлення помилок. Розділ «Безперервне навчання» (Continuous Learning) розповідає, як учитися на власних помилках та покращувати продукт, інструментарій і документацію.

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

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

Continuous Delivery by Jez Humble, David Farley

Російською — Джез Хамбл «Непрерывное развертывание ПО. Автоматизация процессов сборки, тестирования и внедрения новых версий программ»

З цієї книжки почалося моє занурення у світ CI/CD та, трошки пізніше, DevOps. Вона поділена на три частини: «Базові принципи» (Foundation) пояснюють усі передумови, потрібні для розуміння наступного розділу, — «Конвеєр розгортання» (Deployment pipeline), який пояснює базові концепти й реалізацію різних частин конвеєра (pipeline). Третій розділ «Екосистема розгортання» (Delivery Ecosystem) націлений на обговорення міжгалузевих практик і методів, що підтримують конвеєр розгортання. (Як на мене, «конвеєр розгортання» звучить досить дивно, але кращого перекладу «deployment pipeline» я, на жаль, не знаю).

Сама книжка випущена ще 2011 року, але вона витримала випробування часом, і більшість описаних там принципів актуальні й досі. Дуже рекомендую як базове джерело для ознайомлення з концептами Continuous Integration і Continuous Delivery (CI/CD).

Release It! by Michael T. Nygard

Російською — Майкл Нейгард «Release it! Проектирование и дизайн ПО для тех, кому не все равно»

Майкл — чудовий оратор (дуже раджу подивитися його виступи з конференцій на YouTube) з не менш чудовим почуттям гумору (іноді це майже вбивчий сарказм). Його книжка — це квінтесенція виступів, де з першого абзацу зрозуміло, про що вона. «Ви тяжко працювали останній рік над проєктом. Нарешті все вказує на те, що весь функціонал зроблено й навіть покрито тестами. Тепер можна зітхнути з полегшенням. Ви закінчили. Ви точно впевнені, що закінчили?»

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

Refactoring by Martin Fowler

Російською — «Рефакторинг. Улучшение существующего кода»

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

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

Повышение налогов vs здравый смысл, или По налогам бритвой Оккама

$
0
0
Дисклеймер. При написании статьи ни один чиновник не пострадал.
Все совпадения случайны, имена выдуманы.


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

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

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

Ниже представлен прогноз: что будет, если повысить налоги. Это предсказание, или моё субъективное мнение. Оно, конечно, может быть совсем по-другому, но, скорее всего, будет так.

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

...Мощно возрастаєт дєнь ото дня
процент жиров у маслі.
© митець


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

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

Почему денег больше не станет

Нельзя решением суда
заставить курицу нести яйца. ©


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

Что может государство

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


Давайте подумаем, что государство может сделать, чтобы повысить сборы:

  • Принять какой угодно закон.Сомневаетесь? Я нет! Исключить АйТи из перечня разрешенных видов деятельности для «упрощенки»? Запросто! Установить драконовские штрафы за неуплату налогов с доходов от занятия программированием? Без проблем, ведь установили же штрафы за работу без оформления! Даже уголовную статью «нарисуют».
  • Усложнить жизнь любой фирме и тем более гражданину.
  • Закрутить гайки. Запреты всего, что можно и чего нельзя, «маски-шоу» — на все это государство очень щедро.
  • Провести широкую рекламно-пропагандистскую кампанию: мол, как это здорово — платить налоги.

И... пожалуй, все.

Чего не может

Перекрыть все лазейки для неуплаты

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

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

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

Ну и, кроме того,факт выплаты «черной» зарплаты может быть железно доказан только для одного этого агента, другие скажут: «Ничего не знаем, получаем две минимальные зарплаты. С этого живём. Откуда деньги? Из тумбочки? Кто туда кладет? Жена! А она откуда берет? У меня! А я где беру? Да я же вам сказал: из тумбочки!» Так что компания нахально откажется выплачивать начисленные суммы штрафов и обратится в международный суд. И мне подсказывает интуиция, что международный суд будет рассматривать дело в соответствии с законом, а не с политической целесообразностью.

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

Нельзя нанять больше, чем десять человек? Условный «Люксофт» создает подставную фирму где-нибудь на Сейшелах, заключает с каждым программистом контракт от ее имени и таким же макаром платит. Сделать сейшельской фирме ничего нельзя, она законам Украины не подконтрольна. Запретить работать больше чем ХХ контракторам на одну контору? Вы что, издеваетесь?! Откуда предприниматель может знать, кто еще кроме него работает и в каком статусе? Я не буду приводить всех возможных проблем и вариантов решения, ясно одно: любые меры, кроме полного запрета АйТи приведут только к небольшим дополнительным расходам.

Закрутить гайки всем, кроме себя

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

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

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

Добиться добровольной уплаты

Выйдите на улицу и спросите: «Зачем власть поднимает налоги?» В девяти из десяти случаев ответ не понравится представителям государства. Более того, вам тут же приведут кучу примеров, где и как воруют, и даже кто конкретно.

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

Заставить стучать

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

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

Так что извините, у нас стукачей не любят.

Беспредельничать без ухудшения кармы

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

У Анатолия Каплана так вообще начатую бутылку ромаукрали со стола.

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

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

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

Удержать программистов в стране

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

Варить лягушку медленно

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

Так? Нет, не так! Проблема в том, что программисты прекрасно понимают: аппетит приходит во время еды. Если сейчас стерпеть небольшое повышение, через год налоги повысят еще, а потом еще — пока от доходов совсем ничего не останется. Все это понимают и вострят лыжи уже сейчас. И знаете, что самое плохое? Уезжают самые лучшие, востребованные на рынке труда западных стран. Если даже уедет 5 процентов всех программистов, для Украины это будет очень плохо. Представьте, с завода разом уволились все мастера и рабочие высоких разрядов. Не много, 5% от всего коллектива, но опытные. Завод сможет работать? Ответ: нет!

Почему едут

Украина — неудобная страна

Как же удержать программистов в стране? Поставим вопрос по-другому: из-за чего они едут?

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

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

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

Нет возможности для инвестиций.Куда-куда-куда!?! Не в накопительный же уровень пенсионной системы, в самом деле.

Государство как проблема

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

Коррупция. Тут даже комментировать не буду.

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

Почему остаются

Очень просто: соотношение доходов и затрат здесь очень приятное. Если приносишь денег домой больше, чем жители Европы или США, то на многое внимания не обращаешь. Теперь представим, что это изменилось. Домой вместо четырех-пяти тысяч программист принесет две-три, а это уже меньше европейских доходов. Цены? Но гайки закручивают не только программистам, так что цены неизбежно вырастут. А больше в этой стране для представителей среднего класса ничего интересного нет.

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

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

Таким образом, видно: программистов держат в стране только низкие налоги, если их ощутимо поднять, уедут все!

Куда можно уехать? Не будем описывать все страны с их налогами и инфраструктурой, остановимся на одной. Грузия! Вот цитата:

«В Грузии предприятия, занимающиеся информационными технологиями, могут получить статус „Лица виртуальной зоны“. Для этого следует обратиться к уполномоченному лицу. Статус присваивается в течение 10 рабочих дней, и еще через 2 рабочих дня формируется электронный сертификат, удостоверяющий право на льготы. В соответствии с Законом Грузии „Об информационных технологических зонах“ лица, зарегистрированные в виртуальных зонах, освобождаются от уплаты:

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

Имеющий глаза да увидит! В Грузии IT-компании не платят налогов. То есть, вырисовывается следующая схема. Приезжает программист, регистрируется как лицо виртуальной зоны, заключает контракт с зарубежным представительством IT-компании (с любым, хоть с «Люксофт» или ЕПАМ, благо с этим проблем нет) и работает точно так же, как из Украины. Эта же IT-компания может арендовать офис и посадить программистов вместе. С аренды будут честно уплачены все налоги (или не уплачены, это проблема арендодателя).

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

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

Что делать

Что можно действительно сделать для достижения амбициозных целей правительства по развитию АйТи? Привлечь программистов из других стран? Увы, нет! Ответьте мне на один вопрос: зачем люди с хорошим образованием и знанием английского вдруг поедут в Украину? Налоги повышают, и мы уже выяснили, что, кроме низких налогов, здесь для среднего класса ничего хорошего нет (зато есть война на востоке). Лучше ехать в США или Европу. Есть еще одна проблема — языковая. Английского языка не знают у нас почти нигде, даже в Киеве, не говоря уж о периферии. То есть продукты в супермаркете иностранец так просто не купит.

В странах Азии и Африки не знают украинского. В Украине не знают языков африканских стран и английского тоже не знают.

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

Образование? Важная, но не первостепенная проблема. Знаете почему? Учить стало некого! Абитуриенты массово едут в Польшу, Венгрию, Чехию и поступают там. По причинам, указанным выше.

Так что же делать? Явно не то, что планирует министерство!

  1. Признаться самим себе, что Украина — бедная страна, стремительно теряющая население, и рецепты, подходящие развитым странам, здесь не работают.
  2. Мораторий на изменение налогового законодательствана десять лет или больше! Работает — не трогай!
  3. Введение материальной ответственности за действия чиновников, повлекшие ущерб законному бизнесу.У нас ведь как: придут «маски-шоу», положат всех мордой в ковер, изымут оборудование, арестуют счета, и все — ждите суда через год. На него правоохранители традиционно не являются, или адвокат не просто разваливает дело, а аргументированно доказывает, что обвинителям надо бы начать изучение права с курса средней школы. После этого опростоволосившиеся стражи порядка, не понесшие никакой ответственности, вновь гордо планируют очередной набег на мирную IT-контору.
  4. По живому, ножом обрезать все препоны бизнесу в виде ненужных бумажек и разрешений.
  5. Чтобы сэкономить, нужно сокращать раздутый госаппарат. Всех этих тетиклав и иваниванычей — на рынок труда! Оставить одного вместо двадцати, дав ему пятикратную зарплату!

Выводы

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

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


Иллюстрации Романа Кривенко

Vert.x + Micronaut. Для чого нам Dependency Injection y світі мікросервісів?

$
0
0

За більш ніж 6 років у розробці довелося мати справу з різними проектами, а також з різними реалізаціями Dependency Injection (DI). Якщо в Grails/Spring DI це практично основа, то, наприклад, для Android-проекту його потрібно було додавати вручну (Dagger 2), так само як і для геймдев-проекту на Unity (Zenject). Інші програми, як-от pure Servlet-сервіс на Apache Olingo чи мікросервіси на Vert.x, узагалі не використовували DI. Власне, спроба додати DI до проекту на Vert.x підштовхнула до досліджень та експериментів, які було проаналізовано й задокументовано.

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

Для чого нам DI

У світі Spring DI доступний за замовчуванням. Тому для більшості Java-розробників дискусія про те, чи потрібен він узагалі, може виглядати трохи дивною. Це питання стає обґрунтованішим, коли йдеться про мікросервіси. Вони повинні бути якомога меншими й швидко запускатися, тому логічно мінімізувати набір додаткових бібліотек. Більше того, деякі фреймворки не змушують розробника використовувати якісь конкретні бібліотеки і дозволяють обрати те, що необхідно.

Хорошим прикладом є Vert.x — неймовірно швидкий і компактний non-blocking фреймворк, який розбито на компоненти подібно до Spring, але без DI в основі. Виглядає як хороший кандидат для високонавантажених мікросервісів!

Враховуючи все вищеописане, додати DI у проект на базі Vert.x тільки тому, що це виглядає правильним, — не дуже хороша ідея. Dependency Injection — це інструмент, а кожен інструмент слід використовувати для вирішення певних задач. Давайте з’ясуємо типові проблеми проектів без DI і визначимо, чи можна їх позбутися, використавши DI.

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

Переваги та недоліки DI

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

Плюси

  • Чистий код, який простіше читати / підтримувати / використовувати повторно.
  • Код легше тестувати.
  • Простіше змінювати реалізацію.
  • Дотримання принципів хорошого дизайну (SRP, Loose Coupling і Dependency Inversion).

Мінуси

  • Використання абстракцій може збільшити кількість класів.
  • Швидкодія під час старту програми може погіршитися.
  • DI може виявитися зайвим для невеликих проектів.
  • Код прив’язано до DI-фреймворку.

Демопроект

Цей Vert.x-проект зберігає користувачів у базі даних і повертає їх через HTTP. Перший планувальник періодично додає нового користувача в базу даних, а другий відправляє їм повідомлення.

Проект містить 3 вертікли (для тих, хто не знайомий із фреймворком, вертікл можна спрощено вважати модулем / стартовою точкою програми):

  1. HttpServerVerticle — слухає порт 8080 і повертає JSON з користувачами.
  2. CustomerProducerVerticle — додає нового користувача кожних 5 секунд.
  3. CustomerNotificationVerticle — відправляє повідомлення користувачам кожних 10 секунд.

CustomerServiceвідповідає за повернення/додавання користувачів і використовує CustomerRepository, який працює з базою даних.

Повний код проекту доступний тут: без DI, з DI.

Які проблеми може вирішити DI?

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

Деякі типові code smells, які часто можна зустріти на проекті без DI:

  • Зловживання синглтонами з глобальним станом.
  • Самостійне створення залежностей, які не є логічною частиною класу, що їх створює й використовує.
  • Потрібно багато рутинного коду, щоб передати «важкі» об’єкти під час створення залежностей; роздуті списки параметрів методів/конструкторів.
  • Використання синглтонів, які зберігають стан (наприклад, connection pool), різними вертіклами (стосується лише Vert.x).
  • Код важче тестувати й використовувати повторно.

Самостійне створення залежностей

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

public class CustomerProducerVerticle extends AbstractVerticle {
CustomerService customerService = new CustomerService();

З таким підходом тестування стає важчим: створити мок для приватних полів не просто.

public class CustomerService {
private CustomerRepository customerRepository = new CustomerRepository();

Приклад нижче показує, що CustomerNotifier використовує імплементацію EmailNotifier. Це означає, що ми не зможемо легко змінити реалізацію на SMSNotifier, якщо це буде потрібно.

public class CustomerNotificationVerticle extends AbstractVerticle {
private CustomerNotifier notifier = new EmailNotifier();

Отримання синглтон-залежностей зі статичного методу

Код, що використовує статичні методи, важко протестувати unit-тестами без PowerMock. А з Vert.x його важко тестувати навіть з PowerMock через деякі конфлікти анотацій Vert.x і Junit5.

MySQLPool pool = PoolManager.getPool();
vertx.setPeriodic(5000, id -> pool.getConnection(conn ->
addCustomer(conn.result())));

Більше того, вертікл повинен ізолювати свої стан і поведінку, щоб уникнути проблем з потоками. Правильний спосіб комунікації між вертіклами — Event Bus.

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

Отримання залежностей ззовні вимагає багато рутинного коду

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

Наприклад, Connection-об’єкт створюється в HttpServletVerticle і передається в сервіс:

pool.getConnection(res -> {
if (res.succeeded()) {
customerService.getCustomers(0, 0, res.result())

Потім сервіс передає його в репозиторій:

public class CustomerService {
public Future<List<Customer>> getCustomers(int offset, int limit, SqlConnection connection) {
return customerRepository.getCustomers(offset, limit, connection);}

І нарешті, репозиторій використовує його:

public class CustomerRepository {
public Future<List<Customer>> getCustomers(int offset, int limit,
SqlConnection connection) {

DI-фреймворки

  • Weld — орієнтований на програми Enterprise-рівня й надає багато можливостей, не потрібних мікросервісам.
  • Spring — використовує рефлексію та впливає на час/пам’ять під час запуску.
  • Google Guice — легкий DI-фреймворк.Використовує рефлексію та впливає на час/пам’ять під час запуску.
  • Dagger 2 — легкий (<100 kb), швидкий compile-time DI. Базується на JSR-330. Створений, в першу чергу, для Android, але підійде для будь-якого Java-проекту. Спочатку може здаватися складним.
  • Micronaut DI — швидкий compile-time DI, який створили під впливом Dagger колишні розробники зі Spring. Базується на JSR-330.

Micronaut

Перед тим як ми побачимо, чому Micronaut DI здається найкращим варіантом, ось короткий огляд самого фреймворку:

  • Створений розробниками Grails.
  • Базується на JVM — Java/Groovy/Kotlin.
  • Підтримує реактивні й non-blocking аплікації.
  • Швидкий час запуску й мінімальне споживання пам’яті.
  • Найменший HelloWorld JAR на Micronaut займає 12 MB (14 MB на Groovy).
  • Запускається на 10 MB max heap (20 MB для Groovy).
  • Час запуску: кілька сотень мілісекунд (20 мілісекундна GraalVM!).
  • Головна особливість — DI, AOP і генерація проксі відбуваються під час компіляції.

Micronaut DI

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

Підсумуємо переваги цього інструмента:

  • Дані, необхідні для Dependency Injection, генеруються під час компіляції. Це істотно зменшує час запуску й затрати пам’яті, а розмір коду практично не впливає на ці показники.
  • JSR-330.
  • Підтримка Java/Groovy/Kotlin.
  • Легкий для старту.

Інтеграція з Micronaut DI

Отже, у нас є простий Vert.x-проект. Час додати до нього Micronaut! Для цього потрібно підключити додаткову залежність і плагін для обробки анотацій:

<dependency>
 <groupId>io.micronaut</groupId>
 <artifactId>micronaut-inject</artifactId>
 <version>${micronaut.version}</version>
</dependency>
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.8.0</version>
 <configuration>
   <source>11</source>
   <target>11</target>
   <annotationProcessorPaths>
     <path>
       <groupId>io.micronaut</groupId>
       <artifactId>micronaut-inject-java</artifactId>
       <version>${micronaut.version}</version>
     </path>
   </annotationProcessorPaths>
 </configuration>
</plugin>

Відрефакторений код

Micronaut підтримує JSR-300, тому можна легко перетворити залежності на біни, використовуючи анотації @Singletonабо @Named.

@Singleton
public class CustomerRepository {

Переважно існує один Composition Root, де збираються всі залежності. Але в проекті з Vert.x може бути корисно мати окремий контекст для кожного вертікла. Це зробить вертікли повністю ізольованими, і тоді не треба перейматися, що різні вертікли використають не thread-safe синглтони.

public CustomerNotificationVerticle() {
BeanContext beanContext = BeanContext.run();
this.customerService = beanContext.getBean(CustomerService.class);
this.notifier = beanContext.getBean(CustomerNotifier.class);
}

Інші вертікли слід створити так само.

Залишилося тільки написати фабрику, що створить реалізацію інтерфейсу CustomerNotifier,і фабрику для створення Connection Pool.

@Factory
public class NotifierFactory {
@Singleton
CustomerNotifier notifier() {return new EmailNotifier();}
}
@Factory
public class PoolFactory {
private static MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(InMemoryDBHandler.PORT)
.setHost("localhost")
.setDatabase(InMemoryDBHandler.DB)
.setUser(InMemoryDBHandler.USER)
.setPassword(InMemoryDBHandler.PASSWORD);
private static PoolOptions poolOptions = new PoolOptions()
.setMaxSize(5);
@Singleton
MySQLPool createPool() {
return MySQLPool.pool(VertxSingletonHolder.vertx(), connectOptions,
poolOptions);}

Тепер Connection Pool можна легко отримати там, де він потрібний:

@Singleton
public class CustomerRepository {
   private MySQLPool pool;
public CustomerRepository(MySQLPool pool) {
       this.pool = pool;
   }

Не потрібно передавати pool/connection у методи: список параметрів став меншим і читабельнішим.

@Singleton
public class CustomerService {
   private CustomerRepository customerRepository;
...
   public Future<List<Customer>> getCustomers(int offset, int limit){
       return customerRepository.getCustomers(offset, limit);
   }

Вплив на запуск програми

Середній час запуску без DI становив 500 мс. Після додавання Micronaut DI час збільшився до ~700 мс.

Вплив на запуск програми з ростом залежностей

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

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

Що з недоліками?

  • «Використання абстракцій може збільшити кількість класів». Вирішення цієї проблеми залежить від програміста, і необов’язково вносити додаткову абстракцію без необхідності.
  • «Швидкодія під час старту програми може погіршитися». Завдяки генеруванню необхідних класів під час компіляції вплив на запуск програми є незначним і він практично не збільшуватиметься з розміром коду.
  • «DI може виявитися зайвим для невеликих проектів». Як було з’ясовано, DI дуже корисний навіть для мікросервісів, тому його використання цілком виправдано.
  • «Код прив’язано до DI-фреймворку».Оскільки Micronaut підтримує JSR-330, у майбутньому його можна замінити будь-яким іншим JSR-330-фреймворком. Єдиною прив’язкою до фреймворку є логіка створення бінів (@Factory).

Які переваги?

Чистий код

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

«За якихось рік-два команди, що дуже швидко рухалися вперед на самому початку проекту, починають повзти зі швидкістю равлика. Кожна зміна, яку вносять у код, порушує його роботу у двох-трьох місцях. Жодна зміна не проходить тривіально. Для кожного доповнення чи модифікації системи потрібно „розуміти“ всі хитросплетіння коду, щоб у програмі їх ще побільшало». Роберт Мартін «Чистий код»

Image Source

Maintenance

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

Створюючи код, який легко підтримувати, можна оптимізувати до 70% часу й коштів, потрібних на maintenance, на відміну від 30% часу та коштів для написання коду.

Продуктивність

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

Тестування

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

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

Ізоляція вертіклів

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

Висновки

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

Інвестування часу в написання хорошого коду насправді зменшує вартість розробки програмного забезпечення.

Ви підприємець чи науковець? Як продакт-менеджеру обирати компанію відповідно до схильностей

$
0
0
Поганий продакт-менеджер — хороший татопідприємець.
Народна мудрість


Привіт, мене звати Вова, і я — продакт-менеджер, автор подкасту «Клуб анонімних продакт-менеджерів» й організатор мітапів КАМП:talks. Попрацювавши Head of Product у Wix, устиг проспівбесідувати більше сотні продакт-менеджерів, а віднедавна консультую компанії з наймання продактів. Цим дописом я хочу допомогти шукачам продакт-менеджерів визначити свого ідеального кандидата, а продакт-менеджерам розпізнати компанію, в якій буде можливість розкрити свій потенціал.

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

Ілюстрація Уляни Патоки

Підприємець

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

Наприклад, уявний продакт-менеджер Давид 10 років працював у рекрутингу. Почав як найманий працівник, але швидко збагнув, що може непогано заробляти, працюючи на себе. Згодом його самозайнятість перетворилась на невелику рекрутингову агенцію. За час роботи Давид перепробував велику кількість CRM-систем, поштових сервісів, браузерних плагінів і став експертом у цьому. Щоправда, за 10 років рекрутинг йому трохи набрид, тож коли колишні клієнти запропонували йому приєднатися до них як ПМ у новому продукті для рекрутингового ринку, він швидко погодився. І це був marriage made in heaven, оскільки він швидко міг і розставити пріоритети, і намалювати простий та зрозумілий UX. Попри те, що інколи бути користувачем свого продукту може стати на заваді об’єктивній оцінці, у випадку з Давидом зірки зійшлися, і продукт став швидко набирати популярність.

Науковець

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

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

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

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

Кого наймати компаніям

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

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

Важливе питання: чому фаундери переважно не готові наймати продактів з підприємницькими схильностями? Страх? Невпевненість? Роздуте его?

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

Друга причина — це те, що компаніям на певному етапі розвитку потрібен саме науковець, а не підприємець. Цей етап настає тоді, коли інсайтів засновника вже не вистачає, щоб рухати продукт уперед. Або коли головні гіпотези перевірено, бізнес-модель визначено й продукт потребує розвитку та масштабування. Це дорослішання компанії і перехід від founder-driven до product-driven розробки відбувається інколи болісно для засновника, але без цього вкрай важко буде зробити стрибок від $1 млн до $10 млн ARR, наприклад.

Як продактам обрати компанію

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

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

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

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

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

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

Зарплаты выше, но не у всех. Анализ данных об удаленной работе украинских ИТ-специалистов

$
0
0

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

В последнем зарплатном опросе (декабрь 2019) выросла доля людей, работающих удаленно. До этого она была стабильно в рамках 2-3%,а теперь увеличилась до 4,2%.

Доля ИТ-специалистов, работающих удаленно

Источник: зарплатный опрос DOU
Цветом отмечены статистически значимые различия по сравнению с предыдущей волной опроса (уровень значимости 95%)


4,2% — это с одной стороны немного, но с другой стороны, это немногим меньше, чем количество ИТ-шников в Одессе.

Доля ИТ-специалистов по городам

Источник: зарплатный опрос DOU за декабрь 2019


В то же время, по данным Портрета ИТ-специалиста, доля работающих вне офиса значительно выше (15-16%)и не меняется со временем.

Доля ИТ-специалистов, работающих вне офиса (дома, в коворкинге или «где придется»)

Источник: Портрет ИТ-специалиста, DOU
Не обнаружено статистически значимых различий по сравнению с предыдущими волнами опроса (уровень значимости 95%)


Такие различия могут быть вызваны разными формулировками вопросов. В зарплатном опросе нужно выбрать «Город». Те, кто живут, например, в Киеве, но работают из дома, могут выбрать как «Киев», так и «удаленно». В Портрете же вопрос более прямой: «Где вы работаете?» (В офисе / Дома / Где придется / В коворкинге).

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

Но вот что мы знаем наверняка: растет количество вакансий с возможностью ремоута.

Вакансии: рост ремоута за счет разработчиков

Количество ремоут вакансий растет, причем за счет девелоперов. Во втором полугодии 2019 года 11% вакансий для девелоперов позволяли удаленную работу, 5% были чисто удаленными. Для не девелоперов таких вакансий было 7% и 3% соответственно.

Доля вакансий с возможностью ремоута / только ремоут

Источник: jobs.dou.ua
Цветом отмечены статистически значимые различия по сравнению с предыдущим полугодием (уровень значимости 95%)

Удаленная работа — глобальный тренд

По данным US Census Bureau, доля людей, работающих на дому, хотя и относительно невелика, но стабильно растет. За период с 2000 по 2017 она выросла с 3,3% до 5,2%.

Опрос нанимающих менеджеров, проведенный по заказу Upwork, показывает: 55% нанимателей считают, что удаленная работа стала более популярной по сравнению с ситуацией трехлетней давности.

По результатам опроса Work.ua, 75% украинцев хотят работать удаленно. Опрос был проведен в 2015 году, и 9% заявили, что не хотят работать удаленно — в 2013 году таких было 23%.

Согласно отчету Emerging Jobs Report 2020 от Linkedinв США удаленная работа раньше воспринималась как дополнительный бонус, но теперь набирает приоритет у кандидатов. Особенно это касается «миллениалов», составляющих сейчас большую часть рабочей силы.

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

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

Мы опросили 10+ компаний, разместивших на DOU вакансии с возможностью удаленной работы. Практически все ответили, что сотрудники свободны в выборе места работы: могут ходить в офис, а могут 100% работать из дома. Это позволяет нанимать людей, живущих в разных городах, а не только там где есть офис компании.

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

Девелоперы, особенно опытные

Больше всего удаленщиков среди копирайтеров, DBA, Scrum-мастеров и системных архитекторов.

ТОП-5 должностей по доле удаленных сотрудников

Источник: зарплатный опрос DOU за декабрь 2019


Тем не менее, и среди удаленщиков, и среди офисных работников больше всего девелоперов. Среди офисных сотрудников девелоперов 44%, а среди удаленщиков 63%, причем эта разница возникает за счет миддлов (22% vs 28%) и особенно сениоров (12% vs 26%).

Должности удаленных и офисных сотрудников

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)


На удаленку чаще уходят более опытные сотрудники: 40% удаленщиков — это специалисты с опытом более 5 лет, тогда как среди офисных сотрудников таких 26%.

Опыт работы удаленных и офисных сотрудников

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)


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

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

Доля вакансий с возможностью ремоута в зависимости от требуемого опыта работы

Источник: jobs.dou.ua
Цветом отмечены статистически значимые различия по сравнению с предыдущим полугодием (уровень значимости 95%)

Небольшие компании — стартапы и продукт

Удаленные сотрудники ожидаемо чаще работают в небольших компаниях: 42% — в компаниях до 10 человек (vs 11% офисных сотрудников). Соответственно, не удивляет, что удаленные сотрудники чаще работают в стартапах — 15% vs 3% офисных сотрудников. Но все же чаще всего удаленщики работают в продуктовых компаниях (42%), тогда как среди офисных работников больше всего работают в аутсорсе (47%).

Размер компании-работодателя: удаленные и офисные сотрудники

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)

Тип компании-работодателя: удаленные и офисные сотрудники

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)

Уровень образования такой же, а английского чуть выше

Среди удаленщиков немного больше людей с образованием уровня школы / техникума / колледжа, но в абсолютном выражении таких около 5%. Абсолютное же большинство как офисных (73%), так и удаленных (72%) сотрудников имеют одно высшее образование.

Уровень образования: удаленные и офисные сотрудники

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)


Среди удаленных сотрудников несколько больше людей с продвинутым уровнем английского: 18% vs 11% офисных сотрудников.

Уровень английского: удаленные и офисные сотрудники

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)

Зарплата удаленщиков выше, чем в офисе, но только у опытных специалистов

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

Процентили зарплаты офисных и удаленных сотрудников

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)


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

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

Источник: зарплатный опрос DOU за декабрь 2019
Жирным выделены статистически значимые различия по сравнению с офисными сотрудниками (уровень значимости 95%)

Итоги статьи и интересные ссылки по теме

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

Напоследок делимся некоторыми интересными материалами об удаленной работе.

Исследование Google о работе распределенных команд. Оно про совместную работу людей из разных офисов компании, но многое будет релевантно и для «строго удаленной» работы:

Joel Spolsky дает советы по организации работы команд удаленных сотрудников:

Еще две статьи от создателей StackOverflow. В первой сооснователь и первый разработчик платформы Jeff Atwood рассказывает о своем опыте удаленной работы в StackOverflow. Кстати, один из его советов — брать на удаленку только опытных разработчиков. Во второй статье CTO David Fullerton рассказывает, почему они работают удаленно, как организовывают работу, какие есть подводные камни:

Опыт SkyEng в организации работы распределенной команды:

TED Talk: экономист из Стенфорда провел эксперимент с шанхайской компанией: часть сотрудников работали из дома, а часть в офисе. Результат — рост продуктивности и снижение текучки кадров среди тех, кто работал из дома:

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

Многие исследования опубликованы на малоизвестных сайтах и имеют не очень внятную методологию, но есть, к примеру, и мета-анализ с PubMed. Он показывает позитивное влияние удаленной работы на удовлетворенность работой и производительность, уменьшает текучку и work-family conflict. Ущерб для отношений с коллегами был замечен только в случае удаленной работы более 2,5 дней в неделю, хотя в целом удаленная работа не имеет негативного эффекта на рабочие отношения.


Если вам попадались интересные материалы об удаленной работе (книги, статьи, видео), делитесь ссылками в комментариях :)


Текст и аналитика: Ольга Макарова
Визуализация данных: Игорь Яновский


Когда стоит переписывать код проекта и как это донести до заказчика

$
0
0

Всем привет! Меня зовут Елена Шаровар, я Lead Node.js developer в Waverley Software. В этой статье мы рассмотрим ситуацию, когда программисты говорят: «Нужно все переписать», но это тяжело донести до заказчика.

Разберемся, что с этим делать и как помирить программистов и бизнес, если вы — Lead проекта, Project Manager или тот самый программист, который хочет улучшений, а вас как будто не слышат. Скорее всего, об этой проблеме вы знаете не понаслышке: такое случается то с вами, то с вашими друзьями или коллегами, и в очередной раз начинается обсуждение: а что же делать?

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

Стейкхолдеры проекта

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

  1. Инвесторы — потому что они вкладывают свои финансовые средства в этот проект и ожидают хороший Return on Investment (ROI).
  2. Product Owner — человек, который занимается управлением этого проекта и приоритизирует функционал, который вы разрабатываете. Он общается с программистами и инвесторами.
  3. Пользователи — те, кто использует ваш продукт и, скорее всего, платит за него.
  4. Программисты — да-да, они также являются стейкхолдерами, проект должен их устраивать, иначе у вас не будет программистов.

Как проект выглядит для всех, кроме программистов

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

Почему программисты хотят переписать код проекта

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

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

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

Где интересы программистов и других стейкхолдеров пересекаются

Кроме функциональных характеристик, у программ есть нефункциональные характеристики. К ним относятся:

  • скорость ответа (response time, performance);
  • отсутствие багов (reliability, usability);
  • доступность (availability);
  • устойчивость к отказам (resilience);
  • расширяемость (extendability);
  • поддерживаемость (maintainability);
  • среднее время починки (mean time to repair);
  • стоимость разработки и поддержки (cost);
  • тестируемость (testability);
  • возможность аудита и отладки (auditability).

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

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

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

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

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

Почему стороны не могут договориться

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

СтороныЖеланияОпасения
ИнвесторыПолучить хороший IRR и много платящих пользователейВпустую слить бюджет
ПользователиИметь надежный продукт, решающий их бизнес-задачи.Нестабильная работа продукта в тот самый момент, когда он очень нужен.
Product OwnerИдти в соответствии с разработанным roadmap, превосходить конкурентов, выпускать те фичи, которые имеют наибольшую конечную ценность.Думает об Opportunity Cost — убытках, которые понесет компания, если будет делать переписывание вместо новых фич
ПрограммистыПолучать удовольствие от работы на проекте, понимать систему, программировать, работать с новыми технологиямиНестабильная программа, в которой приходится чинить баги по ночам или выходным

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

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

Что по поводу переписывания говорят эксперты

Joel Spolsky написал 20 лет назад:

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

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

«Никто не хочет делать те части работы, которые не веселые. Чинить баги — это не весело. А писать с нуля — весело», — пишет Jamie Zawinski.

Так что же, совсем не переписывать?

Неверный вывод. Принцип «работает — не трожь» также не подходит. В книге «Object-Oriented Reengineering Patterns»упоминается, что если система функционирует, но вы не можете ее ни поддерживать ни расширять, она сломана.

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

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

Microsoft переписала Visual Studio и выпустила VSCode, которым многие, я думаю, пользуются. Google переписала свой Inbox, однако оставила работать обе версии — старую Inbox и новую GMail.

Достойные причины переписать проект

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

Недостойные причины переписать проект

  • Здесь написано на промисах, а я хочу async/await.
  • Здесь фреймворк N, а мои друзья говорят, сейчас модный Y.
  • Я хочу добавить парочку технологий себе в резюме.
  • Я не люблю код, который писал не я.
  • Код работает, но я не понимаю как.

Подводные камни

  • Переписывание всегда занимает больше времени, чем ожидается (по мировой статистике, упоминаемой в книге МакКоннелла «Сколько стоит программный продукт», программные проекты обычно недооцениваются на 30% и больше).
  • Простое переписывание дает мало ценности для конечного пользователя.
  • Вы «забудете» или «потеряете» часть функционала, если нет полной документации по старой системе.
  • Вы сделаете те же баги, которые уже делали и чинили до вас предыдущие программисты.
  • При переписывании с нуля вам придется какое-то время поддерживать обе версии — и старую, и новую.

Переписать или отрефакторить?

Переписывание (rewrite from scratch) — это когда вы заново, с нуля, пишете код, используя старый только для чтения. Рефакторинг — это когда путем последовательных преобразований старого кода вы приходите к новому его виду.

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

Но рефакторинг считается более безопасным по таким причинам:

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

А где ваш план!

Вы делали ремонт? Помните, что вас интересовало? Цена, качество и сроки, верно? Здесь то же самое. Чтобы заказчик сказал вам «да» — предоставьте ему информацию о цене, качестве и сроках.

Цена и сроки

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

  • Сделайте схемы и диаграммы того, что вы хотите получить в итоге.
  • Объясните в комментариях или в design document, чем новая структура лучше старой.
  • Разбейте работу на этапы и составьте эстимейт (оптимистичный, пессимистичный, реалистичный).
  • Продумайте риски (например, уход ключевого разработчика).
  • Кто и как будет тестировать результат, есть ли у вас чек-лист для полного тестирования?
  • Не забудьте включить в эстимейты работу по настройке деплоймента, переносу данных и миграции пользователей.

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

Качество

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

Пару слов об инженерной этике

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

При вступлении в профессию программиста мы не даем [еще пока] никаких клятв, но кодекс этики программиста существует здесьи здесь, и похожий пункт там тоже есть: «Principle 2: Software engineers shall act in a manner that is in the best interests of their client and employer consistent with the public interest»

Преследовать свои личные цели, а не цели бизнеса — неэтично.

Дайте цифры

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

Стоимость переписывания посчитать проще всего, она прямо пропорциональна времени на переписывание и выкатывание новой версии.

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

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

Выберите подходящее время

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

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

Mожно обсудить с Product Owner, когда, по его мнению, все это можно будет реализовать, и запастись терпением. Подумайте: можно ли переписать не все, а часть? Определите самые проблемные части проекта, просмотрев историю баг-репортов или жалоб пользователей.

Спросим коллег

Oleksandr Brychuk, Head of IT Department at UniSender

На початку роботи в UniSender ми стикнулися з тим, що продукт за своєю природою був страшним легасі з практик початку 2000-х.Час на адаптацію нової людини в проєкті був немалим, деякі частини проєкту взагалі було важко підтримувати, один баг нам обійшовся в кругленьку суму. Їх було багато, і зменшити кількість нам не вдавалося.Я і колеги взяли ініціативу в свої руки. Зробили документ, в якому описали бачення того, куди потрібно рухатися з технічної точки зору. Приблизно оцінили терміни. Варіантів було два: переписувати все з нуля або рефакторити. Запрошували зовнішніх експертів для аудиту і перевірки власних гіпотез. І презентували це власникам. У кінці-кінців вирішили рефакторити, і почали з найбільш важливого для нашого бізнесу.

Ми рефакторили, а не переписувати з нуля, тому що часто зупинялися в процесі і робили те, що було потрібно на ту мить, а не в перспективі — це додало гнучкості. Перші півроку нічого не робили, крім рефакторингу, потім займалися ним по-різному: від 30-40%до 60-70%часу. Все залежало від цілей на той момент.

Eugene Naumenko, Founder at Adferret.tech

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

Eugene Bogatyriov, VP of Engineering, Waverley Software

Расчеты — это ключевой момент: нужно предоставить расчеты ROI проекта по переписыванию/рефакторингу. ROI — время, за которое окупится инвестиция в переписывание. Если переписывание окупается за год-полтора — эту идею примут и «спасибо» скажут. Расчеты желательно презентовать стейкхолдерам по одному, индивидуально, начиная снизу по иерархии. Есть неписаное правило о том, что продукт надо переписывать с нуля минимум каждые 10 лет в связи с устареванием технологий. У меня был пример как раз такого типа, где десктопный продукт переписывали с нуля под веб. Команда 80 человек, три года.

Summary

Итого, если вам кажется, что ваш проект нужно переписать:

  • Убедитесь, что причины весомые, а не просто «мне не нравится этот код».
  • Найдите точку пересечения ваших интересов и интересов других стейкхолдеров.
  • Определите опасения стейкхолдеров и способы снижения их опасений.
  • Составьте детальное описание того, что хотите получить в результате: схемы, диаграммы, design document.
  • Подумайте, почему нельзя прийти к тому же результату путем рефакторинга.
  • Сделайте оптимистичный, реалистичный и пессимистичный эстимейт.
  • Сравните затраты и выгоды, получаемые в результате.
  • Выберите подходящее время.
  • Заручитесь доверием со стороны ЛПР (лиц, принимающих решения).
  • Попробуйте менять поэтапно и начать с самых критичных частей.

Полезные ссылки

Чому команди прохлопують свої естимейти

$
0
0

Я Оля Чмир, уже другий рік одна з проджект-менеджерів у компанії SPD-Ukraine на проекті PitchBook. У проекті тепер залучено 200 спеціалістів. На постійній основі я працюю з трьома різними командами, але, залежно від релізу, також маю можливість співпрацювати з іншими командами.

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

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

Що ж, пригадаймо той момент, коли проджект-менеджер приходить до команди й починає просити оцінити час, потрібний на виконання завдання чи навіть цілого проекту. І перше, що бачить в очах розробника, — сум та пригнічення. І не дарма. Протягом багатьох десятиліть чимало команд, які не могли об’єктивно оцінити потрібний їм час, і менеджери, які потім притягали команду до відповідальності за їхніми оцінками, неправильно використовували оцінки. Ще більше розчарування виникає, коли менеджери зважають лише на найнижчу кількість потрібних годин, почуту від розробників! Але погодьтеся: розробка не магія! І не дивно, що хештег #NoEstimates так прославився.

Давати точні оцінки складно, потрапити в них ще складніше.

Оцінки ніколи не досконалі. Але мета кожної спроби оцінювання — забезпечити надійний внесок у «досить хороший» план.

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

Процес оцінки

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

Визначення результату виконання завдання

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

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

Декомпозиція та деталізація

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

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

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

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

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

Визначення ризикових підзавдань

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

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

Як це працює в нас:по-перше, ми використовуємо систему падінгів. Кожне завдання в WBD має свій рахунок — від 0 до 3. Розробник, що створює декомпозицію, оцінює ризиковість завдання за встановленою шкалою. Відповідно до рахунку фінальна оцінка кожного окремого завдання зростає на 0–30%максимально оціненого часу.

По-друге, якщо рахунок становить >3, то ми проводимо Investigation щодо окремо взятих завдань.

Оцінка часу деталізованого завдання, або Коли в гру вступає менеджер

По-перше, оцінюючи завдання, пам’ятайте: розробник ніколи не витрачає всі 8 годин робочого дня безпосередньо на роботу над завданням. Завжди будуть витрати часу на заварити/попити кави-чаю, послухати свіжий анекдот тощо. Потім розробник сідає за комп’ютер і намагається якийсь час згадати, що ж він робив. Його увагу відвертають колеги запитаннями щодо роботи й таке інше... А скільки часу витрачають розробники на мітингах?

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

Як це працює в нас:з моїми командами ми маємо домовленість, що вони оцінюють завдання в девгодинах (тільки під час формування роадмапи, коли все, що ми знаємо про нову функціональність, — кілька речень опису і, ймовірно, проблема, яку хочемо розв’язати, — ми можемо оцінювати в тижнях або навіть місяцях). Кількість ефективних годин для середньостатистичного розробника — 5,5 години на день, для тім/технічного ліда — 2–4години на день.

Час на код-рев’ю, виявилося, оцінити навіть важче, ніж час на реалізацію завдання. Були ситуації, коли час рев’ю інколи перевищував навіть час реалізації. Проте дослідним способом ми визначили, що на рев’ю витрачається близько 30% часу.

Окрім того, проекти, над якими працюють мої команди, дуже динамічні, і нам не властиві довгострокові проекти (зазвичай тривалість реалізації нового функціоналу —1,5–2 місяці).Тому на інтеграцію додаємо ще 1 тиждень.

Цифри та невідомі

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

Невизначеність оцінок пов’язана з невідомими. Що більше невідомих, то менше впевнені ми повинні бути в оцінках. І навпаки, що менше невідомих, то більше впевненими ми повинні почуватися щодо оцінок.

Що це означає? Кожен проект має певний рівень невідомих. Коли розробники дають приблизну оцінку, — скажімо, 4–8 днів, —вони дають дві цінні інформації: кількість днів і впевненість у цьому. Якщо непевність велика, це означає, що є потенційно багато невідомих, які вплинуть на ймовірну поставку. Такий вплив може бути великий або взагалі бути відсутнім.

По-перше, звертаючись до невідомих, ми підвищуємо впевненість в оцінках.

Є 2 типи невідомих: невідомі невідомі й відомі невідомі. Не так уже й багато можна зробити для невідомих невідомих. За умовчанням, розробники не можуть врахувати їх у своїх оцінках; але вони могли б дати собі ще кілька днів «про всяк випадок», і ці дні зазвичай витрачаються на налагодження та інтеграцію. Щодо відомих невідомих, то, витрачаючи перші години або дні вашого проекту на їх вирішення, можна значно полегшити роботу, зменшивши цю невизначеність. Наприклад, 6 днів +/— 2 дні може стати, наприклад, 6 днів +/— 1 день.

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

До речі, можна зрозуміти, що технічні завдання — частина можливих відомих невідомих. Що точніші технічні завдання, то менше невизначеності буде. Ставте собі кілька запитань:

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

Параліч перед оцінкою також легко побороти.

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

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

Я:Тобі вистачить 3 місяці?
Розробник:Та ні, це занадто!
Я:Як щодо місяця?
Розробник:Хм... Можливо.
Я:А за тиждень?
Розробник:Точно не встигну! Там стільки роботи...
Я: 3 тижні буде досить? Чи 2?
Розробник:За 2 спробую закінчити. Проте 3 тижні має вистачити.

І ось ми вже на початку третього тижня й підходимо до закінчення розробки та підготовки завдання до код-рев’ю ;-)

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

(To) : K = Tр / Tо

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

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

  1. Попередня оцінка на основі короткого опису та проблем (зазвичай надається в тижнях або місяцях).
  2. Декомпозиція та її оцінка на основі специфікації (зазвичай створюється тім/технічним лідом релізу).
  3. Оцінка завдання розробником, який безпосередньо працюватиме над завданням.

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

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

Що робити, якщо команда давно знає і використовує ці правила, а оцінки все одно «вилітають»

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

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

Що стосується когнітивного викривлення під час планування, то ми занадто оптимістичні в нашому плануванні. Роджер Бюхлер опитував групи студентів. Він запитував, у минулому, коли вони виконували певне завдання, яка була ймовірність того, що вони виконали його справді в ті строки, у які хотіли, і дістав результат, що в 70% випадків ніхто в зазначений термін не вкладався. Наступним запитанням було таке: «Як думаєте, чи можливо виконати наступне завдання в термін, який ви собі встановлюєте?», і 80% опитаних були впевнені, що вони вкладуться в нього.

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

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

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

Прокинутись і встати о 7-йранку. 1,5 години на ранкові процедури та збори. О 9-йприїхати в офіс. 30 хвилин на зробити каву, перевірити пошту, навіть спитати про вихідні в колег. О 9:30 я, мотивована та натхненна, починаю готувати план нового проекту. Чи піде все за цим планом? Чи зможу я його зреалізувати? Ні... Знаєте, де зламається мій ідеальний план? Я нізащо не встану о 7-йранку!..

Чому так відбувається

Коли ми щось продумали для себе, то нам здається, що так станеться з високою імовірністю

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

Концепт hot-cold empathy gap

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

«Фокалізм»

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

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

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

То в чому ж рація, якщо все одно нічого не працює...

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

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

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

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

Перше запитання: «Якщо все буде, як завжди, скільки часу потрібно на виконання цього завдання?»

Друге запитання: «Як розвивалися події і які події зазвичай призводять до того, що строки так зміщуються?». І дослідники стверджують, що всі, хто ставив ці запитання, надавали більш реалістичні строки виконання своїх завдань. І ці підходи варті того, щоб їх пробувати, адже вони розвивають не скіл оцінки завдань як такий, вони розвивають цілий менталітет. Тобто ми відходимо від детального планування, охолоджуємо себе від гарячого стану й дивимося на речі реально, адже тепер знаємо, що це не працює, що завтра / через тиждень може трапитися що завгодно, ми можемо бути в зовсім іншому стані чи настрої. Замість цього ми встановлюємо собі нехай більші, але реалістичні строки.

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

Перші кроки в NLP: розглядаємо Python-бібліотеку NLTK в реальному завданні

$
0
0

Усім привіт! Звати мене Андрій, і я 8 років працюю в оцінці майна, в жодній ІТ-компанії не працював, але люблю програмувати. Як хобі я почав готувати власний проєкт — систему для зручного й ефективного відображення оголошень з продажу нерухомості в Україні з різноманітних загальнодоступних джерел. У результаті проєкт «виріс» до доволі великих розмірів і включає систему збору й попередньої обробки оголошень, систему знаходження їхніх геокоординат, систему класифікації оголошень за певними типами й невеликий користувацький інтерфейс, написаний на Django. А в цій статті я спробую детально розповісти про реалізацію однієї з його частин, а саме класифікацію оголошень з продажу земельних ділянок в Україні за допомогою методів NLP.

Спочатку під час роботи над проєктом я поставив перед собою ціль ознайомитися з різноманітними бібліотеками Python на реальному завданні. Мета написання статті — поділитися набутим досвідом, враховуючи, що в українськомовному сегменті мережі таких статей, на мій погляд, недостатньо. У результаті вийшов огляд можливостей кількох бібліотек Python для машинного навчання, а саму статтю довелося розділити на три частини. Я наведу приклади реалізації класифікаторів, написаних за допомогою бібліотек NLTK, scikit-learn і TensorFlow.

Перша частина статті включає перше знайомство з даними й приклад побудови класифікаторів на основі бібліотеки NLTK.

Друга частина міститиме приклад побудови класифікаторів на основі бібліотеки scikit-learn.

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

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

Отже, починаймо.

Постановка проблеми й знайомство з даними

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

В Україні земельні ділянки поділяютьза цільовим призначенням на 119 видів. Мені для роботи така детальна класифікація не потрібна, тому я виділив 7 типів (класів) земельних ділянок. Ось вони:

Таблиця 1. Типи земельних ділянок

IDТип ділянкиКоротка назва
1Для будівництва й обслуговування житлового будинку, господарських будівель і споруд (присадибна ділянка)ОЖБ
2Для ведення особистого селянського господарства й подібніОСГ
3Для індивідуального й колективного садівництва та дачного будівництваCадова
4Під комерційну діяльність та інші, що не ввійшли до решти групКомерційна
5Під багатоквартирний будинокБагатоповерхова
6Для ведення товарного сільського господарства й подібніТоварна
7Одна з ділянок під ОЖБ, а одна під ОСГОЖБ й ОСГ

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

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

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

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

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

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

Погляньмо на перші десять оголошень, що я підібрав (весь код тут):

Таблиця 2. Перші оголошення з набору

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

Детальніше розглянемо кожну колонку.

«land_types_source» — тип ділянки визначено або невизначено в джерелі інформації.

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

«description» — поле з описом оголошення. З цього поля видалено всі цифри, номери, розділові знаки тощо. Залишено лише слова (букви), розділені пробілом. Інформація з поля «description» — лише результат роботи програми, що я розробив (зразок наведу нижче).

«built_up» — поле, що показує: ділянку забудовано (цифра «1») чи незабудовано (цифра «0»).

«land_types» — поле, що показує тип (клас) земельних ділянок в оголошенні (id типів наведено в таблиці 1).

«land_squer» — показує площу ділянок в оголошенні.

З даними ми ознайомилися. Погляньмо на розподіл оголошень за класами:

Рис. 1. Розподіл оголошень за класами

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

Тут потрібно звернути увагу на кілька особливостей набору даних, що я підготував. Передусім оголошення з продажу земельних ділянок для ведення товарного сільського господарства є викидами. В Україні станом на дату підготовки статті діє мораторій на продаж земельних ділянок для ведення товарного сільського господарства (до речі, на відміну від земельних ділянок, наданих для ведення особистого селянського господарства). Однак є велика ймовірність, що мораторій знімуть, тому я вирішив залишити ці оголошення у вибірці. По-друге, у вибірці є лише один комбінований тип земельних ділянок: під ОЖБ й ОСГ, інші комбінації відкинуто як викиди, оскільки трапляються дуже й дуже рідко. І останнє — кожний запис у вибірці унікальний за комбінацією стовпців «land_types_source», «land_types_PcmU» й «description», а самі оголошення можуть повторюватися.

Для спрощення процесу класифікації, я об’єднав стовпці «land_types_source», «land_types_PcmU» й «description» в один стовпець «text».

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

NLP і модель «мішка слів»

Отже, обробка природної мови (Natural-languageprocessing, NLP) — загальний напрям інформатики, штучного інтелекту й математичної лінгвістики. Він вивчає проблеми комп’ютерного аналізу й синтезу природної мови. Щодо штучного інтелекту, то аналіз — це розуміння мови, а синтез — генерація розумного тексту.

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

У своєму проєкті я використав одну з моделей NLP — модель «мішка слів» (МС, bag-of-words). Модель МС дає змогу презентувати текст як невпорядковану колекцію слів (якщо бути точним, то токенів) без урахування граматичних правил і порядку розміщення їх у конкретному розділі тексту.

В основі моделі «мішка слів» лежить досить проста ідея, яку можна резюмувати так:

  1. Створити з усього набору документів вокабуляр унікальних лексем (токенів) — наприклад, слів. Якщо послідовність елементів (токенів) у моделі МС складається зі слів, вона називається юніграмною (наприклад, речення «Продаж земельної ділянки» ділять на елементи [«продаж», «земельної», «ділянки»]). Але вона може складатися й з послідовності слів (наприклад, двограмної послідовності [«продаж земельної», «земельної ділянки»]). У ширшому значенні в NLP безперервні послідовності елементів — слова, літери або символи — називають також n-грамами. Вибір числа n у n-грамній моделі залежить від окремо взятої ділянки.
  2. Побудувати з кожного документа вектор ознак, що містить частотності входжень кожного слова в певний документ.

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

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

Бібліотека NLTK

Natural Language Toolkit (NLTK) — це набір бібліотек і програм для символьної та статистичної обробки природних мов, написаної мовою програмування Python. Її розробили Стівен Берд й Едвард Лопер.

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

Для початку роботи з NLTK необхідно згадати ще кілька понять:

  • Tokenizer — забезпечує токенізацію документів (розбиття на лексеми);
  • Stopwords — слова, які зустрічаються в мові надто часто, щоб нести якусь важливу інформацію (наприклад, артикль «а»);
  • Stemming (стемінг) — це процес скорочення слова до основи шляхом відкидання допоміжних частин, таких як закінчення або суфікса (наприклад, слова «будинку», «будинки» рахуватимуть як одне слово «будинк»);
  • Lemmatisation (лематизація) — це процес групування переплетених форм слова, щоб їх можна було проаналізувати як один предмет, ідентифікований лемою слова або словниковою формою (наприклад, слова «будинку», «будинки» рахуватимуть як одне слово «будинок»).

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

Отримавши всю необхідну інформацію, переходьмо безпосередньо до коду.

Перш за все визначимо Tokenizer, який буде проводити попередню обробку тексту й розбивку його на окремі слова (не забуваючи, звичайно, про імпорт відповідних бібліотек):

def ua_tokenizer(text,ua_stemmer=True,stop_words=[]):
    """ Tokenizer for Ukrainian language, returns only alphabetic tokens.
    
    Keyword arguments:
    text -- text for tokenize
    ua_stemmer -- if True use UkrainianStemmer for stemming words (default True)
    stop_words -- list of stop words (default [])
    """
    tokenized_list=[]
    text=re.sub(r"""['’"`�]""", '', text)
    text=re.sub(r"""([0-9])([\u0400-\u04FF]|[A-z])""", r"\1 \2", text)
    text=re.sub(r"""([\u0400-\u04FF]|[A-z])([0-9])""", r"\1 \2", text)
    text=re.sub(r"""[\-.,:+*/_]""", ' ', text)

    for word in nltk.word_tokenize(text):
        if word.isalpha():
            word=word.lower()
        if ua_stemmer is True:
            word=UkrainianStemmer(word).stem_word()
        if word not in stop_words:    
            tokenized_list.append(word)
    return tokenized_list

Функція ua_tokenizer отримує на вході текст, який потрібно розбити на токени, список stop_words, якщо треба також підтвердження в необхідності використовувати стемер. На початковому етапі очищає текст від додаткових символів, далі розбиває його на токени за допомогою функції nltk.word_tokenize(), потім перевіряє, чи токен складається зі слів (метод isalpha()), якщо так, то слова приводять до нижнього регістра, за потреби обробляють стемером і записують у новий список.

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

Маючи токенайзер, отримаємо докладнішу інформацію про нашу вибірку:

def  ngrams_info(series,n=1,most_common=20,ua_stemmer=True,stop_words=[]):
    """ ngrams_info - Show detailed information about string pandas.Series column.
    
    Keyword arguments:
    series -- pandas.Series object
    most_common -- show most common words(default 50)
    ua_stemmer -- if True use UkrainianStemmer for stemming words (default True)
    stop_words -- list of stop words (default [])
   	 
    """
    words=series.str.cat(sep=' ')
    print ('Кількість символів: ',len(words))
    words=nltk.ngrams(ua_tokenizer(words,ua_stemmer=ua_stemmer,stop_words=stop_words),n)
    words=nltk.FreqDist(words)
    print ('Кількість токенів: ',words.N())
    print ('Кількість унікальних токенів: ',words.B())
    print ('Найбільш уживані токени: ',words.most_common(most_common))
    words.plot (most_common, cumulative = True)

Функція ngrams_info об’єднує всі рядки об’єкта pandas.Series в один об’єкт типу string, далі за допомогою функції nltk.ngrams утворює список n-грамів (токенів) вказаного розміру, а функція nltk.FreqDist створює розподіл частот, що містить дані про n-грами й друкує основну інформацію.

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

Для юніграмів:

Рис. 2. Частоти найуживаніших юніграмів

Для триграмів:

Рис. 3. Частоти найуживаніших триграмів

Отже, для юніграмів (читай — слів) ми маємо у вибірці з 4256 екземплярів 151 318 токенів, з яких лише 6638 токенів (під час використання стемера) унікальні. А на частку 20 найуживаніших токенів припадає близько 30% усіх токенів, що є в датасеті.

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

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

А зараз перейдемо нарешті до класифікації.

Як моделі для класифікації я використав три класи класифікаторів nltk.NaiveBayesClassifier, nltk.MaxentClassifierі nltk.DecisionTreeClassifier. До технічної частини я не вдаватимуся, але коротко розповім про класифікатори. Кому цікаво, є книжка про бібліотеку NLTK — Natural Language Processing with Python (автори Steven Bird, Ewan Klein and Edward Loper), в якій детально розглянуто можливості бібліотеки загалом і специфіку класифікаторів (враховуючи, що її написали автори бібліотеки, я розглядаю її як «частину/доповнення» до документації). Під час написання коду до цієї статті в частині бібліотеки NLTK за основу я брав приклади саме з цієї книжки.

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

Клас nltk.NaiveBayesClassifier базується на наївному класифікаторі Баєса (НКБ). Наївні класифікатори Баєса — це сімейство простих імовірнісних класифікаторів, що ґрунтуються на застосуванні теореми Баєса з припущенням (наївним) про незалежність між змінними. Суть НКБ полягає в тому, що нам треба знайти такий клас, при якому його ймовірність для конкретного випробування була б максимальною, а припущення про незалежність між змінними потрібне для спрощення розрахунків.

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

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

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

Далі для навчання класифікатора, будь-якого з наведених класифікаторів, використовується метод train, що першим параметром приймає параметр labeled_featuresets (з документації «param labeled_featuresets: A list of classified featuresets, i.e., a list of tuples ``(featureset, label)``»). За своєю суттю параметр labeled_featuresets — це список, кожен елемент якого містить кортеж, що презентує одне випробування (наприклад, одне оголошення з набору) й складається з двох елементів: перший featureset — це ще один список, кожен елемент якого містить словник виду: {токен : наявність або відсутність токена у випробуванні (True або False)}, довжина списку featureset для всіх випробувань однакова й визначається вокабуляром унікальних токенів, другий елемент кортежу — це мітка класу для випробування. На перший погляд це здається складним (а якщо розібратись то й неефективним в обчислювальному плані), але спробую по порядку розповісти, як це можна реалізувати. Насамперед, визначимо вокабуляр (читай — список) унікальних токенів:

words=dataframe[X_column].str.cat(sep=' ') words=nltk.ngrams(ua_tokenizer(words,ua_stemmer=ua_stemmer,stop_words=stop_words),n=n)
words=nltk.FreqDist(words)
word_features=words.most_common(most_common)
word_features=[words[0] for words in word_features]

Тут усе просто: за аналогією до функції ngrams_info всі значення з колонки об’єкту DataFrame об’єднуємо в один об’єкт типу string, перетворюємо в об’єкт FreqDist (див. пояснення вище), знаходимо перших most_common-токенів, що найчастіше з’являються з їхніми частотами, і складаємо список найчастіше вживаних токенів без їхніх частот. Основне завдання цього етапу — знайти список перших найуживаніших токенів (юніграмів, біграмів тощо), що трапляються в усьому наборі даних. Чому беремо найбільш вживані токени? Тут ми керуємося припущенням, що найуживаніші токени несуть найбільше інформації, а решту можна відкинути. Це припущення має очевидні недоліки, але поки що візьмімо його за основу.

На наступному етапі визначимо невелику функцію, котра буде будувати featureset. Ось вона:

def bag_of_words(document_tokens,word_features):
    """ Return the dict of bag_of_words.

    Keyword arguments:
    document_tokens -- list of tokens
    word_features -- list of features

    """
   	 
    features={}
    for word in word_features:
        features['contains({})'.format(word)]=(word[0] in document_tokens)   	 
    return features

Функція bag_of_words на вході приймає список токенів кожного випробування document_tokens (у нашому випадку оголошення) і список найуживаніших токенів усієї вибірки word_features, повертає словник, що містить назву токена та його наявність або відсутність у конкретному випробуванні.

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

Отже, нижче наведено універсальну функцію для базових класифікаторів бібліотеки NLTK:

def nltk_classifiers(dataframe,X_column,y_column,classifier=nltk.NaiveBayesClassifier,n=1,stop_words=[],ua_stemmer=False,most_common=1000):
     
    words=dataframe[X_column].str.cat(sep=' ')
    words=nltk.ngrams(ua_tokenizer(words,ua_stemmer=ua_stemmer,stop_words=stop_words),n=n)
    words=nltk.FreqDist(words)
    word_features=words.most_common(most_common)
    word_features=[words[0] for words in word_features]
    
    labeled_featuresets=[]
    for _,row in dataframe.iterrows():
        row[X_column]=nltk.ngrams(ua_tokenizer(row[X_column],ua_stemmer=ua_stemmer,stop_words=stop_words),n=n)
        row[X_column]=[words[0] for words in nltk.FreqDist(row[X_column])]   	 
        labeled_featuresets.append((bag_of_words(row[X_column],word_features=word_features), row[y_column]))  
   	 
    
    train_set,test_set,_,_=train_test_split(labeled_featuresets,dataframe[y_column],stratify=dataframe[y_column],test_size=0.33)
    
    if classifier==nltk.MaxentClassifier:
        classifier=classifier.train(train_set, max_iter=5)
    else:
        classifier=classifier.train(train_set)    	 
        accuracy_train=nltk.classify.accuracy(classifier, train_set)
        accuracy=nltk.classify.accuracy(classifier, test_set)
        print('Точність класифікатора на навчальних даних:',accuracy_train)
        print('Точність класифікатора на тестових даних:',accuracy)
        y_true=[]
        y_pred=[]
        for test in test_set:
            y_true.append(test[1])
            y_pred.append(classifier.classify(test[0]))
        confmat=nltk.ConfusionMatrix(y_pred,y_true)
        print(confmat)
    return classifier  

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

Ми перетворили нашу вибірку у формат, придатний для подачі до класифікатора, однак постає питання якісного оцінювання класифікатора. Зрозуміло, що якщо ми будемо оцінювати класифікатори за даними, за якими вони навчалися, не відомо, як вони будуть поводити себе на даних, яких вони не бачили під час навчання. Найпростіший вихід із ситуації — розбиття вибірки на дві підмножини: навчальну й тестову, в ідеалі тестову множину можна використовувати лише для фінальної перевірки класифікатора з уже підібраними параметрами. Функція train_test_split бібліотеки scikit-learn розбиває нашу множину вибірки на дві підмножини: навчальну й тестову, пропорційно попередньо визначеним класам (за це відповідає параметр stratify), у такому разі вона має дивний вигляд, але це пов’язано з різною логікою подачі даних в обох бібліотеках (про бібліотеку scikit-learn поговоримо в другій частині статті, тому зациклюватися на ній не буду).

На наступному етапі після розбиття даних навчаємо наш класифікатор.

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

У нас усе готово, тож запускаємо класифікатори з кількома різними параметрами для порівняння. Код нижче:

classifiers=[nltk.NaiveBayesClassifier,nltk.MaxentClassifier,nltk.DecisionTreeClassifier]
for y_column in ('land_types','built_up'):
    for classifier in classifiers:    
        for n in (1,3): 	 
            print ('Класифікатор -',classifier)
            print ('Порядок n -',n)      	 
            print ('Класифікатор за колонкою -',y_column)
            model=nltk_classifiers(land_data,X_column='text',y_column=y_column,classifier=classifier, n=n)
            if classifier==nltk.NaiveBayesClassifier:
                print ('Найважливіші токени для класифікації за колонкою -',y_column)
                model.show_most_informative_features(10)

На мій погляд, тут майже все зрозуміло, тож не затримуватимуся. Єдиний момент — метод show_most_informative_features() класифікатора nltk.NaiveBayesClassifier показує зазначену кількість токенів, що найкраще класифікують той чи інший об’єкт.

А тепер перейдемо до результатів класифікації за типами для юніграмів для кожного класифікатора:

Результати класифікації за типами для класифікатора nltk.NaiveBayesClassifier:

Класифікатор - <class 'nltk.classify.naivebayes.NaiveBayesClassifier'>
Порядок n - 1
Класифікатор за колонкою - land_types
Точність класифікатора на навчальних даних: 0.8796913363732024
Точність класифікатора на тестових даних: 0.8327402135231317
  |   1   2   3   4   5   6   7 |
--+-----------------------------+
1 |<735>  4   5   7   8   .   9 |
2 |   5 <86>  7   8   .   2   3 |
3 |  76  15<271>  5   1   .   . |
4 |  14   5   2 <61>  1   .   . |
5 |   7   .   .   2  <3>  .   . |
6 |   .   .   .   .   .  <.>  . |
7 |  36   7   5   1   .   . <14>|
--+-----------------------------+
(row = reference; col = test)

Результати класифікації за типами для класифікатора nltk.MaxentClassifier:

Класифікатор - <class 'nltk.classify.maxent.MaxentClassifier'>
Порядок n - 1
Класифікатор за колонкою - land_types
  ==> Training (5 iterations)

  	Iteration	Log Likelihood	Accuracy
  	---------------------------------------
         	1      	-1.94591    	0.019
         	2      	-1.07311    	0.697
         	3      	-0.83080    	0.697
         	4      	-0.71131    	0.697
     	Final      	-0.64350    	0.697
Точність класифікатора на навчальних даних: 0.6969484391441599
Точність класифікатора на тестових даних: 0.6832740213523132
  |   1   2   3   4   5   6   7 |
--+-----------------------------+
1 |<869>113 216  70  13   2  26 |
2 |   .  <4>  .   1   .   .   . |
3 |   3   . <74>  .   .   .   . |
4 |   1   .   . <13>  .   .   . |
5 |   .   .   .   .  <.>  .   . |
6 |   .   .   .   .   .  <.>  . |
7 |   .   .   .   .   .   .  <.>|
--+-----------------------------+
(row = reference; col = test)

Результати класифікації за типами для класифікатора nltk.DecisionTreeClassifier:

Класифікатор - <class 'nltk.classify.decisiontree.DecisionTreeClassifier'>
Порядок n - 1
Класифікатор за колонкою - land_types
Точність класифікатора на навчальних даних: 0.9786039985969835
Точність класифікатора на тестових даних: 0.9138790035587189
  |   1   2   3   4   5   6   7 |
--+-----------------------------+
1 |<827>  4  17  22   2   .   2 |
2 |   7<106>  2   3   .   .  10 |
3 |  14   2<271>  .   .   .   3 |
4 |  18   2   . <58>  1   .   1 |
5 |   6   .   .   1 <10>  .   . |
6 |   .   .   .   .   .  <2>  . |
7 |   1   3   .   .   .   . <10>|
--+-----------------------------+
(row = reference; col = test)

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

Результати класифікації за забудованістю для класифікатора nltk.NaiveBayesClassifier:

Класифікатор - <class 'nltk.classify.naivebayes.NaiveBayesClassifier'>
Порядок n - 1
Класифікатор за колонкою - built_up
Точність класифікатора на навчальних даних: 0.9214310768151526
Точність класифікатора на тестових даних: 0.892526690391459
  |   0	    1 |
--+-----------+
0 |<1096>  45 |
1 |  106 <158>|
--+-----------+
(row = reference; col = test)

Результати класифікації за забудованістю для класифікатора nltk.MaxentClassifier:

Класифікатор - <class 'nltk.classify.naivebayes.NaiveBayesClassifier'>
Порядок n - 1
Класифікатор за колонкою - built_up
Точність класифікатора на навчальних даних: 0.9214310768151526
Точність класифікатора на тестових даних: 0.892526690391459
  |   0	    1 |
--+-----------+
0 |<1096>  45 |
1 |  106 <158>|
--+-----------+
(row = reference; col = test)

Результати класифікації за забудованістю для класифікатора nltk.DecisionTreeClassifier:

Класифікатор - <class 'nltk.classify.decisiontree.DecisionTreeClassifier'>
Порядок n - 1
Класифікатор за колонкою - built_up
Точність класифікатора на навчальних даних: 0.9705366538056822
Точність класифікатора на тестових даних: 0.9373665480427046
  |   0	    1 |
--+-----------+
0 |<1155>  41 |
1 |   47 <162>|
--+-----------+
(row = reference; col = test)

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

Важливо зауважити, що для забудованих земельних ділянок класифікатор, що присвоюватиме всім значенням вибірки значення 0 (фактично класифікатором не буде, а прийматиме, що всі земельні ділянки незабудовані й не розв’язуватиме поставленого завдання) точність становитиме 85,53% (частка незабудованих земельних ділянок у вибірці), тому всі класифікатори нижче цього рівня можна навіть не розглядати.

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

Наприклад, умовно у вибірці є 50 оголошень продажу вільних від забудови ділянок у селі Сокільники, тоді класифікатор розглядатиме токен «сокільник» як ідентифікатор класу «незабудована», що за своєю суттю неправильно. Але як зрозуміти, як кожен токен «сприймається» класифікатором? Однією з особливостей бібліотеки NLTK є можливість виклику методу show_most_informative_features() для класифікаторів nltk.NaiveBayesClassifier і nltk.MaxentClassifier. Ось результати для класифікатора nltk.NaiveBayesClassifier:

Для класифікації за типами ділянок:

Найважливіші токени для класифікації за колонкою - land_types
Most Informative Features
contains(('виробництв',)) = True            6 : 1  	=   620.9 : 1.0
contains(('сільськогосподарськ',)) = True   6 : 1  	=   443.5 : 1.0
contains(('селянськ',)) = True              2 : 1  	=   309.9 : 1.0
contains(('веденн',)) = True                6 : 1  	=   282.2 : 1.0
contains(('me',)) = True                    6 : 1  	=   266.1 : 1.0
contains(('канал',)) = True                 6 : 1  	=   266.1 : 1.0
contains(('sitalozemlyaзагальн',)) = True   6 : 1  	=   266.1 : 1.0
contains(('господарств',)) = True           2 : 3  	=   257.8 : 1.0
contains(('багатоквартирн',)) = True        5 : 1  	=   234.7 : 1.0
contains(('колективн',)) = True            	3 : 1  	=   226.3 : 1.0

Для класифікації за забудованістю ділянок:

Найважливіші токени для класифікації за колонкою - built_up
Most Informative Features
contains(('цегл',)) = True               1 : 0  =  119.8 : 1.0
contains(('стоїт',)) = True              1 : 0  =  60.1 : 1.0
contains(('кухн',)) = True               1 : 0  =  60.1 : 1.0
contains(('цеглян',)) = True             1 : 0  =  58.3 : 1.0
contains(('літн',)) = True               1 : 0  =  53.0 : 1.0
contains(('одноповерхов',)) = True       1 : 0  =  49.1 : 1.0
contains(('опаленн',)) = True            1 : 0  =  45.2 : 1.0
contains(('підвал',)) = True             1 : 0  =  43.6 : 1.0
contains(('деревян',)) = True            1 : 0  =  38.6 : 1.0
contains(('горищ',)) = True              1 : 0  =  37.3 : 1.0

Метод show_most_informative_features() дозволяє досліджувати класифікатор, щоб визначити, які з властивостей (токенів), які він знайшов, найефективніші для класифікації. Наприклад, він показує, що слово «цегли» у 119,8 раза частіше свідчить про те, що ділянку забудовано.

Висновки

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

Звичайно, отримані результати класифікаторів можна покращити і покращувати їх якість я за допомогою бібліотеки scikit-learn — на мій особистий і суб’єктивний погляд, однієї із найкращих бібліотек, написаних на Python і точно з найкращою документацією, але про це вже в другій частині. А щодо бібліотеки NLTK, то це дуже хороша бібліотека для NLP з великим колом можливостей, що виходять далеко за межі цієї теми.

Рекомендовані джерела:

"Давно на часі". Що ІТ-компанії думають про імміграційні квоти

$
0
0

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

Але спочатку трішки теорії від Мінцифри

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

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

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

5000 квот розподілили серед п’яти міст:

  • Київ — 2500;
  • Харків — 700;
  • Львів — 600;
  • Дніпро — 600;
  • Одеса — 600.

Думка ІТ-компаній

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

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

Юрій Антонюк, віце-президент EPAM, глава компанії у Центральній та Східній Європі

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

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

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

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

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

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

Ярослав Любінець, співзасновник та голова Ради директорів Softserve

Ініціатива Міністерства цифрової трансформації щодо квоти на імміграцію 5000 іноземних ІТ-спеціалістів — давно на часі.

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

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

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

Андрей Яворский, вице-президент по стратегии и технологиям GlobalLogic

Нехватка ІТ-специалистов в стране — один из вызовов для роста индустрии. Сейчас в Украине более 160 тысяч ІТ-специалистов. С одной стороны, по данным Министерства цифровой трансформации, университеты выпускают около 15 тысяч профильных выпускников ежегодно — менее 10% от общего количества технических талантов в стране. С другой, по данным Минцифры, ежегодно в украинских IT-компаниях открывается около 40 тысяч позиций.

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

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

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

По данным Министерства цифровой трансформации, столица получит больше всего мест — 2500, Харьков — 700, Днепр, Одесса, Львов по 600. Такое распределение по квотам выглядит вполне логично, учитывая динамику количества открытых позиций по городам. По данным DOU, в столице в феврале 2020 года насчитывалось около 3 тысяч открытых позиций, в Харькове 765, чуть меньше во Львове — 675, в Днепре и Одессе около 300 открытых позиций.

Віталій Кармазінський, керуючий директор Luxoft Ukraine

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

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

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

Віталій Седлер, СЕО та співзасновник Intellias

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

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

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

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

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

Валерій Красовський, CEO та співзасновник Sigma Software

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

За різними оцінками сьогодні в країні нараховують близько 200 000 ІТ-спеціалістів, близько 10% від цієї кількості — відкриті вакансії різних IT-компаній. Тож можемо порахувати нестачу в 20 000 фахівців в галузі. Якщо ініціатива закриє пролом хоча б в 5000 професіоналів — це вже позитивний результат для індустрії. Роботи та проектів вистачить всім.

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

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

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

Дар’я Горніцька, Director of Global Delivery Operations Astound Commerce

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

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

Щодо розподілу квот за містами — все закономірно. Його визначали на базі багатьох факторів, зокрема — ринку ІТ-компаній та спеціалістів, наявності ІТ-спільноти, розвиненої транспортної інфраструктури, привабливості локації з точки зору умов життя, безпеки та ін. До того ж, у цих п’яти містах зосереджена найбільша кількість сервісних і продуктових ІТ-компаній, стартапів.
З переліку запропонованих міст Astound Commerce цікавий тільки Київ, в якому знаходиться наш найбільший офіс в Україні. Наразі ми лише аналізуємо можливість застосування цього інструменту для залучення іноземних ІТ-спеціалістів до компанії, оскільки саме зараз ми працюємо над запуском офісів на ринках південно-східної Європи та південної Азії. Можливо, найближчим часом у нас виникне необхідність запросити фахівців з нових інжиніринг-центрів приєднатися до української команди.

Олександр Конотопський, Founder & CEO Ajax Systems

Вважаю це чудовою ідеєю. Хоч ця квота і виглядає дещо кумедно, тому що, на мій погляд, візи для розумних людей в Україну потрібно давати у необмежених кількостях. Але цей закон стане добрим початком. Почнемо з IT-шників, потім додадуть квоти для інженерів, маркетологів, продавців. Займатися talent acquisition в країну — дуже правильна ініціатива, і я схвалюю будь-який крок у цей бік. Український IT-ринок ще дуже молодий. Дорослі і досвідчені європейці, американці чи азіати сильно допоможуть у розвитку сегмента і кожного окремого спеціаліста.

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

Щодо поділу квот між містами — це дивна річ. Можливо, це пов’язано з розвитком та підтримкою регіонів, але ж сьогодні в Україні достатньо спеціалістів не тільки у Києві. Нещодавно ми відкрили R&D-офіс в Харкові саме через велику кількість талановитих фахівців. І будемо ще відкриватися в регіонах з R&D чи виробничими потужностями.

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

Глобально це дуже хороша тема.

Юрий Варчинский, Chairman & founder HYS Enterprise

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

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

За текущий год менее 1% (из рассматриваемых кандидатур) иностранных граждан обратились к нам с желанием переселиться в Одессу. Так что со своей стороны я бы приветствовал усилия государства в направлении популяризации Украины как места для иммиграции таких специалистов. Даже для экспертов из западных стран с развитой экономикой такой переезд бы сопровождался существенным улучшением потребительской способности и качества жизни в целом, не говоря уже о странах ближнего зарубежья.

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

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

Денис Жаданов, VP of Marketing Readdle

Вообще инициатива хорошая, как по мне. Любое движение к упрощению бюрократии — это хорошо. Вопрос в другом, есть ли в самом деле 5000 человек, которые готовы приехать и работать в Украине? Если да — то это прекрасно.

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

Квоты по городам не совсем понимаю зачем нужны.

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

Что следует знать об организации работы при переходе на микросервисную архитектуру

$
0
0

Привет! Меня зовут Руслан Колодяжный, я CTO R&D-центра финтех-компании Wirex. За 5 лет существования наша компания выросла со стартапа до международной платформы, которой пользуются более 3 миллионов людей по всему миру. Одним из важных этапов нашего развития был переход от монолитной архитектуры к микросервисной, подкрепленный новой организационной структурой. В этой статье я расскажу о том, как изменения организационного подхода повлияли на процесс разработки. Возможно, опыт нашей компании будет полезным тем, кто планирует переход на микросервисную архитектуру и хочет сделать этот процесс максимально эффективным.

Предыстория

Все началось с приложения, написанного на .NET Framework. В качестве облачной платформы мы выбрали Azure, как базу данных использовали Azure SQL, а системой контроля версий выступал Bitbucket. В качестве хостинга для API отдали предпочтение Azure App Services. Back-end хостился в виде Azure Cloud Service workers, которые были тесно связаны между собой и являлись монолитом. Разработка back-end велась в одном репозитории командой из 5 человек. Задачей команды было максимально быстро доставить изменения в production и получить обратную связь от пользователей.

Спустя полгода после начала работы количество пользователей выросло до 50 тысяч. Для его увеличения приняли решение расширить функциональность приложения. Число разработчиков увеличилось до 15, и они были разделены на несколько команд. Как методологию разработки мы использовали Feature driven development, фокус разработчиков был сосредоточен на функциональных элементах (features), полезных с точки зрения пользователя. Владение кодовой базой на данном этапе было коллективным (collective code ownership), ответственность команд заключалась в имплементации новой функциональности, а также доставке изменений в production.

Рис. 1. Коллективное владение единой кодовой базой

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

Каждая из команд имела в своем владении dev environment, которая была максимально похожа на prod. Разработка новой функциональности (feature) для команды из 3–4человек в среднем занимала 2–3 недели.Но за счет того, что количество QA-инженеров было ограничено, формировалась очередь на прохождение регрессионного тестирования на UAT, и в некоторых случаях это могла быть неделя или даже больше. Эти факторы вместе с ограничениями масштабируемости монолитного приложения в дни рассылки маркетинговых кампаний и постоянно растущая клиентская база дали толчок к переходу на микросервисную архитектуру.

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

Мы начали всю функциональность максимально переносить из монолитного приложения во вспомогательные или независимые микросервисы. В качестве инфраструктурной платформы был выбран Azure Service Fabric, так как она позволяет быстро настроить кластер и управлять масштабированием. Также Azure Service Fabric предоставляет богатую программную модель в виде stateful/stateless-сервисов, поддержку actor model и reliable state, которые мы использовали в своих микросервисах.

При разделении монолита мы применяли DDD, шаблон Decompose by Subdomain. Количество микросервисов увеличивалось с добавлением в продукт новой функциональности. Каждому микросервису мы выделили свою кодовую базу (репозиторий). При проектировании применялся подход отдельных баз данных (БД) под каждый микросервис. Для разделения ответственности в своем продукте мы использовали CQRS- и Event Sourcing-подходы, shared libraries поставлялись через NuGet.

Также был настроен процесс CI/CD с помощью TeamCity & Octopus. Микросервисы доставлялись в production в виде гранулярных rolling upgrade-деплоев.

Рис. 2. Распределение ответственности команд по микросервисам, коллективное владение распределенной кодовой базой

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

При разделении на микросервисы особое внимание уделяли безопасности.

Мы смогли реализовать ограничение по доступности своих сервисов на уровне подсетей (Network Security Groups, Demilitarized Zone). Некоторые компоненты, которые владеют информацией security sensitive, вынесены в изолированные кластеры. Вследствие кластеризации мы ежегодно проходим PCI DSS-сертификацию.

Введение strong code ownership и распределение ответственности

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

Решением стало введение строгого типа владения кодовой базой (strong code ownership) и разделение зон ответственности. Каждый сервис должен был принадлежать только одной команде, которая отвечает за внесение изменений, будущее развитие этого сервиса, его поддержку и доставку в production.

Воплощением strong code ownership в Wirex стали доменные команды, которые появились вместо feature teams. Команды были созданы вокруг доменов — областей знаний, логически объединенных бизнес-процессов и нашего приложения. Их сфера ответственности касалась нескольких микросервисов. Таких команд у нас пять, каждая из них управляет своими микросервисами.

Рис. 3. Распределение ответственности доменных команд по микросервисам, строгий тип владения кодовой базой

Сейчас у каждой доменной команды есть своя development environment, которая максимально приближена по инфраструктуре к production environment.
Появилась полноценная команда DevOps из 8 человек, которая полностью отвечает за инфраструктуру и безопасность. Скорость разработки и количество релизов увеличились примерно в 5 раз.

Как это изменило структуру разработки в компании в целом (не только Back-end)

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

Рис. 4. Процесс сбора требований и декомпозирования задач на доменную структуру

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

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

Выводы

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

Viewing all 2504 articles
Browse latest View live