🍀BitBitGo🍀 Системный Анализ
3.22K subscribers
216 photos
153 videos
112 links
Курс «Системный анализ»
https://bitbitgo.by/
Пишем про системный анализ.
Поможем стартануть в карьере IT. Присоединяйся!
Download Telegram
🔗 #INTEGRATION: КАК НЕ УТОНУТЬ В API И НЕ ПРОСПАТЬ ИЗМЕНЕНИЯ

Привет, коллеги! 👋 Интеграции — это не просто «дёрнуть API». Это управление контрактами, версиями и нагрузкой. Покажу на кейсах, как инструменты спасают проекты. 🚀

📌 КЕЙС 1: REST API — OpenAPI как контракт

CRM и биллинг ссорились из-за формата телефона. 😫

Решение: OpenAPI-спецификация с жёсткой схемой.

phone: { type: string, pattern: '^\+7\d{10}$' }


Код валидации (Pydantic):

Customer(phone="+79991234567")  # ok
Customer(phone="89991234567") # error


Вывод: OpenAPI — стандарт для REST. 📝

🔄 КЕЙС 2: АСИНХРОН — Avro + Schema Registry

Добавили поле в событие Kafka — аналитика упала. 💥

Решение: Avro-схемы с default-значениями.

{"name": "promo_code", "type": ["null", "string"], "default": null}
Schema Registry хранит версии — потребители не ломаются.


Вывод: Avro + Registry для асинхронных шин. 📦

⏱️ КЕЙС 3: RATE LIMITING

SMS-шлюз отвечал 429 в час пик, уведомления терялись. 📉

Решение: Асинхронная очередь с лимитером.

async with AsyncLimiter(100, 1):
await send_sms(phone, text) # не превысит лимит

Вывод: Rate limiting и retry policy обязательны.

ЧЕК-ЛИСТ АНАЛИТИКА:

Контракт: OpenAPI / AsyncAPI / Avro
Валидация: схемы на всех уровнях
Версионирование: политика совместимости
Ошибки: retry policy, DLQ, rate limiting
Мониторинг: метрики, алерты, логи

🎯 ИТОГ: Интеграция — это контракты, версии и защита. Закладывайте это в требования.
🧪 #TESTING: КАК АНАЛИТИКУ ЗАКЛАДЫВАТЬ КАЧЕСТВО ДО КОДА

Привет, коллеги! 👋 Аналитик не просто пишет требования — он создаёт тестируемую систему. Покажу на кейсах, как формализация помогает QA. Поехали! 🚀

📌 КЕЙС 1: ПЛОХИЕ ACCEPTANCE CRITERIA

Было: «При сумме >5000 скидка». Разработчик сделал 5%, а нужно было 10% для новых клиентов. 😱

Решение: Given-When-Then

Scenario: Постоянный клиент с суммой >5000
Given клиент постоянный (более 5 заказов)
And сумма 6000
When считаем итог
Then скидка = 600 (10%), итог = 5400


Вывод: Сценарии исключают разночтения.

📦 КЕЙС 2: JSON SCHEMA ДЛЯ КОНТРАКТОВ

Интеграция упала: телефон передали числом, а API ждал строку с +7. 💥

Решение: JSON Schema

{
"properties": {
"phone": {"type": "string", "pattern": "^\\+7\\d{10}$"}
}
}


Код проверки:

python
validate(instance=request, schema=schema) # ошибка при неверном формате
Вывод: Контракты ловят нестыковки до прода. 🛡

🛠 КЕЙС 3: ГЕНЕРАЦИЯ ТЕСТОВЫХ ДАННЫХ

Тестировщики вручную создавали заказы. Аналитик написал скрипт.

def generate_order():
total = random.choice([3000, 6000, 10000])
discount = total * 0.1 if total > 5000 else 0
return {"total": total, "discount": discount}


Вывод: Готовые данные по бизнес-правилам экономят часы. ⏱️

ЧЕК-ЛИСТ АНАЛИТИКА:

Acceptance Criteria в Given-When-Then
JSON Schema для всех интеграций
Скрипты генерации тестовых данных
Примеры запросов-ответов
Негативные сценарии

🎯 ИТОГ: Чем чётче требования — тем меньше багов в проде. Инструменты выше — must-have для аналитика.

#TESTING
🗄 #DBMS ДЛЯ СИСТЕМНОГО АНАЛИТИКА: КАК НЕ УТОНУТЬ В ДАННЫХ

Привет, коллеги! 👋 Решения аналитика на этапе проектирования определяют, будет ли система тормозить или рухнет под нагрузкой. Покажу на кейсах, как понимание БД спасает проекты. 🚀

📌 КЕЙС 1: НОРМАЛИЗАЦИЯ

Всё хранили в одной таблице заказов. Клиент сменил телефон — обновляли 1000 записей. 😱

Было (плохо):

CREATE TABLE orders (customer_name, customer_phone, product_name, ...);
Стало (хорошо):


CREATE TABLE customers (id, name, phone);
CREATE TABLE products (id, name, price);
CREATE TABLE orders (id, customer_id, date);
CREATE TABLE order_items (order_id, product_id, qty);


Вывод: Нормализация устраняет аномалии. Проектируйте структуру, а не «табличку».

📊 КЕЙС 2: ИНДЕКСЫ

Поиск клиента по email в таблице users (10 млн строк) — 30 секунд.

До:

SELECT * FROM users WHERE email = 'ivan@example.com'; -- 30 сек
После:


CREATE INDEX idx_users_email ON users(email); -- 10 мс


Вывод: Индексы на полях в WHERE обязательны. Это дёшево и эффективно.

🔒 КЕЙС 3: ТРАНЗАКЦИИ

Два менеджера одновременно забронировали последний номер в отеле. Двойная продажа! 💔

