Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
354 - Telegram Web
Telegram Web
Ой да бросьте, смешно же. Ладно, ок я понял, вам нравится koin, говоря откровенно он и мне нравится, но только в проектах на бэке, и которые я делаю в соло. Однако зачем же вы, понимаете мои слова так буквально? Под 5-ю экранами, я не подразумевал именно 5 экранов, более того если у вас 5 экранов, вам вообще DI нахер не нужен. Я разумеется подразумевал 10 экранов, вот если больше 10 то koin уже нельзя, так своим коллегам и передайте, что ноунейм с канала в телеге, запретил в таком случае использовать koin.
Ладно а теперь на чистоту, вы мне много чего накидали за воротник по поводу koin. Многие пишут, что вот у нас 100 экранов и вообще никаких проблем мы не испытываем. Хорошо, допустим, вам все нравится, в прописывании кучи get, поиском ответа на вопрос, а откуда же мне тут приходит зависимость и прописывании изолированных контекстов вы не видите ничего плохого.

При этом вы точно уверены, что у вас достаточно большой проект сейчас? Я сейчас работаю на проекте, где 40+ Android разрабов, более 1000 gradle модулей, а количество экранов я даже посчитать не смогу, кажется уже бесконечность. В проекте такого уровня использовать Koin это страшное преступление.

Каждый разраб сошел бы с ума нахер, пытаясь найти что, где откуда берется и как мне сейчас прописыванием очередного single c параметром ничего не сломать. Я уже молчу про перформанс, он с треском проигрывает любому другому DI на базе кодогенерации.
Вот я же просто хотел сделать обзор на разные DI фреймворки и в итоге был вовлечен в срач про koin и супераппы. Однако я продолжу, а про недостатки koin потом сделаю отдельный пост, если будет настроение)

Итак, вершина инженерной мысли, 9 симфония в мире Java Backend, покровитель всего интерпрайза – Spring.

Разумеется Spring это уже давно ансамбль различных технологий, но нам интересен только DI. На самом деле это первая DI либа с которой я вообще работал. Перед тем как рассказывать про то как Spring кладется на нашу модель нужно понимать одну вещь.

В мобилке мы используем кодогенерацию для ускорения инициализации графа, ведь это влияет на запуск приложения. Ну или забиваем и используем либу из прошлого поста. На беке же, грубо говоря, поебать на скорость запуска. Ты хоть 5 минут можешь граф инициализировать, главное чтобы все не тормозило в процессе. Поэтому в Spring практически все работает на базе рефлексии. Да медленно, зато удобно, а готовые плагины показывают откуда, берутся зависимости (отсоси Koin!)

Component. Как отдельного класса его нет. Тут можно представить что создается компонент на каждый класс, в котором ты используешь DI. Поставил аннотацию @Component и все, теперь внутри класса можешь инжектить все что тебе вдумается и главное как тебе вдумается. Spring умеет инжектить и через конструктор, и через приватное поле, и через setter и даже через твою ма…

Module. Реализуются похожим на Dagger подходом. Делаем класс, реализуем методы для создания зависимостей, проставляем каждому методу аннотацию @Bean (не спрашивайте почему Bean, интерпрайзные приколы). Далее классу проставляем аннотацию @Configuration и все. На практике такие модули создают редко и только для всяких конфигураций. Всякие Repository и Interactor у нас являются @Component, поэтому их Spring за тебя сам создаст и запихает куда нужно.

Scope. Опять-таки аннотация @Scope. Можно сделать чтобы зависимость жила пока не умрет все приложение, можно сделать чтобы зависимость жила пока живет сессия или вообще сделать scope на уровне запроса. Ну и также этой же аннотацией мы проставляем Singleton или Prototype.

Ну и касательно зависимостей в явном виде как это сделано в Dagger их нет, тут все аналогично тому, как это работает в koin. Но и на бэке гораздо реже происходит ситуация, когда делают много модулей, там, как правило, разъезжаются на микросервисы, когда становится много команд.

