Войти в Y_LAB | IT развитие и юмор
Open in Telegram
Стажировки, вакансии, полезные материалы, развлекательный контент. Y_LAB — команда опытных IT-специалистов, которая готова помочь вам войти в мир технологий! Сотрудничество (ylab v it) @tamriko1_5
Show more749
Subscribers
No data24 hours
+17 days
-930 days
Posts Archive
Новый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “System Design: архитектура, компромиссы и AI-driven разработка”.
О чем видео?
В новом выпуске подкаста вместе с ведущим Павлом и специальным приглашённым гостем Павлом Востриковым обсуждаем системный дизайн, архитектурные компромиссы и влияние AI на разработку. Поговорим о микрофронтах и масштабировании, роли frontend-разработчиков, over-engineering, архитектурных конфликтах и ошибках, а также о том, как меняются инженерные практики и роли разработчиков в эпоху AI-агентов.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
Новый пост Y_LAB_Learning! | Масштабирование БД в Java: Replication и Eventual Consistency
📊📱 БД, Java
О чем статья?
Как репликация помогает масштабировать базы данных и распределять нагрузку между Primary и Replica. Разбираемся с replication lag, Eventual Consistency и тем, какие нюансы это создаёт для приложения и Java-разработчика.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем разбирать реальные инженерные ловушки, которые легко не заметить в обычной разработке.
Сегодня под микроскопом — клиентские таймеры во фронтенде ⌛️
useEffect(() => {
const interval = setInterval(() => {
fetch("/api/notifications");
}, 5000);
return () => clearInterval(interval);
}, []);
Каждые 5 секунд запрашиваем уведомления…
❗️ Но
здесь есть несколько нюансов.
🎯 1. Не забываем очищать таймер
Если написать так:
useEffect(() => {
setInterval(() => {
fetch("/api/notifications");
}, 5000);
}, []);
и компонент смонтируется несколько раз, старые таймеры продолжат работать.
В результате:
1 монтирование → 1 запрос / 5 сек
3 монтирования → 3 запроса / 5 сек
Поэтому setInterval нужно очищать при размонтировании.
🎯 2. 5 секунд — это не точный интервал
5000 в setInterval не означает, что callback выполнится ровно через 5 секунд.
После истечения этого времени задача становится готовой к выполнению и попадает в очередь задач. Но когда именно она будет выполнена, зависит от работы event loop: если call stack занят, callback будет ждать.
💜 И даже при свободном stack браузер может ограничивать таймеры, например, в неактивных вкладках.
Поэтому setInterval не гарантирует выполнение callback через заданный период.
🎯 3. Запросы могут накладываться
Допустим, API отвечает 8 секунд:
0 сек → запрос №1
5 сек → запрос №2
8 сек → ответ №1
10 сек → запрос №3
В итоге несколько запросов выполняются одновременно.
Поэтому при polling стоит учитывать не только заданный интервал, но и время выполнения самого запроса.
🖍️🖍️🖍️
Используя таймер на фронтенде, спросите себя:
Где он выполняется? Когда уничтожается? Что произойдёт, если вкладка станет неактивной?А если таймер запускает запросы:
Что будет, если предыдущий запрос ещё не завершился?#Y_LAB_University #Y_LAB_Actual
Новый пост Y_LAB_Learning! | От API до отказоустойчивости: разбираемся с System Design на Python
📱 Python
О чем статья?
Как Python-разработчику подходить к проектированию высоконагруженных систем: от сбора требований и оценки нагрузки до масштабирования, кэширования, асинхронности и отказоустойчивости.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины проблем, которые не всегда очевидны на первый взгляд.
Сегодня под микроскопом — equals() и hashCode() в Java 📱
👨💻 Представим класс пользователя:
class User {
private final String email;
public User(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof User)) return false;
User other = (User) obj;
return email.equals(other.email);
}
}
Здесь email объявлен как final. Для объектов, которые используются как ключи в hash-based коллекциях, неизменяемые поля, участвующие в equals() и hashCode(), значительно облегчают жизнь.
Иначе можно получить ещё одну неприятную ситуацию: объект уже добавлен в HashSet, но его поле, влияющее на хэш, изменилось, и коллекция больше не сможет найти его по новому или старому значению.
➡️ А теперь попробуем использовать User в HashSet:
Set<User> users = new HashSet<>();
users.add(new User("user@example.com"));
System.out.println(
users.contains(new User("user@example.com"))
);
Что выведет программа?
true?Потому что у обоих объектов одинаковый email, а equals() считает их равными.
Но на самом деле результат будет
false🤔 Почему так происходит?
HashSet использует не только equals(), но и hashCode().Сначала коллекция определяет, в какую область поиска должен попасть объект, используя его хэш. И только после этого при необходимости сравнивает объекты через equals(). А мы переопределили equals(), но не переопределили hashCode(). Поэтому два объекта:
new User("user@example.com")
new User("user@example.com")
считаются равными через equals(), но могут иметь разные хэш-коды. В результате HashSet ищет второй объект не там, где находится первый.
🔧 Как исправить?
Если переопределяем equals(), необходимо согласованно переопределить и hashCode():
@Override
public int hashCode() {
return email.hashCode();
}
Теперь объекты с одинаковым email будут иметь одинаковый хэш-код, и HashSet сможет корректно их находить.
🎯🎯🎯
Такая ошибка особенно коварна:
• Компилятор не ругается;
• Приложение не падает;
• equals() работает именно так, как мы ожидаем;
• Проблема проявляется только при использовании хэш-коллекций.
И внезапно оказывается, что:
set.contains(user)
возвращает false, хотя объект с такими же данными в Set уже есть.
⬇️⬇️⬇️
Если объект должен использоваться в HashSet, HashMap или других структурах на основе хэширования, всегда проверяйте контракт между equals() и hashCode():
↔️ Если два объекта равны через equals(), их hashCode() должен быть одинаковым.
❗️ Но обратное утверждение неверно: если у двух объектов одинаковый hashCode(), это ещё не означает, что они равны через equals().
Одинаковый хэш может быть у разных объектов — это называется коллизией.
А встречались с ситуацией, когда объект «есть» в коллекции, но contains() почему-то говорит обратное? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “От вайб-кодинга до Enterprise: как ИИ меняет разработку. Часть 2”.
О чем видео?
Во второй части выпуска вместе с ведущим Максимом и Python-разработчиком Александром продолжаем разбираться, как ИИ-агенты меняют разработку. Обсуждаем, как джунам расти в профессии, если базовый код всё чаще пишет ИИ, разбираем типичные сценарии сбоев и проблемы надёжности агентов, а также выясняем, могут ли они обходить установленные ограничения. В финале подводим итоги и отвечаем на главный вопрос: ИИ-агенты — угроза для разработчиков или новый инструмент, который меняет профессию?
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
Новый пост Y_LAB_Learning! | Клиент-серверная архитектура и микросервисы: в чем разница и как они работают вместе
🧑💻 Основы и старт в IT
О чем статья?
Чем отличается клиент-серверная архитектура от микросервисной и почему это не взаимоисключающие подходы. Монолит, микросервисы, взаимодействие сервисов, работа с данными, масштабирование.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины проблем, которые не всегда очевидны на первый взгляд.
Сегодня под микроскопом — секреты в Docker 🐳
Представим, что разработчику нужно передать API-ключ приложению:
FROM python:3.12
ENV API_KEY="super-secret-key"
COPY . .
CMD ["python", "app.py"]
↔️ приложение получает ключ;
↔️ контейнер запускается;
↔️ секрет не нужно хранить отдельно от проекта.
❗️ Но в таком подходе есть серьёзная проблема.
Секрет оказывается внутри Docker-образа.
А образ — это не просто один файл с приложением. Docker хранит историю его слоёв, и информация, которая попала в один из них, может остаться доступной даже после того, как строку удалили из Dockerfile.
То есть разработчик может сделать:
ENV API_KEY="super-secret-key"
а потом заменить это на:
ENV API_KEY=""
и пересобрать образ.
Но это ещё не означает, что старый ключ исчез из истории.
❓ Как сделать безопаснее ❓
Секреты лучше передавать во время запуска контейнера или использовать специальные механизмы управления секретами.
Например:
docker run \
-e API_KEY="$API_KEY" \
my-app
Теперь ключ не нужно записывать непосредственно в Dockerfile.
А в более крупных системах для хранения секретов используют специальные инструменты: secret management в Kubernetes, Docker Secrets, Vault и облачные менеджеры секретов.
🎯🎯🎯
Docker-образ может попасть:
• в container registry;
• на CI/CD-сервер;
• на сервер разработчика;
• к другому члену команды.
Если внутри образа оказался настоящий API-ключ, пароль или токен, это уже не просто технический долг. Это потенциальный инцидент безопасности.
И даже если секрет быстро удалить из текущей версии кода, он может продолжать существовать в старых слоях, образах или истории сборок.
А доводилось находить API-ключи или пароли прямо в Docker-образах, Git-репозиториях или CI/CD? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “От вайб-кодинга до Enterprise: как ИИ меняет разработку”.
О чем видео?
В новом выпуске подкаста вместе с ведущим Максимом и Python-разработчиком Александром разбираемся, что такое ИИ-агенты и как они уже меняют процесс разработки. Это первая часть выпуска: говорим о вайб-кодинге, реальной продуктивности ИИ, его эффективности в пет-проектах и Enterprise и о том, действительно ли нейросеть может оказаться дешевле разработчика.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
Новый пост Y_LAB_Learning! | CORS, CSRF и Spring Security: что происходит с HTTP-запросом
💬 Java, Frontend
О чем статья?
Задачи CORS и CSRF. Как они работают, что происходит с запросом между frontend и Java backend. Как правильно настраивать защиту в Spring Security.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины проблем, которые не всегда очевидны на первый взгляд.
Сегодня под микроскопом — 🤨 React и повторные запросы
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const options = {
headers: {
Authorization: "Bearer token"
}
};
useEffect(() => {
fetch(`/api/users/${userId}`, options)
.then(response => response.json())
.then(setUser);
}, [userId, options]);
return <div>{user?.name}</div>;
}
Почему при обычном рендере компонента API может начать получать множество одинаковых запросов?🎯 useEffect зависит от userId; 🎯 запрос выполняется при изменении пользователя; 🎯 после получения данных вызывается setUser. 💜Но есть одна проблема:
const options = {
headers: {
Authorization: "Bearer token"
}
};
Этот объект создаётся заново при каждом рендере компонента.
А useEffect следит за ним:
[userId, options]
React сравнивает зависимости по ссылке.
Поэтому для него:
options → старый объект
options → новый объект
— это разные значения, даже если содержимое объектов полностью одинаковое.
🤔 Что происходит дальше?
Компонент рендерится -> Создаётся новый options -> useEffect отправляет запрос -> При получении ответа вызывается setUser -> Компонент снова рендерится -> Создаётся новый options -> React считает зависимость изменившейся -> useEffect снова отправляет запрос
И так запросы могут начать повторяться снова и снова.
🛠 Как исправить?
Если объект действительно не меняется, его можно вынести за пределы компонента:
const options = {
headers: {
Authorization: "Bearer token"
}
};
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`, options)
.then(response => response.json())
.then(setUser);
}, [userId]);
return <div>{user?.name}</div>;
}
Но иногда проблема решается не внутри самого компонента. Можно вынести работу с API в отдельный слой. Например, компонент отвечает только за отображение данных, а запросы находятся в отдельном сервисе:
Component
↓
API layer
↓
Backend
📌 Ещё один вариант — использовать библиотеку для работы с серверными данными. Например, TanStack Query или RTK Query. Они позволяют вынести запросы и управление их состоянием за пределы компонентов, а также предоставляют кэширование, дедупликацию запросов и другие механизмы для работы с серверными данными. В результате компоненту не обязательно самостоятельно решать, когда отправить запрос, где хранить результат и нужно ли повторно загружать те же данные.
⬇️⬇️⬇️
Один лишний запрос кажется мелочью. Но если такой компонент находится на странице, которая активно обновляется, или подобных компонентов десятки, количество запросов может быстро вырасти.
В итоге можно получить:
🎯 Лишнюю нагрузку на API;
🎯 Замедление интерфейса;
🎯 Превышение rate limit;
🎯 Неожиданные 429 Too Many Requests;
🎯 Лишние расходы на инфраструктуру.
И проблему не всегда получится обнаружить просто открыв Network DevTools. Если запрос выполняется на сервере (например, при SSR или в Server Components), его вообще может не быть среди сетевых запросов браузера. Поэтому при подозрении на лишние обращения к API стоит смотреть не только на frontend, но и на логи, метрики и трассировку запросов.
А замечали когда-нибудь, что один компонент способен породить десятки одинаковых запросов? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “System Design: как проектировать высоконагруженные системы на Python”.
О чем видео?
В новом выпуске подкаста вместе с ведущим Павлом и Python-разработчиком Данилом разбираемся, как проектировать высоконагруженные системы на Python и какие архитектурные решения помогают приложениям оставаться стабильными даже при резком росте нагрузки. Обсудим, действительно ли Python медленный, как работают GIL, асинхронность и масштабирование, какие метрики важно отслеживать, а также поговорим о роли ИИ в современной разработке.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