Решение: Блокировка строки.

BEGIN;
SELECT * FROM rooms WHERE id = 123 AND status = 'free' FOR UPDATE;
-- теперь никто не изменит строку
INSERT INTO bookings (room_id, customer_id) VALUES (123, 456);
COMMIT;


Вывод: Аналитик должен предусматривать конкурентный доступ и блокировки.

📈 КЕЙС 4: ВЫБОР БД

10 000 датчиков шлют показания каждую секунду. PostgreSQL раздулся и тормозит.

Решение: Time Series DB (InfluxDB).

INSERT sensors,device_id=101 temperature=22.5
SELECT MEAN(temperature) FROM sensors WHERE time > now() - 1h


Вывод: Выбирайте СУБД под задачу: реляционные, документные, временные ряды, графовые.

ЧЕК-ЛИСТ АНАЛИТИКА:

Нормализация (до 3НФ)
Индексы на частые WHERE
Транзакции и блокировки
Выбор типа СУБД под задачу

🎯 ИТОГ: База данных — сердце системы. Ошибки в проектировании на этапе анализа приводят к миллионным потерям позже. Хороший аналитик — архитектор данных.

#DBMS
🛠 #SYSTEMDESIGN: КАК ПРОЕКТИРОВАТЬ СИСТЕМЫ, КОТОРЫЕ НЕ РАЗВАЛЯТСЯ

Привет, коллеги! 👋 Проектирование — это компромиссы и предвидение. Разберём на реальных кейсах, какие решения спасают проекты, а какие — убивают. 🚀

📌 КЕЙС 1: МОНОЛИТ VS МИКРОСЕРВИСЫ

Стартап доставки, команда 5 человек, MVP за 2 месяца. Техлид хотел микросервисы — это убило бы сроки.

Решение: Модульный монолит с чёткими слоями. Запустились вовремя, через год выделили сервис доставки без переписывания.
Вывод: Для маленькой команды — модульный монолит. Микросервисы нужны для независимых команд, а не для «модности».

🔒 КЕЙС 2: ПОСЛЕДНИЙ БИЛЕТ

Два пользователя одновременно покупают последний билет — двойная продажа. Ошибка: в требованиях не учли конкурентность.

Решение: Пессимистическая блокировка SELECT FOR UPDATE. Второй пользователь ждёт и видит, что место уже занято.
Вывод: Для уникальных ресурсов (места, товары) закладывайте блокировки.

📊 КЕЙС 3: IoT-ПОТОК

10 000 датчиков в секунду. Пытались писать в PostgreSQL — БД раздулась, запросы тормозили.

Решение: Потоковая обработка (Kafka + Flink) + ClickHouse для агрегатов. Сырые данные не храним — только 5-минутные средние.
Вывод: Для временных рядов — специализированные БД (Time Series).

🚀 КЕЙС 4: КЭШИРОВАНИЕ

Интернет-магазин: страницы товаров грузились 5 секунд. DevOps хотел сервер за 2 млн руб.

Решение: Внедрили Redis. Кэш на 5 минут, нагрузка на БД упала на 95%, время загрузки — 200 мс. Сервер не купили.
Вывод: Кэширование — первое средство от высокой нагрузки на чтение.

🧩 КЕЙС 5: CQRS

Система задач: отчёты строились 5 минут, потому что читали те же таблицы, куда активно писали.

Решение: Разделили модели записи (PostgreSQL) и чтения (MongoDB). Синхронизация через события.
Вывод: При дисбалансе чтения и записи помогает CQRS.

ЧЕК-ЛИСТ АНАЛИТИКА:

Какая нагрузка (чтение/запись, пики)?
Конкурентность (что, если одновременно)?
Объём данных (рост через год)?
Допустимое время отклика?
Бюджет и команда сейчас и потом.

🎯 ИТОГ: Проектирование — это выбор компромиссов. Хороший аналитик помогает команде найти баланс между скоростью, стоимостью и масштабируемостью.

#OTHER
1👍1
🛠 #SYSTEMDESIGN: 5 РЕШЕНИЙ, КОТОРЫЕ СПАСУТ ВАШ ПРОЕКТ

Привет, коллеги! 👋 System Design — это компромиссы. Разберём 5 кейсов, где правильные решения спасли бизнес. 🚀

🔁 КЕЙС 1: RETRY + CIRCUIT BREAKER

Платёжный шлюз падал с 503. Сервис терял деньги.

Решение:

@retry(stop_max_attempt_number=3)
@circuit_breaker(failure_threshold=5)
def process_payment(data):
return gateway.charge(data)


Retry спасает от временных сбоев, Circuit Breaker — от лавины.

Вывод: Интеграции = Retry + Circuit Breaker.

📨 КЕЙС 2: АСИНХРОННОСТЬ ДЛЯ УВЕДОМЛЕНИЙ

При регистрации email и SMS тормозили 10 секунд.

Решение:

user.save()
queue.send('email', user) # асинхронно
queue.send('sms', user)
return "OK" # 200 мс
Пользователь не ждёт, сбои не ломают UX.


Вывод: Всё не критичное — в очередь.

🔢 КЕЙС 3: ВЕРСИОНИРОВАНИЕ API

Изменили формат ответа — мобильное приложение упало.

Решение:

GET /api/v1/orders  # старый формат
GET /api/v2/orders # новый формат
Старые клиенты работают, новые используют v2.


Вывод: Версионируйте API с первого дня.

📁 КЕЙС 4: ЗАГРУЗКА ФАЙЛОВ В S3

Аватарки через бэкенд убивали сервер.

Решение: Подписанные URL.

1. Бэкенд выдаёт временную ссылку на S3
2. Клиент загружает файл напрямую
3. S3 уведомляет бэкенд
Бэкенд не тратит ресурсы на файлы.


Вывод: Файлы — в облако, через подписанные URL.

⏱️ КЕЙС 5: АСИНХРОННЫЙ КОЛЛБЭК

Внешний сервис отвечал 30 секунд — пользователь ждал.

Решение:

1. Запрос → получаем request_id
2. "Ждите уведомление"
3. Webhook с результатом
Пользователь не ждёт, сервер не блокируется.


Вывод: Долгие операции — асинхронно.

ЧЕК-ЛИСТ:

Retry + Circuit Breaker для интеграций
Асинхронность для не критичного
Версионирование API
Файлы через подписанные URL
Webhook для долгих операций

🎯 ИТОГ: System Design — это умные компромиссы. Хороший аналитик помогает команде выбрать решения, которые работают сегодня и не убьют завтра.

#SYSTEMDESIGN
#SYSTEMDESIGN
👍1
📚 #OTHER: КАК АНАЛИТИК СПАС LEGACY-ПРОЕКТ БЕЗ ДОКУМЕНТАЦИИ

Привет, коллеги! 👋

В рубрике #OTHER собираем нестандартные ситуации, которые не вписываются в шаблоны, но без которых профессия аналитика немыслима. Сегодня расскажу историю про расследование в legacy-джунглях. Когда код молчит, документация сгорела, а бизнес требует новую фичу «на вчера». Поехали! 🚀

🔥 КЕЙС: НАЙТИ ИГЛУ В СТОГЕ СПАГЕТТИ-КОДА

Контекст:
Крупный логистический оператор. Система управления заказами написана в 2002 году на Delphi, база данных — Oracle 9i. Автор системы уволился в 2008-м, документация — пара мятых листов с каракулями. Бизнес-процессы за 15 лет изменились до неузнаваемости, но система работает и её надо развивать.

Задача:
Добавить новый тип доставки — «курьером до двери с примеркой». Нужно понять, как сейчас рассчитывается стоимость доставки, чтобы интегрировать новый тариф. Срок — 2 недели.

Команда в панике:

Разработчики боятся трогать код.
Тестировщики не знают, что должно быть правильно.
Бизнес давит: «Мы теряем деньги каждый день».
🕵️ МЕТОД РАБОТЫ АНАЛИТИКА-ДЕТЕКТИВА

Шаг 1. Поиск свидетелей
Оказалось, в компании ещё работает технолог, который принимал ту систему 20 лет назад. Он помнил бизнес-логику:
«Доставка по Москве считалась как вес × 15, но если суммарный вес больше 100 кг — дополнительный коэффициент 0,8. А для области — вес × 20 плюс зональный коэффициент».

📌 Вывод: 80% логики можно восстановить через живых людей. Интервью с ветеранами — золотая жила.

Шаг 2. Reverse engineering через данные
Я выгрузил из базы 50 000 завершённых заказов: входные параметры (вес, габариты, регион) и итоговую стоимость. Построил простую линейную регрессию в Python, которая предсказывала стоимость с точностью 97%. Затем проанализировал, какие признаки важны — так я вычислил скрытые коэффициенты и формулы.

Пример кода для анализа:

import pandas as pd
from sklearn.linear_model import LinearRegression

data = pd.read_sql("SELECT weight, region, distance, final_cost FROM orders", connection)
X = data[['weight', 'region', 'distance']]
y = data['final_cost']
model = LinearRegression().fit(X, y)
print(model.coef_) # выявили веса


Шаг 3. Провокация системы
На тестовом контуре я отправлял «странные» заказы: отрицательный вес, нулевая стоимость, несуществующий регион. Смотрел, какие ошибки вылетают. Иногда ошибки содержали куски кода или названия процедур — это давало зацепки. Например, ошибка «Division by zero in CalculateRegionalCoefficient» подсказала название ключевого метода.

Шаг 4. Археология кода
Не читая всё подряд, я искал маркеры: названия полей из базы, константы, числа. Нашёл блок:

if Region in [1,3,5,7] then
Coef := 1.2
else
Coef := 1.5


Сверил с бизнес-правилами — оказалось, это надбавка за «дальнее Подмосковье». Задокументировал.

РЕЗУЛЬТАТ

Через 10 дней у меня была точная спецификация алгоритма на человеческом языке. Java-разработчик написал новый микросервис за неделю, тестирование на исторических данных показало 100% совпадение. Бизнес получил новую фичу в срок.

Что важнее кода?

Умение задавать правильные вопросы.
Навыки работы с данными (SQL, Python).
Терпение и методичность.
Коммуникация с ветеранами.

🎯 ИТОГ:

Системный аналитик в мире legacy — это археолог, детектив и переводчик с машинного на человеческий. Навыки работы с «прочим» — с отсутствием документации, молчащим кодом и утерянными знаниями — отличают настоящего профессионала.

Помните: каждая непонятная строчка кода — это чьё-то бизнес-правило, за которое кто-то платил деньги. Ваша задача — вернуть этому правилу смысл.

#OTHER
3
📚 #OTHER: КАК ПРОВОДИТЬ ИНТЕРВЬЮ С ЗАКАЗЧИКОМ, ЧТОБЫ НЕ ПОЛУЧИТЬ «КОТА В МЕШКЕ»

Привет, коллеги! 👋

В рубрике #OTHER сегодня поговорим о навыке, который не выучить по учебникам, но без которого аналитик превращается в секретаря-стенографиста. Речь о проведении интервью с заказчиком. Казалось бы, что сложного: пришёл, задал вопросы, записал ответы. Но на практике именно на этом этапе рождаются (или умирают) требования. Разберём реальные кейсы и лайфхаки. Поехали! 🚀

🎭 КЕЙС 1: ИСТОРИЯ ПРО «НАМ НУЖНО КАК В СБЕР»

Ситуация:
Менеджер говорит: «Сделайте личный кабинет как в Сбербанке — удобно и современно». Команда кивает, разработчики рисуют интерфейсы, через месяц показывают — заказчик в ярости: «Это не то, у Сбера по-другому!».

Ошибка аналитика:
Не были заданы уточняющие вопросы. «Как в Сбере» — это не требование, а эмоция.

Что нужно было спросить:

Какие именно функции Сбера вам нравятся? (переводы, история, шаблоны?)
Что вы подразумеваете под «удобно»? (минимум кликов, крупные кнопки, подсказки?)
Покажите, где вы это видели, давайте вместе посмотрим.
Результат:
Совместный просмотр сайта Сбера выявил, что заказчику нравится конкретный виджет — история операций с графиками. Остальное не нужно.

Вывод:
Все абстрактные пожелания («как в...», «современный», «удобный») требуют декомпозиции до конкретных примеров.

🕵️ КЕЙС 2: МОЛЧАЛИВЫЙ ЭКСПЕРТ

Ситуация:
Интервью с главным бухгалтером. На все вопросы отвечает односложно: «да», «нет», «нормально». Время идёт, информации ноль.

Ошибка аналитика:
Не подготовился, не создал доверительную атмосферу, задавал закрытые вопросы.

Что сработало:

Начал с лёгкого: «Расскажите, как проходит ваш типичный день. С чего начинаете работу в системе?»
Переключился на открытые вопросы: «Опишите самую сложную ситуацию, с которой сталкивались при закрытии месяца».
Принёс распечатки текущих отчётов: «Покажите, где обычно возникают ошибки?»
Результат:
Разговорился, выяснили кучу нюансов, которые не были нигде задокументированы.

Вывод:
Если эксперт неразговорчив — меняйте тактику: открытые вопросы, визуальные материалы, сценарии.

📊 КЕЙС 3: ЗАКАЗЧИК-ФАНТАЗЁР

Ситуация:
Владелец продукта сыплет идеями: «А ещё сделаем чат с ИИ, и интеграцию с телеграмом, и блокчейн для лояльности…». Бюджет и сроки нереальны.

Ошибка аналитика:
Записывал всё подряд, не приоритезируя.

Что нужно было сделать:

Техника «Five Whys»: «Для чего вам блокчейн? А какая проблема решается? А что будет, если не сделаем?»
Визуализация скоупа: «Давайте отметим, что войдёт в MVP, а что — в следующие релизы».
Оценка усилий: «Эта функция потребует 3 месяца разработки. Мы можем сдвинуть дату запуска или заменить её на что-то более простое?»
Результат:
От блокчейна отказались, ИИ отложили, MVP запустили вовремя.

Вывод:
Аналитик должен фильтровать и приоритизировать, иначе проект утонет в «хотелках».

ПРАВИЛА УСПЕШНОГО ИНТЕРВЬЮ

Готовься
Изучи предметную область заранее.
Составь список вопросов, но будь готов импровизировать.
Узнай роли участников: кто принимает решения, кто эксперт, кто пользователь.
Создавай комфорт
Начинай с лёгких, нейтральных тем.
Объясни цель интервью и как его результаты помогут.
Не перебивай, дай высказаться.
Задавай правильные вопросы
Открытые: «Как вы делаете это сейчас?» вместо «Вы делаете так?».
Уточняющие: «Что значит "быстро"? 1 секунда или 10?».
Гипотетические: «Что произойдёт, если этот отчёт не сформируется вовремя?».
Используй визуализацию
Рисуй схемы прямо при нём, уточняй: «Я правильно понял, что данные идут так?».
Показывай прототипы или скриншоты похожих систем.
Фиксируй и перепроверяй
Записывай (с разрешения) на диктофон.
После встречи отправляй резюме: «Правильно ли я понял, что...».
Уточняй приоритеты: «Что из этого самое важное?».
Управляй ожиданиями
Сразу обозначай ограничения: «Это технически возможно, но займёт 2 месяца».
Не обещай того, в чём не уверен.

🎯 ИТОГ:

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

#OTHER
1
🏗 АРХИТЕКТУРА ПО ДЛЯ АНАЛИТИКА: КЕЙСЫ С КОДОМ

Привет, коллеги! 👋 Часто слышу: «Архитектура — не моё дело». Это опасное заблуждение. Аналитик закладывает архитектуру через требования. Разберём на реальных кейсах с примерами кода, почему без понимания #ARCHITECTURE проект рискует превратиться в руины. 🏚

📌 Кейс 1: Монолит vs Микросервисы

Задача: Доставка еды. Разработчик пишет монолит:

def create_order(user_id, items):
user = db.users.find_one(user_id)
if user.balance < total_cost(items): raise "Не хватает средств"
db.users.update_one(user_id, {"$inc": {"balance": -total_cost(items)}})
order_id = db.orders.insert_one({"user": user_id, "items": items})
requests.post("http://courier-system/api/assign", json={"order": order_id})
return order_id


Проблема: Если упал сервис курьеров — заказ не создаётся. Любое изменение в уведомлениях ломает заказ.

Что должен был заложить аналитик: Асинхронное событие через брокер.

def create_order(user_id, items):
with db.transaction():
# проверка и списание
user = db.users.find_one(user_id)
if user.balance < total_cost(items): raise
db.users.update_one(user_id, {"$inc": {"balance": -total_cost(items)}})
order_id = db.orders.insert_one({"user": user_id, "items": items})
kafka.produce("order_created", {"order_id": order_id}) # событие
return order_id


Требование: «Критичные операции синхронны, остальные — асинхронны через брокер». Это развязывает сервисы и повышает отказоустойчивость.

📌 Кейс 2: Нагрузка и кэширование

Задача: Банковский личный кабинет. Аналитик забыл спросить про нагрузку. Разработчик пишет:

public AccountInfo getAccount(String userId) {
return jdbc.query("SELECT * FROM accounts WHERE user_id = ?", userId);
}


Реальность: 10 000 запросов в секунду кладут БД. Баланс открывается 10 секунд.

Правильное требование: «Время отклика < 1 секунды при 10 000 RPS». Решение — кэш:

public AccountInfo getAccount(String userId) {
AccountInfo cached = redis.get("account:" + userId);
if (cached != null) return cached;
AccountInfo fromDb = jdbc.query(...);
redis.setex("account:" + userId, 60, fromDb); // TTL 60 сек
return fromDb;
}


Вывод: NFR диктуют архитектуру.

📌 Кейс 3: Синхронный вызов, который всё тормозит

Задача: Онлайн-кинотеатр — при старте фильма обновить рекомендации.

Плохо (всё синхронно):

def start_movie(user_id, movie_id):
check_subscription(user_id)
deduct_credit(user_id)
recommendations.update(user_id, movie_id) # тормозит — пользователь ждёт
return "ok"


Хорошо (асинхронно):

def start_movie(user_id, movie_id):
check_subscription(user_id)
deduct_credit(user_id)
kafka.produce("movie_started", {"user": user_id, "movie": movie_id}) # не ждём
return "ok"

Требование: «Некритичные интеграции — асинхронны с гарантированной доставкой».

📌 Кейс 4: Забыли про GDPR

Задача: FinTech для Европы. Аналитик не учёл требования. Хранят логи вечно:

CREATE TABLE access_logs (user_id INT, accessed_at TIMESTAMP, ip VARCHAR(45));
Штраф: €20 млн за нарушение GDPR.


Правильные требования:

Логи хранятся 90 дней, затем удаляются.
IP хранить в хэшированном виде.
По запросу пользователя — полное удаление.
Реализация TTL:

db.logs.insert_one({
"user_id": user_id,
"ip_hash": hashlib.sha256(ip.encode()).hexdigest(),
"expire_at": datetime.utcnow() + timedelta(days=90)
})
db.logs.create_index("expire_at", expireAfterSeconds=0) # автоудаление


Запомните: Аналитик не обязан писать код, но обязан понимать последствия своих требований. Примеры выше — не для копирования, а для понимания, как архитектура влияет на бизнес. 💡

#ARCHITECHTURE
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Необходимые компетенции менеджера в IT
😁2
🔍 ТЕСТИРОВАНИЕ ДЛЯ СИСТЕМНОГО АНАЛИТИКА: НЕ ПРОСТО СДАЛ И ЗАБЫЛ

Привет, коллеги! 👋 Хороший аналитик активно участвует в тестировании — он лучше всех знает, как система должна работать. Разберём на примерах с кодом, как это помогает.

📌 Зачем аналитику тестирование?

Валидация требований
Поиск неучтённых сценариев
Экономия времени (баг на ранней стадии дешевле)

📌 Виды тестирования, где аналитик незаменим

🔹 Приёмочное тестирование (UAT)

Готовим сценарии и проверяем бизнес-требования.

Пример: Оформление заказа с промокодом. Проверяем не только успех, но и:

Промокод истёк
Не применим к товару
Введён с маленькой буквы

🔹 Интеграционное тестирование

Аналитик описывает все возможные ответы внешнего сервиса.

Код (Python):

import requests, time
def test_payment_retry():
response = requests.post("https://payment-gateway/api/pay", json={"order_id": 123})
if response.status_code == 429: # Too Many Requests
time.sleep(5) # повтор через 5 сек
response = requests.post(...)
assert response.status_code == 200
else:
assert response.status_code == 200


Кейс: Внешний сервис возвращал 500 при временной ошибке. Разработчик обработал как фатальную. Аналитик настоял на ретраях — баг нашли на стенде, не на проде.

🔹 Регрессионное тестирование

Автоматизируем ключевые бизнес-сценарии.

Код (проверка баланса):

def test_balance_after_purchase():
user_id = 123
initial = get_balance(user_id)
purchase(user_id, 300)
new_balance = get_balance(user_id)
assert new_balance == initial - 300


📌 Кейс: «Баг, который нашёл аналитик»

Ситуация: В ТЗ: «При изменении email уведомление на старый и новый адреса». Разработчик сделал только на новый. Тестировщики не заметили — в тест-кейсах не было уточнения.

Что сделал аналитик? Написал приёмочный тест с проверкой двух адресов и провалил приёмку. Баг исправили до проде.

Мораль: Критерии приёмки должны быть конкретными, а аналитик — участвовать в проверке.

📌 Как аналитик может писать автотесты?

Проверять API в Postman
Писать простые скрипты на Python
Формулировать Gherkin-сценарии для Cucumber
Пример Gherkin:

Feature: Оформление заказа
Scenario: Успешное оформление с промокодом
Given пользователь авторизован
And в корзине товар на 1000 рублей
And у пользователя есть промокод на скидку 10%
When пользователь применяет промокод
Then сумма заказа уменьшается на 10%
And заказ успешно оформлен


🎯 ИТОГ: ЧТО ДЕЛАТЬ АНАЛИТИКУ?

Участвовать в планировании тестирования
Писать приёмочные тесты
Проверять демо перед показом заказчику
Автоматизировать рутину простыми скриптами
Анализировать баги на проде — они показывают слабые места в требованиях

Помните: Качественный анализ + участие в тестировании = надёжный продукт. Аналитик, который проверяет результат, стоит дороже любого документа. 💰

#TESTING
🔍 ТЕСТИРОВАНИЕ ДЛЯ АНАЛИТИКА: КОД, КЕЙСЫ, ИНСАЙТЫ

Привет, коллеги! 👋 Хороший аналитик не просто пишет требования, но и участвует в тестировании. Почему? Потому что именно вы знаете, как система должна работать на самом деле. Сегодня покажу на реальных кейсах с примерами кода, как аналитик может помочь QA и разработке находить баги до продакшена. 🚀

📌 Кейс 1: Интеграция и ретраи (код на Python)

Ситуация: Платежный шлюз иногда возвращает 503 (сервис временно недоступен). В требованиях написано: «При ошибке повторить запрос». Разработчик сделал один повтор через 1 секунду.

Что сделал аналитик: Написал простой скрипт, который показал, что 1 секунда — слишком мало, сервис не успевает восстановиться.

```python
import requests
import time

def test_payment_retry():
url = "https://payment-gateway/api/pay"
payload = {"order_id": 123, "amount": 1000}

for attempt in range(3):
response = requests.post(url, json=payload)
if response.status_code == 503:
wait_time = 2 ** attempt # 1, 2, 4 секунды
print(f"Попытка {attempt+1} не удалась, ждём {wait_time}с")
time.sleep(wait_time)
else:
assert response.status_code == 200
print("Успех!")
return
assert False, "Все попытки исчерпаны"


Результат: Баг нашли на тестовом стенде. В ТЗ добавили экспоненциальную задержку (1, 2, 4 сек) и 3 попытки. 🎯

📌 Кейс 2: Граничные значения (тестируем форму)

Ситуация: В форме заказа есть поле «Количество товаров» от 1 до 999. Разработчик сделал валидацию, но пропустил ноль и отрицательные числа.

Что сделал аналитик: Написал параметризованный тест на Python с библиотекой pytest:

import pytest

def validate_quantity(q):
return 1 <= q <= 999

@pytest.mark.parametrize("input,expected", [
(0, False), # граница снизу
(1, True), # минимальное допустимое
(500, True), # среднее значение
(999, True), # максимальное допустимое
(1000, False), # граница сверху
(-5, False), # отрицательное
("abc", False) # не число
])
def test_quantity_validation(input, expected):
assert validate_quantity(input) == expected


Результат: Тест показал, что 0 и отрицательные числа пропускаются. Разработчик исправил валидацию до выкладки.

📌 Кейс 3: Регрессия (автотест на проверку баланса)

Ситуация: Добавили новую фичу — скидки постоянным клиентам. Нужно убедиться, что старый функционал (списание баланса) не сломался.

Что сделал аналитик: Простой скрипт для smoke-теста:

def test_balance_after_purchase():
# Данные тестового пользователя
user_id = 999
initial_balance = get_balance(user_id) # предположим, 1000

# Покупаем товар за 300
purchase(user_id, 300)

# Проверяем новый баланс
new_balance = get_balance(user_id)
expected = initial_balance - 300

assert new_balance == expected, f"Ожидалось {expected}, получено {new_balance}"
print("Баланс обновился корректно")


Результат: Запускаем перед каждым релизом — спим спокойно. 😴

📌 Инструменты для аналитика

Postman — коллекции с автотестами для API (проверка статусов, схем ответа).
Python + requests — быстрые скрипты для сложных сценариев.
pytest — параметризация, фикстуры, отчёты.
Gherkin (Cucumber) — сценарии на понятном бизнесу языке:

Feature: Бонусы за регистрацию
Scenario: Новый пользователь получает 500 бонусов
Given пользователь не зарегистрирован
When он регистрируется с телефоном "+79991234567"
Then его бонусный счёт равен 500


🎯 ИТОГ: ЧТО ДЕЛАТЬ АНАЛИТИКУ?

Писать проверяемые требования — с цифрами, диапазонами, примерами.
Готовить тестовые сценарии — включая негативные и граничные.
Автоматизировать рутину — простые скрипты экономят часы ручных проверок.
Участвовать в код-ревью тестов — подсказывать QA, какие кейсы важны.
Помните: Баг, найденный на этапе анализа или тестирования, стоит в 10 раз дешевле, чем на проде. Аналитик с навыками тестирования — золото для команды. 💰

#TESTING
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
📊 SQL ДЛЯ СИСТЕМНОГО АНАЛИТИКА: НЕ ПРОСТО ЗАПРОСЫ, А СУПЕРСИЛА

Привет, коллеги! 👋 Часто слышу: «SQL — это для разработчиков и DBA». На самом деле, SQL — один из главных инструментов аналитика. С его помощью вы можете:

проверять данные, не дожидаясь отчётов;
находить баги быстрее, чем разработчики;
отвечать на вопросы бизнеса за 5 минут.
Сегодня покажу на реальных кейсах, как SQL спасает проекты. 🚀

📌 Кейс 1: «Где мои бонусы?» (проверка гипотезы)

Менеджер жалуется: «Клиенты не получают бонусы за регистрацию!». Разработчики говорят: «Всё работает, проверяли». Вы решаете проверить сами.

Пишете запрос в базу:

SELECT 
DATE(created_at) as reg_date,
COUNT(user_id) as total_users,
COUNT(bonus_id) as users_with_bonus,
ROUND(COUNT(bonus_id) * 100.0 / COUNT(user_id), 2) as percent
FROM users
LEFT JOIN bonuses ON users.user_id = bonuses.user_id
WHERE created_at >= '2024-10-01'
GROUP BY reg_date
ORDER BY reg_date;

Результат: бонусы получают только 30% пользователей, хотя должны все. Баг найден за 2 минуты — разработчик ошибся в условии начисления. Вы сэкономили день споров.

📌 Кейс 2: «Аномалия в продажах» (обнаружение бага)

Бизнес заметил: вчера продажи упали на 20%. Начинается паника. Вы идёте в базу и смотрите динамику по часам:

SELECT 
DATE_TRUNC('hour', order_time) as hour,
COUNT(order_id) as orders,
SUM(amount) as revenue
FROM orders
WHERE order_time >= CURRENT_DATE - INTERVAL '2 days'
GROUP BY hour
ORDER BY hour;

Обнаруживаете, что провал пришёлся на 14:00–15:00 — именно в это время выкатывали новую версию. Дальше — запрос по конкретному виду товаров:

SELECT 
product_category,
COUNT(order_id) as orders
FROM orders
WHERE order_time BETWEEN '2024-10-15 14:00' AND '2024-10-15 15:00'
GROUP BY product_category;

Выясняется: пропали заказы из категории «Электроника». Оказывается, разработчики задефили изменения в прайсе для этой категории. Без SQL вы бы искали проблему часами. ⏱️

📌 Кейс 3: «Тестовые данные для приёмки» (помощь тестировщикам)

QA нужно проверить сценарий «пользователь с 10 заказами». Вы пишете запрос, который выгружает подходящих пользователей:

SELECT 
user_id,
COUNT(order_id) as order_count,
SUM(amount) as total_spent
FROM orders
GROUP BY user_id
HAVING COUNT(order_id) >= 10
ORDER BY order_count DESC
LIMIT 20;

Тестировщики получают готовый список реальных пользователей (или их id) и могут быстро проверить сценарий. Никакого ручного подбора данных. 🧪

📌 Кейс 4: «Массовое обновление» (подготовка данных)

Нужно проставить признак «VIP» всем клиентам, у которых сумма покупок > 1 млн. Вместо ручного обновления пишете запрос:

UPDATE customers
SET is_vip = TRUE
WHERE customer_id IN (
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 1000000
);

10 секунд — и задача решена. Безопасно, быстро, без ошибок. 🔥

🎯 ЧТО ДАЁТ SQL АНАЛИТИКУ?

Независимость — вы не ждёте отчёты от разработчиков.
Скорость — ответы на вопросы бизнеса за минуты.
Глубина — можете проверить данные на любом уровне детализации.
Доверие — ваши выводы подкреплены фактами, а не догадками.
📚 С ЧЕГО НАЧАТЬ?

Освойте SELECT, WHERE, GROUP BY, JOIN — этого хватит для 80% задач.
Изучите оконные функции (ROW_NUMBER(), LAG()) — они выводят анализ на новый уровень.
Практикуйтесь на учебных базах или в своём проекте (с доступом только на чтение!).

Помните: SQL — это не просто язык запросов, а ваш главный помощник в расследованиях. Чем лучше вы им владеете, тем больше инсайтов можете дать команде. 💪

#SQL
Please open Telegram to view this post
VIEW IN TELEGRAM
📊 SQL ДЛЯ АНАЛИТИКА: ОКОННЫЕ ФУНКЦИИ — СЛЕДУЮЩИЙ УРОВЕНЬ

Привет, коллеги! 👋 Вы уже знаете SELECT, JOIN и GROUP BY. Но есть вещь, которая выводит анализ на новый уровень — оконные функции. Они позволяют считать скользящие средние, приросты, доли и ранги без сложных подзапросов. Сегодня разберём на реальных задачах. Поехали! 🚀

📌 Кейс 1: Сравнение продаж с прошлым месяцем (LAG)

Менеджер просит: «Покажи помесячную динамику и прирост к прошлому месяцу». Без оконных функций пришлось бы делать self-join или подзапрос. А так:

SELECT 
DATE_TRUNC('month', order_date) as month,
SUM(amount) as revenue,
LAG(SUM(amount)) OVER (ORDER BY DATE_TRUNC('month', order_date)) as prev_revenue,
(SUM(amount) - LAG(SUM(amount)) OVER (ORDER BY DATE_TRUNC('month', order_date))) /
LAG(SUM(amount)) OVER (ORDER BY DATE_TRUNC('month', order_date)) * 100 as growth_percent
FROM orders
GROUP BY month
ORDER BY month;

Что получим: месячная выручка, прошлая выручка и процент роста. Всё одним запросом! 🔥

📌 Кейс 2: Топ-3 товара в каждой категории (ROW_NUMBER)

Нужно для каждой категории выделить три самых продаваемых товара. Раньше — муть с подзапросами. Теперь:

WITH ranked_products AS (
SELECT
category_id,
product_id,
SUM(quantity) as total_sold,
ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY SUM(quantity) DESC) as rn
FROM order_items
GROUP BY category_id, product_id
)
SELECT category_id, product_id, total_sold
FROM ranked_products
WHERE rn <= 3;

Результат: аккуратный топ по каждой категории. А если нужны все товары с повторами (если продажи одинаковые) — используйте RANK() или DENSE_RANK(). 🏆

📌 Кейс 3: Скользящее среднее за 7 дней (AVG OVER)

Для отчёта по трендам нужно сгладить дневные скачки. Скользящее среднее — идеально:

SELECT 
date,
revenue,
AVG(revenue) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) as avg_7d
FROM daily_revenue
ORDER BY date;

Теперь видно тенденцию без шума. Маркетологи будут благодарны! 📈

📌 Кейс 4: Доля товара в общей выручке (SUM OVER)

ABC-анализ: надо понять, какие товары дают 80% выручки. Считаем долю накопленным итогом:

WITH product_revenue AS (
SELECT
product_id,
SUM(amount) as revenue,
SUM(SUM(amount)) OVER () as total_revenue
FROM sales
GROUP BY product_id
)
SELECT
product_id,
revenue,
revenue / total_revenue * 100 as percent,
SUM(revenue / total_revenue * 100) OVER (ORDER BY revenue DESC) as cumulative_percent
FROM product_revenue
ORDER BY revenue DESC;

Видим, где граница 80%. Классика для категорийных менеджеров. 📦

🎯 ПОЧЕМУ ЭТО ВАЖНО ДЛЯ АНАЛИТИКА?

Скорость: один запрос вместо трёх.
Гибкость: можно комбинировать с группировками и фильтрами.
Точность: меньше шансов ошибиться в логике.

Освойте оконные функции — и бизнес будет носить вас на руках за быстрые и точные ответы. 💪

#SQL
90% каналов про AI и ИТ бесполезны

Одни пересказывают новости.
Другие копируют посты друг у друга.

В итоге человек читает десятки каналов, но новых идей почти не появляется.

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

Поэтому мы собрали подборку сильных каналов про ит и искусственный интеллект. Внутри авторы, которые разбирают: новые AI-инструменты, технологии и продукты, стартапы, реальные кейсы использования нейросетей, вайб-кодинг и др. Это экономит время. Не нужно искать хорошие каналы по одному

Ссылка для добавления➡️ https://t.me/addlist/3WsuUGbOgm8xYTAy

Давайте поддержим каналы, чтобы качественного контента стало больше!
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Media is too big
VIEW IN TELEGRAM
Экспертиза тех специалиста IT
😁5
📜 ТРЕБОВАНИЯ, КОТОРЫЕ РАБОТАЮТ: КАК КОД ПОМОГАЕТ АНАЛИТИКУ

Привет, коллеги! 👋 Слышали фразу: «Требования должны быть однозначными»? Легко сказать, сложно сделать. Сегодня покажу, как код (да, код!) помогает аналитику проверять и уточнять требования до передачи разработчикам. Реальные кейсы внутри. 🧑‍💻

📌 Кейс 1: «Скидка при заказе от 1000 рублей»

Бизнес-аналитик записал: «Если сумма заказа превышает 1000 рублей, применяется скидка 10%». Разработчик реализовал, тестировщик проверил — всё ок. Но на проде клиенты жалуются: скидка не применяется, когда сумма ровно 1000.

В чём проблема? Слово «превышает» можно трактовать как «больше» (>1000) или «больше или равно» (>=1000)? Аналитик не уточнил.

Что сделал бы проактивный аналитик? Написал бы простой тест на Python ещё до разработки:

def test_discount():
assert apply_discount(1000) == 1000 # 0% или 10%?
assert apply_discount(1001) == 900.9 # должно быть 10%
assert apply_discount(500) == 500 # без скидки

Или даже на бизнес-языке (Gherkin):

Feature: Скидка на заказ
Scenario: Сумма ровно 1000
Given сумма заказа 1000 рублей
When рассчитывается скидка
Then скидка не применяется (0%) # или применяется? Надо решить!

Этот тест сразу подсветит неоднозначность. Спор решается на этапе анализа, а не на проде. 🔥

📌 Кейс 2: «Пароль должен содержать спецсимволы»

Требование: «Пароль должен содержать хотя бы один спецсимвол». Разработчик написал проверку: if any(c in "!@#$%" for c in password). Тестировщик проверил пароль "pass!" — работает. Через месяц выясняется, что клиенты из Германии не могут ввести "ß", потому что это не спецсимвол, а буква. Или спецсимволы типа "©" не считаются.

Как аналитик мог предотвратить это? Уточнить: «спецсимволы — это символы из набора ASCII: !"#$%&'()*+,-./:;<=>?@[]^_{|}~`». Или ещё лучше — сразу дать регулярное выражение в требованиях:

[!@#$%^&*(),.?":{}|<>]

Но и это не всё. Аналитик может написать параметризованный тест, который проверяет граничные случаи:

import pytest

def validate_password(password):
# минимальная проверка для примера
return any(c in "!@#$%^&*" for c in password)

@pytest.mark.parametrize("pwd,expected", [
("pass!", True), # содержит !
("pass", False), # нет спецсимвола
("pass©", False), # © не в наборе
("pass#", True), # содержит #
])
def test_special_char(pwd, expected):
assert validate_password(pwd) == expected

Тест "pass©" провалится, и аналитик поймёт: нужно либо расширить набор, либо уточнить у бизнеса, считать ли «©» спецсимволом. 🎯

📌 Кейс 3: «Акция действует с 1 по 31 октября»

Бизнес сказал: «Акция на товары категории "Электроника" с 1 по 31 октября». Разработчик жёстко закодил даты. 1 ноября акция закончилась, но менеджер просит продлить до 5 ноября. Начинается аврал.

Что должен был сделать аналитик? Сформулировать требование как параметризованное, а не жёсткое. И показать пример кода, как это должно быть реализовано:

# Плохо
if date >= "2025-10-01" and date <= "2025-10-31":
apply_discount()

# Хорошо — параметры в конфиге или БД
promo = get_promo("october_electronics")
if promo.is_active(date):
apply_discount()

И тест, проверяющий, что даты можно менять без изменения кода:

def test_promo_flexible():
set_promo_dates("2025-10-01", "2025-10-31")
assert is_promo_active("2025-10-15") == True
assert is_promo_active("2025-11-01") == False
set_promo_dates("2025-10-01", "2025-11-05")
assert is_promo_active("2025-11-01") == True

Теперь гибкость заложена в требования. 🚀

🎯 ЧТО ДАЁТ АНАЛИТИКУ ТАКОЙ ПОДХОД?

Экономия времени на переделках.
Повышение доверия команды — требования превращаются в исполняемые спецификации.
Автоматическая регрессия — тесты остаются и проверяют, что требования не нарушены.

Совет: Дружить с разработчиками и просить их показывать код тестов. А лучше — писать простые тесты самим (хотя бы в виде псевдокода). Это поднимает качество требований на новый уровень. 📈

#REQUIREMENTS
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Когда решил помочь коллегам, но вовремя осознал, на кого повесят задачу
🙈4