P.S для матерых бекендеров. Да я знаю что есть еще @Service и @Repository которые работают слегка по другому, но давайте не усложнять сейчас)
Сейчас делаю на работе бота, по сути небольшой бекенд и мне нужно было валидировать модели в запросах. Весьма дефолтная задача, приходит объект, он должен удовлетворять каким-то правилам. Если какие-то поля заполнены неверно, нужно фронту отдать список полей в нужном формате с припиской почему именно поле заполнено неверно. Задача максимально базовая, и в Spring решается за пару аннотаций. Однако так уж вышло что у меня используется ktor и поэтому такое приходится делать самому.

Есть два варианта как это сделать: пишем валидацию и генерацию текста ошибок вручную или используем уже какую-то либу для kotlin, которая это умеет делать.
Разумеется я рот топтал делать это вручную. Все либы для валидации которые я нашел, работают по одному и тому же принципу. Получаем KProperty, который позволяет получить как данные, так и название поля, что помогает на месте выдать список ошибок. А дальше через dsl прописываем условия, которым поле должно удовлетворять, и текст ошибки если не удовлетворяет.

Я решил затащить вот такую. В целом довольно удобный API, можно дописывать свои проверки, короче мою задачу решает. Но…, разумеется я бы не стал про это писать, если бы не было "но". Есть две вещи которые меня страшно веселят. 

Первое, я заметил тенденцию, что все либы, которые пишутся сейчас на kotlin, как будто обязаны быть мультиплатформенными. Ощущение такое, что разрабы боятся того, что если вдруг либа будет только для JVM, их кресло превратится в бутылку. При том что в этой либе таргет только на JVM, ну да ладно, вместо одного src получаем 3, пофиг.

Второе, в этой либе есть ksp. И вот с одной стороны ты можешь подумать, ну ведь можно же представить чтобы такую либу использовать в мобилке и там, чтобы без рефлексии было? Представить можно, однако знаете для чего тут нужен ksp? Исключительно для того, чтобы обернуть KProperty в один конкретный метод. Другим словами вместо:
validatableOf(Person::name).isNotEmpty()

можно было написать:
name.isNotEmpty()

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

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

Итак, набираем воздух в грудь, как же полностью избавится от страха перед собесами?

Никак нахуй!

Смиритесь, нет способов полностью избавиться от волнения. Жизнь так устроена, что на всех важных моментах, которые значительно меняют нашу жизнь вы будете испытывать страх. Подойти познакомится с девушкой, пройти собес, выступить на конференции – все эти моменты в жизни нельзя пройти в одиночку, рядом всегда будет эта мразина в виде волнения. Да я сам ссу перед собесами, которые же сам блять и провожу, это вообще еще что такое?

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

Есть еще более радикальный способ, но подходит только мальчикам. Попробуйте на бокс походить. После пары спарингов, волнение от коммуникаций вообще снижается до минимума. Главное не переусердствуйте)

Короче страх никуда не уйдет, но его голос можно сделать заметно тише. Поэтому если вы уже давно хотите что-то поменять, но чувствуете неуверенность. Сходите и попробуйте. Лучше сделать и проебаться, чем не сделать.
После публикации поста, спустя 0.0001 секунду меня обвинили в сексизме. Поэтому приношу свои глубочайшие извинения, разумеется радикальный способ могут использовать и девочки
Недавно на работе возник разговор о Double check locking. Напомню если вдруг забыли. Вот представьте у вас тяжелый объект какой-то, который при создании требует кучу или памяти или времени, и вы не хотите его создавать сразу, а лениво когда понадобится. Мы можем конечно просто взять и вынести его в функцию, и потом вызвать в нужный момент:


private var heavy: HeavyObject? = null

fun get():HeabyObject {
if( heavy == null ){
heavy = HeavyObject()
}
return heavy
}



Однако, что если два потока одновременно вызовут эту функцию? Если класс действительно тяжелый, например инициализация LLM это может быть проблемой. Я уже молчу про остальные проблемы с visibility поля и прочими проблемы с многопоточкой. Тоже мне проблема, ну можно же тупо поставить синхронизацию и все, делов то.


private var heavy: HeavyObject? = null

fun get():HeabyObject = synchronized { … }


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

Чтобы решить эту проблему, придумали подход называемый Double check locking, который используется в Dagger кстати. Суть проста, давай захватывать Mutex только если мы видим что объект еще не проинициализирован.


@Volatile
private var heavy: HeavyObject? = null

fun get(): HeavyObject {
var result: HeavyObject? = heavy
if (result == null) {
synchronized(lock) {
result = heavy
if (result == null) {
result = HeavyObject()
heavy = result
}
}
}
return result!!
}


Ну понимаете да, сначала чекаем на null, затем захватываем Mutex и еще раз чекаем, ведь кто-то мог захватить Mutex раньше и уже проинициализировать поле. Поэтому и double check.

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

Есть у JVM одна интересная особенность, все static блоки выполняются thread safe, т.е JVM их автоматически синхронизирует потому как важно гарантировать что этот блок вызовется лишь один раз. Еще фишка static блоков в том, что они вызываются только в момент обращения к классу. Поэтому мы можем использовать эту систему, чтобы сделать ленивую инициализацию:


private object FieldHolder {

val field: HeavyObject = createObject()

private fun createObject(): HeavyObject = HeavyObject()
}

fun get(): HeavyObject {
return FieldHolder.field
}


Не особо верится, что тут действительно ленивая инициализация или что оно thread safe. Ради эксперимента попробуйте сами это проверить)

Главный вопрос тут конечно, почему тот же Dagger не использует данный подход? Вероятно потому, что если на каждую зависимость будет генериться по классу Holder, а огромное количество классов, которые существуют просто для некоторой оптимизации так себе идея.

Однако в своем коде, если хотите выебнуться на МРе можете такое попробовать. Только потом не плачьте, что с вами на обед не хотят идти. Один дурачок проверял, не будут раскрывать его личность....
Смотрите под ноги, дамы и господа, ибо я собираюсь уронить немного мудрости. Когда-то давным-давно я проходил курс по тестированию. Там говорилось о 7 основных принципах тестирования. Один из них называется "Скопление ошибок", который гласит: "Ошибки часто концентрируются в небольшом числе модулей".

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

Однако на практике я постоянно на это натыкаюсь, вот сука, почти каждый раз. Ты делаешь какую-то фичу, в ней обнаруживается баг. Ты лезешь его чинить и по пути обнаруживаешь ещё 3 бага, а если не обнаруживаешь, тебе эти 3-4 бага прилетят от QA в ближайшее время. Ну бывало же у вас такое?

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

Думаю, под Новый год как раз сделаю список своих самых эпичных проебов. Кажется, это будет самый полезный пост за весь год.
Please open Telegram to view this post
VIEW IN TELEGRAM
Вот я все время избегал названия компаний, потому что думал: вдруг я туда захочу попасть или они ко мне придут с рекламой, но вчера чаша моего терпения переполнилась, поэтому…

Меня в край уже заебал Яндекс. Это просто немыслимо, меня умудрилось расстроить каждое приложение экосистемы. Думали я только Gradle могу хейтить? Сегодня я сделаю исключение!

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

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

Ты нажимаешь на "оплатить картой яндекс", тебя перекидывают на экран создания карты. Ты ее создаешь, потом пополняешь, пока все хорошо и правильно. Потом ты идешь в корзину и пытаешься выставить оплату картой. Однако при нажатии, тебя отпинывает на страницу карты. После 15 минут попыток, от слова пыток, я нашел что нужно сделать.

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

