iOS Makes Me Hate
3.93K subscribers
1.16K photos
167 videos
15 files
1.33K links
Авторский канал про iOS разработку. Путь продуктовых самураев в MAANG.

Самое больше iOS сообщество практиков: https://boosty.to/lionbond/

Автор: @lvbond Senior iOS Yandex, ex-Avito, VK
Download Telegram
Forwarded from Банки, деньги, два офшора
Путин обязал Apple предустанавливать RuStore на все новые iPhone и планшеты в России с 1 сентября. @bankrollo
1151
Об алгоритмах на собеседовании

У меня, на первый взгляд, противоречивое мнение про алгоритмы. С одной стороны, я долго их решал и даже учавствовал в соревнованиях и шел "365 дней Богу Алгоритмов". С другой, я все также не умею проходить алгоритмические собеседования 😄

Опыт долгих тренировок определенно точно помог мне в кодинге, мышлении, какой-то базе. Но вот секции с алгосами для меня отдельный вид спорта 😂 Устно решать вслух != комфортненько молча за столом.

Но эти секции точно не стоит бояться. Мне нравится, как о них расписал наш руководитель отдела разработки Яндекс Еды Дима Александров @vit_ded

У нас во фронтендах часто не понимают зачем алгосы, а автор не редко сравнивает разные точки зрения и может найти сложные алгоритмы даже в нашей практике!
8
Действительно ли вы хорошо знаете SwiftUI?

Нашел супер крутую статью, о которой преступно умалчивают другие авторы.
В этой статье автор задает вопрос "А действительно ли вы хорошо знаете SwiftUI?".

Взяв самую популярную демо-задачу с Counter'ом он начинает подсвечивать самые частые заблуждения: начиная от использования незадокументированного _printChanges() заканчивая причинами зависаний экрана.

As you can see by adding .debugBackground() to every Text cell we can observe updating each cell whenever we click on theCounter +1 button. And as you remember we have 100_000 values🤯. That causes lagging! To be more precise — lagging is caused by the List cell creation behavior. Whenever List is created, it has to create all its inside items first because it needs to know how many items are on the screen. By clicking on the button we change the view state, and SwiftUI detects the state change and starts rebuilding the view, and because of the large number of values — this view rebuilds long.


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

Автор круто подчеркивает, что SwiftUI лишь обманчив простотой. Чтобы сделать хороший по перфомансу лайаут нужно приложить много ресурсов и изучить много вещей, которые плохо задокументированы и требуют собрать мозаику знаний. Ну и главное, чтобы это все не сломал Apple со след версией iOS 🙂

Многие советы вам известные, но дают чуть контекста на проблему. Например, тема про POD vs Non-POD чуть лучше расскрывается.

P.S. Говорят, что одна из ключевых черт зрелого инженера — умение выбирать правильные инструменты. Ну и одно из моих любимых правил: Если слишком сложно, то возможно не ты тупой, а плохой дизайн и проектирование инструмента для этих задач. Попробуй взять или придумать другой инструмент.
13
Forwarded from Воробей
Вернуть блюрную заливку
Убрать стекло
Переименоваться в iOS 19
5021
Swift Concurrency: что делает компилятор?

Я не считаю, что обучение по чужим статьям и твиторам — эффективно. Чаще это инфошум. Поэтому продолжаю структурировать и делым понятным то, что разбросано по кускам. Мы уже немного познакомились с Swift Concurrency по первоисточникам. Выяснили какие proposals почитать и какие wwdc посмотреть.

Теперь перейдем к кратким формулировкам и структурированию мозаик. Все абстракции и примерные мыслительные модели бесполезны, если мы не поймем как работает код.

Давайте по порядку. В теории, можно разделить все на такие ключевые слова:
- Компилятор ->
- State Machine ->
- suspension points ->
- Continuation ->
- Executor ->
- Co-operative thread pool

🟣Компилятор и State Machine. Каждый раз, когда компилятор видит await, то он режет функцию на структуру с полем resumePoint. Разбивает код на блоки и вставляет переходы между ними.

🟣Suspension points. Каждое await — это место приостановки. В интернете нет явной инфы, но общая формулировка такая: Функция приостанавливается и текущий стэк с переменными и позицией сохраняются в кучу. Создаётся continuation.

Swift implements asynchronous functions by transforming them into state machines. Each call to an asynchronous function and each await is a suspension point, where the function can suspend execution


🟣Continuation. Это объект, который хранит что делать дальше, после await. Он хранит в каком месте приостановилось выполнение, какие переменные были в контексте, что делать, когда результат будет готов.

