Yield at me 'cause I'm awaiting: асинхронные итераторы в C# 8Andrey Karpov
Язык C# продолжает интенсивно развиваться. Готовящаяся к выходу новая версия добавляет поддержку асинхронных итераторов. Что это такое? Для чего это нужно? Как это работает? В докладе мы ответим на все эти вопросы, разберём нововведения в BCL, сравним новые возможности с уже существующими средствами и, конечно же, заглянем под капот компилятора.
Модульное тестирование является неотъемлемой частью современного процесса разработки. В своем докладе я хочу поговорить о том как нужно разрабатывать модульные тесты в проекте на C++ так чтобы это приносило максимум пользы.
В рамках данного выступления вас ждут:
* рассказ о полезных и интересных вещах из Boost
* новости с передовиц разработки Boost и о новинках ожидаемых в следующих версиях
* что из Boost готовится к переезду в новый стандарт С++
* как экспериментировать с Boost, имея под рукой только браузер
* что людям не нравится в Boost и как с этими людьми бороться (-:
Григорий Демченко — Асинхронное программирование и сопрограммыYandex
Как показывает практика, повсеместное применение классического, основанного на callback’ах подхода к асинхронному программированию обычно оказывается неудобным. Для упрощения написания и поддержки сложного асинхронного кода можно использовать иной подход — с использованием сопрограмм. Он значительно сокращает объём и сложность кода, а также существенно упрощает реализацию нетривиальных сценариев, связанных с отменой вычислений и таймаутами операций.
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
В последнее время в промышленной разработке ПО особую популярность обретают Domain-Specific Lanugages (DSL). Они драматически упрощают разработку и дают возможность “программировать” не только программистам, но и пользователям прикладных программ.
В своем докладе я расскажу об опыте использования DSL применительно к С++, причем упор будет сделан на производительность кода DSL, и его мгновенную “встраиваемость” в запущенную программу путем компиляции DSL-кода в нативный код с помощью инструментария LLVM.
Yield at me 'cause I'm awaiting: асинхронные итераторы в C# 8Andrey Karpov
Язык C# продолжает интенсивно развиваться. Готовящаяся к выходу новая версия добавляет поддержку асинхронных итераторов. Что это такое? Для чего это нужно? Как это работает? В докладе мы ответим на все эти вопросы, разберём нововведения в BCL, сравним новые возможности с уже существующими средствами и, конечно же, заглянем под капот компилятора.
Модульное тестирование является неотъемлемой частью современного процесса разработки. В своем докладе я хочу поговорить о том как нужно разрабатывать модульные тесты в проекте на C++ так чтобы это приносило максимум пользы.
В рамках данного выступления вас ждут:
* рассказ о полезных и интересных вещах из Boost
* новости с передовиц разработки Boost и о новинках ожидаемых в следующих версиях
* что из Boost готовится к переезду в новый стандарт С++
* как экспериментировать с Boost, имея под рукой только браузер
* что людям не нравится в Boost и как с этими людьми бороться (-:
Григорий Демченко — Асинхронное программирование и сопрограммыYandex
Как показывает практика, повсеместное применение классического, основанного на callback’ах подхода к асинхронному программированию обычно оказывается неудобным. Для упрощения написания и поддержки сложного асинхронного кода можно использовать иной подход — с использованием сопрограмм. Он значительно сокращает объём и сложность кода, а также существенно упрощает реализацию нетривиальных сценариев, связанных с отменой вычислений и таймаутами операций.
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
В последнее время в промышленной разработке ПО особую популярность обретают Domain-Specific Lanugages (DSL). Они драматически упрощают разработку и дают возможность “программировать” не только программистам, но и пользователям прикладных программ.
В своем докладе я расскажу об опыте использования DSL применительно к С++, причем упор будет сделан на производительность кода DSL, и его мгновенную “встраиваемость” в запущенную программу путем компиляции DSL-кода в нативный код с помощью инструментария LLVM.
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
В докладе перед нами откроется великолепный мир велосипедов и устаревших технологий, которые люди продолжают переносить в новые проекты и повсеместно использовать. Мы поговорим о:
Copy-On-Write
разработке без оглядки на готовые решения и к чему это приводит
force inline
оптимизациях, которые отлично себя показывают на бенчмарках и плохо себя ведут в реальной жизни
бездумно отключаемых оптимизациях компилятора
тонкостях стандартной библиотеки для повседневного использования
супер качественном велосипедостроении
Доклад вводит в рассмотрение универсальный адаптер, позволяющий обернуть любой класс с целью добавления новых свойств, отсутствующих в оригинальном классе. Получаемые классы могут иметь в точности такой же интерфейс, как и первоначальные, что позволяет прозрачно заменять их и оборачивать любое количество раз.
Это позволяет добавлять необходимые свойства объектам, не переписывая его с нуля. Предложенная обобщенная концепция будет последовательно введена и проиллюстрирована простыми, но интересными примерами.
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
Одной из проблем C++ является большое количество конструкций, поведение которых не определено или просто неожиданно для программиста. С такими ошибками мы часто сталкиваемся при разработке статического анализатора кода. Но, как известно, лучше всего находить ошибки ещё на этапе компиляции. На этом докладе мы поговорим о том, какие техники из современного C++ позволяют писать не только более простой и выразительный, но и безопасный код. Вы увидите ошибки в коде различных Open Source проектов и узнаете, как можно их избежать, используя новые стандарты
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
Шаблоны — мощный инструмент, добавляющий в язык новые возможности, а программистам в команде — новые проблемы. Доклад покажет, как тщательно продуманный шаблонный код может не усложнить, а упростить жизнь и дать надёжную абстракцию межпроцессных межъязыковых асинхронных вызовов функций. С помощью шаблонов можно:
адаптировать Promise/A+ из Javascript для C++
автоматически проверять и раскладывать динамический массив аргументов на статичные аргументы функции
сделать аналог std::bind для weak_ptr.
Эти вещи будут показаны на примере взаимных вызовов между C++ и Javascript в одном приложении с помощью CEF3.
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
Зачастую, знакомство с алиасингом в C++ у многих программистов начинается и заканчивается одинаково: -fno-strict-aliasing. На вопросы новичка, более опытные коллеги отвечают в стиле: «не трогай! а то все сломаешь!». Новичок и не трогает. В докладе будет предпринята попытка заглянуть под капот и понять, что же там, внутри. Что такое алиасинг, где он может быть полезен и какие реальные преимущества дает. Тема будет рассмотрена и со стороны программиста и со стороны разработчика компилятора. А по сему, вопрос «зачем?» будет центральным в повествовании.
В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения.
В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов.
Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS
Код библиотеки будет разработан с использованием следующих принципов, приемов и методик:
S.O.L.I.D. - принципы
Unit-tests
Mock
IoC контейнеры
Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
Практика показывает, что использование подхода, основанного на колбеках для асинхронного программирования обычно не является удобным и подвержено различным ошибкам. Для упрощения написания и поддержки сложных асинхронных программ можно использовать несколько иной подход: использовать сопрограммы для переключения контекста на время ожидания события. Такой подход позволяет реализовать интересные неблокирующие примитивы, включая неблокирующее сетевое взаимодействие, неблокирующие мьютексы, а также удобное переключение между различными пулами потоков для разнесения выполнения задач, которые требуют различные ресурсы.
Со времён С++98 стандартные контейнеры и идиома RAII позволяли избегать использования оператора delete, что делало код более безопасным. С приходом С++11 и умных указателей отпала необходимость использовать оператор new, что позволило практически полностью переложить управление памятью на плечи компилятора. В докладе объясняется идеология управления памятью и ресурсами в современном С++.
Дмитрий Прокопцев, Яндекс
Речь пойдёт о, наверное, одном из самых важных и в то же время сложных нововведений в С++11 — R-ссылках (rvalue references). Мы рассмотрим базовые правила работы с такими ссылками и связанные с ними новые концепции языка: перемещение классов, универсальные ссылки и перенаправление вызовов.
В докладе рассказывается об опыте применения «инверсия управления» (Inversion of Control) при разработке новой версии KES. Этот подход заключается в том, что более высокоуровневый код не зависит напрямую от конкретной реализации нижележащего слоя. Вместо этого он зависит от абстрактного протокола (интерфейса), конкретный же компонент подставляется конфигурационным кодом-клиентом. Эта практика позволяет понизить loose coupling программных модулей и применяется практически в любых крупных проектах.
При разработке новой версии KES было принято решение изменить подход к реализации инверсии управления. Было решено отказаться от централизованного обобщенного реестра доступных компонентов (шаблон (паттерн) Service Locator) в пользу явной передачи зависимостей конфигуратором (ручная инъекция зависимостей (manual Dependency Injection)). При это возникли проблемы с использованием готовых библиотек Dependency Injection Frameworks. Применение подобных библиотек стало стандартом в мире разработки Java/C# за последние 10-15 лет, но в мире C++ они пока не получили подобного распространения. В докладе делается обзор и сравнение актуальных DI-Framework’ов на C++, анализируется их применимость к практическим задачам ЛК. Анализируется, что могут привнести стандарты C++11/14 для упрощения решения таких задач.
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
Вот уже более двух лет мы создаём онлайн-специализацию по С++ на платформе Coursera. Её цель — обучить языку C++ с нуля до уровня, достаточного для решения практических задач, с которыми приходилось сталкиваться авторам в своей практике. В своём докладе я расскажу, как мы создаём наши онлайн-курсы, и уделю особое внимание техническим проблемам, которые нам пришлось решить в процессе создания автоматической системы проверки программ студентов.
В докладе пойдёт речь о практическом применении lock-free структур и алгоритмов, которые используются в RealTime-Поиске в Яндексе. Из-за сложности теоретических исследований по lock-free и оторванности от практики часто создаётся впечатление, что это просто развлечение для знатоков computer science и не может быть использовано в реальном проекте. Будут рассмотрены проблемы традиционного подхода к lock-free и показано, как взглянув по новому на всю идею lock-free, добиться максимальной производительности, невозможной при использовании блокировок.
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
Доклад посвящён различным аспектам компилятора С++, созданного с участием автора. В выступлении рассказывается о продвинутой архитектуре компилятора, основных проектных решениях, а также обсуждаются особенности входного языка, повлиявшие на реализацию компилятора.
Опыт разработки статического анализатора кодаAndrey Karpov
Один из основателей проекта PVS-Studio расскажет об опыте разработки статического анализатора кода C++. У инструментов статического анализа кода существует "проблема айсберга". От пользователей скрыты сложные механизмы анализа кода, и иногда им кажется, что статические анализаторы – это просто какие-то утилиты, ищущие опечатки с помощью регулярных выражений. Автор доклада постарается в общих чертах описать, как всё обстоит на самом деле. Он покажет на примерах, почему нормальный анализ с помощью регулярных выражений нереализуем, что такое Data Flow анализ, а также расскажет о других технологиях, применяемых при анализе кода. Вкратце будет затронут вопрос использования нейронных сетей, обсуждение которых сейчас является очень модной темой, и рассказано, почему с точки зрения анализа кода отношение к этому направлению является очень скептическим.
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
В докладе перед нами откроется великолепный мир велосипедов и устаревших технологий, которые люди продолжают переносить в новые проекты и повсеместно использовать. Мы поговорим о:
Copy-On-Write
разработке без оглядки на готовые решения и к чему это приводит
force inline
оптимизациях, которые отлично себя показывают на бенчмарках и плохо себя ведут в реальной жизни
бездумно отключаемых оптимизациях компилятора
тонкостях стандартной библиотеки для повседневного использования
супер качественном велосипедостроении
Доклад вводит в рассмотрение универсальный адаптер, позволяющий обернуть любой класс с целью добавления новых свойств, отсутствующих в оригинальном классе. Получаемые классы могут иметь в точности такой же интерфейс, как и первоначальные, что позволяет прозрачно заменять их и оборачивать любое количество раз.
Это позволяет добавлять необходимые свойства объектам, не переписывая его с нуля. Предложенная обобщенная концепция будет последовательно введена и проиллюстрирована простыми, но интересными примерами.
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
Одной из проблем C++ является большое количество конструкций, поведение которых не определено или просто неожиданно для программиста. С такими ошибками мы часто сталкиваемся при разработке статического анализатора кода. Но, как известно, лучше всего находить ошибки ещё на этапе компиляции. На этом докладе мы поговорим о том, какие техники из современного C++ позволяют писать не только более простой и выразительный, но и безопасный код. Вы увидите ошибки в коде различных Open Source проектов и узнаете, как можно их избежать, используя новые стандарты
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
Шаблоны — мощный инструмент, добавляющий в язык новые возможности, а программистам в команде — новые проблемы. Доклад покажет, как тщательно продуманный шаблонный код может не усложнить, а упростить жизнь и дать надёжную абстракцию межпроцессных межъязыковых асинхронных вызовов функций. С помощью шаблонов можно:
адаптировать Promise/A+ из Javascript для C++
автоматически проверять и раскладывать динамический массив аргументов на статичные аргументы функции
сделать аналог std::bind для weak_ptr.
Эти вещи будут показаны на примере взаимных вызовов между C++ и Javascript в одном приложении с помощью CEF3.
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
Зачастую, знакомство с алиасингом в C++ у многих программистов начинается и заканчивается одинаково: -fno-strict-aliasing. На вопросы новичка, более опытные коллеги отвечают в стиле: «не трогай! а то все сломаешь!». Новичок и не трогает. В докладе будет предпринята попытка заглянуть под капот и понять, что же там, внутри. Что такое алиасинг, где он может быть полезен и какие реальные преимущества дает. Тема будет рассмотрена и со стороны программиста и со стороны разработчика компилятора. А по сему, вопрос «зачем?» будет центральным в повествовании.
В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения.
В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов.
Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS
Код библиотеки будет разработан с использованием следующих принципов, приемов и методик:
S.O.L.I.D. - принципы
Unit-tests
Mock
IoC контейнеры
Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
Практика показывает, что использование подхода, основанного на колбеках для асинхронного программирования обычно не является удобным и подвержено различным ошибкам. Для упрощения написания и поддержки сложных асинхронных программ можно использовать несколько иной подход: использовать сопрограммы для переключения контекста на время ожидания события. Такой подход позволяет реализовать интересные неблокирующие примитивы, включая неблокирующее сетевое взаимодействие, неблокирующие мьютексы, а также удобное переключение между различными пулами потоков для разнесения выполнения задач, которые требуют различные ресурсы.
Со времён С++98 стандартные контейнеры и идиома RAII позволяли избегать использования оператора delete, что делало код более безопасным. С приходом С++11 и умных указателей отпала необходимость использовать оператор new, что позволило практически полностью переложить управление памятью на плечи компилятора. В докладе объясняется идеология управления памятью и ресурсами в современном С++.
Дмитрий Прокопцев, Яндекс
Речь пойдёт о, наверное, одном из самых важных и в то же время сложных нововведений в С++11 — R-ссылках (rvalue references). Мы рассмотрим базовые правила работы с такими ссылками и связанные с ними новые концепции языка: перемещение классов, универсальные ссылки и перенаправление вызовов.
В докладе рассказывается об опыте применения «инверсия управления» (Inversion of Control) при разработке новой версии KES. Этот подход заключается в том, что более высокоуровневый код не зависит напрямую от конкретной реализации нижележащего слоя. Вместо этого он зависит от абстрактного протокола (интерфейса), конкретный же компонент подставляется конфигурационным кодом-клиентом. Эта практика позволяет понизить loose coupling программных модулей и применяется практически в любых крупных проектах.
При разработке новой версии KES было принято решение изменить подход к реализации инверсии управления. Было решено отказаться от централизованного обобщенного реестра доступных компонентов (шаблон (паттерн) Service Locator) в пользу явной передачи зависимостей конфигуратором (ручная инъекция зависимостей (manual Dependency Injection)). При это возникли проблемы с использованием готовых библиотек Dependency Injection Frameworks. Применение подобных библиотек стало стандартом в мире разработки Java/C# за последние 10-15 лет, но в мире C++ они пока не получили подобного распространения. В докладе делается обзор и сравнение актуальных DI-Framework’ов на C++, анализируется их применимость к практическим задачам ЛК. Анализируется, что могут привнести стандарты C++11/14 для упрощения решения таких задач.
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
Вот уже более двух лет мы создаём онлайн-специализацию по С++ на платформе Coursera. Её цель — обучить языку C++ с нуля до уровня, достаточного для решения практических задач, с которыми приходилось сталкиваться авторам в своей практике. В своём докладе я расскажу, как мы создаём наши онлайн-курсы, и уделю особое внимание техническим проблемам, которые нам пришлось решить в процессе создания автоматической системы проверки программ студентов.
В докладе пойдёт речь о практическом применении lock-free структур и алгоритмов, которые используются в RealTime-Поиске в Яндексе. Из-за сложности теоретических исследований по lock-free и оторванности от практики часто создаётся впечатление, что это просто развлечение для знатоков computer science и не может быть использовано в реальном проекте. Будут рассмотрены проблемы традиционного подхода к lock-free и показано, как взглянув по новому на всю идею lock-free, добиться максимальной производительности, невозможной при использовании блокировок.
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
Доклад посвящён различным аспектам компилятора С++, созданного с участием автора. В выступлении рассказывается о продвинутой архитектуре компилятора, основных проектных решениях, а также обсуждаются особенности входного языка, повлиявшие на реализацию компилятора.
Опыт разработки статического анализатора кодаAndrey Karpov
Один из основателей проекта PVS-Studio расскажет об опыте разработки статического анализатора кода C++. У инструментов статического анализа кода существует "проблема айсберга". От пользователей скрыты сложные механизмы анализа кода, и иногда им кажется, что статические анализаторы – это просто какие-то утилиты, ищущие опечатки с помощью регулярных выражений. Автор доклада постарается в общих чертах описать, как всё обстоит на самом деле. Он покажет на примерах, почему нормальный анализ с помощью регулярных выражений нереализуем, что такое Data Flow анализ, а также расскажет о других технологиях, применяемых при анализе кода. Вкратце будет затронут вопрос использования нейронных сетей, обсуждение которых сейчас является очень модной темой, и рассказано, почему с точки зрения анализа кода отношение к этому направлению является очень скептическим.
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
На примере некоторых архитектурных решений Крипты Дмитрий расскажет о способах реализации полиморфного поведения в программах на C++, о преимуществах и недостатках этих способов, а также о новых возможностях C++11.
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETDev2Dev
Работа с данными - это ключевая функция большинства приложений. Но работать с данными не так просто как кажется. С одной стороны, нам нужна производительность, с другой все best practices диктуют нам принцип persistence ignorance, с третьей еще и хочется писать красивый и понятный код. Как найти баланс между всем этим? Чем хороший IRepository отличается от плохого? Что такое CQRS и причем тут функциональное программирование? Об этом и пойдет речь, а так же немного граблей и личного опыта.
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
На примере некоторых архитектурных решений Крипты Дмитрий расскажет о способах реализации полиморфного поведения в программах на C++, о преимуществах и недостатках этих способов, а также о новых возможностях C++11.
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Yandex
Основываясь на опыте разработки Крипты, Дмитрий рассмотрит средства реализации статического и динамического полиморфизма в C++, а также некоторые их паттерны и антипаттерны.
* Почему Angular 2 такой быстрый и как его ускорить еще сильнее?
* Как работает Change Detection механизм и как им управлять?
* Зачем нам Zone.js и Функциональное Реактивное Программирование?
* Как работать с Redux и Mobx в Angular 2 и что можно от этого выиграть?
Об этом и ряде других вещей вы узнаете из этого доклада.
Generics were added to the Java language more than 10 year ago. But do you really understand them?
We’ll discuss:
What is heap pollution?
How does the compiler translate generics?
Why it’s not allowed to create parametrized array (List<string>[])
What are bridge methods, can we reach them?
Type erasure rules
Difference between List, List<object>, List<?>
Why it’s not allowed to add Integer to List<?>
Why it’s not allowed to parameterize exception classes?
What’s wrong with Collections.max signature: <t><?>> T max(Collection<?> coll);
Code that should be compiled, but can’t be compiled and vice versa
How to write good API using generics and wildcards
And other generic puzzlers
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
Наша команда в DevExpress недавно выпустила Preview версию нового продукта, RTF web-редактора – ASPxRichEdit.
Продукт требует высокой отзывчивости на действия пользователя и максимальной производительности. Поэтому клиент получился «толстым» в отличие от «тонких клиентов» большинства бизнес-приложений.
В составе продукта два полнофункциональных компонента - клиентский и серверный текстовые процессоры. Оба компонента работают независимо друг от друга. Клиентская часть создавалась как оптимизированная версия серверного компонента, переписанного с .NET на TypeScript.
Клиентская часть не уступает в сложности серверной. Кроме того, возникают дополнительные проблемы синхронизации состояний моделей на клиенте и сервере и глубокого тестирования клиент-серверного взаимодействия.
В этом докладе вы узнаете, как мы разрабатывали этот продукт, какие проблемы встретили и какие методики тестирования использовали.
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Ontico
РИТ++ 2017, AppsConf
Зал Касабланка, 6 июня, 16:00
Тезисы:
http://appsconf.ru/2017/abstracts/2704.html
В последнее время паттерн MVP будоражит Android-комьюнити. Уже есть несколько довольно приличных библиотек, которые помогают использовать этот подход. Но с ними вам придётся писать много boilerplate-кода. Поэтому я хочу познакомить вас с Moxy. Покажу, как использовать её компоненты для решения задач, которые будут вставать перед вами, когда вы решите использовать паттерн MVP. И расскажу, как устроены эти компоненты, и почему именно так, чтобы вы не боялись использовать Moxy из-за потенциальных подводных камней.
Разработка крупного Standalone проекта на юнити: улучшаем производительностьВадим Воробьев
Презентация к докладу на DevGamm 2015, Минск.
В докладе рассказывлось о технических тонкостях оптимизации под ПК в Unity на примере The Godlike и приводились истории разработки. Как использовать кодогенерацию, что может профайлер Unity, как правильно работать с UI и почему не стоит связываться с LINQ.
4. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
5. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
9. Требования
• Декомпозиция задач
• Отделение контекста выполнения задачи от логики
• Возможность связывать различные иерархии задач
• Декларативность в объявлении статических параметров типа задач
25. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
26. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
27. • 1999. Refactoring: Improving the Design of Existing Code
• 2000. Planning Extreme Programming
• 2002. Patterns of Enterprise Application Architecture
32. Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {
if (!isCancelled()) {
setResult(onExecute());
onDone();
return mResult;
}
return null;
}
}
33. Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {…}
protected abstract V onExecute();
}
34. Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {…}
protected abstract V onExecute();
protected void onDone() {
}
}
36. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {
CommandEntry commandEntry = null;
while ((commandEntry = getNextCommand()) != null){
onExecuteCommand(commandEntry.getCommand());
}
return null;
}
}
37. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
}
38. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){
…
}
}
39. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
}
40. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
}
41. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
public void addCommand(Command<?,?> cmd){…}
}
42. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
public void addCommand(Command<?,?> cmd){…}
public void addCommandAtFront(Command<?,?> cmd){…}
}
43. Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
public void cancel() {
synchronized (this) {
super.cancel();
if(mCurrentFuture != null) {
mCurrentFuture.cancel(true);
}
if(mCurrentCommand != null){
mCurrentCommand.cancel();
}
}
}
}
50. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
51. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
52. Ограничения
• Проблемы и задачи.
• Long running operations. Типы задач. Ограничения.
• Шаблонные операции, изменение workflow задач.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс.
• Фоновые задачи и их приоритезация.
• Особенности тестирования.
59. Планировщик задач
public abstract class CommandGroup extends Command<Void,Object> {
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){
final Future<T> future = getExecutor().execute(cmd);
final T result = getResultFromFuture(future);
return result;
}
}
63. Команда
public abstract class Command<P, V> implements Cancelable {
@Override
public int hashCode() {
int result = this.getClass().hashCode();
result = 31 * result + (mParams != null ? mParams.hashCode() : 0);
return result;
}
}
64. Команда
public abstract class Command<P, V> implements Cancelable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (mParams != null ? !mParams.equals(((Command) o).getParams()) :
((Command) o).getParams() != null)
return false;
return true;
}
}
65. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
67. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
71. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
72. Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Всем привет, меня зовут Кирилл Харьков, я занимаюсь Android разработкой в Mail.Ru,
Я бы хотел сегодня рассказать вам о том, как мы подходим к формированию и выполнению задач в наших проектах.
Разнотипных задач в любом проекте много. Это АПИ взаимодействие, изменение объектов доменной модели, подсчеты, рендеринг и т.д.
Держать это все в порядке нам нужно, причем нужно это делать не частично, а комплексно.
Сразу хочу сказать, что мой доклад никак не противоречит использованию rxJava и retrofit, и это не еще одна попытка привнести плюшки
Функциональных языков в ваш проект.
Я предлагаю чуть шире посмотреть на процесс выполнения задач и расскажу о решениях, которые помогут более гибко им управлять.
Свой доклад я предлагаю построить следующим образом:
Сначала я расскажу как все плохо. Как много задач и какие страшные проблемы поджидают нас на пути их решения
Также я немного расскажу о классификации этих задач, к чему это все применимо и рассмотрю несколько кейзов, в которых простые решения не работают.
Возьмем пример казалось бы простой задачи:
У нас есть письмо, которое необходимо показать пользователю. Из чего состоит эта задача
Что это значит?
С точки зрения написания кода выполнение должно казаться линейным и однопоточным.
Но должна быть возможность выполнять каждую отдельную команду по-своему.
В своем потоке, со своей стратегией публикации результата
Например это запросы на разные сервера, которые ходят по разному API,
соответственно имеют разную иехрархию классов,
но должны быть перемешаны из-за кривой бизнес логики.
Это в большей степени является проблемой, в тех случаях когда такая декларативность отсутствует.
Часто бывает так, что в необходимая информация о каком-то запросе\задаче скрыта в предках настолько глубоко, что когда до нее нужно докопаться, это занимает кучу времени и сильно запутывает клиента класса.
Итак, вся эта задумка изначально нацелена, конечно на long running operations,
в принципе, …
Рассмотрим типичную задачу «открытие новости» из чего она может состоять:
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Как это выглядит
Мы сначала проверяем локальный сторадж, потом идем в сеть.
Допустим у нас медленное соединение. Сеть нестабильна. Ограничение по параллельному исполнению задач достигнуты, потому что все ждут пока нам придет результат от сети.
Пользователь устал ждать и хочет выйти в список, чтобы прочитать то, что он отложил себе в заметки, пока наше приложение пыхтит и пытается получить данные из сети.
Он не может этого сделать, хотя запрос локального списка сейчас может легко выполниться, ведь в модель никто ничего не пишет и не читает оттуда. Модель свободна и доступна для чтения и записи
Это проблема, причем очень неприятная проблема и мы вернемся к ней еще, когда я буду рассказывать подробнее о контексте выполнения задач и о планировщике.
Теперь давайте рассмотрим еще такую модную и всячески пропагандируемую со стороны евангелистов android фичу, как префетчинг. Что это такое. Это предзагрузка данных. Приложение должно грузить данные заранее, чтобы для пользователя создать лучший user experience и максимально быстро показать ему информацию. Это круто. Но это дает возможность приложению начать запрашивать одни и те же данные из разных модулей приложения: из префетчинга и например из интерфейса пользователя.
Естесственно, мы не можем гарантировать в какой последовательности эти операции попадут на выполнение. Если вторая задача, например от интерфейса поступит после того как первая полностью завершилась, то у нас нет проблемы.
Если же произойдет как показано на этой схеме, то мы два раза запросим одно и то же. Зачем нам такое прекеширование, которое в два раза увеличит трафик приложения?
В идеале мы хотим получить во вторую операцию результат выполнения первой операции, так как он будет доступен раньше.
Давайте еще немного усложним задачу, и представим, что эти одинаковые операции имеют какой-то детерминированный прогресс. Соответственно задача, которая поступила позже должна не только получить результат от первой задачи, но еще и получать прогресс.
Очевидно, что это прогресс для второй задачи начнется не с нуля, а с того места, на котором сейчас находится первая задача.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Здесь важный момент это имплементация с точки зрения потокобезопасности. Мы должны безопасно получить следующую команду в многопоточном контексте выполнения, но не должны блокироваться на методе, иначе мы не сможем эту команду отменить.
Всвязи с этим нужно осторожно подойти к имплементации метода получения следующей команды.
Эта часть выходит за рамки доклада, если кому-то интересно, всю реализацию я могу показать и рассказать после сессии.
Здесь важный момент это имплементация с точки зрения потокобезопасности. Мы должны безопасно получить следующую команду в многопоточном контексте выполнения, но не должны блокироваться на методе, иначе мы не сможем эту команду отменить.
Всвязи с этим нужно осторожно подойти к имплементации метода получения следующей команды.
Эта часть выходит за рамки доклада, если кому-то интересно, всю реализацию я могу показать и рассказать после сессии.
Это точка расширения поведения и обработки результатов выполнения команды для потомков.
Мы еще вернемся к этом методу, когда будем говорить о контексте выполнения операций.
Базовая имплементация просто получает результат выполнения команды и удаляет выполненную команду. Наследники могут взять этот результат и обработать
Таким образом мы можем реализовать обертку, которая будет следить за авторизацией команд.
Пример с обновлением очень характерен, потому что мы не хотим показать пользователю закешированную информацию сначала, и идти на сервер за обновлениями, но мы не хотим ждать, эти задачи должны выполняться параллельно.
Сначала мы делали две независимые задачи. Мы пробовали по-разному обыграть этот кейз, но в итоге обманывали сами себя. Сталкивались с проблемами повторного выполнения запросов и т.д.
Тогда мы решили решать задачу так, как она сформулирована. Если от нас требуется делать что-то параллельно, то стоит попробовать делать это параллельно.
Рассмотрим христоматийное приложение, например показ новостей.
Разница с CommandGroup в том, что там мы отправляем на выполнение и ждем результат, а здесь сначала все команды отправляем на выполнение, а потом ждем пока все завершатся.
Результатом параллельных независимых задач является Map, который собирается из результатов выполнения каждой отдельной команды
Итак мы получаем этакие building blocks, с помощью которых у нас есть возможность выстроить compound операцию любой сложности.
Я затрагивал проблему декларативности того что происходит.
Причина в том, что в сложной бизнес логике невозможно выстроить структуру классов так, чтобы не пришлось идти на компромисс.
Где то мы добавляем дублирование, где-то не можем переиспользовать имеющийся код, где-то добавляем костыли.
Чаще всего речь идет о статических особенностях какого-то класса. В таком случае никогда не стоит забывать о таком мощном инструменте как аннотации
Таким образом мы можем задавать и потом использовать, например в планировщике задач информацию о том, куда этот запрос пошел, сколько выполнялся, как его правильно логировать и так далее.
К тому же при необходимости, все необходимая информация находится в объявлении класса.
С параметрами мы пошли еще дальше и повесили на них полную информацию о том, как эти параметры будут передаваться серверу.
Вспоминаем первый кейз:
У нас сетевые операции из-за медленного интернета повесили весь пул потоков.
Мы не можем выполнить выборку из модели, потому что исчерпали лимит.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Теперь возвращаемся ко второму ограничению:
Специфика android разработки такова, что архитектура приложения может и должна быть независимой друг от друга и состоять из обособленных модулей, которые могут работать вместе или по отдельности и в идеале вообще не знают о существовании друг друга.
Эта особенность значительно усложняет задачу, потому что появляются повторные запросы в одно и то же время.
Как я уже приводил пример, это может быть префетчер, который получил сигнал о том, что можно грузить новости и пользователь, который вдруг открыл именно ту новость, которую префетчер старательно подгружает для него.
В целом проблема не новая, бывалые java разработчики сразу вспомнили про Future интерфейс
Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
Рассмотрим христоматийное приложение, например показ новостей.
Рассмотрим христоматийное приложение, например показ новостей.
Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается
В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается
В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
Теперь возвращаемся ко второму ограничению:
Теперь возвращаемся ко второму ограничению:
Теперь возвращаемся ко второму ограничению:
Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается
В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается
В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.