Golang | Вопросы собесов
4.35K subscribers
26 photos
1 video
714 links
Download Telegram
🤔 Что такое Go?

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

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

🟠Компиляция и скорость
Go — компилируемый язык, обеспечивающий высокую производительность.
🟠Простота
Язык избегает избыточности, улучшая читаемость кода.
🟠Сборка мусора
Автоматическое управление памятью.
🟠Конкурентность
Встроенные средства для работы с параллельными вычислениями, такие как горутины и каналы.
🟠Стандартная библиотека
Широкий набор инструментов и библиотек.

🚩Пример простого приложения

Простого веб-сервера:
package main

import (
"fmt"
"net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}

func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("Starting server on :8080")
http.ListenAndServe(":8080", nil)
}


🚩Основные концепции

🟠Горутины
Легковесные потоки для параллельных вычислений.
go func() {
fmt.Println("Hello from a goroutine!")
}()


🟠Каналы
Средства обмена данными между горутинами.
ch := make(chan int)
go func() {
ch <- 42
}()
value := <-ch
fmt.Println(value)


🟠Интерфейсы
Абстракция поведения без привязки к реализации.
type Stringer interface {
String() string
}


🟠Пакеты
Организация кода для управления и повторного использования.
package mypackage

import "fmt"

func MyFunction() {
fmt.Println("Hello from mypackage")
}


🚩Применение Go

Go используется для серверного ПО, облачных сервисов, микросервисов, инструментов командной строки и систем с высокой производительностью. Известные проекты на Go включают Kubernetes, Docker, Prometheus, а также Google, Dropbox и Netflix.

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

Высокая производительность
Быстро компилируемый язык.
Простота и читаемость
Минимум синтаксического шума.
Конкурентность
Простые механизмы параллельных вычислений.
Богатая библиотека
Широкий набор встроенных инструментов.
Ограниченные обобщения
Ранее отсутствовали, добавлены в Go 1.18.
Нет исключений
Используется управление ошибками через возвращаемые значения.

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

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

🟠Компиляция и выполнение
Go: Компилируемый язык, компилируется в машинный код, что обеспечивает высокую производительность и быстрое время выполнения.
Java: Компилируется в байт-код, который выполняется на виртуальной машине Java (JVM). Это обеспечивает переносимость, но может добавлять накладные расходы.
Python: Интерпретируемый язык, что делает его менее производительным по сравнению с компилируемыми языками.

🟠Простота и лаконичность
Go: Разработан для простоты и читаемости, минимизирует синтаксическую сложность, избегает избыточности.
Java: Сложный и многословный синтаксис, требует больше кода для выполнения тех же задач.
Python: Простой и читаемый синтаксис, который делает его легким для изучения и использования.

🟠Управление памятью
Go: Автоматическая сборка мусора, но с управляемыми задержками для обеспечения высокой производительности.
Java: Автоматическая сборка мусора на JVM, что может приводить к задержкам в критических приложениях.
Python: Автоматическая сборка мусора с использованием подсчета ссылок и циклического сборщика мусора.

🟠Конкурентность и параллелизм
Go: Встроенная поддержка конкурентности через горутины и каналы, легковесные потоки с низкими накладными расходами.
Java: Многопоточность с использованием потоков, сложное управление потоками и синхронизацией.
Python: Поддержка многопоточности, но ограниченная глобальной блокировкой интерпретатора (GIL), что затрудняет использование многопоточности для параллельных вычислений.

🟠Статическая и динамическая типизация
Go: Статически типизированный язык, ошибки типа обнаруживаются на этапе компиляции, что повышает надежность кода.
Java: Статически типизированный язык, что позволяет обнаруживать ошибки типа на этапе компиляции.
Python: Динамически типизированный язык, типы проверяются во время выполнения, что может приводить к ошибкам времени выполнения.

🟠Интерфейсы и наследование
Go: Использует интерфейсы для определения поведения без наследования. Интерфейсы реализуются неявно.
Java: Использует классы и интерфейсы, поддерживает множественное наследование через интерфейсы и одиночное наследование классов.
Python: Поддерживает множественное наследование классов, что может усложнять структуру программы.

🟠Стандартная библиотека
Go: Богатая стандартная библиотека с встроенной поддержкой работы с сетью, веб-серверами и другими задачами.
Java: Широкая стандартная библиотека с обширной поддержкой различных API и утилит.
Python: Обширная стандартная библиотека, особенно сильная в области научных вычислений, обработки данных и веб-разработки.