Ну как вам UX? Правда здорово? Я думал я с ума сойду от ярости! Это же блять ваш банк, ну сука сделайте вы сами еще один запрос и сами добавьте свою же карту! Ну это же абсурд, они не могут двумя командами договорится чтоли?
Чтобы вы понимали, у нас только что упал кубернетес который находится угадайте где?) Правильно на серверах Яндекса. Это правда так совпало, не то, чтобы я ждал когда все наебнется чтобы выпустить пост. Ну или они возможно так мстят, обидчивые однако...
Я на работе основную часть времени делаю сервис для автоматизации релизов. Это по сути небольшой бэк написаный на Ktor. Не знаю как так получилось, что я будучи мобильным разрабом неожиданно обнаружил себя посреди куберов, докеров, редисов и вот этих слов, вынуждающих фронтов разбегаться в ужасе.

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

DI завязан на koin, который как вы знаете я очень люблю и уважаю, нет готовых инструментов, чтобы хранить сессии в редис и для авторизации нужно оборачивать функции обработки запросов в другие функции (почти как Compose только для бэка). В Spring такие вещи уже давно решены и делаются одной аннотацией.

Правда в Spring другой прикол, ты заходишь в любой туториал, и тебе говорят, ну вот ебани эту аннотацию и внyтри объекта создай вот такой экземляр класса и оно заведется.

И это блять, вообще не очевидно. Практически все исключительно на уровне документации, ты никак по коду это не отследишь. Там такой уровень магии, что кажется можно было победить темного лорда закидав парочкой примеров из Spring, и никакая бузинная палочка не помогла бы.
Я на канале никогда не писал про игры, но про эту не могу не написать, настолько она откликнулась в моей душе. Я уже давно видел рофлы про опилки в суп и детский труд, но не вдавался в подробности откуда это. Итак – frostpunk.

Если вдруг про нее не слышали. Суть сюжета: Температура на всей планете снижается быстрыми темпами, упала до -20 и продолжает уменьшаться. Вы с группой людей отправляетесь на север в поисках убежища. Гениальное решение верно? Да! Ведь именно на севере расположен генератор тепла, вокруг которого вы возводите поселение.

Тебе как руководителю группы нужно построить город и организовать добычу ресурсов так, чтобы всем всего хватило, все не поубивали друг друга и не замерзли к херам. Задача не из легких, коммунальщики в Питере до сих пор не научились.

В игре огромное количество моментов из-за которых она запала мне в душу. Эстетика стимпанка на фоне снега очень хорошо смотрится под новый год. В определенный момент игры ты встаешь перед выбором либо ты строишь милитаризм, либо продвигаешь религию! Поселение на севере, где во главе стоит милитаризм с религией, где-то я такое уже видел, дай бог вспомнить где?

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

Все это я пишу не просто так. Ведь frospunk очень хорошее олицетворение работы в команде инфры. Ты пытаешься сделать как можно лучше, но люди почти всегда будут чем-то недовольны)
Вот еще какая тема бесит в найме и собесах. Если я сейчас захочу поменять компанию и мне нужно будет проходить собесы я наткнусь на проблему следующего рода. Я уже давно не разрабатываю под мобилку. Не чтобы я вообще забыл, что такое Android разработка, если меня попросят сделать фичу, то как нефиг делать. Тем не менее меня сейчас интересует другое направление. При этом, я не то чтобы полностью ушел в backend, там еще куча вещей в которых я плаваю.

В случае, если я захочу сменить компанию, вероятнее всего я буду собеситься как обычный Android разработчик. Мне на собесе придется отвечать на вот эти ебучие вопросы: "А сколько методов в классе Object?", "Расскажи сколько раз вызывается onMeasure в CustomView", "А как бы ты ускорил RecyclerView?", "А ты знаешь что такое Json?"– господи убейте меня.

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

Да, справедливо, в целом я немного прихуел, но стоит пояснить. Я последние 2 года работаю в команде инфры: пайплайны, билды, метрики, эмуляторы для тестов вся вот эта фигня. Иногда я даже встречаю название своей позиции: mobile devops. Хотя по идее это не совсем devops, но да похер. По большому счету мне интересно продолжать этим заниматься.

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

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

