Программирование

We use cookies. Read the Privacy and Cookie Policy

Основной принцип работы компьютера не многим отличается от принципа действия карманного калькулятора. Допустим, мы задаем калькулятору задачу: сложить числа 3 и 5. Мы должны для этого нажать на клавиши «3», «+» и «5», а затем на знак равенства «=». Калькулятор таким образом «узнает», что от него требуется результат сложения чисел «3» и «5». Имея же дело с компьютером, мы даем ему следующие команды: «Возьми одно число (в нашем случае это число «3»). Возьми второе число («5»). Сложи их друг с другом. Покажи полученный результат.»

Всю процедуру можно разделить на два этапа: первым будет выбор задаваемых чисел (например, чисел «3» и «5»), вторым — непосредственно вычисление. Выбранные нами слагаемые можно представить в виде шаров с написанными на них числами; предположим, что каждый такой шар находится в отдельной ячейке. В этом случае процесс вычисления может выглядеть следующим образом: «Возьми число «3» из первой ячейки и прибавь к нему число «5» из второй ячейки. Помести результат в следующую, третью, ячейку». При более сложных вычислениях алгоритм может стать более сложным; скажем, число из третьей ячейки необходимо будет умножить на число из четвертой и т. д. Основная задача, таким образом, каждый раз остается очень простой, однако при этом достигается большая амплитуда вариаций, поскольку мы можем и изменять числа в каждой из ячеек, и продолжать сам алгоритм. Можно, допустим, дать компьютеру команду «сохрани полученный результат снова в первой ячейке» и построить таким образом так называемый цикл, который обеспечит непрерывное повторение заданного вычислительного процесса. Например, так можно вычислить значение произведения 2?2?2?2?...

У программиста, работающего с «большими» компьютерами, используемыми в научных расчетах, те же две задачи: с одной стороны, он программирует отдельные операции — шаги, которые должен выполнить компьютер (сложение, вычитание, умножение и деление, к примеру), а с другой стороны, программист обеспечивает машину новыми данными, которые она обрабатывает в соответствии с заданной последовательностью вычислительных операций.

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

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

Однако этим возможности компьютеров не исчерпываются, с чем, собственно, и связаны и наши надежды, и наши трудности. Подобно тому, как мы представляли себе шары с числами, помещенные в отдельные ячейки и готовые к дальнейшей компьютерной обработке, можно представить ячейки и с такими шарами, на которых содержатся записи о тех или иных вычислительных операциях, своего рода сигналы к действию. Компьютер в этом случае получает команду, смысл которой приблизительно таков: «Возьми следующий шар и сделай то, что написано на этом шаре.» (Естественно, в действительности нет никаких шаров, которые компьютер мог бы «брать», как при игре в лото. Скорее, можно говорить о существовании особого запоминающего устройства, где компьютер хранит данные и откуда получает электрические сигналы, означающие для него команду «выполнить то или иное действие».) «Шар» может содержать, например, указание перемножить два заданных числа; но может также и представлять собой команду для запуска какой-то посторонней сложной программы. В результате объединения в одно целое столь разнообразных предписаний компьютерные процессы могут становиться очень и очень сложными. Эта сложность, кстати, приводит к возникновению особой «разновидности» программистов, называемой на компьютерном жаргоне английским словом «hacker»[27]. Хакер — это программист, который из чистого интереса к творчеству без конца придумывает все новые и новые программы, перестает в конце концов ориентироваться в собственных наработках, сидит перед компьютером ночь напролет с разбухшей головой, пытаясь разобраться, что и где пошло не так. При этом незадачливый хакер забирается все глубже и глубже, и к утру оказывается вынужден признать, что в его компьютере царит теперь полнейшая неразбериха. Приведенный пример, без сомнения, наглядно свидетельствует о том, насколько коварной штукой может быть программирование.

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