Архив

Как разрабатывают ПО для шатлов

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

В то время, когда 120-ти тонный шаттл стоит, окруженный почти 4-мя миллионами фунтов ракетного топлива, источая ядовитые пары, с явным желанием бросить вызов земной гравитации; его бортовые компьютеры получают команду. Четыре идентичных компьютера, работающие под управлением идентичного ПО, собирают информацию из тысяч датчиков, принимая сотни миллисекундных решений, утверждая каждое решение, сверяясь друг с другом 250 раз в секунду. Пятый компьютер, с другим ПО, готов взять управление на себя в случае сбоя остальных четырех.

В момент времени -6.6 секунды, если давления, насосы и температуры в норме, компьютеры дают приказ зажечь главные двигатели шаттла – каждый из трех двигателей вспыхивает ровно через 160 миллисекунд, тонны сверхохлажденного жидкого топлива попадают в камеры сгорания, корабль дрожит на своей пусковой площадке, удерживаемый на земле только креплениями. Когда главные двигатели достигают силы тяги в миллион фунтов, их выхлопы превращаются в голубые бриллианты пламени.

Тогда и только тогда, в момент времени -0 секунд, если компьютеры убедились, что двигатели работают правильно, они дают приказ поджечь массивные ракетные ускорители. Менее чем за секунду, они развивают силу тяги в 6.6 миллионов фунтов. И именно в этот момент, компьютер отдает приказ взрывчатым креплениям взорваться, и корабль весом 4.5 миллионов фунтов величественно поднимается над стартовой площадкой.

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

Правильная вещь – это программное обеспечение. Программное обеспечение отдает приказы подключить основные двигатели, для того, чтобы вскоре после того, как шаттл освободит башню, произошло поразительное вращение фюзеляжа. ПО приглушает двигатели, чтобы корабль не разгонялся слишком быстро. Оно отслеживает, где находится шаттл, приказывает ракетным ускорителям отделиться, производит небольшие корректировки курса и, спустя примерно 10 минут, направляет шаттл на орбиту на высоте более 100 миль. Когда ПО удовлетворено положением шаттла в космосе, оно приказывает главным двигателям отключиться – наступает невесомость и все начинает парить.

Но поразителен не объем работ, который выполняет программное обеспечение. Что действительно поражает, так это то, как хорошо это ПО работает. Это ПО никогда не падает. Оно никогда не требует перезагрузки. Оно не содержит ошибок. Оно совершенно, настолько совершенно, насколько человек смог этого достичь. Посмотрите на статистику: последние три версии этой программы – каждая по 420.000 строк кода – имели всего по одной ошибке в каждой. Последние 11 версии этого ПО имели в сумме 17 ошибок. Коммерческие программы, подобного уровня сложности имели бы 5.000 ошибок.

Это программное обеспечение – результат работы 260 женщин и мужчин, расположенных в безымянном офисном здании, находящемся напротив Джонсовского космического центра в городе Клир-Лэйк, штат Техас, на юго-восток от Хьюстона. Они работают в "бортовой группе шаттла", филиале подразделения космических систем корпорации Lockheed Martin, и их отвага всемирно известна: группа разработки ПО для шаттлов – одна из всего четырех организаций в мире, которая достигла 5 уровня по правительственной шкале Института Разработки Программного обеспечения (Software Engineering Institute – SEI) – меры сложности и надежности тех методов, при помощи которых они делают свое дело.

Группа пишет такое хорошее ПО, потому что оно должно быть таким. Каждый раз, когда оно поджигает шаттл, от их ПО зависит оборудование, стоимостью 4 миллиарда долларов, жизни полудюжины астронавтов и мечты нации. Даже малейшая ошибка в космосе может иметь чудовищные последствия – на орбите космический челнок движется со скоростью 17.500 миль в час; ошибка при определении временного интервала всего на две трети секунды отклонит шаттл от курса на три мили.

НАСА знает, насколько хорошим должно быть ПО. Перед каждым полетом, Тед Келлер, старший технический менеджер бортовой группы шаттла, летит во Флориду, где он подписывает документ, удостоверяющий, что ПО не подвергнет космический корабль опасности. Если Келлер не в состоянии этого сделать, то формальная линия преемственности предписывает, кто может подписать этот документ вместо него.

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

Программное обеспечение – это все.

В истории человечества, еще не было ничего, что было бы настолько важным, как программное обеспечение.

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

"Это подобно дошумерской цивилизации," – говорит Брэд Кокс, который написал ПО для компьютера Стива Джобса NeXT и профессор университета имени Джорджа Меэйсона. "Тот способ, которым мы создаем ПО – это эра охотников и собирателей".

