Записи за месяц: September 2019

О программировании

Навык программиста в том, чтобы делать то, что хочется быстро и дёшево.
NB: Позже я придумал иначе: в том, чтобы наиболее выгодно переводить усилия в удобство (чьё-то, а в конечном счёте своё).

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

Из этого заблуждения возникает архитектурная астронавтика и боязнь хардкода. "Что, если эти обстоятельства изменятся? А если эти? А те?" Такой образ мыслей существует до тех пор, пока человек замечает обстоятельства избирательно; пока он не окинет свой код взглядом и не увидит, что всё в нём – это обстоятельства. Программа это закодированное условие, ограничение на полный произвол. Делая её "универсальнее", вы убираете часть условий, перекладываете их на плечи пользователя.

Например, вы пишете интерфейс доступа к базе данных. Ваша цель конкретна: каталог фильмов, режиссёров, актёров. Что сделает начинающий программист? Запросы "getMovie", "getActor", "getDirector" и так далее.
Но это неуниверсально! Что, если завтра в базе появятся книги? Другой программист предлагает: сделаем "getWork", "getPerson", у work будет параметр type (movie, book), а person будет по отношению к work иметь relation (актёр, режиссёр, автор книги).
Хорошая это идея? Ну, нормальная. Реализовывать её сложнее. Пользоваться ей сложнее! API слегка неочевиднее. Но действительно, очень полезно для расширения.
Третий программист говорит: Кто знает этих заказчиков! Сегодня они хотят одни поля, а завтра другие. Предлагаю сделать ещё универсальнее: getTable(name), getRecord(table, index), getField(record, index). Обратите внимание, какая универсальность! Мы можем хранить внутри таблицы фильмов и актёров, а можем автобусов и маршрутов. Мы можем хранить данные на сервере, а можем кешировать локально. Может прозрачно вводить любые отношения и ограничения!

Но этот универсальный интерфейс по сути не предоставляет никакого интерфейса. Вся сложность, все обстоятельства задачи легли на плечи пользователя. Универсальный интерфейс стал просто интерфейсом доступа к базе данных.
Архитектурным астронавтам это в голову не приходит, но ведь можно пойти ещё дальше. Кто сказал, что нам нужны таблицы и поля? А если завтра это изменится? Можно предоставить интерфейс "readBytes()" или "executeCode()". В таком случае пользователь может сам написать любой код, который будет работать с любыми данными, как ему вздумается!

Колхозная доктрина:
https://eax.me/kolkhoz-doctrine/

Открытый закрытый

В спортивном комплексе на Семёновской есть открытый бассейн и несколько закрытых. Однажды на двери открытого повесили объявление:

"Открытый бассейн временно закрыт, для желающих открыт закрытый бассейн".

Это уже достаточно всех запутало. Но пришёл сентябрь и касса закрытого тоже закрылась:

"Касса временно не работает. Билеты приобретайте в здании открытого бассейна"

То есть, надо вернуться в здание открытого бассейна, купить билет, а потом вернуться в закрытый.

Когда же приходишь за билетами, то выясняется, что по вечерам в закрытом бассейне теперь тренируются спортсмены олимпийского резерва, а поскольку меня можно считать олимпийским резервом лишь в том смысле, в каком является резервом неприкосновенный запас коровьих туш, хранящихся с 1960-х где-то на ледниках на случай голода и войны, то мне пришлось заниматься в 25-метровом!

С тех пор открытый бассейн снова открыли.

Круг света 2019

Самое красочное шоу на Театральной, четыре ролика длиной в час, пролетает только так. Индонезийский больше всего понравился. Много рекламы — вот уж чего не ожидал увидеть на Большом театре!

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

На Сахарова просто цветомузыка 45 минут, интересно только первый клип 5 минут (искры и змейка) и последний столько же (белые полосы). Первый показ в 19:30, так что если придёте к его концу где-то в 20:15, увидите всё самое интересное, когда станет скучно, можно валить. Но можно и не ходить.

В Коломенском лес расцвечен разными цветами, в кроне деревье светятся в темноте таинственные лица. Несколько крупных зданий — с анимацией. Симпатично, но мало.

Экономика бесконечной разработки

Вот есть какое-нибудь Яндекс.Метро. Простое приложение для расчёта поездки. В последнее время оно показывает много рекламы. Понятно, почему: разработчикам надо платить. Поддержка на Google Play так и пишет: "благодаря рекламе оно продолжает жить и развиваться".

Сколько приложению нужно денег? Начнём с одного разработчика в месяц. Пусть даже он получает 300 тысяч. Или их несколько, но получают меньше, или работают не полную ставку. Неважно. Приложение установлено 150 тысяч раз, будем считать, 100 тысяч им пользуются. С каждого надо в месяц получить три рубля.
Нельзя ли вместо рекламы оплатить разработку прямо? Сколько это будет стоит? За год – 3*12=36 рублей + процент гугла = 50. Немного, но ощутимо каждый год, если таких приложений много.
А одной ставкой на 300 тысяч наверняка дело не обходится.

И тут возникает вопрос. А собственно, чем занимаются эти одна-две-три ставки на 300 тысяч? И нужно ли мне это?

Если подумать, мои интересы обычно противоположны. Я не хочу, чтобы приложение "развивалось". "Развитие" большинства приложений приносит мне только досаду и утрату привычных функций. Например, от Яндекс.Метро мне больше ничего не нужно. Я бы хотел, чтобы оно оставалось таким, какое есть. И я не хотел бы смотреть рекламу или каждый год платить за него. Удивительно, как эти интересы совпадают, и противоположны тому, что пользователь якобы должен хотеть!

