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

Українські ІТ-фахівці на Burning Man: навіщо їхати в пустелю

$
0
0

Burning Man — подія, що з 1986 року збирає в пустелі Невади майже 80 000 людей, які протягом восьми днів живуть за власними цінностями й правилами, самовисловлюються, спілкуються, тусуються та оглядають арт-об’єкти. Задоволення — не з дешевих. Проте ІТ-спеціалісти не шкодують ні грошей, ні часу, щоб потрапити на подію. Ми розпитали кількох українських ІТ-фахівців про враження від цьогорічного Burning Man.

Женя Варавва, SRE в Google, Сан-Франциско

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

Найчастіше Burning Man описують як тижневу подію в пустелі Black Rock у Неваді, яка об’єднує в собі арт- і музичний фестивалі, екстремальний кемпінг та екстравагантні костюми. Хоча все це і є на Burning Man, це найменше, що можна звідти взяти, і це не те, чому його відвідує більшість учасників: від артистів, інженерів і ремісників до топ-менеджерів великих компаній та інших знаменитостей.





Фото: Valya Karchevskaya
Усяку істотну розповідь про Burning Man варто розпочинати з принципів, які є стрижневою засадою унікальності цієї події. Принципи — це те, що робить Burning Man більш, ніж музичним фестивалем чи відривною вечіркою. Головне, що варто взяти із цього допису, — що хоча не всі принципи обов’язкові до виконання (немає поліції принципів), для отримання максимальної віддачі варто керуватися ними в процесі підготовки, під час події, а також узяти їх у повсякденне життя опісля.

Один з найголовніших принципів — Radical self-reliance. Якщо коротко, то за кожного учасника чи учасницю відповідає, передусім, він сам або вона сама. Як описав один з моїх кемпмейтів, організатори дбають, щоб ніхто на фестивалі не помер (хоча вдається не завжди), а решта — відповідальність учасників. Завдання чітке: вижити тиждень (насправді більше) у пустелі, де температура коливається від +5 до +38 ºC, де в кожного учасника або команди є лише клаптик пустелі й приблизно все. Звідси, залежно від фінансових можливостей, авантюризму чи організаторських здібностей, кожен вирішує як виживати. Хтось укладається тисячами доларів в індивідуальний RV — будиночок на колесах, хтось об’єднується в табори за інтересами й облаштовує спільний побут, а хтось приїжджає з одним рюкзаком і якось викручується на місці. Варто зазначити, що найближча цивілізація (наприклад продуктові магазини, пальне й спорядження для кемпінгу) за 100 кілометрів. Планування — головне.

Burning Man — не фестиваль для відвідувачів (принцип Participation), а подія, яку творять самі учасники. Більшість квитків розподіляють між артистами й командами, які роблять свій унесок у фестиваль: будують арт-об’єкти, проводять перформанси, працюють у барах і кафе, збирають арт-кари або мутантні авто. Варто зазначити, що тут немає жодних комерційних відносин між учасниками: жодні послуги учасників не можна купити або продати, а бартер не вітається. Тому все, що учасники із собою привозять, призначено, крім побуту, для дарування іншим.

Український арт-об’єкт Catharsis

Процес підготовки

Відвідування Burning Man потребує палкого бажання, а купівля квитка — перша його перевірка. Квитки розподіляють у кілька етапів: серед учасників, які зробили свій унесок минулого року, серед артистів, які готують унесок цього року, і загальний продаж — Main Sale. Загальна ціна квитка для всіх учасників — орієнтовно $450, незалежно від особистого внеску. Індивідуально малозабезпечені учасники можуть придбати квитки зі знижкою. Щедріші учасники можуть укластися у квитки більше, придбавши їх на FOMO Sale за $1400, у такий спосіб допомагаючи неприбутковій компанії-організатору з витратами, а учасникам — з побудовою арту. Заборонено продавати квитки дорожче за собівартість. Покарання — анулювання квитка. Хоча щороку знаходяться унікальні люди, що платять тисячі за квиток, на практиці щороку в учасників та у спільнотах артистів на локальних групах події вдосталь квитків за собівартістю. Головна порада — якщо ви не змогли купити квиток на Main Sale, готуйтеся так, ніби квиток у вас є. Він знайдеться.

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

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

Костюми чомусь вважають невіддільною частиною Burning Man, особливо серед учасників з пострадянських країн. Burning Man — це не Геловін і не костюмована вечірка. Один з перших принципів звучить так: radical self-expression, а не radical impression. Не варто одягатися, щоб вразити когось. Одягайтеся так або тими, ким ви себе почуваєте. Хтось, хто 360 днів на рік ходить на роботу в офіс у краватці, чекатиме цього тижня, щоб нарешті побути собою: ходити в костюмі єдинорога, а для когось самовираженням буде звільнитися від одягу взагалі.

Цього року кілька проектів, що ми зреалізували, — це арт-кар T-Car і кемп друзів, які об’єдналися навколо нього. Оскільки зазвичай Burning Man-спільноти не мають розподілу на «організаторів» і «відвідувачів», то всі розділяють труднощі організації: як забезпечити достатній рівень комфорту й дотримуватися принципів? Труднощі логістичні, організаційні й технічні. Перетворити вантажівку, якій більше років, ніж мені, на унікальний витвір мистецтва зі світловими, аудіо- й вогняними ефектами. Скільки потрібно води на тиждень на 30 людей у пустелі? А на кухню? А на душ? А як збудувати в пустелі душ і ще й так, щоб жодна крапля не пролилася на землю? Як цю воду привезти, а залишки вивезти? Як провести світло від генераторів? Скільки потрібно пального? Як усі учасники табору дістануться зазначеного місця? Хто приїде раніше будувати інфраструктуру, а хто залишиться надовше, щоб її розбирати?

Паша Поповиченко, iOS-розробник у Trulia, Zillow Group, Сан-Франциско

У нашому словнику немає слова, яким можна описати Burning Man. Це не фестиваль, не тусовка й не івент. Ні відео, ні фото, ні слова не можуть пояснити, що таке Burning Man. Це не про візуал, а про емоції, які варто прожити.

Як я дізнався про Burning Man, або Yes, we must go

Уперше про Burning Man я почув від дівчини в Україні, але інформація відклалася десь on the back of my mind. Уже живучи в США, натрапив на влог Джессі Джеймсаі зрозумів, що це не фест, куди їдуть фотографуватися чи послухати музику, це — нагода відчути унікальні емоції. Я люблю отримувати нові враження: займаюся альпінізмом, катанням на лижах і серфінгом. Тому вирішив: потрібно їхати.

Проблем із квитками в мене не було, хоча купівля зайняла чимало часу. Щойно стартував продаж, тієї самої секунди я з кількох девайсів натискав на сайті кнопку «взяти участь», паралельно читаючи чати, де обговорювали придбання квитків. В одному з них порадили зайти з телефону в режимі «інкогніто». Так я зміг купити два квитки — для себе й друга, заплативши за кожен по $425.

Я був на Burning Man двічі: 2018-гой 2019-го.Ти можеш прочитати сотні історій, переглянути купу відео, але однаково не знатимеш, куди потрапиш і що на тебе чекатиме. Другий Burning Man пролетів швидше. Ми знали, чого очікувати, куди хочемо поїхати й що подивитися.

Найяскравіші враження: від пилу до обміну емоціями

Burning Man 2018 року зустрів мене штормом під час восьмигодинного стояння в черзі на вхід. Перше враження — це пил, що проникає всюди. Від пилу нікуди не втечеш, але швидко до нього звикнеш.

Burning Man — це про радикальне самовираження. Ти бачиш, що всі різні. Хтось голий, хтось у шубі, хтось у неоновому підсвічуванні, а хтось зі смолоскипом. Усі люди відкриті. Якщо говорити про Україну, то тут люди дуже закриті, а в США всі багато всміхаються, але це поверхнево. На Burning Man люди справді готові вислухати тебе й обмінятися позитивом.





Один з найяскравіших моментів якраз пов’язаний з розділенням емоцій. Я був у Temple — місці, наповненому атмосферою прощання. Там люди відпускають частинку себе: залежність, стосунки, минуле... Багато хто плаче, розкаюється й переживає справді потужні емоції. Там були gift-навушники, у яких лунав стрім гри на піаніно. Місце, музика, люди — уся ця комбінація змусила мене впасти на коліна й розплакатися. Емоції переповнювали. Тієї миті до мене підійшла незнайома дівчина, обійняла, подивилася просто в очі й пішла. Ця підтримка сповнила мене вірою в людство.

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

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

Арт

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

Мене вразив арт-об’єкт The Head Maze. Посеред пустелі — величезна металева голова, з якої лунає музика. Об’єкт закритий для доступу, бо недобудований, але ж на Burning Man немає правил. Я проліз, і виявилося, що цей арт-об’єкт — лабіринт із тематичними кімнатами.

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

Атмосфера: інша планета

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

Третього дня помітив, що на запитання: «Привіт, ти хто?» я почав називати себе по-іншому. Я не відповідав: «Паша, розробник, Сан-Франциско». Я не думав про роботу й зовнішній світ, а тому говорив: «Тішуся життям і намагаюся пізнати себе». На Burning Man ти їдеш, беручи із собою лише себе. Увесь зовнішній світ стає недосяжний.

Я раджу їхати на Burning Man і брати із собою дітей (для них є навіть окремий кемп). З таких дітей виросте покоління, яке зможе допомогти планеті, адже їх формує атмосфера безкорисливості, дарування й самовираження.

Лайфхаки, або Як зробити побут на Burning Man комфортнішим

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

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

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

Повернення до реального життя

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

Макс Тітов, СЕО в Altigee, Львів/Бангкок

Щойно я потрапив на локацію, повз мене проїхав диван, на якому двіжували люди. І тієї миті зрозумів: «Так, я вдома!». Я б порівняв Burning Man з дитячою грою, де кожен має роль. Хтось — бармен, хтось — пожежник. Знаєте, усі грали в такі ігри, де замість грошей листочки. Так ось BM — це коли 80 000 людей створюють свій світ, щоб грати в таку гру. Єдиний недолік Burning Man — потреба спати. Ти стомлюєшся й не встигаєш побачити все.

Одружився на цьогорічному Burning Man

Як я дізнався про Burning Man, або Компенсація за невтілений «Казантип»

Я завжди хотів потрапити на «Казантип», і коли нарешті вже зібрався, через відомі причини їхати вже було нікуди. Одного разу натрапив на фото з Burning Man і зрозумів, що хочу там побувати.

2018 року я поїхав уперше. Мені пощастило мати хорошу компанію й потрапити до кемпу «Куренівка», де все було облаштовано. А могло й не поталанити. На BM варто їхати з розумінням його 10 заповідей, одна з яких — бути самодостатнім. Потрібно подбати не лише про свій аутфіт, а й про забезпеченість водою, світлом і їжею. Це ж, зрештою, пустеля.

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

Квитки на 80 000 осіб: як не провтикати

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

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

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

Витрати й побут

Загалом цьогорічний Burning Man обійшовся в $4000.

  • літак до Сан-Франциско зі Львова — $1200;
  • оренда RV + бензин — $1200 (на 5 осіб);
  • квиток — $450;
  • кемп-fee — $300 (ціна залежить від кемпу — від $0 до 20 000);
  • одяг, lights, взуття та шуба — $300 (залежно від потреб можна витратити й менше);
  • їжа — $100;
  • алкоголь, засоби гігієни (вологі серветки — must have) тощо.

Важливо забезпечити себе всім потрібним, адже просто так залишати Burning Man і повертатися не можна. Минулого року в нас були проблеми з генератором, які на плаї (місце проведення BM — ред.)розв’язати не могли (класика закону Мерфі: усе, що може піти не так, піде). Тому довелося зробити коротку вилазку до Герлача — найближчого села. Цього ж року ми підготувалися й узяли два генератори про запас.

Костюм Mad Max і лосини

Як вибрати костюм? Одягнути те, у чому в буденному житті ніколи не вийдеш на вулицю. Оскільки Burning Man у мене асоціюється із сюжетом Mad Max — пустеля, пил та апокаліптичні пейзажі, — вибрав собі костюм типового героя постапокаліптичних фільмів: широкий плащ з обрізаними рукавами, круглі окуляри й штани. Також підібрав аутфіт для спекотних днів, у якому можна похизуватися накачаним торсом (я ж не дарма заморочуюся кросфітом і дієтами!): золоті трухани, золотий капелюх, прозорий халат...

Mad Max і лосіни

Кожен Burning Man має власну тематику. Якщо минулого року була тема «Я, робот» Айзека Азімова, то й костюми учасників містили елементи плат, мікросхем і біоніки. Цього ж року «Перевтілення» Франца Кафки відбилося на костюмах, пов’язаних з комахами, метеликами й іншими «метаморфозами». До речі, на Burning Man є тематичні дні. Наприклад, день пачки. Усі вдягають балетну пачку — і чоловіки, і жінки. Ще є день білого, коли всі намагаються вдягнути біле.

Boeing, піраміда, торт

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

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

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

Був також палац у формі торта — «храм радості». Люди приходили туди, лишали записки, а потім «торт» спалили й усі меседжі «здійнялися в космос».

З найкрутіших сцен — це, безперечно, пересувний Boeing і піраміда, усередині якої вечірка, а зовні — кіноекран.







Про українські арт-об’єкти

Метелик «Катарсис» — це максимально український арт. Від свого творіння я отримав дуже сильні емоції. З одного боку, тому що це — своє, а з іншого — вийшло справді класно. Створити арт-об’єкт — це насправді запустити свій стартап і зробити його успішним.

Ми втілили тему «Метаморфози» Кафки сповна! Цікаво, що задум створити метелика під назвою «Метаморфози» з’явився ще до оголошення тематики Burning Man 2019. Дізнавшись тему, нам довелося змінити назву проекту на «Катарсис», що означає момент змін у житті людини. Кожен з нас переживав чимало катарсисів, і Burning Man — один з них.

Команда з Дніпра збудувала кокон (проект Cocoonap), що вдень схожий на писанку, а вночі оживає: повільно розкривається, показуючи дві постаті людей із крилами янголів, що підносяться, а потім згасають. Цей об’єкт розповідає історію про народження, кохання та смерть. Об’єкт дуже кінетичний і складний з інженерного погляду.

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

Вікторія Придатко, IT-рекрутер, засновниця VP Team, Київ

На Burning Man всі вдягаються так, як заманеться. Мій костюм не мав супер-ідеї, хотілось просто відірватісь. У BDSM-вбранні можна вийти або на Бернінгем, або на BDSM-вечірку. А з огляду на те, що рекрутинг — той ще BDSM, я одяглася, можна сказати, професійно.

Не знати про Burning Man складно, адже всі про нього говорять. Давно хотіла поїхати, бо мені імпонує ідея дарування і взаємного безгрошового обміну, що є ключовою цінністю «бьорна». Цього року нарешті все склалось. Квитки допоміг придбати Ярослав Корець, співзасновник Kurenivka camp (першого українського кемпу в пустелі Black Rock), бо я волонтерила в цьому кемпі (у тому числі — ліпила фігурки глиняних «дітей» для проекту «Сад теплих дітей»).

Компанія сформувалась з друзів подруги і моїх приятельок. Ми прилетіли в Сан-Франциско, а звідти автобусом доїхали до Ріно, де на нас уже чекав RV. На Burning Man потрапила пізно вночі. Опинилась на плаї і була приголомшена. Вдень відчувала себе на іншій планеті: яскраве блакитне небо, шалені арт-об’єкти. Сподобався пегас, що палає. Це один з найголовніших арт-об’єктів «бьорна».

Я ціную комфорт: жити в таку спеку в наметі не хотіла б. На п’ятьох осіб орендований RV з душем і кондиціонером обійшовся в $6 500. Дорожче, ніж могло бути, адже його нам пригнали в Ріно і забирали там же. Інакше довелося б самостійно забирати і відвозити назад. За це заплатили $1 500 «зверху».









Один з принципів Burning Man — самозабезпечення, тож важливо вирішити питання харчування до того, як потрапиш на плай. Був варіант заплатити $250 за тиждень і харчуватись в кемпі (сніданки, обіди, вечері і снеки). Але оскільки для мене їжа була важкуватою, я їла те, що ми купили в супермаркеті і зберігали в холодильнику в RV. У пустелі можна придбати лише каву і лід, хоча є багато кемпів, що пригощають їжею безкоштовно. Найкраще — це дуже душевна атмосфера, відкриті і щирі люди. Вони діляться з тобою, а ти — з ними.

Гриша Шехет, Software Engineer в Grammarly, Сан-Франциско

О Burning Man я узнал на третьем курсе университета. Тогда моего Product Manager пригласили на «Громадське», где он рассказывал про свой опыт посещения ивента. Привет, Саша. После просмотра репортажа я решил когда-нибудь попасть в Black Rock City. Спойлер: через 4 года у меня это получилось :)

Основная проблема, которая стоит перед поездкой на BM, это покупка билета, так как алгоритм работы очередей не поддается здравому смыслу. К примеру, ты можешь зайди на сайт спустя час от начала продажи и приобрести билет за 4 минуты. А можешь создать 100500 аккаунтов, менеджить их в облаке и в результате ни один из них не купит заветный кусочек картона.

Для счастливчиков по жизни все же есть лайфхак, которым я и воспользовался: Burning Express Ticket. В определенные дату и время вы можете зайти в личный кабинет и купить билет на автобус, который дает возможность без очередей приобрести долгожданный «абонемент» на праздник жизни. Недостаток метода — это гибкость в транспортации на BM: вы можете добраться только на автобусе.

Проблем с поиском компании и кемпа на фестиваль у меня не было. Так как я живу в Сан-Франциско, у меня много хороших друзей, которые регулярно посещают ивент. Также не стал огромным челенджем и выбор костюмов. Как-никак, XXI век на дворе: все можно заказать в интернете (AliExpress, Amazon и т. д.). В общем, пара дней в сети — и ты абсолютно готов покорять пустыню!

Что же такое Burning Man

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

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

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

Во-первых, это мир без интернета и технологий. В эпоху диджитализации ты часами просиживаешь за монитором, забывая про внешний (настоящий) мир. Забавно, но потеря сети может творить удивительные вещи! К примеру, тебе нужно встретится с другом, который живет в другом лагере. Ты отправляешься к нему, а его нет на месте. И наоборот, он приезжает к тебе и по случайному стечению обстоятельств не застает тебя на месте. Просто челлендж ХХI века. Apple, где мой почтовый голубь?

Во-вторых, это факт существования самого Black Rock City. Только представьте: за одну неделю посреди безлюдной пустыни Невады строится новый город, который не похож ни на один населенный пункт мира. В нем есть своя культура и обычаи, нет бюрократии и ты можешь осуществить любую задумку. Представьте обычную ситуацию: вы едете по ночной пустыне и мимо вас проносится привидение из пакмана, которое убегает от гигантской рыбы! Гигантской Рыбы, Карл!

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

