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

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

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

Прорыв на рынке автоматизации процессов управления бизнесом

Понедельник, 07 Августа 2017 г. 18:46 + в цитатник
BE FLEXBBY

Роман Чёсов: «Да, мы создали интеллектуальную платформу Flexbby Parametric, на базе которой мы можем предлагать заказчику невозможное – с нашими приложениями можно работать «вечно».

image

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

Роман Чёсов, директор по развитию компании «Флексби Солюшнс»: «Непросто пробиться сквозь информационный фон рекламы, и, конечно, многие компании имеют задел – наработали репутацию, раскрутили свой бренд. Международные компании пришли на рынок с опытом развития на других рынках, с бюджетами, именем. Предложений на рынке много, но это иллюзия, что рынок насыщен. В 2016 году наша компания начала выводить прорывную технологию в области разработки приложений по автоматизации бизнес процессов. Сейчас все более и более актуальным становится автоматизация сквозных процессов, которые раньше автоматизировались с помощью нескольких систем и внесистемных процессов, основанных на работе с «файлами по почте». Мы пионеры, создатели нового подхода к автоматизации процессов за счет параметризации бизнес логики и объектов. Это новая ниша на рынке программного обеспечения для бизнеса».

Разве можно конкурировать с акулами на этом рынке? Вы можете предложить что-то, что нет у них?

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

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

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

А почему это не могут сделать другие разработчики?

Роман Чёсов: У нас есть ноу-хау – слой параметризации в нашей платформе Flexbby Parametric.
Название платформы отражает суть наших технологических возможностей – мы создаем приложения с высоким уровнем кастомизации. Параметризация существенно облегчает и ускоряет модификацию приложения под нужды компании, и позволяет приложению развиваться буквально вместе с компанией. Система настраивается и донастраивается без программирования.

Имеет ли ваша компания отраслевую специализацию, и какой уже опыт внедрения вашей технологии?

Роман Чёсов: Мы работаем с компаниями любой индустрии. Но мы работаем с крупными проектами, где пользоваться системой будут 50 пользователей и больше. Именно для крупных компаний, сложных процессов жизненно необходимо автоматизировать процессы управления по самым совершенным технологиям. Уникальная архитектура Flexbby Parametric позволяет внедрять приложения в любой индустрии, учитывая специфику оргструктуры и процесса принятия решений в корпорации без дополнительных инвестиций в разработку. Приложения масштабируются на неограниченное количество пользователей. Первыми компаниями, где были внедрены решения на базе Flexbby Parametric стали Раменский комбинат хлебопродуктов и NVision (сервисная компания в области IT&Telecom).

http://flexbby.com
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335102/


Метки:  

[Перевод] Надёжность Go в инфраструктуре Dropbox

Понедельник, 07 Августа 2017 г. 18:41 + в цитатник
Об авторе: Тэмми Бутов — технический руководитель инфраструктуры для разработчиков в Dropbox. Это управление потоками кода — полный цикл использования Go в Dropbox, от программирования до выпуска. Она выступала на конференции GopherCon 2017 на тему того, как разработчики Dropbox создают и поддерживают работу крупномасштабных сервисов на Go.

Как Dropbox пришёл к использованию Go


Тэмми цитирует статью Роба Пайка «Go в компании Google: языковой дизайн в службе разработки ПО» от 2012 года, поскольку она в целом хорошо передаёт, почему Go хорошо работает и в Dropbox:

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

Масштаб Dropbox впечатляет:

  • Более 500 млн пользователей
  • 200 000 бизнес-пользователей
  • 500 петабайт пользовательских данных
  • Многоэкзабайтная система хранения Go

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

  • Создавать надёжные системы
  • Создавать безопасные системы
  • Объединять надёжность и безопасность в изначальной архитектуре
  • Надёжность 99,9999999999% (двенадцать девяток)
  • Доступность 99,99%

Состояние Go в Dropbox


Сегодня б'oльшая часть инфраструктуры Dropbox написана на Go. В частности:

  • У сервера репозиториев Go — 150 уникальных контрибуторов (из 500 разработчиков в компании)
  • Более 15 групп создают и поддерживают работу сервисов Go в Dropbox
  • По всей компании в Dropbox написано 1,3 млн строк на Go

некоторые из ключевых систем, написанных на Go:

  • RAT: ограничение скорости и дросселирование (приглушение) трафика
  • HAT: замена memcached
  • AFS: файловая система для замены глобального Zookeeper
  • Edgestore: распределённая база данных
  • Bolt: для сообщений
  • DBmanager: для автоматизации и мониторинга более 6000 баз данных Dropbox
  • Jetstream, Telescope, маршрутизация блоков и многое другое

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

Как Dropbox начал использовать Go?


Тэмми поделилась несколькими историями, как Dropbox естественным путём перешёл на Go.

Прототип ограничителя скорости на Go с хакерской недели
До хакерской недели, которая случилась однажды, разработчики Dropbox внедряли ограничение скорости и дросселирование отдельно для каждого сервиса, где требовалось. Но для этой хакерской недели один инженер Dropbox решил создать единую реализацию этих функций. Так родился RAT (Rate limiting And Throttling).

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

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

Для управления этим процессом инженер Dropbox разработал Dbmanager — UI в вебе для быстрого просмотра состояния всех более чем 6000 баз данных. Информация о статусе также передаётся в другие системы.

Обновление версий Go в Dropbox
Имея сотни разработчиков, Dropbox аккуратно координирует обновление основных версий Go. Тэмми не упомянула о каких-то определённых проблемах, что указывает на плавный процесс!

Некоторые интересные факты:

  • Dropbox недавно закончил миграцию сервисов продакшна с Go 1.5 на 1.6.
  • Для отслеживания процесса обновления они создали простой документ Dropbox Paper, где владелец каждого сервиса отчитывается о прогрессе и запрашивает помощь при необходимости.
  • Dropbox пропускает версию Go 1.7 и сразу перейдёт на Go 1.8, когда миграция на Go 1.6 полностью завершится (включая сервисы не в продакшне).

Как инженеры Dropbox осваивают Go


Каждый инженер Dropbox проходит через один и тот же строгий процесс освоения Go, который состоит из следующих этапов:

  • Чтение инфраструктурной топологии, руководства по стилю Go и руководства по стилю Protobuf
  • Строгие, но дружелюбные анализы кода
  • Создание маленького приложения (в App Store) на Go
  • Изучение Bazel для сборки и тестирования кода Go

Для опытного программиста процесс занимает около недели.

Что прошло гладко с внедрением Go в компании Dropbox? А что нет?


В целом, использование Go в Dropbox’s было очень удачным.

  • На Go легко показать высокую производительность труда.
  • На Go легко писать и использовать сервисы. (И людям нравится и то, и другое!)
  • Стандартная библиотека очень хороша.
  • Инструменты отладки (в основном!) работают хорошо.

Здесь один из важных фактов состоит в том, что в Dropbox нет попыток переписать сервисы Go на других языках. Это знак, что люди в целом довольны. (Тэмми выдала интригующую деталь: в Dropbox немного используют Rust. Но его не считают заменой для Go).

Что сложного Dropbox нашёл в Go?


Наибольшей сложностью Тэмми назвала работу с состоянием гонки.

  • Состояние гонки данных — самый трудный баг для отладки, для обнаружения, исправления и т. д.
  • Несколько инженеров Dropbox особенно хороши в обнаружении таких багов, а остальные опираются на их опыт.
  • Детектор состояния гонки в Go не всегда помогает. Нужно понимать, когда он беспомощен.
  • Важно аккуратно проектировать программы Go, если требуется одновременный доступ к данным.

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

https://habrahabr.ru/post/335056/


Метки:  

NeoDelphi`низм

Понедельник, 07 Августа 2017 г. 18:32 + в цитатник

Оглавление


  • Предпосылки
  • Основная концепция
  • Субъекты, объекты и душа
  • Мироустройство
  • API




Предпосылки



Сказ о том, как программирование влияет на мировоззрение.
Основой создания NeoDelphi`низм послужил Delphi`низм, основателем которого является Евгений Гусев. Он изъявил следующую проблему:
Тип чтоооо будет, если челик коснётся провода, по которому 220В + 880А идёт?

Евгений Гусев


И тут возникла идея о том, что в этот момент прикосновения (человек умрёт) освободиться память, как в огромном компьютере. Соответственно подумав над этой проблемой и появилась идея создать течение NeoDelphi`низм.

Немного из Delphi`ного писания:

Кстати
Я не основатель
Я бог
А ты тип библию написал
Моисей короч ты

TDelphi Act 0


И ш
Ты написал то библию уже?

TDelphi Act 1




Основная концепция



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

image

Отсюда можно ввести новое понятие ЖЦЧЖ:
Жизненный цикл человеческой жизни (ЖЦЧЖ) — это процесс, длящийся во времени, от самого создания (выделения памяти) субъекта типа человека, до уничтожения (освобождения) субъекта типа человек. Понятие субъекта описывается в следующем разделе.

Возникают следующие основные вопросы:
  • Откуда выделяется память?
  • Кто ответственен за освобождение памяти?
  • Существует ли адресация?

Рассмотрим каждый из них.

Откуда выделяется память



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

Кто ответственен за освобождение памяти?



Ответственным за освобождения памяти является Garbage Collector. В различных культурах и верованиях его называют Смертью.

Существует ли адресация?



Да. Существуют два типа адресации.
image

Ещё одно из важнейших понятий — это указатель:
Указатель (Pointer) — это бесформенный объект, который не поддаётся рационализму.

Абсолютная адресация выглядит следующим образом:

image

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

Как мы видим, Душа является единственным указателем на Субъект. Таким образом при создании (выделении памяти) создаётся душа, которая указывает на физическую оболочку Субъекта. То есть теперь мы можем объяснить, почему издавна считается, что душа покидает тело, так как Душа является бесформенным объектом, то в момент, когда Душа во сне покидает физическое тело, оно просто на время перестаёт на него указывать.

Сразу же возникает вопрос: «А может ли возникнуть утечка памяти?». Нет. Не возможна, так как указатель использует специальный метод для сохранения адреса и специальный метод для возврата по сохранённом адресу.

Относительная адресация выглядит следующим образом:
image

Относительная адресация — это косвенное указание на Субъект. Относительный адрес формируется по известным хар-кам Субъекта.

То есть, любой Субъект, который имеет адрес на другого Субъект, например его (ФИО + Дата Рождения) относительно указывает на него. При такой адресации, возможны неточности, так как может происходить коллизия при указании на Субъект.

Субъекты, объекты и душа



Душа — это экземпляр класса TSoul, который является указателем на Субъект.
image

Субъект — это совокупность классов (полиморфных шаблонов), которые в совокупности организуют собственную иерархию и систему, которая способна к осуществлению метода эксзистенциию.
image

Это упрощённая схема. Вспомнив биологию, схему можно дополнить различными детали. То есть любой Субъект создаётся по такому принципу:
  1. Определяется набор клеток необходимый для существования
  2. Определяется организм с необходимыми функциями для экзистенции
  3. Создаётся Субъект относящийся к конкретному классу
    image
  4. Затем происходит создание экземпляра класса TSoul, который является указателем на наш Субъект
  5. Субъект вызывает метод TSubject.Existance() и выполняет до тех пор, пока Garbage Collector не освободить память.


Следующий процесс изображён на схеме:
image

Мироустройство


Оно изображено не схеме. Теперь надо объяснить как всё это работает.
image

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

Никто не знает, как и когда появился Cruth. Это не поддаётся рационализму. Остаётся лишь это воспринимать как идеи.

Borland (Бог Борладн) — бесформенный Бог, под который по ошибке была выделена память и теперь весь мир существует благодаря ему.
Digia (Бог Дигиа) — бесформенный Бог, который был создан с намерением исправить деяния Бога Borland. Уже 4000 тысячи лет идут Holy Wars…

Как мы видим Бог Borland унаследовал от себя два основных класса TSoul и TEdugin:
TSoul — это основной указатель на Субъект, как уже говорилось ранее.
TEdugin — это отдельный Субъект типа челвоек, который был создан для того, чтобы установить баланс между Borland & Digia, путём изучения обоих систем. Но у Borland дургие планы на TEdugin, он является проповедником Delphi`низма, сам того не подозревая.

Затем Borland создал TSubject, чтобы создать себе армию для очередной Holy Wars с Digia. Но было бы слишком жестко создать чисто человека и заставить его воевать, поэтому Бог Borland создал всё остальное и теперь мы уже получили всё то, что наблюдаем каждый день.

Можно заметить, что Бог Digia совсем иначе подходит к решению проблемы. Он унаследовал от себя QSoul и создал QGod. То есть концепция указателя осталась прежней, но теперь во главе стоит QGod.

QGod — это человекоподобная сущность, которая имеет возможность создавать QSubject и QObject.

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

В заключении об мироустройстве можно сказать, что однозначно существует GC, Cruth и Borland, Digia. Не подозревая того, вечно идёт Holy War за выделение памяти под Borland или Digia, но уже давно устоялось, что Borland вышел победителем, иначе мы бы уже давно вступили в контакт с QGod`s. Даже если и есть представители QGod`s, они прячутся и не выдают себя, чтобы GC не собрал их и не пересоздал их под Borland.

API


У мира есть API! Но чтобы получить к нему доступ мы должны получить контроль над нашим указателем (TSoul). Именно этим занимаются восточные религии.

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

https://habrahabr.ru/post/335100/


Метки:  

[Из песочницы] Ruby on Rails для разработки маркетплейса

Понедельник, 07 Августа 2017 г. 17:54 + в цитатник

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


Коротко о том, что такое "маркетплейс" и его специфике


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


  • В маркетплейсе не один, а множество различных брендов

  • Самому продавцу нет необходимости заботиться о функционале магазина. Его задача – предоставить информацию о своих товарах

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

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

И это лишь основные моменты. Таким образом, покупатель получает удобную площадку, где есть буквально всё; продавец получает больше покупателей без лишних затрат на промо (чем не дополнительный канал продаж?); владелец маркетплейса получает доход без лишних "телодвижений" (ведь, все, что ему необходимо делать – не изготовлять товары и доставлять их, а создать и поддерживать маркетплейс).


В качестве примера маркетплейса можно рассмотреть Amazon, Airbnb, Uber, Spotify или OLX. Эти гиганты давно себя зарекомндовали на рынке. Кроме того, не следует забывать и про App Store с Google Play, ведь это тоже маркетплейсы. И мы практически каждый день ими пользуемся.


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


B2B (англ. "business to business"),
mCommerce (сокращение от "мобильная коммерция"),
Crowdfunding (от англ. "crowdfund" – "финансирование посредством сбора денег у сообщества"),
C2C (англ. "customer to customer" – "потребитель для потребителя"),
eCommerce (сокращение от "электронная коммерция"),
B2C (англ. "business to customer"),
peer-to-peer (от англ. "равные для равных")
auction platforms (от англ. "аукцион")


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


Способы создания онлайн маркетплейсов


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


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


  • Дизайн интерфейса
  • База данных для веб приложения и язык программирования
  • Авторизация и безопасность
  • Функционал для инфтерфейсов покупателя и продавца
  • Функционал товарных списков
  • Процесс заказа
  • Функционал совершения оплаты и получения средств на счет
  • Возможность для состевления рейтингов и написания отзывов
  • Напоминания и уведомления
  • Организация возможности поиска
    И это далеко не все...

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


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


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


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

Для разработки с нуля используются различные фреймфорки (англ. "web application framework").


Разработка онлайн маркетплейса с Ruby on Rails


Несмотря на то, что для каждой платформы находится много любителей и противников (маркетплейсы также часто создаются на платформах Laravel, Django, Meteor), мы предпочитаем именно Ruby on Rails.


