Archive

Archive for the ‘Инструментарий’ Category

Конференция «Будущее Flash-платформы»

May 12th, 2010 No comments

Adobe FlashВчера был на конференции “Будущее Flash-платформы” в МГУ. Эта первое мероприятие такого рода, которое мне посчастливилось посетить.

Программа:

  • Презентация Flex 4/Flash Catalyst, Tom Krcha
  • Flex 4 Gumbo, Валерий Песецкий и Сергей Язловецкий
  • 3D во Flash, Антон Волков
  • Технологии развития и будущее Flash-платформы, Артемий Малков

Предлагаю вашему вниманию подробный отчет.

Презентация Flex 4/Flash Catalyst

Tom Krcha

Том – классный парень в красных штанах, много улыбается и отлично говорит по-английски. Работает в Adobe евангелистом.

Евангелист – человек, который ездит по миру и рассказывает о технологиях, языках и т.п.

Том показывал презентации, кодил в режиме реального времени, делал, в общем, всяческие интересные штуки. Показывал новые возможности IDE (умную табуляцию, например) и отладчика (conditional breakpoints). Много рассказывал про Flash Catalyst, показывал, как можно сделать дизайн в Иллюстраторе, а затем «перетащить» его во Флэш. Часто можно было услышать «without any line of code», и это, кажется, действительно так. Похоже, что можно сделать типовое приложение, работающее с БД, одной мышкой. Мне не нравится подход «without any line of code» и «программирование мышкой», но это сейчас модно. Действительно, почему бы не решать простые задачи по-простому?

Tom Krcha

Тому задавали много вопросов. В конце с вопросами выступил настоящий гуру Флеш-разработки (Александр Немцов), он спрашивал коварные вещи, на которые Тому было нечего ответить. Мне стало его даже немного жалко.

В целом выступление Тома прошло весело и бойко.

Flex 4 Gumbo

Валерий Песецкий, Сергей Язловецкий

Валерий и Сергей рассказывали про то, чем четвертый Flex отличается от третьего.

Основные моменты:

  • Новая концепция компонентов, «Spark»
  • Графика в MXML, то есть можно «рисовать» треугольники, кружочки и т.д. текстом в MXML описании
  • FXG (Flash Xml Graphic), формат графики, совместимый с Adobe Illustrator и другими программами
  • Состояния (States) стали круче
  • Двустороннее связывание данных
  • Дополнительные возможности CSS
  • Поддержка ASDoc (автоматическая генерация документации), для этого служат комментарии в MXML с тремя минусами
  • Новый механизм создания анимации (фильтры, в том числе Pixel Bender)
  • Компоновка стала динамической, теперь можно поворачивать элементы в контейнерах и размещать и на разных слоях
  • FTE (Flex Text Engine), текст теперь может располагаться в нескольких столбцах, быть вертикальным, справа налево и т.д.
  • Больше всего обрадовало то, что теперь графики входят в стандартную комплектацию Flex, то есть они бесплатны!

Ораторы подробно отвечали на все вопросы; при этом выяснилось, что теперь компонентам не рекомендуется иметь дочерние. То есть функция createChildren() теряет актуальность. Новая концепция предполагает, что за дочерние компоненты отвечает скин, который, кстати говоря, теперь полноценный UIComponent. В остальном архитектура Flex вроде бы не изменилась.

Стоит отметить то, что новые компоненты Spark нормально уживаются со старыми, так как находятся в разных пространствах имен. Так что явных проблем при переносе проекта с третьего Flex на четвертый быть не должно.

Приложения Adobe Flash для графических планшетов Wacom

Ольга Никулина

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

Качайте SDK, берите планшет и начинайте писать для него мини-приложения на платформе Flash. Победитель получит 1000 фунтов и приглашение на ацкую флеш вечерину.
http://mini-developer.wacom.com

3D во Flash

Антон Волков

«Антон прекрасно поет и танцует», – анонсировал оратора Артемий Малков. Сюда по тому, что я увидел в течение следующего часа, прекрасно петь и танцевать – сущая ерунда для Антона. Он представлял проект «3D Alternativa». Это сложнейший движок трехмерной графики для Flash.

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

Затем мне посчастливилось быть свидетелем премьеры «TANKI ONLINE». Скажу честно, я и не предполагал, что Flash на такое способен. Выглядит очень круто!
http://tankionline.com

Несмотря на следующие проблемы платформы:

  • Нет Z-буфера
  • Pixel Bender бесполезен
  • Байт-код не всегда эффективен
  • Нет многопоточности
  • Нет аппаратного ускорения

Для их решения Антону и его команде пришлось «подковать блоху», придумывая хитрые методы оптимизации (запомнился предварительный расчет видимости, который на приличной машине выполняется четверо суток).

В завершение Антон сказал обнадеживающие слова о будущем Flash, и закончил выступление видеороликом «3D + мультитач – девчонкам нравится».

Технологии развития и будущее Flash-платформы

Артемий Малков

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

Боюсь изложить неточно идеи оратора, но я выделил следующие важные вещи:

  • На ближайшие 5 лет Flash будет оставаться доминирующей технологией насыщенного веба
  • Десктоп-приложения уходят в прошлое
  • Стоит присматриваться к мобильным устройствам
  • Учить английский
  • Интегрироваться в профессиональные сообщества

Спасибо всем участникам и организаторам за конференцию и подаренные значок, наклейки и футболку!

P.S. А еще сайту flash-ripper, благодаря которому я попал на эту конференцию.

Злой плагин для jQuery

April 1st, 2010 No comments

SUMMARY

