(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Нашел вот такую интересную штуку для работы с git - https://gitbutler.com/ По сути ребята взяли идею IDEA ))) с change list-ами, и сделали из change list полноценную ветку. Ну как полноценную - виртуальную, git про них не знает, вся информация о такой ветке хранится локально. change list-у можно дать название и закоммитить отдельно, а в виртуальной ветке, как и в обычной, кроме того можно делать коммиты, а также объединять, переименовывать и откатывать их. Вот видео с основными фишками https://www.youtube.com/watch?v=PWc4meBj4jo

Цель утилиты - одновременная работа над несколькими ветками. Причем судя по видео создание новых веток и переключение между ними реально быстрое, у меня даже иногда возникала мысль - а не ускорили ли они видео) Ну и надо сказать, утилита пропагандирует минимально возможные изменения в коммите и в ветках, в пределе - одно изменение = один коммит, что также способствует скорости работы. В этом она мне напомнила https://darcs.net/Features, где тоже идет упор на то, что каждая строчка с изменением может стать отдельным коммитом. Но в отличие от Darcs GitButler полностью совместим с Git. И активно развивается.

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

Главное неудобство - нельзя работать с ветками в IDEA, т.к. git client, встроенный в IDEA, ничего не знает о виртуальных ветках.

Второй момент - пока доступно только для Mac и Linux, а так я бы попробовал(

#git
Всем привет!

Интересно сравнить рейтинг языков программирования по поисковым запросам https://www.tiobe.com/tiobe-index/ и по коду на github https://innovationgraph.github.com/global-metrics/programming-languages

Что бросилось в глаза:

1) большего всего кода на JavaScript, хотя ищут информацию по нему существенно меньше. Аналогично по TypeScript, причем в поиске он явно в тени JavaScript. Что ж, это стандарт в вебе, никуда с подводной лодки не денешься)

2) Java, Kotlin - позиции примерно совпадают в обоих списках. Стабильность) Perl и PHP к слову тоже. Но если позиция Java меня радует, Kotlin - кажется должно быть выше, Perl - ну ок, позиция в районе 25 места, то к PHP и его стабильному месту в десятке вопросики... Хотя надо сказать, что именно в PHP я видел самые строгие требования к документации. Правда похоже никто из разработчиков их не читает)

3) позиции Go и Rust по поиску сильно выше, чем по коду. Разница в 10 позиций. Налицо рост популярности

4) но еще сильнее разрыв между поиском и кодов для Fortran и Cobol. Cobol так вообще по коду в топ 50 не входит, а ищут его неплохо, как Kotlin. Подозреваю, причина в том, что код лежит во внутренних репозиториях "кровавого enterprise") И пришла пора его интегрировать с AI)

5) у Ruby кода существенно больше, чем популярности в поиске, тоже разница порядка 10 позиций. Так что хоронить Ruby еще рано, но то, что он уже не модный - факт)

6) наблюдается взлет популярности в поиске С#

7) позиции C и C++ по коду поменьше, чем в поиске. Я бы предположил, что тут как в анекдоте: удар молотком - 1 рубль, знал куда ударить - 1000 рублей)

8) Swift давно обогнал Objective-C в поиске, но еще не обогнал по коду. Это основные языки для разработки iOS\MacOS если что

9) код на Delphi где-то спрятан... Не думаю, что Enterprise, скорее на компьютерах университетов и школ

10) довольно много кода в репо для Shell, Makefile, Dockerfile, CMake, Powershell что в целом объяснимо. Groovy тоже можно в эту категорию отнести - сборка и deploy.

#languages
Всем привет!

Нашел хорошую статью-боль https://habr.com/ru/articles/739452/
Она как бы про DevOps, но на самом деле нет - точно такая же проблема есть у разработчиков, тестировщиков, сопровождения.

Корень проблемы на мой взгляд - то, что в ИТ многие пришли из других специальностей, не изучая Computer Science - базовые алгоритмы, устройство процессора, памяти, сетей, файловой системы. Либо из такого ВУЗа, который преподает по "советским" лекалам - т.е. устаревшую информацию.

Потому что если ты эти знания не получил в ВУЗе, то нужно желание учиться и годы опыта. Я, если что, пошел по второму пути)

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

