• Механическая работа

    Любую работу я условно делю на осмысленную и механическую. Первая — когда нужно думать, вторая — когда не нужно. Если проще, то в первом случае работает голова — нужно соображать, искать варианты. Во втором случае — задница: нужно сесть и сделать монотонную работу.

    Каждый вид хорош по-своему, и секрет в том, как их чередовать.

    Механическую работу нельзя делать, пока остался потенциал для осмысленной. Лучше сделать осмысленную, а механическую оставить на потом. Обратное тоже верно: нельзя браться за осмысленную, если уже устал — лучше заняться рутиной.

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

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

    Осмысленность и механика — две стороны одной медали. На самом деле одно и то же, но и разные. Дают гибкость и маневр, скрашивают капризы нашего тела.

  • Крайний

    К слову “крайний” в значении “последний” я отношусь с улыбкой. Это дремучее просторечие, и дергать людей из-за него — то же самое, что поправлять “одеть” и “надеть”. Пусть человек говорит, такая у него особенность.

    Но я никогда не думал, что прочту “крайний” в значении “последний” в книге. И не в прямой речи простолюдина, скажем, “братан, предупреждаю, это крайний раз”. Слово “крайний” использует рассказчик книги, по сюжету — развитый, интеллектуальный персонаж.

    Как же случилось, что такое просторечение пропустили переводчик, корректор и редактор? Это уму не постижимо — разве что все трое приехали из одной рязанской деревни. Другой версии у меня нет.

    Книга — “Звездный десант”, крайний перевод.

    UPD: в Телеграме объяснили, что “крайний” пришло из военных и прочих профессий, связанных с риском. Там не говорят “последний раз”, опасаясь, что он станет таковым буквально. Можно понять: у военных, моряков и летчиков целый букет прибабахов. Но зачем перенимать это в обычную жизнь – загадка.

  • Задача с датами

    Прочитал, что в одной фирме дают задание: не используя библиотеки и Гугл, написать функцию, которая для заданной даты вернет название дня. Скажем, для 2021-03-25 — вторник, для 2015-09-11 — среду (беру с потолка). Я бы эту задачу не решил, и вот почему.

    Во-первых, я не помню все критерии високосного года. Каждый четвертый — это понятно, но есть еще два критерия, которые встречаются реже. Нужно смотреть их в википедии.

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

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

    Еще был переход с юлианского календаря на григорианский, отсюда “старый стиль”, “старый новый год” и прочее.

    Наконец, текущая система дат и времени — это костыль на костыле, которые достались нам от древних греков. Самое худшее, что можно вообразить — это работать с датами без библиотеки.

    “Что ж, свою кандидатуру я снимаю сам.” ©

    А вы бы решили?

  • Еще про Silent Hill 2

    Еще одна заметка про Silent Hill. Понимаю, что всем пофиг, но это для себя. В этот раз — еще одна партия наблюдений, незамеченных в детстве.

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

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

    Не монстры, не ужасы города, а именно Мария становится главным мучением Джеймса. В каждой ее смерти он винит себя. Это напоминает наказание в аду, когда преступник переживает преступление снова и снова. Вот в чем заключается наказание Джеймса: город дает ему идеальную женщину и постоянно убивает ее, сводя с ума.

    Только в последней сцене, увидев Марию живой в четвертый раз, Джеймс отвергает ее. Этим он разрывает порочный круг, и начинается финал.

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

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

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

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

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

    Каждый персонаж живет в своем мире, и только изредка они пересекаются. Каждому предназначено свое мучение. Об этом не сказано явно, нужно догадаться из диалогов. Когда Джеймс видит Анжелу в последний раз, он замечает, что все в огне (намек на то, что Анжела сожгла дом вместе с насильником). На это Анжела отвечает, что “для нее всегда так”. Неудачника Эдди преследуют выдуманные им же люди, которые насмехаются над ним. Джеймс не видит этих людей, потому что они в мире Эдди. Пересекаясь с ним, он видит только трупы убитых насмешников. В мире Лоры нет ни монстров, ни опасностей, только кошки. Догадаться об этом можно по диалогу, когда Джеймс находит Лору в подвале госпиталя и спрашивает, как есть удалось не получить ни царапины. Лора искренне не понимает, что ей может угрожать.


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

  • Саундтрек из Silent Hill 2

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

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

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

    Пересматривая кат-сцены, не переставал удивляться глубокому символизму игры. Каждый кадр, каждая сцена выстроена так, чтобы сообщать что-то между строк. Это и окружающие предметы, и антураж, и одежда героев.

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

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

    Ближе к концу игры Анжела просит отдать нож: она хочет покончить с собой, чтобы избежать мучений. Джеймс отказывается, на что Анжела замечает: бережешь для себя? И хотя Джеймс несколько раз за игру произносит, что не убил бы себя, именно это случается в главной концовке. Я в курсе, что есть и другие, в том числе когда он уходит из города с новой женщиной, а в лучшем случае — даже с ребенком. Но получить хорошую концовку при первом прохождении, скажем мягко, затруднительно. Поэтому суицидальный конец истории я считаю каноничным.

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

    Здесь и таится главная недосказанность игры: в багажнике машины лежит тело его жены. Повидав ужасы города, лишенный всех надежд Джеймс, пережив смерть жены дважды, возвращается на парковку. Там он заводит автомобиль и топит себя с телом жены. Не все из этого показано в игре, но концепция не оставляет других толкований.

    На мой взгляд, второй Silent Hill — это “Преступление и наказание” нашего времени. В нем заложен такой плотный концепт, что можно разбирать очень долго. Это самообман, оправдание преступления, различные приемы, чтобы убедить совесть в обратном, подавленная сексуальность, ненависть к зависимому человеку и целый короб подобных штучек. И это только Джеймс, не считая второстепенных персонажей вроде Анжелы, Эдди и Лоры. Подобно Раскольникову или Соне, каждого персонажа можно брать и рассматривать часами.

    Пишу это, чтобы напомнить: второй Silent Hill — важный культурный продукт нашего времени. Понимаю, это несколько странно: применять к игре формулировки, которые больше подходят книге. Да, из-за формата не все могут ознакомиться с ней. Но будь у вас лишние несколько часиков — не знаю, правда, откуда они в сорок лет — ознакомиться не помешает.

  • Микросервисы

    Беда микросервисов в том, что их разработчики не понимают одну вещь. Хотя формально микросервисы отделены друг от друга, на самом деле они связаны, потому что подчиняются общим требованиям.

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

    Не все равно хотя бы по следующим причинам.

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

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

    Далее трассировка. Каждый сервис трекает в общей базе request-id, с которым его вызвали. Записывается начало запроса, конец и статус. Должна быть админка, где вводишь request-id и система рисует граф вызовов с метриками. Опять же, где вы такое видели?

    Лимиты. У каждого сервиса должен быть механизм рейт-лимита, чтобы его не ддосили. Как бывает обычно? Ты вызвал сервис 1000 раз, и начинаются крики “кто нас дидосит!!11”. Так ведь нигде не написано, сколько раз можно вызывать! Должна быть прокладка, которая считает число запросов в разрезе потребителей и внятно отвечает, сколько ждать до обнуления. Такое хоть где-то бывает?

    Длины массивов. Сервис принимает список айдишников. Передаю 10 тысяч и получаю статус 500. Начинается восточный базар: передавай по сто. Нет, это мало, давай по тысяче? Нет, давай по пятьсот. Ну ок.

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

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

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

  • Нейролица

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

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

    Моральных аспект: искусственные лица подаются как клиенты бизнеса, которых на самом деле нет. Тут включается внутренний голос и говорит: будь на фотках люди с фотостоков, тебе было бы легче? Это же модели, актеры, которые сегодня врачи, завтра домохозяйки, а послезавтра у них съемки белья для Вайлдберриз. Прям так сильно тебе нужны настоящие люди?

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

  • Разрешения

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

    Может быть, не все помнят ранний Андроид, а я помню. В версиях до какой-то там у Андроида не было разрешений по требованию. Это значит, ты ставишь какой-нибудь Фонарик Про, а он говорит: нужен доступ к фоткам, контактам, акселерометру и еще десяти пунктам. А если не согласен, иди лесом. У Эпла разрешения были по запросу с возможностью позже отозвать их. Модель Гугла была ужасна, ее обузили так сильно, что пришлось сделать как у Эпла.

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

    Вряд ли такое произойдет, но помечтать не вредно.

  • Last in Clojure

    Chat GPT: No, the last function is not particularly expensive for vectors in Clojure. It runs in O(1) time because vectors in Clojure support efficient access to their last element.

    Meanwhile, Clojure:

  • Подробней о last

    Поскольку в заметке про last отметились только профильные специалисты (в Телеграме), считаю, нужна его подробная версия. Я и сам понимаю, что для таких огрызков служит Твиттер, но чего нет — того нет.

    Итак, дело вот в чем. Коллега спрашивает у Chat GPT, насколько дорого получить последний элемент вектора функцией last в Кложе. На это чат говорит — все тип-топ, у вектора доступ к последнему элементу работает за O(1).

    Все бы ничего, но в ответе напутаны правда и ложь, и в целом он не верный. Чтобы в этом убедиться, откроем исходный код функции last:

    (dеf
     ^{:doc "Return the last item in coll, in linear time"}
     last (fn ^:static last [s]
            (if (next s)
              (recur (next s))
              (first s))))
    

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

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

    Наконец, докстринг функции как бы говорит нам: вернуть последний элемент коллекции за линейное время. Линейное, Карл, то есть такое, что растет с числом элементов, то есть O(N).

    Поэтому буквальный ответ на вопрос таков: нет, функция last вернет последний элемент вектора за O(N) шагов. Что не подходит для больших векторов.

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

    Можно предъявить Ричу Хикки: надо было сделать интерфейс Lastable с методом getLast. Обычные коллекции бегут с головы, а вектор берет с конца. Все это упаковано в last, который переключает на нужную логику. Все довольны и смеются. Но имеем то, что имеем, тем более что я согласен с текущим положением дел. Из всех коллекций только вектор может вернуть последний элемент. Остальным коллекциям это не положено по идеологическим причинам.

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

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

Страница 1 из 84