Нормально ли для программиста время от времени не иметь 100% ясности в отношении своего кода? [закрыто]


19

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

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

При написании сложного кода программисты не понимают, что они делают половину времени?


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

3
Чтобы добавить к другим (проницательным) ответам в том смысле, что они пахнут слишком сложным или плохо разработанным кодом (не волнуйтесь, большинству из нас пришлось пройти этот этап): Документ . Как путем присвоения собственных имен переменным / методам / классам / модулям, так и путем добавления правильного описания к каждой функции, и путем (когда вы не видите другого выхода) написания простого встроенного комментария, объясняющего, почему и как вы используете какой-то сложный фрагмент код.
SJuan76

4
У меня никогда не было 100% ясности по поводу моего собственного кода.
CodesInChaos

2
Этот массив 5D действительно звучит так, как будто он может использовать некоторую абстракцию.

3
У любого разработчика всегда есть 100% ясность по его коду?
Йохан

Ответы:


30

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

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

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

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


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


8
[1] С более пессимистической точки зрения это нормально, но не хорошо.
Дан

1
Если «пятимерный массив» представляет собой просто карту из 4-х или 5-ти кортежей в стратегию, автор мог бы использовать хеш-таблицу или вспомогательную функцию поиска. Однако, если автор тратит большую часть времени на кодирование механики инициализации массива (вложенных циклов for), то фактическое «понимание алгоритма» будет утоплено в куче «механического кода». Программисты стремятся сохранить последний вид шума отдельным. Таким образом, хорошие программисты должны знать, как писать библиотеки в первую очередь для размещения этого механического кода.
Rwong

1-D массив - это линия, 2-й - это сетка, 3-й - это куб, 4-й - это линия кубов, 5-й - это сетка из кубов и т. Д., Но я не вижу смысла для такой сложной структуры данных, когда речь идет о шахматах.
user2785724

15

Существует два вида этого: 1.) заблуждение 2.) блаженное невежество

Первый плохой и может исчезнуть со временем и опытом.

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

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

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


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

12

Я бы сказал, что это чаще, чем люди хотят признать. Даже Брайан Керниган намекал на это:

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

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

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

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


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

@JamesSnell Он не сказал, что отладка плохая или неприятная, просто она сложная, а отладка сложного кода еще сложнее.
cbojar

5

Я думаю, что это то, что уйдет с опытом.

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

У вас будет много моментов, когда вы смотрите на какой-то код, который вы написали 6 месяцев назад, и думаете: «Что, черт возьми, здесь происходит?», Но если это произойдет через день после того, как вы написали код, вы должны думать «чисто». Кодекс больше.

Источник: никогда не использовал 5-мерный массив :)


3
@ 83457 - потому что 5d массив - плохая модель 2d проблемы. Если вы действительно думаете, что это хороший код, отправьте его на codereview.stackexchange.com и посмотрите, какие ответы вы получите.
Джеймс Снелл

2
@ 83457 - Если это чертовски запутанно, вы ответили сами. Вполне возможно, что 5-D массив не сбивает с толку, но, вероятно, не для большинства из нас, независимо от уровня наших навыков.
dbasnett

2
@ 83457 быть смущенным до чертиков уже должно быть очень хорошей мотивацией, чтобы не использовать это.
Фабио Марколини

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

2
@CodesInChaos За исключением того, что это не просто массивы, они представляют значимые последовательности (например, вложенные деревья решений). Называя их соответствующим образом и давая им типы, чтобы они не могли быть использованы (даже если эти типы являются более тонкими обертками над массивами), вы делаете код более понятным и с меньшей вероятностью содержать ошибки, практически без каких-либо затрат.
deworde

5

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

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

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

Связанный:

  • Когда Понимание означает Переписывание - статья о проблеме понимания кода.
  • Эффективный ML - долгий разговор о ML / OCaml о том, как написать код для «читателей» (т. Е. Сопровождающих): «Пользуйся читателями по сравнению с писателями». Я рекомендую смотреть независимо от того, какой язык вы используете.

2

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

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

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

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

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


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

@ rwong Спасибо. В основном это опыт - я пишу программы 46 лет и не собираюсь уходить в ближайшее время.
tcrosley

2

Здесь много достойных ответов.

У меня есть несколько вариантов этого.

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

Мое другое мнение заключается в том, что реальный ключ заключается в использовании шаблонов здравого смысла и соглашений в вашем коде. Это гораздо большая тема, чем может затронуть один небольшой пост. Но поищите хорошую литературу по этому вопросу, включая некоторые старые резервные копии, такие как книги «Code Complete» и «Writing Solid Code».

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

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

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


1

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

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

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

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