Как Dark развертывает код за 50 мс

Чем быстрее процесс разработки, тем быстрее развивается технологическая компания.

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

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

От скорости этих пайплайнов зависит скорость разработки. У лучших команд развертывание занимает 5–10 минут, но обычно все делается гораздо дольше, и для одного развертывания требуется несколько часов.

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

Почему конвейеры непрерывной поставки такие медленные?

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

Внесение изменений

  • Создание новой ветки в git
  • Внесение изменений за переключателем функции
  • Модульное тестирование для проверки изменений с переключателем функции и без

Пул-реквест

  • Коммит изменений
  • Отправка изменений в удаленный репозиторий на github
  • Пул-реквест
  • Сборка CI выполняется автоматически в фоновом режиме
  • Ревью кода
  • Еще несколько ревью, если нужно
  • Слияние изменений с мастером git.

CI выполняется на мастере

  • Установка фронтенд-зависимостей через npm
  • Сборка и оптимизация ресурсов HTML+CSS+JS
  • Прогон во фронтенде модульных и функциональных тестов
  • Установка зависимостей Python из PyPI
  • Прогон в бэкенде модульных и функциональных тестов
  • Тестирование интеграции на обоих концах
  • Отправка ресурсов фронтенда в CDN
  • Сборка контейнера для программы Python
  • Отправка контейнера в реестр
  • Обновление манифеста Kubernetes

Замена старого кода новым

  • Kubernetes запускает несколько экземпляров нового контейнера
  • Kubernetes ждет, чтобы экземпляры стали работоспособными
  • Kubernetes добавляет экземпляры в балансировщик нагрузки HTTP
  • Kubernetes ждет, пока старые экземпляры перестанут использоваться
  • Kubernetes останавливает старые экземпляры
  • Kubernetes повторяет эти операции, пока новые экземпляры не заменят все старые

Включение нового переключателя функции

  • Новый код включается только для себя, чтобы убедиться, что все нормально
  • Новый код включается для 10% пользователей, отслеживаются операционные и бизнес-метрики
  • Новый код включается для 50% пользователей, отслеживаются операционные и бизнес-метрики
  • Новый код включается для 100% пользователей, отслеживаются операционные и бизнес-метрики
  • Наконец, вы повторяете всю процедуру, чтобы удалить старый код и переключатель

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

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

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

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

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

Реализация непрерывной поставки в Dark

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

Джесси Фразель (Jessie Frazelle) придумала новое слово deployless (не требующий развертывания) на конференции Future of Software Development в Рейкьявике

Мы сразу решили, что Dark будет основан на концепции «deployless» (спасибо Джесси Фразель за неологизм). Deployless означает, что любой код моментально развертывается и готов к употреблению в продакшене. Конечно, мы не пропустим неисправный или неполный код (принципы безопасности я опишу ниже).

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

Dark запускает интерпретаторы в облаке. Допустим, вы пишете код в функции или обработчике HTTP или событий. Мы отправляем diff в абстрактное синтаксическое дерево (реализацию кода, которую внутренне использует наш редактор и серверы) на наши серверы, а затем запускаем этот код, когда поступают запросы. Так что развертывание выглядит просто как скромная запись в базу данных — моментальная и элементарная. Развертывание происходит так быстро, потому что включает самый минимум.

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

Безопасное развертывание

Структурированный редактор

Код в Dark пишется в редакторе Dark. Структурированный редактор не допускает синтаксических ошибок. По сути, в Dark даже анализатора нет. Пока вы вводите текст, мы напрямую работаем с абстрактным синтаксическим деревом (AST), как Paredit, Sketch-n-Sketch, Tofu, Prune и MPS.

У любого незавершенного кода в Dark есть допустимая семантика выполнения, примерно как typed holes в Hazel. Например, если вы меняете вызов функции, мы храним старую функцию, пока новая не станет пригодной.

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

Режимы редактирования

Вы пишете код в Dark в двух случаях. Первый: вы пишете новый код и являетесь единственным пользователем. Например, он в REPL, и другие пользователи никогда не получат к нему доступ, или это новый маршрут HTTP, на который вы нигде не ссылаетесь. Тут можно работать без всяких мер предосторожности, и сейчас вы примерно так и работаете в среде разработки.

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

Переключатели функций

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

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

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

Среда разработки

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

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

Ветки и развертывания

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

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

Git сложно использовать, особенно новичкам, и это здорово его ограничивает, но зато у него есть удобные ветки. Мы сгладили многие недостатки git. Dark редактируется в реальном времени и обеспечивает возможность совместной работы в стиле Google Документов, чтобы не приходилось отправлять код и можно было реже выполнять перебазирование и слияние.

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

Версионирование

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

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

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

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

Новые версии пакетов и стандартная библиотека

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


Скриншот части автоматического процесса в Dark, показывающий две версии функции Dict::get. Dict::get_v0 возвращал тип Any (от которого мы отказываемся), а Dict::get_v1 возвращает тип Option.

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

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

Новые версии Dark

Переход с Python 2 на Python 3 растянулся на десятилетие и до сих пор остается проблемой. Раз мы создаем Dark для непрерывной поставки, нужно учитывать эти изменения языка.

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

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

Миграции баз данных

Для безопасной миграции базы данных существует стандартная формула:

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

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

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

Доступ к хранилищам данных в Dark осуществляется через версионированные имена переменных. Например, хранилище данных Users изначально будет называться Users-v0. Когда создается новая версия с другим типом, имя меняется на Users-v1. Если данные сохранены через Users-v0, а вы обращаетесь к ним через Users-v1, применяется функция наката. Если данные сохранены через Users-v1, а вы обращаетесь к ним через Users-v0, применяется функция отката.


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

Используйте переключатели функций, чтобы направить вызовы к Users-v0 в версию Users-v1. Это можно делать по одному обработчику HTTP за раз, чтобы снизить риски, а еще переключатели работают для отдельных пользователей, чтобы вы могли проверить, что все работает, как ожидалось. Когда пользователей Users-v0 не останется, Dark преобразует все оставшиеся данные в фоновом режиме из старого формата в новый. Вы этого даже не заметите.

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

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

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

От чего мы избавились

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


Сравнение стандартного пайплайна непрерывной поставки (слева) и непрерывная поставка Dark (справа). В Dark поставка состоит из 6 шагов и одного цикла, а традиционная версия включает 35 шагов и 3 цикла.

В Dark в развертывании всего 6 шагов и 1 цикл (шаги, которые повторяются несколько раз), в то время как современный пайплайн непрерывной поставки состоит из 35 шагов и 3 циклов. В Dark тесты запускаются автоматически, и вы этого даже не видите; зависимости устанавливаются автоматически; все, что связано с git или Github, больше не нужно; собирать, тестировать и отправлять контейнеры Docker не нужно; развертывание в Kubernetes больше не нужно.

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

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

Я отвечаю на вопросы об этом на HackerNews.

Чтобы узнать больше об устройстве Dark, прочтите статью о Dark, подпишитесь на нас в Twitter (или на меня) или запишитесь на бета-версию и получайте уведомления о следующих постах. Если едете на StrangeLoop в сентябре, приходите к нам на запуск.


ссылка на оригинал статьи https://habr.com/ru/company/southbridge/blog/462027/

Вход в Aeronet, эпизод 2: Самонаводящийся дрон

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

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

Такое задание (лопнуть шарик автономным дроном) недавно выполняли команды на секции Аэронет всероссийского Робокросса-2019. На него нас вдохновила песня “Seek and destroy” с дебютного альбома одной весьма популярной во времена моей бурной молодости американской группы.
В последующем цикле статей мы рассмотрим, как научить автономного дрона выполнять нехитрые инструкции из припева вышеупомянутой песенки.

Итак, нам понадобится следующее:

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

Далее, обо всём по порядку.

jMAVSim, управляемый с клавиатуры

Представим себе дрон, видящий шарик, примерно как на картинке выше. Камера дрона смотрит строго вперёд.