Если сложить это все вместе, то ты оказываешься в самом интересном месте во Вселенной. Вокруг тебя есть океан возможностей и занятий. Все зависит только от тебя!

Об искусстве

Как ни странно, но арт-объектом на Burning Man может быть все, что угодно. Начиная с луков участников фестиваля: поверьте, интересных образов на нем хватало.

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

На очереди — перфомансы. Чем вам не арт-проекты? К примеру, я успел трижды посмотреть выступление различных труп Cirque du Soleil и даже умудрился на одном уснуть. Чувствую, стал чересчур разборчивым за время Burning Man.

Идем дальше: арт-кары. Если вы думаете, что машиной вас сложно удивить, то вы ошибаетесь. Такое ощущение, что автоконструкторы со всего света смогли реализовали все свои детские мечты именно здесь. Вот вам автомобиль в виде дракона, а здесь проезжает мост Golden Gate. Все доходит до совершенно немыслимых масштабов трансконтинентального Boeing-747, которые превратили в самый настоящий трехэтажный клуб!

Ну и напоследок об арт-инсталляциях. Тут их миллион: на любой вкус и цвет. Мой топ-5:

  • Paraluna — в простонародье «ромашка». Отличный визуальный перфоманс под симфонический оркестр. Лидер в номинации «Залипательно».
  • Sky whale project — представьте ситуацию: вы едете на велосипеде и вдруг на горизонте в небе вы видите гигантского кита...
  • The Folly — мини-городок с живой музыкой, артом и сценой талантов.
  • Wings of Glory — гиганский, не побоюсь этого слова, пегас, которым можно управлять!
  • The Temple of Direction — символическое место, где каждый оставляет частичку себя или пишет пожелания близким, которых уже нет. В последний день фестиваля темпл сжигают, отпуская все, что в нем было. Очень сильное зрелище...




О лучшем

В изобилии океана етрекшинов BM сложно выдилить что-то лучшее. Но я постораюсь составить свои топ-3.

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

Дикий рейв.Если вы фанат edm или техно, то вы однозначно созданы для BM: (потрясающий визуальный ряд и локейшн), «Experience Incendia (рейв под огненным куполом) и Mayan Warrior (звук этого арт-кара звучит в моей голове и сейчас).

Рассвет.Скажу по секрету, самое прекрасное всегда происходит по окончанию приключения — на рассвете. Главное — до него дожить!

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

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

Юліана Осельська, Product Marketer, ex-YouTeam, Лондон

Вперше дізналась про Burning Man, коли у 2015 році в Facebook побачила фото арт-об’єкту «Любов», який Олександр Мілов з Одеси того року привіз у пустелю. Двоє дорослих після сварки сидят спинами, а всередині кожного з них — маленька дитина. Діти стоять обличчями одне до одного і їх лодоні торкаются. Це фото зворушило мене і спонукало більше дізнатись про Burning Man. Тоді я думала про це як виставку тимчасових арт-об’єктів в пустелі, які спалюють в кінці (як виявилось, спалюють далеко не всі). Але я навіть і не думала про те, як туди потрапити, тому що це ж майже нереально: «Я ж не митець».

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

У листопаді 2018 спільнота «бьорнерів» України організувала вечірку «Burning Man Decompression Kyiv». Тоді я ще не розуміла значення «decompression» («коли ти повертаєшся до реальності»), але думала, що це буде класна нагода, щоб законектитись і зрозуміти, чи такого роду люди будуть мені по духу. Це був один з найяскравіших івентів, на яких я була в Києві: одночасно можна було побачити і вбрання монашок, і відверті костюми, і все світилися вночі. Було доволі дивно у перші хвилини. А вже через мить мене з кінцями потягнуло до цих людей.

«Decompression Kyiv», 2018

Квитки — не проблема, головне — бажання

Для безпеки і комфорту (наскільки це можливо у пустелі) кількість учасників лімітована. Квитки розпродаються онлайн у перші 2-3години в порядку електронної черги. Буквально! Тому важливо спробувати не провтикати їх, але це вже як пощастить.

Вартість стандартного квитка $425. Є три основні хвилі: Pre-Sale ($1400), Main Sale ($425), OMG Sale ($550). Для кожної хвилі завчасно потрібно зареєструватись на сайті і вичікувати офіційного часу, коли стартує продаж онлайн. Рекомендують купувати відразу 2 квитки (це і є максимум на один акаунт), адже другий квиток завжди знайдеться кому продати з друзів.

Нам не пощастило. Сервер був перевантажений і ми не купили квитків з офіційного продажу. Але друзі сказали: «Квитки — це не проблема. Головне, щоб було бажання і ми їх знайдемо».

І ми знайшли ще одну (як виявилось пізніше, набагато кращу) опцію: долучитись до команди арт-проекту. Неприбуткова організація Burning Man Project, яка відповідає за всі квитки, забезпечує окрему кількість квитків для кемпів (Directed Group Sale). Як правило, кемпи мають три основні функції: вони будують саму інфраструктуру події, де живуть люди, допомагають арт-командам з їх інсталяціями і організовують воркшопи чи інші «experiences» на плаї. Ми стали частиною команди Catharsis.

Частина команди Catharsis біля самої інсталяції

Український метелик у пустелі не може не надихати

Коли мені запропонували долучитись до команди арт-об’єкту в квітні цього року, я спершу була далеко не в захваті. «Що? Доведеться ще щось і робити?». Тоді я ще не розуміла, що gifting («дарувати») — один із 10-типринципів спільноти Burning Man. Але щойно ми провели перший відео-дзвінок з основною частиною команди у Сієтлі, я відразу захотіла долучатись.

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

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

Самовиживання (self-reliance) — один з 10-типринципів Burning Man

Black Rock City — це тимчасове місто, яке будують винятково для події Burning Man раз на рік. В усі інші місяці, крім серпня, це пустеля, де немає рослин і живності. Тут потрібно виживати. І це є одним із десяти принципів BM: розраховувати на власні ресурси впродовж усього перебування в пустелі.

Кожна людина повинна сама подбати про те, де вона буде спати, що буде їсти, як і де буде митись. І що важливо — Leaving No Trace («не залишати сміття») — ще один принцип спільноти. Щоб полегшити організацію інфраструктури, люди об’єднуються в кемпи і буквально все завозять (і після все-все вивозять) для побудови міста Black Rock City.

Будучи частиною команди Catharsis, ми були закріплені за кемпом «Rouge Nation Village». Ми орендували RV, у ньому приїхали і в ньому жили. Було дуже комфортно, оскільки, на відміну від shiftpod чи наметів, у нас був кондиціонер, що часто рятувало у самий пік спеки вдень.

Виживання не тільки групою, а й наодинці

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

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

Burning Man — це про самовираження, людей і досвід

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

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

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

Irene Avetisyan, 10+ лет в IT outsourcing, co-founder в IT startups, Киев

В прошлом году в случайном разговоре знакомая упоминала, что ее друзья едут на Burning Man, и за менее чем неделю до начала, мне повезло спонтанно попасть в лагерь «Борщ» от Украины. Для меня это было интуитивное решение: я просто ехала за новым опытом.

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

Мы собирались в Солт-Лейк Сити, там же делали финальные закупки в лагерь, забирали арендованные RV и оттуда колонной ехали на Burning Man.

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

«Берн» — это постоянные события на протяжении 24 часов каждый день. Ты выбираешь и принимаешь решение, каким образом хочешь в этом участвовать. Иногда хотелось танцевать под громкую музыку среди толпы людей, а иногда — просто лежать под звездами или кататься между объектами, наблюдая, как они меняются и создают атмосферу, мысли. Во время первого «Берна» в 2018 году меня больше всего впечатлили объекты, инсталляции, особенно в ночное время, когда они все сияют, движутся и каждая создаёт своё настроение. Второй «Берн» в 2019 году — больше про людей и личные внутренние открытия. Оба раза это о людях, о создании и проявлении, внутреннем переосмыслении и осознанности.





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

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

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


Коммуникации в жизни QA: как понимать людей и поддерживать хорошие отношения со всеми

$
0
0

Меня зовут Оксана Харчук, и я QA-специалист в компании DataArt. Проработав более 5 лет в качестве QA Engineer и QA Lead на разных проектах, обучив при этом несколько практикантов, я сделала вывод, что все люди разные и у каждого, как говорится, свои тараканы в голове, но найти общий язык можно абсолютно со всеми. В этой статье я расскажу о роли коммуникаций в жизни QA.

Круг общения QA

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

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

Дизайнеры

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

Разработчики

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

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

Причины, по которым Dev и QA могут не ужиться

Черствость и равнодушие

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

Неумение принимать критику

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

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

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

Сложные люди

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

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

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

Советы для счастливой совместной жизни Dev и QA

Не судите строго за ошибки

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

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

Обменивайтесь идеями

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

Будьте реалистами

Бывает, сидишь и ловишь баг полдня, выписываешь шаги, а потом бац — и он уже со статусом «won’t fix» или «it is not a bug», и на глазах появляются слезы, потому что потрачено столько времени и сил. Будьте реалистами, постарайтесь понять причину, по которой баг был отклонен. Может, вы что-то неправильно поняли или предположили. Постарайтесь убедить разработчика или менеджера устранить баг, если вы считаете, что представленный вами сценарий был верным, и двигайтесь дальше.

Расставляйте приоритеты повсюду

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

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

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

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

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

Бизнес-аналитики

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

На следующем проекте мне посчастливилось поработать с Senior BA, и, скажу честно, поначалу я не понимала, насколько мне повезло. Только спустя несколько месяцев я осознала, как удобно работать с бизнес-аналитиком, и выделила следующие плюсы:

  • Хорошие требования. User Stories ориентированы на бизнес, нет зависимости со стороны разработки — есть задача, которую требуется выполнить. А вот как — это уже головная боль разработчиков.
  • Есть на кого спихнуть.Если в функциональности заказчику что-то не понравилось, вы всегда можете сказать, что она реализована согласно заявленным требованиям, и тогда уже бизнес-аналитик объясняет, откуда он взял такие требования.
  • Лучшее понимание, есть возможность обсудить, взвесить все за и против и принять необходимое решение на ранней стадии разработки.

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

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

Заказчики

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

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

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

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

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

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

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

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

Все вышесказанное может принести вам и вашей команде следующие плюсы:

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

Заключение

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

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

Развивайте свои soft skills, двигайтесь по карьерной лестнице вверх, цените свое время и время других.

От джуниора к лидеру. Какие навыки нужны для роста в профессии

$
0
0

С лета этого года мы в компании Namecheap, Incзапустили экспериментальный отдел R&D для формирования и реализации перспективных разработок и фасилитации инноваций среди наших инженеров. А значит, появилось время порефлексировать на тему карьерного роста в IT-индустрии и собрать мнения коллег по цеху...

Image Source: Unsplash

В процессе движения по карьерной лестнице от новичка в веб-разработке до руководящих должностей в компании (я побывал в роли от Junior до Senior Software Engineer, Team Lead, Scrum Master, Product Owner, Head of the technical stream, Solution and System Architect и DevOps), всегда было трудно понять, какие навыки нужно развивать для движения вперед.

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

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

Базовая модель

Для визуализации дальнейших тезисов давайте воспользуемся широко распространенной и простой моделью Т-образного набора навыков (T-shaped skillset).

В целом каждый специалист обладает:

  • Некоторыми фундаментальными знаниями, связанными с профессиональной сферой, без которых было бы чрезвычайно сложно построить свою карьеру, так как все остальное обычно ложится поверх них. Например, чтобы стать инженером по машинному обучению, вы должны иметь сильные математические навыки.
  • Базовые навыки в смежных областях. Например, для Front-end Web Developer это Design, UX, Back-end development, управление проектами и т. д. Этот вид знаний помогает вам эффективно общаться с коллегами.
  • Личностные качества (soft skills) в таких областях, как лидерство, эмоциональный интеллект, самоконтроль, наставничество и т. д. Они необходимы, чтобы иметь возможность четко выражать свои идеи и результаты работы, строить доверительные отношения со своими товарищами по команде, с менеджером и подчиненными. А также справляться со своими и командными неудачами и строить неформальные отношения, которые чрезвычайно важны.
  • И конечно, у вас должны быть глубокие знания в одной или несколько конкретных областях. Обычно это те навыки, благодаря которым вы были наняты. И это ваше самое мощное оружие для завоевания рынка.

В следующих разделах следите за ростом различных секций на диаграмме. И давайте начнем с самого начала :)

Имейте в виду, это усредненное представление карьерного роста. Но мы все ведь особенные, верно? Так что корректируйте модель в соответствии с вашими сильными и слабыми сторонами по ходу дела.

Junior Engineer

Итак, вам повезло и после нескольких лет интенсивного обучения вас наняли на позицию Junior [your tech] Engineer. Вероятнее всего, ваш Т-образный набор навыков выглядит следующим образом:

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

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

Middle Engineer

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

Обычно в течение первых 1-2лет вы можете практически удвоить свой основной навык, получить представление о работе, выполняемой вашими коллегами (по смежным специальностям), и прокачать свои личностные навыки.

Теперь вы можете делать практически все под менторством более опытного коллеги. Проверьте, можете ли вы сказать это о себе :)

Senior Engineer

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

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

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

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

Team/Tech Leader

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

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

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

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

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

Architect / Head of the department

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

Architect

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

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

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

Head of department

Если же вы выбрали «альтернативный» путь для своей карьеры, у меня есть для вас сюрприз :) Вот так скоро будут выглядеть ваши навыки:

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

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

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

Заключение

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

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

Желаю вам всего наилучшего в процессе саморазвития и достижения карьерного успеха!

Оставляйте свои комментарии и замечания. Всегда интересно услышать мнение коллег и изучить альтернативный опыт :)

Как GlobalLogic создавала EcoHike — приложение для туристов, которые хотят очистить Карпаты от мусора

$
0
0

В рубрике DOU Labsмы приглашаем IT-компании делиться опытом собственных интересных разработок и внутренних технологических инициатив. Вопросы и заявки на участие присылайте на editors@dou.ua.

Привет! Меня зовут Юрий Голованов, я отвечаю за развитие мобильной практики во львовском офисе GlobalLogic. Вместе со своей командой мы занимаемся созданием решений для мобильных устройств на iOS и Android. В июле мы запустили приложение EcoHike, некоммерческий социальный проект компании, цель которого сделать Карпаты чище. Теперь путешественники могут отмечать на карте загрязненные участки. Соответственно, другие пользователи могут проложить маршрут своего отдыха так, чтобы убрать отмеченную местность. В этом материале я расскажу подробнее о технической реализации проекта.

Как возникла идея и с чего начиналось приложение

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




Подобные проекты и команда разработчиков

Разумеется, не мы первыми взялись решать подобную задачу. Приложения с похожим функционалом для систематизации и организации процесса уборки мусора на разной местности уже были реализованы. Подобный проект — приложение TrashOut, созданное в Словакии. По сценарию информацию о метках получают экологические организации, активисты и власти по e-mail. В Украине на карте этого приложения, по последним данным, отмечены более 600 мест, чуть меньше 20 из них были в результате убраны. Другие приложения сосредоточены на горахили отдельных городах. Еще до нашего проекта в Украине была создана Ecomapa, интерактивная карта Министерства экологии и природных ресурсов Украины. Ее целью в первую очередь было обращение граждан и контроль властей для решения проблемы загрязнения окружающей среды.

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

У нас никогда не было цели сделать EcoHike коммерческим, поэтому мы не привлекали инвестиции и не измеряли денежный эквивалент приложения. Проектом занимались в свободное от основных задач время, а модерация осуществляется целиком на добровольных началах. На разных этапах в проекте EcoHike было задействовано 7–8 человек.Кто-то приходил, кто-то уходил, но в основной команде всегда было 5 человек: техлид, iOS-, Android- и веб-разработчики.

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

Сейчас существует много решений для написания кода одновременно для двух основных мобильных операционных систем (таких, как Xamarin, React Native, Flutter и т. д). Мы сознательно отказались от использования этих инструментов в пользу «нативной» разработки, что позволило улучшить производительность и скорость отклика приложения. Использовали Swift для iOS, Kotlin и Java для Android, а также библиотеку Mapboxдля работы с картами. Это позволяет сохранять карты в офлайне без дублирования секторов, благодаря чему можно сэкономить место в памяти устройства.

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

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

  1. Наличие интернета.
  2. Интервал перезапуска (то есть, если произошла неудачная попытка, условно через десять минут запрос повторится, но время повтора будет увеличиваться экспоненциально).

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

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






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

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

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

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

Сложности во время создания приложения

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

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

Приложение в действии и планы по развитию

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






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

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

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

Во-первых, установите себе приложение EcoHike для iOSили Android. Попробуйте его в действии и дайте нам обратную связь.

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

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

Для связи с командой EcoHike пишите на почту ecohike@globallogic.com. Больше о приложении в нашем видео.

ANTLR: немного теории

$
0
0

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

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

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

Грамматика

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

Существует очень много определений грамматики, но пока они нам не нужны. В ANTLR используется только небольшое подмножество. Итак, контекстно-независимая порождающая грамматика — это не более, чем набор продукций, выражений вида X → Y, где X и Y — цепочки символов или правил. Начинается грамматика со стартового правила, например S.

Если путём подстановки из главного правила можно получить некоторую строку, она соответствует грамматике. Если нельзя, то нет.

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

S → (S)
S→ ɛ, где ɛ - специальный символ, обозначающий пустоту.

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

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

Спецсимволы, или Расширенное определение грамматик

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

Альтернативы

Если мы хотим сказать, что правило A порождает цепочку B, это можно записать так:

A → B
A → C

или так:

A → B|C

Перечисления

Чтобы сказать, что цепочка встречается один или более раз, используется символ «+», нуль или более раз - «*», нуль или 1 раз - «?».

Пример. Допустим, мы хотим создать грамматику, описывающую цепочку букв «a».

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

S→a+

Если мы хотим, чтобы грамматике соответствовала цепочка вообще без букв, запишем это так:

S→a*

В случае, когда буква «а» может встретиться нуль или один раз, так:

S→a?

Теперь вернёмся к грамматике из предыдущей статьи.

actions:action+;

action:moveTo|lineTo;

moveTo: moveToName='MoveTo' '(' x=INT ',' y=INT ')';

lineTo: lineToName='LineTo' '(' x=INT ',' y=INT ')';

INT :'-'? DIGIT+ ; 
fragment DIGIT : [0-9];

Как видно, в ANTLR вместо стрелочек используется двоеточие (возможно, потому, что стрелочка относится к спецсимволам и её просто нет на большинстве клавиатур). В остальном применение спецсимволов совпадает с определением, данным выше. Кое-что из текущей грамматики осталось не до конца описанным. Самое время дать пояснения.

Лексический и синтаксический анализ

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

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

