Вейсманистам-морганистам на заметку

Сегодня обсуждали успехи истинно мичуринского садоводства на фазенде. Я в разговоре раздвигал руки, показывая длину выращенных кабачков и показывал ладошкой высоту укропа. Минут за 20 кабачки «выросли» с 15-20 сантиметров до метра, а укроп — выше человеческого роста. Вот она, истинная сила мичуринской агробиологии!

Аналогичные достижения вейсманистов-морганистов мне неизвестны. [info]hirou, может, расскажешь?

О цене на водку

Или «какую страну просрали». Навеяно последней записью [info]shoei1980.

Разные люди независимыми методами пришли к мнению, что курс советского рубля середины 80-х к нынешнему российскому составляет примерно 1:100 — то есть один советский рубль равен ста нынешним. Советская водка времен начала антиалкогольной кампании Горбачева стоила 4 рубля 12 копеек получше или 3 рубля 62 копейки похуже — то есть 412 и 362 российских рубля соответственно. Средняя советская зарплата составляла 200 рублей, средняя российская — около 20 тысяч.

Сейчас идут разговоры о том, что хорошо бы продавать «социальную водку» для конченых алкашей рублей по 70-80. Разумеется, «социальное пойло» должно быть настолько отвратительным (из-за специальных вкусовых добавок), что пить его сможет только полностью опустившийся человек (но при этом оно должно быть более «привлекательным», чем стеклоочиститель или тормозная жидкость). Так вот, возникает вопрос: за что боролись? С 1985 года «потребительская стоимость» водки упала более, чем вчетверо. Можно предположить, что и алкашей стало много больше (так как напиться до поросячьего визга стало вчетверо легче).

Удивительно, что все разговоры о повышении цены на алкоголь заканчиваются ссылками на «исторический опыт» — якобы если самая гнусная водка станет стоить больше 100 нынешних рублей, то население перейдет на всякую косорыловку, как случилось после 1985 года. Интересно, как любители косорыловки обходились в СССР, когда водка стоила намного дороже, чем 1 рубль?

Собираем toolchain для MIPS

Как конченый китаефоб, я попросту не доверяю тем toolchain-ам, которые можно скачать с сайта Ingenic. А как вымирающий миниксовод, просто-таки обязан использовать для разработки Minix.

На самом деле, правда, я решил использовать ноутбук с миниксом как машину для разработки по одной простой причине — Minix 3 сейчас представляет собой довольно странную систему с точки зрения набора средств разработки. Например, make в миниксе — это вариация на темы BSD make, а входящий в Cygwin (под которым я хотел работать сначала) GNU make не понимает «позаимствованные» из NetBSD makefile-ы ядра Minix. Собрать BSD make в Cygwin у меня не получилось, там есть какие-то нюансы, так что я решил портированием миникса заниматься на нем самом.

Естественно, что фирма Ingenic не подозревает о существовании такой ОС и «готовый» toolchain для него не выкладывает. Тем хуже для них, потому как компилятор и утилиты для MIPS ничего особо страшного не представляют. Я решил действовать по инструкции с linux-mips.org. Пока что я собрал только binutils и GCC, перспективы использования отладчика пока туманные (так что все дальнейшее превращается в некую авантюру). Успокаиваю себя тем, что в Minix 3 приличного отладчика тоже никогда не было, и ничего, живут люди.

Итак, для начала скачиваем рекомендованные на сайте версии binutils (2-16.1) и GCC (3.4.4). Думаю, что binutils можно и посвежее, а вот с выбором GCC лучше не торопиться. То, что другие называют «бета-версией», разработчики компилятора GNU считают самостоятельным релизом. Например, в магистерской работе Ингмара Альтинга про портирование Minix 3 на PowerPC специально обращается внимание, что GCC 3.4.6 нормально компилирует MinixPPC, а 4 версия (4.x.x) жестко косячит.

Перед сборкой определим некоторые переменные окружения.

export WDIR=/tmp
export TARGET=mipsel-unknown-linux-gnu
export PREFIX=/usr/local/mipseltools
export PATH="${PATH}":${PREFIX}/bin

Говорят, что в качестве $TARGET можно безболезненно использовать сокращенную запись того же самого — а именно, mipsel-linux, но я не проверял. Вообще, эта строка строится по правилу архитектура-компания-ядро-ОС или иногда — архитектура-компания-ОС, например, mips-sgi-irix6.

Для начала собираем binutils. Тут все без сюрпризов. Распаковываем, конфигурируем, собираем, устанавливаем.

tar xjf binutils-2.16.1.tar.bz2
mkdir build-binutils && cd build-binutils
../binutils-2.16.1/configure --target=$TARGET --prefix=$PREFIX
gmake
gmake install
cd ..

Обращу внимание, что вместо make надо вызывать gmake, в случае с binutils все прокатывает, а с gcc возможны ошибки из-за различия синтаксиса Makefile-ов.

C gcc придется немного повозиться. Во-первых, configure неверно определяет возможности системы, во-вторых, встроенные типы Minix конфликтуют с некоторыми локальными для gcc определениями. Итак, распаковываем и конфигурируем.

tar xjf gcc-3.4.4.tar.bz2
mkdir build-gcc-bootstrap && cd build-gcc-bootstrap
../gcc-3.4.4/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c --without-headers --with-gnu-ld --with-gnu-as --disable-shared --disable-threads

В файле gcc/auto-host.h убираем определения HAVE_GETRLIMIT и HAVE_MMAP_FILE. Кроме того, надо временно закомментировать в файле /usr/include/minix/types.h определение типа block_t. В одном из модулей gcc определяется собственный тип с таким же названием, не имеющий никакого отношения к блокам файловой системы Minix. После этого —

gmake
gmake install
cd ..

Работоспособность всей получившейся хрени можно проверить, собрав u-boot. Все очень просто — скачиваем его с VoGeeky (а можно, кстати, поставить git). Правда, придется поправить Makefile. Вместо конструкции

ifeq ($(ARCH),mips)
CROSS_COMPILE = mipsel-linux-
endif

пишем

