Golang | Вопросы собесов
4.42K subscribers
38 photos
753 links
Download Telegram
🤔 Как устроен массив?

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

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

Горутины в 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
👍4🔥21
🤔 Как устроен слайс?

Это гибкая структура, представляющая ссылку на часть массива. Он включает указатель на массив, длину (len) и ёмкость (cap) — максимальное количество элементов, которое может быть добавлено без перераспределения памяти.

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

Концепции объектно-ориентированного программирования (ООП) реализованы несколько иначе, чем в традиционных ООП-языках, таких как Java или C++. Не использует классы, наследование и полиморфизм на основе классов в привычном понимании. Вместо этого он применяет интерфейсы, структуры и встраивание для достижения гибкости и мощи ООП.

🟠Структуры вместо классов
Основной способ организации и капсуляции данных — это структуры (structs). Структуры объединяют данные в одну сущность, но в отличие от классов, они не включают определение методов внутри себя. Вместо этого методы определяются отдельно и ассоциируются со структурой через определение получателя метода.
type Person struct {
Name string
Age int
}

func (p Person) Greet() string {
return "Hello, my name is " + p.Name
}


🟠Интерфейсы для полиморфизма
Реализуется через интерфейсы. Интерфейс — это набор сигнатур методов. Тип считается реализующим интерфейс, если он имеет все методы, указанные в интерфейсе. Важной особенностью интерфейсов в Go является то, что типы могут удовлетворять интерфейсам неявно, без специального объявления.
type Greeter interface {
Greet() string
}

func GreetSomeone(g Greeter) {
fmt.Println(g.Greet())
}


🟠Встраивание для композиции
Один из способов реализации композиции — встраивание структур. Можно встроить одну структуру в другую, что позволяет делегировать часть работы встроенной структуре.
type Employee struct {
Person
Position string
}

func (e Employee) Work() string {
return e.Name + " is working as a " + e.Position
}


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

1. С помощью литерала: s := []int{1, 2, 3}.
2. Через функцию make: s := make([]int, length, capacity).
3. Срезав массив: s := array[start:end].


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

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

🚩Чтобы избежать deadlock, нужно следовать этим принципам

🟠Грамотно проектировать порядок блокировок
Если несколько горутин используют блокировки (например, через мьютексы), убедитесь, что все они захватывают их в одном и том же порядке.
func main() {
var mu1, mu2 sync.Mutex

go func() {
mu1.Lock()
defer mu1.Unlock()

mu2.Lock()
defer mu2.Unlock()
}()

go func() {
mu2.Lock()
defer mu2.Unlock()

mu1.Lock()
defer mu1.Unlock()
}()
}


🟠Не блокировать каналы навсегда
Каналы должны всегда иметь возможность отправки и получения данных. Если одна сторона (отправитель или получатель) заблокирована навсегда, возникает deadlock.
func main() {
ch := make(chan int)
ch <- 42 // Deadlock, так как никто не читает из канала
}


🟠Закрывайте каналы правильно
Каналы нужно закрывать только со стороны отправителя, и только тогда, когда больше не будет отправок данных. Неправильное закрытие или отсутствие закрытия может привести к проблемам, включая deadlock.
ch := make(chan int)
close(ch) // Закрыт слишком рано
ch <- 42 // Паника


🟠Избегайте ситуаций с ожиданием себя
Иногда deadlock происходит, если горутина ждет сама себя.
func main() {
ch := make(chan int)
ch <- 1
fmt.Println(<-ch) // Никогда не выполнится
}


🟠Использовать тайм-ауты и селекторы
Go позволяет избегать блокировок с помощью механизма тайм-аутов и оператора select. Если операция занимает слишком много времени, можно выполнить альтернативное действие.
func main() {
ch := make(chan int)

select {
case data := <-ch:
fmt.Println("Получены данные:", data)
case <-time.After(1 * time.Second):
fmt.Println("Тайм-аут, завершение")
}
}


🟠Используйте инструменты анализа
Go предоставляет утилиту go run -race, которая помогает выявлять гонки данных и другие проблемы, связанные с синхронизацией.
go run -race main.go


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

Это nil. Такой слайс имеет длину и ёмкость равные нулю и не ссылается на какой-либо массив.

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

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

🚩Свойства ключей

🟠Сравнимость
Ключи должны поддерживать операцию сравнения с использованием оператора ==. Это необходимо для проверки равенства ключей при выполнении операций вставки, поиска и удаления в карте.

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

🚩Допустимые типы ключей

Булевый тип (bool)
  m := map[bool]string{
true: "Yes",
false: "No",
}


Целочисленные типы (int, int8, int16, int32, int64, а также их беззнаковые эквиваленты uint, uint8, uint16, uint32, uint64)
  m := map[int]string{
1: "One",
2: "Two",
}


Числа с плавающей точкой (float32, float64)
  m := map[float64]string{
1.1: "One point one",
2.2: "Two point two",
}


Строки (string)
  m := map[string]int{
"Alice": 25,
"Bob": 30,
}


Составные типы (структуры, массивы), при условии, что все их поля также поддерживают сравнение с помощью оператора ==
  type Key struct {
FirstName string
LastName string
}

m := map[Key]int{
{"Alice", "Smith"}: 1,
{"Bob", "Johnson"}: 2,
}


🚩Недопустимые типы ключей

🟠Срезы (slice)
Срезы не поддерживают операцию сравнения с использованием оператора == (только сравнение с nil).
🟠Карты (map)
Карты не поддерживают операцию сравнения.
🟠Функции (func)
Функции не поддерживают операцию сравнения.

package main

import "fmt"

type Person struct {
FirstName string
LastName string
}

func main() {
// Создаем карту с ключами типа Person
m := make(map[Person]int)

// Вставляем значения в карту
m[Person{"Alice", "Smith"}] = 25
m[Person{"Bob", "Johnson"}] = 30

// Выводим значения из карты
fmt.Println(m[Person{"Alice", "Smith"}]) // Выводит: 25
fmt.Println(m[Person{"Bob", "Johnson"}]) // Выводит: 30
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что такое nil-слайс и чем отличается

Это слайс, который не ссылается на массив. Он отличается от пустого слайса, который ссылается на массив нулевой длины, но также имеет len и cap равные нулю.

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

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

🚩Зачем это нужно

🟠Ограничение области видимости переменных
Переменные, объявленные внутри блока {}, видимы только в пределах этого блока. Это полезно для временных переменных, которые не должны "загрязнять" основную область видимости функции.
func processData() {
{
value := 42
fmt.Println("Внутренний блок, value =", value) // value доступна только здесь
}
// fmt.Println(value) // Ошибка: value не определена за пределами блока
}


🟠Управление временем жизни ресурсов
С помощью блоков можно явно управлять временем жизни переменных, таких как файлы, соединения или буферы. Это особенно важно для ресурсов, которые необходимо закрыть или освободить.
func readFile() {
{
file, err := os.Open("example.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close() // Закроется при выходе из блока

// Работа с файлом
fmt.Println("Чтение файла")
}
// Здесь файл уже закрыт
}


🟠Локализация кода для улучшения читаемости
В больших функциях дополнительный блок позволяет логически разделить код на части, делая его более понятным.
func main() {
{
// Работа с настройками
config := loadConfig()
fmt.Println("Конфигурация загружена:", config)
}

{
// Работа с данными
data := fetchData()
fmt.Println("Данные получены:", data)
}
}


🟠Проверка и тестирование отдельных блоков
Можно использовать дополнительные блоки для изоляции сложных кусков кода и последующего их упрощения.
func calculate() int {
result := 0
{
a := 10
b := 20
result = a + b
}
return result
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Можно ли добавлять элементы в nil-слайс?

Да, в nil-слайс можно добавлять элементы с помощью append, так как он автоматически выделяет память для нового массива.

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

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

🚩Что произойдет при сложении строк?

🟠Создание новой строки
Когда вы складываете строки, Go создает новую строку, содержащую все символы исходных строк, соединенных друг за другом. Исходные строки при этом остаются неизменными.
s1 := "Hello"
s2 := "World"
result := s1 + " " + s2
fmt.Println(result) // Output: Hello World


🟠Новая строка размещается в памяти
Так как строки в Go неизменяемы, результирующая строка создается заново, а память для нее выделяется в куче или на стеке, в зависимости от размера и контекста.

🚩Особенности сложения строк в Go

🟠Эффективность
Сложение строк через оператор + может быть неэффективным при множественных операциях, так как каждый раз создается новая строка, а старые промежуточные результаты удаляются сборщиком мусора.
result := ""
for i := 0; i < 5; i++ {
result += "Go"
}
fmt.Println(result) // Output: GoGoGoGoGo


🟠Использование `strings.Builder` для оптимизации
Если требуется объединить много строк, рекомендуется использовать strings.Builder. Это более эффективный способ, так как Builder работает с буфером и избегает лишних аллокаций.
   import "strings"

func main() {
var builder strings.Builder
for i := 0; i < 5; i++ {
builder.WriteString("Go")
}
fmt.Println(builder.String()) // Output: GoGoGoGoGo
}


🚩Особенности Unicode

Go строки поддерживают Unicode, поэтому сложение строк корректно работает с многобайтовыми символами.
s1 := "Привет"
s2 := "Мир"
result := s1 + " " + s2
fmt.Println(result) // Output: Привет Мир


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

Проверить длину слайса: len(slice) == 0. Nil-слайс также будет считаться пустым, так как его длина равна нулю.

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

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

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

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

🟠Хэш-таблица
Массив фиксированного размера, где каждый элемент называется "корзиной" (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
👍7
🤔 Как можно добавить элементы в слайс?

Используйте функцию append:
1. Добавление одного элемента: slice = append(slice, element).
2. Добавление нескольких элементов: slice = append(slice, elements...).
3. Слияние с другим слайсом: slice = append(slice, otherSlice...).


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

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

🚩Основные способы проверки работы горутины через каналы

🟠Односторонний канал для завершения горутины
Горутина может отправлять сигнал (например, true) в канал, чтобы уведомить о своем завершении.
func worker(done chan bool) {
fmt.Println("Работа началась...")
time.Sleep(2 * time.Second) // Имитация работы
fmt.Println("Работа завершена!")
done <- true // Отправляем сигнал в канал
}

func main() {
done := make(chan bool)

go worker(done) // Запускаем горутину

// Ожидаем сигнал завершения
<-done
fmt.Println("Основной поток: горутина завершена")
}


🟠Канал для передачи промежуточных результатов
Горутина может отправлять данные в канал, чтобы сигнализировать о прогрессе выполнения.
func worker(progress chan int) {
for i := 1; i <= 5; i++ {
fmt.Printf("Шаг %d выполнен\n", i)
progress <- i // Отправляем номер шага в канал
time.Sleep(500 * time.Millisecond) // Имитация работы
}
close(progress) // Закрываем канал после завершения работы
}

func main() {
progress := make(chan int)

go worker(progress) // Запускаем горутину

// Считываем данные из канала
for step := range progress {
fmt.Printf("Получен сигнал: шаг %d завершен\n", step)
}
fmt.Println("Все шаги выполнены!")
}


🟠Тайм-ауты и проверка работы через `select`
Если важно знать, работает ли горутина, но при этом нужно ограничить ожидание, используется оператор select с тайм-аутом.
func worker(status chan string) {
time.Sleep(2 * time.Second) // Имитация работы
status <- "Горутина завершена"
}

func main() {
status := make(chan string)

go worker(status)

select {
case msg := <-status:
fmt.Println(msg)
case <-time.After(1 * time.Second): // Тайм-аут 1 секунда
fmt.Println("Горутина работает слишком долго")
}
}


🟠Закрытие канала как индикатор завершения
Закрытие канала может служить сигналом того, что горутина завершила свою работу.
func worker(done chan struct{}) {
fmt.Println("Горутина работает...")
time.Sleep(2 * time.Second)
fmt.Println("Горутина завершена!")
close(done) // Закрываем канал
}

func main() {
done := make(chan struct{})

go worker(done)

// Проверяем, когда канал закроется
<-done
fmt.Println("Основной поток: горутина завершила работу")
}


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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что возвращает оператор "квадратные скобки" для строки ?

Оператор "квадратные скобки" ([]) при применении к строке используется для доступа к отдельным байтам в этой строке. Строки представлены как последовательности байтов, и оператор [] позволяет получить байт по указанному индексу.

package main

import (
"fmt"
)

func main() {
str := "hello"

// Получаем байт по индексу
firstByte := str[0]

// Выводим байт и его символ
fmt.Printf("Первый байт: %d\n", firstByte) // Выводит: 104
fmt.Printf("Первый символ: %c\n", firstByte) // Выводит: h
}


🚩Объяснение

1⃣Доступ к байту
В этой строке кода мы получаем байт, расположенный по индексу 0 в строке str. В данном случае это байт, соответствующий символу 'h'.
firstByte := str[0]   


2⃣Вывод байта в числовом формате
Здесь мы выводим байт в виде целого числа. Поскольку символ 'h' имеет ASCII-код 104, вывод будет 104.
fmt.Printf("Первый байт: %d\n", firstByte)   


3⃣Вывод байта как символа
Мы также можем вывести байт как символ, используя формат %c. Это отобразит символ 'h'.
fmt.Printf("Первый символ: %c\n", firstByte)   


🚩Работа с Unicode

Важно понимать, что строки являются последовательностями байтов, а не символов. Это означает, что доступ по индексу с помощью [] дает байт, а не руну (rune). Если строка содержит многобайтовые символы (например, символы Unicode), то доступ по индексу может вернуть только один из байтов, составляющих символ.
package main

import (
"fmt"
)

func main() {
str := "Привет"

// Получаем байт по индексу
firstByte := str[0]

// Выводим байт и его символ
fmt.Printf("Первый байт: %d\n", firstByte) // Выводит: 208
fmt.Printf("Первый символ: %c\n", firstByte) // Выводит: � (неполный символ)
}


Для корректной работы с многобайтовыми символами (рунами) в строках используется преобразование строки в срез рун
package main

import (
"fmt"
)

func main() {
str := "Привет"

// Преобразуем строку в срез рун
runes := []rune(str)

// Получаем руну по индексу
firstRune := runes[0]

// Выводим руну и её символ
fmt.Printf("Первая руна: %d\n", firstRune) // Выводит: 1055 (код Unicode для 'П')
fmt.Printf("Первый символ: %c\n", firstRune) // Выводит: П
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Что такое массив (array)?

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

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