Обратите внимание на грамматику из предыдущей статьи. В ней есть правила, начинающиеся с большой буквы, — это лексемы. И с маленькой — это, собственно, правила. Разбиение на правила и лексемы, в общем-то, условно. В самом деле, что считать правилом, а что лексемой? В ANTLR есть одно важное отличие: правила могут состоять из правил, лексем и строк; лексемы — только из строк, других лексем и фрагментов. Что же такое фрагмент? Это часть грамматики, которая может быть только частью лексемы, частью же правила быть не может. То есть вот так написать можно:

INT :'-'? DIGIT+ ; 
fragment DIGIT : [0-9];

А так нет:

int :'-'? DIGIT+ ; 
fragment DIGIT : [0-9];

Леворекурсивные грамматики

Один мудрый человек сказал, что после фразы «один мудрый человек сказал» обычно пишут какую-то дурь. ©

ANTLR, как и любое другое программное обеспечение, не упало нам с неба. Его кто-то написал и в процессе пользовался неким алгоритмом. Он называется LL(1)-парсинг, или леворекурсивный парсинг, или рекурсивный обход слева направо. Приводить его алгоритм целиком мы не будем, желающие могут погуглить. Но важно, что с правилом, содержащим самого себя в правой части, без продвижения по строке этот алгоритм справиться не может. То есть при обработке вот такого правила:

A→Aabc

он зациклится. Пояснить это в двух словах можно так: алгоритм этот разбирает грамматику слева направо, рекурсивно. То есть при разборе предыдущего правила вызовется правило для разбора A рекурсивно. Потом ещё раз A и ещё раз. И так пока не переполнится стек.

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

Value→[0-9]+ ‘/’ '(' Expr ')'
Product → Expr (('*' / '/') Expr)*
Sum     → Expr (('+' / '-') Expr)*
Expr    → Product |Sum | Value

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

Какой код генерирует ANTLR

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

Листенер

Для листенера ANTLR генерирует интерфейс, наследуемый от ParseTreeListener. В нем для каждого правила или метки (мы вернемся к ним позже).

Он выглядит вот так:

 // Generated from CuttingLanguage.g4 by ANTLR 4.4
package org.newlanguageservice.ch1;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTreeListener;

/**
 * This interface defines a complete listener for a parse tree produced by
 * {@link CuttingLanguageParser}.
 */
public interface CuttingLanguageListener extends ParseTreeListener {
	/**
	 * Enter a parse tree produced by {@link CuttingLanguageParser#action}.
	 * @param ctx the parse tree
	 */
	void enterAction(@NotNull CuttingLanguageParser.ActionContext ctx);
	/**
	 * Exit a parse tree produced by {@link CuttingLanguageParser#action}.
	 * @param ctx the parse tree
	 */
	void exitAction(@NotNull CuttingLanguageParser.ActionContext ctx);
	/**
	 * Enter a parse tree produced by {@link CuttingLanguageParser#lineTo}.
	 * @param ctx the parse tree
	 */
	void enterLineTo(@NotNull CuttingLanguageParser.LineToContext ctx);
	/**
	 * Exit a parse tree produced by {@link CuttingLanguageParser#lineTo}.
	 * @param ctx the parse tree
	 */
	void exitLineTo(@NotNull CuttingLanguageParser.LineToContext ctx);
	/**
	 * Enter a parse tree produced by {@link CuttingLanguageParser#actions}.
	 * @param ctx the parse tree
	 */
	void enterActions(@NotNull CuttingLanguageParser.ActionsContext ctx);
	/**
	 * Exit a parse tree produced by {@link CuttingLanguageParser#actions}.
	 * @param ctx the parse tree
	 */
	void exitActions(@NotNull CuttingLanguageParser.ActionsContext ctx);
	/**
	 * Enter a parse tree produced by {@link CuttingLanguageParser#moveTo}.
	 * @param ctx the parse tree
	 */
	void enterMoveTo(@NotNull CuttingLanguageParser.MoveToContext ctx);
	/**
	 * Exit a parse tree produced by {@link CuttingLanguageParser#moveTo}.
	 * @param ctx the parse tree
	 */
	void exitMoveTo(@NotNull CuttingLanguageParser.MoveToContext ctx);
}

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

Визитор

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

Метки грамматик

Допустим, имеется вот такая грамматика:

grammar Arithmetic;

expr
:   expr '+' expr #plus
	| expr '-' expr #minus
	| expr '*' expr #mul
	| expr '/' expr #div
	| INT #int
;

INT :[0-9]+;

WS: [ \t\r\n]+ -> skip; 

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

Выглядеть это будет так:

// Generated from Arithmetic.g4 by ANTLR 4.7.2
import org.antlr.v4.runtime.tree.ParseTreeVisitor;

/**
 * This interface defines a complete generic visitor for a parse tree produced
 * by {@link ArithmeticParser}.
 *
 * @param <T> The return type of the visit operation. Use {@link Void} for
 * operations with no return type.
 */
public interface ArithmeticVisitor<T> extends ParseTreeVisitor<T> {
	/**
	 * Visit a parse tree produced by the {@code div}
	 * labeled alternative in {@link ArithmeticParser#expr}.
	 * @param ctx the parse tree
	 * @return the visitor result
	 */
	T visitDiv(ArithmeticParser.DivContext ctx);
	/**
	 * Visit a parse tree produced by the {@code minus}
	 * labeled alternative in {@link ArithmeticParser#expr}.
	 * @param ctx the parse tree
	 * @return the visitor result
	 */
	T visitMinus(ArithmeticParser.MinusContext ctx);
	/**
	 * Visit a parse tree produced by the {@code mul}
	 * labeled alternative in {@link ArithmeticParser#expr}.
	 * @param ctx the parse tree
	 * @return the visitor result
	 */
	T visitMul(ArithmeticParser.MulContext ctx);
	/**
	 * Visit a parse tree produced by the {@code int}
	 * labeled alternative in {@link ArithmeticParser#expr}.
	 * @param ctx the parse tree
	 * @return the visitor result
	 */
	T visitInt(ArithmeticParser.IntContext ctx);
	/**
	 * Visit a parse tree produced by the {@code plus}
	 * labeled alternative in {@link ArithmeticParser#expr}.
	 * @param ctx the parse tree
	 * @return the visitor result
	 */
	T visitPlus(ArithmeticParser.PlusContext ctx);
}

Смотрите, появились правила visit..., где ... — имя метки. Хотя в грамматике таких правил нет.

В завершение

Вот вкратце всё, что я хотел рассказать по теории. На первое время хватит. Будут и другие экскурсы, но непосредственно, когда они понадобятся. Следующая статья будет посвящена обзору инструментов для ANTLR-разработки.


Предыдущая часть цикла:ANTLR: неформальное введение

Как UICollectionViewDiffableDataSource упрощает разработку UICollectionView

$
0
0

В предыдущей статьея поделился результатами своих исследований UICollectionViewCompositionalLayout. Но всем опытным разработчикам известно, что UICollectionViewсостоит из двух частей: Layout и DataSource. В этой статье я рассмотрю вторую половину, которую представили на WWDC, — UICollectionViewDiffableDataSource.

Если вы где-то слышали или читали о IGListKit, то вам UICollectionViewDiffableDataSourceпокажется очень знакомым. Действительно, Apple, как это часто бывает, взяла за основу идею, которая реализована в IGListKit, и представила свое решение.

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

open class UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType> : NSObject, UICollectionViewDataSource where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable 

public struct NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType> where SectionIdentifierType : Hashable, ItemIdentifierType : Hashable

UICollectionViewDiffableDataSource

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

 public typealias CellProvider = (UICollectionView, IndexPath, ItemIdentifierType) -> UICollectionViewCell?

    public typealias SupplementaryViewProvider = (UICollectionView, String, IndexPath) -> UICollectionReusableView?

    public var supplementaryViewProvider: UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.SupplementaryViewProvider?

    public init(collectionView: UICollectionView, cellProvider: @escaping UICollectionViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType>.CellProvider)

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

open func apply(_ snapshot: NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>, animatingDifferences: Bool = true, completion: (() -> Void)? = nil)

    open func snapshot() -> NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>

    open func itemIdentifier(for indexPath: IndexPath) -> ItemIdentifierType?

    open func indexPath(for itemIdentifier: ItemIdentifierType) -> IndexPath?

Давайте вспомним, что нам предоставляла Apple раньше. До этого момента у нас был объект, который хранил все данные для коллекции и являлся для нее UICollectionViewDataSource. Он возвращал количество секций, элементов, ячеек и т. д. Если нам было необходимо вставить, удалить, переместить элементы в коллекции, то для начала нужно разобраться, что изменилось в наших данных, и потом сообщить об этом коллекции, воспользовавшись этими методами.

 open func insertSections(_ sections: IndexSet)
    open func deleteSections(_ sections: IndexSet)
    open func reloadSections(_ sections: IndexSet)
    open func moveSection(_ section: Int, toSection newSection: Int)

    open func insertItems(at indexPaths: [IndexPath])
    open func deleteItems(at indexPaths: [IndexPath])
    open func reloadItems(at indexPaths: [IndexPath])
    open func moveItem(at indexPath: IndexPath, to newIndexPath: IndexPat

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

  1. Сложно найти разницу в изменениях, для этого нужен какой-то алгоритм.
  2. Вызывая performBatchUpdates, очень нередко можно было увидеть вот это:
Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).

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

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

NSDiffableDataSourceSnapshot

Эта структура представляет собой слепок данных, который обрабатывает DataSource. У него есть все методы для манипуляции данными: insert, move, delete, append, reload. Не буду останавливаться на этих методах подробнее, думаю, все понятно и новичкам. Лучше постараюсь объяснить то, что не описано в документации.

В основе данных слепка лежат два дженерик-элемента:

SectionIdentifierType : Hashable
ItemIdentifierType : Hashable

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

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

public mutating func appendItems(_ identifiers: [ItemIdentifierType], toSection sectionIdentifier: SectionIdentifierType? = ni

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

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

Слепок можно использовать двумя способами. Первый способ — взять уже текущий у DataSource и изменить его.

open func snapshot() -> NSDiffableDataSourceSnapshot<SectionIdentifierType, ItemIdentifierType>

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

@objc func reloadItem() {
        var snapshot = dataSource.snapshot()
        var item = snapshot.itemIdentifiers[2]
        item.value = Int.random(in: 1...25)
        snapshot.deleteItems([item])
        snapshot.insertItems([item], beforeItem: snapshot.itemIdentifiers[2])
        snapshot.reloadItems([item])
        dataSource.apply(snapshot, animatingDifferences: true)
    }

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

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

func dataSnapshot() -> NSDiffableDataSourceSnapshot<Section, Item> {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections(sections)
        snapshot.appendItems(firstSectionData, toSection: .first)
        if sections.contains(.second) {
            snapshot.appendItems(secondSectionData, toSection: .second)
        }
        if sections.contains(.third) {
            snapshot.appendItems(thirdSectionData, toSection: .third)
        }
        return snapshot
    }

Бонус

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

Метод applyкласса UICollectionViewDiffableDataSourceможно вызывать в background-потоке, он будет там просчитывать все изменения, а методы UICollectionViewавтоматически вызовет в основном потоке. Это нужно в случае, если у вас большие объемы данных, по которым нужно рассчитывать разницу. Есть одно ограничение: метод apply нужно следует вызывать в одном и том же потоке, иначе вы увидите предупреждение в логах, и разработчики не обещают нормального поведения класса в таком случае.

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

UIView.animate(withDuration: 2) {
      self.dataSource.apply(snapshot, animatingDifferences: true)
  }

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

Первый способ — это применение ассоциированных enum.

enum Item: Hashable {
        case string(String)
        case number(Int)
    }

dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collection) {
            (collectionView: UICollectionView, indexPath: IndexPath, item: Item) -> UICollectionViewCell? in

            // Get a cell of the desired kind.
            guard let cell = collectionView.dequeueReusableCell(
                withReuseIdentifier: TextCell.reuseIdentifier,
                for: indexPath) as? TextCell else { fatalError("Cannot create new cell") }

            // Populate the cell with our item description.
            switch item {
            case .number(let value):
                cell.configureWith(text: "Section \(indexPath.section), Row \(indexPath.row), Item \(value)")
            case .string(let value):
                cell.configureWith(text: "Section \(indexPath.section), Row \(indexPath.row), Item \(value)")
            }

            // Return the cell.
            return cell
        }

Второй — использовать структуру-обертку AnyHashable.

struct IntItem: Hashable {
        let id = UUID().uuidString
        var value: Int
    }

    struct StringItem: Hashable {
        let id = UUID().uuidString
        var value: String
    }
dataSource = UICollectionViewDiffableDataSource<Section, AnyHashable>(collectionView: collection) {
            (collectionView: UICollectionView, indexPath: IndexPath, item: AnyHashable) -> UICollectionViewCell? in

            // Get a cell of the desired kind.
            guard let cell = collectionView.dequeueReusableCell(
                withReuseIdentifier: TextCell.reuseIdentifier,
                for: indexPath) as? TextCell else { fatalError("Cannot create new cell") }

            // Populate the cell with our item description.
            switch item {
            case let item as IntItem:
                cell.configureWith(text: "Section \(indexPath.section), Row \(indexPath.row), Item \(item.value)")
            case let item as StringItem:
                cell.configureWith(text: "Section \(indexPath.section), Row \(indexPath.row), Item \(item.value)")
            default:
                ()
            }

            // Return the cell.
            return cell
        }

Итоги

Данный datasourceзначительно облегчает нам разработку на UICollectionView. Мы избавляемся от необходимости дополнительно вызывать методы, уменьшаем количество ошибок которые можем допустить. В последней и завершительной статье я постараюсь объединить UICollectionViewDiffableDataSourceи UICollectionViewCompositionalLayout, построить на их основе сложный экран с коллекцией.

Полезные ссылки

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

$
0
0

Привет! Меня зовут Сергей Шелехов. Я программист, работаю с .NET. В 2017 году мы с женой переехали жить в Израиль, где устроились работать в разных IT-компаниях.

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

Переезд

Начну с того, что гражданство Израиля у меня есть с 6 лет. Моя семья репатриировалась туда в далеком 1990 году, а в 1992-мвернулась обратно. Прежде чем начать работать в IT в Украине, я успел пожить в двух западных странах — в Германии и Великобритании. «Так какого черта ты делал в Украине?» — спросите вы и, конечно же, будете по-своему правы. Но это тема для отдельного поста, а сегодня речь пойдет о нашем с женой переезде в Израиль в 2017 году.

До переезда в Израиль мы с женой жили в Киеве, затем перебрались в мой родной город Харьков, где и работали девелоперами. Весной 2017 года мы решили, что хотим переехать жить за границу. Причины были разные, но основная мысль формулировалась так: «А почему бы и нет!» Перед нами встал выбор: либо уехать по рабочей визе / трактором в одну из развитых стран и прожить там 3-4лет до получения ПМЖ, либо поехать в Израиль, где у меня есть гражданство. После размышлений выбрали Израиль.

Кстати, для тех, кто обдумывает возможность переезда в Израиль, лучшего способа переезда, чем репатриация по еврейской линии, к сожалению, нет и не будет. Трактор тут не работает, так как в Израиле хоть и есть рабочая виза (в том числе для highly skilled workers), но нет возможности через нее получить ПМЖ и гражданство. Так что лучше попробовать поискать еврейскую кровь у своих родственников.

Мы с женой на всякий случай воспользовались услугами местного юриста, которого нашли еще в Украине; он помог нам с переводами и оформлением всех документов в Израиле. Осенью того же 2017 года я приехал в Израиль, взял с собой денег примерно на 3-4 месяца.Приехав, тут же приступил к поиску работы. Поиски эти продлились недолго, так как повезло, плюс я просил немного ниже зарплату, чем рыночная; и уже к ноябрю вышел на работу, где до сих пор и работаю. Компания называется FMR Systems, она разрабатывает инструменты для финансовой индустрии. Взяли меня на позицию Senior Engineer, но сегодня я уже руковожу разработкой Web API и back-end на нескольких наших проектах.

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




Жизнь в Израиле в целом

Израиль среди прочего — это страна контрастов, колорита, истории, изрядного бардака и красоты. Погода тут в целом неплохая, но летом очень жарко. В среднем здесь 40 дождливых дней в году, и 25-30из них — зимой. То есть в январе — феврале рубят дожди, а в апреле солнечно и +25. Иногда приходит так называемый хамсин (ветер из пустыни), и тогда жара может быть, как в сауне. Здесь комфортнее всего весной и осенью. Это почти идеальное время, когда вроде бы и тепло, но нет жары. Плюс иногда бонусом заходит дождь. Летом приходится сидеть под кондиционерами весь день. Со временем, правда, привыкаешь к жаре и уже становится не так тяжело. Одно из первых слов, которое здесь выучиваешь, — мазган (кондиционер).

Израиль вытянут в длину (с севера на юг) на сотни километров. В самом узком месте страна имеет ширину лишь 15 км. Здесь есть Средиземное, Красное и Мертвое моря, большое Тивериадское озеро (также известное как Галилейское), пустыня на юге, минеральные источники, горный хребет Хермон на севере высотой 2000 м.





Работа здесь начинается в воскресенье, а заканчивается с началом Шаббата (в пятницу около 12 часов дня). В некоторых секторах, в том числе IT, принято работать с воскресенья по четверг с 9:00 до 18:00. К соблюдению Шаббата здесь относятся серьезно: закрывается 80% магазинов, торговых центров, прекращает ходить транспорт. К этому поначалу очень трудно привыкнуть.

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

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

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

В Тель-Авиве в час пик сильные пробки, и тогда на машине из Герцлии (город, котором я живу) в Тель-Авив расстояние в 12-13 кмможно преодолеть за 40-50 мин.Но в это время дня разумнее пользоваться поездом или автобусом, так как у городского транспорта здесь своя полоса, и поэтому он едет быстрее, чем остальной поток машин.

В среднем у меня дорога из Герцлии в Тель-Авив на работу занимает около 30-40 мин.,что по местным меркам считается совсем неплохо.





Цены на проезд в транспорте зависят от расстояния. Вот некоторые цифры:

Вид транспортаЦена, в шекеляхЦена, в долларах США
автобус5-101,5-2,8
поезд102,8
маршрутка7-102-2,8
такси до 5 км25-507-14
авто, литр бензина6,31,75
Постоянный проездной на месяц для Тель-Авива и окрестностей24470

Примечание. 1 шекель — 0,28 USD.

Жизнь здесь супердорогая. Недавно Тель-Авив даже засветился в каком-то из чартов самых дорогих городов мира, где занял 9-еместо, а Герцлия даже несколько дороже. Если кому интересно более подробно, то сайты вроде Numbeoили Expatistanотображают достаточно правдивые цифры по ценам в Израиле.

Вот некоторые усредненные цены:

