<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Kotlin</title>
    <description/>
    <link>https://tproger.ru/tag/kotlin</link>
    <atom:link href="https://tproger.ru/tag/kotlin/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sat, 03 Oct 2026 12:50:37 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Kotlin</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Один фреймворк для Android и iOS: звучит круто, работает?  Нет</title>
      <link>https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net</link>
      <comments>https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Роман Новохацкий]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net</guid>
      <description><![CDATA[<p>Почему единый кроссплатформенный фреймворк для автотестов Android и iOS не работает на практике и когда стоит разделить его на два отдельных проекта.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net">Один фреймворк для Android и iOS: звучит круто, работает?  Нет</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Распознавание]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Jul 2026 13:20:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Я сделал автотесты на Appium для Android и iOS в одном проекте. Один репозиторий, общий фреймворк, общие Page Objects, общие steps. Красота.</p><p>Потом проект вырос, в команду пришли ещё люди, и стало понятно: этот красивый монолит пора разделять.</p><p>Это было взвешенное решение. В какой-то момент общий фреймворк превратился в поле мерж-конфликтов, где ты уже не тесты пишешь, а разбираешься, кто чей page object сломал и почему Android отвалился после правки для iOS.</p><p>Appium тут ни при чём, как и скорость тестов. Проблема была в архитектуре: один общий слой для двух разных платформ начал мешать сильнее, чем помогать.</p><p>Как говорил один мой коллега, перефразируя классическое “вам шашечки или ехать”:</p><blockquote>Ты сюда страдать пришёл или тесты писать?</blockquote><p>После этого решение разделить Android и iOS на два проекта стало очевидным.</p><p>Сейчас у меня два отдельных проекта: mb-android-tests и mb-ios-tests. И знаете что? Это лучшее архитектурное решение за всё время на этом проекте. Серьёзно.</p><p><b>Контекст: что за проект и почему это важно</b></p><p>Финтех. Нативное приложение. Отдельные кодовые базы, Kotlin на Android, Swift на iOS. И UI там не «три кнопки и список», формы с десятками полей, кастомные контролы, WebView-вставки, платежи, валютные операции, бюджетные переводы. Ну вы поняли.</p><p>Стек: Java 21, TestNG, Appium 2.x, Selenide, Allure, Maven. CI на GitLab, крутится на Mac Mini. 5 Android-эмуляторов, 4 iOS-симулятора, 9 Appium-серверов — по одному на устройство.</p><p>Но это сейчас. А начиналось всё с одного жирного монолита.</p><p><b>Старый проект: 8 модулей и конструктор-монстр</b></p><figure><img src="https://media.tproger.ru/user-uploads/139426/2026-07-07/54be52bb-7e50-4e11-b624-86cc1ce0766b.webp" alt="" /></figure><p>Идея была «как в книжке»: один репозиторий, модульная структура, переиспользование. DRY во все поля. Ну а чё, красиво же.</p><p>8 модулей. Один mvn clean install. Все зависят от mobile-automation-framework, в котором живут DriverFactory, BaseTest, общие Page Objects и слой Steps.</p><p>А DriverFactory принимал <b>11 параметров</b>. Одиннадцать, Карл.</p><p>Половина нужна только Android, другая только iOS. Но метод один. Потому что так более по программистцки, как написано в каждой второй статье про архитектуру автотестов.</p><p>Когда я работал один, было норм. Ты сам знаешь, от куда что идет.</p><p>А потом пришли люди.</p><p><b>Почему с людьми всё навернулось</b></p><p><b>Мерж-конфликты каждый божий день</b></p><p>Вот конкретная ситуация. Один человек правит LoginPage в общем фреймворке, добавляет метод для iOS, меняет локатор. Второй в тот же момент рефакторит этот же LoginPage под новую версию Android-приложения.</p><p>Мерж. Конфликт.</p><p>И тут начинается самое весёлое: какой локатор правильный? Для Android? Для iOS? Для обоих? Кто будет разбираться? Тот, кто мёрджит? А он вообще контекст понимает?</p><p>Это не единичный случай. Это было <b>каждый</b> день. Потому что mobile-automation-framework получился общим модулем, от которого зависят все. И все туда лезут. Постоянно.</p><figure><img src="https://media.tproger.ru/user-uploads/139426/2026-07-07/3866002d-86c5-4894-a441-2522f48dcab1.webp" alt="" /></figure><p><b>Обновление одной библиотеки = блокировка всех</b></p><p>Решил обновить java-client с 7.x на 8.x. Нормальное желание — API поменялся, MobileElement удалили, capabilities переехали на типизированные Options.</p><p>Вот что произошло в реальности:</p><ol><li>Меняю версию в parent pom.xml</li><li>MobileElement удалён → compilation error в DriverFactory, во всех DriverManager’ах</li><li>DesiredCapabilities → UiAutomator2Options / XCUITestOptions → переписываю все менеджеры</li><li>selenide-appium 1.x несовместим с java-client 8.x → обновляю до 2.x</li><li>selenide-appium 2.x требует Selenide 6.x → обновляю Selenide</li><li>Selenide 6.x ломает API page objects → переписываю page objects во всех модулях</li><li>А Selenide 6.x ещё и Java 8 не поддерживает → обновляю Java</li></ol><p>Одна библиотека.</p><p>Задача «обновить одну библиотеку» превратилась в 50+ файлов, 4-5 каскадных обновлений, 2-3 недели работы. И всё это время develop нестабилен. Все заблокированы. Тесты не запускаются.</p><p>Две недели.</p><p>Из-за одной строчки в pom.xml.</p><p><b>Page Objects с if/else — это два page object в одном файле</b></p><p>Общие Page Objects звучат красиво на бумаге: пишем один раз, используем для обеих платформ. А на практике…</p><p>Это не page object. Это два page objects, запиханных в один файл через if/else. И так в каждом методе.</p><p>А сверху ещё слой Steps. Обёртки над page objects «для читаемости». И в steps тоже if (platform), потому что логика взаимодействия разная. На Android ты скроллишь через UiScrollable семантически, «прокрути до элемента с текстом X». На iOS координатами, «двигай палец из точки A в точку B». Один метод в steps, а внутри два разных мира.</p><p>В какой-то момент ловишь себя на мысли: я же не тесты пишу. Я подгоняю pages и steps под две платформы, чтобы фреймворк не развалился. Это уже не автоматизация тестирования, это поддержка фреймворка ради поддержки фреймворка.</p><p><b>Каждый работает в своём темпе и все друг другу мешают</b></p><p>У одного задача покрыть тестами новый экран на Android. У второго пофиксить падающие тесты на iOS. У третьего добавить тестовые данные.</p><p>Все трое лезут в mobile-automation-framework. Все трое меняют pom.xml, BaseTest, page objects. Каждый в своей ветке.</p><p>А потом мёрдж.</p><p><b>Технические причины, которые добили окончательно</b></p><p>Ладно, человеческий фактор. Но были и чисто технические штуки, которые окончательно убедили меня, что кроссплатформа тут бессмысленна.</p><p><b>Локаторы: работай с тем, что дают</b></p><p>Сразу скажу то, о чём мало кто пишет в статьях: в мобильной автоматизации ты работаешь с тем, что дают, а не с тем, что хотелось бы.</p><p>В теории есть AccessibilityID единый локатор для обеих платформ. Звучит хорошо. А на практике? Попробуй попросить мобильных разработчиков расставить одинаковые accessibility-идентификаторы на сотнях экранов. На Kotlin и Swift. Одновременно. Они тебя вежливо пошлют, но скорее всего не вежливо. И будут правы, у них свои спринты, свои дедлайны, и твои автотесты в их приоритетах где-то между «поправить тень у кнопки» и «никогда».</p><p>Так что реальный выбор:</p><p><b>XPath -</b> работает, но на iOS может быть тормозным. На Android через UiSelector быстро, нативно, надёжно. На iOS через NSPredicate тоже ок. А «универсальные» XPath типа //*[@text='Войти' or @label='Войти']  это путь к боли, потому что Page Source на двух платформах два совершенно разных XML-дерева.</p><p><b>Координаты -</b> костыль? Да. Но иногда единственный вариант. Когда у тебя кастомный контрол без accessibility-свойств, а разработчик говорит «это декоративный элемент», ты либо тыкаешь по координатам, либо не тестируешь.</p><p><b>OpenCV</b> - есть ещё вариант с распознаванием элементов по картинке. Для некоторых кейсов реально выручает. Но это отдельная тема на целую статью, может напишу потом.</p><p>Суть в том, что «напиши один локатор и работай на двух платформах» это миф. Page Source на Android это android.widget.Button с resource-id. На iOS  XCUIElementTypeButton с name и label. Разные типы элементов, разные атрибуты, разная глубина вложенности. Разные миры.</p><p><b>StaleElementReferenceException — «подарок» от iOS</b></p><p>Android рендерит UI через Choreographer синхронно с VSYNC. Элемент появился → стабилен → кликаем.</p><p>iOS рендерит через CoreAnimation с неявными анимациями. Элемент есть в дереве, но ещё анимируется. Формально кликабелен, фактически хрен.</p><p>Стандартный WebDriverWait с elementToBeClickable это не ловит. Элемент «кликабелен» по мнению Appium wait завершается. А потом click() падает, потому что DOM изменился между вызовами.</p><p>На Android этой проблемы нет вообще. Тот же тест, тот же wait, тот же код зелёный на Android, красный на iOS. Один и тот же метод, два разных результата. И это не баг это фундаментальное различие платформ.</p><p>Кастомные wait-стратегии для iOS отличаются от Android принципиально. Пихать их в один фреймворк строить leaky abstraction, которая протекает на каждом шаге.</p><p><b>Жесты — два разных мира</b></p><p>Свайп вниз на Android:</p><p>Свайп вниз на iOS:</p><p>Чувствуете разницу? И даже длительность свайпа важна: на Android 200мс это нормальный скролл. На iOS 200мс это fling, и элемент улетает за экран.</p><p>«Кроссплатформенная» обёртка для скролла функция на 40 строк с двумя ветками if (platform), внутри каждой и ещё if для performSwipeDown() vs performSwipeUp(). На 50+ экранах таких обёрток, которых десятки.</p><p>И каждая место для бага.</p><p><b>Решение: разделяй и властвуй</b></p><p>Решение было болезненным. Я реально откладывал, потому что казалось, что это шаг назад. Дублирование кода, нарушение DRY, всё такое. Мозг сопротивлялся.</p><p>А потом я просто сел и разделил.</p><p>Никаких общих page objects. Никаких общих steps. Никакого общего DriverFactory с 11 параметрами. Каждый проект со своим pom.xml, свои зависимости, свой BaseTest, свои локаторы.</p><p>Что осталось общего: подход к структуре (Maven + TestNG + Allure), CI-шаблоны, принципы организации. Но не код. Код полностью раздельный.</p><p><b>Что поменялось на практике</b></p><p>В Android-проекте DriverManager типизирован под AndroidDriver. В iOS под IOSDriver. Не AppiumDriver&lt;MobileElement&gt; с кастами и проверками, а конкретный тип для конкретной платформы. IDE подсказывает только релевантные методы. Компилятор ловит ошибки на этапе сборки, а не в рантайме.</p><p>BaseTest принимает ровно те параметры, которые нужны. Android: deviceName, platformVersion, udid, appPackage, appActivity, systemPort, serverUrl, appPath — 8 штук, все релевантные. iOS: deviceName, platformVersion, udid, appPath, serverUrl, wdaLocalPort — 6. Никаких @Optional("systemPort") со строкой “systemPort” в качестве дефолта.</p><p><b>А мерж-конфликты?</b></p><p>Когда один человек работает в mb-android-tests, а второй в mb-ios-tests то они <b>вообще</b> не пересекаются. Разные репозитории. Конфликт невозможен физически.</p><p>Обновление java-client в Android-проекте не затрагивает iOS. Хочешь обновить, обновляй. iOS продолжает работать на старой версии.</p><p>Добавить новый параметр для iOS? Меняешь BaseTest и testng.xml в iOS-проекте. Android даже не узнает.</p><p>Это прям кайф.</p><p><b>А как же дублирование кода?!</b></p><p>Конечно, конечно. Первый вопрос, который задают: «Но ведь ты пишешь тесты дважды!»</p><p>Нет.</p><p>Я пишу каждый тест один раз и без костылей. Без if (platform) в каждом методе. Да, для одного и того же экрана есть два теста, один для Android, один для iOS. Но каждый из них чистый, понятный, заточенный под свою платформу.</p><p>В старом варианте я тоже «писал один раз», а потом тратил столько же времени на поддержку if/else, мерж-конфликты и каскадные обновления. «Экономия» на создании оборачивалась переплатой на поддержке. С процентами.</p><p><b>Когда кроссплатформа всё-таки ок</b></p><p>Я не топлю за то, что кроссплатформенный фреймворк абсолютное зло. Есть ситуации, где он работает:</p><p>Приложение простое, пара экранов, стандартные контролы, минимум кастомного UI.</p><p>UI реально идентичен на обеих платформах. Бывает, наверное.</p><p>Команда из одиного человека. Сам пишешь, сам мёрджишь, сам разруливаешь. Голова справляется.</p><p>Минимум жестов. Нет сложных свайпов, drag-and-drop, pinch-to-zoom.</p><p>Если у тебя финтех, банк, enterprise-приложение с сотнями экранов, кастомными контролами и тремя+ QA, то два проекта дешевле. Не в строках кода, а во времени. В нервах. В часах, потраченных на мерж-конфликты вместо написания тестов.</p><p><b>Итого</b></p><p>Два проекта это не шаг назад и не двойная работа. Со стороны может выглядеть именно так, но на практике ты пишешь каждый тест один раз, под конкретную платформу, без лишних компромиссов. Потом поддерживаешь его без постоянных мерж конфликтов, каскадных обновлений и if/else в каждом втором методе.</p><p>Кроссплатформенный фреймворк на Appium для сложного нативного приложения часто оказывается иллюзией экономии.</p><p>В следующей статье покажу, как у нас устроена инфраструктура для 9 параллельных устройств на одном Mac Mini: порты, bash скрипты, Appium серверы и workaround’ы, которых нет в документации. Спойлер: там тоже всё не совсем как в гайдах.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin исполнилось 15 лет: что принесут 2.4.0, toolchain и AI-агенты</title>
      <link>https://tproger.ru/articles/kotlin-ispolnilos-15-let-chto-prinesut-2-4-0-toolchain-i-ai-ag</link>
      <comments>https://tproger.ru/articles/kotlin-ispolnilos-15-let-chto-prinesut-2-4-0-toolchain-i-ai-ag?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kotlin-ispolnilos-15-let-chto-prinesut-2-4-0-toolchain-i-ai-ag</guid>
      <description><![CDATA[<p>15-летие Kotlin, релиз 2.4.0, Kotlin Toolchain 0.11 и AI-агенты на Koog. Разбираем, что меняется для Android-, backend- и KMP-разработчиков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kotlin-ispolnilos-15-let-chto-prinesut-2-4-0-toolchain-i-ai-ag">Kotlin исполнилось 15 лет: что принесут 2.4.0, toolchain и AI-агенты</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Jul 2026 11:28:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Летом 2026 года Kotlin отмечает 15 лет с момента первого публичного анонса. За это время язык из «ещё одной JVM-альтернативы» превратился в де-факто стандарт Android-разработки, инструмент для backend-сервисов и основу Kotlin Multiplatform. JetBrains подвела итоги весны и начала лета: вышел стабильный <b>Kotlin 2.4.0</b>, появился <b>Kotlin Toolchain 0.11</b>, а фреймворк <b>Koog</b> доведён до первой мажорной версии. Разбираем, что из этого действительно влияет на проекты.</p><p>Для российских разработчиков это особенно близкая история: Kotlin создавался в JetBrains, компании, основанной выпускниками Санкт-Петербургского политехнического университета. Язык, названный в честь острова в Балтийском море, стал одним из самых заметных российских технологических экспортов последнего десятилетия.</p><p><b>15 лет Kotlin.</b> Первый анонс состоялся в июле 2011 года, стабильная 1.0 — в феврале 2016-го.</p><p><b>Kotlin 2.4.0.</b> Стабильные context parameters, explicit backing fields, поддержка Java 26, Swift packages в Kotlin/Native и совместимость с Gradle 9.5.0.</p><p><b>Kotlin Toolchain 0.11.</b> Amper эволюционировал в единый инструментарий: одна команда kotlin для создания, сборки, тестирования и публикации проектов.</p><p><b>Koog 1.0.</b> JetBrains выпустила стабильный фреймворк для AI-агентов на Kotlin и Java с годовой гарантией совместимости ядра.</p><p><b>Compose Multiplatform 1.12.0-beta01</b> и <b>Compose Hot Reload 1.2.0-beta01</b> развивают shared UI и экспериментальный MCP-сервер для AI-агентов.</p><p><b>Гранты Kotlin Foundation 2026.</b> Приём заявок на финансирование open-source библиотек и инструментов открыт до 14 июля 2026 года.</p><h2>Пятнадцать лет: от внутреннего проекта до мейнстрима</h2><p>История Kotlin началась в 2010 году как попытка JetBrains решить собственные проблемы с Java. В 2011-м язык впервые показали публике, а в феврале 2016 года вышла стабильная версия 1.0. Переломным моментом стал Google I/O 2017: Kotlin получил статус первоклассного языка для Android, после чего интерес к нему резко вырос.</p><p>Сегодня Kotlin используется не только в мобильной разработке. На нём пишут backend на Spring и Ktor, делают кроссплатформенные приложения через Kotlin Multiplatform, экспериментируют с Kotlin/Wasm и даже строят AI-агентов. По данным ежегодных опросов JetBrains, доля Kotlin в коммерческих проектах стабильно растёт как в Европе, так и в России, несмотря на санкционные ограничения в части корпоративных лицензий.</p><blockquote>If I were to choose one word to describe Kotlin's design, it would be pragmatism. For us it means caring about the usefulness.</blockquote><h2>Kotlin 2.4.0: что вошло в релиз</h2><p>3 июня 2026 года JetBrains выпустила стабильный <b>Kotlin 2.4.0</b>. Это не инкрементальный патч, а полноценная мажорная версия с изменениями в языке, стандартной библиотеке, компиляторе и всех целевых платформах.</p><ul><li><b>Язык.</b> Стабилизированы context parameters и explicit backing fields, добавлены новые target'ы для аннотаций.</li><li><b>Стандартная библиотека.</b> UUID API вышел из экспериментального статуса, появились функции для проверки отсортированности коллекций.</li><li><b>Kotlin/JVM.</b> Поддержка Java 26 и аннотации в метаданных включены по умолчанию.</li><li><b>Kotlin/Native.</b> Swift packages можно использовать как зависимости, обновлён Swift export, по умолчанию включён CMS GC.</li><li><b>Kotlin/Wasm.</b> Инкрементальная компиляция по умолчанию и поддержка WebAssembly Component Model.</li><li><b>Kotlin/JS.</b> Экспорт value-класс и возможности ES2015 при инлайнинге JS-кода.</li><li><b>Gradle.</b> Совместимость с Gradle 9.5.0.</li><li><b>Maven.</b> Автоматическое выравнивание версий Java и JVM target.</li><li><b>Компилятор.</b> Более предсказуемое поведение inline-функций при компиляции .klib.</li></ul><p>Для практики это означает: если ваш проект живёт на JVM, можно обновляться ради Java 26 и улучшений stdlib; если вы работаете с iOS через Kotlin/Native — стоит посмотреть на Swift packages; для WebAssembly-экспериментов 2.4.0 делает сборку заметно быстрее.</p><h3>Как обновиться</h3><p>Обновление до 2.4.0 проходит через указание версии в Gradle или Maven. В Android Studio и IntelliJ IDEA новая версия уже включена в последние сборки.</p><h2>Kotlin Toolchain 0.11: Amper уходит в прошлое</h2><p>В июне 2026 года JetBrains окончательно переименовала Amper в <b>Kotlin Toolchain</b> и выпустила версию 0.11. Это не просто ребрендинг: инструмент позиционируется как единая точка входа для работы с Kotlin-проектами. Одной командой kotlin можно создать, собрать, протестировать и опубликовать проект.</p><p>В 0.11 появилась возможность публиковать JVM-библиотеки, улучшена разработка плагинов и упрощена начальная настройка. Для российских команд, часть которых уходит от корпоративных Gradle-лицензий к open-source инструментам, Kotlin Toolchain может стать интересной альтернативой для новых проектов и прототипов.</p><p><b>Важно:</b> Kotlin Toolchain пока в статусе Alpha. Для существующих Gradle-проектов массово мигрировать смысла нет — инструмент ещё не покрывает все сценарии зрелых сборок. Но пробовать на небольших сервисах и pet-проектах уже можно.</p><h2>Koog 1.0: AI-агенты на Kotlin</h2><p>Фреймворк <b>Koog</b> от JetBrains вышел в версии 1.0. Он предоставляет примитивы для построения агентных приложений: инструменты, workflow, персистентность, память, observability и интеграции с JVM/KMP-проектами. Главное для Java-команд: Koog теперь предлагает идиоматичный Java API, то есть переходить на Kotlin ради агентов не обязательно.</p><p>Koog интегрируется со <b>Spring AI</b>, что делает его естественным выбором для backend-разработчиков, которые уже используют Spring Boot. Появилась мультиплатформенная observability и годовая гарантия совместимости ядра — это важно для команд, которые рассматривают агентов не как прототип, а как часть продакшена.</p><h2>Compose и инструменты UI</h2><p>Для UI-разработчиков в выпуске два значимых обновления. <b>Compose Multiplatform 1.12.0-beta01</b> продолжает развивать shared UI: новые графические возможности, улучшения accessibility на iOS, обновления поведения UI-тестов и исправления для десктопа, веба и Gradle-плагина.</p><p>Отдельно стоит <b>Compose Hot Reload 1.2.0-beta01</b>. В нём развивается экспериментальный MCP-сервер: AI-агенты получают доступ к логам, ошибкам UI, могут перезапускать приложение и управлять его жизненным циклом. Это ещё не production-ready, но демонстрирует направление: разработка интерфейсов становится более визуальной и интерактивной.</p><h2>Экосистема: библиотеки, гранты и корпоративный опыт</h2><p>В обзоре JetBrains упомянуты три KMP-библиотеки, которые стоит изучить: <b>ComposeMediaPlayer</b> для кроссплатформенного видео, <b>NSExceptionKt</b> для улучшенной обработки крэшей на Apple-платформах и <b>multiplatform-settings</b> для хранения key-value данных в shared-коде.</p><p>Кроме того, Kotlin Foundation открыл <b>грантовую программу 2026</b>. Финансирование могут получить open-source проекты вокруг Kotlin Multiplatform, AI и больших языковых моделей. Заявки принимаются до <b>14 июля 2026 года</b>. Для российских авторов библиотек это реальный способ поддержать проект, особенно если он пользуется спросом у зарубежного комьюнити.</p><p>Ещё один сигнал зрелости экосистемы — история <b>Booking.com</b>. Компания внедрила Kotlin Multiplatform для экспериментальной библиотеки и получила результаты выше ожиданий: улучшилась консистентность между Android и iOS, при этом команды не отказывались от платформенно-специфичной разработки.</p><h2>Обучение: бесплатные курсы на Hyperskill</h2><p>К юбилею JetBrains сделала часть Kotlin-курсов на <b>Hyperskill</b> бесплатными. Это проектно-ориентированная платформа: можно укрепить основы или пойти в сторону мобильной и backend-разработки. Для тех, кто только начинает или переходит с Java, это удобный способ получить практику, а не только теорию.</p><h2>Выводы</h2><p>15 лет Kotlin — это не только юбилей, но и точка, где язык перешёл из фазы «быстрого роста» в фазу «экосистемного инструмента». <b>Kotlin 2.4.0</b> делает язык зрелее на всех платформах, <b>Kotlin Toolchain</b> упрощает вход в экосистему, а <b>Koog</b> и <b>Compose Hot Reload</b> показывают, что Kotlin активно используется в новой волне AI-разработки.</p><p>Для работающих проектов самый безопасный шаг — обновиться до Kotlin 2.4.0 в тестовом окружении и проверить совместимость. Новые инструменты вроде Toolchain и Koog стоит пробовать на pet-проектах, прежде чем тащить в продакшен. А если у вас есть open-source библиотека вокруг Kotlin — грантовая программа Kotlin Foundation может стать хорошим подспорьем.</p><p><b>Источник:</b> <a href="https://blog.jetbrains.com/kotlin/2026/06/kodees-kotlin-roundup-kotlin-turns-15-kotlin-2-4-0-and-the-kotlin-toolchain/">Kodee's Kotlin Roundup: Kotlin Turns 15, Kotlin 2.4.0, and the Kotlin Toolchain</a> — блог JetBrains.</p>]]></content:encoded>
    </item>
    <item>
      <title>Почему главные конфликты в разработке не связаны с технологиями</title>
      <link>https://tproger.ru/articles/pochemu-glavnye-konflikty-v-razrabotke-ne-svyazany-s-tehnologiyami</link>
      <comments>https://tproger.ru/articles/pochemu-glavnye-konflikty-v-razrabotke-ne-svyazany-s-tehnologiyami?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Андрей Козлов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-glavnye-konflikty-v-razrabotke-ne-svyazany-s-tehnologiyami</guid>
      <description><![CDATA[<p>Почему конфликты в IT-командах возникают не из-за технологий, а из-за коммуникации, идентичности и инженерной культуры. Разбор споров вокруг Scala, Kotlin, архитектуры, технического долга и командной динамики в разработке.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-glavnye-konflikty-v-razrabotke-ne-svyazany-s-tehnologiyami">Почему главные конфликты в разработке не связаны с технологиями</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Функциональное программирование]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Lego]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 15 May 2026 06:19:51 GMT</pubDate>
      <content:encoded><![CDATA[<p>В первый месяц работы юный разработчик может думать, что причина конфликтов в команде скрывается в технологических нюансах. Через год он начинает подозревать: дело в чем-то другом. Десять лет спустя он с уверенностью скажет: технологии здесь вообще ни при чем.</p><h2>Инструмент как часть личности</h2><p>Возьмем типичную ситуацию: переход на новый стек или поддержка старой базы. Допустим, команда третью неделю (а иногда и третий месяц!) обсуждает, оставить Scala или перейти на Kotlin. Аргументы обеих сторон озвучиваются на первой же встрече, а затем просто повторяются от созвона к созвону. Кто-то говорит об экосистеме, кто-то — о кривой обучения. Внешне это выглядит как техническая дискуссия, но решение не принимается.</p><p>За годы работы с инженерными командами я заметил закономерность: чем дольше тянется спор, тем меньше в нем остается от сути технологий. Люди спорят о синтаксисе, но неозвученная дискуссия идет о том, чья экспертиза весит больше, чья позиция будет услышана и кто в итоге будет нести ответственность.</p><p>Программист, который пять лет пишет на Scala, не просто использует инструмент. Язык стал частью его мышления: как он декомпозирует задачи и выстраивает архитектуру. И когда кто-то предлагает перейти на Kotlin, человек слышит: «То, что ты умеешь, больше не нужно». Отсюда и высокий градус эмоций. Годы практики делают стек частью профессиональной идентичности. Оспорить выбор инструмента — значит задеть человека лично.</p><h2>Ловушка единомышленников</h2><p>Отдельная история — когда вся команда пришла из одной среды. Если вы учились в одном вузе, слушали тех же спикеров и одновременно осваивали стек — на старте это кажется преимуществом. Вы понимаете друг друга с полуслова.</p><p>Однако со временем команда перестает замечать собственные слепые пятна. Любой «человек со стороны» с его новым взглядом воспринимается как дилетант, пытающийся найти изъяны в идеальной системе. Холивары в таких коллективах особенно вязкие: все одинаково уверены, что «очевидное очевидно», а любое альтернативное мнение априори ошибочно или упоминается лишь в контексте «идея хорошая, но делать ее мы не будем».</p><h2>Скульптура против Lego: конфликт ценностей</h2><p>В инженерной культуре сложность часто путают с качеством. Из-за этого возникают одни из самых затяжных конфликтов: когда один разработчик ратует за лаконичность и скорость, а другой — за «высокую архитектуру». Scala появилась именно из этой логики: язык создавался людьми, которые хотели объединить объектно-ориентированное и функциональное программирование в одном инструменте. Получилось мощно и академически красиво, но взаправду сложно. И вопрос, а всегда ли нужно вот настолько сложно, тоже порождает споры.</p><p>Хорошая аналогия — скульптура из мрамора против фигурки из Lego. Когда мы видим работы Страцца и Бернини, которые смогли передать в камне эффект тончайшей вуали, мы застываем в восхищении посреди музея. Но создание таких статуй требовало времени, а внести “правки от заказчика” означало бы подвергнуть риску всю работу: попробуйте исправить скол на мраморной статуе, которую ваяли сильно дольше, чем планировалось. В случае с конструкцией из Lego все намного проще: вынул блок, вставил другой, и вот из фигурки кошки уже получился «Тысячелетний сокол».</p><p>Чем сложнее язык или технология, тем глубже оказываются ошибки и тем труднее их потом найти. Причем платит за это не только тот, кто писал. Автор ошибки как раз легко может к этому моменту уже уйти на повышение. Но каждый следующий человек, который начнет взаимодействовать с этим кодом, заплатит ту же цену. Технический долг в командах почти всегда описывают одинаково: «это то, что написали до меня». Мы сильно реже склонны упоминать его, имея в виду собственный код и свои планы. Сложные решения, выбранные ради красоты концепции, — один из самых надежных способов создать именно такой долг.</p><p>Сложный инструмент — не приговор. Но когда его выбирают ради престижа, а не задачи, споры вокруг него становятся особенно изматывающими.</p><h2>Конфликт как трудности перевода</h2><p>Важная вещь, которую часто пропускают: разные люди воспринимают одно и то же взаимодействие по-разному. Для одних горячий спор — нормальный способ думать вслух и нащупывать решение. Для других тот же разговор выглядит как конфликт, который нужно срочно разрядить или который надо зарепортить, тимлиду или сразу в HR.</p><p>Представьте, что два инженера увлеченно спорят об архитектуре: перебивают друг друга, говорят громко, каждый настаивает на своем. Третий коллега идет к руководителю и взволнованно сообщает, что в команде глубокий конфликт. Двое из начала абзаца искренне удивляются: какой конфликт, мы просто разговаривали. Но наблюдатель снаружи видит драку.</p><p>Проблема возникает, когда команда не договорилась, что считать нормой. Один воспринимает прямую полемику как рабочий режим, другой как личную атаку. Они будут решать разные задачи в одном разговоре и никогда не придут к общему решению, пока не поймут, что разговаривают на разных языках.</p><h2>Молчание как последствие конфликтофобии</h2><p>Если порыться в памяти, мы вспомним истории, когда инженер предлагал идею, но получил отказ — причем без объяснений, просто нет. Инженер предлагает снова, и снова получает неаргументированный отказ. В такой ситуации мало кто предложит инициативу в третий раз. Психологи называют это выученной беспомощностью — человек перестает пробовать, потому что система не воспринимает предложения. А объяснять детали система не обучена или не планирует, ведь чем больше информации она даст участникам системы, тем больше поводов для споров может возникнуть.</p><p>Проходит полгода, и руководители удивляются: почему никто не проявляет инициативы, почему все приходится тянуть самому. Получается, что боязнь конфликтов через неспособность доносить аргументы порождает дальнейшие проблемы.</p><p>А люди оптимизируют поведение под реальные условия. Те, кто уходит из команд, где их не слышали, редко называют настоящую причину даже во время exit-интервью — говорят про оффер, зарплату, должность. Такой отток не попадает ни в какой дашборд, и поэтому его не замечают.</p><p>Маленькое трение, умноженное на количество людей и рабочих дней, становится реальной проблемой производительности. Разница в том, что не всегда можно четко измерить, когда человек не доволен. Это не видно на графиках, и поэтому проще игнорировать, но трение точно ощущается человеком изо дня в день.</p><p>Команды, которые застревают в спорах о технологиях, обычно делают это не из-за недостатка экспертизы. Оказывается, что, когда нет безопасного способа не соглашаться и обсуждать разные мнения, никакие условия труда и семинары по управлению конфликтами ситуацию не улучшат. Но чтобы исправить эту проблему, сначала нужно признать, что это вообще проблема — и, главное, проблема не техническая.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin 2.4.0-Beta2 и Golden Kodee: дайджест Kotlin за апрель</title>
      <link>https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z</link>
      <comments>https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z</guid>
      <description><![CDATA[<p>Главные события Kotlin за апрель: вышел 2.4.0-Beta2 и патч 2.3.21, объявлены финалисты Golden Kodee, готовится KotlinConf 2026. Что обновить уже сейчас.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z">Kotlin 2.4.0-Beta2 и Golden Kodee: дайджест Kotlin за апрель</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>JetBrains <a href="https://blog.jetbrains.com/kotlin/2026/05/kodees-kotlin-roundup-golden-kodee-finalists-kotlin-2-4-0-beta2-and-new-learning-resources/">опубликовала апрельский обзор</a> ключевых событий вокруг Kotlin: вышли <b>Kotlin 2.4.0-Beta2</b> (первый публичный взгляд на следующую мажорную версию языка), <b>Kotlin 2.3.21</b> с фиксами производительности, <b>IntelliJ IDEA 2026.1</b> и <b>Amper 0.10.0</b>. Параллельно объявлены финалисты <b>Golden Kodee</b> — главной комьюнити-награды Kotlin, — и стартовала подготовка к <b>KotlinConf 2026</b>, которая пройдёт 20–22 мая в Мюнхене. До feature-freeze 2.4 остаётся пара месяцев — самое время прогнать бету на своём проекте, пока баги ещё ловят.</p><p>Собрали в одном материале то, что разработчику на Kotlin стоит держать в голове в ближайшие недели — релизы, инструменты, события и ресурсы для прокачки.</p><p><b>Kotlin 2.4.0-Beta2.</b> Ранний обзор будущей мажорной версии: изменения в языке, stdlib, JVM-бэкенде, Kotlin/Native и компиляторе.</p><p><b>Kotlin 2.3.21.</b> Параллельный патч в стабильную ветку 2.3 — оптимизация производительности и баг-фиксы.</p><p><b>KotlinConf 2026.</b> 20–22 мая в Мюнхене, ожидается 2000+ разработчиков. Онлайн-трансляция — на YouTube-канале Kotlin для тех, кто не сможет приехать.</p><p><b>Golden Kodee.</b> Финалисты главной комьюнити-награды объявлены — top 3 в каждой категории получат приглашения в Мюнхен, победителей выберут на конференции.</p><p><b>Tooling.</b> IntelliJ IDEA 2026.1, Amper 0.10.0 (автопровижн JDK, Maven-to-Amper конвертер), Ktor 3.4.3, Dokka 2.2.0, Exposed 1.0+ с поддержкой PostgreSQL array.</p><h2>Kotlin 2.4.0-Beta2 и 2.3.21</h2><p>JetBrains выложила первую <b>Beta2</b> следующей мажорной версии — 2.4.0-Beta2. Это «предварительный взгляд» на то, что попадёт в стабильный релиз 2.4: изменения распределены сразу по нескольким слоям — самому языку, стандартной библиотеке, JVM-бэкенду, Kotlin/Native и компилятору. Если поддерживаете крупный проект — самое время прогнать его на бете и зарепортить регрессии до до заморозки кода.</p><p>Параллельно вышел 2.3.21 в стабильной ветке: фокус на производительности и багфиксах. Если вы пока не готовы переезжать на 2.4 — это безопасный апдейт минор-версии, без сюрпризов.</p><h2>KotlinConf 2026 и Golden Kodee</h2><p>Главное событие года для Kotlin-сообщества — <b>KotlinConf 2026</b>. Пройдёт <b>20–22 мая в Мюнхене</b>, ожидается более 2000 разработчиков из разных стран. Если поехать не получается, JetBrains обещает livestream на <a href="https://www.youtube.com/@Kotlin">YouTube-канале Kotlin</a> — основные кейноты и анонсы можно будет посмотреть в прямом эфире.</p><p>К конференции приурочена ежегодная награда <b>Golden Kodee</b> для самых заметных людей сообщества — тех, кто организует мероприятия, делится знаниями, помогает новичкам. Финалисты в каждой категории объявлены: топ-3 в каждой категории приглашают в Мюнхен, победителей объявляют на конференции.</p><p>Из спикеров — стоит обратить внимание на keynote второго дня от <b>Лены Райнхард</b>: она будет говорить про карьеру в IT, лидерство, неопределённость на рынке и что значит «продуктивность» в эпоху ИИ.</p><h2>Инструменты: IntelliJ, Amper, Koog, Ktor</h2><p>Главные инструментальные апдейты апреля:</p><ul><li><b>IntelliJ IDEA 2026.1.</b> Общая оптимизация производительности + улучшенная поддержка языков и фреймворков. Это значимый апдейт IDE, на который стоит переехать всем Kotlin-разработчикам.</li><li><b>Amper 0.10.0.</b> Инструмент сборки от JetBrains получил автоматический provisioning JDK (больше не нужно вручную ставить нужную версию), Maven-to-Amper конвертер (полезно для миграции проектов с легаси-кодом), поддержку кастомных Kotlin плагины компилятора и общее улучшение IDE-опыта.</li><li><b>Koog для JVM-экосистемы.</b> Koog — фреймворк JetBrains для построения AI-агентов на JVM. Появился идиоматичный Java API — теперь Java-команды могут строить пайплайны агентов без переписывания на Kotlin. Кроме того, Koog интегрировался со <b>Spring AI</b> — для Kotlin/Spring проектов это знакомый стек для работы с агентами.</li><li><b>Ktor 3.4.3.</b> Очередной патч асинхронного фреймворка для серверов и клиентов на Kotlin.</li><li><b>Dokka 2.2.0.</b> Стандартный документ-генератор для Kotlin-проектов.</li><li><b>Exposed 1.0+.</b> SQL-фреймворк теперь поддерживает array-типы PostgreSQL «из коробки» — раньше для этого нужны были custom-расширения.</li></ul><h2>Бэкенд, мультиплатформа и WebAssembly</h2><p>Несколько практических материалов для тех, кто работает с Kotlin на бэкенде или в мультиплатформенных проектах:</p><ul><li><b>Spring Data JPA с Kotlin.</b> Гайд про entities, repositories, custom queries и DTO — полезно для команд, уже сидящих на Spring и думающих про переход с Java на Kotlin.</li><li><b>Spring guide: Uploading Files на Kotlin и Java.</b> Параллельное сравнение помогает увидеть, как Kotlin вписывается в существующие бэкенд-процессы.</li><li><b>Kotlin + WebAssembly</b> с примером wasi:http (стандарт WebAssembly System Interface для HTTP-серверов) — минимальный HTTP-сервер на Kotlin/Wasm. Не production-ready, но ясно показывает, в каком направлении движется WebAssembly у Kotlin.</li><li><b>KMP-аргументы для бизнеса.</b> Гостевой пост от Touchlab про то, как объяснять руководству ценность Kotlin Multiplatform: ускорение поставки, снижение рисков, долгосрочная продуктовая стратегия. На tproger у нас был <a href="https://tproger.ru/news/creating-an-app-for-kotlin-multiplatform">базовый туториал по созданию первого KMP-приложения</a> для тех, кто хочет потрогать руками.</li></ul><h2>Обучение и развлечение</h2><p>Если хочется прокачать или закрепить Kotlin — два полезных ресурса:</p><ul><li><b>Kotlin Professional Certificate by JetBrains</b> на LinkedIn Learning. Четыре курса, финальный экзамен, сертификат на профиль. Заявленная длительность — менее 12 часов общего материала.</li><li><b>Coroutines Races Guesser Game</b> от kt.academy. Интерактивная игра: предсказываете, как поведут себя корутины в разных ситуациях. Хороший способ проверить интуицию по асинхронной логике, особенно если давно не работали со Structured Concurrency.</li></ul><h2>Выводы</h2><p>Апрель в Kotlin-экосистеме оказался плотным: одновременно вышли беты будущей мажорной версии, патчи стабильной ветки, обновления IDE, инструментов сборки и фреймворков. Параллельно сообщество готовится к KotlinConf и финалу Golden Kodee. Если вы поддерживаете Kotlin-проект — стоит как минимум обновить IntelliJ до 2026.1 и поставить 2.3.21 в стабильный пайплайн.</p>]]></content:encoded>
    </item>
    <item>
      <title>Apple выпустила Swift SDK для написания Android-приложений — спустя 11 лет после релиза языка</title>
      <link>https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka</link>
      <comments>https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka</guid>
      <description><![CDATA[<p>Apple выпустила Swift SDK для Android — теперь на Swift можно писать нативные Android-приложения и переносить код между платформами</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka">Apple выпустила Swift SDK для написания Android-приложений — спустя 11 лет после релиза языка</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Objective-C]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[iPhone]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 27 Oct 2025 04:06:16 GMT</pubDate>
      <content:encoded><![CDATA[<p>Apple неожиданно открыла новую страницу в истории Swift.</p><p>Компания <a href="https://www.swift.org/blog/nightly-swift-sdk-for-android/">представила</a> <b>официальный Swift SDK для Android</b>, позволяющий писать нативные Android-приложения на фирменном языке, изначально созданном для iOS и macOS.</p><h2>От iPhone до Android</h2><p>Swift появился в 2014 году как альтернатива Objective-C — более безопасный, современный и лаконичный язык для экосистемы Apple.</p><p>За 11 лет он вырос из «внутреннего» инструмента в многофункциональную платформу, на которой создают <b>облачные сервисы, десктопные приложения для Windows и даже прошивки для микроконтроллеров</b>.</p><p>Теперь Swift впервые официально выходит за пределы «яблочной экосистемы. Превью-версия SDK для Android доступна уже сегодня — в составе Swift-инсталлятора для Windows или отдельно для macOS и Linux.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-10-27/9d4f131a-7f10-47c1-a75b-3180cfe12892.jpeg" alt="" /></figure><h2>Как это работает</h2><p>Новый SDK — результат многомесячной работы <b>Swift Android Workgroup</b>, открытого сообщества, куда может присоединиться любой разработчик. С его помощью можно:</p><ul><li>собирать <b>нативные Android-приложения</b> на Swift;</li><li><b>переносить существующие Swift-пакеты</b> — более 25% уже совместимы с Android;</li><li><b>интегрировать Swift-код с Java</b> через проект <b>swift-java</b>, автоматически генерирующий безопасные биндинги между языками.</li></ul><p>Apple <a href="https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html">опубликовала</a> подробное руководство <i>«Getting Started»</i> и примеры кода, демонстрирующие полный цикл разработки Android-приложений на Swift.</p><h2>Что это значит для экосистемы</h2><p>Релиз открывает дорогу к кроссплатформенным приложениям без использования Flutter, Kotlin Multiplatform или React Native.</p><p>Теперь компании смогут писать бизнес-логику один раз на Swift и использовать ее и в iOS-, и в Android-версиях.</p><p>Эксперты отмечают, что шаг Apple может <b>снизить барьеры между мобильными экосистемами</b> и ускорить развитие open-source сообщества Swift.</p><h2>Что дальше</h2><p>По словам участников проекта, впереди — создание полноценного Android-Toolchain, улучшение совместимости со средами разработки и официальное внедрение CI-сборок.</p><p>Разработчики уже готовят документ с видением будущего Swift на Android, который определит приоритеты и стратегию развития.</p><p><i>«Swift вырос из языка для iOS в универсальный инструмент для всего программного мира. Теперь он будет жить и в Android-экосистеме»</i>, — говорится в сообщении разработчиков.</p>]]></content:encoded>
    </item>
    <item>
      <title>CameraX 1.5: Как обеспечить совместимость функций камеры в Android-приложениях</title>
      <link>https://tproger.ru/articles/camerax-1-5--kak-obespechit-sovmestimost-funkcij-kamery-v-android-prilozheniyah</link>
      <comments>https://tproger.ru/articles/camerax-1-5--kak-obespechit-sovmestimost-funkcij-kamery-v-android-prilozheniyah?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/camerax-1-5--kak-obespechit-sovmestimost-funkcij-kamery-v-android-prilozheniyah</guid>
      <description><![CDATA[<p>CameraX 1.5 упрощает разработку Android-приложений для камеры с новым API Feature Group. Узнайте, как гарантировать поддержку комбинаций HDR, 60 FPS и стабилизации для создания надежных и мощных приложений.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/camerax-1-5--kak-obespechit-sovmestimost-funkcij-kamery-v-android-prilozheniyah">CameraX 1.5: Как обеспечить совместимость функций камеры в Android-приложениях</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 Oct 2025 12:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Эта статья — </i><a href="https://android-developers.googleblog.com/2025/10/beyond-single-features-guaranteeing.html">перевод</a><i> оригинального материала о новых возможностях CameraX 1.5, адаптированный для русскоязычной аудитории с сохранением смысла и стиля оригинала.</i></p><p>Современные приложения для камеры должны сочетать мощные функции: пользователи хотят снимать видео в HDR, с частотой 60 кадров в секунду и стабилизацией изображения — и всё это одновременно. Но как разработчику гарантировать, что устройство поддерживает такую комбинацию?</p><p>Ранее совмещение нескольких функций было рискованным: проверка поддержки каждой функции по отдельности не гарантировала их совместной работы. Это могло привести к нестабильной работе камеры или её полному сбою. Чтобы избежать проблем, разработчики ограничивали функциональность, лишая пользователей с мощными устройствами, такими как Pixel 10 Pro, полноценного опыта.</p><p>CameraX 1.5 решает эту проблему с помощью нового API Feature Group. Теперь вы можете заранее проверить поддержку комбинации функций или задать приоритеты, а библиотека сама подберёт оптимальную конфигурацию для устройства.</p><h2>Что такое CameraX?</h2><p>CameraX — это библиотека Jetpack, которая упрощает разработку приложений для камеры на Android. Она предлагает удобный и единообразный API, совместимый с большинством устройств, начиная с Android 6.0 (API level 23). Для новичков рекомендуем изучить <a href="https://developer.android.com/media/camera/camerax?hl=ru">официальную документацию</a> и пройти практический <a href="https://developer.android.com/codelabs/camerax-getting-started#0">codelab.</a></p><h2>Возможности API Feature Group</h2><p>Новый API позволяет создавать продвинутые приложения для камеры, избегая проблем с совместимостью. Вы сможете:</p><ul><li>Создавать адаптивные интерфейсы: Динамически включать или отключать настройки в зависимости от возможностей устройства. Например, если пользователь включает HDR, опция 60 FPS автоматически станет недоступной, если комбинация не поддерживается.</li><li>Реализовать режим “Максимальное качество”: Укажите желаемые функции с приоритетами, и CameraX выберет лучшую комбинацию, поддерживаемую устройством, без сложной логики.</li><li>Избежать сбоев: Проверка поддержки комбинаций заранее предотвращает ошибки при настройке камеры, обеспечивая стабильную работу.</li></ul><h2>Как это работает: основные компоненты</h2><p>API построен на обновленных классах SessionConfig и CameraInfo.</p><ul><li><b>GroupableFeature:</b> Включает набор функций, таких как HDR_HLG10, FPS_60, PREVIEW_STABILIZATION и IMAGE_ULTRA_HDR. Список пока ограничен из-за вычислительных требований, но будет расширен в следующих версиях.</li><li><b>Новые параметры SessionConfig:</b>requiredFeatureGroup: Для обязательных функций. Если комбинация не поддерживается, вызов bindToLifecycle завершится ошибкой IllegalArgumentException.preferredFeatureGroup :Для необязательных функций. Укажите список с приоритетами, и CameraX выберет лучшую комбинацию.</li><li><b>requiredFeatureGroup:</b> Для обязательных функций. Если комбинация не поддерживается, вызов bindToLifecycle завершится ошибкой IllegalArgumentException.</li><li><b>preferredFeatureGroup: </b>Для необязательных функций. Укажите список с приоритетами, и CameraX выберет лучшую комбинацию.</li><li><b>CameraInfo#isFeatureGroupSupported():</b> Метод для проверки поддержки комбинации функций. Передайте SessionConfig, чтобы узнать, поддерживается ли набор функций, и настройте интерфейс соответственно.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-10-21/2ca60fbb-4915-40de-945d-6469aeccd243.png" alt="" /></figure><h2>Практическое применение</h2><p>Рассмотрим два сценария использования API.</p><h3>Сценарий 1: Режим "Максимальное качество"</h3><p>Чтобы автоматически включить лучшие функции, задайте список приоритетов в preferredFeatureGroup. Например, приоритет: HDR, затем 60 FPS, затем стабилизация. CameraX сам выберет оптимальную комбинацию.</p><p>CameraX проверит комбинации в порядке приоритета, выбрав первую поддерживаемую:</p><ol><li>HDR + 60 FPS + Стабилизация</li><li>HDR + 60 FPS</li><li>HDR + Стабилизация</li><li>HDR</li><li>60 FPS + Стабилизация</li><li>60 FPS</li><li>Стабилизация</li><li>Ничего</li></ol><h2>Сценарий 2: Адаптивный интерфейс</h2><p>Для интерфейса, реагирующего на выбор пользователя, проверяйте неподдерживаемые комбинации:</p><p>Интегрируйте логику в интерфейс для отключения неподдерживаемых опций и привязки стабильной конфигурации:</p><p>Ознакомьтесь с тестовым приложением CameraX для примера реализации (не для продакшена).</p><p>API Feature Group устраняет неопределенность при работе с продвинутыми функциями камеры, позволяя создавать надежные приложения. Он доступен как экспериментальный в CameraX 1.5 и станет стабильным в версии 1.6 с дополнительными улучшениями.</p>]]></content:encoded>
    </item>
    <item>
      <title>Зачем нужны приложения, можно ли писать код на смартфоне — ответы эксперта на самые безумные вопросы о мобильной разработке</title>
      <link>https://tproger.ru/articles/zachem-nuzhny-prilozheniya--pochemu-android-ne--ajfon--mozhno-li-pisat-kod-na-smartfone---otvety-eksperta-na-samye-bezumnye-voprosy-o-mobilnoj-razrabotke</link>
      <comments>https://tproger.ru/articles/zachem-nuzhny-prilozheniya--pochemu-android-ne--ajfon--mozhno-li-pisat-kod-na-smartfone---otvety-eksperta-na-samye-bezumnye-voprosy-o-mobilnoj-razrabotke?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/zachem-nuzhny-prilozheniya--pochemu-android-ne--ajfon--mozhno-li-pisat-kod-na-smartfone---otvety-eksperta-na-samye-bezumnye-voprosy-o-mobilnoj-razrabotke</guid>
      <description><![CDATA[<p>Ответы на самые странные и частые вопросы о мобильной разработке: в чем разница между iOS и Android, почему нужно платить $99 для тестирования на iPhone и можно ли писать код на смартфоне. Обсуждаем Flutter, нативную разработку, пуши и безумные требования менеджеров с экспертом Аней Жарковой. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/zachem-nuzhny-prilozheniya--pochemu-android-ne--ajfon--mozhno-li-pisat-kod-na-smartfone---otvety-eksperta-na-samye-bezumnye-voprosy-o-mobilnoj-razrabotke">Зачем нужны приложения, можно ли писать код на смартфоне — ответы эксперта на самые безумные вопросы о мобильной разработке</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 18 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В юмористическом <a href="https://www.youtube.com/watch?v=q0PtYxsg03U">выпуске</a> подкаста «Спроси айтишника» <a href="https://darovska.com/">Маша Даровская</a>, шеф-редактор Tproger, автор телеграм-канала <a href="https://t.me/MashaDevRel">«Деврелишна»</a> и Аня Жаркова, руководитель мобильной разработки в USETECH, ищут ответы на самые странные и неожиданные вопросы подписчиков.</p><p><b>Смотреть подкаст на <a href="https://www.youtube.com/watch?v=q0PtYxsg03U">YouTube</a>, в <a href="https://vk.com/video-30666517_456246783">VK</a></b>.</p><p>Анна Жаркова пишет нативные приложения под iOS и Android и кросс-платформенные приложения на Xamarin, Xamarin.Forms и Kotlin Multiplatform. Написала книгу о Kotlin Multiplatform, которая выходит в сентябре. Пишет статьи, выступает на конференциях и митапах. Член программного комитета Mobius, CodeFest, «Стачка». Увлекается живописью и участвует в выставках.</p><p>Поговорили о безумных проджект-менеджерах, войне Android и iOS, о том, почему ИИ не заменит программистов, и что делать, если вам позарез нужно установить ВСЕ приложения из магазина. Добро пожаловать в абсурдный и увлекательный мир мобильных разработчиков!</p><h2>О смысле мобильных приложений</h2><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-01/5b4fca7c-0c3e-406b-982a-b7cef90e550f.jpg" alt="" /></figure><p><i>Какие нам вопросы задали наши прекрасные подписчики. Первый вопрос: «А зачем вообще нужны мобильные приложения? У меня вот компьютер, а у друга ноутбук». </i></p><p>Ну, да, вопросы бывают разные, мы к этому привыкли. Начнём с того, что это, конечно, здорово, что есть компы и ноутбуки, но с собой человек, скорее всего, носит именно смартфон, а не компьютер или ноутбук.</p><p>Если попробовать ответить на этот вопрос серьёзно: мобильное устройство — это не просто «звонилка», это ещё и полезные клиентские приложения, которые позволяют получить быстрый доступ к информации или услугам. Конечно, это всё можно сделать и с компьютера, но главное назначение мобильного устройства — дать вам максимум возможностей при минимуме затрат: ресурсов, времени и с минимальным размером самого устройства.</p><p><i>Ну да, взять то же банковское приложение, оплату с телефона… Ребята, с компьютером не походишь, чтобы это всё делать. Давай поедем к следующему. Можно делать так, чтобы приложение ставилось не из App Store?</i></p><p>Конечно. Если это приложение под Android, оно будет ставиться через Google Play, а также есть специальные магазины, например, AppGallery для Huawei или RuStore. Также у некоторых вендоров есть свои маркеты, например, у Samsung.</p><p>Если же говорить про iOS, то тут всё строго с App Store. Но кто знает, возможно, в будущем появятся и кастомные магазины для iOS. Хотелось бы, чтобы поскорее.</p><p><i>А скажи, пожалуйста, насколько широкий ассортимент приложений в этих альтернативных магазинах? У меня всё на яблоках, я не особо разбираюсь, что там происходит, особенно с Huawei, с RuStore. Можешь рассказать, насколько там всё хорошо или плохо?</i></p><p>Я думаю, если говорить про приложения, которые имеют ограничения в загрузке в App Store, они, в принципе, есть и в Google Play, но свободно грузятся в остальные магазины. Особых ограничений нет. Конечно, бывают ситуации, когда приложение пропадает из магазина по чьей-то жалобе. Но выбор приложений довольно большой. Например, в компании, где я работаю, мы свободно загружаем наши приложения в разные магазины, и всё в порядке.</p><p><i>Супер. А насколько вообще отличается разработка для, скажем, Huawei от классической Android? Там есть какая-то своя специфика, или всё тоже самое? Может, свой стэк?</i></p><p>Плюс-минус как Android, но есть определённые различия. У них своя среда разработки, свои сервисы, дополнительные технологии. Тема довольно обширная, но в принципе, всё это плюс-минус то же самое, и Android-разработчику освоить это несложно. Главное — поставить нужную IDE (Интегрированную среду разработки) и взять устройство для отладки.</p><p>А какие там специфические IDE?</p><p>Да, там есть, по-моему, собственная IDE, но я скажу честно, я с ней особо не работала. Я сейчас копаю немножко в другом направлении.</p><h2>О фантастическом девайсе</h2><p><i>«Пользователю позарез нужно установить вообще все мобильные приложения, которые существуют на маркете. Всё использует, всё жизненно важно. Вопрос: что представлял бы из себя девайс, который смог бы это выдержать?» Я с трудом представляю, интересно твоё мнение.</i></p><p>Что ж, ну, возникает вопрос: наверное, у этого пользователя очень много денег, он может позволить себе все платные приложения. Порадуемся за него!</p><p>Но если говорить про аппарат, то это должен быть какой-то супермощный с параметрами из серии «Чёрная дыра». Современное приложение, тот же самый «суперап», который объединяет кучу сервисов, может занимать сотни мегабайт. Обычное банковское приложение — тоже несколько сотен мегабайт.</p><p>Поэтому если у пользователя есть какой-то супермощный компьютер, возможно, он причастен к каким-то научным, суперсекретным, может быть, даже военным разработкам, и у него память на каком-то кристалле из чёрной дыры… то, возможно, это и сработает.</p><p>В реальности, конечно, это похоже на шутку «я сейчас все игры установлю». Но ни одного нормального девайса даже с супервозможностями не хватит. Сейчас максимум — это 512 ГБ внутреннего хранилища, часто без возможности расширения. Но даже с картой памяти вам точно не хватит.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-01/d12496af-061b-410d-af88-6a36063e3ef1.jpg" alt="" /></figure><p><i>Да, вот у меня даже на айфоне он сгружает в облако всё, что не нужно. И у меня стоит довольно много приложений, в том числе детские, с ИИ, чтобы звёзды смотреть, цветы диагностировать… Куча странных приложений, которые я использую очень ситуативно. Я не представляю, сколько надо времени, чтобы скачать себе даже десятую часть всех существующих приложений в Store. Ну, это невозможно.</i></p><p>Ну, может, человек решил стать суперблогером по приложениям, решил сделать краш-тест всего маркета и всех возможных аппаратов. Удачи ему и успехов.</p><h2>О разработке на мобильном телефоне</h2><p><i>«Раз для компов проги пишут на компах, разве не уместнее для мобилок писать на мобилках?»</i></p><p>Кстати, очень хороший вопрос. На заре энтузиазма, когда только появлялись смартфоны, все считали: «Сейчас они будут настолько мощные, что не понадобится настоящий комп, чтобы писать программы».</p><p>Но это столкновение с реальностью. Девайс довольно слабенький, и ресурсов не хватит. Это сложный процесс: чтобы скомпилировать приложение, необходимо несколько гигабайт свободной памяти и много вычислительных ресурсов.</p><p>Конечно, на мобильном устройстве можно скомпилировать какие-то простые, легковесные приложения, например, на скриптовых языках. Есть такие технологии. И в том числе можно использовать мобильные устройства как инструмент для разработки. У того же GitHub такое было.</p><p>Но честно говоря, если есть желание что-то писать на мобильном аппарате, то лучше работать с облачными средами разработки. Потому что даже на компе та же Android Studio может кушать очень много памяти и сохранять много кэша. Облачная среда, конечно, в какой-то степени небезопасна, потому что вы что-то загружаете на сторонние сервера. Но если это ваше собственное, настроенное место, то вполне можно по удалёнке получать доступ. Другой вопрос, что вам тогда необходим хороший интернет.</p><p><i>Ну, ты знаешь, у меня вот был странный опыт. Когда я училась на Python-разработчика, у меня был старый макбук. Он у меня сдох через полгода, просто потому что не вывез: ты ставишь все эти библиотеки, прописываешь команды, подгружаешь версии… В общем, у меня просто сдох жесткий диск. Поэтому да, хороший вопрос. Не всякий даже ноут это выдержит, как выяснилось.</i></p><p>Более того, даже для сборки мощных мобильных приложений на Mac сейчас часто требуется 32, а то и 64 ГБ памяти. Были бы, конечно, такие крутые мобильные устройства, полноценные мини-компьютеры… Но это уже из области фантазии наших зрителей.</p><h2>О Keycloak и мобильной безопасности</h2><p><i>Так, следующий вопрос. «Подскажите, кто-нибудь пользуется Keycloak для SSO (стандарт единого входа)?»</i></p><p>Интересный, конечно, вопрос про Keycloak. Я слышала такое слово от бэкендеров — это механизм, который используют для безопасности на бэкенд-части. Но что примечательно, с вопросом про Keycloak часто приходят именно к нам, мобильным разработчикам.</p><p>Тебе говорят слово «Keycloak», и ты думаешь: «Хорошо, а я тут причём?» Так что да, это довольно часто задаваемый не по адресу вопрос. Ответ — спросите у аналитика или у бэкенд-разработчика.</p><p><i>А как ты думаешь, почему к мобильным разработчикам приходят с этим вопросом?</i></p><p>Я думаю, потому что говорят, что это какой-то механизм, необходимый для безопасной разработки. И часто люди путают, с чьей стороны должно быть внедрение того или иного решения.</p><p>Keycloak — это система идентификации и управления доступом с единой точкой входа. Мобильное приложение — это фронтенд-клиент, который обращается к API вашего сервера. Поэтому вся система должна быть реализована на бэкенде. Мобильщик будет лишь использовать готовое API. Если вам говорят, что вы должны это сделать сами на мобилке, ну тогда вы, получается, не мобильщик, а фуллстэк. Я вас поздравляю!</p><h2>О выборе технологии: натив vs Flutter</h2><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-01/1a7ae6af-57d6-433a-8a89-adddc189ab51.png" alt="" /></figure><p><i>Так, переходим к следующему вопросу. «Стоит ли погружаться в нативную разработку или сразу учить Flutter?»</i></p><p>Очень хороший вопрос. Flutter — это отдельная технология со своим языком Dart. Но тут есть маленький нюанс. Да, Flutter — технология отличная, но вы разрабатываете под Android и iOS, и поэтому вам необходимы знания нативной разработки, хотя бы в минимальном объёме. Есть проекты, где пишут код Flutter-разработчики, но от них требуют хороших, крепких знаний по нативу хотя бы одной платформы.</p><p>Когда у вас есть такой базис, вы понимаете, что вам необходимо сделать: как работать с жизненным циклом, с памятью, с сенсорами, с моделью разрешений. Всё это — знания натива, и без этого не обойтись. Это необходимо.</p><p><i>То есть, сначала учим какую-то одну платформу как базу, а потом уже идём во всякие Flutter’ы с ними.</i></p><p>Безусловно. Вы исходите из того, что пишете под Android (или iOS). И уже смотрите: как я могу это делать? Я могу писать на нативе, а могу на Flutter’е. Но Flutter всё равно будет опираться на натив, поэтому получается такая ступень по изучению технологий.</p><h2>О роли ИИ в мобильной разработке</h2><p><i>Что сейчас можно сделать с помощью ИИ в мобильной разработке?</i></p><p>Довольно много. Но тут возникает уточняющий вопрос: использовать ИИ как инструмент или внедрять ИИ в приложение? Есть возможности по внедрению ИИ, чтобы оно что-то генерировало в вашем приложении: умные ассистенты, генерация изображений и т.д.</p><p>Есть также возможности с помощью ИИ генерировать код. Но это явно не для начинающих. Почему? Потому что ошибок в таком коде довольно много. Чтобы этот код работал, нужен человек, который понимает, как такой код писать самому. То есть ИИ может помочь сократить время, выступить инструментом генерации, но не более.</p><p>К тому же сейчас есть технологии, которые позволяют разместить у себя модель нейросети, обучить её под свои нужды и использовать. Да, это дорого и ресурсоёмко, но возможность есть. В целом, возможности широкие, но они не заменят нормального разработчика. Все помнят мем про кружку, которую ИИ не догадался перевернуть? Это показательно.</p><p><i>Вопрос от этого же задавателя вопросов. «Используют ли Kotlin Multiplatform React Native (технологии для кроссплатформенной разработки) и так далее? Если да, бывают ли задачи с адаптацией под мобильный веб?»</i></p><p>Хм, хороший вопрос. Если говорить про работу с искусственным интеллектом в контексте этих технологий… Вы можете попробовать сгенерировать код под любую платформу. Для этого нужно писать много промтов и иметь много ресурсов для обучения модели.</p><p>Но если говорить о продакшене, то тут имеет смысл использовать только то, что безопасно. Есть компании, которые разрабатывают свои инструменты на основе LLM-моделей, как, например, Яндекс. Есть те, кто берут открытые модели, разворачивают их и используют.</p><p>А вот публичные сервисы вроде ChatGPT я не рекомендую использовать для продакшена. Они могут залогировать ваш код и потом выдать его кому-то. Это крайне небезопасно. В прошлом или позапрошлом году был скандал, когда ChatGPT выдавал куски кода одной компании, вплоть до креденшиалов. Так что в продакшене — только собственные решения.</p><h2>О сегментации рынков Android и iOS</h2><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-01/401fce44-6d95-4999-b01d-dbe53c1609ca.jpg" alt="" /></figure><p><i>Насколько реально сегментированы рынки Android и iOS?</i></p><p>Если говорить про iOS, то тут всё просто: один вендор — Apple. Вся экосистема: iOS, iPadOS, watchOS, специальная OS для авто. Минимальная сегментация. А вот с Android вендоров много. Это и гиганты типа Samsung, большой кусок рынка у Xiaomi и её суббрендов вроде Poco или Redmi.</p><p>Но стоит не забывать, что есть страны Латинской Америки, Африки, Юго-Восточной Азии, где ситуация с разработкой и устройствами совершенно другая, чем в Штатах, Европе или СНГ. Там до сих пор используют такие технологии, как Cordova, PhoneGap, потому что это дёшево, а iPhone там очень непопулярны — банально не по карману.</p><h2>О самых сложных задачах</h2><p><i>Какие задачи в мобильной разработке самые сложные?</i></p><p>Всё зависит от того, что считать задачами. Есть интересные фичевые задачи, которые дают возможность разрабатывать что-то новое. Есть рутинные, неинтересные, но простые задачи, которые просто отнимают много времени.</p><p>А есть задачи-челленджи, когда ты создаёшь что-то на основе сложной библиотеки или, наоборот, из простых исходников делаешь суперсложное решение — например, для работы со звуком, видео, сканеры и т.д.</p><p>Но многие скажут, что самая сложная задача — это работа с заказчиком, с ТЗ, работа между командами. То есть, есть элемент технического челленджа, а есть — психологического. Разработчику надо уметь преодолевать и те, и другие, потому что это позволяет потом работать проще и интереснее.</p><h2>Об ассемблере в 2025 году</h2><p><i>«Какое место в Android и, видимо, iOS-разработке занимает ассемблер в 2025 году?» Вообще ассемблер и мобильная разработка, мне кажется, две немножко разные сущности.</i></p><p>Честно говоря, я не пользовалась ассемблером для мобильной разработки. Если у того, кто это задал, есть наработки, пусть пришлёт, посмотрим. Или придёт на Mobius и расскажет про это — у нас ещё открыт CFP. Если это будет супер-хардовый доклад, это будет здорово!</p><p>Например, пару лет назад у нас был человек, который встроил Doom (а он написан на ассемблере) в SwiftUI. То есть низкоуровневое что-то встраивается через C, C++ (например, через NDK для Android). Всё это можно сделать.</p><p>Но возникает вопрос: зачем? Потому что есть решение «потому что могу» — и это круто. А есть принцип разумной достаточности: не надо усложнять решение там, где это не нужно. Мы экономим и делаем оптимальной не только архитектуру приложения, но и время разработчика. Так что, отвечая на вопрос: есть Doom UI. Можете посмотреть: где только Doom не запускали.</p><h2>О дизайне под Android и iOS</h2><p><i>«Почему менеджеры и дизайнеры всегда хотят, чтобы на Android всё выглядело точно так же, как на iOS?»</i></p><p>Я думаю, потому что это красиво. У iOS долгое время очень много вкладывалось в визуал, в неповторимые жесты и систему. Это было просто супер. Затем Google решил догнать. Сначала появился Material Design, потом более продвинутый. И теперь, если посмотреть на доклады Google и Apple, можно заметить, что в какой-то момент предложения инженеров Google превращают Android в iOS, а у iOS есть тенденция становиться визуально похожим на Android.</p><p>Основная причина, почему хочется использовать iOS-подобный дизайн на Android, — «потому что красиво». Но Android не повезло: красивые вещи довольно затратны. Изначально Android затачивался под аппараты для всех, включая страны с дешёвыми устройствами малой мощности. Тащить туда всю красоту — вредить пользователям. Там действует принцип «максимум возможностей при минимальных затратах».</p><p><i>Ну да, Apple всегда стремились делать очень красиво. Так, скоро же выйдут новые модели Apple, они там всё выкатят в сентябре. Там какие-то изменения по разработке будут под iOS?</i></p><p>Я думаю, не без этого. Изменения идут каждый год, иногда несколько раз в год. Но что хорошо у Apple и Google — нет таких радикальных изменений, чтобы все бросали работу и шли переписывать приложение под новую парадигму.</p><p>Были у них такие периоды, но это было связано скорее с языками (Swift у Apple, Jetpack Compose у Google), которые сильно менялись. Но кардинальной смены инструментов или парадигмы в ближайшее время не планируется.</p><h2>Крик души мобильного разработчика</h2><p><i>Так, ещё у нас остался один большой вопрос, прямо крик души. Цитирую: </i><i>«Почему на симуляторе всё работает, а на телефоне нет? Телефон тупее? Если отключу фоновые процессы, батарейка начнёт заряжаться в обратную сторону? А можно сделать так, чтобы приложение работало одинаково на всех 19 тысячах моделей телефонов? Почему я должна платить 99 долларов в год, чтобы тестировать на своем же телефоне? Почему пуши приходят только тогда, когда я уже сама все проверила вручную? Почему SwiftUI делает все проще, но я все равно страдаю?»</i></p><p>Я так понимаю, это крик души. Мы пойдём по частям. Судя по желанию, «чтобы оно работало везде одинаково», — это PM или Product Owner detected. «Нехорошо, неправильно не делайте, делайте правильно». Вот такой тезис.</p><p>Давай пройдёмся по частям.</p><p><b>Про симулятор и телефон.</b> Эмулятор имеет ограниченные ресурсы и параметры ОС. Он запускается на вашем компьютере, где ресурсов больше, и вы можете настроить сеть, например, прокси. А телефон — это реальное железо с ограниченными ресурсами, которых может не хватить. Кроме того, на эмуляторе некоторые вещи могут игнорироваться или, наоборот, не воспроизводиться. Тестировать на эмуляторе безопаснее для вашего телефона, его ресурсы просто сожрутся. Хотя тестировщик, конечно, должен проверять на реальных устройствах.</p><p><b>Про 99 долларов.</b> Вы платите не мне, а компании Apple. А компания Apple считает, что вы должны платить, «потому что они красивые». Вот. Такова жизнь.</p><p><b>Про пуши и SwiftUI.</b> Можно сказать, что страданиями душа совершенствуется, а также навыки разработчика. У каждой технологии есть подводные камни, главное — правильно её использовать. Но даже если вы знаете, как правильно, вы не застрахованы от багов и питфолов.</p><p>С пушами отдельная история. Доставка пуш-уведомлений — вещь негарантированная. Многое зависит от сервиса, который вы используете (Firebase часто капризничает, try RuStore, они стабильнее), от территориальных особенностей, от того, как настроена рассылка. На Android и iOS разные политики работы с пушами. Иногда, если понизить приоритет пушам, они дойдут гарантированнее, чем с высоким приоритетом. Всё индивидуально.</p><p>А по SwiftUI... Я очень сочувствую вашему опыту. Если вы посмотрите WWDC последних двух лет, особенно этот год, они даже не прикладывают исходники тех примеров, которые показывают. То есть покажут сниппет, а целиком приложение не дают. Так что, возможно, это всё на их совести. Пусть они спят плохо.</p><h2>О собеседованиях и офферах</h2><p><i>«Почему для получения оффера недостаточно, что в своём телефоне я разработчик?»</i></p><p>Хороший вопрос. Когда вы приходите на собеседование и у вас проверяют знания, это не потому что мы редиски и хотим попить вашу кровушку. Мы выбираем человека, с которым будем работать.</p><p>Это как на стройке: есть прораб и рабочие. Каждый делает свою операцию. Человек, которого мы ждём в коллектив, будет брать часть нашей работы. А вы меняете ваше время, усилия и навыки на денежки. Вот так работает экономика.</p><p>Чтобы вы получили оффер, мы должны понимать, что вы придёте и сможете делать задачи. 90% вопросов на собеседовании — это либо общая теория, либо обсуждение кейсов. Тестовые задания сейчас практически не дают, особенно на миддлов и сеньоров. Мы надеемся, что человек с опытом может мысленно разложить задачу и рассказать, как бы он это сделал. Чтобы показать, что он сможет с этим работать.</p><p><i>Скажи, а вот такие тест-кейсы на собеседованиях помогают вычислить и не допустить тех, кто опыт накручивает?</i></p><p>Ох, на самом деле да. Бывает, людей вводят в заблуждение разные кураторы, и они считают, что если суперуверенно рассказать что-то HR, то он уже прошёл. Вот эти кейсы, где предлагается подумать и рассказать, как бы ты это делал, — довольно показательны.</p><p>Тем более, человек может запнуться на теории, войти в ступор. У меня самой такое было лет шесть назад. А когда просишь рассказать, как бы ты это делал, это показывает, как человек думает, как решает задачи на практике, с какими технологиями он умеет работать.</p><p>Если человек говорит: «Это всё гуглится», — возникает вопрос: «Зачем ты тогда тут?» Кейсы экономят время, не у всех может открыться среда для лайвкодинга, и они помогают понять, как человек мыслит и насколько он адекватен.</p><h2>Об автомобильной разработке</h2><p><i>Так, и вот последний странненький, на мой взгляд, вопрос. «Зачем нужны специалисты по мобильной разработке, если есть уже автомобильная?»</i></p><p>Хороший вопрос. Можно обыграть, что автомобильная — это разработка на vibe-кодинге, just for fun. Если говорить серьёзно, то автомобильную разработку тоже делают мобильные разработчики! Так что можно быть автомобильным разработчиком, но не сужайте себе поле, попробуйте другие девайсы, вам тоже понравится.</p><p>Например, брать с собой в карман автомобиль — это, конечно, шикарно, но не везде реализуемо. Он тяжёлый.</p>]]></content:encoded>
    </item>
    <item>
      <title>WebAssembly 3.0 добрался до браузеров: 64-битная память, сборщик мусора и настоящие исключения</title>
      <link>https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya</link>
      <comments>https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya</guid>
      <description><![CDATA[<p>WebAssembly 3.0 уже работает в браузерах: 64-битная память, полноценный GC, система исключений и новые инструменты для языков</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya">WebAssembly 3.0 добрался до браузеров: 64-битная память, сборщик мусора и настоящие исключения</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Компиляторы]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Firefox]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 18 Sep 2025 03:28:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Спустя три года после релиза версии 2.0, WebAssembly <a href="https://webassembly.org/news/2025-09-17-wasm-3.0/">получил</a> масштабное обновление.</p><p>Новый стандарт 3.0 уже поддерживается большинством современных браузеров и приносит сразу несколько ключевых нововведений.</p><h2>Главное из нововведений</h2><ul><li><b>64-битная адресация:</b> теперь Wasm может использовать i64 вместо i32, что расширяет лимит адресуемой памяти с 4 ГБ до 16 ЭБ (в реальности — до 16 ГБ в браузерах).</li><li><b>Несколько областей памяти:</b> модули теперь могут напрямую использовать и копировать данные между разной памятью, без обходных трюков с импортом других модулей.</li><li><b>Сборка мусора (GC):</b> добавлена поддержка управляемой памяти для языков с автоматическим управлением памятью (например, Java, Scala, Kotlin, Dart).</li><li><b>Типизированные ссылки:</b> улучшенная типизация ссылок и функций позволяет избежать лишних проверок в рантайме.</li><li><b>Исключения:</b> наконец-то появилась полноценная система обработки исключений — с try, throw и catch, как в других языках.</li><li><b>Хвостовые вызовы:</b> позволяют не занимать стек при возврате через вызов, что критично для функциональных языков и оптимизаций.</li><li><b>Расслабленные SIMD-инструкции:</b> добавлены быстрые, но менее детерминированные версии векторных инструкций для повышения производительности.</li><li><b>Детерминированный профиль:</b> теперь для задач с требованием полной воспроизводимости (например, блокчейны) можно включить строго определенное поведение операций.</li><li><b>Аннотации в тексте:</b> появилась возможность вставлять пользовательские аннотации прямо в текстовый формат .wat.</li></ul><h2>Что это значит</h2><p>WebAssembly становится всё ближе к полноценной виртуальной машине для высокоуровневых языков. В новой версии уже появляются компиляторы для Java, OCaml, Scala и прочих ЯП — благодаря поддержке GC и исключений.</p><p>Новый стандарт уже <b>поддерживается в основных браузерах</b>, включая Chrome и Firefox. Независимые движки, такие как Wasmtime, тоже догоняют.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как встроить распознавание паспорта РФ в Android: пошаговое руководство</title>
      <link>https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-android--powagovoe-rukovodstvo</link>
      <comments>https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-android--powagovoe-rukovodstvo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Smart Engines]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-android--powagovoe-rukovodstvo</guid>
      <description><![CDATA[<p>Пошагово объясняем, как встроить быстрое и безопасное распознавание паспорта РФ в Android. Нативное приложение с возможностью распознавания ДУЛ на устройстве.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-android--powagovoe-rukovodstvo">Как встроить распознавание паспорта РФ в Android: пошаговое руководство</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Распознавание]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 30 May 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет, Tproger!</p><p>Мы в <a href="https://smartengines.ru/">Smart Engines</a> занимаемся разработкой софта для распознавания самых разных документов – начиная от паспорта РФ, свидетельства о рождении и заканчивая первичкой вроде УПД или ТОРГ-12, а также банковских карт, номеров телефона и баркодов.</p><p>Наши библиотеки написаны полностью с нуля (на плюсах), мы уделяем огромное внимание скорости алгоритмов, нейросетям (новым архитектурам, размеру и правильному применению) и оптимизации, за счет чего наш софт портируется на любые архитектуры и может быть использован на любой платформе.</p><p>Объяснять (и хвастаться) проще всего на примере – покажем, как развернуть распознавание паспорта РФ прямо на устройстве на Android.</p><h2>Зачем это всё?</h2><p>Кстати, <b>распознавание паспорта РФ на мобильном телефоне</b> – ключевой элемент процесса удостоверения личности в цифровых каналах. Функциональность дает возможность удаленно открывать счета в банковских приложениях, регистрироваться в шеринговых сервисах, покупать билеты на самолеты и поезда и многое другое.</p><p>Кроме того, распознавание на мобильнике открывает возможность к ещё одной функциональности — <b>распознаванию в видеопотоке</b>. При таком сценарии пользователь наводит камеру на документ, а система анализирует входящие кадры до тех пор, пока не будет обеспечено достаточное для распознавания документа качества. Таким образом клиенту не нужно несколько раз переснимать документ, если вдруг кадр не удался — получился размазанным, засвеченным и так далее.</p><h2>Немного вводных</h2><p>SDK <a href="https://smartengines.ru/smart-idreader/">Smart ID Engine</a> – это библиотека, собранная под нативную платформу, конфигурационный бандл и обёртка для вызова функций библиотеки с помощью других языков программирования (в этой статье нам понадобится java).</p><p>Сперва коротко об <b>интерфейсе библиотеки</b>, без этого мы не сможем написать адекватное работающее приложение. Система распознавания включает:</p><ul><li><b>Движок распознавания.</b>  Он создаётся с указанием конфигурационного бандла и представляет собой что-то вроде “склада инструментов” для распознавания различных документов. Движок создаётся в самом начале, существует на всём протяжении жизни (приложения или хотя бы сценария, в котором используется распознавание). От него создаются следующие элементы интерфейса:</li></ul><ul><li><b>Сессия распознавания</b>. Это сам процесс распознавания конкретного физического объекта – паспорта, ВУ, СТС, загранпаспорта и других. Всего по состоянию на сегодняшний день мы поддерживаем более 3 тысяч типов документов.  В сессию можно передать всего одно изображение, а можно - серию изображений последовательно (видеопоток), при этом после каждого нового распознавания результат будет уточняться, а так же на основе уверенности в результате будет приниматься решение, нужно ли распознавать дальше или лучше уже не будет.</li></ul><p><i>Важная оговорка: Вообще сессии бывают разных типов - помимо распознавания документов также существуют сессия сравнения лиц (сравнить два изображения на степень “похожести” или провести проверку определения живости лица. Кстати, это происходит без выявления биометрических дескрипторов). А также сессия файловой форензики (поиск признаков вмешательства в исходное изображение) и другие.</i></p><ul><li><b>Настройки сессии.</b> Они хранят список доступных для распознавания типов документов (сам по себе этот список определяется конфигурационным бандлом), дополнительную информацию о каждом документе, а также позволяют настроить процесс распознавания: задать список ожидаемых типов документов для сессии распознавания (кстати, если поставить *, то система сама определит тип документа из всех преднастроенных шаблонов), включить\выключить проверки признаков подлинности, задать таймаут для сессии распознавания и так далее. Настройки создаются перед созданием самой сессии и не могут редактироваться в процессе распознавания.</li></ul><ul><li><b>Результат распознавания. </b>Это объект, в котором хранится множество различной информации: координаты шаблонов документов (допустим, вторая и третья страницы паспорта ищутся отдельно) и всех полей на этих шаблонах, текстовые поля (вплоть до разбиения на варианты каждого символа с их весами), поля с изображениями, поля с проверками признаков подлинности документа. Как этим всем богатством пользоваться, расскажем чуть ниже.</li></ul><p>Беглого взгляда на этот интерфейс достаточно, чтобы понять, как его правильно встроить в приложение. При старте приложения (или сценария) создаем экземпляр движка, перед непосредственно распознаванием создаем настройки сессии и заполняем их, после чего при переходе на экран с превью камеры создаем саму сессию распознавания и “кормим” её кадрами до тех пор, пока сессия не затерминалится (= не решит, что “ей хватит”). После чего можно переходить к разбору результата распознавания.</p><h2>Как это встраивается и работает</h2><p>А теперь немного кода - покажем, как делается распознавание документа с помощью камеры устройства на Android. Полный код можно найти, перейдя по <a href="https://github.com/SmartEngines/Smart-ID-Engine-SDK/tree/main/Smart-ID-Engine-2.5.0-Full-bundle_idengine-Android">ссылке</a> на GitHub, а ниже – наиболее интересные моменты.</p><p>Начнём с создания движка:</p><p>Объявим класс:</p><p>И приведём его имплементацию:</p><p>Теперь нам нужно создать и подготовить настройки сессии, чтобы библиотека знала, какие именно инструменты использовать при распознавании:</p><p>С имплементацией:</p><p>Дальше, наконец, само распознавание. Поскольку для распознавания нужно откуда-то брать кадры (мы всё же не волшебники), логично завести контроллер, который будет хранить сессию, иметь доступ к камере и кормить сессию кадрами, пока та не попросит остановиться. Реализуем свой ImageProcessor, который будет кормить кадры из превью сессии распознавания:</p><p>Когда в процессе распознавания достигается терминальность, можно переходить к разбору результата распознавания. Результат распознавания хранит в себе множество информации - помимо собственно текстовых полей и фото владельца, там лежит геометрия (координаты документа на изображении), данные проверок признаков подлинности и различные атрибуты.</p><p>Теперь вы знаете, что встроить распознавание паспорта РФ в приложение для Android — намного проще, чем может показаться на первый взгляд.</p><p>Это далеко не единственный вариант использования нашего софта. Как минимум, помимо распознавания документов также можно сверять лица, проверять лицо на “живость”, организовывать распознавание двусторонних документов и еще много чего.</p><p>Но схема работы останется той же: движок – настройки сессии – сессия – разбор результата. Такая схема позволяет как сделать сервер с распознаванием тысяч документов одновременно, так и встроить распознавание хоть в браузер.</p><p>Если заинтересовались – добро пожаловать на <a href="https://smartengines.ru">наш сайт</a>. И не расходимся, скоро расскажем еще много чего интересного!</p>]]></content:encoded>
    </item>
    <item>
      <title>Большой гайд по мобильной разработке от Tproger: полезные статьи, практики и советы</title>
      <link>https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety</link>
      <comments>https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety</guid>
      <description><![CDATA[<p>Делимся нашими статьями про мобильную разработку: iOS, Android, Flutter, SwiftUI, Jetpack Compose, публикация в сторах и советы по доступности — всё в одном месте.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety">Большой гайд по мобильной разработке от Tproger: полезные статьи, практики и советы</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 02 May 2025 10:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мечтаете сделать своё приложение, но не знаете, с чего начать? Или уже пилите продукт, но хочется сильнее прокачаться в Android или iOS? Мы собрали для вас подборку самых полезных и актуальных статей по мобильной разработке от Tproger.</p><p>Сначала — немного базы: теории, языков, платформ. Потом — инструменты, практические гайды и даже ошибки, которых стоит избегать. Сохраняйте, чтобы не потерять!</p><h2>Немного базы</h2><p>Статьи, которые помогут разобраться, с чего начать и куда двигаться:</p><p><a href="https://tproger.ru/articles/pervye-wagi-v-mobilnoj-razrabotke-s-flutter"><b>Первые шаги в мобильно</b>й разработке с <b>Flutter</b></a> — Здесь обзор фреймворка Flutter: настройка окружения, создание первого приложения и особенности виджетов.</p><p><a href="https://tproger.ru/articles/sozdayom-mobilnoe-prilozhenie-s-nulya--ot-idei-do-publikacii-v-app-store-i-google-play">Создаём мобильное приложение с нуля: от идеи до публикации в App Store и Google Play</a> — Делимся полным циклом создания: дизайн, разработка, тестирование, релиз.</p><p><a href="https://tproger.ru/articles/introduction-to-mobile-development">Введение в мобильную разработку для Android: с каких языков начать изучение?</a> — Рассматриваем, с каких языков программирования начать путь в Android-разработке и почему.</p><p><a href="https://tproger.ru/articles/8-jazykov-programmirovanija-dlja-android-razrabotchika">8 языков программирования для Android-разработчика</a> — Перечисляем восемь языков программирования, которые стоит рассмотреть Android-разработчику. Изучаем плюсы, минусы, области применения, особенности.</p><p><a href="https://tproger.ru/articles/kak-stat-android-razrabotchikom-s-nulja-dorozhnaja-karta">Дорожная карта по Android-разработке с нуля</a> — Пошаговое руководство для тех, кто хочет освоить Android-разработку с нуля: от установки среды до публикации.</p><p><a href="https://tproger.ru/articles/osnovy-swiftui-dlya-ios-razrabotchikov">Основы SwiftUI для iOS-разработчиков</a> — Изучаем базовые возможности SwiftUI: декларативная верстка интерфейсов, примеры кода и сокращение сроков разработки.</p><p><a href="https://tproger.ru/articles/nachalo-raboty-v-android-studio-i-pervyj-prostoj-proekt">Начало работы в Android Studio и первый простой проект</a> — Пошаговое руководство по началу работы в Android Studio и созданию первого простого проекта. Учимся пользоваться инструментом с нуля.</p><h2>Практика, инструменты и тонкости</h2><p>Когда разобрались с базой — идём дальше и погружаемся в инструменты и реальные задачи:</p><p><a href="https://tproger.ru/articles/rabota-s-animaciej-v-android-razbiraem-motionlayout">Работа с анимацией в Android: разбираем MotionLayout</a> — Рассказываем, как использовать MotionLayout для создания сложных анимаций в Android-приложениях. С примерами!</p><p><a href="https://tproger.ru/articles/jetpack-compose-i-kotlin--kak-razrabatyvat-sovremennye-ui">Jetpack Compose и Kotlin: как разрабатывать современные UI</a> — Показываем, как разрабатывать современные пользовательские интерфейсы с помощью Jetpack Compose и языка Kotlin. Делимся, как использовать в проектах.</p><p><a href="https://tproger.ru/articles/java-vs-kotlin">Java vs Kotlin для Android-разработки: ответы «за» и «против»</a> — Сравниваем Java и Kotlin для Android-разработки: плюсы, минусы и рекомендации по выбору.</p><p><a href="https://tproger.ru/articles/bojlerplejt-na-fastlane-dlja-integracii-obnovlenij-ci-cd-android-prilozhenij">Бойлерплейт Fastlane для быстрого обновления Android-приложений</a> — Показываем, как использовать Fastlane для автоматизации обновлений Android-приложений, даем рекомендации по применению.</p><p><a href="https://tproger.ru/articles/kak-uderzhat-polzovatelya-v-prilozhenii-s-pomoshhyu-dostupnosti">Accessibility для всех: как удержать пользователя в приложении с помощью доступности</a> — Объясняем, как внедрение accessibility улучшает пользовательский опыт и помогает удержать аудиторию.</p><h2>Про рост, релиз и продвижение</h2><p>Когда всё работает — пора думать про рост, релиз и продвижение:</p><p><a href="https://tproger.ru/articles/kak-dobavit-prilozhenie-v-google-play">Как добавить приложение в Google Play</a> — Объясняем, как подготовить и опубликовать приложение в Google Play: от регистрации до релиза.</p><p><a href="https://tproger.ru/articles/5-glavnyh-oshibok-v-aso-app-store-optimization">5 главных ошибок в ASO — App Store Optimization</a> — Разбираем пять распространенных ошибок в App Store Optimization и как их избежать. Что нужно делать, чтобы не слить продвижение.</p><p><a href="https://tproger.ru/articles/ot-idei-k-uspehu--kak-sozdat-populyarnoe-mobilnoe-prilozhenie">От идеи к успеху: как создать популярное мобильное приложение</a> — Рассказываем, как пройти путь от идеи до успешного мобильного приложения: планирование, разработка, тестирование и продвижение.</p><p>Не забудьте сохранить, чтобы не искать потом по всему интернету!</p><p>Большая подборка по <a href="https://tproger.ru/articles/bolwoj-gajd-po-react-ot-tproger--topovye-stati-i-instrumenty">React</a> — уже на сайте.</p><p>Кстати! Забрать все самые топовые нейронки для айтишников можно в нашем <a href="https://tprg.ru/LN8a">большом гайде с 70+ ИИ-инструментами </a></p>]]></content:encoded>
    </item>
    <item>
      <title>От идеи к успеху: как создать популярное мобильное приложение</title>
      <link>https://tproger.ru/articles/ot-idei-k-uspehu--kak-sozdat-populyarnoe-mobilnoe-prilozhenie</link>
      <comments>https://tproger.ru/articles/ot-idei-k-uspehu--kak-sozdat-populyarnoe-mobilnoe-prilozhenie?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ot-idei-k-uspehu--kak-sozdat-populyarnoe-mobilnoe-prilozhenie</guid>
      <description><![CDATA[<p>Кирилл Васильев, руководитель кластера кросс-функциональных команд в RuStore, рассказывает, как создать популярное приложение.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ot-idei-k-uspehu--kak-sozdat-populyarnoe-mobilnoe-prilozhenie">От идеи к успеху: как создать популярное мобильное приложение</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Социальные сети]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Google Analytics]]></category>
      <category><![CDATA[Xcode]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[Dart]]></category>
      <category><![CDATA[Figma]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Firebase]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 18 Apr 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Создание и продвижение мобильного приложения — это путь, который требует грамотного подхода на каждом этапе. Как разработать идею, выбрать функционал и сделать продукт удобным? Какие инструменты продвижения эффективны в цифровом мире? В этой статье Кирилл Васильев, руководитель кластера кросс-функциональных команд в RuStore, разобрал весь процесс: от идеи до привлечения тысяч пользователей.</p><h2>Определяем цель</h2><p>Успех приложения начинается с четкого понимания, зачем оно нужно — так становится проще определить целевую аудиторию. Это влияет не только на функционал, но и на дизайн, способы продвижения и даже тон общения с пользователями.</p><p>Некоторые программы помогают развивать существующий бизнес — как это делают банковские сервисы, которые упрощают работу с клиентами. Другие становятся самостоятельными продуктами, например, для обучения, занятий спортом или развлечений.</p><p>Кроме того, приложение должно решать реальные проблемы пользователей. Допустим, вы задумали создать программу для фрилансеров. Решили провести исследование, и оно показало, что фрилансеры часто страдают от прокрастинации и ненавидят заниматься выставлением счетов клиентам. Ваша идея и главная фишка — приложение, которое автоматизирует процесс оплаты, контролирует сроки выполнения проектов и помогает планировать рабочее время.</p><p>Чтобы убедиться, что идея действительно рабочая, проведите опросы в Telegram-каналах фрилансеров или создайте анкету. Вы можете спросить, какие функции для них наиболее актуальны: автоматический расчет налогов, интеграция с платежными системами или отслеживание времени работы. Это поможет сфокусироваться на действительно важных фичах и отсеять второстепенные.</p><h2>Выбираем платформу и инструменты</h2><p>Сегодня на российском рынке <a href="https://lenta.ru/articles/2025/03/12/luchshie-smartfony-na-android/">доминируют</a> две мобильные операционные системы: Android (около 70% пользователей) и iOS (около 30%). Оптимальным решением будет разработка приложения для обеих платформ, особенно если вы ориентируетесь на крупные города, где доля пользователей iOS существенно выше.</p><p>Приложения под Android большинство разработчиков пишет на Kotlin, хотя Java до сих пор остается одним из вариантов из-за обширной базы готовых решений и библиотек. Основной средой выступает Android Studio — в ней есть весь необходимый инструментарий для создания, отладки и тестирования приложений. Современные разработчики активно используют Jetpack Compose для построения пользовательского интерфейса, Room для работы с базами данных, Retrofit для сетевых запросов и Dagger или Hilt для внедрения зависимостей.</p><p>В мире iOS основным языком программирования стал Swift — современный и безопасный инструмент для нативных приложений. Разработка ведется в среде Xcode, официальной IDE от Apple. Для построения интерфейсов все чаще используется SwiftUI, для управления данными — Core Data, а для сетевого взаимодействия — фреймворк Alamofire. Работа с асинхронными событиями упрощается с помощью фреймворка Combine.</p><p>При ограниченных ресурсах можно рассмотреть кросс-платформенную разработку. Так, Flutter использует язык программирования Dart и позволяет создавать производительные приложения с нативным внешним видом. React Native дает возможность применять веб-технологии для мобильной разработки, а Xamarin ориентирован на разработчиков, привыкших к экосистеме Microsoft и языку C#.</p><p>Выбор платформы и инструментов должен основываться на характеристиках вашей ЦА, требованиях к функционалу и имеющихся ресурсах. Учитывайте также, что для разных магазинов приложений (RuStore, App Store, Google Play) могут потребоваться специфические оптимизации и настройки.</p><h2>Продумываем функционал</h2><p>При разработке функционала важно следовать концепции MVP (Minimum Viable Product) — минимально жизнеспособного продукта. Это позволит быстрее выйти на рынок, получить обратную связь и итеративно улучшить приложение.</p><p>Возьмем для примера приложение доставки еды. В этом случае MVP должен включать:</p><ul><li>авторизацию пользователя через телефон, email или социальные сети;</li><li>каталог ресторанов с фильтрацией по кухне, рейтингу и времени доставки; меню каждого заведения с фотографиями и описанием блюд;</li><li>корзину с возможностью изменения состава заказа;</li><li>оформление заказа с выбором адреса доставки и способа оплаты;</li><li>отслеживание статуса заказа в реальном времени;</li><li>профиль пользователя с историей заказов.</li></ul><p>Важно уделить внимание и техническим аспектам функционала:</p><ul><li>Локальное кэширование данных. Поддерживает работу приложения при слабом интернет-соединении или его отсутствии. Сохраняет каталоги, популярные позиции и историю действий пользователя.</li><li>Офлайн-режим. Определяет набор функций, доступных без подключения к сети. Критически важен для удержания пользователей в зонах с плохим интернетом.</li><li>Система пуш-уведомлений. Информирует пользователей о важных событиях, статусах заказов и специальных предложениях. Повышает вовлеченность и возвращаемость в приложение.</li><li>Многопоточная обработка. Выполняет ресурсоемкие операции в фоновом режиме. Гарантирует отзывчивость интерфейса даже при выполнении сложных задач.</li><li>Оптимизация изображений. Внедряет алгоритмы сжатия для быстрой загрузки визуального контента. Обеспечивает комфортное использование даже при ограниченной скорости соединения.</li></ul><p>При этом разработчики часто допускают ошибки, и одна из самых распространенных — функциональная перегруженность. Не стоит добавлять AR-анимации, игровые механики и другие «модные» функции, если они не решают реальных проблем клиентов.</p><p>Также многие игнорируют обратную связь пользователей, хотя механизмы ее сбора стоит включать уже в MVP. Недостаточное внимание к безопасности может стать критичным для приложений с личными данными и платежами. А отсутствие встроенных инструментов аналитики затрудняет понимание того, как пользователи взаимодействуют с программой.</p><p>Выбор правильной архитектуры — это фундамент, который определяет надежность, масштабируемость и удобство поддержки. Вот основные паттерны для мобильных приложений:</p><ul><li>MVVM — рекомендуемый Google подход с разделением UI и бизнес-логики</li><li>MVI — однонаправленный поток данных, хорошо сочетается с реактивным программированием</li><li>MVP — классическая архитектура. Популярна благодаря простоте реализации</li><li>Clean Architecture — многослойный подход с упором на тестируемость и гибкость</li><li>VIPER (iOS) — расширенный MVC со строгим разделением ответственности</li></ul><p>Важное значение имеет также выбор технологий для хранения и передачи данных. Для локальной работы подойдут SQLite + Room, Realm или DataStore; для сетевого взаимодействия на Android чаще всего используют Retrofit + OkHttp, а в реактивных сценариях — Ktor Client.</p><p>Правильный выбор архитектуры напрямую зависит от масштаба проекта и размера команды. Небольшие приложения могут обойтись простыми решениями, тогда как сложные продукты требуют комплексного подхода с продуманным разделением ответственности.</p><h2>Создаем удобный интерфейс</h2><p>Интерфейс — это лицо приложения. Даже если у вас отличный функционал, но пользоваться им неудобно, людям будет проще удалить программу и найти что-то другое.</p><p>Эффективный UI/UX строится на пяти ключевых принципах:</p><ol><li>Очевидность (интуитивное понимание интерфейса);</li><li>Экономия внимания (минимум шагов для достижения цели);</li><li>Консистентность (единообразие элементов с одинаковой функциональностью);</li><li>Обратная связь (видимый результат каждого действия);</li><li>Прощение ошибок (возможность отмены операций).</li></ol><p>Современные инструменты значительно ускоряют создание качественных интерфейсов. Дизайнеры используют Figma, Adobe XD и Sketch для прототипирования. Android-разработчики предпочитают Jetpack Compose и Material Design Components. Для iOS актуальны SwiftUI, UIKit и Human Interface Guidelines от Apple.</p><p>Наглядный пример различий между хорошим и плохим интерфейсом — приложения для доставки еды. В удачном решении ключевые элементы находятся в зоне комфортного доступа, процесс заказа разбит на логические шаги с индикацией прогресса, а дизайн адаптируется к условиям использования. В неудачном — мелкие тесно расположенные кнопки, длинные формы без разбивки на шаги и непонятная навигация.</p><h2>Проводим тестирование</h2><p>Юзабилити-тесты с фокус-группами, A/B-тестирование элементов и аналитика пользовательского поведения дают объективную картину взаимодействия клиентов с приложением.</p><p>Комплексное тестирование включает два основных направления:</p><ol><li>Автоматизированное тестирование: unit-тесты (JUnit, XCTest) для проверки отдельных компонентов; интеграционные тесты для проверки взаимодействия между модулями; UI-тесты (Espresso, XCUITest) для проверки интерфейса; end-to-end тесты для имитации полного пользовательского сценария.</li><li>Ручное тестирование: функциональное (соответствие требованиям), тестирование производительности (работа под нагрузкой), юзабилити (оценка удобства), кросс-платформенное тестирование (проверка на разных устройствах) и тестирование подключений (поведение при различном качестве интернет-соединения).</li></ol><p>Для этого используют специализированные инструменты: Firebase Test Lab для запуска тестов на множестве устройств, Crashlytics для мониторинга сбоев, Android Profiler и Xcode Instruments для анализа производительности. А Accessibility Scanner помогает адаптировать интерфейс для людей с ограниченными возможностями, расширяя потенциальную аудиторию.</p><h2>Публикуем приложение</h2><p>После тестирования и исправления проблем наступает ответственный момент публикации. Каждый магазин приложений имеет свои особенности процесса:</p><ul><li>Google Play: создание аккаунта разработчика ($25 единоразово); подготовка материалов (иконка, скриншоты, видео, описание); загрузка APK/App Bundle; заполнение формы оценки контента; настройка дистрибуции и ценообразования; ожидание проверки (до 2 дней).</li><li>App Store: регистрация в Apple Developer Program ($99/год); создание записи в App Store Connect; подготовка маркетинговых материалов; загрузка сборки из Xcode; заполнение информации о возрастных ограничениях; ожидание рассмотрения (1-7 дней).</li><li>RuStore: бесплатное создание аккаунта; подготовка материалов; загрузка APK; заполнение метаданных; быстрая модерация (до часа).</li></ul><p>Перед публикацией важно убедиться в соответствии приложения правилам магазина, подготовить политику конфиденциальности и настроить аналитику для мониторинга производительности с первого дня.</p><h2>Поддерживаем и обновляем</h2><p>После выпуска начинается непрерывный процесс поддержки и совершенствования продукта. Разработчики регулярно исправляют найденные ошибки, добавляют новые функции и улучшают работу уже существующих.</p><p>Для эффективного мониторинга используют комплексные аналитические инструменты: Firebase Crashlytics для отслеживания сбоев, Firebase Analytics/Google Analytics для анализа пользовательского поведения, RuStore Remote Config — бесплатный аналог  Firebase, Mixpanel для углубленного анализа пользовательских путей, AppMetrica от Яндекса как комплексное решение для российского рынка.</p><p>Автоматизация процессов разработки критически важна для регулярных релизов. CI/CD-системы (GitHub Actions, GitLab CI, Bitrise, Fastlane) позволяют автоматизировать сборку, тестирование и публикацию обновлений, значительно сокращая время выхода новых версий.</p><p>Оптимальная стратегия обновлений включает регулярный график релизов (каждые 2-4 недели) с четким приоритетом задач: критические исправления, новые функции, оптимизация производительности. В тренде современной разработки: персонализация на основе ИИ, многофункциональные суперапп-решения, адаптация под новые форм-факторы устройств и повышенное внимание к приватности данных.</p><h2>Продвигаем приложение</h2><p>На рынке огромная конкуренция, и без активного продвижения ваш продукт просто затеряется среди тысяч других программ. Важную роль здесь играет ASO (App Store Optimization) — оптимизация для магазина приложений. В некоторых случаях был <a href="https://www.businessofapps.com/marketplace/app-store-optimization/research/app-store-optimization-strategies/">зафиксирован</a> рост установок до 70% благодаря сильным ASO-стратегиям.</p><p>Для Android-приложений это означает настройку страницы так, чтобы пользователи легко находили ваш продукт. Здесь важно правильно подобрать ключевые слова для описания, создать привлекательную иконку и подготовить качественные скриншоты. Чтобы понять, какое оформление работает лучше, разработчики всё чаще используют A/B-тесты — такая возможность есть, например, в RuStore. Она позволяет сравнить разные версии карточки приложения и выбрать ту, которая эффективнее привлекает пользователей.</p><p>Также разработчики могут использовать как бесплатные, так и платные форматы продвижения. Один из бесплатных форматов — фичеринг, когда редакция размещает приложение в подборках, разделах или на главной странице магазина. Платное же продвижение позволяет настраивать таргетинг по демографии, географии, интересам, ключевым фразам и устройствам, а также запускать кампании прямо в поисковой выдаче магазина.</p><p>Еще один инструмент для продвижения приложений — социальные сети. Здесь можно показывать функционал программы, общаться с пользователями, отвечать на их вопросы и рассказывать о новых опциях. Это помогает создать активное сообщество вокруг продукта. Так, к примеру, В 2023 году компания Geozilla, разработчик приложения для отслеживания местоположения близких, провела кампанию по продвижению с инфлюенсерами в социальных сетях. В рамках сотрудничества удалось собрать более 1 миллиона просмотров, а коэффициент конверсии из кликов в установки приложения составил 24%.</p><p>Партнерские программы и рекламные кампании тоже сильно влияют на привлечение новых пользователей. Нельзя забывать и о работе с отзывами — нужно активно отвечать на комментарии и решать проблемы, о которых пишут люди.</p><p>Собственный сайт или блог разработчика тоже может привлечь внимание к приложению, особенно если у вас уже есть известный бренд.</p><h2>Подводим итоги</h2><p>Создание успешного приложения начинается с четкого определения цели и понимания потребностей пользователей. Затем нужно выбрать подходящие технологии, продумать необходимые функции, спланировать архитектуру и разработать понятный интерфейс. Обязательно проведите тщательное тестирование перед запуском. После публикации важно регулярно обновлять приложение на основе отзывов пользователей и данных аналитики, а также активно продвигать его в магазинах приложений и социальных сетях.</p><p>Не гонитесь за модными технологиями ради технологий — сосредоточьтесь на том, что действительно нужно вашим пользователям. Если вы создадите действительно полезный и удобный продукт, он найдет свою аудиторию и станет успешным.</p><p>iOS или Android? React Native или Flutter? Собираем все новости и гайды по мобильной разработке <a href="https://t.me/+Fb6_4ek5P6gzOTcy">тут</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Бэкенд — это тоже красиво: как метрики и мониторинг делают вашу работу заметной</title>
      <link>https://tproger.ru/articles/bekend---eto-tozhe-krasivo--kak-metriki-i-monitoring-delayut-vawu-rabotu-zametnoj</link>
      <comments>https://tproger.ru/articles/bekend---eto-tozhe-krasivo--kak-metriki-i-monitoring-delayut-vawu-rabotu-zametnoj?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bekend---eto-tozhe-krasivo--kak-metriki-i-monitoring-delayut-vawu-rabotu-zametnoj</guid>
      <description><![CDATA[<p>Вадим Ваганов, руководитель разработки и Head of Profession Backend в Газпромбанке, рассказывает, почему важно визуализировать метрики и свою работу.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bekend---eto-tozhe-krasivo--kak-metriki-i-monitoring-delayut-vawu-rabotu-zametnoj">Бэкенд — это тоже красиво: как метрики и мониторинг делают вашу работу заметной</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Oracle]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Визуализация]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 31 Mar 2025 14:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Фронтендеры и мобильщики могут продемонстрировать результаты своей работы визуально — показать красивый интерфейс, анимацию, новую удобную кнопку. А как быть бэкендерам, особенно начинающим? Как эффектно показать, что результат вашей недельной работы — это не какие-то там циферки в консоли, а важный результат? Ответ: метрики, визуализация, мониторинг.</p><p>Меня зовут Вадим Ваганов, я руководитель разработки и Head of Profession Backend в Газпромбанке. Я люблю делиться опытом, а также обучать и приносить пользу другим. Все свои статьи я строю на личных историях, так что эта будет такой же. Она для тех, кто только начинает свой путь в бэкенд-разработке и еще не вник в вопросы визуализации своей работы. Расскажу, почему стоит инвестировать время в эти направления и как благодаря им вы станете более крутым инженером с первых шагов в профессии.</p><p>Дисклеймер: да, мониторинг — более широкая тема, но сегодня будем говорить в первую очередь про метрики и их визуализацию.</p><h2>Проблема: что делать, если есть трудности с презентацией и оценкой своей работы</h2><p>Фронтендерам и мобильщикам чуть проще в начале пути разработчика: они могут нарисовать красивую кнопочку, сделать что-то визуальное, и даже если логика проста, то визуал можно «продать» — банально показать друзьям. А бэкендерам что показать? Как в консольку выводим циферки?</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/0d4d4da7-6724-43d7-8b28-f443fd8d14ba.png" alt="" /></figure><p>Это, конечно, шутка (хоть и с долей правды), но проблема демонстрации результатов своей работы для бэкендеров действительно существует — будь то коллеге, боссу, бизнесу или самому себе, в конце концов. Решение есть — метрики, визуализация, мониторинг.  Эта тема сильно недооценена. Часто люди ничем, кроме логов, не пользуются. Не допускайте этой ошибки!</p><h2>Начинаем с простого: получаем данные о состоянии приложения</h2><p>Я не хочу делать это просто вводной, теоретической статьей по мониторингу. Нам нужна база, и мы рассмотрим ее на практике. Все примеры доступны в <a href="https://github.com/vaganov-vadim/backend-is-also-beautiful">репозитории на GitHub</a>, где вы найдете полный код и конфигурацию. Вы можете либо клонировать <a href="https://github.com/vaganov-vadim/backend-is-also-beautiful">репозиторий</a>, либо настроить все с нуля, следуя инструкциям ниже. Нам понадобится всего 5–10 минут, чтобы получить первые результаты.</p><p><b>Подготовка окружения</b></p><p>Для примера нам понадобятся:</p><ul><li><a href="https://github.com/docker">Docker</a></li><li><a href="https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html">JDK 17</a></li></ul><p>Все придумано до нас, поэтому воспользуемся готовыми инструментами — например, <a href="https://micrometer.io/">micrometer</a> (<a href="https://docs.micrometer.io/micrometer/reference/concepts.html">документация тут</a>) или аналог, если у вас не Java/Kotlin. Интегрируем его с /actuator.</p><p>В <a href="https://github.com/vaganov-vadim/backend-is-also-beautiful/blob/main/build.gradle">build.gradle</a> нужно добавить следующее:</p><p>Проверяем запрос в тестовом контроллере:</p><p>и смотрим на метрики:</p><p>Пока что мы можем получать такую информацию в моменте, но мы хотим историчности, следовательно, это дело надо как-то получать и где-то хранить.</p><p>У нас есть заготовленный конфиг, чтобы поднять <a href="https://grafana.com/">Grafana</a> и <a href="https://prometheus.io/">Prometheus</a>:</p><p>Открываем <a href="http://localhost:9090/">UI Prometheus</a>, пробуем найти demo_requests_total, нажимаем Execute, проверяем историчность — она есть!</p><p>Теперь можно визуализировать данные. Открываем <a href="http://localhost:3000/">Grafana</a>, вводим admin/admin и создаем дашборд:</p><ol><li>Dashboards -&gt; Create Dashboard -&gt; Add visualization</li><li>Конфигурируем Data Source: Configure a new data source -&gt; Prometheus -&gt; Connection = http://prometheus:9090 -&gt; Save &amp; test</li><li>Возвращаемся к меню Create Dashboard -&gt; Add visualization, выбираем Data Source prometheus</li><li>Настраиваем дашборд: выбираем Code вместо Builder, пишем sum (rate(demo_requests_total[1m]))</li></ol><p>Отлично! Давайте накидаем еще запросов, чтобы посмотреть, как это будет выглядеть:</p><p>Теперь у нас на графике видна динамика запросов. Инструментарий готов! Теперь мы можем:</p><ul><li>создавать любые метрики в приложении;</li><li>собирать, хранить и получать метрики за выбранный период;</li><li>визуализировать метрики как душе угодно.</li></ul><h2>Что отслеживать в бэкенд-приложениях</h2><p>У вас когда-нибудь было состояние, когда вам плохо, болит голова, першит горло, и вы думаете, что все — у вас 38 °C, и вы жутко простудились. Берете градусник, измеряете температуру... А у вас 36.6 °C. Не полагайтесь на ощущения — смотрите в мониторинг!</p><h3>Состояние серверов и инфраструктуры</h3><ul><li>Загруженность CPU и памяти серверов.</li><li>Загруженность дисков.</li><li>Мониторинг сети.</li><li>И другие инфраструктурные метрики.</li></ul><p>Здесь важен в том числе анализ долгосрочных тенденций, например: насколько скоро закончится свободное место при текущем уровне нагрузки?</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/2a12df47-db1e-4258-a332-ba10ac6024ff.jpeg" alt="" /></figure><h2>Метрики производительности приложения</h2><p>В SRE Google выделяют 4 золотых сигнала:</p><ol><li><b>Latency (задержка)</b> — время, необходимое для обработки запроса;</li><li><b>Traffic (трафик)</b> — количество запросов к системе;</li><li><b>Errors (ошибки)</b> — процент запросов, которые заканчиваются ошибкой;</li><li><b>Saturation (насыщение)</b> — насколько система загружена.</li></ol><p>ВАЖНО: иногда ваше приложение начинает работать медленно из-за интеграций, поэтому их тоже просто необходимо отслеживать. Если провайдер данных отвечает за 1 с, а у вас в <a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%88%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1_%D1%83%D1%80%D0%BE%D0%B2%D0%BD%D0%B5_%D1%83%D1%81%D0%BB%D1%83%D0%B3">SLA</a> — 250 мс, то как бы производительно и надежно ни было ваше приложение — у вас уже проблемы.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/726af92a-89e9-4db4-8297-bcb1bd28512d.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/89e3f1f4-f42e-431e-982b-83542fcfb68a.png" alt="" /></figure><h2>Бизнес-метрики</h2><p>Это те метрики, которые совершенно прекрасны, потому что они помогут вам почувствовать себя не просто писателем кода, а тем, кто действительно влияет на продукт и бизнес в целом. Скажем, можно отслеживать конверсии и ключевые действия: если ваше приложение связано с бизнес-процессами, важно отслеживать ключевые метрики, например количество покупок. Это помогает понять, насколько успешно работает ваше приложение.</p><p>Если вы проверяете гипотезы или проводите a/b-тестирование — собирать и визуализировать метрики просто обязательно.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/99c0c383-f638-43c9-9b55-dacd3acecb9f.png" alt="" /></figure><p><i>Красиво — это не только про визуал. Получать обратную связь и взаимодействовать с системой/продуктом — тоже красиво!</i></p><h2>Почему мониторинг — это навык, который стоит прокачать любому инженеру</h2><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-03-31/111f0b2e-9606-477d-82e5-2813e2f5e12a.png" alt="" /></figure><h3>Мониторинг как важная составляющая DevOps- и SRE-практик</h3><p>Современные инженеры все чаще сталкиваются с задачами, которые выходят за рамки чистой разработки кода. Инженеры должны не только писать код, но и понимать, как этот код работает в реальных условиях. Это не только сделает вас более компетентными, но и придаст новый интерес работе.</p><h3>Взаимодействие мониторинга с процессами CI/CD</h3><p>Изменения — наше все, именно благодаря им мы приносим пользу бизнесу: улучшаем пользовательский опыт, проверяем гипотезы, зарабатываем деньги.</p><p>Мониторинг помогает убедиться, что новые изменения работают как задумано, а также не приводят к ухудшению производительности или стабильности системы. Интеграция мониторинга в CI/CD позволяет быстро выявлять проблемы и откатывать изменения, если что-то пошло не так.</p><h3>Универсальный и вечнозеленый навык</h3><p>На каком бы стеке вы ни работали, чем бы ни занимались в бэкенд-разработке, уверяю вас: это тот навык, который будет полезен на протяжении всей карьеры.</p><h3>Важность анализа данных о вашем продукте</h3><p>Важные решения принимаются на основе данных, без грамотного отслеживания метрик и их визуализации вы будете просто подбрасывать монетку.</p><h3>Возможность предвидеть и предотвращать проблемы</h3><p>Успешные инженеры могут не только решать проблемы, но и предотвращать их. Мониторинг позволяет выявлять аномалии и потенциальные угрозы до того, как они приведут к сбоям.</p><h2>Подведение итогов</h2><p>Метрики — это то, что ты хочешь смотреть не только когда плохо, но и когда хорошо.</p><p>Мониторинг — это не просто инструмент, это философия. Это способ мышления, который помогает вам быть в курсе того, что происходит с вашей системой, и принимать обоснованные решения.</p><p>Мониторинг делает вас более уверенным инженером. Когда вы знаете, что происходит с вашим приложением, вы можете спокойно спать по ночам, зная, что система под контролем.</p><p>Мониторинг помогает вам расти. Это навык, который будет полезен не только в вашей текущей работе, но и в будущем. Чем раньше вы начнете погружаться в эту тему, тем быстрее вы станете более востребованным специалистом.</p><p>Мониторинг — это инвестиция в стабильность и качество. В конечном итоге это то, что делает ваше приложение надежным, а вашу команду — эффективной.</p><p>И да, мониторинг — это просто красиво. Когда наглядно видишь тонкости работы приложения — это совершенно новый уровень погружения в работу.</p><p>Так что если вы еще не начали заниматься мониторингом, самое время начать. У вас есть все инструменты и все возможности — вы можете скачать <a href="https://github.com/vaganov-vadim/backend-is-also-beautiful">наш репозиторий</a> и начать вникать прямо сейчас.</p><h4>Полезные источники</h4><ul><li><a href="https://docs.micrometer.io/micrometer/reference/">Официальная документация Micrometer</a></li><li><a href="https://prometheus.io/docs/introduction/overview/">Официальная документация Prometheus</a></li><li><a href="https://grafana.com/docs/grafana/latest/dashboards/">Официальная документация Grafana</a></li><li><a href="https://sre.google/sre-book/monitoring-distributed-systems/">4 золотых сигнала</a></li><li><a href="https://www.piter.com/product/site-reliability-engineering-nadezhnost-i-bezotkaznost-kak-v-google">Книга об SRE</a></li></ul><p>Если вам понравится материал и вы захотите ознакомиться с другим моим контентом — приглашаю в <a href="https://t.me/vaganov_vadim">мой телеграм-канал</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Количество кода от ИИ в российских компаниях увеличится втрое в ближайшее время</title>
      <link>https://tproger.ru/news/kolichestvo-koda-ot-ii-uvelichitsya-vtroe-v-blizhajwee-vremya</link>
      <comments>https://tproger.ru/news/kolichestvo-koda-ot-ii-uvelichitsya-vtroe-v-blizhajwee-vremya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/kolichestvo-koda-ot-ii-uvelichitsya-vtroe-v-blizhajwee-vremya</guid>
      <description><![CDATA[<p>Объем ИИ-кода растёт: к 2027 году 25% строк будет написано нейросетями. Разработчики превращаются в архитекторов, а компании внедряют ИИ-инструменты</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/kolichestvo-koda-ot-ii-uvelichitsya-vtroe-v-blizhajwee-vremya">Количество кода от ИИ в российских компаниях увеличится втрое в ближайшее время</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 11 Mar 2025 10:45:51 GMT</pubDate>
      <content:encoded><![CDATA[<p>ИИ-инструменты становятся неотъемлемой частью разработки: уже сейчас <b>8% кода в системах МТС</b> создается при помощи искусственного интеллекта, а к <b>2027 году</b> этот показатель может достичь <b>25%</b>.</p><h2>Как ИИ меняет процесс разработки</h2><p>По <a href="https://www.vedomosti.ru/technology/articles/2025/03/11/1097183-neiroset-skoro-budet-pisat-vtroe-bolshe-koda-za-razrabotchikov">данным</a> <b>Ведомостей</b>, рост использования нейросетей ускоряет цифровую трансформацию компаний.</p><p>По прогнозам <b>МТС</b>, к 2030 году <b>более 90% программистов</b> будут применять ИИ-инструменты для написания и проверки кода.</p><p>На данный момент:</p><ul><li><b>В среднем на рынке</b> ИИ выполняет <b>5–10% рутинных задач</b>.</li><li><b>Нейросети заменяют функционал джуниор-разработчиков</b>.</li><li><b>Роль программистов</b> постепенно трансформируется в <b>архитектора решений</b>.</li><li><b>В 25% стартапов Y Combinator</b> ИИ уже написал <b>95% кода</b>.</li></ul><p>Несмотря на такие темпы развития, пока <b>код, сгенерированный ИИ, не идеален</b> и требует проверки. Полного замещения разработчиков в ближайшее время не ожидается.</p><h2>Какие решения внедряют компании</h2><ul><li><b>МТС</b> развивает <b>DevX-платформу</b> и <b>Kodify</b>, которые помогают ускорить разработку на <b>55%</b>.</li><li><b>Яндекс</b> представил <b>SourceCraft Code Assistant</b>, который генерирует более <b>250 тыс строк кода в неделю</b> для своих разработчиков. Поддерживаются <b>30+ языков</b>, включая <b>C++</b>, <b>Go</b>, <b>Kotlin</b>, <b>Python</b> и другие.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Яндекс представил SourceCraft — свой аналог GitHub</title>
      <link>https://tproger.ru/news/--yandeks-predstavil-sourcecraft---svoj-analog-github</link>
      <comments>https://tproger.ru/news/--yandeks-predstavil-sourcecraft---svoj-analog-github?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--yandeks-predstavil-sourcecraft---svoj-analog-github</guid>
      <description><![CDATA[<p>Яндекс запустил SourceCraft — аналог GitHub с CI/CD, ИИ-ассистентом и интеграцией с Yandex Cloud. Платформа уже доступна в тестовом режиме</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--yandeks-predstavil-sourcecraft---svoj-analog-github">Яндекс представил SourceCraft — свой аналог GitHub</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 26 Feb 2025 08:55:16 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Yandex B2B Tech</b> <a href="https://yandex.ru/company/news/01-26-02-2025">запустила</a> <b>SourceCraft</b> — платформу для совместной разработки программных продуктов.</p><p>Это инструмент для командной работы над кодом, в котором есть <b>автоматизация CI/CD, умная навигация</b> и <b>встроенный ИИ-ассистент</b>.</p><p>Пока что сервис работает в тестовом режиме — доступ можно получить по заявке.</p><h2>Что умеет SourceCraft</h2><p>SourceCraft предлагает знакомый интерфейс и удобную навигацию, напоминающую IDE. Разработчики могут искать код по <b>ключевым словам, файлам и структуре проекта</b>, что особенно полезно при работе с большими <b>пул-реквестами</b>.</p><p>Одним из главных элементов платформы стал <b>ИИ-ассистент SourceCraft Code Assistant</b>. Он поддерживает <b>более 30 языков программирования</b> (C++, Go, Java, Kotlin, Python и др), предлагает <b>автодополнение кода</b> и вскоре получит <b>режим чата</b>.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-02-26/b6ac74dc-c49a-406a-88ea-67adf22de1a8.jpeg" alt="" /></figure><p>Инструмент уже протестировали тысячи пользователей, а также он доступен как плагин для <b>VSCode</b> и <b>JetBrains</b>.</p><blockquote>Мы создавали платформу с нуля и даже разрабатывали её последние версии внутри самой SourceCraft. Теперь мы готовы открыть тестирование для внешних пользователей и продолжим развивать платформу с учётом их обратной связи.</blockquote><h2>Будущее платформы</h2><p>Сейчас SourceCraft доступен через веб-интерфейс, но в будущем появится <b>глубокая интеграция с Yandex Cloud</b> — развернуть проект в облаке можно будет «по нажатию кнопки».</p><p>Отдельный фокус сделан на <b>безопасность</b>. В ближайших обновлениях появятся:</p><ul><li><b>Автоматическое сканирование секретов</b>, чтобы избежать утечек данных.</li><li><b>Поиск уязвимостей в цепочках поставок</b> для защиты от компрометированных зависимостей.</li><li><b>Улучшенные инструменты автоматизации</b>, критически важные для работы с <b>крупными кодовыми базами</b>.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Jetpack Compose и Kotlin: как разрабатывать современные UI</title>
      <link>https://tproger.ru/articles/jetpack-compose-i-kotlin--kak-razrabatyvat-sovremennye-ui</link>
      <comments>https://tproger.ru/articles/jetpack-compose-i-kotlin--kak-razrabatyvat-sovremennye-ui?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ксения Андреева]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/jetpack-compose-i-kotlin--kak-razrabatyvat-sovremennye-ui</guid>
      <description><![CDATA[<p>Jetpack Compose и Kotlin. Показываем, как разрабатывать современные UI. Рассматриваем инструменты и техники ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/jetpack-compose-i-kotlin--kak-razrabatyvat-sovremennye-ui">Jetpack Compose и Kotlin: как разрабатывать современные UI</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 20 Feb 2025 10:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если раньше пользовательские интерфейсы приходилось писать вручную, то сейчас достаточно освоить инструмент для разработки интерфейсов Jetpack Compose и язык Kotlin. Так можно создавать современные UI с минимальным кодингом и максимальной эффективностью решений. Сегодня разберемся в основах Jetpack Compose и Cotlin и узнаем, как применять инструменты в своих проектах.</p><h2>Jetpack Compose: что это за зверь</h2><p>Jetpack Compose — современный инструмент для создания пользовательских интерфейсов на Android, который использует декларативный подход. Разработчик описывает, как должен выглядеть UI в зависимости от данных, а система автоматически обновляет его при изменении этих данных. Так, вместо императивного управления элементами интерфейса, как в традиционной Android-разработке, Compose позволяет сосредоточиться на конечном результате.</p><h3>Чем Compose отличается от традиционного XML</h3><p>Традиционно интерфейсы в Android создаются с помощью XML-разметки, но этот метод имеет ряд недостатков:</p><ul><li>Разделяет логику интерфейса (XML) и управления им (Kotlin/Java), что усложняет поддержку;</li><li>Усложняет код по мере роста приложения;</li><li>Необходимо вручную обновлять UI при изменении данных.</li></ul><p>Compose заменяет XML-разметку Kotlin-кодом, в котором UI описывается с помощью функций. Фреймворк сам отслеживает изменения данных и обновляет только нужные элементы.</p><h3>Основные концепции: Composable-функции, Recomposition, State</h3><h4>Composable-функции</h4><p>Основной строительный блок интерфейсов в Jetpack Compose — Composable-функции. Они представляют собой модули, из которых можно собирать весь UI. Каждая функция отвечает за определённую часть интерфейса, а сложные экраны формируются путем комбинирования элементов.</p><h4>Recomposition</h4><p>Одна из ключевых особенностей Jetpack Compose — механизм Recomposition. Если изменяются данные, система пересчитывает и обновляет только те элементы интерфейса, которые зависят от этих данных. Это повышает производительность и избавляет разработчика от необходимости вручную следить за обновлениями UI.</p><h4>State</h4><p>Для управления изменяемыми данными в Compose используется механизм State. Он позволяет отслеживать изменения данных и автоматически обновлять связанные элементы интерфейса. Работа с состоянием в Compose построена на реактивных принципах, что делает его управление более удобным и предсказуемым.</p><p>Jetpack Compose упрощает разработку UI на Android. Вместо сложных XML-разметок и ручного обновления элементов, разработчики теперь могут сосредоточиться на логике и удобстве использования своих приложений.</p><h2>Как установить и настроить проект</h2><h3>Добавьте зависимости</h3><p>Это первый шаг в освоении Jetpack Compose. Чтобы начать работу, нужно открыть build.gradle файл и добавить туда следующие строки:</p><p>Так подключаются основные библиотеки для работы с Compose UI и Material Design.</p><h3>Проверьте минимальные требования</h3><p>В первую очередь, нужно обновить Android Studio хотя бы до версии Arctic Fox или выше. Также необходимо апдейтнуть Gradle до 7.x и Kotlin до версии 1.5.x.</p><p>Минимальная версия API проекта должна быть не ниже 21 (да простят нас пользователи старых телефонов). Если хотите использовать все фишки Compose по максимуму — не ниже 23.</p><h3>Легко запустите пустой проект</h3><p>Запустив Android Studio и создав новый проект, выберите шаблон Empty Compose Activity. В итоге увидите проект со всеми добавленными настройками и фрагментами.</p><figure><img src="https://media.tproger.ru/user-uploads/106063/2025-02-18/00ec1e3f-ed8e-415b-b6da-f31675c792a8.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/106063/2025-02-18/f1c9c808-b91d-4e93-b3dd-3047c8a107c4.png" alt="" /></figure><p>Если же вы начинаете проект с нуля, то просто вставьте зависимости из первого пункта и проверьте настройки compileSdkVersion и minSdkVersion.</p><h2>Как создать базовые компоненты UI</h2><p>Если раньше разработка интерфейсов была долгим и сложным логическим процессом, то с Kotlin и Jetpack Compose работа с UI превратилась в старый добрый тетрис, где задача — просто контролировать расположение блоков.</p><h3>Работа с текстами</h3><p>Создать текстовый элемент здесь очень просто:</p><p>Если нужно работать с оформлением и стилем текста, то:</p><h3>Кнопки и их стилизация</h3><p>В Compose кнопки создаются так же легко, как и текст:</p><p>Ещё кнопки можно стилизовать:</p><h3>Организация макетов: Column, Row, Box</h3><p>В компоновке элементов UI всё должно быть на своих местах. В Jetpack Compose есть 3 главных инструмента для организации макета: <b>Column, Row и Box.</b></p><p><b>Column</b> используется для вертикального расположения элементов:</p><p>И наоборот, когда элементы должны располагаться горизонтально, <b>используется Row:</b></p><p><b>Box</b> — инструмент для наложения элементов друг на друга:</p><h2>Как управлять состоянием в Jetpack Compose</h2><p>В Jetpack Compose концепция <b>State </b>играет очень важную роль. State — часть данных приложения, которая может меняться со временем. Здесь «лежать» способно что угодно: от простого текста до информации о данных пользователя.</p><h3>Использование remember и mutableStateOf</h3><p>Как управлять состоянием в Kotlin и Jetpack Compose? Здесь на помощь приходят функции remember и mutableStateOf.<b></b></p><p>Когда вы пересоздаете UI (например, из-за изменения данных), remember поможет сохранить значения.</p><p><b>Пример с кнопкой-счётчиком:</b></p><p>Здесь mutableStateOf(0) создаёт изменяемое состояние с начальным значением 0, а remember удерживает это состояние во время пересозданий компонента Counter. Так, при клике значение увеличивается на единицу.</p><h3>Поддержание реактивности интерфейса</h3><p>Один из главных плюсов Jetpack Compose — его реактивность. Изменения состояния автоматически обновляют пользовательский интерфейс без ручного ввода.</p><p>Когда Counter вызывается заново из-за высокого значения count после клика, система Jetpack Compose автоматически обновляет только те части интерфейса, которые зависят от этих данных.</p><p>Управление состоянием — база в создании UI на основе Kotlin и Jetpack Compose.</p><h3>Темизация и стилизация</h3><p>Темизация и стилизация важны для создания классного UI. Kotlin и Jetpack Compose предлагают по-настоящему мощные инструменты для работы с темами, с помощью которых можно легко адаптировать внешний вид приложения в зависимости от предпочтений пользователей.</p><h2>Работа с темами: Light и Dark mode</h2><p>В Jetpack Compose можно автоматически переключаться между светлой и тёмной темами, используя при этом системные настройки. Ещё использовать MaterialTheme, встроенный в Compose. Он определяет палитру для обеих тем, создавая согласованность дизайна на всех экранах.</p><h3>Определение кастомной темы приложения</h3><p>Для создания уникальной темы, которая будет отражать ваш бренд, можно использовать кастомизацию темы приложения.</p><p>Сначала нужно определить основные цвета, оттенки фона и акценты. Далее выбрать шрифты, их размер для разных текстовых элементов. Очень важно уделить внимание формам элементов (кнопкам и карточкам) — здесь можно выбрать обводку и углы закругления.</p><h3>Использование Material Design 3</h3><p>С выходом Material Design 3, на Android можно создавать ещё более интуитивные и адаптивные дизайны — всё зависит от ваших предпочтений и нужд.</p><p>Например, с помощью поддержки динамической цветовой схемы (Dynamic Color), можно адаптировать цвета интерфейса к обоям устройства и другим условиям.</p><p>Кроме того, в Material Design 3 есть обновлённый набор компонентов UI с адаптацией под разрешение экрана и ориентацию устройства.</p><h2>Сложные интерфейсы</h2><p>Эффективность, удобство и привлекательность — 3 кита, на которых строится успешное приложение. Разбираемся, как с помощью Kotlin и Jetpack Compose создавать сложные интерфейсы.</p><h3>Работа со списками: LazyColumn и LazyRow</h3><p>Можно работать с LazyColumn и LazyRow — они используются для отображения больших наборов данных без «утяжеления» производительности приложения.</p><p><b>LazyColumn </b>— вертикальный список элементов, который подгружает данные по мере необходимости. Для создания списка используется @Composable, а сами элементы списка создаются <b>внутри блока items:</b></p><p>А <b>LazyRow</b> позволяет создавать горизонтальные списки — подойдёт для каруселей или галерей:</p><p>Также с помощью этих компонентов вы можете добавлять разделители и/или анимации:</p><h3>Создание пользовательских Composable-компонентов</h3><p>Собственные composable-компоненты — возможность создавать уникальные элементы интерфейса. Для этого достаточно поместить логику отображения элементов <b>с помощью </b>@Composable:</p><p>@Composable можно использовать, например, с настройкой параметров onClick и label — так улучшается модульность кода.</p><h3>Анимации в Jetpack Compose: плавные переходы и визуальные эффекты</h3><p>В Jetpack Compose есть API для создания плавных переходов между блоками через функции по типу animateDpAsState <b>и </b>animateColorAsState<b>.</b> Например, для изменения размера можно использовать анимацию:</p><p>Также необходима библиотека<b> </b>Accompanist<b> </b>или<b> </b>функции<b> </b>вроде<b> </b>AnimatedVisibility, для динамического отображения контента с эффектом появления/исчезновения:</p><h2>Интеграция с существующими Android-компонентами</h2><p>Jetpack Compose можно использовать в существующих Android-приложениях, не переписывая их с нуля. Для этого предусмотрена интеграция с компонентами View через ComposeView.</p><h3>Встраивание Compose в существующие приложения</h3><p>В приложениях, где уже используется XML-разметка, элементы Compose можно добавлять через ComposeView, вставляя их прямо в макет или Activity:</p><p>Например: добавим Text в XML-разметку через ComposeView:</p><p>Далее, в Activity:</p><h3>Использование View и Compose вместе (interop)</h3><p>При постепенном переходе на Compose можно внедрять его в отдельные UI-элементы. Например, статическую часть формы оставить в XML, а интерактивную — реализовать на Compose:</p><p>Такой подход позволяет постепенно внедрять Compose в проект, сохраняя совместимость с существующим кодом.</p><h2>Тестирование интерфейсов</h2><h3>Инструменты для тестирования Jetpack Compose</h3><p>В Jetpack Compose есть набор инструментов для тестирования UI. Один из главных — <b>библиотека Compose Test</b>, в которой вы можете найти функции для проверки UI. Она работает с Android Testing Framework, а значит, можно не забывать привычный для разработчиков синтаксис.</p><p>С помощью Compose Test можно:</p><ul><li>Проверять отображение и свойства элементов UI;</li><li>Симулировать пользовательские действия (нажатия, прокрутку, ввод текста);</li><li>Изменять состояние приложения в тестовой среде.</li></ul><h3>UI-тесты и проверка состояния</h3><p><b>В автоматизированных тестах есть 2 основных типа:</b> юнит-тесты (<i>фокус на коде</i>) и UI-тесты (<i>фокус на интерфейсе и взаимодействии пользователя с ним)</i>.</p><p>UI-тесты позволяют проверить, правильно ли отображаются элементы, и реагируют ли они на действия пользователя. Например, можно проверить:</p><ul><li>Отображается ли нужная кнопка на экране;</li><li>Изменяется ли текст после нажатия;</li><li>Работает ли прокрутка списков.</li></ul><p>Jetpack Compose делает UI-тестирование удобнее, позволяя работать с декларативным подходом и минимизировать сложность тестов.</p><h3>Примеры написания тестов</h3><p>Несколько примеров UI-тестов с использованием библиотеки<b> Compose Test.</b></p><p><b>Пример 1: проверка наличия элемента</b></p><p><b>Пример 2: работа с элементами</b></p><p><b>Пример 3: проверка изменения состояния</b></p><p>Вообще инструменты Jetpack Compose крайне хороши для тестирования: повышается качество приложений за счёт поиска ошибок в интерфейсе.</p><h2>Советы по оптимизации производительности</h2><p>Kotlin и Jetpack Compose дают разработчикам инструменты, чтобы создавать современные интерфейсы — это факт. Но для достижения лучших результатов важно понимать, как и за счёт чего оптимизируется производительность.</p><h3>Избегайте избыточной рекомпозиции</h3><p>Рекомпозиция — пересоздание части интерфейса при изменении состояния приложения. Из минусов — она может сильно замедлить приложение.</p><p><b>Как свести рекомпозицию к минимуму:</b></p><ol><li><b>Используйте remember</b>, чтобы не было пересоздания одного и того же состояния. Так снижается нагрузка на систему, а работа приложения ускоряется.</li><li><b>Разделяйте состояния</b> композиций так, чтобы изменения одного элемента не приводили к рекомпозиции других элементов. Здесь поможет принцип SRP.</li><li><b>Чем более простой элемент, тем быстрее наступят изменения.</b></li></ol><h3>Используйте инструментов Android Studio для анализа производительности</h3><p>Основные инструменты:</p><ol><li><b>Layout Inspector. </b>Позволяет создать дерево компоновки приложения в реальном времени, показывая затраты на выполнение функций и методов.</li><li><b>Profiler. </b>Даёт полную информацию об использовании ресурсов приложения и определяет потенциальные проблемы с производительностью.</li><li><b>Сравнительный анализ</b>. Помогает выявить слабые места при взаимодействии пользователя с приложением.</li></ol><p>Вы можете создавать более интерактивные и интересные (с точки зрения визуала) приложения с меньшими затратами времени и усилий. Вообще Jetpack Compose не только ускоряет процесс создания UI, но и поднимает качество приложения. Пользуйтесь!</p><p>Если хочешь освоить больше инструментов по мобильной разработке, собираем все актуальные новости<a href="https://t.me/+y4TvdnlepShjOTEy"> тут.</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Создаём мобильное приложение с нуля: от идеи до публикации в App Store и Google Play</title>
      <link>https://tproger.ru/articles/sozdayom-mobilnoe-prilozhenie-s-nulya--ot-idei-do-publikacii-v-app-store-i-google-play</link>
      <comments>https://tproger.ru/articles/sozdayom-mobilnoe-prilozhenie-s-nulya--ot-idei-do-publikacii-v-app-store-i-google-play?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ксения Андреева]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sozdayom-mobilnoe-prilozhenie-s-nulya--ot-idei-do-publikacii-v-app-store-i-google-play</guid>
      <description><![CDATA[<p>Узнайте, как создать мобильное приложение с нуля: от формирования идеи и разработки до тестирования и публикации в App Store и Google Play. Полный обзор ключевых этапов!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sozdayom-mobilnoe-prilozhenie-s-nulya--ot-idei-do-publikacii-v-app-store-i-google-play">Создаём мобильное приложение с нуля: от идеи до публикации в App Store и Google Play</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Figma]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 30 Jan 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый день сотни миллионов людей используют мобильные приложения для разных задач: от общения и развлечений до управления финансами и организации рабочего процесса.</p><p>Сегодня расскажем о том, как создать своё мобильное приложение с нуля до публикации в сторах.</p><h2>1 этап — идея</h2><p>На этапе работы над идеей важно решить, какие запросы пользователей будет решать приложение, почему нужно устанавливать <b>его</b>, а не приложение конкурента. А ещё важно определиться с УТП и понимать аудиторию.</p><p><b>Выбор ниши — крайне важный шаг.</b> <a href="https://app2top.ru/news/sensor-tower-v-2024-godu-iap-vy-ruchka-ry-nka-mobil-ny-h-igr-dostigla-80-9-mlrd-dollarov-e-to-vy-she-prognoza-226931.html">Sensor Tower</a>: за 2024 год выручка мобильных приложений достигла $81 млрд, что выше изначального прогноза на год.</p><p><b>Важно понять: </b>мобильное приложение — это бизнес. А значит, важно определиться с нишей и предложением для пользователей.</p><p><b>Чтобы выбрать правильную нишу, нужно:</b></p><ul><li>Понять, что вам действительно интересно, в чём вы экспертны. Ваша задача — заниматься тем, что вам действительно по душе, и «заражать» этой идеей пользователей.</li><li>Оценить спрос на выбранную нишу. Для первичного анализа интереса можно использовать простые инструменты по типу Google Trends.</li><li>Создать портреты ваших потенциальных пользователей. Это и демографические данные (пол, возраст, география), и психографические (интересы, потребности, поведение пользователей). Важно создать несколько портретов пользователей и как можно более подробно — вам это пригодится в продвижении приложения.</li></ul><p><b>Следующий шаг — подробный анализ конкурентов. А для этого как минимум нужно:</b></p><ul><li>Составить список прямых и косвенных конкурентов. Найдите приложения с функционалом, похожим на ваш продукт.</li><li>Проанализировать отзывы пользователей в сторах — что нравится и не нравится пользователям, о чём они пишут?</li><li>Провести SWOT-анализ (сильные и слабые стороны конкурентов и ниши, возможности и угрозы конкурентов и ниши).</li><li>Найти недостатки у конкурентов и решить, как вы можете улучшить пользовательский опыт, как именно вы можете усилить ваше предложение.</li><li>Глубже погрузиться в статистику, используя для этого ресурсы по типу Statista, App Annie и другие платформы.</li></ul><h2>2 этап — планирование и дизайн</h2><p>На этом этапе вы сможете уже точно понимать, какое именно приложение вы будете создавать, как оно будет выглядеть и какой у него будет функционал.</p><p><b>Первый шаг здесь — определить функционал вашего приложения. </b>Нужно понять, какие функции в приложении будут основные, чтобы протестировать его жизнеспособность с помощью MVP.</p><p>Сосредоточьтесь на решении ключевых запросов пользователя. Например, если вы разрабатываете приложение для доставки еды из ресторанов, основными функциями могут быть поиск ресторанов, просмотр меню, оформление заказа и отслеживание доставки. А уже позже можно добавить систему рейтинга, формы обратной связи, привязку аккаунтов и другие фичи.</p><p>После того, как вы определили основные функции, нужно <b>создать прототип приложения.</b> Это простая визуализация, с помощью которой вы сможете лучше понять структуру и то, как работает пользовательский интерфейс.</p><p>С помощью <a href="https://www.figma.com/">Figma</a> или <a href="https://www.sketch.com/">Sketch</a> можно создать интерактивные прототипы без необходимости писать код. При этом, если дизайном приложения занимается другой человек, вы всегда сможете перейти, например, в Фигму, и оставить комментарии прямо там, чтобы дизайнер понимал, как улучшить интерфейс. А значит, вы и сами сможете протестировать пользовательский интерфейс ещё до начала фактической разработки приложения. Да ещё и сэкономите время, деньги… И нервы 🙂</p><h2>3 этап — технологии и инструменты разработки</h2><p><b>Есть два вида разработки приложений: нативная и кроссплатформенная. </b>Нативная разработка предполагает создание приложения для каждой платформы отдельно на базе Swift для iOS и Kotlin для Android.</p><p><a href="https://developer.apple.com/documentation/swift">Swift</a> — специально разработанный Apple язык программирования для создания приложений под iOS, macOS, watchOS и tvOS. На базе Свифта можно создавать быстрые приложения, которые по максимуму используют возможности экосистемы Apple.</p><p><a href="https://kotlinlang.org/docs/home.html">Кotlin от Google</a> — стандарт нативной разработки для устройств на базе Android. Приложения на Kotlin легко интегрируются с существующим Java-кодом благодаря совместимости JVM.</p><p>Кроссплатформенная разработка подойдёт для тех, кто хочет создать приложение сразу для нескольких платформ.</p><p><a href="https://docs.flutter.dev/">Flutter от Google</a> помогает в разработке приложения для iOS и Android из одного исходного кода на базе языка Dart. У Flutter есть большие библиотеки виджетов с возможностью создания сложных пользовательских интерфейсов.</p><p><a href="https://reactnative.dev/docs/getting-started">React Native от Facebook</a> хорош как кроссплатформенное решение тем, что использует JavaScript для создания мобильных приложений. Принцип работы тот же, что и у Flutter — создаётся «обёртка» над нативными компонентами.</p><p>При выборе инструментов нужно отталкиваться не столько от платформы разработки, сколько от удобства работы в IDE. Например, <a href="https://developer.apple.com/xcode/">Xcode</a> — это официальная среда разработки от Apple для создания приложений под iOS. В Xcode есть редактор кода, симулятор устройств и инструменты для отладки. А <a href="https://developer.android.com/studio?hl=ru">Android Studio</a> — официальная IDE от Google, которая работает с Kotlin и Java.</p><p>А ещё для кроссплатформенной разработки часто работают с <a href="https://code.visualstudio.com/">VS Code</a> — его выбирают за поддержку разных языков программирования, включая Dart и JavaScript.</p><h2>4 этап — разработка</h2><p>Для чистого и логически правильного кода важно создать единую структуру разработки, чтобы облегчить и текущий этап, и будущие функциональные и технические обновления.</p><p>Структура проекта должна быть логичной и модульной; должно быть разделение кода на компоненты или модули, каждый из которых отвечает за реализацию конкретной функции. Например, можно создать модули для обработки пользовательского интерфейса или управления данными. Так вы облегчите тестирование приложения, поиск и устранение багов.</p><p><b>Что ещё важно:</b></p><ul><li><b>Придерживаться принципа SOLID. </b>Один класс = одна задача; классы должны быть открыты для расширения, но закрыты для изменения; объекты должны быть заменяемыми, но без изменения корректности работы; большой интерфейс = много небольших, но конкретных интерфейсов; высокоуровневые модули должны быть отделены от низкоуровневых.</li><li><b>Чистый, читаемый код. </b>Это важно для дальнейшего развития вашего приложения. Везде, где возможно, оставляйте комментарии, чтобы позже вы могли к ним вернуться.</li><li><b>Контроль версий. </b>Здесь помогут системы по типу Git для отслеживания изменений в коде.</li></ul><p><b>Задумайтесь и об интеграции приложения с API. </b>Используйте HTTPS-протоколы для защиты данных, сделайте так, чтобы вы получали все сообщения о взаимодействии с API (это к вопросу об отслеживании ошибок), используйте кэширование данных, чтобы не перегружать сервер.</p><p><b>Следующий шаг — выбор базы данных.</b> Для хранения данных на iOS часто используют Core Data или SQLite, а для Android — Room. А если вы работаете с облачными базами, используйте решения по типу Firebase.</p><p><b>Последний шаг в разработке приложения — тестирование. </b>Именно с помощью тестирования вы сможете найти баги до того, как приложение будет использоваться. Есть два типа тестирования: автоматизированное и ручное. И здесь нельзя выбрать что-то одно, нужно использовать и тот, и другой формат.</p><p>Для автоматизированного тестирования используют юнит-тесты, которые проверяют разные фрагменты кода на наличие логических ошибок. Проводят интеграционные тесты, которые проверяют, нет ли конфликтов между модулями, и UI-тесты — они автоматически воспроизводят сценарии через интерфейс приложения.</p><p>Ручной формат тестирования подразумевает под собой usability-тесты для оценки интерфейса и альфа/бета-тесты для того, чтобы небольшая группа пользователей сама смогла обнаружить баги.</p><h2>5 этап — подготовка к публикации</h2><p>У App Store строгие правила по контенту и функциональности приложений. Здесь абсолютно все модули — от интерфейса до API — тщательно проверяются. По <a href="https://developer.apple.com/app-store/guidelines/">этой ссылке</a> вы найдёте информацию о стандартах проверки приложений Apple.</p><p>А вот с Google Play ситуация обстоит гораздо лучше. Но, разумеется, вы в любом случае должны соблюдать стандарты <a href="https://play.google/developer-content-policy/">Google Play Developer Policy Center</a>.</p><p>Для того, чтобы запустить процесс публикации приложения, вам <b>нужно создать аккаунты разработчика на двух платформах:</b></p><ul><li>Для регистрации в программе <a href="https://developer.apple.com/programs/enroll/">Apple Developer</a> нужно внести оплату годового взноса в размере $99;</li><li>Регистрация разработчика через <a href="https://developer.android.com/distribute/console?hl=ru">Google Play Console</a> обойдётся в $25 единоразово.</li></ul><p>Следующий шаг подготовки к публикации приложения — <b>заполнение страницы:</b></p><ul><li>Иконка вашего приложения должна быть запоминающейся. Не забывайте про рекомендации по размерам и форматам изображений для <a href="https://developer.apple.com/design/human-interface-guidelines/app-icons">iOS</a> и <a href="https://stackoverflow.com/questions/4654811/what-is-the-feature-graphic-for-android-apps">Android</a>.</li><li>Скриншоты должны наглядно демонстрировать основные функции приложения. Это влияет на первое впечатление пользователей.</li><li>Хорошее описание — не просто рассказ о функциях приложения, но и маркетинговый инструмент. Определите ключевые слова, по которым пользователи найдут вас в поиске.</li></ul><h2>6 этап — публикация и продвижение</h2><p>Окей, вы создали учётки разработчика на нужных платформах, подготовили приложение к публикации. Что дальше?</p><p><b>Далее вам нужно заполнить все поля</b>, включая информацию о приложении, цены, регионы и возрастные ограничения. Особенно уделите внимание настройкам конфиденциальности и безопасности. После этого приложение проходит процесс проверки на соответствие требованиям.</p><p>После публикации начинается новый этап — <b>контроль метрик с помощью аналитики.</b> Так вы сможете понять поведение пользователей, популярность функций и возможные проблемы приложения.</p><p><i>Изучайте отзывы! </i>Пользователи могут указывать на ошибки и предлагать новые интересные идеи для вашего приложения. И не забывайте отвечать на отзывы — это важно.</p><p><b>Продвижение приложения — всегда несколько стратегий одновременно:</b></p><ul><li><b>ASO или App Store Optimization </b>— процесс оптимизации вашего приложения для повышения его видимости в сторе. Сюда входит работа над ключевыми словами, заголовками, описаниями и визуалом карточки приложения.</li><li><b>Целевые рекламные кампании</b> помогут вам «достучаться» до нужной аудитории. Здесь не пытайтесь провести кампанию самостоятельно, лучше наймите специалиста.</li><li><b>Важно продвижение в социальных сетях и на отраслевых сайтах</b>, чтобы больше пользователей узнало о вас. Анонсируйте в мероприятия, которые недоступны в приложении: например, конкурс на лучшую историю использования вашего приложения, которую далее вы сможете использовать в маркетинговой стратегии.</li></ul><p>Важно понимать, что приложение «на коленке» —  буквально смерть для вашего проекта. Нужно подойти к процессу планирования, выбора инструментов, разработки приложения, публикации в сторах и маркетинговой стратегии с умом. И не забывайте всегда тестировать разные гипотезы — возможно, самые нетривиальные решения больше всего зацепят аудиторию, которую вы искали с самого начала.</p><p>Если вы мечтаете создать свое мобильное приложение — делимся опытом, инструментами и полезными ресурсами <a href="https://t.me/+4r1h88a5IthiNjVi">здесь</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin: как работают корутины и многопоточность? Уровень — middle</title>
      <link>https://tproger.ru/articles/kotlin--kak-rabotayut-korutiny-i-mnogopotochnost--uroven---middle</link>
      <comments>https://tproger.ru/articles/kotlin--kak-rabotayut-korutiny-i-mnogopotochnost--uroven---middle?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kotlin--kak-rabotayut-korutiny-i-mnogopotochnost--uroven---middle</guid>
      <description><![CDATA[<p>Проходи квиз, чтобы узнать, как хорошо ты шаришь в Котлине. С нас — почет и уважение</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kotlin--kak-rabotayut-korutiny-i-mnogopotochnost--uroven---middle">Kotlin: как работают корутины и многопоточность? Уровень — middle</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Многопоточность]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Функциональное программирование]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 18 Jan 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Сегодняшний квиз не совсем для новичков. Многопоточность и корутины — уже скорее для уровня джун+/мидл. Хотя… Если вы настолько уверены в своих навыках, то попробуйте их проверить и доказать, что вы прирожденный Kotlin-разработчик. А если хотите немного освежить знания, читайте наши статьи:</p><ol><li><a href="https://tproger.ru/articles/kotlin-i-funkcionalnoe-programmirovanie--berite-luchwee">Kotlin и функциональное программирование: сделайте код лучше</a></li><li><a href="https://tproger.ru/articles/perehod-s-java-na-kotlin-pri-sozdanii-mobilnogo-prilozhenija">Переход с Java на Kotlin при создании мобильного приложения</a></li><li><a href="https://tproger.ru/translations/10-lajfhakov-dlja-android-razrabotchika-poleznye-extensions-na-kotlin">10 лайфхаков для Android-разработчика: полезные extensions на Kotlin</a></li></ol>]]></content:encoded>
    </item>
    <item>
      <title>Ужасный код: если бы злодеи хорроров стали программистами</title>
      <link>https://tproger.ru/articles/uzhasnyj-kod--esli-by-zlodei-horrorov-stali-programmistami</link>
      <comments>https://tproger.ru/articles/uzhasnyj-kod--esli-by-zlodei-horrorov-stali-programmistami?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/uzhasnyj-kod--esli-by-zlodei-horrorov-stali-programmistami</guid>
      <description><![CDATA[<p>Мы погрузились в мрачный мир фантазий и представили, какие языки программирования и роли могли бы выбрать самые известные злодеи хоррор-фильмов, если бы они ворвались в IT. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/uzhasnyj-kod--esli-by-zlodei-horrorov-stali-programmistami">Ужасный код: если бы злодеи хорроров стали программистами</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 31 Oct 2024 09:30:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ночь Хэллоуина сгущается, тьма окутывает мир, и из самых глубоких уголков кинематографа выходят наши любимые кошмары. Но представьте, если бы эти жуткие персонажи сменили свое оружие на клавиатуру и монитор? Что, если бы Норман Бейтс автоматизировал свой мотель с помощью Python, а Пеннивайз заманивал пользователей в свои веб-ловушки на JavaScript?</p><h2>1. Норман Бейтс («Психо»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/6951c6b4-9e2b-4498-94aa-7700063929f1.jpg" alt="" /></figure><h2>Почему Python?</h2><p>Норман — сотрудник с раздвоением личности. Python для него как второй Норман: гибкий, мощный и позволяет быстро автоматизировать все, что только можно. Идеально подходит для человека, который ведет двойную жизнь и хочет держать все под контролем, не привлекая лишнего внимания.</p><h2>Его путь в IT</h2><p>Норман начинал как сисадмин в семейном мотеле "Бейтс". Ручное управление серверами быстро ему надоело — ну сколько можно делать одно и то же? Он начал писать скрипты на Python, автоматизируя бэкапы, мониторинг и деплой. Затем подсел на Docker и Kubernetes, завернул всю инфраструктуру в контейнеры и настроил CI/CD пайплайны.</p><p>Однажды Норман без уведомления команды внес критические изменения в продакшен-серверы ночью, когда никого не было на месте. Это привело к сбою системы на несколько часов. Когда коллеги попытались разобраться, он отрицал свою причастность, ссылаясь на проблемы с автоматизацией.</p><p>Но позже выяснилось, что он сделал это под влиянием своего "второго я", не осознавая последствий.</p><h2>2. Майкл Майерс («Хэллоуин»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/2edbbf8b-1b3f-47ba-af52-d973ac93c0cc.jpg" alt="" /></figure><h2>Почему C?</h2><p>Майкл — молчаливый и непробиваемый. C для него — идеальный язык: никаких лишних абстракций, полный контроль над железом. Ему не нужны навороты и фреймворки — только чистый код и абсолютная власть над системой.</p><h2>Его путь в IT</h2><p>С детства Майкл разбирал и собирал механизмы, пытаясь понять, как все работает изнутри. Начал с ассемблера, но перешел на C, когда понял, что так можно быть эффективнее, не теряя контроля. Работал над прошивками для микроконтроллеров, системами реального времени, где каждая миллисекунда на счету. Его код запускает медицинское оборудование и авионику — там, где ошибки не прощаются.</p><p>Однажды Майкл взялся за разработку критически важного модуля в одиночку, отказавшись от помощи и код-ревью. Когда модуль был интегрирован, система дала сбой, что привело к остановке производства.</p><p>Майкл любитель действовать в одиночку, игнорируя окружающих, на работе его нежелание сотрудничать может привести к серьезным проблемам.</p><h2>3. Пеннивайз («Оно»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/3672c708-3a03-446b-be8c-4cb2aa300c53.jpg" alt="" /></figure><h2>Почему JavaScript?</h2><p>Пеннивайз — мастер иллюзий и обмана. JavaScript для него — как волшебная палочка: можно творить что угодно и где угодно. Он любит удивлять пользователей неожиданными эффектами и нестандартными решениями. Вездесущность JS позволяет ему быть везде и сразу, играя с восприятием и ожиданиями.</p><h2>Его путь в IT</h2><p>Начал с создания веб-сайтов, которые завораживали и одновременно пугали пользователей своей необычностью. Быстро освоил все популярные фреймворки, переключаясь между React и Vue. Решил, что одной клиентской магии мало, и ушел в бэкенд.</p><p>Однажды Пеннивайз внедрил в продакшен нестабильную экспериментальную функцию без согласования. Пользователи были шокированы неожиданными изменениями интерфейса, что привело к массовому оттоку клиентов.</p><p>Раньше он появлялся и пугал детей, теперь на работе его неожиданные решения могут привести к убыткам компании и увольнению одним днем.</p><h2>4. Гостфейс («Крик»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/402925e7-3402-42e4-bdb4-36cc95b258aa.jpg" alt="" /></figure><h2>Почему Ruby?</h2><p>Гостфейс обожает интриги и игры разума. Ruby, по его мнению, идеально подходит для хакинга. Ему нравится быть на шаг впереди и всегда оставаться в тени. Ruby дает ему возможность быстро писать скрипты для поиска уязвимостей и эксплойтов.</p><h2>Его путь в IT</h2><p>Сначала был обычным админом, но быстро заскучал без адреналина. Погрузился в мир кибербезопасности, специализируясь на пентестах и социальной инженерии. Может украсить пароль у кого угодно, используя социальную инженерию и хитрость. В компании он тот, кто проводит внутренние проверки безопасности, и никто не знает, когда ждать следующего сюрприза.</p><p>На прошлой неделе Гостфейс решил проверить бдительность коллег и организовал фишинговую атаку внутри компании без предупреждения руководства. Это вызвало панику и недоверие среди сотрудников. Но лучше так, чем терроризировать жертв звонками, хотя...</p><h2>5. Кожаное лицо («Техасская резня бензопилой»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/6b8107b6-df04-4239-9fcf-e2bdc89ca177.jpg" alt="" /></figure><h2>Почему C++?</h2><p>Кожаное лицо любит работать с железом напрямую. C++ дает ему мощь и гибкость, позволяя писать эффективный код для микроконтроллеров. Он ценит контроль над памятью и возможность выжать максимум из ресурсов. Для него код — это инструмент, как и бензопила, которым он мастерски владеет.</p><h2>Его путь в IT</h2><p>С юных лет мастерил устройства из подручных материалов. Когда открыл для себя программирование микроконтроллеров, понял, что это его стихия. Создает прошивки для IoT-устройств, умных гаджетов и даже для самодельных девайсов. Его разработки надежны и устойчивы к любым условиям — будь то жара Техаса или суровая зима.</p><p>Коллеги знают: если нужно что-то спаять, запрограммировать и заставить работать — это к нему. Хотя он не особо разговорчив и может показаться грубоватым.</p><p>Во время стресса из-за сжатых сроков Кожаное лицо повредил дорогостоящее оборудование в лаборатории, пытаясь "улучшить" его без согласования.</p><h2>6. Акула («Челюсти»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/dbc0f930-5c93-49e9-a00e-836b47b26d6c.jpg" alt="" /></figure><h2>Почему Go?</h2><p>Акула — воплощение скорости и эффективности. Go для нее — идеальный инструмент для создания высокопроизводительных сервисов. Простота синтаксиса и мощные возможности конкурентности позволяют ей строить системы, которые не тонут под нагрузкой. Go — это язык для хищников, которые не терпят рутинных задач.</p><h2>Ее путь в IT</h2><p>Начинала с Java, но быстро поняла, что Go лучше подходит для ее целей. Стала экспертом в микросервисной архитектуре, разворачивая кластеры, способные обрабатывать миллионы запросов в секунду. Ее код оптимизирован на все 100%, как и она сама в погоне за добычей.</p><p>Коллеги уважают ее за способность быстро решать сложные задачи и держать систему на плаву. Но однажды в попытках улучшить производительность, Акула самостоятельно изменила настройки кластера, что привело к потере данных. Ей сложно перестроиться от бесконтрольных атак, поэтому на работе ее агрессивные действия могут причинить ущерб. Будьте осторожны.</p><h2>7. Существа из «Тихое место»</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/76c6e40d-6b9e-4077-b55d-f300f7cd357d.jpg" alt="" /></figure><h2>Почему Rust?</h2><p>Существа ценят тишину и надежность. Rust дает им безопасность и высокую производительность, предотвращая ошибки еще на этапе компиляции. Они создают системы, которые работают без сбоев и не требуют вмешательства — все тихо и гладко. Rust — идеальный язык для тех, кто предпочитает оставаться в тени, обеспечивая стабильность.</p><h2>Их путь в IT</h2><p>Начали как системные администраторы, но быстро поняли, что могут сделать больше. Освоили Rust для разработки внутренних инструментов и сервисов мониторинга. Настроили инфраструктуру так, что пользователи даже не подозревают о ее существовании — все работает как по маслу, без лишнего шума.</p><p>Недавно их чрезмерная реакция на мелкие проблемы привела к полной остановке системы. Маленький баг был воспринят как критическая угроза, и они отключили сервисы для "предотвращения катастрофы". Помните, они нападают на любой звук, на работе их гиперчувствительность может нанести вред.</p><h2>8. Сара Фир («Улица страха»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/68b9ede1-3c9c-46a8-b7c8-4d5c22e73a5c.jpg" alt="" /></figure><h2>Почему Kotlin?</h2><p>Сара видит то, что скрыто от других. Kotlin дает ей мощь и гибкость для создания масштабируемых приложений. Он современный и лаконичный, позволяющий писать чистый и понятный код. В сочетании с ML она строит модели, которые могут предсказывать будущее.</p><h2>Ее путь в IT</h2><p>Начинала как аналитик данных, копаясь в цифрах и выявляя закономерности. Освоила Kotlin, чтобы писать эффективные приложения для обработки больших данных.  Руководит командой Data Science, создавая алгоритмы, которые помогают компании быть на шаг впереди конкурентов.</p><p>Убежденная в своей правоте, Сара обновила новую модель без тестирования. Это привело к неверным прогнозам и финансовым потерям. Стоит сказать CTO, что на работе ее уверенность может обернуться против компании.</p><h2>9. Джейсон Вурхиз («Пятница, 13-е»)</h2><figure><img src="https://media.tproger.ru/user-uploads/99854/2024-10-30/d3194107-8621-4d13-a422-7c047cd60ee9.jpg" alt="" /></figure><h2>Почему Java?</h2><p>Джейсон — вечный, как сама Java. Java для него — символ стабильности и надежности. Он ценит проверенные временем технологии и масштабируемость, которую предоставляет язык. Его код такой же прочный, как и он сам, выдерживает любые нагрузки и атаки.</p><h2>Его путь в IT</h2><p>Начал с разработки для банков и крупных корпораций, где ошибка может стоить миллионов. Специализируется на системах, где отказоустойчивость и безопасность на первом месте. С помощью Spring и Hibernate строит архитектуры, которые работают годами без сбоев.</p><p>Было и такое, что Джейсон отказался от обновления технологий и продолжал использовать устаревшие версии, что сделало систему уязвимой для атак. Уверенность в стабильных решениях — это хорошо, но на работе его сопротивление изменениям может навредить безопасности компании.</p><p>Вот такие айтишные персонажи могли бы получиться из наших любимых хоррор-злодеев! У каждого свой уникальный стиль, подход к работе и, конечно же, свой любимый язык программирования.</p>]]></content:encoded>
    </item>
    <item>
      <title>Дилемма СТО: внедрять инновационные технологии или использовать проверенный стек</title>
      <link>https://tproger.ru/articles/dilemma-sto--vnedryat-innovacionnye-tehnologii-ili-ispolzovat-proverennyj-stek</link>
      <comments>https://tproger.ru/articles/dilemma-sto--vnedryat-innovacionnye-tehnologii-ili-ispolzovat-proverennyj-stek?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/dilemma-sto--vnedryat-innovacionnye-tehnologii-ili-ispolzovat-proverennyj-stek</guid>
      <description><![CDATA[<p>Есть поговорка, что разработчики трудятся по принципу «работает, не трогай», но откуда тогда появляются прорывные решения? Рассмотрим, как создаются быстрые и конкурентоспособные ИТ-продукты на реальных кейсах: обсудим ИИ-ассистентов, разговоры с Пушкиным (как в «Черном зеркале») и конечно затронем тему найма разработчиков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/dilemma-sto--vnedryat-innovacionnye-tehnologii-ili-ispolzovat-proverennyj-stek">Дилемма СТО: внедрять инновационные технологии или использовать проверенный стек</a>»</p>]]></description>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Распознавание]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 15 Oct 2024 10:24:59 GMT</pubDate>
      <content:encoded><![CDATA[<p>Часто ИТ-команды используют проверенные технологии для новых проектов. Есть подходящая команда, опыт и не нужно тратить ресурсы и время на исследования, проверку гипотез и переобучение людей. В большинстве случаев это помогает создать надежный и качественный продукт в срок, но когда нужно создать абсолютно новое для рынка решение, этот подход не работает.</p><p>На конференции МТС Платформа 2024 Инесса Галактионова, первый вице-президент МТС по телекоммуникационному бизнесу, рассказала о подготовке компанией виртуального ассистента, который станет полноценным участником телефонных звонков. Чем он будет отличаться от существующих голосовых ассистентов и почему его невозможно было сделать по принципу «как все», расскажу вам я, CTO стрима «Виртуальный ассистент» компании МТС, Иван Мясников.</p><h2>Новые подходы нужны для уникальных продуктов</h2><p>Наш ассистент рассчитан не только на стандартные для ИИ задачи. Да, он подскажет прогноз погоды или прочитает сказку, но основная его фишка не в этом. Мы первые решили внедрить ИИ-ассистента прямо в звонок: он будет реагировать на голосовую команду, записывать звонок, если это нужно абоненту, выделять из него главное и отправлять в SMS. Или даже собирать информацию по теме, пока вы говорите по телефону.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2024-10-14/890f18f8-8382-4a81-9c45-44013deef982.jpg" alt="" /><figcaption>ASR — преобразование речевого сигнала в текстовое представление. Интент — намерение пользователя, которое отражается в поисковом запросе. Skill Classifier — сервис, который производит предварительную классификацию навыков. TTS — синтетическая озвучка заданного текста.</figcaption></figure><p>Как это работает: допустим, вы с друзьями планируете совместное путешествие. Вы созвонились обсудить поездку, позвали ассистента во время звонка. Он по команде запишет нужную часть разговора, чтобы никто не забыл о планах, узнает погоду, найдет доступные рейсы и отели в пункте назначения, соберет достопримечательности, которые можно посетить, и так далее. Все за счет распознавания речи и интеграции с другими сервисами экосистемы МТС.</p><p>При этом ассистент не будет влиять на качество связи. В звонок мы встраиваем только маленькую и легкую модельку, которая определяет, вызвал ли абонент голосового ассистента. Если имя ассистента названо, запускается распознавание голоса и общение на естественном языке, но оно происходит асинхронно, поэтому не влияет на качество связи.</p><p>Чтобы сделать такой продукт, аудиопоток должен передаваться быстрее, а речь — считываться и записыватьсякачественнее, чем у конкурентов. У любого такого продукта на старте мало данных для обучения моделей, а синтетически генерировать их дорого и неэффективно. Поэтому приходится «срезать углы», выбирая нестандартные решения, чтобы выиграть время и опередить конкурентов. Поэтому мы приняли несколько нестандартных решений.</p><p>Во-первых, отошли от обычной для нас работы через веб-сокет и выбрали gRPC-протокол. Исследование, проведенное нашей командой, показало, что gRPC позволяет выиграть в скорости получения голосового запроса и скорости доставки ответа абоненту. При нагрузочном тестировании мы обнаружили, что такой подход дает нам выигрыш по скорости в два-три раза. Пользователь получает ответ быстрее, а оборудование загружается меньше. Преимущество появилось за счет того, что веб-сокет передает данные в текстовом формате, а gPRC — в бинарном. Вместе с HTTP/2 протокол gPRC позволяет включать мультиплексирование, сжимать передаваемые данные и при необходимости приоритизировать запросы.</p><p>Во-вторых, для бэкенда мы выбрали язык Kotlin вместо применяемого обычно Java. У этого решения нашлось несколько важных преимуществ. Из главных — меньший объем кода и лучшая читаемость за счет корутин и более лаконичного синтаксиса. Концепция Null Safety в Kotlin помогает избежать ошибок неопределенности — одних из самых частых и очень трудно выявляемых в Java. В результате оказалось, что применение Kotlin повышает надежность и масштабируемость системы по сравнению с Java при сравнимых трудозатратах.</p><p>Бонусом мы получили неожиданный источник кандидатов. Если у вас уже набрано ядро команды, то можно хантить джавистов и быстро их переучивать. Оказалось, что многие разработчики на Java осознают вышеперечисленные преимущества и рассматривают переход на Kotlin как ступеньку в карьере или возможность найти для себя новые вызовы и задачи.</p><h2>Дело не только в стеке</h2><p>Иногда новые подходы не связаны с технологическим стеком. Чтобы собрать лучших, мы нанимали ребят по всей России, они живут в разных часовых поясах. Но это не мешает нам работать по спринтам, ревьюить код, тестировать, править баги, проводить ретро и демо.</p><p>После «ковидной» удаленки мы не стали возвращать всех сотрудников в офис, а перестроили процессы и перешли на асинхронный подход: когда мы пишем запрос в чат или комментарий в задаче, то не ждем мгновенного ответа. Для этой модели важна правильная декомпозиция — в компании должно быть достаточно независимых процессов и задач. Тогда даже если вы получите ответ не сразу, а через день-два, ничего страшного не произойдет: специалист просто переключается на другую часть задачи или меняет «таску». Главное, что в результате ему не приходится ждать или торопить коллег.</p><p>В результате повышается концентрация всех членов команды: не нужно постоянно мониторить чаты, задачи и почту, можно выделить на это, например, час после ежедневной планерки, а все остальное время кодить, тестировать, писать документацию. Сокращение количества созвонов (мы оставили только самые необходимые мероприятия — демо, ретро и т.п.) особенно важно для команды, которая работает в разных часовых поясах: от Москвы до Братска.</p><p>А как же встречи у кулера и командные обеды, без которых, кажется, невозможно выстроить взаимоотношения в команде? Мы нашли, чем их заменить. Иногда собираем всех в одном городе (чаще всего в Москве), работаем в офисе, а после идем толпой в бар или еще куда-нибудь. За счет этого ребята узнают друг друга лично и налаживают связи. Они сами организуются в клубы по интересам: в одном городе собираются поиграть в настолки, в другом — в футбол.</p><p><a></a>Мы начали работать по асинхронной схеме не сразу. Сперва договаривались с разработчиками, что нужно ответить в течение часа, потом – в течение двух; ребятам, которые всегда отвечали в течение двух минут, рассказывали, что отвлекаться от текущих задач не обязательно, ничего не сгорит. Параллельно работали с продактами, рассказывали, что нужен запас времени на выполнение задачи, чтобы мы могли работать эффективно, качественно, в срок, но не в спешке из-за того, что кто-то уже пообещал показать новую версию.</p><p>Свой подход к работе мы перенесли в наём: сразу рассказывали о процессах, о специфике нашей работы, искали подходящих ребят через вопросы и разбор кейсов на собеседовании. Например: «К вам в 9 утра прибежал коллега с задачей, которую обязательно надо сдать сегодня. Что вы будете делать?»</p><p>Наконец, в роли СТО я старался работать с коллегами, которые приходят с горящими задачами, например: «Через неделю демо продуктов, нам надо обязательно участвовать, и мы хотим показать фичи 1, 2 и 3, хотя мы понимаем, что фича 2 не будет готова вовремя, надо повышать приоритет, чтобы успеть». В таких случаях мы выясняем, откуда срочность — действительно ли надо реализовать функцию к ближайшей встрече или имеет смысл сделать ее несколько позже, зато более качественно.</p><p>Разбор с коллегами, когда задача действительно нужна срочно, а в каких случаях требует более глубокой проработки — это специфика продукта на старте, сейчас такая дилема возникает редко. Но в любом случае опыт инцидент-менеджмента, когда приходится выбирать между интересами разных команд и отделов, позволяет улучшить процесс и организацию действий. Получив достаточный опыт работы с новым продуктом, мы научились декомпозировать возникающие задачи так, чтобы выполнять их качественно и в срок.</p><p>Конечно, бывают случаи, когда надо сделать что-то максимально быстро. Тогда мы переходим в режим «синхронной коммуникации», но после решения всех проблем возвращаемся к более эффективному для нас «асинхронному» состоянию.</p><h2>Что дают инновации разработчику?</h2><p>Я и вне работы стараюсь следить за развитием технологий, чтобы не терять интерес к программированию. Иногда делаю пет-проекты.</p><p>Забавный пример: когда команда только-только формировалась, многие ребята делились друг с другом мемами в корпоративном чате, и это не нравилось части коллег. Чтобы их примирить, я сделал бота, который собирал мемы. А потом он отправлял их в отдельный канал, куда заходили только желающие.</p><p>Из недавнего и интересного: делаю сервис Personaj, в котором можно общаться с виртуальными личностями — от Эйнштейна до Пикачу. Сейчас аватаров уже больше 100, и база растет (к тому же можно добавить своего). Суть такая: каждый человек после регистрации может предоставить фото, текстовое описание и имя персонажа — допустим, Пушкин. Моделька на основе этих UGC-данных создаст аватара, который будет отвечать, как этот самый Пушкин (с учетом предоставленных данных, конечно). Другой вариант — поговорить с уже готовым Пушкиным, данные о котором мы подгрузили из открытых источников.</p><p>Бэкенд у нас на Python, фронт пока на low-code, но скоро переедем на React, который мне всегда нравился. Смотрел и другие варианты, например, порог входа в Angular по необходимым знаниям мне показался выше, и он скорее подходит для больших команд. Так что важно учитывать разные аспекты при выборе стека и подбирать его не только под задачу, но и под имеющуюся команду. Вот примеры работы проекта:</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2024-10-14/df4f7797-82ca-4895-bc63-1c38b14e762b.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/101078/2024-10-14/588aab5e-1a4a-497c-b6fb-3dd9f994d917.png" alt="" /></figure><h2>Всегда ли нужны новые технологии?</h2><p>В заключение отмечу, что не обязательно в каждый проект внедрять новый фреймворк или модный язык программирования. Все зависит от конкретной задачи. Если вам нужно сделать что-то инновационное или догнать конкурентов, разумеется, лучше пробовать новое. Но если делаете стандартный продукт, который хорошо работает на старом стеке, не стоит изобретать велосипед.</p><p>В случае с ассистентом новый стек был необходим, но для системы авторизации МТС ID, которую мы делали для экосистемы, подобного не требовалось. Так что мы взяли многим известный <a href="https://www.keycloak.org/">Keycloack</a>, интегрировали и получили качественный продукт (который к тому же оставляет возможности для кастомизации и написания собственных, нестандартных интеграций).</p><p>Чтобы понять, что нужно внедрять инновации, пробовать новые технологии в проекте, я советую отталкиваться от следующих критериев:</p><ol><li>Есть ли у кого-то в команде опыт работы в этом направлении или все будут учиться вместе «с нуля».</li><li>Есть ли время и ресурсы на исследования и готовы ли вы к тому, что часть идей и гипотез не выстрелит.</li></ol><p>Часто привычных для вас подходов хватает, чтобы сделать надежный, качественный продукт. Но не стоит забывать, что разработка — это постоянное обучение и рост над собой.</p>]]></content:encoded>
    </item>
    <item>
      <title>У Яндекса появился аналог GitHub Copilot для помощи с написанием кода</title>
      <link>https://tproger.ru/news/--u-yandeksa-poyavilsya-analog-github-copilot-dlya-pomoshhi-s-napisaniem-koda</link>
      <comments>https://tproger.ru/news/--u-yandeksa-poyavilsya-analog-github-copilot-dlya-pomoshhi-s-napisaniem-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--u-yandeksa-poyavilsya-analog-github-copilot-dlya-pomoshhi-s-napisaniem-koda</guid>
      <description><![CDATA[<p>Яндекс запускает Yandex Code Assistant — аналог GitHub Copilot для российских разработчиков. Этот ИИ-ассистент помогает генерировать продолжение кода на популярных языках, таких как C++, Go, Java и Python</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--u-yandeksa-poyavilsya-analog-github-copilot-dlya-pomoshhi-s-napisaniem-koda">У Яндекса появился аналог GitHub Copilot для помощи с написанием кода</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[Сбер]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 12 Sep 2024 08:25:07 GMT</pubDate>
      <content:encoded><![CDATA[<p>Яндекс готовит к запуску собственного ИИ-ассистента для программистов, который будет помогать в написании кода, аналогично Copilot от Microsoft.</p><p>Сервис получил название Yandex Code Assistant. Его тестирование уже началось на облачной платформе Yandex Cloud.</p><p>Хотя доступ к новинке ограничен и требует <a href="https://yandex.cloud/services/code-assistant">подачи заявки</a>, Яндекс обещает, что в будущем она станет доступной более широкому кругу разработчиков.</p><h2>Yandex Code Assistant: российский ответ Microsoft Copilot</h2><p>Yandex Code Assistant позволяет разработчикам по фрагменту кода автоматически генерировать его продолжение.</p><p>Это значительно упрощает процесс написания и редактирования программного обеспечения, ускоряя разработку.</p><p>Яндекс сообщил, что сервис был протестирован тысячами внутренних разработчиков, из которых 60% стали постоянными пользователями.</p><p>На данный момент новинка поддерживает генерацию кода на популярных языках, таких как C++, Go, Java, Kotlin и Python. При этом планируется расширение списка поддерживаемых языков до более чем 30.</p><h2>Удобство использования и эффективность</h2><p>По словам разработчиков ассистента, одним из ключевых преимуществ Yandex Code Assistant является его скорость.</p><p>В 95% случаев ассистент генерирует продолжение кода всего за 400 мс, не нагружая при этом ресурсы компьютера разработчика, так как вся обработка происходит в облаке.</p><p>Сервис поддерживает работу с популярными редакторами кода, хотя конкретные названия пока не были раскрыты:</p><h2>Российские конкуренты</h2><p>Yandex Code Assistant — это не первая попытка создания российского аналога Copilot.</p><p>В 2023 году Сбер также запустил своего ИИ-ассистента GigaCode, а MTS AI представила сервис Kodify для генерации кода.</p>]]></content:encoded>
    </item>
    <item>
      <title>Blink: что под капотом приложения для мониторинга друзей</title>
      <link>https://tproger.ru/interview/blink--chto-pod-kapotom-prilozheniya-dlya-monitoringa-druzej</link>
      <comments>https://tproger.ru/interview/blink--chto-pod-kapotom-prilozheniya-dlya-monitoringa-druzej?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/interview/blink--chto-pod-kapotom-prilozheniya-dlya-monitoringa-druzej</guid>
      <description><![CDATA[<p>Расскажем о том, как функционирует приложение для мониторинга друзей Blink. Какой стек используется для точной геолокации и каким образом пользователи взаимодействуют друг с другом.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/interview/blink--chto-pod-kapotom-prilozheniya-dlya-monitoringa-druzej">Blink: что под капотом приложения для мониторинга друзей</a>»</p>]]></description>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Интервью]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 15 Aug 2024 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<h4>На сайте приложения указано, что оно создано выходцами из Zenly. Получается, вы выступаете в роли «импортозаместителя»? Или Blink — самостоятельное решение, лишь вдохновленное французами?</h4><p>После закрытия Zenly мы вместе с коллегами Димой Трачуком и Марией Мышь (ранее работала в Zenly), собрались и начали обдумывать создание своего приложения. К нам постепенно присоединились и другие специалисты, и мы продолжили формировать команду.</p><p>Конечно, вдохновлялись Zenly, ведь сами являлись активными пользователями ранее популярного и полезного сервиса. После его закрытия у нас появилась потребность в аналогичном решении для отслеживания местоположения друзей. Поэтому мы решили создать Blink. Позаимствовали положительный опыт использования Zenly, но дополнили продукт новыми функциями и улучшениями, делающими его уникальным и отвечающим потребностям пользователей.</p><p>Стоит отметить, что импортозамещение обычно подразумевает создание аналога продукта, который больше не доступен в России. В случае Zenly, это приложение не просто ушло из России — оно полностью прекратило свою деятельность. Поэтому мы не выступаем импортозаместителями в прямом смысле этого слова. Наше приложение — самостоятельное решение, разработанное с нуля.</p><h3>Какие основные функции и возможности предлагает Blink пользователям? Можем ли мы «бампнуться» по-старинке или отправить смайлик другу на весь экран?</h3><p>Blink — это приложение, которое вобрало в себя все ключевые функции некогда популярного Zenly, но с рядом значительных улучшений и новшеств.</p><p>Одна из новых возможностей Blink — функция отслеживания шагов. Теперь пользователи могут соревноваться друг с другом, сравнивая свою ежедневную активность. Эта опция стала возможной благодаря высокой точности геолокации.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-08-14/c444357c-95a1-4193-a055-07d1a4d48d04.jpg" alt="" /></figure><p>Кроме того, в Blink реализована усовершенствованная система чекинов. При отметке пользователя в определенной локации, его друзьям тут же приходит push-уведомление. В Zenly данная функция работала менее эффективно, поэтому мы приняли решение о ее полной переработке.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-08-14/0de5084e-74cf-4642-a958-e24b7174310d.png" alt="" /></figure><p>Еще одна интересная особенность Blink — функция «трях», аналогичная «бампу» из Zenly. Теперь, чтобы сообщить друзьям о встрече, достаточно просто потрясти телефонами. Вообще, термин «бамп» в английском языке имеет сексуальный подтекст, поэтому для англоговорящей аудитории звучит так же странно, как «трях» для русскоязычной.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-08-14/a51f6344-011c-4120-a888-11d1a83cdaed.jpg" alt="" /></figure><h3>Какие программные платформы и языки программирования использовались для разработки Blink? Почему был выбран именно такой технологический стек?</h3><p>Выбор стека связан с наличием специалистов на рынке, задачами и с высокими хайлоадом.  В качестве основного языка веб-разработки мы выбрали компилируемый  Golang, это современный стандарт для стартапов.</p><p>Помимо Golang, в стек входит ряд других ключевых инструментов. Для обработки потоков данных в режиме реального времени используется Apache Kafka, надежный и производительный брокер, с которым уже была знакома команда разработчиков и DevOps/SRE. Выбор Kafka обусловлен необходимостью надежной маршрутизации гигабайтов геопакетов в секунду.</p><p>В качестве основной базы данных выбран PostgreSQL, известный своей надежностью, производительностью и возможностью масштабироваться. Для кэширования данных используется Redis, а ClickHouse – для аналитики и обработки больших объемов данных, в том числе для пост-процессинга геокоординат. На данный момент объем данных в кластере приближается к 30 ТБ, и ClickHouse справляется с этой нагрузкой.</p><p>Для мобильных платформ мы используем Swift для iOS и Kotlin для Android.</p><p>Основной принцип, которым руководствуемся при выборе технологий – широкое распространение и длительная история использования, гарантирующие надежность. Было решено не экспериментировать с новыми технологиями, а использовать проверенные инструменты, с которыми уже работали ключевые специалисты.</p><h3>Перейдем к конкретным фичам. Какие алгоритмы и методы используются для определения местоположения пользователей в Blink? Как вы обеспечиваете высокую точность геолокации?</h3><p>В основе нашей работы лежит сбор данных с устройств пользователей и применение технологий геофенсинга. Хотя мы не изобретаем революционных решений, поскольку действуем в рамках закрытых операционных систем (iOS и Android), тщательно обрабатываем полученные данные, чтобы обеспечить их точность и надежность. Как происходит процесс?</p><p>Все начинается с получения координат от пользователя. Эти данные проходят несколько этапов проверки. Мы анализируем, не произошел ли резкий скачок местоположения, например, перемещение из России в Австралию за короткий промежуток времени. Фильтр Калмана помогает сглаживать координаты, удаляя аномальные значения и улучшая точность.</p><p>Если координаты проходят наши фильтры, они отправляются на дальнейшую обработку. Но если выявляем проблемы по типу воздействия GPS-глушилок,  применяем дополнительные этапы проверки.</p><p>Мы также проверяем, находится ли пользователь в знакомом окружении, например, в домашней сети Wi-Fi. Если данные указывают на аномальное перемещение, корректируем местоположение.</p><p>Стоит отметить, что в последнее время мы все чаще сталкиваемся с проблемами навигационных систем и GPS-глушилок. Поэтому разработали целый ряд фильтров и механизмов для обеспечения высокой точности геолокации. Кроме того, работаем над улучшением клиентской части, оптимизируя работу приложения для минимального потребления заряда аккумулятора. Blink в среднем потребляет всего 1% заряда в сутки, что является отличным показателем. Мы потратили много времени на это улучшение, и теперь приложение практически не тратит заряд, хотя работает в фоновом режиме.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2024-08-14/169567a1-cae3-4ffc-b020-a1c9b75b0bb0.png" alt="" /></figure><h3>Как реализована система хранения и обработки больших объемов геоданных в приложении? Какие технологии и подходы задействованы?</h3><p>Мы внедрили два ключевых решения: Apache Kafka и ClickHouse.</p><p>Apache Kafka выступает в качестве надежного механизма передачи данных между различными сервисами. Он обеспечивает бесперебойную доставку координат пользователей, которые постоянно обрабатываются и анализируются приложением.</p><p>В свою очередь, ClickHouse — это высокопроизводительная аналитическая база данных, где мы храним всю историю передвижений наших пользователей. Это позволяет создавать уникальные решения, раскрывающие интересные закономерности и паттерны поведения людей. Например, мы можем показывать пользователям, где они чаще всего ночевали, с кем больше всего общались, какие места посещали и какие районы исследовали. Эти «цифровые следы» помогают людям лучше понимать свои привычки.</p><p>Стоит отметить, что объем накопленных нами данных уже превышает 30 терабайт. Это огромный массив информации, который требует применения современных Big Data решений, таких как Kafka и ClickHouse. Благодаря этому мы можем эффективно управлять и анализировать все эти данные, извлекая ценные инсайты и предоставляя полезный сервис нашим пользователям.</p><h3>А что насчет самих пользователей? Как вы подходите к вопросам безопасности и конфиденциальности данных в Blink? Какие меры предприняты для защиты личной информации?</h3><p>Мы применяем комплексный подход, сочетающий в себе передовые технологии шифрования и строгие меры контроля доступа.</p><p>Во-первых, все данные тщательно зашифрованы. Даже в случае несанкционированного доступа к бэкапам, злоумышленник не сможет расшифровать эту информацию без наличия соответствующих ключей. Объем хранимых данных также делает невозможным их незаметное похищение.</p><p>Во-вторых, в компании регулярно проводится аудит безопасности. Мы тщательно контролируем, кто и к каким данным имеет доступ. Более того, любое обращение к конфиденциальным ресурсам, будь то подключение к базе данных из нестандартного местоположения, вызывает срабатывание системы оповещения. Таким образом, все действия с чувствительной информацией пользователей фиксируются в журнале регистрации и расцениваются как инциденты безопасности.</p><h3>Какие методы и инструменты применяются для анализа поведения пользователей, их передвижений и активности в приложении? Как вы используете эти данные для улучшения сервиса?</h3><p>У нас есть два основных направления аналитики: клиентская и серверная.</p><p>Для клиентской аналитики мы используем как бесплатные, так и платные трекеры для отслеживания активности пользователей. Одним из ключевых инструментов является Amplitude, позволяющий собирать и анализировать данные о взаимодействии пользователей с приложением.</p><p>В части серверной аналитики:</p><ul><li>Все события, связанные с действиями пользователей, собираются и отправляются на наш сервер, где хранятся в базе данных ClickHouse. Это касается как клиентских, так и серверных событий.</li></ul><ul><li>Собранные данные затем передаются в BI-системы, такие как Redash и Superset, для визуализации и построения дашбордов.</li></ul><ul><li>Наши аналитики проверяют гипотезы и анализируют поведение пользователей. При этом данные обезличены, чтобы не нарушать конфиденциальность.</li></ul><p>Один из последних кейсов:</p><p>В дашборде, посвященном онбордингу пользователей, мы заметили значительное снижение конверсии на этапе заполнения никнейма. Анализ показал, что многие никнеймы уже были заняты, и новым пользователям сложно было выбрать уникальные. В результате мы внедрили функцию автоматической генерации никнеймов, с возможностью их изменения. Это решение повысило конверсию на этапе онбординга на 3 процентных пункта.</p><p>В целом, при разработке новой функциональности мы всегда опираемся на данные. Мы анализируем, как пользователи взаимодействуют с приложением, какие у них возникают проблемы, что пользуется наибольшей популярностью, а что — меньшей. Такой аналитический подход позволяет нам принимать обоснованные решения и улучшать продукт на основе реальности, а не интуитивных предположений.</p><h3>С какими основными трудностями и вызовами вы сталкивались в процессе разработки и масштабирования Blink? Как вы их преодолевали?</h3><p>Несмотря на стремительный рост, мы столкнулись с несколькими серьезными техническими вызовами:</p><ol><li>Изначально, с нагрузкой в 10 тысяч онлайн-пользователей, наши го и легковесные горутины, а также оптимизированные веб-фреймворки справлялись с нагрузкой. Однако с ростом аудитории до 100 тысяч возникли проблемы на сетевом уровне, которые нашим инженерам удалось решить за счет переконфигурирования балансеров (nginx + sysctl).</li><li>Для хранения географических данных мы выбрали PostgreSQL, но со временем объем этих данных превысил 1 ТБ, что привело к существенному падению производительности. Попытки горизонтально масштабировать PostgreSQL оказались малоэффективными, и в итоге мы перешли на Clickhouse, который гораздо лучше справился с этой задачей. Перевод на Clickhouse занял около недели, но куда больше времени потребовалось на миграцию данных из PostgreSQL.</li><li>Недостаток мониторинга приводил к тому, что о проблемах мы узнавали уже тогда, когда они становились критическими и вызывали простои сервиса. Несколько бессонных ночей наглядно продемонстрировали важность использования инструментов вроде Grafana.</li></ol><p>Несмотря на эти трудности, нам удалось преодолеть их и продолжить успешное развитие Blink. Опыт, полученный в ходе решения этих задач, стал для нас бесценным.</p><h3>Каковы ваши планы на дальнейшее развитие приложения? Над какими новыми функциями и возможностями сейчас работаете?</h3><p>В первую очередь, мы активно работаем над улучшением качества геолокации. Поскольку основная особенность нашего продукта заключается в точном определении местоположения пользователей, важно, чтобы оно всегда отображалось корректно. Мы тщательно анализируем возникающие у пользователей проблемы (случайные вылеты и неверные координаты) и внедряем разные фильтры для их минимизации. В случаях, когда проблему невозможно решить из-за внешних факторов, мы честно информируем пользователей о временных неудобствах.</p><p>Из больших сервисов, над которыми работаем сейчас — чекины. Это инструмент, который позволяет пользователям в реальном времени делиться своим местоположением, фотографиями и видео, рассказывая друзьям о том, где они находятся прямо сейчас. В ближайшем будущем планируем добавить элементы геймификации, например, возможность соревноваться за звание «мэра» в различных локациях, основываясь на частоте посещений.</p><p>Кроме того, мы разрабатываем собственную карту Blink Maps, которая будет интегрирована в приложение уже через несколько месяцев для некоторых устройств на Android. Это наша собственная 3D-карта, позволяющая решить технические ограничения, с которыми мы сталкиваемся при использовании платформенных карт, по типу Google Maps. Например, сможем более эффективно отображать больше пинов без задержек и сбоев. Карта будет регулярно обновляться, что позволит избегать проблем с устаревшей информацией. У нас свой движок, построенный на видеопроцессоре GPU, который на основе данных OpenStreetMap делает магию. Основу мы берем из OSM и поверх накручиваем все свои изменения.</p><h3>Как вы считаете, какие тенденции и инновации будут определять развитие мобильных приложений для отслеживания местоположения в ближайшем будущем?</h3><p>Развитие мобильных приложений для отслеживания местоположения будет в значительной степени определяться несколькими ключевыми тенденциями. Во-первых, одним из главных трендов станет создание и использование собственных карт. Компании будут стремиться к разработке индивидуальных картографических решений, чтобы обеспечить более точное и актуальное отображение данных. Это позволит делать карты под себя, а не универсальную балалайку для всех. Сегодня оффлайн — это дополнение к онлайну, а карта лучше всего интегрирует реальный мир в виртуальный.</p><p>Во-вторых, предиктивный анализ и прогнозирование местоположения станут важными направлениями развития. Использование алгоритмов машинного обучения и искусственного интеллекта позволит не только фиксировать текущее местоположение, но и предсказывать перемещения пользователей на основе их привычек и исторических данных. Это значительно улучшит пользовательский опыт и откроет новые возможности для персонализации сервисов.</p><p>Однако, в свете этих тенденций, стоит учитывать, что Apple и Google, например, продолжают усложнять работу с геолокацией для сторонних разработчиков. Несмотря на наличие встроенных решений, таких как Find My Friends у Apple, ограничения и новые требования для работы с геоданными становятся все более жесткими. Это создает дополнительные вызовы для разработчиков, которые должны адаптироваться к меняющимся условиям и искать альтернативные пути стабильной работы своих приложений.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin 2.0: собрали для вас главное из крупнейшего релиза языка за последнее время</title>
      <link>https://tproger.ru/news/kotlin-2-0--sobrali-dlya-vas-glavnoe-iz-krupnejwego-reliza-yazyka-za-poslednee-vremya</link>
      <comments>https://tproger.ru/news/kotlin-2-0--sobrali-dlya-vas-glavnoe-iz-krupnejwego-reliza-yazyka-za-poslednee-vremya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/kotlin-2-0--sobrali-dlya-vas-glavnoe-iz-krupnejwego-reliza-yazyka-za-poslednee-vremya</guid>
      <description><![CDATA[<p>Компания JetBrains наконец-то порадовала нас свежим релизом — Kotlin 2.0. Он включает в себя немало новых возможностей и улучшений</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/kotlin-2-0--sobrali-dlya-vas-glavnoe-iz-krupnejwego-reliza-yazyka-za-poslednee-vremya">Kotlin 2.0: собрали для вас главное из крупнейшего релиза языка за последнее время</a>»</p>]]></description>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 May 2024 12:48:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>JetBrains выпустила долгожданную версию Kotlin 2.0. Релиз включает множество новых возможностей, улучшение производительности и исправление ошибок. Давайте рассмотрим ключевые нововведения.</p><h2>Анализ API</h2><p>В Kotlin 2.0 была улучшена поддержка чтения содержимого библиотек (klib) в анализе API. Это обновление значительно упрощает работу с различными библиотеками и их интеграцию в проекты.</p><h2>Упрощенные инициализаторы</h2><p>Теперь компилятор может лучше оптимизировать код, использующий std::initializer_list, что сокращает количество вызовов memcpy и улучшает производительность.</p><h2>Оптимизация контекстного коллектора, хранения и разрешения</h2><p>Производительность контекстного коллектора была улучшена за счет уменьшения избыточных разрешений в элементах файла, что снижает затраты памяти и ускоряет выполнение операций.</p><p>Были оптимизированы методы getFirForNonKtFileElement и getOnAirGetTowerContextProvider, тем самым время выполнения операций уменьшилось, общая производительность компилятора повысилась.</p><h2>Разрешение проблем с файловыми структурами</h2><p>Исправлены проблемы, связанные с кэшированием и обработкой файловых структур, что повысило стабильность работы инструмента анализа API.</p><h2>Поддержка наследников запечатанных классов</h2><p>Теперь поддержка запечатанных классов в KMP реализована корректно, что устранило множество ошибок и улучшило совместимость между модулями.</p><h2>Улучшение диагностики</h2><p>Kotlin 2.0 предлагает улучшенные диагностические сообщения и поддержку аннотаций, что облегчает отладку и разработку приложений. Введена новая система предупреждений, позволяющая лучше идентифицировать проблемы на ранних этапах разработки.</p><p>Стоит отметить, что Kotlin 2.0 приносит множество улучшений и новых возможностей, о которых в одном материале сложно рассказать. Подробнее можно узнать на странице релиза, перейдя по <a href="https://github.com/JetBrains/kotlin/releases/tag/v2.0.0">ссылке</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin и функциональное программирование: сделайте код лучше</title>
      <link>https://tproger.ru/articles/kotlin-i-funkcionalnoe-programmirovanie--berite-luchwee</link>
      <comments>https://tproger.ru/articles/kotlin-i-funkcionalnoe-programmirovanie--berite-luchwee?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ирина Тюльпакова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kotlin-i-funkcionalnoe-programmirovanie--berite-luchwee</guid>
      <description><![CDATA[<p>Урс Питер на KotlinConf 2023 объяснил, какие принципы сделают код функциональнее, рассказал про монады, контейнеры и библиотеку Arrow.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kotlin-i-funkcionalnoe-programmirovanie--berite-luchwee">Kotlin и функциональное программирование: сделайте код лучше</a>»</p>]]></description>
      <category><![CDATA[Функциональное программирование]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 11 Mar 2024 14:42:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Урс Питер, сеньор software developer поделился лучшими практиками программирования на Kotlin.</p><p>В видео он рассказал:</p><ol><li>В чём заключается основные принципы императивного и ориентированного на выражения программирования.</li><li>Что такое монады и как их использовать.</li><li>О пользе скоуп функций, функций высшего порядка и композитных функций.</li><li>Представил Arrow - библиотеку для Kotlin, которая реализует концепции категорной теории и предлагает расширенные возможности для функционального программирования.</li><li>Продемонстрировал, что важно выборочно использовать монады, так как они могут как улучшить, так и усложнить код.</li></ol><p>Ниже — транскрибация ролика на русском языке.</p><p>Что ж, моя презентация будет посвящена функциональному программированию и Kotlin. Краткое введение о себе.</p><p>Я Урс Питер, сеньор software developer. «Днём» я работаю по специальности. Также  являюсь тренером в Академии Xebia, где помогаю разработчикам на всех этапах в Kotlin от новичка до среднего и продвинутого уровня, что довольно интересно, потому что я сталкиваюсь со многими средами и вижу, как Kotlin используется разными способами. Я также сертифицированный тренер Chatbrain. Карьеру я начинал около 20 лет назад с Java, затем около 10 лет назад перешел на Scala, вложил значительные средства в экосистему Scala, также был одним из первых сертифицированных тренеров, написал множество приложений на Scala, создал учебные материалы.</p><p>Но уже примерно четыре-пять лет я пишу исключительно серверную часть, по крайней мере, на Kotlin. К чему я это? К тому, что именно опыт работы со Scala побудил меня выступить с этим докладом. И это во многом связано с этим графиком.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/83fc7abf-1b19-4023-b083-5fcdff251d88.png" alt="" /></figure><p>Итак, когда вы смотрите на временную шкалу, в 2017 году Kotlin начал стремительно расти, но в то же время начался спад Scala. И вопрос, конечно, в том, почему это так? Нет ни одной резонной причины, но я думаю, что в этой презентации я коснусь довольно важных деталей, почему это произошло. И, конечно, мы не хотим, чтобы это повторилось с Kotlin.</p><p>&lt;...&gt;</p><h2>Стили программирования</h2><p>Тогда, что ж, давайте отправимся в путь и начнем наше путешествие, которое, надеюсь, будет преобразующим. И начнем мы с болот императивного программирования. &lt;...&gt;</p><p>Почему? если бы вы классифицировали стили программирования, которые у нас есть, и выделили бы только две большие группы, мы могли бы сказать, что, с одной стороны, у нас императивное программирование. Оно в основном основывается на объявлениях переменных, которые затем изменяются по ходу дела.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/e61b4b90-8505-4b18-a48f-577fb74fe657.png" alt="" /></figure><p>Как вы видите в этом конкретном примере. Языковая функция, которую мы используем в Kotlin для реализации этого стиля, — это var`s, циклы, множество изменяемых вещей, такие как изменяемые коллекции, изменяемые объекты, операторы return.</p><p>Итак, как только мы достигли определенного этапа, мы думаем: хорошо, теперь все достаточно хорошо. Это императивное программирование.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/40b8b4ef-d6a3-4fdf-9421-4eef50b657f0.png" alt="" /></figure><p>Напротив, у вас есть вторая категория, которая является программированием, ориентированным на выражения (Expression-Oriented Programming). Это еще не функциональное программирование, но оно лежит в его основе. И программирование, ориентированное на выражения, больше опирается на мышление функциями с точки зрения ввода и вывода. Функции, которые мы используем, — это более неизменяемые функции Kotlin, такие как классы данных, неизменяемые коллекции.</p><p>И конструкции, которые мы стараемся использовать, являются конструкциями выражений, что означает, что мы всегда ищем концепции, которые возвращают значение, а не только производят побочный эффект. И это, конечно, также относится к функциям более высокого порядка.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/038e89d2-849e-4e5a-9d46-98a04315fb90.png" alt="" /></figure><p>Примеры, которые вы видите здесь, в точности совпадают. Они дают точно такой же результат. Итак, что же на самом деле является фундаментальным в этих двух стилях программирования?</p><p>Что ж, императивное программирование опирается на изменяемые данные наряду с побочными эффектами. Именно так мы думаем о нашей логике программирования, в то время как программирование, ориентированное на выражения… Оно как бы поддерживает представление о преобразованиях данных на основе некоторого ввода, который затем передается в некоторый вывод, и этот конкретный ввод может снова служить входными данными для следующего преобразования. Это действительно фундаментально для этих двух стилей. Итак, как только я лично начал осваивать экспрессионно-ориентированное программирование, я действительно стал лучше как программист, в том смысле, что я написал более качественное программное обеспечение, которое лучше поддерживается, более надежное и так далее.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/b6da6d4c-b0ed-4a49-9fa7-490d81a9d423.png" alt="" /></figure><p>Почему это так? Ну, это довольно легко обосновать. Итак, во-первых, когда вы просто смотрите на приведенный здесь пример, там меньше строк, он более лаконичный. Это также более понятно, потому что в основном мы программируем на более высоком уровне абстракции. Вместо циклов и изменения переменных мы теперь очень четко выражаем наши намерения, говоря, что мы фильтруем, мы максимизируем. Таким образом, это придает нашему коду больше семантики.</p><p>Поскольку у нас есть ввод-вывод, мы также более детерминированы, верно? Потому что мы получаем выходные данные, а когда у вас есть выходные данные, нам легче их протестировать. И что также интересно отметить, так это то, что при программировании, ориентированном на выражения, наши блоки области видимости (scope blocks) меньше, чем при императивном стиле.</p><p>В императивном примере вы видите, что мы объявляем эту переменную devs сверху, а затем на протяжении всей процедуры мы используем её. Таким образом, область применения довольно велика, в то время как в стиле, ориентированном на выражение, у нас в основном есть только функция, которая является областью применения, а затем мы переходим к следующей области применения, что также значительно упрощает рассуждения о разработке программного обеспечения, о нашем программном обеспечении. Итак, если вы еще не полностью освоили этот стиль программирования, ориентированный на выражение, то я советую сделать это.</p><p>Попробуйте хотя бы две недели. И потом, я совершенно уверен, что если вы по-прежнему будете использовать более императивный стиль, вы от него уже не уйдёте. Потому что когда вы выберетесь из болот императивного программирования, вы окажетесь в плодородной долине программирования, ориентированного на выражения. Ладно, пока все хорошо, что ж, вы можете подумать, что звучит все это мило, но реальный мир не всегда так идеален, как мы только что описали, потому что у нас есть много API, которые все еще очень изменчивы, так как же мы можем справиться с этими ситуациями?</p><h2>Функции области видимости (scope functions)</h2><p>Сначала давайте посмотрим на пример, чтобы увидеть, что мы более или менее делаем. Итак, очевидно, мы инициализируем некоторые клиенты REST, а также назначаем некоторые свойства для выполнения нашего вызова. Затем мы что-то делаем с файлом.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/d52f6874-6c7f-4db3-821d-175e360fdc73.png" alt="" /></figure><p>В конечном итоге мы извлекаем данные с помощью этих REST-клиентов, которые затем выводим в какой-нибудь CSV-файл, и в конце концов закрываем наш ресурс. И поскольку эти API изменяемы, вы можете подумать «хорошо, единственный способ, которым я могу решить эту проблему, — это объявления переменных, а затем попутно менять их». Ну, это не совсем так.</p><p>Потому что в Kotlin есть эти замечательные функции области видимости, и, применяя их, мы можем добиться большего. Это был бы пример со скоуп функциями. Итак, что мы получаем с помощью скоуп функций?</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/cbf2df9d-6820-4a5c-afe4-46c3c623e0c3.png" alt="" /></figure><p>Прежде всего, теперь с помощью apply мы группируем все операции, которые ...вызывают изменения в нашем объекте. Таким образом, он, по крайней мере, изолирован. Мы изолируем нашу изменчивую часть. С помощью let мы можем опустить оператор getAll и return. Кроме того, это приятно, потому что теперь мы четко отмечаем побочный эффект.</p><p>Итак, когда вы читаете этот код, вы говорите: "О да, здесь имеет место побочный эффект". Кроме того, пример с файлом и run является прекрасным примером изоляции в том смысле, что мы группируем операции с файлом в блок, но мы даже не раскрываем файл. В примере слева у нас была файловая переменная, которую мы можем использовать везде. Поэтому, когда мы позже проведем рефакторинг, вы можете легко сделать что-то с файлом, случайно весь его изменить, в то время как справа это действительно применимо только в этом блоке, а не за его пределами.</p><h2>Функции высшего порядка (higher-order functions)</h2><p>Итак, что мы получаем с помощью этих скоуп функций, так это способ как бы соединить императивный мир с миром, более ориентированным на выражение. Итак, имея это в виду, я думаю, мы продвинулись немного дальше в нашей плодотворной долине. Но что ж, когда вы оглядываетесь вокруг, горы все еще есть, верно? И мы еще не там.</p><p>Мы все еще в долине. Итак, давайте посмотрим, сможем ли мы подняться наверх, чтобы полюбоваться прекрасным видом. Итак, мой клиент подходит к моему столу и спрашивает: "Приятно, что вы выводите мои данные в CSV, но мне нужен гораздо более навороченный формат. Я также хочу иметь TSV, отдельные значения в табуляции.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/e394f1a8-bef5-4f63-b4ee-a51ff922842d.png" alt="" /></figure><p>Вот как мы могли бы решить эту проблему, верно?</p><p>Что, конечно, довольно глупо. Мы просто продублировали все это, изменили наши выходные данные на TSV и создали проблему с ремонтопригодностью. Итак, как вы можете лучше решить ее?</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/2cd6563e-a3ed-49e7-9c3e-6982c4c50961.png" alt="" /></figure><p>Это довольно просто сделать. Итак, что мы можем сделать в первую очередь, так это определить часть, которую мы дублировали. И эта дублированная часть, по сути, становится нашей общей структурой управления. Затем мы идентифицируем изменяющуюся часть.</p><p>И мы очень внимательно смотрим на то, что входит и что выходит. И эту часть мы выводим в функцию. А затем используем эту функцию в указанном месте, чтобы, ну, теперь быть очень гибкими. Итак, в этом преимущества функций более высокого порядка. Я часто вижу, что функции более высокого порядка используются в коллекциях и, возможно, в других API, но я не всегда вижу, как они используются в вашем собственном бизнес-коде.</p><p>В то время как есть много случаев, когда у вас есть какая-то структура управления, которую вы хотите повторно использовать и просто подправить определенную ее часть, именно здесь функции более высокого уровня действительно могут отлично справиться. Как пример в тестировании, с которым я часто сталкиваюсь. Тестирование часто не является тем местом, где вы применяете лучшие инженерные практики, поэтому дублирование не считается таким злом, как в реальном бизнес-коде.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/94f49ad1-11d0-4e43-b14b-308e72898028.png" alt="" /></figure><p>Итак, вы видите этот код довольно часто, по крайней мере, там, где я бываю. Например, здесь мы создаем некоторые тестовые данные, а затем очищаем их. Вот пример использования, который у нас здесь есть.</p><p>И здесь применим тот же трюк, выводим общую структуру управления, преобразуем изменяющуюся часть в функцию, и тогда мы получаем два преимущества. Прежде всего, у нас было повторное использование. Мы даже можем сделать нашу функцию немного настраиваемой, например, сказать, что я хочу создать так много элементов для тестирования.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/f98ff4f3-8c1f-4eaa-bea7-d15fcbbdf7b5.png" alt="" /></figure><p>Итак, это, во-первых, повторное использование, а во-вторых, также наши тесты становятся более выразительными, потому что теперь мы можем сосредоточиться на условиях тестирования, а не на всей аппаратуре, необходимой нам для получения определенного фрагмента данных в состоянии, при котором мы можем его протестировать.</p><p>Хорошо. Итак, как только мы освоим функции высокого порядка, мы окажемся на изобильной высоте функций высокого порядка, которая все еще не достигла вершины.</p><h2>Композитные функции (composable functions)</h2><p>Что ж, если вы внимательно посмотрите на эти иерархические функции, которые мы только что создали, то чего нам все еще не хватает, так это какой-то абстракции, чтобы объединить их вместе для создания новых ценных результатов, верно? Итак, чего нам, по сути, не хватает, так это того, что называется композиционностью.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/bec83b0e-eaad-40b1-aa7e-576b5ae52754.png" alt="" /></figure><p>Эти вещи не складываются. Когда мы смотрим на самый первый пример, который мы видели в начале выступления, с коллекциями, мы видим, что это прекрасно складывается, не так ли? Итак, у вас есть коллекция, затем у вас есть эти функции более высокого порядка, которые вы применяете, вы выполняете свои преобразования, пока не получите желаемый результат.</p><p>Очевидно, контейнер коллекции или объект коллекции для сбора, вместе с функциями более высокого порядка, дает нам эту возможность. Так что было бы довольно интересно сделать еще один шаг вперед и взглянуть на фундаментальные аспекты, которые позволяют нам поддерживать композиционность.</p><p>Потому что, если бы мы могли как бы вывести эти существенные аспекты, мы смогли бы создавать наши собственные структуры данных помимо коллекций, которые мы можем составлять.</p><h2>Теория категорий</h2><p>Что ж, и если вы попытаетесь достичь этого, то вот куда вы направляетесь, в область теории категорий. Что такое теория категорий? Теория категорий — это теория математических структур и их отношений. Мне нравится сравнивать ее с периодической таблицей Менделеева в физике, знаете, где у вас есть все атомы, и все атомы вы также можете объединить в молекулы, которые обладают определенными чертами и характеристиками.</p><p>И третья категория — это нечто похожее, но с логическими строительными блоками, которые вы можете комбинировать, пока не получите определенные характеристики. И, как вы можете видеть, это не высота, не холм, это гора. А в горах можно подняться очень высоко, но можно и упасть очень глубоко. Итак, это опасная зона, где внезапно появляются все эти модные слова. Ну, а почему это опасная зона?</p><p>Я думаю, во многом это потому, что терминология, используемая в категориальной теории, которая не обязательно имеет отношение к разработке программного обеспечения, просто используется в разработке программного обеспечения, потому что это хорошая область ее применения. Но эти термины действительно своего рода притянуты за уши.</p><p>&lt;...&gt;</p><h2>Контейнеры</h2><p>Хорошо, итак, когда я спросил в начале, кто слышал слово «монада», поднялось довольно много рук, но определенно не все, верно? Приятно то, что мы все используем монады, и даже на ежедневной основе.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/7e81dabd-0710-4338-beed-c67fc7c693dc.png" alt="" /></figure><p>Очевидно, вы используете его, сами того не подозревая. Мне нравится думать о монадах по-разному, и есть разные способы, этот способ помогает мне лучше всего — думать о них как о контейнерах. Что такое контейнер? Ну, контейнер — это то, что содержит предметы. Интересная особенность контейнеров в том, что у вас есть разные виды контейнеров. У вас есть герметичные контейнеры, у вас есть контейнеры с кондиционером, у вас есть безопасные контейнеры. Несмотря на то, что контейнеры содержат что-то общее, они все равно могут быть разной формы. Итак, что мы попытаемся сделать сейчас, так это взглянуть на контейнер коллекций. Коллекции также содержат элементы, верно?</p><p>И на что мы действительно смотрим, так это на то, что такая коллекция делает полезной с точки зрения композиции? Итак, не все эти функции высшего порядка, но с точки зрения компонуемости, каковы ключевые характеристики, которые делают это возможным? Хорошо, давайте начнем с первого шага. И все это довольно просто, вы можете быть удивлены.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/5211ee01-f4b9-4988-ad37-8796d10f7fef.png" alt="" /></figure><p>Вероятно, только при сочетании вещей они становятся немного сложнее. Итак, первый пример, который вы видите, — это то, что мы можем комбинировать коллекции. Когда у нас есть контейнер с элементами, и мы объединяем его с другим контейнером с элементами, мы получаем новый контейнер, содержащий все элементы предыдущих. И когда вы затем переходите к этой категории, горе, скала, тогда можно назвать это моноидом.</p><p>У монады есть две характеристики. Она может создавать пустую вещь. Вы можете создать пустой список, верно? И вы можете объединять списки. Но когда вы объединяете списки, вы не получаете как бы два контейнера. Нет, вы по-прежнему получаете один контейнер, который содержит события другого. И просто чтобы сделать это немного сложнее, в основном, комбинируемая часть называется полугруппой.</p><p>Но ладно, пока давайте просто придерживаться термина “монада” (я бы предпочел термин "комбинируемый"; тогда я бы вроде как понял, о да, вы комбинируете разные вещи).</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/436c6503-226f-4c6d-9447-7130fafc4317.png" alt="" /></figure><p>Итак, это первая характеристика. Вторая заключается в том, что вы можете преобразовывать элементы коллекции. У нас снова есть контейнер, содержащий элементы. Мы берем каждый элемент, применяем к нему определенную функцию, результатом чего затем будет новый контейнер с преобразованными элементами. И если у вас есть такая возможность, то объектам удается вызвать это функтором. Итак, когда у чего-то есть метод map, это функтор. «Сопоставимый» (mappable) для меня звучало бы более логичным.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/b7f72368-45c3-4ce2-86aa-d5b6c8dbbc6b.png" alt="" /></figure><p>Хорошо, тогда третий вопрос, который, вероятно, самый важный, самый запутанный, заключается в следующем. Давайте посмотрим на эти простые домены, у меня есть разработчик, у которого есть языки, и если я хочу знать все языки нескольких разработчиков, тогда, если я буду использовать map, я получу этот список списков, верно? Но, в конце концов, я просто хочу иметь список языков.</p><p>Итак, что я должен применить? Вот тут-то и появляется flatMap, так что же делает flatMap? Каждый элемент, который вы извлекаете из контейнера, снова преобразуется в контейнер, но результирующий контейнер как бы выравнивает (убирает) дополнительный контейнер, который мы добавили.</p><p>Все в порядке, вы получаете только один список с элементами. И если вы затем объедините характеристики, которые мы видели раньше, то есть моноид и функтор, в сочетании с flatMap, то та-да, вот и наша монада. Итак, я сказал, что монада — это комбинация моноида, который я сейчас называю комбинируемым, функтора, отображаемого аспекта и монады, я бы предпочел термин «компонуемый», потому что это то, что вы можете делать с этими вещами. Хорошая ли идея дать этому новую терминологию?</p><p>Честно говоря, я думаю, что это плохая идея. Поэтому я думаю, забудьте об этом, придерживайтесь моноидной строки и так далее. Но, ну, определенно, не помогло то, что они использовали такого рода терминологию. И также здесь, на самом деле, больше уровней абстракции. Моноид идёт от «применимый» (applicative) и так далее. Есть также небольшие нюансы, но пока давайте просто придерживаться этих трех. Итак, мы все знаем монады, верно?</p><h2>Монады (Monads)</h2><p>Потому что вы используете коллекции. И я уверен, что вы знаете больше монад. Например, optional. Что такое optional?</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/f85fd8ef-d45a-42d3-b542-2a9975c3bc4f.png" alt="" /></figure><p>Если вы попытаетесь определить, что делает монада, есть какое-то особое житейское определение, которое вы можете применить к ней. Которое выглядит следующим образом: «Опциональность моделирует эффект опциональности» («an optional models the effect of optionality»). Итак, эффект опциональности.</p><p>Это очень важная часть, и мы также увидим позже, что это слово будет повторяться. Итак, давайте посмотрим, является ли опциональный параметр монадой? Давайте проверим. Есть ли у нас пустой метод? Мы можем создать пустой опциональный параметр, который является числом, верно? Можем ли мы сопоставить наши значения?</p><p>Да, мы можем. Итак, если опциональный параметр содержит значение, мы можем сопоставить его. И если он пуст, он ничего не делает. Здесь вы видите эффект сопоставления.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/e5c54d69-b009-4e64-b40e-f2a0096f3b36.png" alt="" /></figure><p>Отличается от коллекции, но это все равно map с другим эффектом, то же самое верно и для flatMap, поэтому, если на flatMap я создам наши опции, я не получу опциональный набор опций (option of optionals), потому что один слой будет выровнен… Кто занимался Reactive программированием с фьючерсами, всеми этими абстракциями? Да, хорошо, круто, довольно много. Там тоже есть монады.</p><p>Что они делают? Ну, моноблок или реактивный блок моделирует эффект синхронности. Можем ли мы создать пустой?</p><p>Можем. Итак, как здесь появляется map? Что делает map? Здесь у нас есть некоторый API, который возвращает моноид (mono), и map в основном будет вызван, как только асинхронная обработка будет завершена, и мы получим значение «окей». Здесь вызывается map.</p><p>То же самое верно и для flatMap, поэтому, если я хочу последовательно вызывать реактивный блок, то есть сначала API 1, затем API 2, я должен использовать flatMap, потому что в противном случае я получил бы моноид из моноида. Итак, вы также видите здесь, что эффект map и flatMap полностью отличается от других монад, которые мы видели до сих пор, но это все равно map и flatMap.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/baaa7503-6dbb-4199-a581-e81815bc1437.png" alt="" /></figure><p>Так для чего же хороши эти контейнеры монад? Ну, все эти абстракции, я действительно думаю, что плохое в этом смысле уже произошло, так что вы не можете повернуть время вспять, но в основном это просто отпугнуло людей. Это недостаток. Но что вы получите, если пройдете через это, так это, ну, возможность компоновки. И поскольку мы знаем, что можем компоновать материал, что ж, давайте попробуем это.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/ceb04bd5-31e3-4786-9907-0d6637761b0b.png" alt="" /></figure><p>Давайте составим что-нибудь. И хорошим примером использования компонуемости может быть обработка ошибок. У вас здесь есть эти перехваты попыток, и, что ж, на самом деле это некомпонуемая конструкция, верно? Своего рода языковые функции, которые нельзя комбинировать. Просто они должны использоваться несвязанно, по-разному.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/1fc24de4-2ff8-425b-81fa-6a98c71aa483.png" alt="" /></figure><p>Ну, если мы хотим что-то скомпоновать, тогда нам нужна монада, и хорошей новостью является то, что в стандартной библиотеке Kotlin уже есть такая монада, которая называется result и выглядит результат. Result моделирует эффект наличия значения «окей» или исключения, и мы можем применить результат выглядит следующим образом: у него есть map и flatMap, так что, по-видимому, это монада. Это был код раньше, теперь мы используем runСatching в клиентском коде, который затем не вернет нашему разработчику результат либо хорошего значения, либо исключения, и с этого момента мы можем начать компоновать. Это довольно хороший вопрос, не так ли? Итак, у нас есть этот клиент GetDevByName. Откуда мы знаем, что можем ожидать исключения? Этого нет в подписи. Контракт не говорит мне, что есть исключение. И это очень интересная дискуссия, которая, в некотором смысле, то, что мы здесь видим, не является прозрачным.</p><p>Мы можем вернуть то, чего нет в нашем контракте. И функциональным людям это не нравится. Они считают, что прозрачность важна.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/7bbdd266-cb72-4176-bf0e-73e3704be027.png" alt="" /></figure><p>Напротив, довольно интересно, что в Kotlin есть только непроверямые (unchecked, те, которые не отлавливаются компилятором  — прим.переводчика) исключения. Так что, по-видимому, есть некоторые, да, и это немного не согласовано. Не будет рассуждать, хорошо это или плохо. Так что давайте просто продолжим исследование, и я думаю, тогда мы сами придем к выводу. Предположим, что мы хотим быть прозрачными. А если мы хотим быть прозрачными, тогда мы должны быть откровенны. Итак, мы должны четко отметить, что этот метод также может выдать вам исключение посредством результата. И что ж, это то, что мы должны сделать. Таким образом, все наши методы теперь относятся не к языку как к возвращаемому термину, а к результату языка. Тогда мы можем творить нашу композиционную магию. Хорошо, давайте расширим наш пример и используем третий вызов API.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/c8763e6e-a986-4d19-a3fe-f57b87a67fae.png" alt="" /></figure><p>И если мы попытаемся вызвать эти три API последовательно, сначала один, используя выходные данные в качестве входных данных, то в итоге мы получим вот такой код. Таким образом, задействовано много flatMaping. В начале я сказал, что бываю во многих местах, где обучаю разработчиков Kotlin, но объяснять это, особенно тому, у кого очень сильный опыт работы с императивами, довольно сложно. Я имею в виду, что коллекции плоских отображений уже немного сложно. Но контекст flatMaping отличается от контекста других структур? Я имею в виду, это не так уж сложно, но все равно, ощущения не очень приятные.</p><p>Итак, вопрос, конечно, в том, есть ли способ лучше? Я думаю, сейчас тот момент, когда я представляю вам Arrow.</p><p>Что такое Arrow? Arrow — это действительно красиво созданный API, который фактически реализует всю эту теорию, категорию, парадигму, а также предлагает большое разнообразие монад. Я действительно считаю это жемчужиной, что не всегда было так, потому что вначале это был порт из Scala. В Scala есть этот материал в большем количестве, довольно много библиотек доходят до крайности с такого рода концепциями, и они были перенесены на Kotlin. Самая первая версия была как бы не связана с идиоматическим Kotlin. У вас был Kotlin, а затем у вас был этот функциональный мир, и вам действительно приходилось выбирать между одним и другим.</p><p>Они не очень хорошо сочетались. И действительно, самое замечательное в том, что сделала Arrow, особенно в релизе, который вышел сейчас, 2.0, заключается в том, что им удалось действительно блестящим образом соединить два мира, так что большая сложность, которая обычно бросалась бы вам в глаза, исчезла, и вы действительно можете воспользоваться преимуществами. Я приведу несколько примеров этого. Итак, в основе Arrow лежит эффект. Если вы помните, мы всегда говорили, что опциональная модель — это эффект чего-либо.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/b3929c5a-8610-4a33-98ae-bcbfec7e973c.png" alt="" /></figure><p>Эффект — это основная вещь, и затем у вас есть монады, которые реализуют определенный эффект, например опциональный. Результат также преобразуется в эффект. У вас также есть either, вы, возможно, слышали об этом типе, either немного мощнее, чем result. Result может содержать только хорошее значение и исключение. Either просто может содержать два значения, может содержать одно значение разной формы. Таким образом, он может иметь значение типа A или значение типа B, и только по одному за раз.</p><p>Обычно правое ассоциируется с хорошим результатом, а левое — с плохим, но это не обязательно так, но часто это применяется именно таким образом. Есть validated, где вы можете выполнить некоторую накопленную проверку &lt;...&gt;. Хорошо, что Arrow также предлагает очень классную функцию, которая называется monad comprehensions. С ней мы можем работать лучше, чем с помощью flatMap.</p><h2>Monad comprehensions</h2><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/37627c63-521a-41f7-9545-afa627b9f03f.png" alt="" /></figure><p>Как это работает? Что важно упомянуть, так это то, что монопонимание — это нечто из функциональных языков, а у функциональных языков для этого есть языковые особенности. В Kotlin нет языковой функции для монокомпонентов, но в Kotlin есть эта функция, литерал которой связан с receiver, верно? Это то, что вы видите здесь, result, и тогда receiver в этом случае будет такой областью действия result, которая для вас как бы скрыта. Но у этого есть некоторые методы расширения, которые являются bind, и этот метод bind затем может вызывать монады внутри вашего блока кода. Итак, здесь вызов bind и то, что делает bind, — это либо дает вам значение, если вы вычисляете правильное значение, и если это было бы исключением, оно просто провалилось бы и просто вернуло результат, содержащий исключение.</p><p>Таким образом, вычисления сразу же прекратились бы. Таким образом, вам не нужна эта вложенность в flatMap для достижения вашей цели. Это действительно блестящий способ по-прежнему использовать потенциал этих монад, но при этом не быть обремененным flatMapping. Я думаю, что это отличный подход.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/1c05be77-3aed-47e9-998c-19e0001ebe06.png" alt="" /></figure><p>Более того, и это также то, что они вам скажут, так что это краткий обзор, заключается в том, что с появлением этих контекстных приемников вы даже можете сделать эти сигнатуры методов еще более совместимыми с идиоматикой Kotlin, в том смысле, что теперь они определяют только базовый возврат потока тип, поэтому языковая статистика и другие эффекты, которые я мог бы получить, как бы четко отделены от, ну, базового типа, использующего эти контекстные приемники. Я также думаю, что здесь это отличный способ быть откровенным, но не так, чтобы это слишком сильно мешало вам. Так что это определенно потрясающая разработка. Ладно, теперь я думаю, что эта компонуемость потрясающая.</p><p>Итак, давайте просто используем все, что можем. И поскольку мой вариант использования требует только более одной монады, почему бы просто не объединить эти вещи вместе? Потому что мне, во-первых, нужно какое-то реактивное поведение. Во-вторых, я хочу, чтобы код был прозрачным. И в-третьих, почему бы не использовать option?</p><p>Итак, вы получаете эти вложенные контейнеры. Если бы вы тогда только попытались вызвать эти три службы последовательно, это то, что у вас получилось бы в итоге.</p><h2>Проблемы...</h2><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/389ec14f-1fb5-4217-897a-40078b2348a5.png" alt="" /></figure><p>И вы можете себе представить, что теперь мы только что ввели небольшую головную боль при обслуживании. Итак, все map и flatMap, которые мы видим здесь, вызываются одинаково, но я сказал, что эффект на самом деле разный. FlatMap монад отличается от map из result, отличается от map из optional, но это все map и flatMap. Это то, что вы видите.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/2aab6daa-f935-4fbb-8bb8-96e9ae9f5ae2.png" alt="" /></figure><p>Так что все не так уж и здорово. Ну да, вы еще не занимались бизнес-логикой, и если вы обнаружите, что пишете такой код, тогда я могу поздравить вас, потому что вам удалось превратить свою кодовую базу в контейнерный терминал, и если вы внимательно посмотрите, где вы находитесь, то это здесь, у этого крана, и вы просто перемещаетесь вокруг этих контейнеров и пытаетесь найти [что-то], заворачивайте и разворачивайте их, чтобы добраться до того, что вам нужно. Потому что в основном мы программируем обеспечение, которое создаем, что действительно интересно — это то, что находится внутри контейнеров, а не сам контейнер. И это именно то, что у меня много раз было со Scala, и я действительно знаю, что у многих других было то же самое, что… Это очень неприятное чувство в том смысле, что я хочу создать бизнес-логику для выполнения моих вариантов использования, но я всегда борюсь только с упаковкой, распаковкой, заглядыванием в эти контейнеры. Итак, мы только что видели, что у вас есть эти представления о монадах, возможно, они и здесь могут помочь.</p><h2>... и их решение</h2><p>Извините, плохие новости. Понимание монад работает только для одного уровня монады. Так что, если у вас есть вложенные монады, это не сработает. Как насчет трансформаторов монад? Что такое трансформаторы монад? Это снова своего рода грязный трюк для преобразования значения внутренней монады во внешнюю. Итак, вместо того, чтобы вызывать map, flatMap, теперь вы можете вызвать mapT. И тогда вы преобразовали бы комбинацию mono result напрямую в convert result. Ну, это работает только для двух уровней.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/35849873-bc84-4de5-8fc2-415d38d8dc6c.png" alt="" /></figure><p>У нас их три, верно? И вы все равно не можете использовать для этого что-то более всеобъемлющее. И поверьте мне, если вы пойдете по этому пути, то получите такого рода методы: mapТ, mapТ, mapТ, внешняя flatMap, внутренняя. Я написал такой код.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/3072db9a-c4e5-4680-99fa-d319956ef5fd.png" alt="" /></figure><p>Как только это было сделано и мой тест сработал, на следующий день код перестал работать, не говоря уже о том, что мои коллеги не поняли, что происходит. Это действительно не то, что вы хотели бы получить. Итак, совсем не весело. Хорошо, значит, монада совсем не хороша? Что ж, если вы ограничитесь одной монадой, я думаю, у вас все будет в порядке.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/98aec687-0046-4fb9-861a-d3ce3ccd6eb8.png" alt="" /></figure><p>Но как я могу свести три к одному? Итак, давайте попробуем. Я видел, как некоторые из вас все еще поднимают руки, которые использовали эти реактивные строительные блоки. Кто их использует до сих пор? Хорошо, не многие. Я думаю, это хорошо, потому что, если вы это сделаете, я действительно настоятельно советую вам взглянуть на со-программы. Они могут значительно облегчить вашу жизнь, но при этом дают вам точно такие же характеристики, которые вы получаете с помощью этих реактивных строительных блоков.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/cf5a2d1d-6b21-4b42-a9a8-97b5e9ea6f10.png" alt="" /></figure><p>Так что настоятельно рекомендую обратить на них внимание. Итак, мы преобразуем их в spend и можем выбросить наш mono. Второй, ну, вариант. Я думаю, у нас уже есть эта конструкция в Kotlin, верно, которая является nullability. Зачем вводить другой тип конструкции для использования возможности обнуления? Вы же не собираетесь использовать необязательный параметр Java в своем коде, верно?</p><p>Во всяком случае я не советую вам так делать. Просто придерживайтесь одной концепции опциональности, которая в Kotlin ещё и nullability, и все. Хорошо, и как только мы это сделаем, я думаю, наш код снова станет в некотором роде управляемым. И если вы используете let или если вы затем используете другие гласные, которым вы присваиваете свои результаты, это зависит от вас. Но тогда с пониманием результата, комбинацией с методами привязки и приостановки, возможностью обнуления лучше подойдёт. Ладно, я думаю, теперь мы прошли через этот монадический туман, просто взглянули на вершину.</p><p>Если бы я остановился прямо сейчас, я думаю, мы все равно были бы не очень довольны, верно? Должен же быть какой-то синтез целого. Итак, давайте попробуем, если у вас получится лучше. Что на самом деле подводит нас к следующему вопросу: какая монада хороша для вашего кода? Что подводит нас к более широкому вопросу: что такое хороший код?</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/14818146-09db-4c24-be97-0f8ee3fc8405.png" alt="" /></figure><p>Что ж, об этом написано много книг, и еще много книг будет написано на эту тему. Мне хотелось бы, чтобы все было довольно просто. Пока что я видел, что хороший код отражает область, в которой вы находитесь. Итак, если вы зоомагазин, то речь идет о кошках, собаках, собачьем корме. Если вы финансовое учреждение, то речь идет об ипотеке, акциях и так далее. Другими словами, недоменные абстракции, которые вы используете в своем коде, на самом деле не выходят за пределы вашего домена, являются частью абстракций. И если у вас есть эти недоменные абстракции, что ж, тогда они действительно служат очень специфической, полезной службе. Другими словами, если ваш заказчик просматривает ваш код и понимает его, это то, что я считаю хорошей основой для создания кода, который будет поддерживаться многими поколениями, которые придут после вас. Другими словами, если ваш код выглядит как контейнерный терминал, это явно не очень хороший код.</p><p>За исключением случаев, когда ваша компания является контейнерным терминалом, верно? Тогда можно называть вещи «контейнерами» и менять их местами. Итак, теперь то, что я хотел бы сделать, это как бы дать вам представление о том, что произойдет, если вы просто добавите монады ко всему. Как это повлияет на цепочку вызовов вашего приложения.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/a289edf7-a442-44da-96d7-c109fc1d9acb.png" alt="" /></figure><p>Используя очень простое приложение, так что никаких причудливых шестиугольников, но и там вы получили бы более или менее тот же эффект. Итак, у вас есть некоторый уровень доступа к данным, затем у нас есть некоторый уровень обслуживания, некоторый уровень API, я предполагаю, что обычно используется Spring Boot, и затем, ну, вам нужно обработать некоторые исключения. И что мы видим здесь, в данном конкретном случае, так это то, что мы откровенны, правы, прозрачны, мы передаем эти результаты, потому что хотим быть откровенными и прозрачными, но делаем ли мы что-то с этой прозрачностью?</p><p>Нет. Что вы делаете, так это в контроллерегенерируем исключение, чтобы наш обработчик исключений мог обработать его и вернуть ответ REST. Возможно, это могло бы вернуть результат в нашем контроллере. Да, мы могли бы заставить это работать, но мы ничего с этим не делаем. Итак, что ж, если в 95% случаев вы все равно их не используете, я обнаружил, что, обратившись к Scala, где мы действительно довели это до крайности, это просто работает лучше.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/bfbf4bf7-106b-4830-93de-843a1850dfdd.png" alt="" /></figure><p>И да, это не совсем чистый метод, но он работает лучше. И, конечно, у вас есть остальные 5%. Я думаю, это интересный случай. Итак, мы рассмотрим наши примеры, которые у нас есть.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/390fa31f-0df7-430a-94fc-d686e1ffff43.png" alt="" /></figure><p>Итак, у нас есть наши основные потоки. Затем у нас есть определенные исключения, например, вы не можете получить доступ к своей базе данных. В любом случае, вы не сможете восстановиться после этого. Просто выбросьте его и верните свой ответ об ошибке. Но есть случаи, в основном в API, когда в зависимости от определенной ошибки API мы хотим восстановить ее в нашем сервисе.</p><p>И здесь действительно имеет смысл быть откровенным. Итак, в зависимости от того, что мы получаем , и мы могли бы использовать хороший floor или eternity flow, так что это означает , что для работы с базой данных я бы действительно не стал оборачивать это в монады, просто верните ему сущности, достаточно хороший API сказал, что в зависимости от того, что вы хотите сделать, я бы не стал использовать result кстати, я бы предпочел использовать либо потому что результат в случае, если у вас есть исключения, вам нужно было бы как бы извлечь исключения, чтобы внедрить их в свой бизнес-процесс для принятия других решений, которые в исключительных случаях не принимаются, верно? Поток управления, основанный на исключениях, немного противоречит шаблону. Но с помощью IDER мы можем просто определить тип ошибки, который может быть закрытым интерфейсом с некоторыми классами данных, и тогда мы сможем довольно легко обработать левую часть нашего IDER. Таким образом, поступая таким образом, мы получаем два преимущества.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/39607d9d-cb99-47bc-b3c6-a0fdd2af38a5.png" alt="" /></figure><p>Прежде всего, мы получаем явный контракт. Мы видим, о да, мы можем вернуть именно эти ошибки. И у нас также есть эти операторы для обработки случая, когда мы получаем ошибку, так что мы можем довольно легко восстановить. И если все же произойдет что-то еще, что нас не волнует, выбросьте и позвольте универсальной обработке исключений просто выполнять свою работу. Итак, ключевая мысль здесь заключается в том, что если вы используете монады выборочно, то они действительно великолепны.</p><p>Итак, два примера, прежде чем мы подведем итог. Вот, например, проблема, с которой я тоже сталкиваюсь довольно часто. Чтобы создать какие-то объекты, вы должны проверить их на возможность nullability.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/6f03ded7-d410-4d68-afee-021342a05f94.png" alt="" /></figure><p>Для различных переменных, прежде чем вы передадите их, в противном случае вы не сможете создать такую переменную Kotlin, потому что значения, которые она принимает, не являются null, это довольно утомительно, также здесь у Arrow есть отличная функция, которая заключается в понимании монады с нулевым значением, поэтому в Arrow типы с нулевым значением также считаются монадой, так что вы можете используйте это понимание, а затем вместо использования if-else просто использовать bind, и если одно из этих значений вернет null, то, что ж, весь результат будет null. Итак, я думаю, что это отличное дополнение к вашему коду, позволяющее предотвратить множество конструкций if-else. Еще одна прекрасная вещь — это решение этой конкретной проблемы.</p><figure><img src="https://media.tproger.ru/user-uploads/88534/2024-03-11/51ef84c5-880d-4ecb-a6c6-5dcb38d16e66.png" alt="" /></figure><p>Итак, если у вас глубоко вложенные структуры данных и вы хотите что-то изменить на конечном уровне, и, конечно, мы предполагаем неизменяемые структуры данных, то это довольно утомительная задача — добраться до конечного уровня и преобразовать его, верно? Вы должны копировать, копировать, копировать. На различных конференциях я видел ужасные решения для этого, чрезвычайно сложные с компоновщиками и большим количеством кодирования только для решения этой проблемы. Также здесь Arrow использует так называемую оптику (optics).</p><p>Oxygen также основан на всех этих функциональных концепциях, и они действительно проделывают огромную работу, чтобы решить именно эту конкретную проблему. Таким образом, вы можете просмотреть график с тем, что вы видите в начале, затем вызвать modify, передать конкретный экземпляр, а затем скопировать только тот уровень, который вы хотите скопировать. Это может быть на каждом уровне иерархии вашей структуры данных. Это не то, что вы можете использовать просто так. Для этого вам нужно настроить плагин компилятора, потому что необходимо сгенерировать некоторый код.</p><p>[42:54] Вам также нужно аннотировать свои классы. Но это определенно стоит хлопот, если вы делаете это много раз в своем домене. Это действительно того стоит. Хорошо, итак, я сказал, что как только мы сможем не использовать монады в качестве золотого молотка, бросать его во все подряд, чтобы все наши цепочки вызовов были как бы загрязнены монадами, я думаю, что именно здесь мы достигли пользы функционального здравого смысла. Итак, где вы можете выбрать лучшее и просто пропустить остальное.</p>]]></content:encoded>
    </item>
    <item>
      <title>Стартер-пак Android-разработчика: что учить</title>
      <link>https://tproger.ru/articles/starter-pak-android-razrabotchika--chto-uchit</link>
      <comments>https://tproger.ru/articles/starter-pak-android-razrabotchika--chto-uchit?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/starter-pak-android-razrabotchika--chto-uchit</guid>
      <description><![CDATA[<p>Узнали у middle и senior разработчиков, что нужно учить каждому Android-разработчику, какие фреймворки, библиотеки и инструменты устарели, а какие актуальны.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/starter-pak-android-razrabotchika--chto-uchit">Стартер-пак Android-разработчика: что учить</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 22 Feb 2024 13:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Узнали у middle и senior разработчиков, что нужно учить каждому Android-разработчику. Спросили, какие фреймворки, библиотеки и инструменты безнадёжно устарели, а какие невероятно актуальны.</p><p>Напоминаем, что вы можете задать свой вопрос экспертам, а мы соберём на него ответы, если он окажется интересным. Вопросы, которые уже задавались, можно найти в списке выпусков рубрики.</p><p>Если вы хотите присоединиться к числу экспертов и прислать ответ от вашей компании или лично от вас, то пишите на <a>experts@tproger.ru</a>, мы расскажем, как это сделать.</p><h2>Какие библиотеки, инструменты, фреймворки Android уже устарели?</h2><p>Андроид развивается очень динамично, поэтому, многое из того, что было популярно 5 лет назад уже не используется. Конечно же сразу приходит на ум RxJava, про нее был каждый второй доклад на любой конференции 5-6 лет назад. А теперь ее изредка спрашивают на собеседованиях. На замену ей пришли Kotlin Coroutines.</p><p>Java как язык разработки под андроид остался, наверное, только в каких-то старых проектах динозаврах. Kotlin это новый стандарт уже лет 6.</p><p>С появлением Jetpack Compose UI код использующий стандартные Android Views стал легаси. Многие приложения сейчас Compose First, и все новые фичи тоже разрабатываются на Compose.</p><p>Архитектура презентационного слоя так же изменилась, всё меньше можно увидеть MVP, а MVVP и MVI стали де факто стандартами разработки.</p><h2>Какие библиотеки Android нужно знать в 2024 году?</h2><p>Если мы возьмем более менее стандартное приложение со стандартными подходами, то наверняка там будут эти библиотеки: Retrofit 2, Dagger2/Hilt, Kotlin Coroutines, Jetpack ViewModel, Room, Lifecycle. Но стоит помнить, что библиотеки приходят и уходят, а фундаментальные знания остаются. Человеку, освоившему фундамент будет гораздо легче освоить какую-либо библиотеку.</p><h2>Какие фреймворки Android нужно знать в 2024 году?</h2><p>В Андроид немного фреймворков, наверное главный и самый нашумевший в последнее время это Jetpack Compose. Так же стоит знать архитектурные подходы MVI/MVVM, MVP, плюсы и минусы их работы. Так же неплохо было бы понимать базовые вещи, которые могут не относится только к Android, например SOLID, Dependency Injection.</p><h2>Какие инструменты Android нужно знать в 2024 году?</h2><p>Швейцарский нож Android разработчика в 2024 это Kotlin, Kotlin Coroutines, Jetpack Compose, MVVM/MVI, Google Jetpack Libraries, REST, Single Activity, Dagger 2, Retrofit 2. Зная этот стек можно будет легко разобраться в 95% приложений.</p><h2>Что уже устарело</h2><h3>Язык разработки Java для Android</h3><p>Современный подход к разработке под Android является Kotlin-first. Это означает, что Kotlin является основным языком для разработки приложений. Также уже несколько лет все нативные библиотеки для самых различных целей и задач пишутся преимущественно на Kotlin. Поэтому будет полезнее направить усилия по изучению данного языка вместо Java. Java вы всегда успеете выучить при необходимости, чтобы лучше понимать подкапотный мир JVM, общий с Kotlin.</p><p>Расхожее мнение, что с появлением Jetpack Compose учить разработку View на Xml становится неактуально. Тут все неоднозначно. Несмотря на нарастающую популярность Compose, все еще много проектов, где UI реализуется преимущественно на классическом подходе (View + Xml), а переезд на новую технологию по каким-то причинам не так приоритетен.</p><h3>RxJava</h3><p>Использование реактивного подхода было весьма популярно еще буквально несколько лет назад. С помощью фреймворков типа RxJava решали вопрос и компактности кода, и реализации асинхронной разработки. Сейчас фокус сместился в сторону Kotlin Coroutines. Это является актуальным и рекомендованным решением для многопоточной разработки.</p><p>Также к устаревшим технологиям относятся DataBinding для связи верстки и бизнес-логики, KAPT для обработки аннотаций. Редко уже используется SqLite ORM.</p><p>В целом, большинство устаревших решений никуда не уходят. Просто появляются новые библиотеки-обертки, делающие работу с ними и их освоение более удобным.</p><p>Какие библиотеки нужно знать в 2024 году</p><p>Must-havе любого разработчика Android - это семейство библиотек Jetpack Components:</p><ul><li>ViewModels (это не только ViewModels для MVVM, но и в целом рекомендованный компонент для вызова бизнес-логики и хранения состояния),</li><li>Lifecycle,</li><li>Navigation</li><li>Room ORM (для локального хранилища).</li></ul><p>Для сети продолжает оставаться актуальным использование Retrofit. В качестве альтернативы можно порекомендовать Ktor.</p><p>Очень полезным будет знание Kotlin Coroutines, Kotlin Flows. Для организации фоновой работы будет полезно знание такого механизма как WorkManager.</p><p>Для построения корректной архитектуры приложения необходимо знание 1-2 библиотек для Dependency Injection. Актуальным будет знание Dagger/Hilt, дополнительно можно освоить Koin и Kodein.</p><h2>Какие фреймворки нужно знать</h2><p>Конечно, Android SDK и Jetpack Compose. С первым все понятно - это база по Android. Декларативные подходе к разработке приложений в принципе актуальны последние несколько лет, т.к упрощают и ускоряют процесс. После выхода первой стабильной версии Compose, несмотря на необходимость доработок, компания Google сделала ставку на данную технологию. Практически все туториалы и гайды по работе с UI ориентированы теперь и на Compose. Какие-то решения уже идут Compose-First. Например, Google добавили в фреймворку поддержку различных классных анимаций.</p><p>Философия Jetpack Compose - это не только UI, но и управление состоянием приложения, связь элементов с бизнес-логикой, поддержка навигации и т.п</p><h2>Какие инструменты нужно знать</h2><p>Основным инструментом разработки под Android является Android Studio. Это доступная и бесплатная среда разработки, которую можно установить на любую операционную систему. Помимо тулинга для разработки, дебага и сборки приложения, IDE содержит инструменты для профилировки приложения. Очень важно знать Gradle как систему управления зависимостями и сборкой приложения.</p><p>Эрудированному разработчику Android в 2024 году полезно знать набор Jetpack Components, Jetpack Compose, Kotlin Coroutines, Retrofit, Dagger/Hilt. Обязательно владение Android SDK и Kotlin, знание паттернов и архитектур, понимание принципов SOLID и ООП.</p><p>Напоминаем, что вы можете задать свой вопрос экспертам, а мы соберём на него ответы, если он окажется интересным. Вопросы, которые уже задавались, можно найти в списке выпусков рубрики.

Если вы хотите присоединиться к числу экспертов и прислать ответ от вашей компании или лично от вас, то пишите на experts@tproger.ru, мы расскажем, как это сделать.</p>]]></content:encoded>
    </item>
    <item>
      <title>«Приключение космического барахольщика» — квест по Swift и Kotlin от Tproger x Авиасейлс</title>
      <link>https://tproger.ru/interactive/quest-tproger-x-aviasales</link>
      <comments>https://tproger.ru/interactive/quest-tproger-x-aviasales?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Чуватова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/interactive/quest-tproger-x-aviasales</guid>
      <description><![CDATA[<p>Пройдите космический квест и разгадайте тайну коробочки в квесте от Авиасейлс и Tproger.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/interactive/quest-tproger-x-aviasales">«Приключение космического барахольщика» — квест по Swift и Kotlin от Tproger x Авиасейлс</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Партнёрский материал]]></category>
      <category><![CDATA[Игры]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 19 Feb 2024 15:38:23 GMT</pubDate>
    </item>
    <item>
      <title>Газпромбанк разработал технологическую платформу для создания клиентских сервисов</title>
      <link>https://tproger.ru/news/gazprombank-razrabotal-tehnologicheskuyu-platformu-dlya-sozdaniya-klientskih-servisov-249162</link>
      <comments>https://tproger.ru/news/gazprombank-razrabotal-tehnologicheskuyu-platformu-dlya-sozdaniya-klientskih-servisov-249162?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вика Овсянникова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/gazprombank-razrabotal-tehnologicheskuyu-platformu-dlya-sozdaniya-klientskih-servisov-249162</guid>
      <description><![CDATA[<p>Для чего нужна и что можно делать с помощью платформы G2 для клиентских сервисов и автоматизированных систем.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/gazprombank-razrabotal-tehnologicheskuyu-platformu-dlya-sozdaniya-klientskih-servisov-249162">Газпромбанк разработал технологическую платформу для создания клиентских сервисов</a>»</p>]]></description>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Новости компаний]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 31 Jan 2024 07:30:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Газпромбанк запустил технологическую платформу G2 для клиентских сервисов и автоматизированных систем. Разработка позволит отказаться от ПО поставщиков, ушедших с российского рынка.</p><p>Приложения на Платформе G2 способны заменить программное обеспечение поставщиков, ушедших с российского рынка. Задача импортозамещения решается благодаря использованию опенсорсных компонентов технологического стека с поддержкой от отечественных компаний, в частности СУБД PostgreSQL.</p><p>Платформа предоставляет разработчику набор эффективных концепций с их программной поддержкой и представляет из себя набор библиотек и инструментов разработчика на языках Kotlin и TypeScript.</p><p>Использование платформы G2 позволяет:</p><ul><li>сократить время разработки новых систем в два и более раза,</li><li>уменьшить количество задействованных разработчиков,</li><li>стандартизировать архитектуру приложений.</li></ul><p>В Газпромбанке проводят импортозамещение ключевых банковских систем за счет собственной разработки. Новая платформа станет важным элементом инфраструктуры, так как с ее помощью можно быстро автоматизировать деятельность банков и корпораций, разрабатывая приложения и дистанционные сервисы в виде web-приложений. В настоящее время на ней создано два промышленных приложения для банка и его дочерних компаний, и еще два находятся в активной фазе разработки.</p><p>Платформа G2 включена в реестр российского ПО, в этом году планируется выпустить продукт на рынок.</p><blockquote>Сейчас перед всеми крупными компаниями стоит глобальная задача – перевести ключевые процессы на российское ПО. Мы решили пойти по пути создания собственной платформы, которая позволяет быстро собирать новые системы из готовых элементов. При разработке G2 мы учли недостатки других платформ и постарались их исправить в нашем продукте. У нас получился удобный и эффективный инструмент для разработчиков, который мы готовы предложить рынку. Решение могут использовать любые организации: корпорации и другие предприятия, финансовые организации, ИТ интеграторы и разработчики ПО, чтобы обеспечить безопасность и независимость своих ИТ-систем.</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Тренды в мобильной разработке в 2024 году</title>
      <link>https://tproger.ru/articles/trendy-v-mobilnoj-razrabotke-v-2024-godu</link>
      <comments>https://tproger.ru/articles/trendy-v-mobilnoj-razrabotke-v-2024-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Юлия Волощенко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/trendy-v-mobilnoj-razrabotke-v-2024-godu</guid>
      <description><![CDATA[<p>Рассказали, что в мобильной разработке будет популярно в 2024 году и на какие технологии стоит делать ставку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/trendy-v-mobilnoj-razrabotke-v-2024-godu">Тренды в мобильной разработке в 2024 году</a>»</p>]]></description>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 22 Jan 2024 13:40:01 GMT</pubDate>
      <content:encoded><![CDATA[<p>2023 год принес много нового, интересного и даже неожиданного для мобильной разработки. Это и версии уже известных языков разработки, и популярных библиотек, так и совершенно новые направления, инструменты и технологии.</p><p>Подробнее, что же будет популярно в 2024 году, на какие технологии стоит делать ставку, расскажет Анна Жаркова, руководитель группы разработки компании Usetech, мобильный разработчик с опытом более 10 лет, эксперт Mobile Broadcast и Skillbox, а также член программных комитетов Mobius, Codefest и DevFest (Омск).</p><h2>Искусственный интеллект</h2><p>Начнем мы с самого популярного и многообещающего направления, а именно с использования систем Искусственного Интеллекта. <a href="https://www.mckinsey.com/mgi/overview/in-the-news/ai-could-increase-corporate-profits-by-4-trillion-a-year-according-to-new-research">McKinsey Global Institute</a> пишут о возможном увеличении прибыли компаний на $4,4 триллиона в год благодаря ИИ. Кроме того, бизнес чаще начинает внедрять генеративный ИИ в повседневные приложения.</p><p>Технологии ML давно используются в мобильной разработке. Это и различные библиотеки для распознавания и поиска изображений, сканирования и распознавания текста, работы с видео, звуком. И встроенные возможности софта для разработки приложений, которые помогают делать код лучше, бороться с утечками памяти и т.п. Та же самая технология FaceId использует в своей основе инструментарий ML.</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2024-01-22/120ae242-520c-4962-9905-bbc5fbc21239.png" alt="" /><figcaption>Источник: https://vilmate.com/blog/how-to-use-machine-learning-in-mobile-apps/</figcaption></figure><p>С конца 2022 года отмечается настоящий всплеск по разработке систем ИИ. На данный момент нейросеть ChatGPT занимает первую строчку в рейтинге технологий генеративного ИИ. В российском сегменте нельзя не отметить мощный аналог от компании Яндекс Yandex GPT. Компании планируют активно встраивать решения на основе нейросетей в свои приложения. Это может быть не только сбор и обработка информации для улучшения пользовательского опыта. Например, сбор и анализ информации позволит строить модели поведения пользователей, сценарии, на основе которых улучшать подбор рекомендуемого контента и т.п. Также это решение различных генеративных задач. Например, автоматический перевод текста, умное взаимодействие с пользователем.</p><p>В плане самой разработки ИИ может быть использован для генерации и оптимизации кода. Много споров вызывают такие вопросы, как: насколько качественные решения будут создавать системы ИИ, а также насколько безопасно использовать их для анализа кода приложений. Но перспектива использования таких решений, тенденция к их развитию, определенно, есть.</p><h2>Кроссплатформа, Kotlin Multiplatform, Flutter</h2><p>Технологии кроссплатформенной мобильной разработки под несколько платформ одновременно популярны уже довольно давно. На текущий момент самыми используемыми являются SDK Kotlin Multiplatform (KMP) от JetBrains и Flutter от Google. Оба решения активно развиваются, и без сомнения, в 2024 году порадуют новыми решениями. Кстати, JetBrains проводит ежегодный опрос по использованию Kotlin, который доступен по <a href="https://www.jetbrains.com/lp/devecosystem-2023/kotlin/">ссылке</a>.</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2024-01-22/3c05c91a-b183-465b-97ea-ee28745567e9.png" alt="" /><figcaption>Источник: https://www.jetbrains.com/lp/devecosystem-2023/kotlin/</figcaption></figure><p>Осенью 2023 года произошло то, чего ждали многие разработчики и почитатели технологии KMP. Технология перешла в статус Stable и стала полностью готова к полноценному использованию. Это означает, что многие, актуальные для Alfa и Beta версий SDK проблемы, были решены. Например, улучшили поддержку Kotlin/Native, работу с многопоточностью, памятью и т.п. Одной из целей роадмапа на 2024 год сформулировали реализацию прямого взаимодействия между языками Kotlin и Swift. Несмотря на то, что разработчики Google являются авторами конкурирующего продукта Flutter, компания официально делает большую ставку на KMP. Поддержка кросс-платформы включается во многие решения. Так что советуем присмотреться к данному продукту.</p><p>Еще одним трендом связанным с кроссплатформенной разработкой является использование Compose Multiplatform для реализации кросс-платформенного UI. Данный декларативный фреймворк объединяет такие технологии как Compose for Desktop, Compose iOS, Compose for Web, а также Jetpack Compose для Android, и позволяет быстро и относительно просто создавать общий UI для разных платформ. В 2023 году вышла альфа-версия Compose для iOS. В 2024 году ожидается выход Бета-версии, в которую войдут улучшения по работе с нативным UI iOS, а также поддержка кросс-платформенного решения для навигации.</p><p>В общемировых тенденциях мобильной разработки сохраняется популярность таких решений, как React Native, гибридной разработки на Cordova и ionic, а также Xamarin. Также сохраняется тренд на PWA разработку,</p><h2>Российская разработка, импортозамещение</h2><p>Еще в 2022 году возникла потребность в собственных решениях для импортозамещения, а также развития отечественных технологий. Одним из самых актуальных направлений мобильной разработки становится разработка под Aurora OS. Если сначала попробовать устройства под ее управлением могли в основном участники специальной бета-программы и энтузиасты, помогающие компании OMP в разработке и улучшении продукта, то уже осенью 2023 года смартфоны и планшеты на Aurora OS становятся доступны для приобретения для всех желающих. Готовится к выходу 5 версия OS  с поддержкой встроенного магазин приложений на RuStore. Многие российские компании уже работают над своими собственными решениями с поддержкой Aurora OS.</p><p>Компания OMP также обновили и улучшили инструменты для разработчиков. Предлагается использовать не только QT/QML/C++, но и специальную версию Flutter для разработки под Aurora. Так что здесь стоит отметить сочетание двух трендов мобильной разработки.</p><p>Определенно, стоит уделить внимание платформе <a href="https://mobile.rosa.ru/">Rosa Mobile</a>. Данная ОС была заявлена как замена Android, и освоить разработку приложений под нее, было бы весьма нелишним.</p><p>Также актуальным трендом остается переход на отечественные сервисы. Например, решения от Yandex для сбора метрик, карты, погода и другие SDK. Замена сервисов Firebase <a href="https://www.rustore.ru/help/">сервисами RuStore</a> (те же пуш-уведомления).</p><h2>Нативная разработка</h2><p>Технологии и фреймворки меняются, нативная разработка остается. Это основа основ, база, которую должен знать каждый разработчик. Использование родных языков и инструментов, как и подхода Native First, будет актуально всегда. К тому же для реализации проектов со сложной логикой, сложным UI, стоит выбирать именно нативную разработку.</p><p>Ежегодно разработчики платформ iOS/Android, а также языков Swift и Kotlin, выпускают много новых и интересных решений, про которые рассказывают на тематических конференциях WWDC и Google I/O.</p><p>Особое внимание стоит уделить усиливающемуся тренду на декларативную разработку в мобильных приложениях. Фреймворки SwiftUI и Jetpack Compose активно развиваются, стабильно улучшаются, становятся более удобными и надежными в работе. Их все чаще используют в разработке приложений различной сложности. Много библиотек и готовых решений, заточенных под SwiftUI и Jetpack Compose. Можно сказать, что это новый стандарт мобильной разработки под Android и iOS.</p><p>Также стоит обратить внимание на дополнение мобильных приложений <a href="https://developer.apple.com/videos/play/wwdc2023/10028/">интерактивными виджетами</a>, которые помогут привлечь внимание к приложениям и предоставить мгновенный доступ к ряду функций.</p><h2>Виртуальная реальность</h2><p>В 2023 году на конференции WWDC компания Apple представила одну из самых громких новинок — очки виртуальной реальности Vision Pro, работающие на платформе <a href="https://developer.apple.com/visionos/">VisionOS</a>.  Разумеется, это далеко не самый первый такой девайс в мире, и подобные аппараты уже давно используются в игровой индустрии. Ставка делается на уникальные технологии иммерсивности, улучшенное качество звука и изображения. В рамках создания девайса были проведены масштабные разработки в области пространственных вычислений. Поддержка VisionOS была включена в такие инструменты, как: ARKit, RealityKit, Unity, RealityComposer и т.п. И инструментарий, и документация на данный момент доступны для всех заинтересованных разработчиков. Старт продаж самого устройства намечен на 2024-2025 год.</p><p>Недавно создатели Vision Pro <a href="https://twitter.com/DylanMcD8/status/1747307110847680611?s=20">сообщили</a> о скором запуске магазина приложений для очков виртуальной реальности. А это значит, что в 2024 году нас ждет бум различных приложений для AR/VR устройств: игры, виртуальные примерочные, приложения для подбора интерьера, иммерсивный просмотр фильмов, прослушивание музыки и т.п. Кроме того, согласно <a href="https://www.statista.com/outlook/amo/ar-vr/worldwide">Statista</a>, к 2028 году число пользователей рынка AR и VR в мире достигнет 3674,0 млн пользователей.</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2024-01-22/85422a97-f0a2-4768-9bd5-624dc9e43818.png" alt="" /></figure><p>Также и Google, и Apple уделяют большое внимание улучшению иммерсивного опыта пользователей и на стандартных смартфонах, часах и планшетах.</p><h2>Не только смартфоны. IoT</h2><p>Каждый год выпускаются новые различные устройства под управлением ОС Android, iOS. Это не только смартфоны и планшеты, но и часы, смарт-телевизоры, игровые приставки, фитнес-трекеры, компьютеры автомобилей, а также устройства системы “умный дом”. Компании-разработчики ОС заинтересованы не только в поддержке новых возможностей устройств и гаджетов, но и улучшении инструментария для сторонних разработчиков.</p><p>Использование NFC, Bluetooth в приложениях по-прежнему остается актуальным. Yahoo Finance прогнозирует рост в области NFC<a href="https://finance.yahoo.com/news/near-field-communication-nfc-market-213000434.html?guccounter=1&amp;guce_referrer=aHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8&amp;guce_referrer_sig=AQAAALwl1HTpULp9ZvS_n8uhLfu6SphAaiYcsmcHcjctk3dE_1rciyChCs618ZjwDh-3wHv8hsDHMQKnDz9xLwcM52sE6ogK90uwb8JJR_5ZnMpU8VOZK4ynqgMws7Ry4bOtN6KxXay6zVsK6FUCKTv1biA8vvoDwlyYiZD2l8TUTiQo"> с 2023 по 2030 годы на 33,1 миллиарда долларов США</a>.</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2024-01-22/e4a88b7a-947b-4bdd-a905-d7124de21c82.png" alt="" /><figcaption>Источник: https://www.fnfresearch.com/near-field-communication-nfc-market</figcaption></figure><h2>Безопасность, улучшенная работа с сетью</h2><p>Сохранение конфиденциальных сведений было и остается одной из главных задач разработчиков. Об этом свидетельствует <a href="https://www.gartner.com/en/newsroom/press-releases/2023-09-27-gartner-says-cisos-need-to-champion-ai-trism-to-improve-ai-results">прогноз Gartner</a>. Внедрение усиленных мер безопасности (аутентификация по биометрии, использование блокчейн и т.п) весьма актуальны и в 2024 году. Также особое внимание следует уделять стабильной и безопасной работе с сетью, в том числе и работе с облачными сервисами, с NFC, при подключении к другим устройствам. Современные мобильные ОС предлагают широкий спектр нативных средств для реализации и поддержки безопасной работы приложений.</p><h2>Подведем итог</h2><p>В 2024 мобильные платформы, языки и инструменты разработки продолжат свое развитие. Основными направлениями, на которые мы рекомендуем обратить внимание, будут являться:</p><ul><li>нативная разработка;</li><li>кроссплатформа;</li><li>разработка под различные мобильные устройства, IoT;</li><li>поддержка и использование российских технологий;</li><li>безопасность, работы с сетью;</li><li>AR/VR.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Пятый раунд битвы языков программирования в 2023 году</title>
      <link>https://tproger.ru/articles/pyatyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu</link>
      <comments>https://tproger.ru/articles/pyatyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pyatyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu</guid>
      <description><![CDATA[<p>В пятом раунде батла лучших языков программирования в 2023 году встретились Swift и Python, Kotlin и Golang. Голосуйте сердцем!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pyatyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Пятый раунд битвы языков программирования в 2023 году</a>»</p>]]></description>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 23 Dec 2023 08:05:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Четвёртый раунд батла лучших языков программирования окончился победой JavaScript над PHP с отрывом в 40% голосов и победой C над Ruby с отрывом в 30% голосов.</p><p>Результаты четвёртого раунда <a href="https://tproger.ru/articles/chetvyortyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">можно посмотреть здесь</a>.</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2023-12-23/f94d91c9-22fd-497f-914b-732b69972948.png" alt="" /><figcaption>Турнирная таблица батла лучших языков программирования в 2023 году</figcaption></figure><p>Сегодня за звание лучшего языка соревнуются:</p><ul><li>Swift и Python;</li><li>Kotlin и Golang.</li></ul><p>Голосование продлится до завтра, 24 декабря 2023 года, до 11 часов по МСК.</p><p>Выберите те языки, которые вы любите больше других. Голосуйте сердцем! Не думайте о популярности языков или их востребованности. В этом турнире важна только народная любовь.</p><p>Со всеми условиями батла <a href="https://tproger.ru/articles/startuet-batl-yazykov-programmirovaniya-2023">можно ознакомиться в анонсе</a>.</p><p>Чтобы не пропустить следующие раунды, подпишитесь на тэг <a href="https://tproger.ru/tag/toplang2023">Лучший язык 2023</a>. Тогда новые раунды появятся в вашей личной ленте, а вам будут приходить уведомления об их публикации.</p>]]></content:encoded>
    </item>
    <item>
      <title>Второй раунд битвы языков программирования в 2023 году</title>
      <link>https://tproger.ru/articles/vtoroj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu</link>
      <comments>https://tproger.ru/articles/vtoroj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vtoroj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu</guid>
      <description><![CDATA[<p>Во втором раунде батла лучших языков программирования в 2023 году встретились Kotlin и Java, Rust и Golang. Голосуйте сердцем!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vtoroj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Второй раунд битвы языков программирования в 2023 году</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Лучший язык 2023]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 20 Dec 2023 08:00:38 GMT</pubDate>
    </item>
    <item>
      <title>Стартует батл языков программирования 2023</title>
      <link>https://tproger.ru/articles/startuet-batl-yazykov-programmirovaniya-2023</link>
      <comments>https://tproger.ru/articles/startuet-batl-yazykov-programmirovaniya-2023?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/startuet-batl-yazykov-programmirovaniya-2023</guid>
      <description><![CDATA[<p>Стартует турнир за звание лучшего языка программирования в 2023 году среди читателей Tproger. Кто же победит в этом году?</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/startuet-batl-yazykov-programmirovaniya-2023">Стартует батл языков программирования 2023</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Dart]]></category>
      <category><![CDATA[Лучший язык 2023]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 18 Dec 2023 08:27:48 GMT</pubDate>
      <content:encoded><![CDATA[<p>Подходит к концу 2023 год, а это значит, пора подвести его итоги и запустить традиционный батл за звание лучшего языка программирования на Tproger.</p><p>Мы уже проводили батл в прошлых <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2022-zavershilsja">2020</a>, <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-zavershilsja">2021</a> и <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2022-zavershilsja-2">2022</a> годах: первые два раза в голосовании победил Python, а в прошлом году — C#.</p><p>Вот, кто поборется за звание лучшего языка в 2023 году:</p><figure><img src="https://media.tproger.ru/user-uploads/48741/2023-12-18/7e3c300f-7dab-486d-af02-360ba8dc5952.png" alt="" /></figure><p>Правила батла остаются прежними:</p><ol><li>В батле участвует 16 языков программирования.</li><li>Ежедневно соревнуются две пары.</li><li>За любимый язык можно проголосовать в течение 24 часов.</li><li>Пары составляются рандомно, так что выбирайте язык, который субъективно нравится больше.</li><li>В финале мы определим тройку победителей.</li><li>Старт — 19 декабря, финал — 26 декабря.</li></ol><p>Примечание Сохраните эту запись в закладки: сюда мы добавим ссылки на все раунды батла во время голосования.</p><ol><li><a href="https://tproger.ru/articles/nachalsya-battl-yazykov-programmirovaniya-2023">Первый раунд</a></li><li><a href="https://tproger.ru/articles/vtoroj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Второй раунд</a></li><li><a href="https://tproger.ru/articles/tretij-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Третий раунд</a></li><li><a href="https://tproger.ru/articles/chetvyortyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Четвёртый раунд</a></li><li><a href="https://tproger.ru/articles/pyatyj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Пятый раунд</a></li><li><a href="https://tproger.ru/articles/westoj-raund-bitvy-yazykov-programmirovaniya-v-2023-godu">Шестой раунд</a></li><li><a href="https://tproger.ru/articles/polufinal-bitvy-yazykov-programmirovaniya-v-2023-godu">Полуфинал</a></li><li><a href="https://tproger.ru/articles/final-bitvy-yazykov-programmirovaniya-v-2023-godu">Финал</a></li><li><a href="https://tproger.ru/articles/batl-yazykov-programmirovaniya-2023-zaverwilsya">Результаты</a></li></ol><p>Также подпишитесь на тэг <a href="https://tproger.ru/tag/toplang2023">Лучший язык 2023</a>. Тогда новые раунды батла появятся в вашей личной ленте, а вам будут приходить уведомления об их появлении.</p><p>Старт уже завтра — 19 декабря в 11:00 МСК. Следите, участвуйте, голосуйте!</p>]]></content:encoded>
    </item>
    <item>
      <title>Telegram Bot API на Kotlin — конкурс пет-проектов</title>
      <link>https://tproger.ru/articles/telegram-bot-api-na-kotlin-kak-ono-bylo</link>
      <comments>https://tproger.ru/articles/telegram-bot-api-na-kotlin-kak-ono-bylo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Овсянников]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/telegram-bot-api-na-kotlin-kak-ono-bylo</guid>
      <description><![CDATA[<p>Написал на Kotlin библиотеку с поддержкой WebApp в JS таргете и множеством разных DSL.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/telegram-bot-api-na-kotlin-kak-ono-bylo">Telegram Bot API на Kotlin — конкурс пет-проектов</a>»</p>]]></description>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Pet-проекты]]></category>
      <category><![CDATA[Лучший пет-проект 2023]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 25 Oct 2023 07:11:19 GMT</pubDate>
      <content:encoded><![CDATA[<p>Добрый день 🙂 Я Алексей Овсянников, автор библиотеки <a href="https://github.com/InsanusMokrassar/ktgbotapi">KTgBotAPI</a>, о которой и хотел бы рассказать в рамках конкурса пет-проектов.</p><h2>Что за библиотека такая</h2><p>Изначально задачей библиотеки была строгая типизация работы с <a href="https://core.telegram.org/bots/api">Telegram Bots API</a>. Так уж вышло, что со временем это переросло в нечто большее, теперь это — мультиплатформенная библиотека с поддержкой WebApp в JS таргете и кучей разных DSL.</p><h3>О зарождении</h3><p>По счастливому стечению обстоятельств, на момент начинания библиотеки я уже имел опыт публикации JVM-библиотек, работы с Kotlin и работы с Telegram Bots API. Понятное дело, что тогда (около пяти лет назад) уже были какие-то решения для этих задач, но:</p><ul><li>Как минимум, бОльшая часть была написана на Java для JVM — ни о какой null-safety и других фишках Kotlin не шло речи.</li><li>Ни одна из изученных мной библиотек не обладала хотя бы намёком на какую-то безопасность при работе — поля запросто могли отсутствовать, а методы не применяться.</li><li>Тогда еще не так популярны были всякие DSL + поскольку библиотеки были на JVM, очень много чего скрывалось в документации или в лучшем случае в JavaDoc’ах</li></ul><p>Самой большой болью было то, что библиотеки калькировали API, из-за чего постоянно происходили выстрелы в ногу: то поле отсутствует для какого-то типа, то метод не применим для чата.</p><h3>Трудности по-пути</h3><p>Трудностей было много. Например, на первую версию ушел месяц, без учёта тестов. На входе у пользователей библиотеки до сих пор сохраняются сложности в связи со строгой типизацией и тем, что за ней следует, например, базовый <a href="https://tgbotapi.inmo.dev/tgbotapi.core/dev.inmo.tgbotapi.types.chat/-chat/index.html">Chat</a> имеет только идентификатор, все остальные параметры для общей абстракции чатов просто отсутствуют.</p><p>Также, каждая итерация поддержки <a href="https://core.telegram.org/bots/api">Telegram Bots API</a> вносила свои приколы: например, форумы — это просто группы с галочкой форумов, у которых для сообщений есть поле threadId. Само собой, каждое обновление заставляло перелопачивать иерархию типов, что иногда приводило к болючим изменениям. Цена прогресса, так сказать 🙂</p><p>Из забавностей, в одном из обновлений ребята из команды Telegram толи вывалили наружу, толи подглядели в либу и почти скопировали какую-то иерархию типов (кажется, для прав) — это было очень интересно видеть почти 1-в-1 названия для типов и их отношения друг к другу в официальном API и моей либе 😀</p><h3>Сообщество</h3><p>Отдельное спасибо я хочу сказать сообществу. Новые идеи, репорты багов, а иногда даже и самостоятельный вклад — многое произошло благодаря сообществу. Например, текущая <a href="https://docs.inmo.dev/index.html">дока</a> появилась в том виде, в каком она есть, благодаря одному из <a href="https://t.me/m_a_d_h_e_a_d">пользователей</a> либы — он подсказал, куда можно смотреть, чтобы получить доку, в которую можно будет предлагать правки и которая будет удобна в использовании.</p><h3>К чему я (мы) пришел</h3><p>Я начинал работу над библиотекой один. Со временем приходили люди и привносили идеи. Так появилось много всего:</p><ul><li>удобный API, вроде как дублирующий методы в оригинальном API, но на самом деле также разделённый по типам и строго декларирующий, какие параметры с какими можно сочетать;</li><li>различные DSL вроде <a href="https://docs.inmo.dev/tgbotapi/dsls/keyboards.html">Keyboards DSL</a> и <a href="https://docs.inmo.dev/tgbotapi/dsls/text.html">Text Entities DSL</a>;</li><li>некоторые библиотеки вокруг: <a href="https://docs.inmo.dev/plagubot/index.html">PlaguBot</a> для унификации частей ботов (плагинов), различные FSM и <a href="https://docs.inmo.dev/tgbotapi/logic/behaviour-builder.html">BehaviorBuilder</a>.</li></ul><h2>Вместо выводов</h2><p>Библиотека жива. Сейчас во многом она в ситуации поддержки — возможности целенаправленно развивать её и её экосистему особо нет, но тем не менее всё время появляются какие-то классные штуки, как то отдельная абстракция для <a href="https://t.me/ktgbotapi/354">предварительной информации о чатах</a> или различные дополнения документации.</p><h4>Спасибо за внимание 🙂</h4>]]></content:encoded>
    </item>
    <item>
      <title>Какие языки учить в 2023 году, если собираетесь в геймдев</title>
      <link>https://tproger.ru/articles/kakie-yazyki-uchit-v-2023-godu-esli-sobiraetes-v-gejmdev</link>
      <comments>https://tproger.ru/articles/kakie-yazyki-uchit-v-2023-godu-esli-sobiraetes-v-gejmdev?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[МТС]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kakie-yazyki-uchit-v-2023-godu-esli-sobiraetes-v-gejmdev</guid>
      <description><![CDATA[<p>На чём разрабатывают игры для браузеров, мобильных телефонов, консолей и ПК. Вспоминаем самые популярные языки для геймдева.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kakie-yazyki-uchit-v-2023-godu-esli-sobiraetes-v-gejmdev">Какие языки учить в 2023 году, если собираетесь в геймдев</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Разработка игр]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Unity]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 19 Jun 2023 14:49:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если любите компьютерные игры, наверняка задумывались о том, чтобы попробовать себя в разработке. И это хорошая мысль, ведь, по данным <a href="https://disk.yandex.ru/d/2K-qNZjaiNbI_w?roistat_visit=939804">исследования</a> Moscow Digital School, средняя зарплата разработчика в геймдеве превышает 280 000 рублей.</p><p>Сегодня расскажем, какие языки программирования нужно знать, чтобы стать новыми Джоном Кармаком или Гейбом Ньюэллом.</p><h2>Языки для программирования браузерных игр</h2><p>Большинство веб-игр работает на комбинации HTML, CSS и JavaScript. HTML формирует структуру и содержимое веб-страницы, CSS определяет внешний вид и стиль элементов, а JavaScript управляет игровой логикой, анимациями и интерактивными элементами. Если добавить сюда PHP, можно прописать бэкенд, настроить взаимодействие с серверной частью и сделать игру многопользовательской.</p><h3>Примеры браузерных игр</h3><p>Браузерные игры могут быть как довольно примитивными (головоломки, загадки, ребусы), так и детализированными (с разными персонажами, экипировкой, сюжетом). Вот примеры некоторых из них.</p><figure><img src="https://media.tproger.ru/uploads/2023/06/a84beeda-af9c-4ae5-902f-e471b54a44cc.png" alt="" /><figcaption>Quick, Draw! — игра, в которой за 20 секунд надо нарисовать загаданный предмет, а нейросеть попробует его угадать</figcaption></figure><figure><img src="https://media.tproger.ru/uploads/2023/06/298e4428-1100-499c-bc54-41403a882158.png" alt="" /><figcaption>Paс-Man — легендарная игра, адаптированная для браузеров. Игроку в роли колобка нужно съесть все белые точки в лабиринте, избегая встречи с призраками</figcaption></figure><h2>Языки для программирования мобильных игр</h2><p>Игры для смартфонов и планшетов обычно сложнее и интереснее браузерных, однако до компьютерных они не дотягивают из-за ограничений мобильных устройств: небольшого экрана и низкой производительности.</p><p>Но в этом есть и плюс — простота разработки. Можно использовать один из движков (например, Unity) и за несколько недель собрать свою игру, добавив только спрайты и модели и прописав логику на одном из поддерживаемых языков программирования (для Unity это C#).</p><p>Другой вариант — написать мобильную игру с нуля, не ограничивая себя готовыми движками.</p><p>Тогда для геймдева понадобятся следующие языки:</p><h3>● Java</h3><p>Язык для разработки нативных мобильных игр под платформу Android. Программы обычно преобразуются в байт-код, который выполняется на любой виртуальной машине Java (JVM), независимо от характеристик процессора. Для Java также разработаны библиотеки и фреймворки, которые помогают в создании игр, например LibGDX.</p><h3>● Kotlin</h3><p>Ещё один язык для геймдева на Java, который появился не так давно. Он полностью совместим с Java, поэтому эти языки можно использовать в проекте одновременно или быстро переписать код с одного на другой. С помощью SDK Kotlin Multiplatform Mobile на этом языке можно создавать кроссплатформенные игры для iOS и Android.</p><h3>● Objective-C и Swift</h3><p>Objective-C — первый язык программирования приложений и игр для устройств Apple. Он был создан в 80-х годах XX века как объектно-ориентированное расширение языка C.</p><p>Objective-C активно использовался Apple на протяжении многих лет, но всё же с годами его синтаксис и другие особенности устарели. Поэтому в 2014 году в компании создали новый язык программирования Swift. Он имеет более современный и интуитивно понятный синтаксис, обеспечивает статическую типизацию и автоматическое управление памятью, что помогает устранить некоторые ошибки Objective-C и упростить отладку.</p><h4>Примеры мобильных игр</h4><figure><img src="https://media.tproger.ru/uploads/2023/06/0e06d279-a090-4ea5-95f5-e721ee27d84f.jpg" alt="" /><figcaption>Genshin Impact — экшн-RPG с большим открытым миром, разнообразными игровыми механиками и головоломками. Разработана на игровом движке Unity</figcaption></figure><figure><img src="https://media.tproger.ru/uploads/2023/06/f64dd41e-a7c6-4b6a-a287-964a9107e581.jpg" alt="" /><figcaption>Diablo Immortal — многопользовательская игра в жанрах Action/RPG и hack and slash, разработанная для мобильных устройств на движке Messiah</figcaption></figure><h2>Коммерческие движки и языки программирования</h2><p>Коммерческие движки произвели революцию в сфере создания игр. Теперь, чтобы выпустить сложный игровой продукт для консоли или ПК, необязательно нанимать огромный штат программистов и тратить годы на разработку.</p><h3>Unity</h3><p>Кроссплатформенный игровой движок, популярный у независимых игровых студий. По сути это не просто движок, а среда разработки, под капотом которой находятся текстовый редактор, компилятор, отладчик и другие полезные инструменты.</p><p>Unity легко освоить даже новичку в геймдеве, но для создания сценариев взаимодействия с сервером понадобится знание <b>C#</b>. Это объектно-ориентированный язык, созданный компанией Microsoft в 2000 году для работы с платформой .NET. Он не такой сложный, как C++, и на нём не нужно писать много шаблонного кода, как на Java.</p><h4>Примеры игр, созданных на Unity</h4><figure><img src="https://media.tproger.ru/uploads/2023/06/8a8d54b2-6c96-429f-9474-e13f4317e174.png" alt="" /><figcaption>Among Us — многопользовательская игра, вдохновлённая настолкой «Мафия». Задача игроков — вычислить двух предателей на борту космического корабля, пока они не убили всю команду</figcaption></figure><figure><img src="https://media.tproger.ru/uploads/2023/06/69d20591-a815-44e7-bb7f-a26372a6fd22.jpg" alt="" /><figcaption>Outer Wilds — игра про космос, в которой главный герой исследует маленькую планету, погибающую каждые 22 минуты</figcaption></figure><h3>Unreal Engine</h3><p>Движок от известной игровой компании Epic Games, выпущенный в 1998 году. Уже больше двух десятков лет его используют в геймдеве для создания сложных игр категории AAA разных жанров — от MMORPG до шутеров от первого лица.</p><p>Unreal Engine ценят за шикарные визуальные эффекты, но освоить этот движок сложнее, чем Unity. Для создания сценариев в нём используется <b>C++</b>, правда с определёнными отличиями (без низкоуровневого управления памятью и библиотеки шаблонов).</p><p>Это довольно старый и сложный язык, но благодаря визуальному редактору Blueprints создавать скрипты и размещать объекты в Unreal Engine можно и без C++.</p><h4>Примеры игр, созданных на Unreal Engine</h4><figure><img src="https://media.tproger.ru/uploads/2023/06/67b74bcf-403c-40b7-bc4e-f017051f7dbe.jpg" alt="" /><figcaption>Fortnite — онлайн-игра, которая сочетает в себе королевскую битву, песочницу и кооперативный симулятор выживания в открытом мире</figcaption></figure><figure><img src="https://media.tproger.ru/uploads/2023/06/4df3d929-4a1f-4606-be62-92c4643c7fa2.jpg" alt="" /><figcaption>Hogwarts Legacy — RPG во вселенной Гарри Поттера со множеством квестов, интересным геймплеем и, конечно же, полётами на мётлах</figcaption></figure><h2>Итоги</h2><p>Если собираетесь работать в геймдеве и хотите выбрать язык программирования, лучше заранее понять, какие игры вы хотите создавать:</p><ol><li>для браузерных игр понадобится знание JavaScript и PHP;</li><li>мобильных — Java, Kotlin и Swift;</li><li>консольных и ПК-игр — C++ и C#, а ещё опыт работы с коммерческими движками.</li></ol>]]></content:encoded>
    </item>
    <item>
      <title>Основы OkHttp в Android-разработке</title>
      <link>https://tproger.ru/articles/osnovy-okhttp-v-android-razrabotke-2</link>
      <comments>https://tproger.ru/articles/osnovy-okhttp-v-android-razrabotke-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Intergalactic]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/osnovy-okhttp-v-android-razrabotke-2</guid>
      <description><![CDATA[<p>Как применять OkHttp — библиотеку и, по совместительству, HTTP-клиент с открытым исходным кодом для Java и Kotlin.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/osnovy-okhttp-v-android-razrabotke-2">Основы OkHttp в Android-разработке</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 Feb 2023 08:35:32 GMT</pubDate>
      <content:encoded><![CDATA[<p>OkHttp — библиотека и по совместительству HTTP-клиент с открытым исходным кодом для Java и Kotlin, разработанная Square, которая также создала Retrofit.</p><p>OkHttp предоставляет простой, легкий в использовании API для выполнения HTTP-запросов, включая поддержку протоколов HTTP/1.1 и HTTP/2. Библиотека поддерживает все стандартные методы HTTP и может легко обрабатывать несколько одновременных запросов, а также предоставляет расширенные возможности: кэширование запросов/ответов, объединение подключений в пул (connection pooling), аутентификация и др.</p><p>О том, почему иногда стоит использовать OkHttp, а не вездесущий Retrofit, можно посмотреть в <a href="https://youtu.be/r6Ga9a5w6V0">видео от Android Broadcast</a>. Краткое пояснение дано в следующем пункте статьи.</p><p>В статье подробно рассмотрены основные объекты и методы библиотеки и представлены основы работы с ней в Android-разработке.</p><p>Содержание:</p><ul><li>Преимущества OkHttp</li><li>Основные классы и методы</li><li>Простой GET-запрос (синхронный/асинхронный)</li><li>Сериализация/десериализация</li><li>Простой POST-запрос</li><li>Особенности работы с HTTPS</li><li>Аутентификация на сервере</li><li>Использование вместе с ViewModel</li></ul><h2>Преимущества OkHttp</h2><p>OkHttp — это библиотека более низкого уровня, чем Retrofit. Это означает, что HTTP-запросы, автоматизированные в Retrofit с помощью аннотаций, придётся писать вручную. Однако в этом и главный плюс библиотеки: она предоставляет более обширный функционал и настройки соединения, что может повысить производительность и сократить использование памяти. К слову, Retrofit под капотом использует OkHttp.</p><p>Библиотека разработана как легкая и эффективная, с акцентом на снижение задержек и повышение работоспособности. Это достигается за счет применения различных методов оптимизации, таких как повторное использование соединений, сжатие и конвейеризация.</p><p>Преимущества OkHttp:</p><ul><li>Гибкость: Библиотека предоставляет больше контроля над процессом сетевого взаимодействием за счёт дополнительных функций, например, пользовательской обработки запросов и ответов.</li><li>Лёгкость: OkHttp — более компактная библиотека, чем Retrofit, что позволяет минимизировать размер используемой приложением памяти.</li><li>Кэширование: Библиотека имеет встроенную поддержку HTTP-кэширования, что может повысить производительность и снизить нагрузку на сеть.</li><li>Аутентификация: OkHttp предоставляет гибкий и расширяемый API аутентификации, что упрощает реализацию различных её моделей.</li><li>Перехватчики (Interceptors): Это механизм, позволяющий легко настраивать запросы и ответы, а также хороший выбор для приложений, требующих расширенной обработки запросов.</li><li>WebSockets: OkHttp обеспечивает встроенную поддержку WebSockets, что позволяет легко реализовать коммуникацию с сервером в режиме реального времени.</li></ul><h2>Основные объекты и методы</h2><h4>Настройка клиента и запроса</h4><p>Класс <a href="https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/">OkHttpClient </a>— клиент для HTTP-вызовов, который можно использовать для отправки запросов и чтения ответов.</p><p><a href="https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.Builder.html">OkHttpClient.Builder</a> — класс предоставляющий методы для настройки клиента, например кэш, аутентификация, перехватчики, тайм-ауты и др. По завершению настройки используется метод build(), который возвращает экземпляр класса OkHttpClient.</p><p>OkHttp работает лучше при создании одного экземпляра OkHttpClient и повторном его использовании для всех HTTP-вызовов. Так происходит потому, что каждый клиент содержит свой собственный пул соединений и пул потоков. Повторное использование соединений и потоков уменьшает задержку и экономит память. И наоборот, создание клиента для каждого запроса приводит к трате ресурсов на незадействованные пулы.</p><p>Класс <a href="https://square.github.io/okhttp/3.x/okhttp/okhttp3/Request.html">Request</a> представляет собой HTTP-запрос. <a href="https://square.github.io/okhttp/3.x/okhttp/okhttp3/Request.Builder.html">Request.Builder</a> позволяет установить параметры запроса, например url и заголовки.</p><p>В целом, HTTP-заголовки представляют собой что-то похожее на Map: каждое поле имеет одно значение или не имеет его вовсе. Однако некоторые заголовки могут иметь несколько значений. В связи с этим для добавления заголовка к запросу применяются два метода:</p><ul><li>header(name, value) — устанавливает только одно значение заголовка name. При этом все существующие значения заголовка будут удалены, и после этого будет установлено новое значение.</li><li>addHeader(name, value) — добавляет заголовок без удаления уже имеющихся значений.</li></ul><p>При чтении заголовка из ответа используйте header(name), чтобы вернуть последнее вхождение заголовка (зачастую это единственное вхождение). Если значение отсутствует, header(name) вернет null. Чтобы прочитать все значения заголовка в виде списка, используйте headers(name).</p><p>Для установки целевого URL-адреса запроса используется метод <b>url()</b>. По завершению настройки запроса используется метод <b>build()</b>, который возвращает объект Request.</p><h4>Отправка запроса</h4><p><b>newCall </b>— метод класса OkHttpClient, который подготавливает запрос к выполнению в будущем. Принимает объект Request и возвращает объект Call.</p><p>Класс <b>Call </b>(вызов) — это запрос, который был подготовлен к выполнению. Вызов может быть отменен. Поскольку экземпляр класса представляет одну пару запрос/ответ, он не может быть выполнен дважды. Для выполнения запроса существуют два метода:</p><ul><li>execute() — при синхронном вызове. Метод незамедлительно выполняет запрос и блокирует поток до тех пор, пока ответ не будет доступен для обработки или пока не возникнет ошибка.</li><li>enqueue() — при асинхронном вызове. Метод назначает запрос на выполнение в определенный момент в будущем. Диспетчер определяет, когда будет выполнен запрос: обычно сразу же, если в данный момент не выполняются несколько других запросов. Позже клиент получает объект responseCallback либо с HTTP-ответом, либо с исключением в случае возникновения ошибки.</li></ul><h4>Чтение ответа</h4><p>Класс <a href="https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response/">Response </a>представляет HTTP-ответ. Тело ответа — свойство экземпляра класса, которое может быть использовано только один раз и затем закрыто. Все остальные свойства неизменяемы.</p><p>Прежде чем как-либо использовать тело ответа, необходимо проверить, был ли запрос к серверу успешен. Для этого существует метод <b>isSuccessful() </b>вышеупомянутого класса. Метод проверяет код состояния (status code) HTTP-ответа и возвращает значение true, если код находится в диапазоне 200-300. Если код находится за пределами этого диапазона, он возвращает значение false, указывающее, что запрос не был успешным.</p><p>Неуспешный запрос означает, что возникли проблемы на стороне клиента или сервера. Например, запрос был неправильно составлен, на сервере произошла ошибка или сервер некорректно обработал запрос. Если не проверять код состояния, то в конечном счёте можно работать с ответом, который не содержит ожидаемых данных.</p><p>Для получения тела ответа используется метод <b>body()</b> класса Response, который возвращает экземпляр класса ResponseBody.</p><p><a href="https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response-body/">ResponseBody </a>— одноразовый поток от сервера к клиенту, содержащий тело ответа в виде необработанных байтов. Каждое тело ответа поддерживается активным подключением к веб-серверу.</p><p>Класс ResponseBody поддерживает потоковую передачу очень больших ответов. Например, его можно использовать для чтения ответа, размер которого превышает всю память, выделенную текущему процессу. Можно даже передавать в потоковом режиме ответ, объем которого превышает общий объем памяти на текущем устройстве, что является обычным требованием для стриминговых видео-приложений.</p><p>Класс не загружает весь ответ в память, поэтому тело ответа может быть считано только один раз. Для этого существует несколько методов:</p><ul><li>bytes() и string() — считывают весь текст ответа в память, а затем возвращают его в виде массива байтов или строки соответственно. Методы следует использовать только для небольших ответов. При считывании больших ответов будет вызвана ошибка OutOfMemoryError.</li><li>source, byteStream, charStream — предназначены для потокового чтения ответа. Метод source возвращает объект BufferedSource, позволяющий читать тело ответа в виде потока байтов. byteStream работает аналогично, но возвращает объект InputStream. charStream — возвращает объект Reader, который позволяет читать тело ответа в виде потока символов.</li></ul><p>Если использовать body() без упомянутых методов, то будет получен сам объект ResponseBody, с которым ничего особо не поделаешь.</p><h2>Простой GET-запрос (синхронный/асинхронный)</h2><p>Перед использованием библиотеки нужно добавить соответствующую зависимость в Gradle:</p><p>Номер последней версии можно посмотреть на <a href="https://search.maven.org/artifact/com.squareup.okhttp3/okhttp/4.10.0/jar">Maven Central</a>.</p><p>Синхронный запрос (Java):</p><p>Синхронный запрос (Kotlin):</p><p>В то время как в Java используются методы объектов, в Kotlin иногда используются их свойства. Например, свойство body объекта Response.</p><p>Каждое тело ответа поддерживается ограниченным ресурсом. Поэтому после использования оно должно быть закрыто. Закрытие ресурса освобождает все системные средства, которые были выделены ресурсу, и делает его доступным для сбора мусора (garbage collection). Если не закрыть тело ответа, произойдет утечка ресурсов, что в конечном итоге может привести к замедлению или крашу приложения.</p><p>Для закрытия ресурса можно использовать метод close(), но предпочтительнее использовать блок try-with-resources (Java) и метод use (Kotlin). Обе конструкции выполняют блок кода относительно заданного ресурса, а затем корректно закрывают его, независимо от того, вызвано исключение или нет.</p><p>Асинхронный запрос (Java):</p><p>Асинхронный запрос (Kotlin):</p><p>Асинхронный запрос выполняется в потоке Worker. Когда ответ доступен для чтения выполняется обратный вызов (сallback). Этот вызов выполнится после того, как будут готовы заголовки ответа. Чтение тела ответа все еще может блокировать поток. OkHttp в настоящее время не предлагает асинхронных API для получения тела ответа по частям.</p><p>Callback имеет два абстрактных метода:</p><ul><li>onResponse — вызывается, когда HTTP-ответ был успешно получен от удаленного сервера.</li><li>onFailure — вызывается, когда запрос не может быть выполнен из-за проблем с подключением, тайм-аута или при его отмене. Поскольку в сети может произойти сбой во время соединения с сервером, возможен случай, когда удаленный сервер успевает принять запрос до сбоя.</li></ul><h2>Сериализация/десериализация</h2><p>В данном пункте кратко рассмотрена сериализация и десериализация объектов (их преобразование в определённую последовательность байтов, которую можно передать по сети, и наоборот).</p><p>Для того, чтобы преобразовать объект в строку JSON или наоборот можно воспользоваться библиотеками Gson и/или Moshi.</p><p>Вкратце, если вам нужна проста использования и широкий набор функций, то выбираете Gson. Если нужна производительность и эффективное использование памяти, то лучшим выбором будет Moshi.</p><p>Рассмотрим пример сериализации с помощью Moshi (Java).</p><p>То же самое в Kotlin:</p><p>Для сериализации необходимо создать объект Moshi, адаптер и передать ему тип сериализуемого объекта. В данном случае это тип Class.</p><p>Если требуется сериализовать более сложный объект, например коллекцию, то тип можно передать двумя способами.</p><p>1) С помощью метода Types.newParameterizedType(), который создает новый параметризованный тип.</p><p>2) С помощью класса TypeToken библиотеки Gson. Класс используется для передачи информации о типах во время выполнения программы. Конструктор класса возвращает представленный класс из заданного типа.</p><p>Разница способов состоит в том, что TypeToken более типобезопасен (typesafe), а Types.newParameterizedType более эффективен.</p><p>Десериализация осуществляется аналогичным образом.</p><p>При сериализации/десериализации Moshi может вызывать разного рода исключения, к примеру если десериалируемая строка не является строкой JSON или если строка не соответствует объекту, в который её пытаются преобразовать.</p><p>Если серверная и клиентская часть настроены правильно, то такого не должно происходить. Но всё же рекомендуется оборачивать операции Moshi в блок try-catch.</p><h2>Простой POST-запрос</h2><p>Чтобы сделать POST-запрос, используется метод post() класса Request.Builder. Метод принимает RequestBody, который он добавляет к запросу.</p><p>POST-запрос в Java:</p><p>POST-запрос в Kotlin:</p><p>Объект MediaType необходим для описания типа содержимого тела запроса или ответа. Обычно он используется для установки заголовка “Content-Type” в HTTP-запросе.</p><p>Чтобы получить объект <a href="https://square.github.io/okhttp/3.x/okhttp/index.html?okhttp3/MediaType.html">MediaType </a>можно использовать один из статических методов одноименного класса:</p><ul><li>MediaType.parse(String) — создает новый экземпляр MediaType с указанным типом содержимого и кодировкой. Функция возвращает медиатип для строки, или null, если строка не является правильно сформированным медиатипом.</li><li>MediaType.get(String) — работает аналогично MediaType.parse, но если строка сформирована неправильно, то вызывает исключение IllegalArgumentException.</li></ul><p>В Kotlin используется метод <b>toMediaType()</b> объекта String. Метод является аналогом MediaType.get(String).</p><p><a href="https://square.github.io/okhttp/3.x/okhttp/okhttp3/RequestBody.html">RequestBody </a>— класс, представляющий собой тело запроса. Экземпляр класса создаётся с помощью метода create.</p><p><b>RequestBody.create(MediaType, String)</b> создает тело запроса с указанным содержимым и его типом. Метод имеет несколько реализаций. Содержимое можно передать в виде массива байтов, файла, строки или объекта okio.ByteString. Тип содержимого всегда указывается с помощью объекта MediaType. Этот объект также устанавливает заголовку “Content-type” соответствующее значение, поэтому вручную устанавливать этот заголовок не нужно.</p><p>Аналогом RequestBody.create(MediaType, String) в Kotlin является метод <b>toRequestBody(MediaType?)</b> объекта String.</p><h2>Особенности работы с HTTPS</h2><p>OkHttp пытается балансировать между двумя задачами:</p><ul><li>Подключение к максимально возможному количеству хостов. Сюда входят как современные хосты, на которых используются последние версии boringssl, так и немного устаревшие хосты, на которых используются старые версии OpenSSL.</li><li>Безопасность соединения. Сюда входит проверка удаленного веб-сервера с помощью сертификатов и конфиденциальность данных, передаваемых с помощью надежных шифров.</li></ul><p>При согласовании соединения с HTTPS-сервером OkHttp должен знать, какие предлагать версии TLS и наборы шифров. Для клиента, который хочет максимизировать возможность соединения с различными серверами, это будут устаревшие версии TLS и слабые по конструкции наборы шифров. Для клиента, который хочет максимизировать безопасность, это будут только последняя версия TLS и самые сильные наборы шифров.</p><p>Конкретные решения по безопасности и соединению реализуются с помощью ConnectionSpec. OkHttp включает четыре встроенных типа соединений:</p><ul><li>RESTRICTED_TLS – безопасная конфигурация, предназначенная для удовлетворения более строгих требований по соответствию.</li><li>MODERN_TLS – безопасная конфигурация, позволяющая подключаться к современным HTTPS-серверам.</li><li>COMPATIBLE_TLS – безопасная конфигурация, которая подключается к безопасным, но менее современным серверам HTTPS.</li><li>CLEARTEXT – небезопасная конфигурация, которая используется для URL-адресов http://.</li></ul><p>По умолчанию OkHttp будет пытаться установить соединение MODERN_TLS. Если соединение MODERN_TLS не удастся, okhttp3 переключится на другой тип соединения. Точный механизм отката зависит от конкретной реализации okhttp3 и конфигурации, установленной разработчиками.</p><p>Настроить конфигурацию можно следующим образом:</p><p>В <a href="https://square.github.io/okhttp/features/https/">официальной документации</a> можно найти дополнительные способы работы с HTTPS, такие как создание собственной спецификации подключения, закрепление сертификата и настройка доверенных сертификатов.</p><h2>Аутентификация на сервере</h2><p>Аутентификацию на сервере можно реализовать двумя способами.</p><p>1) Вручную добавить заголовок аутентификации. Полезно в случае, если нужна аутентификация только для одного запроса. Для того, чтобы добавлять заголовок ко всем запросам клиента, можно создать перехватчик. Способ полезен, если у вас статический ключ API или токен, который нужно отправлять с каждым запросом.</p><p>2) Использовать интерфейс Authenticator — полезно, когда необходимо динамически аутентифицироваться или нужна дополнительная настройка процесса аутентификации.</p><p>Интерфейс позволяет выполнить либо предварительную аутентификацию перед подключением к серверу, либо реактивную аутентификацию после получения ответа от веб-сервера или прокси-сервера.</p><p>Рассмотрим пример реактивной аутентификации. В таком случае, если код состояния ответа равен 401 (Unauthorized), OkHttp посылает повторный запрос, включающий заголовок “Authorization”.</p><p>При этом важно сделать проверку, была ли в первоначальном запросе попытка аутентификации. Если да, то, скорее всего, дальнейшие попытки будут бесполезны, и аутентификатор должен отказаться от них.</p><p>Здесь метод authenticator с помощью лямбда-функции устанавливает экземпляр интерфейса Authenticator, который предоставляет механизм для проверки ответа от сервера и возвращает запрос, включающий в себя учетные данные клиента. Метод Credentials.basic используется для кодирования имени пользователя и пароля при базовой аутентификации.</p><h2>Использование вместе с ViewModel</h2><p>Простой асинхронный запрос в ViewModel можно сделать следующим образом.</p><p>Метод <b>postValue </b>передаёт задачу по установке значения главному потоку. Если попытаться присвоить значение напрямую, то будет вызвано исключение java.lang.IllegalStateException: Cannot invoke setValue on a background thread.</p><p>Необходимо делать именно асинхронный запрос, чтобы не блокировать поток интерфейса и чтобы приложение оставалось отзывчивым. Либо можно самостоятельно настроить синхронный вызов в другом потоке.</p><p>Начиная с SDK 10 при попытке синхронного вызова в главном потоке будет вызвано исключение android.os.NetworkOnMainThreadException.</p><p>Чтобы сделать запрос в отдельном api-файле и передать ответ переменной из ViewModel можно воспользоваться механизмом callback.</p><p>В файле SomeApiService.kt находится интерфейс RequestCallback, класс SomeApiService с методом makeRequest, который делает запрос к серверу, и объект SomeApi, через который будет осуществляться доступ к экземпляру класса.</p><p>В MainViewModel.kt функция getResponseFromApi реализует интерфейс RequestCallback и передает его в качестве параметра методу makeRequest().</p><p>Представленный код можно обернуть во viewModelScope.launch {…}, чтобы запрос был отменён при очистке (разрушении) MainViewModel.</p><h2>Заключение</h2><p>OkHttp — гибкая библиотека, выступающая в роли HTTP-клиента.</p><p>В отличии Retrofit настраивать клиент, писать запросы и обрабатывать ответы необходимо вручную. Это одновременно и преимущество и недостаток OkHttp. Недостаток заключается в необходимости писать много шаблонного кода. Преимущество — возможность кастомизировать соединение.</p><p>Из-за слабой кастомизируемости в некоторых случаях Retrofit может не подойти, и без OkHttp не обойтись. Также благодаря кастомизации OkHttp можно повысить производительность и уменьшить использование памяти.</p><p>Полезные ресурсы: <a href="https://square.github.io/okhttp/4.x/okhttp/okhttp3/-authenticator/">Подробнее про Authenticator</a>; <a href="https://square.github.io/okhttp/recipes/#asynchronous-get-kt-java">Различные примеры использования библиотеки</a>; <a href="https://square.github.io/okhttp/features/interceptors/">Перехватчики (Interceptors)</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Какой язык программирования выбрать новичку в 2023 году</title>
      <link>https://tproger.ru/articles/kakoj-jazyk-programmirovanija-vybrat-novichku-v-2023-godu</link>
      <comments>https://tproger.ru/articles/kakoj-jazyk-programmirovanija-vybrat-novichku-v-2023-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Виктория Овсянникова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kakoj-jazyk-programmirovanija-vybrat-novichku-v-2023-godu</guid>
      <description><![CDATA[<p>Мы проанализировали популярность, уровни зарплат и собрали подборку, которая поможет выбрать язык программирования для изучения в 2023 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kakoj-jazyk-programmirovanija-vybrat-novichku-v-2023-godu">Какой язык программирования выбрать новичку в 2023 году</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 18 Jan 2023 10:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Совсем недавно закончилась «Битва языков программирования 2022». А в этой статье поговорим о том, какой язык программирования стоит изучать уже в 2023 году.</i></p><figure><img src="https://media.tproger.ru/uploads/2023/01/image8.png" alt="" /></figure><p>Сейчас <a href="https://yandex.ru/q/tech/736954369/">насчитывается</a> больше 8 000 разных языков программирования (ЯП), и их количество постоянно растёт. Каждый год, если не месяц, появляются новые, в том числе созданные just for fun, но популярных и востребованных всё же гораздо меньше. На какие из них стоит обратить внимание новичку?</p><p>Отвечая на этот вопрос, мы проанализировали несколько самых известных языков и сравнили их популярность по двум рейтингам: TIOBE и Stack Overflow. Также мы изучили уровень зарплат для каждого языка из статьи и проанализировали порог вхождения. В статье рассматриваются JavaScript, Golang, C++, Python, Java, Swift и Kotlin из мобильной разработки.</p><ol><li><a href="https://tproger.ru/#1">JavaScript</a></li><li><a href="https://tproger.ru/#2">Golang</a></li><li><a href="https://tproger.ru/#3">C++</a></li><li><a href="https://tproger.ru/#4">Python</a></li><li><a href="https://tproger.ru/#5">Java</a></li><li><a href="https://tproger.ru/#6">Swift</a></li><li><a href="https://tproger.ru/#7">Kotlin</a></li><li><a href="https://tproger.ru/#8">Так что же выбрать?</a><br /></li></ol><h2>JavaScript</h2><h3>Популярность</h3><p>Этот язык находится на 7–ом месте по индексу <a href="https://www.tiobe.com/tiobe-index/">TIOBE</a>, строящемуся на основе подсчёта результатов поисковых запросов, содержащих название ЯП. В 2022 году рейтинг <a href="https://tproger.ru/articles/javascript-s-nulja-dorozhnaja-karta/">JavaScript</a> вырос на 0,9%. На графике ниже показана динамика изменения рейтинга языка с 2002 года.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image2.png" alt="" /></figure><p>Что касается индекса Stack Overflow, то JavaScript находится на 17–ом месте. Он нравится 61,46% пользователей ресурса (индекс составлен с учётом 22 544 голосов).</p><h3>Уровень зарплат</h3><p>По данным Хабр Карьеры, медианный уровень зарплаты программистов на JavaScript — 150 000 рублей. Этот показатель не вырос, но и не снизился с 2021 года, что может говорить о стабильном спросе на разработчиков, специализирующихся на этом ЯП.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image4.png" alt="" /></figure><h3>Порог вхождения и перспективы</h3><p>По мнению самих разработчиков, у JavaScript относительно невысокий порог входа, что делает его весьма популярным и востребованным. Его стоит изучать потому, что технологии на базе языка повсеместны. Так, он исполняется у любого пользователя сети в браузере и применяется в бэкенде. При этом задачи, для решения которых используется JS, могут быть очень сложными.</p><p>Перспективы у JS хорошие — его популярность вряд ли будет снижаться в ближайшие несколько лет. Хотя бы потому, что это единственный язык программирования такого класса, который поддерживается браузерами. Плюс он подходит для работы с серверными технологиями.<br /></p><h2>Golang</h2><h3>Популярность</h3><p>Golang — относительно молодой ЯП, созданный командой Google. За примерно десять лет он поднялся до 12-го места в индексе TIOBE. В 2021 году он занимал 19–ю позицию. Вот динамика изменения рейтинга ЯП с момента его появления в 2010 году.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image1.png" alt="" /></figure><p>В индексе Stack Overflow он занимает 8–е место. С ним предпочитают работать 64,58% пользователей ресурса.</p><h3>Уровень зарплат</h3><p>По данным Хабр Карьеры, медианная зарплата разработчиков Golang составляет 205 000 рублей, с ростом на 3% по отношению к 2021 году. Рост зарплат может быть свидетельством увеличения популярности языка от года к году.</p><h3>Порог вхождения и перспективы</h3><p>По этому показателю Golang несколько проигрывает JavaScript, поскольку язык изучают в основном профессиональные разработчики, которые программируют и на других языках. Как правило, язык изучают в связке с PHP и Python.</p><p>Тем не менее многие программисты считают, что <a href="https://tproger.ru/translations/golang-basics/">Go</a> подходит и для изучения в качестве первого ЯП. Это полный язык по Тьюрингу, а его достоинства — простота и лаконичность. С помощью Golang можно решать задачи практически любого уровня сложности.<br /></p><h2>С++</h2><h3>Популярность</h3><p>Согласно индексу TIOBE «плюсы» занимают 3–ю позицию, поднявшись с 4–го места в 2021 году. За год рейтинг языка увеличился на 4,21%. Ниже — динамика популярности с 2002 года.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image7.png" alt="" /></figure><p>А вот согласно индексу Stack Overflow язык занимает 25–е место. Он нравится 48,39% пользователей ресурса.</p><h3>Уровень зарплат</h3><p>Медианный уровень, по данным Хабр Карьеры, — 150 000 рублей. По сравнению с 2021 годом уровень зарплат вырос на 9%.</p><h3>Порог вхождения и перспективы</h3><p>У этого языка довольно высокий порог вхождения. Желательно иметь хотя бы базовое представление о том, что такое программирование, как работает аппаратное обеспечение ПК и ОС. При работе с языком требуется контролировать типы данных, а также выделение и освобождение памяти.</p><p>Спрос же на разработчиков <a href="https://tproger.ru/articles/razrabotka-na-c-s-nulja-v-2022-godu-dorozhnaja-karta/">С++</a> остаётся стабильно высоким. Их приглашают на работу в компании разного масштаба, включая такие крупные, как Microsoft, Amazon и Google.<br /></p><h2>Python</h2><h3>Популярность</h3><p>По данным индекса TIOBE, <a href="https://tproger.ru/articles/python-roadmap/">Python</a> занял в 2022 году 1–е место, его показатель популярности вырос с 2021 года на 3,76%. Судя по динамике изменения рейтинга, востребованность специалистов по этому ЯП постоянно растёт.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image6.png" alt="" /></figure><p>В индексе Stack Overflow язык занимает 6–е место. Его выбирают 67,34% пользователей ресурса.</p><h3>Уровень зарплат</h3><p>По данным Хабр Карьеры, Python-программисты получают около 140 000 рублей. При этом с 2021 года этот показатель упал на 7%. Падение может быть связано с ростом количества программистов, работающих с этим ЯП, и вследствие этого ростом предложения на рынке.</p><h3>Порог вхождения и перспективы</h3><p>Язык считается несложным для изучения. До уровня Junior его могут освоить люди без технического образования. Что касается перспектив Python, то его популярность растёт год от года. Причина — несмотря на относительную простоту, ЯП позволяет разрабатывать серьёзные проекты со сложной архитектурой.<br /></p><h2>Java</h2><h3>Популярность</h3><p>В индексе TIOBE Java находится на 4–ом месте, тогда как в 2021 ЯП занимал 3–ю позицию. Язык много лет занимает ведущие позиции рейтинга, перемещаясь в первой пятёрке. Вот динамика изменения рейтинга.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image5.png" alt="" /></figure><p>А вот по версии индекса Stack Overflow он находится на 28–ом месте. Язык нравится 45,75% пользователей ресурса.</p><h3>Уровень зарплат</h3><p>Согласно данным Хабр Карьеры медианная зарплата Java-разработчика составляет около 200 000 рублей. За год зарплаты в среднем выросли на 13%.</p><h3>Порог вхождения и перспективы</h3><p>По мнению ряда разработчиков, порог вхождения в Java средний. Чтобы научиться программировать на языке, нужен технический английский, чтобы разбираться в документации. Требуются общие знания ООП, паттернов проектирования, а также общее хорошее знание Java в объёме Sun’s java tutorial.</p><p>Стоит отметить, что Java — язык программирования, который используется в энтерпрайзе. В мире нет крупных компаний, которые не используют Java. В ближайшие лет 10 никто не сможет отказаться от этого языка, поскольку на нём написано множество продуктов, модулей и т. п.<br /></p><h2>Swift</h2><h3>Популярность</h3><p>Согласно индексу TIOBE язык Swift занимает 15–е место по популярности среди разработчиков. Стоит отметить, что за год ЯП опустился сразу на 5 позиций, в прошлом году он занимал 10–е место. Вот динамика изменения популярности языка с 2014 года.</p><figure><img src="https://media.tproger.ru/uploads/2023/01/image3.png" alt="" /></figure><p>Что касается индекса Stack Overflow, то Swift занимает 12–е место. Язык нравится 62,88% разработчиков.</p><h3>Уровень зарплат</h3><p>Хабр Карьеры говорит о том, что Swift-разработчики получают около 200 000 рублей, за год зарплаты остались на прежнем уровне. Это может говорить о стабильном спросе на специалистов по этому ЯП, который остаётся примерно на одном и том же уровне из года в год.</p><h3>Порог вхождения и перспективы</h3><p>Он довольно низкий по сравнению с другими языками. Начать работать после получения базового опыта и знаний можно в пределах года с момента начала изучения Swift. При этом, если раньше кодовая база имела 75 000 кодовых строк, то сейчас это количество сокращено более чем на две трети.</p><p>У языка отличные перспективы, поскольку экосистема Apple, для поддержки устройств которой и создан язык, продолжает активно развиваться. Практически у любой относительно крупной компании есть приложение на iOS, что означает, что спрос на разработчиков не будет падать в ближайшие несколько лет.<br /></p><h2>Kotlin</h2><h3>Популярность</h3><p>Согласно индексу TIOBE Kotlin занимает 23–е место. Это относительно новый язык, который ещё просто не успел войти в первую двадцатку или тем более десятку. Тем не менее его популярность постепенно растёт. Так, с прошлого года рейтинг ЯП вырос на 0,58%.</p><p>По индексу Stack Overflow язык занимает 11–е место. Он нравится 63,29% разработчиков.</p><h3>Уровень зарплат</h3><p>Тезис о росте популярности языка подтверждает и уровень зарплат разработчиков, которые специализируются на Kotlin. По данным Хабр Карьеры, медианная зарплата программиста на Kotlin составляет около 185 000 рублей. За год этот показатель увеличился на 3%.</p><h3>Порог вхождения и перспективы</h3><p>По мнению разработчиков, порог вхождения в Kotlin низкий по сравнению с другими языками. Ещё быстрее его можно освоить, если разработчик хотя бы на базовом уровне знает Java. При этом родные для Java итераторы и коллекции поддерживаются им «из коробки».</p><p>Интересный факт: в Google считают, что Kotlin открывает больше возможностей, чем Java. Его популярность постепенно растёт — некоторые компании предпочитают переходить на Kotlin с Java. Плюс это универсальный язык, на котором можно написать и Android-приложение, и сервис, и приложение для ПК. В ближайшие лет 5 его популярность будет расти, так что и спрос на Kotlin-разработчиков будет стабильно высоким.</p><h2>Так что же выбрать?</h2><p>Мы рекомендуем выбирать тот язык программирования, принципы развития и сфера применения которого ближе к вашим профессиональным интересам. Скажем, если вы собираетесь выбрать своей отраслью Data Science, то вам нужен Python. Если хотите посвятить себя мобильной разработке, то без Java, Swift или Kotlin не обойтись.</p><p>Так что приведённые данные относительно места разных ЯП в индексе или уровня зарплат разработчиков — лишь ориентир, но далеко не главный фактор, которым стоит руководствоваться при выборе языка программирования, который вы собираетесь начать учить в 2023 году.</p>]]></content:encoded>
    </item>
    <item>
      <title>Лучший язык программирования: рейтинг TIOBE 2022</title>
      <link>https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022</link>
      <comments>https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022</guid>
      <description><![CDATA[<p>В этом году рейтинг языков программирования TIOBE удивил тройкой лидеров. Узнайте, какой из языков потеснил Java и вышел в топ-3!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022">Лучший язык программирования: рейтинг TIOBE 2022</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Perl]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 23 Dec 2022 12:35:23 GMT</pubDate>
      <content:encoded><![CDATA[<p>На днях у нас прошёл батл языков программирования 2022, и настало время обратиться к рейтингам TIOBE.</p><p>Напомним, что индекс TIOBE оценивает популярность языков программирования, основываясь на поисковых запросах, которые содержат тот или иной язык. Для формирования индекса используются такие ресурсы, как Google, YouTube, Amazon, Wikipedia, Yahoo!, Bing и Baidu.</p><p>В 2023 году популярность языков изменилась. Какие языки потеряли популярность, а какие — нет, <a href="https://tproger.ru/articles/best-prog-lang-2023">рассказали в этой статье</a>.</p><ol><li>Python, C и C++ соревнуются за звание лучшего языка</li><li>Пара слов о других языках</li><li>Выводы</li></ol><h2>Python, C и C++ соревнуются за звание лучшего языка</h2><p>Именно таковы результаты по состоянию на конец декабря — двадцать языков программирования с наибольшей рыночной долей по версии TIOBE:</p><figure><img src="https://media.tproger.ru/uploads/2022/12/9bcee0e3-9325-45a6-985b-c850cc01a924.jpg" alt="" /></figure><p>Ещё в прошлом году Java уверенно держалась в тройке, но теперь уступила своё место «плюсам». Любопытно, что в последний раз C++ становился лидером рейтинга TIOBE в далёком 2003 году, и это впервые, когда данный язык программирования обошёл Java по поисковым запросам. При этом Java входила в топ-3 свыше двадцати лет, начиная с 2001.</p><p>Уже в следующем месяце мы узнаем имя победителя. Каждый из лидирующей тройки уже занимал первое место по итогам года:</p><ol><li>C++ — 1 раз (2003).</li><li>C — 3 раза (2008, 2017, 2019).</li><li>Python — 5 раз (2007, 2010, 2018, 2020, 2021).</li></ol><h2>Пара слов о других языках</h2><p>Помимо прочего, мы видим, как Kotlin и Julia приближаются к топ-20, JavaScript держится в семёрке, а PHP вырывается в десятку, тогда как в прошлом году занял 12-е место.</p><p>Интересно, что Go поднялся аж на 7 позиций и теперь занял 12-е место рейтинга. Стоит отметить, что по версии GitHub за третий квартал 2022 Golang также находится на четвёртом месте по популярности, обогнав при этом PHP, C, C#, Ruby, TypeScript и JavaScript. Тенденция налицо:</p><figure><img src="https://media.tproger.ru/uploads/2022/12/d6659c61-2e2c-4fa7-8d63-f8121e17b018.jpg" alt="" /></figure><p>На 18-е место рейтинга TIOBE вернулся Perl. Rust удерживает 20 позицию. Что касается Delphi, то он всю осень прыгал туда-сюда:</p><ul><li>сентябрь — 13 место (1.09%);</li><li>октябрь — 18 место (0.85%);</li><li>ноябрь — 14 место (1.08%).</li></ul><p>В декабре же язык опустился на 16 место (0.85%), что соответствует результатам декабря прошлого года.</p><h2>Выводы</h2><p>Разумеется, рейтинг языков программирования 2022 TIOBE сложно назвать объективным, так как он рассматривает лишь один аспект — популярность ЯП в поисковых запросах пользователей. Он не отражает реальный рыночный спрос или количество написанного кода, как это делает GitHub в своих отчётах на основе проектов.</p><p>Тем не менее, индекс TIOBE можно использовать, чтобы проверить, актуальны ли ваши навыки, или принять решение о том, на какой язык программирования можно перейти или какой следует использовать при написании новой программы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Шестой раунд битвы языков программирования 2022</title>
      <link>https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022</link>
      <comments>https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022</guid>
      <description><![CDATA[<p>Стартовал шестой раунд битвы языков программирования за звание лучшего в 2022 году. В нём борются PHP против TypeScript, Kotlin против Java.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022">Шестой раунд битвы языков программирования 2022</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Лучший язык 2022]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 18 Dec 2022 08:02:24 GMT</pubDate>
      <content:encoded><![CDATA[<p>Это — шестой раунд битвы языков программирования за звание лучшего в 2022 году. В нём борются PHP против TypeScript, Kotlin против Java.</p><p>По итогам пятого раунда Python обошёл Pascal, а C# обошёл С. Результаты прошлого раунда можно посмотреть <a href="https://tproger.ru/articles/pjatyj-raund-bitvy-jazykov-programmirovanija-2022/">здесь</a>.</p><p>Подпишитесь на тег <a href="https://tproger.ru/tag/luchshij-jazyk-2022/">Лучший язык 2022</a> и следите за обновлениями в личной ленте, чтобы не пропустить новые раунды битвы.</p><figure><img src="https://media.tproger.ru/uploads/2022/12/battle_table-5.png" alt="" /></figure><p>Голосование по пятому раунду продлится до 18 декабря 2022 года. Опросы будут закрыты в 11:00 по МСК.</p>]]></content:encoded>
    </item>
    <item>
      <title>Третий раунд битвы языков программирования в 2022 году</title>
      <link>https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu</link>
      <comments>https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu</guid>
      <description><![CDATA[<p>Начинается третий раунд битвы за звание лучшего языка программирования в 2022 году. На этот раз столкнулись PHP и Ruby, Swift и Kotlin.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu">Третий раунд битвы языков программирования в 2022 году</a>»</p>]]></description>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Лучший язык 2022]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 15 Dec 2022 08:00:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Второй раунд битвы за титул лучшего языка программирования 2022 завершился победой Python над Golang и C над Assembler. Ознакомиться с результатами прошлого раунда можно <a href="https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu/">здесь</a>.</p><p>Не хотите пропустить новые раунды? Подпишитесь на тэг <a href="https://tproger.ru/tag/luchshij-jazyk-2022/">Лучший язык 2022</a> и следите за обновлениями в личной ленте.</p><p>Сегодня между собой соревнуются:</p><ul><li>Ruby и PHP;</li><li>Swift и Kotlin.</li></ul><figure><img src="https://media.tproger.ru/uploads/2022/12/battle_table-1-1.png" alt="" /></figure><p>Голосование по этим языкам программирования продлится до 16 декабря 2022 года. Опросы будут закрыты в 11:00 по МСК.</p>]]></content:encoded>
    </item>
    <item>
      <title>Стартует батл языков программирования 2022</title>
      <link>https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022</link>
      <comments>https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022</guid>
      <description><![CDATA[<p>Батл на звание лучшего языка программирования 2022 уже не за горами. Давайте узнаем, какой ЯП наиболее популярен по версии Tproger!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022">Стартует батл языков программирования 2022</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2022]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 12 Dec 2022 08:00:40 GMT</pubDate>
      <content:encoded><![CDATA[<p>Предлагаем отвлечься от серьёзных рейтингов вроде <a href="https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022/">TIOBE</a> или PYPL и выбрать лучший язык программирования 2022 по версии пользователей Tproger.</p><p>Правила батла по-прежнему просты:</p><ol><li>В батле участвует 16 языков программирования.</li><li>Ежедневно соревнуются две пары.</li><li>За любимый язык можно проголосовать в течение 24 часов.</li><li>Пары составляются рандомно, так что выбирайте язык, который субъективно нравится больше.</li><li>В финале мы определим тройку победителей.</li><li>Старт — 13 декабря, финал — 20 декабря.</li></ol><p>Примечание Забирайте эту запись в закладки, ведь именно в неё будут добавляться ссылки на последующие этапы голосования.</p><ul><li><a href="https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2022/">Этап 1</a></li><li><a href="https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu/">Этап 2</a></li><li><a href="https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu/">Этап 3</a></li><li><a href="https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 4</a></li><li><a href="https://tproger.ru/articles/pjatyj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 5</a></li><li><a href="https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 6</a></li><li><a href="https://tproger.ru/articles/polufinal-bitvy-jazykov-programmirovanija-2022">Полуфинал</a></li><li><a href="https://tproger.ru/articles/final-bitvy-jazykov-programmirovanija-2022/">Финал</a></li><li><a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2022-zavershilsja-2/">Результаты</a></li></ul><p>Турнирная таблица:</p><figure><img src="https://media.tproger.ru/uploads/2022/12/Turnirnaja-tablica.png" alt="" /></figure><p>Старт уже завтра — 13 декабря в 11:00 МСК. Следите, участвуйте, голосуйте!</p>]]></content:encoded>
    </item>
    <item>
      <title>Уменьшаем размер приложения на Android с помощью Dynamic delivery</title>
      <link>https://tproger.ru/articles/umenshaem-razmer-prilozhenija-na-android-s-pomoshhju-dynamic-delivery</link>
      <comments>https://tproger.ru/articles/umenshaem-razmer-prilozhenija-na-android-s-pomoshhju-dynamic-delivery?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Мария Кривоченко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/umenshaem-razmer-prilozhenija-na-android-s-pomoshhju-dynamic-delivery</guid>
      <description><![CDATA[<p>Рассказали об особенностях принципах работы с Dynamic delivery и разобрали, как с её помощью перенести фичи приложения в динамические модули.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/umenshaem-razmer-prilozhenija-na-android-s-pomoshhju-dynamic-delivery">Уменьшаем размер приложения на Android с помощью Dynamic delivery</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 26 Oct 2022 15:31:12 GMT</pubDate>
      <content:encoded><![CDATA[<p>В мобильной разработке не первый год актуальна концепция мультифункционального приложения (Super app). Она имеет много преимуществ, но зачастую пользователя интересует лишь часть функционала. А остальные фичи остаются невостребованными и занимают место на устройстве. Создание единого большого приложения ведёт ещё и к увеличению объёма, что негативно отражается на количестве скачиваний.</p><p>Уменьшить размер приложения и дать пользователю возможность самостоятельно выбрать подходящий ему набор фич — важные задачи, которые помогает решить Dynamic delivery. В сети есть много инструкций, как создать динамическую фичу с нуля. Но как превратить написанный код в динамическую фичу?</p><p>В этой статье я хочу раскрыть вопрос миграции фич в динамические модули на примере нашего флагманского приложения на Android. Расскажу о влиянии Dynamic delivery на архитектуру, о возможных сценариях миграции существующих фич, о сложностях, с которыми я столкнулся и о результатах, которые мы получили.</p><ol><li><a href="https://tproger.ru/#part1">Коротко о Dynamic feature delivery</a></li><li><a href="https://tproger.ru/#part2">Влияние Dynamic delivery на архитектуру нашего приложения</a></li><li><a href="https://tproger.ru/#part3">Миграция существующих фич</a></li><li><a href="https://tproger.ru/#part4">Результаты</a></li><li><a href="https://tproger.ru/#part5">Заключение</a></li><li><a href="https://tproger.ru/#part6">Дополнительные материалы</a></li></ol><h2>Коротко о Dynamic feature delivery</h2><p>Dynamic delivery — технология от Google, которая позволяет выделить из монолитного приложения фичи, и устанавливать и удалять их прямо во время выполнения программы.</p><p>Если вы только начали знакомство с Dynamic delivery, то рекомендую начать с ссылок, которые я собрал <a href="https://tproger.ru/#part6">в конце статьи</a>.</p><p>После ознакомления с этим материалом вы сможете лучше понять принцип работы Dynamic delivery, ознакомиться с предоставляемым API, найти пример с использованием архитектуры RIBs. Однако, не во всех проектах используется эта архитектура. Поэтому я дополню подборку источников и расскажу, как у нас <a href="https://kas.pr/mobile-dynamicdelivery-azamat-tproger">в мобильном штабе «Лаборатории Касперского»</a> происходила миграция существующего кода в динамический модуль.</p><h2>Влияние Dynamic delivery на архитектуру нашего приложения</h2><h3>Как была построена многомодульность</h3><p>Начну с короткого описания нашей архитектуры (более подробное можно найти по ссылкам <a href="https://tproger.ru/#part6">в конце статьи</a>). В нашем проекте <a href="https://www.kaspersky.ru/android-security">Kaspersky Internet Security для Android</a> есть module-injector, который содержит базовые интерфейсы:</p><p>BaseDependencies используется для перечисления объектов, которые требуются фиче на вход (зависимости фичи). BaseApi — для перечисления объектов, которые фича предоставляет наружу (внешний интерфейс фичи). ComponentHolder нужен для связки BaseDependencies. BaseApi — позволяет получить реализацию BaseApi конкретной фичи, передав все необходимые зависимости.</p><p>Для лучшего понимания рассмотрим эти три интерфейса на примере фичи Security news. Эта фича позволяет получать актуальные новости безопасности. В качестве входных зависимостей  у неё будет логин в формате строки. А наружу она предоставит интерактор с методом проверки новостей:</p><p>Связующим звеном выступает SecurityNewsFeatureComponentHolder:</p><p>Таким образом, чтобы получить инстанс интерактора в основном модуле, необходимо в метод init объекта SecurityNewsFeatureComponentHolder передать зависимости фичи.</p><p>В проекте присутствует и альтернативный вариант базового ComponentHolder — LazyComponentHolder, который создаёт инстанс API фичи только при первом обращении. Реализацию его в статье приводить не буду, чтоб не усложнять материал.</p><p>Если в проекте используется Dagger, то в теле метода createApi будет обращение к dagger-компоненту фичи. Однако, такая тройка интерфейсов не обязывает использовать тот или иной DI-инструмент.</p><p>В приведённом выше коде SecurityNewsComponent расширяет интерфейс SecurityNewsFeatureApi презентором SecNewsPresenter. Он объявлен в интерфейсе SecurityNewsComponent, а не в SecurityNewsFeatureApi, потому что используется в коде внутри модуля фичи, а не внутри модуля App. Чтобы внутри фичи можно было получить SecNewsPresenter, изменим код SecurityNewsFeatureComponentHolder:</p><p>Как можно заметить, теперь мы держим ссылку типа SecurityNewsComponent, а не SecurityNewsFeatureApi. Появился метод getSecurityNewsComponent, который поможет получить SecNewsPresenter внутри кода фичи. В итоге внутри модуля фичи происходит обращение к методу getSecurityNewsComponent, а вне его — к методу get.</p><h3>Влияние Dynamic delivery на архитектуру приложения</h3><p>В случае обычных приложений главный модуль App знает обо всех фича-модулях. В случае Dynamic delivery динамическая фича зависит от модуля App, которыйничего не знает о модуле динамической фичи и работает с ней через ReflectionAPI. Подробнее можно почитать в <a href="https://developer.android.com/guide/playcore/feature-delivery">документации</a>.</p><figure><img src="https://media.tproger.ru/uploads/2022/10/image1-4.png" alt="" /><figcaption>Cхема зависимости модулей друг от друга</figcaption></figure><p>Описанные выше ограничения Dynamic delivery подталкивают нас изменить код внутри модуля фичи. Начнём с разделения модуля на API и реализацию.</p><figure><img src="https://media.tproger.ru/uploads/2022/10/image2-4.png" alt="" /><figcaption>Схема зависимости модулей с учётом Dynamic feature delivery</figcaption></figure><p>Такое разделение следует сделать для создания общего для App и Dynamic feature impl-модуля, куда можно положить классы и интерфейсы, на которые ссылаются в коде оба модуля.</p><p>В Dynamic feature API выносим SecurityNewsFeatureDependencies, SecurityNewsFeatureApi и все интерфейсы и классы, которые используются в них (в нашем случае — SecurityNewsInteractor). Однако, мы не можем вынести SecurityNewsFeatureComponentHolder — он связан с сущностями фичи, которые должны остаться в том же модуле. Если обращений к SecurityNewsFeatureComponentHolder будет несколько, то увеличится количество использования ReflectionAPI в коде (например, через ReflectionAPI нужно будет вызвать метод init, чтобы проинициализировать фичу, а затем — get, чтобы получить внешний интерфейс фичи).</p><p>Для упрощения кода можно уменьшить количество доступных только через Reflection API методов до одного (оставить только метод инициализации init). Для этого в module-injector создаём абстрактный класс ApiHolder:</p><p>В модуле FeatureSecurityNewsApi создаём объект SecurityNewsApiHolder:</p><p>В модуле FeatureSecurityNewsImpl меняем код в SecurityNewsFeatureComponentHolder:</p><p>Таким образом, сперва через ReflectionAPI нужно вызвать метод инициализации у SecurityNewsFeatureComponentHolder, в результате чего будет создан SecurityNewsComponent, а ссылка на компонент сохранится в поле объекта FeatureSecurityNewsApi. После инициализации внутри модуля фичи будет происходить обращение к методу getSecurityNewsComponent объекта SecurityNewsFeatureComponentHolder, а вне модуля — к методу getApi объекта SecurityNewsApiHolder.23ц</p><h2>Миграция существующих фич</h2><p>Мы успешно адаптировали архитектуру многомодульного приложения под Dynamic delivery. Следующим шагом применим один из нескольких сценариев включения фичи в состав приложения. Исходя из официального описания, существует 3 сценария:</p><ul><li>при установке (install-time delivery);</li><li>при установке с определёнными фильтрами (conditional delivery);</li><li>по запросу (on demand delivery).</li></ul><p>Второй сценарий позволяет исключить из приложения набор фич по заданным признакам (например, страна скачивания или характеристики девайса). Третий — исключить модуль из приложения для всех пользователей с возможностью в дальнейшем его скачать.</p><p>Рассмотрим сценарий, когда фича Security news была частью приложения, а теперь мы хотим её сделать динамически подгружаемой по требованию. Если обычный gradle-модуль сделать сразу динамически подгружаемым, то фича в следующем релизе исчезнет у пользователя, который получит обновление. Это может иметь негативные последствия как поведенческого характера, так и юридического. Если это не критично, можно явно пользователя попросить скачать фичу снова. Если по каким-то причинам важно сохранить фичу на девайсах тех, к кому она уже попала (например, если за неё уже заплатили), то нужно проработать процесс миграции. Рассмотрим возможные сценарии миграции от простого к сложному.</p><h3>1 вариант</h3><p>Выше мы рассмотрели 3 сценария включения фичи в состав приложения. Чтобы сохранить фичу у пользователя, можно сперва gradle-модуль превратить в динамическую фичу, доступную в момент установки (сценарий install time), а после этого сделать её подгружаемой по требованию (сценарий on-demand delivery). В этом варианте получаем 3 релиза приложения:</p><ul><li>релиз A содержит фичу как обычный gradle модуль;</li><li>релиз B содержит фичу как Dynamic module с dist-параметром install-time;</li><li>релиз C содержит фичу как Dynamic module с dist-параметром on-demand.</li></ul><p>В этом случае, при миграции с релиза B на релиз C фича не пропадёт с устройства пользователя. Однако, такой вариант миграции всё равно сохраняет риск потери фичи: если пользователь получит релиз A, не получит релиз B, а затем получит релиз C.</p><h3>2 вариант</h3><p>Очевидно, что проблему с неполучением промежуточного релиза можно решить увеличением количества этих промежуточных релизов. То есть между релизами A и C из первого варианта выпустить промежуточные: B1, B2, B3… Если пользователь не получил релиз B1, он сможет получить B2 или B3.</p><p>Этот вариант тоже не даст гарантированный результат сохранения фичи у всех пользователей. Однако, поможет уменьшить процент затронутых пользователь.</p><h3>3 вариант</h3><p>В этом варианте миграции можно запустить скачивание фичи в фоне при её отсутствии после получения обновления. Загрузка модуля не по запросу пользователя может завершиться обрабатываемой ошибкой:</p><p>exception com.google.android.play.core.splitinstall.SplitInstallException: Split Install Error(-7): Download not permitted under current device circumstances (e.g. in background). (<a href="https://developer.android.com/reference/com/google/android/play/core/splitinstall/model/SplitInstallErrorCode.html#ACCESS_DENIED">https://developer.android.com/reference/com/google/android/play/core/splitinstall/model/SplitInstallErrorCode.html#ACCESS_DENIED</a>).</p><p>Я не нашёл в официальной документации упоминание чётких критериев, когда фоновая загрузка может закончиться неудачей и попросить от пользователя явного подтверждения.</p><p>По личному опыту, я смог больше 10 раз поставить фичу в фоне, прежде чем получить ошибку (10 раз провести последовательность действий: ставить apk, скачивать в фоне фичу, удалять apk). Только после получения ошибки пришлось зайти в приложение и явно подтверждать скачивание. Вдобавок расходовать трафик на скачивание фичи без его ведома может быть плохим решением.</p><p>Этот вариант тоже не даёт гарантию. Потребуется явное согласие пользователя: нужно будет попросить его подтвердить скачивание. Это 4-й вариант.</p><h3>4 вариант</h3><p>В случае неудачной попытки скачать отсутствующую фичу в фоне показать пользователю уведомление с пояснением, что фича отсутствует на девайсе. Пользователь должен будет зайти в приложение и подтвердить скачивание. Однако, он может либо не увидеть нужное уведомление, либо отключить уведомления от приложения.</p><h3>5 вариант</h3><p>Google предоставляет возможность отложенной установки (deferred install). Такой вариант не даёт контроля над установкой. В официальной документации можно найти такую фразу: best-effort when the app is in the background. Практика показывает, что скачивание происходит при получении и установке следующего обновления. Таким образом, пользователь может пробыть без фичи какое-то время до получения обновления.</p><h3>6 вариант</h3><p>Если важно сохранить какой-то функционал у всех пользователей, можно ядро фичи оставить в приложении, а опциональную часть и тяжёлые ресурсы вынести в динамическую фичу, подгружаемую по требованию. В случае фичи Security news в состав ядра можно включить интерактор, который останется в приложении и продолжит мониторить и получать свежие новости. А всю логику, связанную с UI, — загружать отдельно по требованию.</p><p>Для каждой фичи должен проводиться отдельный анализ риска исчезновения на девайсах пользователей. И решение о том или ином сценарии миграции должно применяться исходя из результатов анализа.</p><h2>Результаты</h2><p>Выделение кода существующих фич в динамические модули может быть трудозатратным и требовать использования одного из предложенных выше сценариев миграции. Безусловно, новые фичи разрабатывать, как динамические модули, зачастую бывает проще. Однако, выделение уже существующих фич может существенно уменьшить объём приложения приложения.</p><p>Стоить отметить, что Dynamic delivery возможен только с использованием AppBundle, который сам по себе даёт хорошую оптимизацию. В нашем случае переход на AppBundle помог уменьшить размер приложения на разных устройствах в среднем на 16%.</p><p>Дальнейшее выделение динамических фич из приложения поможет больше сократить размер. Приложение можно распаковать и оценить ожидаемый результат. Можно оптимизировать размеры:</p><ul><li>dex-файлов вынесением части кода в динамические модули (в том числе вынесением больших используемых библиотек, которые нужны только этой фиче);</li><li>папок res и assets вынесением картинок и других файлов в динамические модули;</li><li>папки lib (например, тяжёлые нативные .so-файлы);</li><li>бинарных ресурсов вынесением большого количества строк и идентификаторов в динамические модули.</li></ul><p>Выбор функционала, который следует превратить в динамические модули, может быть основан не только на потенциальной выгоде по объёму, но и на его популярности или на критериях доступности. Например, если какой-то набор фич доступен только после покупки лицензии или активации подписки, его можно вынести из основного приложения и предлагать устанавливать только после перехода в платный режим.</p><p>Следует помнить, что вынесение определённых фич может негативно отразиться на конверсиях в покупки, подписки и так далее.</p><h2>Заключение</h2><p>Dynamic delivery предоставляет возможность лучше контролировать размер приложения, за счёт возможности скачать те или иные фичи после установки по желанию пользователя. Прежде чем выделять код в подгружаемые модули, нужно проанализировать целесообразность и трудозатраты для той или иной фичи.</p><p>Описанная в статье многомодульная архитектура может упростить вам работу с динамическими модулями, а предложенные сценарии миграции — минимизировать возможные негативные риски.</p><p>Надеюсь, статья была полезна для вас. Делитесь в комментариях своими результатами и мнениями об этой возможности от Google.</p><h2>Дополнительные материалы</h2><ul><li><a href="https://developer.android.com/guide/playcore/feature-delivery">Инструкция к Dynamic Delivery;</a></li><li><a href="https://github.com/googlecodelabs/android-dynamic-features">Codelabs Android Dynamic features;</a></li><li>Dynamic Delivery в многомодульных проектах (части<a href="https://habr.com/ru/company/badoo/blog/489434/"> 1</a> и<a href="https://habr.com/ru/company/badoo/blog/489438/"> 2</a>);</li><li><a href="https://habr.com/ru/post/279125/">Dagger 2. Основы, создание графа зависимостей, Scopes;</a></li><li><a href="https://habr.com/ru/company/kaspersky/blog/520766/">Ещё раз про многомодульность Android-приложений;</a></li><li><a href="https://kas.pr/mobile-dynamicdelivery-azamat-tproger">Присоединиться к мобильной команде «Лаборатории Касперского».</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Битва титанов: Java vs Kotlin</title>
      <link>https://tproger.ru/articles/bitva-titanov-java-vs-kotlin</link>
      <comments>https://tproger.ru/articles/bitva-titanov-java-vs-kotlin?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Мария Кривоченко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bitva-titanov-java-vs-kotlin</guid>
      <description><![CDATA[<p>Разберём, какой язык программирования подходит для новичков, опытных программистов и бизнеса — Kotlin или Java.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bitva-titanov-java-vs-kotlin">Битва титанов: Java vs Kotlin</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 07 Oct 2022 13:30:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Один из старейших языков программирования Java и один из наиболее молодых Kotlin — активно используются для мобильной разработки. Но они также подходят для создания десктопных и серверных решений. Главный разработчик Группы «Иннотех» Владимир Полховцев сравнивает двух гигантов Android-разработки.</p><p>Java, по мнению <a href="https://aws.amazon.com/ru/blogs/opensource/sustainability-with-rust/">Amazon</a>, один из оптимальных по энергопотреблению и времени выполнения языков программирования. Он зарекомендовал себя для серверной разработки, на тех платформах, где может работать виртуальная машина. Не зря же его называют WORA (Write Once and Run Anywhere — «Напиши один раз, запускай где угодно»). Но кроме того, его применяют для разработки игр, облачных вычислений, больших данных, искусственного интеллекта и интернета вещей.</p><p>Кто же ему наступает на пятки и пробует выбить из основных сегментов? Изначальный клон Java под названием Kotlin. Авторы хотели улучшить типобезопасность по сравнению с прародителем и сделать язык более простым, чем Scala.</p><p>В мае 2017 года Google объявил, что язык программирования Kotlin теперь является предпочтительным языком для разработчиков приложений для Android. Это стало признанием отрасли.</p><p>Google оценивает, что 70% из 1 000 лучших приложений в Play Store написаны на Kotlin. Также на нём сделаны Maps, Play, Drive. Однако этот язык программирования используют и для бэкенд-разработки, например, он доступен в Spring Framework.</p><p>Рассмотрим эти два популярных языка с разных аспектов для новичков, опытных программистов и бизнеса. Я приведу релевантные, на мой взгляд, факты и умозаключения, а лучшего предлагаю выбрать читателю.</p><h2>Для новичков</h2><p>Новичкам важны низкий порог вхождения в язык программирования, а также прощение ошибок из-за неопытности и общность технологической базы. Строгость языковых конструкций может сыграть в негативную сторону.</p><p>К примеру, новичку поставили задачу написать и backend server, и android-приложение, обращающееся к нему. Какие технологии для этой задачи необходимо будет изучить, чтобы выполнить задачу на Java и Kotlin?! На Java и Kotlin необходимо знать сам язык, принципы Rest взаимодействия, Android-платформу.</p><p>Минимальные специфичные для Java технологии, которые будут отличаться от Kotlin, — Spring Boot, Retrofit. Чтобы то же самое сделать на Kotlin, нужно изучить только фреймворк Ktor в дополнение к общему стеку.</p><h3>Kotlin</h3><p>+ официальный язык для Android;</p><p>+ кросс-платформенность: можно писать backend-, Android-, iOS- и веб-приложения, создавать IoT-решения;</p><p>+ де-факто стандарт разработки и в нём много синтаксического «сахара»;</p><p>+ более лаконичен и малословен, что позитивно влияет на читабельность;</p><p>+ более консистентен при построении межплатформенного взаимодействия.</p><h3>Java</h3><p>+ кросс-платформенность: мобильные и серверные приложения, работа с AI и IoT;</p><p><b>−</b> не прощает ошибок: забыл запятую, и всё посыпалось.</p><h2>Для опытных разработчиков</h2><p>Опытные программисты смотрят на скорость выполнения кода, возможности синтаксиса и актуальность версий. Чем чаще обновляются версии, тем быстрее исправляются баги и добавляется новая функциональность. А значит, язык развивается и соответствует современным требованиям.</p><p>Например, разработчикам передали макеты приложения в Figma. Им нужно создать подходящий код, чтобы дизайн превратился в полноценный продукт. Для ускорения и упрощения разработки нужно выбирать наиболее безопасный и быстрый в плане компиляции язык.</p><h3>Kotlin</h3><p>+ совместимость с Java;</p><p>+ большая безопасность;</p><p>− считается молодым языком программирования с «детскими» болячками.</p><h3>Java</h3><p>+ сильное сообщество;</p><p>− <a href="https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d">анализ</a> 2016 года давал преимущество Java над Kotlin в 12–15% для чистых сборок. В текущем году <a href="https://www.baeldung.com/kotlin/kotlin-java-performance">анализ</a> говорит, что быстродействие сопоставимо;</p><p>− требует больше памяти.</p><h2>Для бизнес-процессов</h2><p>Для бизнеса важна скорость разработки и внедрения создаваемых решений. Кроме того, приоритетно экономить бюджет на поддержке. Чем меньше строк кода нужно писать, тем быстрее будет закончен проект. Кроме того, требуется универсальность языка, чтобы разработчик мог писать как серверные, так и мобильные или десктопные приложения.</p><p>Например, для каждой страны должны быть создана собственная версия приложения с учётом особенностей законодательной базы. При этом запустить продукт нужно одновременно на всех рынках в короткие сроки. Должно быть достаточно команд разработки и тестирования, а также возможность быстро обучить новых ИТ-специалистов для локальных офисов.</p><h3>Kotlin</h3><p>+ возможность автоматической конвертации в Java и обратно;</p><p>+ классная поддержка языковых в фич в IDE экосистемы JetBrains;</p><p>− более 3 600 соискателей в Москве;</p><p>− мало литературы и обучающих курсов.</p><h3>Java</h3><p>+ более 42 400 соискателей в Москве;</p><p>− платная коммерческая лицензия начиная с 11 версии.</p>]]></content:encoded>
    </item>
    <item>
      <title>Коллекции в Kotlin: знакомство и основные функции</title>
      <link>https://tproger.ru/articles/kollekcii-v-kotlin-znakomstvo-i-osnovnye-funkcii</link>
      <comments>https://tproger.ru/articles/kollekcii-v-kotlin-znakomstvo-i-osnovnye-funkcii?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Azamat Nurkhojayev]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kollekcii-v-kotlin-znakomstvo-i-osnovnye-funkcii</guid>
      <description><![CDATA[<p>Зачем нужны коллекции в Kotlin — List, Set и Map — и как они работают. Как создать редактируемые классы MutableList, MutableSet и MutableMap.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kollekcii-v-kotlin-znakomstvo-i-osnovnye-funkcii">Коллекции в Kotlin: знакомство и основные функции</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 22 Jul 2022 07:36:28 GMT</pubDate>
      <content:encoded><![CDATA[<p>Kotlin — это статически типизированный, объектно-ориентированный язык программирования, работающий поверх JVM (Java Virtual Machine) и разработанный компанией JetBrains.</p><p>Kotlin можно использовать везде, где работает Java — а это бэкенд, веб-приложения (как серверная часть, так и интерфейс), десктопные приложения, приложения под Android.</p><h2>Что же такое коллекция?</h2><p>Коллекция — это классы-дженерики. Коллекции используются в программировании каждый день.</p><p>Коллекции в Kotlin те же самые, что на Java, но с расширением. При создании объекта он либо явно указывается, либо компилятор сам выводит тип составляющих коллекцию объектов.</p><p>Для чего же необходимы коллекции? Для того, чтобы облегчить хранение данных.</p><h2>Виды коллекций</h2><p>В Kotlin существуют три основных типа коллекций: List, Set и Map.</p><p>List хранит и отслеживает позицию элементов. Эта коллекция знает, в какой позиции списка находится тот или иной элемент. Несколько элементов List могут содержать ссылки на один объект.</p><p>Set не разрешает дубликаты и не отслеживает порядок, в котором хранятся значения. Коллекция Set не может содержать несколько элементов, ссылающихся на один и тот же объект, или несколько элементов, ссылающихся на два объекта, которые считаются равными.</p><p>Map использует пары «ключ-значение». Этот тип коллекции знает, какое значение связано с заданным ключом.</p><p>Два ключа могут ссылаться на один объект, но дубликаты ключей невозможны. Хотя ключи обычно представляют собой строковые имена (например, для составления списков свойств в формате»имя-значение«), ключом также может быть произвольный объект.</p><p>Простые коллекции являются неизменяемыми. Это значит, что после инициализации вы не сможете добавлять или удалять элементы из коллекции.</p><p>Для редактирования коллекций Kotlin представляет изменяемые версии подклассов MutableList, MutableSet и MutableMap.</p><h2>List и MutableList</h2><p>Для создания списка List в программе вызывается функция с именем listOf:</p><p>Компилятор определяет тип объекта, который должен содержаться в списке List, по типам всех значений, переданных при создании.</p><p>Также List можно создать явно, указав тип List:</p><p>Для получения элемента вводим:</p><p>Перебор всех элементов List выполняется следующим кодом:</p><p>Также можно проверить, содержит ли List ссылку на конкретный объект и получить индекс соответствующего элемента.</p><p>Если вам нужен список с возможностью обновления элементов, используйте MutableList.</p><p>Новые элементы добавляются в MutableList функцией add. При этом новый элемент добавляется в конец списка.</p><p>Если же вы хотите вставить значение в позицию с конкретным индексом, передайте индекс функции наряду со значением.</p><p>Есть два способа удаления значений из MutableList.</p><p>В первом способе вызывается функция remove, которой передается удаляемое значение. Например, следующий код проверяет, содержит ли список animals строку «Cow», после чего удаляет соответствующий элемент:</p><p>Второй способ основан на использовании функции removeAt для удаления значения с заданным индексом:</p><p>Если вы хотите обновить MutableList так, чтобы значение с конкретным индексом было заменено другим значением, это можно сделать при помощи функции set:</p><h3>Прочие функции MutableList:</h3><ol><li>sort — возвращает список List и сортирует содержимое MutableList в естественном порядке;</li><li>reverse — возвращает список List и переставляет элементы в обратном порядке;</li><li>shuffle — возвращает список List и сгенерирует случайную перестановку;</li><li>addAll — добавляет все элементы, хранящиеся в другой коллекции;</li><li>removeAll — удаляет элементы, входящие в другую коллекцию;</li><li>retainAll — оставляет все элементы, входящие в другую коллекцию, и удаляет все остальные;</li><li>clear — удаляет все элементы.</li></ol><h2>Set и MutableSet</h2><p>Если вам нужна коллекция, которая не допускает дублирования, используйте Set: неупорядоченную коллекцию без повторяющихся значений.</p><p>В отличие от List, множество Set не упорядочено и не может содержать повторяющихся значений.</p><p>В Set не может быть дубликатов: при попытке создания дублирующих элементов Set будет игнорировать их.</p><p>Для создания списка Set в программе вызывается функция с именем setOf:</p><p>Перебор элементов множества Set в цикле:</p><p>Функция contains возвращает true, если содержит элемент, и false в противном случае.</p><p>Множество Set неизменяемо — в него нельзя добавлять новые или удалять существующие значения. Для выполнения таких операций используется класс MutableSet.</p><h3>Функции MutableSet:</h3><ol><li>add — добляет элемент;</li><li>remove — удаляет элемент;</li><li>clear — удаление всех элементов;</li><li>функции addAll, removeAll и retainAll также могут использоваться для внесения массовых изменений в MutableSet (по аналогии с MutableList).</li></ol><h2>Map и MutableMap</h2><p>Коллекция Map работает как список свойств. Вы передаете ей ключ, а Map возвращает значение, связанное с этим ключом. Хотя ключи обычно имеют тип String, они могут быть объектами любого типа.</p><p>Каждый элемент Map состоит из двух объектов — ключа и значения. С каждым ключом связывается одно значение. В коллекции могут присутствовать повторяющиеся значения, но не повторяющиеся ключи.</p><p>Чтобы создать Map, вызовите функцию с именем mapOf и передайте ей пары «ключ-значение» для инициализации Map.</p><p>С Map чаще всего выполняются три операции: проверка наличия конкретного ключа или значения, выборка значения для заданного ключа и перебор всех элементов Map.</p><p>Для проверки наличия конкретного ключа или значения в Map используются его функции containsKey и containsValue:</p><p>Для получения значения, связанного с конкретным ключом, используются функции get и getValue. Если заданный ключ не существует, get возвращает null, а getValue вызывает исключение.</p><p>Также вы можете перебрать все элементы Map. Например, вот как цикл for используется для вывода всех пар «ключ-значение» в recipeMap:</p><p>Объект Map неизменяем, поэтому вы не сможете добавлять или удалять пары «ключ-значение», а также обновлять значение, хранящееся для заданного ключа. Для выполнения такой операции следует использовать класс MutableMap. Посмотрим, как он работает.</p><p>Давайте создадим MutableMap:</p><p>Для добавления элементов в MutableMap используется функция put:</p><p>Также в MutableMap можно добавить сразу несколько пар «ключ-значение» при помощи функции putAll:</p><p>Удаление элемента с ключом с помощью remove уничтожит все элементы с clear:</p><p>Еще можно удалить их таким способом:</p><p>Надеюсь, что вам была полезна эта статья, а я смог верно передать информацию о коллекциях в Kotlin, об основных видах коллекций и функциях.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое функции расширения Kotlin и где их правильно применять?</title>
      <link>https://tproger.ru/articles/chto-takoe-funkcii-rasshirenija-kotlin-i-gde-ih-pravilno-primenjat</link>
      <comments>https://tproger.ru/articles/chto-takoe-funkcii-rasshirenija-kotlin-i-gde-ih-pravilno-primenjat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Viacheslav Aksenov]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-funkcii-rasshirenija-kotlin-i-gde-ih-pravilno-primenjat</guid>
      <description><![CDATA[<p>Функции расширения Kotlin упрощают код в подходящих сценариях, но могут сделать его сложнее. Ключевые аспекты: случаи применения и ограничения этого приёма.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-funkcii-rasshirenija-kotlin-i-gde-ih-pravilno-primenjat">Что такое функции расширения Kotlin и где их правильно применять?</a>»</p>]]></description>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 25 Feb 2022 13:47:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Меня зовут Аксёнов Вячеслав, я профессиональный Java/Kotlin бэкенд разработчик в крупном энерпрайзе. В моей зоне ответственности – проектирование систем из набора сервисов и выстраивание сложной бизнес логики. Также время от времени я пишу свои пет проекты, некоторые из которых вы можете найти в моем github:</p><p>Уже больше года я использую преимущественно Kotlin для написания кода, и в этой статье хочу остановиться на одной из конструкций этого языка — функциях расширения. А также рассмотреть случаи, когда их использование может помочь, а когда сделает вашу жизнь только сложнее.</p><h2>Чем являются функции расширения Kotlin на самом деле</h2><p>По своей задумке, функция расширения Kotlin — это дополнительный метод для любого объекта, даже для потенциально несуществующего (нуллабельного). Этот инструмент является прямой реализацией переопределения методов паттерна проектирования декоратор. Благодаря удобному синтаксису пользоваться данной сахарной надстройкой в Kotlin очень просто.</p><p>Рассмотрим пример:</p><p>Обычный dto класс Book, у которого есть некий набор полей. И есть класс SomeService, в котором есть публичный метод для анализа книги. Предполагаем, что для анализа книги требуется форматированные данные из dto. Однако класс закрыт для расширения, возможно он лежит в сторонней библиотеке. С помощью функции расширения можно написать метод, который будет словно бы принадлежать данному классу. При том обратите внимание, что на этот метод можно повесить любой модификатор доступа — в данном случае private.</p><p>Если скомпилировать данный код и разобрать байткод в Java, то конструкция с методом будет выглядеть следующим образом:</p><p>Таким образом, на собственном опыте мы увидели, что функции расширения для JVM являются статическими final методами. Но у каждого инструмента есть спектр задач, для решения которых он подходит лучше всего. К примеру забивать гвозди бутербродом будет очень некомфортно, бутерброды нужно кушать. Давайте определимся, в каких задачах функции расширения показывают себя лучше всего и действительно облегчают жизнь.</p><h2>Расширение API класса, который вам не принадлежит</h2><p>К примеру класс чужой библиотеки имеет крайне неудачную структуру, а вам в коде постоянно нужно залезать в глубину этой структуры. Написание собственной модели будет слишком дорогим решением проблемы, но функции расширения будут весьма кстати:</p><h2>Конвертация моделей из одной в другую</h2><p>Потенциально опасное использование, но если держать в голове следующие правила, то очень даже удобное.</p><p>Обратите внимание на нейминг функций. Следует их начинать с непопулярных названий методов, либо делать конвертеры приватными в области видимости только тех мест, где они нужны. Иначе можно замусорить весь контекст проекта. Взгляните на утрированный пример:</p><figure><img src="https://media.tproger.ru/uploads/2022/02/IydseHhaP1RRAGISU5o7L5wy3r62-lk92n2f.jpeg" alt="" /></figure><h2>Расширение возможностей любого класса, но в ограниченной области видимости</h2><p>Представьте, что есть класс для которого нужно написать сложный метод, который будет использоваться только в одном сервисе. Это вполне можно сделать с помощью функции расширения Kotlin, главное — сделать расширение приватным.</p><p>В данном примере внутри функции расширения Kotlin используется поле сервиса — thirdPartyClient, из которого получаются некие мета данные. Это вполне допустимое использование функции расширения, но следует быть предельно осторожным если вы помещаете внутрь такого метода любое внешнее поле! Для этого должна быть веская причина!</p><h2>Расширение функционала дженериков</h2><p>Да, Kotln позволяет делать даже такое, и иногда это действительно полезно. К примеру вам может потребоваться расширить API всех наследников некоего класса, но без добавления метода в этот класс.</p><p>Будьте внимательны, если имя этого метода будет слишком общим, вы рискуете очень сильно засорить контекст IDE в местах использования этого метода.</p><h2>Для чего никогда нельзя применять функции расширения</h2><p>Запомните, если вы будете использовать функции расширения для следующих целей, то либо вы, либо будущие разработчики в вашей команде рано или поздно споткнутся об этот код и будут страдать.</p><ul><li>Первое. Бесконтрольное расширение любого функционала вместо написание обычного метода на глобальном уровне очень сильно засорит контекст IDE и станет большой болью в поиске всех мест, где был расширен какой-то класс.</li><li>Второе. Если размер функции расширения Kotlin превышает 5 строк, значит настало время писать обычный метод.</li></ul><p>Иначе вы рискуете рано или поздно столкнуться с потребностью зарефакторить такой метод, просто потому что поддерживать его без нарушения здравого смысла будет очень непросто.</p><p>И последнее. Никогда не меняйте глобальные параметры с помощью функций расширения. Иначе вы не сможете адекватно отследить в какой именно момент это сделали.</p><h2>В заключение.</h2><p>Функции расширения — удобный синтаксический сахар Kotlin, который позволяет использовать язык практически как угодно. Однако будьте бдительны и применяйте их только там, где они действительно упростят жизнь. Эти методы должны быть маленькими и решающими конкретную задачу, никто не намерен сделать cmd+click по методу и провалиться в ад с огромным количеством бизнес-логики.</p><p>Используйте их как вспомогательный инструмент и не злоупотребляйте их мощью ?</p>]]></content:encoded>
    </item>
    <item>
      <title>Переход с Java на Kotlin при создании мобильного приложения</title>
      <link>https://tproger.ru/articles/perehod-s-java-na-kotlin-pri-sozdanii-mobilnogo-prilozhenija</link>
      <comments>https://tproger.ru/articles/perehod-s-java-na-kotlin-pri-sozdanii-mobilnogo-prilozhenija?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Anastasia undefined]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/perehod-s-java-na-kotlin-pri-sozdanii-mobilnogo-prilozhenija</guid>
      <description><![CDATA[<p>Переход с Java на Kotlin при создании мобильного приложения требует учёта деталей миграции; рекомендации полезны разработчикам бэкенда.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/perehod-s-java-na-kotlin-pri-sozdanii-mobilnogo-prilozhenija">Переход с Java на Kotlin при создании мобильного приложения</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Гостевая публикация]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 09 Feb 2022 09:23:52 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мобильные приложения играют всё большую роль в ИТ-ландшафтах заказчиков и цифровизации экономики в целом. Логично, что предметные вопросы их разработки сегодня актуальны как никогда. В данном материале я расскажу, почему нужна миграция с Java на Kotlin при создании мобильного приложения. При этом какие-то детали будут полезны не только разработчикам под Android, но и тем, кто занимается миграцией бэкенда.</p><h2>Зачем нужен переход на Kotlin</h2><p>Стоит задуматься о переходе с Java на Kotlin, если вы постоянно пишите однотипный код и во время его исполнения сталкиваетесь с ошибками, на которые ранее мог бы указать компилятор, или в целом хотите повысить качество и читаемость исходников.</p><p>Kotlin сильно уменьшает количество кода, например, простой Java-объект (Plain Old Java Object), хранящий пять полей, займет примерно 96 строк кода. В то время как на Kotlin аналогичный Data-класс займёт всего одну строку, поскольку компилятор переопределит все нужные методы.</p><p>Кроме того, существует несколько серьёзных проблем, которые до сих пор есть в Java, но — внимание — уже решены в Kotlin! Вот некоторые из них:</p><ul><li>Nullability — в Java мы не знаем, возможен ли null в значении данного объекта (и нельзя запретить ему принимать null), из-за чего может случиться всем известная ошибка NullPointerException, поскольку имело место обращение к «нулевому» объекту.</li><li>Raw types — это generic-типы в Java без указания типа-параметра, использование которых может привести к heap<br />pollution — ситуации, когда переменная параметризованного типа хранит в себе объект, параметризованный другим типом. В результате может возникнуть ClassCastException в процессе исполнения программы — в Kotlin такие типы исключены.</li><li>Полноценные функциональные типы отсутствуют в Java в отличие от Kotlin.</li></ul><h2>Преимущества и дополнительные возможности Kotlin</h2><p>Kotlin относится к объектно-ориентированным языкам программирования, сочетая в себе черты функциональных языков, что отличает его от Java, на котором не получится без проблем писать в функциональном стиле. Если вы разрабатываете под Android, то, скорее всего, выберете Kotlin, так как этот язык теперь официально поддерживается и продвигается Google, всё реже можно найти примеры кода на Java.</p><p>Огромное преимущество Kotlin – наличие Coroutines, которые легко позволяют управлять потоками при асинхронном программировании. В Java аналогичный код получается более сложным, плохо читаемым и громоздким.</p><p>У Kotlin есть множество возможностей, самые примечательные из которых:</p><ul><li>Extension-функции или функции-расширения класса — делают код «чище», а в сочетании с автодополнением в IDE ускоряют разработку;</li><li>Data-классы хранят данные в лаконичном виде;</li><li>Лямбда-выражения и inline-функции — нужны для использования функций высшего порядка без потери производительности;</li><li>Object-классы позволяют с лёгкостью реализовать полезный паттерн проектирования Singleton;</li><li>Inline-функции с параметрами reified типа  позволяют во многих случаях избавиться от рефлексии, которая может влиять на производительность (на старых версиях компиляторов).</li></ul><h2>Особенности миграции</h2><p>Есть некоторые особенности, которые стоит учитывать при переходе.</p><p>Во-первых, в Kotlin нет привычных методов с ключевым словом static, для этого используется «companion object» в теле класса либо package level-функции. Аннотация @JvmStatic необходима тогда, когда мы хотим вызвать «companion object» — методы из Java таким же образом, каким бы вызывали любой другой static-метод в Java.</p><p>Во-вторых, Kotlin-файл может одновременно содержать константы, несколько классов, extension-функции, что разительно отличается от возможностей Java-файла, а это значит, что вам, скорее всего, придется поменять свой привычный способ организации кода и функций по классам.</p><p>В-третьих, в Kotlin существуют неизменяемые immutable-коллекции, которые более безопасно использовать при многопоточности, поэтому вы, вероятно, захотите переписать часть кода на них, а лучше вообще на Coroutines. При этом работать с коллекциями удобно в функциональном стиле.</p><p>Специальной подготовки непосредственно данных в БД не требуется. Если вы заменяете обычные Java-объекты на Data-классы, то необходимо проверить, что логика переопределенных вами ранее методов toString(), equlas() и hashCode() соответствует той, что по умолчанию будет сгенерирована в этих методах в Kotlin.</p><h2>Необходимые шаги по переходу</h2><ul><li>Выделите основные участки кода, которые в первую очередь необходимо мигрировать. Выберите места, где максимально сократится код или значительно повысится читаемость и безопасность. Лучше начинать не с core-модулей, а с верхних слоев приложения: из-за того что Kotlin проектировался с учетом необходимости взаимодействия с языком Java, а не наоборот, лучше наследоваться от Java-классов, чем в Java наследоваться от Kotlin-классов.</li><li>Для упрощения перехода используйте встроенные средства конвертации Java-кода в Kotlin-код в IDE<br />Intellij Idea или Android Studio, но не забывайте проверять полученный код.</li><li>Начинайте писать всю новую функциональность только на Kotlin и по возможности дорабатывайте старый код тоже на нём.</li><li>Постепенно углубляйте миграцию — переписывайте внутренние, абстрактные слои до тех пор, пока Java-кода не останется в проекте.</li></ul><h2>Возможные проблемы и уязвимости при переходе на Kotlin</h2><p>Kotlin создавался как стопроцентно совместимый с Java — это значит, что проблемы при переходе будут минимальными.</p><p>Самая распространённая проблема связана с nullability, ведь когда мы вызываем Java-код из Kotlin-кода, то используем платформенные типы, которые не дают никакой информации о допустимости null-значений, а компилятор в свою очередь не делает дополнительной проверки на null. Так мы можем вызвать какой-нибудь метод на возвращённом нам объекте и получить на этапе исполнения кода описанную ранее NullPointerException.</p><p>Если в исходном проекте вы использовали популярный плагин Lombok для автоматической генерации методов (getters, setters и так далее), то вам придётся полностью от него отказаться, ведь Kotlin и так выполняет большинство функций Lombok, и вместе работать они не смогут. Полная замена Lombok может привести к масштабным изменениям в коде.</p><p>Если вы мигрируете проект, реализованный на Spring Boot, необходимо учитывать, что классы в Kotlin по умолчанию «закрыты» для наследования. Если не «открыть» классы с аннотациями типа @Configuration и @Service, это приведёт к ошибкам при запуске.</p><p>Кроме того, могут возникнуть ошибки при недостаточном понимании устройства языка, в редких случаях довольно, казалось бы, простой код ведет себя непредсказуемым образом. Рекомендую ознакомиться с Kotlin Puzzlers на Github, где вы увидите неочевидные головоломки в Kotlin и их решения. Это поможет лучше узнать язык и защитить себя от подобных проблем.</p><h2>Пример реального кейса</h2><p>На одном из проектов, где я выступала в роли backend-разработчика, необходимо было мигрировать высоконагруженную интеграционную платформу с Java на Kotlin. Отмечу, что особых проблем с переходом не возникало, несмотря на большой объем исходного кода.</p><p>Система сейчас успешно работает в продуктиве — за всё время развития и поддержки доля ошибок, связанных с Kotlin или взаимодействием Java и Kotlin, ничтожно мала. По состоянию на 2020 год все ключевые модули были переписаны, что составляло 60–70% от общего кода. Стоит также отметить, что переход на Kotlin происходил в начале развития этого языка программирования, задолго до пика популярности, что не помешало нам успешно использовать его в продуктиве.</p>]]></content:encoded>
    </item>
    <item>
      <title>Шестой раунд битвы языков программирования 2021</title>
      <link>https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2021</link>
      <comments>https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2021?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2021</guid>
      <description><![CDATA[<p>В этот раз за звание лучшего языка программирования 2021 будут соревноваться: C++ vs. C#, Kotlin vs. Python.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2021">Шестой раунд битвы языков программирования 2021</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Лучший язык 2021]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 19 Dec 2021 08:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>По итогам пятого раунда в битве за звание лучшего языка программирования 2021 в полуфинал выходят Java и Go, которые обошли по голосам C и TypeScript соответственно. Результаты голосования <a href="https://tproger.ru/articles/pjatyj-raund-bitvy-jazykov-programmirovanija-2021/">по ссылке</a>.</p><p>В решающем раунде перед полуфиналом батла схлестнутся:</p><ul><li>C++ vs. C#</li><li>Kotlin vs. Python</li></ul><figure><img src="https://media.tproger.ru/uploads/2021/12/Frame-13-3.png" alt="" /></figure><p>Выбирайте язык, основываясь на личных предпочтениях. Голосование в шестом раунде остановится 20 декабря 2021 года в 11:00 по Москве.</p>]]></content:encoded>
    </item>
    <item>
      <title>Четвёртый раунд битвы языков программирования 2021</title>
      <link>https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2021</link>
      <comments>https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2021?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2021</guid>
      <description><![CDATA[<p>В этом раунде на лучший язык программирования 2021 претендуют такие кандидаты: JavaScript vs. C++, а также Ruby vs. Kotlin.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2021">Четвёртый раунд битвы языков программирования 2021</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Лучший язык 2021]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Dec 2021 07:59:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вчера завершился третий раунд батла, по итогам которого язык Java в десять раз превзошёл оппонента в лице Visual Basic, а Go утопил Swift. Результаты можно посмотреть <a href="https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-2021/">по ссылке</a>.</p><p>В четвёртом раунде за звание лучшего языка программирования 2021 поборются:</p><ul><li>JavaScript vs. C++</li><li>Ruby vs. Kotlin</li></ul><figure><img src="https://media.tproger.ru/uploads/2021/12/Frame-13-1-1.png" alt="" /></figure><p>Слушайте сердце и выбирайте язык, исходя из личной симпатии. Голосование в четвёртом раунде будет завершено 18 декабря 2021 года в 11:00 по Москве.</p>]]></content:encoded>
    </item>
    <item>
      <title>Баттл языков программирования 2021 стартует уже завтра</title>
      <link>https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra</link>
      <comments>https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra</guid>
      <description><![CDATA[<p>Отбросьте результаты исследований TIOBE, ведь в нашем баттле именно вы выбираете лучший язык программирования 2021.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra">Баттл языков программирования 2021 стартует уже завтра</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2021]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Dec 2021 08:12:38 GMT</pubDate>
      <content:encoded><![CDATA[<p>Лучший язык программирования в 2021 году — это Java или Python? Совсем недавно рейтинг TIOBE взбудоражил всё IT-сообщество, ведь именно Python потеснил извечных лидеров в виде Java и C.</p><p>Но давайте отвлечёмся от официальной статистики и узнаем, какие языки предпочитаете именно вы! Завтра стартует баттл языков программирования 2021. Правила просты:</p><ol><li>Всего участвует 16 языков программирования.</li><li>Каждый день соревнуются две пары.</li><li>На возможность проголосовать за любимый язык отводится 24 часа.</li><li>Пары составляются рандомно.</li><li>Выбирайте тот язык, который субъективно нравится вам больше.</li><li>В финале мы определим победителей — языки которые заняли первое, второе и третье место.</li><li>Старт — 14 декабря, финал — 21 декабря.</li></ol><p>Так выглядит изначальная турнирная таблица:</p><figure><img src="https://media.tproger.ru/uploads/2021/12/languages_battle_2021_announce.png" alt="" /></figure><p>А вот как мы <a href="https://tproger.ru/tag/toplang2020/">выбирали лучший язык программирования</a> в прошлом году.</p><p>Подписывайтесь на уведомления на сайте, чтобы быть в курсе лидеров и новых голосований.</p><p>Результаты баттла можно посмотреть по <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-zavershilsja/">ссылке</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Сравнение Kotlin и Java при написания backend-приложений</title>
      <link>https://tproger.ru/articles/sravnenie-kotlin-i-java-pri-napisanija-backend-prilozhenij</link>
      <comments>https://tproger.ru/articles/sravnenie-kotlin-i-java-pri-napisanija-backend-prilozhenij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Viacheslav Aksenov]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sravnenie-kotlin-i-java-pri-napisanija-backend-prilozhenij</guid>
      <description><![CDATA[<p>Всем привет, меня зовут Вячеслав Аксёнов. В этой статье я расскажу, как пересел на Kotlin после Java 8/11 и в чём его преимущества.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sravnenie-kotlin-i-java-pri-napisanija-backend-prilozhenij">Сравнение Kotlin и Java при написания backend-приложений</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 10 Aug 2021 12:43:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Я разработчик больших и маленьких бэкенд систем в крупных компаниях. Приходилось писать как отдельные сервисы, которые общаются с другими бэкенд сервисами разного уровня глубины, так и сервисы, работающие в связке с фронтом. Раньше для написания кода я использовал  Java + Spring.</p><p>А после поменял проект и столкнулся с Kotlin именно в бэкенде. И хочу поделиться преимуществами Kotlin отличиями Kotlin от Java в абсолютно одинаковых задачах.</p><p>Забегая вперёд скажу, что колоссальной разницы, из-за которой нужно срочно переписывать всё на Kotlin, нет. Но есть огромное количество фич, которые делают разработку быстрее, проще и безопаснее. На текущем проекте весь новый функционал мы с командой пишем на Kotlin, параллельно переписывая старые куски Java-кода n-летней давности. На Kotlin эти куски получаются гораздо более читабельными и короткими.</p><h2>Простота интеграции в уже существующий проект, написанный на Java</h2><p>Если вы только присматриваетесь к Kotlin для бэкенда, то учитывайте что в окружении, которое запускает ваш проект на Java 8, можно без танцев с бубном запустить скомпилированный проект на Kotlin. Да, на той же jvm, на том же окружении и с минимумом усилий.</p><p>Для меня было открытием, что даже в рамках одного приложения могут быть классы на Java и Kotlin. Вся магия происходит на этапе компиляции. В зависимости от настроек, можно указать что собирать первым: Kotlin-классы или Java-классы.</p><p>Сейчас доступна компиляция Kotlin-исходников в байткод от Java LTS – 8, 11 и (пока экспериментально) 16.</p><h2>Инициализация и логика работы с DTO классами</h2><p>Пример избитый, но максимально наглядный.</p><p>И теперь то же самое на Java:</p><p>Мне кажется, здесь даже комментарии излишни.</p><p>Указатели data class в Kotlin по-умолчанию подразумевают наличие getter, setter (для var полей), equals, hashcode, toString для всех полей. При желании можно переопределить каждый из этих методов по своему, но требуется это крайне редко.</p><h2>Null safety</h2><p>В Kotlin требуется явно указывать, может ли тот или иной метод вернуть null или нет. Таким образом можно считать, что все данные уже обернуты в аналог Optional. И NullPointerException будет вами встречаться настолько редко, что вы успеете по нему соскучиться.</p><h2>Выделение основного конструктора</h2><p>Суть в чём: есть основной (Primary) конструктор и вспомогательные (Secondary). Вспомогательные обязаны вызывать основной как конструктор родительского класса.</p><h2>Явное объявление изменяемых и неизменяемых полей</h2><p>Следующее преимущество: в Kotlin получаются довольно простые и элегантные конструкции. Если требуется, чтобы поле dto можно было менять, то для его объявления используется var. Тогда будет создан метод setter и поле не будет final.</p><p>А если нужно сделать поле иммутабельным, для объявления следует использовать val. Смотрится очень красиво и просто. Плюс не нужно следить за вспомогательными методами.</p><p>Пример: поля цвета и роста можно изменить после создания, а имя — только при инициализации объекта:</p><h2>Immutable коллекции по умолчанию.</h2><p>То, что появилось в Java несколько позже, уже давно было в Kotlin — создание коллекций сразу иммутабельными.</p><p>Любые изменения с этими коллекциями будут создавать новую иммутабельную коллекцию после преобразования:</p><p>Но изменить какой-то элемент отдельно не получится. Для классических мутабельных коллекций используется явно изменяемые аналоги:</p><h2>Работа со сложными классами методами примитивов</h2><p>Преимущество Kotlin, которому не перестаю радоваться — возможность использовать операторы для базовых операций к сложным классам. Если нужно сложить BigDecimal числа — берёшь и пишешь их через плюс. Не нужно явно вызывать метод у первого слагаемого.</p><p>То же самое с массивами: хочешь удалить элемент из мутабельного массива – пишешь массив минус этот элемент. И если элемент присутствует, то он удаляется</p><p>В Java нужно вызывать специальный метод:</p><p>Аналогичные приёмы работают и с более сложными классами, например с коллекциями:</p><h2>Возможно писать однострочные методы действительно в одну строку</h2><p>Если метод простой и состоит из одной операции или из цепочки операций, записанных в одну строчку, то не обязательно писать фигурные скобки и return. Прямо пишешь:</p><p>Вместо Java варианта:</p><h2>Контекстные функции.</h2><p>Интересные движения в сторону функционального программирования в духе выделения контекста: лямбды можно вертеть как хочешь.</p><p>Есть функции let, apply, also, with, run. Из-за их обилия вначале возникает вопрос: что подходит для конкретного кейса. Но когда привыкаешь, становится непонятно как раньше жил без них.</p><p>Простой пример: взять результат и как-то его обработать:</p><p>Либо инициализировать объект и дополнительно проинициализировать его var поля:</p><p>Кто-то может сказать, что это сахар сахарный и будет прав. Но по себе скажу: если большое количество шаблонных вещей входит в язык, и о них не нужно постоянно думать — процесс разработки становится проще, количество ошибок — меньше. Но нужно чаще думать про код стайл, потому что без него навертеть можно многое 🙂</p><p>Сейчас я по-прежнему продолжаю писать и видеть код на Java, но в 99% случаев это связано с образовательными программами, в которых принимаю участие: профессия Java разработчика на Hexlet и различные вебинары для онлайн школ и курсов. Так что я постоянно сравниваю два языка и радуюсь, что рабочие проекты пишу на Kotlin.</p><p>Советую попробовать каждому — как минимум на pet-проекте чтобы понять подходят вам парадигмы Kotlin или нет.</p>]]></content:encoded>
    </item>
    <item>
      <title>Google наконец-то выпустила Jetpack Compose. Этот инструмент ждали 2 года</title>
      <link>https://tproger.ru/news/google-nakonec-to-vypustila-jetpack-compose-jetot-instrument-anonsirovali-2-goda-nazad</link>
      <comments>https://tproger.ru/news/google-nakonec-to-vypustila-jetpack-compose-jetot-instrument-anonsirovali-2-goda-nazad?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Андрей Борисов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/google-nakonec-to-vypustila-jetpack-compose-jetot-instrument-anonsirovali-2-goda-nazad</guid>
      <description><![CDATA[<p>Google выпустила стабильную версию Jetpack Compose 1.0 — это инструмент, который упростит разработчикам создание интерфейсов в Android с помощью Kotlin.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/google-nakonec-to-vypustila-jetpack-compose-jetot-instrument-anonsirovali-2-goda-nazad">Google наконец-то выпустила Jetpack Compose. Этот инструмент ждали 2 года</a>»</p>]]></description>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 29 Jul 2021 06:37:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Google <a href="https://android-developers.googleblog.com/2021/07/jetpack-compose-announcement.html">выпустила</a> стабильную версию Jetpack Compose 1.0 — это инструмент, который упростит разработчикам создание интерфейсов в Android с помощью Kotlin.</p><p>Jetpack Compose — это аналог SwiftUI для Android. Правда, свой UI-инструмент Google анонсировала раньше — ещё два года назад — но с выпуском затянула.</p><p>Разработчики ждали стабильную версию, чтобы интегрировать Jetpack Compose в свои приложения, хотя бета 1.0 вышла ещё в марте.</p><h2>Что полезного</h2><p>Jetpack Compose позволяет программисту удобно описывать интерфейсы программ — это экономит время на разработку и сопровождение.</p><p>В Jetpack Preview есть две новых полезных  фичи:</p><ul><li><b>Compose Preview</b> визуализирует пользовательские интерфейсы в различных состояниях: в светлой и темной темах, с разными настройками шрифта и так далее.</li><li><b>Deploy Preview </b>позволяет пушить обновлённый код без необходимости перезапускать приложение.</li></ul><figure><img src="https://media.tproger.ru/uploads/2021/07/image-78.png" alt="" /><figcaption>Так работает Deploy Preview</figcaption></figure><h2>Что удобно</h2><p>Фреймворк позволяет интегрировать Jetpack Compose в проекты любым удобным способом. Для этого не нужно переписывать код или совершать какие-то большие переходы.</p><h2>Как начать работу</h2><p>Чтобы начать работу с Jetpack Compose, нужно обновить Android Studio Arctic Fox.</p><p>Подробная инструкция о том, как начать работу с Jetpack Compose, <a href="https://developer.android.com/courses/pathways/compose">описана на сайте Android Developers</a>.</p><h2>Каких функций ждать</h2><p>Google выложила <a href="https://developer.android.com/jetpack/androidx/compose-roadmap">дорожную карту разработки Jetpack Compose</a>.</p><p>В следующем релизе обещают завезти виджеты и поддержку WearOS.</p><p>Источник: <a href="https://www.androidpolice.com/2021/07/28/googles-vision-of-android-development-is-finally-realized-with-jetpack-compose-1-0/">AndroidPolice</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Кроссплатформа для мобильного приложения: как ускорить и удешевить разработку?</title>
      <link>https://tproger.ru/articles/krossplatforma-dlja-mobilnogo-prilozhenija-kak-uskorit-i-udeshevit-razrabotku</link>
      <comments>https://tproger.ru/articles/krossplatforma-dlja-mobilnogo-prilozhenija-kak-uskorit-i-udeshevit-razrabotku?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Гладков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/krossplatforma-dlja-mobilnogo-prilozhenija-kak-uskorit-i-udeshevit-razrabotku</guid>
      <description><![CDATA[<p>Расскажу о том, как кроссплатформенная технология позволяет сократить расходы и повысить эффективность разработки мобильного приложения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/krossplatforma-dlja-mobilnogo-prilozhenija-kak-uskorit-i-udeshevit-razrabotku">Кроссплатформа для мобильного приложения: как ускорить и удешевить разработку?</a>»</p>]]></description>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 28 Jul 2021 12:42:32 GMT</pubDate>
      <content:encoded><![CDATA[<p>Покупки в самых разных областях сегодня происходят онлайн. А пользовательская активность перетекает с сайтов в мобильные приложения. Поэтому часто основной упор в разработке делается на мобильные платформы.</p><p>У компании уже были мобильные приложения для iOS и Android, но дублирование логики домена, устаревший код и огромные затраты на поддержку обеих платформ создавали множество проблем. Чтобы повысить управляемость, гибкость и рентабельность, мы решили всё переписать. Специалистов у нас было меньше, чем обычно в команде разработчиков мобильных приложений в нашей отрасли, а это означало, что внедрение изменений займёт больше времени.</p><p>Представлялось два варианта ускорить процесс:</p><ul><li>нанять больше людей;</li><li>использовать технологию, которая позволит объединить платформы iOS и Android.</li></ul><p>Мы выбрали второй вариант и начали искать подходящую технологию, которая обеспечивала бы безопасность, качество и стабильность наших приложений. Потребовалось время, чтобы найти кроссплатформенное решение с интеграцией пользовательского интерфейса. Нужен был разумный подход, и мы рассматривали Flutter и React Native.</p><p>React Native уже использовался в других приложениях, поэтому эта технология в первую очередь попала в число претендентов. Но React Native не оправдал наших ожиданий из-за качества итогового продукта. Можно было бы создать приложение с использованием Flutter, но возникли проблемы:</p><ul><li>на тот момент было мало специалистов, которые знают Dart;</li><li>уже была команда, которая писала нативно;</li><li>Android и iOS регулярно выпускают новые версии и UX-паттерны, и между нативным выпуском и его реализацией Flutter будет разрыв.</li></ul><p>Дальнейшие исследования показали, что лучше не использовать общий пользовательский интерфейс между мобильными платформами. Android и iOS имеют разные принципы руководства пользовательским интерфейсом, и для поддержки общего UI иногда требуется больше времени, чем занимает отдельная разработка.</p><p>Требовалось кроссплатформенное решение. Узнав про Kotlin Multiplatform Mobile, мы поняли, что это тот самый подход. Технология исключает дублирование бизнес-логики, обеспечивая производительность и безопасность собственного пользовательского интерфейса.</p><h2>Использование Kotlin в продукте</h2><p>Тестирование подхода KMM мы начали в тех частях приложения, которые использовались реже — это, например, соглашения с клиентами и формы обратной связи. Важно было понять, не возникнут ли проблемы, связанные с библиотекой.</p><p>В нашем приложении есть два типа запросов: с авторизацией и без. Запросы с авторизаций — самая сложная часть, поэтому мы начали экспериментировать с запросами, которые не требовали ни авторизации, ни работы с базой данных. В процессе переписывания модулей с самого начала разрабатывались новые пользовательские сценарии с KMM. Но и существующие были перенесены в KMM.</p><p>Перед написанием мультиплатформенного кода приложения для iOS и Android должны иметь схожую архитектуру с модулями или уровнями, имеющими идентичную логику. В наших приложениях было подобное разделение слоев:</p><ul><li>UI (презентация);</li><li>домен (уровень бизнес-логики);</li><li>дата (уровень источника данных).</li></ul><p>Сначала мы ограничивались перемещением уровня данных, но затем стали перемещать всё остальное, включая бизнес-логику приложения. Единственные части KMM, которые мы не используем, — это пользовательский интерфейс и специфичные для платформы функции, такие как Apple и Google Pay.</p><p>Внутри библиотеки мы используем Ktor, Kotlin Serialization и Coroutines. Оболочка Rx применяется для адаптации платформы, но в будущем планируем использовать только Coroutines на Android и, если будет возможность использовать Async\Await на стороне iOS</p><p>Чтобы перенести функциональность корзины пользователя нужно было кэшировать данные с API и мы начали использовать библиотеку SQLDelight. Выполнив эту задачу, начали переносить в KMM более сложные функции приложения.</p><h2>Достоинства и недостатки КММ</h2><p>Недостатки, которые обнаружились при использовании Kotlin Multiplatform Mobile:</p><ul><li>нашим разработчикам iOS пришлось потратить много времени на изучение Gradle, среды разработки и языковых функций;</li><li>сложнее тестировать на устройстве, сложный контроль качества.</li></ul><p>Далее выявленные достоинства.</p><ul><li>До KMM основные функции типа корзины требовали 40-60 часов работы для каждой платформы (80-120 часов для обеих), не считая тестирования. С помощью KMM мы можем сократить временные рамки до 50-70 часов для обеих платформ.</li><li>Мы разделяем только бизнес-логику между платформами и используем собственный код для каждого пользовательского интерфейса. Такой подход обеспечивает максимальную производительность при минимальном количестве шаблонного кода.</li><li>Легкий наём и поддержка — KMM работает на Kotlin, которым владеют большинство разработчиков Android. А из-за близости к JVM-языкам любой backend-разработчик теоретически может работать с Kotlin и KMM.</li><li>Идентичная логика на обеих платформах значительно снижает расхождения, а значит, удешевляет разработку и поддержку.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>JetBrains выпустила исследование про разработчиков C++. Оказалось, треть из них не пишет юнит-тесты</title>
      <link>https://tproger.ru/news/jetbrains-vypustila-issledovanie-pro-razrabotchikov-c-okazalos-tret-iz-nih-ne-pishet-junit-testy</link>
      <comments>https://tproger.ru/news/jetbrains-vypustila-issledovanie-pro-razrabotchikov-c-okazalos-tret-iz-nih-ne-pishet-junit-testy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Андрей Борисов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/jetbrains-vypustila-issledovanie-pro-razrabotchikov-c-okazalos-tret-iz-nih-ne-pishet-junit-testy</guid>
      <description><![CDATA[<p>Исследование JetBrains показывает, что около трети C++-разработчиков не пишут юнит-тесты; результаты сравнивают практики разных языковых сообществ.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/jetbrains-vypustila-issledovanie-pro-razrabotchikov-c-okazalos-tret-iz-nih-ne-pishet-junit-testy">JetBrains выпустила исследование про разработчиков C++. Оказалось, треть из них не пишет юнит-тесты</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 21 Jul 2021 13:32:44 GMT</pubDate>
      <content:encoded><![CDATA[<p>В рамках ежегодного отчёта The State of Developer Ecosystem компания JetBrains выложила результаты исследования по каждому популярному языку программирования.</p><p>JetBrains <a href="https://blog.jetbrains.com/clion/2021/07/cpp-ecosystem-in-2021/">сделала</a> отдельную статью про язык C++, в которой собрала мнение экспертов по полученной статистике.</p><h2>20% используют C++20</h2><p>Каждый пятый респондент использует последний официально подписанный стандарт C++20, хотя он поддерживается ещё не во всех компиляторах.</p><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok-jekrana-2021-07-21-v-16.17.49.png" alt="" /><figcaption>1 из 5 разработчиков уже использует C++20</figcaption></figure><p>Ещё столько же опрошенных собираются перейти с самого популярного стандарта С++11 на C++20.</p><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok-jekrana-2021-07-21-v-16.15.24.png" alt="" /><figcaption>20% пользователей планируют перейти на C++20 с C++11</figcaption></figure><h2>30% не пишут юнит-тесты</h2><p>Эксперт Мэтт Годболт (Matt Godbolt) считает, что это очень печальная статистика.</p><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok-jekrana-2021-07-21-v-16.24.02.png" alt="" /><figcaption>30% не пишут юнит-тесты для C++</figcaption></figure><p>Ещё 32% используют Google Test для написания юнит-тестов.</p><h2>55% используют CMake для сборки</h2><p>Принято считать, что в мире C++ какой-то стандартной системы для сборки нет. Однако больше половины пользователей предпочитают CMake.</p><p>Ещё в топе — Makefile и Visual Studio.</p><figure><img src="https://media.tproger.ru/uploads/2021/07/image-69.png" alt="" /><figcaption>Для сборки используют в основном CMake, Makefile и Visual Studio</figcaption></figure><h2>Где почитать ещё?</h2><p><a href="https://www.jetbrains.com/lp/devecosystem-2021/cpp/">Исследование C++ </a></p><p><a href="https://www.jetbrains.com/lp/devecosystem-2021/javascript/">Исследование JavaScript</a></p><p><a href="https://www.jetbrains.com/lp/devecosystem-2021/python/">Исследование Python</a></p><p><a href="https://www.jetbrains.com/lp/devecosystem-2021/go/">Исследование Go</a></p><p><a href="https://www.jetbrains.com/lp/devecosystem-2021/kotlin/">Исследование Kotlin</a></p><p>Источник: <a href="https://blog.jetbrains.com/clion/2021/07/cpp-ecosystem-in-2021/">Блог JetBrains</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>