Для налёта на шарик наш дрон должен уметь: двигаться вперёд/назад, поворачивать влево и вправо, лететь выше и ниже. Шарик будет двигаться в объективе камеры не только от порывов ветра, но и от наклонов дрона по крену и тангажу, но данными наклонами мы пока пренебрегаем.

Управлять мы будем скоростями дрона, отправляя через mavros сообщения в топик /mavros/setpoint_velocity/cmd_vel_unstamped.

Для манипуляций дроном с клавиатуры используем модуль curses (описание на русском, на английском).

Алгоритм простой: текущие значения желаемых скоростей хранятся в переменной setvel типа geometry_msgs.msg.Twist. По нажатии кнопки на клавиатуре мы увеличиваем/уменьшаем нужную компоненту скорости. По таймеру 20 раз в секунду публикуем скорость в указанный топик.

Для скорости движения вперёд (относительно дрона) потребуется уточнение. Дело в том, что скорости полёта должны задаваться в локальной системе координат «мира», в котором летает наш дрон. Поэтому нужно отслеживать текущее положение (pose) дрона в этой системе координат. Ось Х дрона повёрнута относительно оси Х «мира» на определённый угол yaw. Текущую позицию дрона в координатах «мира» mavros публикует в топик /mavros/local_position/pose. Получив из позиции угол yaw, чтобы получить и опубликовать желаемую скорость дрона в координатах мира – мы умножаем желаемую скорость движения вперёд setvel_forward на cos(yaw) для оси Х и на sin(yaw) для оси Y «мира», соответственно.

Полный текст программы:

#!/usr/bin/env python # coding=UTF-8 import rospy import mavros import mavros.command as mc from mavros_msgs.msg import State from geometry_msgs.msg import PoseStamped, Twist, Quaternion from mavros_msgs.srv import CommandBool from mavros_msgs.srv import SetMode import tf.transformations as t import math  current_state=State() current_pose = PoseStamped() current_vel = Twist()  def localpose_callback(data):     global current_pose     current_pose = data  def publish_setvel(event):     global current_pose, setvel_pub, setvel, setvel_forward     q=current_pose.pose.orientation.x, current_pose.pose.orientation.y,current_pose.pose.orientation.z,current_pose.pose.orientation.w     roll, pitch, yaw = t.euler_from_quaternion(q)     setvel.linear.x = setvel_forward * math.cos(yaw)     setvel.linear.y = setvel_forward * math.sin(yaw)     setvel_pub.publish(setvel)  def main():     global current_pose, setvel, setvel_pub, setvel_forward      rospy.init_node("offbrd",anonymous=True)     rate=rospy.Rate(10)     pose_sub=rospy.Subscriber("/mavros/local_position/pose",PoseStamped,localpose_callback)     setvel_pub=rospy.Publisher("/mavros/setpoint_velocity/cmd_vel_unstamped",Twist,queue_size=1)     arming_s=rospy.ServiceProxy("/mavros/cmd/arming",CommandBool)     set_mode=rospy.ServiceProxy("/mavros/set_mode",SetMode)     setvel=Twist()     setvel_forward = 0      arming_s(True)     set_mode(0,"AUTO.TAKEOFF")     print 'Taking off.....\r'     rospy.sleep(5)      # keyboard manipulation     import curses     stdscr = curses.initscr()     curses.noecho()     stdscr.nodelay(1)     stdscr.keypad(1)      for i in range (0,10):         setvel_pub.publish(setvel)         rate.sleep()     set_mode(0,"OFFBOARD")     setvel_timer = rospy.Timer(rospy.Duration(0.05), publish_setvel)     while (rospy.is_shutdown()==False):         rate.sleep()         # keyboard  hcommands handling             c = stdscr.getch()         if c == ord('q'): break  # Exit the while()         elif c == ord('u'): setvel.linear.z += 0.25         elif c == ord('d'): setvel.linear.z -= 0.25         elif c == curses.KEY_LEFT: setvel.angular.z += 0.25         elif c == curses.KEY_RIGHT: setvel.angular.z -= 0.25         elif c == curses.KEY_UP: setvel_forward += 0.25          elif c == curses.KEY_DOWN: setvel_forward -= 0.25         elif c == ord('s'): setvel_forward=setvel.linear.z=setvel.angular.z=0         if  c!=curses.ERR:            print setvel,'\r'     curses.endwin()     set_mode(0,"AUTO.LAND")     print 'Landing.......\r'  if __name__=="__main__":     main()