Графа расходовУточнениеЦена, в шекеляхЦена, в долларах США
Покушать (на 1 человека)в недорогом ресторане6017
в дорогом ресторане9025,6
Капучино и чай в небольших кофейнях102,8
в недорогом ресторане174,8
Аренда 3-комнатнойквартиры в месяц (без счетов)не центр60001706,9
центр80002275,9
Аренда 1-комнатнойквартиры в месяц (без счетов)не центр37001052,6
центр50001422,4
Интернет в месяц10028,4
Телефон5014,2
Квартира в новострое в хорошем районе в Герцлиине менее 2,5 млн710 тыс.

В Израиле все говорят на иврите, но как минимум каждый третий говорит хотя бы на слабом английском, русская речь тоже встречается частенько. По официальной статистике, в Израиле до 15% русскоговорящего населения.

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

Про Армию обороны Израиля

Служить в Армии обороны Израиля (Цахал) здесь принято и модно. Народ с радостью идет на службу, некоторые иммигранты даже специально за этим приезжают. Служить здесь забирают всех и вся с 18 лет. Срок срочной службы для мужчин — 32 месяца, для женщин — 24 месяца. Как указано тут, от службы освобождаются:

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

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

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

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

Для ясности, от терроризма с 1 января 2015 года в сумме погиб 251 человек. Большая часть — в Иерусалиме и территориях, граничащих с арабскими поселениями и сектором Газа.




Startup Nation

Израильтяне себя не без гордости именуют нацией стартапов. Журнал Forbes подсчитал, что в Израиле на 1400 человек населения приходится 1 стартап.

IT здесь называют high tech (хай-тек). Айтишников — свыше 300 тыс. человек, или чуть более 9% от общего числа работающего населения страны (взято отсюда).

Израильские компании, которые все время ищут способ сократить затраты, создают все больше R&D-центров в странах, где есть недорогие и качественные специалисты. Сегодня у каждой четвертой компании есть команда разработчиков за рубежом. Самое популярное направление (вы будете смеяться) — Украина. Украинские спецы, переехавшие в Израиль, тоже имеют в целом хорошую репутацию. Хай-тек постоянно растет, и ему не хватает специалистов.

Здесь нужны все: от Trainee Graphical Designer до Senior Cobol Engineer. Хотя из-за большого количества стартапов я бы сказал, что здесь акцент в целом смещен на доступные, open source, динамичные технологии вроде Python, Node.js, JavaScript и т. п.

В Израиле чуть-чуть сложнее, если ты спец по «солидным» технологиям, которые в основном юзаются на Enterprise-проектах вроде Java, .NET. Тут это отнюдь не мейнстрим, и вакансий сравнительно меньше, хотя тоже хватает.

Плюс здесь нужно быть несколько более разносторонне развитым специалистом, чем в Украине. В большинстве вакансий указана некая смесь технологий, иногда (по моему представлению) не очень сочетающихся, вроде: «We are looking for a Senior Java Engineer who is good in C++, who knows DevOps (containerization and cluster orchestration)».

Практически вся IT-активность приходится на 3 крупных хаба: Тель-Авив, Иерусалим и Хайфу. Сам не проверял, но ощущение такое, что на эти города суммарно приходится до 90% всех вакансий в стране, причем половина на Тель-Авив (город, где я работаю).

Герцлия является некой тихой гаванью и по совместительству IT-хабом. Здесь находятся центры разработки таких гигантов, как Google, IBM, Microsoft. Также есть офис компании Plarium.






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

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

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

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

Зарплаты в IT

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

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

УровеньЗарплата, тыс. шекелейЗарплата, тыс. долларов США
Trainee7-112-3
Junior developer11-143-4
Middle developer14-214-6
Senior developer23-336,4-9,2
Lead developer / Tech Lead30более 8,3

Для QA вилки похожие, только минус 25%. Спецы, знающие трендовые штуки вроде Machine learning или Big data, получают чуть больше. Среди программистов здесь принято знать несколько языков программирования и хорошо — алгоритмику.

Стоит отметить, что термины Junior, Middle, Senior здесь имеют другой подтекст. Часто бывает, что написано что-то вроде: «Ищем Sr. Developer, зарплата 14 тыс.» или «Разыскивается Jr, зарплата 8 тыс.», то есть на зарплату не особо влияет титул, который написан в вакансии. Каждая компания вкладывает какой-то свой смысл в эти понятия.

В таблице выше я использовал «наше» понимание того, кто такой Junior, Middle и Senior. К примеру, сколько бы спец, которому в Украине дали мидла, получал бы в Израиле.

Гораздо больше инфы о зарплатах в Израиле, причем для всего IT, можно найти здесь (англ.) или здесь (иврит, юзаем Google Translate).





Налоги

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

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

Куда отчисляются налогиСуммаПлюшки, которые получит Плющенко
Налоговая (рассчитывается по таблице прогрессивного налога)4500 шекелей — 22,5% от зарплаты «брутто»Никаких плюшек, налог есть налог.
Фонд национального страхования (для получения бесплатной медицины)650 шекелей — 3,25%Бесплатная медицина. Если ему, не дай бог, понадобится операция за 200 тыс. долларов США, то государство обязано будет ее оплатить.
Пенсионный фонд550 шекелей — 2,75%Плющенко получит 550 шекелей на пенсионный фонд, который он может заюзать в старости, а может и снять деньги в любой момент (при необходимости). Кстати, работодатель обязан по закону добавить Плющенко на пенсию не меньше такой же суммы. То есть на пенсионный фонд зайдет ему не 550 шекелей, а 1100 шекелей.
Вывод: плюс 550 шекелей халявы.
Так называемый фонд развития400 шекелей — 2,5% от «потолка» в 15 900 шекелей либо от зарплаты, если она ниже.Та же история, работодатель отчисляет Плющенко в 2-3раза больше, чем тот платит (зависит от контракта). На его счет заходит не 400 шекелей, а 1200-1600.Эти деньги можно снять до 6 лет, уплатив налог в 35%, либо после 6 лет — без уплаты налога.

Из зарплаты Плющенко суммарно снимут около 6-7 тыс.шекелей отчислений. Чистая же его зарплата (netto) составит около 13,5-14 тыс.шекелей, или 3,8-4 тыс.долларов США.

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

Кстати, если вас уволили или если вы 3 месяца не можете найти работу, то вы имеете право на пособие по безработице, которое достигает 70% от зарплаты хай-тек-специалиста.

Выводы

Как и везде, здесь есть свои плюсы и свои минусы. Хотя всевозможные отчисления в Израиле и большие, но, как видим, из 31% зарплаты, которые программист отчисляет кому-то, 22,5% являются налогами, а за остальные 8,5% он получает бесплатную медицину и 10-15%от зарплаты (с учетом отчислений работодателя) на разные свои счета, которые позже можно использовать.

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

Техническая поддержка микросервисов 24/7: как мы строили процесс

$
0
0

Всем привет. Меня зовут Андрей Трубицын, я сотрудничаю с ЕРАМ как Java Solution Architect. В этой статье расскажу, как мы построили процесс технической поддержки микросервисов в режиме нон-стоп для крупного американского клиента.

Это был первый опыт внедрения такого подхода за моих 4 года работы в харьковском офисе ЕРАМ, и он оказался непростым для команды: надо было разобраться в новой для нас системе — Opsgenie и ее интеграции, найти желающих для ночных дежурств, спланировать работу и поставить процесс на рельсы. На нашем проекте в силу микросервисной архитектуры очень частые релизы и динамичный ритм. Мы всегда в тонусе, многим ребятам такой интенсив по душе. Однако важно, чтобы баланс работы и личной жизни сохранялся без ущерба для качества непрерывных поставок обновлений (в том числе и в среду промышленной эксплуатации).

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

Бизнес-проблема

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

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

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

Над продуктом работают свыше 200 человек, более 70 из них — в Харькове. В состав каждой проектной команды входят разработчики, системные инженеры, автоматизаторы. Вместе они отвечают за написание кода и тестов, за процесс обновления микросервиса в продукте (CI/CD pipeline) и «выкатывание» в промышленную среду эксплуатации. Требования к качеству высокие: на проекте используется статический анализ исходного кода, поузловая проверка тестами, тестирование компонентов на моделях, интеграционное и функциональное тестирование, проверка на наличие уязвимостей и производительности и т. д.

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

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

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

Начало пути

На старте наша работа состояла из следующих этапов:

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

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

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

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

4. Сделать PoC.Мы изучили документацию выбранной системы управления авариями, получили доступ к их «песочнице», построили свой Proof of Concept на базе тестового сервиса, который моделировал бы разные исключительные ситуации, и отработали схему взаимодействия с Opsgenie.

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

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

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

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

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

Как работает система управления авариями

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

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

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

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

Как мы интегрировали микросервисы и Opsgenie

Для примера предлагаю рассмотреть конфигурацию реакции системы управления авариями на остановку одного из сервисов (например, в Java-приложении закончилась память в контейнере), запущенном в ECS-кластере AWS. Такая конфигурация работает на нашем проекте, но некоторые детали изменены в силу политик конфиденциальности компании.

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

Для интеграции с Opsgenie со стороны микросервиса создаем SNS Topic и прописываем ссылку, которую мы сгенерировали на предыдущем шаге.

Resources:
  MicroserviceECSAlarmTopic:
    Type: AWS:: SNS::Topic
    Condition: InLive
    Properties:
      TopicName: "MicroserviceECSAlarmsTopic"
      Subscription:
      - Endpoint: https://api.opsgenie.com/v1/json/amazonsns?apiKey=eeeeeeee-cccc-ffff-bbbb-aaaaaaaaaaaa
        Protocol: https

Далее, создаем правило, по которому мы будем слушать определенный тип сообщений от ECS-кластера и отправлять на созданный нами SNS Topic сообщение о том, что Docker-контейнер с нашим микросервисом остановился.

ECSStoppedRule:
    Type: "AWS::Events::Rule"
    Condition: InLive
    Properties:
      Name: 'MicroserviceECSStoppedRule'
      Description: "Notify when the microservice goes down"
      EventPattern:
        source: ["aws.ecs"]
        detail-type: ["ECS Task State Change", "ECS Container Instance State Change"]
        detail:
          clusterArn: #############
          lastStatus: [ "STOPPED" ]
          stoppedReason: [ "Essential container in task exited", "Task stopped by user" ]
          group: #############
      State: "ENABLED"
      Targets:
        - Arn: !Ref MicroserviceECSAlarmTopic
          Id: " MicroserviceECSAlarmTopic "
          InputTransformer:
            InputPathsMap:
              detail: "$.detail"
            InputTemplate: '"The microservice has stopped working with the following details: <detail>"

Здесь в секции EventPattern мы описываем сообщения, которые хотим слушать. Для этого в параметре source: [«aws.ecs»] указываем, что слушаем сообщения от ECS-кластера в облаке AWS; в параметре detail-type мы задаем конкретные типы сообщений: запуск/остановка задачи нашего микросервиса или изменение состояния Docker-контейнера с нашим микросервисом. Из указанных сообщений мы выбираем только те, что привели к остановке Docker-контейнера с нашим микросервисом; это делается через параметр detail, в котором мы прописали последний статус и причины остановки.

Далее, в секции Targets указываем, что мы хотим сделать в случае получения вышеописанных сообщений. В приведенном примере мы готовим новое сообщение на основе извлеченной информации из полученного. Она извлекается в параметре InputPathsMaps, где мы объявляем новую переменную detail и заносим в нее значение из параметра detail полученного сообщения. В параметре InputTemplate мы формируем тело нового сообщения и используем переменные из InputPathsMaps.

Теперь нам нужно выгрузить описанный CloudFormation-шаблон на стенд в облаке Amazon и надеяться, что ночью нас беспокоить не будут :) У нашей команды, кстати, в первый месяц работы по такой системе было 26 критичных ситуаций, во второй — 5, а дальше максимум одна в месяц. То есть активными дежурства бывают нечасто. Все благодаря тому, что код инженеры стали писать качественнее.

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

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

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

Выученные уроки

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

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

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

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

Выводы

За время работы с Opsgenie и техподдержкой микросервисов 24/7 мы убедились, что этот подход позволяет значительно улучшить качество кода в системе (к слову, одной из первых его применила Amazon). Отмечу, что техническая сторона вопроса не требует много времени: чтобы прописать одну исключительную ситуацию на одном микросервисе, хватит одного-двух дней. В нашем случае самыми сложными в запуске техподдержки 24/7 были все же нетехнические моменты.

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

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


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

$
0
0

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

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

План и процесс обучения

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

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

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

Цель новичка — быстрее попасть в профессиональную среду и приступить к разработке практических решений. А не делать домашние проекты по шаблону, считая их своим детищем. Я не умаляю значение pet projects для саморазвития и закрепления практических навыков, но давайте начистоту: глядя на свои проекты двух-трехлетней давности, лишь единицы назовут свой код достойным похвалы. И если опыта продакшена нет, то не стоит вписывать в резюме ссылку на GitHub-аккаунт. Если только его не ревьюил знакомый разработчик с опытом.

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

  1. Продолжительные курсы офлайн-обучения (6 месяцев и больше) хороши, если:
    • у вас низкий уровень понимания по большинству покрываемых курсом тем;
    • отзывы о школе/курсах действительно хорошие либо есть человек, закончивший их и трудоустроившийся, которого вы знаете лично.
  2. Онлайн-курсы по узким направлениям (углубленные алгоритмы или базы данных, тестирование Java-приложений) стоит отложить на период после трудоустройства, чтобы не уходить в сторону от основной краткосрочной цели.
  3. Процесс составления изначального плана обучения значительно важнее трудолюбия и энтузиазма в разработке.

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

Градации

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

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

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

Недоджун

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

Младший джун

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

Крепкий джун

Когда вы увидите вакансию «ищем Junior Java-девелопера с опытом разработки от 1 года», это о нем. Смело обходит большинство кандидатов на эту позицию. Чаще всего вопрос трудоустройства упирается только в требования по зарплате: хочет больше, чем умеет, но рынок — дело хитрое.

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

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

Градация приведена скорее для тех людей, кто ошибочно рассматривает общепринятые уровни (junior, middle, senior) в контексте времени работы в отрасли, а не в контексте знаний. Несмотря на некоторую корреляцию этих факторов, она очень индивидуальна. Кто-то за 4 года может набраться senior-знаний, а другой и через 5 все еще остается джуном.

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

  1. Основы языка и технологий.
  2. Работа с БД, JDBC.
  3. Hibernate.
  4. Spring.
  5. Алгоритмы.
  6. Логирование, тестирование.
  7. Паттерны проектирования.
  8. Системы контроля версий.
  9. Сборка проекта.
  10. Методологии разработки, веб-технологии, инструменты профилирования и т. д.

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

Основы языка и технологий

Недоджун

Вопросы минимально упорядочены:

  • принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм;
  • принципы SOLID, уметь рассказать на примерах из Java;
  • парадигмы программирования (императивное, декларативное и их основные подтипы);
  • интерфейсы, классы, объекты, знать разницу и особенности применения;
  • методы класса Object, понимать обязанности каждого метода и почему он был вынесен к верхушке объектной иерархии;
  • типы данных, уметь ориентироваться и использовать (примеры вопросов: «Зачем нужны классы-обертки для примитивов? Расскажите о приведении (casting) примитивных типов. А о приведении объектов?»);
  • типы классов (абстрактные, внешние, внутренние, вложенные и т. п.), модификаторы доступа;
  • коллекции, их иерархия, особенности и отличия одной от другой (LinkedList от ArrayList, HashMap от TreeMap), что под капотом у ArrayList, HashSet, на основе чего они работают и как устроены;
  • исключения, их иерархия и основы обработки (для чего, как и где);
  • стек, куча, как с ними организована работа в Java (общие принципы);
  • многопоточность: понятия процесса и потока, варианты создания потока, методы синхронизации и служебные слова в Java (называть только те, о которых можете рассказать), как вы понимаете потокобезопасность, deadlock, volatile, атомики, thread, runnable и callable;
  • стримы, лямбды, функциональные интерфейсы без серьезного углубления.

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

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

Младший джун

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

Темы:

  • особенности работы кучи и стека: внутреннее устройство, скорость доступа, использование памяти, сборщик мусора поверхностно;
  • нестандартное использование коллекций и особенности работы с ними: обработка NULL-значений в HashMap, TreeMap; удаление диапазона из TreeMap; почему строка — хороший выбор для ключа в HashMap. Дженерики и работа с ними: если метод принимает List, что туда можно передать; как в рантайме дженерики выглядят; могут ли быть конструкторы в абстрактных классах; если класс нельзя инициализировать, то зачем они;
  • наследование «IS-A» и ассоциация (включает в себя композицию «HAS-A» и агрегацию «USES-A or IMPLEMENTED-IN-TERMS-OF») в контексте Java;
  • интерфейсы-маркеры с примерами: сериализация, клонирование, конфигурируемая сериализация (интерфейс Externalizable);
  • более детально по типам данных: нотации основных методов (в классах-обертках, хеш-код, equals, что возвращают, почему, как переопределять), boxing-unboxing, инициализация переменных локальных и класса, пул строк (что такое, где хранится). Знать битовые операции AND, OR, XOR; byte b = 127, b++, какой результат и почему (по шагам); int p1, long p2, в чем разница между операциями p1 = p1 + p2 и p1 += p2;
  • более детальные вопросы по стримам: привести пример обработки из практики, скорость работы стримов, какие два типа операций есть, что за чем идет в операциях в стриме;
  • многопоточность детальнее: приведите пример дедлока (странный вопрос, но задают), как создать потокобезопасный класс, для чего нужен CompletableFuture, что такое пул потоков;
  • детальнее по исключениям: если оно выпало сначала в try, потом в catch, что будет; можно ли try без catch, но с finally, куда пойдет исключение; а если return будет и в catch, и в finally, как обработается;
  • рефлексия поверхностно, что возвращает getClass и зачем он нужен;
  • класслоадеры и их иерархия. Ситуация: getClass у двух классов возвращает одно значение, во время каста одного к другому происходит ошибка. Почему? (Классы загружены разными класслоадерами).

Крепкий джун

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

  • I/O vs NIO (спрашивают обычно поверхностно);
  • работа с датой и периодами;
  • еще больше многопоточности: атомики изнутри (cas, faa), все основные классы из пакета Concurrent знать (где используется BlockingQueue, например), параллельные стримы и минусы их использования, forkJoin пул, вокруг чего бывает синхронизация (классы и объекты), какими способами, в чем разница ConcurrentHashMap и SynchronizedMap, ключевые отличия Callable от Runnable (обработка checked exceptions), happens-before ситуации при работе с потоками;
  • типы ссылок в Java, как и где используются;
  • стратегии сборщика мусора;
  • что объявляется в try-with-resources (вопрос по autocloseable);
  • рассказать об основных функциональных интерфейсах;
  • исключения: как ведут себя в конструкторе, как при наследовании и переопределении методов;
  • еще больше изощренных вопросов по коллекциям и классам/интерфейсам: если map не наследуется от Iterable, как по ней идет итератор; когда возникает ConcurrentModificationException и как избежать; HashMap приводит значения в корзине к дереву для оптимизации доступа начиная с определенного количества коллизий, но не всегда, а при каком условии; модификаторы доступа у полей и методов интерфейса; можно ли переопределять статические методы при наследовании;
  • где хранится в рантайме информация о классах, методах.

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

Работа с БД, JDBC

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

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

Вопросы по SQL:

  • основы: типы запросов (DDL, DML, DCL, TCL), CRUD-операции, типы данных, первичные и внешние ключи, ограничения (constraints), HAVING vs WHERE, все типы JOIN плюс уметь применять на практике, UNION (какое условие выполнения оператора для двух таблиц), последовательность операций в запросе, триггеры — теоретическое представление, индексы одиночные и составные, кластерные и некластерные (сколько может быть кластерных индексов для таблицы и сколько некластерных, почему), курсоры — что это и зачем, команда EXPLAIN;
  • нормализация и денормализация, самые дотошные могут спросить о 3 классических нормальных формах;
  • транзакции, их свойства ACID, уровни изоляции транзакций (достаточно 4 классических).

Простые запросы не должны вызывать размышлений. Пример: достаньте из базы userinfo данные юзера, чья salary больше 5000. Зарплата в отдельной таблице лежит. Таких типовых задач в сети достаточно, очень советую поискать и попрактиковаться перед собеседованием.

Вопросы по JDBC:

  • назовите последовательность шагов при подключении и работе с базой с помощью JDBC;
  • для чего нужны: DriverManager, Driver, Connection, Statement, ResultSet;
  • какие вы знаете типы запросов (Statement, PreparedStatement, CallableStatement), расскажите о каждом типе;
  • за счет чего PreparedStatement бывает быстрее обычного Statement (прекомпиляция); если упомянуть пул прекомпилированных запросов, это сразу плюс в глазах собеседующего;
  • методы execute, executeUpdate, executeQuery, что возвращают, зачем нужны.

С крепкими джунами могут поверхностно коснуться темы масштабирования и репликации в рамках проверки общего архитектурного представления работы БД.

Итоги

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

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


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

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

$
0
0

Вітаю! Я Ігор Берегівський, мені 26 років, п’ять з яких працюю тестувальником. Коли дізнався, що є така професія, одразу ж загорівся, оскільки з дитинства любив досліджувати, як працюють різні механізми й наскільки вони міцні. За час роботи в QA я встиг здобути сертифікацію ISTQB Advanced Level у тест-менеджменті, лідити команду із 14 тестувальників, менеджити частину відділу тестування, викладати курс із тестування й жодного разу не змінити компанію :)

У цій статті розповім, як тестування під час розробки допомогло нам — компанії Diligences — створити готовий до релізу внутрішній продукт, що переріс у своєрідний стартап. Стаття буде корисною для проджект/продакт-менеджерів, тімлідів і початківців у сфері забезпечення якості. Водночас для досвідчених QA я можу здатися Капітаном Очевидністю :)

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

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

Відсутність команди тестування

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

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

Несвоєчасне тестування

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

Брак стратегії тестування

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

Надто багато розробки, надто мало виправлень

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

Triple W проблем

Усі ці проблеми я намагався об’єднати в групи triple W або ж у назву всім відомої гри What? Where? When?

Що тестувати

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

Де тестувати

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

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

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

Коли тестувати

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

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

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

Тільки те, що ви почали тестування рано, не означає, що потрібно рано й закінчувати :)

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

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

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

Як це працює

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

Якось ми вирішили перетворити його на комерційний проект і почали з таких цифр:

  • один місяць витрачали на реліз кожної фічі;
  • 40% усіх багів перевідкривали;
  • у беклогу було 74 мінорні баги й 6 major-багів.

І ми мали такий тестовий репорт:

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

Тому ми вирішили прилучити команду тестування, щоб визначити проблеми. Передусім ми визначили найважливіший функціонал для кінцевих користувачів і написали тестове покриття за цими випадками. Це стало нашим першим чеклістом, який ми почали використовувати для тестування перед кожним релізом. Також почали писати баг-репорти, що містили всю потрібну інформацію — Steps to reproduce, Version, Actual and Expected result, — і додали критерії прийняття до кожної фічі, яку розробляли. І ось що ми отримали:

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

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

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

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

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

Отже, наприкінці ми впровадили три процеси:

  1. Acceptance-тестування кожної фічі, яку було змерджено в dev stage.
  2. Smoke-тестування кожної збірки.
  3. Регресійне тестування перед кожним релізом на прод.

І ці три процеси допомогли нам поліпшити такі метрики:

  1. Період реалізації фічі зменшився до 1 тижня.
  2. Кількість перевідкритих тикетів знизилася до 3%.
  3. Кількість тикетів про баги в системі підтримки користувачів зменшилася із 40 тикетів на місяць до 5.

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

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

На завершення я хотів би поділитися корисними порадами, які вам потрібно пам’ятати, коли ви тестуєте й розробляєте свій продукт:

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

Користуйтеся загальноприйнятою термінологією.Вам потрібно використовувати терміни, які визначено в стандартах ISO / IEEEта інших стандартах, щоб ви розмовляли спільною мовою з іншими. Так, вам потрібно припинити називати своє передрелізне тестування smoke-тестуванням, тому що smoke-тестування — це швидкий тест, щоб визначити, чи прийнятна збірка для подальшого тестування.

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

Интеграция приложения с Google Maps, или Как заинтересовать в своем продукте IТ-гиганта

$
0
0

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

Что собой представляет Allset

Случалось ли вам когда-нибудь прийти в ресторан, а свободных столиков там нет? Или чтобы вы хотели быстро поесть, а официант и повар, как назло, делали все, будто в slow-mo? Именно такие вызовы жизни современного человека решает Allset. Через мобильное приложение вы можете заказать столик, выбрать еду и оплатить счет, а когда придете в ресторан, то вкусные блюда уже будут ожидать вас.

Основатели Allset (слева направо): Дмитрий Никулин, Анна Полищук, Павел Тирон и Стас Матвиенко

За четыре года существования мы привлекли более 10 млн долларов США инвестиций, и сейчас сервис работает в 11 крупнейших городах Америки с более чем 2500 заведений.

Как и положено настоящему стартапу, Allset начинался с небольшой группы основателей. Сейчас же в компании работает 65 человек: 53 в Киеве и 12 в Сан-Франциско. Команда постоянно увеличивается, ведь рыночный оборот ресторанного бизнеса в США составляет уже около 800 млрд долларов, а заказы через мобильные приложения выросли на 50% в 2018 году. Команды из киевского офиса периодически ездят в США, чтобы лучше понимать все нюансы работы продукта и тестировать его в реальных условиях.

Сотрудничество с Google

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

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

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

Как найти нужного человека

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

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

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

Я написал, что знаком с их Knowledge Panel, упомянул об Allset и удивился, почему нашего сервиса там нет. То есть я представил ситуацию так, что стало казаться, словно наше отсутствие в этой панели — это скорее упущение с их стороны. Это сработало, и почти сразу мне ответила Head of Product Partnership, сказав, что слышала о нас, и предложила встречу в офисе Google в Нью-Йорке.

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

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

Если вы планируете работать с крупной компанией вроде Google, то у меня для вас несколько советов:

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

Уникальность импонирует Google

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

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

Google оценила это и решила не просто включить нас в перечень сервисов, а внести как отдельную фичу в свою Knowledge Panel. Большинство других сервисов попадают только в общий список.

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

Интеграция за 10 дней

Всю интеграцию наш экс-техдиректор Павел Тирон сделал сам (сейчас должность Head of Engineering занимает Тарас Березовский). Основная задача, которая стояла перед технической командой, — обеспечить поддержку системы обмена сообщениями в Google Maps. Там все реализовано через протокол Protobuf, который Google сама придумала и применяет достаточно часто. Самое сложное было скомпилировать данные.

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

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

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

Особенности работы с Protobuf

Работа с Protobuf имеет как свои преимущества, так и предостережения:

  • Одно из главных преимуществ — простое взаимодействие языков и возможность добавлять поддержку новых языков с помощью плагинов. Protobuf реализован на разных языках, и это значительно упрощает совместимость с приложениями, написанными на разных языках в вашей архитектуре. Если вы добавляете новый сервис, например на Java или Go, либо работаете с бэкендом, написанным на Node, Clojure или Scala, вам нужно просто передать прототип файла генератору кода, написанному на целевом языке. Безопасность и совместимость между этими архитектурами гарантируется.
  • Protobuf обеспечит хорошую скорость работы.
  • Протокол помогает создать компактный бинарный формат, который будет занимать намного меньше места, чем XML и JSON. Но если ваше приложение написано на JavaScript или вы хотите, чтобы данные были удобочитаемыми или напрямую потреблялись веб-браузером, то в таких случаях JSON подойдет лучше. Protobuf не предназначен для чтения пользователем и представляет собой двоичный формат. Для десериализации данных необходим отдельный PROTO-файл, в котором определяется формат сообщения.
  • Protobuf является суперкомпактным форматом и поможет сделать многоязыковую сериализацию, то есть вы сможете обмениваться данными на любых операционных системах (Windows, Linux), и эта сериализация будет простой в использовании.

Протокол Protobuf достаточно сложный для первичной адаптации, но, так как интеграция с Google Maps работает только через него, это было главным аргументом в его пользу. Без предыдущего опыта реализация Protobuf займет много времени. В целом стоит задействовать его в специализированных интеграциях, как в нашем случае, где такое использование было обязательным условием. В других случаях лучше применять более универсальные платформы, такие как JSON или XML.

Коммуникация с Google

Она там построена очень эффективно. За один звонок нам объяснили, что необходимо сделать для успешной интеграции, и даже больше, рассказали о том, где у нас могут возникнуть трудности с Protobuf. Мы получили замечательную панель управления, где видели все наши данные, которые затем попадают в Google Maps, и могли удобно руководить процессами. Через пять дней техническая команда уже начала тестирование.

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

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

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

В чем особенности работы с IT-гигантом

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

Если в Google видят перспективу, то пытаются оперативно сделать все, чтобы ею воспользоваться. Конкретные работники готовы проталкивать определенные вопросы и имеют больше свободы в принятии решений. Я не думаю, что решение о партнерстве с нами утверждали C-levelили топы компании. Все было одобрено в рамках отдела, который отвечает за партнерства Google Maps.

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

Напоследок

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

Материал создан в соавторстве с Павлом Тироном.

Автоматическая генерация тестов: подходы и инструменты

$
0
0

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

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

Случайная генерация

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

Свойства:

  1. Очень просто реализовать, есть инструменты, которые позволяют автоматически генерировать синтаксически корректные юнит-тесты (в рамках синтаксиса какого-либо ЯП и/или библиотеки).
  2. Можно очень быстро сгенерировать очень много тестов.
  3. Нахождение ошибок столь же случайно, как и сами входные данные.

Сферы применения:

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

Генерация на основании алгоритмов поиска

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

Свойства:

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

Сферы применения:

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

Генетические алгоритмы

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

Свойства:

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

Сферы применения:

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

Генерация тестовых последовательностей

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

Свойства:

  1. На вход таким алгоритмам подается формальная модель, то есть параметры и значения, которые они принимают, условия, которые накладываются на комбинации таких значений, параметры комбинаций (например, каждый с каждым, только пары, только тройки и т. д.). Следовательно, результат проектирования полностью предсказуем и обладает строго тем набором свойств, которые заложены в модели.
  2. В дополнение к правилам генерации и заданным зависимостям между значениями параметров можно устанавливать веса значений. Таким образом, можно регулировать частоту встречаемости значений в тестах: там, где в комбинациях все равно, какое значение выбрать, вес задает вероятность такого выбора.
  3. Кроме весов значений, можно задавать и приоритизацию, то есть порядок, в котором тесты появятся в наборе. Плохая новость в том, что такая возможность есть не во всех инструментах.

Сферы применения:

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

Инструменты

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

Генерация юнит-тестов на Java с Randoop (случайная генерация)

Как это работает:

  1. Создать файл myclasses.txt со списком имен классов, которые подлежат тестированию.
  2. Вызвать Randoop: java -classpath $(RANDOOP_JAR) randoop.main.Main gentests --classlist=myclasses.txt --time-limit=60
  3. Скомпилировать и запустить тесты, которые сгенерировал Randoop. Получится два набора: ErrorTest и RegressionTest. Тесты из первого набора не пройдут (предположительно, баги, требуется дополнительное исследование). Тесты из второго набора пройдут успешно.

Что примерно получится:

	@Test
	public void test001() throws Throwable {

		if (debug) { System.out.format("%n%s%n","RegressionTest0.test001"); }

		MerArbiter.TestMyMerArbiterSym testMyMerArbiterSym0 = new MerArbiter.TestMyMerArbiterSym();
		testMyMerArbiterSym0.run2((int)'a', true, (int)'a', false, (int)'4', (int)(byte)100, true, (int)(short)100, false, (int)' ', 10, false, 100, false, (-1), (int)' ', false, (int)(short)(-1), true, 0, true, true, (int)'a', (int)(short)1);
		testMyMerArbiterSym0.run2((int)(byte)100, false, 10, true, (int)'4', (int)' ', false, 1, false, 100, 100, false, (int)(byte)(-1), false, (int)'#', (int)(byte)1, false, 0, true, (int)(byte)100, true, true, (int)(short)10, (int)(short)10);
		testMyMerArbiterSym0.run2((int)(short)100, false, 0, false, (int)(byte)1, (int)(byte)1, true, (int)(byte)0, true, (int)(byte)100, (int)'a', true, (int)' ', false, (int)(byte)1, (int)(byte)100, false, (int)'4', false, (int)' ', true, false, (int)(short)100, (int)'4');

	}

Генерация юнит-тестов на Java с EvoSuite (алгоритмы поиска)

Как это работает:

  1. Определиться с классом, который будет тестироваться, путем к этому классу и его зависимостям.
  2. Определиться с целевой функцией.
  3. Вызвать EvoSuite, например так (задан целевой параметр): $EVOSUITE -class <ClassName> -projectCP <ClassPath> -criterion branch

Что примерно получится:

public class MyMerArbiterSymTest {
	MyMerArbiterSym o = new MyMerArbiterSym();
	@Test
	public void test0() {
		o.run2(3215, false, 3215, false, -633, -1952, false, 3215, false, 0, -2384, false, 3215, false, 3215, -90, false, -90, false, 599, false, true, 0, -1952);
	}
	@Test
	public void test1() {
		o.run2(0, true, 0, true, -1, 562, false, 0, false, -1, 0, false, 2844, true, 1354, 0, false, 1, true, 0, false, false, 0, -2561);
	}
	@Test
	public void test2() {
		o.run2(562, true, -1, false, -1448, -3029, false, 11, false, 0, 0, false, 0, false, 0, -3029, false, 0, false, -1218, false, false, 562, -1);
	}
	@Test
	public void test3() {
		o.run2(0, false, 0, false, 0, 2, false, 0, false, 0, -1, false, 11, false, 0, -3029, false, 0, false, 0, false, false, 1, -3884);
	}

}

Генерация данных с PICT (комбинаторное тестирование)

Как это работает:

1. Задать модель и ее ограничения, например так:

BROWSER: IE, Firefox, Chrome, Opera
LANG: en, ru, ua
OS: win, linux, android
{BROWSER, LANG, OS} @ 1
IF [OS] = "linux" THEN [BROWSER] <> "IE";

2. Запустить PICT, передав модель на вход, перенаправить вывод в файл при необходимости: pict.exe model.txt > results.csv

Что примерно получится:

Для модели выше, скажем, получится файл (или вывод в консоль) вот с такими данными:

IE	       	ua	win
Firefox	  	en	win
Opera		ua	linux
Chrome		ru	android

Что с этим потом делать — на усмотрение автора модели или других причастных.

Полезные ссылки

Выводы

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

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

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

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

WWDC 2019: обзор и практическое применение Custom Instruments и SF Symbols

$
0
0

Пожалуй, WWDC 2019 стала самой значимой конференцией для iOS девелоперов за последние несколько лет — так утверждали большинство участников ивента. Я поехал вместе с коллегой, таким образом среди 6 тысяч счастливых участников этого события оказались еще и два разработчика из NIX. Мы посетили самые важные закрытые сессии и воркшопы конференции, на которых как раз и разбирались особенности работы с новыми инструментами. В этой статье я расскажу, что осталось за кадром онлайн-трансляции и с чем предстоит работать iOS девелоперам уже в ближайшем будущем.

Да, я знаю, что после WWDC 2019 прошло уже три месяца, и о событиях конференции успели написать многие. И все же для меня эта пауза была не напрасной по двум причинам. Во-первых, если бы я сел за статью раньше, вы увидели бы примерно такое начало: «А-а-а, я пожал руку Крэйгу Федериги!» :) Во-вторых, все лето мы с командой осваивали презентованные фичи, разбирались в особенностях их работы и даже успели обсудить нюансы их применения на открытой конференции iThink #3, благодаря чему я смог четко сформулировать для себя, чем стоит поделиться с вами в этой статье.

Custom Instruments

Это фича от Apple, которая была презентована ещё в прошлом году. На WWDC 2019 ей было посвящено несколько сессий. На них докладчики рассказали, как работают кастомные инструменты, в каких случаях их применять и чем они могут быть полезны девелоперу. Основа — os_signpost. Это трассировщик, который Apple представила в прошлом году. Оs_signpost может делать простые ивенты и интервалы.

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

Архитектура самого инструмента в самом начале встречает нас Data stream — потоком данных. И теперь их мы получаем как раз благодаря os_signpost. Эти данные записываются в input таблицу. Схема этой и output таблицы описана с помощью специальной XML структуры. Шаги считывания данных и записи в таблицу являются трассировкой.

Далее следует modeller. Здесь данные, которые попали в input таблицу, начинают обрабатываться modeller’ом. Сам моделлер пишется на специальном языке CLIPS, который имеет декларативную и императивную часть для обработки новых событий и преобразования данных. Тут может производиться кастомный подсчёт или преобразование данных в нужный нам формат.

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

CloudKit + CoreData

Фича от Apple, презентованная в этом году, позволяет включить автоматическую синхронизацию Core Data с Cloud Kit. Для этого достаточно поставить две галочки при старте проекта. Тем самым мы получаем:

Важно не забыть включить нотификации и сам CLoudKit в Capabilities, так как автоматически это не произойдет.

