Pull to refresh
7
0
Сергей @ImLiar

Пользователь

Send message
Что-то неправда ваша про ЗП

Два года назад в Хельсинки взяли мидлом, зп была выше вами озвученной для архитекторов и тимлидов, и это продуктовая компания.
Если попасть в консалтинг, будет еще интереснее в этом плане.
А если в какой-нибудь SuperCell, что не у каждого выйдет, конечно, то можно будет купаться в теплом шоколаде, т.к. со всеми премиальными там может выйти за 150-200 в год (до вычета)
Так с вами-то я и не спорил. Все так и есть.
Вы с точки зрения программирования или теории категорий?
Если бд умеет в лок на уровне таблиц, то это будет справедливо для обеих архитектур.
И что? Вот у меня огромное хранилище у микрухи с заказами, миграция занимает часы. Что изменилось?
Так а как тут поможет монолит или микруха, если БД под завязку?
Стейтлесс приложения обновляются один за другим без особых проблем. С тяжелыми базами будут проблемы вне зависимости от архитектуры системы.
Какие ухищрения? Round-robin на фронте?

На _нормальный_ девопс вороха микрух времени уйдет не меньше, чем на разработку. Для небольших команд это может быть критично, т.к. вместо имплементации фич они будут дрочиться, почему же у них на EC2 инстанс не качается докер имадж из приватного ECR. А выделять на это приходится человека, который код пишет.

У меня есть опыт работы и в небольшой команде, и в крупной компании. Есть возможность сравнить плюс и минусы подходов на практике, без теоретического «ну оно там чото скейлится, чтоб обрабатывать мои 100 запросов в час».
Преимущество только для кейса «много разработчиков @ много команд». На малых масштабах летит так себе
Ой, камон.

Основная суть микросервисов — это масштабирование на бизнес-уровне.
Пусть в компании X определена общая политика — все микросервисы должны предоставлять REST API. Вот книжка с good practice, следуйте.

Теперь каждая команда обозначает API через какой-нибудь swagger/graphql/whatever и имплементирует уже как хочет. Полная независимость разработки между командами, никаких баундов. Технологии и языки вольна выбирать команда, ответственность за продукт end to end, бизнес-домен как зона ответственности команды и продукта.

Единственное правило — не ломать API. А дальше уже скейлите, заливайте огрехи баблом и т.п. Когда у вас на фронте все рендерится по несколько сотен мс, не пофиг ли, что там на бэкэнде теперь оверхед на запросы между сервисами?

Теперь повторите такой же трюк с монолитом на масштабах больше 1к разработчиков. Чтоб гибко и независимо. Вот почему это работает для таких гигантов как Netflix или Spotify

Для команд по 5-6 человек на всю компанию вы на нормальный девопс убьете не меньше ресурсов, чем на, собственно, разработку микрух. Это из собственного опыта.
Хотя сейчас kubernetes + AWS сервисы и облегают задачу с service discovery, failover и т.п., но мороки все равно хватает.
AFAIR в circe макрос только для проверки, что можно вывести энкодер. А сам вывод на старом добром shapeless
Ммм. Немного некорректно дано определение вывода.

Автоматический вывод тайп-классов — это фактически вывод тайп-класса для некого типа `T` на основе уже имеющейся информации. Например, если у вас описаны тайп-классы для примитивов, можно вывести через LabelledGeneric для кейс-классов. А через копродукты еще и для трейтов.

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

Возьмем, как пример, библиотеку circe для работы с JSON. Есть множество энкодеров/декодеров для примитивов из коробки. На основе этих энкодеров в circe есть дженерик для автоматического вывода энкодеров для любых классов (если есть необходимый). Т.е. в вашем кейсе достаточно было один раз описать свои энкодеры для необходимых примитивов и дальше использовать их сколько душе угодно. И никакого абуза макросов.

Евгений говорил, что холивар на тему, когда использовать type level программирование, а когда — макросы, может длиться очень долго. Но основная мысль — макросы нужны там, где у нас реальный кодоген и мы пишем сложные деревья. По-крайне мере, в большинстве крупных проектов они так и работают.

Для L-уровня имхо лучше использовать type level подход просто по той причине, что это сопровождать будет проще.
У вашего комментария была мысль?
Ну это уже звучит как трешталк неосилятора.

Все там читаемо.
И на 100% процентов уверен, что на _ЛЮБОМ_ языке, который человеку не знаком, можно найти такой пример, что у субъекта прикипит и он начнет исходить слюнями. От асма до name-yourself.

Макросы в скале в текущей реализации — это экспоуз компилятор наружу, за что их не особо любят (это же, о боже, надо понимать, что такое Expr и Tree!).
Позже появились квазицитаты, стало попроще. Сейчас пилят scala-meta, там все радужно и с пони.

Но меня всегда умиляло, как вылезают такие уникумы, и на абстрактных примерах использования макросов или type level программирования составляют суждение о языке как таковом. Это все равно что о крестах судить через призму шаблонов. Пфф
А разве нельзя было то же самое на shapeless зарядить с автоматическим выводом тайп-классов?
Там еще были бы и рекорды из коробки
Если речь про backpressure из коробки, то его сейчас каждый ленивый делает. Взять Akka стримы, например
Не правда про Guice. Scaldi хорош
А вы хоть раз писали на cake pattern'e? Особенно, когда зависимостей > 2?
Хм, интересно, как себя поведет shapeless + aux паттерн, да и вообще всё type-level программирование.
Хотя, если запилят частичное применение типов, то ничего страшного не случится.
Например, можно писать так:

for {
  a <- futureA
  b <- futureB
  c <- futureC
} yield {
...
}


Компилятор сам разложит на map/flatMap (можно даже с if подключить filter). Это для начального уровня.

Зайдя чуть дальше в ФП — там Future всё еще монада (ну ладно, тут я лукавлю, она монада, если забыть про эксепшены внутри, иначе left identity не выполняется, но не суть). А значит, можно подрубить монад-трансформеры и работать с Future[Option[A]] словно у вас праздник на улице. В коде ниже мы получаем доступ сразу до значения типа А внутри двух монад:

for {
  a <- futureOptA.optionT //a: A
  b <- futureOptB.optionT //b: B
  c <- futureOptC.optionT //c: C
} yield {
...
}


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

Любопытства ради, хотелось бы увидеть решение на джаве. Слышал, там Option тоже завезли.
На одной работе 5 бэкэндщиков.
На другой — 6.

Не вижу корреляции.
1
23 ...

Information

Rating
Does not participate
Location
Helsinki, Southern Finland, Финляндия
Date of birth
Registered
Activity