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

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

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

 

 -Статистика

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

Habrahabr/New








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

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

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

Этапы развития проекта обучения Java: как это было, взгляд изнутри

Пятница, 22 Сентября 2017 г. 08:59 + в цитатник
gkislin сегодня в 08:59 Разное

Этапы развития проекта обучения Java: как это было, взгляд изнутри


    Здравствуйте! Меня зовут Григорий Кислин, автор и ведущий учебных проектов и стажировок Java. Хотел рассказать с технической точки зрения, как проект жил и развивался. На каждом этапе приходилось выбирть только самые необходимые для текущей работы решения, которые реализовывались по принципу KISS, или, по русски ДУП: Дешево, Удобно и Практично.

    Начало: преподавание в учебном центре


    Все началось с оффлайн преподавания в Санкт-Петербургском платном учебном центре в октября 2013 г. Там провел несколько очных выпусков разработанного мной курса «Практика Java. Разработка Web приложения». Преподавание шло на основе разработки одного большого веб проекта и приходилось решать достаточно тривиальные вещи, например, передача написаного мной кода всем участникам. Пробовались флешки:), скайп, передача файлов по сети. Искалось решение для обновления проекта участниками и отделения моего кода от кода домашних заданий. В конце пришли к очевидному решению — к системе контроля версий, обновлению проекта патчами и выполнению домашних заданий в ветках git. К обучению Java добавилось обучение Git и GitHub, без знания которых жизнь разработчика немыслима. Параллельно преподаванию я разрабатывал учебный проект Java Enterprise (Spring, JPA/Hibernate, REST, ..), основанный на вступительном задании в Toptal.

    Уход в совбодное плавание


    В преподавании хотелось некоторой автономии, например, приводить своих участников на курс с небольшой скидкой и получать за них комиссионные, что не было в планах владельцов центра. В результате переключился на онлайн формат и стал вести разработку проекта на вебинарах самостоятельно. Сделал простенький сайт на Bootstrap, выбрал недорогой хостинг host-food (там же можно недорого купить домен) и прикрутил к сайту php скрипт для рассылки писем: при регистрации на сайте он рассылал 2 письма — мне и участнику. Письма регистрации веб клиент Yandex сортировал в разные папки, откуда я их вставлял в Google Sheets. Письма рассылал несколькими группами (не более 25 адресатов в одном письме).

    Для вебинаров взял платформу Adobe Connect (25 человек в комнате и месяц Trial), общались в группе Skype. Adobe хорошо работает с 2-мя экранами (один для показа, второй рабочий, с заранее подготовленным кодом проекта по занятию) и хорошо записывает у себя в облаке видео вебинара, которое доступно участникам сразу после занятия (надо только не забывать включать запись!). Параллельно скрёб по всем сусекам для набора на первый выпуск Java Enterprise. Запустил его в августе 2014, набралось целых 6 человек!

    Рост вглубь


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

    Выбор пал на хостинг AWS с годом! бесплатного пользования. Будте аккуратнее их с бесплатным стеком, через пару недель мне начислили около доллара за то, что не был отключен ежедневный бэкап моего пустого PostgreSQL, и они превысили бесплатные 5 Gb на Amazon S3. А при нажатии кнопки примера деплоя в AWS Elastic Beanstalk он развернул сразу 3 инстанса, что обошлось мне в несколько центов:). В результате остановился на простой конфигурации: EC2 (Amazon Linux AMI), база H2 (понравилась возможность подключения к ней при работающем приложении через запуск TCP сервера) и запуск Spring Boot как JAR. Кстати, при моих нагрузках, бэкап H2 это обычное копирование файла без остановки сервера. Проекту делал push на GitHub, и забирал его через pull на сервере (недавно процесс еще более упростился — делаю push со своего компа прямо на EC2 по ssh, а логи смотрю в Terminal окне IDEA). Шаблоны писем сделал в Thymeleaf с очисткой кэша каждые 3 секунды (полагаю, что это решение лучше, чем его полностью отключить). В результате шаблон на сервере обновляется сразу, передеплой не требуется.

    Почту отправлял через SMTP Yandex (ограничение ~ 500 писем в день, для массовой рассылки необходим заголовок List-Unsubscribe для возможности отписки). Форма регистрации на сайте дергала мой сервис, который сохранял человека в базу, отправлял письмо и показывал результат отправки.

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

    Дальше-больше: ограничения


    500 писем в день стало не хватать, и Yandex стал меня банить. Переключение на запасные email был не лучший вариант и, пошукав, я нашел отличное решение: Amazon Simple Email Service (SES). Единственно, что для нормальной работы с ним надо написать в техподдержку с просьбой снять ограничения, дать сылку на сайт и ответить 3 раза «Да» на вопросы про управление подпиской. В результате я целый год бесплатно рассылал письма и сейчас за них плачу центы (объемы небольшие, ~ 5-7 тыс. писем в месяц).

    Группа Skype, где более 50 человек, становится неудобной для обучения. Мы перешли на Slak, где для каждого урока и каждой темы (например help, отзывы по работе, вакансии) сделали свой канал. Со временем появились каналы подписок RSS, изменений в проекте и пр. Приглашение в Slack также сделал автоматическим через их недокументированное API.

    Следующим ограничением было максимальное количество людей для доступа к папке в Google Drive (отредактированные видео вебинаров храню там): 600 человек. Проблема решилось через предоставления доступа к Google группам и G-Suite Admin SDK для автоматического добавления участников в группу. Пришлось изрядно (дня 3-4) погуглить, чтобы с ним проинтегрироваться. Стоит удовольствие 4 € в месяц за участника (т.к. участник я один, а все остальные — гости, то выходит недорого:)

    Развитие вширь: новые функции (фичи)


    Сайт на host-food стал лишним, логично было его перенести вместе с приложением на AWS. При редизане сайта помогли простые рекомендации от Google, а при его настройке тестирование на скорость загрузки. Например, следуя рекомендации, простое включение Gzip в Ngix подняла оценку скорости загрузки с Good до Excelent.

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

    Досточно долго я жил без авторизации вообще. Участник попадал в свой профиль на сайте по ссылке из письма с посоленным хэшем своего email. И только недавно c помощью выпускников (времени самому на все не хватает) добавил авторизацию по OAuth2 через Google и GitHub. Интерфейс задания пароля, его смены и напоминания не потребовался.

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

    Приложение находится в постоянном изменении: пришлось изменить процесс выдачи бесплатных купонов на IDEA при переходе JetBrains на новую политику, настроил подписку с сайта на рассылки в группы VK (см. статью рассылки в ВК), интергируюсь с сервисом поиска разработчиков GetCoder. Кстати, если рассматриваете предложения о работе, заполните у себя в профиле GitHub локацию — это важная информация для HR. Около 2-х лет назад пришлось уйти с основной работы синьором и полностью отдать себя проекту.

    Заранее отвечу на Ваши вероятные вопросы:

    Текущий твой бизнес даёт доход хотя бы на уровне сениорной зарплаты? Не жалеешь о переходе?
    Нет, хотя сейчас получается примерно столько же. У синьора есть потолок: его возможности. А в бизнесе все от тебя зависит, только двигаться надо. Работать приходится много, но зато отдыхать тоже могу, когда хочу (вместе с компом правда:). И работа на себя приносит больше радости и удовлетворения. Особенно когда видишь ее результаты — трудоустроенных выпускников и хорошие отзывы.
    Это не в рубрику «Я пиарюсь»?
    Надеюсь, что нет. Ссылок на себя не давал, писал про историческое развитие проекта и технические решения, которые, надеюсь, кому-то будут полезны.

    Если статья была интересна или полезна, плюсаните. Если нет — напишите замечание. Спасибо за внимание.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/338442/


    Метки:  

    оБУЧЕНИНЕ РОБОТОВ ИЛИ ЛЮДЕЙ (страшный рассказ)

    Пятница, 22 Сентября 2017 г. 03:33 + в цитатник
    livandos сегодня в 03:33 Разное

    оБУЧЕНИНЕ РОБОТОВ ИЛИ ЛЮДЕЙ (страшный рассказ)

      Сори за ашипки я двоечник плохо учился в школе.
      Вообщем почитать хотел про обучение роботов ан нет компьютер уже не можеттекст грузить. Кроме сраных картинов к и видеол.ю
      Акраз после после профессорам и 20 венчурным инветорам из пентагона.
      Мой старый копьютерик затормозил.
      И это мой копьютерки предо мной стоимостью в 40 долларов США с кпд в 299%
      Эти люди мне пишут об облаках из пентагона и серетных баз Паловиджа?
      Бред полный.
      Учить робтов конечно легче но имхо им нужны просто задачи. Все эти муоттики и фильмы про роботов на скрипках играющих и рисующих картины
      Во и все господа учите сових выродков дальше.
      Понять вы ничего тут не сможете так как дебилы.
      Эта программа для людей отсталых понимаешь из дурдомов, рожденных с дефектами и брачком. Но все аврно они должны учится и проходить тесты, славать экзамены и получать дипломы, чтобы вешать их на стеночки и опказывать своим выблядкам. :)
      Ps вся статься не охраняется авторским правом можете брать и размещать.
      Original source: habrahabr.ru (comments, light).

      https://habrahabr.ru/post/338448/


      Метки:  

      Раскрутка на развлекательных сайтах, или “Извините, но похоже, что Вы единственный программист в России”

      Четверг, 21 Сентября 2017 г. 23:55 + в цитатник
      Deka87 вчера в 23:55 Разработка

      Раскрутка на развлекательных сайтах, или “Извините, но похоже, что Вы единственный программист в России”

        image
        Все началось в 2012 году. В то время разработкой я только начинал интересоваться, но желание создать что-нибудь полезное (хайпануть) не давало мне покоя. Поиск идей привел меня на сайт www.ssa.gov, где каждый мог проверить наиболее популярное детское имя в США за определенный период. Данная тема меня заинтересовала, но, поскольку молодые семьи — это не самый большой рынок, я решил, что будет интереснее сравнивать популярность имен среди всего населения России. Так и родилась идея сайта names.pp.org (в поcледующем popname.ru), где каждый мог проверить, насколько популярно его имя по сравнению с другими мужскими / женскими именами в РФ.



        Разработчиком в то время я был никудышным, поэтому пришлось как-то выкручиваться. Была скачана база данных самых популярных имен в России и сделан парсинг этих имен по базе данных Вконтакте, чтобы сравнить количество пользователей с тем или иным именем. Нужно заметить, что производные имена (Татьяна — Таня) игнорировались. Поэтому, а также по ряду других причин (средний возраст пользователя Вконтакте, особенно в то время, был явно ниже тридцати) рейтинг получился не совсем (или совсем не) актуальным. Но, как выяснилось позже, пользователей это мало волновало, поскольку они нашли немного другое применение сайту. В итоге на разработку сайта ушло примерно 2 дня. Финальным аккордом была идея добавить немного модифицированную страницу 404, которая сообщала, что “Извините, но похоже, что Вы единственный ХХХ в России. Гордитесь своей уникальностью!”.

        Раскрутка


        Не думаю, что стал первооткрывателем, когда решил раскручивать сайт через развлекательные порталы. Я создал два поста на самых популярных ресурсах в то время (Pikabu и Yaplakal), которые в сумме собрали чуть больше тысячи “лайков”. При этом ссылку на сайт я добавлять не стал и разместил ее только после того, как пользователи спросили адрес сайта в комментариях. Оба поста вышли в топ на каждом из ресурсов, и пошел огромный, по моим меркам, трафик. Скриншоты о том, насколько пользователи уникальны, стали разлетаться по Интернету, и возникло огромное желание монетизировать этот трафик. Adblock в то время еще не был популярен, и, поскольку у меня был опыт работы с Google Adsense, было решено добавить небольшой рекламный блок сразу под поисковой строкой. Главной “фишкой” сайта стали скриншоты, рассказывающие об уникальности их создателя, поэтому я решил не засорять их рекламой хотя бы первые сутки (на то, что рекламу вырежут при помощи консоли разработчика, я не надеялся). Но и ждать дольше я не мог, поскольку популярность сайта неизбежно должна была упасть. В итоге самым плодотворным днем стал третий, когда посещаемость сайта достигла 80 000 уникальных пользователей в день, что остается моим личным рекордом и по сей день. Далее трафик пошел на спад и сайт был продал третьим лицам.

        Итог


        После пяти лет забвения, когда посещаемость сайта вертелась на уровне 100 — 200 человек в день, я снова вспомнил о нем, когда мой товарищ прислал мне ссылку на какой-то твит со старым-добрым скриншотом. Я проверил сайт и увидел, что за последний день его посетили около 10 000 человек. После небольшого расследования было выяснена причина неожиданного трафика — статья на сайте Meduza, что стало приятной неожиданностью. Видимо, подросло новое поколение уникальных людей.
        Original source: habrahabr.ru (comments, light).

        https://habrahabr.ru/post/338446/


        Метки:  

        Абстракция сетевого слоя с применением «стратегий»

        Четверг, 21 Сентября 2017 г. 22:51 + в цитатник
        iWheelBuy вчера в 22:51 Разработка

        Абстракция сетевого слоя с применением «стратегий»

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


          Часть 1. Взгляд на существующие подходы


          Для начала из публикации 21 Amazing Open Source iOS Apps Written in Swift взято приложение Artsy. В нем используется популярный фреймворк Moya, на базе которого и построен весь сетевой слой. Отмечу ряд основных недостатков, которые встретил в данном проекте и часто встречаю в других приложениях и публикациях.


          Повторы цепочек преобразования ответа


          let endpoint: ArtsyAPI = ArtsyAPI.activeAuctions
          provider.request(endpoint)
              .filterSuccessfulStatusCodes()
              .mapJSON()
              .mapTo(arrayOf: Sale.self)

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


          Большое количество зависимостей


          Часто для работы с сетью используются фреймворки Alamofire, Moya и др. В идеале приложение должно минимально зависеть от этих фреймворков. Если в поиске по репозитоию Artsy набрать import Moya, то можно увидеть десятки совпадений. Если вдруг проект решит отказаться от использования Moya — очень много кода придется рефакторить.


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


          Общий класс менедежера запросов


          Возможным выходом из ситуации с зависимостями будет создание специального класса, который будет один знать о фреймворках и обо всех возможных способах получить данные из сети. Эти способы будут описаны функциями со строго типизированными входящими и исходящими параметрами, что в свою очередь будет являться контрактом, упомянутом выше, и поможет справиться с проблемой повторов цепочек преобразования ответа. Такой подход тоже достаточно часто встречается. Его применение на практике можно также найти в приложениях из списка 21 Amazing Open Source iOS Apps Written in Swift. Например, в приложении DesignerNewsApp. Выглядит такой класс следующим образом:


          struct DesignerNewsService {
          
              static func storiesForSection(..., response: ([Story]) -> ()) {
                  // parameters
                  Alamofire.request(...).response { _ in
                      // parsing
                  }
              }
          
              static func loginWithEmail(..., response: (token: String?) -> ()) {
                  // parameters
                  Alamofire.request(...).response { _ in
                      // parsing
                  }
              }
          }

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


          Вам знакомо то чувство уныния, когда нужно интегрировать проект с очередным RESTful API? Это когда в очередной раз нужно создавать какой-нибудь APIManager и наполнять его Alamofire запросами… (ссылка)

          Часть 2. Подход, основанный на стратегиях


          Учитывая все недостатки, описанные в 1-й части публикации, я сформулировал для себя ряд требований к будущему слою работы с сетью:


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

          Что получилось в итоге:


          Базовые протоколы сетевого слоя


          Протокол ApiTarget определяет все данные, которые необходимы для формирования запроса (параметры, путь, метод… и др.)


          protocol ApiTarget {
          
              var parameters: [String : String] { get }
          }

          Обобщенный протокол ApiResponseConvertible определяет способ преобразования полученного объекта (в данном случае Data) в объект связанного типа.


          protocol ApiResponseConvertible {
          
              associatedtype ResultType
          
              func map(data: Data) throws -> ResultType
          }

          Протокол ApiService определяет способ отправки запросов. Обычно функция, объявленная в протоколе, принимает замыкание содержащее объект ответа и возможные ошибки. В текущей реализации функция возвращает Observable — объект реактивного фреймворка RxSwift.


          protocol ApiService: class {
          
              func request(with target: T) -> Observable where T: ApiResponseConvertible, T: ApiTarget
          }

          Стратегии


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


          protocol Strategy {
          
              associatedtype ObjectType
              associatedtype ResultType
          }

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


          protocol ApiStrategy {
          
              associatedtype ObjectType
              associatedtype ResultType
          
              static func target(with object: ObjectType) -> AnyTarget
          }

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


          struct AnyTarget: ApiResponseConvertible, ApiTarget {
          
              private let _map: (Data) throws -> T
              let parameters: [String : String]
          
              init(with target: U) where U: ApiResponseConvertible, U: ApiTarget, U.ResultType == T {
                  _map = target.map
                  parameters = target.parameters
              }
          
              func map(data: Data) throws -> T {
                  return try _map(data)
              }
          }

          Вот так выглядит самая примитивная реализация стратегии:


          struct SimpleStrategy: ApiStrategy {
          
              typealias ObjectType = Int
              typealias ResultType = String
          
              static func target(with object: Int) -> AnyTarget {
                  let target = Target(value: object)
                  return AnyTarget(with: target)
              }
          }
          
          private struct Target {
          
              let value: Int
          }
          
          extension Target: ApiTarget {
          
              var parameters: [String : String] {
                  return [:]
              }
          }
          
          extension Target: ApiResponseConvertible {
          
              public func map(data: Data) throws -> String {
                  return "\(value)" // map value from data
              }
          }

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


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


          Использование стратегий и сервиса


          let service: ApiService = ...
          let target = SimpleStrategy.target(with: ...)
          let request = service.request(with: target)

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


          Реализация ApiService


          Как можно было заметить, в данном подходе сетевой фреймворк остался за пределами основной логики построения сервиса. На первых порах его можно не использовать совсем. Например, если в реализации функции map протокола ApiResponseConvertible возвращать mock-объект, то сервис может быть совсем примитивным классом:


          class MockService: ApiService {
          
              func request(with target: T) -> Observable where T : ApiResponseConvertible, T : ApiTarget {
                  return Observable
                      .just(Data())
                      .map({ [map = target.map] (data) -> T.ResultType in
                          return try map(data)
                      })
              }
          }

          Тестовую реализацию и применение протокола ApiService на базе реального сетевого фреймворка Moya можно посмотреть спойлере:


          ApiService + Moya + Реализация
          public extension Api {
          
              public class Service {
          
                  public enum Kind {
          
                      case failing(Api.Error)
                      case normal
                      case test
                  }
          
                  let kind: Api.Service.Kind
                  let logs: Bool
                  fileprivate lazy var provider: MoyaProvider = self.getProvider()
          
                  public init(kind: Api.Service.Kind, logs: Bool) {
                      self.kind = kind
                      self.logs = logs
                  }
          
                  fileprivate func getProvider() -> MoyaProvider {
                      return MoyaProvider(
                          stubClosure: stubClosure,
                          plugins: plugins
                      )
                  }
          
                  private var plugins: [PluginType] {
                      return logs ? [RequestPluginType()] : []
                  }
          
                  private func stubClosure(_ target: Target) -> Moya.StubBehavior {
                      switch kind {
                      case .failing, .normal:
                          return Moya.StubBehavior.never
                      case .test:
                          return Moya.StubBehavior.immediate
                      }
                  }
              }
          }
          
          extension Api.Service: ApiService {
          
              public func dispose() {
                  //
              }
          
              public func request(headers: [Api.Header: String], scheduler: ImmediateSchedulerType, target: T) -> Observable where T: ApiResponseConvertible, T: ApiTarget {
                  switch kind {
                  case .failing(let error):
                      return Observable.error(error)
                  default:
                      return Observable
                          .just((), scheduler: scheduler)
                          .map({ [weak self] _ -> MoyaProvider? in
                              return self?.provider
                          })
                          .filterNil()
                          .flatMap({ [headers, target] provider -> Observable in
                              let api = Target(headers: headers, target: target)
                              return provider.rx
                                  .request(api)
                                  .asObservable()
                          })
                          .map({ [map = target.map] (response: Moya.Response) -> T.ResultType in
                              switch response.statusCode {
                              case 200:
                                  return try map(response.data)
                              case 401:
                                  throw Api.Error.invalidToken
                              case 404:
                                  do {
                                      let json: JSON = try response.data.materialize()
                                      let message: String = try json["ErrorMessage"].materialize()
                                      throw Api.Error.failedWithMessage(message)
                                  } catch let error {
                                      if case .some(let error) = error as? Api.Error, case .failedWithMessage = error {
                                          throw error
                                      } else {
                                          throw Api.Error.failedWithMessage(nil)
                                      }
                                  }
                              case 500:
                                  throw Api.Error.serverInteralError
                              case 501:
                                  throw Api.Error.appUpdateRequired
                              default:
                                  throw Api.Error.unknown(nil)
                              }
                          })
                          .catchError({ (error) -> Observable in
                              switch error as? Api.Error {
                              case .some(let error):
                                  return Observable.error(error)
                              default:
                                  let error = Api.Error.unknown(error)
                                  return Observable.error(error)
                              }
                          })
                  }
              }
          }

          ApiService + Moya + Использование
          func observableRequest(_ observableCancel: Observable, _ observableTextPrepared: Observable) -> Observable> {
              let factoryApiService = base.factoryApiService
              let factoryIndicator = base.factoryIndicator
              let factorySchedulerConcurrent = base.factorySchedulerConcurrent
              return observableTextPrepared
                  .observeOn(base.factorySchedulerConcurrent())
                  .flatMapLatest(observableCancel: observableCancel, observableFactory: { (text) -> Observable> in
                      return Observable
                          .using(factoryApiService) { (service: Api.Service) -> Observable> in
                              let object = Api.Request.Categories.Name(text: text)
                              let target = Api.Strategy.Categories.Auto.target(with: object)
                              let headers = [Api.Header.authorization: ""]
                              let request = service
                                  .request(headers: headers, scheduler: factorySchedulerConcurrent(), target: target)
                                  .map({ Objects(text: text, manual: true, objects: $0) })
                                  .map({ Result(value: $0) })
                                  .shareReplayLatestWhileConnected()
                              switch factoryIndicator() {
                              case .some(let activityIndicator):
                                  return request.trackActivity(activityIndicator)
                              default:
                                  return request
                              }
                          }
                          .catchError({ (error) -> Observable> in
                              switch error as? Api.Error {
                              case .some(let error):
                                  return Observable.just(Result(error: error))
                              default:
                                  return Observable.just(Result(error: Api.Error.unknown(nil)))
                              }
                          })
                  })
                  .observeOn(base.factorySchedulerConcurrent())
                  .shareReplayLatestWhileConnected()
          }

          Вывод


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

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

          https://habrahabr.ru/post/338380/


          Метки:  

          learnopengl. Уроки 3.1(Assimp) + 3.2(класс Mesh)

          Четверг, 21 Сентября 2017 г. 20:10 + в цитатник
          dima19972525 вчера в 20:10 Разработка

          learnopengl. Уроки 3.1(Assimp) + 3.2(класс Mesh)

          • Tutorial
          OGL3

          Assimp


          Во всех уроках, мы, в основном, использовали нашего маленького друга — контейнер, но через некоторое время, даже наши лучшие друзья становятся немного скучными. В большом графическом приложении, обычно присутствуют много моделей, на которые намного приятнее смотреть, чем на наш статичный контейнер. Хотя, в отличие от контейнера, нам будет очень сложно, вручную, определить все вершины, нормали и текстурные координаты таких сложных моделей, как например дом или человекоподобные персонажи. Вместо этого, мы будем имортировать модели в наше приложение; модели, которые были тщательно нарисованы, в 3D редакторах, таких как Blender, 3DS MAX или Maya.



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

          Таким образом, наша работа заключается в анализе этих экспортированных файлов модели и извлечении всей соответствующей информации, чтобы мы могли хранить их в формате, который понимает OpenGL. Однако, распространенная проблема заключается в том, что существуют десятки различных форматов файлов, каждый из которых экспортирует данные модели по-своему уникальному способу. Форматы модели, как .obj от Wavefront содержат только данные модели с незначительной информацией материала, такой как цвет модели или диффузные\бликовые карты, в то время как файлы моделей, на основе XML, чрезвычайно обширны и содержат модели, освещения, много информации о материалах, анимацию и многое другое. Формат obj считается легко анализированным. Рекомендуется ознакомиться со структурой файла, например, на странице в википедии. Это должно дать вам базовые сведения о том, как храниться модель в файле формата obj.

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

          Библиотека для загрузки моделей


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

          При импорте модели, с помощью Assimp, библиотека загружает всю модель в объект сцены (Scene), содержащий все данные импортированной модели. Затем Assimp создает коллекцию узлов, где каждый узел содержит индексы к данным, хранящимся в объекте сцены, каждый узел может иметь потомка. Простая модель структуры Assimp представлена ниже:
          image


          • Все данные модели содержатся в объекте Scene, как и данные о материалах и полигональной сетки. Scene также содержит ссылку на корневой узел (Root node) сцены.
          • Корневой узел (Root node) может иметь потомков (Child node) (как и остальные узлы) и может иметь индексы, которые указывают на данные полигональной сетки, хранящиеся в массиве объекта сцены mMeshes. Массив mMeshes корневого узла содержит конкретные объекты полигональных сеток, а значения в массиве mMeshes у любого потомка являются лишь индексами для выборки из массива сеток корневого узла.
          • Объект полигональной сетки (Mesh) содержит все соответствующие данные, необходимые для отрисовки: вершинные координаты, вектора нормалей, текстурных координаты, грани и информацию о материале объекта.
          • Полигональная сетка (Mesh) содержит несколько граней. Грани (Faces) представляют собой примитивы объекта (треугольники, квадраты, точки). Они содержат индексы вершин, образующие примитивы. Так как у нас имеются вершины и их индексы, отрисовка происходит намного легче благодаря element buffer objects (Hello Triangle)
          • Так же, полигональная сетка содержит индекс на материальный объект (Material), который имеет несколько функций для получения свойств материала.


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

          Mesh — набор вершин и треугольников
          Одна сетка (Mesh) — это минимальный набор данных, необходимый для вывода средствами OpenGL(данные вершин, индексов, материала). Модель же, обычно, состоит из нескольких сеток. При моделировании объектов в специальных программах(Blender, 3D max), художники не создают целую модель из одной формы. Обычно, каждая модель имеет несколько под-моделей\форм, из которых она состоит. Подумайте о человеке, как о модели: художник обычно моделирует голову, конечности, одежду, оружие, все как отдельные компоненты, затем объединив все под-модели, получает исходную.


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

          Сборка Assimp


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

          Несколько проблем появлялись во время сборки Assimp, так что я отмечу их здесь, с их решениями в случае, если кто-либо из вас получит те же ошибки:

          • CMake выдает ошибки о отсутствующих библиотеках DiretX, такие как:
            Could not locate DirectX
            CMake Error at cmake-modules/FindPkgMacros.cmake:110 (message):
            Required library DirectX not found! Install the library (including dev packages)
            and try again. If the library is already installed, set the missing variables
            manually in cmake.

            Нужно установить DirectX SDK, в случае если он не был установлен. Вы можете скачать SDK здесь .
          • Во время установка DirectX SDK выскакивает код ошибки s1023.
            В этом случае вам сначала нужно установить пакет С++, до того как устанавливать SDK,
            как описано здесь.

          • После завершения настройки можно создать файл проекта, открыть его и скомпилировать библиотеки.
          • По умолчанию, Assimp предоставляется в виде динамической библиотеки, поэтому нам нужно включить в проект соответствующую dll с именем assimp.DLL. Можно просто файл библиотеку DLL в ту же папку, где находится исполняемый файл приложения.
          • После компиляции, библиотека и её dll файл будут находится в папках code/Debug или code/Release.
          • Далее просто свяжите файл библиотеки и dll файл с вашим проектом, и убедитесь, что вы не забыли также подключить заголовочные файлы Assimp.

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

          На этом моменте, вы должны были скомпилировать Assimp и внедрить его в ваше приложение.

          Класс Mesh


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

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

          Теперь, мы можем определить структуру вершины:
          struct Vertex {
              glm::vec3 Position;
              glm::vec3 Normal;
              glm::vec2 TexCoords;
          };

          Каждая вершина хранится в структуре Vertex, которая может использоваться для индексации каждой вершины. Помимо структуры Vertex, нам также нужно создать структуру, которая хранит текстурные данные.
          struct Texture {
              unsigned int id;
              string type;
          }; 

          Она хранит id и тип текстуры (диффузная или бликовая).

          Написав структуры, можно начинать писать наш класс:
          class Mesh {
              public:
                  /*  Mesh Data  */
                  vector vertices;
                  vector indices;
                  vector textures;
                  /*  Functions  */
                  Mesh(vector vertices, vector indices, vector textures);
                  void Draw(Shader shader);
              private:
                  /*  Render data  */
                  unsigned int VAO, VBO, EBO;
                  /*  Functions    */
                  void setupMesh();
          };

          Как вы можете видеть, класс не очень сложен. Конструктор принимает все нужные нам данные, в методе setupMesh мы инициализируем буферы, в методе Draw мы будем отрисовывать нашу полигональную сетку. Обратите внимание, что функция отрисовки (Draw), принимает объект шейдера, чтобы мы могли установить соответствующие uniform переменные, до отрисовки.

          Код конструктора довольно прост, мы просто присваиваем аргументам класса, соответствующие аргуметы. Также мы вызываем функцию setupMesh:
          Mesh(vector vertices, vector indices, vector textures)
          {
              this->vertices = vertices;
              this->indices = indices;
              this->textures = textures;
          
              setupMesh();
          }


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

          Инициализация


          Благодаря конструктору, у нас имеется все нужные нам данные, которые мы можем использовать для отрисовки. Однако, нам сначала нужно настроить соответствующие буферы. К этому моменту у вас не должно быть проблем с этими понятиями, но, возможно, мы вас немного удивим как можно передавать данные в буфер, которые находятся в структуре:
          void setupMesh()
          {
              glGenVertexArrays(1, &VAO);
              glGenBuffers(1, &VBO);
              glGenBuffers(1, &EBO);
            
              glBindVertexArray(VAO);
              glBindBuffer(GL_ARRAY_BUFFER, VBO);
          
              glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);  
          
              glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
              glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), 
                           &indices[0], GL_STATIC_DRAW);
          
              // vertex positions
              glEnableVertexAttribArray(0);	
              glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
              // vertex normals
              glEnableVertexAttribArray(1);	
              glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
              // vertex texture coords
              glEnableVertexAttribArray(2);	
              glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
          
              glBindVertexArray(0);
          }  


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

          В С++, у структур есть отличное свойство — их память является последовательной. То есть, если бы мы представили структуру как массив данных, то она содержала бы переменные в том порядке, в котором они определены в самой структуре. Например, если мы наполним структуру Vertex, какими нибудь значениями, то их размещение в памяти будет равной:
          Vertex vertex;
          vertex.Position  = glm::vec3(0.2f, 0.4f, 0.6f);
          vertex.Normal    = glm::vec3(0.0f, 1.0f, 0.0f);
          vertex.TexCoords = glm::vec2(1.0f, 0.0f);
          // = [0.2f, 0.4f, 0.6f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f];


          Благодаря этому свойству, например, если мы применим функцию sizeof к нашей структуре, она вернет размер все аргументов, которые в ней определены. Она должна весить 32 байта
          (8 * 4 — размер 1 float). Мы можем это использовать для функции glBufferData:
          glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices[0], GL_STATIC_DRAW);


          Также мы используем макрокоманду offsetof, которая в качестве первого аргумента принимает структуру, а в качестве второго — имя переменной структуры. А возвращает она смещение в байтах указанной структуры, до переменной, переданной во втором аргументе. Это идеально подходит для определения последнего параметра функции glVertexAttribPointer:
          glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));


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

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

          Отрисовка


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

          Чтобы решить эту проблему, мы примем некоторые соглашения об именовании: каждая диффузная текстура называется texture_diffuseN, а каждая бликовая текстурная карта должна называться texture_specularN, где N-любое число, начиная с 1 до максимального количества разрешенных текстур. Допустим у нас есть 3 диффузные текстуры и 2 бликовые текстуры для конкретной полигональной сетки, мы должны определить их так:
          uniform sampler2D texture_diffuse1;
          uniform sampler2D texture_diffuse2;
          uniform sampler2D texture_diffuse3;
          uniform sampler2D texture_specular1;
          uniform sampler2D texture_specular2;


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

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


          Код метода Draw:
          void Draw(Shader shader) 
          {
              unsigned int diffuseNr = 1;
              unsigned int specularNr = 1;
              for(unsigned int i = 0; i < textures.size(); i++)
              {
                  glActiveTexture(GL_TEXTURE0 + i); // активируем текстурный блок, до привязки
                  // получаем номер текстуры
                  stringstream ss;
                  string number;
                  string name = textures[i].type;
                  if(name == "texture_diffuse")
                      ss << diffuseNr++; // передаем unsigned int в stream
                  else if(name == "texture_specular")
                      ss << specularNr++; // передаем unsigned int в stream
                  number = ss.str(); 
          
                  shader.setFloat(("material." + name + number).c_str(), i);
                  glBindTexture(GL_TEXTURE_2D, textures[i].id);
              }
              glActiveTexture(GL_TEXTURE0);
          
              // отрисовывем полигональную сетку
              glBindVertexArray(VAO);
              glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
              glBindVertexArray(0);
          }  


          Это не самый красивый код, но отчасти в этом виноват С++, так как, например, в нем нет такого преобразования типов, как int в строку. Мы пробегаемся по N-текстурам и определяем присваиваем их типы строковой переменной, что бы затем мы имели преставление, какой номер конкретного типа текстуры. Далее, мы узнаём номер нашего текстурного объекта, ну и наконец, устанавливаем этому текстурному объекту номер, соответствующий активному текстурному блоку и связываем текстуру. Обратите внимание, что мы собираемся хранить текстурные объекты в структуре Material, как обычно мы и делали.

          Обратите внимание, что увеличив диффузные и бликовые счетчики, мы сразу передаем их в stringstream. Правый инкремент в C++ увеличивает значение на 1, но возвращает старое значение.


          Вы можете найти полный код класса Mesh здесь.

          В следующем уроке, мы создадим класс Model, который работает как контейнер, для объектов класса Mesh и фактически реализует интерфейс загрузки Assimp.
          Original source: habrahabr.ru (comments, light).

          https://habrahabr.ru/post/338436/


          Метки:  

          Беседы о Виртуальной реальности. Беседа №2. Практично о Виртуальности

          Четверг, 21 Сентября 2017 г. 18:06 + в цитатник
          ARadzishevskiy сегодня в 18:06 Разное

          Беседы о Виртуальной реальности. Беседа №2. Практично о Виртуальности

          • Tutorial
          Беседу №1 можно освежить в памяти, перейдя по ссылке

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

          III Использование Виртуальной реальности


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

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

          1. Погружение в комфортную иллюзию, придуманную кем-то


          А когда же мы впервые сталкиваемся с ощущениями несуществующего мира? Наверное это все-таки сказки, которые нам читали в детстве. С давних времен, испытывая потребность хотя бы на время убежать от жестокой реальности, в иную: счастливую, справедливую и комфортную, люди придумывали сказки. Хотя справедливости ради, надо заметить, что на некоторых больше действует обратный эффект. Окунаясь в ужасы и страдания, человек вырвавшись обратно в объективную реальность, понимает, что жизнь, по сравнению с прочувствованными ощущениями, не так уж ужасна, а вполне даже сносна, и он еще не плохо устроился, да чего там — повезло просто и все. И даже повзрослев, люди не перестают нуждаться в сказках. Так и тянет добавить сюда фразу «и некоторые козлы этим пользуются…».

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

          Исходя из концепции представленной в первой беседе — модель сказки может выглядеть так



          2. Воссоздание представления о потерянных со временем артефактах и событиях


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

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


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

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

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



          Социальные сети реализуют еще один феномен, который успешно рассматривал в своих трудах американский психиатр Арнольд Людвиг (англ. Arnold M. Ludwig) – это социальная сплоченность, При помощи этого инструмента мир стал меняться гораздо быстрее. В последнее время, это все чаще стало обращаться в оружие, при борьбе кого-то с кем-то. Но эту тему как-то страшно даже поднимать. Когда я писал в свой статье об инструментах создания «Социального организма», меня обвинили в “состряпывании” инструкции по созданию секты. Но и умолчать об этом, я тоже не мог.

          4. Имитация опасных ситуаций для приобретения опыта


          Обратить внимание на проявление еще одного назначения Виртуальной реальности, мене помогла мысль великого философа Фридриха Вильгельма Ницше. Он писал: «Несбывшееся бывает куда важнее случившегося…». А несбывшегося, как мы понимаем, нет и никогда не было и единственная среда его существования – Виртуальная реальность. Именно она позволяет моделировать ситуации и заглядывать за грань обозримого, избегая негативных последствий в реальном мире. Человек приобретает опыт, учась на своих — «чужих» (виртуальных) ошибках. Это избавляет Вас от одной из самых страшных ошибок в жизни — постоянно боятся совершить ошибку. И вы можете как в фильме «День сурка», раз за разом пробовать изменить сюжетную линию и понаблюдать изнутри, к чему это приведет.

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

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

          5. Виртуализация деловых процессов


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

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

          6. Виртуализация взаиморасчетов


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

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

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

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

          7. Резюме раздела


          В итоге у нас получилось выделить следующие необходимости использовать Виртуальную реальность:

          1. Воссоздание представлений о потерянных со временем артефактах и событиях;
          2. Приобретение собственного опыта, основываясь на чужих представлениях, зачастую гипертрофированных, для усиления эффекта;
          3. Создания вокруг себя альтернативного, более комфортного мира, помогающего почувствовать себя счастливее, чем в реальной жизни;
          4. Возможность анонимного общения, позволяющая скрыть свою физическую идентичность, а иногда и духовную. Позволяет притвориться другим человеком, снизить уязвимость;
          5. Моделирование различных опасных ситуаций, которые могли бы происходить в реальной жизни, для предотвращения их негативных последствий в реальном мире и выбора наилучших вариантов решения проблем;
          6. Создание иллюзии, обмана, для того чтобы ввести людей в заблуждение, в каких-то корыстных целях;
          7. Подмена человека в деловых процессах, позволяющая исключить негативные проявления его слабостей и пороков;
          8. Исключение из взаиморасчетов официальных финансовых институтов, для минимизации затрат на их услуги.

          Список литературы
          1. А. В. Россохин, В.Л.Измагурова. Личность в измененных состояниях сознания. Москва: Смысл, 2004 г.
          2. Н.А., Носов. Виртуальная психология. Москва: «Аграф, 2000 г.
          3. А.Ф., Иванов. Об онтологическом статусе виртуальной реальности.
          Original source: habrahabr.ru (comments, light).

          https://habrahabr.ru/post/338250/


          Метки:  

          День открытых дверей «Лаборатории Касперского»: закрываем данные от взлома, открываем новые возможности

          Четверг, 21 Сентября 2017 г. 17:43 + в цитатник
          Выше головы не прыгнешь. Это утверждение вполне описывает карьерные перспективы талантливого специалиста в крупной стабильной компании. Многообещающему сотруднику гарантируют стабильную зарплату и «печеньки за счет заведения», но ограничивают в выборе проекта, спектра решаемых задач и, откровенно говоря, устанавливают потолок роста (выше руководителя направления программист вряд ли сможет подняться). Именно поэтому сегодня молодых айтишников привлекает уже не карьерный рост, а возможность развивать собственные проекты. Читать далее

          https://habrahabr.ru/post/338224/


          Метки:  

          Достижения в глубоком обучении за последний год

          Четверг, 21 Сентября 2017 г. 17:28 + в цитатник
          EdT сегодня в 17:28 Разработка

          Достижения в глубоком обучении за последний год


            Привет, Хабр. В своей статье я расскажу вам, что интересного произошло в мире машинного обучения за последний год (в основном в Deep Learning). А произошло очень многое, поэтому я остановился на самых, на мой взгляд, зрелищных и/или значимых достижениях. Технические аспекты улучшения архитектур сетей в статье не приводятся. Расширяем кругозор!


            1. Текст


            1.1. Google Neural Machine Translation


            Почти год назад Google анонсировала запуск новой модели для Google Translate. Компания подробно описала архитектуру сети — Recurrent Neural Network (RNN) — в своей статье.



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


            image


            2.1. Переговоры. Будет сделка?


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


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


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


            image


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


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




            За последний год рекуррентные сети активно развивали и использовали во многих задачах и приложениях. Архитектуры рекуррентных сетей сильно усложнились, однако по некоторым направлениям похожих результатов достигают и простые feedforward-сети — DSSM. Например, Google для своей почтовой фичи Smart Reply достигла такого же качества, как и с LSTM до этого. А Яндекс запустил новый поисковый движок на основе таких сетей.


            2. Речь


            2.1. WaveNet: генерирующая модель для необработанного аудио


            Сотрудники DeepMind (компания, известная своим ботом для игры в го, ныне принадлежащая Google) рассказали в своей статье про генерирование аудио.


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



            Сеть обучалась end-to-end: на вход текст, на выход аудио. Результат превосходный, разница с человеком сократилась на 50 %.


            image


            Основной недостаток сети — низкая производительность, потому что из-за авторегрессии звуки генерируются последовательно, на создание одной секунды аудио уходит около 1—2 минут.


            Английский: пример


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


            Генерирование голоса: пример


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


            Пример пианино


            Подробности — в статье.


            2.2. Чтение по губам


            Еще одна победа машинного обучения над человеком ;) На этот раз — в чтении по губам.


            Google Deepmind в сотрудничестве с Оксфордским университетом рассказывают в статье «Lip Reading Sentences in the Wild», как их модель, обученная на телевизионном датасете, смогла превзойти профессионального lips reader’а c канала BBC.


            image


            В датасете 100 тыс. предложений с аудио и видео. Модель: LSTM на аудио, CNN + LSTM на видео, эти два state-вектора подаются в итоговую LSTM, которая генерирует результат (characters).


            image


            При обучении использовались разные варианты входных данных: аудио, видео, аудио + видео, то есть модель «омниканальна».


            image


            2.3. Синтезируя Обаму: синхронизация движения губ с аудио


            image


            Университет Вашингтона проделал серьезную работу по генерированию движения губ бывшего президента США Обамы. Выбор пал на него в том числе из-за огромного количества записей его выступления в сети (17 часов HD-видео).


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


            image


            Результат впечатляет. Скоро нельзя будет верить даже видео с президентом ;)


            3. Компьютерное зрение


            3.1. OCR: Google Maps и Street View


            В своих посте и статье команда Google Brain рассказывает, как внедрила в свои Карты новый движок OCR (Optical Character Recognition), с помощью которого распознаются указатели улиц и вывески магазинов.


            image


            image


            В процессе разработки технологии компания составила новый FSNS (French Street Name Signs), который содержит множество сложных кейсов.


            Сеть использует для распознавания каждого знака до четырех его фотографий. С помощью CNN извлекаются фичи, взвешиваются с помощью spatial attention (учитываются пиксельные координаты), а результат подается в LSTM.


            image


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


            3.2. Visual Reasoning


            Существует такой тип задач, как Visual Reasoning, то есть нейросеть должна по фотографии ответить на какой-то вопрос. Например: «Есть ли на картинке резиновые вещи того же размера, что и желтый металлический цилиндр?» Вопрос и правда нетривиальный, и до недавнего времени задача решалась с точностью всего лишь 68,5 %.


            image


            И вновь прорыва добилась команда из Deepmind: на датасете CLEVR они достигли super-human точности в 95,5 %.


            Архитектура сети весьма интересная:


            1. По текстовому вопросу с помощью pretrained LSTM получаем embedding (представление) вопроса.
            2. По картинке с помощью CNN (всего четыре слоя) получаем feature maps (фичи, характеризующие картинку).
            3. Далее формируем попарные комбинации покоординатных slice’ов feature maps (желтые, синие, красные на картинке ниже), добавляем к каждой координаты и текстовый embedding.
            4. Прогоняем все эти тройки через еще одну сеть, суммируем.
            5. Полученное представление прогоняем через еще одну feedforward-сеть, которая уже на софтмаксе выдает ответ.


              image



            3.3. Pix2Code


            Интересное применение нейросетям придумала компания Uizard: по скриншоту от дизайнера интерфейсов генерировать код верстки.


            image


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


            Кода и датасета в open source пока нет, но обещают выложить.





            3.4. SketchRNN: учим машину рисовать


            Возможно, вы видели страничку Quick, Draw! от Google с призывом нарисовать скетчи различных объектов за 20 секунд. Корпорация собирала этот датасет для того, чтобы обучить нейросеть рисовать, о чем Google рассказала в своем блоге и статье.


            image


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


            Исследователи обучили Sequence-to-Sequence Variational Autoencoder (VAE) c использованием RNN в качестве механизма кодирования/декодирования.


            image


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


            image


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


            image


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


            image


            3.5. GAN


            Одна из самых горячих тем в Deep Learning — Generative Adversarial Networks (GAN). Чаще всего эту идею используют для работы с изображениями, поэтому объясню концепцию именно на них.


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


            Схематично это выглядит так:


            image


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


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


            Классический пример результата обучения GAN — картинки спален или лиц.


            image


            image


            Ранее мы рассматривали автокодировщики (Sketch-RNN), которые кодируют исходные данные в латентное представление. С генератором получается то же самое.


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


            image


            Работает все та же арифметика над латентным пространством: «мужчина в очках» минус «мужчина» плюс «женщина» равно «женщина в очках».


            image


            3.6. Изменение возраста лица с помощью GAN


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


            Так поступили авторы статьи «Face Aging With Conditional Generative Adversarial Networks». Обучив машину на датасете IMDB с известным возрастом актеров, исследователи получили возможность менять возраст лица.


            image


            3.7. Фотографии профессионального уровня


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


            Обученный алгоритм прошелся по панорамам Google Street View в поиске лучших композиций и получил некоторые снимки профессионального и полупрофессионального качества (по оценкам фотографов).


            image


            image


            3.8. Синтезирование из текстового описания в изображение


            Впечатляющий пример использования GAN — генерирование картинок по тексту.


            image


            Авторы статьи предлагают подавать embedding текста на вход не только генератору (conditional GAN), но и дискриминатору, чтобы он проверял соответствие текста картинке. Чтобы дискриминатор научился выполнять свою функцию, дополнительно в обучение добавляли пары с неверным текстом для реальных картинок.


            image


            3.9. Pix2pix


            Одна из ярких статей конца 2016 года — «Image-to-Image Translation with Conditional Adversarial Networks» Berkeley AI Research (BAIR). Исследователи решали проблему image-to-image генерирования, когда, например, требуется по снимку со спутника создать карту или по наброску предметов — их реалистичную текстуру.


            image


            Это еще один пример успешной работы conditional GAN, в данном случае condition идет на целую картинку. В качестве архитектуры генератора использовалась UNet, популярная в сегментации изображений, а для борьбы с размытыми изображениями в качестве дискриминатора взяли новый классификатор PatchGAN (картинка нарезается на N патчей, и предсказание fake/real идет по каждому из них в отдельности).


            Авторы выпустили онлайн-демо своих сетей, что вызвало огромный интерес у пользователей.


            image


            Исходный код.


            3.10. CycleGAN


            Чтобы применить Pix2Pix, требуется датасет с соответствующими парами картинок из разных доменов. В случае, например, с картами собрать такой датасет не проблема. Но если хочется сделать что-то более сложное вроде «трансфигурирования» объектов или стилизации, то пар объектов не найти в принципе. Поэтому авторы Pix2Pix решили развить свою идею и придумали CycleGAN для трансфера между разными доменами изображений без конкретных пар — Unpaired Image-to-Image Translation.


            image


            Идея состоит в следующем: мы учим две пары генератор-дискриминатор из одного домена в другой и обратно, при этом мы требуем cycle consistency — после последовательного применения генераторов должно получиться изображение, похожее на исходное по L1 loss’у. Цикличный loss требуется для того, чтобы генератор не начал просто транслировать картинки одного домена в совершенно не связанные с исходным изображением.


            image


            Такой подход позволяет выучить маппинг лошади –> зебры.



            Такие трансформации работают нестабильно и часто создают неудачные варианты:


            image


            Исходный код.


            3.11. Разработка молекул в онкологии


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


            Мы уже подробно писали об этом исследовании тут, поэтому коротко: с помощью Adversarial Auto Encoder (AAE) можно выучить латентное представление молекул и дальше с его помощью искать новые. В результате нашли 69 молекул, половина из которых применяются для борьбы с раком, остальные имеют серьезный потенциал.


            image


            3.12. Adversarial-атаки


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


            image


            Устойчивость достигается с помощью, например, Fast Gradient Sign Method (FGSM): имея доступ к параметрам модели, можно сделать один или несколько градиентных шагов в сторону нужного класса и изменить исходную картинку.


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


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


            image


            Такие манипуляции со знаками тоже не позволяют правильно их распознать.


            image


            Набор статей от организаторов конкурса.


            Уже написанные библиотеки для атак: cleverhans и foolbox.


            4. Обучение с подкреплением


            Reinforcement learning (RL), или обучение с подкреплением, — также сейчас одна из интереснейших и активно развивающихся тем в машинном обучении.


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


            image


            RL активно применяют в играх, роботах, управлении системами (трафиком, например).


            Разумеется, все слышали о победах AlphaGo от DeepMind в игре го над лучшими профессионалами. Статья авторов была опубликована в Nature «Mastering the game of Go». При обучении разработчики использовали RL: бот играл сам с собой для совершенствования своих стратегий.


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


            В предыдущие годы DeepMind научился с помощью DQN играть в аркадные игры лучше человека. Сейчас алгоритмы учат играть в более сложные игры типа Doom.


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


            Deepmind в своем блоге рассказывает о том, что введение дополнительных loss’ов (auxiliary tasks, вспомогательных задач), таких как предсказание изменения кадра (pixel control), чтобы агент лучше понимал последствия действий, существенно ускоряет обучение.



            Результаты обучения:





            4.2. Обучающиеся роботы


            В OpenAI активно исследуют обучение человеком агента в виртуальной среде, что более безопасно для экспериментов, чем в реальной жизни ;)


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


            image


            Эх, если бы с людьми было так просто ;)


            4.3. Обучение на человеческих предпочтениях


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


            image



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


            image


            4.4. Движение в сложных окружениях


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


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


            image


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







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


            5. Прочее


            5.1. Охлаждение дата-центра


            В июле 2017-го Google рассказала, что воспользовалась разработками DeepMind в машинном обучении, чтобы сократить энергозатраты своего дата-центра.


            На основе информации с тысяч датчиков в дата-центре разработчики Google натренировали ансамбль нейросетей для предсказания PUE (Power Usage Effectiveness) и более эффективного управления дата-центром. Это впечатляющий и значимый пример практического применения ML.


            image


            5.2. Одна модель на все задачи


            Как вы знаете, обученные модели плохо переносятся от задачи к задаче, под каждую задачу приходится обучать/дообучать специфичную модель. Небольшой шаг в сторону универсальности моделей сделала Google Brain в своей статье «One Model To Learn Them All».


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


            image


            Для достижения этой цели сделали сложную архитектуру сети с различными блоками для обработки разных входных данных и генерирования результата. Блоки для encoder/decoder делятся на три типа: сверточные, attention, gated mixture of experts (MoE).


            image


            image


            Основные итоги обучения:


            • получились почти совершенные модели (авторы не делали тонкой настройки гиперпараметров);
            • происходит передача знаний между разными доменами, то есть на задачах с большим количеством данных производительность будет почти такой же. А на маленьких задачах (например, на парсинге) — лучше;
            • блоки, нужные для разных задач, не мешают друг другу и даже иногда помогают, например, MoE — для Imagenet-задачи.

            Кстати, эта модель есть в tensor2tensor.


            5.3. Обучение на Imagenet за один час


            В своем посте сотрудники Facebook рассказали, как их инженеры смогли добиться обучения модели Resnet-50 на Imagenet всего за один час. Правда, для этого потребовался кластер из 256 GPU (Tesla P100).


            Для распределенного обучения использовали Gloo и Caffe2. Чтобы процесс шел эффективно, пришлось адаптировать стратегию обучения при огромном батче (8192 элемента): усреднение градиентов, фаза прогрева, специальные learning rate и тому подобное. Подробнее в статье.


            В итоге удалось добиться эффективности 90% при масштабировании от 8 к 256 GPU. Теперь исследователи из Facebook могут экспериментировать еще быстрее, в отличие от простых смертных без такого кластера ;)


            6. Новости


            6.1. Беспилотные автомобили


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


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


            Также совсем недавно беспилотным автомобилям разрешили колесить по всем штатам США.


            6.2. Здравоохранение


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


            image


            Deepmind создал даже отдельное подразделение.


            image


            В этом году в рамках Data Science Bowl был проведен конкурс по предсказанию рака легких через год на основе подробных снимков, призовой фонд — один миллион долларов.


            6.3. Инвестиции


            Сейчас много и усердно инвестируют в ML, как до этого — в BigData.


            КНР вкладывает 150 млрд долларов в AI, чтобы стать мировым лидером индустрии.


            Для сравнения, в Baidu Research работает 1300 человек, а в том же FAIR (Facebook) — 80. На последнем KDD сотрудники Alibaba рассказывали про свой parameter server KungPeng, который работает на 100 миллиардных выборках при триллионе параметров, что «становится обычной задачей» (с).


            image




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

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

            https://habrahabr.ru/post/338248/


            Метки:  

            Uptime day 2: российские ИТ-компании расскажут о том, как справляются с катастрофами

            Четверг, 21 Сентября 2017 г. 17:19 + в цитатник
            eapotapov сегодня в 17:19 Администрирование

            Uptime day 2: российские ИТ-компании расскажут о том, как справляются с катастрофами

              Через три недели, в пятницу, 13-го, в коворкинге Deworkacy в Москве пройдет уже вторая конференция сообщества Uptime, тема которой — аварии в ИТ-инфраструктуре. Мест всего 300, участие бесплатное — под катом есть ссылка на регистрацию.

              image

              Немного истории


              Идея назвать так конференцию (и сообщество) пришла нам в одно и то же время с ребятами из Code&Supply в Питтсбурге. Их домен uptime.events зарегистрирован 28 марта 2017, наш uptime.community — 14 марта. Первая наша конференция состоялась в апреле, смотрите видеозаписи.

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

              image

              Что будет на Uptime day 2


              Итак, 13 октября в Москве мы обсудим ИТ-катастрофы, которые случались в жизни сотрудников Badoo, Carprice, «Ревизиума», ITSumma, «Битрикс24».

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

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

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

              Рассмотрим такие процессы:
              1. Фиксация того, как взаимодействуют между собой участники команды во время устранения аварии.
              2. Создание и анализ пост-мортемов аварий.
              3. Разработка рекомендаций и регламентов для нас и для клиентов.
              4. Разработка программного обеспечения для менеджмента инцидентов.
              5. Внедрение результатов анализа в ежедневные процедуры разработки и поддержки.

              Пятница, 13-е — отличный день, чтобы поговорить о катастрофах. Участие бесплатное, регистрируйтесь.
              Original source: habrahabr.ru (comments, light).

              https://habrahabr.ru/post/338432/


              Метки:  

              REQ Labs 2017. Онлайн-конференция для бизнес- и системных аналитиков

              Четверг, 21 Сентября 2017 г. 17:13 + в цитатник
              Evgenia_s5 вчера в 17:13 Разное

              REQ Labs 2017. Онлайн-конференция для бизнес- и системных аналитиков

                Уважаемые коллеги, приглашаем вас принять участие в четвёртой онлайн-конференции посвящённой бизнес- и системному анализу REQ Labs 2017. Формат мероприятия остаётся прежним, мы делимся своим опытом, вы задаёте свои каверзные вопросы.

                30 сентября с 11:30 до 18:00 по московскому времени представим на ваш суд четыре презентации:

                • Павел Цытович расскажет о разработке языка описания предметной области на этапе сбора и анализа требований;
                • Вместе с Дмитрием Приймаком разберёмся в вопросе, какие качества важны для современного аналитика с точки зрения BABOK;
                • Ксения Вигандт поделится опытом в области создания автоматизированных тестов для оценки знаний системных аналитиков;
                • Кирилл Барабанов расскажет как разрабатывались требования DWH/BI для Capital Markets IT.


                6 октября в 10:30 по московскому времени, в качестве дополнения к конференции, состоится семинар Елены Рожковой — «Техники по работе со сложными клиентами».

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

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

                https://habrahabr.ru/post/338430/


                Метки:  

                Три идеи, как повысить эффективность разработки: итоги хакатона по Machine Learning в СберТехе

                Четверг, 21 Сентября 2017 г. 16:54 + в цитатник
                Sberbank сегодня в 16:54 Разработка

                Три идеи, как повысить эффективность разработки: итоги хакатона по Machine Learning в СберТехе

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

                  Участникам предложили разработать решения на Machine Learning, которые помогали бы предсказывать сроки выполнения доработок и критичность багов. Эти решения могли бы повысить эффективность разработки в СберТехе, в том числе:

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

                  Лучшие идеи участников планируется внедрить в СберТехе уже в ближайшее время.

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

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

                  Задача решалась на основе данных из Jira внутренней и внешней рабочих сетей, а также из ЦУП (внутренняя автоматизированная система по управлению проектами). Если дата-сеты из Jira представляли собой текстовые поля с историей и вложениями, то в ЦУП хранилась более специфичная информация, используемая для планирования изменений.

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

                  Железо

                  Если в знаниях и навыках коллег мы почти не сомневались, то мощность настольных компьютеров, мягко говоря, не запредельна. Поэтому дополнительно по запросу предоставлялся небольшой Hadoop-кластер. Конфигурация кластера (80 CPU, 200 ГБ, 1,5 ТБ) напоминает одноюнитовый сервер с упором на вычисления, но нет, это все-таки кластер, развернутый в Openstack-е.

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

                  В Лаборатории Данных был задействован JupyterHUB, создававший отдельные инстансы JupyterNotebook. А чтобы можно было работать с параллельными вычислениями, с помощью Cloudera parcels мы добавили в Jupyter несколько вариантов kernel-ов с разными наборами python-библиотек.

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

                  I место — автообработка багов


                  Цель: Создание pipeline автообработки багов в проектах Сбербанк-Технологии.
                  Авторы решения: Анна Рожкова, Павел Швец и Михаил Баранов (Москва)

                  В качестве исходных данных команда использовала отзывы клиентов мобильного приложения Сбербанк Онлайн из Google Play и AppStore, а также информацию о багах из Jira.



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

                  • обновления
                  • антивирус (рут, прошивка)
                  • смс и платежи

                  В отдельную категорию попали люди, писавшие, что «все плохо».

                  С помощью агломеративной иерархической кластеризации команда разделила отзывы по клиентским проблемам (преимущество такого подхода — возможность добавления экспертного мнения, к примеру, когда отзывы о целях и вкладах можно отнести к одному кластеру). Так, например, один из выделенных кластеров объединил проблемы со входом на устройстве Asus Zenfone 2 (период между появлением первых отзывов о проблеме и регистрацией бага в Jira составил 16 дней).



                  Участники предложили максимально сократить время реагирования на проблемы пользователей, сделав онлайн-обработку отзывов с автосозданием багов по выделенным кластерам, используя преимущество банка — большое количество неравнодушных клиентов (1500 отзывов в день). В ходе работы удалось добиться accuracy = 86% и precision = 88% при определении негативных отзывов.

                  Еще одно решение команды — визуализация процессов в разработке. Кейс был разобран на примере Сбербанк Онлайн Android (ASBOL).



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

                  Дополнительно участники попробовали разобрать проблему автоматической приоритизации багов с использованием логистической регрессии и наивного байесовского классификатора. Для этого была определена важность бага по его описанию, наличию вложений и другим характеристика. Однако модель показала результат accuracy = 54% при кросс-валидации на 3-х фолдах – на момент сдачи работ не пригодный для внедрения прототип.

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

                  Презентация команды

                  II место — оптимизация производственных процессов


                  Автор решения: Антон Баранов (Москва)
                  Задачи:

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

                  Антон работал с багами из Jira. Дата-сет включал информацию о более чем 67 000 багов в статусе «завершен» с 2011 по 2017 год. Поиск решения поставленных задач он вел с помощью библиотек языка Python и других ML-библиотек.



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



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

                  Презентация участника

                  III место: прогнозирование рисков


                  Автор решения: Николай Желтовский (Иннополис)

                  Цель: Создание системы прогнозирования на основе нейронной сети для минимизации рисков при управлении ИТ-проектами.

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

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



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



                  Нейронная сеть предсказывает некоторые критические события с точностью 91-94%. Например, повторное открытие задачи. Дата закрытия задачи предсказывается с отклонением от 0 до 37 дней сразу после её создания. На более поздних этапах, когда проведены какие-либо работы по задаче, максимальное отклонение составляет не более недели.



                  Презентация участника
                  Original source: habrahabr.ru (comments, light).

                  https://habrahabr.ru/post/338426/


                  Метки:  

                  Новая операция кибершпионажа FinFisher: атаки MitM на уровне провайдера?

                  Четверг, 21 Сентября 2017 г. 16:40 + в цитатник
                  esetnod32 сегодня в 16:40 Администрирование

                  Новая операция кибершпионажа FinFisher: атаки MitM на уровне провайдера?

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



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

                    Заражение целей


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

                    Новое и наиболее тревожное в последних кампаниях FinFisher – появление схемы man-in-the-middle, где указанный «man» с большой долей вероятности находится на уровне интернет-провайдера. Мы видели использование этого вектора в двух странах, где обнаружена последняя версия FinFisher (в остальных пяти странах используются традиционные векторы заражения).

                    Когда пользователь (объект слежки) собирается скачать одно из популярных легитимных приложений, его перенаправляют на версию программы, зараженную FinFisher. Мы видели троянизированные версии WhatsApp, Skype, Avast, WinRAR, VLC Player и некоторых других программ. Важно отметить, что теоретически таким образом можно использовать любое легитимное приложение.

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


                    Рисунок 1. Механизм заражения последними версиями FinFisher

                    Переадресация осуществляется путем подмены легитимной ссылки вредоносной. Модифицированная вредоносная ссылка доставляется в браузер пользователя с помощью кода ответа на статус перенаправления HTTP 307 Temporary Redirect (запрошенное содержимое временно перемещено по новому адресу). Процесс переадресации невидим для пользователя.


                    Рисунок 2. Детальное описание механизма заражения

                    FinFisher: работа вне зоны видимости


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

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


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

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

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


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

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

                    Кто он – man-in-the-middle?


                    Технически можно предположить, что man-in-the-middle участвует в атаке на одном из этапов пути от целевого компьютера до легитимного сервера (как вариант, это может быть скомпрометированная точка Wi-Fi). Однако географическое распределение последних версий FinFisher, обнаруженных ESET, позволяет предположить, что атаки MitM производятся на более высоком уровне, и наиболее вероятный вариант – участие интернет-провайдера (ISP).

                    Это предположение подтверждает ряд фактов. Во-первых, согласно утекшим в сеть материалам, опубликованным WikiLeaks, разработчик FinFisher предлагал решение под названием «FinFly ISP» для развертывания в сетях ISP с функциями, напоминающими те, что нужны для атак MitM. Во-вторых, способ заражения (переадресация HTTP 307) применяется идентичным образом в обеих странах, где происходило заражение. Маловероятно, что данные схемы разработаны и/или предоставлены разными источниками. В-третьих, все пораженные цели в пределах страны используют услуги одного интернет-провайдера. Наконец, тот же метод и формат переадресации используется провайдерами для фильтрации интернет-контента как минимум в одной из этих стран.

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

                    Мой компьютер заражен?


                    Все продукты ESET обнаруживают и блокируют эту угрозу как Win32/FinSpy.AA и Win32/FinSpy.AB. При помощи ESET Online Scanner вы можете проверить компьютер на наличие угрозы и удалить ее при обнаружении. Пользователи ESET защищены автоматически.

                    Индикаторы компрометации


                    Имена обнаружения ESET:
                    Win32/FinSpy.AA
                    Win32/FinSpy.AB

                    Переадресация:
                    HTTP/1.1 307 Temporary Redirect\r\nLocation:\r\nConnection: close\r\n\r\n

                    Список адресов URL, обнаруженных в процессе исследования:
                    hxxp://108.61.165.27/setup/TrueCrypt-7.2.rar
                    hxxp://download.downloading.shop/pcdownload.php?a=dad2f8ed616d2bfe2e9320a821f0ee39
                    hxxp://download.downloading.shop/pcdownload.php?a=84619b1b3dc8266bc8878d2478168baa
                    hxxp://download.downloading.shop/pcdownload.php?a=ddba855c17da36d61bcab45b042884be
                    hxxp://download.downloading.shop/pcdownload.php?a=d16ef6194a95d4c8324c2e6673be7352
                    hxxp://download.downloading.shop/pcdownload.php?a=95207e8f706510116847d39c32415d98
                    hxxp://download.downloading.shop/pcdownload.php?a=43f02726664a3b30e20e39eb866fb1f8
                    hxxp://download.downloading.shop/pcdownload.php?a=cb858365d08ebfb029083d9e4dcf57c2
                    hxxp://download.downloading.shop/pcdownload.php?a=8f8383592ba080b81e45a8913a360b27
                    hxxp://download.downloading.shop/pcdownload.php?a=e916ba5c43e3dd6adb0d835947576123
                    hxxp://download.downloading.shop/pcdownload.php?a=96362220acc8190dcd5323437d513215
                    hxxp://download.downloading.shop/pcdownload.php?a=84162502fa8a838943bd82dc936f1459
                    hxxp://download.downloading.shop/pcdownload.php?a=974b73ee3c206283b6ee4e170551d1f7
                    hxxp://download.downloading.shop/pcdownload.php?a=cd32a3477c67defde88ce8929014573d
                    hxxp://download.downloading.shop/pcdownload.php?a=36a5c94ffd487ccd60c9b0db4ae822cf
                    hxxp://download.downloading.shop/pcdownload.php?a=0ebb764617253fab56d2dd49b0830914
                    hxxp://download.downloading.shop/pcdownload.php?a=f35e058c83bc0ae6e6c4dffa82f5f7e7
                    hxxp://download.downloading.shop/pcdownload.php?a=64f09230fd56149307b35e9665c6fe4c
                    hxxp://download.downloading.shop/pcdownload.php?a=b3cc01341cb00d91bcc7d2b38cedc064
                    hxxp://download.downloading.shop/pcdownload.php?a=5fc0440e395125bd9d4c318935a6b2b0
                    hxxp://download.downloading.shop/pcdownload.php?a=5ca93ad295c9bce5e083faab2e2ac97a
                    hxxp://download.downloading.shop/pcdownload.php?a=f761984bb5803640aff60b9bc2e53db7
                    hxxp://download.downloading.shop/pcdownload.php?a=5ca93ad295c9bce5e083faab2e2ac97a
                    hxxp://download.downloading.shop/pcdownload.php?a=514893fa5f3f4e899d2e89e1c59096f3
                    hxxp://download.downloading.shop/pcdownload.php?a=a700af6b8a49f0e1a91c48508894a47c
                    hxxp://download.downloading.shop/pcdownload.php?a=36a5c94ffd487ccd60c9b0db4ae822cf
                    hxxp://download.downloading.shop/pcdownload.php?a=a700af6b8a49f0e1a91c48508894a47c
                    hxxp://download.downloading.shop/pcdownload.php?a=395ce676d1ebc1048004daad855fb3c4
                    hxxp://download.downloading.shop/pcdownload.php?a=cd32a3477c67defde88ce8929014573d
                    hxxp://download.downloading.shop/pcdownload.php?a=49d6d828308e99fede1f79f82df797e9
                    hxxp://download.downloading.shop/pcdownload.php?a=d16ef6194a95d4c8324c2e6673be7352


                    Образцы (SHA-1)
                    ca08793c08b1344ca67dc339a0fb45e06bdf3e2f
                    417072b246af74647897978902f7d903562e0f6f
                    c4d1fb784fcd252d13058dbb947645a902fc8935
                    e3f183e67c818f4e693b69748962eecda53f7f88
                    d9294b86b3976ddf89b66b8051ccf98cfae2e312
                    a6d14b104744188f80c6c6b368b589e0bd361607
                    417072b246af74647897978902f7d903562e0f6f
                    f82d18656341793c0a6b9204a68605232f0c39e7
                    df76eda3c1f9005fb392a637381db39cceb2e6a8
                    5f51084a4b81b40a8fcf485b0808f97ba3b0f6af
                    4b41f36da7e5bc1353d4077c3b7ef945ddd09130
                    1098ba4f3da4795f25715ce74c556e3f9dac61fc
                    d3c65377d39e97ab019f7f00458036ee0c7509a7
                    c0ad9c242c533effd50b51e94874514a5b9f2219
                    a16ef7d96a72a24e2a645d5e3758c7d8e6469a55
                    c33fe4c286845a175ee0d83db6d234fe24dd2864
                    cfa8fb7c9c3737a8a525562853659b1e0b4d1ba8
                    9fc71853d3e6ac843bd36ce9297e398507e5b2bd
                    66eccea3e8901f6d5151b49bca53c126f086e437
                    400e4f843ff93df95145554b2d574a9abf24653f
                    fb4a4143d4f32b0af4c2f6f59c8d91504d670b41
                    f326479a4aacc2aaf86b364b78ed5b1b0def1fbe
                    275e76fc462b865fe1af32f5f15b41a37496dd97
                    df4b8c4b485d916c3cadd963f91f7fa9f509723f
                    Original source: habrahabr.ru (comments, light).

                    https://habrahabr.ru/post/338422/


                    Метки:  

                    [Из песочницы] IT-работа в Барселоне, кратко не получилось

                    Четверг, 21 Сентября 2017 г. 16:17 + в цитатник
                    Mia_Lebedeva сегодня в 16:17 Разное

                    IT-работа в Барселоне, кратко не получилось

                    Прочитав статью про Прагу и перечитав все комментарии я поняла несколько вещей:

                    1. Мне очень повезло, а могло закончится просто катастрофой;

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

                    Как все началось?


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

                    Муж лениво листал скайп в телефоне и неожидано, поперхнувшись чаем спросил:
                    — А ты хочешь в Барселону?
                    Я: — В отпуск?
                    Муж: — Не, на долго. Мне работу предлогают. Ну что? Нужно сегодня дать ответ, чтоб выслали условия и договор.

                    Хорошенький вопрос. Муж работает на фриланс проектах уже довольно долго. Офис не любит, а я люблю.

                    Я COO (chief operating officer) в одной из топовых украино-американской кампании, предоставляющей в аренду сервера и платформу для рекламных сетей.

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

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

                    Я.

                    Почему?

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

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

                    Условия и предубеждения


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

                    • Нам оплачивают оформление визы (а на тот момент безвиза еще не было).
                    • Нам оплачивают билеты (при чем туда и обратно, на всякий случай).
                    • Нам снимают квартиру на две недели или пока мы не найдем приемлемый вариант но не больше 4 недель.
                    • Нам оформляют NIE (это такой внутренний документ в Испании в котором стоит разрешение на пребывание в стране, в нашем случае по факту работы мужа).
                    • Компания берет на себя обязательства платить налоги и соц страховку и на руки мы получаем чистые.
                    • Компания ведет налоговые отчеты.
                    • Зарплата составляет всего 60% от того что мы запросили изначально, но по факту на 50% больше того, что получала я и на 30%, чем получал муж. По итогу все равно меньше чем сумма наших зарплат, но я надеялась найти работу.

                    Реальность


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

                    В результате мой коллега по работе оформил телефоны на себя и интернет провел на свое имя.

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

                    А вот мед. страховку государственую мы до сих пор ждем (карточки Cat Salut). Приватную оформили в банке. 65 евро с носа (нас 4).

                    Банк Santander таки соизволил открыть нам счета без nie по рабочему контракту мужа и то только потому, что его контора клиент крупный в этом банке.

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

                    Работа в испанской IT кампании


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

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

                    В Барселоне муж уходит на работу в 11, возвращаеться в 5, и обед полтора часа и он имеет права два дня в неделю работать дома, потому что «а почему бы и нет если вам удобно».

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

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

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

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

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

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

                    Немного о деньгах


                    Мы тратим в месяц на еду (я, муж, сын, дочь, и пес) чуть менее чем 300-400 европейского образца денежных единиц. При этом квартира — 900 +100 коммунальные. Телефон +интернет (два номера и роутер) 65 в месяц. Страховка медицинская — 65 за каждого кроме пса. Пес к слову обходится 50-60 евро в месяц + 45 раз в три месяца на стрижку.

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

                    Если вас позовут на пиво, то в 40 вы вложитесь спокойно, конечно мы предпочитаем просто в гости ходить и приглашать, потому как процентов на 50-60 дешевле выходит.

                    Подытожим


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

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

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

                    Еда дешевая, если готовить самим или есть не в 3 звездах.

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

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

                    Медицина на уровне космоса для меня (после украинских поликлиник). Проверено оперциями. Страховка работает.

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

                    https://habrahabr.ru/post/338424/


                    Метки:  

                    RailsClub 2017. Интервью с организатором elixir-lang.moscow Никитой Соболевым

                    Четверг, 21 Сентября 2017 г. 16:06 + в цитатник

                    Метки:  

                    Обзор одной российской RTOS, часть 5. Первое приложение

                    Четверг, 21 Сентября 2017 г. 16:03 + в цитатник
                    EasyLy сегодня в 16:03 Разработка

                    Обзор одной российской RTOS, часть 5. Первое приложение

                      Готова очередная публикация обзора особенностей ОСРВ МАКС. В предыдущей статье мы разбирались с теорией, а сегодня наступило время практики.

                      Часть 1. Общие сведения
                      Часть 2. Ядро ОСРВ МАКС
                      Часть 3. Структура простейшей программы
                      Часть 4. Полезная теория
                      Часть 5. Первое приложение (настоящая статья)
                      Часть 6. Средства синхронизации потоков
                      Часть 7. Средства обмена данными между задачами
                      Часть 8. Работа с прерываниями

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

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

                      Итак, пока нет генератора проектов, берём проект по-умолчанию для своей макетной платы и своего любимого компилятора (я взял ...\maksRTOS\Compilers\STM32F4xx\MDK-ARM 5\Projects\Default) и копируем его под иным именем (у меня получилось ...\maksRTOS\Compilers\STM32F4xx\MDK-ARM 5\Projects\Test1) . Также следует снять со всех файлов атрибут «Только для чтения».

                      image

                      Каталог файлов проекта весьма спартанский.

                      DefaultApp.cpp
                      DefaultApp.h
                      main.cpp
                      MaksConfig.h

                      Файл main.cpp относится к каноническому примеру, файлы DefaultApp.cpp и DefaultApp.h описывают пустой класс-наследник от Application. Файл MaksConfig.h мы будем использовать для изменения опций системы.

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

                      image

                      В свойствах проекта также имеется бешеное количество настроек.

                      image

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

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

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

                      Сделаем класс задачи, которая занимается этим шевелением. Драйверы мы использовать пока не умеем, поэтому будем обращаться к портам по-старинке. Выберем пару свободных портов на плате. Пусть это будут PE2 и PE3. Что они свободны, я вывел из следующей таблицы, содержащейся в описании платы STM32F429-DISCO:

                      image

                      Сначала сделаем класс, шевелящий ножкой PE2, потом — переделаем его на шаблонный вид.
                      Идём в файл DefaultApp.h (как мы помним, это неправильно для реальной работы, но зато наглядно для текста) и создаём класс-наследник от Task. Что туда нужно добавить? Правильно, конструктор и функцию Execute(). Прекрасно, пишем (первая и последняя строки оставлены, как реперные, чтобы было ясно, куда именно пишем):

                      #include "maksRTOS.h"
                      
                      class Blinker : public Task
                      {
                      public:
                      	Blinker (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<<2);
                      			GPIOE->BSRR = (1<<(2+16));
                      		}
                      	}
                      };
                      class DefaultApp : public Application

                      Задача, дёргающая PE2 готов. Но теперь надо

                      • Включить тактирование порта E;
                      • Подключить задачу к планировщику.


                      Где это удобнее всего делать? Правильно, мы уже знаем, что это удобнее всего делать в функции

                      void DefaultApp::Initialize()

                      благо заготовка уже имеется. Пишем что-то, вроде этого:

                      void DefaultApp::Initialize()
                      {
                      	/* Начните код приложения здесь */
                      	
                      	// Включили тактирование порта E
                      	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
                      	
                      	// Линии PE2 и PE3 сделали выходами
                      	GPIOE->MODER = GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0;
                      	
                      	// Подключили поток к планировщику
                      	Task::Add (new Blinker ("Blink_PE2"));
                      	
                      }

                      Шьём в в пла… Ой, а в проекте по умолчанию используется симулятор.

                      image

                      Хорошо, переключаемся на JTAG адаптер (в случае платы STM32F429-DISCO — на ST-Link).

                      image

                      Теперь всё можно залить в плату. Заливаем, подключаем осциллограф к линии PE2, наблюдаем…

                      image

                      Красота! Только быстродействие какое-то низковатое.

                      image

                      Заменяем оптимизацию с уровня 0 на уровень 3

                      image

                      И… Всё перестаёт работать вообще

                      image

                      Пытаемя трассировать — по шагам прекрасно работает. Что за чудо? Ну, это не проблемы ОС, это проблемы микроконтроллера, ему не нравятся рядом стоящие команды записи в порт (скорее всего, так как частота ядра 168 МГц, а частота шины с портами — 42 МГц). Уж больно оптимизатор всё хорошо умял:

                      0x08004092 6182 STR r2,[r0,#0x18]
                      0x08004094 6181 STR r1,[r0,#0x18]
                      0x08004096 E7FC B 0x08004092


                      Отмечаем этот забавный факт в голове, а код поправим так:


                      то же самое текстом
                      virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<<2);
                      			asm {nop}
                      			GPIOE->BSRR = (1<<(2+16));
                      		}
                      	}
                      };


                      Ну вот, теперь быстродействие стало уже лучше. Как раз практически 42МГц/2

                      image

                      Правда, на другом масштабе нет-нет, да и проскочат вот такие чёрные провалы

                      image

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


                      Текстом
                      class Blinker : public Task
                      {
                      	int m_nBit;
                      public:
                      	Blinker (int nBit,const char * name = nullptr) : Task (name),m_nBit(nBit){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<BSRR = (1<<(m_nBit+16));
                      		}
                      	}
                      };


                      А добавление задач в планировщик — вот так:


                      Текстом
                      void DefaultApp::Initialize()
                      {
                      	/* Начните код приложения здесь */
                      	
                      	// Включили тактирование порта E
                      	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
                      	
                      	// Линии PE2 и PE3 сделали выходами
                      	GPIOE->MODER = GPIO_MODER_MODER2_0 | GPIO_MODER_MODER3_0;
                      	
                      	// Подключили поток к планировщику
                      	Task::Add (new Blinker (2,"Blink_PE2"));
                      	Task::Add (new Blinker (3,"Blink_PE3"));	
                      }


                      Подключаем второй канал осциллографа к выводу PE3. Теперь иногда идут импульсы на одном канале

                      image

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


                      Текстом
                      template 
                      class Blinker : public Task
                      {
                      public:
                      	Blinker (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<BSRR = (1<<(nBit+16));
                      		}
                      	}
                      };


                      И её постановку на планирование — вот так:


                      Текстом
                      	Task::Add (new Blinker<2> ("Blink_PE2"));
                      	Task::Add (new Blinker<3> ("Blink_PE3"));


                      Итак. Теперь иногда импульсы (с правильной частотой) идут на одном канале:

                      image

                      А иногда — на другом

                      image

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

                      image

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

                      image

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

                      public:
                      	Funny (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			Delay (5);
                      			CpuDelay (5);
                      		}
                      	}
                      };

                      И добавим её в планировщик с более высоким приоритетом


                      Текстом
                      	Task::Add (new Blinker<2> ("Blink_PE2"));
                      	Task::Add (new Blinker<3> ("Blink_PE3"));
                      	Task::Add (new Funny ("FunnyTask"),Task::PriorityHigh);


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

                      image

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

                      image

                      Убираем работу этой ужасной задачи. Продолжать будем с двумя основными
                      Task::Add (new Blinker<2> («Blink_PE2»));
                      Task::Add (new Blinker<3> («Blink_PE3»));

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


                      Текстом
                      class Blinker : public Task
                      {
                      public:
                      	Blinker (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<BSRR = (1<<(nBit+16));
                      			Delay (5);
                      		}
                      	}
                      };


                      Тепрерь подключаем амперметр. Для платы STM32F429-DISCO надо снять перемычку JP3 и включить прибор вместо неё, о чём сказано в документации:

                      image

                      Измеряем ток, потребляемый данным вариантом программы

                      image

                      Идём в файл MaksConfig.h и добавляем туда строку:
                      #define MAKS_SLEEP_ON_IDLE 1

                      image

                      Собираем проект, «прошиваем» результат в плату, смотрим на амперметр:

                      image

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

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


                      Текстом
                      class DefaultApp : public Application
                      {
                      public:
                      	DefaultApp() : Application (false){}
                      private:
                      	virtual void Initialize();
                      };


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


                      Текстом
                      template 
                      class Blinker : public Task
                      {
                      public:
                      	Blinker (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		while (true)
                      		{
                      			for (int i=0;i<3;i++)
                      			{
                      				GPIOE->BSRR = (1<BSRR = (1<<(nBit+16));
                      				CpuDelay (1);
                      			}
                      			Yield();
                      		}
                      	}
                      };


                      Что там на осциллографе?

                      image

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


                      Текстом
                      class DefaultApp : public Application
                      {
                      public:
                      	DefaultApp() : Application (true){}
                      	virtual ALARM_ACTION OnAlarm(ALARM_REASON reason)
                      	{
                      		while (true)
                      		{
                      			volatile ALARM_REASON r = reason;
                      		}
                      	}		
                      private:
                      	virtual void Initialize();
                      };


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

                      	Blinker (const char * name = nullptr) : Task (name){}
                      	virtual void Execute()
                      	{
                      		CriticalSection cs;
                      		while (true)
                      		{
                      			GPIOE->BSRR = (1<BSRR = (1<<(nBit+16));
                      			Delay (5);
                      		}

                      Запускаем проект на отладку, ставим точку останова на следующую строку



                      после чего запускаем на исполнение (F5). Моментально получаем останов (если не сработало — щёлкаем по пиктограмме «Stop»).



                      В строке, на которой произошёл останов, наводим курсор на переменную reason. Получаем следующий результат:



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

                      https://habrahabr.ru/post/337974/


                      Метки:  

                      Jenkins Pipeline Shared Libraries

                      Четверг, 21 Сентября 2017 г. 16:03 + в цитатник
                      Andrey_V_Markelov сегодня в 16:03 Администрирование

                      Jenkins Pipeline Shared Libraries

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

                        Задача была следующей: есть определенный набор скриптов для развертывания сервисов, которые нужно запускать на каждом сервере каждого дата-центра. Скрипты выполняют серию операций: проверка статуса, вывод из-под load balancer’а, выпуск версии, развертывание, проверка статуса, отправка уведомлений через email и Slack и т.д. Это просто и удобно, но с ростом числа дата-центров и сервисов процесс выкатки новой версии может занять целый день. Кроме того, за некоторые действия отвечают отдельные команды, например, настройка load balancer’а. Также хотелось, чтобы управляющий процессом код хранился в общедоступном репозитории, дабы каждый член команды мог его поддерживать.
                        Решить задачу удалось с помощью Jenkins Pipeline Shared Libraries: этапы процесса разделились визуально на логические части, код хранится в репозитории, а осуществить доставку на 20 серверов стало возможно в один клик. Ниже приведен пример подобного тестового проекта:

                        image

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

                        Создание библиотеки


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

                        image
                        Директория src используется для Java/Groovy классов, которые добавляются в classpath при выполнении Pipeline.
                        Директория vars используется в скриптах, которые определяют глобальные переменные, доступные из Pipeline.

                        Ниже приведен пример Groovy класса
                        @Grab(group = 'org.apache.commons', module = 'commons-lang3', version = '3.6')
                        import org.apache.commons.lang3.StringUtils
                        
                        class Deployer {
                            int tries = 0
                            Script script
                        
                            def run() {
                                while (tries < 10) {
                                    Thread.sleep(1000)
                                    tries++
                                    script.echo("tries is numeric: " + StringUtils.isAlphanumeric("" + tries))
                                }
                            }
                        }
                        

                        В классах можно использовать любые возможности языка: создавать потоки, соединяться по FTP и т.д.
                        Важно:
                        — чтобы выводить в лог консоли из Pipeline, нужно передавать Script;
                        — для импорта библиотек просто используем @Grab.

                        Ниже пример скрипта:
                        #!/usr/bin/env groovy
                        
                        def call(body) {
                            echo "Start Deploy"
                        
                            new Deployer(script:this).run()
                        
                            echo "Deployed"
                            currentBuild.result = 'SUCCESS' //FAILURE to fail
                        
                            return this
                        }
                        

                        В скриптах можно использовать любые возможности языка и также получить переменные сборки и параметры Jenkins.
                        Важно:
                        — Чтобы остановить выполнение достаточно установить значение currentBuild.result = 'FAILURE';
                        — Получить параметры параметризованной сборки можно через переменную env. Например, env.param1.

                        Вот пример репозитория с другими примерами.

                        Подключение репозитория


                        Следующий шаг — добавить наш репозиторий как глобальную библиотеку Pipeline.
                        Для этого в Jenkins нужно перейти: Manage Jenkins -> Configure System (Настроить Jenkins -> Конфигурирование системы). В блоке Global Pipeline Libraries, добавить наш репозиторий, как на картинке ниже:

                        image

                        Создание Pipeline


                        Последний шаг — создать Pipeline.
                        Наш Pipeline будет выглядеть следующим образом:
                        @Library('jenkins-pipeline-shared-lib-sample')_
                        
                        stage('Print Build Info') {
                            printBuildinfo {
                                name = "Sample Name"
                            }
                        } stage('Disable balancer') {
                            disableBalancerUtils()
                        } stage('Deploy') {
                            deploy()
                        } stage('Enable balancer') {
                            enableBalancerUtils()
                        } stage('Check Status') {
                            checkStatus()
                        }
                        

                        Т.е. мы просто добавляем @Library('jenkins-pipeline-shared-lib-sample')_ (не забываем добавить _ в конце) и вызываем наши функции по имени скриптов, например deploy.

                        Наш Pipeline готов.

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

                        Спасибо за внимание!
                        Original source: habrahabr.ru (comments, light).

                        https://habrahabr.ru/post/338032/


                        Метки:  

                        [Перевод] 10 вещей, которые ненавидят UX-писатели

                        Четверг, 21 Сентября 2017 г. 15:47 + в цитатник

                        Метки:  

                        Управление ресурсами при разработке продуктов в машиностроении

                        Четверг, 21 Сентября 2017 г. 15:47 + в цитатник
                        ruslasib сегодня в 15:47 Управление

                        Управление ресурсами при разработке продуктов в машиностроении

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


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





                          Во-первых, проведен анализ ресурсов производства и выявлены следующие: менеджмент, работа руками, работа головой. М (или менеджмент) – это то, что можно делегировать сотрудникам производства. Например, отдать в работу операторам станков с ЧПУ изготовление деталей. Р (работа руками) – это то, что своими руками создает Антон. Например, сваривает стеллаж, проводит испытания на прочность. Г (голова, работа головой) – это работа, связанная с созданием документов, файлов, схем, работа за компьютером.



                          Во-вторых, каждой задаче присвоен буквенно-числовой номер (01М, 03Р, 50Г и т.д.). Буква означает тип ресурса, описанный выше, цифра – порядковый номер проекта в дорожной карте проектов. Чем меньше число – тем важнее проект. В информационной системе в наименовании каждой задачи производства этот номер присутствует. Поэтому можно в пару кликов отсортировать задачи по приоритетам. Таким образом, было сформулировано правило: «Чем выше задача в списке, тем она важнее».



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

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

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



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



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

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

                          3. Искать резервы ресурсов внутри предприятия
                          Задуматься на тему поиска ресурсов внутри предприятия и оптимизации ресурсов пришлось, когда я обнаружил, что у Сергея, нашего технического писателя, на исполнении стоит около 30 задач разного уровня сложности. Это не настолько удивительно, так как одновременно на разных стадиях разработки у нас находится 16 проектов. На ежедневных летучках мне просто приходилось отражать натиск маркетолога, что Сергей занят чем угодно, но только не маркетинговыми задачами. Кроме того, что технический писатель занимался написанием статей в блог компании, разработкой инструкций по эксплуатации, SMM, на его мужские плечи легла обязанность разработки инструкций по упаковке продукта. При том, что фактически же при разработке инструкций по упаковке Сергей работал, как это мы называем, печатной машинкой – он всего лишь сводил в один файл информацию, полученную с участка упаковки. Эта обезьянья работа сводила на нет профессиональные возможности нашего техписа.

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

                          Давайте посмотрим на результаты:
                          — число задач по проектам у технического писателя сократилось до 4;
                          — высвободилось время на SMM и маркетинг;
                          — время на разработку инструкций по упаковке сократилось в несколько раз за счет того, что заниматься ими стали люди на местах. Здесь я руководствовался следующим принципом японских производств: «Если хочешь решить проблему, иди в гемба [рабочее место], где эта проблема возникла». Другими словами, люди которые работают по инструкциям, лучше знают, как эта инструкция должна выглядеть. Поэтому и разработка инструкций стала занимать меньше времени.

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

                          4. Разрабатывать и внедрять регламенты
                          Как говорят японцы: «Всякий раз, когда в текущем процессе появляются отклонения, надо задать следующие вопросы: «Это случилось потому, что у нас не было стандарта? Это случилось потому, что мы не следовали стандарту? Это случилось потому, что стандарт не был адекватным?» (Гемба кайдзен: Путь к снижению затрат и повышению качества; Масааки Имаи).

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

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

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

                          На настоящий момент все процессы, схемы рисуются в обычном документе excel. В будущем планируем все эти процессы перенести в bpm-систему.



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

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

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

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

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

                          Соответственно, чтобы переработать старые продукты, нужно затратить дополнительные (и не малые) ресурсы. Как мы подсчитали – это работа на несколько месяцев. И мы за нее взялись. Задачи по переработке продуктов ставятся так же, как и проектные задачи, выносятся на доску канбан. Это добавляет прозрачности в использовании ресурсов. Нами взято за правило, что одновременно в переработке находится только один проект.

                          Таким образом, стремимся к тому, чтобы любая задача должна быть учтена.

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

                          https://habrahabr.ru/post/338418/


                          Метки:  

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

                          Четверг, 21 Сентября 2017 г. 15:45 + в цитатник
                          Yota4All сегодня в 15:45 Разное

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

                            image

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

                            Конструктор Yota во многом не похож на другие предложения, существующие на российском рынке. Более того, подобный подход к формированию пакета услуг выглядит необычным даже для зарубежных операторов. В России раньше операторы продавали всё «поштучно»: минуты голосовой связи, десятки или сотни SMS, и так далее. Потом все перешли на пакеты. В других же странах есть свои особенности «упаковки».

                            Мы поинтересовались, как формируются тарифы на связь в разных странах.

                            Европа и Европейский союз

                            image

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

                            С 15 июня 2017 года на территории Евросоюза на межгосударственном уровне отменили плату за роуминг. Жители могут путешествовать по территории 28 государств с ценами оператора своего домашнего региона. На законодательном уровне было установлено, что минута мобильного общения между странами ЕС не может быть дороже 0,35 евро, а цена SMS не может превышать 0,11 евро.

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

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

                            Большая конкуренция и общее правовое поле привели к интересным метаморфозам. Появилось огромное количество различных тарифных планов от сотен операторов. По количеству действующих виртуальных операторов Европа занимает лидирующие позиции в мире — около 600 операторов связи (59% от мирового показателя). И это число даже не учитывает «дочерние» компании и бренды основных сотовых операторов — Telefonica O2, Vodafone и T-Mobile.

                            Львиная доля всех виртуальных операторов сосредоточена в пяти странах: на долю Германии, Великобритании, Нидерландов, Франции и Испании приходится как самая большая конкуренция, так и максимальный выбор различных тарифных планов. Главное преимущество «виртуалов» — низкая цена. Виртуальные операторы отказываются от традиционных офисов, осуществляя обслуживание через сайт. Здесь можно заказать SIM-карту и получить её с доставкой на дом. Виртуальные операторы также предлагают интересные тарифы на день, неделю или месяц. После завершения срока тарифа карта заблокируется, а вы не потратите лишние деньги.

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

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

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

                            Есть предоплатные тарифные планы (например, у Lebara), специально созданные для международных звонков, в том числе в Россию. Другие тарифы рассчитаны на активных пользователей интернета — у Meteor в отдельных тарифных планах не учитывается трафик соцсетей и мессенджеров. Однако тут есть хитрая особенность: в мессенджерах бесплатно вы можете только обмениваться сообщениями, но не звонить через них.

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

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

                            США

                            image

                            Как мы уже упоминали в предыдущей статье, в США связь стоит очень дорого. На тарифах за 30-40 долларов вы получите лимит трафика 2-4 Гб. Однако есть возможность подключить безлимитный тариф — у T-Mobile за 75 долларов в месяц. Это еще не самый дорогой тарифный план, дороже стоят те, которые предназначены для звонков по всему миру. Единственный способ сэкономить — выбрать пакет услуг сразу для всей семьи. Подключив несколько SIM-карт разом, можно выгадать 10-20 долларов в месяц.

                            Все основные операторы связи — T-Mobile, Verizon, AT&T, Sprint — предлагают очень похожие тарифы, разница заключается лишь в месячном объеме мобильного интернета. К каждому тарифу можно дополнительно подключить роуминг, международные звонки, SMS, а также некоторые уникальные услуги.

                            T-Mobile остается одним из самых прогрессивных операторов в стране. Именно он представил первый в мире безлимитный интернет в роуминге. Ограничением стала лишь скорость: оператор принудительно подключал абонентов в роуминге только к сетям 2G.

                            В 2017 году даже при лимитированном доступе к сети T-Mobile предлагает опцию Music Freedom, по которой предоставляется бесплатный трафик из популярных стриминговых музыкальных сервисов.

                            T-Mobile предлагает не просто тарифные планы, а приложения, внутри которых «завернут» какой-либо тариф. Так, в приложении Binge On сделан стриминг видео c Amazon, YouTube, HBO, Netflix и множества других сайтов. У вас может быть любой тарифный план, но установив одно приложение Binge On, вы бесплатно получите дополнительные услуги в рамках уже оплаченных. В этом случае оператор получит возможность транслировать вам дополнительно рекламу через приложение.

                            Африка

                            image

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

                            В таких условиях никак нельзя обойтись без устойчивой связи. Крупнейший мобильный оператор Южной Африки Vodacom предлагает как контрактные предложения, так и предоплаченные тарифы. На сайте можно кастомизировать свой пакет индивидуально для каждого пользователя. В предоплаченных предложениях пользователям доступны различные варианты пакетов голосовых вызовов. Как правило, голосовая связь оплачивается поминутно, и есть возможность выбрать самый удобный по цене тариф. Также можно выбрать количество трафика. Пользователь оплачивает пакет из необходимого ему мегабайтов или гигабайтов, а превышение трафика оплачивается дополнительно. Например, в пакете с 0,79 центов (примерно 3,5 р.) за минуту разговора внутри сети каждый мегабайт обойдется в 20 центов.

                            Интересная особенность — наличие у некоторых операторов (например, у Orange Egypt) роуминга внутри домашнего региона. В тарифном плане Baladna ElGedeed низкая цена на звонки существует только для регионов вне Каира и Александрии. В «опасных» зонах цена вырастет на 30%.

                            Южная Америка

                            image

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

                            Другие регионы

                            image

                            В Китае есть два основных оператора: China Mobile (крупнейший оператор мобильной связи в мире, у которого 833 миллиона абонентов) и China Unicom. China Mobile может похвастаться отличным покрытием сети даже в самых отдаленных деревнях. Молодая аудитория отдает предпочтение оператору China Unicom, так как он делает ставку на развитие мобильного интернета и предлагает более выгодные тарифы для интернет-пользователей.

                            В Израиле HOT Mobile и Golan Telecom часто предлагают самые выгодные тарифные планы только для новых клиентов. Однако такие предложения действуют на ограниченный период времени.

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

                            В Индонезии ведущий оператор Telkomsel разделил интернет-трафик и звонки/SMS по разным тарифным планам. Более того, сам пакет интернет-трафика делится на две независимые услуги с разной ценой: 4G и 3G. А Dialog на Шри-Ланке дополнительно делит трафик на дневной и ночной: половину вы можете израсходовать только днем, а вторую половину — ночью.

                            В ОАЭ оператор DU включил в некоторые тарифные планы необычные бонусы — бесплатную поездку на Uber, бесплатные билеты в развлекательные центры, катание на лодке с ужином и другие.
                            Original source: habrahabr.ru (comments, light).

                            https://habrahabr.ru/post/338414/


                            Метки:  

                            ИТ против ИИ: отберут ли машины работу у своих создателей?

                            Четверг, 21 Сентября 2017 г. 15:18 + в цитатник
                            Разговоры о том, что системы искусственного интеллекта рано или поздно вытеснят людей из ряда профессий, ведутся уже не первый десяток лет. Роботы проникают в медицину, тяжелую промышленность, решают сложные аналитические и творческие задачи. А издание The Guardian не так давно сообщило, что одна из японский страховых компаний сократила часть сотрудников, заменив их системой Watson Explorer от IBM, которая, по предположениям менеджмента, должна оказаться на 30% продуктивнее людей.

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

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

                            В этом материале:

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

                            Читать дальше ->

                            https://habrahabr.ru/post/338410/


                            Метки:  

                            Поиск сообщений в rss_rss_hh_new
                            Страницы: 1437 ... 1154 1153 [1152] 1151 1150 ..
                            .. 1 Календарь