nikitonsky_pub | Unsorted

Telegram-канал nikitonsky_pub - Стой под стрелой

10602

Ведет @nikitonsky. Рекламы нет

Subscribe to a channel

Стой под стрелой

Знакомлюсь потихоньку с фронтендом, узнал, что у нас используется библиотека Turbo. Как я это узнал? А очень просто. На запуске она печатает здоровый такой баннер, что у нее вышла новая версия и пора бы обновиться.

Офигеть, да? Какая-то сраная библиотечка считает себя насколько пупом земли, что позволяет себе а) занять десяток строчек в логе, б) сходить в интернет и проверить версию, хотя ее об этом никто не просил, и в) присесть мне на уши по поводу обновления, как будто у меня других дел нет.

Отдельно бесит, что вообще говоря в использовании более старых библиотек никаких проблем нет: меня все устраивает, все нужные функции есть и работают как мне надо, нафига мне обновляться? Чтобы что? Просто чтобы еще работы на пустом месте создать и еще чуть больше устать? Спасибо, услужили.

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

С ужасом жду момента, когда другие переймут эту практику и на старте в логе будет пяток-другой баннеров, в идеале с мигающими буквами, бегущей строкой и анимированной псевдографикой, которые будут просить обновиться, занести денег бездомным котятам, переименовать master в main и стать веганом. Даже библиотека для этого будет, shame.js. Как будто к этому все и идет.

Читать полностью…

Стой под стрелой

И вдогонку: коллективным разумом выяснили, что лампочка показывает уровень заряда кейса, если вытащить наушники, и «заряжаются ли наушники», если они в нем. ОДНА И ТА ЖЕ ЛАМПОЧКА. ОДНИМ И ТЕМ ЖЕ ЦВЕТОМ. ДВЕ ПРИНЦИПИАЛЬНО РАЗНЫЕ ВЕЩИ. К вопросу о модальности и как она легко может запутать даже взрослых умных людей.

Очень жаль, что Эплы решили не делать свою машину. Представляю, как у них внутри была бы лампочка, которая показывает уровень заряда батареи, если водительская дверь открыта, и «включены ли фары», если закрыта. Столько возможностей, ух

Читать полностью…

Стой под стрелой

Мало кто думает про долгосрочные психологические эффекты программ, а они есть.

Простой — надежность. AirDrop классный, когда он работает, но невозможный, когда нет. На его фоне Телеграм кажется истинным чудом — ни разу еще такого не было, чтобы ты положил файл на одном устройстве и он не появился через пару секунд на другом. Это ощущение надежности не купишь никакими интерфейсами, шрифтами, кнопками или анимациями. Что толку в Аирдропе, если в конечном итоге я не получу файл? Команде Телеграма удалось сделать лучший файлообменник, настолько хороший, что им можно пользоваться даже несмотря на другие ненужные функции вроде чатов. А нужна-то была — всего-навсего — надежность.

Со звонками наоборот: на телефоне Телеграм работает кое-как, а Вотсапп гораздо лучше. А вот на компе найти программу для созвонов, на которой вот чтобы совсем не было ебли, у меня пока не получилось. Причем тут речь не о 90% успеха, а именно о 99,999%. Чтобы пропал страх, нужно прям долгое и стабильное закрепление.

Или наушники — с блютусными ты знаешь, что в 10% случаев будет какая-то боль, у тебя прям в голове этот психологический барьер, когда их надеваешь — ух, щас или все хорошо будет, или я знатно поебусь. А с проводными или вайфайными такой проблемы просто нет, нет этого барьера.

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

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

Результат? «Учиться» пользоваться компьютером потеряло смысл. А не могу показать маме, где кнопка «выбрать аудиоустройство», потому что она сегодня тут, а завтра — там, и выглядит по-другому. В компьютере сегодня нужно учиться ориентироваться на незнакомой местности.

Читать полностью…

Стой под стрелой

Я уже писал, что главный принцип хорошего кода — названия переменных из одного слова. И вот вчера тырил код (опен-сорсный, релакс) и там у чела синдром второго слова во все щели, просто невозможно. И, главное, все без проблем переименовывается и читается в сто раз лучше:


curChar - ch
bufChar - ch
idata - i или data
startpos - start или pos
cbBuffer - cb или buffer
nElems - n или len или cnt
retval - ret или res
strdata - str, блин!
keyVal - key
valVal - val
mapObj - map или m
aryObj - res или acc (ну там по смыслу)
objReader - reader


Не надо так.

Читать полностью…

Стой под стрелой

Самая смешная фигня на свете — инструкции, как подбирать «сочетающиеся» цвета на цветовом круге.

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

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

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

