-Поиск по дневнику

Поиск сообщений в rss_rss_hh_new

 -Подписка по e-mail

 

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 51

Habrahabr/New








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/new/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-new-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

[Из песочницы] Послевкусие от Kotlin

Вторник, 20 Июня 2017 г. 13:34 + в цитатник
Написано довольно много статей о Kotlin, но об его использовании в реальных проектах – единицы. В особенности, Kotlin часто хвалят, поэтому я буду говорить о проблемах.

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

image

1. Annotation Processors


Проблема в том, что Kotlin компилируется в Java, а уже на основе Java генерятся классы, скажем, для JPA или, как в моём случае, QueryDsl. Поэтому результат работы annotation processor не удастся использовать в том же модуле (в тестах можно).

Варианты обхода проблемы:

  • выделить классы, с которыми работает annotation processor в отдельный модуль.
  • исползовать результат annotation processor только из Java класов (их можно будет легально вызывать из Kotlin). Придётся возиться с maven, чтобы он в точности соблюдал последовательность: компилируем Kotlin, наш annotation processor, компилируем Java.
  • попробовать помучиться с kapt (у меня с QueryDsl не вышло)

2. Аннотации внутри конструктора


Наткулся на это при объявлении валидации модели. Вот класс, который правильно валидируется:

class UserWithField(param: String) {
    @NotEmpty var field: String = param
}

А вот этот уже нет:
class UserWithConstructor(
    @NotEmpty var paramAndField: String
)

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

class UserWithFixedConstructor(
    @field:NotEmpty var paramAndField: String
)

Сложно винить за это JetBrains, они честно задокументировали это поведение. И выбор дефолтного поведения понятен – параметры в конструкторе — не всегда поля. Но я чуть не попался.
Мораль: всегда ставьте @field: в аннотациях конструктора, даже если это не нужно (как в случае javax.persistence.Column), целее будете.

3. Переопределение setter


Вещь полезная. Так, к примеру, можно обрезать дату до месяца (где это ещё делать?). Но есть одно но:

class NotDefaultSetterTest {
    @Test fun customSetter() {
        val ivan = User("Ivan")
        assertEquals("Ivan", ivan.name)
        ivan.name = "Ivan"
        assertEquals("IVAN", ivan.name)
    }

    class User(
            nameParam: String
    ) {
        var name: String = nameParam
            set(value) {
                field = value.toUpperCase()
            }
    }
}

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

class User(
        nameParam: String
) {
    var name: String = nameParam.toUpperCase()
        set(value) {
            field = value.toUpperCase()
        }
}

4. Особенности работы с фреймворками


Изначально были большие проблемы работы со Spring и Hibernate, но в итоге появился плагин, который всё решил. Вкратце – плагин делает все поля not final и добавляет конструктор без параметров для классов с указанными анотациями.

Но интересные вещи начались при работе с JSF. Раньше я, как добросовестный Java-программист, везде вставлял getter-setter. Теперь, так как язык обязывает, я каждый раз задумываюсь, а изменяемо ли поле. Но нет, JSF это не интересно, setter нужен через раз. Так что всё, что у меня передавалось в JSF, стало полностью mutable. Это заставило меня везде использовать DTO. Не то чтобы это было плохо…

А ещё иногда JSF нужен конструктор без параметров. Я, если честно, даже не смог воспроизвести, пока писал статью. Проблема связана с особенностями жизненного цикла view.

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

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

5. Код, понятный только посвященным


Изначально всё остается понятным для неподготовленного читателя. Убрали get-set, null-safe, функциональщина, extensions… Но после погружения начинаешь использовать особенности языка.

Вот конкретный пример:

fun getBalance(group: ClassGroup, month: Date, payments: Map>): Balance {
    val errors = mutableListOf()
    fun tryGetBalanceItem(block: () -> Balance.Item) = try {
        block()
    } catch(e: LackOfInformation) {
        errors += e.message!!
        Balance.Item.empty
    }

    val credit = tryGetBalanceItem {
        creditBalancePart(group, month, payments)
    }
    val salary = tryGetBalanceItem {
        salaryBalancePart(group, month)
    }
    val rent = tryGetBalanceItem {
        rentBalancePart(group, month)
    }
    return Balance(credit, salary, rent, errors)
}

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

Объяснение работы метода
Для начала, try, if и when являются блоками, возвращающими значения (последняя строка в блоке). Особенно это важно для try/catch, потому что следующий код, привычный Java-разработчику не компилируется:

val result: String
try {
    //some code
    result = "first"
    //some other code
} catch (e: Exception) {
    result = "second"
}

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

Дальше: fun tryGetBalanceItem – локальная функция. Прямо как в JavaScript, только со строгой типизацией.

Кроме того, tryGetBalanceItem принимает в качестве аргумента другую функцию и выполняет её внутри try. Если переданная функция провалилась, ошибка добавляется в список и возвращается дефолтный объект.

6. Параметры по умолчанию


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

Например, мы решили, что у User есть обязательные поля, которые нам будут известны при регистрации. А есть поле, вроде даты создания, которое явно имеет только одно значение при создании объекта и будет указываться явно только при восстановлении объекта из DTO.

data class User (
        val name: String,
        val birthDate: Date,
        val created: Date = Date()
)
fun usageVersion1() {
    val newUser = User("Ivan", SEPTEMBER_1990)
    val userFromDto = User(userDto.name, userDto.birthDate, userDto.created)
}

Через месяц мы добавляем поле disabled, которое, так же как и created, при создании User имеет только одно осмысленное значение:

data class User (
        val name: String,
        val birthDate: Date,
        val created: Date = Date(),
        val disabled: Boolean = false
)
fun usageVersion2() {
    val newUser = User("Ivan", SEPTEMBER_1990)
    val userFromDto = User(userDto.name, userDto.birthDate, userDto.created, userDto.disabled)
}

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

7. Лямбда, вложенная в лямбду


val months: List = ...
val hallsRents: Map> = months
        .map { month ->
            month to halls
                    .map { it.name to rent(month, it) }
                    .toMap()
        }
        .toMap()

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

Казалось бы, обычный стримоз мозга – возьми, да и замени на цикл. Но есть одно но: hallsRents станет MutableMap, что неправильно.

Долгое время код оставался в таком виде. Но сейчас подобные места заменяю на:

val months: List = ...
val hallsRents: Map> = months
        .map { it to rentsByHallNames(it) }
        .toMap()

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

Свой проект я считаю репрезентативным: 8500 строк, при том что Kotlin лаконичен (в первый раз считаю строки). Могу сказать, что кроме описаных выше, проблем не возникало и это показательно. Проект функционирует в prod два месяца, при этом проблемы возникали только дважды: один NPE (это была очень глупая ошибка) и одна бага в ehcache (к моменту обнаружения уже вышла новая версия с исправлением).

PS. В следующей статье напишу о полезных вещах, которые дал мне переход на Kotlin.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331280/


Метки:  

Как программист машину покупал. Часть III

Вторник, 20 Июня 2017 г. 13:32 + в цитатник
В двух предыдущих частях (I, II) своего повествования о сервисе для поиска выгодных автомобилей я подробно изложил техническую сторону вопроса — постановку задачи и ее решение.

В этой статье я более подробно остановлюсь на результатах и возможностях сервиса robasta.ru.

Для тех, кто не читал предыдущие статьи и не горит желанием этого делать:

Robasta.ru — сервис для поиска выгодных автомобилей (цена которых ниже рыночной) по данным со всех основных сайтов с объявлениями о продаже б/у автомобилей в РФ.

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

image
Читать дальше →

https://habrahabr.ru/post/331278/


Метки:  

Время смелых. Как мигрировать в облака, не нарушая требований регуляторов?

Вторник, 20 Июня 2017 г. 12:21 + в цитатник


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


Несмотря на то, что в мире банковский сектор стал одним из первых использовать облачные технологии, в РФ к ним, из-за принятия ряда новых законов (Закона «О персональных данных» и сопутствующих документов), финансовые учреждения относятся осторожно. И если рынка частных облаков законодательные акты не коснулись, то публичных компании опасаются. Ведь использование «внешних» сервисов всегда требовало повышенного внимания к вопросам информационной безопасности, все-таки банковская отрасль. Кроме того, за последние годы существенно увеличилось количество киберугроз и хакерских атак, и теперь на участников финансового рынка накладываются ужесточенные требования законодательства РФ в области защиты информации и акты регулирующих органов.


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



Законодательные акты, дотянувшиеся до «облаков»


Начнем с главного – с требований законодательства и регулирующих органов.


  1. Требования законодательства РФ в области защиты информации – Федеральные законы 149-ФЗ («Об информации, информационных технологиях и о защите информации»), 152-ФЗ («О персональных данных»), 242-ФЗ («О внесении изменений в отдельные законодательные акты РФ по вопросам осуществления государственного контроля (надзора) и муниципального контроля»), 161-ФЗ («О национальной платежной системе») и др.;
  2. Требования ФСТЭК России и ФСБ России в области защиты информации – содержащие меры по защите персональных данных приказ ФСТЭК России №21 и Приказ ФСБ России №378, методические документы и разъяснения регуляторов;
  3. Требования Центрального Банка РФ (ЦБ) в области защиты информации – отраслевой стандарт по обеспечению информационной безопасности (СТО БР ИББС) и рекомендации в области стандартизации (РС БР ИББС), Положения ЦБ РФ №382-П и №552-П по защите информации при обеспечении переводов денежных средств, указания ЦБ РФ и другие документы;
  4. Требования ФСТЭК России и ФСБ России к лицензиатам по деятельности в области защиты информации;
  5. Требования международных платежных систем по защите информации данных держателей карт (PCI DSS);
  6. Инициативы ЦБ.

Разрушая мифы о невозможности публичных «облаков»


Список документов внушительный. Давайте разбираться. Если не рассматривать информацию, отнесенную к государственной тайне, то запрета по размещению в публичных облаках любых банковских информационных систем нет. В том числе нет запретов на использование информационных систем (ИС), обрабатывающих персональные данные (ПДн). Единственное законодательное ограничение содержится в Федеральном Законе №242-ФЗ и касается физического размещения средств обработки и хранения ПДн на территории РФ при сборе ПДн.


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


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


ФСТЭК не возражает, ФСБ не против


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


ФСТЭК со своей стороны не предъявляет дополнительных требований по защите информации при использовании публичных облаков. Есть требования по защите среды виртуализации, но конкретно по защите облаков – нет. Приказ ФСТЭК №21, непосредственно посвященный обеспечению безопасности ПДн, говорит о необходимости защиты ключевого элемента облачных вычислений — «среды виртуализации» (ч.2, п.8), не запрещая напрямую или косвенно использовать внешние сервисы. Также данный приказ содержит конкретные меры по защите среды виртуализации, которые должны быть реализованы в зависимости от уровня защищенности персональных данных и наличия актуальных угроз (ЗСВ.1 – ЗСВ.10).


Кстати, об угрозах. Если посмотреть банк данных угроз, пользоваться которым при моделировании угроз активно призывает ФСТЭК (а в случае с госсистемами — явно требует), то в данном банке можно обнаружить множество угроз, реализация которых возможна исключительно в системах, расположенных в облаках.


ФСБ пока молчит. В ее документах отсутствует упоминание облаков.


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


Облачные намерения ЦБ


Свое видение по облачным технологиям, помимо вышеуказанных документов, есть и у регулятора финансовой отрасли – Центробанка (ЦБ). К тестированию облачных технологий финансовый регулятор приступил в 2011 году. Уже тогда ИТ-специалисты Банка России говорили, что в «облаке» должны быть защита от вредоносного кода, контроль и разграничение доступа на сетевом уровне, на уровне доступа к различным приложениям и виртуальным машинам. В 2014 году была создана рабочая группа, задачей которой стала разработка предложений по внесению необходимых изменений в законодательство, позволяющих более широко использовать электронный документооборот (ЭДО). По сути, тогда ЦБ стал готовиться к проведению финансовых операций в облачных сервисах. В мае 2016 года участники финрынка перешли на обязательный ЭДО с Банком России. Летом прошлого года на Международном финансовом конгрессе зампред ЦБ Ольга Скоробогатова объявила, что крупнейшие банки и ИТ-компании во главе с Банком России создают консорциум по внедрению новых технологий. Сообщество поставило целью изучить и затем внедрять технологии распределенных регистров (blockchain), облачных технологий, управления большими данными (big data) и развитие системы упрощенной идентификации.


В «Основных направлениях развития финансового рынка Российской Федерации на период 2016–2018 годов» говорится, что Банк России намерен «проработать подходы по предоставлению сервисов для малых поднадзорных финансовых организаций, позволяющих вести учет хоздеятельности без обязанности сдавать отчетность при предоставлении ЦБ права непосредственного использования данных бухгалтерского учета, в том числе с использованием облачных технологий». В рамках этого, согласно «Основным мероприятиям по развитию финансового рынка Российской Федерации на период 2016–2018 годов», в 2016 году был определен подход (план) работы ЦБ по созданию для малых поднадзорных организаций единой технологии по ведению учета хоздеятельности без обязанности сдавать отчетность. Иных мероприятий по «облачному» направлению в документе не значится.


Собственно, сам ЦБ уже использует облачные продукты в своей деятельности. К примеру, в марте этого года «Ведомости» со ссылкой на данные электронной торговой площадки сообщили, что Банк России намерен приобрести около 45 тыс. лицензии на облачный офисный продукт Office 365. ЦБ объяснял покупку продлением лицензий. В планах у финансового регулятора и создание с банками, входящими в ассоциацию «Финтех», платформы моментальных платежей (p2p). И понятно, что без облачных технологий здесь не обойтись.


Безобидный PCI DSS


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




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


Страх против технологий


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




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


Далее начинается работа над подготовкой или актуализацией внутренних документов банка, необходимых для успешного прохождения аудитов по СТО БР ИББС, положению ЦБ РФ №382-П, стандарту PCI DSS v.3.2 и др. с учетом новой модели потребления инфраструктурных ресурсов. Параллельно идет перенос ИС банка в облачную платформу.


В целом, мировая практика показывает, что компании, специализирующиеся на облачных сервисах, чаще всего, создают более качественную инфраструктуру и сервисы, чем это могут позволить себе большинство не профильных организаций. К примеру, Техносерв Cloud развернута на площадке дата-центра категории Tier III. Платформа состоит из двух физически изолированных частей (VDC и VDC.152; для государственных и финансовых организаций):


  • Сегмент «Закрытый» реализован с использованием решений VMware. Инфраструктура соответствует требованиям приказов №17 и №21 ФСТЭК для обеспечения до 1-го класса защиты ГИС и 1-го уровня защищенности ПДн включительно. Собственно говоря, решение позволяет, в том числе, государственным органам размещать ИС с наивысшими требованиями к информационной безопасности, что подтверждается наличием аттестата соответствия требованиям защиты информации, установленным ФСТЭК России.


  • Сегмент «Защищенный» подходит для финансовых учреждений, реализован с использованием решений VMware. Инфраструктура соответствует требованиям Положения ЦБ РФ №382-П, сертифицирована на соответствие требованиям стандарта PCI DSS.

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

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330598/


Метки:  

Материальная мотивация персонала в отделе интернет-маркетинга

Вторник, 20 Июня 2017 г. 12:09 + в цитатник
Материальная мотивация персонала

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

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

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

Проблемы


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

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

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

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

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

Общие принципы мотивации


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

Цели и задачи мотивации персонала:

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

Принципы мотивации, которые я заложила в основу модели стимулирования в отделе интернет-маркетинга:

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

Принципы мотивации персонала

  • Правила мотивации и распределения премий фиксируются в общедоступном корпоративном документе и корректируются не чаще 1 раза в 6 месяцев.
  • Цели и задачи для каждого из сотрудников формируются 1 раз в месяц и являются объективно достижимыми.
  • Цели и задачи распределяются исходя из квалификации специалистов. Все сотрудники знают персональные цели коллег.
  • Сотрудники отделов и групп в режиме реального времени могут контролировать процент выполнения как общего плана, так и своего собственного.
  • Размер премии каждого зависит от его личного вклада и общего вклада всех коллег из его группы.
  • Размер премии имеет прогрессивную шкалу и может варьироваться от 60% до 120% от максимально возможного.
  • Каждый может увеличить размер премии за счет продажи дополнительных услуг и разовых работ клиентам.

Немного о структуре отдела интернет-маркетинга


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

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


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

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

  1. премия для групп (руководители, менеджеры) — 80% от общего фонда;
  2. премия технических и финансовых специалистов — 20% от общего фонда.


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

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

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

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

Размер премии руководителя группы рассчитывается по следующей схеме:

  • Премиальный фонд группы, который рассчитывается пропорционально внесенному финансовому вкладу. Если SEO заработали 60% от оборота отдела, на долю его сотрудников придется 60% общего премиального фонда.
  • Потенциальная премия руководителя составляет 25% от премиального фонда группы.

Свою премию руководитель получает по следующей схеме:
Процент выполнения суммарного плана по итогам месяца Размер премии в % от потенциальной
Менее 90% от поставленного плана премия не выплачивается
90,00–99,99% от поставленного плана 60%
100,00–109,99% от поставленного плана 100%
110,00% и более от поставленного плана 120%

Дополнительные бонусы руководителя:

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

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

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

Анализируя работу схемы мотивации для руководителей групп в течение 10 месяцев, мы получили следующие цифры:

  • Повышенную премию руководитель получает в среднем 1 раз в четыре месяца.
  • Премию в размере 60% от РПП руководители получают каждый второй месяц.
  • Без премии руководители остаются 1 из четырех месяцев.
  • Премия в размере 100% от РПП составляет 60% от базового оклада руководителя, что для сотрудника является приятным и существенным бонусом.
  • В целом для компании удалось наладить работу, при которой руководители хорошо замотивированы на эффективность, принятый финансовый план агентства выполняется, а клиентская база растет.


Мотивация менеджеров
KPI для аккаунт-менеджеров формируется на основании 7 составляющих:

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

Премия аккаунт-менеджера рассчитывается по схеме:

Потенциальная премия менеджера = общая премия всех менеджеров группы * личная доля менеджера.

Финальный размер премии зависит от процента выполнения его личного плана:
Процент выполнения суммарного плана по итогам месяца Размер премии в % от потенциальной
Менее 90% от поставленного плана премия не выплачивается
90,00–99,99% от поставленного плана 60%
100,00–109,99% от поставленного плана 100%
110,00% и более от поставленного плана 120%

Дополнительные бонусы менеджера:

  1. за четкое выполнение регламентов ведения проектов;
  2. за наличие в течение отчетного месяца не менее 4 отзывов от клиентов со средним баллом 4 и выше;
  3. за внедрение новых технологий и методов работы, личный вклад;
  4. за ведение клиентов сотрудников, которые уходят в отпуск или на больничный.

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

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

Анализ работы схемы мотивации менеджеров в течение 10 месяцев показал

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

Мотивация технических и финансовых специалистов

KPI для технических и финансовых специалистов формируется на основании 6 составляющих:

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

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

Потенциальная премия специалиста = общая премия специалистов * коэффициент личного участия.

Финальный размер премии специалиста зависит от процента выполнения общего финансового плана отдела:
Процент выполнения суммарного плана по итогам месяца Размер премии в % от потенциальной
Менее 90% от поставленного плана премия не выплачивается
90,00–99,99% от поставленного плана 60%
100,00–109,99% от поставленного плана 100%
110,00% и более от поставленного плана 120%

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

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

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

Анализ работы схемы мотивации специалистов в течение 10 месяцев показал

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

ИТОГИ


Что дало внедрение схемы дополнительной мотивации отдела интернет-маркетинга по итогам 10 месяцев?

  1. Увеличился совокупный финансовый доход эффективных и квалифицированных сотрудников, что повысило их лояльность к компании.
  2. Удалось на 15% уменьшить текучку клиентской базы и ускорить темпы ее роста.
  3. Повысился общий уровень удовлетворенности клиентов качеством услуг.
  4. Стабилизировалась кривая выполнения финансового плана отдела.
  5. Получилось оптимизировать штат сотрудников, т.к. они четко понимают: увеличение персонала снижает нагрузку на каждого из них, но и уменьшает размер их личной премии.
  6. Удалось дать общий вектор достижения целей для всех групп, исключить конкуренцию между ними за клиентов и ресурсы.
Насколько необходима материальная мотивация в IT — компании?

Проголосовало 16 человек. Воздержалось 5 человек.

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

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331274/


Метки:  

Скорочтение: работает или нет? Часть 1

Вторник, 20 Июня 2017 г. 12:06 + в цитатник
Можно ли прочесть «программу на лето» за неделю и изучить рекомендованную литературу к экзамену за одну ночь? Разбираемся в вопросе, который всегда был актуален для студентов.

/ Фото Craig Sunter / CC

Фантастические возможности «быстрого чтения»


Каждый из нас в среднем успевает прочесть 200-400 слов в минуту, тогда как «скорочтецы», по их признаниям, могут увеличить этот показатель в 3-4 раза (до 1 000 или даже 1 700 слов в минуту соответственно). Пожалуй, один из самых известных скорочтецов – президент США Джон Ф. Кеннеди. По собственным словам, он не только владел этим навыком и (по некоторым оценкам) читал со скоростью 1 200 слов в минуту, но и стремился к тому, чтобы члены его команды также учились скорочтению и посещали курсы Эвелин Вуд (Эвелин Вуд в конце 1950-х гг. разработала основы обучения скорочтению, которые стали базой для ее учебника и школы «динамического чтения»).

Однако успехи Кеннеди меркнут на фоне других «звезд скорочтения» – Ким Пик (Kim Peek), прототип героя Дастина Хоффмана из фильма «Человек дождя», мог читать со скоростью 10 000 слов в минуту (8-10 секунд на стандартный книжный разворот). При этом он мог «распараллеливать процессы» – читать две страницы книги одновременно. Такая удивительная способность, правда, была достигнута не только (и не столько) упражнениями: Пик родился с врожденным пороком, который характеризуется отсутствием в мозге мозолистого тела (это сплетение нервных волокон обеспечивает связь между полушариями мозга), и потому (по некоторым предположениям) его полушария могли обрабатывать информацию независимо друг от друга.

Тем не менее, и рекорд в 10 000 слов в минуту оказался побит. Материалы американского исследования 1963 года сообщали о скорочтеце, который умудрялся прочитать более 17 000 слов в минуту. Самым быстрым чтецом в мире, согласно Книге рекордов Гиннеса (издание за 1990 год), оказался Говард Берг (Howard Berg), который утверждал, что читает книги со скоростью 25 000 слов в минуту (в среднем это более 80 стандартных страниц текста за 60 секунд). Чтение книги в таком режиме выглядит просто как быстрое перелистывание страниц!

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

Чтение и скорочтение: в чем разница


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

После нескольких скачков мы снова останавливаемся, чтобы «переварить» прочитанную фразу или предложение. На это обычно тратится еще 0,3–0,5 секунды. Поэтому Кит Рейнер (Keith Rayner), психолингвист из Массачусетского университета в Амхерсте признавал, что большинство людей, владеющих навыком чтения на уровне школьника старших классов или студента, и читающих «для удовольствия», делают это примерно с одинаковой скоростью – порядка 300 слов в минуту.

Как выглядит скорочтение


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

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

Быстрое последовательное визуальное предъявление (Rapid Serial Visual Presentation) – метод, который чаще других используется в современных программах по обучению скорочтению. Он состоит в том, что текст выводится на экран устройства пословно. По мере обучения растет и скорость смены слов на экране (один из наиболее известных примеров проектов, обучающих этой технике скорочтения, – Spritz) [о приложениях, проектах и методиках, помогающих читать если не быстрее, то качественнее, мы подробно расскажем во второй части материала].

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

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

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

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

Тимоти Ноа (Timothy Noah), писатель, редактор Politico, ведущий автор в Slate (2000–2011гг.)

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

Скорочтение – это не чтение [что бы это ни значило]


Выводы Рейнера оказываются не беспочвенны: научную работу, в которой они опубликованы, автор назвал «Движения глаз при чтении и обработке информации: результаты 20 лет исследований» (Eye movements in reading and information processing: 20 years of research). В этой работе Рейнер подтвеждает, что доля людей, читающих «на уровне студента колледжа» (в данном случае имеется в виду, что испытуемый имеет базовое образование и умеет читать не «по слогам»), попадающих по скорости чтения в интервал от 200 до 400 слов в минуту, составляет 95% (средняя скорость чтения, повторимся, равна примерно 300 словам в минуту).

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

Я окончил курсы скорочтения – нас заставляли водить пальцем вдоль страниц, – и прочел «Войну и мир» за двадцать минут. Там что-то про Россию

Вуди Аллен

Рональд Карвер (Ronald Carver), автор книги «Причины высоких и низких достижений в чтении» («The Causes of High and Low Reading Achievement») (издана в 1990 году) и профессор в сфере педагогики и психологии Университета Миссури в Канзас-Сити, также активно занимался вопросами изучения скорости чтения. Он тщательно изучил различные техники «ускорения» чтения и провел ряд собственных исследований. В частности, для тестирования он отобрал группу из 16 «суперзвезд» скорочтения. В нее входили как победители конкурсов по скорочтению, так и профессионалы, в чьи рабочие обязанности входило чтение большого объема текстов (среди них – колумнист «Нью-Йоркера» Фред Шапиро и редактор медицинского журнала).

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

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

Что стоит за впечатляющими результатами скорочтецов


К сожалению, выдающиеся результаты многих скорочтецов (за исключением Кима Пика) обусловлены их эго, а не реальными возможностями. Все тот же Карвер отмечает, что достижения Кеннеди в реальности могли быть более скромными – скорее всего, он мог читать со скоростью 500-600 слов в минуту, а бегло просматривать текст – со скоростью порядка 1000 слов в минуту (хотя это все равно в два раза быстрее «обычного» чтения).

Как же тогда появилась цифра в 1200 слов в минуту? Биограф Кеннеди Ричард Ривз (Richard Reeves) считает, что она фактически была «взята с потолка» – так предположил один из репортеров Time magazine, работавших в Белом доме. Репортер связывался со школой Эвелин Вуд, в которой обучался скорочтению Кеннеди, но не получил результатов его итогового тестирования – оно не проводилось, так как Кеннеди не завершил курс.

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

То же самое относится и к достижениям Говарда Берга. По словам Марка Пеннингтона (Mark Pennington), специалиста по вопросам чтения, «Представители Книги рекордов Гиннеса в то время не отличались любовью к перепроверке рекордов, которые они публиковали, и этот рекорд не был зафиксирован ими лично. Они поверили Бергу на слово, а он, вероятно, просто выдумал свой рекорд».

Кстати, в 1998 году Берга привлекла к ответственности Федеральная Торговая Комиссия США за «неверные» и «вводящие в заблуждение» маркетинговые приемы, связанные с продажей его продуктов по повышению скорости чтения. В итоге Бергу было запрещено рекламировать свой продукт как «систему, позволяющую любому – ребенку, взрослому, человеку с инвалидностью – научиться читать со скоростью в 800 слов в минуту и выше».

Итак, вкратце:


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

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

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

Супер-результаты скорочтецов – как правило, результат саморекламы. Если вы захотите обучиться какой-либо методике скорочтения, стоит рассчитывать на то, что вы сможете читать со скоростью 500-600 слов в минуту без существенной потери понимания текста. Результат в несколько тысяч (или десятков тысяч) слов в минуту едва ли достижим. Но даже 600 слов в минуту – это в два раза быстрее средней скорости чтения практически у всех, кто окончил школу или вуз.

Во второй части материала мы остановимся на том, какие методы скорочтения помогают сэкономить время, а какие не имеют ничего общего с физиологией и реальными возможностями человека. А также расскажем, какие еще методы и лайфхаки помогают узнавать из книг и статей больше за меньшее время.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331270/


Метки:  

[Перевод] HTTP/2 Server Push не так прост, как я думал

Вторник, 20 Июня 2017 г. 11:56 + в цитатник


Фото найдено на просторах Википедии


Привет! Меня зовут Макс Матюхин, я работаю PHP-программистом в Badoo. Мы постоянно изучаем различные возможности по ускорению работы нашего приложения и самыми интересными находками, конечно, делимся в нашем блоге на Хабре.


Вторая версия протокола HTTP обещает нам много улучшений, и одной из любопытных особенностей HTTP/2 является поддержка push. Теоретически эта возможность позволяет ускорить загрузку приложения. Недавно Jake Archibald написал большую статью, в которой проанализировал особенности реализации push в различных браузерах, и оказалось, что таких особенностей довольно много.


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


Я много раз слышал фразу «HTTP/2 Server Push справится с этим», когда дело касалось проблем с загрузкой страницы, но я мало что понимал в этой теме и потому решил разобраться подробнее.


HTTP/2 Server Push оказалась более сложной и низкоуровневой, чем я думал, но по-настоящему меня удивило то, насколько отличается её взаимодействие с различными браузерами – я-то всегда считал, что это полностью отработанная фича, готовая к использованию в production.


Я не хочу сказать, что HTTP/2 Server Push – это бесполезная ерунда; думаю, это действительно мощный инструмент, который со временем станет лучше. Но я уже не считаю его «серебряной пулей из золотого ружья».


Схема извлечения данных


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



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


Как работает HTTP/2 Server Push



Страница: Привет, example.com, могу я получить твою домашнюю страницу? 10:24
Сервер: Конечно! О, пока она отправляется, вот ещё таблица стилей, изображения, JavaScript и JSON. 10:24
Страница: Вау, класс! 10:24
Страница: Я читаю HTML, и, похоже, мне понадобится таблица сти… О, ты уже отправил мне её, круто! 10:25


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


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


Вот практически всё, что я знал об HTTP/2 Server Push. Звучало это довольно легко, но на деле всё оказалось совсем не так просто…


Что угодно может использовать push-кеш


HTTP/2 Server Push – это низкоуровневая сетевая фича: всё, что использует сетевой стек, может использовать и её.


Но любая фича полезна, если она непротиворечива и предсказуема. Я протестировал HTTP/2 Server Push по этим показателям, запушив ресурсы и попробовав их собрать с помощью:


  • fetch()
  • XMLHttpRequest

https://habrahabr.ru/post/331216/


Метки:  

[Из песочницы] GraphicsJS – графическая JavaScript библиотека

Вторник, 20 Июня 2017 г. 11:52 + в цитатник


Перевод статьи. Англоязычный оригинал опубликован на SitePoint – "Introducing GraphicsJS, a Powerful Lightweight Graphics Library".

HTML5 – основа основ современного веба. И сегодня, когда встает задача создать интерактивную графику, выбор чаще всего падает на такие технологии, как SVG и Canvas. Flash позабыт, Silverlight – редкая птица, обитающая на задворках веба, и почти никто не помнит сторонние ActiveX и Java-плагины.

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

В данной статье я хочу рассказать о GraphicsJS. Это мощная графическая JavaScript-библиотека с открытым исходным кодом, основанная на технологии SVG (VML для старых версий IE). Начну с краткого введения в основы GraphicsJS, а затем проиллюстрирую возможности библиотеки двумя небольшими, но наглядными примерами. Первый из них посвящен изобразительному искусству. Второй покажет, как менее чем за 50 строк кода сделать простую арт-игру в жанре таймкиллера.

Почему GraphicsJS


Библиотек, облегчающих работу с SVG, довольно много: в число лучших входят Rapha"el, Snap.svg и BonsaiJS. У каждой есть сильные и слабые стороны, однако их детальное сравнение будет темой одной из следующих публикаций. Данная же статья – исключительно о GraphicsJS, и сейчас я попытаюсь объяснить, чем эта библиотека хороша и выделяется среди прочих.

Во-первых, GraphicsJS весит совсем немного и обладает очень гибким JavaScript API. Она предоставляет богатые возможности для форматирования текста, а также виртуальный DOM – независимый от специфики HTML DOM в разных браузерах.

Во-вторых, код этой библиотеки был открыт только прошлой осенью. Компания AnyChart, один из лидеров в разработке решений для интерактивной визуализации данных, использует GraphicsJS как графический движок в своих коммерческих продуктах уже порядка трех лет (с момента выхода AnyChart 7.0), так что эта библиотека проверена в боевых условиях. (Дисклеймер: я руководитель R&D в AnyChart и ведущий разработчик GraphicsJS.)

В-третьих, в отличие от других продуктов AnyChart – JavaScript-библиотек для построения графиков – GraphicsJS бесплатна для использования как в коммерческих, так и в некоммерческих целях. Библиотека доступна на GitHub под лицензией Apache.

В-четвертых, GraphicsJS обладает кросс-браузерной совместимостью, включая поддержку Internet Explorer 6.0+, Safari 3.0+, Firefox 3.0+, Opera 9.5+. В старых версиях IE библиотека использует VML, во всех остальных браузерах – SVG.

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

