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

Поиск сообщений в 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 ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

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

Место Java в мире HFT

Понедельник, 26 Июня 2017 г. 14:34 + в цитатник

В статье автор пытается проанализировать почему существуют торговые системы написанные на Java. Как может Java соперничать в области высокой производительности с C и C++? Далее размещены небольшие размышления о достоинствах и недостатках использования Java в качестве языка программирования/платформы для разработки систем HFT.

Небольшой дисклеймер: мир Java широк, и в статье я буду подразумевать именно HotSpot реализацию Java, если не сказано обратное.

1. Введение


Хочется намного рассказать про место Java в мире HFT. Для начала, давайте определимся с тем, что же такое HFT (High Frequency Trading). У этого термина существует несколько определений, объясняющих различные его аспекты. В контексте данной статьи я буду придерживаться объяснения, которое дал Питер Лаури (Peter Lawrey), создатель Java Performance User’s Group: «HFT — это торговля, которая быстрее скорости реакции человека (faster than a human can see)».

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

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

  1. Чем быстрее должна быть система, тем проще должна быть заложенная в нее модель. Т.е. если наша торговая логика реализована на FPGA, то о сложных моделях можно забыть. И наоборот, если мы пишем код не на FPGA или plain assembler, то мы должны закладывать в код более сложные модели.
  2. Сетевые задержки. Оптимизировать микросекунды имеет смысл только тогда, когда это ощутимо может сократить суммарное время обработки, которое включает сетевые задержки. Одно дело, когда сетевые задержки — это десятки и сотни микросекунд (в случае работы только с одной биржей), и совершенно другое — 20мс в каждую сторону до Лондона (а до Нью-Йорка еще дальше!). Во втором случае оптимизация микросекунд, затраченных на обработку данных, не принесет ощутимого сокращения суммарного времени реакции системы, в которое входит сетевая задержка.

Оптимизация HFT систем в первую очередь преследует сокращение не суммарной скорости обработки информации (throughput), а времени отклика системы на внешнее воздействие (latency). Что это значит на практике?

Для оптимизации по throughput важна результирующая производительность на длительном интервале времени (минуты/часы/дни/…). Т.е. для подобных систем нормально остановить обработку на какой-то ощутимый промежуток времени (миллисекунды/секунды), например на Garbage Collection в Java (привет, Enterprise Java!) если это не влечет существенного снижения производительности на длительном интервале времени.

При оптимизации по latency в первую очередь интересна максимально быстрая реакция на внешнее событие. Подобная оптимизация накладывает свой отпечаток на используемые средства. Например, если для оптимизации по throughput обычно используются примитивы синхронизации уровня ядра ОС (например, мьютексы), то для оптимизации по latency зачастую приходится использовать busy-spin, так как это минимизирует время отклика на событие.

Определив, что такое HFT, будем двигаться дальше. Где же место Java в этом «дивном новом мире»? И как Java может тягаться в скорости с такими титанами, как C, C++?

2. Что входит в понятие «производительность»


В первом приближении, разделим все аспекты производительности на 3 корзины:

  1. CPU-производительность как таковая, или скорость выполнения сгенерированного кода,
  2. Производительность подсистемы памяти,
  3. Сетевая производительность.

Рассмотрим каждую составляющую подробнее.

2.1. CPU-performance


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

Рассмотрим следующий небольшой пример:

int doSmth(int i) {
    if (i == 1) {
          goo();
    } else {
          foo();
    }
    return …;
}

При генерации кода у статического компилятора (который работает в compile-time) физически нет никакой возможности определить (если не брать в расчет PGO), какой вариант более частый: i == 1 или нет. Из-за этого, компилятор может лишь догадываться, какой сгенерированный код быстрее: #1, #2, или #3. В лучшем случае статический компилятор будет руководствоваться какой-либо эвристикой. А в худшем просто расположением в исходном коде.

Вариант #1
cmpl    $1, %edi
je      .L7
call    goo
NEXT:
...
ret
.L7:
call    foo
jmp NEXT


Вариант #2
cmpl    $1, %edi
jne      .L9
call    foo
NEXT:
...
ret
.L9:
call    goo
jmp NEXT


Вариант #3
cmpl $1, %edi
je/jne .L3
call foo/goo
jmp NEXT:
.L3:
call goo/foo
NEXT:
…
ret


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

Во-вторых, в Java есть так называемые спекулятивные оптимизации. Поясню на примере. Допустим, у нас есть код:

void doSmth(IMyInterface impl) {
    impl.doSmth();
}

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

У компилятора Java, работающего в момент работы приложения, есть дополнительная информация:

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

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

В-третьих, компилятор Java оптимизирует программу под конкретное железо, на котором он был запущен.

Статические компиляторы вынуждены использовать только инструкции достаточно древнего железа для обеспечения обратной совместимости. В результате, все современные расширения, доступные в расширениях x86, остаются за бортом. Да, можно компилировать под нескольких наборов инструкций и во время работы программы делать runtime-dispatching (например, с использованием ifunc'ов в LINUX), но кто это делает?

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

2.2. Производительность подсистемы памяти


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

2.2.1 Паттерн доступа к памяти


В разрезе паттерна доступа к памяти наиболее интересен вопрос в различии физического расположения объектов в памяти или data layout. И тут у языков С и С++ огромное преимущество — ведь мы можем явно управлять расположением объектов в памяти, а отличии от Java. Для примера рассмотрим следующий код на C++):

class A {
  int i;
};
class B {
  long l;
};
class C {
  A a;
  B b;
};
C c;

При компиляции данного кода компилятором C/C++, поля полей-подобъектов будут физически расположены последовательно, примерно таким образом (не учитываем возможный паддинг между полями и возможные data-layout трансформации, производимые компилятором):



Т.е. выражение виде ‘return c.a.i + c.b.l’ будет скомпилировано в такие инструкции ассемблера x86:

mov  (%rdi), %rax   ; << чтение c.a.i
add  ANY_OFFSET(%rdi), %rax   ; << чтение c.b.l и сложение с c.a.i
ret

Такой простой код был достигнут за счет того, что объект располагается линейно в памяти и компилятор на этапе компиляции смещения требуемых полей от начала объекта. Более того, при обращении к полю c.a.i, процессор загрузит всю кэш-линию длиной 64 байта, в которую, скорее всего, попадут и соседние поля, например c.b.l. Таким образом, доступ к нескольким полям будет относительно быстрый.

Как же будут располагаться данный объект в случае использования Java? В виду того, что объекты не могут быть значениями (в отличии от примитивных типов), а всегда ссылочные, то в процессе выполнения данные будут располагаться в памяти в виде древовидной структуры, а не последовательной области памяти:



И тогда выражение ‘c.a.i + c.b.l’ будет компилироваться в лучшем случае во что-то похожее на такой код ассемблера x86:

mov    (%rdi), %rax     ;  << загружаем адрес объекта a
mov    8(%rdi), %rdx   ;  << загружаем адрес объекта b
mov  (%rax), %rax   ;  <<  загружаем значение поля i объекта a
add    (%rdx), %rax    ;  << загружаем значение поля l объекта b

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

2.2.2. Скорость аллокации (выделения)


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

Обычно для аллокации в Java используются так называемые TLAB'ы (Thread local allocation buffer), то есть области памяти, уникальные для каждого потока. Аллокация выглядит как уменьшение указателя, указывающего на начало свободной памяти.

Например, указатель на начало свободной памяти в TLAB'е указывает на 0х4000. Для аллокации, скажем, 16 байт нужно изменить значение указателя на 0х4010. Теперь можно пользоваться свежевыделенной памятью в диапазоне 0х4000:0х4010. Более того, так как доступ к TLAB'у возможен только из одного потока (ведь это thread-local buffer, как следует из названия), то нет необходимости в синхронизации!

В языках с ручным управлением памятью, для выделения памяти обычно используются функции operator new/malloc/realloc/calloc. Большинство реализаций содержат ресурсы, разделяемые между потоками, и намного более сложны, чем описанный способ выделения памяти в Java. В некоторых случаях нехватки памяти или фрагментации кучи (heap) операции выделения памяти могут потребовать значительного времени, что ухудшит latency.

2.2.3. Скорость освобождения памяти


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

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

И теперь ввиду отсутствия в языке внятных синтаксических средств контроля за жизненным циклом ресурсов приходится использовать достаточно громоздкие конструкции типа try-finally или try-with-resources.

Сравним:

Java:

{
    try (Connection c = createConnection()) {
        ...
    }
}

или так:

{
    Connection c = createConnection();
    try {
        ...
    } finally {
        c.close();
    }
}

С тем, что можно написать в С++

{
    Connection c = createConnection();
} // деструктор будет автоматически вызван при вызоде из scope'а

Однако вернемся к освобождению памяти. Для всех сборщиков мусора, поставляемых с Java, характерна пауза Stop-The-World. Единственный способ минимизации ее влияния на производительность торговой системы (не забываем, что нам нужна оптимизация не по throughput, а по latency) — это уменьшить частоту любых остановок на Garbage Collection.

В настоящий момент наиболее употребимым способом это сделать является «переиспользование» объектов. То есть когда объект нам становится не нужен (в языках C/C++ необходимо вызвать оператор delete), мы записываем объект в некоторый пул объектов. А когда нам необходимо создать объект вместо оператора new, обращаемся к этому пулу. И если в пуле есть ранее созданный объект, то достаем его и используем, как будто он был только что создан. Посмотрим, как это будет выглядеть на уровне исходного кода:

Автоматическое управление памятью:

{
    Object obj = new Object();
    .....
    // Здесь объект уже не нужен, просто забываем про него
}

И с переиспользованием объектов:

{
    Object obj = Storage.malloc(); // получаем объект из пула
    ...
    Storage.free(obj); // возвращаем объект в пул
}

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

2.3. Сетевая производительность


Тут позиции Java вполне сравнимы с традиционными языками C и C++. Более того, сетевой стек (уровень 4 модели OSI и ниже), расположенный в ядре ОС, физически один и тот же при использовании любого языка программирования. Все настройки быстродействия сетевого стека, релевантные для C/C++, релевантны и для приложения на Java.

3. Скорость разработки и отладки


Java позволяет намного быстрее развивать логику за счет намного большей скорости написания кода. Не в последнюю очередь, это является следствием отказа от ручного управления памятью и дуализма указатель-число. Действительно, зачастую быстрее и проще настроить Garbage Collection до удовлетворительного уровня, чем вылавливать многочисленные ошибки управления динамической памятью. Вспомним, что ошибки при разработке на C++ зачастую принимают совершенно мистический оборот: воспроизводятся в релизной сборке или только по средам (подсказка: в английском языке “среда” — самый длинный по написанию день недели). Разработка на Java в подавляющем большинстве случаев обходится без подобного оккультизма, и на каждую ошибку можно получить нормальный stack trace (даже с номерами строк!). Использование Java в HFT позволяет тратить на написание корректного кода существенно меньше времени, что влечет за собой увеличение скорости адаптации системы к постоянным изменениям на рынке.

4. Резюме


В мире HFT то, насколько успешна торговая система зависит от суммы двух параметров: скорости самой торговой системы и скорости ее разработки, развития. И если скорость работы торговой системы — критерий относительно простой и понятный (по крайней мере понятно как измерять), то скорость развития системы ощутимо сложнее в оценке. Можно представить скорость развития как сумму бесчисленного множества факторов, среди которых и скорость написания кода и скорость отладки и скорость профилирования и удобство инструментальных средств и порог входа. Также, важными факторами являются скорость интеграции идей, полученный от аналитиков-квантов (Quantitative Researcher’ов), которые, в свою очередь, могут переиспользовать код продуктовой торговой системы для анализа данных. Как мне кажется, Java — разумный компромисс между всеми этими факторами. Этот язык сочетает в себе:

  • достаточно хорошее быстродействие;
  • относительно низкий порог входа;
  • простоту инструментальных средств (К сожаления, для C++ нет сред разработки, сравнимых с IDEA);
  • возможность простого переиспользования кода аналитиками;
  • простоту работы под большими технически сложными системами.

Суммируя вышеперечисленное, можно резюмировать следующее: у Java в HFT есть своя существенная ниша. Использование Java, а не С++, ощутимо ускоряет развития системы. В вопросе производительности быстродействие Java может быть сравнимо с быстродействием C++ и кроме того, в Java есть набор уникальных, недоступных для С/С++ возможностей по оптимизации.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331608/


Метки:  

Взгляд изнутри: «On Rails!» об участии в «Противостоянии»

Понедельник, 26 Июня 2017 г. 14:20 + в цитатник


Противостояние — ежегодное мероприятие, в котором специалисты по информационной безопасности пробуют свои силы в атаке и защите, используя различные системы и программные платформы. Обычно проводится соревнование в виде реального противостояния двух команд. Первая команда атакует системы безопасности, которые поддерживаются командой защитников и экспертных центров мониторинга. Само мероприятие проводится в рамках Международного форума по практической безопасности Positive Hack Days. «Цель Противостояния — столкнуть две противоборствующие стороны в более или менее контролируемой среде, чтобы посмотреть, что победит — целенаправленные атаки или целенаправленная защита. На роль защитников и SOC пришли эксперты отрасли — интеграторы, вендоры и те, кто выполняет функцию ИБ на стороне заказчиков», — рассказывает о мероприятии член оргкомитета форума Михаил Левин.

Каждый год команды, принимающие участие в «Противостоянии», преследуют свои цели. В этом плане текущий год ничем не отличается от предыдущих. Одна из команд, On Rails!, которая представляет IBM и практикующих экспертов in-house SOC, пробовала свои силы в Противостоянии с решениями из портфеля IBM Security. Само мероприятие уже прошло, и о нем не раз и не два рассказывали в сети. Настало время и нам сделать небольшое review участия команды «On Rails!» в противостоянии «The Standoff». Команда была сформирована в конце апреля из экспертов, с которыми не страшно было пойти в бой против хакеров: Эльман Бейбутов, Роман Андреев, Андрей Курицын, Сергей Кулаков, Сергей Романов, Владимир Камышанов и другие, пожелавшие остаться неизвестными героями. Многие были знакомы между собой и даже работали в прошлом в одних компаниях, поэтому быстро удалось скоординироваться и обсудить тактику защиты.

Команде было предложено на выбор две инфраструктуры для защиты – железнодорожная или энергетическая компания. После недолго обсуждения большинство защитников отдали свои голоса за обеспечение безопасности железнодорожных перевозок. Вскоре после этого появилось название команды – «On Rails!» – и простой, но очевидный логотип дорожного знака с паровозом.



Первый момент. У команды было достаточно мало времени на подготовку, аудит защищаемой инфраструктуры и выбор средств защиты. План «А» — это упор на закрытие уязвимостей, смену дефолтных учетных записей и установку свежих версий ПО в представленной инфраструктуре. Это минимальный набор действий, который единогласно был одобрен и не требовал никаких затрат из без того ограниченного бюджета. Ключевыми технологиями защиты стали обнаружение вторжений с помощью решения IBM XGS, а в качестве системы мониторинга инцидентов ИБ использовалось решение IBM QRadar SIEM. Также использовалось opensource решение OSSEC для обнаружения вторжений на уровне хостов – им покрыли прежде всего все ноутбуки самих защитников, а также установили агентов на все ключевые сервера и рабочие станции в инфраструктуре – охватили 12 хостов сети.

Конечно, когда начался отсчет времени «The Standoff», наши средства защиты ещё не были полностью настроены, а безопасная конфигурация объектов защиты не внедрена. На самом деле это здорово: ведь, как и в реальной жизни, хакеры не будут ждать, пока безопасники наконец-то всё приведут в порядок. Поэтому в самые первые часы схватки работать пришлось в ускоренном темпе. В качестве плана «Б» Сергей Романов предложил сделать ставку на Active Response и подготовил небольшой набор скриптов для автоматизированной обратной реакции по результатам корреляции событий. Это могло пригодиться в случае, если бы хакерам удалось преодолеть периметр.

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



Третий, самый важный момент проявился в ночь со вторника на среду, когда из участников конференции остались только хакеры, защитники и организаторы. Ночь можно было охарактеризовать фразой: «Развлекались, как могли!» Ребята из «Vulners» пытались установить свою «железку» в разрыв с нашими подключениями. Очевидно, для организации атаки типа Man-in-the-Middle. Другая команда осторожно попыталась подключиться напрямую к оборудованию в стойках защитников. Как оказалось, правила даже это допускают. Пришлось заниматься настоящей физической безопасностью и прогонять их.

Действуя под покровом ночи, несколько участников «On Rails!» получили дополнительную информацию, попросту надев толстовки с капюшонами и пересев в зону хакеров за один из освободившихся столов (наверно, некоторые хакеры решили поспать). Итогами такой партизанской контрразведки стало раскрытие карты сети, которую организаторы предоставили хакерам, а также получение ценной информации о том, что команда «ЦАРКА», лидер соревнования, до железнодорожной инфраструктуры пока не добралась.

Утро тоже было интересным. Не спать совсем нам не удалось, человеческие ресурсы были все же ограничены и держать контроль 24х7 оказалось непростой задачей. На утро мы, к сожалению для себя, обнаружили, что span порт для нашей IDS не работает. Роман Андреев экстренно переключился на непрерывный мониторинг инцидентов в IBM QRadar SIEM (мы предусмотрительно завели туда Netflow), а Сергей Романов предложил остальным заняться Threat Hunting’ом. Threat Hunting подразумевает подход, при котором считается, что система уже скомпрометирована, и задача, найти этому свидетельства.

По итогу соревнований мы показали 100% SLA. Хакеры нас не взломали.



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

«Противостояние «The Standoff» позволят лучше понимать хакеров, корректировать приоритеты в технической составляющей защиты. В итоге, сохраненный уровень защищенности еще и подтверждает высокий уровень слаженности работы команды», — говорит Эльман Бейбутов, координатор команды On Rails!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331672/


Метки:  

Dlang Tour переведен на русский язык

Понедельник, 26 Июня 2017 г. 13:56 + в цитатник

