Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
448 - Telegram Web
Telegram Web
💬 Что из себя представляет концепция channels of channels?

Это концепция в Go, которая предусматривает использование каналов для передачи других каналов.

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

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

📌 Разберем на примере:


package main

import (
"fmt"
)

func main() {
// Создаём канал, который будет передавать каналы
ch := make(chan chan int)

// Горутина, которая получает канал из ch и отправляет данные через него
go func() {
newCh := <-ch
newCh <- 42
}()

// Создаём новый канал для передачи данных
newCh := make(chan int)

// Отправляем новый канал через ch
ch <- newCh

// Получаем данные из newCh
fmt.Println(<-newCh) // Вывод: 42
}


👉 Подробнее
👍11🔥2
🚀 Выжимаем из Go максимум производительности: по мотивам доклада на Saint HighLoad++

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

📌 Вы узнаете:

• про память, а именно про small-size объекты и интерфейс;
• как сильно может влиять на производительность BCE (Bounds Check Elimination) и почему не все циклы for-loop одинаково полезны;
• про особенности, которые текущий компилятор Go накладывает на код;
• про оптимальную конвертацию string -> []byte и []byte -> string, конкатенацию и связанные с ней оптимизации.

👉 Читать статю
👍7
💬 Что такое рекурсия и для каких целей она может использоваться?

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

Распространенный пример — вычисление факториала положительного целого числа, то есть произведения всех положительных целых чисел, меньших или равных n:


package main

import "fmt"

func factorial(n int) int {
if n < 1 {
return 1
}
return n * factorial(n-1)
}

func main() {
fmt.Println(factorial(11)) // 39916800
}


Выделяют три вида рекурсии:

🔸 Прямая: функция вызывает саму себя.
🔸 Косвенная: цепочка вызовов включает более одной функции.
🔸 Хвостовая: рекурсивный вызов стоит последней операцией в функции.

Рекурсия широко используется в программировании для решения целого ряда задач:

🔸 Математические расчеты, в которых следующее значение получается на основе предыдущего.
🔸 Реализация алгоритмов и структур данных.
🔸 Разбиение сложных задач на простые.
🥱8👍1
Самые полезные каналы для программистов в одной подборке!

Сохраняйте себе, чтобы не потерять 💾

🔥Для всех

Библиотека программиста — новости, статьи, досуг, фундаментальные темы
Книги для программистов
IT-мемы
Proglib Academy — тут мы рассказываем про обучение и курсы
Азбука айтишника — здесь мы познаем азы из мира программирования

🤖Про нейросети
Библиотека робототехники и беспилотников | Роботы, ИИ, интернет вещей
Библиотека нейрозвука | Транскрибация, синтез речи, ИИ-музыка
Библиотека нейротекста | ChatGPT, Gemini, Bing
Библиотека нейровидео | Sora AI, Runway ML, дипфейки
Библиотека нейрокартинок | Midjourney, DALL-E, Stable Diffusion

#️⃣C#

Книги для шарпистов | C#, .NET, F#
Библиотека шарписта — полезные статьи, новости и обучающие материалы по C#
Библиотека задач по C# — код, квизы и тесты
Библиотека собеса по C# — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Вакансии по C#, .NET, Unity Вакансии по PHP, Symfony, Laravel

☁️DevOps

Библиотека devops’а — полезные статьи, новости и обучающие материалы по DevOps
Вакансии по DevOps & SRE
Библиотека задач по DevOps — код, квизы и тесты
Библиотека собеса по DevOps — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования

🐘PHP

Библиотека пхпшника — полезные статьи, новости и обучающие материалы по PHP
Вакансии по PHP, Symfony, Laravel
Библиотека PHP для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по PHP — код, квизы и тесты

🐍Python

Библиотека питониста — полезные статьи, новости и обучающие материалы по Python
Вакансии по питону, Django, Flask
Библиотека Python для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Python — код, квизы и тесты

Java

Книги для джавистов | Java
Библиотека джависта — полезные статьи по Java, новости и обучающие материалы
Библиотека Java для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Java — код, квизы и тесты
Вакансии для java-разработчиков

👾Data Science

Книги для дата сайентистов | Data Science
Библиотека Data Science — полезные статьи, новости и обучающие материалы по Data Science
Библиотека Data Science для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Data Science — код, квизы и тесты
Вакансии по Data Science, анализу данных, аналитике, искусственному интеллекту

🦫Go

Книги для Go разработчиков
Библиотека Go разработчика — полезные статьи, новости и обучающие материалы по Go
Библиотека Go для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Go — код, квизы и тесты
Вакансии по Go

🧠C++

Книги для C/C++ разработчиков
Библиотека C/C++ разработчика — полезные статьи, новости и обучающие материалы по C++
Библиотека C++ для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по C++ — код, квизы и тесты
Вакансии по C++

💻Другие каналы

Библиотека фронтендера
Библиотека мобильного разработчика
Библиотека хакера
Библиотека тестировщика
Библиотека разработчика игр | Gamedev, Unity, Unreal Engine
Вакансии по фронтенду, джаваскрипт, React, Angular, Vue
Вакансии для мобильных разработчиков
Вакансии по QA тестированию
InfoSec Jobs — вакансии по информационной безопасности

📁Чтобы добавить папку с нашими каналами, нажмите 👉сюда👈

Также у нас есть боты:
Бот с IT-вакансиями
Бот с мероприятиями в сфере IT

Мы в других соцсетях:
🔸VK
🔸YouTube
🔸Дзен
🔸Facebook *
🔸Instagram *

* Организация Meta запрещена на территории РФ
👍1
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

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

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
💬 Что из себя представляет netpoller в контексте Go?

Netpoller — это механизм, встроенный в рантайм Go, который занимается мониторингом сетевых сокетов для I/O операций, используя модели мультиплексирования событий, такие как epoll на Linux, kqueue на BSD системах и macOS, и IOCP на Windows.

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

Когда Go-программа выполняет сетевую операцию, она регистрирует соответствующий сокет в netpoller.
🔸 Netpoller отслеживает эти сокеты и уведомляет Go рантайм, когда один из них готов для выполнения I/O операции.
🔸 Это уведомление передается планировщику Go, который назначает выполнение соответствующей горутины, связанной с этим сокетом.
👍133🔥2
💬 Что из себя представляют методы в Go?

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

Возьмем для примера тип Vertex и добавим к нему метод Square, указав ресивер с именем v и типом *Vertex:


package main

import "fmt"

type Vertex struct {
X, Y int
}

func (v *Vertex) Square() { метод к типу *Vertex
v.X *= v.X
v.Y *= v.Y
}

func main() {
vert := &Vertex{3, 4}
fmt.Println(vert) // &{3 4}
vert.Square()
fmt.Println(vert) // &{9 16}
}


Метод Square изменяет значения полей X и Y структуры Vertex на их квадраты. Вызов vert.Square() изменяет vert на &{9 16}.

Помимо структур можно также создавать свои версии стандартных составных типов — структур, срезов или ассоциативных массивов — и присоединять к ним свои методы. Например, объявим новый тип MyMap, версию стандартного ассоциативного массива map[string]int, и присоединим к нему метод Length:


package main

import "fmt"

type MyMap map[string]int

func (m MyMap) Length() int {
return len(m)
}

func main() {
mm := MyMap{"A": 1, "B": 2}
fmt.Println(mm) // map[A:1 B:2]
fmt.Println(mm["A"]) // 1
fmt.Println(mm.Length()) // 2
}


Результатом является новый тип MyMap, отображающий строки в целые числа подобно map[string]int, но имеющий дополнительный метод Length, который возвращает количество элементов в массиве.
👍16🥱71
💬 Как можно проверить тип переменной во время выполнения в Go?

В Go мы можем использовать switch для проверки типа переменной во время выполнения. Он называется type switch.

