Обработка особых случаев
Работа с null ключами
Разные реализации по-разному обрабатывают null ключи:
HashMap: Специально обрабатывает null ключ, храня его в бакете 0
TreeMap: Не поддерживает null ключи (NullPointerException)
ConcurrentHashMap: Не поддерживает null ключи из-за многопоточных ограничений
Коллизии и равенство ключей
Процесс определения равенства ключей критически важен для корректности поиска.
Система использует комбинацию проверок:
Сравнение хэш-кодов: Быстрая предварительная проверка
Проверка ссылочного равенства (==): Оптимизация для часто используемых ключей
Вызов equals(): Точное определение семантического равенства
Разработчики должны обеспечивать консистентность между hashCode() и equals() — равные объекты должны иметь равные хэш-коды.
Факторы, влияющие на производительность
Для HashMap
Качество хэш-функции: Плохая хэш-функция, создающая множество коллизий, значительно замедляет поиск. Идеальная хэш-функция равномерно распределяет ключи по бакетам.
Коэффициент загрузки: Высокий коэффициент загрузки увеличивает среднюю длину цепочек, что замедляет поиск в случае коллизий.
Размер данных: При правильном распределении производительность остается постоянной, но при многих коллизиях деградирует до O(log n) или даже O(n).
Для TreeMap
Сбалансированность дерева: Хотя красно-черное дерево гарантирует сбалансированность, степень сбалансированности влияет на константные множители производительности.
Сложность сравнения: Для ключей со сложной логикой сравнения стоимость операции get может значительно возрастать.
Потокобезопасность и видимость изменений
В контексте многопоточного программирования операция get имеет важные семантические особенности:
Несинхронизированные Map: В HashMap, LinkedHashMap, TreeMap операция get не является потокобезопасной при concurrent модификациях. Это может привести к бесконечным циклам, повреждению данных или неконсистентным результатам.
ConcurrentHashMap: Обеспечивает thread-safe операции get без блокировок, но с гарантиями weak consistency — поток может не увидеть недавно добавленные элементы.
Memory barriers: В правильно синхронизированных сценариях операция get обеспечивает happens-before отношения для последующих операций.
Кэширование и оптимизации поиска
Современные JVM применяют различные оптимизации для ускорения операций поиска:
Inline-кэширование: JVM может закэшировать результаты частых операций поиска для одинаковых ключей.
Профилирование вызовов: Сбор статистики о частоте и паттернах доступа для оптимизации горячих путей.
JIT-компиляция: Агрессивная оптимизация и развертывание циклов в критических участках кода.
Практические рекомендации
Выбор реализации для различных сценариев
Для частых операций get:
HashMap с хорошими хэш-функциями — лучший выбор
EnumMap — для enum ключей
IdentityHashMap — когда нужна ссылочная семантика
Для отсортированного доступа:
TreeMap — когда нужна сортировка или диапазонные запросы
Для многопоточных сценариев:
ConcurrentHashMap — для высококонкурентного доступа
Collections.synchronizedMap() — для низкой конкуренции
Оптимизация ключей
Неизменяемость: Использование immutable ключей предотвращает изменение хэш-кода и обеспечивает консистентность.
Эффективные equals() и hashCode():
Минимизация вычислений в этих методах
Кэширование хэш-кода для сложных объектов
Использование быстрых алгоритмов сравнения
Правильный размер: Предварительное задание адекватной емкости для HashMap уменьшает необходимость resize операций.
Отладка и мониторинг
Для диагностики проблем с производительностью операции get полезны:
Профилирование: Измерение времени, проводимого в операциях get
Анализ распределения: Для HashMap — мониторинг длины цепочек коллизий
JMX мониторинг: Для стандартных реализаций Map доступна статистика через JMX
#Java #для_новичков #beginner #Map #get
Работа с null ключами
Разные реализации по-разному обрабатывают null ключи:
HashMap: Специально обрабатывает null ключ, храня его в бакете 0
TreeMap: Не поддерживает null ключи (NullPointerException)
ConcurrentHashMap: Не поддерживает null ключи из-за многопоточных ограничений
Коллизии и равенство ключей
Процесс определения равенства ключей критически важен для корректности поиска.
Система использует комбинацию проверок:
Сравнение хэш-кодов: Быстрая предварительная проверка
Проверка ссылочного равенства (==): Оптимизация для часто используемых ключей
Вызов equals(): Точное определение семантического равенства
Разработчики должны обеспечивать консистентность между hashCode() и equals() — равные объекты должны иметь равные хэш-коды.
Факторы, влияющие на производительность
Для HashMap
Качество хэш-функции: Плохая хэш-функция, создающая множество коллизий, значительно замедляет поиск. Идеальная хэш-функция равномерно распределяет ключи по бакетам.
Коэффициент загрузки: Высокий коэффициент загрузки увеличивает среднюю длину цепочек, что замедляет поиск в случае коллизий.
Размер данных: При правильном распределении производительность остается постоянной, но при многих коллизиях деградирует до O(log n) или даже O(n).
Для TreeMap
Сбалансированность дерева: Хотя красно-черное дерево гарантирует сбалансированность, степень сбалансированности влияет на константные множители производительности.
Сложность сравнения: Для ключей со сложной логикой сравнения стоимость операции get может значительно возрастать.
Потокобезопасность и видимость изменений
В контексте многопоточного программирования операция get имеет важные семантические особенности:
Несинхронизированные Map: В HashMap, LinkedHashMap, TreeMap операция get не является потокобезопасной при concurrent модификациях. Это может привести к бесконечным циклам, повреждению данных или неконсистентным результатам.
ConcurrentHashMap: Обеспечивает thread-safe операции get без блокировок, но с гарантиями weak consistency — поток может не увидеть недавно добавленные элементы.
Memory barriers: В правильно синхронизированных сценариях операция get обеспечивает happens-before отношения для последующих операций.
Кэширование и оптимизации поиска
Современные JVM применяют различные оптимизации для ускорения операций поиска:
Inline-кэширование: JVM может закэшировать результаты частых операций поиска для одинаковых ключей.
Профилирование вызовов: Сбор статистики о частоте и паттернах доступа для оптимизации горячих путей.
JIT-компиляция: Агрессивная оптимизация и развертывание циклов в критических участках кода.
Практические рекомендации
Выбор реализации для различных сценариев
Для частых операций get:
HashMap с хорошими хэш-функциями — лучший выбор
EnumMap — для enum ключей
IdentityHashMap — когда нужна ссылочная семантика
Для отсортированного доступа:
TreeMap — когда нужна сортировка или диапазонные запросы
Для многопоточных сценариев:
ConcurrentHashMap — для высококонкурентного доступа
Collections.synchronizedMap() — для низкой конкуренции
Оптимизация ключей
Неизменяемость: Использование immutable ключей предотвращает изменение хэш-кода и обеспечивает консистентность.
Эффективные equals() и hashCode():
Минимизация вычислений в этих методах
Кэширование хэш-кода для сложных объектов
Использование быстрых алгоритмов сравнения
Правильный размер: Предварительное задание адекватной емкости для HashMap уменьшает необходимость resize операций.
Отладка и мониторинг
Для диагностики проблем с производительностью операции get полезны:
Профилирование: Измерение времени, проводимого в операциях get
Анализ распределения: Для HashMap — мониторинг длины цепочек коллизий
JMX мониторинг: Для стандартных реализаций Map доступна статистика через JMX
#Java #для_новичков #beginner #Map #get
👍2
Что выведет код?
#Tasks
import java.util.Map;
import java.util.HashMap;
public class Task051125 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", null);
Integer value1 = map.get("a");
Integer value2 = map.get("c");
Integer value3 = map.get("d");
int value4 = map.getOrDefault("d", -1);
System.out.println(value1);
System.out.println(value2);
System.out.println(value3);
System.out.println(value4);
}
}
#Tasks
Вопрос с собеседований
Чем отличается Factory от Builder?🤓
Ответ:
Factory отвечает за создание объекта определённого типа без явного вызова конструктора.
Builder — за пошаговое создание сложного объекта с множеством параметров.
Factory — «что создать», Builder — «как создать».
#собеседование
Чем отличается Factory от Builder?
Ответ:
Factory
Builder — за пошаговое создание сложного объекта с множеством параметров.
Factory — «что создать», Builder — «как создать».
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2 1
История IT-технологий сегодня — 07 ноября
ℹ️ Кто родился в этот день
Барбара Лисков (англ. Liskov, урождённая Барбара Джейн Губерман, англ. Barbara Jane Huberman; род. 7 ноября 1939, Лос-Анджелес) — американский учёный-информатик, лауреат премии Тьюринга, автор принципа замещения Лисков (Liskov substitution principle) и одного из первых языков CLU; значительный вклад в организацию дисциплины программирования.
🌐 Знаковые события
2002 — Microsoft запустила Tablet PC – первую коммерческую платформу для планшетных компьютеров с поддержкой стилуса, работающую на Windows XP Tablet PC Edition, что стало важным шагом в развитии мобильных вычислений.
#Biography #Birth_Date #Events #07Ноября
Барбара Лисков (англ. Liskov, урождённая Барбара Джейн Губерман, англ. Barbara Jane Huberman; род. 7 ноября 1939, Лос-Анджелес) — американский учёный-информатик, лауреат премии Тьюринга, автор принципа замещения Лисков (Liskov substitution principle) и одного из первых языков CLU; значительный вклад в организацию дисциплины программирования.
2002 — Microsoft запустила Tablet PC – первую коммерческую платформу для планшетных компьютеров с поддержкой стилуса, работающую на Windows XP Tablet PC Edition, что стало важным шагом в развитии мобильных вычислений.
#Biography #Birth_Date #Events #07Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Вы вкладываете деньги? Инвестируете?
Anonymous Poll
13%
Да! И давно)
13%
Не скажу. Это тайна...
38%
Нет, но хотел бы начать, но пока не с чего))
38%
Нет и я не верю в эту белиберду
gRPC в продакшене
1. Аутентификация и авторизация
gRPC изначально построен на HTTP/2, а значит поддерживает все стандартные механизмы шифрования и аутентификации, включая TLS/SSL.
На уровне протокола клиент и сервер могут обмениваться метаданными (headers), которые используются для передачи токенов, ключей или сессионных идентификаторов.
Аутентификация (authentication)
Аутентификация — это подтверждение личности клиента.
В gRPC это реализуется через метаданные (Metadata), которые добавляются к каждому запросу:
На стороне сервера этот токен можно проверить с помощью interceptor (см. ниже).
В корпоративных системах часто используются:
JWT (JSON Web Token) — стандартный формат токена.
mTLS (Mutual TLS) — двустороннее TLS-шифрование, где аутентифицируются обе стороны.
OAuth 2.0 — для интеграции с внешними провайдерами (Google, Auth0 и т.п.).
Авторизация (authorization)
После того как клиент прошёл аутентификацию, нужно проверить, имеет ли он право выполнять определённые действия.
Обычно авторизация реализуется на уровне interceptor’ов или бизнес-логики, где проверяются роли и права пользователя.
2. Interceptors — middleware для gRPC
Interceptors в gRPC выполняют ту же роль, что фильтры в Spring или middleware в Express.js.
Это промежуточные обработчики, которые могут:
логировать запросы и ответы;
измерять метрики;
проверять токены безопасности;
модифицировать контекст вызова;
перехватывать ошибки.
Пример серверного interceptor’а
Регистрируется interceptor при инициализации сервера:
Interceptors можно комбинировать — например, один для логирования, другой для метрик, третий для авторизации.
Это делает gRPC гибким и расширяемым.
#Java #middle #gRPC #proto
1. Аутентификация и авторизация
gRPC изначально построен на HTTP/2, а значит поддерживает все стандартные механизмы шифрования и аутентификации, включая TLS/SSL.
На уровне протокола клиент и сервер могут обмениваться метаданными (headers), которые используются для передачи токенов, ключей или сессионных идентификаторов.
Аутентификация (authentication)
Аутентификация — это подтверждение личности клиента.
В gRPC это реализуется через метаданные (Metadata), которые добавляются к каждому запросу:
// Пример Java-клиента с авторизационным токеном
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 50051)
.useTransportSecurity()
.build();
CarServiceGrpc.CarServiceBlockingStub stub = CarServiceGrpc
.newBlockingStub(channel)
.withCallCredentials(new CallCredentials() {
@Override
public void applyRequestMetadata(
RequestInfo requestInfo, Executor executor, MetadataApplier applier) {
Metadata headers = new Metadata();
Metadata.Key<String> AUTHORIZATION =
Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER);
headers.put(AUTHORIZATION, "Bearer my-secret-token");
applier.apply(headers);
}
});
На стороне сервера этот токен можно проверить с помощью interceptor (см. ниже).
В корпоративных системах часто используются:
JWT (JSON Web Token) — стандартный формат токена.
mTLS (Mutual TLS) — двустороннее TLS-шифрование, где аутентифицируются обе стороны.
OAuth 2.0 — для интеграции с внешними провайдерами (Google, Auth0 и т.п.).
Авторизация (authorization)
После того как клиент прошёл аутентификацию, нужно проверить, имеет ли он право выполнять определённые действия.
Обычно авторизация реализуется на уровне interceptor’ов или бизнес-логики, где проверяются роли и права пользователя.
2. Interceptors — middleware для gRPC
Interceptors в gRPC выполняют ту же роль, что фильтры в Spring или middleware в Express.js.
Это промежуточные обработчики, которые могут:
логировать запросы и ответы;
измерять метрики;
проверять токены безопасности;
модифицировать контекст вызова;
перехватывать ошибки.
Пример серверного interceptor’а
public class AuthInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
ServerCall<ReqT, RespT> call,
Metadata headers,
ServerCallHandler<ReqT, RespT> next) {
String token = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
if (token == null || !token.equals("Bearer my-secret-token")) {
call.close(Status.UNAUTHENTICATED.withDescription("Invalid token"), headers);
return new ServerCall.Listener<>() {}; // пустой listener
}
return next.startCall(call, headers);
}
}Регистрируется interceptor при инициализации сервера:
Server server = ServerBuilder
.forPort(50051)
.addService(ServerInterceptors.intercept(new CarServiceImpl(), new AuthInterceptor()))
.build()
.start();
Interceptors можно комбинировать — например, один для логирования, другой для метрик, третий для авторизации.
Это делает gRPC гибким и расширяемым.
#Java #middle #gRPC #proto
👍1
3. gRPC Gateway — REST-прокси для совместимости
Хотя gRPC эффективен, не все клиенты умеют с ним работать напрямую (например, браузеры без gRPC-Web).
Чтобы не дублировать API, используется gRPC Gateway — это HTTP-прокси, который преобразует REST-запросы в gRPC-вызовы.
Как это работает
Клиент делает обычный HTTP-запрос (GET, POST, PUT).
Gateway принимает запрос и преобразует его в бинарный gRPC-вызов.
Сервер gRPC обрабатывает его и возвращает ответ.
Gateway обратно конвертирует ответ в JSON.
Файл .proto содержит специальные аннотации:
Так создаётся REST-эндпоинт /v1/cars/{id}, который вызывает gRPC-метод GetCar.
gRPC Gateway позволяет сохранять одну кодовую базу и одну схему, но обслуживать и gRPC-, и REST-клиентов одновременно.
4. Балансировка нагрузки и мониторинг
gRPC поддерживает client-side load balancing, когда клиент сам выбирает, к какому серверу подключаться, используя список адресов.
Это особенно важно для микросервисов, где количество экземпляров сервиса динамически меняется.
Поддерживаются различные политики: round-robin, pick-first, weighted.
В Kubernetes это можно комбинировать с сервис-дискавери (через DNS или Consul).
Для продакшена жизненно важно собирать метрики.
gRPC интегрируется с Prometheus, OpenTelemetry, Zipkin, Jaeger для трассировки и мониторинга.
Через interceptors можно логировать время ответа, коды ошибок и нагрузку:
Трассировка (tracing) позволяет увидеть цепочку вызовов между микросервисами — от клиента до базы данных.
5. Совместимость версий и эволюция схем
Когда сервисы растут, .proto-файлы меняются.
Важно, чтобы новые версии клиента и сервера могли работать вместе без сбоев.
Для этого protobuf предоставляет правила совместимости.
Основные правила миграции
Не менять номера полей.
Каждое поле в message имеет уникальный номер, и именно он используется при сериализации.
Изменить имя поля можно, номер — нельзя.
Резервировать удалённые поля.
Если поле больше не используется, его нужно “зарезервировать”:
Это защищает от случайного переиспользования номеров или имён.
Добавлять новые поля безопасно.
Клиенты старых версий просто игнорируют незнакомые поля, сохраняя обратную совместимость.
Не менять тип данных существующих полей.
Например, int32 нельзя заменить на string.
Версионирование API
Часто версии отражаются в пакетах или namespace:
Так можно постепенно внедрять новые контракты без нарушения старых клиентов.
6. Как всё выглядит в продакшене
Реальная система на gRPC обычно включает:
Сервер с набором interceptor’ов (логирование, метрики, безопасность).
TLS-сертификаты и JWT-аутентификацию.
Балансировку через Kubernetes или сервис-дискавери.
Мониторинг и трассировку через OpenTelemetry.
gRPC Gateway для REST-клиентов.
CI/CD-пайплайн, генерирующий код по .proto и публикующий артефакты для разных языков.
#Java #middle #gRPC #proto
Хотя gRPC эффективен, не все клиенты умеют с ним работать напрямую (например, браузеры без gRPC-Web).
Чтобы не дублировать API, используется gRPC Gateway — это HTTP-прокси, который преобразует REST-запросы в gRPC-вызовы.
Как это работает
Клиент делает обычный HTTP-запрос (GET, POST, PUT).
Gateway принимает запрос и преобразует его в бинарный gRPC-вызов.
Сервер gRPC обрабатывает его и возвращает ответ.
Gateway обратно конвертирует ответ в JSON.
Файл .proto содержит специальные аннотации:
import "google/api/annotations.proto";
service CarService {
rpc GetCar(GetCarRequest) returns (CarResponse) {
option (google.api.http) = {
get: "/v1/cars/{id}"
};
}
}
Так создаётся REST-эндпоинт /v1/cars/{id}, который вызывает gRPC-метод GetCar.
gRPC Gateway позволяет сохранять одну кодовую базу и одну схему, но обслуживать и gRPC-, и REST-клиентов одновременно.
4. Балансировка нагрузки и мониторинг
gRPC поддерживает client-side load balancing, когда клиент сам выбирает, к какому серверу подключаться, используя список адресов.
Это особенно важно для микросервисов, где количество экземпляров сервиса динамически меняется.
Поддерживаются различные политики: round-robin, pick-first, weighted.
В Kubernetes это можно комбинировать с сервис-дискавери (через DNS или Consul).
ManagedChannel channel = ManagedChannelBuilder
.forTarget("dns:///my-grpc-service.default.svc.cluster.local")
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext()
.build();
Для продакшена жизненно важно собирать метрики.
gRPC интегрируется с Prometheus, OpenTelemetry, Zipkin, Jaeger для трассировки и мониторинга.
Через interceptors можно логировать время ответа, коды ошибок и нагрузку:
long start = System.nanoTime();
RespT response = next.startCall(call, headers);
long duration = System.nanoTime() - start;
metrics.recordLatency(duration);
Трассировка (tracing) позволяет увидеть цепочку вызовов между микросервисами — от клиента до базы данных.
5. Совместимость версий и эволюция схем
Когда сервисы растут, .proto-файлы меняются.
Важно, чтобы новые версии клиента и сервера могли работать вместе без сбоев.
Для этого protobuf предоставляет правила совместимости.
Основные правила миграции
Не менять номера полей.
Каждое поле в message имеет уникальный номер, и именно он используется при сериализации.
Изменить имя поля можно, номер — нельзя.
Резервировать удалённые поля.
Если поле больше не используется, его нужно “зарезервировать”:
message Car {
reserved 4, 6 to 8;
reserved "old_model", "legacy_color";
}Это защищает от случайного переиспользования номеров или имён.
Добавлять новые поля безопасно.
Клиенты старых версий просто игнорируют незнакомые поля, сохраняя обратную совместимость.
Не менять тип данных существующих полей.
Например, int32 нельзя заменить на string.
Версионирование API
Часто версии отражаются в пакетах или namespace:
package car.v1;
service CarService { ... }
package car.v2;
service CarService { ... }
Так можно постепенно внедрять новые контракты без нарушения старых клиентов.
6. Как всё выглядит в продакшене
Реальная система на gRPC обычно включает:
Сервер с набором interceptor’ов (логирование, метрики, безопасность).
TLS-сертификаты и JWT-аутентификацию.
Балансировку через Kubernetes или сервис-дискавери.
Мониторинг и трассировку через OpenTelemetry.
gRPC Gateway для REST-клиентов.
CI/CD-пайплайн, генерирующий код по .proto и публикующий артефакты для разных языков.
#Java #middle #gRPC #proto
👍1
Что выведет код?
#Tasks
import java.util.concurrent.ConcurrentHashMap;
public class Task071125 {
public static void main(String[] args) throws InterruptedException {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("count", 0);
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
map.computeIfPresent("count", (k, v) -> v + 1);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
map.put("count", map.get("count") + 1);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(map.get("count"));
}
}
#Tasks
👍2
Варианты ответа:
Anonymous Quiz
36%
Будет исключение
0%
Больше 2000
55%
Меньше или равно 2000
9%
Меньше 1000
Вопрос с собеседований
Что делает паттерн Strategy?🤓
Ответ:
Strategy определяет семейство алгоритмов и позволяет подменять их во время выполнения.
Вместо множества if-else выбирается реализация через интерфейс.
Например, разные алгоритмы сортировки или расчёта скидок можно инкапсулировать в отдельные классы.
#собеседование
Что делает паттерн Strategy?
Ответ:
Вместо множества if-else выбирается реализация через интерфейс.
Например, разные алгоритмы сортировки или расчёта скидок можно инкапсулировать в отдельные классы.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
История IT-технологий сегодня — 08 ноября
ℹ️ Кто родился в этот день
Билл Джой (полное имя Уильям Нельсон Джой, William Nelson Joy, 8 ноября 1954 года, Детройт) — американский инженер-программист, со-основатель Sun Microsystems, один из ключевых авторов Unix/BSD, создатель редактора vi; пример сильного влияния на ОС и инфраструктуру ИТ.
Джек Сен-Клер Ки́лби (англ. Jack St. Clair Kilby, 8 ноября 1923 года, Джефферсон-Сити — 20 июня 2005, Даллас) — американский учёный. Лауреат Нобелевской премии по физике 2000 года за изобретение интегральной схемы в 1958 году в период работы в Texas Instruments (TI). Также он — изобретатель карманного калькулятора и термопринтера (1967).
🌐 Знаковые события
1895 — в процессе экспериментов с электричеством Вильгельм Рентген открыл излучение, названное им X-лучами. Впоследствии в честь учёного оно получило название рентгеновского.
#Biography #Birth_Date #Events #08Ноября
Билл Джой (полное имя Уильям Нельсон Джой, William Nelson Joy, 8 ноября 1954 года, Детройт) — американский инженер-программист, со-основатель Sun Microsystems, один из ключевых авторов Unix/BSD, создатель редактора vi; пример сильного влияния на ОС и инфраструктуру ИТ.
Джек Сен-Клер Ки́лби (англ. Jack St. Clair Kilby, 8 ноября 1923 года, Джефферсон-Сити — 20 июня 2005, Даллас) — американский учёный. Лауреат Нобелевской премии по физике 2000 года за изобретение интегральной схемы в 1958 году в период работы в Texas Instruments (TI). Также он — изобретатель карманного калькулятора и термопринтера (1967).
1895 — в процессе экспериментов с электричеством Вильгельм Рентген открыл излучение, названное им X-лучами. Впоследствии в честь учёного оно получило название рентгеновского.
#Biography #Birth_Date #Events #08Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
С 01.11 по 07.11
Предыдущий пост(с 25.10 по 31.10)
Воскресный мотивационный пост:
не было мотивации
Запись встреч/видео:
GraphQL. Как усложнение упрощает жизнь
Обучающие статьи:
Java:
Коллекции в Java
Глава 5. Map — отображения (словари)
Основные методы: put - глубокое погружение в механизм добавления элементов
Основные методы: get - глубокое погружение в механизм поиска элементов
gRPC
Типы RPC в gRPC
gRPC в продакшене
Полезные статьи и видео:
Маппинг даты и времени в Hibernate и JPA
Гибкий поиск в Spring Data Elasticsearch: Превращаем «првт мр» в «Привет, мир!»
Build AI-Powered Apps with MCP Clients in Spring AI
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 25.10 по 31.10)
Воскресный мотивационный пост:
не было мотивации
Запись встреч/видео:
GraphQL. Как усложнение упрощает жизнь
Обучающие статьи:
Java:
Коллекции в Java
Глава 5. Map — отображения (словари)
Основные методы: put - глубокое погружение в механизм добавления элементов
Основные методы: get - глубокое погружение в механизм поиска элементов
gRPC
Типы RPC в gRPC
gRPC в продакшене
Полезные статьи и видео:
Маппинг даты и времени в Hibernate и JPA
Гибкий поиск в Spring Data Elasticsearch: Превращаем «првт мр» в «Привет, мир!»
Build AI-Powered Apps with MCP Clients in Spring AI
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Оглавление.
Раздел 1: Знакомство с Java
Глава 1. Введение в Java
Введение в Java
Области применения Java
Как установить JDK
Глава 2. Настройка среды разработки
Основы работы с терминалом в Java
Обзор платформ для разработки на Java
Глава 3. Первая программа
Первая программа на Java
Раздел 1: Знакомство с Java
Глава 1. Введение в Java
Введение в Java
Области применения Java
Как установить JDK
Глава 2. Настройка среды разработки
Основы работы с терминалом в Java
Обзор платформ для разработки на Java
Глава 3. Первая программа
Первая программа на Java
🔥2
Оглавление.
Введение в Gradle и концептуальная архитектура
Структура build-файла Gradle
Зависимости и конфигурации в Gradle
Задачи и жизненный цикл в Gradle
Плагины и расширение функциональности в Gradle
Модульность и многомодульные проекты в Gradle
Конфигурация, профили, параметры и свойства в Gradle: Управление сборкой
Интеграции, публикации в Gradle
Введение в Gradle и концептуальная архитектура
Структура build-файла Gradle
Зависимости и конфигурации в Gradle
Задачи и жизненный цикл в Gradle
Плагины и расширение функциональности в Gradle
Модульность и многомодульные проекты в Gradle
Конфигурация, профили, параметры и свойства в Gradle: Управление сборкой
Интеграции, публикации в Gradle
👍2
Оглавление.
Раздел 4: Управляющие конструкции
Глава 1. Условные операторы
if / else в Java
Switch/case в Java
Глава 2. Циклы
while / do-while в Java
for, foreach
Break, continue, метки (label) в Java
Раздел 4: Управляющие конструкции
Глава 1. Условные операторы
if / else в Java
Switch/case в Java
Глава 2. Циклы
while / do-while в Java
for, foreach
Break, continue, метки (label) в Java
Оглавление.
Раздел 5. Основы ООП
Глава 1. Классы и объекты
ООП. Классы и объекты
Классы и объекты Конструкторы. Перегрузка. Ключевое слово this
Глава 2. Инкапсуляция
Инкапсуляция Принцип инкапсуляции: скрытие внутреннего состояния
Геттеры и сеттеры. Инкапсуляция как интерфейс класса
Глава 3. Наследование
Расширение классов с extends
Переопределение и ключевое слово super
Глава 4. Полиморфизм
Полиморфизм. Поведение через суперкласс и интерфейс
Полиморфизм. instanceof и приведение типов
Глава 5. Абстракция
Абстракция. Абстрактные классы и методы
Интерфейсы. Default и static методы
Глава 6. Ключевые модификаторы ООП
final: переменные, методы, классы
static: поля, методы, блоки инициализации
Перечисления (enum)
Глава 7. Принципы проектирования и хорошего кода
Принципы проектирования и хорошего кода: SOLID
DRY, KISS, YAGNI
Композиция vs Наследование
Раздел 5. Основы ООП
Глава 1. Классы и объекты
ООП. Классы и объекты
Классы и объекты Конструкторы. Перегрузка. Ключевое слово this
Глава 2. Инкапсуляция
Инкапсуляция Принцип инкапсуляции: скрытие внутреннего состояния
Геттеры и сеттеры. Инкапсуляция как интерфейс класса
Глава 3. Наследование
Расширение классов с extends
Переопределение и ключевое слово super
Глава 4. Полиморфизм
Полиморфизм. Поведение через суперкласс и интерфейс
Полиморфизм. instanceof и приведение типов
Глава 5. Абстракция
Абстракция. Абстрактные классы и методы
Интерфейсы. Default и static методы
Глава 6. Ключевые модификаторы ООП
final: переменные, методы, классы
static: поля, методы, блоки инициализации
Перечисления (enum)
Глава 7. Принципы проектирования и хорошего кода
Принципы проектирования и хорошего кода: SOLID
DRY, KISS, YAGNI
Композиция vs Наследование
Оглавление.
Раздел 6. Коллекции
Глава 1. Введение в коллекции
Обзор Java Collections Framework. Интерфейсы Collection и Map. Иерархия коллекций. Отличия коллекций от массивов
Основные характеристики коллекций: время доступа (Big O), хранение уникальных элементов, упорядоченность и сортировка
(Практика): Начать проект «Библиотека»
Глава 2. List — списки
Глава 3. Set — множества
Интерфейс Set. Особенности множеств
Реализации: HashSet, LinkedHashSet, TreeSet
Методы add, remove, contains
Практика: В «Библиотеке» создать коллекцию Set для хранения уникальных имён авторов. Добавлять автора при добавлении книги, проверять уникальность
Глава 4. Queue и Deque
Интерфейс Queue. Очередь как структура FIFO. Методы offer, poll, peek
Реализации: PriorityQueue, LinkedList как очередь. Применение: обработка задач, хранение заявок
Интерфейс Deque. Двусторонняя очередь (FIFO и LIFO). Реализации: ArrayDeque, LinkedList
Практика: проект «Библиотека»
Глава 5. Map — отображения (словари)
Интерфейс Map. Хранение пар «ключ–значение»
Реализации: HashMap, LinkedHashMap, TreeMap и остальные
Глава 6. Итераторы
Глава 7. Сравнение объектов
Глава 8. Дополнительные аспекты коллекций
Раздел 6. Коллекции
Глава 1. Введение в коллекции
Обзор Java Collections Framework. Интерфейсы Collection и Map. Иерархия коллекций. Отличия коллекций от массивов
Основные характеристики коллекций: время доступа (Big O), хранение уникальных элементов, упорядоченность и сортировка
(Практика): Начать проект «Библиотека»
Глава 2. List — списки
Глава 3. Set — множества
Интерфейс Set. Особенности множеств
Реализации: HashSet, LinkedHashSet, TreeSet
Методы add, remove, contains
Практика: В «Библиотеке» создать коллекцию Set для хранения уникальных имён авторов. Добавлять автора при добавлении книги, проверять уникальность
Глава 4. Queue и Deque
Интерфейс Queue. Очередь как структура FIFO. Методы offer, poll, peek
Реализации: PriorityQueue, LinkedList как очередь. Применение: обработка задач, хранение заявок
Интерфейс Deque. Двусторонняя очередь (FIFO и LIFO). Реализации: ArrayDeque, LinkedList
Практика: проект «Библиотека»
Глава 5. Map — отображения (словари)
Интерфейс Map. Хранение пар «ключ–значение»
Реализации: HashMap, LinkedHashMap, TreeMap и остальные
Глава 6. Итераторы
Глава 7. Сравнение объектов
Глава 8. Дополнительные аспекты коллекций