🟠Экосистема и инструменты
Go: Современные и мощные инструменты для сборки, тестирования и профилирования. Простая система управления зависимостями.
Java: Зрелая экосистема с множеством фреймворков и инструментов (например, Maven, Gradle, Spring).
Python: Обширная экосистема пакетов и библиотек (например, pip, virtualenv, Django).

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

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

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

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

🚩Основные концепции пакетов

🟠Определение пакета
Каждый файл Go начинается с объявления пакета, к которому он принадлежит. Например, package main или package fmt.

🟠Импорт пакетов
Для использования кода из другого пакета необходимо импортировать его с помощью ключевого слова import.

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

🟠Публичные и приватные члены
Имена, которые начинаются с заглавной буквы, являются экспортируемыми (доступными из других пакетов). Имена, которые начинаются с маленькой буквы, являются неэкспортируемыми (доступны только внутри пакета).

🚩Пример использования пакетов

🟠Создание пакета
Файл mypackage/mypackage.go
package mypackage

import "fmt"

// Экспортируемая функция
func PrintHello() {
fmt.Println("Hello from mypackage")
}

// Неэкспортируемая функция
func privateFunction() {
fmt.Println("This is a private function")
}


🟠Использование пакета
Файл main.go
package main

import (
"mypackage"
)

func main() {
mypackage.PrintHello() // Output: Hello from mypackage
// mypackage.privateFunction() // Ошибка: неэкспортируемая функция
}


🚩Импорт нескольких пакетов

В Go можно импортировать несколько пакетов в одном блоке.
package main

import (
"fmt"
"mypackage"
)

func main() {
fmt.Println("Using multiple packages")
mypackage.PrintHello()
}


🚩Именованные импорты

Иногда необходимо импортировать пакеты с другим именем для избежания конфликтов или для удобства. Это делается с помощью именованных импортов.
package main

import (
"fmt"
mp "mypackage"
)

func main() {
fmt.Println("Using aliased package")
mp.PrintHello()
}


🚩Пустой импорт

Пустой импорт используется, когда нужно выполнить инициализацию пакета, но не использовать его явно. Это часто используется для регистрации драйверов или других побочных эффектов.
import (
_ "some/package"
)


🚩Структура проекта с пакетами

Проекты на Go часто организуются в виде нескольких пакетов, где каждый пакет выполняет определенную роль. Типичная структура проекта может выглядеть следующим образом:
myproject/
main.go
mypackage/
mypackage.go
anotherpackage/
anotherpackage.go


Файл main.go
package main

import (
"mypackage"
"anotherpackage"
)

func main() {
mypackage.PrintHello()
anotherpackage.DoSomething()
}


Файл anotherpackage/anotherpackage.go
package anotherpackage

import "fmt"

func DoSomething() {
fmt.Println("Doing something in anotherpackage")
}


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

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

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

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

🚩Создание пакета

🟠Создание структуры проекта
Создайте папку для вашего проекта и внутри нее создайте папку для вашего пакета.
myproject/
main.go
mypackage/
mypackage.go


🟠Определение пакета
В файле mypackage.go определите пакет с именем mypackage и добавьте функции, которые вы хотите экспортировать.
Файл mypackage/mypackage.go
package mypackage

import "fmt"

// Экспортируемая функция (имя начинается с заглавной буквы)
func PrintHello() {
fmt.Println("Hello from mypackage")
}

// Неэкспортируемая функция (имя начинается с маленькой буквы)
func privateFunction() {
fmt.Println("This is a private function")
}


🚩Импортирование и использование пакета

🟠Импортирование пакета в `main.go`
Чтобы использовать функции из вашего пакета mypackage в файле main.go, нужно импортировать этот пакет.
Файл main.go
package main

import (
"mypackage" // Импортируем наш пакет
)

func main() {
mypackage.PrintHello() // Вызов экспортируемой функции из пакета mypackage
// mypackage.privateFunction() // Это вызовет ошибку, так как функция не экспортируется
}


🟠Запуск программы
Перейдите в корневую папку вашего проекта (myproject) и выполните команду
go run main.go


Вы должны увидеть выво
Hello from mypackage


🟠Именованные импорты
Иногда может потребоваться импортировать пакет под другим именем. Это может быть полезно для сокращения длинных имен пакетов или для избежания конфликтов имен.
Пример с именованным импортом:
Файл main.go:
package main

import (
"fmt"
mp "mypackage" // Импортируем mypackage под именем mp
)

func main() {
mp.PrintHello() // Используем алиас для вызова функции из пакета
}


🟠Пустой импорт
Пустой импорт используется для выполнения побочных эффектов, таких как инициализация или регистрация пакетов, без явного использования их функций.
Пример пустого импорта
import (
_ "some/package" // Импортируем пакет только для его инициализации
)


🚩Модули и управление зависимостями

Для управления зависимостями в Go используется система модулей. Она позволяет указать зависимости вашего проекта и их версии.

🟠Инициализация модуля
Для создания нового модуля выполните команду
go mod init myproject


🟠Добавление зависимостей
Когда вы импортируете внешний пакет, Go автоматически добавляет его в ваш файл go.mod.

🚩Полный пример

1⃣Структура проекта
myproject/
go.mod
main.go
mypackage/
mypackage.go


2⃣Файл mypackage/mypackage.go
package mypackage

import "fmt"

func PrintHello() {
fmt.Println("Hello from mypackage")
}


3⃣Файл main.go
package main

import (
"mypackage"
)

func main() {
mypackage.PrintHello()
}


4⃣Инициализация модуля и запуск
cd myproject
go mod init myproject
go run main.go


5⃣Вы должны увидеть вывод
Hello from mypackage


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

Тесты пишутся в файлах с суффиксом _test.go, а функции тестов имеют сигнатуру func TestXxx(t *testing.T). Для запуска тестов используется команда go test, которая автоматически находит и выполняет тесты. Пакет testing предоставляет методы для логирования, проверки условий и обработки ошибок в тестах.

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

Это практика автоматизации разработки, тестирования и развертывания программного обеспечения. Цель CI/CD — повысить скорость, частоту и надежность релизов, снижая риски и улучшая качество кода. Давайте разберем, что означает каждый компонент CI/CD и как они работают вместе.

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

🟠Continuous Integration (CI)
Процесс регулярного объединения изменений кода из разных источников в общую кодовую базу. Обнаружение и устранение проблем на ранних стадиях разработки. Разработчики часто интегрируют свой код в общий репозиторий (например, несколько раз в день). Каждый коммит запускает автоматическую сборку и тестирование, чтобы убедиться, что изменения не сломали существующий код.
Инструменты: Jenkins, GitLab CI, Travis CI, CircleCI.

🟠Continuous Delivery (CD)
Практика, при которой код всегда готов к развертыванию в продакшен, но развертывание может требовать ручного вмешательства. Обеспечение готовности кода к релизу в любой момент времени. После успешного прохождения всех этапов CI, код автоматически продвигается к этапам развертывания на различные среды (staging, production). Требует минимального ручного вмешательства для выпуска новой версии.
Инструменты: Spinnaker, Bamboo, Jenkins.

🟠Continuous Deployment
Расширение Continuous Delivery, где каждое изменение, прошедшее все этапы тестирования, автоматически развертывается в продакшен. Полная автоматизация развертывания, минимизация времени между коммитом и доставкой кода пользователям. После успешного прохождения всех этапов CI и CD, изменения автоматически развертываются в продакшен без ручного вмешательства.
Инструменты: Jenkins, GitLab CI/CD, CircleCI, AWS CodePipeline.

🚩Пример использования

🟠Настройка Jenkins
Установите и настройте Jenkins на сервере.
Создайте новый pipeline проект в Jenkins.

🟠Создание Jenkinsfile:
В корне вашего репозитория создайте файл Jenkinsfile, который описывает этапы вашего CI/CD процесса.
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'go build -v'
}
}
stage('Test') {
steps {
sh 'go test -v ./...'
}
}
stage('Deploy') {
steps {
sh 'echo "Deploying to production"'
// Ваши команды для развертывания
}
}
}
}


🟠Запуск Pipeline
Коммиты в репозиторий автоматически запускают Pipeline, выполняющий сборку, тестирование и развертывание.

🚩Плюсы

Быстрое обнаружение ошибок
Автоматическое тестирование каждого изменения кода помогает быстро обнаруживать и устранять ошибки.
Повышение качества кода
Регулярное объединение кода и тестирование улучшают качество и стабильность кода.
Быстрое и надежное развертывание
Автоматизация развертывания минимизирует человеческие ошибки и ускоряет выпуск новых версий.
Упрощение обратной связи
Быстрая интеграция изменений позволяет разработчикам получать обратную связь о качестве кода в реальном времени.

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

Опциональные функции в протоколах помечаются с помощью атрибута @objc optional. Класс, который реализует такой протокол, может либо реализовать функцию, либо проигнорировать её.

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

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

🚩Основные функции линтеров

