...

суббота, 18 марта 2017 г.

[Из песочницы] Как создать музыку для видеоигры

[Публикую собственный перевод статьи за авторством TitanSlayer, автора музыки для видео игр, фильмов и ТВ]

Мне всегда нравились видеоигры. С самого детства я был очарован, загипнотизирован такими играми как Quake, Hexen, Heroes of Might & Magic.

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

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

image

Общение и Согласованность

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

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

Есть несколько простых способов придти к общему мнению:

Эталонные треки (Reference tracks) – трэки определенного исполнителя или группы которые выберет разработчик.

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

Знакомство с игровой историей (game lore) – чем больше вы знаете об игре и ее истории, тем лучше вы сможете передать главную идею игры через звуки и музыку.

Анализ сценария

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

Когда я работал над Quake 4: False Dawn, неофициальным аддоном от Little Gears, для меня было очень важно добавить что то свежее и новое к наследию Quake. Я пришел к мнению, что для того чтобы сделать это, мне нужно начать полностью игнорировать заголовок Quake в названии. И думать об этом проекте не как о еще одной части из данной серии игр, а просто как об еще одном шутере.

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

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

Организация и производство

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

Давайте взглянем на них:

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

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

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

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

image

Мегагорны (The Megahorns), зеленые, это Главные блоки. Партия арпеджио на синтезаторе (Arp Synth), основная партия синтезатора (Lead Synth), Фактура (Texture), все синего цвета, это наши исследовательские блоки. Бас партия, крэши и т.д., красный цвет, это экшн блоки.

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

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

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

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

TITAN SLAYER - Project Hyperion

Он содержит в себе все те блоки, о которых я говорил выше.

Итак, как же это работает?

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

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

Приведу пример.

TITAN SLAYER - Outlander

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

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

Заключение

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

Комментарии (0)

    Let's block ads! (Why?)

    Iptables: немного о действии REDIRECT, его ограничениях и области применения


    Данная заметка повествует о действии REDIRECT в iptables, его ограничениях и области применения

    Iptables и REDIRECT


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

    Работает REDIRECT только в цепочках PREROUTING и OUTPUT таблицы nat. Таким образом, область применения сводится только к перенаправлению с одного порта на другой. Чаще всего это используется для прозрачного прокси, когда клиент из локальной сети коннектится на 80 порт, а шлюз редиректит пакеты на локальный порт прокси:
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3128
    

    Кейс


    Допустим, надо сменить порт приложения только перенаправлением при помощи iptables, не трогая настроек демона. Пусть новый порт будет 5555, а порт приложения 22. Таким образом, надо сделать редирект с порта 5555 на 22.

    REDIRECT и удаленный клиент


    Первый шаг очевиден и будет таким же, что и в примере выше:
    iptables -t nat -A PREROUTING -p tcp --dport 5555 -j REDIRECT --to-port 22
    

    Однако, правило будет работать только для внешних клиентов и только при открытом порте приложения.

    REDIRECT и локальный клиент


    Предыдущее правило для самого хоста с iptables не сработает, т.к. пакеты с localhost не попадают в таблицу nat. Чтобы кейс сработал на локальной машине — надо добавить редирект в цепочку OUTPUT таблицы nat:
    iptables -t nat -A OUTPUT -p tcp -s 127.0.0.1 --dport 5555 -j REDIRECT --to-ports 22
    

    Теперь локальный клиент тоже может подключиться по 5555 порту.

    REDIRECT и закрытый порт


    Смысл кейса в том, чтобы использовать левый порт, а порт приложения держать закрытым, но если выполнить DROP правило в INPUT цепочке по 22 порту, то 5555 тоже перестанет отвечать. Собственно, хитрость в том, чтобы открыть порт приложения в INPUT цепочке, а дропать его в mangle:
    iptables -t mangle -A PREROUTING -p tcp --dport 22 -j DROP
    

    Полный набор правил


    Редирект с сетевым и локальным доступом при закрытом порте приложения:
    iptables -t nat -A PREROUTING -p tcp --dport 5555 -j REDIRECT --to-port 22
    iptables -t nat -A OUTPUT -p tcp -s 127.0.0.1 --dport 5555 -j REDIRECT --to-ports 22
    iptables -A INPUT -p tcp --dport 5555 -j ACCEPT
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    iptables -A INPUT -i lo -j ACCEPT
    iptables -t mangle -A PREROUTING -p tcp --dport 22 -j DROP
    iptables -P INPUT DROP
    

    Комментарии (0)

      Let's block ads! (Why?)

      Рекуррентные нейронные сети | Теория

      Опрос айтишников. На «вы» или на «ты»?

      Дайджест: Технологии DPI и оборудование СОРМ

      В третьем тематическом дайджесте мы подобрали наши свежие материалы, в которых разобраны различные аспекты технологий Deep Packet Inspection и оборудования СОРМ.

      Другие выпуски дайджеста:


      / Flickr / Pascal / PD
      Что будет с интернет-провайдерами после 1 июля 2018 года
      • Немного о том, что подразумевает «пакет Яровой» на практике, сколько будет стоить выполнение всех требований, кто за это будет платить и как можно смягчить последствия.

      QoS или прибыль: Ограничение объема загружаемых данных
      • Наш краткий анализ общей ситуации с потреблением различных типов контента, обзор американских «безлимититных» тарифов и возможностей DPI.

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

      Конференция C++ Russia 2017: атмосфера чистого C++
      • Наш тематический отчет с конференции C++ Russia, которая проходила с 23 по 25 февраля 2017 года в Москве. О том, что обсуждалось и какие темы были затронуты спикерами.

      Могут ли наши решения для ИТ-инфраструктуры конкурировать с западными
      • Немного о том, что мы обсуждали вместе с коллегами на технической сессии «Сетевые технологии» на Пиринговом форуме MSK-IX 2016, который состоялся 1 декабря 2016 года в Москве.

      Профессор Гильермо Франсия о кибербезопасности национальной инфраструктуры
      • Интервью с экспертом по кибербезопасности — профессором Гильермо Франсия. Сейчас он занимает должность директора Центра обеспечения информационной безопасности Университета штата Джэксонвилл и изучает вопросы безопасности критически значимых объектов инфраструктуры (энергетические установки и системы водоснабжения).


      / Flickr / Pascal / PD
      Кто в России производит оборудование СОРМ
      • Требования закона таковы: оператор связи или интернет-провайдер, предоставляющий услуги на территории России, обязан установить оборудование СОРМ. Здесь мы рассмотрели примеры конкретных компаний-производителей, виды СОРМ и поговорили о стоимости таких систем.

      Европейская и американская реализация СОРМ
      • О самом понятии «законного перехвата» (Lawful Interception) и соответствующий решениях, разработанных по стандартам ETSI (European Telecommunications Standards Institute) и североамериканской организацией CALEA (Communications Assistance for Law Enforcement Act). Здесь мы рассмотрим цели и задачи таких систем, плюс поговорим об основных отличия от СОРМ.

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

      Место СОРМ-2 и СОРМ-3 в сети оператора связи
      • Краткий разбор схем сети со встроенным решением СОРМ. Более подробно об устройстве СОРМ-2, СОРМ-3 и системе взаимодействия с пультом управления на стороне спецслужб.

      Емкость системы хранения для СОРМ-3
      • Еще один ознакомительный материал о категориях статистической информации, сроках хранения и экономической части вопроса — расчете емкости СХД.


      / Flickr / Pascal / PD
      СКАТ DPI против Cisco SCE 8000
      • Краткий обзор технических характеристик и сравнение систем на практике. Подробно о недостатках и преимуществах СКАТ DPI.

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

      Современные аппаратные платформы для DPI
      • Здесь мы поговорили о том, какие решения предлагают производители для удовлетворения потребностей платформ DPI — разобрали требования к компонентам и проанализировали сам решения от производителей.

      Расширенная функциональность в СКАТ DPI
      • В этом материале мы рассказали о таких возможностях как фильтрация по реестру запрещенных сайтов; аналитика в режиме реального времени; распределение канала между абонентами; информирование абонентов; кэширование контента; защита от DDoS атак и предфильтр СОРМ.

      Новые возможности продукта СКАТ DPI 6.0 «Севастополь» от VAS Experts
      • Совсем недавно мы представили новую версию решения СКАТ DPI 6.0 «Севастополь». Система получила несколько исправлений, основанных на опыте разработки предыдущих версий продукта, а также обзавелась новыми функциями, о которых мы и рассказали в этом посте.

      Информация об абоненте – опыт оператора связи ГК «Спецсвязь»
      • Практический кейс применения системы СКАТ DPI, в рамках которого оператор связи ГК «Спецсвязь» (г. Челябинск) повысил качество обслуживания корпоративных заказчиков и сократил время отклика и решения задач по обслуживанию клиентов.

      P.S. Прошлый выпуск дайджеста материалов по теме Deep Packet Inspection.

      Комментарии (0)

        Let's block ads! (Why?)

        Функциональная безопасность, часть 6 из 6. Оценивание показателей функциональной безопасности и надежности

        пятница, 17 марта 2017 г.

        [Из песочницы] Собираем свой OpenShift Origin Cluster

        Security Week 11: 38 зараженных смартфонов, ФБР плачет от шифрования, Google снова подлатал Chrome

        [Из песочницы] Готовим плацдарм для react-приложения

        [Из песочницы] Пишем Java Stream API на коленке за пару минут

        [Из песочницы] NodeJS фреймворк с синтаксисом Laravel

 (и без лапши в коде)

        Glitch — новый подход к разработке приложений

        Дефекты безопасности, которые устранила команда PVS-Studio на этой неделе: выпуск N2

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

        Для тех, кто ещё не знаком с инструментом PVS-Studio


        PVS-Studio — это инструмент, который выявляет в коде многие разновидности ошибок и уязвимостей. PVS-Studio выполняет статический анализ кода и рекомендует программисту обратить внимание на участки программы, в которых с большой вероятностью содержатся ошибки. Наилучший эффект достигается тогда, когда статический анализ выполняется регулярно. Идеологически предупреждения анализатора подобны предупреждениям компилятора. Но в отличии от компиляторов, PVS-Studio выполняет более глубокий и разносторонний анализ кода. Это позволяет ему находить ошибки в том числе и в компиляторах: GCC; LLVM 1, 2, 3; Roslyn.

        Поддерживается анализ кода на языках C, C++ и C#. Анализатор работает под управлением Windows и Linux. В Windows анализатор может интегрироваться как плагин в Visual Studio.

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


        Уязвимости


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

        1. Clang. CWE-571 (Expression is Always True)

        V768 The enumeration constant 'S_MOVRELS_B64' is used as a variable of a Boolean-type. gcnhazardrecognizer.cpp 75

        namespace AMDGPU {
          enum {
            ....
            S_MOVRELS_B64 = 4043,
            ....
          };
        }
        
        static bool isSMovRel(unsigned Opcode) {
          return
            Opcode == AMDGPU::S_MOVRELS_B32 || AMDGPU::S_MOVRELS_B64 ||
            Opcode == AMDGPU::S_MOVRELD_B32 || AMDGPU::S_MOVRELD_B64;
        }
        

        Pull Request: http://ift.tt/2mzZwjf

        2. Clang. CWE-457 (Use of Uninitialized Variable)

        V573 Uninitialized variable 'BytesToDrop' was used. The variable was used to initialize itself. typerecordmapping.cpp 73

        static Error mapNameAndUniqueName(....) {
          ....
          size_t BytesLeft = IO.maxFieldLength();
          if (HasUniqueName) {
            .....
            if (BytesNeeded > BytesLeft) {
              size_t BytesToDrop = (BytesNeeded - BytesLeft);
              size_t DropN = std::min(N.size(), BytesToDrop / 2);
              size_t DropU = std::min(U.size(), BytesToDrop - DropN);
              ....
            }
          } else {
            size_t BytesNeeded = Name.size() + 1;
            StringRef N = Name;
            if (BytesNeeded > BytesLeft) {
              size_t BytesToDrop = std::min(N.size(), BytesToDrop); // <=
              N = N.drop_back(BytesToDrop);
            }
            error(IO.mapStringZ(N));
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mzMrXl

        3. Clang. CWE-570 Expression is Always False

        V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 416, 418. iteratorpastendchecker.cpp 416

        bool IteratorPastEndChecker::evalCall(const CallExpr *CE,
                                              CheckerContext &C) const {
          ....
          if (FD->getIdentifier() == II_find) {
            return evalFind(C, CE);
          } else if (FD->getIdentifier() == II_find_end) {
            return evalFindEnd(C, CE);
          } else if (FD->getIdentifier() == II_find_first_of) {
            return evalFindFirstOf(C, CE);
          } else if (FD->getIdentifier() == II_find_if) {         // <=
            return evalFindIf(C, CE);
          } else if (FD->getIdentifier() == II_find_if) {         // <=
            return evalFindIf(C, CE);
          } else if (FD->getIdentifier() == II_find_if_not) {
            return evalFindIfNot(C, CE);
          } else if (FD->getIdentifier() == II_upper_bound) {
            return evalUpperBound(C, CE);
          } else if (FD->getIdentifier() == II_lower_bound) {
            return evalLowerBound(C, CE);
          } else if (FD->getIdentifier() == II_search) {
            return evalSearch(C, CE);
          } else if (FD->getIdentifier() == II_search_n) {
            return evalSearchN(C, CE);
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mzDqOc

        4. GCC. CWE-476 (NULL Pointer Dereference)

        V595 The 'm->component' pointer was utilized before it was verified against nullptr. Check lines: 399, 407. genmodes.c 399

        static void complete_mode (struct mode_data *m)
        {
          ....
          if (   m->cl == MODE_COMPLEX_INT 
              || m->cl == MODE_COMPLEX_FLOAT)
            alignment = m->component->bytesize;        // <=
          else
            alignment = m->bytesize;
        
          m->alignment = alignment & (~alignment + 1);
        
          if (m->component)                            // <=
          {
            m->next_cont = m->component->contained;
            m->component->contained = m;
          }
        }
        

        Pull Request: http://ift.tt/2mzQxPi

        5. GCC. CWE-570 (Expression is Always False)

        V625 Consider inspecting the 'for' operator. Initial and final values of the iterator are the same. sese.c 201

        void free_sese_info (sese_info_p region)
        {
          region->params.release ();
          region->loop_nest.release ();
        
          for (rename_map_t::iterator it = region->rename_map->begin();
               it != region->rename_map->begin (); ++it) // <=
            (*it).second.release();
          ....
        }
        

        Pull Request: http://ift.tt/2mzV0l8

        6. GCC. CWE-571 (Expression is Always True)

        V501 There are identical sub-expressions '!strcmp(a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1)' to the left and to the right of the '&&' operator. dwarf2out.c 1434

        static bool dw_val_equal_p (dw_val_node *a, dw_val_node *b)
        {
          ....
          switch (a->val_class)
          {
            ....
          case dw_val_class_vms_delta:
            return (   !strcmp (a->v.val_vms_delta.lbl1,
                                b->v.val_vms_delta.lbl1)
                    && !strcmp (a->v.val_vms_delta.lbl1, 
                                b->v.val_vms_delta.lbl1));
            ....
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mzZyYp

        7. GCC. CWE-483 (Incorrect Block Delimitation)

        V640 The code's operational logic does not correspond with its formatting. The second statement will always be executed. It is possible that curly brackets are missing. asan.c 2582

        void initialize_sanitizer_builtins (void)
        {
          ....
          #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
          decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
                     BUILT_IN_NORMAL, NAME, NULL_TREE);  \
          set_call_expr_flags (decl, ATTRS);          \
          set_builtin_decl (ENUM, decl, true);
        
          #include "sanitizer.def"
        
          if ((flag_sanitize & SANITIZE_OBJECT_SIZE)
              && !builtin_decl_implicit_p (BUILT_IN_OBJECT_SIZE))
            DEF_SANITIZER_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size",
                 BT_FN_SIZE_CONST_PTR_INT,
                 ATTR_PURE_NOTHROW_LEAF_LIST)
          ....
        }
        

        Pull Request: http://ift.tt/2mzQAus

        8. FreeBSD. CWE-467: (Use of sizeof() on a Pointer Type)

        V512 A call of the 'memset' function will lead to underflow of the buffer 'plog'. nat64lsn.c 218

        struct pfloghdr {
          u_int8_t  length;
          sa_family_t  af;
          u_int8_t  action;
          u_int8_t  reason;
          char    ifname[IFNAMSIZ];
          char    ruleset[PFLOG_RULESET_NAME_SIZE];
          u_int32_t  rulenr;
          u_int32_t  subrulenr;
          uid_t    uid;
          pid_t    pid;
          uid_t    rule_uid;
          pid_t    rule_pid;
          u_int8_t  dir;
          u_int8_t  pad[3];
        };
        
        static void
        nat64lsn_log(struct pfloghdr *plog, ....)
        {
          memset(plog, 0, sizeof(plog));        // <=
          plog->length = PFLOG_REAL_HDRLEN;
          plog->af = family;
          plog->action = PF_NAT;
          plog->dir = PF_IN;
          plog->rulenr = htonl(n);
          plog->subrulenr = htonl(sn);
          plog->ruleset[0] = '\0';
          strlcpy(plog->ifname, "NAT64LSN", sizeof(plog->ifname));
          ipfw_bpf_mtap2(plog, PFLOG_HDRLEN, m);
        }
        

        Pull Request: http://ift.tt/2mzLJcH

        9. FreeBSD. CWE-570 (Expression is Always False)

        V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 102, 109. dtrace_debug.c 102

        static void
        dtrace_debug_output(void)
        {
          ....
          if (d->first < d->next) {
            char *p1 = dtrace_debug_bufr;
            count = (uintptr_t) d->next - (uintptr_t) d->first;
            for (p = d->first; p < d->next; p++)
              *p1++ = *p;
          } else if (d->next > d->first) {
            char *p1 = dtrace_debug_bufr;
            count = (uintptr_t) d->last - (uintptr_t) d->first;
            for (p = d->first; p < d->last; p++)
              *p1++ = *p;
            count += (uintptr_t) d->next - (uintptr_t) d->bufr;
            for (p = d->bufr; p < d->next; p++)
              *p1++ = *p;
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mWSg4v

        10. FreeBSD. CWE-571 (Expression is Always True)

        V547 Expression 'cfgflags >= 0 || cfgflags <= 3' is always true. hwpmc_piv.c 812

        V547 Expression 'cfgflags >= 0 || cfgflags <= 3' is always true. hwpmc_piv.c 838

        static int
        p4_config_pmc(int cpu, int ri, struct pmc *pm)
        {
          ....
          int cfgflags, cpuflag;
          ....
          KASSERT(cfgflags >= 0 || cfgflags <= 3,
              ("[p4,%d] illegal cfgflags cfg=%d on cpu=%d ri=%d",
            __LINE__, cfgflags, cpu, ri));
          ....
          KASSERT(cfgflags >= 0 || cfgflags <= 3,
              ("[p4,%d] illegal runcount cfg=%d on cpu=%d ri=%d",
            __LINE__, cfgflags, cpu, ri));
          ....
        }
        

        Pull Request: http://ift.tt/2mWFRxI

        11. FreeBSD. CWE-570 (Expression is Always False)

        V547 Expression is always false. scif_sas_controller.c 531

        ....
        U16  max_ncq_depth;
        ....
        SCI_STATUS scif_user_parameters_set(
           SCI_CONTROLLER_HANDLE_T   controller,
           SCIF_USER_PARAMETERS_T  * scif_parms
        )
        {
          ....
           if (scif_parms->sas.max_ncq_depth < 1 &&
               scif_parms->sas.max_ncq_depth > 32)
             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
          ....
        }
        

        Pull Request: http://ift.tt/2mzLoa0

        12. FreeBSD. CWE-571: (Expression is Always True)

        V547 Expression 'cdb[0] != 0x28 || cdb[0] != 0x2A' is always true. Probably the '&&' operator should be used here. mfi_tbolt.c 1110

        int
        mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm)
        {
          ....
          uint8_t *cdb;
          ....
          /* check for inquiry commands coming from CLI */
          if (cdb[0] != 0x28 || cdb[0] != 0x2A) {
            if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {
              device_printf(sc->mfi_dev, "Mapping from MFI "
                                         "to MPT Failed \n");
              return 1;
            }
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mWRiFB

        13. FreeBSD. CWE-571 (Expression is Always True)

        V560 A part of conditional expression is always true: 0x2002. sampirsp.c 7224

        #define OSSA_MPI_ENC_ERR_ILLEGAL_DEK_PARAM            0x2001
        #define OSSA_MPI_ERR_DEK_MANAGEMENT_DEK_UNWRAP_FAIL   0x2002
        
        GLOBAL bit32 mpiDekManagementRsp(
          agsaRoot_t               *agRoot,
          agsaDekManagementRsp_t   *pIomb
          )
        {
          ....
          if (status == OSSA_MPI_ENC_ERR_ILLEGAL_DEK_PARAM ||
              OSSA_MPI_ERR_DEK_MANAGEMENT_DEK_UNWRAP_FAIL)
          {
            agEvent.eq = errorQualifier;
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mWFSSi

        14. FreeBSD. CWE-571 (Expression is Always True)

        V560 A part of conditional expression is always true: 0x7dac. t4_main.c 8001

        #define A_TP_KEEP_INTVL 0x7dac
        
        static int
        sysctl_tp_timer(SYSCTL_HANDLER_ARGS)
        {
          struct adapter *sc = arg1;
          int reg = arg2;
          u_int tre;
          u_long tp_tick_us, v;
          u_int cclk_ps = 1000000000 / sc->params.vpd.cclk;
        
          MPASS(reg == A_TP_RXT_MIN || reg == A_TP_RXT_MAX ||
              reg == A_TP_PERS_MIN || reg == A_TP_PERS_MAX ||
              reg == A_TP_KEEP_IDLE || A_TP_KEEP_INTVL ||
              reg == A_TP_INIT_SRTT || reg == A_TP_FINWAIT2_TIMER);
          ....
        }
        

        Pull Request: http://ift.tt/2mA3BnD

        15. FreeBSD. CWE-476 (NULL Pointer Dereference)

        V595 The 'mc' pointer was utilized before it was verified against nullptr. Check lines: 2954, 2955. mly.c 2954

        static int
        mly_user_command(struct mly_softc *sc, struct mly_user_command *uc)
        {
          struct mly_command  *mc;
          ....
          if (mc->mc_data != NULL)           // <=
            free(mc->mc_data, M_DEVBUF);     // <=
          if (mc != NULL) {                  // <=
            MLY_LOCK(sc);
            mly_release_command(mc);
            MLY_UNLOCK(sc);
          }
          return(error);
        }
        

        Pull Request: http://ift.tt/2mWJtQe

        16. FreeBSD. CWE-563 (Assignment to Variable without Use ('Unused Variable'))

        V519 The 'vf->flags' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 5992, 5994. if_ix.c 5994

        static int
        ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config)
        {
          ....
          if (nvlist_exists_binary(config, "mac-addr")) {
            mac = nvlist_get_binary(config, "mac-addr", NULL);
            bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
            if (nvlist_get_bool(config, "allow-set-mac"))
              vf->flags |= IXGBE_VF_CAP_MAC;
          } else
            /*
             * If the administrator has not specified a MAC address then
             * we must allow the VF to choose one.
             */
            vf->flags |= IXGBE_VF_CAP_MAC;
        
          vf->flags = IXGBE_VF_ACTIVE;
          ....
        }
        

        Pull Request: http://ift.tt/2mWNcgC

        17. FreeBSD. CWE-563 (Assignment to Variable without Use ('Unused Variable'))

        V519 The 'pmuctrl' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 2025, 2026. bhnd_pmu_subr.c 2026

        static void
        bhnd_pmu1_pllinit0(struct bhnd_pmu_softc *sc, uint32_t xtal)
        {
          uint32_t pmuctrl;
          ....
          /* Write XtalFreq. Set the divisor also. */
          pmuctrl = BHND_PMU_READ_4(sc, BHND_PMU_CTRL);
          pmuctrl = ~(BHND_PMU_CTRL_ILP_DIV_MASK |
                      BHND_PMU_CTRL_XTALFREQ_MASK);
          pmuctrl |= BHND_PMU_SET_BITS(((xt->fref + 127) / 128) - 1,
                     BHND_PMU_CTRL_ILP_DIV);
          pmuctrl |= BHND_PMU_SET_BITS(xt->xf, BHND_PMU_CTRL_XTALFREQ);
          ....
        }
        

        Pull Request: http://ift.tt/2mzBDIS

        18. FreeBSD. CWE-561 (Dead Code)

        V779 Unreachable code detected. It is possible that an error is present. if_wi_pci.c 258

        static int
        wi_pci_resume(device_t dev)
        {
          struct wi_softc  *sc = device_get_softc(dev);
          struct ieee80211com *ic = &sc->sc_ic;
        
          WI_LOCK(sc);
          if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
            return (0);                                 // <=
            WI_UNLOCK(sc);                              // <=
          }
          if (ic->ic_nrunning > 0)
            wi_init(sc);
          WI_UNLOCK(sc);
          return (0);
        }
        

        Pull Request: http://ift.tt/2mzS5sD

        19. FreeBSD. CWE-561 (Dead Code)

        V779 Unreachable code detected. It is possible that an error is present. mpr.c 1329

        void panic(const char *a) __dead2;
        
        static int
        mpr_alloc_requests(struct mpr_softc *sc)
        {
          ....
          else {
            panic("failed to allocate command %d\n", i);
            sc->num_reqs = i;
            break;
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mX7Gpx

        Прочие ошибки


        1. GCC

        V590 Consider inspecting this expression. The expression is excessive or contains a misprint. genmatch.c 3829

        const cpp_token * parser::next ()
        {
          const cpp_token *token;
          do
          {
            token = cpp_get_token (r);
          }
          while (   token->type == CPP_PADDING
                 && token->type != CPP_EOF);    // <=
          return token;
        }
        

        Pull Request: http://ift.tt/2mWR6Go

        2. Clang

        V501 There are identical sub-expressions 'RA.getSubReg() != 0' to the left and to the right of the '||' operator. hexagonearlyifconv.cpp 485

        unsigned HexagonEarlyIfConversion::computePhiCost(....) const {
          ....
          const MachineOperand &RA = MI.getOperand(1);
          const MachineOperand &RB = MI.getOperand(3);
          assert(RA.isReg() && RB.isReg());
          // Must have a MUX if the phi uses a subregister.
          if (RA.getSubReg() != 0 || RA.getSubReg() != 0) {
            Cost++;
            continue;
          }
          ....
        }
        

        Pull Request: http://ift.tt/2mzZwzL

        Заключение


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

        Для быстрого знакомства с анализатором, вы можете воспользоваться утилитами, отслеживающими запуски компилятора и собирающие для проверки всю необходимую информацию. См. описание утилиты CLMonitoring и pvs-studio-analyzer. Если вы работаете с классическим типом проекта в Visual Studio, то всё ещё проще: достаточно выбрать в меню PVS-Studio команду «Check Solution».

        Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. Weaknesses detected by PVS-Studio this week: episode N2

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

        Комментарии (0)

          Let's block ads! (Why?)

          [Из песочницы] Аналог std::vector из C++11 на чистом C89 и как я его писал

          Russian Code Cup снова бросает вызов программистам

          Крупнейший российский чемпионат по спортивному программированию Russian Code Cup 2017 стартует 19 марта. Талантливые программисты со всего мира вновь будут соревноваться в правильности и скорости решения задач и поборются за призовой фонд в размере 750 тысяч рублей.

          Основная программа Russian Code Cup (RCC) традиционно состоит из трех этапов: три квалификационных раунда (2 апреля, 16 апреля и 29 апреля), отборочный раунд (14 мая) и финал (10 сентября). На каждом этапе участникам предстоит решить от четырех до восьми разноплановых задач. Те, кому не повезло в первом квалификационном раунде, могут попытать удачи в следующих. В отборочный тур пройдут по 200 лучших участников с каждой квалификации, а в финале сойдутся 50 лучших программистов.

          Победителю чемпионата достанется главный денежный приз в размере 150 000 рублей. За второе и третье место конкурсанты получат 100 и 65 тыс. рублей соответственно. Кроме того, все участники отборочного раунда получат памятные призы — футболки с логотипом чемпионата.

          «В прошлом году в Russian Code Cup впервые официально вышел на международную аудиторию. Из 4,5 тысяч участников соревнования более тысячи были англоговорящими: в финальном раунде за титул чемпиона боролись жители стран СНГ, Германии, Финляндии, Японии, Швейцарии, Китая и Южной Кореи, — говорит Ольга Августан, руководитель образовательного направления Mail.Ru Group. — Чемпионат проводится уже в седьмой раз, и с каждым годом конкуренция возрастает, а значит на вершину прорваться становится все сложнее и почетнее».

          Задания и техническую часть соревнования обеспечивают специалисты Mail.Ru Group и эксперты университета ИТМО. Более подробные правила читайте на сайте чемпионата.

          Зачем участвовать в чемпионате?


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

          Программистам


          Для большинства участников чемпионаты — это возможность подучить алгоритмы и приучить свой мозг быстро выдавать решение в стрессовых ситуациях с ограниченным временем и ресурсами. Успешное выступление — показатель собственной крутости. Безусловно, победа на RCC многое может сказать об уровне человека: скорее всего, у него есть определенный талант и солидный опыт за плечами. Мы рады видеть всех победителей в рядах нашей компании, но активной «охоты за талантами» не устраиваем, как и организаторы других подобных чемпионатов. Цель таких мероприятий — создание и укрепление IT-культуры.

          Студентам


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

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


          Для участия в чемпионате необходимо зарегистрироваться на сайте Russian Code Cup. Соревнования пройдут онлайн. С 19 марта стартует предварительный раунд: участники смогут ознакомиться с платформой и оценить свои силы в решении одной типичной задачи. Участие в этом раунде не обязательно, а его результаты не влияют на итоги следующих. Квалификационные раунды пройдут 2, 16 и 29 апреля.

          Комментарии (0)

            Let's block ads! (Why?)

            [Из песочницы] Разработка первой игры под Android с применением Adobe AIR и Stage3D

            Введение


            Давно хотел сделать хоть какую-нибудь игрушку для мобильника. Разработка игр – это одно из моих хобби. Времени я уделяю для этого крайне мало, но делаю это с удовольствием.

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

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

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

            Выбор технологии


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

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

            Пробовал haxe – очень интересная штука, но собирать приложение долго, часто глючит сборка через Android SDK/NDK (у меня несколько сред разработки по работе со своими хранилищами Android SDK/NDK, возможно они конфликтуют с haxe), да и производительность не сильно лучше Starling для AIR.

            Ковырялся я долго в разных движках и в какой-то момент решил просто выпустить ради самого процесса игрушку. Поэтому я обратился к старому другу – AS3 с технологией AIR. Как-то делал небольшие радиоуправляемые игрушки и вместо пульта использовал телефон, на котором были разработаны простенькие интерфейсы джойстика управления по WI-FI. Как раз для этого я использовал AIR, ведь раньше я делал игрушки на Flash, и создание приложения для мобильника на AIR оказалось крайне быстрым и простым.

            Stage3D


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

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

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

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

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

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

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

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

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

            Сделал поддержку покадровой анимации и программной (костной анимации) и небольшие программы для преобразования MovieClip’ов из Adobe Animate в спрайтшиты и файлы описаний программной и покадровой анимации.

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

            Выводы


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

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

            Для испытания всего этого я разработал простенькую аркаду «Древние Руны» и опубликовал ее на Google Play.

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

            Вот, если интересно, пример apk бенчмарка от старлинга (я поменял только статичные картинки на анимации, возможно, там что-то можно ускорить) и пример движка на основе GPUSprite от Adobe с анимацией

            starling
            GPUSprite

            Комментарии (0)

              Let's block ads! (Why?)

              Загрузка доверенной среды или лёгкий путь к паранойе в IT


              Несмотря на несколько академичное название, тема носит вполне себе практичный характер.
              Когда мы видим заголовки новостей об очередном успешном взломе чатов Telegram или WhatsApp (ЦРУ, Иранскими спецслужбами, Zimperium – нужное подчеркнуть), людям достаточно часто приходится объяснять, что компрометация операционной системы или аккаунта пользователя не является синонимом слабости защиты самого приложения, и это не является поводом отказаться от пользования своим любимым мессенджером, т.к. на его месте может оказаться без принципиальной разницы любой другой.


              А если вы, например, загрузившись с флэшки «перезабиваете» пароли администратора любой своей Windows-машины, это отнюдь не говорит о чудовищных дырах в «мастдае», а о вас – как о супер-хакере, взломавшем детище Microsoft.


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


              Итак, начнём с практики, есть следующий кейс:


              Вы после успешного празднования дня системного администратора, забыли все свои логины и пароли для входа в систему и не можете работать со своими компьютерами. Как вернуть доступ? Рассмотрим на примере двух популярных ОС: Ubuntu и Windows (MacOS рассмотрим попозже).


              Сброс забытого пароля в ОС Ubuntu


              Сценарий 1. Есть доступ к меню выбора операционных систем GRUB.


              Если у вас при загрузке компьютера появляется меню выбора операционных систем, то, скорее всего, у вас в нём есть пункт, обозначенный как recovery mode.



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



              У вас запустится консоль с правами root.


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


              1. Сначала необходимо перевести корневую файловую систему в режим записи
                mount -no remount,rw /
              2. Теперь для установки нового пароля достаточно выполнить команду
                passwd имя_пользователя
                где вместо имя_пользователя подставить имя нужного пользователя, а потом выполнить
                reboot
                для перезагрузки компьютера.

              Если пункта recovery mode нет, то:


              1. выберите строчку с вашей системой;
              2. нажмите клавишу E;
              3. допишите в конец опций ядра слово single;
              4. нажмите клавишу B.

              Загрузится тот же терминал с правами суперпользователя.


              Сценарий 2. Меню выбора операционных систем GRUB недоступно.


              Если у вас по тем или иным причинам отключён выбор операционных систем при загрузке, то пароль можно сбросить с помощью любого Live CD с Linux. Для этого необходимо загрузиться с Live CD, примонтировать ваш корневой раздел, а далее установить пустой пароль пользователю путём редактирования файла etc/shadow на этом разделе.


              Пустой пароль поставить можно на любого пользователя, кроме root.


              Примечание: Вообще говоря, никакими инструментальными средствами Ubuntu нельзя установить пользователю пустой пароль. Все графические утилиты требуют пароль минимум из 6-ти символов, а программа passwd умеет устанавливать любой пароль, кроме пустого. Однако всё же существует способ задания пользователю пустого пароля.

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

              Нам потребуется изменить системный файл /etc/shadow, поэтому крайне рекомендуется перед выполнением дальнейших действий сделать резервную копию:


              sudo cp /etc/shadow /etc/shadow.bak
              

              Теперь в любом текстовом редакторе от имени root откройте файл /etc/shadow, найдите строку, начинающуюся с логина нужного пользователя, и удалите всё между первым и вторым двоеточием в этой строке. Например, была такая строка:


              admin:$6$eZ1pQKRK$tGvrlJnV7NU/anEFoxRCluIbe5kSNE2x2uqRrw62xHVrQPWKKbfYZ0cvdmgxXAcrGxBngPM7HnrrKxdmNwp0:14371:0:99999:7:::
              

              Для задания пустого пароля пользователю admin необходимо привести её в обоих файлах к виду:


              admin::14371:0:99999:7:::
              

              После этого пароль пользователя admin станет пустым.


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


              Как сбросить пароль ОС Windows 10


              Рассмотрим два сценария для сброса пароля локального пользователя в Windows 10.


              Сценарий 1. Подмена исполняемого файла.


              Для использования данного способа потребуется одно из: Live CD с возможностью загрузки и доступа к файловой системе компьютера, диск (флешка) восстановления или дистрибутив Windows 10, 8.1 или Windows 7. Далее будет рассмотрен сброс пароля с помощью средств восстановления Windows на установочной флешке.


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


              В командной строке введите по порядку команды (после ввода нажать Enter):


              diskpart
              list volume
              


              Вы увидите список разделов на жестком диске. Найдите букву раздела, на котором установлена Windows 10. Введите команду Exit и нажмите Enter для выхода из DiskPart. Используя букву раздела (С) в командах, следует ввести далее:


              move c:\windows\system32\utilman.exe c:\windows\system32\utilman2.exe
              copy c:\windows\system32\cmd.exe c:\windows\system32\utilman.exe



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


              Примечание: если вы использовали не установочный диск, а что-то еще, то ваша задача с помощью командной строки, как было описано выше, или другими средствами, сделать копию cmd.exe в папке System32 и переименовать эту копию в utilman.exe.

              После загрузки в окне ввода пароля нажмите на иконку «Специальные возможности» внизу справа. Откроется командная строка Windows 10.


              В командной строке введите net user имя_пользователя новый_пароль и нажмите Enter. Если имя пользователя состоит из нескольких слов, используйте кавычки. Если вы не знаете имени пользователя, используйте команду net user, чтобы посмотреть список имен пользователей Windows 10. После смены пароля, вы сразу же сможете зайти под новым паролем в учетную запись.


              Сценарий 2. Правка реестра.


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


              Суть способа в следующем:


              1. Загрузиться с накопителя, в программе установки нажать Shift + F10, чтобы открыть командную строку.
              2. Ввести regedit и нажать Enter для запуска редактора реестра.
              3. В редакторе реестра выбрать раздел HKEY_LOCAL_MACHINE после чего в меню выбрать «Файл» — «Загрузить куст» и открыть файл C:\ Windows\ System32\ config\ system
              4. При запросе имени раздела, указать любой.
              5. Внутри HKEY_LOCAL_MACHINE загруженного куста (раздела реестра) с указанным вами именем выбрать раздел setup и в правой части изменить следующие значения (путем двойного клика по ним).
              6. CmdLine — установить значение cmd.exe
              7. SetupType — установить значение 2.
              8. В редакторе реестра выбрать «Файл» — «Выгрузить куст» и подтвердить выгрузку.
                После этого закройте редактор реестра, командную строку, выйдите из программы установки и загрузитесь с жесткого диска компьютера. При загрузке Windows 10 откроется командная строка, в которой вы сможете сбросить пароль путем ввода:
                net user имя_пользователя новый_пароль

              Для продолжения загрузки ОС, наберите в командной строке exit и нажмите Enter. Каким-либо образом возвращать параметры в исходное состояние не потребуется: параметр SetupType в реестре вернется к значению 0.


              Что это было?


              Вот здесь как раз и всплывают вопросы среды и доверия к ней.
              Итак, что произошло выше?


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


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


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


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



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


              Как же нам получить надёжное здание? В IT это называют доверенные системы (trusted systems) или доверенной средой/платформой (trusted platform).


              Понятие «доверенная среда» на текущий момент не имеет устоявшегося определения, специалисты не могут сойтись во мнениях, а в нормативной базе, строго говоря, термин «доверенный» не определен. Само понятие «доверенная среда» появилось уже после "доверенная система", введённого ещё в 1983г. в так называемой Оранжевой книге (TSSEC — Trusted Computer System Evaluation Criteria), явившейся исходным материалом для ряда руководящих документов Гостехкомиссии РФ, например, РД АС.


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


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


              Заключение


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


              Литература


              1. ГОСТ Р 54583-2011/ISO/IEC/TR 154443-3:2007. Информационная технология. Меры и средства обеспечения безопасности. М.: Стандартинформ. 2013.;
              2. ГОСТ Р ИСО/МЭК 15408-3-2002. Информационная технология. Методы и средства обеспечения безопасности. Критерии оценки безопасности информационных технологий. Часть 3. Требования доверия к безопасности;
              3. Цирлов В.Л. Основы информационной безопасности автоматизированных систем, Краткий курс. — Ростов-на-Дону: Феникс, 2008. — 253 с.;
              4. Авезова Я.Э., Фадин А.А. Вопросы обеспечения доверенной загрузки в физических и виртуальных средах // Вопросы кибербезопасности. 2016. № 1(14). С. 24-30;
              5. Сведения о реестре Windows для опытных пользователей, http://ift.tt/2nMnSaA;
              6. Пользовательская документация на Ubuntu, http://ift.tt/2nMoSvt;
              7. Trusted Computer System Evaluation Criteria, http://ift.tt/1Agkm9Z;
              8. Руководящий документ. Автоматизированные системы. Защита от несанкционированного доступа к информации. Классификация автоматизированных систем и требования по защите информации. М.: Гостехкомиссия России, 1992.

              Комментарии (0)

                Let's block ads! (Why?)

                [Перевод] Простой, надёжный и удобный мониторинг серверов на Linux

                Дайджест практических материалов о работе с IaaS

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

                / фото Steve JurvetsonCC

                Обзор перспективных ИТ-технологий
                Согласно нашей традиции мы подготовили большой обзор аналитической информации о дальнейшем развитии сферы ИТ. Мы поговорили о безопасности, аналитике, сервисах XaaS, мобильных приложениях и виртуализации.
                ИТ-ГРАД подводит итоги 2016 года в направлении IaaS
                Кратко о наших достижениях в сфере приобретения новых статусов и компетенций и немного о новых облачных сервисах, которые мы запустили в 2016 году.
                Как IaaS влияет на развитие новых бизнес-моделей
                Сегодняшний рост спроса на услуги IaaS-провайдеров обсуловлен не только экономической эффективностью, но и более кардинальным пересмотром существующих бизнес-моделей. Здесь мы рассмотрели IaaS как источник увеличения доходов и драйвера развития «Облака 2.0». Помимо этого мы затронули темы машинного обучения, искусственного интеллекта и бессерверных вычислений.
                Как IaaS решает задачи в строительном бизнесе
                Этот материал предоставляет обзор ситуации с применением облачных технологий в сфере строительства. От решений, позволяющих работать на этапе проектирования, до продуктов для обеспечения эффективного взаимодействия специалистов. Еще мы рассмотрели облачное решение BIM 360 Glue и применение дронов.
                Кому интересен российский IaaS
                Аналитика и профильные исследования говорят о том, что мировой рынок виртуальной инфраструктуры начал постепенно насыщаться предложениями IaaS-провайдеров. Российский сегмент не отстает — число IaaS-провайдеров увеличивается по мере роста спроса на их услуги. Мы рассказали о наших практический рейсах.
                Что выбрать: Виртуальный сервер или виртуальный ЦОД
                Простыми словами о том, что такое виртуальный сервер и виртуальный ЦОД. Мы разобрались с плюсами и минусами, основными отличиями, способами минимизации затрат и подходов, позволяющих сократить время простоя.
                Какие стартапы используют IaaS
                Мы поговорили о практической составляющей работы с виртуальной инфраструктурой и вспомнили некоторые кейсы нашей работы со стартапами.

                / Фото Leonardo RizziCC

                Как «развернуться» в облаке
                Здесь мы собрали основные практические советы по быстрому и безопасному размещению проектов в облаке. О самом главном, на что стоит обратить внимание и немного о методологии развертывания.
                Что требовать от SAP- хостинг-сервис-провайдера
                Наше комплексное руководство для тех, кто хотел бы разобраться с тем, как начать работу с решениями SAP. Мы познакомим вас с особенностями хостинга решений SAP и подскажем, на что обратить внимание при выборе провайдера. Здесь важно понимать как общий состав услуг, так и то, что клиент может сделать своими силами.
                Руководство: SAP HANA и программно-определяемый ЦОД
                В этом туториале мы разобрали процесс настройки логики сетевых соединений, способ добавления логического коммутатора NSX, привязку виртуальной машины к коммутатору, добавление логического распределенного роутера и настройку правил брандмауэра.
                Как работать с зонами доступности в vCloud Director
                Речь идет о настройке возможности эластичного развертывания приложений с использованием балансировки нагрузки и кластеризации. Здесь мы говорим о кейсе с несколькими зонами доступности и работе с «растянутой» сетью организации с помощью vCenter Server.
                IaaS на практике: Работа с каталогом и сетью
                В этой статье мы разобрались с тем, что требуется для начала работы с вашим IaaS-провайдером. Мы остановились подробнее на работе с каталогом в vCloud Director и особенностях создания локальной сети.
                Сравнение четырех топ-решений для аварийного восстановления
                Мы рассмотрели сильные и слабые стороны DR-решений и такие продукты как VMware SRM, Zerto Virtual Replication, Veeam Backup и Altaro VM Backup.
                Как работает Stretch Deploy для vCloud Connector
                Эта технология позволяет перераспределять нагрузку и переносить собственные виртуальные машины в облако IaaS-провайдера с сохранением сетевой конфигурации. В данном материале мы разобрались с тем, как устроен Stretch Deploy и требованиями для подготовки окружения и настройки.


                / Фото m1try/ CC

                Обзор ключевых особенностей VMware vSphere Client 3.0
                Немного о знакомстве с новым поколением тонкого клиента для управления виртуальной инфраструктурой — VMware vSphere Client 3.0 (vSphere HTML5 Web Client). Мы рассказали о том, какие он получил обновления и кратко остановились на средстве для разработки плагинов для vSphere.
                VMware vSphere 6.0 все еще актуален — 3 причины
                «Шестерка» — самая используемая платформа виртуализации, включающая в себя более 650 технологических улучшений. В данной версии сделаны значительные расширения — например, технология живой миграции vMotion была значительный образом доработана в VMware vSphere 6.0.
                Unboxing all-flash СХД NetApp AFF A300
                Одна из наших любимых рубрик, в рамках которой мы уделяем время нюансам и деталям того железа, которое используется на площадке «ИТ-ГРАД». Система NetApp AFF A300 рассчитана почти на 100 терабайт SSD — в нашем анбоксинге — пара High-Availability-контроллеров NetApp A300 в одном шасси и дисковая полка DS224C c набором из 24 SSD-дисков по 3,8 ТБ каждый.

                Комментарии (0)

                  Let's block ads! (Why?)

                  [Перевод] Фильтрация и создание цепочек в функциональном JavaScript

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

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

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

                  Фильтрация для ограничения датасетов


                  С появлением ES5 массивы в JS унаследовали несколько методов, делающих функциональное программирование ещё удобнее. Теперь массивы нативно поддерживают map, reduce и filter. Каждый метод проходит по всем элементам массива, и выполняет анализ без использования циклов и изменения локальных состояний. Результат может быть возвращён для немедленного использования, или оставлен для последующей обработки.

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

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


                  Пример проблемы, решить которую поможет фильтрация — ограничение массива, содержащего строковые значения, только теми, что состоят из трёх символов. Задача не сложная, и решить её можно довольно искусно с помощью ванильных JS-циклов for, без использования filter. Например:
                  var animals = ["cat","dog","fish"];
                  var threeLetterAnimals = [];
                  for (let count = 0; count < animals.length; count++){
                    if (animals[count].length === 3) {
                      threeLetterAnimals.push(animals[count]);
                    }
                  }
                  console.log(threeLetterAnimals); // ["cat", "dog"]
                  

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

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

                  Использование метода Filter


                  Предыдущее решение технически корректно. Но использование метода filter позволяет сделать код гораздо чище и проще. Например:
                  var animals = ["cat","dog","fish"];
                  var threeLetterAnimals = animals.filter(function(animal) {
                    return animal.length === 3;
                  });
                  console.log(threeLetterAnimals); // ["cat", "dog"]
                  

                  Здесь мы тоже начали с переменной, содержащей исходный массив. Определили новую переменную для массива, куда будем класть строковые из трёх символов. Но применив метод filter, мы напрямую связали результаты фильтрации со вторым массивом. Передаём filter анонимной встроенной (in-line) функции, возвращающей true, если длина оперируемого значения равна трём.

                  Метод filter работает так: проходит по каждому элементу массива и применяет к нему тестовую функцию (test function). Если функция возвращает true, то метод filter возвращает массив, содержащий этот элемент. Другие элементы пропускаются.

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

                  Чистота кода — один из приятных побочных продуктов функционального программирования. Это следствие ограничения преобразования внешних переменных из функций и необходимости хранить меньше локальных состояний. Переменная count и разные состояния, принимаемые массивом threeLetterAnimals при прохождении циклов по исходному массиву, это дополнительные состояния, которые надо отслеживать. Метод filter избавил нас от цикла и переменной count. И мы не меняем многократно значение для нового массива, как в первом случае. Мы определили его один раз и связали со значением, получаемым в результате применения условия filter к исходному массиву.

                  Другие способы форматирования Filter


                  Можно написать ещё короче. Воспользуемся объявлениями const и анонимными встроенными стрелочными функциями (inline arrow functions). Это благодаря EcmaScript 6 (ES6), который нативно поддерживается большинством браузеров и JavaScript-движков.
                  const animals = ["cat","dog","fish"];
                  const threeLetterAnimals = animals.filter(item => item.length === 3);
                  console.log(threeLetterAnimals); // ["cat", "dog"]
                  

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

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

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

                  const animals = ["cat","dog","fish"];
                  function exactlyThree(word) {
                    return word.length === 3;
                  }
                  const threeLetterAnimals = animals.filter(exactlyThree);
                  console.log(threeLetterAnimals); // ["cat", "dog"]
                  

                  Здесь мы просто извлекли анонимную встроенную стрелочную функцию, определённую до этого, и превратили в отдельную именованную. Мы определили чистую функцию (pure function). Она получает соответствующий тип-значение для элементов массива, и возвращает такой же тип. Можем в качестве условия просто передать в filter имя этой функции.

                  Быстрый обзор Map и Reduce


                  Фильтрация работает рука об руку с двумя другими функциональными методами ES5 — map и reduce. Создавая цепочки методов, можно использовать эту комбинацию для написания очень чистого кода, выполняющего довольно сложные функции.

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

                  const animals = ["cat","dog","fish"];
                  const lengths = animals.map(getLength);
                  function getLength(word) {
                    return word.length;
                  }
                  console.log(lengths); //[3, 3, 4]
                  

                  Метод reduce проходит по массиву и выполняет ряд операций. Промежуточный результат каждой из них передаёт в сумматор. По завершении обработки массива метод выдаёт финальный результат. В нашем случае можно использовать второй аргумент для начальной установки сумматора в 0.
                  const animals = ["cat","dog","fish"];
                  const total = animals.reduce(addLength, 0);
                  function addLength(sum, word) {
                    return sum + word.length;
                  }
                  console.log(total); //10
                  

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

                  Создание цепочек из Map, Reduce и Filter


                  Рассмотрим простейший пример. Допустим, вам нужно взять массив из строковых значений, и вернуть одно, состоящее из трёх символов. Но при этом отформатировать его в стиле StudlyCaps. Без map, reduce и filter это будет выглядеть примерно так:
                  const animals = ["cat","dog","fish"];
                  let threeLetterAnimalsArray = [];
                  let threeLetterAnimals;
                  let item;
                  for (let count = 0; count < animals.length; count++){
                    item = animals[count];
                    if (item.length === 3) {
                      item = item.charAt(0).toUpperCase() + item.slice(1);
                      threeLetterAnimalsArray.push(item);
                    }
                  }
                  threeLetterAnimals = threeLetterAnimalsArray.join("");
                  console.log(threeLetterAnimals); // "CatDog"
                  

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

                  Объявлять целевой пустой массив можно с помощью let или const.

                  Создадим чистые функции, берущие и возвращающие строковые значения. Затем используем их в цепочках методов map, reduce и filter, передавая результаты от одного к другому:

                  const animals = ["cat","dog","fish"];
                  function studlyCaps(words, word) {
                    return words + word;
                  }
                  function exactlyThree(word) {
                    return (word.length === 3);
                  }
                  function capitalize(word) {
                    return word.charAt(0).toUpperCase() + word.slice(1);
                  }
                  const threeLetterAnimals = animals
                    .filter(exactlyThree)
                    .map(capitalize)
                    .reduce(studlyCaps);
                  console.log(threeLetterAnimals); // "CatDog"
                  

                  Три чистые функции: studlyCaps, exactlyThree и capitalize. Можно передавать их напрямую в map, reduce и filter в пределах одной неразрывной цепочки. Сначала с помощью exactlyThree фильтруем исходный массив. Передаём результат в capitalize. А уже её результат обрабатываем с помощью studlyCaps. Финальный результат присваиваем напрямую переменной threeLetterAnimals. Без циклов и промежуточных состояний, не трогая исходный массив.

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

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


                  Не забывайте, что метод filter наверняка будет работать чуть медленнее, чем цикл for, пока браузеры и JS-движки не будут оптимизированы под новые методы работы с массивами (jsPerf).

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

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

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

                  Комментарии (0)

                    Let's block ads! (Why?)

                    [Из песочницы] Создаем веб приложение используя VueJS и .NET

                    Видеозаписи лучших докладов DotNext 2016 Moscow: Перфоманс, CLR и функциональное программирование на .NET

                    Если у вас еще нет планов на выходные – у меня есть предложение: посмотрите доклады с DotNext 2016 Moscow, вчера мы выложили их в общий доступ.

                    Вообще, мой любимый формат поста про конференции – обзор лучших докладов. Жаль, делать его получается только один раз на конференцию… В любом случае, сегодня у нас есть о чем поговорить: мы открыли доступ к видеозаписям лучших докладов конференции DotNext 2016 Moscow и близимся к завершению программы DotNext 2017 Piter (Питер, 19-20 мая), о которой тоже скажу пару слов.

                    Все видео под катом.

                    10 лучших докладов DotNext 2016 Piter


                    Давайте без долгих вступлений перейдем к делу. Десятку лучших у нас закрывает Marco Cecconi, перфоманс-инженер из SO, c интересным докладом «Performance tuning Stack Overflow tags» о том, как команда Stack Overflow добивается той производительности, которую демонстрирует SO, на примере Stack Overflow tags.

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



                    На девятом месте у нас доклад Вагифа Абилова «Моя жизнь с актерами: опыт внедрения модели актеров на F#», посвященный самому процессу и подводным камням перехода медиапроекта с большим объемом видеоконтента с C# SOLID архитектуры на F# с Akka.NET.

                    Начиная с обзора функциональных изменений и новых принципов дизайна системы, Вагиф рассказывает, почему именно было принято решение перейти на F# + Akka.NET, сравнивает message driven development c ООП, и показывает, как новы подход позволил уйти от ручного управления потоками и контроля над состояниями общего доступа. После этого – еще полчаса разбора проблем и решений, которые были порождены переходом.

                    В конце доклада Вагиф исполняет (да-да, live!) песню о жизни актера, которая позволит вам запомнить, все, что он рассказывал до этого, и демонстирует примеры рефакторинга с C# на F#.



                    На восьмом месте оказался доклад Михаила Щербакова «Странные дела: уязвимости в .NET платформе». Какие типы уязвимостей находят в .NET Framework? Что может стать целью атакующего? Как знание о типичных атаках помогает разрабатывать защищённые приложения? Михаил отвечает на эти вопросы, наглядно в коде демонстрируя примеры дырок, найденных в ASP .NET, .NET Remoting и в свежем .NET Core.


                    На седьмой позиции доклад Filip W о не слишком распространенной теме скриптинга на C#. На эту тему мы брали у Филипа интервью, так что здесь много писать не буду. Из основного: Филип утверждает, что за счет богатсва инфраструктуры C# превосходит по эффективности любой другой скриптовый язык. Холивар? Смотрите видео:


                    Что мы знаем о времени? Наверное, не так много, как хотелось бы. А что мы знаем о реализации Date&Time на .NET? Оказывается, тоже не все. Илья Фофанов в своем докладе показывает, к чему приводит невнимательность в работе с датами и временем: отсутствие дат при переходе с одного календаря на другой, некорректное вычисление возраста человека, проблемы планирования будущих событий, арифметике на датах и времени и многом другом. Конечно, о том, как можно избежать большинства проблеми лучших практиках, Илья тоже рассказывает.


                    На пятом месте у нас снова F# в докладе Романа Неволина «F# во славу Data Science», посвященном возможностям функционального .NET-языка в работе с большими данными: обработка и анализ, интерактивное взаимодействие и визуализация. В докладе есть обзор не только обзор языка, но и полезных велосипедов библиотек: Fable, Deedle, Accord Framework, R provider и другие.

                    Кстати, доклад можно смотреть, даже если вы с F# «ни в зуб ногой»:



                    Переходим к хардкорным делам – на четвертом месте доклад Sasha goldshtn Goldshtein, перфоманс-инженера, автора книги «Pro .NET Performance» о том, как извлекать максимум производительности из железа: векторизация на параллельных потоках, оптимизация вашего кода в работе с последними наборами инструкций и структурами кэшей. Об инструментах, позволяющих находить и исправлять «бутылочные горлышки» в ваших алгоритмах без игры в угадайку.

                    Все это демонстрируется на живых примерах построения алгоритмов, оптимизированных по современные CPU и модели памяти, на C#. Доклад на английском языке.



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

                    Доклад начинается с описания наработок Microsoft в этой области с примерами, любопытными демками и подробным описанием API. После этого Дмитрий прямо на докладе пишет бота в облаке.



                    На втором месте доклад Андрея DreamWalker Акиньшин, в котором он продолжил тему .NET-арифметики с DotNext 2017 Piter, но если в прошлый раз это были шутливые паззлеры, в Москве речь шла о фундаментальной теории и практических аспектах работы с числами.

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

                    • Грабли денормализованных чисел;
                    • Особенности генерации ASM-кода для простейших арифметических операций на стороне JIT-компиляторов;
                    • Неожиданные последствия незначительных изменений в исходном коде для перфоманса и точности вычислений.



                    А на первом месте у нас, сюрприз-сюрприз, конечно, Sasha Goldshtein c докладом о возможностях WinDbg для .NET-разработчика. Из доклада вы узнаете, как настроить WinDbg так, чтобы он был полее понятен и удобен; как работать со скриптами и брейкпоинтами WinDbg; об инструментах автоматизации работы с инструментом, а также о том, как работать с перфомансом удаленно.

                    Важное замечание, 90% вещей, описанных в докладе, невозможно сделать силами Visual Studio.

                    Видеозаписи всех остальных докладов смотрите на нашем YouTube-канале.



                    Что дальше?


                    А дальше — DotNext 2017 Piter (29-20 мая 2017). Мы посмотрели на оценки всех докладов и решили в этот раз снизить градус хардкора, сделав акцент на технологиях, необходимых в повседневной работе .NET-разработчика. Конечно, будет что послушать и про перфоманс, но большая часть программы посвящена разным областям: новым фреймворкам, обновлениям привычных инструментов, разработке правильного GUI и вообще правильным паттернам и подходам.

                    Поговорим об Entity Framework Core, NuGet, Rider IDE, Xamarin.Forms и AvaloniaUI, REST-фреймворках, – в общем, смотрите программу, там много интересного.

                    По каждой технологии будет исчерпывающий обзор, не в стиле «С++ за час», а достаточный, чтобы понять, что происходит в той или иной области. Кстати, у нас уже 9 (!) MVP докладчиков, включая Jon Skeet!

                    P.S. У нас в программе еще осталось несколько слотов для докладов, если у вас есть чем поделиться — подавайте нам доклад! Если опыта нет — мы поможем: поставим речь, расскажем о правильной структуре доклада, сделаем несколько тренировок, – все, что нужно, чтобы зажечь на сцене!

                    Комментарии (0)

                      Let's block ads! (Why?)