Рассмотрим пример, где мы проверяем тип переменной v и выполняем определенный набор операций.
switch v := param.(type) {
default:
fmt.Printf("Unexpected type %T", v)
case uint64:
fmt.Println("Integer type")
case string:
fmt.Println("String type")
}
👍19🥱1
💬 Есть четыре микросервиса: A → B → C → D. Как обеспечить согласованность данных?

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

1. Распределенный мьютекс для синхронизации доступа к общим ресурсам и предотвращения гонок данных.
2. Распределенные транзакции для обеспечения атомарности операций между микросервисами можно использовать протокол двухфазного коммита (2PC). Это гарантирует, что все изменения будут применены одновременно или откатятся в случае ошибки.
3. Паттерн Saga, который представляет собой набор локальных транзакций. Каждая локальная транзакция обновляет базу данных и публикует сообщение или событие, инициируя следующую локальную транзакцию в саге. Если транзакция завершилась неудачей, например, из-за нарушения бизнес правил, тогда сага запускает компенсирующие транзакции, которые откатывают изменения, сделанные предшествующими локальными транзакциями.
🤔92👍2
🏃 Самоучитель по Go для начинающих. Часть 14. Интерфейсы ввода-вывода. Буферизация. Работа с файлами. Пакеты io, bufio, os

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

👉 Читать гайд

📌 Остальные части в серии:

1. Особенности и сфера применения Go, установка, настройка
2. Ресурсы для изучения Go с нуля
3. Организация кода. Пакеты, импорты, модули. Ввод-вывод текста.
4. Переменные. Типы данных и их преобразования. Основные операторы
5. Условные конструкции if-else и switch-case. Цикл for. Вложенные и бесконечные циклы
6. Функции и аргументы. Области видимости. Рекурсия. Defer
7. Массивы и слайсы. Append и сopy. Пакет slices
8. Строки, руны, байты. Пакет strings. Хеш-таблица (map)
9. Структуры и методы. Интерфейсы. Указатели. Основы ООП
10. Введение в ООП. Наследование, абстракция, полиморфизм, инкапсуляция
11. Обработка ошибок. Паника. Восстановление. Логирование
12. Обобщенное программирование. Дженерики
13. Работа с датой и временем. Пакет time
👍3
💬 Как горутина, выполняющая блокирующий системный вызов, перемещается в глобальную очередь готовых к выполнению горутин в рантайме Go. Какие этапы проходят при этом?

Когда горутина выполняет блокирующий системный вызов, она блокируется и рантайм Go временно паркует её, освобождая поток (M) для выполнения других горутин.

После завершения блокирующей операции горутина разблокируется и перемещается в глобальную очередь готовых к выполнению горутин. Планировщик Go затем выбирает горутину из глобальной очереди и назначает её на доступный поток (M) с логическим процессором (P) для продолжения выполнения.

📌 Пример:

package main

import (
"fmt"
"net/http"
"time"
)

func main() {
go fetch("http://example.com")
fmt.Println("Fetching started")
time.Sleep(5 * time.Second)
}

func fetch(url string) {
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error fetching URL:", err)
return
}
defer resp.Body.Close()
fmt.Println("Fetched", url, "with status:", resp.Status)
}


Он демонстрирует, как горутина fetch блокируется на HTTP-запросе, освобождает поток, и после завершения системного вызова возвращается в глобальную очередь для продолжения выполнения.
👍8👾32
💬 Назовите основные юзкейсы для контекста WithoutCancel.

Основные кейсы для использования context.WithoutCancel (Go 1.21+) включают ситуации, когда необходимо гарантировать завершение определенных операций независимо от отмены родительского контекста. В таких случаях WithoutCancel помогает изолировать часть логики, которая не должна прерываться. Вот несколько конкретных примеров:

1. Фоновые задачи: когда необходимо выполнять фоновую операцию, такую как обновление кеша или периодическая синхронизация данных, важно, чтобы эти процессы не прерывались отменой основного контекста. Использование WithoutCancel гарантирует, что такие фоновые задачи продолжат выполнение до завершения.
2. Логирование и мониторинг: в системах, где логирование критически важно, необходимо гарантировать, что операции записи логов завершатся, даже если родительский контекст был отменен. Это помогает сохранить целостность логов и иметь полную информацию о произошедших событиях.
3. Rollback: в случае возникновения ошибки в транзакции или критической операции необходимо гарантировать, что операции отката будут выполнены полностью, даже если основной контекст был отменен. Это важно для поддержания согласованности данных.
4. Задачи с высоким приоритетом завершения: некоторые задачи должны быть завершены независимо от внешних факторов. Это могут быть операции, связанные с безопасностью, или критически важные операции системы.
12👍7
💬 Нужно ли лочить структуру мьютексом, если идет конкурентная запись в разные поля структуры?

В Go структура данных не является автоматически потокобезопасной. Даже если мы записываем в разные поля структуры из разных горутин, могут возникнуть проблемы с синхронизацией, такие как race conditions.

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

Рассмотрим пример структуры с двумя полями, которые обновляются конкурентно:


package main

import (
"fmt"
"sync"
)

type Data struct {
Field1 int
Field2 int
mu sync.Mutex
}

func main() {
d := &Data{}

var wg sync.WaitGroup

// Запись в Field1
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
d.mu.Lock()
d.Field1 = i
d.mu.Unlock()
}
}()

// Запись в Field2
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
d.mu.Lock()
d.Field2 = i
d.mu.Unlock()
}
}()

wg.Wait()
fmt.Println("Field1:", d.Field1)
fmt.Println("Field2:", d.Field2)
}


1. Мы используем мьютекс (d.mu.Lock() и d.mu.Unlock()) для защиты записи в структуру Data. Даже если запись происходит в разные поля структуры, мьютекс гарантирует, что только одна горутина имеет доступ к структуре в любой момент времени.
2. Использование мьютекса предотвращает гонки данных и гарантирует корректное обновление полей структуры.

Если известно, что запись в разные поля не приведет к гонкам данных (например, поля абсолютно независимы и нет побочных эффектов), можно обойтись без мьютекса. Однако это решение требует глубокого понимания контекста и потенциальных рисков.
👍211
Ответьте на 3 вопроса, чтобы получить вводные занятия к курсу «Алгоритмы и структуры данных»

🔥Получите вводные занятия, ответив на 3 вопроса – https://proglib.io/w/e500f583

На вводной части вас ждут:

1. Лекция «Производительность алгоритмов» от руководителя разработки Яндекс.Самокатов;

2. Лекция «Итеративные сортировки и линейные сортировки» от аспирант департамента искусственного интеллекта ВШЭ;

3. Практические задания после лекций;

4. Ссылки на дополнительные материалы для самостоятельного изучения.

⚡️Переходите и начинайте учиться уже сегодня – https://proglib.io/w/e500f583
Please open Telegram to view this post
VIEW IN TELEGRAM
💬 Как использовать string canonicalization для экономии памяти?

В Go, строки неизменяемы и часто одинаковые строки могут иметь разные блоки памяти. String canonicalization позволяет этим строкам делить один и тот же блок памяти, что может значительно сэкономить память. Рассмотрим два способа реализации на Go.

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


func CanonicalizeStrings(ss []string) {
type S struct {
str string
index int
}
var temp = make([]S, len(ss))
for i := range temp {
temp[i] = S {
str: ss[i],
index: i,
}
}

for i := 0; i < len(temp); {
var k = i+1
for j := k; j < len(temp); j++ {
if temp[j].str == temp[i].str {
temp[j].str = temp[i].str
temp[k], temp[j] = temp[j], temp[k]
k++
}
}
i = k
}

for i := range temp {
ss[temp[i].index] = temp[i].str
}
}


2️⃣ Использование unique.Handle, представленного в Go 1.23.

Этот способ более удобен и гибок:


import "unique"

func CanonicalizeString(s string) string {
return unique.Make(s).Value()
}

func CanonicalizeStrings(ss []string) {
for i, s := range ss {
ss[i] = CanonicalizeString(s)
}
}
👍61
💬 Как итерироваться по рунам в строке Go?

Для получения рун в строке достаточно использовать конструкцию for-range.

for i, rune := range aString {
... // используем руну
}


Руна может состоять из 1-4 байтов в кодировке UTF-8. Здесь i является начальным индексом байтов руны. Если нам нужно не только получить сами руны, но и их длину, удобным способом будет использование пакета unicode/utf8:

import "unicode/utf8"

var str = aString
for {
rune, size := utf8.DecodeRuneInString(str)
if size == 0 {
break
}
str = str[size:]

... // используем руну
}
💵⚡️ДАРИМ 40 000₽ ЗА ВИДЕО

Конкурс года в «Библиотеке программиста»: смонтируйте короткий вертикальный ролик формата Shorts/Reels* на тему программирования и разработки — лучший автор получит 40 тысяч рублей 🤑

Подробные условия:
➡️смонтируйте короткий смешной вертикальный ролик (можно и нужно использовать мемы)
➡️отправьте нам в бота @ProglibContest_bot
➡️лучшие ролики (по мнению редакции) мы будем выкладывать в канал и в наш инстаграм*
➡️тот, чей ролик соберет больше всего просмотров в инстаграм*, получит приз — 40 тысяч рублей

Какие ролики мы не принимаем:
😟не вашего авторства (проверим!)
😟длинные, невертикальные, несмешные

Таймлайн:
2 августа — заканчиваем принимать видео
⬇️
3 августа — начинаем загружать лучшие видео в инстаграм
⬇️
9 августа — подводим итоги

*Организация Meta признана экстремистской в РФ
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
✍️ «Библиотека программиста» находится в поиске автора на написание книжных рецензий

Кто нужен?
● Энтузиасты (джуны и выше), которые которые разбираются в IT
● Любители книг, которые хотели бы получать деньги за чтение и написание рецензий
● Работаем с самозанятыми (компенсируем налог), ИП

Мы предлагаем частичную занятость и полностью удаленный формат работы — можно совмещать с основной и находиться в любом месте🌴

✉️ Станьте частью нашей команды — присылайте резюме и примеры работ hello@proglib.io
💬 Как получить адреса байтов строки в Go?

1. Использование unsafe до версии Go 1.22. До версии Go 1.22 получение адресов байтов строки было возможно только через пакет unsafe. Это небезопасный способ, но он работает:


package main

import (
"unsafe"
)

func main() {
str := "Hello, Go!"
addr := unsafe.StringData(str)
println(addr, string(*addr))
}


2. Использование reflect с версии Go 1.23

Начиная с версии Go 1.23, метод reflect.Value.UnsafePointer позволяет получить адреса байтов строки:


package main

import (
"reflect"
)

func main() {
str := "Hello, Go!"
addr := (*byte)(reflect.ValueOf(str).UnsafePointer())
println(addr, string(*addr))
}


3. Конвертация строки в срез байтов. С версии Go 1.22 была добавлена оптимизация, которая позволяет конвертировать строки в срезы байтов без копирования памяти, если байты не будут изменяться. Это позволяет безопасно получать адреса байтов строки:


package main

func main() {
str := "Hello, Go!"
byteSlice := []byte(str)
addr := &byteSlice[0]
println(addr, string(*addr))
}
🔥5👍1
💬 Перечислите все способы клонирования срезов на Go?

1️⃣ Использование make и copy


cloned := make(SliceType, len(aSlice))
copy(cloned, aSlice)


2️⃣ Более развернутая форма 1 способа


var cloned SliceType
if aSlice != nil {
cloned = make(SliceType, len(aSlice))
copy(cloned, aSlice)
}


3️⃣ Использование make и append


append(make(SliceType, 0, len(aSlice)), aSlice...)


4️⃣ Использование append


append(SliceType(nil), aSlice...) // Вариант 1
// или
append(SliceType{}, aSlice...) // Вариант 2


5️⃣ Другой способ использования append


append(aSlice[:0:0], aSlice...)


6️⃣ Использование slices.Clone (Go 1.21+)


import "slices"
slices.Clone(aSlice)
👍17🥱10
2025/07/12 19:57:57
Back to Top
HTML Embed Code: