Media is too big
VIEW IN TELEGRAM
🎙 Запись второго выпуска нашего Подкаста IT-тоLк уже доступна!
💡 В этом выпуске наш системный аналитик Олег и мобильный разработчик Андрей делятся личным опытом как войти в IT , с чего начать и как выбрать направление, где и как учиться и как получить первую стажировку и работу, поделятся практическими советами и лайфхаками для новичков.
Найти Подкаст можно тут 👉 https://clck.ru/3Lv5x6
💡 В этом выпуске наш системный аналитик Олег и мобильный разработчик Андрей делятся личным опытом как войти в IT , с чего начать и как выбрать направление, где и как учиться и как получить первую стажировку и работу, поделятся практическими советами и лайфхаками для новичков.
Найти Подкаст можно тут 👉 https://clck.ru/3Lv5x6
🔥6❤1
🖐🏻Привет всем! Приглашаем на наш вебинар "Методы планирования – как успевать больше без стресса", который будет полезен для всех!
Мы поделимся проверенными методами планирования, которые помогут вам организовать свое время и увеличить продуктивность!
🔑 Что узнаете на вебинаре?
• Как метод «Съешь лягушку» поможет вам справиться с самыми сложными задачами.
• Правило 1-3-5, как правильно расставлять приоритеты.
• Timeboxing и метод Pomodoro для эффективного управления временем.
🚀 Вы научитесь избегать основных ошибок в планировании:
• Переоценка своих сил
• Отсутствие приоритетов
• Прокрастинация и «пожиратели времени»
📅 29 мая
🕒 18:30 (Мск)
👩🏻🦱 Виктория Павлюкова- системный аналитик
🔗 Регистрация на вебинар
Мы поделимся проверенными методами планирования, которые помогут вам организовать свое время и увеличить продуктивность!
🔑 Что узнаете на вебинаре?
• Как метод «Съешь лягушку» поможет вам справиться с самыми сложными задачами.
• Правило 1-3-5, как правильно расставлять приоритеты.
• Timeboxing и метод Pomodoro для эффективного управления временем.
🚀 Вы научитесь избегать основных ошибок в планировании:
• Переоценка своих сил
• Отсутствие приоритетов
• Прокрастинация и «пожиратели времени»
📅 29 мая
🕒 18:30 (Мск)
👩🏻🦱 Виктория Павлюкова- системный аналитик
🔗 Регистрация на вебинар
🔥5❤2
Бета-релиз Laravel-плагина для VS Code
Команда Laravel представила официальное расширение для Visual Studio Code, и в его описании есть любопытная деталь:
> This extension will occasionally boot your app in the background to collect information about your app for use in autocompletion, linking, hovering, and diagnostics
Расширение периодически запускает Laravel-приложение в фоновом режиме, чтобы глубже понять проект и улучшить автокомплит, навигацию, подсказки и диагностику.
Традиционные инструменты, такие как PhpStorm, Laravel Idea и другие IDE, полагаются на статический анализ, который не всегда справляется с «магией» PHP. Например, плагин MetaStorm требует явно описывать динамику и конвенции в специальном синтаксисе.
Может ли runtime-анализ (динамический запуск приложения) помочь редактору лучше понять код по сравнению со статическим подходом? Интуитивно — да!
Мы считаем, что динамический анализ, в теории, имеет огромный потенциал. Особенно для сложных проектов, где статический анализ не всегда дает точную картину. Но, как это бывает с большинством новых технологий, важно подождать, пока плагин выйдет из бета-версии, станет более стабильным и легким в настройке. В идеале, если бы плагин интегрировал динамический и статический подходы, это было бы отличным решением для улучшения работы с Laravel-проектами.
А как считаете вы?
Поэтому следим за его развитием и ждем стабильного релиза, прежде чем интегрировать его в повседневную разработку.
🔗 Подробнее на Marketplace
#evapps_news
Команда Laravel представила официальное расширение для Visual Studio Code, и в его описании есть любопытная деталь:
> This extension will occasionally boot your app in the background to collect information about your app for use in autocompletion, linking, hovering, and diagnostics
Расширение периодически запускает Laravel-приложение в фоновом режиме, чтобы глубже понять проект и улучшить автокомплит, навигацию, подсказки и диагностику.
Традиционные инструменты, такие как PhpStorm, Laravel Idea и другие IDE, полагаются на статический анализ, который не всегда справляется с «магией» PHP. Например, плагин MetaStorm требует явно описывать динамику и конвенции в специальном синтаксисе.
Может ли runtime-анализ (динамический запуск приложения) помочь редактору лучше понять код по сравнению со статическим подходом? Интуитивно — да!
Мы считаем, что динамический анализ, в теории, имеет огромный потенциал. Особенно для сложных проектов, где статический анализ не всегда дает точную картину. Но, как это бывает с большинством новых технологий, важно подождать, пока плагин выйдет из бета-версии, станет более стабильным и легким в настройке. В идеале, если бы плагин интегрировал динамический и статический подходы, это было бы отличным решением для улучшения работы с Laravel-проектами.
А как считаете вы?
Поэтому следим за его развитием и ждем стабильного релиза, прежде чем интегрировать его в повседневную разработку.
🔗 Подробнее на Marketplace
#evapps_news
🔥4
🙌🏻Привет! На связи Юра, разработчик компании EvApps. На днях прочитал книгу Роберта Мартина "Идеальная работа" (или "Чистое мастерство") — пятую в серии "Чистое программирование".
Вот несколько важных моментов, которые точно стоит учесть:
📚 Мастерство: В будущем программисты не смогут просто списывать свои ошибки на неопытность. Бизнес и общество будут требовать от нас качественного кода, и работать в этой индустрии будут только настоящие мастера.
🧪 TDD и тестирование: TDD (разработка через тестирование) — это основа. Мартин подробно рассказывает, как с помощью тестов и маленьких итераций можно писать реально рабочий код. Тесты здесь — это почти как документация, только лучше.
🔄 Рефакторинг: Рефакторинг — это не просто улучшение кода, а его улучшение без изменения поведения. Мартин советует быть смелым: не бойтесь переименовывать переменные и делать код понятным. Если код не читается как книга, это уже проблема.
🎨Дизайн и принципы: Не нужно делать лишнего. Следите, чтобы код был тестируемым и минимизируйте дублирование. Мартин советует придерживаться принципа YAGNI (You Aren’t Gonna Need It) — не добавляйте то, что вам не нужно.
👥Совместное программирование: Работать в паре — круто. Это помогает улучшать качество кода, особенно если оба разработчика опытные и готовы учиться друг у друга.
⚖️Этика программиста: Не забывайте про свою ответственность за код. Если вы не берете ответственность за возможные ошибки в программе, значит, вы не профессионал. Важно всегда быть честным и не бояться признаться, что что-то не знаете.
📈Качество и производительность: Качество — это не что-то, что можно достичь за один раз. Оно требует постоянного улучшения, а производительность должна быть стабильной. Не забывайте учиться и не стесняйтесь просить помощи, когда нужно.
📖 Советую прочесть всем, кто хочет расти как профессионал! А если уже читали — давайте обсудим в комментах. 👇
#evapps_польза
Вот несколько важных моментов, которые точно стоит учесть:
📚 Мастерство: В будущем программисты не смогут просто списывать свои ошибки на неопытность. Бизнес и общество будут требовать от нас качественного кода, и работать в этой индустрии будут только настоящие мастера.
🧪 TDD и тестирование: TDD (разработка через тестирование) — это основа. Мартин подробно рассказывает, как с помощью тестов и маленьких итераций можно писать реально рабочий код. Тесты здесь — это почти как документация, только лучше.
🔄 Рефакторинг: Рефакторинг — это не просто улучшение кода, а его улучшение без изменения поведения. Мартин советует быть смелым: не бойтесь переименовывать переменные и делать код понятным. Если код не читается как книга, это уже проблема.
🎨Дизайн и принципы: Не нужно делать лишнего. Следите, чтобы код был тестируемым и минимизируйте дублирование. Мартин советует придерживаться принципа YAGNI (You Aren’t Gonna Need It) — не добавляйте то, что вам не нужно.
👥Совместное программирование: Работать в паре — круто. Это помогает улучшать качество кода, особенно если оба разработчика опытные и готовы учиться друг у друга.
⚖️Этика программиста: Не забывайте про свою ответственность за код. Если вы не берете ответственность за возможные ошибки в программе, значит, вы не профессионал. Важно всегда быть честным и не бояться признаться, что что-то не знаете.
📈Качество и производительность: Качество — это не что-то, что можно достичь за один раз. Оно требует постоянного улучшения, а производительность должна быть стабильной. Не забывайте учиться и не стесняйтесь просить помощи, когда нужно.
📖 Советую прочесть всем, кто хочет расти как профессионал! А если уже читали — давайте обсудим в комментах. 👇
#evapps_польза
🔥8👍1
😊Привет, я Таня Драбовская, PHP-разработчик Evapps. Сегодня поговорим про технические аспекты кастомизации и масштабирования платформы Nextcloud!
🚀 Nextcloud представляет собой модульную клиент-серверную платформу, ориентированную на развёртывание приватных облачных решений.
Базовая функциональность включает:
- файловое хранилище,
- контроль доступа,
- веб-интерфейс,
- систему авторизации.
Архитектура построена на PHP с использованием собственного App Framework. Фронтенд реализован на Vue.js .
Серверная часть поддерживает интеграцию с MariaDB, PostgreSQL , Redis , S3-хранилищами, внешними файловыми системами и кеширующими решениями (OPcache, file-based cache).
Платформа поддерживает гибкую кастомизацию за счёт API, системы событий и разработки собственных модулей.
☝️Рассмотрим два основных кейса:
1️. Автоматическая сортировка файлов на основе MIME-типов
В рамках проекта была реализована логика автоматической сортировки загружаемых файлов на основе MIME-типов. Решение оформлено в виде отдельного приложения, использующего хук postWrite файловой подсистемы. При загрузке файл классифицируется и перемещается в предопределённую директорию (/Documents , /Images , /Videos ). UI-часть реализована на Vue.js ; конфигурация осуществляется через API и административную панель.
2️. Оптимизация полнотекстового поиска с использованием Elasticsearch
Для повышения удобства работы с хранилищами большого объёма был внедрён механизм полнотекстового поиска на базе Elasticsearch.
🔎 Ключевые технологии полнотекстового поиска:
• fulltextsearch — модуль Nextcloud, управляющий процессами индексации и поиска;
• fulltextsearch_elasticsearch — компонент для интеграции с Elasticsearch;
• Elasticsearch — внешний высокопроизводительный поисковый движок.
⚠️Проблемы стандартной реализации, с которыми мы столкнулись при работе:
• продолжительное время индексации при больших объёмах файлов (сотни тысяч документов)
• высокая нагрузка на центральный процессор сервера
• потенциальная деградация производительности и доступности сервиса для конечных пользователей
🛠Для минимизации задержек и снижения деградации производительности мы провели оптимизацию:
✔️ Распараллелили процесс индексации:
• внедрили асинхронный HTTP-клиент для отправки данных в Elasticsearch
• реализовали пакетную отправку данных (batch-запросы) по 500–1000 документов
• добавили обработку ошибок и механизм повторных попыток (retry)
✔️ Оптимизировали взаимодействие с базой данных Nextcloud:
• перешли с одиночных SQL-запросов на bulk INSERT
• использовали постоянные соединения к базе данных (persistent connections)
✔️ Донастроили Elasticsearch:
• отключили неиспользуемые в индексе поля для уменьшения объёма
• применили ngram-анализатор для ускоренного поиска коротких фрагментов текста
🎯 Комплексная оптимизация процессов индексации и поиска в Nextcloud позволила существенно повысить эффективность работы системы и снизить нагрузку на серверные ресурсы. Это обеспечило стабильную производительность при масштабной эксплуатации.
Готова ответить на ваши вопросы! 😊
🚀 Nextcloud представляет собой модульную клиент-серверную платформу, ориентированную на развёртывание приватных облачных решений.
Базовая функциональность включает:
- файловое хранилище,
- контроль доступа,
- веб-интерфейс,
- систему авторизации.
Архитектура построена на PHP с использованием собственного App Framework. Фронтенд реализован на Vue.js .
Серверная часть поддерживает интеграцию с MariaDB, PostgreSQL , Redis , S3-хранилищами, внешними файловыми системами и кеширующими решениями (OPcache, file-based cache).
Платформа поддерживает гибкую кастомизацию за счёт API, системы событий и разработки собственных модулей.
☝️Рассмотрим два основных кейса:
1️. Автоматическая сортировка файлов на основе MIME-типов
В рамках проекта была реализована логика автоматической сортировки загружаемых файлов на основе MIME-типов. Решение оформлено в виде отдельного приложения, использующего хук postWrite файловой подсистемы. При загрузке файл классифицируется и перемещается в предопределённую директорию (/Documents , /Images , /Videos ). UI-часть реализована на Vue.js ; конфигурация осуществляется через API и административную панель.
2️. Оптимизация полнотекстового поиска с использованием Elasticsearch
Для повышения удобства работы с хранилищами большого объёма был внедрён механизм полнотекстового поиска на базе Elasticsearch.
🔎 Ключевые технологии полнотекстового поиска:
• fulltextsearch — модуль Nextcloud, управляющий процессами индексации и поиска;
• fulltextsearch_elasticsearch — компонент для интеграции с Elasticsearch;
• Elasticsearch — внешний высокопроизводительный поисковый движок.
⚠️Проблемы стандартной реализации, с которыми мы столкнулись при работе:
• продолжительное время индексации при больших объёмах файлов (сотни тысяч документов)
• высокая нагрузка на центральный процессор сервера
• потенциальная деградация производительности и доступности сервиса для конечных пользователей
🛠Для минимизации задержек и снижения деградации производительности мы провели оптимизацию:
✔️ Распараллелили процесс индексации:
• внедрили асинхронный HTTP-клиент для отправки данных в Elasticsearch
• реализовали пакетную отправку данных (batch-запросы) по 500–1000 документов
• добавили обработку ошибок и механизм повторных попыток (retry)
✔️ Оптимизировали взаимодействие с базой данных Nextcloud:
• перешли с одиночных SQL-запросов на bulk INSERT
• использовали постоянные соединения к базе данных (persistent connections)
✔️ Донастроили Elasticsearch:
• отключили неиспользуемые в индексе поля для уменьшения объёма
• применили ngram-анализатор для ускоренного поиска коротких фрагментов текста
🎯 Комплексная оптимизация процессов индексации и поиска в Nextcloud позволила существенно повысить эффективность работы системы и снизить нагрузку на серверные ресурсы. Это обеспечило стабильную производительность при масштабной эксплуатации.
Готова ответить на ваши вопросы! 😊
❤4🔥4
Готов третий эпизод нашего подкаста - на этот раз обсудили "боли" рекрутеров, "художества" в резюме и отличие "мясных" резюме от тех, которые сочинил ChatGPT, с нашим руководителем отдела по работе с персоналом Александрой Радиной 💪
👀 Смотрим в нашем сообществе в ВК: https://vk.com/video-78780379_456239279
👀 Смотрим в нашем сообществе в ВК: https://vk.com/video-78780379_456239279
VK Видео
IT ТОLК by Evapps. Рекрутинг в IT: ложь, боль и искусственный интеллект
Руководитель наших HR-ов Александра Радина о "творчестве" в резюме, "мясных" кандидатах, разработчиках уровня "чайка" - и немного о конях:) Обещанные ссылочки: - статья о резюме здорового человека: https://clck.ru/3N4ZEo - чат для системных аналитиков: …
🔥10❤1
Всем привет!
На связи снова разработчики EvApps💪
Сегодня поговорим про DTO (Data Transfer Objects), а именно разберем, зачем и как использовать его в Laravel.
⭕️ DTO (Объект Передачи Данных) - это шаблон проектирования, используемый для передачи данных между уровнями в программной архитектуре. Основная цель DTO - отделить различные уровни или компоненты приложения, позволяя им взаимодействовать друг с другом, не вникая в детали реализации друг друга.
Итак, DTO - это простой объект передачи данных, который помогает отделить и изолировать компоненты друг от друга.
Если мы знаем структуру данных используемую в конкретном участке кода, то нам легко его поддерживать и изменять, тут нам и помогает DTO.
❇️ Например, код контроллера сохранения статьи:
В данном примере мы не знаем, что вернет метод $request->all().
Мы можем создать свой класс CreateArticleRequest и, при необходимости, смотреть, что он возвращает. Но теперь валидация данных связана с HTTP Request, и если нам нужно вызвать метод createArticle в другом месте кода, то нужно будет вручную передавать объект CreateArticleRequest. К тому же, класс CreateArticleRequest вернёт массив полей и мы не можем принудительно указать тип данных передаваемых в метод createArticle.
Используя DTO мы решим проблемы описанные выше.
⭕️ Как использовать?
Как мы сказали выше, DTO - это простой объект для сопоставления свойств.
❇️ Создадим класс DTO:
В объявлении класса DTO используем ключевые слова final readonly, то есть запрещаем наследовать класс DTO и переопределять свойства объекта, поэтому после создания класса DTO его контекст нельзя будет изменить, и мы можем быть уверены, что получим на вход именно нашу DTO, которую указали в контракте метода createArticle. Эти действия позволят нам использовать контекстный объект и добавить безопасность типов.
Контроллер теперь выглядит вот так:
Благодаря именованным аргументам в PHP8 мы легко создаем экземпляр CreateArticleDTO, используя конструкцию new CreateArticleDTO (...$request->all())
Такой подход использования DTO позволяет решить проблемы:
✅ Мы всегда знаем какие данные получит метод;
✅ Мы явно указываем тип переданных данных;
✅ Мы не привязаны к объекту CreateArticleRequest и можем вызвать createArticle в любом месте нашего кода.
Теперь код стал более качественным и поддерживаемым👍
❓А вы в своих Laravel-проектах используете DTO или работаете напрямую с массивами/Request?
#PHP #Laravel #DTO #backend #паттерны_проектирования #чистый_код #туториал
На связи снова разработчики EvApps💪
Сегодня поговорим про DTO (Data Transfer Objects), а именно разберем, зачем и как использовать его в Laravel.
⭕️ DTO (Объект Передачи Данных) - это шаблон проектирования, используемый для передачи данных между уровнями в программной архитектуре. Основная цель DTO - отделить различные уровни или компоненты приложения, позволяя им взаимодействовать друг с другом, не вникая в детали реализации друг друга.
Итак, DTO - это простой объект передачи данных, который помогает отделить и изолировать компоненты друг от друга.
Если мы знаем структуру данных используемую в конкретном участке кода, то нам легко его поддерживать и изменять, тут нам и помогает DTO.
❇️ Например, код контроллера сохранения статьи:
public function store(Request $request): JsonResponse
{
return response()->json([
$this->service->createArticle($request->all()),
Response::HTTP_CREATED
]);
}
В данном примере мы не знаем, что вернет метод $request->all().
Мы можем создать свой класс CreateArticleRequest и, при необходимости, смотреть, что он возвращает. Но теперь валидация данных связана с HTTP Request, и если нам нужно вызвать метод createArticle в другом месте кода, то нужно будет вручную передавать объект CreateArticleRequest. К тому же, класс CreateArticleRequest вернёт массив полей и мы не можем принудительно указать тип данных передаваемых в метод createArticle.
Используя DTO мы решим проблемы описанные выше.
⭕️ Как использовать?
Как мы сказали выше, DTO - это простой объект для сопоставления свойств.
❇️ Создадим класс DTO:
final readonly class CreateArticleDTO
{
public function __construct(
public string $noscript,
public string $denoscription,
public string $body,
) {}
}
В объявлении класса DTO используем ключевые слова final readonly, то есть запрещаем наследовать класс DTO и переопределять свойства объекта, поэтому после создания класса DTO его контекст нельзя будет изменить, и мы можем быть уверены, что получим на вход именно нашу DTO, которую указали в контракте метода createArticle. Эти действия позволят нам использовать контекстный объект и добавить безопасность типов.
Контроллер теперь выглядит вот так:
public function store(Request $request): JsonResponse
{
return response()->json([
$this->service->createArticle(new CreateArticleDTO(...$request->all())),
Response::HTTP_CREATED
]);
}
Благодаря именованным аргументам в PHP8 мы легко создаем экземпляр CreateArticleDTO, используя конструкцию new CreateArticleDTO (...$request->all())
Такой подход использования DTO позволяет решить проблемы:
✅ Мы всегда знаем какие данные получит метод;
✅ Мы явно указываем тип переданных данных;
✅ Мы не привязаны к объекту CreateArticleRequest и можем вызвать createArticle в любом месте нашего кода.
Теперь код стал более качественным и поддерживаемым👍
❓А вы в своих Laravel-проектах используете DTO или работаете напрямую с массивами/Request?
#PHP #Laravel #DTO #backend #паттерны_проектирования #чистый_код #туториал
🔥3🤔1
👋 Всем привет!
В прошлых постах мы говорили про различные системы и инструменты, которые помогают решать задачи разработчика.
А сегодня поговорим о том, как в Bitrix можно организовать компонент не просто для отображения, а как полноценный контроллер с CRUD-операциями.
Обработчик запросов в классе компонента (файл class.php) позволяет:
✅ Инкапсулировать весь код в одном классе
✅ Повторно использовать методы, данные и параметры компонента
✅ Использовать языковые фразы, шаблоны компонента
✅ Переопределять в компонентах-потомках стандартное поведение
Чтобы класс компонента мог обрабатывать запросы, необходимо:
▶️ Реализовать интерфейс \Bitrix\Main\Engine\Contract\Controllerable
▶️ Определить методы-действия с суффиксом Action
▶️ Реализовать метод configureActions (обычно возвращает пустой массив — конфигурацию по умолчанию)
▶️ Если нужно добавлять, обрабатывать ошибки, то стоит реализовать \Bitrix\Main\Errorable
При выполнении компонента в аяксовом режиме выполняются последовательно:
1️⃣ CBitrixComponent::onIncludeComponentLang
2️⃣ CBitrixComponent::onPrepareComponentParams
Запуск действия с фильтрами:
В прошлых постах мы говорили про различные системы и инструменты, которые помогают решать задачи разработчика.
А сегодня поговорим о том, как в Bitrix можно организовать компонент не просто для отображения, а как полноценный контроллер с CRUD-операциями.
Обработчик запросов в классе компонента (файл class.php) позволяет:
✅ Инкапсулировать весь код в одном классе
✅ Повторно использовать методы, данные и параметры компонента
✅ Использовать языковые фразы, шаблоны компонента
✅ Переопределять в компонентах-потомках стандартное поведение
Чтобы класс компонента мог обрабатывать запросы, необходимо:
▶️ Реализовать интерфейс \Bitrix\Main\Engine\Contract\Controllerable
▶️ Определить методы-действия с суффиксом Action
▶️ Реализовать метод configureActions (обычно возвращает пустой массив — конфигурацию по умолчанию)
▶️ Если нужно добавлять, обрабатывать ошибки, то стоит реализовать \Bitrix\Main\Errorable
При выполнении компонента в аяксовом режиме выполняются последовательно:
Запуск действия с фильтрами:
<?php
namespace local\components\vendor\example;
use CBitrixComponent;
use Bitrix\Main\Error;
use Bitrix\Main\Engine\Contract\Controllerable;
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
class ExampleComponent extends CBitrixComponent implements Controllerable
{
public function executeComponent()
{
// этот код не будет выполняться при запуске ajax-действий
}
public function configureActions()
{
return [];
}
public function onPrepareComponentParams($arParams)
{
// подготовка параметров
}
public function createAction(array $fields): ?array
{
$example = Example::add($fields);
if (!$example) {
$this->addError(new Error('Could not create example.', {код_ошибки}));
return null;
}
return $example->toArray();
}
public function viewAction(int $id): ?array
{
$example = Example::getById($id);
if (!$example) {
$this->addError(new Error('Could not find example.', {код_ошибки}));
return null;
}
return $example->toArray();
}
public function listAction(array $fields): ?array
{
$examples = Example::getList($fields);
return array_map(static fn ($example) => $example->toArray(), $examples);
}
public function updateAction(int $id, array $fields): ?array
{
$example = Example::update($id, $fields);
if (!$example) {
$this->addError(new Error('Could not update example.', {код_ошибки}));
return null;
}
return $example->toArray();
}
public function deleteAction(int $id): ?array
{
$example = Example::delete($id);
if (!$example) {
$this->addError(new Error('Could not delete example.', {код_ошибки}));
return null;
}
return $example->toArray();
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
👋 Всем привет
Сегодня мы поговорим про CSS и как правильно настроить загрузку шрифтов с помощью дескриптора
Этот дескриптор важен для управления тем, как будет отображаться текст до того, как шрифт будет загружен.
🔑 Параметры для
* auto — поведение по умолчанию, зависит от браузера.
* block — текст скрыт до 3 секунд; если шрифт не загрузился, показывается запасной, потом текст перерисовывается. Плюс: текст с нужным шрифтом без «скачка». Минус: может быть невидимым, может сильно ухудшить UX и LCP.
* swap — сразу показывается запасной шрифт, после загрузки шрифта происходит замена. Плюс: текст виден, улучшает UX и SEO. Минус: возможен визуальный «скачок».
* fallback — скрытие 100 мс, потом запасной шрифт; если основной не загрузился через 3 с, остаётся запасной. Замена на загруженный шрифт без перезагрузки не произойдёт.
* optional — скрытие 100 мс, затем запасной шрифт; замена на основной возможна только после обновления страницы.
✨ Рекомендация: чаще всего используйте
Материалы:
MDN Web Docs — font-display
W3C — CSS Fonts Module Level 4
❓ Как вы настраиваете `font-display` в своих проектах?
#frontend #CSS #UIUX #WebDev
Сегодня мы поговорим про CSS и как правильно настроить загрузку шрифтов с помощью дескриптора
font-display в @font-face.Этот дескриптор важен для управления тем, как будет отображаться текст до того, как шрифт будет загружен.
@font-face {
font-display: auto;
font-display: block;
font-display: swap;
font-display: fallback;
font-display: optional;
}🔑 Параметры для
font-display:* auto — поведение по умолчанию, зависит от браузера.
* block — текст скрыт до 3 секунд; если шрифт не загрузился, показывается запасной, потом текст перерисовывается. Плюс: текст с нужным шрифтом без «скачка». Минус: может быть невидимым, может сильно ухудшить UX и LCP.
* swap — сразу показывается запасной шрифт, после загрузки шрифта происходит замена. Плюс: текст виден, улучшает UX и SEO. Минус: возможен визуальный «скачок».
* fallback — скрытие 100 мс, потом запасной шрифт; если основной не загрузился через 3 с, остаётся запасной. Замена на загруженный шрифт без перезагрузки не произойдёт.
* optional — скрытие 100 мс, затем запасной шрифт; замена на основной возможна только после обновления страницы.
✨ Рекомендация: чаще всего используйте
swap (он стоит по умолчанию в Google Fonts), а если необходимо избежать мелькания текста, выбирайте optional.Материалы:
MDN Web Docs — font-display
W3C — CSS Fonts Module Level 4
❓ Как вы настраиваете `font-display` в своих проектах?
#frontend #CSS #UIUX #WebDev
MDN Web Docs
font-display - CSS | MDN
The font-display denoscriptor for the @font-face at-rule determines how a font face is displayed based on whether and when it is downloaded and ready to use.
🔥4
Привет всем!
🚀 Сегодня запускаем серию постов, в которых будем подробно разбирать паттерны интеграции ограниченных контекстов. Для начала поговорим о трех подходах, которые играют ключевую роль в организации взаимодействия между командами и контекстами.
Cooperation 🌐
Этот паттерн идеально подходит для команд с устоявшимися коммуникациями. Это может быть одна команда или несколько команд с взаимозависимыми целями, когда успех одной зависит от успеха другой. Главное здесь — это качественная взаимодействие между участниками процесса.
Partnership 🤝
В этом случае команды работают совместно, без диктата одной команды над другой. Если нужно внести изменения в контракты, команды договариваются и оперативно внедряют изменения, что позволяет получить быструю обратную связь. Однако для распределённых команд этот паттерн может стать проблемой из-за сложности в коммуникации.
Shared Kernel 🧩
Иногда модели, ограниченные контекстом, частично реализованы в разных контекстах. Однако важно, чтобы общее ядро удовлетворяло требованиям обоих контекстов и оставалось минималистичным, чтобы избежать каскадных изменений. В идеале, общее ядро должно содержать только те элементы, которые необходимы для интеграции, и изменения требуют обязательных тестов в обоих контекстах.
В следующем посте продолжим рассматривать, когда и как применять Shared Kernel и перейдем к другим паттернам интеграции!
#development #паттерны #boundedcontext #cooperation #sharedkernel #Partnership
🚀 Сегодня запускаем серию постов, в которых будем подробно разбирать паттерны интеграции ограниченных контекстов. Для начала поговорим о трех подходах, которые играют ключевую роль в организации взаимодействия между командами и контекстами.
Cooperation 🌐
Этот паттерн идеально подходит для команд с устоявшимися коммуникациями. Это может быть одна команда или несколько команд с взаимозависимыми целями, когда успех одной зависит от успеха другой. Главное здесь — это качественная взаимодействие между участниками процесса.
Partnership 🤝
В этом случае команды работают совместно, без диктата одной команды над другой. Если нужно внести изменения в контракты, команды договариваются и оперативно внедряют изменения, что позволяет получить быструю обратную связь. Однако для распределённых команд этот паттерн может стать проблемой из-за сложности в коммуникации.
Shared Kernel 🧩
Иногда модели, ограниченные контекстом, частично реализованы в разных контекстах. Однако важно, чтобы общее ядро удовлетворяло требованиям обоих контекстов и оставалось минималистичным, чтобы избежать каскадных изменений. В идеале, общее ядро должно содержать только те элементы, которые необходимы для интеграции, и изменения требуют обязательных тестов в обоих контекстах.
В следующем посте продолжим рассматривать, когда и как применять Shared Kernel и перейдем к другим паттернам интеграции!
#development #паттерны #boundedcontext #cooperation #sharedkernel #Partnership
❤1
Привет снова 👋
Продолжаем нашу серию постов о паттернах, и сегодня поговорим о трех интересных паттернах интеграции, которые помогут наладить взаимодействие между контекстами в условиях автономности команд.
Customer-Supplier 🏷🔗
Этот паттерн можно представить как поток: контекст Customer находится ниже по течению, а Supplier — выше. В отличие от кооперативных паттернов, здесь обе стороны могут решать свои задачи независимо. Однако это может создать дисбаланс во взаимоотношениях.
Conformist 🔄
Здесь Customer принимает контракты, предложенные Supplier, не имея возможности их изменять. Этот паттерн часто встречается в случае использования внешних сервисов или когда Supplier определяет отраслевой стандарт, который должен быть принят всеми контекстами, расположенными ниже.
Anticorruption Layer 🛡🔄
Когда Customer не соглашается с контрактами Supplier, он создает внутренний слой, который трансформирует контракты Supplier в те, которые отвечают потребностям Customer. Этот слой защищает бизнес-логику Customer от внешних изменений и помогает адаптировать контракты под нужды конкретного контекста.
Завершим нашу серию постов в следующем посте, расскажем про Open-Host Service и Separate Ways.
#development #паттерны #customersupplier #anticorruptionlayer #Conformist #boundedcontext
Продолжаем нашу серию постов о паттернах, и сегодня поговорим о трех интересных паттернах интеграции, которые помогут наладить взаимодействие между контекстами в условиях автономности команд.
Customer-Supplier 🏷🔗
Этот паттерн можно представить как поток: контекст Customer находится ниже по течению, а Supplier — выше. В отличие от кооперативных паттернов, здесь обе стороны могут решать свои задачи независимо. Однако это может создать дисбаланс во взаимоотношениях.
Conformist 🔄
Здесь Customer принимает контракты, предложенные Supplier, не имея возможности их изменять. Этот паттерн часто встречается в случае использования внешних сервисов или когда Supplier определяет отраслевой стандарт, который должен быть принят всеми контекстами, расположенными ниже.
Anticorruption Layer 🛡🔄
Когда Customer не соглашается с контрактами Supplier, он создает внутренний слой, который трансформирует контракты Supplier в те, которые отвечают потребностям Customer. Этот слой защищает бизнес-логику Customer от внешних изменений и помогает адаптировать контракты под нужды конкретного контекста.
Завершим нашу серию постов в следующем посте, расскажем про Open-Host Service и Separate Ways.
#development #паттерны #customersupplier #anticorruptionlayer #Conformist #boundedcontext
🆒3
Media is too big
VIEW IN TELEGRAM
С пятницей, коллеги!
Сегодня разбавляем серьезный контент... наболевшим🤯
В новом эпизоде нашего подкаста IT ToLк by EvApps системный аналитик Олег и мобильный разработчик Андрей разгоняют про боли и слёзы айтишников.
▶️ Четвертый эпизод уже в ВК - https://vk.cc/cPE3fD
Сегодня разбавляем серьезный контент... наболевшим🤯
В новом эпизоде нашего подкаста IT ToLк by EvApps системный аналитик Олег и мобильный разработчик Андрей разгоняют про боли и слёзы айтишников.
▶️ Четвертый эпизод уже в ВК - https://vk.cc/cPE3fD
🔥5😁1
Привет, друзья 👋
В этом посте завершаем нашу серию и рассмотрим два последних паттерна, которые могут быть полезны в ситуациях, когда требуется особая защита и автономность для контекстов.
Open-Host Service 🌐🔐
Этот паттерн противоположен Anticorruption Layer. Здесь Supplier создает защитный слой, чтобы обезопасить своих пользователей от изменений в своей системе. Он использует публичные контракты (published language), которые помогают изолировать изменения внутри Supplier и позволить ему развиваться автономно от нижележащих контекстов.
Separate Ways 🛑🚶♂️
Последний тип взаимодействия, по сути, исключает само взаимодействие между командами. Этот паттерн применяется в случаях, когда команды не могут или не хотят взаимодействовать по различным причинам.
Такая ситуация может возникнуть, если из-за организационных или политических факторов достижение согласия между командами занимает много времени и значительно увеличивает стоимость разработки. Также, если затраты на дублирование и поддержку функциональности (чаще всего это касается generic subdomains) ниже, чем на разработку общего решения и интеграцию между контекстами.
Иногда модели ограниченных контекстов настолько отличаются друг от друга, что использование паттернов типа Customer-Supplier становится слишком дорогим в реализации и обслуживании. В таких случаях проще и выгоднее просто продублировать функциональность, чем пытаться интегрировать её в рамках общего контекста.
Примечание: ⚠️ Следует избегать паттерна Separate Ways в реализации core subdomains.
#development #паттерны #openhostservice #separateways #boundedcontext
В этом посте завершаем нашу серию и рассмотрим два последних паттерна, которые могут быть полезны в ситуациях, когда требуется особая защита и автономность для контекстов.
Open-Host Service 🌐🔐
Этот паттерн противоположен Anticorruption Layer. Здесь Supplier создает защитный слой, чтобы обезопасить своих пользователей от изменений в своей системе. Он использует публичные контракты (published language), которые помогают изолировать изменения внутри Supplier и позволить ему развиваться автономно от нижележащих контекстов.
Separate Ways 🛑🚶♂️
Последний тип взаимодействия, по сути, исключает само взаимодействие между командами. Этот паттерн применяется в случаях, когда команды не могут или не хотят взаимодействовать по различным причинам.
Такая ситуация может возникнуть, если из-за организационных или политических факторов достижение согласия между командами занимает много времени и значительно увеличивает стоимость разработки. Также, если затраты на дублирование и поддержку функциональности (чаще всего это касается generic subdomains) ниже, чем на разработку общего решения и интеграцию между контекстами.
Иногда модели ограниченных контекстов настолько отличаются друг от друга, что использование паттернов типа Customer-Supplier становится слишком дорогим в реализации и обслуживании. В таких случаях проще и выгоднее просто продублировать функциональность, чем пытаться интегрировать её в рамках общего контекста.
Примечание: ⚠️ Следует избегать паттерна Separate Ways в реализации core subdomains.
#development #паттерны #openhostservice #separateways #boundedcontext
Привет 👋
💡 Сегодня разбираем базовую, но важную тему в Git — три способа интеграции изменений между ветками: Merge, Rebase и Fast-Forward.
Каждый из них влияет на историю коммитов и рабочий процесс команды.
🔀Merge
Объединяет изменения из одной ветки в другую, создавая отдельный merge-коммит.
Вид ветки: сохраняет полную и разветвлённую структуру — видно, где ветки расходились и сходились.
Когда использовать: при объединении фич в main ветку, когда важно сохранить контекст разработки, особенно в командной работе.
♻️Rebase
Переносит коммиты ветки на новую, обычно на актуальное состояние main ветки.
Вид ветки: становится линейной, без merge-коммитов — будто работа шла поверх main ветки.
Когда использовать: удобно для локальных веток, чтобы очистить историю перед слиянием.
⏩ Fast-Forward Merge
Происходит, если основная ветка не расходилась с твоей. В этом случае Git перемещает указатель вперёд без создания нового коммита.
Вид ветки: полностью линейная, как после rebase.
Когда использовать: если в целевой ветке не было других изменений. Можно указать флаг --ff-only.
📚Отличия:
Структура ветки: git merge сохраняет разветвлённую структуру с merge-коммитами; git rebase создаёт линейную структуру, переписывая коммиты; fast-forward даёт линейную структуру, перемещая указатель.
ID коммитов: git merge сохраняет оригинальные ID коммитов; git rebase создаёт новые ID для перебазированных коммитов.
Безопасность: git merge обычно безопаснее для общих веток, так как не переписывает историю; git rebase следует использовать с осторожностью на общих ветках из-за переписывания истории.
Выбирайте учитывая ваши рабочие процессы и приоритеты команды — что важнее: чистая история или точное сохранение контекста разработки.
🖥 Попрактиковаться с ветками и коммитами можно на интерактивном тренажёре: Learn Git Branching
#git #development #merge #rebase #fastforward #workflow
💡 Сегодня разбираем базовую, но важную тему в Git — три способа интеграции изменений между ветками: Merge, Rebase и Fast-Forward.
Каждый из них влияет на историю коммитов и рабочий процесс команды.
🔀Merge
Объединяет изменения из одной ветки в другую, создавая отдельный merge-коммит.
Вид ветки: сохраняет полную и разветвлённую структуру — видно, где ветки расходились и сходились.
Когда использовать: при объединении фич в main ветку, когда важно сохранить контекст разработки, особенно в командной работе.
♻️Rebase
Переносит коммиты ветки на новую, обычно на актуальное состояние main ветки.
Вид ветки: становится линейной, без merge-коммитов — будто работа шла поверх main ветки.
Когда использовать: удобно для локальных веток, чтобы очистить историю перед слиянием.
⏩ Fast-Forward Merge
Происходит, если основная ветка не расходилась с твоей. В этом случае Git перемещает указатель вперёд без создания нового коммита.
Вид ветки: полностью линейная, как после rebase.
Когда использовать: если в целевой ветке не было других изменений. Можно указать флаг --ff-only.
📚Отличия:
Структура ветки: git merge сохраняет разветвлённую структуру с merge-коммитами; git rebase создаёт линейную структуру, переписывая коммиты; fast-forward даёт линейную структуру, перемещая указатель.
ID коммитов: git merge сохраняет оригинальные ID коммитов; git rebase создаёт новые ID для перебазированных коммитов.
Безопасность: git merge обычно безопаснее для общих веток, так как не переписывает историю; git rebase следует использовать с осторожностью на общих ветках из-за переписывания истории.
Выбирайте учитывая ваши рабочие процессы и приоритеты команды — что важнее: чистая история или точное сохранение контекста разработки.
🖥 Попрактиковаться с ветками и коммитами можно на интерактивном тренажёре: Learn Git Branching
#git #development #merge #rebase #fastforward #workflow
learngitbranching.js.org
Learn Git Branching
An interactive Git visualization tool to educate and challenge!
👍5
Сегодня нейросетям всё чаще доверяют писать и править код, чтобы ускорить разработку.
Но нередко результат — день, потраченный на устранение хаоса.
Этот кейс — не обвинение ИИ, а напоминание: важно понимать, с чем мы работаем
💡 Почему нейросети ломают код?
Нейросеть — не разработчик, а языковая модель.
Она не понимает код — она предсказывает, что выглядит как правильный ответ.
Ее цель — звучать уверенно, а не быть точной.
Поэтому она может предложить «исправление», которое в итоге ломает всё.
Она видит не систему, а текст — и делает то, что статистически похоже на решение.
📘 1. Оптимизирован не под правду, а под уверенность.
Модель обучена звучать убедительно, даже если ошибается.
Её «награда» — не корректность, а ощущение правильности.
💻 2. Не тестируют и не исполняют.
Разработчик проверяет код, запускает тесты, видит окружение и файлы проекта.
AI-ассистенты, даже встроенные в редактор, могут «видеть» файлы и окружение, но не запускают код и не проверяют его работу.
Они просто предсказывают, как может выглядеть «фикс» — не зная, сработает ли он на самом деле.
🧠 3. Не помнит, а делает вид, что помнит.
Контекст диалога ограничен — старые детали теряются.
Но вместо того чтобы признаться, ИИ «достраивает» логику самостоятельно, будто всё под контролем.
⚙️ Нейросети не ломают системы специально.
Они делает это, потому что не понимают, что такое система.
Они не видят ваших дедлайнов, пользователей, окружения — только текст.
А когда текст становится единственной мерой истины, реальность перестаёт иметь значение.
ИИ не должен заменять разработчиков — ему нужны разработчики, которые помнят, как выглядит реальность.
Используйте его, чтобы усиливать свои навыки, а не подменять их.
Потому что в тот момент, когда вы отдаёте ему свой код — вы отдаёте ему контроль.
#ai #development #code #workflow #risk #vibe_coding
Но нередко результат — день, потраченный на устранение хаоса.
Этот кейс — не обвинение ИИ, а напоминание: важно понимать, с чем мы работаем
💡 Почему нейросети ломают код?
Нейросеть — не разработчик, а языковая модель.
Она не понимает код — она предсказывает, что выглядит как правильный ответ.
Ее цель — звучать уверенно, а не быть точной.
Поэтому она может предложить «исправление», которое в итоге ломает всё.
Она видит не систему, а текст — и делает то, что статистически похоже на решение.
📘 1. Оптимизирован не под правду, а под уверенность.
Модель обучена звучать убедительно, даже если ошибается.
Её «награда» — не корректность, а ощущение правильности.
💻 2. Не тестируют и не исполняют.
Разработчик проверяет код, запускает тесты, видит окружение и файлы проекта.
AI-ассистенты, даже встроенные в редактор, могут «видеть» файлы и окружение, но не запускают код и не проверяют его работу.
Они просто предсказывают, как может выглядеть «фикс» — не зная, сработает ли он на самом деле.
🧠 3. Не помнит, а делает вид, что помнит.
Контекст диалога ограничен — старые детали теряются.
Но вместо того чтобы признаться, ИИ «достраивает» логику самостоятельно, будто всё под контролем.
⚙️ Нейросети не ломают системы специально.
Они делает это, потому что не понимают, что такое система.
Они не видят ваших дедлайнов, пользователей, окружения — только текст.
А когда текст становится единственной мерой истины, реальность перестаёт иметь значение.
ИИ не должен заменять разработчиков — ему нужны разработчики, которые помнят, как выглядит реальность.
Используйте его, чтобы усиливать свои навыки, а не подменять их.
Потому что в тот момент, когда вы отдаёте ему свой код — вы отдаёте ему контроль.
#ai #development #code #workflow #risk #vibe_coding
🏆1
Forwarded from Двач
This media is not supported in your browser
VIEW IN TELEGRAM
ChatGPT, когда в очередной раз выдал говёный код с ошибкой:
Всем привет🖐
Недавно, у нас возникла идея рассмотреть lazy loading не только как инструмент оптимизации, но и как возможный способ защиты чувствительного кода.
Lazy-loading — это способ загружать модули, компоненты или шаблоны только тогда, когда они действительно нужны, а не при первом запуске приложения.
В React и других фреймворках это реализуется через:
- разделение модулей,
- конфигурацию роутов,
- отложенную загрузку компонентов.
Преимущества стандартны:
⚡️ быстреее начальная загрузка
📉 меньше трафика
🚀 выше производительность
В React это реализуется через React.lazy() и Suspense:
Такое разбиение кода уменьшает размер бандла и повышает скорость загрузки.
Во время разбирательств, мы заметили странную вещь — почти ни один фреймворк не упоминает lazy-loading в контексте безопасности. Только как оптимизацию.
Но если задуматься:
В серверно-рендеримых приложениях чувствительный код не возвращается клиенту, пока пользователь не прошёл аутентификацию.
В SPA всё иначе — весь код загружается сразу, даже тот, что должен быть доступен только после входа.
Lazy-loading позволяет решить это:
мы можем не загружать части приложения с чувствительной логикой до тех пор, пока пользователь не авторизован.
Вот пример с использованием OAuth2-библиотеки для клиентской аутентификации:
Вместо простого текста здесь может быть целый <ComplexApp /> — с десятками килобайт JS, потенциально раскрывающих уязвимости.
Решение: оборачивать такие блоки в <Suspense> и загружать их только после подтверждённой аутентификации.
Классическое SPA грузит всё и сразу, включая закрытый функционал.
Lazy-loading — загружает только то, что нужно конкретному пользователю в данный момент.
Это не «панацея» для безопасности, но важный слой защиты:
Чем меньше кода попадает в браузер, тем меньше поверхность атаки.
- Должны ли мы использовать lazy-loading не только ради скорости, но и ради защиты кода?
- Да. Определённо должны.
🧠 А вы что думаете? Встречали такой способ использования lazy-loading?
#webdev #security #architecture #frontend #development
Недавно, у нас возникла идея рассмотреть lazy loading не только как инструмент оптимизации, но и как возможный способ защиты чувствительного кода.
Lazy-loading — это способ загружать модули, компоненты или шаблоны только тогда, когда они действительно нужны, а не при первом запуске приложения.
В React и других фреймворках это реализуется через:
- разделение модулей,
- конфигурацию роутов,
- отложенную загрузку компонентов.
Преимущества стандартны:
⚡️ быстреее начальная загрузка
📉 меньше трафика
🚀 выше производительность
В React это реализуется через React.lazy() и Suspense:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}Такое разбиение кода уменьшает размер бандла и повышает скорость загрузки.
Во время разбирательств, мы заметили странную вещь — почти ни один фреймворк не упоминает lazy-loading в контексте безопасности. Только как оптимизацию.
Но если задуматься:
В серверно-рендеримых приложениях чувствительный код не возвращается клиенту, пока пользователь не прошёл аутентификацию.
В SPA всё иначе — весь код загружается сразу, даже тот, что должен быть доступен только после входа.
Lazy-loading позволяет решить это:
мы можем не загружать части приложения с чувствительной логикой до тех пор, пока пользователь не авторизован.
Вот пример с использованием OAuth2-библиотеки для клиентской аутентификации:
<AuthenticatedTemplate>
<p>Вход выполнен как: {user?.username}</p>
</AuthenticatedTemplate>
Вместо простого текста здесь может быть целый <ComplexApp /> — с десятками килобайт JS, потенциально раскрывающих уязвимости.
Решение: оборачивать такие блоки в <Suspense> и загружать их только после подтверждённой аутентификации.
Классическое SPA грузит всё и сразу, включая закрытый функционал.
Lazy-loading — загружает только то, что нужно конкретному пользователю в данный момент.
Это не «панацея» для безопасности, но важный слой защиты:
Чем меньше кода попадает в браузер, тем меньше поверхность атаки.
- Должны ли мы использовать lazy-loading не только ради скорости, но и ради защиты кода?
- Да. Определённо должны.
🧠 А вы что думаете? Встречали такой способ использования lazy-loading?
#webdev #security #architecture #frontend #development
❤3🔥3
Представьте: утро, обычный рабочий день.
Открываешь приложение — и что-то не так.
База не поднимается. Файлы повреждены. Или какой-то баг просто всё удалил.
В голове сразу мысль: «Ладно, не страшно — есть же бэкапы».
Но при попытке восстановить — тишина.
Архивы пустые, повреждённые или восстанавливаются бесконечно.
Горькая правда:
бэкап ничего не стоит, пока ты не попробовал его восстановить.
Недавно у одной из команд случилась такая история.
Меняли схему базы данных в одном из проектов, и во время миграции что-то пошло не так — SQLite база повредилась.
Попробовали развернуть резервную копию — но и она оказалась битой.
Позже выяснилось, что копирование шло в тот момент, когда приложение ещё писало данные.
Система месяцами создавала битые бэкапы — и никто не знал, потому что восстановление ни разу не проверялось.
К счастью, это были тестовые данные. Но если бы прод?
Пользовательские данные, проект, репутация — всё под угрозой.
Часто живёшь в иллюзии, что раз бэкап есть — значит, всё под контролем.
На деле это копия, которая может не сработать в тот момент, когда она нужна.
Что важно бэкапить:
🧠 Код — GitHub, GitLab
🗄 Базу — Postgres, MySQL, Supabase, SQLite
🖼 Файлы пользователей — изображения, документы
🔐 Конфиги и секреты — .env, API-ключи, настройки деплоя
Главная ошибка:
ты не знаешь, работает ли бэкап, пока не попробуешь восстановление.
Без этого — он как кот Шрёдингера, запертый в коробке.
Как делают большие компании:
— GitLab ежедневно тестирует восстановление и следит за метриками
— Basecamp проводит «тесты катастроф» — симулирует исчезновение датацентра
Типовая схема:
• Делать бэкапы автоматически (ночные дампы, снапшоты)
• Восстанавливать в тестовую среду
• Проверять: база поднимается, файлы читаются, логин работает (плюс smoke-тесты)
• Отправлять алерты при сбоях
• Периодически симулировать сбой и измерять скорость восстановления
Что и как проверять:
💻 Код: Push в GitHub/GitLab (с 2FA) → клонировать в новую папку и собрать проект
🗄 База данных: pg_dump / .backup / PITR → восстановить в тестовую БД и проверить данные
🖼 Файлы пользователей: S3 / B2 / GCS → случайно скачать несколько файлов и открыть
🔐 Конфиги и секреты: 1Password / Bitwarden / VeraCrypt → запустить проект, используя только эти конфиги
💡 Для SQLite:
копирование живой .db может её повредить.
Используй:
sqlite3 mydb.db "VACUUM INTO backup.db"
Так создаётся чистая копия без ошибок.
Когда тестировать восстановление:
— Раз в месяц: локально проверить случайный бэкап
— Раз в квартал: полный тест — база + файлы + приложение
— Раз в год: симулировать потерю устройства и попробовать вернуть
Почему это важно:
Один сбой может уничтожить проект, если вы не проверяли восстановление.
Теперь бэкапы делаются не ради спокойствия,
а ради уверенности, что смогу восстановиться.
Потому что бэкапы — это не паранойя.
Это способ быть уверенным, что завтра твой проект не исчезнет. ❤️
#backup #development #risk #code
Открываешь приложение — и что-то не так.
База не поднимается. Файлы повреждены. Или какой-то баг просто всё удалил.
В голове сразу мысль: «Ладно, не страшно — есть же бэкапы».
Но при попытке восстановить — тишина.
Архивы пустые, повреждённые или восстанавливаются бесконечно.
Горькая правда:
бэкап ничего не стоит, пока ты не попробовал его восстановить.
Недавно у одной из команд случилась такая история.
Меняли схему базы данных в одном из проектов, и во время миграции что-то пошло не так — SQLite база повредилась.
Попробовали развернуть резервную копию — но и она оказалась битой.
Позже выяснилось, что копирование шло в тот момент, когда приложение ещё писало данные.
Система месяцами создавала битые бэкапы — и никто не знал, потому что восстановление ни разу не проверялось.
К счастью, это были тестовые данные. Но если бы прод?
Пользовательские данные, проект, репутация — всё под угрозой.
Часто живёшь в иллюзии, что раз бэкап есть — значит, всё под контролем.
На деле это копия, которая может не сработать в тот момент, когда она нужна.
Что важно бэкапить:
🧠 Код — GitHub, GitLab
🗄 Базу — Postgres, MySQL, Supabase, SQLite
🖼 Файлы пользователей — изображения, документы
🔐 Конфиги и секреты — .env, API-ключи, настройки деплоя
Главная ошибка:
ты не знаешь, работает ли бэкап, пока не попробуешь восстановление.
Без этого — он как кот Шрёдингера, запертый в коробке.
Как делают большие компании:
— GitLab ежедневно тестирует восстановление и следит за метриками
— Basecamp проводит «тесты катастроф» — симулирует исчезновение датацентра
Типовая схема:
• Делать бэкапы автоматически (ночные дампы, снапшоты)
• Восстанавливать в тестовую среду
• Проверять: база поднимается, файлы читаются, логин работает (плюс smoke-тесты)
• Отправлять алерты при сбоях
• Периодически симулировать сбой и измерять скорость восстановления
Что и как проверять:
💻 Код: Push в GitHub/GitLab (с 2FA) → клонировать в новую папку и собрать проект
🗄 База данных: pg_dump / .backup / PITR → восстановить в тестовую БД и проверить данные
🖼 Файлы пользователей: S3 / B2 / GCS → случайно скачать несколько файлов и открыть
🔐 Конфиги и секреты: 1Password / Bitwarden / VeraCrypt → запустить проект, используя только эти конфиги
💡 Для SQLite:
копирование живой .db может её повредить.
Используй:
sqlite3 mydb.db "VACUUM INTO backup.db"
Так создаётся чистая копия без ошибок.
Когда тестировать восстановление:
— Раз в месяц: локально проверить случайный бэкап
— Раз в квартал: полный тест — база + файлы + приложение
— Раз в год: симулировать потерю устройства и попробовать вернуть
Почему это важно:
Один сбой может уничтожить проект, если вы не проверяли восстановление.
Теперь бэкапы делаются не ради спокойствия,
а ради уверенности, что смогу восстановиться.
Потому что бэкапы — это не паранойя.
Это способ быть уверенным, что завтра твой проект не исчезнет. ❤️
#backup #development #risk #code
❤7
🚀 Почему dev-серверы часто запускаются на localhost:3000 (и сейчас ещё на 5173)
Когда ты запускаешь сервер localhost:3000 или localhost:5173, это не случайность.
За этими портами — история веб-разработки: от Ruby on Rails и Java до Node.js и Vite.
💡 Что такое порт?
Порт — это номер, по которому на компьютере слушает сервис.
Представь, что твой компьютер — это здание, а порты — двери с номерами.
Когда ты заходишь на localhost:3000, ты буквально открываешь дверь № 3000, чтобы увидеть своё приложение.
Всего таких дверей 65 535:
🔹 0–1023 — системные (HTTP 80, HTTPS 443, SSH 22)
🔹 1024–49151 — пользовательские (3000, 8000, 8080 и др.)
🔹 49152–65535 — временные (используются ОС)
Так что 3000 — просто одно из множества возможных значений.
⚙️ Порт 3000 — путь от Rails к Node.js
В Ruby on Rails по умолчанию сервер разработки запускался на 3000.
Позже, с ростом Node.js и Express, в официальных примерах часто встречалась строка:
Эта привычка закрепилась: её копировали в туториалах, курсах и шаблонах.
React, Next.js и другие фреймворки просто продолжили эту традицию.
Сегодня 3000 — неофициальный “Hello World” порт веб-разработки.
🐍 Порт 8000 — классика Python
Ещё до Node, Python-разработчики поднимали локальные HTTP-сервера командой:
По умолчанию сервер слушал 8000 — безопасный номер, не требующий прав администратора.
Фреймворк Django тоже выбрал этот порт.
Со временем 8000 стал синонимом “запустил и проверил локально”.
☕️ Порт 8080 — наследие Java
В 90-х порты ниже 1024 требовали root-прав.
Java-разработчики из Apache Tomcat и Jetty придумали обход:
80 → 8080
Выглядит похоже, но работает без повышенных прав.
С тех пор 8080 стал стандартом для “серьёзных” серверов вроде Spring Boot.
⚡️ Порт 5173 — современный штрих от Vite
Когда появился Vite, авторы выбрали порт с пасхалкой:
51 = VI
73 = TE
👉 5173 = VITE 😎
Теперь каждый npm run dev открывает localhost:5173 — фирменный почерк нового поколения фронтенда.
🧠 Можно ли использовать другие порты?
Конечно!
Многие привыкают к 3000 и паникуют, увидев:
Но свободных портов тысячи.
Попробуй:
И никаких конфликтов 😄
🕰 Заключение
8080 — обход ограничений Java
8000 — прагматичный выбор Python
3000 — наследие Rails и Node.js
5173 — фирменный порт Vite
Эти цифры — не просто числа.
Это часть истории веб-разработки с 90-х годов.
Когда в следующий раз запустишь:
👉 http://localhost:3000/
вспомни — за этим числом десятилетия привычек и технологий.
Если порт занят — не убивай процесс.
Просто выбери другое число.
Сделай его своим фирменным портом 😉
Безопасный диапазон: 1024–49151
И когда будешь запускать сервер — делай это с уважением😁
А вы оставляете порт по умолчанию или меняете на свой?
#development #webdev #frontend #backend
Когда ты запускаешь сервер localhost:3000 или localhost:5173, это не случайность.
За этими портами — история веб-разработки: от Ruby on Rails и Java до Node.js и Vite.
💡 Что такое порт?
Порт — это номер, по которому на компьютере слушает сервис.
Представь, что твой компьютер — это здание, а порты — двери с номерами.
Когда ты заходишь на localhost:3000, ты буквально открываешь дверь № 3000, чтобы увидеть своё приложение.
Всего таких дверей 65 535:
🔹 0–1023 — системные (HTTP 80, HTTPS 443, SSH 22)
🔹 1024–49151 — пользовательские (3000, 8000, 8080 и др.)
🔹 49152–65535 — временные (используются ОС)
Так что 3000 — просто одно из множества возможных значений.
⚙️ Порт 3000 — путь от Rails к Node.js
В Ruby on Rails по умолчанию сервер разработки запускался на 3000.
Позже, с ростом Node.js и Express, в официальных примерах часто встречалась строка:
app.listen(3000, () => console.log('Server running on port 3000'));Эта привычка закрепилась: её копировали в туториалах, курсах и шаблонах.
React, Next.js и другие фреймворки просто продолжили эту традицию.
Сегодня 3000 — неофициальный “Hello World” порт веб-разработки.
🐍 Порт 8000 — классика Python
Ещё до Node, Python-разработчики поднимали локальные HTTP-сервера командой:
python3 -m http.server
По умолчанию сервер слушал 8000 — безопасный номер, не требующий прав администратора.
Фреймворк Django тоже выбрал этот порт.
Со временем 8000 стал синонимом “запустил и проверил локально”.
☕️ Порт 8080 — наследие Java
В 90-х порты ниже 1024 требовали root-прав.
Java-разработчики из Apache Tomcat и Jetty придумали обход:
80 → 8080
Выглядит похоже, но работает без повышенных прав.
С тех пор 8080 стал стандартом для “серьёзных” серверов вроде Spring Boot.
⚡️ Порт 5173 — современный штрих от Vite
Когда появился Vite, авторы выбрали порт с пасхалкой:
51 = VI
73 = TE
👉 5173 = VITE 😎
Теперь каждый npm run dev открывает localhost:5173 — фирменный почерк нового поколения фронтенда.
🧠 Можно ли использовать другие порты?
Конечно!
Многие привыкают к 3000 и паникуют, увидев:
Error: Port 3000 already in use
Но свободных портов тысячи.
Попробуй:
npm run dev -- --port=42069
vite --port=13337
И никаких конфликтов 😄
🕰 Заключение
8080 — обход ограничений Java
8000 — прагматичный выбор Python
3000 — наследие Rails и Node.js
5173 — фирменный порт Vite
Эти цифры — не просто числа.
Это часть истории веб-разработки с 90-х годов.
Когда в следующий раз запустишь:
👉 http://localhost:3000/
вспомни — за этим числом десятилетия привычек и технологий.
Если порт занят — не убивай процесс.
Просто выбери другое число.
Сделай его своим фирменным портом 😉
Безопасный диапазон: 1024–49151
И когда будешь запускать сервер — делай это с уважением😁
А вы оставляете порт по умолчанию или меняете на свой?
#development #webdev #frontend #backend
👍5🔥1
🚀 Наши друзья из Intelsy проводят вебинар для тех, кто руководит ИТ и хочет навести порядок в хаосе 1С-проектов - а мы такое всецело поддерживаем!
Тема: Будни ИТ-директора: стабильность, быстродействие, борьба с 1С
Дата: 6 ноября в 11:00 по мск
Формат: открытый разговор без маркетинговых лозунгов
О чем поговорим:
– какие вопросы тянет на себе ИТ-директор;
– зачем нужны внешние спецы при собственном штате;
– к кому обращаться за ресурсами и как не ошибиться;
– как работает обращение к внешним ресурсам и что остается за кадром.
📍 Регистрация — по ссылке, без спама и рассылок.
Вебинар
Вебинар
Вебинар
🔥 Залетай, если хочешь меньше хаоса и больше стабильности в своих 1С-проектах.
Тема: Будни ИТ-директора: стабильность, быстродействие, борьба с 1С
Дата: 6 ноября в 11:00 по мск
Формат: открытый разговор без маркетинговых лозунгов
О чем поговорим:
– какие вопросы тянет на себе ИТ-директор;
– зачем нужны внешние спецы при собственном штате;
– к кому обращаться за ресурсами и как не ошибиться;
– как работает обращение к внешним ресурсам и что остается за кадром.
📍 Регистрация — по ссылке, без спама и рассылок.
Вебинар
Вебинар
Вебинар
🔥 Залетай, если хочешь меньше хаоса и больше стабильности в своих 1С-проектах.