Mobile VK Hub
766 subscribers
53 photos
6 videos
27 links
Комьюнити от VK для мобильных разработчиков. Здесь всё о том, как создаются приложения для миллионов: от нативных подходов до кросс-платформы.
Download Telegram
👆 Ошибки =/= проблемы

Иногда ошибки — это способ решить проблему.

Кирилл Попов прошёл долгий путь внутри VK — когда-то он был обычным джуном. Он много разбирался в устройстве продуктов, с которыми работал, искал ошибки в коде, находил лучшие решения. Однажды он придумал Tracer — сервис для автоматического поиска ошибок и диагностики причин их появления.

В карточках рассказываем историю появления инструмента, который сейчас используется в 1,5 тыс. приложений, а полную статью о появлении Tracer читайте здесь. Мы скоро расскажем, как сервис эволюционировал на протяжении последних лет.

А ещё у нас есть выпуск подкаста «Кофе-брейк VK» с Кириллом — слушайте и получайте информацию от первоисточника.

#mobilevk #tracer
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥52👏1
Media is too big
VIEW IN TELEGRAM
🙂 Полный зал разработчиков, живые обсуждения и ворох идей для будущих проектов — так прошла RuStore Gamedev Mobile Conf.

Вместе с командами из России и Азии говорили о трендах мобильного геймдева, обменивались опытом, слушали доклады коллег из RuStore и тестировали игры независимых студий прямо на площадке.

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

Как это было — смотрите в видео и продолжайте следить за новостями индустрии!

#mobilevk #RuStoreConf
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥3👏2
Ностальгируем по VK JT Mobile и несём вам аж 7 часов хардового контента про мобильную разработку: там и про iOS, и про Android, и про веб-приложения много полезного.

🔖 Сохраняйте, чтобы не потерять

#mobilevk #vkjt
Please open Telegram to view this post
VIEW IN TELEGRAM
👏521🔥1🍾1
Автотест упал? Начинаем заново.
Разбираем на примере ОК

ОК есть везде: в вебе, в мобильном вебе, в приложениях Android и iOS. Это 50 тысяч контейнеров Docker, 1 эксабайт данных и обработка данных в 7 дата-центрах. Следить вручную за тем, чтобы ничего из этого списка не падало, однажды стало просто невозможно. Так появилась команда автоматизации тестирования, которая уже написала более 10 тысяч автотестов.

👆 В статье у нас на Хабре руководитель команды Эмилия Куцарева рассказала, что стоит за автотестами ОК и как команде удалось сделать их точными и прогнозируемыми.

#mobilevk #автоматизациятестирования #одноклассники
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥51💯1🍌1🤗1
Привет! Это рубрика «Знакомство с командой», и сегодня с нами старший Android-разработчик Почты и Облака — Алексей Закалдаев. Поговорим про карьеру, хобби, и то, как преподавание помогает расти.

▶️ У тебя интересная карьерная история: ты начинал как Android-разработчик, но потом ушел в аналитику. Почему решил вернуться обратно?

Когда я учился в университете на прикладной математике и информатике, нас обучали машинному обучению, и мне стала интересна эта область. Я захотел перейти в Data Science и устроился аналитиком данных с прицелом на будущее.

Проработал год, но чувствовал себя не в своей тарелке. Когда занимаешься аналитикой, ты, по сути, не код пишешь, а ковыряешься с данными, выгружаешь их из баз, строишь дашборды. Ещё мы пытались сделать детектор аномалий для графиков и метрик: чтобы не глазами каждый график отслеживать, а чтобы автоматическая система видела странное поведение и присылала алерт.

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

Был и финансовый момент: как аналитик я только начинал и получал минимальную зарплату, а в Android-разработке у меня уже был опыт 2–3 года. В итоге всё сложилось так, что я вернулся в мобильную разработку и сейчас уже больше трех лет работаю в VK.

▶️ Над какими проектами ты работал в компании за последнее время?

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

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

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

▶️ Что считаешь важным, чтобы оставаться эффективным и не выгорать?

