Обновить
64K+

Kotlin *

Статически типизированный язык программирования

57,09
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Мутационное тестирование: прекрасная концепция, которой вы редко будете пользоваться на практике

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели8.7K

В новом переводе от команды Spring АйО на простом Java-примере показываем:

– как работает мутационное тестирование с Pitest;  
– почему 100% покрытия недостаточно;  
– откуда берутся выжившие мутанты;  
– почему не стоит прогонять MT по всему проекту;  
– и в каких случаях этот подход действительно окупается.

А ещё как поручить настройку и запуск Pitest AI-агенту с помощью готового skill.

Читать далее

Новости

Как я делал self‑host медиатеку на Kotlin Multiplatform и почему сервер «стримит» интерфейс на клиент

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели8.8K

Я пользовался для трекинга фильмов и сериалов Кинопоиском, Trakt, Letterboxd, IMDb, TMDB, MyShows — и по-честному ни один из них не бесил настолько, чтобы стать поводом всё бросить и писать своё. У каждого свои шероховатости: у Кинопоиска в какой-то момент стало слишком много рекламы, а заодно убрали подробную статистику по жанрам и странам, которая раньше была. У Trakt банально медленный сайт, лимит в 1000 фильмов в списке и ограниченные возможности с созданием списков. У IMDb так и не появилось нормального трекинга сериалов. TMDB — просто не нравится интерфейс. С Letterboxd — не могу даже сформулировать, почему, просто не зашло. А MyShows,устраивает почти во всём: удобно, есть оповещения о новых сериях, реклама ненавязчивая, лёгкая подписка для поддержки сервиса.

Так в чём тогда была зацепка? Не в том, что существующие сервисы плохие — большинство из них вполне рабочие. А в том, что ни один не даёт того сочетания, которое хотелось: self-host, где данные и инфраструктура твои, а не чужие; стриминг собственного контента внутри того же интерфейса, где ты его трекаешь; и просто инженерный азарт — я долгое время обдумывал архитектуру гибридной SDUI/BDUI на Kotlin, когда сервер стримит слоты на клиент, а клиент рендерит заранее заготовленные UI-элементы, при этом чтобы приложение ощущалось и выглядело как нативное. Это была отдельная задача, которую хотелось решить независимо от недостатков конкурентов.

Клиент — минималистичный интерфейс с трекингом фильмов и сериалов: статусы просмотра, оценки, свои списки.

Читать далее

Мы переизобрели Gradle Flavors на KMP и вот почему

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели6.3K

Если вы хоть раз работали с крупными KMP проектами, то наверняка хотели обратиться к старым добрым гредл флейворам, которые всем так хорошо знакомы по андроид разработке.

Но спустя 5 минут поисков до вас доходит осознание:Gradle Flavor на KMP нет и не планируется, а вместо них нам достается expect/actual, разбивающий код по платформенным сорц сетам

Читать далее

Лучшие практики управления конфигурацией в Spring Boot

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели10K

Конфигурация Spring Boot приложений гораздо более сложная, чем может показаться на первый взгляд.

В новом переводе от команды Spring АйО, мы вместе постараемся внести небольшую ясность в этот процесс.

Читать далее

Автономное ПО для велокомпьютера

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели10K

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

Читать далее

Как я написал круговой лаунчер на Jetpack Compose: тригонометрия свайпов и системные грабли

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели6K

Большинство лаунчеров для Android повторяют одну и ту же концепцию сетки иконок. Чтобы открыть приложение, нужно листать бесконечные рабочие столы и тянуться пальцем до нужной иконки.

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

В этой статье я расскажу, как проект прошел путь от простого прототипа на 4 стороны света до динамической сетки на Jetpack Compose, с какими подводными камнями Android пришлось столкнуться и как устроена математика свайпов под капотом.

Читать далее

Снапшот-тесты доступности: как сэкономить ресурс QA-отдела и спасти ревьюеров от гадания на кофейной гуще

Время на прочтение11 мин
Охват и читатели8.3K

Почта — массовый продукт, которым пользуются самые разные люди, и поэтому он должен быть максимально доступен. Нам важно, чтобы приложение Яндекс Почты было удобно каждому, в том числе людям с особенностями зрения. 

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

Читать далее

Рецензия на книгу «Асинхронный Kotlin»

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели7.9K

Книга «Асинхронный Kotlin» Яны Седовой посвящена теме, которая часто вызывает проблемы у начинающих Android‑разработчиков, — корутинам и Flow. Книга строится по маршруту от простого определения к рабочему мессенджеру на Jetpack Compose, Room и Retrofit, закрывая пробелы в знаниях, которые обычно оставляют ИТ‑курсы и лекции в ВУЗах. Для студента, стажера или начинающего разработчика (джуна) это полезный русскоязычный учебник, где асинхронность на Kotlin разобрана системно и последовательно, без необходимости собирать воедино материал из самых разных статей на Хабре.

Читать далее

Jabbit — фоновые задачи в KMP с API как у WorkManager (почти)

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели11K

Привет!

Представьте, что вы с удовольствием пишите один код на все платформы на Kotlin Multiplatform, и вдруг приходит задача «синкать данные раз в час, только по вайфаю и когда телефон на зарядке».

Под Android вы берёте WorkManager и за пятнадцать минут закрываете тикет. Потом яблочный смежник открывает документацию по BGTaskScheduler и обнаруживает, что модель там вообще другая и работает всё по-другому: нет очереди задач, есть окна, которые система выдаёт по своему усмотрению и т. д.

В итоге в проекте появляется expect fun scheduleSync() с разными реализациями, которые ведут себя по-разному, и никто в команде через год не сможет сказать, что именно произойдёт на iOS, если приложение свернули посреди загрузки.

Так как я андроидер с альтернативным мышлением, мне нравится API WorkManager'а. Я захотел его скопировать под KMP, породив так называемый Kotlin Multiplatform Work Manager или же Jabbit (job + rabbit, да, я знаю) — планировщик фоновых задач для KMP.

Таргеты: Android, iOS, js и wasmJs. Как будет время и желание, появится ещё и декстоп.

Читать далее

Android CameraX: детекция лица в реалтайме для биометрии

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели8.1K

Привет, Хабр! Я Евгений Шувагин, последний год работаю над компонентом Face-Shot в Т-Банке.

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

Читать далее

Конвертация docx на сервере: LibreOffice headless против Apache POI, и где каждый ломается

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели6.8K

Задача звучит безобидно: «нам нужно на бэкенде превращать .docx в .html (а иногда .html в .pdf)». В тикете это одна строчка. На практике конвертация офисных документов — одна из тех тем, где красивый прототип собирается за час, а потом полгода латается по краям: то таблица разъехалась, то картинки пропали, то сервис лёг под нагрузкой, то .doc из 2007-го отказывается открываться.

Я подходил к этой задаче двумя принципиально разными способами и в итоге держу два отдельных репозитория:

Читать далее

Я сделал CRM без бэкенда. Вот чего мне это стоило

Уровень сложностиПростой
Время на прочтение9 мин
Охват и читатели7.4K

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

Дальше идёт счёт, который за это пришёл, и он вполне конкретный: шесть с половиной минут работы на десятиминутный разговор и половина возможностей, которые в приложении с сервером есть по умолчанию.

Читать далее

Шпаргалка: Kotlin Coroutines Channels и Actor‑модель

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели7.9K

Пытаюсь лучше понять работу Kotlin Coroutines. Беру небольшую тему про Kotlin Coroutines и пытаюсь разобраться и написать шпаргалку (максимально кратко и лаконично). Сегодня поговорим про Каналы (Channel) и паттерн Actor.

В предыдущих частях мы выяснили, что обычные suspend-функции возвращают результат только один раз. Но что делать, если у нас есть непрерывный поток данных, который асинхронно генерируется в одной корутине, а обрабатываться должен в другой (или даже в нескольких)? Нам нужна потокобезопасная «труба». В мире корутин этой трубой является Channel.

Читать далее

Ближайшие события

Почему баннер Yandex Ads мигает в LazyColumn — и при чём здесь AndroidView.onReset

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели8.3K

Представьте обычный feed на LazyColumn: новости, карточки, между ними рекламный баннер. Баннер загрузился, пользователь пролистал его вниз, затем вернулся обратно, и мерцание реклама грузится заново.

Ещё раз вниз. Ещё раз вверх. Ещё одно мерцание и загрузка.

На первый взгляд причина кажется очевидной: item покидает экран, rememberBannerAdState теряет состояние, Compose создаёт всё заново. Значит, достаточно сохранить BannerAdState за пределами item и проблема исчезнет.

Я тоже так подумал.

Не исчезла.
Мерцания остались.

С этого момента простой баг (?) интеграции Yandex Ads превратился для меня в небольшое расследование: пришлось разобраться, что на самом деле происходит с item внутри LazyColumn, как SubcomposeLayout переиспользует composition, почему это ещё не означает переиспользование AndroidView и какой lifecycle поверх всего этого построил Compose API Yandex Ads.

В итоге вопрос «почему баннер моргает?» оказался гораздо интереснее самого workaround.

Читать далее

Почему Java-разработчики слишком доверяют рекомендациям ИИ

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели11K

Представьте: в пятницу вечером руководитель уверенно сообщает, что переход со Spring Boot 3.5 на 4.0 будет простым и его можно закончить за выходные. Скорее всего, вы уточните, на чём основана такая оценка, и напомните о несовместимых изменениях.

Теперь заменим руководителя на GitHub Copilot или другую большую языковую модель (LLM). Она предлагает рефакторинг метода, новую зависимость или готовый шаблон реализации. Ответ выглядит аккуратно и звучит уверенно. Модель не предупреждает, что может ошибаться. Возникает вопрос: проверяем ли мы такой код столь же строго, как заявление руководителя, или сразу принимаем его?

По данным отчёта Sonatype за 2026 год, 27,76% из 36 870 сгенерированных LLM рекомендаций по обновлению зависимостей ссылались на несуществующие версии этих зависимостей. Получается, одна из трёх-четырёх зависимостей — выдуманная. И проблема не ограничивается зависимостями: та же ложная уверенность может присутствовать в любой строке кода, созданной ИИ.

Читать далее

Как мы переводили страницу объявления на Beduin в мобильной версии Авито

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели7.4K

Всем привет! Меня зовут Егор Савинцев, я Frontend Platform Engineer в Авито. Сейчас я работаю в команде архитектуры, а до этого в команде Phobos в рамках Платформизации переводил страницу объявления на Beduin — разрабатывал клиентскую архитектуру и переписывал блоки. 

Сразу важное отступление. 

Beduin — это Backend‑Driven UI. Если в нативе в коде клиентского приложения есть компоненты, бэкенд присылает им данные, и всё работает. В Beduin бэкенд присылает и данные, и сами компоненты в специальном виде. На клиенте у нас только рендерер — специальный компонент, который принимает JSON и рендерит то, что мы прислали. 

В этой статье я расскажу, зачем вообще переписывать работающую страницу, как эволюционировала наша архитектура и с какими компромиссами между нативным кодом и BDUI нам пришлось столкнуться.

Статья будет полезна frontend‑ и mobile‑разработчикам, инженерам платформенных команд, архитекторам клиентских приложений и backend‑разработчикам, которые внедряют Backend‑Driven UI. В общем, всем, кто планирует переводить крупные экраны на BDUI и хочет заранее узнать, что может пойти не так. Спойлер: всё.

Читать далее

История создания звонилки без номера: месяц, миллионы токенов и грабли, которые легли в основу этого цикла статей

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели8.3K

В октябре прошлого года на Хабре вышла статья «Как я писал свою звонилку для видеозвонков» — автор под ником CEOCTO за несколько вечеров написал P2P-видеозвонилку на WebRTC, потому что его достали обрывающиеся созвоны в мессенджерах. Я прочитал, улыбнулся, полез смотреть исходники на GitHub — и на этом всё. Как обычно бывает с чужими pet-проектами: оценил, закрыл вкладку, забыл

Читать далее

Пересекая реку Стикс: Spring Boot 3.5 и проблема зомби-зависимостей

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели9K

Недавно я разбирал истории CVE, связанные с завершением поддержки Tomcat 8.5, и решил посмотреть на Spring Boot 3.5. Я задался тем же вопросом применительно к Spring Boot: что происходит с уровнем защищённости приложения, когда используемая версия достигает End Of Life (EOL)?

Читать далее

# DI без рефлексии и бойлерплейта: магия KSP в действии

Уровень сложностиПростой
Время на прочтение9 мин
Охват и читатели8.6K

Погряз в боли настройки DI в многомодульных проектах и решил написать собственный велосипед на Kotlin Symbol Processing. Рассказываю, как поэкспериментировал с генерацией кода, победил R8/ProGuard, добавил compile-time валидацию графа и что из этого вообще получилось

Читать далее

Как мы перенесли ответственность за поддержку мапперов моделей на KSP

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели11K

Каждый разработчик, работавший с проектом, где одни модели мапятся в другие, знает эту боль: добавил поле в модель и пошёл обновлять десятки мапперов вручную. Переименовал параметр - компилятор взрывается ошибками, и ты снова правишь код руками. Мапперы - это “мёртвая зона”: они пишутся механически, но при этом легко ломаются и не приносят никакой ценности бизнесу. В статье я расскажу о том, как мы от этого ушли и какие результаты получили

Читать далее
1
23 ...