• Перекладывание

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

    Прилетает вам джейсон из сети. Надо его прочитать, провалидировать, распарсить даты, подрезать лишнее. Потом выгрести из базы то, из кэша се, из S3 третье и все это собрать в нечто нужное бизнесу. Сделать эксельку, положить в S3 и отписать в очередь.

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

    Иные джейсоны пятиэтажной вложенности. Нужно рыскать по их кишкам и строить обратные мапы (индексы). Потом передавать по пять индексов в другие функции.

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

    В идеале покрыть все случаи тестами, желательно с Докером, чтобы были настоящие база, Редис, S3 и так далее.

    Все еще легко, на ваш взгляд? Не знаю, мне кажется трудным. Поэтому над “перекладыванием” я не смеюсь.

  • Excel и CSV

    Маленькая техническая заметка. Не пользуйтесь CSV в надежде, что он откроется в Экселе. Если ваши потребители – люди с Экселем (а таких большинство), нужно генерить .xlsx, а не .csv.

    Дело в том, что Эксель писали в Микрософте. Может быть, сегодняшний MS уже обрел какую-то человечность. Но Эксель отсчитывает возраст с 1985 года – прямо как я – и старше многих читателей этой заметки. Поэтому ни о какой человечности говорить не приходится.

    Эксель никогда не откроет CSV без ошибок. Он обязательно промажет с разделителем: если в файле запятая, он ищет точку с запятой и наоборот. Для обхода придумали грубый костыль: в первой строке может быть выражение sep=, и тогда Эксель возьмет запятую. Но этот заголовок ломает парсеры CSV, которые ни о каком Экселе не слышали.

    Разделитель по умолчанию может зависеть от локали. У француза откроется, а у австрийца не откроется.

    Эксель по-прежнему игнорирует UTF8. Немецкие умляуты становятся кракозябрами. Махинации с меткой BOM ни к чему не приводят.

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

    В общем, нужно напрячь булки и выкинуть CSV, и вместо этого генерить нормальный Эксель.

    Если вдруг у вас Джава или Кложа, берите fastexcel и fastexcel-reader – они быстрее и компилируются Граалем. Все, что основано на Apache POI, тормозное и не компилируется Граалем. Я эту дорогу прошел и вот делюсь с вами.

  • Мои объявления

    Авито, страница “Мои объявления” — разве это не забавно? На экране все что угодно, кроме моих объявлений. Огромная плашка, громадные пустоты. Слоеный дизайн, когда каждый слой, пусть даже занимает сантиметр в ширину, растекается на весь экран.

    Очередной калека-дизайнер, которому “не хватило места”. Важная часть уехала на экран ниже — потому что первый экран занял всякий шлак.

    Считаю, таких дизайнеров надо даже не учить, а лечить. Обучение бессильно, пусть действуют профильные специалисты.

  • Загрузка в Амазоне

    У веб-панели S3 есть особенность: если скачать оттуда файл, Амазон поправит расширение в зависимости от Content-Type, который назначили файлу при создании. Например, если у файла нет расширения, а Content-Type равен application/json, то Амазон допишет в конец .json, чтобы файлик открылся.

    Казалось бы, хорошо? А вот что имеем на практике.

    Если залить файл hello.json.gzip, внутри которого сжатый Gzip-ом JSON, и указать заголовки Content-Type: application/json, Content-Encoding: gzip, то при загрузке произойдет следующее.

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

    После раскодировки Амазон смотрит: что там внутри? Application/json? Значит удалим .gzip и добавим .json. В результате получается файл hello.json.json. Я не шучу, проверьте сами.

    Второй случай: я залил в Амазон файл report.xlsx, но указал не тот Content-Type. Указал старый application/vnd.ms-excel для xls документов, а надо было такую колбасу: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet. При загрузке Амазон молча исправил расширение с .xlsx на .xls. А Эксель тоже хорош: по клику на файл он пишет, что формат битый, ничего не знаю – нет бы первые 100 байтов проверить, тупица.

    На ровном месте Амазон заруинил файл, хотя никто об этом не просил.

    Понимаете, не нужно мне помогать! Не нужно что-то тайно переименовывать для моей же пользы. Если прям чешется в одном месте – спроси, и я нажму “больше не спрашивать”.

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

    Верю, что когда-нибудь в Амазоне это поймут.

  • Время в Interstellar

    Вы же смотрели Интерстеллар? Помните высадку на планету с волной? А музыку в фоне, такую тревожную, помните? Тик-так, тик-так по нарастающей?

    Этот тик-так — неспроста. Каждый тик равен 1.37 секунды, и за это время на Земле проходят сутки. Именно такое соотношение времени между Землей и той планетой из-за близости к черной дыре. Ганс Циммер гений.

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

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

    Нечто похожее встретилось в дневниках Корнея Чуковского времен блокады Ленинграда: “дни сгорают как бумажные”. Потому он и великий писатель, что не уходят, не летят, а именно сгорают.

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

  • Список через запятую

    Одна из самых дурацких вещей в айти – это список через запятую, например:

    (1, 2, 3)
    ["test", "foo", "hello"]
    [{:id 1}, {:id 2}, {:id 3}]
    

    Каждый, кто работал с таким форматом, знает, какой геморрой учитывать запятые. Элементы нельзя просто записать в цикле. Нужно собрать их в массив, а потом join-ить запятой. Это сводит на нет стриминг элементов, когда их много. А чтобы работал стриминг, нужно завести флажок “запятая уже была”, выставить его в первый раз и постоянно проверять: была или не была?

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

    Какие проблемы возникнут, если запятые убрать?

    (1 2 3)
    ["test" "foo" "hello"]
    [{:id 1} {:id 2} {:id 3}]
    

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

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

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

  • Выпадашка в Хроме

    На скриншоте — типичная ситуация наших дней. По клику на аватару появляется выпадашка, но содержимое не вмещается, и у выпадашки появляется прокрутка.

    Окно браузера растянуто максимально, ничего не сжато. Зум нулевой. Никаких вредоносных действий с моей стороны. Просто дизайнеру “не хватило” места. Еще бы: если обернуть каждый элемент в паддинг, скруглить углы, добавить отступы где только можно, поместить всю фигуру в другой паддинг, сместить вниз — откуда ж возьмется место?

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

    Раньше можно было понять: разрешение 800 на 600, кривой IE6, умирающий Netscape, ранние оперы и фейерфоксы. У каждого багов — как блох на жучке. Но сегодня-то что? Везде ретины, 4К, только Хром и его поделки. Что мешает делать нормально: без выпадашек с прокрутками?

    Какая-то загадка.

  • Датомик

    Лет семь назад я увлекся Датомиком. Кто не знает, это база данных, написанная на Сlojure и Java. Среди ее плюсов – неизменяемость (данные только накапливаются), независимость от времени (можно вернуться в прошлое) и выразительный язык запросов Datalog, взятый из Пролога.

    Я долго ходил вокруг да около, а потом повезло: семья уехала на неделю, и я провел это время, читая доки и экспериментируя. У меня тогда был пет-проект на Postgres, и я перевел его на Датомик. Позже я использовал его в других проектах, в том числе в Хайлоад-капах от Mail.ru. Я написал статью про миграцию с Постгреса на Датомик, и она даже попала на главную Хакер-Ньюз.

    У Датомика есть важное свойство: он красивый. Бросил взгляд, и сразу мысль – да, круто. Это изящная абстракция, воздвигнутая на элементарных вещах. Мало проектов, где эти свойства – изящность и простота – выражены столь же ярко.

    Я много играл с Датомиком и даже пытался реализовать его поверх реляционных баз. Кое-что мне удалось, но поделки я так и не довел до ума. Практика показала, что скучные Postgres/Maria удобней в работе.

    Прежде всего, неизменяемость из коробки не нужна. Там, где нужно хранить историю, Postgres/Maria справляются за счет триггеров или запросов вида INSERT ... FROM UPDATE/INSERT/DELETE. Когда говорят об исторических данных, у меня сразу вопрос – как вы ими пользуетесь? Они вообще вам нужны?

    Далее: страшные буквы GDPR. Если пользователь хочет удалить свои данные, с Датомиком будут проблемы. В Датомике атрибуты не меняются, а добавляются новые с поздним временем. Поэтому, читая один и тот же атрибут в разное время, получим разные значения. Но GDPR требует, чтобы в базе физически не было личных данных. Если вы записали в базу атрибут (42, :user/name "XXXXXX"), то старый атрибут (42, :user/name "Ivan") остался, и прочитать его – дело техники.

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

    Можно отключить историю атрибутов, но тогда вопрос – зачем вообще история, которой так гордится Датомик?

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

    У Датомика никакой поиск, нет сортировки и пагинации. Как с этим жить – решать вам. Кого ни спрашивал – каждый пилит свои костыли, каждый случай – свое маленькое приключение.

    Есть еще кое-что: Датомик, при всей своей красоте, нарушает доменную область. Я как-то говорил о том, что главное свойство домена – его ортогональность другим доменам. Другими словами, у базы и кода на Сlojure разные зоны ответственности. Датомик стирает эту границу: он превращает базу в хранилище, к которой только он имеет доступ. Этому есть объяснение, поскольку физически данные хранятся как бинарные дампы с кусками индексов, и работать с ними умеет только Датомик.

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

    Это резко контрастирует с Postgres/Maria, которые предлагают свои языки и инструменты для работы с данными. Это и есть домен, когда я могу исправить данные, не обращаясь к Кложе. Бывает, я сижу в psql днями и неделями, манипулируя данными на чистом SQL.

    Датомик нарушает это правило. Да, у него есть веб-консоль, но по сравнению с psql она крайне уныла, а до программ уровня PGAdmin или DBeaver ей как до луны.

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

    Выбирая Датомик, имейте в виду вышесказанное.

  • Кража дизайна

    Иногда я слушаю дизайнера Женю Арутюнова, он говорит клевые вещи. Говорит мягко и с самоиронией. Не бывает так, что слушаешь тезис, а потом: кто не со мной, тот мудак.

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

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

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

    Именно поэтому когда случилась колоссальная утечка Яндекса — 50 гигабайтов исходников — я даже ухом не повел. Их обсасывали на всех новостных ресурсах, но скажите: что вы хотели там найти? Обычный корпоративный код: прочитать JSON, проверить его, положить в базу, дернуть очередь, записать в лог, собрать эксепшены в сборщик ошибок.

    По той же причине я скептичен к коду, написанному ИИ. Пусть он пишет тетрис и змейку, этого добра на Гитхабе пруд пруди. Как мне поможет ИИ, если нужно впендюрить очередной if цепочку бизнес-процессов, чтобы ничего не упало? Как он придумает новый твиттер? Как он придумает игру, где участники отрывают жопы от стула(!) и идут в парк ловить виртуальных зверей?

    Идея первична, лишь затем следует код.

    Вот почему, имея горы открытого кода, мы, словно герой Никулина, ищем “такой же, но с перламутровыми пуговицами”. Потому что требования. Потому что это наша работа.

  • Телефонный спам

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

    Иногда я слушаю, что скажет тот или иной “помощник”, чтобы быть в курсе технологий. Повторюсь, качество просто запредельное. Хорошо подобраны фоновый шум, интонация, неточности разговорной речи. Бот определяет, когда его пытаются перебить и вежливо просит дослушать до конца, а потом обсудить вопросы. Дерево сценариев огромно, продумано много случаев.

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

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

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

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

    С телефонным спамом борются и фирмы. Почти у всех операторов есть услуга “антиспам”, и она даже работает, я проверял. Тиньков разрывает звонок и шлет смс, что это спам. Но почему фирмы борются с фирмами при полном попустительстве закона?

    Напоминает современный веб: трекинг — блокировщики, еще больше трекинга — еще больше блокировщиков, а при открытии вкладки закипает мой ноут.

    Пожилые люди запуганы спамерами и мошенниками. Много раз наблюдал: у человека звонит телефон, неизвестный номер, он смотрит на цифры, пытаясь определить — спам или нет? Думает, местный или нет, боиться принять вызов… до чего довели!

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

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

    Объясните родственнику: если он сомневается в номере, пусть сбросит вызов и перезвонит через минуту. В лучшем случае он никуда не дозвонится, потому что у мошенников динамический пул номеров. Если это банк с кредитом, он услышит музыку и номер в очереди. Наконец, если это был обычный человек, он примет вызов.

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

Страница 2 из 79