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

Junior дайджест: курси, стажування, вакансії. Вересень’19

$
0
0

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

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

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

КомпаніяМістоНапрям, дедлайнТип
AltexSoftКременчук.NET, Xamarin — вересеньКурси
AprioritДніпроС++ — 4 вересня, .Net web — 18 вересняКурси
COAX SoftwareІвано-Франківськ Ruby — 16 вересня

Python — 7 жовтня

Курси
EPAMКиїв, Вінниця, Харків, ДніпроJava, DevOps, Front-end, QA, Test Automation, .NET — дедлайниКурси
Forte GroupТернопільSoftware Testing — 16 вересняКурси
GlobalLogicКиїв, ХарківReact, Linux Kernel — 10 вересняКурси
InternetDevelsЛуцькWeb Development, QA, Project ManagementКурси
InventorSoftЧернівці

Java — 2 вересня


Front-end — 16 вересня

Курси
Netcracker Київ Java — 2 вересняКурси
NIX Solutions LtdХарківJava, PHP + CMS, Linux Administration / DevOps, QAКурси
QATestLabonline«Основи тестування ПЗ» — 10 вересняКурси
RubyGarageДніпроRuby/Ruby on Rails — 1 вересняКурси
SoftServeЛьвів, Івано-Франківськ, Харків, Рівне, ЧернівціDevOps, Test Automation, Java, .Net, Ruby, WebUI- дедлайниКурси
SolvdЧернівціQA- 10 вересняКурси
SolveCareКиївReactNative — 9 вересняКурси
SPD-UniversityЧеркасиJava, Front-end, Test Automation — 13 вересня Курси
YalantisДніпроiOS — до 3 вересня Курси
Ш++КропивницькийJava — 7 вересняКурси
AMC BridgeДніпро, Львів, Суми, Хмельницький, ЧернівціC++, C#, web services — на постійній основіСтажування
BAKOTECHКиївКібербезпекаСтажування
CHI SoftwareХарківSales ManagementСтажування
CleveroadДніпро, ХарківJavaScript, Front-end React/Angular — до 15 вересняСтажування
Clockwise SoftwareДніпроJavaScript, Project managerСтажування
DataArtКиїв, Львів

Київ: .NET, QA, Java, Front end

Львів: .NET, QA

Харків: Python, .NET

Стажування
GeeksForLessМиколаївС#, .Net — на постійній основіСтажування
groupBWTЗапоріжжяPHP, Python — на постійній основіСтажування
IdeaSoft.ioХарківSalesСтажування
LeobitЛьвів.NET, Ruby, Automation QA, ReactСтажування
LogicifyХерсонAngular, Python — на постійній основіСтажування
Quality Assurance GroupЛьвівQA — на постійній основіСтажування
QubstudioЛьвівUX/UI design — 13 вересняСтажування
SerpstatОдесаCustomer Support Стажування
Sigma Software UniversityКиїв, Львів, Одеса, ХарківTechnical Support, Python, JavaScript (Game Development), Embedded, PHP, IT Researcher, Ruby on Rails, Java — дедлайниСтажування
SysGearsДніпроJava, JS — до набору групиСтажування
TeamDevХарківJava — на постійній основіСтажування
UbisoftКиївOnline Programming — до 16 вересняСтажування
WEB4PROХарківPHP (Magento 2) — на постійній основіСтажування
WebinseДніпроMagento Developer — 16 вересняСтажування
White Label AgencyПолтаваWordPress — на постійній основіСтажування
WiserBrandХарківCustomer SupportСтажування
ZazmicонлайнNode.jsСтажування
AgilitesХарківManual QA — на постійній основіРобота
AlcorКиїв, ОдесаIT ResearcherРобота
AltigeeЛьвівLead Generation ManagerРобота
Bini BambiniХарківData Analyst, .NET, Animator 2DРобота
DevelopExКиївQAРобота
ExpercastвіддаленоQAРобота
GenesisКиївProduct AnalystРобота
IntersogОдеса, КиївResearch & Development, Python Робота
JoobleКиївJunior SysAdmin/HelpdeskРобота
LoopMeДніпроJavaScriptРобота
MaybeWorksХарківJavaScriptРобота
MobiDevХарків, Чернівці

Чернівці: QA

Харків: Project management, QA
Робота
NIX Solutions Ltd ХарківQA, Tech Support, BA, Java, PHP/CMS, Node.js, .NET, Data, Unix, Python, AndroidРобота
PioGroup SoftwareХарківPHPРобота
SMART businessКиївCRM, AXРобота
Solid Software ХарківFlutter — на постійній основіРобота
TechMagicЛьвівIOS Trainee — 22 серпняРобота
Ubisoft КиївQC, Game TesterРобота
YouScanКиївTech support engineer, IT Support/System AdministrationРобота

AltexSoft

Напрям:курси .NET, Xamarin
Місто:Кременчук.
Дедлайн подачі заявок:вересень.

Вимоги до кандидатів:

  • технічна освіта;
  • базові знання: C#, SQL;
  • англійська — не нижче Pre-intermediate.

Як потрапити:заповнити форму.

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

Деталі:пишіть на пошту lab@altexsoft.com, 0993361216.

Apriorit

Напрям:курси C++, .Net web.
Місто:Дніпро.
Дедлайн подачі заявок: C+± 4 вересня, .Net web — 18 вересня.

Вимоги до кандидатів:

С++:

  • студент ІТ-спеціальності у ВНЗ;
  • базові знання C++;
  • англійська — не нижче Intermediate.

.Net web:

  • студент ІТ-спеціальності у ВНЗ;
  • базові знання C#;
  • англійська — не нижче Intermediate.

Як потрапити:заповнити форму для С++або .Net web, пройти письмове тестування.

Умови:тривалість — 2 місяці, за кращий проект — премія, можливість працевлаштування в компанії.

Деталі:на сайті: C++, .Net web.

COAX Software

Напрям:курси Ruby, Python.
Місто:Іано-Франківськ.
Дедлайн подачі заявок: Ruby- 16 вересн, Python — 7 жовтня.

Вимоги до кандидатів:

Ruby:

  • знання СУБД MySQL/PostgreSQL, OOP;
  • базові навички в Ruby / Rails;
  • досвід роботи з Linux / OS X;
  • англійська — не нижче Intermediate.

Python:

  • досвід роботи з HTML, CSS, JavaScript;
  • знання систем Linux / UNIX;
  • розуміння HTTP / TCP;
  • знання Python (синтаксис Python; принципи OOP; OOP з Python);
  • знання баз даних (MySQL, Postgresql), SQL;
  • знання Git.

Як потрапити:заповнити форму для Rubyчи Python.

Умови:заявники повинні мати власний ноутбук.

Деталі:Rubyчи Python, або пишіть на пошту recruiter@coaxsoft.comчи телефонуйте +38 068 240 8700.

EPAM

Тип:курси.
Місто:Київ, Харків, Дніпро, Вінниця.

Напрями та дедлайни подачі заявок:

Київ:

Харків:

Дніпро

Вінниця

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

Умови:зовнішні заняття (до 3 місяців), Pre-Production лабораторія (від 3 до 6 місяців). Після закінчення навчання найкращі випускники отримають можливість продовжити співпрацю з компанією.

Forte Group

Напрям:навчання — Software Testing.
Місто:Тернопіль.
Дедлайн подачі заявок:до 16 вересня.

Вимоги до кандидатів:

  • загальна технічна обізнаність;
  • логічне мислення, аналітичні навички;
  • англійська на рівні Intermediate або вище.

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

Умови:тривалість курсу: 1 жовтня — 30 листопада, можливість працевлаштування.

Деталі:на сайті

GlobalLogic

Напрям:навчання — React, Linux Kernel.
Місто:Київ, Харків.
Дедлайн подачі заявок:до 10 вересня.

Вимоги до кандидатів:

React:

  • 1,5+ роки практичного досвіду із JavaScript, HTML, CSS;
  • впевнені знання JavaScript (lexical structure, data types, variable declarations and visibility scopes, primary expressions and operators, conditions, statements, functions, closures, this, Promise);
  • розуміння колекцій у JavaScript та основних методів взаємодії з ними;
  • досвід роботи з DOM, маніпуляції DOM Nodes, DOM Events;
  • розуміння принципів клієнт-серверної взаємодії;
  • досвід роботи з системою контролю версій Git;
  • знання базових алгоритмів;
  • англійська на рівні Intermediate або вище.

Linux Kernel:

  • досвід розробки на мові C — від 2 років;
  • досвід розробки програмного забезпечення для вбудованих систем (embedded systems);
  • знання Linux на рівні користувача та базові знання інтерфейсу командного рядка в Unix-подібних ОС;
  • вища освіта за напрямками розробки ПЗ, системного програмування, комп’ютерних систем або мікроелектронних систем.

Як потрапити:заповнити форму для Reactабо Linux Kernel.

Умови:початок зустрічей — у другій половині вересня, у вечірній час; тривалість — близько 1 місяця (React) та 3 місяці (для Linux Kernel), 2-3рази на тиждень.

Деталі:React: пишіть на пошту kyiv-procamp@globallogic.com (будь ласка, вкажіть у темі листа «React GL ProCamp»), на сайті, Linux Kernel: пишіть на пошту join.kharkiv@globallogic.com, на сайті.

InternetDevels

Напрям:курси — розробка сайтів на CMS Drupal 8, QA та PM.
Місто:Луцьк.
Дедлайн подачі заявок:реєстрація відбувається на постійній основі, оскільки курси відбуваються регулярно. Охочих, що не встигнуть потрапити на цей набір, запрошують на наступний.

Вимоги до кандидатів:

  • для майбутніх програмістів необхідне базове розуміння PHP, HTML, CSS, JavaSсript (не обов’язково);
  • для майбутніх РМ’ів необхідне знання англійської мови на рівні спілкування;
  • загалом необхідне бажання вчитися та розвиватися.

Як потрапити:подати заявку на сайті.

Умови:курс триває 4 тижні. Заняття 3 — 5 разів на тиждень по 2-3 години.Найкращим студентам після закінчення курсу пропонують подальшу інтернатуру в компанії і працевлаштування.

Деталі:на сайті, на сторінці Facebook.

InventorSoft

Напрям:курси — Java, Front-end.
Місто:Чернівці.
Дедлайн подачі заявок: Java — 2 вересня, Front-end — 16 вересня.

Вимоги до кандидатів:

Front-end

  • рівень англійської — Intermediate+;
  • базові знання з HTML, JavaScript, CSS.

Java

  • рівень англійської — Intermediate+;
  • базові знання з HTML/JS, SQL, OOP, Java.

Як потрапити:подати заявку на сайті, пройти технічне тестування та тестування з англійської мови, пройти технічну співбесіду та співбесіду з HR.

Умови:початок навчання — 16 версеня (Java) та 30 вересня (Front-end) , тривалість — 3 місяці. Два етапи: лекційні заняття з практичними завданнями та створення групового проекту. Після закінчення навчання можливе працевлаштування.

Деталі:на сайтіабо пишіть на пошту office@inventorsoft.co.

Netcracker

Напрям:курси Java.
Місто:Київ.
Дедлайн подачі заявок: 2 вересня.

Вимоги до кандидатів:

  • базовий рівень знань ООП;
  • базовий рівень знань БД;
  • англійська мова на рівні Intermediate+;
  • студенти 3+ курсів, технічна спеціальність.

Як потрапити:заповнити анкету на сайтідо 2 вересня, пройти відбір анкет, пройти 2 співбесіди (технічну та з HR).

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

Деталі:на сайтіабо пишіть на пошту EduCenterKyivGroup@netcracker.com.

NIX Solutions Ltd

Напрям:курси.
Місто:Харків.

Вимоги до кандидатів:

Як потрапити:подати резюме на сайті, пройти тестування в офісі або ВНЗ, пройти співбесіду.

Умови:Практика — очне навчання 40 годин на тиждень в офісі компанії протягом 3-хтижнів у літній період. Навчання — 2-3рази на тиждень у вечірній час від 1 до 5 місяців. Інтенсив — очне навчання 40 годин на тиждень в офісі компанії протягом 2-хмісяців.

Деталі:пишіть на пошту education@nixsolutions.com.

QATestLab

Напрям:онлайн-курси QA.
Дедлайн подачі заявок:реєстрація відбувається постійно. «Основи тестування ПЗ» — старт 10 вересня.
Вимоги до кандидатів:навчатися можуть усі охочі.

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

Умови:викладачi курсів — QAEngineers компанії QA TestLab. Формат навчання: онлайн. Тривалість курсів — від 3 до 5 тижнів. Курси включають в себе лекції, що проводяться через систему GoToWebinar двічі на тиждень, практичні домашні завдання та підсумковий іспит.

Деталі:на сайті.

RubyGarage

Напрям:курси Ruby/Ruby on Rails.
Місто:Дніпро.
Дедлайн подачі заявок: 1 вересня.

