-
Зависание окон в Экселе
Работал в Экселе и заметил одну вещь.
В офисном пакете интерфейс устроен по принципу “один файл – одно окно”. Это значит, если открыто пять файлов, то будет пять окон. А восприятие наше таково, что каждое окно считается независимым. Технически много окон могут обслуживаться одним процессом, да. Но когда я вижу окно во весь экран с менюшкой и табиками, оно ощущается отдельной программой.
Это приводит к странному поведению: во время долгого импорта виснут все окна Экселя. Я рассуждал так: пока импортируется тяжелый файл, я поработаю с другим файлом. Но Эксель в этом плане однопоточный: остальные окна тупо ждут, пока отпустит первое. Может, такое только на Маке, а на Винде проблем нет, спорить не буду.
Интересно вот что. Сегодня все браузеры работают по принципу “одна вкладка – один процесс”. Я смутно помню, что этого браузеры, в том числе Хром, часто вылетали с ошибками, потому что вкладки были на тредах. Сегодня это редкость, а лет 15 назад было в порядке вещей. Или браузер мог повиснуть на Ютубе или какой-то упоротой верстке, заморозив все табы. А теперь, когда вкладке плохо, мы этого даже не замечаем.
Было бы забавно проверить эту модель в современном вебе. Иногда на звонках люди шарят экран, и я вижу Хром с тремя десятками вкладок. Без преувеличения, не менее тридцати, потому что табики сжаты до размера иконки. Десятки табов Джиры, Конфлюэнса и прочей корпоративной жести. А каждая Джира – это, на минуточку, 50 мегабайтов скриптов и запросы на каждый клик. Мне кажется, если бы тридцать Джир крутились в одном процессе, интернета мы бы вообще не увидели.
И еще одна мысль, которую не знаю, куда приткнуть. Сервер PostgreSQL работает по принципу “одно соединение – один процесс”. Никаких тредов там нет и в помине, на каждое подключение делается форк главного процесса. Обмен данными происходит через shared memory – участок памяти, доступный всем процессам. Что-то вроде глобальной переменной, только в рамках процессов.
Вроде топорно, но оказывается удобным на практике, потому и дожило до наших дней.
-
Зачем пароль?
Вот что меня удивляет. Когда логинишься в любой сервис, ввода пароля уже недостаточно. Обязательно спросят код с телефона или почты. В какой-то степени я с этим согласен, потому что телефон – физическое устройство, им трудно завладеть, коды одноразовые, их сложнее перехватить.
Хорошо, но зачем тогда вообще пароль? Если мы не доверяем тому, кто ввел пароль, зачем он нужен? Вроде бы есть проверка, но она не точная как фильтр Блума.
Коды из смс и всякие токены из приложения – все это буквально кричит о кризисе системы паролей. И вместо того, чтобы закопать стюардессу и отменить пароли, продолжают их использовать.
Видимо, кто-то считает, что связка “пароль” + “код из смс” безопасней, чем оба по отдельности, но я в это не верю. Это примерно как вызвать хэш-фукцию десять раз вместо одного: доказано, что такой подход не приносит пользы.
Телефон уже давно умеет в биометрию и может авторизировать человека где угодно. Неужели лица и отпечатка пальца недостаточно, чтобы зайти в личный кабинет? С какой стати человек должен помнить пароли вроде “не менее 8 символов, не менее двух заглавных букв” и мусора вроде решеток и долларов? И так для двадцати разных сервисов?
Тем не менее, все бездумно лепят одну и ту же схему: пароль, которому никто не верит, и коды с телефона. Тут явно нужно что-то менять.
Самое смешное: сейчас вы повозмущаетесь в комментариях, а что потом? Пойдете пилить форму авторизации с паролем.
-
Перевод часов
Трудно поверить, но во многих странах до сих пор живодерский обычай переводить время на час и обратно. Даже находятся те, кто утверждает, что это полезно для экономики.
Напомню, что сто пятьдесят лет назад какой-то бюрократ посчитал, что если зажигать лампочку на час позже, это будет дешевле. О мелочах вроде сорванных встреч, опозданий и нарушений биоритмов никто не думал.
Поражаюсь, почему люди до сих пор живут с этим бредом? Было совсем другое время, другое общество, только что вступившее в индустриальную фазу. Сегодня другие приоритеты. Почему не пересмотреть вопрос, но на этот раз учесть все факторы, а не только “экономию” нескольких тысяч долларов на всю страну?
Согласен, что зимой нужно корректировать время, но делать это нужно по-другому.
Зимой человек устает больше и спит больше. Поднять и собрать детей в школу зимой – целый подвиг. А весной или ранней осенью, когда солнце уже показалось, вставать легче. Отсюда вывод: нужно двигать не циферблат целиком, а распорядок госучреждений. Например, начинать занятия в школах, садах и госконторах не в 8 утра, а в 9 или хотя бы в 8:30. То есть давать людям лишние 30 минут на сон.
Это честно, потому что затрагивает только тех, кому это нужно. На офисных работниках, у которых служба начинается в 10, это никак не отразится. У них не поедет календарь, не придется опаздывать. У стариков не нарушится прием лекарств. Что может быть лучше?
Пока писал, вспомнил свою жизнь в Чите. Я тогда работал в Энергосбыте, где служба начиналась в 8 утра, и за опозданиями следили строго. Пара опозданий – выговор, три и более – лишают премии. Только одна женщина из соседнего отдела могла приходить к 9 утра, но такую привилегию нужно было выслуживать годами.
Так вот, Чита, зима, поднимаешься в 6:30. За окном ночь. Завтрак, подъем ребенка, сбор в садик. Едем на санках по морозу -30. Машины нет, да и не каждая машина заведется, постояв ночь при такой температуре. После сада нужно сесть на маршрутку, а они все полные. Кое-как добраться до работы, чтобы пересечь турникет за две минуты до 8 утра. Зайти в кабинет и полчаса отогреваться и отпиваться чаем. Зато успел, премии не лишат.
Блин, зачем так жить? Зачем рвать задницу ради 8 часов утра? Зачем переводить часы глобально? Почему нельзя подвинуть распорядок тех контор, которые начинают рано? То, что в мире сейчас – это какой-то идиотизм от начала до конца.
-
Книги не устаревают
Удивляюсь, когда говорят: айтишные книги устаревают. Это не так.
Книги об алгоритмах, сетях или азах разработки не устаревают в силу своей базы. Нет такого, что каждый день придумывают новую сортировку или топологию дерева. Новый сетевой протокол выходит раз в несколько лет, а не дней. Поэтому здесь волноваться не о чем.
Если условный Rust меняется каждый день, и код из прошлогодней книги уже не работает, то это проблема технологии, а не книги. Пусть читатель либо подождет, пока язык стабилизируется, либо выберет что-то более надежное.
Читая книгу, человек не просто что-то узнает. Он насыщает индекс, обучает свою нейронную сеть. Даже если он сядет за новую версию технологии, сработает фактор знакомства: это я уже видел, тут на 70% как в книжке.
Читайте книги!
-
Телефонные боты
Замечаю еще один забавный паттерн. Звоню в разные фирмы, и как обычно, на входе голосовое меню. Чтобы узнать то, нажми 1, чтобы это, нажми 2 и так далее. Либо тыкаешь сразу 0, чтобы попасть на оператора, либо ждешь, пока меню отпустит и сработает фолбек.
Но когда скрипт переключает на оператора, включается ИИ-бот. “Я голосовой помощник Иннокентий, какой у вас вопрос?” Говоришь “дай оператора”, и начинаются расспросы: а по какому вопросу тебе нужен оператор? В точности пенсионер-вахтер.
К чему я это пишу. Ребята, которые внедряют голосовых ботов: не кажется ли вам странным оставлять голосовое меню из нулевых годов? У вас же вроде ИИ, который знает и умеет все на свете, и который скоро всех заменит. Но прежде чем попасть на бота, я должен кликать в голосовом меню? Как-то не сходится. Зачем боту такой костыль?
То, что голосовые помощники тупы как пробки, нет смысла говорить. Выделяют ключевые слова и читают то, что уже есть на сайте. Например, спросишь: на какой премиальный курс я могу рассчитывать, если сумма обмена больше N тысяч евро? И он диктует текущий курс или расписание отделений.
Беда.
-
Postgres как поисковый движок
Накину ссылку, которая очень мне помогла:
Речь о том, как делать гибридный поиск в Посгресе. Это когда документы ищутся по разным критериям, ранжируются, а потом объединяются в финальный набор. Как раз то, над чем я работаю в текущем проекте.
Статья полезна вот чем: до нее я не понимал, как объединять выборки с удалением дублей. Бывает, один и тот же документ оказывается в разных выборках, и нужно оставить ту, у которой больше ранг. Пытался сделать это при помощи
UNION, но из-за ранга дубликаты не удалялись. Чистить их вторым проходом тяжело, усложняется план.Так вот: автор предлагает объединение выборок при помощи full outer join и coalesce среди айдишек прошлых результатов. Звучит непонятно, но если разобраться, то получается как в примере ниже.
Для сравнения, вот первый запрос, который выбирает документы по условиям и сортирует по выражению с рангом:
SELECT aggregate FROM some_aggregates WHERE NOT ((aggregate #>> ARRAY['state']) = ':deleted') AND (((aggregate #>> ARRAY['attrs', 'code']) = 'hello') OR (aggregate @@ '$.attrs."code-name" == "hello"') OR ((aggregate #>> ARRAY['attrs', 'code']) ILIKE '%hello%') OR ((aggregate #>> ARRAY['attrs', 'code-name']) ILIKE '%hello%')) ORDER BY CASE WHEN (aggregate #>> ARRAY['attrs', 'code']) = 'hello' THEN 0 WHEN aggregate @@ '$.attrs."code-name" == "hello"' THEN 1 WHEN (aggregate #>> ARRAY['attrs', 'code']) ILIKE '%hello%' THEN 2 WHEN (aggregate #>> ARRAY['attrs', 'code-name']) ILIKE '%hello%' THEN 3 ELSE 999 END ASC LIMIT 51 OFFSET 0На таблице с 1.5 миллионами записей метрики такие: execution=450ms, cost=90000, что довольно много.
А вот то же самое, но с подходом, который предлагает автор:
with sub1 as ( select id, 0 as rank from some_aggregates where NOT ((aggregate #>> ARRAY['state']) = ':deleted') and ((aggregate #>> ARRAY['attrs', 'code']) = 'hello') limit 51 ), sub2 as ( select id, 1 as rank from some_aggregates where NOT ((aggregate #>> ARRAY['state']) = ':deleted') and (aggregate @@ '$.attrs."code-name" == "hello"') limit 51 ), sub3 as ( select id, 2 as rank from some_aggregates where NOT ((aggregate #>> ARRAY['state']) = ':deleted') and ((aggregate #>> ARRAY['attrs', 'code']) ILIKE '%hello%') limit 51 ), sub4 as ( select id, 3 as rank from some_aggregates where NOT ((aggregate #>> ARRAY['state']) = ':deleted') and ((aggregate #>> ARRAY['attrs', 'code-name']) ILIKE '%hello%') limit 51 ) select aggs.id, aggs.aggregate #>> ARRAY['attrs', 'code'], aggs.aggregate #>> ARRAY['attrs', 'code-name'], sub1.rank, sub2.rank, sub3.rank, sub4.rank, aggs.aggregate from sub1 full outer join sub2 on coalesce(sub1.id) = sub2.id full outer join sub3 on coalesce(sub1.id, sub2.id) = sub3.id full outer join sub4 on coalesce(sub1.id, sub2.id, sub3.id) = sub4.id join some_aggregates aggs on coalesce(sub1.id, sub2.id, sub3.id, sub4.id) = aggs.id order by sub1.rank, sub2.rank, sub3.rank, sub3.rank asc limit 51Хоть он и выглядит длинно, содержит CTE и джоины, но метрики такие: execution=7ms, cost=15000. Гораздо быстрее первого варианта.
Мораль в том, что короткий запрос не всегда значит быстрый. С помощью правильного джоина можно отсечь огромную часть выборки, сведя ее нескольким записям.
Статья на Хабре – перевод вот этого блога: https://anyblockers.com/posts/postgres-as-a-search-engine
В свою очередь, автор взял идею из блога Supabase: https://supabase.com/docs/guides/ai/hybrid-search
Тем, кто ковыряеся с Посгресом, будет очень полезно изучить ссылки.
-
Настоящий гей
Встречаюсь с приятелем, и он рассказывает: водил жену в ресторан, и знаешь, какой официант нас обслуживал? Настоящий гей! Или знакомый врач говорит: представляешь, вчера на приеме был настоящий гомик! Разумеется, они используют более резкие термины, но я не привожу, чтобы никого не обидеть.
В такие моменты я оживляюсь и спрашиваю: как ты определил, что это гей? Он оставил записку с предложением встретиться? Он погладил тебя за руку? Шлепнул по заднице? Пристал в гардеробе?
Все оказывается банально: этот “гей” был вычурно одет, пользовался косметикой, говорил с другой интонацией. И все? “Божечки, а разговоров-то было…” (с)
В городской среде сексуальная ориентация и внешность никак не связаны. Можно спать с мужчинами и носить обычную одежду. Можно носить ошейник и кожаные штаны, но не иметь связей в принципе.
В случае с официантом причин может быть много. Когда у человека совсем плохо с женщинами, он может притворяться геем, особенно если работает в женском коллективе. Это старый прием, потому что к геям девушки относятся по-другому.
Человеку может нравиться ролевая модель гея. Он изображает того, кто не вписывается в рамки. Ему нравится эпатировать публику, ловить взгляды. Провоцировать других и писать гневные посты в VK: а сегодня одно быдло сказало мне… Отсюда прилизанные лаком волосы, мушка на щеке, брошь размером с кулак.
Не вижу разницы с неформалами, готами и другими ребятами. Везде, если копнуть, сидит желание выделиться или уход от своих проблем.
Отучайтесь делать выводы об ориентации по внешности. Иначе вы не лучше деревенского гопника, который выучил, в каком ухе должна быть серьга, в какую сторону приглаживать челку, и какой фасон джинсов “правильный”. Мир как бы сложнее этих правил.
-
Палец в Фоллауте

В детстве я увлекался Фоллаутом. Разумеется, двумя первыми играми с видом сверху. Месяцами бродил по пустыням, выполнял квесты, а то и вовсе вырезал город за городом. Тогда мне казалось это интересным.
Не хочу наговаривать на последующие части, но Фоллауты с видом от первого лица – это не мое. Абсолютно не понимаю их. По мне это как Doom в виде карточной игры.
Так вот, с опозданием в 25 лет я выяснил забавный факт. Помните Пип-боя, маскота игры? Прикладываю картинку. Почему он вытянул руку, поднял палец и прищурился? Это не просто так, здесь умысел.
Дело вот в чем. Предположим, на горизонте образовался ядерный гриб. Как проверить, безопасно ли расстояние до него? Нужно вытянуть руку и навести большой палец на гриб. Если палец полностью закрывает его, значит расстояние безопасно, и можно идти по своим делам. Если же гриб вылезает, нужно что-то предпринять.
Оказалось, все это время Пип-бой вымерял пальцем ядерный гриб, а я не знал. Он че!
-
Наклейки на ноутах
В корпоративной почте пришло сообщение. Я с ним солидарен и поэтому перескажу здесь.
Если коротко: когда фирма выдает ноут, ваша обязанность вернуть его в том же виде, в каком он был. Ясное дело, годы берут свое, но по крайней мере не должно быть следов явной порчи. Вряд ли следующему человеку захочется работать за таким ноутом. Вряд ли вам захочется быть тем, кто получит такой ноут.
Особенно это касается наклеек. Иные ребята клеят на крышку с десяток стикеров и возвращают в таком виде. Под ними остаются пятна, которые уже никогда не сойдут. К письму было приложено несколько фоток. Скажу честно, при их виде у меня заныло сердце.
Картину можно описать так: ё…ый стыд. Нашлись люди, которые налепили, казалось бы, логотипы всех конференций и технологий. Node.js, Кубер-Докер, какая-то конфа по Джаве… живого места не оставили. А когда наклейки убрали, ноут выглядит как шкура далматинца – вся в пятнах. Их уже не оттереть, это навсегда.
Что творилось в голове у этого человека, я не знаю. Даже когда ноут свой, я с сомнением смотрю на обилие наклеек. Блин, ты что, редко видишь свой Кубернетис? Наверняка же он у тебя с экрана не сходит, так еще и на ноут лепить? А клеить на чужой ноут – это за гранью добра и зла. Я даже подумать не мог, что об этом нужно писать в рассылке – но оказывается, очень даже нужно. Есть те, кто этого не понимают.
Пожалуйста, не делайте так. Берегите чужую технику.
-
Именованные операторы
Считаю, что операторам, отличным от
+,-,*и/, нужно давать трехсимвольные имена, а не лепить закорючки. Например:pow– возведение в степень;div– целая часть деления;mod– остаток деленияxor– исключающее побитовое OR,log,ln– десятичный и натуральный логорифмы.
Да, будет на пару символов больше, но блин… как же достало переключаться на условный питон и разбирать, что значит двойная звездочка, крышка, двойной слэш, что там еще…
А, вот: ну-ка, не заглядывая в Гугл, скажите, что значит палка-минус?
c = a |- bСчастливой отладки (с)!
Пользуясь случаем, напомню про один скобочный язык, где сделали правильно:
(or a b) (not a) (and a b) (mod 10 3) (quot 10 3) (bit-and 10 20) (bit-xor 10 2)и так далее. Вот оно: нет операторов, только формы, а значит, достаточно дать первому элементу нормальное имя.
UPD
В Телеграме справедливо упрекнули синтаксис макросов:
#', #_, #?, #:, #::, #=, #^, ##Inf, %&, #?@, ~@, >!!, <!!, >!, <!?Да, все это кложурный синтаксис. Есть над чем поработать.