.NET Разработчик
6.53K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День восемьсот пятьдесят пятый. #Оффтоп #КакСтатьСеньором
После некоторого перерыва продолжу серию #КакСтатьСеньором с простыми, но полезными советами.

Написание Кода
1. Legacy-код и следующий разработчик
Вы когда-нибудь смотрели на код и чувствовали, что тут что-то не так? Зачем они так сделали? В этом нет никакого смысла. Я имел счастье работать с устаревшей кодовой базой. С комментариями типа
//Раскомментировать этот код, когда прояснится ситуация с Мухамедом
Что это? Кто такой Мухамед?

То же относится к вам. Подумайте о следующем человеке, который прочитает ваш код. Код покажется ему странным? Обзор кода частично решает эту проблему. Это привело меня к идее контекста: осознавать контекст, в котором работает команда.

Если я забуду код, вернусь к нему позже и не смогу воссоздать контекст, в котором был написан код, я подумаю: «Какой дебил это написал? Тут нет никакого смысла… Ой, это же я написал». И здесь на помощь приходит документация и комментарии.

2. Документация и комментарии
Документация – головная боль для большинства команд разработчиков. Не только комментарии, но и описание процессов, связанных с кодом. Но они помогают сохранять контекст и делиться знаниями. Основная ценность программного обеспечения - это не созданный код, а знания, накопленные людьми, которые его создали.

У нас есть конечная точка клиентского API, которую, казалось, никто никогда не использовал. Просто удалим её? В конце концов, это технический долг. А что, если раз в год 10 человек отправляют свои отчёты на эту конечную точку? Как это проверить? Если документации нет, то никак. Мы удалили эту конечную точку. Через несколько месяцев наступило то самое время года. Пользователи не смогли отправить 10 важных отчетов, потому что конечной точки больше не существовала. Люди, знавшие продукт, давно покинули команду. Конечно, теперь в коде есть комментарии, объясняющие, для чего предназначена эта конечная точка.

3. Атомарные коммиты
Если вам придётся откатить ваши изменения (а вам рано или поздно придётся это сделать), что случится с приложением? Атомарен ли ваш коммит? То есть, переводит ли он приложение из одного стабильного состояния в другое (например, проект компилируется и до ваших изменений, и после)?

4. Уверенность в удалении плохого кода
Поначалу мне было очень неловко удалять плохой или устаревший код. Я считал священным то, что когда-то было написано, тем более не мной. Я размышлял так: «Когда это писали, они явно хотели этим что-то сказать». Это традиции и культура против рационального мышления. Отчасти такие мысли подкрепляются случаями, вроде удаления той конечной точки.

Я пытался во что бы то ни стало сохранить код, придумывая костыли для обхода, тогда как сеньор безропотно бы его удалил. Удаляйте. Блок if, который никогда не выполнится, функцию, которую не нужно вызывать. В противном случае вы просто увеличите сложность кода и технический долг. Следующему человеку будет ещё труднее понять, что тут происходит.

Правило: есть код, которого вы не понимаете, и код, который никогда будет достигнут. Удалите код, который не достигается, и будьте осторожны с кодом, который вы не понимаете.

5. Обзоры кода
Обзоры кода великолепны для обучения. Это внешний цикл обратной связи о том, как вы пишете код и как его пишут другие. В чем разница? Один способ лучше другого? Я задавал себе этот вопрос на каждом обзоре: «Почему они сделали это именно так?». Когда я не мог найти подходящего ответа, я приходил поговорить с коллегами.

По прошествии первого месяца я начал замечать ошибки в коде моих коллег (а они замечали мои). Рецензирование стало для меня намного интереснее. Это была игра, которую я с нетерпением ждал. Игра, которая улучшит моё восприятие кода.
Правило: не одобряйте код, пока не поймёте, как он работает.

Источник:
https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
День восемьсот шестьдесят второй. #Оффтоп #КакСтатьСеньором

Тестирование
Я настолько полюбил тестирование, что мне неловко писать код без тестов.

Если ваше приложение выполняет всего одну задачу (как школьная лабораторная работа), то ручное тестирование ещё приемлемо. Раньше я так и делал. А что, если приложение выполняет сотню различных действий? Я не хочу тратить полчаса на тестирование всего функционала, а иногда и забывать, что мне нужно проверить.

Я думаю о тестировании как о документировании. Это документация, подтверждающая мои предположения о коде. Тесты говорят мне, что я ожидаю от работы кода, и сообщают мне обо всех случаях, когда что-то идёт не так.

Итак, когда я пишу тесты, я:
1. Демонстрирую, как использовать класс/функцию/систему, которую я тестирую.
2. Демонстрирую всё, что может пойти не так.
3. В большинстве случаев тестирую поведение (публичный API), а не реализацию.

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

Просто написание этих тестов не улучшает качество моего кода, в отличие от написания самого кода. Но понимание, которое я получаю от чтения тестов, помогает мне писать лучший код.

Но это не единственный вид тестирования.

Есть машины, на которых вы разрабатываете (источник всех мемов «Оно работает на моей машине!»). Есть машины, на которых вы тестируете (зачастую, это те же машины для разработки). И наконец, есть машины, на которых вы развёртываете приложение. Если существует несоответствие среды между тестовой и производственной машинами, у вас будут проблемы.

У нас есть локальная разработка, например, в докере на машине разработчика. Есть среда разработки, где установлен набор библиотек (и инструментов разработки). Туда мы устанавливаем код, который мы пишем, и там же проводим все тесты с другими зависимыми системами. Затем идёт среда бета (staging), которая в точности совпадает с производственной средой. Наконец, производственная среда, состоящая из машин, на которых выполняется код и обслуживает реальных клиентов.

Идея состоит в том, чтобы попытаться выявить ошибки, которые не удалось бы выявить при модульном и системном тестировании. Например, несоответствие API запрашивающей и отвечающей системы.

Думаю, всё было бы по-другому в личном проекте или в небольшой компании. Не у всех есть ресурсы для создания собственной инфраструктуры. Однако эта идея актуальна для облачных провайдеров, таких как AWS и Azure.

Вы можете настроить отдельные кластеры для разработки и производственной среды. AWS ECS использует для развёртывания образы докеров, поэтому в разных средах всё относительно единообразно. Сложность - это интеграция с другими облачными сервисами: вызывать нужную конечную точку из правильной среды.

Источник: https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
День восемьсот семьдесят второй. #Оффтоп #КакСтатьСеньором

Проектирование
Почему я ставлю проектирование после написания кода и тестирования? Оно может идти и первым, но, если бы я не писал код и не тестировал его в среде, в которой я нахожусь (под средой тут понимается в том числе и стек технологий), я, вероятно, не смог бы спроектировать систему, которая учитывает особенности среды.
При проектировании системы нужно о многом подумать:
- Какая будет нагрузка?
- Сколько существует пользователей и каков их ожидаемый прирост? (Это может повлиять на размер БД)
- Какие могут быть подводные камни в будущем?

Всё это нужно преобразовать в контрольный список требований. Тут важно соблюсти баланс: какую часть вы можете спроектировать, прежде чем приступить к реализации? Когда имеет смысл нырять с головой в реализацию, а когда делать шаг назад?

Конечно, просто собрать требования - это еще не всё, о чем стоит подумать. Включение процессов разработки в проектирование также окупается:
- Как будет организовано написание кода, сборка, развёртывание и CI/CD?
- Как мы будем проводить сквозное и нагрузочное тестирование?
- Как мы будем управлять секретами?

Например, кто бы мог подумать, что управление секретами в производственной среде может оказаться таким сложным? Вы не можете поместить их в код, так как тогда их сможет увидеть любой.
Поместить их в переменные среды? Хорошая идея. Как их туда поместить и как ими управлять? Хранить файл секретов? Откуда он будет браться и как его изменять? И т.д., и т.п. Кроме того, мы не хотим, чтобы всё это выполнялось вручную. Можно рассмотреть базу данных, чтобы код получал секреты из базы при запуске. Опять же, подход может сильно отличаться при использовании облачного провайдера, где не нужно много думать о секретах, т.к. для этого есть специальный функционал.

Проектирование с учетом поддержки
Проектировать системы - это увлекательно. Поддерживать их – не очень. Рано или поздно задаёшься вопросом, почему и как системы деградируют?

Во-первых, проблема в нежелании выбрасывать старые вещи, всегда добавляя новые. Склонность к добавлению вместо удаления (есть за вами такой грешок?)

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

Есть как минимум три способа снизить скорость деградации:
1. Разделяйте бизнес-логику и инфраструктуру. Обычно быстрее деградирует инфраструктура: увеличивается нагрузка, фреймворки устаревают, появляются уязвимости и т.д.
2. Стройте процессы вокруг поддержки. Обновляйте как новый, так и устаревший код. Это предотвращает различие между новыми и старыми частями и сохраняет весь код «современным».
3. Убедитесь, что вы на постоянной основе избавляетесь от всех ненужных/устаревших вещей.

Источник:
https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
День восемьсот девяносто третий. #Оффтоп #КакСтатьСеньором
Когда Дела Идут не по Плану
Когда что-то идёт не так, а такое рано или поздно обязательно случится, золотое правило - свести к минимуму влияние на клиента.

Раньше, когда что-то шло не так, моей первой реакцией было устранить проблему. Оказывается, это не самое оптимальное решение. Вместо того, чтобы исправлять то, что пошло не так, даже если это «изменение одной строки», первое, что нужно сделать, - это откатиться. Вернитесь в предыдущее рабочее состояние. Это самый быстрый способ вернуть клиентов к рабочей версии.

Только после этого можно искать, что пошло не так, и исправлять эти ошибки. Тот же подход, что и с глючащей машиной в вашем кластере: отключите её, отметьте как недоступную, прежде чем пытаться выяснить, что с ней не так.

Странно, как мои естественные склонности и инстинкты расходятся с оптимальным решением. Думаю, что этот инстинкт также ведёт меня по более долгому пути в исправлении ошибок. Иногда мне кажется, что это не работает, потому что что-то не так с тем, что я написал, и я погружаюсь в исходники, просматривая каждую строку кода. Что-то вроде «поиска в глубину».

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

Теперь мой подход заключается в том, чтобы выполнять «поиск в ширину» перед «поиском в глубину», чтобы избавиться от узлов верхнего уровня. Что я могу проверить на верхнем уровне?
- Машина работает?
- Установлен правильный код?
- Конфигурация на месте?
- Правильно ли задана конфигурация для конкретного кода, например, правильная ли маршрутизация в коде?
- Обновлена ли база данных?
И только потом можно искать ошибку в коде.

«Мы думали, что nginx некорректно установился на машине, но оказалось, что просто в конфигурации было установлено значение false.»

Конечно, не нужно делать так всегда. Иногда достаточно просто сообщения об ошибке, чтобы сузить пространство поиска и сразу лезть в код.

Когда я не могу понять, в чём проблема, я стараюсь свести к минимуму изменения кода, чтобы выяснить, что не так. Чем меньше изменений, тем быстрее я смогу найти реальную проблему.

Я также теперь веду дневник ошибок, на устранение которых мне потребовалось более 1 часа: Чего мне не хватило? О чём я не подумал? Обычно это какое-нибудь мелкое дерьмо, которое я забыл проверить, например, настройка маршрутизации, соответствие версии схемы и версии сервиса и т. д. Это ещё один шаг знакомства с используемым мной технологическим стеком, и то, что даёт только опыт: интуицию для точного понимания того, почему что-то не работает.

Источник: https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
День 1191.
Подборка тегов, используемых в постах на канале, чтобы облегчить поиск. Не могу гарантировать, что все 1190 постов идеально и корректно помечены тегами, но всё-таки, эта подборка должна помочь.

Общие
Эти посты на совершенно разные темы, помечены этими тегами только с целью различать общую направленность поста.

#ЗаметкиНаПолях – технические посты. Краткие описания теории, особенности языка C# и платформы .NET, примеры кода, и т.п.

#Шпаргалка - примеры кода, команды для утилит и т.п.

#Юмор – шутки, комиксы и просто весёлые тексты или ссылки на видео.

#Оффтоп – всё прочее.


Специализированные
Эти теги более тематические, выделяют основную тему поста.

#Карьера – советы по повышению продуктивности, карьерному росту, прохождению собеседований и т.п.

#Книги – обзоры книг, которые (чаще всего) я лично прочитал, либо ещё нет, но советую прочитать.

#Курсы – обзоры и ссылки на онлайн курсы.

#МоиИнструменты – различные программы, утилиты и расширения IDE, которые я использую в работе.

#ЧтоНовенького – новости из мира .NET.


Узкоспециализированные
Эти теги относятся к определённой узкой теме.

#AsyncTips – серия постов из книги Стивена Клири “Конкурентность в C#”
#AsyncAwaitFAQ – серия постов “Самые Частые Ошибки при Работе с async/await.”

#BestPractices – советы по лучшим практикам, паттернам разработки.

#DesignPatterns – всё о паттернах проектирования, SOLID, IDEALS и т.п.

#DotNetAZ – серия постов с описанием терминов из мира .NET.

#GC – серия постов “Топ Вопросов о Памяти в .NET.” от Конрада Кокосы.

#MoreEffectiveCSharp – серия постов из книги Билла Вагнера “More Effective C#”.

#Testing – всё о тестировании кода.

#TipsAndTricks – советы и трюки, в основном по функционалу Visual Studio.

#Quiz - опросы в виде викторины.

#97Вещей – серия постов из книги “97 Вещей, Которые Должен Знать Каждый Программист”.

#ВопросыНаСобеседовании – тег говорит сам за себя, самые часто задаваемые вопросы на собеседовании по C#, ASP.NET и .NET.
#ЗадачиНаСобеседовании – похоже на вопросы, но здесь больше приводятся практические задачи. Чаще всего это 2 поста: собственно задача и ответ с разбором.

#КакСтатьСеньором – серия постов «Как Стать Сеньором» с советами о продвижении по карьерной лестнице.

Помимо этого, можно просто воспользоваться поиском по постам и попробовать найти то, что вам нужно.
1👍60👎1
День 2165. #Оффтоп #AI
ИИ не Заменит Команду Инженеров. Начало
Если позволите, я тоже немного отдохну. Поэтому вот вам лёгкий лонгрид на праздники.

На заре распространения персональных компьютеров найти работу сисадмином или веб-дизайнером было проще простого. Если ты знал пяток команд командной строки и мог набросать простенькую HTML-форму, обязательно нашёлся бы тот, кто был согласен тебе платить. Не нужно было даже образования. Только настойчивость и желание работать. Сейчас это совсем не так.

В какой-то степени это всегда происходит, когда отрасль взрослеет. Ранние дни любой отрасли — это что-то вроде Дикого Запада, где ставки низкие, регулирование отсутствует, а стандарты только зарождаются. Это никогда не длится долго. Количество предварительных знаний и опыта, которые вам необходимо иметь, прежде чем вы сможете войти в отрасль, стремительно увеличивается. Растут ставки, масштабы и цена ошибок. Появляются сертификации, тренинги, стандарты, юридические процедуры. Мы спорим о том, являются ли инженеры-программисты на самом деле инженерами.

ПО - индустрия обучения
Сейчас никто не возьмёт недоучившегося студента в штат. Необходимые для входа в индустрию знания выросли, вы больше не можете научиться буквально всему на работе, как когда-то.

Но не похоже, что вы можете научиться всему и в вузе. Степень в области компьютерных наук обычно лучше готовит вас к жизни компьютерных исследователей, чем к жизни в качестве обычного инженера-программиста. Более практичным путём в индустрию может стать хороший учебный лагерь по кодированию с упором на решение проблем и изучение современного инструментария. В любом случае вы не столько узнаете, «как выполнять работу», сколько «узнаете достаточно основ, чтобы понимать и использовать инструменты, необходимые для изучения работы».

ПО — индустрия обучения. Вы не можете научиться быть инженером-программистом, читая книги. Вы можете учиться только делая… и делая, и ещё делая. Неважно, какое у вас образование, большая часть обучения происходит на работе… и никогда не заканчивается!

Требуется более 7 лет, чтобы выковать компетентного инженера-программиста (как в большинстве случаев называют, сеньора). Это много лет написания, проверки и развёртывания кода каждый день в команде вместе с более опытными инженерами.

Что значит быть «сеньором»?
Об этом есть целая серия постов на канале. Ищите по тэгу #КакСтатьСеньором

По поводу сроков есть очень много споров:
«7 лет?! Пфф, мне потребовалось 2 года!»
«Меня повысили до сеньора меньше, чем за 5 лет!»

Молодцы! Да, в 7 годах нет ничего волшебного. Но для того, чтобы стать опытным инженером, способным сплотить команду, требуются время и опыт. Более того, нужна практика.

Думаю, мы стали использовать слово «сеньор» как сокращение для инженеров, которые могут поставлять готовый чистый код и быть продуктивными, и кажется, что это огромная ошибка. Это подразумевает, что младшие инженеры менее продуктивны, что неверно. И это упускает из виду истинную природу работы по разработке ПО, в которой написание кода является лишь небольшой частью.

Быть сеньором — это не способность писать код. Это гораздо больше связано с вашей способностью понимать, поддерживать, объяснять и управлять большим объёмом ПО в производстве с течением времени, а также способностью переводить бизнес-потребности в техническую реализацию. Большая часть работы связана с созданием и курированием этих больших, сложных социотехнических систем, а код — это всего лишь одно из представлений этих систем. Это значит, что вы научились, прежде всего, учиться и учить; как держать эти модели в голове и рассуждать о них, и как поддерживать, расширять и эксплуатировать эти системы с течением времени. Это значит, что у вас есть здравый смысл и инстинкты, которым вы можете доверять.

Что подводит нас к вопросу об ИИ.

Продолжение следует…

Источник:
https://stackoverflow.blog/2024/12/31/generative-ai-is-not-going-to-build-your-engineering-team-for-you
5👍20👎1