Основы GraphicsJS


Для начала работы с GraphicsJS нужно подключить саму библиотеку и создать блочный элемент HTML-кода для будущего рисунка:


  
    
        
  
  
    

Затем надо построить рабочую область и что-нибудь в ней нарисовать, например прямоугольник, круг или какую-то другую фигуру:

// создаем рабочую область
var stage = acgraph.create('stage-container');
// рисуем прямоугольник
var stage.rect(25, 50, 350, 300);

Вот пример на CodePen, в котором мы идем чуть дальше и рисуем знак Даров Смерти.

Наш первый шедевр


Контур, заливка цветом и узором


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

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

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

// создаем рабочую область
var stage = acgraph.create('stage-container');

// рисуем рамку
var frame = stage.rect(25, 50, 350, 300);

// рисуем дом
var walls = stage.rect(50, 250, 200, 100);
var roof  = stage.path()
  .moveTo(50, 250)
  .lineTo(150, 180)
  .lineTo(250, 250)
  .close();

// рисуем человечка
var head = stage.circle(330, 280, 10);
var neck = stage.path().moveTo(330, 290).lineTo(330, 300);
var kilt = stage.triangleUp(330, 320, 20);
var rightLeg = stage.path().moveTo(320, 330).lineTo(320, 340);
var leftLeg = stage.path().moveTo(340, 330).lineTo(340, 340);

Результат можно посмотреть на CodePen.

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

Кроме того, в GraphicsJS можно активно применять цепные вызовы (например, stage.path().moveTo(320, 330).lineTo(320, 340);), что позволяет сократить код. Использовать эту возможность нужно аккуратно, но при правильном подходе цепной вызов действительно делает код более компактным и легко читаемым.

Теперь можно дать получившуюся у нас картинку какому-нибудь ребенку и попросить раскрасить ее – ведь даже ребенок способен освоить следующий прием:

// раскрашиваем картинку
// элегантная рамка
frame.stroke(["red", "green", "blue"], 2, "2 2 2");
// кирпичные стены
walls.fill(acgraph.hatchFill('horizontalbrick'));
// соломенная крыша
roof.fill("#e4d96f");
// клетчатый килт
kilt.fill(acgraph.hatchFill('plaid'));

Теперь наш пример выглядит вот так.

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

// 169 - символьный код значка копирайта
var  text = acgraph.text().text(String.fromCharCode(169)).opacity(0.2);
var  pattern_font = stage.pattern(text.getBounds());
pattern_font.addChild(text);
// заполняем паттерном все изображение
frame.fill(pattern_font);

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


Рисуем арт-игру (таймкиллер) менее чем за 50 строк кода


В следующей части статьи я покажу, как с помощью GraphicsJS нарисовать игру-кликер типа Cookie Clicker меньше чем за 50 строк кода.

Название этой игры – «Дворник на ветру». В ней пользователь выступает в роли дворника, который подметает улицу ветреным осенним днем. Здесь частично используется код примера с процедурно генерируемыми листьями из галереи GraphicsJS.

Финальный вариант игры можно посмотреть на CodePen (или в конце этой статьи).

Слои, zIndex, виртуальный DOM


Начнем с создания рабочей области (как в предыдущем примере). И затем объявим несколько исходных переменных:

// создаем рабочую область
var stage = acgraph.create("stage-container");

// цветовые палитры для листьев
var palette_fill = ['#5f8c3f', '#cb9226', '#515523', '#f2ad33', '#8b0f01']; 
var palette_stroke = ['#43622c', '#8e661b', '#393b19', '#a97924', '#610b01'];

// счетчик
var leavesCounter = 0;

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

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

// создаем надпись для отображения счетчика
var counterLabel = stage.text(10,10, "Swiped: 0", {fontSize: 20});

// слой для листьев
var gameLayer = stage.layer().zIndex(counterLabel.zIndex()-1);

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

Трансформации


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

function drawLeaf(x, y) {
  // выбираем произвольный цвет из палитры
  var index = Math.floor(Math.random() * 5);
  var fill = palette_fill[index];
  var stroke = palette_stroke[index];

  // генерируем произвольные масштабирующий коэффициент и угол поворота
  var scale = Math.round(Math.random() * 30) / 10 + 1;
  var angle = Math.round(Math.random() * 360 * 100) / 100;

  // создаем новый путь (лист)
  var path = acgraph.path();

  // задаем раскраску и рисуем лист
  path.fill(fill).stroke(stroke, 1, 'none', 'round', 'round');
  var size = 18;
  path.moveTo(x, y)
    .curveTo(x + size / 2, y - size / 2, x + 3 * size / 4, y + size / 4, x + size, y)
    .curveTo(x + 3 * size / 4, y + size / 3, x + size / 3, y + size / 3, x, y);

  // применяем произвольные трансформации
  path.scale(scale, scale, x, y).rotate(angle, x, y);

  return path; 
};

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

Работа с событиями


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

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

path.listen("mouseover", function(){
  path.remove();
  counterLabel.text("Swiped: " + leavesCounter++);
  if (gameLayer.numChildren() < 200) shakeTree(300); 
});

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

if (gameLayer.numChildren() < 200) shakeTree(300); 

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

Библиотека GraphicsJS дает возможность использовать виртуальный DOM, абстракцию HTML DOM, легкую и независимую от специфики применения SVG/VML в разных браузерах. Эта технология пригодится для реализации целого ряда полезных функций, таких как контроль за всеми объектами и слоями, применение трансформаций к группам и оптимизация рендеринга с помощью методов, которые позволяют отслеживать и контролировать весь его процесс.

Оптимизация производительности


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

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

function shakeTree(n){
  stage.suspend(); // приостанавливаем рендеринг
  for (var i = 0; i < n; i++) {
    var x = Math.random() * stage.width()/2 + 50;
    var y = Math.random() * stage.height()/2 + 50;
    gameLayer.addChild(drawLeaf(x, y)); // добавляем лист
  }

  stage.resume(); // возобновляем рендеринг
}

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

// первый раз сбрасываем все листья
shakeTree(500);

Ну и наконец, сбрасываем все листья, вызвав метод shakeTree().

Конечный результат



Заключение


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

Буду рад получить обратную связь по поводу GraphicsJS в комментариях. Уже используете эту библиотеку? Готовы ли рассмотреть возможность ее применения в новом проекте? Интересно было бы узнать, почему, равно как и почему нет. Кстати, сейчас я работаю над созданием списка лучших графических JavaScript-библиотек и статьей, где они будут сравниваться, – так что предлагаю написать в комментариях, какие библиотеки вы бы хотели там видеть.

Cсылки





Автор оригинальной статьи на SitePoint: Роман Любушкин (Roman Lubushkin).
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331272/


Фреймворк Jobs-To-Be-Done: наш опыт использования

Вторник, 20 Июня 2017 г. 11:51 + в цитатник


Outcome-driven innovation — это фреймворк, в основе которого приоритизация планов разработки компании на основе задач, для которых клиенты эти продукты покупают — Jobs to be done. Фреймворк дает хорошее методическое описание и обоснование идей и практик, которые каждый product owner, по идее, и так применяет или должен применять, но обычно — интуитивно и на менее системном уровне.

На Codefest 2017 Аркадий Рушкевич, product-manager Wrike, рассказал о собственном опыте использования Jobs to be done и ODI — как и зачем Wrike начал заниматься этим, какие плюсы и минусы мы увидели, чего добились.

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







Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330868/


Метки:  

[Перевод] Введение в алгоритм A*

Вторник, 20 Июня 2017 г. 11:24 + в цитатник
При разработке игр нам часто нужно находить пути из одной точки в другую. Мы не просто стремимся найти кратчайшее расстояние, нам также нужно учесть и длительность движения. Передвигайте звёздочку (начальную точку) и крестик (конечную точку), чтобы увидеть кратчайший путь. [Прим. пер.: в статьях этого автора всегда много интерактивных вставок, рекомендую сходить в оригинал статьи.]



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

Представление карты


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

Вход: алгоритмы поиска по графу, в том числе и A*, получают в качестве входных данных граф. Граф — это набор точек («узлов») и соединений («рёбер») между ними. Вот граф, который я передал A*:



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



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



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

А что, если мы превратим двери в рёбра?



А если мы применим сетку для поиска пути?



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

Алгоритмы


Существует множество алгоритмов, работающих с графами. Я рассмотрю следующие:



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



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



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

Я начну с самого простого — поиска в ширину, и буду добавлять функции, постепенно превращая его в A*.

Поиск в ширину


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




Как это реализовать? Повторяем эти шаги, пока граница не окажется пустой:

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

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




Алгоритм описывается всего в десяти строках кода на Python:

frontier = Queue()
frontier.put(start )
visited = {}
visited[start] = True

while not frontier.empty():
   current = frontier.get()
   for next in graph.neighbors(current):
      if next not in visited:
         frontier.put(next)
         visited[next] = True

В этом цикле заключается вся сущность алгоритмов поиска по графу этой статьи, в том числе и A*. Но как нам найти кратчайший путь? Цикл на самом деле не создаёт путей, он просто говорит нам, как посетить все точки на карте. Так получилось потому, что поиск в ширину можно использовать для гораздо большего, чем просто поиск путей. В этой статье я показываю, как он применяется в играх tower defense, но его также можно использовать в картах расстояний, в процедурной генерации карт и многом другом. Однако здесь мы хотим использовать его для поиска путей, поэтому давайте изменим цикл так, чтобы отслеживать, откуда мы пришли для каждой посещённой точки, и переименуем visited в came_from:

frontier = Queue()
frontier.put(start )
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()
   for next in graph.neighbors(current):
      if next not in came_from:
         frontier.put(next)
         came_from[next] = current

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



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

current = goal 
path = [current]
while current != start: 
   current = came_from[current]
   path.append(current)
path.append(start) # optional
path.reverse() # optional

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

Ранний выход


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



Код достаточно прямолинеен:

frontier = Queue()
frontier.put(start )
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal: 
      break           

   for next in graph.neighbors(current):
      if next not in came_from:
         frontier.put(next)
         came_from[next] = current

Стоимость перемещения


Пока мы делали шаги с одинаковой стоимостью. В некоторых случаях поиска путей у разных типов движения есть разная стоимость. Например, в Civilization движение через равнины или пустыню может стоить 1 очко движения, а движение через лес — 5 очков движения. На карте в самом начале статьи прохождение через воду стоит в 10 раз дороже, чем движение по траве. Ещё одним примером является диагональное движение в сетке, которое стоит больше, чем движение по осям. Нам нужно, чтобы поиск пути учитывал эту стоимость. Давайте сравним количество шагов от начала с расстоянием от начала:



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

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      new_cost = cost_so_far[current] + graph.cost(current, next)
      if next not in cost_so_far or new_cost < cost_so_far[next]:
         cost_so_far[next] = new_cost
         priority = new_cost
         frontier.put(next, priority)
         came_from[next] = current

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




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

Эвристический поиск


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

def heuristic(a, b):
   # Manhattan distance on a square grid
   return abs(a.x - b.x) + abs(a.y - b.y)

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

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      if next not in came_from:
         priority = heuristic(goal, next)
         frontier.put(next, priority)
         came_from[next] = current

Давайте посмотрим, как это работает:




Ого! Потрясающе, правда? Но что случится на более сложной карте?




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

Алгоритм A*


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

Код очень похож на алгоритм Дейкстры:

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break
   
   for next in graph.neighbors(current):
      new_cost = cost_so_far[current] + graph.cost(current, next)
      if next not in cost_so_far or new_cost < cost_so_far[next]:
         cost_so_far[next] = new_cost
         priority = new_cost + heuristic(goal, next)
         frontier.put(next, priority)
         came_from[next] = current

Сравните алгоритмы: алгоритм Дейкстры вычисляет расстояние от начальной точки. Жадный поиск по первому наилучшему совпадению оценивает расстояние до точки цели. A* использует сумму этих двух расстояний.



Попробуйте в оригинале статьи делать отверстия в разных местах стены. Вы обнаружите, что жадный поиск находит правильный ответ, A* тоже его находит, исследуя ту же область. Когда жадный поиск по первому наилучшему находит неверный ответ (более длинный путь), A* находит правильный, как и алгоритм Дейкстры, но всё равно исследует меньше, чем алгоритм Дейкстры.

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

И… на этом всё! В этом и заключается алгоритм A*.

Дополнительное чтение


Вы готовы реализовать его? Попробуйте использовать готовую библиотеку. Если вы хотите реализовать его самостоятельно, то у меня есть инструкция по пошаговой реализации графов, очередей и алгоритмов поиска пути на Python, C++ и C#.

Какой алгоритм стоит использовать для поиска путей на игровой карте?

  • Если вам нужно найти пути из или ко всем точкам, используйте поиск в ширину или алгоритм Дейкстры. Используйте поиск в ширину, если стоимость движения одинакова. Используйте алгоритм Дейкстры, если стоимость движения изменяется.
  • Если нужно найти пути к одной точке, используйте жадный поиск по наилучшему первому или A*. В большинстве случаев стоит отдать предпочтение A*. Когда есть искушение использовать жадный поиск, то подумайте над применением A* с «недопустимой» эвристикой.

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

А как насчёт производительности? Лучше всего устранить ненужные точки графа. Если вы используете сетку, то прочитайте это. Уменьшение размера графа помогает всем алгоритмам поиска по графам. После этого используйте простейший из возможных алгоритмов. Простые очереди выполняются быстрее. Жадный поиск обычно выполняется быстрее, чем алгоритм Дейкстры, но не обеспечивает оптимальных путей. Для большинства задач по поиску путей оптимальным выбором является A*.

А что насчёт использования не на картах? Я использовал в статье карты, потому что думаю, что на них проще объяснить работу алгоритма. Однако эти алгоритмы поиска по графам можно использовать на любых графах, не только на игровых картах, и я пытался представить код алгоритма в виде, не зависящем от двухмерных сеток. Стоимость движения на картах превращается в произвольные веса рёбер графа. Эвристики перенести на произвольные карты не так просто, необходимо создавать эвристику для каждого типа графа. Для плоских карт хорошим выбором будут расстояния, поэтому здесь мы использовали их.

Я написал ещё много всего о поиске путей здесь. Не забывайте, что поиск по графам — это только одна часть того, что вам нужно. Сам по себе A* не обрабатывает такие аспекты, как совместное движение, перемещение препятствий, изменение карты, оценку опасных областей, формации, радиусы поворота, размеры объектов, анимацию, сглаживание путей и многое другое.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331192/


Метки:  

Надстройка над биткойн-блокчейном — Lightning Network

Вторник, 20 Июня 2017 г. 11:14 + в цитатник
Lightning Network (LN), вероятно, одно из самых ожидаемых нововведений для биткойн-блокчейна. Идея, впервые предложенная Джозефом Пуном (Joseph Poon) и Таджем Дрийа (Tadge Dryja) около двух лет назад. Lightning Network обещает поддержку неограниченного количества транзакций между пользователями, выполняемых в сети платежных каналов, развернутой поверх блокчейна. При этом система наследует надежность биткойн-блокчейна.

Над реализацией LN-протокола работают сразу несколько компаний, среди которых Lightning Labs, Blockstream, ACINQ, а также Bitfury. Эта технология позволит производить микроплатежи с использованием биткойнов, что существенно расширит возможности и сферу применимости криптовалюты. В этом материале мы поговорим, на чем строится концепция Lightning Network и как работает эта сеть.

/ изображение Iraia Mart'inez CC

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

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

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


Высокоуровневая схема сети Lightning

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

Установление двунаправленного канала


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

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

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

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

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

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

Работа в сети и трехсторонний обмен


Если кто-то из участников двустороннего канала захочет передать биткойны третьей стороне, он сможет использовать своего «партнера» в качестве гаранта сделки (в том случае, если у последнего уже установлен платежный канал с третьей стороной). Допустим, Алиса хочет переслать один биткойн третьему участнику, скажем Карлосу. Она может отправить этот биткойн Бобу, после чего Боб отправит его Карлосу как посредник.

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

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

Маршрутизация в Lightning Network


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

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

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

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


Схема алгоритма маршрутизации Flare

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

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

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

Использовав эту спецификацию, команде исследователей из ACINQ удалось реализовать и проверить алгоритм на 2,5 тыс. узлах AWS. Правда, часть, которая была протестирована, являлась лишь первым из двух этапов маршрутизации Lightning. Однако по результатам тестирования удалось установить, что алгоритм Flare способен определить путь платежа за 5 секунд с вероятностью его реализации в 80%. И это уже очень хороший шаг к коммерческой реализации сети Lightning.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331268/


Метки:  

[Перевод] Хостинг-провайдер заплатил миллион долларов хакерам-вымогателям

Вторник, 20 Июня 2017 г. 11:06 + в цитатник


10 июня южнокорейская хостинговая компания NAYANA стала жертвой атаки вируса-вымогателя Erebus (обнаружен Trend Micro как RANSOM_ELFEREBUS.A). В результате было заражено 153 Linux-сервера и более 3400 бизнес-сайтов, которые размещает хостинг-провайдер.

В сообщении, опубликованном на сайте NAYANA 12 июня, компания сообщила, что злоумышленники потребовали беспрецедентный по размеру выкуп в 550 биткоинов (BTC) или 1,62 миллиона долларов за расшифровку файлов на всех заражённых серверах. Вот часть переговоров с вымогателями:
Мой босс сказал мне дать вам хорошую цену, так как вы покупаете много машин,
550 BTC
Если у вас недостаточно денег, вам нужно взять кредит

У вас 40 сотрудников,
Годовой оклад каждого сотрудника 30 000 долларов США
Все сотрудники 30 000 * 40 = $ 1 200 000
Все сервера 550BTC = $ 1,620,000

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

Позднее 14 июня NAYANA сообщила о договорённости по выплате в рассрочку суммы в размере 397,6 BTC (около 1,01 миллиона долларов США по состоянию на 19 июня 2017 года). 17 июня компания сообщила, что проведён второй из трёх платежей. 18 июня NAYANA начала восстанавливать сервера партиями. В настоящее время на некоторых серверах второй партии имеются ошибки баз данных. Третий платеж будет выплачен после успешного восстановления первой и второй партии серверов.

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

Erebus был впервые замечен в сентябре 2016 года, тогда он распространялся через вредоносную рекламу. Вновь он появился в феврале 2017 года, уже используя метод, который обходил контроль учётной записи Windows. Вот некоторые из технических подробностей, которые доступны о Linux-версии Erebus:


Рисунок 1: Erebus имеет многоязычное уведомление о выкупе (вариант на английском языке выше)


Рисунок 2: Кадр демонстрационного видео от злоумышленников, в котором показано, как расшифровать файлы

Возможный вектор вирусных атак


Что касается того, как заражаются Linux-системы, мы можем только предположить, что Erebus, возможно, использовал эксплойт Linux. Например, на основе информации с открытым исходным кодом исследователи установили, что сайт NAYANA работает на ядре Linux 2.6.24.2, которое было скомпилировано ещё в 2008 году. Поэтому угрозы безопасности, такие как DIRTY COW, могут предоставить злоумышленникам root-доступ к уязвимым Linux-системам.

Кроме того, на веб-сайте NAYANA используются устаревшие версии Apache 1.3.36 и PHP 5.1.4, обе из которых были выпущены еще в 2006 году. Используемая NAYANA версия Apache запускается под пользователем nobody(uid=99), что указывает на то, что некоторые ранее известные эксплойты также могли быть использованы в атаке.


Рисунок 3: Erebus Linux Rasomware

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

Процедура шифрования


Каждый файл, зашифрованный Erebus, будет иметь следующий формат:

Header (0x438 bytes)
RSA-2048-encrypted original filename
RSA-2048-encrypted AES key
AES-encrypted RC4 key
RC4-encrypted data

Сначала каждый отдельный файл, разбивается на блоки по 500 КБ и скремблируется с помощью алгоритма шифрования RC4 со случайно сгенерированными ключами. Затем ключ RC4 кодируется алгоритмом шифрования AES. AES-ключ снова зашифровывается с использованием алгоритма RSA-2048, открытый ключ которого сохраняется в файле.

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

Целевые типы файлов


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

В таблице ниже указаны папки, которые ищет Erebus.
var/www/ — папки, в которых хранятся файлы/данные веб-сайтов, а файлы ibdata используются в MySQL:
Included directories: Excluded directories:
var/www/ $/bin/
Included files: $/boot/
ibdata0 $/dev/
ibdata1 $/etc/
ibdata2 $/lib/
ibdata3 $/lib64/
ibdata4 $/proc/
ibdata5 $/run/
ibdata6 $/sbin/
ibdata7 $/srv/
ibdata8 $/sys/
ibdata9 $/tmp/
ib_logfile0 $/usr/
ib_logfile1 $/var/
ib_logfile2 /.gem/
ib_logfile3 /.bundle/
ib_logfile4 /.nvm/
ib_logfile5 /.npm/

Как защититься?


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

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


Хеш-функции SHA256 RANSOM_ELFEREBUS.A:
0b7996bca486575be15e68dba7cbd802b1e5f90436ba23f802da66292c8a055f
d889734783273b7158deeae6cf804a6be99c3a5353d94225a4dbe92caf3a3d48

Мы обновим этот пост в случае, если будет получена новая информация об особенностях распространения вируса.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331266/


Как PVS-Studio может помочь в поиске уязвимостей?

Вторник, 20 Июня 2017 г. 10:33 + в цитатник


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


PVS-Studio — инструмент, предотвращающий не только ошибки, но и уязвимости


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

Picture 4



PVS-Studio — статический анализатор кода, который ищет ошибки (и уязвимости, в чем вы убедитесь далее) в программах, написанных на C, C++, C#. Работает под Windows и Linux, умеет встраиваться в IDE Visual Studio в качестве плагина. На данный момент в анализаторе реализовано свыше 450 диагностических правил, каждое из которых сопровождается документацией.

На момент написания статьи с помощью PVS-Studio проверено более 280 open source проектов, в которых было найдено свыше 11 000 ошибок. Интересно, сколько из этих ошибок являются уязвимостями…

Загрузить и попробовать PVS-Studio можно на официальном сайте.

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

Терминология


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

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

CVE (Common Vulnerabilities and Exposures) — ошибки программы, которые могут быть непосредственно использованы злоумышленниками.

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

PVS-Studio: иное позиционирование


Предыстория


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

Однако со временем оказалось, что некоторые из ошибок, обнаруживаемых PVS-Studio, могут быть трактованы более серьезным образом. Например, неправильное использование функции printf может повлечь за собой куда более негативные последствия, нежели вывод неправильного сообщения в stdout. Когда стало понятно, что с помощью многих диагностических правил можно обнаруживать не просто ошибки, а потенциальные уязвимости (CWE), было принято решение подойти к вопросу более детально и посмотреть, как соотносятся диагностические правила PVS-Studio и CWE.

Отношение предупреждений PVS-Studio и CWE


По результатам работы по выявлению взаимосвязей между предупреждениями PVS-Studio и CWE была составлена следующая таблица:
CWE PVS-Studio CWE Description
CWE-14 V597 Compiler Removal of Code to Clear Buffers
CWE-36 V631, V3039 Absolute Path Traversal
CWE-121 V755 Stack-based Buffer Overflow
CWE-122 V755 Heap-based Buffer Overflow
CWE-123 V575 Write-what-where Condition
CWE-129 V557, V781, V3106 Improper Validation of Array Index
CWE-190 V636 Integer Overflow or Wraparound
CWE-193 V645 Off-by-one Error
CWE-252 V522, V575 Unchecked Return Value
CWE-253 V544, V545, V676, V716, V721, V724 Incorrect Check of Function Return Value
CWE-390 V565 Detection of Error Condition Without Action
CWE-476 V522, V595, V664, V757, V769, V3019, V3042, V3080, V3095, V3105, V3125 NULL Pointer Dereference
CWE-481 V559, V3055 Assigning instead of comparing
CWE-482 V607 Comparing instead of Assigning
CWE-587 V566 Assignment of a Fixed Address to a Pointer
CWE-369 V609, V3064 Divide By Zero
CWE-416 V723, V774 Use after free
CWE-467 V511, V512, V568 Use of sizeof() on a Pointer Type
CWE-805 V512, V594, V3106 Buffer Access with Incorrect Length Value
CWE-806 V512 Buffer Access Using Size of Source Buffer
CWE-483 V640, V3043 Incorrect Block Delimitation
CWE-134 V576, V618, V3025 Use of Externally-Controlled Format String
CWE-135 V518, V635 Incorrect Calculation of Multi-Byte String Length
CWE-462 V766, V3058 Duplicate Key in Associative List (Alist)
CWE-401 V701, V773 Improper Release of Memory Before Removing Last Reference ('Memory Leak')
CWE-468 V613, V620, V643 Incorrect Pointer Scaling
CWE-588 V641 Attempt to Access Child of a Non-structure Pointer
CWE-843 V641 Access of Resource Using Incompatible Type ('Type Confusion')
CWE-131 V512, V514, V531, V568, V620, V627, V635, V641, V645, V651, V687, V706, V727 Incorrect Calculation of Buffer Size
CWE-195 V569 Signed to Unsigned Conversion Error
CWE-197 V642 Numeric Truncation Error
CWE-762 V611, V780 Mismatched Memory Management Routines
CWE-478 V577, V719, V622, V3002 Missing Default Case in Switch Statement
CWE-415 V586 Double Free
CWE-188 V557, V3106 Reliance on Data/Memory Layout
CWE-562 V558 Return of Stack Variable Address
CWE-690 V522, V3080 Unchecked Return Value to NULL Pointer Dereference
CWE-457 V573, V614, V730, V670, V3070, V3128 Use of Uninitialized Variable
CWE-404 V611, V773 Improper Resource Shutdown or Release
CWE-563 V519, V603, V751, V763, V3061, V3065, V3077, V3117 Assignment to Variable without Use ('Unused Variable')
CWE-561 V551, V695, V734, V776, V779, V3021 Dead Code
CWE-570 V501, V547, V517, V560, V625, V654, V3022, V3063 Expression is Always False
CWE-571 V501, V547, V560, V617, V654, V694, V768, V3022, V3063 Expression is Always True
CWE-670 V696 Always-Incorrect Control Flow Implementation
CWE-674 V3110 Uncontrolled Recursion
CWE-681 V601 Incorrect Conversion between Numeric Types
CWE-688 V549 Function Call With Incorrect Variable or Reference as Argument
CWE-697 V556, V668 Insufficient Comparison

Таблица N1 — Черновой вариант таблицы соответствий CWE и диагностик PVS-Studio


Это не окончательный вариант таблицы, но он даёт некоторое представление о том, как соотносятся между собой предупреждения PVS-Studio и CWE. Теперь стало понятно, что PVS-Studio успешно находит (и всегда находил) в коде программ не просто баги, а потенциальные уязвимости, то есть CWE. На эту тему было написано несколько статей, их перечень приведён в конце текущей статьи.

Базы CVE


Picture 2



Потенциальная уязвимость (CWE) — ещё не есть уязвимость (CVE). Реальные уязвимости, найденные как в open source, так и в проприетарных проектах, собраны на сайте http://cve.mitre.org. Там можно посмотреть описание конкретной уязвимости, найти дополнительные ссылки (например, на обсуждение, бюллетень исправлений уязвимостей, ссылки на коммиты, закрывающие уязвимости, и т.п.). При желании эту базу можно выгрузить целиком в интересующем формате. На момент написания статьи база в текстовом формате представляла собой .txt файл размером порядка 100Мб и объёмом более 2.7 млн строк. Весьма внушительно, согласитесь.

Picture 6



В ходе работы я нашёл ещё один интересный ресурс, который может быть полезен заинтересованным — http://www.cvedetails.com/. Он удобен тем, что даёт такие возможности, как:
  • поиск CVE по идентификатору CWE;
  • поиск CVE в определённом продукте;
  • просмотр статистики появления/исправления уязвимостей;
  • просмотр различных таблиц данных, так или иначе связанных с CVE (например, рейтинг фирм, в программных продуктах которых было найдено наибольшее количество уязвимостей);
  • и т.п.

Некоторые CVE, которые могли бы быть найдены с помощью PVS-Studio


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

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

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

illumos-gate


Picture 7



Первая уязвимость, о которой пойдёт речь, была обнаружена в исходном коде проекта illumos-gate. illumos-gate — проект с открытым исходным кодом (доступным в репозитории на GitHub), формирующий ядро операционной системы, уходящей корнями к Unix и BSD.

Уязвимость имеет кодовое название CVE-2014-9491.

Описание CVE-2014-9491: The devzvol_readdir function in illumos does not check the return value of a strchr call, which allows remote attackers to cause a denial of service (NULL pointer dereference and panic) via unspecified vectors.

Проблемный код находился в функции devzvol_readdir и выглядел следующим образом:
static int devzvol_readdir(....)
{
  ....
  char *ptr;
  ....
  ptr = strchr(ptr + 1, '/') + 1;
  rw_exit(&sdvp->sdev_contents);
  sdev_iter_datasets(dvp, ZFS_IOC_DATASET_LIST_NEXT, ptr);
  ....
}

Функция strchr возвращает указатель на первое вхождение символа, переданного в качестве второго аргумента. Однако функция может вернуть нулевой указатель в случае, если символ не был найден в исходной строке. Но этот факт был забыт или не учтён. В итоге к возвращаемому значению просто прибавляется 1, результат записывается в переменную ptr, и дальше с указателем работают «как есть». Если полученный указатель был нулевым, то, прибавив к нему единицу, мы получим невалидный указатель, проверка которого на неравенство NULL не будет означать его валидности. При определённых условиях этот код мог приводить к возникновению kernel panic.

PVS-Studio обнаруживает эту уязвимость при помощи диагностического правила V769, сообщая, что указатель, возвращённый функцией strchr, может быть нулевым, и при этом он портится (из-за прибавления 1):

V769 The 'strchr(ptr + 1, '/')' pointer in the 'strchr(ptr + 1, '/') + 1' expression could be nullptr. In such case, resulting value will be senseless and it should not be used.

Network Audio System


Network Audio System (NAS) — клиент-серверная система передачи звука с открытым исходным кодом, доступным на SourceForge. NAS работает как под Unix, так и под Windows.

Уязвимость, обнаруженная в этом проекте, имеет кодовое название CVE-2013-4258.

Описание CVE-2013-4258: Format string vulnerability in the osLogMsg function in server/os/aulog.c in Network Audio System (NAS) 1.9.3 allows remote attackers to cause a denial of service (crash) and possibly execute arbitrary code via format string specifiers in unspecified vectors, related to syslog.

Код выглядел следующим образом:
....
if (NasConfig.DoDaemon) {   /* daemons use syslog */
  openlog("nas", LOG_PID, LOG_DAEMON);
  syslog(LOG_DEBUG, buf);
  closelog();
} else {
  errfd = stderr;
....

В этом фрагменте кода неправильно используется функция syslog. Объявление этой функции выглядит следующим образом:
void syslog(int priority, const char *format, ...);

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

Если верить записи в базе SecurityFocus, уязвимость проявлялась в операционных системах Debian и Gentoo.

Что же PVS-Studio? PVS-Studio обнаруживает эту ошибку с помощью диагностического правила V618 и выдаёт предупреждение:

V618 It's dangerous to call the 'syslog' function in such a manner, as the line being passed could contain format specification. The example of the safe code: printf("%s", str);

Обнаруживать эту и подобные ошибки помогает реализованный в анализаторе механизм аннотирования функций и большое количество аннотаций — сейчас их количество превышает 6500 для C, C++ и 900 для C#.

Правильный вызов этой функции, закрывающий данную уязвимость, выглядит следующим образом:
syslog(LOG_DEBUG, "%s", buf);

Здесь используется строка формата "%s", что делает вызов функции syslog безопасным.

Ytnef (Yerase's TNEF Stream Reader)


Ytnef — программа с открытым исходным кодом, доступным на GitHub. Предназначена для декодирования TNEF потоков, например, созданных в Outlook.

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

Описание CVE-2017-6298: An issue was discovered in ytnef before 1.9.1. This is related to a patch described as «1 of 9. Null Pointer Deref / calloc return value not checked.»

Все исправленные места, в которых могло произойти разыменование нулевого указателя, имели приблизительно один и тот же вид:
vl->data = calloc(vl->size, sizeof(WORD));
temp_word = SwapWord((BYTE*)d, sizeof(WORD));
memcpy(vl->data, &temp_word, vl->size);

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

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

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

V575 The potential null pointer is passed into 'memcpy' function. Inspect the first argument.

Анализатор обнаружил, что потенциально нулевой указатель, полученный в результате вызова функции calloc, передаётся в функцию memcpy без проверки на неравенство NULL.

Таким образом, PVS-Studio обнаружил и эту уязвимость. А ведь если бы анализатор регулярно использовался в процессе написания кода, то можно было бы предотвратить эту проблему ещё даже до того, как она попала бы в систему контроля версий…

MySQL


Picture 8



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

Рассмотрим одну из уязвимостей, обнаруженных в данном проекте — CVE-2012-2122.

Описание CVE-2012-2122: sql/password.c in Oracle MySQL 5.1.x before 5.1.63, 5.5.x before 5.5.24, and 5.6.x before 5.6.6, and MariaDB 5.1.x before 5.1.62, 5.2.x before 5.2.12, 5.3.x before 5.3.6, and 5.5.x before 5.5.23, when running in certain environments with certain implementations of the memcmp function, allows remote attackers to bypass authentication by repeatedly authenticating with the same incorrect password, which eventually causes a token comparison to succeed due to an improperly-checked return value.

Вот так выглядит код, содержащий уязвимость:
typedef char my_bool;
my_bool
check_scramble(const char *scramble_arg, const char *message,
               const uint8 *hash_stage2)
{
  ....
  return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}

Тип возвращаемого значения функции memcmpint, а тип возвращаемого значения функции check_scramblemy_bool, фактически — char. В результате происходит неявное приведение int к char, при котором отбрасываются значения старших битов. Это приводило к тому, что примерно в 1 случае из 256 удавалось подключиться с любым паролем, зная имя пользователя. Ввиду того, что 300 попыток подключения занимали меньше секунды, эта защита настолько же хороша, как и её отсутствие. Подробнее про эту уязвимость можно почитать по ссылкам, упомянутым на странице CVE-2012-2122.

PVS-Studio обнаруживает эту проблему с помощью диагностического правила V642. Предупреждение выглядит следующим образом:

V642 Saving the 'memcmp' function result inside the 'char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. password.c

Выходит, что и эту уязвимость удалось обнаружить, используя PVS-Studio.

iOS


Picture 9



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

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

Описание уязвимости CVE-2014-1266: The SSLVerifySignedServerKeyExchange function in libsecurity_ssl/lib/sslKeyExchange.c in the Secure Transport feature in the Data Security component in Apple iOS 6.x before 6.1.6 and 7.x before 7.0.6, Apple TV 6.x before 6.0.2, and Apple OS X 10.9.x before 10.9.2 does not check the signature in a TLS Server Key Exchange message, which allows man-in-the-middle attackers to spoof SSL servers by (1) using an arbitrary private key for the signing step or (2) omitting the signing step.

Фрагмент кода, который привёл к возникновению уязвимости, выглядел следующим образом:
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, 
                                 bool isRsa, 
                                 SSLBuffer signedParams,
                                 uint8_t *signature, 
                                 UInt16 signatureLen)
{
  OSStatus err;
  ....

  if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
    goto fail;
  if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;
  if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
    goto fail;
  ....

fail:
  SSLFreeBuffer(&signedHashes);
  SSLFreeBuffer(&hashCtx);
  return err;
}

Проблема заключается в двух операторах goto, расположенных рядом друг с другом. Только первый из этих операторов относится к оператору if, второй — нет. Таким образом, вне зависимости от значений предыдущих условий, будет осуществлён переход к метке fail. Из-за выполнения второго оператора goto значение err будет успешным. Это приводило к тому, что злоумышленники могли обманывать SSL сервера.

PVS-Studio обнаруживает эту проблему при помощи сразу двух диагностических правил — V640 и V779. Предупреждения выглядят следующим образом:
  • V640 The code's operational logic does not correspond with its formatting. The statement is indented to the right, but it is always executed. It is possible that curly brackets are missing.
  • V779 Unreachable code detected. It is possible that an error is present

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

Выходит, что и тут PVS-Studio успешно справился со своей работой.

Эффективное использование статического анализа


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

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

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

Вообще, чем раньше обнаружена и исправлена ошибка, тем дешевле стоимость её исправления. На рисунке, представленном ниже, приведены данные из книги Каперса Джонса (Capers Jones) «Applied Software Measurement».

Picture 1



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

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

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

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

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

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

Заключение


Надеюсь, мне удалось показать вам, что:
  • даже простой, казалось бы, баг может являться серьёзной уязвимостью;
  • PVS-Studio успешно справляется не только с поиском ошибок в коде, но и с поиском CWE и CVE.

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

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

Дополнительные ссылки






Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Sergey Vasiliev. How Can PVS-Studio Help in the Detection of Vulnerabilities?

Прочитали статью и есть вопрос?
Часто к нашим статьям задают одни и те же вопросы. Ответы на них мы собрали здесь: Ответы на вопросы читателей статей про PVS-Studio, версия 2015. Пожалуйста, ознакомьтесь со списком.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331262/


Почему стоит полностью переходить на Ceylon или Kotlin (часть 2)

Вторник, 20 Июня 2017 г. 10:17 + в цитатник

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


Поехали:


18# Типы — объединения (union types)


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


function f() {
    value rnd = DefaultRandom().nextInteger(5);
    return 
        switch(rnd) 
        case (0) false
        case (1) 1.0
        case (2) "2"
        case (3) null
        case (4) empty
        else ComplexNumber(1.0, 2.0);
}

value v = f();

Какой реальный тип будет у v? В Kotlin или Scala тип будет Object? или просто Object, как наиболее общий из возможных вариантов.
В случае Ceylon тип будет Boolean|Float|String|Null|[]|ComplexNumber.


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


if (is Integer v) { ...} //Не скомпилируется, v не может физически быть такого типа
if (is Float v) { ...} //Все нормально

Что это дает на практике?


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


Соответственно можно, например, написать:


Integer|Exception p = Integer.parse("56");

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


assert(is Integer p);

Или мы можем обработать все возможные варианты через switch:


switch(p)
case(is Integer) {print(p);}
else {print("ERROR");}

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


19# Типы — пересечения (Intersection types)


Рассмотрим код:


interface CanRun {
    shared void run() => print("I am running");
}

interface CanSwim {
    shared void swim() => print("I am swimming");
}

interface CanFly {
    shared void fly() => print("I am flying");
}

class Duck() satisfies CanRun & CanSwim & CanFly {}
class Pigeon() satisfies CanRun & CanFly {}
class Chicken() satisfies CanRun {}
class Fish() satisfies CanSwim {}

void f(CanFly & CanSwim arg) {
    arg.fly(); 
    arg.swim();
}
f(Duck()); //OK Duck can swim and fly
f(Fish());//ERROR = fish can swim only

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


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


20# Типы — перечисления (enumerated types)


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


abstract class Point()
        of Polar | Cartesian {
    // ...
}

В результате можно писать обработчики в switch не указывая else


void printPoint(Point point) {
    switch (point)
    case (is Polar) {
        print("r = " + point.radius.string);
        print("theta = " + point.angle.string);
    }
    case (is Cartesian) {
        print("x = " + point.x.string);
        print("y = " + point.y.string);
    }
}

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


С помощью данного функционала в Ceylon делается аналог enum в Java:


shared abstract class Animal(shared String name) of fish | duck | cat {}
shared object fish extends Animal("fish") {}
shared object duck extends Animal("duck") {}
shared object cat extends Animal("cat") {}

В результате мы получаем функционал enum практически не прибегая к дополнительным абстракциям.
Если нужен функционал, аналогичный valueOf в Java, мы можем написать:


shared Animal fromStrToAnimal(String name) {
    Animal? res = `Animal`.caseValues.find((el) => el.name == name);
    assert(exists res);
    return res;
}

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


23# Алиасы типов (Type aliases)
Ceylon является языков с весьма строгой типизацией. Но иногда тип может быть довольно громоздким и запутанным. Для улучшения читаемости можно использовать алиасы типов:
Например можно сделать алиас интерфейса, в результате чего избавиться от необходимости указания типа дженерика:


interface People => Set;

Для типов объединений или пересечений можно использовать более короткое наименование:


alias Num => Float|Integer;

Или даже:


alias ListOrMap => List|Map;

Можно сделать алиасы на интерфейс:


interface Strings => Collection;

Или на класс, причем класс с конструктором:


class People({Person*} people) => ArrayList(people);

Также планируется алиас класса на кортеж.


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


21# Кортежи
В цейлоне очень хорошая поддержка кортежей, они органично встроены в язык. В Kotlin посчитали, что они не нужны. В Scala они сделаны с ограничениями по размеру. В Ceylon кортежи представляют собой связанный список, и соответственно могут быть произвольного размера. Хотя в реальности использование кортежей из множества разнотипных элементов это весьма спорная практика, достаточно длинные кортежи могут понадобиться, например, при работе со строками таблиц баз данных
Рассмотрим пример:


value t = ["Str", 1, 2.3];

Тип будет довольно читаемым — [String, Integer, Float]
А теперь самое вкусное — деструктуризация. Если мы получили кортеж, то можно легко получить конкретные значения. Синтаксис по удобству будет практически как в Python:


value [str, intVar, floatType] = t;
value [first, *rest] = t;
value [i, f] = rest;

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


22# Конструирование коллекций (for comprehensions)
Очень полезная особенность, от которой сложно отказаться после того, как ее освоил.
Попробуем проитерировать от 1 до 25 с шагом 2, исключая элементы делящиеся без остатка на 3 и возведем их в квадрат.
Рассмотрим код на python:


res = [x**2 for x in xrange(1, 25, 2) if x % 3 != 0]

На Ceylon можно писать в подобном стиле:


value res = [for (x in (1:25).by(2)) if ( (x % 3) != 0) x*x];

Можно тоже самое сделать лениво:


value res = {for (x in (1:25).by(2)) if ( (x % 3) != 0) x*x};

Синтаксис работает в том числе с коллекциями:


value m = HashMap { for (i in 1..10) i -> i + 1 };

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


value javaList = Arrays.asList(*ObjectArray.with { for (i in 1..10) i});

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


    value javaConcurrentHashMap = createConcurrentHashMap {for (i in 1..10) i -> i + 1};

22# Модульность и Ceylon Herd
Задолго до выхода Java 9 в Ceylon существовала модульность.


module myModule "3.5.0" {
    shared import ceylon.collection "1.3.2";
    import ceylon.json "1.3.2";
}

Система модулей уже интегрирована с maven, соответственно зависимости можно импортировать традиционными средствами. Но вообще, для Ceylon рекомендуется использовать не Maven артефакторий, а Ceylon Herd. Это отдельный сервер (который можно развернуть и локально), который хранит артефакты. В отличие от Maven, здесь можно сразу хранить документацию, а также Herd проверяет все зависимости модулей.
Если все делать правильно, получается уйти от jar hell, весьма распространенный в Java проектах.
По умолчанию модули иерархичны, каждый модуль загружается через иерархию Class Loaders. В результате мы получаем защиту, что один класс будет по одному и тому же пути в ClassPath. Можно включить поведение, как в Java, когда classpath плоский — это бывает нужно когда мы используем Java библиотеки для сериализации. Ибо при десериализации ClassLoader библиотеки не сможет загрузить класс, в который мы десериализуем, так как модуль библиотеки сериализации не содержит зависимостей на модуль, в котором определен класс, в который мы десериализуем.


24# Улучшенные дженерики


В Ceylon нет Erasure. Соответственно можно написать:


switch(obj)
case (is List) {print("this is list of string)};
case (is List) {print("this is list of Integer)};

Можно для конкретного метода узнать в рантайме тип:


shared void myFunc() given T satisfies Object {
    Type tclass = `T`;
    //some actions with tClass

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


shared interface Comparable
        given Other satisfies Comparable {
    shared formal Integer compareTo(Other other);
    shared Integer reverseCompareTo(Other other) {
        return other.compareTo(this); //error: this not assignable to Other
    }
}

Не получилось! В одну сторону compareTo работает без проблем. А в другую не получается!


А теперь применим функционал self types:


shared interface Comparable of Other
        given Other satisfies Comparable {
    shared formal Integer compareTo(Other other);
    shared Integer reverseCompareTo(Other other) {
        return other.compareTo(this);
    }
}

Все компилируется, мы можем сравнивать объекты строго одного типа, работает!


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


shared interface Iterable ...

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


24# Метамодель


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


Рассмотрим некоторые варианты:


ClassWithInitializerDeclaration v = `class Singleton`;
InterfaceDeclaration v =`interface List`;
FunctionDeclaration v =`function Iterable.map`;
FunctionDeclaration v =`function sum`;
AliasDeclaration v =`alias Number`;
ValueDeclaration v =`value Iterable.size`;
Module v =`module ceylon.language`;
Package v =`package ceylon.language.meta`;
Class,[String]> v =`Singleton`;
Interface> v =`List`;
Interface<{Object+}> v =`{Object+}`;
Method<{Anything*},{String*},[String(Anything)]> v =`{Anything*}.map`;
Function v =`sum`;
Attribute<{String*},Integer,Nothing> v =`{String*}.size`;
Class<[Float, Float, String],[Float, [Float, String]]> v =`[Float,Float,String]`;
UnionType v =`Float|Integer`;

Здесь v — объект метамодели, который мы можем проинспектировать. Например мы можем создать экземпляр, если это класс, мы можем вызвать функцию с параметром, если это функция, мы можем получить значение, если это атрибут, мы можем получить список классов, если это пакет и т.д. При этом справа от v стоит не строка, и компилятор проверит, что мы правильно сослались на элемент программы. То есть в Ceylon мы по существу имеем типобезопасную рефлексию. Соответственно благодаря метамодели мы можем написать весьма гибкие фреймворки.


Для примера, найдем средствами языка, без привлечения сторонних библиотек, все экземпляры класса в текущем модуле, которые имплементят определенный интерфейс:


shared interface DataCollector {}

service(`interface DataCollector`)
shared class DataCollectorUserV1() satisfies DataCollector {}

shared void example() {
    {DataCollector*} allDataCollectorsImpls = `module`.findServiceProviders(`DataCollector`);
}

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


#25 Общий дизайн языка


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


Рассмотрим, например, синтаксис прямоугольных скобок:


[] unit = [];
[Integer] singleton = [1];
[Float,Float] pair = [1.0, 2.0];
[Float,Float,String] triple = [0.0, 0.0, "origin"];
[Integer*] cubes = [ for (x in 1..100) x^3 ];

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


val unit: Unit = ()
val singleton: Tuple1[Long] = new Tuple1(1)
val pair: (Double,Double) = (1.0, 2.0)
val triple: (Double,Double,String) = (0.0, 0.0, "origin")
val cubes: List[Integer] = ... 

В язык очень органично добавлены аннотации synchronized, native, variable, shared и т.д — это все выглядит как ключевые слова, но по существу это обычные аннотации. Ради аннотаций, чтобы не требовалось добавлять знак @ в Ceylon даже пришлось пожертвовать синтаксисом — к сожалению точка с запятой является обязательной. Соответственно Ceylon сделан таким образом, чтобы код, предполагающий использование уже существующих распространенных Java библиотеки вроде Spring, Hibernate, был максимально приятным для глаз.


Например посмотрим как выглядит использование Ceylon с JPA:


shared entity class Employee(name) {
    generatedValue id
    shared late Integer id;

    column { lenght = 50;}
    shared String name;

    column
    shared variable Integer? year = null;
}

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


Посмотрим как будет выглядеть код Criteria API:


shared List employeesForName(String name) {
    value crit = entityManager.createCriteria();
        return
            let (e = crit.from(`Employee`))
            crit.where(equal(e.get(`Employee.name`),
                             crit.parameter(name))
                .select(e)
                .getResultList();
}

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


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


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


Для заинтересованных еще немного интересных ссылок
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330796/


Метки:  

CocoaHeads Russia в офисе Туту.ру

Вторник, 20 Июня 2017 г. 10:08 + в цитатник


23 июня Туту.ру и CocoaHeads Russia проведут очередную встречу сообщества iOS-разработчиков в Москве. В программе 3 доклада, викторина и афтерпати после встречи.



Программа


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

Темы митапа:
  1. Анимация как средство самовыражения
  2. Team Lead. Структурирование мыслей
  3. Реактивный VIPER


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

Спикеры



Александр Зимин, iOS-разработчик
Тема: Анимация как средство самовыражения
Расскажу о том, как создавать сложные анимации в iOS приложениях.
— CoreAnimation и его особенности
— Анимационные переходы между экранами
— Работа с анимациями, экспортированными из Adobe After Effects





Николай Ашанин, iOS-Lead, Touch Instinct
Тема: Team Lead. Структурирование мыслей
Расскажу, как вырасти из разработчика в тимлида и не сойти с ума. Технические и психологические рекомендации, ошибки, негатив и дельные советы для разработчиков. Будет интересно разработчикам, которые задумываются о росте.





Дмитрий Котенко, iOS-разработчик Туту.ру
Тема: Реактивный VIPER
Расскажу про развитие идеи реактивного программирования. Пройдем путь от MVVM к VIPER при использовании рективщины, обсудим плюсы и минусы последнего в сравнении с императивной реализацией.


Регистрация


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

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

Начало мероприятия в 19:00 (начало регистрации – в 18:30).
Адрес: 1-й Нагатинский пр-д, 10, Офис Туту.ру

Регистрация на мероприятие

Ждем вас на митапе, в офисе Туту.ру! :)
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331260/


Метки:  

«Мое самое главное испытание – не сломать драйвер» — Dave Cramer о разработке драйвера JDBC для PostgreSQL

Вторник, 20 Июня 2017 г. 09:49 + в цитатник
Наш сегодняшний собеседник – Dave Cramer, один из ключевых контрибьюторов в PostgreSQL, автор и мэнтейнер драйвера JDBC для Посгреса на протяжении более 15 лет.

Dave не очень часто выступает на публике. Нам крупно повезло, он согласился приехать на PG Day'17 Russia, чтобы провести практикум / мастер-класс по оптимизации и эффективному использованию Java в PostgreSQL вместе со своими коллегами-контрибьюторами в pgjdbc, 'Alvaro Hern'andez Tortosa и Владимиром Ситниковым. Не менее интересным намечается доклад Дэйва, посвященный скрытым возможностям драйвера.

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




PG Day: Dave, расскажи вкратце о себе: кто ты, чем занимаешься, как проводишь свободное время?

Dave: Привет, меня зовут Дэйв Крамер, я работаю с языком PostgreSQL уже 15-16 лет, начиная с 2000-го года, и основной сферой моей деятельности здесь является работа с драйвером JDBC, потому что раньше я был программистом Java. Я также занимался некоторыми процедурными языками, например, pl/R. Что меня интересует в PostgreSQL? Продвижение сообщества, его развитие.

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

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

PG Day: Как и почему ты начал работать с драйвером Java для PostgreSQL?

Dave: В 1999-2000 годах программное обеспечение с открытым исходным кодом (open source) было не так распространено, как сейчас. В тот момент, я только стал частным подрядчиком, работать сам на себя. Как-то я позвонил в техподдержку Microsoft (у меня был клиент), возникла проблема, и я надеялся, что они ее решат. Они ответили: «Мы свяжемся с вами через три недели». Понятно, что на три недели я остался без работы, поэтому меня это немного напрягло. Я начал рассматривать другие варианты, и наткнулся на open source, я об этом ничего не знал. Я поспрашивал людей, как разобраться в этом? И мне посоветовали отвечать на вопросы в mailing list. Я так и сделал. На первый вопрос я отвечал два или три дня. Со вторым я разобрался проще. И потихоньку я стал довольно оперативно на них отвечать.

В то время другой человек занимался драйвером JDBC, и внезапно ему это стало не интересно, а я всё время был на виду, так что Bruce Momjian предложил мне им заняться. И я ответил «да». Это было 15-16 лет назад и вот – до сих пор.

PG Day: Ты и сейчас продолжаешь обновлять кодовую базу?

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

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

Вот только сегодня пофиксил пару багов, так что… К слову, много кодят русские. Владимир Ситников, например. Очень много кода внес в драйвер.

PG Day: Сколько людей сейчас задействовано в активном развитии драйвера? Как происходит рабочий процесс?

Dave: Откровенно говоря, людей не хватает. Их число время от времени меняется. В зависимости от того, кто хочет решить ту или иную проблему. Совсем недавно парень в Великобритании полностью переписал драйвер для Maven. Владимир Горячев, кажется, так его зовут, написал компонент для логического декодирования к драйверу. Владимир Ситников потратил большое количество времени на оптимизацию драйвера.

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

PG Day: Есть ли какие-то крупные компании, которые пытаются спонсировать развитие, поддерживать инициативу, платя людям за улучшение проекта?

Dave: Я никогда не видел, чтобы кто-то предложил свою помощь и оплатил работу над драйвером. Я думаю, Владимиру Ситникову платит его компания (Netcracker — прим.ред.), чтобы он работал над драйвером. Но я в этом не уверен. Мне кажется, Red Hat спонсировала какую-то работу, связанную с пакетированием. Pivotal, в ту пору когда я на них работал, были не против, чтобы я работал над драйвером. Open SCG также были не против. Но чтобы компания спонсировала чью-то работу над драйвером… Такого, кажется, не случалось.

PG Day: Ты планируешь оставить свою роль куратора и менеджера проекта? Какие у тебя планы на будущее?

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

PG Day: Какие из последних улучшений JDBC тебе кажутся наиболее интересными, впечатляющими, если говорить о PostgreSQL?

Dave: Самая поразительная вещь, которая случилась на моих глазах с драйвером – у нас появилась логическая репликация. Почему это так важно? Теперь мы можем осуществлять сбор изменившихся данных (Changed Data Capture). Мы пишем чистый код на Java. До этого времени нам приходилось писать триггеры, посылать данные в какой-то алгоритм, создавать файл, очередь или что-нибудь подобное, читать данные асинхронно, а затем обновлять код. Обновлять приложение.

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

PG Day: Есть ли какие-то проблемы в архитектуре драйвера, которые ты хотел бы исправить?

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

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

PG Day: Как люди справляются с отсутствием поддержки пользовательских типов? Существуют ли какие-то способы решения проблемы?

Dave: Для PostgreSQL есть еще один драйвер, который выполняет эту задачу. Он называется pgjdbc-ng, драйвер нового поколения. Внимания он не привлекает, и я не думаю, что пользовательские типы – это элемент, который часто используется в сообществе, где применяется PostgreSQL. Мне кажется, большинство тех, что пользуются Java, используют технологию Hibernate, Spring, и по большей части их данные очень просты. Они делают выборки, вставляют данные, удаляют и в общем-то всё.

По-моему, есть один момент – и он относится к вопросу, который ты задал ранее – тратят ли люди, компании деньги для работы над драйвером… Что является самой большой сложностью для нас, как для создателей драйвера JDBC (и любых других драйверов)? Драйверы – это как колёса у машин. Люди покупают машину и ожидают, что у нее будут колёса. Они круглые, у них мало функций, однако они двигают машину. Но пока колёса крутятся, людям на них наплевать. Это не модно. Люди не тратят часы своего времени, обсуждая это на hackers’ list.

Мое самое главное испытание – не сломать драйвер.

PG Day: Java внутри PostgreSQL как язык для написания хранимых процедур – это хорошая мысль? Каковы типичные случаи применения такого инструмента?

Dave: Да, существует технология под названием PL/Java – Java как язык хранимых процедур в PostgreSQL. Проблема заключается в том, что PostgreSQL процессно-ориентирован. Каждый раз, как вы пишете на языке хранимых процедур Java и исполняете их, необходимо стартовать JVM внутри соединения.

Это становится довольно дорогостоящим процессом. Так что надо убедиться в том, что вы используете запуск хранимой процедуры из Java только тогда, когда это можно написать на Java. И стоит тех startup costs, которые тратятся на JVM. Это можно наблюдать и в других языках, например, PL/Python и в особенности в pl/R. Все эти языки мы хотели бы использовать, чтобы производить какую-то существенную обработку данных в JVM, pl/R или Python – языках, используемых специалистами по обработке и анализу данных.

Считаю ли я PL/Java хорошей идеей? Я не очень-то в этом убеждён. Некоторое время я занимался другим проектом под названием pl/J, который осуществлял разделяемый доступ к JVM среди соединений, и я буду рад, если этот проект кто-то возродит. Лично у меня не было на него времени. Код еще остался. Это довольно сложно. Oracle проделали довольно большую работу относительно Java внутри базы данных. Их JVM внутри Oracle – это не та JVM, что есть у нас. У них есть отдельная JVM, оптимизированная специально под эти задачи. Я думаю, что у нее нет тех startup costs, которые есть для PostgreSQL. В таком случае, если что-то можно сделать только на Java, это будет оправданно.

PG Day: Ни для кого не секрет, что Java – одна из основных корпоративных технологий. Как, по вашему мнению, PostgreSQL – хороший выбор для построения вокруг него комплекса корпоративных технологий?

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

Более серьезное испытание, с которым мы сталкиваемся, как разработчики PostgreSQL, – это внедрение технологии и наши попытки заставить людей поверить в него. В Северной Америке мы заметили серьезный интерес к PostgreSQL. Всплеск интереса, так как люди стали больше внимания обращать на стоимость проектов.

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

PG Day: Какие изменения ты заметил за последние 5-10 лет, проведённых в сообществе? Есть ли понимание, в какую сторону оно движется?

Dave: За последние пять лет популярность PostgreSQL выросла. Увеличивается количество людей, работающих на нём, как и количество людей, пишущих код для самого PostgreSQL. Когда я начинал, довольно мало людей писали код, всего 4-5 человек, которые реально работали с кодом. Сегодня у нас уже около 10 компаний, в каждой по 10 человек, и все они вносят существенный вклад в код проекта.

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

PG Day: Можешь дать краткое превью того, что будет на вашем семинаре, который Вы устраиваете с Альваро и Владимиром на PG Day’17 Russia? Что Вы включите в программу, над какими проблемами и задачами будете работать?

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

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

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

PG Day: Спасибо, Dave!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331162/


Метки:  

Yet another вариант отправки уведомлений от Asterisk в Telegram

Вторник, 20 Июня 2017 г. 08:13 + в цитатник
image

Добрый день, уважаемые хабражители.

В последнее время на хабре появилось несколько статей об интеграции Asterisk и Telegram: раз, два

Предлагаю рассмотреть еще один вариант.

По некоторым причинам данные решения мне не подходили.

Что-то по объективным причинам: использование telegram-cli, по отзывам не слишком стабильного, да и для его использования нужно авторизоваться на сервере под своим telegram-аккаунтом, показалось мне не слишком удобным и правильным.

Что-то по субъективным: не хотелось использовать php как в варианте 1 и заставлять сотрудников писать боту свои номера.

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

Исходные данные:



У клиента несколько удаленных менеджеров с мобильными телефонами, звонок поступает на Asterisk на общий SIP-номер, после чего через sip-транк переадресуется на мобильные менеджеров. При данной схеме довольно много удобств — менеджеры не обязаны сидеть в офисе, а могут работать, что называется «в поле» (@boffart извини за плагиат:). Однако есть одно неудобство, которое перевешивает все плюсы — невозможность увидеть исходный Callerid клиента.

Для реализации обхода данного неудобства было принято решение об отправке в общую группу менеджеров в telegram сообщения вида «Входящий вызов с номера ${CALLERID(num)} на номер ${EXTEN}».

Итак, приступим:



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

После регистрации бота напишем небольшой скрипт на python, который будет вызываться из Asterisk'a и слать нам в telegram уведомления.

Используемая версия python — 2.7

Так как я реализовывал все на Centos 6.6, в котором «из коробки» используется python 2.6 (проверить вашу версию python можно набрав в консоли python -V), то для начала нам нужно установить python 2.7. Есть два варианта: установка из rpm-пакетов и из исходников. Рассмотрим оба.

Установка из исходников



Обновим систему и поставим необходимые пакеты:
yum -y update
yum groupinstall -y 'development tools'
yum install -y zlib-dev openssl-devel sqlite-devel bzip2-devel
yum install xz-libs



Качаем исходники python 2.7:
wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tar.xz
xz -d Python-2.7.6.tar.xz
tar -xvf Python-2.7.6.tar



Конфигурация и установка python 2.7:
cd Python-2.7.6
./configure --prefix=/usr/local/bin (префикс можно ставить любой удобный вам, к примеру импортировать его из переменной $HOME)
make
make altinstall



Установка pip 2.7:
Перед установкой необходиом скачать и установить setuptools
wget --no-check-certificate https://pypi.python.org/packages/source/s/setuptools/setuptools-1.4.2.tar.gz
tar -xvf setuptools-1.4.2.tar.gz
cd setuptools-1.4.2
python2.7 setup.py install

и сам pip
curl https://bootstrap.pypa.io/get-pip.py | python2.7 -



Установка из rpm



Добавляем rpm-пакеты, ставим python, pip:
rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/ius-release-1.0-14.ius.el6.noarch.rpm
yum clean all
yum install python27
yum install python27-pip



Python нужной версии установлен, установим библиотеку для работы с Telegram API:

pip2.7 install pyTelegramBotAPI==2.3.1


И непосредственно сам код скрипта:
#!/usr/local/bin/python2.7
# -*- coding: utf-8 -*-

import telebot
import sys

token = 'INSERT_YOUR_TOKEN'  # Вводим свой телеграм API токен
group_id = -123456789  # Вводим id группы, куда надо слать сообщения (обратите внимание, что id группы - отрицательное целое число)
bot = telebot.TeleBot(token, skip_pending=True)


# Ловим команду старта при старте без аргументов (первый старт)
@bot.message_handler(func=lambda message: True, commands=['start'])
def start(message):
    if len(sys.argv) != 1:
        return
    bot.send_message(message.chat.id, "ID чата: " + str(message.chat.id))
    print message.chat.id
    sys.exit()


# Если были переданы три аргумента, то возвращаем в чат сообщение
if len(sys.argv) == 4:
    callerid = str(sys.argv[1])
    exten = str(sys.argv[2])
    redirectnum = str(sys.argv[3])
    bot.send_message(group_id, "Вызов с номера " + callerid + "\nна номер " + exten + "\nпереадресован на номер " + redirectnum)
# Если аргумента нет, то считаем первым стартом и запускаем в режиме полинга
if len(sys.argv) == 1:
    bot.polling(none_stop=True)



Дело осталось за малым: перед поступлением входящего звонка вызвать скрипт из dialplan'а Asterisk. У меня он, к примеру, такой:

vim /etc/asterisk/extensions.conf:
exten => 84951234567,1,Set(CALLERID(num)=+7${CALLERID(num)})
same => n,Answer()
same => n,Playback(hello)
same => n,Set(REDIRECTNUM=+79261234567)
same => n,System(/etc/asterisk/redirector/redirector.py ${CALLERID(num)} +7${EXTEN:1} ${REDIRECTNUM})
same =>n,Dial(SIP/mytrunk/mymobilenumer&SIP/mytrunk/mymobilenumber2,40,tTm(default))
same =>n,Hangup()



При входящем звонке менеджеры получают в группу telegram подобное сообщение:image

Для удобства хабровчан оформил всё в github.

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

Автор: Asterisk'ер компании Southbridge Михаил Комов.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/329668/


Метки:  

Мальта как новое направление для IT специалистов

Вторник, 20 Июня 2017 г. 06:49 + в цитатник
Если Вы подумали о солнце, море и яхтах — тогда вы все верно поняли :)



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

Климат подходит для всех любителей солнца и моря. Почти всегда солнечно, даже зимой. Хотя раз в 3 года зима бывает очень дождливой, а при температуре +14 и ветре может быть довольно прохладно. Зато остров расцветает зеленью!

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

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


Blue Lagoon

Я живу на острове Мальта. Хоть он и самый большой из 3-х остров, его длина составляет не более 30 км, а ширина — 15км. Но это совершенно не ощущается. Когда поживешь некоторое время на острове, 5 км кажутся большим расстоянием.

Лучший способ познакомиться с островом — это воспользоваться hop on hop off турами. Так вы сможете посетить самые интересные места, и хоть их тут не очень много, но некоторые из них поражают воображение. Например, Hagar Qim — The Megalithic Temples of Malta одни из самых древних на планете (3600-3200 BC). Или Skorba Temples — правда там мало что осталось, но на этом месте найдены признаки самых первых поселенцев, которым почти 7 тысяч лет. В таких местах возникают особые ощущения.

Кстати, есть еще один музей на Мальте, где представлены животные, некогда населявшие остров, например слоны…

Опасных насекомых на Мальте нет и акулы предпочитают побережье Сицилии.

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

Работа в IT
Благодаря низким (относительно других стран ЕС) налогам, Мальта очень привлекательная для иностранных компаний, а особенно для iGaming компаний. Пожалуй самая крупная иностранная компания на Мальте — Betsson Group насчитывает около 1000 сотрудников. Большая часть ее IT офиса также располагается на острове.

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

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

Налоги
Я выше упоминал, что налоги на Мальте низкие. Для наемных сотрудников налогообложение применяется по шкале от 0 до максимальных 35% (если годовой доход превышает €60 000)

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

Зарплаты в IT
Средняя зарплата до налогов в IT на Мальте составляет €40,000 в год. Программист уровня Senior в среднем получает €48,000 — €50,000. Разумеется, есть исключения в сторону увеличения и так же можно договариваться о соцпакете, например частная медицинская страховка может быть включена как бонус.

Вакансии
Как правило нужны специалисты уровня Senior и Middle. Front-end, Backend, Fullstack, DevOps, QA, Product owner.
JavaScript, Node.JS, Angular, React.Js, PHP, .NET, Ruby, Python, C#, Java, SQL и т.д. Как я уже упоминал, все больше компаний приезжает на остров и список технологий расширяется, что приводит к появлению спроса на самый широкий спектр IT специалистов.

Для стартап проектов чаще всего требуются Front-end, Backend и реже CTO. Самые популярные технологии: JavaScript, PHP, Node.js, AngularJS, ReactJS. Также опыт разработки гибридных мобильных приложений (Ionic, React Native, Cordova).

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

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

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

Банки
Заработная плата перечисляется в большинстве случаев на расчетный счет в местном банке. Для открытия счета, помимо стандартного набора документов, Вам обязательно нужно иметь письмо из вашего банка (reference letter), где у вас есть р/сч, о том, что вы надежный и добросовестный клиент. Причем, стоит заранее уточнить в вашем банке, смогут ли они оперативно ответить на запрос о вашей добросовестности через межбанковскую систему SWIFT.

Впрочем, есть возможность обойти это требование обратившись в Banif Bank, который, так и быть, откроет вам счет и выдаст карточку, но потребует депозит в €500 и ежемесячно будет у вас снимать минимум €50 для пополнения депозита. Все что накопится на депозите Вам вернут после закрытия счета (что приятно).
Пожив 2 года на острове и имея рабочий контракт, Вы вполне можете попробовать получить кредит на недвижимости под смешных 3.5% годовых. Первый взнос 30%

Медицина
Медицинское обслуживание, на мой взгляд, достаточно хорошего уровня. Центральная больница Mater Dei хорошо оборудована. Из недостатков местного медицинского обслуживания и я бы выделил длинные очереди. Например, чтобы сделать профилактическое узи нужно ждать 6-12 мес. Если что-то серьезное и срочное, разумеется медицинскую помощь вам окажут оперативно, а скорые тут супер быстрые.

Аренда жилья
Аренда 2k, 3к квартиры в хорошем состоянии в популярных городах обойдутся в €700-1200. 1к и 2к квартиры встречаются реже и цена не намного ниже. Обращаю внимание, что тут считаются только спальни, следовательно 1к квартира на самом деле 2-х комнатная. Как правило 2 и 3к квартиры имеют по 2 с/у один из которых ensuite. Все квартиры меблированы и имеют полностью оборудованную кухню. Альтернативный вариант для одиноких и неприхотливых — снять комнату. Это гораздо дешевле и удобнее, и очень популярно среди молодежи.

Большинство IT компаний сосредоточены в городах St Julian's и Sliema, соответственно стоимость аренды жилья там одна из самых высоких. Приходится выбирать — или платить больше за аренду и добираться на работу за 5-10 минут или снять квартиру в менее популярных городах и купить личный транспорт. Аренда 3к, относительно новой квартиры, например в городе Bugibba или St. Paul's Bay будет на €100-200 дешевле.

Коммунальные услуги
В среднем, на человека получается около 40 евро в мес. Зависит от того, насколько хорошо Вы умеете экономить свет и воду.

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

Покупка личного транспорта
Цены на новые китайские скутеры начинаются примерно от €1200. Можно купить б/у за €500+. Для двигателей объемом до 125cc лицензия составляет €10 в год. Для автомобилей стоимость ежегодной лицензии начинается от €100 и зависит от возраста автомобиля и объема двигателя.

Новые автомобили стоят примерно как в Европе или дороже. Б/у автомобили стоят существенно дороже чем, например в Германии. Toyota Yaris 2010-2011 г. Обойдется в €6000-€7000. Ежегодная лицензия примерно €130+
За €300-€1000 тут можно купить самую настоящую развалюху.
Со своим транспортом словно обретаешь крылья. Узнаешь много новых мест, и за покупками ездить становится намного проще.

Питание
На острове имеются большие супермаркеты, где есть почти все. Также всегда можно найти местные магазинчики с ассортиментом из всего самого необходимого. На семью из 4 человек в неделю на питание уходит €100-120 или €200+ если покупать био продукты.

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

Средний чек в ресторане на двоих будет около €40. Самая распространенная кухня — итальянская. Для любителей японской и китайской кухни тоже что-то найдется.

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

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

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

Многие приезжают на Мальту из-за климата, но на практике иногда разочаровываются, так как выясняется, что при + 15, высокой влажности и наличии ветра 25 м/с может быть очень даже холодно в зимнее время. Зимы бывают разные, дождливые или вообще без дождя. Но нужно помнить, что если на Мальте затяжная холодная зима, то какая же она тогда в других странах Европы…

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

Для детей сложнее. Хотя есть аквапарк и Popeye Village.


Popeye Village

Для желающих научится управлять парусными и моторными яхтами тут все условия. Стоимость курсов от €150 и даже можно получить местный сертификат.

Путешествия/перелеты
На Мальту летает несколько low-cost авиа-компаний, среди них Wizz Air, Ryanair и EasyJet. Есть локальная авиакомпания Air Malta c довольно хорошим сервисом. Она же осуществляет прямые рейсы из Москвы. Из Киева нет прямых рейсов, но можно добраться с пересадкой через Мюнхен, Франкфурт или Стамбул. Стоимость билетов от €150. Из Белоруссии можно добираться через Литву — Ryanair летает из Вильнюса.

С Мальты на пароме можно добраться до Сицилии — стоимость билета в обе стороны €40-80 в зависимости от сезона и наличия скидок. Но можно полететь в Катанию на Ryanair за €12,99 в одну сторону (если следить за ценами)

В целом если покупать билеты вовремя, средняя стоимость на человека будет €40-50 в одну сторону.

Немного о проекте itRabota.com
За 2 года сформировалась стратегия, в основе которой лежит личное общение с каждым кандидатом. Иногда люди удивляются, когда узнают, что большинство писем, особенно касательно профиля и вакансий, я пишу собственноручно. Что не удивительно, если учесть, что все стремятся автоматизировать как можно больше операций. Но мой опыт показал, что нужно лично работать с каждым кандидатом, чтобы правильно оценить его потребности и пожелания относительно вакансий. Это же касается и работы с компаниями и рекрутерами — я со всеми лично обсуждаю требования по вакансиям.

Чтобы выкроить время для личного общения, я автоматизирую процесс сбора информации.
itRabota.com был недавно полностью перестроен. Также появился дополнительный домен resuma.io

Так, в вашем распоряжении есть 2 типа профиля:
  • Quick job application — быстрый способ создать профиль заполнив только самую важную информацию + загрузка резюме (предполагается, что оно у вас есть)
  • Full resume — создание профиля в виде резюме, которое можно будет бесплатно загрузить в формате PDF (если захотите)

Резюме постоянно совершенствуется. Об этом я напишу отдельную статью.

Кстати, все услуги предоставляются бесплатно!

Вакансий много и спрос на IT специалистов огромный (что вы и так знали)
Например, только по Германии более 50 вакансий. Все с визовой поддержкой и почти все с relocation package. Технологии те же, что выше упоминались — JavaScript, Node.JS, Angular, React.Js, PHP, .NET, ASP.NET, Ruby, Python, C#, Java, SQL…

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

Front-End Web Developer
Core skills: JavaScript/ES6, ReactJs (React Native)
Experience: 3+ years
Industry: iGaming (football related)

Работа над созданием приложения на React Native только началась. Команда молодая, но опытная.
Зарплата от €30 000 до €40 000 в год. При €40 000 после уплаты налогов будет оставаться €2,500 в мес.
Компания оплачивает перелет на Мальту, 2 недели проживания, частную страховку и компенсирует 250€ в год на спортзал.

Если у вас есть вопросы на счет Мальты, буду рад ответить!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331250/


Краткое описание BPMN с примером

Вторник, 20 Июня 2017 г. 02:43 + в цитатник
Краткое описание BPMNО том, что такое BPMN, написано очень много. Но проблема в том, что почти вся информация, которую можно найти в Интернет, ориентирована на людей, которые уже ранее сталкивались с BPMN или с другим стандартом моделирования бизнес-процессов. Я же предлагаю разобраться «с нуля» — что такое BPMN? В чем особенности и преимущества этой технологии и почему она появилась и оказалась столь востребованной, по крайней мере, за рубежом. Да и у нас в стране ей все больше и больше интересуются.

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

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

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

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

Лично я познакомился впервые с BPMN около восьми лет назад, когда начал изучать систему Bizagi Modeler. Заинтересовался я этой системой по причине того, что давно уже понимал всю важность моделирования. До этого я лично пользовался IDEF0 и IDEF3, но там я сталкивался с определенными ограничениями. Дело в том, что IDEF0 несколько ограничен по числу возможностей. А IDEF3 мне лично показался излишне строгим и «сухим», в нем было сложно моделировать многие виды бизнес-процессов с участием программных продуктов.

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

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

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

BPM: ОСНОВНЫЕ ПОНЯТИЯ


Для того чтобы разобраться, что такое BPMN, нужно понимать, что часть этой аббревиатуры «BPM» имеет две расшифровки — Business Process Modeling и Business Process Management. В первом случае – это непосредственно моделирование бизнес процесса, а во втором – управление бизнес-процессами, т.е. общая система, частью которой и является Business Process Modeling.

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

Есть и еще одно понятие, о котором стоит сразу упомянуть – это «BPMS», т.е. Business Process Modeling System. Этот термин описывает те самые системы управления, в которых производится моделирование, а также исполнение бизнес-процессов.

Можно сказать, что BPMN является частью двух важнейших составляющих:

  • BPM (Business Process Modeling) – это та среда, где вы занимаетесь непосредственно моделированием. Самостоятельно или в команде.
  • BPMS (Business Process Modeling System) – это инструменты для исполнения созданных вами моделей. Это может быть Bizagi, Comundo,ELMA и пр.
  • Итак, основные понятия у нас есть. Подробнее о BPM я планирую поговорить в следующих статьях.

ЯЗЫК ОПИСАНИЯ БИЗНЕС-ПРОЦЕССОВ


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

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

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

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

Например, для моделирования бизнес-процессов вам понадобится знание таких понятий, как «условия», «цикл», «декомпозиция» и т.д.

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

НЕМНОГО ИСТОРИИ BPMN


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

Первая версия BPMN 1.0 была выпущена в мае 2004 года компанией Business Process Management Initiative. Эта версия обладала ограниченными возможностями и была, так сказать, «пробным вариантом», который нуждался в многочисленных доработках.

Следующая версия BPMN 1.1 выходит в январе 2008, и здесь разработкой и поддержкой занималась уже Object Management Group, организация, появившаяся в результате слияния BPMI с другой компанией-разработчиком программного обеспечения.

Еще один релиз появляется всего через год, версия BPMN 1.2 выходит в свет в январе 2009. Разработчик OMG остается прежним. Команда, которая занимается продуктом, после слияния практически не меняется.

В январе 2011 года компания OMG выпускает версию BPMN 2.0, а в декабре 2013 выходит последний на данный момент релиз – BPMN 2.0.2. Именно эта версия предлагается всем пользователям и сегодня, так как система получилась стабильной, возможности моделирования в ней очень широкие, а язык моделирования (набор обозначений) по большей части понятен всем бизнес-пользователям – как бизнесменам, бизнес-консультантам, так и техническим специалистам.

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

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

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

ИЗ ЧЕГО СОСТОИТ НОТАЦИЯ BPMN?


И здесь я хочу сделать небольшое отступление. Дело в том, что перевод терминов и понятий с английского языка на русский – занятие сложное. Найти наиболее точное слово обычно может специалист, но переводом занимается совсем другой человек, часто вообще не имеющий понятия о сути тех понятий, которые он переводит. В результате появляется множество неточностей, понятия усложняются, возникает путаница. Об особенностях перевода и сложностях применения терминов в сравнении с графикой я уже писал, например, в статье Знакомство с нотацией IDEF0 и пример использования (см. раздел “Несколько слов о преимуществах графики”).

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

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

Язык описания бизнес-процессов опирается на следующие базовые объекты:

  • Event – Событие;
  • Activity – Действия;
  • Gateway – Шлюзы или Развилки;
  • Flow – Поток.
  • Date – Данные;
  • Artefact – Артефакты;
  • Swimline – «плавательные дорожки»;
  • Pool (Пул) — набор.

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

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

EVENT (СОБЫТИЕ)


EVENT (СОБЫТИЕ)

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

Например, опишем процесс получения заказа от клиента по телефону:

  • Событие Старт – это входящий звонок от клиента.
  • Событие Финиш – это отправка готового расходного документа на печать.

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

ACTIVITY (ДЕЙСТВИЯ)


ACTIVITY (ДЕЙСТВИЯ)

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

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

Обычно действия делят следующим образом:

  • Процесс – крупное действие, которое требует дальнейшей детализации при моделировании.
  • Задача – элементарное действие, которое уже не может быть дальше детализировано.

GATEWAY (ШЛЮЗ, РАЗВИЛКА)


GATEWAY (ШЛЮЗ, РАЗВИЛКА)

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

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

FLOW (ПОТОК) И MESSAGE FLOWS (ПОТОК СООБЩЕНИЙ)


FLOW (ПОТОК) И MESSAGE FLOWS (ПОТОК СООБЩЕНИЙ)

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

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

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

POOL (ПУЛ)


POOL (ПУЛ)

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

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

DATE OBJECT (ДАННЫЕ, ОБЪЕКТЫ ДАННЫХ)


DATE OBJECT (ДАННЫЕ, ОБЪЕКТЫ ДАННЫХ)

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

MESSAGE (СООБЩЕНИЕ)


MESSAGE (СООБЩЕНИЕ)

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

ARTEFACT (АРТЕФАКТЫ)


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

Выделяют два вида артефактов:

  • Object Group (Группа объектов)
  • Text Annotation (Текстовая аннотация)

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

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

ИСПОЛНЯЕМЫЕ И НЕИСПОЛНЯЕМЫЕ БИЗНЕС-ПРОЦЕССЫ


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

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

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

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

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

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

ПОДХОДИТ ЛИ BPMN ДЛЯ МАЛОГО И СРЕДНЕГО БИЗНЕСА?


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

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

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

МИНУСЫ И ВАЖНЫЕ ОСОБЕННОСТИ BPMN


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

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

ПРИМЕР ПРАКТИЧЕСКОГО ПРИМЕНЕНИЯ BPMN


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

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

Данный бизнес-процесс выполняется следующим образом:

  1. Менеджер по продажам получает информацию о потребностях клиента (заказ).
  2. В системе CRM создается документ Заказ покупателя.
  3. Если нужные товары есть в наличие, то менеджер создает расходный документ в программе учета. Если товара нет в наличии, менеджер делает запрос в отдел закупки.
  4. Отдел закупки оформляет запрос поставщикам на получение товара.

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

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

Точкой входа служит получение заказа от покупателя. Точкой выхода – «резервирование товара».
Изображение примера BPMN диаграммы

Обратите внимание, что после получения заказа стрелка ведет к этапу-ромбу, т.е. условию:

  • Если весь товар имеется в наличие, то менеджер выполняет подпроцесс «резервирование товаров». Я специально оформил эти действия именно подпроцессом, чтобы иметь возможность при необходимости детализировать действия менеджера. А потом – к точке выхода «Резервирование товаров проведено».
  • Если товаров в наличие нет, то менеджер выполняет запрос в отдел закупки. Информация о заказе переходит в отдел закупки к другому исполнителю – менеджеру по закупкам, что наглядно видно на схеме, и уже этот исполнитель создает заказ поставщику. На схеме также видно, что заказ поставщику создан на основе запроса на поставку и заказа поставщикам.

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

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

КАК РАЗРАБАТЫВАТЬ ДИАГРАММЫ BPMN НА ПРАКТИКЕ?


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

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

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

Что еще хотелось бы посоветовать:

  1. Создавайте диаграммы как можно менее разветвленные. Чем больше элементов окажется на вашей диаграмме, тем сложнее ее будет читать и вам, и вашим заказчикам.
  2. Используйте наиболее простую и понятную терминологию. Очень важно, чтобы ваши заказчики, а также технические специалисты, которые будут работать с диаграммами, без лишних пояснений понимали все (или почти все) термины.
  3. Все названия процессов должны быть максимально информативны и понятны. Иначе читабельность диаграммы также будет крайне низкой. Для названий процессов лучше всего подойдут либо термины, принятые в конкретной организации для описания работы, либо – просто понятные интуитивно фразы.
  4. Зоны ответственности также важно называть понятно для сотрудников компании, бизнес-модель работы которой вы описываете. Самое простое решение – выбирать названия среди существующих подразделений. А если необходимой должности или отдела в компании пока еще не существует, не бойтесь придумывать его сами. Но постарайтесь, чтобы название также было «говорящим», понятным для широкого круга бизнес-аудитории.
  5. Подпроцессов должно быть столько, чтобы избежать ненужной детализации, но не более того. Помните о чувстве меры. Если подпроцессов будет слишком мало, то действия, которые стоило бы спрятать в них, будут находиться в общем процессе, создавая дополнительные объекты, стрелки, ветвления и, как следствие, путаницу. Если вы перестараетесь с желанием убрать все в подпроцессы, то диаграмма потеряет свою информативность, а какие-то изменения в подпроцессе начнут ненаглядно влиять на результаты всего процесса.
  6. Не бойтесь ошибаться! Если вы ошибетесь в исполняемой методологии, это очень быстро выяснится в процессе исполнения (отладки) процесса. Если вы создаете просто наглядную схему, то мелкие ошибки не столь важны, главное, чтобы эта схема помогла вам и людям, для которых вы ее делаете (заказчики, технические специалисты), понять все нюансы вашей идеи. И в любом случае, на ошибках учатся, а исправления внести в бизнес-модель можно быстро и просто.

И, конечно же, независимо от того, какой вариант бизнес-моделирования вам нужен, не стоит бояться BPMN – выучить нотацию очень просто, а для чтения таких диаграмм вашим коллегам и клиентам даже минимальные знания не понадобятся, моделирование очень наглядно и готовые диаграммы понятны интуитивно. Попробуйте, у вас также обязательно все получится.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331254/


Метки:  

История неожиданного «окирпичивания» и восстановления одного смартфона

Вторник, 20 Июня 2017 г. 01:45 + в цитатник


Началась эта история с того, что в результате неудачных экспериментов с ядром смартфона Samsung Galaxy Ace 2 (он же GT-I8160, aka codina), приводящих к ребутам девайса, оказалось так, что раздел EFS перестал читаться. Собственно, сами эксперименты отношения к данному вопросу не имеют — возможно, как-нибудь дойду и до них, но это выходит за рамки данной статьи. Хотя и раздел EFS – один из наиболее важных на этом смартфоне, убийство данного раздела само по себе не приводит к катастрофическим последствиям, поскольку его все еще можно восстановить, например, с другого телефона, после чего, при желании сменить WIFI MAC и BT MAC. На данном устройстве IMEI хранится не на разделе EFS, а CSPSA (Crash Safe Parameter Storage Area, дословно переводится как «Область хранения параметров, устойчивая к крашам»). Вот если с этим разделом пойдет что-то не так, это уже будет не столь весело, собственно об этом и пойдет речь далее. Кого заинтересовал, прошу под кат.

После выхода из строя раздела EFS, я, в первую очередь, снял его дамп и попытался поднять его при помощи e2fsck. Неудача – суперблок EXT4 поврежден, да и вообще все выглядело так, словно содержимое раздела превратилось в фарш. Самое время было поискать бэкап, но, какова беспечность (!), в самый неподходящий момент его не оказалось ни на компе, ни на флешке. Всех дальнейших мучений можно было избежать, только если бы у меня были своевременно сделанные бэкапы. Дело было поздним вечером, принявшись искать дампы этого раздела в интернете и найдя один на зарубежном ресурсе, я тут же принялся его прошивать. Наверное, одна из самых страшных вещей, что может произойти при пользовании утилитой dd — это опечатка или ошибка при наборе пути к разделу. Сейчас мне только остается удивляться собственной неосторожности (или криворукости, называйте, как хотите), но именно это и произошло… Раздел EFS на данном девайсе – это /dev/block/mmcblk0p7, но я почему-то в тот момент не имел ни тени сомнения, что это, якобы, должен быть /dev/block/mmcblk0p6. Собственно, дальнейшее не требует особых объяснений, обо всей катастрофичности произошедшего я уже понял только тогда, когда dd вывел сообщение о том, что при записи был достигнут конец раздела. Вроде далеко не первый год пользуюсь устройством и являюсь одним из тех немногих оставшихся разработчиков под этот богом забытый девайс. Как же я мог оказаться в такой, с какой стороны не посмотри, дурацкой ситуации? Не спрашивате меня, самому хотелось бы знать… Так телефон с легкой руки стал если не «кирпичом», то «инвалидом» точно.

Исследование раздела CSPSA


Итак, раздел EFS оказался убит крашем во время активной записи на диск, раздел же CSPSA, усточивый к крашам, не устоял к моей опрометчивости. Пойди я в СЦ, даже там наверняка бы развели руками. Прошивка CSPSA от другого девайса дела также не исправит, т.к. IMEI, очевидно, хранится где-то помимо данного раздела и сравнивается с тем, что находится в CSPSA. Да и статья не о смене IMEI, а об его восстановлении.

Ситуация безвыходная, как ни посмотри, думал я. Я оказался втянут в то, чем явно не планировал заниматься, ковырять внутренности раздела CSPSA. Оказалось, что среди утекших в 2014 году исходников для чипсета ST-Ericsson Novathor U8500 есть исходники на утилиты, позволяющие работать с данным разделом:
root@:/ # cd ramdisk
root@:/ramdisk # ./cspsa-cmd
[CSPSA]: open CSPSA0
[CSPSA]: 
[CSPSA]: 
[CSPSA]: ls
       Key       Size
         0          4
         1         96
         2         96
         3         96
      1000         38
     66048        497
     -8192         41
        -4          4
        -3          4
        -2          4
        -1          4

Number of keys in CSPSA : 11
Total size of all values: 884

[CSPSA]: read_to_file 3e8 /sdcard/1000.bin
[CSPSA]: sdcard/1000.bin'>
[CSPSA]: CSPSA_GetSizeOfValue(000003e8): T_CSPSA_RESULT_OK
[CSPSA]: 
[CSPSA]: 
[CSPSA]: <38 bytes written to file '/sdcard/1000.bin'.>
[CSPSA]: write_from_file 3e8 /sdcard/1000.bin
[CSPSA]: sdcard/1000.bin'>
[CSPSA]: <38 bytes read from file '/sdcard/1000.bin'.>
[CSPSA]: 
[CSPSA]: 


Команда «open CSPSA0» открывает сокет CSPSA0, таким образом подключаясь к процессу cspsa-server. Как можно видеть, команда ls отображает хранимые в CSPSA параметры и их размер.
Далее, командой read_to_file можно записать параметр (здесь это номер 1000, указаный в HEX, — 3e8) в файл, и точно также записать параметр из файла в раздел командой write_from_file.
Это конечно здорово, что удалось найти такую утилиту, но не давало мне никаких подсказок по поводу того, что должно было находиться в данных параметрах, чтобы IMEI снова читался нормально. По факту, утилита могла «скрывать» часть правды, выдавая не все параметры, и скрывая тот, в котором хранится IMEI. Для того, чтобы понять, что могло находиться в этих параметрах, нужно было иметь несколько таких различных разделов CSPSA, но в самом деле, не могу же я просить кого-то слить раздел со столь приватной информацией. В интернете нашлись два различных раздела CSPSA, но сравнение считанных через cspsa-cmd параметров выдало слишком большую разницу, около 512-768 байт суммарно при сравнении их друг с другом. Даже при наличии всех исходников, могло пройти немало времени до того, пока я бы разобрался (если разобрался вообще). Идею о восстановлении CSPSA «в лоб» пришлось оставить, обратив взгляд на другие части слитых исходников, которые бы могли помочь восстановить телефон.

Я наткнулся на еще одну утилиту, которая выглядела многообещающе.

По ссылке приведен список комманд поддерживающихся данной утилитой.
(...)
static const struct {
    const char *str;
    cops_return_code_t (*func)(cops_context_id_t *ctx,
                               int *argc, char **argv[]);
} api_funcs[] = {
    {"read_imei", cmd_read_imei},
    {"bind_properties", cmd_bind_properties},
    {"read_data", cmd_read_data},
    {"get_nbr_of_otp_rows", cmd_get_nbr_of_otp_rows},
    {"read_otp", cmd_read_otp},
    {"write_otp", cmd_write_otp},
    {"authenticate", cmd_authenticate},
    {"deauthenticate", cmd_deauthenticate},
    {"get_challenge", cmd_get_challenge},
    {"modem_sipc_mx", cmd_modem_sipc_mx},
    {"unlock", cmd_simlock_unlock},
    {"lock", cmd_simlock_lock},
    {"ota_ul", cmd_ota_simlock_unlock},
    {"get_status", cmd_simlock_get_status},
    {"key_ver", cmd_verify_simlock_control_keys},
    {"get_device_state", cmd_get_device_state},
    {"verify_imsi", cmd_verify_imsi},
    {"bind_data", cmd_bind_data},
    {"verify_data_binding", cmd_verify_data_binding},
    {"verify_signed_header", cmd_verify_signed_header},
    {"calcdigest", cmd_calcdigest},
    {"lock_bootpartition", cmd_lock_bootpartition},
    {"init_arb_table", cmd_init_arb_table},
    {"write_secprofile", cmd_write_secprofile},
    {"change_simkey", cmd_change_simkey},
    {"write_rpmb_key", cmd_write_rpmb_key},
    {"get_product_debug_settings", cmd_get_product_debug_settings}

};
(...)

Как и в предыдущем случае с cspsa-cmd, cops_cmd подключается к процессу-серверу, copsdaemon (COPS расшифровывается как COre Platform Security).
Этот самый бинарник copsdaemon на девайсе оказался отличным от того, что в исходниках (или у меня не получилось правильно сконфигурировать Android.mk), так или иначе, собранный из исходников отказывался работать. Однако, похоже утилита cops_cmd была совместима с остальным проприетарным ПО и запускалась нормально.
Первое, что я попробовал сделать — запустить команду cops_cmd read_imei — точно сейчас не вспомню, выдало, что-то вроде «error 13, device is tampered». Ага, конечно, чего еще можно было ожидать, с запоротым-то разделом CSPSA. Недолгое чтение исходников привело к команде «bind_properties»:
static cops_return_code_t cmd_bind_properties(cops_context_id_t *ctx,
        int *argc, char **argv[])
{
    cops_return_code_t ret_code;
    cops_imei_t imei;
(...)
usage:
(...)
    fprintf(stderr,
            "Usage: bind_properties imei  (15 digits)\n"
            "Usage: bind_properties keys  (keys are space delimited)\n"
            "Usage: bind_properties auth_data  \n"
            "Usage: bind_properties data  \n");
    return COPS_RC_ARGUMENT_ERROR;
}

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

В поиске идей


Прошло несколько дней в поисках и размышлениях. После общения с одним своим знакомым с xda-developers я узнал, что для разновидности GT-I8160 с чипом NFC, GT-I8160P, есть прошивка с неким дефолтным, «полу-пустым» разделом CSPSA, и что прошивка этого РОМа на данном девайсе приводит к тому, что IMEI «обнуляется», то есть все 15 цифр IMEI становятся нулями (не помню точно, происходит ли это в случае запоротого раздела CSPSA или вообще независимо от того). Первым же делом скачал данную прошивку и прошил раздел CSPSA — безрезультатно. Коллега предлагал частичную прошивку (т.е. прошивку отдельных разделов, не включая такие «опасные», как загрузчик и другие) данного РОМа. Довольно бесперспективное занятие, это могло окончательно «окирпичить» девайс. Наконец по прошествию еще пары дней, в то время, как я был занят исходниками выше, коллега с XDA сделал поистине невероятную и бесценную находку:
#TA Loader to write default IMEI
service ta_load /system/bin/ta_loader recovery
    user root
    group radio
    oneshot

Это вырезка содержимого файла init.samsungcodina.rc рамдиска из стоковой прошивки Android 4.1.2, где прямо указано в комментарии, что это сервис для восстановления IMEI по умолчанию.
Недолго думая, я запустил из терминала:
/system/bin/ta_loader recovery

Девайс перезагрузился в режим рекавери, затем еще одна перезагрузка вручную в систему, и вуаля! IMEI уже отображается не как «null», а обнуленный, регистрация в сети доступна, прогресс, однако. Тайна «обнуленного» IMEI была раскрыта.
Но это, разумеется, совсем не здорово ходить вот с таким IMEI «по умолчанию». Совсем недолгих поисков хватило, на то, чтобы глянуть на бинарник ta_loader в HEX-редакторе (исходников на эту тулзу уже не нашлось) и подменить нулевой IMEI на свой командой типа:
sed -i "s,<15_zeroes>,," /ramdisk/ta_loader
sed -i "s,0,<16_zeroes>," /ramdisk/ta_loader

Почему команда sed вызывается два раза? В бинарнике есть последовательность из более, чем 15 нулей, не относящаяся к IMEI, поэтому, чтобы вернуть нежеланное изменение, необходимо вызвать команду второй раз. Спешу заверить, пытаться записать «левый» IMEI таким образом бесполезно, утилита работает так, что записать можно только IMEI с коробки (либо дефолтный). Еще одна перезагрузка в рекавери, потом в систему, и, о чудо — IMEI на месте! Более подробно процесс восстановления я описал на форуме XDA Developers. Такие вот дела, повезло, что производитель оставил лазейку для восстановления исходного IMEI. Не случись злоключений выше, наверно, мне и в голову бы не пришло ковыряться во всем этом, но с другой стороны, и не было бы всей этой истории.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331256/


Метки:  

Автомонтирование файловых систем с systemd

Понедельник, 19 Июня 2017 г. 21:49 + в цитатник
Среди множества функций, которые предоставляет systemd, есть одна, которую несправедливо забыли. Это функция автомонтирования. При настройке автомонтирования указанный каталог будет подмонтирован только после первого обращения к нему (точнее, прямо во время).

NFS over VPN


Конкретный пример: у меня есть удалённый сервер, на котором есть интересующий меня каталог. Я хочу иметь этот каталог локально на своей машине. Протокол доступа — nfs. Т.к. он не имеет шифрования, то разумным решением выглядит использование vpn-канала до сервера.

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

Как оно устроено


Systemd имеет специальный вид automount-юнитов, которые позволяют автоматически монтировать указанный каталог.

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

Соответственно, при конфигурации:
  • Опции монтирования, устройство (или сервер в случае NFS) указываются в mount-юните
  • Зависимости и install-секция указываются в automount-юните
  • Свзяка automount-юнита и mount-юнита происходит по параметру where


Это же можно заметить по структуре самих юнитов. У mount-юнита есть секция [Mount] в которой может быть множество параметров. У automount-юнита такой секции быть не должно, а вместо этого есть секция [Automount], в которой могут быть всего несколько параметров: Where, DirectoryMode и TimeoutIdleSec.

Практический пример


/etc/systemd/system/media-nfs.mount:
[Unit]
Description=NFS share
[Mount]
What=server.url.example.com:/srv/nfs_share
Where=/media/nfs
Type=nfs4
Options=rw
DirectoryMode=0755


/etc/systemd/system/media-nfs.automount:
[Unit]
Description=NFS share
Requires=openvpn@vpn.service
Requires=network-online.target
[Automount]
Where=/media/nfs
TimeoutIdleSec=301
[Install]
WantedBy=graphical.target


Наблюдение: при том, что для mount-юнита нормальное состояние это active (mounted), то для automount — active (running), как для сервиса.

Если же automount ещё не случился, то статус будет «active (waiting)».

После настройки automount'а нужно сделать (sudo) systemctl daemon-reload, и сделать ls /media/nfs (для примера выше) — после некоторой задержки от монтирования nfs'а, мы увидим содержимое файлов на удалённом сервере.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331240/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1014 1013 [1012] 1011 1010 ..
.. 1 Календарь