Полная карта
Все домены знаний на одной диаграмме. Кликните по уровню — попадёте в нужную секцию.
Карта меняется при выборе уровня в фильтре выше.
graph LR
T[Trainee] --> J[Junior]
J --> M[Middle]
M --> S[Senior]
S --> L[Tech Lead]
S --> ST[Staff/Principal]
L --> ST
T -.- F[CS, Git, CLI]
J -.- LA[Swift, UIKit, SwiftUI]
M -.- AR[Архитектура, Concurrency, Networking]
S -.- SD[System Design, Performance, Security]
L -.- LE[Команда, найм, грейды]
ST -.- PR[Орг-стратегия, влияние]
graph TD
ROOT[Trainee · 0–6 мес] --> CS[CS-фундамент]
ROOT --> SW[Swift синтаксис]
ROOT --> TOOL[Tooling]
ROOT --> UI[UI-старт]
CS --> CS1[Big-O · базово]
CS --> CS2[Value vs Reference]
SW --> SW1[Optionals, guard]
SW --> SW2[Замыкания]
SW --> SW3[Структуры/классы]
TOOL --> T1[Xcode]
TOOL --> T2[Git basics: commit, push, PR]
TOOL --> T3[CLI: brew, zsh, jq]
UI --> UI1[UIKit · 1 экран]
UI --> UI2[SwiftUI · State, Binding]
UI --> UI3[Auto Layout · stack views]
graph TD
ROOT[Junior · 0.5–1.5 года] --> CORE[Core iOS]
ROOT --> NET[Сеть и данные]
ROOT --> ARCH[Архитектура]
ROOT --> Q[Качество]
ROOT --> AI[AI tooling]
CORE --> C1[UIKit lifecycle]
CORE --> C2[SwiftUI 90% задач]
CORE --> C3[Анимации basics]
NET --> N1[URLSession async]
NET --> N2[Codable + DTO]
NET --> N3[UserDefaults / Keychain]
ARCH --> A1[MVVM с Observable]
ARCH --> A2[DI без фреймворков]
Q --> Q1[XCTest / Swift Testing]
Q --> Q2[LLDB · po, breakpoint]
AI --> AI1[Cursor / Claude Code basic]
AI --> AI2[CLAUDE.md в проекте]
graph TD
ROOT[Middle · 1.5–3 года] --> LANG[Swift глубже]
ROOT --> CONC[Concurrency]
ROOT --> ARCH[Архитектура]
ROOT --> PERF[Performance]
ROOT --> CICD[CI/CD]
ROOT --> AI[AI tooling]
LANG --> L1[Generics, some/any]
LANG --> L2[Property wrappers]
LANG --> L3[Result builders]
CONC --> CC1[async/await, Task]
CONC --> CC2[actor, MainActor]
CONC --> CC3[Sendable, isolation]
ARCH --> AA1[Clean architecture]
ARCH --> AA2[Coordinator + deep links]
ARCH --> AA3[SPM модули]
PERF --> P1[Instruments · Time/Hangs]
PERF --> P2[Image decoding async]
CICD --> CI1[Fastlane / Xcode Cloud]
CICD --> CI2[GitHub Actions]
AI --> AIM[MCP-серверы базово]
AI --> AIM2[Subagent для review]
graph TD
ROOT[Senior · 3–6 лет] --> SD[System Design]
ROOT --> ADVL[Swift advanced]
ROOT --> SEC[Безопасность]
ROOT --> PERF[Performance бюджет]
ROOT --> AI[AI как часть процесса]
ROOT --> INF[Влияние]
SD --> SD1[Кэш, offline-first]
SD --> SD2[Real-time, push, WS]
SD --> SD3[Дизайн-система]
ADVL --> AL1[Swift 6 strict concurrency]
ADVL --> AL2[Type erasure, phantom types]
SEC --> S1[Cert pinning, App Attest]
SEC --> S2[Secure Enclave]
PERF --> P1[App launch < 400 мс]
PERF --> P2[MetricKit в проде]
AI --> A1[Свои MCP-серверы]
AI --> A2[AI-driven docs/onboarding]
INF --> IN1[RFC и архитектурные доклады]
INF --> IN2[Менторство]
graph TD
ROOT[Tech Lead · 5+ лет] --> TEAM[Команда]
ROOT --> PROC[Процессы]
ROOT --> ARCH[Технические стандарты]
ROOT --> BIZ[Бизнес-связь]
TEAM --> T1[Найм и интервью]
TEAM --> T2[Грейды и 1-1]
TEAM --> T3[Развитие людей]
PROC --> P1[Релизный цикл]
PROC --> P2[Code review культура]
PROC --> P3[Постмортемы]
ARCH --> A1[Roadmap техдолга]
ARCH --> A2[Стандарты модуляризации]
ARCH --> A3[Performance budgets]
BIZ --> B1[Метрики продукта]
BIZ --> B2[Эстимейты команды]
BIZ --> B3[Защита решений с PM]
graph TD
ROOT[Staff/Principal · 7+ лет] --> ORG[Орг-уровень]
ROOT --> STRAT[Стратегия]
ROOT --> EXT[Внешнее влияние]
ORG --> O1[Мульти-команды]
ORG --> O2[Техкомитет, RFC]
ORG --> O3[Платформа для других]
STRAT --> S1[Стек и миграции]
STRAT --> S2[AI-инструменты в орг.]
STRAT --> S3[Связи с iOS, backend, web]
EXT --> E1[Доклады, статьи]
EXT --> E2[Hiring brand]
EXT --> E3[Open source]
Карта в Markdown
Сверните или разверните: всю структуру можно забрать к себе в Notion / Obsidian.
Развернуть карту
Как пользоваться
Не нужно учить всё подряд — выбирайте по уровню и задаче.
- Не читайте подряд. Включите фильтр сверху по своему уровню — увидите только нужное.
- Раскройте раздел. Внутри: карта, термины, упражнения, ссылки на доки и Habr.
- Делайте упражнения. Чтение без практики — это иллюзия знания.
- Помечайте пройденное. Скопируйте Markdown-карту выше в свой Notion / Obsidian и закрашивайте.
- Премиум-плашки ведут к постам на канале @iosdev с углублёнными разборами.
- Возвращайтесь. Roadmap живой — обновляется с выходом новых версий iOS и инструментов.
В каждом разделе есть блок 🎯 Фокус vs можно отложить — куда вкладывать время сейчас, а что само придёт с практикой. Начиная с Senior внутри секций есть блок 🌟 Стратегическое развитие — про влияние, технические инвестиции и работу с людьми, не только про код.
I. Фундамент
База, без которой всё остальное держится на честном слове.
01
Computer Science для iOS-разработчика
Computer Science для iOS-разработчика
CS не нужен «для галочки», а нужен, чтобы понимать, почему ваше приложение тормозит, ест память или ломается на 100 пользователях. Без базы вы перепрыгиваете к фреймворкам и потом всю жизнь объясняете «магией».
🎯 Фокус vs можно отложить
- Сложность алгоритмов в нотации Big-O — пригодится буквально каждый день.
- Система типов: что такое ссылка, что такое значение, в чём разница.
- Стек vs куча — где живут данные, как двигаются между потоками.
- Бинарное представление чисел (чтобы не было сюрпризов с
Int,UInt8,Float).
- Конкретные алгоритмы сортировки (сортировки за вас написали в стандартной библиотеке).
- Глубокая теория компиляторов и автоматов — понадобится только в очень специфичных задачах.
- Доказательство NP-полноты — придёт само, если выберете путь System Design.
📊 Карта раздела
graph TD
A[CS Foundations] --> B[Структуры данных]
A --> C[Алгоритмы]
A --> D[Память]
A --> E[Парадигмы]
B --> B1[Array, Dict, Set]
B --> B2[Tree, Graph, Heap]
C --> C1[Big-O]
C --> C2[Поиск/сортировка]
D --> D1[Stack vs Heap]
D --> D2[Reference vs Value]
E --> E1[OOP]
E --> E2[FP]
E --> E3[Protocol-Oriented]
📚 Ключевые термины
- Big-O
- Оценка асимптотики: как растёт время/память при росте входа.
O(1)— константа,O(log n)— бинарный поиск,O(n)— линейный,O(n log n)— сортировки,O(n²)— наивные двойные циклы. - Stack vs Heap
- Стек быстрый, ограниченный, авто-очистка. Куча — динамическая, медленнее, очищается ARC/GC. Value-типы Swift живут на стеке (если не захвачены замыканием), reference — на куче.
- Value vs Reference type
- Value (struct, enum) — копируется при передаче. Reference (class) — передаётся по ссылке. Это влияет на производительность и многопоточность.
- Copy-on-Write
- Оптимизация для коллекций: копия делается только при записи.
Array,Dictionary,Set,String— все CoW. - Парадигмы
- OOP (наследование, полиморфизм), FP (чистые функции, иммутабельность), POP (компоновка через протоколы) — Swift поддерживает все три.
🏋️ Упражнения (8)
- Big-O для своего кода. Откройте проект и найдите 5 функций. Для каждой определите сложность по времени и памяти. Где O(n²)? Можно ли свести к O(n log n)?
Подсказка: вложенный
for— это часто O(n²). ИспользуйтеSet/Dictionaryдля O(1) поиска. - Stack vs Heap. Создайте struct с массивом и class с массивом. Запустите Time Profiler и сравните аллокации при создании 1 млн копий. Перед запуском включите Allocations Instrument. Обратите внимание на колонку Persistent.
- Copy-on-Write. Реализуйте свою CoW-структуру с
isKnownUniquelyReferenced. Покажите, что копия не происходит при чтении. Внутри хранитеclass-обёртку. На запись — проверка уникальности и только тогда копия. - Структуры данных вручную. Реализуйте односвязный список, hash table, мин-кучу — без стандартной библиотеки. Это лучше любого учебника. Hash table — самое полезное. В iOS-собесах его просят чаще, чем кажется.
- Парадигмы на одном примере. Возьмите сценарий «список задач» и решите его 3 способа: классический OOP, чистый FP, POP-стиль. Сравните читаемость.
- Бинарное представление. Что выведет
Int8(127) &+ 1? АUInt8.max + 1? Запустите в playground и объясните результат через двоичную запись. Это про переполнение и дополнительный код (two's complement). - Big-O для коллекций Swift. Найдите в документации сложности операций для
Array,Set,Dictionary. Какая сложность уcontainsна массиве из 100k элементов? - Ленивая оценка. Сравните
arr.map(...).filter(...)иarr.lazy.map(...).filter(...)на массиве из 1 млн элементов. Где разница? Lazy не материализует промежуточные коллекции — экономит память.
Глубже на бусти и в Notion
Готовая подборка с разборами, схемами и задачами повышенной сложности — для тех, кому мало YouTube и Habr.
02
Операционные системы и сети для iOS
Операционные системы и сети для iOS
iOS — это Unix под капотом. Понимать процессы, потоки, файловые дескрипторы и сетевой стек нужно, потому что иначе вы будете плодить race condition'ы и не понимать, почему сетевой запрос «иногда» падает.
🎯 Фокус vs можно отложить
- HTTP/1.1 vs HTTP/2 vs HTTP/3 — что меняется на практике (multiplexing, TLS 1.3, QUIC).
- TLS-handshake и сертификаты — без этого ATS-ошибки будут «магией».
- Процессы vs потоки vs очереди — это база Concurrency.
- Sandbox iOS-приложения, файловая система, App Group.
- Глубокая реализация TCP/IP (control flags, congestion windows) — нужно, только если строите VPN/SDK.
- Линуксовые системные вызовы — пригодятся точечно.
- Подробности SSL/TLS-хендшейка вручную — поймите концептуально.
📊 Карта раздела
graph LR
OS[iOS as Unix] --> P[Процессы]
OS --> T[Потоки]
OS --> SB[Sandbox]
N[Сети] --> H[HTTP/1, 2, 3]
N --> TLS[TLS 1.3]
N --> WS[WebSocket]
N --> WK[WebKit/URL]
P --> Q[GCD/Operations]
T --> RL[RunLoop]
📚 Ключевые термины
- RunLoop
- Цикл обработки событий, привязанный к потоку.
mainRunLoop отвечает за UI-события, таймеры, источники. - Sandbox
- Изолированная среда: приложение видит только свои контейнеры (
~/Library,Documents,tmp). Доступ к чужим — через intent/share extensions. - App Transport Security (ATS)
- iOS требует HTTPS с TLS 1.2+. Disable можно только через
Info.plistи не для прода. - HTTP/2
- Мультиплексирование, бинарный формат, server push. URLSession поддерживает «из коробки».
- HTTP/3 (QUIC)
- Поверх UDP, быстрее устанавливает соединение. Включается в URLSession через
assumesHTTP3Capable.
🏋️ Упражнения (7)
- Пощупать sandbox. Попробуйте записать файл в
/private/tmpиз приложения и вFileManager.default.url(for: .documentDirectory). Сравните результат. - Анализ TLS. Откройте
nscurl --ats-diagnostics https://example.com. Какие версии TLS поддерживаются? Что блокирует ATS? - Charles/Proxyman. Перехватите трафик симулятора. Найдите запросы, которые шлёт SwiftUI Preview. Установите root-сертификат Proxyman в симулятор и trust его в Settings.
- HTTP/2 → HTTP/3. Включите
config.assumesHTTP3Capable = trueи сравните latency на 100 запросах. - WebSocket с нуля. Используйте
URLSessionWebSocketTaskи подключитесь к публичному echo-серверу. Реализуйте reconnect с экспоненциальной задержкой. - RunLoop в действии. Запустите
Timer.scheduledTimerс задержкой 1с в фоновом потоке без явного RunLoop. Почему он не сработает? - Background modes. Включите Background Fetch и реализуйте обновление данных через
BGAppRefreshTask. Замерьте, сколько раз iOS его реально вызвал за сутки.
Углублённо на бусти
Разборы URLSession, TLS, App Transport и code signing — то, что в документации Apple раскинуто по 12 страницам.
03
Git, командная работа и code review
Git, командная работа и code review
Незнание git — главный убийца времени джуниора. Не освоив rebase, cherry-pick и работу с конфликтами, вы будете «терять» PR и вызывать гнев тимлида.
🎯 Фокус vs можно отложить
- Атомарные коммиты, осмысленные сообщения (Conventional Commits — но без догматизма).
rebasevsmerge: когда что использовать.- Разрешение конфликтов осознанно, не через «принять свои».
- Этикет код-ревью: как давать и получать обратную связь.
- Внутренности git (objects, packfiles) — нужно при написании tooling.
- Submodules — лучше избегайте; используйте SPM/Tuist.
- Subtrees — экзотика.
🏋️ Упражнения (8)
- Interactive rebase. Сделайте 5 коммитов, переименуйте 2-й, объедините 3-й и 4-й, удалите 5-й.
git rebase -i HEAD~5— затемreword,squash,drop. - Cherry-pick. Перенесите конкретный коммит из feature-ветки в hotfix.
- Bisect. Найдите коммит, в котором сломался тест — без чтения diff'ов, только через
git bisect. - Merge vs Rebase. Сделайте PR с merge, затем PR с rebase. Сравните историю в
git log --graph. - Conflict осознанно. Создайте конфликт, разберите его в Xcode'овском merge view. Убедитесь, что код всё ещё компилируется.
- Reflog. «Случайно» сделайте
reset --hard. Восстановите коммит черезgit reflog. - Hooks. Напишите pre-commit, который запускает SwiftLint. Сделайте коммит с warning — он должен упасть.
- Code review навык. Найдите свой PR полугодовой давности и напишите ревью на самого себя.
🌟 Стратегическое развитие (Senior+)
- Trunk-based vs GitFlow. Понимать, какая стратегия подходит вашей команде. Не навязывайте GitFlow стартапу из 4 человек.
- Code review как наставничество. Хорошее ревью — это не «верните пробел», а «вот почему этот подход создаст проблему через год».
- Релизные процессы. Связка git-flow + ветки релизов + теги версий + автогенерация changelog.
- Контракты команды. Договариваетесь, как именно вы коммитите, мерджите и ревьюите. Документируйте в README.
04
CLI, shell, dotfiles и продуктивность в терминале
CLI, shell, dotfiles и продуктивность в терминале
Терминал — это второй Xcode. Чем меньше вы тыкаете мышкой, тем быстрее работаете. Хорошие dotfiles экономят 1-2 часа в неделю.
🎯 Фокус vs можно отложить
- zsh + Oh My Zsh / starship — приятный prompt и плагины.
- Homebrew, brew bundle, Brewfile — воспроизводимое окружение.
jq,fzf,ripgrep,bat,tldr— обязательные.xcrun,simctl,xcodebuild— Xcode без UI.
- Глубокий awk/sed — обычно достаточно
jqи Python-скриптов. - Vim/Emacs holy wars — выберите редактор и идите дальше.
🏋️ Упражнения (7)
- Brewfile. Соберите все ваши пакеты в
Brewfile:brew bundle dump. Сохраните в dotfiles-репо. - simctl. Запустите симулятор iPhone 15 Pro из терминала, установите
.app, снимите скриншот.xcrun simctl boot "iPhone 15 Pro",simctl install,simctl io ... screenshot. - jq для App Store Connect API. Распарсите ответ
/v1/buildsи достаньте номер последней сборки одной строкой. - fzf. Настройте поиск по последним веткам:
git checkout $(git branch | fzf). - Алиасы. Создайте
gco,gst,gp,xcb. Каждый сэкономит ~50 нажатий в день. - tldr. Замените 80% вызовов
manнаtldr. Убедитесь, что это быстрее. - xcodebuild без Xcode. Соберите проект, прогоните тесты, поднимите архив — целиком из терминала.
II. Swift
Язык, на котором вы будете писать ближайшие 5+ лет. Стоит знать его лучше, чем «свой английский».
05
Swift: базовый синтаксис и идиоматика
Swift: базовый синтаксис и идиоматика
Optional, value/reference типы, control flow, функции, замыкания, расширения. Swift — выразительный язык, и идиоматичный код легко отличить от «Java на Swift».
🎯 Фокус vs можно отложить
- Optional и его обработка:
if let,guard let,??, optional chaining. - Замыкания: capture lists, escaping vs non-escaping, trailing syntax.
- Расширения и условные расширения для дженерик-типов.
- Уровни доступа: open, public, internal, fileprivate, private.
- Property wrappers и result builders на пользовательском уровне.
- Дотошное знание всех глобальных функций Stdlib — учим по мере встречи.
@dynamicMemberLookup,@dynamicCallable— экзотика.- Swift macros на уровне написания — пользоваться чужими достаточно для джуна-мидла.
📚 Ключевые термины
- Optional
- Перечисление с двумя кейсами:
.some(Wrapped)и.none. Все «крестики» (?,!) — это сахар над ним. - Capture list
- Список захватываемых переменных в начале замыкания:
{ [weak self] in ... }. Без него — захват по сильной ссылке, с риском retain cycle. - @escaping
- Замыкание, которое переживёт текущий scope (например, callback в URLSession). Требует явного захвата self.
- guard
- Ранний выход из функции. Делает «happy path» плоским.
- Result builder
- Декларативный синтаксис «как в SwiftUI». Используется через
@resultBuilderаннотацию.
🏋️ Упражнения (10)
- Optional pyramid → guard. Возьмите код с 4 вложенными
if letи переписали черезguard let. Какой вариант читать легче? - Capture list. Создайте retain cycle с замыканием в
UIViewController. Поймайте его через Memory Graph. Исправьте через[weak self]. - Trailing closure. Перепишите
UIView.animate(withDuration: 0.3, animations: {}, completion: {})в trailing-стиле с двумя замыканиями. - Property wrapper. Напишите
@Clamped(0...100), который ограничивает значение Int. - Result builder. Реализуйте свой
@AttributedStringBuilder, который собираетNSAttributedStringдекларативно. - Уровни доступа. Создайте модуль через SPM. Сделайте API так, чтобы внешний код видел только то, что нужно.
- Equatable + Hashable. Объявите struct с 3 свойствами и реализуйте Hashable вручную (без autosynthesis).
- Расширения протоколов. Напишите дефолтную реализацию
descriptionчерезMirrorдля всех типов, реализующихReflectable. - Result type. Перепишите callback с
(Data?, Error?)наResult<Data, Error>. Сравните читаемость. - String — это коллекция. Сравните
str.countиstr.utf8.countдля строки"👨👩👧👦". Объясните разницу. Это про grapheme clusters vs code units.
Глубже на бусти
Подборки, которые я давал на менторинге — те самые «непереведённые в TLDR» нюансы, которые любят на собесах в больших компаниях.
06
Типы, протоколы, дженерики, opaque и existentials
Типы, протоколы, дженерики, opaque и existentials
Тут начинается «настоящий Swift». Дженерики, ассоциированные типы, some vs any — то, что делит middle и senior на собесах.
🎯 Фокус vs можно отложить
- PAT — protocol with associated types — почему нельзя использовать как тип напрямую.
some(opaque) vsany(existential): когда что выбирать.- Type erasure (
AnyPublisher,AnySequence): зачем и как сделать свой. - Дженерик-ограничения:
where,==,:, several constraints. - Phantom types для compile-time контроля состояния.
- Variadic generics (
each T) — недавно появились, узкий круг задач. - Метатипы и
Self-семантика на углублённом уровне — пригодится точечно.
📊 some vs any
graph LR P[Protocol P] --> S[some P · opaque] P --> A[any P · existential] S --> S1[Конкретный тип
известен компилятору] S --> S2[Без overhead] A --> A1[Тип может меняться
в runtime] A --> A2[Existential box
+ overhead]
🏋️ Упражнения (8)
- PAT. Объявите
protocol Container { associatedtype Item; ... }. Попробуйте использоватьContainerкак тип переменной — поймайте ошибку компиляции, исправьте черезany. - some vs any. Напишите функцию
makeAdder() -> some Numeric. Затем перепишите какany Numeric. Сравните бенчмарк черезXCTMetric. - Type erasure. Сделайте свой
AnyViewс двумя реализациямиSomeViewиOtherView. Измерьте размер на runtime черезMemoryLayout. - Phantom types. Реализуйте API
Money<USD>иMoney<EUR>. Компилятор должен запретить складывать их. - Дженерик-ограничения. Реализуйте
extension Array where Element: Numeric { var average: Element }. - Sequence/Collection. Сделайте свой
FibonacciSequence, реализующийSequence. Используйте черезfor-in. - Result builder. Реализуйте
HTMLBuilder, чтобы собирать html-строку декларативно. - Conditional conformance. Сделайте
extension Array: Equatable where Element: Equatable. Проверьте, что[Any]не равно само себе.
🌟 Стратегическое развитие (Senior+)
- Дизайн API. На senior уже не «как написать код», а «как другие будут им пользоваться». Читайте API Design Guidelines, смотрите эволюцию Stdlib.
- Источник истины — SE-предложения. swift-evolution. Понимать, куда движется язык, и принимать архитектурные решения с заделом.
- Балансы. Не упарываться в дженерики там, где protocol достаточно. Сложность — это техдолг.
- Менторство. Объяснить protocol with associated types джуну так, чтобы он понял с первого раза — самостоятельный навык.
Глубже в Notion
07
Память, ARC, retain cycles, side tables
Память, ARC, retain cycles, side tables
ARC экономит вам нервы, но иногда делает не то, что вы ожидаете. Не понимая weak/unowned, side tables и autoreleasepool, вы будете дебажить «я ничего не делал, оно само утекает». Эта тема — топ-3 на собеседованиях iOS Middle/Senior.
🎯 Фокус vs можно отложить
- Retain cycles в замыканиях, делегатах, NotificationCenter, Combine, Task.
weakvsunownedvsunowned(unsafe): когда какое использовать и какова цена.- Side tables — что хранится отдельно от объекта (strong / unowned / weak counters).
autoreleasepoolв горячих циклах с Objective-C объектами.- Memory Graph и Allocations Instrument: ловить утечки и фантомные объекты.
MemoryLayout:size,stride,alignment.- Value type vs Reference type: где живёт, как копируется.
- Внутренности
HeapObjectи weak references на C++ уровне — крутой контент, но не для джуниора. - Подробности
swift_release/swift_retainи оптимизаций компилятора — пригодится при оптимизации горячих участков. - Memory Integrity Enforcement (Swift 6.x) — концептуально достаточно понимать.
📚 Что учить по уровням
Junior
- Что такое ARC и почему не нужно вручную
release. - Поймать retain cycle через Memory Graph (зелёные/фиолетовые квадратики).
[weak self]в замыканияхUIView.animate,URLSession,DispatchQueue.- Делегаты как
weak var. - Базовые
Value type(struct) vsReference type(class).
Middle
- Side tables: зачем хранить
weak-счётчик отдельно, как «зомби-объект» становится nil. weakvsunownedvsunowned(unsafe)+ цена доступа.- Retain cycle между двумя классами; через
Closure; черезCombine.AnyCancellable. autoreleasepoolс UIImage/Data в горячих циклах.- Профилирование через Allocations + Leaks Instrument.
- Понимать «утечка vs abandoned memory» — это разное.
Senior
- Внутренности
HeapObject: header, refCount, weakRefCount. - COW-семантика для Array/Dictionary через
isKnownUniquelyReferenced. - Свои
@autoclosure/@escaping-обёртки без захвата self. - Анализ memory footprint в проде через MetricKit + диагностика abandoned memory.
- Memory Integrity Enforcement (Swift 6+).
- Менторство джунов — типовые ошибки в код-ревью.
📊 Карта раздела
graph TD
M[Память в Swift] --> S[Stack]
M --> H[Heap]
M --> ARC[ARC]
M --> TYPES[Типы]
S --> S1[value-types]
S --> S2[быстро, авто-очистка]
H --> H1[reference-types]
H --> H2[освобождает ARC]
ARC --> A1[strong]
ARC --> A2[weak]
ARC --> A3[unowned]
TYPES --> T1[struct/enum]
TYPES --> T2[class/closure]
TYPES --> T3[CoW коллекции]
📊 Side table — как хранится weak
graph LR HO[HeapObject] -->|inline| HD[Header
strong + unowned] HO --> SP[side-table-ptr] SP --> ST[Side Table] ST --> SC[strong count] ST --> UC[unowned count] ST --> WC[weak count] W1[weak ref #1] --> ST W2[weak ref #2] --> ST
При первом обращении weak-ссылки создаётся side table с тремя счётчиками. Сама weak-ссылка указывает не на объект, а на side table — поэтому когда объект уничтожается, она «обнуляется» автоматически.
📊 Типичные retain cycle и как чинить
graph LR P[ViewController] -->|strong| C[Closure] C -->|capture self strong| P P -.->|или| D[Delegate] D -.->|strong
ОШИБКА| P P2[ParentVC] -->|strong child| Ch[ChildVC] Ch -.->|strong parent
ОШИБКА| P2 N[NotificationCenter] -.- O[Observer] T[Timer] -->|strong target| P
Замыкание → [weak self]. Делегат → weak var delegate. Child → Parent → weak. Timer → invalidate() в deinit родителя или используйте API с blocks. NotificationCenter с iOS 9+ держит наблюдателей слабо.
📊 weak vs unowned — выбор
graph TD Q[Объект может стать nil раньше владельца?] -->|да| W[weak
Optional, с проверкой] Q -->|нет, гарантированно живёт| U[unowned
не Optional] Q -->|подозреваешь null, но хочется без проверки| US[unowned unsafe
опасно: краш] W --> WP[Чуть медленнее
+ side table] U --> UP[Быстрее
но при разыменовании nil — краш] US --> USP[Самый быстрый
UB при ошибке]
📚 Ключевые термины
- ARC
- Automatic Reference Counting. Компилятор автоматически вставляет
retain/releaseпри создании/выходе из области видимости ссылочных типов. - Strong
- Дефолтный режим. Удерживает объект; при
refCount == 0объект уничтожается. - Weak
- Не удерживает объект, всегда Optional. Автоматически становится
nilпри уничтожении объекта (через side table). - Unowned
- Не удерживает объект, не Optional. При обращении к уничтоженному — крах. Дешевле
weak. - Side table
- Дополнительная структура, где живут
strong/unowned/weakсчётчики и список weak-ссылок. Создаётся лениво при первой weak-ссылке. - Heap object header
- 16 байт: указатель на metadata + inline-счётчики strong и unowned. Если есть weak — добавляется указатель на side table.
- Capture list
{ [weak self, unowned vc] in ... }— явное указание, как захватить self/другие переменные в замыкание.- Retain cycle
- Два или больше объектов держат друг друга через strong, ARC не может их освободить.
- Abandoned memory
- Не утечка, но память «забыта»: на неё ещё есть ссылки, но в логике приложения она не используется.
- Autoreleasepool
- Скоп, в конце которого освобождаются объекты, отмеченные autorelease (актуально для Foundation/Objective-C — UIImage, NSString, файлы).
- MemoryLayout
size— реальный размер,stride— шаг в массиве (с padding),alignment— требуемое выравнивание.- Copy-on-Write
- Коллекции (Array, Dictionary, Set, String) создают копию буфера только при записи и только если
!isKnownUniquelyReferenced. - EXC_BAD_ACCESS
- Обращение к освобождённой/невалидной памяти. Часто — следствие
unownedна уже мёртвый объект или ручной C-pointer.
🏋️ Упражнения (12)
- Таймер-утечка. Создайте
UIViewControllerсTimer.scheduledTimer(target: self, ...). Откройте Memory Graph — увидите утечку. Исправьте черезweak targetили новый block-APITimer(timeInterval:repeats:block:). - weak vs unowned. Реализуйте обе версии замыкания и убедитесь, что
unownedкрашится при доступе к освобождённому объекту. Замерьте разницу в скорости черезXCTMetric. - NotificationCenter в iOS 9+. Подпишитесь без сохранения токена, отпустите ViewController. Объясните, почему утечки нет.
NC хранит наблюдателей через
weakс iOS 9+, но если используетеaddObserver(forName:queue:using:)с замыканием — нужен токен. - autoreleasepool. Загрузите 1000
UIImage(contentsOfFile:)в цикле. Сравните рост памяти сautoreleasepoolи без — разница может быть в 50-100×. - Closure capture list. Передайте
selfвTask { ... }. Поймайте retain cycle в Memory Graph. Исправьте через[weak self]. - Side tables. Объясните, почему
weak varчуть медленнее, чемstrong. Посмотрите доклад «Understanding Swift Performance» (WWDC 2016, session 416). - Combine cycle.
$publisher.sink { value in self.use(value) }. Поймайте утечку и исправьте через[weak self]илиstore(in: &cancellables). - UIView retain cycle. Замените все
strongссылки между parent и child view наweak. Объясните, что сломается, что нет. - Memory Graph CLI. Запустите приложение, снимите
.memgraphчерезleaks PID -outputGraph file.memgraph, откройте в Xcode. - MemoryLayout. Сравните
size,stride,alignmentдляBool,UInt8, кастомногоstruct Pair. - Copy-on-Write вручную. Реализуйте свою CoW-структуру через
isKnownUniquelyReferenced. Убедитесь, что копия не происходит при чтении. - weak self в Task. Внутри
actorили async-функции захватитеselfчерез[weak self]. Поймёте, почему семантика отличается от GCD.
🌟 Стратегическое развитие (Senior+)
- Memory budget команды. Договоритесь о пиковом и среднем footprint. Включите измерение в CI через UI-тест с XCTMemoryMetric.
- Plan для extensions. Виджеты/share-extensions имеют жёсткие лимиты памяти (30-50 MB) — нужна стратегия preview, обработки изображений, кэша.
- Code review-чек-лист. 1)
selfв замыканиях — capture list. 2) Делегаты —weak. 3) Combine —store(in:). 4) Timer/DisplayLink —invalidateвdeinit. 5) NotificationCenter — токены. - Менторство. Объяснить «почему 2 МБ картинка ест 80 МБ» и научить искать abandoned memory — отдельный навык.
Премиум-разборы
У меня большой набор материалов конкретно по памяти — собирал годами. Каждая ссылка ведёт на пост на канале с продолжением на Boosty.
08
Swift Concurrency: async/await, actor, isolation
Swift Concurrency: async/await, actor, isolation
Swift Concurrency — это не «GCD на стероидах», это совершенно другая модель с гарантиями на уровне компилятора. Если не разобраться, в Swift 6 mode проект перестанет собираться.
🎯 Фокус vs можно отложить
async/await,Task,TaskGroup— основа.actor,@MainActor, isolation domains.Sendable, data races на компиляции.- Structured vs unstructured concurrency.
- Cancellation:
Task.checkCancellation,withTaskCancellationHandler. - Bridge от GCD/callback API через
withCheckedContinuation.
- Custom Executor — экзотика, нужна в системных задачах.
distributed actor— пока редко используется.- Глубокая интеграция с Combine, если у вас новый проект.
📚 Что учить по уровням
Junior
- Понять разницу между sync / async вызовами и зачем нужно
await. - Запустить
Task { ... }в обработчике кнопки и сделатьawaitURLSession. - Обернуть старый callback-API через
withCheckedContinuation. - Понимать, что
@MainActor— это для UI.
Middle
- TaskGroup / withTaskGroup для параллельных запросов с сохранением порядка.
- actor для защиты состояния, понимать reentrancy и priority inversion.
- Sendable,
@unchecked Sendable,@preconcurrency import. - Cancellation:
checkCancellation(),withTaskCancellationHandler. - AsyncSequence и собственные
AsyncStream.
Senior
- Включить Swift 6 strict concurrency на крупном модуле, починить все warning.
- Spend-time на дизайн isolation domains: где actor, где @MainActor, где global actor.
- Глобальные акторы под доменные зоны (
@DataActor). - Профилирование async-кода через Instruments > Concurrency.
- Решения: где осознанно использовать
nonisolated(unsafe).
Tech Lead
- План миграции команды на Swift 6 (RFC, фазы, временные
@preconcurrency). - Code review-стандарт: какие паттерны блокируют, что можно отложить.
- Onboarding-набор для новичков по Concurrency.
Staff/Principal
- Стратегия для всей организации: общий стиль isolation, кастомные executor’ы для critical-path задач.
- Внутренние библиотеки/abstractions поверх Concurrency, чтобы скрыть низкоуровневые детали от продуктовых команд.
- Доклад внутри компании / на конференции по миграции.
📊 Карта Concurrency
graph TD
C[Swift Concurrency] --> AS[async/await]
C --> T[Task]
C --> A[Actor]
C --> S[Sendable]
T --> TG[TaskGroup]
T --> CN[Cancellation]
A --> MA[@MainActor]
A --> GA[Global Actor]
S --> IS[Isolation Domain]
🏋️ Упражнения (10)
- Bridge. Перепишите
URLSession.dataTask(with:completion:)наasyncчерезwithCheckedContinuation. - TaskGroup. Скачайте 10 картинок параллельно через
withTaskGroup. Сохраните порядок. - Actor. Реализуйте
actor BankAccountсdeposit/withdraw. Запустите 100 параллельных депозитов — всё должно сходиться. - Race condition. Создайте
classс мутабельным массивом. Запустите 1000 паралл.append. Поймайте data race в Thread Sanitizer. - @MainActor. Найдите в проекте 3 места, где обновление UI делается без
@MainActor. Добавьте аннотацию. - Sendable. Объявите
struct Userи попробуйте передать вTask. Если выдаст warning — исправьте черезSendable. - Cancellation. Реализуйте загрузку, которая корректно отменяется при
Task.cancel(). - AsyncSequence. Сделайте свою
AsyncSequence, которая выдаёт значения каждые 1с. - Reentrancy. Внутри actor вызовите await ещё одного actor. Объясните, почему второй вызов может «переплестись».
- Migrate to Swift 6. Включите
SWIFT_STRICT_CONCURRENCY=complete. Исправьте все warning.
🌟 Стратегическое развитие (Senior+)
- План миграции. На больших проектах нельзя «просто включить» strict concurrency. Нужен план: модули, прогрессия, временные
@preconcurrency. - Архитектурные паттерны. Использовать ли
@MainActor-only архитектуру? Когда выделять Domain-actor? Это решения, которые влияют на 5+ лет проекта. - Обучение команды. Доклады, code review с акцентом, internal RFC. Senior — это не «я знаю», а «команда знает».
Премиум-материалы по Concurrency
Самая частая боль на собесах 2024-2026. У меня собрана отдельная карта изучения с 30+ задачами, разборы изоляции и гонок данных.
III. iOS SDK
Платформенные фреймворки. Знание UIKit и SwiftUI вместе — гигиенический минимум на 2026 год.
09
Foundation, App lifecycle, Scene-based архитектура
Foundation, App lifecycle, Scene-based архитектура
Foundation — это «Си-стандартная библиотека» iOS: Date, URL, FileManager, JSONDecoder, Notification. Без хорошего знания этого слоя любой код превращается в велосипед.
🎯 Фокус vs можно отложить
- App lifecycle:
application(_:didFinishLaunching),UIScene, состояния foreground/background. - Время и даты:
Date,Calendar,DateFormatter,FormatStyle. FileManager— где что лежит (Documents, Caches, tmp, App Group).- Codable: encoder/decoder, custom keys, версионирование DTO.
- NotificationCenter, KVO — современные альтернативы (Combine/AsyncSequence).
- NSCoder/NSKeyedArchiver вручную — Codable покрывает 95% задач.
- Глубокая работа с
NSPredicateвне CoreData. - NSRegularExpression — есть нативный
Regexс iOS 16.
🏋️ Упражнения (8)
- Lifecycle логирование. Залогируйте все 6 переходов состояний приложения (active/inactive/background/...). Проверьте: что происходит при свайпе домой?
- Scene-based миграция. Перенесите старое UIKit-приложение с Scene Delegate. Сравните, что изменилось.
- Codable с миграцией. Версионируйте DTO: добавьте новое поле, обработайте отсутствие у старых клиентов.
- FormatStyle. Отформатируйте сумму
1234.5как «1 234,50 ₽» через.formatted(.currency(code: "RUB")). - Date arithmetic. Подсчитайте, сколько дней осталось до конца месяца (учтите часовой пояс).
- FileManager. Сохраните файл в
Caches. Что произойдёт, если устройство близко к заполнению? - App Group. Поделитесь данными между приложением и виджетом через App Group container.
- Notification → AsyncSequence. Подпишитесь на
UIApplication.didBecomeActiveNotificationчерезNotificationCenter.default.notifications(named:).
Углублённо в Notion
10
UIKit: View hierarchy, lifecycle, gestures, transitions
UIKit: View hierarchy, lifecycle, gestures, transitions
UIKit живее всех живых: 90% продакшен-приложений на нём, и SwiftUI пока не закрывает все кейсы (динамическая навигация, кастомные коллекции, сложные анимации).
🎯 Фокус vs можно отложить
- UIView vs UIViewController vs UIWindow lifecycle (
viewDidLoad,viewWillAppear,viewIsAppearing). - Responder chain, hit-testing — без этого жесты «магия».
- Layer vs View,
setNeedsLayoutvslayoutIfNeeded. - Адаптивность: trait collections, dynamic type, dark mode.
- Storyboards и XIB — на новых проектах их почти не делают, но читать уметь надо.
- Tab bar customisation на низком уровне (когда хватает
UITabBarController).
📚 Что учить по уровням
Trainee
- Что такое
UIView,UIViewController, как поставить кнопку и обработать тап. - Базовый Auto Layout через
translatesAutoresizingMaskIntoConstraints = false.
Junior
- Полный lifecycle:
viewDidLoad,viewWillAppear,viewIsAppearing. - UIScrollView, UITableView, базовый UICollectionView.
- Programmatic UI без storyboard для одного экрана.
- Поддержка Dark mode и Dynamic Type.
Middle
- Diffable Data Source + Compositional Layout.
- Hit-testing, responder chain, кастомные жесты.
- Custom transitions через
UIViewControllerAnimatedTransitioning. - Adaptive Layout: trait collections, multiple size classes.
Senior
- Гибридные UIKit + SwiftUI экраны через
UIHostingControllerс динамическим content size. - Бесшовная миграция legacy-MVC в современную архитектуру без переписывания всего.
- Профилирование скролла на 60-120fps, image decoding async.
Tech Lead
- Стратегия UIKit ↔ SwiftUI: где какой использовать в проекте.
- Дизайн-система поверх UIKit с компонентами и токенами.
📚 Ключевые термины
- Responder chain
- Цепочка ответственных за события объектов: View → SuperView → ViewController → Window → App. Понимание её решает 80% багов с жестами.
- Hit-testing
- Алгоритм поиска view, по которому ткнули. Переопределение
hitTest(_:with:)позволяет делать «прозрачные» области. - setNeedsLayout
- Помечает view, что layout устарел. Реальный
layoutSubviewsзапустится в следующем цикле. - Trait collection
- Контекст: размер класс, dynamic type, accessibility, dark mode. Меняется без перезапуска.
🏋️ Упражнения (10)
- Lifecycle лог. Залогируйте все методы жизненного цикла VC при presentation/dismissal/push/pop.
- iOS 13+ viewIsAppearing. Используйте новый метод и сравните с
viewWillAppear. Когда какой? - Hit-test puzzle. Сделайте кнопку, которая ловит тапы на 50px вокруг себя. Реализуйте через переопределение
point(inside:with:). - Custom transition. Реализуйте своё
UIViewControllerAnimatedTransitioningс zoom-эффектом. - Gestures. Создайте конфликтующие
UIPanGestureRecognizerна ScrollView и кастомной view. Разрешите конфликт черезUIGestureRecognizerDelegate. - Trait collection. Реализуйте view, реагирующую на изменение dark mode и accessibility размера.
- Embedded VC. Сделайте контейнер, который встраивает 2 child VC и переключает между ними анимированно.
- UIScrollView с Auto Layout. Зацепите content size автоматически через констрейнты.
- Diffable + UICollectionView. Реализуйте список с
NSDiffableDataSourceSnapshot. Анимируйте удаление. - Programmatic only. Сделайте экран без сториборда и xib, целиком кодом. Используйте
UICollectionViewCompositionalLayout.
Глубже на бусти
11
SwiftUI: декларативный UI и state management
SwiftUI: декларативный UI и state management
SwiftUI к 2026 году — взрослая технология: navigation stack, observation, animations стабилизировались. Игнорировать его — значит упустить пол iOS-рынка.
🎯 Фокус vs можно отложить
- State management:
@State,@Binding,@Observable,@Environment. - View identity и структурная идентичность — почему view иногда «теряет» state.
NavigationStack,NavigationPath, deep links.- Перформанс: разделение view,
EquatableView, профилирование_printChanges(). - Интеграция с UIKit через
UIViewRepresentable.
- Старый
NavigationView— устарел, забываем. - ObservableObject/@Published на новых проектах — переходим на
@Observable. - Ручной
GeometryReaderвезде — естьonGeometryChangeиcontainerRelativeFrame.
📚 Что учить по уровням
Junior
@State,@Binding— базовое состояние и связь с дочерними view.- Стандартные контейнеры: VStack, HStack, ZStack, List, ScrollView.
- NavigationStack: push/pop с типами в path.
- Простая интеграция с UIKit через
UIViewRepresentable.
Middle
@Observableмакрос (новый стандарт после iOS 17).- Identity и lifetime view, понимание перерисовок через
Self._printChanges(). - Performance: EquatableView, LazyVStack, разделение body на subviews.
- Custom
Layoutprotocol для нестандартных раскладок. - Анимации:
matchedGeometryEffect,PhaseAnimator.
Senior
- Snapshot-тесты для всех state-вариантов.
- Сложные навигационные сценарии с deep links и tab + modal stack.
- Migration UIKit ↔ SwiftUI с замером перфоманса.
- Свой
Environment-слой для DI/темы.
Tech Lead
- Дизайн-система на SwiftUI с токенами цвета, типографики, отступов.
- Performance budget команды (FPS, body re-renders) и контроль через CI.
- Решение когда применять SwiftUI Previews как dev-iteration инструмент.
📊 SwiftUI · State property wrappers
graph LR V[View] --> S[@State
локальное] V --> B[@Binding
двусторонняя связь] V --> O[@Observable
модель] V --> E[@Environment
контекст] V --> SC[@SceneStorage
per-scene]
🏋️ Упражнения (10)
- @Observable. Перепишите модель с
ObservableObject + @Publishedна новый макрос. Сравните количество перерисовок. - NavigationStack. Сделайте stack с deep linking:
app://users/42открывает экран пользователя. - Identity. Реализуйте список, в котором при reorder теряется state дочерней view. Исправьте через
.id(...). - Performance. Сделайте экран с 1000 элементами. Используйте
LazyVStack, выделите тяжёлые subviews в отдельные. - UIKit bridge. Встройте
MKMapViewчерезUIViewRepresentable. Реализуйте обновление черезupdateUIView. - Custom layout. Реализуйте
FlowLayoutчерезLayoutprotocol. - Анимация. Сделайте matched geometry effect между двумя экранами.
- Environment. Создайте свой
EnvironmentValueдля темы. Передайте его через все экраны. - Snapshot тестирование. Используйте swift-snapshot-testing для всех state-вариантов экрана.
- Профилирование. Включите
let _ = Self._printChanges()и найдите лишние перерисовки.
🌟 Стратегическое развитие (Senior+)
- Решение «UIKit или SwiftUI». Senior определяет миграционную стратегию: где UIKit обоснован, где SwiftUI экономит время.
- Дизайн-система. Свой layer над SwiftUI с компонентами, токенами цвета, типографикой. Позволяет команде делать UI быстрее и единообразно.
- Performance budget. Договариваетесь с командой: сколько перерисовок допустимо на экран, какие FPS-минимумы. Меряете в Instruments.
Премиум по SwiftUI
12
Auto Layout, адаптивность, Stack & Compositional
Auto Layout, адаптивность, Stack & Compositional
Auto Layout — это система ограничений на основе Cassowary. Поняв её принцип («constraints формируют систему уравнений»), вы перестанете бояться «оранжевых» и «красных» предупреждений Xcode.
🎯 Фокус vs можно отложить
- NSLayoutConstraint и Anchor API — кодовые констрейнты быстрее любого Interface Builder.
- Content hugging vs compression resistance — без этого не сделать ни одной хорошей формы.
- UIStackView — ¾ задач решает он, не плодите констрейнты руками.
- Safe area, layout margins, readable content guide.
- Глубокие нюансы Visual Format Language — устарел.
- Storyboards-only подход.
🏋️ Упражнения (8)
- Anchor API. Расположите 4 кнопки в форме сетки 2x2 без UIStackView, используя только anchors.
- UIStackView. Перепишите экран с 8 констрейнтами в 2 вложенных стека.
- Hugging/Compression. Сделайте лейбл с длинным текстом, который сжимается, а не растягивает кнопку рядом.
- Safe area. Сделайте экран, который правильно работает на iPhone SE и iPhone 16 Pro Max.
- Compositional Layout. Реализуйте экран App Store: горизонтальный список с большими карточками, ниже — горизонтальная сетка.
- Self-sizing cells. Сделайте таблицу, где высота ячейки зависит от длины текста.
- Layout debugging. Поймайте «conflicting constraints» в консоли и научитесь читать сообщение.
- UIKit + SwiftUI. Встройте
UIHostingControllerс динамическим content size.
13
UICollectionView, Compositional Layout, Diffable Data Source
UICollectionView, Compositional Layout, Diffable Data Source
90% сложных экранов — это UICollectionView. Освойте Compositional Layout + Diffable — и будете решать задачи в 3 раза быстрее.
🎯 Фокус vs можно отложить
- NSDiffableDataSourceSnapshot, секции, supplementary views.
- UICollectionViewCompositionalLayout с группами и orthogonal scrolling.
- Pre-fetching, recycle ячеек, конфигурация через
UICollectionView.CellRegistration. - Производительность: image decoding, drawing async.
- UICollectionViewFlowLayout — устарел для новых проектов.
- Ручная отрисовка через
drawRectна ячейках без необходимости.
🏋️ Упражнения (8)
- App Store-like экран. 3 секции: hero-карточка, horizontal carousel, grid.
- Diffable + анимация. Реализуйте drag-and-drop с анимацией.
- Pre-fetching. Реализуйте
UICollectionViewDataSourcePrefetchingдля подгрузки изображений. - Self-sizing. Ячейки с динамической высотой через Compositional Layout.
- Sticky headers. Реализуйте «прилипающие» заголовки секций.
- Lists API. Используйте
UICollectionLayoutListConfigurationдля table-like UI с swipe-actions. - Custom decoration. Добавьте подложку под секцию через
NSCollectionLayoutDecorationItem. - Производительность. Сделайте лист с 10 000 элементов и сложными ячейками — 60fps без даунгрейдов.
Углублённо в Notion
14
Анимации: UIView, CAAnimation, SwiftUI matched geometry
Анимации: UIView, CAAnimation, SwiftUI matched geometry
Анимации — это «душа» интерфейса. Apple отличается от конкурентов именно вниманием к движению. Хорошие анимации делают приложение премиальным.
🎯 Фокус vs можно отложить
- UIView.animate с spring — для большинства задач достаточно.
- CABasicAnimation, CAKeyframe — когда нужна тонкая настройка.
- Interactive transitions с UIPercentDrivenInteractiveTransition.
- SwiftUI:
matchedGeometryEffect, customAnimation,PhaseAnimator.
- Lottie — мощно, но добавляет вес. Используйте, если есть готовая анимация от дизайнеров.
- Hero и подобные библиотеки — на новых проектах достаточно нативных API.
🏋️ Упражнения (7)
- UIViewPropertyAnimator. Сделайте паузируемую анимацию.
- Spring. Подберите параметры spring для естественного движения карточки.
- Interactive dismiss. Свайп вниз — закрывает экран с интерактивной отменой.
- matchedGeometryEffect. Реализуйте hero-переход в SwiftUI.
- Lock Screen анимация. Повторите анимацию iOS 16 (см. мою статью).
- CAEmitterLayer. Сделайте конфетти при успешном действии.
- PhaseAnimator (iOS 17+). Анимация в несколько фаз без таймеров.
15
Графика: Core Graphics, Core Image, Metal, Shaders
Графика: Core Graphics, Core Image, Metal, Shaders
Уровень, который отличает обычные приложения от тех, у которых «вау-эффект». Шейдеры, Metal-Performance-Shaders, кастомная отрисовка — это конкурентное преимущество.
🎯 Фокус vs можно отложить
- SwiftUI
.colorEffect,.layerEffect— самый простой путь к шейдерам с iOS 17+. - Core Image для фильтров, Vision для распознавания.
- CALayer и его подклассы для тонкой работы с UI.
- Глубокая работа с Metal-командами — нужно для игр и пост-эффектов.
- Compute shaders — узкая ниша.
🏋️ Упражнения (6)
- SwiftUI Shader. Сделайте кнопку с эффектом «жидкого стекла» через
.layerEffect. - CIFilter. Примените blur и vignette к фото.
- CAGradientLayer. Сделайте анимированный gradient-background.
- CADisplayLink. Реализуйте плавную анимацию, синхронизированную с обновлением экрана.
- Vision. Распознайте текст с фото через
VNRecognizeTextRequest. - MetalKit. Нарисуйте треугольник через
MTKViewи собственный shader.
IV. Архитектура
Разделение ответственности, тестируемость, масштабируемость. Меньше boilerplate'а, больше пользы.
16
MVC → MVVM → VIPER → Clean → TCA
MVC → MVVM → VIPER → Clean → TCA
Архитектура — это не «выбрать VIPER потому что круто звучит». Это инструмент: для каких границ, какой команды и каких изменений вы оптимизируете.
🎯 Фокус vs можно отложить
- MVVM с binding'ами — самый ходовой паттерн на Junior/Middle.
- Clean Architecture: разделение domain / data / presentation.
- SOLID на практике, не в теории.
- Dependency Injection без фреймворков — composition root.
- The Composable Architecture — современный кандидат для SwiftUI-проектов.
- VIPER ради VIPER — много boilerplate'а, оправдан только в больших командах.
- «Идеальная» архитектура — её не существует.
📚 Что учить по уровням
Junior
- MVC по Apple — что лежит во ViewController, что в Model.
- Базовый MVVM: ViewModel и публичные свойства.
- SOLID на простых примерах (хотя бы S и D).
Middle
- MVVM с
@Observable; ViewModel testable, без UIKit-зависимостей. - Clean Architecture: разделение Domain / Data / Presentation.
- DI без фреймворков: composition root, протоколы в инициализаторе.
- Coordinator/Router для навигации.
- Знакомство с TCA на простом фиче.
Senior
- Применение нескольких архитектур осознанно: какой кусок какой.
- Грамотный технический долг: «уродливое сейчас → план рефакторинга».
- VIPER в больших командах с автогенерацией шаблонов.
- Trade-offs между TCA / MVVM / Clean — с замерами.
Tech Lead
- RFC-документ при изменении архитектуры команды.
- Стандарт: какие протоколы команда обязана выставлять.
- Onboarding-flow: новички осваивают архитектуру за < 2 недели.
Staff/Principal
- Кросс-командные паттерны: чтобы 5 продуктовых команд собирали единое приложение без хаоса.
- Стандарты для всей орг.: BFF-API, общий Auth-модуль, единый Analytics.
📊 Сравнение
graph LR MVC[MVC
Apple legacy] --> MVVM[MVVM
Junior/Middle] MVVM --> CLEAN[Clean
Middle/Senior] CLEAN --> VIPER[VIPER
Большие команды] CLEAN --> TCA[TCA
SwiftUI/функц.] CLEAN --> RIB[RIBs
Uber-style]
🏋️ Упражнения (8)
- MVVM. Реализуйте экран профиля с биндингами через
@Observable. - Clean. Разнесите код на 3 модуля: domain (use cases), data (repositories), presentation. Compile-time-проверка зависимостей.
- VIPER. Один экран на VIPER. Подсчитайте количество файлов — это даст почувствовать стоимость.
- TCA. Реализуйте feature через Reducer/State/Action. Напишите unit-тесты на reducer.
- DI без фреймворка. Composition root в AppDelegate, протоколы вместо классов в инициализаторах.
- Coordinator. Уберите весь navigation код из ViewController в Coordinator.
- Тестируемость. Покройте unit-тестами use case без UI-симуляторов.
- Миграция. Возьмите legacy-MVC экран и поэтапно мигрируйте на MVVM (без переписывания всего).
🌟 Стратегическое развитие (Senior+)
- Архитектурный RFC. На крупных проектах изменение архитектуры — это документ с обсуждением, тренадеоффами и планом миграции.
- Не «лучшая», а «уместная». Маленький стартап — простая MVVM. Холдинг с 50 разработчиками — модульная Clean. Не путайте.
- Контекст команды. Учитывайте: уровень разработчиков, время на onboarding, поддержку.
- Технический долг. Senior умеет принимать «уродливое сейчас, рефакторинг по плану». Перфекционизм убивает проекты.
18
Модуляризация: SPM, Tuist, XcodeGen
Модуляризация: SPM, Tuist, XcodeGen
Когда проект больше 100k строк, монолит на одном target становится невыносимым. Модули ускоряют сборку, изолируют зависимости и заставляют команду думать о границах.
🎯 Фокус vs можно отложить
- Swift Package Manager — стартовая точка для любой модуляризации.
- Tuist для генерации проектов из
Project.swift— устраняет merge conflicts в pbxproj. - Структура слоёв: Feature / Domain / Data / DesignSystem / CoreUtils.
- Public/Internal API — сознательное решение, что выставлять наружу.
- CocoaPods на новых проектах — SPM достаточно.
- Carthage — почти не используется.
🏋️ Упражнения (7)
- SPM локальный. Вынесите фичу в local SPM-package. Сравните время сборки.
- Tuist старт. Сгенерируйте проект из
Project.swift. - Feature module. Разбейте экран профиля:
ProfileFeature,ProfileUI,ProfileDomain. - Public API. Намеренно скройте внутренности через
internal. Используйте Sample app для тестирования. - Module Graph. Постройте граф зависимостей через
tuist graph. - Кэширование. Включите
tuist cacheи сравните время первой и последующих сборок. - Resource bundle. Передайте лок-строки в SPM-модуль через
Bundle.module.
🌟 Стратегическое развитие (Senior+)
- Стандарт команды. Договоритесь, как именно делятся модули, как именуются. Документируйте в CONTRIBUTING.md.
- Время сборки как метрика. Меряйте, сколько собирается incremental и clean. Цель — не дать им расти быстрее, чем растёт продукт.
- Sample apps. Каждая фича собирается отдельным mini-app — ускоряет dev-итерации в 10x.
19
System Design мобильного приложения
System Design мобильного приложения
Спроектировать «дизайн ВКонтакте на iOS» — это не про код. Это про слои данных, кэш, сценарии, ограничения сети. Самая популярная секция собесов на Senior+.
🎯 Фокус vs можно отложить
- Frame: контекст → ограничения → сценарии → API → данные → клиентская архитектура → углы.
- Кэширование (см. отдельный раздел) и offline-first.
- Pagination, real-time обновления (WS, push).
- Тулинг: feature flags, AB-тесты, аналитика.
- Безопасность ключей (Keychain, secure enclave).
- Глубоко в backend — knowing-your-place полезно.
- Распределённые системы — клиенту достаточно концепций.
🏋️ Упражнения (6)
- Дизайн ленты. Спроектируйте Twitter-like ленту: пагинация, кэш, real-time.
- Чат. Спроектируйте Telegram-like чат: оффлайн отправка, синхронизация, push.
- Загрузчик. Сервис загрузки файлов с приостановкой/возобновлением.
- Аналитика. Унифицируйте отправку событий, добавьте батчинг и retry.
- Платежи. Платёжный флоу с 3DS и idempotency keys.
- Виджет. Спроектируйте виджет с App Group + Background tasks обновлением.
🌟 Стратегическое развитие (Senior+)
- Технологическое влияние. На Staff/Principal вы — тот, кто делает технологические выборы (нативно vs кросс, новый стек, миграции). Эти решения отражаются на 100+ инженерах годами.
- Документация и RFC. Большие изменения должны жить как живой документ с argued trade-offs, не как «обсудили в slack».
- Обучение через примеры. Любой сложный системный выбор должен быть сопровождён demo-приложением и open-source примером для команды.
System Design в Notion
V. Данные и сеть
Обмен и хранение — самый частый источник багов в проде. Здесь нужно знать «слои», а не только API.
20
Networking: URLSession, REST, WebSocket, GraphQL, gRPC
Networking: URLSession, REST, WebSocket, GraphQL, gRPC
Сеть — самая «честная» в плане отзывов: либо пакеты ходят, либо нет. Знание уровней (TCP, TLS, HTTP, прикладной слой) экономит десятки часов дебага.
🎯 Фокус vs можно отложить
- URLSession (configuration, delegate, async API).
- Retry, exponential backoff, идемпотентность запросов.
- Codable + DTO + версионирование контрактов.
- WebSocket через
URLSessionWebSocketTask. - Логирование запросов и трекинг через interceptor-ы.
- Alamofire/Moya на новых проектах — нативного API хватает.
- Глубокий gRPC — нужен на специфичных проектах.
- Подробности TLS handshake — концептуально достаточно.
📚 Что учить по уровням
Junior
URLSession.shared.data(from:)через async/await.Codable, базовое декодирование JSON.- Обработка ошибок:
Result,do/catch.
Middle
- Typed API-клиент (
protocol APIClient, request-builder). - Retry + exponential backoff, идемпотентность.
- WebSocket через
URLSessionWebSocketTask. - Multipart upload с прогрессом.
Senior
- Interceptor’ы: логи, авторизация, рефреш токена, mocks.
- Cert/PK pinning, App Attest.
- HTTP/3 (QUIC), измерения latency.
- Контракты с бекендом: версионирование, обратная совместимость DTO.
Tech Lead
- Стратегия: REST vs GraphQL vs gRPC для команды.
- Контракт-тесты с backend, mock-server в CI.
🏋️ Упражнения (8)
- Network layer. Спроектируйте
protocol APIClientс типизированными request/response. - Retry с backoff. Реализуйте retry: 3 попытки, задержки 1s, 2s, 4s.
- Idempotency. Добавьте header
Idempotency-Keyк POST-запросам. - Multipart upload. Загрузите файл с прогрессом через
uploadTask. - WebSocket reconnect. Реализуйте автоматический reconnect при потере соединения.
- Логи запросов. Перехватите все запросы через
URLProtocolи сохраните в файл. - Mock server. Поднимите локальный mock через
swifterилиswift-nio, прогоните UI-тесты. - Cache headers. Используйте
ETag/If-None-Matchдля кэширования на клиенте.
В Notion
21
Хранение данных: UserDefaults, Keychain, CoreData, SwiftData, GRDB
Хранение данных: UserDefaults, Keychain, CoreData, SwiftData, GRDB
Выбор хранилища — это компромисс между удобством, производительностью и безопасностью. Не стоит хранить токены в UserDefaults и юзеров в Keychain.
🎯 Фокус vs можно отложить
- Когда что: UserDefaults (настройки), Keychain (секреты), File (бинарь), SQL (списки), CoreData/SwiftData (графы объектов).
- SwiftData — современный путь для новых проектов.
- Миграции схем (lightweight, ручные).
- Шифрование на уровне файла или базы.
- Realm/MagicalRecord на новых проектах — нативные альтернативы зрелее.
- Глубокая работа с FetchedResultsController — SwiftData упрощает.
📊 Карта хранилищ
graph TD
D[Что храним?] --> S{Тип}
S -->|настройки| U[UserDefaults]
S -->|токены| K[Keychain]
S -->|файлы| F[FileManager]
S -->|таблицы| Q[SQLite/GRDB]
S -->|граф объектов| C[CoreData/SwiftData]
S -->|кэш| CC[NSCache/Disk Cache]
🏋️ Упражнения (8)
- SwiftData CRUD. Создайте модель
@Model class Note. Сделайте список с фильтром. - Миграция. Добавьте новое поле в модель. Реализуйте lightweight migration.
- Keychain wrapper. Напишите свой
protocol SecureStorageповерх Security framework. - Бэкапы. Включите/выключите
isExcludedFromBackupдля папки кэшей. - FileCoordinator. Напишите безопасное чтение/запись файла из нескольких процессов.
- GRDB. Сделайте таблицу с FTS5 (full-text search) и реализуйте поиск.
- App Group + UserDefaults. Поделитесь настройками между приложением и виджетом.
- Шифрование. Сохраните JSON в файл, зашифрованный AES (CommonCrypto).
22
Кэширование и offline-first
Кэширование и offline-first
Кэш — это не NSCache в коде. Это стратегия: что хранить, когда обновлять, как инвалидировать. Cache invalidation — одна из «двух тяжёлых проблем CS».
🎯 Фокус vs можно отложить
- Стратегии: cache-aside, write-through, write-behind, refresh-ahead.
- HTTP caching: ETag, Cache-Control, max-age.
- Offline-first: локальная база как single source of truth.
- Конфликты данных: last-write-wins, CRDT.
- Полноценная синхронизация типа CouchDB — экзотика для большинства приложений.
🏋️ Упражнения (6)
- Repository pattern. Реализуйте
UserRepository, который сначала отдаёт из cache, потом обновляет из сети. - NSCache. Сделайте image cache с лимитом 50 MB.
- Disk cache. Сохраните JPEG на диск с TTL 24 часа.
- HTTP cache. Настройте
URLCacheс правильными заголовками. - Offline сценарий. Поставьте режим «без интернета». Приложение должно отображать данные из кэша и помечать «outdated».
- Optimistic UI. При лайке мгновенно обновите UI, отправьте запрос в фоне, при ошибке откатите.
VI. Качество
Тесты, инструменты диагностики, безопасность, производительность, доступность. То, что отличает «работает на ноутбуке» от прода.
23
Тестирование: Unit, UI, Snapshot, Test Plans
Тестирование: Unit, UI, Snapshot, Test Plans
Тесты — это не «галочка для CI», а инструмент быстрой обратной связи. Без них рефакторинг превращается в страх.
🎯 Фокус vs можно отложить
- Swift Testing (новый фреймворк) и XCTest.
- Mock vs Stub vs Spy vs Fake — понимать разницу.
- Snapshot-тесты для UI (swift-snapshot-testing).
- Test Plans для разных конфигураций.
- Покрытие как индикатор, не как KPI.
- BDD-фреймворки (Quick/Nimble) — на новых проектах SwiftTesting + Test Plans достаточно.
- Стопроцентное покрытие — миф, ведущий к плохим тестам.
🏋️ Упражнения (8)
- Swift Testing старт. Перепишите 5 XCTestCase в новый
@Testсинтаксис. - Mock сети. Подменяйте
URLProtocolв тестах для контролируемых ответов. - Snapshot. Зафиксируйте 3 состояния экрана профиля.
- UI test. Напишите end-to-end сценарий «логин → главная → выход».
- Тест async. Тестируйте actor с разными порядками операций.
- Параметризованные тесты. 10 кейсов через
arguments:. - Тестирование времени. Подменяйте
Dateчерез DI. - CI metric. Добавьте отчёт о покрытии в PR.
24
Debug, LLDB, Instruments, Memory Graph
Debug, LLDB, Instruments, Memory Graph
«print(...) везде» — это путь юниора. Senior находит баг через LLDB и Instruments в 10 раз быстрее.
🎯 Фокус vs можно отложить
- LLDB:
po,p,v,thread backtrace, breakpoint actions. - Memory Graph и Allocations Instrument.
- Time Profiler, Hangs, Hitches.
- Network Instrument, Animation Hitches.
- Сanonical breakpoints (
UIViewAlertForUnsatisfiableConstraints,-_NSAutoreleaseNoPool).
- Скриптование LLDB на Python — узкая ниша.
- Hopper/IDA — нужно при reverse engineering.
🏋️ Упражнения (7)
- Conditional breakpoint. Поставьте остановку, срабатывающую только когда
userId == 42. - Sound на breakpoint. Используйте action «Play sound» вместо
print. - Memory Graph. Найдите «фантомный»
UIViewController. - Time Profiler. Профилируйте старт приложения. Найдите 3 узких места.
- Hitches. Запустите Animation Hitches и поймайте дёрганый scroll.
- os_log. Перейдите с
printнаLogger. Просмотрите в Console.app. - LLDB chisel. Установите Facebook Chisel и используйте
vs(view dump).
25
Производительность: hangs, hitches, scrolling, app launch
Производительность: hangs, hitches, scrolling, app launch
Прирост 2 секунды к старту приложения у миллиона пользователей — это десятки тысяч сэкономленных часов в год.
🎯 Фокус vs можно отложить
- Метрики из MetricKit и App Store Connect (Hangs, Hitches, Disk writes).
- Cold start: что выполнять до first frame, что отложить.
- Image decoding на background.
- Бюджет аллокаций в горячих циклах.
- Бенчмарки через
XCTMetricиOSSignpost.
- Микрооптимизации без замеров — корень всех зол.
📚 Что учить по уровням
Middle
- Time Profiler в Instruments, чтение flame graph.
- Проблемы со скроллом: image decoding async, prefetching.
- Базовое профилирование cold start через
os_signpost.
Senior
- Hangs, Hitches Instrument; цель cold start < 400 мс.
- MetricKit в проде — собрать реальные метрики и встроить в свою аналитику.
- Памят-бюджет: snapshot Memory Graph, поиск утечек на CI.
- SwiftUI:
_printChanges(), оптимизация перерисовок.
Tech Lead
- Performance budget команды: метрики в CI, gate на регрессии.
- RUM (real user monitoring): связка MetricKit + Sentry / Firebase Performance.
- Объяснение перформанса бизнесу через метрики продукта.
Staff/Principal
- Орг-стандарт: единые SLA по перформансу, общие dashboards.
- Доклады/посты, чтобы команды учились на чужих кейсах.
🏋️ Упражнения (7)
- App launch <400ms. Замерьте через
OSSignpostInterval. Найдите 3 источника задержки. - Hangs. Поймайте main thread block в Instruments.
- Image decoding. Перенесите decode в background thread. Сравните FPS на скролле.
- Memory footprint. Снизьте пиковую память на 30%.
- SwiftUI body diff. Найдите тяжёлый body, разделите на subviews.
- Networking burst. Пакетируйте запросы при онбординге.
- MetricKit. Соберите real-world метрики и отправьте в свою аналитику.
🌟 Стратегическое развитие (Senior+)
- Performance budget. Договоритесь с командой о метриках (cold start, scroll FPS, memory). Включите в CI.
- Real user monitoring. Не только лабораторно, но и в проде — через MetricKit, Sentry, Firebase Performance.
- Перформанс как продукт. Уметь продать улучшения бизнесу через метрики (retention, conversion, ratings).
В Notion
26
Безопасность: Keychain, ATS, Code Signing, обфускация
Безопасность: Keychain, ATS, Code Signing, обфускация
«Защитите токен — не кладите в UserDefaults». Этот совет повторяют каждые полгода, но забывают про jailbreak detection, certificate pinning и runtime защиту.
🎯 Фокус vs можно отложить
- Keychain:
kSecAttrAccessible, sharing groups. - ATS, certificate pinning, public key pinning.
- Code Signing: provisioning profiles, entitlements, App ID.
- OWASP Mobile Top 10.
- Глубокая обфускация Swift — почти невозможна без сторонних инструментов.
- White-box cryptography — узкая ниша.
🏋️ Упражнения (6)
- Keychain wrapper. Сохраните токен с
kSecAttrAccessibleAfterFirstUnlock. - Cert pinning. Настройте pinning на public key через
URLSessionDelegate. - Биометрия. Используйте
LAContextдля подтверждения операции. - Jailbreak detection. Проверьте 5 признаков (без ложных срабатываний).
- Secure enclave. Сгенерируйте ключ в Secure Enclave и подпишите данные.
- App attest. Реализуйте проверку integrity приложения.
27
Доступность (VoiceOver), Dynamic Type, локализация
Доступность (VoiceOver), Dynamic Type, локализация
Доступность — не «фича для незрячих», это про UX в целом. Хорошее VoiceOver = хорошая семантика = удобный интерфейс для всех.
🎯 Фокус vs можно отложить
- VoiceOver labels, hints, traits.
- Dynamic Type на всех экранах.
- Локализация через
String Catalog(.xcstrings). - Множественное число и плюрализация.
- RTL-языки (арабский, иврит).
- Поддержка всех локалей сразу — лучше start small.
🏋️ Упражнения (6)
- VoiceOver сессия. Включите VoiceOver и пройдите 3 экрана своего приложения.
- Dynamic Type. Прогоните UI на самом большом размере шрифта (AX5).
- String Catalog. Перенесите .strings файлы в .xcstrings.
- Pluralization. Реализуйте «1 сообщение / 2 сообщения / 5 сообщений».
- Accessibility Inspector. Прогоните audit и исправьте все warnings.
- RTL test. Включите Hebrew и проверьте все экраны.
VII. DevOps и релизы
От «нажал кнопку — собралось» до «merge в main — улетело пользователям».
28
CI/CD: Fastlane, Xcode Cloud, GitHub Actions, Bitrise
CI/CD: Fastlane, Xcode Cloud, GitHub Actions, Bitrise
Хороший pipeline — это «git push → через 15 минут TestFlight у тестировщиков». Без него каждая сборка стоит 30 минут ручного труда.
🎯 Фокус vs можно отложить
- Fastlane:
match,gym,pilot,deliver. - Xcode Cloud — самый простой CI без серверов.
- GitHub Actions для запуска тестов.
- Кэширование: derived data, SPM, Tuist cache.
- Версионирование (semver, build number).
- Свои Mac-раннеры — дорогая инфраструктура, начните с облачных.
🏋️ Упражнения (7)
- Fastlane match. Настройте управление сертификатами через приватный git-репо.
- Beta lane. Сделайте
fastlane betaдля отправки в TestFlight. - GitHub Actions. Запускайте тесты на каждый PR.
- Кэш SPM. Уменьшите время сборки в 2 раза за счёт кэша.
- Build number автоинкремент. Из тегов git.
- Slack уведомление. После успешного билда отправьте в канал.
- Xcode Cloud. Поднимите минимальную конфигурацию: тест + архив.
29
App Store Connect, TestFlight, релизный процесс
App Store Connect, TestFlight, релизный процесс
Понимать релизный процесс — значит знать, как избежать reject'а на ровном месте и как дотянуть до публикации без 3 дополнительных дней ожидания.
🎯 Фокус vs можно отложить
- App Store Connect API.
- TestFlight группы и phased release.
- App Review Guidelines (особенно секции о приватности).
- Privacy nutrition labels, App Tracking Transparency.
- Подготовка скриншотов (см. мою статью про status bar 9:41).
- Apple Search Ads — нужно при росте маркетинга.
🏋️ Упражнения (5)
- API. Получите список билдов через
App Store Connect API. - TestFlight ad-hoc. Раздайте билд внешним тестерам.
- Phased release. Включите 7-дневный rollout.
- Privacy labels. Заполните корректно для своего приложения.
- Скриншоты. Сгенерируйте через
fastlane snapshot.
30
Crash analytics, мониторинг, аналитика
Crash analytics, мониторинг, аналитика
«Зелёная сборка» не значит «работает». Crash-free пользователей — главная метрика стабильности после публикации.
🎯 Фокус vs можно отложить
- Crashlytics / Sentry / Bugsnag — выбор и интеграция.
- Symbolication, dSYM upload в CI.
- Custom keys и breadcrumbs.
- Дашборды: crash-free %, ANR, slow frames.
- Аналитика событий (Amplitude, Mixpanel, Firebase).
- Свой crash-reporter — нет смысла, всё уже сделано.
🏋️ Упражнения (5)
- Sentry SDK. Установите, отправьте искусственный краш.
- dSYM upload. Автоматизируйте через CI.
- Breadcrumbs. Логируйте 10 ключевых событий до краша.
- MetricKit. Подключите hangs и hitches к мониторингу.
- Аналитика. Спроектируйте универсальный
EventTrackerс батчингом.
VIII. Алгоритмы и паттерны
Базовый CS не уходит — особенно на собесах в большие компании.
31
Алгоритмы, структуры данных, Big-O в задачах
Алгоритмы, структуры данных, Big-O в задачах
Алгоритмическая секция — стандарт собесов в Яндекс/Avito/VK/Ozon. Не заучите 200 задач — поймите 8 паттернов.
🎯 Фокус vs можно отложить
- Two pointers / sliding window.
- Hash map / set для O(1) поиска.
- BFS / DFS на графе и матрице.
- Бинарный поиск (включая по ответу).
- Dynamic programming (на 1D, 2D).
- Backtracking.
- Heap / priority queue.
- Union-Find (DSU).
- Сегментные деревья, fenwick — олимпиадная экзотика.
- Сложные жадные на 7+ строк — редко спрашивают.
🏋️ Упражнения (10 задач)
- Two Sum. O(n) через hash map.
- Longest substring without repeating. Sliding window.
- Number of Islands. BFS/DFS на матрице.
- Search in Rotated Sorted Array. Бинпоиск с условием.
- House Robber. Базовое DP.
- Coin Change. DP с возвратами.
- Word Break. DP + строки.
- Top K Frequent Elements. Heap.
- Friend Circles. Union-Find.
- Generate Parentheses. Backtracking.
На бусти — большая база задач
32
Паттерны проектирования (GoF + iOS-специфика)
Паттерны проектирования (GoF + iOS-специфика)
23 паттерна GoF — ориентир, не катехизис. В iOS чаще востребованы: Singleton (с осторожностью), Observer/Delegate, Builder, Factory, Strategy, Decorator, Coordinator.
🎯 Фокус vs можно отложить
- Делегирование, target-action, ответственная цепочка.
- Observer (NotificationCenter, KVO, Combine, AsyncSequence).
- Builder, Factory Method, Abstract Factory.
- Strategy и Decorator.
- iOS: Coordinator, Repository, Use Case.
- Visitor, Memento, Mediator — редко в чистом виде.
🏋️ Упражнения (5)
- Builder для NSAttributedString. Сделайте текучий API.
- Strategy. Разные алгоритмы сортировки списка как стратегии.
- Decorator. Логирование запросов через декоратор API-клиента.
- Observer. Сравните NotificationCenter, Combine, AsyncSequence на одной задаче.
- Singleton. Покажите, почему он мешает тестам, и замените на DI.
IX. AI-направление
В 2026 году игнорировать AI — значит проигрывать в 3-5 раз тем, кто им пользуется. Раздел про инструменты, промпты и on-device ML.
33
Claude Code, Cursor, Copilot, MCP — настройка и работа
Claude Code, Cursor, Copilot, MCP — настройка и работа
AI-ассистент уровня Claude Code не «генерирует код» — он становится твоим pair-програмистом. Конфигурация решает: толковая настройка экономит 10-15 часов в неделю.
🎯 Фокус vs можно отложить
- Claude Code (CLI) и его hooks/slash-команды.
- CLAUDE.md как «контракт проекта» с агентом.
- MCP-серверы (Model Context Protocol) для интеграций.
- Cursor: rules, settings, agent mode.
- GitHub Copilot для inline-completions.
- Промпт-инженерия (см. следующий раздел).
- Тренировка собственных моделей — узкая ниша.
- Прыжки между 5 ассистентами — выберите 1-2 главных.
⚡ Быстрая установка Claude Code
Минимальная конфигурация для iOS-проекта. Создаётся CLAUDE.md в корне, добавляются hook'и и MCP-сервер для Xcode Build.
# 1. Установка npm install -g @anthropic-ai/claude-code # 2. Запуск из корня проекта cd ~/Projects/MyApp claude # 3. Внутри сессии — инициализировать CLAUDE.md /init # 4. Настроить permissions для безопасных команд # settings.json: allow xcodebuild, swift, brew, git status
CLAUDE.md должен описывать: архитектуру, конвенции имён, тестовые команды, запрещённые операции.
🔌 MCP-серверы для iOS-разработки
Расширяют возможности Claude Code: даёт доступ к Xcode, симулятору, App Store Connect API.
# MCP для управления симулятором { "mcpServers": { "xcode-simulator": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-simulator"] }, "appstore": { "command": "asc-mcp-server" } } }
🏋️ Упражнения (8)
- CLAUDE.md. Опишите проект в 200 строк: архитектура, тесты, стиль кода, запрещённые операции.
- Slash-команда. Создайте
/review, который проводит ревью текущего PR по чек-листу. - Hook на Stop. При завершении агента запустите
swiftlint. - MCP simulator. Подключите MCP, через который Claude Code запускает приложение в симуляторе.
- Cursor rules. Настройте
.cursor/rulesс правилами для iOS-проекта. - Сравнение. Сделайте одну фичу через Claude Code и через Cursor agent. Сравните скорость и качество.
- Subagent. Создайте subagent
@code-reviewerс узкой задачей. - Pre-commit AI hook. AI проверяет изменения перед коммитом и предлагает улучшения.
🌟 Стратегическое развитие (Senior+)
- Команда + AI. Договоритесь о правилах: что отдаём AI, что нет (security-критичный код, бизнес-логика).
- Свои MCP-серверы. Если в команде уникальные инструменты — заверните в MCP, чтобы AI работал с ними напрямую.
- AI-onboarding. Новички осваивают кодбазу через диалог с агентом, который знает ваш CLAUDE.md.
- AI-driven docs. Документация автогенерируется из кода и проверяется на актуальность через AI.
🛠 Что такое Skills и зачем они нужны
Skills (Anthropic Claude Skills) — переиспользуемые наборы инструкций + кода, которые делают AI-агента «специалистом» по конкретной задаче. Аналог macOS Shortcuts, но для агента: набор файлов SKILL.md + опциональные скрипты, которые агент подгружает по требованию.
- Назначение: упаковать «как мы это делаем» — стиль кода, шаблоны PR, проверка лицензий — чтобы агент применял рутинные операции одинаково.
- Состав:
SKILL.mdс описанием +scripts/+templates/. Загружается лениво, не съедает контекст до момента вызова. - Примеры: swift-test-author (генерация тестов в стиле проекта), pr-reviewer (ревью по чек-листу команды), arch-rfc-writer (черновик RFC по шаблону).
- Где хранить: локально в репозитории
.claude/skills/или в Anthropic Console для всех агентов.
🔌 MCP — Model Context Protocol на пальцах
MCP — открытый стандарт для подключения внешних источников данных и инструментов к AI-ассистентам (как USB для AI). Сервер MCP предоставляет агенту: resources (читаемый контекст), tools (вызываемые действия), prompts (готовые шаблоны).
iOS-полезные MCP-серверы:
- modelcontextprotocol/servers — официальная коллекция MCP-серверов (filesystem, github, postgres, slack, sqlite, time).
- ios-simulator-mcp — MCP для управления симулятором iOS (boot/shutdown/screenshot/install).
- XcodeBuildMCP — управление Xcode-сборкой, тестами, симуляторами.
- xcode-mcp-server — пакетные операции с Xcode-проектом.
- github/github-mcp-server — официальный сервер для работы с GitHub PR/issues/CI.
- AppStoreConnectMCP — App Store Connect API через MCP.
- mcp-package-version — следит за версиями SPM-пакетов.
- awesome-mcp-servers — каталог 500+ серверов.
Как подключить в Claude Code:
claude mcp add-json xcode-simulator '{
"command": "npx",
"args": ["-y", "ios-simulator-mcp"]
}'
📚 Популярные репозитории и статьи
AI-агенты и ассистенты
- anthropics/claude-code — официальный CLI Claude Code.
- anthropic-quickstarts — стартовые проекты, в т.ч. computer-use agent.
- getcursor/cursor — Cursor IDE.
- sourcegraph/cody — open-source ассистент с Code Search.
- Open Interpreter — локальный agent с code execution.
- OpenHands (ex OpenDevin) — open-source автономный software engineer.
- aider — CLI-ассистент с Git-flow.
- Cline — VS Code agent с auto-approve.
- Roo Code — fork Cline с расширенной кастомизацией.
- continue.dev — open-source Copilot для VS Code/JetBrains.
iOS / Swift × AI
- apple/swift-mcp-sdk — официальный SDK Apple для MCP на Swift.
- MacPaw/OpenAI — клиент OpenAI API на Swift.
- SwiftAnthropic — Swift SDK для Anthropic API.
- exyte/AIChat — UI-компоненты чата для AI-приложений.
- huggingface/swift-transformers — запуск трансформеров на iOS.
- WhisperKit — on-device транскрипция через Whisper + Core ML.
- mlx-swift — Apple ML-фреймворк, родственник PyTorch для M-серии.
- awesome-apple — каталог Apple/Swift инструментов.
Awesome-списки
- awesome-mcp-servers — 500+ MCP-серверов.
- awesome-mcp-clients — клиенты MCP.
- Awesome-LLM — общая база по LLM.
- awesome-chatgpt — инструменты вокруг ChatGPT.
- Awesome-CoreML-Models — готовые модели для iOS.
- awesome-production-ml — деплой ML в проде.
Статьи · английский
- Anthropic · Claude Code best practices
- Anthropic · Building effective agents
- Anthropic · How we build Claude Skills
- MCP · Introduction (официальная)
- Cursor · Agent mode documentation
- GitHub blog · Copilot tag
- Simon Willison · LLM blog (must-read)
- Every · Chain of Thought (Dan Shipper)
- LogRocket · Integrating MCP into an iOS app
- NSHipster · Foundation Models
Статьи · русский (Habr и др.)
34
Prompt engineering для iOS-разработчиков
Prompt engineering для iOS-разработчиков
Хороший промпт = хороший контекст. Не «напиши код для логина», а «вот мой UseCase-протокол, вот ошибки сети, реализуй с retry и логированием».
🎯 Фокус vs можно отложить
- Контекстные подсказки: roles, examples, constraints.
- Поэтапная декомпозиция (chain-of-thought).
- Передача файлов и схем через @-меньки/attachments.
- Iterative refinement — лучше 5 итераций короткими промптами.
- Знать слабые места моделей (галлюцинации API, устаревшие фреймворки).
- «Магические» формулировки — большинство трюков уже не нужны на современных моделях.
🏋️ Упражнения (6)
- One-shot bad → good. Возьмите свой реальный плохой промпт и перепишите его в 3 итерации.
- Шаблон рефакторинга. «Возьми этот код, [роль reviewer], сохраняя API, …». Сравните результаты.
- Декомпозиция. Большая задача → 5 промптов вместо одного.
- Examples-based. Дайте 2 примера правильных тестов и попросите написать аналогичный.
- Verification. Заставьте AI самого проверить результат на чек-листе.
- System prompt в CLAUDE.md. Ограничьте поведение агента: «не используй force unwrap», «всегда добавляй mock».
35
On-device ML: Foundation Models, Core ML, Vision, Create ML
On-device ML: Foundation Models, Core ML, Vision, Create ML
Apple Intelligence сделала on-device LLM мейнстримом. Foundation Models — ваш входной билет в локальный AI без серверов.
🎯 Фокус vs можно отложить
- Foundation Models framework — генерация текста на устройстве.
- Core ML: интеграция готовых моделей (.mlmodel/.mlpackage).
- Vision: распознавание объектов, текста, лиц.
- Natural Language: язык, тональность, лемматизация.
- Create ML для дообучения на своих данных.
- Тренировка с нуля больших моделей — узкая ниша.
- Custom Metal-kernels для CoreML — нужно при оптимизации.
🏋️ Упражнения (6)
- Foundation Models. Сгенерируйте summary текста через
SystemLanguageModel. - Vision OCR. Распознайте текст с фото через
VNRecognizeTextRequest. - Sentiment. Определите тональность отзыва через
NLTagger. - Image classification. Классифицируйте картинки готовой моделью с CoreML.
- Create ML. Обучите классификатор «кошки/собаки» на своих фото.
- Стриминг. Streaming-ответ от Foundation Models с обновлением UI токен за токеном.
В Notion
X. Карьера и софт-скилы
На Senior+ код пишет 30% времени. Остальное — коммуникация, влияние, решения.
36
Soft skills, коммуникация, менторство
Soft skills, коммуникация, менторство
«Сильный технарь, но слабый коммуникатор» — частая причина застоя на Middle-Senior.
🎯 Фокус vs можно отложить
- Письменная коммуникация: PR-описания, RFC, постмортемы.
- Конструктивный код-ревью: hard on idea, soft on author.
- Эстимейты: декомпозиция, риски, буферы.
- Менторство джуниоров.
- Принятие feedback без обиды.
- Курсы публичных выступлений на 100 человек — нужно ситуативно.
🌟 Стратегическое развитие (Senior+)
- Влияние без власти. На Lead/Staff вы влияете, не приказывая. Это про argued posts, demo, RFC.
- Сеть. Конференции, твиттер, опен-сорс — возможности приходят через людей.
- Менторство как мультипликатор. 5 учеников = 5 параллельных «вы».
- Энергия и приоритеты. Senior умеет говорить «нет» и не сгорать.
37
Карьерная лестница: Trainee → Staff/Principal
Карьерная лестница: Trainee → Staff/Principal
Каждый уровень — это смена не «количества знаний», а сферы влияния. Trainee делает задачу, Junior — фичу, Middle — модуль, Senior — направление, Lead — команду, Staff — продукт/компанию.
🎯 Что меняется на каждом уровне
- Trainee → Junior: от «помоги, сломалось» к «сделал сам, спросил review».
- Junior → Middle: от «сделал фичу» к «спроектировал модуль и закрыл углы».
- Middle → Senior: от «решил задачу» к «выбираю, какие задачи делать и почему».
- Senior → Lead: от «себя» к «команде»: процессы, найм, грейды.
- Lead → Staff/Principal: от «одной команды» к «организации»: стандарты, тренды, технологический PR.
Подробная матрица компетенций по уровням — ниже в разделе «Матрица».
38
Подготовка к собеседованиям
Подготовка к собеседованиям
Собес = алгоритмы + Swift/iOS + System Design + culture fit + вопросы про опыт. К каждому стоит готовиться отдельно.
🎯 Что качаем под собес
- Алгоритмы: 80-100 задач из 8 паттернов (см. раздел 31).
- iOS: Concurrency, ARC, UIKit/SwiftUI, архитектура.
- System Design: разделы 19, 20, 22.
- Поведенческие: STAR-формат, заранее подготовленные истории.
- Вопросы к ним: 3 серьёзных вопроса в каждом раунде.
Главный набор для подготовки
Я собрал большой хаб именно для собеседований. Если бы можно было выбрать только одну ссылку — возьмите эту.
Зарплаты, матрица, глоссарий
Финальная сборка: вилки по уровням, матрица компетенций для самопроверки и термины.
Зарплатные вилки iOS · 2024–2026
Цифры — медиана по российскому рынку (Habr Career, GetMatch, Авито/Яндекс/VK). Динамика и подробности — в посте на канале: «Динамика зарплат разработчиков 2023» (@iosdev/1099), а также свежий обзор в @iosdev/921.
Выше — российский рынок. На зарубежных контрактах вилки сильно шире (Senior часто $80-160k/год, Staff $180-300k/год). Регулярно публикую свежую аналитику в @iosdev с реальными офферами и трендами рынка.
Матрица компетенций
Кликните по уровню в таблице или в панели сверху — столбец подсветится. Наведите на ячейку — справа покажем детально, что значит этот уровень для конкретного навыка. ● — обязательно, ✓ — желательно, — — придёт само с практикой.
- Avito · Playbook — открытая матрица грейдов
- iOS Developer Roadmap (GitHub) — карта тем
- roadmap.sh / iOS — стандарт сообщества
- Bohdan Orlov · iOS Roadmap — старейший roadmap
- Skyeng · матрица для разработчиков
- Dodo Engineering · уровни инженеров
- Яндекс · грейды разработчиков
- progression.fyi — каталог матриц компаний
- Engineering Ladders — общий шаблон
- Pat Kua · Tech Lead definition
| Компетенция | Trainee | Junior | Middle | Senior | Lead | Staff |
|---|
Глоссарий ключевых терминов
- ARC
- Automatic Reference Counting — автоматический подсчёт ссылок. Освобождает объект, когда у него 0 strong-ссылок.
- actor
- Тип в Swift, гарантирующий serialised access к своему состоянию.
- @MainActor
- Глобальный actor, привязывающий выполнение к main queue.
- Sendable
- Маркерный протокол для типов, безопасных для пересечения isolation domains.
- Existential
- Тип «any P», коробка для произвольной реализации протокола в runtime.
- Opaque
- Тип «some P», скрывающий конкретный тип, известный компилятору.
- PAT
- Protocol with Associated Types — протокол с ассоциированными типами.
- Diffable Data Source
- API для UICollectionView/UITableView с автоматическими анимациями через snapshot.
- Compositional Layout
- Декларативный layout для UICollectionView: items → groups → sections.
- Result Builder
- Декларативный синтаксис, как в SwiftUI body. Через
@resultBuilder. - Keychain
- Хранилище секретов, изолированное от приложения и зашифрованное системой.
- ATS
- App Transport Security — требование HTTPS с TLS 1.2+.
- MetricKit
- Фреймворк сбора метрик стабильности и производительности с реальных устройств.
- MCP
- Model Context Protocol — стандарт интеграции AI-ассистентов с внешними инструментами.
- SPM
- Swift Package Manager — менеджер пакетов от Apple.
- Tuist
- Инструмент генерации Xcode-проекта из swift-описания.
- TCA
- The Composable Architecture от Point-Free — Reducer/State/Action для SwiftUI.
- RFC
- Request For Comments — документ с предложением технического изменения.
Хочешь ускорить путь?
Мой Boosty — это премиум-материалы (deep dives, навигация в SwiftUI, system design), а Tribute — удобная альтернатива оплаты. Telegram — основной канал общения и анонсов.