Так рецепты и размножаются.

Читать полностью…

Стой под стрелой

Я, кстати, потеплел к ChatGPT и начал пользоваться. Главное, что я понял — не задавать ей сложные вопросы, а задавать простые. «Сколько хранится открытый йогурт», «какие есть варианты поставить Стим на Маке», «как избавиться от трупа», «как работает VAT», «куда вставлять лицензию от библиотеки, код которой используешь», «как сконвертировать mp4 в gif».

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

Действительно, в поисковике это заняло бы больше времени, пришлось бы почитать много плохого SEO-оптимизированного текста, причем текста, который не на мои вопросы отвечает, а вообще.

А так — получил свой ответ и пошел.

Что насчет кода? Ну код это пока сложный вопрос :) По крайней мере у меня. Но заглушки неплохо генерит.

UPD: А, еще она ошибки в тексте хорошо исправляет. Потому что языковая модель же

Читать полностью…

Стой под стрелой

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

А теперь представим, что кнопки вообще нет. Как нет? А вот так вот. Появляется по ховеру. Эпл такое любит: когда приложение хочет показывать нотификации, об этом появляется нотификация: “App name” Notifications: Notifications may include alerts, sounds and icon badges. Ты читаешь и думаешь: что сказать-то хотели? Какой-то незаконченный текст.

А это все потому, что это не просто сообщение на самом деле. Это скрытый вопрос! На самом деле там есть _выпадайка_, в которой две опции: Allow и Don’t allow, просто ее не видно. Буквально, кнопка есть, по смыслу нужна, но она просто графически нигде не нарисована. Появляется чисто по ховеру. Даже места под нее нет, чтобы об ее существовании можно было догадаться: она прям поверх текста этого появляется, когда наводишь мышку.

Ну и вот. Получается, площадь кнопки какая? Ноль. Подставляем в закон Фиттса, получаем деление на ноль, т.е. время нажатия улетает в бесконечность. И отсюда выводится уже мой закон: пользователь не может нажать на кнопку, если он не видит ее.

Казалось бы, какой банальный закон, тривиальщина. Однако нарушается каждый день, и не только Эплом. А вы говорите гуманитарная дисциплина. Умели бы цифры в формулу подставлять, так авось и проблем бы таких не было!

Читать полностью…

Стой под стрелой

Анекдот. Программистам будет больно, сразу предупреждаю.

Яша с утра спросил у супруги, почему она отрезает кончики сосисок, когда готовит их. «Не знаю, меня мама так научила, спроси у неё», — отвечает супруга. Яша оказался любопытным и пошёл к тёще. Он спросил: «Мама, почему действительно вы всё время кончики у сосисок отрезаете, когда варите?»

Она говорит: «Я не знаю, меня мама так научила. Если тебе интересно, позвони ей». Ну Яша такой любопытный, пошёл звонить. Звонит, говорит: «Ида Самуиловна, это Яша, ваша внучка (моя жена) и ваша дочь (моя тёща) всё время, когда варят сосиски, отрезают кончики и говорят, что это вы их научили. В чём смысл?»

«Вы что, до сих пор варите сосиски в той моей самой маленькой кастрюлечке?»

Читать полностью…

Стой под стрелой

Проклятие современного мира — логины.

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

Доходит до абсурдного: логины теперь есть в браузерах, редакторах кода, терминалах, драйверах видеокарты, мышке, телевизоре, посудомойке. Недавно я обнаружил возможность логиниться в приложения MS Paint и «Часы» (да, блин, ЧАСЫ) на Винде. Ждем, когда аккаунты добавят в Блокнот и Выбор WiFi, а то как-то непривычно что ли.

При этом нормальные ребята как не играли в эту игру, так и не играют. Лицензии вполне себе покупались и покупаются без аккаунтов, файлы и данные прекрасно синхронизируются тоже. Вот Syncthing, синкает файлы между произвольным количеством машин, через интернет, и ни одного ебучего аккаунта не надо нигде заводить. А что, так можно было? Оказывается, можно.

Реально не понимаю, мне ясны только минусы: во-первых, пользователи бесятся (хотя кого это когда-либо волновало). Во-вторых, тебе надо управлять базой емейлов и паролей, что как бы сложности и риски.

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

Ну или ладно, делаешь ты терминал на Расте, или там редактор кода на Расте, или драйвер для мышки. И требуешь заводить аккаунт. Окей. Завели. Дальше что? Как это конвертируется в прибыль? Где тут деньги? Какая мотивация лежит за всей этой модой? Что продается?