Если начинаешь перерабатывать и засиживаешься по 10 часов, в конце концов пропадает желание вообще что-то делать. Вместо того чтобы больше работать, стоит свободное время посвящать саморазвитию, получению новых знаний.
И, конечно, важно не забывать про здоровье. Я сейчас хожу в тренажерный зал два раза в неделю. Физическая активность оказывает очень сильное влияние на самочувствие.

▶️ Ты пишешь статьи, ведешь канал и даже начал преподавать. Как это помогает тебе как специалисту?

Я исхожу из принципа: чтобы самому хорошо разобраться в теме, надо объяснить её другому.

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

То же самое со статьями. Например, мне нужно было разобраться, как устроена фоновая работа в Android. Я покопался, понял, что там очень много нюансов, и решил поделиться этим с другими. Информации оказалось так много, что пришлось разбить на две статьи для Хабра.

Другой пример — я купил механическую клавиатуру, причём собирал её по частям: отдельно базу, свитчи, кнопки. Пока всё это проходил, узнал много нового. Изначально я вообще не понимал: зачем их покупают, в чём прикол, почему так дорого? А когда разобрался, захотелось снять видео и упаковать этот опыт, чтобы рассказать другим людям.

Это помогает структурировать собственные знания: когда превращаешь опыт в контент, смотришь на него со стороны, обобщаешь, и появляются новые выводы.

#mobilevk #команда
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍6🔥5👏1🎉1
Мержить нельзя тестировать

Команда автоматизации тестирования ОК пишет UI-автотесты для Android, которые сокращают время на проверку фич и сводят к минимуму участие инженеров в ручном тестировании.

Ребята запретили мержить pull-request, если количество неудачных тестов слишком высокое — ошибки больше не проникают в код.

👆 Полную статью руководителя команды Эмилии Куцаревой можно почитать у нас на Хабре: там примеры, алгоритм действий и полезные советы.

#mobilevk #автоматизациятестирования #одноклассники
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
В этом году Дедушка Мороз попросил передать для вас подарочки пораньше 🎅
Заглянули в мешок — а там годовые подписки на Облако Mail и VK Музыку!

Получить подарки проще простого:
🔹подпишитесь на каналы @frontendhubvk, @backendhubvk и @mobilehubvk
🔹 нажмите кнопку «Участвовать»

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

Удачи!
10🔥4👏3🍾3🎉1
This media is not supported in your browser
VIEW IN TELEGRAM
Конец года, и снова заканчиваются все подписки 😱

Узнали? Согласны? Не беда — мы как раз разыгрываем промокоды на год от Облака Mail и VK Музыки!

Условия участия простые:
🔹 подпишитесь на наш канал @mobilehubvk
🔹нажмите кнопку «Участвовать»
🔹 дождитесь 30 декабря — в этом посте мы выберем случайным образом 6 победителей

Информацию об организаторе, правилах и призах ищите по ссылке.

Удачи!
🍾2217🎉8🔥6👏3
Всем привет. Продолжаем знакомиться с нашей командой. На этот раз с нами iOS-разработчик в Core-команде ВКонтакте — Кирилл Бережной. Он расскажет, как пришёл в IT после профессионального спорта и над какими проектами успел поработать в компании.

▶️ Расскажи, как ты вообще попал в разработку?

Мой путь начался необычно, потому что изначально я занимался профессиональным футболом. Играл в молодежке «ФК Ростов» и «СКА-Ростов», но случилась травма. Я сломался и почти на год вылетел.

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

▶️ Какие качества помогли тебе быстро попасть в бигтех?

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

Я играл опорного полузащитника. Там нужна борьба, нельзя бояться «идти в стык». Кроме того, в центре поля нужно много думать, анализировать и уметь расставлять всё по полочкам. Так что можно сказать, в определённом смысле моя футбольная карьера помогает моей нынешней карьере разработчика.

▶️ Ты говорил про нереализованные амбиции в спорте. Удалось перенести этот азарт в работу?

Да, знакомая история. Первое время было тяжело принять, что жизнь изменилась. Но потом я взвесил всё: в футболе люди ломаются к 35 годам, много подводных камней. И я понял, что амбициозность и желание добиться результата можно перенести в карьеру разработчика..
Я нашел челленджи в работе. Стараюсь быть инициативным, двигаться, общаться с большим количеством людей. Это избавило меня от мыслей о несбывшемся успехе.

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

