Как стать автором
Поиск
Написать публикацию
Обновить
194.48

Go *

Компилируемый, многопоточный язык программирования

Сначала показывать
Порог рейтинга

5 библиотек Golang для эффективной разработки веб-приложений

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

1. CHI Router

Как по мне, самая лучшая библиотека для веб разработки. Полная совместимость с роутером голанга, а также большое кол-во middleware - вот главные плюсы Chi router. Им я пользуюсь на постоянной основе

2. Go Fiber

Если Вам не понравился Chi router - есть Go FIber. Быстр, но нет совместимости со встроенным роутером. Если для Вас это не проблема - используйте его. Для меня его преимущества - скорость и возможность возвращать ошибки из хэндлеров

3. Jet templates

Насколько сильно мне упростила эта библиотека жизнь. Наипростейшее использование темплэйтов в Golang. Если Вам не нравится встроенное их использование, Jet - Ваше спасение

4. Scs

Отличный менеджер сессий. Если Вам надо использовать сессии - Scs

5. CHI Render

Отличная библиотека от тех же людей, что сделали CHI router. Помогает работать с HTTP запросами

На этом все, но могу также порекомендовать такие библиотеки, как testify для упрощения написания тестов и cleanenv для чтения конфига, ведь это так же важно.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии2

Чем занимаются Go-специалисты в Островке?

У нас 10 команд, использующих Go, как основной язык. Для примера возьмём команду интеграций с поставщиками отелей. Вот что делают разработчики в этой команде:

  • Адаптируют API различных поставщиков к внутреннему API сервиса. Внешние поставщики отелей используют разные технологии: GraphQL, XML, SOAP, WTF. В каждом API своё время ответа, свои коды ошибок и ещё много кастомного. 

  • Поддерживают и правят существующие интеграции. Протокол сменился, или (куда реже) коды ошибок стали другие — всё надо держать в актуальном состоянии и при необходимости править.

  • Уменьшают технический долг. Это задачи, связанные с библиотеками и рефакторингом. Есть правило — на одну итерацию должно приходиться 75% продуктовых задач и 25% техдолговых.

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

  • Обмениваются знаниями внутри компании. В Островке есть активности, напрямую не связанные с работой. Например, канал в слаке #dev-golang и еженедельный книжный клуб.

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

Теги:
Всего голосов 4: ↑3 и ↓1+6
Комментарии2

Go: Раскрытие потенциала скорости

Я всегда борюсь за скорость. Началось это все с того, как я прочитал книгу “Грокаем алгоритмы” и меня заинтересовало измерение скорости выполнения. Потом, решая задачи на LeetCode я расстраивался, если алгоритм получался медленным. Недавно мне пришла идея написать пост на эту тему, а во время написания изучить этот вопрос получше. Я прочитал не мало статьей, большинство из которых - англоязычные.Так что вот советы по увеличению скорости Вашего приложения на Golang :

1. Выделять ёмкость для среза с помощью make

При создании среза выделяйте ёмкость с помощью make, так Вы избавитесь от перераспределений

2. При возвращении указателя, объявлять его при создании переменной

 func (r Ruleset) Match(path string) (*Rule, error) {
 	for i := len(r) - 1; i >= 0; i-- {
		rule := r[i] //так НЕ надо
		rule := &r[i] //так надо
 		match, err := rule.Match(path)
 		if match || err != nil {
			return &rule, err //так НЕ надо
			return rule, err //так надо
 		}
 	}
 	return nil, nil
}

3. Пишите бенчмарки

Пишите бенчмарки для вашего приложения, так Вы поймете, в каком месте оно работает медленнее всего. Источник для того, чтобы научиться писать бенчмарки: https://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go и др.

4. Используйте горутины!

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

Теги:
Всего голосов 5: ↑2 и ↓3+3
Комментарии4

Эта программа сериализует данные из слайса структур User в JSON-формат. Но есть одна проблема: программа не работает. Нужно найти ошибку и исправить её. Когда программа заработает, она выведет данные на экран в JSON-формате.

import (
  "encoding/json"
  "fmt"
)

type User struct {
  id       int    `json:"id"`
  name     string `json:"name,omitempty"`
  email    string `json:"email,omitempty"`
  password string `json:"-"`
}

func main() {
  users := []User{
    {
      id:       1,
      name:     "Gopher",
      email:    "gopher@example.com",
      password: "Im4G0pH3r",
    },
    {
      id:       2,
      name:     "Rustocaen",
      email:    "rustocean@example.com",
      password: "iT$Ru$t0C34n",
    },
  }

  out, err := json.MarshalIndent(users, "", "    ")
  if err != nil {
    fmt.Printf("serialization error: %s\n", err.Error())
    return
  }

  fmt.Println(string(out))
}

Решение задачи опубликуем в комментариях.

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии4

Что почитать начинающим разработчикам на Go

Привет, Хабр! Меня зовут Алексей Артамонов, я лид команды интеграции в «Островке». Сделал подборку, что можно почитать для старта работы с Go:

  • «The Go programming language» — азы для старта. Хотя синтаксис в Go простой, важно уметь из этих простых вещей собирать сложные конструкции. 

  • Effective Go — практическое пособие для создания тех самых сложных конструкций.

  • «Сто ошибок в Go» — ещё одна хорошая книга. Заход со стороны «как делать не надо».

  • В различных обучающих программах очень много внимания уделяют монолитам, микросервисам и в принципе архитектуре. Но правда в том, что джун или мидл вряд ли столкнётся со столь глобальными задачами. Ему важнее уметь разбить свою логику по классам, пакетам, модулям. Важно писать качественный код. Для этого обязательно рекомендую книгу «Good code, bad code».

  • Много полезного в книге «Принципы юнит-тестирования». Хорошие юнит-тесты неразрывно связаны с тем, как приложение разбито на модули, какие есть связи и зависимости.

  • Два блога-рассылки: GoLang Blog и Awesome Go Weekly.

  • Подкасты довольно сложны для восприятия в фоновом режиме. Особенно для новичков. Но если очень хочется: GoTime, GoPodcast и GoGetPodcast.

Обучение пройдёт легче, если уже знать какой-нибудь язык программирования. К примеру, в «Островке» два главных языка — Python и, собственно, Go. Главный секрет — желание и практика. Если хочешь стать программистом — надо сесть и начать кодить. Ни одна книга без практики не поможет стать программистом.

Теги:
Всего голосов 15: ↑15 и ↓0+20
Комментарии2

Всем привет, прошел уже 1 месяц с того момента как я опубликовал свою первую статью на habr и около 2,5 месяцев с первого дня разработки моей игры. В этом посте я бы хотел рассказать о прогрессе, которого я смог достичь за то время, которое прошло с момента последней публикации.

В обновлении я добавил такое как:

  • Возможность разобрать блоки обратно в материалы

  • Добавил множество строительных блоков и блоков интерьера

  • Переписал процедурный генератор мира и добавил новые структуры

  • Добавил рабочие инструменты и обновил принцип добычи материалов, теперь вам нужно иметь кирку, чтобы добывать камень, вам нужно иметь топор, чтобы добывать древесину

  • Написал систему проигрывания саундтреков

  • Теперь обновления мира из новых версий игры вносятся в старый игровой мир, таким образом все новые структуры будут доступны также и в старом мире

  • Провел оптимизацию рисовку игрового мира

  • Теперь игра доступна не только для Windows, но еще и для Linux

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

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии3

6 июня. Golang meetup в московском офисе Ситидрайва

6 июня ждем вас в московском офисе Ситидрайва на камерный Golang митап!

Инженеры из команды Ситидрайва, VK рекламы и E-com Tech расскажут о сервисах на Golang: только кейсы из практики и личный опыт. В завершение каждого доклада можно будет задать вопросы и пообщаться со спикерами в неформальной обстановке. 

Программа:

18:15-18:30 | Сбор в офисе Ситидрайва, знакомство и Welcome

18:30-19:00 | Доклад «Не Go единым»

Спикер: Вячеслав Морозов — Head of Backend разработки клиентских сервисов в Ситидрайве

19:10-19:40 | Доклад “Использование Kafka с Golang: Оптимизация эффективности обработки сообщений”

Спикер: Симоне Кабрино — Руководитель команды в e-com.tech (ранее samokat.tech), которая разрабатывает Customer Data Platform

19:40-20:10 | Нетворкинг

20:10-20:40 | Доклад «Жизнь в продакшене сервиса на Go»

Спикер: Иван Ремень — Руководитель разработки рекламного ядра в VK рекламе

20:45-21:15 | Доклад «C? Go? Cgo! — Интеграция библиотек на C в проектах на Golang»

Спикер: Иван Сорокин — Руководитель команды разработки, которая отвечает за все финансовые истории внутри приложения Ситидрайва

21:15-22:00 | Нетворкинг

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

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

До встречи!

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

Go SDK
Будучи скромным гофером хочу отметить, что решение тех или иных задач - требует понимание базы и идиом языка. Конечно, есть замечательная документация, есть не менее замечательный хаб, но пока самые-самые сердечки это репозитория go, где в центре внимания легендарный пакет runtime и sync.
Вот несколько примеров, как описан sync.Map в коде, комментарии к которому и реализация методов отвечает на многие вопросы

//...
// Load, LoadAndDelete, LoadOrStore, Swap, CompareAndSwap, and CompareAndDelete
// are read operations; Delete, LoadAndDelete, Store, and Swap are write operations;
// LoadOrStore is a write operation when it returns loaded set to false;
// CompareAndSwap is a write operation when it returns swapped set to true;
// and CompareAndDelete is a write operation when it returns deleted set to true.
type Map struct {
//...
// Range may be O(N) with the number of elements in the map even if f returns
// false after a constant number of calls.
func (m *Map) Range(f func(key, value any) bool) {
	// We need to be able to iterate over all of the keys that were already
	// present at the start of the call to Range.
	// If read.amended is false, then read.m satisfies that property without
	// requiring us to hold m.mu for a long time.
	read := m.loadReadOnly()
	if read.amended {
		// m.dirty contains keys not in read.m. Fortunately, Range is already O(N)
		// (assuming the caller does not break out early)...
    ...

Всем приятного копания базы и профессионального роста.

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

В go 1.22 провели изящный рефакторинг части когда по увеличение емкости среза на x1.25 относительно порога значения емкости в 256.
Не большой тест на arm M1 Pro:

const threshold = 256 
//v 1.21
func BenchmarkName121(b *testing.B) {  
  var newcap = threshold  
  var newLen = 100_000_000_000  
  for 0 < newcap && newcap < newLen {   
    newcap += (newcap + 3*threshold) / 4 
  }  
  if newcap <= 0 {   
    newcap = newLen  
  }
}

//v 1.22
func BenchmarkName122(b *testing.B) {
  var newcap = threshold 
  var newLen = 100_000_000_000  
  for {    
    newcap += (newcap + 3*threshold) >> 2    
    if uint(newcap) >= uint(newLen) {   
      break   
    }  
  }
}

В 8 из 10 прогонов результат одинаковый, в оставшихся - 121 показывает лучший результат
В 8 из 10 прогонов результат одинаковый, в оставшихся - 121 показывает лучший результат

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии1

Питонисты! В 19:00 начинаем транслировать Selectel Python Meetup.

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

Смотрите трансляцию прямо в этом посте или переходите на YouTube.

Теги:
Всего голосов 8: ↑8 и ↓0+8
Комментарии0

28 марта в 19:00 мы проведем Selectel Python Meetup для разработчиков, техлидов и тимлидов разработки. Соберем экспертов из Selectel, Банка Точка и Yandex.Cloud. Обсудим «еще один» быстрый фреймворк, плюсы и минусы чистой архитектуры, опыт перехода с Python на Go.

Темы докладов:

  • «Черная овечка на фоне FastAPI»,

  • «Слоистая архитектура в Python-приложениях: гибкость кода vs оптимизация»,

  • «Перешел с Python на Go. Лучше стало?».

Регистрируйтесь на митап — будем ждать вас в онлайн-трансляции или в офисе Selectel.

Регистрация →

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

На GitHub под лицензией Apache License 2.0 опубликован проект под названием Nuke v1.1.0. Это реализация арены памяти для Go с бенчмарками и даже реализацией параллельной арены.

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

  • повышение производительности: распределяя память большими блоками, арены памяти сокращают накладные расходы, связанные с частыми вызовами системного распределителя памяти;

  • Улучшенная локальность кэша. Арены памяти также могут улучшить локальность кэша, размещая тесно связанные объекты в одном блоке памяти;

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

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

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Проклятие дженериков 💀

Дженерики могут показаться очень простой темой.
Например, вот так в Java выглядят классные и простые методы интерфейса List:

interface List<E> extends Collection<E> {
	boolean add(E e);
	E set(int index, E element);
}

Но у обобщений много нюансов: вложенность, вариантность, границы и т.д. Это сильно усложняет их использование.
Вот не менее классный, но совсем непростой flatMap интерфейса Stream🙈:

interface Stream<T> extends BaseStream<T, Stream<T>> {
	<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
}

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

Из-за таких сложностей, в языке Go (философия которого - простота и минимализм) дженерики появились аж через 12 лет после релиза языка. А первый коммент про то что нужны дженерики появился меньше чем через 24 часа🙃

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

  • С++ вышел в 1979, дженерики - 1986

  • Java - 1996, дженерики - 2004

  • C# - 2001, дженерики - 2005

  • Go - 2009, дженерики - 2021

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии8

Ближайшие события

Поделитесь с командой создателей Go своими отзывами о разработке с помощью этого языка программирования.

Опрос для разработчиков Go 2024 открыт, и мы хотим услышать ваше мнение!

С 2016 года данные опросов разработчиков Go помогают нам определять ключевые модели использования, понимать проблемы разработчиков, узнавать предпочтения в отношении инструментов и отслеживать новые тенденции в сообществе. Ваши отзывы очень важны для формирования будущего Go, поэтому, пожалуйста, уделите 10–15 минут, чтобы заполнить опрос до 11 февраля 2024 года. Примите участие в опросе прямо сейчас!

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

Теги:
Рейтинг0
Комментарии0

Хитрый способ в PostgreSQL перебрать всю таблицу медленно и аккуратно, но эффективно, используя указатель ссылающийся на конкретный tuple - ctid.

	var endBlock int
	row := db.QueryRow(ctx, `select relpages from pg_class where oid = 'table1'::regclass::oid`)
	err = row.Scan(&endBlock)
	if err != nil {
		return
	}

	startBlock := 0
	blocksPerIteration := 50
	maxTuplesPerBlock := 150

	for {
		var rows pgx.Rows
		rows, err = db.Query(ctx, `
				select id
				from table1
				where ctid = any (
					array(
    					select format('(%s, %s)', a, b)::tid
    					from generate_series($1::int, $2::int) a(a)
							cross join generate_series(0, $3) b(b)
					))
					and value = '100000'`,
			startBlock,
			startBlock+blocksPerIteration,
			maxTuplesPerBlock,
		)
		if err != nil {
			return
		}
		var id int
		for rows.Next() {
			err = rows.Scan(&id)
			if err != nil {
				return
			}

			slog.Info("found row", "id", id)
		}
		rows.Close()

		startBlock += blocksPerIteration
		if startBlock > endBlock {
			break
		}
		time.Sleep(100 * time.Millisecond)
	}

Нюансы:

  • из-за того что тип tid не оптимизирует операции больше/меньше, приходится использовать ctid = any (...)

  • для определения maxTuplesPerBlock можно использовать запрос

select 8096 / min(x)
from (
    select pg_column_size(table1) x
    from table1 tablesample system(1)
) d
  • можно делать не только select , но и update и delete, но помнить что строки могут и перемещаются как внутри блока, так и между ними

Теги:
Рейтинг0
Комментарии2

Небольшой пример как копировать данные между базами данных используя go, pgx, и copy.

Предположим что у нас есть два коннекта к базе (одной или нескольким, это не важно). Далее используя io.Pipe() создаём Reader и Writer, и используя CopyTo() и CopyFrom() переносим данные.

  r, w := io.Pipe()

  go func() {
      _, err := db1.PgConn().CopyTo(ctx, w, `copy table1 to stdout binary`)
      if err != nil {
          slog.Error("error", "err", err)
          return
      }
      _ = w.Close()
  }()

  _, err = db2.PgConn().CopyFrom(ctx, r, `copy table1 from stdin binary`)
  _ = r.Close()

Вся прелесть тут в том что используем наиболее быстрый способ с точки зрения PostgreSQL.

Используя copy (select * from where ... order by ... limit ...) to stdout можем регулировать нагрузку на чтение, следить за прогрессом и управлять копированием данных.

В качестве Reader может выступать что угодно, хоть файл csv, хоть другая СУБД, но тогда данные придётся дополнительно конвертировать в формат понимаемый PostgreSQL - csv или tsv, и использовать copy ... from stdin (format csv).

Нюанс: copy ... from stdin binary , binary обязывает использовать одинаковые типы данных, нельзя будет integer колонку перенести в колонку smallint, если такое требуется, то параметр binary надо опустить.

Весь код туть. И ещё немного кода для вдохновения.

Теги:
Рейтинг0
Комментарии0

Вклад авторов