惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
T
Tor Project blog
U
Unit 42
G
Google Developers Blog
T
The Blog of Author Tim Ferriss
Recorded Future
Recorded Future
B
Blog
I
InfoQ
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
aimingoo的专栏
aimingoo的专栏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
小众软件
小众软件
Spread Privacy
Spread Privacy
T
Tenable Blog
C
Cybersecurity and Infrastructure Security Agency CISA
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
I
Intezer
P
Proofpoint News Feed
A
About on SuperTechFans
S
Securelist
D
DataBreaches.Net
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
Know Your Adversary
Know Your Adversary
大猫的无限游戏
大猫的无限游戏
Cyberwarzone
Cyberwarzone
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
MyScale Blog
MyScale Blog
V
Visual Studio Blog
A
Arctic Wolf
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
博客园 - 司徒正美
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
B
Blog RSS Feed
Vercel News
Vercel News
T
Threatpost
博客园 - Franky
有赞技术团队
有赞技术团队
爱范儿
爱范儿
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 热门话题

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Файл вырос до 800 строк и это была моя вина…
k8r4a7n2fg23 · 2026-05-11 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение6 мин

Охват и читатели266

Мнение

На каждом ревью найдётся кто‑то, кто спросит «Зачем четыре файла, если это один пайплайн?»

А затем, давайте объясню!


Как это происходит

Очевидно, что никто не садится и не пишет processor.py на 900 строк намеренно.

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

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


Почему лимит вообще работает

Популярный аргумент звучит так: «большие файлы труднее читать, потому что рабочая память ограничена» — с отсылкой к Миллеру (1956) и Коуэну (2001). Это правда, но прямой экстраполяции нет: Миллер изучал запоминание случайных слогов, не чтение кода в IDE с навигацией по символам.

Реальная проблема — не в скролле. Она в неопределённости.

Когда открываешь permissions.py — область понятна из имени. Когда открываешь service.py на 800 строк с четырьмя разными ответственностями — сначала нужно восстановить карту файла в голове, и только потом трогать. Этот overhead не катастрофичен сам по себе, но он накапливается каждый раз, когда ты заходишь в файл.

Есть и эмпирика: Jay et al. (2009) проверили более 1,2 млн файлов из SourceForge и обнаружили линейную зависимость между LOC и цикломатической сложностью — устойчивую к языку и парадигме. Большой файл с высокой вероятностью сложный, независимо от аккуратности написания. Правда, Landman et al. (2016) эту корреляцию оспаривают — на Java и C результаты слабее. Данные неоднозначны. Но как первая метрика, которая дёшево считается и достаточно часто срабатывает — LOC работает.


Мои цифры — и почему они разные

Важный момент, который обычно упускают: я не использую одно число для всего кода. Разные типы файлов — разные лимиты.

Функция — 80 строк. Если не помещается в экран без скролла, скорее всего делает больше одного дела. 80 строк — это точка, где я останавливаюсь и спрашиваю: это действительно одна задача?

Handler / pipeline — 350 строк. Хендлер принимает событие, валидирует данные, передаёт дальше. Всё. Бизнес‑логики здесь нет. 350 строк — это около 10–12 хендлеров с валидацией. Больше — возможно, логика уже поехала не туда.

Processor / service — 450 строк. Здесь живёт реальная логика. 450 — точка, после которой мне становится тяжелее держать в голове внутренние зависимости класса без постоянного возврата наверх. Если перерастает — почти всегда это два смешанных контракта, а не просто «много кода».

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


Пример 1 — FSM‑хендлер, который вырос органически

Задача: пошаговый мастер подачи заявки в боте (aiogram 3 + FSMContext). Девять шагов с ветками, отмена на любом этапе, inline‑клавиатуры на каждый переход.

До:

bot/
├── handlers/
│   ├── hr_request/
│   │   ├── __init__.py         # регистрация router
│   │   └── wizard.py           # ~800 строк за полгода выросло из 200:
│   │                           # добавлялись ветки флоу, keyboards рядом с хендлерами,
│   │                           # валидация там же - ведь "один флоу, незачем дробить"
│   └── admin.py
├── services/
│   └── ticket_service.py       # 310 строк
└── db/
    └── repository.py           # ~490 строк: один TicketRepository, CRUD + аналитические JOIN
                                # добавлялись методы по запросам

