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

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

$
0
0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

$
0
0

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

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

Randomization

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

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

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

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

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

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

Random Source

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

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

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

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

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

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

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

Random Distribution

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

State Machine

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

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

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

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

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

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

Uploading State

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

Successful and Failure State

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

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

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

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

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

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

Заключение

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

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

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

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

$
0
0

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

.NET

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

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

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

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

Announcing .NET Core 3.0

Microsoft REST API Guidelines

Разное

Kubernetes Academy

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

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

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

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

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

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

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

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

DevOps Guide from basic to advanced with Interview Questions and Notes

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


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


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

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

$
0
0

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

Debug у Visual Studio та Visual Studio Code

Visual Studio:

Visual Studio Code:

Події

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

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

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

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

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

Modern C++

We don’t need no stinking expression templates

C++20 span tutorial

A Universal Async Abstraction for C++

C++20’s Conditionally Explicit Constructors

Eliminating the Static Overhead of Ranges

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

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

Why PE need Original First Thunk(OFT)?

Access tuple-like container by type to return an index

How to Merge Consecutive Elements in a C++ Collection

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

C/C++ Include Guidelines

Don’t Use unique_ptr for PIMPL

Efficient QString concatenation with C++17 fold expressions

Інструменти

AddressSanitizer (ASan) for Windows with MSVC

Introducing C++ Build Insights

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

Support for C++20’s Concepts in CLion

Deterministic builds with clang and lld

Оновлення

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

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


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

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

$
0
0

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

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

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

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

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

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

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

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

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

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

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

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

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

Почему нет?

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

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

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

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

Почему да?

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

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

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

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

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

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

Выбор страны

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

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

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

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

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

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

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

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

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

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

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

Политика

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

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

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

Язык

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

Погода

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

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

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

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

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

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

Медицина

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

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

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

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

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

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

Недостатки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Монреаль

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

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

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

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

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

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

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

Эдмонтон

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Торонто

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Всё зеленое.




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

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

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

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

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

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

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

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

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

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

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

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

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

Трупиал

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

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

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

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

Курильщики

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

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

Белки

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

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

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

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

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

Кошки

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

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

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

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

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

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

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

Вода

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

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





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

Улицы

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

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

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

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

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

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

Борщ

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

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

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

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

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

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

Язык

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Культура

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

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

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

Адаптация

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

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

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

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

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

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

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

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

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

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

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

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

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

Улыбки

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

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

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

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

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

LGBT

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

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

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

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

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

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

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

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

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

Тяжелое

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

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

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

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

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

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

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

1,7 / 27,3 / 1,4

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

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

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

1,8 / 5,30 / 6,20

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

114 / 655 / 157

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

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

Банки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Всё просто:

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

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

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

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

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

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

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

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

Итак, дети.

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

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

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

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

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

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

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

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

Ботинки

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

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

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

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

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

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

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

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

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

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

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

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

Вело и дороги

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

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

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

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

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

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

Машины

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

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

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

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

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

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

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

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

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

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

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

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

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

Рекомендую:

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

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

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

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

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

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

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

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

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

Переезд

Этапы:

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

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

Шаги:

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

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

Вебинар

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

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

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

© не моя

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

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

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

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

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

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

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

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

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

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

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

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

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

$
0
0

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

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

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

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

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

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

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

Що таке кукі?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Форма згоди

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

$
0
0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Подводя итог

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

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

$
0
0

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

Алгоритмы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Какие виды тестирования знаете и чем они отличаются? Разработчику достаточно назвать модульное, интеграционное и функциональное. Если назовете нагрузочное, то необходимо заранее посмотреть в сторону такого инструмента, как JMeter, чтобы было что отвечать на дополнительные вопросы без серьезного погружения в тему.
  • Основные аннотации в JUnit (test, before, after, beforeClass, afterClass, ignore) и их особенности.
  • Чем отличается Mock от Spy в мокито? Приведите пример использования первого и второго (крепкий джун+).
  • Что, если ожидаем от метода выброшенного исключения? Что, если метод не должен выполняться дольше определенного количества времени?
  • Какие модификаторы доступа у тестовых методов в JUnit?

У крепкого джуна могут также спросить про параметризированное/категоризированное тестирование (@RunWith аннотация). Или про нюансы тестирования методов, которые обращаются к БД.

Логирование

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

ALLЛогируются все сообщения
TRACEМелкое сообщение при отладке
DEBUGВажные сообщения при отладке
INFOПросто сообщение
WARNПредупреждение
ERRORОшибка
FATALФатальная ошибка

Если выставить уровень логирования в WARN, то все менее важные, чем WARN сообщения, будут отброшены (TRACE, DEBUG, INFO). Если нужно настроить, чтобы какие-то логи писались в файл, настраивается с помощью Appenders.

Дебаг

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

На примере IntelliJ IDEA: знать, какие функции в режиме отладки выполняют F7, F8, F9. Как посмотреть содержимое обрабатываемой коллекции в конкретный момент выполнения. Как изменить значение, которое передается в метод прямо в момент отладки. Попробуйте все это на практике: сложного ничего нет, а практической пользы очень много.

Методологии разработки

Так как работать разработчику приходится в команде, то и взаимодействие внутри нее всегда организовано в виде конкретного системного подхода. Сегодня балом правит Agile — набор гибких принципов, на основе которых строятся популярные методологии. Достаточно знать две самых распространенных из них: Scrum и Kanban.

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

У Kanban в основе визуализация процесса выполнения задач в виде трех колонок таблицы: To do, Doing, Done. Основная идея — уменьшать количество запланированных задач (куда уж банальнее) и постепенно перемещать их из колонки «To do» в «Done». Очень подходит для проектов, находящихся в стадии поддержки, где основной функционал уже разработан и остались минимальные доработки и багфиксинг.

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

Подготовка и процесс собеседования

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

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

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

На джава-форумах и каналах иногда просят оценить структуру готового домашнего проекта, чтобы понять, насколько все плохо/хорошо. Я считаю это хорошим подходом. Также неплохая книга для понимания таких основ — Thinking in JavaЭккеля.

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

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

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

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

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

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

В завершение

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

Дорогу осилит идущий. Удачи!


При возникновении вопросов, пообщаться со мной можно в телеграме: @liohamitec


14 типов менеджеров, которые бесят разработчиков

$
0
0

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

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

Сперва пару слов о нас. Я Front-end Developer в DataArt, в профессии 7+ лет. Дмитрий Ховрич также больше 5 лет работает в коммерческой Front-end разработке.

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

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

1. Митинг-мэн

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

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

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

Утром мы собрались, обсудили на стендапе задачи на день, выпили кофе, пообщались, сели за работу — и спустя час-два получаем инвайт на митинг. На митинге спрашивают: «Ну, что ты успел сделать? А что тебе мешало сделать больше? Может, тебе что-то нужно от коллег?» Так и хочется сказать: «Ну если нужно, то я подойду к коллеге и спрошу!» Если каждого в команде 5+ человек поспрашивать на митинге — уже, считай, минус час-полтора времени, которое можно было потратить на разработку.

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

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

2. Инкогнито

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

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

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

3. ХЗ-мэн

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

Практически каждый разработчик сталкивался с таской, которая состоит из одного title, например, «implement login». Смотришь на этот title и не понимаешь: что вообще нужно сделать?! Менеджер подразумевал фронтенд, бэкенд или вообще дизайн? Работа над такими задачами — это гадание по хрустальному шару.

К сожалению, ХЗ-мэны достаточно распространены. Поэтому, чтобы разработчики не впадали в ступор, когда они видят задачу, существуют такие проверенные временем подходы, как написание Acceptance Criteria и Definition of Done.

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

4. Задрот-мэн

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

Есть проект, довольно крупное мобильное приложение (количество пользователей исчисляется сотнями тысяч). Разработка ведется по Scrum: стандартные двухнедельные спринты, планирование, эстимейты — все, как положено в лучших домах Лондона и Парижа.

Внезапно в середине спринта ломается логин. Заказчик прибегает к менеджеру: «У меня 100К пользователей, и никто не может войти в систему, что делать? Давайте, ребята, почините». Менеджер: «У нас скрам! Все распланировано, мы не можем просто так взять и починить логин! Если ты хочешь, чтобы мы его починили, то давай сперва сядем, посмотрим бэклог, выберем задачу, которую выкинем из этого спринта, а вместо нее поставим задачу по фиксу логина».

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

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

5. Эстимейт-мэн

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

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

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

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

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

6. А давайте так-мэн

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

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

У моего товарища была ситуация, когда они полгода писали CRM-ку на Angular, в проекте были некоторые проблемы, которые менеджер планировал решить переписыванием всего на Vue через полгода разработки! Как это может решить проблему — непонятно, но команда была «в восторге».

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

У моих коллег был опыт с адекватным менеджером. Разработчики стояли перед выбором, как развивать проект, написанный на старом Angular. Пришел новый PM, предыдущий опыт которого был с командой, которая использовала Vue, поэтому он предложил: «Ребята, у нас в прошлой команде достаточно неплохо работал Vue. Давайте, может быть, тоже попробуем?» Общение шло в дружеском ключе, своего мнения он не навязывал. Разработчики подумали, попробовали и решили продолжать проект на Vue.

7. Криворукий джира-мэн

Практически в любом проекте есть какой-то таск-трекер (Jira, Trello), который за счет определенных инструментов позволяет выстроить flow разработки, тестирования и учета задач.

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

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

8. Да, конечно-мэн

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

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

9. Таска-мэн

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

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

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

10. Додо-мэн

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

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

11. Excel-мэн

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

Был у них в команде PM, который в силу каких-то своих убеждений не мог пользоваться Jira, Trello и другими таск-трекерами. Он создал Excel-ку, в которой были расписаны задачи и исполнители. А вместо того чтобы в Jira перенести таску в колонку «In Progress», нужно было подойти к менеджеру и попросить его внести изменения в таблицу.

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

12. Копипаст-мэн

Менеджер не заморачивается с описанием стори/тасок. Просто копирует текст от клиента из письма/мессенджера и вставляет в описание в Jira. Разработчики сами разберутся.

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

13. Контроль-фрик

В отличие от Эстимейт-мэна, заморачивается на предмет того, на что вообще разработчик тратит время.

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

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

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

14. Потому что-мэн

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

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

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

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

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

В завершение

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

Union-find: алгоритм, применение и анализ сложности

$
0
0

Всем привет! Меня зовут Данил, и я Java-разработчик в компании TeamDev, занимаюсь написанием ПО для сетевых устройств.

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

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

Введение

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

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

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

Немного из теории множеств

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

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

Рассмотрим следующую задачу: имеется набор из N объектов, которые связаны между собой каким-то образом. Необходимо определить, существует ли путь, соединяющий выбранные объекты A и B через другие объекты. В теории графовданная задача определена как «задача о динамической связности» (dynamic connectivity).

Задача о динамической связности

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

Такую структуру данных, где элементы распределены на непересекающиеся множества, называют системой непересекающихся множеств (union-find data structure).

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

Правила и ограничения

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

  1. Не имеет значения, что из себя представляют объекты. Для простоты можно сопоставить N объектам числа от 0до N  −  1.
  2. Не нужно определять, каким образом объекты связаны между собой, достаточно будет определить, принадлежат ли сопоставляемые им элементы одному множеству.
  3. Когда элементы непересекающихся множеств образуют связь, их множества объединяются.

Интерфейс

Итак, согласно первому правилу элементами множества будут числа от 0до N − 1. Для решения любых задач, использующих структуру данных union-find, будет достаточно определить следующие операции (здесь и далее примеры кода приводятся на языке Java):

    public interface UnionFind {
        void union(int p, int q);
        boolean connected(int p, int q);
    }

Немного подробнее о каждой из них:

  1. void union(int p, int q) — объединяет элементы pи q, а также множества, которым они принадлежат (правило 3).
  2. boolean connected(int p, int q) — проверяет, принадлежат ли элементы pи qодному множеству.

Жадный алгоритм

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

Структура данных, используемая в алгоритме, — простой массив целых чисел (nodes[]) размера N, где индексы от 0до N  −  1сопоставляются элементам множеств, которые могут впоследствии объединяться. Два элемента с индексами pи qбудут принадлежать одному множеству, если их значения по индексу совпадают (nodes[p] == nodes[q]). Значением может быть любой элемент множества, поэтому его еще называют представителем множества.

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

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

    public class QuickFind implements UnionFind {
        private int[] nodes;
        public QuickFind(int N) {
            nodes = new int[N];
            for (int i = 0; i < N; i++) {
                nodes[i] = i;
            }
        }
        public void union(int p, int q) { ... }
        public boolean connected(int p, int q) { ... }
     }

Возьмем для примера N = 10:

Вначале каждый элемент представляет собой синглтон

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

Алгоритм Quick-find

Теперь для того, чтобы определить, принадлежат ли два выбранных элемента одному множеству, достаточно сравнить значения по индексу: nodes[p] == nodes[q].

Ниже приведена реализация unionи connected:

    public void union(int p, int q) {
        int pNode = nodes[p];
        int qNode = nodes[q];
        for (int i = 0; i < nodes.length; i++) {
            if (nodes[i] == qNode) {
                nodes[i] = pNode;
            }
        }
    }
    public boolean connected(int p, int q) {
        return nodes[p] == nodes[q];
    }

Оценка сложности Quick-find

Очевидно, что поиск связи между элементами (операция connected) осуществляется за константное время: O(1).

Однако при объединении множеств нам придется пройти весь массив. В таком случае для Nэлементов операция union имеет линейную сложность: O(N).

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

Алгоритмы с квадратичной сложностью редко находят применение на практике. Уже при N = 109поиск решения занимает часы, а при N = 1012 — годы.

Представление в виде деревьев

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

В предыдущей реализации мы представляли каждый элемент в качестве индекса i в массиве, а его принадлежность конкретному множеству — в качестве значения по индексу nodes[i]. У такого подхода есть недостаток: необходимо проходить массив каждый раз при объединении множеств.

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

Структура данных определяется следующим образом:

  1. Каждый элемент представляется в виде индекса массива nodes[]длины N.
  2. Родитель элемента i — это nodes[i].
  3. Корень iнаходится последовательной индексацией элемента: nodes[nodes[...nodes[i]...]] (пока nodes[i] ≠ i).

Операция union выполняется следующим образом: nodes[root(q)] = root(p). Визуально это можно представить, как будто корень элемента qподвязывается к корню элемента p.

Представление связей в виде дерева

Код алгоритма прост и лаконичен. Ниже приведена реализация root, unionи connected.

    public void union(int p, int q) {
        int pRoot = root(p);
        int qRoot = root(q);
        nodes[qRoot] = pRoot;
    }
    public boolean connected(int p, int q) {
        return root(p) == root(q);
    }
    private int root(int p) {
        while (p != nodes[p]) {
            p = nodes[p];
        }
        return p;
    }

Оценка реализации Quick-union

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

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

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

Взвешенные деревья

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

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

Объединение деревьев с учетом их размера

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

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

Оказывается, что при таком подходе высота самого высокого дерева будет не более log(N), или, другими словами, ранг любого узла дерева не превышает log(N). Рангом узла будем называть расстояние (число ребер) от данного узла до корня дерева.

Итак, введем новую эвристику:

  1. Структура данных такая же, как и в алгоритме Quick-union.
  2. Вводится дополнительный массив sz[]для подсчета количества элементов дерева с корнем i.

Код операций rootи connectedостается прежним, меняется только union:

    public void union(int p, int q) {
        int pRoot = root(p);
        int qRoot = root(q);
        if (pRoot == qRoot)
            return;
        if (sz[pRoot] < sz[qRoot]) {
            nodes[pRoot] = qRoot;
            sz[qRoot] += sz[pRoot];
        } else {
            nodes[qRoot] = pRoot;
            sz[pRoot] += sz[qRoot];
        }
    }

Изменений в коде немного, однако скорость работы алгоритма существенно возросла. Этот факт будет несложно доказать.

Доказательство сложности log(N)

Утверждение.Ранг любого узла x не превышает log(N), где N — количество узлов.

Доказательство.Рассмотрим, при каких условиях ранг x возрастает.

Ранг xпосле слияния увеличивается на 1

Слияние двух деревьев всегда происходит за счет подвязывания корня меньшего дерева к корню большего. Это означает, что ранг любого элемента x, принадлежащего дереву T1, после слияния с деревом T2всегда увеличивается на 1, при этом |T2| ≥ |T1|. В результате слияния получим дерево с мощностью |T2| + |T1|.

В крайнем случае, когда |T2| = |T1|, мощность результирующего дерева после слияния увеличится вдвое. Другими словами, ранг xувеличивается на 1, когда количество элементов дерева растет не более чем вдвое. А это значит, что ранг x не превышает log(N).

Сжатие путей

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

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

Сжатие путей

Код connectedи unionостается прежним. В реализации root мы добавляем всего одну строчку.

    private int root(int p) {
        while (p != nodes[p]) {
            nodes[p] = nodes[nodes[p]];
            p = nodes[p];
        }
        return p;
    }

Обратите внимание на строчку 3: мы поднимаем узел на уровень выше на каждой итерации цикла.

Финальная оценка сложности

Сложность операции unionпосле применения сжатия путей ограничивается функцией итерированного логарифма — O(log*(N)).

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

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

nlog*(n)
(—∞, 1]0
(1, 2]1
(2, 4]2
(4, 16]3
(16, 65536]4
(65536, 265536]5

Это означает, что для объема данных, встречающегося на практике, операция unionвыполняется за константное время, и это было достигнуто всего одной строчкой кода!

Подытожим сложности всех операций для каждого алгоритма:

initializationunionconnected
Quick-findNN1
Quick-unionNNN
Weighted QUNlog(N)log(N)
Weighted QU + path compressionNlog*(N)log*(N)

Применение

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

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

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

Сколько надо добавить медных опилок в ящик с песком, чтобы смесь начала проводить ток?

Смоделируем задачу в 2D для простоты вычислений и реализации:

  1. Представим материал в виде решетки N на N.
  2. Каждая ячейка может быть открыта с вероятностью pили закрыта с вероятностью 1 − p. Ток, соответственно, может проходить только через открытые ячейки.
  3. Протекание возникает тогда и только тогда, когда верх и низ решетки соединены открытыми ячейками.

Закрытые ячейки помечены черным цветом, открытые — белым, ток — синим

Обозначим открытую ячейку s0, а закрытую — s3. Тогда соотношение открытых ячеек к закрытым и есть вероятность p = s0 / s3.

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

Очевидно, что при p = 1ток будет протекать с вероятностью 100%, а при p = 0 — не будет. Однако нам необходимо определить более точное значение p, при котором решетка начинает проводить ток.

Самое интересное, что данная задача не решается математически. Определить приблизительное значение p, при котором ток будет просачиваться с вероятностью p* > 1/2, можно лишь эмпирическим путем.

Число pтакже называют порогом протекания, минимальной концентрацией элементов перколяционного кластера (в нашем случае — s0), при которой возникает протекание.

При каком pрешетка начнет проводить ток

На рисунке показано, что вероятности p = 0,4недостаточно для возникновения перколяции, а при p = 0,7можно уверенно сказать, что ток будет протекать через решетку. Сомнения возникают при p = 0,6, когда не всегда можно дать положительный ответ.

Реализация Percolation

Рассмотрим, как можно представить нашу задачу в виде системы непересекающихся множеств:

  1. Решетку N на N можно представить в виде массива размерности .
  2. Обозначим закрытую ячейку как 0, а открытую — 1. Изначально все ячейки закрыты.
  3. Последовательно открываем случайные ячейки.
  4. Если соседняя ячейка (сверху, снизу, справа или слева) также открыта, выполняем операцию union с каждой из них.
  5. Повторяем шаги 3–4,пока любая верхняя ячейка не будет связана с любой нижней. Проверка осуществляется с помощью знакомой нам операции connected.

Представление решетки N на N в виде массива элементов

Как видите, алгоритм предельно прост, однако шаг 5-йдостаточно ресурсоемкий. Нам придется выполнять connectedпоследовательно для каждой верхней ячейки с каждой нижней, то есть сложность этих вычислений составит O(N²).

Чтобы упростить последний шаг, можно пойти на небольшую хитрость. Мы введем 2 виртуальных элемента, pTopи pBottom, и свяжем их с верхней и нижней строкой соответственно. Тогда на 5-мшаге мы будем просто проверять connected(pTop, pBottom).

Виртуальные элементы pTopи pBottom

Вычисление порога протекания

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

Традиционно для изучения случайных процессов воспользуемся методом Монте-Карло:

  1. Инициализируем решетку N на N закрытыми ячейками.
  2. Выбираем случайную ячейку и открываем ее.
  3. Повторяем шаг 2-й,пока решетка не будет в состоянии перколяции.
  4. Вычисляем порог протекания как отношение открытых ячеек к закрытым: p = s3 / s0.
  5. Повторяем шаги 1–4-й T раз.

Точность результата зависит от размера решетки Nи количества экспериментов T. В конце значения порогов усредняются и вычисляется среднеквадратичное отклонение. Пусть, xt — значение порога протекания в эксперименте t, тогда среднее значение xи среднеквадратичное отклонение определяются так:

В результате получаем заветное число — 0,593. Это означает, что концентрация медных опилок в ящике с песком должна превышать 50%, чтобы смесь была токопроводящей.

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

Выводы

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

Верхняя граница сложности O(f(N))отвечает на вопрос, с какой скоростью растет число операций алгоритма при увеличении N. То есть, к примеру, если мы удвоим количество элементов в алгоритме Quick-find, то объем работы для операции unionтакже удвоится.

Позднее мы доказали, что сложность unionможно свести к O(log*(N)), а это означает, что при любых объемах данных, применяемых на практике, операция unionбудет выполняться одинаковое время.

Безусловно, для важных научных исследований можно воспользоваться мощностью суперкомпьютера, производительность которого измеряется экзафлопсами (1012). Однако, если посчитать, это всего на 6 порядков выше производительности домашнего ПК (1018). Когда мы имеем дело с алгоритмом квадратичной сложности, суперкомпьютер обеспечит прирост объема входных данных всего в 1000 раз, чего может быть недостаточно для решения поставленной задачи за допустимое время.

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

Благодарность

Выражаю благодарность профессору Принстонского университета Роберту Седжвику и доктору технических наук Кевину Уэйну за составление исчерпывающего курсапо алгоритмам «Algorithms, Part I, II» на сайте coursera.org. Также в свободном доступе можно найти их книгу Algorithms, 4th Edition.

Источники

  1. Sedgewick, Robert; Wayne, Kevin (2011). Algorithms. 4th ed. Addison-Wesley Professional. ISBN 978-0-321-57351-3.
  2. Sedgewick, Robert (2012). Union Find. Coursera.
  3. Disjoint-set data structure (2019) in Wikipedia: The Free Encyclopedia, Wikimedia Foundation Inc.

Станут ли микросервисы архитектурой будущего

$
0
0

Меня зовут Михаил Бродский, я Lead Software Engineer, Consultant в GlobalLogic (Харьков). В сфере IT уже более 7 лет. Занимался проектированием, разработкой информационных систем и их внедрением. Сейчас возглавляю проект, связанный с сетевой безопасностью. Занимаюсь повышением эффективности процесса разработки с помощью виртуализации, разработкой и анализом архитектурных решений, а также реализацией программной функциональности.

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

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

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

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

Микросервисы

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

Высокоуровневая схема микросервисной архитектуры

Почему мы использовали именно микросервисы?

В первую очередь из-за повышения скорости работы модели. При разделении монолитной системы на независимые элементы такую систему становится легче разрабатывать, ее можно «расскейлить», распараллелить: несколько команд смогут работать над разными микросервисами, при этом каждый микросервис будет иметь свой pipeline, continuous integration, continuous delivery. Таким образом, скорость работы системы повышается.

Безопасность и стабильность. После распределения модели на несколько микросервисов появляются некоторые дополнительные возможности. Например, представим себе скоростной суперкар. Что произойдет, если мы не будем контролировать его скорость? Он разобьется. Если мы имеем дело с «умной» машиной, ее датчики и контроллеры помогут нам отследить скорость, контролировать ее, управлять транспортным средством. Это позволяет повысить безопасность работы.

Это же относится и к работе с микросервисами: мы можем применять некоторые паттерны стабильности. Например, паттерн Timeout: если один из микросервисов не отвечает, мы можем быстро отключиться по тайм-ауту, показав пользователю, что этот сервис недоступен. Можно также применить паттерн Circuit Breaker («Предохранитель») — здесь уместна аналогия с домашней сетью электроприборов: при резком скачке напряжения барьер, контролирующий сетевое напряжение, отключает систему на некоторое время и после тайм-аута проверяет, вернулось ли напряжение в норму, можем ли мы подключить устройства к сети. Если нет, после определенного периода покоя проверка выполняется снова. Также возможно применение паттерна переборок. При распределении монолита между несколькими микросервисами становится возможным независимое применение таких паттернов.

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

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

Три основные группы микросервисов

Существует три основные группы микросервисов:

  • Stateless — сервисы без сохранения состояния.
  • Persistence — сервисы, которые сохраняют свое состояние.
  • Aggregators — агрегаторы.

Stateless

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

Persistence

Другой тип микросервисов — сохраняющие свое состояние. К ним относятся сервисы, которые сохраняют зависимость от storage, у них есть операции записи/чтения, их точно так же легко масштабировать, если есть зависимость от диска, если разделены операции, применив паттерн CQRS. В двух словах: у нас есть запрос на чтение и запрос на запись. Мы можем распределить эти модели — за каждую модель будет отвечать определенный микросервис. Таким образом, мы можем масштабировать такую модель на независимые микросервисы. В первую очередь при этом мы зависим от других сервисов. Если взять Amazon или Netflix, один сервис вызывает огромное количество других сервисов. Кроме зависимости от других сервисов, есть зависимость от сети. Появляется запись в базу данных и, конечно же, Disk I/O Dependence.

Aggregators

Рассмотрим пример архитектуры, которую мы применяли для реализации группы паттерна микросервиса «Агрегатор».

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

Изначально наша архитектура выглядела так:

Микросервис-агрегатор с блокирующим (синхронным) запросом

Было устройство — брандмауэр, использовался микросервис, ответственный за сбор телеметрии (Device Data Collector MS), микросервис, ответственный за обработку полученной информации (Device Data Processor), а также микросервис, ответственный за генерацию уведомлений (Alert Generator).

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

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

Изначально мы должны были поддерживать 5000 устройств. Каждые 5 минут — не очень часто — каждое из этих устройств отправляло какую-то информацию о своей работе, и это составляло 17 запросов в секунду (тоже не очень много). За два часа работы собиралось 35 мегабайт, эту информацию мы сохраняли в базу данных, хранили ее 2 часа, и, если что-то произошло, запускалось задание, анализировалась информация, вызывался следующий микросервис, генерирующий уведомление, которое отображалось на доске уведомлений.

Все было отлично, пока не поменялись требования. Вместо 5000 устройств от нас потребовалось подключение 50 000. И тут мы поняли, что возникнут проблемы. Собрали все метрики, проанализировали информацию — проблема заключалась в том, что устройство блокировалось на время обработки всей цепочки сообщения. Как можно было решить эту проблему?

Микросервис-агрегатор с асинхронным ответом

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

И тут возникает несколько вопросов.

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

  • Заблокировать отправителя до того момента, пока не будет обработано сообщение.
  • Блокировать очередь либо при увеличении сохранять ее часть на жесткий диск.
  • Применить метод контролирования обратного потока (используется в TCP-протоколе): создается буфер складирования сообщений, при переполнении которого поступление сообщений блокируется.

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

Третий.Что произойдет, если Device Data Processor не сможет выбирать сообщения (как мы описывали ранее)? А что, если устройству будет необходим результат обработки сообщения?

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

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

Системы обработки сообщений

Рассмотрим основные понятия.

Message

Первое — сообщение. Можно провести аналогию: HTTP-запрос.

Message Broker & Message Queue

«Посредники» — брокер сообщений или очередь. К ним относятся TIBCO Enterprise Message Service, WebSphere, webMethods, RabbitMQ, ActiveMQ, HornetQ, NATS, Apache Kafka. Это нечто среднее между RPS и реляционной базой данных. Другими словами, это базы данных, адаптированные исключительно для работы с очередью.
Приведу несколько различий между этими двумя подходами.

Direct Communication

TCP, one-to-one

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

UDP, ZeroMQ (over TCP), Webhooks (HTTP Callbacks)

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

Message Brokers

JMS, AMQP, RabbitMQ, ActiveMQ, HornetQ, Qpid, TIBCO Enterprise Message Service, IBM MQ, Azure Service Bus, Google Cloud Pub/Sub, SQS — их особенность в том, что при необходимости сообщить подписчику о нештатной ситуации (например, сообщение не было обработано, доставлено) используются посредники. Далее я расскажу, чем отличается Kafka от остальных существующих подходов.

Logs-Based Message Brokers

Посредники, работающие на основании логов.

HTTP Callbacks with Payload

Схема паттерна HTTP Callbacks with Payload

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

Logs-Based Message Storage

Рассмотрим системы отправки сообщений на основании логов. К ним относятся Kafka, Distribute Logs от Twitter и реализация от Azure.

Схема работы систем сообщений на основе логов

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

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

Итак, у нас имеются очереди, добавляются продюсеры и потребители (Consumers). Когда какой-то из потребителей считывает сообщение, присваивается сдвиг (Offset): сколько сообщений было прочитано и какое сообщение было прочитано. Допустим, если мы прочитали определенное количество сообщений в разделе 0, мы записываем, чему равен сдвиг для этого раздела (например, 6):

Offset for P0 = 6

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

Объем релиза

В теории графов существует интересная формула, которая подсчитывает оптимальное число изменений в релизе: n — количество изменений (количество ребер в графе; соединения между ребрами — это изменения, зависимости) (рисунок 6). Политика Netflix — минимизировать число изменений, повысив частоту релизов. Если вы включаете в релиз большое число изменений, растет число дефектов, которые необходимо будет обнаружить и исправить. Например, при числе изменений n = 5 мы получаем 10 зависимостей. Минимизируя число изменений, мы уменьшаем число дефектов в системе.