“Continuations are the fundamental building block for suspending and resuming execution in Swift’s concurrency model.”


🟣Executor. Это условный планировщик, который решает, на каком потоке и когда выполнять async-код. Если continuation — это инструкция, то Executor — исполнитель. Сontinuation возобновляется и передаётся в executor, который решает где и когда продолжить выполнение.

“The continuation resumes execution via an executor, which may be the same as the original or different, depending on actor context.”


🟣Co-operative thread pool. Если Executor — это манагер задач, то Co-operative thread pool — это рабочие потоки, на которых Executor исполняет эти задачи. Это общий пул потоков, управляемый Swift Runtime. Потоки не создаются на каждую задачу, вместо этого задачи добровольно уступают выполнение, когда достигают await. Потоки переключаются на другие задачи, пока первая ждёт. Executor получает задачу, ставит ее в очередь и запускает на одном из потоков пулла.

Полезные ссылки:
- Apple Docs
- 0392-custom-actor-executors
- Swift concurrency: Behind the scenes

1/5
Please open Telegram to view this post
VIEW IN TELEGRAM
221
Swift Concurrency: Cooperative thread pool

Если затрагивать SC, то нельзя не остановиться отдельно на этой теме.

Для чего это придумали? GCD и DispatchQueue.global().async мог создавать на каждую задачу отдельный поток. Это приводит ко многим пролемам оптимизации, но главная — это thread explosion. Это когда создается слишком много потоков одновременно и врызвается жопа ОС.


for _ in 0..<10_000 {
DispatchQueue.global().async {
// что-то делает
}
}


Cooperative Thread Pool — это ключевая часть архитектуры Swift Concurrency. Если простыми словами, то это пул с потоками, которые делят CPU по договорённости. Swift Concurrency использует ограниченный пул потоков — примерно от 4 до 8, в зависимости от устройства и от кол-ва ядер в устройстве. Они уступают управление когда задача "приостанавливается" (await и Suspension points).

Swift runtime использует global concurrent executor. Этот executor основан на libdispatch (GCD), но с отдельной очередью с флагом COOPERATIVE. Это concurrent dispatch queue с названием com.apple.root.default-qos.cooperative. Даже если ты создашь тысячу Task { ... }, они не запустятся параллельно. Они будут ставиться в очередь и по очереди исполняться на тех же 8 потоках.

Чуть позже разберем пару НО и как Swift 6 помогает их избежать.

Полезные ссылки:
- How is the Cooperative Thread Pool integrated in Swift?
- Swift concurrency: Behind the scenes
- How does cooperative thread pool work?
- Limit Swift Concurrency's cooperative pool

2/5
121
94
Эстетика сырого текста в эпоху AI

Поговорим о важном культурном сдвиге. Я заметил, что в эпоху, когда ИИ умеет делать красиво, правильно и гладко это тупо перестаёт быть ценностью. Люди начинают искать неидеальность, трушность, эмоцию.

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

80% контента стало стерильным. Все утомились от «слишком правильного», которое не отличаешь от сотен других. Сырые же текста и контент стали более живыми.

Даже с играми и фильмами. Мне стали нравятся твердые четверки, кто не идеален. The Alters, expedition 33, tainted grail. Эти игры имеют уйму минусов, багов, но в них есть много плюсов, которые перевешивают. Они пахнут потом и любовью, а не пугающе белыми стенами больниц.

Я стал любить простоту. Ходить в самые обычные места. Есть самую обычную еду. Пить просто воду.

Мы стали будто жить по правилу «слишком идеально, чтобы быть настоящим».

Возможно, скоро неотредактированный текст станет новым жанром. Как raw photo в инсте или живой звук в музыке.

Люди захотят читать не идеальные тексты, а тексты с дыханием.
20
316
Систем дизайн в деле

Есть огромное минное поле заблуждений по систем дизайну. От "это про нарисовать схему из интернета" до "это про знание паттернов проектирование и архитектур". От "бэкенд систем дизайн отличается от мобильного" до "весь систем дизайн можно зазубрить".

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

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

Нашел полезное видео, которое пусть и для бэкенда, но очень крутое.
8
Туториал по Container

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

Мы уже разбирали в чем разница software developer vs software engineer. А также подробно проходили по виртуализации.

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

Когда это поможет:
- Ускоряет и упрощает CI/CD-процессы для ios‑разрабов. например, сразу fastlane, swiflint и тп с другими версиями
- изолировать версии в разных окружениях
- тестировать пуши, авторизацию, базы данных с быстрым запуском нужных сервисов.
- настраивать ручные и автотесты за счет мок-сервисов
- проще подготавливать окружение для новичков
- если баги воспроизводятся только на конкретной версии окружения, то ты можешь легко ее собрать
- запуск новых либ или сдк в "чистом" окружении