Dlang Tour — это интерактивное введение в язык D.


Сделан по образцу Golang Tour.



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


Разделы тура


Начало


Helloworld, установка компилятора, компиляция и запуск программы из командной строки.


Основы D


Введение в синтаксис и основные особенности языка.


Жемчужины D


Этот раздел будет интересен даже для знающих язык.


Практически каждая статья этого раздела — описание очередной killer feature языка.


Многопоточность


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


Vibe.d


Асинхронный фреймворк на основе Fibers (сопрограмм, легковесных потоков).


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


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


  • Репозиторий DUB.
  • Awesome D — список фреймворков, библиотек, приложений и различных ресурсов по D — по примеру awesome-python
  • D Idioms — список полезных "фишек" языка D.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331670/


Метки:  

[Перевод] Ubuntu для мобильных устройств: посмертный анализ

Понедельник, 26 Июня 2017 г. 13:32 + в цитатник

Так выглядела Ubuntu Touch, когда проект анонсировали 2 января 2013 года. Изображение: Canonical

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

Чтобы резюмировать моё участие в проекте: я использовал Ubuntu Touch на Nexus 7 постоянно и периодически с момента его анонса в 2013 году и до декабря 2014 года, начал работать над приложениями Click в декабре 2014-го, начал писать статью из 15-ти частей “Hacking Ubuntu Touch” об устройстве системы в январе 2015-го, был инсайдером по программе Ubuntu Phone Insider, получил Meizu MX4 от Canonical, организовал конкурс для разработчиков приложений UbuContest и был его спонсором, работал над баг-репортами и приложениями примерно до апреля 2016 года, а затем продал или переделал все мои оставшиеся устройства в середине 2016-го. Так что думаю, что могу поделиться какими-то мыслями о проекте, его проблемах и о том, где мы могли сработать лучше.

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

1. Он не попал в прибыльную нишу


Ubuntu для ПК, ноутбуков и серверов сделал это относительно легко. Почти все эти устройства позволяют вам установить любую операционную систему, которая умеет работать с аппаратным обеспечением, так что когда Ubuntu появилась в 2004 году, её крупнейший конкурент (Microsoft) был очень уязвим. У Windows была плохая репутация, высокая цена и эта система по-свински пожирала ресурсы, так что Ubuntu оставалось всего лишь быть менее раздражающей, дешевле, легче в установке и лучше работать на более старых компьютерах. И это в точности что она сделала. У Windows и сейчас сохранилась плохая репутация, теперь даже она шпионит за пользователями, и она по-прежнему довольно дорога. Так что Ubuntu Desktop не нужно было тогда и не нужно сейчас делать многое, чтобы сохранить и увеличить аудиторию пользователей.

На серверном рынке Windows, Red Hat и особенно SUSE воспринимались как слишком консервативные решения, слишком неповоротливые и опять же слишком дорогие. Подписка Red Hat Enterprise стоит несколько сотен долларов в год, и эта подписка даже необязательно включает в себя живую человеческую поддержку. Быстроразвивающаяся, менее дорогая альтернатива с некоторой поддержкой от индустрии и гигантским количеством пакетов в репозиториях должна была заинтересовать многих, особенно для облачных решений. То, что Ubuntu выбрали образцовой операционной системой для OpenStack, тоже во многом помогло.

Но с мобильными устройствами всё иначе. Вы не можете просто прошить любую операционную систему на своём телефоне или планшете. Каждое устройство поставляется с кастомным, специально подготовленным билдом Android. Когда Ubuntu объявила о выходе на мобильный рынок в 2013 году, ни Android, ни iOS не были уязвимы, в отличие от ситуации на десктопном рынке. Люди призывали к созданию третьей альтернативы не потому что Android и iOS имели плохую репутацию или какие-то ограничения, или неудобны в использовании, а потому что они (справедливо) опасались монополии Google. Так что нападение на Android и iOS оказалось не таким простым, как на Microsoft и Red Hat на десктопном и серверном рынках.

Я помню, кто-то из Canonical говорил, что проекту нужно захватить около 1% мобильного рынка, чтобы поддерживать себя. В то время это означало продажу около 11 млн телефонов Ubuntu и пару миллионов планшетов ежегодно. Если бы вы умудрились зарабатывать хотя бы один доллар/евро на ПО и сервисах для каждого устройства, то легко оплатили бы труд более сотни разработчиков, это много денег, если правильно их использовать. В компании Jolla, которая разрабатывает Sailfish OS, было около 120 сотрудников в какой-то момент, я думаю, но там были отделы маркетинга и поддержки, которые у Canonical уже имелись в наличии. Но продажа 11 млн телефонов и пары миллионов планшетов в годы была очень амбициозной целью, учитывая, что количество пользователей Ubuntu Desktop находилось где-то в районе 20-30 млн.

  • Возможность № 1 добиться одного процента. Быть настолько лучше конкурентов, что вы становитесь стандартом и уже даже не беспокоитесь о каком-то одном проценте. Думаю, мы все знали, что такое невозможно, особенно это стало ясно после того, как все важные сервисы (WhatsApp, Google, Twitter, Instagram и др.) даже не позволяли клонировать их приложения для запуска на устройствах Ubuntu. Canonical не сделала свой собственный клиент Telegram, когда первые коммерческие телефоны Ubuntu вышли на рынок, там вообще не было никакого мессенджера. И это в 2015 году, когда все обмениваются текстовыми сообщениями постоянно. Никто не хотел платить те же деньги за телефон Ubuntu, если он не может делать те же вещи, что и такая же модель под Android, даже если его позиционируют как «устройство для разработчика».
  • Возможность № 2 добиться одного процента. Позиционироваться в ниши с глубокими карманами. Canonical слишком сконцентрировалась в нише «Конвергенция», которая не была интересна большому количеству людей, в то же время она игнорировала всех хакеров, мейкеров и людей, которые наелись слежкой со стороны Microsoft, Google и АНБ. Немногие были готовы платить премиальную цену за телефон, который может превратиться в тормознутый ноутбук при подключении к внешнему дисплею, но зато многие были готовы платить премиальную цену за Blackphone.


2. Неудобство для пользователя и искажённые приоритеты


Хочу быть честным: после получения первых нескольких обновлений over-the-air (OTA) я спросил себя: «Будут ли bq и Meizu, а особенно их пользователи мириться с этим?» Телефоны тормозили, их нужно было регулярно перезагружать. Meizu MX4 перегревался. Индикатор батареи часто показывал ложные данные. Мобильные данные работали ненадёжно, (национальный) роуминг часто вообще не работал. Сервис определения местоположения был очень ненадёжен. Телефон не всегда подавал сигнал при входящем звонке или вы не могли сделать исходящий вызов, потому что UI спрятал кнопки. На будильник нельзя было положиться. Bluetooth поддерживал только аудиоустройства, а позже устройства ввода, но никакой передачи файлов даже в базовом виде. WiFi не мог подключиться к сетям WPA Enterprise вплоть до пятого обновления OTA-5. Мне кажется, в какой-то момент аудиоплееер даже начал удалять файлы в процессе их индексации. И так далее.

Список вещей, которые должны были работать, но не работали, очень длинный. Что ещё хуже, несколько раз баги возвращались через несколько обновлений OTA, как регрессия. Во время существования проекта для телефонов/планшетов количество сообщений о багах на Launchpad взлетело так, как я никогда прежде не видел.

Искоренение всех этих багов не являлось главным приоритетом, а разработчики тратили основную часть времени на поддержку большего количества железа (Meizu Pro 5, bq Aquaris 10) и на обеспечение конвергенции. До последнего дня существования проекта пользователи, с которыми я разговаривал, не были довольны устройством. Только те, кто пользовался самым базовым функционалом, как мой отец, у которого даже не была включена функция передачи данных и он делал один звонок в два дня, были довольны, потому что устройство работало днями без подзарядки. Впрочем, купить смартфон за 150 евро, а затем не использовать функции, которые делают его «смарт», не имеет особого смысла.


Как должна была выглядеть конвергенция. Изображение: Canonical

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

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

3. Устройства было сложно раздобыть и они устаревали


Я думаю, мы все можем согласиться, что реально раздобыть устройство было слишком трудно. Я купил свой первый Nexus 7 в магазине, а Nexus 4 на eBay, но когда проект действительно вышел на серьёзные обороты, эти устройства уже устарели, их стало труднее достать, а вскоре для них перестали выходить официальные билды образов. Устройства bq хотя бы продавались по всей Европе, но чаще всего на странице стояла пометка “out of stock”. Раздобыть MX4 было практически невозможно для всякого, кто не участвовал в программе Ubuntu Phone Insiders. Если людям из США даже и удавалось получить его, то он не подключался к мобильным сетям на полной скорости.

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



С другой стороны, то устройство, которое большинство ждали — исключительно высокопроизводительный Ubuntu Edge — оказалось другим. Устройства bq были дешёвыми, с маленьким объёмом встроенной памяти и только с поддержкой 3G. В MX4 был большой экран, высокая скорость и 4G, но больше ничего, даже отсутствовал разъём для карт SD. Выход HDMI, необходимый для конвергенции, отсутствовал на всех официальных телефонах, а Miracast/Aethercast не был равноценной заменой. Многие думали, что Ubuntu раскроет полный потенциал их железа, например, FM-радио на Aquaris E4.5/E5, но такого не было даже в планах, а без исходников драйверов под Android было практически невозможно добавить такую фичу.

Многие также ожидали, что их телефоны Ubuntu будут изначально более безопасными, чем Android, потому что здесь open source и частые обновления. Очевидно, это было не так, драйверы Android и софт для мобильного передатчика по-прежнему оставались проприетарными и небезопасными, и при этом с полным доступом к железу. Немногие это осознавали.

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


Я тратил огромное количество времени каждый день, пытаясь поспеть за разработкой, но обычно даже я не знал, что появится в следующем OTA, а что уберут. Списки почтовой рассылки, IRC, каналы Telegram, Launchpad, официальные веб-сайты, приватные разговоры между разработчиками, спринты, Ubuntu Online Summit — это было слишком. И это даже не упоминая все секретные разговоры в Canonical, когда они хотели сохранить новость в тайне, чтобы гарантировать максимальное освещение в СМИ в момент анонса.

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

Человек, работающий над исходниками ядра, мог быть где-то в Азии. Сотрудник, который отвечает за все Q&A, мог быть где-то в США. Я был в Европе. Наше рабочее время в реальности не особенно пересекалось. Так что в некоторые дни мне приходилось разговаривать с парнем из Азии в 8:00 утра, пока он не ушёл с работы, а потом с человеком из США в полдень или ночью, когда там только начинается рабочий день.


Рекламируемые функции bq Aquaris E4.5 Ubuntu Edition. Заметьте отсутствие слов «конвергенция», HDMI, FM-радио и многих других вещей, которые люди ожидали, но маркетинг им этого не дал. Изображение: bq

Должен сказать, что я многое узнал от отдела маркетинга, особенно относительно «ожиданий и реальности». Например, многие предполагали как нечто само собой разумеющееся, что Aquaris E4.5/E5 и MX4 получат функцию конвергенции с более поздним обновлением OTA, но ни производители, ни Canonical не обещали это при продаже устройств. До самого момента отмены проекта большинство людей про себя предполагали, что смогут запускать те же приложения, что и на десктопе (Firefox, SIP-клиенты и др.) и управлять приложениями при помощи apt-get, и вот здесь маркетинг стал просто вводить в заблуждение. Было слишком много акцентов на том, что «это та же самая Ubuntu», хотя на самом деле это не так. Не могу припомнить, как часто мне приходилось объяснять случайным людям на различных каналах поддержки, что Firefox не запустится, а apt-get всё сломает. Часто люди очень удивлялись, узнав, что Ubuntu для мобильных настолько отличается.

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


У меня такое чувство, что анонс новой и независимой мобильной операционной системы стал хорошей причиной для архитекторов сказать: «Да, давайте сделаем это, но давайте сделаем это Правильным Способом, и будем лучше остальных». Ubuntu должна была не просто предоставить графический интерфейс пользователя, но такой интерфейс, который будет работать на всех устройствах и в любых форм-факторах. Она не просто изолирует приложения друг от друга, как делает ядро Linux и Android, а реализует полноценную песочницу с защитой данных и приватности. Она магически сделает так, что работающие приложения не будут расходовать заряд батареи. И так далее. Что бы другие не сделали с технической стороны, Ubuntu должна сделать лучше и более элегантным способом.




Не всё это для меня имело смысл. Выпуск Unity 8 был необходим, потому что Unity 7 зависела от Compiz и не очень хорошо подходила для работы на множестве форм-факторов с поворотными дисплеями и т. д. Но единственным делом для Mir была замена X.Org и SurfaceFlinger, так что Unity 8 могла использовать единый API на десктопах и мобильных устройствах. Я не эксперт по графическим технологиям и API, но мне кажется, что хотя бы с точки зрения «у нас не хватает рабочих рук» разработка полностью нового графического сервера, который никто больше не хочет использовать и который не добавляет ничего особенного по сравнению с существующими альтернативами, — это то, чего следовало избегать любой ценой. Особенно если пользователь никогда не увидит разницу. Ubuntu Touch спокойно использовала Android SurfaceFlinger до конца 2013 года.

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

Ещё один хороший пример — запланированный фреймворк для сообщений. Вы должны были получить одно системное приложение для всех типов сообщений, будь то Jabber/XMPP, SMS, Telegram или WhatsApp, а сторонние сервисы могли выпускать плагины для своих протоколов. Этот фреймворк был одной из основных причин, почему приложениям запрещали работать в фоновом режиме. Так что вы не могли просто сделать отдельный XMPP-клиент, который бы получал сообщения в фоне. Но фреймворк для сообщений, к которому вы должны были выпустить плагин, задерживался и в итоге так никогда и не вышел. Даже клиент Telegram не мог работать в фоне, он мог показывать только всплывающие сообщения, потому что Canonical убедила разработчиков Telegram изменить их серверный код (!) для поддержки сервиса Ubuntu Push Notification.

Некоторые ключевые разработчики в Canonical действительно думали, что Ubuntu настолько важна, что все сервис-провайдеры изменят свои серверные коды для поддержки Ubuntu Push Notification, и это решит проблему. Никто кроме Telegram даже не задумался об этом.

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

6. Жизнь разработчиков приложений была слишком сложной


Современная мобильная ОС — это больше, чем ОС. Это экосистема. И вот здесь Ubuntu провалилась сильнее всего.

Ubuntu для мобильных устройств оказалась фундаментально несовместима с любым окружением для исполнения программ, какое существовало до него. Она не могла запускать приложения Android, Windows, X11 или iOS. Вы не могли просто перекомпилировать приложения Android, Windows, X11 или iOS. Графическая система, системные сервисы, песочница, набор базовых библиотек — всё было другим. Она даже полностью отличалась от Ubuntu Desktop. Можете целыми днями говорить, что «Это та же самая Ubuntu», но если я даже не могу протестировать свои приложения на десктопе, потому что там не запускается Mir, то это не та же самая Ubuntu и мне нужно разрабатывать для двух разных платформ.

Canonical пришла и сделала целый SDK, Integrated Development Environment на базе Qt Creator, плюс среду кросс-компиляции, плюс полностью новый набор компонентов Ubuntu QML. Я действительно не хочу никого здесь обидеть, но помимо неиспользования существующего кода, то, как всё это было сделано, оказалось крайне запутанным и стало разочарованием для разработчиков приложений. Ничего не работало, всё изменялось и ломалось постоянно. Иногда SDK был сломан неделями. Появились схемы версионирования, но ваше приложение всё равно не работало.

В какой-то момент мне пришлось пересобирать и обновлять моё приложение glmark2 в каталоге, потому что вышел OTA с обновлёнными клиентскими библиотеками Mir, хотя ОС заявляла тот же уровень совместимости, что и раньше. Затем стало ясно, что схема версионирования просто гарантирует, что официальный метод написания приложения гарантированно работает, но официальный метод — это просто QML и HTML5. Программа glmark2 взаимодействовала напрямую с Mir, как и многие другие (например, игры с использованием SDL). Приложения в каталоге могли просто прекратить работать, если не проверять и обновлять их после каждого OTA. Вы по-прежнему можете запускать старые Android-приложения на современном Android-смартфоне, но вот приложение Click с прошлого года может прекратить работу после следующего OTA, если вы не отслеживаете его постоянно. Я помню яркую дискуссию в IRC в конце 2015 года, во время которой несколько разработчиков Canonical были озадачены этим фактом и спрашивали у сотрудников группы SDK, как, по их мнению, разработчикам приложений работать в таких условиях.


Рендеринг bq Aquaris E4.5 с игрой Panda Love, одним из моих приложений в Click Store

Я начинал как разработчик приложений. Что бы я ни хотел сделать, начинать приходилось практически с нуля. Сделать GUI? Поддерживался только QML с компонентами Ubuntu QML, а QML не назовёшь устоявшейся экосистемой с большим количеством существующего кода и хорошим инструментарием. Просто использовать одну из существующих библиотек UI? Они все предназначены для работы с X11 или, может быть, Wayland, и прошло немало времени, пока SDL и прочие получили бэкенды для Mir. Коммуникации с железом и системными сервисами? Из-за песочницы было трудно обращаться напрямую к специализированным сервисам Ubuntu через D-Bus, к большинству «стандартных» процессов вроде NetworkManager нельзя было обращаться изнутри песочницы. Скачать что-нибудь в фоновом режиме? Для этого нужно обращаться к специальному менеджеру скачиваний Ubuntu. Получить уведомления о событиях за пределами телефона? Только если интегрируете всё с сервисом Ubuntu Push Notification.

Вот почему мне пришлось начинать работу с самой базовой системы. Тогда в январе 2015-го я хотел сделать сканеры WiFi и Bluetooth, но всех необходимых API и системных сервисов просто ещё не существовало. Многие из отсутствующих API и системных сервисов так никогда и не появились.