Джон Мансон, программист и профессор информатики университета Айдахо еще более категоричен. "Пещерное искусство" – он говорит. "Это примитив. Считается, что мы обучаем компьютер науке. Но здесь нет науки вообще."

Программное обеспечение может быть двигателем для постиндустриального мира, но его создание остается доиндустриальным ремеслом. Согласно исследования SEI, около 70% программистских организаций застряли на первых двух уровнях по шкале SEI: хаос и нечто лучшее, чем хаос. Ситуация настолько тяжелая, что некоторые пионеры программирования ушли из компаний, подобных Микрософт, чтобы преподавать искусство создания ПО.

Марк Полк, старший член технического совета SEI говорит, что успех ПО делает его недостатки еще более драматичными. "Мы разработали продукт, который является невероятно сложным и невероятно мощным. Мы очень сильно от него зависим," – говорит Полк. "К тому же все жалуются на то, насколько оно плохое, со всеми его дефектами. Если бы вы купили автомобиль с 5.000 дефектов, вы бы были расстроены."

В этом болоте программного обеспечения, бортовая группа шаттла держится особняком. Десять лет назад эта группа была как все. С тех пор, она снизила количество своих ошибок на 90%.

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

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

Программное обеспечение для взрослых

"Этот кошмар со скорейшим выпуском новых версий продолжается и сегодня. Давай, давай, давай! Нам никогда этого не сделать. Я говорил уже об этом? Почему мы всегда преуменьшаем наши планы по выпуску новых версий? Я просто не понимаю. Приходим на работу к 9.30, уходим в 23.30. В обед – пицца из "Домино". И три диетические Колы."

Нет, это не бортовая группа шаттла. Это сценарий Дугласа Копланда, в точности описывающий жизнь передовой софтверной компании. И это доминирующий образ индустрии разработки программного обеспечения: поколение исполнителей в спортивных майках с обезумевшими взглядами, выжимающее слишком много геройского кода, за слишком малое время; роликовые коньки и горные велосипеды, сложенные по углам; коробки из-под пиццы и чашки, оставленные в комнате для совещаний. Это мир, ставший известным, романтическим, даже неизбежным благодаря историям из Sun Microsystems, Microsoft и Netscape.

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

Они работают с 8 до 5 – работа допоздна случается, но это, скорее, исключение. Программисты работают напряженно, но сдержано. Многие из них отдали годы работе либо в IBM (куда входила группа шаттла до 1994 года), либо непосредственно в разработке программного обеспечения для шаттлов. Они взрослые люди, у них есть супруги, дети и личная жизнь помимо их поразительных программ.

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

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

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

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

Другой момент – это порядок, детали и методические повторения. Данное совещание, классическое мероприятие в НАСА – это репетиция практически идентичного совещания, которое произойдет через несколько недель. Оно состоит из прогона невероятных объемов данных и изображений – графы, которые описывают прогресс и состояние программного обеспечения по каждой строке. За исключением Келлеровских лирических отступлений, тон, в целом, деловой, почти формальный, изображения – диаграммы мелькают настолько быстро, насколько они могут восприниматься, смесь из аббревиатур, диаграмм и графиков.

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

Точно также культура не терпит творчества, индивидуальной показухи и признаков классической индустрии ПО. "Люди спрашивают, разве такой процесс не душит творчество? Вы должны делать все в точности так, как говорит руководство, и у вас есть некто, кто заглядывает вам через плечо" – говорит Келлер. "Ответом будет – да, этот процесс действительно душит творчество".

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

Сладкие песни обычного мира, где производится ПО, могут не устоять перед строгой критикой, которую практикует группа. Куин Ларсон, 34 года, проработал над ПО для шаттлов семь лет, прежде чем покинул группу и перешел работать в Micron Technology в Бойсе, штат Айдахо, автоматизирующую производство чипов памяти.

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

"Я сам должен был определять что и как делать", – говорит Ларсон. "Здесь не было совещаний, здесь не велось записей". У него была полная свобода действий, и это было настоящим ударом. C точки зрения Ларсона, культура не была нацелена на получение качественного продукта. "Скорость там была превыше всего", говорит он. "Инженеры говорили, что вот, мол, это наши основные приоритеты, и нам необходимо достичь их как можно быстрее." Но у Ларсона сложилось впечатление, что их, похоже, не особо беспокоило то, насколько хорошо работает программное обеспечение, которое они выпускают. "По существу, они хотели получить быстрое ПО – чтобы поскорее вытолкнуть его за дверь."

В середине августа Ларсон вернулся в группу шаттла. "Здесь работают люди высочайшей пробы", – сказал он в свой первый рабочий день после возвращения в Клир-Лэйк