Расчет оптимального релиз-скоупа

Выводы

В итоге на базе микросервисов мы создали асинхронный компонент, основная задача которого — сбор телеметрии от IoT-девайсов и создание необходимых оповещений (алертов) для уведомления пользователя. Каждые 2 часа мы получаем и сохраняем до 400 мегабайт информации.

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

  • получили практику предварительной оценки и разработки прототипов микросервисов;
  • с нуля создали асинхронный компонент, который позволил оптимизировать работу всей системы для большего количества подключенных устройств (до 50 000 устройств в одном регионе).
Что дальше? Мы смотрим в будущее с оптимизмом: переход от монолитной системы к микросервисам не только даст бизнесу и пользователям лучший user experience, но и позволит создавать целый набор различных сервисов, которые облегчат работу и жизнь.

Сейчас перед нами стоит задача поддержки и развития этого компонента, впереди еще много работы!

Хотите узнать больше или есть вопросы? Пишите в комментарии, в LinkedInи подписывайтесь на YouTube-канал.

Як у SoftServe втілили концепцію Mixed Reality, у якій віртуальні об’єкти можна відчути на дотик

$
0
0

У рубриці DOU Labsми запрошуємо IT-компанї ділитись досвідом власних цікавих розробок та внутрішніх технологічних ініціатив.

Привіт, я Тед Романус, Research Engineer у SoftServe в напрямку Human-сomputer interactions (HCI). Наша група в R&D працює над новими технологіями, що змінюють взаємодію людини з цифровими медіа — від віртуальної (Virtual) і доданої (Augmented) реальності до ефектів дотику (Haptics) та взаємодії через мову тіла й емоції (Affective computing).

Сьогодні я розповім про наш проект Touch My Heart — першу у світі голограму, якої можна торкнутися, яку можна штовхнути і яка передає такі легкі модуляції як серцебиття людини. Це демо, яке ми вже презентували на кількох найбільших HCI-конференціях у Великій Британії, США, Японії, Іспанії та Китаї, відкриває нові можливості природнішої й інтимнішої взаємодії з віртуальними об’єктами та дозволяє вже тепер почуватися героєм Blade Runner.

Виставка IoT World Expo 2018 в Барселоні

У цьому проекті ми поєднали:

  • AR-голограму, яку можна побачити через окуляри Magic Leap;
  • ефект дотику через ультразвукові хвилі (Ultrahaptics);
  • трекінг рук сенсором Leap Motion;
  • біосенсори.

Як наслідок, ми зреалізували концепцію Mixed Reality, у якій віртуальні об’єкти зливаються з реальним світом.

Ідея

Усе почалося з нашого знайомства з технологією Ultrahaptics, яка передає ультразвуковий імпульс у певну точку простору, що створює відчуття, схоже на фізичний дотик. Микола Максименко, R&D Director у SoftServe, давно знайомий з Орестісом Георгіу, Research Director в Ultrahaptics, і кілька разів запрошував його в Україну на конференцію IT Weekend Ukraine та виступити в Українському католицькому університеті. Орестіс Георгіу погодився на наше запрошення.

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

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

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

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

Робота над проектом

Спочатку розробляв проект (писав код, тестував) під окуляри Meta я, консультуючись з іншими R&D-фахівцями. У схожих дослідницьких проектах немає чіткого розуміння, чи вийде зреалізувати задумане, тож ми поступово розв’язували окремі технічні проблеми й розширювали кейс.

До окремих завдань долучались інші інженери. Наприклад, адаптували технологію до інших AR-окулярів або поліпшували 3D-модель R&D-інженер і дизайнер з нашої команди.

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

У комплекті з пристроєм Ultrahaptics іде SDK для розробки під Windows/Mac. Використовуючи його, ми змогли вивести анімацію серця на екран комп’ютера й створити відчуття дотику в просторі, тобто людина могла фізично відчувати те, що бачить на екрані комп’ютера.

Ми пішли далі й додатково використали окуляри Magic Leap, до яких розробили віртуальну модель серця (таку саму, яка відображається на екрані комп’ютера). Щоб користувач міг бачити серце через Magic Leap і одночасно торкатися його через ультразвукові хвилі, згенеровані Ultrahaptics, треба було поєднати системи координат цих двох пристроїв.
Це вже був значний крок уперед у використанні технології Haptic Feedback — доповнену реальність тепер можна було відчути фізично.

Ми вирішили не зупинятися й поставили собі наступну мету — зробити так, щоб серце здавалося живим. Для цього треба було створити коливання інтенсивності імпульсів, що передаються на шкіру. За основу взяли STM_Circle (один зі скриптів, які йдуть разом з Ultrahaptics SDK). Саме відчуття складається з точок, які бігають по колу радіусом 3 см з частотою 100 Гц (зважаючи на затримку опрацювання сигналів людським мозком, воно сприймається як ціле коло). Щоб одержати відчуття серцебиття на базі цього статичного відчуття, ми запропонували два підходи:

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

Насамкінець для яскравішої демонстрації ми взяли не якісь статичні дані, а відтворили ритм серцебиття реальної людини. Для цього я використав Apple Watch, підходить також годинник українського бренду MAWI, який дозволяє не лише міряти пульс (PPG), а й знімати кардіограму (ECG). Дослідженняпоказують, що Apple Watch вимірює пульс найточніше з усіх доступних на ринку фітнес-трекерів. MAWI практично міряє кардіограму, у якій значно більше даних, ніж у PPG (дослідження). Використовуючи такий метод, пульс визначаємо якнайточніше (саме з цим методом порівнюють усі інші).

Схема застосунку

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

  • OpenCV вибрали саме тому, що на всіх нових платформах популярні image tracking фреймворки не мають імплементації, і ми не маємо доступу до параметрів камер. А в OpenCV є методи, з якими можна провести 3D-реконструкцію (тобто розпізнати прості патерни в 3D) на будь-яких камерах. Недавно в Magic Leap SDK додали свою імплементацію розпізнавання зображень, і ми переписали все на неї.
  • Ultrahaptics plugin, Leap motion plugin, Lumin SDK для інтеграції окулярів Magic Leap в Unity3D — потрібні речі для роботи, які не мають аналогів.
  • http-сервер для передачі даних про серцебиття — простий і кросплатформний спосіб для передачі інформації.

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

Ми поділилися результатом з Орестісом і виявилося, що таких рішень у світі ще немає, окрім відеоконцепту Ultrahaptics і дизайн-студії Nike. Тож уже разом з Ultrahaptics ми написали кілька матеріалів для конференцій з human-computer interaction.

З технічного погляду цей проект — насправді 3 окремі програми (для ноутбука, для Magic Leap, для Apple Watch), які треба запустити й протестувати. Бібліотеки, які ми використовували, мали досить скромну документацію, на StackOverflow узагалі порожньо (останнім часом для Magic Leap ця ситуація виправилася, для Ultrahaptics досі нічого загуглити не вийде). Щоб правильно засинкати всі системи координат, перетворення тощо, треба було ще розібратись у лінійній алгебрі й математиці 3D-перетворень, що теж забрало багато часу.

Перспективи

Перші версії демо Touch My Heart ми показували на маркетингових стендах, щоб побачити реакцію людей і, відповідно, удосконалити проект. Люди дуже емоційно реагують на такий новий спосіб взаємодії, найчастіше, це емоції захоплення й здивування. Цього року ми презентували його на кількох спеціалізованих міжнародних конференціях з Human-Computer Interaction, зокрема на CHI2019 у Ґлазґо й World Haptics Conference в Токіо, де дістали позитивний фідбек щодо новизни нашої ідеї та реалізації. Зокрема, наше демо в Японії помітив навіть засновник Magic Leap Роні Абовіц, а на Augmented World Expo ми потрапили до фіналу Auggie Awards в номінації Best Interactive Software.

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

Загалом ця технологія має потенціал для практичного застосування в таких напрямках:

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

Путешествие на планету Java. Мой опыт прохождения cертификации Java 11 Developer (часть 2)

$
0
0

Меня зовут Евгений Бережной, я — Java Developer в AB Sof, и речь в этой статье пойдёт о втором экзамене Java 11 Programmer II (1Z0-816). О первом экзамене и в целом о Professional: Java 11 Developer certificationчитайте первую часть. Второй экзамен существенно отличается от первого, но хочу вас порадовать: как по мне, в лучшую сторону.

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

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

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

Иллюстрации: Дмитрий Яценко

Чтобы получить сертификат, нужно сдать оба экзамена. К сдаче Java 11 Programmer II (1Z0-816) я советую подходить после сдачи Java 11 Programmer I (1Z0-815), хотя экзаменаторы этого не требуют и сдавать экзамены можно в любом порядке.

Если вы являетесь обладателем титула OCP 6...8, то вам надо сдать только один экзамен — Upgrade OCP Java 6, 7 & 8 to Java SE 11 Developer 1Z0-817, который очень похож на Java 11 Programmer II (1Z0-816) по затронутым в нем темам, поэтому информация вам тоже будет полезна.

Кстати, конкретно по этому экзамену коллега из дружественной Беларуси написал очень неплохой Study Guide.

Если же вы являетесь обладателем титула OCA 7, 8 то сдавать экзамен Java 11 Programmer I (1Z0-815) вам не надо, можете сразу покорять Java 11 Programmer II (1Z0-816).

Хорошая новость: у вас есть право на одну бесплатную пересдачу каждого экзамена. Детальнее об этом можно прочесть тут.

Темы экзамена

Java 11 Programmer II (1Z0-816) основан на старом экзамене OCP 8 (1Z0-809), список тем и сравнительная таблица приведены здесь.

Для подготовки я советую использовать книгу «OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide: Exam 1Z0-809» Boyarksy/Selikoffлибо «OCP Java SE 8 Programmer II Exam Guide (Exam 1Z0-809)» Sierra/Bates, в них детально описаны темы, которые перекочевали из OCP 8. В этой же статье я подробно расскажу о новшествах Java 9...11 и темах, которых раньше не было на экзамене.

Прошу обратить внимание, что некоторые темы из книг не будут подниматься на экзамене, но все равно пригодятся в повседневной работе. К примеру, вопросов по Fork/Join Framework и паттернам проектирования на экзамене уже нет.

Итак, начнем наш обзор новинок :)

Модульность

Модули — наше все! Разделяй и властвуй! Под этим девизом Oracle усиленно продвигает нововведение. Вопросов о модулях будет порядка 10, и, в отличие от первой части, эти вопросы будут практического характера.

Вас спросят, правильно ли написан module-info.java, включая корректное использование Service Provider Interface (SPI), который с появлением модульности обрел вторую жизнь. Зададут вопрос, правильно ли сделаны импорты и экспорты, должен ли быть хоть один провайдер сервиса во время компиляции и выполнения, а также массу других вопросов, узнать ответы на которые вам поможет только практика.

Поэтому я рекомендую взять книгу Шилданачиная с десятого издания, где приведены емкие примеры с пояснениями (всего 25 страниц). Освоив их на практике, вы получите ответы на 90% вопросов о модульности. Но помните: главное — «запачкать свои руки», а не просто полистать книгу.

Если есть желание окунуться в модульность с головой, советую книгу «Java 9 Modularity Book». В ней есть отличные примеры практического использования и стратегии миграции.

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

Вопросов о jmodи jlinkна экзамене не было.

Сериализация и безопасность

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

  • что надо сделать в коде, чтобы он считался безопасным;
  • когда нужно делать deep copy объекта для мутабельных классов;
  • когда надо делать copy constructor.
Кроме обязательного чтения нудных и сухих руководств Secure Coding Guidelinesи Chapters 1, 2, and 3 of Serialization Specification, рекомендую почитать горячо любимую мною «Effective Java»Джошуа Блоха. Там есть один раздел, посвященный сериализации, где рассматриваются вопросы безопасности.

Аннотации

Аннотация — одна из старых возможностей Java, которой раньше не было на экзамене, но без которой трудно представить современную разработку. На экзамене от вас потребуется знание базовых встроенных аннотаций, таких как @SuppressWarnings и @SafeVarargs, будут вопросы и по аннотациям @Repeatable.

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

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

JDBC

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

Интерфейсы

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

Эти методы подчиняются правилам, аналогичным для приватных методов класса:

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

Темы, перекочевавшие из OCP 8, и в целом о подготовке

Выберите одну из книг: Boyarksy/Selikoffлибо Sierra/Bates. Переключаться между ними не стоит. Возьмите себе за правило каждую неделю читать главу и проходить один мок-экзамен в конце главы. В результате через 2 с половиной месяца вы будете готовы по перекочевавшим из OCP 8 темам (IO, NIO 2.0, Concurrency и т. д.). Подготовиться по новым темам вам помогут советы из этой статьи.

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

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

Особое внимание стоит уделить Stream API и лямбдам. На экзамене их будет очень много. Выучите наизусть методы, аргументы и возвращаемые значения базовых функциональных интерфейсов (Consumer, Supplier, Function, Predicate, UnaryOperator). Обязательно нужно понимать, как получаются производные интерфейсы. Также вы должны знать, как написать собственный функциональный интерфейс.

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

public class TestClass{
    public static int operate(IntUnaryOperator iuo){
        return iuo.applyAsInt(5);
    }
    public static void main(String[] args) {  
        IntFunction<IntUnaryOperator> fo = a->b->a-b; 
        int x = operate(fo.apply(20)); //2
        System.out.println(x);
    }
}

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

IntFunction — это функциональный интерфейс, который получает intи возвращает то, к чему он типизирован. В данном случае он приведен к IntUnaryOperator. Следовательно, IntFunction<IntUnaryOperator>принимает intи возвращает IntUnaryOperator.

Теперь, если вы посмотрите на fo = a->b->a-b, то увидите, что a — это аргумент типа int (т. к. он используется, чтобы получить IntFunction), а b->a-bформируют тело метода этого IntFunction, которое вернет IntUnaryOperator.

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

То есть, когда вы вызываете fo.apply(20), вы устанавливаете a=20. Отсюда b->a-bвозвращает как IntUnaryFunction iuoравной b->20-b.

Затем вы вызываете iuo.applyAsInt(5), в которой значение bустанавливается равным 5, и в результате возвращается 20-5, т. е. 15.

Со стримами также очень много громоздких конструкций. Хорошо разберитесь с использованием методов groupingByи particioningBy, merge. Попрактикуйтесь, научитесь пользоваться ссылками на метод.

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

Если после выполнения всех рекомендаций у вас останутся сомнения в собственных силах, попробуйте мок-тесты Enthuware, посмотрите форум о сертификации на CodeRanch.

Итог

Как я ранее писал, экзамен длится 3 часа. Всего 80 вопросов, времени вполне хватает. Проходной балл — 63%.

Результаты экзамена придут в течение 15 минут на вашу почту.

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

Электронный бейдж

При желании можно заказать бумажную копию, которая придет через 2-3недели по почте. Лично я не стал убивать еще одно дерево, думаю, в современном мире это будет лишним.

Так выглядит сертификат

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

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

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

Да пребудет с вами сила! Удачи!

Security Sandwich: инструкция по приготовлению

$
0
0

