🚀 В IT ценится не перфекционизм, а движение вперёд, и если вы давно откладывали обучение — самое время начать.
❤️ Proglib Academy продлевает розыгрыш MacBook Pro 14 до 30 ноября!
Что нужно:
⚡️ выбрать курс;
⚡️ пройти минимум две недели обучения (можно за два вечера);
⚡️ написать куратору #розыгрыш;
⚡️ забрать макбук.
🎓 Курсы, которые участвуют
👉 Участвовать
❤️ Proglib Academy продлевает розыгрыш MacBook Pro 14 до 30 ноября!
Что нужно:
⚡️ выбрать курс;
⚡️ пройти минимум две недели обучения (можно за два вечера);
⚡️ написать куратору #розыгрыш;
⚡️ забрать макбук.
🎓 Курсы, которые участвуют
👉 Участвовать
ЭЛТ-мониторы — это размытые края, линии сканирования и лёгкое свечение. Такой эффект можно воспроизвести в Compose с помощью
GraphicsLayer, градиентов и размытия.🔹 Базовый принцип
Мы один раз записываем контент во внеэкранный буфер и многократно перерисовываем его разными слоями.
val graphicsLayer = rememberGraphicsLayer()
Box(Modifier.drawWithContent {
graphicsLayer.record { drawContent() }
}) {
content()
}
Теперь
drawLayer(graphicsLayer) можно использовать в любых эффектах.🔹 Линии сканирования
Создаём повторяющиеся градиенты — вертикальные и горизонтальные:
private fun DrawScope.drawScanLines(alpha: Float, blend: BlendMode) {
val c = Colors.Black.copy(alpha)
drawRect(
brush = Brush.verticalGradient(
0f to c, 0.4f to c, 0.4f to Colors.Transparent, 1f to Colors.Transparent,
tileMode = TileMode.Repeated, endY = 10f
),
blendMode = blend
)
}Добавляем их поверх слоя:
.drawBehind {
layer {
drawLayer(graphicsLayer)
drawScanLines(alpha = 1f, blend = BlendMode.DstOut)
}
}DstOut вычитает градиент и создаёт характерный "CRT-срез".🔹 Размытие и свечение
Для реалистичного свечения рисуем несколько слоёв с разным blur/scale/alpha:
val blurLayers = listOf(
Triple(5.dp, .3f, 1.02f to 1.03f),
Triple(0.dp, .8f, 1f to 1f),
Triple(10.dp, .6f, 1.001f to 1f),
)
Каждый слой:
Box(
Modifier
.matchParentSize()
.blur(blur, BlurredEdgeTreatment.Unbounded)
.graphicsLayer { scaleX = scale.first; scaleY = scale.second; this.alpha = alpha }
.drawBehind {
layer {
drawLayer(graphicsLayer)
drawScanLines(1f, BlendMode.DstOut)
}
}
)
🔹 Дрожание экрана
var shake by remember { mutableStateOf(Offset.Zero) }
LaunchedEffect(Unit) {
while (true) {
shake = Offset(
Random.nextFloat() * Random.nextInt(-1, 1),
Random.nextFloat() * Random.nextInt(-1, 1),
)
delay(32)
}
}И применяем:
.graphicsLayer {
translationX = shake.x
translationY = shake.y
}#PixelPerfect #MiddlePath #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
🤖 Нужны ли UI-тесты в мобильной разработке
Одни уверяют:
«UI-тесты — это инвестиция. Они ловят самые подлые баги и экономят время всей команде!»
Другие отвечают:
«Писать UI-тесты дольше, чем сам экран. Ломаются от любого чиха. Зачем оно вообще?»
А правда — где-то между стабильным билдом и бесконечным падением тестов в CI.
А ты что думаешь?💬
❤️ — Пишу UI-тесты — люблю надёжность
👍 — Не пишу — быстрее руками проверить
🤝 — Идеально: только критические сценарии
🐸 Библиотека мобильного разработчика
#междусобойчик
Одни уверяют:
«UI-тесты — это инвестиция. Они ловят самые подлые баги и экономят время всей команде!»
Другие отвечают:
«Писать UI-тесты дольше, чем сам экран. Ломаются от любого чиха. Зачем оно вообще?»
А правда — где-то между стабильным билдом и бесконечным падением тестов в CI.
А ты что думаешь?
❤️ — Пишу UI-тесты — люблю надёжность
👍 — Не пишу — быстрее руками проверить
🤝 — Идеально: только критические сценарии
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤4🤝2
Старший iOS разработчик / Senior iOS разработчик — от 300 000 ₽, гибрид (Санкт-Петербург)
Android Developer | Middle+ - Senior — до 350 000 ₽, удалёнка
iOS Developer — от 270 000 до 300 000 ₽, удалёнка
Senior Android Developer — от 4 000 до 6 000 $, удалёнка
Senior iOS Developer (Swift) — от 4 500 до 5 000 $, удалёнка
#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
А вы знали, что почти все ViewModels нестабильны?
Когда мы только изучаем Compose,
нас учат использовать стабильный класс, а не нестабильный.
Но ViewModels нестабильны. Так почему же никто ничего не говорит о том, что мы используем нестабильные ViewModels?
🔹 Как Compose определяет стабильность?
Компилятор Compose считает класс стабильным, если:
val/var) неизменяемы (val).MutableState<T>).Взгляните на примеры:
// Стабильный класс
data class Stable(
val a: Int, // Стабильно
val b: MutableState<Int>, // Стабильно, отслеживается Compose
val c: SnapshotStateList<Int> // Стабильно, отслеживается Compose
)
// Нестабильный класс
data class Unstable(
var b: Int // Нестабильно из-за `var`
)
// "Неопределенная" стабильность
data class Runtime(
val i: Interface // Компилятор не знает, какая реализация будет на runtime.
)
Но есть важный нюанс: это правило работает только внутри модуля, где подключен компилятор Compose.
🔹 Что происходит на границах модулей?
Допустим, вы создали стабильную
data class в слое данных (data) и внедрили её в ViewModel в слое презентации.Логично ожидать, что
ViewModel тоже будет стабильным. Но на практике — нет!Compose-компилятор в модуле презентации не может заглянуть в модуль данных, чтобы проверить стабильность вашего класса. Поэтому он перестраховывается и помечает любой класс извне как нестабильный.
А раз наш
ViewModel зависит от репозиториев и UseCase из других модулей (domain/data), то и он сам автоматически становится нестабильным.🔹 Так почему же нестабильный ViewModel — это норма?
Ответ простой и лежит на поверхности: мы не передаем сам ViewModel в дочерние композаблы.
Вместо этого мы:
1. Создаем
ViewModel один раз наверху (например, в NavGraph).2. Коллектим его состояние (
state), которое уже является стабильным.3. Пробрасываем это стабильное состояние вниз по дереву композиции.
@Composable
fun Screen(viewModel: TestViewModel) { // ViewModel нестабилен, и это ок
val state by viewModel.state.collectAsState() // Состояние - стабильно
Child(state) // Передаем стабильный state
}
@Composable
fun Child(state: TestState) { // Стабильный пропс -> рекомпозиции оптимизированы
Text(state.data)
}
Compose-рантайм следит за изменениями в
state. Сам ViewModel как объект не «пробрасывается» глубже и не триггерит лишних рекомпозиций.🔹 Итоги
Так что можете спать спокойно — с вашим кодом всё в порядке.
#АрхитектурныйКод #MiddlePath #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1❤🔥1🔥1🤔1
🎓 Экспресс-курс «Математика для Data Science» стартует 4 декабря
Этот курс для вас, если вы:
🧑💻 Программист
Когда нужно понять, что происходит «под капотом» ML-алгоритмов.
📊 Начинающий DS / аналитик / студент
Чтобы закрыть теорию, подтянуть фундамент и собрать портфолио.
📈 Смежный специалист
Чтобы уверенно работать с моделями, статистикой и гипотезами.
🎁 Сейчас лучший момент стартовать:
— скидка 40% на курс до конца ноября
— можно пройти бесплатный тест на знание основ математики
👉 Записаться на курс
Этот курс для вас, если вы:
🧑💻 Программист
Когда нужно понять, что происходит «под капотом» ML-алгоритмов.
📊 Начинающий DS / аналитик / студент
Чтобы закрыть теорию, подтянуть фундамент и собрать портфолио.
📈 Смежный специалист
Чтобы уверенно работать с моделями, статистикой и гипотезами.
🎁 Сейчас лучший момент стартовать:
— скидка 40% на курс до конца ноября
— можно пройти бесплатный тест на знание основ математики
👉 Записаться на курс
Please open Telegram to view this post
VIEW IN TELEGRAM
adb shell am broadcast – отправка broadcast-интентов из командной строкиМощный инструмент для тестирования обработки broadcast-сообщений в вашем приложении без необходимости эмулировать системные события через UI.
# Отправка кастомного broadcast
adb shell am broadcast -a "com.yourapp.action.CUSTOM_ACTION"
# С дополнительными данными
adb shell am broadcast -a "com.yourapp.action.CUSTOM_ACTION" --es "key" "value"
1. Тестирование системных событий:
# Имитация подключения зарядки
adb shell am broadcast -a android.intent.action.ACTION_POWER_CONNECTED
# Имитация изменения языка системы
adb shell am broadcast -a android.intent.action.LOCALE_CHANGED
2. Тестирование кастомных broadcast receivers:
# Отправка с дополнительными extras
adb shell am broadcast -a "com.yourapp.action.DATA_REFRESH" \
--es "refresh_type" "full" \
--ei "user_id" 12345 \
--ez "force_update" true
3. Отправка конкретному пакету:
# Только для вашего приложения
adb shell am broadcast -a "com.yourapp.action.TEST" -n com.yourapp.package/.ReceiverName
Уведомление о низком заряде:
adb shell am broadcast -a android.intent.action.BATTERY_LOW
Изменение конфигурации:
adb shell am broadcast -a android.intent.action.CONFIGURATION_CHANGED
События времени:
adb shell am broadcast -a android.intent.action.TIME_SET
Какие broadcast-ы вы чаще всего тестируете через командную строку?
#буст #MiddlePath #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝1
This media is not supported in your browser
VIEW IN TELEGRAM
Чем важна математика расскажет Мария Тихонова - кандидат компьютерных наук, руководитель исследовательского направления SberAI, доцент факультета компьютерных наук и преподаватель НИУ ВШЭ на курсе «Математика для Data Science» от Proglib Academy.
Курс предусматривает выполнение практического проекта с фидбеком от экспертов. За проект можно взять темы:
• обучите градиентный спуск для предсказания цен на квартиры
• создадите классификатор тональности или тематики текста
• построите простую рекомендательную систему на матричных разложениях
Бонусы:
- скидка 40% до 30 ноября
- если оплатить до конца ноября, получите курс «Базовая математика» в подарок
➡️ Пройти бесплатный тест на знание математики
Записаться на курс
Please open Telegram to view this post
VIEW IN TELEGRAM
Сегодня большинство компаний разрабатывают мобильные приложения, поэтому умение работать с ними становится почти обязательным скиллом. Мобильное приложение — это не просто веб в миниатюре, это отдельный мир со своей архитектурой, устройствами, операционными системами и ограничениями.
В статье автор расскажет об основных особенностях мобильных платформ, с которыми тестировщики сталкиваются на практике.
#свежак #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👾 Compose Stability Analyzer — аналитика стабильности композабл в Android Studio
Compose Stability Analyzer анализирует стабильность ваших композабл функций Jetpack Compose в режиме реального времени непосредственно в Android Studio или IntelliJ. Он помогает понять, почему компонуемая функция стабильна или нестабильна, и предоставляет подробную информацию благодаря трассировке и журналированию рекомпозиции.
Кроме того, вы можете отслеживать причину, по которой ваша компонуемая функция запускает рекомпозицию, с помощью аннотации
💻 Compose Stability Analyzer на GitHub
🔸 Курс «Специалист по ИИ»
🔸 Получить консультацию менеджера
🔸 Сайт Академии 🔸 Сайт Proglib
🐸 Библиотека мобильного разработчика
#буст #Android
Compose Stability Analyzer анализирует стабильность ваших композабл функций Jetpack Compose в режиме реального времени непосредственно в Android Studio или IntelliJ. Он помогает понять, почему компонуемая функция стабильна или нестабильна, и предоставляет подробную информацию благодаря трассировке и журналированию рекомпозиции.
Кроме того, вы можете отслеживать причину, по которой ваша компонуемая функция запускает рекомпозицию, с помощью аннотации
TraceRecomposition и экспортировать отчёты о стабильности и совместимости с помощью тасков Gradle для просмотра изменений.🔸 Курс «Специалист по ИИ»
🔸 Получить консультацию менеджера
🔸 Сайт Академии 🔸 Сайт Proglib
#буст #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰1
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему происходит ошибка "index out of range"?
Anonymous Quiz
8%
Неправильное использование weak self
38%
Race condition между обновлением данных и прокруткой
2%
Проблема с асинхронной загрузкой данных
33%
Данные обновляются, но таблица еще не обновила индексы
19%
Посмотреть ответ
This media is not supported in your browser
VIEW IN TELEGRAM
🤖 AI сейчас на пике — и математика снова в центре внимания.
Одна из топовых экспертов, кто сегодня участвует на AIJ, преподаёт у нас.
Мария Тихонова — PhD по Computer Science, руководитель направления в SberAI и доцент ВШЭ. Она работает с LLM каждый день и объясняет математику так, как она реально применяется в AI.
🔥 Экспресс-курс «Математика для DS» — 8 недель, чтобы закрыть пробелы и уверенно проходить собесы.
🎁 До 30 ноября:
→ скидка 40%
→ курс «Школьная математика» в подарок при оплате
→ бесплатный тест на знание основ математики
👉 Записаться на курс
«На конференции AIJ только и разговоров, что о AI и математике. Ведь в основе генеративных моделей Gen AI лежит фундаментальная математика.»
Одна из топовых экспертов, кто сегодня участвует на AIJ, преподаёт у нас.
Мария Тихонова — PhD по Computer Science, руководитель направления в SberAI и доцент ВШЭ. Она работает с LLM каждый день и объясняет математику так, как она реально применяется в AI.
🔥 Экспресс-курс «Математика для DS» — 8 недель, чтобы закрыть пробелы и уверенно проходить собесы.
🎁 До 30 ноября:
→ скидка 40%
→ курс «Школьная математика» в подарок при оплате
→ бесплатный тест на знание основ математики
👉 Записаться на курс
Доклад Юрия Петрова на конференции CrossConf 2025. Доклад посвящен возможностям портирования Flutter-приложений на различные платформы, включая нестандартные устройства.
Юрий рассказывает, что Flutter поддерживает не только стандартные платформы (iOS, Android, Web, Windows, macOS, Linux), но и множество других систем: Aurora OS, Huawei HarmonyOS, Tizen (Samsung TV), WebOS, Raspberry Pi и даже Yocto Project для встраиваемых устройств.
👉 Читать статью
🔸 Курс «Основы IT для непрограммистов»
🔸 Получить консультацию менеджера
🔸 Сайт Академии 🔸 Сайт Proglib
#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1🥱1
Optional (необязательный) означает, что переменная или данные могут быть равны нулю, и вы обрабатываете эти нулевые значения с помощью некоторых ключевых слов Swift.
Если вы обнаруживали
nil и развертывали его с помощью optional для обработки, это значит, что вы знакомы с таким типом переменных.Давайте рассмотрим сложные аспекты
optional в Swift, которые всех сбивают с толку.? против !Есть два способа сделать переменную optional с помощью
? и !, но каждый из них имеет разное значение.Когда вы делаете любую переменную необязательной (optional) с помощью
?, это означает, что вам также придётся обрабатывать значение nil.var name: String?
if let name = name {
print("Hello, \(name)")
} else {
print("No name found.")
}
Здесь мы использовали
if-let для обработки имени. Если имя равно nil, выполняется блок else; в противном случае выполняется блок if.Когда вы создаёте переменную с помощью
!, это означает, что вам не нужно обрабатывать значение nil.var userId: String!
print(userId.count)
Код выполняется успешно, но если значение равно нулю, приложение аварийно завершает работу.
Примечание. Используйте
!, если вы уверены, что заданное значение не будет равно нулю, даже если оно объявлено как optional.С помощью цепочки необязательных переменных (?) вы можете безопасно выполнить код с необязательной переменной.
let size = user?.name.count
Этот код работает нормально, даже если имя равно нулю. Всё выражение возвращает
nil, но не приводит к крешу.Необязательная цепочка (Optional Chaining) не остановит выполнение программы, если значение равно нулю. Взгляните на этот пример:
user?.logout()
print("Done!")
Если
user равен нулю, функция выхода из системы не будет вызвана, но приведенный ниже код будет выполнен.if let — не всегда лучший выборif-let полезен для управления нулевыми значениями, но иногда он может сделать код более сложным и запутанным.if let name = data?.name {
if let city = data?.address?.city {
print("\(name) lives in \(city)")
}
}Это затрудняет чтение вложенного кода.
Лучший способ:
guard let name = data?.name,
let city = data?.address?.city else {
return
}
print("\(name) lives in \(city)")
Еще лучший способ:
let city = data?.address?.city ?? "Unknown City"
??)Вы уже знакомы с таким кодом:
var name: String? = "Jayant"
Переменная
name имеет строковое значение или может быть равна нулю.Но видели ли вы что-то подобное?
let value: String?? = "Jayant"
Это называется Double Optional (
??). Читается как Optional(optional("Jayant")).Основной вариант использования — когда вы возвращаете необязательный параметр из функции и присваиваете эту функцию любой переменной, которая также возвращает optional параметр.
func getName() -> String? {
return nil
}
let name: String?? = getName()Здесь функция
getName() возвращает String?, а при назначении имени вы пишете String??, что означает optional, содержащую другую optional строку.Взгляните на этот код:
var names: [String]? = []
На первый взгляд кажется, что это просто пустой массив, но на самом деле это optional массив, содержащий внутри себя пустой массив.
Необязательный массив может находиться в различных состояниях.
var names: [String]? = nil // it's not an array
var names: [String]? = [] // Array exists, but it’s empty
var names: [String]? = ["Jayant", "Neha"] // Array with values
Давайте посмотрим, что произойдет, если вы это проверите:
var names: [String]? = []
if names != nil {
print("Array exists")
}
// output ---> Array exists
Как видите, массив существует и пуст.
🔹 Курс «Основы IT для непрограммистов»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
#буст #JuniorKit #Swift
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉 Большая распродажа Proglib Academy — минус 40% на всё!
📚 Выбирай свой курс:
▫️ «Экспресс-курс по математике для DS» — получи фундамент для построения успешной карьеры в Data Science
▫️ «Математика для DS» — для тех, кто хочет уверенно работать с данными;
▫️ «Основы Python» — чтобы начать писать код с нуля;
▫️ «Алгоритмы и структуры данных» — для будущих инженеров;
▫️ «Специалист по ИИ» или «AI-агенты», или «Машинное обучение» — для тех, кто хочет прокачаться в ИИ.
▫️ «Архитектуры и шаблоны проектирования» — чтобы писать гибкий, масштабируемый код как мидл+ разработчик.
▫️ «Основы IT для непрограммистов» — для тех, кто хочет понимать, как устроены технологии, не будучи разработчиком.
🎁 Бонусы ноября:
▫️ Розыгрыш MacBook Pro 14 — купи любой курс и пройди 2 недели обучения до 30 ноября.
▫️ Бесплатный тест по математике — за 5 минут покажет, какие темы стоит подтянуть перед DS.
👉 Выбрать курс со скидкой
📚 Выбирай свой курс:
▫️ «Экспресс-курс по математике для DS» — получи фундамент для построения успешной карьеры в Data Science
▫️ «Математика для DS» — для тех, кто хочет уверенно работать с данными;
▫️ «Основы Python» — чтобы начать писать код с нуля;
▫️ «Алгоритмы и структуры данных» — для будущих инженеров;
▫️ «Специалист по ИИ» или «AI-агенты», или «Машинное обучение» — для тех, кто хочет прокачаться в ИИ.
▫️ «Архитектуры и шаблоны проектирования» — чтобы писать гибкий, масштабируемый код как мидл+ разработчик.
▫️ «Основы IT для непрограммистов» — для тех, кто хочет понимать, как устроены технологии, не будучи разработчиком.
🎁 Бонусы ноября:
▫️ Розыгрыш MacBook Pro 14 — купи любой курс и пройди 2 недели обучения до 30 ноября.
▫️ Бесплатный тест по математике — за 5 минут покажет, какие темы стоит подтянуть перед DS.
👉 Выбрать курс со скидкой