Как писать юнит-тесты на многопоточный код
Следующий месяц будет преимущественно про Advanced Swift Concurrency + Swift 6:
🔘 Порешаем самые интересные задачи
🔘 изучим не только плюсы, но и глубже познакомимся с проблемами
🔘 сразу перейдем к практике и задачам
🔘 и многое другое
Начнем со статьи с интересной темой — написание юнит тестов с многопточным кодом. Почему это важно:
- меня пару раз просили на собесах писать тест именно на многопоточный код. И не всегда оптимальное решение приходит сразу в голову
- не все пишут такие тесты в реальных проектах из-за страха флаки тестов, хотя писать их супер важно.
Следующий месяц будет преимущественно про Advanced Swift Concurrency + Swift 6:
Начнем со статьи с интересной темой — написание юнит тестов с многопточным кодом. Почему это важно:
- меня пару раз просили на собесах писать тест именно на многопоточный код. И не всегда оптимальное решение приходит сразу в голову
- не все пишут такие тесты в реальных проектах из-за страха флаки тестов, хотя писать их супер важно.
Please open Telegram to view this post
VIEW IN TELEGRAM
DEV Community
Deterministic Unit Tests in Swift Concurrency
Introduction Testing code that leverages Swift Concurrency can be challenging, especially...
Forwarded from Московский кэш
📥 RuStore может появиться на iPhone
В тестовой версии нашли функцию RuStore Bridge, которая позволит устанавливать приложения из RuStore на iPhone через подключение к Android-смартфону по USB.
В тестовой версии нашли функцию RuStore Bridge, которая позволит устанавливать приложения из RuStore на iPhone через подключение к Android-смартфону по USB.
На каком стэке преимущественно (>60% кода за последний месяц) вы пишите текущий проект?
Anonymous Poll
31%
UIKit + GCD
25%
UIKit + Swift Councurrency
33%
SwiftUI + Swift Councurrency
6%
SwiftUI + GCD
14%
SwiftUI + Combine
6%
Кроссплатформа
7%
BDUI
8%
UIKit + Combine
8%
Другое
A deep dive into Collections, Sequences, and Iterators in Swift
Походу Donny Wals читает наш канал, хоть и с опозданием. Ведь еще в феврале была серия постов как мы писали свою потокобезопасную коллекцию тут, тут и тут
Донни считает что знать это полезно потому что:
- Понимание Sequence и Collection помогает писать структуры или расширять существующие с правильной семантикой
- Знание как работет под капотом for in помогает предвидеть проблемы с производительностью или безопасностью
Когда я работал в Авито Финтехе, то это помогло мне в задаче из практики: тогда мне нужно было сделать историю операций. Ну как в банках где показано куда и когда вы что-то получали и оплачивали.
Нужно было пагинировано загружать блоки. Обычный массив мне показалось скучно. Да и планов на этот экран было много: обновлять через вебсокеты и делать это интерактивно. Выгружать данные из CSV. Добавлять сложные запросы. Подписки, баланс, статусы перевод. Короче, хз че как там сейчас. Но экран был потенциально амбициозный (а как еще эффективно продать разработку разрабам).
Я решил запроектировать и написать свою коллекцию TransactionsHistory, а для универсальных транзакций заюзать какой-нибудь WalletActivityStream (AsyncSequence).
Почему не подходил обычный массив?
- Ну, массиву нужно знать заранее сколько памяти хранить. Это не всегда эффективно по памяти.
- Копируется при мутации (CoW). Мутации требуют перераспределения данных
- Большие массивы === большой риск Out Of Memory
- Нет асинхронной семантики
- Нет ленивой выборки
Если у пользователя 20 000 транзакций — в память загружается весь буфер. Если пришла новая операция, то массив нужно пересоздавать или вставлять, а это потенциально капец как дорого. Статус платежа изменился? Снова изменение коллекции. Ну и вот такие детали помогают лучше понимать когда нужна коллекция, а когда стрим.
Так сделал ли я в итоге крутую коллекцию? Отложил после MVP😂
Походу Donny Wals читает наш канал, хоть и с опозданием. Ведь еще в феврале была серия постов как мы писали свою потокобезопасную коллекцию тут, тут и тут
Донни считает что знать это полезно потому что:
- Понимание Sequence и Collection помогает писать структуры или расширять существующие с правильной семантикой
- Знание как работет под капотом for in помогает предвидеть проблемы с производительностью или безопасностью
Когда я работал в Авито Финтехе, то это помогло мне в задаче из практики: тогда мне нужно было сделать историю операций. Ну как в банках где показано куда и когда вы что-то получали и оплачивали.
Нужно было пагинировано загружать блоки. Обычный массив мне показалось скучно. Да и планов на этот экран было много: обновлять через вебсокеты и делать это интерактивно. Выгружать данные из CSV. Добавлять сложные запросы. Подписки, баланс, статусы перевод. Короче, хз че как там сейчас. Но экран был потенциально амбициозный (а как еще эффективно продать разработку разрабам).
Я решил запроектировать и написать свою коллекцию TransactionsHistory, а для универсальных транзакций заюзать какой-нибудь WalletActivityStream (AsyncSequence).
Почему не подходил обычный массив?
- Ну, массиву нужно знать заранее сколько памяти хранить. Это не всегда эффективно по памяти.
- Копируется при мутации (CoW). Мутации требуют перераспределения данных
- Большие массивы === большой риск Out Of Memory
- Нет асинхронной семантики
- Нет ленивой выборки
Если у пользователя 20 000 транзакций — в память загружается весь буфер. Если пришла новая операция, то массив нужно пересоздавать или вставлять, а это потенциально капец как дорого. Статус платежа изменился? Снова изменение коллекции. Ну и вот такие детали помогают лучше понимать когда нужна коллекция, а когда стрим.
Так сделал ли я в итоге крутую коллекцию? Отложил после MVP
Please open Telegram to view this post
VIEW IN TELEGRAM
Donny Wals
A deep dive into Collections, Sequences, and Iterators in Swift – Donny Wals
When you write the compiler quietly sets a lot of machinery in motion. Usually writing a for loop is a pretty mundane task, it’s not that complex of a syntax to write. However, it’s always fun to dig…
Мы снова глубоко погружаемся в Swift Concurrency. На канале было много теории и практики — но этого все равно мало.
Хочется услышать опыт инженера, который прошел этот путь в проде: переписывал и лидировал проекты, сталкивался с подводными камнями и точно знает, что работает, а что нет.
В выпуске он поделился:
Этого не расскажет чатгпт!
В конце месяца сделаем тренировки по SC и порешаем реальные задачи.
Получить доступ по скидке
Please open Telegram to view this post
VIEW IN TELEGRAM
The price of mandatory code reviews
Холливара перед выходными.
Код ревью переоценено. Во многих компаниях в этот процесс вкладывают больше, чем он может дать. Иногда ошибочно считая что только детальное и дотошное ревью помогает обеспечить наивысшее качество проекта. А еще хуже когда внедряют метрику "сколько ты сделал комментариев реквестам". Так некоторые эксперты искусственно создают свою значимость и отказываются от движения вперед.
Для меня код ревью теряет ценность и становится каким-то около формально-бюрократичным процессом во многих компаниях. Я выделяю несколько причин:
- слишком большой поток реквестов и ревьюеров размывает ответственность и не дает нормально вчитываться
- сложные и большие реквесты даже если ревьюится, то уже поздно на что-то глобально влиять. Код написан. Ты не можешь развернуть разраба и приходится идти на компромиссы. Тут лучше справляется арх ревью, а не код ревью
- в крутых командах высокое доверие. Если тебе нужно выделять час времени и писать 30-40 комментов своему коллеги, то проблема сидит глубже.
- в больших компаниях и командах кодревью почти условное из-за огромного кол-ва велосипедов, BDUI, кроссплатформ и тп. У тебя не хватает экспертов кто также хорошо разбирается в том, в чем разбираешься ты
Вот и автор приводит данные: сравнение команд, где код-ревью обязательны, и тех, где их нет или они используются по желанию.
- Команды без обязательных ревью работают быстрее, но выпускают больше багов
- Команды с обязательными ревью имеют меньше багов, но могут быть медленнее
Вывод автора: обязательные ревью — не универсальное решение. Он предлагает: пусть ревью будут выборочными, качественными и быстрыми.
Кодревью нужно, но оно не должно быть только одним процессом качества. Гораздо лучше помогают:
- автотесты при разработке
- архревью перед разработкой больших задач
- аи тулкиты могут снизить рутину и уже неплохо подсвечивают критические и грубые ошибки
- парное программирование
Холливара перед выходными.
Код ревью переоценено. Во многих компаниях в этот процесс вкладывают больше, чем он может дать. Иногда ошибочно считая что только детальное и дотошное ревью помогает обеспечить наивысшее качество проекта. А еще хуже когда внедряют метрику "сколько ты сделал комментариев реквестам". Так некоторые эксперты искусственно создают свою значимость и отказываются от движения вперед.
Для меня код ревью теряет ценность и становится каким-то около формально-бюрократичным процессом во многих компаниях. Я выделяю несколько причин:
- слишком большой поток реквестов и ревьюеров размывает ответственность и не дает нормально вчитываться
- сложные и большие реквесты даже если ревьюится, то уже поздно на что-то глобально влиять. Код написан. Ты не можешь развернуть разраба и приходится идти на компромиссы. Тут лучше справляется арх ревью, а не код ревью
- в крутых командах высокое доверие. Если тебе нужно выделять час времени и писать 30-40 комментов своему коллеги, то проблема сидит глубже.
- в больших компаниях и командах кодревью почти условное из-за огромного кол-ва велосипедов, BDUI, кроссплатформ и тп. У тебя не хватает экспертов кто также хорошо разбирается в том, в чем разбираешься ты
Вот и автор приводит данные: сравнение команд, где код-ревью обязательны, и тех, где их нет или они используются по желанию.
- Команды без обязательных ревью работают быстрее, но выпускают больше багов
- Команды с обязательными ревью имеют меньше багов, но могут быть медленнее
Вывод автора: обязательные ревью — не универсальное решение. Он предлагает: пусть ревью будут выборочными, качественными и быстрыми.
Кодревью нужно, но оно не должно быть только одним процессом качества. Гораздо лучше помогают:
- автотесты при разработке
- архревью перед разработкой больших задач
- аи тулкиты могут снизить рутину и уже неплохо подсвечивают критические и грубые ошибки
- парное программирование
newsletter.manager.dev
The price of mandatory code reviews
Challenging the unwritten law of software engineering
Servant Leadership
Не все идеи agile и scrum я поддерживаю. Но некоторые очень нравятся. Например идея о сервант-лидерстве. Есть в ней что-то самурайское.
Почему-то в современном мире любая мысль "думать о других, а не о себе" высмеивается и считается куколдизмом. Мне это сложно понять и я считаю это незрелой позицией. Особенно когда многие результаты можно добиться только командной игрой, где важно доверие и поддержка.
Не все идеи agile и scrum я поддерживаю. Но некоторые очень нравятся. Например идея о сервант-лидерстве. Есть в ней что-то самурайское.
Сервант-лидерство = “служить, чтобы вести”: лидер ставит успех людей выше личных заслуг, действует с позиции скромности и не "забирает" себе победы команды. Ключевые принципы: доверие, эмпатия, сотрудничество и этичное использование влияния; лидер «ведёт из-за спины», убирая препятствия и помогая самоорганизации.
Это стиль для лидеров в команде — фокус на создании условий, в которых команда сама принимает решения и растёт.
Почему-то в современном мире любая мысль "думать о других, а не о себе" высмеивается и считается куколдизмом. Мне это сложно понять и я считаю это незрелой позицией. Особенно когда многие результаты можно добиться только командной игрой, где важно доверие и поддержка.
DivKit
Почти каждый яндексоид знает что это за зверь. Да что там яндексоид, я до яндекса слышал о нем разное... Среди каналов и разрабов, кто не работал с BDUI, есть много мифов и заблуждений.
Будто App Store может тебя заблокировать из-за этого или что BDUI развитие только в СНГ (где удаляют прилы). Но почти все фаанг компании написали и юзают по паре таких технологий. Тот же Facebook*(осуждаем и порицаем) и апки гугла почти все на BDUI.
А в СНГ это Авито, Озон, Х5, Маркет.
На тренировках по систем дизайну мы разбирали BDUI. Где я во многом опирался на общие практики.
Как это работает:
- Сервер формирует JSON (карточку/экран) — руками или через json-builder.
- Клиент получает JSON и отдаёт его див-рендереру (DivView), который строит нативную иерархию.
- Интерактивность описывается в JSON: состояния, анимации переходов, обработчики действий, переменные.
Самое важное что пишется в самой доке это рекомендации когда юзать DivKit, а когда нет. На мой взгляд это отличный чеклист для всех BDUI:
- Нужно часто менять интерфейс без публикации в сторах
- Хочется единый контракт на UI между iOS/Android/Web
Когда не нужно использовать:
- Экран редко меняется, а весь продукт — чисто нативный без SDUI-процессов
- Команда/процессы не готовы поддерживать контракты и версии между клиентом и сервером
- Когда нужны сложные анимации и красивый UI
Ставь 🖤 если нравится BDUI
и💀 если нет
Почти каждый яндексоид знает что это за зверь. Да что там яндексоид, я до яндекса слышал о нем разное... Среди каналов и разрабов, кто не работал с BDUI, есть много мифов и заблуждений.
Будто App Store может тебя заблокировать из-за этого или что BDUI развитие только в СНГ (где удаляют прилы). Но почти все фаанг компании написали и юзают по паре таких технологий. Тот же Facebook*(осуждаем и порицаем) и апки гугла почти все на BDUI.
А в СНГ это Авито, Озон, Х5, Маркет.
DivKit — это фреймворка для BDUI. Это позволяет менять экран без релиза приложения и переиспользовать код и настройки UI между платформами. Под капотом — общий JSON, набор рендереров для клиентов и утилиты для генерации/сборки JSON на сервере.
На тренировках по систем дизайну мы разбирали BDUI. Где я во многом опирался на общие практики.
Как это работает:
- Сервер формирует JSON (карточку/экран) — руками или через json-builder.
- Клиент получает JSON и отдаёт его див-рендереру (DivView), который строит нативную иерархию.
- Интерактивность описывается в JSON: состояния, анимации переходов, обработчики действий, переменные.
Самое важное что пишется в самой доке это рекомендации когда юзать DivKit, а когда нет. На мой взгляд это отличный чеклист для всех BDUI:
- Нужно часто менять интерфейс без публикации в сторах
- Хочется единый контракт на UI между iOS/Android/Web
Когда не нужно использовать:
- Экран редко меняется, а весь продукт — чисто нативный без SDUI-процессов
- Команда/процессы не готовы поддерживать контракты и версии между клиентом и сервером
- Когда нужны сложные анимации и красивый UI
Ставь 🖤 если нравится BDUI
и
Please open Telegram to view this post
VIEW IN TELEGRAM
DivKit
DivKit — Кроссплатформенный фреймворк для Server-driven UI с открытым кодом
TaskLocal в Swift
В нашем воркшопе по Swift Concurrency + Swift 6 Савва немного прошелся по TaskLocal. Подметив, что это интересная, но редкая механика языка. Я даже пошел копаться в последних проектах и не нашел ни одного использования.
Представь, что у тебя куча асинхронных задач. Каждой нужен свой контекст — ID запроса, логгер, настройки. Как решать эту задачу?
Пробрасывать через параметры? Замусорено при большом кол-ве.
Глобальная переменная? Гонка данных. TaskLocal — элегантное решение.
Данные доступны везде внутри этой задачи и ее детей, но не видны другим задачам.
Ситуация: Пользователь делает запрос к серверу. Ты хочешь логировать всё, что происходит с этим запросом — куда ходили, что упало, сколько времени заняло.
🧬 Без TaskLocal: контекст либо глобальный, либо прокидываешь через 100500 параметров.
💎 С TaskLocal: каждая задача живет в своем контексте с данными, которые видны всем внутри, но изолированы от других задач.
Это как номер заказа в ресторане — официант не таскает бумажку с номером, но всегда знает, какой заказ обслуживает. Другие официанты со своими заказами ему не мешают.
В нашем воркшопе по Swift Concurrency + Swift 6 Савва немного прошелся по TaskLocal. Подметив, что это интересная, но редкая механика языка. Я даже пошел копаться в последних проектах и не нашел ни одного использования.
Представь, что у тебя куча асинхронных задач. Каждой нужен свой контекст — ID запроса, логгер, настройки. Как решать эту задачу?
Пробрасывать через параметры? Замусорено при большом кол-ве.
Глобальная переменная? Гонка данных. TaskLocal — элегантное решение.
Данные доступны везде внутри этой задачи и ее детей, но не видны другим задачам.
Ситуация: Пользователь делает запрос к серверу. Ты хочешь логировать всё, что происходит с этим запросом — куда ходили, что упало, сколько времени заняло.
Это как номер заказа в ресторане — официант не таскает бумажку с номером, но всегда знает, какой заказ обслуживает. Другие официанты со своими заказами ему не мешают.
Please open Telegram to view this post
VIEW IN TELEGRAM
Референсы про продуктовое мышление vs. проектное мышление
Я давно работаю в продуктовых командах и большую часть пути прошел именно в продуктовых компаниях. Навык искать бизнес-ценность у меня формировался ещё в Авито, там это отдельный пункт в матрице компетенций, и без него расти действительно сложно. Если нет ориентации на оуткамы, то и движение вперед ощущается иначе.
Ещё раньше одним из главных источников идей для меня был канал @product_developer. Так вышло, что Никита, автор канала, позже стал моим лидом — и у него есть много сильных материалов на тему продуктового подхода. Некоторые из его постов я часто пересылаю и сам регулярно пишу на темы вроде:
- продуктовое мышление в разработке,
- бизнес-заинтересованность инженера,
- как стать сильным инженером.
Сейчас вижу, как этот подход постепенно становится массовым. Порой даже появляется забавный "race condition": кто же первым в 2025 начал говорить об инженерной продуктовой заинтересованности? (но ведь об этом мы в канале говорим с 2022)
Иногда, когда я поднимаю эти темы (а пишу о них уже несколько лет), другие каналы ошибочно думают, что я ссылаюсь именно на них. Но здесь важно помнить простую вещь: прежде чем считать какую-то мысль своей уникальной, стоит проверить недавние публикации коллег. И может быть окажется что ты сам окажешься лишь поверхностной копией и кратким пересказом, который не понимает масштабов и глубин тем своих коллег.
Такое бывает, когда изучаешь тему поверхностно, кажется, что идея пришла сама собой. И легко не заметить, что у нее уже есть источник, где эта мысль была разобрана глубже и качественнее. Недостаточная глубина погружения иногда искажает ощущение "первооткрывательства". Создает пьянящую иллюзию, что твой микро-твит стал главным вдохновителем среди тонны контента, качеством в разы лучше твоего.
Кстати, всякие LLMки круто помогают сделать погружения глубже.
Я давно работаю в продуктовых командах и большую часть пути прошел именно в продуктовых компаниях. Навык искать бизнес-ценность у меня формировался ещё в Авито, там это отдельный пункт в матрице компетенций, и без него расти действительно сложно. Если нет ориентации на оуткамы, то и движение вперед ощущается иначе.
Ещё раньше одним из главных источников идей для меня был канал @product_developer. Так вышло, что Никита, автор канала, позже стал моим лидом — и у него есть много сильных материалов на тему продуктового подхода. Некоторые из его постов я часто пересылаю и сам регулярно пишу на темы вроде:
- продуктовое мышление в разработке,
- бизнес-заинтересованность инженера,
- как стать сильным инженером.
Сейчас вижу, как этот подход постепенно становится массовым. Порой даже появляется забавный "race condition": кто же первым в 2025 начал говорить об инженерной продуктовой заинтересованности? (но ведь об этом мы в канале говорим с 2022)
Иногда, когда я поднимаю эти темы (а пишу о них уже несколько лет), другие каналы ошибочно думают, что я ссылаюсь именно на них. Но здесь важно помнить простую вещь: прежде чем считать какую-то мысль своей уникальной, стоит проверить недавние публикации коллег. И может быть окажется что ты сам окажешься лишь поверхностной копией и кратким пересказом, который не понимает масштабов и глубин тем своих коллег.
Такое бывает, когда изучаешь тему поверхностно, кажется, что идея пришла сама собой. И легко не заметить, что у нее уже есть источник, где эта мысль была разобрана глубже и качественнее. Недостаточная глубина погружения иногда искажает ощущение "первооткрывательства". Создает пьянящую иллюзию, что твой микро-твит стал главным вдохновителем среди тонны контента, качеством в разы лучше твоего.
Кстати, всякие LLMки круто помогают сделать погружения глубже.
Telegram
iOS Makes Me Hate
Продукт vs проект, и в чем разница для разработчика.
Представим проект по постройке дома на заказ. Есть чертежи, есть план работ, сроки. Всё посчитано, всё оптимально. Берешь ресурсы, делаешь по плану, в срок сдаешь дом. Звучит просто.
На деле все проекты…
Представим проект по постройке дома на заказ. Есть чертежи, есть план работ, сроки. Всё посчитано, всё оптимально. Берешь ресурсы, делаешь по плану, в срок сдаешь дом. Звучит просто.
На деле все проекты…
Недавно в опросе выяснилось, что почти 58% из 678 участников уже используют Swift Concurrency в реальных проектах. Это впечатляет. Но при этом практических материалов почти нет — в основном лишь пересказы документации или обзоры базовых концепций.
Отдельный феномен — реакция некоторых авторов. Достаточно в большом материале случайно повторить пару слов из их микротвитов и репостов чужих материалов, и уже можно получить обвинение в "копировании". Или в непрофессиональной этике, когда ты опубликовал похожую чужую статью "слишком рано", ведь эту статью они опубликовали первыми. Правила этой игры я не понимаю, когда ты бежишь не за репостами, а за шарингом знаний. Особенно если статья чужая. Но когда вы приходили в лс и говорили что копируюте идею с бусти и приложением я молчал
Забавно наблюдать претензии на оригинальность от каналов, которые сами просто пересказывают статьи. Если сомневаетесь, оцените уникальность любого любимого канала через чатгпт — иллюзии быстро рассеиваются. Я так регулярно делаю и для себя.
Но я не хочу превращать свой канал в ежедневный агрегатор чужих постов. Мне важнее другое — окружать себя людьми сильнее меня, брать опыт у реальных практиков и двигать индустрию, которая на фоне AI стремительно меняется. Мне нужны оффлайн тренировки, а не наблюдения как тренируются другие. Интервью, советы, разборы, консультации, созвоны — все это дает живой опыт и держит меня в тонусе. В такой среде работают правила спортивной конкуренции: высокий темп, постоянное развитие. Изоляция же ведет к застою и фантазиям, оторванным от реальности.
В ежедневной работе у меня хватает задач: оптимизация рендеринга, продумывание многопоточности для тяжёлых вычислений, работа с адаптацией под разные скорости сети. Проект позволяет почти не цепляться за легаси и использовать Swift Concurrency по полной.
Вот Миша Рубанов подсветил, что нужно обязательно отменять загрузку контента если ты решил его скрыть в ленте, это очень важная база о которой часто забывают думая отмена происходит автоматом. Но та же загрузка видосов может быть очень тяжеловесной операцией и в разных странах бывает разная скорость интернета.
В этой подборке я начал с классических задач:
Кстати, я все чаще думаю выделять пару часов в неделю на создание видеороликов с разбором практики и лайфкодинга. Ставь
А в закрытой базе мы собираем самые практические задачи
Please open Telegram to view this post
VIEW IN TELEGRAM
2 16 4 1
Ко мне недавно пришли и спросили: "Каких людей любят читать иосеры? Тимлид или обычный работяга? Новичок или CEO?".
У меня есть свои ожидания, но давайте опросим вас
У меня есть свои ожидания, но давайте опросим вас
Anonymous Poll
10%
Новичок, который только начинает свой вкат
25%
Мидл. Пока не сеньор, но уже перешел рубеж
53%
Сеньор. Проработал в бигтехах и имеет большой опыт
50%
Ведущий программист. Уже про сложные архитектуры и далек от верстки и кнопок. Почти не работает с UI
19%
Тимлид. Почти не пишет код, но уже знает психологию работяг и их управление
9%
CTO. Давно не занимается работой и мало понимает в деталях технички, но с базой мобильщика
10%
Другое
Forwarded from YDC — Pizza Powered iOS (Kirill Smirnov)
Мы уже поднимали тему важности метричности.
Сегодня — системно разберём технические метрики качества и производительности мобильного приложения, которые собираются в рантайме на реальных пользователях.
(только технические, без продуктовых и без CI — они будут в отдельных постах)
#Metrics
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM