Читать в телеге. Когда-то там были посты не только от меня.
Отличие SQL Merge от Upsert
Облако напомнило, что пора бы обновить Postgres, потому что используемая версия (14) невероятно устарела. Я осознал, что мои знания о функциональности в новых версиях остановились где-то в районе 10 версии (работает и ладно же), а сейчас уже скоро будет 18, решил почитать, что нового там появилось.
Среди кучи улучшений производительность и новых фич, которые я вряд ли использую, с удивлением обнаружил, что в 15 версии добавили MERGE
. Оказывается, эта команда так вообще часть стандарта SQL, причем достаточно старого, 2003. При этом проблема upsert в Postgres издревле решалась через INSERT ... ON CONFLICT ...
.
Нюанс в том, что MERGE
решает немного другие проблемы, чем upsert. MERGE
лучше предназначен для пакетных операций, и при параллельных транзакциях все равно может быть проблема, ON CONFLICT
надежнее в этом плане, поскольку он атомарный.
Вроде полезно релиз-ноты читать, но у устоявшихся технологий мало что революционного происходит.
А еще SQL стандарт развивается. Теперь там еще и JSON есть, в 2023.
Pattern guards в Kotlin
В Kotlin 2.1 завезли pattern guards. Джва года (9) ждали, как говорится: после Scala очень не хватало их. Так скоро и до деструктуризации/экстракторов доживем :)
Исследование про продуктивность разработчиков с ИИ
В каждом утюге сейчас эта статья. Почти везде ее кратко описывают как “ИИ агенты вредят продуктивности разработчиков”. При этом в самой статье довольно четко пишут
We do not provide evidence that … AI systems do not currently speed up many or most software developers
В целом исследование достаточно сдержанное, почитать было интересно. Рекомендую самостоятельно хотя бы посмотреть таблички и картинки, чтобы сформировать свое мнение.
На месте исследователей я бы проверил гипотезу про область поиска. Мне иногда кажется, что довольно времени тратится в чате с гпт на изучение альтернативных путей решения (кроме “очевидных” уточнений задачи и просьб исправить ошибки и т.п.). Т.е. чат-бот может иногда подкинуть (довольно часто неправильное или вообще нагаллюционированное) альтернативное решение(я) проблемы, иногда они могут показаться перспективными (в редких случаях даже оказываются ими), но на их фильтрацию тратится уже человеческое время.
Diátaxis — системный подход к документации
Сабж. Хороший материал, основная идея которого — определить цель документации (помочь понять или помочь получить результат) и ее фокус (теория или практика), а потом писать и структурировать материал соответствующим образом. Без понимания цели, аудитории и т.п. получается каша, которую тяжело использовать.
Примечательно, что авторы призывают читать не все описание фреймворка, а только одну довольно короткую страничку, где достаточно кратко изложена основная идея, и углубляться только если будут конкретные вопросы.
Резиновый квадрат в CSS
Прогресс не стоит на месте. Когда делал галерею со смешнявками на чистом CSS в далеком 2020 году, у меня был вопрос, на который не могли ответить ни знакомые фронтендеры, ни на StackOverflow: как сделать “резиновый” квадрат, совместимый с другими фичами.
И вот, 5 лет спустя, шальная мысль пришла в голову и решение нашлось за один запрос: примерно с 2021 везде доступно свойство aspect-ratio, которое делает именно то, что нужно. Никаких больше уродских абсолютных значений в пикселях!
Не тестируйте внешние домены
Не раз такое видел, что в тесте по интеграции с внешним API идет обращение к реальному домену. Некоторые даже при этом говорят “ачетаково”.
Основных проблем две: нестабильность теста и безопасность.
С нестабильностью понятно — сервис прилег, проблемы по дороге с сетью/DNS, rate-limiter зарубил вашего разраба, который запускал тесты 100500 раз в секунду, и привет, тест завален (очень сомневаюсь, что там учитываются подобные проблемы). Да, изредка нужно протестировать интеграцию 1-в-1, но это имеет смысл в весьма редких случаях и может быть достигнуто другими средствами (ну и graceful degradation никто не отменял). Опять же, как вы с реальным сервисом будете тестировать обработку всех проблем?
С безопасностью посложнее — между вами и доменом сервиса есть несколько промежуточных узлов, и вряд ли вы проверяете всю цепочку… Ок, домен доверенный, снимаем шапочку из фольги. А если у вас в коде randomserver.org
? Конечно, вероятность, что об этом кто-то узнает, довольно мала. Внимательный читатель может догадаться, почему эта вероятность может резко повыситься:) Но если прям очень надо потестировать что-то связанное с реальной сетью (что еще более невероятно), то хотя бы используйте домены из RFC: .test
, .example
, .invalid
.
Хотя о чем это я, простите, в половине инструкций в интернете сейчас curl | sh
.
Почему коллеги не хотят
Хороший доклад про разрешение конфликтов и как продвигать “очевидные” изменения.
Начинается с показательных примеров про конфликт интересов (“наши доблестные воины…”.jpg) и кажущиеся полярными точки зрения относительно “очевидно хороших” предложений.
В целом навалено базы:
- Компромисс мало к чему приведет;
- Надо понять своего «оппонента»;
- Надо думать не решениями, а проблемами;
- Зависит от
задапроблемы; - У людей (обычно) нет цели сделать плохо, проблема в системе.
И одна из основных идей — людей ты не поменяешь, поэтому «начни с себя»: лучше погрузись в проблему: какую проблему решаем? действительно ли это проблема? надо ли ее решать сейчас? плюсы/минусы и т.д. При этом признается, что конченные люди все-таки существуют, но не так много как думается, ну и работать с ними не стоит. Дискуссия в кои-то веки тоже полезная.
Правда, в здоровой команде люди достаточно взрослые, чтобы давать обратную связь и конструктивно объяснять, что не так. Ну, мечтать не вредно:)
Об одном нестабильном браузерном тесте
У меня с браузерными тестами и selenium в частности весьма неоднозначные отношения: с одной стороны — автоматическое тестирование — это хорошо, с другой — много видимых пользователю косяков можно легко пропустить (т.е. руками все равно надо будет тестировать) и, по моему опыту, тесты очень хрупкие.
И вот была у меня недавно проблема с частью браузерных тестов уровня “нажми сюда и попадешь на эту страницу”: в CI работает, локально — нет: остается на той же странице. В логах пусто, никаких индикаторов о том, что происходит — нет. Некритично, но неприятно. Потратил кучу времени: может не нажимается? Нажимается, но не работает. Пробовал и так, и сяк (рандомные советы из интернетов) — не работает и все. Я мужественно забил и отложил эту проблему на пару месяцев.
Недавно, после очередного обновления хрома (в котором у нас тестируется) и селениума опять запустил тесты — и, в headless-режиме, который не подразумевает никакого интерфейса, вижу, как мелькает окошко от хрома — твой пароль небезопасен!!1. И правда, в тестах логина, которые локально не работали, использовался p@ssw0rd
. Заменил его на “более сильный” (хотя надо было бы генерировать, по-хорошему), и тесты “починились”. Т.е. благодаря багу хрома я смог обнаружить проблему, о которой не сообщал selenium :/
Теги git
Все в курсе, что у git раковый UX, но даже он не перестает удивлять. Вот есть в репозитории теги:
$ git tag
v1
v2
Уже на этом этапе я обычно хочу написать tags
, ну да ладно. Вот я хочу посмотреть список коммитов, на которые эти теги указывают. Берем первый ответ из гугла:
$ git show-ref --tags
1baddd8efa7f0afac329e16876d94fa54febef4f refs/tags/v1
24105f5ffeb2c93c8dd6f8f10ce0d1701e67a1cd refs/tags/v2
Вроде все логично, однако если сравнить этот вывод с историей:
$ git log --pretty=format:"%H %s"
0c4bd3ad8d403463fbdd6dda50bfe7834ecd2634 second commit
1baddd8efa7f0afac329e16876d94fa54febef4f first commit
То видна проблема — хэши не совпадают. Тут я должен вспомнить, что в git есть два вида тегов: обычные и аннотированные, в которых есть сообщение, автор и т.п.:
$ git for-each-ref refs/tags --format="%(refname:short) %(objecttype)"
v1 commit
v2 tag
Ладно, но как получить то, что я хотел? Для одного тега проще всего запомнить git show $tag
, а вот для всего списка нужно всего лишь
$ git for-each-ref --format='%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end) %(refname:short)' refs/tags
1baddd8efa7f0afac329e16876d94fa54febef4f v1
0c4bd3ad8d403463fbdd6dda50bfe7834ecd2634 v2
24105f5ffeb2c93c8dd6f8f10ce0d1701e67a1cd v2.1 # oops!
Но даже этот метод (от мейнтейнера git, между прочим!) — неправильный, потому что аннотированные теги могут быть вложенными. Поэтому надо сделать
git tag | while read tag; do echo "$(git rev-parse $tag^{}) $tag"; done
Перегрузка скриптов в DevTools
Оказывается, в инструментах разработчика можно подправить JS-скрипты, загруженные на странице. По сути скачиваешь скрипт, редактируешь его на компе, перезагружаешь страницу — и используется уже он. В Chrome было давно, в Firefox появилось сравнительно недавно.
Понятно, что если приложение полностью под контролем, проще его пересобрать, а что-то мелкое можно и через консоль протестировать. Однако если код не полностью под контролем (например, он сгеренирован каким-то экзотическим языком) и/или как-то нестандартно связан с другими модулям — так может быть проще.