Процесс

Каким образом они пишут правильную вещь?

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

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

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

1. Продукт хорош настолько, насколько хорош план для него.

В бортовой группе шаттла, около трети процесса по написанию ПО происходит до того, как кто-либо напишет хоть одну строку кода. НАСА и группа из Локхид Мартин достигают соглашения в самых подробных описаниях, касательно всего, что новый код должен будет делать – и затем они фиксируют достигнутые договоренности на бумаге с такой скрупулезностью и точностью, которую обычно можно наблюдать при ксерокопировании. Ничто в спецификациях не может быть изменено без согласия и полного понимания с обеих сторон. И никто не изменит ни одной сроки кода без спецификации, подробно описывающей это изменение. Возьмем, к примеру, обновление ПО, позволяющее управлять шаттлом при помощи спутников Системы Глобального Позиционирования (GPS). Это изменение затрагивало всего 1.5 процента от всей программы или 6.366 строк кода. Спецификации для него занимали 2.500 страниц, том, толще, чем телефонный справочник. Спецификации для всего программного обеспечения в его текущем состоянии занимают 30 томов или около 40.000 страниц.

"Наши требования – это практически псевдокод", говорит Уильям Претт, который руководит этим проектом в НАСА. "Они говорят – вы должны делать именно это, именно таким образом, в данных условиях и при данных обстоятельствах".

Такой тщательный процесс проектирования уже сам по себе достаточен для того, чтобы обеспечить классную организацию труда, говорит Джон Мансон из Университета Айдахо. Большинство организаций берутся даже за большие проекты без детального планирования того, что их ПО должно делать. И, как правило, после того, как программисты уже начали писать программу, заказчик настоятельно требует изменить архитектуру. Результатом является хаос, высокая стоимость разработки, где код постоянно изменяется и содержит ошибки, даже при проектировании.

"Большинство людей решают потратить свои деньги тогда, когда процесс, казалось бы, подходит к концу", говорит Мансон. "В современной индустрии программного обеспечения 80% затрат на разработку приходится на период, который наступает после выпуска первой версии, – но люди поначалу не понимают этого, и тратят время на выяснение отношений." В группе шаттла, все делается правильно с первого раза. И никто не изменяет программное обеспечение без изменения плана. Вот почему их ПО настолько совершено.

2. Лучшая работа в команде – это здоровая конкуренция.

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

Центральная группа разделяется на две ключевые команды: разработчики – люди, которые сидят и пишут код, и проверяющие – люди, которые пытаются найти дефекты в коде. Обе команды отчитываются разным начальникам и имеют прямо противоположные задачи. Группа разработки обязана выпустить абсолютно безошибочный код, настолько безупречный, чтобы тестеры не нашли дефектов вовсе. Группа тестирования обязана истязать этот код при помощи сценариев полета и симуляций, чтобы обнаружить как можно больше дефектов. Результатом является то, что Том Петерсон называет "отношениями дружеского соперничества".

"Они конкурируют между собой на предмет того, кто обнаружит ошибки", говорит Келлер. "Иногда они грызутся, как кошки с собаками. Разработчики хотят отловить все свои ошибки. Тестеры выходят из себя: "Эй, забейте! Вы отнимаете наше время для тестирования программы."

Разработчики даже начали проводить свои собственные ревизии кода на заседаниях, скрупулезный анализ, который, как они надеются, расстроит тестеров. Проверяющие, в свою очередь, утверждают, что они заслужили такой авторитет, что некоторые ошибки обнаруживаются еще до того, как они начинают тестирование. "С точки зрения группы тестирования", – говорит Пэт Маклилллан, старший менеджер, – "мы осознаем, что если бы не было независимой группы тестирования, разработчики были бы более расслабленными. Одно только существование нашей группы заставляет их быть более внимательными."

В результате такой дружеской конкуренции группа шаттла сейчас обнаруживает 85% ошибок до начала формального тестирования, и 99.9% до того, как программа отправляется в НАСА.

3. База данных – это фундамент программного обеспечения.

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

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

Другая база данных – это база данных ошибок, является своего рода памятником тому пути, которым прошла бортовая группа шаттла в своей работе. Здесь содержатся все ошибки, которые были когда-либо допущены при написании или при работе с ПО, на протяжении почти 20 лет. Для каждой ошибки в базе данных хранятся записи о том, когда эта ошибка была обнаружена; какой набор команд привел к ней; кто обнаружил ошибку; на какой стадии ошибка была обнаружена – при тестировании, при тренировке или в полете. Здесь отслеживается как ошибка проявилась в программе; как ошибке удалось просочиться сквозь фильтры на каждой стадии поиска ошибок – почему она не была обнаружена при проектировании? при ревизиях кода? при тестировании? В конечном итоге база данных содержит информацию о том, как ошибка была исправлена и не могли ли подобные ошибки просочиться сквозь эти дыры.

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

"Мы никогда не пускаем ничего на самотек", – говорит Претти Торнтон, старший менеджер. – "Мы делаем прямо противоположное: мы допускаем, чтобы все нас беспокоило."

4. Мало исправить ошибку – в первую очередь, необходимо исправить все, что позволило этой ошибке случиться.

Процесс является настолько всеобъемлющим, что он оказывается в ответе за каждую ошибку – если есть дефект в программе, значит что-то не в порядке с процессом написания кода, что-то что должно быть исправлено. Любая ошибка, не обнаруженная на стадии планирования, проникла, по крайней мере, сквозь несколько проверок. Почему так случилось? Что-то не в порядке с ревизиями кода? Или в контрольный список следует добавить новый пункт?

Важно заметить, что группа избегает обвинять людей в ошибках. Все обвинения берет на себя процесс – и именно процесс подвергается анализу, чтобы определить как и почему произошла ошибка. В то же время, ответственность является принципом команды: ни один человек не отвечает единолично за написание или ревизию кода. "Вас не будут наказывать за то, что вы допускаете ошибки", – говорит Маджори Сейтер, старший сотрудник технического персонала. "Если я делаю ошибку, а другие проверяют мою работу, значит я не одинок. Меня не будут обвинять в этом."

Тед Келлер приводит пример отдачи от такого подхода, касающийся шаттловского дистанционного манипулятора-руки. "Мы передали наше ПО для обучения команды шаттла", – говорит Келлер, – "что позволило астронавтам управлять этой "рукой" и перемещать грузы. Когда "рука" оказывалась в определенной точке, она просто переставала двигаться."

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

"Даже несмотря на то, что это было некритично", – говорит Келлер, – "мы проанализировали, какие еще строки кода могли содержать точно такой же тип дефекта." Они обнаружили восемь подобных ситуаций, где в семи из них округление не порождало проблем. "Одна из таких ситуаций была связана с подпрограммой, управляющей мощной антенной", – говорит Келлер. "Это была главная антенна корабля. Если бы эта ошибка проявилась, в критический момент могла бы прерваться связь с землей. А это уже намного серьезнее."

Процесс работает таким образом, что он обнаруживает ошибки не только в ПО. Он обнаруживает ошибки в самом себе.

Проблема только в программном обеспечении.

Бомбардировщик Б-2 не смог отправиться в свой первый полет – из-за ошибки в ПО. Новый аэропорт Денвера открылся на несколько месяцев позже и превысил бюджет на несколько миллионов долларов из-за проблемы в системе управления багажом – но проблема была исключительно в ПО. Новая ракета Европейского Космического Агентства Ариан 5 взорвалась при первом запуске из-за маленькой ошибки в ПО. Крупные федеральные правительственные агентства, начиная от Налоговой Службы и заканчивая Национальной Службой Погоды, увязли в проектах, просроченных на годы и превысивших бюджет на сотни миллионов долларов, зачастую из-за небольших проблем с программным обеспечением. Программное обеспечение становится все более и более повсеместным, и, следовательно, все более и более важным, но похоже, оно не становится все более и более надежным.

В то время когда остальной мир еще осваивает основы, бортовая группа шаттла постепенно продвигается к совершенному программному обеспечению. Естественно, у них есть масса преимуществ перед остальным миром разработки программного обеспечения. Они разрабатывают всего лишь один продукт: одну программу, которая управляет одним космическим кораблем. Они знают свою программу досконально на протяжении всего времени работы над ней. У группы только один заказчик, причем, весьма разумный. К тому же, деньги здесь не являются ограничивающим фактором: бюджет группы размером в 35 миллионов долларов является незначительным кусочком НАСА’вского пирога, но в пересчете на количество строк кода это делает группу одной из наиболее дорогостоящих организаций по разработке ПО в США.

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

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

Автор: Charles Fishman (fish@nando.net). Оригинал находится здесь: http://www.fastcompany.com/online/06/writestuff.html

Перевод: http://kholeg.wordpress.com/2006/11/20/%D0%BE%D0%BD%D0%B8-%D0%BF%D0%B8%D1%88%D1%83%D1%82-%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D1%8C%D0%BD%D1%83%D1%8E-%D0%B2%D0%B5%D1%89%D1%8C/


Другие статьи в блоге:

⟵ PHP Перевернуть строку без буфера
Dive into Python :) ⟶