Саботировать стандарты кодирования [закрыто]


35

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

Два примечательных примера - это MISRA C и стандарт C ++, разработанный для проекта JSF .

Они обычно имеют следующую форму, после тщательного определения того, что означают слова «должен», «должен», «должен», «может» и т. Д.

Пример:

Правило 50: Переменные с плавающей запятой не должны проверяться на точное равенство или неравенство.

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

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

Теперь давайте злоупотребим этим!

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

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

счет

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

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

Правила и положения

  • Правило или правила должны выглядеть профессионально, как в приведенном выше примере
  • Правила должны выглядеть подлинно (поэтому такие вещи, как «все переменные должны содержать хотя бы одно подчеркивание, одну заглавную букву, одну строчную букву и две цифры» , не принимаются. Они действительно будут мешать разработчикам, но, скорее всего, не будут приняты комитет), и если их заслуга не сразу очевидна, вы должны дать хорошее обоснование.
  • Вы должны быть в состоянии найти способ использовать / злоупотреблять вашими правилами, чтобы саботировать разработчиков позже. Вы можете злоупотреблять любой двусмысленностью в других правилах, или вы можете использовать несколько правил, которые сами по себе безвредны, но однажды объединены!
  • Вы должны опубликовать объяснение в тегах спойлера в конце вашего сообщения о том, как вы можете злоупотреблять правилами
  • Используемый язык не должен быть эзотерическим. Язык, широко используемый в реальных проектах, должен быть выбран, поэтому предпочтение отдается языкам с синтаксисом, подобным С (вместо таких вещей, как Golfscript).

4
Python, Ruby, Haskell, Makefile, XML и т. Д. - это некоторые языки, используемые во многих реальных проектах, которые не имеют C-подобного синтаксиса.
kennytm

7
Этот вопрос кажется не по теме, потому что это не соревнование по программированию.
Питер Тейлор

5
@PeterTaylor: определение включает в себя «Пазлы программирования», что не означает, что ответ должен быть частью программного кода. Нигде в определении сайта не написано, что речь идет только о «соревнованиях по программированию». Определение
таково

7
@PeterTaylor для меня это похоже на соревнование по программированию; в заданиях «полицейские и грабители» грабители тоже не пишут код (и если ваш аргумент заключается в том, что грабители комментируют, то обязательно прокомментируйте мета-пост, который предлагает разделить вызовы полицейских и грабителей на два отдельных вопроса)
Джон Дворжак

5
Я проголосовал за открытие. Кажется, у нас все еще есть некоторые вопросы, по которым мы не можем договориться о том, относятся ли они к теме. Это напоминает мне об этом искусстве, которое было закрыто, а затем вновь открыто. У меня есть идея для ответа на этот вопрос, и это определенно связано с программированием. Этот вопрос даже соответствует 2 тегам на сайте.
hmatt1

Ответы:


40

C / C ++

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

Обоснование: восьмеричные константы могут быть причиной путаницы. Например, случайный взгляд на строку const int coefficients[] = {132, 521, 013, 102};
может пропустить тот факт, что одно из чисел в массиве определено в восьмеричном виде.

Если вы хотите быть еще более злым, добавьте следующее:

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

Обоснование: если константа представляет числовое значение, она более читаема, если она в десятичном виде. Шестнадцатеричная константа должна указывать, что она представляет битовую маску, а не числовое значение.

Как этим можно злоупотреблять:

Возьмите следующую простую программу, которая добавит первые 10 элементов массива. Этот код не будет соответствовать стандартам.

sum = 0;
for (i = 0; i < 10; i++) 
{
    sum += array[i];
}

Обратите внимание, что 0, по определению, восьмеричная константа. В соответствии с правилом 1 требование его записи в виде 0x00 по всему коду разочаровывает. По правилу 2, еще больше расстраивает.


1
Не могли бы вы дать ссылку на стандартное определение кодирования, которое гласит, что 0это восьмеричная константа? Я предполагаю, что это потому, что все начинается с характера 0. Это усилит аргумент вашего гипотетического педанта.
xnor


16

питон

Правило 1: Весь код должен быть скомпилирован с использованием -OOфлага, который оптимизирует байт-код. Мы хотим оптимизировать байт-код для размера и эффективности!

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

Использование -OOудаляет assertутверждения. В сочетании с правилом 2 это фактически запрещает использование assertоператоров в тестах. Повеселись!


Это также удаляет строки документации, что означает, что вы ничего не получите от help()REPL, а неформальное REPL-тестирование все еще тестирует.
Кевин

Нет. Если вы напишите надлежащую тестовую среду, она будет использовать unittestмодуль or, который реализует свои собственные утверждения, не зависящие от __debug__флага. Однако Doctests молча не побежит. Подлый!
pppery

15

Это для проекта Node.JS.

Раздел 3 - Скорость и эффективность важны

Правило 3.1: файлы должны храниться не более 1 КБ. Файлы большего размера, чем это занимает слишком много времени для анализа.

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

Правило 3.3. Избегайте require()обходных путей.

Правило 3.3.1. Любые модули require()d не require()должны иметь глубину более 3-х. Глубокие require()цепочки дороги как с точки зрения использования памяти, так и с точки зрения скорости.

Правило 3.3.2. Основные модули считаются едиными require(), независимо от того, сколько раз они были require()внутренними.

Правило 3.3.3. Количество внешних модулей не должно превышать 2 require()с. Мы не можем позволить себе такую ​​же снисходительность, как с основными модулями, но можем предположить, что авторы модулей пишут эффективный код.

Правило 3.4. Избегайте синхронных вызовов любой ценой. Это часто занимает много времени и блокирует весь цикл событий от продолжения.

Как этим можно злоупотреблять:

Правила 3.1 и 3.3 плохо работают вместе. Удерживая максимум 1 КБ и 3 require()с вниз по цепочке, им будет трудно добиться успеха.
Правила 3.2 и 3.4 практически несовместимы. 3.4 запреты синхронных звонков; 3.2 затрудняет продвинутую асинхронную работу, ограничивая количество обратных вызовов.
Правило 3.4, честно говоря, является правилом, которому хорошо следовать по-настоящему. 3.1, 3.2 и 3.3 являются полностью поддельными.


11

JavaScript (ECMAScript)

7.3.2: литералы регулярных выражений

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

RegularExpression     :: '/' RegularExpressionBody '/'
RegularExpressionBody :: [empty]
                         RegularExpressionBody [any-but-'/']

[empty] соответствует пустой строке, а [any-but - '/'] соответствует любой односимвольной строке, кроме той, которая содержит '/' (косая черта, U+002F).

обоснование

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

Тем не менее, Организация ™ признает, что регулярные выражения иногда являются лучшим инструментом для работы. Поэтому сам RegExpобъект не запрещен.

(Синтаксис самого фрагмента грамматики [не тот, который он определяет] соответствует синтаксису спецификации ECMAScript. Конечно, это будет определено более строго в другом пункте гипотетической спецификации.)

Трюк

Следующая программа не соответствует:

// sgn(x) is -1 if x < 0, +1 if x > 0, and 0 if x = 0.
function sgn(x) {
  return x > 0?  +1
       : x < 0?  -1
       :          0
}

Представленные выше нетерминальные выражения RegularExpressionBody показывают общий способ выражения списков в BNF, полагаясь на явную рекурсию. Хитрость в том, что я «случайно» разрешаю пустую строку как RegularExpressionBody , так что строка //запрещена в исходном коде. Но кому все равно нужны однострочные комментарии? C89 и CSS, кажется, делают все правильно, позволяя только /* */блокировать комментарии.


15
На самом деле это даже более злобно: код может не содержать ни блочных комментариев, ни более одного оператора деления на файл.
Chromatix

Ах да, ты прав. Я даже не думал об этом. : P
FireFly

5

C #

12.1. Статические методы, влияющие на состояние программы, запрещены.

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

12.2 Статические методы должны быть детерминированными

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

Зачем

Точкой входа для программы на C # является закрытый статический метод main. По первому правилу это теперь запрещено, потому что правило забывает заявить, что только публичные, защищенные или внутренние методы должны следовать этому правилу. Если тестирование действительно является проблемой, только общедоступные методы должны следовать правилу 1. Main может также нарушать правило 2, поскольку программа выдаст код ошибки, если программа завершится неудачно, это может произойти независимо от входных параметров. Например, программа может не найти файл или может зависеть от других систем, которые настроены неправильно.


4

JAVA / SPRING

4.2 Использование отражения в производственном коде

Поскольку Reflection можно использовать для доступа к другим частям нашего исходного кода, использование отражений в Production Code строго запрещено.

Трюк

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


3

Кодировка сайта

666.13 UTF-8 не должен использоваться и должен быть заменен на UTF-7.
Обоснование: UTF-7 более эффективен, чем UTF-8, особенно в отношении пользователей из арабских стран, что мы и делаем.

Как этим можно злоупотреблять:

HTML5 специально запрещает UTF-7. Это означает, что современные браузеры не будут поддерживать его. Если все тестирование выполняется в браузере, таком как IE 11, никто не заметит этого, пока не станет слишком поздно.


2

Битовые операторы JavaScript

1.9 Вы не должны использовать умножение или деление или настил, если они не значительно быстрее, чем их побитовые аналоги. Они должны быть заменены побитовыми операторами <<, >> и ~~ соответственно.
Обоснование: побитовые операторы более эффективны.

Как этим можно злоупотреблять:

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


2
Я думаю, что уже очевидно, что x = (x<<10) + (x<<8) + (x<<5) + (x<<4) + (x<<3) + (x)он уступает во всех отношениях (возможно, даже по скорости) x *= 1337, и что замена деления не степенью двойки суммами битовых сдвигов еще хуже.
lirtosiast

@ Томас Ква Я отредактировал свой ответ соответствующим образом. Спасибо за указание на это. Я новичок в побитовых операторах.
Стефнотч

1

JavaScript (ECMAScript)

7.3.1: Соглашения об идентификаторах

Ограничения налагаются на идентификаторы в зависимости от типа идентификатора. Идентификаторы делятся на типы Variable , Constant , Function и Constructor ; см. 5.3. Ограничения приведены ниже.

  • Переменная: первый символ должен быть строчной буквой. Случай верблюда (см. 1.3) должен использоваться для разделения слов в идентификаторе.

  • Константа: Идентификатор должен состоять только из букв верхнего регистра символов и символов подчеркивания ( «_», U+005F). Символы подчеркивания должны использоваться для разделения слов в идентификаторе.

  • Функция: функции должны следовать тем же правилам, что и тип идентификатора .

  • Конструктор: первый символ должен быть заглавной буквой. Случай верблюда (см. 1.3) должен использоваться для разделения слов в идентификаторе.

обоснование

Читаемые имена идентификаторов очень важны для удобства обслуживания. Ограничение идентификаторов известными соглашениями также облегчает переход между различными базами кода. Эти конкретные соглашения смоделированы после стандартных соглашений для языка программирования Java ™ [1] .

Трюк

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


2
»Функции должны следовать тем же правилам, что и тип идентификатора .« - Вы имеете в виду »как тип переменной «?
Пажло Эберманн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.