Полезно выходить за границы мобильных приложений, особенно когда это требует изменчивый рынок.
11
💎 Swift Concurrency: Task, actor, Executor

Окей, все посты выше мы говорили о работе SC в общих мазках. Сейчас подойдем к более привычным и простым снарядам. Мы ведь говорили о каких-то компилятарах, ядрах и тп. Но не дошли до самой сути. Так как мой код исполняет на доступной мне абстракции? Зачем были эти прелюдии если мы так и не затронули common сущности и прикладной уровень?

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

🎶 Task — это задача, которую нужно выполнить. Я далек от музыки, но допустим это какая-то песня.

🎤 Actor — это объект для работы с задачами. Или же музыкант отдельного инструмента, который играет песню. Например, гитарист.

🧑‍⚖️ Executor — это механизм, который управляет порядком и исполнением задач. В той же аналогии это дирижер, который управляет, кто и когда играет. В какой момент подключится вокалист, гитарист, басист и тп.

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


actor Counter {
var value = 0

func increment() {
value += 1
}
}


Тут мы опускаем всякие нюансы с Reentrancy и MainActor, но часто пишут, что swift гарантирует безопасность данных и отсутствие гонки (ага, щас).

А вот Executor — это внутренний механизм, который решает где и в каком порядке исполнять таски и акторы. Каждый actor имеет свой serial executor, то есть он выполняет задачи по очереди, одну за одной. Допустим у тебя 3 таски и каждая хочет что-то сделать внутри одного актора. Executor ставит их в очередь и выполняет по одной, даже если все они вызваны одновременно.

Вроде все понятно. Но так ли на самом деле просто и идеально? Не совсем. В след постах поговорим про Reentrancy, hops'ы и перфоманс, nonisolated и другие приколы, которые могут вам сломать исполнение

3/5
Please open Telegram to view this post
VIEW IN TELEGRAM
74
Блин, за ленивый пост извиняюсь. Набросал пост про «концентрированный опыт» и отдал его чатгпт, решил узнать че скажет. В целом получилось интересно и по содержанию почти так, как я хотел донести, но по подаче конечно супер пресно. Поделюсь ответом с вами, а нормальный пост как-нибудь позже напишу:
——————-

«Концентрированность опыта важнее количества лет и суммы в оффере»
или
«Где вырастает настоящий сеньор? В деньгах или в деле?»



💡 Ключевые идеи, которые можно раскрыть:

1. Концентрированность опыта vs Количество лет
• Пример: у двух людей по 5 лет опыта. Один — писал UI-фичи и фиксил баги, другой — запускал 3 проекта с нуля, внедрял CI/CD, строил архитектуру.
👉 Первый “набрал время”, второй — сжал опыт в концентрат.
• Формулировка: “Опыт – это не часы, проведённые в коде. Это задачи, которые требовали от тебя расти.”



2. Цена опыта и окупаемость
• Вставь понятие «опыт как инвестиция»:
• Проект без вызовов = “депозит под 2%” (низкий рост).
• Проект с болью, сложностями и ростом = “венчур” — сначала тяжело, потом x3.

Метафора: «Ты не на зарплату работаешь, а на апгрейд себя.»



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

👉 Задай вопрос читателю: «Вы когда-нибудь доживали до последствий собственных решений через 6–12 месяцев?»



4. Что такое “бесперспективный оффер”
• Деньги — не всегда сигнал “ты хорош”.
• Иногда это компенсация за рутину, токсичность, отсутствие роста, или необходимость “заткнуть дыру”.
Идея: “Не каждая высокая зарплата — это признание. Иногда — это капкан.”



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



6. Роль ментальности и амбиций
• Некоторые “работают в IT”, а другие — “строят карьеру в инженерии”.
• Покажи разницу: первые просто кодят задачи, вторые — растут стратегически.



🧩 Завершающая мысль

Можно закончить вот так:

“Концентрированность опыта — это когда ты идёшь не по количеству строк кода, а по качеству вызовов, которые ты принял. Не каждый год делает тебя сильнее. Но каждый проект может — если ты выбрал его осознанно.”
10
This media is not supported in your browser
VIEW IN TELEGRAM
Кстати, завтра будет репортаж корпоратива Яндекса из БАНИ
113
Неоспоримая база от любимого автора

Наш любимый блогер, а также автор лучшей книги 2024 года для инженеров, дал инфу о базе базовой.

