Golang | Вопросы собесов
4.72K subscribers
30 photos
964 links
Download Telegram
🤔 Куда смотреть, если лагает сервер?

Если сервер "тормозит", важно пошагово анализировать:
- CPU / память / диск: проверить загрузку через мониторинг (htop, top, Prometheus, Grafana).
- Сеть: задержки, потери пакетов, перегрузка порта.
- Логи приложения и системы: ошибки, таймауты, исключения.
- Количество запросов / соединений: возможно, сервер не выдерживает нагрузку.
- База данных: медленные запросы, блокировки.
- Очереди / кэши: переполнение, задержки в обработке.
Всё это помогает локализовать «узкое место».


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что такое 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


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
🤔 Что может быть пустым интерфейсом?

Пустым интерфейсом (interface{}) может быть значение любого типа: числа, строки, структуры или указателя. Это возможно, потому что пустой интерфейс не требует реализации методов, а значит, любая сущность соответствует его требованиям. Например, interface{} часто используется для хранения данных неизвестного типа.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Знакомы ли с концепцией 12FA для проектирования SaaS приложений?

Да, знаком. 12FA (12-Factor App) — это набор принципов, созданных разработчиками Heroku для построения масштабируемых, надежных и удобных в развертывании SaaS-приложений. Эти принципы особенно полезны при разработке облачных сервисов (Cloud-Native).

🚩Основные 12 факторов

🟠Кодовая база (Codebase)
У приложения должна быть единая кодовая база (один репозиторий), независимо от количества развертываний (production, staging, dev).

🟠Зависимости (Dependencies)
Все зависимости должны явно указываться в go.mod / go.sum (для Go). Никаких глобальных зависимостей в системе.

🟠Конфигурация (Config)
Конфигурация должна храниться в переменных окружения, а не в коде.
export DATABASE_URL="postgres://user:pass@host:5432/db"



🟠Бэкенд-сервисы (Backing Services)
Внешние сервисы (БД, кэш, API) должны быть заменяемыми и подключаться через URL (без хардкода).

🟠Постоянная сборка, запуск и запуск (Build, Release, Run)
Сборка, релиз и запуск должны быть разделены. Например, Docker-контейнеры для каждой стадии.

🟠Процессы (Processes)
Приложение должно быть бесстатичным (не хранить файлы локально, использовать БД, S3 и т. д.).

🟠Привязка портов (Port Binding)
Приложение должно быть самодостаточным и слушать порт (например, через http.ListenAndServe).

🟠Параллелизм (Concurrency)
Масштабируемость должна обеспечиваться горизонтальным масштабированием (разделением на процессы).

🟠Отказоустойчивость (Disposability)
Приложение должно быстро запускаться и корректно завершаться (например, ловить SIGTERM).

🟠Совместимость Dev/Prod (Dev/Prod Parity)
Среды разработки и продакшена должны быть максимально похожи.

🟠Логирование (Logs)
Логи должны писаться в стандартный вывод и обрабатываться внешними системами (ELK, Loki, Grafana).

🟠Админ-процессы (Admin Processes)
Скрипты администрирования (миграции, отладка) должны выполняться как отдельные процессы.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
🤔Что такое эвакуация, и в каком случае она будет происходить?

Эвакуация — это перемещение объектов из младшего поколения памяти в старшее при сборке мусора, если объект переживает несколько циклов сборки.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4👍1🔥1
🤔 Как устроен массив в Go?

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

🚩Основные характеристики

🟠Фиксированный размер
Размер массива задается при его объявлении и не может изменяться во время выполнения программы.
🟠Тип элементов
Все элементы массива имеют один и тот же тип.
🟠Непосредственное хранение данных
В отличие от слайсов, массивы хранят свои элементы в непрерывном блоке памяти.

🟠Объявление массива
С указанием типа элементов и фиксированного размера. Это объявление создает массив из пяти целых чисел, инициализированных нулями.
var arr [5]int


🟠Инициализация массива
Массивы могут быть инициализированы при объявлении
arr := [5]int{1, 2, 3, 4, 5}


Можно также инициализировать массив частично, оставив остальные элементы равными нулям:
arr := [5]int{1, 2}


🟠Доступ к элементам
Осуществляется с использованием индексов, начиная с 0
fmt.Println(arr[0]) // 1
arr[1] = 10
fmt.Println(arr[1]) // 10


🟠Длина массива
Фиксирована и задается при его объявлении. Ее можно получить с помощью функции len
fmt.Println(len(arr)) // 5


🟠Копирование массива
При присваивании одного массива другому копируются все элементы:
arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := arr1
arr2[0] = 10
fmt.Println(arr1) // [1 2 3 4 5]
fmt.Println(arr2) // [10 2 3 4 5]


🟠Передача массива в функции
При этом копируется весь массив:
func modifyArray(a [5]int) {
a[0] = 10
}

arr := [5]int{1, 2, 3, 4, 5}
modifyArray(arr)
fmt.Println(arr) // [1 2 3 4 5]


🚩Сравнение

🟠Размер
Массивы имеют фиксированный размер, тогда как слайсы динамичны.

🟠Производительность
Массивы могут быть более производительными для небольших коллекций данных из-за отсутствия накладных расходов на управление динамическими данными.

🟠Гибкость: Слайсы более гибки благодаря динамическому изменению размера и доступным методам.

Использование массивов
package main

import (
"fmt"
)

func main() {
// Объявление и инициализация массива
arr := [5]int{1, 2, 3, 4, 5}

// Доступ к элементам
fmt.Println("First element:", arr[0]) // First element: 1

// Изменение элементов
arr[1] = 10
fmt.Println("Modified array:", arr) // Modified array: [1 10 3 4 5]

// Длина массива
fmt.Println("Length of array:", len(arr)) // Length of array: 5

// Копирование массива
arr2 := arr
arr2[0] = 20
fmt.Println("Original array:", arr) // Original array: [1 10 3 4 5]
fmt.Println("Copied array:", arr2) // Copied array: [20 10 3 4 5]

// Передача массива в функцию
modifyArray(arr)
fmt.Println("Array after modifyArray call:", arr) // Array after modifyArray call: [1 10 3 4 5]
}

func modifyArray(a [5]int) {
a[0] = 10
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Для чего используют индексы?

1. Ускорение поиска – уменьшает количество проверяемых строк.
2. Оптимизация ORDER BY и GROUP BY – индексы помогают быстрее сортировать и группировать данные.
3. Повышение эффективности JOIN – индексы на ключах улучшают соединение таблиц.
4. Поддержка UNIQUE и PRIMARY KEY – гарантируют уникальность данных.
5. Оптимизация полнотекстового поиска – full-text индексы помогают эффективно искать текстовые данные.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 Что такое хэш-таблица?

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

🚩Основные компоненты

🟠Хеш-функция
Функция, которая принимает ключ и преобразует его в индекс массива, называемого "хэш-таблицей". Хорошая хеш-функция распределяет ключи равномерно по хэш-таблице, минимизируя количество коллизий.

🟠Хэш-таблица
Массив фиксированного размера, где каждый элемент называется "корзиной" (bucket). Корзина может содержать одно или несколько значений.

🟠Коллизии
Ситуация, когда два разных ключа хешируются в один и тот же индекс. Коллизии решаются с помощью различных методов, таких как цепочки (chaining) или открытая адресация (open addressing).

🚩Принцип работы

🟠Вставка
Хеш-функция вычисляет индекс для данного ключа. Значение помещается в соответствующую корзину по этому индексу. Если возникает коллизия, используется метод разрешения коллизий.

🟠Поиск
Хеш-функция вычисляет индекс для ключа. Корзина по этому индексу проверяется на наличие значения. Если значение найдено, оно возвращается; если нет, возвращается индикатор отсутствия значения.

🟠Удаление
Хеш-функция вычисляет индекс для ключа. Значение удаляется из соответствующей корзины. При необходимости корректируются ссылки или структура данных для разрешения коллизий.

🚩Плюсы и минусы

Быстрый доступ
Среднее время доступа к элементу составляет O(1).
Простота использования
Обеспечивает простой интерфейс для вставки, поиска и удаления данных.
Коллизии
Требуют дополнительных механизмов для разрешения, что может усложнить реализацию.
Зависимость от хеш-функции
Эффективность хэш-таблицы зависит от качества хеш-функции.
Перераспределение
При увеличении количества элементов может потребоваться перераспределение и увеличение размера таблицы, что временно снижает производительность.

package main

import "fmt"

func main() {
// Создание карты
myMap := make(map[string]int)

// Вставка значений
myMap["Alice"] = 25
myMap["Bob"] = 30

// Поиск значений
value, exists := myMap["Alice"]
if exists {
fmt.Println("Alice:", value) // Alice: 25
} else {
fmt.Println("Alice not found")
}

// Удаление значений
delete(myMap, "Alice")
_, exists = myMap["Alice"]
if !exists {
fmt.Println("Alice has been deleted") // Alice has been deleted
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 В чем ключевое различие слайса от массива?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Есть отличия между SSL и TLS?

Да, между SSL (Secure Sockets Layer) и TLS (Transport Layer Security) есть отличия. TLS является улучшенной и более безопасной версией SSL.

🚩История и версия

🟠SSL:
SSL 1.0: Никогда не был выпущен публично из-за серьезных уязвимостей.
SSL 2.0: Выпущен в 1995 году, но вскоре был признан небезопасным из-за множества уязвимостей.
SSL 3.0: Выпущен в 1996 году, значительно улучшил безопасность, но со временем также был признан устаревшим из-за уязвимостей (например, POODLE-атака).

🟠TLS:
TLS 1.0: Выпущен в 1999 году как обновление SSL 3.0. Включает исправления безопасности и улучшения.
TLS 1.1: Выпущен в 2006 году с дополнительными защитами от некоторых атак.
TLS 1.2: Выпущен в 2008 году, поддерживает современные алгоритмы шифрования и хеширования.
TLS 1.3: Выпущен в 2018 году, значительно улучшена безопасность и производительность, упрощен процесс установки соединения.

🚩Технические отличия

🟠Алгоритмы шифрования:
SSL: Поддерживает более старые и менее безопасные алгоритмы шифрования.
TLS: Поддерживает более современные и безопасные алгоритмы шифрования. TLS 1.3 исключает поддержку устаревших алгоритмов и предлагает только современные безопасные алгоритмы.

🟠Процесс рукопожатия (Handshake):
SSL: Более сложный процесс рукопожатия, включающий несколько шагов, что делает его уязвимым для некоторых атак.
TLS: Улучшенный процесс рукопожатия, включая использование HMAC (Hash-based Message Authentication Code) для обеспечения целостности сообщения. TLS 1.3 значительно упрощает и ускоряет процесс рукопожатия.

🟠Целостность данных:
SSL: Использует комбинацию MD5 и SHA-1 для целостности данных, что не так безопасно по современным стандартам.
TLS: Использует HMAC с SHA-256 и другими современными алгоритмами для обеспечения целостности данных.

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

🚩Безопасность

🟠SSL: Уязвим для ряда атак, таких как POODLE, BEAST и другие, из-за устаревших и менее безопасных методов шифрования и проверки целостности.
🟠TLS: Значительно более безопасен благодаря устранению уязвимостей SSL и внедрению современных методов шифрования и проверки целостности. TLS 1.3 еще более безопасен благодаря исключению устаревших методов и упрощению процесса рукопожатия.

🚩Совместимость

🟠SSL: Практически не используется в современных системах из-за известных уязвимостей и устаревших методов безопасности.
🟠TLS: Широко поддерживается и используется в современных браузерах, серверах и других сетевых устройствах. TLS 1.2 и TLS 1.3 являются наиболее часто используемыми версиями.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как инкапсуляция осуществлена в Golang?

В Go инкапсуляция достигается через модификаторы доступа, управляемые первой буквой имени: заглавная буква делает элемент экспортируемым (публичным), а строчная — доступным только в пакете (приватным).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Forwarded from easyoffer
Новая фича на easyoffer Автоотлики

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

🚀 Запуск занимаем всего 3 минуты, а экономит очень много времени
🛡 Это безопасно: easyoffer официально одобрен HeadHunter и прошел его модерацию.
🥷🏻 Автоотклик незаметен для рекртера. Автоотклик ничем не отличается от обычного отклика, который вы делаете вручную

Рекрутеры давно используют автоматизацию для поиска кандидатов. Так почему вы должны откликаться вручную?

💡Совет – Добавьте шаблон сопроводительного письма, чтобы откликаться на большее количество вакансий (на некоторые вакансии нельзя откликнуться без сопроводительного)

Попробовать бесплатно → https://easyoffer.ru/autoapply
🤔2
🤔 Как происходит поиск по ключу в map?

Карты (maps) реализованы на основе хеш-таблиц, что обеспечивает быстрый доступ к значениям по ключам. Давайте рассмотрим, как происходит поиск по ключу в карте, и какие этапы включены в этот процесс.

🚩Основные этапы

🟠Хеширование ключа
Сначала вычисляется хеш-значение ключа. Функция хеширования преобразует ключ в целое число, которое служит индексом в хеш-таблице.

🟠Поиск в хеш-таблице
Хеш-значение используется для доступа к соответствующей "ячейке" или "корзине" (bucket) в хеш-таблице.

🟠Поиск в корзине
Если корзина содержит несколько элементов (из-за коллизий хеширования), Go выполняет линейный поиск среди этих элементов, сравнивая ключи с использованием оператора ==.

🚩Детали

🟠Хеширование ключа
Когда вы пытаетесь получить значение по ключу, Go сначала вычисляет хеш-значение этого ключа. Хеш-функция берет ключ (например, строку или целое число) и преобразует его в индекс хеш-таблицы.

🟠Доступ к корзине
Хеш-значение указывает на конкретную корзину в хеш-таблице. Корзина может содержать один или несколько элементов. В случае коллизий (когда несколько ключей хешируются в один и тот же индекс) корзина может содержать связанный список или другой механизм для хранения нескольких элементов.

🟠Линейный поиск внутри корзины
Если корзина содержит несколько элементов, Go выполняет линейный поиск среди этих элементов. Для каждого элемента в корзине сравнивается ключ с искомым ключом с использованием оператора ==. Если ключи совпадают, возвращается соответствующее значение. Если ключ не найден, возвращается нулевое значение типа (zero value) и флаг, указывающий на отсутствие ключа.

package main

import "fmt"

func main() {
myMap := map[string]int{
"Alice": 25,
"Bob": 30,
}

value, exists := myMap["Alice"]
if exists {
fmt.Println("Alice:", value) // Alice: 25
} else {
fmt.Println("Alice not found")
}

value, exists = myMap["Charlie"]
if exists {
fmt.Println("Charlie:", value)
} else {
fmt.Println("Charlie not found") // Charlie not found
}
}


🚩Подводные камни и особенности

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

🟠Производительность
В среднем, доступ к элементу в карте осуществляется за константное время O(1), что делает карты очень эффективными для поиска по ключу. Однако в худшем случае, при большой нагрузке коллизий, производительность может деградировать до линейного времени O(n).

🟠Изменение карты во время поиска
Карты не являются потокобезопасными. Если одна горутина изменяет карту, в то время как другая горутина читает из нее, это может привести к панике. Для обеспечения потокобезопасности используйте мьютексы или структуру sync.Map.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊3
🤔 В чем разница процесса и потока в рамках операционной системы?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 По какому алгоритму растет slice?

В Go срезы (slice) динамически изменяемы, и при добавлении новых элементов их вместимость (capacity) увеличивается по определённому алгоритму.

🚩Как растёт `slice` в Go?

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

🚩Алгоритм роста:

Если cap(slice) < 1024, то новая ёмкость (capacity) удваивается.
Если cap(slice) >= 1024, то увеличение идёт примерно на 25% от текущего размера.

package main

import "fmt"

func main() {
var s []int
prevCap := cap(s)

for i := 0; i < 20; i++ {
s = append(s, i)
if cap(s) != prevCap {
fmt.Printf("Len: %d, New Cap: %d (growth: %.2fx)\n", len(s), cap(s), float64(cap(s))/float64(prevCap))
prevCap = cap(s)
}
}
}


Выходные данные (может отличаться в зависимости от реализации Go)
Len: 1, New Cap: 1 (growth: Inf)
Len: 2, New Cap: 2 (growth: 2.00x)
Len: 3, New Cap: 4 (growth: 2.00x)
Len: 5, New Cap: 8 (growth: 2.00x)
Len: 9, New Cap: 16 (growth: 2.00x)
Len: 17, New Cap: 32 (growth: 2.00x)


🚩Почему так?

🟠Экономия памяти
если бы рост был на 1 элемент, то это вызывало бы частые копирования.
🟠Скорость работы
экспоненциальный рост уменьшает количество выделений памяти.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🤔 Что будет, если сложить строки?

При сложении строк с помощью + создаётся новая строка, объединяющая обе:
Такая операция безопасна, но при множественных склеиваниях может быть неэффективной — лучше использовать буферы или массив + .joined().


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4👍2
🤔 Назови преимущества горутин перед потоками ОС?

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

Легковесность
Горутины потребляют значительно меньше памяти и ресурсов по сравнению с потоками ОС. Каждая горутина стартует с размером стека порядка 2 КБ, тогда как поток ОС требует гораздо большего размера стека (обычно несколько мегабайт).

Планировщик Go
Горутины управляются встроенным планировщиком Go, а не планировщиком ОС. Планировщик Go распределяет выполнение горутин по доступным потокам ОС, используя концепцию "M:N" (много горутин на несколько потоков).

Отсутствие необходимости ручного управления
Создание, синхронизация и управление горутинами намного проще благодаря встроенным средствам Go, таким как каналы (channels) и sync-пакет. В то время как работа с потоками ОС требует дополнительных усилий для синхронизации (мьютексы, условные переменные и т.д.).

Автоматическое управление стеком
Стек горутины автоматически увеличивается или уменьшается в зависимости от потребностей, что позволяет эффективно использовать память.

Простота и удобство
Синтаксис и использование горутин интуитивно понятны. Для запуска достаточно добавить go перед вызовом функции:

package main

import (
"fmt"
"time"
)

func sayHello() {
for i := 0; i < 5; i++ {
fmt.Println("Hello")
time.Sleep(100 * time.Millisecond)
}
}

func main() {
go sayHello() // Запускаем горутину
fmt.Println("World")
time.Sleep(1 * time.Second) // Даем горутине время завершиться
}


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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Какой тип многозадачности используется в Go и какой был до версии Go 1.15?

Go использует кооперативную (мягкую) многозадачность. Это значит, что переключение между горутинами происходит не по системному таймеру, а в определённых точках выполнения, например при вызове функций ввода-вывода, channel-операций или при runtime.Gosched().
До Go 1.14 переключение происходило реже, потому что не было прерываний по таймеру. С Go 1.14+ появилась возможность принудительного прерывания при помощи механизма async preemption (асинхронное вытеснение), что приблизило поведение к "жёсткой" многозадачности, но в рамках кооперативной модели.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3💊1
🤔 Как можно откопировать слайс?

Слайсы являются ссылочными типами, поэтому простое присваивание одного слайса другому создаст новую ссылку на тот же подлежащий массив. Если вы хотите создать копию слайса с независимым подлежащим массивом, можно использовать встроенную функцию copy или методы, такие как использование append.

🚩Способы копирования слайса

🟠Использование функции `copy`
Создает побайтовую копию элементов из одного слайса в другой.
package main

import "fmt"

func main() {
original := []int{1, 2, 3, 4, 5}

// Создаем новый слайс той же длины, что и оригинал
copySlice := make([]int, len(original))

// Копируем элементы из оригинального слайса в новый
copy(copySlice, original)

// Изменяем элемент в копии
copySlice[0] = 100

fmt.Println("Оригинал:", original) // Выводит: Оригинал: [1 2 3 4 5]
fmt.Println("Копия:", copySlice) // Выводит: Копия: [100 2 3 4 5]
}


Использование функции
inal)   


Чтобы создать новый слайс с копированными элементами.
package main

import "fmt"

func main() {
original := []int{1, 2, 3, 4, 5}

// Копируем элементы из оригинального слайса в новый слайс
copySlice := append([]int(nil), original...)

// Изменяем элемент в копии
copySlice[0] = 100

fmt.Println("Оригинал:", original) // Выводит: Оригинал: [1 2 3 4 5]
fmt.Println("Копия:", copySlice) // Выводит: Копия: [100 2 3 4 5]
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Как создавать и импортировать пакеты?

Создание пакета начинается с указания package packageName в файлах. Импорт пакетов осуществляется через import "packageName". Сторонние пакеты подключаются через Go Modules.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3