🟠Проверка стиля кода
Линтеры проверяют, соответствует ли код стилевым рекомендациям и стандартам, таким как использование отступов, именование переменных и форматирование.

🟠Поиск ошибок
Линтеры могут обнаруживать потенциальные ошибки, такие как неиспользуемые переменные, неправильные типы данных, неинициализированные переменные и другие проблемы.

🟠Обеспечение соответствия стандартам
Линтеры помогают поддерживать код в соответствии с общепринятыми стандартами и лучшими практиками, что улучшает читаемость и поддержку кода.

🟠Улучшение качества кода
Линтеры могут указывать на участки кода, которые можно улучшить, например, упростить сложные конструкции или оптимизировать производительность.

🚩Примеры линтеров для различных языков

🟠Go
golint: Проверяет стиль кода на соответствие рекомендациям Go.
gofmt: Автоматически форматирует код в соответствии со стандартами Go.
staticcheck: Более мощный инструмент, который находит ошибки, неэффективные конструкции и другие проблемы.

🟠JavaScript/TypeScript
ESLint: Очень мощный и настраиваемый линтер для JavaScript и TypeScript
JSHint: Инструмент для выявления ошибок и потенциальных проблем в JavaScript-коде.

🟠Python
Pylint: Линтер для Python, который проверяет стиль кода, ищет ошибки и предлагает улучшения.
flake8: Комбинированный инструмент, который включает в себя проверки на стиль, ошибки и другие проблемы.

🟠Java
Checkstyle: Инструмент для проверки стиля кода Java.
PMD: Находит потенциальные ошибки, неиспользуемый код и другие проблемы в коде Java.

🚩Пример использования линтера в Go

1⃣Установка golint
go install golang.org/x/lint/golint@latest


2⃣Создайте файл example.go
package main

import "fmt"

func main() {
fmt.Println("Hello, world!")
}


3⃣Запустите golint
golint example.go


🚩Пример использования линтера в JavaScript

1⃣Установка ESLint
npm install eslint --save-dev


2⃣Инициализация конфигурации ESLint
npx eslint --init


3⃣Создайте файл example.js
function hello() {
console.log("Hello, world!");
}

hello();


Запустите ESLint:
npx eslint example.js


🚩Плюсы

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

Раннее обнаружение ошибок
Линтеры могут обнаруживать ошибки еще до запуска кода, что сокращает время на отладку и тестирование.

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

Обучение и развитие
Использование линтеров помогает разработчикам учиться и развиваться, узнавая о лучших практиках и стандартах кода.

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

Последним кнопку в иерархии вьюшек может обработать корневой объект, например, UIApplication или основной ViewController. Это происходит, если события не обработаны дочерними вьюшками, и они передаются вверх по цепочке обработчиков.

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

Линтеры (linters) нужны для обеспечения качества и чистоты кода, повышения его читаемости и поддержки, а также для предотвращения ошибок на ранних этапах разработки.

🚩Основные причины

🟠Обнаружение ошибок на ранних этапах
Линтеры анализируют код и обнаруживают синтаксические ошибки, неинициализированные переменные, неправильные типы данных и другие потенциальные проблемы еще до запуска программы.

🟠Поддержание единого стиля кода
Линтеры помогают разработчикам придерживаться единого стиля кода, что улучшает читаемость и поддержку проекта. Это особенно важно в больших командах, где много людей работают над одним проектом.

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

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

🟠Обучение и развитие
Линтеры помогают разработчикам узнавать о лучших практиках и стандартах кода, что способствует их профессиональному росту и развитию.

🟠Поддержка кода
Линтеры упрощают поддержку кода, делая его более понятным и структурированным. Это особенно важно в долгосрочных проектах, где код может часто меняться.

🚩Примеры использования линтеров

🟠Использование линтера для Go

1⃣Установка golint
go install golang.org/x/lint/golint@latest


2⃣Пример кода example.go
package main

import "fmt"

func main() {
fmt.Println("Hello, world!")
}


3⃣Запуск golint
golint example.go


🟠Использование линтера для JavaScript

1⃣Установка ESLint
npm install eslint --save-dev


2⃣Инициализация конфигурации ESLint
npx eslint --init


3⃣Пример кода example.js
function hello() {
console.log("Hello, world!");
}

hello();


4⃣Запуск ESLint
npx eslint example.js


🚩Плюсы

Единообразие кода
Линтеры помогают поддерживать единообразие кода, что упрощает работу с ним и его сопровождение.

Сокращение времени на отладку
Раннее обнаружение ошибок позволяет сократить время на отладку и тестирование, улучшая производительность команды.

Снижение количества багов
Линтеры обнаруживают потенциальные ошибки до запуска кода, что снижает вероятность появления багов в продакшене.

Улучшение производительности команды
Автоматизация проверки стиля и качества кода позволяет разработчикам сосредоточиться на более важных задачах, повышая общую производительность команды.

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

unowned ссылка производительнее, так как она не увеличивает счётчик ссылок объекта. Однако unowned нужно использовать осторожно, так как она приводит к крашу, если объект уже деинициализирован. weak безопаснее, но добавляет небольшую накладную из-за проверки на nil.

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

Это объект, размещённый в куче, где память выделяется динамически. Такие объекты хранятся до тех пор, пока на них есть ссылки, и освобождаются автоматически, когда ссылки удаляются (через сборщик мусора или ARC).

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
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
🤔 Что такое retail release?

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

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

Слайсы являются ссылочными типами, поэтому простое присваивание одного слайса другому создаст новую ссылку на тот же подлежащий массив. Если вы хотите создать копию слайса с независимым подлежащим массивом, можно использовать встроенную функцию 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
🤔 Какое свойство должно быть у ключа в Map?

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


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

🟠Создание слайса с использованием литералов
Позволяют создать и инициализировать слайс одновременно
package main

import "fmt"

func main() {
slice := []int{1, 2, 3, 4, 5}
fmt.Println(slice) // [1 2 3 4 5]
}


🟠Создание слайса с использованием функции make
Позволяет создать слайс определенной длины и емкости
package main

import "fmt"

func main() {
slice := make([]int, 3) // Создаем слайс длиной 3 и емкостью 3
fmt.Println(slice) // [0 0 0]

sliceWithCapacity := make([]int, 3, 5) // Создаем слайс длиной 3 и емкостью 5
fmt.Println(sliceWithCapacity) // [0 0 0]
}


🟠Создание слайса на основе массива
Указав подмножество элементов массива
package main

import "fmt"

func main() {
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // Слайс содержит элементы с индексами 1, 2 и 3
fmt.Println(slice) // [2 3 4]
}


🟠Создание слайса на основе другого слайса (Slicing)
Указав подмножество элементов существующего слайса
package main

import "fmt"

func main() {
slice := []int{1, 2, 3, 4, 5}
subSlice := slice[1:4] // Новый слайс содержит элементы с индексами 1, 2 и 3
fmt.Println(subSlice) // [2 3 4]
}


🟠Создание пустого слайса
Длина и емкость которого равны нулю
package main

import "fmt"

func main() {
var emptySlice []int // Пустой слайс
fmt.Println(emptySlice, len(emptySlice), cap(emptySlice)) // [] 0 0

emptySlice = append(emptySlice, 1) // Добавление элемента
fmt.Println(emptySlice) // [1]
}


🟠Создание слайса с использованием среза от существующего слайса
Указывая начальный и конечный индекс (исключительно)
package main

import "fmt"

func main() {
original := []int{1, 2, 3, 4, 5}
newSlice := original[:3] // Слайс содержит элементы с индексами 0, 1, 2
fmt.Println(newSlice) // [1 2 3]

anotherSlice := original[2:] // Слайс содержит элементы с индекса 2 до конца
fmt.Println(anotherSlice) // [3 4 5]
}


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

import "fmt"

func main() {
// Создание слайса с использованием литерала
sliceLiteral := []int{1, 2, 3, 4, 5}
fmt.Println("Slice literal:", sliceLiteral)

// Создание слайса с использованием make
sliceMake := make([]int, 3) // Длина 3, емкость 3
fmt.Println("Slice make:", sliceMake)

sliceMakeWithCapacity := make([]int, 3, 5) // Длина 3, емкость 5
fmt.Println("Slice make with capacity:", sliceMakeWithCapacity)

// Создание слайса на основе массива
arr := [5]int{1, 2, 3, 4, 5}
sliceFromArray := arr[1:4] // Элементы с индексами 1, 2, 3
fmt.Println("Slice from array:", sliceFromArray)

// Создание слайса на основе другого слайса
sliceFromSlice := sliceLiteral[2:5] // Элементы с индексами 2, 3, 4
fmt.Println("Slice from slice:", sliceFromSlice)

// Создание пустого слайса
var emptySlice []int
fmt.Println("Empty slice:", emptySlice, len(emptySlice), cap(emptySlice))

// Добавление элемента в пустой слайс
emptySlice = append(emptySlice, 10)
fmt.Println("After append:", emptySlice)
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM