💡 Учимся: Осваиваем Go с нуля, разбираем синтаксис, паттерны и лучшие практики.
⚡️ Практикуем: Пишем код вместе, разбираем ошибки, обсуждаем их.
🤖 Моки & Сервисы: Создаем тестовые API, микросервисы и полезные инструменты в командах.
🎯 Развиваемся: Помогаем друг другу расти как backend-команде.
✅ Пошаговые гайды и туториалы
✅ Разбор реальных кейсов и задач
✅ Совместные проекты и код-ревью
✅ Поддержка комьюнити и ответы на вопросы
📌 Правила просты:
Максимум практики, минимум воды
Делимся знаниями и опытом
Готов прокачаться в Go
Please open Telegram to view this post
VIEW IN TELEGRAM
Приветствую всех любителей Go! 🥳
📌 Меня зовут Рома, и я разработчик на Go уже больше 5 лет. За это время я не только успел поработать над множеством интересных проектов, но и приобрел ценный опыт, которым хочу поделиться с вами в роли ментора🖱
Почему Go – отличный выбор, и почему вам стоит ко мне присоединиться➡️
➡️ Простота и эффективность: Go славится своим чистым и лаконичным синтаксисом, благодаря чему его легко изучать и поддерживать. Этот язык идеально подходит для создания высокопроизводительных и масштабируемых приложений.
➡️ Современность: Go был разработан Google с учетом потребностей современной разработки. Он отлично справляется с параллельным программированием, что делает его идеальным для создания распределенных систем.
➡️ Востребованность: Go – один из самых востребованных языков на рынке труда. Компании активно ищут Go-разработчиков для работы над облачными сервисами, микросервисной архитектурой и другими передовыми технологиями.
➡️ Огромное сообщество: Сообщество Go – одно из самых дружелюбных и активных в мире программирования. Вы всегда найдете помощь, поддержку и вдохновение.
💬 Что я предлагаю как ментор:
🔘 Индивидуальный подход: Я подстрою программу обучения под ваши цели и уровень подготовки.
🔘 Практические навыки: Мы будем работать над реальными проектами, чтобы вы смогли применить свои знания на практике.
🔘 Разбор сложных тем: Я помогу вам разобраться с самыми сложными концепциями Go, такими как горутины, каналы, интерфейсы и т.д.
🔘 Карьерные советы: Я поделюсь своим опытом работы в индустрии и помогу вам подготовиться к собеседованиям.
🟢 Особенности работы со мной:
Я верю в практическое обучение и активное взаимодействие. Мы будем не только изучать теорию, но и писать много кода, разбирать ошибки и делиться опытом. Я всегда на связи и готов ответить на ваши вопросы, а также предоставить конструктивную обратную связь.
Если вы хотите начать свой путь в мир Go или улучшить свои навыки, я буду рад стать вашим проводником!💻
Пишите мне в личные сообщения, чтобы узнать больше о программе менторства и записаться на пробное занятие.🐈
#go #golang #программирование #менторство #разработка #обучение #google #разработчик
Почему Go – отличный выбор, и почему вам стоит ко мне присоединиться
Я верю в практическое обучение и активное взаимодействие. Мы будем не только изучать теорию, но и писать много кода, разбирать ошибки и делиться опытом. Я всегда на связи и готов ответить на ваши вопросы, а также предоставить конструктивную обратную связь.
Если вы хотите начать свой путь в мир Go или улучшить свои навыки, я буду рад стать вашим проводником!
Пишите мне в личные сообщения, чтобы узнать больше о программе менторства и записаться на пробное занятие.
#go #golang #программирование #менторство #разработка #обучение #google #разработчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1 1
Что выведет код?
#код
func main() {
s := make([]int, 0, 5)
s = append(s, 1, 2, 3)
f := func(sl []int) {
sl = append(sl, 4)
sl[0] = 10
}
f(s)
s = append(s, 5)
fmt.Println(s)
}#код
Создается слайс len=0 и cap=5, далее в него записываем 1, 2, 3. Массив родитель не аллоцировался, так как до cap мы еще не дошли.
sl - копия s
Мы добавили в sl 4 и поменяли первый элемент(помним в голове, что sl ссылается на тот же массив родитель), и получается, что у sl len=4, cap=5. Массив родитель в памяти выглядит так: [10 2 3 4]
Довольные выходим из функции, и приходим к s, у которого len=3, cap=5 (мы же с ним ничего не делали). И получается, что массив родитель [10 2 3 4], но len у него 3, то есть по сути сам s выглядит как [10 2 3]. И как раз-таки при append мы добавляем 5 в ячейку где уже была 4, и перезаписываем ее
Please open Telegram to view this post
VIEW IN TELEGRAM
1 3🔥2❤1👍1
Хотели бы вы принять участие в бесплатном практическом созвоне, где мы напишем с нуля базовый микросервис на Go?
Anonymous Poll
66%
Да, интересно! Хочу посмотреть на реальный процесс разработки
29%
Возможно, зависит от темы и времени
6%
Нет, не интересно
Благодаря этому написание моков и подмена слоев на любую другую реализацию (например, юзали библиотеку БД gorm, а в v2-версии слоя решили перейти на самописные SQL запросы) превращается из боли и страданий, в кайф и красоту. На моем опыте я раз 20 переписывал слои сервиса, чтобы их просто замокать и сделать тесты, потому что все завязывались на реализации сущностей
type Speaker interface {
Speak() string
}
type Duck struct {
Name string
}
func (d Duck) Speak() string {
return fmt.Sprintf("%s говорит Кря", d.Name)
}
type Pigeon struct {
Name string
}
func (c Pigeon) Speak() string {
return fmt.Sprintf("%s говорит Гули-Гули", c.Name)
}
func main() {
animals := []Speaker{
Duck{Name: "Утка"},
Pigeon{Name: "Голубь"},
}
for _, a := range animals {
a.Speak()
}
}Please open Telegram to view this post
VIEW IN TELEGRAM
👏2 2❤1
Что выведет код?
#код
func main() {
mainSl := []string{"Test", "slices", "copying"}
var sl []string
copy(sl, mainSl)
sl1 := make([]string, 1, 3)
copy(sl1, mainSl)
fmt.Println(sl, sl1)
}#код
Код выведет:
Anonymous Poll
44%
[] [Test]
22%
[Test, slices, copying] [Test, slices, copying]
4%
[] [Test, slices, copying]
26%
Паника, копирование в nil-слайс
4%
[] []
😁2 2👏1 1
Лучшее объяснение этого вывода состоит в идее copy. Предназначена эта функция для копирования элементов слайса-родителя в слайс-ребенок, отвязывая от ссылки на массив родитель
То есть, если есть выделенная под элемент ячейка слайса, то copy сделает свою работу, а вот если ячейки не оказалось, то copy просто пожимает плечами.
Теперь важный момент на понимание слайса: выделенные ячейки - это не cap! Это len! Ровно по этому числу мы понимаем сколько проинициализированных ячеек в слайсе
В sl мы ничего не получили по причине того, что инициализация вида
var sl []string
это инициализация nil-слайса, у которого нет ни длины, ни капасити
💡Во втором примере у sl1 уже установлена длина 1 и капасити 3, следовательно copy переносит в инициализированную ячейку элемент
На просторах коммерческой разработки мало встречал использования этой функции, хотя и не понимаю почему
func main() {
sl := []int{1, 2, 3, 4}
part := sl[:2]
partByCopy := make([]int, 2)
copy(partByCopy, sl)
// Изменим sl, чтобы показать наследование ссылки на массив-родитель
sl[0] = 5
fmt.Println(part, partByCopy)
// Получаем вывод:[5 2] [1 2] -> получение базового ломтика, приводит к риску мутаций, в отличие от copy
}Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2 2
Давайте согласуем удобное время для мита по написанию микросервиса
Anonymous Poll
19%
Сегодня
15%
25 июня
19%
26 июня
11%
27 июня
67%
Выходные
Что произойдет при запуске программы?
#код
var m = map[string]int{"a": 1}
func main() {
go Read()
time.Sleep(1 * time.Second)
go Write()
time.Sleep(1 * time.Minute)
}
func Read() {
for {
fmt.Println(m["a"])
}
}
func Write() {
for i := 0; ; i++ {
m[fmt.Sprintf("%d", i)] = i
}
}#код
Голосуем за время воскресного мита
Anonymous Poll
11%
11:00
17%
12:00
44%
17:00
28%
21:00
17%
Не могу в вс🙁
Go Level Up
Что произойдет при запуске программы? var m = map[string]int{"a": 1} func main() { go Read() time.Sleep(1 * time.Second) go Write() time.Sleep(1 * time.Minute) } func Read() { for { fmt.Println(m["a"]) } } func Write() { for i := 0;…
📌При запуске программы произойдет - бесконечный вывод 1 и фатальная ошибка fatal error: concurrent map read and map write
➡️Важно! Данный результат произойдет при версии го, где мапа реализована в виде бакетов, то есть до swiss table. Какой результат будет в новой версии, требует отдельного поста.➡️
💻Итак, вернемся к нашей старой доброй мапе на бакетах. Каждый раз, когда показываю менти этот код, они вчитываются в код и пытаются найти здесь скрытый смысл. Но нет, по сути все, что достаточно увидеть - чтение и запись в мапу из горутин 🔜🔜🔜 ошибка. Дело в том, что мапа не потокобезопасна. 🥳
➡️На моках постоянно отвечают так😳Но не понимают почему так и что это значит. Это значит, что как раз-таки из мапы нельзя читать и писать одновременно в связи с вероятностью обратиться к несуществующему эвакуированному куску памяти или вовсе вызвать гонку данных.
💬Причина: при эвакуации старые бакеты постепенно освобождаются и ключи-значения переходят в новые выделенные бакеты бОльшего количества. Так вот когда мы пишем мы сталкиваемся с риском эвакуации, а когда читаем с риском обратиться к несуществующему удаленному блоку памяти или непредсказуемым данным(из-за data race)🖥
➡️Важно! Данный результат произойдет при версии го, где мапа реализована в виде бакетов, то есть до swiss table. Какой результат будет в новой версии, требует отдельного поста.➡️
💻Итак, вернемся к нашей старой доброй мапе на бакетах. Каждый раз, когда показываю менти этот код, они вчитываются в код и пытаются найти здесь скрытый смысл. Но нет, по сути все, что достаточно увидеть - чтение и запись в мапу из горутин 🔜🔜🔜 ошибка. Дело в том, что мапа не потокобезопасна. 🥳
➡️На моках постоянно отвечают так😳Но не понимают почему так и что это значит. Это значит, что как раз-таки из мапы нельзя читать и писать одновременно в связи с вероятностью обратиться к несуществующему эвакуированному куску памяти или вовсе вызвать гонку данных.
💬Причина: при эвакуации старые бакеты постепенно освобождаются и ключи-значения переходят в новые выделенные бакеты бОльшего количества. Так вот когда мы пишем мы сталкиваемся с риском эвакуации, а когда читаем с риском обратиться к несуществующему удаленному блоку памяти или непредсказуемым данным(из-за data race)🖥
👍3❤2 1
type SafeMap struct {
sync.RWMutex
data map[string]int
}
func main() {
protectedMap := SafeMap{
data: map[string]int{"a": 1},
}
go protectedMap.Read()
time.Sleep(1 * time.Second)
go protectedMap.Write()
time.Sleep(1 * time.Minute)
}
func (sm *SafeMap) Read() {
for {
sm.RLock()
fmt.Println(sm.data["a"])
sm.RUnlock()
}
}
func (sm *SafeMap) Write() {
for i := 0; ; i++ {
sm.Lock()
sm.data[fmt.Sprintf("%d", i)] = i
sm.Unlock()
}
}Please open Telegram to view this post
VIEW IN TELEGRAM
Коллеги, спасибо за участие в опросе! Большинство выбрало вариант 17:00. 💻
🖱 Сегодня в 17:00 (МСК) созвон — обсудим как писать микросервис на го. Жду всех!📌
Please open Telegram to view this post
VIEW IN TELEGRAM
Коллеги, созвон по написанию микросервиса начинается. Всех жду
https://us04web.zoom.us/j/79268156565?pwd=dSYcbdVxZC0K0IJx97ubNHgoYIGt8w.1
https://us04web.zoom.us/j/79268156565?pwd=dSYcbdVxZC0K0IJx97ubNHgoYIGt8w.1
Zoom
Join our Cloud HD Video Meeting
Zoom is the leader in modern enterprise cloud communications.
❤4