В Русском музее, оказывается, одновременно несколько интересных выставок проходит 😳
Очень сложный выбор, хочется сходить на все и сразу 🥲
UPD: в выходные узнаете, что я в итоге выбрала👩🍳
Очень сложный выбор, хочется сходить на все и сразу 🥲
UPD: в выходные узнаете, что я в итоге выбрала
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11
Крутая новость, команда Яндекса обновила Хэндбук по Flutter 😳
В нем и так была база для подготовки к собеседованиям и обновлению знаний, так еще и добавили разделы про архитектуру, тестирование и взаимодействие с нативом😎
Мне в свое время очень помог раздел про рендеринг, наконец смогла сложить в голове концепции того, как это происходит под капотом🧑💻
В нем и так была база для подготовки к собеседованиям и обновлению знаний, так еще и добавили разделы про архитектуру, тестирование и взаимодействие с нативом
Мне в свое время очень помог раздел про рендеринг, наконец смогла сложить в голове концепции того, как это происходит под капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
education.yandex.ru
Flutter — Хендбук от Яндекс Образования
Этот хендбук позволит вам разобраться в устройстве Flutter, особенностях его компонентов, языке Dart и паттернах проектирования современных приложений
❤9👍5🔥2
Осень - мое любимое время для посещения музеев
Приобщились к прекрасному, посетив сразу две временные выставки в Русском музее🤠
Узнали о тенденциях русского искусства начала 20 века на выставке Наш Авангард, из зала в зал прослеживался творческий поиск авторов в разных направлениях, от импрессионизма до кубизма.
И конечно не могли пройти мимо выставки работ Архипа Куинджи, мастера по работе со светом. Впервые с его творчеством я познакомилась, впервые посетив Третьяковскую галерею. Помню, что зависла на несколько минут перед "Ночью на Днепре", казалось что отражение луны в ночном пейзаже светится изнутри.
В Русский музей ее конечно тоже привезли, но мне показалось странным решение выделить под нее отдельный зал с тусклым освещением и установленными прожекторами по бокам.💪
А вы находите время ходить на выставки? Если да, какая последняя вас реально зацепила?☺️
Приобщились к прекрасному, посетив сразу две временные выставки в Русском музее
Узнали о тенденциях русского искусства начала 20 века на выставке Наш Авангард, из зала в зал прослеживался творческий поиск авторов в разных направлениях, от импрессионизма до кубизма.
И конечно не могли пройти мимо выставки работ Архипа Куинджи, мастера по работе со светом. Впервые с его творчеством я познакомилась, впервые посетив Третьяковскую галерею. Помню, что зависла на несколько минут перед "Ночью на Днепре", казалось что отражение луны в ночном пейзаже светится изнутри.
В Русский музей ее конечно тоже привезли, но мне показалось странным решение выделить под нее отдельный зал с тусклым освещением и установленными прожекторами по бокам.
А вы находите время ходить на выставки? Если да, какая последняя вас реально зацепила?
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍5💅4💘2
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10💅3💘2
В последнее время плотно занималась увеличением показателя покрытия тестами, поэтому хочу поделиться своими мыслями на этот счет.
Зачем вообще писать тесты?
Провокационный вопрос, но я знаю что среди моих дорогих подписчиков есть те, кто их не пишет. 0 осуждения, 100% понимания
Для себя выделила базовые причины, по которым стоит покрывать тестами код:
Также я пришла к выводу, что для написания рабочих тестов нужна хорошая организованность структуры кода - важно задуматься, возможно ли его в дальнейшем без проблем протестировать.
А вы как относитесь к тестам? Пишете их или обходитесь ручным тестированием? Может, есть свои лайфхаки? Делитесь в комментариях
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1
Поздравляю всех с пятницей 💜
Знаю, что у кого-то и на выходных работа не заканчивается, но стоит иногда взять паузу и похвалить себя за хорошую работу🐈
Знаю, что у кого-то и на выходных работа не заканчивается, но стоит иногда взять паузу и похвалить себя за хорошую работу
Please open Telegram to view this post
VIEW IN TELEGRAM
💘6❤4💅3🔥1
В Pinterest появилась настройка видеть меньше AI слопа 😳
Сразу же все отключила, т.к частенько захожу на Pinterest в поисках вдохновения, но количество нейронных картинок угнетало🥺
Сразу же все отключила, т.к частенько захожу на Pinterest в поисках вдохновения, но количество нейронных картинок угнетало
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤3💅3👍1
Как упростить себе жизнь при тестировании
В предыдущем посте про тестирование я упомянула про хорошую структуру кода для написания тестов, хочу сегодня раскрыть эту тему😮
👩💻 Тестируемый код - это код, в котором внешние зависимости и влияния среды выполнения (например, текущее время, состояние файловой системы, ответы сети) изолированы от основной бизнес-логики и могут быть подменены при тестировании.
🤕 Антипаттерн - создание зависимостей внутри метода:
❌ Проблема в том, что такой объект не получится замокать, поэтому решением будет вынос зависимости через конструктор и регистрация в Dependency Injection.
✔️ Теперь можно замокать наш ApiClient, используя mocktail:
😠 Коварные статические методы, например DateTime.now(), SharedPreferences.getInstance().
Разберем, что с ними можно сделать, используя встроенные методы для тестирования, либо сторонние библиотеки:
❌ В этом примере зависимость на конкретный час, не позволяющая протестировать все возможные варианты.
✔️ Для решения этой проблемы существует пакет clock - это провайдер текущего времени, позволяющий зафиксировать время в тестах.
🤥 В SharedPreferences есть встроенный метод setMockInitialValues для инициализации с заданным набором значений для тестирования:
🙄 Работа с асинхронными операциями (например, Future.delayed, Timer, Stream.periodic)
Можно использовать либу FakeAsync , которая позволяет контролировать время их выполнения и сократить время на выполнение тестов.
В ней также есть интеграция с пакетом clock и при его использовании не требуется дополнительных действий, так как FakeAsync автоматически оверрайдит его на том же уровне, что и классы dart:async.
Например:
Я перечислила далеко не все способы упростить тестирование, могут также использоваться самописные обертки для классов, вспомогательные методы, собственные наборы мок данных и т.д😉
Интересно узнать, с какими проблемами вы сталкивались при тестировании. Делитесь в комментариях (кто смог дочитать до конца)🍿
В предыдущем посте про тестирование я упомянула про хорошую структуру кода для написания тестов, хочу сегодня раскрыть эту тему
class UserService {
String getUserName() {
final api = ApiClient(); // каждый раз создается новый инстанс 🥲
final user = api.fetchUser();
return user.name;
}
}class UserService {
final ApiClient api;
UserService(this.api);
String getUserName() {
final user = api.fetchUser();
return user.name;
}
}
// Это упрощенная версия теста, в обычном случае создаем мок, доступный внутри группы тестов
test('getUserName возвращает имя', () {
final mockApi = MockApiClient(); // моковый апи клиент
when(() => mockApi.fetchUser())
.thenReturn(User(name: 'user')); // пишем нужную заглушку для тестируемого метода
final service = UserService(mockApi); // прокидываем мок в конструктор
final result = service.getUserName();
expect(result, 'user');
});Разберем, что с ними можно сделать, используя встроенные методы для тестирования, либо сторонние библиотеки:
String getGreeting() {
final hour = DateTime.now().hour; // зависит от реального времени
return hour < 12 ? 'Доброе утро!' : 'Добрый день!';
}String getGreeting() {
final hour = clock.now().hour; // заменили DateTime на clock
return hour < 12 ? 'Доброе утро!' : 'Добрый день!';
}
// В тесте фиксируем время на 9 утра
test('В 9 утра возвращается верный результат', () {
final fixedClock = Clock.fixed(DateTime(2025, 1, 1, 9));
withClock(fixedClock, () {
final greeting = getGreeting();
expect(greeting, 'Доброе утро!');
});
});test('Получение значения темы из Preferences', () async {
SharedPreferences.setMockInitialValues({'theme': 'dark'});
expect(await getTheme(), 'dark');
});Можно использовать либу FakeAsync , которая позволяет контролировать время их выполнения и сократить время на выполнение тестов.
В ней также есть интеграция с пакетом clock и при его использовании не требуется дополнительных действий, так как FakeAsync автоматически оверрайдит его на том же уровне, что и классы dart:async.
Например:
Future<DataModel> loadData() async {
await Future.delayed(const Duration(minutes: 2));
return DataModel(status: 'loaded');
}
test('данные загружаются корректно', () {
fakeAsync((async) {
final future = loadData();
expect(future, completion(equals(DataModel(status: 'loaded'))));
// пропускаем 2 минуты
async.elapse(const Duration(minutes: 2));
});
});Я перечислила далеко не все способы упростить тестирование, могут также использоваться самописные обертки для классов, вспомогательные методы, собственные наборы мок данных и т.д
Интересно узнать, с какими проблемами вы сталкивались при тестировании. Делитесь в комментариях (кто смог дочитать до конца)
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥12👍6💘4❤2
Forwarded from Чтобы не выгорать
Когда тревога перед новым делом берёт верх, задайте себе вопрос: а что интересного я могу узнать в процессе?
Такой подход помогает почувствовать интерес и любопытство, а не давление от ожидания идеального результата
Такой подход помогает почувствовать интерес и любопытство, а не давление от ожидания идеального результата
❤7🔥3💘2💅1
Объединение потоков во Flutter
👀 Недавно вышло видео с интригующим названием The great thread merge, где мистер Craig рассказывает о прошлом и будущем флаттера в контексте потоков (threads).
🔜 Как было: Раньше между платформенным потоком и UI существовал разрыв, из-за чего все обращения к апи нативной платформы с использованием Platform Channels были асинхронными. Каждый вызов сопровождался сериализацией данных, переключением контекста и ожиданием ответа - даже если нативная функция возвращала результат мгновенно.
🔥 С версии 3.29 ситуация изменилась: Dart-код теперь исполняется в том же потоке, что и платформенный UI. Это означает, что вызовы нативных функций могут быть синхронными, без необходимости оборачивать их в Future. Типобезопасность теперь обеспечивается механизмом FFI (Foreign Function Interface) и инструментом ffigen, который генерирует Dart-биндинги к C-API.
⚡️ На практике это открывает новые возможности: плагины могут быть переписаны так, чтобы вызовы типа получения уровня батареи, статуса сети или доступа к датчикам возвращали значение сразу. Виджеты становятся проще - вместо StatefulWidget можно обойтись обычным StatelessWidget, если данные доступны синхронно.
🧑💻 Сейчас возможно отключить объединение потоков на Windows и macOS используя флаг:
project.set_ui_thread_policy(flutter::UIThreadPolicy::RunOnSeparateThread)
Попыталась найти аналогичный для мобильных платформ, но оказалось что он уже выпилен🥹
🧑💻 Это серьезное архитектурное изменение, которое позволит писать больше Dart кода, но не стоит забывать о производительности: тяжёлые операции должны выноситься в изоляты, иначе они заблокируют UI 🔪
project.set_ui_thread_policy(flutter::UIThreadPolicy::RunOnSeparateThread)
Попыталась найти аналогичный для мобильных платформ, но оказалось что он уже выпилен
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
The great thread merge
Dive deep into Flutter's thread merge, a fundamental shift in its engine design aimed at enhancing native interoperability. Craig breaks down the roles of the UI and Raster threads, introduces the native platform thread, and explains how integrating Dart…
1🔥11👍3💅3❤1💘1
Сегодня хочу поделиться полезным видео по асинхронному программированию в Dart 😦
Затронуты практически все основные темы, которые, к тому же, часто спрашивают на собеседовании:
🟣 Что такое async/await
🟡 Виды Future и можно ли его отменить, обработка ошибок
🔵 Принцип работы Event loop
🟢 Очень много базы про стримы (Stream), работа с StreamController и Zone
Да, видео с таким количеством информации не может быть коротким, но подача хорошая и довольно много наглядных примеров😱
Затронуты практически все основные темы, которые, к тому же, часто спрашивают на собеседовании:
Да, видео с таким количеством информации не может быть коротким, но подача хорошая и довольно много наглядных примеров
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Асинхронка — ШМР 2024
Асинхронное программирование в дарте. Future, FutureOr, Stream, async, await, yield, Zone... Как это всё работает? Копаем вглубь, ломаем стереотипы, убираем магию.
1❤7🔥5
Небольшая задача на асинхронность 👍
В каком порядке выполнятся функции? В следующем посте будет опрос с правильным вариантом ответа🧑💻
В каком порядке выполнятся функции? В следующем посте будет опрос с правильным вариантом ответа
void testEventLoop() {
print(1);
scheduleMicrotask(() => print(2));
Future(() => print(3))
.then((_) => print(4));
Future.microtask(() => print(5));
Timer.run(() => print(6));
Future.delayed(Duration.zero, () => print(7));
Future(() async {
print(8);
await Future.delayed(Duration(milliseconds: 1));
print(9);
});
Future.sync(() => print(10));
print(11);
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8💅4
Anonymous Quiz
19%
1, 10, 11, 2, 5, 3, 4, 7, 6, 8, 9
3%
1, 11, 10, 2, 3, 5, 4, 6, 8, 7, 9
46%
1, 10, 11, 2, 5, 3, 4, 6, 7, 8, 9
32%
1, 11, 2, 5, 10, 3, 4, 6, 7, 8, 9
❤6
Forwarded from MADTeacher | Станислав Чернышев
Update Dart Spec 🍿
В репозиторий спецификации языка добавили сразу несколько черновиков новых фич🔫
1️⃣ Implied Parameter/Record Field Names
Позволяет в момент вызова метода, функции или конструктора опускать имя аргументов, если у передаваемой ему на вход переменной (функции) аналогичное имя:
Пример с функциями/методами:
Пример с переменными:
2️⃣ Anonymous Methods (AM)
А вот это уже зверь из области функциональщины, который позволяет добавлять объекту анонимные методы и выстраивать цепочки из них, передавая результат одного анонимного метода в вызов другого😏
Допустим, у нас есть блок кода, который ну никак не представить в виде цепочки последовательных вызовов с помощью каскадного оператора
С добавлением одной из вариаций анонимного метода (=>) и использованием каскадного оператора его можно преобразить следующим образом:
Другая вариация подразумевает конструкции типа
или так
Если же мы хотим избежать конфликта имен или явно работать захваченным ранее объектом, который передаем в анонимный метод можно использовать конструкции типа
Как вам новые фичи Dart?
👍 – О, да, детка!!!
👌 – Сомнительно, но Окей
👎 – Отстой!
В репозиторий спецификации языка добавили сразу несколько черновиков новых фич
Позволяет в момент вызова метода, функции или конструктора опускать имя аргументов, если у передаваемой ему на вход переменной (функции) аналогичное имя:
Пример с функциями/методами:
// before
var subnoscription = stream.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
// after
var subnoscription = stream.listen(
onData,
:onError,
:onDone,
:cancelOnError,
);
Пример с переменными:
typedef Color = ({int red, int green, int blue, int alpha});
// before
Color colorWithAlpha(Color color, int newAlpha) {
var (:red, :green, :blue, alpha: _) = color;
return (red: red, green: green, blue: blue, alpha: newAlpha);
}
// after
Color colorWithAlpha(Color color, int alpha) {
var (:red, :green, :blue, alpha: _) = color;
return (:red, :green, :blue, :alpha);
}А вот это уже зверь из области функциональщины, который позволяет добавлять объекту анонимные методы и выстраивать цепочки из них, передавая результат одного анонимного метода в вызов другого
Допустим, у нас есть блок кода, который ну никак не представить в виде цепочки последовательных вызовов с помощью каскадного оператора
..void main() {
final String halfDone, result;
final sb = StringBuffer('Hello');
sb.write(',');
halfDone = sb.function toString() { [native code] }();
sb.write(' ');
sb.write('world!');
result = sb.function toString() { [native code] }();
print('Creating an important string: $halfDone then $result');
}С добавлением одной из вариаций анонимного метода (=>) и использованием каскадного оператора его можно преобразить следующим образом:
void main() {
final String halfDone, result;
final sb = StringBuffer('Hello')
..write(',')
..=> halfDone = function toString() { [native code] }() // AM
..write(' ')
..write('world!')
..=> result = function toString() { [native code] }(); // AM
print('Creating an important string: $halfDone then $result');
}Другая вариация подразумевает конструкции типа
O.{что-то делаем} или O.{что-то делаем}.{получаем результат предыдущей АМ и снова что-то делаем}.{и т.д.}. Благодаря ней мы можем переписать код так:// применяем AM к StringBuffer('Hello').
void main() => StringBuffer('Hello').{
final String halfDone, result;
write(',');
halfDone = function toString() { [native code] }();
write(' ');
write('world!');
result = function toString() { [native code] }();
print('Creating an important string: $halfDone then $result');
};или так
void main() {
// применяем AM к StringBuffer('Hello').
StringBuffer('Hello').{
write(', world!');
return function toString() { [native code] }();
}.{ // определяем следующий анонимный метод
// `this` is the string returned by
`toString()`.print(length); // Prints '13'.
return length > 10;
}.=> print('That was a ${this ? 'very' : '') long string!');
}Если же мы хотим избежать конфликта имен или явно работать захваченным ранее объектом, который передаем в анонимный метод можно использовать конструкции типа
O.(имя и тип арг1, [арг 2, арг3, ...]){что-то делаем} и выстраивать с ними цепочки различной длины:class A {
void bar() {}
void foo() {
StringBuffer('Hello').(sb) { // sb -> StringBuffer('Hello')
sb.write(', world!');
this.bar(); // `this` refers to the current instance of `A`.
return sb.function toString() { [native code] }();
}.(s) { // снова АМ
print(s.length);
bar(); // An implicit `this` also refers to the current `A`.
return s.length > 10;
}.(cond) => print('That was a ${cond ? 'very' : '') long string!'); // АМ
}
}Как вам новые фичи Dart?
👍 – О, да, детка!!!
👌 – Сомнительно, но Окей
👎 – Отстой!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2👎1
Октябрь 2025: первые посты, впечатления от посещения конференции, тесты, асинхронка
Нас уже 85🥳
Планирую продолжать делиться новостями, полезными материалами и темами, которые считаю важными в разработке🧑💻
Очень радуюсь вашему интересу к контенту и активности под постами, кого-то даже получилось вдохновить на написание тестов❤️
А вот посты за прошедший месяц:
🟣 Вводный пост
рефлексия по созданию этого канала, возможно в будущем дополню
🟣 Впечатления от конференции Стачка 2025 впервые посетила такую большую конфу, перечислила новые и интересные для меня темы
🟣 Долгожданное обновления хэндбука по Flutter
добавили много новых тем, советую ознакомиться
🟣 Сходила на выставки в Русском музее
мои впечатления о выставках искусства начала 20 века
🟣 Когда стоит покрывать тестами код
размышления о тестировании, подчеркнула важность написания тестируемого кода
🟣 Как упростить себе жизнь при тестировании
практические советы по неочевидным моментам, примеры использования пакетов для стабильных тестов
🟣 Архитектурные изменения во Flutter - The great thread merge
важная новость о будущем Flutter, новый способ взаимодействия с платформой
🟣 Видео с базой по асинхронному программированию в Dart
поделилась полезным видео с базой по асинхронке
🟣 Задача на асинхронность
проверили знание порядка выполнения операций
Нас уже 85
Планирую продолжать делиться новостями, полезными материалами и темами, которые считаю важными в разработке
Очень радуюсь вашему интересу к контенту и активности под постами, кого-то даже получилось вдохновить на написание тестов
А вот посты за прошедший месяц:
рефлексия по созданию этого канала, возможно в будущем дополню
добавили много новых тем, советую ознакомиться
мои впечатления о выставках искусства начала 20 века
размышления о тестировании, подчеркнула важность написания тестируемого кода
практические советы по неочевидным моментам, примеры использования пакетов для стабильных тестов
важная новость о будущем Flutter, новый способ взаимодействия с платформой
поделилась полезным видео с базой по асинхронке
проверили знание порядка выполнения операций
Please open Telegram to view this post
VIEW IN TELEGRAM
10❤7🔥5💅2
Уровень моей удачи - слечь с температурой на выходные и праздники 🤧
Восприняла это как сигнал о необходимости передохнуть, скоро вернусь с новыми силами и постами😶
Восприняла это как сигнал о необходимости передохнуть, скоро вернусь с новыми силами и постами
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤15👎2