14242
Java Библиотека По всем вопросам- @notxxx1 @ai_machinelearning_big_data - machine learning @pythonl - Python @itchannels_telegram - 🔥 best it channels @ArtificialIntelligencedl - AI @pythonlbooks-📚 @programming_books_it -it 📚 № 5032728887
💡 Java cj: unmodifiableList() не делает настоящую копию
Эти два варианта выглядят похоже, но работают по-разному:
List<String> source = new ArrayList<>();
source.add("Java");
List<String> view = Collections.unmodifiableList(source);
List<String> copy = List.copyOf(source);
source.add("Spring");
System.out.println(view); // [Java, Spring]
System.out.println(copy); // [Java]
Collections.unmodifiableList() создаёт только неизменяемое представление исходного списка. Если source изменится, изменения появятся и в view.List.copyOf() создаёт отдельный неизменяемый снимок данных.unmodifiableList() — когда нужен read-only view актуального списка;List.copyOf() — когда нужно зафиксировать состояние и безопасно вернуть его наружу.
public List<String> getUsers() {
return List.copyOf(users);
}
users не повлияют на уже возвращённый результат.List.copyOf() доступен начиная с Java 10.
💡 Редкий совет Java: используйте `ClassValue` для кэша, привязанного к классу
Обычно метаданные кэшируют так:
Map<Class<?>, Metadata> cache = new ConcurrentHashMap<>();
Но такой кэш способен удерживать классы и их ClassLoader, создавая утечки памяти в плагинах, серверах приложений и системах с динамической загрузкой.
Для подобных случаев в Java есть ClassValue:
private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return inspect(type);
}
};
Metadata metadata = CACHE.get(User.class);
Значение вычисляется отдельно для каждого класса и может быть очищено после его выгрузки.ClassValue особенно полезен для reflection-кэшей, сериализаторов, ORM, прокси и плагинных архитектур.
Редкий инструмент JVM, который часто безопаснее, чем ConcurrentHashMap<Class<?>, ...>.
#Java #JVM #Backend #Performance
Rust, который наконец становится понятным 🦀
Давно хочешь выучить Rust, но ownership, borrowing и lifetimes выглядят как отдельный вид боли?
Этот курс проведёт тебя с самого начала до уровня, где ты уже пишешь реальные системные и сетевые программы.
Ты разберёшь:
Ownership → Borrowing → ошибки → коллекции → Generics → Traits → модули → тесты → сетевой код
Никакого бесконечного чтения документации. После каждого урока ты сразу пишешь код, проходишь тесты и решаешь задачу с автопроверкой.
🔥 Rust с нуля
🔥 5–6 часов в неделю
🔥 Практика после каждого урока
🔥 Подойдёт после Python, JavaScript, Java и других языков
🔥 Можно начать сразу
В конце у тебя будет понимание Rust, с которым уже можно писать быстрые backend-сервисы, сетевые приложения и системные утилиты, а не смотреть на borrow checker как на врага.
Пора добавить Rust в свой стек. Начинай курс и пиши первый код уже сегодня: https://stepik.org/a/294885/
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку
В IT прокачивается тот, кто каждый день видит сильные идеи, новые инструменты, реальные задачи, вакансии и разборы.
Окружение решает больше, чем кажется.
Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.
AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: t.me/DevopsDocker
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/java_library
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: /channel/gamedev
Haskell: t.me/haskell_tg
Собеседования и карьера:
DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview
Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: /channel/addlist/2Ls-snqEeytkMDgy
Папка Frontend: /channel/addlist/mzMMG3RPZhY2M2Iy
Полезное сверху:
ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: @courses
ИТ-книги бесплатно: /channel/addlist/BkskQciUW_FhNjEy
Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg
Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
Пока кто-то листает шум, ты будешь видеть инструменты, задачи и идеи, которые помогают расти в профессии.
Если хочешь развиваться в бэкенд-разработке — выстроить сильную базу, углубиться в архитектуру или перейти в роль тимлида — в Центральном университете есть магистратура под каждый сценарий. И на нее можно получить грант до 75%. Места ограничены, дедлайн подачи заявок — 20 августа.
«Бэкенд-разработка» — это офлайн-направление (пары по вечерам и в выходные в центре Москвы) с тремя треками на выбор:
⚫️Технический — для студентов старших курсов и разработчиков в начале карьеры. Языки программирования, DevOps-инструменты, базы данных, архитектура ПО и распределенные системы. Программа ежегодно обновляется под реальные запросы компаний, а преподают разработчики, тимлиды и CTO из ведущих IT-компаний. К выпуску — сильное портфолио бэкенд-проектов
⚫️Совместный с MAGNIT TECH — обучение на реальных кейсах и архитектуре распределенных систем федерального масштаба, буткемп с экспертами компании и возможность выйти на оплачиваемую стажировку в техническую команду в течение первого года
⚫️Тимлидский — для опытных разработчиков, которые хотят перейти к роли руководителя команды: выстраивать процессы разработки, принимать архитектурные решения и развивать команду
Магистратура в Центральном университете — это 2 года обучения, которое можно совмещать с работой, и диплом государственного образца. Карьерная поддержка начинается еще во время учебы: консультации, тренировочные собеседования и помощь с трудоустройством. Студенты уже в процессе обучения выходят на новые позиции или повышаются в грейде в Яндексе, Авито, Т-Банке и других компаниях.
Поступление проходит через грантовый конкурс — это одновременно способ попасть на программу и возможность выиграть финансовую поддержку на все время обучения: грант покрывает до 75% стоимости. В 2026 году доступно 550 грантов на все программы магистратуры.
Подробнее о программе и условиях участия в конкурсе — по ссылке
N+1 в Spring Boot выглядит безобидно, пока прод не начинает молиться на базу данных.
Классический сценарий:
Вы грузите список заказов:orderRepository.findAll()
А потом в цикле обращаетесь к order.getItems().
Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.
100 заказов = 101 SQL-запрос.
И вот здесь спасает @EntityGraph.
Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:@EntityGraph(attributePaths = {"items"})
В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.
Что получаем:
- меньше SQL-запросов
- меньше нагрузки на БД
- чище код репозитория
- без ручного JPQL
- fetch-стратегия управляется точечно под конкретный кейсLAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.
🖥 В Java длинные цепочки вроде `user → address → city` легко превращаются в ловушку для `NullPointerException`.
Обычный вариант быстро разрастается:
User user = userRepository.findByEmail(email);
if (user != null) {
Address address = user.getAddress();
if (address != null) {
return address.getCity();
}
}
return "unknown";
if легко забыть один уровень проверки и получить NPE в самом неожиданном месте.Optional это можно записать короче и безопаснее:
return userRepository.findByEmail(email)
.map(User::getAddress)
.map(Address::getCity)
.orElse("unknown");
map() выполняется только если предыдущее значение существует.orElse().Optional хорошо работает как способ явно показать:Optional в новую религию.null.
Читать полностью…
📌 Magic numbers в Java - мелкая привычка, которая потом превращает поддержку кода в археологию.
Когда в коде встречается 86400, 7, 1.21 или 5000, компилятору всё равно. Человеку - нет. Через месяц уже приходится вспоминать, что это было: секунд в дне, дней сессии, НДС или задержка перед повторной попыткой.
Плохой вариант выглядит так:if (sessionAgeSeconds > 86400 * 7)
Формально код работает. Но смысл спрятан внутри чисел.
Нормальный вариант:SECONDS_PER_DAYSESSION_DAYSVAT_RATERETRY_DELAY_MS
Теперь намерение видно прямо в месте вызова. Не нужно угадывать, почему именно 7, что означает 5000 и можно ли безопасно поменять значение.
Это особенно важно в бизнес-логике, где числа редко бывают случайными. Лимиты, комиссии, таймауты, скидки, сроки жизни сессии, количество попыток - всё это правила продукта, а не просто цифры в коде.
Хорошее правило простое: если число несёт смысл, дай ему имя. Исключения вроде 0, 1, индексов и простых счётчиков можно не трогать.
Чистый код часто начинается не с архитектуры, а с таких скучных вещей: убрать загадочные числа и оставить будущему разработчику понятный контекст.
#java #cleancode
Твой код — в сердце мощного ИИ! 💚
Команда GigaChat зовёт на One Day Offer амбициозных Java-разработчиков, которые готовы создавать AI‑продукты уровня BigTech и стать частью крупнейшего AI-комьюнити.
Если ты дружишь с Java (версии 8–25), ладишь со Spring и Hibernate, а PostgreSQL и ClickHouse для тебя — не просто слова, переходи по ссылке и занимай слот на One Day Offer.
Встречаемся 23 мая — очень ждём именно тебя!
N+1 в Spring Boot выглядит безобидно, пока прод не начинает молиться на базу данных.
Классический сценарий:
Вы грузите список заказов:orderRepository.findAll()
А потом в цикле обращаетесь к order.getItems().
Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.
100 заказов = 101 SQL-запрос.
И вот здесь спасает @EntityGraph.
Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:@EntityGraph(attributePaths = {"items"})
В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.
Что получаем:
- меньше SQL-запросов
- меньше нагрузки на БД
- чище код репозитория
- без ручного JPQL
- fetch-стратегия управляется точечно под конкретный кейсLAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.
⚡️ CORS в Spring Boot: не лечите это костылями на фронте
Если frontend и backend живут на разных доменах или портах, браузер начнет резать запросы по CORS. Это не баг Spring Boot и не проблема React. Это нормальный механизм безопасности браузера.
Правильный способ - настроить CORS на стороне backend.
В Spring Boot это можно сделать глобально через WebMvcConfigurer: указать маршруты, разрешенные origins, HTTP-методы, заголовки и работу с credentials.
Главное - не ставить бездумно * везде подряд, особенно если используете cookies, токены или allowCredentials(true). В проде лучше явно перечислять доверенные домены, например frontend-домен приложения.
Такой подход дает централизованный контроль: вы один раз задаете политику CORS и не размазываете настройки по каждому контроллеру.
Для Java backend-разработчика это базовая, но важная вещь: CORS должен быть частью архитектуры API, а не случайной правкой перед деплоем.
Spring Boot может уронить API из-за одного лишнего поля в JSON
Классика: приходит запрос с дополнительным полем, которого нет в DTO и ты ловишь UnrecognizedPropertyException. Клиент добавил поле, ты не обновил модель - всё падает.
Решение в одну строку:
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserDTO {
private String name;
private int age;
}
⚡️ Java лайфхак: не убивай производительность боксингом
Многие даже не замечают, как теряют скорость из-за автoboxing в Stream API.
❌ Плохо (создаются объекты Integer):
Stream<Integer> boxed = Stream.of(1, 2, 3, 4, 5);
int sum = boxed.reduce(0, Integer::sum);
Каждое число → объект → лишняя память + нагрузка на GC
✅ Хорошо (работа с примитивами):
int sum = IntStream.of(1, 2, 3, 4, 5).sum();
Без лишних объектов. Быстрее. Чище.
Запомни:
- IntStream → для int
- LongStream → для long
- DoubleStream → для double
Если работаешь с числами — всегда используй primitive streams.
Это мелочь, которая на больших данных превращается в реальную экономию ресурсов.
Сохрани, чтобы не писать медленный код.
🔥 Лучшие БЕСПЛАТНЫЕ ресурсы по Linux в 2026 году
1. Linux Foundation Training
https://training.linuxfoundation.org/training/introduction-to-linux/
2. Linux Journey
https://linuxjourney.com
3. Ubuntu Tutorials
https://ubuntu.com/tutorials
4. Red Hat Training Resources
https://developers.redhat.com/learn
5. Документация GNU
https://gnu.org/manual
6. OverTheWire Bandit (Linux-варгеймы)
https://overthewire.org/wargames
7. Книга The Linux Command Line
https://linuxcommand.org/tlcl.php
8. MIT Missing Semester (Linux и CLI)
https://missing.csail.mit.edu
9. Туториалы по Linux от DigitalOcean
https://digitalocean.com/community/tutorials
10. Linux From Scratch
https://linuxfromscratch.org
11. Arch Linux Wiki
https://wiki.archlinux.org
12. Курс по Linux от freeCodeCamp
https://freecodecamp.org/news/tag/linux
13. Linux Survival (интерактивное обучение)
https://linuxsurvival.com
14. NDG Linux Essentials
https://netacad.com/courses/os-it/ndg-linux-essentials
15. Bash Guide (руководство по Bash)
https://tldp.org/LDP/Bash-Beginners-Guide/html
🚀 Spring Boot: не делай эту ошибку с filters / interceptors
Многие используют фильтры и интерцепторы неправильно 👇
👉 Они должны быть только для cross-cutting задач
(то, что применяется ко ВСЕМ запросам)
Примеры нормального использования:
🟢 Filters:
- CORS
- Encoding
🟢 Interceptors:
- аутентификация / авторизация
- метрики / логирование
- locale
- общие headers
❌ Главная ошибка:
кладут туда бизнес-логику
Например:
- запрос в БД
- проверка подписки
- сложная логика
Почему это плохо:
- выполняется на КАЖДЫЙ запрос
- создаёт лишнюю нагрузку
- ломает архитектуру
- усложняет тестирование
📉 Итог:
interceptor превращается в «мусорный слой»
💡 Как правильно:
- бизнес-логика → в сервисах
- контроллеры → orchestration
⚡️ Полезные ресурсы по Java 🚀 Max
🖥 Java можно учить месяцами - и всё равно бояться написать собственный сервер
Курс «Java: с нуля до сетевого гуру» построен так, чтобы ты как можно быстрее перешёл от теории к рабочему коду.
Сначала разберёшь основы языка, ООП, коллекции и исключения. Затем перейдёшь к тому, ради чего многие и выбирают Java:
- многопоточность;
- TCP/IP и сокеты;
- клиент-серверные приложения;
- обработка нескольких подключений;
- собственные сетевые проекты.
Каждая новая тема закрепляется практикой. Ты будешь запускать серверы, подключать клиентов, передавать данные и постепенно собирать проекты, которые уже можно показывать в портфолио.
Курс подходит новичкам. Никакой подготовки не требуется: обучение начинается с базы и шаг за шагом выводит к задачам реальной backend-разработки.
В результате ты получишь крепкую основу Java, поймёшь, как работают сетевые приложения, и перестанешь смотреть на серверный код как на магию.
Начни сейчас - и преврати Java из «когда-нибудь выучу» в навык, которым уже можно пользоваться.
Курс доступен на Stepik: https://stepik.org/a/295392/
Java-совет: два разных пути могут вести к одному файлу
Сравнение через Path.equals() проверяет только сами пути. Поэтому эти значения считаются разными:
Path path1 = Path.of("data/report.txt");
Path path2 = Path.of("data/../data/report.txt");
boolean same = Files.isSameFile(path1, path2);
Path original = Path.of("/app/config.json");
Path symlink = Path.of("/app/current-config");
if (Files.isSameFile(original, symlink)) {
System.out.println("Это один файл");
}
IOException.Files.isSameFile() полезен перед копированием, перемещением или удалением файлов — особенно когда в проекте используются символические ссылки и нестандартные пути.
Читать полностью…
❓Что из вариантов лучше всего описывается определением: Операция, которая содержит серию задач, которые должны быть выполнены либо все, либо не выполнена ни одн
#spring
Кто-то разобрал Claude Code почти до винтикаlearn-coding-agent - репозиторий для тех, кто хочет понять, как устроены современные coding agents не на уровне промо-страниц, а на уровне архитектуры.
Автор собрал разбор Claude Code по публичным источникам: цикл агента, систему инструментов, разрешения, работу с контекстом, сессии, подпроцессы, MCP, удалённые настройки, телеметрию и скрытые флаги.
Получился не “гайд по использованию”, а карта внутренней логики CLI-агента: как он принимает решение, когда просит разрешение, как вызывает инструменты, как хранит историю и как расширяется через внешние интеграции.
https://github.com/justxor/Claudecourse/
💡 Java: делегирование часто безопаснее наследования
Наследование кажется удобным, пока суперкласс не начинает жить своей жизнью.
Если класс наследуется от родителя, он получает весь его API. Любое изменение сверху может внезапно сломать поведение дочернего класса.
С делегированием проще: объект хранит внутри helper/service и передаёт ему нужные вызовы.
Плюсы:
* меньше жёсткой связности
* проще тестировать и мокать
* легче менять реализацию
* меньше риска сломаться из-за изменений в родителе
Правило простое: наследуйтесь только когда связь is-a действительно железная. В остальных случаях чаще лучше композиция и делегирование.
Новая фича затрагивает десятки файлов? Тесты становятся сложнее самого кода? А когда бизнес меняет требования — приходится переписывать половину сервиса?
Если это знакомо, то проблема, скорее всего, не в коде.
🚫 Проблема в архитектуре.
🔥 15 июля стартует практический курс по Domain-Driven Design и Clean Architecture на Java.
За 6 недель вы научитесь:
✔️ Организовывать код так, чтобы новые требования не приводили к переписыванию половины сервиса
✔️ Изолировать бизнес-логику от HTTP, Kafka, БД и других технических деталей
✔️ Строить сервисы, которые проще поддерживать, тестировать и развивать
✔️ Писать тесты, которые проверяют поведение системы, а не набор моков
✔️ Добавлять новые интеграции без изменений в ядре приложения
✔️ Уверенно работать со сложной бизнес-логикой без постоянного роста технического долга
Для этого на практике разберёте Domain-Driven Design, Aggregate, Entity и Value Object, освоите Domain Events, Clean Architecture, Hexagonal и Onion Architecture.
📦 На курсе вы соберёте полноценный сервис диспетчеризации заказов и получите готовый шаблон микросервиса, который сможете использовать в рабочих проектах.
Автор курса — Кирилл Ветчинкин, архитектор Авито, ex Staff Engineer в Купер.
👉 Посмотрите первый модуль и оцените, насколько этот подход подходит для ваших проектов: https://microarch.ru/courses/ddd/languages/java?utm_source=posev&utm_medium=erid:2VtzqwyW4fK&utm_campaign=1
Реклама. ИП Ветчинкин К.Е. ИНН: 773376451099 Erid: 2VtzqwyW4fK
✔️ Java-совет, который спасает от тихих утечек ресурсов.
Если работаете с BufferedReader, InputStream, OutputStream, FileReader, соединениями или другими ресурсами, которые нужно закрывать, используйте try-with-resources.
Плохо:
BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
reader.close() может не выполниться. В итоге останутся открытые file handles, stream’ы или соединения.
try (BufferedReader reader =
new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
try-with-resources автоматически вызовет close() даже при исключении.finallyAutoCloseable или Closeable, почти всегда стоит использовать try-with-resources.
N+1 в Spring Boot выглядит безобидно, пока прод не начинает молиться на базу данных.
Классический сценарий:
Вы грузите список заказов:orderRepository.findAll()
А потом в цикле обращаетесь к order.getItems().
Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.
100 заказов = 101 SQL-запрос.
И вот здесь спасает @EntityGraph.
Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:@EntityGraph(attributePaths = {"items"})
В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.
Что получаем:
- меньше SQL-запросов
- меньше нагрузки на БД
- чище код репозитория
- без ручного JPQL
- fetch-стратегия управляется точечно под конкретный кейсLAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.
Spring Boot: уберите try/catch из контроллеров
В Spring Boot не нужно размазывать обработку ошибок по каждому endpoint через бесконечные try/catch.
Для этого есть @RestControllerAdvice.
Идея простая: вы выносите обработку исключений в один глобальный класс, а контроллеры оставляете чистыми.
Например:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handleBadRequest(IllegalArgumentException ex) {
return ResponseEntity
.badRequest()
.body(new ErrorResponse("BAD_REQUEST", ex.getMessage()));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleGeneric(Exception ex) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("INTERNAL_ERROR", "Something went wrong"));
}
}
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
Небольшой, но полезный совет для Spring Boot.
Если у вас есть scheduled task, не стоит хардкодить интервал прямо в аннотации:
`@Scheduled(fixedRate = 5000)`
`@Scheduled(fixedRateString = "${task.interval}")`
application.properties указать:
`task.interval=5000`
⚡️ Перестаём писать методы с 7+ параметрами
Если сигнатура выглядит как:createUser(firstName, lastName, email, phone, address, city, country)
Это уже сигнал, что модель данных развалилась.
Проблема не только в читаемости.
Такие методы сложнее поддерживать, расширять и тестировать. Любое изменение ломает сигнатуру и тянет за собой каскад правок.
Нормальный вариант - собрать связанные данные в объект:UserInfo userInfo
Получаем:
- чище API
- проще добавлять поля
- меньше ошибок при передаче параметров
- код начинает отражать доменную модель, а не список строк
Это базовый приём, но именно на нём чаще всего экономят, а потом платят сложностью.
📌 Нашли 15 сайтов с миллионами бесплатных книг
Это не просто подборка, а реально огромные библиотеки
от художки до научных статей, диссертаций и учебников.
И главное
базы постоянно обновляются
• planetebook.com
• oceanofpdf.com
• freecomputerbooks.com
• zlibrary.to
• bookboon.com
• gutenberg.org
• manybooks.net
• pdfdrive.com
• digilibraries.com
• openlibrary.org
• standardebooks.org
• librivox.org
• getfreeebooks.com
• authorama.com
Если читаешь и прокачиваешься
сохрани, пригодится
🚀 Java - regex без боли
Нашли интересную библиотеку - Sift. Она заменяет весь этот ад с регулярками на нормальный fluent API.
Теперь вместо нечитаемых строк вида:
^[0-9a-fA-F]{6}$
Пишешь код, который реально понимаешь:
.char('#')
.then()
.exactly(6)
.hexDigits()
📌 Что это дает:
- Читаемый и понятный код
- Меньше ошибок в regex
- Быстрее разработка и поддержка
По сути — это как “переводчик” с языка регулярных выражений на человеческий Java-код.
Если когда-нибудь ломал голову над regex -это прям must-have.
#Java #JavaDev
🧠 Можно ли переопределить getClass() в Java?
Нет, нельзя.
Метод getClass() в java.lang.Object объявлен так:
public final native Class<?> getClass();
final — запрещает переопределение в наследниках.native — реализован в JVM, а не на Java.obj.getClass() всегда вернётся реальный класс объекта, без подмен и сюрпризов.
class MyClass {
public String getTypeName() {
return "CustomType";
}
}
getClass() сломал бы рефлексию, сериализацию и кучу системных механизмов. Именно поэтому Java защищает его.
🚀 Java 26 стала умнее — особенно в pattern matching
Теперь работа с pattern matching выражениями стала заметно стабильнее и предсказуемее
Что улучшили:
🟢 Более надёжный type inference
компилятор лучше понимает типы в сложных условиях
🟢 Меньше edge-case ошибок
меньше неожиданных падений и предупреждений
🟢 Консистентное поведение
одинаковая логика в if и switch
Что это даёт на практике:
раньше при усложнении условий
компилятор мог “теряться”
теперь:
- анализ потока стал умнее
- переменные из pattern matching корректно распознаются
- код становится чище и безопаснее
Java становится всё ближе к современным языкам
с удобным и предсказуемым контролем типов
#Java #JavaDev
⚡️ Полезные ресурсы по Java 🚀 Max
@javatg