A jQuery plugin for crashing IE6. That’ll teach those motherf!%@*#s to upgrade their s#*t.

http://plugins.jquery.com/project/crash

О плагине я узнал сегодня на хабре. В документации подробно описывается, как им пользоваться.

USAGE

To crash IE6 call

$.crash();

В jQuery добавляется метод crash(), вызов которого валит IE6 вот так:

iecrash

Что же именно приводит IE6 к такому конфузу? Я скачал плагин и стал изучать его исходный код…

/**
 * jQuery Crash (http://mktgdept.com/jquery-crash)
 * A jQuery plugin to crash IE6.
 *
 * v0.0.2 - 5 March 2010
 *
 * Copyright (c) 2009 Chad Smith (http://twitter.com/chadsmith)
 * Dual licensed under the MIT and GPL licenses.
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.opensource.org/licenses/gpl-license.php
 *
 * Use $.crash();
 *
 **/
;jQuery.crash=function(x){for(x in document.open);};

То есть вот этот код IE6 выполнить не может:

for(x in document.open);

Для тех кто не очень хорошо знаком с JavaScript, цикл for-in – это обход всех свойств объекта. Вообще document.open – это функция, которая открывает новое окно по указанному URL (MSDN). Но JavaScript позволяет использовать функции и как объекты в том числе. То есть на функции можно вешать разные свойства и это будет корректно с точки зрения языка.

Например, такой код покажет окошко с текстом «document.open.kuku = Ku-ku!» в Гугл Хроме. IE6 тоже покажет окошко, но другое (то, что в начале статьи).

document.open.kuku = "Ku-ku!";
 
for(x in document.open)
{
	alert('document.open.' + x + ' = ' + document.open[x]);
}

(*) вызов document.open.kuku эквивалентен вызову document.open['kuku'] в JavaScript

chrome_not_crash

У меня нет IE6, так что не могу проверить, распространяется ли эта особенность на такие функции, как document.getElementById() и вообще любые функции. Если у кого-то есть старый добрый злой ослик, проверьте и напишите. Мне весьма любопытно)

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

Mac OS X, часть 2.2. Графическая подсистема Quartz. Продолжение.

March 28th, 2010 No comments

Для тех, кто из-за большого перерыва между статьями уже забыл, напомню — в прошлый раз мы начали знакомство с Quartz — графической подсистемой Mac OS X. Я рассказал о том, как в целом устроен Quartz, из каких частей состоит, и за что каждая из этих частей в итоге отвечает, а также показал на примере Mac OS X 10.0 (Cheetah) как собственно был реализован Quartz, и с какими проблемами пришлось столкнуться разработчикам. С проблем-то и начнём.

Основная проблема с Quartz в первой версии Mac OS X заключалась в том, что работало всё довольно таки медленно (помните тест с полупрозрачной консолью и QuickTime-роликом?). Центральному процессору приходилось трудиться за себя и за того парня, выполняя команды рисования Quartz2D, записывая результаты их работы в backing store, а за тем — выполнять композитинг всех окон в финальную сцену. Разумеется, долго так продолжаться не могло, и вот как поступили разработчики Quartz в Mac OS X 10.2 (в версии 10.1 особых изменений в работе Quartz не было за исключением некоторых общих оптимизаций).

Quartz-Jaguar

Как видно из рисунка, теперь Quartz Compositor целиком выполняется на GPU видеокарты. Этого удалось добиться, переделав Compositor в OpenGL-приложение, для которого каждое окно представляло собой двухмерную поверхность, а содержимое backing store для этого окна —текстуру этой поверхности. Эту версию Quartz назвали Quartz Extreme, и она работала только на видеокартах, поддерживавших текстуры произвольного размера (так как окно, по сути, также может быть любого размера) и AGP 2x, для того, чтобы иметь возможность читать содержимое backing store напрямую из оперативной памяти.

Перенос Quartz Compositor на видеокарту сильно разгрузил центральный процессор. Выполнение операций по блендингу больших битмапов — с этим GPU справляется очень и очень хорошо (для этого его и придумали). Более того, центральный процессор перестал заниматься и переносом backing stores из оперативной в видеопамять, а это тогда значило очень много (когда частота системной шины не превышала 133 мегагерца). Возвращась к тесту с полупрозрачным окном терминала и видеороликом: на том же самом компьютере, но со включенным Quartz Extreme, fps видео вообще не менялся, вне зависимости от того, сколько полупрозрачных окон было размещено поверх него. Самые отчаянные экспериментаторы доходили до 25 окон, но fps ролика оставался невозмутимым — 24 кадра в секунду.

Mac OS X 10.3 (Panther) тоже не принесла никаких изменений в работе Quartz (как и 10.1), кроме общей оптимизации. Посмотрим теперь, что произошло в 10.4 под кодовым названием Tiger.

Quartz Extreme отлично справлялся с работой по композитингу backing stores в финальную сцену, однако загвоздка в том, что backing store не заполняется по мановению волшебной палочки — его содержимое сначала кто-то должен нарисовать. Представим, например, окно браузера с текстом, картинками, элементами управления и тому подобным. Если только окно не является полупрозрачным (или находится под другим полупрозрачным окном), трудоёмкость композитинга меркнет в сравнении с вычислительной сложностью задачи отрисовки содержимого окна в backing store. Рассмотрим в качестве примера текст. Каждый из этих символов должен быть растеризован из своего векторного описания в файле шрифта, к этому растру должно быть применено сглаживание, а затем он должен быть помещён на саму страницу с учётом фона (то есть, по сути — должен быть выполнен композитинг для этого конкретного символа внутри окна браузера). Всю эту работу приходится выполнять CPU, так как Quartz Compositor имеет дело с уже заполненными backing stores. Более того, содержимое окна перерисовывается каждый раз, когда, например, меняется его размер или выполняется прокрутка его содержимого. И в этом случае Quartz Extreme ничем не может нам помочь — он просто мучительно долго (в сравнении с CPU) ждёт, пока центральный процессор закончит рисовать в backing store, а затем очень быстро выполняет композитинг финальной сцены и ждёт следующей итерации.

