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

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

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

Мультиформатные баннеры в Tinkoff.ru и подход к верстке адаптивных баннеров в Google AdWords

Четверг, 21 Сентября 2017 г. 15:09 + в цитатник
AndreyIvanoff сегодня в 15:09 Маркетинг

Мультиформатные баннеры в Tinkoff.ru и подход к верстке адаптивных баннеров в Google AdWords

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

    image

    Реализация мультиформатного баннера, шаблон Leaderboard 1.

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

    Тот, кто хоть раз имел дело с запуском медийных рекламных кампаний по технологии RTB (англ. Real Time Bidding), сталкивался с проблемой: клиент предоставил для размещения баннер формата 240x400 и на этом всё. Однако стандарты IAB предусматривают как минимум 15 разных форматов: Leaderboard (728x90), Inline rectangle (300x250), Mobile leaderboard (320x50), Half-page (300x600), Banner, Large rectangle и другие.

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

    Сколько форматов баннеров в RTB-трафике


    Их очень много: по данным рекламной платформы DataMind, на конец 2016 года — около 1700 форматов, количество потенциальных показов по которым превышает 100 тысяч в месяц.

    Ниже представлена диаграмма распределения трафика между размерами рекламных блоков. Чем больше точка, тем больше трафика на нее приходится. В топ выходят всем известные форматы: 320x50, 240x400, 728x90, 300x250. Но для проведения масштабной рекламной кампании этих форматов оказывается недостаточно.

    image

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

    Если рекламная кампания запускается только с одним баннером формата 240x400, рекламодатель охватывает только 17,22% от всего доступного трафика. А если подготовить рекламные материалы для всех IAB-форматов, охват увеличится до 77,2%.


    Распределение рекламного трафика по форматам баннеров. 22,8% рекламных показов возможны для форматов, которые не включены в стандарт IAB

    Но что делать, если хочется получить все 100% и еще сэкономить? Не каждый рекламодатель будет делать баннер формата, например, 800x90, поэтому и аукцион для этого формата будет менее «горячим» по сравнению с аукционом для формата 240x400.

    Универсальная классификация рекламных форматов баннеров


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


    Точечная диаграмма для форматов баннеров с потенциальными показами свыше 100 тысяч в месяц в RTB-трафике для территории России. Классифицированы форматы Towers, Squares, Leaderboards

    Здесь вся плоскость разбита на три больших области:

    • баннеры-башни (Towers);
    • баннеры-квадраты (Squares);
    • баннеры-перетяжки (Leaderboards).

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

    $k_{-2}=\frac{height}{width}=1.78, k_{-1}=\frac{height}{width}=1.33, k_0=\frac{height}{width}= 1,\\ k_{1}=\frac{height}{width}=0.75, k_{2}=\frac{height}{width}=0.56.$

    Нажмите, если формула не отображается.
    image

    Можно обнаружить интересную степенную зависимость, которая, кажется, как-то связана с историческим развитием форматов экранов (См. Соотношение сторон экрана):

    $$display$$\begin{equation} k_{i}=\left(\frac{3}{4}\right)^{i}, i=-2,-1,0,1,2. \end{equation}$$display$$

    Нажмите, если формула не отображается
    image

    Если у вас есть идеи на этот счет, пожалуйста, расскажите о них в комментариях.

    Классификация форматов баннеров на Towers, Squares, Leaderboars интуитивно понятна. Кажется, что достаточно сверстать три HTML-шаблона для каждого формата, и мы сможем отобразить рекламные материалы в рекламном блоке любого размера. Отчасти это так.

    Как устроены адаптивные баннеры AdWords


    Разрабатывая собственную технологию мультиформатных баннеров, мы в Tinkoff.ru решили исследовать технологию, которую использует Google. Оказалось, что она не применяет резиновую верстку в комбинации с media-запросами. Для каждого рекламного блока удаленный и очень хитрый сервис отдает позицию каждого элемента HTML-баннера, по которой элемент жестко фиксируется в рекламном блоке. Нам стало интересно, какой алгоритм используется для адаптации рекламных материалов к рекламному блоку заданного размера.

    Для исследования был «пойман» реальный рекламный мультиформатный баннер с рекламой одного из продуктов Tinkoff.ru. Он был принудительно отображен в блоках разного размера, при этом ширина блока изменялась от 216 до 1 200 px, а высота — от 36 до 1 200 px с шагом в 1 пиксель. Мы провели около 1,145 миллиона наблюдений за поведением верстки мультиформатного баннера при разных значениях ширины и высоты рекламного места. И выявили девять типичных HTML-шаблонов, которые использует Google при отображении баннера. Мы разбили их на три класса и дали им названия:

    • для класса Tower: Tower 1 и Tower 2 (визуально различаются только используемыми шрифтами, поэтому далее не будем выделять Tower 2 отдельно);
    • для класса Square: Square 1, Square 2, Square 3, Square 4;
    • для класса Leaderboard: Leaderboard 1 (пример — на первом рисунке в статье), Leaderboard 2, Leaderboard 3.

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


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

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

    Обработка результатов наблюдений


    Алгоритм выбора шаблона в зависимости от размера рекламного блока устанавливается просто, если использовать деревья решений. Мы использовали Recursive Partitioning and Regression Trees из R-пакета rpart со следующим набором фич:

    • Площадь рекламного блока $S = width \cdot height$;
    • Угол наклона $k = \frac{height}{width}$;
    • Ширина $width$;
    • Высота $height$.

    Нажмите, если формулы не отображаются
    image

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

    на JavaScript
    template_names = ['leaderboard1', 'leaderboard2', 'leaderboard3', 'square1', 'square2', 'square3', 'square4', 'tower1'];
    function getTemplate(w, h) {
      var wdh = w/h,
        wh = w*h;
      if (wdh >= 0.7000456) {
        if (wdh >= 2.499373) {
          if (wh >= 32399) {
            if (wdh >= 4.501131) {
              return template_names[0]; //leaderboard1 - bannerA
            } else {
              return template_names[1]; //leaderboard2 - bannerB
            }
          };
          return template_names[2]; //leaderboard3 - smallBanner
        } else {
          if (wdh < 1.200121) {
            if (wdh >= 0.8999545) {
              if (w < 781.5) {
                if (wh < 32399.5) {
                  return template_names[5];// "square3"; //smallSquare
                } else {
                  return template_names[6];//"square4"; //square191
                }
              } else {
                if (wdh >= 0.9995005) {
                  return template_names[5];//"square3"; //smallSquare
                } else {
                  return template_names[7];//"tower1"; //towerB
                }
              }
            } else {
              if (wh < 32399) {
                  return template_names[5]; //"square3"; //smallSquare
              } else {
                  return template_names[4]; //"square2"; //squareC
              }
            }
          } else {
            if (h< 174.5) {
              if (wdh >= 2.002874 && wh >= 32392.5) {
                return template_names[1];//"leaderboard2"; //bannerB
              }
              return template_names[5];//"square3"; //smallSquare
            } else {
              if (w < 601.5 && wdh < 1.531339) {
                  return template_names[3];//"square1"; //squareA
              }
              return template_names[4];//"square2"; //squareC
            }
          }
        }
      } else {
          return template_names[7];//"tower1"; //towerA + towerB
      }
    }

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

    Схематичное представление шаблонов


    Как же выглядят эти шаблоны для отображения рекламных материалов? Мы представили их в виде схем-таблиц.

    image

    Схематичное представление девяти HTML-шаблонов, используемых в AdWords

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

    image

    Частота присутствия рассмотренных девяти шаблонов в RTB-трафике

    Шаблоны из класса Leaderboard


    Leaderboard 1 — один из самых простых шаблонов. Ассеты — главная картинка, логотип, заголовок, описание, кнопка — располагаются последовательно. Leaderboard 2 — более сложный шаблон, который отображает дополнительную информацию о компании — дополнительный ассет Short Name в схеме-таблице выше. Шаблон Leaderboard 3 часто используется в рекламных блоках на мобильных устройствах. Из-за ограниченного места он анимирует смену заголовка и описания. Сравните реализацию этих шаблонов:
    image
    Leaderboard 1 для рекламного блока 480x70
    image
    Leaderboard 2 для рекламного блока 400x125
    image
    Leaderboard 3 для рекламного блока 400x100. Показан второй кадр с описанием

    Шаблоны из класса Square


    Квадратные шаблоны востребованы меньше всего, но они занимают свою большую долю в 20,35%. Различия между шаблонами Square 1 и Square 4 визуально практически отсутствуют, однако согласно полученному классификатору, на шаблон Square 1 приходится около 0,66% трафика. Почему так происходит, остается загадкой. Возможно, гипербола, которую мы наблюдали выше, — результат работы какого-то адаптивного алгоритма, специфичного для нашего экспериментального баннера.
    image
    image
    image
    image
    Square 1 для рекламного блока 300x300
    Square 2 для рекламного блока 150x215
    Square 3 для рекламного блока 215x250
    Square 4 для рекламного блока 250x250

    Шаблоны из класса Tower


    Мы не нашли существенных различий между шаблонами Tower 1 и Tower 2, поэтому реализовали только первый из них.
    image
    image
    image
    Реализации шаблона Tower

    Использование мультиформатного баннера в RTB


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

    Отдельная проблема сервинга мультиформатных баннеров — создание так называемых заглушек. Часто каждый HTML-баннер должен сопровождаться заглушкой в виде картинки. Она является компаньоном к HTML-баннеру и отображается, если рендеринг HTML5 по каким-то причинам невозможен. Поэтому для каждого формата рекламного блока нужно уметь создавать не только HTML-код, но и соответствующее изображение. Для этого мы используем
    CasperJs. С помощью этого модуля организовано и скриншот-тестирование представленных в статье шаблонов.

    Заключение


    Что дает технология мультиформатных баннеров? В первую очередь она позволяет проводить масштабные A/B-тестирования рекламных слоганов и других ассетов на 100% рекламных блоков разного размера без привлечения дизайнеров. Разнообразную механику многоруких бандитов можно применить для тестирования конкретных вариаций ассетов и самих шаблонов баннеров.

    К сожалению, в AdWords недоступна статистика показов в разрезе рассмотренных шаблонов. Система AdWords выбирает шаблон автоматически, и в этой статье мы попытались разобраться, как она это делает. Нам не удалось определить используемый в AdWords алгоритм выбора размера шрифтов — для каждого шаблона он особенный. Идентифицировать методику фиксации высоты/ширины каждого ассета в шаблоне тоже оказалось крайне сложно. Для этого мы придумали собственное решение, но это уже совсем другая история.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/335952/


    Метки:  

    [Из песочницы] Продажа электронных подписей и сопутствующих услуг

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

    Продажа электронных подписей и сопутствующих услуг

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

    Введение


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

    Расширение бизнеса


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

    1. Документация для регистрации в налоговой;
    2. Документация для открытия расчетного счета (обязательно, если это ООО);
    3. Круглая печать;
    4. Электронная подпись для сдачи отчетности;

    Это самый минимальный список, для нормальной работы нужно гораздо больше. Конечно можно сдавать отчеты почтой (только не НДС), некоторым ИП можно работать без печати, даже счета не открывая, но мы все же о бизнесе, а не о выживании).
    Три первые пункта мы предоставляем клиентам, осталось как то организовать работу с ЭП.

    «Начать может и один человек, без лицензии»


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

    1. Покупка межсетевого экрана и его настройка;
    2. Покупка антивируса;
    3. Покупка охранного оборудования;
    4. Ежемесячные затраты на охрану;

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

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

    Осуществление предпринимательской деятельности без специального разрешения (лицензии), если такое разрешение (такая лицензия) обязательно (обязательна), — влечет наложение административного штрафа:

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

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

    Мы будем просто передавать документы


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

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

    Постановление Правительства РФ от 16.04.2012 N 313 (ред. от 18.05.2017)

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

    22. Передача защищенных с использованием шифровальных (криптографических) средств информационных систем.

    23. Передача защищенных с использованием шифровальных (криптографических) средств телекоммуникационных систем.

    24. Передача средств изготовления ключевых документов.

    С Вами говорит ФСБ


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

    1. Да, лицензия нужна;
    2. Для ее получения нам необходимо обучить всего одного человека;
    3. Необходимые виды деятельности для работы с УЦ "*******" в качестве партнера — 21, 22, 23, 24;

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

    Предпринимателям


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

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

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

    https://habrahabr.ru/post/338408/


    Метки:  

    Пишем для UEFI BIOS в Visual Studio. Часть 2 – создаем свой первый драйвер и ускоряем отладку

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

    Введение


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

    Те, кто заинтересовался — добро пожаловать под кат.
    Читать дальше ->

    https://habrahabr.ru/post/338404/


    Метки:  

    Внедрение Help Desk. 9 типичных заблуждений на этапе выбора. Развеиваем мифы

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

    Внедрение Help Desk. 9 типичных заблуждений на этапе выбора. Развеиваем мифы

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

      • ит аутсорсинг;
      • обслуживание ККТ и другого специализированного оборудования;
      • digital агентства и веб студии;
      • вендоры и разработчики сервисов.

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




      «Мы — слишком маленькие. У нас мало клиентов / заявок»


      Действительно, небольшим компаниям, особенно в начале развития, удобнее не тратить время на внедрение Help Desk систем, не приносящих на данной стадии заметной пользы. Однако при масштабировании важно не упустить тот момент, когда отсутствие системы службы поддержки будет якорем, т.е. когда заявки начнут теряться из-за того, что существующая система учета (будь то бумажный журнал, канал в viber или цепочки писем в ящике электронной почты) перестанет справляться с нагрузкой. По нашей статистике “средняя температура по больнице”, при которой заявки начинают “теряться”, составляет 10-12 обращений в день.
      «Мы стали терять заявки клиентов. В разгар сезона только в течение месяца это привело к потере двух клиентов на абонентском обслуживании в год приносящих нам около 100 тыс. рублей»
      Александр Мишин, директор ООО «Бизнес Технологии»

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

      «Система поддержки пользователей не будет поддерживать текущий рабочий процесс»





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

      Постоянная нехватка времени или рабочих рук для внедрения нового



      Подавляющее большинство компаний среднего и малого бизнеса постоянно «тушат пожары», т.е. время и силы вкладываются туда, где в данный момент «уже горит». При сохранении существующей схемы работы возможностей даже на небольшие преобразования, как организационные, так и ИТ-ландшафта, такой бизнес не найдет никогда. Но именно для них и существуют простые системы службы поддержки. Важно лишь правильно распределить усилия — немного отклониться от принципа “постоянного затыкания дыр” и подумать о перспективах. Зачастую вопрос решается административно: выделяется время и люди на внедрение тех самых простых инструментов, вне зависимости от статуса остальных задач. Важным аргументом в пользу выбора Help Desk решения для таких компаний, несомненно, будет удобный и простой интерфейс, а также отсутствие необходимости серьезных и длительных настроек для старта работы. Например, Okdesk компании запускают в эксплуатацию за 1-2 дня.
      «Долгое время использовали в работе Intraservice, но функционально он перестал отвечать нашим требованиям. Переход на новую систему, как и в случае любой миграции, вызывал опасения: новый интерфейс, новые правила работы, недовольство сотрудников. На Okdesk переход прошел незаметно и был встречен всеми исключительно положительно. Система действительно очень удобная и интуитивно понятная»
      Алексей Теплоухов, директор ООО «Частные решения»

      Нехватка денег на внедрение Help Desk системы




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

      Негативный опыт внедрения в прошлом или боязнь выбора неподходящего “партнера”


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

      Непреодолимые организационные барьеры




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

      «Отсутствие опыта подобных внедрений обязательно приведет к неудаче»


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

      «У нас и так все хорошо!»




      Так бывает, когда руководство спускает задачу выбора и внедрения Help Desk системы на линейных руководителей. Однако и сами собственники в малом бизнесе зачастую отмахиваются от систем автоматизации с таким же обоснованием. Важный (можно сказать даже “философский”) вопрос: ценности у какого-то конкретного инструмента в данном случае действительно нет или ее просто не хотят видеть? По нашему опыту подобная причина отказа возникает тогда, когда серьезно не хватает мотивации на повышение качества и прозрачности работы (а отсюда и саботаж)? Мало ли что выявит новая система?!
      Для объективной оценки нужны метрики. У бизнеса их нет? Это уже повод задуматься о том, не пора ли взяться за эффективность.
      В целом рыночные условия становятся все более жесткими. Конкуренция и так высока, а в дополнение постоянно повышается налоговая нагрузка, да и от инфляции никуда не деться. Единственный способ остаться на плаву в этих условиях — постоянно двигаться вперед, изыскивая новые источники ресурсов. И один из таких источников — оптимизация производительности труда как раз за счет автоматизации.
      «Честно говоря, я искренне желаю, чтобы мои конкуренты и дальше работали с заявками в Excel. Но это желание не реализуемо. Все развивается, в любом случае нужно будет внедрять что-либо, если они хотят дальше находиться на рынке. Количество денег все меньше. В следующем году нам предложат более полно платить налоги (у государства появится возможность детальнее контролировать налогооблагаемую базу). Затраты на налогообложение вырастут, а значит где-то нужно найти резервы. По моим представлениям они есть только в производительности труда»
      Владимир Бачурин, директор «ИННИКО»

      «Уже есть другая система»




      Уже есть какая-то автоматизация. Однако инструмент инструменту рознь. Зачастую для автоматизации того же Help Desk используется электронная почта или Excel, совершенно для этого не предназначенные. Такой инструментарий работает неэффективно. Причем, чем больше масштабы бизнеса, тем серьезнее на результате сказываются недостатки инструмента. И тут мы возвращаемся к предыдущему пункту: а есть ли мотивация работать эффективнее? Если есть, необходимо реформировать набор используемых инструментов, ведь дальше без необходимого функционала будет все сложнее и сложнее. Мы писали об этом в заметке о недостатках Excel как инструмента учета.
      В одной из ближайших статей мы разберем вопросы миграции со специализированной системы.

      Вместо выводов


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

      https://habrahabr.ru/post/338402/


      RAIF-Challenge 2017: онлайн-чемпионат по искусственному интеллекту. Применяем ML/AI на практике

      Четверг, 21 Сентября 2017 г. 14:04 + в цитатник
      В то время как с помощью искусственного интеллекта IBM Watson лучше докторов диагностирует рак, MasterCard и PayPal — отсекают мошеннические операции, а беспилотная техника начала летать наравне с «пилотной», российский бизнес отказывается верить в «великую силу» ИИ. Внедрения успешны — но единичны. Чтобы исправить ситуацию и на практике показать компаниям все возможности подобных технологий, «Инфосистемы Джет» при поддержке «М.Видео», «Альфастрахования» и банка «УРАЛСИБ» с 20 сентября по 25 октября проводят онлайн-чемпионат по AI и машинному обучению «RAIF-Challenge 2017» в рамках форума RAIF (Russian Artificial Intelligence Forum). читать далее

      https://habrahabr.ru/post/338296/


      Zabbix 3.4: Массовый сбор данных на примерах счетчика Меркурий и smartmontools

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

      Zabbix 3.4: Массовый сбор данных на примерах счетчика Меркурий и smartmontools

      • Tutorial

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

      • сбор всех данных за раз, полученных в JSON от консольной утилиты счетчика электроэнергии Меркурий 236
      • сбор показателей S.M.A.R.T. жестких дисков и SSD, полученных в табличном виде от smartmontools.



      А в чем была собственно проблема?


      Собирать данные через консольные утилиты или вызовы API данные можно было и ранее, но существовали сложности:

      • медленные запуски утилит каждый раз, на каждый нужный элемент данных
      • обращение к ресурсу (диск, порт, счетчик, API приложения) на каждый элемент данных
      • парсинг результата нужно было делать внешними скриптами/утилитами
      • а если потом нужно было поправить парсинг – приходилось опять обновлять UserParameters или скрипты
      • кроме всего прочего, одновременные запросы от нескольких Zabbix pollers приводили к ошибке при обращении, например, к последовательному порту.

      В общем, дело было так:


      А с появлением зависимых элементов данных, стало возможно так:


      Как это работает?

      • В Zabbix 3.4 источником данных может выступать другой элемент данных, который называется родительским или мастер-элементом. Такой элемент может, например, содержать массив данных в формате JSON, XML или фривольном текстовом формате.
      • В момент поступления новых данных в родительский элемент, остальные элементы данных, которые называются зависимыми, обращаются к родительскому элементу и при помощи таких функций препроцессинга как JSON path, XPath или Regex выделяют из текста нужную метрику.


      Кстати, препроцессинг – тоже нововведение 3.4, он реализован добавлением новых процессов preprocessing_manager и preprocessing_worker на Zabbix-сервере. Поэтому, если вы обновляетесь с 3.2 – не забудьте обновить шаблон для сервера, чтобы мониторить их работу.

      Переходим к примерам.


      Меркурий 236



      Представим, что на нашем проекте, кроме контейнеров, виртуальных машин, приложений, сетевых устройств, баз данных, бизнес показателей и всего прочего требующего контроля, присутствует необходимость мониторить показатели электросети и другой «инженерки», как, например, климатическое оборудование. Используются стандартные для нашей средней полосы устройства: трехфазный счетчик электроэнергии Меркурий 236 АRT-01 PQRS с интерфейсом RS-485, поверх которого общение происходит через проприетарный протокол производителя.
      Задача ответственная – сразу собирать показатели напряжения, мощности, тока, потребления, частоты. Подключить такой прибор к серверу с Zabbix агентом – задача посильная – достаточно будет серийного порта с RS-485, например, в форме USB адаптера. Но как прочитать данные? Если бы не github и добрые люди, поделившиеся своим решением для умного дома, писать бы нам модуль к Zabbix, который бы мы учили разговаривать на протоколе счетчика и опрашивать показатели.
      Утилита простая и удобная (за что автору большое человеческое спасибо) подключается к счетчику на указанный порт, считывает данные и отдает нам в виде текста, CSV или JSON.

      Давайте попробуем установить и запустить:

      git clone https://github.com/Shden/mercury236.git
      cd mercury236
      make
      ./mercury236 /dev/ttyS0 --help
      Usage: mercury236 RS485 [OPTIONS] ...
      RS485 address of RS485 dongle (e.g. /dev/ttyUSB0), required
      --debug to print extra debug info
      --testRun dry run to see output sample, no hardware required
      Output formatting:
      ....
      --help prints this screen


      Запускается! Отлично, подключаем счетчик, опрашиваем, получаем JSON:

      ./mercury236 /dev/ttyS0 --json
      {
                      "U": {
                                     "p1": 0.35,
                                     "p2": 0.35,
                                     "p3": 226.86
                      },
                      "I": {
                                     "p1": 0.00,
                                     "p2": 0.00,
                                     "p3": 0.39
                      },
                      "CosF": {
                                     "p1": 0.00,
                                     "p2": 0.00,
                                     "p3": 0.60,
                                     "sum": 0.60
                      },
                      "F": 50.00,
                      "A": {
                                     "p1": 41943.03,
                                     "p2": 41943.03,
                                     "p3": 41943.03
                      },
                      "P": {
                                     "p1": 0.00,
                                     "p2": 0.00,
                                     "p3": 53.45,
                                     "sum": 53.45
                      },
                      "S": {
                                     "p1": 0.00,
                                     "p2": 0.00,
                                     "p3": 89.83,
                                     "sum": 89.83
                      },
                      "PR": {
                                     "ap": 120.51
                      },
                      "PR-day": {
                                     "ap": 86.00
                      },
                      "PR-night": {
                                     "ap": 34.51
                      },
                      "PY": {
                                     "ap": 0.00
                      },
                      "PT": {
                                     "ap": 0.04
                      }
      }


      В итоге утилита уже сделала всю сложную работу за нас, реализовав протокол общения с счетчиком, вытащив данные, да еще и предложила нам это в виде удобного JSON объекта. Вот только раньше просто так мы ей не смогли бы воспользоваться — пришлось бы писать обвязку в виде скриптов, а самое главное – реализовывать механизм контроля доступа к среде последовательного порта. Ведь если два поллера Zabbix одновременно обратятся к нему – один за током третьей фазы 3, а другой — за током фазы 2, у нас не вернулось бы ничего.
      В 3.4 все становится гораздо проще, и мы теперь быстро и легко можем передавать данные сторонних консольных утилит в Zabbix, не прибегая к оберточным скриптам, и не запуская по 10 раз одно и тоже на каждый элемент данных отдельно. Итак,


      Настроим запуск утилиты mercury236 из Zabbix


      sudo cp mercury236 /etc/zabbix/scripts
      cd /etc/zabbix/scripts
      chmod +x mercury236
      sudo usermod -G dialout zabbix

      Для запуска скрипта, создадим в конфиге Zabbix-агента новый UserParameter:
      UserParameter=mercury236[],/etc/zabbix/scripts/mercury236 $1 $2

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


      Как видите, в родительском элементе данных нет ничего особенного – просто проверка через UserParameter Zabbix-агента. А это значит, что и нет никаких ограничений на то, какой тип проверки может выступать в роли родительского элемента – здесь могут быть и данные полученные через Zabbix trapper или через Внешние проверки. Единственное, мы выбрали Тип информации – Text и срок хранения истории в 1 день – хранить дольше мы собираемся метрики отдельно в зависимых элементах (можно не хранить данные вообще в родительском элементе, выставив срок хранения 0). Обратите внимание, что препроцессинг в этом элементе данных мы не трогаем.


      Настроим получение наших метрик счетчика


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


      Создадим элемент данных для напряжения первой фазы, выберем:

      • Тип: Зависимый элемент данных
      • Основной элемент данных: mercury-get




      Затем во вкладке «Предобработка» добавим наше выражение JSON Path:
      Путь JSON: $.U.p1


      Кстати, маленький совет. Чтобы не тратить много времени на отладку и ловлю ошибок, перед тем как заполнять JSON Path можно быстро проверить правильность выражения онлайн, например здесь: jsonpath.com, скопировав туда JSON, полученный от утилиты.
      Аналогичным образом создаем другие интересующие нас метрики. В том числе — для накопленной энергии по дневному тарифу.

      Для этого создадим новый элемент данных и выберем:

      • Тип: Зависимый элемент данных
      • Основной элемент данных: mercury-get

      А вот во вкладке «Предобработка» обратите внимания на два нюанса:

      • будем использовать нотацию с квадратными скобками, так как в пути JSON есть дефис
      • препроцессинг может быть многошаговым, например здесь результата первого шага умножим на 1000, чтобы получить Вт*ч из кВт*ч




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



      Доведем наш шаблон до ума


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



      Что получилось


      Шаблон готов, данные побежали, посмотрим, что у нас получилось:

      Все последние данные, собранные за одно обращение:


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

      • переиспользовали хорошую программку и не тратили время на написание своей реализации сбора данных по протоколу Меркурий
      • UserParameter остался, но схлопнулся до простого вызова. По сути можно даже system.run[] использовать
      • cкрипты-обертки тоже не писали. Всё распарсили через JSON path в шаблоне
      • cчетчик не мучали сильно, один запрос – все нужные нам данные разом.



      Smartctl и smartmontools



      Давно мы уже писали на хабре, как можно контролировать S.M.A.R.T. жестких дисков, чтобы успеть их вовремя поменять, через использование UserParameters. Такой подход работает, но он не был лишен недостатков:

      • избыточные запуски утилиты smartctl, а она в свою очередь каждый раз обращалась к контроллеру жесткого диска
      • пришлось делать отдельный парсинг для Linux и Windows. Особенно больно с этим сейчас работать в Win: (for /F… так… экранируем двойные кавычки еще кавычками…. Аааа!!!!)

      Постараемся в 3.4 от всего этого избавится.

      Случай с smartmontools имеет два отличия от примера со счетчиком выше:

      • smartctl нам JSON не возвращает
      • дисков в сервере может быть различное количество, поэтому нам нужно использовать низкоуровневое обнаружение(LLD).

      Но ничего страшного! Во-первых, зависимые элементы данных работают и для LLD, а во-вторых у нас среди preprocessing-фильтров есть и PCRE regex. Воспользуемся им, чтобы вытащить нужные показатели из не супер сильно структурированного ответа утилиты. Примерно такого:

      Приступим.


      Упрощаем UserParameters


      Было:
      UserParameter=uHDD[], sudo smartctl -A $1| grep -i "$2"| tail -1| cut -c 88-|cut -f1 -d' '
      UserParameter=uHDD.model.[],sudo smartctl -i $1 |grep -i "Device Model"| cut -f2 -d: |tr -d " "
      UserParameter=uHDD.sn.[],sudo smartctl -i $1 |grep -i "Serial Number"| cut -f2 -d: |tr -d " "
      UserParameter=uHDD.health.[],sudo smartctl -H $1 |grep -i "test"| cut -f2 -d: |tr -d " "
      UserParameter=uHDD.errorlog.[],sudo smartctl -l error $1 |grep -i "ATA Error Count"| cut -f2 -d: |tr -d " "
      UserParameter=uHDD.discovery,sudo /etc/zabbix/scripts/smartctl-disks-discovery.pl
      

      Стало:
      UserParameter=uHDD.A[],sudo smartctl -A $1
      UserParameter=uHDD.i[],sudo smartctl -i $1
      UserParameter=uHDD.health[],sudo smartctl -H $1
      UserParameter=uHDD.discovery,sudo /etc/zabbix/scripts/smartctl-disks-discovery.pl
      

      Аналогично делаем и для Windows, попутно избавляясь от CMD магии с использование for /F и find. Посмотреть можно тут.

      Создаем новые родительские элементы данных


      Для сбора всех атрибутов S.M.A.R.T. создадим прототип мастер-элемента данных:


      Как и в предыдущем примере, ничего особенного настраивать не надо. Только Тип информации – Text, а Период хранения — 1 день.
      Для сбора результатов тестов и инвентарных данных нам потребуется запускать smartctl с другими ключами. Поэтому аналогично создадим еще два элемента данных:

      • uHDD.i["{#DISKNAME}"]
      • uHDD.health["{#DISKNAME}"]



      Настроим получение наших атрибутов S.M.A.R.T. диска


      Создадим зависимый элемент данных для атрибута 5, Reallocated:


      И во вкладке «Предобработка» используем регулярное выражение:


      И так же как и с JSON Path, чтобы не тратить много времени на отладку и ловлю ошибок, перед тем как заполнять regex, удобно быстро проверить правильность выражения онлайн, например здесь: regex101.com скопировав туда наш вывод smartctl.
      В итоге получим такой вот список прототипов:



      Тестируем, смотрим что получилось


      Для двух HDD:


      Для SSD под Windows:


      Подведем итоги примера с smartmontools:
      • мы убрали весь парсинг из UserParameters
      • нет внешних скриптов (кроме LLD), нет внешних зависимостей, весь парсинг происходит на Zabbix-сервере, там его легко посмотреть и подправить, если нужно
      • когда утилита или API не возвращает XML/JSON – не беда, всегда можно попробовать использовать регулярные выражения
      • жесткие диски больше не мучаем – сначала достаем весь список параметров S.M.A.R.T., а затем уже на Zabbix-сервере раскладываем его по метрикам.

      Обновленный шаблон (заодно обновили триггеры, добавили элементы данных для SSD) доступен на репозитории решений на share.zabbix.com здесь.


      В завершении


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

      https://habrahabr.ru/post/337856/


      Метки:  

      LibGDX. Практические вопросы и ответы

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

      LibGDX. Практические вопросы и ответы

      • Tutorial
      imageПривет хабр!
      Закончился конкурс от ВКонтакте vk.com/wall-104669514_37 и мой 2-х недельный марафон в интернете по поиску нужной информации
      Хочу поделится небольшим опытом работы с графическим движком LibGDX. В интернете полно примеров, но большинство далеки от практики (нарисованный спрайт это далеко еще не игра) или уже устарели.


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

      Вопросы, которые мне приходилось решать:

      Вариант использования встроенного логгера
      Я часто использую Timber из-за удобства. В core модуле он недоступен, потому написал простой вспомогательный класс с использованием имеющегося в LibGDX логгера, с которым приложение в релиз версии перестает писать логи
      import com.badlogic.gdx.Gdx;
      
      public class GdxLog {
      
       public static boolean DEBUG;
      
       @SuppressWarnings("all")
       public static void print(String tag, String message) {
        if (DEBUG) {
         Gdx.app.log(tag, message);
        }
       }
      
       @SuppressWarnings("all")
       public static void d(String tag, String message, Integer...values) {
        if (DEBUG) {
         Gdx.app.log(tag, String.format(message, values));
        }
       }
      
       @SuppressWarnings("all")
       public static void f(String tag, String message, Float...values) {
        if (DEBUG) {
         Gdx.app.log(tag, String.format(message.replaceAll("%f", "%.0f"), values));
        }
       }
      }
      
      //... вызов
      GdxLog.d(TAG, "worldWidth: %d", worldWidth);
      

      Плюс для удобства различные float значения 1.23456789 округляются

      E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
      Поначалу сильно огорчала такая ошибка, ничего не мог понять. Она происходит, потому что графика GLSurfaceView отрисовывается в своем отдельном потоке, когда проиcходит попытка извне вмешаться в этот процесс. Как исправить:
      Gdx.app.postRunnable(new Runnable() {
         @Override
         public void run() {
             // Здесь выполняется в самом потоке
         }
      });
      

      Впринципе аналогично, как и в случае, view.postInvalidate()
      Я не любитель анонимных классов, поэтому написал такой простой метод для сокращения кода (иначе он просто становился не читаемым). Хотя с java 8 это уже не такая проблема, но из дополнительных плюсов то, что обрабатываются InvocationTargetException, когда, например, файл не найден, приложение уже не упадет по такой незначительной ошибке.
      // null may be only String params
      public void postRunnable(final String name, final Object...params) {
       Gdx.app.postRunnable(new Runnable() {
        @Override
        public void run() {
         Method method = null;
         Class[] classes = new Class[params.length];
         for (int i = 0; i < params.length; i++) {
          classes[i] = params[i] == null ? String.class : params[i].getClass();
         }
         try {
          method = World.class.getMethod(name, classes);
         } catch (SecurityException e) {
          GdxLog.print(TAG, e.toString());
         } catch (NoSuchMethodException e) {
          GdxLog.print(TAG, e.toString());
         }
         if (method == null) {
          return;
         }
         try {
          method.invoke(WorldAdapter.this, params);
         } catch (IllegalArgumentException e) {
          GdxLog.print(TAG, e.toString());
         } catch (IllegalAccessException e) {
          GdxLog.print(TAG, e.toString());
         } catch (InvocationTargetException e) {
          GdxLog.print(TAG, e.toString());
         }
        }
       });
      }
      

      Важно, чтобы параметры не были примитивами, а наследовали Object. И плюс здесь упрощение с null параметром (только от класса String)

      Как использовать LibGDX с другими виджетами
      Через фрагмент. Больше информации в wiki
      Пример:
      public class ActivityMain extends AppCompatActivity
          implements AndroidFragmentApplication.Callbacks {
      
      protected FragmentWorld fragmentWorld;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       // ...
       getSupportFragmentManager()
        .beginTransaction()
        .add(R.id.world, fragmentWorld, FragmentWorld.class.getSimpleName())
        .commitAllowingStateLoss();
      }
      
      @Override
      public void exit() {}
      

      И сам фрагмент:
      public class FragmentWorld extends AndroidFragmentApplication {
      
       public World world;
      
       @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        int worldWidth = getResources().getDimensionPixelSize(R.dimen.world_width);
        int worldHeight = getResources().getDimensionPixelSize(R.dimen.world_height);
        world = new World(BuildConfig.DEBUG, worldWidth, worldHeight);
        return initializeForView(world);
       }
      }
      


      Как вытащить рендер мира или Pixmap в Bitmap
      Я не хотел сохранять pixmap в файл и потом средствами Android вытаскивать Bitmap
      Поэтому придумал такой лайфхак с OutputStream классом. Работает прекрасно и не требует медленных r/w операций
      final Pixmap pixmap = getScreenshot();
      Observable.fromCallable(new Callable  () {
       @Override
       public Boolean call() throws Exception {
        PixmapIO.PNG writer = new PixmapIO.PNG((int)(pixmap.getWidth() * pixmap.getHeight() * 1.5 f));
        writer.setFlipY(false);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
         writer.write(output, pixmap);
        } finally {
         StreamUtils.closeQuietly(output);
         writer.dispose();
         pixmap.dispose();
        }
        byte[] bytes = output.toByteArray();
        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        return true;
       }
      }).subscribeOn(Schedulers.io()).subscribe();
      


      Как работать с colors совместно с Android
      На самом деле можно int, наверное, (Color класс в LibGDX довольно специфичен как и вся графика, по-моему мнению, т.е. нужно разбираться на уровне битов) но для простоты я предпочел hex хранить и передавать в String
      Соотвественно понадобился парсер:
      protected Color parseColor(String hex) {
       String s1 = hex.substring(0, 2);
       int v1 = Integer.parseInt(s1, 16);
       float f1 = 1 f * v1 / 255 f;
       String s2 = hex.substring(2, 4);
       int v2 = Integer.parseInt(s2, 16);
       float f2 = 1 f * v2 / 255 f;
       String s3 = hex.substring(4, 6);
       int v3 = Integer.parseInt(s3, 16);
       float f3 = 1 f * v3 / 255 f;
       return new Color(f1, f2, f3, 1 f);
      }
      

      Пример параметра «ffffff»

      Как определить нажатие на actor
      sticker.addListener() Все проще. Есть метод hit у сцены
      Sticker sticker = (Sticker) stickersStage.hit(coordinates.x, coordinates.y, false);
      


      Математика scale и rotation на событие pinch (два пальца)
      Возможно это не лучшее решение, но работает хорошо. Поворот без резких скачков, плавный зум
      @Override
      public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1,
       Vector2 pointer2) {
       // initialPointer doesn't change
       // all vectors contains device coordinates
       Sticker sticker = getCurrentSticker();
       if (sticker == null) {
        return false;
       }
      
       Vector2 startVector = new Vector2(initialPointer1).sub(initialPointer2);
       Vector2 currentVector = new Vector2(pointer1).sub(pointer2);
       sticker.setScale(sticker.startScale * currentVector.len() / startVector.len());
      
       float startAngle = (float) Math.toDegrees(Math.atan2(startVector.x, startVector.y));
       float endAngle = (float) Math.toDegrees(Math.atan2(currentVector.x, currentVector.y));
       sticker.setRotation(sticker.startRotation + endAngle - startAngle);
       return false;
      }
      

      Единственно необходимо перед этим событием запоминать текущий зум и поворот
      @Override
      public boolean touchDown(float x, float y, int pointer, int button) {
       if (pointer == FIRST_FINGER) {
        Vector2 coordinates = stickersStage.screenToStageCoordinates(new Vector2(x, y));
        Sticker sticker = (Sticker) stickersStage.hit(coordinates.x, coordinates.y, false);
        if (sticker != null) {
         // здесь
         sticker.setPinchStarts();
         currentSticker = sticker.index;
        }
       }
       return false;
      }
      
      @Override
      public void pinchStop() {
       Sticker sticker = getCurrentSticker();
       if (sticker != null) {
        // здесь
        sticker.setPinchStarts();
       }
      }
      

      И на время события pinch актер неподвижен в этом случае

      Почему не происходит анимация, но action к актеру добавлен
      Ключевой метод act у сцены. Боль, когда этого не знаешь)
      spriteBatch.begin();
      stickersStage.act();
      stickersStage.getRoot().draw(spriteBatch, 1);
      spriteBatch.end();
      


      Градиент в LibGDX
      Насколько я понял, можно задать только левый верхний и нижний правый цвета. При этом есть не задавать остальные (transparent), то между ними будет пробел. Т.е. остальные определяются как сумма этих двух цветов на данном расстоянии, если речь идет о линейном градиенте. Сказать, что своеобразно, ничего не сказать
      gradientTopLeftColor = parseColor(topLeftColor);
      gradientBottomRightColor = parseColor(bottomRightColor);
      gradientBlendedColor = new Color(gradientTopLeftColor).add(gradientBottomRightColor);
      


      Хитрости обработки движения актера (событие pan)
      Вот этот обработчик
      @Override
      public boolean pan(float x, float y, float deltaX, float deltaY) {
       if (currentSticker != Sticker.INDEX_NONE) {
        Sticker sticker = getCurrentSticker();
        if (sticker != null) {
         sticker.moveBy(deltaX * worldDensity, -deltaY * worldDensity);
        }
       }
       return false;
      }
      

      worldDensity это разница между перемещением пальца в экранных координатах и актера в игровых. Без этого параметра актер будет отрываться от пальца
      @Override
      public void resize(int width, int height) {
       if (height > width) {
        worldDensity = 1f * worldWidth / width;
       } else {
        worldDensity = 1f * worldHeight / height;
       }
       viewport.update(width, height, true);
      }
      

      И если сделать привязку touch input через sticker.addListener, то поступающие координаты будут относительного самого актера к текущему положению пальца. Лучше так не делать, потому что при малом размере актера (зум) он задергается и вылетит из сцены (как было у меня)

      Как лучше работать с анимациями актеров (Action)
      Использовать Pool класс. В моем проекте есть пример более детально реализации дополнительной
      public void onAppear() {
       ScaleToAction scaleToAction = scaleToPool.obtain();
       scaleToAction.setPool(scaleToPool);
       scaleToAction.setScale(startScale);
       scaleToAction.setDuration(ANIMATION_TIME_APPEAR);
       addAction(scaleToAction);
      }
      


      Наверное все, что из интересного. Сам не нашел решение проблемы увеличения viewport. Камера zoom помогает только с приближением сцены, и получается, что сцена сокращается больше чем надо (область видимости неизменная).
      Другой вопрос это сохранение рендера мира. На выходе он соотвествует размеру экрана, но мне нужен определенный размер. Пробовал с framebuffer, но не получилось вытащить с него pixmap (присутствуют какие-то баги с инициализацией класса Texture)

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

      Но в целом, все очень даже хорошо. Развивайся дальше LibGDX)

      Ссылка на проект: github.com/androidovshchik/VKAdvancedPosting
      Original source: habrahabr.ru (comments, light).

      https://habrahabr.ru/post/338398/


      Метки:  

      Первый суперкомпьютер DGX-1 на базе Tesla V100 применят в медицине

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

      Первый суперкомпьютер DGX-1 на базе Tesla V100 применят в медицине

        Ученые из Центра клинических научных исследований (Center of Clinical Data Science) станут первыми, кто сможет обрабатывать данные с помощью суперкомпьютера для глубокого обучения DGX-1 на базе восьми графических процессоров Tesla V100. V100 показывают результат в 960 терафлопс при вычислениях FP16 благодаря технологии Volta Tensor Core.


        / Flickr / Fritzchens Fritz / PD

        Платформу для дата-центров Tesla V100 представили в мае 2017 года. Она содержит 21,1 млрд транзисторов, построена по 12-нанометровому техпроцессу FinFET, а отдельные 640 ядер Tensor используются для обеспечения работы нейронных сетей, выдавая 120 терафлопс при глубоком обучении.

        Nvidia провела апгрейд своей шины NVLink — теперь она «развивает» 300 Гбит/с, что почти в два раза больше по сравнению с предыдущей реализацией. Это стало возможно благодаря увеличению числа контактов с четырех до шести и расширению пропускной способности до 25 Гбит/с. Модуль 3D-памяти HBM2 также получил улучшения — пропускная способность выросла до 900 Гбит/с.

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

        «Врачи вынуждены иметь дело с огромным количеством информации: лабораторные исследования, МРТ, томография, данные о здоровье членов семьи и многое другое. Из-за этого принимать решения невероятно сложно. Технология, которая поможет врачам в диагностике, способна оптимизировать их работу», — рассказал исполнительный директор CCDS Марк Михалски (Mark Michalski).

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

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

        Кто еще использует GPU


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

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

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

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

        Например, Nike использует серверы с GPU и ПО MapD для анализа истории продаж и предсказания спроса в отдельных регионах. Еще один клиент MapD — Verizon — использует системы с GPU для анализа логов серверов, отслеживающих мобильные телефоны.

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

        P.S. Несколько материалов по теме из нашего блога:

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

        https://habrahabr.ru/post/338212/


        Метки:  

        Есть ли OpenVPN GUI для Linux?

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

        Есть ли OpenVPN GUI для Linux?

          Название статьи подсказала тема на одном из форумов. Несмотря на то, что с момента возникновения вопроса прошло шесть лет, в этом направлении мало что изменилось. А поскольку в последнее время у меня на слуху постоянно был OpenVPN, то было решено исправить данную ситуацию. Так родилась графическая утилита VpnGUI для создания, редактирования, запуска и контроля выполнения утилиты openvpn.
          После запуска утилиты VpnGUI в трее появится иконка (квадрат разбитый на четыре сине-красных квадратика) утилиты:

          image

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

          image

          Разработка велась на python с использованием графического пакета Tkinter и дизайнера Page.
          Напомним, что для использования «великого, могучего, правдивого и свободного русского языка!» (И.С. Тургенев), необходимо добавить в файл файл gui_pyton_gen.tcl дизайнера Page после 418 строки следующий код:
          # -*- coding: utf-8 -*- 	

          Аналогичный код необходимо дабавить также в файл support_python_gen.tcl (после 458 строки).

          Для программирования трея был установлен пакет Pystray.

          Работа утилиты начинается с выбора пользователем выполняемого файла openvpn или его форков. Утилита проверяет наличие выполняемого файла и заполняет списки перечнем поддерживаемых mac (алгоритмя контроля целостности), ciphers (алгоритмы шифрования) и перечнем поддерживаемых шифрсьютов:
          # openvpn –show-digests
          …
          #openvpn –show-ciphers
          …
          #openvpn –show-tls
          …

          image

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

          image

          После ввода пароля в окне «Протокол работы» будут отображаться диагностические сообщения OpenVPN:

          image

          До тех пор пока openvpn нормально работает книопка «VPN активен» будет блокирована. Если openvpn по каким-то причинам завершит свою работу или будет остановлен пользователем (кнопка «Стоп VPN»), то кнопка разблокируется и снова станет кнопкой «Старт VPN».

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

          image

          Теперь, когда openvpn нормально работает, можно его убрать в трей. Для этого можно использовать как кнопку «В трей» на окне «Протокол работы» или меню главного окна (Manager->Убрать в трей):

          image

          Утилита плафтормонезависима. Бинарный код утилиты можно получить, используя пакет Nuitka. Проект утилиты VPNGui, ее исходный код на Python, а также бинарный код для Linux x86_64 можно получить здесь. Имея на руках проект, каждый может доработать утилиту по своему усмотрению.
          Original source: habrahabr.ru (comments, light).

          https://habrahabr.ru/post/338390/


          [Перевод] Kotlin в продакшене, что мы получили, и что мы потеряли?

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

          Kotlin в продакшене, что мы получили, и что мы потеряли?

          • Перевод
          KotlinС того времени, как Google сделал Koltin новой любимой женой уже прошло достаточно времени. И сразу же после этого объявления наша команда начала новый проект полностью на Котлине. Проясню: не тестовый или просто внутренний проект, а новый модуль для живого приложения с 600+ тысячами активных пользователей в месяц. Какой опыт мы из этого извлекли? Что мы выиграли и что потеряли?

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

          Фан-фактор


          Очевидно, Котлин надо сначала выучить. Даже несмотря на то, что кривая обучения не выглядит как гора К2, плоской она тоже не является: один из коллег заметил, что на выполнение задач на Котлине у него уходило примерно в два раза больше времени, тем не менее, никто ни разу не пожаловался. Наоборот, все были только рады возможности применить новую крутую игрушку со всеми ее свистелками в продакшене. Более того, для привлечения лучших кандидатов мы стали не сговариваясь упоминать в ходе интервью, что пишем на Котлине. Так что чистая победа в этой категории +100 очков Котлину.

          Скорость


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

          Скорость написания


          В среднем на то, чтобы почувствовать себя более-менее комфортно с Котлином ушло около двух недель. И еще примерно две недели понадобилось, чтобы начать писать на нем быстрее чем на Джаве. Тем, у кого был опыт Scala и Groovy было проще, так как авторы Котлина во многом вдохновлялись ими. Поддержка со стороны IDE все еще не идеальна: много удобных и привычных по Джаве рефакторингов и автоподстановок просто не работают сейчас. Но даже несмотря на эту проблему, в итоге мы все равно немного в плюсе по скорости. Слабая победа Котлина в этой категории, впрочем мы ждем большего от финальной версии Android Studio 3.0 (на момент написания статьи мы все еще пользовались бетой).

          Скорость чтения


          Хоть код на Котлине и получается ощутимо короче, разбирать пулл-реквесты на ГитХабе приходится дольше. Почему так? Во-первых, ни Google ни JetBrains не подготовили полноценный стайл-гайд, так что члены команды стали проводить больше времени за дискуссиями на тему «красоты». Даже официальные примера кода не во всем однородны. Во-вторых, некоторые новые (для Джавы) конструкции могут быть использованы во вред, в то время как на Джаве так написать попросту не получится. Итого: небольшой но все же проигрыш на этом направлении, хотя, опять же, мы ожидаем улучшений в ближайшем будущем, потому что по поводу 99% спорных кейсов уже пришли к согласию.

          Инструменты и библиотеки


          Страшная правда в том, что Checkstyle и Lint пока еще абсолютно бесполезны для Котлина, а мы их используем и активно, но тот же Dagger работает отлично. А еще мы получили Kotlin-X и собираемся втянуть в проект Anko. Тут опять проигрыш Котлина, и хоть Anko с Kotlin-X могут подсластить пилюлю, мы особо не ожидаем драматических улучшений в работе стайлчекеров в ближайшее время.

          Тестирование


          А вот тут мы неожиданно получили преимущество. С Котлином не поставляется никаких новых инструментов или библиотек для тестирования, но новые языковые фичи, особенно type inference, extensions, и reified-типы существенно сократили количество бойлерплейта в тестовых классах. Чистая победа тут, даже несмотря на то, что IDE иногда пытается запустить Espresso как будто это чистые JVM юнит-тесты и, очевидно, не справляется с задачей.

          Саморазвитие


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

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

          https://habrahabr.ru/post/338388/


          Метки:  

          35 Гбит/с — как Megafon и Huawei поставили рекорд скорости 5G

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

          35 Гбит/с — как Megafon и Huawei поставили рекорд скорости 5G

            Операторы и производители оборудования уверенно движутся в сторону 5G, все увеличивая и увеличивая скорость. Год назад это был 1 Гбит/сек, в прошлом сентябре Megafon и Nokia демонстрировали прототипы БС и устройств 5G с максимальной скоростью 5 Гбит/сек, а 1 июня этого года в рамках Петербургского экономического форума Megafon вместе с Huawei добились максимальной скорости в 35 Гбит/сек, поставив рекорд скорости мобильного интернета. Уже в день этого события новостные агентства тиражировали фото с мероприятия и шумели о достигнутой скорости. А сегодня мы раскрываем интересные технические подробности рекорда.




            Приближаемся к стандарту 5G — агрегация и рефарминг


            Внедрение следующего поколения мобильной связи ожидается в 2020 году (это полностью согласуется с оценкой «новая технология мобильной связи каждые 10 лет»).  По мере приближения к «часу Х» стандарт 5G приобретает все более явные очертания. Одновременно операторы и производители оборудования экспериментируют с частотами и каналами связи, определяя направление дальнейшего движения. Насколько успешны эти эксперименты, показывают скорости передачи данных, демонстрируемые в рамках очередных испытаний.

            Около года назад «МегаФон» вместе с Huawei демонстрировали скорость передачи данных в 1 Гбит/сек. Такой результат удалось получить за счет передачи данных на нескольких частотах одновременно (использования трех несущих), что, в свою очередь, стало возможно, благодаря рефармингу — использованию частот, которые изначально предназначались для другой технологии.

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

            В рамках упомянутого эксперимента Megafon и Huawei была задействована частота в 1800 МГц, которая ранее использовалась для сетей GSM.



            Новый эксперимент — бимформинг


            Однако эксперименты продолжаются. Решение, продемонстрированное в этом году на Петербургском экономическом форуме, вместо агрегации частот из разных диапазонов использует для связи прототипа базовой станции и абонентского терминала одну, но очень широкую полосу частот — 2 ГГц — в диапазоне 70 ГГц (это одна из возможных частот будущего стандарта 5G). В ходе тестирования удалось достичь скорости передачи данных в 35 Гб/сек, что является абсолютным рекордом для мобильной передачи данных.



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

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

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



            Ничего сверхъестественного в ней, это просто пластина из стали:



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

            В двух словах о QAM


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

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



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

            Картинка иллюстрирует 16-QAM, но в 64-QAM все тоже самое, просто возможных состояний больше — 64, а значит, мы можем передать уже не 4, а 6 бит.

            Ложка дегтя


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



            Достаточно поднести руку к излучателю и скорость на графике тут же падает. Одновременно мы видим, как начинает рассыпаться сигнальное созвездие — аналог глазковых диаграмм для 64-QAM (ну, строго говоря, не только для нее):



            Сигнальное созвездие позволяет видеть «качество» передачи и одновременно замечать некоторые проблемы (подробнее можно посмотреть вот тут)

            Когда 5G попробуют абоненты?


            Тестовые зоны 5G «МегаФон» намерен развернуть уже в следующем году во время чемпионата мира по футболу. По сложившейся традиции новые стандарты мобильной связи тестируются во время крупных международных мероприятий.
            Original source: habrahabr.ru (comments, light).

            https://habrahabr.ru/post/337204/


            Метки:  

            Байки поддержки первой линии: отличная работа, если у вас крепкие нервы

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

            Байки поддержки первой линии: отличная работа, если у вас крепкие нервы



              Мы поддерживаем офис одной сервисной компании и хотели бы немного рассказать про нашу работу. Для поднятия настроения, так сказать. В общем-то, наш день выглядит одинаково: приходим, логинимся в cisco agent, садимся за телефон и начинаем слушать хотелки юзеров. Что-то разруливаем сами, что-то передаём второй линии рядом. Несмотря на то, что офис заказчика состоит преимущественно из инженеров, тикеты не очень сильно отличаются от тикетов нефтегазовой компании или госкомпании. Конечно, без того, чтобы проехать 200 километров, чтобы включить принтер в розетку (реальный случай), но всё же.

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

              Разумеется, техэксперты и техмены, обитающие в офисе, по большинству решают проблемы самостоятельно (ну или ставят очень понятные тикеты, где всё делается в пару кликов). Но есть ещё и различные «дополнительные службы», типа: столовая или спортзал. Некоторые из них вообще иногда доставляют нам море радости своими тикетами с просьбой установить World of Tanks на компьютер. Или: «Я слышу людей в мониторе, а меня никто не слышит!»

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

              Пару раз выталкивали машины с парковки, один раз помогали качать колесо. Почему? Потому что к нам стучат тогда, когда не знают, к кому обращаться. Мы же поддержка. Мы всегда поможем. В ITSM рабочие часы на такие вещи списываются по графе «неподдерживаемый сервис» — раньше это были всякие штуки с прикладным ПО, которые не входят в наш SLA, а теперь по большей части — как раз вот эти вот странные запросы. Нет, конечно, мы их фильтруем, но всё равно иногда так или иначе делаем. Пользователю же очень сложно объяснить, что к нам, а что — нет. Самый яркий пример — когда человек не получает бутерброд в автомате на этаже, но не может вернуть деньги, он сначала бьёт автомат, а потом пишет тикет нам.

              Естественно, всем всё нужно вчера — но это, думаю, данность у каждой первой линии.

              Иногда бывают дни ада — это когда у пользователей приходит время плановой смены паролей. За такой день может поступить 70–80 звонков на сотрудника: всем нужно войти в учётки. Это ещё не считая обычных проблем вроде кончившегося тонера или сломавшегося блока питания.

              Очень мало проблем с вирусами — в компании стоят хорошие NGFW и песочницы, поэтому все эпидемии проходят мимо. Единственное — опять же личные устройства. У подкованных они защищены, а вот та же охрана страдает. У меня был тикет про сходящего с ума охранника, который кликал на видео про Госдуму, а попадал на порнуху. На месте оказалось, что он смотрел какой-то отличный сайт, где блоки Ютуба были только нарисованы, а на деле это были IMG с реферальной ссылкой на порносайт. Психику человеку я тогда спас.

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

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

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

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

              Один раз просили включить Sony PlayStation4, причём в рамках поддерживаемого сервиса. Смотрим — он и правда поддерживаемый, теперь в комнате отдыха одна стоит.

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

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

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

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

              Есть пользователь-вампир: он уже 6 лет пишет заявки только после заката. Мы его не знаем, но тикеты закрываем. Наверное, какой-нибудь спец по поддержке линий связи Дальнего Востока. Кстати, да, для ночной смены самое интересное время — 4–5 часов утра, когда просыпается Иркутск и начинает ставить срочные задачи.

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

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

              Ну и сегодня, наверное, мы получим по башке от нашего коллеги Стаса. Потому что не рассказать эту историю я просто не могу. У нас две комнаты, мы в первой, а Стас с командой — во второй. Дело в том, что мы как-то месяц встречали каждого заходящего в гости пользователя, внимательно выслушивали и говорили, что именно на его вопросе специализируется Стас. И он лучше всех это решит. Юзер шёл в другую комнату и обращался лично к нему. Стас чуть с ума не сошёл, думая, почему все идут только по его душу. Ну, теперь, наверное, узнает.
              Original source: habrahabr.ru (comments, light).

              https://habrahabr.ru/post/338384/


              Метки:  

              Работа со смарт-контрактами через Ethereum RPC API

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

              Работа со смарт-контрактами через Ethereum RPC API

              • Tutorial


              Всем привет. В этой статье мы рассмотрим основные приемы по публикации смарт-контрактов и взаимодействию с ними с использованием Ethereum RPC API. Обсуждаемые методы API позволяют решать такие задачи:

              1. Создание счёта.
              2. Создание корректного смарт-контракта.
              3. Получение информации со смарт-контракта.
              4. Изменение состояния смарт-контракта.


              Содержание:

              • Некоторые общие замечания
              • Упаковка параметров и возвращаемых данных Создание счёта и работа с ним
              • Создание смарт-контракта
                • Компиляция исходного кода смарт-контракта
                • Извлечение кода из транзакции
                • Рассчёт стоимости опубликования контракта
                • Выполнение транзакции на публикацию контракта
              • Взаимодействие со смарт-контрактом
                • Создание контракта с параметрами
                • Идентификация методов контракта
                • Вызов методов запроса информации
                • Вызов методов, изменяющих состояние контракта

              Описание используемого API:


              Некоторые общие замечания



              1. Все предлагаемые действия иллюстрируются реальными данными из тестовой сети Rinkeby (на момент написания статьи).
              2. Состояние транзакций, счетов и смарт-контрактов в Rinkeby можно отслеживать по сайту https://rinkeby.etherscan.io/ (для подсети Ropsten будет, соответственно, https://ropsten.etherscan.io/).

              Упаковка параметров и возвращаемых данных


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

              Входящий (параметры) или исходящий пакет данных для контракта формируется по следующему принципу:

              • Фиксированные по длине типы данных (address, uint32, bytes32) передаются с выравниванием до 32-байтного слова (64 hex-цифры).
              • Переменные по длине типы данных (строковые, массивы) передаются по следующей схеме:
                • В позиции объекта в списке передается смещение блока с его данными относительно начала пакета (с выравниванием до 32-байтного слова).
                • В первом 32-байтном слове блока передается число единиц данных.
                • В последующих 32-байтных словах передаются сами данные.

              Рассмотрим, например, блок, в котором передается следующий набор данных: address, string, uint32, address[] (в начале каждой 32-байтовой строки для удобства дан ее шестнадцатеричный адрес относительно начала блока).

              000:000000000000000000000000570f5d143ee469d12dc29bf8b3345fa5536476d9
              020:0000000000000000000000000000000000000000000000000000000000000080
              040:0000000000000000000000000000000000000000000000000000000000001234
              060:00000000000000000000000000000000000000000000000000000000000000c0
              080:0000000000000000000000000000000000000000000000000000000000000003
              0a0:4e65770000000000000000000000000000000000000000000000000000000000
              0c0:0000000000000000000000000000000000000000000000000000000000000002
              0e0:000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 100:000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

              В строке 000 передается адрес 0х570f5d143ee469d12dc29bf8b3345fa5536476d9.
              В строке 020 передается ссылка на блок, описывающий переменную типа string 0x80 байт от начала блока.
              В строке 040 передается целое число 0х1234.
              В строке 060 передается ссылка на блок, описывающий массив address[]0xc0 байт от начала блока.
              В строке 080 передается счетчик символов переменной типа string 3.
              В строке 0a0 передаются сами символы переменной типа string — слово New.
              В строке 0c0 передается счетчик элементов массива address[]2.
              В строке 0e0 передается первый элемент массива address[]0хaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.
              В строке 100 передается второй элемент массива address[]0хbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.

              Внимание! Весь блок передается одним слитным массивом:

              Создание счёта и работа с ним


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

              {"jsonrpc":"2.0","method":"personal_newAccount","params":["PASSWORD"],"id":1}

              В ответ приходит идентификатор счёта, в данном случае — 0xfbeda9914b78b58a0f0e810298f9d545f8379f8d.

              {"jsonrpc":"2.0","id":1,"result":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d"}

              Все дальнейшие манипуляции мы будем производить с этого счета — 0xfbeda9914b78b58a0f0e810298f9d545f8379f8d.

              Теперь нам необходимо положить на него некоторую сумму для оплаты исполнения транзакций. Так как в тестовой сети Rinkeby поучаствовать в майнинге человеку со стороны невозможно, то для пополнения счетов предусмотрен специальный «кран», процедура использования которого описана здесь — https://faucet.rinkeby.io/.

              Для пополнения счета необходимо:

              • Зарегистрироваться на github.com и создать новый gist:



              • Вписать в него идентификатор счета:



                и создать публичный gist («Create public gist»)
              • Далее нам понадобится URL gist-а, в нашем случае — https://gist.github.com/oldmadjackal/6e246d3f199a80bfb82bfe626faad604:



              • Переходим на https://faucet.rinkeby.io/, вводим URL gist-а в поле и выбираем сумму пополнения счёта:



                Если всё хорошо, то появится зелёное сообщение с подтверждением. Транзакция может пройти не очень быстро — за 5-10 минут.
              • Смотрим счёт на EtherScan:



              • Для повторных пополнений можно использовать тот же gist.

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

              {"jsonrpc":"2.0","method":"personal_unlockAccount","params":["0xfbeda9914b78b58a0f0e810298f9d 545f8379f8d", "PASSWORD", 600],"id":1}
              
              {"jsonrpc":"2.0","id":1,"result":true}

              Создание смарт-контракта


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

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

              • Компиляцией из исходного текста смарт-контракта.
              • Извлечением из другой транзакции создания такого же смарт-контракта.

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

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

              Компиляция исходного кода смарт-контракта


              Для компиляции исходного кода на Solidity я использую Remix — https://remix.ethereum.org/.



              Вводим текст контракта, если ошибок нет — в поле Bytecode будет находиться собственно байткод, в нашем случае:

              6060604052341561000f57600080fd5b5b6040805190810160405280600381526020017f4e657700000
              000000000000000000000000000000000000000000000000000008152506000908051906020019061
              005b929190610062565b505b610107565b82805460018160011615610100020316600290049060005
              2602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b
              828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906
              100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082111561010057600081600
              09055506001016100e8565b5090565b90565b6101b6806101166000396000f30060606040526000357 c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063abd95b 951461003e575b600080fd5b341561004957600080fd5b6100516100cd565b604051808060200182810
              3825283818151815260200191508051906020019080838360005b8381101561009257808201518184
              01525b602081019050610076565b50505050905090810190601f1680156100bf578082038051600183
              6020036101000a031916815260200191505b509250505060405180910390f35b6100d5610176565b60
              008054600181600116156101000203166002900480601f016020809104026020016040519081016040
              52809291908181526020018280546001816001161561010002031660029004801561016b5780601f10
              6101405761010080835404028352916020019161016b565b820191906000526020600020905b81548
              152906001019060200180831161014e57829003601f168201915b505050505090505b90565b6020604
              051908101604052806000815250905600a165627a7a723058208ce8782af87268eb0fb543832301a980
              e57bdb35f0a3cdbfe8f2ece20d9a3eaa0029

              Извлечение кода из транзакции


              Для извлечения кода из транзакции используется метод eth_getTransactionByHash. В нашем примере «клонируемый» смарт-контракт был создан транзакцией 0xc4d20bb8f9eede45968fc6bc850397e92b9f263eeb11200615cc08562d46c2e7.

              {"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0xc4d20bb8f9eede45968fc6bc850 397e92b9f263eeb11200615cc08562d46c2e7"],"id":1}

              В тэге input ответа содержится байткод контракта.

              {"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x731f202b0232de8c474c71677b29868f65802c068d0d e31b17bec09f3e31144c",    "blockNumber":"0xbad3f", "from":"0x17eafa57fd812968d90aecc5a51e330e2e1c11a3",     "gas":"0x31b2e", "gasPrice":"0x9c7652400", "hash":"0xc4d20bb8f9eede45968fc6bc850397e92b9f263eeb11200615cc08562d46c2e7", "input":"0x6060604052341561000f57600080fd5b5b6040805190810160405280600381526020017f4e 657700000000000000000000000000000000000000000000000000000000008152506000908051906
              020019061005b929190610062565b505b610107565b82805460018160011615610100020316600290
              0490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556
              100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190
              600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b8082111561010057
              60008160009055506001016100e8565b5090565b90565b6101b6806101166000396000f30060606040
              526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168
              063abd95b951461003e575b600080fd5b341561004957600080fd5b6100516100cd565b604051808060
              2001828103825283818151815260200191508051906020019080838360005b8381101561009257808
              20151818401525b602081019050610076565b50505050905090810190601f1680156100bf578082038
              0516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d5610
              176565b60008054600181600116156101000203166002900480601f016020809104026020016040519
              08101604052809291908181526020018280546001816001161561010002031660029004801561016b
              5780601f106101405761010080835404028352916020019161016b565b820191906000526020600020
              905b81548152906001019060200180831161014e57829003601f168201915b505050505090505b9056
              5b6020604051908101604052806000815250905600a165627a7a723058208ce8782af87268eb0fb5438
              32301a980e57bdb35f0a3cdbfe8f2ece20d9a3eaa0029", "nonce":"0x30", "to":null, "transactionIndex":"0x2", "value":"0x0", "v":"0x2c", "r":"0x577865931aac644a3eefb83b59344caeab9e2970cfeb1bef02837b1bb4bccca0", "s":"0x48013e0c5ca3bff66fa7e19ebbcd9eaed63bc0a45004041c310f9fc4dfc5e5e8"}}

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

              Расчет стоимости опубликования контракта


              Для расчета стоимости опубликования контракта используется метод eth_estimateGas, в параметрах которого следует указать номер счета (тэг from), с которого будет создан контракт, а также байт-код контракта (тэг data). В ответе будет указано необходимое количество Gas.

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

              {"jsonrpc":"2.0","method":"eth_estimateGas","params":[{ "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d", "data":"0x6060604052341561000f57600080fd5b5b6040805190810160405280600381526020017f4e6 577000000000000000000000000000000000000000000000000000000000081525060009080519060
              20019061005b929190610062565b505b610107565b828054600181600116156101000203166002900
              490600052602060002090601f016020900481019282601f106100a357805160ff191683800117855561
              00d1565b828001600101855582156100d1579182015b828111156100d057825182559160200191906
              00101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b80821115610100576
              0008160009055506001016100e8565b5090565b90565b6101b6806101166000396000f300606060405
              26000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680
              63abd95b951461003e575b600080fd5b341561004957600080fd5b6100516100cd565b6040518080602
              001828103825283818151815260200191508051906020019080838360005b83811015610092578082
              0151818401525b602081019050610076565b50505050905090810190601f1680156100bf5780820380
              516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d56101
              76565b60008054600181600116156101000203166002900480601f0160208091040260200160405190
              8101604052809291908181526020018280546001816001161561010002031660029004801561016b5
              780601f106101405761010080835404028352916020019161016b565b8201919060005260206000209
              05b81548152906001019060200180831161014e57829003601f168201915b505050505090505b90565 b6020604051908101604052806000815250905600a165627a7a723058208ce8782af87268eb0fb54383
              2301a980e57bdb35f0a3cdbfe8f2ece20d9a3eaa0029" }], "id":1}
              
              {"jsonrpc":"2.0","id":1,"result":"0x31b2e"}

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

              Выполнение транзакции на публикацию контракта


              Для публикации контракта используется метод eth_sendTransaction. В качестве параметров методу передаются:

              • номер счета, с которого создаётся контракт (тэг from);
              • стоимость публикации в Gas (тэг gas, берется из предыдущего пункта);
              • байт-код контракта с пристыкованным блоком параметров конструктора (тэг data, должен полностью совпадать с использованным в предыдущем пункте).

              {"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{ "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d",     "gas":"0x31b2e", "data":"0x6060604052341561000f57600080fd5b5b6040805190810160405280600381526020017f4e6 577000000000000000000000000000000000000000000000000000000000081525060009080519060
              20019061005b929190610062565b505b610107565b828054600181600116156101000203166002900
              490600052602060002090601f016020900481019282601f106100a357805160ff191683800117855561
              00d1565b828001600101855582156100d1579182015b828111156100d057825182559160200191906
              00101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b80821115610100576
              0008160009055506001016100e8565b5090565b90565b6101b6806101166000396000f300606060405
              26000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680
              63abd95b951461003e575b600080fd5b341561004957600080fd5b6100516100cd565b6040518080602
              001828103825283818151815260200191508051906020019080838360005b83811015610092578082
              0151818401525b602081019050610076565b50505050905090810190601f1680156100bf5780820380
              516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d56101
              76565b60008054600181600116156101000203166002900480601f0160208091040260200160405190
              8101604052809291908181526020018280546001816001161561010002031660029004801561016b5
              780601f106101405761010080835404028352916020019161016b565b8201919060005260206000209
              05b81548152906001019060200180831161014e57829003601f168201915b505050505090505b90565 b6020604051908101604052806000815250905600a165627a7a723058208ce8782af87268eb0fb54383
              2301a980e57bdb35f0a3cdbfe8f2ece20d9a3eaa0029" }], "id":1}

              В ответ мы получим номер транзакции:

              {"jsonrpc":"2.0","id":1,"result":"0x26cd429a43bc2f706f206fa6a536374cc7bf0e5090f0ed9b8f30ded71 73529f5"}

              или сообщение об ошибке:

              {"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"authentication needed: password or unlock"}}

              Теперь необходимо дождаться завершения транзакции и получить результат её исполнения — создан контракт или нет. Для этого используется метод eth_getTransactionReceipt:

              {"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x26cd429a43bc2f706f206fa6a53 6374cc7bf0e5090f0ed9b8f30ded7173529f5"],"id":1}

              Пока транзакция находится в «листе ожидания» (Pending Txn), будет выдаваться следующий ответ:

              {"jsonrpc":"2.0","id":1,"result":null}

              После исполнения транзакции мы получим полную «квитанцию», в теге contractAddress которой будет содержаться адрес созданного смарт-контракта:

              {"jsonrpc":"2.0", "id":1, "result":{"blockHash":"0x3afdc600435caebebb91497f01372c3ad6ac712c37fe9b1028445d8b41a58fca"
              ,    "blockNumber":"0xc4b16",    "contractAddress":"0x2af49c8a413ea4b66ca8fd872befa9d1c8d22562", "cumulativeGasUsed":"0x31b2d",      "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d", "gasUsed":"0x31b2d","logs":[], "logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000",
              "root":"0x47b6297fef6ba21c45ea845a6fba19ddb144d957f600cfe7230e05f0f711ac12",      "to":null, "transactionHash":"0x26cd429a43bc2f706f206fa6a536374cc7bf0e5090f0ed9b8f30ded7173529f5", "transactionIndex":"0x0"}}

              Если в течении 5 минут квитанция не получена, то либо в сети проблемы, либо ваш узел не разослал проводку по сети. Чтобы понять истинную причину, следует просмотреть очередь Pending Txn на etherscan.io (https://rinkeby.etherscan.io/txsPending). Если транзакции там нет — значит, надо перезапустить клиент Ethereum и повторить публикацию заново.

              Теперь следует проверить, корректно ли создался смарт-контракт. Для этого можно использовать метод eth_getCode — получение кода контракта по его адресу:

              {"jsonrpc":"2.0","method":"eth_getCode","params":["0x2af49c8a413ea4b66ca8fd872befa9d1c8d2256 2", "latest" ],"id":1}

              Если контракт создался некорректно, то будет получен ответ:

              {"jsonrpc":"2.0","id":1,"result":"0x"}

              Если в тэге result выдаются некоторые данные, отличные от 0x, то контракт создан успешно.

              Взаимодействие со смарт-контрактом


              Для демонстрации взаимодействия со смарт-контрактом будем использовать следующий образцовый смарт-контракт:

              pragma solidity ^0.4.9;
              
              contract Test
              {
              	address Owner ; 
              	address Seller ; 
              	address Bank ; 
              	address BankCert ; 
              	string Status ;
              
              	function Test(address seller_, address bank_)
              	{
              		Owner=msg.sender ; 
              		Seller=seller_ ;
              		Bank=bank_ ; 
              		Status="New" ;
              	}
              
              	// 0xabd95b95
              	function GetStatus() constant returns (address, address, string retVal)
              	{
              		return(Seller, Bank, Status) ;
              	}
              
              	// 0x1bb71149
              	function SetBankCert(address cert)
              	{
              		if(msg.sender!=Bank) return ; BankCert=cert ;
              			Status="Confirmed" ;
              	}
              }

              При создании контракта (конструктор — функция Test) ему передаются адрес Продавца (seller_) и адрес Банка (bank_). Метод GetStatus возвращает адресa Продавца, Банка и текущий статус контракта. Метод SetBankCert предназначен для сохранения в контракте некоторого цифрового идентификатора с переводом в статус «Confirmed».

              Байт-код контракта:

              6060604052341561000f57600080fd5b60405160408061064383398101604052808051906020019091
              9080519060200190919050505b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908 373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173fffffffffffffffffffffffffffffffff fffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260006101000a81548173ffffffffff ffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550604080519081016040 5280600381526020017f4e657700000000000000000000000000000000000000000000000000000000
              008152506004908051906020019061014292919061014b565b505b50506101f0565b82805460018160
              0116156101000203166002900490600052602060002090601f016020900481019282601f1061018c57
              805160ff19168380011785556101ba565b828001600101855582156101ba579182015b828111156101 b957825182559160200191906001019061019e565b5b5090506101c791906101cb565b5090565b6101 ed91905b808211156101e95760008160009055506001016101d1565b5090565b90565b610444806101 ff6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000 000000000900463ffffffff1680631bb7114914610049578063abd95b9514610082575b600080fd5b34156
              1005457600080fd5b610080600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061017 7565b005b341561008d57600080fd5b610095610264565b604051808473ffffffffffffffffffffffffffffffffffffffff1 673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673fffffffffffffffffffffffff fffffffffffffff1681526020018060200182810382528381815181526020019150805190602001908083836 0005b8381101561013a5780820151818401525b60208101905061011e565b505050509050908101906
              01f1680156101675780820380516001836020036101000a031916815260200191505b5094505050505
              060405180910390f35b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffff ffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101d357610261565b80600360006101 000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506 040805190810160405280600981526020017f436f6e6669726d6564000000000000000000000000000
              00000000000000000008152506004908051906020019061025f92919061035f565b505b50565b60008
              061026f6103df565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600090549 06101000a900473ffffffffffffffffffffffffffffffffffffffff16600480805460018160011615610100020316600290 0480601f01602080910402602001604051908101604052809291908181526020018280546001816001
              161561010002031660029004801561034c5780601f1061032157610100808354040283529160200191
              61034c565b820191906000526020600020905b81548152906001019060200180831161032f57829003
              601f168201915b505050505090509250925092505b909192565b828054600181600116156101000203
              166002900490600052602060002090601f016020900481019282601f106103a057805160ff191683800
              11785556103ce565b828001600101855582156103ce579182015b828111156103cd578251825591602
              0019190600101906103b2565b5b5090506103db91906103f3565b5090565b602060405190810160405
              280600081525090565b61041591905b808211156104115760008160009055506001016103f9565b509
              0565b905600a165627a7a72305820554a2d34ed0a4ad399f7464c8b29ba8c619e7f5de89746021f5aded 9516dd1860029

              Создание контракта с параметрами


              Если конструктор смарт-контракта использует параметры (как в нашем демонстрационном примере), то они должны быть «упакованы» в соответствии с описанием «Упаковка параметров и возвращаемых данных» и присоединены в хвост к байт-коду контракта.

              В нашем случае, передача адреса Продавца 0x794ce6de39fa2d274438cc1692db04dfb5bea836 и адреса Банка 0xfbeda9914 b78b58a0f0e810298f9d545f8379f8d при создании смарт-контракта будет выглядеть следующим образом (байт-код контракта кончается на 0029):

              60606040...94000029000000000000000000000000794ce6de39fa2d274438cc1692db04dfb5bea8360
              00000000000000000000000fbeda9914b78b58a0f0e810298f9d545f8379f8d

              Еще раз обращаю внимание, что расчет Gas должен выполняться для всего блока Байт-код + Параметры, иначе контракт или не будет создан, или будет неработоспособен.

              Наш тестовый демо-контракт был создан по адресу 0x3d20e579f5befdc7d3f589adb6155f684d9a751c.

              Идентификация методов контракта


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

              Например, для метода GetStatus демо-контракта описанием будет GetStatus(), а для метода SetBankCert SetBankCert(address). Особое внимание следует обратить на отсутствие пробелов в описании — были печальные прецеденты :(.

              Для определения хэша используется метод web3_sha3, при этом строчное значение следует давать в шестнадцатеричном представлении (для GetStatus() это будет 0x4765745374617475732829):

              {"jsonrpc":"2.0","method":"web3_sha3","params":["0x4765745374617475732829"],"id":1}
              
              {"jsonrpc":"2.0","id":1,"result":"0xabd95b950242a279866243fa2b8fec5adddf6560d4e1b4f8745cfe7b5 7786865"}

              Соответственно, идентификатором метода GetStatus будет 0xabd95b95, для метода SetBankCert идентификатор — 0x1bb71149.

              Вызов методов запроса информации


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

              Запрос метода имеет такую структуру:

              {"jsonrpc":"2.0","method":"eth_call","params":[{"to":<Адрес контракта>, "data":<Данные запроса>},"latest"],"id":1} 

              Блок <Данные запроса> формируется следующим образом:

              <Идентификатор метода><Данные параметров>

              где <Данные параметров> формируются, как указано в пункте «Упаковка параметров и возвращаемых данных».

              Если метод не предполагает наличия параметров, то блок <Данные запроса> состоит только из идентификатора метода.

              Например, для вызова метода GetStatus демо-контракта Test используется запрос:

              {"jsonrpc":"2.0", "method":"eth_call", "params":[{"to":"0x3d20e579f5befdc7d3f589adb6155f684d9a751c",      "data":"0xabd95b95"}, "latest"],"id":1}

              на который будет дан ответ:

              {"jsonrpc":"2.0", "id":1, "result":"0x000000000000000000000000794ce6de39fa2d274438cc1692db04dfb5bea8360000000000 00000000000000fbeda9914b78b58a0f0e810298f9d545f8379f8d000000000000000000000000000000
              000000000000000000000000000000006000000000000000000000000000000000000000000000000
              000000000000000034e65770000000000000000000000000000000000000000000000000000000000"
              }

              Разберем полученный ответ в соответствии с правилами пункта «Упаковка параметров и возвращаемых данных» и с учетом описания метода GetStatus — function GetStatus() constant returns (address, address, string retVal).

              Для удобства анализа разложим ответ на 32-байтные слова:

              000:000000000000000000000000794ce6de39fa2d274438cc1692db04dfb5bea836
              020:000000000000000000000000fbeda9914b78b58a0f0e810298f9d545f8379f8d
              040:0000000000000000000000000000000000000000000000000000000000000060
              060:0000000000000000000000000000000000000000000000000000000000000003
              080:4e65770000000000000000000000000000000000000000000000000000000000

              Исходя из описания мы ожидаем получение следующего набора переменных: address, string. Таким образом:

              • в строке 000 находится адрес Продавца (тип address) — 0x794ce6de39fa2d274438cc1692db04dfb5bea836
              • в строке 020 находится адрес Продавца (тип address) — 0xfbeda9914b78b58a0f0e810298f9d545f8379f8d
              • в строке 040 находится ссылка на блок описания статуса контракта (тип string) — блок начинается с адреса 060
              • в строке 060 находится счетчик символов в строке статуса контракта — 3 символа
              • в строке 080 находятся собственно символы статуса контракта в шестнадцатеричной кодировке — New

              Вызов методов, изменяющих состояние контракта


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

              Запрос метода имеет такую структуру:

              {"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{ "from":<Адрес инициатора>, "to":<Адрес контракта>, "gas":<Стоимость исполнения>, "data":<Данные запроса> }], "id":1}

              <Адрес инициатора> должен иметь баланс, достаточный для выплаты <Стоимости исполнения>. Кроме того, следуют учитывать, что контракт может содержать внутренние условия по контролю <Адреса инициатора>, как, например, в методе SetBankCert нашего демо-контракта.
              Блок <Данные запроса> формируется следующим образом:

              <Идентификатор метода><Данные параметров>

              где <Данные параметров> формируются, как указано в параграфе «Упаковка параметров и возвращаемых данных».

              Если метод не предполагает наличия параметров, то блок <Данные запроса> состоит только из идентификатора метода.

              Например, для вызова метода SetBankCert("0хf7b0f8870a5596a7b57dd3e035550aeb5af16607") демо-контракта, <Данные запроса> будут иметь следующий вид:

              0x1bb71149000000000000000000000000f7b0f8870a5596a7b57dd3e035550aeb5af16607.

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

              {"jsonrpc":"2.0","method":"eth_estimateGas","params":[{ "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d", "to":"0x3d20e579f5befdc7d3f589adb6155f684d9a751c", "data":"0x1bb71149000000000000000000000000f7b0f8870a5596a7b57dd3e035550aeb5af16607"
              }],"id":1}
              
              {"jsonrpc":"2.0","id":1,"result":"0xd312"}

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

              Далее вызываем метод eth_sendTransaction:

              {"jsonrpc":"2.0", "method":"eth_sendTransaction", "params":[{ "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d", "to":"0x3d20e579f5befdc7d3f589adb6155f684d9a751c",     "gas":"0xd312", "data":"0x1bb71149000000000000000000000000f7b0f8870a5596a7b57dd3e035550aeb5af16607"
              }],"id":1}

              и получаем в ответ идентификатор транзакции:

              {"jsonrpc":"2.0","id":1,"result":"0xe55c9fe8f816f5730053fc491ea27acfd83c615b6623d06f25fb281fea 750f3c"}

              Как и в случае с созданием смарт-контракта, ожидаем исполнения транзакции, запрашивая квитанцию (метод eth_getTran sactionReceipt):

              {"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xe55c9fe8f816f5730053fc491ea2 7acfd83c615b6623d06f25fb281fea750f3c"],"id":1}

              Как только квитанция пришла — транзакция исполнилась:

              {"jsonrpc":"2.0", "id":1, "result":{"blockHash":"0xd8bb4a0b0ca3a598a69786f2f40876d547a672044fc8d961ec22da60606fa2fb"
              , "blockNumber":"0xc4b6f", "contractAddress":null, "cumulativeGasUsed":"0x459e5", "from":"0xfbeda9914b78b58a0f0e810298f9d545f8379f8d", "gasUsed":"0xd311", "logs":[], "logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000000000000000000000000000000000000000000000
              000000000000000000000000000000000000000",
              "root":"0x75f6823221a4f0e4f80dfa6c7ccfc961c7522833aac959d6a398537730a62041", "to":"0x3d20e579f5befdc7d3f589adb6155f684d9a751c", "transactionHash":"0xe55c9fe8f816f5730053fc491ea27acfd83c615b6623d06f25fb281fea750f3c", "transactionIndex":"0x1"}}

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

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

              000:000000000000000000000000794ce6de39fa2d274438cc1692db04dfb5bea836
              020:000000000000000000000000fbeda9914b78b58a0f0e810298f9d545f8379f8d
              040:0000000000000000000000000000000000000000000000000000000000000060
              050:0000000000000000000000000000000000000000000000000000000000000009
              060:436f6e6669726d65640000000000000000000000000000000000000000000000

              Разобрав ответ, мы увидим, что статус изменился на «Confirmed».

              Резюме


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

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

              https://habrahabr.ru/post/338172/


              Метки:  

              [Перевод] Go для больших данных

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

              Go для больших данных

              • Перевод


              В этом посте мы расскажем об использовании библиотеки ускорения аналитики данных Intel Data Analytics Acceleration Library (Intel DAAL) с языком программирования Go для пакетной, интерактивной и распределенной обработки.

              На основе Go построены самые современные инфраструктурные проекты, в том числе Kubernetes, Docker, Consul, etcd и многие другие. Go становится предпочитаемым языком для DevOps, веб-серверов и микрослужб. Этот язык прост в изучении, удобен в развертывании, он очень быстрый, для него есть прекрасный набор инструментов разработки.

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

              Один из способов надежной, быстрой и масштабируемой обработки данных в Go состоит в использовании библиотеки Intel Data Analytics Acceleration Library (Intel DAAL) в программах Go. Эта библиотека предоставляет алгоритмы пакетной, интерактивной и распределенной обработки для целого ряда полезных задач.



              Поскольку Go прекрасно взаимодействует с C/C++, можно реализовать эту функциональность в программах Go без особых затруднений. При этом мы существенно выиграем по скорости: эти библиотеки уже оптимизированы для архитектуры Intel. Как показано здесь, в определенных операциях, например при анализе основных компонентов, Intel DAAL может работать в семь раз быстрее, чем Spark с MLlib. Это очень здорово! Было бы очень кстати задействовать такую мощь в приложениях Go.

              Установка Intel DAAL


              Библиотека Intel DAAL доступна в виде открытого исходного кода, для ее установки выполните следующие инструкции. На моем компьютере с Linux это было невероятно просто.
              1. Загрузка исходного кода.
              2. Запуск сценария установки.
              3. Настройка необходимых переменных среды (для этого также можно использовать предоставляемый сценарий shell).

              Перед интеграцией Intel DAAL в любую программу Go имеет смысл убедиться, что все правильно работает. Для этого можно воспользоваться различными руководствами по началу работы в документации Intel DAAL. В частности, в этих руководствах предоставляется пример приложения Intel DAAL для алгоритма разложения Холецкого. Ниже мы попробуем создать его на языке Go. Исходный пример алгоритма разложения Холецкого на языке C++ выглядит так.

              /****************************************************************************
              !  Copyright(C) 2014-2017 Intel Corporation. All Rights Reserved.
              !
              !  The source code, information and material ("Material") contained herein is
              !  owned by Intel Corporation or its suppliers or licensors, and title to such
              !  Material remains with Intel Corporation or its suppliers or licensors. The
              !  Material contains proprietary information of Intel or its suppliers and
              !  licensors. The Material is protected by worldwide copyright laws and treaty
              !  provisions. No part of the Material may be used, copied, reproduced,
              !  modified, published, uploaded, posted, transmitted, distributed or disclosed
              !  in any way without Intel's prior express written permission. No license
              !  under any patent, copyright or other intellectual property rights in the
              !  Material is granted to or conferred upon you, either expressly, by
              !  implication, inducement, estoppel or otherwise. Any license under such
              !  intellectual property rights must be express and approved by Intel in
              !  writing.
              !
              !  *Third Party trademarks are the property of their respective owners.
              !
              !  Unless otherwise agreed by Intel in writing, you may not remove or alter
              !  this notice or any other notice embedded in Materials by Intel or Intel's
              !  suppliers or licensors in any way.
              !
              !****************************************************************************
              !  Content:
              !    Cholesky decomposition sample program.
              !***************************************************************************/
              
              #include "daal.h"
              #include 
              
              using namespace daal;
              using namespace daal::algorithms;
              using namespace daal::data_management;
              using namespace daal::services;
              
              const size_t dimension = 3;
              double inputArray[dimension *dimension] =
              {
                  1.0, 2.0, 4.0,
                  2.0, 13.0, 23.0,
                  4.0, 23.0, 77.0
              };
              
              int main(int argc, char *argv[])
              {
                  /* Create input numeric table from array */
                  SharedPtr inputData = SharedPtr(new Matrix(dimension, dimension, inputArray));
              
                  /* Create the algorithm object for computation of the Cholesky decomposition using the default method */
                  cholesky::Batch<> algorithm;
              
                  /* Set input for the algorithm */
                  algorithm.input.set(cholesky::data, inputData);
              
                  /* Compute Cholesky decomposition */
                  algorithm.compute();
              
                  /* Get pointer to Cholesky factor */
                  SharedPtr factor =
                      staticPointerCast(algorithm.getResult()->get(cholesky::choleskyFactor));
              
                  /* Print the first element of the Cholesky factor */
                  std::cout << "The first element of the Cholesky factor: " 
              << (*factor)[0][0];
              
                  return 0;
              }
              

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

              Использование Intel DAAL в программах на языке Go


              Если речь идет об использовании библиотеки Intel DAAL в программах на Go, у нас есть несколько возможных вариантов.
              1. Непосредственный вызов библиотеки Intel DAAL из программы Go через функцию-оболочку.
              2. Создание многократно используемой библиотеки с определенной функциональностью Intel DAAL.

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

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

              Вызов библиотеки Intel DAAL непосредственно из Go


              Go предоставляет инструмент под названием cgo, который дает возможность создавать пакеты Go, вызывающие код C. В этом случае мы будем использовать cgo для организации взаимодействия нашей программы Go с библиотекой Intel DAAL.

              Кстати, использование cgo с программами Go сопряжено с определенными ограничениями, которые достаточно подробно обсуждаются в Интернете (в частности, см. обсуждение Дейва Чени (Dave Cheney) или эту статью компании Cockroach Labs). Принимая решение об использовании cgo, всегда принимайте во внимания эти ограничения или хотя бы просто помните о них. В данном случае мы готовы примириться с ограничениями cgo, чтобы воспользоваться преимуществами оптимизированной распределенной библиотеки Intel DAAL: эти ограничения с лихвой окупятся повышением производительности в определенных случаях с высокой вычислительной нагрузкой или с большими объемами данных.

              Для интеграции алгоритма разложения Холецкого из Intel DAAL в программу Go потребуется создать следующую структуру папок (в директории $GOPATH).
              cholesky`
              +-- cholesky.go`
              +-- cholesky.hxx`
              +-- cholesky.cxx`


              Файл cholesky.go — это наша программа Go, которая будет использовать алгоритм разложения Холецкого из библиотеки Intel DAAL. Файлы cholesky.cxx и cholesky.hxx — это определения/объявления C++, включающие Intel DAAL и указывающие компилятору cgo, какую функциональность Intel DAAL мы будем использовать. Рассмотрим каждый из них.
              Сначала файл *.cxx.

              #include "cholesky.hxx"
              #include "daal.h"
              #include 
              
              using namespace daal;
              using namespace daal::algorithms;
              using namespace daal::data_management;
              using namespace daal::services;
              
              int choleskyDecompose(int dimension, double inputArray[]) {
              
                  /* Create input numeric table from array */
                  SharedPtr inputData = SharedPtr(new Matrix(dimension, dimension, inputArray));
              
                  /* Create the algorithm object for computation of the Cholesky decomposition using the default method */
                  cholesky::Batch<> algorithm;
              
                  /* Set input for the algorithm */
                  algorithm.input.set(cholesky::data, inputData);
              
                  /* Compute Cholesky decomposition */
                  algorithm.compute();
              
                  /* Get pointer to Cholesky factor */
                  SharedPtr factor =
                      staticPointerCast(algorithm.getResult()->get(cholesky::choleskyFactor));
              
                  /* Return the first element of the Cholesky factor */
                  return (*factor)[0][0];
              }
              

              Теперь файл *.hxx.

              
              #ifndef CHOLESKY_H
              #define CHOLESKY_H
              
              // __cplusplus gets defined when a C++ compiler processes the file.
              // extern "C" is needed so the C++ compiler exports the symbols w/out name issues.
              #ifdef __cplusplus
              extern "C" {
              #endif
              
              int choleskyDecompose(int dimension, double inputArray[]);
              
              #ifdef __cplusplus
              }
              #endif
              
              #endif
              

              Эти файлы определяют функцию-оболочку choleskyDecompose на C++, использующую алгоритм разложения Холецкого Intel DAAL для разложения входной матрицы и вывода первого элемента множителя Холецкого (как в примере, приведенном в руководстве по началу работы с Intel DAAL). Обратите внимание, что в этом случае наши входные данные — это массив длины размерности матрицы (т. е. матрица 3 х 3 соответствует входному массиву длиной 9). Нужно включить extern “C” в файл *.hxx. В этом случае компилятор C++ будет «знать», что нужно экспортировать соответствующие имена, определенные в наших файлах C++.

              После определения функции-оболочки разложения Холецкого в файлах *.cxx и *.hxx можно вызвать эту функцию напрямую из Go. cholesky.go выглядит так.

              package main
              
              // #cgo CXXFLAGS: -I$DAALINCLUDE
              // #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
              // #include "cholesky.hxx"
              import "C"
              
              import (
              	"fmt"
              	"unsafe"
              )
              
              func main() {
              
              	// Define the input matrix as an array.
              	inputArray := [9]float64{
              		1.0, 2.0, 4.0,
              		2.0, 13.0, 23.0,
              		4.0, 23.0, 77.0,
              	}
              
              	// Get the first Cholesky decomposition factor.
              	data := (*C.double)(unsafe.Pointer(&inputArray[0]))
              	factor := C.choleskyDecompose(3, data)
              
              	// Output the first Cholesky dcomposition factor to stdout.
              	fmt.Printf("The first Cholesky decomp. factor is: %d\n", factor)
              }
              

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

              // #cgo CXXFLAGS: -I$DAALINCLUDE
              // #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
              // #include "cholesky.hxx"
              import "C"


              Чтобы использовать, требуется import “C”: это псевдоупаковка, сообщающая об использовании cgo. Если непосредственно перед командой импорта «C» стоит комментарий, то этот комментарий (он называется преамбулой) будет использован в качестве заголовка при компиляции компонентов C++ этого пакета.

              С помощью CXXFLAGS и LDFLAGS можно указать флаги компиляции и компоновки, которые cgo должен использовать при компиляции, а нашу функцию C++ можно добавить, используя // #include «cholesky.hxx”. Для компиляции этого примера я использовал Linux и gcc, что и указано выше с помощью соответствующих флагов. Впрочем, можно следовать этому руководству, чтобы определить, как скомпоновать приложение с Intel DAAL.

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

              // Define the input matrix as an array.
              inputArray := [9]float64{
              	1.0, 2.0, 4.0,
              	2.0, 13.0, 23.0,
              	4.0, 23.0, 77.0,
              }
              
              // Get the first Cholesky decomposition factor.
              data := (*C.double)(unsafe.Pointer(&inputArray[0]))
              factor := C.choleskyDecompose(3, data)
              
              // Output the first Cholesky dcomposition factor to stdout.
              fmt.Printf("The first Cholesky decomp. factor is: %d\n", factor)


              Уникальная особенность в этом случае (она обусловлена использованием cgo) состоит в том, что нужно преобразовать указатель на первый элемент нашего среза float64 в небезопасный указатель, который затем можно будет явным образом преобразовать в указатель *C.double (совместимый с C++) на нашу функцию choleskyDecompose. Упаковка в небезопасный указатель позволяет нам обойти ограничения безопасности типов, действующие в программах Go.
              Отлично! Итак, у нас есть программа Go, которая вызвала алгоритм разложения Холецкого из библиотеки Intel DAAL. Теперь пора собрать и запустить эту программу. Это можно сделать обычным образом с помощью go build.

              $ ls
              cholesky.cxx  cholesky.go  cholesky.hxx
              $ go build
              $ ls
              cholesky  cholesky.cxx  cholesky.go  cholesky.hxx
              $ ./cholesky 
              The first Cholesky decomp. factor is: 1
              $ 


              И результат готов! Разумеется, первый множитель разложения Холецкого равен 1. Мы успешно воспользовались библиотекой Intel DAAL непосредственно из Go. Впрочем, наша программа на Go выглядит достаточно странно с небезопасными указателями и фрагментами кода C. Кроме того, это одноразовое решение. Теперь попробуем реализовать эту же функциональность в виде многократно используемого пакета Go, который можно будет импортировать точно так же, как и любой другой пакет Go.

              Создание многократно используемого пакета Go с Intel DAAL


              Чтобы создать пакет Go, содержащий функциональность Intel DAAL, мы воспользуемся программой SWIG. В Go, помимо использования cgo, можно вызывать SWIG при сборке, чтобы компилировать пакеты Go, реализующие функциональность C/C++. Для такой сборки потребуется создать следующую структуру папок.

              choleskylib
              +-- cholesky.go
              +-- cholesky.hxx
              +-- cholesky.cxx
              +-- cholesky.swigcxx


              При этом файлы оболочек *.cxx и *.hxx могут остаться такими же. Но теперь нужно добавить файл *.swigcxx. Этот файл выглядит так.

              %{
              #include "cholesky.hxx"
              %}
              
              %include "cholesky.hxx"


              Теперь программа SWIG создает код-оболочку для функции разложения Холецкого, что позволит использовать этот код в качестве пакета Go.

              Кроме того, мы создаем пакет Go, пригодный для многократного использования (а не отдельное приложение), поэтому файл *.go может не включать package main или function main. Он должен просто определять имя нашего пакета. В данном случае назовем его cholesky. Теперь cholesky.go будет выглядеть так.

              package cholesky
              
              // #cgo CXXFLAGS: -I$DAALINCLUDE
              // #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
              import "C"

              (Снова указываем файлы в заголовке.)

              Теперь можно собрать пакет и установить его локально.
              $ ls
              cholesky.cxx  cholesky.go  cholesky.hxx  cholesky.swigcxx
              $ go install
              $ 


              Эта команда компилирует все необходимые двоичные файлы и библиотеки, к которым обращается программа Go, использующая этот пакет. Go «видит», что в нашей папке есть файл *.swigcxx, и автоматически использует SWIG для сборки пакета.
              Великолепно! Теперь у нас есть пакет Go, использующий Intel DAAL. Посмотрим, как сработают импорт и использование пакета.

              package main
              
              import (
              	"fmt"
              
              	"github.com/dwhitena/daal-go/choleskylib"
              )
              
              func main() {
              
              	// Define the input matrix as an array.
              	inputArray := [9]float64{
              		1.0, 2.0, 4.0,
              		2.0, 13.0, 23.0,
              		4.0, 23.0, 77.0,
              	}
              
              	// Get the first Cholesky decomposition factor.
              	factor := cholesky.CholeskyDecompose(3, &inputArray[0])
              
              	// Output the first Cholesky dcomposition factor to stdout.
              	fmt.Printf("The first Cholesky decomp. factor is: %d\n", factor)
              }
              


              Класс! Такой код намного чище по сравнению с прямым использованием Intel DAAL. Можно импортировать пакет алгоритма Холецкого, как и любой другой пакет Go, и вызвать заключенную в оболочку функцию как cholesky.CholeskyDecompose(...). Кроме того, в SWIG были автоматически обработаны и все небезопасные компоненты. Теперь можно просто передать адрес первого элемента нашего исходного среза float64 в cholesky.CholeskyDecompose(...).

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

              $ ls
              main.go
              $ go build
              $ ls
              example  main.go
              $ ./example 
              The first Cholesky decomp. factor is: 1
              $ 


              Ура! Все правильно. Теперь можно использовать этот пакет в других программах Go, если нам потребуется алгоритм разложения Холецкого.

              Выводы и ресурсы


              С помощью Intel DAAL, cgo и SWIG нам удалось встроить оптимизированный алгоритм разложения Холецкого в программы на языке Go. Разумеется, возможности не ограничиваются только этим алгоритмом. Аналогичным образом можно создавать программы и пакеты на языке Go, использующие любые алгоритмы, реализованные в Intel DAAL. Можно создавать нейросети с пакетной, интерактивной и распределенной обработкой, кластеризацией, ускорением, совместной фильтрацией и другими возможностями непосредственно в приложениях Go.

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

              Ресурсы по языку программирования Go
              • Присоединяйтесь к Gophers on Slack и поговорите с другими участниками канала #data-science, которые занимаются большими данными, анализом данных, машинным обучением и прочими аналогичными решениями с помощью Go.
              • Посетите сайт организации GopherData, где пользователи взаимодействуют с разработчиками средств управления данными, обработки, анализа, машинного обучения и визуализации данных на языке Go.
              • Отслеживайте GopherData в Twitter.
              • Используйте (и пополняйте) растущий перечень инструментов для Go.

              Ресурсы по DAAL

              Об авторе


              Дэниэл (@dwhitena) — доктор наук, опытный исследователь данных, он работает в компании Pachyderm (@pachydermIO). Он занимается разработкой современных распределенных конвейеров данных, включающих предсказательные модели, визуализацию данных, статистический анализ и другие возможности. Он выступал на конференциях в разных странах мира (ODSC, Spark Summit, Datapalooza, DevFest Siberia, GopherCon b lheubt), преподает исследование и анализ данных в компании Ardan Labs (@ardanlabs), поддерживает ядро Go для Jupyter и активно участвует в развитии различных проектов по интеллектуальному исследованию данных с открытым исходным кодом.
              Original source: habrahabr.ru (comments, light).

              https://habrahabr.ru/post/338002/


              Метки:  

              Наша методика расчета стека печатных плат

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

              Наша методика расчета стека печатных плат

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



                Сразу к делу — вот о чём написано в этой статье:
                • Материалы для производства печатных плат
                • Учет изменения толщины препрега в процессе изготовления PCB
                • Учет Etch Factor
                • Особенности расчета толщины металлизации
                • Учет паяльной маски

                Все описанное ниже — это не Know How, а по сути, собранные воедино и систематизированные данные из разных источников. На абсолютное знание мы также не претендуем.
                Итак, поехали.

                Материалы для производства печатных плат


                Преамбула (как обычно это происходит).
                Обычно инженер примерно оценивает стек платы, передает его производителю PCB. В ответ ему приходит много китайских бланков с предложениями — на которые он обычно соглашается. Сводятся они к изменению толщин ядер/препрегов, а также проводников и зазоров в CAM редакторе.
                Обычно оно и нормально. Но тут есть три минуса:
                • Итоговое изделие отличается от того, что описано в вашей КД (иногда чуть более, чем полностью).
                • Повторяемости результата при переходе к другому производителю — нет. Например у нас есть борд, который запускался на двух разных фабах с совершенно разными стеками (при этом исходные данные в обоих случая были одни и те же).
                • Если толщины проводников на печатной плате находятся в зоне 4 mil — то любое изменение их ширины в сторону уменьшения весьма серьезно влияет на потери. Если между проводником 6 mil и 5 mil разница незначительна, то между 5 mil и 4 mil — весьма существенна, а 4 mil и 3 mil — это с точки зрения потерь разные вселенные. (Вообще на наш взгляд идеальные топологии дифференциальной пары — 6-6-6 или 7-7-7).

                Поэтому мы предпочитаем сформировать стек так, чтобы его зависимость от особенностей конкретного производителя PCB сводилась к минимуму. Если вы работаете с одним и тем же вендором, то вполне реально сформировать стек так, чтобы его модификация производителем не требовалась совсем. Это экономия 1—2 недель при подготовке к производству.

                Кстати оффтоп.
                Наверняка кто-то нибудь захочет спросить — что лучше, сильносвязанные или слабосвязанные дифференциальные пары. Наше мнение: лучше слабосвязанные — их проще выровнять по длине. Можно позволить себе более серьезные бампы. Никаких особенных преимуществ сильносвязанных пар перед слабосвязанными (если не рассматривать странные топологии типа 5-14-5) c точки зрения SI на наш взгляд — нет. Для любителей формальных правил: одна-две ширины между проводниками в паре — нормально. Больше — уже не очень. Меньше — трудно выравнивать. Несмотря на то, что ЭМС показатели сильносвязанных пар сильно лучше, в абсолютном выражении это «сильно» — несущественно.

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


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

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

                Если значения Dk/Df приведены для разных частот, то рекомендуется использовать значения данных параметров для частоты, наиболее близкой к частоте Найквиста наиболее быстрого интерфейса на PCB. Например, если в PCB присутствует PCI Express Gen3, то следует использовать значения Dk/Df для частоты, наиболее близкой к 4 ГГц.

                Кто-то возразит: как же, ведь полоса того же Gen3 простирается аж до 18 ГГц. Это правда — но спецификация PCIe регламентирует RL и IL до Найквиста, да и не пройдут все эти адовые гигагерцы через коннекторы, переходные отверстия и печатную плату — затухнут по дороге. А если пройдут — это большой вопрос, понравится ли Вам результат.

                В ситуации, когда на PCB присутствует несколько разных высокоскоростных интерфейсов — не стоит в рамках стека одной платы использовать значения Dk/Df для разных частот. Несмотря на то, что такой подход является более верным с точки зрения расчета импеданса — он вызовет большие трудности при согласовании стека с производителем PCB (их тестовое оборудование настраивается на одну конкретную частоту).

                В случае, если значения Dk/Df значительно варьируются с частотой, а контроль импеданса критичен — имеет смысл, получив значения импеданса для реальной частоты интерфейса, пересчитать его, взяв Dk для некоторой единой частоты (самого критичного интерфейса). «Отнормированное» таким образом значение импеданса — указать в качестве целевого для контроля производителем PCB.

                Например вы делаете расчет 100 Омной трассы для частоты 4 ГГц, используете значение Dk для 4 ГГц, и в соответствии с полученными данными осуществляете трассировку. Далее, если у вас например есть интерфейсы, требующие расчета для 10 ГГц — подставьте значение Dk для более высокой частоты в исходный расчет. Допустим, при этом вы получите значение импеданса 105 Ом. Наш совет: вот 105 Ом и укажите производителю PCB для контроля. Не стоить морочить ему голову разными Dk для разных частот на одном и том же слое.

                Также не повредит на берегу поинтересоваться с каким стеклом работает фаб, чтобы не было потом проблем со сроками поставки. Потому что есть популярные препреги и не очень. Обычно на складе у него всегда в достатке 3-4 типа, из которых и стоит выстраивать стек PCB. Материалов с низкими потерями обычно на складе не бывает, в силу ограниченного срока хранения — поэтому применение чего-то особенного это всегда вопрос не столько цены, сколько сроков изготовления.

                Учет изменения толщины препрега в процессе изготовления PCB


                В таблице ниже приведены абсолютные значения изменения толщины одного слоя препрега для разных условий применения. Допуск на все значения составляет 10%.
                Условия Изменение толщины препрега при начальном значении
                Не более 2.3 mil Более 2.3 mil
                Прилегание к меди 0.5 oz с 30% заполнением 0.4 mil 0.4 mil
                Прилегание к меди 0.5 oz с 70% заполнением 0.1 mil 0.2 mil
                Прилегание к меди 1 oz с 30% заполнением 0.8 mil 0.9 mil
                Прилегание к меди 1 oz с 70% заполнением 0.3 mil 0.4 mil
                Прилегание к меди 2 oz с 30% заполнением 1.8 mil 1.9 mil
                Прилегание к меди 2 oz с 70% заполнением 0.8 mil 0.8 mil
                Расположен между двумя слоями препрега 9% 10%
                Прилегание к внешнему слою не изменяется не изменяется

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

                $H=T1x(1-\frac{S_{copper}}{S_{outline}})$


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

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

                Пример


                Необходимо рассчитать финишную толщину стека, приведенного на рисунке. На всех слоях металлизации используется медь 1 oz. Исходная толщина препрега 2116 равна 5.1 mil.


                Результирующий стек будет иметь вид:
                Тип слоя Начальная толщина Изменение толщины Финишная толщина
                Внешний 1.35 mil 1.35 mil
                Слой 2116 5.1 mil 5.1 mil
                Слой 2116 5.1 mill 0.9 mil 4.2 mil
                Внутренний сигнальный 1.35 mil 1.35 mil
                Core 39 mil 39 mil
                Внутренний Plane 1.35 mil 1.35 mil
                Слой 2116 5.1 mil 0.4 mil 4.7 mil
                Слой 2116 5.1 mil 5.1 mil
                Внешний 1.35 mil 1.35 mil
                Итого: 63.5 mil ± 10%


                Учет Etch Factor


                Выражение для расчета Etch Factor для процесса электрического осаждения меди представлено на рисунке:

                В таблице приведены значения Etch Factor для разных типов металлизации для различных производителей. Как видите, они сильно разнятся. Поэтому значение EF — это первое, что вы должны уточнить у вашего PCB-партнера.
                Тип слоя Фабрика 1 Фабрика 2 Фабрика 3 Фабрика 4
                EF W2-W1 EF W2-W1 EF W2-W1 EF W2-W1
                Внешний 0.5 oz 3.4 — 4 1 mil 3.4 — 4 1 mi 3.4 — 2 1.5 mil 2.6
                Внешний 1 oz 1.66 2.4 mil 2.6
                Внутренний 0.5 oz 1.75 0.8 mil 4.33 0.3 mil 1.73 1.75 mil 3
                Внутренний 1 oz 2.4 1 mil 4.33 0.6 mil 2.6 1 mil 3
                Внутренний 2 oz 1.5 — 2 mil 4.33 1.2 mil 2.6 2 mil 3
                Внутренний 3 oz 2.6 3 mil 3
                Внутренний 4 oz 2.3 4.5 mil 3


                Для случаев, когда информация о значении EF от конкретного производства отсутствует – можно считать, что EF принимает следующие значения:
                • внешние слои — 2.6
                • внутренние слои — 3.7


                Особенности расчета толщины металлизации


                Металлизация внешних слоев


                При расчете металлизации внешних слоев значение толщины меди весом 1 oz как правило принимается равным 1.37 mil. Рекомендуется отдельно задавать вес базовой меди и вес осаждаемой меди. Итоговое значение получается в результате суммирования этих двух параметров. Типовые значения приведены в таблице:
                Base copper Plating copper
                0.7oz 1oz 2oz
                0.5oz 1.644 mil 2.055 mil 3.425 mil
                1oz 2.329 mil 2.74 mil 4.11 mil
                2oz 3.699 mil 4.11 mil 5.48 mil
                3oz 5.069 mil 5.48 mil 6.85 mil


                Металлизация внутренних слоев


                Для внутренних слоев значение толщины меди весом 1 oz, как правило, принимается равным 1.3 mil.

                Учет паяльной маски


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

                В случаях, когда явно не указано иное, можно считать, что паяльная маска имеет следующие параметры:
                • Dk — 3.7
                • Df — 0.025
                • Толщина — 0.8 mil

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

                Некоторые фабрики считают значения C1 и C3 равными толщине металлизации (T1), а C2 – 0.8 mil. Правильность данного подхода приблизительно подтверждается реальными данными, полученными после производства PCB.

                Один из наших PCB-партнеров считает толщину паяльной маски на сплошных участках меди 0.79 — 1.18 mil, на краях проводников 0.2 mil. Также данный производитель при расчете стека рекомендует не включать паяльную маску в расчет, так как при травлении внешних слоев происходит малейший перетрав (то есть увеличение значения импеданса), который маской компенсируется в номинал теоретического измерения импеданса внешних слоев без маски.
                Это, кстати, хороший пример того, что при работе с данным производством — толщина трасс на вашей PCB будет меньше, чем заложено в рисунке печатной платы.

                Итоги


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

                https://habrahabr.ru/post/338382/


                Метки:  

                [recovery mode] Как оправдать ожидания потребителей в отношении Интернета вещей? (результаты опроса)

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

                Как оправдать ожидания потребителей в отношении Интернета вещей? (результаты опроса)

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

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



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

                В ходе опроса потребителей вырисовалось три основных направления, вызывающих большинство вопросов:

                1. Проблема доверия к подключенным объектам
                2. Насущная потребность в унифицированном потребительском опыте
                3. Персонализация сервисов

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

                Знакомьтесь: Поль и Эмма.



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

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



                Но стремления пользователей отнюдь не ограничиваются лишь возможностью управления своей жизнью через смартфон. К примеру, Поль хотел бы использовать свой телефон в качестве удостоверения личности. Подобный сценарий использования уже реализован в Колорадо (США), где в пилотном режиме развернута система цифровых водительских удостоверений (Digital Drivers Licenses). Подчеркнем еще раз, для реализации подобных инициатив необходимо более тесное взаимодействие между различными участниками отрасли.



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



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

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

                https://habrahabr.ru/post/337498/


                Метки:  

                Диспетчер задач на и для Javascript

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

                Диспетчер задач на и для Javascript

                  image

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

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

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

                  И да, это не про Node.js, библиотека написана для старого доброго браузерного Javascript.



                  Базовая функциональность



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

                      
                  


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

                  task:{
                    // код, который будет выполнять эта задача
                    handler: ()=>{conslole.log("Hello world!")}
                    // задержка перед выполнением
                    delay: 5000,
                    // повторять или нет, по сути выбор между setTimeout и setInterval
                    repeat: false,
                    // имя задачи, должно соответствовать правилам именования переменных
                    name: "task1",
                    // описание задачи, используется только в логах и интерфейсе
                    description: "This task created at the name of Invisible Pink Unicorn!"
                    // время выполнения, для цикличных задач время первого запуска
                    at: "2017-09-20",
                    // идентификатор процесса
                   pid: 42
                  }
                  

                  Для хранения и управления ими создадим экземпляр библиотеки:
                  var verboseLogs = true,
                    verboseTime = true,
                    writeLogs = true;
                  var cs = new Chronoshift(verboseLogs, verboseTime, writeLogs) ;
                  


                  Имена переменных достаточно понятны, однако разъясним аргументы конструктора подробнее:
                  verboseLogs — требуется ли выводить логи работы в консоль
                  verboseTime — требуется ли выводить время события, может использоваться в вызове без вывода лога
                  writeLogs — требуется ли хранить логи.
                  Хранение логов может стать достаточно дорогой операцией, примерно 0.1 КБ на событие. В современном мире эта цифра может показаться смешной, но… Тема хорошо раскрыта в «Ученике Чародея» Диснеем ещё в прошлом веке.

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

                  cs.runTask( () => {console.log("task 1 executed")}, 3000);
                  


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

                  cs.runTask( () => {console.log("task 1 executed")}, 3000)
                  [20.09.2017, 12:33:58.326]
                  Creating task: {"delay":3000}
                  [20.09.2017, 12:33:58.327]
                  Added a task task_7a0dh9bllhg with timeout 3000
                  2
                  task 1 executed
                  [20.09.2017, 12:34:01.327]
                  Task executed: task_7a0dh9bllhg


                  Как видно из логов, задача была создана, поскольку имя ей не было задано, имя было сгенерировано случайным образом.
                  В пояснении нуждается цифра 2 — это идентификатор процесса. Его выкидывает в консоль нативная функция setTimeout/setInterval. Подробнее можно почитать здесь.
                  Далее задача была выполнена и лог этого также был выведен.

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

                  cs.setLogging(false, false, true);


                  Теперь лишняя информация не будет выводиться в консоль, но доступ к ней останется через cs.logs. Если вам потребуется посмотреть логи в читаемом виде, вызовите метод showLogs:



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

                  //выполним код за пять минут до полуночи
                  cs.runTaskAt(()=>{console.log("Уж полночь близится, а Германа всё нет!");}, "22:55", "German");
                  //или утром седьмого июля
                  cs.runTaskAt(()=>{console.log("Пора готовить топоры!");}, "07-07 07:07:07", "p777", "Время трёх топоров");
                  


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

                  Управление задачами


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

                  cs.runTask( () => {console.log("task 1 executed")}, 3000, false, "task1");
                  


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

                  cs.executeTask("task1");
                  


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

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

                  cs.stopTask("task1");
                  cs.restartTask("task1");
                  


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

                  // создадим задачу, которая выполнится через три секунды
                  cs.runTask( () => {console.log("task 1 executed")}, 3000, false, "task1");
                  ...
                  //какой-то код выполнялся две секунды, задача должна выполниться через секунду но мы её остановим
                  cs.stopTask("task1");
                  ...
                  //какой-то код выполнялся ещё две секунды, то есть всего прошло 4 секунды и мы перезапускаем задачу
                  cs.restartTask("task1");
                  //задача выполнится ещё через три секунды, итого семь секунд спустя
                  


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

                  //в качестве аргумента для любого метода изменяющего задачи могут использоваться как имя так и  id процесса
                   cs.removeTask(2);
                  


                  Графический интерфейс



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


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

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

                  Подводные камни


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

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

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

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

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

                  Если перевести в человекочитаемые единицы, то максимальная задержка составит чуть меньше чем 24 дня 20 часов 31 минуту и 23,65 секунды. В библиотеке поставлена проверка на переполнение.

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

                  Небольшое послесловие



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

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

                  https://habrahabr.ru/post/338336/


                  Метки:  

                  Бесконечные потоки с помощью Observable и доказательства

                  Среда, 20 Сентября 2017 г. 23:46 + в цитатник
                  Implozia сегодня в 23:46 Разработка

                  Бесконечные потоки с помощью Observable и доказательства

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

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


                    Итак, собственно вот ссылка на гит, можете склонировать, собрать apk и проверить сами, cpu в пике чуть больше 3%, сборщик мусора, тоже замечательно делает свою работу, утечек нет, по крайней мере это все на моем устройстве, чтож, проверьте сами, если интересно: git clone Xsinh@bitbucket.org/Defolte/infinitytest.git

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

                    https://habrahabr.ru/post/338372/


                    Метки:  

                    Мимикрируй: как рекрутеру стать своим в IT-сообществе

                    Среда, 20 Сентября 2017 г. 20:24 + в цитатник
                    blog_potok сегодня в 20:24 Управление

                    Мимикрируй: как рекрутеру стать своим в IT-сообществе

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



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

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



                      В чем проблема?


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

                      На это есть причины?


                      Определенно.



                      Причина №1 = Недостаток знаний


                      Мы не хотим обвинять во всем коллег, которые с ужасом врываются в чаты Java разработчиков и ищут там тех, кто готов работать с SQL (СРОЧНО!!!) или тех, кто считают, что Java и JavaScript — одно и то же.

                      Тру стори от Ани Атрошкиной из INDEX, которую рассказал ей 1С разработчик:

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

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

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

                      Блог Stackoverflow: наверное, самый толковый блог про то, как общаться и не облажаться с терминами и подходом.
                      Хабрахабр: потому что если у вас есть вопрос, тут точно на него есть ответ
                      Блог Devskiller: отличный блог про поиск, сами его читаем постоянно
                      Книги Джоэла Спольски о программировании и подборе разработчиков
                      Книга “Совершенный код. Мастер-класс” Стива Макконнелла: потому что даже если кажется, что она устарела, всё равно она полезнее кучи других пособий
                      Блог Amazing Hiring: ребята знают, что делают

                      +
                      И ещё 31 блог для tech-рекрутеров (хватайте и бегите)

                      Пристать к хорошему разработчику, который не обидит
                      Это вариант для тех, кто хочет, чтобы для него базовые понятия разложили по полочкам. Короче, в студию приглашаем IT-коуча! :D Если вы HR в компании, зовите вашу IT-команду на кофе и просите ответить на вопросы, которые у вас есть.

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

                      Посещать мероприятия про IT
                      Отраслевые мероприятия — это тоже для вас. Мы категорически не разделяем позицию IT-сообщества “рекрутерам тут не место”. Обе стороны выигрывают: специалисты прокачивают свои навыки и… другие специалисты тоже прокачивают навыки и лучше узнают аудиторию. Обычно такие сходки бесплатны и могут быть, конечно, засекречены (OH GOD WHY). И для этого нужно быть постоянно в курсе того, что происходит на рынке и в сообществе разработчиков, с которыми вы работаете.

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

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

                      Понимать внутренние процессы компании (“Я знал, но забыл”)
                      Архитектура проекта? Баг трекер? Где таски ставят разработчики? Оупесорсный ли проект?

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

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

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

                      Причина №2 = Непонимание того, кто есть кто


                      Пора рассказать всем, что Сеньор помидор и Senior Front-End Developer — разные люди. Знаем, звучит жестоко.

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

                      “Junior – делает то, что скажут, за ним перепроверяет всё
                      Middle — он уже понимает, что делает и предлагает свои варианты
                      Senior — предлагает, что нужно сделать, сам делает и подчищает концы за первыми двумя
                      CTO — контролирует все процессы и ругается”

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

                      Причина №3 = Невнимательность


                      У вас мало времени и куча вакансий? Конечно, лучший выход начать писать всем подряд!
                      Плохая шутка, зато про реальные кейсы.

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

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

                      Причина №4 = Отсутствие личного подхода


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

                      Есть несколько простых правил, которые вообще должны работать не только в IT-рекрутменте.

                      — Правило “личные письма — чистая совесть”:
                      Обращение по имени, детали из резюме в письме, попытка расставить приоритеты и почувствовать себя в шкуре человека, которому пишете.

                      — Так уж случилось, что не вы выбираете канал коммуникации, а кандидат — это нормально идти навстречу. И если он написал, что ему удобно общаться в Viber — так тому и быть.

                      — Общайтесь просто и без занудства. Это никак не противоречит тому, чтобы писать, используя классную терминологию правильно. Но вот от “в целях проведения тестирования в рамках этапа подбора на вакансию БЛАБАОЛААБА” — оставим это для тех кандидатов, кому подобное близко. Вряд ли it-специалисты — это та самая аудитория.

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

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

                      — Опоздал – кандидата потерял (и сам виноват).

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

                      Что же делать, чтобы все жили долго и счастливо


                      Начните с себя и с пересмотра процесса подбора



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

                      1. Создайте mind-map с терминами, которые будете использовать в подборе (можно для этого почитать все вакансии в it, которые найдете выложенными в каналах/чатах)

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

                      3. Подпишитесь на рассылки, которые могут быть полезны вам. Нет другой такой сферы, в которой знания так стремительно устаревают, так что одноразовое использование информации и их загрузка в мозг — это не решение проблемы. Да и подумайте сами, вот что вы из университетской программы вообще помните? Не ходите за информацией сами, позвольте ей падать прямо в ящик с письмами.тРассылки резюме кандидатов (Мой Круг тот же!)], рассылки статей про новые технологии, каналы в Telegram, в которых девелоперы делятся болью (боже, это же прям святой источник данных для вас), группы на FB, беседы на форумах и в открытых чатах в Slack.

                      4. Соберите грамотные Boolean search’и и X-ray после того, как разобрались с вакансией. На каждую вакансию прям подбирайте каждый раз, добавляйте, если видите, что какие-то части запроса устаревают. Если вдруг решили искать не только в Москве, а в LORD HELP ME всей Вселенной.

                      5. Тестируйте площадки. Skype может быть для php, Telegram для ios’ников, а Москва для дорогих разработчиков, ггг. Попробуйте Instagram, чего бы нет! Прям анализируйте новые инструменты и источники, отказываясь на неделю от чего-то — ”всё, неделю никакого гихаба!”. Продержитесь? Сколько оттуда по воронке провалится кандидатов? Сколько не отвалятся по пути? Без аналитики вы всё время будете тыкать пальцем в небо, а хорошие ребята, создающие CRM’ки для рекрутмента, не для того страдают, чтобы вы аналитику в блокноте считали.

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

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

                      Пис.
                      Original source: habrahabr.ru (comments, light).

                      https://habrahabr.ru/post/338358/


                      Зачем нужен БЭМ

                      Среда, 20 Сентября 2017 г. 19:00 + в цитатник
                      htmlacademy вчера в 19:00 Разработка

                      Зачем нужен БЭМ


                        Следуете ли вы БЭМу, и насколько он востребован вне Яндекса?

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


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


                        В основу того, что мы сейчас называем БЭМом, легла идея независимых блоков, которую Виталий Харисов сформулировал и презентовал в 2007 году на первой российской конференции по фронтенду. Это было настолько давно, что тогда даже слова «фронтенд» ещё не было, тогда это называлось клиент-сайд.


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


                        #menu ul > li {
                          color: old;
                        }
                        .menu-item {
                          color: bem;
                        }

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


                        .block {}
                        .block_mod {}
                        .block__element {}
                        .block__element_mod {}

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


                        Изначально АНБ, а потом и БЭМ, решали задачу важную для вёрстки любых масштабов: предсказуемое поведение и создание надёжного конструктора. Вы же хотите, чтобы ваша вёрстка была предсказуемой? Вот и Яндекс тоже. Ещё это называется «модульность» — о ней хорошо написал Филип Уолтон в «Архитектуре CSS», ссылка на перевод в описании.


                        Через пару лет в Яндексе окончательно сформулировали нотацию БЭМ. Любой интерфейс предлагалось разделять на блоки. Неотделимые части блоков — элементы. У тех и других есть модификаторы.



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


                        Для полной независимости блоков мало назвать классы правильно или изолировать стили, нужно собрать всё, что к нему относится. В проекте по БЭМу нет общего script.js или папки images со всеми картинками сайта. В одной папке с каждым блоком лежит всё, что нужно для его работы. Это позволяет удобно добавлять, удалять и переносить блоки между проектами. Потом, конечно, все ресурсы блоков при сборке объединяются в зависимости от задач проекта.


                        Когда БЭМ вышел за пределы Яндекса, сначала его воспринимали как магию и старались воспроизводить дословно, вплоть до префиксов b- у каждого блока. Такой смешной карго-культ.


                        .b-block {}
                        .b-block--mod {}
                        .b-block__element {}
                        .b-block__element--mod {}

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


                        .block {}
                        .block--mod {}
                        .block__element {}
                        .block__element--mod {}

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


                        Возьмём, к примеру, русский язык. Мы же пишем с прописной имена людей, названия и прочее такое? Пишем. Чтобы легко потом считывалось: это Надя или надежда на лучшее? Уж не говоря про знаки препинания и другие полезные договорённости. Вот буква «ё», например, смягчает… так, о чём мы? Да, БЭМ.


                        До БЭМа были проекты с портянками стилей, которые нельзя трогать. Они копились годами, слой за слоем, как обои в древней коммуналке. Их просто подключали первыми, а потом перезаписывали что мешало. Когда у вас есть div { font-size: 80% } — это даже уже не смешно.


                        /* Не смешно */
                        
                        div {
                          font-size: 80%;
                        }

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


                        Были и другие методологии: OOCSS Николь Салливан, SMACSS Джонатана Снука, вариации БЭМа и целые фреймворки. Даже у нас на продвинутом интенсиве можно было выбрать любую методологию для вёрстки учебного проекта.


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


                        Модульность и изоляцию стилей блока можно решить ещё лучше. Есть веб-компоненты, CSS-модули, куча решений CSS-в-JS и даже, прости господи, атомарный CSS. Но нет единого решения накопившихся проблем на следующие 10 лет, каким когда-то стал БЭМ. Что это будет? Посмотрим. Я ставлю на веб-компоненты.


                        А пока, если вы опишете интерфейс по БЭМу — код будет организован, предсказуем, расширяем и готов для повторного использования. Не только для вас, но и для других.


                        Видеоверсия





                        Вопросы можно задавать здесь.

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

                        https://habrahabr.ru/post/337286/


                        Метки:  

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