Для запуска программы на выполнение нам нужно запустить jMAVSim, и подключить к нему mavros с помощью команды roslaunch mavros (предварительно запустив roscore, если он не был запущен автоматически):

roslaunch mavros mavros_sitl.launch fcu_url:="udp://@192.168.7.14:14580"

Убедиться, что мы подключились с помощью rostopic echo /mavros/state. Поле connected должно быть = True .

После этого сохранить код программы в файл и запустить его на выполнение командой python fly_mavsim.py. Виртуальный квадрокоптер должен подняться на высоту примерно 2 метра (высота взлёта задаётся в параметре MIS_TAKEOFF_ALT в QGroundControl) и зависнуть. С помощью кнопок на клавиатуре им можно управлять: стрелки вправо-влево – поворот, стрелки вверх-вниз – движение вперёд/назад, u – лететь вверх (UP), d – лететь вниз (DOWN), s – зависнуть на месте (STOP, все скорости = 0), q – выйти из программы (QUIT) и посадить квадрокоптер.

Можно полетать по виртуальному миру, проверить как ведёт себя в полёте идеальный виртуальный дрон.

Витруальный дрон в полёте

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

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

Управляемый с клавиатуры реальный дрон

В сети много инструкций по сборке и настройке коптеров на стеке PX4. Довольно подробно процесс описан в документации разработчиков.

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

В качестве бортового компьютера мы используем Raspberry PI 3 Model B+, с установленным Raspbian + ROS Kinetic. Подключение Raspberry к полётному контролеру Pixracer осуществляется через uart, по схеме:

Pixracer + Raspberry PI

GPS модуль подключается в порт GPS полётного контроллера. Я пользуюсь модулем TS100 от Radiolink, качество хорошее, стоимость не высокая.

ROS Kinetic можно установить самостоятельно, воспользовавшись инструкцией. На Raspberry следует настроить доступ по Wifi и ssh (вот инструкция, например).

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

sudo systemctl stop clever sudo systemctl disable clever

Другой образ Raspberry с ROS и OpenCV описан вот здесь, его я не пробовал в работе, но используемые инструменты похожи.

После включения дрона и подключения к Raspberry по ssh – запускаем mavros и проверяем связь с полётным контроллером:

roslaunch mavros px4.launch fcu_url:='/dev/ttyAMA0:921600' gcs_url:='tcp-l://0.0.0.0:5760' rostopic echo /mavros/state

Если всё работает правильно – раз в секунду получаем сообщения о состоянии полётного контроллера с полем Connected = True.

Параметр gcs_url в вызове mavros нужен для того, чтоб мы могли подключить QGroundControl к полётному контроллеру дрона по WiFi через TCP-bridge. Параметры подключения задаются в QGroundControl:

Для подготовки дрона к автономному полёту я выполняю несколько простых шагов:

1. Убедимся, что дрон хорошо летает в ручном режиме. Для этого должны быть выбраны правильные настройки параметров и откалиброваны все датчики. Использование серийно производимого дрона избавило меня от мороки на этом этапе. Я использовал LPE estimator с включенным GPS и барометром:

2. Если старт системы происходит в новом месте или первый раз – следует дождаться «прогрева» GPS модуля. При штатной работе на улице GPS у меня обычно ловит от 16 до 22 спутников.

3. Перед полётом на новом месте, и в случае, если дрон не держит точку – следует перекалибровать компас:

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

Если все настройки выполнены корректно – дрон должен уверенно держать точку в режиме HOLD и летать стабильно в режиме Position.