▶️ Над какими задачами ты работаешь в компании?

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

Также работал над приложением VK Музыка. Из интересного — написал шейдер для плеера с помощью низкоуровневой библиотеки Metal.

Ещё мы перевели проект на Tuist — это такая система сборки. Мы оптимизировали скорость сборки проекта, в разы сократили её. Соответственно, наши разработчики стали собирать проект и разрабатывать фичи намного быстрее.

▶️ Ты был ментором в Бауманке. Чем этот опыт отличается от работы со стажерами?

Студенты сильно отличаются от стажеров. Это совсем зеленые ребята, к ним нужен особый подход. Это заставляет тебя по-другому воспринимать информацию: перефразировать более простым языком, доносить её понятно.

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

▶️ Чем занимаешься за пределами работы?

В свободное время я иногда пишу музыку: играю на гитаре, пишу в Ableton или FL Studio. Люблю спорт. Играю в падел и не забываю про футбол.

#mobilevk #команда
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19🎉74👍4👏2
Привет, мобильные разработчики! 🎄

Перед праздниками делимся с вами подборкой важных и глубоких материалов от авторов VK — идеями и подходами, которые пригодятся в реальных проектах.

Актуальные практики работы в фоне Android-приложений
Как современные ограничения Android влияют на фоновые задачи и какие инструменты реально работают на актуальных версиях ОС. Алексей Закалдаев, старший Android-разработчик Почты и Облака, проходит по основным механизмам фоновой работы — от WorkManager и JobScheduler до ForegroundService и DownloadManager, объясняет, когда что выбирать, какие ограничения накладывает система и как учитывать Doze, App Standby и оптимизацию батареи. По ходу даём примеры кода и практические советы по правильному использованию каждого API.

Быстрее, чище, стабильнее: как мы ускорили UI-тесты в iOS в 2,5 раза
Кейс оптимизации UI-тестов: с чего команда начинала, какие проблемы тормозили прогон, и как шаг за шагом удалось добиться существенного ускорения. Рассматриваем схемы запуска, кеширование артефактов, изменение пайплайна, улучшение инфраструктуры и оптимизация симуляторов — в итоге длительность прогонов снизилась почти в 2,5 раза без потери стабильности.

Отделяем мух от Kotlett: динамические обновления без релизов и BDUI
Глубокий обзор внутреннего фреймворка Kotlett, позволяющего доставлять новые фичи «по воздуху» без классических релизов и без зависимости от Backend-Driven UI (BDUI). Александр Наумов, руководитель разработки мобильной платформы в VK Tech и Mail, объясняет, почему BDUI не подходит для офлайн-ориентированных продуктов, как устроена архитектура Kotlett (Kotlin Multiplatform + JS-бандлы + runtime интеграция через DivKit), и как это ускоряет доставку функциональности, сохраняя полную нативность.

Как поддержать Flutter в своей библиотеке. Опыт VK ID SDK
Практический кейс интеграции поддержки Flutter в крупный SDK: планирование работ, архитектура с публичным Dart-интерфейсом, обёртки для Android/iOS, реализация MethodChannel и работа с платформенными Views. Материал особенно полезен тем, кто делает библиотеки и хочет обеспечить кросс-платформенную поддержку без дублирования логики.

Новые подходы в Swift для тестирования: разбор технологии Swift Testing
Обзор современного тестового фреймворка Swift Testing, представленного на WWDC24. Вместо классических XCTest-классов он предлагает аннотации @Test и @Suite, поддержку макросов и Swift Concurrency, гибкую параметризацию тестов, новые механизмы проверки (#expect, #require), и возможности кастомизации через трейты и тегирование. Материал полезен тем, кто хочет писать более выразительные и модульные тесты в Swift.

👆 Сохраняйте материалы, читайте, комментируйте и делитесь опытом!

#mobilevk #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥4🍾2👏1💋1
Привет! Сегодня поговорим с руководителем отделов разработки приложения Дзен и соцсервисов в Одноклассниках — Дмитрием Мовчаном. Обсудим карьерный путь в мобильной разработке, нюансы управления командой в период активного роста и то, как дисциплина помогает ему в работе и жизни.

▶️ Как ты попал в IT и почему выбрал мобильную разработку?

Мой отец был системным администратором, поэтому компьютер стоял дома с самого детства. Я учился в лицее при Бауманке, потом в самом университете на кафедре компьютерных систем и сетей, а в середине обучения пошёл в существовавший тогда проект Технопарк от Mail.ru. Мне тогда очень нравился бэкенд на Java, но компания не нанимала стажеров-бэкендеров, зато я увидел, что в программе есть мобильная разработка — это было схоже с Java-бэкендом. Вакансий там было больше, поэтому я решил попробовать себя в мобилке.

Сначала я пробовался в ICQ (тогда часть Mail.ru), но меня не взяли. Не отчаялся, пошел в «Касперский» — туда приняли, и так завертелась карьера.

▶️ Ты выбрал Android. Это было осознанное решение или случайность?

Это типичный выбор для того времени: разработчики под iOS и Android были сильно разграничены наличием техники. У меня тогда не было ни макбука, ни айфона, поэтому идти в iOS казалось нелогичным.

Хотя диплом по iOS-разработке у меня тоже есть. В Технопарке курсы шли параллельно: Android был в общей программе (за него могли отчислить), а iOS — факультативом. Все силы были брошены на Android, но «корочку» по iOS я всё-таки получил.

▶️ Над какими задачами ты работал и работаешь в VK?

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

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

▶️ Ты пришел сразу лидом, а сейчас руководишь отделом. Какой совет можешь дать будущим руководителям?

Расти лучше постепенно: сначала руководишь одним человеком, потом командой из 5–6, потом несколькими командами. Если перепрыгнуть ступени, потеряешь контекст.

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

И еще важно учиться. В России менеджмент как дисциплина часто находится в роли догоняющего, поэтому стоит изучать зарубежные труды и литературу, чтобы применять актуальные методики. Я могу порекомендовать книгу «Карьера Software Engineering Manager» автора Джеймса Стэньера. Там чуть больше про зарубежный менеджмент, чем про российский, но это всё равно самая полезная книга по менеджменту из всех, которые я прочитал. Недавно выложил в свой телеграм-канал большой список полезной литературы.

▶️ Как ты отдыхаешь от работы?

Мне нравится автоспорт. Недавно впервые съездил вживую на Формулу-1 в Баку. Очень понравилась атмосфера. Увлекаюсь дрифтом — не на парковке торгового центра, а серьезно — с командой технарей на специальном треке. Домой купил кокпит, руль, гоняю в симуляторы.

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

#mobilevk #команда
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥105👏4👍2
Tracer VK: единый мониторинг ошибок для мобильных платформ

Tracer — сервис VK для сбора и анализа ошибок мобильных приложений и веб‑сайтов. Сегодня его используют более 2 100 организаций, подключено около 3 600 приложений, а число пользователей превышает 10 000 человек. Инструмент применяется как в продуктах VK — ВКонтакте, ОК, RuStore, Дзен, Mail, так и в других компаниях.

👆 Ключевые возможности для мобильных команд:

➡️ Поддержка основных мобильных платформ

Tracer поддерживает:
🟣Android
🟣iOS
🟣ОС Аврора

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

➡️ SDK и расширенный контекст ошибок

Для мобильных приложений доступны:
🟣детальные стектрейсы,
🟣последовательность действий пользователя перед сбоем,
🟣технический контекст, достаточный для быстрой локализации проблемы.

➡️ Новые платформы и устройства

В 2025 году добавлена поддержка:
🟣Apple TV,
🟣desktop-приложений под Windows, Linux и macOS, включая рабочие станции разработчиков.

Это упрощает анализ ошибок на всех этапах разработки и тестирования.

➡️ Аналитика и проактивное обнаружение сбоев

В Tracer появились:
🟣алерты по критическим ошибкам,
🟣телеметрия,
🟣мини-графики,
🟣язык запросов TQL для фильтрации и анализа данных под задачи конкретной команды.

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

➡️ Масштаб и стабильность
Tracer обработал рост нагрузки более чем в 30 раз без падения производительности — благодаря оптимизации интерфейса и масштабированию хранилища данных.

#Tracer #ios #android
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥82👏2👎1
Activity — это Context с жизненным циклом. Когда Activity уничтожается, но на неё остаётся ссылка, garbage collector не может её собрать. А Activity держит ссылку на всё view-дерево, битмапы, ресурсы. Утечка одной Activity — это мегабайты.

Типичные ошибки:


// плохо: синглтон держит Activity
object Analytics {
lateinit var context: Context
fun init(ctx: Context) { context = ctx }
}



// плохо: внутренний класс держит ссылку на outer
class MyActivity : Activity() {
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
updateUI() // implicit reference to MyActivity
}
}
}



// плохо: listener не отписан
override fun onStart() {
LocationManager.addListener(this) // this = Activity
}
// onStop без removeListener = утечка


Правила:
— синглтонам передавать applicationContext, не Activity;
— внутренние классы делать static (в Kotlin — без inner) или использовать WeakReference;
— всегда отписываться от listeners в симметричных lifecycle-методах.


// правильно: weak reference для callback
class SafeHandler(activity: Activity) : Handler(Looper.getMainLooper()) {
private val activityRef = WeakReference(activity)
override fun handleMessage(msg: Message) {
activityRef.get()?.updateUI()
}
}


LeakCanary — обязательный инструмент. Он автоматически детектит утечки Activity и Fragment в debug-билдах. Если не используете — утечки копятся незаметно, пока пользователи не начнут жаловаться на OutOfMemoryError.

#mobilevk #android
🔥8321👏1
StateFlow и SharedFlow — разные инструменты для разных задач, а не взаимозаменяемые

StateFlow — это всегда текущее значение. Новые подписчики сразу получают последнее состояние. При эмите одинакового значения подряд дедупликация — подписчики не получат повторное событие.


private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState

// подписчик сразу получит текущий UiState.Loading


SharedFlow — это поток событий. По умолчанию нет начального значения, нет дедупликации. Новые подписчики получают только будущие события (если не настроен replay).


private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events

// события, которые не должны пропадать и повторяться

_events.emit(Event.ShowToast("Saved"))


Ошибка — использовать StateFlow для one-shot событий:

// плохо: при пересоздании Activity событие сработает снова
data class UiState(val showError: Boolean = false)

_uiState.value = _uiState.value.copy(showError = true)
// после показа ошибки надо вручную сбрасывать обратно в false


Правильно — StateFlow для состояния UI (loading, content, error), SharedFlow для событий (navigation, toast, dialog). Для событий также подходит Channel с receiveAsFlow(), он гарантирует доставку ровно одному подписчику.


val navigationEvents = Channel<NavEvent>(Channel.BUFFERED)

// collect получит событие ровно один раз
navigationEvents.receiveAsFlow().collect { navController.navigate(it) }

#mobilevk #android #kotlin
👍4🍌32🔥2👏2
LaunchedEffect с ключом запускается заново при изменении ключа — это и фича, и источник багов


@Composable
fun UserProfile(userId: String) {
var user by remember { mutableStateOf<User?>(null) }

LaunchedEffect(userId) {
user = api.fetchUser(userId) // перезапускается при смене userId
}
}


Если userId меняется — предыдущая корутина отменяется, запускается новая. Правильное поведение для загрузки данных.

Баг возникает, когда ключ меняется непреднамеренно:

LaunchedEffect(someObject) { // объект пересоздаётся каждую рекомпозицию
// бесконечный перезапуск!
}


Или когда забывают про ключ:

LaunchedEffect(Unit) { // никогда не перезапустится
user = api.fetchUser(userId) // userId изменился, но эффект старый
}


Правило: ключ LaunchedEffect — все значения, от которых зависит логика внутри. Не больше (лишние перезапуски) и не меньше (stale данные).

#mobilevk #kotlin
👍54🔥2