И вот почему:


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


  2. Эта же простота разработки приводит к следующему преимуществу – значительному сокращению времени на разработку. Что может быть лучше, если проект можно запустить в два раза быстрее, чем планировалось ранее? К тому же, именно из-за простоты, команда разработчиков сравнительно невелика. А это – очевидная экономия.


  3. RoR рассчитан на сайты с большим количеством информации. Другими словами, если нужно предусмотреть наполнение сайта контентом, то нет ничего лучше, чем Ruby on Rails. Это очень важно для CRM и CMS систем.


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

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


Существует огромное количество маркетплейсов, возданных на Ruby on Rails. Тот же Shopify (о котором шла речь ранее) или всемирно известный Couchserfing.


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

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

https://habrahabr.ru/post/335094/


Метки:  

[Перевод] 10 основ брендинга для начинающих предпринимателей

Понедельник, 07 Августа 2017 г. 17:50 + в цитатник
image
Сколько у вас друзей, которые сейчас запускают свой бизнес? Shark Tank — одно из самых популярных шоу на кабельном на данный момент (американская телепередача, в которой участвуют бизнесмены (стартаперы), которым нужны инвестиции в свой бизнес), оно привлекает большое количество людей, заинтересованных в бизнесе, дизайне и фирменной символике. В то время как одни рьяные «бред-приниматели» (“want-repreneurs”) погружаются в идею вокруг основной идеи, остальные мгновенно переключают разговор на то, как их идея будет выглядеть.

  • Как будет выглядеть логотип? Можно ли создать собственный логотип самому или стоит нанять дизайнера?


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

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

01 — Что такое фирменный стиль?



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

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

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

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


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

02 — У меня обычный маленький бизнес, зачем мне нужно беспокоиться о брендинге?



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

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

03 — Какова разница между брендингом и логотипом?



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

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

04 — Как вы относитесь к готовым шаблонам логотипов? Почему вы не рекомендуете использовать их?



Начнем с того, почему логотип столь важен.

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

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

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

05 — Является ли мой логотип сложным? Каковы преимущества использования простого логотипа?



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

В большинстве случаев простой логотип упрощает его масштабирование в этих форматах. Вы должны понимать, как логотип будет выглядеть и в случае сверхбольшого размера, и тогда, когда он уменьшается на 100-1000%. Простота в большинстве случаев будет служить вам наилучшим образом. Однако, создание минималистичного логотипа для представления вашего стиля — это очень сложная задача. Опять же, не надо полагаться на кого-то, кто «спроектирует» ваш логотип за $5. Такие дизайнеры просто сделают что-то, что им нравится. Как это поможет вам?

06 — Какой формат файла следует запросить у дизайнера (или сделать самому), чтобы напечатать визитные карточки?



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

07 — Какие программы вы рекомендуете для разработки системы фирменной символики?



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

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

Лучшим программным обеспечением, которое использует векторный формат для печати, является Adobe Illustrator. Также Sketch очень близок к нему, и я слышал, что Affinity Designer является также хорошим инструментом.

08 — Как дизайнер, какие ключевые вопросы вы задаете клиенту перед началом этапа проектирования логотипа? Что вы используете для вдохновения?



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

· Каким вы видите свой новый логотип?

· Каков возрастной диапазон целевой аудитории?

· Какое ощущение или сообщение вы хотите передать с помощью логотипа?

· Какие логотипы привлекают вас и почему?

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

09 — Распределяя бюджет на начальном этапе, какие элементы брендинга наиболее важны? (визитные карточки, веб-сайт и т.д.)



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

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

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

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

После этого переходите к визитным карточкам, а уж потом — к полному веб-сайту. Также есть отличные недорогие стартовые платформы. Отличные темы для веб-сайта можно приобрести на WordPress, Shopify и SquareSpace.

10 — Как лучше всего показать мой бренд людям?



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

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

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

https://habrahabr.ru/post/335092/


Метки:  

[Перевод] Невидимые сообщения в именах свойств JavaScript

Понедельник, 07 Августа 2017 г. 15:19 + в цитатник

Метки:  

[Из песочницы] 5G Глазами Huawei

Понедельник, 07 Августа 2017 г. 15:15 + в цитатник

Статья о будущей сети 5G, о которой рассказывали на Honor Cup 2016.


Содержание


  • Немного истории
  • Концепция
  • Характеристики
  • Архитектура
  • Где и когда
  • Заключение



История 5G


image

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


Концепция


Основные направления 5G:

  1. Мобильный интернет (Качественное покрытие[1], hot-spot[2])
  2. Интернет вещей[3] (Минимальная задержка, маломощные соединения[4])

Рассмотрим более подробно. Основная концепция 5G сетей — это представление её как конвергентной технологии[5] и объединение всего между собой в единую систему, к одному облаку. Предполагается, что сама сеть будет представлять собой облако, к которому через приложения или Telco OS будут получать доступ: абоненты, разработчики, операторы, партнёры.

Как это работает? Очень просто. Вы через приложение или Telco OS получаете доступ к той части облака, которое необходимо для вашей задачи. И само выделение этой части облака происходит виртуально, то есть на программном уровне.

Помимо этого отказ от нынешней архитектуры сотовой связи. Если в кратце, то старая архитектура вынуждала абонентов сети «гоняться» за сетью, теперь же 5G хочет сделать обратное, «гоняться» за абонентом. Всё это построено на архитектуре Massive MIMO, что в свою очередь пришло от военных и использоваться будут не только вышки, которые имеются сейчас, но и военные антенны.

Характеристики


  • Широкополосное соединение (Работа с очень широким диапазоном частот)
  • Hot-spot (1 гигабит/секунду)
  • Sensor Network — сбор информации с разных датчиков
  • Tactile Internet — мгновенный отклик ( < 1 мс)
  • Оповещения в чрезвычайных ситуациях
  • Сверхнадёжная связь
  • Streaming Service

Всё это можно отобразить на следующей схеме.

image

Links — кол-во соединений (100 миллиардов)
Throughout — пропускная способность или кол-во передаваемых данных (10 гигабит/сек.)
Delay — задержка (< 1 мс)

Как мы видим, 5G стремиться объединить абсолютно всё. Если раньше 2G, 3G, 4G были в основном для мобильного интернета, теперь же всё стало гораздо шире.

Архитектура


Сама архитектура такой конвергентной технологии представляет собой «пирог». То есть она разделена на 3 слоя:

  • Приложение — получение доступа к 5G
  • Виртуализация (Выделение конкретной аппаратной части под требуемую задачу)
  • Аппаратный (5G devices, 5G RAT family)

Само облако построено на SDN/NFV.
SDN (Software-defined network) — программно определяемая сеть
NFV (Network function virtualization) — виртуализация сетевых функций

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

  1. Удешевляется услуги, то есть не нужно закупать аппаратные средства
  2. В основном меняется ПО, а не аппаратные средства

Где и когда? (Применительно к России)


Первый запуск планируется в 2018 году на World Cup. Реализатором выбран Мегафон.

Заключение


Лично мне сама концепция 5G не понравилась по нескольким причинам:

  • Про безопасность не было ничего сказано. Даже тогда, когда я задал вопрос лектору, то он сказал, что не задавался вопросом.
  • Концепция реализации архитектуры похожа на сервис Gaikai, который на данный момент является Playstation Now
  • Учитывая, что доступ будет осуществляется через приложения или Telco OS, то никто не даёт гарантии, что кто-то при проектировании (я намекаю на то что выше компаний) не поставят чудьненькие приборчики, которые в соответствии с нашим законодательством будут отлично его выполнять. Собственно фиг с ним.
  • Сама концепция связывания интернет вещей, то есть no fool devices, может привести к любому голливудскому сценарию о восстании машин, если в конечном итоге всё отдадут под контроль ИИ
  • И отдельный пункт, опять про безопасность. Учитывая, что разделение ресурсов облака идёт на программном уровне, никто не даёт гарантии, что кто-либо с очень «хорошими» намерениями не захочет расширить свой кусок или того получить доступ к системе или части системы



P.S. Все сведения получены с лекции 5G

[1] — то есть распространение работы сети по всей территории
[2] — высокоскоростная точка доступа
[3] — «вещи», которые имеют возможность общения с такими же «вещами»
[4] — работа с некоторыми устройствами напрямую.
[5] — представление, как единого целого.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335084/


Метки:  

Использование Hotspot Helper Extension

Понедельник, 07 Августа 2017 г. 14:21 + в цитатник
В современном мире наличие публичного Wi-Fi в общественных заведениях считается само собой разумеющимся. Посещая кафе, торговые центры, отели, аэропорты, парки отдыха и многие другие места, мы сразу ищем заветный сигнал без пароля. А это бывает нелегко, поскольку, во-первых, точек в списке может оказаться несколько, а во-вторых, бесплатный Wi-Fi может быть запаролен, так что единственный выход — ловить сотрудника, который сможет указать на правильную сеть и назвать пароль. Но даже после этого случается так, что ничего не работает. Пользователь должен догадаться о том, что ему необходимо открыть браузер (причем еще вопрос, какую страницу следует загружать) и совершить дополнительные действия (авторизоваться, просмотреть рекламу, подтвердить пользовательское соглашение), прежде чем ему предоставят полноценный доступ в сеть.

Впрочем, сейчас многие популярные заведения предлагают приложения, облегчающие подключение к бесплатным точкам. Уверен, что каждый из нас сможет легко припомнить пару-тройку подобных примеров, поэтому обойдусь без названий и рекламы. Тем более что ниже пойдет речь о другом варианте решения этой проблемы — мы будем писать собственный Network Helper! С таким подходом больше не придется гадать, к какой сетке подключаться. Даже дополнительные действия для получения доступа в сеть можно будет производить в удобном нативном UI и гораздо быстрее, чем в браузере.

Все просто. Достаточно задействовать технологию NEHotspotHelper, которая стала доступна разработчикам еще со времен выхода iOS 9. Основная задача этого инструмента — классификация Wi-Fi-сетей и авторизация пользователя в них. NEHotspotHelper входит в состав фреймворка NetworkExtension. Чуть ниже вы найдете схему входящих в него на момент выхода iOS 11 инструментов:

Network Extention Framework

Основная документация находится тут: Hotspot Network Subsystem Programming Guide. Помимо этого никакой информации в сети обнаружить не удалось, в связи с чем я и пишу эту статью. Надеюсь, мой материал поможет восполнить пробелы документации и объяснит, как реализовать свой собственный Hotspot Helper. Пример использования этой технологии можно найти на GitHub.

Принцип работы


В основе работы Hotspot Helper — машина состояний Wi-Fi-соединения и посылаемые системой Helper команды, обработка которых переводит машину из одного состояния в другое. Ниже представлена приблизительная схема состояний, которую приводит сама Apple в своей документации:

State Machine

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

Достаточно понимать следующее:

  1. При первом подключении к сети после перезагрузки устройства выбирается Helper, который будет её обслуживать (Evaluate).
  2. Как только выбор сделан, запускается авторизация в сети с помощью выбранного Hotspot Helper (Authenticating).
  3. Если в процессе авторизации необходимо отобразить UI, Hotspot Helper его явно запрашивает (PresentingUI). Если такой нужды нет, Helper в фоне совершает необходимые действия по авторизации пользователя в сети (Authenticated).
  4. Периодически система пробуждает выбранный Hotspot Helper для поддержки сессии, если это необходимо (Maintain).
  5. Во время поддержки сессии Helper может ничего не делать, а может запросить повторную авторизацию или спровоцировать повторное подключение к сети.


Единственный неочевидный момент: после первого подключения к сети система кеширует выбранный для нее Hotspot Helper, поэтому при последующем подключении машина cразу переключается в состояние Maintain, минуя все предыдущие.