Вимоги до кандидатів:

  • базові знання HTML, CSS, JavaScript та мінімальний досвід роботи з цими технологіями;
  • знання базових принципів роботи баз даних і мови SQL;
  • розуміння об’єктно-орієнтованої парадигми програмування;
  • знайомство з однією з серверних мов програмування (PHP, Java, С ++ / С #, Python...);
  • технічна англійська на рівні читання документації;
  • бажання навчатися та вирішувати задачі;
  • мінімум 10-15вільних годин в тиждень на навчання.

Як потрапити:заповнити форму на сайті, виконати тестове завдання, пройти співбесіду.

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

Деталі:на сайтіабо пишіть на пошту railscourses@rubygarage.org.

SoftServe

Тип:курси.
Місто:Львів, Київ, Івано-Франківськ, Харків, Дніпро, Рівне, Чернівці.
Напрям та дедлайн подачі заявок:

Нижче вказані дати початку курсів. Реєстрація закривається за 14 днів до старту.

  • DevOps: Івано-Франківськ — 16 вересня;
  • Java : Івано-Франківськ — 16 вересня; Рівне — 17 вересня, Львів — 10 жовтня;
  • .Net: Львів — 16 вересня;
  • DevOps Development for Unix: Чернівці — 16 вересня, Львів — 29 вересня;
  • Ruby: Івано-Франківськ — 23 вересня;
  • WebUI: Харків — 3 жовтня;
  • Test Automation: Харків (.NET) — 14 жовтня; Чернівці (Python) — 28 жовтня.

Вимоги до кандидатів:

  • рівень англійської Intermediate+;
  • студенти дотичних напрямків 2-йкурс і вище;
  • готовність до насиченої роботи.

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

Solvd

Напрям: QA.
Місто:Чернівці.
Дедлайн подачі заявок: 10 вересня.

Вимоги до кандидатів:

  • завершена технічна освіта;
  • рівень англійської В2.

Як потрапити:завантажити резюме та мотиваційний лист (!) у форму.

Умови:працевлаштування для кращих студентів.

Деталі:на сайті.

SolveCare

Напрям: ReactNative.
Місто:Київ.
Дедлайн подачі заявок: 9 вересня.

Вимоги до кандидатів:

  • досвід роботи з HTML/CSS;
  • базові знання Javascript;
  • готовність працювати 25+ годин на тиждень;
  • рівень англійської Upper Intermediate.

Як потрапити:надіслати резюме на Academy@solve.careз лінком на GitHub або проекти.

Умови:навчання по буднях з 9:00 до 14:00.

Деталі:пишіть на пошту Academy@solve.careабо на сайті.

SPD-University

Напрям: Java, Front-end, Test Automation.
Місто:Черкаси.
Дедлайн подачі заявок: 13 вересня.

Вимоги до кандидатів:

Java:

  • Java 8 Core: класи/інтерфейси, Generic, Collections API, IO, Exceptions, анотації;
  • принципи ООП;
  • знання алгоритмів і структур даних;
  • основи SQL;
  • основи HTML/CSS/JS;
  • основи Web: HTTP запити, Cookies, Session;
  • основи Git;
  • рівень англійської Intermediate або вище.

Front-end:

  • знання основ HTML/CSS;
  • вміння користуватися одним із графічних редакторів;
  • досвід верстки від 3 місяців;
  • досвід Responsive або Adaptive верстки;
  • розуміння основ програмування, структур даних та алгоритмів;
  • базові знання Javascript;
  • основи Git;
  • рівень англійської Intermediate або вище.

Test Automation:

  • теоретична база QA;
  • основи Java 8;
  • принципи ООП;
  • основи SQL;
  • основи HTML/CSS;
  • основи Web: HTTP запити, Cookies, Session;
  • основи Git;
  • рівень англійської Intermediate або вище.

Як потрапити:подати заявку на сайтідо 13 вересня 2019 року, пройти тестування (англійською), пройти співбесіду (українською).

Умови:тривалість курсу: 7 місяців. Останні півтора місяця — робота в командах над фінальними проектами. Після успішного завершення — сертифікат SPD-University.

Деталі:пишіть на пошту info@spd-university.comабо на сайті.

Yalantis

Напрям:курс iOS.
Місто:Дніпро.
Дедлайн подачі заявок: 3 вересня.

Вимоги до кандидатів:

  • знання і розуміння принципів ООП, SOLID;
  • знання синтаксису й основних конструкцій Swift;
  • уміння створювати простий UI з використанням Auto Layout;
  • уміння відправляти запити в мережу (URLSession, Alamofire тощо);
  • уміння працювати з Git;
  • наявність свого обладнання для розробки під iOS (особистий Mac або інша техніка з hackintosh);
  • рівень англійської мови на рівні Intermediate та вище.

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

Умови:тривалiсть занять: з 16 вересня до 31 жовтня. Розклад: понеділок і четвер, з 19:00 до 21:00. Домашні завдання для закріплення вивченого матеріалу. У результаті успішного проходження — можливість працевлаштування в Yalantis.

Деталі:на DOUабо пишіть на пошту dasha.kornienko@yalantis.net, у skype: dashka_krn, Facebook.

Школа програмування Ш++

Напрям:курс Java.
Місто:Кропивницький.
Дедлайн подачі заявок: 7 вересня.

Вимоги до кандидатів:вміти пробігтись по масиву циклом, за допомогою однієї з мов: С++, JavaScript, Java.

Як потрапити:зареєструватися, пройти вступне випробуванняна одній із мов: Java, C++, Javascript.

Умови: Peer-to-peer — це коли ви навчаєтесь без менторів, груп, з офлайн-складовою. Тривалість курсу складає 4 місяці і дає можливість обрати напрямки для більш поглибленого навчання (наприклад, web/mobile development). Заняття проходять двічі на тиждень в м. Кропивницький.

Деталі:пишіть на пошту info@programming.kr.ua, телефонуйте 050 20 111 80 або на сайті.

AMC Bridge

Напрям:стажування C++, C#, web services.
Місто:Дніпро, Львів, Суми, Хмельницький, Чернівці.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:студенти 3-6-го курсів технічних спеціальностей вищих навчальних закладів. Термін стажування повинен збігатися з навчальним планом ВНЗ.

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

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

Деталі:на сайтіабо пишіть на пошту contacts@amcbridge.com.

BAKOTECH

Напрям:кібербезпека.
Місто:Київ.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:

  • студенти та випускники технічних спеціальностей;
  • знання серверної частини Windows (MS AD, DNS, DHCP);
  • знання архітектури мережі (модель OSI, VPN, VLAN, та ін.);
  • навички використання середовища віртуалізації: VMware та / або Hyper-V;
  • розмовний рівень англійської мови.

Як потрапити:надіслати резюме з поміткою «Стажування з DOU» на пошту Tatiana.Kiselevich@bakotech.com, пройти співбесіду в офісі, виконати тестове завдання.

Умови:програма розрахована на 3 місяці з можливістю подальшого працевлаштування. Стажування проходить в офісі, 5 днів на тиждень, з 9 до 18 години. Програма включає практичні завдання під керівництвом спеціалістів відділу. Стажування передбачає помісячну оплату.

Деталі:Tatiana.Kiselevich@bakotech.com, 063-117-84-78.

CHI Software

Напрям: Sales Management.
Місто:Харків.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:

  • англійська Upper-Intermediate;
  • нестандартний підхід до вирішення завдань, аналітичні здібності та навички вирішення проблем.

Як потрапити:подати заявку на careers@chisw.com.

Умови:перший місяць інтернатури — 2 заняття на тиждень тривалістю 2 години. Далі — 3 місяці оплачуваного стажування у компанії, реальні проекти, повний робочий день. Менторство досвідчених sales managers. По закіненню — можливість працевлаштування.

Деталі:на сайті.

Cleveroad

Напрям і місто:стажування у Харкові — JavaScript та Дніпрі — Front-end React/Angular.
Дедлайн подачі заявок: 15 вересня.

Вимоги до кандидатів:

JavaScript

  • базові знання JavaScript;
  • реляційні бази даних (MySQL або PostgreSQL), розуміння нормалізації баз даних.;
  • знання та розуміння принципів ООП;
  • базові знання алгоритмів;
  • знання HTML5 та CSS3.

Front-end React/Angular

  • розуміння основних принципів ООП;
  • знання HTML5, CSS3;
  • розуміння DOM моделі;
  • розуміння Ajax.

Як потрапити:надіслати резюме на пошту alena.yarochevska.cr@gmail.com, виконати технічний тест, пройти співбесіду.

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

Деталі:пишіть на пошту alena.yarochevska.cr@gmail.com.

Clockwise Software

Напрям і місто:стажування у Дніпрі — JavaScript, PM.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:

JavaScript

  • профільна освіта або курси за напрямком;
  • знання алгоритмів;
  • англійська мова — intermediate.

Project manager

  • англійська мова — upper intermediate;
  • теоретична база.

Як потрапити:надіслати резюме на пошту hr@clockwise.softwareабо на сайті.

Умови:індивідуальна програма, супровід ментора.

Деталі:пишіть на пошту hr@clockwise.softwareабо на сайті.

DataArt

Напрям і місто:стажування у Львові: .NET, QA, Києві: .NET, QA, Java, Front end та Харкові: Python, .NET.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів у Львові:

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

Вимоги до кандидатів у Києві:

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

Вимоги до кандидатів у Харкові:

  • базові знання за обраним напрямком;
  • володіння розмовною англійською.

Як потрапити:
Львів: надіслати резюме на пошту careers.lviv@dataart.com.
Київ: надіслати резюме на пошту hr-kyiv@dataart.comз приміткою стажер Київ.
Харків: надіслати резюме на пошту careers.kharkiv@dataart.com

Умови:
У Львовішукають по одному практиканту з кожного напряму. Тривалість програми — 3 місяці. 8-годиннийробочий день. При успішному проходжені практики пропонують працевлаштування. Є оплата.
У Києві — для студентів, що продовжують навчання у вузі. Підтримка ментора на проектних задачах. Навчання індивідуальне. Тривалість — 6 місяців. Графік для студентів гнучкий. При успішному проходжені практики пропонують працевлаштування. Є оплата.
У Харковіпрограма триватиме близько 3 місяців. Є оплата. На весь період за практикантом закріплюють ментора. Можливе подальше працевлаштування в компанії.

Деталі:
Львів: пишіть на пошту careers.lviv@dataart.com.
Київ та Харків: на сайті.

GeeksForLess

Напрям:стажування .NET, C#.
Місто:Миколаїв.
Дедлайн подачі заявок:на постійній основі.

Вимоги до кандидатів:базові знання С#.

Як потрапити:надіслати резюме на Mykolayiv@geeksforless.com, виконати тестове завдання.

Умови:оплата — $ 200 на місяць.

Деталі:на сайті, або пишіть за адресою Mykolayiv@geeksforless.com.

groupBWT

Напрям:стажування PHP, Python.
Місто:Запоріжжя.
Дедлайн подачі заявок:стажування відкрите на постійній основі.

Вимоги до кандидатів:

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

Як потрапити:надіслати резюме на сайті, пройти телефонне інтерв’ю, виконати тестове завдання, пройти співбесіду в офісі.

Умови:програма розрахована на 3 місяці с можливістю подальшого працевлаштування. Стажування проходить в офісі 40 годин на тиждень. Можливий індивідуальний графік для поєднання з навчанням у виші. У разі успішного виконання практичних завдань кандидат отримуватиме стипендію. Це не навчання, а стажування, тому теорію, якої не вистачатиме, необхідно буде освоювати самостійно. На стажуванні основний акцент робиться на PHP, Laravel, Python, методи збору і обробки даних (парсери). Крім того, кандидат навчиться працювати в команді, користуватися інструментами розробки та системами ведення проектів, ефективно використовувати свій робочий час.

Деталі:на сайті.

IdeaSoft.io

Напрям:стажування Sales.
Місто:Харків.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:

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

Як потрапити:подати заявку на пошту julia.s@ideasoft.io.

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

Деталі: Skype: julia.syzonenko.

Leobit

Напрям:стажування .NET, Ruby, Automation QA, React.
Місто:Львів.
Дедлайн подачі заявок:немає.

Вимоги до кандидатів:

  • студенти 4-5-го курсів або випускники за 2 останні роки (технічні спеціальності вищих навчальних закладів);
  • теоретичні знання відповідно до обраного напрямку;
  • хороші аналітичні навички;
  • рівень англійської — Intermediate+.

Як потрапити:надіслати резюме на cv@leobit.com, виконати тестове завдання, пройти співбесіду по телефону та технічну в офісі.

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

Деталі:на сайтіабо пишіть на пошту cv@leobit.com.

Logicify

Напрям:стажування Angular, Python.
Місто:Херсон.
Дедлайн подачі заявок:реєстрація відкрита на постійній основі.

Вимоги до кандидатів:

Як потрапити:ознайомитися с вимогами, обрати бажаний напрям, заповнити форму на сторінці відповідного напряму стажування. Далі — тестове завдання та співбесіда.

Умови:програма стажування проходить в офісі Logicify та розрахована на 2 місяці, 40 годин на тиждень. Стажерам передбачена невелика стипендія, також можливий індивідуальний графік. Протягом двох місяців у вас буде ментор, який буде ставити задачі, підказувати а також надавати фідбек. З огляду на те, що ми не є учбовим закладом, ми, на жаль, не можемо і не будемо вчити теорії так, як це відбувається у університеті або на курсах. Ми очікуємо, що в вас вже є фундаментальні знання, а тих, що не вистачає, ви будете набувати самостійно. Ми, в свою чергу, допоможемо учбовими матеріалами та консультаціями ментора.

Деталі:на сайті.

Quality Assurance Group

Напрям:стажування / виробнича практика QA.
Місто:Львів.
Дедлайн подачі заявок:немає.
Вимоги до кандидатів:курс можуть проходити усі охочі.

Як потрапити:подати заявку, заповнивши анкету, або телефонуйте (099) 376 65 05; (098) 903 64 45.

Умови:стажування повністю присвячене практиці. Студенти працюють з реальними проектами самостійно у групах під керівництвом координатора і таким чином отримують досвід роботи та напрацювання у якості прикладу своїх робіт. Робота проходить з баг-трекінговою системою Jira; Zephyr test management tool, Test Rail, Jmeter ect. Навчання проводять спеціалісти компанії QArtrock.

Деталі:на сайті.

Qubstudio

Напрям:стажування UX/UI design.
Місто:Львів.
Дедлайн подачі заявок: 13 вересня.
Вимоги до кандидатів:навички графічного дизайну, вміння користуватись дизайнерськими інструментами (Figma/Sketch, Invision, Principle).

Як потрапити:подати заявку на сайті, виконати тестове завдання та пройти співбесіду.

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

Деталі:на сайті.

Serpstat

Напям:стажування Support.

Вимоги до кандидатів:

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

Як потрапити:заповнити анкету на сайті. Виконати тестове, пройти співбесіду.

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

Деталі:на сайті.

Sigma Software University

Тип:стажування.

Вимоги до кандидатів та дедлайни:

Як потрапити:заповнити реєстраційну форму на сайті (у відповідному розділі) та додати резюме.

Умови:тривалість стажування від 3 до 6 місяців залежно від напряму; повний робочий день.

Деталі:на сайті.

SysGears

Тип:стажування Java, JS — до набору групи.

Вимоги до кандидатів:

  • знання алгоритмів і структур даних, ООП і БД;
  • письмова англйська мова рівня Intermediate;
  • досвід самостійної розробки простих застосунків на будь-якій з мов.

Як потрапити:надіслати резюме jobs@sysgears.com, пройти тестування та співбесіду.

Умови:самостійна робота за підтримки куратора. Тривалість — 6 тижнів. Графік з 9.00 до 18.00, з понеділка по п’ятницю. Індивідуальне і обладнане робоче місце. При результативному завершенні програми — стипендія. Після успішного закінчення стажування — можливе працевлаштування.

Деталі:на сайті.

TeamDev

Напрям:стажування Java.
Місто:Харків.

Вимоги до кандидатів:

  • англійська рівня Intermediate;
  • досвід програмування, крім курсових/дипломів;
  • профільна технiчна незакінчена/закінчена вища освіта;
  • знання основ математики;
  • розуміння основних принципів ООП;
  • базові знання Java.

Як потрапити:заповнити реєстраційну форму, надіслати резюме за адресою work@teamdev.com. Надіслати приклад вашого коду — це може бути будь-який код на будь-якій мові програмування: покажіть код, яким ви пишаєтеся! Пройти співбесіду з фахівцями компанії.

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

Деталі:на сайтіабо пишіть на пошту work@teamdev.com.

Ubisoft

Напрям:стажування Online Programming — до 16 вересня.
Місто:Київ.

Вимоги до кандидатів:

  • пристрасть до відеоігор (наявність власних ігрових проектів);
  • хороший рівень знання з програмування (C/C++);
  • випускник ВНЗ або студент останнього курсу;
  • навички алгоритміки, аналітичне мислення та вміння структурувати данні;
  • просунутий рівень англійської мови;
  • вміння ефективно комунікувати та працювати в команді.

Як потрапити:надіслати резюме за адресою hr_kiev@ubisoft.com.

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

Деталі:на сайтіабо пишіть на пошту hr_kiev@ubisoft.com.

VAIMO

Напрям:стажування PHP + Magento.
Місто:Харків.
Дедлайн подачі заявок: 20 вересня.

Вимоги до кандидатів:

  • рівень англійської — Intermediate+;
  • мінімальний досід програмування на PHP;
  • базові знання з HTML, CSS, OOP.

Як потрапити:подати заявку на сайті, пройти технічне тестування, технічну співбесіду та співбесіду з HR.

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

Деталі:на сайті.

WEB4PRO

Напрям:стажування PHP (Magento 2).
Місто:Харків.
Дедлайн подачі заявок:стажування відкрите на постійній основі.

Вимоги до кандидатів:

  • досвід роботи з PHP та MySQL;
  • розуміння OOP;
  • базові знання JS.

Як потрапити:відправити резюме на hr@corp.web4pro.com.ua, пройти тестування та співбесіду в офісі.

Умови:тривалість — 3 місяці. Стажування в офісі 8 годин на день 5 днів на тиждень. Є стипендія та ментор. Можливість працевлаштування в компанії.

Деталі:на сайті.

Webinse

Напрям:стажування Magento.
Місто:Дніпро.
Дедлайн подачі заявок:16 вересня.

Вимоги до кандидатів:

  • володіння HTML, CSS;
  • практичні навики роботи з PHP, Javascript, MySQL;
  • базові знання OOP и MVC паттерна.

Як потрапити:заповнити форму.

Умови:менторство.

Деталі:на сайті.

White Label Agency

Напрям:стажування WordPress.
Місто:Полтава.
Дедлайн подачі заявок:стажування відкрите на постійній основі.

Вимоги до кандидатів:

  • студенти останнього курсу та випускники;
  • базове розуміння CMS WordPress, PHP;
  • знання HTML & CSS;
  • досвід програмування.

Як потрапити:заповнити форму на сайтіабо відправити резюме на hr@thewhitelabelagency.com, пройти співбесіду та виконати тестове завдання.

Умови:викладачі інтернатури — Tech leads та Senior Developers компанії. Тривалість програми — від 1 до 2 місяців залежно від рівня кандидата. 5 днів на тиждень, 8 годин на день. Стажування оплачується щомісячно. Програма включає практичні завдання, розробку тесових проектів під керівництвом кураторів та лекції. За умови успішного проходження курсу є можливість працевлаштуватися на позицію Junior.

Деталі:на сайті.

WiserBrand

Напрям:стажування Customer Support.
Місто:Харків.
Дедлайн подачі заявок:стажування відкрите на постійній основі.

Вимоги до кандидатів:володіння англійською на рівні Upper та вище.

Як потрапити:заповнити форму на сайті.

Умови:тривалість стажування 3 місяці, що оплачуються компанією. Є можливість подальшого працевлаштування в компанії.

Деталі:на сайтіабо пишіть на пошту alexa.a@wiserbrand.com, @Aleksa_Andr — telegram.

Zazmic

Напрям:стажування Node.js.
Місто:онлайн.
Дедлайн подачі заявок: 2 вересня.

Вимоги до кандидатів:

  • знання основ JavaScript;
  • базові знання Databases;
  • репозиторій с кодом на GitHub;
  • рівень володіння англійською Intermediate+.

Як потрапити:заповнити форму на сайті.

Умови:навчальна стипендія, робота з командою з використанням Agile-методології, зокрема Scrum, менторство.

Деталі:на сайтіабо пишіть на пошту dariya.t@zazmic.com.

Agilites

Напрям:робота Manual QA.
Місто:Харків.

Вимоги до кандидатів:

  • вища освіта та/або курси QA;
  • гарне знання теорії тестування програмного забезпечення;
  • розуміння SDLC;
  • базове знання SQL, SOAP та XML.

Як потрапити:подати резюме на сайті.

Умови:випробний термін — 2 місяці (з виплатою зарплатні з першого дня), після успішного проходження — подальше працевлаштування. Великий ентерпрайз-проект, в команді 20+ QA інженерів. ЗП $250–450.

Деталі:на сайтіабо пишіть на пошту hr@agilites.com.

Alcor

Напрям:робота IT Researcher.
Місто:Київ, Одеса.

Вимоги до кандидатів:

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

Як потрапити:подати резюме на сайті для Києва, для Одеси.

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

Деталі:пишіть на пошту TLukianets@alcor-bpo.com, 0933591359 (Viber, Telegram).

Altigee

Напрям:робота Lead Generation Manager.
Місто:Львів.

Вимоги до кандидатів:

  • вільне володіння англійською мовою (рівень advanced);
  • досвід роботи з Google Drive, LinkedIn, CRM (HubSpot або Pipedrive), Linked Helper, FindThatLead, snov.ioсервісами.

Як потрапити:подати резюме на сайті, пройти співбесіду.

Умови: .

Деталі:на сайтіабо пишіть на пошту hi@altigee.com.

Bini Bambini

Напрям:робота Data Analyst, .NET, Animator 2D.
Місто:Харків.

Вимоги до кандидатів:

Data Analyst:

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

.NET:

  • знання ООП;
  • розуміння C #, .Net;
  • знання основ програмування;
  • стаж від 0,5 року.

2D Animator:

  • розуміння, сучасних комп’ютерних ігор і бажання їх створювати;
  • навички персонажной анімації, знання теорії та принципів класичної анімації;
  • навички анімації інтерфейсів, створення ефектів і інших ігрових анімацій;
  • розуміння теорії і принципів класичної анімації;
  • навички роботи в техніках «2D-перекладки» (Flash, Adobe Effect)
  • уміння швидко створювати якісну анімацію;
  • уміння грамотно використовувати референс.

Як потрапити:подати резюме Data Analyst, Animator 2D,.NET .

Умови:випробувальний термін — 3 місяці.

Деталі:на сайтіабо пишіть на пошту anzhela.ziarmand@binibambini.com.

DevelopEx

Напрям:робота QA.
Місто:Київ.

Вимоги до кандидатів:

  • півроку досвіду роботи QA-інженером;
  • вища освіта;
  • знання англійської мови не нижче intermediate.

Як потрапити:подати резюме на сайті.

Умови:оплачувана відпустка, лікарняні, уроки англійської та йога.

Деталі:на сайтіабо пишіть на пошту hr@developex.com.

Expercast

Напрям:робота QA.
Місто:віддалено.

Вимоги до кандидатів:

  • розуміння основних технік та методів тестування, досвід ручного тестування ;
  • знання англійської мови на рівні Upper-intermediate.

Як потрапити:подати резюме на сайті.

Умови:парт-тайм на постійній основі.

Деталі:на сайтіабо пишіть на пошту hiring@expercast.com.

Genesis

Напрям:робота Product Analyst.
Місто:Київ.

Вимоги до кандидатів:

  • знання SQL та Excel;
  • розвинені аналітичні навички;
  • зрозуміння основ маркетингу: сегментація, CPA / CPC / CPM / EPC / EPV, A/B тестування.

Як потрапити:подати резюме на сайті.

Умови:пройти співбесіду з менеджером проекту та виконати тестове завдання.

Деталі:на сайтіабо telegram: @mariiabrynza

Intersog

Напрям і місто:робота Research & Development engineer — Одеса, Python — Київ.

Вимоги до кандидатів:

Research & Development:

  • базовий досвід з Python, Javascript або Java;
  • базове розуміння веб технологій: HTTP, HTML/CSS/JS;
  • базовий досвід з Fiddler;
  • як мінімум Intermediate розмовна англійська.

Python:

  • базовий досвід з Django та Django Rest Framework;
  • базове розуміння SQL та реляційних БД;
  • досвід з Git;
  • досвід з asyncio;
  • як мінімум Intermediate розмовна англійська.

Як потрапити:надіслати резюме на Research & Developmentабо Python, виконати тестове завдання.

Умови:повний робочий день.
Деталі:на сайтіабо пишіть на пошту hr@intersog.com.

Jooble

Напрям і місто:робота Junior SysAdmin/Helpdesk — Київ.

Вимоги до кандидатів:

  • досвід встановлення та налаштування пакету офісних програм;
  • досвід налагодження мереж, налаштування маршрутизації, підмереж, розуміння принципів роботи TCP/IP, протоколів маршрутизації;
  • діагностика апаратних та програмних проблем;
  • знання клієнтських ОС Windows 10.

Як потрапити:надіслати резюме на сайті.

Умови:оплачувана робота на постійній основі з можливістю кар’єрного зростання.

Деталі:на сайтіабо пишіть на пошту od@jooble.com.

LoopMe

Напрям:робота JavaScript.
Місто:Дніпро.

Вимоги до кандидатів:

  • практичний досвід та / або курси на JavaScript (ES6);
  • упевнені навички використання HTML5 / CSS3;
  • практичний досвід у адаптивному веб-дизайні;
  • зацікавленість в анімації та інтерактивному дизайні.

Як потрапити:подати резюме на сайті.

Умови:пройти HR-співбесіду, виконати тестове завдання та пройти технічну співбесіду.

Деталі:на сайтіабо пишіть на пошту yuliia.matsenko@loopme.comчи olha.mohunova@loopme.com.

MaybeWorks

Напрям:робота JavaScript.
Місто:Харків.

Вимоги до кандидатів:

  • розуміння та застосування принципів ООП у розробці;
  • знання базових патернів і архітектури;
  • досвід використання одного з фреймворків front-end: angular/ react/ vue;
  • вміння написати back-end на node.js;
  • робота з БД на рівні SQL-запитів.

Як потрапити:подати резюме на сайтіз позначкою «Робота DOU», пройти онлайн-інтерв’ю (до 1 жовтня).

Умови:виконати тестове завдання. У разі успішного результату — працевлаштування (оплата з першого дня).

Деталі:на сайтіабо пишіть на пошту hr@maybeworks.com.

MobiDev

Напрям:робота QA, Project management.
Місто:Харків, Чернівці.

Вимоги до кандидатів:

QA (Чернівці, Харків):

  • впевнені знання теорії тестування;
  • розуміння процесу розробки програмного забезпечення;
  • вміння аналізувати та структурувати інформацію;
  • рівень англійської (письмова та усна) — Intermediate.

Project management (Харків):

  • достатні теоретичні знання у РМ-галузі;
  • рівень англійської (письмова та усна) — Upper-Intermediate;
  • розуміння ІТ-індустрії та процесу mobile/web-розробки.

Як потрапити:подати резюме QA (Чернцівці), QA (Харків), PM (Харків), пройти співбесіду.

Умови:повноцінна робота в компанії.

Деталі:на сайтіабо пишіть на пошту chernivtsi@mobidev.biz (Чернівці), jobs@mobidev.biz (Харків).

NIX Solutions Ltd

Напрям:робота.
Місто:Харків.

Вимоги до кандидатів:

Як потрапити:подати резюме на сайті, пройти співбесіду.

Умови:повна зайнятість.

Деталі:на сайті.

PioGroup Software

Напрям:робота PHP.
Місто:Харків.

Вимоги до кандидатів:

  • знання та досвід роботи з PHP 5/7, MySQL;
  • знання одного з фреймфорків Symfony, Laravel;
  • знання англійської мови на рівні не нижче Intermediate.

Як потрапити:надіслати резюме на сайті.

Умови:Повний робочий день. Під час адаптації підтримка та супровід ментора.

Деталі:на сайтіабо пишіть на oz@piogroup.net.

SMART business

Напрям:робота CRM, AX.
Місто:Київ.

Вимоги до кандидатів:

CRM:

  • вища технічна освіта (студент 3–6курсів або випускник);
  • знання C # і .NET;
  • досвід роботи з JavaScript, HTML5, CSS3 та веб-розробкою;
  • розуміння структури та операцій реляційних баз даних (MySQL, MS SQL);
  • англійська — середній рівень або вище.

AX:

  • вища технічна освіта (студент 3–6курсів або випускник);
  • навички розробки програмного забезпечення (досвід роботи з X ++, C/C ++/C#);
  • розуміння об’єктно-орієнтованого програмування;
  • розуміння структури та операцій реляційних баз даних (MySQL, MS SQL);
  • англійська — середній рівень або вище.

Як потрапити:надіслати резюме на сайті для CRM, AX.

Умови:CRM:навчальна програма для студентів (SMART академія), коучинг, сертифікація MS, програма Gamification. AX:навчальна програма для студентів (SMART academy), сертифікація, програма Gamification.

Деталі:на сайті: CRM, AX.

Solid Software

Напрям:робота Flutter.
Місто:Харків.

Вимоги до кандидатів:

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

Як потрапити:надіслати резюме на сайті, виконати тестове завдання.

Умови:робоче місце з MacBook, оплачувана відпустка та лікарняні.

Деталі:на сайті.

TechMagic

Напрям:робота iOS Trainee.
Місто:Львів.

Вимоги до кандидатів:

  • англійська рівня intermediate/upper-intermediate;
  • бакалавр або спеціаліст/магістр в області ІТ (або суміжних спеціальностях);
  • мінімальний досвід з Swift, Xcode, CocoaPods, GIT;
  • розуміння принципів OOП.

Як потрапити:подати заявку на сайті, пройти тестування в офісі компанії (технічна частина та тест на визначення рівня англійської мови), пройти співбесіду із IOS-розробником та рекрутером.

Умови:конкурсний відбір, офер на повний робочий день.

Деталі:на сайті.

Ubisoft

Напрям:робота QC, Game Tester.
Місто:Київ.

Вимоги до кандидатів:

QC:

  • базові знання ігрового тестування / процедури звітності про помилки / життєвий цикл помилки;
  • ігровий досвід, знання ігрової термінології;
  • базові знання комп’ютерних і консольних ігор;
  • знання Microsoft Office (Word, Excel, Outlook);
  • середній рівень англійської, як письмової, так і усної;
  • уважність до деталей;
  • здатність працювати в команді.

Game Tester:

  • пристрасть до відеоігор (широкий ігровий досвід та хороші знання різних ігрових жанрів);
  • початковий або середній рівень англійської, як письмової, так і усної;
  • базові знання ігрового тестування;
  • базові знання комп’ютерних і консольних ігор;
  • знання Microsoft Office (Word, Excel, Outlook);
  • уважність до деталей;
  • вміння працювати в команді.

Як потрапити:надіслати резюме на сайті QC, Game Tester.

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

Деталі:на сайті, або пишіть на пошту hr_kiev@ubisoft.com.

YouScan

Напрям:робота Tech support, IT Support/System Administration.
Місто:Київ.

Вимоги до кандидатів:

Tech support:

  • основи або досвід із HTML/CSS, Chrome DevTools, fiddler/postman/curl;
  • рівень англійської достатній для робочої переписки.

IT Support/System Administration:

  • технічна освіта;
  • адміністрування Windows, Linux, Mac OS;
  • Active Directory, G Suite, 1C;
  • рівень англійської intermediate+.

Як потрапити:надіслати резюме Tech support, IT Support/System Administration.

Умови:
Tech support: робота на повний день, оформлення. IT Support/System Administration: повний робочий день, графік може бути гнучким, частину часу можна працювати віддалено.

Деталі:
пишіть на пошту hr@youscan.io, або на сайтах Tech support, IT Support/System Administration.


Роль Product Manager на разных этапах развития проекта

$
0
0

Статья написана в соавторстве с Мэри Ротарь, Co-Founder IAMPM.

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

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

Если в стартапе все нужно делать максимально быстро, пусть даже «из добра и палок», лишь бы работало, то в период роста продукта от менеджера ожидают качества, достижения KPI и customer success. Так что буквально за два года на проекте Product Manager может сменить 3 разные роли, и у каждой есть свои плюсы и минусы. Важно понимать, что все проекты уникальны, и нельзя четко сказать, на каком количестве клиентов, размере команды и величине прибыли для Product Manager заканчивается одна стадия роста и начинается другая. Но лучше давайте обо всем по порядку.

Product Manager в стартапе на этапе поиска Product Market Fit

В стартапе весело, такой себе хакатон каждый день.

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

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

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

В процессе игры «Создать и продать продукт» главная задача, которую решает Product Manager, — это поиск так называемого Product Market Fit, ситуации, когда продукт удовлетворяет потребности целевой аудитории и она готова за этот продукт платить.

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

С точки зрения бизнеса Product Manager в стартапе — это такой jack of all trades. Он занимается всем подряд:

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

Одна из самых важных задач продакта в стартапе — именно питчинг. Это трехминутная презентация продукта инвесторам, которая отвечает на 5 вопросов:

  1. Что представляет из себя продукт?
  2. Какую проблему он решает?
  3. Для каких пользователей он предназначен?
  4. Кто наши конкуренты?
  5. Как мы планируем на всем этом зарабатывать?

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

Product Manager в стартапе постоянно находится в состоянии неопределенности: он часто не знает, какая из идей выстрелит, поэтому очень много экспериментирует. Иногда релизы делаются чуть ли не раз в день. Чтобы нащупать тот самый Product Market Fit и начать расти, приходится участвовать в бесконечной гонке изменений.

В этом процессе продакт часто сталкивается с такой штукой, как пивот (pivot). Пивот — это изменение стратегии развития продукта, иногда это поворот на 180 градусов, который сопровождается сменой целевой аудитории, финансовой модели или даже сферы деятельности. Хороший пример — компания Odeo (сейчас Twitter), которая изначально была платформой для подкастов, но, когда в 2005-м Apple анонсировала iTunes, владельцы Odeo поняли, что не смогут конкурировать с гигантом. Нужно было перестраиваться — так родилась идея социальной сети, сформированной вокруг «статусов» пользователей.

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

Момент нахождения Product Market Fit — чуть ли не конечная точка в работе Product Manager на стадии стартапа. Можно сказать, что на этом этапе стартап более-менее оправдал себя и в состоянии привлечь деньги инвесторов (или использовать прибыль) для масштабирования той самой модели, которую нашли и построили.

Product Manager в запустившемся продукте

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

Product Manager в стартапе, «который смог»

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

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

Product Manager начинает фокусироваться на:

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

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

Команда на этом этапе тоже расширяется: добавляются QA, UI/UX-дизайнер и маркетолог, если повезет, нанимают бизнес-аналитика.

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

Product Manager в «карманном» стартапе

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

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

Product Manager в «карманном» стартапе больше похож на менеджера в запустившемся продукте, ведь ему:

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

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

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

Product Manager в успешно развивающемся продукте

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

Product Manager в развивающемся продукте чаще всего занимается:

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

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

Для B2B: обеспечить масштабируемость (scalability) продукта

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

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

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

Для B2C: рост и улучшение метрик продукта, увеличение прибыли

Ключевой метрикой на этом этапе становится LTV — суммарная прибыль, которую получает компания от одного пользователя за все время его взаимодействия с продуктом. Именно LTV мотивирует продактов менять модель монетизации на подписку вместо разовой покупки, так как в долгосрочной перспективе подписка может оказаться гораздо выгоднее. Даже BMW и Mercedes-Benzпланируют продавать свои автомобили по этой схеме, задумайтесь!

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

На этом этапе развития компании Product Manager сталкивается с новыми реалиями:

  1. 90% его идей о том, как улучшить метрики, не работают, и продакт должен бороться с постоянной фрустрацией, ибо «что бы ты ни делал, не растет кокос».
  2. У PM появляется большое количество скучной работы, связанной с детализацией спецификаций, документацией и релиз-менеджментом.
  3. Все еще возникают вопросы с compliance: в зависимости от доменной области продукта продакт может столкнуться с security, accessibility и любыми другими вариантами compliance.

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

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

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

Однако не деньгами едиными. По мере роста компании менеджера продукта начинают волновать вопросы культуры и миссии бренда: что мы создаем, каких людей нанимаем в команду, как выстраиваем процессы внутри компании, чтобы повысить качество и производительность. Тем более что команда сильно расширяется: как правило, под одну фичу выделяется кросс-функциональная команда из Product Manager, Marketing Specialist, Tech Lead, Data Scientist, Development Team.

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

В нашей компании, например, Project Manager нет, за процесс внедрения продукта у клиента отвечают VP of Engineering, VP of Client Success и Product Manager. Для нас вопросы культуры очень важны, потому что успевать контролировать и менеджерить всех специалистов даже втроем невозможно. А это значит, что поведение команды очень сильно влияет на качество, сроки и бюджет. Если Product Manager хочет получить на выходе классный продукт, придется найти время на все эти вопросы.

Какими навыками должен обладать хороший Product Manager на любой стадии развития проекта

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

Product Manager — лидер команды, и он должен во что бы то ни стало реализовать озвученное ранее и сформулированное в roadmap видение продукта. Для этого нужно как минимум ясно и понятно писать спеки и быть на «ты» с командой разработки.

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

А еще хороший Product Manager — отличный коммуникатор:

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

Ну и самое главное: Product Manager — евангелист продукта! Он верит в то, что делает, потому что иначе добиться успеха невозможно.

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

DOU Ревізор в Materialise: «Простір, де кожен сантиметр має призначення»

$
0
0

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

Materialise заснували 1990 року в Бельгії, в Україні компанія з’явилася вже 2000 року. Наразі вона має 26 офісів у 20 країнах світу на всіх континентах, крім Африки та Антарктиди.

Глобально з компанією співпрацює понад 2000 осіб. У Києві їх 400, з них 270 — технічні спеціалісти.

В околицях і поблизу

До офісу за адресою вул. Раїси Окіпної, 8А переїхали ще дванадцять років тому. Сама локація наразі потребує заміни вивісок: на першому поверсі будівлі донедавна знаходився банк, який залишив власний банер.

Офіс знаходиться в 9 хвилинах пішки від метро Лівобережна та в 3 хвилинах — від зупинки Раїси Окіпної.




Поблизу — сила-силенна закладів харчування різних цінових категорій:

  • У 4 хвилинах пішки від офісу знаходиться ірландський паб з комплексними обідами To Dublin. Середній чек ~100 грн.
  • У межах 5-7хвилин у бік метро є також «Пузата хата», «Євразія» і азійський ресторан Woki Toki. Середній чек у закладах складає приблизно 80-200 грн.
  • У сусідній будівлі розташовано ресторан китайської кухні Kitaika з середнім чеком у 100-150 грн.
  • Каву та солодощі можна придбати у кав’ярні «Буна», що також знаходиться неподалік.
  • У межах 10-15хвилин прогулянки Русанівською набережною є Tarantino, Soul Café (обід — 80-200 грн),іl Molino, Pesto, «Моменти», «Жовток», Spezzo та інші заклади.
  • Купити продукти можна в «АТБ», що навпроти офісу, або у «Сільпо» біля метро Лівобережна.

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

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

Офісний побут

Materialise Community займає весь простір шестиповерхової будівлі, плюс напівпідвальний «нульовий» поверх. Загальна площа всіх приміщень складає 3500 м² (у середньому 500 м²на один поверх).

Зазвичай спеціалісти присвячують проектам 8 годин на день. Бажано — з 10 до 19, втім, цей час можна рухати, головне — бути присутніми на основних зустрічах. Вони зазвичай відбуваються об 11-12 годині.

Щодо можливості віддаленої співпраці, то чітких усталених правил щодо цього Materialise поки не має. Як повідомляють представники компанії, наразі вони працюють над створенням такої політики. У компанії є спеціалісти, що віддалено працюють на постійній основі або 30-50%часу. З боку технічної реалізації все просто: можна під’єднатися з наданого ноутбука через VPN або за допомогою віддаленого доступу працювати з власного комп’ютера.

В офісі є книжкова шафа, до якої можна замовити будь-яку літературу для професійного саморозвитку. Серед замовлень — «Creativity» Едвіна Кетмелла та «Business Model Generation: A Handbook for Visionaries, Game Changers, and Challengers» Александра Остервальдера.

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




Повноцінна кухня з холодильниками, посудомийною машиною, мікрохвильовками та іншим приладдям знаходиться на нульовому поверсі. Також там розміщено багато обідніх столиків, розрахованих на 80-100 осіб.Крім холодильників, з яких можна придбати готову їжу та розрахуватися за неї карткою, на кухні є імпровізована снек-лавка. Це стелаж, за який відповідають самі члени Materialise Community, регулярно наповнюючи його снеками або чимось смачненьким від своїх друзів/знайомих.





Оскільки приміщення нульового поверху напівпідвальне, там немає нічого, крім кухні, п’яти кімнат для перемовин, лаунж-зони та простору для проведення зовнішніх і внутрішніх мітапів. (Див. розділ «Відпочинок та натхнення»).

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

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




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

Щодо зон для паління, то вони знаходяться на вулиці, подалі від кондиціонерів та вентиляції.

Робочий простір

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

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





Офіс вдало зоновано: тут є маленькі (на п’ять-шість спеціалістів) кабінети та великі опенспейси (до 30), поєднані коридором. Оскільки офіс розширювався поступово, кожен простір має власні особливості ремонту. Що стосується доступу до простору, то електронну перепустку необхідно мати при собі і щоб зайти, і щоб вийти з поверху. Пересування переговорними кімнатами та кабінетами не обмежується, виняток складає лише офіс-спейс для Deployment Team, до кімнати якої, відповідно до вимог SOX, мають доступ лише члени цієї команди.






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

Раз на два-три місяці в Materialise проводять Newcomers’ Day, коли новачків знайомлять з традиціями, культурою, внутрішніми особливостями структури компанії, дарують брендовані блокноти. Department Manager-и кожного напрямку розповідають про те, чим займаються спеціалісти в їхньому домені. Також в програмі дня — ланч новачків та керівників департаментів і вечірній фуршет-нетворкінг.




Кожен спеціаліст, який приходить працювати до компанії, забезпечується усім необхідним: столом, тумбою, кріслом та комп’ютером Dell з периферією. Аналітики та менеджери проектів отримують ноутбуки, решта спеціалістів користуються стаціонарними комп’ютерами. Де-не-де в кабінетах зустрічаються iMac комп’ютери, які призначені для тестування. Але основна операційна система, на якій використовуються продукти, розроблені Materialise, — Windows, тож комп’ютери з «яблуком» — радше виняток.





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




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

У середньому, за даними компанії, на одну особу припадає 3,5 м²офісного простору.

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




Відпочинок і натхнення

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




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




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

Втілити свої ідеї в життя та роздрукувати будь-які макети можна за допомогою одного з двох офісних 3D-принтерів.




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

У Materialise Community є футбольна команда, яку компанія підтримує: покриває вартість залу, форми, тренувань, а також участь у турнірах.

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

На одному поверсі з кухнею знаходиться лекторій на 50 місць, де регулярно проводяться зовнішні мітапи спільноти ALT.NET, KyivAlgoClub, а також власні мітапи з С++.




DOU Ревізор запитує

Ми провели анонімне опитування членів Materialise Community, у якому взяли участь 124 спеціалісти, з яких 97 — технічні. Ми поцікавилися, чи задоволені вони офісом, і попросили оцінити за п’ятибальною шкалою певні характеристики: розміщення, графік і офісний простір.

Розміщенням цілком задоволені більше половини спеціалістів, і лише 13% опитаних оцінили цей критерій в 3 та менше балів. При цьому 8% називають розташування однією з основних переваг офісу.

Особистим графіком роботи цілком задоволені понад 70% опитаних. Найменш задовільні оцінки отримала можливість віддаленої співпраці: більше половини опитаних поставили оцінку 3 і нижче. Причому кожен четвертий спеціаліст зазначив саме можливість обирати, звідки працювати над проектом, перевагою, якою користується найчастіше, і понад 10% вказали, що опція потребує покращення.

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

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

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

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

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

Макс, Software Engineer, 3 роки в компанії

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

Круто також, що ми не ділимо простір з іншими компаніями і офіс цілком у нашому розпорядженні. Тут доволі просторі кімнати і лише один великий опенспейс — на першому поверсі. Там буває доволі гучно. Решту ж опенспейсів розраховано на 10-15осіб і в основному призначено для команд. Ми в кімнаті домовляємося про певний мікроклімат: хто «морозостійкий» — під кондиціонер, хто теплолюбивий — до вікна.

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

Що стосується організаційних штук — у нас все ок.

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

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

Поліна, функціональний аналітик, 6 років у компанії

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

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

Ілля, Software Engineer, 1,5 роки в компанії

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

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

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

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

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

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

Андрій, Business Intelligence Engineer, 3,5 роки в компанії

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

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

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

Добираться на работу на машине с Позняков мне было очень комфортно до открытия River Mall. Сейчас еще и реконструкция Южного моста со стороны Правого берега наложилась, так что на работу едешь 15-20 минут,а с работы — все 40. Но если на метро — то час.


Ну що, ми поїхали далі... А якщо ви хочете, щоб DOU Ревізор приїхав до вас, пишіть нам: revisor@dou.ua

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

Стежте за нами у Facebook.

Підписуйтесь на відеоканал DOU Ревізора на YouTube.


Фотограф: Леся Коверега

5 лучших книг для изучения JavaScript от Senior Front-end разработчика Александра Головатого

$
0
0

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

[Об авторе: Александр Головатый — Senior Front-end Developer в компании AppsFlyer, мировом лидере по мобильной атрибуции и аналитике. C 2011 по 2016 работал старшим разработчиком и руководителем Front-end команды в американской компании Inflection (Svitla Systems, outstaff), с 2016 по 2017 — Front-end Lead в американском стартапе JetBridge. Сооснователь курсов по программированию «FullStack Академия». Увлекается книгами о саморазвитии и стартапах]

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

Очень тяжело рекомендовать литературу для старших JavaScript разработчиков, (особенно когда нужно указать только 5). Спектр задач, которые можно решать с помощью JavaScript, очень широк: от мультиплатформенной разработки на Elektron, мобильной — React Native или NativeScript, веб-, как Front-end, так и Backend, до разработки браузерных расширений. Для более опытных JS «ниндзя» лучше всего подойдет специализированная литература под прикладные задачи, разбор открытых библиотек на GitHub и олимпиадные задачки по информатике, а также работа с ментором.

Нік Морган «JavaScript для дітей. Веселий вступ до програмування»

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

Илья Кантор «Современный учебник JavaScript»

Учебник написан настоящим гуру по JS Ильей Кантором, автором знаменитого русскоязычного онлайн-ресурса по изучению JavaScript — javascript.ru, знакомого каждому веб-разработчику. Этот трехтомный труд достойный похвалы, очень детализированное описание всех тонкостей и особенностей современного JavaScript. Кроме стандартного изучения основ, структур данных, замыкания, объектов, ООП в JS, вы также изучите более продвинутые темы: итераторы, промисы, генераторы, модули, события, создание графических компонентов, регулярные выражения, анимацию, AJAX, оптимизацию и еще много другого.

Учебник состоит из трех томов: «Язык JavaScript», «Документ, события, интерфейсы», «Тематические разделы». Книга читается легче, чем еще один классический труд — «JavaScript. Подробное руководство» Дэвида Флэнагана, который по праву также входит в нашу пятерку.

Флэнаган Дэвид «JavaScript. Подробное руководство»

Эта книга для меня является самым обширным справочником по JS. В первый раз она читается немного сложновато. Но через некоторое время книгу нужно снова прочесть для более глубокого понимания материала. В мире JavaScript, думаю, она уже давно стала священным «Граалем», обязательным для изучения. Вы сможете выучить кроме базового JavaScript, также работу с документами, объектом Window, обработкой событий, с протоколом HTTP, библиотекой jQuery, изучить работу с графикой и медиафайлами и как сохранять данные на стороне клиента, а также работу с прикладными интерфейсами HTML5.

Лично для меня две вышеперечисленные книги являются самыми лучшими и полными учебниками по JavaScript.

Кайл Симпсон «Вы не знаете JS»

В оригинале — Kyle Simpson «You Don’t Know Js»
Онлайн-версия книги на английском доступна на GitHub

Кайл Симпсон — это Open Web евангелист из Остина, штат Техас, который увлечен всем, что связано с JavaScript. Он — автор, тренер семинаров, технический спикер на многочисленных конференциях. На самом деле это целая серия небольших книг по JavaScript. Так как каждая книга раскрывает лишь небольшую часть материала, я рассматриваю их как один источник и как одну «книгу, разбитую на главы». Вот список: «Up & Going», «Scope & Closures», «this & Object Prototypes», «Types & Grammar», «Async & Performance», «ES6 & Beyond». Эта серия учебников идеально подходит для более глубокого изучения и понимания самых сложных частей JavaScript. Особенно стоит выделить «Scope & Closures», «this & Object Prototypes», «Async & Performance». Вся серия книг отлично дополняет изучение JS после трех вышеописанных учебников.

Michael McMillan «Data Structures and Algorithms with JavaScript»

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


В библиотеке современного разработчика находятся десятки, а то и сотни книг по программированию. Мне очень интересно узнать, какие ваши лучшие книги по изучению и разработке JavaScript. Пишите ваши топ-5 книг в комментариях, включайте также книги по React, Angular и Vue. Буду рад ответить на любые вопросы.

Вступна кампанія 2019: КПІ лідирує за кількістю заяв, а УКУ — за найвищим середнім балом абітурієнтів

$
0
0

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

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

Якщо ви не знаєте або забули термінологію абітурієнтів:

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

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

Лише Інженерія програмного забезпечення наблизилася до топ-спеціальностей за прохідними балами

Прохідні бали на IT-спеціальності досить високі, а конкурс в найкращі університети країни за найпопулярнішими IT-спеціальностями був більше ніж 10 осіб на одне місце щасливого студента. Однак до топ-спеціальностейз найвищими прохідними балами наблизилась лише одна спеціальність IT — Інженерія програмного забезпечення (181,764).

Прохідні бали на IT і дотичні до IT спеціальності в 2019 році:

СпеціальністьДеннаЗаочна
Інженерія програмного забезпечення181,764146,28
Прикладна математика171,972-
Інформаційні технології171,146151,112
Автоматизація та комп’ютерно-інтегровані технології154,739150,182
Електроніка та телекомунікації143,718155,754
Прикладна фізика та наноматеріали138,587-
Математика127,2-
Інформатика (Середня освіта) 113,716133,275
Комп’ютерні технології (Професійна освіта)112,404135,364

Для порівняння, найвищи прохідні бали українські університети встановили для студентів, які після закінчення навчання представлятимуть Україну на міжнародному рівні: Міжнародне право (194,25); Міжнародні відносини, суспільні комунікації та регіональні студії (194,00); Міжнародні економічні відносини (190,84).

Судячи з того, наскільки високі прохідні бали на деякі філологічні спеціальності, Гаудеамус в перекладі на мову власного винаходу першого вересня десь буде співати наш, український Толкін. Так, на спеціальність «Східні мови та літератури (переклад включно), перша — китайська» прохідний конкурсний бал — 193,53; на «Германські мови та літератури (переклад включно), перша — шведська» — 192,85; на «Східні мови та літератури (переклад включно), перша — японська» — 192,30.

Високі прохідні бали також і на медичні спеціальності «Стоматологія» (189,18) та «Медична психологія» (186,90). Однак, варто зазначити, що це є прохідні бали на рівень магістра.

Суспільствознавчі науки також потрапили у топ спеціальностей з найвищими прохідними балами цього року. Для того, щоб вступити на спеціальність «Політологія», потрібно було мати 189,13 балів та вище; на Журналістику (МОН) — 188,75; на Культурологію (МОН) — 185,69; на Історію та археологію — 185,05.

Комп’ютерні науки — найпопулярніша ІТ-спеціальність

За даними Міністерства освіти і науки України найпопулярнішою IT-спеціальністю серед абітурієнтів в 2019 році стала спеціальність Комп’ютерні науки: 39 588 заяв було прийнято на очну і заочну форму навчання, серед них 26 539 заяв на бюджетну форму. Наступною за популярністю стала спеціальність Інженерія програмного забезпечення (27 302 / 18 836). Замикає трійку лідерів Комп’ютерна інженерія, на яку подали 16 661 заяву, серед яких 12 201 заява на бюджетну форму навчання.

А ось людей, які будуть розвивати інформатику та комп’ютерні технології в школах та професійних навчальних закладах не так вже й багато: 656 заяв було отримано на вчителя інформатики в середніх школах та 611 заяв на викладачів комп’ютерних технологій в закладах професійної освіти. Ці дві спеціальності стали найменш затребуваними серед абітурієнтів, які планують пов’язати свою кар’єру з IT.

Спеціалізація. Кількість поданих заяв

Найвищий конкурсний бал у математиків та фізиків

Щодо середніх балів вступників, то лідерами стали дотичні до IT спеціальності: Прикладна математика (середній конкурсний бал — 167), Математика (164) і Прикладна фізика та наноматеріали (159). А власне IT-спеціальності дещо від математиків і фізиків відстають цього року за середніми конкурсними балами абітурієнтів.

Загальний середній бал заяв за спеціальностями:

Прикладна математика167
Математика164
Прикладна фізика та наноматеріали159
Системний аналіз155
Інженерія програмного забезпечення153
Кібербезпека152
Інформаційні системи та технології152
Комп’ютерні науки151
Комп’ютерна інженерія150
Середня освіта (Інформатика)148
Автоматизація та комп’ютерно-інтегровані технології147
Професійна освіта (Комп’ютерні технології)146
Електроніка143
Телекомунікації та радіотехніка143

Заяви на бюджет мають стабільно вищий середній бал. Це справедливо для всіх спеціальностей, однак часом різниця не так вже й велика. Наприклад, середній бал заяв на бюджет на спеціальності Середня освіта (Інформатика) і Прикладна фізика та наноматеріали вищий від загального середнього балу лише на 1%. На 2% вище середній бал заяв на бюджет на спеціальності Математика та Прикладна математика; на 3% — Професійна освіта (Комп’ютерні технології) і Автоматизація та комп’ютерно-інтегровані технології; на 4% — Телекомунікації та радіотехніка, Електроніка, Інформаційні системи та технології, а також Системний аналіз; на 5% — Комп’ютерна інженерія, Комп’ютерні науки та Кібербезпека. Інженерія програмного забезпечення — спеціальність із найбільшою різницею між загальним середнім балом (153) та середнім балом заяв на бюджет (161) в 6%.

Спеціалізація. Середній бал

Серед найпопулярніших ІТ-вишів — КПІ, Львівська політехніка та Шевченка

В рамках зазначених вище спеціальностей лідерство серед університетів по кількості отриманих заяв тримає НТУУ «КПІ ім. І. Сікорського», куди подали 19 260 заяв на вступ, з яких 15 156 заяв на бюджет. В п’ятірку лідерів по кількості заяв в 2019 році потрапили також Національний університет «Львівська політехніка» (10 752 / 8213), Київський національний університет імені Тараса Шевченка (8230 / 6192), Харківський національний університет радіоелектроніки (7342 / 5947) та Національний авіаційний університет (6592 / 4935).

Топ-30 ВНЗ. Кількість поданих заяв

УКУ лідирує за конкурсними балами абітурієнтів

А ось перша п’ятірка закладів вищої освіти за найвищими загальними середніми конкурсними балами абітурієнтів дещо інша. Першість за найвищим середнім балом поданих заяв на IT та дотичні спеціальності має «Український католицький університет» з середнім балом 189; далі — Національний університет «Києво-Могилянська академія» (загальний середній бал 175, середній бал заяв на бюджет — 181); майже не відстає Київський національний університет імені Тараса Шевченка (174 / 177); Львівський національний університет імені Івана Франка (168 / 174) та замикає п’ятірку лідерів Приватний заклад вищої освіти «ІТ СТЕП Університет» (загальний середній бал — 168).

Топ-30 ВНЗ. Середній бал

Отже, за ким будуть полювати роботодавці за 5 років

Комп’ютерні науки. Найвищий середній конкурсний бал за цією спеціальністю цього року в Українському католицькому університеті — 188,57. Загальний конкурс за даними порталу vstup.osvita.uaв цей університет на спеціальність Комп’ютерні науки складає 7,74 осіб на місце. Найбільшу кількість заяв на цю спеціальність надійшло до КПІ ім. Ігоря Сікорського (3288; загальний конкурс на цю спеціальність в Інститут прикладного системного аналізу складає 10,24 осіб на місце), Національного університету «Львівська політехніка» (3128 заяв) та Харківського національного університету радіоелектроніки (2498 заяв).

Інженерія програмного забезпечення (прохідний бал денна — 181,764, заочна — 146,28). В КНУ ім. Шевченка найвищий середній конкурсний бал за спеціальністю Інженерія програмного забезпечення — 175,48, крім того, Шевченка — другий університет за кількістю поданих заяв (2031). Загальний конкурс на Факультет інформаційних технологій тут 12,39 осіб на місце. Першість за показником кількості заяв має НТУУ «КПІ ім. Ігоря Сікорського» з 5212 заявами. В трійку лідерів за кількістю заяв потрапляє також і Національний університет «Львівська політехніка» (1925 заяв).

Комп’ютерна інженерія. Найбільшу кількість заяв на цю спеціальність подали до університетів: НТУУ «КПІ ім. Ігоря Сікорського» (2528 заяв, загальний конкурс на Факультеті інформатики та обчислювальної техніки — 9,23), Національний університет «Львівська політехніка» (1258), НТУ «Харківський політехнічний інститут» (1214). Найвищий середній конкурсний бал за спеціальністю Комп’ютерна інженерія у абітурієнтів Київського національного університету ім. Тараса Шевченка — 173 бали, конкурс був 5,88 осіб на місце.

Кібербезпека. Топ-3 за кількістю поданих заяв: НТУУ «КПІ імені Ігоря Сікорського» (1703 заяви, загальний конкурс — 9,57), Національний університет «Львівська політехніка» (1438), Національний авіаційний університет (1356). Найвищий середній конкурсний бал, як і у попередніх спеціальностях, у майбутніх студентів КНУ ім. Тараса Шевченка (171), із загальним конкурсом 8,56 осіб на місце.

Інформаційні системи та технології. Найбільшу кількість заяв на цю спеціальність було подано до НТУУ «КПІ ім. Ігоря Сікорського» (1555) і конкурс в цьому університеті був 5,17 осіб на місце, Національний університет «Львівська політехніка» (984) та Львівський національний університет імені Івана Франка (476). Середній конкурсний бал заяв на спеціальність Інформаційні системи та технології найвищий цього року в КНУ ім. Шевченка (171 бал), де загальний конкурс склав 7,32 осіб на місце.

Автоматизація та комп’ютерно-інтегровані технології (прохідний бал денна — 154,739; заочна — 150,182). Окрім НТУУ «КПІ ім. Ігоря Сікорського» (1405 заяв) в трійку лідерів по кількості заяв на спеціальність Автоматизація та комп’ютерно-інтегровані технології потрапили Харківський національний університет радіоелектроніки (527) та Національний авіаційний університет (461). Харківський національний університет імені В.Н. Каразіна — університет з найвищим середнім конкурсним балом на цю спеціальність в країні цього року — 165 балів, загальний конкурс в ХНУ ім. Каразіна на цю спеціальність був 5,63.

Системний аналіз. Традиційно, найбільшу кількість заяв на вступ абітурієнти віднесли до столичного КПІ ім. Ігоря Сікорського (818 заяв, загальний конкурс 4,17 осіб на місце), наступними за популярністю йдуть львівські університети: Національний університет «Львівська політехніка» (696) та Львівський національний університет імені Івана Франка (483). У Львові також будуть навчатися студенти з найвищими балами в «Українському католицькому університеті», де середній конкурсний бал вступних заяв становить 189 балів, а конкурс — 6,20 осіб на одне місце.

Прикладна математика (прохідний бал — 171,972). Найбільше заяв на спеціальність Прикладна математика цього року було до НТУУ КПІ ім. Ігоря Сікорського (974 заяви, загальний конкурс на Факультеті прикладної математики — 5,27), КНУ ім. Тараса Шевченка (528 заяв, загальний конкурс 4,15), де крім того був і найвищий середній конкурсний бал — 184, та в ЛНУ ім. Івана Франка (505 заяв).

Телекомунікації та радіотехніка. Більше всього заяв абітурієнти віднесли до КПІ ім. Ігоря Сікорського (1038, загальний конкурс в Інституті телекомунікаційних систем — 2,50), Харківського національного університету радіоелектроніки (504) та Державного університету телекомунікацій (423). Середній конкурсний бал заяв на спеціальність Телекомунікації та радіотехніка найвищий в Чернівецькому національному університеті ім. Юрія Федьковича (171 бал), хоча загальний конкурс в цьому університеті на спеціальність Телекомунікації та радіотехніка невеликий — 0,25.

Прикладна фізика та наноматеріали (прохідний бал — 138,587). Дві третини заяв на цю спеціальність сконцентрувалися в трьох університетах: КНУ ім. Тараса Шевченка (408, загальний конкурс 3,44), ХНУ ім. В.Н. Каразіна (407) та НТУ України «Київський політехнічний інститут ім. Ігоря Сікорського» (190 заяв), де найвищий середній конкурсний бал — 168, а загальний конкурс — 3,27 осіб на місце.

Математика (прохідний бал — 127,2). Топ трійка ВНЗ за спеціальністю Математика за кількістю поданих заяв спільна зі спеціальністю Прикладна математика: КНУ ім. Тараса Шевченка (458 заяв, загальний конкурс на освітню програму Комп’ютерна математика — 5,11), НТУУ «КПІ ім. Ігоря Сікорського» (203) та Львівський національний університет імені Івана Франка (185). Однак найвищий середній конкурсний бал за цією спеціальністю серед абітурієнтів Харківського національного університету ім. В.Н. Каразіна — 182, де загальний конкурс 1,06.

Електроніка. До НТУУ «Київський політехнічний інститут ім. Ігоря Сікорського» подали 346 заяви на спеціальність Електроніка (загальний конкурс 1,50 осіб на місце), 148 заяв — до Харківського національного університету радіоелектроніки, та 140 заяв прийняли в Національному авіаційному університеті. Сумський державний університет не увійшов в трійку лідерів за кількістю поданих заяв, однак там найвищий середній конкурсний бал за цією спеціальністю — 162.


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


Читайте також «Рейтинг вишів DOU 2019: у Могилянки з’явився конкурент за перше місце, а КПІ за межами 10-килідерів»

Метафора системы: как повысить качество кода

$
0
0

Всем привет!

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

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

Определение метафоры системы

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

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

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

Википедия

Итак, метафора системы. С одной стороны, определение очень общее и не совсем понятно, как им пользоваться, с другой — широко распространенной информации по данному подходу, в отличие от других практик, например TDD, Pair Programming или CodeReview, не очень много, и постигать саму концепцию приходится скорее на практике.

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

К практике

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

Первое знакомство или структура проекта

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

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

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

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

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

В ходе развития проекта и расширения команды возникла необходимость такую договоренность ввести, и давайте посмотрим на то, как доменную область можно построить уже в готовом коде. Суть нашей работы в этом проекте заключается в создании CLI Tool для решения задач CI/CD в рамках процесса разработки. Я думаю, что при изучении различных инструментов вы не раз пользовались такими инструментами, которые упрощают технологические задачи, например, в angular или react приложениях.

Предметная область

Итак, давайте посмотрим, какие понятия из нашей предметной области отсутствуют на данный момент в структуре проекта, и постараемся их добавить. Первое, что приходит мне в голову, — это отсутствие понятия Command (а ведь CLI = Command Line Interface :) ). В проекте присутствует класс CommandLineOptions — в нем сосредоточено описание всех параметров для всех команд. В результате чего любому разработчику ничего не остается, кроме как дописывать сами команды в класс, который этого не запрещает напрямую. Новые и новые строки кода добавляются в файл, в результате чего получается своеобразное ассорти, но при этом стоит отметить, что даже такое название класса однозначно определяет его назначение, и вы не встретите в проекте описание параметров команд в другом месте.

Обратите внимание, что объем этого класса не очень большой с одной стороны, а с другой — количество using-ов в нём очень умеренное. То, что внешние показатели класса не кажутся очень пугающими, обусловлено тем, что у него довольно конкретная область ответственности, заложенная в его названии. Это значит, что все разработчики одинаково интерпретируют и используют его в своей работе. Однако давайте построим связи дальше и рассмотрим, как же этот класс связан с упомянутым выше классом Program, который содержит почти 1000 строк. Если мы для описания команд имели хоть мало-мальски выделенную структурную единицу, то для реализации самой команды такой структурной единицы нет. Всю реализацию команд мы найдем в классе Program.

Проблема файлов, которые агрегируют различные классы, сродни проблеме множественной ответственности. Зачастую такие классы визуально от вас скрывают проблему структурной организации кода (стоит отметить, что для вскрытия или обнаружения такой проблемы можно использовать инструменты, встроенные в IDE, которые отобразят диаграмму классов проекта) Данная проблема очень часто встречается в проектах, где есть классы или файлы, названные с помощью общих слов, которые не уточняют их предназначение и не помогают разработчикам идентифицировать ответственность класса в изначальном плане. Например, это Tools, Utilities, Extensions, Helper и им подобные. Часто, рождаясь в проекте как временные, они могут обрастать функционалом, поскольку уже подключены в места, откуда этот функционал можно вызвать — или, что еще хуже, приводят к ситуации, когда возможности использовать полезные функции в этих классах без сложной инициализации зависимостей просто нет. Однако не стоит сразу отчаиваться, если в своем проекте вы столкнулись с данной проблемой. У таких файлов есть одна интересная особенность, о которой нужно помнить и стараться использовать при изменении структуры кода: они легко разделяются при введении метафоры всей системы или хотя бы в отдельно взятой её области. Этот эффект вызван как раз тем, что код внутри такого файла часто бывает очень слабо связан между собой ввиду того, что относится к разным задачам. В тех же местах, где использование такого кода есть, это решается с помощью приёма в рефакторинге выделения нового класса.

Глаза боятся, а руки делают

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

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

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

Стоимость и временные затраты на такое действие — ничтожно малы. Создаем класс AppListCommand и переносим из класса Program реализацию метода ShowAppList.

AppListComand

Program

Давайте рассмотрим, что произошло со структурой кода после этих операций, на которые мы потратили всего пару минут:

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

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

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

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


До
После

Вывод

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

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

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

Як змусити Amazon Alexa грати музику з Google Music, хоч вона цього й не хоче

$
0
0

Привіт, мене звати Олег Шанковський, я Java-програміст. Працюю в Києві в американській компанії, що спеціалізується на кібербезпеці. У цьому матеріалі розповім, як змусити розумну голосову асистентку Алексу від Amazon програвати музику з Google Music, як обійти пов’язані проблеми, а також навіщо це все потрібно.

Із чим маємо справу

Серед популярних голосових асистентів (Siri від Apple, Assistant від Google, чи, Боже збав, Cortana від Microsoft) Алексу вважають найрозумнішою й найкориснішою. Одна з основних причин — можливість навчати її новим умінням і відносна легкість цього процесу. Ви можете додати до вашої колонки нове вміння з великого магазину скілів, а якщо не знайдете там потрібний — створити скіл самотужки. Саме цим ми сьогодні й займемося.

Понад рік я вдома користуюся двома колонками Amazon Echo Dot, які під’єднано до стереосистем на кухні й у вітальні. Мої колонки вміють умикати/вимикати телевізор та андроїд-приставку до нього (Alexa, TV on), знаходити мій телефон (Alexa, ask Tracker to ring my phone), програвати подкасти й аудіокниги, розповідати про погоду, читати «Вікіпедію» тощо. Колонки знають одна про одну, уміють одна одну вмикати/вимикати (Alexa, stop in the kitchen), а також грати музику синхронно (Alexa, play Nirvana everywhere).

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

Цю проблему я розв’язав, указавши в реєстраційних даних регіон США й адресу супермаркету в Чикаго. Завдяки цьому мені, як новоспеченому американцеві, став доступним цілий набір музичних сервісів, серед яких найкорисніші — Pandora й iHeartRadio. На цих сервісах є чимало справді хорошої музики, і цим можна було б й обмежитися, якби не одна проблема. Річ у тім, що ви можете задати Алексі лише виконавця, а не конкретну пісню. З указаного вами виконавця Алекса створить треклист, у який, окрім бажаного артиста, додасть пісні такого ж жанру інших виконавців. Наприклад, у відповідь на команду Alexa, play Metallica on iHeart, окрім самої Metallica, ви почуєте Black Sabbath, Nirvana, Scorpions і навіть Queen.

Для більшості випадків такої поведінки повністю достатньо: замовили бажаний жанр і займаєтеся своїми справами під хорошу музику. Однак, якщо вам раптом захочеться послухати саме Unforgiven II, Алекса у відповідь запропонує купити платну передплату на Amazon Music за 10 доларів на місяць. Не те щоб це було дорого, однак я вже оплачую преміум-передплату Google і купувати ще одну, лише щоб слухати її вдома, мені не хотілося. Найочевиднішим рішенням було б зактивувати на Алексі скіл Google Music, однак такого просто не існує. Кажуть, причина в конкуренції компаній Google та Amazon.

Ну що ж, challenge accepted! Створимо скіл самотужки.

Створюємо скіл

Для того щоб у відповідь на наш голосовий запит Алекса почала програвати задану пісню, ми повинні дати посилання на неї. Тобто нам потрібен програмний інтерфейс, який знайде й поверне нам це посилання. Тут ми стикаємося зі ще однією проблемою: офіційного Google Music API не існує. Є офіційний API для YouTube, однак він повертає посилання на відео-, а не на аудіофайл. Після певного дослідження я дійшов висновку, що компанія Google доклала чимало зусиль, щоб ускладнити виділення аудіопотоку з відеофайлу (як мінімум, це було б незручно з погляду часових затрат на виконання команди), й облишив цю справу.

Після коротких додаткових пошуків виявив, що є хороший неофіційний API для Google Music, який написано на Python, а також Java wrapperдо нього. Останнє — саме те, що нам і потрібно, беремо.

Починаємо створення скіла. Для цього заходимо на Alexa Developer Consoleі реєструємо там акаунт, до якого прив’язано нашу розумну колонку. Після реєстрації потрапляємо в консоль, у якій бачимо кнопку Create Skill.

Натискаємо її, уводимо потрібну назву скіла, залишаємо тип моделі Custom, а мову взаємодії — англійську. У наступному вікні вибираємо Start from scratch. Потрапляємо в головну адмінку нашого скіла.

Починаємо із секції Invocation, де вказуємо, яке звернення активуватиме наш скіл (Alexa, ask Google Music to play...), і вибираємо Google Music.

Переходимо до секції Intents, де вказуємо основні параметри взаємодії з нашим скілом. Intent — це намір, і тут Алекса дізнається, що ви хочете зробити. Є низка убудованих інтентів, які ми можемо використовувати під час створення скіла, наприклад, AMAZON.StopIntent зупинить виконання певної дії, AMAZON.PauseIntent поставить її на паузу тощо. Назва інтента — це не голосова команда, тому називаємо його так, як нам до вподоби. Наприклад GoogleMusic. Натискаємо Create custom intent.

Потім консоль пропонує нам вказати Sample Utterances, тобто голосову фразу, що зактивує інтент і вкаже йому, що слід зробити. Нас цікавить лише одна команда — play. Пишемо її.

Далі нам потрібна змінна, щоб передати назву пісні, яку ми хочемо послухати. Такі змінні називають слотами. Можна було б указати два слоти: окремо для пісні й виконавця, однак це зробило б взаємодію з Алексою менш зручною. Тим паче, що наш Google Music API чудово вміє шукати практично за будь-якою побудовою фрази. Тому залишаємо один слот і називаємо його song. Окрім назви, нам також потрібно вибрати один з наявних типів слота. Загалом тип (наприклад, Actor, Airline, Book, Drink, Duration) може потім допомогти Алексі краще визначити, що саме ми хочемо, і виконати команду якісніше, але, оскільки наш пошук здійснюватиме не Алекса, а Google, то для нас це не має жодного значення. Як тип я вибрав AMAZON.MusicCreativeWorkType.

Повертаємося нагору до нашого Sample Utterances, який ми назвали play, й у фігурних дужках після нього вписуємо наш слот song.

Це означає, що фразу, яку ми промовимо після слова play, буде записано в слот song. Тиснемо кнопку Save Model угорі.

Переходимо в розділ Interfaces, активуємо Audio Player і тиснемо Save Interfaces.

Переходимо в розділ Endpoint. Тут ми повинні вказати, де живе бекенд, який обробить нашу команду й поверне відповідь. У нас є два варіанти: AWS Lambda ARN i HTTPS. Оскільки другий варіант означає розгортання сервера, ми зупиняємося на першому, дуже простому й зручному для наших цілей. Однак Lambda слід спершу налаштувати, тому поки відкладаємо консоль Алекси й в сусідній вкладці відкриваємо консоль Amazon Web Services (AWS).

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

Під час реєстрації Amazon попросить вас указати дані кредитної картки на випадок, якщо захочете користуватися платними сервісами. Ці дані вказати доведеться, однак гроші на цьому проекті ви точно не потратите: Lambda надає безоплатно 1 млн запитів або 400 тис. Гб/с на місяць. Розслабляємося й реєструємося.

Зайшовши в консоль AWS, знаходимо серед сервісів Lambda, переходимо в розділ Functions і тиснемо кнопку Create function. Серед варіантів створення функції залишаємо активним Author from scratch, указуємо назву функції (наприклад googleMusic) і вибираємо мову Java 8. У розділі Choose or create an execution role вибираємо Create a new role with basic lambda permissions. Тиснемо Create function.
Потрапляємо в консоль нашої нової функції. Найперше нам треба вказати, що саме її активуватиме. Тиснемо Add trigger і вибираємо Alexa Skills Kit. Повертаємося в консоль Алекси, знаходимо в розділі Endpoint рядок з ID нашого скіла (amzn1.ask.skill...), копіюємо, повертаємося в консоль Lambda й уставляємо його в поле Skill ID.

Тиснемо Save угорі екрана.

Поруч із кнопкою Save бачимо ідентифікатор нашої функції arn:aws:lambda:... Копіюємо цей рядок і повертаємося в консоль Алекси. Тут, у розділі Endpoint, уставляємо рядок у поле Default Region.

Тепер наші скіл і функція Lambda зв’язані між собою. Переходимо в розділ Intents і тиснемо кнопку Build model.

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

Пишемо бекенд

Я писатиму бекенд на Java в середовищі IntelliJ IDEA, а проект збиратиму за допомогою Maven.

Створюємо звичайний Java-проект. Найперше додаємо всі потрібні залежності. Для роботи з Алексою й Lambda нам потрібно:

<dependency><groupId>com.amazon.alexa</groupId><artifactId>alexa-skills-kit</artifactId><version>1.8.1</version></dependency><dependency><groupId>com.amazonaws</groupId><artifactId>aws-lambda-java-core</artifactId><version>1.2.0</version></dependency><dependency><groupId>com.amazonaws</groupId><artifactId>aws-lambda-java-events</artifactId><version>2.2.6</version></dependency>

Під’єднуємо неофіційний Google Music API:

<dependency><groupId>com.github.felixgail</groupId><artifactId>gplaymusic</artifactId><version>0.3.6</version></dependency>

Згодом під час деплою готового коду на Lambda я стикнувся з проблемою: функція не могла знайти шлях до основного хендлера. Поґуґливши, я виявив, що ця проблема є типовою і її розв’язують пакуванням проекту в over-jar з усіма залежностями замість звичайного jar. Для цього додаємо плагін shade для Maven:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.2.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals></execution></executions></plugin></plugins></build>

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

Наш клас повинен зімплементити інтерфейс SpeechletV2 й заоверрайдити чотири методи:

  • onSessionStarted;
  • onLaunch;
  • onIntent;
  • onSessionEnded.

onSessionStarted

У методі onSessionStarted відбуваються ініціалізація скіла і його підготовка до роботи. Тут ми повинні налаштувати основний об’єкт GPlayMusic, який і шукатиме музику за нашим запитом. Для цього нам слід залогінитися в Google.

Передусім ми повинні створити токен (об’єкт AuthToken), надавши йому адресу Google-пошти, пароль від неї (panic mode: on!) й IMEI мобільного пристрою, на якому зараз чи колись було встановлено додаток Google Play Music.

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

Розв’язати цю проблему можна, створивши спеціальний пароль для додатків. Для цього вам слід зайти в Google-акаунт, перейти в розділ «Безпека» й вибрати «Пароль додатків». У відповідь Google створить спеціальний 16-значнийпароль, який ви зможете використати під час створення AuthToken та успішно залогінитися у вашому Google-акаунті. Отже, ви не передаєте в програму ваш справжній пароль.

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

Звичайно, ми не прописуватимемо облікові дані просто в коді. На Lambda можна вказати змінні середовища (Environment variables), у які ми й упишемо наші дані: USER_NAME, USER_PASSWORD та IMEI). Також Lambda дає змогу зенкриптити ці дані.

Отже, логінимося:

AuthToken token = null;
try {
   token = TokenProvider.provideToken(System.getenv("USER_NAME"), System.getenv("USER_PASSWORD"), System.getenv("IMEI"));
} catch (IOException | Gpsoauth.TokenRequestFailed e) {
   log.error("Error while auth token generating", e);
}

api = new GPlayMusic.Builder()
   .setAuthToken(token)
   .build();

На цьому завдання методу onSessionStarted виконано, переходимо до onLaunch.

onLaunch

Метод onLaunch викликають за допомогою команди Alexa, open Google Music. У відповідь ми просто привітаємося.

Алекса надсилає нам запит від користувача в об’єкті SpeechletRequestEnvelope. У відповідь ми повинні надіслати об’єкт SpeechletResponse. У цей об’єкт ми повинні помістити все, що потрібно нашій колонці для відповіді користувачу. У цьому разі це буде просто вітання, яке ми помістимо в об’єкт PlainTextOutputSpeech. Окрім самого вітання, ми додамо repromptSpeech — додаткову фразу, якою Алекса пояснить користувачу, що саме він може робити:

PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
speech.setText(WELCOME_TEXT);
PlainTextOutputSpeech repromptSpeech = new PlainTextOutputSpeech();
repromptSpeech.setText(CHOOSE_THE_SONG_REQUEST);
Reprompt reprompt = new Reprompt();
reprompt.setOutputSpeech(repromptSpeech);