После успешных тестовых полётов в ручном режиме – мы можем проверить, как работает наша программа fly_jmavsim.py на реальном дроне: видео.

Реальный дрон летает не так идеально, как виртуальный – но он также должен слушаться команд с клавиатуры – лететь в нужном направлении, и останавливаться по команде.

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

Настройки нашего полётного контроллера + программный код выложены на Гитхабе.


ссылка на оригинал статьи https://habr.com/ru/post/461887/

Подходы к сегментации мобильных игроков — перевод

Алисса Перез из команды Google Play Dev написала статью, которую мы перевели. В ней много полезной информации о подходах к сегментации пользователей: юзер-таргетинге и его связи с развитием бизнеса.

image

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

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

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

Преимущества сегментации

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

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

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

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

Сегментация по вовлеченности

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

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

Сегментация по вовлеченности позволяет нам:

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

Как измерить вовлеченность?

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

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

Ниже я приведу примеры ключевых действий в разных жанрах:

  • В казуальных играх «три-в-ряд» важны не те, кто заходит в игру и собирает ежедневный бонус, а те, кто проходит уровни. Или хотя бы пытается их пройти, потому что именно это отражает желание пройти игру. Любое прохождение уровня (особенно неудачное!) мотивирует игрока тратить внутриигровую валюту.
  • Социальные азартные игры позволяют игрокам ежедневно (иногда даже ежечасно) зарабатывать внутриигровую валюту. Здесь ключевое действие заключается в трате этой самой валюты. Вовлеченность отражает то, сколько раз игрок крутил рулетку, играл в бинго и разом тратил все свои сбережения.
  • Стратегии вынуждают игрока тщательно планировать множество разных действий как для своего развития, так и для борьбы с другими игроками. Тут вовлеченность зависит преимущественно от взаимодействий между игроками. Хорошим показателем служит, например, количество нападений, потому что от них обычно многое зависит: скорость восстановления ресурсов, строительства новых лагерей, ответные атаки. В то же время игроки, которые выполняют сюжетные задания, тоже совершают ключевое действие, являясь той социальной группой, которой не слишком интересны исключительно войны с другими людьми. Тем не менее, обе этих группы могут очень активно тратить внутриигровую валюту.

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

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

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

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

Сегментация по монетизации

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

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

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

  1. Мотиваторы покупки. Это факторы, которые определяют покупательское поведение. Они могут быть связаны с игровым прогрессом, размером игрового кошелька, набором новичка, акциями, игровыми событиями, новым контентом и многим другим.
  2. Уровень платежеспособности. После того как игрок единожды совершил внутриигровую покупку, нам нужно определить, сколько он готов тратить в принципе и насколько часто. Для этого мы можем рассчитать среднюю потраченную сумму (за 4–6 недель) и впоследствии предлагать ему только те условия, на которые он потенциально согласен.
  3. Частота покупок. Эта информация поможет нам сохранить текущую частоту покупок или, возможно, увеличить ее, поскольку мы начнем понимать, как часто игроку комфортно тратить деньги. Если игрок совершил несколько покупок подряд, то, возможно, стоит предложить ему что-то еще дополнительно.

Именно на эти моменты следует опираться в процессе модернизации своей стратегии по монетизации. Например:

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

Попробуем объяснить на примере, как правильно формировать предложение. Предположим, у нас есть пользователь, который за месяц совершил покупок на 10$. Мы можем предложить ему товаров на 50$, но! Во-первых, он вряд ли их купит: сумма заметно выше той, которую он тратит обычно. Во-вторых, даже если он их купит, он может решить начать экономить и на какое-то время перестать покупать внутриигровые товары. Более того, существует вероятность, что непривычно большого количества товаров ему хватит до следующей акции, что сформирует у него привычку делать исключительно акционные покупки. Мы рекомендуем сделать такому пользователю сразу два предложения: менее ценное за 5$ и очень ценное за 15$.

image

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

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

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

«Во Vlogger Go Viral мы утроили количество плательщиков, сегментируя нашу аудиторию и предлагая разным группам разные предложения», — Гильерм Кэмпбелл, глава производственного отдела, Tapps games.

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

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

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

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

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