Всё это делало платформу крайне непривлекательной для большинства сторонних разработчиков. Они не видели, как могут окупиться их инвестиции в создание ещё одной версии приложения с нуля, особенно с учётом маленькой пользовательской базы. Я не помню ни одного приложения, которое в Click Store закачал бы его «оригинальный» разработчик. Даже клиент Telegram разработала сама Canonical.

Так что многие из нас создавали простенькие веб-приложения или клонировали существующие приложения. И немедленно столкнулись с проблемой, что многие приложения полагаются на некий вид несвободного онлайнового сервиса с очень невыгодными условиями использования. Лично я разработал BD Navigator, клон Deutsche Bahn Navigator. Я провёл обратную разработку их клиент-серверного протокола до той точки, где мог копировать практически всё, кроме покупки настоящего билета на поезд, но они встроили небольшой фрагмент криптографии, а использование краденых криптографических ключей в Германии незаконно. Я спросил разрешения у Deutsche Bahn, они отказали. В конце концов всё приложение целиком деградировало до уровня величественного веб-контейнера с закладками на их мобильные веб-страницы.

Точно то же самое справедливо для WhatsApp, Twitter, Instagram, Google Plus, Google Drive и других. Мы можем скопировать много чего, но сервис-провайдеры не разрешают нам делать это. Говорят, что WhatsApp запросил семизначную сумму просто за доступ к их API, а не за разработку полноценного клиента. Instagram настолько закрыл свои API, что даже встроенный Instagram Scope пришлось удалить. У Google для многих сервисов нет публичного API.

(Также небольшое количество нердов open source никогда бы не смогли поддерживать актуальную коллекцию клонов для всех популярных приложений. Это просто не масштабируется).

7. Она не была такой открытой и не пользовалась такой общественной поддержкой, как предполагалось


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

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

  • Исходный код всего, что мы разрабатывали, был где-то распределён по неизвестному количеству проектов Launchpad.
  • Исходники ядра на GitHub часто были устаревшими.
  • Код всех проприетарных драйверов Android и другого софта был доступен только сотрудникам Canonical.
  • У Canonical и её коммерческих партнёров имелась полностью приватная зона Launchpad с приватными баг-репортами. Довольно часто в публичных баг-репортах встречались ссылки на приватные страницы, так что у вас была только половина информации.
  • Большую часть информации о будущих устройствах сообщество получало с помощью поиска случайных утечек информации, по большей мере на paste.ubuntu.com.
  • Узнав о будущей фиче, мы часто обнаруживали, что соответствующий проект Launchpad открыт неделями или месяцами ранее под кодовым названием или что разработчики Canonical месяцами работают над ним в приватных репозиториях. Например, так было с Aethercast.
  • Не будучи сотрудником Canonical, вам было трудно понять, над чем идёт работа, что запланировано и где вы можете помочь.
  • Если вы нашли, где помочь, то очень трудно установить контакт с разработчиками Canonical. У них рабочий день как минимум восемь часов, но у вас нет восьми часов свободного времени, а ваше свободное время часто не совпадает с их рабочим графиком.
  • У меня никогда не возникало ощущение, что пожелания пользователей и более широкого сообщества имеет какое-то влияние на список будущих фич или на то, что войдёт в следующий OTA. Во многих случаях баг-репорты Launchpad и запросы функций с наибольшей поддержкой задерживались дольше остальных.

FAQ


Вот некоторые вопросы, которые мне иногда задают.

Сколько устройств вы купили для разработки?


Думаю, что купил два новых Nexus 7, два использованных Nexus 4, три новых bq Aquaris E4.5 и два дешёвых китайских телефона Mediatek (для реверс-инжиниринга) специально для работы с Ubuntu. Также у меня был MX4 от Canonical. Думаю, я потратил где-то больше тысячи евро на семь телефонов и два планшета.

Вы когда-нибудь оценивали затраченное время?


Да. После всех расчётов у меня вышло шесть человеко-месяцев за полуторалетний период или объём работы, аналогичный тому, если бы Canonical наняла меня на 30% ставки.

Вы жалеете, что потратили столько времени и усилий?


Нет

Когда вы впервые начали сомневаться, что всё получится?


Если не ошибаюсь, это было в районе Рождества 2015 года. Большая шумиха вроде как закончилась, и стало ясно, что мы никогда не получим полноценные приложения WhatsApp, Twitter и другие, а для многих владельцев телефонов планируется не так уже много «реально» важной функциональности. Шла работа над конвергенцией для планшета, но немногим удалось заполучить bq Aquaris M10.

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

Вы ушли в середине 2016-го, задолго до закрытия проекта. Почему?


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

С другой стороны, я больше не чувствовал, что работа над проектом приносит мне радость. Иногда я думал «Я делаю недостаточно, это моя вина», просидев над устройством восемь часов подряд. Не такие чувства должны быть у человека, который работает над проектом в свободное время ради удовольствия.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331658/


Когда мне вышлют оффер? Подсказки для соискателей от HR-менеджера

Понедельник, 26 Июня 2017 г. 13:26 + в цитатник


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

Как правило, в представлении соискателя процесс довольно прямолинейный.



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



Как открывается вакансия?


В Appodeal сначала определяется потребность в новом сотруднике — руководитель команды (Team Lead) обращается с запросом к HR. Потребность в вакансии согласовывается с Head of Moscow Office. Вакансия вносится в рекрутинговый план CIS-региона (это cтраны СНГ) и на нее заполняется отдельная заявка.

После инициирования вакансии мы составляем ее описание — здесь указываются общая информация и требования к кандидату, а также расписывается процесс подбора.
Работа над вакансией — стандартный процесс по поиску, привлечению и отбору кандидатов. Ничего сверхъестественного в этом этапе нет, однако при подачи заявки не стоит забывать, что кроме вас у специалиста есть от 5 до 15 кандидатов. Их заявки и резюме тоже нужно детально изучить, а после — провести одно или несколько интервью, которые занимают от 1 до 2 часов рабочего времени. Именно поэтому не стоит паниковать, если вам не перезвонили через два дня после интервью — HR просто обязан рассмотреть всех кандидатов и не может сделать стремительный выбор в вашу пользу в силу своих должностных обязательств.

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

Что может повлиять на сроки?


Случается и так, что вакансия была приостановлена. HR-специалисты — тоже люди, и они тоже уходят в отпуска и заболевают. Соответственно, поиск кандидатов приостанавливается. Иногда в процессе поиска пересматривается рекрутинговый план — количество вакансий или требование к кандидатам, о чем вам тоже должны сообщить (по крайней мере, мы сообщаем). Вакансия считается закрытой, когда кандидат найден, принял Job Offer и вышел на работу или вакансия отменена из-за пересмотра плана и отсутствия потребности в сотруднике. HR может вздохнуть спокойно только тогда, когда его кандидат прошел испытательный срок. Как правило, вакансию переносят в архив только после выхода сотрудника на работу. Поэтому вакансия еще некоторое время может висеть на сайте компании (или на HR-ресурсах), а ваши отклики — просто разбираться, добавляться в базу. Кандидатам в этот период будет приходить стандартное сообщение о рассмотрении.
Как только принятый кандидат проходит испытательный срок, HR-специалист меняет статус вакансии на «закрыта» на всех ресурсах, фиксирует данные о сотруднике и планируемую дату выхода на работу в специальной таблице.
Чем выше уровень навыков специалиста и степень его ответственности, тем больше времени занимает его поиск и отбор кандидатов.

Ниже — таблица сроков, на которую можно ориентироваться, если вы подали резюме. Мы в Appodeal стараемся следовать потребностям бизнеса и закрываем вакансии по принципу “чем скорее, тем лучше”, то есть, HR работают на полную катушку и опережает сроки, указанные в таблице:)



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



Особое внимание уделите информации о компании


Невероятно, но факт: нам очень часто встречаются кандидаты, которые понятия не имеют, чем мы занимаемся. Узнать подробности и задать вопросы — отличный способ понравиться HR и понять, подходите ли вы компании и, что немаловажно, подходит ли она вам. На сайтах компании (в том числе, и на нашем) в разделе “Карьера”, “Вакансии” или “Работа у нас” часто прописаны основные ценности компании, есть фотографии офиса и потенциальных коллег. Не поленитесь вбить в поисковик название компании плюс “интервью” или “статья”, чтобы почитать, что пишут о будущем месте работы в СМИ, если пишут вообще. Полчаса потраченного времени и искренняя заинтересованность в том, чем занимается компания, могут здорово сыграть вам на руку — а вот явное безразличие не спасет даже с учетом хорошего резюме.

Почему важно найти рекомендателя среди сотрудников компании?


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

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

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

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

https://habrahabr.ru/post/331666/


Автоэнкодеры в Keras, Часть 4: Conditional VAE

Понедельник, 26 Июня 2017 г. 13:25 + в цитатник

Содержание



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

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


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

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



Сначала подумаем о причинах 1-го недостатка:


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

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

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

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

Код
# Импорт необходимых библиотек
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns

# Создание датасета
x1 = np.linspace(-2.2, 2.2, 1000)
fx = np.sin(x1)
dots1 = np.vstack([x1, fx]).T

t = np.linspace(0, 2*np.pi, num=1000)
dots2 = 0.5*np.array([np.sin(t), np.cos(t)]).T + np.array([1.5, -0.5])[None, :]

dots = np.vstack([dots1, dots2])
noise = 0.06 * np.random.randn(*dots.shape)

labels = np.array([0]*1000 + [1]*1000)
noised = dots + noise


# Визуализация
colors = ['b']*1000 + ['g']*1000
plt.figure(figsize=(15, 9))
plt.xlim([-2.5, 2.5])
plt.ylim([-1.5, 1.5])
plt.scatter(noised[:, 0], noised[:, 1], c=colors)
plt.plot(dots1[:, 0], dots1[:, 1],  color="red",    linewidth=4)
plt.plot(dots2[:, 0], dots2[:, 1],  color="yellow", linewidth=4)
plt.grid(False)

# Модель и обучение
from keras.layers import Input, Dense
from keras.models import Model
from keras.optimizers import Adam

def deep_ae():
    input_dots = Input((2,))
    x = Dense(64, activation='elu')(input_dots)
    x = Dense(64, activation='elu')(x)
    code = Dense(1, activation='linear')(x)
    x = Dense(64, activation='elu')(code)
    x = Dense(64, activation='elu')(x)
    out = Dense(2, activation='linear')(x)

    ae = Model(input_dots, out)
    return ae

dae = deep_ae()
dae.compile(Adam(0.001), 'mse')
dae.fit(noised, noised, epochs=300, batch_size=30, verbose=2)

# Результат
predicted = dae.predict(noised)

# Визуализация
plt.figure(figsize=(15, 9))
plt.xlim([-2.5, 2.5])
plt.ylim([-1.5, 1.5])
plt.scatter(noised[:, 0], noised[:, 1], c=colors)
plt.plot(dots1[:, 0], dots1[:, 1],  color="red",    linewidth=4)
plt.plot(dots2[:, 0], dots2[:, 1],  color="yellow", linewidth=4)
plt.scatter(predicted[:, 0], predicted[:, 1], c='white', s=50)
plt.grid(False)



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

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

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

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

Код
from keras.layers import concatenate

def deep_cond_ae():
    input_dots = Input((2,))
    input_lbls = Input((1,))
    full_input = concatenate([input_dots, input_lbls])
    x = Dense(64, activation='elu')(full_input)
    x = Dense(64, activation='elu')(x)
    code = Dense(1, activation='linear')(x)

    full_code = concatenate([code, input_lbls])
    x = Dense(64, activation='elu')(full_code)
    x = Dense(64, activation='elu')(x)
    out = Dense(2, activation='linear')(x)

    ae = Model([input_dots, input_lbls], out)
    return ae

cdae = deep_cond_ae()
cdae.compile(Adam(0.001), 'mse')
cdae.fit([noised, labels], noised, epochs=300, batch_size=30, verbose=2)


predicted = cdae.predict([noised, labels])

# Визуализация
plt.figure(figsize=(15, 9))
plt.xlim([-2.5, 2.5])
plt.ylim([-1.5, 1.5])
plt.scatter(noised[:, 0], noised[:, 1], c=colors)
plt.plot(dots1[:, 0], dots1[:, 1],  color="red",    linewidth=4)
plt.plot(dots2[:, 0], dots2[:, 1],  color="yellow", linewidth=4)
plt.scatter(predicted[:, 0], predicted[:, 1], c='white', s=50)
plt.grid(False)



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

CVAE


Если же теперь взять VAE, как в предыдущей части, и подавать на вход еще и лейблы, то получится Conditional Variational Autoencoder (CVAE).

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


Картинка выше из [2]

В этом случае основное уравнение VAE из прошлой части становится просто conditioned на Y (Y не обязан быть дискретным), то есть на лейбле.

\log P(X|Y;\theta_2) - KL[Q(Z|X,Y;\theta_1)||P(Z|X,Y;\theta_2)] = E_{Z \sim Q}[\log P(X|Z,Y;\theta_2)] - KL[Q(Z|X,Y;\theta_1)||N(0,I)]

Q(Z|X,Y;\theta_1) мы опять сравниваем с N(0,I).
Это можно интерпретировать так: для каждого Y у нас отдельный автоэнкодер VAE, при этом у них огромное количество общих весов (почти абсолютный weight sharing).

В результате получается, что CVAE кодирует в Z свойства входного сигнала общие для всех Y.

Перенос стиля


(Комментарий: это не то же самое, что перенос стиля в Prisme, там совсем другое)

Теперь становится понятно, как создавать новые картинки в стиле заданной:
  1. обучаем CVAE на картинках с лейблами,
  2. кодируем стиль заданной картинки в Z,
  3. меняя лейблы Y, создаем из закодированного Z новые картинки.

Код на Keras


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

Код
import sys
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# import seaborn as sns

from keras.datasets import mnist
from keras.utils import to_categorical
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test  = x_test .astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test  = np.reshape(x_test,  (len(x_test),  28, 28, 1))

y_train_cat = to_categorical(y_train).astype(np.float32)
y_test_cat  = to_categorical(y_test).astype(np.float32)
num_classes = y_test_cat.shape[1]

batch_size = 500
latent_dim = 8
dropout_rate = 0.3
start_lr = 0.001

from keras.layers import Input, Dense 
from keras.layers import BatchNormalization, Dropout, Flatten, Reshape, Lambda
from keras.layers import concatenate
from keras.models import Model
from keras.objectives import binary_crossentropy
from keras.layers.advanced_activations import LeakyReLU
from keras import backend as K


def create_cvae():
    models = {}

    # Добавим Dropout и BatchNormalization
    def apply_bn_and_dropout(x):
        return Dropout(dropout_rate)(BatchNormalization()(x))

    # Энкодер
    input_img = Input(shape=(28, 28, 1))
    flatten_img = Flatten()(input_img)
    input_lbl = Input(shape=(num_classes,), dtype='float32')

    x = concatenate([flatten_img, input_lbl])
    x = Dense(256, activation='relu')(x)
    x = apply_bn_and_dropout(x)
    # Предсказываем параметры распределений
    # Вместо того чтобы предсказывать стандартное отклонение, предсказываем логарифм вариации
    z_mean = Dense(latent_dim)(x)
    z_log_var = Dense(latent_dim)(x)

    # Сэмплирование из Q с трюком репараметризации
    def sampling(args):
        z_mean, z_log_var = args
        epsilon = K.random_normal(shape=(batch_size, latent_dim), mean=0., stddev=1.0)
        return z_mean + K.exp(z_log_var / 2) * epsilon
    l = Lambda(sampling, output_shape=(latent_dim,))([z_mean, z_log_var])

    models["encoder"]  = Model([input_img, input_lbl], l, 'Encoder') 
    models["z_meaner"] = Model([input_img, input_lbl], z_mean, 'Enc_z_mean')
    models["z_lvarer"] = Model([input_img, input_lbl], z_log_var, 'Enc_z_log_var')

    # Декодер
    z = Input(shape=(latent_dim, ))
    input_lbl_d = Input(shape=(num_classes,), dtype='float32')
    x = concatenate([z, input_lbl_d])
    x = Dense(256)(x)
    x = LeakyReLU()(x)
    x = apply_bn_and_dropout(x)
    x = Dense(28*28, activation='sigmoid')(x)
    decoded = Reshape((28, 28, 1))(x)

    models["decoder"] = Model([z, input_lbl_d], decoded, name='Decoder')
    models["cvae"]    = Model([input_img, input_lbl, input_lbl_d], 
                              models["decoder"]([models["encoder"]([input_img, input_lbl]), input_lbl_d]), 
                              name="CVAE")
    models["style_t"] = Model([input_img, input_lbl, input_lbl_d], 
                               models["decoder"]([models["z_meaner"]([input_img, input_lbl]), input_lbl_d]), 
                               name="style_transfer")
    
    
    def vae_loss(x, decoded):
        x = K.reshape(x, shape=(batch_size, 28*28))
        decoded = K.reshape(decoded, shape=(batch_size, 28*28))
        xent_loss = 28*28*binary_crossentropy(x, decoded)
        kl_loss = -0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
        return (xent_loss + kl_loss)/2/28/28

    return models, vae_loss

models, vae_loss = create_cvae()
cvae = models["cvae"]

from keras.optimizers import Adam, RMSprop
cvae.compile(optimizer=Adam(start_lr), loss=vae_loss)

digit_size = 28
def plot_digits(*args, invert_colors=False):
    args = [x.squeeze() for x in args]
    n = min([x.shape[0] for x in args])
    figure = np.zeros((digit_size * len(args), digit_size * n))

    for i in range(n):
        for j in range(len(args)):
            figure[j * digit_size: (j + 1) * digit_size,
                   i * digit_size: (i + 1) * digit_size] = args[j][i].squeeze()

    if invert_colors:
        figure = 1-figure

    plt.figure(figsize=(2*n, 2*len(args)))
    plt.imshow(figure, cmap='Greys_r')
    plt.grid(False)
    ax = plt.gca()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    plt.show()


n = 15 # Картинка с 15x15 цифр

from scipy.stats import norm
# Так как сэмплируем из N(0, I), то сетку узлов, в которых генерируем цифры, берем из обратной функции распределения
grid_x = norm.ppf(np.linspace(0.05, 0.95, n))
grid_y = norm.ppf(np.linspace(0.05, 0.95, n))

def draw_manifold(generator, lbl, show=True):
    # Рисование цифр из многообразия
    figure = np.zeros((digit_size * n, digit_size * n))
    input_lbl = np.zeros((1, 10))
    input_lbl[0, lbl] = 1
    for i, yi in enumerate(grid_x):
        for j, xi in enumerate(grid_y):
            z_sample = np.zeros((1, latent_dim))
            z_sample[:, :2] = np.array([[xi, yi]])

            x_decoded = generator.predict([z_sample, input_lbl])
            digit = x_decoded[0].squeeze()
            figure[i * digit_size: (i + 1) * digit_size,
                   j * digit_size: (j + 1) * digit_size] = digit
    if show:
        # Визуализация
        plt.figure(figsize=(10, 10))
        plt.imshow(figure, cmap='Greys_r')
        plt.grid(False)
        ax = plt.gca()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        plt.show()
    return figure


def draw_z_distr(z_predicted, lbl):
    # Рисование рпспределения z
    input_lbl = np.zeros((1, 10))
    input_lbl[0, lbl] = 1
    im = plt.scatter(z_predicted[:, 0], z_predicted[:, 1])
    im.axes.set_xlim(-5, 5)
    im.axes.set_ylim(-5, 5)
    plt.show()

from IPython.display import clear_output
from keras.callbacks import LambdaCallback, ReduceLROnPlateau, TensorBoard

# Массивы, в которые будем сохранять результаты для последующей визуализации
figs = [[] for x in range(num_classes)]
latent_distrs = [[] for x in range(num_classes)]
epochs = []

# Эпохи, в которые будем сохранять
save_epochs = set(list((np.arange(0, 59)**1.701).astype(np.int)) + list(range(10)))

# Отслеживать будем на вот этих цифрах
imgs = x_test[:batch_size]
imgs_lbls = y_test_cat[:batch_size]
n_compare = 10

# Модели
generator      = models["decoder"]
encoder_mean   = models["z_meaner"]


# Функция, которую будем запускать после каждой эпохи
def on_epoch_end(epoch, logs):
    if epoch in save_epochs:
        clear_output() # Не захламляем output

        # Сравнение реальных и декодированных цифр
        decoded = cvae.predict([imgs, imgs_lbls, imgs_lbls], batch_size=batch_size)
        plot_digits(imgs[:n_compare], decoded[:n_compare])

        # Рисование многообразия для рандомного y и распределения z|y
        draw_lbl = np.random.randint(0, num_classes)
        print(draw_lbl)
        for lbl in range(num_classes):
            figs[lbl].append(draw_manifold(generator, lbl, show=lbl==draw_lbl))
            idxs = y_test == lbl
            z_predicted = encoder_mean.predict([x_test[idxs], y_test_cat[idxs]], batch_size)
            latent_distrs[lbl].append(z_predicted)
            if lbl==draw_lbl:
                draw_z_distr(z_predicted, lbl)
        epochs.append(epoch)


# Коллбэки
pltfig = LambdaCallback(on_epoch_end=on_epoch_end)
# lr_red = ReduceLROnPlateau(factor=0.1, patience=25)
tb     = TensorBoard(log_dir='./logs')


# Запуск обучения 
cvae.fit([x_train, y_train_cat, y_train_cat], x_train, shuffle=True, epochs=1000,
         batch_size=batch_size,
         validation_data=([x_test, y_test_cat, y_test_cat], x_test),
         callbacks=[pltfig, tb],
         verbose=1)


Результаты


(Извиняюсь, что местами белые цифры на черном фоне, а местами черные на белом)

Переводит цифры этот автоэнкодер вот так:


Сгенерированные цифры каждого лейбла сэмплированные из N(0|I):

(Отлично видно как общие черты закодированы в координатах Z)


Генерация цифр заданного лейбла из Z и распределение Z для каждого лейбла


Тяжелые гифки

Перенос стиля этой моделью


В качестве источников стиля возьмем первые десять «7»-ок, и на основе их кода Z создадим остальные цифры.

Код
def style_transfer(model, X, lbl_in, lbl_out):
    rows = X.shape[0]
    if isinstance(lbl_in, int):
        lbl = lbl_in
        lbl_in = np.zeros((rows, 10))
        lbl_in[:, lbl] = 1
    if isinstance(lbl_out, int):
        lbl = lbl_out
        lbl_out = np.zeros((rows, 10))
        lbl_out[:, lbl] = 1
    return model.predict([X, lbl_in, lbl_out])


n = 10
lbl = 7
generated = []
prot = x_train[y_train == lbl][:n]

for i in range(num_classes):
    generated.append(style_transfer(models["style_t"], prot, lbl, i))

generated[lbl] = prot
plot_digits(*generated, invert_colors=True)




Стиль перенесен довольно удачно: сохранены наклон и толщина штриха.

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

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

Код создания гифок


Код
from matplotlib.animation import FuncAnimation
from matplotlib import cm
import matplotlib

def make_2d_figs_gif(figs, epochs, c, fname, fig): 
    norm = matplotlib.colors.Normalize(vmin=0, vmax=1, clip=False)
    im = plt.imshow(np.zeros((28,28)), cmap='Greys', norm=norm)
    plt.grid(None)
    plt.title("Label: {}\nEpoch: {}".format(c, epochs[0]))

    def update(i):
        im.set_array(figs[i])
        im.axes.set_title("Label: {}\nEpoch: {}".format(c, epochs[i]))
        im.axes.get_xaxis().set_visible(False)
        im.axes.get_yaxis().set_visible(False)
        return im
    
    anim = FuncAnimation(fig, update, frames=range(len(figs)), interval=100)
    anim.save(fname, dpi=80, writer='imagemagick')

def make_2d_scatter_gif(zs, epochs, c, fname, fig):
    im = plt.scatter(zs[0][:, 0], zs[0][:, 1])
    plt.title("Label: {}\nEpoch: {}".format(c, epochs[0]))

    def update(i):
        fig.clear()
        im = plt.scatter(zs[i][:, 0], zs[i][:, 1])
        im.axes.set_title("Label: {}\nEpoch: {}".format(c, epochs[i]))
        im.axes.set_xlim(-5, 5)
        im.axes.set_ylim(-5, 5)
        return im

    anim = FuncAnimation(fig, update, frames=range(len(zs)), interval=100)
    anim.save(fname, dpi=80, writer='imagemagick')

for lbl in range(num_classes):
    make_2d_figs_gif(figs[lbl], epochs, lbl, "./figs4/manifold_{}.gif".format(lbl), plt.figure(figsize=(7,7)))
    make_2d_scatter_gif(latent_distrs[lbl], epochs, lbl, "./figs4/z_distr_{}.gif".format(lbl), plt.figure(figsize=(7,7)))


Полезные ссылки и литература


Теоретическая часть основана на статье:
[1] Tutorial on Variational Autoencoders, Carl Doersch, https://arxiv.org/abs/1606.05908
и фактически является ее кратким изложением.

Многие картинки взяты из блога Isaac Dykeman:
[2] Isaac Dykeman, http://ijdykeman.github.io/ml/2016/12/21/cvae.html

Подробнее прочитать про расстояние Кульбака-Лейблера на русском можно в
[3] http://www.machinelearning.ru/wiki/images/d/d0/BMMO11_6.pdf

Код частично основан на статье Francois Chollet:
[4] https://blog.keras.io/building-autoencoders-in-keras.html

Другие интересные ссылки:
http://blog.fastforwardlabs.com/2016/08/12/introducing-variational-autoencoders-in-prose-and.html
http://kvfrans.com/variational-autoencoders-explained/
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331664/


Метки:  

[Перевод] Создание шейдерного эффекта 3D-принтера

Понедельник, 26 Июня 2017 г. 13:15 + в цитатник
В этом туториале мы воссоздадим эффект 3D-принтера, используемый в таких играх, как Astroneer и Planetary Annihilation. Это интересный эффект, показывающий процесс создания объекта. Несмотря на внешнюю простоту, в нём есть множество далеко не тривиальных сложностей.



Введение: первая попытка


Для воссоздания этого эффекта давайте начнём с чего-нибудь попроще. Например, с шейдера, по-разному раскрашивающего объект в зависимости от его положения. Для этого необходимо получить доступ к положению отрисовываемых пикселей в мире. Это можно выполнить, добавив поле worldPos к структуре Input поверхностного шейдера Unity 5.

struct Input {
	float2 uv_MainTex;
	float3 worldPos;
};

Затем можно использовать в функции поверхности координату Y положения в мире для изменения цвета объекта. Этого можно добиться изменением свойства Albedo в структуре SurfaceOutputStandard.

float _ConstructY;
fixed4 _ConstructColor;
 
void surf (Input IN, inout SurfaceOutputStandard o) {
	
	if (IN.worldPos.y < _ConstructY)
	{
		fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
		o.Albedo = c.rgb;
		o.Alpha  = c.a;
	}
	else
	{
		o.Albedo = _ConstructColor.rgb;
		o.Alpha  = _ConstructColor.a;
	}
 
	o.Metallic = _Metallic;
	o.Smoothness = _Glossiness;
}

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

image

Неосвещённый поверхностный шейдер


В предыдущем туториале PBR and Lighting Models мы изучали способ создания собственных моделей освещения для поверхностных шейдеров. Неосвещённый шейдер всегда создаёт один и тот же цвет, вне зависимости от внешнего освещения и угла обзора. Можно реализовать его следующим образом:

#pragma surface surf Unlit fullforwardshadows
inline half4 LightingUnlit (SurfaceOutput s, half3 lightDir, half atten)
{
	return _ConstructColor;
}

Его единственная задача — возвращать единственный сплошной цвет. Как мы видим, он обращается к SurfaceOutput, который использовался в Unity 4. Если мы хотим создать собственную модель освещения, работающую с PBR и глобальным освещением, то нужно реализовать функцию, получающую в качестве входных данных SurfaceOutputStandard. В Unity 5 для этого используется следующая функция:

inline half4 LightingUnlit (SurfaceOutputStandard s, half3 lightDir, UnityGI gi)
{
	return _ConstructColor;
}

Параметр gi здесь относится к глобальному освещению (global illumination), но в нашем неосвещённом шейдере он не выполняет никаких задач. Такой подход работает, но у него есть большая проблема. Unity не позволяет поверхностному шейдеру выборочно изменять функцию освещения. Мы не можем применить стандартное освещение по Ламберту к нижней части объекта и одновременно сделать верхнюю часть неосвещённой. Можно назначить единственную функцию освещения для всего объекта. Мы должны сами менять способ рендеринга объекта в зависимости от его положения.

image

Передаём параметры функции освещения


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

int building;
void surf (Input IN, inout SurfaceOutputStandard o) {
	
	if (IN.worldPos.y < _ConstructY)
	{
		fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
		o.Albedo = c.rgb;
		o.Alpha  = c.a;

		building = 0;
	}
	else
	{
		o.Albedo = _ConstructColor.rgb;
		o.Alpha  = _ConstructColor.a;

		building = 1;
	}

	o.Metallic = _Metallic;
	o.Smoothness = _Glossiness;
}

Расширяем стандартную функцию освещения


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

В традиционном стандартном поверхностном шейдере директива #pragma, определяющая использование функции освещения PBR, имеет следующий вид:

#pragma surface surf Standard fullforwardshadows

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

Мы хотим создать собственную функцию освещения под названием LightingCustom. В обычных условиях она просто вызывает стандартную функцию PBR из Unity под названием LightingStandard. Однако при необходимости она использует определённую ранее LightingUnlit.

inline half4 LightingCustom(SurfaceOutputStandard s, half3 lightDir, UnityGI gi)
{
	if (!building)
		return LightingStandard(s, lightDir, gi); // Unity5 PBR
	return _ConstructColor; // Unlit
}

Чтобы скомпилировать этот код, Unity 5 нужно определить ещё одну функцию:

inline void LightingCustom_GI(SurfaceOutputStandard s, UnityGIInput data, inout UnityGI gi)
{
	LightingStandard_GI(s, data, gi);		
}

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

Результат выйдет точно таким, какой нам нужен:

image

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

Отрезаем геометрию


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

void surf (Input IN, inout SurfaceOutputStandard o)
{
	if (IN.worldPos.y > _ConstructY + _ConstructGap)
		discard;
 
	...
}

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

Cull Off

image

Теперь нас больше всего не устраивает то, что объект выглядит полым. Это не просто ощущение: в сущности, все 3D-модели являются полыми. Однако нам нужно создать иллюзию, что объект на самом деле сплошной. Этого с лёгкостью можно добиться, раскрашивая объект изнутри тем же неосвещённым шейдером. Объект по-прежнему полый, но воспринимается заполненным.

Чтобы достичь этого, мы просто раскрашиваем треугольники, направленные к камере обратной стороной. Если вы незнакомы с векторной алгеброй, то это может показаться достаточно сложным. На самом деле, этого можно довольно просто добиться с помощью скалярного произведения. Скалярное произведение двух векторов показывает, насколько они «сонаправлены». А это непосредственно связано с углом между ними. Когда скалярное произведение двух векторов отрицательно, то угол между ними больше 90 градусов. Мы можем проверить наше исходное условие, взяв скалярное произведение между направлением взгляда камеры (viewDir в поверхностном шейдере) и нормалью треугольника. Если оно отрицательное, то треугольник повёрнут от камеры. То есть мы видим его «изнанку» и можем отрендерить её сплошным цветом.

struct Input {
	float2 uv_MainTex;
	float3 worldPos;
	float3 viewDir;
};
 
void surf (Input IN, inout SurfaceOutputStandard o)
{
	viewDir = IN.viewDir;
	...
}
 
inline half4 LightingCustom(SurfaceOutputStandard s, half3 lightDir, UnityGI gi)
{
	if (building)
		return _ConstructColor;
 
	if (dot(s.Normal, viewDir) < 0)
		return _ConstructColor;
 
	return LightingStandard(s, lightDir, gi);
}

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

image

Эффект «волнистости»


image

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

void surf (Input IN, inout SurfaceOutputStandard o)
{
	float s = +sin((IN.worldPos.x * IN.worldPos.z) * 60 + _Time[3] + o.Normal) / 120;
 
	if (IN.worldPos.y > _ConstructY + s + _ConstructGap)
		discard;
	
	...
}

Эти параметры можно подправить вручную для получения красивого эффекта волнистости.

image

Анимация


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

public class BuildingTimer : MonoBehaviour
{
    public Material material;
 
    public float minY = 0;
    public float maxY = 2;
    public float duration = 5;
 
    // Update is called once per frame
    void Update () {
        float y = Mathf.Lerp(minY, maxY, Time.time / duration);
        material.SetFloat("_ConstructY", y);
    }
}

image

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

[Можно скачать пакет Unity (код, шейдер и 3D-модели), поддержав автора оригинала статьи десятью долларами на Patreon.]
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331576/


Метки:  

Защищенное рабочее место на базе VDI Huawei FusionCloud Desktop Solution 6.1

Понедельник, 26 Июня 2017 г. 13:12 + в цитатник
Мы продолжаем публиковать материалы с форума «Совместная безопасность облачных решений для бизнеса», который мы провели совместно с «Лабораторией Касперского» и HUAWEI 31 мая в Москве. Представляем доклад Ивана Юдичева из компании Huawei, «Защищенное рабочее место на базе VDI Huawei FusionCloud Desktop Solution 6.1».


Меня зовут Иван Юдичев, я занимаюсь в компании Huawei облачными проектами и поддержкой госсектора. Облачными проектами я занимаюсь уже давно. Я начал этим заниматься еще когда работал в «Заказчике», где-то 2010 году. Тогда еще была Vmware ESX 2.5, потом был Microsoft, потом была Vmware, вот, наконец, Huawei, где мы продолжаем развивать добрые традиции виртуализации серверов и VDI. Но сегодня я буду больше рассказывать про VDI.







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

На сегодняшний день даже IDC, которых трудно уличить в каких-то неадекватных оценках, они поместили нас, как можете увидеть, в major players. Это нам стоило действительно больших усилий, и еще три года назад об этом никто не мог и подумать. На сегодняшний день мы уже по многим независимым тестам, конкретно по VDI, по производительности близки к Цитриксу. Функционально, конечно, мы по уму не так развиты за счет меньшего возраста софта, но все основные функции, мы уже реализовали. Я сейчас на них более детально остановлюсь.


Архитектура решения. Сам по себе VDI развертывается в какую-то облачную среду, теоретически он может работать, предоставляя удаленный доступ с помощью традиционных компьютеров, но когда мы говорим про виртуализацию рабочего окружения, обычно речь идет про облако. И если мы говорим в данном разрезе про VDI, то решение, архитектура решения следующее. Внизу у нас есть оборудование — железо, серверы системы хранения, sdn, то есть облако. Дальше в облачную платформу мы разворачиваем соответственно весь набор софта, который позволяет разворачивать: первое — виртуальные машины для пользователей, и второе — служить брокером для того, чтобы эти машины раздавать, автоматизировать процесс. Основы VDI, я думаю, вам знакомы. И полный комплекс решения от Huawei он выглядит как платформа FusionCompute, Fusion сфера от Huawei и FusionAccess как софт, который позволяет создавать виртуальные рабочие столы.

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

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

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

Гостевые операционные системы, какие мы поддерживаем внутри. Естественно windows 7, 8, 10, то есть полная поддержка на сегодняшний день существует. Также для того чтобы избежать оплаты лицензии microsoft и vda, и свести затраты на десктоп в капекс, можно разворачивать виртуальные рабочие столы на базе windows server. Это одна из возможностей, которые мы предоставляем. Здесь есть обязательно этап сертификации, тестирования приложений, будут они работать под windows server или нет, потому что могут быть нюансы. Но 90 процентов случаев — это все отлично работает, что в клиентской операционной системе, что в серверной. И многие заказчики пользуются таким способом, разворачивают серверные операционные системы, как клиентские.

Обычно это что-то самописное, то есть что-то на базе java, может быть, какое-то приложение, там плагин для, может быть, 1С. То есть какие-то такие стандартные вещи, типа офиса, они всегда работают в серверной среде. На моей практике не возникало каких-то ситуаций, чтобы широко известный софт он не работал в windows server. Проблемы возникали с каким-то кастомизированным софтом, у гос. заказчиков, у них что-то там устаревшее унаследованное было, оно вываливалось в ошибку. Но такие вещи они бывают при миграции с xp на 7, с 7 на 8, то есть это стандартная история.


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


Далее, ПО, которое предоставляет VDI для клиентов, называется у нас FusionAccess. На сегодняшний день актуальной версией является версия 6.1, но еще в версии 6.0 возникло, появилось очень много интересных возможностей, которые я сейчас кратко пробегу. Я сознательно исключаю какие-то такие базовые вещи, типа поддержки windows 10, потому что очевидно, что она поддерживается полностью. И я выделил несколько наиболее, на мой взгляд, важных вещей.


То есть что мы поддерживаем с версией 6.0? Мы поддерживаем linux, как гостевую операционную систему. Это очень такой достаточно частый вопрос был, когда вы начнете это поддерживать, вот с начала этого года мы поддерживаем. Ubuntu и red hat, как гостевые операционные системы. То есть теперь нет никакой необходимости использовать только windows, тратить, платить деньги за лицензию, можно использовать бесплатный linux, и разворачивать VDI, и получать еще больше выгоды за счет этого. То есть функционально, практически тоже самое. Ну, естественно максимальный набор функций вы получите в windows, но такие базовые вещи, как работа с флешками, работа с принтерами, с аудио, все основные виды десктопов, они доступны, в том числе и в linux. Опять же, 80 процентов случаев — можно выбирать и то, и другое, и при этом не чувствовать себя, каким-то образом, обделенным.


Далее, появилась полная поддержка работы с разрешением 4K. Это может быть в принципе и несколько мониторной конфигурацией, либо это один монитор с разрешением ultra hd. Чаще всего используется в графическом дизайне, либо в разработке для cad-приложений. Забегая немножко вперед скажу, что в версии 6.1 мы также добавили поддержку графических видео редакторов, которые работают в режиме 4K. Там были немного специфичные требования, потребовалось полгода для того, чтобы полностью оттестировать решение. Вот на сегодняшний день это тоже работает.


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


Мы сильно упростили в версии 6 развертывание ядра системы, вряд ли вы, наверное, знакомы с FusionAccess версии 5, вот, но по своему опыту помню, что для этого требовалось заворачивать какое-то гигантское количество виртуальных машин, часть из них разворачивалось на linux, часть – в windows. Вот, с версии 6.0 мы драматически упростили этот процесс, есть один инсталляционный пакет, одна версия linux, и все виртуальные машины запускаются именно с этого диска, и процесс развертывания сократился где-то раз в пять по времени.


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


Появилась функция lazy desk. То есть, как это выглядит. Есть тонкий клиент, к нему по его id однозначно привязывается конкретная виртуальная машина. Дальше при вводе учетных данных в тонкий клиент автоматически происходит подключение к виртуальной машине, и для пользователя нет такой разницы, заходит он на локальный pc или работает с VDI. Это может быть очень удобно для каких-то публичных терминалов, склады, медицина, либо какие-то удаленные точки, где бывает очень много проблем с пользователями, им трудно понять, что нужно один раз залогиниться, потом еще раз залогиниться. Для того, чтобы этого избежать, можно применить функцию lazy desk, жестко привязать клиента с виртуальной машиной, и в дальнейшем это сильно упростит работу пользователя. Один раз вбили, один раз зашли, все, полное ощущение, что работаете за локальным компьютером.


Далее, с точки зрения администратора системы. Это больше, наверное, упрощение для наших партнеров, но тем не менее. Процесс подготовки шаблона для виртуальной машины сократился по времени раза в три — в четыре. Раньше был огромный гайд на 30 пунктов, который нужно было руками проверить, убедиться, что операционная система настроена корректно, теперь всего этого нет. У нас есть wizard с тремя большими кнопками, сделать мне такой десктоп, такой и такой, в зависимости от того, какая задача у вас стоит. То есть нажимаете один раз кнопочку, происходит заскриптованный процесс, все, виртуалка готова, можно заворачивать.


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

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


И теперь несколько слов про то, что появилось буквально недавно, меньше месяца назад вышла 6.1. Если раньше десктопы на серверных операционных системах были на 8 и на 12 версиях, то теперь, можно использовать windows server 2016. Шестнадцатая версия – это полностью 64-битная операционная система, там вырезан блок, отвечающий за эмуляцию 32-битного окружения, поэтому здесь могут быть вопросы с совместимостью, как уже отметили. То есть нужно тестировать. Именно поэтому везде ставим плашку, что это limited commercial use, то есть это ограничено для использования, не для широкого использования, а только после предварительных тестов, но технически никаких проблем нет, выглядит также как windows 10. Преимущества, как у любой операционной системы, в лицензировании.


Далее, с версией 6.1 появился универсальный драйвер веб-камеры. С его выходом теперь не только, ну раньше единственный способ взаимодействия с веб-камерой был это использование фильтров windows directshow. Теперь появилась опция обращаться напрямую к камере, и эта вещь очень востребована при работе каких-то корпоративных voice over ip приложений, cisco jabber, например, или skype, то есть теперь можно работать с камерой напрямую и использовать ее возможности, не говоря уже о том, что это несколько снижает потерю производительности.


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

Обработка видео. Разрешение 4K, как я уже говорил, теперь полностью сертифицировано, проверено, работает.


Появилась функция перенаправления звука и видео при работе с тонкими клиентами. Раньше как было, в виртуальную машину, виртуальный десктоп ставился клиент voice over ip приложение, там обрабатывается звук и видео. Как правило, звук отправляется в ЦОД, там обрабатывается, возвращается назад. Это все перегружает каналы. Для того, чтобы этого избежать, есть функция перенаправления звука и видео, на тонкий клиент ставится приложение либо плагин, и в дальнейшем звук и видео уходят напрямую из тонкого клиента, минуя вот эту вот петлю в ЦОД и обратно. За счет этого можно спокойно работать с какими-то локальными провайдерами, то есть не обращаться в ЦОД каждый раз, когда нужно кому-то позвонить и вот в конечном итоге позволяет на один и тот же канал сесть большему количеству пользователей. Сейчас у нас были проведены тесты с cisco jabber, теоретически может работать любой софт, надо просто протестировать, проверить.
 

Есть отдельно плагин для skype for business. В тонкий клиент, в случае skype, ставится плагин. В случае cisco jabber, ставится целиком софт прямо в тонкий клиент.


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


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


Появилась функция управления профилями пользователей. В принципе управлять профилями можно было раньше с использованием windows roaming profile, но у такого решения есть определенные недостатки, потому что сам win roaming profile настроить надо. Он иногда не очень стабильно отрабатывает, когда теряется связь, а с центральным сервером, где хранятся профили, то есть там может быть кратковременное отключение, после того, как сервер возвращается в рабочий режим, бывает, что профиль он не отрисовывается, приходится разлогиниваться и обратно, то есть неудобно. Вот для того чтобы этого избежать, либо в том случае если не хочется настраивать roaming profiles в windows active directory, либо если вы просто не хотите использовать windows directory, а для тестовых пользователей, просто было достаточно каких-то локальных машин, вот можно использовать встроенный persona management. Он интегрирован как с active directory, если она есть, так и с нашей локальной Micro AD и позволяет управлять профилями, то есть средствами FusionAccess, а не какой-то внешней системы.


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


Лицензирование. Если продукт этот приобретать в собственный ЦОД, то он лицензируется двумя типами. Есть лицензия именованная, есть лицензия по подключениям. Соответственно, и три вида лицензий. Standart — это обычный десктоп, то есть просто виртуальная машина, в которой пользователь работает. SBC, server based computing у нас называется, по сути, это терминалы. То есть SBC Standart – это лицензия на использование терминального режима работы VDI. Аdvanced соответственно позволяет использовать как стандартный режим, так и терминальный. Лицензии именованные несколько дешевле, чем лицензии на конкурентное подключение. Цены RPL, то есть russian price list, в реальности они могут отличаться в ту или иную сторону, лучше всего спрашивать у партнера или у аккаунт-менеджера, с которым вы привыкли работать.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331656/


Метки:  

Скорочтение: работает или нет? Часть 2: разбор методик

Понедельник, 26 Июня 2017 г. 13:10 + в цитатник

Метки:  

Make QR Codes Great Again или камерная революция от Apple

Понедельник, 26 Июня 2017 г. 12:48 + в цитатник

На недавнем WWDC Keynote Крэйг Фидеричи мельком анонсировал нативную поддержку QR-кодов в iOS11. Новость эта прошла почти незаметно. А зря.


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


История развития QR-кодов в 4 действиях


Младенчество


QR-код появился на свет в Японии в 1994 году в семье-подразделении TOYOTA, занимавшейся разработкой сканеров для штрих-кодов (DENSO WAVE). Отцом был записан Хара Масахиро.


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


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



В честь этого преимущества детку и нарекли – QR (Quick Response).


Детство


Существенно подрасти, набрать вес и стать самым распространённым в мире двумерным кодом среди десятков конкурентов QR-коду помогли два фактора:


  1. DENSO WAVE сделала спецификации QR-кода публично доступными: любой мог ими свободно пользоваться.
  2. В Корпорации публично заявили, что даже несмотря на оформленный патент, предъявлять его кому-либо или претендовать на лицензионные они не собираются.


Свои первые уверенные шаги технология сделала в направлении японских автопроизводителей, которые внедрили QR-коды в текущие Kanban-процессы. Затем подтянулись другие индустрии, увидевшие пользу применения квадратиков в своих циклах.


Но по-настоящему в люди из душных производственных стен QR-код вывели первые японские камерофоны в начале 2002 года. QR-архитектура позволяла беспроблемное считывание на самых допотопных аппаратах.


Половое созревание


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



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


  • близость к Японии;
  • низкий процент грамотности населения: когда не умеешь читать, остается только сканить QR-код и внимать на простом китайском языке, чего от тебя хотят;
  • те, кто грамотный – задалбливались возиться с иероглифами: остаётся только сканить QR-код и получать на простом китайском языке, чего тебе хочется;
  • поддержка ключевыми игроками: по словам гендира WeChat, большинство пользователей 768-миллионной аудитории супер-мессенджера регулярно сканирует QR-коды.


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


Молодость


А вот здесь начинается самое интересное. С сентября 2017 благодаря волевому решению Apple у QR-кода начнется новый жизненный этап. После релиза iOS11 сотни миллионов устройств по всему миру окажутся на расстоянии всего одного свайпа до:


  • перехода на web-cайт по QR-коду;
  • звонка по QR-коду;
  • отправки SMS (на заданный номер с заданным текстом) по QR-коду;
  • добавления контакта по QR-коду;
  • добавления события в календарь по QR-коду;
  • отправки Email (на заданный адрес с заданными текстом и темой) по QR-коду;
  • показа места на карте по QR-коду;
  • подключения к заданной Wi-Fi сети (без необходимости вводить пароль) по QR-коду (!!!);
  • перехода в определенное место в App’е (deeplinking) по QR-коду (!!!).

Посмотреть на все это своими глазами можно уже сейчас. Достаточно скачать beta-версию iOS11 и воспользоваться каким-нибудь мощным генератором QR-кодов.



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


Возможно, именно этот шаг яблочной корпорации, за которой со временем последуют Google и его hardware-партнеры, даст старт эре “Camera is the New Keyboard”. Мы же ожидаем, что уже к концу этого года QR-код можно будет назвать двумерным кодом в самом расцвете сил.


Готовьтесь к штурму


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



Мы предлагаем орудовать вместе :)


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


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


В любом случае будьте готовы к сомнительному поощрению из Китая – страны-фаната технологии. Трое комментаторов, которые внесут самый крупный вклад в дискуссию, получат “Низкая стоимость ручной qr-код принтер bluetooth прочный может напечатать испанский, Португальский, арабский и т. д. (QS5806)” с сайта Alibaba.com. Подробнее об устройстве можно узнать, конечно же, считав QR-код.



И да зародится в комментах Хабра первый FunTech-стартап. Аминь.

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

https://habrahabr.ru/post/331452/


Метки:  

Развлечения для интеллектуалов: играем во «Что? Где? Когда?» — как?

Понедельник, 26 Июня 2017 г. 12:33 + в цитатник
Мы тут как-то рассказывали, как ребята из Veeam Software решили выяснить, «кто на свете всех умнее», собрали команду по «Что? Где? Когда?» и пошли соревноваться с другими айтишниками (и не только), и даже победили, и даже не один раз. С тех пор много чего поменялось на этом самом свете: в Рио прошли Олимпийские Игры, в Питере, кажется, достроили стадион, а Veeam стал бэкапить не только виртуалки, но и физические машины.
Но сегодня не об этом, а о том, как можно самим провести турнир по «Что? Где? Когда?» у себя в компании, какая польза от этого сборной команде, и как удивительно в результате может повернуться карьера участника.




Сам себе event-менеджер


Вообще-то народ в наших офисах много во что играет: есть специально отведенные комнаты для кикера и настольного тенниса, кто-то предпочитает шахматы и шашки, есть и любители настолок. Но мы решили замахнуться на более массовую игру. Ведь сборной по ЧГК были нужны свежие силы в связи с отъездом некоторых игроков в Чехию, к тому же все больше новичков, рассказывая на собеседованиях о своих увлечениях, называли в том числе и интеллектуальный спорт. В общем, мы подумали и сели организовывать Кубок Veeam по интеллектуальным играм.
Сразу оговорюсь, что профессиональных event-менеджеров среди нас не было, поэтому к этой задаче мы подошли, можно сказать, по-инженерному: смотрим, как это работает – вычленяем составляющие – собираем у себя из идентичных деталей, при необходимости «обрабатываем напильником», то есть адаптируем под себя.
Итак, где-то смотрим, как происходит оффлайн-игра для аудитории из нескольких команд. Фиксируем, какие ресурсы задействованы и какие процессы происходят. Прикидываем, какие подготовительные действия понадобятся, и кто в нашей компании за что отвечает (закупки, оформление документов, массовые рассылки и прочее). Сводим все воедино и получаем «раскладку» по мероприятию. Ниже коротко о ключевых моментах.

Пункт 1. Помещение: Если у вас набирается не очень много народа, то есть человек 30 (это 5 команд), то можно поиграть и в офисе — в учебной аудитории, в большой переговорке, в столовой и т.п. У нас же в этом году с обеих питерских площадок набралось 13 команд, а это больше 70 человек, представители почти всех отделов. Поэтому мы озадачились арендой просторного помещения и организацией кофе-брейка. Довольно быстро нашли подходящий конференц-зал в гостинице неподалеку от обоих офисов. По идее, можно договориться об аренде в ДК, в Доме детского творчества, да просто в кафе (в первый раз мы так и делали – арендовали помещение кафетерия в нашем БЦ).

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

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



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

Даша Аксенова, координатор проекта в одном из офисов, секретарь: Я в детстве смотрела игру «Что? Где? Когда?» по телевизору, и у меня была мечта отправить туда вопрос. Позже, во время учебы в школе у меня уже был опыт игры: мы выступали со школьной командой «Коржи» на городских и областных турнирах по «Брейн-рингу» и даже занимали призовые места.
Когда я узнала, что в нашей компании проводится такая корпоративная игра, то очень обрадовалась и заинтересовалась, а когда выяснилось, что ведущим будет Михаил Скипский, для меня это было просто невероятно! Я же его игры смотрела по телевизору, мне очень нравилась и нравится их команда, я всегда за них болею. А тут я поняла, что увижу его прямо лицом к лицу, и он будет ведущим – конечно, я была в восторге!

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

Пункт 3. Процедурные моменты
ОЧЕНЬ ВАЖНО! Обязательно разработайте и выложите в общий доступ Регламент турнира! Можно почитать, как его пишут другие, и что-то взять за основу. Непременно решите, кто будет следить за его выполнением. Возможно, вам понадобится жюри из нескольких человек (желательно опытных игроков).
  • Подготовьте бумажные бланки для ответов — по числу команд, и еще несколько про запас.
  • Если планируете использовать микрофон и\или включать музыку – назначьте ответственного за звуковое сопровождение.
  • Если среди коллег есть умеющие вести репортажную съемку – отлично! Когда еще можно запечатлеть для истории командную работу мозга.
  • Придумайте, чем награждать победителей. Да, лучше много маленьких призов, чем один большой. Можно давать призы за самый смешной ответ, за лучшую командную форму, и т.д. и т.п.

Когда всё «утряслось» с помещением, регламентом и ведением, можно оповестить всех желающих, после чего начинаем регистрацию на турнир. Мы поступаем просто: в каждом из офисов назначаем ответственных за сбор заявок по e-mail и ввод их в общую таблицу на GoogleDocs. Каждая команда придумывает название и выбирает капитана. Всеобщее веселье и буйство фантазии начинается уже в этот момент – так, в наш список попали «Conversion 146%», «АнсабскрАйбнем», «Без Петровича», «Красный баг», «All Insider Друзь» и сборная всех офисов, названная в честь всех трёх бизнес-центров «Кондратий Плазович Леже». Забегая вперед, скажу, что именно сборная и стала обладателем Кубка-2017, и это, наверное, символично, ведь ЧГК – игра командная.
Ура, наконец-то закончена беготня с бумажками, согласование бюджета, закупка призов и печать бланков, можно выдвигаться на игру!

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

Итак, все расселись, отгремели знакомые звуки увертюры Рихарда Штрауса, и началась разминочная «Матрица» (аналог «Своей игры»). В результате разминки мы с коллегами узнали, что такое термин «свежий ветер», какое прозвище носит футбольная команда «Глазго Рейнджерс», и много других занимательных фактов.
Основной же турнир включал в себя 2 тура по 12 вопросов разной степени сложности. Вот мнения участников.

В этот раз вопросы были труднее, чем на Первом Кубке год назад?

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

Ольга Слюсаренко, технический писатель: Да, возможно, дело и в этом. В прошлый раз было больше команд, и на мой взгляд, не все были оптимально готовы к тому, что нужно будет реально сконцентрироваться, быстро думать, искать решение, и не только для простых вопросов. Может, кто-то из-за результата расстроился. Хотя ребята, которые год назад заняли 3 место, сразу же заявили, что в следующий раз возьмут реванш! То есть это их, наоборот, мотивировало. В этот раз победители взяли 21 вопрос из 24, это очень хороший результат.

Денис Руденко, капитан сборной Veeam, руководитель департамента QA: По-моему, в этот раз многие вопросы были слишком лёгкие. Может, даже, в следующий раз лучше вообще «сборников» не звать за стол. Дать другим игрокам, командам подумать, побороться. А «сборников» отправить, например, в жюри.

Сложно ли было организовать турнир у себя в компании?

Ольга: У меня уже был опыт организации Кубка в прошлом году, тогда да, все было впервые, много неочевидных для меня вещей, но мы справились… А потом люди постоянно спрашивали – когда же будет следующая игра? Получилось ровно через год. В этот раз уже все было куда проще. Хотя… пришлось заводить все договоры в систему 1С – вот работа с 1С стала для меня самой большой трудностью :).

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



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

Чем тебе запомнился Кубок Veeam-2017?

Даша: Наверное, атмосферой – это не было какое-то нервное напряжение у каждой команды, а была такая дружеская атмосфера. Еще запомнились, наверное, смешные версии ответов – например, был такой вопрос:«Пустынная улитка период с мая по октябрь проводит в НЕЙ. Назовите ЕЁ». Одна из команд ответила, что «улитка в коме». (У меня был вариант, что она в осенней депрессии (когда спит)), но мы не выбрали эту версию.)
Смех был по-настоящему искренний, добрый, от радости участия. Я думаю, что все прошло очень здорово, и зал мне очень понравился, красивое оформление, и организация, и кофе-брейк. Конечно, ведущий Михаил Скипский, и подарки, призы.



Кто «на новенького» в сборной?



В сборных же Veeam, выступающих в клубе «60 секунд», за эти 2 года появились новые игроки, добавившие красок игре команды.

Как вы попали в сборную Veeam?

Кирилл Стецко, специалист службы техподдержки, регион Испания: У нас при приеме на работу просят заполнить анкету, там есть вопрос про увлечения, я написал, что играю в ЧГК. Потом ко мне Дима подошел, пригласил на игру.

Костя Ляпцев, инженер отдела тестирования: Вообще-то я очень давно играю в «Мафию», можно сказать, стоял у истоков питерского сообщества. А в ЧГК тоже стало интересно себя попробовать, и я отправил заявку сначала на участие во внутреннем турнире-2016. Мы проводили тренировки, хорошо выступили — заняли 1 место. Наверное, мне удалось неплохо себя проявить, и меня пригласили сыграть за сборную. Сначала я играл за Veeam-2 в Корпоративной Лиге клуба «60 секунд», теперь уже вызываюсь и на игры в Лиге Чемпионов.

Женя Иванов: Изначально я работал в команде renewals (продление лицензий), но мечтал о работе в отделе технической поддержки. Тогда команды по ЧГК только создавались, игроков было немного. Я играл за Veeam-2 в Корпоративной Лиге, и мы с коллегой приезжали на совместные тренировки к ребятам в «Кондратьевский» (на этой площадке находятся R&D, QA и TechSupport). Там познакомился с парнями из саппорта, потом с их тим-лидом общался. Конечно, параллельно я серьезно готовился, ведь хотя навык общения с клиентами у меня уже был, нужно же было еще хорошее понимание технических вопросов. И вот менеджеры дали добро, и я наконец перешёл в саппорт на должность джуниор инженера! То есть, можно сказать, игра в ЧГК помогла мне осуществить свою мечту. Сейчас я играю уже за первую сборную, да и на работе дорос до сеньора, так что это получилась прямо-таки Success Story :).



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

Дима Мордберг, тим-лид команды техподдержки, регион Франция: У меня зашедуленная активность в календаре. Никто не может поставить мне совещание на это время:).

Денис: У меня сейчас так – работа «съест» всё время, которое я на нее выделю. То есть вопрос в том, чтобы выделить столько, сколько нужно, на необходимое, самое главное, самое важное. И у меня дети еще маленькие, так что свободного времени в целом немного, и ты в какие-то его остатки пытаешься втиснуть что-то — вот ЧГК еще пока втискивается.

Женя: Скажу так: до перехода в саппорт я думал, что я много работаю. Теперь я понимаю, что все эти предыдущие годы я, можно сказать, отдыхал! Потому что жизнь джуниор саппорт инженера реально была тяжела. Вот Дима, например, отлично помнит, как он заходил за мной, а я на каком-нибудь вебексе досиживал последние минуты, просил: «Дима, пожалуйста, еще 5 минут!» И тут он мне помогал с рабочими вещами, чтобы я мог освободиться вовремя и пойти на игру. А сейчас у меня уже и опыт появился, и тайм-менеджмент лучше стал, ну и обязанности теперь более разнообразные – это и обучение новичков, и написание всяких статей, так что непосредственно работа с клиентами занимает, наверное, примерно треть времени. Так что в целом стало, наоборот, легче.

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

Денис: Наверное, надо пытаться на другой уровень постепенно выбираться. У меня идея — надо найти там команды из спортивного ЧГК (их там пока немного, 2-3), либо свою попробовать организовать и играть самим. Так что надо продолжать читать, тренироваться. И кто-то ведь планирует возвращаться в Питер, а там уже будет новая страница, новые команды, новое будущее…

А что скажет уже «бывалый пражанин»? Что общего и чем различаются питерский и пражский ЧГК?

Ян Димант, инженер отдела тестирования: Здесь, в Чехии, есть 2 или 3 команды, играющие в спортивное ЧГК, а в Праге проходят игры «Открытой Лиги» клуба «60 секунд». В ее весенней серии приняли участие 26 команд. Отличие от питерских игр в том, что в команде может быть до 8 игроков. И, конечно, здесь отличное чешское пиво, которое прекрасно идет в перерывах между турами и после игры :).
Игра традиционно начинается с «Матрицы», затем 3 тура ЧГК, по 10 вопросов. Для кого-то, может, и слишком просто, но мне в самый раз. Наша команда называется «Veeam_Software_cz», в целом играем достаточно неплохо – в весенней серии поучаствовали в 5 играх, из которых в 2 поделили первое место. Вот один из «призовых подиумов» нашего маленького, но гордого филиала:


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

«Нет места, кроме первого!»



В начале марта в рамках чемпионата IT Challenge (спартакиады «по всякой всячине» среди IT-компаний Питера) прошла игра «IT Brain Battle». Естественно, на нее заявилась и сборная Veeam. Вообще у нашей команды непростые отношения с этим турниром: в первый год его проведения опоздали с заявкой, затем остались за чертой призеров, хотя и показали неплохой результат. В этом сезоне очень хотелось реабилитироваться.
За стол в конференц-зале гостиницы «Азимут» сборная садилась в полном составе и с очень серьёзным настроем.



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



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



Но и среди «любителей» то и дело мелькают известные лица: вот команда Елены Потаниной «Маршак Начеку», а вот и сборная клуба «60 секунд» под предводительством его президента Леонида Эдлина. Вот представители Казахстана, Латвии, Израиля, Швеции — всего 46 команд, более 270 участников. Вёл турнир Магистр ТВ-клуба «Что? Где? Когда?» Максим Поташев, он же был редактором одного из туров.

В ходе двух дней чемпионата было сыграно 6 туров по 12 вопросов, причем во двух из них Veeam набрал наибольшее число очков. (Фото по качеству, конечно, плохое — зато оно хорошо передает настроение парней после выигранного тура.)



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

Наверное, войти в десятку лучших команд ЧМ – неплохой результат?

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

Денис: Мы, можно сказать, остановились в шаге от третьего общего места и от первого в корпоративном зачете, всего 3 баллов не хватило. Там чисто на моих неправильных выборах можно было больше набрать. Две команды были чуть сильнее — и всё. А мысли «не наш уровень» по дефолту — не совсем правильные. Уровень ведь и мыслями тоже определяется. Вполне реально было третье место занять. И сыграли моментами просто хорошо, а в сумме да, получилось средне.

Какие, по-твоему, есть резервы у знатоков, чтобы расти?

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

Даша: Перед турниром мы с моей командой собирались на небольшие тренировки, которые организовывали сами. Было бы интересно и полезно организовать общие тренировки для нескольких команд, с рассказом, какие роли могут быть в команде, какого плана могут быть вопросы… Можно сделать скайп-колл или собрать брошюру с полезными советами, сделать тренировки регулярными – вот это было бы очень здорово!

Вместо послесловия


Вот пост на Хабре о том, с чего все это начиналось.
Рассказ о Кубке Veeam в корпоративном паблике
И, само собой, благодарности и респекты:
  • За финансовую и организационную поддержку нашего участия во всех этих турнирах команда знатоков благодарит компанию Veeam Software и лично Александра Ширманова (@sysmetic)
  • За предоставленные фотоматериалы автор благодарит участников команды знатоков Veeam, а также лично Алексея Соболева (@bw3d), компанию IT-Dominanta, а также интеллектуальный клуб «60 секунд» (http://club60sec.ru/) и лично Максима Морозова.

До новых игр!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330914/


Метки:  

Как перестать искать хороший дата-центр и начать жить

Понедельник, 26 Июня 2017 г. 12:28 + в цитатник


Жаль вас расстраивать, коллеги, но мой ответ: никак. Или, как говорилось в одной отечественной рекламе, «сынок, это фантастика». Нет, в природе существуют Tier IV ДЦ и ЦОДы, заключающие и выполняющие SLA, но в этой статье речь пойдет не о них (так как их услуги стоят, простите за каламбур, заоблачных денег), а о провайдерах выделенных физических и виртуальных серверов и сервисов, которыми в настоящее время пользуется большинство простых смертных, в том числе и мы в Pixonic.

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

Ёж — птица гордая: пока не пнешь, не полетит



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

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

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

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

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

Пишите письма

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

При письменном общении с представителем провайдера заострите внимание на следующих моментах:

  • как правило, в каждый момент времени над проблемой работают инженеры разного уровня квалификации, при этом они ограничены внутренними регламентами их компании. Часто сменщик не обменивается информацией по проблеме со сменяемым — будьте готовы повторять по многу раз одно и то же и досконально разжевывать проблему;
  • если в общении упоминается время, всегда уточняйте и вашу временную зону, и время по UTC;
  • если корень проблемы вам очевиден, напишите пошаговую инструкцию вплоть до запятой и в общении с менеджером (о нем чуть ниже) постарайтесь настоять на том, чтобы она была выполнена беспрекословно без лишних вопросов — как правило, из-за упомянутых выше регламентов инженер обязан у вас спросить всякое странное, вроде собрать и предоставить статистику MTR за 1000+ итераций с разных хостов в одной подсети;
  • часто техподдержка провайдера увлекается расследованием инцидента, которое может длиться неделями; в таком случае не стесняйтесь просить радикальных мер: физической замены сервера или его переноса в другую стойку/PDU/коммутатор;
  • если при составлении тикета есть возможность выставить степень важности проблемы, указывайте честно, чтобы не оказаться в ситуации из известной притчи про мальчика и волков;
  • если «разбором полетов» с провайдерами у вас занимается отдельный человек, не являющийся лицом, принимающим решения, ему не стоит употреблять корпоративную подпись с указанием его должности — пусть ограничивается чем-то вроде: «Regards, Имярек» — они будут воспринимать его как ЛПР и активнее работать по проблеме;
  • вообще, в некоторых ситуациях, если для вас это приемлемо, может быть полезно выстроить некоторую модель общения по электронной почте, где среди формальных, оформленных в HTML сообщениях в треде будет появляться персонаж, пишущий рубленые фразы в plain text без подписи — цель та же;
  • во всех случаях, когда считаете нужным, употребляйте аббревиатуру ASAP и фразу «business critical» в разных вариациях — они это «любят», особенно менеджеры, которых обязательно нужно либо ставить в копию, либо, если нет такой возможности, упоминать по ФИО прямо в тикете, чтобы показать техподдержке, что их начальство уже в курсе проблемы;
  • если на третий раз эти волшебные фразы не подействовали, грозите съехать от них вот прямо завтра без разговоров и оплат — их это еще сильнее «бодрит».


А если не помогает?



На самом деле, на практике лишь часть инфраструктуры флагманского продукта Pixonic единственный раз действительно съехала от провайдера Х (чтоб их черти мучили).

Как правило, если у вас, конечно, не 5-10 серверов на весь проект, провайдер очень заинтересован, чтобы вы остались у него. И тут с них нужно просить, нет, не неустойки (к слову, из всех провайдеров, с кем мы общались на повышенных тонах по критичному для бизнеса инциденту, был только один, кто сразу спросил, как и сколько денег вернуть) — ведь, положа руку на сердце, у вас не заложен механизм расчета финансовых потерь из-за факапа облачного провайдера, временной неработоспособности DNS, временной несходимости интернета из-за проблем на магистральных каналах? Вот тут нужно требовать по максимуму! Самое простое — скидки на новые сервера/инстансы, бесплатную аренду или расширение уже существующих, повышение уровня качества техподдержки и тому подобное. Но правильнее всего требовать отдельного менеджера, который — да-да — как раз будет лично мотивировать свою команду на повышенный интерес к вашему бизнесу.

В общении с таким менеджером тоже есть свои нюансы, а именно:

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

30 часов боли. Разом




Где-то в параллельной вселенной после жалоб клиентов

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


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


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


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

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


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


Как-то возникла необходимость обновить «железо» 50+ «боевых» серверов в одном регионе. Чтобы эта активность минимально сказалась на продакшене, обновляли по 5 штук. Так вот, в каждой партии обязательно попадался один неисправный сервер! Либо проблемный БП, либо битые диски, либо сгоревшая материнка. В итоге заложенное на обновление время увеличилось вдвое.


Тоже про обновление, но операционных систем. Провайдер предоставляет веб-интерфейс и API для манипуляций с серверами, в том числе для переустановки ОС. В нашем случае оказалось, что для 80% серверов, которые нужно было обновить, эти инструменты просто не работали! Разработчики провайдера пообещали разобраться, а техподдержка в это время предложила переустановку ОС вручную. Первая переустановка Windows заняла у инженера двое суток!


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


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


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

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

Заключение



Я повторюсь, озвученным в статье советам достаточно просто следовать, чтобы минимизировать проблемы, возникающие из-за расхождения ожиданий в отношении дата-центров с реальностью, и сосредоточиться на бизнес-задачах. Но эти проблемы так или иначе будут присутствовать. Чтобы защититься от них по максимуму, закладывайте отказоустойчивость и гибкую инфраструктуру на уровне архитектуры приложений, как это делаем мы в Pixonic. И обязательно правильно настройте свой мониторинг, чтобы было к чему апеллировать в общении с представителями провайдера вместо сбора 1000+ MTRов.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331490/


Метки:  

Как Pony Express удается вам доставлять

Понедельник, 26 Июня 2017 г. 12:16 + в цитатник
Чего хочет любой клиент от логистического оператора? Конечно, чтобы всё происходило быстро, качественно и желательно, по максимуму, без его — клиента — непосредственного участия. Чтобы можно было заплатить свои кровные, а дальше оно уж как-нибудь само. Но в некоторых случаях, чтобы «оно само», клиенту тоже нужно немного пошевелиться. Как быть компании, если он не торопится? Под катом — опыт Pony Express.




Справка о компании:

Pony Express — крупнейший в СНГ универсальный логистический оператор. Компания предлагает полный комплекс услуг по экспресс-доставке, складскому хранению, грузоперевозкам, а также комплексные логистические решения для различных отраслей бизнеса. Имеет представительства в России, Казахстане, Киргизии, Украине, Беларуси, Узбекистане, Азербайджане, Молдове, Армении.


Режим мобилизации клиента


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

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

Оптимизированная забота


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

Теперь схема коммуникации Pony Express с получателями посылок выглядит так:

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

Если после двух дней ничего не произошло, и клиент не заполнил форму, то подключается оператор Pony Express. К этой мере Pony Express прибегает, в основном, если сроки совсем критические.

Как это всё заработало


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


Voximplant напрямую интегрирован с ERP-системой Pony Express. Из нее «робот» берёт данные для обзвона, а потом автоматически загружает статусы совершённых звонков.

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

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

Клиент прокачан


Как отмечают представители Pony Express, такая схема напоминания очень эффективна. В sms-ке клиент получает в удобной форме информацию, к которой может легко обратиться в любое время. Но главной мотивацией к заполнению декларации для клиента становится именно робозвонок. По данным компании, если в первый же день (после sms со ссылкой) данные вносят примерно 19-20% самых обязательных клиентов, то после автоматизированного напоминания — все 95% (почти что все остальные, напуганные роботом).

Операторам в крайнем случае остаётся лишь доделать за роботом очень небольшой процент работы в этом поле, потому что львиную долю он отобрал. За счёт того что первичный обзвон клиентов по поводу деклараций больше не входит в обязанности сотрудников колл-центра, Pony Express удалось здорово сократить расходы. Автоматизированное напоминание обходится компании, по её собственным подсчётам, в 4 раза дешевле, чем услуги оператора!

Как это понимать


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

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

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

Картинка до ката взята из интернет-журнала vchae.com
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331650/


Метки:  

«В Тарантуле нет такой проблемы как сильная деградация со временем и под нагрузкой» – Василий Сошников

Понедельник, 26 Июня 2017 г. 12:09 + в цитатник
Сегодня мы беседуем с Василием Сошниковым, архитектором и разработчиком отечественной open source СУБД Tarantool.

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

На PG Day'17 Russia, Василий проведет интенсивный практический курс по построению масштабируемой распределенной архитектуры для OLTP-задач, используя всего лишь два инструмента: Tarantool и nginx. Все участники курса прослушают краткий ликбез об архитектуре и внутреннем устройстве Тарантула, после чего погрузятся в 3-хчасовую практику, во время которой с нуля построят отказоустойчивый и масштабируемый сервис.

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




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

Василий: Я – старший разработчик / архитектор. В мои обязанности входит проектирование и разработка. Также я иногда пересекаюсь с бизнесовой, менеджерской и организационной составляющей. Трудно охарактеризовать мою работу одним словом. Сейчас я разрабатываю и продвигаю open source проект Tarantool. Также иногда помогаю другим сторонним проектам, к примеру Centrifugo (это message broker для веба).

Говоря о моей страсти – это video streaming. Я им занимался один раз в жизни, было это в компании РБК, я создал весь backend для РБК-ТВ. Наверное, это был мой самый интересный, с точки зрения архитектуры и кода, проект.

PG Day: Чем именно ты занимаешься внутри проекта Tarantool?

Василий: В основном, планированием и архитектурными решениями на базе самого Tarantool, разработкой частей ядра и внешних модулей. К примеру, из разработанных мной: Tarantool Curl – это binding libcurl’а в Tarantool; Tarantool MQTT – binding для MQTT; и модуль для nginx – это reverse proxy модуль, который преобразовывает поток HTTP-запросов в протокол Тарантула и наоборот. Что касается ядра, недавно как раз принимал участие в переносе внешнего проекта в ядро. Это был Tarantool Curl, HTTP в базе данных нужен всем.

PG Day: Сколько человек занято разработкой Тарантула? Есть такое понятие как корневая команда (core team)?

Василий: Да, конечно. На самом деле, это не только разработчики. Это еще и технические писатели, немного маркетинга и еще кое-кто. Суммарно нас 21 человек. Это те, кто сидит в Москве, в офисе Mail.ru, и разрабатывает Тарантул. Достаточно большой вклад вносят люди из нашего сообщества. Например, они добавляют новые connector’ы для разных языков, придумывают фичи и даже их реализовывают!

PG Day: Чем крут Тарантул как база данных? Что его отличает от других продуктов?

Василий: Ответ прост – OLTP. В Тарантуле нет такой проблемы как сильная деградация со временем и под нагрузкой. Любая дисковая база данных, и даже некоторые in-memory, сильно деградирует. К примеру, тот же Redis, когда он сильно загружен и при этом делает snapshot – мы получаем x2 к размеру занимаемой памяти и тормоза, а это, я отмечу, еще и под нагрузкой происходит. У Tarantool’а этих недостатков нет, плюс ко всему он транзакционный.

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

PG Day: За счет чего достигается такая предсказуемость и стабильность в работе на высоких транзакционных нагрузках?

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

PG Day: Неожиданно, но хорошо, принимается такой ответ! Насколько я понял, ты планируешь на мастер-классе теорию с практикой совместить?

Василий: У меня запланировано несколько секций. Первая секция – самая короткая, без практики. Она о том, как Тарантул устроен изнутри, что это такое и как надо его использовать. Также мы обсудим проблемы, которые в нем есть; это очень важно – во время эксплуатации знать о всех проблемах! Вторая часть – это будет очень легонькая практика. Мы запустим Tarantool, посмотрим, как он работает, что такое концепция Application server. Третья часть – самая сложная, мы создадим полноценный сервис, будем это масштабировать и, в качестве вишенки на торте, сделаем все это отказоустойчивым. Резюмирую. Теории будет где-то 50 минут, дальше – только практика.

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

Василий: Нет, не потребуется, только ноутбуки. Язык Lua примитивен, я всем его объясню. Файлы конфигурации можно будет взять с моего github, ссылку я дам.

PG Day: Получается своеобразный plug-n-play: как взять минимальное количество инструментов и сразу начать создавать работающую архитектуру.

Василий: Все верно. Мы создадим проект, который будет удовлетворять двум требованиям: прогнозируемое масштабирование и отказоустойчивость. Будут использоваться две технологии: собственно, Тарантул и nginx (тот самый reverse proxy модуль, про который я говорил).

PG Day: Какие фичи вы хотите добавить в Тарантул? Делаете что-то крутое сейчас, что скоро в нем появится?

Василий: Вначале хочу сказать, что у нас полностью открытый roadmap, на который может влиять community. Наверное, SQL – одна из самых больших фич, которая прямо сейчас разрабатывается, уже доступна alpha-версия. Наш план: догнать ее до stable, после чего начать реализовывать распределённый SQL и полноценный планировщик запросов.

PG Day: Под SQL подразумевается стандарт SQL или какая-то разновидность?

Василий: Мы взяли парсер SQLite3. SQL стандарт, если мне память не изменяет, 2003 года. Но, надо понимать, что в нем есть какие-то нестандартные вещи.

PG Day: Есть ли планы сделать встроенный в Тарантул SQL совместимым с популярными СУБД?

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

PG Day: Тарантул – это что-то такое, что следует брать на старте, когда начинается запуск продукта, или же есть какие-то примеры применения в уже сложившейся инфраструктуре?

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

Был отличный кейс недавно: Тарантул использовали как read-only реплику в MySQL кластере, все это позволило сильно разгрузить кластер MySQL и увеличить время отклика. Создала это компания Mamba (Wamba).

Говоря о community, коллеги из Mamba сами разработали репликационные механизмы между этими базами и выложили их в open source для общего пользования. Мы об этом всем узнали, когда человек в нашем community-чате начал активно спрашивать о репликации.

Еще есть у нас один клиент, сделавший репликацию через Oracle GoldenGate в Tarantool. Схема та же: вся OLTP-нагрузка переносится в Tarantool. Это им позволило сэкономить много денег и повысить время отклика.

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

Василий: На контрактной основе.

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

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

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

PG Day: Есть в планах идея сделать Тарантул продуктом, пригодным для стабильного и быстрого OLAP? Или это все-таки противоречит его идеологии?

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

PG Day: Текущий roadmap сформирован из актуальных требований и реальных прецедентов?

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

PG Day: А в какой момент вы понимаете, что есть какая-то фича, которая должна попасть в roadmap продукта?

Василий: Это сложный вопрос. Бывает совершенно по-разному. Могу свой недавний опыт пересказать.

Была такая задача: добавить возможность возвращать HTTP статусы и заголовки из Tarantool в nginx модуль. Идея висела где-то год, многие за эту идею проголосовали, а у меня все руки до реализации не доходили. Дошли, когда появились два заказчика, которые говорят: «Парни, а вот у нас тут везде SOAP и REST, и нам очень нужны коды статусов». Естественно, фича сразу появилась в open source.

PG Day: Мы уже немного поговорили про содержание мастер-класса. Кому в первую очередь он будет полезен?

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

PG Day: Спасибо, Василий! Хочу поблагодарить за то время, которое ты нам уделил. С нетерпением ждем нашей встречи в Санкт-Петербурге.

Василий: Взаимно, Роман! Очень жду. Для меня это будет интересный опыт.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331646/


Метки:  

Анонс Mobius 2017 Moscow: покорение Москвы

Понедельник, 26 Июня 2017 г. 11:12 + в цитатник


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

Что можно ожидать от первого столичного Mobius? Имена спикеров и другие подробности — под катом.


Чего ждать




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

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



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

Среди тем Mobius будут и «вечные», и актуальные конкретно сейчас. Среди вечных, которые нам интересны, есть:
  • Шаблоны проектирования
  • Архитектура (хоть Android, где Google недавно выкатил «официальный» подход, хоть iOS)
  • «Реактивщина»
  • Сокращение цикла разработки (горячий редеплой на девайс, оптимизация скриптов сборки, эмуляторы, подходы к тестированию).


А вот интересующие нас «свежие» (если вам самим есть что рассказать об этом, смотрите ниже раздел «Стать докладчиком»):
  • Новинки Android O
  • Kotlin best practices. Темы вроде «что нового в Котлине» и «как устроены корутины» уже были широко раскрыты — теперь настало время учиться хорошо писать на нём. Поэтому нам интересен опыт применения Kotlin в продакшене.
  • Аналогично со Swift best practices. «Теоретических» докладов про язык уже было немало, сообщество ждёт разбора реальных примеров из жизни.
  • Машинное обучение: Google анонсировал облегчённую версию TensorFlow для использования на мобильном устройстве, но так ли просто воспользоваться ей сейчас?


Спикеры




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

Денис Неклюдов (90Seconds) — «ветеран» конференции и обладатель почётного статуса Google Developer Expert. Этой весной на петербургском Mobius особенно активно говорили об архитектуре — и одной из причин этого было выступление Дениса со Степаном Гончаровым «Современный подход к архитектуре Android-приложения».





David Gonz'alez — а вот этот известный андроидовод, в отличие от Дениса, ранее на Mobius не выступал. Зато с Денисом он похож в другом: во-первых, тоже обладает званием GDE, а во-вторых, он на Mobius тоже поговорит об архитектуре — интересно будет сравнить их доклады.






Александр Зимин (Uberchord GmbH) — тоже заметный спикер, но уже не по Android, а по iOS. Победитель программы WWDC 2015 Scholarships, вёл первые курсы Swift в России, организатор CocoaHeads Russia — перечислять его заслуги можно долго. Ещё не можем огласить тему его нового доклада, но можем напомнить предыдущую: на Mobius 2017 Piter он рассказывал об измерении UX в iOS-приложении.





Матвей Мальков — в 2015-м его доклад о реактивном программировании под Android попал в топ докладов Mobius 2015 по оценкам зрителей. В 2016-м, развив тему реактивщины, Матвей снова оказался с ней в топе, а также выступил с докладом об использовании Scala в Android. Mobius 2017 Piter он пропустил, а вот в Москве будет — так что в 2017-м москвичам больше повезло с ним, чем петербуржцам.





Максим Соколов (Avito), доклад которого «Advanced Swift Generics — перейдём на » в прошлом году стал фаворитом зрителей на петербургском Mobius. Теперь Максим, разрабатывая в Avito мессенджер, получил ещё больше опыта работы со Swift — и на новом Mobius поделится этим опытом.





Aleksander Piotrowski — польский спикер, на петербургском Mobius рассказывавший о ConstraintLayout, тогда оказался благодарен за то, что мы не против использовать эту его фотографию: «Некоторые конференции, когда я присылаю её, просят прислать какую-нибудь другую. Не понимаю, чем им не понравился мой лоб?» В общем, ждём осенью в Москве Александра с его лбом, скрывающим много знаний об Android.





Игорь Кашкута (Badoo) выступал на Mobius уже дважды (с темами «Пизанская башня мобильной разработки» и «Процесс разработки iOS-приложения»), и во второй раз зрители остались ощутимо более воодушевлены. Работа в Badoo должна дать много материала и для нового доклада в Москве — постараемся, чтобы там зрителям понравилось ещё больше.





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





Йонатан Левин на Mobius 2017 Piter выступал сразу с двумя докладами: «IPC: AIDL — это не ругательство» погружался в технические детали, а закрывающий кейноут «Как сделать из вашего приложения продукт» был рассчитан на всех. Оба выступления понравились зрителям, и было бы глупо не позвать Йонатана снова. Сейчас он ещё не знает точно свой график поездок и пока не подтвердил участие, но надеемся, что громкий голос комьюнити заставит Йонатана найти время в своём плотном графике (и вы можете этому поспособствовать — например, в комментариях).


Стать докладчиком




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

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

Главное требование одно: ваш доклад должен быть полезен другим разработчикам.

Программа и регистрация


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

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

https://habrahabr.ru/post/331640/


Бизнес-планирование в игровой индустрии

Понедельник, 26 Июня 2017 г. 10:51 + в цитатник
В апреле в Высшей школе бизнес-информатики НИУ ВШЭ проходила закрытая лекция по бизнес-планированию в игровой индустрии от продюсера компании Rocket Jump Александра Тезяева. Лекция проходила в рамках образовательной программы “Менеджмент игровых проектов”, где мы часто проводим такие мероприятия для слушателей и выпускников наших программ. Под катом предлагаем вашему вниманию краткий конспект лекции.




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

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



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


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

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


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


Бизнес-план игры помогает дать ответы на вопросы:
  • Каков рыночный спрос на игру и как он будет изменяться
  • Какие ресурсы и в каких количествах потребуются для разработки игры
  • Сколько будут стоить ресурсы и где их найти
  • Каковы будут показатели у игры. Самый простой и дешевый способ их определить — сделать soft launch
  • Какими могут быть общие доходы и как их следует распределять между всеми участниками
  • Что делать при наступлении риска. Важно не только написать, с какими рисками вы можете столкнуться, но и продумать, что вы будете с ними делать



Основные пункты бизнес-плана:
  • Лицензии. Авторские права. Юридические особенности;
  • Маркетинговый план. Конкурентный анализ;
  • Производственный план. Бюджетирование;
  • Персонал;
  • Оценка рисков;
  • План выпуска игры;
  • Инвестиционный план;
  • Бизнес-модель

Лицензии и авторские права
Если вы хотите хоть что-нибудь сделать в игре, убедитесь:
  • Что вы не нарушаете никакие лицензионные соглашения
  • Что вы будете и можете соответствовать всем правилам стора и рынка, в котором хотите выходить

Вариантов лицензий очень много и их нужно учитывать и разбираться, чтобы не возникло конфликта со стором и вам не заблокировали игру.
Очень важно следить за авторскими правами: любая строчка кода программиста приравнивается к литературному произведению. Звук тоже защищается авторским правом, даже если он очень короткий.
Из практики: любое оспаривание авторского права в Европе или США стоит от 50 000$.

Возможные последствия нарушения:
  • Игру не выпустят в сторе
  • Игру удалят из стора после того, как вы зальете трафик
  • СМИ осветят игру и вас в негативном свете
  • Вас оштрафуют или вы получите претензию правообладателя




Маркетинговый план
Основные пункты маркетингового плана:
  • Определите основной рынок для игры
  • Узнайте всю специфику основного рынка. Что под этим подразумевается? Есть культурные, социальные и политические различия. Очень важно их знать.
  • Определите нишу для вашей игры
  • Узнайте своих игроков. Можно посмотреть на игроков конкурентов, собрать информацию на форумах, почитать отчеты крупных компаний и так далее. Вам важно знать о них максимально много.
  • Конкуренты. Маленьким компаниям и стартапам найти своих конкурентов очень просто: нужно зайти в стор и посмотреть похожие игры. Большим компаниям для этого нужно больше инструментов, потому что нужно и больше информации. Главная цель — понять, что уже есть и не копировать это, либо копировать, но делать лучше.
  • Определите ваше уникальное конкурентное преимущество. Вы должны сразу понимать, чем ваша игра понравится игрокам и везде делать на этом акцент.
  • Трафик и иные средства продвижения. Цена трафика сейчас очень большая, поэтому нужно делать акцент в том числе и на иные средства продвижения: pr, соцсети, мессенджеры, виральные механики, спецпроекты и так далее.
  • Подготовьте план релиза игры. Если кому-то кажется, что зарелизить игру — это просто, он ошибается. К сожалению, после релиза ваша работа только начинается.


Производственный план — как будем делать игру?
Основные пункты производственного плана:
  • Сеттинг и жанр
  • Кто нужен и что нужно для создания игры. Кто — понятно, это люди, а вот что будет участвовать в разработке — нужно подумать. Во-первых, это компьютер. Еще часто забывают, что игру нужно будет тестировать, а для этого нужны устройства. Кроме того вам могут понадобиться столы, стулья, стенды — все, что угодно
  • Не забываем про лицензии!
  • Какие ресурсы у вас есть для создания игры. Если, к примеру, у вас есть связи, которые помогут найти инвестиции или пропиарить игру, нужно обязательно это прописать
  • Определите очередность использования ресурсов. Желательно отметить ключевые точки на вашем таймлайне. Когда нужно будет найти издателя, когда нужно что-то купить и так далее. Это поможет вам распределить деньги.
  • Определите риски и как вы будете их устранять
  • Рассчитайте KPI игры. Существуют рассчитываемый KPI и тот, который есть по факту. Чем точнее вы рассчитаете KPI, тем проще вам будет потом



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

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

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


Что еще нужно указать в финансовом плане?
  • Девайсы
  • Разработка и сопутствующие затраты
  • Зарплата
  • Аренда помещения и все, что с этим связано
  • Не забываем про лицензии!
  • Стоимость разработки игры
  • Стоимость продвижения игры
  • Общая (итоговая) стоимость игры. Именно она позволит вам говорить, была игра успешной или нет


Финансовый план

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

Персонал

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

Риски

Форс-мажорные риски — то, что невозможно предусмотреть. Для таких рисков полезно сразу поставить резервную сумму — условные 10000$ или 10% от бюджета.

Примеры рисков при выпуске игры:
  • Курс рубля к основным мировым валютам
  • Цена аутсорса
  • Изменились лицензионные условия
  • Изменилось законодательство
  • Изменилось культурное восприятие вашей игры
  • Изменились условия сотрудничества/инвестирования
  • Уход ведущих специалистов
  • Кража ваших наработок
  • Пропала мотивация


План выпуска игры
Основные пункт плана выпуска игры для бизнес-плана:
  • Позиционирование игры на рынке. Берем из маркетингового плана
  • Портрет ЦА. Можно взять из Facebook Insights
  • Разработка бизнес-модели игры
  • Расчет KPI игры — то, что вы посчитали из тех показателей, которые можете найти
  • Определите точки роста и ваши действия на них. Когда ваша игра выстрелит, вам срочно кто-то понадобится: копирайтер, КМ, маркетолог и др. Вы должны обязательно это учитывать.
  • Определите способы продвижения
  • Сформируйте бюджет для soft launch
  • Определите дату soft launch и другие ключевые даты по проекту


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


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

Осенью у нас начинается обучение на образовательной программе «Менеджмент игровых проектов», приглашаем 28 июня на день открытых дверей!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331642/


Метки:  

Как я сдал экзамен на сертификат CISSP

Понедельник, 26 Июня 2017 г. 10:42 + в цитатник
Первый источник информации, из которого я многое узнал о CISSP, это публикация на Хабре. В своем описании постараюсь не дублировать информацию из этого поста.

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

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

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

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

После работы по учебникам, наступает этап тренировки с тестовыми вопросами. Без него сдать экзамен не получится. Существует множество ресурсов с такими вопросами. Из бесплатных мне больше понравился ресурс Skillset. Я прислушался к рекомендациям прошлых поколений экзаменующихся и за $129,99 приобрел себе платный годовой доступ к коммерческой базе вопросов CCCure.

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

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

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

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

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

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

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

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

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

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

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

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

https://habrahabr.ru/post/330984/


Метки:  

Azure-IaaS-Дайджест №16 (Май)

Понедельник, 26 Июня 2017 г. 10:13 + в цитатник
Disclaimer: Я пишу в основном про Azure с точки зрения инфраструктуры (DSC, IaaS, Hybrid\Private Cloud, OMS, ASR, Backup и т.д.). Не про разработку под Azure (хотя иногда что-то проскакивает).

Простите за опоздание, но «Поехали»!

Azure




OMS




Azure Stack


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

https://habrahabr.ru/post/330164/


Метки:  

Головная боль от использования математического софта

Понедельник, 26 Июня 2017 г. 09:41 + в цитатник

Picture 2

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

Введение


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

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

Для выявления всех дефектов кода, представленных в статье, использовался статический анализатор PVS-Studio версии 6.15, работающий в Windows/Linux с языками программирования C/C++/C#.

Ошибки из 3rd party


Эта история началась с поиска ошибок в проекте Point Cloud Library (PCL, GitHub). Не ставив себе цели найти много ошибок и написать статью, я просто просматривал отчёт и нашёл очень интересную ошибку:

V533 It is likely that a wrong variable is being incremented inside the 'for' operator. Consider reviewing 'i'. sparsematrix.inl 212
template
SparseMatrix& SparseMatrix::operator *= (const T& V)
{
  for( int i=0 ; icode>

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

Этот код оказался из математической библиотеки Poisson Surface Reconstruction. Я убедился, что ошибка до сих по присутствует в последней версии кода. Страшно подумать, сколько ещё проектов включают в себя эту библиотеку.

Вот ещё один странный фрагмент кода:

V607 Ownerless expression 'j < remains'. allocator.h 120
void rollBack(const AllocatorState& state){
  ....
  if(state.index/ <=
      memory[index][j].~T();
      new(&memory[index][j]) T();
    }
    remains=state.remains;
  }
  ....
}

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

Scilab


О проекте


Scilab — пакет прикладных математических программ, предоставляющий открытое окружение для инженерных (технических) и научных расчётов. Эта среда разработки является одной из общедоступных альтернатив Matlab, которая широко используется в разных учреждениях и научных исследованиях. Ещё одной популярной альтернативой Matlab является GNU Octave, и ранее мы уже обращали внимание на эти проекты:
Перед написанием новой статьи о Scilab я прочитал старую и сделал всего два вывода:
  1. За 3 года не исправили всего парочку мест («Зачем исправлять неопределённое поведение, если и так всё работает?» — видимо, подумали разработчики);
  2. В проекте появилось много новых ошибок. Я решил поместить в статью только пару десятков, чтобы не слишком утомить читателя.

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

Красивые опечатки


V530 The return value of function 'back' is required to be utilized. sci_mscanf.cpp 274
types::Function::ReturnValue sci_mscanf(....)
{
  ....
  std::vector pITTemp = std::vector<...>();
  ....
  case types::InternalType::ScilabString :
  {
    ....
    pITTemp.pop_back();       // <=
    pITTemp.push_back(pType);
  }
  break;
  case types::InternalType::ScilabDouble :
  {
    ....
    pITTemp.back();           // <= ???
    pITTemp.push_back(pType);
  }
  break;
  ....
}

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

V595 The 'Block.inptr' pointer was utilized before it was verified against nullptr. Check lines: 478, 479. sci_model2blk.cpp 478
types::Function::ReturnValue sci_model2blk(....)
{
  ....

  Block.inptr[i] = MALLOC(size);
  if (Block.inptr == nullptr)
  {
      freeBlock(&Block);
      Scierror(888, _("%s : Allocation error.\n"), name.data());
      return types::Function::Error;
  }

  memset(Block.inptr[i], 0x00, size);
  ....
}

Очень интересный случай опечатки, из-за которой контроль за выделением памяти перестал работать. Скорее всего, правильный код должен быть таким:
Block.inptr[i] = MALLOC(size);
if (Block.inptr[i] == nullptr)
{
  ....
}

V595 The 'pwstLines' pointer was utilized before it was verified against nullptr. Check lines: 78, 79. mgetl.cpp 78
int mgetl(int iFileID, int iLineCount, wchar_t ***pwstLines)
{
  *pwstLines = NULL;
  ....
  *pwstLines = (wchar_t**)MALLOC(iLineCount * sizeof(wchar_t*));
  if (pwstLines == NULL)
  {
      return -1;
  }
  ....
}

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

V595 The 'array_size' pointer was utilized before it was verified against nullptr. Check lines: 67, 68. diary_manager.cpp 67
wchar_t **getDiaryFilenames(int *array_size)
{
  *array_size = 0;
  if (SCIDIARY)
  {
    std::list wstringFilenames = SCIDIARY->get....
    *array_size = (int)wstringFilenames.size();
    if (array_size > 0)
    {
      ....
    }
  ....
}

Стабильность — признак мастерства. Программист снова забыл разыменовать указатель, из-за чего с нулём сравнивается не размер некоторого массива, а указатель на эту переменную.

V501 There are identical sub-expressions 'strncmp(tx, "%pi", 3) == 0' to the left and to the right of the '||' operator. stringtocomplex.c 276
static int ParseNumber(const char* tx)
{
  ....
  else if (strlen(tx) >= 4 && (strncmp(tx, "%eps", 4) == 0
    || strncmp(tx, "+%pi", 4) == 0 || strncmp(tx, "-%pi", 4) == 0
    || strncmp(tx, "+Inf", 4) == 0 || strncmp(tx, "-Inf", 4) == 0
    || strncmp(tx, "+Nan", 4) == 0 || strncmp(tx, "-Nan", 4) == 0
    || strncmp(tx, "%nan", 4) == 0 || strncmp(tx, "%inf", 4) == 0
          ))
  {
      return 4;
  }
  else if (strlen(tx) >= 3
    && (strncmp(tx, "+%e", 3) == 0
     || strncmp(tx, "-%e", 3) == 0
     || strncmp(tx, "%pi", 3) == 0   // <=
     || strncmp(tx, "Nan", 3) == 0
     || strncmp(tx, "Inf", 3) == 0
     || strncmp(tx, "%pi", 3) == 0)) // <=
  {
      return 3;
  }
  ....
}

Эта функция содержит некий код для парсинга чисел. Анализатор нашёл подозрительное сравнение с двумя одинаковыми строками "%pi". Глядя на соседний фрагмент кода, можно предположить, что вместо продублированной строки могла быть строка "-%pi" или "-Inf". Также не исключено, что это просто лишняя скопированная строчка кода, но тогда её лучше удалить.

Приоритеты операций


V502 Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '==' operator. sci_sparse.cpp 49
types::Function::ReturnValue sci_sparse(....)
{
  bool isValid = true;
  ....
  for (int i = 0 ; isValid && i < in.size() ; i++)
  {
    switch (in[i]->getType())
    {
      case types::InternalType::ScilabBool :
      case types::InternalType::ScilabSparseBool :
      {
        isValid = (i == (in.size() > 1) ? 1 : 0);
      }
  ....
}

Ошибки с приоритетами операций очень распространены в современном коде. (см. статью "Логические выражения в C/C++. Как ошибаются профессионалы").

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

Следует переписать код на правильный приоритет операций:
isValid = (i == (in.size() > 1 ? 1 : 0));

V590 Consider inspecting the 'iType != — 1 && iType == 8' expression. The expression is excessive or contains a misprint. scilabview.cpp 175
void ScilabView::createObject(int iUID)
{
  int iType = -1;
  int *piType = &iType;

  getGraphicObjectProperty(....);
  if (iType != -1 && iType == __GO_FIGURE__)
  {
    m_figureList[iUID] = -1;
    setCurrentFigure(iUID);
  }
  ....
}

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

Условное подвыражение (iType != -1) никак не влияет на результат всего условного выражения. Убедиться в ошибке можно с помощью построения таблицы истинности для этого примера.

Ещё один такой пример:
  • V590 Consider inspecting the 'iObjectType != — 1 && iObjectType == 5' expression. The expression is excessive or contains a misprint. sci_unglue.c 90

Неправильные сообщения об ошибках


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

V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 159, 163. cdfbase.c 159
void cdf_error(char const* const fname, int status, double bound)
{
  switch (status)
  {
    ....
    case 10:
    if (strcmp(fname, "cdfchi") == 0)      // <=
    {
      Scierror(999
               _("%s: cumgam returned an error\n"), fname);
    }
    else if (strcmp(fname, "cdfchi") == 0) // <=
    {
      Scierror(999,
        _("%s: gamma or inverse gamma routine failed\n"), fname);
    }
    break;
  ....
}

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

V510 The 'Scierror' function is not expected to receive class-type variable as third actual argument. sci_winqueryreg.cpp 149
const std::string fname = "winqueryreg";

types::Function::ReturnValue sci_winqueryreg(....)
{
  ....
  if (rhs != 2 && rhs != 3)
  {
    Scierror(77, _("%s: Wrong number...\n"), fname.data(), 2, 3);
    return types::Function::Error;
  }
  ....
  else
  {
    Scierror(999, _("%s: Cannot open Windows regist..."), fname);
    return types::Function::Error;
  }
  ....
}

При печати строки в одном месте забыли вызвать метод data().

V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 48
int sci_scinotes(char * fname, void* pvApiCtx)
{
  ....
  try
  {
    callSciNotesW(NULL, 0);
  }
  catch (GiwsException::JniCallMethodException exception)
  {
    Scierror(999, "%s: %s\n", fname,
      exception.getJavaDescription().c_str());
  }
  catch (GiwsException::JniException exception)
  {
    Scierror(999, "%s: %s\n", fname,
      exception.whatStr().c_str());
  }
  ....
}

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

Таких мест найдено несколько:
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_builddoc.cpp 270
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_closescinotesfromscilab.cpp 45
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_closescinotesfromscilab.cpp 50
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 52
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 263
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 272
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 349
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 353
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 365
  • V746 Type slicing. An exception should be caught by reference rather than by value. sci_scinotes.cpp 369
  • V746 Type slicing. An exception should be caught by reference rather than by value. visitor_common.cpp 1743
  • V746 Type slicing. An exception should be caught by reference rather than by value. overload.cpp 135

Странный код


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

V523 The 'then' statement is equivalent to the 'else' statement. data3d.cpp 51
void Data3D::getDataProperty(int property, void **_pvData)
{
  if (property == UNKNOWN_DATA_PROPERTY)
  {
    *_pvData = NULL;
  }
  else
  {
    *_pvData = NULL;
  }
}

Вот такая нехитрая функция, которая всегда обнуляет указатель.

V575 The 'memset' function processes '0' elements. Inspect the third argument. win_mem_alloc.c 91
void *MyHeapAlloc(size_t dwSize, char *file, int line)
{
  LPVOID NewPointer = NULL;

  if (dwSize > 0)
  {
    _try
    {
      NewPointer = malloc(dwSize);
      NewPointer = memset (NewPointer, 0, dwSize);
    }
    _except (EXCEPTION_EXECUTE_HANDLER)
    {
    }
    ....
  }
  else
  {
    _try
    {
      NewPointer = malloc(dwSize);
      NewPointer = memset (NewPointer, 0, dwSize);
    }
    _except (EXCEPTION_EXECUTE_HANDLER)
    {
    }
  }
  return NewPointer;
}

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

V695 Range intersections are possible within conditional expressions. Example: if (A < 5) {… } else if (A < 2) {… }. Check lines: 438, 442. sci_sorder.c 442
int sci_sorder(char *fname, void* pvApiCtx)
{
  ....
  if (iRows * iCols > 0)
  {
      dblTol1 = pdblTol[0];
  }
  else if (iRows * iCols > 1)
  {
      dblTol2 = pdblTol[1];
  }
  ....
}

Второе условие всегда ложно, так как если EXPR > 0, то проверять EXPR > 1 уже не имеет смысла. В этом коде явно присутствует какая-то ошибка.

Разыменование нулевых указателей и неопределённое поведение


V522 Dereferencing of the null pointer 'dataz' might take place. polylinedata_wrap.c 373
BOOL translatePolyline(int uid, double x, double y, double z,
                       int flagX, int flagY, int flagZ)
{
  double *datax = NULL;
  double *datay = NULL;
  double *dataz = NULL;                          // <=

  int i = 0;
  if (x != 0.0)
  {
    datax = getDataX(uid);
    if (datax == NULL) return FALSE;
  ....
  if (z != 0 && isZCoordSet(uid))
  {
    if (flagZ) {
      for (i = 0; i < getDataSize_(uid); ++i)
      {
        dataz[i] = pow(10.,log10(dataz[i]) + z); // <=
      }
    } else {
      for (i = 0; i < getDataSize_(uid); ++i)
      {
        dataz[i] += z;                           // <=
      }
    }
  }

  return TRUE;
}

Есть массивы datax, datay и dataz. Последний нигде не инициализируется, но при определённых условиях используется.

V595 The 'number' pointer was utilized before it was verified against nullptr. Check lines: 410, 425. scilab_sscanf.cpp 410
int scilab_sscanf(....)
{
  ....
  wchar_t* number = NULL;
  ....
  number = (wchar_t*)MALLOC((nbrOfDigit + 1) * sizeof(wchar_t));
  memcpy(number, wcsData, nbrOfDigit * sizeof(wchar_t));
  number[nbrOfDigit] = L'\0';
  iSingleData = wcstoul(number, &number, base);
  if ((iSingleData == 0) && (number[0] == wcsData[0]))
  {
    ....
  }
  if (number == NULL)
  {
      wcsData += nbrOfDigit;
  }
  else
  {
      wcsData += (nbrOfDigit - wcslen(number));
  }
  ....
}

Под строку number выделили память с помощью функции malloc(), при этом до проверки указателя его несколько раз разыменовывают и передают в функцию memcpy() в качестве аргумента, что недопустимо.

V595 The 'OuputStrings' pointer was utilized before it was verified against nullptr. Check lines: 271, 272. spawncommand.c 271
char **CreateOuput(pipeinfo *pipe, BOOL DetachProcess)
{
  char **OuputStrings = NULL;
  ....
  OuputStrings = (char**)MALLOC((pipe->NumberOfLines) * ....);
  memset(OuputStrings, 0x00,sizeof(char*) * pipe->NumberOfLines);
  if (OuputStrings)
  {
    char *line = strtok(buffer, LF_STR);
    int i = 0;

    while (line)
    {
      OuputStrings[i] = convertLine(line, DetachProcess);
  ....
}

Здесь выделяют динамическую память для переменной OuputStrings, но до проверки этого указателя, выделенную память обнуляют с помощью функции memset(), а так делать нельзя. Цитата из документации к функции: "The behavior is undefined if 'dest' is a null pointer".

Утечки памяти и незакрытые ресурсы


V611 The memory was allocated using 'new T[]' operator but was released using the 'delete' operator. Consider inspecting this code. It's probably better to use 'delete [] piP;'. sci_grand.cpp 990

V611 The memory was allocated using 'new T[]' operator but was released using the 'delete' operator. Consider inspecting this code. It's probably better to use 'delete [] piOut;'. sci_grand.cpp 991
types::Function::ReturnValue sci_grand(....)
{
  ....
  int* piP = new int[vectpDblInput[0]->getSize()];
  int* piOut = new int[pDblOut->getSize()];
  ....
  delete piP;
  delete piOut;
  ....
}

Тут были допущены две серьезные ошибки. После выделения динамической памяти под массивы, очищать ее следует с помощью вызова оператора delete[], т.е. с квадратными скобками.

V773 The function was exited without releasing the 'doc' pointer. A memory leak is possible. sci_builddoc.cpp 263
int sci_buildDoc(char *fname, void* pvApiCtx)
{
  ....
  try
  {
    org_scilab_modules_helptools::SciDocMain * doc = new ....

    if (doc->setOutputDirectory((char *)outputDirectory.c_str()))
    {
      ....
    }
    else
    {
      Scierror(999, _("...."), fname, outputDirectory.c_str());
      return FALSE;  // <=
    }
    if (doc != NULL)
    {
      delete doc;
    }
  }
  catch (GiwsException::JniException ex)
  {
    Scierror(....);
    Scierror(....);
    Scierror(....);
    return FALSE;
  }
  ....
}

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

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

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

V773 Visibility scope of the 'hProcess' handle was exited without releasing the resource. A resource leak is possible. killscilabprocess.c 35
void killScilabProcess(int exitCode)
{
  HANDLE hProcess;

  /* Ouverture de ce Process avec droit pour le tuer */
  hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ....);
  if (hProcess)
  {
    /* Tue ce Process */
    TerminateProcess(hProcess, exitCode);
  }
  else
  {
    MessageBox(NULL, "....", "Warning", MB_ICONWARNING);
  }
}

Утечка ресурса. Согласно документации, после вызова функции OpenProcess необходимо звать функцию CloseHandle.

Заключение


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

Следующим проверенным проектом, в котором много математики, и он востребован в разных исследованиях, будет OpenCV library.

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



Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Svyatoslav Razmyslov. Headache from using mathematical software

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

https://habrahabr.ru/post/331638/


Метки:  

[Перевод] Искусственный интеллект Half-Life SDK: ретроспектива

Понедельник, 26 Июня 2017 г. 09:41 + в цитатник

Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1023 1022 [1021] 1020 1019 ..
.. 1 Календарь