Dev Easy Notes
3.15K subscribers
122 photos
1 video
145 links
Работаю в IT уже 8 лет. Рассказываю про разработку простым языком. Полезность скрыта под тупыми шутками и слоем мата. Лучший underground канал про разработку, который вы сможете найти.

По сотрудничеству писать @haroncode
Download Telegram
Далее koin. Когда в детстве разработчиков Koin подкидывали и забыли ловить… ладно объясню нормально.

Module. В нем создаем зависимости, аналогично Dagger. Далее эти модули нужно указать в инициализаторе Koin.

Component. Он так и называется KoinComponent, позволяет использовать функции для получения зависимостей. Ну на самом деле он просто ищет глобальный контекст Koin и через него уже получает доступ ко всем загруженным модулям. Помимо этого в модуле для Android уже реализованы расширения для использования inject и get во всех стандартных компонентах.

Dependencies. А вот с этим в Koin все довольно забавно. Эта собака же сама все хранит в глобальном контексте. Поэтому работает это так. Вот в app модуле приложения вы прописали какие модули Koin нужно загрузить т.е сразу все. И так как контекст то у Koin один, что значит все теперь все модули доступны везде. Что означает, вы в фиче модуле, в модуле Koin можете сразу использовать зависимости, которые вы например определили в app модуле. Минус в том, что вы можете случайно получить зависимость с другого фича модуля и отслеживать это придется вручную.

Хотелось бы чтобы это было явно. В целом это можно решить тем, что вы делаете интерфейс зависимостей и затем пытаетесь в модулях, которые прописаны в фиче, получать зависимости не через koin, а инстанс этого интерфейса, который вы реализовали в app. Да запутанно, поэтому не используйте koin, если у вас проект чуть больше чем 5 экранов.

Scope. В Koin можно прям явно указать что объекты создаются на время работы конкретного экрана, т.е они привязаны в Activity или фрагменту и уничтожаются при выходе с этого экрана. Тут все более явно чем в Dagger.
👎16👍10🤔9
Ой да бросьте, смешно же. Ладно, ок я понял, вам нравится koin, говоря откровенно он и мне нравится, но только в проектах на бэке, и которые я делаю в соло. Однако зачем же вы, понимаете мои слова так буквально? Под 5-ю экранами, я не подразумевал именно 5 экранов, более того если у вас 5 экранов, вам вообще DI нахер не нужен. Я разумеется подразумевал 10 экранов, вот если больше 10 то koin уже нельзя, так своим коллегам и передайте, что ноунейм с канала в телеге, запретил в таком случае использовать koin.
😁67🤡7🔥2👏2
Ладно а теперь на чистоту, вы мне много чего накидали за воротник по поводу koin. Многие пишут, что вот у нас 100 экранов и вообще никаких проблем мы не испытываем. Хорошо, допустим, вам все нравится, в прописывании кучи get, поиском ответа на вопрос, а откуда же мне тут приходит зависимость и прописывании изолированных контекстов вы не видите ничего плохого.

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

Каждый разраб сошел бы с ума нахер, пытаясь найти что, где откуда берется и как мне сейчас прописыванием очередного single c параметром ничего не сломать. Я уже молчу про перформанс, он с треском проигрывает любому другому DI на базе кодогенерации.
👍27🔥6🤡4🗿2
Вот я же просто хотел сделать обзор на разные 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 которые работают слегка по другому, но давайте не усложнять сейчас)
🔥22👎2🤡21🥰1
Сейчас делаю на работе бота, по сути небольшой бекенд и мне нужно было валидировать модели в запросах. Весьма дефолтная задача, приходит объект, он должен удовлетворять каким-то правилам. Если какие-то поля заполнены неверно, нужно фронту отдать список полей в нужном формате с припиской почему именно поле заполнено неверно. Задача максимально базовая, и в Spring решается за пару аннотаций. Однако так уж вышло что у меня используется ktor и поэтому такое приходится делать самому.

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

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

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

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

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

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

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

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

Никак нахуй!

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

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

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

Короче страх никуда не уйдет, но его голос можно сделать заметно тише. Поэтому если вы уже давно хотите что-то поменять, но чувствуете неуверенность. Сходите и попробуйте. Лучше сделать и проебаться, чем не сделать.
1👍64🔥7👎3🗿21
После публикации поста, спустя 0.0001 секунду меня обвинили в сексизме. Поэтому приношу свои глубочайшие извинения, разумеется радикальный способ могут использовать и девочки
😁59👏10🥰7💩1
Недавно на работе возник разговор о 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, а огромное количество классов, которые существуют просто для некоторой оптимизации так себе идея.

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

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

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

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

Думаю, под Новый год как раз сделаю список своих самых эпичных проебов. Кажется, это будет самый полезный пост за весь год.
🔥62👍228😁8🤔2
Увидел недавно комментарий к статье про сравнение MVVM и MVI (прикиньте, их до сих пор пишут), и кое-кто написал следующее:
Есть один метод обработки событий аля handleAction то это MVI, а если несколько разных методов это MVVM

Вроде же столько статей уже написано, куча докладов, уже вроде как все из этой темы высосали, но нет же до сих пор у многих какое-то странное представление о разнице этих двух подходов.

Поэтому попробую объяснить… Вот у вас есть ViewModel, вы используете MVVM и решили, сейчас я добавлю единый state и у меня будет MVI. Нет не будет, у вас будет MVVM просто с единым state вместо нескольких полей, вот и все.

Главных отличий MVVM от MVI 2: реактивный подход для обработки событий, и state который меняется последовательно и только в одном месте.
Реактивный подход означает, что вы не просто делаете большой switch и в зависимости от action вызываете те или иные функции. Вы этот action отправляете в очередь, где он уже позже обработается. В этом и проявляется реактивность, мы обрабатываем все поступившие action по очереди, друг за другом, и прикладываем к обработке текущий state, но об этом далее.

Ключевое отличие между MVI и MVVM с единым state – изменение этого самого state в одном конкретном месте последовательно. Если у вас несколько мест где меняется state, то вся идея unidirection data flow идет лесом. Если два метода будут одновременно менять state, то он может оказаться в некосистентном состоянии, нет никаких гарантий. Даже если вы поставите lock и в один момент времени state будет менять только один поток, все равно вы не контролируете порядок, это не реактивный подход. Когда по коду раскидано изменение состояние, ты попробуй отдебажить все это дело, когда у тебя куча асинхронщины.

Вся идея именно в том, что action отправляются в очередь, накладываются на текущий state, генерируется новый state в одном месте и все повторяется заново. Поэтому все чуть сложнее чем просто зафигачить один единый state во ViewModel.
👍5610👎4🗿1
Вот я все время избегал названия компаний, потому что думал: вдруг я туда захочу попасть или они ко мне придут с рекламой, но вчера чаша моего терпения переполнилась, поэтому…

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Проще говоря, совершенно не важно, чем ты занимался на прошлой работе. При выходе на рынок ты начинаешь все с начала, обнуляешься, ты теперь никто и звать тебя никак. Если ты не селебрити, которого знают все, каждый раз тебе придется проходить через эти одинаковые вопросы, которые вообще не относятся к твоей работе. При этом если ты собесишься в корпорацию, вообще похую, что у тебя будет написано в резюме.
1🔥49👏11😁7👍6🗿42
Пока не перешли к другой теме в догонку к предыдущему посту. В комментариях справедливо заметили: "вот это поворот, что ты ожидаешь вопросы про Android разработку, приходя на позицию Android разработчика".

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

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

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

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

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

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

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

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

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

Вы уже себе в приложение снежинки добавили? Если же не добавили, то чем вы весь декабрь занимались?
1😁81👍7👎5