Что такое функция copy ?
Спросят с вероятностью 8%
Функция copy используется для копирования элементов из одного слайса в другой. Она возвращает количество скопированных элементов, которое будет равно минимальному значению из длины двух слайсов: источника и назначения.
Синтаксис функции
✅
✅
Примеры использования copy
Пример 1: Копирование слайса
Пример 2: Частичное копирование
Если длина слайса назначения меньше длины слайса источника, то копируются только те элементы, которые помещаются в слайс назначения.
Пример 3: Копирование в пустой слайс
Если длина слайса источника меньше длины слайса назначения, то копируются только те элементы, которые имеются в источнике.
Применение функции copy
Часто используется для создания копий слайсов или для работы с подмножествами данных. Она может быть полезна в различных ситуациях, таких как:
✅Изменение части слайса.
✅Создание независимой копии слайса, чтобы изменения в копии не затрагивали исходный слайс.
✅Реализация алгоритмов, требующих манипуляций с массивами данных.
Функция
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Функция copy используется для копирования элементов из одного слайса в другой. Она возвращает количество скопированных элементов, которое будет равно минимальному значению из длины двух слайсов: источника и назначения.
Синтаксис функции
func copy(dst, src []T) int
✅
dst: слайс назначения (куда будут копироваться элементы).✅
src: слайс источника (откуда будут копироваться элементы).Примеры использования copy
Пример 1: Копирование слайса
package main
import "fmt"
func main() {
src := []int{1, 2, 3, 4, 5}
dst := make([]int, 5) // Создаем слайс назначения длиной 5
n := copy(dst, src) // Копируем элементы из src в dst
fmt.Println("Copied elements:", n) // 5
fmt.Println("Destination slice:", dst) // [1 2 3 4 5]
}
Пример 2: Частичное копирование
Если длина слайса назначения меньше длины слайса источника, то копируются только те элементы, которые помещаются в слайс назначения.
package main
import "fmt"
func main() {
src := []int{1, 2, 3, 4, 5}
dst := make([]int, 3) // Создаем слайс назначения длиной 3
n := copy(dst, src) // Копируем элементы из src в dst
fmt.Println("Copied elements:", n) // 3
fmt.Println("Destination slice:", dst) // [1 2 3]
}
Пример 3: Копирование в пустой слайс
Если длина слайса источника меньше длины слайса назначения, то копируются только те элементы, которые имеются в источнике.
package main
import "fmt"
func main() {
src := []int{1, 2, 3}
dst := make([]int, 5) // Создаем слайс назначения длиной 5
n := copy(dst, src) // Копируем элементы из src в dst
fmt.Println("Copied elements:", n) // 3
fmt.Println("Destination slice:", dst) // [1 2 3 0 0]
}
Применение функции copy
Часто используется для создания копий слайсов или для работы с подмножествами данных. Она может быть полезна в различных ситуациях, таких как:
✅Изменение части слайса.
✅Создание независимой копии слайса, чтобы изменения в копии не затрагивали исходный слайс.
✅Реализация алгоритмов, требующих манипуляций с массивами данных.
Функция
copy является полезным инструментом для копирования элементов между слайсами. Она возвращает количество скопированных элементов и автоматически обрабатывает случаи, когда длина слайсов различается.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍2
Как в Go пишут unit тесты со стандартным пакетом testing ?
Спросят с вероятностью 8%
Модульные тесты (unit tests) пишутся с использованием стандартного пакета
Как это делается:
1️⃣Создание тестового файла: Тестовые файлы должны иметь суффикс
2️⃣Написание тестовых функций: Тестовые функции должны начинаться с
3️⃣Использование метода `t.Errorf` или
Допустим, у нас есть простая функция для сложения двух чисел в файле
Создадим тест для этой функции в файле
Детали:
1️⃣Импорт пакетамер,
2️⃣Определение тестовой функции: Функция должна принимать один аргумент типа
3️⃣Проверка результата: Внутри тестовой функции вы вызываете тестируемую функцию, проверяете результат и используете методы
Расширенные возможности:
✅Табличные тесты: Полезны для тестирования нескольких сценариев с разными входными данными и ожидаемыми результатами.
Чтобы запустить тесты, используйте команду:
Эта команда автоматически находит все файлы с суффиксом
Модульные тесты пишутся с использованием стандартного пакета
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Модульные тесты (unit tests) пишутся с использованием стандартного пакета
testing. Они направлены на проверку отдельных функций или методов в изоляции, чтобы убедиться, что каждая функция работает корректно.Как это делается:
1️⃣Создание тестового файла: Тестовые файлы должны иметь суффикс
_test.go. Например, если у вас есть файл math.go, тестовый файл для него будет называться math_test.go.2️⃣Написание тестовых функций: Тестовые функции должны начинаться с
Test, а их имя должно быть описательным. Например, TestAdd для функции Add.3️⃣Использование метода `t.Errorf` или
t.Fatalf: Эти методы позволяют сообщать о провале теста. t.Errorf продолжает выполнение тестов после ошибки, а t.Fatalf завершает выполнение текущего теста.Допустим, у нас есть простая функция для сложения двух чисел в файле
math.go:// file: math.go
package math
func Add(a, b int) int {
return a + b
}
Создадим тест для этой функции в файле
math_test.go:// file: math_test.go
package math
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
expected := 5
if result != expected {
t.Errorf("Add(2, 3) = %d; expected %d", result, expected)
}
}
Детали:
1️⃣Импорт пакетамер,
TestAd Это обязательный шаг для использования функций и типов, предоставляемых пакетом testing.2️⃣Определение тестовой функции: Функция должна принимать один аргумент типа
*testing.T. Это структура, предоставляемая пакетом testing, которая используется для логирования и отчета об ошибках.3️⃣Проверка результата: Внутри тестовой функции вы вызываете тестируемую функцию, проверяете результат и используете методы
t.Errorf или t.Fatalf для сообщения о несоответствиях.Расширенные возможности:
✅Табличные тесты: Полезны для тестирования нескольких сценариев с разными входными данными и ожидаемыми результатами.
func TestAddTableDriven(t *testing.T) {
tests := []struct {
a, b int
result int
}{
{1, 1, 2},
{2, 3, 5},
{10, -2, 8},
{-1, -1, -2},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%d+%d", tt.a, tt.b), func(t *testing.T) {
res := Add(tt.a, tt.b)
if res != tt.result {
t.Errorf("Add(%d, %d) = %d; expected %d", tt.a, tt.b, res, tt.result)
}
})
}
}Чтобы запустить тесты, используйте команду:
go test
Эта команда автоматически находит все файлы с суффиксом
_test.go, компилирует их и запускает тестовые функции.Модульные тесты пишутся с использованием стандартного пакета
testing. Они помогают убедиться, что отдельные функции работают правильно. Тесты создаются в файлах с суффиксом _test.go и включают тестовые функции, начинающиеся с Test, которые проверяют результаты работы функций и сообщают о несоответствиях.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍1
Anonymous Quiz
7%
Статические массивы фиксированной длины
91%
Динамические массивы, которые могут изменять размер
1%
Указатели на функции
1%
Каналы для передачи данных
❤1
Anonymous Quiz
21%
Каналы могут передавать значения любого типа.
4%
Отправка данных в канал неблокирующая.
73%
Каналы могут быть буферизированными.
2%
Каналы не поддерживают типизацию.
👀12
Что такое моки (mocks) ?
Спросят с вероятностью 8%
Моки (mocks) – это имитации объектов или компонентов, которые используются в тестировании для замены реальных объектов. Они помогают изолировать тестируемый код, эмулируя поведение зависимостей, таких как базы данных, внешние API или другие сервисы. Это особенно полезно в модульных тестах, где важно проверить функциональность конкретного блока кода без влияния внешних факторов.
Зачем они нужны:
1️⃣Изоляция тестируемого кода: Позволяют тестировать функциональность в изоляции, не затрагивая реальные зависимости.
2️⃣Ускорение тестирования: Исключение реальных зависимостей (например, обращения к базе данных или сетевых вызовов) делает тесты быстрее.
3️⃣Предсказуемость: Обеспечивают контроль над входными данными и поведением зависимостей, что позволяет точно проверять ожидаемое поведение.
4️⃣Удобство тестирования пограничных случаев: Позволяют легко имитировать ошибки и нестандартные ситуации, что бывает сложно с реальными объектами.
Как их использовать:
Для создания их часто используются интерфейсы и специальные библиотеки, такие как
Пример использования с testify/mock:
1️⃣Определение интерфейса:
2️⃣Создание функции, использующей интерфейс:
3️⃣Написание теста с использованием мока:
Объяснение:
1️⃣Определение интерфейса: Интерфейс
2️⃣Использование интерфейса в сервисе: Сервис
3️⃣Создание мока: Мы создаем мок
4️⃣Определение поведения мока: Устанавливаем ожидания, что метод
5️⃣Тестирование сервиса: Проверяем, что метод
Моки – это заменители реальных объектов, используемые в тестировании для изоляции кода, ускорения тестов и создания предсказуемых условий. Для этого часто используют интерфейсы и библиотеки, такие как
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Моки (mocks) – это имитации объектов или компонентов, которые используются в тестировании для замены реальных объектов. Они помогают изолировать тестируемый код, эмулируя поведение зависимостей, таких как базы данных, внешние API или другие сервисы. Это особенно полезно в модульных тестах, где важно проверить функциональность конкретного блока кода без влияния внешних факторов.
Зачем они нужны:
1️⃣Изоляция тестируемого кода: Позволяют тестировать функциональность в изоляции, не затрагивая реальные зависимости.
2️⃣Ускорение тестирования: Исключение реальных зависимостей (например, обращения к базе данных или сетевых вызовов) делает тесты быстрее.
3️⃣Предсказуемость: Обеспечивают контроль над входными данными и поведением зависимостей, что позволяет точно проверять ожидаемое поведение.
4️⃣Удобство тестирования пограничных случаев: Позволяют легко имитировать ошибки и нестандартные ситуации, что бывает сложно с реальными объектами.
Как их использовать:
Для создания их часто используются интерфейсы и специальные библиотеки, такие как
gomock или testify/mock.Пример использования с testify/mock:
1️⃣Определение интерфейса:
// file: user.go
package user
type User struct {
ID int
Name string
}
type UserRepository interface {
GetUserByID(id int) (*User, error)
}
2️⃣Создание функции, использующей интерфейс:
// file: service.go
package user
type UserService struct {
Repo UserRepository
}
func (s *UserService) GetUserName(id int) (string, error) {
user, err := s.Repo.GetUserByID(id)
if err != nil {
return "", err
}
return user.Name, nil
}
3️⃣Написание теста с использованием мока:
// file: service_test.go
package user
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
// MockUserRepository is a mock implementation of the UserRepository interface.
type MockUserRepository struct {
mock.Mock
}
func (m *MockUserRepository) GetUserByID(id int) (*User, error) {
args := m.Called(id)
return args.Get(0).(*User), args.Error(1)
}
func TestGetUserName(t *testing.T) {
mockRepo := new(MockUserRepository)
service := UserService{Repo: mockRepo}
// Определяем поведение мока
mockRepo.On("GetUserByID", 1).Return(&User{ID: 1, Name: "Alice"}, nil)
// Выполнение теста
name, err := service.GetUserName(1)
// Проверка результатов
assert.NoError(t, err)
assert.Equal(t, "Alice", name)
// Проверка, что мок был вызван с правильными параметрами
mockRepo.AssertExpectations(t)
}
Объяснение:
1️⃣Определение интерфейса: Интерфейс
UserRepository определяет метод GetUserByID.2️⃣Использование интерфейса в сервисе: Сервис
UserService использует UserRepository для получения информации о пользователе.3️⃣Создание мока: Мы создаем мок
MockUserRepository, реализующий интерфейс UserRepository.4️⃣Определение поведения мока: Устанавливаем ожидания, что метод
GetUserByID будет вызван с определенными параметрами и вернет заданные результаты.5️⃣Тестирование сервиса: Проверяем, что метод
GetUserName возвращает правильное значение, и что мок был вызван с ожидаемыми параметрами.Моки – это заменители реальных объектов, используемые в тестировании для изоляции кода, ускорения тестов и создания предсказуемых условий. Для этого часто используют интерфейсы и библиотеки, такие как
testify/mock.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
🔥1
Anonymous Quiz
8%
С помощью методов private и public
87%
С помощью разделения видимости через заглавные и строчные буквы.
3%
С помощью модификаторов доступа protected и internal.
2%
С помощью ключевых слов export и unexport
Как можно добавить элементы в слайс ?
Спросят с вероятностью 8%
Слайсы являются динамическими структурами данных, и вы можете добавлять в них элементы с помощью встроенной функции
Использование append для добавления элементов в слайс
1️⃣Добавление одного элемента
Чтобы это сделать используйте
2️⃣Добавление нескольких элементов
Чтобы это сделать передайте их через запятую:
3️⃣Добавление элементов из другого слайса
Чтобы это сделать используйте оператор разворачивания (
Пример динамического увеличения емкости слайса
Когда слайс заполняется до предела его емкости, функция
Функция
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Слайсы являются динамическими структурами данных, и вы можете добавлять в них элементы с помощью встроенной функции
append. Функция append позволяет добавлять один или несколько элементов в конец слайса. При необходимости append автоматически увеличивает емкость слайса и выделяет новый массив для хранения элементов.Использование append для добавления элементов в слайс
1️⃣Добавление одного элемента
Чтобы это сделать используйте
append следующим образом:package main
import "fmt"
func main() {
slice := []int{1, 2, 3}
slice = append(slice, 4) // Добавление одного элемента
fmt.Println(slice) // [1 2 3 4]
}
2️⃣Добавление нескольких элементов
Чтобы это сделать передайте их через запятую:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3}
slice = append(slice, 4, 5, 6) // Добавление нескольких элементов
fmt.Println(slice) // [1 2 3 4 5 6]
}
3️⃣Добавление элементов из другого слайса
Чтобы это сделать используйте оператор разворачивания (
...):package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{4, 5, 6}
slice1 = append(slice1, slice2...) // Добавление элементов из slice2 в slice1
fmt.Println(slice1) // [1 2 3 4 5 6]
}
Пример динамического увеличения емкости слайса
Когда слайс заполняется до предела его емкости, функция
append выделяет новый массив большей емкости и копирует существующие элементы в новый массив. В результате слайс может работать с большими объемами данных без явного управления памятью.package main
import "fmt"
func main() {
slice := make([]int, 0, 2) // Создаем слайс длиной 0 и емкостью 2
fmt.Println("Initial:", slice, "Len:", len(slice), "Cap:", cap(slice))
// Добавляем элементы
slice = append(slice, 1)
fmt.Println("After append 1:", slice, "Len:", len(slice), "Cap:", cap(slice))
slice = append(slice, 2)
fmt.Println("After append 2:", slice, "Len:", len(slice), "Cap:", cap(slice))
slice = append(slice, 3) // Емкость увеличивается автоматически
fmt.Println("After append 3:", slice, "Len:", len(slice), "Cap:", cap(slice))
slice = append(slice, 4, 5, 6) // Добавляем несколько элементов
fmt.Println("After append 4, 5, 6:", slice, "Len:", len(slice), "Cap:", cap(slice))
}
Функция
append позволяет легко добавлять элементы в слайс, автоматически увеличивая емкость по мере необходимости. Вы можете добавлять один или несколько элементов, а также элементы из другого слайса, используя append.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
❤1
Anonymous Quiz
2%
define
15%
struct
74%
type
9%
new
Опишите алгоритм, как будет происходить вставка в Map ?
Спросят с вероятностью 8%
Карта (map) представляет собой хеш-таблицу, которая обеспечивает быструю вставку, удаление и поиск ключей. Алгоритм вставки в карту можно обобщить следующим образом:
1️⃣Хеширование ключа: Вычисляется хеш-код для ключа с использованием функции хеширования. Это дает нам число, которое будет использоваться для определения позиции ключа в хеш-таблице.
2️⃣Определение индекса: Индекс в массиве корзин (buckets) вычисляется на основе хеш-кода и размера массива. Обычно используется операция побитового И (
3️⃣Поиск корзины: С использованием вычисленного индекса определяется конкретная корзина, в которую будет помещен ключ.
4️⃣Проверка на коллизию: Если корзина уже содержит элементы, проверяется, есть ли в ней элемент с таким же ключом:
✅Если элемент с таким ключом уже существует, его значение обновляется новым значением.
✅Если элемент с таким ключом не найден, новый ключ-значение добавляется в корзину.
5️⃣Вставка элемента: Новый элемент добавляется в соответствующую корзину.
Алгоритм вставки на более низком уровне:
1️⃣Хеширование ключа:
2️⃣Определение индекса:
3️⃣Поиск корзины и проверка на коллизию:
✅Проверяем корзину по индексу:
✅Итерируемся по элементам в корзине для поиска совпадения ключа:
4️⃣Добавление нового элемента:
✅Если совпадения ключа не найдено, добавляем новый элемент в корзину:
Пример вставки элемента в карту:
В этом примере:
1️⃣Создается карта
2️⃣Вставляются пары ключ-значение:
3️⃣Значение для ключа
4️⃣Карта выводится на экран.
Важные моменты:
✅Коллизии: Если два ключа имеют один и тот же хеш-код, они попадают в одну корзину. Решение коллизий обычно осуществляется с помощью связных списков или других структур данных внутри каждой корзины.
✅Распределение хеша: Хорошая функция хеширования равномерно распределяет ключи по корзинам, минимизируя количество коллизий.
✅Динамическое изменение размера: При переполнении корзин карта автоматически увеличивает размер массива корзин, чтобы поддерживать эффективное время выполнения операций.
Вставка в карту включает хеширование ключа, определение индекса корзины, проверку на коллизии и добавление элемента в соответствующую корзину. Если ключ уже существует, его значение обновляется.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Карта (map) представляет собой хеш-таблицу, которая обеспечивает быструю вставку, удаление и поиск ключей. Алгоритм вставки в карту можно обобщить следующим образом:
1️⃣Хеширование ключа: Вычисляется хеш-код для ключа с использованием функции хеширования. Это дает нам число, которое будет использоваться для определения позиции ключа в хеш-таблице.
2️⃣Определение индекса: Индекс в массиве корзин (buckets) вычисляется на основе хеш-кода и размера массива. Обычно используется операция побитового И (
&) для получения индекса.3️⃣Поиск корзины: С использованием вычисленного индекса определяется конкретная корзина, в которую будет помещен ключ.
4️⃣Проверка на коллизию: Если корзина уже содержит элементы, проверяется, есть ли в ней элемент с таким же ключом:
✅Если элемент с таким ключом уже существует, его значение обновляется новым значением.
✅Если элемент с таким ключом не найден, новый ключ-значение добавляется в корзину.
5️⃣Вставка элемента: Новый элемент добавляется в соответствующую корзину.
Алгоритм вставки на более низком уровне:
1️⃣Хеширование ключа:
hash := hashFunction(key)
2️⃣Определение индекса:
index := hash & (len(buckets) - 1)
3️⃣Поиск корзины и проверка на коллизию:
✅Проверяем корзину по индексу:
bucket := buckets[index]
✅Итерируемся по элементам в корзине для поиска совпадения ключа:
for _, element := range bucket {
if element.key == key {
element.value = newValue
return
}
}
4️⃣Добавление нового элемента:
✅Если совпадения ключа не найдено, добавляем новый элемент в корзину:
bucket = append(bucket, newElement)
Пример вставки элемента в карту:
package main
import "fmt"
func main() {
// Создаем карту
myMap := make(map[string]int)
// Вставка элементов
myMap["Alice"] = 25
myMap["Bob"] = 30
// Обновление значения существующего ключа
myMap["Alice"] = 26
// Печать карты
fmt.Println(myMap)
}
В этом примере:
1️⃣Создается карта
myMap с ключами типа string и значениями типа int.2️⃣Вставляются пары ключ-значение:
"Alice": 25 и "Bob": 30.3️⃣Значение для ключа
"Alice" обновляется на 26.4️⃣Карта выводится на экран.
Важные моменты:
✅Коллизии: Если два ключа имеют один и тот же хеш-код, они попадают в одну корзину. Решение коллизий обычно осуществляется с помощью связных списков или других структур данных внутри каждой корзины.
✅Распределение хеша: Хорошая функция хеширования равномерно распределяет ключи по корзинам, минимизируя количество коллизий.
✅Динамическое изменение размера: При переполнении корзин карта автоматически увеличивает размер массива корзин, чтобы поддерживать эффективное время выполнения операций.
Вставка в карту включает хеширование ключа, определение индекса корзины, проверку на коллизии и добавление элемента в соответствующую корзину. Если ключ уже существует, его значение обновляется.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍3❤1🤯1
Anonymous Quiz
32%
append()
3%
insert()
8%
add()
56%
Присваивание по ключу
Как проверить слайс на пустоту ?
Спросят с вероятностью 8%
Существует несколько способов проверки слайса на пустоту. Выбор метода зависит от конкретной ситуации и того, что именно вы подразумеваете под "пустотой". Рассмотрим различные подходы.
1️⃣Проверка длины слайса
Самый распространенный способ проверить, пустой ли слайс, — это проверить его длину с помощью функции
2️⃣Проверка на nil
Иногда важно отличать
Комбинированная проверка
В некоторых случаях может потребоваться отличать
Для проверки слайса на пустоту обычно используют
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Существует несколько способов проверки слайса на пустоту. Выбор метода зависит от конкретной ситуации и того, что именно вы подразумеваете под "пустотой". Рассмотрим различные подходы.
1️⃣Проверка длины слайса
Самый распространенный способ проверить, пустой ли слайс, — это проверить его длину с помощью функции
len. Если длина слайса равна нулю, то слайс пустой.package main
import "fmt"
func main() {
var slice1 []int // nil слайс
slice2 := []int{} // Пустой слайс, но не nil
slice3 := []int{1, 2, 3} // Непустой слайс
fmt.Println("slice1 is empty:", len(slice1) == 0) // true
fmt.Println("slice2 is empty:", len(slice2) == 0) // true
fmt.Println("slice3 is empty:", len(slice3) == 0) // false
}
2️⃣Проверка на nil
Иногда важно отличать
nil слайс от пустого слайса с нулевой длиной. Для этого можно использовать сравнение с ним же.package main
import "fmt"
func main() {
var slice1 []int // nil слайс
slice2 := []int{} // Пустой слайс, но не nil
fmt.Println("slice1 is nil:", slice1 == nil) // true
fmt.Println("slice2 is nil:", slice2 == nil) // false
}
Комбинированная проверка
В некоторых случаях может потребоваться отличать
nil слайс от пустого слайса и одновременно проверять, пустой ли он. Это можно сделать с помощью комбинации проверок len и сравнения с nil.package main
import "fmt"
func isEmpty(slice []int) bool {
return slice == nil || len(slice) == 0
}
func main() {
var slice1 []int // nil слайс
slice2 := []int{} // Пустой слайс, но не nil
slice3 := []int{1, 2, 3} // Непустой слайс
fmt.Println("slice1 is empty:", isEmpty(slice1)) // true
fmt.Println("slice2 is empty:", isEmpty(slice2)) // true
fmt.Println("slice3 is empty:", isEmpty(slice3)) // false
}
Для проверки слайса на пустоту обычно используют
len(slice) == 0. Для проверки, является ли слайс nil, используют slice == nil. Для комбинированной проверки можно использовать оба условия.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍2❤1
Anonymous Quiz
22%
Строка - это изменяемый байтовый срез.
74%
Строка - это неизменяемый байтовый срез.
3%
Строка может содержать только символы ASCII.
1%
Строка может изменять свои значения напрямую.
Что такое хэш-коллизия ?
Спросят с вероятностью 8%
Хэш-коллизия происходит, когда два различных ключа в хэш-таблице имеют одинаковое значение хэш-функции, что приводит к попытке размещения их в одной и той же корзине (bucket).
Почему они возникают:
1️⃣Ограниченное количество хэш-значений: Обычно возвращают значения в ограниченном диапазоне (например, 32-битное или 64-битное число), тогда как количество возможных ключей может быть значительно больше.
2️⃣Имперфектное хэширование: Даже хорошая хэш-функция не может идеально распределить все возможные ключи по всем возможным хэш-значениям, особенно при увеличении количества ключей.
Методы разрешения:
1️⃣Открытая адресация:
✅Линейное пробирование: При коллизии алгоритм проверяет следующую ячейку в массиве до тех пор, пока не найдет пустую ячейку.
✅Квадратичное пробирование: Вместо линейного шага проверяются ячейки с квадратичным шагом.
✅Двойное хеширование: Используются две разные хэш-функции для расчета шага пробирования.
2️⃣Цепочки (Chaining):
✅Каждая корзина (bucket) является связным списком или другой структурой данных, в которой хранятся все элементы с одинаковым хэш-значением.
Пример реализации цепочек:
Объяснение кода:
✅HashTable: Структура, представляющая хэш-таблицу с цепочками.
✅NewHashTable: Функция, создающая новую хэш-таблицу заданного размера.
✅hash: Простая хэш-функция для строк.
✅Insert: Метод для вставки ключ-значение в хэш-таблицу.
✅Search: Метод для поиска значения по ключу в хэш-таблице.
Хэш-коллизия возникает, когда два разных ключа имеют одинаковое хэш-значение. Основные методы разрешения коллизий включают открытую адресацию и цепочки. Можно использовать структуры данных, такие как списки, для реализации цепочек.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Хэш-коллизия происходит, когда два различных ключа в хэш-таблице имеют одинаковое значение хэш-функции, что приводит к попытке размещения их в одной и той же корзине (bucket).
Почему они возникают:
1️⃣Ограниченное количество хэш-значений: Обычно возвращают значения в ограниченном диапазоне (например, 32-битное или 64-битное число), тогда как количество возможных ключей может быть значительно больше.
2️⃣Имперфектное хэширование: Даже хорошая хэш-функция не может идеально распределить все возможные ключи по всем возможным хэш-значениям, особенно при увеличении количества ключей.
Методы разрешения:
1️⃣Открытая адресация:
✅Линейное пробирование: При коллизии алгоритм проверяет следующую ячейку в массиве до тех пор, пока не найдет пустую ячейку.
index = (hash + i) % len(buckets)
✅Квадратичное пробирование: Вместо линейного шага проверяются ячейки с квадратичным шагом.
index = (hash + i*i) % len(buckets)
✅Двойное хеширование: Используются две разные хэш-функции для расчета шага пробирования.
index = (hash1 + i*hash2) % len(buckets)
2️⃣Цепочки (Chaining):
✅Каждая корзина (bucket) является связным списком или другой структурой данных, в которой хранятся все элементы с одинаковым хэш-значением.
type Node struct {
key string
value int
next *Node
}
Пример реализации цепочек:
package main
import (
"container/list"
"fmt"
)
// Простая хэш-таблица с цепочками
type HashTable struct {
buckets []*list.List
size int
}
// Создаем новую хэш-таблицу
func NewHashTable(size int) *HashTable {
buckets := make([]*list.List, size)
for i := range buckets {
buckets[i] = list.New()
}
return &HashTable{
buckets: buckets,
size: size,
}
}
// Хэш-функция
func (ht *HashTable) hash(key string) int {
hash := 0
for i := 0; i < len(key); i++ {
hash = (31 * hash) + int(key[i])
}
return hash % ht.size
}
// Вставка в хэш-таблицу
func (ht *HashTable) Insert(key string, value int) {
index := ht.hash(key)
bucket := ht.buckets[index]
for e := bucket.Front(); e != nil; e = e.Next() {
pair := e.Value.(map[string]int)
if _, ok := pair[key]; ok {
pair[key] = value
return
}
}
bucket.PushBack(map[string]int{key: value})
}
// Поиск в хэш-таблице
func (ht *HashTable) Search(key string) (int, bool) {
index := ht.hash(key)
bucket := ht.buckets[index]
for e := bucket.Front(); e != nil; e = e.Next() {
pair := e.Value.(map[string]int)
if val, ok := pair[key]; ok {
return val, true
}
}
return 0, false
}
func main() {
ht := NewHashTable(10)
ht.Insert("Alice", 25)
ht.Insert("Bob", 30)
ht.Insert("Charlie", 35)
if value, found := ht.Search("Alice"); found {
fmt.Println("Alice:", value)
} else {
fmt.Println("Alice not found")
}
if value, found := ht.Search("Bob"); found {
fmt.Println("Bob:", value)
} else {
fmt.Println("Bob not found")
}
if value, found := ht.Search("Eve"); found {
fmt.Println("Eve:", value)
} else {
fmt.Println("Eve not found")
}
}
Объяснение кода:
✅HashTable: Структура, представляющая хэш-таблицу с цепочками.
✅NewHashTable: Функция, создающая новую хэш-таблицу заданного размера.
✅hash: Простая хэш-функция для строк.
✅Insert: Метод для вставки ключ-значение в хэш-таблицу.
✅Search: Метод для поиска значения по ключу в хэш-таблице.
Хэш-коллизия возникает, когда два разных ключа имеют одинаковое хэш-значение. Основные методы разрешения коллизий включают открытую адресацию и цепочки. Можно использовать структуры данных, такие как списки, для реализации цепочек.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍1
Anonymous Quiz
6%
Буферизированные и неблокирующие.
7%
Блокирующие и неблокирующие.
82%
Буферизированные и небуферизированные.
4%
Типизированные и нетипизированные.
Можно ли добавлять элементы в nil слайс ?
Спросят с вероятностью 8%
Можно добавлять элементы в
Пример:
Как он работает с nil слайсом
Когда вызывается
1️⃣Проверка емкости: Go проверяет, достаточно ли емкости для добавления новых элементов.
2️⃣Выделение памяти: Если емкости недостаточно (что всегда будет в случае
3️⃣Копирование элементов: Существующие элементы (если таковые имеются) копируются в новый массив.
4️⃣Добавление новых элементов: Новые элементы добавляются в массив.
5️⃣Возврат нового слайса: Возвращается новый слайс, который указывает на новый массив.
Можно добавлять элементы в
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Можно добавлять элементы в
nil слайс. Когда используется функция append для добавления элементов в nil слайс, Go автоматически выделяет необходимую память и создает новый массив для хранения элементов. После этого слайс больше не будет нулевым.Пример:
package main
import "fmt"
func main() {
var nilSlice []int // nil слайс
// Добавление элемента в nil слайс
nilSlice = append(nilSlice, 1)
fmt.Println(nilSlice) // [1]
fmt.Println(len(nilSlice)) // 1
fmt.Println(cap(nilSlice)) // 1
fmt.Println(nilSlice == nil) // false (теперь слайс больше не nil)
// Добавление нескольких элементов
nilSlice = append(nilSlice, 2, 3, 4)
fmt.Println(nilSlice) // [1 2 3 4]
fmt.Println(len(nilSlice)) // 4
fmt.Println(cap(nilSlice)) // в зависимости от реализации, емкость может быть увеличена
}
Как он работает с nil слайсом
Когда вызывается
append для nil слайса, происходит следующее:1️⃣Проверка емкости: Go проверяет, достаточно ли емкости для добавления новых элементов.
2️⃣Выделение памяти: Если емкости недостаточно (что всегда будет в случае
nil слайса), Go выделяет новый массив с достаточной емкостью для хранения существующих и новых элементов.3️⃣Копирование элементов: Существующие элементы (если таковые имеются) копируются в новый массив.
4️⃣Добавление новых элементов: Новые элементы добавляются в массив.
5️⃣Возврат нового слайса: Возвращается новый слайс, который указывает на новый массив.
package main
import "fmt"
func main() {
var nilSlice []int
// Проверка начальных значений
fmt.Println("Initial nilSlice:", nilSlice) // []
fmt.Println("Length:", len(nilSlice)) // 0
fmt.Println("Capacity:", cap(nilSlice)) // 0
fmt.Println("Is nilSlice nil?", nilSlice == nil) // true
// Добавление первого элемента
nilSlice = append(nilSlice, 1)
fmt.Println("After append 1:", nilSlice) // [1]
fmt.Println("Length:", len(nilSlice)) // 1
fmt.Println("Capacity:", cap(nilSlice)) // 1
fmt.Println("Is nilSlice nil?", nilSlice == nil) // false
// Добавление нескольких элементов
nilSlice = append(nilSlice, 2, 3, 4)
fmt.Println("After append 2, 3, 4:", nilSlice) // [1 2 3 4]
fmt.Println("Length:", len(nilSlice)) // 4
fmt.Println("Capacity:", cap(nilSlice)) // >= 4
}
Можно добавлять элементы в
nil слайс с помощью функции append. При этом Go автоматически выделяет необходимую память и создает новый массив для хранения элементов, после чего слайс больше не является nil.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍1
Anonymous Quiz
96%
const
2%
constant
2%
final
0%
immutable
Что можно хранить в качестве ключа, если Float не использовать ?
Спросят с вероятностью 8%
В качестве ключей в хэш-таблице (map) можно использовать любой тип, который поддерживает операцию сравнения с помощью оператора
1️⃣Булевый тип (
2️⃣Целочисленные типы (
3️⃣Строки (
4️⃣Указатели (любого типа):
5️⃣Интерфейсы (при условии, что конкретные типы, которые они содержат, поддерживают сравнение):
6️⃣Составные типы (структуры, массивы), при условии, что все их поля также поддерживают сравнение с помощью оператора
Почему float не рекомендуется использовать в качестве ключа
✅Проблемы с точностью: Плавающие числа (float) часто имеют проблемы с точностью представления. Два значения, которые математически равны, могут иметь небольшие различия в их бинарном представлении из-за ограничений точности. Это может привести к неожиданному поведению при сравнении ключей.
✅Стандарты IEEE 754: Плавающие числа следуют стандарту IEEE 754, который предусматривает такие значения, как
Рассмотрим пример использования структуры в качестве ключа в хэш-таблице:
В этом примере:
1️⃣Определение структуры: Создаем структуру
2️⃣Создание карты: Создаем карту
3️⃣Вставка значений: Вставляем в карту два значения с ключами типа
4️⃣Поиск и вывод значений: Ищем значения по ключам и выводим их на экран.
В качестве ключей в хэш-таблицах можно использовать типы, которые поддерживают операцию сравнения с помощью оператора
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
В качестве ключей в хэш-таблице (map) можно использовать любой тип, который поддерживает операцию сравнения с помощью оператора
==. Это включает в себя следующие типы данных:1️⃣Булевый тип (
bool): m := map[bool]string{
true: "Yes",
false: "No",
}
2️⃣Целочисленные типы (
int, int8, int16, int32, int64, а также их беззнаковые эквиваленты uint, uint8, uint16, uint32, uint64): m := map[int]string{
1: "One",
2: "Two",
}
3️⃣Строки (
string): m := map[string]int{
"Alice": 25,
"Bob": 30,
}
4️⃣Указатели (любого типа):
a, b := 1, 2
m := map[*int]string{
&a: "Pointer to a",
&b: "Pointer to b",
}
5️⃣Интерфейсы (при условии, что конкретные типы, которые они содержат, поддерживают сравнение):
var i interface{} = "string"
m := map[interface{}]string{
i: "interface as key",
}
6️⃣Составные типы (структуры, массивы), при условии, что все их поля также поддерживают сравнение с помощью оператора
==): type Key struct {
FirstName string
LastName string
}
m := map[Key]int{
{"Alice", "Smith": 1},
{"Bob", "Johnson": 2},
}
Почему float не рекомендуется использовать в качестве ключа
✅Проблемы с точностью: Плавающие числа (float) часто имеют проблемы с точностью представления. Два значения, которые математически равны, могут иметь небольшие различия в их бинарном представлении из-за ограничений точности. Это может привести к неожиданному поведению при сравнении ключей.
✅Стандарты IEEE 754: Плавающие числа следуют стандарту IEEE 754, который предусматривает такие значения, как
NaN (Not a Number). В Go, NaN не равен сам себе (NaN != NaN), что делает их проблематичными для использования в качестве ключей в хэш-таблицах.Рассмотрим пример использования структуры в качестве ключа в хэш-таблице:
package main
import "fmt"
type Person struct {
FirstName string
LastName string
}
func main() {
m := make(map[Person]int)
// Вставка значений в карту
m[Person{"Alice", "Smith"}] = 25
m[Person{"Bob", "Johnson"}] = 30
// Поиск и вывод значений
fmt.Println("Alice Smith age:", m[Person{"Alice", "Smith"}])
fmt.Println("Bob Johnson age:", m[Person{"Bob", "Johnson"}])
}
В этом примере:
1️⃣Определение структуры: Создаем структуру
Person с полями FirstName и LastName.2️⃣Создание карты: Создаем карту
m с ключами типа Person.3️⃣Вставка значений: Вставляем в карту два значения с ключами типа
Person.4️⃣Поиск и вывод значений: Ищем значения по ключам и выводим их на экран.
В качестве ключей в хэш-таблицах можно использовать типы, которые поддерживают операцию сравнения с помощью оператора
==. Это включает булевые, целочисленные типы, строки, указатели, интерфейсы и составные типы, такие как структуры. Плавающие числа не рекомендуются из-за проблем с точностью и особенностей стандарта IEEE 754.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
👍1
Anonymous Quiz
91%
"time"
7%
"datetime"
1%
"clock"
1%
"calendar"
Что такое nil слайс и чем отличается ?
Спросят с вероятностью 8%
Слайсы могут быть либо
nil
Это слайс, который не указывает ни на какой массив. Он имеет следующие характеристики:
1️⃣Указатель на базовый массив равен `nil`.
2️⃣Длина равна 0.
3️⃣Емкость равна 0.
Ненулевой (пустой)
Это слайс, который инициализирован и указывает на некоторый массив, даже если этот массив имеет нулевую длину. Такой слайс имеет ненулевую емкость.
Отличия nil от ненулевого
1️⃣Инициализация:
✅
✅Ненулевой слайс: Инициализирован явно, даже если длина равна 0.
✅
✅Ненулевой слайс:
3️⃣Использование в функциях:
✅Оба типа слайсов могут передаваться в функции и использоваться для операций, таких как добавление элементов с помощью
Особенности и применения
✅Иногда полезно проверять, является ли слайс
Инициализация :
✅При этом, они будут заполняться позже, часто используют
✅Для их создания фиксированной или предварительно известной емкости используют
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Спросят с вероятностью 8%
Слайсы могут быть либо
nil, либо ненулевыми. Понимание разницы между ними важно для правильного использования и управления памятью. Разберем, что такое nil слайс, как он отличается от ненулевого слайса, и какие особенности и применения есть у обоих.nil
Это слайс, который не указывает ни на какой массив. Он имеет следующие характеристики:
1️⃣Указатель на базовый массив равен `nil`.
2️⃣Длина равна 0.
3️⃣Емкость равна 0.
package main
import "fmt"
func main() {
var slice []int // Объявление слайса без инициализации
fmt.Println(slice) // []
fmt.Println(len(slice)) // 0
fmt.Println(cap(slice)) // 0
fmt.Println(slice == nil) // true
}
Ненулевой (пустой)
Это слайс, который инициализирован и указывает на некоторый массив, даже если этот массив имеет нулевую длину. Такой слайс имеет ненулевую емкость.
package main
import "fmt"
func main() {
slice := make([]int, 0) // Создание пустого слайса с длиной 0
fmt.Println(slice) // []
fmt.Println(len(slice)) // 0
fmt.Println(cap(slice)) // В зависимости от реализации, например, 0 или больше
fmt.Println(slice == nil) // false
}
Отличия nil от ненулевого
1️⃣Инициализация:
✅
nil слайс: Не инициализирован явно, инициализирован с nil.✅Ненулевой слайс: Инициализирован явно, даже если длина равна 0.
2️⃣
Сравнение с
ain() {✅
nil слайс: slice == nil возвращает true.✅Ненулевой слайс:
slice == nil возвращает false.3️⃣Использование в функциях:
✅Оба типа слайсов могут передаваться в функции и использоваться для операций, таких как добавление элементов с помощью
append.package main
import "fmt"
func main() {
var nilSlice []int
nonNilSlice := make([]int, 0)
nilSlice = append(nilSlice, 1)
nonNilSlice = append(nonNilSlice, 1)
fmt.Println(nilSlice) // [1]
fmt.Println(nonNilSlice) // [1]
fmt.Println(nilSlice == nil) // false
fmt.Println(nonNilSlice == nil) // false
}
Особенности и применения
Проверка на
fmt.P
✅Иногда полезно проверять, является ли слайс
nil, чтобы избежать ненужных операций или для специальной обработки. if slice == nil {
fmt.Println("Slice is nil")
} else {
fmt.Println("Slice is not nil")
}
Инициализация :
✅При этом, они будут заполняться позже, часто используют
nil слайсы.✅Для их создания фиксированной или предварительно известной емкости используют
make.nil — это слайс, который не указывает на массив и имеет длину и емкость 0. Ненулевой может иметь длину 0, но указывает на массив и обычно имеет емкость, отличную от 0. Понимание разницы между ними важно для правильного использования слайсов и управления памятью.👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 349 вопроса на Golang разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых
Anonymous Quiz
10%
exit
4%
stop
37%
return
49%
нет специального ключевого слова