~800 строк в wizard.py — не хаос. Логика прослеживается, имена понятны. Проблема появляется, когда клавиатура на шаге 6 рендерит не то и нужно найти конкретный InlineKeyboardMarkup среди всего потока переходов. А правка клавиатуры рядом с логикой перехода — это риск задеть соседний код, который ты в этот момент вообще не читаешь.

Часто возникает вопрос: почему не два класса в одном файле? Потому что StepsHandler и WizardKeyboards меняются по разным причинам — первый при изменении бизнес‑логики, второй при изменениях UI.

В одном файле это смешивается в git diff: правка кнопки выглядит как правка флоу.

В разных файлах граница видна сразу — и в diff, и при импорте.

После:

bot/
├── handlers/
│   ├── hr_request/
│   │   ├── __init__.py
│   │   ├── states.py           # 25 строк  - StatesGroup
│   │   ├── steps.py            # 310 строк - только переходы
│   │   ├── keyboards.py        # 195 строк - клавиатуры по шагам
│   │   └── validators.py       # 120 строк - input валидация
│   └── admin.py
├── services/
│   └── ticket_service.py       # 310 строк
└── db/
    ├── ticket_repo.py          # 280 строк - CRUD + простые выборки
    └── ticket_queries.py       # 230 строк - агрегаты, JOIN, аналитика

Суммарный LOC немного вырос — за счёт импортов и init.py, но цель не в этом, цель — предсказуемая граница изменений: клавиатура шага 6 это keyboards.py на 195 строк, а не поиск по 800.

Репозиторий разбился по той же логике: CRUD‑методы и аналитические запросы меняются по разным поводам и теперьticket_queries.py трогаешь при новых отчётах, ticket_repo.py — при изменениях схемы. Разная частота, разные причины.

aiogram 3.x добавил Scene‑классы как осознанную альтернативу — весь флоу в одном изолированном классе. Валидный подход. Но если внутри сцены начинают жить генераторы клавиатур и валидационная логика — она вырастет точно так же.


Пример 2 — Maya‑процессор по типам ассетов

Начинали с mesh. Потом пришли rig, animation, fx — у каждого своя логика нормализации имён и валидации LOD.

До:

tools/
└── maya_asset_tool/
    ├── ui/
    │   └── main_window.py          # 290 строк
    ├── core/
    │   └── asset_processor.py      # ~680 строк: BaseProcessor + MeshProcessor + RigProcessor + AnimProcessor
    │                               # тут казалось логичным держать все процессоры вместе
    └── integrations/
        ├── perforce.py             # 170 строк
        └── maya_api.py             # 200 строк

Четыре хорошо написанных класса. Проблема в тестах: from core.asset_processor import RigProcessor тянет весь модуль — включая Maya‑зависимости MeshProcessor, которых в тестовой среде нет. Мокаешь то, что к тесту вообще не относится.

После:

tools/
└── maya_asset_tool/
    ├── ui/
    │   └── main_window.py          # 290 строк
    ├── core/
    │   ├── base_processor.py       # 110 строк
    │   ├── mesh_processor.py       # 185 строк
    │   ├── rig_processor.py        # 170 строк
    │   ├── anim_processor.py       # 150 строк
    │   └── validators.py           # 125 строк
    └── integrations/
        ├── perforce.py             # 170 строк
        └── maya_api.py             # 200 строк

from core.rig_processor import RigProcessor — только то, что нужно.

Пришёл VFX — создаёшь vfx_processor.py, остальные не трогаешь.

Граница изменений стала явной.


Когда большой файл нормален

Тексты и шаблоны. Файл на 900 строк из констант или строк, сгруппированных по классам, читается совершенно иначе. Нет зависимостей между блоками, нет сайд‑эффектов. Открыл, нашёл нужный класс, поправил.

Репозиторий на 500+ строк — нормально, если все методы независимы, каждый не длиннее ~50 строк, никакой бизнес‑логики. Например, get_by_id() ничего не знает про get_with_analytics() (у сервисного слоя зависимостей между методами больше, поэтому и порог ниже).

Scene в aiogram 3x — осознанное архитектурное решение фреймворка, а не исключение из правил.


Как это контролировать

Лимиты работают только если их не нужно помнить. Мы с коллегой ввели простую проверку в CI: скрипт считает непустые строки в файлах по суффиксу имени и возвращает варнинги, если файл перевалил за лимит своего типа. Не как строгий запрет, а чтобы сделать превышение видимым.

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


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

Не универсальный рецепт. Просто то, что работает у меня уже несколько лет.


А у Вас есть формальные ограничения в команде, или держитесь на договорённостях?