Hotspot Helper участвует в авторизации пользователя в Wi-Fi-сети на всех этапах — от отображения списка сетей и подключения к выбранной до поддержки авторизации и самостоятельного логаута. При этом для установки соединения Hotspot Helper обрабатывает все требуемые команды, благодаря чему система обеспечивает его запуск в любой ситуации (даже если пользователь принудительно выключит приложение (что привело бы к игнорированию silent-push уведомлений). Ведь от этого зависит работа всего устройства. Надо понимать, что для пользователя весь процесс протекает прозрачно. Таким образом, наиболее частый сценарий — это запуск приложения в фоне.

Итак, повторим: для установки Wi-Fi-соединения Hotspot Helper должен обработать все требуемые команды. Иными словами, устройство не будет считать себя подключенным к сети до тех пор, пока StateMachine не перейдет в состояние Authenticated. И это несмотря на то, что Hotspot Helper начнет видеть соединение уже при получении команды Evaluate. Этот момент отлично отслеживается средствами Reachability, о чем мы поговорим чуть ниже.

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

Предварительная подготовка


Для регистрации приложения как Hotspot Helper нужно получить разрешение у Apple. Для этого Team Agent должен перейти по ссылке и заполнить опросник.
На момент написания статьи он выглядит так:
Опросник_1 Опросник_2

Если все пройдет хорошо, то при создании provisioning profile на https://developer.apple.com появится возможность выбрать для него entitlement с ключом com.apple.developer.networking.HotspotHelper, дающий право на использование всех плюшек.

Provisioning
Кроме того, необходимо включить в проекте Background Mode Capability и прописать в Info.plist в раздел UIBackgroundModes строку network-authentication. После этого можно приступать к самому интересному — кодингу.

Регистрация


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

class NEHotspotHelper 
    class func register(options: [String : NSObject]? = nil, queue: DispatchQueue, 
                        handler: @escaping NetworkExtension.NEHotspotHelperHandler) -> Bool
 
 
Метод принимает три параметра:
  • Опциональный словарь параметров. Сейчас поддерживается единственный параметр: kNEHotspotHelperOptionDisplayName — имя Hotspot Helper, которое будет отображаться в списке доступных Wi-Fi-сетей рядом с теми сетями, которые HH поддерживает (об этом ниже). Сменить это имя можно только после перезапуска приложения, передав новое имя в качестве параметра. Согласно требованиям Apple, имя должно быть максимально коротким.
  • Очередь, на которой будут обрабатываться команды, получаемые от системы. Её можно использовать не только для обработки команд в фоне, но и для синхронизации обработки команд с другим кодом приложения.
  • Блок — обработчик команд. Это ключевой элемент конструкции. Его сигнатура проста:

    typealias NEHotspotHelperHandler = (NEHotspotHelperCommand) -> Void
    

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


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

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

Кроме того, в отличие от многих других функций системы (таких как фотогалерея, календарь и даже уведомления), обработка Wi-Fi-соединения средствами Hotspot Helper не требует никаких разрешений от пользователя и происходит прозрачно для него (он попросту не сталкивается с подобными понятиями).

Обработка команд


Команда представляет собой объект класса NEHotspotHelperCommand, содержащий тип и набор данных, характерный для каждой из команд (сеть либо список сетей, если это подразумевает команда).
После обработки каждой из команд следует создать NEHotspotHelperResponse с результатом выполнения и набором данных, который также зависит от конкретной команды.
Объект NEHotspotHelperResponse создается вызовом на полученной команде данного метода:

 func createResponse(_ result: NEHotspotHelperResult) -> NEHotspotHelperResponse

Кроме того, использование объекта команды позволяет установить TCP- либо UDP-соединение на основании сети, к которой команда относится, вызывая соответствующие методы:
 
 func createTCPConnection(_ endpoint: NWEndpoint) -> NWTCPConnection
 func createUDPSession(_ endpoint: NWEndpoint) -> NWUDPSession
 
Для более высокоуровневого общения с сервером можно создать NSURLRequest. Приложив к нему команду, Hotspot Helper получает возможность взаимодействия с сервером в условиях, когда устройство не видит Wi-Fi-соединения. Установленное таким образом соединение можно использовать для авторизации «по-своему». IYKWIM
 
 func bind(to command: NEHotspotHelperCommand)

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

Официально на выполнение каждой команды отводится не более 45 секунд (однако, если посмотреть на доступное время работы в фоне, можно увидеть цифру 60 секунд). После этого команда считается необработанной, а работа Hotspot Helper приостанавливается. Это ограничение необходимо, чтобы устранить излишние задержки при подключении к сети, ведь пока команда не будет обработана, пользователь не увидит заветного значка Wi-Fi в Status Bar. При этом надо понимать, что, если в системе несколько Hotspot Helper, которые обрабатывают одну и ту же сеть, будет выбран самый быстрый из них (об этом опять же ниже).

NEHotspotHelperCommandType.filterScanList


Это особенная команда, которая, в отличие от остальных, не привязана ни к одному из состояний StateMachine и может быть вызвана в любой момент. Команда вызывается на всех Hotspot Helper, известных системе, каждые 5 секунд. Происходит это все время, пока пользователь находится на экране списка Wi-Fi-сетей в системном Settings.app.

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

var networkList: [NEHotspotNetwork]? { get }

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

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

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

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

В итоге обрабатывать команду следует так:
 
let network = 
network.setPassword("PASSWORD")
let response = command.createResponse(.success)
response.setNetworkList([network])
response.deliver()
 
В результате пользователь увидит нечто подобное:
Wi-Fi-настройки_1 Wi-Fi-настройки_2

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

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

NEHotspotHelperCommandType.evaluate


Данная команда вызывается при первом подключении к сети на всех Hotspot Helper, известных системе.
Note: при последующих подключениях evaluate не вызовется, сразу последует maintain на том Hotspot Helper, который был выбран в процессе evaluate.
 
Цель этой команды — первичное выявление наиболее подходящего для обработки подключения к выбранной сети Hotspot Helper. Для этого вместе с командой Hotspot Helper получает и данные по сети, к которой производится подключение:
 
var network: NEHotspotNetwork? { get }

Network содержит ряд свойств, однако в процессе обработки команды evaluate значения имеют только следующие:
 
// Идентифицируют сеть
var ssid: String { get }
var bssid: String { get }
 
// Отражают силу сигнала по шкале от 0.0 до 1.0 (дБ, увы, не предоставляются) 
var signalStrength: Double { get }
 
// Признак необходимости ввода пароля для подключения к сети
var isSecure: Bool { get }
 
// Признак, показывающий, было ли подключение выполнено автоматически 
// или пользователь явно выбрал эту сеть в настройках
var didAutoJoin: Bool { get }

Получив эту информацию, Hotspot Helper должен проанализировать сеть любым способом (начиная от локальной таблицы и заканчивая запросом на сервер) и выставить сети соответствующий уровень confidence:
 
// Helper уверен, что не обрабатывает эту сеть.
case none
 
// Helper предполагает, что сможет обработать подключение к этой сети, но не уверен полностью*.
case low
 
// Helper уверен, что может полноценно обработать подключение к этой сети.
case high

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

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

let network = command.network
 
// Оценить сеть и определить уровень confidence...
 
network.setConfidence()
 
let response = command.createResponse(.success)
response.setNetwork(network)
response.deliver()
 
На обработку команды предоставляется 45 секунд, при этом есть смысл постараться сделать это как можно быстрее. Потому что, как только система получает первый ответ с high confidence, обработка команды прекращается. Затем ответивший Hotspot Helper выбирается для дальнейший обработки подключения в сети, а все остальные прекращают свою работу и переходят в suspended state.

NEHotspotHelperCommandType.authenticate


Команда authenticate вызывается на наиболее подходящем Hotspot Helper по результатам выполнения команды evaluate.

Целью этой команды служит выполнение всех действий, необходимых для предоставления полного доступа пользователя к выбранной Wi-Fi-сети. Для этого вместе с командой Hotspot Helper получает и данные по сети, к которой производится подключение:

var network: NEHotspotNetwork? { get }
 
В обработке этой команды и заключается основная суть работы Hotspot Helper. На этом этапе барьером между пользователем и доступом к сети является только Hotspot Helper, и он должен любым доступным фантазии разработчика способом решить, предоставлять пользователю доступ или нет.
На обработку команды дается 45 секунд, по истечении которых необходимо вернуть response с одним из следующих результатов:
 
.success — авторизация успешно завершена. Доступ в сеть полностью открыт. StateMachine переходит в состояние authenticated.
 
.unsupportedNetwork — данная сеть не поддерживается Helper: произведен неправильный анализ сети на этапе evaluate. StateMachine возвращается на этап evaluate, а Helper добавляется в исключения для данной сети. Такое может произойти, например, если Helper вернул для этой сети low confidence на этапе evaluate, а сейчас убедился, что не справится.
 
.uiRequired — требуется взаимодействие с пользователем. Этот результат возвращается в случае, если для авторизации требуется ввести какие-либо дополнительные данные. Однако не все так просто: UI не покажется сам собой при возвращении этого результата.

Работает это так: Hotspot Helper генерируется UILocalNotification, посредством которой сообщает пользователю о необходимости дополнительного взаимодействия. Если пользователь ее проигнорирует, ничего больше не произойдет. Получив результат обработки, StateMachine переходит в состояние presentingUI и остается в нем до завершения авторизации либо отключения от сети. 
 
.temporaryFailure — исправимая ошибка. Например, в ходе авторизации произошла сетевая ошибка. StateMachine переходит в состояние failure, устройство отключается от выбранной сети.
 
.failure (или любой другой результат, а равно и его отсутствие) — неисправимая ошибка. Что-то пошло совсем не так, и обработать подключение нельзя: например, поменялся протокол авторизации на стороне сервера, а клиент к этому не готов. StateMachine переходит в состояние failure, устройство отключается от выбранной сети. Дополнительно, в отличие от temporaryFailure, для такой сети отключается функция auto-join
 
В итоге обрабатывать команду следует так:
 
let network = command.network

// Авторизовать пользователя необходимым образом и сформировать результат обработки команды
// Вывести UILocalNotification в случае необходимости дополнительного взаимодействия (.uiRequired)

command.createResponse().deliver()

NEHotspotHelperCommandType.presentUI


Эта команда вызывается на выбранном Hotspot Helper в случае, если он вернул результат uiRequired в процессе обработки команды authenticate.

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

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

В итоге необходимо вернуть response с одним из следующих результатов:
 
.success — авторизация успешно завершена. Доступ в сеть полностью открыт. StateMachine переходит в состояние authenticated.
 
.unsupportedNetwork — данная сеть не поддерживается Helper: произведен неправильный анализ сети на этапе evaluate. StateMachine возвращается на этап evaluate, а Helper добавляется в исключения для данной сети. Такое может произойти, например, если Helper вернул для этой сети low confidence на этапе evaluate, а сейчас убедился, что не справится.
 
.temporaryFailure — исправимая ошибка. Скажем, в ходе авторизации произошла сетевая ошибка. StateMachine переходит в состояние failure, устройство отключается от выбранной сети.
 
.failure (или любой другой результат, а равно и его отсутствие) — неисправимая ошибка. Что-то пошло не так, и обработать подключение нельзя: например, поменялся протокол авторизации на стороне сервера, а клиент к этому не готов. StateMachine переходит в состояние failure, устройство отключается от выбранной сети.  Дополнительно, в отличие от temporaryFailure, для такой сети отключается функция auto-join

В итоге обрабатывать команду следует так:

let network = command.network

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

command.createResponse().deliver()

NEHotspotHelperCommandType.maintain


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

  1. Каждые 300 секунд (пять минут) на протяжении всего времени подключения устройства к Wi-Fi-сети.
  2. При установке подключения к сети вместо команды evaluate, для обработки которой текущий Hotspot Helper был выбран ранее.


Предполагается, что в обоих случаях Hotspot Helper проанализирует текущее состояние сессии авторизации и выполнит одно из следующих действий:

  • мгновенно предоставит (продолжит предоставлять) пользователю доступ в сеть, вызвав response с результатом .success;
  • потребует повторной авторизации, вызвав response с результатом .authenticationRequired (в этом случае StateMachine переходит в состояние Authenticating и посылает Hotspot Helper команду authenticate).
  • сообщит о невозможности продолжить сессию, завершив команду с кодом ошибки ,(.temporaryFailure/.failure или любым другим, отличным от перечисленных выше). В этом случае StateMachine переходит в состояние Evaluating для выбора того Hotspot Helper, который сможет обработать соединение.


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

В итоге обрабатывать команду следует так:

let network = command.network

if network.didJustJoin {
     // Новое подключение к сети, для обработки которой выбран данный Helper
}
else {
     // Поддержка сессии в сети, в которой была произведена авторизация (раз в 300 сек.)
}
 
// Обеспечить авторизацию пользователя в сети любым способом 
// и сформировать результат обработки команды

command.createResponse().deliver()

Следует отметить, что во время повторной авторизации соединение будет недоступно для устройства вплоть до возвращения в состояние Authenticated.

NEHotspotHelperCommandType.logoff


Команда logoff, как можно было бы ожидать, не посылается при отключении от сети. Отследить отключение от сети средствами Hotspot Helper невозможно.

Эта команда предназначена для завершения внутренней сессии авторизации выбранного Hotspot Helper и посылается ему в ответ на вызов статического метода NEHotspotHelper:

class func logoff(_ network: NEHotspotNetwork) -> Bool

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

В результате StateMachine переходит в состояние LoggingOff, а Hotspot Helper получает заветную команду и 45 секунд на её выполнение.

Получить сеть, которую необходимо передать в метод, можно следующим образом:
 
let network = NEHotspotHelper.supportedNetworkInterfaces().first 

Основной use-case: выполнение логаута из UI приложения, что актуально для сценария авторизации с использованием команды presentUI.
 
Как только Hotspot Helper завершит выполнение команды (либо время выполнения истечет), StateMachine переходит в состояние inactive, и устройство отсоединяется от Wi-Fi-сети. 

В итоге обрабатывать команду следует так:
 
let network = command.network
 
// Произвести logoff и сбросить внутренние данные сессии авторизации
 
let response = command.createResponse(.success).deliver()

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

Что еще полезно знать


Выше описаны принцип работы и детали реализации Hotspot Helper. Однако есть еще несколько особенностей, о которых следует знать, приступая к разработке, а именно:

  • Hotspot Helper нельзя зарегистрировать на симуляторе — для разработки и отладки потребуется реальное устройство.

  • Зарегистрированное как Hotspot Helper приложение будет запущено системой в фоне в любой ситуации, поскольку от этого зависит работа всей системы. Даже если приложение выгрузил пользователь, отключил background fetch, включил low power mode и т.д.

  • Hotspot Helper не предоставляет никаких возможностей отслеживать отключения от сети (пусть команда logoff не вводит в заблуждение: это обработка завершения сессии авторизации самим Helper). Если необходимо мониторить отключение, следует воспользоваться уведомлениями от reachability (само собой, приложение при этом должно быть активно — в фоне система вас не поднимет).

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

    let network = NEHotspotHelper.supportedNetworkInterfaces().first

    Следует отметить, что, несмотря на swift-сигнатуру данного метода (в которой указан non-optional-массив в качестве результата) и ожидаемое поведение (отсутствие сети представляется пустым массивом), при отсутствии соединения можно получить объект сети с пустыми строками в качестве SSID и BSSID и силой сигнала 0.0. Иногда, что еще страшнее, на выходе можно получить и nil (а вместе с ним и crash). В примере приведен код, позволяющий избежать этих ситуаций. 

    Note: C выходом iOS 11 эта проблема устранена.

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

    Следует отметить, что существует единственная ситуация, в которой reachability уже видит Wi-Fi, а Hotspot Helper не получает никаких команд. Происходит это, когда пользователь может видеть следующее состояние в настройках:

    Wi-Fi settings

    Чем обусловлена такая ситуация, понять сложно. Если у вас есть идеи, поделитесь ими, пожалуйста.

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

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

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

    Следует отметить, что какого-либо надежного способа определить наличие другого Hotspot Helper в системе нет. Единственное, что можно сделать, — проверить, выбран ли в текущий момент Hotspot Helper основным для активной сети. Это можно сделать так:

    let network = NEHotspotHelper.supportedNetworkInterfaces().first
    if !network.isChosenHelper {
         // Hotspot Helper не обрабатывает активную сеть
    }

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

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

    func createTCPConnection(_ endpoint: NWEndpoint) -> NWTCPConnection
    func createUDPSession(_ endpoint: NWEndpoint) -> NWUDPSession

    А также расширение на NSMutableURLRequest:

    func bind(to command: NEHotspotHelperCommand)

  • С выходом iOS10.3, очевидно в целях экономии ресурсов, система начала производить самовольные отключения от сети при засыпании устройства с последующим переподключением к той же сети. Интервалы отключения-подключения не поддаются прогнозированию и зависят от текущего состояния системы, устройства и установленных на нём приложений. Интервалы могут быть самые разные: от долей секунд до нескольких часов. Более того, не удаётся найти какой-либо возможности отличить автоматическое переподключение к сети от выполненного самим пользователем — для устройства они оба происходят одинаково.

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

  • С выходом iOS 11 функционал NEHotspotHelper дополнит новый класс  NEHotspotConfigurationManager, с помощью которого можно подключаться к Wi-Fi прямо из приложения. Больше не надо заставлять пользователя идти в чуждые для него настройки и выбирать сеть из огромного списка с замороченными названиями. Это полезно в двух ситуациях:
    • для приложений, предоставляющих публичные сервисы (кафе, бизнес-центры и др.);
    • для приложений, производящих конфигурацию устройств по их собственной Wi-Fi-сети (например, видеокамеры). Для этого можно временно подключиться к заданной сетке до момента выхода из приложения.

Заключение


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

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

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


  1. Припер реализации на GitHub
  2. Hotspot Network Subsystem Programming Guide
  3. Network Extension
  4. NEHotspotHelper reference
  5. WWDC’15 What's New in Network Extension and VPN и её конспект
  6. WWDC’17 Advances in Networking, Part 1
  7. Forum: How to cancel register an app as a Hotspot Helper (NEHotspotHelper)?
  8. Forum: Как получить entitlements через почту или через прямую ссылку на форму запроса
  9. Forum: Как показать UI
  10. Небольшая статья про HotspotHelper
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335028/


Метки:  

[Из песочницы] Оптимизация шаблонов представления в Codeigniter Framework при помощи AST трансформаций

Понедельник, 07 Августа 2017 г. 14:10 + в цитатник

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


Предыстория


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


Но есть несколько проблем. Одной из которых является отсутствие обработчика для представлений. В качестве шаблонизатора используется чистый php (с мелкими вставками Codeigniter).


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


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


Проблема


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


Так было и в моем случае — количество файлов шаблонов подключаемых при загрузке страницы достигало 50 (информация от встроенной функции get_included_files).


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


image


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


Перед работой с шаблонами, я смог, при помощи минимальных оптимизаций кода, сократить время вывода страницы на 1 секунду (30%) до +-2 секунд:


Loading Time: Base Classes      0.0274
Controller Execution Time   1.9403
Total Execution Time    1.9687

Это было все еще слишком много


Решение


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


Использование готового шаблонизатора типа twig или smarty отпали сразу, так как пришлось бы переписывать все контроллеры, и шаблоны а их очень много.


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


...
...

Конструкция


$this->load->view(string $templatePath,array $params)

делает "include" с передачей дополнительных параметров $params
Суть задачи была в том, чтобы заменить все такие вызовы на содержимое самих шаблонов и передачу в них параметров inline. Рекурсивно.


Интересно, подумал я и взялся за инструменты которых нашлось аж один: Nikic PHP-Parser. Это очень мощный инструмент который позволяет делать разного рода манипуляции над абстрактным синтаксическим деревом вашего кода и потом сохранять измененное дерево обратно в php код. И все это можно делать в самом же php — парсер не имеет каких-либо зависимостей от с-расширений и может работать на php 5.2+.


Реализация


PHP-Parser предоставляет удобные инструменты для работой с AST: интерфейсы NodeVisitor и NodeTraverser при помощи которых мы и будем сооружать наш оптимизатор.


Главное — это найти все вызовы метода view на свойстве класса load и понять, что за шаблон должен быть загружен. Это можно проделать с помощью NodeVisitor. Нас интересует его метод leaveNode(Node $node) который будет вызван когда NodeTraverser будет "уходить" с узла дерева AST:


class MyNodeVisitor extends NodeVisitorAbstract {

 public function leaveNode(Node $node) {
    // если тип узла - вызов метода то обрабатываем его
    if ($node instanceof Node\Expr\MethodCall) {
            // проверяем, вызов ли это нужного нам метода 
            if ($node->name == 'view') {
                 // тут также нужно проверить на чем этот метод вызывается
                 // возможно это не функционал Codeigniter'a, тогда у нас будет ошибка
                 // я это проигнорировал :)

                // мы должны проверить, сможем ли мы узнать какой шаблон подключается.
                // если параметр - скалярная строка, тогда без проблем
                // можно достать информацию и с других типов, но это сложнее и мы это пропустим
                if ($node->args[0]->value instanceof \PhpParser\Node\Scalar\String_) {

                    // дадим методу уникальное имя, чтобы потом можно было правильно обработать
                    $code = md5(mt_rand(0, 7219832) . microtime(true));
                    $node->name = 'to_be_changed_' . $code;
                    $params = null;

                    // сохраним параметры, которые нам нужно будет передать `inline`
                    if (count($node->args) > 1) {
                        if ($node->args[1]->value instanceof Node\Expr\Array_) {
                            $params = new Node\Expr\Array_($node->args[1]->value->items, [
                                'kind' => Node\Expr\Array_::KIND_SHORT,
                            ]);
                        } else {
                            if ($node->args[1]->value->name != 'this') {
                                $params = $node->args[1]->value;
                            }
                        }
                    }

                    // сохраним место, где мы должны будем заменить шаблон
                    // замена происходит в другом прогоне по коду
                    $this->nodesToSubstitute[] = new TemplateReference($this->nodeIndex, $node->args[0]->value->value, $params, $code);
                }
            }
...

Таким образом мы сможем выделить все элементы которые должны заменить. Также можно сделать замену и любых других элементов: явных require, include и т.д.


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


Код обработчика
class CodeigniterTemplateOptimizer {

    private $optimizedFiles = [];
    private $parser;
    private $traverser;
    private $prettyPrinter;
    private $factory;
    private $myVisitor;
    private $templatesFolder = '';

    public function __construct(string $templatesFolder) {
        $this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP5);

        $this->traverser = new MyNodeTraverser();
        $this->prettyPrinter = new PrettyPrinter\Standard();
        $this->factory = new BuilderFactory();

        $this->templatesFolder = $templatesFolder;

        $this->myVisitor = new MyNodeVisitor();

        $this->traverser->addVisitor($this->myVisitor);
    }

    public function optimizeTemplate(string $relativePath, $depth = 0, $keepOptimizing = true) {
        if (substr($relativePath, -4, 4) !== '.php') {
            $relativePath .= '.php';
        }

        if (!isset($this->optimizedFiles[$relativePath])) {

            $templatePath = $this->templatesFolder . $relativePath;

            if (file_exists($templatePath)) {

                $templateOffset = 0;

                $notOptimized = file_get_contents($templatePath);

                // читаем код в AST
                $stmts = $this->parser->parse($notOptimized);

                if ($keepOptimizing) {
                    $this->myVisitor->clean();

                    $this->traverser->setCurrentWorkingFile($relativePath);

                    // здесь мы обходим наше AST
                    $stmts = $this->traverser->traverse($stmts);

                    // Получаем список элементов к замене от MyNodeVisitor
                    $inlineTemplateReference = $this->myVisitor->getNodesToSubstitute();
                    ++$depth;

                    $stmsBefore = count($stmts);

                    foreach ($inlineTemplateReference as $ref) {
                        // погружаемся глубже - рекурсивно обрабатываем шаблоны вглубь
                        $nestedTemplateStatements = $this->optimizeTemplate($ref->relativePath, $depth);

                        $subtempalteLength = count($nestedTemplateStatements);

                        $insertOffset = $ref->nodeIndex + $templateOffset;

                        $pp = new PrettyPrinter\Standard();

                        // вставляем параметры для шаблона `inline`:  при помощи конструкции `extract`
                        if ($ref->paramsNodes) {
                            array_unshift($nestedTemplateStatements, new Node\Expr\FuncCall(new Node\Name('extract'), [$ref->paramsNodes]));
                        }

                        // мы нашли то место, где должны вставить содержание шаблона
                        if (get_class($stmts[$insertOffset]) === 'PhpParser\Node\Expr\MethodCall' && ($stmts[$insertOffset]->name === "to_be_changed_" . $ref->code)) {

                            // чтобы не "ламать" набор стейтментов родительского AST 
                            // вставляем шаблон в if(1), чтобы он выглядел как один элемент
                            $stmts[$insertOffset] = new Node\Stmt\If_(new Node\Scalar\LNumber(1), [
                                'stmts' => $nestedTemplateStatements
                            ]);
                        } else {
                            // этот кусок кода намеренно вырезан, здесь вложенная обработка ast
                        }
                    }
                }

                // записываем в кеш "оптимизированных" шаблонов. 
                // В этот момент уже все  вложенные шаблоны оптимизированы 
                $this->optimizedFiles[$relativePath] = $stmts;
            } else {
                throw new Exception("File not exists `" . $templatePath . "` when optimizing templates");
            }
        }

        // возвращаем оптимизированный шаблон
        return $this->optimizedFiles[$relativePath];
    }

    public function writeToFile(string $filePath, $nodes) {
        $code = $this->prettyPrinter->prettyPrintFile($nodes);

        // create directories in a path if they not exists
        if (!is_dir(dirname($filePath))) {
            mkdir(dirname($filePath), 0755, true);
        }

        // write to file
        file_put_contents($filePath, $code);
    }

} 

Вот и все, запускаем оптимизатор:


    // создаем объект оптимизатора с параметром - путем к шаблонам 
    $optimizer = new CodeigniterTemplateOptimizer('./views/');
    // сохраняем оптимизированный шаблон куда нужно
    $optimizer->writeToFile($to, $optimizer->optimizeTemplate($from));

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


Выводы и результаты


После замены шаблонов на оптимизированные, мне удалось сократить более чем 1с времени на выполнение, результаты профайлера Codeigniter:


Loading Time: Base Classes      0.0229
Controller Execution Time   0.7975
Total Execution Time    0.8215

При помощи оптимизации шаблонов мне удалось сократить больше времени чем при оптимизации php-кода. Затраты на оптимизацию шаблонов несопоставимы с изменением многих строк кода. Также оптимизация шаблонов никаким образом не изменяет поведение приложения (это ж ведь просто "склеивание") что есть очень положительным фактом.


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

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

https://habrahabr.ru/post/335080/


Метки:  

Сначала они воруют, а когда ты побеждаешь, то тебя убивают

Понедельник, 07 Августа 2017 г. 13:42 + в цитатник
Кому-то может показаться, что это начало какой-то детской загадки, но на самом деле это реальность. Ответ на нее Департамент Информационных Технологий.
Заранее говорю, что статья является лишь сводом информации. Каждый из вас может сделать собственные выводы.

Легенда


ЕМП — единая мобильная платформа. Суть — дать доступ к АПИ московских сервисов (ЖКХ, штрафы, образование)
МРКО — Электронный дневник школьника. Старый.
ОЭЖД — Электронный дневника школьника. Новый.
Мое приложение — Приложение, которому 1.5 года (А если брать старые версии, то 3.5).
Я — Бывший школьник. Только окончил обычную московскую школу. Сейчас уже поступил в ВУЗ.

Если вам лень читать всю историю, то просто переходите к «ЧТО? КАК ТАК?».

За что я борюсь


Я верю, что дети могут учиться хорошо и даже отлично. Я верю, что вопрос лишь в мотивации.
Что в жизни? А в жизни все грустно. Дети часто бывают забыты родителями. Учителя также редко мотивируют детей.
Да, детей не мотивируют учиться. И самое страшное — им никто не говорит, что они в принципе могут учиться хорошо. Дети просто не знают об этом!
Чаще всего урок — монотонное чтение информации. Если в вашей школе есть хоть 1 не такой учитель, то вам безумно повезло! Может быть ваш ребенок будет знать хоть 1 предмет.

Что я предлагаю


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

Как это происходит обычно


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

Объяснение математикой: Итоговая оценка — округление средней оценки. Средняя оценка — среднее арифметическое взвешенное. Чем больше ребенок получает оценок, тем сложнее изменить среднее значение.

Как это решить


На самом деле это очень просто. Важно лишь быть рядом с ребенком с самого начала пути, а не когда уже поздно.
В приложении есть основной функционал:
1. Советы — приложение говорит сколько нужно получить пятерок чтобы достичь цели.
2. Подсказки — каждый предмет выделен цветом. Зеленый — цель достигнута, можно расслабиться. Желтый — спорная оценка. Красный — нужно подготовиться к предмету и получить оценку.
3. Пуш уведомления — ребенок не может «проспать оценку».
image
Слева официальный дневник, а справа мой
Взаимоотношение с приложением происходит примерно так:
Начало года. Оценок пока еще не много.
1. Ребенок открывает дневник
2. На главном экране сразу советы. Они ему говорят: «Эй, парень, у тебя будет 5 по биологии, просто получи 2 пятерки!»
3. Он запоминает это.
4. Ребенок открывает дневник на завтра и видит, что домашнего задания много. Целых 7 уроков, но из «красных» одна физика и начинает её делать. Специально для пятерки.
5. У ребенка откладывается хоть что-то из того, что он сделал. Понимание предмета увеличивается.
6. Если ребенок получил оценку, то ему приходит пуш уведомление с просьбой проверить. Если оценка хорошая, то ребенок получает похвалу в виде зеленого цвета и осознание того, что учиться хорошо возможно. А если оценка плохая, то ребенок узнает о ней в самом начале и успеет исправить.
В итоге у ребенка есть постоянная ситуация успеха, любая проблема решается с самого начала, а у него откладывается в голове, что все в его руках.

Я называю это борьбой


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

Что за новое АПИ?


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

Также я заметил, что авторизация в их дневнике происходит мимо ЕМП, т.е. даже не спрашивают пароль. На вопрос почему мне ответили: «Мы не должны раскрывать логику авторизации вашего конкурента». Ага, особенно это невозможно, когда получение данных происходит напрямую с серверов ДИТ.

ЧТО? КАК ТАК?


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

Компания Альтарикс — создатель госуслуг и ЕМП. «Госуслуги» является официальным приложением для дневника.

Теперь давайте начнем вскрывать все покровы и выстроим связь altarix.ru — мои конкуренты.
1. Находим сайт cloud4smartcity.com, который находится на том же IP, что и altarix.ru.
2. На этом сайте придается активный гражданин, госуслуги, продукт KidRadar
3. KidRadar один из продуктов Taktik Labs, которые являются создателями дневника моего конкурента (https://play.google.com/store/apps/developer?id=Taktik+Labs)
4. На десерт: devs.hostoasis.net на этом сервере есть шаблоны всех сайтов.
Теперь мы понимаем, что эти компании тесно связаны.

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

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


Кошки-мышки


Если ввести в AppStore «МРКО», то можно увидеть, что мое приложение первое, а приложение конкурентов второе. Каждый раз работники ЕМП пытались найти причину для блокировки меня.

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

В какой-то момент 300 пользователей увидели рекламу, которая почти 18+(просто пошлая), а при переходе по ней открывался UС Browser. Скорее всего, я накосячил с фильтром гугл адмоб.
Ошибка была исправлена в тот же вечер, но не тут-то было. Сайт начали менять и портить парсинг. В день по 2-3 раза.
Стало понятно что меня пытаются «убить» и я решил, что теперь буду использовать АПИ, его-то не запретят.
Конечно, я ошибался. Как только я начал использовать АПИ, мне прилетело письмо:

Обратите внимание на отправителя писма.
Они нашли какую-то левую причину, по которой заблокировали мне АПИ. Я подумал: «Ну ок», и написал, что они могут удалить всех лишних пользователей. Но они ничего не сделали, а заблокировали не: «через 14 дней», а сразу.

Представляете как удобно? Вы управляете ЕМП, баните меня, а вся моя аудитория переходит к вам!
После блокировки меня заставляли ходить на какие-то бессмысленные переговоры в ДИТ, а на деле просто тянули время. (Тянули до момента, пока я не стану вторым)
Например:
1. Переговоры назначались за несколько часов.
2. Сначала меня заставили предоставить отчет о том, что подобных ошибок больше не будет. После того, как я его предоставил в тот же день, они пытались найти другие поводы
3. Скиньте нам исходники приложения
4. Сделайте приложение которое работает с АПИ, но документацию не дадим
5. Если в приложении будут баги, то не разрешим пользоваться АПИ
6. В течении нескольких недель переносили встречу
Апогеем ситуации стал момент, когда я сидел в офисе ДИТ, с приложением которое вроде как должно работать т.к. было разработано с какой-то очень странной документацией и без доступа к тестовому апи.
Мы сидим в комнате, которая была сделана в японском стиле. В комнате сижу я и 2 работника(1 из дит, а второй из ЕМП). Один из них мне говорит: «Ты действительно готов? Мы сейчас включим тебе доступ и если что-то будет не работать, то мы его закроем», на их глазах рисовалась насмешка, а я понимал, что обратного пути нет (Да и не нужно было), я им отвечаю: «Да».
Доступ открывают и начинается веселье. Приложение работало идеально, хотя это был первый запуск, но данные грузились и отображались правильно. На их глазах было недоумение, а я понимал, что мне сейчас откроют доступ и я выложу приложение.
Но они переглянулись и у них был такой диалог:
— Ну что, открываем доступ?
— Ну да, раз ошибок нет
— Точно?
— Ну да
— Мммм… Ладно, Леван, мы сейчас доступ закрываем, а завтра откроем.
И они ушли. Короче, завтра они доступ не открыли, а только спустя время.
И как долго они бы не тянули, мое приложение все еще оставалось первым в поиске.
После этой ситуации, мне постоянно шли угрозы о блокировках, а я постоянно отбивался.

Итоги


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

В начале лета 2017 года, я спросил ЕМП: «Будут ли какие-то изменения в методах или в функционале?», а мне ответили, что пока они не знают.
1 августа я получил письмо о том, что АПИ больше не будет и попросили меня сообщить моим пользователям, что теперь надо пользоваться госуслугами.

А кто будет мотивировать детей теперь?
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335010/


Метки:  

[Из песочницы] Пишем и собираем приложения для Android в linux консоли

Понедельник, 07 Августа 2017 г. 13:11 + в цитатник

image


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


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


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


Введение


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


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


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


Похожая статья уже встречалась на этом ресурсе, но в ней было рассмотрена разработка в Windows.


Здесь же я рассмотрю, как можно собрать приложение в linux.


Железо


Тестирование проводилось на стареньком нетбуке с процессором Атом, 1Гб ОЗУ
и 8Гб SSD диска.


Операционная система


Я тестировал приложение на Ubuntu 17.04.
Начиная с Ubunu 16.04 android-sdk можно установить через пакетный менеджер.


Загрузка SDK вручную

В принципе, тот же SDK можно
скачать с сайта.
Качать файл из раздела 'Get just the command line tools'
По сути это не сильно меняет процесс, но через пакетный менеджер все гораздо проще.
Разница будет лишь в путях и установке дополнительных пакетов "android-platform".


Установка пакетов


Итак, приступим к установке.


sudo apt install android-sdk

Будет установлено большое количество пакетов, включая Java.


Далее, в зависимости от требуемой версии Android, необходимо установить нужную
версию пакетов. Для lolipop 5.1 необходимо ставить:


sudo apt install google-android-platform-22-installer
sudo apt install google-android-build-tools-22-installer

Так же необходимо установить дополнительный пакет.


sudo apt install apksigner

Если вы планируете устанавливать apk-пакет через adb, то необходимо немного дополнительных настроек.


Настройка adb


С помощью lsusb найти подключенное устройство


# lsusb
....
Bus 001 Device 004: ID 1782:75b0 MyDevice
....

И создать файл с правилом:


sudo vi /etc/udev/rules.d/51-android.rules

В файл добавить одну строку:


SUBSYSTEM=="usb", ATTR{idVendor}=="1782", MODE="0666", GROUP="plugdev"

Здесь "1782" взято из вывода lsusb.


Перезапускаем сервис


sudo systemctl restart udev

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


Теперь все готово к работе.


Постановка задачи


Приложение, которое будем собирать немного сложнее, чем 'Hello world'.


  • Требуется по нажатию кнопки взять строку из буфера обмена.
  • Вырезать подстроку
  • Записать подстроку обратно в буфер.
  • С помощь Toast вывести подстроку или сообщение об ошибке.

В общем-то все просто.


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


Создание подписи


Сначала создадим ключ для подписи файла:


keytool -genkeypair -keystore keystore.jks -alias androidkey \
      -validity 10000 -keyalg RSA -keysize 2048 \
      -storepass android -keypass android

Это нам пригодится позже.


Манифест


AndroidManifest.xml


    
    
        
            
                
                
            
        
    

Здесь указываем имя приложения в атрибуте "android:label".
Так же приложение будет использоваться свою иконку, она указана в атрибуте "android:icon"
Сама иконка лежит в каталоге "res/drawable-mdpi" файл "icon.png". В качестве иконки можно взять любой небольшой png файл.


Layout


Файл с расположением элементов находится в каталоге "/res/layout/".


activity_main.xml



    

      


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


Исходный код приложения


Исходный код приложения находится здесь "java/ru/kx13/extractvidid"


MainActivity.java
package ru.kx13.extractvidid;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
import android.content.ClipboardManager;
import android.content.ClipData;

public class MainActivity extends Activity {
  private static String extract(String s) {
    int start = s.indexOf("%3D");
    int end = s.indexOf("%26");
    if(start == -1 ||  end == -1) {
      return "error";
    }
    return s.substring(start + 3, end);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView text = (TextView)findViewById(R.id.my_text);
    text.setText("Извлечь  youtube video id");
    Button button = (Button) findViewById(R.id.button_id);
    button.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        ClipboardManager myClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
        ClipData abc = myClipboard.getPrimaryClip();
        ClipData.Item item = abc.getItemAt(0);
        String text = item.getText().toString();
        String video_id = MainActivity.extract(text);
        ClipData myClip = ClipData.newPlainText("text", video_id);
        myClipboard.setPrimaryClip(myClip);

        Toast toast = Toast.makeText(getApplicationContext(), 
            video_id, Toast.LENGTH_SHORT); 
        toast.show(); 
      }
    });
  }
}

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


Скрипт для сборки


Я не стал использовать утилит сборки типа make или ant, т.к. весь код
находится в одном файле и особых преимуществ это не даст.
Поэтому это обычный shell скрипт:


build.sh
#!/bin/sh
SOURCE=ru/kx13/extractvidid
BASE=/usr/lib
SDK="${BASE}/android-sdk"
BUILD_TOOLS="${SDK}/build-tools/22.0.1"
PLATFORM="${SDK}/platforms/android-22"
mkdir -p build/gen build/obj build/apk
"${BUILD_TOOLS}/aapt" package -f -m -J build/gen/ -S res -M AndroidManifest.xml -I "${PLATFORM}/android.jar"
javac -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" \
         -classpath "${PLATFORM}/android.jar" -d build/obj \
         build/gen/${SOURCE}/R.java java/${SOURCE}/MainActivity.java
"${BUILD_TOOLS}/dx" --dex --output=build/apk/classes.dex build/obj/
"${BUILD_TOOLS}/aapt" package -f -M AndroidManifest.xml -S res/  -I "${PLATFORM}/android.jar" \
        -F build/Extractor.unsigned.apk build/apk/
"${BUILD_TOOLS}/zipalign" -f 4 build/Extractor.unsigned.apk build/Extractor.aligned.apk
apksigner sign --ks keystore.jks \
        --ks-key-alias androidkey --ks-pass pass:android \
              --key-pass pass:android --out build/Extractor.apk \
              build/Extractor.aligned.apk

Некоторые замечания по поводу путей.


  • По умолчанию, переменная BASE указывает на путь, в который пакетный менеджер сохраняет файлы. Если вы ставите SDK вручную, то путь надо будет изменить.
  • Если вы используете версию API отличную от 22, то вам надо подправить переменные BUILD_TOOLS и PLATFORM

Сборка и установка


Для сборки просто запустите


./build.sh

Если все настроено правильно никаких сообщений не будет выведено, а в каталоге "build" появится файл "Extractor.apk"


Теперь надо установить наше приложение


adb install -r build/Extractor.apk

Если все прошло нормально, на устройстве появится новое приложение.
Можно запускать и пользоваться.


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


Заключение


Как видно из статьи начать разработку в консоли совсем несложно.


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


Приятной разработки!

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

https://habrahabr.ru/post/335074/


Метки:  

PGHACK. Соревнование в офисе Avito 2 сентября

Понедельник, 07 Августа 2017 г. 13:01 + в цитатник
В декабре 2016 мой коллега kevteev сказал, что было бы неплохо замутить митап по постгресу в следующем году на площадке Avito. А незадолго до этого безопасники пригласили меня поучаствовать в нескольких CTF, в том числе одном Attack-Defence. И я ответил ему: “А почему бы не замутить постгресовый хакатон?”. И вот мы подготовили первое в России очное соревнование для специалистов по PostgreSQL, и сегодня я хочу пригласить на него вас.


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

PGHACK — для кого?


Мы ждём на соревновании специалистов по работе с базами данных: разработчиков, программистов, администраторов. Участие смогут принять DevOps-инженеры и фуллстэк разработчики с большой базой знаний по теме. Желательно понимать:
  • что такое MVCC;
  • как работают триггеры;
  • как база данных обеспечивает валидность данных, которые хранятся в таблице;
  • как администрировать Linux — нужно уметь установить программу из исходного кода и собрать её вручную.


Механика соревнования


Первый этап, заочный, отборочный


На этом этапе мы принимаем заявки на участие в PGHACK. Для этого необходимо ввести регистрационные данные и ответить на 5 вопросов в форме на этой странице. Участники, которые предложат правильные варианты решения, получат возможность побороться за победу в финальном раунде. Критерии отбора: правильность ответов и их скорость. Время проведения этапа — с сегодняшнего дня, 7.08, и по 25.08. Если мы отберём 50 финалистов раньше этого срока, то сразу же закроем регистрацию на TimePad. Всем, кто заполнит форму на странице мероприятия, придут письма с результатами отборочного этапа.

Финал PGHACK в московском офисе Avito


По итогам первого этапа мы пригласим 50 участников в московский офис Avito 2 сентября. Для участия в финальном раунде участникам понадобится ноутбук с 20Gb свободного пространства на жестком диске и 3GB оперативной памяти. Виртуальная машина будет предоставлена на месте. Если понадобится — поможем настроить окружение. И начнётся игра!

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

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

Партнёры


Партнёрами соревнования выступают PGDay Russia, наша любимая питерская профильная конференция, и #RuPostgres, русскоязычное сообщество разработчиков и пользователей этой СУБД, с которым мы не раз проводили совместные мероприятия.

Призы


Конечно, там где проходит соревнование, должны быть и награды. Главный приз PGHACK — квадрокоптер. Также победитель получит билет на PG Day Russia'2018. Участникам из ТОП-10 достанутся наборы с Arduino, гаджеты, мини-коптеры. И конечно, всем присутствующим на финале приготовлены сувениры от Avito. Непременно обеспечим всех пиццей и приятной компанией профи.

Что потом?


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

https://habrahabr.ru/post/334886/


Метки:  

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

Понедельник, 07 Августа 2017 г. 13:00 + в цитатник
Клиент что-то заказал и ждёт, когда ему это привезут? День доставки заранее согласован? Значит, курьер может выезжать? Увы, нет. Рейд курьера может быть бессмыслен и бесполезен, потому что клиент… только что вышел в магазин, застрял в пробке, сидит на совещании, заснул, ушел с ребенком на детскую площадку – и ещё 1000 и одна причина, почему не сейчас. Как плохой футболист, которому внезапно дали пас. И, чтобы передача состоялась, надо как-то проверить, удобно ли клиенту, и не будет ли курьер мотаться почём зря. В компания СДЭК задумались, как это сделать, и при помощи Voximplant нашли для себя оптимальное решение, о котором – под катом.


Справка о компании:
СДЭК — оператор, специализирующийся на экспресс-доставке грузов и документов. У СДЭК порядка 600 подразделений и представительств в России и за рубежом. Франшиза СДЭК входит в пятерку самых успешных франшиз по версии Forbes.


До двери и обратно


Курьер в рамках своих должностных обязанностей находится в ситуации “принеси известно что известно куда, но часто — неизвестно когда конкретно”. СДЭК ему в помощь создал специальное мобильное приложение, которое используют все курьеры. В приложении содержится вся информация о клиентах, накладные заказов и статусы их доставки. И курьер может выудить из карточки клиента его номер телефона и позвонить ему перед тем, как ехать к нему с грузом, чтобы не стоять в итоге без толку под дверью. И всё бы ничего, только этот процесс занимает время, которое курьер мог бы потратить на выполнение своих прямых обязанностей. Никаких гарантий, что клиент ответит сразу или что ответит вообще. А если ответит и, например, захочет перенести доставку, то курьеру нужно будет ещё и звонить в колл-центр, просить уже их связаться с клиентом, чтобы назначить доставку на другой день.

В СДЭК решили, что нужно как-то упростить жизнь своим сотрудникам. И теперь у курьеров в приложении есть кнопка интеллектуального звонка. Курьер просто нажимает на неё, и вместо него клиенту звонит робот. Клиент доволен, а курьер работает на маршруте быстрее и эффективнее.

Оператор — третий лишний


Кроме того, что предупредить клиента выгодно курьеру, сервисное уведомление — формальное требование партнёров СДЭК, чьи посылки получают клиенты. Живые звонки курьеров с трудом поддавались аудиту, а с интеллектуальным обзвоном такой проблемы нет. Статусы звонков можно отслеживать в режиме реального времени, и фиксируется каждая попытка звонка.

Когда звонит робот, клиент при помощи IVR сообщает о том, что он готов: принять заказ, отказаться, перенести доставку. Его ответ отображается в приложении курьера через 30 секунд после обзвона. Если клиент выбирает статус переноса доставки, ему автоматически приходит sms с инструкцией, как самостоятельно выбрать удобное время. Курьер в это время может спокойно заниматься своими прямыми обязанностями – доставкой.

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

Курьер ездит — вызов идёт


Чтобы запустить интеллектуальный обзвон, курьер находит в мобильном приложении карточки клиентов, к которым он планирует заехать в ближайший час, и нажимает кнопку звонка. Робот Voximplant делает до 3 попыток звонка и отправляет ответ клиента прямиком в CRM-систему СДЭК. Статус, выбранный клиентом, подгружается из CRM в приложение курьера.

Во время звонка клиент может выбрать опцию связаться с курьером, если он испытывает в этом необходимость. Именно поэтому СДЭК рекомендует курьерам запускать не более 5 обзвонов единовременно. Тогда клиенту не придется висеть на линии.


О пользе предупреждений


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

Сейчас к сервису подключены 2000 курьеров из двухсот подразделений СДЭК по России. Даже в тестовом режиме платформа каждый день совершает около 4 тысяч звонков.

О дружбе клиентов и роботов


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

https://habrahabr.ru/post/335068/


Метки:  

ГДЕ ЛОГИКА? Учимся мыслить системно. Часть 3

Понедельник, 07 Августа 2017 г. 12:53 + в цитатник
С частью 1 можно ознакомиться, перейдя по ссылке habrahabr.ru/post/334892
С частью 2 можно ознакомиться, перейдя по ссылке habrahabr.ru/post/334916

IV ПОДБОР МЕТОДОВ УПРАВЛЕНИЯ ОТНОШЕНИЯМИ С ЛЮДЬМИ


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

1. ДЕТАЛИЗАЦИЯ СЛОЖНЫХ ЯВЛЕНИЙ И СОБЫТИЙ


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

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

Рисунок 1 – Пример детализации
Дальше каждое из них разложили на еще более мелкие части. А потом их, на еще более мелкие… Мы могли бы и пожелания к «Питанию» разложить на более детальные прихоти, например: «Бесплатные обеды», «Кофе, печеньки», «Скидка в ресторане». Но такие подробности скорее всего уже будут только мешать принятию решения, о выборе работы – глаза разбегутся, да и не самое это главное набить желудок на работе. Вот тут мы, как бы случайно, затронули очень важное уточнение «самое (не самое) главное», то есть вес оценки. Находясь в разных ситуациях, человек может по разному оценивать значимость каждой составляющей, при выборе. Например, когда я в кризис 2008-2009 гг. сидел несколько месяцев в чужом и очень дорогом городе в съемном жилье без заработка, я готов был идти на любую работу, где платили бы хоть какие-то деньги покрывающие мои расходы. А вот когда я несколько лет проработал в очень напряженном графике, и скопил какие-то деньги позволяющие расслабиться, для меня в поиске работы стал играть большую роль качественный уровень общения – то есть насколько профессионально, рационально и интересно построено взаимодействие в коллективе на предприятии.
Естественно есть профессиональные методики, которые предоставляют возможность строить модели, шаг за шагом раскладывая сложные элементы, на составные части. Причем они позволяют не придумывать компоненты наугад, как мы делали в примере выше, а выявлять их на основании информации о происходящих процессах. Но знакомство с этими инструментами сейчас не входит в наши планы.

2. ВЫЯВЛЕНИЕ ТОЧЕК ЗРЕНИЯ


Когда человек решает исключительно свои проблемы, которые вообще никак не связаны с другими людьми (если такое вообще возможно), он спокойно может оценить их прямо на месте, не сходя со своей точки зрения. Конечно, лучше использовать чужой опыт, знать варианты решения проблемы, но выносить вердикт, нужно исключительно учитывая свои интересы. А вот если в деле замешаны и другие люди, группы людей, огромные коллективы или даже все человечество, то учитывать необходимо гораздо большее количество мнений и взглядов. Случается еще и так, что приходится решать проблемы не свои, а совсем других людей и соответственно приходится мысленно абстрагироваться от себя самого и на время прикидываться — тем другим человеком. Давайте разберемся, как это лучше всего сделать на практике.
Парадигма восприятия мира, зачастую пересекается с законами геометрии. Например, в том, что: «Чем шире угол зрения, тем он тупее». Продолжая подобные сравнения можно утверждать, что чем больше точек зрения, тем более точные контуры проблемы можно очертить.
Обычный обыватель чаще всего рассматривает только одну точку зрения — свою. Мы же поставили своей целью научиться эффективно взаимодействовать с людьми, поэтому нам надо уметь ставить себя на “чужое место” и заглядывать на проблему со стороны. Проще всего это сделать, просто собрав мнения разных респондентов по рассматриваемому вопросу. Например, найти нужную группу в социальных сетях и обсудить там волнующую тему. Можно еще поискать в сети статьи, рефераты и т.п.
Для примера, открыл первую попавшуюся страницу в «поисковике» по запросу «выбор работы критерии» и нашел статью: «Работа мечты и как ее получить» rabota-of-dream.livejournal.com/28957.html. В ней приводятся результаты опроса мнений. То, что удалось из нее подчеркнуть занес в таблицу:

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

3. АНАЛИЗ ОБЪЕКТИВНОСТИ ТОЧЕК ЗРЕНИЯ


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

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

4. РАЗРАБОТКА УБЕДИТЕЛЬНЫХ ДОВОДОВ В ОБЩЕНИИ


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

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

5. АНАЛИЗ СОБЫТИЙ И ЯВЛЕНИЙ В ДИНАМИКЕ


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

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

6. ПРИЕМЫ ПРОЕКТИРОВАНИЯ ВЗАИМООТНОШЕНИЙ


Во взаимоотношениях людей многие аспекты предопределены заранее. Например: характером, привычками, разницей в социальным положением общающихся и т.п. Это неизбежность которая существует и с которой необходимо считаться. Проявляется сие например, в сокрытии информации или ее искажении. Для того чтобы противостоять отрицательному влиянию субъективных качеств людей, а еще лучше использовать их в своих целях, желательно понимать причины, которые препятствуют плодотворному общению. Вот некоторые из часто встречающихся мотивов:
• влияние на мировоззрение стереотипов мышления;
• податливость реальному или воображаемому давлению оппонента;
• склонность к поддержке социально одобряемых мнений;
• невозможность четко осознать собственное мнение, позицию и отношение;
• антипатия к оппоненту;
• сомнения в сохранении конфиденциальности общения:
• невольные ошибки памяти.
Например, иногда случается так, что при обсуждении проблемы вы чувствуете, что на собеседника оказало неизгладимое впечатление подсмотренное им где-то ранее решение. Оно так глубоко отложилось в его сознании, что в беседе с вами человек повествует не о том, что ему реально нужно и волнует в данной ситуации, а фантазирует на «тему увиденного». В подобных ситуациях не стоит конфликтовать или оказывать давление на личность, чаще всего это приводит к обратному эффекту. В таких случаях можно эффективно применить один из приемов, описанных ниже.
Для собеседника с «отвлечёнными фантазиями», можно использовать метод «Лестницы». Целью этого метода является установление причинно-следственных связей между желаниями собеседника и выгодами, которые он реально хочет получить при его реализации. Вы должны сформулировать вопросы таким образом, чтобы выстраивалась цепочка от конкретного желания человека, к сулящим при его воплощении выгодам. Основные вопросы: «Почему это важно для Вас» и «Что это значит для Вас». Из наводящих вопросов выстраивается «лестница» к действительно необходимому решению.
Еще один эффективный прием — Проективные методики. Они применяются, когда необходимо ответить на вопросы: почему человеку важны те или иные решения. Задавая вопросы негативно настроенному собеседнику напрямую, существует большая вероятность получить ложную информацию. А бывает и так, что реальное положение вещей не осознается человеком, так как скрывается от его сознания с помощью психологической защиты. Проективные методики позволяют «обмануть» сознание человека и обойти психологические барьеры. Таким образом — мы можем узнать реальное отношение собеседника к обсуждаемой проблеме.
На практике можно использовать следующие основные виды проективных методик:
Ассоциативные. Собеседника побуждают сказать, написать или выбрать из заранее подготовленных вариантов то, что у него ассоциируется с обсуждаемой проблемой. Для этого метода удобно воспользоваться приемом сравнения предлагаемого решения проблемы с аналогичными решениями успешно примененными на практике.
На завершение задания. Собеседника просят закончить незавершенные «стимулы», например, дописать предложение или выбрать из нескольких предложенных вариантов.
Конструирующие. Собеседнику предоставляют сценарии действий, в которых отображены какие-либо ситуации, и просят рассказать о том, что могут думать и чувствовать участники этих сценариев, а также что могло происходить с ними до начала и после окончания рассматриваемых ситуаций.
Еще один вариант — поставить собеседника на “чужое место”. Для этого можно подготовить вопросы, начинающиеся с некоторого утверждения, якобы высказанного другим человеком. Далее собеседника просят объяснить причины, по которым “замещаемый” высказал такую точку зрения и сформулировать собственное видение вопроса.
Ранжирование. Методика имеет множество модификаций. Например, собеседнику дают списки аспектов обсуждаемой проблемы и просят выбрать те из них, которые наиболее ему импонируют. Или просят проранжировать характеристики по какому-либо признаку (например, по степени важности).
В проективных методиках самое главное — понять разницу между тем, что человек сказал и тем, что он имел в виду. Для этого вам необходимо постоянно просить собеседника объяснять свои действия или слова. Главный вопрос в этом случае «Почему?».
Таким образом, следует обращать особое внимание на субъективные качества человека, как на потенциальные причины всевозможных искажений предоставляемой им информации. В этом деле вам здорово поможет развитие собственной проницательности и коммуникабельности. Особое значение при использовании подобных методик играет: уровень ваших морально-этических качеств, сдержанность и терпение, общая эрудиция, располагающие манеры и внешность.

P.S.


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

https://habrahabr.ru/post/334972/


Метки:  

Хакатон «Budget-Pro»: первый шаг к победе в конкурсе

Понедельник, 07 Августа 2017 г. 12:31 + в цитатник
image

Минфин России, продолжая следовать концепции открытости федеральных органов исполнительной власти и развивать направление открытых государственных данных, запустил прием заявок на участие в третьем конкурсе «Открытые государственные финансовые данные BudgetApps 2017».

12-13 августа Инфокультура совместно с Минфином России в рамках конкурса проведут хакатон «Budget-Pro», который откроется мастер-классами экспертов в области дизайна и прототипирования на тему «Быстрое прототипирование: технологии и инструменты». После чего начнется основная часть.

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




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

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

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

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

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

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

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

Зарегистрироваться на хакатон можно здесь.

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

Уже сейчас можно подать заявку на участие в конкурсе, получить поддержку контактного центра конкурса по почте opendata@minfin.ru или по телефону 8-800-500-10-92, а также запланировать участие в других мероприятиях конкурса BudgetApps.

Следите за новостями конкурса на официальном сайте Минфина России и в социальных сетях: Facebook и Вконтакте.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335066/


[Перевод] Вышел GitLab 9.4: Связанные задачи и веб-мониторинг приложений

Понедельник, 07 Августа 2017 г. 12:29 + в цитатник

Вышел GitLab 9.4: Связанные задачи и веб-мониторинг приложений


image


В GitLab 9.4 мы представляем связанные задачи, веб-мониторинг приложений, обновленную навигацию, групповые майлстоуны и многое другое!


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


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



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


Вдобавок к этому, мы добавляем простую и понятную интеграцию с Trello при помощи GitLab PowerUp для Trello.


Также, продолжая разговор об интеграции, в версию 9.4 входит новое приложение Slack для GitLab.


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


Приглашаем на нашу встречу!


GitLab MVP badge


MVP этого месяца — Matt Gresko


Matt добавил поддержку учетных данных профиля EC2 при использовании кластеров elasticsearch AWS; ранее можно было использовать только статические данные IAM. Это сложная работа, которая значительно улучшает интеграцию GitLab с elasticsearch. Благодаря этим нововведениям, некоторые аспекты нашего Улучшенного глобального поиска настраиваются автоматически, когда GitLab запущен на AWS.


Matt также работал над изначальной имплементацией AWS. Спасибо, Matt!


Связанные задачи (EES, EEP)


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


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


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


Related Issues


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


Обновленная навигация (CE, EES, EEP)


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


Для ее включения нажмите на иконку вашего профиля в правом верхнем углу экрана и выберите вариант Turn on new navigation.


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


Будем рады обратной связи.


Больше информации об обновлениях навигации в [нашей документации]


New Navigation


Веб-мониторинг приложений (CE, EES, EEP)


В GitLab 9.0 мы выпустили систему мониторинга производительности, интегрированную с развертыванием CI/CD, занимающуюся сбором статистики (использование процессора и памяти) развернутых на Kubernetes приложений. Это был успешный первый шаг, и теперь мы запускаем веб-мониторинг приложений, поддерживающий уже не только Kubernetes.


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


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


Больше информации о веб-мониторинге приложений в нашей документации


Web Application Monitoring


Секретные переменные группового уровня (CE, EES, EEP)


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


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


Больше информации о секретных переменных группового уровня в нашей документации


Group-level Secret Variables


Переменные в расписаниях конвейеров (CE, EES, EEP)


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


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


Больше информации о переменных в расписаниях конвейеров в нашей документации


Variables in Pipeline Schedules


Секретные переменные для сред (EEP)


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


В GitLab 9.4 для решения этой задачи добавлены секретные переменные для сред; теперь разработчики могут уточнять, какие среды получат определенную переменную. Можно даже включать динамические среды, к примеру, review/. Так что теперь можно с легкостью проводить развертывание на различные среды.


Больше информации о секретных переменных для сред в нашей документации


Environment-specific Secret Variables


GitLab Power-Up для Trello (CE, EES, EEP)


Пользуетесь одновременно Trello и GitLab? Теперь это стало еще проще благодаря новому GitLab Power-Up! Для его подключения в Trello перейдите в раздел Power-Ups и найдите Power-Up GitLab. После настройки вы сможете прикреплять мерж-реквесты GitLab прямо к карточкам Trello.


В Trello вам понадобится настроить ваш домен, например gitlab.com/api/v4 для GitLab.com, а также добавить ваш персональный токен.


Больше информации о GitLab Power-Up для Trello в нашей документации


GitLab Power-Up for Trello


Приложение GitLab Slack для GitLab (CE, EES, EEP)


GitLab уже глубоко связан с Slack (и Mattermost, Microsoft Teams и HipChat), но у нас до сих пор не было приложения в директории приложения Slack. Теперь оно у нас есть! Интегрировать Slack в ваши проекты на GitLab.com стало гораздо проще.


Вы можете настроить интеграцию с приложением из настроек проекта в GitLab (Settings > Integrations). Скоро это также будет доступно из директории самого Slack. Вместе с Slack мы работаем над тем, чтобы убедиться, что приватные инстансы будут способны использовать одно и то же приложение Slack в ближайшем будущем. И, конечно, приватные инстансы можно интегрировать с Slack вручную по шагам, описанным в документации.


Подробнее в документации о приложении GitLab Slack для GitLab.com


GitLab Slack App for GitLab.com


Другие улучшения в GitLab 9.4


Улучшенная локализацию (CE, EES, EEP)


Мы постепенно ускоряемся с локализацией GitLab. Большое спасибо участникам нашего комьюнити, которые посодействовали в добавлении дополнительных языков — китайского, французского, японского и бразильского португальского. Огромное спасибо Huang Tao за постоянный вклад в это дело!


В GitLab 9.4 мы добавили локализацию поддержки для страницы коммитов.


Подробнее о локализации в нашем гайде


Групповые майлстоуны (CE, EES, EEP)


Майлстоуны — одна из основных частей отслеживания задач. Их часто используют, чтобы отмечать спринты (35 неделя), релизы (версия 9.4) или категорию (бэклог) задач и мерж-реквестов. Часто майлстоуны охватывают несколько проектов: у вас есть возможность быстро создавать майлстоуны для нескольких проектов сразу. Теперь еще лучше: мы добавили возможность создавать групповые майлстоуны.


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


Чтобы создать групповой майлстоун, перейдите в вашу группу, нажмите Issues, а потомMilestones.


Читайте подробнее в документации о групповых майлстоунах


Улучшения GitLab Geo (EEP)


Важные изменения:


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

Документация о GitLab Geo


Хранение объектов для артефактов CI (EEP)


Компании продолжают внедрять CI/CD по всей организации, и их хранилища артефактов тоже растут. В GitLab 9.4 вы сможете перемещать существующие артефакты CI в Amazon S3, чтобы освободить дополнительное локальное пространство и эффективно и надежно сохранять сколько угодно артефактов. Сейчас эту операцию нужно проводить каждый раз, когда вы захотите переместить ваши локальные артефакты в S3, но в следующей итерации это будет происходить автоматически, и все новые артефакты будут сохраняться в хранилище объектов сразу после их создания — никаких миграций вручную.


Подробности в документации об артефактах CI


Расширенная настройка Docker для CI/CD (CE, EES, EEP)


В GitLab 9.4 появились новые улучшенные опции настройки для .gitlab-ci.yml. Они дают более гибко настраивать образы Docker, которые вы хотите использовать для ваших конвейеров. Чтобы воспользоваться этими возможностями, вам потребуется версия GitLab Runner 9.4 или выше.


Теперь вы сможете определить для вашего образа Docker специальную точку входа (entrypoint), чтобы переопределить ту, которая используется по умолчанию. Ниже приведен пример настройки точки входа для /bin/sh — это сделает образ подходящим для работ GitLab CI без дополнительных модификаций:


image:
  name: super/sql:experimental
  entrypoint: ["/bin/sh"]

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


services:
- name: super/sql:latest
  command: ["/usr/bin/super-sql", "run"]
  alias: super-sql-1
- name: super/sql:latest
  alias: super-sql-2

Подробности об изменении в документации о расширенной настройке Docker


Безопасность: добавили SSL проверку сертификата LDAP (CE, EES, EEP)


Мы добавили поддержку верификации сертификата LDAP через SSL. По умолчанию эта опция будет отключена, чтобы обеспечить обратную совместимость до выхода GitLab 9.5. Кроме того, чтобы упростить настройку безопасного соединения, вы теперь можете определить файл сертификата CA и версию SSL. Названия способов шифрования ssl и tls превратились в simple_tls и start_tls соответственно.


Читайте документацию по LDAP


Настраиваемый путь для настроек CI/CD (CE, EES, EEP)


GitLab определяет настройки CI/CD в YAML файле .gitlab-ci.yml, расположенном в корне репозитория. Бывают случаи, когда вам нужно определить другую локацию для определения ваших конвейеров — например, когда вы зеркалируете SVN репозиторий и не можете хранить файлы в корне проекта.


Начиная с версии GitLab 9.4, вы сможете определять специальный путь в Settings > Pipelines, по которому будут считываться настройки CI/CD — вместо .gitlab-ci.yml по умолчанию. Переменная под названием $CI_CONFIG_PATH доступна для работ, которым нужен доступ к текущей локации настроек.


Читайте подробности в документации о GitLab CI/CD


Новая политика кэширования для настройки CI/CD (CE, EES, EEP)


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


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


Если вам не нужно обновлять кэшированные файлы в определенной работе, вы можете пропустить шаг загрузки, выставив policy: pull в настройках работы. А если у вас есть работа, которая всегда воссоздает кэш без обращения к предыдущему содержанию, вы можете использовать policy: push, чтобы избежать излишней нагрузки на сервер кэширования. Для этой функциональности потребуется GitLab Runner версии 9.4 или выше.


Читайте документацию о GitLab CI/CD


Грядущее подписание пакетов Omnibus (CE, EES, EEP)


Начиная со следующего релиза 22 августа мы будем подписывать все новые пакеты. Наряду с подписанным пакетом 9.5.0 мы также будем предоставлять подписанные версии двух последних релизов (9.4 и 9.3).


Подписание пакетов добавляет уверенности в том, что файлы .deb и .rpm, необходимые для установки GitLab, не были кем-либо изменены.


GitLab Runner 9.4 (CE, EES, EEP)


Также в этом релизе мы выпустили GitLab Runner 9.4.


Самые важные изменения:


Полный список изменений смотрите в CHANGELOG GitLab Runner .


Полная документация по GitLab Runner




Подробные release notes и инструкции по обновлению/установке можно прочитать в оригинальном англоязычном посте: https://about.gitlab.com/2017/07/22/gitlab-9-4-released/


Перевод с английского выполнен переводческой артелью «Надмозг и партнеры», http://nadmosq.ru. Над переводом работали rishavant и sgnl_05 .

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

https://habrahabr.ru/post/335064/


Как встать на плечи гиганта. Пособие для финтех-стартапов

Понедельник, 07 Августа 2017 г. 12:24 + в цитатник


Сегодня мы решили поговорить с Сергеем SergeyMaksimchuk Максимчуком, он отвечает за работу с перспективными партнерами в команде инноваций (Innovation Team) Альфа-Лаборатории, которая призвана искать и привносить в Альфа-Банк инновации с внешнего мира. Именно через него стартапы могут предложить свои идеи банку. Задача Innovation team — оценив проект, найти заказчика внутри Альфа-Банка и сделать так, чтобы проект полетел. Так ли это сложно? Чего хочет Альфа-Банк от стартаперов? Что должны сделать команды, чтобы партнерство состоялось? Сергей раскрывает все секреты.

— Как вообще банки и финтех-стартапы могут дружить? Какая в этом польза? Разве они не конкуренты друг другу?



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



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

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

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

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


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

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

— И много стартапов удается «напылесосить» на нашем рынке?


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



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

— Как и где ищутся стартапы?


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

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



Отклик с рынка был большой. На первую программу мы получили 370 заявок, а на вторую — 888! Сейчас я работаю над запуском третьего Кэмпа. Хотим его запустить в 2017 году
Мы также проводим хакатоны для команд. С Microsoft мы провели виртуальный хакатон, на котором выставили свое программное обеспечение по API, подключение к сервису платежей с карты на карту и попросили команды придумать различные клиентские сервисы, используя нашу платформу.

Вот только что, 5-6 августа в Москве состоялся наш хакатон, на котором команды разрабатывали продукты для состоятельных клиентов и среднего класса. A!Hack получился мощным событием. В него заявилось порядка 80 команд из России, Белоруссии, Украины, Израиля, Польши, Великобритании и США. Участники хакатона использовали высокотехнологичные решения, и их уровень по-хорошему нас удивил.

Также мы поддерживаем ключевые мероприятия. В этом году были одним из организаторов форума FinTech Russia. После этого, кстати, два проекта нашли своего бизнес-заказчика у нас в Альфа-Банке. Мы были официальным партнером Startup Village, крупнейшей конференции для стартапов, которую проводит фонд Сколково.

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

— Ну и как происходит отбор, на что вы смотрите в первую очередь?


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

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

— Допустим, стартап прошел через это, кто с ним работает дальше?


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

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

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


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

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

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

Расскажу интересный пример. Мы в начале этого года запустили сервис по оформлению и получению возврата налога на доходы физических лиц. Он сейчас интегрирован в сайт Альфа-Банка, там есть раздел, через который клиент может, заполнив форму, получить возврат налогов от государства на свою карточку.



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

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


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

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



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

— Что-то не очень правдоподобно…


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

— Есть какие-то проверенные приметы, что стартап навряд ли взлетит?


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



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

— Слышал, вы разрабатываете платформу быстрой оценки стартапов. Что это будет за зверь?


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

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

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

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

https://habrahabr.ru/post/335060/


Метки:  

Игра-головоломка Neo Angle. Продолжение истории разработки и релиз в Appstore

Понедельник, 07 Августа 2017 г. 12:10 + в цитатник


Приветствую всех! Прошло почти полгода с момента публикации первой части (а также релиза в Google Play), в которой я описал историю возникновения идеи Neo Angle и ее реинкарнацию из портальной флэшки в мобильную игру на Unity. За это время многое изменилось, вследствие чего хотел бы рассказать о следующих моментах:

  • Результаты релиза в Google Play (статистика, цифры)
  • Поиск паблишера и работа с ним
  • Устранение ошибок
  • Presskit (будет много графики)
  • Релиз в Appstore

Итоги Google Play

Итак, начнем с того, что не имея на руках MacOS устройства (для сборки билда под ios), я нацелился на рынок андроид девайсов и решил покорить его своими силами. Выбрав, казалось бы, простую и логичную схему монетизации: первые 14 уровней бесплатные, а за остальные 25 заплати 0,99$. Я думал, что схема идеальна, так как игроку предоставляется достаточное количество бесплатных уровней чтобы прочувствовать геймплей. На деле же вышло совсем иначе, чтобы не быть голословным вот статистика прогресса игроков:

  • уровень 1 прошло 4000 игроков
  • уровень 3 — 3000
  • уровень 5 — 2000
  • уровень 8 — 1000
  • уровень 14 — 500 (на этом уровне демо-версия заканчивается)
  • уровень 15 — 125 (теоретически, это должно было быть 125 покупок, однако реальных покупок было около 10 :) да-да...)