return SpeechletResponse.newAskResponse(speech, reprompt);

Варто зазначити, що метод onLaunch не спрацює, якщо користувач відразу попросить Алексу ввімкнути конкретну пісню на нашому скілі (Alexa, ask Google Music to play...). У такому разі ми відразу перейдемо до методу onIntent.

onIntent

Основна робота відбувається саме тут. Разом із запитом ми отримаємо об’єкт Intent, який містить у собі назву інтента й слот. Ми очікуємо від користувача дві дії: програвати музику й зупинити її. Якщо користувач хоче програвати музику, витягуємо з інтента слот і передаємо його як пошуковий запит у наш Google Music API. Якщо користувач захотів тиші, вішаємо на наш SpeechletResponse текст Goodbye і надсилаємо Алексі директиву StopDirective. Якщо нам почулося щось інше, повідомляємо користувача про помилку й просимо повторити.

@Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
   logMethodStart("onIntent", requestEnvelope);
   IntentRequest request = requestEnvelope.getRequest();
   Intent intent = request.getIntent();
   String name = intent.getName();
   log.info("Requested intent: {}", name);

   switch (name) {
       case GOOGLE_MUSIC_INTENT:
           String song = intent.getSlot(SONG_SLOT).getValue();
           try {
               return playMusicResponse(song);
           } catch (Exception e) {
               log.error("Couldn't play {}", song, e);
               return newAskRequest(ERROR);
           }
       case "AMAZON.StopIntent":
       case "AMAZON.CancelIntent":
           return goodbye();
       default:
           log.error("Unexpected intent: " + name);
           return newAskRequest(WRONG_REQUEST);
   }
}

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

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

  • Stream, що міститиме посилання на пісню й кілька додаткових технічних параметрів;
  • AudioItem, що міститиме Stream;
  • PlayDirective — команда Алексі програвати музику, що міститиме AudioItem, а також деякі додаткові параметри;
  • SpeechletResponse, що міститиме об’єкт PlayDirective, а також текст із назвою пісні й ім’ям виконавця, який Алекса промовить перед початком програвання музики.

Ось який це має вигляд:

private SpeechletResponse playMusicResponse(String songRequest) throws Exception {
   List<Track> trackList = api.getTrackApi().search(songRequest, 1);
   if (trackList.isEmpty())
       return noTrackFoundResponse(songRequest);

   Track track = trackList.get(0);

   Stream stream = new Stream();
   stream.setUrl(track.getStreamURL(StreamQuality.HIGH).toString());
   stream.setOffsetInMilliseconds(0);
   stream.setExpectedPreviousToken(null);
   stream.setToken("0");

   AudioItem song = new AudioItem();
   song.setStream(stream);

   PlayDirective directive = new PlayDirective();
   directive.setAudioItem(song);
   directive.setPlayBehavior(PlayBehavior.REPLACE_ALL);

   SpeechletResponse response = new SpeechletResponse();
   response.setDirectives(singletonList(directive));
   response.setNullableShouldEndSession(null);

   PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
   speech.setText("Playing " + track.getTitle() + " by " + track.getArtist());

   response.setOutputSpeech(speech);

   return response;
}

onSessionEnded

У нашому випадку додаткові дії в цьому методі не потрібні, тому просто логуємо його виклик.

Крім класу GoogleMusicSpeechlet, нам слід створити ще один, який наслідуватиме клас SpeechletRequestStreamHandler і стане точкою входу для Алекси. Єдине його завдання — зберігати ID скіла, який може викликати цей функціонал.

public class GoogleMusicRequestStreamHandler extends SpeechletRequestStreamHandler {
   private static final Set<String> supportedApplicationIds = new HashSet<>();

   static {
       supportedApplicationIds.add("amzn1.ask.skill.da7a7858-5bf8-46be-a12a-30f85a7b3283");
   }

   public GoogleMusicRequestStreamHandler() {
       super(new GoogleMusicSpeechlet(), supportedApplicationIds);
   }
}

Наш бекенд готовий. Приправити логами за смаком, додати трохи юніт-тестів і можна подавати. Білдимо jar (mvn package) і деплоїмо його на Lambda.

У полі Runtime вибираємо Java 8, у полі Handler указуємо повністю шлях до GoogleMusicRequestStreamHandler і завантажуємо наш jar.

Готово. Тепер наш скіл доступний на колонці й готовий виконати замовлення. Крім того, тестувати його можна через вебінтерфейс у консолі Алекси:

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

Через обмеження браузера власне програвання музики не розпочнеться, однак такого тестування здебільшого достатньо, щоб не бігати щоразу до колонки. Також тестувати скіл можна через мобільний додаток Reverb for Amazon Alexa, який чудово імітує спілкування з Алексою.

Логи можна читати на CloudWatch Logs.

Код бекенду.

Що далі?

Звичайно, ми не можемо опублікувати скіл у магазині Amazon: компанія не затвердить його зі зрозумілих причин. Однак спокійно можемо користуватися ним удома в режимі In Development.

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

Alexa, play We are the champions.

XSLT-шаблонизатор для PHP

$
0
0

Привіт! Мене звати Артем, я — PHP-програміст. У цій статті розглянемо основи XSLT і приклади його використання як шаблонизатора для веб-сайтів, які створено мовою PHP.

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

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

Схема роботи XSLT

Зізнаюся відверто, що не відразу зрозумів цю технологію, а тим паче оцінив її переваги. Насамперед мене спантеличувала парадигма програмування, яка істотно відрізняється від звичної для PHP об’єктно-орієнтованої, або навіть процедурної. До того ж мова Extensible Stylesheet складніша, як порівняти з тим же Smarty. І це не дивно, адже XSLT — цілком незалежна самодостатня мова, розроблена W3C як міжнародний стандарт для перетворення структур даних. Але згодом, коли мій мозок звик до нової парадигми, я зрозумів, що мої перестороги були марними.

Документ у форматі XML за допомогою шаблонів XSL можна змінити на XML-документз іншою структурою або на HTML-сторінку, Plain Text чи навіть PDF. Але саме зараз нас цікавить на виході лише HTML. І для цього нам навіть спочатку не знадобиться PHP: більшість сучасних веб-оглядачів уміє здійснювати XSL-перетворення самостійно. Налаштуймо для цих потреб локальний тестовий веб-сайт (наприклад, цей) і створімо в ньому кілька файлів.

Шаблони

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

<?xml version="1.0" encoding="UTF-8" ?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/*">
        ...<xsl:apply-templates select="country/city" />
        ...<xsl:call-template name="map" />
        ...</xsl:template><xsl:template match="country/city">
        ...</xsl:template><xsl:template name="map">
        ...</xsl:template></xsl:stylesheet>

XSL-файл складається зі щонайменше одного або кількох шаблонів template. У них за допомогою простих інструкцій у вигляді XSLT-елементів, створюють нову структуру даних на основі вхідних даних. Або, інакше кажучи, шаблон XSLT описує, які дані з вхідного XML-файлуй у якому місці виводити (у цьому разі — поміж HTML), і як саме.

Шаблони XSLT, так само як і функції в програмуванні, мають два призначення: основне й додаткове. Основне — це уникнення дублювання коду шляхом його повторного використання. А додаткове — поділ великих шматків коду на менші, зручніші для сприйняття.

Шаблон <xsl:template match="/*">...</xsl:template>обробляє головний елемент вхідних даних, який розташовано в самому корені XML-документа,тому це головний шаблон. Він автоматично запускається першим, і зазвичай через нього застосовують усі інші шаблони, прописуючи відповідні виклики шаблонів з відповідними умовами або іменами в певних місцях.

Шаблони в XSLT викликаються двома різними способами та мають різні підходи до області видимості вхідних даних XML у самому шаблоні. Я називаю їх, за аналогією з умовним переходом в програмуванні, шаблонами з умовним або безумовним викликом.

Шаблон з умовним викликом застосовують за допомогою елемента apply-templates з атрибутом select, у якому вказано умову виклику шаблона. Виклик зактивізується лише тоді, коли хоч якась частина вхідного документа відповідає умові виклику. Цей тип шаблонів, по-моєму, є родзинкою XSLT і робить його таким, яким він є. Він за своєю природою реалізує принцип обробки потокових даних, а саме тут — ще й ієрархічної структури.

<!-- Застосувати шаблон, якщо
 на поточному рівні дерева присутній елемент country --><xsl:apply-templates select="country" /><!-- Застосувати шаблон, якщо
 на поточному рівні дерева присутній елемент country,
  який містить дочірній елемент city --><xsl:apply-templates select="country/city" /><!-- Застосувати шаблон, якщо
 на поточному рівні дерева присутній елемент country,
  який містить дочірній елемент city,
    який містить атрибут size --><xsl:apply-templates select="country/city[@size]" /><!-- Застосувати шаблон, якщо
 на поточному рівні дерева присутній елемент country,
  який містить дочірній елемент city,
    який містить атрибут size,
      який має значення 'big' --><xsl:apply-templates select="country/city[@size='big']" /><!-- Застосувати шаблон з атрибутом mode,
 який має значення article, якщо
  на поточному рівні дерева присутній елемент country,
    який містить дочірній елемент city,
      який містить атрибут size,
        який має значення 'big' --><xsl:apply-templates select="country/city[@size='big']" mode="article" />

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

Якщо ви хочете отримати дані з елементів чи атрибутів, які містяться за межами кореневого елемента цього шаблона, то до них можна звернутися або за допомогою абсолютного шляху (наприклад: /document/country/@title), або за допомогою відносного (наприклад: ../@title).

Шаблон з безумовним викликом викликають за допомогою інструкції call-template і, на противагу попередньому, абсолютно без жодних умов. Як наслідок, в інструкції й у шаблоні, який вона викликає, указують власну назву шаблона — name, а не умову його застосування.

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

Для того щоб краще зрозуміти шаблони, методи їхнього виклику й інші пов’язані із цим речі, пропоную створити невеликий практичний приклад. Створімо спочатку простенький XML-файлtemplates.xmlлише з кількома елементами.

<?xml version="1.0" encoding="UTF-8" ?><?xml-stylesheet type="text/xsl" href="templates.xsl" ?><document><element attribute="Значення атрибута елемента"><subelement>Значення дочірнього елемента</subelement></element></document>

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

<?xml version="1.0" encoding="UTF-8" ?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" indent="yes" encoding="UTF-8" media-type="text/html" /><xsl:template match="/document"><html><head><title>Шаблони</title></head><body><h1>Приклад головного шаблону</h1><div class="class1">...</div><!-- Приклад умовного виклику шаблону --><xsl:apply-templates select="element" /><!-- Приклад безумовного виклику шаблону --><xsl:call-template name="name1" /><!-- Приклад безумовного виклику шаблону з параметром --><xsl:call-template name="name2"><xsl:with-param name="title" select="'Приклад параметра до шаблона'" /></xsl:call-template></body></html></xsl:template><xsl:template match="element"><div class="class2"><h2>Приклад шаблону з умовним викликом</h2><em><xsl:value-of select="@attribute" /></em><p>...</p><!-- Приклад умовного виклику вкладеного шаблону в режимі mode1 --><xsl:apply-templates select="subelement" mode="mode1" /><!-- Приклад умовного виклику вкладеного шаблону в режимі mode2 --><xsl:apply-templates select="subelement" mode="mode2" /></div></xsl:template><xsl:template match="element/subelement" mode="mode1"><div class="class3"><h3>Приклад вкладеного шаблону з умовним викликом в режимі mode1</h3><em><xsl:value-of select="." /> (mode1)</em><p>...</p></div></xsl:template><xsl:template match="element/subelement" mode="mode2"><div class="class4"><h3>Приклад вкладеного шаблону з умовним викликом в режимі mode2</h3><em><xsl:value-of select="." /> (mode2)</em><p>...</p></div></xsl:template><xsl:template name="name1"><div class="class5"><h2>Приклад шаблону з безумовним викликом</h2><p>...</p></div></xsl:template><xsl:template name="name2"><xsl:param name="title" /><div class="class6"><h2>Приклад шаблону з безумовним викликом з параметром</h2><em><xsl:value-of select="$title" /></em><p>...</p></div></xsl:template></xsl:stylesheet>

А тепер найцікавіше — процес трансформації. Запускаємо створений нами XML-файлза адресоюі насолоджуємося нашою першою HTML-сторінкою, згенерованою за допомогою XSL-перетворення з боку клієнта за допомогою веб-оглядача.

Приклад роботи шаблонів в XSLT

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

Для того щоб усе-таки побачити HTML-код новоствореної сторінки, потрібно скористатися внутрішніми інструментами розроблення, які надає веб-оглядач (наприклад Chrome DevTools). Якщо ви зробили все правильно, то код вашої сторінки матиме приблизно такий вигляд:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Шаблони</title></head><body><h1>Приклад головного шаблону</h1><div class="class1">...</div><div class="class2"><h2>Приклад шаблону з умовним викликом</h2><em>Значення атрибута елемента</em><p>...</p><div class="class3"><h3>Приклад вкладеного шаблону з умовним викликом в режимі mode1</h3><em>Значення дочірнього елемента (mode1)</em><p>...</p></div><div class="class4"><h3>Приклад вкладеного шаблону з умовним викликом в режимі mode2</h3><em>Значення дочірнього елемента (mode2)</em><p>...</p></div></div><div class="class5"><h2>Приклад шаблону з безумовним викликом</h2><p>...</p></div><div class="class6"><h2>Приклад шаблону з безумовним викликом з параметром</h2><em>Приклад параметра до шаблона</em><p>...</p></div></body></html>

Решта інструкцій

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

XML

Але спочатку для демонстрації можливостей шаблона потрібно створити файл index.xml з певними структурою й даними.

<?xml version="1.0" encoding="UTF-8" ?><?xml-stylesheet type="text/xsl" href="index.xsl" ?><root title="Новини України та світу" copyright="2019"
      description="Самі свіжі та точні новини України та світу"><menu><item title="Домашня" description="Домашня сторінка сайту" section="home" /><item title="Новини" description="Стрічка новин" section="news" /><item title="Категорії" description="Перелік категорій публікацій" section="category" /><item title="Мітки" description="Список міток публікацій" section="tag" /><item title="Автори" description="Перелік авторів публікацій" section="user" /></menu><main /><notifications>&lt;p&gt;Редакція може не погоджуватись з автором публікації&lt;/p&gt;&lt;p&gt;Передрук частини публікації дозволено тільки за наявності посилання&lt;/p&gt;&lt;p&gt;Рекламні матеріали публікуються виключно з відповідною позначкою&lt;/p&gt;</notifications></root>

Стандарт XML, як і решта поширених форматів даних (CSV, YAML, JSON), настільки простий, що я не витрачатиму час на його опис. Лише в таблиці нижче наведу кілька прикладів найпоширеніших способів здійснення навігації в ієрархічній структурі за допомогою мови запитів XPath, яку, до речі, теж створили в W3C. Якщо вам цих прикладів буде замало, завжди можна підглянути в розділі «Синтаксис XPath».

/rootПряме звернення до кореневого елемента root
/root/@titleПряме звернення до атрибута titleкореневого елемента root
/root/menuЗвернення до дочірніх елементів menuбатьківського кореневого елементу root
/root/menu/*Звернення до нащадків батьківського елемента menuкореневого елемента root
menu/*/@titleВідносне звернення до атрибутів titleнащадків батьківського menu
menu/item[1]/@sectionВідносне звернення до атрибута sectionпершого дочірнього елемента itemбатьківського елемента menu