Ещё одна проблема становится видна, если посмотреть на схему работы Quartz Extreme, обращая особое внимание на ширину полосы пропускания (напоминаю, что конкретные цифры приведены исключительно для относительного сравнения) и сопоставляя её с объёмами данных на каждом участке. Результаты вызовов API Quartz2D, по сути, представляют собой большие растровые изображения, которым нужна довольно таки широкая полоса. Сами вызовы Quartz2D довольно маленькие по объёму, и большой полосы пропускания им не надо. На рисунке же мы видим, что самое узкое место (между оперативной и видеопамятью) используется для передачи самых больших объёмов данных (заполненных backing stores).

Наконец, учитывая то, что backing stores обрабатываются на двух разных процессорах (CPU и GPU), с раздельной памятью (RAM и VRAM), можно догадаться, что эта схема работы обладает высокими накладными расходами на синхронизацию. Пока с backing store окна работает Quartz Compositor, приложение рисовать туда не может, и наоборот — Quartz Compositor не может начать выполнять композитинг до тех пор, пока приложение не закончило рисование.

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

Quartz-Tiger

Глядя на картинку можно заметить, как всё больше и больше задач в Quartz выполняется на видеокарте. Объясняется это очень просто — достаточно посмотреть на величины ширины полосы пропускания между GPU и видеопамятью. Причём, эта величина продолжает расти, и расти гораздо быстрее, чем полоса пропускания между центральным процессором и RAM.

Как мы видим, вызовы Quartz2D теперь выполняются на GPU, а центральному процессору остаётся только отправлять сравнительно небольшие по объёму команды рисования через драйвер на видеокарту. Естественно, не было бы смысла перемещать Quartz2D на видеокарту, а backing stores хранить по-прежнему в RAM, поэтому и они теперь перехали в видеопамять. Помимо того, что теперь отрисованные backing stores передаются по широким шинам между GPU и видеопамятью, разработчики Quartz ещё и существенно снизили задержки на синхронизацию, ибо теперь и Quartz2D, и Quartz Compositor выполняются на одном процессоре (GPU) и пишут/читают из одной и той же памяти (VRAM).

Казалось бы — победа. Однако, как это часто бывает в жизни, всё оказалось не так просто. Во-первых, центральный процессор не всегда передаёт только маленькие команды рисования для Quartz2D. Самый распространённый пример — растровые изображения. Представим ситуацию — изображение на диске, а backing store рисующего приложения — в видеопамяти. Как оно может туда попасть? Напрямую с диска видеокарта читать не умеет, поэтому эту операцию приходится выполнять всё тому же CPU, сначала загружая изображение в оперативную память, а потом передавая её по узкой шине между оперативной памятью и видеокартой. Таким образом, если CPU придётся часто передавать большие растровые изображения, это может уничтожить все преимущества в скорости, которые даёт использование Quartz2D Extreme. Решение оказалось довольно таки простым — такие растровые изображения, будучи переданными на видеокарту один раз, кэшируются в видеопамяти, и затем Quartz использует только локальную копию в VRAM.

Но тут перед нами встаёт другое проявление суровой реальности — видеопамять, к сожалению, конечна, и постоянно кэшировать в ней большие растры не представляется возможным. Что произойдёт, если объёма VRAM окажется недостаточно для хранения всех backing stores, закэшированных битмапов, отрендеренных шрифтов и так далее? Нетрудно заметить, что относительно недавно (в масштабах вечности, разумеется) такая же проблема вставала с другой памятью — оперативной. Решение нам всем хорошо знакомо — виртуализация. Таким же образом поступили и разработчики Quartz — те данные, которые не уместились в видеопамяти, сбрасываются на более медленный носитель — оперативную память. Разумеется, Quartz старается размещать в видеопамяти не любые данные по принципу FIFO, а именно те, которые используются чаще всего. А когда видеопамяти всё-таки оказывается недостаточно, то начинается печально известный «хронический пэйджинг», который знаком каждому, кто пытался запустить какую-нибудь современную ОС на компьютере с 256 мегабайтами оперативной памяти, разве что диск не шумит.

Учитывая всё вышесказанное, какой же выйгрыш даёт применение Quartz2D Extreme (и даёт ли вообще)? Посмотрим на результаты синтетических тестов в следующей таблице:

  Quartz2D
Тысяч операций в секунду
Quartz2D Extreme
Тысяч операций в секунду
Ускорение
Прямоугольник 100×100 40 185 4.6x
Прямоугольник 800×800 2 472 236x
Узор 8×8 42 177 4.2x
Картинка 128×128 32 392 12x
Строка из 12 символов 1,733 4,720 2.7x
Линии 1,700 14,900 9x

В принципе, все результаты являются предсказуемыми, а особенно выделяется тест на заполнение прямоугольника размером 800 на 800 пикселей. По сути, этот тест проверяет, как быстро Quartz сможет нарисовать 640 тысяч пикселей в backing store, пропустить его и другие backing stores через Quartz Compositor и вывести всё это на экран. В предыдущих реализациях Quartz, центральному процессору пришлось бы рисовать этот прямоугольник в backing store, который находится в оперативной памяти, а затем передавать его на видеокарту, чтобы Quartz Compositor мог выполнить композитинг и выполнить вывод на экран; теперь же центральному процессору достаточно передать только одну OpenGL-команду на рисование прямоугольника в Quartz2D Extreme, который отрисует прямоугольник прямо в видеопамять — как раз туда, где его уже ждёт Quartz Compositor. Стоит обратить внимание ещё на одну деталь. Строка из 12 символов рисуется «всего» в 2,7 раза быстрее с помощью Quartz2D Extreme, что показывает, насколько хорошо в Tiger оптимизирована софтверная реализация Quartz2D (без Extreme). Это становится ещё заметнее, если сравнить её с софтверной реализацией Quartz2D в предыдущей версии Mac OS, Panther. Обратимся к результатам теста на рисование линий:

Panther-Situation

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

Tiger-Situation

За 12 миллионами линий в секунду, которые успевает отрисовать Quartz2D Extreme, трудно разглядеть, что тот самый софтверный Quartz2D, который в предыдущей версии был медленнее QuickDraw почти в два раза, теперь стал быстрее его в пять раз. В итоге имеем неплохой прирост производительности в 10 раз.

Ну, а теперь самый животрепещущий вопрос — повысились ли удои? Виден ли этот бешеный рост производительности в реальных приложениях? Так вот — разница вовсе не так заметна, а некоторые приложения стали работать _медленнее_ при включенном Quartz2D Extreme. В чём же проблема? А проблема как раз в кэшировании битмапов в видеопамяти. Дело в том, что Quartz без посторонней помощи не может предсказать (хотя и старается), какие битмапы будут использоваться приложением в ближайшем будущем. Чтобы знать об этом, приложение должно сигнализировать Quartz, какие битмапы ещё будут вскоре использоваться, сохраняя ссылки на них (тут я поясню, что в CoreGraphics — API, которое позволяет получить доступ к функциям Quartz2D — да и во многих других API Mac OS реализован механизм счётчика ссылок). А это прямо противоречит установившейся практике, когда память из под использованных битмапов освобождалась сразу, а потом, при необходимости, изображение снова читалось с диска (тут ещё и хороший дисковый кэш помогал). Однако, с момента выхода Tiger, разработчики приложений для Mac OS X (особенно усиленно работающих с графикой) уже поправили эти моменты, и теперь всё работает, как по маслу.

Вот, пожалуй, и всё, что я хотел рассказать вам про Quartz — графическую подсистему Mac OS X. Самое интересное, что предложенная в Tiger реализация без каких-либо особых изменений продолжает работать и в последней версии Mac OS X — Snow Leopard, много раз в секунду что-то рисуя, копируя, кэшируя, выполняя композитинг и выводя всё это безобразие на экран.

В следующей серии статей мы поговорим об API и инструментах разработчика, которые предоставляет Mac OS X нам, программистам; ну а пока, как обычно, я приглашаю всех к обсуждению статьи в комментариях. Stay tuned!

Анализ трафика HTTP

February 9th, 2010 No comments

Продолжение серии статей об Интернет-ботах.

Часть 1, Часть 2, Часть 3

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

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

Средства анализа

Существуют различные средства анализа трафика. Можно, например, установить специальный сетевой драйвер-фильтр. Однако значительно проще воспользоваться плагином к браузеру. Мне нравится вот этот (для Firefox): Live HTTP Headers.

Итак, нужен плагин. Этот или другой, главное, чтобы он сканировал заголовки как запросов, так и ответов.

Запускаем его и вводим в браузере «www.ya.ru». Я вижу вот что:

http://ya.ru/
 
GET / HTTP/1.1
Host: ya.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
 
HTTP/1.x 200 OK
Server: nginx
Date: Mon, 25 Jan 2010 22:21:14 GMT
Content-Type: text/html; charset=utf-8
Last-Modified: Tue, 12 Jan 2010 15:29:03 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

Это стартовые строки и заголовки реального браузерного запроса и ответа ему. Здесь видно, что Firefox умеет принимать сжатый ответ, о чем сообщил серверу Яндекса. Тот это понял и прислал сообщение, упакованное методом gzip.

Отправка формы

Для примера, оставим комментарий на Свиттере.

К сожалению, большинство комментариев, посупающих на модерацию, именно такие :) Итак, подготавливаем форму, как на картинке, запускаем плагин мониторинга HTTP, нажимаем «Отправить».

Запрос:

POST /wp-comments-post.php HTTP/1.1
Host: svitter.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://svitter.ru/?p=378
Content-Type: application/x-www-form-urlencoded
Content-Length: 350
 
author=%D0%9E%D0%BA%D0%BD%D0%B0+%D0%9F%D0%92%D0%A5&email=x%40x.com&url=x.com&comment=%D0%9A%D1%83%D0%BF%D0%B8%D1%82%D1%8C+%D0%BE%D0%BA%D0%BD%D0%B0+%D0%9F%D0%92%D0%A5%2C+%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0+%D0%BF%D0%BE+%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5&submit.x=54&submit.y=12&submit=Submit+Comment&comment_post_ID=378&comment_parent=0

Браузер отправляет запрос методом POST, передвая введенную нами информацию в теле сообщения. Оно имеет такой вид:

param1=value1&param2=value2&param3=value3

Где param1, param2, param3 – имена параметров, а value1, value2, value3 – их значения. Таких пар имя-значение может быть сколь угодно много. Пробелы браузер заменил на «+», кирилицу и прочие специальные символы на их коды вида %XX или %XX%YY (если символ кодируется двумя байтами).

author=%D0%9E%D0%BA%D0%BD%D0%B0+%D0%9F%D0%92%D0%A5&email=x%40x.com&url=x.com&comment=%D0%9A%D1%83%D0%BF%D0%B8%D1%82%D1%8C+%D0%BE%D0%BA%D0%BD%D0%B0+%D0%9F%D0%92%D0%A5%2C+%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0+%D0%BF%D0%BE+%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5&submit.x=54&submit.y=12&submit=Submit+Comment&comment_post_ID=378&comment_parent=0

Следует читать как:

author=Окна ПВХ&
email=x@x.com&
url=x.com&
comment=Купить окна ПВХ, доставка по Москве&
submit.x=54&
submit.y=12&
submit=Submit+Comment&
comment_post_ID=378&
comment_parent=0

Вот так можно оставлять комментарии на Свиттере Telnet-клиентом. Просто добавьте воды введите нужные заголовки и тело запроса.

Ответ:

HTTP/1.x 302 Moved Temporarily
Via: 1.1 RGW
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Transfer-Encoding: chunked
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Date: Tue, 26 Jan 2010 16:05:10 GMT
Location: http://svitter.ru/?p=378&cpage=1#comment-349
Content-Type: text/html
Server: nginx/0.7.62
Keep-Alive: timeout=20
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
X-Powered-By: PHP/5.3.1
Set-Cookie: comment_author=%D0%9E%D0%BA%D0%BD%D0%B0+%D0%9F%D0%92%D0%A5; expires=Sat, 08-Jan-2011 21:25:10 GMT; path=/
Set-Cookie: comment_author_email=x%40x.com; expires=Sat, 08-Jan-2011 21:25:10 GMT; path=/
Set-Cookie: comment_author_url=http%3A%2F%2Fx.com; expires=Sat, 08-Jan-2011 21:25:10 GMT; path=/
Last-Modified: Tue, 26 Jan 2010 16:05:10 GMT

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

Обратите внимание на заголовки Set-Cookie. Таким образом сервер сообщает браузеру, что введенные автором коментария данные (имя, email и url) нужно сохранить в cookies. Благодаря этому, при отправке следующего комментария останется ввести лишь текст сообщения.

А что же делать, если для доступа к сайту необходима авторизация? Об этом я расскажу в следующей статье. (скоро)

Mac OS X, часть 2.1. Графическая подсистема Quartz.

February 5th, 2010 Comments off

«Я тоже когда в магазинах видел маки, тыкался мышкой и не мог понять нафига оно все. Крутиться, сверкает – да. А толку?»

Завсегдатай форума iu7-world.ru

Вероятно, первое, что бросается в глаза, когда «тыкаешься мышкой в мак», — это насыщенность операционной системы графикой, как статичной, так и динамической. Огромные (настоящий размер почти всех иконок в Mac OS — 512 на 512 пикселей) полноцветные иконки с прозрачностью, эффектное «утекание» окон в док или их «разлетание» в Exposé, «волны по воде» при добавлении нового виджета на Dashboard или вращающийся кубик при переключении пользователей — за всем этим явно что-то стоит. Не буду ничего скрывать, «что-то» — это Quartz, графическая подсистема Mac OS X, несущая на своих плечах всё это безобразие, а также всю работу с текстом, цветовыми профилями и ещё много чего. Об основных архитектурных решениях, лежащих в основе Quartz, я расскажу чуть позже, а пока, как всегда, немного истории.

Иконка местного Notepad/Wordpad — TextEdit

Иконка местного Notepad/Wordpad — TextEdit

3 поколения графических подсистем.
Всю историю развития графических подсистем современных (и не очень) операционных систем можно условно разделить на 3 поколения. В графической подсистеме первого поколения основным примитивом являлся пиксель (а ещё раньше — символ). Зная координаты пикселя, ему можно было назначить определённый цвет и, собственно, всё. Если у программиста появлялась необходимость нарисовать линию, то раскладывать её на пиксельную сетку должен был он сам (алгоритм Брезенхема, если вы понимаете, о чём я :-) ) После того, как он рисовал линию, информация о том, что это именно линия, по сути, терялась — графическая подсистема просто работала на другом уровне абстракций. В принципе, можно даже сказать, что графическая подсистема первого поколения — это её отсутствие, ибо никакого интерфейса, кроме прямого доступа к видеопамяти, она не предоставляла.

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

Основным примитивом графической подсистемы третьего поколения является вектор. Информация о всех других примитивах, которые выводятся на экран, сохраняется в графической подсистеме в виде векторного описания каждой фигуры. Обладая этой информацией, графическая подсистема легко может выполнять математические преобразования над примитивами, не теряя при этом точности. В случае графической подсистемы второго поколения приложению пришлось бы самому реализовывать весь этот функционал, который теперь оказался встроен в саму ОС. Одной из первых графических подсистем третьего поколения был Display Postscript, использовавшийся в (угадайте, где?) известной нам по предыдущему посту NeXTSTEP. Использование уже существующего языка описания векторных объектов, такого, как Postscript, выглядит закономерным. Немного забегая вперёд, скажу, что в Quartz в качестве языка описания примитивов используется самый обычный PDF.

Quartz как он есть
Как вы уже, возможно, догадались, Quartz относится к графическим подсистемам третьего поколения. Основными составными частями Quartz являются:

  • Quartz 2D — набор API для рисования, операции которого хорошо ложатся на операции, определённые в стандарте PDF
  • Quartz Compositor — движок, выполняющий так называемый композитинг (совмещение всех backing stores в единую картинку, которая и будет показана на экране)
  • Window Server — эта часть Quartz занимается всеми окнами, элементами управления, фокусом ввода и маршрутизацией сообщений от устройств ввода к приложениям.

Честно признаюсь, про Window Server я говорить не буду — особо интересного в нём ничего нет, кроме того, что он работает. А вот на Quartz 2D / Quartz Compositor стоит посмотреть попристальнее.

Сразу отмечу, что кроме Quartz 2D, в Mac OS X есть ещё 2 API, с помощью которых можно выводить изображение на экран: хорошо известный OpenGL (для трёхмерной графики) и чуть менее известный QuickTime (для видео). Так как Quartz Compositor работает только с растровыми изображениями, рано или поздно результат выполнения каждого вызова этих API должен быть сохранён в виде битмапа в памяти. Эти буфера называются backing stores, и они создаются для каждого окна в системе. Позже Quartz Compositor использует backing stores при композитинге финальной сцены, которая позже попадёт в буфер кадра видеокарты, а оттуда — на экран. С высоты птичьего полёта картина выглядит так:

Quartz-Conceptual

Теперь посмотрим, как эта схема реализовывалась по ходу развития Mac OS X.

Долгий путь к сияющим вершинам
Когда Mac OS X впервые увидела свет в 2001 году, реализация Quartz выглядела следующим образом:
Quartz-Cheetah

(Небольшие пояснения: стрелочки жёлтого цвета указывают на то, что в передаче данных задействуется CPU, а стрелочки красного цвета — на то, что CPU не задействуется (DMA). Абсолютные значения ширины полосы пропускания не имеют значения, важно именно их соотношение, а не конкретные цифры.)

Из рисунка видно, что в этой реализации CPU, мягко говоря, сильно загружен. Мало того, что Quartz 2D и Quartz Compositor выполняются на процессоре, CPU ещё участвует и практически в каждой операции по передаче данных. Единственное исключение — запись итоговой сцены в буфер кадра видеокарты, выполняемая без участия CPU, однако толку от этого мало, потому что большая часть времени всё равно тратится на растеризацию и композитинг.

В итоге первая версия Mac OS X казалась явно медленной. CPU приходилось работать изо всех сил, рисуя в backing store каждого приложения с помощью функций Quartz 2D и выполняя композитинг всех backing stores (с помощью Quartz Compositor) в итоговую сцену. Если учесть, что в те времена частота шины между процессором и памятью достигала 100 (!) мегагерц, ситуация выглядела ещё плачевнее. Хороший тест скорости композитинга заключался в том, чтобы потрясти мышкой полупрозрачное окно терминала поверх окна, в котором проигрывался QuickTime-ролик. В этом случае композитинг должен был выполняться каждый раз либо когда двигалось окно терминала, либо когда отображался новый кадр видео. Этого было достаточно, чтобы нагрузка на CPU возрастала настолько, что FPS (frames per second, кадров в секунду) ролика падал в два раза. Разместив поверх окна с видео 5 полупрозрачных окон, можно было добиться того, что загрузка процессора достигала 100%, а проигрывание ролика останавливалось полностью: 0 FPS.

Про то, как разработчики Quartz вышли из этого затруднительного положения, я расскажу в следующей статье, а пока приглашаю всех к обсуждению в комментариях к посту. Вопросы, замечания, предложения — на всё постараюсь ответить. Stay tuned!

Что важно знать о HTTP

January 28th, 2010 Comments off

Продолжение серии статей об Интернет-ботах.

Часть 1, Часть 2, Часть 3

HTTP (Hyper Text Transport Protocol) – это тот самый язык, на котором разговаривают браузеры с веб-серверами.

Самое важное о HTTP:

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

svideteli_osvidetelstvovanija

Перечисленные особенности делают HTTP очень простым и расширяемым. Например, когда возникла задача сохранять информацию на машине клиента, протокол переписывать не пришлось. Все что надо было сделать – добавть один новый заголовок запроса (Cookie) и один – ответа (Set-Cookie).

Ниже по тексту я буду предлагать вам делать разные вещи. Например, скачать Яндекс Telnet-клиентом. «Пощупав» HTTP своими руками, проще понять его принцип. Но можно и просто читать, специально для вас у меня припасены скриншоты :)

Минимальный HTTP запрос

Скачаем содержимое сайта www.ya.ru без браузера. Для этого подойдет Telnet-клиент, который наверняка есть в вашей ОС. Чтобы воспользоваться им в Windows, запустите интерпретатор командной строки (cmd.exe). Далее набирайте текст, как на картинке, и нажимайте Enter.

1

Появился пустой черный экран. Вводите:

GET / HTTP/1.1

Нажимайте Enter. Пусть вас не смущает, что ничего не отображается на экране. Продолжайте ввод:

Host: www.ya.ru

Нажимайте Enter дважды.

Это был HTTP-запрос. А вот и ответ:

2

Что же мы сделали:

  1. подключились к серверу ya.ru на 80-ый порт (стандартный для HTTP)
  2. отправили сообщение, состоящее из стартовой строки и одного заголовка
  3. получили ответ, состоящий из стартовой строки, семи заголовков и тела

В стартовой строке запроса необходимо указать HTTP метод, URI документа и версию HTTP. В заголовке Host – имя хоста. Это был минимальный запрос. Если что-нибудь убрать, сервер скажет «Bad request».

Ответ начинается со стартовой строки «HTTP/1.1 200 OK», что означает, что наш запрос обработан успешно. Нам присылают желанный документ, содержимое которого находится в теле HTTP ответа. Именно его мы увидим, если нажмем в браузере кнопку «Исходный код страницы». Из заголовков хотел бы обратить ваше внимание только на Content-Length – здесь указан размер тела сообщения в байтах.

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

Методы HTTP

Стартовая строка запроса начинается с названия метода, то есть имени основной операции, производимой над ресурсом.

Основные методы:

  • GET – используется при наборе адреса вручную или переходе по ссылке
  • POST – используется при отправке формы

Думаю, что распределение частоты запросов примерно такое:

  • 99.9% – GET
  • 0.1% – POST (читают Интернет намного чаще, чем пишут)
  • 0% – другие методы (имеют скорее историческую ценность)

Примечание: не стоит воспринимать эти цифры буквально.

При обращении к серверному скрипту обычно передаются параметры запроса. Например, URI http://svitter.ru/?p=621 означает, что я хочу прочитать статью #621. Методом GET можно передать парамтеры только через URI. С помощью POST их можно передавать как через URI, так и в теле сообщения.

В следующей статье я напишу, как анализировать HTTP трафик. Это необходимо для создания программы, эмулирующей браузер (ведь нам нужен Интернет-бот, помните? :) ).

Mac OS X, часть 1. XNU, Darwin и все-все-все.

January 27th, 2010 Comments off

Disclaimer
Заранее хочу предупредить — моя оценка многих вещей, касающихся Apple, более чем смещена и временами космически субъективна. Я, разумеется, стараюсь быть как можно более толерантным к пользователям других операционных систем (и вообще считаю, что судить о человеке, по тому, какой ОС он пользуется, по меньшей мере недальновидно), но получается далеко не всегда :-)

Немного истории
В середине 90-ых годов прошлого века Apple оказалась в сложной ситуации. Классическая Mac OS (до восьмой версии называвшаяся просто и незатейливо — System) к этому времени уже, мягко говоря, отставала от современных веяний в развитии операционных систем — процессы могли писать (и писали!) друг другу в адресные пространства, многозадачность была кооперативной, каждый процесс мог рисовать напрямую в видеопамять и так далее. С каждой новой версией Mac OS становилось ясно, что ничем хорошим это закончиться в итоге не может.

В Apple это понимали, и поэтому параллельно с разработкой основной линейки Mac OS были запущены несколько проектов исследовательского характера: MkLinux (Microkernel Linux), Copland, Taligent и другие. Ни один из них не был доведён до стадии коммерческого продукта, но опробованные в них идеи были плавно внедрены в Mac OS (хотя коренным образом изменить ситуацию с ОС они уже не могли).

В итоге в Apple было принято решение купить операционную систему на стороне (вместе с компанией-разработчиком) и дорабатывать уже её под собственные нужды. Кандидатов оказалось два: Be Inc. с операционной системой BeOS и NeXT со своей NeXTSTEP. Руководство Be Inc. запросило 200 млн. долларов, Apple отказались платить больше, чем 125 млн., после чего переговоры с Be зашли в тупик. В конце концов, совет директоров Apple решил купить NeXT за 429 (!) миллионов, и, таким образом, именно NeXTSTEP оказалась в основе Mac OS X.

NeXTSTEP
Первая версия NeXTSTEP была выпущена в 1989 году вместе с первым компьютером NeXTcube и представляла собой многозадачную UNIX-based операционную систему, отличительными особенностями которой являлись:

  • лежащие в основе ОС микроядро Mach и BSD-подсистема
  • оконная подсистема, использовавшая Display PostScript в качестве внутреннего формата представления данных
  • Objective C в качестве основного языка разработки, а также все API, оформленные в виде Objective C фреймворков

Помимо этого, NeXTSTEP была одной из первых операционных систем, в которой появились теперь уже привычные псевдотрёхмерные элементы управления, большие полноцветные иконки, плавная прокрутка окон, а также панель быстрого запуска приложений (док) и поддержка Drag and Drop для объектов различного типа во всей операционной системе. Кроме этого, NeXTSTEP включала в себя поддержку прозрачности, стандартов по профессиональной работе с цветом, обширных возможностей по обработке видео и аудио, интернационализации, современной типографики и так далее.

(Лирическое отступление: выпуск первого компьютера с NeXTSTEP на борту задержался на несколько месяцев, но когда Стива Джобса спросили, что он думает по этому поводу, то он ответил «Мы опоздали на несколько месяцев? На мой взгляд, эта операционная система на несколько лет опередила своё время». Пожалуй, тут я с ним соглашусь.)

Наконец, NeXTSTEP предоставляла удобную среду для разработки приложений — Project Builder / Interface Builder, что, в совокупности с Objective C и обширным набором объектно-ориентированных API, позволило NeXTSTEP стать достаточно популярной среди разработчиков.

XNU
Таким образом, Mac OS X должна была стать симбиозом классической Mac OS и NeXTSTEP. То, что получилось в итоге, я постараюсь описать в этом и следующих постах.

Итак, в основе Mac OS X лежит ядро XNU (X is Not Unix), структура которого показана на следующем рисунке:

Структура ядра XNU

В самом низу пирога находится микроядро Mach, которое на самом деле не совсем микроядро в данном случае, поскольку работает с BSD-подсистемой в одном адресном пространстве. Если вы помните из курса системного программирования, основным недостатком микроядер является низкая скорость работы из-за необходимости постоянно переключаться из пользовательского контекста в контекст ядра (и наоборот), а также из-за необходимости копировать/отображать данные, передаваемые в виде сообщений между сервисами, в адресные пространства этих сервисов. Вообще говоря, создатели Mach на это и рассчитывали, и разрабатывали Mach с тем прицелом, чтобы под его (её) управлением могли работать целые операционные системы в виде обычных процессов. Однако, в случае XNU, такая функциональность не требовалась (операционная система всё равно будет только одна — BSD), и поэтому полная изоляция процессов друг от друга (характерная для классической микроядерной архитектуры) была принесена в жертву быстродействию.

В XNU Mach отвечает за работу самых базовых механизмов: вытесняющая многозадачность, передача сообщений (IPC), защищённая виртуальная память, поддержка «очень мягкого» реального времени, поддержка отладки самого ядра и консольный ввод/вывод.

Поверх слоя Mach работает BSD-подсистема, которая, по сути, представляет собой модифицированное ядро FreeBSD. Она отвечает за:

  • реализацию стандарта POSIX
  • Unix-модель процессов поверх задач Mach
  • базовые элементы безопасности (права на доступ к файлам, пользователи и группы)
  • стек сетевых протоколов
  • инфраструктура VFS (virtual file system), в рамках которой реализована поддержка различных локальных (HFS/HFS+, ISO9660 и т. д.) и сетевых (NFS) файловых систем
  • примитивы синхронизации (мьютексы, критические секции, спинлоки и т. д.)
  • POSIX IPC (сокеты, каналы, очереди и т. д.)

Ещё один важный компонент XNU — I/O Kit. I/O Kit — это объектно-ориентированный фреймворк для разработки драйверов, написанный с использованием ограниченного подмножества С++, из которого были убраны всякие излишества, использование в ядре которых было нежелательно: множественное наследование, обработка исключений и рефлексия (RTTI, run-time type information). Основная идея, стоящая за I/O Kit, проистекает из его объектно-ориентированного дизайна: функционал, общий для какого-либо класса устройств, реализуется в базовых классах самого фреймворка, позволяя разработчику драйвера сконцентрироваться на особенностях его конкретного устройства, просто унаследовав свои классы от нужного базового. Как результат — драйверы пишутся быстрее и с меньшим количеством ошибок. I/O Kit поддерживает многопоточность, в курсе особенностей работы на? SMP, поддерживает «горячее» подключение устройств и их автоматическое динамическое конфигурирование. Кроме этого, стоит отметить, что в Mac OS X определённые драйверы могут работать (и работают) в пользовательском контексте, что положительно влияет на общую стабильность системы.

Последние пару слов о XNU. Начиная с Mac OS X 10.6, XNU существует в двух вариантах — К32 и К64. Как нетрудно догадаться из названия, первый вариант — 32-битный (однако может запускать 64-битные пользовательские приложения), а второй вариант — полностью 64-битный. 64-битное ядро поддерживает:

  • больше 32 гигабайт оперативной памяти
  • размеры кэшей больше 4 гигабайт
  • и вообще, 64-битное адресное пространство — это хорошо

Однако, для того, чтобы загрузить K64, необходимо, чтобы и все модули ядра (Kernel EXTension, KEXT) и драйверы также были 64-битными, а вот с этим пока проблемы. В итоге, на данный момент K64 по умолчанию загружается только на новых моделях XServe и Mac Pro.

Darwin
Для того, чтобы завершить картину, осталось разобраться с последней штукой — Darwin. Apple часто довольно вольно жонглирует словами XNU и Darwin, часто обозначая ими одно и то же, хотя, вообще-то, это разные вещи. XNU — это именно ядро операционной системы, в то время, как Darwin — это вполне себе законченная POSIX-совместимая операционная система, основанная на XNU. По сути, Darwin — это Mac OS X без графической подсистемы и объектно-ориентированных фреймворков Carbon и Cocoa, Java VM и прочего. Раньше Apple выкладывала бинарные образы Darwin для свободного скачивания вплоть до восьмой версии, но потом перестала это делать, и теперь Darwin доступен только в исходниках на opensource.apple.com. Вот, собственно, и всё, что необходимо знать про Darwin.

Hands-On

А что, если я вам всё это время врал? Посмотрим, что выведет команда uname -v на моём МакБуке:

AndreyMacBook:~ Andrey$ uname -v
Darwin Kernel Version 10.2.0: Tue Nov 3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386

Как говорится, из рисунка видно, что в основе Mac OS X 10.6.2 лежит Darwin версии 10.2.0 (двойки совпадают неслучайно), а в основе этой версии Darwin лежит сборка XNU 1486.2.11 для платформы x86 от третьего ноября.

Hands-Off

И чо мне от этого всего?
Да, собственно, вот что. Благодаря своему FreeBSD’шному прошлому, Mac OS X — полновесная POSIX-совместимая операционная система. Это означает, что довольно-таки много программ, предназначенных, например, для Linux, легко и просто начинают работать в Mac OS X после стандартного набора заклинаний configure && make && make install (разумеется, если разработчики предусмотрели нужную ветку в configure-скрипте, но это всё-таки гораздо проще, чем целиком портировать приложение). Среди этих приложений есть и программы с графическим интерфейсом, так как в составе Mac OS X входит реализация стандартных иксов (X Window System). Запустив терминал, можно убедиться, что все любимые заклинания на месте, начиная от whoami и заканчивая kill.

В итоге, важно помнить, что Mac OS X — полноценный Юникс с набором POSIX-интерфейсов, дополненный собственными разработками Apple, со всеми вытекающими последствиями. И если кто-то будет убеждать вас, что Mac OS X — это просто красивая обёртка вокруг пустоты, не верьте — они просто не знают, о чём говорят :-)

В следующем выпуске «Кальвадоса» я думаю коснуться своей любимой темы — графической подсистемы Mac OS X, носящей название Quartz. А сейчас — приглашаю всех к обсуждению в комментариях к этому посту. Указывайте на ошибки, неточности, непонятности, задавайте вопросы — обязательно отвечу.

До встречи!