Привет! Меня зовут Таня, и я все еще тестировщик. За то время, что мы с вами не виделись, я успела основать митап QA Amsterdam и дать интервью о том, как докатилась до такой жизни. А сегодня я хочу рассказать о Security Sandwich.

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

Что же представляет из себя классический бутерброд безопасности

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

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

Go-Live-стадия, включающая код ревью и тестирование на проникновение.

Начальная стадия: все хотят от чего-то защититься. Но от чего?

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

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

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

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

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

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

Например, пару месяцев назад они отправляли e-mail в стиле «Привет! Сижу на совещании, не могу говорить, срочно пришли такую-то информацию. Рудольф». Отправлено с айфона.

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

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

Итак, что у нас должно быть результатом работы на первом этапе

Цели безопасности: определен круг запросов от бизнеса, юристов и регулятивный контекст (какие законы должны соблюдаться и пр.).

Сценарий«А что, если?..»: что произойдет, если наши поставленные цели будут нарушены?

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

Разработка: когда же «происходит» безопасность

Традиционно путь к продакшену включает:

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

На этапе анализамы устанавливаем Definitions of Ready.

Для этого нам нужно:

  • проанализировать имеющиеся активы: что именно мы затронем изменениями, какие новые компоненты будут в этом затрагивании участвовать, насколько критично то, что у нас сейчас есть и как все это вместе повлияет на текущую ситуацию;
  • смоделировать угрозы. Эта часть самая интересная. Она базово включает в себя вопросы о том, как мы можем быть взломаны и что будет при этом задето. Но моделирование угроз само по себе — один из моих любимых этапов. Модели бывают простые и известные типа STRIDE, а есть прикольные и замысловатые типа Persona non Grata. Я очень хочу с этой темой выступить на следующем митапе, но перед этим потренироваться. Если вы хотите присоединиться и послушать про моделирование угроз, то приходите на вебинар 27 ноября, в 20.00 (по Киеву) . N. B. Материал будет читаться на английском языке!
  • предусмотреть действия при взломах. Смягчить? Перенаправить? Избежать? Или принять?
  • предусмотреть обратную связь. Как мы защищались? Как отвечали на взлом? Как восстанавливалась система? Какие у нас могли бы быть альтернативы?

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

На этапе разработкимы облегчаем себе жизнь с помощью автоматизации, а также:

  • обращаем внимание на зависимости: действуем на упреждение, поддерживаем их в актуальном состоянии и активно тестируем;
  • используем CVE (Common Vulnerabilities and Exposures): списки с уязвимостями постоянно пополняются, и это можно и нужно использовать. Автоматическая настройка сканеров для библиотек и фреймворков никогда не повредит;
  • контейнеры: как ни странно, контейнеризация — это не панацея от всех бед. В них тоже есть уязвимости, и хорошо бы настроить и для них автоматическое сканирование.

Go-Live: знай свою систему!

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

  1. Визуализируем текущее состояние системы. Это всяческие метрики и статистика в реальном времени, по одному взгляду на которые можно сделать вывод, хорошо ли все идет. Например, у нас в компании в комнате каждой команды установлены большие мониторы (а у менеджеров их и вовсе по несколько штук), на которые выведены дашборды с метриками системы. В любой момент каждый член команды может достоверно сказать, все ли идет как надо. Для этого достаточно поднять голову и посмотреть на монитор на стене.
  2. Делаем структурированные и понятные логи. Хорошим тоном тут считается не засовывать логи в стринги, а логировать нормальные, индексируемые данные. В идеале система логирования должна быть легко инспектируемой и коррелировать со всей системой.
  3. Определяем нормальное и не очень поведение. Мы должны уметь быстро фиксировать, что что-то пошло не так, и иметь стандартную процедуру поведения в таких ситуациях. Например, у нас один раз «кое-что» случилось. Это «кое-что» быстро устранили, но нервов потрепали немало, потому что, во-первых, «кое-что» случилось около полуночи, а во-вторых, процедуры на случай «кое-что» не было. Поэтому действовали по наитию и достаточно хаотично. После устранения «кое-что» провели работу над ошибками и сделали строго определенный регламент поведения на случай повторения, который разослали всем работникам компании: кому звонить первому, кому второму, по каким телефонам, каких клиентов и каким образом информировать и так далее.
  4. Применяем методологию безопасности Shift Left. Эта (и схожая с ней Shift Right) методология набирает все больше популярности, и вот она доползла до безопасности. Суть ее проста: если мы представим процесс разработки как прямую с планированием в точке ноль и выпуском готового функционала в крайней правой точке, то Shift Left — это сдвиг влево. То есть начинаем делать что-то как можно раньше. Так теперь и с безопасностью: раньше начнешь — меньше потеряешь. Поэтому стоит следить за Security Debt, внедрять коллективную ответственность за дыры безопасности в коде и прочие приятные штуки.

В качестве заключения

Security Sandwich кажется простой и незамысловатой вещью, тем не менее в процессе постоянно что-то теряется.

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

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

Ну а убрав середину (анализ, разработка, тестирование), получим не сэндвич, а вообще какое-то хлебное недоразумение.

Готовьте ваш Security Sandwich правильно.

И приятного аппетита!

DevOps дайджест #27: Docker Enterprise, Helm 3.0, ClusterAPI и дайте свой email

$
0
0

В выпуске: скандалы-интриги-расследования о Docker Enterprise, почему лучше не использовать очереди в PostgreSQL, как получить первый опыт работы с клаудами, почему у Gitlab скоро будет больше вакансий, как быстро запустить что угодно на Google Cloud Run, посмотреть доклад Envoy as TCP Proxy и много-много интересностей.

Docker Enterpsise теперь Mirantis

Что случилось с Docker Enterprise?

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

Mirantis Acquires Docker Enterprise Platform Business

Docker new direction

Docker’s Next Chapter: Advancing Developer Workflows for Modern Apps

В двух словах:

  • Mirantis купил Docker Enterprise, для того чтобы развивать свой Kubernetes-as-a-Service. Даже учитывая то, что треть компаний из Fortune 100 использовала Docker Enterprise, — он был не особо прибыльным.
  • Docker Inc. продала Docker Enterprise и сразу получила $35 Million инвестиций для рекапитализации и усиления своей финансовой позиции.
  • Docker’s Next Chapter: они сфокусируются на улучшении взаимодействия с программистами, будут строить новые процессы и улучшения в области сборки контейнеров, их дистрибуции и запуска.
  • У Docker Inc. теперь новый СЕО.

Мнения и интересности

Сказ о PostgreSQL и сложности инфраструктуры
Новая статья в блоге Всеволода Полякова о том, как не нужно решать инженерные задачи на примере «просто решения» с очередями в PostgreSQL. Какие проблемы после этого появляются? Можно ли использовать PostgreSQL как message queue? Ответы в статье.

Modern applications at AWS
CTO из Amazon делится своим подходом и виденьем о том, как делать приложения. Интересные моменты, которые я заметил: one DB per microservice и безопасность — it’s not SecOps job, it’s everyone’s job. В статье есть чему поучиться, рекомендую к прочтению.

Stop Bashing Bash — Pattern for Sharing Bash
Признавайтесь, что вы тоже пишете bash-скрипты. И да, их достаточно много, и большая часть из них — это ужас. Эта библиотека — попытка вынести общие проблемы всех bash developers в общую библиотеку. Сейчас пока что функций маловато: покрыт Git, Kubernetes, тестирование скриптов и еще по мелочи. Думаю, в будущем туда добавят побольше удобностей, и можно будет инклудить в каждую тулу. Обратите внимание на Bash Links в статье — там перечислены классные мануалы, на них опирались создатели библиотеки.

В Netflix по пятницам принято не деплоить

Deploy on Fridays, or Don’t.
Если вы деплоите по пятницам — почитайте. А если не деплоите — тоже почитайте. Мое мнение: деплой в пятницу — это норма. Автоматизированный, покрытый тестами, предсказуемый деплой. Обычный, который вы запускаете три раза каждый день, к которому вы привыкли. Деплой, который меняет схему самой большой таблички в БД, деплой с фичей, которая разрабатывалась параллельно с проектом пару месяцев, миграция стореджа или какие-то большие изменения — не норм. Потому что при таком подходе выходных не будет, результат — овертайм, выгорание, смена компании. Зачем?

How do you get cloud experience?
В основном работаете с bare metal и очень хочется пощупать Cloud? Или постоянно работаете с AWS, но очень интересно посмотреть, как оно там в Google Cloud или Azure? Вы не одни такие. В этой теме на Reddit автору дают советы о том, как получить этот самый опыт с Cloud. Конечно же, основной совет — бери и пробуй :) Но есть еще много советов, например: где можно взять Free Cloud credits, какие есть Education предложения у Cloud провайдеров.

GitLab hiring ban by Country
GitLab рассматривает вопрос о прекращении найма SRE и Support инженеров в России и Китае. Аргументируют обеспокоенностью некоторых Enterprise клиентов и геополитическим климатом. HackerNews сообщество отреагировалоочень по-разному. Если вы SRE из других стран — посмотрите вакансии Gitlab, думаю, в скорости их может стать больше.

The (real) 11 reasons I don’t hire you
Что делать с этими причинами: вывернуть наоборот, обработать и сделать так, чтобы наняли.

kube-proxy iptables «nat» control flow
Tim Hockinиз Google cделал шпаргалку по kube-proxy iptables nat таблице, когда kube-proxy работает в iptables режиме. Хардкор!

New from Universe 2019: GitHub
Недавно прошел Github Universe, на котором объявили о создании мобильного приложения, возможности архивации open-source проектов на 1000 лет (лол), секьюрити фичи. Больше можно прочитать здесь.

The SSO Wall of Shame: выбираем провайдера
Список сервисов и цены, за которые они продают SSO. Местами за базовую секьюрити фичу цены отличаются до 5 раз. И сюда же сразу небольшой гайд: An Illustrated Guide to OAuth and OpenID Connectот Okta с картинками, все как вы любите.

The importance of soft skills in IT

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

Видео с конференций

Devops Enterprise Summit 2019: Keynotes
Если вы не в Los Angeles, то это не беда — видео с местного Devops Enterprise Summit можно посмотреть на YouTube. По ссылке будет плейлист с Keynotes.

Monitorama 2019: видео с конференции
Опять же, если не удалось попасть в США на Monitorama — всегда можно посмотреть видео. По ссылке — плейлист и 17 докладов.

PromCon Munich 2019: онлайн трансляция
Два дня видео с PromCon в Munich. Очень радует этот месяц обильным количеством классных доступных конференций.

YAML Is Better than Your Favorite Language: Fightin’ words about Infrastructure as code
Видео о YAML: почему он лучше всех остальных DSL для IaC, по мнению автора, и как правильно готовить, чтобы не больно было.

Руководства и инструкции

Deploy Traefik as Ingress Controller
Туториал о том, как задеплоить Traefik в качестве ingress в DO Kubernetes кластере.

Serverless Go application in Google Cloud Run

Running a serverless Go web application in Google Cloud Run
Интересный туториал о том, как легче всего запустить serverless приложение. Автор показывает пример постой Go программы, упаковывает ее в Docker и запускает в Google Cloud Run. И действительно, выглядит очень быстро и просто.

ClusterAPI — A Guide on How to Get Started
ClusterAPI — это проект для Kubernetes, который призван объединить все варианты инсталляций Kubernetes в одном API и позволять управлять ими через один интерфейс. У нас в компании за эту штуку очень топит Саша Милушев, и даже есть вакансияв его команду. Если вы хотите в Pango — лучше напишите мне в личку, чтобы мне дали бонус. А в статье рассматриваются основы ClusterAPI.

Continuously enforce policies on your configs with Conftest and CircleCI
Если вы задумывались, как делать unit-тестирование ваших Kubernetes манифестов с помощью Open Policy Agent — статья будет полезной, новой и интересной. Если вы о таком задумывались, напишите, пожалуйста, в личку — вероятно, я бы взял интервью у такого человека.

Как мониторить Amazon MQ и какие метрики собирать в Amazon MQ
Две очень хорошие комплексные статьи о том, как правильно мониторить и какие метрики собирать в Amazon MQ. Datadog очень хорошо умеют делать качественные tutorials.

BLESSing away SSH worries
Netflix Bless — это SSH Certificate Authority, запущенный на AWS Lambda и его задача — подписывать SSH ключи в вашей компании. В целом это уже давно популярная практика — не переписывать authorized_keys, а настроить хост, чтобы он доверял вашей SSH CA. Резюмируя, если вы все еще патчите authorized_keys — перестаньте так делать и сделайте Netflix Bless по этому мануалу.

Обзор DevOpsStage 2019

DevOpsStage Kyiv 2019: какие доклады посмотреть

Посмотрите эти доклады сейчас, а если не сейчас, то на выходных (полезно и с пользой):

  1. Envoy as TCP proxy — конечно, это мой доклад, который я анонсировал немногим ранее. История о том, как мы решили проблему трафика между сервисами в небезопасном интернете, обзор решений + еще хайринг к нам в Pango :)
  2. Kubernetes Navigation Stories — интересно о Kubernetes в thredUP (большой онлайн-секонд с разработкой в Украине).
  3. Hacking Terraform for fun and profit — Антон Бабенко о Terraform, много хороших рекомендаций по этому докладу.
  4. Make Architects aligned with business needs — Дима Лавриненко о том, как стать архитектором (мы с ним выступали параллельно, и он в шутку порекомендовал мой трек :))
  5. Premature automatization — Сева Поляков о том, как не нужно делать автоматизацию. Я попал под конец доклада, и очень даже зашло.

Конференция HAProxyConf 2019 (Amsterdam)

12-13ноября в Амстердаме проходила HAProxyConf, где выступал один из наших соавторов. Было очень много интересных тем: GitHub, Booking.com, Vimeo делились опытом создания своих отказоустойчивых систем и какую роль в них играет HAProxy.

Анонсировали и рассказывали о HAProxy One — CDN + ADN + Firewall + WAF + красивый UI. Ребята хотят предоставлять клиентам All in One решение и потеснить... Судя по описанию фич выше, вы, думаю, сами поняли, кто конкуренты ;)

Забавный факт о докладах про Kubernetes: все production-решения пока используют HAProxy как Standalone solution, а на Ingress Controller только посматривают, пробуют.

К следующему дайджесту опубликуем ссылки на самые интересные доклады.

Наконец-то Helm 3.0

Helm 3.0.0 has been released!

И это большая, очень хорошая новость. Вот основные изменения:

  1. Removal of Tiller — его больше нет, и устанавливать его в кластер не нужно. Его функции распределили: рендерингом темплейтов занимается клиент, а релиз конфигурация и информация хранится в Kubernetes API. Tiller теперь просто не нужен.
  2. Improved Upgrade Strategy — теперь Helm понимает и видит больше изменений как в upgrade, так и в rollback. Покрыто много кейсов, в которых раньше было больно.
  3. Release Names — теперь можно делать релизы с одинаковым названием в разных неймспейсах.

Все DevOps-related идут на XP Days

XP Days Ukraine 2019 (22-23 ноября)

Я как раз вернусь с отдыха, чтобы послушать Ярослава Молочко с докладом Self-healing in prod do you really need AI for that?— уверен, будет пушка. По инсайдерской информации знаю, что будет реальный опыт, как очень просто развалить супер-хай-авейлбл-селф-хилинг Hashicorp Vault кластер в Kubernetes с Etcd бекендом (выглядит так, что это невозможно, а на самом деле — карточный домик).

И еще там будут такие известные личности как Paul Stack, Philipp Krenn, Vsevolod Poliakov, Igor Borodin, Dmytro Lavrinenko — очень хороший набор спикеров. И классное завершение осени таким звёздным составом!

Кстати, в телеграм канале ДевОпс инженересть промо на −10%, а сюда код попросили не выкладывать. Не знаю почему так, все равно кому нужно — перейдут в канал и без проблем найдут.

В этом выпуске также участвовали:

Дайте свой email

В общем, я подумал, что круто было бы сделать The DevOps Digest Monthly с email-рассылкой. Да, это прямо как DevOps Weekly, Monitoring Weekly, etc weekly, только monthly. Польза очевидна: вы точно не пропустите новый релиз Helm, не забудете обновить Grafana и абсолютно точно будете знать, что можно вкрутить Netflix Bless, и будет круто. И акцент на англоязычный сегмент. Суть — сделать worldwide дайджест, для всех DevOps Engineer’s in the whole world.

Сначала я думал сделать лендос для сбора email и вкрутить SendGrid. Прокрастинировал на этой идее пару недель и понял: нужно действовать по концепции Lean Startup.

Для этого я придумал сделать самую простую форму.

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


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


Product Marketing дайджест #1: стратегия Ahrefs, 63 совета по увеличению конверсии

$
0
0

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

Почитать

«Is your startup idea taken?» — and why we love X for Y startups. Andrew Chan рассказывает почему инвесторы любят формулировки Uber для детей и т. д.

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

How Much Do SaaS Companies Spend on Their MVPs? CXL сравнил, сколько разные компании потратили в свое время на MVP. Тратить больше не всегда лучше.

How to Make Your Customers Fall in Love with You. Основатель Sales Flare рассказывает, за счет его им удается выживать на алом рынке CRM-систем и как сделать так, чтобы пользователи любили ваш продукт.

Quora Marketing: ~1 Million Views Generated. Here’s How to Replicate Our Success. Ahrefs делится своим успешным опытом привлечения пользователей с Quora. Если вы продукт, то попробуйте этот канал. Трафик от туда часто намного дешевле, чем в FB и Google Ads.

How to Listen: A guide for marketers who want to know what their customers want. Уметь активно слушать важно не только в маркетинге, а и в обычном общении. Автор рассказывает, почему мы это делаем плохо и как это исправить.

The Detail Principle for Writing Good Blog Posts. Как писать блог-посты, чтобы их было интересно читать не только поисковым роботам, но и людям?

21 Ways to Promote Your Blog. Мы уже разобрались, как писать блог-посты. Backlinko рассказал, как сделать так, чтобы твои посты увидело как можно больше людей и при небольших затратах.

User Behavior 101: How to Track + Analyze What Drives Your Users. С помощью анализа поведения можно узнать, чего пользователи хотят, как ведут себя определенные страницы, где возникают трудности у пользователей и что больше всего их интересует. Hotjar рассказал, с чего начать и как получить инсайты.

63 Post-Click Landing Page Optimisation Techniques Proven to Generate Conversions. Instapage составил список из 63 советов, которые помогут вам увеличить конверсию.

SaaS CRO: What You’re Not Testing (But Should). В SaaS-бизнесе, если речь идет об оптимизации конверсий, то в основном говорят про эксперименты на этапе привлечения пользователей. Но все важные вещи происходит после этапа верхней воронки.

Intercom’s 6 strategies to convert customers on their website. По статистике, около 98% посетителей сайта уходит, не совершив целевого действия. Автор разбирает, как Intercom решают эту проблему у себя на сайте.

19 SaaS Marketing Strategies That Bootstrapped Ahrefs To $40m ARR. Детальный разбор маркетинговой стратегии Ahrefs, которая помогла достичь им $40m ARR.

What Is UX Copywriting?Работа маркетологов и копирайтеров заключается в том, чтобы выслушать то, что хотят пользователи, а затем их проиллюстрировать самые простые способы по достижению этой цели. В статье рассказывается, что такое UX-копирайтинг и почему он важен.

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

Послушать

Talking to Customers and Growing to $50,000 a Month with Sarah Hum of Canny. Фаундер стартапа Canny, рассказывает, почему она ушла с работы в Facebook и основала свой собственный стартап. А также почему она решила бустрапить и путешествовать по миру, а не поднимать деньги в Сан-Франциско.

Google Isn’t a Search Engine Anymore, but Your Competitor. Основатель Moz и SparkToro рассказал о своих ошибках при создании продуктов, а также какое MVP должно быть.

Сходить

CONFIDENCEconf: Product Management Conference. Первая конференция по продакт-менеджменту от организаторов Growth Marketing Stage. Спикеры из Booking, Uber, Shopify расскажут о том, как строить продукты, которые будут востребованы рынком. Для читателей дайджеста −15% по промокоду dou15.

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


Спасибо, что дочитали до конца. Увидимся в следующем выпуске!

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


← Предыдущий выпуск: Product Marketing дайджест #0

З данських теплиць до харківської IT-компанії. Історія механіка, який став програмістом

$
0
0

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

Данські теплиці і повернення додому

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

Уперше після третього курсу я поїхав до Польщі, до населеного пункту Olchowiec, але там не сподобалися умови: проживання з 64 іншими людьми в одному домі, по 16 осіб на кімнату, лише три газові плити та шість душових кабінок на всіх, що призводило до довгих черг. Та й збирати у полі лохину досить важко фізично. Наступного разу майже через рік поїхав до Швейцарії, працював у господарстві Brunner beeren неподалік Базеля. Там умови були кращими, жив лише з двома румунами, дуже смачне триразове харчування за рахунок фермера та легша праця на зборі малини (порівняно з Польщею). Повернувшись, вирішив, що знову варто кудись поїхати. Обрав Данію, місто Оденсе, за цією ж університетською програмою. Там один за одним відпрацював два контракти з фермером, тривалістю по півроку кожен.

Робота моя частково полягала в тому, щоб ремонтувати машини, мінітрактори, сівалки — власне, всю наявну в господарстві техніку. Але більшість часу я опікувався квітами, які й складали основу господарства: гвоздиками, петуніями, жоржинами та іншими. Висаджував їх, поливав, упаковував. Господар постачав квіти у кілька найбільших торгових мереж Данії, а також збував на експорт до Швеції, Німеччини та Нідерландів.

Мені працювалося легко і подобалося з кількох причин. Передусім, така праця не вимагала від мене надмірних фізичних зусиль, я не надто втомлювався. Ймовірно, ще й тому, що робочий день у Данії коротший, і за його дотриманням стежать, навіть якщо ти тимчасовий сезонний робітник. Починали працювати о 7 ранку, а о 16.00 я був уже вільний — іноді не помічав, як збігає час. Також праця гідно оплачувалася: 71 крона на годину до вирахування податків для працівника, який працює на умовах стажера, як я (приблизно 284 грн). Для порівняння: мінімальна платня, яку в Данії отримують за цей час, складає 110 крон. Мене цілком влаштовував такий заробіток, його вистачало, аби покрити поточні потреби та й поза тим забезпечити собі певну якість життя. Скажімо, з данських заробітків я придбав собі та дівчині кілька гаджетів (телефони, ноутбук), міг вихідними поїздити Європою, та ще й привіз солідну суму додому. Цей аспект подорожей мені теж подобався, як і загалом життя у незвичній для себе країні, спілкування з новими людьми.

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

Тож останніми місяцями свого перебування в Данії, навесні цього року, я почав розмірковувати про те, ким працюватиму далі. Викладачем англійської? (Гарно знав мову, для поїздки до Данії належало скласти мовний тест КЕТ. Також уже в Данії почав глибше вивчати англійську з репетитором — у чужій країні хочеться знати мову на такому рівні, щоб не потрапляти до ситуацій, коли всі жартують, а ти не розумієш, про що йдеться). Це можливо, та особливих задатків педагога я не мав. Ще в університеті я добре розв’язував різні логічні завдання, навіть допомагав одногрупникам із математикою. Коли перебирав ймовірні варіанти, збагнув, що IT може бути опцією для мене.

Співбесіда і початок навчання

Мій друг мав бажання повчити Python і запропонував зробити це разом. Почали вивчати ще за два місяці до закінчення контракту в Данії в післяробочий час, спочатку пройшли курс Python for everybody, потім почали читати Learning Pythonавторства Mark Lutz. У результаті йому не зайшло, а мені сподобалося, тож вирішив занурюватися в тему. Почав читати профільні ресурси, різні статті на ДОУ, якось побачив статтю про Mate Academy. Мене зацікавив їхній підхід до навчання: якщо на звичайних курсах платиш гроші наперед, вони тебе навчають, але ніхто нічого не обіцяє, то тут я мав гарантію, адже плачу гроші лише у разі успішного працевлаштування. Подумав собі: навіть якщо, в найгіршому разі, нічого не вийде, то максимум, що втрачу, — це кілька місяців життя. Коли ж усе складеться — спробую себе в новій професії.

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

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

Початок навчання

Навчання відбувалося онлайн у групі з 30 осіб (зідзвонювалися в Zoom-і). Я вибрав напрямок фронт-енд, оскільки поставив собі за мету стати фул-стек розробником, а досвідчені знайомі порадили в такому разі починати з фронту. Зранку о восьмій годині нам розсилали задачки на JS — така собі розминка мозку перед лекцією. Потім розпочиналася двогодинна лекція.

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

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

Шість співбесід, чотири тестових і три офери

Так сталося, що я працевлаштувався після двох з половиною місяців, ще не закінчивши повний курс навчання. Отримав три офери — і всі три були не на позицію React девелопера. Один — на Vue.js девелопера, другий — на Angular девелопера, а третій трохи стосувався Реакту, але з більшим нахилом у бек-частину розробки (такий собі фул-стек :).

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

У CV я вказував абсолютно всі технології, якими володів, навіть якщо рівень мав не надто високий. В cover letter потрібно було описати, чому саме ти «perfect fit» для даної вакансії, а також вчергове наголосити на своїх перевагах порівняно з іншими кандидатами. Більшість ейчарів писали мені на Djinni, куди я просто додав своє портфоліо з трьох проектів, які ми виконували в академії (два лендінги та SPA TODO app).

Я одразу був готовий до переїзду, тож розглядав вакансії у різних містах. На моє здивування писати стали часто — якимось дивом я за тиждень потрапив на 12-темісце в топі у Дніпрі (з-поміж 200 кандидатів). У Києві ж мій рейтинг був значно скромнішим — я тримався на 160 місці. Зауважив, що роботодавцям подобалося моє знання англійської — вони наголошували на ньому під час співбесід. Згодом щойно запитували про знання іноземної, я сам пропонував нею говорити, оскільки зрозумів, що це моя перевага.

За результатами надісланих резюме мені відповіли три компанії з Одеси, Києва та Дніпра (BIIR, E-consulting та LoopMe). Співбесіди було заплановано зі всіма трьома, але встиг пройти лише з компанією, яка відгукнулася з Дніпра (оскільки з двома іншими співбесіди мали відбутися наступного тижня). У ході співбесіди зрозумів, що вони потребують не звичайного джуніора, а людини з досить великим об’ємом знань (як мені здалось, можливо, навіть на рівні мідла). Тестовим завданням було написати код, який би збирав інформацію про поведінку користувачів на сайті та виводив цю інфу у вигляді теплової карти для перегляду адміном. На виконання цього завдання давався тиждень — у принципі, достатньо часу, аби розібратися і зробити карту. Але водночас я розумів, що іншому, досвідченішому кандидату це ж завдання може датися простіше, а я, вникаючи в деталі, лише вб’ю тиждень часу і залишуся ні з чим, і разом з тим не матиму змоги виконувати інші тестові. Тож відмовився.

Мені за декілька днів написало досить багато ейчарів на Djinni, яким я навіть не надсилав своє CV. З багатьма з них я мав інтерв’ю, але виділю лише три, від яких отримав офери.

У компанію зі Львова RestTech треба було написати SPA, який би працював з Spotify API, був би схожий на Spotify та мав подібний функціонал. Успішно впорався за вихідні і отримав офер. Ще два офери були з Харкова, в обох випадках для компаній був дуже важливий problem solving skill. У першій flow.ai (фул-стек позиція) я мав лише співбесіду, на якій перевірили мої технічні здібності та те, як себе поводжу під тиском, шляхом психологічного пресингу під час співбесіди. Наприклад, мені задавали питання, які не стосувалися моєї спеціалізації, і при цьому підганяли з відповіддю. Після цієї співбесіди я одразу ж отримав офер. У другій компанії Ukad, що в Харкові (позиція Angular розробника), я спочатку виконав тестове завдання на JS (задача на логічне мислення), а потім пройшов співбесіду з CTO, тімлідом та ейчаром компанії, в якій також багато уваги приділялось тому, як я вирішую поставлені завдання. Отримав офери від обох компаній, але вибрав останню, оскільки там мені запропонували досить гарні умови розвитку як спеціаліста, а ще я об’єктивно не був готовим до роботи на позиції фул-стека.

Переїзд до Харкова та плани на майбутнє

Якщо підсумувати досвід співбесід, які я пройшов, то запитання завжди були різними, і те, що не питали на одній співбесіді, могло бути дуже важливим на іншій. Але все ж спільні запитання траплялися, і їх можна умовно поділити на дві групи: запитання стосовно HTML/CSS/JS стеку, що є досить очевидним, адже це основи, і друга група запитань стосувалася побудови логічного ланцюжка з вирішення тієї чи іншої проблеми (наприклад, як би я реалізував кешування в додатку, схожому на Інстаграм, пояснити, чому саме таке рішення, в чому його плюси та мінуси та чи я бачу можливі шляхи оптимізації цього рішення).

Від себе хотів би порадити тим, хто лише почав подаватись на вакансії, бути наполегливими та в жодному разі не здаватися після того, як відмовлять 10-20або й більше разів. Також для мене спрацювало те, що я наголошував на своїх перевагах, особливо якщо це англійська (всі компанії, в яких я проходив співбесіди, хотіли кандидата з дуже гарним рівнем англійської). Ще одне загальне спостереження: не варто хвилюватися на співбесідах, адже якщо вас запросили, то ви потрібні цій компанії не менше, ніж вона вам ;)

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


Дякуємо за допомогу у підготовці статті Ярославі Тимощук.

Ищем причины овертаймов в команде: чек-лист для менеджера

$
0
0

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

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

Процесс составления/обновления расписания проекта

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

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

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

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

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

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

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

Проработка содержания проекта

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

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

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

  • Существует ли процесс управления изменениями в проекте?
  • Осведомлены ли все участники проекта о том, каким образом обрабатываются изменения в проекте?
  • Есть ли на проекте steering committee? Прописана ли его роль в разрешении конфликтов, связанных с изменениями в содержании?
  • Как выглядит сессия product backlog refinement, если она есть?
  • Каковы обязанности и роль владельца продукта, если таковой имеется?

