Как стать автором
Обновить

Компания Karuna временно не ведёт блог на Хабре

Сначала показывать

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

Время на прочтение3 мин
Количество просмотров1.8K

Привет, Хабр! Эта статья для тех, кто хочет понять, когда стоит использовать 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{}
}

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

Читать дальше →
Всего голосов 9: ↑8 и ↓1+11
Комментарии4

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

Время на прочтение3 мин
Количество просмотров18K
// гофер пытается найти логику среди обработки ошибок
+-------+-------+-------+-------+-------+-------+
|       |  err  |       |  err  |       |  err  |
|  ,_,,,        |       |       |       |       |
| (◉ _ ◉)       |       |       |       |       |
|  /)  (\               |       |       |       |
|  ""  ""               |       |       |       |
+       +-------+       +-------+       +-------+
|       |  err          |  err  |       |  err  |
|       |               |       |       |       |
|       |               |       |       |       |
+-------+       +-------+       +-------+       +
|  err  |               |  err                  |
|       |               |                       |
|       |               |                       |
+       +-------+       +       +-------+       +
|       |  err  |               |  err  | logic |
|       |       |               |       |       |
|       |       |               |       |       |
+-------+-------+-------+-------+-------+-------+

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


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


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

Читать дальше →
Всего голосов 45: ↑41 и ↓4+42
Комментарии95

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

Время на прочтение3 мин
Количество просмотров28K

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


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


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


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


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


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


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


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

Читать дальше →
Всего голосов 75: ↑35 и ↓40+7
Комментарии240

Structured concurrency в языке Go

Время на прочтение5 мин
Количество просмотров5K

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


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


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

Читай или страдай
Всего голосов 16: ↑13 и ↓3+13
Комментарии17

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

Время на прочтение5 мин
Количество просмотров8.7K


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


TLDR:


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

Как не про…пустить все дедлайны. Автоматизируй, властвуй, сохраняй

Уровень сложностиПростой
Время на прочтение11 мин
Количество просмотров3.6K

Как не умереть от рабочей рутины и не потерять фокус между десятками ежедневных задач? Как по максимуму использовать почту, календарь, мессенджер и браузер?
Читайте мини-гайд и берите на заметку!
P.S. ТОП 8 неудачных прыжков на грабли в комплекте

Читать далее
Всего голосов 8: ↑6 и ↓2+6
Комментарии7

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

Время на прочтение2 мин
Количество просмотров4.4K

Как бы вы решали такую задачу? Предположим, есть таблица с купонами, и у купонов есть некая дата устаревания 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
)
Читать дальше →
Всего голосов 13: ↑11 и ↓2+12
Комментарии20

Код-ревью и Рингельман

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров3.1K

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

Читать далее
Всего голосов 8: ↑6 и ↓2+7
Комментарии1

Как не про…пустить все дедлайны. Таск-трекер в деле

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров8.6K

Какие подходы к управлению временем вы сейчас используете? Готовы ли вы сказать, что у вас чёткая система по управлению вашими рабочими задачами?

Я готов сказать — да, и поделиться как это работает у меня вот уже много лет.

Читать далее
Всего голосов 11: ↑8 и ↓3+6
Комментарии9

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

Время на прочтение4 мин
Количество просмотров31K


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


Проблемы


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

Мониторинг с Grafana. Best practices

Уровень сложностиСредний
Время на прочтение11 мин
Количество просмотров50K

Сборная солянка из существующих best practices по работе с Grafana и немного с Prometheus, проверенных мной лично. Можно просто положить в закладки — когда-нибудь да пригодится.

Будет полезно
Всего голосов 17: ↑17 и ↓0+17
Комментарии12

Как получить полезную информацию из своих категориальных признаков?

Уровень сложностиПростой
Время на прочтение9 мин
Количество просмотров7.7K

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

Читать далее
Всего голосов 10: ↑10 и ↓0+10
Комментарии5

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

Время на прочтение3 мин
Количество просмотров3.8K

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


go build -cover

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


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


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


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


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

Читать дальше →
Всего голосов 10: ↑9 и ↓1+10
Комментарии4

Как понять, что клиента пора реактивировать?

Уровень сложностиПростой
Время на прочтение15 мин
Количество просмотров1.9K

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

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

Меня зовут Артём, я антифрод-аналитик в Каруне, и в данной статье мы рассмотрим достаточно простой подход, с помощью которого можно решить обозначенную проблему. Если вы скажете, что антифрод решает абсолютно другой спектр задач, то будете абсолютно правы. Однако во время работы с одним из проектов при переосмыслении использованного алгоритмического стека в нём, мы пришли к выводу, что отдельные небольшие кусочки этого стека вполне могут подходить и для решения других задач. На базе нашего опыта расскажу, как с помощью байесовского моделирования и библиотеки PyMC3 можно получить примерную картину о том, как долго ваш клиент должен быть неактивным, чтобы считать его отточником. Это может помочь ответить на базовые вопросы бизнеса и подготовиться к реализации более точных и качественных моделей (если это потребуется).

Читать далее
Всего голосов 7: ↑7 и ↓0+7
Комментарии0

Два стула для руководителя. Слабо усидеть на обоих?

Уровень сложностиПростой
Время на прочтение14 мин
Количество просмотров4K

Вы когда-нибудь приходили на позицию руководителя в новую для вас команду? 

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

Вас ждет небольшой Cookbook по непростым ситуациям и вариантам их решения. 

Упор делаю на процессы и людей — именно эти 2 “стула” вам предстоит осилить.

Читать далее
Всего голосов 13: ↑11 и ↓2+15
Комментарии3

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

Время на прочтение4 мин
Количество просмотров14K
// теперь в Go так можно!
slices.Contains(s, v)

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


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


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


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


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

Читать дальше →
Всего голосов 35: ↑33 и ↓2+39
Комментарии7

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

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров4.4K

О чем и для кого статья?

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

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

Читать далее
Всего голосов 11: ↑7 и ↓4+6
Комментарии14

Как стать тестировщиком без регистрации и смс, но с нейросетями. Эксперимент, который зашёл слишком далеко

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров4.5K

Привет, меня зовут Мария, я работаю в Каруне неунывающим экспериментатором чата GPT, ну а вообще UX-писателем. В предыдущей статье я попыталась устроиться Middle Full-Stack разработчикам только с помощью чата GPT. Результаты моего эксперимента можно почитать в этой статье.

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

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

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

Читать далее
Всего голосов 6: ↑5 и ↓1+5
Комментарии3

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

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров13K

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


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


Поехали.


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


Одна команда


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

Читать дальше →
Всего голосов 39: ↑37 и ↓2+41
Комментарии86

Ультимативный гайд по хакатону без кода: как проработать 3 запроса бизнеса за 9 часов, и при чём здесь Гарри Поттер

Уровень сложностиПростой
Время на прочтение8 мин
Количество просмотров1.3K

У нас было 3 темы, 15 команд, 6 сочных заданий, 9 часов плотного хакатонинга с перерывом на обед, заполненный 10+ проектами на 2 квартала вперёд роадмап, и ноль программирования. Мы называли это Карунатон.

Давайте сразу черкану, что даст вам эта статья, и зачем читать её до конца: 

Читать далее
Всего голосов 4: ↑4 и ↓0+4
Комментарии2