День 2581. #МоиИнструменты #PG
Инструменты Оптимизации Запросов в PostgreSQL. Часть 2
2. Анализатор производительности БД (DPA) SolarWinds
Что даёт: Мониторинг производительности запросов к различным базам данных в одном унифицированном интерфейсе.
Тип: Коммерческий (доступна бесплатная пробная версия)
Базы данных: Postgres, MySQL, Oracle, SQL Server, MongoDB
Зачем нужен: Большинство компаний используют несколько БД. Postgres для транзакционных операций, MySQL для устаревших приложений, Redshift для аналитики. Для каждой из них существуют разные инструменты мониторинга. DPA обеспечивает унифицированный мониторинг производительности для всех из них.
Главная особенность: анализ времени ожидания. Вместо того чтобы просто показывать медленные запросы, DPA показывает почему они медленные — ожидание блокировок, дисковый ввод-вывод, ЦП, сеть и т. д.
Что показывает
Когда использовать
- Многобазовая среда;
- Бюджет на коммерческие инструменты ($1500-5000 в год на БД);
- Необходима корреляция между базами данных;
- Требуется анализ исторических тенденций.
Когда отказаться
- Одна БД (pgBadger или специализированные под БД инструменты дешевле);
- Ограниченный бюджет;
- Необходимо профилирование на уровне кода (DPA ориентирован на уровень запросов).
Скрытая функция
Обнаружение аномалий без настройки. DPA автоматически изучает шаблоны поведения:
Не требуется ручная настройка порогового значения.
Снижает усталость от оповещений.
С осторожностью
Реальные накладные расходы агента DPA:
- ЦП: +2-5% на сервере БД;
- Память: ~500 МБ на каждый отслеживаемый экземпляр;
- Сеть: ~10-50 Мбит/с телеметрии.
Для высоконагруженной производственной среды:
- Запускайте агент на отдельном сервере;
- Используйте выборочный мониторинг (отслеживайте 10% запросов);
- Настройте частоту сбора данных.
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
Инструменты Оптимизации Запросов в PostgreSQL. Часть 2
2. Анализатор производительности БД (DPA) SolarWinds
Что даёт: Мониторинг производительности запросов к различным базам данных в одном унифицированном интерфейсе.
Тип: Коммерческий (доступна бесплатная пробная версия)
Базы данных: Postgres, MySQL, Oracle, SQL Server, MongoDB
Зачем нужен: Большинство компаний используют несколько БД. Postgres для транзакционных операций, MySQL для устаревших приложений, Redshift для аналитики. Для каждой из них существуют разные инструменты мониторинга. DPA обеспечивает унифицированный мониторинг производительности для всех из них.
Главная особенность: анализ времени ожидания. Вместо того чтобы просто показывать медленные запросы, DPA показывает почему они медленные — ожидание блокировок, дисковый ввод-вывод, ЦП, сеть и т. д.
Что показывает
Query: SELECT * FROM orders WHERE customer_id = ?
Total time: 12.5 seconds
Breakdown:
- CPU time: 0.3s (2%)
- Lock wait: 11.8s (94%) ← Проблема тут
- I/O wait: 0.2s (2%)
- Network: 0.2s (2%)
Action: Investigate lock contention, not query optimization
(Решение: Исследуйте конфликты блокировок, а не оптимизацию запросов.)
Когда использовать
- Многобазовая среда;
- Бюджет на коммерческие инструменты ($1500-5000 в год на БД);
- Необходима корреляция между базами данных;
- Требуется анализ исторических тенденций.
Когда отказаться
- Одна БД (pgBadger или специализированные под БД инструменты дешевле);
- Ограниченный бюджет;
- Необходимо профилирование на уровне кода (DPA ориентирован на уровень запросов).
Скрытая функция
Обнаружение аномалий без настройки. DPA автоматически изучает шаблоны поведения:
- Typical query response time: 2.3s ±0.5s
(Типичное время ответа на запрос: 2,3с ±0,5с)
- Today's execution: 8.7s
(Время выполнения сегодня: 8,7с)
- Alert: Query degraded 3.7x from baseline
(Предупреждение: Скорость выполнения запроса снизилась в 3,7 раза по сравнению с базовым уровнем).
Не требуется ручная настройка порогового значения.
Снижает усталость от оповещений.
С осторожностью
Реальные накладные расходы агента DPA:
- ЦП: +2-5% на сервере БД;
- Память: ~500 МБ на каждый отслеживаемый экземпляр;
- Сеть: ~10-50 Мбит/с телеметрии.
Для высоконагруженной производственной среды:
- Запускайте агент на отдельном сервере;
- Используйте выборочный мониторинг (отслеживайте 10% запросов);
- Настройте частоту сбора данных.
Источник: https://medium.com/@reliabledataengineering/15-sql-optimization-tools-that-make-queries-10x-faster-8629ac451d97
1👎5👍1
День 2582. #ЧтоНовенького #NET11
Вышла Превью 1 .NET 11. Начало
Команда Microsoft .NET выпустила первую предварительную версию .NET 11. Про главную особенность превью – асинхронную обработку в среде выполнения – я уже писал. Теперь рассмотрим другие важные новинки.
Библиотеки
1. Добавлена нативная поддержка сжатия Zstandard (zstd) благодаря новому классу ZstandardStream. Zstandard обеспечивает значительно более быстрое сжатие и распаковку по сравнению с существующими алгоритмами, сохраняя при этом конкурентоспособные коэффициенты сжатия. Новые API включают полный набор возможностей потокового, однократного и словарного сжатия и распаковки.
2. В ZipArchiveEntry добавлены:
- параметр FileAccess, позволяющий указать, тип доступа к открываемому файлу FileAccess.Read или FileAccess.Write;
- свойство CompressionMethod в ZipArchiveEntry типа перечисления ZipCompressionMethod, позволяющее приложениям определять алгоритм сжатия для каждой записи.
3. Добавлены аргументы выражений коллекций с ключевым словом with и поддержка выражений коллекций для FrozenDictionary:
4. Поддержка рун в String, StringBuilder и TextWriter
System.Text.Rune теперь можно использовать гораздо шире. Это значительно упрощает корректную работу приложений с текстом Unicode, особенно для символов, находящихся за пределами базовой многоязычной плоскости, которые требуют суррогатных пар при представлении в виде символов:
5. Помощник по MIME-типам System.Net.Mime.MediaTypeMap
6. API для проверки HMAC и KMAC
Добавлены методы Verify ко всем классам HMAC и KMAC. Значения HMAC часто необходимо сравнивать за фиксированное время, чтобы предотвратить атаки по времени. Ранее это требовало двух шагов: вычисления HMAC с помощью HashData, а затем сравнения с помощью CryptographicOperations.FixedTimeEquals. Новые методы Verify объединяют оба этапа в один безопасный вызов.
7. DivisionRounding для целочисленного деления
Добавлена поддержка альтернативных режимов округления при целочисленном делении с помощью нового перечисления DivisionRounding и новых методов в IBinaryInteger<T>: Divide, DivRem и Remainder. Большинство аппаратных средств реализуют деление нацело (/ и % в C#), но разные языки и предметные области требуют округления до большего или меньшего целого числа, евклидова округления или округления от нуля. Хотя это довольно тривиально, новые API позволяют выбрать правильный режим и хорошо оптимизированную реализацию:
Окончание следует…
Источник: https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
Вышла Превью 1 .NET 11. Начало
Команда Microsoft .NET выпустила первую предварительную версию .NET 11. Про главную особенность превью – асинхронную обработку в среде выполнения – я уже писал. Теперь рассмотрим другие важные новинки.
Библиотеки
1. Добавлена нативная поддержка сжатия Zstandard (zstd) благодаря новому классу ZstandardStream. Zstandard обеспечивает значительно более быстрое сжатие и распаковку по сравнению с существующими алгоритмами, сохраняя при этом конкурентоспособные коэффициенты сжатия. Новые API включают полный набор возможностей потокового, однократного и словарного сжатия и распаковки.
// Сжатие с ZstandardStream
using var compressStream =
new ZstandardStream(outputStream, CompressionMode.Compress);
await inputStream.CopyToAsync(compressStream);
// Распаковка
using var decompressStream
= new ZstandardStream(inputStream, CompressionMode.Decompress);
await decompressStream.CopyToAsync(outputStream);
2. В ZipArchiveEntry добавлены:
- параметр FileAccess, позволяющий указать, тип доступа к открываемому файлу FileAccess.Read или FileAccess.Write;
- свойство CompressionMethod в ZipArchiveEntry типа перечисления ZipCompressionMethod, позволяющее приложениям определять алгоритм сжатия для каждой записи.
3. Добавлены аргументы выражений коллекций с ключевым словом with и поддержка выражений коллекций для FrozenDictionary:
FrozenDictionary<string, int> lookup =
[with(StringComparer.Ordinal), "one":1, "two":2, "three":3];
4. Поддержка рун в String, StringBuilder и TextWriter
System.Text.Rune теперь можно использовать гораздо шире. Это значительно упрощает корректную работу приложений с текстом Unicode, особенно для символов, находящихся за пределами базовой многоязычной плоскости, которые требуют суррогатных пар при представлении в виде символов:
var s = "Hello 🌍";
var glb = new Rune(0x1F30D); // 🌍
s.Contains(glb); // true
s.IndexOf(glb); // 6
s.StartsWith(glb); // false
s.Replace(glb, new Rune('X')); // "Hello X"
5. Помощник по MIME-типам System.Net.Mime.MediaTypeMap
6. API для проверки HMAC и KMAC
Добавлены методы Verify ко всем классам HMAC и KMAC. Значения HMAC часто необходимо сравнивать за фиксированное время, чтобы предотвратить атаки по времени. Ранее это требовало двух шагов: вычисления HMAC с помощью HashData, а затем сравнения с помощью CryptographicOperations.FixedTimeEquals. Новые методы Verify объединяют оба этапа в один безопасный вызов.
7. DivisionRounding для целочисленного деления
Добавлена поддержка альтернативных режимов округления при целочисленном делении с помощью нового перечисления DivisionRounding и новых методов в IBinaryInteger<T>: Divide, DivRem и Remainder. Большинство аппаратных средств реализуют деление нацело (/ и % в C#), но разные языки и предметные области требуют округления до большего или меньшего целого числа, евклидова округления или округления от нуля. Хотя это довольно тривиально, новые API позволяют выбрать правильный режим и хорошо оптимизированную реализацию:
int truncated =
int.Divide(-7, 2, DivisionRounding.Truncate); // -3
int floored =
int.Divide(-7, 2, DivisionRounding.Floor); // -4
// всегда неотрицательный
int euclideanRem =
int.Remainder(-7, 3, DivisionRounding.Euclidean); // 2
// Получаем частное и остаток сразу
var (q, r) =
int.DivRem(-7, 2, DivisionRounding.Floor); // q=-4, r=1
Окончание следует…
Источник: https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
1👍10
День 2583. #ЧтоНовенького #NET11
Вышла Превью 1 .NET 11. Окончание
Начало
.NET MAUI
1. Генерация исходного кода XAML по умолчанию в .NET MAUI. Чтобы вернуться к XAMLC, нужно добавить в файл проекта:
2. CoreCLR в качестве среды выполнения Android по умолчанию для релизных сборок. Это должно улучшить совместимость с остальными компонентами .NET, а также сократить время запуска при разумном увеличении размера приложения. Чтобы вернуться к Mono:
3. Интерактивный выбор целевой платформы и устройства для
Blazor
1. Новый компонент EnvironmentBoundary позволяет осуществлять условный рендеринг в зависимости от среды хостинга, аналогично тег-хелперу environment в MVC:
2. Blazor WebAssembly теперь поддерживает IHostedService для запуска фоновых сервисов в браузере и может получать доступ к переменным среды через IConfiguration для настройки во время выполнения без пересборки приложения.
3. Фреймворк также добавляет новые компоненты Label и DisplayName для форм. Они будут отображать значения из атрибутов [Display] или [DisplayName] свойства:
4. Добавлено событие щелчка по строкам в QuickGrid.
5. Относительная навигация в NavigationManager.NavigateTo() и NavLink с помощью опции RelativeToCurrentUri="true".
6. Шаблон проекта Blazor Web App теперь поддерживает опцию «Добавить поддержку контейнеризации» в Visual Studio.
ASP.NET Core
1. OpenAPI для конечных точек, возвращающих FileContentResult, теперь будет генерировать соответствующую документацию схемы:
2. Новый интерфейс IOutputCachePolicyProvider для динамических политик кэширования вывода. Этот интерфейс позволяет приложениям определять базовую политику кэширования по умолчанию, проверять наличие именованных политик и поддерживать сложные сценарии, в которых политики должны определяться динамически. Примерами являются загрузка политик из внешних источников конфигурации, баз данных или применение правил кэширования, специфичных для конкретного клиента.
3. Сертификаты разработчика в средах WSL теперь автоматически считаются доверенными как в WSL, так и в Windows.
Источник: https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
Вышла Превью 1 .NET 11. Окончание
Начало
.NET MAUI
1. Генерация исходного кода XAML по умолчанию в .NET MAUI. Чтобы вернуться к XAMLC, нужно добавить в файл проекта:
<PropertyGroup>
<MauiXamlInflator>XamlC</MauiXamlInflator>
</PropertyGroup>
2. CoreCLR в качестве среды выполнения Android по умолчанию для релизных сборок. Это должно улучшить совместимость с остальными компонентами .NET, а также сократить время запуска при разумном увеличении размера приложения. Чтобы вернуться к Mono:
<PropertyGroup>
<UseMonoRuntime>true</UseMonoRuntime>
</ProperyGroup>
3. Интерактивный выбор целевой платформы и устройства для
dotnet run. Теперь после запуска в консоли вам будет предложен выбор целевой платформы или устройства/эмулятора (если их несколько).Blazor
1. Новый компонент EnvironmentBoundary позволяет осуществлять условный рендеринг в зависимости от среды хостинга, аналогично тег-хелперу environment в MVC:
<EnvironmentBoundary Include="Development,Staging">
<p>Pre-production environment</p>
</EnvironmentBoundary>
2. Blazor WebAssembly теперь поддерживает IHostedService для запуска фоновых сервисов в браузере и может получать доступ к переменным среды через IConfiguration для настройки во время выполнения без пересборки приложения.
3. Фреймворк также добавляет новые компоненты Label и DisplayName для форм. Они будут отображать значения из атрибутов [Display] или [DisplayName] свойства:
<Label For="() => model.Name" />
4. Добавлено событие щелчка по строкам в QuickGrid.
5. Относительная навигация в NavigationManager.NavigateTo() и NavLink с помощью опции RelativeToCurrentUri="true".
6. Шаблон проекта Blazor Web App теперь поддерживает опцию «Добавить поддержку контейнеризации» в Visual Studio.
ASP.NET Core
1. OpenAPI для конечных точек, возвращающих FileContentResult, теперь будет генерировать соответствующую документацию схемы:
FileContentResult:
type: string
format: binary
2. Новый интерфейс IOutputCachePolicyProvider для динамических политик кэширования вывода. Этот интерфейс позволяет приложениям определять базовую политику кэширования по умолчанию, проверять наличие именованных политик и поддерживать сложные сценарии, в которых политики должны определяться динамически. Примерами являются загрузка политик из внешних источников конфигурации, баз данных или применение правил кэширования, специфичных для конкретного клиента.
3. Сертификаты разработчика в средах WSL теперь автоматически считаются доверенными как в WSL, так и в Windows.
Источник: https://github.com/dotnet/core/tree/main/release-notes/11.0/preview/preview1
1👍7
День 2584. #Карьера
Коллега Сказал Мне, что Мой Код «Уровня Джуна». Начало
47 комментариев. Я посчитал дважды, потому что сначала подумал, что что-то пошло не так. Может глюк утилиты сравнения? Но нет.
Знаете чувство, когда ты только что выпустил что-то, чем искренне гордишься. Я отправил PR, ожидая… ну, не знаю… пару придирок. Вместо этого я получил бесконечный документ с комментариями. Каждый комментарий — небольшой, точечный удар. А внизу, от инженера, которого я никогда не встречал, фраза, которая перевернула что-то внутри меня: «Это похоже на код джуна».
Я закрыл ноутбук, прогулялся вокруг квартала… дважды… Тот момент, когда обратная связь перестаёт касаться вашей работы и начинает ощущаться как касающаяся вас. Инстинкт срабатывает быстро. Отвергать. Защищаться. Обновить резюме.
Чего я тогда не понимал, но понимаю сейчас: самые болезненные отзывы часто несут в себе самый сильный сигнал. Не потому, что резкость — это хорошо. Но тот, кто готов быть настолько прямолинейным, обычно указывает на реальные проблемы, которых я не замечал.
PR, которым я гордился
Я работал уже 5 лет без нареканий. Получил уверенность, которая появляется, когда то, что вы выпускаете, в целом работает, и на вас никто не орёт. PR представлял собой рефакторинг конвейера данных. Около 800 строк в шести файлах. Тесты пройдены. Производительность улучшена. Я даже добавил подробные комментарии, что (как мне казалось) свидетельствовало о зрелости. В моей голове такой PR одобряют без лишних проблем, может быть, с небольшим комплиментом. Вместо этого я получил мастер-класс по всему, чего я не знал, что не знаю.
Коллега не указывал на ошибки. Он указывал на огрехи мышления. Паттерны, которые работали, но не выдержали бы контакта с реальностью. Абстракции, которые решали сегодняшнюю проблему, тихо закладывая основу для завтрашней.
Одна функция одновременно обрабатывала валидацию и преобразование. «Это разные обязанности», — написал коллега. «Когда требования изменятся, а они изменятся, ты потратишь дни на то, чтобы разобраться в этом».
Я написал умный код. Компактный. Гордился его плотностью. «Мне пришлось перечитывать это три раза», — один из комментариев. «Умно — значит дорого. Ясность — вот в чём ценность».
Моя обработка ошибок была оптимистической. Счастливый путь сиял, несчастливые пути были запутанными и несогласованными. «В проде в основном несчастливые пути. Твой код этого ещё не знает».
Моей первой реакцией было то, что коллега придирался. Код работал. Почему гипотетические будущие проблемы перевешивали текущую функциональность? Позже я понял, что эта реакция была именно тем пробелом, на который он указывал.
Я думал, что сеньор — это решение более сложных проблем. Более сложные алгоритмы и архитектуры. Это не так. Работа опытного инженера заключается в решении проблем таким образом, чтобы не создавать новых. Код, который выдерживает взаимодействие с коллегами, меняющиеся требования, инциденты в 2 часа ночи и вашу забывчивость. Речь идёт не о том, чтобы быть умным, а о том, чтобы быть внимательным к будущему.
На практике для меня это было неочевидно. Я оптимизировал код, ориентируясь на «работает ли это», вместо того чтобы оптимизировать его на «что произойдёт, когда это сломается».
Окончание следует…
Источник: https://medium.com/beyond-localhost/a-google-staff-engineer-told-me-my-code-was-junior-level-he-was-right-69ba2f80b7d3
Коллега Сказал Мне, что Мой Код «Уровня Джуна». Начало
47 комментариев. Я посчитал дважды, потому что сначала подумал, что что-то пошло не так. Может глюк утилиты сравнения? Но нет.
Знаете чувство, когда ты только что выпустил что-то, чем искренне гордишься. Я отправил PR, ожидая… ну, не знаю… пару придирок. Вместо этого я получил бесконечный документ с комментариями. Каждый комментарий — небольшой, точечный удар. А внизу, от инженера, которого я никогда не встречал, фраза, которая перевернула что-то внутри меня: «Это похоже на код джуна».
Я закрыл ноутбук, прогулялся вокруг квартала… дважды… Тот момент, когда обратная связь перестаёт касаться вашей работы и начинает ощущаться как касающаяся вас. Инстинкт срабатывает быстро. Отвергать. Защищаться. Обновить резюме.
Чего я тогда не понимал, но понимаю сейчас: самые болезненные отзывы часто несут в себе самый сильный сигнал. Не потому, что резкость — это хорошо. Но тот, кто готов быть настолько прямолинейным, обычно указывает на реальные проблемы, которых я не замечал.
PR, которым я гордился
Я работал уже 5 лет без нареканий. Получил уверенность, которая появляется, когда то, что вы выпускаете, в целом работает, и на вас никто не орёт. PR представлял собой рефакторинг конвейера данных. Около 800 строк в шести файлах. Тесты пройдены. Производительность улучшена. Я даже добавил подробные комментарии, что (как мне казалось) свидетельствовало о зрелости. В моей голове такой PR одобряют без лишних проблем, может быть, с небольшим комплиментом. Вместо этого я получил мастер-класс по всему, чего я не знал, что не знаю.
Коллега не указывал на ошибки. Он указывал на огрехи мышления. Паттерны, которые работали, но не выдержали бы контакта с реальностью. Абстракции, которые решали сегодняшнюю проблему, тихо закладывая основу для завтрашней.
Одна функция одновременно обрабатывала валидацию и преобразование. «Это разные обязанности», — написал коллега. «Когда требования изменятся, а они изменятся, ты потратишь дни на то, чтобы разобраться в этом».
Я написал умный код. Компактный. Гордился его плотностью. «Мне пришлось перечитывать это три раза», — один из комментариев. «Умно — значит дорого. Ясность — вот в чём ценность».
Моя обработка ошибок была оптимистической. Счастливый путь сиял, несчастливые пути были запутанными и несогласованными. «В проде в основном несчастливые пути. Твой код этого ещё не знает».
Моей первой реакцией было то, что коллега придирался. Код работал. Почему гипотетические будущие проблемы перевешивали текущую функциональность? Позже я понял, что эта реакция была именно тем пробелом, на который он указывал.
Я думал, что сеньор — это решение более сложных проблем. Более сложные алгоритмы и архитектуры. Это не так. Работа опытного инженера заключается в решении проблем таким образом, чтобы не создавать новых. Код, который выдерживает взаимодействие с коллегами, меняющиеся требования, инциденты в 2 часа ночи и вашу забывчивость. Речь идёт не о том, чтобы быть умным, а о том, чтобы быть внимательным к будущему.
На практике для меня это было неочевидно. Я оптимизировал код, ориентируясь на «работает ли это», вместо того чтобы оптимизировать его на «что произойдёт, когда это сломается».
Окончание следует…
Источник: https://medium.com/beyond-localhost/a-google-staff-engineer-told-me-my-code-was-junior-level-he-was-right-69ba2f80b7d3
👍49👎2
День 2585. #Карьера
Коллега Сказал Мне, что Мой Код «Уровня Джуна». Окончание
Начало
Три шаблона, которые изменили всё
Коллега не просто критиковал мой код. В последующем разговоре он перестроил мою ментальную модель, внушив мне три идеи, которые я теперь постоянно использую.
1. Разделяйте «что» и «как»
Мои функции делали слишком много, потому что я мыслил задачами, а не обязанностями. Теперь я спрашиваю себя: «Что заставит меня переписать это?» Если для функции есть несколько вариантов ответа, я разделяю её. Код становится длиннее, но его гораздо проще изменить.
2. Пишите код для того, кто отлаживает его в 2 часа ночи
Этот человек может оказаться вами через полгода, когда контекст полностью забудется. Правило простое. Если для понимания требуется удерживать в голове более 3 вещей одновременно, проводите рефакторинг, пока это не перестанет быть необходимым.
3. Изначально проектируйте с учётом возможных ошибок
Большинство из нас проектируют оптимальный сценарий, а обработку ошибок добавляют потом. Делайте наоборот. Начните с перечисления всех возможных способов поломки. Постройте сценарий успешного выполнения как один из многих вариантов. Этот единственный сдвиг мышления полностью изменил мои представления о надёжности.
Нюанс, который я чуть не упустил
Вот что вызывает дискомфорт. Подача коллеги не была идеальной. 47 комментариев, кульминацией чего стало «код уровня джуна», — это обидно. Во многих командах это воспринимается слишком резко. Но информация была точной.
В этом и проблема. Обратная связь может быть слишком резкой и одновременно совершенно правильной. Подача информации может стоить обсуждения с вашим руководителем. Содержание же при этом может быть невероятно полезным.
Теперь я научился разделять эти вещи. Реагировать на тон потом. Сначала воспринимать сигнал. Не каждому достанется такой коллега, который готов всё объяснить. Некоторые строгие рецензенты просто грубы. Никаких уроков, только резкость. Нужно научиться различать.
Что на самом деле изменилось
Три месяца спустя. PR аналогичного размера. Тот же рецензент. 4 комментария. Три были придирками. Один - действительно ценным замечанием. Разница была не в том, что я работал усерднее, а в том, что я стал по-другому смотреть на код.
Прежде чем что-либо отправить, я задаю себе три вопроса:
- Если требования изменятся, какие функции сломаются первыми?
- Что запутает другого разработчика, который будет читать это во время инцидента в 2 часа ночи?
- Важны ли для меня пути ошибок так же, как и пути успешного выполнения?
Эти вопросы больше меня не замедляют. Это просто мой нынешний образ мышления.
Возвращаясь к тому случаю
Я до сих пор помню жар на лице. Обида ещё не полностью утихла. Может быть, и не должна. Но вот что я теперь знаю. Этот дискомфорт был ощущением, будто мой потолок поднимается. Через боль, но поднимается.
Код, который я пишу сегодня, был бы неузнаваем для человека, отправившего этот PR. Не потому, что я стал умнее. А потому, что кто-то указал на то, чего я сам не видел. Если вы сейчас получаете болезненный отзыв, задайте себе один вопрос: указывает ли этот человек на что-то реальное, даже если он делает это грубо?
Иногда ответ — нет. Игнорируйте такой отзыв. Но иногда ответ — да. И вот тогда начинается настоящая работа.
Источник: https://medium.com/beyond-localhost/a-google-staff-engineer-told-me-my-code-was-junior-level-he-was-right-69ba2f80b7d3
Коллега Сказал Мне, что Мой Код «Уровня Джуна». Окончание
Начало
Три шаблона, которые изменили всё
Коллега не просто критиковал мой код. В последующем разговоре он перестроил мою ментальную модель, внушив мне три идеи, которые я теперь постоянно использую.
1. Разделяйте «что» и «как»
Мои функции делали слишком много, потому что я мыслил задачами, а не обязанностями. Теперь я спрашиваю себя: «Что заставит меня переписать это?» Если для функции есть несколько вариантов ответа, я разделяю её. Код становится длиннее, но его гораздо проще изменить.
2. Пишите код для того, кто отлаживает его в 2 часа ночи
Этот человек может оказаться вами через полгода, когда контекст полностью забудется. Правило простое. Если для понимания требуется удерживать в голове более 3 вещей одновременно, проводите рефакторинг, пока это не перестанет быть необходимым.
3. Изначально проектируйте с учётом возможных ошибок
Большинство из нас проектируют оптимальный сценарий, а обработку ошибок добавляют потом. Делайте наоборот. Начните с перечисления всех возможных способов поломки. Постройте сценарий успешного выполнения как один из многих вариантов. Этот единственный сдвиг мышления полностью изменил мои представления о надёжности.
Нюанс, который я чуть не упустил
Вот что вызывает дискомфорт. Подача коллеги не была идеальной. 47 комментариев, кульминацией чего стало «код уровня джуна», — это обидно. Во многих командах это воспринимается слишком резко. Но информация была точной.
В этом и проблема. Обратная связь может быть слишком резкой и одновременно совершенно правильной. Подача информации может стоить обсуждения с вашим руководителем. Содержание же при этом может быть невероятно полезным.
Теперь я научился разделять эти вещи. Реагировать на тон потом. Сначала воспринимать сигнал. Не каждому достанется такой коллега, который готов всё объяснить. Некоторые строгие рецензенты просто грубы. Никаких уроков, только резкость. Нужно научиться различать.
Что на самом деле изменилось
Три месяца спустя. PR аналогичного размера. Тот же рецензент. 4 комментария. Три были придирками. Один - действительно ценным замечанием. Разница была не в том, что я работал усерднее, а в том, что я стал по-другому смотреть на код.
Прежде чем что-либо отправить, я задаю себе три вопроса:
- Если требования изменятся, какие функции сломаются первыми?
- Что запутает другого разработчика, который будет читать это во время инцидента в 2 часа ночи?
- Важны ли для меня пути ошибок так же, как и пути успешного выполнения?
Эти вопросы больше меня не замедляют. Это просто мой нынешний образ мышления.
Возвращаясь к тому случаю
Я до сих пор помню жар на лице. Обида ещё не полностью утихла. Может быть, и не должна. Но вот что я теперь знаю. Этот дискомфорт был ощущением, будто мой потолок поднимается. Через боль, но поднимается.
Код, который я пишу сегодня, был бы неузнаваем для человека, отправившего этот PR. Не потому, что я стал умнее. А потому, что кто-то указал на то, чего я сам не видел. Если вы сейчас получаете болезненный отзыв, задайте себе один вопрос: указывает ли этот человек на что-то реальное, даже если он делает это грубо?
Иногда ответ — нет. Игнорируйте такой отзыв. Но иногда ответ — да. И вот тогда начинается настоящая работа.
Источник: https://medium.com/beyond-localhost/a-google-staff-engineer-told-me-my-code-was-junior-level-he-was-right-69ba2f80b7d3
👍19
День 2586. #ВопросыНаСобеседовании
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
24. Agile и Scrum
«Расскажите, как методологии Agile и Scrum могут быть полезны в проектах разработки ПО? Применяли ли вы практики Scrum в своих прошлых проектах».
Хороший ответ
Agile и Scrum предоставляют структурированную, но гибкую основу для управления проектами разработки, особенно подходящую для сред, где требования быстро меняются. Agile фокусируется на непрерывном совершенствовании, гибком реагировании на изменения и предоставлении высококачественного ПО. Scrum реализует принципы Agile посредством определённых ролей, ритуалов и артефактов.
Преимущества
1. Итеративная разработка: Частые итерации (спринты) позволяют получать регулярную обратную связь и быстро адаптироваться к изменениям. Это особенно полезно в проектах .NET, интегрирующих различные технологии и фреймворки, которые могут развиваться в течение цикла разработки.
2. Сотрудничество и коммуникация в команде: Scrum улучшает сотрудничество в команде, чётко определяя роли (Scrum-мастер, владелец продукта, команда разработчиков) и поощряя ежедневные совещания для обсуждения прогресса и препятствий. Так все члены команды согласованы и могут эффективно сотрудничать над решениями.
3. Фокус на ценности для пользователя: Scrum поощряет расстановку приоритетов в работе. Это позволяет максимально эффективно использовать ресурсы, что обеспечивается бэклогом продукта и планированием спринта.
В предыдущем проекте на .NET мы использовали Scrum для разработки сложного корпоративного приложения. Мы организовали работу в двухнедельные спринты. Каждый спринт начинался с совещания по планированию, где команда коллективно определяла объём работы, которую необходимо выполнить.
Во время спринтов ежедневные совещания помогали выявлять препятствия и синхронизировать действия, чтобы убедиться, что мы движемся в правильном направлении. В конце каждого спринта проводились ретроспективы для обсуждения, что прошло хорошо, а что можно улучшить. Мы также проводили регулярные совещания с заинтересованными сторонами для демонстрации новых функций, обеспечивая соответствие разработки потребностям бизнеса и корректируя бэклог продукта по мере необходимости.
Пример цикла спринта
- Планирование: определите цель спринта и выберите задачи из бэклога.
- Ежедневные совещания: короткие встречи для обсуждения прогресса и препятствий.
- Обзор: демонстрация завершённых функций заинтересованным сторонам для получения обратной связи.
- Ретроспектива: командный анализ прошедшего спринта для выявления возможностей улучшения процесса.
Часто встречающийся плохой ответ
«Scrum — это ежедневные совещания и работа в коротких циклах.»
Почему это неправильно:
- Упрощение: Этот ответ значительно упрощает Scrum, сводя его к ежедневным совещаниям и коротким рабочим циклам. Scrum включает в себя гораздо больше: роли, события, артефакты и стремление к постоянному совершенствованию.
- Неправильное понимание элементов Scrum: игнорируются такие важные элементы, как важность бэклога продукта, планирование спринтов, обзоры и ретроспективы.
- Отсутствие внимания к принципам: не рассматриваются основополагающие принципы Agile, которые воплощает Scrum, такие как реагирование на изменения, частая поставка и сотрудничество бизнеса и разработчиков.
Эта ошибка часто возникает из-за поверхностного понимания методологии, возможно, из-за наблюдения или участия в неправильно реализованных средах Scrum.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
24. Agile и Scrum
«Расскажите, как методологии Agile и Scrum могут быть полезны в проектах разработки ПО? Применяли ли вы практики Scrum в своих прошлых проектах».
Хороший ответ
Agile и Scrum предоставляют структурированную, но гибкую основу для управления проектами разработки, особенно подходящую для сред, где требования быстро меняются. Agile фокусируется на непрерывном совершенствовании, гибком реагировании на изменения и предоставлении высококачественного ПО. Scrum реализует принципы Agile посредством определённых ролей, ритуалов и артефактов.
Преимущества
1. Итеративная разработка: Частые итерации (спринты) позволяют получать регулярную обратную связь и быстро адаптироваться к изменениям. Это особенно полезно в проектах .NET, интегрирующих различные технологии и фреймворки, которые могут развиваться в течение цикла разработки.
2. Сотрудничество и коммуникация в команде: Scrum улучшает сотрудничество в команде, чётко определяя роли (Scrum-мастер, владелец продукта, команда разработчиков) и поощряя ежедневные совещания для обсуждения прогресса и препятствий. Так все члены команды согласованы и могут эффективно сотрудничать над решениями.
3. Фокус на ценности для пользователя: Scrum поощряет расстановку приоритетов в работе. Это позволяет максимально эффективно использовать ресурсы, что обеспечивается бэклогом продукта и планированием спринта.
В предыдущем проекте на .NET мы использовали Scrum для разработки сложного корпоративного приложения. Мы организовали работу в двухнедельные спринты. Каждый спринт начинался с совещания по планированию, где команда коллективно определяла объём работы, которую необходимо выполнить.
Во время спринтов ежедневные совещания помогали выявлять препятствия и синхронизировать действия, чтобы убедиться, что мы движемся в правильном направлении. В конце каждого спринта проводились ретроспективы для обсуждения, что прошло хорошо, а что можно улучшить. Мы также проводили регулярные совещания с заинтересованными сторонами для демонстрации новых функций, обеспечивая соответствие разработки потребностям бизнеса и корректируя бэклог продукта по мере необходимости.
Пример цикла спринта
- Планирование: определите цель спринта и выберите задачи из бэклога.
- Ежедневные совещания: короткие встречи для обсуждения прогресса и препятствий.
- Обзор: демонстрация завершённых функций заинтересованным сторонам для получения обратной связи.
- Ретроспектива: командный анализ прошедшего спринта для выявления возможностей улучшения процесса.
Часто встречающийся плохой ответ
«Scrum — это ежедневные совещания и работа в коротких циклах.»
Почему это неправильно:
- Упрощение: Этот ответ значительно упрощает Scrum, сводя его к ежедневным совещаниям и коротким рабочим циклам. Scrum включает в себя гораздо больше: роли, события, артефакты и стремление к постоянному совершенствованию.
- Неправильное понимание элементов Scrum: игнорируются такие важные элементы, как важность бэклога продукта, планирование спринтов, обзоры и ретроспективы.
- Отсутствие внимания к принципам: не рассматриваются основополагающие принципы Agile, которые воплощает Scrum, такие как реагирование на изменения, частая поставка и сотрудничество бизнеса и разработчиков.
Эта ошибка часто возникает из-за поверхностного понимания методологии, возможно, из-за наблюдения или участия в неправильно реализованных средах Scrum.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
День 2587. #Оффтоп
Я уже писал об этом инциденте, который чуть не обрушил интернет, дав root-доступ ко всем Linux-машинам. Но один из моих любимых каналов про науку, Veritasium, выпустил часовой ролик с подробным разбором инцидента.
Обычно там физика, астрономия, биология и прочие железячки. А тут они решили рассказать про софт. А конкретнее – про один из самых опасных инцидентов, который, к счастью, не случился, но по чистой случайности.
Наверняка все видели картинку ниже. Но кто бы мог предположить, что шутка про то, что вся современная цифровая инфраструктура держится на проекте, который какой-то чувак бесплатно поддерживает в одиночку десятилетиями – эта шутка в итоге окажется совсем не шуткой.
В общем, интереснейшая история о возникновении ПО с открытым кодом, о возникновении Linux, о зависимостях и их мейнтейнерах. И как работник Microsoft и мейнтейнер PostgreSql, тестируя работу постгреса в превью новой версии Red Hat Linux, случайно обнаружил вредоносный код, который грозил (без преувеличения) разрушить Интернет.
https://youtu.be/aoag03mSuXQ
Приятного просмотра.
Я уже писал об этом инциденте, который чуть не обрушил интернет, дав root-доступ ко всем Linux-машинам. Но один из моих любимых каналов про науку, Veritasium, выпустил часовой ролик с подробным разбором инцидента.
Обычно там физика, астрономия, биология и прочие железячки. А тут они решили рассказать про софт. А конкретнее – про один из самых опасных инцидентов, который, к счастью, не случился, но по чистой случайности.
Наверняка все видели картинку ниже. Но кто бы мог предположить, что шутка про то, что вся современная цифровая инфраструктура держится на проекте, который какой-то чувак бесплатно поддерживает в одиночку десятилетиями – эта шутка в итоге окажется совсем не шуткой.
В общем, интереснейшая история о возникновении ПО с открытым кодом, о возникновении Linux, о зависимостях и их мейнтейнерах. И как работник Microsoft и мейнтейнер PostgreSql, тестируя работу постгреса в превью новой версии Red Hat Linux, случайно обнаружил вредоносный код, который грозил (без преувеличения) разрушить Интернет.
https://youtu.be/aoag03mSuXQ
Приятного просмотра.
👍11
День 2588. #Карьера #AI
Топ Советов по Повышению Продуктивности. Часть 10. Начало
Части 1, 2, 3, 4, 5, 6, 7, 8, 9
10. Используйте инструменты ИИ, но не позволяйте им думать за вас
ИИ-помощники коренным образом изменили разработку. Они теперь могут писать значительные фрагменты кода. Если их игнорировать, вы сами себе создадите препятствия. Чрезмерная зависимость от них приведёт к атрофии необходимых навыков. Оптимально использовать ИИ-инструменты как помощников, а не как замену.
Польза ИИ-помощников
1. Устранение шаблонного кода
Нужен REST API со стандартным CRUD? Нужен шаблонный код для тестов? Они мгновенно генерируют структуру, а вы настраиваете важные части.
2. Объяснение и документация
Столкнулись с незнакомым кодом? Работаете со сложным алгоритмом? Они могут объяснить происходящее простым языком. Это как иметь опытного разработчика, доступного 24/7 для вопросов типа "как это работает?".
3. Помощь в отладке
Часто они мгновенно обнаруживают проблему или предлагают стратегии отладки, которые вы не рассматривали.
4. Преобразование кода
Обновить проект до новой версии .NET? Перевести TypeScript на JavaScript? ИИ-инструменты мгновенно и, как правило, корректно обрабатывают эти механические преобразования.
5. Ускоритель обучения
Хотите разобраться в новом фреймворке? Они могут генерировать примеры кода, объяснять концепции и отвечать на дополнительные вопросы. Это интерактивная документация, которая адаптируется к вашему стилю обучения.
Опасность ИИ-инструментов
1. Архитектурные решения
Они предлагают шаблоны, но не понимают ограничений вашей системы, соглашений команды или ваших потребностей в долгосрочной поддержке. Они предлагают «решение», а не «решение для вас».
2. Код, критически важный для безопасности
Сгенерированный ИИ код аутентификации, авторизации, криптографии или проверки данных требует предельной тщательности. ИИ-инструменты могут генерировать правдоподобно выглядящий код с едва заметными уязвимостями безопасности.
3. Специфическая для предметной области логика
Ваши бизнес-правила, модель данных, уникальные крайние случаи — ИИ-инструменты этого не знают. Они предложат общие решения, которые могут быть совершенно неподходящими для вашего контекста.
4. Сложное управление состоянием
ИИ-инструменты испытывают трудности со сложными взаимодействиями состояний, состояниями гонки и сложными асинхронными потоками. Они сгенерируют код, который работает в оптимальном сценарии, но дает сбои в крайних случаях.
5. Код, критически важный для производительности
В коде, сгенерированном ИИ, приоритет отдаётся корректности и ясности, а не производительности. Если вы оптимизируете ресурсоёмкие сценарии или работаете с большими наборами данных, необходима оценка сложности алгоритма и стратегий оптимизации, сделанная человеком.
Окончание следует…
Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
Топ Советов по Повышению Продуктивности. Часть 10. Начало
Части 1, 2, 3, 4, 5, 6, 7, 8, 9
10. Используйте инструменты ИИ, но не позволяйте им думать за вас
ИИ-помощники коренным образом изменили разработку. Они теперь могут писать значительные фрагменты кода. Если их игнорировать, вы сами себе создадите препятствия. Чрезмерная зависимость от них приведёт к атрофии необходимых навыков. Оптимально использовать ИИ-инструменты как помощников, а не как замену.
Польза ИИ-помощников
1. Устранение шаблонного кода
Нужен REST API со стандартным CRUD? Нужен шаблонный код для тестов? Они мгновенно генерируют структуру, а вы настраиваете важные части.
2. Объяснение и документация
Столкнулись с незнакомым кодом? Работаете со сложным алгоритмом? Они могут объяснить происходящее простым языком. Это как иметь опытного разработчика, доступного 24/7 для вопросов типа "как это работает?".
3. Помощь в отладке
Часто они мгновенно обнаруживают проблему или предлагают стратегии отладки, которые вы не рассматривали.
4. Преобразование кода
Обновить проект до новой версии .NET? Перевести TypeScript на JavaScript? ИИ-инструменты мгновенно и, как правило, корректно обрабатывают эти механические преобразования.
5. Ускоритель обучения
Хотите разобраться в новом фреймворке? Они могут генерировать примеры кода, объяснять концепции и отвечать на дополнительные вопросы. Это интерактивная документация, которая адаптируется к вашему стилю обучения.
Опасность ИИ-инструментов
1. Архитектурные решения
Они предлагают шаблоны, но не понимают ограничений вашей системы, соглашений команды или ваших потребностей в долгосрочной поддержке. Они предлагают «решение», а не «решение для вас».
2. Код, критически важный для безопасности
Сгенерированный ИИ код аутентификации, авторизации, криптографии или проверки данных требует предельной тщательности. ИИ-инструменты могут генерировать правдоподобно выглядящий код с едва заметными уязвимостями безопасности.
3. Специфическая для предметной области логика
Ваши бизнес-правила, модель данных, уникальные крайние случаи — ИИ-инструменты этого не знают. Они предложат общие решения, которые могут быть совершенно неподходящими для вашего контекста.
4. Сложное управление состоянием
ИИ-инструменты испытывают трудности со сложными взаимодействиями состояний, состояниями гонки и сложными асинхронными потоками. Они сгенерируют код, который работает в оптимальном сценарии, но дает сбои в крайних случаях.
5. Код, критически важный для производительности
В коде, сгенерированном ИИ, приоритет отдаётся корректности и ясности, а не производительности. Если вы оптимизируете ресурсоёмкие сценарии или работаете с большими наборами данных, необходима оценка сложности алгоритма и стратегий оптимизации, сделанная человеком.
Окончание следует…
Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
54👍6
День 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