UPD: Как правильно замечают, «Ещё и на свою ебучую рожу смотреть в углу каждого ебучего приложения»

Читать полностью…

Стой под стрелой

Запускал вчера по воле случая Дискорд, и у них там плашка про Хэллоуин вылазит. И вот что подумал:

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

«Ой, смотрите, у нас новая фича!». «Ой, устанавливаю апдейты! 1/15» «Ой, мы обновили тему» «Ой, у нас новый интерфейс» «Ой, хуюлька переехала в пиздюльку» «Ой, вы давно не смотрели нотификации» «Ой, а релиз ноуты прочитали? Ну а вдруг нет. На всякий случай напоминаю»

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

А мне и представлять не надо. Сегодня все пытаются из программы сделать «продукт» и занять угол в вашей голове. Даже браузеры.

Читать полностью…

Стой под стрелой

Кстати, смеха ради, попробуйте найти JettyWebSocketServletContainerInitializer.java и понять, что он делает. Там сто строк кода, они все тщательно (больше половины строк — комменты) задокументированы, присутствует логгирование, проверки на null, лицензия.

НО ЧТО ОН, СУКА, ДЕЛАЕТ-ТО???

Единственное осмысленное, что я смог понять, это что ему могут передать штуку (тот самый configurator), он ее сохранит и потом вызовет (accept). Почему ее не может вызвать тот, кто ее создал, зачем для этого целых два класса (один вложенный) на 100 строк — загадка.

Читать полностью…

Стой под стрелой

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

И не то чтобы я их не подключал к питанию — за этот месяц они заряжались раз десять-пятнадцать. Просто не ночью.

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

Жаль что его нет, конечно.

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

Читать полностью…

Стой под стрелой

Забыл сразу написать, а это важно. Тут возникла дискуссия, что надо делать «фичи» (пагинацию, поиск, фильтры), а я не согласен.

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

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

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

Кажется, что без фич мы ограничили пользователя в возможностях, а на самом деле мы его освободили.

Читать полностью…

Стой под стрелой

Заглянул в Джиру (я знаю, я знаю) и увидел показательный пример. Там можно выбрать фильтр кнопкой More и выпадайкой с дополнительными фильтрами. Типа, те, которые на панель сразу не поместились.

Знаете, сколько там фильтров? 78. Знаете, сколько показывается за один раз? 10.

Да, 10. Де-сять. Десять.

Еще десять можно получить по кнопке More. И так далее.

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

НО. Не надо доводить ее до абсурда. С одной стороны, вы пихаете в браузер 43 мегабайта джаваскрипта (да, я проверил, не поленился). А с другой боитесь загрузить список из 78 элементов. Линейный список! Коротких строк по 10-15 символов.

Знаете, сколько занимает весь список, целиком, от начала и до конца? Из всех 78-и элементов? 100 килобайт! (это DOM, это плохо, но чего еще вы ожидали от Жиры?). ^W^W 1 килобайт. ОДИН! КИЛО! БАЙТ!

Это примерно (достает калькулятор) в 43000 раз меньше, чем джаваскрип, который вы только что не моргнув глазом загрузили. Сорок. Три. Тысячи. Раз. Три с половиной порядка! (UPD: четыре с половиной!)

Какой из этого вывод? Да, сделать 10 элементов кажется максимально естественным решением. Цифра красивая. Но в большинстве случаев это преступно мало. Я бы хотел, чтобы нормализовали 1000, но браузеры и так еле-еле шевелятся, поэтому давайте сойдемся на сотне.

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

Читать полностью…

Стой под стрелой

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

А на деле это обычно с потолка взятая цифра, которую за три секунды кто-то придумал. Типа, «нам надо обрабатывать 5000 запросов/секунду». Почему именно 5000? А если 10000 обработаем? А если 1000? Не то чтобы решения будут сильно разными, и не то чтобы кто-то специально будет программу замедлять. Команда напишет код to the best of its abilities, купят сервачок какой-нибудь, а там херакс — и 100,000 вместо 5000 получится. И чего? Обратно отдавать куда-то?

В обратную сторону тоже верно. Написали, получилось тысяча — что теперь, не запускаться? Запустятся все равно, один фиг столько пользователей на старте не будет. А потом посмотрят, сколько придет.

То же самое с reliability, и с дедлайнами, с временем отклика. Все будут стараться, но получится как получится, и запуск будет все равно.

А еще иногда кто-нибудь выходит и говорит гордо: we’ve met our requirements. Типа, выполнили требования. А ты смотришь и видишь — фигню какую-то сделали. Типа, сайт три секунды открывается. А он такой — так у нас и были требования чтобы три секунды.

Ну и нафига тогда требования?

