Search
Write a publication
Pull to refresh
277
0
Антон Околелов @varanio

Go-тимлид, веду канал https://t.me/crossjoin

Send message

Virtual generated columns в PostgreSQL 18

Reading time1 min
Views2.7K

В PostgreSQL 18 добавят виртуальные сгенерированные столбцы (комит).


Ранее PostgreSQL уже поддерживал сгенерированные столбцы (начиная с версии 12), но только в варианте STORED, когда результат вычислений сохраняется в таблице. Теперь появилась возможность вычислять значения "на лету" при чтении, что экономит место и даёт больше гибкости в проектировании схем данных.


Как создать виртуальный столбец?

Читать дальше →

Microsoft создала первый в мире топологический квантовый процессор: на пути к миллиону кубитов

Reading time3 min
Views16K

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

Читать далее

Перестаньте молиться на принципы S.O.L.I.D

Reading time6 min
Views48K

В мире разработки программного обеспечения существует множество "священных коров" — принципов и практик, которые принимаются как данность и редко подвергаются критическому анализу. Особенно показательна ситуация с принципами SOLID на русскоязычных ресурсах: достаточно открыть Хабр, чтобы найти 100500 статей о SOLID, и в каждой из них принципы интерпретируются по-разному.


Само существование такого количества "объяснительных" статей говорит о фундаментальной проблеме: если принципы требуют толкования, значит их названия не являются самодостаточными и интуитивно понятными. А если каждый разработчик понимает принципы по-своему, возникает вопрос — зачем вообще нужны принципы, которые не дают однозначного руководства к действию? Принципы SOLID, предложенные Робертом Мартином, давно стали одной из таких "священных коров". Однако пришло время честно признать: то, как мы используем SOLID сегодня, часто противоречит изначальным идеям и в целом иногда может приносить больше вреда, чем пользы. Зависит от контекста.


SRP не SRP


Самый яркий пример искажения первоначального замысла — это интерпретация принципа единственной ответственности (SRP).

Читать дальше →

React Native полностью переделан

Reading time3 min
Views15K

После 6 лет разработки команда React Native представила полностью переписанную архитектуру фреймворка (0.76) – самое значительное обновление с момента создания React Native. Это результат масштабной работы над улучшением производительности, стабильности и возможностей платформы.

Читать дальше →

Внутреннее устройство sync.Map, сравнение производительности с map + RWMutex

Reading time3 min
Views4.4K

Привет, Хабр! Эта статья для тех, кто хочет понять, когда стоит использовать sync.Map, а когда достаточно обычной map с мьютексом.


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


Внутреннее устройство sync.Map


sync.Map — это потокобезопасная реализация мапы в Go, оптимизированная для определенных сценариев использования.


Основная структура sync.Map выглядит примерно так:


type Map struct {
    mu Mutex
    read atomic.Value // readOnly
    dirty map[interface{}]*entry
    misses int
}

type readOnly struct {
    m       map[interface{}]*entry
    amended bool
}

type entry struct {
    p unsafe.Pointer // *interface{}
}

Здесь мы видим несколько ключевых полей:

Читать дальше →

Ошибки в языке Go — это большая ошибка

Reading time3 min
Views19K
// гофер пытается найти логику среди обработки ошибок
+-------+-------+-------+-------+-------+-------+
|       |  err  |       |  err  |       |  err  |
|  ,_,,,        |       |       |       |       |
| (◉ _ ◉)       |       |       |       |       |
|  /)  (\               |       |       |       |
|  ""  ""               |       |       |       |
+       +-------+       +-------+       +-------+
|       |  err          |  err  |       |  err  |
|       |               |       |       |       |
|       |               |       |       |       |
+-------+       +-------+       +-------+       +
|  err  |               |  err                  |
|       |               |                       |
|       |               |                       |
+       +-------+       +       +-------+       +
|       |  err  |               |  err  | logic |
|       |       |               |       |       |
|       |       |               |       |       |
+-------+-------+-------+-------+-------+-------+

Я пишу на Go несколько лет, в Каруне многие вещи сделаны на нём; язык мне нравится своей простотой, незамысловатой прямолинейностью и приличной эффективностью. На других языках я писать не хочу.


Но сорян, к бесконечным if err != nil я до конца привыкнуть так и не смог.


Да-да, я знаю все аргументы: явное лучше неявного, язык Go многословен, зато понятен, и всё такое. Но, блин, на мой взгляд Го-вэй Го-вэю рознь.

Читать дальше →

А что если исходные коды программ хранить в бинарном формате?

Reading time3 min
Views28K

Эта статья — просто идея, не судите строго.


TLDR: предлагаю рассмотреть хранение исходных кодов программ в некоем бинарном формате вместо голого текста.


Компилятор и IDE


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


И только потом идут этапы, приводящие в конце концов к появлению исполняемого файла.


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


Т.е. сам текст программы нужен только человеку на этапе ввода информации. Потому что ему для понимания происходящего AST-дерево не подойдёт.


Но что если хранить исходный код по-другому?

Читать дальше →

Structured concurrency в языке Go

Reading time5 min
Views6.3K

Горутины виснут непонятно почему, случайная запись в закрытый канал вызывает panic, нормально протестировать приложение вообще невозможно.


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


Чтобы не запутаться, люди придумали концепцию structured concurrency, которую можно применять и в Go.

Читай или страдай

Пишем поиск семантически похожих текстов (или товаров) за полчаса на Go и Postgres (pgVector)

Reading time5 min
Views11K


Казалось бы, в посгресе и так есть неплохой полнотекстовый поиск (tsvector/tsquery), и вы из коробки можете проиндексировать ваши тексты, а потом поискать по ним. Но на самом деле это не совсем то, что нужно — такой поиск работает лишь по чётким совпадениям слов. Т.е. postgres не догадается, что "кошка гонится за мышью" — это довольно близко к "котёнок охотится на грызуна". Как же победить такую проблему?


TLDR:


  1. Преобразовываем наши тексты в наборы чисел (векторы) при помощи API openAI.
  2. Сохраняем векторы в базе с помощью pgvector.
  3. Легко ищем близкие друг к другу векторы или ищем их по вектору-запросу.
  4. Ускоряем индексами.
Читать дальше →

PostgreSQL: обеспечение уникальности записи с проверкой даты валидности

Reading time2 min
Views4.9K

Как бы вы решали такую задачу? Предположим, есть таблица с купонами, и у купонов есть некая дата устаревания valid_until. Вам надо обеспечить такое ограничение (constraint) на уровне БД, чтобы у одного человека мог быть только один действующий купон.


Т.е., таблица изначально выглядит так:


CREATE TABLE coupons (
    id  bigint primary key generated by default as identity,
    user_id bigint not null,
    created_at timestamp not null,
    valid_until timestamp not null
)
Читать дальше →

ORM для реальных приложений не окупается

Reading time4 min
Views32K


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


Проблемы


  1. При использовании ORM мы обычно прописываем в коде сущности и их взаимосвязи, и по сути это — проектирование БД ещё раз (дублирование логики!) прямо в коде.
  2. Борьба с проблемами производительности никуда не денется всё равно, как ни абстрагируй. Ты просто не можешь не знать, что у тебя под капотом происходит. Какие там делаются джойны и группировки.
  3. Язык запросов в виде цепочки объектов и методов читается хуже, чем SQL, по сути это — особый язык, который надо учить. За себя скажу, что когда писал на PHP (Laravel), длинные запросы на Eloquent меня иногда изумляли своей сложностью чтения:
Читать дальше →

Golang: как найти мёртвый код в проекте, а заодно оценить покрытие тестами живого кода

Reading time3 min
Views4K

В Go 1.20 сделали возможность сбилдить приложение с флагом cover


go build -cover

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


Это, конечно, было сделано для интеграционных тестов, когда приложение запускается целиком в каких-то сценариях (а не через go test), но, вероятно, это можно попробовать использовать и по-другому:


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


Так можно найти недовыпиленный легаси-код, старые эндпоинты API, которые давно никому не нужны, малозначимые проверки if err != nil и прочее. Как минимум, на это интересно посмотреть, можно найти что-нибудь удивительное.


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

Читать дальше →

Ключ к эффективности разработки: делать то, что нужно, но лишнего не делать

Reading time2 min
Views5.4K

Кучу времени можно сэкономить если:


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


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

Читать дальше →

В Go меняется фундаментальная вещь — цикл

Reading time2 min
Views31K

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


проще показать на примере:


 funcs := []func(){}

 for i := 0; i < 5; i++ {
  funcs = append(funcs, func() {
   fmt.Println(i)
  })
 }

 funcs[0]()

Последняя строка примера напечатает 5 в go 1.21, но в go 1.22 будет уже интуитивно понятный 0.

Читать дальше →

В Go 1.21 существенно расширяется стандартная библиотека

Reading time4 min
Views15K
// теперь в Go так можно!
slices.Contains(s, v)

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


Однако для стандартной библиотеки Go это было по-настоящему царским подарком. Появились новые стандартные обобщенные функции, и, отстоявшись в экспериментальном репозитории golang.org/x/exp, теперь появятся в Go 1.21. Релиз буквально через месяц.


TLDR: появилось множество функций по работе со слайсами, мапами, а также новый логгер с (почти) всеми нужными фишечками.


Лично для меня знаковым событием стало появление возможности поиска элемента в слайсе и получение ключей мапы, потому что ну давно пора, 10 лет языку.


Но давайте обо всём по порядку.

Читать дальше →

Я бы пересмотрел вообще всё

Reading time4 min
Views78K

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


Вот примеры.


1) Например, DRY — don’t repeat yourself. Хорошее полезное правило, но его можно довести до маразма. Из того что я встречал на практике: есть два разных по бизнес-смыслу раздела, которые начинались с простого CRUD, и многие части (и фронта и бека) выглядели во многом абсолютно одинаково. Если их объединить с помощью общей высосанной из пальца абстракции и тем самым избавиться от небольшого дублирования кода, то потом (очень скоро) можно будет сойти с ума, потому что эти две вещи скоро разъедутся, обрастая кастомными фичами, и абстракция будет только вредить. Нельзя абстрагировать неабстрагуемое, даже если DRY нарушен.


«[Немного] дублирования обходится гораздо дешевле, чем неправильная абстракция» — Сэнди Мец

Т.е. DRY — хороший принцип, но бывают исключения.

Читать дальше →

Неразрешимые проблемы разработки

Reading time3 min
Views10K


Сроки


В разработке ПО существует неразрешимое противоречие — это оценка сроков.


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


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


  • новая функциональность нетипична
  • есть зависимости на другие команды
  • будет задействована новая технология
  • ТЗ надо сильно уточнять
  • надо разобраться в логике легаси-кода

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

Читать дальше →

Опасен ли AI? Человечество дебажит свои идеи прямо на «проде»

Level of difficultyEasy
Reading time5 min
Views3.2K

Сейчас модно обсуждать ChatGPT / Сopilot и код, который они генерируют. Может ли AI полноценно программировать? Заменит ли он меня? Имхо этот вопрос вторичен, проблема куда глубже и серьёзнее.


Одни говорят, что на сегодняшний день в Copilot нет ничего плохого — это всего лишь инструмент, устраняющий мелкую рутину. Оно напишет за тебя цикл, проверит if err != nil, но не более того. Другие — что развитие ИИ идет нелинейно, с ускорением, и по опросам специалистов появление разума, сравнимого с человеческим, неизбежно. А если можно будет тиражировать искусственных ученых и программистов, то и до сверхразума недалеко. Который, хе-хе, может решить уничтожить всех людей.


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


вероятность опасного развития событий больше нуля

и эта вероятность не то чтобы совсем иллюзорна.

Читать дальше →

Монолит или микросервисы — это не вопрос технологических предпочтений, это про time-to-market

Level of difficultyEasy
Reading time5 min
Views14K

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


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


Поехали.


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


Одна команда


Когда команда одна, не очень большая (two pizza team), то никто никому не мешает. Код ревью, рефакторинг, деплой проходят быстро и весело. Бизнес сфокусирован на цели и работает как единое целое. Целью, кстати, зачастую является проверка гипотезы, нужен ли вообще этот проект кому-то или нет.

Читать дальше →

Алгоритм «Longest common subsequence» на Go. Как прийти к решению?

Level of difficultyMedium
Reading time6 min
Views5.6K

Среди программистов не утихают споры о том, надо ли знать "алгосики" для реальной работы, или же это просто некий странный ритуал для прохождения воронки собеседований в компании а-ля FAANG (MANGA). У нас в Каруне в разных командах есть разные мнения на этот счёт. Я, например, как тимлид Go-команды считаю, что некую элементарную базу знать точно бы не помешало, но всё же главное, чтоб человек был хороший.


Мнения могут различаться, но одно я знаю точно: разгадывать загадки бывает очень интересно. Я как-то из любопытства прорешивал задачки на hackerrank, и, если для решения простых задач тупо достаточно догадаться отсортировать данные или построить map (даже не надо ничего особо знать), то для некоторых придумать решение довольно проблематично.


Одна из таких задач — нахождение самой длинной общей подпоследовательности (longest common subsequence). Подобный алгоритм используется в реальной жизни, в таких программах как diff. Скажу сразу: я не смог решить задачу самостоятельно за разумное время (т.е. пока не надоело решать) и посмотрел алгоритм в Википедии.


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


Disclaimer: я точно не олимпиадник и не гуру алгоритмов, просто любопытствующий.

Читать дальше →

Information

Rating
Does not participate
Location
Praha, Hlavni Mesto Praha, Чехия
Date of birth
Registered
Activity

Specialization

Backend Developer, Fullstack Developer
Lead