ifeq ($(ARCH),mips)
CROSS_COMPILE = mipsel-unknown-linux-gnu-
endif

Теперь можно собирать (естественно, не забыв, что путь к тулчейну был добавлен в $PATH):

gmake volans_nand_config
gmake

После этого компилятор поработает-поработает и выплюнет вполне работоспособный загрузчик. Правда, придется перекинуть его на другую машину, чтобы засунуть в плату — дело в том, что в Minix то ли нет поддержки USB, то ли она в зачаточном состоянии. Соответственно, jzboot запустить не удастся. Ну а как перекидывать файлы — прекрасно написано в руководстве по сетевым возможностям Minix 3.

Валим из этой страны

Все пропало, средний чек в московском макдаке составляет 8,92 $, а в американском — всего лишь 6,50.

http://www.nytimes.com/2011/08/04/business/global/russia-becomes-a-magnet-for-american-fast-food-chains.html?_r=3&pagewanted=1&ref=business

Пока наши СМИ в один голос твердят, что бизнес в России невозможен, к нам лезут американские сети быстрого питания. Почему-то они СЭС не боятся.

Джойстик от Денди

Кстати, нашел схему джойстика Dendy. Оказывается, это всего лишь восьмибитный статический регистр (микросхема 4021) с соответствующим количеством кнопок, а схему вполне можно вписать в габариты отсека для клавиатуры Playstation. В общем, можно попробовать превратить вогоплеер в гибрид плеера и Dendy. Ничуть не хуже Playstation :)

Необходимые пояснения

Запись про обучение программированию на мехмате МГУ почему-то сегодня привлекла внимание общественности. Так как запись, в общем-то, провокационная, необходимо дать некоторые разъяснения.

Во-первых, по поводу того, что на «профильных» кафедрах (вычислительной математики, математической теории интеллектуальных систем и т. п.) читается несколько более полный курс. Если заметите, то основные претензии я предъявляю к «Программированию и работе на ЭВМ». Этот курс растянут на четыре семестра и читается на первом и втором курсах, еще до распределения на кафедры. Соответственно, он и представляет (должен представлять) собой то, что требуется знать математику, этакое «введение в Computer Science». Даже некий «идеальный» курс программирования для мехмата (я его не буду озвучивать, чтобы не вызывать холиваров — у меня есть некие предположения, что там должно было бы быть, но я считаю себя не вполне компетентным, чтобы выдавть своих личных «тараканов в голове» за ту необходимую часть CS) будет содержать лишь некоторые из пунктов, озвученных [info]sharpc под заголовком «Теоретический минимум для программиста«.

«Практикум на ЭВМ» третьего и четвертого курсов, на мой взгляд — вполне разумное дополнение к курсу «Численные методы», а его растягивание на четыре семестра связано исключительно с тем, как (плохо и медленно) умеют писать программы студенты, успешно сдавшие «Программирование и работу на ЭВМ».

Во-вторых, к вопросу о том, нужно ли программирование на мехмате вообще. Здесь я солидарен с человеком, подписывающимся ником Гастрит ([info]__gastrit), который на старом-престаром форуме мехмата написал следующее в ответ на аналогичную по содержанию реплику (по поводу второй части можно с Гастритом и поспорить, но делать это в отсутствии оппонента как-то глупо):

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

Сегодня — 5 августа 2011, но актуальность эта фраза не потеряла. К сожалению, для математика «элементарные навыки работы с ЭВМ» оказываются довольно обширными. Универсальных средств, позволяющих в произвольной форме, допустим, преобразовывать к нужной форме любые выражения или же доказывать теоремы, на сегодняшний день не существует. Следовательно, математик должен уметь заставлять ЭВМ делать то, что ему нужно, то есть писать программы. Это требует некоторых знаний в области Computer Science.

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

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

< … >

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

Если посмотреть на выделенные формулировки — то можно понять, что математик (в понимании составителя сборника), пусть даже и не выполняя непосредственно обязанностей программиста, должен все же иметь некоторые знания об использовании вычислительной техники и разработке алгоритмов.

Следующее. По поводу того, что программа мехмата сравнивается с программами факультетов Computer Science. Последние намного шире, чем та «идеальная» программа мехмата, которую мне хотелось бы видеть. Более того, я говорю о той области CS, которая незаслуженно «обходится» на мехмате. Вычислительная геометрия все-таки для математика важнее, чем теория операционных систем (которая излагается в трех словах: «Ядра — чистый изумруд!»). На мехмате вместо, допустим, изучения важных алгоритмов из этой области, студентов учат рисовать картинки в Wolfram Mathematica. Дело тоже полезное, но на «Практикум по компьютерной геометрии» не тянет.

Наконец, последнее. Говорят, что выпускники непрограммистских факультетов американских университетов «умеют писать только на фортране и знать не знают про ООП». Американских университетов существует довольно много, наряду с MIT или Беркли есть и «университеты штатов» — какой-нибудь Michigan State University. Там действительно программы — на уровне МГУшной. Вообще, в красивом дипломе, который с 2010 года выдает Московский Университет, большими латинскими буквами написано Moscow State University — как перевел бы американец, «Университет штата Москва». Как ни странно, во всяких международных рейтингах ВУЗов МГУ находится среди всех этих «Nord Wyoming State University», так что название вполне соответствует.

Кстати, недавние выпускники мехмата назвали ту запись «чересчур мягкой» :)

Про хаброидов

На днях видел на хабре две записи, можно либо смеяться, либо плакать.

Первая — «как правильно писать на Javascript». Первый же совет звучал примерно так:

Никогда-никогда не используйте eval()! Даже если очень надо — все равно не используйте! eval() позволяет порождать код, а это очень-очень нехорошо! Так делать нельзя, потому что так делать нельзя никогда!

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

Доводя это до абсурда, скажу, что самые true-программисты никогда не используют операторы цикла, а обходятся только goto и if в виде

if(condition) goto somewhere;

Всякие бесполезные циклы нарушают логику работы программы, привычную тем, кто всю жизнь писал на FORTRAN-77.

