Java for Beginner
775 subscribers
773 photos
220 videos
12 files
1.3K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Вопрос с собеседований

Разница между Callable и Runnable? 🤓


Ответ:

Runnable
не возвращает результат и не бросает проверяемых исключений.

Callable возвращает значение и может выбрасывать исключения, что делает его удобным для асинхронных задач.

Обычно используется вместе с Future и ExecutorService для получения результатов.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
История IT-технологий сегодня — 09 декабря


ℹ️ Кто родился в этот день

Грейс Хоппер (англ. Grace Hopper, урождённая Grace Brewster Murray — Грейс Брюстер Мюррей; 9 декабря 1906 — 1 января 1992) — пионер программирования, создатель компиляторов и одного из предшественников COBOL; её работа по машинно-независимым языкам стала краеугольным камнем прикладного ПО.

Дэвид Стифлер Джонсон (9 декабря 1945, Вашингтон — 8 марта 2016) — ведущий исследователь в области алгоритмов и теории сложности, автор важной монографии по NP-полноте и многолетний руководитель исследований по оптимизации в AT&T Labs.

Шветак Пател (Патель) (Shwetak N. Patel; род. 9 декабря 1981, Сельма, Алабама) — современный исследователь в области сенсоров и энергосберегающих систем (убер-сенсоры для умного дома, мобильные сенсоры), лауреат премий за прикладные решения в мобильном и экологическом сенсировании.


🌐 Знаковые события

1968 — Дуглас Энгельбарт впервые публично продемонстрировал изобретённые им или в его лаборатории компьютерную мышь и гипертекст.


#Biography #Birth_Date #Events #09Декабря
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Конфигурация маршрутов в Spring Cloud Gateway

Декларативная конфигурация через application.yml
Конфигурация через YAML-файлы является декларативным подходом, где маршруты определяются статически на этапе компиляции или до запуска приложения. Этот метод обеспечивает простоту чтения, версионирование через системы контроля версий и простоту аудита изменений.


Базовая структура конфигурации маршрута


В YAML маршруты конфигурируются через иерархию spring.cloud.gateway.routes. Каждый маршрут должен иметь уникальный идентификатор, URI назначения, список предикатов и опциональный список фильтров.
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: http://localhost:8081
predicates:
- Path=/api/users/**
- Method=GET,POST
- Header=X-Requested-With, XMLHttpRequest
filters:
- StripPrefix=1
- AddRequestHeader=X-Gateway-Version, v2.0
- RewritePath=/api/users/(?<segment>.*), /$\{segment}
metadata:
response-timeout: 5000
connect-timeout: 2000
max-auto-retries: 3



Детализация предикатов

Предикаты в YAML конфигурируются как список строк, где каждая строка соответствует фабрике предикатов и её параметрам. Формат: Name=arg1,arg2,...,key1=value1,key2=value2.

Предикат Path:
predicates:
- Path=/api/v1/.*
- Path=/api/orders/{segment}, /api/products/{segment}
При использовании фигурных скобок {segment} происходит извлечение переменных пути, которые затем доступны в фильтрах через шаблоны типа ${segment}.


Составные предикаты с помощью After и Before:
predicates:
- After=2023-01-20T17:42:47.789-07:00[America/Denver]
- Between=2023-01-20T17:42:47.789-07:00[America/Denver],2023-01-21T17:42:47.789-07:00[America/Denver]
Временные предикаты используют формат даты-времени ISO-8601 и учитывают временные зоны. Они полезны для канарей-развёртываний и управления версиями API.


Предикат Query для проверки параметров:
predicates:
- Query=version, ^v[0-9]+$
- Query=token
Первый вариант проверяет, что параметр version существует и соответствует регулярному выражению. Второй вариант проверяет только наличие параметра token без проверки значения.


Предикат RemoteAddr для контроля доступа по IP:
predicates:
- RemoteAddr=192.168.1.1/24, 10.0.0.1/8
Поддерживается CIDR-нотация. Этот предикат часто комбинируется с фильтрами аутентификации для создания многоуровневой безопасности.


Кастомный предикат с использованием SpEL:

predicates:
- name: Custom
args:
name: myPredicate
spel: "#{@tokenValidator.validate(request)}"
Для кастомных предикатов используется полная форма конфигурации с указанием имени и аргументов. SpEL (Spring Expression Language) позволяет вызывать Spring Beans и выполнять сложную логику.



Фильтры в YAML конфигурации

Фильтры определяют преобразования, применяемые к запросу или ответу. Они выполняются в порядке объявления.

Базовые фильтры преобразования:
filters:
# Удаление частей пути
- StripPrefix=2

# Добавление заголовков
- AddRequestHeader=X-Client-Version, 1.0.0
- AddResponseHeader=X-Response-Time, "`new java.text.SimpleDateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(new java.util.Date())`"

# Установка пути
- SetPath=/api/v2/{segment}

# Изменение порта и хоста
- SetRequestHost=api.example.com

# Перенаправление
- RedirectTo=302, https://secure.example.com


Фильтры для работы с телом запроса:
filters:
# Модификация тела запроса (требует чтения всего тела в память)
- ModifyRequestBody=com.example.JsonTransformer, application/json, application/json, 102400

# Модификация тела ответа
- ModifyResponseBody=com.example.ResponseNormalizer, application/json, application/json

# Кэширование тела запроса для многократного чтения
- CacheRequestBody=""

Фильтры модификации тела используют регистрируемые через Spring Beans трансформеры. Важно понимать, что они требуют чтения всего тела запроса в память, что может быть проблематично для больших payload.



#Java #middle #Spring_Cloud_Gateway
👍2
Фильтры устойчивости и ограничения:
filters:
# Circuit Breaker с Resilience4J
- name: CircuitBreaker
args:
name: userServiceBreaker
fallbackUri: forward:/fallback/user
statusCodes: 500,502,503

# Ограничение частоты запросов с Redis
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
key-resolver: "#{@userKeyResolver}"

# Retry с экспоненциальной отсрочкой
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR
methods: GET,POST
series: SERVER_ERROR
backoff:
firstBackoff: 50ms
maxBackoff: 1000ms
factor: 2
basedOnPreviousValue: false



URI и метаданные

URI назначения поддерживает несколько схем:
uri: http://localhost:8081           # Прямой URL
uri: https://api.example.com:8443 # HTTPS
uri: lb://USER-SERVICE # Балансировка нагрузки через Service Discovery
uri: ws://echo.example.com # WebSocket
uri: forward:/fallback # Внутреннее перенаправление

Схема lb:// активирует клиентскую балансировку нагрузки. При использовании с Service Discovery (Eureka, Consul) имя сервиса автоматически разрешается в список доступных экземпляров.


Метаданные маршрута предоставляют дополнительную конфигурацию, специфичную для маршрута:
metadata:
# Таймауты для Netty
response-timeout: 5000 # Таймаут ответа в миллисекундах
connect-timeout: 2000 # Таймаут соединения
max-auto-retries: 2 # Автоматические повторы для сетевых ошибок

# Конфигурация для конкретных интеграций
hystrix.commandName: userCommand
metrics.tags: "service=user,version=v2"

# Пользовательские метаданные
feature-flags: "canary=true,experimental=false"
sla: "p99<200ms"

Метаданные доступны в фильтрах через exchange.getAttribute(ROUTE_ATTRIBUTE).getMetadata() и могут использоваться для реализации динамического поведения.



#Java #middle #Spring_Cloud_Gateway
👍2
Java DSL: Fluent API для программируемой конфигурации

Java DSL через RouteLocatorBuilder предоставляет императивный способ определения маршрутов, который позволяет использовать всю мощь Java: условия, циклы, вызовы методов, dependency injection.

Базовый fluent-синтаксис

@Configuration
public class GatewayConfiguration {

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user_route", r -> r
.path("/api/users/**")
.and()
.method(HttpMethod.GET, HttpMethod.POST)
.and()
.header("X-API-Version", "v2")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-Gateway-Route", "user")
.circuitBreaker(config -> config
.setName("userCircuitBreaker")
.setFallbackUri("forward:/fallback/user"))
.retry(config -> config
.setRetries(3)
.setStatuses(HttpStatus.INTERNAL_SERVER_ERROR,
HttpStatus.BAD_GATEWAY)
.setMethods(HttpMethod.GET)
.setBackoff(50, 200, 2, true))
)
.uri("lb://user-service")
.metadata("response-timeout", 3000)
.metadata("connect-timeout", 1000)
)
.route("product_route", r -> r
.path("/api/products/**")
.filters(f -> f
.rewritePath("/api/products/(?<segment>.*)",
"/v2/products/${segment}")
.addResponseHeader("X-Cache-Control", "max-age=3600")
.requestRateLimiter(config -> config
.setRateLimiter(redisRateLimiter())
.setKeyResolver(userKeyResolver()))
)
.uri("lb://product-service")
)
.build();
}

@Bean
public RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(10, 20, 1);
}

@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getHeaders()
.getFirst("X-User-Id")
);
}
}



Преимущества Java DSL перед YAML

1. Использование Spring Beans в конфигурации:
@Bean
public RouteLocator dynamicRouteLocator(
RouteLocatorBuilder builder,
FeatureFlagService featureService,
CircuitBreakerRegistry breakerRegistry) {

return builder.routes()
.route("feature_route", r -> r
.path("/experimental/**")
.predicate(exchange -> {
// Динамическая проверка feature flags
boolean enabled = featureService.isEnabled(
"experimental_api",
exchange.getRequest().getHeaders()
.getFirst("X-User-Id")
);
return enabled;
})
.filters(f -> f
.circuitBreaker(config -> config
.setCircuitBreakerFactory(
new ReactiveResilience4JCircuitBreakerFactory(
breakerRegistry
)
)
.setName("experimentalBreaker")
)
)
.uri("lb://experimental-service")
)
.build();
}



#Java #middle #Spring_Cloud_Gateway
👍3
2. Генерация маршрутов на основе данных из внешних источников:
@Bean
public RouteLocator generatedRoutes(
RouteLocatorBuilder builder,
RouteTemplateService templateService) {

RouteLocatorBuilder.Builder routesBuilder = builder.routes();

// Загрузка шаблонов маршрутов из базы данных
List<RouteTemplate> templates = templateService.loadTemplates();

for (RouteTemplate template : templates) {
routesBuilder.route(template.getId(), r -> {
RouteLocatorBuilder.Builder spec = r
.path(template.getPathPattern())
.uri(template.getTargetUri());

// Динамическое добавление фильтров
for (FilterConfig filterConfig : template.getFilters()) {
spec.filters(f -> addFilterDynamically(f, filterConfig));
}

return spec;
});
}

return routesBuilder.build();
}


3. Создание сложных составных предикатов:
@Bean
public RouteLocator complexPredicateRoute(RouteLocatorBuilder builder) {
return builder.routes()
.route("business_rule_route", r -> r
// Комбинация предикатов с кастомной логикой
.asyncPredicate(exchange -> {
return businessRuleEngine()
.evaluate(exchange.getRequest())
.map(BusinessDecision::isAllowed);
})
.and()
.weight("group_a", 80) // 80% трафика
.and()
.cookie("session_id", ".*")
.filters(f -> f
.modifyRequestBody(String.class, String.class,
(exchange, body) -> {
// Модификация тела на основе бизнес-правил
return Mono.just(
transformPayload(body, exchange)
);
}
)
)
.uri("lb://primary-service")
)
.build();
}



Что можно делать только в DSL и нельзя в YAML

1. Использование произвольных Predicate<ServerWebExchange>:
.route("custom_predicate", r -> r
.predicate(exchange -> {
// Любая Java-логика
String clientIp = exchange.getRequest()
.getRemoteAddress()
.getAddress()
.getHostAddress();

return !ipBlacklist.contains(clientIp) &&
rateLimiter.tryAcquire(clientIp);
})
.uri("lb://service")
)


2. Интеграция с внешними системами конфигурации:
.route("external_config", r -> r
.asyncPredicate(exchange -> {
// Загрузка правил из внешнего сервиса
return configClient.getRoutingRules()
.map(rules -> rules.matches(exchange.getRequest()));
})
.filters((exchange, chain) -> {
// Динамическая модификация на основе конфигурации
ServerHttpRequest request = exchange.getRequest();
Map<String, String> headers = externalConfig
.getHeadersForRoute(request.getPath().toString());

ServerHttpRequest mutated = request.mutate()
.headers(h -> headers.forEach(h::add))
.build();

return chain.filter(
exchange.mutate().request(mutated).build()
);
})
.uri("lb://target")
)


#Java #middle #Spring_Cloud_Gateway
👍3
3. Генерация маршрутов в runtime:
@Bean
public RouteLocator runtimeGeneratedRoutes(
RouteLocatorBuilder builder,
ApplicationContext context) {

RouteLocatorBuilder.Builder routes = builder.routes();

// Динамическое создание маршрутов на основе Bean-ов
Map<String, RouteProvider> providers = context
.getBeansOfType(RouteProvider.class);

providers.forEach((name, provider) -> {
provider.getRoutes().forEach(routeDef -> {
routes.route(routeDef.getId(), r -> {
AbstractRouteSpec spec = r
.path(routeDef.getPath())
.uri(routeDef.getUri());

routeDef.getFilters().forEach(filter -> {
spec.filters(f -> configureFilter(f, filter));
});

return spec;
});
});
});

return routes.build();
}



Динамическая маршрутизация

DiscoveryClientRouteDefinitionLocator

DiscoveryClientRouteDefinitionLocator обеспечивает автоматическое создание маршрутов на основе сервисов, зарегистрированных в Service Discovery. При активации, для каждого зарегистрированного сервиса создаётся маршрут, который перенаправляет трафик на этот сервис.

spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
predicates:
- name: Path
args:
pattern: "'/services/' + serviceId.toLowerCase() + '/**'"
filters:
- name: RewritePath
args:
regexp: "'/services/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"


Эта конфигурация создаст маршруты вида:
http://gateway/services/user-service/** → lb://user-service
http://gateway/services/order-service/** → lb://order-service



Интеграция с Eureka

Для интеграции с Eureka необходимо добавить зависимость и соответствующую конфигурацию:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>


eureka:
client:
service-url:
defaultZone: http://eureka-server:8761/eureka
registry-fetch-interval-seconds: 5
instance:
lease-renewal-interval-in-seconds: 10
lease-expiration-duration-in-seconds: 30

spring:
cloud:
gateway:
discovery:
locator:
enabled: true
# Добавление метаданных из Eureka в маршруты
include-expression: metadata['gateway.enabled'] == 'true'
url-expression: "'lb://' + serviceId"


Eureka-специфичные метаданные могут использоваться для управления маршрутизацией:
@Bean
public RouteLocator eurekaAwareRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("zone_aware", r -> r
.path("/zone/**")
.predicate(exchange -> {
// Выбор экземпляра в той же зоне доступности
ServiceInstance instance = loadBalancer.choose(
"target-service",
new ZonePreferenceServiceInstanceListSupplier()
);
return instance != null;
})
.uri("lb://target-service")
)
.build();
}



#Java #middle #Spring_Cloud_Gateway
👍2
Интеграция с Consul

Consul предоставляет более богатые возможности для service discovery и health checking:

spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
health-check-path: /actuator/health
health-check-interval: 10s
tags:
- gateway-enabled
- version=v2
query-passing: true # Использовать только здоровые инстансы

gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/consul/' + serviceId + '/**'"
filters:
- name: RewritePath
args:
regexp: "'/consul/' + serviceId + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
# Фильтрация по Consul-тегам
include-expression: tags.contains('gateway-enabled')


Consul теги могут использоваться для реализации сложной логики маршрутизации:
@Bean
public RouteLocator consulTagBasedRoutes(
RouteLocatorBuilder builder,
ConsulDiscoveryClient discoveryClient) {

return builder.routes()
.route("canary_route", r -> r
.path("/api/canary/**")
.predicate(exchange -> {
// Динамическая канареечная маршрутизация
List<ServiceInstance> instances = discoveryClient
.getInstances("product-service");

// Выбор инстансов с тегом canary
ServiceInstance canaryInstance = instances.stream()
.filter(inst -> inst.getMetadata()
.getOrDefault("canary", "false")
.equals("true"))
.findFirst()
.orElse(null);

// 10% трафика на canary
return canaryInstance != null &&
Math.random() < 0.1;
})
.uri("lb://product-service")
)
.build();
}



#Java #middle #Spring_Cloud_Gateway
👍2
Кастомный RouteDefinitionRepository

Для полностью динамической маршрутизации можно реализовать собственный RouteDefinitionRepository, который будет загружать маршруты из произвольного источника (БД, файловая система, внешний сервис).

Базовая реализация с поддержкой обновлений:

@Component
public class DatabaseRouteDefinitionRepository
implements RouteDefinitionRepository, ApplicationEventPublisherAware {

private final RouteDefinitionDAO routeDefinitionDAO;
private final Map<String, RouteDefinition> cache =
new ConcurrentHashMap<>();
private ApplicationEventPublisher publisher;

public DatabaseRouteDefinitionRepository(
RouteDefinitionDAO routeDefinitionDAO) {
this.routeDefinitionDAO = routeDefinitionDAO;
loadRoutes();
}

@Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(cache.values());
}

@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap(routeDef -> {
return routeDefinitionDAO.save(routeDef)
.doOnSuccess(saved -> {
cache.put(saved.getId(), saved);
publishRefreshEvent();
})
.then();
});
}

@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
return routeDefinitionDAO.delete(id)
.doOnSuccess(deleted -> {
cache.remove(id);
publishRefreshEvent();
})
.then();
});
}

private void loadRoutes() {
routeDefinitionDAO.findAll()
.doOnNext(routeDef -> cache.put(routeDef.getId(), routeDef))
.subscribe();
}

private void publishRefreshEvent() {
if (publisher != null) {
publisher.publishEvent(
new RefreshRoutesEvent(this)
);
}
}

@Override
public void setApplicationEventPublisher(
ApplicationEventPublisher publisher) {
this.publisher = publisher;
}

// Метод для внешних триггеров обновления
@Scheduled(fixedDelay = 30000)
public void refreshRoutes() {
loadRoutes();
publishRefreshEvent();
}
}


Реализация с поддержкой веб-интерфейса для управления маршрутами:
@RestController
@RequestMapping("/api/gateway/routes")
public class RouteManagementController {

private final RouteDefinitionWriter routeDefinitionWriter;
private final RouteDefinitionLocator routeDefinitionLocator;

@PostMapping
public Mono<ResponseEntity<Void>> createRoute(
@RequestBody RouteDefinition routeDefinition) {
return routeDefinitionWriter
.save(Mono.just(routeDefinition))
.then(Mono.just(ResponseEntity.ok().build()));
}

@GetMapping
public Flux<RouteDefinition> getAllRoutes() {
return routeDefinitionLocator.getRouteDefinitions();
}

@PutMapping("/{id}")
public Mono<ResponseEntity<Void>> updateRoute(
@PathVariable String id,
@RequestBody RouteDefinition routeDefinition) {

return routeDefinitionWriter
.delete(Mono.just(id))
.then(routeDefinitionWriter.save(Mono.just(routeDefinition)))
.then(Mono.just(ResponseEntity.ok().build()));
}

@DeleteMapping("/{id}")
public Mono<ResponseEntity<Void>> deleteRoute(@PathVariable String id) {
return routeDefinitionWriter
.delete(Mono.just(id))
.then(Mono.just(ResponseEntity.noContent().build()));
}
}


#Java #middle #Spring_Cloud_Gateway
👍2
Интеграция с внешними системами конфигурации:
@Component
public class ExternalConfigRouteDefinitionRepository
implements RouteDefinitionRepository {

private final ConfigClient configClient;
private final AtomicReference<List<RouteDefinition>> cachedRoutes =
new AtomicReference<>(Collections.emptyList());

public ExternalConfigRouteDefinitionRepository(
ConfigClient configClient) {
this.configClient = configClient;
configClient.watchRoutes()
.doOnNext(this::updateRoutes)
.subscribe();
}

@Override
public Flux<RouteDefinition> getRouteDefinitions() {
return Flux.fromIterable(cachedRoutes.get());
}

private void updateRoutes(List<RouteConfig> routeConfigs) {
List<RouteDefinition> routeDefinitions = routeConfigs.stream()
.map(this::convertToRouteDefinition)
.collect(Collectors.toList());

cachedRoutes.set(routeDefinitions);

// Генерация события обновления маршрутов
SpringApplication.publishEvent(
new RefreshRoutesEvent(this)
);
}

private RouteDefinition convertToRouteDefinition(
RouteConfig config) {
RouteDefinition definition = new RouteDefinition();
definition.setId(config.getId());
definition.setUri(URI.create(config.getUri()));

// Конвертация предикатов
config.getPredicates().forEach((name, args) -> {
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(name);
predicate.setArgs(args);
definition.getPredicates().add(predicate);
});

// Конвертация фильтров
config.getFilters().forEach((name, args) -> {
FilterDefinition filter = new FilterDefinition();
filter.setName(name);
filter.setArgs(args);
definition.getFilters().add(filter);
});

definition.setMetadata(config.getMetadata());
return definition;
}

@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
// Делегирование сохранения во внешнюю систему
return route.flatMap(routeDef ->
configClient.saveRoute(convertToRouteConfig(routeDef))
).then();
}

@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id ->
configClient.deleteRoute(id)
).then();
}
}


Обработка событий обновления маршрутов:
@Component
public class RouteUpdateListener {

private final RouteRefreshListener routeRefreshListener;

@EventListener
public void handleRefreshRoutesEvent(RefreshRoutesEvent event) {
// Логирование обновления маршрутов
logger.info("Routes refreshed by {}", event.getSource());

// Метрики
meterRegistry.counter("gateway.routes.refresh").increment();

// Уведомление подписчиков
routeRefreshListener.notifyRefresh();
}

@EventListener
public void handleApplicationEvent(ApplicationEvent event) {
if (event instanceof InstanceRegisteredEvent) {
// Обработка регистрации нового инстанса
updateRoutesForNewInstance(
((InstanceRegisteredEvent) event).getInstance()
);
}
}
}


#Java #middle #Spring_Cloud_Gateway
👍2
Что выведет код?

import java.util.LinkedList;
import java.util.Queue;

public class Task091225 {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.offer("first");
queue.offer("second");
queue.offer(null);
queue.offer("third");

System.out.println(queue.poll());
System.out.println(queue.peek());
System.out.println(queue.element());
System.out.println(queue.size());
}
}


#Tasks
👍1
Вопрос с собеседований

Что такое TLAB? 🤓


Ответ:

Thread Local Allocation Buffer
— выделенный буфер памяти для каждого потока при создании объектов.

Это уменьшает синхронизацию и ускоряет аллокации. Когда буфер заполнен, поток получает новый.

Механизм повышает производительность JVM на многопроцессорных системах.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
История IT-технологий сегодня — 10 декабря


ℹ️ Кто родился в этот день

Авгу́ста А́да Кинг (урождённая Ба́йрон), графиня Ла́влейс (англ. Augusta Ada King Byron, Countess of Lovelace; более известная как Ада Лавлейс; 10 декабря 1815, Лондон, Англия, Британская империя — 27 ноября 1852, Марилебон, Лондон, Англия, Британская империя) — исторически признана первым «программистом»: её заметки к аналитической машине Бэббиджа содержат алгоритмические идеи, опередившие своё время.

Михаэль Элад (ивр . מיכאל אלעד ; родился 10 декабря 1963 года) — израильский исследователь в обработке сигналов и компьютерном зрении; работы по разрежённым представлениям (K-SVD, super-resolution) активно применяются в современных ML/компьютерном зрении.


🌐 Знаковые события

1993 — Выходит Doom для MS-DOS.


#Biography #Birth_Date #Events #10Декабря
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
ПОДКЛЮЧЕНИЕ GPT GO на ГОД!

Всем привет! 🙃

Не знаю кому пригодится, но вот инструкция (работающая сейчас, проверено!), чтобы подключить GPT GO на год.

1. Через любой VPN подключаемся к Индии.
2. Вверху появится плашка о "специальном предложении". Переходим туда.
3. Далее выбираем GPT GO и нажимаем оформить.
4. Для оформления выбираем оплата картой. Чтобы ее найти переходим на сайт https://namso-gen.com/ и выбираем вкладку advance.
5. На этой вкладке в поле BIN вводим 551827706xxxxxxx и нажимаем Generate
6. Выбираем из предложенных любой вариант и вводим на странице оформления GPT GO. Обязательно вводим имя держателя карты (воображение поможет).
7. Далее чтобы указать адрес держателя карты переходим на сайт и снова нажимаем generate. Выбираем адрес где хотели бы жить и вводим на странице оформления GPT GO.
8. Ставим галочку о том, что будет взиматься плата и нажимаем оформить.
9. Решаем сложные капчи, подтверждаем, что вы человек, а не тварь дрожащая.
10. Пользуемся и не стесняемся ставить лайки и пересылать инструкцию друзьям и знакомым.

Всем спасибо 🤫

Рекомендую использовать новый аккаунт во избежание проблем с ним

И думаю педик Альтман не обеднеет 🖕


И подписываемся на канал ✌️
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤯1
#Mems Важная памятка 😎
🔥6👍1