P.S. 943 коммента показывают актуальность темы)

#computer_science #найм #devops
Всем привет!

Я уже рассказывал про один из вариантов ускорения запуска JVM приложений - использование native image https://t.me/javaKotlinDevOps/242
Напомню, основная идея была в том, что на этапе компиляции мы превращаем байт-код в нативный код. Можно рассматривать этот процесс как некий дамп универсального кода в конкретный, предназначенный для определенной процессорной архитектуры.

Похожий принцип используется и в случае JVM checkpoint/restore https://openjdk.org/projects/crac/ - проект CRaC.
Проект использует функционал Linux checkpoint/restore для Docker образов https://criu.org/Main_Page.
Т.е. в данном случае мы дампим все содержимое памяти JVM приложения на диск.
Работает, соответственно только для Docker и только в Linux, но кажется это не критическое ограничение.
Вот как это можно сделать на чистом Java приложении https://habr.com/ru/articles/719522/
Есть поддержка на всех основных платформах - Spring Boot, Micronaut, Quarqus, см. https://github.com/CRaC/docs
Проблему долгого первого запуска можно обойти либо сделав дамп до выхода на ПРОМ на идентичном Linux-е, либо разворачивая новые версии как канарейку или в моменты минимальной нагрузки, т.е. когда долгий старт не критичен.

Плюсом этого решения перед native image является то, что нет никаких ограничений на динамическую загрузки библиотек и рефлексию.

Кажется, одним из выгодоприобитетелей будут облачные провайдеры FaaS - Function as a Service, а если быть точным - их пользователи. И, собственно, так и есть - Amazon Lambda уже https://github.com/CRaC/aws-lambda-java-libs подддерживает

#crac #startup_time #jvm #performance #java_start_boost
Всем привет!

Не ошибусь, если предположу, что многие Java разработчики знают об Sun code style conventions https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
Их автоматическая проверка реализована в Checkstyle https://checkstyle.org/styleguides/sun-code-conventions-19990420/CodeConvTOC.doc.html

Но это еще не все, что предлагают себе и нам разработчики Java.

Во-первых Sun уже давно нет, есть Oracle, который его купил.
И есть более новая версия code style от Oracle https://cr.openjdk.org/~alundblad/styleguide/index-v6.html#toc-introduction (доступ по VPN)

А кроме того, у Oracle есть свои правила для проверки качества кода https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88487665
Ссылка выше ведет на раздел по обработке исключений, чтобы можно было оценить объем и глубину требований на конкретной фиче языка.
Что интересно - не все правила есть в SonarQube, по тем же исключениям увидел несколько новых для себя вещей.
Некоторые из них я полностью поддерживаю, они вроде как логичны и можно сказать очевидны https://wiki.sei.cmu.edu/confluence/display/java/ERR03-J.+Restore+prior+object+state+on+method+failure
Некоторые https://wiki.sei.cmu.edu/confluence/display/java/ERR06-J.+Do+not+throw+undeclared+checked+exceptions можно кратко суммировать так: да, я нашем языке есть дыры, но не надо их использовать, пожалуйста)))
Что хорошо - в конце страницы с описанием правила есть секция со ссылками на соответствующие правила SonarQube и прочих утилит статического анализа кода.

#java #code_static_analysis
Всем привет!

Я уже рассказывал про 5 возможных моделей ветвления в git https://t.me/javaKotlinDevOps/95
Нашел еще одну, причем уверен некоторым читателям этого блога она покажется знакомым)
Встречайте stacked pull requests.
Вот краткое описание https://www.michaelagreiler.com/stacked-pull-requests
А вот еще более краткое от меня:
1) работаем через Pull Requests (PR), они же Merge Requests
2) PR выстраиваем в лесенку
3) вливаем в обратном порядке
4) при изменениях в родительском PR, например, по результату код-ревью, проталкиваем изменения во все дочерние PR

Основное назначение данной схемы:
1) упор на ревью небольших кусочков кода, разделение фичи на мелкие commit-ы, удобные для ревью
2) разного рода миграции, когда на промежуточных стадиях код не компилируется и тесты не проходят, а все вместе - неудобоваримо для код ревью

Данная модель может работать поверх любого их описанных выше flow, за исключение trunk based. trunk based, напомню, вообще убирает Pull Requests, а процесс ревью осуществляется либо при парном программировании, либо пост-фактум.

Альтернативой является один PR с предположим 10 commits. Но преимущество данной схемы в том, что создавая вместо этого 10 PR автор скорее задумается о том, чтобы каждый из них представлял атомарное изменение, удобное для ревью.

#git #vcs #branching
Всем привет!

Минутка истории. И разных подходов к работе с opensource.

1-я история. Жила была компания Microsoft, и в какой-то момент она "запустила" свою инфраструктуру разработки. Были выделены ресурсы для исправление этой ситуации. Один из примеров такой деятельность - перенос исходников в git, создание своего форка git, проверка его на GitHub и вливание форка в основную ветку git. Вот тут немного подробнее про доработку git под требования Microsoft - большой объем репозитория - https://habr.com/ru/articles/795635/

2-я история. Жила была компания Facebook, тогда еще не иноагент) Компания была молодая, но тоже уже столкнулась с проблемой хранения и организации код-ревью на большом объеме кода. Разработчики компании готовы innersource-ить, чтобы решить проблему. Постучались в git, получили отказ с формулировкой - это частный случай, для основной массы пользователей не нужно, делайте маленькие репозитории. Постучались в Mercurial - там ее pull request согласились принять. Перешли на Mercurial https://habr.com/ru/articles/798881 Но предположу, что часть разработчиков на этом не успокоилась и в результате появился Sapling https://sapling-scm.com/docs/introduction/differences-hg
Это новая Version Control System, которая может работать как со своим форматом repo, так и с git. При этом делает упор на частичное клонирование репо и работу с коммитами: быстрый откат, сохранение истории изменений при слиянии коммитов и даже https://sapling-scm.com/docs/commands/absorb

Тут наверное нужна мораль...)
На первый взгляд подход git более последователен - выбрали лидера рынка, допилили, вернули в основную ветку, помогли opensource сообществу. Но с другой стороны git хоть и является стандартом, но не идеален. И Sapling решает ряд его проблем. Кто-то должен протаптывать новые тропы, пусть и ценой чуть большего беспорядка в своей инфраструктуре разработки

#git #vcs
Всем привет!

Уже писал от проблеме внедрения новых технологий в enterprise компаниях https://t.me/javaKotlinDevOps/250

Два дополнения.

1) предлагаемое решение можно назвать технологическим стеком, но есть более распространенное «импортное» название - техрадар.

2) вот пример реальной компании, которая серьезно занялась этой проблемой https://habr.com/ru/companies/sbermarket/articles/645661/
Особенно хочу подчеркнуть принцип построения снизу-вверх, или поощряющая vs принуждающая система.
И идею, что техрадар может быть ориентиром для карьерного роста, он же план развития.

#arch #technology #techradar
Всем привет!

Когда говорят о том, как необходимо учитывать требования информационной безопасности (ИБ) при разработке ПО часто забывают об одной проблеме.
Мир ИБ и мир разработки часто практически не пересекаются. Специалистов по ИБ нет в командах, разработчики и "безопасники" говорят на разном языке. Поверхность атаки, вектор атаки, SAST, DAST, OSS - для команды это что-то далекое, внешнее. Это плохо, но это факт. А встречаются эти два мира часто перед моментом выхода нового релиза на ПРОМ. Что тоже плохо.

Что же тут можно сделать?
1) базу про ИБ разработка должна знать, немного писал об этом тут https://t.me/javaKotlinDevOps/27
2) представители ИБ должны приходить в команды, в виде митапов, личных встреч, раннего ревью архитектуры, т.к. в любом случае именно они знают наиболее важные болевые точки
3) а так как мы живем в мире победившего Agile - требования ИБ тоже можно внедрять по Agile. Начиная с простых - технических, связанных с конкретными интеграциями и данными. Т.к. именно техническую стороны разработчики знают и могут контролировать. Подключая владельца продукта и специалиста ИБ, т.к. именно они должны знать, где потенциально могут быть наибольшие потери в финансовом и репутационном плане.

И по этому поводу есть хорошая статья, где процесс расписан по шагам https://habr.com/ru/companies/vk/articles/504062/

#security
Всем привет!

Продолжим серию с тэгом #interview_question

Вот код:

@Service
public class MyService {

public void syncMethod() {
System.out.println("Synchronous method executed.");
asyncMethod();
}

@Async
public void asyncMethod() {
System.out.println("Async method executed.");
}

}

Что с ним не так?

Подсказка: @Async выполняет код в отдельном потоке.
Еще подсказка: магия Spring работает через proxy объекты. Из-за proxy объектов, к слову, магия ломается на финальных классах, в частности в Kotlin, без специальных настроек.
И последняя подсказка: вызов метода того же класса в Java работает через неявное указание this, и этот вызов идет через пул констант класса
https://ru.stackoverflow.com/questions/846457/Пул-констант-в-java

В общем код проблема в том, что asyncMethod будет вызван синхронно, как обычный метод того же класса, proxy код будет проигнорирован. Аналогичная проблема будет и с @Transactional. Проблема называется self execution.

Решений два:
1) простое и поэтому правильное - вызывать метод asyncMethod() из другого класса
2) сделать self injection - внедрить класс сам в себя. Выглядит странно, может сбить с толку, но наверняка может пригодится в отдельных случаях.

P.S. Еще один оффтопик. Код для поста я попросил сгененировать GigaChat и ChatGPT. Первый не справился, второй - справился, но с третьей попытки. И к тому же его пришлось почистить. Указание на название проблемы - self execution - не помогло, у обоих моделей без уточняющих подсказок выдается пример с рекурсивным вызовом асинхронного метода. В общем быстрее написать самому)

#interview_question #spring #java
И снова здравствуйте)

Вчера произошло знаменательное событие для этого блога - первые 100 подписчиков. Просить голоса не буду, не представляю, что с ними делать. Ну не сторисы же записывать?)))
Сделаю по-другому - пишите в личку или в комменты вопросы\проблемы, которые было бы интересно обсудить. По первым трем, по которым мне есть что сказать, сделаю посты.

#blog
Всем привет!


В продолжение вчерашней темы про магию аннотаций Spring - статья про то, чем различаются @Async и @Scheduled под капотом
https://habr.com/ru/articles/771112/
И почему их может иметь смысл использовать вместе.

И та, и другая аннотация приводит к выполнению кода в отдельном потоке. Вопрос только в том, сколько таких потоков?
@Async по умолчанию создает новый поток.
А все @Scheduled - работают в одном потоке.
Как правильно? Правильно управлять потоками явно, через явное указание пула потоков в обоих случаях.

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

#spring #spring_magic #multithreading
Всем привет!

Недавно вышла 22-я Java. Обычная, не LTS версия.
Вот неплохой обзор нововведений https://habr.com/ru/articles/801467/

Что могу отметить: из 12 JEP - больших фичей Java по сути - по которым велась работа в релизе, 7 появились в предыдущих версиях. Т.е фиксят и рефакторят.

Что же появилось интересного из новых фичей?

Launch Multi-File Source-Code Programs (JEP 458) - возможность быстрого запуска из командной строки без сборки в jar для кода, разбросанного по нескольким файлам. Запускать код из одного файла можно было и ранее.
Вместе с появившимся в 21 Java Implicitly Declared Classes and Instance Main Methods (Second Preview) (JEP 463) - запуск кода из простого метода main без параметров и без класса - видна тенденция упростить вкатывание новичков в Java, сделать его похожим на тот же Python.

Stream Gatherers (Preview) (JEP 461) - если раньше для стримов можно было писать свои коллекторы, то сейчас можно будет и gatherer - промежуточные операции. Кажется интересная тема, открывает возможности для большого расширения возможностей стримов. Странно, что ждали 14 версий)

Class-File API (Preview) (JEP 457) - если раньше для работы с байт-кодом использовались сторонние библиотеки, одна из которых - ASM - была первой среди равных, т.к. поставлялась с JDK, то сейчас сделали ее аналог уже в составе JDK. Цель - чтобы изменения в API Java и в API для работы с байт-кодом были синхронизированы. Тоже в общем-то вполне логичная фича.

Ну и еще одна мелкая фича, появление как я подозреваю которой приведет к тому, что появятся новые головоломные задачки на собесах. Statements before super(...) (Preview) (JEP 447) - как следует из названия в конструкторах можно писать код перед вызовом super(), но не любой, а только не нарушающий порядок инициализации класса. Это вам не Spring, никаких проксей) Т.е. код в прологе не должен ссылаться на конструируемый объект, включая поля из суперкласса и на экземпляры внутреннего класса.

P.S. Да, все еще идут споры по String Templates, про которые я писал ранее https://t.me/javaKotlinDevOps/246 Делать их расширяемыми или как у всех) В 22-й Java пока оставили как было

#java #java_new_version #interview_question
Всем привет!

Небольшая ремарка по использованию ChatGPT и аналогов.
На мой взгляд самая большая проблема с ними возникает не тогда, когда они генерируют ерунду - это сразу видно.
Ну например, отсутствующие классы или методы. Такой код или сразу отбрасывается, или благодаря подсказкам IDE дописывается.

Плохо, когда генерируемый код похож на правильный. Даже очень похож. Тогда ты принимаешь рекомендацию, мысленно помечаешь задачу как выполненную и пытаешься идти дальше. А приложение падает в неожиданном месте. Пример из моей практики - сгенерированная командная строка. Выглядит как настоящая, отличается одним отсутствующим пробелом. Такие же проблемы возможны с RegExp.
Да, часто проблема решается тестами. Но есть тривиальный код, который с одной стороны не хочется писать самому, т.к. он тривиальный, а с другой стороны он часто покрывается не модульными, а интеграционными тестами. А condition coverage у интеграционных тестов по понятным причинам хуже, чем у модульных.

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

#llm
Всем привет!

Я уже не раз говорил и повторю еще раз - мир Java хорош своей огромной базой opensource библиотек на все случаи жизни.
Даже для работы с LLM (ChatGPT) уже библиотеки появляются https://t.me/javaKotlinDevOps/241
И для прочего Machine Learning тоже https://t.me/javaKotlinDevOps/142

А еще на Java можно писать Telegram боты https://www.baeldung.com/spring-boot-telegram-bot

#java #libraries
Всем привет!

Насколько сложнее разрабатывать монолит? В каком коде больше ошибок - микросервисном или монолитном? Частная проблема в ИТ - не количественных оценок, вместо этого есть экспертное мнение. Но не все так плохо, какие-то данные все же есть. Причём в классике, Макконнел Совершенный код.

Вот график типичной плотности ошибок в проекте в зависимости от числа строк кода. Синий — максимальное, красный — среднее, зелёный — наименьшее количество.

http://www.viva64.com/external-pictures/habr103/image2.png

Детали тут https://habr.com/ru/companies/pvs-studio/articles/150539

#monolith #statistics
Всем привет!

Нашел интересный антипаттерн, о котором ранее не задумывался. Coding By Exception - кодирование через исключения, не знаю как лучше перевести.
Суть в том, что под каждую ошибку заводится отдельное исключение. Почему это плохо?
1) В случае проверяемых исключений понятно - сигнатуры методов не "загрязняются", появляется искушение написать throws Exception.
2) Но ничуть не лучше ситуация в случае непроверяемых исключений. Для обработки исключений все равно приходится писать код. Чем больше исключений - чем больше количество такого кода. А если обработка единообразная для группы исключений возникает вопрос - а точно ли их надо разделять? Исключения хоть и должны быть свои, кастомные, но они должны охватывать какие-то типовые ошибки, а не каждую конкретную ошибку.
3) Если при любой ошибке бросать исключение - это может сказаться на производительности
4) Если при любой ошибке бросать исключение - это по сути goto программирование - переход в произвольное место кода. А goto - это "матерый" антипаттерн)))

#antipatterns
Всем привет!

Недавно вышла новая версия IDEA - 2024.1. В новой версии появилось много "вкусного", вот что я бы отметил:

1) если раньше аналог Copylot (Gigacode) был доступен только по отдельной подписке, и при этом сильно уступал Copylot, то сейчас в Ultimate появился "бесплатный" AutoCompletion. Проверил: в моем случае, предлагает компилируемый код, но требующий правок) Вообще вижу тенденцию, что часть изначально платных LLM инструментов становятся бесплатными - ChatGPT4, IDEA AI. В случае Microsoft - они просто делятся машинным временем для популяризации инструмента, в случае IDEA - работает локальная модель, которой как контекст подается код открытого проекта.

2) IntelliJ в курсе проблемы долгой инициализации проекта... ремарка - еще бы они не были в курсе, такое сложно не заметить) ... и сделала доступной ряд фич IDE во время инициализации. Плюс сейчас происходит быстрый парсинг maven pom, и на основе полученной информации становится доступной навигация по проекту пока идет индексация.

3) ряд улучшений по работе с логами:
- AutoCompletion кода для инициализации логгера, если в классе ее еще нет
- как альтернатива возможна автогенерация этого кода
- парсинг логов на предмет наличия там классов проекта.
Что я бы отдельно отметил на примере этой и предыдущей фичи - комплексный подход. Берем все (заведенные тикеты), что можем улучшить по теме - и улучшаем)

4) новая консоль. Главные фичи - снова AutoCompletion и разбиение единого полотна текста на команды, что облегчает их копирование. В будущем обещают улучшение AutoCompletion и даже подсказки по ошибкам. Видимо с использованием LLM. Жаль, пока работает только на bash и PowerShell, но думаю тоже доделают.

5) sticky режим при прокрутке больших файлов. Т.е. всегда видны декларация класса и текущего метода каким бы большим не был метод. Число видимых строк настраивается. Напомнило мне "хлебные крошки" на сайтах. Большие классы и методы конечно же зло, но это зло существует)

6) куча улучшение по работе с Pull request - можно ревьювить их в IDEA, в т.ч. смотреть diff, писать комментарии, смотреть статус prCheck и даже ставить лайки) К сожалению только GitHub и GitLab.

7) для самого частого рефакторинга - переименование - сделали inline режим: не надо вызывать команду по шорткату или меню - просто переименовываешь сущность, а IDEA сама предложит переименовать ее по всему проекту

8) появилась поддержка OpenRewrite - фреймворка для написания рефакторингов, если встроенные не устраивают. https://t.me/javaKotlinDevOps/116 Правильный подход, я считаю

9) и наконец на первый взгляд незаметная фича - альфа тестирование нового компилятора Kotlin K2. Казалось бы - ну и ладно, заменили компилятор, при чем тут IDE. А штука в том, что ребята специально переписали свой компилятор, чтобы его удобнее было использовать для фич IDEA - сделать то, что раньше не получалось и ускорить работу IDE. Т.е во-первых, интересен тот факт, что для подсветки синтаксиса, AutoCompletion и т.д используется компилятор, а во-вторых - удобно быть и разработчиком IDE, и разработчиком языка) Более этого, это было одной из причин разработки этого языка - https://t.me/javaKotlinDevOps/38

Вот пожалуй и все, что запомнилось.

#idea #kotlin
Всем привет!

Увидел интересное мнение по системам low code. Я о BPM движках, Pega и тому подобных системах, которые предлагают разработку путем создания квадратиков из библиотеки готовых компонент и соединения их стрелочками. Мнение полностью совпадает с моим опытом.
Так вот - 80% задачи такая система вам решит. Возможно) Но на оставшиеся 20% вы потратите кучу времени, причем времени разработчиков. А то, что получится в итоге, будет содержать ряд компромиссов, и поэтому будет хуже, чем разработанное с нуля решение)

#low_code
Всем привет!

Что ж, появилась первая книжка про ChatGPT для разработчиков на русском.
https://www.piter.com/collection/all/product/razrabotka-prilozheniy-na-baze-gpt-4-i-chatgpt
С почином!
Книжка небольшая, 180 страниц, про основы LLM и работу с API ChatGPT.
Я купил, буду изучать.

P.S. Python конечно же)

P.P.S. На Хабре издательство Питер выкладывает статью про каждую книгу с промокодом. https://habr.com/ru/companies/piter/articles/807039/

#llm #chatgpt
Всем привет!

Небольшой пост из серии "хозяйке на заметку")

Можно ли слить в git 2 проекта, не имеющих общей истории?
Первый вопрос, который тут возникает - а зачем???
Но похоже иногда такая потребность есть, потому что у git merge есть опция --allow-unrelated-histories.
Можно предположить, что такая опция может понадобится если проект начал разрабатываться 2 людьми, при этом забыли сделать общий первый commit. Или были жесткие rewrite-ы)

#git #tricks