Основываясь на своем опыте, выделю наиболее часто встречающиеся проблемы:

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

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

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

Управление требованиями

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

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

  • Всем ли вовлеченным сотрудникам известна цель проекта/видение продукта?
  • Используются ли гибкие цели при построении дорожных карт? Как они формулируются?
  • Какая документация используется для трассировки требований?

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

Управление вовлечением заинтересованных сторон

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

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

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

  • Возникают ли ситуации, когда клиент ходит к вашему начальству с просьбой «продавить» изменения в проекте?
  • Является ли проектный менеджер конечной точкой контактов с клиентом? Если нет, какие решения принимает аккаунт-менеджер?

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

  • Существует ли список всех заинтересованных сторон проекта?
  • Существует ли градация заинтересованных сторон проекта? На что она влияет?
  • Используются ли продвинутые модели анализа стейкхолдеров (матрицы, когнитивные карты)? Если да, каким образом эти артефакты обновляются?
  • Каким образом собирается обратная связь от заинтересованных сторон?
  • Каков сейчас уровень удовлетворенности разных стейкхолдеров от проекта? Какие последние действия предприняты для изменения этого показателя?

Наиболее распространенные практические проблемы:

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

Пример из практики.После каждого демо по проекту команда несколько дней оставалась работать сверхурочно. Причиной этого явления было то, что на демо приходили высокопоставленные стейкхолдеры, мнения которых о продукте не спрашивали ни разу, кроме как на самих демо. Никакая работа с ними не велась. Решением стал сбор общего steering committee, обсуждение ролей и интересов каждого стейкхолдера, маппинг стейкхолдеров (более 10 человек) на матрицу «влияние — интерес». Например, несколько человек приходили на демо, потому что это был их единственный источник информации о проекте.

Результатом таких действий явилось радикальное сокращение количества лиц, непосредственно влияющих на разработку продукта, и повышение удовлетворенности стейкхолдеров из-за уместных по объему и своевременных статус-отчетов.

Взаимные уступки

Взаимные уступки (лучший перевод trade-offs, который мне удалось придумать) могут относиться ко всем вышеперечисленным областям. В широком смысле я отношу взаимные уступки к части работы с заинтересованными сторонами, так как самый распространенный trade-off — это соотношение бизнес-задач и технических задач. Вспомните, например, как определяется длина спринта в Scrum: одним из критериев является как раз trade-off между бизнесом (которому нужно побольше и побыстрее) и технологией (нужно подольше делать и поменьше распыляться).

При входе на проект, который уже исполняется, всегда полезно посмотреть, каким образом происходит диалог между людьми из бизнеса и ответственными за технологические решения. Типичным примером может считаться работа с техническим долгом. Частой проблемой, которую я встречаю, является ситуация, когда менеджмент не признает проблему технического долга и продолжает бомбардировать запросами на новую функциональность, тогда как совестливая часть команды работает по ночам, чтобы закрыть пробелы в техническом фундаменте проекта.

Воспользуйтесь следующими вопросами:

  • Используется ли на проекте понятие технического долга? Все ли ознакомлены со смыслом?
  • Каким образом команда проекта управляет техническим долгом (визуализация, мониторинг, репортинг и прочее)?
  • Включена ли работа над техническим долгом в повестку сессий планирования?
  • Каким образом ведется приоритизация задач с учетом накопленного технического долга?
  • Каким образом технические задачи включаются в список работ? Насколько сильно сопротивляется бизнес и насколько команда способна коммуницировать потребности?
  • Включают ли дорожные карты проекта работу над техническими enablers?

Пример из практики.После очередного релиза и в отсутствие бюджета команда несколько дней в авральном порядке решала задачи технического долга. При анализе ситуации выяснилось несколько вещей. Во-первых, клиент не был tech-savvy, и работы по разъяснению того, из каких элементов может состоять бэклог, с ним никогда не проводились. Во-вторых, в команде отсутствовал definition of done, чтобы работать с ожиданиями клиента по готовности новой функциональности. Итак, сначала на очередном обзоре спринта подняли вопрос о том, что большинство обратной связи от клиента должно быть маркировано как «технический долг».

Например, возникли вопросы к быстродействию системы. Вместо создания бессмысленных карточек типа «я, как система, хочу работать быстрее» (да-да, такое, как оказалось, на проекте бывало) внесли пометки, чтобы отличать задачи, связанные с техническим долгом. Во-вторых, немного позже разработали и утвердили definition of done, отдельным пунктом которого стало: «Не создано технического долга, или создан элемент технического долга со сложностью не более 5 стори-пойнтов». Команда перестала работать над ним сверхурочно и сделала большой шаг на пути к zero debt policy.

Система метрик

Множество копий сломано и еще будет повреждено в спорах на тему того, нужны ли метрики в проектах. Практикующим менеджерам ответ понятен: наличие системы метрик позволяет настроить так называемую «приборную доску» проекта, уменьшить количество избыточных коммуникаций, быстро и точно репортить статус проекта как внутренним, так и внешним заинтересованным сторонам. Проблемы начинают возникать, когда система метрик начинает напрямую касаться членов команды. Подстегиваемые жесткими предельными значениями метрик, сотрудники будут впахивать, работая на метрики больше, чем на успех проекта. Ну или же просто сменят обстановку.

Предлагаю обратить внимание на следующие аспекты:

  • Влияют ли проектные метрики на сотрудника напрямую (пересмотр зарплаты, получение отпуска и прочее)?
  • На какие области проекта направлены метрики? Направлены ли они на сотрудника, команду, проект в целом?
  • Кому и как репортятся проектные метрики?
  • Какие решения принимаются на основании проектных метрик?
  • Кто имеет доступ к проектным метрикам?

На практике часто встречаются следующие случаи:

  • Проектные метрики используются для перформанс-ревью отдельного сотрудника.
  • Проектные метрики направлены на отслеживание индивидуальной эффективности членов проектной команды.
  • Проектные метрики слишком сложны или их слишком много, так что они интерпретируются некорректно по отношению к членам команды.
  • Предельные значения проектных метрик завышаются с целью «подстегнуть» команду.

Пример из практики.Однажды я присоединился к проекту, в котором предыдущий менеджер утаил от команды резерв рисков. Команда практически умирала, пытаясь попасть в свои минимальные оценки, потому что им никто не сказал, что их максимальные оценки были-таки учтены при планировании. Разумеется, расчеты EVM подгонялись с целью еще больше надавить на команду.

Здесь я сделал две вещи. Во-первых, я переговорил с руководством, чтобы прояснить и согласовать политику формирования проектных бюджетов. Во-вторых, я немного изменил процесс планирования в целом — команда начала использовать метод трех точек и брать обязательства по достижению средних величин, тогда как резерв рисков оговаривался отдельно и был всегда доступен. При его использовании мы проводили короткие ретро, чтобы разобраться, что не было учтено на этапе планирования и как избежать этого в дальнейшем.

Вместо послесловия

Как вы можете заметить, устранение сверхурочной работы команды может потребовать значительных усилий. Часть работы лежит в плоскости проекта, однако большая часть айсберга, касающаяся прежде всего людей и их взаимодействий, может находиться далеко за пределами сферы влияния проектного менеджера. Тем не менее нужно помнить, что проектный менеджер в первую очередь создает среду и условия для того, чтобы команда добивалась выдающихся результатов в проекте. Это означает, что иногда вы должны быть готовы идти дальше своих должностных инструкций ради блага команды.

Оценка трудоемкости проектов разработки. Часть 1

$
0
0

Меня зовут Александр Катруша, я работаю Senior Engineering Manager в компании Innovecs. Большую часть своей карьеры я занимался разработкой и внедрением ERP-систем, а также оценкой и управлением соответствующих проектов. И хотя тема оценки проектов неисчерпаема, как атом, надеюсь, мой опыт пригодится многим коллегам. Особо ценны будут советы, что делать и чего не делать, как избежать типичных ошибок в оценке и ее коммуникации.

Благодарен ребятам из этой темы на DOUза мотивационный пинок для написания статьи. Она состоит из двух частей. В первой части даны общие соображения, рассмотрены цели и сложности оценки проектов разработки, структура оценки и единицы измерения, требования к оценщикам и исполнителям. Вторая часть описывает пошаговый метод составления и оформления оценки, а также попытку математического обоснования предложенного метода.

Надеюсь, материал будет полезен начинающим и опытным руководителям проектов, сотрудникам отделов продаж, а также всем, кто так или иначе связан с оценкой, продажей и выполнением проектов разработки программного обеспечения.

Терминология

Я постараюсь не злоупотреблять англицизмами, но в случае семантических различий между английскими терминами и их общепринятым русским переводом может встретиться калька с английского термина, например:

  • скоуп (англ. scope) — содержание проекта, рамки проекта, объем работ;
  • assumptions — допущения, предположения;
  • contingency — риск.

Под оценкойпроекта я буду подразумевать только оценку трудоемкости работ (трудозатрат). Оценка затрат, таких как аренда офиса, железо, софт, лицензии, — тема для отдельной статьи. Также практически не буду касаться календарного планирования выполнения проекта, которое часто делается сразу после и на основе оценки трудоемкости.

Хочу также отметить, что в гибких практиках в последнее время принято говорить не об оценке, а о прогнозе (forecast), тем самым подчеркивая принципиальную неопределенность, связанную с выполнением проекта, и нацеленность больше на достижение бизнес-целей заказчика, чем на попадание в сроки и бюджет.

Под точностьюоценки буду подразумевать ее возможность обеспечить качественное планирование и выполнение проекта. Поскольку за время жизни проекта его рамки, предположения и прочие параметры, как правило, сильно изменяются, то вычислить «математическую» точность оценки (то есть отношение плана к факту) практически невозможно.

Когда и зачем нужна оценка проектов

Неопределенность

Одна из базовых проблем оценки — противоречие между принципиальной неопределенностью будущих параметров проекта и необходимостью принятия решений здесь и сейчас. Мы живем в мире годовых бюджетных циклов, тендеров, ROI, time-to-market и прочих практик и концепций, которые вынуждают принимать инвестиционные решения как можно раньше в жизненном цикле проекта, то есть именно тогда, когда риски недооценки или переоценки самые большие.

При этом в процессе переговоров либо участия в тендере на исполнителя оказывается дополнительное давление с целью уменьшения оценки и принятия им на себя большего риска. Стоит всегда помнить об этом противоречии при продаже, оценке и выполнении проекта.

Когда нужна оценка

В каких же случаях может возникнуть необходимость оценить трудоемкость проекта? Несколько возможных ситуаций:

  1. Переговоры с клиентом о новом проекте либо фазе проекта.
  2. Ответ на RFPлибо участие в тендере.
  3. Планирование бюджета и прочих ресурсов организации, например, календарное.
  4. Расчет ROIпроекта в ходе принятия принципиального решения о его запуске.

Если оценка нужна прямо сейчас

Если вы вынуждены оценивать проект в самом начале, на этапе сбора бизнес-требований или еще раньше, есть несколько путей снизить риск:

  1. Используя свой опыт предыдущих проектов, описать и оценить максимальный теоретически возможный скоуп, вплоть до легкой степени абсурдности. Но так, чтобы за каждым числом было пусть и слабое, но обоснование. После легкого шока, как правило, заказчик оценки становится более сговорчивым насчет предоставления необходимых входных данных, времени и ресурсов на оценку.
  2. Дать интервал оценки от и до, подчеркивая неопределенность и уровень риска, присущий проекту на этой стадии. Это позволит стейкхолдерам проекта принимать более осмысленные решения по принятию рисков.
  3. Двигаться итеративно, по пути уточняя прогнозные цифры.

Цели

Ответ на вопрос «зачем оценивать?» может быть не столь очевиден. Помимо собственно подсчета трудозатрат и бюджета, в процессе оценки необходимо проделать немалую работу по обоснованию прогнозных чисел и снижению рисков. Я бы выделил следующие основные цели процесса оценки:

  1. Определить и ограничить рамки проекта (scope) и зафиксировать предположения (assumptions), при которых оценка актуальна.
  2. Определить цену и себестоимость проекта на основе трудозатрат.
  3. Обосновать бюджет проекта перед внешними либо внутренними спонсорами.
  4. Получить входные данные для других процессов, таких как:
    • продажа;
    • планирование;
    • наем сотрудников;
    • бюджетирование.

На первом месте в списке целей — определение рамок проекта. Сложно переоценить важность этого пункта. Никакая оценка не имеет смысла без четкого описания того, что и при каких условиях мы оцениваем. На мой взгляд, отсутствие четкого описания рамок проектов и предположений — одна из основных причин проблем при их выполнении.

Второй и четвертый пункты достаточно очевидны, а вот третий может быть сложен для понимания разработчиками и теми, кто не знаком с работой бюрократических структур. Для выделения бюджета, особенно в больших корпорациях, часто бывает необходимо взять неясные, абсурдные либо вовсе несуществующие требования и сделать красивую обоснованную оценку. И только для того, чтобы люди, распределяющие бюджет, ее утвердили. А в рамках этого бюджета команда смогла бы перейти к выяснению «настоящих» требований и их реализации. При этом все участники процесса могут отлично понимать абсурдность и нереальность требований и их изменчивость. Но чем детальнее и профессиональнее будет выглядеть ваша оценка, тем выше шансы получить бюджет и реализовать проект «как нужно».

Особенно это актуально для не ИТ-клиентов, продающих услуги и продукты с гораздо меньшей степенью неопределенности, чем разработка софта. Их менеджерам может быть сложно понять, почему цена на одну и ту же услугу может отличаться на порядок в зависимости от «незначительных» изменений в требованиях, фазы проекта или поставщика.

На более же высоком уровне, по утверждению Steve McConnell в его великолепной книге Software Estimation, основная цель оценки — определить, являются ли цели проекта достаточно реалистичными для достижения, то есть стоит ли вообще браться за проект.

Эксперимент

Во время семинаров по оценке проектов я несколько раз просил аудиторию в течение нескольких минут оценить полные трудозатраты на разработку достаточно простого бизнес-приложения — программы для торговца цветами с функциями учета заказов, их выполнения, оплаты и хранения базовой информации о клиентах.

В результате даже старшие разработчики и архитекторы, работавшие много лет вместе на одной платформе, на одних и тех же входных данных, находясь в одной аудитории и читающие один и тот же текст, давали оценки, отличающиеся в 20 и более раз! Требования при этом были не очень детальными, но достаточно реалистичными, как если бы они действительно были сформулированы владельцем бизнеса.

Очевидно, причина такого разброса не в технической компетенции разработчиков, в которой я не сомневался. А в том, что они оценивали разный скоуп. Кто-то думал только о разработке базовых функций, кто-то же — и о работе с требованиями, тестировании, потенциальных изменениях, интеграциях, рисках.

Именно в том, чтобы видеть весь объем работ и рисков, и состоит важная часть искусства оценки проектов. Другая важная часть — это коммуникация со всеми стейкхолдерами проекта.

Оценщики и исполнители

Идеальный оценщик

Идеальный оценщик — это разработчик с квалификацией не ниже сеньора, желательно с опытом неудачных оценок и провальных проектов, а также хорошо понимающий процессы продажи, оценки, планирования и выполнения проекта в целом. При этом он должен чувствовать себя психологически в безопасности, то есть не должен бояться быть наказанным за недооценку или переоценку конкретных задач. Иначе он может стремиться закладывать более пессимистичные оценки либо вообще отказываться их давать. Команда же будет рада использовать все выделенное время, и бюджет вашего проекта может вырасти в несколько раз больше необходимого.

Этот феномен хорошо сформулирован в законе Паркинсона: «Работа заполняет время, отпущенное на нее». Опытный разработчик всегда найдет способ, как потратить 40 часов на 16-часовуюзадачу. А значит, завышенная оценка также может влиять на фактические трудозатраты.

Кроме того, очевидно завышенная оценка отдельных задач может подорвать доверие клиента ко всей оценке и ее авторам.

Когнитивные искажения, влияющие на оценку

Даже самые опытные специалисты могут ошибаться. Одна из причин ошибок, на мой взгляд, когнитивные искажения — свойства нашего мозга, мешающие нам мыслить рационально. Больше о них можно прочитать в книгенобелевского лауреата по экономике Даниела Канемана либо в «Википедии». Здесь я опишу три искажения, непосредственно касающиеся, на мой взгляд, нашей темы.

Ошибка планирования и оптимизм

Нам хочется думать, что мы лучше других. Поэтому своим задачам, как правило, даем более оптимистичную оценку, чем похожим задачам других людей. Хороший оценщик должен адекватно оценить свои силы и быть готовым сопротивляться приемам психологического давления вроде вопросов «почему так долго?!», спокойно аргументируя свою позицию.

Также всем, даже опытным разработчикам, присущ оптимизм в оценке задач. По эмпирическим данным, разработчики в среднем дают оценки, заниженные по крайней мере на 30%. И этот оптимизм, к сожалению, находит поддержку у менеджеров и других стейкхолдеров проекта.

Ошибки в оценке вероятностей

Фактическое время выполнения задачи — случайная величина. Даже люди, прошедшие университетский курс теории вероятностей, далеко не всегда в состоянии правильно ими оперировать. См., например, парадокс Монти Холла. Особенно справедливо это для условных, очень больших и очень малых вероятностей, чем с успехом пользуются страховые компании и организаторы лотерей. Также может быть непросто оценщику отличить, например, математическое ожидание трудозатрат от наиболее вероятных трудозатрат на задачу.

Для уменьшения эффекта договаривайтесь с разработчиком о том, что вы подразумеваете под оптимистичной, реалистичной, пессимистичной и вообще оценкой выполнения задачи. Вопрос «сколько может занять эта задача?» предполагает совершенно другой ответ, чем такие вопросы, как: «Какое наиболее вероятное время выполнения этой задачи?», «Какое среднее время выполнения этой задачи?».

Эффект привязки (якорение)

Люди подсознательно стремятся к услышанным или подсказанным кем-то числам. Об этом отлично знают, например, маркетологи. В нашем контексте это может значить, что:

  • Если вы хотите получить действительно независимые цифры от разных оценщиков, не стоит им сообщать результаты друг друга.
  • Не стоит давать никаких намеков, ориентиров, ожиданий, вариантов бюджета оценщику до того, как получите от него числа. Иначе результат будет сильно искажен вашими вводными данными.

Исполнители

Еще одна сложность состоит в том, что оценку, как правило, делают старшие разработчики, а выполняют же большинство задач мидлы и джуны. Как показали исследования, проведенные еще на заре индустрии, продуктивность программистов разной квалификации может отличаться в несколько раз, а иногда и в десятки раз.

Рекомендацией здесь будет проводить оценку для среднего разработчика (мидла), особенно если исполнители неизвестны на момент оценки. То есть оценщик должен поставить себя на место мидла. Тогда при сбалансированной по квалификации команде оценка будет достаточно реалистичной. Но это может потребовать дополнительных усилий от оценщика и отдельной коммуникации с ним.

Если же вы точно знаете, что в вашей команда будет дисбаланс по квалификации, корректируйте оценки. По моим подсчетам на основе продуктивности разработчиков разной квалификации и времени, которое уходит на обучение и ревью младших коллег, продуктивность таких двух команд может отличаться примерно в полтора раза.

Единицы измерения

Трудоемкость vs длительность

Я предпочитаю все задачи и проекты оценивать по трудоемкости (в человеко-часах), а не по длительности (в днях или неделях) по следующим причинам:

  1. На момент оценки команда может быть не набрана или ее состав может измениться в будущем.
  2. Команды часто отвлекаются на другие проекты или задачи.
  3. Из трудозатрат относительно легко получить примерную оценку длительности простым делением на доступные ресурсы.

Длительность при этом более интуитивна и удобна при стабильной команде на коротких отрезках времени.

Человеко-часы, -дни, -недели, -месяцы

Человеко-часы, на мой взгляд, более оптимальны, и вот почему:

  1. Разные люди, страны и компании работают по разным календарям. Рабочие дни и недели могут содержать разное количество рабочих часов, а кто-то из членов команды может работать неполный рабочий день. Это особенно актуально для распределенных команд.
  2. Ставки на разработку на мировом рынке аутсорсинга принято указывать для человеко-часов. Таким образом, простым умножением оценки на ставку можно получить примерный бюджет на работу в деньгах.
  3. Учет рабочего времени, если он есть, ведется в часах. Так будет намного удобнее сопоставлять план с фактом.
  4. Оценки в днях по определению менее точны, чем в часах, и позволяют разработчикам менее ответственно относиться к оценке.

Степени двойки

С учетом выбора человеко-часов в качестве единицы измерения представляется целесообразным использовать степени двойки для оценки конкретных задач. Они достаточно интуитивны, хорошо соответствуют рабочему времени восьмичасового рабочего дня и удобны в расчетах:
  • 0,5–1 ч —время для минимально возможной задачи;
  • 2 ч — время, которое можно комфортно провести за монитором без отвлечения внимания;
  • 4 ч — половина рабочего дня;
  • 8 ч — рабочий день;
  • 16 ч — два рабочих дня;
  • 32 ч — «почти неделя».

При надобности можно использовать и промежуточные числа: 6, 12, 40. Выше 40 ч оценка выглядит не совсем надежной, а задача плохо контролируемой. В таком случае желательно разбиение на подзадачи.

Рабочие часы vs эффективные часы

Не секрет, что разработчики, и не только они, непосредственно работают часов пять-шесть из восьмичасового рабочего дня. Остальное время уходит на отдых, кофе, перекуры, разговоры, Facebook и другие интересные занятия. Много дней подряд по 8 часов эффективно делать творческую работу практически невозможно.

Моя рекомендация — все же оценивать проект в рабочих, то есть астрономических, а не эффективных часах. И главная причина тут проста: сложно объяснить заказчику, почему он платит вам за восемь часов, а работаете вы только шесть... Даже если ваш заказчик — ИТ-компания и «тоже так делает», не стоит давать ему лишний козырь в потенциальных спорах, особенно судебных, которые могут возникнуть в течение жизни проекта. Кроме того, с рабочими часами проще планировать: не нужно вводить дополнительные коэффициенты.

Минус этого подхода проявляется на мелких задачах, при выполнении которых нет разницы между эффективными и рабочими часами. Три задачи по два или одна по шесть часов эффективного времени будут сделаны за один восьмичасовой рабочий день, об этом стоит помнить при оценке и планировании.

Структура оценки

Как мы выяснили в первой части статьи, цель оценки — не только найти трудозатраты, но и описать скоуп, риски, а также правильно преподнести их всем стейкхолдерам проекта. А потому документ «Оценка проекта» как минимум должен содержать:

  1. Скоуп.Что мы оцениваем в виде списка требований, работ и того, что в скоуп не входит.
  2. Предположения и риски.При каких условиях оценка актуальна, и что, по нашему мнению, может пойти не так.
  3. Числа.Сколько трудозатрат потребует сделать 1 при условиях 2.
  4. Упаковка. Last but not least. Правильно преподнести оценку не менее важно, чем качественно оценить, особенно в процессе продажи.

Заметьте, что собственно оценка в виде чисел только на третьем месте, поскольку качественное определение скоупа и предположений намного важнее для успеха проекта, чем точность оценки. Числа неотделимы от того, что и при каких условиях они оценивают. Ошибка в оценке индивидуальной задачи может составить 5%, 10%, пусть даже 50%, и это может быть некритичным для проекта. В то время как неправильная оценка скоупа и рисков может увеличить трудоемкость работ в несколько раз.

Все недосказанности, потенциальные конфликты с заказчиком и другими стейкхолдерами намного дешевле разрешать в начале проекта, чем в его середине или конце. Для этого и необходимо четкое описание скоупа, предположения и рисков. Потому не бойтесь мягко, но настойчиво указывать на недостаток информации или ее противоречивость, ошибки заказчика, видимые риски.

Заключение

Итак, в первой части мы рассмотрели основные сложности в оценке проектов, цели процесса оценки, требования к оценщику (разработчику), структуру и единицы измерения оценки. В следующей части перейдем непосредственно к трудоемкому процессу ее составления.

Certonid - SSH центр сертификации, который работает на AWS Lambda

$
0
0

Всем привет! Меня зовут Алексей, я разработчик/девопс/подкастер, и в этой статье я хочу вам рассказать о своем проекте Certonid — серверлесс-SSH-центре сертификации (serverless SSH certificate authority). Этот инструмент может помочь решить проблему менеджмента доступа к Linux-серверам по SSH. Давайте начнем по порядку.

SSH-сертификаты

SSH вездесущ. Это де-факто стандарт для удаленного администрирования *nix-систем. Когда девопс настраивает Linux-сервер, то обычно создается пара учетных записей с паролями. Локальное управление учетными записями хорошо работает с небольшими группами серверов, но по мере роста продукта требуется создавать центральную систему аутентификации, такую как LDAP и/или Kerberos, чтобы избежать ручного управления учетными записями на каждом сервере. При дальнейшем росте девопс может прийти к выводу, что центральная система аутентификация — единственная и потенциально разрушительная точка отказа всей системы. Как только она выйдет из строя, то все потеряют доступ ко всему (если только не создать учетные записи с прямым, в обход системы аутентификации, доступом, что может быть небезопасно). Блокирование вашей собственной системы — одна из худших вещей, которые могут случиться во время инцидента. Например, если перебои в работе службы повредили вашу систему аутентификации, то вы не сможете войти и исправить ее.

В дополнение к этим рискам выбор SSH-аутентификации с открытым ключом (SSH public key authentication) для ваших разработчиков/девопсов означает необходимость управления их открытыми ключами на всех ваших серверах. Также нередко безопасность системы ставится под угрозу, если есть неизвестные открытые ключи в файлах authorized_keys (в такой файл пишутся открытые ключи, через которые по SSH можно получить доступ к системе). Кроме того, authorised_keys требует определения доверия по отдельной паре ключей, которая не масштабируется.

Для решения проблем с SSH-аутентификацией с помощью открытого ключа (SSH public key authentication) можно перейти к SSH-аутентификации с помощью сертификатов (SSH certificate authentication). Давайте посмотрим, как это работает.

Для начала создадим свой собственный CA (certificate authority, центр сертификации), который, по сути, представляет собой обычную пару ключей:

$ mkdir sshca && cd sshca
$ ssh-keygen -C CA -f ca-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ca-key.
Your public key has been saved in ca-key.pub.

Ssh-keygen-утилита попросит ввести пароль на ваш ключ, что я советую всегда делать. Можно создать ключ и без пароля, но я бы не оставлял этот ключ без него. Пароль в этом случае используется для шифрования закрытого ключа. Это само по себе делает файл ключа бесполезным для злоумышленника (хотя бы на какое-то время). Это, конечно, не означает, что если закрытый ключ был скомпрометирован, то его не нужно будет менять (это придется делать в любом случае). Просто у вас появится фора, пока злоумышленник будет подбирать пароль, чтобы расшифровать ваш закрытый ключ.

Сейчас у вас есть два файла: «ca-key» (закрытый ключ) и «ca-key.pub» (открытый ключ). Теперь надо распространить ca-key.pub по всем серверам, к которым требуется доступ по SSH через сертификаты. Поскольку вы распространяете открытый ключ, то можно не беспокоиться о безопасности его передачи: канал его распространения необязательно шифровать. Для нашего примера давайте разместим его в «/etc/ssh/ca-key.pub» на серверах.

Следующий этап заключается в конфигурации SSH-демонов на серверах, чтобы они доверяли этому ключу, путем добавления/изменения строчки в конфиге «/etc/ssh/sshd_config» (не забудьте после изменений перезагрузить SSH-демон):

TrustedUserCAKeys /etc/ssh/ca-key.pub

Теперь, когда у вас есть цепочка доверия (chain of trust), вы можете начать создавать SSH-сертификаты. В идеале ваш CA должен быть очень защищенным сервером, к которому доступ может получить только команда, которая занимается безопасностью в продукте (security team). Одна очень важная практика безопасности состоит в том, что закрытые ключи никогда не должны покидать систем, на которых они были созданы, независимо от того, насколько безопасен канал передачи данных.

Далее уже на компьютере разработчика генерируем ему SSH-ключи (если их нет или вы хотите использовать отдельные ключи):

$ ssh-keygen -t ecdsa # или “ssh-keygen -t rsa”
Generating public/private ecdsa key pair.
Enter file in which to save the key (/Users/leo/.ssh/id_ecdsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/leo/.ssh/id_ecdsa.
Your public key has been saved in /Users/leo/.ssh/id_ecdsa.pub.

Теперь в «.ssh/» каталоге у нас есть файлы «id_ecdsa» (закрытый ключ) и «id_ecdsa.pub» (открытый ключ). Копируем открытый ключ на CA-сервер. Канал передачи данных неважен. Просто никуда не передавайте закрытый ключ «id_ecdsa».

Наконец, на CA-сервере создаем SSH-сертификат для открытого ключа разработчика:

$ ssh-keygen -s ca-key -I leo -n deployer -V +1w -z 1 id_ecdsa.pub 
Enter passphrase:
Signed user key id_ecdsa.pub: id "leo" serial 1 for deployer valid from 2019-11-07T00:32:00 to 2019-11-14T00:33:44

Что тут происходит? По сути, мы подписываем «id_ecdsa.pub» через ca-key. Идентификатор сертификата будет leo, и единственным principal будет deployer. Сертификат действителен в течение одной недели и имеет серийный номер 1. Теперь у вас должен быть файл id_ecdsa-cert.pub. Скопируйте его обратно на компьютер разработчика и поместите в папку .ssh/. Канал передачи данных и здесь неважен, это общедоступная информация, а сам сертификат не работает без соответствующего закрытого ключа (тот самый id_ecdsa). Поскольку мы не настроили серверы на использование определенного набора principal, стандартная конфигурация sshd позволит этому сертификату войти в систему под именем любого пользователя (который присутствует в системе). Поскольку я использовал -n deployer для создания сертификата, то могу войти в систему как deployer-юзер. Если у вас нет специальной схемы авторизации на серверах, этого для вас может быть достаточно.

Давайте глянем информацию по сертификату с помощью ssh-keygen:

$ ssh-keygen -Lf id_ecdsa-cert.pub
id_ecdsa-cert.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:Kz/8gC5dKLQaYsiAoQwnf7wAbEJLQ0R4TD4iCHwK9Bg
        Signing CA: RSA SHA256:Tk2tXG7mqDJS8Pzj8RiA3MgpqlgOUYG2i3Ju7wYN7QM
        Key ID: "leo"
        Serial: 1
        Valid: from 2019-11-07T00:32:00 to 2019-11-14T00:33:44
        Principals:
                deployer
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

Как уже было сказано, у сертификата есть время жизни. В случае инцидента — ошибки, кражи, неправильного использования — скомпрометированные учетные данные SSH-сертификата истекают автоматически, без вмешательства, даже если инцидент остался незамеченным. Можно создавать сертификаты, время жизни которых будет несколько минут, потому что SSH-сервер не выбросит пользователя из системы, если сертификат истек, пока он к ней подключен.

Теперь, когда у нас есть сертификат и закрытый ключ, можно подключиться как пользователь deployer на SSH-сервер, который доверяет нашему CA:

$ ssh deployer@system-which-trust-ca-key

Как только произойдет подключение к серверу, в журнале аутентификации можно будет заметить такую строчку:

Nov 6 22:55:11 example sshd[1899]: Accepted publickey for deployer from 176.14.529.36 port 56223 ssh2: ED25519-CERT ID leo (serial 1) CA RSA SHA256:...

Прекрасно видно, что даже при входе на сервер от имени deployer система может идентифицировать сертификат, используемый для аутентификации. В этом случае сертификат с идентификатором leo. Это означает, что использование правильного -I с ssh-keygen очень важно, потому что оно идентифицирует, кому принадлежит сертификат. Также рекомендуется использовать уникальный серийный номер (тут serial 1), чтобы вы могли идентифицировать каждый выданный отдельный сертификат. Кстати, уникальные серийные номера обязательны, если вы хотите использовать SSH-параметр RevokedKeys в конфиге для отзыва скомпрометированных сертификатов с закрытыми ключами.

Надеюсь, теперь вам ясно, как работают SSH-сертификаты. Хочу заметить, что это решение не какая-то новая хипстерская поделка — аутентификация с использованием сертификатов была добавлена в OpenSSH 5.4 почти десять лет назад.

Автоматизация

Теперь рассмотрим более серьезный вопрос: как это автоматизировать? Держать отдельного человека, который будет сидеть за своим компьютером и подписывать сертификаты вручную, — кажется не очень хорошим решением. Существует множество инструментов для управления SSH-сертификатами. Вот некоторые из них:

  • netflix/bless — решение от Netflix. Работает на AWS Lambda (serverless) и использует AWS IAM. Написано на Python;
  • nsheridan/cashier — решение от Intercom. Представляет собой сервер и клиент, написанный на Golang;
  • uber/pam-ussh — подключаемый модуль аутентификации (PAM) от Uber, который написан на Golang;
  • hashicorp/vault — решение от HashiCorp для хранения секретов. Содержит SSH secrets engineс поддержкой сертификатов.

BLESS от Netflix из всех этих решений кажется наиболее интересным. В первую очередь из-за того, что не нужно создавать сервер, который будет заниматься подписыванием сертификатов. Ведь в таком случае нужно понять, как обезопасить (сертификатов еще нет, чтобы через них ходить на этот сервер) и создать избыточность, чтобы он не стал точкой отказа всей инфраструктуры. Использование AWS Lambda с регионами AWS позволяет избежать этих двух проблем. Но если подход интересен, то сам BLESS имеет несколько не очень удобных вещей:

  1. BLESS написан на Python. Сам по себе язык Python не является чем-то плохим (хороший язык), но BLESS требует сборки проекта. Поскольку там идет сборка нативных библиотек, это надо делать в Docker-контейнере. Но даже и после этого нет гарантии, что у вас все получится: зависимости могут поломаться (опять же язык тут ни при чем). В сборку заранее нужно не забыть добавить CA-ключ, самому зашифровать его пароль и сам файл. Все это не позволяет так просто использовать BLESS.
  2. Развернуть BLESS не так легко и понятно, как кажется. Особенно если вам нужно еще добавить поддержку KMSAuth. Документация не очень дружелюбная в этом плане.
  3. У BLESS нет хорошего официального клиента. Есть небольшой Python-скрипт, и на этом все. Имеются, конечно, сторонние решения, что уже делает вызов BLESS-функции удобнее. Но даже сторонние решения не решают проблему, когда ты как пользователь должен переключаться между проектами (когда у тебя один проект, например Netflix, таких проблем не ощущаешь).
  4. BLESS заточен для работы на бастион-хосте. Бастион (Bastion host) — так называют специально отведенный компьютер в сети, обычно расположенный на внешней стороне демилитаризованной зоны (ДМЗ) организации. Через него попадают уже на другие серверы, которые находятся в закрытой сети. Я выскажу непопулярное мнение, идущее вразрез с нынешними best security practices: вам, вероятнее всего, не нужен бастион, и он может принести больше вреда, чем пользы. Я могу привести в качестве доказательства много пунктов, которые покажут, что этот узел не добавляет надежности и безопасности, но статья не об этом. Единственный плюс, который я не буду оспаривать: бастион замедляют атаку, особенно автоматизированную. Это как купить очень хорошую входную дверь: невскрываемых дверей нет, но более защищенная доставит больше хлопот грабителю при вскрытии, и поэтому многие просто могут отказаться ее вскрывать. Так вот, в большинстве продуктов нет бастион-хоста, и доступ по SSH нужно получить с машины пользователя. В таком случае настройка и развертывание клиента, что будет помогать в этом, должны быть простой процедурой.

После нескольких не очень успешных попыток завести BLESS (в комплексе, а не только AWS Lambda) за несколько выходных был написан «свой велосипед». Certonid — это как раз тот же SSH Serverless CA. Написан на Golang, за счет чего сразу предоставляются собранные бинарные файлы, которые вам не требуется дополнительно подготавливать. Состоит он из двух частей — CLI и серверлесс-части. Подготовить его достаточно просто. Вам нужно скачать CLI (выбрать под вашу систему) и серверлесс-часть (только одна версия — AWS Lambda работает на Linux). Далее создать zip-файл, в который положить серверлесс serverless.linux.amd64 (лучше назвать файл serverless), ваш ca-key и certonid.yml. В конфиге нужно будет указать, как получить доступ к ca-key (сам файл можно зашифровать симметричным шифрованием или с использованием AWS KMS) и как получить пароль для ключа (Certonid работает только с закрытыми ключами, у которых есть пароль), который будет тоже зашифрован симметричным шифрованием или с использованием AWS KMS. Для упрощения этой работы у CLI есть вспомогательные функции для шифрования строк или файлов. Пример конфига:

ca:
  storage: file
  path: ca.pem
  encrypted:
    encryption: aws_kms
    region: us-east-1
  passphrase:
    encryption: aws_kms
    region: us-east-1
    content: AQICAHhBwiHijA5XW9EyanTVga4XbbwEVCmBLSUiWIxrCrxrUwGGt8JapxlfiJljay3FycLOAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMtZxOyGi2foFM+y9SAgEQgCOY1N4sMr5RIiyQ4/8yloRIAi6vWaK3n/jEdgPfn3bdJjrkNQ==

certificates:
  user:
    max_valid_until: 2h
    additional_principals:
      - "ubuntu"
      - "ec2-user"
    critical_options:
      - "source-address 0.0.0.0/0"
    extensions:
    - "permit-X11-forwarding"
    - "permit-agent-forwarding"
    - "permit-port-forwarding"
    - "permit-pty"
    - "permit-user-rc"

logging:
  level: info

Далее этот zip-файл загружаем в AWS Lambda. AWS Lambda Runtime — Go 1.x. AWS Lambda Handler должен быть именем файла серверлесс-компонента Certonid в zip-файле (в примере файл serverless). Не забудьте, что этой функции требуется доступ к ключам AWS KMS, если вы через него зашифровали пароли и, по желанию, сам CA-ключ.

Памяти и времени выполнения на эту функцию много не потребуется (128 Мбайт и 10 с должно хватить с запасом). Для примера строчка из CloudWatch-логов:

REPORT RequestId: d7e99280-7860-426e-a6e1-e80d83176f83 Duration: 3223.70 ms Billed Duration: 3300 ms Memory Size: 128 MB Max Memory Used: 58 MB Init Duration: 124.16 ms

После этого нужно настроить Certonid CLI. Для вызова функции AWS Lambda используется AWS Identity and Access Management (IAM): каждому пользователю, которому требуется доступ по SSH на серверы, создается пользователь в IAM. Если человек покидает проект, его аккаунт блокируется на AWS, и он более не сможет запрашивать новые сертификаты, чтобы попадать на серверы (старые перестанут работать по истечении указанного вами времени жизни). Совет от меня: если вы уже используете AWS для проекта, то лучше для Certonid AWS Lambda и IAM-менеджмента создать отдельный AWS-аккаунт, чтобы не смешивать сущности и доступы уже самого продукта. Конфиг CLI по умолчанию хранится в $HOME/.certonid.yml. Пример конфига:

certificates:
  examplecom:
    public_key_path: ~/.ssh/id_ed25519.pub
    username: leopard
    runner: aws
    valid_until: 4h
    aws:
      profile: aws-profile
      region: us-east-1
      function_name: CertonidFunction

Секция certificates содержит разные проекты/функции с сертификатами, поэтому один CLI может работать с несколькими серверлесс-центрами сертификации.

Для настроек доступа можно в конфиге Certonid указать AWS Access Key ID и Secret Access Key через переменные окружения или (я пользуюсь таким вариантом) настроить AWS CLI профилии внести нужный профиль для Certonid в конфигурации (в примере так сделано).

После этого с помощью команды certonid gencert можем получить сертификат на наш открытый ключ:

$ certonid gencert examplecom                                 
INFO[2019-11-07T17:57:20+02:00] Signing public key                            
certificate=/Users/leo/.projects_certs/examplecom-cert.pub 
public key=/Users/leo/.ssh/id_ed25519.pub runner=aws
INFO[2019-11-07T17:57:25+02:00] Certificate generated and stored              
certificate=/Users/leo/.projects_certs/examplecom-cert.pub 
public_key=/Users/leo/.ssh/id_ed25519.pub valid until="2019-11-08 15:57:22 +0000 UTC"

Если команду запустить заново, то она проверит существующий сертификат, и если он все еще работает, то CLI просто завершит свою работу и лишний раз не будет вызывать AWS Lambda (не забываем, что эти вызовы стоят денег).

$ certonid gencert examplecom
INFO[2019-11-07T18:00:35+02:00] Current certificate still valid. Exiting...   certificate=/Users/leo/.projects_certs/examplecom-cert.pub valid until="2019-11-08 15:57:22 +0000 UTC"

Больше по командам можно узнать из certonid -h или Вики.

Интеграция с SSH

Есть одно условие для работы сертификатов: сертификат должен лежать в той же папке, что и закрытый ключ с именем файла <имя закрытого ключа>-cert.pub. В таком случае SSH agent при добавлении закрытого ключа автоматически подхватит в хранилище сертификат. Но это неудобно, если вы используете один и тот же закрытый ключ для разных проектов (нужно перезаписывать файл сертификата и потом добавлять его в SSH-агент).

Certonid по умолчанию складывает сертификаты в отдельную папку, чтобы у вас была возможность использовать один закрытый ключ (если требуется) для разных проектов, не переписывая каждый раз один файл. Конечно же, через конфиг это можно поменять и сохранять его там, где вам нравится. Но тогда как эти сертификаты использовать, раз они хранятся не по формату OpenSSH?

Другой вопрос, который у вас может созреть в голове: «Это все хорошо, но мне теперь каждый раз запускать эту поделку, перед тем как подключиться по SSH к серверу?» Замечание очень верное, и это неудобство нужно как-то решать.

Первый вариант решения проблемы заключается в создании конфигурации для вашего SSH-клиента. Допустим, нам нужно подключаться к доменам *.example.com через сертификат examplecom. В файл конфигурации ($HOME/.ssh/config) мы можем добавить:

Match Host *.example.com exec "certonid gencert examplecom"
    Port 22
    User deployer
    IdentityFile  ~/.ssh/id_ed25519
    CertificateFile ~/.projects_certs/examplecom-cert.pub
    PasswordAuthentication no

Как видите, SSH-конфиг поддерживает для сравнения exec-опцию, которая выполнит команду, и если она завершится успешно (код выхода ноль), то условие считается истинным для конфигурации. Вот в этот параметр можно добавить команду certonid gencert examplecom. Поскольку сертификат лежит в другом месте, его можно указать через параметр CertificateFile. После такой конфигурации можно просто писать в консоли и подключаться к серверам:

$ ssh web1.example.com
$ ssh web4.example.com

Но бывают случаи, когда определенный софт не умеет работать с SSH-конфигом, а на <имя закрытого ключа>-cert.pub ему может быть все равно. Если этот софт поддерживает работу с SSH-агентом, сертификат можно добавить в него. Пример команды прост:

$ certonid gencert examplecom --add-to-ssh-agent ~/.ssh/id_ed25519

Поскольку сертификат не добавить в SSH-агент без закрытого ключа, его придется указать как значение для команды —add-to-ssh-agent. Этот параметр можно добавить в yml-конфиг, но такой вариант не подойдет тем, у кого закрытые ключи зашифрованы паролем, потому что при каждом запуске с такой командой Certonid будет спрашивать тот самый пароль. После этого можно проверить сертификат в агенте:

$ ssh-add -l
4096 SHA256:... leo@Alexeys-MacBook-Air.local (RSA)
256 SHA256:... leo@Alexeys-MacBook-Air.local (ED25519)
256 SHA256:... leopard_1573142242 [Expires 2019-11-08 17:57:22 +0200 EET] (ED25519-CERT)

При этом Certonid добавил сертификат со сроком его жизни в SSH-агент. Поэтому, как только сертификат станет недействительным, он автоматически исчезнет из агента (мусор за собой нужно убирать). После этого можете подключаться к серверам или добавлять в SSH-конфиг:

Host *.example.com
    Port 22
    User deployer
    ForwardAgent yes
    PasswordAuthentication no

В заключение

На текущий момент Certonid не содержит всего функционала, что я задумал для него:

  • нет автоматического переключения на другие serverless, если регион упал;
  • нет тестов (что немаловажно для последующей разработки);
  • хочется добавить поддержку Google Cloud и Azure (если с первым все понятно, то у второго нет поддержки Golang);
  • надо еще улучшать документацию.

Но я надеюсь, что этот продукт уже сможет вам помочь более безопасно работать с SSH.

Формат статьи не позволяет за один раз раскрыть важные аспекты работы с SSH-сертификатами и Certonid, такие как SSH-хост-сертификаты, critical options и extensions в сертификатах, настройка и работа с KMSAuth, значение настроек в конфигах Certonid и прочее. Если читателям эта тема интересна, я постараюсь продолжить рассказ в следующей статье.

Благодарю за внимание! Успехов вам с SSH-безопасностью!

Viewing all 8945 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>