Я программист-самоучка, на всякий случай, если на этот вопрос ответят в CS 101. Я выучил и использовал много языков, в основном для личного пользования, но иногда и для профессиональных вещей.
Кажется, что я всегда сталкиваюсь с одной и той же стеной, когда сталкиваюсь с проблемами программирования. Например, я только что задал вопрос на другом форуме о том, как обрабатывать указатель на массив, который был возвращен функцией. Сначала я думаю, что просто не знаю правильную технику, которую разработчики C ++ создали, чтобы справиться с ситуацией. Но из ответов и обсуждений, которые следуют, я вижу, что я действительно не понимаю, что происходит, когда что-то «возвращается».
Насколько глубокий уровень понимания процесса программирования должен достичь хороший программист?
Ответы:
Нет. Никто не понимает, что происходит на аппаратном уровне.
Компьютерные системы похожи на лук - есть много слоев, и каждый из них зависит от слоя под ним для поддержки. Если вы парень, работающий над одним из внешних слоев, вам не нужно слишком беспокоиться о том, что происходит в середине лука. И это хорошо, потому что середина лука постоянно меняется. Пока слой или слои, которые поддерживают ваш конкретный слой, продолжают выглядеть одинаково и поддерживают ваш слой, у вас все хорошо.
Но опять же...
Да. Я имею в виду, вам не нужно понимать, что на самом деле происходит внутри лука, но это очень помогает иметь мысленную модель того, как выглядит внутренняя часть типичного лука. Может быть, не самая глубокая часть, где у вас есть вентили, состоящие из транзисторов и тому подобного, или следующий слой или два, где у вас есть микрокод, часы, единицы декодирования команд и т. Д. Однако следующие слои, где вы У меня есть регистры, стек и куча. Это самые глубокие уровни, на которые вы оказываете большое влияние на происходящее: компилятор переводит ваш код в инструкции, которые выполняются на этом уровне, и, если вы хотите, вы обычно можете выполнить эти инструкции и выяснить, что «на самом деле» происходит.
Большинство опытных программистов имеют слегка сказочную версию этих слоев в своей голове. Они помогают вам понять, о чем говорит компилятор, когда он сообщает, что произошла «ошибка недопустимого адреса» или «ошибка переполнения стека» или что-то в этом роде.
Если вам интересно, почитайте книгу по компьютерной архитектуре. Это даже не должно быть особенно новой книгой - цифровые компьютеры долгое время работали примерно одинаково. Чем больше вы узнаете о внутренней части лука, тем больше вы будете поражены тем, что все это работает! Изучение (приблизительно) того, что происходит на нижних уровнях, делает программирование менее загадочным и, так или иначе, более волшебным. И действительно, веселее.
Еще одна вещь, на которую вы можете обратить внимание, это встроенный лук. Я имею в виду встроенные системы. Есть ряд встроенных платформ, которые довольно просты в использовании: Arduino и BASIC Stamp - два примера. Это в основном небольшие микропроцессоры с множеством встроенных функций. Вы можете думать о них как о луке с меньшим количеством слоев, чем у вашего обычного настольного ПК, так что можно получить довольно полное представление о том, что происходит во всей системе, от аппаратного обеспечения до программного обеспечения.
источник
Вы не говорите об аппаратном уровне, вы говорите о том, что действительно делает компилятор с тем, что вы говорите ему делать.
Вам, безусловно, нужен этот уровень понимания, чтобы понять, что пошло не так, когда это неочевидно, особенно когда речь идет о ситуации с памятью.
источник
Понимание памяти программ! = Понимание оборудования
Понимание иерархии памяти == Понимание оборудования
Чтобы ответить на ваш общий вопрос: это зависит. Это не помешает понять аппаратное обеспечение, но понимание этого не поможет во всех случаях.
Исходя из вашего примера, вам просто нужно больше узнать о том, как распределяется память и как она организована при запуске программы. Понимание аппаратного обеспечения не поможет вам в этом отношении, потому что память (видимая для программы) даже не представляет аппаратно, благодаря магии виртуальной памяти.
Если вам любопытно узнать о проблемах производительности, связанных с порядком, в котором вы обращаетесь к памяти, СЕЙЧАС вы выиграете от понимания аппаратного обеспечения, иерархии памяти, ошибок кэширования, сбоев страниц и всего великолепного качества, которое исходит от оборудования.
источник
Если вы действительно решили узнать немного ассемблера, вероятно , вы должны узнать что - то вроде 6502 ассемблера на Commodore 64 (эмулировать, конечно), или 68000 на Amiga.
Вы можете получить представление о Commodore 64 здесь ...
http://thepiratebay.org/torrent/4609238/Tag3-Saal2-Slot16_00--ID2874-the_ultimate_commodore_64_talk-Main
Классическая книга «все, что нужно знать» описана здесь ...
http://reprog.wordpress.com/2010/03/12/programming-books-part-3-programming-the-commodore-64/
Вы можете, вероятно, найти сканирование PDF, если вы посмотрите вокруг.
IMO, 6502 легче, чем Z80, и 68000 легче, чем 8086 - более регулярные наборы команд и т. Д.
Но процессор - это только один аспект аппаратного обеспечения. Кроме того, современный ЦП - это совершенно другой зверь, и он делает вещи прозрачными даже с точки зрения компиляторов, такие как представление виртуального адресного пространства.
Особое преимущество 6502 на C64 заключается в том, что он не только прост с центральным процессором, но и с некоторыми очень простыми аппаратными средствами. Раньше мне было очень весело играть с музыкальным чипом SID.
Так что - это, вероятно, стоящее упражнение, если вы не тратите на него слишком много времени. Я изучил ассемблер 6502 как мой второй язык, когда мне было около 14 лет, сразу после Commodore Basic. Но в основном он получает очень простую рабочую модель, чтобы вы могли добавлять к ней более сложные идеи с минимумом недопонимания.
Некоторые полезные вещи, которые вы можете узнать, работая в ассемблере ...
Одна конкретная причина, по которой я бы порекомендовал это, состоит в том, чтобы лучше понять, как простые шаги действуют совершенно детерминистически, механически и совершенно без интеллекта или здравого смысла. По сути, привыкаешь к императивной модели исполнения в ее самой чистой и упрямо невежественной форме.
Но насколько именно сейчас полезно знать большинство этих вещей, это сложный вопрос.
Одна вещь, которую вы не научитесь, - это как хорошо играть с иерархией памяти. Те старые машины в основном имели простую модель памяти без слоев кеша и виртуальной памяти. Вы также мало что узнаете о параллелизме - они, безусловно, были способами справиться с этим, но это в основном означало прерывания. Вам не нужно беспокоиться о мьютексах и т. Д.
Иногда умственная модель того, как эти вещи когда-то работали или как работает ассемблер, может даже ввести в заблуждение. Например, восприятие указателя C как адреса может привести к неопределенным проблемам поведения. Указатель AC обычно реализуется как целое число, содержащее адрес, но нет никакой гарантии, что это строго верно. Например, на некоторых причудливых платформах разные указатели могут указывать на разные адресные пространства. Это становится важным, когда вы хотите сделать арифметическую или побитовую логику с двумя указателями.
Если у вас нет одной из этих причудливых платформ, вы можете не думать, что вас это беспокоит, но в наши дни компиляторы все чаще используют неопределяемое стандартами поведение для оптимизации.
Таким образом, ментальная модель архитектуры системы может быть полезной, но все же важно кодировать спецификацию языка, а не гипотетическую модель, которую ваш язык и платформа могут не уважать.
Наконец, множество полезных умственных моделей приходит из понимания того, как компиляторы генерируют код - и генерация кода для современных языков сильно отличается от довольно тривиальных компиляторов, доступных в то время.
Это моя любимая книга для этого ...
http://dickgrune.com/Books/MCD_1st_Edition/
Наряду с материалами о синтаксическом анализе, AST и т. Д. Он охватывает генерацию кода для ряда языковых парадигм - императивных, ООП, функциональных, логических, параллельных и распределенных - а также для управления памятью. Если вы хотите знать, как работают полиморфные вызовы методов, не увязая в деталях набора команд процессора, то такая книга - ваш друг - и скоро выйдет новая редакция.
источник
Двадцать лет назад это было важно, но не так много сейчас - между программным обеспечением и современным оборудованием гораздо больше уровней абстракции.
Полезно знать такие вещи, как необходимость использования нескольких потоков для использования преимуществ нескольких ядер или то, что использование большего количества памяти, чем существует в системе, является плохой вещью, но помимо этого вам это не нужно, если только ваша работа не состоит в том, чтобы писать эти абстракции. слои.
Остальная часть вашего вопроса предполагает, что вы, возможно, больше озабочены компилятором, чем аппаратным обеспечением, которое немного отличается. Вы можете столкнуться со случаями, когда это важно, но они, как правило, либо тривиальны (бесконечная рекурсия не очень хорошо работает), либо такие крайние случаи, когда вы можете чувствовать себя хорошо, решая ее, но, вероятно, никогда не столкнетесь с той же проблемой опять таки.
источник
Это очень помогает узнать и понять абстракцию, представленную оборудованием, и немного общей идеи о том, как создается эта иллюзия, - но попытка действительно понять, как на самом деле работает современное оборудование, - это огромный объем работы, из которого вы ' Скорее всего, увидеть только минимальный доход.
Если вы простите небольшую утечку: это напоминает мне кое-что, что я заметил несколько лет назад. Десятилетия назад (вплоть до конца 1970-х годов или около того) большинство людей думали, что компьютеры на шаг не дотягивают до волшебства - на них почти не влияют законы физики, они способны на всевозможные вещи, которые не имеют реального смысла, и так далее. В то время я потратил немало времени, пытаясь (в основном безуспешно) убедить людей, что нет, они не были волшебниками. Это были действительно довольно обычные машины, которые делали ограниченное количество вещей очень быстро и надежно, но в остальном были чрезвычайно обыденными.
В настоящее время взгляды большинства людей на компьютеры изменились. Теперь они довольно обычные - до такой степени, что довольно немногие очень обычные люди имеют практическое понимание их. Просто, например, некоторое время назад, когда я ужинал, я видел / слышал, как официант и официантка в перерыве обсуждают, что она должна получить в своем новом компьютере. Совет, который он давал, был вполне разумным и реалистичным.
Мой взгляд на компьютеры тоже изменился. Я посещал Hot Chips, а до этого Форум по микропроцессорам восходит к середине 1990-х или около того. Я, вероятно, знаю больше о микропроцессорном оборудовании, чем, по крайней мере, 99% программистов - и, зная, что я делаю, я скажу следующее: они больше не обычные. Они же почти нарушают законы физики. Я провел много низкоуровневых тестов, и я могу сказать это наверняка: преодолеть иллюзию, создаваемую процессором, и перейти к уровню демонстрации того, как на самом деле работает оборудование, зачастую невероятно сложно. Я хотел бы опубликовать фотографию одной из наших установок с компьютером, скрытым под кабелями не менее чем из 4 логических анализаторов, просто чтобы правильно измерить один аспект того, как работает кэширование на современном процессоре (не говоря уже о некоторых по-настоящему привередливых программах, чтобы гарантировать, что то, что мы измерили, было именно тем, что делал процессор, и ничего больше).
источник
Разные языки работают на разных уровнях абстракции от аппаратного обеспечения. C и C ++ очень низкого уровня. Языки сценариев, с другой стороны, требуют, чтобы вы знали меньше об основных деталях.
Тем не менее, я бы сказал, что во всех случаях, чем больше вы знаете, тем лучше для программиста. Частью программирования является возможность одновременного манипулирования несколькими уровнями абстракции.
Если вы программируете на C ++, вам нужно хорошо понимать, как работает современный процессор, по крайней мере, на уровне абстракции, на которой работает компилятор. (Внутри процессора происходят вещи, которые также прозрачны для компилятора).
источник
Я хотел бы добавить пункт об общем дизайне языков высокого уровня, таких как C.
В целом, я думаю, можно с уверенностью сказать, что такие языки могут рассматриваться как реализующие абстрактную машину, и именно так сам Деннис Ричи описал, как работает C и как конкретная конструкция абстрактной машины C сделала его более переносимым языком. Таким образом, имея некоторое представление об архитектуре компьютера и функционировании на уровне машины, он может быть чрезвычайно полезен для понимания абстрактной машины языка.
Документ DMR Переносимость программ на C и системы UNIX - первое, что я помню, чтобы обсудить (абстрактную) модель машины для C.
Я думаю, что статья DMR об истории и развитии C также чрезвычайно полезна для демонстрации того, как реальное аппаратное обеспечение влияет на дизайн языка, и, возможно, также является примером раннего проектирования языка программирования: Разработка языка C
источник