Разработка ПО - это наука о деталях, и это самая глубокая, самая ужасная фундаментальная проблема ПО. До тех пор пока мы не научимся понимать и организовывать ПО так, что нам не придется думать о том, каким образом каждая мельчайшая деталь взаимодействует со всеми другими мельчайшими деталями, ничего коренным образом не изменится в лучшую сторону. И нам еще очень далеко до подобных открытий.
Сейбел:То есть нужно лишь преодолеть технические проблемы или просто все дело в сущности самого процесса?
Дойч:Нужно все начать заново. Для начала нужно забыть обо всех языках, в которых существует понятие указателя, потому что в реальном мире нет такого понятия. Нужно смириться с фактом, что информация занимает пространство, существует какое-то время и размещена в определенном месте.
Сейбел:По мере того как вы переходили от работы над небольшими фрагментами кода к созданию крупных систем, вы писали эти маленькие фрагменты с помощью прежних методов и просто приобрели новый взгляд на более крупные системы или это повлияло на ваш подход ко всей работе в целом?
Дойч:Это изменило мой подход к работе в целом. Первыми значительными программами, которые я создал, стали программы на UNIVAC в Гарварде. Следующие несколько программ я сделал на PDP-1 в MIT. В то время - 1960-е, когда я учился в старших классах, - мною были созданы три действительно разные программы, или системы.
Для серийного PDP-1 я написал интерпретатор Лиспа. Я написал какой-то кусок кода операционной системы для причудливо модифицированного PDP-1 Джека Денниса. Кроме того, я написал текстовый редактор для PDP-1 Денниса.
Эти три системы я сделал в целом монолитными. Отличие от моих предыдущих программ на UNIVAC заключалось в том, что здесь мне уже пришлось начать разрабатывать структуры данных. Это было первое серьезное изменение относительно типа программирования, которым я тогда занимался.
Я начал осознавать существование того явления, которое я назову функциональным сегментированием, но тогда я не придавал ему особого значения. Я знал, что можно писать определенные части программы и не заботиться в этот момент о других частях программы, но проблемы с интерфейсами, которые приобретают гигантское значение по мере того, как программа увеличивается в объеме, насколько я помню, не представлялись мне тогда важными.
Переход случился во время работы над моим следующим крупным проектом - во время учебы на старших курсах в Беркли в рамках проекта Genie - над системой разделения времени 940 и над текстовым редактором QED. Еще я написал программу отладки для ассемблера, но почти ничего о ней не помню.
Наиболее системной частью того проекта была операционная система. Я бы погрешил против истины, если бы сказал, что написал всю операционную систему целиком, но это не так. Но я по большому счету написал все ядро на ассемблере. Сейчас речь уже идет о немного более крупных программах - возможно, порядка 10 000 на ассемблере. Там были планировщик процессов, виртуальная память, файловая система. На самом деле там было несколько файловых систем.
И здесь уже передо мной возникли более сложные проблемы в связи с организацией структур данных. Например, из того, что я помню, там была таблица активных процессов. И передо мной встал вопрос: как ее организовать и каким образом операционная система должна решать, когда процесс работоспособен, и прочее. Были и структуры для отслеживания системы виртуальной памяти. Но стали появляться и некоторые проблемы, связанные с интерфейсом. Не в рамках самой операционной системы, нет, поскольку она была настолько мала, что ядро было создано как единый кусок, монолит.
Но были две важные области, в которых стали появляться проблемы программного интерфейса. Одна из них - интерфейс между пользовательскими программами и ядром. Какими должны быть системные вызовы? Как должны быть размещены параметры? Я знаю, что в первых версиях системы 940 основные операции для чтения и записи файлов были эквиваленты вызовам read и write в UNIX, когда вы просто даете базовый адрес и смещение. Это все было очень хорошо, но большую часть времени это было не тем, что нужно. А нужен был попросту потоковый интерфейс. Но в те дни мы и понятия не имели, что можно взять функции операционной системы и затем обернуть их кодом пользовательского уровня, чтобы получился интерфейс получше - вроде того, когда getc и putc надстраиваются над read и write. To есть в более поздних версиях операционной системы мы просто добавили системные вызовы, эквивалентные getc и putc.
Читать дальше
Конец ознакомительного отрывка
Купить книгу