1. Чем больше кода, тем больше багов. Чем больше приложение, тем сложнее делать его качественно.
2. Код - это для людей. Писать код сложнее там, где его читают. Чем больше разрабов в проекте, тем важнее его читабельность и понятность.
3. Архитектура - это про удобство. Чем сложнее, тем хуже.

Даже во времена AI эти правила не меняются
14
Каждый раз когда кто-то проходит испыталку Яндекс делает корпоратив

Кстати, я прошел испыталку. Работаем дальше
36103
Гонка за концентрированностью опыта

У одного тимлида в блоге я увидел пост в стиле
"не нанимайте звезд, берите тех, кто не хочет х2 зп и не ищет челенджи, не выступает на конфах и не придумывает новые архитектуры. Инженера, кто не хочет расти и молча делает свою работу на одном грейде без амбиций роста — сложнее найти"


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

Почему я думаю что в ит такой путь развития не выгоден? Давайте по пунктам:
1. Знания быстро устаревают, и ценность на рынке падает. Вот я пишу про SUI и Async/Await сейчас не просто так, а потому что людей, кто решает задачи на собесах с помощью GCD разворачивают по причине "знает слишком архаитчный стэк". Ценят не твой опыт на пет-проектах, а реальный и боевой. Особенно, если он помог твоему продукту принести бизнес ауткамы и выгоду.

2. Пересмотр зарплаты. Окей, возможно ты не хочешь уходить. Тогда может быть рост зарплаты внутри компании быстрее чем инфляция на рынке? Сомневаюсь. Даже если тебе сейчас комфортно текущий менеджер с текущей политикой может уйти через 2-3 года и придет более голодный и амбициозный менеджер, который может посчитать что вы "слишком тихие".

Я понимаю, почему такие сотрудники удобны менеджерам: они стабильны, не спорят, не увольняются. Но с точки зрения самого инженера это путь к невидимости. В IT растет тот, кто проявляет инициативу: пробует новое, предлагает решения, прокачивает навыки. Без этого легко застрять на одном уровне, пока мир идёт вперёд. Рынок любит тех, кто развивает глубину или ширину но не тех, кто стоит на месте.

Что я хочу сказать?

Расти не нужно всем. Это нормально, что мы этого не хотим. Но:
1. Если ты инженер, то ты должен понимать все риски
2. А если ты менеджер, то должен понимать риски, когда даешь людям советы "сидеть тихо, не рисковать, не проявлять инициативу и не выделяться". Ведь спустя пару лет твои подчиненные не смогут найти работу, когда ты скорее всего найдешь себе новую.

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

Это Win-Win стратегия
16
💎 Я запускаю сайт-тренажер для инженеров

Следите за пальцами.
- Я родился в семье учителей и обучать мне всегда нравилось. Так почти 5 лет назад я стал ментором на solvery (сейчас эта страница чисто для сео-оптимизации)
- после был преподом в нескольких школах программирования как яндекс.практикум, грейд и цифровые привычки
- дальше я запустил этот канал
- после я создал приложение "симулятор иосника" и мы стали в топ 5 апстора.
- после мы создали бусти с закрытым комьюнити, потому что до этого было открытое и много флуда. Мы закрылиьс и за 1,5 года мы собрали сотни задач, материалов и знаний от реальных практикующих экспертов.
- Стали самым большим комьюнити реальных практиков, где разбирают не вход в ит и собесы, а реальные практики.

Что дальше? Спустя два года после релиза симулятора я решил сделать апгрейд. По последним постам о челенджах и разнице между software developer vs software engineer мы пришли — что инженер не ограничивается одной платформой. Мобильное приложение и бусти, пусть это и копируют конкуренты, имеют ряд существенных минусов. Во-первых, это низковисящие фрукты, додуматься и сделать это не нужно много скилла. Во-вторых, банально в мобильном приложении никто не кодит, это плохой UX/UI. Никто не проводит собесы через телефон, никто не кодит через телефон.

Поэтому я решил расти и уже год вынашиваю идею эволюционировать. Сделать не просто то, что может сделать другой. А выйти на новый уровень. Бустануться и апгрейднуться.

Я хочу запустить свой сайт для:
🟣решения задач разных уровней. Начать хотяб с iOS
🟣понятные и полезные роадмапы.
🟣контакты экспертов и менторов
🟣аи-ассисент
🟣лучшие практики и задачи по систем дизайну

И многое другое 🎤

Во многом я подсмотрел идеи у neetcode и литкод, но это будет про наш рынок и наши правила. Я хочу сформулировать то, что копилось годами и обрело максимально практичную форму.

Это конечно не быстрый путь, но точно полезный.
Please open Telegram to view this post
VIEW IN TELEGRAM
3712