Составил шпаргалку ⬆️ , как не терять данные при работе с Kafka . Подойдет тем, кто еще на Zookeeper задержался, и тем, кто уже пересел на KRaft 🔝 .
В первую очередь думаем о конфигурации самого кластера (таблица 1). Следующим этапом может быть переход к 2 (лучше 3) дата-центрам. В этом случае мы должны выбрать между Stretched- и асинхронным кластером.
Однако помним, что исключительно горизонтального масштабирования недостаточно для отказоустойчивости без оглядки на данные: необходима их репликация👌 . Установив replication.factor, например в 2, мы получим еще одну копию для каждой партиции, которая будет находиться на другом брокере. Kafka производит распределение партиций по брокерам из разных стоек благодаря прописанному (вручную) у каждого брокера идентификатору стойки broker.rack.
В процессе репликации данные на партициях-фолловерах могут отставать от данных на партиции-лидере. Это может привести к неконсистентному состоянию данных, если брокер с лидер-партицией откажет⚰️ . Если это недопустимо, то реплики можно сделать синхронными. Выставляем настройки acks=-1 и enable.idempotence=true на продюсере!, не на брокере, а то многие путают. Консьюмеры не смогут прочитать данные, пока те не были успешно реплицированы на фолловерах, т.к. last commit (high watermarked) offset будет указывать на последнее синхронизированное сообщение. Хороший default для сохранения консистентности данных выглядит так:
Также не вижу повода не следовать рекомендациям разработчиков Kafka:
Чем больше число партиций в кластере, тем более долгое восстановление при падении мы получим🛠 .
Существует еще ряд продвинутых настроек, повышающих отказоустойчивость кластера. 😈 . При активированной настройке auto.leader.rebalance.enable (по умолчание true) каждые leader.imbalance.check.interval.seconds секунд, если количество не-preferred лидеров-партиций превышает leader.imbalance.per.broker.percentage, то происходит ребалансировка. Настройки flush.messages и flush.ms (чрезвычайно большой по умолчанию) позволяют выполнять принудительную запись на диск из dirty buffer, что может уберечь от отказа всех синхронных реплик (однако, вероятность этого крайне мала). Настройки max.connections, max.connection.creation.rate и max.connections.per.ip позволяют ограничить число клиентских коннектов к брокерам.
В первую очередь думаем о конфигурации самого кластера (таблица 1). Следующим этапом может быть переход к 2 (лучше 3) дата-центрам. В этом случае мы должны выбрать между Stretched- и асинхронным кластером.
Однако помним, что исключительно горизонтального масштабирования недостаточно для отказоустойчивости без оглядки на данные: необходима их репликация
В процессе репликации данные на партициях-фолловерах могут отставать от данных на партиции-лидере. Это может привести к неконсистентному состоянию данных, если брокер с лидер-партицией откажет
acks=all
replication.factor=3
min.insync.replicas=2
enable.idempotence=true
Также не вижу повода не следовать рекомендациям разработчиков Kafka:
не создавать более 4k партиций на одном брокере
не создавать более 200k партиций в кластере
Чем больше число партиций в кластере, тем более долгое восстановление при падении мы получим
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Тихий убийца вашей продуктивности
Но сегодня хотел рассказать не об этом. Вы чувствовали в помещении духоту?Не путать просто с высокой температурой. Особенно она заметна на контрасте с улицей. Обычно виновником является CO2. Углекислый газ не имеет ни цвета ни запаха, поэтому повышение его концентрации в помещении возможно отследить только по своим ощущениям (когда она будет уже высока) или с помощью специальных датчиков.
Для того, чтобы понимать качество воздуха в помещении, в котором работаю (дома на удаленке😏 ), лет 5 назад я приобрел монитор качества воздуха за 8-10 т.р. Можете посмотреть подробный обзор на него здесь . Мне аппарат служит верой и правдой все это время. Кстати, уже вышла вторая версия, которую хвалят еще больше. И обзор на нее уже есть. Сейчас их великое множество и они отлично работают (даже совсем бюджетные), так что можно брать любой. Только обращайте внимание на интеграцию с умными домами и возможность настроить автоматизацию по типу открывания окна или включения кондиционера, если она вам нужна.
Итак, что же он измеряет?
1️⃣ концентрацию CO2 в ppm (parts per million)
2️⃣ концентрацию частиц PM2.5 (меньше 2,5 мкм). Они могут проходить через наши защитные барьеры, поэтому так опасны. Вы перестанете встряхивать постельное белье, увидев, как растет этот показатель
3️⃣ tVOC (летучие органические соединения), которые могут испускать, например, фанера и мебель, краски. Если уровень в вашем помещении стабильно высокий, то вам стоит поискать его причину
4️⃣ ну и, конечно, температуру и влажность
Какие уровни ppm для CO2 приемлемы?
< 800 ppm наслаждаемся жизнью🔝
800 ppm — 2000 ppm появляется усталость, потеря сосредоточенности, неприятное ощущение духоты
2000 ppm — 5000 ppm головная боль, сонливость, хочется покинуть помещение
> 5000 ppm бегите, глупцы!⚰️
Ок, концентрацию CO2 (и других частиц) в воздухе измерили. И что дальше? Лучший способ снизить уровень CO2 в помещении — это разбавлять его воздухом с улицы. Вентиляция помещения — это ключ к успеху.
Летом, если воздух снаружи чистый, то можно просто открыть окно. Если воздух грязный, то его нужно фильтровать (умеют, например, бризеры). Зимой воздух с улицы надо еще и подогревать (те же бризеры), либо подавать в малых объемах (клапаны на пластиковые окна с фильтрами). В идеале каждое помещение в доме/квартире должно быть подключено к HVAC-системе (Heating, Ventilation, and Air Conditioning), которую, вы, вероятно, видели в отелях.
Еще хочу отметить 2 факта!
Дышите полной грудью!
Перестань смотреть TikTok, рилсы и шортсы! Да, да, это чистая правда!🤔
Но сегодня хотел рассказать не об этом. Вы чувствовали в помещении духоту?
Для того, чтобы понимать качество воздуха в помещении, в котором работаю (дома на удаленке
Итак, что же он измеряет?
Какие уровни ppm для CO2 приемлемы?
< 800 ppm наслаждаемся жизнью
800 ppm — 2000 ppm появляется усталость, потеря сосредоточенности, неприятное ощущение духоты
2000 ppm — 5000 ppm головная боль, сонливость, хочется покинуть помещение
> 5000 ppm бегите, глупцы!
Ок, концентрацию CO2 (и других частиц) в воздухе измерили. И что дальше? Лучший способ снизить уровень CO2 в помещении — это разбавлять его воздухом с улицы. Вентиляция помещения — это ключ к успеху.
Летом, если воздух снаружи чистый, то можно просто открыть окно. Если воздух грязный, то его нужно фильтровать (умеют, например, бризеры). Зимой воздух с улицы надо еще и подогревать (те же бризеры), либо подавать в малых объемах (клапаны на пластиковые окна с фильтрами). В идеале каждое помещение в доме/квартире должно быть подключено к HVAC-системе (Heating, Ventilation, and Air Conditioning), которую, вы, вероятно, видели в отелях.
Еще хочу отметить 2 факта!
Подавляющее большинство кондиционеров не освежает воздух, а только охлаждает его, так как воздух из помещения ходит по замкнутому контуру до внешнего блока и обратно.
Домашние воздухоочистители не поглощают углекислый газ, а лишь отфильтровывают загрязняющие частицы.
Дышите полной грудью!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤯1
Старый добрый Serial Garbage Collector (GC) верой и правдой служит нам c 1996, когда была выпущена самая первая версия всеми нами любимого языка Java. Своим присутствием он радует нас во всех популярных рантаймах (Oracle, OpenJDK, Amazon Corretto, Azul Zulu, AdoptOpenJDK ныне Adoptium, Liberica, и других).
Именно с этого GC многие начали свое знакомство с темой сборки мусора. За это время вдоль и поперек изучены принципы его работы, но если вам все же хочется почитать об этом и других GC подробнее, то рекомендую ставшую легендарной серию статей на habr. Тем не менее мне бы хотелось затронуть ряд не самых очевидных вещей, связанных с Serial GC.
1️⃣ В чем основная причина долголетия Serial GC? Низкие требования к ресурсам окружения. Он прекрасно подойдет для запуска юнит-тестов, "скриптов" и локальной разработки. Хотя, возможно, в этих кейсах вы захотите присмотреться к Epsilon GC, который не убирает мусор, а значит не имеет накладных расходов:
К маломощным средам также можно отнести и контейнеры. Обычно их стараются ограничивать в ресурсах (часто выделяют 1 ядро CPU и/или память менее 1792 MB), а масштабирование проводят не вертикально, а горизонтально за счет увеличения количества инстансов приложения.У вас в компании тоже подсели на иглу микросервисной архитектуры и k8s ❗️ ?
Расскажу связанный с этим факап😵 , который был в моей практике: на проде вместо предполагаемого G1 виртуальная машина предпочла использовать Serial GC. Все из-за пресловутой контейнеризации и малого объема ресурсов, выделенных контейнеру. Согласитесь, неприятно увидеть громадные STW в отзывчивом приложении. Подробнее об этом можно прочитать в книге Java Performance, Scott Oaks в главе 5. An Introduction to Garbage Collection.
Посмотреть используемый GC в новых версиях можно так:
а в старых так:
На проде же рекомендую текущий GC выводить на дашборд в условную Grafana. Это убережет вас от неприятных сюрпризов, в том числе при миграциях между версиями Java.
2️⃣ Несмотря на всю простоту Serial GC, его сложно тюнить. Достигается это настройками размеров областей Eden, Survivor и Tenured. Мне неизвестен никто, кто бы этим занимался. Даже официальный гайд от Oracle по тюнингу GC как бы намекает, что делать это не нужно, любезно переходя от главы 5. Available Collectors сразу к главе 6. The Parallel Collector.
3️⃣ Так как Minor GC чистит только Young-область, то объекты Tenured-области фактически становятся GC Roots. Ссылки же "молодых" объектов на "старые" — игнорируются. Мысль вроде бы несложная, но и проговаривается нечасто. А вот упоминаний Major GC, которая часто упоминается в статьях, ни в логах, ни в исходном коде OpenJDK мне не встретились (может в других есть, не смотрел), только Pause Young и Pause Full.
Ставь ⚡️, если можешь выбирать GC на свой вкус, ставь 🐳, если сидишь на Go c одним GC на выбор.
Именно с этого GC многие начали свое знакомство с темой сборки мусора. За это время вдоль и поперек изучены принципы его работы, но если вам все же хочется почитать об этом и других GC подробнее, то рекомендую ставшую легендарной серию статей на habr. Тем не менее мне бы хотелось затронуть ряд не самых очевидных вещей, связанных с Serial GC.
1️⃣ В чем основная причина долголетия Serial GC? Низкие требования к ресурсам окружения. Он прекрасно подойдет для запуска юнит-тестов, "скриптов" и локальной разработки. Хотя, возможно, в этих кейсах вы захотите присмотреться к Epsilon GC, который не убирает мусор, а значит не имеет накладных расходов:
java -XX:+UseEpsilonGC GCAnalysisApp
К маломощным средам также можно отнести и контейнеры. Обычно их стараются ограничивать в ресурсах (часто выделяют 1 ядро CPU и/или память менее 1792 MB), а масштабирование проводят не вертикально, а горизонтально за счет увеличения количества инстансов приложения.
Расскажу связанный с этим факап
Посмотреть используемый GC в новых версиях можно так:
java -Xlog:gc*:file=gc.log:time GCAnalysisApp
а в старых так:
java -XX:+PrintGCDetails GCAnalysisApp
На проде же рекомендую текущий GC выводить на дашборд в условную Grafana. Это убережет вас от неприятных сюрпризов, в том числе при миграциях между версиями Java.
2️⃣ Несмотря на всю простоту Serial GC, его сложно тюнить. Достигается это настройками размеров областей Eden, Survivor и Tenured. Мне неизвестен никто, кто бы этим занимался. Даже официальный гайд от Oracle по тюнингу GC как бы намекает, что делать это не нужно, любезно переходя от главы 5. Available Collectors сразу к главе 6. The Parallel Collector.
3️⃣ Так как Minor GC чистит только Young-область, то объекты Tenured-области фактически становятся GC Roots. Ссылки же "молодых" объектов на "старые" — игнорируются. Мысль вроде бы несложная, но и проговаривается нечасто. А вот упоминаний Major GC, которая часто упоминается в статьях, ни в логах, ни в исходном коде OpenJDK мне не встретились (может в других есть, не смотрел), только Pause Young и Pause Full.
Ставь ⚡️, если можешь выбирать GC на свой вкус, ставь 🐳, если сидишь на Go c одним GC на выбор.
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡3🐳2👾2
После предыдущего поста еще не захотелось подтюнить GC у себя на проекте? Возможно потому, что вы еще не знакомы с моим любимым ресурсом 🥰 , который собрал все опции JVM по версиям от различных поставщиков. Ресурс ведет соавтор также горячо любимой мной книги с кабанчиком козлом Optimizing Java.
В рабочих задачах периодически возникает необходимость подтюнить JVM и GC в частности. Связано это обычно со спецификой (высокой) нагрузки. Самое банальное — перейти на "новые" Shenandoah и ZGC для обеспечения низкого latency (в том числе за счет ультракоротких STW).
Однако не стоит бежать впереди паровоза, в первую очередь проанализируйте узкие места и потенциальные проблемы вашего кода и архитектуры. За примером далеко ходить не пришлось. На ревью прилетел такой код:
Разработчик задумал последовательное выполнение задач из списка, пока не наступит stopTimeInFuture. Однако без задания ленивости с помощью asSequence() операция takeWhile выполнится сразу для всех элементов, не успев получить false. Это означает, что в map будут выполнены все задачи из taskList😵 .
А может вам нужно пересмотреть работу ключевого алгоритма? Так, Jackson показывает себя не лучшим образом по отношению к конкурентам. Или вы захотите поменять Redis 6 на более производительный KeyDB? Или с KeyDB вернуться обратно на Redis 7😂 ?
В любом случае оценивайте проблему комплексно, а то получите экономию на спичках.
🍂 Всем прекрасной первой осенней рабочей недели 🍁
В рабочих задачах периодически возникает необходимость подтюнить JVM и GC в частности. Связано это обычно со спецификой (высокой) нагрузки. Самое банальное — перейти на "новые" Shenandoah и ZGC для обеспечения низкого latency (в том числе за счет ультракоротких STW).
Однако не стоит бежать впереди паровоза, в первую очередь проанализируйте узкие места и потенциальные проблемы вашего кода и архитектуры. За примером далеко ходить не пришлось. На ревью прилетел такой код:
taskList
.takeWhile { LocalDateTime.now(clock) < stopTimeInFuture }
.map { // do some time-consuming work // }
...
Разработчик задумал последовательное выполнение задач из списка, пока не наступит stopTimeInFuture. Однако без задания ленивости с помощью asSequence() операция takeWhile выполнится сразу для всех элементов, не успев получить false. Это означает, что в map будут выполнены все задачи из taskList
А может вам нужно пересмотреть работу ключевого алгоритма? Так, Jackson показывает себя не лучшим образом по отношению к конкурентам. Или вы захотите поменять Redis 6 на более производительный KeyDB? Или с KeyDB вернуться обратно на Redis 7
В любом случае оценивайте проблему комплексно, а то получите экономию на спичках.
🍂 Всем прекрасной первой осенней рабочей недели 🍁
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1👍1
Жаль, конечно, что декларативный SQL "обогащен" таким невероятным костылем, как транзакции. Для меня является большой загадкой, как в сколь-нибудь большой команде или развесистой системе уберечь себя от аномалий по данным, связанных с транзакциями. Неосторожно добавил новый запрос и ⚰️ . Ставим уровень изоляции Serializable? Тогда в производительности потеряем...
Какие есть варианты?
Поставить на поток нагрузочное тестирование. Нам потребуются постоянно высокого уровня автоматизация тестов и компетентный сотрудник, который будет результаты этих тестов обрабатывать. Как бы грустно ни звучало, но для бизнеса обычно это непозволительная роскошь. В дополнение к этому имеем недетерминированное поведение, когда звезды могут сойтись таким образом, что при теоретической вероятности возникновения аномалий — они не возникнут в очередном прогоне.
Альтернативы? Можно писать интеграционные тесты на уровне сервиса (testcontainers), пытаясь повторить известные нам аномалии. А в чем собственно сложность этого подхода? На Википедии, как и на многих других ресурсах, вам с удовольствием расскажут про такие аномалии, как Lost Update, Dirty Read, Non-Repeatable Read, Phantom Reads. Про Dirty Write, Cursor Lost Update, и Read Skew с Write Skew (которые в некотором смысле являются производными от Lost Update и Non-Repeatable Read соответственно) рассказывают значительно реже. Вполне возможно, что про них не будет знать (или, точнее, не будет задумываться) и автор тестов. Автор тестов может также нехотеть знать про все бизнес-сценарии, которые будут приводить к столкновениям транзакций по данным. Это особенно актуально, если он из другой команды, не связанной плотно с вашим продуктом. Если вы проповедуете TDD, то у вас хорошие шансы преуспеть, хотя человеческий фактор тут остается все равно слишком высоким.
Все еще не страшно? Добиваю🤕 Хотя основные уровни изоляции СУБД обычно соответствуют стандарту (последний ISO/IEC 9075-2:2023), детали их реализации, а соответственно и поведение в реальных условиях могут различаться. Эти различия связаны с архитектурными решениями (использование MVCC, блокировок или снимков состояния) и различными оптимизациями для выживания в условиях высокой нагрузки (конкурентное преимущество на рынке). Делаем вывод, что стандартом де-факто является документация/спецификация вашей СУБД, а значит при смене БД на проекте (что, конечно, бывает не так часто, хотя в условиях санкций многие на PostgreSQL переезжают) или даже при поднятии версии можем столкнуться с новым для себя поведением.
Страшно жить🙀
Какие есть варианты?
Поставить на поток нагрузочное тестирование. Нам потребуются постоянно высокого уровня автоматизация тестов и компетентный сотрудник, который будет результаты этих тестов обрабатывать. Как бы грустно ни звучало, но для бизнеса обычно это непозволительная роскошь. В дополнение к этому имеем недетерминированное поведение, когда звезды могут сойтись таким образом, что при теоретической вероятности возникновения аномалий — они не возникнут в очередном прогоне.
Альтернативы? Можно писать интеграционные тесты на уровне сервиса (testcontainers), пытаясь повторить известные нам аномалии. А в чем собственно сложность этого подхода? На Википедии, как и на многих других ресурсах, вам с удовольствием расскажут про такие аномалии, как Lost Update, Dirty Read, Non-Repeatable Read, Phantom Reads. Про Dirty Write, Cursor Lost Update, и Read Skew с Write Skew (которые в некотором смысле являются производными от Lost Update и Non-Repeatable Read соответственно) рассказывают значительно реже. Вполне возможно, что про них не будет знать (или, точнее, не будет задумываться) и автор тестов. Автор тестов может также не
Хороший взгляд на аномалии при работе с транзакциями можно найти здесь
Все еще не страшно? Добиваю
Страшно жить
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🤓3
Вот такой список недостатков я составил при приемке мебели на заказ 😁 . Надеюсь, вы разобрали мой корявый почерк 😺 15 замечаний в 3 из 5 изделий: это и недокомплект, и ошибки при распиле и непродуманные функциональные решения. Почему в двух других изделиях проблем нет? Их другой технолог проектировал 😃 . И на том спасибо.
В мебельном производстве каждый проект уникален, но процессы и материалы в большинстве стандартные. Все, как у нас в айтишечке, только вместо материалов — язык программирования и окружение программы. Однако, как мы видим, ни там, ни там это не гарантирует качество без должного контроля.
Несмотря на то, что я был активно вовлечен в процесс отрисовки проекта, этого все равно оказалось недостаточно. На получившихся схематичных рендерах от дизайнера многих ошибок еще не было, а чертежи от технологов (именно они идут в производство) мне не передали😢 . В итоге полноценное "код-ревью" провести не удалось.
В моем случае недостатки возникли строго из-за человеческого фактора — один технолог спроектировал лучше, чем другой. Или дизайнер не смогла донести идеи до второго технолога. Кто-то не доложил нужную позицию, а кто-то не так распилил...
При разработке ПО мы сталкиваемся с похожими вызовами, но у нас есть отлаженные методы для обеспечения качества на каждом из этапов жизненного цикла:
✔️верификация
✔️тесты всех сортов и расцветок
✔️статический и динамический анализ
✔️код-ревью (аудит)
✔️профилирование
✔️непрерывная интеграция и доставка (CI/CD)
✔️рефакторинг и автоматизированная модификация кода
Большинство из этих методов прекрасно поддается автоматизации, что позволяет значительно минимизировать влияние человеческого фактора. В случае мебели на заказ о высоком уровне автоматизации процессов производства и контроля качества речи не идет.
Монтажники, заканчивая сборку, сказали, что на производстве все переделают, а установленные изделия демонтируют. Сюр🥴 . Сразу возник вопрос: Какая в мебельном бизнесе маржинальность? Ладно, в IT она еще больше 😂 Всё же переделка изделий — это существенные дополнительные расходы. При таком waterfall-подходе не будет ли выгоднее больше инвестировать в начальный этап проектирования и контроля, чтобы избежать всех этих неприятностей? Это же не хотфикс парой кликов на прод залить 😆 .
В мебельном производстве каждый проект уникален, но процессы и материалы в большинстве стандартные. Все, как у нас в айтишечке, только вместо материалов — язык программирования и окружение программы. Однако, как мы видим, ни там, ни там это не гарантирует качество без должного контроля.
Несмотря на то, что я был активно вовлечен в процесс отрисовки проекта, этого все равно оказалось недостаточно. На получившихся схематичных рендерах от дизайнера многих ошибок еще не было, а чертежи от технологов (именно они идут в производство) мне не передали
В моем случае недостатки возникли строго из-за человеческого фактора — один технолог спроектировал лучше, чем другой. Или дизайнер не смогла донести идеи до второго технолога. Кто-то не доложил нужную позицию, а кто-то не так распилил...
При разработке ПО мы сталкиваемся с похожими вызовами, но у нас есть отлаженные методы для обеспечения качества на каждом из этапов жизненного цикла:
✔️верификация
✔️тесты всех сортов и расцветок
✔️статический и динамический анализ
✔️код-ревью (аудит)
✔️профилирование
✔️непрерывная интеграция и доставка (CI/CD)
✔️рефакторинг и автоматизированная модификация кода
Большинство из этих методов прекрасно поддается автоматизации, что позволяет значительно минимизировать влияние человеческого фактора. В случае мебели на заказ о высоком уровне автоматизации процессов производства и контроля качества речи не идет.
Монтажники, заканчивая сборку, сказали, что на производстве все переделают, а установленные изделия демонтируют. Сюр
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2🤔1
Заканчиваю прохождение практикума по k8s. Давно хотел закрыть этот гештальт. Тем более, что на работе появляется все больше соответствующих задач как в уже имеющихся, так и в новых кластерах, которые только предстоит поднять.
На прошлых выходных завершил работу над финальным заданием / проектом. Нужно было подготовить helm chart'ы для разворачивания окружения (NFS provisioner, EFK, Prometheus-стек, cert-manager, nginx-ingress-controller) и настроить Gitlab CI/CD для приложения с базой данных. Оставалось только защитить проект перед ментором на очной встрече.
Но в дело вмешалась миграция платформы в Yandex Cloud😢 Случилось то, чего я ждал, но боялся... Если кластер на старой платформе был версии 1.27, то на новой — 1.30. Сами ноды также были настроены по-другому. Если раньше мы прописывали DNS на Cloudflare, то теперь доступа к какому-либо API не осталось.
Чарты перепишем, ноды донастроим, но с DNS то что делать? Буду использовать nip.io. Это бесплатныйбез смс и регистрации DNS-сервис, который предоставляет wildcard DNS-записи для любого IP-адреса. Как это работает? Если создать доменное имя, заканчивающееся на
Очень даже удобно для учебных задач, разработки и тестирования, когда требуется доменное имя вместо IP-адреса. Можно использовать даже в локальной сети или за NAT! Главное — ничего дополнительно настраивать не надо⌨️ .
Пока, правда, не разобрался, почему Let's Encrypt сертификат не подтягивается. Думал сначала, что не прошел ограничение rate limiter'a Let's Encrypt по домену (не один же я такой умный nip.io использовать), но в логах☔️ . Будем разбираться!
На прошлых выходных завершил работу над финальным заданием / проектом. Нужно было подготовить helm chart'ы для разворачивания окружения (NFS provisioner, EFK, Prometheus-стек, cert-manager, nginx-ingress-controller) и настроить Gitlab CI/CD для приложения с базой данных. Оставалось только защитить проект перед ментором на очной встрече.
Но в дело вмешалась миграция платформы в Yandex Cloud
Чарты перепишем, ноды донастроим, но с DNS то что делать? Буду использовать nip.io. Это бесплатный
.nip.io, то оно автоматически разрезолвится в указанный в имени IP-адрес. Теперь на пальцах. Если у меня есть публичный IP-адрес 51.250.34.211, то при обращении к 51.250.34.211.nip.io, это доменное имя разрезолвится в 51.250.34.211. Поддомены также работают: grafana-51-250-34-211.nip.io и kibana.51.250.34.211.nip.io разрезолвятся в 51.250.34.211.
Очень даже удобно для учебных задач, разработки и тестирования, когда требуется доменное имя вместо IP-адреса. Можно использовать даже в локальной сети или за NAT! Главное — ничего дополнительно настраивать не надо
Пока, правда, не разобрался, почему Let's Encrypt сертификат не подтягивается. Думал сначала, что не прошел ограничение rate limiter'a Let's Encrypt по домену (не один же я такой умный nip.io использовать), но в логах
failed to perform self check GET request, хотя конфиг по адресу /.well-known/acme-challenge/ лежит Please open Telegram to view this post
VIEW IN TELEGRAM
😢1
Этот код вбил последний гвоздь в крышку гроба изменяемого/мутабельного состояния в моем коде.
Что произошло? На ревью я увидел следующее (с точностью до нейминга):
Мы изменяем состояние приложения (через состояние SomeProperties) каждый раз, когда вызывается doSomeImportantThing⚰️ . Мне кажется, что на несколько минут я потерял дар речи. Самое интересное, что это решение работает в проде и не создает проблем. Или мы о них пока просто не знаем? 😃 Чудеса, да и только!
Это яркий пример того, что если API позволяет допустить ошибку, то разработчик ее совершит. Несмотря на то, что Kotlin весь такой "будем использовать val и const вместо невыразительных final и static final", "интерфейсы List, Set, Map будут отвечать за коллекции, предоставляющие read-only доступ", "будем повсеместно использовать неизменяемые data-классы вкупе с невероятно удобным copy()", к сожалению, наследие в виде развесистых Java-библиотек никуда не делось😢 .
Kotlin автоматически генерирует свойства на основе того, как они объявлены в Java: для final — val, в противном случае — var. Что тогда мешало изначально в библиотеке сделать все поля final? Да просто это реально стремно выглядит. Собственно поэтому final и не используют повсеместно.
В нашем ImportedJavaLibClass без дополнительных манипуляцией someField продолжит считаться мутабельным в Kotlin, а значит его в любой момент можно будет изменить. Признавайтесь, хватит решимости идти править библиотеку😐 ?
С nullability дела обстоят гораздо лучше. Мы можем навесить аннотации Но, должны же на это быть тесты написаны, правда 🤣 ?
Что произошло? На ревью я увидел следующее (с точностью до нейминга):
@ConfigurationProperties
data class SomeProperties (
val property: ImportedJavaLibClass,
...
)
@Service
class SomeService(
val someProperties: SomeProperties,
) {
fun doSomeImportantThing{
...
return someProperties.property.apply { someField = calculatedValue }
}
}
Мы изменяем состояние приложения (через состояние SomeProperties) каждый раз, когда вызывается doSomeImportantThing
Это яркий пример того, что если API позволяет допустить ошибку, то разработчик ее совершит. Несмотря на то, что Kotlin весь такой "будем использовать val и const вместо невыразительных final и static final", "интерфейсы List, Set, Map будут отвечать за коллекции, предоставляющие read-only доступ", "будем повсеместно использовать неизменяемые data-классы вкупе с невероятно удобным copy()", к сожалению, наследие в виде развесистых Java-библиотек никуда не делось
Kotlin автоматически генерирует свойства на основе того, как они объявлены в Java: для final — val, в противном случае — var. Что тогда мешало изначально в библиотеке сделать все поля final? Да просто это реально стремно выглядит. Собственно поэтому final и не используют повсеместно.
В нашем ImportedJavaLibClass без дополнительных манипуляцией someField продолжит считаться мутабельным в Kotlin, а значит его в любой момент можно будет изменить. Признавайтесь, хватит решимости идти править библиотеку
С nullability дела обстоят гораздо лучше. Мы можем навесить аннотации
@NotNull или @Nullable для полей библиотечных Java-классов. Останется только надеяться, что в других проектах мы никому при поднятии версии библиотеки не поломаем использование рефлексии.Please open Telegram to view this post
VIEW IN TELEGRAM
👍7😱1
Я часто страдаю от того, что при возникновении вопросов первым делом не обращаюсь к документации. Даже не знаю, что повлияло на отсутствие этой полезной привычки. Вероятно, мне просто не хочется выискивать и компилировать ответ самостоятельно. Это ж думать надо 😰 Всегда есть надежда, что на твой вопрос в Google найдется ответ по первой ссылке, которая по удачному стечению обстоятельств ведет на StackOverflow. А если еще и ответ залайканный будет... Хотя бы несколько десятков, а лучше сотен и тысяч лайков. Но чем сложнее вопрос, тем меньше знает Google. Хорошо, что можно еще в ChatGPT заскочить 🤤 .
В этот раз ко мне ученик пришел с простым вопросом (на скрине). Я, честно говоря, забыл уже, что это за backing properties и backing field, но тема должна была быть очень простой и объясняться парой предложений. Первым делом хотелось провалидировать ответ ChatGPT, который ему показался непонятным. Я задал ChatGPT (странный, если быть в контексте) вопрос:
Ответ мне не понравился. По крайней мере захотелось поискать другие источники или задать уточняющие вопросы. Я загуглил еще пару статей на эту тему. Тут мне попадались уже более интересные экземпляры, которые давали больше контекста, но ученику их скидывать все равно не хотелось. Я решил посмотреть, а что собственно написано в документации? Это был прекрасный пример того, какой она должна быть: лаконичные примеры кода, понятные комментарии и идеи, которые за ними скрываются. Тут же стало ясно, что все увиденные мной статьи являются перефразированными, но в то же время менее информативными копиями оригинала. В итоге для новичка получился такой ответ, в котором я лишь еще раз подсветил основные идеи:
Так что если изучаем Kotlin, то обращаемся к документации. Это must have. В свое время мне также очень помогли Kotlin in Action и Atomic Kotlin, которые, к сожалению, давно не обновлялись, но все же могут быть полезны, если вас не интересуют последние нововведения. Качественные книги могут не просто пересказать документацию, а более глубоко раскрыть заложенные идеи и концепции изучаемой темы. Такие книги, однако, придется ещё поискать...
Мой друг, кстати, только по доке Golang выучил. Он большой любитель почитать, man'ы⌨️ .
Кроме того некоторые документации часто версионируются, что позволяет сравнить разные версии. Например, документация по всеми любимой PostgreSQL. Вот еще один яркий пример. Даже инструкции по миграции между версиями в наличии.
Вроде тема и совсем капитанская, но, как мне кажется, актуальная для многих. Если вы на постоянной основе не взаимодействуете с качественными источниками информации (вроде книг или документации) по интересующей вас теме, то из раза в раз будете черпать обрывочные знания из несвязанных друг с другом источников, что в средне- и долгосрочной перспективе отсрочит достижение поставленных вами целей.
В этот раз ко мне ученик пришел с простым вопросом (на скрине). Я, честно говоря, забыл уже, что это за backing properties и backing field, но тема должна была быть очень простой и объясняться парой предложений. Первым делом хотелось провалидировать ответ ChatGPT, который ему показался непонятным. Я задал ChatGPT (странный, если быть в контексте) вопрос:
Расскажи, в чем разница между backing properties и backing field в Kotlin?
Ответ мне не понравился. По крайней мере захотелось поискать другие источники или задать уточняющие вопросы. Я загуглил еще пару статей на эту тему. Тут мне попадались уже более интересные экземпляры, которые давали больше контекста, но ученику их скидывать все равно не хотелось. Я решил посмотреть, а что собственно написано в документации? Это был прекрасный пример того, какой она должна быть: лаконичные примеры кода, понятные комментарии и идеи, которые за ними скрываются. Тут же стало ясно, что все увиденные мной статьи являются перефразированными, но в то же время менее информативными копиями оригинала. В итоге для новичка получился такой ответ, в котором я лишь еще раз подсветил основные идеи:
Что такоеbacking propertiesиbacking fieldхорошо описано в документации https://kotlinlang.org/docs/properties.html
В примере сbacking fieldshttps://kotlinlang.org/docs/properties.html#backing-fields вместо использования имени свойстваcounterдля присваивания, компилятор нам предоставляет идентификаторfield. Для чего?counter = valueпредставляет из себя вызов сеттера для свойства, который мы непосредственно сейчас определяем, что приведет к рекурсивному вызову сеттера внутри сеттера.
В примере сbacking propertieshttps://kotlinlang.org/docs/properties.html#backing-properties для работы открытого свойстваpublic val tableпросто используется дополнительное скрытое свойствоprivate var _table, которое можем назвать любым образом. Это своего рода трюк/лайфхак, про который нам решили рассказать авторы документации.
Так что если изучаем Kotlin, то обращаемся к документации. Это must have. В свое время мне также очень помогли Kotlin in Action и Atomic Kotlin, которые, к сожалению, давно не обновлялись, но все же могут быть полезны, если вас не интересуют последние нововведения. Качественные книги могут не просто пересказать документацию, а более глубоко раскрыть заложенные идеи и концепции изучаемой темы. Такие книги, однако, придется ещё поискать...
Мой друг, кстати, только по доке Golang выучил. Он большой любитель почитать, man'ы
Кроме того некоторые документации часто версионируются, что позволяет сравнить разные версии. Например, документация по всеми любимой PostgreSQL. Вот еще один яркий пример. Даже инструкции по миграции между версиями в наличии.
Вроде тема и совсем капитанская, но, как мне кажется, актуальная для многих. Если вы на постоянной основе не взаимодействуете с качественными источниками информации (вроде книг или документации) по интересующей вас теме, то из раза в раз будете черпать обрывочные знания из несвязанных друг с другом источников, что в средне- и долгосрочной перспективе отсрочит достижение поставленных вами целей.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔1🤩1
Как вы начинаете изучать новую для себя тему?
Anonymous Poll
43%
документация
49%
YouTube
22%
книги
30%
курсы
65%
статьи
Мой друг рассказал мне, наверное, уже с год назад о сервисе, который разработает витаминный комплекс под твои потребности. Как это работает? Сначала сдаешь длинный список анализов крови. После того, как придут результаты — тебя проконсультируют врачи (правда, консультация другу не зашла) и пришлют в реально! красивых металлических баночках разноцветные гранулы.
Звучит и выглядит все круто, однако есть 2 НО.
Я немного не доверяю комплексам, куда входят сразу много компонентов. Если хотите просто дополнить свой несбалансированный рацион, то ок. Но, кажется, тут подойдут и обычные витаминно-минеральные комплексы, которые можно найти в аптеке или в магазине спортпита (там они ядрёнее: выше концентрации). Но если у вас есть выраженный дефицит... Для его закрытия врачи мне прописывали убойные дозы. Чтобы усвоиться они должны приниматься не только независимо от других витаминов, но и от некоторых продуктов, приемов пищи и в определенное время (чаще утром)🚨 .
И второе НО. Хотя все и очень удобно, но цена кусается. В этом сентябре я тоже решил организовать себе такой чекап, но самостоятельно. На том же сайте я посмотрел список анализов и сдал его урезанный вариант в лаборатории недалеко от дома. Получилось что-то около 20 т.р. Приемлемо💳 Что по результатам? Сходил к терапевту за интерпретацией.
Холестерин по верхней границе нормы. Вроде фастфудом и жирной пищей не увлекаюсь, но сидячий малоподвижный образ жизни нельзя списывать со счетов. Уже пью Омега-3 ПНЖК. Надо вернуть тренировки по сквошу, но ноги пока не доходят. Продолжаю пить D3, так как хочется дойти до середины нормального уровня (~60 единиц), тем более ,что начинается осенне-зимний период. Сейчас понял, что забыл еще спросить про повышенный ферритин. Оставлю это до следующего визита.
Планирую такой чекап проводить хотя бы раз в год, чтобы наносить недугам упреждающий удар👊 В будущем список анализов скорректирую, в том числе и после консультаций с врачами.
Всем крепкого здоровья! Не болейте🫶
Из того, что не подпадает под историю с витаминами, но что очень зашло — наличие в анализах некоторых популярных онкомаркёров. Кажется, что это те несколько тысяч, которые все же стоит заложить в своем ежегодном бюджете.
Звучит и выглядит все круто, однако есть 2 НО.
Я немного не доверяю комплексам, куда входят сразу много компонентов. Если хотите просто дополнить свой несбалансированный рацион, то ок. Но, кажется, тут подойдут и обычные витаминно-минеральные комплексы, которые можно найти в аптеке или в магазине спортпита (там они ядрёнее: выше концентрации). Но если у вас есть выраженный дефицит... Для его закрытия врачи мне прописывали убойные дозы. Чтобы усвоиться они должны приниматься не только независимо от других витаминов, но и от некоторых продуктов, приемов пищи и в определенное время (чаще утром)
D3 мне таким образом удалось поднять с дефицитных 15 единиц до приемлемых 43. Кто сталкивался с этим, поймут меня.
И второе НО. Хотя все и очень удобно, но цена кусается. В этом сентябре я тоже решил организовать себе такой чекап, но самостоятельно. На том же сайте я посмотрел список анализов и сдал его урезанный вариант в лаборатории недалеко от дома. Получилось что-то около 20 т.р. Приемлемо
Холестерин по верхней границе нормы. Вроде фастфудом и жирной пищей не увлекаюсь, но сидячий малоподвижный образ жизни нельзя списывать со счетов. Уже пью Омега-3 ПНЖК. Надо вернуть тренировки по сквошу, но ноги пока не доходят. Продолжаю пить D3, так как хочется дойти до середины нормального уровня (~60 единиц), тем более ,что начинается осенне-зимний период. Сейчас понял, что забыл еще спросить про повышенный ферритин. Оставлю это до следующего визита.
Планирую такой чекап проводить хотя бы раз в год, чтобы наносить недугам упреждающий удар
Всем крепкого здоровья! Не болейте
Please open Telegram to view this post
VIEW IN TELEGRAM
🤡4❤🔥3
На меня нахлынула волна ностальгии... Шесть лет назад, будучи молодым и зеленым 😏 , я хотел пройти сертификации по Java от Oracle: OCA и OCP. Я усердно готовился, но до экзаменов так и не дошел.
Что они из себя представляют?
OCA оценивает знание фундаментальных основ Java Core. Почти каждый вопрос будет пытаться вас обмануть, проверяя, насколько вы хороший компилятор😃 . Тут и вызовы методов с некорректными сигнатурами, и неправильный нейминг, и необработанные исключения, и так далее по списку... В OCP рассматриваются более высокоуровневые концепции, например, Collection API, Streams, Concurrency и др., приправленные той же проверкой на внимательность.
Эмм, проверка на внимательность, опечатки?.. Звучит сомнительно? С одной стороны — да. Кажется, что хороший программист — не тот, кто не ошибается в синтаксисе. С другой стороны — опытный разработчик должен все это видеть и знать, как само собой разумеющееся. Тут понимаешь, что составляли экзамен авторы старой закалки, для которых такой уровень понимания в порядке вещей. От вас требуется всего лишь знание концепций языка и то, какое отражение в программном коде они находят. Как по мне, в эпоху ИИ, который пишет код сам, экзамен стал еще более актуальным.
Тут, наверное, стоит ответить на вопрос: «Что мне дала эта подготовка?» Это был своеобразный мостик между наивным использованием конструкций языка и:
1) сильными идеями Computer Science, заложенными в язык
2) логикой работы компилятора
о которых узнаешь и начинаешь задумываться. В голове возникал ряд вопросов:
• откуда и почему в коде видны static и non-static переменные вкупе с разными модификаторами доступа(не зная принципов, отгадать очень сложно)
• чем на самом деле являются вложенные классы(синтаксический сахар)
• почему стандартная библиотека Java нарушает принципы SOLID(иммутабельные коллекции и принцип подстановки Барбары Лисков)
• в чем причина использования final и effectively final переменных в анонимных классах(отсутствие полноразмерных замыканий с захватом по значению, а не по ссылке)
• и многие другие
Если у вас все же есть желание подготовиться к этим сертификациям, то существует ряд специализированных книг (OCA, OCP). Я еще пользовался такими тестами. Говорят, что они очень приближены к реальным. Для пущей уверенности можно прикупить дампы реальных экзаменов.
При подготовке я составлял для себя майндкарты (mind maps):
Java Core / OCA
Java Core / OCA / Non-Primitive Types
Java Core / OCP
Боюсь вспоминать, сколько времени было потрачено, хотя объем проделанной работы сейчас не кажется мне большим. Чтобы мои материалы использовать для подготовки в качестве единственного источника требуется серьезно их доработать. Буду это делать по мере возможности.
В любом случае это был увлекательный аттракцион, к которому, возможно, я еще вернусь в будущем. Но абсолютно точно тех ощущений уже не вернуть... Мой первый коммерческий опыт в роли разработчика, никакого ковида, путешествия c друзьями по Европе...
Что они из себя представляют?
OCA оценивает знание фундаментальных основ Java Core. Почти каждый вопрос будет пытаться вас обмануть, проверяя, насколько вы хороший компилятор
Эмм, проверка на внимательность, опечатки?.. Звучит сомнительно? С одной стороны — да. Кажется, что хороший программист — не тот, кто не ошибается в синтаксисе. С другой стороны — опытный разработчик должен все это видеть и знать, как само собой разумеющееся. Тут понимаешь, что составляли экзамен авторы старой закалки, для которых такой уровень понимания в порядке вещей. От вас требуется всего лишь знание концепций языка и то, какое отражение в программном коде они находят. Как по мне, в эпоху ИИ, который пишет код сам, экзамен стал еще более актуальным.
Тут, наверное, стоит ответить на вопрос: «Что мне дала эта подготовка?» Это был своеобразный мостик между наивным использованием конструкций языка и:
1) сильными идеями Computer Science, заложенными в язык
2) логикой работы компилятора
о которых узнаешь и начинаешь задумываться. В голове возникал ряд вопросов:
• откуда и почему в коде видны static и non-static переменные вкупе с разными модификаторами доступа
• чем на самом деле являются вложенные классы
• почему стандартная библиотека Java нарушает принципы SOLID
• в чем причина использования final и effectively final переменных в анонимных классах
• и многие другие
Если у вас все же есть желание подготовиться к этим сертификациям, то существует ряд специализированных книг (OCA, OCP). Я еще пользовался такими тестами. Говорят, что они очень приближены к реальным. Для пущей уверенности можно прикупить дампы реальных экзаменов.
При подготовке я составлял для себя майндкарты (mind maps):
Java Core / OCA
Java Core / OCA / Non-Primitive Types
Java Core / OCP
Боюсь вспоминать, сколько времени было потрачено, хотя объем проделанной работы сейчас не кажется мне большим. Чтобы мои материалы использовать для подготовки в качестве единственного источника требуется серьезно их доработать. Буду это делать по мере возможности.
В любом случае это был увлекательный аттракцион, к которому, возможно, я еще вернусь в будущем. Но абсолютно точно тех ощущений уже не вернуть... Мой первый коммерческий опыт в роли разработчика, никакого ковида, путешествия c друзьями по Европе...
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
Буквально по горячим следам после моего последнего поста вышло видео на канале Вадима Do4a Иванова про чекап организма.
Плюсом к анализам крови он затронул тему проведения УЗИ, которая выпала у меня из головы.
Чем УЗИ так хорошо?
1️⃣ стоит недорого
2️⃣ не вредит организму
3️⃣ делается быстро
Если вы обращались за лечением по ДМС, то знаете, что УЗИ и общий анализ крови назначают практически по-умолчанию, что еще раз подтверждает их эффективность: вас нужно вылечить с минимальными вложениями.
Я мельком посмотрел комплексные предложения от клиник. Диагностика по +- следующему списку:
• органы брюшной полости
• почки
• щитовидная железа
• сердце
• органы малого таза
• сосуды головного мозга и шеи
стоит 5–15 т.р.
Почему могут так отличаться цены, если не брать основной фактор – наценку на услуги. Это, конечно, квалификация врача и уровень оборудования(пока для меня Vivid S70, CANON APLIO 500, Logiq P6 и др. не более чем набор буков) .
Есть еще такие виды исследований, как рентген, МРТ и КТ, но они любо не безвредны, либо дороги. Самостоятельно назначать их себе я бы не стал. Кстати, врач при лечении может МРТ и КТ вам даже не предложить (потому что дорого для среднестатистического гражданина), поэтому я всегда спрашиваю, не стоит ли их сделать для получения ясной картины. То же касается и в целом любых дополнительных анализов.
Ок, чекап сделали. Что дальше? Как я уже говорил — консультируемся с врачами. Но этого, к сожалению, мало. Нужно не забывать следить за своим самочувствием✍️ . Вы находитесь со своим организмом 24/7 в отличие от врача. Только вы можете знать все его особенности, фиксировать причинно-следственные связи. Если вы не соберете такой анамнез, то у вас не будет хорошего подспорья перед всего лишь 15-30 минутной консультацией. Можно, конечно, пытаться отвечать на наводящие вопросы непосредственно на приеме, но качественно сделать это сходу у меня еще не получалось 😨 .
Врачи, однако, тоже бывают разные. В начале года в местной поликлинике меня сразу после недельного стационара хотели выписать с больничного с диагнозом пневмония, хотя все черным по белому было написано в выписке, правда, второй строчкой, после гриппа 😃 . Найти заинтересованного в вашем здоровье профессионала за вменяемые деньги пока тоже не кажется мне простой задачей (смотрю на опыт друзей), но это не повод не начать этот поиск.
На этом свою просветительскую миссию считаю выполненной. Дальше дело за вами😎
Это бизнесмен из СПб, а в прошлом — спортсмен, который пережил инфаркт, после чего начал пристально следить за своим здоровьем.
Плюсом к анализам крови он затронул тему проведения УЗИ, которая выпала у меня из головы.
Чем УЗИ так хорошо?
Если вы обращались за лечением по ДМС, то знаете, что УЗИ и общий анализ крови назначают практически по-умолчанию, что еще раз подтверждает их эффективность: вас нужно вылечить с минимальными вложениями.
Я мельком посмотрел комплексные предложения от клиник. Диагностика по +- следующему списку:
• органы брюшной полости
• почки
• щитовидная железа
• сердце
• органы малого таза
• сосуды головного мозга и шеи
стоит 5–15 т.р.
Почему могут так отличаться цены, если не брать основной фактор – наценку на услуги. Это, конечно, квалификация врача и уровень оборудования
Есть еще такие виды исследований, как рентген, МРТ и КТ, но они любо не безвредны, либо дороги. Самостоятельно назначать их себе я бы не стал. Кстати, врач при лечении может МРТ и КТ вам даже не предложить (потому что дорого для среднестатистического гражданина), поэтому я всегда спрашиваю, не стоит ли их сделать для получения ясной картины. То же касается и в целом любых дополнительных анализов.
Ок, чекап сделали. Что дальше? Как я уже говорил — консультируемся с врачами. Но этого, к сожалению, мало. Нужно не забывать следить за своим самочувствием
Врачи, однако, тоже бывают разные. В начале года в местной поликлинике меня сразу после недельного стационара хотели выписать с больничного с диагнозом пневмония, хотя все черным по белому было написано в выписке
На этом свою просветительскую миссию считаю выполненной. Дальше дело за вами
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥3🔥2
Посмотрел запись от 2018 года с конференции DevOxx, где Джошуа Блох (один из разработчиков платформы Java) распинается перед другими опытными? разработчиками о том, как эффективно! писать код на Java в функциональном стиле, используя λ и Stream API. Это при том, что все рассматриваемые фичи присутствовали уже в Java 8, которая вышла аж в 2014 году. Неужели такая хайповая тема так долго разгонялась?
Кажется, что индустрия сейчас работает на совсем других скоростях.Чего стоит только 36-секундное интро в ролике 😂 . Любой (ну почти) Java-стажер на собеседовании воспроизведет всю эту теорию. Хотя не удивлюсь, если в 2028 году мы продолжим c упоением обсуждать Project Loom.
Тема функционального программирования в Java, действительно, остается, популярной у авторов и по сей день. Ее изъездили вдоль и поперек: написаны многочисленные книги, статьи и курсы. Я каждый год сталкиваюсь с очередной статьей на habr, где стабильно наблюдаю заплюсованный комментарий с просьбой переключиться уже на другую тему.
Я не останусь в долгу и вкину свои пять копеек😀 . Все таблички, систематизирующие Method Reference, которые я встречал, мне не понравились, поэтому я нарисовал свою (прикреплена к посту).
Самым интересным здесь является тип Bound. Попробуем разобраться с ним при помощи байткода на следующем примере:
В
Логика
Внутри
В целом все очевидно, но нужно быть внимательными👍
P.S. не удержался и доработал майндакрты из поста
С другой стороны надо же было отрекламировать запоздавшее третье издание своей книги Effective Java. Она, стоит отметить, учитывает нововведения Java 9, вышедшей в 2017 году. Тем не менее делать упор целиком на фичи 4-х летней давности выглядит странно, но простим ему это.
Кажется, что индустрия сейчас работает на совсем других скоростях.
Тема функционального программирования в Java, действительно, остается, популярной у авторов и по сей день. Ее изъездили вдоль и поперек: написаны многочисленные книги, статьи и курсы. Я каждый год сталкиваюсь с очередной статьей на habr, где стабильно наблюдаю заплюсованный комментарий с просьбой переключиться уже на другую тему.
Я не останусь в долгу и вкину свои пять копеек
Самым интересным здесь является тип Bound. Попробуем разобраться с ним при помощи байткода на следующем примере:
class Example {
public static void main(String[] args) {
Instant then = Instant.now();
Predicate<Instant> p1 = then::isAfter;
Predicate<Instant> p2 = Instant.now()::isAfter;
Predicate<Instant> p3 = otherInstant -> Instant.now().isAfter(otherInstant); // Idea предлагает такой рефакторинг для p2 с оговоркой There are possible side effects found
}
}В
p1 берется заранее созданный объект then со стека:ALOAD 1
DUP
INVOKESTATIC java/util/Objects.requireNonNull (Ljava/lang/Object;)Ljava/lang/Object;
POP
INVOKEDYNAMIC test(Ljava/time/Instant;)Ljava/util/function/Predicate; [
java/time/Instant.isAfter(Ljava/time/Instant;)Z,
(Ljava/lang/Object;)Z
]
Логика
p2 схожа с p1, но объект создаётся вызовом Instant.now() при инициализации. Каждое использование этой лямбда-функции ссылается на создаваемый единожды экземпляр Instant:INVOKESTATIC java/time/Instant.now ()Ljava/time/Instant;
DUP
INVOKESTATIC java/util/Objects.requireNonNull (Ljava/lang/Object;)Ljava/lang/Object;
POP
INVOKEDYNAMIC test(Ljava/time/Instant;)Ljava/util/function/Predicate; [
java/time/Instant.isAfter(Ljava/time/Instant;)Z,
(Ljava/lang/Object;)Z
]
Внутри
p3 создаётся новый Instant при каждом вызове, что отличает эту реализацию от p1 и p2:INVOKEDYNAMIC test()Ljava/util/function/Predicate; [
Example.lambda$main$0(Ljava/time/Instant;)Z,
(Ljava/lang/Object;)Z
]
private static synthetic lambda$main$0(Ljava/time/Instant;)Z
L0
INVOKESTATIC java/time/Instant.now ()Ljava/time/Instant;
ALOAD 0
INVOKEVIRTUAL java/time/Instant.isAfter (Ljava/time/Instant;)Z
IRETURN
В целом все очевидно, но нужно быть внимательными
P.S. не удержался и доработал майндакрты из поста
Please open Telegram to view this post
VIEW IN TELEGRAM
А что если сравнить Stream API в Java c конвейером/пайпланом ввода-вывода в Unix? Это уже сделал за нас некий Diomidis Spinellis в своем блоге. Выглядит по меньшей мере любопытно.
В процессе чтения разблокировалось воспоминание о методенеожиданно T-образный перекресток), как в Unix. Команда
Этот пример сохраняет содержимое файла в
Разветвления сигнала (например, посмотреть вывод в консоли) не очень соответствует идее функционального подхода, поэтому от сбивающего с толку названия tee отказались. Использование имени peek как раз подчеркивает встраиваемость в конвейер.
Но название — это полбеды. К Все зависит от фантазии разработчика 😃 .
А байка оказалась вовсе никакой не байкой. Похоже, что мне удалось найти ту самую переписку уважаемых авторов, где топикстартер, Kevin Bourrillion, дал точную оценку происходящему:
Свой
Реализация получилась зубодробительной🤔
В процессе чтения разблокировалось воспоминание о методе
peek(Consumer<? super T> action), который позволяет (от англ.) подсмотреть, что течет в нашем конвейере. Когда-то я услышал байку: метод изначально хотели назвать tee (от T, который своей формой напоминает tee позволяет перенаправить вывод в 2 источника, например, файл и консоль:cat file.txt | tee intermediate.txt | grep "keyword"
Этот пример сохраняет содержимое файла в
intermediate.txt перед выполнением поиска по ключевому слову.Разветвления сигнала (например, посмотреть вывод в консоли) не очень соответствует идее функционального подхода, поэтому от сбивающего с толку названия tee отказались. Использование имени peek как раз подчеркивает встраиваемость в конвейер.
Но название — это полбеды. К
peek всегда были вопросы с точки зрения дизайна API, так как он предназначен в первую очередь для отладки. Очевидно, что в prod-среде его лучше не использовать, так как он подразумевает наличие side-effects: от банального вывода в консоль до изменения состояния приложения. А байка оказалась вовсе никакой не байкой. Похоже, что мне удалось найти ту самую переписку уважаемых авторов, где топикстартер, Kevin Bourrillion, дал точную оценку происходящему:
tee() stands out like a sore thumb. I'm not surprised that Brian says "this method is mostly for debugging."
It just feels very, very strange to let the user inject a side-effect into the middle of their stream somewhere, for mysterious hidden later execution maybe.
If it really must stay, I think I do like "peek" or "observe" over "tee". But I would love to drop it.
Свой
teeing в Stream API все же появился, но только в Java 12 и в формате коллектора результатов двух независимых коллекторов:Double average = Stream.of(1, 2, 3, 4, 5, 6)
.collect(teeing(
summingDouble(i -> i),
counting(),
(sum, n) -> sum / n));
Реализация получилась зубодробительной
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
С марта этого годя я провел 50 51 первичную консультацию 🎉 Это, честно говоря, стало для меня приятной неожиданностью.
Я уже и забыл, что в прошлый раз, а было это в конце солнечного июня, счетчик показывал только 18 менти, которые получили мою помощь. Мне в какой-то момент показалось, что я сбавил обороты, но нет, получился достаточно стабильный темп: 5-6 консультаций в месяц или 1-2 консультации в неделю!
Накопив некоторую статистику, хочу поделиться с вами некоторыми выводами. Подводим итоги этого направления, так сказать.
Вывод первый. Наши проблемы в большинстве своем не уникальны.
Так 85% менти приходило с такими запросами:
• как устроиться на первую работу
• как выйти на новый уровень заработка
• как прокачать технические скилы
Остальные немногочисленные 15%, это:
• технические вопросы средней и высокой сложности
• смена технического стека / специальности
• как удовлетворить свои карьерные запросы (не подпадают под первую группу)
Хочется, конечно, систематизировать материал, выдаваемый первой группе менти, чтобы высвободить время для решения продвинутых запросов, но руки пока не дошли.
Вывод второй. Ребята, которые приходят на повторные консультации, их тоже около 15%, достигают крутых результатов.Это, конечно, не значит, что остальные не достигают 😄 , просто мне не так очевиден их прогресс. Обычно это трудяги, которые бы и сами добились своих целей, но пройдя по более извилистой и длинной дорожке. Моя задача — сэкономить их силы и время.
Вывод третий. Айти всё? Новичку в айти не войти? Деньги в айти закончились? Из айти пора идти в курьеры? Нет, это миф.
Перестаньте смотреть на статистику по средним зарплатам, собранную работодателями и агрегаторами! Перестаньте читать упаднические статьи! В айти все идет как надо, особенно у тех, кто умеет его правильно готовить🍷
У меня есть живые примеры, как ребята успешно (в денежном выражении):
• устраивались на первую работу, не имея профильного образования и коммерческого опыта
• росли на текущем месте работы
• находили новую работу с более интересными проектами, задачами и стеком
Такие вот несложные, но интересные для меня и многих моих учеников выводы. Спасибо всем, кто приходил на консультации и оставлял отзывы! Это была тяжелая, но продуктивная наша с вами работа.
Записывайтесь на консультацию, если вдруг еще этого не сделали. Самое время сформировать задел перед наступающим новым годом. Вы ведь поставили перед собой амбициозные цели? Я помогу в их достижении🥳
Я уже и забыл, что в прошлый раз, а было это в конце солнечного июня, счетчик показывал только 18 менти, которые получили мою помощь. Мне в какой-то момент показалось, что я сбавил обороты, но нет, получился достаточно стабильный темп: 5-6 консультаций в месяц или 1-2 консультации в неделю!
Накопив некоторую статистику, хочу поделиться с вами некоторыми выводами. Подводим итоги этого направления, так сказать.
Вывод первый. Наши проблемы в большинстве своем не уникальны.
Так 85% менти приходило с такими запросами:
• как устроиться на первую работу
• как выйти на новый уровень заработка
• как прокачать технические скилы
Остальные немногочисленные 15%, это:
• технические вопросы средней и высокой сложности
• смена технического стека / специальности
• как удовлетворить свои карьерные запросы (не подпадают под первую группу)
Хочется, конечно, систематизировать материал, выдаваемый первой группе менти, чтобы высвободить время для решения продвинутых запросов, но руки пока не дошли.
Вывод второй. Ребята, которые приходят на повторные консультации, их тоже около 15%, достигают крутых результатов.
Вывод третий. Айти всё? Новичку в айти не войти? Деньги в айти закончились? Из айти пора идти в курьеры? Нет, это миф.
Перестаньте смотреть на статистику по средним зарплатам, собранную работодателями и агрегаторами! Перестаньте читать упаднические статьи! В айти все идет как надо, особенно у тех, кто умеет его правильно готовить
У меня есть живые примеры, как ребята успешно (в денежном выражении):
• устраивались на первую работу, не имея профильного образования и коммерческого опыта
• росли на текущем месте работы
• находили новую работу с более интересными проектами, задачами и стеком
Такие вот несложные, но интересные для меня и многих моих учеников выводы. Спасибо всем, кто приходил на консультации и оставлял отзывы! Это была тяжелая, но продуктивная наша с вами работа.
Записывайтесь на консультацию, если вдруг еще этого не сделали. Самое время сформировать задел перед наступающим новым годом. Вы ведь поставили перед собой амбициозные цели? Я помогу в их достижении
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2