День 2589. #Карьера #AI
Топ Советов по Повышению Продуктивности. Часть 10. Окончание
Начало
Как продуктивно использовать ИИ-инструменты
1. Начните с ИИ, закончите размышлением
Позвольте ИИ сгенерировать черновик. Прочитайте его построчно. Убедитесь, что понимаете каждый фрагмент. Исправьте неточности, добавьте обработку ошибок, рассмотрите граничные случаи и т.п. Никогда не принимайте сгенерированный код вслепую. Относитесь к нему как к требующему код-ревью перед использованием.
2. Используйте ИИ для ускорения, а не для замены
❌ «Напиши код аутентификации пользователей»
✅ «Сгенерируй шаблон функции промежуточного ПО аутентификации»
Первый промпт просит написать код за вас. Второй экономит время на механической работе, сохраняя при этом контроль над архитектурой.
3. Предоставьте контекст, получите лучше результаты
Не просто вставляйте код и просите о помощи. Объясните:
- Чего вы пытаетесь достичь,
- Что вы уже пробовали,
- В каких условиях вы работаете,
- Какие шаблоны используются в вашей кодовой базе.
Лучший ввод → Лучший вывод.
4. Проверяйте всё
Запустите код. Протестируйте его. Прочитайте его. Поймите его. Не используйте сгенерированный ИИ код, который вы не до конца понимаете. Это потенциальная ошибка (или уязвимость безопасности) в будущем.
5. Используйте ИИ для обучения, а не вместо обучения
Когда ИИ генерирует код, который вы не понимаете, попросите его объяснить. Используйте его как инструмент обучения. Не позволяйте ему создавать пробелы в ваших знаниях.
Баланс между развитием навыков и совершенствованием
Парадокс: ИИ может как улучшить, так и ухудшить ваши навыки как разработчика, в зависимости от того, как вы его используете.
- Умело: вы учитесь быстрее, видите больше закономерностей, исследуете больше решений и концентрируете свое время на мышлении более высокого уровня.
- Неумело: вы становитесь зависимым, теряете фундаментальные навыки, не понимаете собственный код и не можете функционировать без инструмента.
Проверка: можете ли вы решить проблему без ИИ? Если нет, вы чрезмерно полагаетесь на него. Используйте ИИ реже для решения аналогичных задач, пока не усвоите закономерности.
Инструменты, которые стоит попробовать
- GitHub Copilot: автозавершение кода. Отлично подходит для шаблонов.
- Cursor: IDE с интеграцией ИИ. Хорош для подсказок, учитывающих особенности кода.
- ChatGPT/Claude: справка в режиме чата для объяснений и отладки.
- Tabnine: альтернатива Copilot, ориентированная на конфиденциальность.
Выберите один. Освойте его. Поймите его сильные и слабые стороны. Не собирайте несколько ИИ-инструментов, не используя ни один из них эффективно.
Подход, ориентированный на будущее
Инструменты ИИ будут совершенствоваться. Они будут писать больше кода. Но они не заменят мыслительную часть разработки ПО — понимание требований, принятие компромиссов, проектирование систем, учёт поддерживаемости и применение здравого смысла.
Сосредоточьтесь на развитии незаменимых навыков:
- Системное проектирование,
- Методология отладки,
- Оценка кода,
- Принятие архитектурных решений,
- Знания предметной области,
- Коммуникация и сотрудничество.
Это навыки, которые инструменты ИИ улучшают, но не могут заменить. Успешными будут не те разработчики, которые смогут наилучшим образом управлять ИИ, а которые будут использовать его для ускорения выполнения механических задач, сохраняя при этом остроту суждений в стратегических вопросах.
Никогда не переставайте думать. Повышение продуктивности достигается за счёт сотрудничества между человеческим разумом и скоростью машины, а не за счёт отказа от ответственности в пользу машины.
Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
Топ Советов по Повышению Продуктивности. Часть 10. Окончание
Начало
Как продуктивно использовать ИИ-инструменты
1. Начните с ИИ, закончите размышлением
Позвольте ИИ сгенерировать черновик. Прочитайте его построчно. Убедитесь, что понимаете каждый фрагмент. Исправьте неточности, добавьте обработку ошибок, рассмотрите граничные случаи и т.п. Никогда не принимайте сгенерированный код вслепую. Относитесь к нему как к требующему код-ревью перед использованием.
2. Используйте ИИ для ускорения, а не для замены
❌ «Напиши код аутентификации пользователей»
✅ «Сгенерируй шаблон функции промежуточного ПО аутентификации»
Первый промпт просит написать код за вас. Второй экономит время на механической работе, сохраняя при этом контроль над архитектурой.
3. Предоставьте контекст, получите лучше результаты
Не просто вставляйте код и просите о помощи. Объясните:
- Чего вы пытаетесь достичь,
- Что вы уже пробовали,
- В каких условиях вы работаете,
- Какие шаблоны используются в вашей кодовой базе.
Лучший ввод → Лучший вывод.
4. Проверяйте всё
Запустите код. Протестируйте его. Прочитайте его. Поймите его. Не используйте сгенерированный ИИ код, который вы не до конца понимаете. Это потенциальная ошибка (или уязвимость безопасности) в будущем.
5. Используйте ИИ для обучения, а не вместо обучения
Когда ИИ генерирует код, который вы не понимаете, попросите его объяснить. Используйте его как инструмент обучения. Не позволяйте ему создавать пробелы в ваших знаниях.
Баланс между развитием навыков и совершенствованием
Парадокс: ИИ может как улучшить, так и ухудшить ваши навыки как разработчика, в зависимости от того, как вы его используете.
- Умело: вы учитесь быстрее, видите больше закономерностей, исследуете больше решений и концентрируете свое время на мышлении более высокого уровня.
- Неумело: вы становитесь зависимым, теряете фундаментальные навыки, не понимаете собственный код и не можете функционировать без инструмента.
Проверка: можете ли вы решить проблему без ИИ? Если нет, вы чрезмерно полагаетесь на него. Используйте ИИ реже для решения аналогичных задач, пока не усвоите закономерности.
Инструменты, которые стоит попробовать
- GitHub Copilot: автозавершение кода. Отлично подходит для шаблонов.
- Cursor: IDE с интеграцией ИИ. Хорош для подсказок, учитывающих особенности кода.
- ChatGPT/Claude: справка в режиме чата для объяснений и отладки.
- Tabnine: альтернатива Copilot, ориентированная на конфиденциальность.
Выберите один. Освойте его. Поймите его сильные и слабые стороны. Не собирайте несколько ИИ-инструментов, не используя ни один из них эффективно.
Подход, ориентированный на будущее
Инструменты ИИ будут совершенствоваться. Они будут писать больше кода. Но они не заменят мыслительную часть разработки ПО — понимание требований, принятие компромиссов, проектирование систем, учёт поддерживаемости и применение здравого смысла.
Сосредоточьтесь на развитии незаменимых навыков:
- Системное проектирование,
- Методология отладки,
- Оценка кода,
- Принятие архитектурных решений,
- Знания предметной области,
- Коммуникация и сотрудничество.
Это навыки, которые инструменты ИИ улучшают, но не могут заменить. Успешными будут не те разработчики, которые смогут наилучшим образом управлять ИИ, а которые будут использовать его для ускорения выполнения механических задач, сохраняя при этом остроту суждений в стратегических вопросах.
Никогда не переставайте думать. Повышение продуктивности достигается за счёт сотрудничества между человеческим разумом и скоростью машины, а не за счёт отказа от ответственности в пользу машины.
Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
👍21
День 2591. #МоиИнструменты #PG
Инструменты Оптимизации Запросов в PostgreSQL. Часть 3
3. EverSQL (ИИ-оптимизатор Запросов)
Что даёт: автоматически переписывает запросы и даёт рекомендации по индексам с использованием ИИ.
Тип: Коммерческий + Бесплатный уровень.
Базы данных: MySQL, PostgreSQL, Aurora.
Зачем нужен: Многие инженеры знают, что запросы можно оптимизировать, но не знают, как. EverSQL использует ИИ для анализа запросов и предложения конкретных оптимизаций — часто находя улучшения, которые упускают из виду люди.
Как работает:
Анализ EverSQL:
1. Отсутствует индекс
2. Порядок JOIN не оптимальный (примените фильтры к customers перед join).
Рекомендованные индексы:
Новое время выполнения: 1.2 секунды (быстрее в 37 раз).
Когда использовать
- Сложные запросы, которые вы не до конца понимаете;
- Устаревший SQL, который «просто работает», но медленно;
- Нужны рекомендации по индексам;
- Хотите изучить методы оптимизации (ИИ объясняет ход рассуждений).
Когда отказаться
- Простые запросы (ручная оптимизация быстрее);
- Неподдерживаемые БД;
- Нужна оптимизация в реальном времени (EverSQL интерактивный/пакетный).
Скрытая функция
Помимо переписывания запросов, EverSQL анализирует схемы таблиц.
Обнаруженные проблемы:
1. Таблица 'orders' имеет 47 столбцов (слишком широкая).
Предложение: разделить на таблицы orders + order_metadata.
2. Столбец 'customer_data' имеет тип JSON (не индексируемый).
Предложение: вынести часто запрашиваемые поля в столбцы.
3. Отсутствует секционирование по 'orders' (500 млн строк).
Предложение: секционирование по order_date (ежемесячно).
Это позволяет выявлять системные проблемы, которые не могут быть исправлены модификацией запросов.
С осторожностью
Предложения ИИ нуждаются в проверке:
EverSQL предложил оптимизацию
Выглядит хорошо, но…
- В нашем случае: 80% запросов используют
- Индекс по
Всегда проверяйте предложения на реальных шаблонах запросов. ИИ не знает вашего конкретного распределения рабочей нагрузки.
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
Инструменты Оптимизации Запросов в PostgreSQL. Часть 3
3. EverSQL (ИИ-оптимизатор Запросов)
Что даёт: автоматически переписывает запросы и даёт рекомендации по индексам с использованием ИИ.
Тип: Коммерческий + Бесплатный уровень.
Базы данных: MySQL, PostgreSQL, Aurora.
Зачем нужен: Многие инженеры знают, что запросы можно оптимизировать, но не знают, как. EverSQL использует ИИ для анализа запросов и предложения конкретных оптимизаций — часто находя улучшения, которые упускают из виду люди.
Как работает:
-- Ввод: Ваш медленный запрос
SELECT o.*, c.name, c.email, p.product_name
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id
WHERE o.order_date >= '2024-01-01'
AND c.country = 'US'
AND o.status = 'completed'
ORDER BY o.order_date DESC
LIMIT 100;
-- Время выполнения: 45 секунд
Анализ EverSQL:
1. Отсутствует индекс
orders(order_date, status, customer_id);2. Порядок JOIN не оптимальный (примените фильтры к customers перед join).
-- Запрос, переписанный EverSQL:
WITH us_customers AS (
SELECT id, name, email
FROM customers
WHERE country = 'US'
)
SELECT o.*, c.name, c.email, p.product_name
FROM orders o
JOIN us_customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id
WHERE o.order_date >= '2024-01-01'
AND o.status = 'completed'
ORDER BY o.order_date DESC
LIMIT 100;
Рекомендованные индексы:
CREATE INDEX idx_orders_opt ON orders(status, order_date DESC, customer_id, product_id);
CREATE INDEX idx_customers_country ON customers(country) INCLUDE (id, name, email);
Новое время выполнения: 1.2 секунды (быстрее в 37 раз).
Когда использовать
- Сложные запросы, которые вы не до конца понимаете;
- Устаревший SQL, который «просто работает», но медленно;
- Нужны рекомендации по индексам;
- Хотите изучить методы оптимизации (ИИ объясняет ход рассуждений).
Когда отказаться
- Простые запросы (ручная оптимизация быстрее);
- Неподдерживаемые БД;
- Нужна оптимизация в реальном времени (EverSQL интерактивный/пакетный).
Скрытая функция
Помимо переписывания запросов, EverSQL анализирует схемы таблиц.
Обнаруженные проблемы:
1. Таблица 'orders' имеет 47 столбцов (слишком широкая).
Предложение: разделить на таблицы orders + order_metadata.
2. Столбец 'customer_data' имеет тип JSON (не индексируемый).
Предложение: вынести часто запрашиваемые поля в столбцы.
3. Отсутствует секционирование по 'orders' (500 млн строк).
Предложение: секционирование по order_date (ежемесячно).
Это позволяет выявлять системные проблемы, которые не могут быть исправлены модификацией запросов.
С осторожностью
Предложения ИИ нуждаются в проверке:
EverSQL предложил оптимизацию
SELECT … FROM orders
WHERE order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
Выглядит хорошо, но…
- В нашем случае: 80% запросов используют
order_date = CURRENT_DATE;- Индекс по
(order_date, …) лучше выражения (DATE_SUB(…));Всегда проверяйте предложения на реальных шаблонах запросов. ИИ не знает вашего конкретного распределения рабочей нагрузки.
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
👍9
День 2591. #Архитектура #ВопросыНаСобеседовании
Проектирование Систем Как Кофейня. Начало
Собеседования по проектированию систем — это «финальный босс» в разработке ПО. Они пугают не потому, что математика сложная, а потому, что холст чистый. Большинство инженеров думают, что проектирование систем — это знание внутренних механизмов Kafka или нюансов Cassandra. Нет. Это искусство ясно мыслить вслух. Мы будем проектировать кофейню. Потому что, если вы можете масштабировать работу кафе, вы сможете масштабировать и распределённую систему.
Секрет: не спешите строить, задавайте вопросы
Представьте, что вы хотите открыть кофейню. Вы не начинаете с покупки эспрессо-машины за $20К и найма 5 барист в первый же день. Так вы обанкротитесь через месяц.
Начинайте с вопросов:
- Сколько человек живёт в районе?
- Это место, куда можно быстро зайти, или место, где можно посидеть и поработать?
- Что происходит в утренний/вечерний час пик?
Системное проектирование работает точно так же.
Вот схема для прохождения интервью:
1. Фаза «уточнения» (не гадайте)
На собеседовании вопрос обычно расплывчатый: «Разработайте Twitter». Дилетант: начинает рисовать «базу данных твитов».
Профессионал: спрашивает: «Для кого? Мы поддерживаем видео? Что важнее: скорость или согласованность?»
Вопросы, которые следует задать:
- Пользователи: Кто этим пользуется?
- Масштаб: 100 человек или 100 миллионов?
- Соотношение: Это ресурс нагрузкой на чтение (скролл ленты) или на запись (публикация)?
- «Атмосфера»: Требуется низкая задержка или высокая согласованность?
2. Определение «Основного меню» (вариантов использования)
Сосредоточьтесь на 3-5 основных действиях. Если вы попытаетесь спроектировать всё сразу, вы не спроектируете ничего.
Для нашего кафе «Основное меню» состоит из следующих элементов:
- Просмотр: Пользователь просматривает меню.
- Заказ: Пользователь размещает заказ.
- Принятие: Бариста видит и принимает заказ.
- Отслеживание: Пользователь получает уведомление, когда заказ готов.
3. Высокоуровневый дизайн («Эскиз на салфетке»)
Теперь нарисуем «большие блоки». Пока не беспокойтесь о виде БД. Просто определите роли.
- Клиент: Делает заказ с телефона.
- Бэкенд (Менеджер): Получает заказ и решает, куда он будет отправлен.
- БД: Постоянная запись о каждом проданном кофе.
- Очередь: Если 50 человек делают заказ одновременно, «Очередь» сохраняет их и ставит в обработку последовательно, чтобы у баристы не случился нервный срыв.
4. Модель данных (Ингредиенты)
Какую информацию нужно хранить? Не усложняйте. Представьте это как «квитанции заказа».
- Пользователь: Имя, Email, Баллы лояльности.
- Продукт: Название напитка, Цена, Ингредиенты.
- Заказ: Отметка времени, Стоимость, Статус (Ожидание/Выполнено).
- Связи: У одного пользователя может быть много заказов. Один заказ может содержать много товаров.
Вот и всё. Не создавайте сложную сеть таблиц, если интервьюер об этом не просит.
5. Обработка «часа-пик» (Масштабирование)
Это та часть интервью, где меняется «атмосфера». Ваше кафе пользуется огромным успехом! Внезапно за дверью оказывается 500 человек. Если вы не измените систему, она рухнет, и все уйдут недовольные.
Окончание следует…
Источник: https://medium.com/@yashgangane987/system-design-is-just-a-coffee-shop-a-stress-free-guide-for-engineers-af3e82dc589e
Проектирование Систем Как Кофейня. Начало
Собеседования по проектированию систем — это «финальный босс» в разработке ПО. Они пугают не потому, что математика сложная, а потому, что холст чистый. Большинство инженеров думают, что проектирование систем — это знание внутренних механизмов Kafka или нюансов Cassandra. Нет. Это искусство ясно мыслить вслух. Мы будем проектировать кофейню. Потому что, если вы можете масштабировать работу кафе, вы сможете масштабировать и распределённую систему.
Секрет: не спешите строить, задавайте вопросы
Представьте, что вы хотите открыть кофейню. Вы не начинаете с покупки эспрессо-машины за $20К и найма 5 барист в первый же день. Так вы обанкротитесь через месяц.
Начинайте с вопросов:
- Сколько человек живёт в районе?
- Это место, куда можно быстро зайти, или место, где можно посидеть и поработать?
- Что происходит в утренний/вечерний час пик?
Системное проектирование работает точно так же.
Вот схема для прохождения интервью:
1. Фаза «уточнения» (не гадайте)
На собеседовании вопрос обычно расплывчатый: «Разработайте Twitter». Дилетант: начинает рисовать «базу данных твитов».
Профессионал: спрашивает: «Для кого? Мы поддерживаем видео? Что важнее: скорость или согласованность?»
Вопросы, которые следует задать:
- Пользователи: Кто этим пользуется?
- Масштаб: 100 человек или 100 миллионов?
- Соотношение: Это ресурс нагрузкой на чтение (скролл ленты) или на запись (публикация)?
- «Атмосфера»: Требуется низкая задержка или высокая согласованность?
2. Определение «Основного меню» (вариантов использования)
Сосредоточьтесь на 3-5 основных действиях. Если вы попытаетесь спроектировать всё сразу, вы не спроектируете ничего.
Для нашего кафе «Основное меню» состоит из следующих элементов:
- Просмотр: Пользователь просматривает меню.
- Заказ: Пользователь размещает заказ.
- Принятие: Бариста видит и принимает заказ.
- Отслеживание: Пользователь получает уведомление, когда заказ готов.
3. Высокоуровневый дизайн («Эскиз на салфетке»)
Теперь нарисуем «большие блоки». Пока не беспокойтесь о виде БД. Просто определите роли.
- Клиент: Делает заказ с телефона.
- Бэкенд (Менеджер): Получает заказ и решает, куда он будет отправлен.
- БД: Постоянная запись о каждом проданном кофе.
- Очередь: Если 50 человек делают заказ одновременно, «Очередь» сохраняет их и ставит в обработку последовательно, чтобы у баристы не случился нервный срыв.
4. Модель данных (Ингредиенты)
Какую информацию нужно хранить? Не усложняйте. Представьте это как «квитанции заказа».
- Пользователь: Имя, Email, Баллы лояльности.
- Продукт: Название напитка, Цена, Ингредиенты.
- Заказ: Отметка времени, Стоимость, Статус (Ожидание/Выполнено).
- Связи: У одного пользователя может быть много заказов. Один заказ может содержать много товаров.
Вот и всё. Не создавайте сложную сеть таблиц, если интервьюер об этом не просит.
5. Обработка «часа-пик» (Масштабирование)
Это та часть интервью, где меняется «атмосфера». Ваше кафе пользуется огромным успехом! Внезапно за дверью оказывается 500 человек. Если вы не измените систему, она рухнет, и все уйдут недовольные.
Окончание следует…
Источник: https://medium.com/@yashgangane987/system-design-is-just-a-coffee-shop-a-stress-free-guide-for-engineers-af3e82dc589e
👍12👎1
День 2592. #Архитектура #ВопросыНаСобеседовании
Проектирование Систем Как Кофейня. Окончание
Начало
Вот как справляться с «наплывом посетителей».
1. Балансировщик нагрузки (Хостесс)
- Аналогия: Вместо того чтобы все одновременно бросались к стойке, вы нанимаете хостесс у входа. Она смотрит на три кассы и говорит: «Вы идете к кассе 1, вы к кассе 2». Она распределяет нагрузку, чтобы ни один бариста не «вышел из строя».
- Технология: Балансировщик нагрузки (например, Nginx или AWS ELB) находится перед вашими серверами. Он направляет входящий трафик на разные экземпляры серверов, чтобы ни один сервер не был перегружен.
2. Кэширование (Готовые продукты)
- Аналогия: Приготовление сэндвича на заказ занимает 5 минут. Если его хотят сразу 50 человек, у вас будут проблемы. Вместо этого вы готовите 50 «популярных» сэндвичей и кладёте их в холодильник. Когда клиент хочет такой сэндвич, он просто берёт его — никакого ожидания.
- Технология: Кэш (например, Redis или Memcached) хранит результаты частых запросов к БД. Если все спрашивают о «Топ-10 самых популярных постов», не нужно обращаться к БД 1000 раз. Храните ответ в памяти для мгновенного доступа.
3. Реплики для чтения (печатные меню)
- Аналогия: Если у вас одно большое меню за стойкой, всем приходится стоять в одном месте, чтобы его прочитать, создавая узкое место. Вместо этого напечатайте 100 бумажных меню и раздайте их посетителям. Теперь все могут читать меню одновременно.
- Технология: Реплики для чтения — это копии основной БД. Основная БД делает ресурсоёмкую работу (прием заказов/запись данных), а «реплики» обрабатывают трафик «чтения» (просмотр профилей или меню). Это предотвращает перегрузку основной БД.
4. Асинхронная обработка (сигнал о готовности заказа)
- Аналогия: Вы не заставляете клиента стоять у кассы, пока готовится его сложный латте. Вы даёте ему метку и предлагаете сесть. «Заказ» оформлен, и бариста работает над ним в фоновом режиме.
- Технология: очередь сообщений (как Kafka или RabbitMQ). Пользователь немедленно получает ответ «202 Accepted», а интенсивная обработка происходит в фоновом режиме, не вызывая «зависания» приложения для пользователя во время ожидания.
Компромиссы
В проектировании систем нет правильных ответов, есть только компромиссы. Если вы сделаете кофейню очень быстрой (предварительно приготовите 100 латте), качество может снизиться (кофе остынет). Если вы сделаете её высококачественной (готовить только под заказ), люди будут стоять час в очереди. «Мы могли бы добавить кэш, чтобы ускорить процесс, но тогда меню может устаревать на несколько секунд. Для кафе это, вероятно, приемлемо».
Вот как бы мы представили «процесс заказа» на собеседовании:
- Запрос: Клиент нажимает «Заказать» в телефоне.
- Ввод: Запрос поступает на балансировщик нагрузки, который отправляет его на доступный веб-сервер.
- Запись: Сервер сохраняет заказ в БД (статус: «Ожидание»).
- Передача: Сервер помещает заказ в очередь сообщений (например, RabbitMQ или Kafka).
- Действие: Бариста (потребитель очереди) видит заказ у себя в системе и начинает его готовить.
- Уведомление: Бариста нажимает «Готово», обновляя БД и отправляя уведомление пользователю.
Распространенные ошибки
- Переход к «Как» до «Что»: не говорите «Я буду использовать AWS Lambda», даже не определив, что делает приложение.
- Избыточное усложнение: не проектируйте систему для миллиарда пользователей, если интервьюер попросил создать приложение для вашего района. Это покажет не ваш ум, вашу расточительность.
- Молчание: если вы молчите, вы не пройдёте собеседование.
Итого
Проектировать системы не значит быть ходячей энциклопедией технических инструментов. Это значит уметь решать проблемы. В следующий раз на собеседовании сделайте глубокий вдох, представьте, что вы просто пытаетесь быстро доставить кофе клиенту, и начните задавать вопросы.
Источник: https://medium.com/@yashgangane987/system-design-is-just-a-coffee-shop-a-stress-free-guide-for-engineers-af3e82dc589e
Проектирование Систем Как Кофейня. Окончание
Начало
Вот как справляться с «наплывом посетителей».
1. Балансировщик нагрузки (Хостесс)
- Аналогия: Вместо того чтобы все одновременно бросались к стойке, вы нанимаете хостесс у входа. Она смотрит на три кассы и говорит: «Вы идете к кассе 1, вы к кассе 2». Она распределяет нагрузку, чтобы ни один бариста не «вышел из строя».
- Технология: Балансировщик нагрузки (например, Nginx или AWS ELB) находится перед вашими серверами. Он направляет входящий трафик на разные экземпляры серверов, чтобы ни один сервер не был перегружен.
2. Кэширование (Готовые продукты)
- Аналогия: Приготовление сэндвича на заказ занимает 5 минут. Если его хотят сразу 50 человек, у вас будут проблемы. Вместо этого вы готовите 50 «популярных» сэндвичей и кладёте их в холодильник. Когда клиент хочет такой сэндвич, он просто берёт его — никакого ожидания.
- Технология: Кэш (например, Redis или Memcached) хранит результаты частых запросов к БД. Если все спрашивают о «Топ-10 самых популярных постов», не нужно обращаться к БД 1000 раз. Храните ответ в памяти для мгновенного доступа.
3. Реплики для чтения (печатные меню)
- Аналогия: Если у вас одно большое меню за стойкой, всем приходится стоять в одном месте, чтобы его прочитать, создавая узкое место. Вместо этого напечатайте 100 бумажных меню и раздайте их посетителям. Теперь все могут читать меню одновременно.
- Технология: Реплики для чтения — это копии основной БД. Основная БД делает ресурсоёмкую работу (прием заказов/запись данных), а «реплики» обрабатывают трафик «чтения» (просмотр профилей или меню). Это предотвращает перегрузку основной БД.
4. Асинхронная обработка (сигнал о готовности заказа)
- Аналогия: Вы не заставляете клиента стоять у кассы, пока готовится его сложный латте. Вы даёте ему метку и предлагаете сесть. «Заказ» оформлен, и бариста работает над ним в фоновом режиме.
- Технология: очередь сообщений (как Kafka или RabbitMQ). Пользователь немедленно получает ответ «202 Accepted», а интенсивная обработка происходит в фоновом режиме, не вызывая «зависания» приложения для пользователя во время ожидания.
Компромиссы
В проектировании систем нет правильных ответов, есть только компромиссы. Если вы сделаете кофейню очень быстрой (предварительно приготовите 100 латте), качество может снизиться (кофе остынет). Если вы сделаете её высококачественной (готовить только под заказ), люди будут стоять час в очереди. «Мы могли бы добавить кэш, чтобы ускорить процесс, но тогда меню может устаревать на несколько секунд. Для кафе это, вероятно, приемлемо».
Вот как бы мы представили «процесс заказа» на собеседовании:
- Запрос: Клиент нажимает «Заказать» в телефоне.
- Ввод: Запрос поступает на балансировщик нагрузки, который отправляет его на доступный веб-сервер.
- Запись: Сервер сохраняет заказ в БД (статус: «Ожидание»).
- Передача: Сервер помещает заказ в очередь сообщений (например, RabbitMQ или Kafka).
- Действие: Бариста (потребитель очереди) видит заказ у себя в системе и начинает его готовить.
- Уведомление: Бариста нажимает «Готово», обновляя БД и отправляя уведомление пользователю.
Распространенные ошибки
- Переход к «Как» до «Что»: не говорите «Я буду использовать AWS Lambda», даже не определив, что делает приложение.
- Избыточное усложнение: не проектируйте систему для миллиарда пользователей, если интервьюер попросил создать приложение для вашего района. Это покажет не ваш ум, вашу расточительность.
- Молчание: если вы молчите, вы не пройдёте собеседование.
Итого
Проектировать системы не значит быть ходячей энциклопедией технических инструментов. Это значит уметь решать проблемы. В следующий раз на собеседовании сделайте глубокий вдох, представьте, что вы просто пытаетесь быстро доставить кофе клиенту, и начните задавать вопросы.
Источник: https://medium.com/@yashgangane987/system-design-is-just-a-coffee-shop-a-stress-free-guide-for-engineers-af3e82dc589e
👍14
День 2593. #ВопросыНаСобеседовании
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
25. Стандарты документации
«Можете ли вы рассказать о важности документации в разработке и какие инструменты могут быть использованы (или какими пользовались вы) для улучшения проектной документации?»
Хороший ответ
Стандарты документации имеют решающее значение в .NET разработке, поскольку они гарантируют, что все члены команды, заинтересованные стороны и будущие разработчики смогут эффективно понимать архитектуру, использование и аспекты обслуживания ПО. Соблюдение стандартов документации помогает поддерживать согласованность, сокращать время адаптации новых разработчиков и повышать читаемость и удобство использования кода.
DocFX — это инструмент, который может генерировать документацию API непосредственно из исходного кода .NET, а также создавать дополнительный контент, поддерживающий Markdown. Он легко интегрируется с проектами .NET и предоставляет такие функции, как версионирование, полнотекстовый поиск и поддержка нескольких форматов вывода (например, HTML, PDF).
Разметка Mermaid позволяет создавать диаграммы и визуализации с использованием синтаксиса, похожего на Markdown, что чрезвычайно полезно для добавления визуальных средств в документацию. Это могут быть диаграммы, показывающие архитектуру системы, потоки процессов или другие важные детали проекта. Интеграция Mermaid в систему документации позволяет разработчикам поддерживать сложные диаграммы как код, который проще версионировать и изменять по сравнению с традиционными графическими файлами.
Благодаря включению таких инструментов, как DocFX и Mermaid, команда разработчиков .NET, может автоматизировать большую часть процесса документирования, обеспечивая актуальность документации в соответствии с кодовой базой. Это особенно ценно в гибких средах разработки, где изменения происходят часто, и поддержание соответствия документации программному обеспечению представляет собой сложную задачу.
Часто встречающийся плохой ответ
«Документация на самом деле не нужна, если код написан хорошо. Хороший код должен быть самодокументируемым, а документация быстро устаревает, поэтому часто является пустой тратой ресурсов.»
Почему это неправильно
- Недооценка ценности документации: ответ недооценивает важность документации. Хотя хорошо написанный код необходим, документация служит более широким целям, таким как объяснение проектных решений, предоставление инструкций по настройке и подробное описание сценариев использования, которые не сразу очевидны из кода.
- Игнорирование заинтересованных сторон, не являющихся разработчиками: в ответе не учитывается, что заинтересованные стороны, участвующие в проекте, могут не быть разработчиками и нуждаться в высокоуровневой документации для понимания системы.
- Пренебрежение поддержкой и масштабируемостью: Документация имеет решающее значение для долгосрочной поддержки и масштабируемости ПО. Она гарантирует, что система может эффективно поддерживаться и расширяться, даже если состав команды меняется со временем.
Это заблуждение часто возникает из-за слишком узкого взгляда на разработку, где непосредственная практическая польза от написания кода ставится выше долгосрочных преимуществ тщательной документации. Такой подход может привести к значительным проблемам в поддержке и масштабировании ПО, особенно когда сложность возрастает, и первоначальные члены команды переходят к другим проектам.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
25. Стандарты документации
«Можете ли вы рассказать о важности документации в разработке и какие инструменты могут быть использованы (или какими пользовались вы) для улучшения проектной документации?»
Хороший ответ
Стандарты документации имеют решающее значение в .NET разработке, поскольку они гарантируют, что все члены команды, заинтересованные стороны и будущие разработчики смогут эффективно понимать архитектуру, использование и аспекты обслуживания ПО. Соблюдение стандартов документации помогает поддерживать согласованность, сокращать время адаптации новых разработчиков и повышать читаемость и удобство использования кода.
DocFX — это инструмент, который может генерировать документацию API непосредственно из исходного кода .NET, а также создавать дополнительный контент, поддерживающий Markdown. Он легко интегрируется с проектами .NET и предоставляет такие функции, как версионирование, полнотекстовый поиск и поддержка нескольких форматов вывода (например, HTML, PDF).
Разметка Mermaid позволяет создавать диаграммы и визуализации с использованием синтаксиса, похожего на Markdown, что чрезвычайно полезно для добавления визуальных средств в документацию. Это могут быть диаграммы, показывающие архитектуру системы, потоки процессов или другие важные детали проекта. Интеграция Mermaid в систему документации позволяет разработчикам поддерживать сложные диаграммы как код, который проще версионировать и изменять по сравнению с традиционными графическими файлами.
Благодаря включению таких инструментов, как DocFX и Mermaid, команда разработчиков .NET, может автоматизировать большую часть процесса документирования, обеспечивая актуальность документации в соответствии с кодовой базой. Это особенно ценно в гибких средах разработки, где изменения происходят часто, и поддержание соответствия документации программному обеспечению представляет собой сложную задачу.
Часто встречающийся плохой ответ
«Документация на самом деле не нужна, если код написан хорошо. Хороший код должен быть самодокументируемым, а документация быстро устаревает, поэтому часто является пустой тратой ресурсов.»
Почему это неправильно
- Недооценка ценности документации: ответ недооценивает важность документации. Хотя хорошо написанный код необходим, документация служит более широким целям, таким как объяснение проектных решений, предоставление инструкций по настройке и подробное описание сценариев использования, которые не сразу очевидны из кода.
- Игнорирование заинтересованных сторон, не являющихся разработчиками: в ответе не учитывается, что заинтересованные стороны, участвующие в проекте, могут не быть разработчиками и нуждаться в высокоуровневой документации для понимания системы.
- Пренебрежение поддержкой и масштабируемостью: Документация имеет решающее значение для долгосрочной поддержки и масштабируемости ПО. Она гарантирует, что система может эффективно поддерживаться и расширяться, даже если состав команды меняется со временем.
Это заблуждение часто возникает из-за слишком узкого взгляда на разработку, где непосредственная практическая польза от написания кода ставится выше долгосрочных преимуществ тщательной документации. Такой подход может привести к значительным проблемам в поддержке и масштабировании ПО, особенно когда сложность возрастает, и первоначальные члены команды переходят к другим проектам.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
👎9👍2
День 2594. #Карьера
Быть «Просто Разработчиком» Уже Недостаточно
Последние пару десятилетий быть разработчиком было… комфортно. Вы решали проблемы, выпускали код и получали за это хорошую оплату. Не нужно было беспокоиться, зачем существует бизнес или как зарабатываются деньги. Времена изменились…
К 2025му ИИ перестал быть игрушкой и стал настоящим коллегой. Это не замена (пока), но определенно нарушитель спокойствия. Броня «я умею программировать» быстро истощается. Написание кода больше не волшебство. Чисто техническое исполнение больше не является долгосрочным преимуществом.
ИИ — это множитель силы, и теперь доступ к ИИ есть у всех. Общая планка для ПО поднимается, и настоящим победителем здесь становятся пользователи (надеюсь). Но есть подвох. Когда каждый может создавать быстрее, одного создания уже недостаточно. Так как же оставаться ценным?
Вы не перестаёте быть разработчиком. Вы перестаёте быть «просто разработчиком».
1. Знание домена — ваша новая броня
Долгие годы многие разработчики с гордостью говорили: «Сосредоточусь на коде. Пусть бизнесмены занимаются бизнесом». Это больше не работает. Понимание бизнеса, для которого вы разрабатываете продукт, теперь серьезное конкурентное преимущество. Метрики, стимулы, ограничения, клиенты, правила — все эти непривлекательные вещи.
Даже отличного инженера, живущего в отрыве от бизнес-домена, легко заменить, сейчас как никогда. А разработчика, который действительно понимает, скажем, финтех (почему всё строится именно так, профессиональный жаргон, что волнует регуляторов и т.п.) – поместите его в другую финтех-компанию, и он будет продуктивен еще до того, как будут готовы документы по адаптации.
ИИ становится хорош в написании и рефакторинге кода. Но бизнес по-прежнему строится на людях — их мотивах, страхах, ограничениях и политических взглядах. Именно здесь у людей (ВАС) по-прежнему есть преимущество.
2. Расширяйте горизонты, а не просто углубляйтесь
Долгое время совет был прост: специализируйтесь. Изучите фреймворк, освойте стек. Глубокая экспертиза по-прежнему ценна, но сама по себе она уже недостаточна.
Сейчас проще, чем когда-либо, мыслить (и делать) как full-stack, создавать от А до Я. Не нужно знать всё. ИИ может заполнить пробелы за вас. Знание DevOps, безопасности, производительности и надёжности поддерживает работоспособность приложений и сохраняет вашу ценность. ИИ может создавать новые функции, но не справится со сбоем в полночь и не гарантирует, что приложение действительно будет работать у пользователей. Разработчики, способные управлять сложной и непредсказуемой стороной работы ПО, останутся незаменимыми.
Думайте, как специалист по продукту. Понимайте основы маркетинга, чтобы ваша работа действительно доходила до людей, научитесь общаться с пользователями.
3. Создавайте свои приложения
Когда вы берёте на себя ответственность за весь жизненный цикл продукта, хостинг, ценообразование, адаптация и маркетинг, ваше мировоззрение меняется. Это делает вас востребованным разработчиком, но также готовит вас к жизни, где вам вообще не нужен рынок труда. И ИИ делает это более осуществимым, чем когда-либо. То, что раньше казалось непосильной задачей, теперь достижимо, даже при наличии работы на полный рабочий день.
Итого
Для разработчиков это действительно экзистенциальный момент. Это не кризис профессии; это эволюция должностной инструкции разработчика. Базовый уровень изменился. Успех теперь требует большего, чем просто быть «техническим специалистом». Он требует способности видеть всю картину целиком, перестать рассматривать код как конечный продукт и начать видеть его как один из инструментов в большом наборе, используемом для решения бизнес-задачи.
Источник: https://saasykit.com/blog/being-just-a-developer-isnt-enough-anymore
Быть «Просто Разработчиком» Уже Недостаточно
Последние пару десятилетий быть разработчиком было… комфортно. Вы решали проблемы, выпускали код и получали за это хорошую оплату. Не нужно было беспокоиться, зачем существует бизнес или как зарабатываются деньги. Времена изменились…
К 2025му ИИ перестал быть игрушкой и стал настоящим коллегой. Это не замена (пока), но определенно нарушитель спокойствия. Броня «я умею программировать» быстро истощается. Написание кода больше не волшебство. Чисто техническое исполнение больше не является долгосрочным преимуществом.
ИИ — это множитель силы, и теперь доступ к ИИ есть у всех. Общая планка для ПО поднимается, и настоящим победителем здесь становятся пользователи (надеюсь). Но есть подвох. Когда каждый может создавать быстрее, одного создания уже недостаточно. Так как же оставаться ценным?
Вы не перестаёте быть разработчиком. Вы перестаёте быть «просто разработчиком».
1. Знание домена — ваша новая броня
Долгие годы многие разработчики с гордостью говорили: «Сосредоточусь на коде. Пусть бизнесмены занимаются бизнесом». Это больше не работает. Понимание бизнеса, для которого вы разрабатываете продукт, теперь серьезное конкурентное преимущество. Метрики, стимулы, ограничения, клиенты, правила — все эти непривлекательные вещи.
Даже отличного инженера, живущего в отрыве от бизнес-домена, легко заменить, сейчас как никогда. А разработчика, который действительно понимает, скажем, финтех (почему всё строится именно так, профессиональный жаргон, что волнует регуляторов и т.п.) – поместите его в другую финтех-компанию, и он будет продуктивен еще до того, как будут готовы документы по адаптации.
ИИ становится хорош в написании и рефакторинге кода. Но бизнес по-прежнему строится на людях — их мотивах, страхах, ограничениях и политических взглядах. Именно здесь у людей (ВАС) по-прежнему есть преимущество.
2. Расширяйте горизонты, а не просто углубляйтесь
Долгое время совет был прост: специализируйтесь. Изучите фреймворк, освойте стек. Глубокая экспертиза по-прежнему ценна, но сама по себе она уже недостаточна.
Сейчас проще, чем когда-либо, мыслить (и делать) как full-stack, создавать от А до Я. Не нужно знать всё. ИИ может заполнить пробелы за вас. Знание DevOps, безопасности, производительности и надёжности поддерживает работоспособность приложений и сохраняет вашу ценность. ИИ может создавать новые функции, но не справится со сбоем в полночь и не гарантирует, что приложение действительно будет работать у пользователей. Разработчики, способные управлять сложной и непредсказуемой стороной работы ПО, останутся незаменимыми.
Думайте, как специалист по продукту. Понимайте основы маркетинга, чтобы ваша работа действительно доходила до людей, научитесь общаться с пользователями.
3. Создавайте свои приложения
Когда вы берёте на себя ответственность за весь жизненный цикл продукта, хостинг, ценообразование, адаптация и маркетинг, ваше мировоззрение меняется. Это делает вас востребованным разработчиком, но также готовит вас к жизни, где вам вообще не нужен рынок труда. И ИИ делает это более осуществимым, чем когда-либо. То, что раньше казалось непосильной задачей, теперь достижимо, даже при наличии работы на полный рабочий день.
Итого
Для разработчиков это действительно экзистенциальный момент. Это не кризис профессии; это эволюция должностной инструкции разработчика. Базовый уровень изменился. Успех теперь требует большего, чем просто быть «техническим специалистом». Он требует способности видеть всю картину целиком, перестать рассматривать код как конечный продукт и начать видеть его как один из инструментов в большом наборе, используемом для решения бизнес-задачи.
Источник: https://saasykit.com/blog/being-just-a-developer-isnt-enough-anymore
👍29
День 2595. #ЗаметкиНаПолях
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Начало
Каждый проект начинается с благих намерений. Вы согласовываете границы слоёв, соглашения об именовании, направление зависимостей. Через полгода кто-то переносит доменный сервис в проект инфраструктуры, обработчик получает имя не по соглашению или внутренний класс становится публичным, потому что это значение по умолчанию. Архитектурные тесты предотвращают это. Они превращают архитектурные правила в автоматизированные тесты, которые запускаются в CI. Вот архитектурные тесты, которые пригодятся каждому проекту.
ArchUnitNET - позволяет писать архитектурные правила, используя fluent API, и запускать их как обычные тесты. Для примера будем использовать xUnit, хотя поддерживаются и другие фреймворки:
Нужен базовый класс, который загружает все сборки, которые мы хотим протестировать. Каждый слой получает «тип привязки» для получения ссылки на сборку во время компиляции:
ArchLoader сканирует сборки и создает в памяти модель всех типов и их зависимостей.
Каждый тестовый класс наследует от BaseTest.
1. Тесты зависимостей слоёв
Внутренние слои в чистой архитектуре не должны ссылаться на внешние. В большинстве конфигураций чистой архитектуры ссылки на проекты уже предотвращают очевидные нарушения. Вы не можете добавить ссылку из приложения в инфраструктуру, т.к. инфраструктура уже ссылается на приложение, и компилятор не допустит циклических зависимостей.
Но тесты всё равно нужны, т.к. ссылки на проекты — не единственный способ проникновения зависимостей. NuGet, используемый в инфраструктуре, может содержать типы, которые проникают в приложение через транзитивные ссылки. Кто-то может реорганизовать решение и изменить граф ссылок проекта. Тесты — страховочная сетка и в то же время документальное подтверждение задуманной архитектуры.
Добавьте тесты для всех неверных направлений зависимостей.
Fluent API читается как английский язык: «Типы, находящиеся в доменном слое, не должны зависеть от каких-либо типов в прикладном слое». При возникновении нарушения тест точно указывает, какой тип от какого зависит.
Вы также можете расширить его. Например, добавить тесты, что определённые пространства имен внутри слоя не могут ссылаться друг на друга (например, Application.Orders не должны зависеть от Application.Users). Это может быть отлично для обеспечения вертикальной архитектуры, где каждая функция самодостаточна, или внутри модульного монолита, где модули не должны зависеть друг от друга.
Продолжение следует…
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Начало
Каждый проект начинается с благих намерений. Вы согласовываете границы слоёв, соглашения об именовании, направление зависимостей. Через полгода кто-то переносит доменный сервис в проект инфраструктуры, обработчик получает имя не по соглашению или внутренний класс становится публичным, потому что это значение по умолчанию. Архитектурные тесты предотвращают это. Они превращают архитектурные правила в автоматизированные тесты, которые запускаются в CI. Вот архитектурные тесты, которые пригодятся каждому проекту.
ArchUnitNET - позволяет писать архитектурные правила, используя fluent API, и запускать их как обычные тесты. Для примера будем использовать xUnit, хотя поддерживаются и другие фреймворки:
dotnet add package TngTech.ArchUnitNET.xUnit
Нужен базовый класс, который загружает все сборки, которые мы хотим протестировать. Каждый слой получает «тип привязки» для получения ссылки на сборку во время компиляции:
public abstract class BaseTest
{
protected static readonly Assembly
DomainAssembly = typeof(User).Assembly;
protected static readonly Assembly
ApplicationAssembly = typeof(ICommand).Assembly;
// … аналогично остальные сборки
protected static readonly Architecture
Architecture = new ArchLoader()
.LoadAssemblies(
DomainAssembly,
ApplicationAssembly,
…)
.Build();
}
ArchLoader сканирует сборки и создает в памяти модель всех типов и их зависимостей.
Каждый тестовый класс наследует от BaseTest.
1. Тесты зависимостей слоёв
Внутренние слои в чистой архитектуре не должны ссылаться на внешние. В большинстве конфигураций чистой архитектуры ссылки на проекты уже предотвращают очевидные нарушения. Вы не можете добавить ссылку из приложения в инфраструктуру, т.к. инфраструктура уже ссылается на приложение, и компилятор не допустит циклических зависимостей.
Но тесты всё равно нужны, т.к. ссылки на проекты — не единственный способ проникновения зависимостей. NuGet, используемый в инфраструктуре, может содержать типы, которые проникают в приложение через транзитивные ссылки. Кто-то может реорганизовать решение и изменить граф ссылок проекта. Тесты — страховочная сетка и в то же время документальное подтверждение задуманной архитектуры.
public class LayerTests : BaseTest
{
private static readonly
IObjectProvider<IType> DomainLayer =
Types()
.That()
.ResideInAssembly(DomainAssembly)
.As("Domain layer");
private static readonly
IObjectProvider<IType> ApplicationLayer =
Types()
.That()
.ResideInAssembly(ApplicationAssembly)
.As("Application layer");
//…
[Fact]
public void Domain_ShouldNotDependOn_Application ()
{
Types().That().Are(DomainLayer).Should()
.NotDependOnAny(ApplicationLayer)
.Check(Architecture);
}
// … аналогично тесты остальных слоёв
}
Добавьте тесты для всех неверных направлений зависимостей.
Fluent API читается как английский язык: «Типы, находящиеся в доменном слое, не должны зависеть от каких-либо типов в прикладном слое». При возникновении нарушения тест точно указывает, какой тип от какого зависит.
Вы также можете расширить его. Например, добавить тесты, что определённые пространства имен внутри слоя не могут ссылаться друг на друга (например, Application.Orders не должны зависеть от Application.Users). Это может быть отлично для обеспечения вертикальной архитектуры, где каждая функция самодостаточна, или внутри модульного монолита, где модули не должны зависеть друг от друга.
Продолжение следует…
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
👍17
День 2596. #ЗаметкиНаПолях
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Продолжение
Начало
2. Проверка правил именования
Этот пункт может показаться незначительным, но несогласованности быстро накапливаются. ArchUnitNET позволяет обеспечивать соблюдение правил именования, выбирая классы на основе интерфейсов, которые они реализуют:
Проверка валидатора работает в обратном направлении. Она говорит: «классы, заканчивающиеся на Validator, должны находиться в сборке Application». Иногда валидаторы случайно размещают в инфраструктуре.
3. Тесты на размещение в одном пространстве имён
При использовании CQRS вы получаете пары: команду (или запрос) и её обработчик. Их полезно хранить в одном пространстве имен, чтобы всё для конкретного варианта использования существовало вместе.
Этот тест не использует ArchUnitNET. Он использует чистую рефлексию в сочетании с
GetHandlerAndCommandPairs сканирует сборку Application, находит все классы, реализующие интерфейс обработчика, извлекает тип команды/запроса из обобщённого аргумента и возвращает пары для проверки в тесте. Сюда же можно добавить типы запросов и ответов, валидаторы - всё, что должно быть размещено в одном месте.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Продолжение
Начало
2. Проверка правил именования
Этот пункт может показаться незначительным, но несогласованности быстро накапливаются. ArchUnitNET позволяет обеспечивать соблюдение правил именования, выбирая классы на основе интерфейсов, которые они реализуют:
public class NamingTests : BaseTest
{
[Fact]
public void Controllers_ShouldEndWith_Controller()
{
Classes().That()
.AreAssignableTo(typeof(Controller))
.Should().HaveNameEndingWith("Controller")
.Check(Application);
}
[Fact]
public void Validators_ShouldEndWith_Validator()
{
Classes().That()
.HaveNameEndingWith("Validator")
.Should().ResideInAssembly(ApplicationAssembly)
.Check(Architecture);
}
}
Проверка валидатора работает в обратном направлении. Она говорит: «классы, заканчивающиеся на Validator, должны находиться в сборке Application». Иногда валидаторы случайно размещают в инфраструктуре.
3. Тесты на размещение в одном пространстве имён
При использовании CQRS вы получаете пары: команду (или запрос) и её обработчик. Их полезно хранить в одном пространстве имен, чтобы всё для конкретного варианта использования существовало вместе.
Application.TodoItems.Create будет содержать как CreateTodoItemCommand, так и CreateTodoItemCommandHandler. Но ничто не мешает кому-либо перемещать эти классы:public class ColocationTests : BaseTest
{
[Theory]
[MemberData(nameof(GetHandlerAndCommandPairs))]
public void Handlers_ShouldBeWithCommandOrQuery(
Type handlerType,
Type commandType)
{
handlerType.Namespace.ShouldBe(
commandType.Namespace,
$"{handlerType.Name} должен быть в одном пространстве имён с {commandType.Name}");
}
public static TheoryData<Type, Type>
GetHandlerAndCommandPairs()
{
Type[] handlerInterfaces =
[
typeof(ICommandHandler<>),
typeof(IQueryHandler<,>)
];
var pairs = new TheoryData<Type, Type>();
var handlers = ApplicationAssembly
.GetTypes()
.Where(t => t is { IsClass: true, IsAbstract: false, IsGenericTypeDefinition: false })
.Where(t => t.DeclaringType is null);
foreach (Type handler in handlers)
{
foreach (Type iface in handler.GetInterfaces())
{
if (!iface.IsGenericType)
continue;
var genDef = iface.GetGenericTypeDefinition();
if (!handlerInterfaces.Contains(genDef))
continue;
var commandType = iface.GetGenericArguments()[0];
pairs.Add(handler, commandOrQueryType);
}
}
return pairs;
}
}
Этот тест не использует ArchUnitNET. Он использует чистую рефлексию в сочетании с
[Theory] и [MemberData] из xUnit. ArchUnitNET не может выразить правило типа «этот класс должен находиться в том же пространстве имен, что и аргумент обобщённого типа его интерфейса». Поэтому мы прибегаем к рефлексии.GetHandlerAndCommandPairs сканирует сборку Application, находит все классы, реализующие интерфейс обработчика, извлекает тип команды/запроса из обобщённого аргумента и возвращает пары для проверки в тесте. Сюда же можно добавить типы запросов и ответов, валидаторы - всё, что должно быть размещено в одном месте.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
👍2
День 2597. #ЗаметкиНаПолях
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Окончание
Начало
Продолжение
4. Тесты видимости
Обработчики команд и запросов — это детали реализации. Они разрешаются через внедрение зависимостей, на них нет прямых ссылок. Но большинство разработчиков по умолчанию делают их публичными. Это просто привычка. Проблема в том, что на публичный обработчик можно напрямую ссылаться из другого слоя, минуя созданные вами абстракции:
Если вас беспокоит, что DI не обнаружит внутренние классы, не волнуйтесь. Сканирование сборок обнаруживает их без проблем. Вы можете распространить это и на другие типы. Например, гарантировать, что конфигурации EF Core являются внутренними, поскольку нет причин, по которым
5. Тесты защиты от зависимостей
Тесты уровня защиты предотвращают ссылки на ваши собственные сборки. Но библиотеки инфраструктуры могут проникать через транзитивные ссылки NuGet. Ваш уровень предметной области не должен знать об Entity Framework. Ваш уровень приложения не должен знать о Npgsql. Компилятор не предотвратит этого, если пакет доступен транзитивно:
Добавьте все библиотеки, которые подходят для вашего проекта.
Итого
Архитектурные правила, существующие только в документации, будут нарушены. Вопрос только, когда. Все эти тесты выполняются за миллисекунды и не требуют никакой инфраструктуры. Они располагаются рядом с вашими модульными тестами и запускаются при каждой сборке. Архитектурные тесты — это страховочная сеть, которая выявляет нарушения до того, как они попадут в продакшн. Начните с тестов зависимостей слоёв. Их настройка занимает пять минут, и они выявляют наиболее опасные нарушения. Затем добавьте остальные по мере роста вашей кодовой базы.
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Окончание
Начало
Продолжение
4. Тесты видимости
Обработчики команд и запросов — это детали реализации. Они разрешаются через внедрение зависимостей, на них нет прямых ссылок. Но большинство разработчиков по умолчанию делают их публичными. Это просто привычка. Проблема в том, что на публичный обработчик можно напрямую ссылаться из другого слоя, минуя созданные вами абстракции:
public class VisibilityTests : BaseTest
{
[Fact]
public void CommandHandlers_ShouldBeInternal()
{
Classes().That()
.ImplementInterface(typeof(ICommandHandler<>))
.Should().BeInternal()
.Check(Architecture);
}
[Fact]
public void QueryHandlers_ShouldBeInternal()
{
Classes().That()
.ImplementInterface(typeof(IQueryHandler<,>))
.Should().BeInternal()
.Check(Architecture);
}
}
Если вас беспокоит, что DI не обнаружит внутренние классы, не волнуйтесь. Сканирование сборок обнаруживает их без проблем. Вы можете распространить это и на другие типы. Например, гарантировать, что конфигурации EF Core являются внутренними, поскольку нет причин, по которым
OrderConfiguration должен быть виден за пределами инфраструктуры.5. Тесты защиты от зависимостей
Тесты уровня защиты предотвращают ссылки на ваши собственные сборки. Но библиотеки инфраструктуры могут проникать через транзитивные ссылки NuGet. Ваш уровень предметной области не должен знать об Entity Framework. Ваш уровень приложения не должен знать о Npgsql. Компилятор не предотвратит этого, если пакет доступен транзитивно:
public class DependencyGuardTests : BaseTest
{
[Fact]
public void Domain_ShouldNotDependOn_EF()
{
Types().That()
.ResideInAssembly(DomainAssembly).Should()
.NotDependOnAnyTypesThat()
.ResideInNamespace("Microsoft.EntityFrameworkCore")
.Check(Architecture);
}
}
Добавьте все библиотеки, которые подходят для вашего проекта.
Итого
Архитектурные правила, существующие только в документации, будут нарушены. Вопрос только, когда. Все эти тесты выполняются за миллисекунды и не требуют никакой инфраструктуры. Они располагаются рядом с вашими модульными тестами и запускаются при каждой сборке. Архитектурные тесты — это страховочная сеть, которая выявляет нарушения до того, как они попадут в продакшн. Начните с тестов зависимостей слоёв. Их настройка занимает пять минут, и они выявляют наиболее опасные нарушения. Затем добавьте остальные по мере роста вашей кодовой базы.
Источник: https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
👍4
День 2598. #ЗаметкиНаПолях
Мы Создали Слой Кэша. PostgreSQL Показал, что Зря.
Пользователь открывает страницу свего тарифного плана, а видит старый. Он обновляет страницу, и всё исправляется. Наш показатель попадания в кэш 98%, а мы всё равно выглядели некомпетентными. В тот момент мы перестали рассматривать кэширование как функцию повышения производительности и стали рассматривать его как проблему истинности. Потому что система перестала быть медленной, зато она стала ненадёжной.
Ошибка, которая не воспроизводится
Ничего не ломалось постоянно. Приходила жалоба в службу поддержки: цифры менялись после обновления. Коллега воспроизводил это один раз, а потом больше никогда. Отдел QC спрашивал, как это протестировать, и лучшим ответом было – хз, зависит от кэша.
Слой кэширования, которым мы гордились
Мы не просто вставили Redis и стали надеяться на лучшее. Мы регистрировали промахи, измеряли частоту попаданий, использовали TTL, создали правило, что каждая запись должна удалять связанные ключи. А потом реальность посмеялась над нами.
Одной конечной точке требовались данные пользователя, разрешения, метка сегмента и флаги функций. Каждая часть имела свой ключ и
свой TTL, и все части обновлялись с разной частотой. Мы сшили их вместе во время чтения и заметили, что это работает достаточно быстро - первая ложь. Вторая ложь: высокая частота попаданий в кэш создавала у нас чувство безопасности. Штука в том, что это может скрывать проблемы в БД.
Часть, о которой никто не говорит
Кэширование не просто увеличивает скорость. Оно добавляет новое поле для ошибок. Сложность не в хранении байтов. Сложность в определении, что означают эти байты, когда мир меняется. Обновление плана, изменение роли, переключение флага… В БД это отражается как факты, а в кэше… не понятно. Мы не снижали нагрузку, мы увеличивали неопределённость.
Наш ключ кэша был огромным, потому что комбинации фильтров были бесконечны. Поэтому кэш никогда не мог быть полным. При промахе кэша БД получала удар. При попадании всё выглядело хорошо, пока не начинало рушиться.
Разгадка была довольно простой:
– мы фильтровали по столбцам, которые не были проиндексированы вместе;
- мы сортировали так, что Postgres не мог сделать это дёшево;
- мы возвращали больше данных, чем требовалось конечной точке.
Маленькое изменение (добавление правильного индекса) привело к тому, что кэш стал не нужен. Не потому, что Redis плох. Потому что Postgres прекрасно справлялся.
Это решение позволило сократить нагрузку на каждый запрос, а не только на неудачные. До изменений p95 в пиковые периоды трафика находился в диапазоне 420–600 мс. Промахи кэша приводили к ответам >900 мс, и графики становились всё более «зубчатыми». После корректировки индекса и запросов p95 стабилизировался в районе 140–190 мс при той же пиковой нагрузке.
Никаких ритуалов прогрева. Никаких задач «подготовки» кэша. Никаких загадочных жалоб о том, что обновление страницы «изменяет реальность».
Самым большим достижением стала не скорость. Дело в том, что ответ перестал меняться, когда пользователь моргнул. Наша неудача не в добавлении кэширования. Она в том, что мы сделали кэш путём истины по умолчанию. Мы приучили себя больше доверять частоте попаданий, чем корректности.
Правило кэширования
Если вы не можете объяснить правило инвалидации одним предложением, вы не кэшируете, вы гадаете. Зачастую узким местом является не БД, а форма запросов и объём запрашиваемых данных. Кэш может какое-то время скрывать это. А потом это приводит к ухудшению качества работы, не за счёт задержки, а за счёт снижения уверенности.
Источник: https://medium.com/@maahisoft20/we-built-a-cache-layer-postgresql-made-it-embarrassing-9762f055f21f
Мы Создали Слой Кэша. PostgreSQL Показал, что Зря.
Пользователь открывает страницу свего тарифного плана, а видит старый. Он обновляет страницу, и всё исправляется. Наш показатель попадания в кэш 98%, а мы всё равно выглядели некомпетентными. В тот момент мы перестали рассматривать кэширование как функцию повышения производительности и стали рассматривать его как проблему истинности. Потому что система перестала быть медленной, зато она стала ненадёжной.
Ошибка, которая не воспроизводится
Ничего не ломалось постоянно. Приходила жалоба в службу поддержки: цифры менялись после обновления. Коллега воспроизводил это один раз, а потом больше никогда. Отдел QC спрашивал, как это протестировать, и лучшим ответом было – хз, зависит от кэша.
Слой кэширования, которым мы гордились
Мы не просто вставили Redis и стали надеяться на лучшее. Мы регистрировали промахи, измеряли частоту попаданий, использовали TTL, создали правило, что каждая запись должна удалять связанные ключи. А потом реальность посмеялась над нами.
Одной конечной точке требовались данные пользователя, разрешения, метка сегмента и флаги функций. Каждая часть имела свой ключ и
свой TTL, и все части обновлялись с разной частотой. Мы сшили их вместе во время чтения и заметили, что это работает достаточно быстро - первая ложь. Вторая ложь: высокая частота попаданий в кэш создавала у нас чувство безопасности. Штука в том, что это может скрывать проблемы в БД.
Часть, о которой никто не говорит
Кэширование не просто увеличивает скорость. Оно добавляет новое поле для ошибок. Сложность не в хранении байтов. Сложность в определении, что означают эти байты, когда мир меняется. Обновление плана, изменение роли, переключение флага… В БД это отражается как факты, а в кэше… не понятно. Мы не снижали нагрузку, мы увеличивали неопределённость.
Наш ключ кэша был огромным, потому что комбинации фильтров были бесконечны. Поэтому кэш никогда не мог быть полным. При промахе кэша БД получала удар. При попадании всё выглядело хорошо, пока не начинало рушиться.
Разгадка была довольно простой:
– мы фильтровали по столбцам, которые не были проиндексированы вместе;
- мы сортировали так, что Postgres не мог сделать это дёшево;
- мы возвращали больше данных, чем требовалось конечной точке.
Маленькое изменение (добавление правильного индекса) привело к тому, что кэш стал не нужен. Не потому, что Redis плох. Потому что Postgres прекрасно справлялся.
Это решение позволило сократить нагрузку на каждый запрос, а не только на неудачные. До изменений p95 в пиковые периоды трафика находился в диапазоне 420–600 мс. Промахи кэша приводили к ответам >900 мс, и графики становились всё более «зубчатыми». После корректировки индекса и запросов p95 стабилизировался в районе 140–190 мс при той же пиковой нагрузке.
Никаких ритуалов прогрева. Никаких задач «подготовки» кэша. Никаких загадочных жалоб о том, что обновление страницы «изменяет реальность».
Самым большим достижением стала не скорость. Дело в том, что ответ перестал меняться, когда пользователь моргнул. Наша неудача не в добавлении кэширования. Она в том, что мы сделали кэш путём истины по умолчанию. Мы приучили себя больше доверять частоте попаданий, чем корректности.
Правило кэширования
Если вы не можете объяснить правило инвалидации одним предложением, вы не кэшируете, вы гадаете. Зачастую узким местом является не БД, а форма запросов и объём запрашиваемых данных. Кэш может какое-то время скрывать это. А потом это приводит к ухудшению качества работы, не за счёт задержки, а за счёт снижения уверенности.
Источник: https://medium.com/@maahisoft20/we-built-a-cache-layer-postgresql-made-it-embarrassing-9762f055f21f
👍12
День 2599. #Оффтоп
Размер Веб-Страницы Должен Укладываться в 14кБ
Меньше размер – быстрее загрузка, это понятно. Удивительно, что страница в 14кБ может загружаться гораздо быстрее, чем в 15кБ, а разница между 15 и 16кБ незначительна. Дело в алгоритме медленного старта TCP.
TCP
Протокол управления передачей (TCP) — это способ использования интернет-протокола (IP) для надёжной отправки пакетов данных. Сервер отправляет несколько пакетов, затем ждёт ответа от браузера о получении (ACK), затем отправляет ещё — или, если не получил ACK, может отправить пакеты снова.
Алгоритм медленного старта TCP используется серверами для определения количества пакетов, которые они могут отправить за один раз. Сервер не знает, какой объём данных может обработать соединение, поэтому начинает с отправки небольшого и безопасного количества данных — обычно 10 TCP-пакетов. Если на это получен ACK, сервер отправляет больше данных, удваивая количество пакетов. Так до тех пор, пока пакеты не будут потеряны и сервер не получит ACK. (Тогда он продолжает отправлять пакеты, но с меньшей скоростью). В реальности реализация алгоритма может отличаться, но суть та же.
Откуда 14кБ?
Максимальный размер TCP-пакета составляет 1500 байт: 40 байт заголовка (16 – IP, 24 – TCP). Т.е., 10 пакетов по 1460 = 14600 байт или примерно 14кБ!
Таким образом, если страницы (хотя бы важные) вашего сайта умещаются в 14кБ, вы можете сэкономить посетителям много времени. Люди очень нетерпеливы, и даже один обмен данными может быть удивительно долгим, особенно в нестабильных сетях.
Что делать?
Очевидно – делать сайт как можно меньше. Хорошая цель – уместить каждую страницу в 14кБ. Эти 14кБ включают сжатие — так что на самом деле это может быть около 50кБ несжатых данных, что довольно много.
Так что, если избавиться от лишнего CSS и JS, автовоспроизводимых видео, использовать минимизацию кода и т.п., вы, вероятно, легко достигнете цели. Но, даже если этого не получится, из правила 14кБ всё ещё можно извлечь пользу. Первые 14кБ данных, отправляемых посетителям, могут быть использованы для отображения чего-то полезного — например, важных первых нескольких абзацев текста, объясняющих, как использовать ваше приложение.
Примечание: 14кБ включают в себя HTTP-заголовки — которые не сжимаются (даже в HTTP/2 при первом ответе), а также изображения, поэтому выдавайте только то, что находится в видимой области экрана, делайте их очень маленькими, или используйте заполнители, чтобы посетители знали, что на этом месте будет что-то полезное.
Некоторые оговорки:
- Правило 14кБ больше эмпирическое правило, чем фундаментальный закон вычислительной техники. Некоторые серверы увеличили начальное окно медленного старта TCP до 30 пакетов вместо 10.
- Иногда сервер знает, что может начать с большего количества пакетов, потому что он использовал TLS-рукопожатие для установления большего лимита.
- Серверы могут кэшировать количество пакетов, которые может обработать маршрут, и отправлять больше при следующем подключении.
HTTP/2, HTTP/3 и QUIC
Существует мнение, что правило 14кБ больше не действует при использовании HTTP/2+. Однако строгих доказательств этому нет. Если вы знаете, отпишитесь в комментариях.
Источник: https://endtimes.dev/why-your-website-should-be-under-14kb-in-size/
Размер Веб-Страницы Должен Укладываться в 14кБ
Меньше размер – быстрее загрузка, это понятно. Удивительно, что страница в 14кБ может загружаться гораздо быстрее, чем в 15кБ, а разница между 15 и 16кБ незначительна. Дело в алгоритме медленного старта TCP.
TCP
Протокол управления передачей (TCP) — это способ использования интернет-протокола (IP) для надёжной отправки пакетов данных. Сервер отправляет несколько пакетов, затем ждёт ответа от браузера о получении (ACK), затем отправляет ещё — или, если не получил ACK, может отправить пакеты снова.
Алгоритм медленного старта TCP используется серверами для определения количества пакетов, которые они могут отправить за один раз. Сервер не знает, какой объём данных может обработать соединение, поэтому начинает с отправки небольшого и безопасного количества данных — обычно 10 TCP-пакетов. Если на это получен ACK, сервер отправляет больше данных, удваивая количество пакетов. Так до тех пор, пока пакеты не будут потеряны и сервер не получит ACK. (Тогда он продолжает отправлять пакеты, но с меньшей скоростью). В реальности реализация алгоритма может отличаться, но суть та же.
Откуда 14кБ?
Максимальный размер TCP-пакета составляет 1500 байт: 40 байт заголовка (16 – IP, 24 – TCP). Т.е., 10 пакетов по 1460 = 14600 байт или примерно 14кБ!
Таким образом, если страницы (хотя бы важные) вашего сайта умещаются в 14кБ, вы можете сэкономить посетителям много времени. Люди очень нетерпеливы, и даже один обмен данными может быть удивительно долгим, особенно в нестабильных сетях.
Что делать?
Очевидно – делать сайт как можно меньше. Хорошая цель – уместить каждую страницу в 14кБ. Эти 14кБ включают сжатие — так что на самом деле это может быть около 50кБ несжатых данных, что довольно много.
Так что, если избавиться от лишнего CSS и JS, автовоспроизводимых видео, использовать минимизацию кода и т.п., вы, вероятно, легко достигнете цели. Но, даже если этого не получится, из правила 14кБ всё ещё можно извлечь пользу. Первые 14кБ данных, отправляемых посетителям, могут быть использованы для отображения чего-то полезного — например, важных первых нескольких абзацев текста, объясняющих, как использовать ваше приложение.
Примечание: 14кБ включают в себя HTTP-заголовки — которые не сжимаются (даже в HTTP/2 при первом ответе), а также изображения, поэтому выдавайте только то, что находится в видимой области экрана, делайте их очень маленькими, или используйте заполнители, чтобы посетители знали, что на этом месте будет что-то полезное.
Некоторые оговорки:
- Правило 14кБ больше эмпирическое правило, чем фундаментальный закон вычислительной техники. Некоторые серверы увеличили начальное окно медленного старта TCP до 30 пакетов вместо 10.
- Иногда сервер знает, что может начать с большего количества пакетов, потому что он использовал TLS-рукопожатие для установления большего лимита.
- Серверы могут кэшировать количество пакетов, которые может обработать маршрут, и отправлять больше при следующем подключении.
HTTP/2, HTTP/3 и QUIC
Существует мнение, что правило 14кБ больше не действует при использовании HTTP/2+. Однако строгих доказательств этому нет. Если вы знаете, отпишитесь в комментариях.
Источник: https://endtimes.dev/why-your-website-should-be-under-14kb-in-size/
👍16
День 2600. #ВопросыНаСобеседовании
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
26. Навыки решения проблем
«Опишите какую-нибудь сложную техническую проблему, с которой вы столкнулись в вашей практике и как вы подошли к её решению? Какие инструменты и стратегии вы использовали, и каков был результат?»
Хороший ответ
В недавнем проекте на .NET я столкнулся с проблемой производительности, когда время ответа веб-API резко возросло при высокой нагрузке. API отвечал за получение сложных данных из БД и преобразование их в определённый формат для использования на стороне клиента.
Я применил следующий подход.
1. Выявление проблемы
Используя логи, я отследил, что узкое место возникает во время получения и обработки данных.
2. Выдвижение гипотез о решениях
Я предположил, что проблема может быть связана с неэффективными запросами к базе и неоптимальной обработкой данных в API.
3. Реализация и тестирование решений
Сначала я оптимизировал SQL-запросы с помощью анализа планов выполнения и обнаружил несколько отсутствующих индексов и некоторые запросы, которые можно переписать для повышения эффективности.
Затем я провёл рефакторинг кода .NET, чтобы использовать асинхронные шаблоны программирования. Я изменил уровень доступа к данным, чтобы использовать async и await, гарантируя, что операции с БД не блокируют потоки без необходимости.
4. Проверка и итерация
После внедрения изменений я повторно провёл нагрузочное тестирование и заметил значительное улучшение времени отклика. Изменения также были рассмотрены на код-ревью, чтобы убедиться в их соответствии передовым практикам.
5. Развёртывание и мониторинг
После развёртывания я продолжил мониторинг производительности приложения и подтвердил, что проблема решена.
6. Результат
Производительность API значительно улучшилась, приложение справляется с более высокими нагрузками с лучшим временем отклика, а решение также улучшило общую масштабируемость приложения.
Этот опыт подчеркнул важность систематической отладки, тщательного тестирования и использования надёжных инструментов для мониторинга и оптимизации ПО.
Часто встречающийся плохой ответ
«Какой-то конкретный случай выделить сложно. Когда я нахожу проблему, я просто пробую разные варианты, обычно что-то срабатывает. Часто я спрашиваю ИИ, обычно он предлагает хорошие решения».
Почему это неправильно:
- Отсутствие систематического подхода: полагаться исключительно на метод проб и ошибок может быть неэффективно, долго и не обязательно приведёт к пониманию первопричины проблемы.
- Неэффективность и риск: случайные попытки решения различных задач без стратегического плана или понимания могут привести к появлению новых ошибок, потенциально вызвать новые проблемы и потратить ценное время на разработку.
- Упущенная возможность обучения: такой подход не позволяет в полной мере использовать возможности обучения, предоставляемые сложными задачами. Понимание того, почему то или иное решение работает, так же важно, как и решение самой проблемы, чтобы предотвратить будущие проблемы и улучшить свои навыки.
Эта ошибка часто возникает из-за недостатка опыта или непонимания эффективных методов решения проблем в разработке ПО.
PS: неспособность привести конкретный пример из вашей практики также не добавит вам плюсов на собеседовании, поэтому заранее продумайте, как бы вы ответили на такой вопрос.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
26. Навыки решения проблем
«Опишите какую-нибудь сложную техническую проблему, с которой вы столкнулись в вашей практике и как вы подошли к её решению? Какие инструменты и стратегии вы использовали, и каков был результат?»
Хороший ответ
В недавнем проекте на .NET я столкнулся с проблемой производительности, когда время ответа веб-API резко возросло при высокой нагрузке. API отвечал за получение сложных данных из БД и преобразование их в определённый формат для использования на стороне клиента.
Я применил следующий подход.
1. Выявление проблемы
Используя логи, я отследил, что узкое место возникает во время получения и обработки данных.
2. Выдвижение гипотез о решениях
Я предположил, что проблема может быть связана с неэффективными запросами к базе и неоптимальной обработкой данных в API.
3. Реализация и тестирование решений
Сначала я оптимизировал SQL-запросы с помощью анализа планов выполнения и обнаружил несколько отсутствующих индексов и некоторые запросы, которые можно переписать для повышения эффективности.
Затем я провёл рефакторинг кода .NET, чтобы использовать асинхронные шаблоны программирования. Я изменил уровень доступа к данным, чтобы использовать async и await, гарантируя, что операции с БД не блокируют потоки без необходимости.
4. Проверка и итерация
После внедрения изменений я повторно провёл нагрузочное тестирование и заметил значительное улучшение времени отклика. Изменения также были рассмотрены на код-ревью, чтобы убедиться в их соответствии передовым практикам.
5. Развёртывание и мониторинг
После развёртывания я продолжил мониторинг производительности приложения и подтвердил, что проблема решена.
6. Результат
Производительность API значительно улучшилась, приложение справляется с более высокими нагрузками с лучшим временем отклика, а решение также улучшило общую масштабируемость приложения.
Этот опыт подчеркнул важность систематической отладки, тщательного тестирования и использования надёжных инструментов для мониторинга и оптимизации ПО.
Часто встречающийся плохой ответ
«Какой-то конкретный случай выделить сложно. Когда я нахожу проблему, я просто пробую разные варианты, обычно что-то срабатывает. Часто я спрашиваю ИИ, обычно он предлагает хорошие решения».
Почему это неправильно:
- Отсутствие систематического подхода: полагаться исключительно на метод проб и ошибок может быть неэффективно, долго и не обязательно приведёт к пониманию первопричины проблемы.
- Неэффективность и риск: случайные попытки решения различных задач без стратегического плана или понимания могут привести к появлению новых ошибок, потенциально вызвать новые проблемы и потратить ценное время на разработку.
- Упущенная возможность обучения: такой подход не позволяет в полной мере использовать возможности обучения, предоставляемые сложными задачами. Понимание того, почему то или иное решение работает, так же важно, как и решение самой проблемы, чтобы предотвратить будущие проблемы и улучшить свои навыки.
Эта ошибка часто возникает из-за недостатка опыта или непонимания эффективных методов решения проблем в разработке ПО.
PS: неспособность привести конкретный пример из вашей практики также не добавит вам плюсов на собеседовании, поэтому заранее продумайте, как бы вы ответили на такой вопрос.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
👎4👍2
День 2601. #SystemDesign101 #Шпаргалка
CPU, GPU и TPU
Почему один и тот же код быстро работает на GPU, медленно на CPU, а на TPU значительно быстрее их обоих? Ответ кроется в архитектуре. CPU, GPU и TPU разработаны для разных рабочих нагрузок.
CPU (Центральный процессор)
CPU обрабатывает вычисления общего назначения. Он создан для работы с низкой задержкой и сложным потоком управления, ветвящейся логикой, системными вызовами, прерываниями и кодом, требующим принятия решений.
Операционные системы, базы данных и большинство приложений работают на CPU, поскольку им необходима такая гибкость.
GPU (Графический процессор)
Вместо нескольких ядер они распределяют работу между тысячами ядер, которые выполняют одну и ту же инструкцию для огромных наборов данных в стиле SIMT (Single Instruction, Multiple Threads — «одна инструкция, множество потоков») / SIMD (Single Instruction, Multiple Data – «одна инструкция, много данных»).
Если ваша рабочая нагрузка повторяющаяся, например, матричные вычисления, затенение пикселей, тензорные операции, GPU справятся с ней быстро.
TPU (Тензорный процессор)
Это специализированное оборудование. Архитектура построена на основе матричного умножения с использованием систолических массивов, с управляемым компилятором потоком данных и встроенными буферами для весов и активаций. По сравнению с графическими процессорами, рассчитан на более высокий объём вычислений с пониженной точностью (например, всего 8-разрядную точность) при более высокой производительности.
Они быстры в обучении нейронных сетей, если рабочая нагрузка хорошо соответствует аппаратному обеспечению.
Источник: https://blog.bytebytego.com/p/ep205-cpu-vs-gpu-vs-tpu
CPU, GPU и TPU
Почему один и тот же код быстро работает на GPU, медленно на CPU, а на TPU значительно быстрее их обоих? Ответ кроется в архитектуре. CPU, GPU и TPU разработаны для разных рабочих нагрузок.
CPU (Центральный процессор)
CPU обрабатывает вычисления общего назначения. Он создан для работы с низкой задержкой и сложным потоком управления, ветвящейся логикой, системными вызовами, прерываниями и кодом, требующим принятия решений.
Операционные системы, базы данных и большинство приложений работают на CPU, поскольку им необходима такая гибкость.
GPU (Графический процессор)
Вместо нескольких ядер они распределяют работу между тысячами ядер, которые выполняют одну и ту же инструкцию для огромных наборов данных в стиле SIMT (Single Instruction, Multiple Threads — «одна инструкция, множество потоков») / SIMD (Single Instruction, Multiple Data – «одна инструкция, много данных»).
Если ваша рабочая нагрузка повторяющаяся, например, матричные вычисления, затенение пикселей, тензорные операции, GPU справятся с ней быстро.
TPU (Тензорный процессор)
Это специализированное оборудование. Архитектура построена на основе матричного умножения с использованием систолических массивов, с управляемым компилятором потоком данных и встроенными буферами для весов и активаций. По сравнению с графическими процессорами, рассчитан на более высокий объём вычислений с пониженной точностью (например, всего 8-разрядную точность) при более высокой производительности.
Они быстры в обучении нейронных сетей, если рабочая нагрузка хорошо соответствует аппаратному обеспечению.
Источник: https://blog.bytebytego.com/p/ep205-cpu-vs-gpu-vs-tpu
👍12
День 2602. #ЧтоНовенького #NET11
Объединения Наконец Появятся в .NET? Начало
После многих лет раздумий, обсуждений дизайна и костылей на уровне библиотек, объединения наконец-то становятся полноценной частью C#. Предложение в репозитории языка C# больше не является отдалённой идеей. Теперь, похоже, что эта функция появилась в превью 2 .NET 11 в качестве одной из ранних возможностей C# 15.
Это важно, потому что объединения решают проблему моделирования, которая существовала в C# очень давно: значение часто имеет ровно одну из нескольких допустимых форм, но система типов не имела встроенного способа выразить это замкнутое множество. В результате обычно использовалось что-то из следующего: обнуляемое значение, управление потоком через исключение, логический флаг или написанная вручную обёртка для результата.
Что именно есть в предложении?
Предложение шире, чем просто единая синтаксическая форма. Оно определяет модель объединений для языка и лаконичный синтаксис объявления поверх этой модели. На высоком уровне предложение вводит 4 возможности, которые важны в повседневном коде (поведения объединения):
1. Неявные преобразования из типов-вариантов в тип объединения;
2. Сопоставление по образцу, которое автоматически распаковывает содержимое объединения;
3. Проверка полноты в выражениях switch, что охвачены все типы-варианты;
4. Улучшения обнуляемости для содержимого объединения.
Основной синтаксис прост:
Это объявление означает, что Pet может содержать ровно один из этих типов-вариантов. Компилятор разрешает прямое построение через значения вариантов и рассматривает сопоставление с образцом в Pet как работу с замкнутым множеством.
Вариант
Типы-объединения и объявления объединения — не одно и то же
C# не просто добавляет форму объявления объединения… Он также определяет, что такое тип-объединение.
Согласно предложению, любой класс или структура, помеченные атрибутом
1. Объединения разработаны как языковая возможность, которая может выходить за рамки объявлений, генерируемых компилятором. Существующие или написанные вручную типы также могут использовать эту модель.
2. Это оставляет место для специализированных реализаций. Сокращённое объявление, показанное выше, намеренно оставлено нечётким, но языковая модель шире, чем это сокращённое объявление.
Окончание следует…
Источник: https://medium.com/@benjaminabt/c-15-unions-unions-are-finally-in-net-ben-abt-f4493c1e9ffc
Объединения Наконец Появятся в .NET? Начало
После многих лет раздумий, обсуждений дизайна и костылей на уровне библиотек, объединения наконец-то становятся полноценной частью C#. Предложение в репозитории языка C# больше не является отдалённой идеей. Теперь, похоже, что эта функция появилась в превью 2 .NET 11 в качестве одной из ранних возможностей C# 15.
Это важно, потому что объединения решают проблему моделирования, которая существовала в C# очень давно: значение часто имеет ровно одну из нескольких допустимых форм, но система типов не имела встроенного способа выразить это замкнутое множество. В результате обычно использовалось что-то из следующего: обнуляемое значение, управление потоком через исключение, логический флаг или написанная вручную обёртка для результата.
Что именно есть в предложении?
Предложение шире, чем просто единая синтаксическая форма. Оно определяет модель объединений для языка и лаконичный синтаксис объявления поверх этой модели. На высоком уровне предложение вводит 4 возможности, которые важны в повседневном коде (поведения объединения):
1. Неявные преобразования из типов-вариантов в тип объединения;
2. Сопоставление по образцу, которое автоматически распаковывает содержимое объединения;
3. Проверка полноты в выражениях switch, что охвачены все типы-варианты;
4. Улучшения обнуляемости для содержимого объединения.
Основной синтаксис прост:
public union Pet(Cat, Dog, Bird);
Это объявление означает, что Pet может содержать ровно один из этих типов-вариантов. Компилятор разрешает прямое построение через значения вариантов и рассматривает сопоставление с образцом в Pet как работу с замкнутым множеством.
public sealed record Cat(string Name);
public sealed record Dog(string Name);
public sealed record Bird(string Name);
public union Pet(Cat, Dog, Bird);
public static string Describe(Pet pet) =>
pet switch
{
Cat cat => $"Cat: {cat.Name}",
Dog dog => $"Dog: {dog.Name}",
Bird bird => $"Bird: {bird.Name}"
};
Вариант
default не требуется, т.к. объединение считается исчерпывающим после обработки всех типов-вариантов.Типы-объединения и объявления объединения — не одно и то же
C# не просто добавляет форму объявления объединения… Он также определяет, что такое тип-объединение.
Согласно предложению, любой класс или структура, помеченные атрибутом
[Union], могут участвовать в поведении объединения (см. 4 варианта выше), если они предоставляют необходимые открытые члены. Т.е. в язык добавляется новый паттерн обработки, а не просто ключевое слово union. Это важно по двум причинам:1. Объединения разработаны как языковая возможность, которая может выходить за рамки объявлений, генерируемых компилятором. Существующие или написанные вручную типы также могут использовать эту модель.
2. Это оставляет место для специализированных реализаций. Сокращённое объявление, показанное выше, намеренно оставлено нечётким, но языковая модель шире, чем это сокращённое объявление.
Окончание следует…
Источник: https://medium.com/@benjaminabt/c-15-unions-unions-are-finally-in-net-ben-abt-f4493c1e9ffc
👍20
День 2603. #ЧтоНовенького #NET11
Объединения Наконец Появятся в .NET? Окончание
Начало
Объявление объединения намеренно размыто
Предложение чётко определяет представление по умолчанию, выбранное для объявлений объединений. Объявление преобразуется в простую структуру со свойством Value типа object и сгенерированным конструктором для каждого типа-варианта. Это означает, что:
- Оно компактно.
- Типы-вариантов в виде типов-значений упаковываются при хранении через форму объявления по умолчанию.
Это не случайность. Предложение позиционирует объявления объединений как простой и широко применимый вариант по умолчанию. Для многих случаев на уровне приложений это правильный компромисс. В результатах, получаемых из сервисов, команд, парсинга и т.п. часто важны ясность и корректность, а не эффективность использования памяти.
Тем не менее, в предложении также признаётся, что этот вариант по умолчанию не будет идеальным для каждого сценария. Он явно оставляет место для пользовательских объединений и для паттернов доступа без упаковки, где структура и производительность имеют большее значение, чем компактное представление в одном поле.
Этот нюанс важен. Нативные объединения станут значительным улучшением для основного кода, но они не делают специализированные библиотеки объединений устаревшими. В основном они заменяют необходимость ручной разработки для распространённых случаев.
Зачем?
Важность объединении в коде C# заключается в возможности указать в системе типов, что операция имеет замкнутый набор допустимых результатов.
Рассмотрим сервис, который получает заказ. Во многих кодовых базах можно найти несколько вариантов реализации:
- тип возврата Order? (обнуляемый),
- исключение при отсутствии данных,
- пользовательская обёртка, которую не проверить, не открыв реализацию.
Объединение делает контракт видимым в прямо в сигнатуре:
Эта сигнатура документирует три типа-результата. Компилятор отвечает за корректность работы. Так объединения переносят проверки корректности на более ранние этапы, уменьшают скрытое управление потоком выполнения и значительно усложняют неправильное использование результатов.
Это также причина, по которой объединения органично вписываются в другие перспективные разработки C#, такие как закрытые иерархии типов и объявления вариантов. Язык движется к более чёткому пониманию замкнутых множеств и исчерпываемости, и объединения являются одним из наиболее ярких выражений этого направления.
Итого
Долгое время объединения в C# обсуждались как нечто, что есть в других языках, а в C# нет. Наконец, это будет не так. Интерес теперь заключается не в том, должны ли в C# быть объединения, а в том, как кодовые базы могут начать использовать преимущества этой модели уже сейчас.
Предложение C#15 наконец-то дает языку первоклассное решение для замкнутых форм результатов и исчерпывающей обработки. Это сочетание необычайно сильно.
Источник: https://medium.com/@benjaminabt/c-15-unions-unions-are-finally-in-net-ben-abt-f4493c1e9ffc
Объединения Наконец Появятся в .NET? Окончание
Начало
Объявление объединения намеренно размыто
Предложение чётко определяет представление по умолчанию, выбранное для объявлений объединений. Объявление преобразуется в простую структуру со свойством Value типа object и сгенерированным конструктором для каждого типа-варианта. Это означает, что:
- Оно компактно.
- Типы-вариантов в виде типов-значений упаковываются при хранении через форму объявления по умолчанию.
Это не случайность. Предложение позиционирует объявления объединений как простой и широко применимый вариант по умолчанию. Для многих случаев на уровне приложений это правильный компромисс. В результатах, получаемых из сервисов, команд, парсинга и т.п. часто важны ясность и корректность, а не эффективность использования памяти.
Тем не менее, в предложении также признаётся, что этот вариант по умолчанию не будет идеальным для каждого сценария. Он явно оставляет место для пользовательских объединений и для паттернов доступа без упаковки, где структура и производительность имеют большее значение, чем компактное представление в одном поле.
Этот нюанс важен. Нативные объединения станут значительным улучшением для основного кода, но они не делают специализированные библиотеки объединений устаревшими. В основном они заменяют необходимость ручной разработки для распространённых случаев.
Зачем?
Важность объединении в коде C# заключается в возможности указать в системе типов, что операция имеет замкнутый набор допустимых результатов.
Рассмотрим сервис, который получает заказ. Во многих кодовых базах можно найти несколько вариантов реализации:
- тип возврата Order? (обнуляемый),
- исключение при отсутствии данных,
- пользовательская обёртка, которую не проверить, не открыв реализацию.
Объединение делает контракт видимым в прямо в сигнатуре:
public sealed record NotFound;
public sealed record Unauthorized;
public sealed record Order(int Id);
public union GetOrderResult(Order, NotFound, Unauthorized);
Эта сигнатура документирует три типа-результата. Компилятор отвечает за корректность работы. Так объединения переносят проверки корректности на более ранние этапы, уменьшают скрытое управление потоком выполнения и значительно усложняют неправильное использование результатов.
Это также причина, по которой объединения органично вписываются в другие перспективные разработки C#, такие как закрытые иерархии типов и объявления вариантов. Язык движется к более чёткому пониманию замкнутых множеств и исчерпываемости, и объединения являются одним из наиболее ярких выражений этого направления.
Итого
Долгое время объединения в C# обсуждались как нечто, что есть в других языках, а в C# нет. Наконец, это будет не так. Интерес теперь заключается не в том, должны ли в C# быть объединения, а в том, как кодовые базы могут начать использовать преимущества этой модели уже сейчас.
Предложение C#15 наконец-то дает языку первоклассное решение для замкнутых форм результатов и исчерпывающей обработки. Это сочетание необычайно сильно.
Источник: https://medium.com/@benjaminabt/c-15-unions-unions-are-finally-in-net-ben-abt-f4493c1e9ffc
👍9
День 2604. #МоиИнструменты #PG
Инструменты Оптимизации Запросов в PostgreSQL. Часть 4
4. pg_stat_statements (встроенное расширение PostgreSQL)
Что даёт: отслеживание производительности запросов без использования внешних инструментов.
Тип: Бесплатное (встроено в PostgreSQL).
Зачем: Перед установкой внешних инструментов включите это расширение. Оно уже есть в PostgreSQL, просто не активировано по умолчанию. Отслеживает время выполнения каждого запроса, количество вызовов и использование ресурсов — важные данные для оптимизации.
Настройка
1. Включаем (однократно)
2. Добавляем в postgresql.conf
3. Перезагружаем Postgres.
Использование
Самые медленные по времени запросы:
Вернёт:
Запросы с большой вариативностью (непостоянная производительность):
Высокий CV (коэффициент вариативности) означает периодические проблемы с производительностью (блокировки, промахи кэша и т.д.).
Когда использовать
- Любая БД Postgres (нет причин не включать);
- Нужен лёгкий мониторинг;
- Нужны метрики на уровне запросов;
- Ограничен бюджет.
Когда отказаться
Особых причин не использовать нет.
Скрытая функция
Выявление запросов, вызывающих нагрузку на ввод-вывод (промахи кэша):
Высокий cache_miss_ratio означает, что запрос сканирует данные не в памяти. Оптимизация: улучшить индексы или увеличить размер shared_buffers.
С осторожностью
У pg_stat_statements буфер фиксированного размера. Проверяем, не достигаем ли мы лимита:
При высоком queries_evicted, увеличьте в postgresql.conf pg_stat_statements.max = 50000 (с 10000), перезапустите Postgres.
Замечание: увеличится расход памяти (~400 байт на запрос).
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
Инструменты Оптимизации Запросов в PostgreSQL. Часть 4
4. pg_stat_statements (встроенное расширение PostgreSQL)
Что даёт: отслеживание производительности запросов без использования внешних инструментов.
Тип: Бесплатное (встроено в PostgreSQL).
Зачем: Перед установкой внешних инструментов включите это расширение. Оно уже есть в PostgreSQL, просто не активировано по умолчанию. Отслеживает время выполнения каждого запроса, количество вызовов и использование ресурсов — важные данные для оптимизации.
Настройка
1. Включаем (однократно)
CREATE EXTENSION pg_stat_statements;
2. Добавляем в postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
pg_stat_statements.max = 10000
3. Перезагружаем Postgres.
Использование
Самые медленные по времени запросы:
SELECT
query,
calls,
total_exec_time,
mean_exec_time,
max_exec_time,
stddev_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
Вернёт:
query | calls | total_exec_time | mean_exec_time
SELECT … FROM orders JOIN … | 50,423 | 8,234,567 ms | 163.4 ms
UPDATE inventory SET … | 12,345 | 4,567,890 ms | 370.0 ms
Запросы с большой вариативностью (непостоянная производительность):
SELECT
query,
calls,
mean_exec_time,
stddev_exec_time,
(stddev_exec_time / mean_exec_time) AS cv
FROM pg_stat_statements
WHERE calls > 100
ORDER BY cv DESC
LIMIT 10;
Высокий CV (коэффициент вариативности) означает периодические проблемы с производительностью (блокировки, промахи кэша и т.д.).
Когда использовать
- Любая БД Postgres (нет причин не включать);
- Нужен лёгкий мониторинг;
- Нужны метрики на уровне запросов;
- Ограничен бюджет.
Когда отказаться
Особых причин не использовать нет.
Скрытая функция
Выявление запросов, вызывающих нагрузку на ввод-вывод (промахи кэша):
SELECT
query,
calls,
shared_blks_hit,
shared_blks_read,
(shared_blks_read::float / NULLIF(shared_blks_hit + shared_blks_read, 0)) AS cache_miss_ratio
FROM pg_stat_statements
WHERE shared_blks_read > 0
ORDER BY shared_blks_read DESC
LIMIT 10;
Высокий cache_miss_ratio означает, что запрос сканирует данные не в памяти. Оптимизация: улучшить индексы или увеличить размер shared_buffers.
С осторожностью
У pg_stat_statements буфер фиксированного размера. Проверяем, не достигаем ли мы лимита:
sql
SELECT
pg_stat_statements_info.dealloc AS queries_evicted,
pg_stat_statements_info.stats_reset AS last_reset
FROM pg_stat_statements_info;
При высоком queries_evicted, увеличьте в postgresql.conf pg_stat_statements.max = 50000 (с 10000), перезапустите Postgres.
Замечание: увеличится расход памяти (~400 байт на запрос).
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
👍16
День 2605. #ЗаметкиНаПолях
5 Малоизвестных Функций C#, Которые Упростят Вашу Жизнь
Фреймворк уже имеет надёжные инструменты для решения различных проблем, но многие из них мало известны. Сегодня рассмотрим некоторые.
1. OperatingSystem.IsX вместо RuntimeInformation
В течение многих лет проверка текущей ОС в .NET означала написание чего-то вроде:
Теперь появились более чистые варианты:
- OperatingSystem.IsWindows,
- OperatingSystem.IsLinux,
- OperatingSystem.IsMacOS
и т.п.
2. Правильная изоляция плагинов с помощью AssemblyLoadContext
Если вы когда-либо пытались создать систему плагинов в .NET, вы знаете, насколько болезненны конфликты сборок. Загрузите две версии одной и той же зависимости, и внезапно всё перестаёт работать. AssemblyLoadContext позволяет загружать сборки изолированно, так что два плагина могут зависеть от разных версий одной и той же DLL, не мешая друг другу. Вот минимальный код для начала:
Теперь каждый плагин существует в своей среде. Вы также можете их выгружать, что очень важно для длительно работающих процессов, таких как серверы.
3. Разбор зависимостей с помощью AssemblyDependencyResolver
AssemblyDependencyResolver, получив путь к плагину или сборке, определяет, откуда должны браться зависимости:
Вы получаете правильные правила разрешения зависимостей, соответствующие тому, как это обычно делает .NET, но с областью действия в контексте плагина. Так вы избегаете неприятных сюрпризов, когда плагин ссылается на Newtonsoft.Json 13.0.1, а хост-приложение использует 12.0.3.
4. Получение версий сборок без ошибок
Часто в коде можно встретить что-то такое:
Дело в том, что это значение не всегда совпадает с версией, которую вы указали в проекте. Это версия сборки, а не обязательно версия файла или информационная версия. Какая из них вам нужна?
-
-
-
Лучший подход – выражаться более явно:
Так вы получите именно ту строку, которую хотели передать, а не то, что MSBuild по умолчанию присвоил вашей DLL.
5. Получение зависимостей из контейнера с помощью ActivatorUtilities
Иногда нужно создать объект, который не зарегистрирован в контейнере, но имеет зависимости, которые зарегистрированы. Используйте ActivatorUtilities:
Это говорит контейнеру: «Я знаю, что MyService не зарегистрирован, но, пожалуйста, внедри все необходимые ему сервисы». Это удобный обходной путь, который избавляет вас от необходимости создавать неудобные фабрики или засорять код логикой разрешения сервисов.
Источник: https://blog.stackademic.com/if-youre-not-using-these-5-net-features-you-re-working-too-hard-0aefbf5a6fdc?gi=bb3ac273e638
5 Малоизвестных Функций C#, Которые Упростят Вашу Жизнь
Фреймворк уже имеет надёжные инструменты для решения различных проблем, но многие из них мало известны. Сегодня рассмотрим некоторые.
1. OperatingSystem.IsX вместо RuntimeInformation
В течение многих лет проверка текущей ОС в .NET означала написание чего-то вроде:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
//…
}
Теперь появились более чистые варианты:
- OperatingSystem.IsWindows,
- OperatingSystem.IsLinux,
- OperatingSystem.IsMacOS
и т.п.
if (OperatingSystem.IsWindows())
{
//…
}
2. Правильная изоляция плагинов с помощью AssemblyLoadContext
Если вы когда-либо пытались создать систему плагинов в .NET, вы знаете, насколько болезненны конфликты сборок. Загрузите две версии одной и той же зависимости, и внезапно всё перестаёт работать. AssemblyLoadContext позволяет загружать сборки изолированно, так что два плагина могут зависеть от разных версий одной и той же DLL, не мешая друг другу. Вот минимальный код для начала:
class PluginLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
public PluginLoadContext(string path) =>
_resolver = new(path);
protected override Assembly? Load(AssemblyName name)
{
var path = _resolver
.ResolveAssemblyToPath(name);
return path != null
? LoadFromAssemblyPath(path)
: null;
}
}
Теперь каждый плагин существует в своей среде. Вы также можете их выгружать, что очень важно для длительно работающих процессов, таких как серверы.
3. Разбор зависимостей с помощью AssemblyDependencyResolver
AssemblyDependencyResolver, получив путь к плагину или сборке, определяет, откуда должны браться зависимости:
var resolver =
new AssemblyDependencyResolver(pluginPath);
var path = resolver
.ResolveAssemblyToPath(assemblyName);
Вы получаете правильные правила разрешения зависимостей, соответствующие тому, как это обычно делает .NET, но с областью действия в контексте плагина. Так вы избегаете неприятных сюрпризов, когда плагин ссылается на Newtonsoft.Json 13.0.1, а хост-приложение использует 12.0.3.
4. Получение версий сборок без ошибок
Часто в коде можно встретить что-то такое:
var version = Assembly
.GetExecutingAssembly()
.GetName()
.Version;
Дело в том, что это значение не всегда совпадает с версией, которую вы указали в проекте. Это версия сборки, а не обязательно версия файла или информационная версия. Какая из них вам нужна?
-
AssemblyName.Version - версия сборки, полученная во время компиляции,-
FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion - версия файла,-
AssemblyInformationalVersionAttribute - семантическая версия, вроде 1.0.0-beta+sha.abc123.Лучший подход – выражаться более явно:
var version = Assembly
.GetExecutingAssembly()
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
.InformationalVersion;
Так вы получите именно ту строку, которую хотели передать, а не то, что MSBuild по умолчанию присвоил вашей DLL.
5. Получение зависимостей из контейнера с помощью ActivatorUtilities
Иногда нужно создать объект, который не зарегистрирован в контейнере, но имеет зависимости, которые зарегистрированы. Используйте ActivatorUtilities:
var myService = ActivatorUtilities
.CreateInstance<MyService>(serviceProvider);
Это говорит контейнеру: «Я знаю, что MyService не зарегистрирован, но, пожалуйста, внедри все необходимые ему сервисы». Это удобный обходной путь, который избавляет вас от необходимости создавать неудобные фабрики или засорять код логикой разрешения сервисов.
Источник: https://blog.stackademic.com/if-youre-not-using-these-5-net-features-you-re-working-too-hard-0aefbf5a6fdc?gi=bb3ac273e638
👍14
День 2606. #Здоровье
Утренние Привычки, Которые Разрушают Ваш Мозг. Начало
Автор оригинала: нейробиолог Патрисия Шмидт
Утро предоставляет уникальную возможность максимально эффективно использовать возможности мозга в течение всего дня. То, что вы делаете (или не делаете) в первые 60–90 минут после пробуждения, повлияет на ваше настроение и когнитивные способности в последующие часы. Горькая правда в том, что большинство людей неосознанно саботируют работу своего мозга утром и удивляются, почему они не могут сосредоточиться или постоянно испытывают стресс. Рассмотрим распространённые утренние привычки с точки зрения нейробиологии и найдём лучшие альтернативы для каждой.
1. Проверка телефона первым делом утром
84% населения США проверяют свои телефоны в течение первых 10 минут после пробуждения.
Почему это проблема:
В первые 30–45 минут после пробуждения происходит реакция пробуждения кортизола (резкое повышение уровня). Здоровая реакция пробуждения кортизола подготавливает вас к предстоящему дню, к ожидаемым ежедневным нагрузкам, и когда вы вводите непосредственные стрессовые факторы (контент на телефоне) в этот чувствительный период, вы нарушаете свою естественную систему подготовки.
Что делать вместо этого:
Подождите хотя бы 45 минут, прежде чем проверять свой телефон. Позвольте реакции пробуждения кортизола развиться естественным образом.
2. Пропуск утреннего воздействия света
Большая часть современной жизни проходит в домах, квартирах и офисах. Воздействие естественного дневного света становится всё более редким явлением.
Почему это проблема:
Наибольшее влияние на ваши внутренние биологические часы оказывает воздействие света. Свет, попадающий в глаза, стимулирует область в мозге, называемую супрахиазматическим ядром (СХЯ). Эта область задаёт темп для мозга и тела, используя солнечный свет для установки суточных ритмов.
Когда свет попадает утром в глаза, начинается каскад нейрохимических событий:
- Естественным образом усиливается здоровая реакция пробуждения кортизола.
- Мелатонин («гормон сна») подавляется, что оптимизирует вечернюю выработку мелатонина, улучшая сон следующей ночью.
- Улучшается оборот серотонина в мозге. Воздействие яркого дневного света может способствовать регулированию настроения, делая вас счастливее и спокойнее.
Воздействие света, особенно рано утром, имеет решающее значение для настройки ваших биологических часов. Недостаточное воздействие утреннего света может привести к вялости в течение дня и ухудшить качество сна следующей ночью.
Что делать:
Как можно скорее после пробуждения, в идеале в течение первых 30 минут, подвергайте глаза воздействию естественного солнечного света. Стремитесь к как минимум 10 минутам пребывания на солнце или 15–20 минутам в пасмурные дни.
Если вы не можете выйти на улицу рано или встаёте в темноте, яркое комнатное освещение может помочь. Стандартные комнатные лампы недостаточно яркие, поэтому подумайте о приобретении лампы солнечного света (яркостью не менее 10 000 люкс). Но не используйте её вечером, так как это может нарушить сон!
Окончание следует…
Источник: https://medium.com/write-a-catalyst/as-a-neuroscientist-i-quit-these-5-morning-habits-that-destroy-your-brain-3efe1f410226
Утренние Привычки, Которые Разрушают Ваш Мозг. Начало
Автор оригинала: нейробиолог Патрисия Шмидт
Утро предоставляет уникальную возможность максимально эффективно использовать возможности мозга в течение всего дня. То, что вы делаете (или не делаете) в первые 60–90 минут после пробуждения, повлияет на ваше настроение и когнитивные способности в последующие часы. Горькая правда в том, что большинство людей неосознанно саботируют работу своего мозга утром и удивляются, почему они не могут сосредоточиться или постоянно испытывают стресс. Рассмотрим распространённые утренние привычки с точки зрения нейробиологии и найдём лучшие альтернативы для каждой.
1. Проверка телефона первым делом утром
84% населения США проверяют свои телефоны в течение первых 10 минут после пробуждения.
Почему это проблема:
В первые 30–45 минут после пробуждения происходит реакция пробуждения кортизола (резкое повышение уровня). Здоровая реакция пробуждения кортизола подготавливает вас к предстоящему дню, к ожидаемым ежедневным нагрузкам, и когда вы вводите непосредственные стрессовые факторы (контент на телефоне) в этот чувствительный период, вы нарушаете свою естественную систему подготовки.
Что делать вместо этого:
Подождите хотя бы 45 минут, прежде чем проверять свой телефон. Позвольте реакции пробуждения кортизола развиться естественным образом.
2. Пропуск утреннего воздействия света
Большая часть современной жизни проходит в домах, квартирах и офисах. Воздействие естественного дневного света становится всё более редким явлением.
Почему это проблема:
Наибольшее влияние на ваши внутренние биологические часы оказывает воздействие света. Свет, попадающий в глаза, стимулирует область в мозге, называемую супрахиазматическим ядром (СХЯ). Эта область задаёт темп для мозга и тела, используя солнечный свет для установки суточных ритмов.
Когда свет попадает утром в глаза, начинается каскад нейрохимических событий:
- Естественным образом усиливается здоровая реакция пробуждения кортизола.
- Мелатонин («гормон сна») подавляется, что оптимизирует вечернюю выработку мелатонина, улучшая сон следующей ночью.
- Улучшается оборот серотонина в мозге. Воздействие яркого дневного света может способствовать регулированию настроения, делая вас счастливее и спокойнее.
Воздействие света, особенно рано утром, имеет решающее значение для настройки ваших биологических часов. Недостаточное воздействие утреннего света может привести к вялости в течение дня и ухудшить качество сна следующей ночью.
Что делать:
Как можно скорее после пробуждения, в идеале в течение первых 30 минут, подвергайте глаза воздействию естественного солнечного света. Стремитесь к как минимум 10 минутам пребывания на солнце или 15–20 минутам в пасмурные дни.
Если вы не можете выйти на улицу рано или встаёте в темноте, яркое комнатное освещение может помочь. Стандартные комнатные лампы недостаточно яркие, поэтому подумайте о приобретении лампы солнечного света (яркостью не менее 10 000 люкс). Но не используйте её вечером, так как это может нарушить сон!
Окончание следует…
Источник: https://medium.com/write-a-catalyst/as-a-neuroscientist-i-quit-these-5-morning-habits-that-destroy-your-brain-3efe1f410226
👍22
День 2607. #Здоровье
Утренние Привычки, Которые Разрушают Ваш Мозг. Окончание
Начало
3. Немедленное погружение в сложную работу, требующую глубокой концентрации
Некоторые люди просыпаются и сразу же начинают работу, требующую глубокой концентрации, чтобы использовать утреннее спокойствие для продуктивности.
Почему это проблема:
Вы просыпаетесь в состоянии, называемом инерцией сна, когда мышление и принятие решений нарушены. Рано утром вы находитесь в расслабленном состоянии ума, которое может быть полезно для творческой работы, но не для глубокой концентрации. Мозг просыпается постепенно, и необходимо, чтобы активизировалась реакция пробуждения кортизола (см. п.1), прежде чем вы сможете выполнять сложную работу.
Что делать вместо этого:
Позвольте мозгу и телу проснуться и поддержите здоровую реакцию пробуждения кортизола с помощью воздействия света, избегания новостей и некоторой физической активности.
4. Сладкий завтрак
Сладкий завтрак очень распространённое явление.
Почему это проблема:
Это приводит к резкому скачку уровня глюкозы в крови, за которым следует его значительное падение через несколько часов. Такая нестабильность влияет на мозг, поскольку он использует глюкозу в качестве топлива.
Что делать вместо этого:
Сосредоточьтесь на белке. Богатый белком завтрак (25–35 граммов белка) поддерживает когнитивные функции, чувство сытости и обеспечивает энергией на протяжении всего дня. То есть не только улучшает работу мозга, но и регулирует аппетит.
5. Недостаток жидкости
Многие люди не знают, что после пробуждения они испытывают лёгкое обезвоживание. Организм постоянно теряет жидкость, и после многих часов без питья утром возникает ее дефицит.
Почему это проблема:
Мозг и тело в основном состоят из воды, и для нормального функционирования им необходима достаточная гидратация. Необходимо восполнять запасы жидкости утром, поскольку даже лёгкое обезвоживание влияет на когнитивные функции и настроение.
Что делать:
Пейте воду сразу после пробуждения. Достаточно 250–350 мл. Держите бутылку или стакан с водой на прикроватной тумбочке, чтобы они были под рукой, когда вы проснётесь.
Итого
Эти 5 привычек могут показаться незначительными, но их влияние накапливается. Ваша утренняя рутина создаёт условия либо для успеха, либо для провального дня. То, что вы делаете в первые 60–90 минут после пробуждения, влияет на вашу когнитивную работоспособность, настроение, энергию и концентрацию внимания в течение всего дня, и даже на качество сна следующей ночью.
Источник: https://medium.com/write-a-catalyst/as-a-neuroscientist-i-quit-these-5-morning-habits-that-destroy-your-brain-3efe1f410226
Утренние Привычки, Которые Разрушают Ваш Мозг. Окончание
Начало
3. Немедленное погружение в сложную работу, требующую глубокой концентрации
Некоторые люди просыпаются и сразу же начинают работу, требующую глубокой концентрации, чтобы использовать утреннее спокойствие для продуктивности.
Почему это проблема:
Вы просыпаетесь в состоянии, называемом инерцией сна, когда мышление и принятие решений нарушены. Рано утром вы находитесь в расслабленном состоянии ума, которое может быть полезно для творческой работы, но не для глубокой концентрации. Мозг просыпается постепенно, и необходимо, чтобы активизировалась реакция пробуждения кортизола (см. п.1), прежде чем вы сможете выполнять сложную работу.
Что делать вместо этого:
Позвольте мозгу и телу проснуться и поддержите здоровую реакцию пробуждения кортизола с помощью воздействия света, избегания новостей и некоторой физической активности.
4. Сладкий завтрак
Сладкий завтрак очень распространённое явление.
Почему это проблема:
Это приводит к резкому скачку уровня глюкозы в крови, за которым следует его значительное падение через несколько часов. Такая нестабильность влияет на мозг, поскольку он использует глюкозу в качестве топлива.
Что делать вместо этого:
Сосредоточьтесь на белке. Богатый белком завтрак (25–35 граммов белка) поддерживает когнитивные функции, чувство сытости и обеспечивает энергией на протяжении всего дня. То есть не только улучшает работу мозга, но и регулирует аппетит.
5. Недостаток жидкости
Многие люди не знают, что после пробуждения они испытывают лёгкое обезвоживание. Организм постоянно теряет жидкость, и после многих часов без питья утром возникает ее дефицит.
Почему это проблема:
Мозг и тело в основном состоят из воды, и для нормального функционирования им необходима достаточная гидратация. Необходимо восполнять запасы жидкости утром, поскольку даже лёгкое обезвоживание влияет на когнитивные функции и настроение.
Что делать:
Пейте воду сразу после пробуждения. Достаточно 250–350 мл. Держите бутылку или стакан с водой на прикроватной тумбочке, чтобы они были под рукой, когда вы проснётесь.
Итого
Эти 5 привычек могут показаться незначительными, но их влияние накапливается. Ваша утренняя рутина создаёт условия либо для успеха, либо для провального дня. То, что вы делаете в первые 60–90 минут после пробуждения, влияет на вашу когнитивную работоспособность, настроение, энергию и концентрацию внимания в течение всего дня, и даже на качество сна следующей ночью.
Источник: https://medium.com/write-a-catalyst/as-a-neuroscientist-i-quit-these-5-morning-habits-that-destroy-your-brain-3efe1f410226
👍14