image

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

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

Подходы к внедрению сегментации

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

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

Итоги

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


ссылка на оригинал статьи https://habr.com/ru/post/462041/

Еще одно мнение о разнице между bin, sbin, usr/bin, usr/sbin

Недавно я обнаружил вот такую статью: Разница между bin, sbin, usr/bin, usr/sbin. Хотелось бы поделиться своим взглядом на стандарт.

/bin

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

Там ожидается присутствие таких команд:

cat, chgrp, chmod, chown, cp, date, dd, df, dmesg, echo, false, hostname, kill, ln, login, ls, mkdir, mknod, more, mount, mv, ps, pwd, rm, rmdir, sed, sh, stty, su, sync, true, umount, uname.

Можно сделать симлинки на /usr, но хотя во времена systemd /usr на отдельном устройстве не встречается, его еще можно встретить на встраиваемой системе, светофоре, кофемолке и PDP-11 обслуживающем важный прибор в одной из лабораторий Академии Наук.

/sbin

Утилиты, используемые для системного администрирования (и другие команды только для root), /sbin содержит двоичные файлы, необходимые для загрузки, восстановления, восстановления и/или восстановления системы в дополнение к двоичным файлам в /bin. Программы, выполняемые после того, как /usr монтируется (когда проблем нет), обычно помещаются в /usr/sbin. Локально установленные программы системного администрирования должны быть помещены в /usr/local/sbin.

Ожидаются:

fastboot, fasthalt, fdisk, fsck, getty, halt, ifconfig, init, mkfs, mkswap, reboot, route, swapon, swapoff, update.

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

/usr/bin

Тут всё просто. Однотипные команды, одинаковые для всех серверов/кофемолок компании. И сам /usr может разворачиваться одинаковым для разных ОС (для /bin и /sbin такое как правило не работает), это архитектурно независимые программы. Может содержать линки на интерпретаторы perl или python, которые лежат в /opt или еще где-то в сети.

/usr/sbin

Тоже самое, что /usr/bin, но для использования только админами.

/usr/local/bin и /usr/local/sbin

Одна из важнейших локаций. В-отличие от остального /usr не может быть одинаковой для всей организации. Тут находядтся ОС-зависимые, hardware-зависимые и просто программы, которые не на всех устройствах нужны. При синхронизации /usr на машинах, /usr/local требуется исключать.

/home/$USER/bin

Тут случай аналогичный с /usr/local, только лежат программы специфичные для конкретного пользователя. Можно переносить (или синхронизировать) на другую машину при переезде пользователя. То, что нельзя переносить складывается в /home/$USER/.local/bin. Можно использовать local без точки. /home/$USER/sbin по понятным соображениям отсутствует.

Буду рад исправлениям и дополнениям.


ссылка на оригинал статьи https://habr.com/ru/post/462045/

Как стать более востребованным специалистом в сфере Data Science в 2019

Заголовок этой статьи может показаться немного странным. И вправду: если вы работаете в сфере Data Science в 2019, вы уже востребованы. Спрос на специалистов в этой области неуклонно растет: на момент написания этой статьи, на LinkedIn размещено 144,527 вакансий с ключевым словом «Data Science».

Тем не менее, следить за последними новостями и трендами в индустрии однозначно стоит. Чтобы помочь вам в этом, мы с командой CV Compiler проанализировали несколько сотен вакансий в сфере Data Science за июнь 2019 и определили, какие навыки ожидают от кандидатов работодатели чаще всего.

Самые востребованные навыки в сфере Data Science в 2019

Этот график показывает навыки, которые работодатели чаще всего упоминают в вакансиях в сфере Data Science в 2019:

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

Важно: Этот рейтинг демонстрирует скорее предпочтения работодателей, чем самих специалистов в сфере Data Science.

Основные тренды в сфере Data Science

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

Big Data

Согласно исследованиям рынка Big Data в 2018 году, применение Big Data на предприятиях возросло с 17% в 2015 до 59% в 2018. Соответственно, возросла и популярность инструментов для работы с большими данными. Если не учитывать Apache Spark и Hadoop (о последнем мы еще поговорим подробнее), самыми популярными инструментами являются MapReduce (36) и Redshift (29).

Hadoop

Несмотря на популярность Spark и облачных хранилищ, «эра» Hadoop еще не окончена. Поэтому некоторые компании ожидают от кандидатов знания Apache Pig (30), HBase (32), и похожих технологий. HDFS (20) также еще встречается в некоторых вакансиях.

Обработка данных в режиме реального времени

Учитывая повсеместное использование различных датчиков и мобильных устройств, а также популярность IoT (18), компании пытаются научиться обрабатывать данные в режиме реального времени. Поэтому платформы обработки потоков, такие как Apache Flink (21), популярны среди работодателей.

Feature Engineering и Hyperparameter Tuning

Подготовка данных и выбор параметров модели — важная часть работы любого специалиста в сфере Data Science. Поэтому термин Data Mining (128) довольно популярен среди работодателей. Некоторые компании также уделяют внимание Hyperparameter Tuning (21) (о таком термине как Feature Engineering тоже забывать не стоит). Подбор оптимальных параметров для модели — это важно, ведь от успеха этой операции зависит работоспособность модели в целом.

Визуализация данных

Умение правильно обработать данные и выводить необходимые закономерности — это важно. Тем не менее, визуализация данных (55) является не менее важным навыком. Необходимо уметь представить результаты своей работы в формате, понятном любому члену команды или клиенту. Что касается инструментов для визуализации данных, работодатели предпочитают Tableau (54).

Общие тренды

В вакансиях нам также встречались такие термины как AWS (86), Docker (36), а также Kubernetes (24). Можно сделать вывод, что общие тренды из сферы разработки ПО потихоньку перекочевали в сферу Data Science.

Мнение экспертов

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

Карла Гентри,
Data Scientist, владелец Analytical Solution
LinkedIn | Twitter

Этот график показывает текущие тренды в области Data Science, но предсказать будущее, основываясь на него, довольно сложно. Я склонен считать, что популярность R будет снижаться (как и популярность MATLAB), в то время как популярность Python будет только расти. Hadoop и Big Data также оказались в списке по инерции: Hadoop вскоре исчезнет (никто больше не инвестирует в эту технологию всерьез), а Big Data перестало быть нарастающим трендом. Будущее Scala не совсем ясно: Google официально поддерживает Kotlin, который гораздо более прост для изучения. Я также скептически отношусь к будущему TensorFlow: научное сообщество предпочитает PyTorch, а влияние научного сообщества в сфере Data Science куда выше, чем во всех остальных сферах. (Это мое личное мнение, которое может не совпадать с мнением Gartner).

Андрей Бурков,
Director of Machine Learning в Gartner,
автор Hundred-Page Machine Learning Book.
LinkedIn

PyTorch — это движущая сила обучения с подкреплением, а также сильный фреймворк для параллельного выполнения кода на нескольких графических процессорах (чего не скажешь о TensorFlow). PyTorch также помогает строить динамические графы, которые эффективны при работе с рекуррентными нейронными сетями. TensorFlow оперирует статическими графами и более сложен для изучения, но его использует большее количество разработчиков и исследователей. Однако, PyTorch ближе к Python в плане отладки кода и библиотек для визуализации данных (matplotlib, seaborn). Большинство инструментов отладки кода на Python можно использовать для отладки кода на PyTorch. У TensorFlow же есть свой инструмент для отладки — tfdbg.

Ганапати Пулипака,
Chief Data Scientist в Accenture,
обладатель премии Top 50 Tech Leader.
LinkedIn | Twitter

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

Лон Ризберг,
Основатель/куратор Data Elixir,
ex-NASA.
Twitter | LinkedIn

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

Эта статья была подготовлена командой CV Compiler — инструмента для улучшения резюме для специалистов в сфере Data Science и других отраслях IT.


ссылка на оригинал статьи https://habr.com/ru/post/462049/