То есть, из всех игроков демо-версию прошло только 12.5%, а до платной версии дошло еще меньше, и то, большая часть из них — пираты. К слову, пиратов не было до тех пор, пока я не опубликовал дополнительно платную версию игры в Google Play (надеясь попасть хотя бы в топ платных головоломок, ха-ха).


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

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

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

Далее опишу какие изменения были внесены в ходе сотрудничества:

  1. Я почти сразу же удалил игру из Google Play и мне было велено про него забыть, потому что основной целью стали Appstore и Steam
  2. Обязательным условием было увеличение числа уровней с 39 до 60-70
  3. Новый туториал, ребаланс гейм дизайна
  4. Подготовка нового пресскита, новой иконки, нового трейлера
  5. Новое звуковое оформление

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

Уровни

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


Новый элемент — перемещающаяся платформа


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

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

Туториал

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



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

Пресскит

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

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



  • Логотип игры (старый > новый):



  • Промо баннер:



  • Иконка (старая > новая):



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

  • Gif-анимации уровней разных видов сложности, например:



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

Саундтрек

Изначально я использовал трек, который был написан на заказ для моей старой флэш-игры, он хорошо вписался по стилю 80-ых с космическим звучанием. Однако, его длина всего 03:30, и в ходе тестирования игроки жаловались на зацикленность и повторяемость музыки. Поэтому, наняв композитора и потратив месяц времени, мы получили 12-минутную атмосферную композицию. Сам бы я не стал над этим заморачиваться, имея на руках неплохой 3-минутный трек, но о результате совсем не жалею, здесь паблишер сыграл свою роль!