Вторая — чувак для понтов реализовал в C++ вычисления, как он сам сказал, «с плавающей точкой» на этапе компиляции (с использованием шаблонов, разумеется). Я не буду придираться к тому, что на постсоветском пространстве вместо точки «плавает» запятая, потому как заголовок неправильный с самого начала. Число с плавающей запятой — это представление числа в виде мантиссы с фиксированным количеством знаков и порядка. У автора реализовано представление в виде отношения двух целых чисел, это несколько другое «решение». Обычно в программировании это называют «рациональными числами», не заботясь, правда, о полной корректности этой формулировки. Подходы эти принципиально разные и путать одно с другим не надо.

В общем, как кто-то заметил, «Русская Википедия — это деревенский кружок любителей истории». Хабр в таком случае — деревенский кружок любителей так называемых «информационных технологий».

Про robots.txt

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

Так вот, robots.txt был придуман не для обеспечения безопасности. Он был придуман для того, чтобы вебмастер мог ограничить тем самым «роботам» заход в некоторые разделы сайта. Например, у меня на сайте есть PHP-скрипт (в реалиях начала 90-х это была бы программа на C или скрипт на Perl), решающий дифференциальное уравнение и строящий график. Если запрашивать странички с чем-то подобным слищком часто, то такое поведение будет называться DoS — Denial of Service, или (вставить название популярного сайта)-эффект. Думаю, если разместить ссылку на этот «построитель графиков» где-то на главной странице сайта с десятком тысяч посетителей в день, то мой сайт просто загнется.

Есть страницы, куда поисковых роботов пускать не надо — например, «версия для печати». Они дублируют существующие страницы и не должны появляться в выдаче поисковика. robots.txt был придуман для того, чтобы поисковик не нарушал работу веб-сервера:

During one of my periods of burn-out I decided to teach myself Perl. So I started by trying to write a web spider — a bot that did a depth-first traversal of the web, to retreive (and eventually index) what it found, or just to download pages (a la wget or curl). There weren’t many resources for robot writers back then; the internet in the UK was pretty embryonic, too. (SCO EMEA had a 64K leased line in those days, shared between 200 people.) I was testing my spider and, absent-mindedly, gave it a wired-in starting URL. What I didn’t realize was that I’d picked a bloody stupid place to start my test traversals from; a website on spiders, run from a server owned by a very small company — over a 14.4K leased line. I guess I’d unintentionally invented the denial of service attack! Martin, the guy who ran the web server, got in touch, and was most displeased. First, he told me to stop hammering his system — advice with which I hastily complied. Then he invented a standard procedure: when visiting a new system, look for a file called «robots.txt», parse it, and avoid any directories or files it lists. I think I may have written the first spider to obey the robots.txt protocol; I’m certainly the numpty who necessitated its invention.

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

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

Так вот, недавно Яндекс соорудил новый «инструмент для вебмастеров» — Яндекс.Метрику, которая позволяет, например, отслеживать маршруты пользователей по сайту. Для этого поисковику передаются адреса всех посещенных пользователями страниц (говорят, что «обезличенно» — но мы-то знаем, пользователя можно практически однозначно идентифицировать по особенностям его браузера) — и кто-то умный решил, что эти адреса тоже стоит включить в индекс. Результаты все видели сами.

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

Cheap life — smart life

Наткнулся в ЖЖ на сообщество [info]cheap_life. Блоггеры и хипстеры соревнуются в том, кто меньше потратит за определенный отчетный период (за месяц, по-моему). Результаты (в рублях) такие:

Наш бесспорный чемпион — [info]sashafomina 8056 рублей!
Второе место у [info]bratkova 10750! Поздравляем!!!
Далее с большим отрывом идут:
[info]aisthetes 16363
[info]mag_afa 17755
[info]lakrizzza 18320
[info]polikvilkin 19680
[info]kubikrubik 19745
[info]bryulik_dixi 21946
[info]suomi 27 774

Напомню, что средний размер заработной платы в РФ — 20 тысяч рублей в месяц (не забываем о подоходном налоге, который съест 2600 рублей), размер пенсии в Москве — 8 тысяч рублей, МРОТ — 4611 рублей (и тут вычитаем подоходный налог), стоимость потребительской корзины по Москве — чуть более 3 тысяч рублей.

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

Люди тупеют

Прекрасное:

Автор, считая, что люди тупеют глубоко ошибается — люди константа. 95% всегда идиоты. Это как число Авогардо.

Из комментариев к очередной статье из серии «А при Сталине у меня хуй стоял делали ракеты».

Кто круче в интернете

fedotov-itogi Проведенный давным-давно по на водке [info]infowatch (на фото справа) эксперимент с одновременным комментированием записей в ЖЖ и на стендалоне дал такие результаты:

— в ЖЖ 13 записей (пока мне не надоело) получили 26 комментариев
— на сайте — всего 18

Казалось бы, безоговорочная победа ЖЖ? Не совсем. Все, кто комментировал в ЖЖ, прекрасно оставляли комментарии и на стендалоне (спасибо технологии OpenID). Проблемы у меня не в невозможности оставить комментарий, а в двух простых вещах (как мне кажется по опыту комментирования на dreamwidth и прочих тифаретниках), которые мне лень сделать уже года три:

— уведомление на почту при ответе на комментарий
— более привычный для ЖЖистов вид формы комментариев

Почему лень? Потому что в борьбе с непрерывно обновляющимся вордпрессом есть только один выход — сделать свой вордпресс с блекджеком и шлюхами. У некоторых получается.

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

Например, лет пять-десять назад, когда рулили «мегапорталы», зарегистрироваться на каком-нибудь средней руки форуме было нельзя без указания адреса электронной почты. Идея простая — e-mail можно получить с некоторым геморроем (типа указания размера обуви, девичьей фамилии матери и доказательства арийского происхождения), зато возможность доступа к ящику электропочты считается достаточной для идентификации пользователя.

I was pretty good at skeet shooting, but was eventually kicked off the range for catching the clay pigeons in a net and dispatching them execution-style.

Мегапорталы благополучно издохли, ныне вмето них появились «социальные сети» — та же хрень, только в профиль. Но самой важной их фишкой в довольно скором времени стала возможность регистрации без указания e-mail, например, с помощью одного только номера мобильного телефона. Вместо того, чтобы «доверять» серверам электронной почты в деле проверки личности пользователя, соцсети стали делать это сами.

Еще одно недавнее новшество — возможность «прозрачного» взаимодействия пользователей разных сервисов. Например, сейчас любой сайтовладелец может, при некоторых усилиях, «прогнуться» перед Twitter или Facebook и воспринимать залогиненных там пользователей, как «своих».

Идея эта отнюдь не новая, как пишет в заметке «Принуждение к безопасности» Н. Н. Федотов, «в реальном мире удалось как-то договориться о признании удостоверений личности, выданных другими». В виртуальном мире можно назвать такие (несостоявшиеся) инициативы, как Microsoft Passport или более удачный OpenID или OAuth. Правда, OpenID тем отличается от «серпастого, молоткастого советского паспорта», что его «провайдером», то есть органом выдачи, может выступать кто угодно (кстати, и e-mail страдает от той же проблемы). Я «признаю» пользователей LiveJournal, LiveJournal «признает» меня и даже отображает в вот таком виде: Шура Люберецкий [luberetsky.ru].

Собственно, OpenID-пользователь мало чем отличается от пользователя ЖЖ — тоже может читать френдленту, с недавних пор нам стало можно писать в сообщества — разве что собственного блога на livejournal.com у него нет. С другой стороны, можно настроить WordPress так, чтобы он воспринимал как «своих» пользователей из ЖЖ — и даже позволить им писать записи, ничуть не хуже, чем в ЖЖшных «сообществах».

Весь это кайф с OpenID придуман создателем ЖЖ, программистом-идеалистом Бредом Фицпатриком. Программистам-идеалистам вообще свойственно представлять реальность в духе лучшего, талантливейшего поэта советской эпохи:

"Дяденька,
          что вы делаете тут,
столько больших дядЕй?"
- Что?
      Социализм:
                свободный труд
свободно
        собравшихся людей.

Разумеется, в нашей капиталистической реальности ни о какой «саморганизации трудящихся» речь не идет. Вместо открытого распределенного протокола OpenID (придуманного для реализации модели «равный-с-равным») Twitter, Facebook и ВКонтакте предлагают свои собственные механизмы для авторизации своих пользователей на других сайтах. При этом ни о каком «равенстве» речь не идет: даже если я добавлю возможность оставлять комментарии для пользователей Twitter, это не будет означать, что Twitter будет воспринимать пользователей luberetsky.ru, как родных.

Знакомые историки не могут не смеяться, когда слышат слово «домен» применительно к Интернету. Как это не странно, термин, обозначающий владения феодала, как нельзя лучше описывает «общественно-экономическую формацию» нынешнего Интернета. Каждый, кто способен настроить web- или почтовый сервер, превращается в такого вот мелкого феодала. Может быть, это имело смысл, когда кто-то придумывал структуру устойчивого к ядерной войне ARPANET и последующие интернетовские сервисы, но сейчас наступает эпоха первых «буржуазных революций» и прочего мракобесия, пришедшего на смену развеселому Средневековью.

Как учил нас Карл Маркс, смена общественно-экономических формаций неизбежна и определяется развитием экономических отношений. Развиваясь, пресловутое «Интернет-сообщество» за какие-то несколько десятков лет прошло путь от обезьяны до человека от первобытного строя до развитого феодализма, который вот-вот и превратится в начальный этап капитализма.

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

Заметьте, что в нашем любимом ЖЖ в последнее время именно это и происходит — все больше и больше внимания уделяется удобству пользователей Facebook и Twitter, на развитие OpenID забито (а для многих он вообще отключен). ЖЖ, по приведенному в первых абзацах определению, теряет свою «крутость» и фактически признает, что Twitter и Facebook теперь стали «главнее». Не будем забывать и про ВКонтакте с его авторизацией, и про попытки Mail.ru тоже сделать что-то «такое» — в общем, ЖЖ превращается из «главного блогохостинга всея Руси» в совершенно рядовой сайт, пусть даже и с немалым количеством пользователей.

PS Кстати, если вам так дороги ваши записи в ЖЖ — сделайте нормальный backup. Сравнительно недавняя история Интернета показывает, что «быть популярным» и «быть прибыльным» — это совсем не одно и то же. Вспомините тот же GeoCities — одну из самых старых (и популярных) служб веб-хостинга, созданную еще в 1994 году. Она поменяла нескольких владельцев, но никто так и не добился прибыльности. В конечном итоге Yahoo!, которому все это досталось, объявил о закрытии этого сайта. Не думайте, что кто-то будет испытывать нежные чувства к блевничкам всяких навальных и ибигданов. ЖЖ явно балансирует на грани рентабельности, и если рассматривать этот проект с чисто «бизнес-стороны» — то прекращение его работы из-за убытков неминуемо. Впрочем, владельцы ЖЖ могут преследовать и иные цели, чем непосредственное извлечение прибыли.

Российского образования псто

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

Как я уже говорил, описаний «делай раз, делай два» для триангуляции Делоне в Интернете практически нет. Есть книга А. В. Скворцова, есть несколько разной подробности описаний на сайтах американских университетов, например, из курса CS 294-5 Университета Беркли. Но я пишу этот пост не оттого, что хочу пожаловаться на жизнь — изобретателю велосипедов так делать нельзя, он сам себе злобный Буратино. Я хочу предложить уважаемой публике сравнить программу курса в Беркли с «Практикумом по компьютерной геометрии«, который с 2009 года включен в программу мехмата МГУ.

Согласитесь, что сравнение «практикума по Wolfram Mathematica» и очень серьезного курса в Беркли (предполагающего немалую самостоятельную работу) как-то не вяжется с представлением о «тупых американцах». Правда, компьютерной геометрии я не застал, а вот чему учат в «Практикуме на ЭВМ» на мехмате — рассказать могу. Предлагаю еще, для полного счастья, открыть пару хороших переводных учебников, типа SICP и Кормена и сравнить все происходящее.

Итак, на первом курсе сей предмет называется «Программирование и работа на ЭВМ» и предполагает сдачу двух зачетов — в осеннем и весеннем семестрах. Твердо установленной программы нет, все зависит от преподавателя, но подразумевается, что два сданных зачета доказывают умение студента писать программы на языке Си. Говорят, что иногда разрешают писать чуть ли не на Паскале. Занятия проходят попеременно в виде занятий за компьютерами и «обычных» семинаров, где препод рассказывает о том, что считает нужным. Например, А. Г. Кушниренко рассказывал про индуктивные функции, про некоторые нюансы языка Си типа арифметики указателей и правильного хранения двумерных матриц, а также — про своих (разумеется, тупых) американских студентов. Кроме того, он пугал нас тем, что на госэкзаменах мы забудем, что такое функция. К сожалению, мне на госах такой вопрос не задали, а я готовился :) Для получения зачета достаточно сдать три-четыре задачи из некоего списка (после этого преподаватель обычно убежден в том, что и остальные задачи студент сдаст, и больше не докапывается). Задачи простые (вот, например, список чего-то подобного), при минимальном знании Си решаются за полчаса каждая (и то время взято с большим запасом). У меня, например, от этого сложилось ложное впечатление, что и дальше все будет так просто.

На втором курсе было уже что-то похожее на вводный курс по Computer Science (с экзаменом в весеннем семестре и все тем же названием). Как всегда, было намешано все и сразу. В два семестра «у нас» запихнули четыре «американских» семестровых курса (вводный курс по C++, алгоритмы и структуры данных, формальные языки и грамматики, и понемногу, для общего знакомства — из курсов по операционным системам и компьютерным сетям). Все это прочитать за указанное время невозможно, поэтому реально программа несколько сокращается. Из лекций (их у нас читал В. В. Борисенко) я помню рассказ про машинную арифметику и стандарт IEEE 754, немного — про вызов функций с передачей параметров через стек в языке Си и ему подобных, было что-то про Register Transfer Language компилятора gcc, про «классические» алгоритмы и структуры данных, типа сортировок, разнообразных стеков, очередей и деревьев, кроме того, студентов развлекали байками о том, как горят в грозу сетевые карточки, и как отличить толстый Ethernet от тонкого. Формально для получения оценки нужно уметь решать задачи из опубликованного в Интернете списка и уметь отвечать на вопросы по программе, реально — надо решить по одной-две задачи из каждой темы или, допустим, найти ошибку в классе, реализующем арифметику произвольной точности (это приравнивается к решению соответствующей задачи). Этого достаточно для того, чтобы получить «пятерку» досрочно, а что происходит на основном экзамене — я не знаю. Говорят, что безбожно списывают, и положительные оценки получают даже полные «нули» по предмету.

В самом начале 2000-х на втором курсе пытались преподавать Java, но в итоге поимели кучу жалоб от студентов, от которых на третьем курсе внезапно потребовали знания Си или Фортрана. Борисенко говорил, что ничего «такого», что есть только в Си, использоваться не будет (а общее подмножество Java, Си и Фортрана осваивается в режиме «не приходя в сознание» за пять минут), но отечественный студент прекрасно умеет пользоваться фразой «а нас этому не учили!«.

Кстати, нельзя не упомянуть матчасть. Нет, это уже не старенький VAX, которому даже посвящен специальный сайт, сейчас мехмат полностью перешел на относительно современные персоналки. Ничего старше Pentium III я уже не застал. Гораздо интереснее софт. Стараниями К. Ю. Богачева на этих компьютерах стоит хитро настроенный Linux, запортить который студенты не могут. Чтобы жизнь малиной не казалась, задачи надо сдавать, используя хитро настроенный gcc (его еще называют «компилятор Богачева»). Там включена опция -Werror, приравнивающая предупреждения компилятора к ошибкам. В результате те, кто пишет дома в более лояльно настроенных компиляторах, сталкиваются с тем, что их программы просто не работают (в частности, компилятор матерно ругается на отсутствие пустой строки в конце файла, или на функцию main, возвращающую нецелое значение).

На третьем курсе начинается «Практикум на ЭВМ». Когда-то давно надо было писать на Фортране под СМ-4. Теперь, когда СМ сдана на цветмет, люди пишут на Си на тех же персоналках. Правда, говорят, что некоторые преподаватели принимают задачи и на Фортране. Не знаю, у нас этого никто не пробовал. Сей практикум растянут на четыре семестра, обо всем по порядку.

Третий курс в основном посвящен реализации алгоритмов из книжки «Методы решения линейных систем и нахождения собственных значений» все того же К. Ю. Богачева. В первом семестре надо написать две программы по 300-400 строк. В первой надо обратить матрицу размера около 1000×1000 (или решить аналогичных размеров линейную систему, это задачи равноценные), во второй — найти собственные значения той же матрицы. Пишутся они совершенно бездумно, простым переписыванием из книжки. Кстати, с точки зрения «справочника рецептов», написана она очень неплохо. Если преподаватель — не К. Ю. Богачев, то этого будет достаточно. Богачев требует несколько большего — а именно, ускорения этих методов в два-три раза. Правда, он еще и объясняет, как это сделать. После того, как сдана «практическая» часть — следует «теоретический» зачет. Всех студентов, сдавших программы, загоняют в аудиторию 14-08 и раздают письменное задание. Необходимо изложить три-четыре метода из книжки, если не полностью — то хотя бы в устраивающем Богачева объеме. Второй семестр — примерно то же самое, только книжка другая. На этот раз — «Методы приближения функций».

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

Четвертый курс несколько забавнее. Например, такого исчерпывающего руководства по всем вопросам, как методички Богачева, больше нет. Кроме того, надо написать не только программу, но и отчет — связный текст на 5-6 страниц, описывающий метод решения и убеждающий преподавателя в его правильности. Конкретные задачи зависят от «препода». Например, кто-то вычисляет интегралы всякими там «методами трапеций» или решает методом Ньютона нелинейные уравнения. У И. С. Григорьева задачи поинтереснее — решение дифференциальных уравнений методом Рунге-Кутта с автоматическим выбором шага и применение принципа максимума Понтрягина в задачах оптимизации (то есть сведение задачи оптимизации, которую человечество в целом решать не умеет, к «решабельной» системе дифференциальных уравнений). Сам Илья Сергеевич регулярно выигрывает некие международные соревнования по решению задач оптимизации и вообще, любит эту тему. Правда, с точки зрения программирования тут все довольно просто и «концептуально» не отличается от, скажем, метода Ньютона решения тех же дифференциальных уравнений. Если имеется «рыба» отчета, то программа вместе с отчетом пишутся за 5-6 часов (а их надо две штуки). Эта простота развращает, но благодаря ей я все-таки увидел Е. А. Лапшина, которого «надо бояться«.

Во втором семестре так же незамысловато решаются уравнения в частных производных. Все еще проще. Собственно, происходящее на третьем и четвертом курсах не имеет никакого отношения к тому, что на Западе называют Computer Science. Это просто практикум по численным методам, но, надо сказать, неплохой — если повезет с преподавателем. У вышеназванной Ченцовой, например, интересных задач не будет — зато будет много геморроя со сдачей отчета. Сегодня она не хочет брать его в руки, потому как «жалко, такой чистый», а завтра будет — «противно, такой грязный». На программу она даже не смотрит, кое-кто даже сомневается в том, что она знает Си.

Кстати, четвертый курс занимается в так называемом «классе Эйч-Пи» (я специально не пишу HP, чтобы не путали с русскими буквами). Это аудитория во «Втором гуманитарном корпусе» (хотя гуманитарность его ставится под сомнение наличием там ВМК и оккупацией мехматом нескольких этажей), где когда-то давно стоял миникомпьютер HP-810 (возможно, название неправильное, так его обозвали на страничке «Компьютеры, которые выбираем не мы«) с пятнадцатью терминалами. Сейчас там стоят обычные персоналки с Windows XP производства, кажется, того же Hewlett-Packard. Так как студенты таскают программы на дискетках, перед тем, как засунуть что-то в компьютер, надо это что-то дать на проверку специально обученной тетеньке, сидящей у входа в класс и умеющей пользоваться Dr. Web с безбожно устаревшими базами и пасьянсом «Косынка». Как нетрудно догадаться, вся зараза первым делом попадает на компьютер с антивирусом, откуда разносится по классу. Систему там переустанавливают по три-четыре раза за семестр. Впрочем, пора бы заканчивать с ностальгическими воспоминаниями.

Если принять «интенсивность работы» в американских ВУЗах из «первого десятка» за эталон — то первый курс мехматовского «Программирования и работы на ЭВМ» — это чистое жевание соплей. Второй курс более-менее похож на что-то нормальное (какие-нибудь «Алгоритмы и структуры данных»), «Практикум на ЭВМ» третьего и четвертого курсов из четырех семестров мог бы сжаться до двух (и идти параллельно с курсом лекций по численным методам). В общем, из восьми семестров получается четыре без особых потерь в содержании (а если так уж хочется оставить восемь — можно добавить столько полезных вещей, типа нормальной вычислительной геометрии…). Вот только с подобной интенсивностью попросту не справится половина студентов, а отчислить столько даже Лапшин не сможет.

Я уже упоминал, почему в американских ВУЗах программа курса строится не по принципу «меньше тройки не получишь», а исходя из того, что может/хочет рассказать преподаватель. Они могут позволить себе такую роскошь, как заваливающие экзамен 3/4 слушателей, у нас этого просто не поймут. Зато троечникам напрягаться не надо.

UPD http://shura.luberetsky.ru/2011/08/05/neobkhodimye-poyasneniya/ — я отвечаю на некоторые вопросы.

Автомобильное

[info]zig_zag63 жалуется на тяжелую жизнь современного автомеханика. Оказывается, на Ford Focus и «соплатформенных» автомобилях (типа Mazda3) замена ремня ГРМ — нетривиальная задача для гаражного Кулибина.

Как это делается на комфортабельных и маневренных автомобилях марки ВАЗ (и вообще всех машинах, которые могут обслуживаться Кулибиными)? У меня тут лежит «Камасутра» по Mitsubishi Lancer 1995-2004 годов (как кто-то говорил, «девятка, собранная японцами» — технически машина довольно простая, как раз для Кулибина), так что цитирую оттуда:

— Отметьте направление вращения зубчатого ремня
— Отвинтите верхнюю подвеску двигателя, подперев при этом двигатель
— Открутите шкив водяного насоса, слегка прижав клиновой ремень рукой, чтобы шкив не проворачивался
— Снимите клиновой ремень
— Установите коленчатый вал в ВМТ 1-го цилиндра: снимите верхний кожух зубчатого ремня, прокручивайте коленчатый вал двигателя по часовой стрелке до достижения распределительным валом положения ВМТ, затем совместите метку на шестерне распределительного вала с меткой ВМТ на головке цилиндров. Двигатель при этом установлен в положение ВМТ зажигания первого цилиндра.
— Отсоедините ременной шкив коленчатого вала от коленчатого вала
— Снимите нижний кожух зубчатого ремня
— Освободите установочный болт натяжителя зубчатого ремня
— Ослабьте натяжение зубчатого ремня и затяните крепежный болт так, чтобы установка натяжителя ремня не сбилась

и установка:

— Проверьте положение ВМТ распределительного и коленчатого валов двигателя
— Наложите зубчатый ремень на шестерню коленчатого вала, удерживайте сторону натяжения зубчатого ремня натянутой, затем проложите зубчатый ремень на шестерню распределительного вала через натяжительное устройство. Бывший в употреблении зубчатый ремень должен устанавливаться в прежнем направлении движения.
— Прокрутите немного шестерню распределительного вала против часовой стрелки. Выкрутите стяжной болт натяжителя. Установите ременный шкив коленчатого вала, чтобы при вращении коленчатого вала не соскочил зубчатый ремень.
— Натяните зубчатый ремень
— Проверьте положение ВМТ коленчатого и распределительного валов двигателя. Все метки и маркировки ВМТ при натянутом зубчатом ремне должны совпадать.
— Установите нижний кожух зубчатого ремня
— Затяните ременный шкив коленчатого вала центральным болтом с усилием 100 Нм
— Закрепите ременный шкив водяного насоса с усилием 10 Нм
— Установите клиновый ремень
— Закрепите верхнюю подвеску двигателя

А как советует это делать Ford Motor Company (я не буду называть ее Автомобильной Компанией Форда, как это сделали бы в 20-30е годы, не надо позорить старика Генри)? Надо купить чемоданчик со специнструментом (одноразовым, после использования деформируется), зафиксировать специальными фигурными планочками валы двигателя (это вместо меток на двигателе и шкивах, планочки, разумеется, небесплатные) и — держитесь за стул — смело перерезать ремень ножом!

knife

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

Генри Форд делал свои машины для простых американских реднеков и гаражных Кулибиных. Нынешний «руководитель» (точнее, executive chairman) FMC, Уильям Клей Форд-младший, правнук Генри Форда, автомобилями не интересуется, а ударился в буддизм и вегетерианство. Результат закономерен — автомобили делают не инженеры, а экономисты. Впрочем, так оно везде.

PS Кстати, интервал замены ремня ГРМ на Ford Focus по рекомендации производителя — 160 тысяч километров. Ремень столько не ходит (обычно вдвое меньше) и разваливается раньше, счастливый владелец влетает… точнее, сначала поршень влетает в незакрывшиеся клапаны, а владелец влетает на бабки.

Про рельеф

В продолжение вот этой задачки:

http://shura.luberetsky.ru/2011/07/19/algoritmicheskaya-zadacha/

Я реализовал алгоритм выбора точек, описанный в статье Systematic selection of Very Important Points from Digital Terrain Model for constructing Triangular Irregular Network без каких-либо изменений. Особо не заморачиваясь с производительностью, я добился того, что из миллиарда точек выбиралось порядка миллиона «очень важных» где-то минут за 40. Такое время меня вполне устраивало. Думаю, при желании можно сократить его в два-три раза, но делать этого я не буду, и вот почему.

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

Во-вторых, чудес не бывает. Более-менее адекватное количество «важных точек» можно выбрать тогда, когда их количество меньше общего количества точек где-то на два порядка. Итого миллиард точек исходника даст 10 миллионов точек TIN, или около 20 миллионов треугольников. Это много.

Если «сложить» эти пункты, то можно преобразовать исходный миллиард точек в 10 миллионов (с которых все и началось), а затем сделать из них 100 000 «важных точек» — около 200 тысяч треугольников, сущая ерунда по нынешним временам.

Кстати, хочу поплакаться на жизнь. Пол-пятницы искал нормальное описание того, как алгоритмически сделать триангуляцию Делоне. В интернетах встречается описание алгоритма со сложностью O(N2) — последовательно добавляем точки к существующей триангуляции, при необходимости перестраивая ее. Каждый шаг в худшем случае требует перестроения всех треугольников, и это мне не нравится. Иногда в довольно общих чертах описывают алгоритм типа «divide and conquer» — разбиваем множество точек надвое, строим для подмножеств триангуляции, а затем объединяем их. Сложность, как можно показать, асимптотически оптимальная, O(N ln N). Описание того, как именно надо объединять, обычно отсутствует. В книге Препараты и Шеймоса подробно разбирается задача построения диаграммы Вороного — графа, двойственного триангуляции Делоне, и вскользь делается упоминание о том, что построив диаграмму Вороного за асимптотически оптимальное время O(N ln N), можно преобразовать ее в триангуляцию. Этот подход тоже мне не нравится, так как для построения диаграммы Вороного требуется выполнять несколько более сложные операции.

Конечно, я нашел относительно адекватное описание всего этого безобразия, но как-то странно — вроде задача довольно классическая, а описаний решения «для тупых» нет.

Че ты лыбишься, как параша?

Из парижской резидентуры сообщают:

здесь (в Париже) в принципе все, как в Москве — много нищих, сумасшедших, много всякой грязи, проблем, рассказали ужасы про парижский смог 2003 года, который был похуже прошлогоднего московского, говорили про проблему с пробками, парковкой и что здесь адская духота в час пик в метро. Только здесь существенно меньше озлобленных людей почему-то.

А вот я хочу спросить у уважаемой публики, потомков варягов, скифов и воинов Чингисхана, можете ли вы улыбаться человеку, которому отдавили ногу, влезая в электричку? А тому, кто в эту электричку ломился, а вы его выпихивали коленкой? Или, может быть, стоит улыбаться охраннику и дежурной у турникетов, которые зафиксировали ваши спортивные достижения в беге с препятствиями? Можно ли изображать доброжелательное отношение к тем, кого вы распихивали локтями на станции «Выхино», чтобы плюхнуть свою задницу на сиденье?

Про недовольных

Говорят, что на Беломорканале сотрудники Речного Регистра в ходе внеплановой проверки задержали теплоход «Плеханов», по слухам, из-за нарушений при установке спасательного оборудования. Вроде бы спасательные плотики закреплены неправильно — читай, накрепко примотаны проволокой.

Народ возмущается и орет про «беспредел». А теперь представьте себе реакцию тех же возмущающихся, если теплоход затонул бы на Онежском озере, а плотики бы не раскрылись? Вот так всегда, причем самое интересное — возмущаются одни и те же люди.

Азиятской дикости псто

На днях был в «Икее» и сподобился съесть остывших пончиков и попить чаю, кофе и всякой разной минводы в тамошней едальне. Если остывшие пончики интереса не представляют, то про разные жижи стоит рассказать подробнее.

Как известно, «Икея» тотально придерживается принципа самообслуживания, в частности, это относится к выбору напитков в жральнике на выходе. Оплатив напиток на кассе, вы получаете стаканчик, с которым направляетесь к автомату с напитками и наливаете то, за что заплочено. Во всяком случае, так поступают европейцы. Как поступают в таком случае потомки скифов? Убедившись, что рядом с автоматом с напитками не стоит янычар и не делает секир-башка, они наливают и пьют все подряд, пока из ушей не польется. В тутошнем бардаке трудно отличить заплативших от незаплативших (правда, стаканчики для чая/кофе и газводы отличаются объемом и раскраской, но всем на это глубоко плевать).

Конечно, я не дошел до такой степени варварства, как приходить в «Икею» с пятилитровым жбаном и наливать туда всякие напитки, но стаканчик на всякий случай забрал с собой — а вдруг занесет туда снова?

PS Жаль, пива не наливают.

PPS Успокаиваю личинку цивилизованного европейца в себе тем, что с такими ценами от «Икеи» не убудет, даже если каждый будет приходить с канистрой для Кока-Колы.

Алгоритмическая задача

Дано: есть матрица высот, то есть (грубо говоря) равномерная сетка точек на поверхности Земли, для каждой из которых приведена ее высота. Точек много, порядка миллиарда. Нужно построить TIN-модель (triangular irregular network), то есть сетку из треугольников с «абы где» расположенными вершинами, «похожую» на исходную матрицу высот. Треугольников должно быть много меньше — несколько десятков тысяч это максимум.

Стандартные алгоритмы построения TIN построены по общему принципу — для каждой точки матрицы высот (всего их N) вычисляется какая-то численная характеристика, связанная с локальными свойствами этой точки, в качестве вершин треугольников выбираются точки с максимальным значением этой характеристики (а их число обозначим M), а затем для построенных вершин строится триангуляция Делоне. Так вот, поговорим про выбор вершин этих треугольников.

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

Легко понять, что функция f, выбирающая из последовательности x0, …, xn M максимальных элементов, является индуктивной, то есть f(x0, …, xn) зависит только от f(x0, …, xn-1) и xn. Можно записать это следующим образом: f(x0, …, xn) = F(f(x0, …, xn-1), xn). Индуктивная функция от последовательности длины N вычисляется за N шагов очень простым циклом, надо знать лишь значение f на пустой или одноэлементной последовательности и функцию F.

Очень просто написать функцию, находящую M «наибольших» элементов в N-элементной последовательности за O(N*M) с расходом памяти O(M) — выбранные элементы хранятся в массиве, каждый новый элемент сравнивается со всеми выбранными до этого. Если включить мозг, то можно улучшить оценку до O(N*log M) с той же оценкой расхода памяти (храним выбранные M элементов в самобалансирующемся дереве). А можно ли сделать это еще быстрее, возможно, отказавшись от подхода с индуктивными функциями? Я ответа пока что не знаю.

Vogue, U-Boot и дисплей

Сумел добавить поддержку дисплея в U-Boot для вогоплеера. Подробности потом, а пока объясните, как пользоваться git :)

Кстати, оценил то, как написан U-Boot и китайские дополнения к нему. Разобраться с тем, что и как наворотили наши узкоглазые друзья — еще та задачка.

Нашел багу

Немного поковырял китайский U-Boot, адаптированный для процессоров Ingenic. Помните, я писал, что там некорректно отрабатывает утилита bmp_logo?

Так вот, дело — в типично китайском коде. Как вы думаете, что напечатает программа?

int main(void){
    int l;
    FILE *in;
/* skipped some code */
    fread(&l, sizeof(uint16_t), 1, in);
    printf("l = %d\n", l);
/* skipped some code */
    return 0;
}

Естественно, что на всех более-менее современных машинах sizeof(int) > sizeof(uint16_t), то есть переменная l окажется просто неопределена — проинициализируются только первые два байта. На little-endian системах программа будет «корректно» работать, если l «автоматически» инициализируется нулем.

Несмотря на то, что в стандарте C ничего не сказано про инициализацию нулем локальных переменных, иногда такое происходит. Когда ОС выделяет память для новой программы, назначенные для нее страницы обнуляются — чтобы никакие вирусы-трояны не искали там логины-пароли. Как бы не было больно знатокам стандарта языка C, main — далеко не та функция, с которой начинается выполнение программы. Сначала вызывается библиотечная функция _start или аналогичная ей по назначению, специфичная для каждого компилятора и инициализирующая необходимые для работы стандартной библиотеки вещи (подумайте, например, как будет работать без инициализации malloc()).

Так вот, в Linux-системах можно надеяться на то, что локальные для main переменные окажутся на еще нетронутой части стека. Происходящее в Windows — гораздо более неясно, но там локальные переменные main «инициализируются» чем-то непонятным.

Кто виноват — ясно. А что делать? Нет, не надо писать int l = 0;. Хочу лишний раз напомнить о существовании big-endian систем. В них после вызова fread() шестнадцатибитное значение запишется не в два младших, а в два старших байта — и нетрудно догадаться, что мы хотели несколько другого.

К сожалению, описанные у Кернигана и Ритчи типы int, short и long имеют нерегламентированную длину. Гарантируются какие-то минимальные значения, и ничего более. int может запросто оказаться двух-, четырех- и даже восьмибайтовым. И как тут жить? Керниган и Ритчи придумали один возможный подход. Например, во всех Unix-системах принято, что «время» — это 32-битовое целое без знака. В time.h с помощью typedef определяется тип time_t, который в реальности может быть int (на 32-битных машинах) или long (на 16-битных). На 64-битной экзотике он вполне может оказаться и short. Определено несколько таких «стандартных типов» — и все.

Естественно, если подходить таким образом, то очень скоро мы начнем определять типы наподобие bmp_file_data_length_t — целое, соответствующее тому типу, в который помещается «длина данных» из bmp-файла. Не очень весело, правда? В современных реализациях C, стандарте C99 и C++0x предусмотрен заголовочный файл stdint.h, в котором определяются целые типы фиксированного размера. Например, uint16_t — это 16-битное беззнаковое целое.

Хорошим тоном считается использовать именно тот тип, который нужен в конкретном случае, особенно, когда речь идет о полях структур или других данных, размер которых четко определен. При переносе на другую платформу не придется биться с тем, что int внезапно стал вдвое длиннее :)

В общем, если бы безвестный китаец знал про типы фиксированного размера, он не стал бы использовать четырехбайтный int для хранения 16-битного значения и все были бы счастливы.

PS А вот еще вопрос. Что произойдет, если l объявить не в теле функции main(), а вне нее, как глобальную для данного файла?