Да и как тут устоишь, если сама вселенная намекает!
Cейчас период, когда релизы заморожены, все получили свои новогодние премии и в работе столько же смысла сколько в сюжете хентая. Кто-то проходит advent of code, кто-то уже просто чилит на работе, а я же решил провести небольшой эксперимент.

Я уже упоминал о боте, которого делаю на работе, я расскажу про него подробнее в своих проебах, но сейчас важно что он написан на ktor. Почему я вообще взял ktor? Изначально это был страшно мелкий проект, буквально один запрос. Как мобильный разраб, который последние лет 6 пишет на kotlin я решил, а почему бы и бэк не написать на чистом kotlin?

Да, я уже работал бэкендером на своей первой работе и знал, что Spring крайне удобная вещь. Однако во мне взыграла гордыня, и я подумал что все проблемы связанные с сыростью технологии в ktor я решу своими силами и даже koin мне не помешает. Ну сказано сделано, подробности можете узнать у моего психиатра...

В преддверие праздника, ко мне явился призрак прошлого опыта: а что если, чисто ради прикола, попробовать часть функционала реализовать на Spring Boot? И вот чтобы вам передать мои ощущения, представьте, что вы разработчик, который всю жизнь писал веб сервисы на голом C, и тут вам показали Java.

Большая часть задач, над которыми мне в ktor приходилось что-то придумывать в spring решаются подключением зависимости. Даже код менять не нужно! Я столько времени потратил на подбор либы для конфигурации, а в spring оно из коробки работает. Причем сразу со всем форматами, ему вообще похую.

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

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

Даже в этом году, я собирался выпустить посты про свои проебы года. Когда же я начал их накидывать, оказалось, что с учетом контекста и объяснения в чем проеб получается несколько длинных лонгридов, которые больше подходят для статьи, чем для постов в канал. Прикиньте, в этом году я даже с проебами года проебался… короче их решил выпустить уже в январе

При этом не знаю как вам, а мне нравится читать про итоги года других. Опыт других людей это всегда интересно. Готов поспорить это одна из главных причин, почему вы меня читаете. Мало вероятно, что я вам тут какие-то истины открываю.

Короче, в этом году я все таки решил их накидать. Итак, погнали, в этом году:

👉 Посетил 9 городов в 5 разных странах. Путешествие года – Будапешт с Руинбарами и гуляшом
👉 2 раза выступал на митапе. Причем несмотря на то, что я мобильный разраб выступал на бэкендовских митапах. Возможно стоит задуматься…
👉 Сериал года – Хильда. Из всех мультсериалов которые я смотрел, он ближе всех к вайбу Гравити Фолз
👉 Игра года – Frostpunk. Про него делал отдельный пост.
👉 Покупка года – ортопедические стельки на заказ. Потрясающая тема, со временем действительно стал ощущать, что нагрузка в спине стала ниже при долгих прогулках и при этом любая обувь автоматически становится удобной. Да, пока другие айтишники покупают тачки и квартиры, я покупаю стельки… дэээ
👉 Софт года – Raycast. Это замена стандартного маковского Spotlight, только на стеройдах. Я через него делаю почти все, даже список МРов смотрю.
👉 Пожал 115 кг, это больше проеб года, чем достижение, тут есть куда рости 😄
👉 За год набрал 500 подписчиков. Это буквально в 2 раза меньше чем в прошлом, но учитывая, что за год я ни одной статьи не написал и делал большие паузы в постах, в целом результат норм. Нагоню в следующем
👉 Проект года – вот тут пусто. На работе я делал прикольные штуки, но прикол в том, что ни одну не успел довести до ума, они все больше прототипы, чем продакшен реди.

Это финальный пост этого года. Всем огромное спасибо, что продолжаете меня читать, всех обнял, приподнял, вы все очень клевые ❤️ С наступающим вас Новым годом! Желаю чтобы в следующем году было чуть легче.
2025/07/06 23:45:37
Back to Top
HTML Embed Code: