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

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

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

Гумано-ориентированное программирование. Часть первая

Суббота, 17 Июня 2017 г. 20:48 + в цитатник
Пост пишется в качестве вводного в контексте обещанного не так давно курса. Я считаю, в этом есть смысл. Итак.

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

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

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

Геолог ищет нефть. А что делает программист? Пишет программу, которая по геологическим данным будет прогнозировать расположение месторождений. Наконец, бухгалтер вводит финансовую операцию — и хорошая база данных 1С вместе с конфигурацией посчитают налоги по актуальному законодательству и сведут дебет с кредитом, а плохая конфигурация — сами понимаете. И так далее — практически во всём.

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

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

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

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

Кстати, принимаю рекомендации по удобочитаемоссти статьи, сокращения, обобщения и так далее. Пишу для людей.
Ещё пример, следующего дня. Windows-программа diskpart. Как известно, в виндоус принято вызывать хелп вот так: /?

DISKPART> create partition /?

Microsoft DiskPart, версия 10.0.14393.0

EFI - Создание системного раздела EFI.
EXTENDED - Создание расширенного раздела.
LOGICAL - Создать логический диск.
MSR - Создание резервного раздела Майкрософт.
PRIMARY - Создание основного раздела.

DISKPART> create partition logical /?

Для этой команды указаны недопустимые аргументы.
Чтобы получить дополнительные сведения о данной команде, введите HELP CREATE PARTITION LOGICAL


Вам это не кажется странным? Мне тоже. Напоминает статью про PHP — фрактал плохого дизайна, где нет строгой конвенции именования функций.
Ещё веселее, когда запускаешь cmd и делаешь что-то вроде

cd c:\ && dir /b/s | findstr "\.docx$" > list.txt && list.txt

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

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

Так фейсбук, решающий в начале проблему общения сокурсников, стал одним из решений для взаимодействия в принципе, синергией порождено, например, такое понятие, как маркетинговый аккаунт. А почему? Потому, что людям удобно и хорошо! И захотелось ещё удобнее… И вообще, абсолютно любой успешный стартап решает проблему. Делая это быстро, приятно, с комфортом. И в этом смысле, когда я запускаю diskpart, я ожидаю от программы запрос: «Для режима мастера нажмите M, для режима строки нажмите ВВОД». При выборе режима мастера программа опрашивает меня и делает конкретную операцию. Быстро и удобно. Профит! И доверие к системе повышается, и зная, что она удобная, начинаешь рекомендовать её, и так далее…

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

И, кстати, во всём этом — одна из главных проблем освоения компьютера как такового. Люди старшего поколения «автоматически» доверяют всё знающим людям, понимая, что давно отстали от прогресса. Знаюшие люди — программисты. И вот человек садится за ту же Windows… и понимает, что перед ним — экран с какими-то картинками. Никаких пояснений. Хотя, чёрт возьми, «интуитивно понятный интерфейс»! А человек понятия не имеет, что со всем этим делать и чувствует себя «динозавром». Совсем другое дело, когда ОС загружается и при соответствующих настройках (предполагающих, например, что за компьютер сел пенсионер) показывает вводный ролик: мол, вот вам мышь, вот вам экран, вот так мышь управляется… Но ничего этого (по моему опыту, поправьте меня, если я не прав) зачастую нет, было в Vista и в школьных редакциях ALT Linux — тоже есть. И это очень радует.

Люди старшего поколения считают программистов компетентными. Да. А теперь представьте, что вот такой человек столкнулся с банально неудобной программой. Что тогда делает человек? Пугается! И это нормальная реакция… И тут надо сказать, что лет через 40 мы с вами будем «динозаврами» куда большими: прогресс ускоряется… Помните об этом. Особенно хорошо помните об этом, когда делаете интерфейс. Давайте будем заботиться о людях.

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

Организация работы в условиях автоматизации — вопрос, на мой взгляд, очень интересный, важный и заслуживает отдельного внимания. Очень важно здесь не быть сапожником без сапог, используя все возможные блага, предоставленные программистам программистам. И только после этого, если вы чувствуете кайф от предоставленных возможностей, имеет смысл писать Hello, world и всё прочее. Если же вам скучно в автоматическом мире, если вы не получаете удовольствия от того, что «Оно работает!», то скорее всего программирование не для вас.

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

Очень надеюсь, что такой, ориентированный на человека подход окажется интересным и найдёт сторонников. Наверняка очень и очень многие люди так или иначе понимают изложенное. Это вполне очевидные вещи. И задача таких постов — просто закрепить их в сознании, напомнить о них.

У меня всё.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331106/


Метки:  

Ищу команду для создания простой игры с целью изучения Unreal Engine 4

Суббота, 17 Июня 2017 г. 18:08 + в цитатник
Всем привет!

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

Меня зовут Алексей и я собираю команду для работы над хобби-проектом.




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


Немного о себе:


  • программист
  • 10+ лет занимаюсь веб-разработкой (в основном Javascript, фронт-енд и всё такое)
  • ~0.5 лет изучения разработки игр, в особенности Unreal Engine 4
  • пока что разработка игр для меня – хобби, обычно есть только пара часов в день на это дело (в лучшем случае)


О проекте


  • Хобби-проект, для самообучения
  • Движок: Unreal Engine 4, в основном C++
  • Жанр: Shoot 'em up, нечто похожее на Crimsonland: вид сверху, скоротечный геймплей, кучи врагов со всех сторон, разные виды оружия, бонусы и т.д.
  • Тематика: фентезийная, с магией и всё такое
  • Несколько стилей геймплея, по выбору игрока: например – рыцарь с мечом, лучник, маг
  • Элементы RPG: прокачка персонажа, изучение скиллов
  • Однопользовательская игра, без мультиплеера
  • [обсуждаемо] Вместо одного персонажа игрок может контролировать сразу нескольких, например одновременно DD (damage dealer), танк и хилер. По аналогии с мобильной игрой Battleheart.
  • [опционально] Кросс-платформеный релиз: все PC – Windows, macOS, Linux; мобильные ОС: iOS, Android


Кого я ищу:


  • Всех заинтересованых! (наиболее нужны сейчас программисты и 3D-моделлеры)
  • Кто может работать самостоятельно (т.к. я ни разу не менеджер)
  • Кто умеет аргументированно обсуждать идеи, но, в то же время, умеет соглашаться с мнением, отличным от своего


Ещё о проекте:


Есть краткий План Разработки в виде mind map
image

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

Добро пожаловать!



p.s. Аналогичный пост создал на Reddit для англоязычной аудитории.
p.p.s. Также буду рад и просто пообщаться на тему этого проекта или геймдева в принципе.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331102/


Метки:  

Повседневный C++: изолируем API в стиле C

Суббота, 17 Июня 2017 г. 17:20 + в цитатник

Мы все ценим C++ за лёгкую интеграцию с кодом на C. И всё же, это два разных языка.


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


Не смешивайте C и бизнес-логику на C++


Не так давно я случайно заметил в своём любимом компоненте новую вставку. Мой код стал жертвой Tester-Driven Development.


Согласно википедии, Tester-driven development — это антиметодология разработки, при которой требования определяются багрепортами или отзывами тестировщиков, а программисты лишь лечат симптомы, но не решают настоящие проблемы

Я сократил код и перевёл его на С++17. Внимательно посмотрите и подумайте, не осталось ли чего лишнего в рамках бизнес-логики:


bool DocumentLoader::MakeDocumentWorkdirCopy()
{
    std::error_code errorCode;
    if (!std::filesystem::exists(m_filepath, errorCode) || errorCode)
    {
        throw DocumentLoadError(DocumentLoadError::NotFound(), m_filepath, errorCode.message());
    }
    else
    {
        // Lock document
        HANDLE fileLock = CreateFileW(m_filepath.c_str(),
                GENERIC_READ,
                0, // Exclusive access
                nullptr, // security attributes
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                nullptr //template file
            );
        if (!fileLock)
        {
            CloseHandle(fileLock);
            throw DocumentLoadError(DocumentLoadError::IsLocked(), m_filepath, "cannot lock file");
        }
        CloseHandle(fileLock);
    }

    std::filesystem::copy_file(m_filepath, m_documentCopyPath);
}

Давайте опишем словесно, что делает функция:


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

Вам не кажется, что кое-что тут выпадает из уровня абстракции функции?


Ненужная иллюстрация


Не смешивайте слои абстракции, код с разным уровнем детализации логики должен быть разделён границами функции, класса или библиотеки. Не смешивайте C и C++, это разные языки.


На мой взгляд, функция должна выглядеть так:


bool DocumentLoader::MakeDocumentWorkdirCopy()
{
    boost::system::error_code errorCode;
    if (!boost::filesystem::exists(m_filepath, errorCode) || errorCode)
    {
        throw DocumentLoadError(DocumentLoadError::NotFound(), m_filepath,      errorCode.message());
    }
    else if (!utils::ipc::MakeFileLock(m_filepath))
    {
        throw DocumentLoadError(DocumentLoadError::IsLocked(), m_filepath, "cannot lock file");
    }

    fs::copy_file(m_filepath, m_documentCopyPath);
}

Почему C и C++ разные?


Начнём с того, что они родились в разное время и у них разные ключевые идеи:


  • лозунг C — "Доверяй программисту", хотя многим современным программистам уже нельзя доверять
  • лозунг C++ — "Не плати за то, что не используешь", хотя вообще-то дорого заплатить можно и просто за неоптимальное использование

В C++ ошибки обрабатываются с помощью исключений. Как они обрабатываются в C? Кто вспомнил про коды возврата, тот неправ: стандартная для языка C функция fopen не возвращает информации об ошибке в кодах возврата. Далее, out-параметры в C передаются по указателю, а в C++ программиста за такое могут и отругать. Далее, в C++ есть идиома RAII для управления ресурсами.


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


  • OpenGL, Vulkan, cairo и других графических API
  • CURL и других сетевых библиотек
  • winapi, freetype и других библиотек системного уровня

Но использовать не значит "пихать во все места"!


Как открыть файл


Если вы используете ifstream, то с обработкой ошибок попытка открыть файл выглядит так:


int main()
{
    try
    {
        std::ifstream in;
        in.exceptions(std::ios::failbit);
        in.open("C:/path-that-definitely-not-exist");
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
    try
    {
        std::ifstream in;
        in.exceptions(std::ios::failbit);
        in.open("C:/");
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
}

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


Скриншот ошибки fstream


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


// Держи это, если ты вендовоз
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

int main()
{
    try
    {
        FILE *in = ::fopen("C:/path-that-definitely-not-exist", "r");
        if (!in)
        {
            throw std::runtime_error("open failed");
        }
        // ..остальной код..
        fclose(in);
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
}

А теперь мы возьмём этот код и покажем, на что способен C++17, даже если перед нами — API в стиле C.


А почему бы не сделать как советует ООП?


Валяйте, попробуйте. У вас получится ещё один iostream, в котором нельзя просто взять и узнать, сколько байт вам удалось прочитать из файла, потому что сигнатура read выглядит примерно так:


basic_istream& read(char_type* s, std::streamsize count);

А если вы всё же хотите воспользоваться iostream, будьте добры вызвать ещё и tellg:


// Функция читает не более чем count байт из файла, путь к которому задан в filepath
std::string GetFirstFileBytes(const std::filesystem::path& filepath, size_t count)
{
    assert(count != 0);

    // Бросаем исключение, если открыть файл нельзя
    std::ifstream stream;
    stream.exceptions(std::ifstream::failbit);

    // Маленький фокус: C++17 позволяет конструировать ifstream
    //  не только из string, но и из wstring
    stream.open(filepath.native(), std::ios::binary);

    std::string result(count, '\0');
    // читаем не более count байт из файла
    stream.read(&result[0], count);
    // обрезаем строку, если считано меньше, чем ожидалось.
    result = result.substr(0, static_cast(stream.tellg()));

    return result;
}

Одна и та же задача в C++ решается двумя вызовами, а в C — одним вызовом fread! Среди множества библиотек, предлагающих C++ wrapper for X, большинство создаёт подобные ограничения или заставляет вас писать неоптимальный код. Я покажу иной подход: процедурный стиль в C++17.


Шаг первый: RAII


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


namespace detail
{
// Функтор, удаляющий ресурс файла
struct FileDeleter
{
    void operator()(FILE* ptr)
    {
        fclose(ptr);
    }
};
}

// Создаём FileUniquePtr - синоним специализации unique_ptr, вызывающей fclose
using FileUniquePtr = std::unique_ptr;

Такая возможность позволяет завернуть функцию ::fopen в функцию fopen2:


// Держи это, если ты вендовоз
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

// Функция открывает файл, пути в Unicode открываются только в UNIX-системах.
FileUniquePtr fopen2(const char* filepath, const char* mode)
{
    assert(filepath);
    assert(mode);
    FILE *file = ::fopen(filepath, mode);
    if (!file)
    {
        throw std::runtime_error("file opening failed");
    }
    return FileUniquePtr(file);
}

У такой функции ещё есть три недостатка:


  • она принимает параметры по указателям
  • исключение не содержит никаких подробностей
  • не обрабатываются Unicode-пути на Windows

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


Скриншот ошибки


Шаг второй: собираем информацию об ошибке


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


И тут надо признать: не только джуниоры, но и многие мидлы и синьоры не в курсе, как правильно работать с errno и насколько это потокобезопасно. Мы напишем так:


// Держи это, если ты вендовоз
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

// Функция открывает файл, пути в Unicode открываются только в UNIX-системах.
FileUniquePtr fopen3(const char* filepath, const char mode)
{
    using namespace std::literals; // для литералов ""s.

    assert(filepath);
    assert(mode);
    FILE *file = ::fopen(filepath, mode);
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

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


Скриншот подробной ошибки


Шаг третий: экспериментируем с filesystem


C++17 принёс множество маленьких улучшений, и одно из них — модуль std::filesystem. Он лучше, чем boost::filesystem:


  • в нём решена проблема 2038 года, а в boost::filesystem не решена
  • в нём есть однозначный способ получить UTF-8 путь, а ведь ряд библиотек (например, SDL2) требуют именно UTF-8 пути
  • реализация boost::filesystem содержит опасные игры с разыменованием указателей, в ней много Undefined Behavior

Для нашего случая filesystem принёс универсальный, не чувствительный к кодировкам класс path. Это позволяет прозрачно обработать Unicode пути на Windows:


// В VS2017 модуль filesystem пока ещё в experimental
#include 
#include 
#include filesystem>
#include 
#include 
#include 

namespace fs = std::experimental::filesystem;

FileUniquePtr fopen4(const fs::path& filepath, const char* mode)
{
    using namespace std::literals;

    assert(mode);
#if defined(_WIN32)
    fs::path convertedMode = mode;
    FILE *file = ::_wfopen(filepath.c_str(), convertedMode.c_str());
#else
    FILE *file = ::fopen(filepath.c_str(), mode);
#endif
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath.u8string() + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

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


Заглядывая в будущее: мир без препроцессора


Сейчас я покажу вам код, который в июне 2017 года, скорее всего, не скомпилирует ни один компилятор. Во всяком случае, в VS2017 constexpr if ещё не реализован, а GCC 8 почему-то компилирует ветку if и выдаёт следующую ошибку:


Скриншот ошибки компиляции


Да-да, речь пойдёт о constexpr if из C++17, который предлагает новый способ условной компиляции исходников.


FileUniquePtr fopen5(const fs::path& filepath, const char* mode)
{
    using namespace std::literals;

    assert(mode);
    FILE *file = nullptr;
    // Если тип path::value_type - это тип wchar_t, используем wide-функции
    // На Windows система хочет видеть пути в UTF-16, и условие истинно.
    //  примечание: wchar_t пригоден для UTF-16 только на Windows.
    if constexpr (std::is_same_v)
    {
        fs::path convertedMode = mode;
        file = _wfopen(filepath.c_str(), convertedMode.c_str());
    }
    // Иначе у нас система, где пути в UTF-8 или вообще нет Unicode
    else
    {
        file = fopen(filepath.c_str(), mode);
    }
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath.u8string() + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

Это потрясающая возможность! Если в язык C++ добавят модули и ещё несколько возможностей, то мы сможем забыть препроцессор из языка C как страшный сон и писать новый код без него. Кроме того, с модулями компиляция (без компоновки) станет намного быстрее, а ведущие IDE будут с меньшей задержкой реагировать на автодополнение.


Плюсы процедурного стиля


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


  • процедурный стиль легче понять, он проще для джуниоров и на нём написано большинство коротких примеров в сети
  • вы можете завернуть функции C, практически не меняя семантику: наша функция fopen4 по-прежнему использует флаги, mode и другие фокусы в стиле C, но надёжно управляет ресурсами, собирает всю информацию об ошибке и аккуратно принимает параметры
  • документация функции fopen всё-ещё актуальна для нашей обёртки, это сильно облегчает поиск, понимание и переиспользование другими программистами

Я рекомендую все функции стандартной библиотеки C, WinAPI, CURL или OpenGL завернуть в подобном процедурном стиле.


Подведём итоги


На C++ Russia 2016 и C++ Russia 2017 замечательный докладчик Михаил Матросов показывал всем желающим, почему не нужно использовать циклы и как жить без них:



Насколько известно, вдохновением для Михаила служил доклад 2013 года "C++ Seasoning" за авторством Sean Parent. В докладе было выделено три правила:


  • не пишите низкоуровневые циклы for и while
    • используйте алгоритмы и другие средства из STL/Boost
    • если готовые средства не подходят, заверните цикл в отдельную функцию
  • не работайте с new/delete напрямую
  • не используйте низкоуровневые примитивы синхронизации, такие как mutex и thread

Я бы добавил ещё одно, четвёртное правило повседневного C++ кода. Не пишите на языке Си-Си-Плюс-Плюс. Не смешивайте бизнес-логику и язык C.


  • Заворачивайте язык C как минимум в один слой изоляции.
  • Если речь об асинхронном коде, заворачивайте в два слоя: первый изолирует C, второй — прячем примитивы синхронизации и шедулинг задач на потоках

Причины прекрасно показаны в этой статье. Сформулируем их так:


Только настоящий герой может написать абсолютно надёжный код на C/C++. Если на работе вам каждый день нужен герой — у вас проблема.
Доступен ли вам великолепный C++17?

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

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

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

https://habrahabr.ru/post/331100/


Метки:  

Что может пойти не так на сайте метапоисковика и что с этим делать? Часть 2

Суббота, 17 Июня 2017 г. 16:17 + в цитатник
Метапоисковик — это не так просто, как кажется. Почему мы не можем подгружать сразу все туры? Почему так часто меняется цена? Кто виноват, когда тур “ушёл”, и как выкрутиться перед клиентом?

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


Отельная страница



Когда открывается серп, направляется запрос в кеш, который хранится от 15 минут до нескольких часов. В момент открытия отельной страницы, если на отель из кеша пришло менее 3 туров, к ТО отправляется новый запрос на поиск по названию отеля. И могут приехать новые цены. Актуальные.

Почему вообще приходится так часто отправлять запросы к ТО?

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

Вторая причина — туры просто быстро раскупают.

image

Самые большие скачки цен на динамический пакетах (не путать с динамическим ценообразованием из абзаца выше). Динамические пакеты — это туры “отель, билет и иногда трансфер”. Туроператор собирает их самостоятельно, подключаясь к GDS в момент стороннего запроса. Схема такова: мы стучимся к ТО, ТО обращается к GDS, забирая стоимость авиабилета (это всегда регулярный рейс) и одновременно к своей базе отелей и трансферов. И только потом складывается финальная цена. Такие туры могут оказаться выгоднее готовых чартерных пакетов, если у ТО есть договорённость с авиакомпанией или отелем и спецтарифы.

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

Какие тут могут возникать проблемы?

  • Не приехал тур.


У того же Букинга есть прямые контакты с отельерами и база с ценами. А наша сборка выдачи больше напоминает метапоиск. Мы отправляем поставщикам цен асинхронные запросы и зависим от того, что отдаст каждый из них. Если ТО тормозят, то и инвентаря не будет. Поэтому клиентам выдача иногда кажется непредсказуемой — в 12 дня увидел одни предложения, через 3 часа приехали другие. Ну или просто желаемый тур уже купили :)

  • Мало информации об отеле.


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

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

image

Чекаут




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

Что может пойти не так?

1. Подгрузился топливный сбор, и цена выросла

Топливный сбор — это такое эфемерное понятие. Кто-то называет его уловкой туроператоров, но бОльшая часть туристов вообще не понимают, что это и для чего он нужен. Тем не менее, он есть и чаще всего на популярные направления. Составляет от $40 до $80 в зависимости от авиакомпании. Нет строгого правила в какую страну и по какому ТО есть топливо, а куда нет. По каждому туру расчёт индивидуален. Но вот у Библио-Глобуса топливного сбора нет ни на одном направлении. Возможно он уже зашит в цену и с ней и передаётся к нам.


2. Топливный сбор не подтянулся, но он есть

Чтобы получить данные по топливу, нужно прокинуть запрос в личный кабинет туроператора на конкретный тур. Иногда ТО может не отдать критерии, и цена не подъезжает. Бывают случаи, когда в ЛК что-то поменяли, и парсер отвалился. Подключаемся, фиксим.

Почему нельзя добавить топливный сбор сразу, в цены на серпе?

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


3. Не прошла актуализация по туру (неверная цена и информация о перелёте)

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

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

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

Что говорим клиенту?

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


Оплата




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

image

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

1. На этапе оплаты могут произойти проблемы с банком. На стороне банка, естественно.

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

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

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


После оплаты




1. Оплаченный тур может не подтвердить туроператор

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

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

image

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

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


2. Рейс перенесли

Здесь ничего не поделаешь. Это особенность чартерных рейсов, которая чётко прописана в договоре. У нас на чекауте есть услуга конкретизации рейса, которая фиксирует номер чартерного рейса. Без этой услуги туриста могут пересадить на любой рейс с вероятностью 20-30%. С конкретизацией рейс зафиксирован, он практически приравнивется к “регулярке”. Хотя и может задержаться, как и любой другой перелёт.


Как справиться с недоверием?

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


Поставщик и посредник — кто кого вытягивает?



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

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

Наши отношения с туроператорами — это взаимовыгодное сотрудничество. Для них IT — не основная специализация. Около 95% всех туров до сих пор продаются в офлайне.

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

https://habrahabr.ru/post/331086/


Метки:  

Лучше один раз услышать чем семь раз прочитать

Суббота, 17 Июня 2017 г. 14:36 + в цитатник
Большинство статей о музыке и нотной записи страдают большим недостатком:
текстовое описание, скажем, отличия септаккорда от трезвучия, есть, а звука, чтоб это отличие услышать — нет.

image

Хорошим обратным примером является интерактивный мини-учебник по теории музыки от Ableton


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



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

Можно ли как-то попроще?


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

Многие веб-секвенсоры предоставляют такую возможность. Например Flat.io даже предоставляет API по встраиванию редактора в страницу с помощью iframe (хотя для большинства форумов это бесполезно т.к. тэг iframe запрещён в сообщениях)



К сожалению, распространённые сервисы предоставляют только нотный стан. Хотя большинство современной музыки пишется в пианоролл (см. Ableton Live, FL Studio, Pro Tools), а не в классической нотации.

Работающий пример с Piano Roll


Возможно использовать RiffShare. Сервис позволяет задать мелодию (или импортировать через .mid) и получить на неё обычную ссылку:



Результат можно вставить в любой блог, в том числе даже в пост или комментарий на Хабре. Вот как может выглядеть статья о гармонизации из учебника Ableton:
Аккорды
“Mary Had a Little Lamb”

Это известная детская песня с узнаваемой простой мелодией. Вот одноголосая мелодия в тональности Фа-мажор.



открыть http://tinyurl.com/y9k93o3r

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



http://tinyurl.com/y8r9xabu

Как используются аккорды?
Мы добавили трезвучия Фа-мажоре и в До-мажоре. Но почему мы добавили именно эти аккорды?
Обратите внимание на совпадение нот мелодии с нотами аккомпанирующих аккордов. Например, в первом такте ноты Фа и Ля мелодии входят в трезвучие Фа-мажор. Ноты Соль не входят в это трезвучие, но они используются в мелодии как «соединение» между Фа и Ля.


Попробуйте поэкспериментировать поменяв аккорды в композиции.


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

https://habrahabr.ru/post/331096/


Метки:  

Тестируем возможности ARKit. Создаем игру с дополненной реальностью

Суббота, 17 Июня 2017 г. 10:17 + в цитатник

image


На WWDC 2017 Apple анонсировала ARKit — SDK для работы с дополненной реальностью. Благодаря ему порог вхождения в эту технологию стал значительно ниже. Можно ожидать появления большого количества качественных игр и приложений.


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


Вынужден расстроить счастливых обладателей iPhone 6 и ниже. На данных девайсах все эти прелести жизни будут недоступны. Для использования всех ключевых функций ARKit необходим процессор А9 и выше. Apple, конечно, даст урезанный доступ к функциональности, но это уже совсем не то.


Дополненная реальность


Дополненная реальность (augmented reality, AR) — это виртуальная среда, которая накладывается на реальный мир для придания ему большей выразительности, информативности или просто ради развлечения. Термин, предположительно, был предложен исследователем компании Boeing Томасом Коделлом еще в 1990 году. Уже тогда начали появляться первые примеры устройств с применением данной технологии. Впервые дополненная реальность была реализована на электронных шлемах летчиков для вывода информации о полете и радаре.


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


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


  • Игровая индустрия;
  • Архитектура;
  • Киноиндустрия.

Возможности ARKit


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


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


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


Основой ARKit являются ARSCNView и ARSKView. Они служат для отображения live видео и рендеринга 3D и 2D изображений. Как все уже догадались, это наследники от SCNView и SKView. Следовательно, ARKit не привносит каких-то невероятных особенностей в отображении данных. Это все те же движки для работы с 2D и 3D графикой, с которыми уже все знакомы. Поэтому порог вхождения в данную технологию будет достаточно низким. Apple знаменита любовью к своим технологиям и продуктам, но несмотря на это разработчики ARKit сделали поддержку Unity и Unreal Engine. Это положительно скажется на количестве качественных приложений, которые появятся в ближайшее время.


ARSCNView и ARSKView содержат в себе сердце ARKit — ARSession. Именно этот класс содержит в себе все необходимое для работы с дополненной реальностью. Для запуска ARSession необходимо передать конфигурацию работы сессии.


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


  • На девайсах с процессором A9 и новее можно использовать ARWorldTrackingSessionConfiguration. Именно эта конфигурация дает возможность воспользоваться всей мощью нового фреймворка. Для вас будет создана модель окружающего мира в виртуальной реальности и предоставлена информация о плоскостях в поле видимости камеры. Это поможет расположить виртуальные объекты с максимальной точностью.
  • На остальных девайсах, поддерживающих ARKit, будет доступна лишь ARSessionConfiguration. Базовый класс предоставляет только информацию о движении устройства в пространстве, но не строит виртуальных моделей. Это не даст необходимого эффекта и не позволит насладиться всем качеством новой технологии. Вам будет недоступна возможность фиксации виртуальных объектов относительно объектов реального мира.

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


override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingSessionConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
}

Важно помнить, что ARKit потребляет довольно много энергии для расчетов. Если View с контентом не отображается в данный момент на экране, то имеет смысл приостановить сессию на это время, используя session.pause().


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


Способ получения информации об окружающей среде зависит от того, какой вид отображения данных вы будете использовать ARSCNView, ARSKView или Metal. Единицей информации, которую предоставляет ARKit, является ARAnchor. Если у вас включено распознавание поверхностей, то вы столкнетесь с сабклассом ARPlaneAnchor. Он содержит в себе информацию о найденных плоскостях. Благодаря данным якорям есть возможность ориентироваться в пространстве. В случае использования Metal вам придется вручную заниматься рендерингом. Тогда можете подписаться на обновления, используя делегат ARSessionDelegate у класса ARSession, и получать якоря от сессии. Если используете один из Apple движков для рендеринга объектов, тогда есть возможность воспользоваться более удобными делегатами ARSCNViewDelegate или ARSKViewDelegate.


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


Тестируем возможности ARKit


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


Для создания тестового приложения мы воспользуемся ARSCNView для создания и рендеринга 3D моделей. Наша игра будет состоять из 2 этапов. Сначала мы будем расставлять мишени по комнате, а после пытаться как можно быстрее попасть по ним всем. Игра довольна примитивна, но продемонстрирует простоту создания игр с дополненной реальностью.


Начнем с того, что растянем на весь ViewController ARSCNView и создадим IBOutlet. Далее будем работать с ней, как с обычной SCNView. Произведем первоначальную настройку. Сделаем контроллер делегатом контактов физического мира и выведем статистику. Настроим запуск и паузу сессии при появлении и скрытии контроллера.


override func viewDidLoad() {
        super.viewDidLoad()

        sceneView.scene.physicsWorld.contactDelegate = self

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true
}

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARSessionConfiguration.isSupported ? 
ARWorldTrackingSessionConfiguration() : ARSessionConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
}

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


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


Мы не будем здесь описывать обработку нажатий или подсчет очков. Это не так важно, и вы можете это увидеть сами в ДЕМО, представленном в конце статьи.


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


Что понадобится, чтобы создать физический объект:


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

Пример реализации классов патрона в виде шара и логотипа в виде куба с нужными текстурами.


class ARBullet: SCNNode {

    override init() {
        super.init()

        let arKitBox = SCNSphere(radius: 0.025)
        self.geometry = arKitBox
        let shape = SCNPhysicsShape(geometry: arKitBox, options: nil)
        self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
        self.physicsBody?.isAffectedByGravity = false

        self.physicsBody?.categoryBitMask = CollisionCategory.arBullets.rawValue
        self.physicsBody?.contactTestBitMask = CollisionCategory.logos.rawValue

        // add texture
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "art.scnassets/ARKit_logo.png")
        self.geometry?.materials  = [material]
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class Logo: SCNNode {

    override init() {
        super.init()

        let logo = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
        self.geometry = logo
        let shape = SCNPhysicsShape(geometry: logo, options: nil)

        self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape)
        self.physicsBody?.isAffectedByGravity = false

        self.physicsBody?.categoryBitMask = CollisionCategory.logos.rawValue
        self.physicsBody?.contactTestBitMask = CollisionCategory.arBullets.rawValue

        // add texture
        let material = SCNMaterial()
        material.diffuse.contents = UIImage(named: "art.scnassets/logo-mobile.png")
        self.geometry?.materials  = Array(repeating: material, count: 6)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

Хочется обратить внимание на CollisionCategory. Это структура используется для определения типа объекта при контакте.


struct CollisionCategory: OptionSet {
    let rawValue: Int

    static let arBullets  = CollisionCategory(rawValue: 1 << 0)
    static let logos = CollisionCategory(rawValue: 1 << 1)
}

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


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


extension ViewController: SCNPhysicsContactDelegate {

    func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
        guard let nodeABitMask = contact.nodeA.physicsBody?.categoryBitMask,
            let nodeBBitMask = contact.nodeB.physicsBody?.categoryBitMask,
            nodeABitMask & nodeBBitMask == CollisionCategory.logos.rawValue & CollisionCategory.arBullets.rawValue else {
                    return
        }

        contact.nodeB.removeFromParentNode()
        logoCount -= 1

        if logoCount == 0 {
            DispatchQueue.main.async {
                self.stopGame()
            }
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
            contact.nodeA.removeFromParentNode()
        })
    }

}

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


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


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


private func addLogo() {
        guard let currentFrame = sceneView.session.currentFrame else {
            return
        }

        let logo = Logo()
        sceneView.scene.rootNode.addChildNode(logo)

        var translation = matrix_identity_float4x4
        translation.columns.3.z = -1
        logo.simdTransform = matrix_multiply(currentFrame.camera.transform, translation)

        logoCount += 1
        if logoCount == ViewController.logoMaxCount {
            startGame()
        }
}

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


private func shoot() {
        let arBullet = ARBullet()

        let (direction, position) = cameraVector
        arBullet.position = position
        arBullet.physicsBody?.applyForce(direction, asImpulse: true)
        sceneView.scene.rootNode.addChildNode(arBullet)
}

Вот так всего за пару десятков строк мы создали простую игру.


Будущее наступит в сентябре


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


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


Демо проект


Скачивайте в репозитории Touch Instinct

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

https://habrahabr.ru/post/331078/


Метки:  

[Перевод] Как добиться того, чтобы обучение в играх не раздражало

Суббота, 17 Июня 2017 г. 10:15 + в цитатник
image

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

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

Самое печальное в этом то, что когда я пишу об обучении, я имею в виду не такое обучение.

Из-за этого заблуждения я не могу сообщить об обучении то, что хочу.

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

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

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

RTFM?


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



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

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

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

Зачем играм вообще нужно обучение?


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

Если двое игроков садятся за шахматную доску, игра не начнётся, пока оба игрока не узнают как двигаются фигуры и каковы условия победы. (И применимо ли правило «взятия на проходе».)

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

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


Если игрок не знает, как играть, то он не сможет играть.

Почему многие считают, что ненавидят обучение в видеоиграх?


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

Вот некоторые из часто встречающихся (и абсолютно справедливых) причин ненависти к обучению:

«Обучение впустую тратит время игрока!»

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

«Обучение навязывают игроку!»

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

«Туториалы — это скучища!»

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

«Обучение оскорбительно!»

Обычно это относится к ерунде про «хотите ли вы переключиться в лёгкий режим». Тон такого обучения слишком снисходящий, он как будто подразумевает, что игрок не является разумным человеческим существом, способным на мышление и исследование. Другим частым случаем бывает текст, котторый появляется уже после того, как вы несколько раз делали какое-то действие. Например, пятидесятое повторение «Нажмите A для прыжка!».

Но буду я говорить о чём-то другом.


О, стрелковый тир, где героями не рождаются, но становятся!

«Обучение неприемлемо эстетически!»

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

Нет, и не об этом я собираюсь рассказать.

«Обучение почти никогда не работает!»

Эта жалоба относится обычно к типу туториалов «быстро покажем экран управления и вы больше никогда его не увидите». Ещё иногда игра обучает чему-то на первом уровне, но не использует это знание, а к моменту его применения игрок о нём уже забывает.

«Как там делается долгий прыжок?»

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

«Я люблю исследовать всё самостоятельно. Мне больше нравятся игры, которые дают мне самому заниматься чем угодно».

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


«Вы уверены, что у вас есть мозг? Нажмите X для потверждения». (Пародия на туториал из Far Cry 3: Blood Dragon.)

Самый известный пример


Я хочу рассказать об известнейшем примере обучения «внутри геймплея»: о первых двух экранах оригинальной Super Mario Bros. для NES.



В одном из эпизодов Iwata Asks технический директор Nintendo Сатору Ивата (Satoru Iwata) беседует с дизайнером Super Mario Bros. Сигэру Миямото (Shigeru Miyamoto) об этом первом экране и обо всём «скрытом» обучении, встроенном в этот обманчиво простой дизайн:

Про гумб (goomba):

Ивата: Если вы играете в первый раз, не имея никаких знаний об игре, то наткнётесь на первого гумбу и умрёте.

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

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

Про грибы-бонусы:

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

Ивата: Вы убегаете.

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

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

Миямото: Верно! (смеётся)

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

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

Например, Марио начинает игру с левой части экрана. Весь экран пуст, и игрок может безопасно поэкспериментировать с управлением. Когда игрок нажимает A, Марио подпрыгивает на месте. Нажимая на крестовину, игрок учится бежать вправо (Марио может бежать влево, но камера не скроллит экран в эту сторону).

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

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

Примеры из мобильных игр


Pudding Monsters

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



Уровень 1

На уровне 1 игрок учится сенсорному перемещению монстра к другому монстру. Если игрок отправит монстра в любом другом направлении, то он улетит с экрана и головоломка начнётся заново. Также игроки учатся тому, что при соединении монстров они превращаются в одного, более крупного нового монстра.

Уровень 2

На уровне 2 игроки обучаются тому, что есть другие, неподвижные части уровня, с которыми могут сталкиваться пудинговые монстры. Такая схема позволяет выполнять повороты. Уровень также учит, что иногда для решения головоломки монстра нужно передвинуть несколько раз. Кроме того, игрок может решить головоломку несколькими способами (двигая верхнего монстра или нижнего).

Уровень 3

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

Cut the Rope

В Cut the Rope больше текста, чем в Pudding Monsters, но можно заметить, как увеличивается сложность дизайна уровней и игрока обучают базовым навыкам, по одному за раз (красные стрелки и текст добавлены мной).



Уровень 1

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

Уровень 2

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

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

Уровень 3

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

Один из моих любимых примеров


Один из моих любимых примеров из истории игр взят из игры для Super Nintendo The Legend of Zelda: A Link to the Past.

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

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

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

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

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

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

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

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


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

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

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

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

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

Послесловие


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

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

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

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

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

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

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


  • Если вы хотите изучить действительно подробный анализ того, как этот способ обучения игроков работал в одной из величайших игр, я рекомендую прочитать превосходную статью Уго Билле (Hugo Bille) The Invisible Hand of Super Metroid.
  • Джош Байсер (Josh Bycer) написал пост о том, что он назвал «органическим дизайном», и я уверен, что он говорит о том же.
  • Я написал ещё одну статью о темпе и архетипах, в которой объясняются некоторые полезные трюки для создания такого типа обучения (а именно мой трюк с ABC из статьи по ссылке). Вводя с нужной скоростью механики, вы естественным образом получаете преимущества, даваемые таким типом обучения.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330948/


Метки:  

Security Week 24: 95 фиксов от Microsoft, роутер сливает данные светодиодами, для MacOS появился рансомвар-сервис

Суббота, 17 Июня 2017 г. 10:03 + в цитатник
Этот вторник патчей – просто праздник какой-то! Microsoft решила порадовать админов и выпустила 95 фиксов для Windows всех поддерживаемых версий, Office, Skype, Internet Explorer и Edge. 18 из них – для критических уязвимостей, включая три RCE. Кто не знает, это дыры, позволяющие удаленно запускать код без аутентификации, то есть самые опасные из всех. Первые две, согласно Microsoft, уже под атакой.

CVE-2017-8543 содержится в поисковом движке Windows Search Service (WSS). Сервис удобный, но, как оказалось, с дырой. Хакер, подключившись по SMB, может тотально поработить системы, например, изменять, удалять файлы, создавать новые учетные записи. Проблема имеется как в актуальных версиях Windows, так и в Windows XP и Server 2003. Для ее решения Microsoft снова выпустила отдельные патчи к неподдерживаемым системам. Похоже, это входит у компании в привычку. Вот все бы вендоры так делали!

CVE-2017-8464 – красивая, если так можно выразиться, дыра, позволяющая запускать код с помощью хитровывернутого ярлыка. Пользователю достаточно увидеть зловредный ярлык в Проводнике, чтобы его машина выполнила какой-нибудь нехороший код. Проблема имеется в операционных системах, начиная с Windows 7 SP1, точный список версий можно поглядеть тут. Кстати, уязвимость этого же типа использовал великий и ужасный Stuxnet.

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

Исследователи заставили роутер передавать данные миганием светодиодов

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

Группа товарищей из Университета имени Бен-Гуриона в Негеве придумала новое применение бытовым роутерам и свитчам. Если на девайс внедрить специальную малварь (для экспримента взяли роутер с прошивкой DD-WRT и загрузили на него самодельный скрипт), то она может задорно мигать индикаторами, передавая данные в двоичном представлении со скоростью до 1000 бит/c на один светодиод. Прием этих данных требует, естественно, прямой видимости до устройства, и камеры с высокой частотой кадров.

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



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

В даркнете появился сервис троянцев-вымогателей для MacOS

Новость. Рынок троянцев-вымогателей развивается и расширяется, что заметно невооруженным глазом. Причем уже настолько расширился, что даже для маков появился новый RaaS-сервис. Не то, чтобы это было новым видом облачных услуг – это Ransomware as a Service.

Не вполне корректное название в этом случае, зато как солидно звучит! А кроется за этим сайт в даркнете, создатели которого предлагают всем желающим сварганить рансомварь для MacOS с заданными параметрами. Исследователи из Fortinet, обнаружившие сервис, связались с авторами и те разрекламировали себя как бывших разработчиков из Yahoo и Facebook. При этом за свои услуги они денег не взяли – просто сделали троянца и выслали заказчикам. Мол, их интерес лишь в сборе информации. Однако, судя по висящему на сайте FAQ, рансомварь требует отправки денег на биткойн-кошелек создателей, заказчику-распространителю они обещают высылать 70% от собранной суммы.

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



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

Древности


«Fish#6»

Резидентный опасный вирус, зашифрован, стандартно поражает COM- и EXE-файлы при их выполнении и закрытии. У заражаемых файлов увеличивает на 100 значение года последней модификации файла.

Поддерживает практически все функции «стелс»-вируса (см. описание вируса «V-4096»). Шифрует свое тело не только в файлах, но и в своей TSR-копии(при входе в вирус по цепочке int 21h вирус расшифровывает себя, при выходе – зашифровывает).

Начиная с 1991 г. «завешивает» систему, предварительно сообщив «FISH VIRUS #6 — EACH DIFF — BONN 2/90». Помимо этой содержит строки «COD», «SHARK», «CARP», «BASS», «TROUT», «MUSKYZ», «SOLE», «PILE», «MACKEREL», «FISH», «TUNA», «FISH FI». Перехватывает int 13 и int 21h.

Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 67.

Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331094/


Метки:  

[Перевод] Сокращаем использование Redux кода с помощью React Apollo

Пятница, 16 Июня 2017 г. 23:40 + в цитатник

Всем привет! Хочу поделиться своим переводом интересной статьи Reducing our Redux code with React Apollo автора Peggy Rayzis. Статья о том, как автор и её команда внедряли технологию GraphQL в их проект. Перевод публикуется с разрешения автора.


Сокращаем использование Redux кода с помощью React Apollo
Переключаемся на декларативный подход в Высшей Футбольной Лиге


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


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


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


Получение данных с помощью Redux


Давайте взглянем на простой компонент Article:


Ссылка на gist


import React from 'react';
import { View, Text } from 'react-native';

export default ({ title, body }) => (
  
    {title}
    {body}
  
);

Предположим, мы хотим отрендерить

в подключённом представлении, который получает ID матча в качестве props. Если бы мы выполняли это без GraphQL клиента, наш процесс получения данных, необходимых для рендеринга
мог бы быть таким:


  1. Когда монтируется, вызываем action creator для получения данных матча по ID. Action creator диспатчит action, чтобы сообщить Redux о начале процесса получения данных.
  2. Мы достигли точки назначения и возвращаемся с данными назад. Мы нормализуем данные в удобную нам структуру.
  3. После того, как данные нормализованы, мы диспатчим ещё один action, чтобы сообщить Redux о завершении процесса получения данных.
  4. Redux обрабатывает action в нашем reducer и обновляет state приложения.
  5. получает все необходимые данные матча через props и отфильтровывает их для рендеринга статьи.

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

! Без клиента GraphQL наш код становится намного более императивным, поскольку нам приходится концентрироваться на том, как мы получаем данные. Но что, если мы не хотим передавать все данные матча для простого рендеринга
? Вы могли бы построить другой endpoint и создать отдельный набор action creators для получения от него данных, но такой вариант очень легко может стать неподдерживаемым.


Давайте сравним, как бы мы могли сделать то же самое с помощью GraphQL:


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

query Article($id: Float!) {
  match(id: $id) {
    article {
      title
      body
    }
  }
}

… и это всё! Как только клиент получает данные, он передаёт их в props, которые могут быть далее переданы в

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


В этом вся прелесть делегирования получения данных GraphQL клиенту, будь то Relay или Apollo. Когда вы начнёте "думать в концепциях GraphQL", вы станете заботиться только о том, в каких props нуждается компонент для рендеринга, вместо того, чтобы беспокоиться о том, как получить эти данные.


В какой то момент вам придётся подумать об этом "как", но это уже забота серверной части, и, соответственно, сложность для front-end резко снижается. Если вы новичок в серверной архитектуре GraphQL, то попробуйте graphql-tools, библиотеку Apollo, которая поможет вам более модульно структурировать вашу схему. Для краткости мы сегодня остановимся только на front-end части.


И хотя этот пост о том, как сократить использование вашего Redux кода, вы не избавитесь от него полностью! Apollo использует Redux под капотом, поэтому вы всё ещё сможете извлекать выгоду из иммутабельности и все клёвые возможности Redux Dev Tools, типа time-travel debugging, так же будут работать. Во время конфигурирования вы можете подключить Apollo к существующему store в Redux, чтобы поддерживать единый "источник правды". Как только ваш store сконфигурирован, вы передаёте его в компонент, который оборачивает всё ваше приложение. Звучит знакомо? Этот компонент является полной заменой вашего существующего из Redux, за исключением того, что вам потребуется передать ему экземпляр ApolloClient через свойство client.


Прежде, чем мы начнём резать наш Redux код, я бы хотела назвать одну из лучших фукнциональных особенностей GraphQL: поэтапная настройка (incremental adoption). Вам не обязательно совершать рефакторинг всего приложения сразу. После интеграции Apollo с вашим существующим Redux store, вы можете переключаться с ваших reducers постепенно. То же самое применимо и к серверной части — если вы работаете над большим масштабным приложением, вы можете использовать GraphQL бок о бок с вашим текущим REST API, до того момента, пока вы не будете готовы для полного перехода. Справедливое предупреждение: как только вы попробуете GraphQL, вы можете влюбиться в эту технологию и захотить переделать всё ваше приложение.


Наши требования


Перед переходом от Redux к Apollo, мы тщательно подумали о том, отвечает ли Apollo нашим потребностям. Вот на что мы обратили внимание перед тем, как принять решение:


  • Агрегирование данных из множественных источников: Матч состоит из данных, получаемых из 4-х различных источников: контент — из нашего REST API, статистика — из нашей MySQL базы данных, медиа-данные — из нашего video API и социальные данные — из нашего Redis хранилища. Первоначально, мы использовали серверный плагин для сбора всех данных в один объект матча перед отправкой на клиент. Надо сказать, он функционирует почти также, как GraphQL! Когда мы поняли это, то стало очевидным, что GraphQL станет идеальным кандидатом для нашего приложения.
  • Оперативные обновления, близкие к реальному времени: Во время матча в прямом эфире мы обычно получаем обновления каждую минуту. До Apollo мы обрабатывали обновления с помощью сокетов и диспатчили их в наш reducer матча. Это не было самым ужасным решением, но также и не было самым элегантным, поскольку мы отправляли весь объект матча, чтобы избежать сложных последовательностей. С Apollo же мы запросто можем кастомизировать интервал поллинга (polling) для каждого компонента в зависимости от статуса игры.
  • Простая пагинация: Поскольку мы создавали страницу расписания с бесконечной прокруткой списка матчей, то нам нужна была соответствующая обработка подобного рода пагинации без лишней головной боли. Разумеется, мы могли бы создать отдельный собственный reducer. Но зачем писать его самим, когда в Apollo есть функция fetchMore, которая проделывает за нас всю тяжёлую работу?

Надо сказать, что Apollo удовлетворял не только всем нашим текущим требованиям, он также охватывал и некоторые наши будущие потребности, особенно учитывая то, что в наш roadmap включена расширенная персонализация. И хотя наш сервер в настоящее время доступен "только для чтения", нам в будущем может потребоваться ввести мутации (mutations) для сохранения пользователями их любимых команд. На случай, если мы решим добавить комментирование в режиме реального времени или взаимодействия с фанатами, которые не могут быть решены с помощью поллинга (polling), то в Apollo есть поддержка подписок (subscriptions).


От Redux к Apollo


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


Что мы удалили


  • reducers матчей (~300 строчек кода)
  • action creators & epics, отвечающие за получение данных (~800 строчек кода)
  • action creators и бизнес логику, отвечающие за группировку и получение обновлений прямого эфира матчей через сокет (~750 строчек кода)
  • actions creators & epics, отвечающие за local storage (~1000 строчек кода). На самом деле, не совсем справедливо включать в общий список этот пункт, так как offline поддержка пока что отложена в нашем проекте, но если мы захотим добавить её снова, то это вполне достижимо с помощью кастомизации функции fetchPolicy из Apollo и использования redux-persist в reducer.
  • Контейнерные компоненты Redux, которые отделяли логику Redux от презентационных компонентов (~1000 строчек кода)
  • Тесты, связанные со всем вышеперечисленным (~1000 строчек кода)

connect() -> graphql()


Если вы умеете пользоваться connect, тогда компонент высшего порядка graphql из Apollo вам покажется очень знакомым! Точно так же, как connect возвращает функцию, которая принимает компонент и подключает его к вашему Redux store, также и graphql возвращает функцию, которая принимает компонент и "подключает" его к клиенту Apollo. Давайте посмотрим на это в действии!


Ссылка на gist


import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import { MatchSummary, NoDataSummary } from '@mls-digital/react-components';
import MatchSummaryQuery from './match-summary.graphql';

// here we're using the graphql HOC as a decorator, but you can use it as a function too!
@graphql(MatchSummaryQuery, {
  options: ({ id, season, shouldPoll }) => {
    return {
      variables: {
        id,
        season,
      },
      pollInterval: shouldPoll ? 1000 * 60 : undefined,
    };
  };
})
class MatchSummaryContainer extends Component {
  render() {
    const { data: { loading, match } } = this.props;

    if (loading && !match) {
      return ;
    }

    return ;
  }
}

export default MatchSummaryContainer;

Первый аргумент, переданный в graphql это MatchSummaryQuery. Это данные, которые мы хотим получить от сервера. Мы используем загрузчик Webpack для парсинга нашего запроса в GraphQL AST, но если вы не используете Webpack, то вам нужно обернуть ваш запрос в шаблонные строки (template string) и передать его в функцию gql, экспортированную из Apollo. Вот пример запроса на получение данных, необходимых для нашего компонента:


Ссылка на gist


query MatchSummary($id: String!, $season: String) {
  match(id: $id) {
    stats {
      scores {
        home {
          score
          isWinner: is_winner
        }
        away {
          score
          isWinner: is_winner
        }
      }
    }
    home {
      id: opta_id
      record(season: $season)
    }
    away {
      id: opta_id
      record(season: $season)
    }
  }
}

Отлично, у нас есть запрос! Чтобы корректно его выполнить, нам нужно передать в него две переменные $id и $season. Но откуда мы возьмём эти переменные? Вот здесь то и вступает в игру второй аргумент функции graphql, представленный в виде объекта конфигурации.


Этот объект имеет несколько свойств, которые вы может указать для настройки поведения компонента высшего порядка (HOC). Одно из самых важных свойств — это options, принимающее функцию, которая получает props вашего контейнера. Эта функция возвращает объект со свойствами типа variables, что позволяет вам передавать ваши переменные в запрос, и pollInterval, который позволяет настраивать поведение поллинга (polling) у компонента. Обратите внимание, как мы используем props нашего контейнера для передачи id и season в наш MatchSummaryQuery. Если эта функция становится слишком длинной, чтобы писать её прямо в декораторе, то мы разбиваем её на отдельную функцию под названием mapPropsToOptions.


mapStateToProps() -> mapResultsToProps()


Наверняка вы использовали функцию mapStateToProps в ваших Redux контейнерах, передавая эту функцию в connect для передачи данных из state приложения в props данного контейнера. Apollo позволяет вам определять похожую функцию. Помните конфигурационный объект, который ранее мы передавали в функцию graphql? У этого объекта есть ещё одно свойство — props, которое принимает функцию, получающую на вход props и обрабатывающую их перед передачей в контейнер. Вы, конечно, можете определить её прямо в graphql, но нам нравится определять её как отдельную функцию mapResultsToProps.


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


Ссылка на gist


import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import { MatchSummary, NoDataSummary } from '@mls-digital/react-components';
import MatchSummaryQuery from './match-summary.graphql';

const mapResultsToProps = ({ data }) => {
  if (!data.match)
    return {
      loading: data.loading,
    };

  const { stats, home, away } = data.match;

  return {
    loading: data.loading,
    home: {
      ...home,
      results: stats.scores.home,
    },
    away: {
      ...away,
      results: stats.scores.away,
    },
  };
};

const mapPropsToOptions = ({ id, season, shouldPoll }) => {
  return {
    variables: {
      id,
      season,
    },
    pollInterval: shouldPoll ? 1000 * 60 : undefined,
  };
};

@graphql(MatchSummaryQuery, {
  props: mapResultsToProps,
  options: mapPropsToOptions,
})
class MatchSummaryContainer extends Component {
  render() {
    const { loading, ...matchSummaryProps } = this.props;

    if (loading && !matchSummaryProps.home) {
      return ;
    }

    return ;
  }
}

export default MatchSummaryContainer;

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


compose()


Compose это функция, использующаяся не только в Redux, но я всё же хочу обратить ваше внимание, что Apollo содержит её. Она очень удобна, если вы хотите скомпоновать несколько graphql функций для использования в одном контейнере. В ней вы даже можете использвать функцию connect из Redux вместе с graphql! Вот как мы используем compose для отображения различных состояний матча:


Ссылка на gist


import React, { Component } from 'react';
import { compose, graphql } from 'react-apollo';
import { NoDataExtension } from '@mls-digital/react-components';
import PostGameExtension from './post-game';
import PreGameExtension from './pre-game';
import PostGameQuery from './post-game.graphql';
import PreGameQuery from './pre-game.graphql';

@compose(
  graphql(PreGameQuery, {
    skip: ({ gameStatus }) => gameStatus !== 'pre',
    props: ({ data }) => ({
      preGameLoading: data.loading,
      preGameProps: data.match,
    }),
  }),
  graphql(PostGameQuery, {
    skip: ({ gameStatus }) => gameStatus !== 'post',
    props: ({ data }) => ({
      postGameLoading: data.loading,
      postGameProps: data.match,
    }),
  }),
)
export default class MatchExtensionContainer extends Component {
  render() {
    const {
      preGameLoading,
      postGameLoading,
      gameStatus,
      preGameProps,
      postGameProps,
      ...rest
    } = this.props;

    if (preGameLoading || postGameLoading)
      return ;

    return gameStatus === 'post'
      ? ;
      : ;
  }
}

compose отлично помогает, когда ваш контейнер содержит множественные состояния. Но что, если вам нужно выполнять отдельный запрос только в зависимости от его состояния? Здесь нам поможет skip, который вы можете увидеть в конфигурационном объекте выше. Свойство skip принимает функцию, которая получает props и позволяет вам пропустить выполнение запроса, если он не соответствует необходимым критериям.


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




Я надеюсь, что опыт перехода Высшей Футбольной Лиги на Apollo поможет вам! Как и в случае с любыми решениями относительно различных библиотек, лучшее решение по контролю над получением данных в вашем приложении будет зависеть от конкретных требований вашего проекта. Если у вас есть какие-либо вопросы касательно нашего опыта, пожалуйста, оставляйте комментарии здесь или стучитесь ко мне в Twitter!


Спасибо за прочтение!

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

https://habrahabr.ru/post/331088/


Метки:  

Неглубокое погружение или восстановление данных с жесткого диска после затопления офиса

Пятница, 16 Июня 2017 г. 23:30 + в цитатник
Офис небольшой торговой компании был размещен на цокольном этаже жилого дома, построенного в семидесятые годы прошлого века. За время своего существования дом изрядно обветшал, но продолжал эксплуатироваться с незначительными косметическими ремонтами. Компания хоть и сетовала на неподобающее состояние труб и сантехнического оборудования, но не торопилась за свой счет заниматься решением этих проблем, полагая, что грядущий капитальный ремонт уменьшит их потенциальные издержки. Но, как показали дальнейшие события, не стоит полагаться на голый экономический расчет без учета рисков.

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

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


рис. 1

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

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


рис. 2

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


рис. 3

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


рис. 4

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

Исходя из результатов первичного визуального осмотра очевидно, что печатная плата «контроллера» данного накопителя деградировала в результате электрохимической коррозии и не может быть использована. В данном семействе (F1_3D) ПЗУ располагается в MCU Marvell 88i8826E. Учитывая, что неизвестно «жив» ли данный MCU, а также сложность пайки BGA микросхем, варианты с получением оригинального содержимого ПЗУ исключим.

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


рис. 5

Проведя анализ модуля FSI, мы установили версию микропрограммы 1AG08ugB.d35. Оценивая содержимое модулей 73_MOVLY, 19_BOVLY, обнаруживаем, что они целиком заполнены нулями. Данное наблюдение позволяет сделать вывод, что для восстановления данных можно использовать практически любое ПЗУ с совместимым идентификатором платформы, которое не использует модули 19 и 73 для хранения исполняемого кода.

Используем плату донора, в которую запишем ближайшее совместимое ПЗУ Ближайшая версия в наличии оказалась 1AA18HuM.d35.

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


рис. 6

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


рис. 7

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

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


рис. 8

Начинаем чтение в UDMA режиме с таймаутом ожидания готовности 300 миллисекунд, с прерыванием операции при обнаружении нестабильности, подачей программного сброса и прыжком на 100 000 секторов вперед.

Обнаруживаются UNC ошибки на секторах 6 24х ххх и 89 36х ххх. Остальные участки читаются без затруднений.

Отправляем накопитель в спящий режим и на копии производим анализ нулевого сектора.


рис. 9

На рис. 9 видно, что присутствуют записи о двух разделах. Первый раздел начинается с сектора 0x0000003F (63) и его длина 0x061A7927 (102 398 247) секторов. Второй раздел начинается с сектора 0x061A7966 (102 398 310), и его длина составляет 0x446AF55B (1 147 860 315) секторов. По смещению 0x1BE находится значение 0x80 – признак активности раздела (раздел является загрузочным). Согласно локализации дефектов очевидно, что они приходятся на первый раздел.

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


рис. 10

Из параметров файловой системы отметим: сектор 512 байт, 8 секторов в кластере, размер раздела в загрузочном секторе соответствует размеру, описанному в таблице разделов.
Первый сектор MFT рассчитывается по формуле: X*Y+Z, где X номер первого кластера расположения MFT, Y – количество секторов в кластере, Z – смещение до начала раздела.

0x00000000000C0000*0x08+0x3F=0x000000000060003F (6 291 519)

Так как по этому смещению у нас недочитанный фрагмент, то рассчитываем позицию MFT Mirror

0x000000000061A792*0x08+0x3F=0x00000000030D3CCF (51 199 183)

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


рис. 11

Производим чтение частично непрочитанного первого фрагмента MFT. Операция проходит без затруднений.

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


рис. 12

Первый является служебной структурой NTFS, которая некритична.

Второй является файлом виртуальной памяти в Windows и тоже не представляет ценности для Заказчика.

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

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

Предыдущая публикация: Всегда ли надежно шифрование или восстановление данных с внешнего жесткого диска Prestigio Data Safe II
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331090/


Вебинар Крикета Ли и Пола Викси о методах защиты сети с использованием DNS RPZ

Пятница, 16 Июня 2017 г. 23:09 + в цитатник
20-го июня 2017 в 20:30 по московскому времени, Крикет Ли (Infoblox Chief DNS Architect, соавтор книг о DNS и Bind) и Пол Викси (CEO of Farsight Security, один из пионеров современного интернета и изобретатель RPZ) проведут совместный вебинар, на котором расскажут:
  • о последних атаках Wannacry, Jeff и других кибер-угрозах;
  • как защититься от известных и новых угроз с использованием DNS RPZ;
  • как интегрировать DNS RPZ в существующие системы защиты.


Несколько слов о вебинаре от Крикета Ли:



Зарегистрироваться можно по этой ссылке.
Для тех, кто не знаком с RPZ, вот краткое описание.
PS По мере возможности я тут выложу запись вебинара.
Был ли интересен/полезен данный вебинар?

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

Используете ли Вы RPZ или политики (MS DNS 2016) для ограничения доступа к вредоносным/нежелательным сайтам?

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

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

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

https://habrahabr.ru/post/331092/


Метки:  

Без заголовка

Пятница, 16 Июня 2017 г. 21:21 + в цитатник

Метки:  

Почему подключаться под атакой к сервису нейтрализации DDoS уже слишком поздно

Пятница, 16 Июня 2017 г. 16:53 + в цитатник


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

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

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

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

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


Каковы плюсы подключения к сети фильтрации трафика до атаки?


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

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

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

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

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

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

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


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

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

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

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

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

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

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

К сетям фильтрации трафика существует два наиболее распространенных способа подключения — с использованием DNS либо BGP. Рассмотрим два этих сценария по отдельности.

DNS


Предположим, что атака ведётся только по доменному имени.
Типичный сценарий подключения сайта под атакой по DNS выглядит следующим образом: владелец сетевого ресурса, представленного доменным именем, в A-записи DNS которого указан текущий IP-адрес атакуемого веб-сервера, обращается к нам за помощью. После соблюдения всех формальностей Qrator Labs выделяет клиенту специальный IP-адрес, на который он заменяет свой текущий адрес.

Как правило, в этот момент приходится учитывать возможный высокий TTL на изменение записи DNS, который может составлять от нескольких часов до суток максимум (предел по RFC: 2147483647 секунд) — в течение этого времени старая А-запись будет существовать в кэше DNS-рекурсоров. Поэтому если вы заранее осознаете, что атака вероятна, необходимо иметь низкий TTL для A-записи DNS.

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

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

BGP


В случае с подключением по протоколу BGP всё выглядит несколько иначе.
Если атакуемый сервис обладает собственными блоками адресов (префиксами) и хочет перевести всю инфраструктуру под защиту целиком, анонсируя собственные префиксы через поставщика услуг нейтрализации DDoS — как выглядит данный процесс?

Автономная система под атакой добавляется в наш AS-SET, для того чтобы иметь возможность анонсировать собственные префиксы, после чего начинаются пресловутые сутки (24 часа) на получение всеми нашими аплинками данной информации и обновления префикс-листов. Естественно, в экстренном случае мы стараемся пойти навстречу такому клиенту, форсируя данный процесс, но это возможно не в каждом случае и делается вручную. В свете вышесказанного, время — ключевой и основной стресс-фактор, ведь защитить ресурс требуется безотлагательно, «обезболить мгновенно».

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

Лирическое отступление: ваш поставщик услуг связности покупает IP-транзит, как правило, у больших и надежных операторов связи, не ниже региональных Tier-1 операторов. Они фильтруют префиксы, поступающие к ним от клиентов, на основании некоторого списка (prefix-list), который они берут из открытых баз данных (RIPE, RADB и других). Штатно одни поставщики IP-транзита сервиса по защите от DDoS обновляют эти фильтры циклично раз в сутки, другие делают это только по запросу. У грамотного поставщика услуг нейтрализации DDoS точки присутствия расположены по всему миру, мгновенно не накатишь.

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

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


Постскриптум.
Коллеги, доводим до вашего сведения следующую важную новость: www.ietf.org/mail-archive/web/idr/current/msg18258.html

Инициатива о внедрении механизма автоматической защиты от возникновения «утечек маршрутов» (route leaks), непосредственное участие в создании которой принимали инженеры Qrator Labs, успешно прошла этап «принятия» (adoption call) и перешла в рабочую группу по Interdomain Routing (IDR).

Следующий этап — доработка документа в рамках IDR и, в дальнейшем, проверка руководящей группой (IESG www.ietf.org/iesg). В случае успешного прохождения этих этапов черновик станет новым сетевым стандартом RFC (https://www.ietf.org/rfc.html).

Авторы: Александр Азимов, Евгений Богомазов, Рэнди Буш (Randy Bush, Internet Initiative Japan), Котикалапуди Шрирам (Kotikalapudi Sriram, US NIST) и Кейур Пател (Keyur Patel, Arrcus Inc.) осознают, что в индустрии есть острый спрос на предлагаемые изменения. Однако спешка в данном процессе также неприемлема, и авторы приложат максимум усилий, чтобы сделать предлагаемый стандарт удобным как для транснациональных операторов, так и небольших домашних сетей.

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

Мы также хотим донести до сведения заинтересованных инженеров, что у вас всё ещё есть возможность выразить собственные пожелания к внесению дополнений и уточнений через рассылку IETF (draft-ymbk-idr-bgp-open-policy@ietf.org) или на через сайт инициатив Qrator Labs.

Важно также отметить, что к моменту принятия финального решения у стандарта должно быть две рабочих реализации. Одна из них уже доступна — это наша разработка на базе раутингового демона Bird, доступная на Github: github.com/QratorLabs/bird. Мы приглашаем вендоров и open source сообщество присоединиться к данному процессу.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331080/


“Коллеги, всё упало!” Что может пойти не так на сайте и что с этим делать? Часть 1

Пятница, 16 Июня 2017 г. 16:45 + в цитатник
Одна из причин, по которой пользователи перед покупкой тура предпочитают поговорить с менеджером — страх, что на сайте что-то пойдёт не так. Такого тура на самом деле нет, оплата не пройдёт и множество других фантазий. Чаще всего клиенты просто не знают, как всё устроено. И это порождает негатив.

Любая ошибка на сайте, реальная она или мнимая, — тревожный звоночек. Особенно для нового клиента, который хочет убедиться, что Травелата — не лохотрон. В этой статье я разберу технические моменты, возможные баги на сайте и не всегда очевидные особенности интерфейса сайта Travelata.ru.

Пройдёмся по воронке.



Главная страница



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

image

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



Поисковая выдача (SERP)



Турист запустил процесс поиска. Подгружается выдача отелей.

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

image

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

Ситуация 1: “Поиск тупит, отели грузятся медленно”

Бывает, что запрос редкий, и в кеше ничего нет (например, запрос из Москвы на Ямайку на Новый год, когда за окном ещё май), или ТО долго отвечает из-за нагрузок на свои сервера. Со стороны юзера получится очень долгое ожидание выдачи. Чтобы не потерять клиента, мы применяем функционал двойного тайм-аута для результатов выдачи: в первые 30 секунд показываем всё, что успело прийти. Ещё через 30 секунд — добавляем ассортимент в выдачу. Если ничего не пришло ни в один из лимитов — показываем, что туров нет, и предлагаем сменить даты или направление.

Для клиента на этом этапе наиболее важно получить максимально релевантную подборку предложений. И если туров очень много, подтянутся не все. Для каждого ТО у нас есть фиксированное количество туров, которые мы можем забрать, чтобы при этом не перегружать их сервера запросами. При этом туроператоры отправляют нам данные в количестве туров, а не отелей. Чтобы выборка не была пустой на редких направлениях, отдел продукта старается “расширять выдачу”, подключая новых ТО, чтобы по каждому запросу было как минимум 10-20 отелей с турами.


Как получить максимально релевантную выдачу?

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

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

image

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

image

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

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

image

Ситуация 2: “Не нашёл отель”

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

Как быстро найти отель?

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

image

Ситуация 3: “Не нашел предложения от конкретного ТО”

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

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


Ситуация 4: “Нет туров на курорт”

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

Если курорт непопулярен у туристов или инвентарь по нему скуден, мы его добавляем к более крупному “виртуальному” курорту. Например, Каликратия с одним-единственным отелем в продаже присоединили к выдаче по полуострову Халкидики. Таким образом, при запросе более известного курорта, можно все равно увидеть и купить этот отель.

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


Ситуация 5: “Тур не актуален”

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

Ситуация 6: “Не могу найти тур на компанию из 5 человек и 3 детей разного возраста”

Такую комбинацию сложно подобрать на сайте самостоятельно. У ТО нет продукта под такой состав.

Что делать?

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


Ситуация 7: “У конкурентов цены ниже!”

Субъективное мнение, которое могло сложиться по ряду факторов. Открыл сортировку по популярности вместо сортировки по цене, установил фильтр на 5 звёзд и забыл про него… Наши цены примерно на одном уровне с конкурентами. Объективно сравнить цены можно только по одному конкретному туру — то есть если совпадают даты вылета, отель, количество ночей, тип питания, тип номера и туроператор. И обязательно “провалиться” до чекаута, чтобы увидеть финальную цену. Некоторые наши конкуренты специально занижают цены на серпе. А многие туристы готовы уйти к ним, даже если тур у него будет на 200 рублей дешевле.


Ситуация 8: “Сайт не работает!”

Трафик на сайт размазывается в течение дня с 10 утра до 7 вечера, спайки по посещениям выявить нельзя. Почтовую рассылку мы тоже отправляем порциями за 3-4 часа. Поэтому в принципе исключаем возможность перенагрузки на сайт. Но бывает, какой-нибудь сервер на нашей стороне не справляется. У части клиентов появляется 504 ошибка. Программисты замечают это моментально. И отключают сервер, перераспределяя нагрузку на работающие сервера. Обычно сайт лежит не более 5, изредка до 15 минут. Но это скорее исключение, которое может случиться с кем-угодно.

image

Это ещё не все баги. Вторая часть уже завтра :)
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331070/


Направо пойдешь — стажировку найдешь, налево пойдешь — в стартап попадешь

Пятница, 16 Июня 2017 г. 16:10 + в цитатник
Мир заиграл яркими красками, улыбка до ушей, ноги ватные, а вокруг развеяно счастье. Это первый признак того, что вы получили диплом! Если у вас еще нет работы, остается два варианта: пройти стажировку в крупной компании (а лучше в Big 4) и стать топовым консультантом или запустить стартап и, может быть, обедать 4 раза в день. А теперь поподробнее о плюсах и минусах каждого пути:



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



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

  1. На позиции стажеров большая конкуренция — миллионы студентов выпускаются каждый год, и каждый хочет поработать в хорошей компании, получить интересный опыт и стать более конкурентоспособным.
  2. Это классика жанра. Вас как бы погружают в инкубатор и по чуть-чуть поливают водичкой с ценными знаниями, боясь затопить мозг кучей информации. Чтобы делать что-то сразу в продакшн — придется подождать.
  3. Никто не даст 100% гарантий, что после стажировки вы получите оффер. Есть вариант, что вы вложите массу усилий и разочаруетесь, потому что кто-то будет чуть лучше вас. И это обидно!
  4. У вас связаны руки. Если у вас появились реальные идеи по улучшению бизнес-процессов в компании, никто вам так сразу ничего сделать не даст. Вы — стажер. Вы можете поделиться идеей, вас выслушают, возможно идею даже примут и применят. Но это не точно.



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

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



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

  1. Вы всегда можете собрать команду и создать что-то свое. Здесь вам никто не помешает и не скажет, что вы не подходите, кроме потребителей, конечно. Вы будете работать в команде друзей, а если и нет – то они точно станут друзьями. Иначе проект рухнет.
  2. Вы работаете в удовольствие: сами распоряжаетесь временем, расставляете приоритеты, что нужно внедрить, где улучшить и решаете в какой день поспать подольше. Можно экспериментировать и всё делать самим. Конечно, ответственность за все это тоже несете вы и ваша команда.
  3. Никого лучше вас не будет потому что вы все – дрим тим! :)
  4. Это необычный опыт. Работодатели ценят таких сотрудников. Вы уже принимали стратегические решения, организовывали работу проектной группы, вели переговоры, показывали презентации и заключали контракты. Следовательно, вы уже можете самостоятельно управлять как минимум средним проектом – круто!

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

Проголосовало 10 человек. Воздержавшихся нет.

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

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

https://habrahabr.ru/post/331076/


Метки:  

[Перевод] Туториал по AsyncDisplayKit 2.0 (Texture): автоматическая компоновка

Пятница, 16 Июня 2017 г. 16:02 + в цитатник

Метки:  

[Перевод] Edge computing заменит Cloud computing?

Пятница, 16 Июня 2017 г. 14:58 + в цитатник

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

Каждая новая технология приходит на смену старой. Иногда, как и в случае с облаком, проводится ребрендинг старых технологий, чтобы сделать их более привлекательными для потребителей и, тем самым, создать иллюзию нового продукта. Облачные вычисления ранее существовали в той или иной форме. На одном из этапов они назывались «on demand computing» (компьютерные ресурсы по требованию), а затем преобразовались в «application service provider» (ASP).

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

Пророчество Левина



Так почему же люди думают, что edge computing победит облако? Это утверждение было заявлено во многих статьях. Например, Клинт Бултон в марте этого года пишет об этом в статье «edge computing заменит облако». Он ссылается на венчурного капиталиста Эндрю Левина, генерального партнера Andreessen Horowitz, который считает, что больше вычислительных ресурсов будут двигаться в направлении оконечных устройств — таких, как беспилотный автомобиль и дроны, — которые составляют, по меньшей мере, часть Интернета вещей. Левин прогнозирует, что это будет означать то, что облаку пришел конец, т.к. процесс обработки данных будет двигаться назад по направлению к edge computing.

Другими словами, сейчас идет тенденция централизации вычислений в ЦОДах, в то время, как в прошлом они часто были децентрализованы или находились ближе к месту использования. Левин видит беспилотный автомобиль, как центр обработки данных: они имеют более чем 200 процессоров, способных обеспечить полную отказоустойчивость, чтобы не привести к несчастному случаю на дороге. Характер автономных транспортных средств означает, что их вычислительные мощности должны быть независимыми и для того, чтобы обеспечить безопасность нужно свести к минимуму любую связь, которую они имеют с облаком. Тем не менее, они не смогут полностью обойтись без него.



Взаимодополняющие модели



Эти два подхода могут дополнять друг друга. Часть аргументов за edge computing просто отпадает, когда речь заходит об увеличении объемов данных, которые приводят к еще более удручающей и медленной сети. Задержка – виновник. Данных становится все больше: увеличивается количество данных на одну транзакцию, «тяжелые» видео и много данных разных датчиков. Виртуальная и дополненная реальность будет играть все большую роль в его росте. При таком росте объема данных, решить проблемы задержки представляется более сложной задачей, чем это было раньше. Сейчас имеет смысл размещать данные ближе к устройствам типа беспилотного автомобиля для того, чтобы устранить задержку, но тем не менее большая часть данных всё-еще находится удаленно в облаке. Облако по-прежнему будет использоваться в качестве поставщика сервисов, таких как СМИ и развлечения. Оно также может быть использовано для резервного копирования данных и для обмена данными, исходящих от транспортного средства.

Немного отойдем от автономных транспортных средств и вернемся к более привычному бизнесу. Создание ряда небольших ЦОДов или площадок аварийного восстановления может уменьшить эффект масштаба, как следствие, увеличить затраты и сделать работу менее эффективной. Да, задержка может быть уменьшена, но в случае катастрофы последствия будут не менее плачевными; поэтому для обеспечения непрерывности бизнеса некоторые данные следует хранить и обрабатывать в другом месте – в облаке. В случае беспилотных машин, в частности, потому что они должны работать независимо от того, есть сетевое соединение или его нет, имеет смысл, чтобы определенные типы вычислений и анализа были совершены самим транспортным средством. Однако эти данные по-прежнему будут бэкапиться в облако, когда соединение доступно. Подход будет гибридным: edge и cloud computing будут взаимодополнять друг друга, а не использоваться по одиночке.

От периферии до облака



Сейджу Скария, старший директор консалтинговой фирмы TCS, предлагает несколько примеров, где edge computing может оказаться полезным. В своей статье на LinkedIn Pulse, «Edge computing vs. Облачные вычисления: за кем будущее?». Он не считает, что с облаком будет покончено.

«Edge computing не заменит облачные вычисления… на самом деле, аналитическая модель или правила могут быть созданы в облаке и затем применяться оконечными устройствами… и некоторые [из них] способны делать анализ». Затем он продолжает говорить о fog computing (туманные вычисления), которая включает в себя обработку данных от периферии до облака. Он считает, что люди не должны забывать о хранилищах данных, так как они используется для «медленных аналитических запросов и массивного хранения данных».

Edge победит облако



Несмотря на этот аргумент, аналитик компании Gartner Томас Битман считает, что «Edge computing «съест» облако». «Сегодня облачные вычисления пожирают центры обработки данных предприятий, все больше и больше нагрузок приходится на облако, а некоторые преобразовываются и перемещаются в облако… но есть еще одна тенденция, которая переместит рабочие нагрузки, данные и стоимость бизнеса далеко от облака… И тенденция перехода к edge computing еще более важная и сильная, чем когда-то была тенденция облачных вычислений.

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

Ускорение данных



Битман делает некоторые справедливые замечания, но он употребляет аргумент, который часто используется в отношении задержек и ЦОДов: они должны быть расположены близко друг к другу. Истина заключается в том, что глобальные сети всегда будут фундаментом edge computing и облачных вычислений. Во-вторых, Битману явно не попадались инструменты ускорения данных, такие, как PORTrockIT и WANrockIT. В то время как физика, безусловно, является ограничивающим и сложным фактором, который всегда будет иметь место в сетях всех видов – включая WANs, сегодня можно разместить свои центры обработки данных на расстоянии друг от друга. Задержка может быть уменьшена, и его воздействие может быть нивелировано, независимо от того, где происходит обработка данных, и независимо от того, где хранятся данные.

Поэтому, edge computing это не новое прорывное решение. Это лишь одно из решений, как и облако. Вместе эти две технологии могут поддержать друг друга. Различие между edge computing и облачными вычислениями, в том, что «edge являются методом ускорения и повышения производительности облачных вычислений для мобильных пользователей». Таким образом, аргумент, что edge computing заменит облачные вычисления является очень неубедительным. По маркетинговым соображениям, облачные вычисления могут быть переименованы, но суть останется та же.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331066/


Метки:  

Вышел Firefox 54, который наконец получил поддержку многопроцессного режима

Пятница, 16 Июня 2017 г. 14:42 + в цитатник
Команда разработчиков Firefox выпустила новую версию браузера с номером 54. Главной особенностью обновленного Firefox является поддержка многопроцессного режима обработки веб-страниц, работа над которым велась восемь лет под кодовым названием Electrolysis (E10S). Представители Mozilla называют новую версию браузера «лучшим Firefox».

/ фото Dees Chinniah CC

Первая версия мультипроцессного Firefox была представлена в августе прошлого года (версия 48). В ней работа с UI была вынесена в отдельный процесс, что делало интерфейс отзывчивым даже при высоких нагрузках на систему. В версии Firefox 54 разработчики пошли еще дальше, организовав работу в нескольких параллельных процессах: каждый со своими ресурсами RAM и CPU, управляемыми операционной системой.

Недостатком при таком подходе обычно остается высокое потребление памяти. Например, Google Chrome по умолчанию создает новый процесс для каждой вкладки и потребляет множество ресурсов. Однако, по словам главы маркетинга Firefox Райана Поллока (Ryan Pollock), в отличие от того же Chrome, Firefox не будет забирать себе всю оперативную память и замедлять работу компьютера пользователя.

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

Сравнение потребления памяти браузеров (Источник)

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

В дополнение к многопроцессорной работе, Firefox 54 также получил несколько новых WebExtension API, для разработки дополнений, совместимых с другими браузерами. В релизе значатся API для создания боковых панелей, позволяющие размещать локальные HTML-файлы внутри панели. Также была добавлена возможность подключения собственного обработчика протоколов и возможность настройки about:newtab. Помимо этого, был внедрен Privacy API для управления настройками безопасности и приватности (networkPredictionEnabled, webRTCIPHandlingPolicy и hyperlinkAuditingEnabled).

В новом браузере была активирована sandbox-изоляция, ограничивающая доступ подпроцессов Firefox к файловой системе и другим процессам. В Linux изоляция системных вызовов реализована с применением Seccomp-bpf, а также User namespace и chroot. В Windows же применяются библиотеки sandboxbroker и sandboxtarget, разработанные и используемые компанией Google. Еще среди изменений, внедренных в Firefox 54, числится возможность создания и сохранения собственных устройств в Responsive Design Mode для тестирования сайтов (можно задать разрешение экрана, пропускную способность сети и др.).

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

И наконец, с выходом Firefox 54, Mozilla завершает процессы по закрытию канала с Aurora-версиями браузера. Теперь организация намерена использовать принцип поэтапной доставки обновлений для Release-канала, где новые функции, такие как Electrolysis, постепенно добавляются в браузеры небольшого числа пользователей. Если нововведение вызывает всплески отказов, или телеметрические данные указывают на возникающие сложности, Mozilla останавливает развертку обновления и дорабатывает решение.

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

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

P.S. О чем еще мы пишем в нашем блоге:

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

https://habrahabr.ru/post/330576/


Метки:  

[Из песочницы] RESTful API: мы всё делаем неправильно

Пятница, 16 Июня 2017 г. 14:34 + в цитатник
Привет, Хабр! Прежде чем я начну, стоит немного рассказать о себе. Я не так давно занимаюсь серьезной разработкой (всего года три) и, как мне кажется, именно отсутствие многолетнего опыта часто позволяет мне смотреть на многие традиции и устоявшиеся способы выполнения стандартных задач с оригинальной точки зрения. Моя специальность — бэкенд сайтов и мобильных приложений (основной язык разработки — python3, любимый фреймворк — Django).

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

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

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

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

За единственное число:


За множественное число:


Как вы можете видеть, аргументы довольно противоречивы, и к каждому можно придумать сотню контраргументов. Добавлю, что ссылаться на чью-то реализацию я вообще считаю достаточно бессмысленным занятием: да, Atlassian и Twitter — гиганты IT, но ведь все могут ошибаться, особенно учитывая, что делают все по-разному.

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

REST uses a resource identifier to identify the particular resource involved in an interaction between components. REST connectors provide a generic interface for accessing and manipulating the value set of a resource, regardless of how the membership function is defined or the type of software that is handling the request. The naming authority that assigned the resource identifier, making it possible to reference the resource, is responsible for maintaining the semantic validity of the mapping over time (i.e., ensuring that the membership function does not change).

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

In regards to «untold hours wasted in debate», that is close to the goal of my dissertation — to introduce a way of thinking about software architecture that promotes honest debate about the properties that are desired and actual thought applied to the constraints chosen to achieve them (and their resulting trade-offs). It is almost never wasted, even when it is poorly informed.

...at best all you will get is a committee that has some vague notion
of what they consider to be design to write down the least common
denominator of misinformed «best practice» based upon whatever Microsoft
chose to implement in its last release. The IETF has made a habit of
that recently.

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

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

  1. В оригинальном описании REST концепция «resource identifier» описывается как уникальный идентификатор, однозначно указывающий на ресурс. Что это за идентификатор — ID, название или хэш строкового представления — не уточняется, этот вопрос оставлен на усмотрение разработчиков с единственным условием: поддержание семантической целостности архитектуры на протяжении всего существования системы.

  2. Необходимо делать архитектуру понятной для пользователя. Внутренние особенности реализации — такие, как название таблицы в БД или имя сущности в описании моделей ORM — должны отходить на второй план, а в идеале вообще не учитываться.

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

Спасибо за внимание!

Источники:

  1. Диссертация Роя Филдинга, глава 5
  2. Википедия
  3. Комментарий самого Филдинга по сходному вопросу
  4. Документация Atlassian
  5. Документация Twitter
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331064/


Метки:  

Как личная жизнь влияет на работу – этапы развития Unified Communications

Пятница, 16 Июня 2017 г. 14:27 + в цитатник
Платон Бегун, руководитель направления контактных центров CTI

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

image


I seek you

Расцвет ICQ (от англ. I seek you — «я ищу тебя») пришелся на 2000-е годы. К 2005 году в этом мессенджере было зарегистрировано 500 млн пользователей по всему миру (для сравнения статистика на сегодня – 12 млн человек).

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

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

image

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

Принцип 3 в 1

На этой волне появилась концепция унифицированных коммуникаций. Самое простое определение, которое я встречал, звучит так: «Unified Communications (UC) – это консолидация различных средств связи и видов сообщений (телефония, электронная почта, службы обмена сообщениями, видео-конференц-связь и др.) в универсальном коммуникаторе с функцией контроля присутствия».

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

Преимущества корпоративной системы унифицированных коммуникаций

Можно выделить ключевые особенности унифицированных коммуникаций:

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

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

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

Реальная экономия

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

image
Выгода достигается за счет:

— публикации сотрудниками своих статусов доступности и предпочтительных каналов связи с ними в данный момент – это 10% рабочего времени в среднем на каждого сотрудника;

— возможности собрать совещание с помощью web и видеоконференций между сотрудниками, которые находятся в разных офисах/городах, при этом есть инструменты для совместной работы над документами, возможно обучение территориально распределенных сотрудников – экономится до 20%-40% времени;

— проведения online-презентаций для клиентов с помощью сервиса web-конференций – 20%-40% рабочего времени;

— оперативного доступа к корпоративным коммуникационным сервисам со смартфонов сотрудников – повышение производительности на 30%-50%.

А повышение лояльности сотрудников к компании за счет получения комфортных условий работы – бесценно!

Это экономия на паразитных потерях времени, связанных с попыткой соединиться с человеком, который, например, сейчас в отпуске и не отвечает, или на совещании, а ему один-второй-третий раз позвонили. Зачем?

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

Корпоративная социальная сеть – следующий этап развития унифицированных коммуникаций

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

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

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

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

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

image

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

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

Развивайся, либо умрешь

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

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

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

Вывод простой

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

https://habrahabr.ru/post/330992/



Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1010 1009 [1008] 1007 1006 ..
.. 1 Календарь