Войти в Y_LAB | IT развитие и юмор
Kanalga Telegram’da o‘tish
Стажировки, вакансии, полезные материалы, развлекательный контент. Y_LAB — команда опытных IT-специалистов, которая готова помочь вам войти в мир технологий! Сотрудничество (ylab v it) @tamriko1_5
Ko'proq ko'rsatish765
Obunachilar
Ma'lumot yo'q24 soatlar
-27 kunlar
-830 kunlar
Postlar arxiv
Новый пост Y_LAB_Learning! | Управление состоянием с MobX: от первых observable до крупных проектов
🔵 Frontend
О чем статья?
Принципы работы MobX, его основные возможности, преимущества и ограничения. Как библиотека упрощает управление состоянием и помогает строить масштабируемые React-приложения.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины проблем, которые появляются не во время разработки, а уже в продакшене.
Сегодня под микроскопом — пул соединений с базой данных (Connection Pool) 🗄
// python
from sqlalchemy import create_engine
engine = create_engine(DB_URL)
connection = engine.connect()
# Работа с базой данных
return
Вопрос:
Почему приложение может внезапно перестать работать с базой данных, хотя сама база полностью исправна?На первый взгляд код выглядит вполне обычным: ↔️ получили соединение ↔️ выполнили запрос ↔️ закончили работу Но есть одна проблема...
Соединение с базой данных никогда не возвращается обратно в пул.💰 Что происходит дальше? Каждый новый запрос получает ещё одно соединение: // text
Запрос №1 → получил соединение
Запрос №2 → получил соединение
Запрос №3 → получил соединение
...
Пока однажды пул не закончится.
После этого новые запросы начинают ждать свободное соединение, а затем приложение может начать выдавать ошибки вроде:
// text
QueuePool limit reached
или
// text
TimeoutError: QueuePool limit reached
При этом сама база данных продолжает работать.
Проблема в приложении.
🛠 Как исправить?
После завершения работы соединение необходимо закрыть:
// python
from sqlalchemy import create_engine
engine = create_engine(DB_URL)
with engine.connect() as connection:
# Работа с базой данных
pass
Контекстный менеджер (with) автоматически вернёт соединение обратно в пул, даже если во время выполнения кода возникнет исключение.
➡️ Если не использовать with, соединение нужно закрывать вручную:
// python
connection.close()
Важно понимать, что при использовании пула данный вызов не закрывает соединение с базой физически, а лишь возвращает его обратно в пул, чтобы его мог использовать следующий запрос.
🌟🌟🌟
Такие ошибки редко проявляются во время разработки.
Локально одновременно работает один пользователь, поэтому свободных соединений почти всегда хватает.
Но после выхода в продакшен десятки или сотни параллельных запросов постепенно "разбирают" весь пул.
И спустя некоторое время приложение перестаёт работать с базой, хотя причина скрывается всего в одной пропущенной строке или отсутствии контекстного менеджера with.
💡💡💡
Если приложение начинает жаловаться на нехватку соединений, не спешите увеличивать размер пула.
Сначала убедитесь, что соединения действительно возвращаются обратно. Очень часто проблема не в количестве соединений, а в том, что часть из них никогда не освобождается.
Приходилось когда-нибудь искать утечку соединений с базой? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “Классы и метаклассы в Python”.
О чем видео?
В данном видео вместе с нашим Python-разработчиком Лерой разберемся, как устроены классы и объекты в Python, зачем нужны магические методы, наследование и перегрузка операторов, а также выясним, почему класс сам является объектом. Постепенно перейдем к метаклассам, разберем принцип их работы, посмотрим реальные примеры использования в Django и Pydantic и поймем, в каких случаях этот мощный инструмент действительно стоит применять.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
Новый пост Y_LAB_Learning! | Тестирование мобильных приложений: реальные задачи, с которыми сталкивается QA
🪲 QA
О чем статья?
Чем мобильное тестирование отличается от WEB, с какими особенностями сталкивается Manual QA и почему проверка приложения не ограничивается интерфейсом.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины проблем, с которыми разработчики сталкиваются в продакшене.
Сегодня под микроскопом — производительность базы данных 🔧
// sql
SELECT *
FROM orders
WHERE user_id = 15482;
Вопрос:
Почему такой простой запрос может выполняться несколько секунд, а иногда и десятки секунд?Казалось бы ↔️ Выбираем данные из одной таблицы; ↔️ Фильтруем по одному полю. Но всё зависит не только от самого запроса, а ещё и от того, как устроена таблица. ⬇️⬇️⬇️ Представим, что в таблице orders хранится 20 миллионов записей. Если для поля
user_id нет индекса, то база данных будет вынуждена проверить практически каждую строку таблицы, чтобы найти нужные записи.
🔎 Такой способ поиска называется полным сканированием таблицы (Sequential Scan).
Чем больше данных, тем дольше будет выполняться запрос.
🔩 Как исправить?
Если поиск по полю выполняется регулярно, имеет смысл создать индекс:
// sql
CREATE INDEX idx_orders_user_id
ON orders(user_id);
Теперь вместо последовательного просмотра миллионов строк база сможет быстро найти нужные записи по индексу.
❗️ Но есть важный нюанс.
Кажется, что индексы — универсальное решение. Но на самом деле каждый индекс:
• Занимает дополнительное место на диске;
• Замедляет операции INSERT, UPDATE и DELETE, потому что его тоже нужно обновлять.
Поэтому создавать индексы "на всякий случай" — не лучшая идея. Хороший индекс — это тот, который действительно ускоряет часто выполняемые запросы.
💬💬💬
На небольших таблицах проблема может быть незаметна.
Но когда количество данных начинает исчисляться миллионами записей, отсутствие одного индекса способно увеличить время ответа API с десятков миллисекунд до нескольких секунд.
Приходилось когда-нибудь искать причину медленного запроса, а потом обнаруживать, что проблема была всего лишь в отсутствии индекса? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB_Learning! | Почему одного UI уже недостаточно: современный взгляд на WEB-тестирование
🪲 QA
О чем статья?
Как устроено современное WEB-тестирование и почему ручному тестировщику уже недостаточно проверять только интерфейс. Связь UI и API, роль DevTools.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные инженерные ситуации и ищем причины ошибок, которые не всегда лежат на поверхности.
Сегодня под микроскопом — HTTP 429 🔍
// python
import requests
for user_id in users:
requests.post(
"https://api.example.com/send",
json={"userId": user_id}
)
На тестовом стенде всё работает отлично.
Но после выхода в прод часть запросов внезапно начинает возвращать:
// http
429 Too Many Requests
Почему так происходит?На первый взгляд кажется, что проблема в самом API. Но чаще всего причина совсем в другом: превышен лимит запросов (Rate Limit). 🚨 Многие сервисы ограничивают количество обращений за определённый промежуток времени, чтобы защититься от перегрузки. Например, API может разрешать: 🎯 Не более 100 запросов в минуту; 🎯 Не более 10 запросов в секунду; 🎯 Или ограничивать число запросов для одного пользователя или IP-адреса. Если приложение отправляет запросы слишком быстро, сервер начинает отвечать: // http
429 Too Many Requests
❓ Как правильно обработать такую ситуацию?
Первая мысль — просто повторить запрос:
// python
while True:
response = requests.post(...)
if response.status_code == 429:
continue
Но это только усугубит проблему. 😭
Пока сервер ограничивает обращения, приложение продолжит отправлять новые запросы, создавая ещё большую нагрузку.
🔧 Что делать вместо этого?
Обычно используют один или сразу несколько подходов:
🎯 Читают заголовок Retry-After, если сервер его возвращает, и повторяют запрос только через указанное время;
🎯 Добавляют экспоненциальную задержку (Exponential Backoff), увеличивая интервал между повторными попытками;
🎯 Ограничивают количество одновременно отправляемых запросов на стороне клиента.
💜💜💜
Код может быть полностью корректным и отлично работать во время разработки.
Но в продакшене пользователей становится в сотни раз больше, и ограничения API начинают проявляться именно под нагрузкой.
Поэтому ошибка 429 чаще говорит не о проблеме сервера, а о том, что приложению пора научиться «общаться» с ним аккуратнее.
А вам приходилось бороться с ограничениями Rate Limit? Какой способ обработки оказался самым эффективным? 👀
#Y_LAB_University #Y_LAB_ActualНовый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “Хочу стать Junior QA”.
О чем видео?
В этом видео разберем Roadmap Junior QA: кто такой QA Engineer, какие hard и soft skills необходимы начинающему тестировщику, какие инструменты используются в работе и что нужно изучить для успешного старта в профессии. Также поговорим о возможных направлениях развития и карьерном росте в тестировании.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
Новый пост Y_LAB_Learning! | Тестирование в Python: от юнит-тестов до TDD и monkey patching
📱 Python
О чем статья?
Чем отличаются юнит- и интеграционные тесты, что такое TDD, когда использовать mocking и monkey patching.
📎 Читать статью
#Y_LAB_University #Y_LAB_Learning
Новый пост Y_LAB Actual | Код под микроскопом 🔍
Продолжаем рубрику, в которой разбираем реальные ситуации из разработки и ищем неочевидные причины ошибок.
Сегодня под микроскопом — многопоточность в Java 📱
class Counter {
private int value = 0;
public void increment() {
value++;
}
public int getValue() {
return value;
}
}
Представим, что метод increment() одновременно вызывают 100 потоков по 1000 раз каждый.
❓ Вопрос:
Какое значение в итоге вернёт:
counter.getValue();
Кажется, ответ очевиден:
100000
Но на практике результат может быть совершенно другим.
🤓 Например:
98341
99612
99987
И каждый запуск программы может давать новое значение.
🤔 Почему так происходит?
Операция:
value++;
только выглядит как одно действие.
На самом деле она состоит сразу из трёх шагов:
🎯1. прочитать текущее значение;
🎯2. увеличить его на единицу;
🎯3. записать обратно.
Если два потока одновременно прочитают одно и то же значение, оба увеличат его и оба запишут результат. Один из инкрементов просто потеряется.
Кроме того, в многопоточных приложениях может возникнуть ещё одна проблема — видимость изменений между потоками. Из-за оптимизаций процессора и JVM один поток может некоторое время работать с устаревшим значением переменной.
Для решения именно этой задачи в Java существует ключевое слово volatile. Оно гарантирует, что потоки будут видеть актуальное значение переменной.
Однако в нашем примере volatile не решит проблему полностью. Операция value++ всё равно состоит из чтения, увеличения и записи, поэтому инкременты могут теряться.
↔️ Например:
Поток A читает 5
Поток B читает 5
Поток A записывает 6
Поток B записывает 6
Хотя ожидалось уже значение 7.
🔗 Как исправить?
Для счётчиков в многопоточной среде обычно используют AtomicInteger:
java AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
или синхронизацию (synchronized), если требуется защитить более сложную логику.
📢📢📢
Такие ошибки одни из самых неприятных.
Программа не падает.
Компилятор не выдаёт ошибок.
Тесты могут проходить десятки раз подряд.
А проблема проявится только под нагрузкой, когда приложение окажется в реальной эксплуатации.
Сталкивались когда-нибудь с багами, которые появлялись только при большом количестве одновременных запросов? 👀
#Y_LAB_University #Y_LAB_ActualНе беспокоить... машина учится 🧑🏫
#Y_LAB_University #Y_LAB_Memes
Новый пост Y_LAB Videos! | Свежее видео
Всем привет! Рады сообщить, что на наших ютуб-канале и вк-сообществе вышел новый видеоролик “Java 21-25: что реально изменилось между двумя LTS-релизами”.
О чем видео?
В данном видео вместе с нашим Java-разработчиком Иваном разбираемся, чем Java 25 отличается от Java 21 и какие изменения действительно важны для production-разработки. Обсудим, как эволюционировали виртуальные потоки, FFM API, JVM, сборщики мусора и средства диагностики, а также почему переход на Java 25 — это не только новые возможности, но и более зрелая, стабильная платформа для современных приложений.
📱 YouTube
———
📱 VK
#Y_LAB_University #Y_LAB_YouTube #Y_LAB_VK