Отчего же приложение не может быть таким? Ну, Яндекс.Метро приходится всё-таки следить за новыми станциями, хоть это не работа на полную ставку. Но почему какой-нибудь текстовый редактор или считалка калорий, то есть, приложения с простыми и понятными целями, не могут замереть и не тратить ни моих денег на разработку, ни моих нервов на обновления?
Почему мост можно построить и всё, а о приложениях стало модно думать как о бесконечно предоставляемой услуге?

Кто-то скажет: это тебя всё устраивает, а другим хочется большего. К тому же, автор желает делать своё приложение всё лучше и лучше. Почему он должен останавливаться на достигнутом?
В общем да. Но почему на достигнутом нельзя остановиться пользователю? Остановиться на той версии, которая устраивает. Больше ничего не платить.

И тут внезапно выясняется, что сделать это почти невозможно. Повсюду автоматические обновления. Вот система автоматических обновлений-то и внедряет в толпы привычку, что приложение это услуга. Да, можно выкачать пакет вручную, можно его сохранить, потом можно отключить обновления, переустанавливать из пакета… Но кто это будет делать?

Logrotate creates empty compressed log files

Case study: After some changes I've noticed logrotate flushes the main log (as it should) but all gzipped archived copies it creates are empty (20b). Logrotate destroys logs instead of preserving them.
You had one job, logrotate!

Turns out my logrotate file looked like this:

/var/log/httpd/*_log /custompath/log/*_log {
..
create ...
}

And the latter had been symlinked to the former.

It made sense when I wrote that. Cover all the bases. But the way logrotate works, it first scans all paths for files that need rotating and then applies rotation to them all.

So if I have /custompath/log/error_log reflected as /var/log/httpd/error_log, logrotate notices two files in need of rotation. It then compresses the first one, replaces it with empty log (create), then compresses the second one (now empty) and replaces the first .gz with an empty archive.

Nice job, logrotate. Make sure the collected filenames resolve to unique files? Nope. Maybe at least don't overwrite already existing gzips? Nope.

Выборы 2019

В кои-то веки почти нет чувства, что за результатом не уследил. Наоборот, сам всё проверил и наполовину руководил подсчётом, сошлось точно. Наш УИК даже сдался в ТИК первым.
За книгами присматривал, и как выдают бюллетени, проверяют паспорта, как вписывают. Не могу сказать, что подтасовки исключены, но в этот раз я не закрыл глаза на подозрения, не тупил, всё проверял.

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

(истории с участка)

Утром спрашиваю председателя:
– Какой последний избиратель в списке?
– Зачем тебе?
– Хочу сравнить со вчерашней цифрой.
– 1715.
– Ну… Более-менее.
– Какое ещё более-менее? 0__0 Ты мне сейчас на камеру такого наговоришь!

Кандидаты от власти теперь стесняются своего единоросства и стыдливо стали “самовыдвиженцы”. Но иногда это выходит боком :) Мужчина смотрит в бюллетень и спрашивает:
– Кто здесь от Единой России?
– Только коммунисты две штуки, ЛДПР и самовыдвиженцы.
– Э… – мысли на лице мужчины просто застревают, он поднимает голову и непонимающе спрашивает: – То есть как это, от Единой России никого нет?
– Нет.
– А как же… Так от Единой… Так они же… Они что, уже… Что, правда никого нет?
Мужчина явно не знает, что ему теперь делать.

Не повезло и другим:
– А вот за этих, за либералов, я никогда в жизни не проголосую! Пусть валят куда-нибудь, если им не нравится, говорит мужик, указывая на ЛДПР.

Заходит опрятный человек в костюме, со всеми поздоровался. Мне говорят: Козлов заходил [кандидат].
– А, так это и был Козлов?
– Да.
Смотрю на фотографию на стенде и без задней мысли говорю:
– Похож.

По закону с урной нас должна сопровождать полиция. К середине дня полиция кончилась (“митинги разгонять у них полиции хватает!” – говорит председатель) и с нами пошла Росгвардия. Оставляли её на первом этаже.
Возвращаемся, с ними уже ведёт диалог мужчина:
– Мне надо? Да пусть бы хоть бы из Пятёрочки. Да пусть бы хоть бы и поллитра. А тебе чего здесь надо? А чего тебе меня… (Увидев нас) А-а-а-а-а. Так вы за этими пришли. Так забирайте их, а чего сразу не говорите?

Обе стороны эскалатора

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

В бассейне на двери женского туалета распечатан призыв: “Дамы и господа! Выходя, оставляйте туалет за собой чистым”. Хорошо, гусары будут иметь в виду.

Когда захожу в твиттер, сверху написано: “Что происходит?”. Я каждый раз грустно соглашаюсь: да вообще… что происходит? Если ты не знаешь, твиттер, то я и подавно.

Да, однажды в одной европейской стране я попал в женский туалет. Я увидел два изображения. На одном инвалид, на другом — просто человек. На самом деле это была женщина. Просто очень гендер-нейтральная женщина. Я подумал: вот это Европа! Два туалета, для инвалидов и для всех остальных. Мне, конечно, в правый. И я пошёл туда. Неудивительно, что внутри не было писсуаров. И когда я выходил, навстречу шли одни женщины. Но я гордо прошёл мимо них, как человек, причастный к европейским ценностям. Нисколько не стесняясь того, что в Европе мужчины и женщины ходят в один сортир. Я вышел оттуда и прошёл немного вперёд. Мимо мужского туалета. Тут я немного отдалился от европейских ценностей и приблизился к картине Эдварда Мунка.