XSL

А тепер створимо файл шаблона index.xsl, у якому з метою ознайомлення використаємо найпоширеніші XSL-інструкції.

<?xml version="1.0" encoding="UTF-8" ?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" indent="yes" encoding="UTF-8" media-type="text/html" /><xsl:variable name="section" select="/root/@section" /><xsl:template match="/*"><xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html &gt;</xsl:text><html xml:lang="uk" lang="uk" dir="ltr"><head><title><xsl:value-of select="@title" /></title><meta name="description" content="{@description}" /><link href="/index.css" rel="stylesheet" /><script src="/index.js" type="application/javascript" /></head><body><header><xsl:call-template name="menu" /></header><main><h1><xsl:value-of select="@title" /></h1><div class="body {name(main/.)}"><xsl:apply-templates select="main/*" /></div></main><footer><div class="copyright"><p>Всі права застережено © <xsl:value-of select="@copyright" /></p></div><div class="notifications"><xsl:value-of select="notifications" disable-output-escaping="yes" /></div></footer></body></html></xsl:template><xsl:template name="menu"><nav><ul><xsl:for-each select="menu/item"><li><xsl:if test="@section=$section"><xsl:attribute name="class">active</xsl:attribute></xsl:if><a href="?section={@section}" title="{@title}"><xsl:value-of select="@title" /></a></li></xsl:for-each></ul></nav></xsl:template><xsl:template match="home">Домашня ...</xsl:template><xsl:template match="news">Новини ...</xsl:template><xsl:template match="category"><div id="index" class="index index-{name(.)}"><xsl:choose><xsl:when test="items/item"><xsl:for-each select="items/item"><p><strong><xsl:value-of select="@title" /></strong>
                            - <xsl:value-of select="@description" /></p></xsl:for-each></xsl:when><xsl:otherwise><p>Записів не знайдено</p></xsl:otherwise></xsl:choose></div></xsl:template><xsl:template match="tag">Мітки ...</xsl:template><xsl:template match="user">Автори ...</xsl:template></xsl:stylesheet>

Перше, що впадає в око тим, хто раніше не працював зі XSLT, — це те, як гармонійно його інструкції вписуються поміж HTML-розмітками. Цьому є просте пояснення: XML, HTML, XSLT і багато інших цікавих речей розробили World Wide Web Consortium, і їх реалізують у схожий спосіб. Тобто XSLT для HTML, на відміну від інших поширених шаблонизаторів, — споріднене середовище.

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

<meta name="description" content="{@description}" />

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

<xsl:value-of select="@title" /><xsl:value-of select="notifications" disable-output-escaping="yes"/>

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

<xsl:attribute name="class">active</xsl:attribute>

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

<xsl:variable name="section" select="/root/@section" />

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

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>

А ось цей елемент використовують доволі рідко, але я змушений його згадати принаймні через цей випадок. Річ у тому, що стандарт XSLT версії 1.0, який ми зараз використовуємо, розробили аж далекого 1999-го (за 15 років до створення стандарту HTML5). І, як наслідок, у ньому не передбачили нового методу оголошення версії HTML5 штатними засобами, як це зробили для попередніх версій HTML. Тому доводиться розв’язувати цю проблему за допомогою таких от хитрощів. З іншого боку, на цьому прикладі дуже просто продемонстрували принцип роботи атрибута disable-output-escaping.

<!-- Приклад інструкції одинарного умовного переходу --><xsl:if test="@section=$section">...</xsl:if><!-- Приклад інструкції множинного умовного переходу --><xsl:choose><xsl:when test="a &lt; b">...</xsl:when><xsl:when test="a &gt; b">...</xsl:when><xsl:otherwise>...</xsl:otherwise></xsl:choose><!-- Приклад інструкції перебору елементів з вхідного документа --><xsl:for-each select="menu/item">...</xsl:for-each>

Останні три інструкції я об’єднав в одному прикладі, оскільки ви їх і так добре знаєте: вони аналогічні операторам з інших мов програмування. Однак варто зазначити, що знаки «менше» чи «більше» (< чи >) водночас службові і їх використовують для позначення тегів. Тому в умовах інструкцій їх варто замінити на їхні HTML-сутності (&lt; чи &gt;).

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

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

XML + XSLT = HTML

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

Спочатку створимо index.css із трьома рядками, щоб надати меню більш-менш людського вигляду.

header nav ul {list-style: none;padding: 0;}
header nav ul li {display: inline;}
header nav ul li.active {font-weight: bold;}

Потім раджу створити файл index.js і додати в нього мінімум два рядки, щоб перевірити роботу JavaScript.

let time=new Date().toLocaleTimeString('uk-UA');
console.log('JavaScript завантажено успішно ['+time+']');

Якщо ми все робили правильно, то в кореневій теці нашого тестового сайту, окрім створених у попередніх розділах файлів templates.xml і templates.xsl, мають бути ще 4 файли: index.xml, index.xsl, index.css та index.js.

Тоді запускаємо раніше створений XML-файлі вже вдруге за сьогодні насолоджуємося магією XSLT.

Приклад роботи інших інструкцій XSLT

Цього разу вихідний HTML-файл має трохи цікавіший вигляд.

<!DOCTYPE html><html xml:lang="uk" lang="uk" dir="ltr" data-lt-installed="true"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Новини України та світу</title><meta name="description" content="Самі свіжі та точні новини України та світу"><link href="/index.css" rel="stylesheet"><script src="/index.js" type="application/javascript"></script></head><body><header><nav><ul><li><a href="?section=home" title="Домашня">Домашня</a></li><li><a href="?section=news" title="Новини">Новини</a></li><li><a href="?section=category" title="Категорії">Категорії</a></li><li><a href="?section=tag" title="Мітки">Мітки</a></li><li><a href="?section=user" title="Автори">Автори</a></li></ul></nav></header><main><h1>Новини України та світу</h1><div class="body main"></div></main><footer><div class="copyright"><p>Всі права застережено © 2019</p></div><div class="notifications"><p>Редакція може не погоджуватись з автором публікації</p><p>Передрук частини публікації дозволено тільки за наявності посилання</p><p>Рекламні матеріали публікуються виключно з відповідною позначкою</p></div></footer></body></html>

PHP + XML + XSLT = HTML

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

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

Ось невеличкий приклад того, як просто з ним працювати:

$xml = '<?xml version="1.0" encoding="UTF-8" ?><document time="" />';

$node = new SimpleXMLElement($xml);

$node['time'] = time();

$nodeCountry = $node->addChild('country');
$nodeCountry->addAttribute('title', 'Україна');
$nodeCountry->addAttribute('image', '/images/ua.jpg');

$nodeCity = $nodeCountry->addChild('city');
$nodeCity->addAttribute('title', 'Львів');
$nodeCity->addAttribute('image', '/images/lviv.jpg');

$nodeObject = $nodeCity->addChild('object', 'Опис ...');
$nodeObject->addAttribute('title', 'Львівська Опера');
$nodeObject->addAttribute('image', '/images/lviv-opera.jpg');

echo $node->asXML();

Спочатку за допомогою XML-рядками створили об’єкт SimpleXMLElement і встановили значення атрибута time в кореневому елементі. Потім за допомогою методів addChild та addAttributeдодали елементи й атрибути в потрібному нам місці ієрархічної структури документа. І, нарешті, за допомогою методу asXMLздійснили конвертацію об’єкта SimpleXMLElement у рядок та вивели його на перегляд.

<?xml version="1.0" encoding="UTF-8"?><document time="1566411359"><country title="Україна" image="/images/ua.jpg"><city title="Львів" image="/images/lviv.jpg"><object title="Львівська Опера" image="/images/lviv-opera.jpg">Опис ...</object></city></country></document>

Тут все настільки просто, що я навіть не знаю, що ще можна додати. Зрідка трапляється, коли обмеженого функціонала SimpleXMLElement бракує. Тоді по допомогу треба звертатися до надзвичайно просунутого й, відповідно, набагато складнішого розширення DOM (Document Object Model). Також варто звернути увагу на те, що для роботи з XML треба під’єднати в PHP розширення php_xml.

Нарешті, як приклад я створив маленький скрипт на PHP, який надасть сторінці динаміки.

// Отримаємо обраний розділ сайту
define('SECTION', ($_GET['section']) ?? '');

// Імітація отриманих даних з БД
$categories = [
    ['id' => '1', 'title' => 'Політика',    'description' => 'Політика опис ...'],
    ['id' => '2', 'title' => 'Економіка',   'description' => 'Економіка опис ...'],
    ['id' => '3', 'title' => 'Соціум',      'description' => 'Соціум опис ...'],
    ['id' => '4', 'title' => 'Культура',    'description' => 'Культура опис ...'],
    ['id' => '5', 'title' => 'Спорт',       'description' => 'Спорт опис ...']
];

// Відкриваємо XML-файл
$xml = file_get_contents('index.xml');
$node = new SimpleXMLElement($xml);

// Додаємо початкові дані до XML-файлу
$node->addAttribute('host', $_SERVER['HTTP_HOST']);
$node->addAttribute('request', $_SERVER['REQUEST_URI']);

try {

    // Оновлюємо, при потребі, дані поточної сторінки
    $node->addAttribute('section', SECTION);
    foreach($node->menu->item as $item) {
        if ($item['section'] == SECTION) {
            $node['title'] = $item['title'];
            $node['description'] = $item['description'];
        }
    }

    // Імпровізований міні-контролер
    switch(SECTION) {
        case '':
        case 'home': {
            $nodeHome = $node->main->addChild('home');
            // ...
        }; break;
        case 'news': {
            $nodeNews = $node->main->addChild('news');
            // ...
        }; break;
        case 'category':{
            $nodeCategory = $node->main->addChild('category');
            $nodeItems = $nodeCategory->addChild('items');
            foreach($categories as $category) {
                $xmlItem = $nodeItems->addChild('item');
                $xmlItem->addAttribute('id', $category['id']);
                $xmlItem->addAttribute('title', $category['title']);
                $xmlItem->addAttribute('description', $category['description']);
            }
        }; break;
        case 'tag': {
            $nodeTag = $node->main->addChild('tag');
            // ...
        }; break;
        case 'user': {
            $nodeUser = $node->main->addChild('user');
            // ...
        }; break;
        default: {
            $message = sprintf('Невідомий розділ сайту "%s"', SECTION);
            throw new Exception($message);
        }
    }
} catch (Exception $exception) {
    header('HTTP/1.x 404 Not Found');
    throw $exception;
}

header("Content-type: text/xml; charset=utf-8'");
echo $node->asXML();

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

Приклад роботи XSLT разом з PHP

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

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

Здійснити XSLT-перетворення PHP ми зможемо за допомогою об’єкта XSLTProcessor, який приймає XML як об’єкт DOMDocument. Тому перед XSLT-перетворенням треба здійснити конвертацію із SimpleXML у DOMDocument (SimpleXML -> DOMDocument -> XSLTProcessor). Як наслідок, доведеться замінити два останні рядки в нашому останньому прикладі на такий код:

$xmlDOM = new DOMDocument('1.0', 'UTF-8');
$xmlDOM->loadXML($node->asXML());

$xsl = new DOMDocument('1.0', 'UTF-8');
$xsl->load('index.xsl', LIBXML_NOCDATA);

$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsl);

header('Content-Type: text/html; charset=utf-8');
echo $xslt->transformToXML($xmlDOM);

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

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

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


iOS дайджест #33: Special — SwiftUI

$
0
0

В выпуске: SwiftUI vs. Auto Layout, ViewModifier, боковое меню и асинхронная загрузка изображений, MapView app, набор расширений.

Хочу узнать основы

SwiftUI Tutorials. Introducing SwiftUI
Было бы нечестно начинать подборку не с эплового туториала, учитывая, как круто они его сделали.

SwiftUI by Example
Пол Хадсон, известен своими туториалами и книгами, уже подоспел написать множество всего по SwiftUI. И, причем, в достаточно интересном формате — как показать список, как удалить ячейку, как закруглить углы и много-много другого.

SwiftUI vs. Auto Layout: Pros and Cons of Each Approach
Уже переписывать весь код на SwiftUI или еще подождать?

MVC without the C: What will SwiftUI change in app architecture?
MVC умер, да здравствует MVC! Как изменится архитектура приложений, написанных с помощью SwiftUI.

Swift Property Wrappers
Максимально исчерпывающая статья от NSHipster про property wrappers с примерами.

Understanding Property Wrappers in SwiftUI
Если лень читать лонгрид, то есть краткое описание встроенных property wrappers.

The power of Environment in SwiftUI
Более детально про @Environment property wrapper. И что более интересно — про DI с помощью него.

SwiftUI’s ViewModifier
Когда основы понятны, можно переходить к интересным моментам, а именно — как создавать свои модификаторы для вьюх.

Using Xcode Previews with existing views without using SwiftUI
Крутейшая штука при работе с SwiftUI — сразу же смотреть как выглядит вьюха. Причем, можно сделать несколько с разными наборами данных.

Хочу узнать детальней

SwiftUI: Paths vs. Shapes
Это все хорошо, но как нарисовать что-то кастомное?

Create a Side menu with SwiftUI
Или, например, боковое меню?

SDWebImageSwiftUI
А картинку асинхронно загрузить?

SwiftUI Generic Image Loading
А если не хочется использовать библиотеку для скачивания картинок, то можно написать самому.

Building a MapView app with SwiftUI
А как использовать не SwiftUI вьюхи в SwiftUI?

Collection: Making a Real World Application With SwiftUI
Ладно, это все детали, а как написать полноценное приложение на SwiftUI?

SwiftUI reusable Button style
Кастомизируем кнопки.

Хочу посмотреть, как пишут другие

Burritos
Огромный набор property wrappers. Посмотреть, чтобы научиться писать свои.

ChartView
Библиотека для отрисовки графиков с анимациями.

Building BarChart with Shape API in SwiftUI
И небольшая статья с описанием, как рисуют графики.

Introducing Container views in SwiftUI
Контейнеры и переиспользование вьюх.

SwiftUIX
Набор расширений для SwiftUI. Опять же, полезно, чтобы сделать что-то свое.


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

Корупція в ІТ-вишах 2019: хабарництво при вступі зменшилося втричі після введення ЗНО

$
0
0

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

Портрет учасників опитування

Корупція в ІТ-вишах на середньому по країні рівні

За даними загальнонаціонального дослідження «Корупція в Україні», проведеного в липні-серпні 2018 року, корупція входить до числа найбільших проблем в Україні: 94 % громадян віком від 18 років вважають її дуже серйозною чи скоріше серйозною проблемою країни. Насамперед громадяни занепокоєні корупцією у вищих ешелонах влади (93 %), але проблема побутової корупції — в освіті, медицині, взаємодії з різними державними органами, також є дуже серйозною чи скоріше серйозною проблемою для 82 % громадян України.

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

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

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

Стикалися з корупцією*Не стикалися
Київ48%52%
Харків68%32%
Львів75%25%
Одеса75%25%
Дніпро79%21%
Загалом63%37%
*Стикалиcя з корупцією особисто чи знають людей, що стикалися


Практично відсутня корупція в НаУКМАта УКУ. Менше чверті тих, хто навчався або ще вчиться в ЧНУ ім. Петра Могилита КНУ ім. Шевченкаособисто стикалися з корупцією чи знають когось, хто стикався.

ЗВО / факультетСтикалися з корупцією*Не стикалися
НаУКМА2%98%
Факультет інформатики0%100%
Український католицький університет2%98%
ЧНУ ім. Петра Могили16%84%
Факультет комп’ютерних наук15%85%
КНУ ім. Шевченка20%80%
Факультет комп’ютерних наук і кібернетики23%77%
ДонНУ ім. В. Стуса34%66%
ХНЕУ ім. Кузнеця37%63%
Факультет економічної інформатики35%65%
СумДУ49%51%
КПІ ім. Сікорського49%51%
ІПСА31%69%
ФПМ31%69%
ФІОТ55%45%
ТЕФ80%20%
ДУТ51%49%
ХПІ67%33%
ЧНУ ім. Федьковича68%32%
ХНУ ім. Каразіна69%31%
ХАІ70%30%
ЛНУ ім. І. Франка71%29%
ХНУРЕ75%25%
Факультет комп’ютерних наук (КН)71%29%
Факультет комп’ютерної інженерії та управління (КІУ)76%25%
ДНУ ім. О. Гончара81%19%
Факультет прикладної математики87%13%
ОНПУ87%13%
Інститут комп’ютерних систем85%15%
НАУ87%13%
Інститут комп’ютерних інформаційних технологій90%10%
Львівська Політехніка90%10%
Інститут комп’ютерних наук та інформаційних технологій90%10%
Інститут комп’ютерних технологій, автоматики і метрології92%9%
ВНТУ93%7%
Факультет інформаційних технологій і комп’ютерної інженерії90%10%
Інші77%23%
Загалом63%37%
*Стикалиcя з корупцією особисто чи знають людей, що стикалися


Непогані (на загальному фоні) показники в ДонНУ ім. Стусата ХНЕУ ім. Кузнеця: там з корупцією стикалися біля третини студентів (34 % та 37 % відповідно).

Схожа ситуація на двох факультетах КПІ — ФПМ та ІПСА (31 % студентів цих факультетів згадали про випадки корупції). Проте загалом біля половини студентів та випускників КПІ стикалися з фактами корупції під час навчання (49 %), при чому серед випускників та студентів ТЕФ їх виявилося аж 80 %.

На одному рівні з КПІ корупція в СумДУ (49 %) та ДУТ (51 %).

У харківських ІТ-вишах біля ⅔ студентів та випускників пригадали про факти корупції під час вступу чи навчання: 67 % в ХПІ, 69 % в ХНУ ім. Каразіна, 70 % в ХАІ. Дещо вищі показники в ХНУРЕ — 75 %.

На одному рівні з харківськими вишами за рівнем корупції перебувають й західноукраїнські виші: Чернівецький університет ім. Федьковича (68 % студентів та випускників згадали про факти корупції) та ЛНУ ім. Франка (71 %).

У деяких університетах практично всі опитані нами студенти та випускники змогли згадати про факти корупції під час вступу чи навчання: 93 % тих, хто вчився чи ще навчається у ВНТУ, 90 % у Львівській Політехніці, по 87 % в НАУта ОНПУ, 81 % в ДНУ ім. Гончара.

ЗНО зменшило корупцію при вступі в ІТ-виші

Студенти ІТ-спеціальностей стикаються з корупцією переважно в процесі навчання, у той час як корупція при вступі помітно зменшилася після введення ЗНО у 2008 році.

В яких ситуаціях стикаються з корупцією в ІТ-вишах

25 % випускників вишів, які вступали до введення ЗНО і випустилися до 2012 року, особисто зіштовхнулися з корупцією при вступі чи знають когось, хто стикався. А серед тих, хто вступав до ІТ-вишу після 2012 року, таких лише 13 %, при чому ми й далі спостерігаємо спадний тренд (серед тих, хто випуститься у 2019 році чи пізніше, лише 7 % згадали про факти корупції при вступі у виш).

Корупція, яка виникає в процесі навчання, на жаль, набагато поширеніша, і її розповсюдженість практично не змінилася за останні роки. В опитуванні щодо вишів, яке проходило у квітні-травні 2019 року, 63 % студентів та випускників ІТ-вишів згадали про факти корупції під час навчання. Навіть Революція Гідності не мала значного впливу на цей показник — 59 % тих, хто вступав у виш у 2013 році чи пізніше, згадували про корупцію під час навчання.

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

Як часто стикаються з корупцією в ІТ-вишах

Корупція це погано, але іноді зручно

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

Частка тих, хто стикався з корупцією в ІТ-виші, в залежності від причин вступу

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

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

Готовність рекомендувати свій виш / факультет

За боротьбу з корупцією відповідає вища влада країни

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

На думку респондентів, з корупцією насамперед має боротися Президент України (так вважає 63 % опитаних), Верховна Рада (44 % опитаних) та Кабінет Міністрів (30 % опитаних). Тільки 11 % опитаних вважають, що самі громадяни повинні боротися з корупцією.

Найефективнішими шляхами подолання корупції опитані вважають забезпечення невідворотності покарання за корупційні злочини (58 %), а також звільнення чиновників та посадових осіб, які вчинили корупційні дії (53 %).


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


Читайте також «Вступна кампанія 2019: КПІ лідирує за кількістю заяв, а УКУ — за найвищим середнім балом абітурієнтів»

Нужны ли программисту алгоритмы и структуры данных

$
0
0

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

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

Денис Цьоменко с докладом «Зачем мне знать алгоритмы, если они все уже реализованы?» на RunIT в Днепре, май 2019

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

Мысль противоположной стороны выражается так: «Через 5-7лет 80% задач, которые необходимы при разработке продукта, смогут выполнять школьники 13-14 лет,которые закончили качественные курсы. Но компаниям нужны инженеры, способные решить остальные 20%». Это могут быть знания и в математической статистике, и в алгебре, и в теории программирования. Но фундамент, в любом случае, строится на знаниях алгоритмов и структур данных.

Поэтому собеседования в FAANGили MINTна 60%-100% состоят из Problem Solving задач, для решения большинства которых нужны знания алгоритмов. Сейчас этот тренд переходит и на middle-size компании в мире и в Украине. Из личного опыта могу сказать, что я писал на С++, .NET и Python. И вне зависимости от языка, я использовал знания алгоритмов.

«Нельзя доверять коду, который вы не написали полностью сами», — Кен Томпсон.

Алгоритмы на собеседованиях

В каждой компании есть свой подход к собеседованиям и оценке кандидатов. Также отличаются цели найма. Но есть вещи, которые их объединяют. Я проходил собеседования в различные компании разных размеров и направлений. Где-то алгоритмы и решение задач были ключевым фактором, где-то — вспомогательным. Задачи могут быть разных уровней сложности. Например, самая простая из тех, что мне встречались, — развернуть строку без использования дополнительной памяти. Одна из задач сводилась к умению быстро считать максимальное значение функции xor на префиксном дереве (бор). Ее сложность скорее заключалась в неочевидном решении, чем в реализации. Хорошая задача на собеседовании должна иметь несколько возможных решений, кроме оптимального. Невозможно знать все.

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

Большие корпорации

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

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

Пройти такое собеседование помогут даже не знания алгоритмов, а количество решенных типичных задач. Важно понимать, что правильное решение не всегда гарантирует успешное прохождение собеседования. Точно также, как и неоптимальное решение не гарантирует отказ. Люди хотят работать с людьми, а не с машинами для написания кода, поэтому хотят посмотреть, как Вы думаете и говорите. В развитии этого навыка очень помогают пробные интервью. Вы можете проводить их с другом, коллегой или на различных ресурсах, где можно провести и пройти интервью со случайными людьми. Классическим же мануалом по прохождению в большие корпорации является книга «Cracking the Coding Interview». И если Вы хотите попасть в одну из них, то советую прочитать.

Минимальный набор знаний для прохождения интервью в большие компании

Структуры данныхАлгоритмыКонцепты
Стэк/очередьБинарный поискБитовые операции
СпискиBFS/DFSПамять (Stack vs Heap)
Хэш-таблицыСортировки (quick, merge, stable, bucket)Рекурсия
СпискиBFS/DFSДинамическое программирование
Деревья, графыBig-O notation

Средние компании

Опыт лучших перенимают и организации, которые гонятся за ними. В Украине существует минимум 3 компании, которые фокусируются на problem solving interview (DataRobot, Ring Labs, Grammarly). Еще большая часть включают их в свой процесс собеседований как вспомогательные.

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

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

Стартапы

Любой успешный стартап — это не только крутая идея, но и качественная реализация. В самом начале пути, когда пишется PoC (Proof of Concept), можно игнорировать и архитектуру, и оптимизацию. В таком случае при развитии и расширении стартапа придется выделить время на переписывание/ доработку/ рефакторинг.

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

На этой волне можно вспомнить статьюоб украинском стартапе Looksery, который был основан людьми, связанными с олимпиадами. Они и набирали себе подобных: призеров и участников ACM ICPC (студенческая командная олимпиада), финалистов IOI (олимпиада для школьников), ребят с высоким рейтингом на CodeForces или TopCoder. Чем закончилась эта история, думаю, все осведомлены, или могут узнать по ссылке выше.

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

Аутсорс

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

Я ни разу не встречал людей, у которых спрашивали problem solving в аутсорсе. В маленьком /среднем/ крупном — не важно.

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

Если у Вас есть истории о прохождении problem solving interview в аутсорсе — поделитесь в комментариях. Будем надеяться на лучшее.

Использование алгоритмов в реальной разработке

За свою карьеру в различных компаниях в трех странах (США, Германия, Украина) я, так или иначе, сталкивался с алгоритмами. Иногда это неявное использование с применением стандартных библиотек, иногда — явная реализация. Даже обычное наследование — это, по сути, граф взаимосвязей между классами. Получается, что каждый день на работе программисты используют какой-то алгоритм или структуру данных. Хэш-таблицы, сортировка, алгоритмы поиска и другие популярные алгоритмы уже реализованы в большинстве популярных языках. И чем лучше понимание как эти алгоритмы реализованы внутри, тем легче будет найти эффективное применение и не встретить неожиданные баги, которые сложно отследить. Два моих любимых примера, которые встречались не один раз, это возгласы: «Почему так долго?» при использовании хэш-таблиц. И второй пример — это флейк тестов при использовании сортировки.

Типичный пример 1

Дано:длинные строки примерно такой структуры: «{время}. {много информации о том, что произошло в этот момент времени}» (структура может отличаться). Для каждой строки нужно посчитать какое-то значение. Например: сколько раз ее просматривали, редактировали и т.д.

Программист решает использовать стандартный dictionary, HashTable, unordered_set, в зависимости от языка. Но «под капотом» — это и есть хэш-таблица.

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

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

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

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

Что делать?

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

Типичный пример 2

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

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

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

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

Что делать?

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

Также поможет использование стабильных сортировок. Например: stable_sort в С++, Enumerable.OrderBy в .Net, sorted в Python (после версии 2.2) или подобное на вашем любимом языке. Даже если стандартная библиотека не содержит стабильную сортировку, напишите сами.

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

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

Хочешь сделать хорошо — сделай это сам

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

Задача 1

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

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

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

Дерево отрезков дает возможность обновлять данные за O(logN), получать показатели для последовательной группы людей тоже за О(logN). Да, нагрузка на память увеличилась за счет того, что нужно хранить два таких дерева (для максимума и для суммы), и они занимают в 4 раза больше места, чем массив с данными. Но в моем случае это было не критично.

Почему не использовать готовую реализацию?

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

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

Примитивное дерево отрезков для функции минимума

Результат

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

Задача 2

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

Пример графа для поиска максимального потока

Решение

При решении схожей задачи у меня не было представления о линейной алгебре и транспортной задаче. Но я слышал об алгоритме Min Cost Max Flow.

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

С изменениями, но для решения этого применялся алгоритм поиска минимальной стоимости максимального потока.

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

Результат

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

Задача 3. Разбор логов сервера

Дано:Файл логов 100 МБ+. Нужно наладить быстрый поиск по этому файлу. Слова и фразы поиска — это коды, тексты ошибок и ID пользователей (короткие строки).

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

Результат

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

Как я пришел к изучению алгоритмов и советы

Честно признаюсь, мне повезло. Я пришел в разработку и начал осваивать архитектурные и технические подходы после изучения алгоритмов и решения 1000+ задач на различных ресурсах. И мой путь выглядел примерно так: видишь задачу -> не знаешь, как решать -> изучаешь, реализовываешь, модифицируешь подходящий алгоритм.

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

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

  • LeetCode. Тут собрано много задач и подборок от easy до hard уровня. Для каждой задачи доступен discuss, где люди делятся идеями решений и реализацией на различных языках.
  • InterviewBit. Здесь задачи разделены по уровням и темам. Также можно установить количество дней до интервью и видеть свой прогресс. Плюс для каждой задачи представлены подсказки и решения.

Существуют также ресурсы, которые предлагают обучение в более игровой форме. Например: Codewarsили Code in game.

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

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

Выводы

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

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

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

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

Алгоритмы и структуры данных помогут вам продвинуться в карьере. На конференции RunIT в Днепре, где я выступал с этой темой, человек в зале привел простой пример: «Однажды за то, что я сумел решить задачу о перемещении шахматного коня из одной клетки в другую за наименьшее количество шагов, мне подняли зарплату на 500 $». Чего и вам желаю.

IT-шники-волонтери: як дизайнер із Чернігова бореться за дерев’яні будинки з мереживом

$
0
0

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

UX/UI-дизайнер Станіслав Іващенкостворив проект «Дерев’яне мереживо Чернігова», щоб привернути увагу суспільства до цієї проблеми й зберегти будинки.

Мене звати Стас, я виріс і живу в Чернігові. Чотири роки займаюся UX/UI-дизайном на фрилансі: малюю веб і мобільні інтерфейси, іноді логотипи. Раніше працював у мобільному стартапі на менеджерській посаді. Тепер також веду віддалено кілька проектів. Обожнюю свою роботу, особливо UX-частину, бо це аналітична професія, а мені подобається вирішувати логічні задачки клієнтів.

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

Будинки, що не потрібні місту

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

Будинок купця Гозенпуда

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

Кожен регіон України історично має певні культурні особливості, зокрема це виявляється в архітектурі. Наприклад, на Поліссі й Чернігівщині дерево завжди використовували як основний матеріал для будівництва. Такої кількости дерев’яних будинків з мереживом ХІХ—ХХ століть ви не знайдете ані у Львові, ані в Харкові чи Вінниці.

Мене дивувало, що попри війну й любов до бетонних коробок у Радянському Союзі, у нас збереглася така кількість дерев’яних будівель. Лише в Чернігові є щонайменше 200 вартих уваги дерев’яних будинків. В області ж їх тисячі.

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

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

Проект «Дерев’яне мереживо Чернігова»: галерея, гід, історик

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

Я виростав, волонтерив, подорожував, працював і вів присвячений будинкам акаунт в Instagram. Одного разу трапився випадок, після якого переживання щодо долі будинків перетворилися на проект. 2018 року я запостив у Facebook три скриншоти з Instagram’у з підписом: «Чернігівці, чи ви колись помічатимете й цінуватимете те, що вас оточує? Чи дочекаємося, поки воно зникне?» На превеликий подив, цей допис за три дні отримав близько 300 поширень і чимало коментарів. Я зрозумів, що не лише мені цікава ця тема, якщо стільки людей не залишилося байдужими до допису.

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

Я зібрав команду з друзів, і хоча їх дерев’яні будинки особливо не цікавили, вони пристали на ідею, бо розуміли, яке значення проект матиме для рідного міста. Основа команди — це Леонід Скрипка (Backend-програміст), Олексій Самойленко (Frontend-програміст) і Тетяна Романюк, яка дуже просунула нас у дослідженні історії будинків. Я керую проектом, продумую його розвиток, вигляд і поведінку сайту, збираю інформацію, знаходжу будинки й наповнюю ресурс контентом.

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

Ми запустили сайтза 5 місяців, 2 липня 2018 року, відразу зі світлинами 160 будинків Чернігова. Для 25 з них удалося зібрати історичну довідку. Сайт вийшов відразу п’ятьма мовами: українською, німецькою, польською, білоруською й англійською. Написано сайт на PHP і JS.

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

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

Сайт має 3 функції:

  1. Галерея.Це первісна ідея проекту: зібрати в одному місці красиві будинки та дати широку й повну картину їхньої кількости в Чернігові й області. Мешканці, туристи, власники й міська влада побачать, що це важливо, що це потрібно берегти й про це варто говорити.

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

    Оскільки я все життя гуляю цими будинками, то знаю, як скласти маршрут прогулянки так, щоб за досить короткий час побачити максимум. Тому ми створили 5 маршрутів від 1,5 до 6 км завдовжки, якими туристи й мешканці можуть користуватися. З описами маршрутів нам допомогла відома в місті Facebook-сторінка «Цікавий Чернігів». Завдяки її авторам ви можете ознайомитися із цікавинками кожного маршруту, перш ніж розпочати прогулянку.

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

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

Скриншот із сайту

Будинки з історіями

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

«Інтеграція»

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

Будинок Дроздова

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

Будинок-переселенець

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

Будинок-переселенець

Будинок на двох вулицях

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

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

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

Будинок, що стоїть одночасно на двох вулицях

Від онлайн до офлайн: урятований дворянський будинок

Коли ми запустили сайт, він відразу зацікавив багатьох людей. Про «Дерев’яне мереживо» почали писати й знімати сюжети місцеві, а згодом і національні ЗМІ. Навіть деякі власники будинків почули про проект, зайшли на сайт, знайшли свій будинок і розповіли нам його історію. Це було схоже на снігову кулю, яка перетворилася на великого сніговика.

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

І ось навесні 2019 року мене запросили на толоку до села Старий Білоус. Там я познайомився з пані Оленою Малишко.

Сама вона з Києва, але в Старому Білоусі 2008 року знайшла й викупила будинок своїх предків-дворян. Річ у тім, що з приходом комуністів дворяни змушені були тікати, а їхні будинки підлягали експропріації. Тепер пані Олена перетворює будинок на музей.

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

Садиба Березовських у Старому Білоусі

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

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

Волонтерство в Старому Білоусі

Роботу щодо його відновлення, яка триває й нині, ми розпочали на початку червня. До середини серпня виконано майже 90% запланованих робіт. Зазвичай ми приїжджаємо у вихідні й працюємо поодинці або вдвох-трьох. Іноді зорганізовуємо масові толоки. Усього на фасаді флігеля 3 види мережива по 7,5 м кожне. З двома видами ми вже завершили й тепер працюємо над третім рядом.

Нове мереживо для будинку в Старому Білоусі

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

Бігова екскурсія дерев’яними будинками

Плани

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

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

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

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

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

Отображение списков с помощью UICollectionViewCompositionalLayout в iOS

$
0
0

В этом году Apple провела «взрывную» WWDC. Все сообщество iOS-разработчиков сфокусировалось на новых фреймворках (SwiftUI, Combine, RealityKit...), пытаясь разобраться, как это работает и что нового принесет. Многие небольшие, но очень полезные для актуальных приложений обновления почему-то остались за кадром. Тем не менее я хочу поделиться моими исследованиями одного из них — UICollectionViewCompositionalLayout.

Я уверен, каждый из начинающих iOS-разработчиков начинал свое обучение с изучения списков. Это тот незаменимый UI-элемент, который присутствует практически в каждом приложении. UICollectionView — это эволюционировавший UITableView, который позволяет размещать элементы списка в разном порядке с помощью UICollectionViewLayout. Тот, кто хоть раз пробовал создать свой кастомный CollectionViewLayout, знает, как это непросто. Мы имеем море методов, с помощью которых нужно задать поведение. Не все их нужно использовать, иногда нужно написать дополнительное кеширование. Все это создает сложности, с которыми редко какой разработчик хочет столкнуться. Вот почему в этом году Apple представила класс, который продолжает направление декларативного программирования, — UICollectionViewCompositionalLayout.

UICollectionViewCompositionalLayout — это Layout, с помощью которого можно задать поведение элементов при отображении их в UICollectionView. После того как будет сформулировано, как отображать эти элементы, Layoutсделает всю остальную работу за нас. То есть уже не нужно будет заботиться о всех тех методах, которые нужно имплементировать при расширении класса UICollectionViewLayout.

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

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .absolute(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])

        let section = NSCollectionLayoutSection(group: group)

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

Далее я рассмотрю все классы, которые участвуют в построении этого Layout.

NSCollectionLayoutSize

NSCollectionLayoutSizeпозволяет задать ширину и высоту элемента в Layout. Имеет две переменные, которые задаются при инициализации:

open var widthDimension: NSCollectionLayoutDimension { get }
open var heightDimension: NSCollectionLayoutDimension { get }

NSCollectionLayoutDimension, в свою очередь, позволяет задать размер в четырех вариантах:

//dimension is computed as a fraction of the width of the containing group
    open class func fractionalWidth(_ fractionalWidth: CGFloat) -> Self

     //dimension is computed as a fraction of the height of the containing group
    open class func fractionalHeight(_ fractionalHeight: CGFloat) -> Self
    // dimension with an absolute point value
    open class func absolute(_ absoluteDimension: CGFloat) -> Self

     // dimension is estimated with a point value. Actual size will be determined when the content is rendered.
    open class func estimated(_ estimatedDimension: CGFloat) -> Self

fractionalWidth — размер относительно ширины группы или контейнера, который содержит группу.
fractionalHeight — размер относительно высоты группы или контейнера, который содержит группу.
absolute — абсолютное значение в пойнтах.
estimated — предположительное значение в пойнтах; реальное значение будет установлено в зависимости от контента.

Есть одна интересная особенность: в NSCollectionLayoutSize.widthDimensionмы можем задавать fractionalHeight и, наоборот, в NSCollectionLayoutSize.heightDimension — относительную ширину (fractionalWidth). То есть, например, NSCollectionLayoutSize.heightDimension = .fractionalWidth(0.5) — высота элемента равна половине ширины группы.

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

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

Ниже приведен пример Layoutдля списка, в котором автоматически рассчитываются размеры элементов.

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .estimated(50))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil, top: .fixed(8), trailing: nil, bottom: .fixed(8))
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .estimated(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])

        let section = NSCollectionLayoutSection(group: group)

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

NSCollectionLayoutItem

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

open var contentInsets: NSDirectionalEdgeInsets
     open var edgeSpacing: NSCollectionLayoutEdgeSpacing?

contentInsetsотвечает за отступы элемента, после того как он уже размещен в Layout. Как отмечено выше, не стоит использовать эти отступы с предположительными размерами элемента (.estimated).

edgeSpacingболее интересен, потому что это отдельный класс NSCollectionLayoutEdgeSpacing. В этом классе можно задать отступы leading, top, trailing, bottom, но с помощью NSCollectionLayoutSpacing. Эти отступы учитываются при размещении элемента в Layout. Можно использовать два вида отступов:

open class func flexible(_ flexibleSpacing: CGFloat) -> Self // i.e. >=
open class func fixed(_ fixedSpacing: CGFloat) -> Self // i.e. ==

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

В качестве примера я приведу Layout, в котором с помощью edgeSpacingрасположил два столбца элементов посредине:

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4),
                                              heightDimension: .fractionalHeight(1))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: .flexible(0), top: nil,
                                                         trailing: .flexible(16), bottom: nil)
        let itemSize2 = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4),
                                              heightDimension: .fractionalHeight(1))
        let item2 = NSCollectionLayoutItem(layoutSize: itemSize2)
        item2.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil, top: nil,
                                                          trailing: .flexible(0), bottom: nil)

        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .absolute(60))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item, item2])

        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = 10

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

NSCollectionLayoutGroup

NSCollectionLayoutGroupрасширяет NSCollectionLayoutItem, добавляя возможность хранить несколько элементов, группируя их. У секции может быть только одна группа. Количество групп в Layoutопределяется количеством элементов в секции, которые отдает datasource. То есть, допустим, у нас есть одна группа, в которой находится один элемент, datasourceговорит нам, что в секции десять элементов, значит, будет отрисовано десять групп. Если элементов в группе два, будет пять групп. Группы могут быть вертикальными и горизонтальными, хранить несколько элементов одного типа или разных типов. Задавать расстояние между элементами в группе можно с помощью переменной interItemSpacing.

open class func horizontal(layoutSize: NSCollectionLayoutSize, subitem: NSCollectionLayoutItem, count: Int) -> Self

    open class func horizontal(layoutSize: NSCollectionLayoutSize, subitems: [NSCollectionLayoutItem]) -> Self

    open class func vertical(layoutSize: NSCollectionLayoutSize, subitem: NSCollectionLayoutItem, count: Int) -> Self

    open class func vertical(layoutSize: NSCollectionLayoutSize, subitems: [NSCollectionLayoutItem]) -> Self

    open var interItemSpacing: NSCollectionLayoutSpacing?

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

open class NSCollectionLayoutGroupCustomItem : NSObject, NSCopying {

    public convenience init(frame: CGRect)

    public convenience init(frame: CGRect, zIndex: Int)
    
    open var frame: CGRect { get }

    open var zIndex: Int { get }
}

public typealias NSCollectionLayoutGroupCustomItemProvider = (NSCollectionLayoutEnvironment) -> [NSCollectionLayoutGroupCustomItem]

open class func custom(layoutSize: NSCollectionLayoutSize, itemProvider: @escaping NSCollectionLayoutGroupCustomItemProvider) -> Self

NSCollectionLayoutGroupCustomItem — это простой объект, в котором нужно установить позицию объекта относительно контейнера. В блоке кода NSCollectionLayoutGroupCustomItemProviderна вход нам придет NSCollectionLayoutEnvironment, который содержит размер контейнера, а также его UITraitCollection. Более подробно мы рассмотрим этот класс чуть позже.

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

private func createLayout() -> UICollectionViewLayout {
        let verticalItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                                      heightDimension: .fractionalHeight(0.3))
        let verticalItem = NSCollectionLayoutItem(layoutSize: verticalItemSize)

        let verticalGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.25),
                                                       heightDimension: .fractionalHeight(1))
        let verticalGroup = NSCollectionLayoutGroup.vertical(layoutSize: verticalGroupSize,
                                                             subitem: verticalItem, count: 3)
        verticalGroup.interItemSpacing = .fixed(8)
        // ---------------------------------------------------------------------------------
        let horizontalItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.25),
                                                      heightDimension: .fractionalHeight(1))
        let horizontalItem = NSCollectionLayoutItem(layoutSize: horizontalItemSize)
        let horizontalItemSize2 = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4),
                                                      heightDimension: .fractionalHeight(1))
        let horizontalItem2 = NSCollectionLayoutItem(layoutSize: horizontalItemSize2)

        let horizontalGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                                    heightDimension: .fractionalHeight(0.3))
        let horizontalGroup = NSCollectionLayoutGroup.horizontal(layoutSize: horizontalGroupSize,
                                                             subitems: [horizontalItem, horizontalItem2, horizontalItem])
        let horizontalGroup2 = NSCollectionLayoutGroup.horizontal(layoutSize: horizontalGroupSize,
                                                                  subitems: [horizontalItem2, horizontalItem, horizontalItem])
        let horizontalGroup3 = NSCollectionLayoutGroup.horizontal(layoutSize: horizontalGroupSize,
                                                                  subitems: [horizontalItem, horizontalItem, horizontalItem2])
        horizontalGroup.interItemSpacing = .fixed(8)
        horizontalGroup2.interItemSpacing = .fixed(8)
        horizontalGroup3.interItemSpacing = .fixed(8)
        // ---------------------------------------------------------------------------------
        let horizontalsGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.75),
                                                       heightDimension: .fractionalHeight(1))
        let horizontalsGroup = NSCollectionLayoutGroup.vertical(layoutSize: horizontalsGroupSize,
                                                             subitems: [horizontalGroup, horizontalGroup2, horizontalGroup3])
        horizontalsGroup.interItemSpacing = .flexible(0)
        // ---------------------------------------------------------------------------------

        let finalGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                                    heightDimension: .fractionalHeight(0.5))
        let finalGroup = NSCollectionLayoutGroup.horizontal(layoutSize: finalGroupSize,
                                                            subitems: [horizontalsGroup, verticalGroup])

        let section = NSCollectionLayoutSection(group: finalGroup)
        section.interGroupSpacing = 8

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

NSCollectionLayoutSection

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

open var contentInsets: NSDirectionalEdgeInsets
 open var interGroupSpacing: CGFloat

Кроме этого, у нее есть два интересных свойства:

open var orthogonalScrollingBehavior: UICollectionLayoutSectionOrthogonalScrollingBehavior
open var visibleItemsInvalidationHandler: NSCollectionLayoutSectionVisibleItemsInvalidationHandler?
public typealias NSCollectionLayoutSectionVisibleItemsInvalidationHandler = ([NSCollectionLayoutVisibleItem], CGPoint, NSCollectionLayoutEnvironment) -> Void

visibleItemsInvalidationHandler — это блок кода, который вызывается перед прорисовкой элементов. Как его использовать, я пока не нашел. Как вариант, можно всегда знать, какие элементы на экране, и знать offsetтекущего списка. При необходимости можно поменять свойства элементов (frame, alpha, zIndex...).

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

Есть 5 вариантов скролла:

// Standard scroll view behavior: UIScrollViewDecelerationRateNormal
    case continuous

    // Scrolling will come to rest on the leading edge of a group boundary
    case continuousGroupLeadingBoundary

    // Standard scroll view paging behavior (UIScrollViewDecelerationRateFast) with page size == extent of the collection view's bounds
    case paging

    // Fractional size paging behavior determined by the sections layout group's dimension
    case groupPaging

    // Same of group paging with additional leading and trailing content insets to center each group's contents along the orthogonal axis
    case groupPagingCentered

Вот пример кода с continuous-типом:

private func listSection() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .absolute(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])

        return NSCollectionLayoutSection(group: group)
    }

    private func gridSection() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                               heightDimension: .fractionalHeight(0.3))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitem: item, count: 3)
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .continuous
        return section
    }

    private func createLayout() -> UICollectionViewLayout {
        return UICollectionViewCompositionalLayout { sectionNumber, env -> NSCollectionLayoutSection? in
            switch Section(rawValue: sectionNumber) {
            case .main:
                return self.listSection()
            case .second:
                return self.gridSection()
            default:
                return nil
            }
        }
    }

UICollectionViewCompositionalLayout

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

public init(section: NSCollectionLayoutSection)

    public init(section: NSCollectionLayoutSection, configuration: UICollectionViewCompositionalLayoutConfiguration)


    public typealias UICollectionViewCompositionalLayoutSectionProvider = (Int, NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection?  
    public init(sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider)

    public init(sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider, configuration: UICollectionViewCompositionalLayoutConfiguration)

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

NSCollectionLayoutSupplementaryItem, NSCollectionLayoutBoundarySupplementaryItem, NSCollectionLayoutDecorationItem

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

NSCollectionLayoutSupplementaryItemможет использоваться для элемента и группы, он наследуется от NSCollectionLayoutItem. Основное их отличие от элементов — это то, как их располагают в Layout. За это отвечает отдельный класс NSCollectionLayoutAnchor. Указанный элемент располагается поверх основного, поэтому мы можем привязать его к сторонам элемента с помощью этого класса. Звучит немного страшно, но на практике легко, вот пример из документации.

//                       +------------------+  +------+   +------------------+
    //                       | [.top, .leading] |  |[.top]|   | [.top,.trailing] |
    //                       +--+---------------+  +---+--+   +---------------+--+
    //                          |                      |                      |
    //                          v                      v                      v
    //                       +-----+----------------+-----+----------------+-----+
    //                       |~~~~~|                |~~~~~|                |~~~~~|
    //                       |~~~~~|                |~~~~~|                |~~~~~|
    //                       +-----+                +-----+                +-----+
    //                       |                                                   |
    //                       +-----+                                       +-----+
    //   +--------------+    |~~~~~|                                       |~~~~~|    +-------------+
    //   |  [.leading]  |--->|~~~~~|                                       |~~~~~|<---| [.trailing] |
    //   +--------------+    +-----+                                       +-----+    +-------------+
    //                       |                                                   |
    //                       +-----+                +-----+                +-----+
    //                       |~~~~~|                |~~~~~|                |~~~~~|
    //                       |~~~~~|                |~~~~~|                |~~~~~|
    //                       +-----+----------------+-----+----------------+-----+
    //                          ^                      ^                      ^
    //                          |                      |                      |
    //                      +---+---------------+ +----+----+  +--------------+----+
    //                      |[.bottom, .leading]| |[.bottom]|  |[.bottom,.trailing]|
    //                      +-------------------+ +---------+  +-------------------+
    //
    // Edges are specified as shown above.
    public convenience init(edges: NSDirectionalRectEdge)

К этому расположению мы можем добавить offset.

public convenience init(edges: NSDirectionalRectEdge, absoluteOffset: CGPoint)

public convenience init(edges: NSDirectionalRectEdge, fractionalOffset: CGPoint)

А вот и пример, в котором я прикрепил к группе дополнительную галочку:

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, 
                                                     bottom: 8, trailing: 8)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                               heightDimension: .fractionalHeight(0.2))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitem: item, count: 3)
        let suppItemSize = NSCollectionLayoutSize(widthDimension: .absolute(45),
                                                  heightDimension: .absolute(45))
        let suppItemPlace = NSCollectionLayoutAnchor(edges: [.top, .trailing])
        let suppItem = NSCollectionLayoutSupplementaryItem(layoutSize: suppItemSize,
                                                           elementKind: CheckmarkGridViewController.checkMarkElementKind,
                                                           containerAnchor: suppItemPlace)
        group.supplementaryItems = [suppItem]

        let section = NSCollectionLayoutSection(group: group)

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

NSCollectionLayoutBoundarySupplementaryItem — это всем уже знакомые футеры и хедеры. Эти элементы можно добавить к NSCollectionLayoutSectionи UICollectionViewCompositionalLayoutConfiguration. Размер задается уже известным нам NSCollectionLayoutSize, расположение — NSRectAlignment. С помощью расположения вы говорите Layout, что это будет: футер (.bottom)или хедер (.top).

public convenience init(layoutSize: NSCollectionLayoutSize, elementKind: String, alignment: NSRectAlignment)

    public convenience init(layoutSize: NSCollectionLayoutSize, elementKind: String, alignment: NSRectAlignment, absoluteOffset: CGPoint)

Самая интересная переменная в этом классе — pinToVisibleBounds, которая позволяет реализовать sticky headerбез особых трудностей. Если ее поставить в true, тогда текущий элемент будет видимым, пока видна секция.

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

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.9),
                                              heightDimension: .absolute(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])
        group.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: .flexible(0), 
                                                          top: nil, 
                                                          trailing: nil, 
                                                          bottom: nil)

        let footerHeaderSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                                      heightDimension: .absolute(50.0))
        let leftSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.1),
                                              heightDimension: .absolute(150.0))
        let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: footerHeaderSize,
                                                                 elementKind: HeaderFooterViewController.headerKind,
                                                                 alignment: .top)
        let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: footerHeaderSize,
                                                                 elementKind: HeaderFooterViewController.footerKind,
                                                                 alignment: .bottom)
        let left = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: leftSize,
                                                               elementKind: HeaderFooterViewController.leadingKind,
                                                               alignment: .leading)
        let section = NSCollectionLayoutSection(group: group)
        section.boundarySupplementaryItems = [header, footer, left]

        let config = UICollectionViewCompositionalLayoutConfiguration()
        config.interSectionSpacing = 16
        let layout = UICollectionViewCompositionalLayout(section: section, configuration: config)

        return layout
    }

NSCollectionLayoutDecorationItemпозволяет установить задний фон для секции, у него присутствует один статический инициализатор:

open class func background(elementKind: String) -> Self

Так как этот элемент наследуется от NSCollectionLayoutItem, то ему можно задать contentInsets. Обычно это необходимо для того, чтобы выровнять границы фона. Единственное, что отличает его от остальных дополнительных элементов, — это регистрация класса для отображения: его нужно регистрировать в Layout.

В примере я покажу, как сделать тень по всей секции:

private func createLayout() -> UICollectionViewLayout {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                             heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .absolute(50))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])
        group.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: .flexible(0), top: nil, trailing: nil, bottom: nil)

        let background = NSCollectionLayoutDecorationItem.background(elementKind: "background")
        background.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
        
        let section = NSCollectionLayoutSection(group: group)
        section.decorationItems = [background]
        section.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0)

        let layout = UICollectionViewCompositionalLayout(section: section)
        layout.register(BackgroundView.self, forDecorationViewOfKind: "background")

        return layout
    }

Итоги

UICollectionViewCompositionalLayout — это еще один эволюционный шаг в разработке на iOS. Благодаря этому инструменту создавать коллекции элементов стало намного проще. Декларативный подход позволяет удовлетворить 99% пожеланий разработчиков. Учитывая, что SwiftUI еще сырой и в нем совсем нет коллекций, я настойчиво рекомендую взять этот инструмент на вооружение в новых проектах. В следующей статье я постараюсь разобраться во втором не менее важном инструменте — UICollectionViewDiffableDataSource.

  1. Документация.
  2. Advances in Collection View Layout (WWDC).
  3. Using Collection View Compositional Layouts and Diffable Data Sources.
  4. GitHub.

Як українські ІТ-компанії провели літо. Відео

$
0
0

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

Якщо ви хочете додати свої відео в статтю, пишіть на maria@dou.ua.

AB Soft

Одесская компания AB Soft, на борту которой 350+ сотрудников, провела Summer Party на стадионе. Спортивный тимбилдинг, выступление команды черлидинга, флешмоб эко-фаеров, море танцев и музыки от DJ Blush и DJ Tyotya Lida, hookah zone, фуршет.

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

Дніпро

Компанія Abto Software цього року відсвяткувала 12-турічницю заснування в стилі «Галицької дефіляди». На вході всіх зустрічали батяри, які запрошували на ранкову каву, пограти в шашки чи футбол та взяти участь у квесті: хто був найшустріший, то й і викупив першим кубок з ломбарду. А ввечері вся команда Abto Software запалювала під треки GG Гуляй Город.

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

BAKOTECH Group виповнилося 16 років. На літній корпоратив зібрали колег з усіх офісів: Чехії, Азербайджану, Польщі, Балтії, Казахстану та України. На святкуванні були активні види спорту, басейн та святковий торт.

Цього разу жага пригод привела команду Binary Studio на одну з вершин Копровського Штиту, що у Словаччині. 18 кілометрів трекінгу, 10 годин під дощем, градом і палючим сонцем — все це, безперечно, вартувало запаморочливого краєвиду. Виснажені, але щасливі, Binary Studio Team сушать дощовики і вже планують наступну подорож!

У червні колектив Blackthorn Vision гучно відсвяткував ювілейну 10-турічницю компанії в заміському відпочинковому комплексі. Колеги з львівського та хмельницького офісів взяли участь у творчому і барабанному майстер-класах, грі у пейнтбол чи стрільбі з луку, плаванні у відкритому басейні чи просто відпочинку на шезлонгах у Relax-зоні. Вечір закінчився урочистим розрізанням торту та танцями під запальні кавер-хіти від гурту «Esken&Friends».

Компания Brightgrove ярко и весело сплавилась на байдарках по р. Северский Донец.

На літній вечірці b2bsoft було багато драйву, спортивних викликів, гучних емоцій та яскравих кольорів!

Цього року Cleveroad відзначив свій перший ювілей — 5-тиріччя! Свято відбулося в стилі Hawaiian party і зібрало співробітників з дніпровського і харківського офісів. Крім спортивних ігор, змагань і крутих челенджів, команда просто релаксувала біля басейну. І в пам’ять про подію кожен відділ отримав брендовані подарунки.

Своє 5-річчя Clockwise зустріли на березі моря. Драйвові айтішники випробували свій командний дух у піратському квесті. Фінішували на велетенському кораблі, де отримали нагороди й відірвалися на морській вечірці на даху Atmosfera Lounge Bar. У вільний час купалися, засмагали, пили коктейлі, гуляли вулицями та каталися на кайті.

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

Цьогоріч літній корпоратив компанії Conscensia відбувся у мексиканьському стилі Fiesta Mexicana. Прекрасна локація у прикарпатському регіоні дала змогу сповна насолодитися різноманітними активностями на свіжому повірті (човни, катамаран, теніс, футбол, волейбол, велосипеди та ін.), а також повеселитися та почастуватися в мексиканському стилі.

Цього літа у компанії Crowdin не традиційний корпоратив, а Week of Happiness. Тиждень розваг і цікавих лекцій в офісі з самого ранку до вечора. Починали ранок з йоги та масажу, разом готували спільні обіди, риболовили, відвідували воркшопи з психології та саморозвитку, лекції про каву та фотографії, спільне малювання картини та графіті, технічні лекції, хакатони і на завершення — яскрава вечірка і Dj-воркшоп. Це як відпустка, але краще :)

Київ

Daxx влаштував сімейне свято «Dutch Dream». Будували картонні боліди, стрибали з дітлахами на батутах, грали у волейбол, а також створили логотип Daxx з відбитків долонь. Було багато помаранчевого кольору і запальної голландської музики.

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

Depositphotos Summer Jam пройшов в Olmeca Space. Серед гостей було 350 співробітників компанії. Протягом дня був квест, мільйон конкурсів і активностей, волейбол, сапи, кавер група та chillbuilding біля басейну. Найактивніші учасники паті отримали банку джема.

Цього року традиційний сімейний пікнік Digitally Inspired відбувся в Зеленому театрі. Головною тематикою вечірки стали капелюхи! Смачана їжа, чудова музика, сімейна атмосфера та чудернацькі капелюхи, що ще потрібно для гарного літнього відпочинку?

Свій 14-ийДень народження Edvantis провів на вечірці Century of Dance Music. Ми танцювали та розважались у різних стилях — від ретро 20-30-х, рок-н-ролу 50-х,яскравих 60-х,диско 80-90-х і так далі аж до сучасних хітів.

Українська культура та мистецтво стали нашим натхненням щодо підбору тематики вечірки, і так з’явилась ідея зробити ELEKS Folk Fest. Елексівці танцювали під запальні хіти «Тартака» і насолоджувались лірикою переможниці «Голосу країни» Оксани Мухи, смакували традиційні українські страви. Також у програмі були різні майстер-класи, пісочне шоу, працювала арт-виставка, виступала корпоративна зумба-команда. А ще напередодні вечірки спеціалісти ELEKS взяли участь у благодійному розпродажі футболок з етнопринтами.

Літній корпоратив і День народження вінницького офісу Exadel Ukraine відсвяткували в Молдові. За три дні команда побувала в Сороцькій фортеці, Національному парку Орхей, побачили Монастир Курки, погуляли по Кишиневу, дегустували вина у погребах Cricova і фотографувались на лавандових полях.

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

Львівська команда GlobalLogic провела літню вечірку у мальовничому куточку області — на базі «Бухта Вікінгів». Тематика заходу — Olympic Games. Формат вечірки — командні ігри на свіжому повітрі, квест та танці. На локації зібралось майже 600 людей і кожен знайшов собі розвагу до смаку!

Цього року на Summer Cinema Party вся харківська команда G5 відвідала кінотеатр під відкритим небом, заспівала улюблені пісні в караоке, займалась аквааеробікою, каталася на серфах, запалювала під музичний бенд та навіть зняла свій власний фільм! А ще на вечірку завітав сам Король Ночі!

Компанія Honeycomb Software влаштувала вечірку в стилі Ocean party. Колектив львівського та рівненського офісів зустрілися на базі відпочинку «Монте Карло», що в Рівненській області. Чудово провели час в дружньому колективі, поїдаючи раків, релаксуючи в чанах та плаваючи на байдарках. Ну і традиційно пограли у волейбол.

Компанія iLogos Game Studios організувала літній корпоратив для співробітників. Невимушеність та спокій — те, що цінують iLogosers, тому гучні вечірки та примусові конкурси — не їхній стиль. Для локації обрали будиночок з територією, де кожен знайшов собі відпочинок до душі: поплавати у басейні або посидіти в лазні, пограти в настільні ігри, більярд або теніс, їсти смачну їжу і пити коктейлі... Що ще потрібно для того, щоб відволіктися від буденної метушні? :)

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

Яскраве та сюрреалістичне святкування 17-річчякомпанії Intellias у Львові та Києві. Фестиваль «IntelliasLand. The Surreal World» наповнили драйвом «ТНМК», кавер-гурт компанії «Веслярі», сети від трьох запальних ді-джеїв, а також неймовірні колеги Intellias у нестандартних образах.

Львів

Компанія InterLink розпочала літо святкуванням 19-годня Народження у Єгипті. Подія пройшла у супергеройській тематиці. Вже четвертий рік поспіль до івенту долучаються команди з чотирьох офісів компанії: двох офісів у Черкасах, Львові та Лондоні.

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

17 серпня близько 400 співробітників одеського офісу Lohika одягли яскраві вбрання та прихопили з собою купальні костюми, щоб долучитися до пляжної вечірки у стилі 90-х — Forever Young Lohika Summer Party. Різноманітні водні змагання та атракціони чергувалися з пориванням у атмосферу 90-х:грою у «Вгадай мелодію», катанням на скейтах, стрибками на скакалці та культовими музикальними хітами від кавер-гурту «Rum Рum Рum» та діджеїв.

Ви чули дзвін кокосових келехів? Відчували ананасово-маракуйєвий аромат в повітрі? Можливо, бачили щасливих людей у гавайському вбранні? Це в MGID влаштували гучну паті в гавайскому стилі, на якій зібралися понад 300 співробітників!

Netpeak

8 червня 500+ нетпіківців відзначили 13-тийдень народження Netpeak Group! Влаштували справжній одеський, колоритний фестиваль під назвою «Однажды в Одессе». Багато гуляли, торгувалися за свою валюту, ворожили на картах, проходили квест, плавали на SUP-бордах, слухали Alyona Alyona і Go Bananas, брали участь у власному шоу «Прожарка», танцювали під Trash Party до світанку.

Колись у давні часи, коли літо лише починалось і ниття про спеку не було в тренді, Нікси запалили 25 ювілейну NIX Hippie Party. Понад 2000 хіпанів з дружинами, дітьми, сестрами, мамками та навіть синами мамкиних подруг долучилися до танців та співів із HeartBeat Brass Band, The Hypnotunez, TAKE Five і створення наймасштабнішого групового фото у власній історії! Якщо в літа був такий старт, завершити його можно лише шаленою вересневою вечіркою на честь 25-річчя NIX!

N-iX святкували День компанії у Львові та Києві. Свято об’єднало 600 працівників львівського офісу! Обравши за тему слоган «Go beyond the limits», компанія запросила команду в Sirka club. Кожен спробував катання на яхті, гідроскутерах та каное. На суші змагалися в настільні ігри, будували плоти та запускали повітряних зміїв. Захід сонця проводжали разом із групою «СКАЙ».

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

Київ

RubyGarage гучно провели традиційний літній корпоратив, відсвяткувавши восьму річницю компанії. Локацією події став готельний комплекс Lake Park у Новомосковську. Цей день запам’ятався купою розваг: командним квестом, SUP-бордами, каяками та неквапливим відпочинком біля басейну. Фіналом насиченого дня стала пляжна вечірка під зоряним небом.

Railsware

У 2019 році компанія Railsware традиційно запросила всіх співробітників разом з їх сім’ями (120 людей) провести тиждень за кордоном. Цього року команда обрала Хорватію. Тиждень на морі у колі друзів та сім’ї, веселі квести, аквапарк, футбол, баскетбол, волейбол, цікаві конференції — усе це залишило чудові спогади та згуртувало команду.

Компанія SBTech точно знає як зробити літній івент крутим. І справа навіть не в яхтах, коктейлях чи сучасних dj-сетах, а в тому, що ми — чудова КОМАНДА! 26 липня понад 200 працівників взяли участь у регаті, фінальною точкою якої стала вечірка у Grand Place.

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

Одного суботнього дня команда SE Ranking вирушила на південь до с. Мигія підкорювати водну стихію. Чотири години, шість рафтів, десятки порогів по-літньому теплої річки Південний Буг. Було весело, інколи трохи лячно, але захопливо. Додамо чудові краєвиди, трохи командних ігор і душевні пісні під гітару — от вам і рецепт незабутнього корпоративу.

Цього літа Sigma Software виповнилося 17. Компанія влаштувала вечірку в етнічному стилі двох народів — українського та шведського, бо Sigma Software — це шведська компанія з українським корінням. Навіть гасло звучить як «Nordic traditions, Ukrainian spirit, Superior software». Вся вечірка була витримана в етно-стилі: від меню — до фотозон та активностей. Гості зі Швеції гучно тостували: «Сколь!», на що українська команда Sigma Software відповідала: «Будьмо!». Разом ліпили вареники, глечики на гончарному крузі, каталися на конях, вчилися стріляти з лука, нестримно танцювали під виступ гурту «Танок на майдані Конго» (ТНМК) та інше. Традиційно святкування проходило в Харкові, куди колеги з’їжджаються з офісів Львова, Києва, Одеси, Дніпра, Сум та Вінниці.

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

Skelia

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

Кожен рік нові пригоди — восьма сімейна подорож SMART business пролунала під девізом «Vilnius Grand Motion». 306 учасників поїздки цього літа вирушили до столиці Литви. Грали у гольф, блукали затишними вулицями Вільнюсу та пізнавали загадки Тракайського замку. А ще команди брали участь у SMART Quiz, вигравали подарунки, здійснили традиційний ранковий забіг, а в останній день подорожі — танцювали до ранку на найяскравішій вечірці — Grand White Open-air Party!

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

Київ

8-гочервня SPD-Ukraine святкували 13-річчякомпанії. Вечірка проходила біля лісу та води. Була велика кількість розваг: квест лісом, пейнтбол, квадрацикли, водні лижі, вейк борд і т.д. Ввечері публіку розважали рок-гурти та діджеї, родзинкою вечору став DJ Tapolsky.

У липні SSA Group відсвяткувала 12-йдень народження компанії. Понад 150 учасників зібралися в пляжному комплексі «Аркада» на вечірку в стилі літнього табору SSA camp. Було все, що потрібно для гарного відпочинку та чудового настрою. Літо, сонце, басейн, цікаві конкурси та майстер-класи, наукове шоу, свято Нептуна, видовищна водна битва і запальна дискотека під улюблені хіти дитинства.

Компанія Symphony Solutions 6 липня провела літній корпоратив «Тисяча й одна ніч» в арабському стилі. Локація — відпочинковий комплекс з басейном. Всього участь взяли 200 працівників. Програма вечірки була насичена східною тематикою: ведучий в ролі Джина, конкурс східного танцю, «польоти на чарівному килимі», обрання Аладдіна та Жасмін вечора, східні солодощі та зона відпочинку, східна музика. Також, за результатами голосування колег, нагородили працівників, які найкраще втілюють цінності компанії.

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

Вікенд команди Terrasoft в Буковелі: захоплюючий квест, подолання екстрим-парку, релакс на озері Молодості, запальна вечірка. Все це — Terrasoft Summer Trip!

Літній корпоратив Uvoteam #uvo90s був флешбеком в епоху Yupi та Super Mario. У командних конкурсах грали в резиночки, передавали естафети, творили в «Умілих ручках», співали «Тополиный пух», виходили до дошки та стрибали через козла, як на фізрі. Це були чумачечі 90-ті!

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

На 7-мурічницю Waverley Software команди з усієї України та клієнти з усього світу зібралися разом на блискучій та неоновій вечірці — Waverley Let’s Glow Crazy!

Компанія WorkNest Technologies відсвяткувала свою Summer pool party під гаслами «Піратів Карибського моря». На один день команда WorkNest стала морськими розбишаками, любителями рому та володарями золота. Усім «на абордаж»!

Щороку YouScan збирає команду із різних міст на літній корпоратив, щоб усі змогли познайомитись і поспілкуватись. Цього разу у червні вся команда — а це 80 співробітників — на 5 днів полетіла до Чорногорії. У програмі було декілька тімбілдингових активностей і багато вільного часу на спілкування. Тож усі разом плавали на катамарані по красивій бухті, зупиняючись на купання і прогулянку вуличками старого містечка, танцювали на терасі з фантастичними краєвидами. А у вільний час малими групками досліджували узбережжя на автівках, ходили пішки в гори, гуляли по Будві, обідали в затишних ресторанчиках, відпочивали на пляжі і в готелі.

У Харкові це була вечірка з темою «Like a Burning Man». Круті арт-інсталяції, битва роботів, плетіння мандал, власноруч розмальована стіна з графіті та кульмінація вечора — спалювання дерев’яної статуї. На день ZONE3000 опинилася у Неваді ;) Закінчили вечірку запальним фаєр-шоу і танцями до світанку.

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

Харків

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

$
0
0

[Роман Сенів — CEO в CopeCart GmbH, Founder у e-freight.eu. Спеціалізується на теоретичних і практичних сторонах моделювання процесів розробки програмного забезпечення, включаючи Lean Software Development і Agile Software.]

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

Нині я CEO компанії CopeCart GmbH. До цього займався власним стартапом, а ще раніше багато років працював в аутсорсі чи не на всіх фронтах: починав як Junior Java developer, а потім був технологічний і процесний консалтинг, різні рівні менеджменту й продаж. Досвід великий і широкий, але в жодному з аспектів назвати себе експертом уже язик не повернеться :)

Замість передмови, або Просто/складно

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

Контекст

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

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

Технічні вимоги прості: Ruby, Rails і Vue.js — доволі типова комбінація — хостимося на AWS: EC2, RDS та Redis, але цього не вимагали. Проте, оскільки наш проект — це фінансова система + пам’ятаємо про плато стабілізації, то до списку додали й інші вимоги: увага до деталей і розуміння шаблонів проектування, рефакторинг і тестування, девпрактики й робота в команді (не плутати з парним програмуванням). Досвід роботи у фінансових проектах, звісно, — велика перевага.

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

Як знайшли людей

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

Проти

Стабільність

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

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

Також важливо було розказати й за потреби показати на співбесіді графік revenue в часі, щоб кандидат міг особисто переконатися, що ми вже не зовсім стартап.
Індивідуальні зростання й розвиток

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

Я говорив відверто: слово tech-lead має дві частини tech і lead, і якщо ви (кандидат) хочете розвиватися за вертикаллю tech, то в нас для цього будуть і можливості, і час. Проте якщо кандидат хоче розвиватися за вертикаллю lead і відходити від роботи руками, то ми не можемо цього обіцяти, принаймні в найближчі два роки.

Соцпакет

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

Відпустки й лікарняні

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

За

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

Як проти перетворили на за

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

Мої помилки

Система

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

Remote

Тоді, коли я згодився на remote + relocate, у мене абсолютно зникли кандидати зі Львова. «Пострілявши» трохи в інших містах і провівши чимало співбесід через скайп, я повернувся туди, де й починав: досить класним кандидатам досить класно там, де вони є, і за моїх хитких позицій переїзд (навіть на місяць рампапу) виявився рівнянням без розв’язку. Тож ми забули про ремоут і сфокусувалися на Львові.

Ruby

Я не рубіст і до Ruby ніколи не належав, тож вимоги рекрутерам дав досить поверхневі. Як наслідок, спочатку було багато нерелевантних резюмешок. Але ми швидко навчилися їх фільтрувати, здебільшого зважаючи на те, чи досвід кандидата був у більших проектах з Rails, чи менших проектах на якійсь із CMS.

Процес співбесіди

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

Літо

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

Результати

Через рекрутерів перебрали приблизно 150 резюме. Провели майже 25 співбесід. Зробили 8 оферів, з яких прийняли 5, а на роботу вийшло 4. Решту людей найняли за рекомендаціями.

Середній час від оферу до виходу на роботу — 6 тижнів. Максимальний — 9.

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

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


Зустріч прем’єр-міністра з ІТ-галуззю: 650 тис. ІТ-спеціалістів за 10 років та нова система оподаткування

$
0
0

4 вересня в Києві відбулася зустріч представників нового уряду з ІТ-галуззю. З боку урядовців були присутні новий український прем’єр Олексій Гончарук, віце-прем’єр міністр України й міністр цифрової трансформації Михайло Федоров, а також голова ДПС України Сергій Варланов. З боку ІТ — керівники компаній та представники асоціацій.

Обговорювали питання розвитку ІТ-галузі, трішки про маски-шоу, ну і, звісно, нове оподаткування. Редакція DOU побувала на зустрічі, і представляємо вам найцікавіше з обговорення.

Image source

Маски-шоу

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

Дефіцит кадрів та освіта

ІТ-індустрія сьогодні — це понад 160 тисяч спеціалістів, які експортують понад $ 3 млрд на рік. За словами прем’єра, уряд буде створювати всі умови, щоб індустрія зростала ще швидше. Одна з очевидних і важливих обставин, що стримує розвиток ІТ, — це брак кадрів. Українська система освіти випускає недостатньо багато людей, яких можна залучати для роботи в ІТ-сфері. А кожного наступного року ІТ-галузь потребуватиме все більше нових спеціалістів. І для цього потрібно створити умови, де б ці люди навчалися. Тож, Гончарук пропонує створити фонд розвитку людського капіталу «IT Creative», який має управлятися не чиновниками, а представниками самої індустрії. По суті, це такий інструмент, який акумулює ресурси й дозволить витрачати їх на три важливі аспекти:

  1. стипендії для талановитих студентів;
  2. гранти для молодих вчених;
  3. партнерство університетів з ІТ-компаніями (спільні кампуси, лабораторії тощо).

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

Він також озвучив цілі для ІТ-галузі на найближчі 10 років:

  • Експорт — 13 млрд.
  • Кількість працівників в ІТ — 650 тис.
  • Україна — лідер у Європі за кількістю ІТ-фахівців.

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

Нова модель оподаткування

Державна податкова служба України працювала останні декілька місяців над новою моделлю оподаткування. Пропонується створити нову опцію в оподаткуванні для ФОП у ІТ-галузі. На сьогодні найпоширенішою є 3-ягрупа спрощенців, які дозволяють генерувати дохід до 5 млн грн зі ставкою ЄП 5 % і сплатою ЄСВ (орієнтовно 900 грн на сьогодні). За словами голови ДПС Сергія Верланова, ІТ-компанії завжди наголошують на певних ризиках, що існують при масовому використанні цієї моделі. І ці ризики з ростом компаній іноді не дають розвиватися. З іншого боку, є класична система трудових відносин, яка є також неідеальною й забюрократизованою, тим самим сповільнює розвиток бізнесу, зазначає Верланов.

З огляду на це, ДПС створила проект нової моделі оподаткування, яка складається з таких платежів:

  • 5 % єдиного податку, який йде в місцеві бюджети.
  • 1,5 % військового збору.
  • ЄСВ із двох мінімальних заробітних плат.
  • Збір на розвиток людського капіталу. Ставка збору зростатиме протягом 5 років, потім вона буде стабільною. Таке поступове зростання дає зрозуміле фіскальне навантаження. Збір на розвиток людського капіталу надходитиме у фонд IT Creative, тобто в спецфонд бюджету. І відповідно буде адмініструватися галуззю.

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

На зустрічі також слово надали представникам ІТ, які в цілому, хоча й обачно, підтримали ініціативи уряду:

Тарас Кицмей, співвласник SoftServe, голова правління Асоціації «IT Ukraine»

Майбутнє України — це креативна економіка, індустрія знань, де люди своїм досвідом компетенціями стають генератором доходу, а не фонди чи фінансові ресурси. ІТ-індустрія своїм успіхом завдячує тому, що робить фокус на людях, а не фінансових ресурсах. Ми використовуємо свої сильні сторони й певним чином нивелюємо наші слабкі сторони. І це повинен бути фокус нашої держави. В ІТ-індустрії є два ключові моменти: 1. Потрібні таланти. 2. Стабільне регуляторне середовище. Якщо подивитися на другий пункт, то де-факто ми зараз маємо певні правила гри, які працюють. І ці правила гри нам дали той успіх, якому ми завдячуємо: понад 4 млрд виторгу, понад 150 тис. айтішників, 18 компаній входять у глобал ІТ-лист тощо. І коли ми говоримо фактично про 5 групу приватних підприємців, мені здається, що ми продовжуємо вдосконалювати правила гри, які на сьогодні маємо.

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

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

Олександра Альхимович, компанія Luxoft, співголова IT-комітету Американської торговельної палати

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

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

Окрім ризиків, варто сказати і про наші можливості: об’єм світового ІТ-ринку зараз складає $ 5 трлн. Якщо порівнювати з нашими 4 млрд, то це менше ніж 1 %. Але водночас ми бачимо, що цифри, які були озвучені прем’єром, — 13 млрд — можливо ми могли досягти не за 10 років, а і швидше. Але для цього потрібно створити умови. Можливо навіть укріпити те, що маємо. ІТ в України досягла таких результатів саме завдяки спрощеній системі оподаткування, ключовим відносинам з ІТ-фахівцями, потужному та великому ІТ-ринку фахівців. Тому ми підтримуємо ініціативи, які спрямовані на покращення, на реформи у сфері оподаткування. Вони повинні бути системні, прозорі, стратегічні, обговорені з усіма сторонами. Ми підтримуємо реформи у сфері ІТ-освіти: цікава ідея щодо створення фонду людського капіталу. Але водночас, як я вже сказала, ми не маємо конкретною моделі, нам потрібно створювати її з нуля. Тому впроваджувати її треба дуже обережно та ретельно.

DevOps. Мы не кормим медведей!

$
0
0

Дай человеку рыбу, и он будет сыт один день. Дай человеку удочку, и он будет сыт всю жизнь.

Привет! Меня зовут Николай Лотоцкий, я — DevOps Evangelist в Namecheap, Inc. В IT более 15 лет. В этой статье я расскажу о процессе образования команд и их инфраструктуре с использованием методологий DevOps.

Почему сейчас именно DevOps?

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

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

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

К чему это я? В инфраструктурных командах девелоперов очень часто начинают «подкармливать». «Как это?» — спросите вы. «А вот так! — отвечу вам я.

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

Замечу, что я слышал об IaaS и как инженер являюсь ее евангелистом. Допустим, инженеру-разработчику Алексею понадобилось внести в свой проект инфраструктурное изменение. Скажем, сменить тип хранилища с S3 Standart на Glacier. Алексей идет в инфраструктурную команду, отвлекает тамошнего инженера Кирилла от его работы над миграциями других команд из дата-центра в облако и успешно рапортует о проделанной работе.

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

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

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

С чем мы тут имеем дело? С типичной прикормкой «медведя» Кириллом. Раз за разом «косолапый» ходил на одно и то же прикормленное место. Возможно, даже отпугивая других «мишек». Пока не встретил отказ.

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

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

Какие вопросы будут в ведении этого дежурного?

Он будет:

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

Дежурный станет некой плотиной между вами и «медведями».

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

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

Как выстроить процесс обучения?

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

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

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

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

Теперь поговорим о принципах подготовки базового курса:

  • Курс не должен быть перегружен. Вы не обучаете нового члена инфраструктурной команды — вы готовите человека, который разделяет DevOps-философию и который будет забирать у вас операционную работу. Кстати, первую лекцию в начале курса посвятите именно философии DevOps, а не инструментам и практикам.
  • Курс должен содержать информацию ТОЛЬКО ОБ ИСПОЛЬЗУЕМЫХ инструментах и практиках, не пытайтесь рассказывать о прекрасном далеко: это все забудется. Лучше сосредоточиться на том, что уже есть.
  • Не углубляйтесь в дебри теории и практики, помните: человек не обязан знать больше того, с чем он встречается при исполнении своих повседневных обязанностей; он не должен уметь развертывать кластер ECS, а вот справляться с созданием сервиса и TaskDefinition обязан.
  • При составлении курса надо давать базис, для того чтобы человек, столкнувшись с проблемой, мог хотя бы правильно подобрать слова для Google, а также для внятного вам ее объяснения без жестикуляции руками.
  • Курс должен содержать накопленные вами рецепты для решения тривиальных задач.
  • Курс не должен быть сверхсложным. Это ни к чему. Материал, на изложение которого у вас уйдет 90% времени, забудется от силы через неделю.
  • Делайте упор на практике: теорию люди выучат потом, если будут копать глубже.
  • По теории. Давайте ее маленькими порциями, и только самое необходимое. Да, понять, как что работает, важно, но также важно освоить инструмент!

После всего вышеперечисленного вы избавитесь от большого объема оперативной работы.

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

P. S. Все совпадения с реальными событиями, людьми или животными непреднамеренны и случайны.

Отладка. Step-by-step к эффективному выявлению ошибок

$
0
0

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

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

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

Запасайтесь кислородом, нас ждет погружение в пучину багов.

Причины возникновения ошибок

Обычно возникновение ошибок связано с написанием или изменением кода. Стоит понимать, что 99% ошибок — это ответственность разработчика. А вот с причинами их возникновения будем разбираться дальше.

Позволю себе выделить такие категории причин (по приоритету сложности обнаружения):

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

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

Опечатки

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

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


Анализаторы кода (Roslyn, ReSharper, SonarQube, ESLintи другие), code review и парное программирование помогут избавиться от этих ошибок.

Непонимание логики

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

  1. Найдите автора кода. Разузнайте детали, задавайте много вопросов, чтобы убедиться, что поняли все верно. Если автор вы или его уже нет, идем дальше.
  2. Обратитесь к тестам. Хорошие тесты доступно описывают поведение кода.
  3. Расспросите QA, владельца продукта, аналитика, PM (или того, кто у вас занимает роль хранителя знаний о поведении этого продукта).

Незнание тонкостей языка разработки

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

Для входного параметра value = 10 условие тоже будет выполняться. Нужно добавить строгое сравнение ===.

Операция + для чисел выполняет сложение, а если один из параметров представлен строковым значением, то конкатенацию:

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

Невнимательность

К этой категории можно отнести следующие ошибки:

  • неучитывание граничного значения, к примеру < вместо <= (о граничных значениях и эквивалентных классах можно почитать здесь);
  • вызов метода с другой перегрузкой;
  • неверный порядок операций, например забыли () для выражения 1 + 2 * 3;
  • использование не того свойства/параметра.

Кейс из жизни.Был цикл динамического наполнения коллекции для combo box на 10 элементов. Позже первым элементом добавили статическое значение, не изменив цикл. В итоге последний элемент коллекции не отображался.

С такими ошибками хорошо справляется unit-тестирование.

Ложные тесты

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

К примеру, этот тест будет проходить даже в том случае, если у currentUser не будет заполнено свойство Id.

Писать более «правдивые» тесты поможет подход TDD. Рекомендую к прочтению книгу адепта TDD Roy Osherove.

Отсутствие обработки ошибок

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

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

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

Паттерн Null-object сокращает количество проверок типа:

Он может быть реализован таким образом:

Копирование чужих ошибок

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

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

Предотвращение багов

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

Code review

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

Парное программирование

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

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

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

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

TDD

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

Анализаторы кода

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

Реализация атомарными частями

Коммитить чаще, релизить чаще — это привычки, которые потенциально сократят ошибки. Частые и маленькие коммиты — быстрое прохождение pipeline-тестирования и ранний feedback по качеству коммита. Этот подход поможет сократить время влияния ошибок на продукт. Чем дольше ошибка в коде, тем дороже будет ее устранение.

Делайте перерывы

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

Поиск и устранение

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

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

Воспроизвести

Получив issue от QA, первым делом нужно убедиться: а есть ли проблема? Нужно воспроизвести ошибку и удостовериться в стабильности ее возникновения.

Проверить актуальность изменений

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

Понять бизнес-логику

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

Свериться со списком частых ошибок

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

Свериться с тестами

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

Проанализировать журнал

Надеюсь, что журналирование в вашей системе есть. В debug-режиме сохраняйте всю необходимую для анализа информацию. Для production логируйте последовательность действий и ошибки. Грамотно составленный журнал позволит выявить проблему без перечитывания сотни строк. Еще больше информации даст подход event sourcing.

Исследовать систему контроля версий

Нередко момент появления бага можно определить с точностью до часа. «Еще вчера работало» — одна из избитых фраз разработчика. И VCS будет лучшим хранителем истории изменений. Посмотрев в log репозитория (blame файла), можно с уверенностью определить роковой commit. В этом случае осмысленные комментарии в коммите и связь с ticket-системой значительно облегчат понимание намерений автора.

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

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

Средства профилирования (dotTrace, ANTS, SQL Profiler) — для поиска плавающих багов, утечек памяти, влияния на систему.

Дебагеры (ChromeTools, OzCode) — для отслеживания выполнения программы строка за строкой. Хорошее владение этими инструментами значительно упрощает поиск и исправление ошибок.

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

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

Сделать гипотезу

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

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

Эффект утенка

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

Заключение

Мы рассмотрели способы, которые помогут сократить время поиска. Системный и структурированный подход к поиску и фиксации ошибок значительно сокращает затраты времени на их исправление. Даже 10% выигранного времени каждого разработчика принесут хорошую выгоду. И вы сможете уделять больше времени созданию, а не исправлению. Формат чек-листа помогает ничего не забыть и наладить системный процесс выявления ошибок. Возможно, вы используете другие подходы, которые помогают вам. Буду рад обсудить их в комментариях.

И помните: качество — синоним успеха!

«Це невідворотна еволюція суспільства». Чому нам не оминути нових податків та куди вони підуть

$
0
0

[Про автора: Іван Лешко — VP Client Success в SoftServe, працює в ІТ-індустрії вже більше 13 років, за які пройшов десятки різних проектів від інженера до керівника бізнес-вертикалі. Останні роки повністю сконцентрований на роботі із клієнтами та розвитку ІТ-індустрії]

Український айтішний офшор — до нескінченності. Ну що, друзі, пригорає від заяв нового прем’єр-міністра і команди? А ви думали, далі буде стабільність?

Прем’єр-міністр Олексій Гончарук презентувавплан створення Фонду розвитку людського капіталу для IT-галузі, який би керувався самою галуззю. І в першу чергу наголос стоїть саме на створенні фонду, а не піднятті податків. А от фонд наповнюватимуть із кількох відсотків додаткових податків до ФОП ІТ. Кошти цього Фонду підуть на галузь освіти (стипендії для студентів, гранти для молодих вчених і створення освітньої інфраструктури).

На додаток голова податкової служби Сергій Верланов розказав, яким чином пропонується ввести спеціальну опцію оподаткування для ФОП в IT-галузі. Окрім теперішнього 5%-го єдиного збору, 1,5%-го військового збору та ЄСВ з двох мінімальних зарплат, передбачається введення збору на розвиток людського капіталу: 2020 — 1%, 2021 — 2%, 2022 — 3%, 2023 — 4%, 2024 — 5%. А тепер жуємо деталі.

Image source

Поточна ситуація

Наразі в Україні є два законні способи для компаній мати найманих працівників: офіційне працевлаштування і 40% податків із кожного працівника або ж ФОП група 3 із 6,5% податків. Звичайно, усі йдуть шляхом менших платежів і обирають ФОП. І от відколи з’явились ФОПи і до сьогодні стався неабиякий прогрес. Як ви думаєте, скільки ФОП третьої групи існує в Україні на сьогодні?— 500 тисяч. Півмільйона українців обрали платити невеликі податки та вимагати багато змін і хороших шкіл для своїх дітей чи рівних доріг для кредитних Rav4.

Але водночас Україна є гравцем на світовому ринку, адже ми обрали рухати країну ближче до Заходу (чи не обирали таке? і замовлення для ІТ приходять із Азії?). А що ж твориться на Західній світовій арені? — А там є МВФ, який вправно керує світовою економікою. Стосовно цієї організації я багато говорив раніше, але є одна незаперечна істина: ще від часів Кучми вони почали перебирати на себе контроль над Україною за допомогою грошових потоків. Кінцева ціль — привести Україну хоч до якогось прийнятного середнього рівня на світовому ринку. Відповідно, вони катком накочують західні правила гри. А там, на Заході, усі справно платять 40%+ податків і ніяк не можуть зрозуміти, чому в Україні такий податковий рай. Тому це питання часу, коли вони все-таки доб’ються ліквідації 3-їгрупи ФОПів. А повірте, вони свого завжди досягають.

Навіщо нові ІТ-ФОПи

Виведення ІТ ФОПів у окрему групу — це своєрідний пілотний експеримент для теперішнього уряду. Взяти 160-180тисяч із 500 тисяч ФОПів і відокремити в групу 5 із новим оподаткуванням. Зрозумілішою для айтішника мовою: написати клієнту PoC із трьома клікабельними скрінами; якщо клієнт апрувне, тоді допиляти ще трохи бекенду і викотити на MVP в клауд.

Відповідно, 5-тагрупа ІТ ФОП — це MVP для цілісної ліквідації третьої групи та наближення України ще на крок до західних стандартів. Саме тут поки, будь ласка, не зачіпайте питання, а де ж західні стандарти життя. Про це трішки згодом.

Чому саме ІТ обрали для MVP

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

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

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

Чи могло воно трапитись ще за минулої влади? — Авжеж, могло, але була тисяча і одна причина, чому того не трапилось. Тому якщо ви звинувачуєте 73% відсотки в поганому виборі — то справа далеко не в цьому. Є невідворотна еволюція будь-якої держави чи суспільства незалежно від того, хто зараз відіграє роль front page.

Отже, ФОП ІТ обрані для MVP саме тому, що ця галузь найбільш прогресивна та активна в Україні. Саме тому, що ще у 2014 році KPMG спрогнозували $3 мільярди на 2019 рік і не помилились. Саме тому, що при теперішніх 180 тисячах ІТ-працівників ми приносимо в Україну три мільярди американських грошей, а через 10 років приноситимемо 10 мільярдів. Кількість працівників повинна зрости до 700 тисяч, а де їх взяти, якщо, наприклад, навчальна база така сама, як і 20 років тому?

Як це буде

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

Читаючи коментарі, я побачив багато людей, які запитували щось на зразок: а чого інженера Петра запросили на презентацію, а мене ні. От, власне, задумайтесь, чому і хто напише правила гри для нас. Якщо у вас є дійсно класні і конструктивні ідеї, то якщо ви їх винесете кудись далі за коментарі у Facebook, то, можливо, і жити стане краще.
Наприклад, чи погодитесь ви платити +5% податків, якщо законодавчо нас введуть у штат як звичайних працівників? — А це вже цікавіше — мати законні трудові відносини із компанією. Ми зможемо не тільки печиво і каву вимагати, а набагато більше.

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

Фонд людського капіталу?

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

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

Є дуже хороша книжка Адріана Сливоцького «Давид перемагає», де він описує критерії успішних країн та компаній за усю історію нашої цивілізації. І один із критеріїв, який він виводить, — Frugal. У перекладі на українську мову — це щось близьке до «заощадливість». Тому я б запропонував назвати цей фонд Frugal. Хоч уряд обрав пафосну назву — IT Creative.

Інвестиції в майбутнє

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

Уявіть, у 2020 році податкова збере у фонд $20 000 000 (двадцять мільйонів доларів). Куди їх подіти? Взяти 10 найкращих вишів України і роздати по 2 мільйони кожному. Допоможе? — Хтозна. Чи, може, закотити паті на 180 тисяч чоловік десь в Одесі? А, можливо, відкрити в Україні філію британського коледжу чи школи. Влаштувати конкурентне середовище для боротьби за стипендії, заснувати нові кафедри в університетах чи, може, навіть цілий новий університет.

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

Мені не вистачає грошей

Ну, коли вже вас переповнила злість, що я топив за Петра, а зараз намагаюся пояснити те, що робить Володимир, логікою. Незалежно від того, хто грає роль front page, еволюція суспільства мусить відбуватись.

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

BA дайджест #4: техники приоритизации, голосовой UX, гайд по написанию API

$
0
0

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

Также, если у кого-то есть идеи тем, которые будут всем интересны и их стоит добавить в дайджест, — пишите в комментариях :) Приятного чтения!

Цифры в скобках возле заголовков — примерное время на изучение материала.

Статьи

Общее

20 Техник Приоритизации в Продукте: Карта и Руководство (32 мин). Просто фантастический гайд, в котором собрано много интересных техник приоритизации задач по разработке продукта. Здорово то, что почти все из них (кроме фин. анализа, пожалуй — тут надо иметь доступ к соответствующей информации) универсальны и применимы в любом проекте.

Benefits of Internal User Research (7 мин). Очень крутая статья о вреде и пользе проведения пользовательского тестирования ваших продуктов силами ваших же сотрудников. От себя могу добавить, что даже среди мега лояльных к идее (или наоборот, не лояльных — их фидбэк бывает даже ценнее) можно найти тех, кто трезво взглянет на идею и даст вам полезные инсайты.

10 основных техник для разработки требований к ПО (5 мин + примеры). Топ-10 техник для аналитика по мнению Дениса Бескова — одного из топовых аналитиков СНГ. Можно сказать, что это MVP для каждого БА. Кстати, вот как он обучает разрабатывать ТЗ.

Чего хотят наниматели от системного аналитика(4 мин + ссылки). Интересное исследование сайта HeadHunter от того же Бескова о том, какие требования предъявляются к аналитикам в СНГ.

Documenting APIs: A guide for technical writers and engineers. Ну очень подробный гайд по написанию API. Целое руководство, которое смело можно включать в программу обучения (правда не все, так как есть и сугубо технические нюансы).

Краткая информация об области знаний «Strategy Analysis» (BABOK 3)(1 мин). Новый постер от Art of BA по областям знаний BABOK. Предыдущие можно найти в их блоге.

Проектирование интернет-магазина для SEO: (теория + чеклист)(7 мин). Достойный гайд о том, как сделать ваш интернет магазин SEO-friendly. Часть советов подойдет и для других типов систем.

Типичные ошибки в английском у IT-специалистов и как их исправлять(6 мин). Статья о наиболее частых ошибках в английском, которые мы допускаем. Отличный чек-лист для самопроверки.

How to Avoid Market Feedback Traps(7 мин). Статья о 6 типовых ошибках восприятия фидбэков пользователей при разработке B2B-продуктов и как избежать этих ошибок.

Should You Create An MVP Before Creating An App?(14 мин). Несколько действительно хороших мыслей об MVP как таковом. Кстати, автор статьи вообще отлично пишет, очень рекомендую подписаться.

Promises, Promises: Negotiating Achievable Commitments(8 мин). Карл Вигерс делится своими наблюдениями о том, как реально формируются коммитменты и какие подводные камни ожидаются в случае, если коммитменты нереалистичны. Карл также дает хорошие советы о том, как изменить ситуацию.

How BAs Fit into Projects and Development(9 мин). Хорошая статья для новичков, которая поможет разобраться в том, какую роль выполняет аналитик в SDLC / PLC (Project Life Cycle).

UI/UX, prototyping

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

Скругленные или остроугольные?(5 мин). Казалось бы, какая разница какой формы будет кнопка? А нет, все не так просто. Автор в деталях поясняет, когда что использовать.

Bottom Navigation Pattern On Mobile Web Pages: A Better Alternative?(11 мин). Весьма нетривиальная мысль о переносе таких ключевых элементов, как бургер меню, в футер скринов. Зачем? Читайте по ссылке :)

4 Rules for Intuitive UX (16 мин). Шикарная статья, которая сделает вас богом UX без необходимости изучать основы дизайна — все действительно интуитивно. Есть много аргументов и примеров. Больше всего понравился Squint Test — «косоглазый тест», который показывает действительно наиболее заметные и ключевые элементы интерфейса.

4 best practices for designing the user onboarding experience(7 мин). Подборка подходов с примерами от «лучших» для вдохновения :) Сюда же — Designing effective onboarding for apps(4 мин).

Designing B2B Products That Scale (9 мин). Несмотря на узконаправленное название, этот весьма объемный гайд можно использовать в отношении любого продукта. В статье идет речь о «стандартизации» дизайна, разработке style guide. Приведено множество примеров, из которых можно собрать «чек-лист» для разработки дизайна, где это имеет делать смысл основательно.

5 Digital Accessibility Myths Busted (9 мин). В статье приводится ряд аргументов о том, что на самом деле accessibility — просто, легко и полезно всем. На мой взгляд, аргументы достаточно весомые. Они подкреплены ссылками на исследования и статистику. Осталось научиться продавать эту пользу бизнесу :)

Form best practices — the Do’s and Don’ts in form design(7 мин). «Simple, but vital» подборка практик для создания хороших интерфейсов.

Accessibility: 7 best practices to get you started(8 мин). Практические советы по созданию более accessible интерфейсов, со ссылками на тулзы, с помощью которых можно проверить выполнение. «Simple, but vital» подборка практик для создания хороших интерфейсов.

Large Devices Preferred for Important Tasks(9 мин). Исследование, показывающее, что для более «серьезных» задач люди все еще предпочитают использовать «большие» экраны вместо мобилок. В частности, главная боль — неудобство печати на мобильных устройствах. Об этом и других нюансах читайте по ссылке.

Результаты исследования от NN Group о паттернах поведения пользователей, с помощью инструмента для отслеживания, куда на странице смотрит пользователь — раз (5 мин), два (8 мин). Туда же — то, как они это делают(6 мин).

Подкасты

Rapid Prototyping (35 мин). Об опыте применения rapid prototyping, видах прототипах, инструментах прототипирования, реакции пользователей на прототипы и сделанных выводах.

MBA192: The Blight of Product Debt(32 мин). Что такое продуктовый долг, откуда он берется, что с ним делать и как с этим жить.

События

20 сентября в Киеве пройдет BA Club Meetup #31. В агенде 3 темы, ориентированные, судя по названиями, скорее, на новеньких аналитиков.

28 сентября в Харькове состоится встреча «Deep Diving: Information architecture для BA». Тема Information Architecture — весьма фундаментальная, будет интересна коллегам с опытом (об этом же пишут и организаторы). Спикеры очень крутые, так что должно быть интересно!

26-27октября пройдет Lviv BAQ Conference Autumn 2019. Судя по описанию, пока не очень понятен уровень тем и детали по ним, так как агенды еще нет. Кстати, а вы тоже заметили, что в последнее время стало больше конференций, где билеты уже продают, а список докладов и спикеры еще не объявлены?

15 ноября состоится Autumn AI & Big Data Day 2019. К сожалению, ситуация со спикерами и докладами такая же. Вместе с тем, судя по описанию потоков, ясно, что должно быть множество стартапов со своими идеями и много докладов про тренды в области.

Инструменты

Loom — простой и удобный chrome extension для записи видео с экрана, с возможностью быстро шарить результат.

Google Sheets introduces Slicers, Scorecards, and Themesдля более эффективной визуализации данных.

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

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

  • вновь стал доступен split view;
  • теперь можно шарить скрин при звонке из веб-версии скайпа;
  • появилась возможность добавить наиболее важные сообщения в закладки;
  • обновлен интерфейс message composer.

Стажировки, курсы

13-17ноября пройдет Тренинг по бизнес-анализу от Art of BA, на котором будут подробно разобраны все области знаний BABOK v3, будет много практики и общениям с опытными коллегами.

Юмор

Вот уж действительно «бесценный» сотрудник

Немножко сути Agile :)


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

Viewing all 8435 articles
Browse latest View live