Итог

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

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

Спасибо за внимание! Я рад поделиться своим опытом, и готов ответить на ваши вопросы.
Кого заинтересовала игра, ищите Neo Angle в Appstore.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335058/


Метки:  

Базовая фортификация Linux: выбираем ежи и учимся рыть траншеи

Понедельник, 07 Августа 2017 г. 12:07 + в цитатник


Несмотря на то, что Linux по праву считается более защищенной системой, чем MS Windows, самого по себе этого факта мало.


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


Где начать закручивать гайки


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


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


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


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


  • в идеале настроить вход на сервер по ключам;


  • не вводить пароль от суперпользователя на ненадежных машинах;


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

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


Защищаем файловую систему


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


В каждом дистрибутиве используется так называемая избирательная система доступа. Например, возможность пользователя открыть файл проверяется по списку управления доступом (Access Control List, ACL) - какие «галочки» для этого пользователя включены.


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

В частности, в системах Linux для файлов используется следующий механизм предоставления доступа:


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


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

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


Тип доступа Владалец Группа Все
Право читать 400 40 4
Право изменять 200 20 2
Право запускать 100 10 1

Таким образом, право на полные права для всех на объект будут выглядеть как: (400+200+100) + (40+20+10)+(4+2+1) = 777. Такие права, как правило, не нужны никогда и никому, допустимо их выставлять лишь в процессе отладки.


Подобный механизм доступа иногда называется UGO (User-Group-Others).


Подробнее о правах доступа и работе с ними можно почитать в соответствующих материалах.


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


По умолчанию эта система отключена. Для ее включения необходимо монтировать жесткий диск с опцией acl. Для примера включим acl для корневого раздела, добавив опцию монтирования в /etc/fstab:



Теперь система загрузится с поддержкой расширенных ACL.


Теперь можно управлять списками доступа с помощью команды setfacl. Просмотр текущих разрешений - getfacl.


Подробнее ознакомиться можно в документации, я же для примера дам полные права доступа пользователю user на файл test.txt:



Предоставление полных прав пользователю user.


Механизм защиты довольно прост, эффективен… и напоминает ACL в файловой системе NTFS.


Огненная стена на автобане


Основной механизм для защиты доступа к серверу - традиционно фаерволл. В системах GNU\Linux для этого используется встроенный в ядро netfilter.


Для желающих освежить в памяти основные принципы работы этого фаервола - добро пожаловать под спойлер.

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


  • ACCEPT. Пропускаем пакет;


  • DROP. Удаляем пакет;


  • QUEUE. Передаем пакет на анализ внешней программе;


  • RETURN. Возвращаем пакет в предыдущую цепочку.

Цепочки по умолчанию выглядят так:


  • PREROUTING. Изначальная обработка входящих пакетов;


  • INPUT. Обработка входящих пакетов, адресованных непосредственно локальному процессу;


  • FORWARD. Обработка входящих пакетов, перенаправленных на выход. Нужно отметить, что перенаправляемые пакеты проходят сначала цепочку PREROUTING, затем FORWARD и POSTROUTING;


  • OUTPUT. Обработка пакетов, генерируемых локальными процессами;


  • POSTROUTING. Окончательная обработка исходящих пакетов.

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


  • raw. Эта таблица просматривается до передачи пакета системе определения состояний. Используется довольно редко, содержит цепочки PREROUTING и OUTPUT;


  • mangle. Содержит правила модификации IP-пакетов. Как правило, модифицируется заголовок пакета. Содержит все пять стандартных цепочек;


  • nat. Работает только с пакетами, создающими новое соединение. Помимо стандартных, поддерживает действия DNAT, SNAT, MASQUERADE, REDIRECT. В современных операционных системах содержит цепочки PREROUTING, INPUT, OUTPUT, и POSTROUTING;


  • filter - основная таблица. Используется по умолчанию, если название таблицы не указано. Содержит цепочки INPUT, FORWARD, и OUTPUT.

Цепочки с одинаковым названием, но в разных таблицах независимы друг от друга. Например, raw PREROUTING и mangle PREROUTING обычно содержат разный набор правил: пакеты сначала проходят через цепочку raw PREROUTING, а потом через mangle PREROUTING.


Также в фаерволе есть специальный модуль определения состояний пакетов -conntrack. Состояния могут быть следующих видов:


  • NEW. Новое подключение, соединение получает это состояние, если обнаружен первый пакет в соединении;


  • ESTABLISHED. Уже состоявшееся подключение. Соединение получает это состояние, если пакет уже не первый. Очень удобно использовать для разрешения ответного трафика;


  • RELATED. Самое «хитрое» состояние соединения. Соединение получает его, только если само было инициировано из другого соединения. Типичный пример - работа FTP-сервера, в котором канал передачи данных поднимается отдельно от канала приема команд;


  • INVALID. Состояние, когда пакет не может быть идентифицирован. Обычно к таким пакетам применяют действие DROP.


Путь проверки пакета в системе netfilter.


Для управления фаерволом чаще всего используется утилита iptables. Материала по ней достаточно, поэтому ограничусь общей рекомендацией - блокируем все, что не разрешено. А что разрешено - максимально ограничиваем.


Например, если доступ по SSH к серверу необходим только с определенных внешних адресов - разрешите доступ только с них.


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


Например, для предоставления доступа по ssh с помощью ufw достаточно выполнить команду:


ufw allow from 1.2.3.4 to any port 22

Тоже самое с помощью iptables выглядело бы более громоздко. Разрешим входящий трафик:


iptables -A INPUT -p tcp -s 1.2.3.4 --dport 22 -j ACCEPT

Затем разрешим ответный трафик:


iptables -A OUTPUT -p tcp --sport 22 -d 1.2.3.4 -j ACCEPT

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

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

В современных RPM-дистрибутивах вроде CentOS, Fedora и Red Hat в качестве замены iptables используют демона firewalld. От привычного механизма он отличен тем, что может применять правила на ходу без перезагрузки списка, а также работой с зонами - уровнями доверия к сетевым подключениям. Немного напоминает встроенный фаервол Windows. Правда, использовать его после iptables немного непривычно, и часто системные администраторы предпочитают вернуть сложный, но привычный iptables.


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


  • мониторит лог какого-либо сервиса, например ssh или ftp;


  • если слишком много подключений с одного IP-адреса с неверными логинами и паролями - блокируем этот IP с помощью фаервола на некоторое время. Вдруг это брутфорс.

Подробнее с настройкой fail2ban можно ознакомиться в официальной Wiki.


АНБ на страже


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


Минусы системы доступа на базе ACL:


  • пользователь сервера может предоставить доступ к своим файлам - например, к закрытым ключам;


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

Устранить эти недостатки может SELinux, созданный АНБ (Агентство Национальной Безопасности США) и Red Hat еще в 1998 году. В ядре Linux-систем эта технология присутствует уже давно. Тем не менее в некоторых инструкциях до сих пор часто встречается рекомендация ее отключить, что не всегда справедливо. Подробнее про SELinux можно почитать в профильной статье на Хабре, поэтому ограничусь небольшим ликбезом.


У SELinux есть три режима работы:


  • enforcing. Режим работы по-умолчанию, все неразрешенные действия блокируются;


  • permissive. Все неразрешенные действия выполняются, но записываются в журнал;


  • disabled. SELinux отключен.

Узнать текущий режим работы можно командой getenforce, переключиться между режимами enforcing и permissive можно командой setenforce. Выключение же SELinux требует перезагрузки системы.


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


ls -Z


Смотрим маркировку свежесозданного файла.


В качестве примера настройки я разберу ситуацию, когда мы хотим разместить сайт в папке не по умолчанию и «повесить» веб-сервер на другой порт. Одной смены значений в конфигурационном файле httpd.conf будет недостаточно, необходимо сказать SELinux, что веб-серверу следует предоставить доступ к папке и к порту. Для этого необходимо:


  • установить пакет администрирования policycoreutils-python;


  • сказать системе о маркировке папки командами:


    semanage fcontext -a -t httpd_sys_content_t "/path/to/www(/.*)?"
    semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/www(/.*)?"

  • восстановить маркировки командой:


    restorecon -R /path/to/www

  • предоставить доступ к порту:
    semanage port -a -t http_port_t -p tcp 81

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


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


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


aa-complain /path/to/bin

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


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


Если описать отличия коротко, то разработчики SELinux делали упор не на простоту использования, а именно на безопасность. С AppArmor все обстоит с точностью до наоборот. Почитать об AppArmor подробнее можно в документации от производителя, либо в библиотеке Ubuntu.

Увы, не могу дать однозначный совет, что вам выбрать, потому что это вопрос приоритетов и предпочтений по дистрибутиву ОС. Поклонники Centos и Red Hat чаще выбирают SELinux, а любители Ubuntu - AppArmor.


Кстати, напишете в комментариях, какой механизм предпочитаете вы?


Набор отмычек на всякий случай


В этом разделе я расскажу про несколько полезных, но не must-have механизмов для защиты сервера.


Запрет подключений root к терминалу


В системах GNU\Linux можно ограничить список терминалов, куда может подключаться пользователь root. Сделать это можно путем модификации файла /etc/securetty. Если файл пустой, то root не сможет напрямую подключаться вовсе, и для получения полных прав понадобится su или sudo.


Политика паролей


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


chage -M 20 username

Где 20 - это срок действия пароля в днях. Другим вариантом будет изменение общей политики паролей в файле /etc/login.defs. Допустим, мы хотим, чтобы пароль нужно было менять каждые 20 дней, и чтобы пользователь за 5 дней получал напоминание об этом. Тогда содержимое файла будет следующим:


PASS_MAX_DAYS 20 

PASS_MIN_DAYS 0

PASS_WARN_AGE 5

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


password required pam_cracklib.so minlen=8 lcredit=1 ucredit=1 dcredit=1 

в файл /etc/pam.d/system-auth.


Уведомления о случаях повышения прав


Еще одна нужная опция - уведомление о каждом вводе sudo для контроля доступа к правам суперпользователя. Для этого достаточно добавить в файл /etc/sudoers следующие строки:


mailto [admin@domain.com](mailto:admin@domain.com)

mail_always on

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


Деактивация компиляторов


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


В качестве примера под спойлером отключим доступ к gcc.

Для начала посмотрим список исполняемых файлов командой:


rpm -q --filesbypkg gcc | grep 'bin'


Исполняемые файлы gcc.


Теперь будет удобно создать отдельную группу командой:


groupadd compilerGroup

Затем сменить группу-владельца для нужных файлов:


chown root:compilerGroup /usr/bin/gcc

И задать права доступа, запрещающие доступ к файлам всем прочим:


chmod 0750 /usr/bin/gcc

Иммунитет для файлов конфигураций


Хороший способ защитить системные файлы и конфигурации даже от суперпользователя - это атрибут иммуности. Для его применения используется команда chattr +i filename.



Даже root не может удалить иммунный файл.


Для снятия этого атрибута достаточно выполнить команду chattr -i filename.


Я думаю у каждого администратора есть еще свои best-practices по безопасности серверов. Предлагаю поделиться ими с коллегами в комментариях.

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

https://habrahabr.ru/post/335040/


Метки:  

[Из песочницы] Истинная реализация нейросети с нуля на языке программирования C#

Понедельник, 07 Августа 2017 г. 11:58 + в цитатник

image


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


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


На самом деле, несмотря на обилие математики, она не такая уж и запредельно сложная. Понять сатанистские каракули и письмена этого пособия сможет среднестатистический 11-классник товарищ-физмат или 1~2-курсник технарьской шараги. Помимо этого, пусть книга достаточно объёмная и трудная для восприятия, но вещи, написанные в ней, реально объясняют, что "твориться у тачки под капотом". Как вы поняли я крайне рекомендую(ни в коем случае не рекламирую) "Нейронные сети. Полный курс" Саймона Хайкина к прочтению в том случае, если вам придётся столкнуться с применением/написанием/разработкой нейросетей и прочего подобного stuff'а. Хотя в ней нет материала про новомодные свёрточные сети, никто не мешает загуглить лекции от какого-нибудь харизматичного работника Yandex/Mail.ru/etc. никто не мешает.


Конечно, осознав устройство сеток, я не мог просто остановиться, так как впереди предстояло написание кода. В связи со своим параллельным занятием, заключающемся в создани игр на Unity, языком реализации оказался ламповый и няшный шарпей 7 версии(ибо она последняя актуальная). Именно в этот момент, оказавшись на просторах интернета, я понял, что число внятных туториалов по написанию нейросетей с нуля(без ваших фреймворков) на шарпе бесконечно мало. Ладно. Я мог использовать, всякие Theano и Tensor Flow, НО под капотом моей смерть-машины в моём ноутбуке стоит "красная" видеокарта без особой поддержки API, через которые обращаются к мощи GPU(ведь именно их и используют Theano/Tensor Flow/etc.).


Помогите школоте прошариться:

Моя видеокарта называется ATI Radeon HD Mobility 4570. И если кто знает, как обратиться к её мощностям для параллелизации нейросетевых вычислений, пожалуйста, напишите в комментарии. Тогда вы поможете мне, и возможно у этой статьи появится продолжение. Не осуждается предложение других ЯП.


Просто, как я понял, она настолько старая, что нифига не поддерживает. Может быть я не прав.


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


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


Прежде чем начать программировать это, можнонужно нарисовать на бумаге, дабы облегчить представление структуры и работы нейронки. Моё воображение вылилось в следующую картинку. И да, кстати, это консольное приложение в Visual Studio 2017, с .NET Framework версии 4.7.


Краткая инфа по сетке(для тех, кому это хоть о чём-то говорит)

Многослойный полносвязный персептрон.
Один скрытый слой.
4 нейрона в скрытом слое(на этом количестве персептрон сошёлся).
Алгоритм обучения — backpropagation.
Критерий останова — преодоление порогового значения среднеквадратичной ошибки по эпохе.(0.001)
Скорость обучения — 0.1.
Функция активации — логистическая сигмоидальная.


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


Also

В папке release||debug этого прожекта располагаются файлы(на каждый слой по одному) по имени типа (fieldname)_memory.xml сами знаете для чего. Они создаются заранее с учётом общего количества весов каждого слоя. Знаю, что XML — это не лучший выбор для парсинга, просто времени было немного на это дело.


using System.Xml;
using static System.Math;
using static System.Console;

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


enum MemoryMode { GET, SET }
enum NeuronType { Hidden, Output }

Всё остальное будет происходить внутри пространства имён, которое я назову просто: Neural Network.


namespace NeuralNetwork
{
//всё, что будет описано ниже, располагается здесь
}

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


class InputLayer
    {
        private (double[], double[])[] _trainset = new(double[], double[])[]//да-да, массив кортежей из 2 массивов
        {
            (new double[]{ 0, 0 }, new double[]{ 0, 1 }),
            (new double[]{ 0, 1 }, new double[]{ 1, 0 }),
            (new double[]{ 1, 0 }, new double[]{ 1, 0 }),
            (new double[]{ 1, 1 }, new double[]{ 0, 1 })
        };
        //инкапсуляция едрид-мадрид
        public (double[], double[])[] Trainset { get => _trainset; }//такие няшные свойства нынче в C# 7
     }

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


class Neuron
    {
        public Neuron(double[] inputs, double[] weights, NeuronType type)
        {
            _type = type;
            _weights = weights;
            _inputs = inputs;
        }
        private NeuronType _type;
        private double[] _weights;
        private double[] _inputs;
        public double[] Weights { get => _weights; set => _weights = value; }
        public double[] Inputs { get => _inputs; set => _inputs = value; }
        public double Output { get => Activator(_inputs, _weights); }
        private double Activator(double[] i, double[] w)//преобразования
        {
            double sum = 0;
            for (int l = 0; l < i.Length; ++l)
                sum += i[l] * w[l];//линейные
            return Pow(1 + Exp(-sum), -1);//нелинейные
        }
        public double Derivativator(double outsignal) => outsignal * (1 - outsignal);//формула производной для текущей функции активации уже выведена в ранее упомянутой книге
        public double Gradientor(double error, double dif, double g_sum) => (_type == NeuronType.Output) ? error * dif : g_sum * dif;//g_sum - это сумма градиентов следующего слоя
    }

Ладно у нас есть нейроны, но их необходимо объединить в слои для вычислений. Возвращаясь к моей схеме выше, хочу объяснить наличие чёрного пунктира. Он разделяет слои так, чтобы показать, что они содержат. То есть один вычислительный слой содержит нейроны и веса для связи с нейронами предыдущего слоя. Нейроны объединяются массивом, а не списком, так как это менее ресурсоёмко. Веса организованы матрицей(двумерным массивом) размера(нетрудно догадаться) [число нейронов текущего слоя X число нейронов предыдущего слоя]. Естественно, слой инициализирует нейроны, иначе словим null reference. При этом эти слои очень похожи друг на друга, но имеют различия в логике, поэтому скрытые и выходной слои должны быть реализованы наследниками одного базового класса, который кстати оказывается абстрактным.


abstract class Layer//модификаторы protected стоят для внутрииерархического использования членов класса
    {//type используется для связи с одноимённым полю слоя файлом памяти
        protected Layer(int non, int nopn, NeuronType nt, string type)
        {//увидите это в WeightInitialize
            numofneurons = non;
            numofprevneurons = nopn;
            Neurons = new Neuron[non];
            double[,] Weights = WeightInitialize(MemoryMode.GET, type);
            for (int i = 0; i < non; ++i)
            {
                double[] temp_weights = new double[nopn];
                for (int j = 0; j < nopn; ++j)
                    temp_weights[j] = Weights[i, j];
                Neurons[i] = new Neuron(null, temp_weights, nt);//про подачу null на входы ниже
            }
        }
        protected int numofneurons;//число нейронов текущего слоя
        protected int numofprevneurons;//число нейронов предыдущего слоя
        protected const double learningrate = 0.1d;//скорость обучения
        Neuron[] _neurons;
        public Neuron[] Neurons { get => _neurons; set => _neurons = value; }
        public double[] Data//я подал null на входы нейронов, так как
        {//сначала нужно будет преобразовать информацию
            set//(видео, изображения, etc.)
            {//а загружать input'ы нейронов слоя надо не сразу,
                for (int i = 0; i < Neurons.Length; ++i)
                    Neurons[i].Inputs = value;
            }//а только после вычисления выходов предыдущего слоя
        }
        public double[,] WeightInitialize(MemoryMode mm, string type)
        {
            double[,] _weights = new double[numofneurons, numofprevneurons];
            WriteLine($"{type} weights are being initialized...");
            XmlDocument memory_doc = new XmlDocument();
            memory_doc.Load($"{type}_memory.xml");
            XmlElement memory_el = memory_doc.DocumentElement;
            switch (mm)
            {
                case MemoryMode.GET:
                    for (int l = 0; l < _weights.GetLength(0); ++l)
                        for (int k = 0; k < _weights.GetLength(1); ++k)
                            _weights[l, k] = double.Parse(memory_el.ChildNodes.Item(k + _weights.GetLength(1) * l).InnerText.Replace(',', '.'), System.Globalization.CultureInfo.InvariantCulture);//parsing stuff
                    break;
                case MemoryMode.SET:
                    for (int l = 0; l < Neurons.Length; ++l)
                        for (int k = 0; k < numofprevneurons; ++k)
                            memory_el.ChildNodes.Item(k + numofprevneurons * l).InnerText = Neurons[l].Weights[k].ToString();
                    break;
            }
            memory_doc.Save($"{type}_memory.xml");
            WriteLine($"{type} weights have been initialized...");
            return _weights;
        }
        abstract public void Recognize(Network net, Layer nextLayer);//для прямых проходов
        abstract public double[] BackwardPass(double[] stuff);//и обратных
    }

Соль абстрактных классов

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


Теперь непосредственно классы-наследники: Hidden и Output. Сразу два класса в цельном куске кода.


class HiddenLayer : Layer
    {
        public HiddenLayer(int non, int nopn, NeuronType nt, string type) : base(non, nopn, nt, type){}
        public override void Recognize(Network net, Layer nextLayer)
        {
            double[] hidden_out = new double[Neurons.Length];
            for (int i = 0; i < Neurons.Length; ++i)
                hidden_out[i] = Neurons[i].Output;
            nextLayer.Data = hidden_out;
        }
        public override double[] BackwardPass(double[] gr_sums)
        {
            double[] gr_sum = null;
            //сюда можно всунуть вычисление градиентных сумм для других скрытых слоёв
            //но градиенты будут вычисляться по-другому, то есть
            //через градиентные суммы следующего слоя и производные
            for (int i = 0; i < numofneurons; ++i)
                for (int n = 0; n < numofprevneurons; ++n)
                    Neurons[i].Weights[n] += learningrate * Neurons[i].Inputs[n] * Neurons[i].Gradientor(0, Neurons[i].Derivativator(Neurons[i].Output), gr_sums[i]);//коррекция весов
            return gr_sum;
        }
    }
class OutputLayer : Layer
    {
        public OutputLayer(int non, int nopn, NeuronType nt, string type) : base(non, nopn, nt, type){}
        public override void Recognize(Network net, Layer nextLayer)
        {
            for (int i = 0; i < Neurons.Length; ++i)
                net.fact[i] = Neurons[i].Output;
        }
        public override double[] BackwardPass(double[] errors)
        {
            double[] gr_sum = new double[numofprevneurons];
            for (int j = 0; j < gr_sum.Length; ++j)//вычисление градиентных сумм выходного слоя
            {
                double sum = 0;
                for (int k = 0; k < Neurons.Length; ++k)
                    sum += Neurons[k].Weights[j] * Neurons[k].Gradientor(errors[k], Neurons[k].Derivativator(Neurons[k].Output), 0);//через ошибку и производную
                gr_sum[j] = sum;
            }
            for (int i = 0; i < numofneurons; ++i)
                for (int n = 0; n < numofprevneurons; ++n)
                    Neurons[i].Weights[n] += learningrate * Neurons[i].Inputs[n] * Neurons[i].Gradientor(errors[i], Neurons[i].Derivativator(Neurons[i].Output), 0);//коррекция весов
            return gr_sum;
        }
    }

В принципе, всё самое важное я описал в комментариях. У нас есть все компоненты: обучающие и тестовые данные, вычислительные элементы, их "конгламераты". Теперь настало время всё связать обучением. Алгоритм обучения — backpropagation, следовательно критерий останова выбираю я, и выбор мой — есть преодоление порогового значения среднеквадратичной ошибки по эпохе, которое я выбрал равным 0.001. Для поставленной цели я написал класс Network, описывающий состояние сети, которое принимается в качестве параметра многих методов, как вы могли заметить.


class Network
    {
        //все слои сети
        InputLayer input_layer = new InputLayer();
        public HiddenLayer hidden_layer = new HiddenLayer(4, 2, NeuronType.Hidden, nameof(hidden_layer));
        public OutputLayer output_layer = new OutputLayer(2, 4, NeuronType.Output, nameof(output_layer));
        //массив для хранения выхода сети
        public double[] fact = new double[2];//не ругайте за 2 пожалуйста
        //ошибка одной итерации обучения
        double GetMSE(double[] errors)
        {
            double sum = 0;
            for (int i = 0; i < errors.Length; ++i)
                sum += Pow(errors[i], 2);
            return 0.5d * sum;
        }
        //ошибка эпохи
        double GetCost(double[] mses)
        {
            double sum = 0;
            for (int i = 0; i < mses.Length; ++i)
                sum += mses[i];
            return (sum / mses.Length);
        }
        //непосредственно обучение
        static void Train(Network net)//backpropagation method
        {
            const double threshold = 0.001d;//порог ошибки
            double[] temp_mses = new double[4];//массив для хранения ошибок итераций
            double temp_cost = 0;//текущее значение ошибки по эпохе
            do
            {
                for (int i = 0; i < net.input_layer.Trainset.Length; ++i)
                {
                    //прямой проход
                    net.hidden_layer.Data = net.input_layer.Trainset[i].Item1;
                    net.hidden_layer.Recognize(null, net.output_layer);
                    net.output_layer.Recognize(net, null);
                    //вычисление ошибки по итерации
                    double[] errors = new double[net.input_layer.Trainset[i].Item2.Length];
                    for (int x = 0; x < errors.Length; ++x)
                        errors[x] = net.input_layer.Trainset[i].Item2[x] - net.fact[x];
                    temp_mses[i] = net.GetMSE(errors);
                    //обратный проход и коррекция весов
                    double[] temp_gsums = net.output_layer.BackwardPass(errors);
                    net.hidden_layer.BackwardPass(temp_gsums);
                }
                temp_cost = net.GetCost(temp_mses);//вычисление ошибки по эпохе
                //debugging
                WriteLine($"{temp_cost}");
            } while (temp_cost > threshold);
            //загрузка скорректированных весов в "память"
            net.hidden_layer.WeightInitialize(MemoryMode.SET, nameof(hidden_layer));
            net.output_layer.WeightInitialize(MemoryMode.SET, nameof(output_layer));
        }
        //тестирование сети
        static void Test(Network net)
        {
            for (int i = 0; i < net.input_layer.Trainset.Length; ++i)
            {
                net.hidden_layer.Data = net.input_layer.Trainset[i].Item1;
                net.hidden_layer.Recognize(null, net.output_layer);
                net.output_layer.Recognize(net, null);
                for (int j = 0; j < net.fact.Length; ++j)
                    WriteLine($"{net.fact[j]}");
                WriteLine();
            }
        }
        //запуск сети
        static void Main(string[] args)
        {
            Network net = new Network();
            Train(net);
            Test(net);
            ReadKey();//чтоб консоль не закрывалась :)
        }
    }

Результат обучения.
image


Итого, путём насилования мозга несложных манипуляций, мы получили основу работающей нейронной сети. Для того, чтобы заставить её делать что-либо другое, достаточно поменять класс InputLayer и подобрать параметры сети для новой задачи. Через время(какое конкретно не знаю) напишу продолжение этой статьи с руководством по созданию с нуля свёрточной нейронной сети на C# и здесь сделаю апдейт этой с ссылками на MLP-рекогнитор картинок MNIST(но это не точно) и код статьи на Python(точно, но дольше ждать).


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

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

https://habrahabr.ru/post/335052/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1084 1083 [1082] 1081 1080 ..
.. 1 Календарь