Дается математическое обоснование S.O.L.I.D принципов с помощью логики Хоара, из которого следует, что S.O.L.I.D верны не только для ООП, но и для статического полиморфизма, но и для императивного программирования вообще.
Обработка коллекций наизнанку: как применить много функций к одному аргументу...corehard_by
Современный язык C++ подвергается всё большему влиянию понятий и методов, заимствованных из парадигмы функционального программирования. В этом докладе представлен пример типично функционального решения, пригодного для довольно широкого круга практических задач. В противоположность привычной обработки коллекций (функции fmap, std::transform), где набор значений пропускается через единственную функцию, можно делать наоборот - подать одно значение на коллекцию функций. Есть несколько способов едалать это, один из них подробно описан здесь. Доклад охватывает как математические свойства, так и реализацию на языке C++, выполненную с использованием вариадических шаблонах и метапрограммирования.
Рассмотрены известные автору подходы к реализации как lock-free, так и fine-grained lock-based set/map: хеш-таблицы, деревья. Что из подходов STL может быть реализовано в lock-free манере, а что принципиально нет. Подводные камни lock-free и их нейтрализация.
Дается математическое обоснование S.O.L.I.D принципов с помощью логики Хоара, из которого следует, что S.O.L.I.D верны не только для ООП, но и для статического полиморфизма, но и для императивного программирования вообще.
Обработка коллекций наизнанку: как применить много функций к одному аргументу...corehard_by
Современный язык C++ подвергается всё большему влиянию понятий и методов, заимствованных из парадигмы функционального программирования. В этом докладе представлен пример типично функционального решения, пригодного для довольно широкого круга практических задач. В противоположность привычной обработки коллекций (функции fmap, std::transform), где набор значений пропускается через единственную функцию, можно делать наоборот - подать одно значение на коллекцию функций. Есть несколько способов едалать это, один из них подробно описан здесь. Доклад охватывает как математические свойства, так и реализацию на языке C++, выполненную с использованием вариадических шаблонах и метапрограммирования.
Рассмотрены известные автору подходы к реализации как lock-free, так и fine-grained lock-based set/map: хеш-таблицы, деревья. Что из подходов STL может быть реализовано в lock-free манере, а что принципиально нет. Подводные камни lock-free и их нейтрализация.
ЛЕКЦИЯ 4. Шаблоны многопоточного программирования
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
ЛЕКЦИЯ 1. Актуальность параллельных вычислений. Анализ параллельных алгоритмов. Многоядерные вычислительные систем с общей памятью
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
- Более детальный анализ алгоритма вычисления чисел Фибоначчи
- Определения O(⋅), преимущества и недостатки их использования для оценки времени работы алгоритмов
- Определения Ω(⋅),Θ(⋅),o(⋅), общие правила сравнения скорости роста стандартных функций
- Графики нескольких часто используемых функций
- Скорости часто используемых функций на практике, заключение
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
http://techtalks.nsu.ru
Видеозапись: http://www.youtube.com/watch?v=v7uBLSm6ft8
06 октября 2015. Как приручить дракона: введение в LLVM (Дмитрий Кашицын, HDsoft)
«В этом докладе мы кратко расскажем о таком звере, о котором много кто слышал, но немногие щупали. Что такое компилятор на самом деле? Чем LLVM отличается от других компиляторов? Как в LLVM происходит компиляция программы, как работают оптимизации? Наконец, какой путь проходит программа от разбора исходного текста до генерации исполняемого файла?
Лекция будет обзорной и не потребует от слушателей глубоких знаний теории компиляторов.»
Лекция прочитана в рамках проекта Tech Talks @NSU – серии открытых лекций о разработке ПО и карьере в IT, проводимых в Новосибирском государственном университете.
Подробности: http://techtalks.nsu.ru
Слайды доклада с конференции dotnetconf в апреле 2014 в Челябинске.
Серверная разработка в .NET исторически ассоциируется с Enterprise архитектурами и монолитным кодом, который сложно и дорого поддерживать. Мы поговорим о принципах построения micro-services архитектур, когда достаточно сложная система складывается из небольших приложений в 200-300 строчек кода. Этот подход достаточно часто встречается в Linux среде, но некоторые моменты довольно успешно переносятся и в сторону .NET
ЛЕКЦИЯ 4. Шаблоны многопоточного программирования
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...corehard_by
Обобщенное программирование - это подход к программированию, когда алгоритм пишется без указания конкретных типов данных. Используя данный подход можно значительно увеличить количество повторно используемого кода. В C++ данный подход реализуется за счет механизма шаблонов. В данном докладе рассмотрим некоторые возможности по обобщенному программированию, которые предоставляет C++. На конкретных примерах рассмотрим, как они могут упростить нам жизнь и с какими трудностями приходится сталкиваться при их использовании.
ЛЕКЦИЯ 1. Актуальность параллельных вычислений. Анализ параллельных алгоритмов. Многоядерные вычислительные систем с общей памятью
Курс "Параллельные вычислительные технологии" (ПВТ), весна 2015
Сибирский государственный университет телекоммуникаций и информатики
Пазников Алексей Александрович
к.т.н., доцент кафедры вычислительных систем СибГУТИ
http://cpct.sibsutis.ru/~apaznikov
- Более детальный анализ алгоритма вычисления чисел Фибоначчи
- Определения O(⋅), преимущества и недостатки их использования для оценки времени работы алгоритмов
- Определения Ω(⋅),Θ(⋅),o(⋅), общие правила сравнения скорости роста стандартных функций
- Графики нескольких часто используемых функций
- Скорости часто используемых функций на практике, заключение
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
http://techtalks.nsu.ru
Видеозапись: http://www.youtube.com/watch?v=v7uBLSm6ft8
06 октября 2015. Как приручить дракона: введение в LLVM (Дмитрий Кашицын, HDsoft)
«В этом докладе мы кратко расскажем о таком звере, о котором много кто слышал, но немногие щупали. Что такое компилятор на самом деле? Чем LLVM отличается от других компиляторов? Как в LLVM происходит компиляция программы, как работают оптимизации? Наконец, какой путь проходит программа от разбора исходного текста до генерации исполняемого файла?
Лекция будет обзорной и не потребует от слушателей глубоких знаний теории компиляторов.»
Лекция прочитана в рамках проекта Tech Talks @NSU – серии открытых лекций о разработке ПО и карьере в IT, проводимых в Новосибирском государственном университете.
Подробности: http://techtalks.nsu.ru
Слайды доклада с конференции dotnetconf в апреле 2014 в Челябинске.
Серверная разработка в .NET исторически ассоциируется с Enterprise архитектурами и монолитным кодом, который сложно и дорого поддерживать. Мы поговорим о принципах построения micro-services архитектур, когда достаточно сложная система складывается из небольших приложений в 200-300 строчек кода. Этот подход достаточно часто встречается в Linux среде, но некоторые моменты довольно успешно переносятся и в сторону .NET
В докладе описываются основные проблемы, которые возникают при разработке проектов, и демонстрируется, что эти проблемы можно предсказать и решать с помощью математической теории, лежащей в основе языков программирования.
Большие данные: как могут навредить и ка могут помочь?etyumentcev
Большие данные — модная и быстро распространяющаяся концепция, которая позволяет нам извлекать разные полезные факты из окружающей нас информации. На конкретных примерах покажу как можно большие данные использовать, а также к каким проблемам может привести неверная интерпретация полученных результатов.
разработка серверов и серверных приложений лекция №4etyumentcev
В данной лекции рассмотрена минимальная реализация акторной модели, включающая
- отправку сообщений,
- создание новых акторов и смену поведения для приема следующего сообщения.
Исходный код реализации выложен на https://github.com/hwdtech/HWdTech.DS. Код на C#.
При разработке использовались библиотеки: Autofac, NuUnit, Moq
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016etyumentcev
В докладе описан опыт построения нагруженной отказоустойчивой системы, использующей jsonb для хранения данных. В частности рассказываются механизмы, которые заменили join, транзакции, в том числе распределенные, репликации обычных SQL баз данных.
The AWS cloud infrastructure has been architected to be one of the most flexible and secure cloud computing environments available today. Security for AWS is about three related elements: visibility, auditability, and control. You have to know what you have and where it is before you can assess the environment against best practices, internal standards, and compliance standards. Controls enable you to place precise, well-understood limits on the access to your information. Did you know, for example, that you can define a rule that says that “Tom is the only person who can access this data object that I store with Amazon, and he can only do so from his corporate desktop on the corporate network, from Monday-Friday 9-5 and when he uses MFA?”. That’s the level of granularity you can choose to implement if you wish. In this session, we’ll cover these topics to provide a practical understanding of the security programs, procedures, and best practices you can use to enhance your current security posture.
Speakers:
Rob Whitmore, AWS Solutions Architect
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETDev2Dev
Работа с данными - это ключевая функция большинства приложений. Но работать с данными не так просто как кажется. С одной стороны, нам нужна производительность, с другой все best practices диктуют нам принцип persistence ignorance, с третьей еще и хочется писать красивый и понятный код. Как найти баланс между всем этим? Чем хороший IRepository отличается от плохого? Что такое CQRS и причем тут функциональное программирование? Об этом и пойдет речь, а так же немного граблей и личного опыта.
В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения.
В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов.
Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS
Код библиотеки будет разработан с использованием следующих принципов, приемов и методик:
S.O.L.I.D. - принципы
Unit-tests
Mock
IoC контейнеры
Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.
разработка серверов и серверных приложений лекция №3etyumentcev
В третьей главе рассматриваются базовые свойства акторов, описанные в PhD диссертации Gul Agha: каждый актор имеет адрес, большой почтовый ящик, куда доставляются сообщения, адресованные актору и поведение. В ответ на входящее сообщение актор может отправить конечный набор сообщений другим акторам и/или создать конечное число новых акторов и/или поменять свое поведение для обработки следующего сообщения.
В рамках данного курса будет разработана библиотека для разработки параллельных приложений на платформе .NET, построенная по модели акторов.
Исходные коды библиотеки будут выкладываться на GitHub: https://github.com/hwdtech/HWdTech.DS
Код библиотеки будет разработан с использованием следующих принципов, приемов и методик:
S.O.L.I.D. - принципы
Unit-tests
Mock
IoC контейнеры
Для удобства слушателей курса краткий обзор данных практик приведен в Главе 4.
Опыт разработки статического анализатора кодаAndrey Karpov
Один из основателей проекта PVS-Studio расскажет об опыте разработки статического анализатора кода C++. У инструментов статического анализа кода существует "проблема айсберга". От пользователей скрыты сложные механизмы анализа кода, и иногда им кажется, что статические анализаторы – это просто какие-то утилиты, ищущие опечатки с помощью регулярных выражений. Автор доклада постарается в общих чертах описать, как всё обстоит на самом деле. Он покажет на примерах, почему нормальный анализ с помощью регулярных выражений нереализуем, что такое Data Flow анализ, а также расскажет о других технологиях, применяемых при анализе кода. Вкратце будет затронут вопрос использования нейронных сетей, обсуждение которых сейчас является очень модной темой, и рассказано, почему с точки зрения анализа кода отношение к этому направлению является очень скептическим.
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Alexander Borzunov
Описание декоратора для автоматической оптимизации алгоритмов с помощью быстрого возведения матриц в степень в Python.
Смотрите подробнее:
GitHub: https://github.com/borzunov/cpmoptimize
Хабрахабр: http://habrahabr.ru/post/236689/
Python Package Index: https://pypi.python.org/pypi/cpmoptimize
Rambler.iOS #9: Анализируй это! (Сергей Крапивенский).
Доклад посвящён наиболее популярным статическим анализаторам кода для iOS: как ими пользоваться, какие проблемы они решают, как внедрить их в привычный цикл разработки, как писать для них свои правила. Также рассмотрен опыт интеграции статического анализа и CI.
Rambler.iOS - митапы iOS-разработчиков, организуемые компанией RAMBLER&Co.
Мы закончили рассмотрение паттернов 64-битных ошибок. Последнее на чем мы остановимся в связи с этими ошибками, является то, как они могут проявляться в программах.
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
На примере некоторых архитектурных решений Крипты Дмитрий расскажет о способах реализации полиморфного поведения в программах на C++, о преимуществах и недостатках этих способов, а также о новых возможностях C++11.
Java 8, самой заметной фичей которой стало появление лямбд, вышла два года назад, а в этом году мы даже начали её использовать в продакшен коде Идеи. Такое заметное нововведение в языке вызывает множество вопросов. Какие возможности перед нами открываются и какие проблемы при неаккуратном использовании лямбд могут возникнуть, как лямбды устроены внутри, во что они компилируются и как исполняются — вот темы, которые мы обсудим на докладе.
Статический и динамический полиморфизм в C++, Дмитрий ЛевановYandex
На примере некоторых архитектурных решений Крипты Дмитрий расскажет о способах реализации полиморфного поведения в программах на C++, о преимуществах и недостатках этих способов, а также о новых возможностях C++11.
Все говорят, что для максимальной производительности работы из Java с базой данных нужно использовать PreparedStatements и Batch DML. Практика показывает, что нельзя слепо идти на поводу у прописных истин. Нужно понимать особенности конкретной базы и характера передаваемых данных.
В докладе мы рассмотрим то, как эффективное использование протокола PostgreSQL позволяет добиться высокой производительности при выборке и сохранении данных. На примерах увидим как простые изменения в коде приложения и JDBC драйвера на порядок ускоряют запросы. Мы увидим как задействовать механизм server prepared statements из клиенсткого кода и узнаем его узкие места. Обсудим средства эффективной передачи данных в базу.
Многие обсуждаемые доработки недавно вошли в состав официального JDBC драйвера. Доклад будет полезен не только Java программистам, т.к. многие подводные грабли вытекают из самого протокола общения PostgreSQL с внешним миром.
Теории и практики фунционального программирования - GDG D2D0xffAA
Большинство разработчиков, к сожалению, считают функциональное программирование чем-то страшным и не понятным, но это совершенно не так. В своем докладе я хочу показать мощь и простоту функционального подхода, рассказать о базовых концепциях и о том, как с их помощью можно делать привычные вещи удивительным образом, а так же расскажу о новых приемах.
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
Similar to математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск, апрель 2015) (20)
разработка серверов и серверных приложений лекция №2etyumentcev
Причины потерь процессорного времени при организации последовательности вычислений внутри потока: 1. Ожидание ответа на запрос (поток спит). 2. Выполнение дополнительных "лишних" действий. Как способ устранения этих потерь - паттерн Пул потоков. Анализ императивного и функционального подхода к борьбе с "жадными" операциями. Эволюция методов организации параллельных вычислений на основе пула потоков.
высокопроизводиетльные системы без доп затратetyumentcev
Нами был разработана библиотека HWdTech.DS для разработки многопоточных и распределенных приложений на платформе .Net. Эта библиотека использует модель акторов и позволяет существенно снизить требования к квалификации программистов при построении высоконагруженных приложений.
Приводится объяснение, почему для программистов не подходят системы тайм-менеджмента. Презентация шла как сопровождение к устному выступлению, поэтому сама по себе без записи доклада, возможно, будет непонятна.
2. 2
Докладчик
Тюменцев Евгений
14 лет преподаю
ИМИТ, ФКН ОмГУ
ИТ-компании
Школа программиста
10 лет разрабатываю ПО
разработчик, архитектор,
PM, руководство до 70 человек
5. 5
The Liskov Substitution Principle
Функции, которые используют ссылки на
объекты базовых классов, должны
использовать объекты производных
классов, ничего не зная о них.
6. 6
The Dependency Inversion Principle
Высокоуровневые компоненты не должны
зависеть от низкоуровневых компонент. И
те, и те должны зависеть от абстракций
(оператора расширения).
11. 11
Выводимость
Пусть L – множество формул, B – формула.
Тогда L ⊦ B, если ∃ B1, B2, …, Bn , что
1.Bn – это B,
2.Bi – это
либо формула из L,
либо аксиома,
либо общезначимая формула,
либо формула полученная при
помощи правила вывода
14. 14
Логика Хоара
1969 г. An Axiomatic Basis for Computer
Programming
1971 г. Procedures and Parameters: An
Axiomatic Approach
1980 г. премия Тьюринга
1990 г. Медаль “Пионер компьютерной
техники”
2000 г. рыцарский титул за заслуги в
области образования и компьютерной
техники, премия Киото
Чарльз Хоар
26. 26
Как упростить операцию insert?
P = c – последний V с – непоследний
{P} insert(c, x) {Q}
Если B = {∀с с – непоследний} – инвариант
P^B→P, {P}insert(c,x){Q} ⊦ {P^B}insert(c,x){Q}
27. 27
Как упростить операцию insert?
P = c – последний V с – непоследний
{P} insert(c, x) {Q}
Если B = {∀с с – непоследний} – инвариант
P^B→P, {P}insert(c,x){Q} ⊦ {P^B}insert(c,x){Q}
Но! P^B = c- непоследний
{c - непоследний} insert(c,x) {Q}
28. 28
Закольц. список с буф. элементом
node* insert(node& c, int v) {
node *n = new node;
n -> val = v;
if(c.next) {
n -> next = c.next;
}
else {
n -> next = 0;
}
c.next = n;
return n;
}
29. 29
Закольц. список с буф. элементом
node* insert_before(node& c, int v) {
node *n = new node;
n -> val = v;
n -> next = c.next;
c.next = n;
return n;
}
34. 34
Повторное использование
Повторное использование кода — методология
проектирования компьютерных и других систем,
заключающаяся в том, что система (компьютерная
программа, программный модуль) частично либо
полностью должна составляться из частей, написанных
ранее компонентов и/или частей другой системы, и
эти компоненты должны применяться более одного
раза (если не в рамках одного проекта, то хотя бы
разных).
https://ru.wikipedia.org/wiki/Повторное_использование_кода
35. 35
А можно ли по-другому?
Выводимость прямо предписывает строить
новые тройки из предыдущих!
36. 36
Когда происходит повторное
использование?
Если нужно внести изменение в существующее
приложение, то мы пытаемся повторно
использовать свой же собственный код, чтобы
получить тоже приложение, но с новой
функциональностью.
44. 44
Что случилось?
Инвариант класса matrix: size > 0
Конструктор matrix() нарушил инвариант: size = 0
Предусловия методов изменились с size > 0 на size
≥ 0, но
45. 45
Что случилось?
Инвариант класса matrix: size > 0
Конструктор matrix() нарушил инвариант: size = 0
Предусловия методов изменились с size > 0 на size
≥ 0, но
{size ≥ 0} det {Q} не выводится из {size > 0} det {Q}
46. 46
Что случилось?
Инвариант класса matrix: size > 0
Конструктор matrix() нарушил инвариант: size = 0
Предусловия методов изменились с size > 0 на size
≥ 0, но
{size ≥ 0} det {Q} не выводится из {size > 0} det {Q}
Следовательно, надо изменять сами методы
47. 47
Конструкторы по умолчанию
Конструктор должен устанавливать
инвариант класса
Конструкторы по умолчанию часто
расширяют допустимые значения
параметров
Стоит несколько раз подумать, прежде чем
использовать конструктор по умолчанию
49. 49
Импликация на множестве
Пусть P1 → P,
B = { x | P1(x) = 1},
A = { x | P (x) = 1}.
Тогда B ⊂ A.
P ⊨ P1. Говорят, что P –
более слабое условие,
P1 – более сильное.
A
B
51. 51
Построим вывод
{S} cb {P}, {P} c {Q}, {Q} ca {R} ⊦ {S} cb; c; ca {R}
Пусть P → P1, Q1 → Q
Известно, что
{S} cb {P}, {P1} c {Q1}, {Q} ca {R}
52. 52
Построим вывод
{S} cb {P}, {P} c {Q}, {Q} ca {R} ⊦ {S} cb; c; ca {R}
Пусть P → P1, Q1 → Q
Известно, что
{S} cb {P}, {P1} c {Q1}, {Q} ca {R}
Тогда
{P} c {Q} (аксиома вывода)
{S} cb; c; ca {R}
53. 53
The Dependency Inversion Principle
Высокоуровневые компоненты не должны
зависеть от низкоуровневых компонент. И
те, и те должны зависеть от абстракций
(оператора расширения).
55. 55
Иначе
{S} cb {P}, {P} c {Q}, {Q} ca {R} ⊦ {S} cb; c; ca
{R}
Пусть P ↛ P1, но P ^ P1 → P1
Известно, что
{S} cb {P}, {P1} c {Q}, {Q} ca {R}
56. 56
Иначе
{S} cb {P}, {P} c {Q}, {Q} ca {R} ⊦ {S} cb; c; ca {R}
Пусть P ↛ P1, но P ^ P1 → P1
Известно, что
{S} cb {P}, {P1} c {Q}, {Q} ca {R}
Тогда
{P1} c {Q} ⊦ {P} if (P1) then c endif {Q}
{S} cb; if(P1) then c endif; ca {R}
59. 59
Как выглядит оператор расширения?
1. Статический полиморфизм
template <class It, class Op>
void for_each(It begin, It end, Op op)
{
for(; begin != end; ++begin)
op(*begin);
}
int arr[] = {1, 2, 3, 4, 5};
for_each(arr, arr+6, max<int>());
60. 60
Как выглядит оператор расширения?
2. Во время выполнения
указатель на функцию
void (*f) (int i);
f pf;
pf(5);
динамический полиморфизм
class Shape {
public:
virtual void Draw() = 0;
};
shape->Draw();
63. 63
The Liskov Substitution Principle
Функции, которые используют ссылки на
объекты базовых классов, должны
использовать объекты производных
классов, ничего не зная о них.
67. 67
А не для классов?
bool (*validator) (Document const & doc);
std::vector<validator> rules = …;
for (int i = 0; i < n; ++i)
if(!rules[i](document))
return false;
return true;
68. 68
В каком случае гарантированно удастся
избежать жирного интерфейса?