Статьи

Некоторые из моих наиболее часто используемых мантр развития (1/2)

Утверждение: я предполагаю, что это работает так!

Мантра: предположение — мать всех придурков

us2 Давайте начнем с этого короткого фрагмента из Under Siege2: http://www.youtube.com/watch?v=wg4trPZFUwc

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

1
i = i++;

Обычно мы пишем что-то как ‘i ++’, оставляя назначение. Тем не менее, назначение кажется избыточным в большинстве. Мы предполагаем, что у него нет других побочных эффектов, и запускаем нашу программу. Но вдруг … БУМ! Сбой связи, Кейси Рэйбэк пинают его задницу (на самом деле, я бы хотел увидеть это), запустить ядерное оружие, и мир во всем мире далек. Наше предположение оказало довольно негативное влияние.

Хорошо, давайте посмотрим, о чем идет речь, и проведем небольшой тест. Что вы ожидаете, что это печатает, у вас есть какие-либо идеи, почему это так?

1
2
3
int i = 0;
i = i++;
System.out.println("i:"+ i);

Пока вы думаете об этом, позвольте мне объяснить, что происходит. Как видно, у нас есть выражение, существующее из унарного оператора и присваивания. Как обсуждалось ранее, назначение является избыточным. Но помимо того, что он избыточен, он также вызывает неприятный побочный эффект. Это заставляет этот код вести себя иначе, чем можно было бы ожидать. Если мы отбросим присваивание (просто оставив ‘i ++;’), код будет точно делать то, что вы думаете, он будет делать.

Случается, что при использовании присваивания JVM помещает значение операндов в так называемый стек операндов, прежде чем что-то с ними делать. Когда выражение вычисляется, значение для присвоения левой переменной извлекается из стека операндов. Этот хитрый унарный оператор следует другим правилам. Он использует инструкцию ‘iinc’. Инструкция iinc принимает в качестве параметра позицию в массиве локальных переменных текущего фрейма, чтобы поместить его значение.

Итак, получается, что «0» помещается в стек локальных операндов. Затем переменная «i» увеличивается на 1 из-за инструкции iinc. В это время локальная переменная «i» фактически будет иметь значение «1». Мы не можем показать это обычным способом, так как присваивание / выражение оценивается за один шаг. Когда присваивание выполнено, оно извлечет последнее значение из стека операндов, присваивая его переменной ‘i’. Это означает, что «i» будет перезаписано значением из стека операндов, и его значение будет изменено с 1 на 0.

Примечание: когда вы пишете ‘i = ++ i;’ думает, что будет работать, как ожидалось, и назначение просто избыточно без побочных эффектов. В этом случае инструкция iinc выполняется перед отправкой значения локальной переменной в стек операндов. Рациональное на самом деле ничем не отличается от приращения переменной в вызове метода; someMethod (++ i) или someMethod (i ++). Однако, с присваиванием кажется менее ясным, что pre или post унарный имеет какое-либо значение, потому что мы склонны связывать его с i ++ или ++ i в одной строке, где абсолютно не имеет значения, является ли ++ pre или post.

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

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

Заявление: не волнуйтесь, это только временно!

Мантра: временного кода не существует

westvleteren Согласитесь, многое в жизни временное. Запас Westvleteren 12 в моем холодильнике — это только один пример. Но в программных проектах «временный» имеет тенденцию начинать жизнь самостоятельно, нанося плохо спроектированный или написанный код на своем пути.

Это имеет смысл, если вы думаете об этом; Я не думаю, что кто-то работает с таким же количеством энергии или самоотдачей, если что-то считается временным. Проблема, однако, в том, что временный код станет постоянным еще до того, как вы его поймете.

Примером, которым я могу поделиться по этой теме, является система управления пользователями, которую мы разработали для предыдущего проекта. Система собиралась стать «временной» системой управления пользователями, потому что «постоянная» система была по какой-то причине задержана. Я не буду вдаваться в подробности, но название программного обеспечения должно было отражать, что оно было временным. Так оно и было названо TUM (Система управления временными пользователями). И вы уже догадались; в конце концов система существовала долгие годы и со временем стала единственной UAM. Через некоторое время даже стало трудно убедить новых коллег, что буква «Т» на самом деле означает «временный».

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

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

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

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