- Общее:
- Как реализовано ООП:
- Инкапсуляция - реализована на уровне пакетов, приватные методы/свойства именуются с маленькой буквы, публичные с большой.
- Полиморфизм - реализован с помощью ключевого слова interface
- Наследование - как такового нет, но можно реализовать с помощью Embedding (встраивание), т.е. мы можем встраивать в структуру другие типы, в том числе другие структуры. При этом будут унаследованы и методы и свойства дочерних структур. Если в родительской и дочерней структуре есть методы с одинаковым именем, то для вызова метода дочерней структуры, нужно будет явно обратиться к нему через тип структуры (parent.Child.DoSomething()).
- Функция как параметр другой функции:
- Замыкания (closures): это функции, которые можно создавать в рантайме (?) и им будет доступны переменные области видимости, в которой они были созданы. Именованные/анонимные
- Как правильно создать проект:
- Escape analysis:
- Как обрабатывать panic:
- Этапы компиляции:
- Parsing (cmd/compile/internal/syntax) - исходники разбиваются на токены, создается синтаксическое дерево
- Type-checking and Abstract Syntax Tree transformations (cmd/compile/internal/gc) - дерево переводится в AST, происходит проверки интерфейсов
- Generic Static SIngle Assignment (cmd/compile/internal/gc, cmd/compile/internal/ssa) - AST переводится в SSA, применяются оптимизации, удаляются ненужные проверки
- Generating machine code (cmd/compile/internal/ssa, cmd/internal/obj) - опять происходят всякие оптимизации, перевод универсальных вещей в платформозависимые. Затем ассемблер генерирует машинный код и записывает в объектный файл.
- Дерективы компилятора:
- Type Switch:
- graceful shutdown:
- работа с указателями:
- оператор & - взятие адреса переменной
- оператор * - либо объявить тип указатель, либо для того, чтобы получить значение по адресу переменной
- все параметры в go передаются по значению
- Как реализовано ООП:
- Ключевые слова и встроенные функции:
- new: встроенная функция, в качестве параметра ей передаётся тип, а возвращается указатель на новую переменную соответствующего типа.
- range:
- make:
- struct:
- interface: определяет набор сигнатур методов, но не представляет реализации.
- defer:
*функция отложенного вызова, выполняется всегда (даже в случае паники внутри вызываемой функции) после того, как функция завершила свое выполнение, но до того, как управление возвращается к вызывающей стороне.
- Функции c defer будут вызываться в обратной последовательности от их объявления во внешней функции.
- Значения в defer передаются в момент вызова функции.
- select: позволяет обрабатывать несколько каналов "одновременно".
- Чтение - Блокируется, пока в один из каналов не попадет сообщение, если в оба канала сообщения пришли одновременно, то case будет выбран случайно. Если указана секция default, то при отсутствии сообщений, перестает быть блокируемым и выполнится код из секции default.
- Запись -
- fallthrough: Ключевое слово для работы с switch-case. Заставляет выполнять код в следующей объявленной булевой секции, вне зависимости подходит ли булевое условие case этой секции.
- Многопоточность:
- Горутины: это функция, выполняющаяся конкурентно с другими горутинами в том же адресном пространстве. Запускается с помощью ключевого слова go имя функции (или замыкание).
- В отличии от потоков, обрабатываются собственным планировщиком go и имеет стэк, размер которого может расти.
- Минимальный размер стэка горутины 2 КБ, максимальный зависит от архитектуры, 1 ГБ для х64, 250 МБ для х32.
- Если размер стэка привышен, то приложение упадет с fatal error.
- Завершить горутину можно с помощью канала, переданного в горутину, который будет сообщать, когда нужно её закрыть или при помощи context.Context.
- Каналы: это структура данных, которая используется как объект связи, работает по принципу FIFO.
- Создается с помощью ключевого слова chan: channel := make(chan int), для чтения data := <-channel, для записи channel <- data, для закрытия close(channel).
- Запись в закрытый канал и повторное закрытие канала, приведет к панике. Запись/чтение в неинициализированный канал приведет к дедлоку
- Буферизированные - создается указанием второго аргумента channel := make(chan int, 5), что является размером канала. В этом случае горутина не блокируется, пока канал не будет заполнен.
- Небуферизированные - чтение или запись данных блокирует горутину и передает управление свободной горутине.
- Планировщик в Go:
- Неявная кооперативность.
- В одном потоке, в один момент времени, выполняется одна горутина, при этом в очереди исполнения их может быть неограниченное количество.
- Горутины: это функция, выполняющаяся конкурентно с другими горутинами в том же адресном пространстве. Запускается с помощью ключевого слова go имя функции (или замыкание).
- Структуры и типы данных:
- Мапы: Неупорядоченная коллекция пар вида ключ-значение. Ключем может быть любой тип, который можно сравнить с помощью операторов сравнения. Структура может быть ключом до тех пор, пока её поля содержат только те типы, которые можно сравнивать. Если писать в не инициализированную мапу, то будет паника. Не потокобезопасна.
- Слайсы (срезы): Упорядоченная структура данных. Реализуется поверх массива и представляет собой указатель на массив, длину (len) и емкость (cap). Может менять свой размер, динамическая аллокация памяти. При выходе за границу емкости, будет создан новый массив большей длины и произойдет копирование данных.
- Увеличении размера слайса (метод growslice) происходит по следующему алгоритму — если его размер менее 1024 элементов, то его размер будет увеличиваться вдвое; иначе же слайс увеличивается на ~12.5% от своего текущего размера.
- Массивы: это последовательность фиксированной длины, состоящая из элементов одного типа.
- Размер массива является частью типа, [3]int и [5]int относятся к разным типам.
- Доступ - константная сложность O(1).
- При выходе за пределы массива сработает паника.
- string: является слайсом байт, доступным только для чтения, при сложении строк результатом будет новая строка. При подсчете длины строки, важно понимать, что количество байт != количеству символов.
- rune: интерпретирует массив байт, как массив символов. var r = 'f' - тип rune, var r = "f" - тип string.
- const и untyped:
- Библиотека sync:
- sync.Mutex - мьютекс как мьютекс
- sync.RWMutex - Шаред мьютекс (read-write mutex), обладает доп. методами RLock() и RUnlock(), которые используются для блокировки только для чтения.
- sync.Map - предоставляет атомарный доступ к элементам map.
- sync.WaitGroup - это реализация счетчика, который можно инкрементировать и декрементировать, и самое главное остановить выполнение куска кода до того момента, пока значение счетчика не будет равно 0.
- sync.Cond - Условная переменная (condition variable) -
- sync.Once - Позволяет определить задачу для однократного выполнения за всё время работы программы. Содержит одну-единственную функцию Do, позволяющую передавать другую функцию для однократного применения.
- Библиотека context:
- Тестирование/профилирование:
- Сборщик мусора в Go:
- ****: