Моя любимая история о рефакторинге продакшена из книги Е. В. Кудрявцева «Техника реставрации картин», Издательства Государственной Третьяковской Галлереи [sic!], Москва, 1948 год.
…
[Partial attacks] с утра весь день я открываю кассу каждые десять минут и перебираю вчерашнюю выручку — шорох и звон успокаивают. дверь с грохотом распахивается, дрожит стекло и меня снова охватывает сострадание: я слышу знакомый запах старого немытого больного тела, засохшей крови, трясущихся рук, перегара, слезящихся глаз, корицы, раскаленного стекла, яблок, соли, железный привкус во рту, тусклая зарешеченная лампа в длинном пустом коридоре, в моих легких уже много лет гниёт болотная вода, и стая птиц снимается с проводов, напуганная далеким взрывом.
What’s New in Purely Functional Data Structures Since Okasaki?
На StackExchange/cstheory: ”What’s new in purely functional data structures since Okasaki?”.
Всем любителям наверняка будет интересно.
Engineering/DevOps блоги
Во-первых, агрегатор разнообразного контента, сфокусированный на scalability: HighScalability.com.
Во-вторых, блоги крупных технологических компаний:
- 37signals: http://37signals.com/svn/;
- Блог CTO Amazon.com;
- Dropbox: https://tech.dropbox.com/;
- Ebay: http://www.ebaytechblog.com/;
- Etsy: http://codeascraft.etsy.com/;
- Evernote: http://blog.evernote.com/tech/;
- Facebook: http://www.facebook.com/Engineering;
- Google: http://google-engtools.blogspot.ru/;
- Github: https://github.com/blog;
- Instagram: http://instagram-engineering.tumblr.com/;
- Netflix: http://techblog.netflix.com/;
- Pinterest: http://engineering.pinterest.com/;
- Tumblr: http://engineering.tumblr.com/;
- Twitter: http://engineering.twitter.com/;
В-третьих, также рекомендуется мудрый твиттер DEVOPS_BORAT.
Номер ревизии в Git
В Subversion есть полезная в некоторых случаях вещь — монотонно увеличивающийся номер ревизии.
Возможно, я предпоследний, кто об этом догадался, но чтобы симулировать его в Git, нужно воспользоваться командой
git log --pretty=oneline | wc -l
которая выдаст число коммитов, предшествующих текущему.
Чтобы добавить к этому номеру уникальность, можно конкатенировать его с текущим sha1 — тогда на разных ветках будут разные номера ревизий.
Конечно, эта схема будет давать сбой при некоторых играх с перезаписыванием истории.
Bash History в терминале Mac OS X
Для Mac OS X оказалось очень удобно поместить в ~/.bash_profile две строчки:
export HISTFILE=~/.bash_history-`tty | sed -e 's/\/dev\///'`
export HISTCONTROL=ignoreboth
Первая строчка делает так, что у bash’ей из разных табов стандартного Terminal теперь будут раздельные файлы с историей команд.
Вторая строчка делает так, чтобы в history не сохранялись а) команды, начинающиеся с пробела (полезно для так или иначе опасных команд) и б) дублирующиеся команды.
Теперь после рестарта компьютера и открытия терминала мы получаем полностью сохранившийся контекст: текущие каталоги, выдачу команд до перезагрузки, а также полную историю каждого окна.
Полезный пример использования Git Stash и Git Diff
В посте ”The second-order-diff Git trick” излагается полезный пример использования git stash.
Вносим массовые изменения в дереве. Если все ок, то делаем git commit, если не все ок — то делаем git stash (а вовсе не git reset, как сделали бы многие). Состояние дерева откатывается до исходного. Вносим исправленные массовые изменения в дереве. Теперь мы можем сказать git diff stash@{0} и увидеть, чем отличаются друг от друга два результата массовых изменений.
Trinity: Fuzz-тестирование системных вызовов Linux
Очень интересный проект Trinity предназначен для fuzz-тестирования системных вызовов ядра Linux.
Каждый системный вызов аннотирован информацией об аргументах системного вызова — например, является ли аргумент набором флагов, адресом памяти или номером файлового дескриптора. При работе Trinity генерирует случайные входные данные для каждого известного syscall, и вызывает его. Так как структура аргументов известна, то эффективность тестирования существенно выше, чем при использовании наивного тестирования, которое просто генерирует случайные числа и скармливает их ядру. Например, можно особое внимание уделить адресам памяти, которые находятся рядом с четырехкилобайтными границами страниц, чтобы отлавливать ошибки off-by-one.
Практика, описанная в статье ”LCA: The Trinity fuzz tester” на прекрасном ресурсе LWN.net, демонстрирует интересные результаты. За 2012 год только сам автор обнаружил больше 150 багов в ядре. Еще больше багов нашли другие пользователи системы. Помимо багов в коде системных вызовов, были обнаружены различные проблемы с сетевой и дисковой подсистемами, а также в многочисленных драйверах. При тестировании системного вызова execve также можно очень быстро обнаружить множество ошибок в системных утилитах, которые запускаются со случайными аргументами командной строки (и падают от того).
В планах автора, помимо прочего — улучшение работы с системным вызовом ioctl, который в силу своей природы традиционно неряшлив — как по структуре (диспетчеризация через номер запроса), так и в силу того, что в коде для работы с оборудованием сложно обработать все возможные варианты.
Кабаний лес
Один из эпизодов романа Ши Найаня «Речные заводи». Обработка Ши Хуана. Рисунки Бу Сяо-хуая.
Издательство литературы на иностранных языках. Пекин, 1960 г. Отпечатано в Китайской Народной Республике.
PDF: kaban.pdf
PDF Metadata в Unicode
Метаданные (такие, как Author, Title и т. п. — видны в Document Properties) в стандарте PDF хранятся в совершенно ужасном формате.
Например, информация об авторе будет записана так:
/Author (...)
Вместо многоточия будет написано собственно имя, в виде строки байтов в одном из двух основных вариантов: Latin1 или Unicode.
Если ваша строка помещается в Latin1, то достаточно записать вместо многоточия сроку в этой кодировке, нужно только искейпить (добавив backslash) как минимум скобки и backslash (tiff2pdf искейпит еще несколько символов: возможно, от ужаса или для обратной совместимости неизвестно с чем).
Если ваша строка требует более полного Unicode, то вам придется сконструировать байтовую строку, состоящую из: а) BOM (Byte-Order Mark) в big-endian UTF-16; б) собственно текста в big-endian UTF-16. После этого нужно еще раз пройтись по этой байтовой строке, и искейпить в ней скобки и backslash (да, прямо «внутри» UTF-16BE). Полученную байтовую строку можно поместить внутрь скобок.
Удивительно здесь, что стандарт требует big endianness, и одновременно с этим требует указывать BOM. Казалось бы — с помощью BOM можно было бы совершенно стандартно поддержать UTF-16BE, UTF-16LE и UTF-8!
Я написал несколько патчей, которые исправляют поддержку Unicode в tiff2pdf.