Golang | Вопросы собесов
الذهاب إلى القناة على Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
إظهار المزيد4 750
المشتركون
لا توجد بيانات24 ساعات
-97 أيام
-3830 أيام
أرشيف المشاركات
Средства для стирки с выгодой!
Скидка 25% на Lenor, Ariel, Tide в Любимой категории
Купить
#реклама
market.yandex.ru
О рекламодателе
🤔 Какие бывают способы оптимизации?
Оптимизация кода в Go может быть выполнена на нескольких уровнях:
🟠Оптимизация алгоритмов и структур данных
Использование более эффективных алгоритмов (например,
O(log n) вместо O(n^2)). Выбор подходящих структур данных (например, map вместо срезов для поиска по ключу).
🟠Оптимизация работы с памятью
Снижение количества аллокаций (использование sync.Pool, предварительное выделение памяти). Использование []byte вместо string, если требуется частое изменение строки. Минимизация копирования данных, например, передача []byte по ссылке вместо копирования.
🟠Оптимизация работы с горутинами
Использование worker pool, чтобы избежать избыточного создания горутин. Ограничение количества параллельных задач (runtime.GOMAXPROCS). Использование каналов правильной ёмкости для минимизации блокировок.
🟠Оптимизация ввода-вывода (I/O)
Буферизация (bufio.Reader, bufio.Writer). Использование асинхронных операций при работе с файлами или сетью. Использование io.Pipe() для потоковой обработки данных.
🟠Использование профилирования и анализа производительности
pprof для анализа CPU, памяти и блокировок. race detector (-race флаг) для выявления проблем с конкурентным доступом. Инструменты трассировки (trace).
🚩Пример оптимизации работы с памятью
Пример неэффективного кода
func inefficient() []string {
var result []string
for i := 0; i < 1000; i++ {
result = append(result, fmt.Sprintf("Item %d", i)) // Частые аллокации
}
return result
}
Оптимизированный вариант
func efficient() []string {
result := make([]string, 0, 1000) // Выделяем память заранее
for i := 0; i < 1000; i++ {
result = append(result, fmt.Sprintf("Item %d", i))
}
return result
}
Ставь 👍 и забирай 📚 Базу знанийЯндекс Музыка до 360 дней бесплатно
Яндекс Музыка для вас и 3-х ваших близких.
Кинопоиск и Яндекс Книги тоже в мультиподписке Плюс.
Попробуйте бесплатно❤️
Слушать
#реклама 18+
music.yandex.ru
О рекламодателе
🤔 Какие циклы есть в Go?
Существует один основной цикл — это цикл for. н может использоваться в различных формах, выполняя функции традиционных циклов
while, do-while и классического for.
🚩Формы цикла
С тремя выражениями
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}
Как while
package main
import "fmt"
func main() {
i := 0
for i < 5 {
fmt.Println(i)
i++
}
}
Бесконечный
package main
import "fmt"
func main() {
i := 0
for {
if i >= 5 {
break
}
fmt.Println(i)
i++
}
}
С использованием range
package main
import "fmt"
func main() {
arr := []int{1, 2, 3, 4, 5}
for index, value := range arr {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
}
🚩Примеры
Итерация по массиву
arr := [5]int{10, 20, 30, 40, 50}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
Итерация по карте
m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
fmt.Printf("Key: %s, Value: %d\n", key, value)
}
Итерация по строке
s := "hello"
for index, char := range s {
fmt.Printf("Index: %d, Char: %c\n", index, char)
}
Ставь 👍 и забирай 📚 Базу знанийУслуги дата-центра в Москве
Размещение и аренда серверного оборудования в дата-центре.
👍 4 современных дата-центра в Москве.
👍 Лицензированный оператор связи.
👍 Индивидуальные конфигурации выделенных серверов под задачи клиента.
👍 Круглосуточная техническая поддержка в Телеграм, без ботов.
Узнать цену
#реклама 16+
itsoft.ru
О рекламодателе
🤔 Как защититься от ошибки во время конкурентной записи в map?
В Go обычный
map не потокобезопасен. Если несколько горутин одновременно записывают в map, возникнет ошибка "fatal error: concurrent map writes".
Решение: использовать синхронизацию через sync.Mutex, sync.RWMutex или sync.Map.
🚩Использование `sync.Mutex` (мьютекс)
Блокируем доступ на запись и чтение через sync.Mutex.
package main
import (
"fmt"
"sync"
)
type SafeMap struct {
mu sync.Mutex
m map[string]int
}
func (s *SafeMap) Set(key string, value int) {
s.mu.Lock() // Блокируем доступ
defer s.mu.Unlock()
s.m[key] = value
}
func (s *SafeMap) Get(key string) int {
s.mu.Lock() // Блокируем на чтение
defer s.mu.Unlock()
return s.m[key]
}
func main() {
safeMap := SafeMap{m: make(map[string]int)}
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
safeMap.Set(fmt.Sprintf("key%d", i), i)
}(i)
}
wg.Wait()
fmt.Println("Готово:", safeMap.Get("key5")) // Получаем значение без гонок данных
}
🚩Использование `sync.RWMutex` (оптимизация для чтения)
sync.RWMutex позволяет нескольким горутинам читать одновременно, но блокирует запись.
type SafeMap struct {
mu sync.RWMutex
m map[string]int
}
func (s *SafeMap) Set(key string, value int) {
s.mu.Lock() // Блокируем только на запись
defer s.mu.Unlock()
s.m[key] = value
}
func (s *SafeMap) Get(key string) int {
s.mu.RLock() // Разрешаем множественное чтение
defer s.mu.RUnlock()
return s.m[key]
}
🟠Использование `sync.Map` (встроенный потокобезопасный `map`)
sync.Map из стандартной библиотеки уже потокобезопасен, но работает немного медленнее обычного map из-за внутренних механизмов.
package main
import (
"fmt"
"sync"
)
func main() {
var m sync.Map
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
m.Store(i, i*10) // Потокобезопасная запись
}(i)
}
wg.Wait()
val, ok := m.Load(5) // Потокобезопасное чтение
if ok {
fmt.Println("Значение:", val)
}
}
Использование канала (`chan`) вместо `map`
Вместо map можно передавать данные через канал (chan), если логика позволяет.
package main
import (
"fmt"
)
func main() {
ch := make(chan map[string]int, 1)
ch <- make(map[string]int)
go func() {
m := <-ch
m["key"] = 42
ch <- m
}()
m := <-ch
fmt.Println(m["key"]) // 42
}
Ставь 👍 и забирай 📚 Базу знанийKafka на практике: продюсеры, консьюмеры, Docker
Хотите увидеть, как реально работает Kafka?
3 августа в 20:00 — вебинар с живыми примерами кода. Поднимем кластер в Docker, создадим топики, напишем продюсеров на Python/Java, настроим консьюмеров с consumer groups. Разберем партиционирование, оффсеты и гарантии доставки.
Для backend-разработчиков, DevOps и всех, кто любит практику.
Узнать больше
#реклама 16+
otus.ru
О рекламодателе
🤔 Как проводить тестирование в Go?
Тестирование в Go реализуется с помощью встроенного пакета testing. Тесты пишутся как функции с именами, начинающимися на Test, принимающими параметр *testing.T. Для запуска тестов используется команда go test. Также доступны инструменты для бенчмарков (Benchmark), покрытия кода тестами (-cover) и работы с примерами (Example).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Получи грант до 1,35 млн руб. на обучение в магистратуре
Хочешь развиваться в сфере ИТ и получить фундаментальные знания с практикой?
Поступай в магистратуру Центрального университета!
— 4 офлайн программы по востребованным направлениям ИТ
— 2 онлайн-программы: машинное обучение и продуктовый менеджмент
— 550 грантов до 75%
— Вечерние занятия и учеба по выходным — удобно совмещать с работой
— Обучение по модели STEM-образования: на стыке науки, технологий и бизнеса
— Возможность стажировок и трудоустройства в ведущих компаниях
— Государственный диплом за 2 года
Магистратура в Центральном университете — это современный подход к образованию, сильный преподавательский состав и актуальные кейсы от индустрии. Оставляй заявку на грант уже сейчас!
Зарегистрироваться
#реклама 16+
cu.ru
О рекламодателе
🤔 Почему нельзя брать ссылку на значение, хранящееся по ключу в map?
Нельзя напрямую взять ссылку на значение, хранящееся по ключу в карте (map), из-за особенностей реализации карт и управления памятью. Рассмотрим подробнее, почему это так.
🚩Причины, почему нельзя брать ссылку на значение в карте
🟠Внутреннее устройство карты (map)
Карты реализованы на основе хеш-таблиц. Внутреннее устройство карты предполагает, что значения могут перемещаться в памяти при выполнении операций, таких как добавление или удаление элементов. Хеш-таблица может перераспределять (реорганизовывать) свои внутренние структуры для оптимизации доступа к элементам. Это может происходить, например, когда карта увеличивается в размере.
🟠Потенциальная недействительность ссылок
Если бы была возможность брать ссылки на значения, хранящиеся в карте, то при любой операции изменения карты (добавление, удаление элементов) ссылки могли бы становиться недействительными. Это привело бы к потенциально небезопасному поведению программы, так как указатель (ссылка) мог бы указывать на уже несуществующую или перемещенную область памяти.
🚩Демонстрация проблемы
Здесь попытка взять ссылку на значение из карты могла бы привести к проблемам
package main
import "fmt"
func main() {
m := map[string]int{"a": 1, "b": 2}
// Нельзя делать так:
// p := &m["a"]
// Вместо этого можно работать с копией значения
value := m["a"]
p := &value
fmt.Println("Value:", *p) // 1
// Изменение карты
m["c"] = 3
// Ссылка на значение в карте могла бы стать недействительной
// fmt.Println("Value after map change:", *p)
}
🚩Правильные способы работы со значениями карты
Для работы с ними лучше использовать копии значений. Вот несколько способов, как это можно сделать:
🟠Работа с копией значения
Получить значение из карты и сохранить его в переменную.
value := m["a"]
🟠Изменение значения в карте
Если необходимо изменить значение в карте, его нужно сначала извлечь, изменить, а затем снова записать в карту.
value := m["a"]
value = value + 10
m["a"] = value
🟠Использование указателей в качестве значений
В некоторых случаях можно использовать указатели в качестве значений карты, чтобы можно было изменять значения через указатели.
package main
import "fmt"
func main() {
m := map[string]*int{"a": new(int), "b": new(int)}
*m["a"] = 1
*m["b"] = 2
// Теперь можно брать указатели на значения
p := m["a"]
fmt.Println("Value:", *p) // 1
// Изменение значения через указатель
*p = 42
fmt.Println("Updated Value:", *m["a"]) // 42
}
Ставь 👍 и забирай 📚 Базу знанийПредзаказ Samsung Galaxy Z серии на сайте МТС!
Оформите предзаказ на Samsung Galaxy Z серии с выгодой до 20 000р. и повышенным кешбэком 10% на сайте МТС! Рассрочка 0-0-24
Узнать больше
#реклама
shop.mts.ru
О рекламодателе
🤔 В чем отличия http 1.1 и http 2?
Это версии протокола HTTP, каждая из которых имеет свои особенности и улучшения по сравнению с предыдущими версиями. Важные различия между этими версиями включают следующие аспекты:
🚩Мультиплексирование
🟠HTTP/1.1
Поддерживает одновременное открытие нескольких TCP соединений (обычно 6-8), что позволяет загружать несколько ресурсов параллельно. Однако каждое соединение может обрабатывать только один запрос за раз, что приводит к задержкам из-за блокировки очереди (head-of-line blocking).
🟠HTTP/2
Вводит мультиплексирование, позволяющее отправлять множество запросов и ответов асинхронно через одно единственное TCP соединение. Это значительно уменьшает задержки и улучшает производительность при загрузке страниц с большим количеством ресурсов.
🚩Бинарный протокол
🟠HTTP/1.1
Является текстовым протоколом, что означает, что запросы и ответы форматируются в виде читаемого текста.
🟠HTTP/2
Бинарный протокол, который делает передачу данных более эффективной и менее подверженной ошибкам в синтаксическом анализе. Бинарный формат упрощает реализацию парсеров и уменьшает размер передаваемых данных.
🚩Сжатие заголовков
🟠HTTP/1.1
Заголовки передаются без сжатия, что может привести к значительному объему передаваемых данных, особенно если одни и те же заголовки отправляются повторно с каждым запросом.
🟠HTTP/2
Использует механизм сжатия заголовков HPACK, который уменьшает избыточность заголовков, сжимая их перед отправкой. Это особенно эффективно для повторяющихся запросов к одним и тем же серверам.
🚩Приоритизация запросов
🟠HTTP/1.1
Не поддерживает приоритизацию запросов, из-за чего браузеры должны использовать эвристики для управления приоритетами ресурсов.
🟠HTTP/2
Поддерживает явную приоритизацию запросов, позволяя клиенту указывать приоритет обработки ресурсов, что делает загрузку страниц более эффективной.
Ставь 👍 и забирай 📚 Базу знаний
Kaspersky Premium со скидкой до 28%
Покупайте Kaspersky Premium со скидкой до 28% и получайте гарантированные ценные подарки от партнёров, а также возможность участовать в розыгрыше путешествия.
Узнать больше
#реклама 16+
kaspersky.ru
О рекламодателе
🤔 Что делает команда kill в Linux:
Команда `kill` в Linux отправляет сигналы процессам. Самым распространенным использованием является отправка сигнала SIGTERM (по умолчанию), который сообщает процессу о необходимости завершения, или SIGKILL, который немедленно прерывает процесс, не позволяя ему корректно завершиться.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Дачная дача в Т-Банк Шопе
Футболки с огурцами, тыквами, капустой и другие крутые штуки, да еще и с финансовыми пожеланиями. Надо брать.
Посмотреть каталог
Финансовые услуги оказывает: АО "Тинькофф Банк".
#реклама
tbank.ru
О рекламодателе
🤔 Что такое iota?
Это предопределенное идентификатор, используемое для создания последовательностей целочисленных констант. Он применяется в контексте объявления констант и автоматически инкрементируется на единицу с каждым новым значением. Обычно используется для определения множества связанных констант без необходимости вручную назначать каждому элементу значение.
🚩Основные характеристики
🟠Инициализация с нуля
Начинает счет с 0 в каждой новой группе констант.
🟠Автоматическое увеличение
Каждое последующее использование
iota в одной группе констант увеличивает его значение на 1.
🟠Повторное использование
При каждом новом объявлении константного блока iota сбрасывается до 0.
package main
import "fmt"
const (
A = iota // 0
B // 1
C // 2
)
func main() {
fmt.Println(A) // Вывод: 0
fmt.Println(B) // Вывод: 1
fmt.Println(C) // Вывод: 2
}
Использование его для создания битовых флагов
package main
import "fmt"
const (
Flag1 = 1 << iota // 1 << 0 = 1
Flag2 // 1 << 1 = 2
Flag3 // 1 << 2 = 4
Flag4 // 1 << 3 = 8
)
func main() {
fmt.Println(Flag1) // Вывод: 1
fmt.Println(Flag2) // Вывод: 2
fmt.Println(Flag3) // Вывод: 4
fmt.Println(Flag4) // Вывод: 8
}
Сброс его в новом блоке
package main
import "fmt"
const (
X = iota // 0
Y // 1
)
const (
Z = iota // 0 (новый блок констант, iota сбрасывается)
W // 1
)
func main() {
fmt.Println(X) // Вывод: 0
fmt.Println(Y) // Вывод: 1
fmt.Println(Z) // Вывод: 0
fmt.Println(W) // Вывод: 1
}
🚩Комплексное использование
Можно использовать в выражениях и совместно с другими константами для создания более сложных последовательностей.
package main
import "fmt"
const (
_ = iota // пропускаем 0
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30 = 1073741824
)
func main() {
fmt.Println("KB:", KB) // Вывод: KB: 1024
fmt.Println("MB:", MB) // Вывод: MB: 1048576
fmt.Println("GB:", GB) // Вывод: GB: 1073741824
}
Ставь 👍 и забирай 📚 Базу знанийОплата на сайте с Яндекс Пэй: ниже отказы, выше продажи
Клиенты оформляют заказ быстрее: оплата через Яндекс Пэй требует минимум действий.
Сохраняйте платёжные данные в аккаунте Яндекса — клиенты платят в один клик.
Интегрируйте кнопку оплаты через готовые модули или по API.
Снижайте отказы и увеличивайте конверсию. Подключите Яндекс Пэй сейчас!
Подать заявку
Финансовые услуги оказывает: АО "Яндекс Банк".
#реклама 16+
pay.yandex.ru
О рекламодателе
🤔 Как устроена объектоориентированная модель?
Объектно-ориентированная модель отличается от традиционных ООП-языков, таких как C# или Java. Нет классов и наследования в привычном понимании. Вместо этого используются структуры (structs) и интерфейсы для реализации основных принципов ООП: инкапсуляции, композиции и полиморфизма.
🚩Концепции
🟠Структуры (Structs)
Служат аналогом классов. Они позволяют объединять данные в логически связанные группы.
type Person struct {
Name string
Age int
}
🟠Методы
Могут быть определены для структур, что позволяет связывать функции с типами.
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s\n", p.Name)
}
🟠Инкапсуляция
Достигается через модификаторы доступа на уровне пакета. Поля и методы, начинающиеся с заглавной буквы, экспортируемые (public), остальные — нет (private).
type Person struct {
name string // неэкспортируемое поле
Age int // экспортируемое поле
}
🟠Композиция
Go не поддерживает классическое наследование. Вместо этого используется композиция для включения функциональности одного типа в другой.
type Employee struct {
Person
Position string
}
🟠Интерфейсы
Используются для определения поведения. Типы могут реализовывать интерфейсы неявно, просто предоставляя методы, указанные в интерфейсе.
type Greeter interface {
Greet()
}
func SayHello(g Greeter) {
g.Greet()
}
type Person struct {
Name string
}
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s\n", p.Name)
}
func main() {
p := Person{Name: "John"}
SayHello(p)
}
🟠Полиморфизм
Достигается через интерфейсы. Любой тип, который реализует интерфейс, может быть использован вместо него.
type Greeter interface {
Greet()
}
func SayHello(g Greeter) {
g.Greet()
}
type Robot struct {
ID string
}
func (r Robot) Greet() {
fmt.Printf("Greetings, I am robot %s\n", r.ID)
}
func main() {
p := Person{Name: "John"}
r := Robot{ID: "XJ-9"}
SayHello(p)
SayHello(r)
}
Ставь 👍 и забирай 📚 Базу знанийRIZALTA RESORT: доходный номер на Алтае от 12 млн ₽
Представьте: вы приезжаете отдыхать на Алтай — и останавливаетесь в собственном номере. А когда вас нет, им управляет профессиональный отельер.
RIZALTA RESORT BELOKURIKHA — гостиничный комплекс с бассейнами, оздоровительными и семейными пространствами.
✅ Номера с ремонтом — от 12 млн ₽.
✅ Прогноз окупаемости — 6 лет.
✅ Доход — от 2 млн ₽ в год.
Управление — ZONT Hotel Group. Покупка по ФЗ-214, проект финансируется Сбером.
Получите презентацию, планировки и персональный расчёт.
Узнать больше
#реклама
rizalta-resort-altay.ru
О рекламодателе
🤔 Что такое Prometheus?
Prometheus – это мощная система мониторинга с временными рядами (time series), которая собирает метрики из сервисов, хранит их и позволяет строить графики и отправлять алерты.
🚩Ключевые особенности Prometheus
Pull-модель – сам запрашивает метрики у сервисов (в отличие от push-модели, как в StatsD).
Формат временных рядов – каждая метрика привязана ко времени и меткам (
labels).
Язык запросов PromQL – позволяет анализировать и агрегировать метрики.
Автодетектирование сервисов – поддержка Kubernetes, Docker, Consul.
Хранение данных в базе TSDB (Time Series Database).
Гибкая система алертов – интеграция с Alertmanager (уведомления в Slack, Telegram и др.).
🚩Как работает Prometheus?
Экспортеры/сервисы предоставляют метрики через HTTP-эндпоинт (/metrics).
Prometheus сам запрашивает данные по расписанию.
Метрики хранятся в базе TSDB.
Можно строить графики в Grafana или запрашивать данные через API.
Алерты отправляются в Alertmanager при достижении пороговых значений.
🚩Пример метрик в Go
Go-сервис может отдавать метрики через HTTP с помощью prometheus/client_golang
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Создаём метрику
var httpRequests = prometheus.NewCounter(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests",
})
func main() {
// Регистрируем метрику
prometheus.MustRegister(httpRequests)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
httpRequests.Inc() // Увеличиваем счётчик при каждом запросе
w.Write([]byte("Hello, Prometheus!"))
})
// Эндпоинт для сбора метрик
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
Пример запроса в PromQL
http_requests_total
Ставь 👍 и забирай 📚 Базу знаний