Читать полностью…

Стой под стрелой

В любом нормальном языке можно работать с путями до файлов. Только иногда пути это просто строки (String), а иногда — специальные классы (File, Path и т.д.).

Так вот, сколько я на это смотрю, так и не понял преимуществ оборачивать пути в классы. Над строками работают все обычные операции со строками — склеить, поделить, интерполировать, сериализовать. А на «путях» — нет. Существование таких классов как правило только возни добавляет. Преимущество делать new Path(pathStr).exists() вместо Path.exists(pathStr) довольно сомнительное.

Может вы знаете? Объясните?

UPD: поменял File на Path чтобы было понятнее

Читать полностью…

Стой под стрелой

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

Ожидание: лампочка горит оранжевым, когда кейс пора заряжать. Ну, типа, как на ЛЮБОМ другом устройстве.

Реальность: лампочка горит оранжевым, если она заряжает наушники. То есть, по сути, всегда: если я складываю в кейс наушник, значит я им только что пользовался, а значит он чуть-чуть, но разряжен.

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

Как же тогда узнать, когда пора заряжать кейс? Очень просто, следите за руками:

Включаем телефон
Разблокируем телефон
Выходим в хоум скрин
Подносим кейс к телефону
Открываем кейс
Трогаем экран, чтобы телефон не успел заблокироваться
Ждем
Ждем
Открываем-закрываем кейс пару раз НА ВСЯКИЙ СЛУЧАЙ
Перемещаем его в пространстве вокруг телефона, трем об спинку, постукиваем, пытаемся приложить к чему-то чувствительному внтури
Сомневаемся в собственной адекватности
Ставим под сомнения каждый жизненный выбор, приведший нас к этой ситуации
О, окно с уровнем зарядки появилось!
Но это только если кейс не сдох совсем в ноль, тогда секунд через 30 ты догадаешься это проверить по лампочке (она не будет включаться совсем)

Никита, но есть же виджеты, показывающие уровень заряда? Есть. Но они показывают заряд в произвольный момент времени в прошлом И НИКАК ОБ ЭТОМ НЕ УВЕДОМЛЯЮТ. То есть 37% на виджете легко может означатт «в среду в семь утра на прошлой неделе уровень заряда был 37%». И никак об этом узнать нельзя.

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

Честное слово, как Ватсон не мог без трубки, так и пользователи Эпла не могут ПРОСТО взять и чем-то пользоваться. Эпловоды должны страдать.

Читать полностью…

Стой под стрелой

«Код должен читаться как книга». Ну что за бред. Конечно же нет.

Книга — это LinkedList. Единственный способ ее потребления — слово за слово, по порядку.

Код — это HashMap. Он читается с произвольного места, у него нет линейного развития, начала и конца.

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

Этот пост напоминает вам об опасности аналогий. Плохая аналогия отдалит вас от правды, а не приблизит. Прямо как котенок с пуговицей.

Читать полностью…

Стой под стрелой

Главное правило интерфейсов: если у вас нарисована скрепка и я на нее нажму, должен открыться диалог выбора файла. Не меню какое-то, а выбор файла.

А то некоторые любят там пофантазировать: какие-то «недавние» файлы предлагать, или дробокс с гугл драйвом, или еще как-то, или вообще не файлы тоже туда засунуть. Слак так делает, Телеграм так делает, Whatsapp, FastMail, Notion. Не надо так!

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

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

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

Читать полностью…

Стой под стрелой

Провел выходные за оптимизацией Java кода. Периодически слышу, как люди говорят «JVM может быть быстрой», и я в целом им верю, но какой ценой?

Например, смотрел доклад, и там чел говорит: ну вот, JVM любит когда ты код попроще пишешь, и не любит по-сложнее. Когда массивы-индексы-примитивные типы так вообще хорошо.

Проблема в том, что это не точные инструкции. Например, сходить в другой класс прочитать поле или даже вызвать несложный метод может быть бесплатно. А может и нет. Как узнать? Никак, пробовать. Вчера мой код начал работать в 10 раз медленее просто потому, что я какую-то переменную перенес из локальной в поле класса. В 10 раз! И только одну конкретную переменную. Пять других перенеслись прекрасно. ПОЧЕМУ?

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

Закончилось все тем, что я написал версию, которая работает за 50 микросекунд на ASCII файле, но если запустить ее на файле с не-ASCII символом, а потом снова на ASCII, то она начинает работать за 100 микросекунд. То есть еще раз, тот же вход, та же функция, просто начинает работать в два раза медленее если кто-то где-то однажды позвал ее на другом файле.

А потом выйдет новая версия и все опять начнет работать по-другому. Или не начнет. Потому что гарантий никаких нет, а внутри магия.

Читать полностью…

Стой под стрелой

Вчера случился передоз фронтендом, который я не понимаю, если честно, на каком-то фундаментальном уровне.

Во-первых, я обновил npm на какую-то минорную версию, и теперь при старте приложения вижу это:


(node:45421) ExperimentalWarning: CommonJS module /opt/homebrew/lib/node_modules/npm/node_modules/debug/src/node.js is loading ES Module /opt/homebrew/lib/node_modules/npm/node_modules/supports-color/index.js using require().
Support for loading ES Module in require() is an experimental feature and might change at any time
(Use node --trace-warnings ... to show where the warning was created)


Я знаю что у вас там много лет идет война за то, как один файл включить в другой. Казалось бы, тривиальная задача, плюс мы это делали 20 лет назад, когда HTML писали руками и по FTP загружали. УЖЕ ТОГДА все работало. Как можно было это сломать? Или — ладно — сломать-то что угодно можно, но как можно так долго такую тривиальщину мусолить? Один файл включить в другой файл. Ну там нет сложности, ну нет, даже если с фонарем поискать. Берешь и включешь.

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

Что такое node:45421 не знает даже гугл.

Второй случай произошел уже в Мастодоне. Пишет мне чел:

> На пайплайне билдится проект, каждый раз имена js/css обмазываются хешами типа main.45387.js (angular обычный). Все это закидывается в CDN, бекенда нет кроме CDN с раздачей этой статики. Нужно безопасно сетить CSP хедер без unsafe-\*. CDN о деплоях и хешах не знает, nonce'ы добавлять тоже не вариант. Как в современном мире принято "безопасно" грузить любе ресурсы со своего же домена без unsafe? 'self' и \*.домен не помогло.

И это все весело по тем же причинам: тривиальная задача (включить один файл в другой), какой-то адовый фарш из терминов и сложности, мое полное фундаментальное непонимание, КАК можно было ТАК сильно сломать такую простую вещь. Типа, блин, HTML загружает JS. С ТОГО ЖЕ ДОМЕНА. Почему это проблема? Как это проблема? Как можно было заблудиться в трех соснах? Как мы дошли до такой жизни? Зачем мне доказывать самому же себе, что я не верблюд?

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

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

Читать полностью…

Стой под стрелой

Есть странный тупняк в маке, который я никогда не пойму. Если ты выводишь звук куда-то, то иногда громкостью можно управлять, а иногда нет.

Если я правильно понимаю, идея была такая: подключил ты условно колонку, вот и регулируй звук на колонке, это «правильно». Где карту открывали...

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

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

Короче, экосистема. Как это назвать, кроме как нарочным вредительством, я не знаю. Если бы, буквально, _ничего_ не делали, было бы лучше.

Читать полностью…

Стой под стрелой

Один важный инсайт, который косвенно пришел ко мне из Кложе-мира, но в целом универсален: никому не нужны ваши программы. Всем нужны данные.

Грубо, никому не нужна программа-просмотрщик PDF. Зато всем нужна сама пэдээфка. И гугль-докс никому не нужен, нужны только тексты, которые в нем написаны. Уйдет гугль-докс — будут писать в ворде, уйдет ворд — придумают что-нибудь еще.

Звучит контринтуитивно — вроде мы так мучаемся, пишем эти самые программы, функции, UI какие-то придумываем, пользователей заставляем пользоваться. Условно, 90% усилий и 90% времени проходит в программах и за написанием программ.

И все же. Программы сами по себе никому не нужны. Они нужны как способ трансформации данных. Взять что-то на вход, обработать, поменять, выплюнуть что-то новое и все. После этого твоя программа снова никого не интересует. Может ее удалят, может забудут, может поменяют на конкурента, или может она сломается с обновлением. А может завтра снова запустят — ху ноуз?

Программы скоротечны — могут пожить год, ну пять, некоторые совсем исключительные дотягивают до тридцатника. А данные — вечны. Данные переносятся между компьютерами, операционными системами, поколениями.

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

Читать полностью…

Стой под стрелой

Делал тут на сайте гостевую книгу^W^W хранилище персональных данных. Ну так, в шутку. Там большая текстарея, над которой написано «Введите персональные данные» и кнопка «Сохранить». Ну и оно сохраняет. Потом обратно скачать можно. Причем все данные одним файлом, от всех участников, чтобы утечек не было. По-моему смешно.

Ну и вот. В порыве юмора добавил в этот файл апишники отметившихся. Типа, пишешь «Привет, я Вася», а оно сохраняет: «IP 3.14.159.265 написал: „Я Вася“»

