Cross Join - канал о разработке – Telegram
Cross Join - канал о разработке
3.69K subscribers
91 photos
8 videos
3 files
286 links
Канал о разработке Антона Околелова. Тимлид Go, живу в Чехии. Мысли, новости, вопросы.

По вопросам рекламы @antonokolelov
Download Telegram
Дотягивать слабые стороны или усиливать сильные?

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

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

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

Есть даже такая известная поговорка «Jack of all trades, master of none». Мастер на все руки – ни в чем не мастер.

Что говорят мудрецы?
Питер Друкер в одной из своих мудрых книг говорил, что сильные стороны сотрудников важнее слабых. Приводил такой пример:
«Генерал Грант был неординарной личностью и вёл не самый здоровый образ жизни. И хотя президент Линкольн знал об этих его особенностях, он всё равно назначил этого генерала главнокомандующим, потому что из всех генералов только Грант умел спланировать и успешно реализовать военные операции. Это было удачное назначение, ставшее переломным моментом Гражданской войны. Так, Линкольн выбрал главнокомандующего за сильные качества, а не за отсутствие недостатков».

В жизни и работе
У каждого из нас есть свои сильные и слабые стороны. И я не уверен, что баланс тут вообще достижим.
А еще я не уверен, что нам нужно достигать этот баланс. Что нам нужно постоянно выравнивать все свои недостатки и корить себя, что это всё никак почему-то не получается.

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

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

И прям морально стало легче.

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

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

Если бы всё было легко, то все бы уже были счастливые, довольные, эффективные и румяные.
👍224👏1💘1
Вообще, щас подумал, что наверно надо развивать не слабые и не сильные стороны, а те, что тебе понадобятся в достижении каких-то целей. Проблема лишь в том, чтобы предсказать будущее и понять, что же тебе будет нужно.
👍191
Шел медведь, видит проект горит.
Влез в него, и выгорел
😁40🗿8👍7💔1
DevHands_io_Highload_Bootcamp_Books_and_Articles_v0_3_16_07_2024.pdf
117.9 KB
Делюсь списком литературы по темам “введение в разработку высоконагруженных проектов”, “архитектура хайлоад-проектов”, “системный дизайн”.

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

Буду рад вашим комментариям и предложениям.
22🔥10👍1🙏1
This media is not supported in your browser
VIEW IN TELEGRAM
Постоянно пользуюсь копайлотом и прочими нейроштуками для программирования. Искренне удивлён, что кто-то до сих пор считает это дурацкой игрушкой.

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

Еще нейросети классно работают для изучения нового. Например, я плохо знаю котлин и как писать плагины для IDE (мой пет проект для выходных). Я слоупок, только в воскресенье попробовал просто нарисовать эскиз в Миро и скормить картинкой в claude.ai - сделай мне класс диалога по экскизу. И всё, я уже вижу код, какие-то новые штуки, фишечки. Да, код надо напильником доработать, но блин, это сокращает путь познания в разы.

Также claude.ai / chatGPT хорош для объяснений чего-то. "Чем отличается технология X от технологии Y"
👍151
UPD: оформил в виде статьи на хабре

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

Хочу явно прописать свои мысли, чтобы потом ссылаться на этот пост.

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

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

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

Читабельность

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

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

Возьмем самый-самый простой пример (псевдокод):

Вместо такого


прочитали из базы()
обработали()
записали результат()


Мы имеем


прочитали из базы()
if err != nil {
return fmt.Errorf("не смогли прочитать из базы: %w", err)
}
обработали()
if err != nil {
return fmt.Errorf("не смогли обработать: %w", err)
}
записали результат()
if err != nil {
return fmt.Errorf("не смогли записать результат: %w", err)
}


какой из двух кусков кода боле читабелен?

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

И это, знаете ли, big fucking deal. Как вы наверно знаете, при программировании люди тратят на чтение кода 80-90% времени, а на написание совсем чуть-чуть. Т.е. сначала надо разобраться, что уже происходит, и лишь потом добавлять новое. Так вот, с чтением кода в Go совсем беда. И беда эта связана только с обработкой ошибок, всё остальное в пределах нормы, а то и лучше.

Стек трейс

Стандартный пакет errors не сохраняет стек вызовов, поэтому когда вы в конце концов на самом высоком уровне получили ошибку и записали ее в лог, в логе вы просто так не поймёте, где изначально была проблема. Например, изначальная ошибка была "ошибка SQL запроса". Где sql, какой именно запрос из сотен? А трейс есть только на момент записи лога, остальной стек уже потерян. Именно поэтому люди вынуждены выкручиваться: использовать сторонние пакеты или прояснять ошибку вручную, добавляя информацию на каждом слое (через fmt.Errorf) или логировать прямо в месте ошибки (еще больше захламляя логику).

В общем, на практике вместо хотя бы

if err != nil {
return nil, err
}

чаще всего идет оборачивание

if err != nil {
return nil, fmt.Errorf("мы тут делали то-то и то-то, а нам вернули ошибку: %w", err)
}


причем это объяснение в 99% нужно не для лучшего понимания происходящего, а тупо для того, чтобы потом по сообщению в логе найти место возникшей проблемы.

Что делать?

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

Например, ключевое слово try перед вызовом функции, которое работает практически как макрос, неявно добавляющий if err != nil {return nil, err}.

или так:
callSomeFunction() orfail
(в случае фейла идет возврат из функции с ошибкой)

тысячи их :)
Как по мне, надо сделать этот самый try. Но его недостаточно, потому что никто не возвращает просто ошибку, ее возвращают с пояснениями. Поэтому нужен try, запоминающий цепочку вызовов. И вот это уже будет бомба.
👍27👎6🤔4😁2🌚2
Почему программисты (и не только) всегда опаздывают с дедлайнами?

Ошибка планирования — это когнитивное искажение, из-за которого мы систематически недооцениваем время, ресурсы и усилия, необходимые для выполнения задачи. Впервые описано психологами Даниэлем Канеманом и Амосом Тверски в 1979 году.

Ключевые фишки:

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

Причины возникновения:

- Чрезмерный оптимизм 😊
- Игнорирование прошлого опыта
- Недооценка сложности и возможных препятствий
- Фокус на идеальном сценарии ("планирование наилучшего случая")
- Внешнее и внутреннее давление сроков
- Желание произвести хорошее впечатление

1️⃣ "Это просто баг, пофикшу за час!"
Спустя 8 часов: "Кто написал этот спагетти-код?!"
2️⃣ Оценка проекта: 2 недели
Реальность: 2 месяца
Причина: Забыли учесть тестирование, документацию и неизбежные правки от клиента.
3️⃣ "Внедрение нового фреймворка займет пару дней"
Месяц спустя: Команда всё еще борется с несовместимостью и неожиданными багами.

Как бороться?

- Разбивайте задачи на мелкие подзадачи
- Применяйте "планирование от прошлого": анализируйте схожие завершенные проекты
- Добавляйте буферное время (умножение оценки на Пи и т.д.)
- Учитывайте "неизвестные неизвестные": резервируйте время на непредвиденные сложности

И всё равно нихера не угадаете

Интересный факт: исследования показывают, что люди более точно оценивают время выполнения задач другими, чем самими собой. В общем, планирование лучше делать коллективно.
20👍9
Прожарка гитхаб-профиля 🙂

https://github-roast.pages.dev/
😁14👎2
Go: Внутреннее устройство sync.Map, сравнение производительности с map + RWMutex

Upd.: теперь и на Хабре

Для тех, кто хочет понять, когда стоит использовать sync.Map, а когда достаточно обычной 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{}
}


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

mu - мьютекс для защиты доступа к dirty мапе
read - атомарное значение, содержащее readOnly структуру
dirty - обычная Go мапа, содержащая все актуальные значения
misses - счетчик промахов при чтении из read мапы

Основная идея sync.Map заключается в использовании двух внутренних карт: read (только для чтения) и dirty (для записи и чтения). Это позволяет оптимизировать операции чтения, которые часто не требуют блокировки.

Операция Load

При выполнении операции Load, sync.Map сначала пытается найти значение в read мапе. Если значение найдено, оно возвращается без какой-либо блокировки. Это очень быстрая операция.
Если значение не найдено в read мапе, увеличивается счетчик misses, и sync.Map проверяет dirty мапу, захватывая мьютекс. Если значение найдено в dirty мапе, оно возвращается.

Операция Store

При выполнении Store, sync.Map сначала проверяет, существует ли ключ в read мапе. Если да, она пытается обновить значение атомарно. Если это не удается (например, ключ был удален), она переходит к обновлению dirty мапы.
Если ключ не существует в read мапе, sync.Map захватывает мьютекс и обновляет dirty мапу.

Когда dirty заменяет read

Интересный момент происходит, когда количество промахов при чтении из read мапы (misses) превышает длину dirty мапы. В этом случае sync.Map выполняет операцию "продвижения":

1. Захватывается мьютекс
2. Содержимое dirty мапы копируется в новую read мапу
3. dirty мапа очищается
4. Счетчик misses сбрасывается

Это выглядит примерно так:

func (m *Map) missLocked() {
m.misses++
if m.misses < len(m.dirty) {
return
}
m.read.Store(&readOnly{m: m.dirty})
m.dirty = nil
m.misses = 0
}

Такой подход позволяет адаптироваться к паттернам использования: если происходит много чтений после серии записей, dirty мапа продвигается в read, что ускоряет последующие операции чтения.

Сравнение производительности с map + RWMutex

Теперь давайте сравним производительность sync.Map с обычной map, защищенной sync.RWMutex.
Обычная потокобезопасная мапа может выглядеть так:

type SafeMap struct {
mu sync.RWMutex
m map[interface{}]interface{}
}

func (sm *SafeMap) Load(key interface{}) (interface{}, bool) {
sm.mu.RLock()
defer sm.mu.RUnlock()
val, ok := sm.m[key]
return val, ok
}

func (sm *SafeMap) Store(key, value interface{}) {
sm.mu.Lock()
defer sm.mu.Unlock()
sm.m[key] = value
}

Производительность этих двух подходов будет зависеть от конкретного сценария использования:

- Если у вас преимущественно операции чтения, sync.Map может быть быстрее, особенно если ключи стабильны (мало добавлений новых ключей).
- Если у вас много операций записи, особенно добавления новых ключей, map + RWMutex может показать лучшую производительность.
- При небольшом количестве горутин, работающих с мапой, разница может быть незначительной, и простота map + RWMutex может быть предпочтительнее.
- При большом количестве горутин, особенно на многоядерных системах, sync.Map может показать лучшую масштабируемость.

Заключение

sync.Map - не серебряная пуля. Её внутреннее устройство оптимизировано под определенные сценарии использования.
👍153
Прикольно. Безо всякого программирования Илья сделал ии-ассистента для своих продавцов, чтобы они могли осмысленно искать товары в каталоге товаров, когда общаются с клиентами. Ноукод как он есть.

За десять минут были заменены сразу и программисты, и опытный продавец. Правда, я так понимаю, это всё может иногда галлюционировать, так что какой-никакой мозг продавца пока что еще нужен.
👍2
Я тут сделал небольшое видео про ИИ-ассистентов и как можно за 15-20 минут сделать себе штуку под названием RAG, которая будет давать ответы, отталкиваясь от ваших данных.
https://youtu.be/4RFJx7rbN2E
👍81🤡1
Ответы на вопросы: один день из жизни CTO

Антон О. попросил написать сабж.

Когда я только-только стал engineering manager, я быстро понял, что вся муть про agile, власть команды и прочая скрам-ересь – это херня полная, потому что она приводит к тормозам, а скоростным компаниям нужна agility. Agility достигается менеджерами, которые херачат и культурой несидения на жопе ровно. Короче, главным навыком является управление, управление проектами, но в первую очередь - управление временем. Миллион людей будут с этим не согласны, будут находить тысячу причин не заниматься управлением даже своего времени, говорить что это стресс, что не для всех задач, и в этом канале уже неоднократно вспыхивали подобные срачики. Ну мне не надоедает в них участвовать и нести разумное-доброе-вечное, но пост не об этом, а о работе CTO.

Так вот, был я, значит, engineering manager и решил “потрекать свое время” - ну это натурально записать “один день из моей жизни”. Помечал всё, что делаю. К середине дня я понял, что поскольку я стараюсь не откладывать мелких дел - я на записи каких-то дел трачу время сравнимое с самим делом. Задумался, не херню ли я делаю, стал мелкие дела опускать. К концу дня я посмотрел на 3 листа A4 и решил, что там решительно нет ничего полезного для анализа, и что больше никогда такой фигней я заниматься не буду.

Мораль: один день даже у CTO (а у CTO тоже много сравнительно мелких дел) если он будет записан, состоит из такого количества “мусора”, что разбираться с ним будет бесполезно. Вот небольшой список того, что могло быть в таких записях. Тут нет хронологии - это просто пример, что могло бы оказаться в этом самом пресловутом “одном дне из жизни CTO”. Утро понедельника полет на работу в Лондон. Куча встреч по ongoing projects (10 встреч в день - легко, чем корпоративнее культура - тем больше встреч). Практика в пиццерии (у меня был онбординг в лондонской пиццерии - я работал там несколько дней, работал плохо и, мне кажется, сильно достал менеджера точки). Подготовка/апдейт презентаций по тех-стратегии. Обсуждение с командой продуктовой стратегии и hiring plan на год. Полет на встречу с акционерами, презентация hiring плана и бюджета на команду. Участие в партнерской конференции - встреча со студентами. Выступление в МФТИ на клубе выпускников. Выступление перед студентами МГУ/Бауманки. Вечер, чуваки из Макинзи позвали в караоке отмечать конец проекта. Intro-calls с кучей людей, не всегда полезных, но вдруг. Подготовка сложного увольнения - бриф с партнерами E&Y. 1:1 со всеми членами моей команды. Участие в ревью – финальные менеджерские оценки, калибрация. Подготовка/выступление на all hands. Понимате? Это я просто что-то написал более-менее интересно за три минуты, а сколько я упустил?

Короче, Антон, прости - но по-моему ты не должен этого хотеть. Тебе нужен не один день из жизни СТО, а один год из жизни CTO - но тебе его никто не напишет 🙂 Впрочем, я думаю, что предыдущий абзац твое любопытство хотя бы частично удовлетворил.

Если же подходить системно о том, из чего состоит работа CTO/CIO, в чем отличие от CIO, например - то я об этому уже писал:
https://news.1rj.ru/str/rybakalexey/5 - CTO не CTO I
https://news.1rj.ru/str/rybakalexey/7 - CTO не CTO II
https://news.1rj.ru/str/rybakalexey/8 - CTO vs CIO
https://news.1rj.ru/str/rybakalexey/9 - CTO vs CIO (продолжение)

Enjoy.
👍6🤡2🌚21
Вчера вышел релиз #go 1.23 - самый спорный релиз на моей памяти https://go.dev/doc/go1.23

В нём стали доступны функции-итераторы https://go.dev/doc/go1.23#language, добавление которых вызвало довольно много негативной реакции в сообществе https://www.gingerbill.org/article/2024/06/17/go-iterator-design/

Помимо пакета нового пакета iter в пакеты slices и maps много новых функций типа Backward, Chunk, Values, Keys и Collect

Так же в этом релизе добавлена функциональность сбора телеметрии тулчейна Go. Телеметрия отключена по умолчанию и собирает анонимную информацию о параметрах go и gopls (https://go.dev/doc/telemetry). Одно время обсуждения самой возможности были довольно бурными https://www.reddit.com/r/golang/comments/10z5ig1/googles_go_may_add_telemetry_reporting_thats_on/ . Телеметрия не затрагивает результат сборки.

Посмотреть на статистические выкладки телеметрии и скачать собранный датасет можно вот тут https://telemetry.go.dev/

Список багов, пойманных телеметрией https://github.com/golang/go/issues?q=label%3Agopls%2Ftelemetry-wins

Из менее противоречивых изменений мне приглянулись
⁃ Новый флаг go mod tidy -diff - печатает изменения, которые произойдут при go mod tidy и возвращает exit_code=1 если такие изменения есть. Сильно упрощает проверки в CI
⁃ Новый флаг go env -changed - печатает изменения в go env, сделанные с помощью -w
⁃ Упрощена работа с time.Timer и time.Ticker - теперь вызовов .Reset и .Stop достаточно для корректного сброса и остановки - не надо вытаскивать stale значения из каналов
⁃ Новый пакет unique, который позволяет интернировать comparable значения
⁃ Новый пакет structs с маркерным типом structs.HostLayout для контроля memory layout структур
⁃ В go.mod корневых модулей (не зависимостей) можно использовать директиву godebug (https://go.dev/doc/godebug), которая позволяет включать старое runtime поведение некоторых частей стандартной библиотеки. Например, новое поведение таймеров можно отключить вот так

godebug(
asynctimerchan=1
)



⁃ В net/http добавили много утилит для работы с cookie и поле Request.Pattern, которое содержит паттерн роута из http.Mux. Ждём когда chi будет выставлять его тоже
⁃ Новая функция os.CopyFS, которая копирует содержимое fs.FS в локальную директорию. Писать распаковщики zip никогда не было так просто!
⁃ Максимальная глубина стека для runtime/pprof увеличина до 128 фреймов (да, я упирался в глубину стека на трейсах 😔)
⁃ Новые функции atomic.And и atomic.Or (и комплиментарные методы), которые позволяют атомарно применять битовые маски

Интерактивные заметки к релизу https://antonz.org/go-1-23/
👍24🤡1
Забавная статья. ChatGPT деминифицировал код.

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

Тогда он сначала попросил ChatGPT объяснить принцип работы, а потом просто сказал, мол, а сгенери-ка ты нормальный человеко-читаемый typenoscript.

И на его удивление, получилось просто почти идеально.

Т.е., гопчат сработал как деминификатор кода.

https://glama.ai/blog/2024-08-29-reverse-engineering-minified-code-using-openai
🔥20👍6🤡1
Среди программистов довольно часто встречаются перфекционисты. Чаще, чем в других профессиях.

А ты? Перфекционируешь небось?

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

Импорты должны быть отсортированы по хитрым правилам. Перед return должен быть перевод строки, иначе мы все умрём. (Или что там у вас?)

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

Короче. Предлагаю лайфхак.

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

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

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

А если при этом думать о системе в целом, то это будет вообще мегаидеально. Прям можно идти на международные соревнования по перфекционизму
👍25🤡10🥱8😁7🔥2💩2🖕2❤‍🔥1
OpenAI сделали новую модель. В отличие от предыдущих, она не сразу выдает ответ, а пытается "порассуждать". В итоге результаты в математических и программерских тестах улучшились в разы.

https://openai.com/index/introducing-openai-o1-preview/
😱17👍1👏1🤔1
Дженерик алиасы типов в Go в 1.24 : что это и зачем они нужны

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

Проблема рефакторинга в больших проектах

Представим, что у вас есть популярный пакет oldpkg с типом User:

package oldpkg

type User struct {
ID int
Name string
}

Теперь вы хотите перенести этот тип в новый пакет newpkg. Но ваш тип User используется в сотнях мест по всему проекту и в зависимых проектах. Как провести такой рефакторинг без боли?

Go 1.9 представил концепцию алиасов типов. Это позволяет нам создать новое имя для существующего типа без создания нового типа. Вот как это выглядит:


package newpkg

import "path/to/oldpkg"

type User = oldpkg.User


Теперь newpkg.User и oldpkg.User - это один и тот же тип. Мы можем постепенно обновлять использование oldpkg.User на newpkg.User по всему проекту, и компилятор будет счастлив.

Но что насчет дженериков?

С появлением дженериков в Go 1.18 возникла новая проблема. Как быть, если наш тип User использует параметры типа? До сих пор алиасы типов не поддерживали параметры типа. Но это изменится в Go 1.24

Дженерик алиасы типов

Представим, что наш тип User теперь дженерик:



package oldpkg

type User[T any] struct {
ID T
Name string
}


В Go 1.24 мы сможем создать алиас для этого типа следующим образом:


package newpkg

import "path/to/oldpkg"

type User[T any] = oldpkg.User[T]


Это позволяет нам сохранить полную совместимость типов при переносе дженерик-типов между пакетами.

Когда это будет доступно?

В Go 1.23 вы можете включить поддержку дженерик алиасов типов с помощью флага GOEXPERIMENT=aliastypeparams.
В Go 1.24 (ожидается в начале 2025 года) эта функция будет включена по умолчанию.

Подробности здесь
👍11🔥5😁2🙏1
Я принес. Гуманизм против «эффективного менеджмента». Почему заботиться о людях выгодно

Вы знаете, что я тот еще гуманист 🙂 Поэтому не мог пройти мимо этого лонгрида https://habr.com/ru/articles/816545/
Текст большой, так что наливайте чай-кофе, заводите один таймер pomodoro и погружайтесь.

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

Так что, граждане тимлиды, этот контент вам точно будет полезен.
👍83🔥2
Вышел PostgreSQL 17

Производительность:

Существенно улучшена работа с памятью. Вакуум теперь потребляет до 20 раз меньше памяти, что ускоряет его работу и снижает нагрузку на систему.
Запись при высокой конкурентной нагрузке стала быстрее в 2 раза благодаря оптимизации обработки WAL.
Улучшена производительность запросов с использованием условий IN для B-tree индексов.
Добавлена поддержка SIMD-инструкций (в том числе AVX-512) для ускорения вычислений.
Оптимизирована производительность COPY для экспорта больших объемов данных.

Для разработчиков:

Расширена поддержка JSON: добавлен JSON_TABLE для конвертации json в обычные таблицы PostgreSQL.
Появились новые конструкторы и функции для работы с json: JSON, JSON_SCALAR, JSON_SERIALIZE, JSON_EXISTS, JSON_QUERY, JSON_VALUE.
Улучшена команда MERGE: добавлена поддержка RETURNING и возможность обновления представлений.
EXPLAIN теперь показывает время, затраченное на локальное чтение и запись блоков, а также использование памяти.

Репликация и обновление:

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

Безопасность и управление:

Новые опции TLS для более гибкой настройки безопасности соединений.
Добавлена предопределенная роль pg_maintain для выполнения задач обслуживания.
Улучшены возможности резервного копирования: поддержка инкрементальных бэкапов в pg_basebackup.

Мониторинг и анализ:

Добавлено отображение прогресса при вакууме индексов.
Новое системное представление pg_wait_events для более детального анализа ожидающих сессий.
🔥36👍4😍1
Я наверно слоупок, только сейчас узнал о программе dust, замене du

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

Запустил в папке с проектами, сразу нашел гигабайтные node_modules в старых проектах, прикольно.

подробнее тут (там куча полезных параметров)

Ставится просто brew install dust
❤‍🔥22🔥7👍3