И всё, основную работу за вас сделал Xcode. Автоматически был сгенерирован вот такой контейнер, который агрегирует в себе работу с базой данных и CloudKit. Если же у вас уже есть проект и вы хотите воспользоваться этой новой фичей от Apple, вы можете сами создать Container и применить его вместо уже существующего. Таким образом даже уже в готовых старых проектах можно добиться простой синхронизации с CloudKit.

    lazy var persistentContainer: NSPersistentCloudKitContainer = {
        let container = NSPersistentCloudKitContainer(name: "_2312")
        guard
            let description = container.persistentStoreDescriptions.first
        else {
            fatalError("No description found in NSPersistentCloudKitContainer” )
        }
        
        let id = "iCloud.testnixsolutions.dontBeBored"
        let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
        description.cloudKitContainerOptions = options
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

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

SF Symbols

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

Я задался вопросом, зачем Apple создала новые символы, если девелоперы уже много лет спокойно использовали .png/.jpg/.pdf картинки. Возможно, этот способ не всегда был удачным, имел свои особенности и нюансы, но все уже привыкли многократно конфигурировать свою UI.

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

Иконки разделяют контексты:

Иконки объединяют контексты:

Иконки должны визуально соответствовать тексту:

Таким образом, Apple создали SF Symbols для легкого решения этих проблем. Так как Apple уделяет много внимания своим продуктам, они создали отдельное приложение, которое позволяет ознакомиться со всеми символами (их сейчас более 1500), воспользоваться поиском, изменить некоторые параметры и посмотреть, что же произойдет с нужным тебе символом.

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

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

// UIKit
let image = UIImage(systemName: "circle")
let image = UIImage(systemName: "circle", withConfiguration: UIImage.Configuration?)

// SwiftUI
let image = Image(systemName: "circle")

Как мы видим, в одном из инициализаторов появился новый параметр UIImage.Configuration. Сюда мы можем передать UIImage.SymbolConfiguration, что является наследником UIImage.Configuration. Стоит отметить, что конфигурации являются иммутабельными, и для применения новых параметров придется использовать applying (_:).

Конфигурация позволяет изменить:

  • PointSize;
  • UIImage.SymbolScale;
  • UIFont.TextStyle;
  • UIImage.SymbolWeight;
  • UIFont.

А теперь обо всем по порядку

Point size — параметр, который позволяет задавать размер символа. Это та самая первая концепция, которая должна дать понять, что символ не является той самой png-картинкой. Важно понимать, что Point size (CGFloat) != CGSize. Таким образом, о размерах SF Symbols думаем в point size, особенно когда работаем в связке символа и текста.

let topFont = topLabel.font
let topConfiguration = UIImage.SymbolConfiguration(pointSize: topFont!.pointSize)
        topImageView.image = UIImage(systemName: "bell", withConfiguration: topConfiguration)

Используя UIImage.SymbolWeight, мы можем придать толщину линии (жирность) символу, как и у UIFont.

Со следующим параметром SymbolConfiguration.init (font: UIFont)все довольно просто. Достаточно закинуть параметром нужный UIFont, и система все делает за тебя.

Самым неоднозначным из всех параметров будет UIImage.SymbolScale. Его тоже используют для изменения размеров символа. Поэтому в итоге мы получаем сразу два параметра, которые меняют размер символа. Но не стоит паниковать. Эти параметры, скорее, взаимодополняющие, чем взаимоисключающие.

Давайте представим ситуацию: вы задали идентичный point size вашему UIFont в лайбе, но при этом ваш символ визуально больше/меньше текста. Чтобы не создавать новую конфигурацию с новым значением point size, нам и пригодится SymbolScale. Он поможет изменить размер изображения, не меняя при этом его point size.

Что же касается параметра UIFont.TextStyle, то здесь также не предвидится ничего сложного. Его нам рекомендуют использовать в случае имплементации dynamic font type.

В итоге

Мы имеем новый подход к работе с символами (картинками) и текстом. Фактически Apple заставила iOS-девелоперов пересмотреть свои взгляды на этот счет. Плюс ко всему, мы получили более широкие возможности добавления своих инструментов, что позволяет нам снизить порог вхождения в проект. Также мы теперь имеем возможность настроить CoreData с CloudKit всего в пару кликов. iOS-разработчикам предстоит попробовать и узнать еще много нового. Начинайте работать с этими инструментами уже сегодня, двигайтесь вперёд и делитесь опытом в статьях и на митапах и, конечно, в комментариях к этому материалу.

DOU Ревізор у Львові: «Окремі кабінети для команд у Lohika»

$
0
0

Цього разу DOU Ревізорзавітав до Lohika, міжнародної аутсорсингової компанії, серед клієнтів якої Skype, Airbnb, BuzzFeed та інші. Lohika було засновано у 2001 році, а два роки тому компанія стала частиною Altran, що має представництва у понад 30 країнах світу і налічує понад 47 000 співробітників.

В Україні Lohika представлена в 4 містах (в Києві, Одесі, Рівному та Львові), де працюють понад 1000 спеціалістів. Зокрема, у львівському офісі 325 співробітників, 267 з них — технічні спеціалісти.

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

Львівський офіс Lohika знаходиться у бізнес-центрі за адресою Лемківська, 15 уже 8 років. Локація розташована у 20 хвилинах пішки від центру міста. Розташування досить зручне, оскільки від офісу можна за 3 хвилини пішки дістатися зупинки маршрутного таксі «Хімічна», а щоб дійти до зупинки трамваю «Палац культури ім. Гната Хоткевича», потрібно 8 хвилин.

Також у пішій віддаленості доволі багато місць, де можна втамувати голод:

  • у 10 хвилинах — ТЦ «Форум Львів» (де багато магазинів, кафе і є Le Silpo);
  • у 5 хвилинах розташовано ТЦ «Ашан», де можна пообідати в «Хінкальні» або «Domino’s Pizza»;
  • за 3 хвилини можна дістатися кондитерської «Братванка».

Середній чек у цих закладах складає від 95 до 105 грн. Також поблизу є стандартна їдальня — «Кухня», де вартість обіду — лише 50-70 грн,та кав’ярня на першому поверсі бізнес-центру.

Як приємний бонус від БЦ, спеціалісти мають у розпорядженні безкоштовну авто- та мотопарковку на 120 місць, а також дві безкоштовні зарядки для електрокарів. Місця не закріплюються за співробітниками — їх отримує той, хто раніше дістався на роботу. Оскільки, крім Lohika, у бізнес-центрі лише одна компанія, проблем з паркінгом немає. Для велосипедистів на паркуванні виділено 25 місць.

На паркуванні є альтанки, які використовуються як зони для відпочинку та куріння.





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

Офіс займає три повних поверхи та ще половину п’ятого поверху БЦ. Приблизна площа — 3500 м2. В планах Lohika — розширятися: наразі триває ремонт на першому поверсі, тож у січні простір збільшиться ще на 841 м2. Зараз кількість квадратних метрів на одну особу в робочому приміщенні складає близько 6 м2 (відповідно до даних компанії).

В Lohika діє карткова пропускна система, що відстежує, чи був спеціаліст в офісі. Йому надходить «Absence request», в якому необхідно вказати причину відсутності: наприклад, він залишив вдома перепустку або просто працював з дому. Спеціаліст визначає причину, а менеджер її верифікує.

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





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

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





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

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

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




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

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




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

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






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

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

Як такої можливості віддаленої роботи в компанії немає. Якщо домовленості з клієнтом не перешкоджають, то логіканці можуть скористатися опцією «work from home». Спеціаліст лише має надіслати запит на узгодження своєму менеджеру.





В Lohika знайшли засіб боротьби з «мертвими» зустрічами, що лише займають кімнати для переговорів. Кожен мітинг-рум обладнано планшетом, на якому відображаються всі бронювання і на якому спеціалісти мають підтверджувати, що зустріч відбудеться. Для цього протягом 15 хвилин (за п’ять хвилин до і десять хвилин після початку зустрічі) необхідно натиснути кнопку «підтвердити» на планшеті біля входу. Якщо ж учасники зустрічі запізнилися більш ніж на десять хвилин та не підтвердили зустріч, вона автоматично видаляється з календаря, і кімната стає доступною для бронювання. Забронювати мітинг-рум можна через Outlook-календар або просто на планшеті біля переговорної кімнати.

Усього в офісі 16 мітинг-румів та п’ять невеликих переговорних. У планах компанії — ще шість невеликих мітинг-румів на першому поверсі. Концепція назв кімнат географічна: на другому поверсі — острови, на третьому — столиці, на четвертому — країни, на п’ятому — гори.





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

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

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

Після обіду в кімнаті для йоги відбуваються масажі. Записатися на сеанси можна за допомогою Outlook-календаря. Страхова компанія відшкодовує 10 сеансів масажу на рік, але якщо спеціаліст перевищить цей ліміт, він все одно може замовити сеанс та домовитися із масажистом про оплату. При цьому не обов’язково відвідувати масаж саме в офісі: можна самостійно знайти масажиста деінде, а страхова проґарантує сеанси.

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




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





Поруч із тренажерним залом є невеличка ігрова кімната, де можна пограти в дартс, настільний футбол або на PlayStation 4 PRO.




По вівторках і четвергах з 13:00 до 15:00 в офісі знаходиться лікар від страхової компанії. Терапевт займає один з мітинг-румів, і в форматі живої черги можна звернутися до нього з питанням. Він може або спрямувати до іншого лікаря, або ж виписати ліки чи лікарняний.

В офісі існує власна бібліотека, що регулярно оновлюється. Її розміщено в окремій кімнаті, де спеціалісти компанії час від часу полюбляють почитати або просто розслабитися. Узяти книжку з бібліотеки в Lohika доволі просто і зручно, для цього логіканці розробили внутрішню систему BookShelf: кожен може подивитися, чи є книжка в наявності в конкретному офісі, чи вона зараз вільна, а також забронювати її. Система наразі працює у web-версії, але вже незабаром стане доступним також мобільний застосунок. Його розробку ініціювали самі співробітники — щоб застосувати знання з останнього внутрішнього курсу з Flutter.




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

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

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

У вечірній час Lohika приймає в офісі такі технічні ком’юніті чи клуби за інтересами, як Python Lviv, SQL user group чи Lviv Travel Club, а вранці по суботах проводять регулярні технічні мітапи Morning@Lohika (в інших офісах їх називають TechTalks і проводять у вечірній час).

Також логіканці утворюють технічні спільноти, серед них Java, Node.js, Scala, DevOps. Наприклад, спеціалісти, що вивчають Java, збираються вранці кожного четверга, дивляться відео на конкретну тему та виконують завдання.

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

Ми провели анонімне опитування львівської команди Lohika, у якому взяли участь 55 співробітників, серед яких 46 технічних спеціалістів. Й поцікавилися, чи задоволені вони офісом, і попросили оцінити за п’ятибальною шкалою певні характеристики, серед яких розташування, графік роботи і офісний простір.

Найвищі оцінки від логіканців отримали графік та робоча техніка: три чверті опитаних оцінили їх на тверду п’ятірку, на трійку та нижче ці показники оцінили менше 5% опитаних.

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

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

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

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

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

Віталій, Java STL, 2 роки з компанією

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

Розташування офісу, як мені здається, ідеальне. Бо де б людина не мешкала, чи-то на Чорновола, чи-то в районі Варшавської, — дуже зручно добиратися. Хіба що з Сихова складно.

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

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

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

Володимир, BigData Project TL, 8 років з компанією

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

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

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

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

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

Андрій, Data Engineer, 2 роки з компанією

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

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

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

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

Василь, JavaScript AE, 2 роки з компанією

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

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

З сонячної сторони офісу влітку доволі задушливо, тож літом мусиш вмикати кондиціонер. На іншому боці все ок.


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

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

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

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


Фотограф: Євген Щегольський

Що має знати Senior Front-end Developer. Результати аналізу вакансій в Україні та Каліфорнії

$
0
0

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

Щоб дізнатися, чого очікують роботодавці від Senior Front-end Developer, ми проаналізували 274 вакансії: 152 українські вакансії на DOU станом на 26 червня та 122 каліфорнійські на LinkedIn станом на 25 серпня. У Каліфорнії до дослідження серед інших потрапили вакансії Amazon, Apple, Atlassian, Cisco, Coursera, Hewlett Packard Enterprise, JPMorgan Chase, LG Electronics, Netflix, Siemens, Tesla, Visa, Walmart.

Ми брали всі вакансії, актуальні в конкретний день та опубліковані протягом останнього місяця. Ігнорувалися лише рекрутингові агенції. Щоб не бути Капітаном Очевидність, ми не враховували JavaScript, HTML та CSS. Детальніше про методику можна прочитати в попередніх випусках серії.

Битва фреймворків: React попереду

Більшість вакансій як в Україні, так і в Каліфорнії передбачають знання React. У Каліфорнії це навичка номер один з показником 73% згадок. Усі версії Angular та AngularJS разом узяті в обох локаціях мають приблизно 45%.

Але для прихильників Vue.js є хороша новина: фреймворк має стабільну нішу в 15-20%вакансій, що співставно з сукупною кількістю вакансій iOS-розробників. З Vue.js ви не пропадете.

Ember.js згадується майже виключно в Каліфорнії.

Сюрпризом стала вкрай низька частка React Native. Але пояснення є: на сьогоднішній день React Native Developer є окремою спеціалізацією.

Англійська дає плюс $9K на рік

В Україні навичкою номер один є англійська мова з показником 61% згадок. Порівняймо компенсацію JavaScript-розробників залежно від рівня англійської згідно з альтернативним зарплатним віджетом.

  • Elementary & Pre-Intermediate — $3797 на місяць після податків (23 анкети);
  • Intermediate — $3635 (112 анкет);
  • Upper-Intermediate — $3915 (147 анкет);
  • Advanced — $4381 (28 анкет).

Найнижчі доходи мають спеціалісти з рівнем англійської Intermediate. Досягнувши рівня Advanced, можна розраховувати на суттєве підвищення доходу: (4381 — 3635) x 12 = $8952 на рік.

Високі доходи людей з англійською нижче Intermediate можна пояснити тим, що лише дуже крутий програміст може вижити в сучасному IT, погано володіючи мовою комунікації з замовником. Скоріше за все, підтягнувши мову до Advanced, ці люди могли б претендувати навіть не на 4381, а відмовлялися б від оферів на 5K :)

«Буде плюсом»: найперспективніші навички

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

Для Senior Front-end Developer найчастіше в додаткових побажаннях в Україні вказують Node.js (16%), AWS (10%), GraphQL (7%), CI/CD (7%), Webpack (6%), React Native (6%), Docker (6%). У Каліфорнії до них додається Java (9%).

Україна vs Каліфорнія: відмінності

Здебільшого статистика вимог є схожою в Україні та Каліфорнії. І там, і там Redux має близько 30%, Webpack — близько 25% тощо. Але є помітні відмінності.

У Каліфорнії кожна друга вакансія вимагає профільного диплому бакалавра. Для Java-розробника цей показник був ще вищим: майже дві третини. На цьому фоні той факт, що 84% вакансій України не згадують освіту навіть як «буде плюсом», демонструє рівень розчарування в наших університетах.

Ще в Каліфорнії чомусь вдвічі більше цінуються комунікативні навички: ~40% проти ~20% в Україні. Agile та Scrum теж згадуються в Каліфорнії вдвічі частіше, ніж в Україні.

Серед технологій в Каліфорнії помітно більше згадок Babel, jQuery, AJAX, Jasmine, Mocha, Chai, Gulp, Grunt. Частіше потрібно знати back-end: Node.js, NPM, Python та Java.

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

Каліфорнія

Hewlett-Packard Enterprise шукала Senior UI Developer з 15 роками досвіду.

Компанія Netskope готова взятина роботу Sr Full Stack UI Developer з дипломом бакалавра психології. А чому б ні?

Компанія Sköna в Сан-Франциско пише: «Weʼre dog friendly — bring along your four legged friend!»

Для компанії TravisMathew Apparel важливо, щоб співробітник по мірі необхідності був на зв’язку вечорами та на вихідних.

Україна

В компанії MOJAM (Харків) для співробітника є можливістьотримати фінансування та запустити власний проект всередині компанії. А в компанії BCD TripTech (Київ) на власний проект співробітника виділяєтьсяодин робочий день на місяць.

В Delphi Software (Київ) відкрита вакансія, що передбачає опціони на акції клієнта: австралійського стартапу Vervoe, що працює зі штучним інтелектом.

Працівники компанії SMARTCRAFT (Одеса) можуть взяти week off for parent’s needs в додаток до 4 тижнів відпустки. Робота без овертаймів. А ось в офісах Intellias у Києві та Львові є дитячі кімнатиз професійним baby-sitter.

Компанія Shopmonkey Inc (Київ) пропонуєкомпенсацію до 5000. Можливе віддалене співробітництво. Компанія Edgica (Київ) теж пропонуєдо 5000, відрядження до європейських країн та роботу в демократичній команді без бюрократії.

Для тих, хто любить подорожувати. Компанія X1 Group відправлятимеу регулярні відрядження з Харкова до Берліну. Вакансія компанії Youwe (Київ) передбачаєвідрядження до Нідерландів. А в компанії Corva.AI (Київ) є можливістьвідвідати США.

В компанії Xenoss (Харків) не обмежуєтьсяробота з дому. Натомість компанія Pharos Production Inc (Київ) пропонуєкрісло, комфортне для спини, та кальян на кухні.

Для продуктової компанії Poster (Дніпро) буде плюсомучасть в олімпіадному програмуванні.

Компанія Soft2bet (Київ) пропонуєофіційне працевлаштування згідно з Трудовим кодексом України. Буде плюсом досвід з TDD.

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

Андрій Кобилін, Senior Front-end Developer в Beetroot

В первую очередь важно уметь писать качественный, легко читаемый и предсказуемый код. Нужно уметь разбивать функциональность на компоненты и комбинировать их в другие, более сложные компоненты. Очень полезно будет освоить функциональное программирование на JavaScript. Оно сейчас в тренде, так как такой код более прогнозируемый и простой в понимании. Рекомендую почитать книгу Composing SoftwareЭрика Эллиотта (Eric Elliott) по этой теме. Также полезно будет почитать про паттерны программирования Learning JavaScript Design PatternsЭдди Османи (Addy Osmani).

Senior Front-end разработчики должны оценивать свой продукт с точки зрения UX/UI. Поэтому также стоить почитать хотя бы базовые книги по UI/UX, чтобы понимать, как сочетать цвета, группировать элементы и т.д. Советую почитать Don’t Make Me ThinkСтива Крюга (Steve Krug).

Конечно же, как и любые другие Senior разработчики, Senior Front-end девелоперы обязаны вникать в проект, понимать, кто является конечным потребителем, для чего внедряется та или иная фича/возможность и какова ее бизнес-ценность. Для этого нужно ориентироваться в предметной области. Если занимаешься приложением для физиотерапевта, то нужно понимать процесс диагностирования и лечения, а если делаешь программу для продажи ж/д билетов — разбираться в классификации поездов, составлении расписания и маршрутов.

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

Alejandro Del Rio, Lead Software Engineer в Symphony Solutions

Хороший Front-end девелопер має:

  • розуміти, як JavaScript виконується, що таке frame stack & call stack;
  • розуміти різницю values types і reference types;
  • знати, що таке functional scope, block scope, lexical scope;
  • розуміння, як працює setTimeout, setInterval, requestAnimationFrame;
  • вміння застосовувати OOP та Design patterns;
  • розуміння і застосування lambda function (map, reduce, etc), Closure, Hoisting, Curring.

Тетяна Ільченко, Front-end Technical Lead в CodeIT

Для хорошего Front-end разработчика, как правило, не достаточно разбираться только в js, html, css и одном из фреймворков (React, Vue.js, Angular etc.).

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

Must have для middle+:

  • Deep knowledge of JavaScript;
  • Algorithms and Data structures;
  • Design patterns;
  • Architecture patterns;
  • Scalable project architecture;
  • Page performance;
  • Security.

Не лишними будет базовое знание back-end (Node.js, PHP, Java etc.). Оно позволит лучше понимать архитектуру всего проекта, а не только его front-end части, облегчит общение с Back-end разработчиками, а также позволит учитывать особенности работы и возможности серверной части.

Немаловажны знания UI/UX -Front-end разработчик всегда тесно работает с дизайнерами и должен уметь увидеть недочеты и/или предложить альтернативный вариант решения.

Знания в области SЕО — помогут в дальнейшем избежать проблем при продвижении сайта.

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

Василь Романчак, Senior Web Developer в MyHeritage

5 років досвіду роботи з технологією Х не робить вас Senior девом. «Сіньйорність» залежить від уваги до деталей, ставлення до роботи, рівня англійської та ваших комунікативних навичок більше, ніж те, як добре ви знаєте React/Angular/Node.

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


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


От легаси к Service Fabric за 360 часов. История одной миграции

$
0
0

Статья посвящена бесконечной борьбе с legacy. Это история о том, что можно сделать, если взять двух разработчиков (второй — для код-ревью) и 360 часов. А также о том, как перенести легаси-код в модный и молодежный клауд-сервис. Код с пошаговой инструкцией тут. Это репозиторий с примером переноса .NET Core Web API как stateless-сервиса Azure Service Fabric c секьюрити, API versioning и т. п.

Начало

Customer: We need to add a new feature to the legacy system, can you give an estimate?
Developer: It depends on when the legacy system will be replaced?
Customer: In five months.
Developer: Then the new feature will take six :)

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

У меня процесс стартовал с обсуждения возможности масштабирования части платформы и уменьшения latency-запросов. Проблемная часть системы была построена на старых сервисах Windows Communication Foundation с классической трехслойной архитектурой. WCF-фреймворк — это SOAP-монстр, но надежный и с широким функционалом, в 2010 году он был основой для Enterprise-решений. На этом же этапе поддержка сервисов и DevOps-задачи забирали приличный объем времени.

Оптимальным считается подход Lift and Shift, который подразумевает перенос сервисов в облако на виртуальные машины с дальнейшим постепенным разделением и рефакторингом на отдельные компоненты. Но такой подход не входил в мои планы, хотя на первый взгляд физически и экономически он выглядел вполне разумно. С другой стороны, перенос кода на .NET Core Web API было достаточно сложно оценить. В результате я сделал PoC за несколько выходных, чтобы оценить возможные риски. Конечно же, оценку рисков стоит начать с проверки качества текущего кода, проверить, живы ли Unit-тесты и т. п. Важно также не планировать отпуск, пока миграция не завершилась успешным развертыванием :)

Почему Service Fabric, а не Kubernetes

Focus on development, not on the infrastructure

Одной из проблем при переходе на новые фреймворки и технологии является повышение сложности систем. Связка Kubernetes + Docker буквально означала, что в результате я получу такой объем DevOps-задач, как и при работе с WCF-сервисами, развернутыми на VMware-фермах.

Эффект IKEA — это когнитивное искажение, которое появляется, когда покупатели непропорционально высоко оценивают значимость (ценность) товаров, которые они создают отчасти сами (Wikipedia).

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

Одной из моих задач было сокращение объема maintenance и DevOps-активностей, чтобы освободить время на разработку нового функционала. Azure Service Fabric после небольшого PoC полностью удовлетворил этим требованиям, плюс кривая обучения гораздо более пологая в сравнении с Kubernetes.

Почему Azure Service Fabric?

  • Сокращение цикла разработки.
  • Почти полное отсутствие DevOps-задач.
  • Простой деливери с помощью Azure DevOps CI/CD pipelines.
  • Надежный scale-out and scale-in и отказоустойчивость.
  • Простая разработка, кластер ASF запускается на ПК разработчика.

Оценка

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

Главное, с чего стоит начать, это с проверки зависимостей и NuGet-пакетов на совместимость с .NET Standard 2.0. Мне повезло, и тут проблем не оказалось.

Что было сделано во время PoC?

  • Проверка зависимостей на совместимость с .NET Standard 2.0.
  • Создание кластера Azure Service Fabric с подходящей конфигурацией VM.
  • Проект с stateless-сервисом Azure Service Fabric.
  • Публикация сервиса в облако и создание нескольких простых нагрузочных тестов с помощью Postman и Loader.io.

Пример создания кластера с помощью CLI из воркшопа для Azure Bootcamp Lviv

Что нужно не забыть при оценке проекта?

  • Использовать данные, полученные на этапе PoC.
  • Добавить время на Infrastructure as Code и настройку CI/CD через Azure DevOps.
  • Об установке дополнительных сертификатов и о работе с Azure Key Vault.
  • Определиться с секьюрити и выбрать Identity-провайдера.
  • Учесть в оценке стоимость работы Dev, Test and Stage энвайронментов.
  • Не забыть о мониторинге (и начать с него).

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

Security — это просто и сложно одновременно. Если сервисы используются внутри сети, то необходимо развернуть Azure VNet и Network Security Group для ограничения доступа к сервисам из интернета. Если же подразумевается открытый доступ, то, имхо, оптимальный вариант — это Identity as a Service в виде Azure AD B2C, OAuth 2.0 или самописного решения на Identity Server 4.

Что нужно знать перед работой с сервис-фабрикой

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

Во-первых, нужно знать разницу между The durability tier и The reliability tier и для чего они нужны.

А во-вторых, понимать, что кластеры Azure Service Fabric работают на тех же Virtual Machine Scale Sets (VMSS), которые используются в Azure App Service. Если с VMSS уже опыт был, тогда переход будет легким. Стоит помнить, что выполнять манипуляции с VMSS в Service Fabric надо только после полного уяснения терминов выше.

Кластер ASF

Cluster: A network-connected set of virtual or physical machines into which your microservices are deployed and managed. Clusters can scale to thousands of machines.

Node: A machine or VM that’s part of a cluster is called a node. Each node is assigned a node name (a string). Nodes have characteristics, such as placement properties. Each machine or VM has an auto-start Windows service, FabricHost.exe, that starts running upon boot and then starts two executables: Fabric.exe and FabricGateway.exe. These two executables make up the node.

Сколько нужно нод и машин в VMSS? Для старта я бы использовал 3 ноды. После первых нагрузочных тестов конфигурацию и количество машин в VMSS можно изменить в любую сторону. Протестируйте нагрузку, и если при нужном вам количестве запросов в минуту (например, 1000) задержки ниже 200 мс, то можно оставить как есть.

Primary-нода в Service Fabric кластере выполняет задачи, связанные с оркестрацией кластера, и делит ресурсы вашего приложения с системными сервисами. Поэтому не стоит удалять и делать эксперименты на ней, а также производить операции scale-up и scale-in без предварительных тестов.

Обязательно нужно различать кластеры durability и reliability tiers. Знать ограничения, касающиеся понижения уровня с золотого до серебряного и т. п. Если вы оценили нагрузку на старые WCF-сервисы и выполнили нагрузочное тестирование API, то после настройки VMSS scale-out можно спать спокойно.

Перенос кода

План был достаточно простым.

  • Перенести код из WCF в Web API.
  • Добавить API в stateless ASF-проект.
  • Добавить все секреты и сертификаты в Azure Key Vault.
  • Распределить функционал по нескольким сервисам.
  • Протестировать результат.

Переносим код. Это несложная операция, требующая внимания и покрытия тестами :) Этап начался с переноса WCF-сервисов в контроллеры Web API, используя правило: 1 сервис => 1 контроллер. Компоненты 3-tier-архитектуры легко переносятся в Onion-архитектуру с aggregation root в Startup.cs (детали вне контекста этой статьи).

После того как перенос кода выполнен, стоит протестировать результат: сделать набор запросов к API и прогнать с помощью Postman. Если HTTP 200, то можно приступать к рефакторингу старых Unit- и Integration-тестов.

Устанавливаем Azure Service Fabric SDK. К сожалению, компоненты локального кластера не работают нормально с Visual Studio 2019, по-прежнему необходима установленная Visual Studio 2017. Перегружаемся и получаем информационное сообщение о запуске локального кластера ASF. После перезагрузки и автоматического запуска кластера стоит сразу уменьшить capacity до 1 ноды, чтобы не тратить ресурсы VM впустую.

Создаем проектService Fabric с stateless-сервисом для Web, запускаем и переходим по URL созданного контроллера для проверки. Затем заменяем созданное веб-приложение Web API и изменяем GUID проекта в sln-файле. Собираем проект, запускаем и затем проверяем контроллеры с помощью набора запросов в Postman. Вуаля!

Разбиваем сервис на несколько логических частей. Руководствоваться стоит данными по нагрузке, собранными на этапе эстимирования, и здравым (!) смыслом. В описанном выше случае 10 WCF-сервисов поместились в 3 Web-сервиса. Нагрузка при этом оказалась неравномерной, и много ресурсов VMSS (Standard_D1_v2) попросту простаивали. К сожалению, серебряной пули нет и придется проверять нагрузку с помощью нагрузочных тестов. В идеале запускать нагрузочные тесты лучше из Azure DevOps, для этого создать нужное число аккаунтов и использовать бесплатный объем тестов из каждого ;)

К сожалению, к моменту запуска не все тесты в солюшене были переписаны под новое .NET Core приложение :(

Конечно же, были и проблемы

Оказалось, что подход Infrastructure as Code подкинул проблем. При попытке создать кластер фабрики через портал с названиями из скрипта Azure CLI названия не проходят валидацию в инпутах :) Видимо, на портале валидация слегка устаревшая, так как инфраструктурные скрипты продолжают выполняться.

Вывод: не используйте GUI, описывайте вашу инфраструктуру в коде и храните ее в Git или хотя бы в проектной Wiki.

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

Цена кластера из 5 нод будет в районе 500 долларов США в месяц. Чтобы уменьшить цену минимум в 3 раза, нужно использовать Linux-машины с shared compute типа Standard_B2s и контракт на 3 года. Но тут надо трезво оценить свои силы (время), так как проект .NET Core Web API, скорее всего, не запустится сразу под Linux.

Установка сертификатов кластера тоже имеет специфику и лучшим образом выполняется только с помощью PowerShell-скриптов. Внимательно отнеситесь к эстимированию задач по деплойменту ;) И храните секреты (сертификаты) в Azure Key Vault. Но если надо, то ниже скрипт для установки сертификатов в кластере.

Полезно разобраться в том, как работает Load Balancer, каковы принципы работы Reverse Proxy, что такое VNet и почему нужна Network Security Group. Но, строго говоря, для старта достаточно двух действий: добавления Load Balancer порта 443 и health probe для этого порта. И не забыть удалить порт 80 :)

Для администрирования кластера я использую PowerShell и Azure CLI

Заключение

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

Что я бы сделал сейчас по-другому? В принципе, многое. Как минимум перенес бы часть нагруженных сервисов на FaaS в виде Azure Functions с увеличением эстимейта. Но это уже совсем другая история. С учетом требований этот проект оправдал себя. Cheers!

Полезные ссылки:


Если будут вопросы, пишите мне в Twitter.

Почему IT-стартапу на ранней стадии не нужен маркетолог

$
0
0

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

Вначале расскажу о собственном опыте. Свой первый продукт я начал строить в 16, и, если быть уж совсем откровенным, предложение должно было бы звучать так: «Свой первый продукт я зафейлил в 16». Нельзя сказать, что это меня остановило. После него шла довольно интересная чехарда из других продуктов in-house, контрактов, своих продуктов, фрилансов — чего только не было. Сейчас я отвечаю за рост в Let’s Enhance, строю свой небольшой продукт Quokkaи помогаю стартапам в рамках Google Developers Launchpad и Startup Wise Guys.

Image Source

Главная ошибка

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

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

Я наблюдал такую ошибку у массы продуктов: все сломя голову бегут искать маркетологов. Но глубину проблемы осознал, лишь когда попал ментором в Google Developers Launchpad, Startup Wise Guys и несколько других инкубаторов. Маркетолог просто не поможет вам. Но чтобы это понять, давайте попробуем разобрать ожидании фаундеров, потребности продукта и силы маркетолога на ранних этапах стартапа.

Ожидания фаундеров

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

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

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

За редким исключением хотят обязательно видеть скилового маркетолога с каким-то очень диким списком навыков вроде ведения соцсетей для энтерпрайз-продукта или умений в ивент-маркетинге для B2C-продукта с чеком в 5 долларов США в месяц. Не надо так.

А что же делать?

Потребности продукта

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

Интервьюирование пользователей — это не rocket science. Важно услышать ответ на вопрос, почему они используют продукт? И вот тут есть один лайфхак, которым я пользуюсь каждый день. Думать не просто о фиче, а о «продукте продукта». Об этой идее мне когда-то рассказал Вася, фаундер Storyline (стартап прошел YC, а после участвовал в слиянии с Voiceflow).

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

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

Это и есть ответ на вопрос, что надо узнать во время интервью. Чего ожидал пользователь, что он получил, какую проблему он решил? Частично могут помочь опросы Шона Эллиса. Это, мягко говоря, не самый лучший способ получить Product Market Fit, но он сгодится для сбора первичного фидбэка от людей.

Теперь перейдем ко второй части списка — привлечь пользователей. Можно отбросить истории с overnight success как сказки. Наша актуальная задача состоит не в том, чтобы вырасти на 1 миллион пользователей, а в том, чтобы обеспечить себе стабильный поток из 1, 10 или 100 пользователей в месяц перед началом итерации продукта. И вот тут есть два сценария: забить на стоимость привлечения и оптимизации или пытаться быть lean.

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

Идея в том, чтобы не смотреть на то, что CAC — 50 долларов США, а LTVедва ли 10. При использовании этого подхода нам абсолютно безразличны эти цифры. Нас интересует просто некое количество пользователей, на которых мы сможем обкатать гипотезы. И при таком варианте развития событий маркетолог совсем не нужен, потому что интерфейсы и логика в Facebook/Google ads крайне простая и стартануть можно буквально через 10 минут с момента первого открытия. А придет к вам маркетолог, когда продукт еще не очень, и снизит САС до 42 долларов США. Легче станет? Нет.

Пытаться быть lean. Тут на помощь приходят Product Hunt, Hacker News, блоги, группы в соцсетях, cold outreach (say hi to GDPR), бандлы с другими продуктами. Вариантов масса. Самое удивительное, что разработчики зачастую намного (прямо в несколько раз) лучше делают маркетинг. Конечно, надо будет почитать статьи, наделать своих ошибок. Но все равно в среднем это работает лучше. Нет ничего важнее для продвижения, чем искренний огонь в глазах и попытки понять, а как же сделать лучше. Примечательно, что маркетолог вам будет, скорее всего, только мешать. Потому что такое продвижение вначале строится на личном бренде, за редким исключением.

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

Навыки маркетолога

Какие хард-скилы требуются маркетологу на этом этапе? Берите свой ARPU. Умножайте на 12. Это поможет понять стек возможных каналов привлечения пользователей. Если эта цифра попала в промежуток 500-5000 (называется death valley), с него надо выбираться. До 50 долларов США — SEO, Viral loops. До 250 долларов — paid ads. До 500 — content marketing. Выше 5000 долларов США — sales. Некоторые навыки могут понадобиться от случая к случаю и будут работать как источник traction, но никак не predictable growth. Соответственно, отсюда понятно, какой опыт у кандидата обязательно должен быть.

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

В чем тут сложность? UA (user acquisition), Growth и Product marketing — это немного разные вещи. И если две последние позиции еще пересекаются, то UA стоит отдельно. Это примерно как искать фулстака, чтобы и серверы поднимал, и бэк делал, и верстал, и еще немного в ML умел. То есть один человек это все не закроет. И даже если он умеет это все делать, каждая область по отдельности — предмет работы на кварталы, но не на спринты.

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

  • Имейл-маркетинг как все еще основной канал общения с пользователями.
  • А/В тесты. Не из-за того, что вы начнете тестировать что-то на 38 пользователях, а, скорее, из подхода к решению проблем, который вырабатывается при тестировании.
  • Эмпатия и готовность общаться с пользователями. Сейчас часто встречаются «технические маркетологи», которые отлично крутят настройки рекламы, но не могут общаться с людьми. Это суперстранно и на первых этапах очень вредно.
  • Копирайтинг. Это в целом базовый инструмент. Большая часть маркетинга — это про коммуникации. Настроить пиксель можно и обезьянку научить, а вот писать хорошо — это уже сложно.
  • На кого ровняется. Конечно, я больше предпочитаю тех, кто читает инженерные блоги компаний или отдельных людей. Это очень хороший маркер понимания индустрии. В Adweekне пишут о том, как Instacartиз-за какого-то подхода к анализу данных смог сделать более правильные решения. А вот в блоге компании — запросто.

Outro. Конфликты

Тут же появляются некоторые конфликты: между фаундерами и продуктом, продуктом и маркетологом, фаундерами и маркетологом. Под конфликтом я подразумеваю не ссоры, увольнения, понижение зарплаты, а, скорее, растущую моральную нагрузку.

Фаундер vs. продукт. Нанимая маркетолога, обычно ждут быстрого роста, который просто по законам физики не может произойти по велению одного человека в команде. Growth как процесс всегда затрагивает весь продукт. И к этому надо быть готовым. Это больно и сложно. Рост в продукте, который к этому не готов, приводит к истории Fabили Homejoy. Легче от этого никому не становится, так как в погоне за красивой цифрой роста теряется из виду, что все меньше пользователей довольны продуктом и все больше их уходят очень быстро.

Продукт vs. маркетолог.Продукт требует фокуса на какой-то одной области. И если первый конфликт не разрешен, все уходит в штопор. От маркетолога ждут переключения между разными частями воронки все время. Обычно это заканчивается примерно никак. Если маркетолог скиловый, он обычно хотел бы углубиться в одном куске user journey. Если нет, его прыгание по разным кускам приводит к тому, что ни один не будет доделан. Лучше 20 шагов в одном направлении, чем по 1 шагу в двадцати. От этого проигрывает продукт. Раньше это была и моя личная ошибка. Мне казалось, что сейчас я вот тут подкручу имейлы, там сделаю onboarding, а вот тут поправлю таргетинг в рекламе... И я все время думал, что сделаю все в первой итерации. Так, увы, не работает. Из 10 А/В-тестов по статистике только 1-2дают прямо хороший рост. Что уж тут говорить о разных кусках продукта.

Фаундеры vs. маркетолог.Замыкает цикл конфликт между фаундерами и маркетологами. Фаундер не видит того, что хотел бы видеть. При этом продукту это как-то не помогает. А маркетолог делает то, чего бы фаундер делать не хотел. Я тоже через это проходил. Все мы слышали в стартапах фразу: «Это стартап, и тут нет четкого распределения обязанностей». Это хорошо работает для фаундеров. Если нанимать человека на дизайн и кидать его в продажи, это приведет к перегоранию. И случается такое постоянно.

Выводы

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

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

  • получили пользователей (выше мы поговорили, как это работает);
  • провели опрос;
  • итерация.

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

Как проводить опросы, написано в статье How Superhuman Built an Engine to Find Product/Market Fit by Rahul Vohra и в книге Mom Test Book by Rob Fitzpatrick. А об итерациях в статье Four Fits for $100m+ Growth By Brian Balfour. Этого хватит любому техническому фаундеру, чтобы понять базис и сделать лучше, чем 80% маркетологов на рынке.

Главные уроки найма, которые я вынес для себя:

  1. Первый найм — сейлз. Даже если экономика потом не позволяет скейлиться, не это на старте ваша проблема.
  2. Второй — кастомер-саппорт.
  3. И только потом, возможно, это будет маркетолог, который в целом, а не в лице кофаундера бесполезен в большинстве своем до раунда эдак А.

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

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

Как учить иностранный язык так, чтобы заговорить на нем

$
0
0

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

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

  • Английский — после 10-летнегоперерыва с момента окончания школы за 6 месяцев до возможности смотреть фильмы в оригинале и общаться с заказчиком. Я тратил около часа в день плюс одно групповое занятие (60 мин.) в неделю в IT-компании.
  • Испанский — с нуля за 4 месяца до возможности читать адаптированную литературу, понимать на слух песни, общаться с испаноязычными туристами. Мне понадобилось также около часа в день, но в этом случае дополнительно одно индивидуальное занятие (60 мин.) в неделю.
  • Датский — с нуля за 8 месяцев до возможности по телефону записаться к врачу, говорить с госслужащими, читать рабочие письма или сообщения из детского сада. Сейчас я трачу около часа в день и прохожу одно групповое занятие (120 мин.) в неделю.

Эти методы помогли заговорить мне и, надеюсь, помогут вам.

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

Четко обозначьте цель

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

На личном примере

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

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

Принимаясь за датский, я поставил цель (это не было требование фирмы или общества) начать говорить с коллегами максимум за год. Здесь был четкий дедлайн (12 месяцев) и объем работы (устные диалоги в офисе).

Учите глаголы

Учите глаголы, они несут больше всего смысла. Вас легче поймут.

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

Учите сразу три формы самых используемых глаголов. Это муторно, но необходимо. И быстро, потому что их немного: всего самых используемых около полсотни, неправильных — 20%.

Загуглите most used verbs in... или «самые употребительные глаголы...».

На личном примере

Работая с иностранными коллегами, я в течение недели выписывал глаголы, которые употреблял в офисе, и помечал самые используемые среди них. Накопилось около 30: deploy, approve, merge, reject, assign, apply, add и т. п. Перевел и начал употреблять короткие простые предложения в чатах, в устных диалогах.

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

Используйте сразу же

Употребляйте новые слова минимум 5 раз в течение недели (сразу после ознакомления, через час, через день, через неделю). Так вы задействуете разные виды памяти.

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

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

На личном примере

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

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

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

Найдите свою сильную память

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

На личном примере

Я делаю ассоциативные связки.

«Хочу спать — SLEEPаются глаза» (английский).

«ЗаMURовали в СТЕНУ» (испанский).

«Лук — LØGовая шелуха» (датский, тут для запоминания написания, так как читается «лёэ»).

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

Чем необычнее ассоциация, тем лучше запомнится: Azul, голубой на испанском, я запомнил через созвучность с Озилем (Месут Озиль из ФК «Реал Мадрид»).

Еще мне помогает сравнение слов с синонимами в иностранном языке. Это задание требует соответствующего настроения, чтобы вникнуть в лингвистические объяснения, зато слова основательно запоминаются и легко извлекаются из памяти в активной речи. Вы задумывались, в чем разница между approve и confirmили, например, Deny/Refuse/Reject/Decline?

Совмещайте с приятным

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

На личном примере

В изучении испанского мне всегда помогал мультфильм «Трое из Простоквашино»на испанском языке. Gato Morinero (кот Матроскин на испанском) — очень смешной и ассоциативный персонаж. Я пересматривал мультфильм много раз и только из него одного вынес очень много.

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

Упрощайте речь

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

Начните говорить короткими предложениями. Простыми. Не больше 3-4 слов.Ваш мозг должен привыкнуть. Ваша нервная система должна привыкнуть.

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

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

Шутка вместо личного примера

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

Готовьтесь к диалогу заранее

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

На личном примере

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

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

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

Когда вы заранее решите употребить новое слово, то в такой цепочке сможете использовать его минимум 5 раз в течение 1-2 суток.

Рассказывайте о своем обучении

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

На личном примере

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

Итого

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

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

DOU Hobby: карпфишинг — спортивная рыбалка со своей философией

$
0
0

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

Виталий Офат — Senior Full Stack Developer и Team Lead в компании Lucky Labs. Его увлечение — особый вид рыбалки — карпфишинг. Виталий рассказал, чем эта рыбалка отличается от других, в чем заключается философия карпфишинга и где в Украине водятся самые крупные карпы.

— Виталий, что такое карпфишинг? В чем его особенности?

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

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

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

— Как и с чего началось ваше увлечение карпфишингом? Откуда узнали о нем? Увлекались ли до этого обычной рыбалкой?

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

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

— Почему вас заинтересовал именно этот вид рыбалки?

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

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

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

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






— Чем еще карпфишинг отличается от обычной рыбалки?

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

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

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

— А откуда в карпфишинге взялась идея, что карпов надо отпускать на волю?

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

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

— Как часто вы ездите на такую рыбалку? Как совмещаете хобби с работой?

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

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

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

— Какая нужна экипировка? Что сколько стоит? Как новичку выбрать правильные вещи?

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

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

Я в самом начале покупал бюджетные удилища британских брендов. Они стоят дороже китайских аналогов, но зато их можно потом продать на вторичном рынке. Удочки и катушки для начинающих обходятся приблизительно в $100 за штуку. То есть начальный набор будет стоить до $1000, и его всегда можно будет продать.

Более качественные снасти стоят $200–300 за удилище и катушку. Ну а профессиональные снасти могут обойтись и в $500–1000.

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

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






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

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

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

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

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

— Насколько вообще в Украине развито сообщество карпфишеров? Есть ли какие-то клубы?

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

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

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

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

Карпы по 5-7 кг,соревнования Аматор&Робинзон, озеро Кричевичи

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

Да, сборная Украины дважды подряд становилась чемпионом мира по карпфишингу — в 2017 и 2018 годах. А в следующем году такой турнир и вовсе пройдет в Украине, на водоеме Прилбичи во Львовской области.

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

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

— Какие цели ставите себе на будущее?

Хочу улучшить свою технику заброса. На многих водоемах, особенно на соревнованиях, рыбу приходится ловить на дальних дистанциях. Это 130–150 мот берега. Для таких забросов важны хорошие снасти и физические показатели, но все же самое главное — это техника заброса. Сейчас я могу бросать примерно на 100–110 м.Для меня это стимул и ходить в тренажерный зал, и улучшать технику на рыбалках :)

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

Также в свободное время я работаю над своим pet-проектом, социальной сетью для «карпятников» — carpfishers.com. Там можно будет делиться отчетами о рыбалках, искать попутчиков и компаньонов, продавать и покупать снасти, регистрироваться на соревнования и искать новые водоемы. Выпустить проект в свет планирую в конце года.

Как построить сложный UICollectionView, используя iOS 13

$
0
0

В первойи второйстатьях я рассмотрел UICollectionViewCompositionalLayoutи UICollectionViewDiffableDataSource — основные компоненты, которые используются при создании UICollectionView. Но это все теория. А как реализовать сложный layout, используя эти компоненты, я постараюсь объяснить в своей третьей статье. Мой подход не претендует на универсальность, но с его помощью удалось покрыть все придуманные мною требования.

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

  1. Информация о клиенте.
  2. Список взятых книг.
  3. Список книг, которые можно взять.

В итоге все будет выглядеть, как на скриншоте:

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

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

Section & Cell

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

protocol Cell {
    associatedtype Object

    func configure(with object: Object)
}

Второй объект — это абстрактный класс Section, который будет имплементировать протокол Hashable. Этот класс понадобится для того, чтобы все секции имели одинаковое поведение.

class Section: Hashable {
    let id: String

    init(id: String) {
        self.id = id
    }

   func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }

    static func == (lhs: Section, rhs: Section) -> Bool {
        return lhs.id == rhs.id
    }
}

CollectionAdapter

CollectionAdapter будет связывать два наших ключевых объекта — UICollectionViewCompositionalLayoutи UICollectionViewDiffableDataSource. Этот адаптер будет хранить в себе UICollectionViewDiffableDataSourceи запрашивать данные для слепков с помощью делегата. Так как в секциях будут разные элементы, сразу будем использовать структуру AnyHashable.

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

С UICollectionViewCompositionalLayoutвсе просто: необходимо возвращать расположение элементов в секциях. Для этого тоже добавим функцию в класс Section.

protocol CollectionAdapterDelegate: AnyObject {
    func sections() -> [Section]
    func itemsFor(section: Section) -> [AnyHashable]
}

class CollectionAdapter {
       private weak var collection: UICollectionView?
       private lazy var datasource: UICollectionViewDiffableDataSource<Section, AnyHashable> = UICollectionViewDiffableDataSource(collectionView: self.collection!, cellProvider: cell)
       private weak var delegate: CollectionAdapterDelegate?

 init(collection: UICollectionView, delegate: CollectionAdapterDelegate) {
        self.collection = collection
        self.delegate = delegate
        super.init()
        collection.collectionViewLayout = UICollectionViewCompositionalLayout(sectionProvider: sectionLayout)
    }

    private func cell(in collection: UICollectionView, at indexPath: IndexPath, for item: AnyHashable) -> UICollectionViewCell? {
        guard let item = datasource.itemIdentifier(for: indexPath) else {
            return nil
        }
        let section = datasource.snapshot().sectionIdentifiers[indexPath.section]
        return section.cell(for: item, at: indexPath, in: collection)
    }

    private func sectionLayout(for sectionIndex: Int, environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? {
        let section = datasource.snapshot().sectionIdentifiers[sectionIndex]
        return section.layout(environment: environment)
    }
}

class Section: Hashable {
     open func cell(for item: AnyHashable, at indexPath: IndexPath, in collection: UICollectionView) -> UICollectionViewCell? {
        return nil
    }

     open func layout(environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? {
        return nil
    }
}

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

func performUpdates(animated: Bool, completion: (() -> Void)? = nil) {
        guard let delegate = delegate, let collection = collection else {
            return
        }

        var snapshot = NSDiffableDataSourceSnapshot<Section, AnyHashable>()
        for section in delegate.sections() {
            section.registerCells(in: collection)
            snapshot.appendSections([section])

            let items = delegate.itemsFor(section: section)
            snapshot.appendItems(items)
        }
        datasource.apply(snapshot, animatingDifferences: animated, completion: completion)
    }

CollectionSection

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

class CollectionSection<T: Hashable, CollectionCell: Cell>: Section
where CollectionCell: UICollectionViewCell, CollectionCell.Object == T {
    var layout: ((NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection)?

    private var cellId: String {
        return String(describing: CollectionCell.self)
    }

    override func registerCells(in collection: UICollectionView) {
        collection.register(UINib(nibName: cellId, bundle: nil),
                            forCellWithReuseIdentifier: cellId)
    }

    override func cell(for item: AnyHashable, at indexPath: IndexPath, in collection: UICollectionView) -> UICollectionViewCell? {
        guard let item = item as? T else {
            return nil
        }

        guard let cell = collection.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as? CollectionCell else {
            return nil
        }
        cell.configure(with: item)

        return cell
    }

    override func layout(environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? {
        return layout?(environment)
    }
}

Client Section

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

struct ClientInfo: Hashable {
    let id: String
    let clientName: String
    let maxBooksAmount: Int
    var booksAmount: Int
}

class ClientInfoCell: UICollectionViewCell, Cell {
    @IBOutlet weak var heyLbl: UILabel!
    @IBOutlet weak var booksInfoLbl: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    func configure(with object: ClientInfo) {
        heyLbl.text = "Hey \(object.clientName)!"
        switch object.booksAmount {
        case 0:
            booksInfoLbl.text = "You have \(object.booksAmount) books from \(object.maxBooksAmount), time to find your best book!"
        case 1..<object.maxBooksAmount:
            booksInfoLbl.text = "You have \(object.booksAmount) books from \(object.maxBooksAmount), dont't forget to return them on time!"
        case object.maxBooksAmount:
            booksInfoLbl.text = "You can't take more books, try to return at least one book"
        default:
            ()
        }
    }
}

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

func sections() -> [Section] {
        let clientSection = CollectionSection<ClientInfo, ClientInfoCell>(id: CollectionSections.clientSection.rawValue)
        clientSection.layout = { env in
            return NSCollectionLayoutSection.listLayout(environment: env, height: .estimated(90))
        }

        return [clientSection]
    }

    func itemsFor(section: Section) -> [AnyHashable] {
        switch section {
        case is CollectionSection<ClientInfo, ClientInfoCell>:
            return [clientInfo]
        default:
            return []
        }
    }
   override func viewDidLoad() {
        super.viewDidLoad()

        adapter.performUpdates(animated: false)
    }

Library Books Section

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

extension CollectionAdapter: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let item = datasource.itemIdentifier(for: indexPath) else {
            return
        }
        let section = datasource.snapshot().sectionIdentifiers[indexPath.section]
        section.didSelect(item: item, at: indexPath.row)
    }
}
class Section: Hashable {
    open func didSelect(item: AnyHashable, at index: Int) {
    }
}


class CollectionSection<T: Hashable, CollectionCell: Cell>: Section
where CollectionCell: UICollectionViewCell, CollectionCell.Object == T {
var cellSelection: ((T, Int) -> Void)?

 override func didSelect(item: AnyHashable, at index: Int) {
        guard let item = item as? T else {
            return
        }

        cellSelection?(item, index)
    }
}

Теперь добавим необходимый метод в ViewController:

func didSelect(book: Book, at index: Int) {
        books[index].isSelected.toggle()
        let book = books[index]
        if book.isSelected && clientInfo.booksAmount != clientInfo.maxBooksAmount {
            clientInfo.booksAmount += 1
            clientBooks.append(ClientBook(book: book))
        } else if !book.isSelected, let clientBookIndex = clientBooks.firstIndex(where: { $0.id == book.id }) {
            clientInfo.booksAmount -= 1
            clientBooks.remove(at: clientBookIndex)
        }
        adapter.performUpdates(animated: true)
    }

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

Client Books Section

В этой секции будут отображаться книги, которые клиент взял из библиотеки. Секция должна горизонтально скроллиться, и при нажатии на кнопку в ячейке секции необходимо возвращать книгу библиотеке. Два интересных требования нужно закрыть. Первое — необходимо иметь возможность разместить emptyView в секции, если у клиента нет еще ни одной книги. Решение, которое я нашел, основывается на том, что в новом layout мы можем разместить supplementaryView, которая будет занимать всю секцию. Layout не подведет и, даже если в секции отсутствуют элементы, нарисует нашу view. Я создал отдельную секцию, которая наследуется от ClientBooksSection. Эта секция умеет возвращать supplementaryView для коллекции и отображает ее, когда у нее нет элементов. О том, что элементов нет, сообщает адаптер.

final class ClientBooksSection: CollectionSection<ClientBook, ClientBookCell> {

    static private let emptyViewKind = "EmptyClientBookSectionView"

    private var emptyView: EmptyClientBookSectionView?
    override var isEmpty: Bool {
        didSet {
            emptyView?.contentView.isHidden = !isEmpty
        }
    }

    override func registerCells(in collection: UICollectionView) {
        super.registerCells(in: collection)
        collection.register(UINib(nibName: ClientBooksSection.emptyViewKind, bundle: nil),
                            forSupplementaryViewOfKind: ClientBooksSection.emptyViewKind,
                            withReuseIdentifier: ClientBooksSection.emptyViewKind)
    }

    override func layout(environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .absolute(200))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.6),
                                               heightDimension: .absolute(200))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                         subitems: [item])

        let emptyViewSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                                   heightDimension: .absolute(150.0))

        let left = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: emptyViewSize,
                                                               elementKind: ClientBooksSection.emptyViewKind,
                                                               alignment: .leading)

        let section = NSCollectionLayoutSection(group: group)
        section.boundarySupplementaryItems = [left]
        section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary
        return section
    }

    override func supplementaryView(kind: String, for item: AnyHashable?, at indexPath: IndexPath, in collection: UICollectionView) -> UICollectionReusableView? {
        guard let emptyView = collection.dequeueReusableSupplementaryView(
            ofKind: kind,
            withReuseIdentifier: ClientBooksSection.emptyViewKind,
            for: indexPath) as? EmptyClientBookSectionView else {
                return nil
        }
        self.emptyView = emptyView
        emptyView.contentView.isHidden = !isEmpty

        return emptyView
    }
}

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

let clientBookSection = ClientBooksSection(id: CollectionSections.clientBookSection.rawValue)
        clientBookSection.cellConfiguration = { cell in
            cell.delegate = self
        }


extension ViewController: ClientBookCellDelegate {
    func didTapReturn(book: ClientBook) {
        guard let index = clientBooks.firstIndex(of: book) else {
            return
        }
        clientInfo.booksAmount -= 1
        clientBooks.remove(at: index)
        if let bookIndex = books.firstIndex(where: { $0.id == book.id }) {
            books[bookIndex].isSelected.toggle()
        }
        adapter.performUpdates(animated: true)
    }
}

Итоги

Подводя черту под всеми тремя статьями, хочется сказать, что Apple сделала то, что уже давно должна была сделать. Компания создала инструменты, которые облегчают разработку списков. Это действительно хорошо, хоть и с опозданием. Как только вы перестанете поддерживать iOS 12, можно смело браться за рефакторинг всех существующих списков на новый манер :) С полным кодом проекта можно ознакомиться на GitHub.

Viewing all 2467 articles
Browse latest View live