И народ так занервничал!

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

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

Вот, давайте для примера я вам еще айпишников напишу:


247.172.180.151
79.156.53.78
43.213.57.243
61.207.97.37
130.126.244.221
200.163.13.46
77.132.32.188
217.178.6.33
89.187.33.214
215.112.6.97


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

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

Кстати, расскажите, что можно с айпишником сделать? Вот, например, мой (реально): 94.135.166.230. Что дальше? Чем я рискую?

Читать полностью…

Стой под стрелой

Редкий случай: в твиттере нашелся чел, который добровольно принял ответственность за невыровненные иконки в Икскоде. Они там буквально косо в квадратиках стоят. Цитирую:

> This is technically my fault. They are programmatically generated from SF Symbols and scaled dynamically [...] There’s something about the font rendering that meant that the CG Graphic or whatever it was, wasn’t seeing the pixels for what they were - I tried all sorts and couldn’t get it to work.

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

> The old icons were even worse and very dated. We had to ship. The person who would’ve been able to fix it was busy with more important things. Just the reality of every software development place.

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

На самом деле интересно было бы узнать, чем именно. Сколько там у Эпла инженеров, тысяч сто? А продуктов? Сто? Тысяча? Ну допустим тысяча. И что, сто инженеров недостаточно, чтобы посадить кого-нибудь выровнять иконки?

Это реально парадокс больших компаний, который я до сих пор никак не могу себе объяснить. Денег бесконечность, людей легион, все при деле, а получается так, хуже среднего. Почему?

А главное: представьте себе мир айти, где задача центрировать иконку решается три года и требует каких-то staff уровня людей. Один, блин, квадрат, внутри другого, блин, квадрата. Это то, что я называю «технологии победили программиста»

Читать полностью…

Стой под стрелой

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


org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer$Configurator


Да, прям так и написано, в одну строчку. 96 символов, между прочим. В перфокарту не влезет.

Но давайте смотреть. Все что до точки это пакет. org.eclipse.jetty, понятно, название библиотеки. Тут у меня уже начинает болеть голова, потому что почему нельзя просто jetty сделать? В смысле нельзя потому что в Джаве так не принято, а почему в Джаве так не принятно?

Мне кажется, люди в 2000-х, когда интернет только начинался, немножко боялись, что имен не хватит на всех и нужно их как-то «занимать». А вот если разделить весь пул имен на три под-пула (com, org, net) то тогда хватит.

Название организации eclipse тут присутствует по похожей причине, типа, а вдруг имена закончатся, а кому-то очень надо будет сделать проект, который тоже будет называться jetty, вот тогда он просто организацию поменяет и будет норм! (спойлер: будет все равно не норм)

Прошло 20 лет и выяснилось, что имен пока всем хватает, даже когда разобрали всех животных, все планеты и латинские слова. Npm вон как-то справляется.

Дальше идет websocket.server.config. Это, собственно, пакет. Точнее, подпакет. Тут у меня три вопроса.

Во-первых, ну ты уже застолбил org.eclipse.jetty, ну и положи туда все, что у тебя есть, что, жопа отвалится? То есть сама необходимость подпакетов.

Во-вторых, если ты делаешь подпакеты, делай их для себя, а пользователю ими голову не парь. В Джаве это, к сожалению, любят. Например, они запилили работу со временем в java.time. Вопросов ноль. Но и положи ты в этот пакет все, Якове, брате, зачем аРхИтЕкТуРу городить? Но нет, таймзоны у них в java.time.zone, форматтеры в java.time.format, остальное размазано равномерно-случайно между java.time.temporal, java.time.chrono и собственно java.time. Может в момент придумывания это и звучало как-то стройно и логично для какого-то одного конкретного случая, но на практике получается, что я всегда импортирую пару классов из одного, пару из другого и остаток из третьего. И чего? В чем, так сказать, глубокий смысл? У нас нет задачи выкопать яму, есть задача заебать солдата.

Ну и в-третьих, окей, у тебя офигеть сложный проект, прям миллион классов, и если вывалить их в один пакет, то файловой системе поплохеет (сомневаюсь, но давайте предположим). НУ СДЕЛАЙ ТЫ ДВА УРОВНЯ ТОГДА. Не городи эту бесконечную вложенность, как программисты любят. Вехний уровень и на нем несколько папок. ВСЕ. Больше ничего не нужно. Красиво. Плоско. Наглядно. В голове помещается. Есть ли в жизни что-то более идиотское, чем бегать туда-сюда по миллиону мелких папок (привет, `src/main/java/`), в каждой из которых по две-три других папки? Я не знаю.

Ура. С пакетами разобрались. Переходим к классу. JettyWebSocketServletContainerInitializer. Шесть существительных. Добрый вечер.

При этом, в чем смысл пакетов? Это неймспейсы, так? Чтобы классы с одинаковыми именами, например, Зарплата, не перепутались, один кладут в пакет лупа, а другой в пупа.

ТОГДА ЗАЧЕМ ЭТУ ВСЮ ИНФОРМАЦИЮ ПОВТОРЯТЬ В НАЗВАНИИ КЛАССА?

А, Джависты? Зачем? Зачем, а? Jetty. Было в пакете. Чего молчишь? А? WebSocket. Было. Заело, да?

Дальше. $ означает вложенный класс. То есть есть класс JettyWebSocketServletContainerInitializer, а у него внутри еще Configurator. Зачем? А никто не знает. Вроде бы пакеты и так выполняют функцию неймспейсов, но в данном случае неймспейсом может поработать класс.

На семантику я даже боюсь смотреть. Зачем нужен целый класс Initializer, почему нельзя просто проинициализировать что-то? Почему нельзя сказать obj.option = "abc". Ну или ладно, obj.initialize(options)? Зачем инициализатору нужен свой отдельный конфигуратор? Никто не знает. Джависты боятся простоты как огня.

Пишите, короче, на Кложе.

Читать полностью…

Стой под стрелой

Всем хороши UUID, вот только репрезентация подкачала. Ну посмотрите:


798bf160-5eda-4aa2-a741-bbfc48ac9f8f


Что это? 36 букв? Дефисики? Чтобы что? По телефону диктовать удобно было? Отдельно меня убивает группировка: 8-4-4-4-12. Кто это придумывал?

(на википедии пишут, что раньше вообще было 34dc23469000.0d.00.00.7c.5f.00.00.00 и urn:oid:2.25.113059749145936325402354257176981405696, так что мы еще легко отделались)

Смотрел я на это, смотрел, и решил, что надо сжимать.

Первая мысль — base64. Это кодировка основана на простой идее: кодировать бинарные данные максимально «безопасными» символами, которые пролезут везде.

Что такое безопасные символы, спросит читатель? Так вышло, что из 256 символов стандартного ASCII половина (128) может попердолить если ошибиться с кодировкой, парочка трансформируется непредсказуемо, если открывать файл в текстовом режиме на разных системах, и еще 32 творят всякую дичь и скорее всего никак не отображаются на экране, что оставляет нам примерно 94 символа, которые отобразятся более-менее одинаково всегда.

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

Теперь следите за руками. В английском 26 маленьких букв. Еще столько же больших. Итого 52. Добавляем 10 цифр, получается 62. ПОЧТИ дотянули до круглого 64.

А дальше начинается разброд. Поскольку идея такая простая, возникло буквально миллион версий base64, которые отличаются только тем, какие последние два символа выбраны.

Если зайти на википедию, можно увидеть, что большинство стандартов, которые прям стандарты-стандарты, берут + и /. Плюс еще куда ни шло, но вот / нам решительно не подходит – он явно будет плохо парситься внутри урлов и файловых путей, а пихать uuid в урлы и файловые пути — это святое.

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

Вот, если что, полный спискок:


! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ ` { | } ~


Если бы я делал, я бы наверное выбрал - — во-первых, потому что он уже в UUID используется, то есть мы ничего не теряем, а во-вторых он прикольно поддерживает тему заглавных/строчных в паре с _.

Но так ли уж нам нужно именно 64 буквы? Есть более радикальная идея: а что если взять всего 62?

На самом деле, если использовать 64, то нам понадобится ⌈128 / log₂64⌉ = 22`символа. А если брать 62, то `⌈128 / log₂62⌉ = 22 все равно!

Да, математика не такая красивая, по 6 бит удобнее откусывать, чем делить на 62 с остатком. Но! Мне кажется, если вы парсите UUID любым способом, кроме прямого memcpy 16 байт, вы уже проиграли игру в оптимизацию, и 22 лишних деления вам погоду не сделают. Зато универсальность!

В итоге UUID будут выглядеть как-то так:


ibIP7XtbjSUXesMuVW63JA


Сравните с тем, что было:


798bf160-5eda-4aa2-a741-bbfc48ac9f8f


Ну кайф же! А трафика, трафика сколько сэкономится! Единственная проблема, впрочем, что они потеряли свой легко узнаваемый вид.

Если играть совсем жестко, то можно все 94 доступных символа заиспользовать. Но тогда идентификатор сократится всего на 2 символа, а выглядеть они станут так:


;n'^}VR!5VIxlUl$\Q37


ИМХО, не стоит того.

А вот что можно провернуть, так это эмоджи! Вроде, если взять все односимвольные эмоджи без модификаторов, можно наскрести 1361 штук. Этого хватит на то, чтобы сократить 128-битные uuid до 13 символов. Можно даже только 1024 использовать, все равно 13 будет, плюс математика попроще.

Выглядеть будет так:


🩸💞🆑🪕🏪🤒🌡🥔🦐🪪🍑🕧🧋


С узнаваемостью проблем нет, а вот с эффективностью... Каждый эмоджи занимает 4 байта в UTF-8, т.е. мы получаем 13 * 4 = 52 байта, что больше даже 36-ти у текущего UUID.

Зато как красиво!

Читать полностью…

Стой под стрелой

Кстати я же вам не рассказывал про сайтик. Я задолбался искать сеансы в кино и сделал сайт Alle Kinos (все кинотеатры Германии, типа).

У обычных сайтов кинотеатров очень нерегулярный интерфейс. Они не могут просто все что есть показать единообразно, они как сайты Бюро — тут обложечка, тут выезжалочка, тут пять новинок, тут трейлер, тут новость, тут интервью с режиссером, тут специальный этаж, и каждый как уникальная снежинка, не похож на соседей. Как будто люди на сайт кинотеатра ходят новости почитать. А, ну и обложки на пол-экрана, так чтобы ты максимум мог три фильма увидеть за раз, даже если в самом кино показывают 25.

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

Ну вот, а я сделал регулярный интерфейс. Все стандартно, одинаково и без выебонов. Чистая функция. Выбираешь город, тебе вываливается ОДНА страница со всеми фильмами, всеми кинотеатрами и сеансами на неделю. Для Берлина это примерно 2 Мб (235 Кб с компрессией), и ничего, никто не умер. Работает побыстрее большинства сайтов, сделанных «настоящими» программистами.

Это еще был эксперимент сделать сайт «без интерфейса». Там нет джаваскрипта совсем, вот ни байтика. Нужно поискать что-то? Ну так в браузере есть поиск. Посмотреть все? Скроль. Перейти по ссылке? Это вообще нативная веб-функциональность. Sticky headers и ленивая подгрузка картинок тоже уже делаются встроенными средствами. Джаваскрипт не нужен! Да, так было можно.

И, главное, никакой пагинации.

Читать полностью…

Стой под стрелой

В Твиттере Тагир показывал, как они научили Идею генерировать javadoc комментарии к методам. И все бы ничего, если бы не пример: на метод


public static <T> @Nullable T getLastElement(T @Nullable [] array) {


оно сгенерировало


/**
* Returns the last element of the provided array.
*
* @param array the array from which the last element is requested. It can be null.
* @return the last element of the array, or null if the array is null or empty.
*/


Когда уже разработчики поймут, что такие вот ничего не добавляющие тавтологические комментарии — вред, а не польза. Все, буквально все, что написано в комментарии, есть тупо в сигнатуре метода, причем в три раза короче. То есть вы только что заставили меня прочитать в три раза больше текста, чтобы не узнать ничего нового. ЗАЧЕМ? Вам что, за буквы платят?

Неудивительно, что в дефолтной теме в Идее комментарии рисуются сереньким. Типа, они конечно есть, но мы все в глубине души понимаем, что там булшит и никто его читать не будет.

Понимают — но делают и продолжают делать.

Читать полностью…

Стой под стрелой

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

А тут недавно купил мини на 8Гб и все-таки заглянул в таб с памятью. Очень, знаете ли, удивился.

Ну, для начала, я браузер с телеграмом никогда за программы вообще не считал. Типа, они не должны есть ресурсов от слова совсем, настолько у них простая задача. А тут оказалось, что Файрфокс с тремя табами это уже полтора гига! Телега еще 600-800. Неплохо, да? И это нативная, без электрона.

Второй сюрприз ждал меня в самом макосе. Ебучие живые обои жрут 2 гига просто так, всегда, низачем. Даже когда они не живые!!! Я их, конечно, выключил, но осадочек остался.

Ну и остальное набегает по мелочи. То есть еще раз, браузер с тремя (тремя!!!) вуладками и телеграм, и уже скушано 11 гигабайт. И это я еще работу даже не открывал. А вы еще спрашиваете, почему я слак в браузере предпочитаю.

Короче, произошел реалити чек. Оказывается, просто чтобы листать вебчик надо уже минимум шестнашку, а для работы, получается, 32 минимум. Тудей я лёрнд.

Читать полностью…
Subscribe to a channel