💬Один из частых вопросов на собесах: «Что такое конкурентность в Go?»
Сначала надо вспомнить о таких вещах, как асинхронность и параллельность.
📌Асинхронность говорит о порядке исполнения кода. Вычисления в системе могут идти двумя способами:
— когда код выполняется последовательно — синхронно;
— когда результат выполнения кода доступен не сразу, а через некоторое время в виде некоторого асинхронного (нарушающего обычный порядок выполнения) вызова, — асинхронно.
📌Параллельность в свою очередь говорит о том, что физически происходит несколько процессов одновременно.
При этом, с точки зрения кода программы это всё может выглядеть вполне синхронно. Например, если подряд вызываются две функции, то исполняющая среда может решить по каким-то признакам, что эти функции независимы, и выполнить их параллельно. С точки зрения программы этого заметно не будет.
На практике, конечно, эти понятия пересекаются очень часто, потому что асинхронные вызовы делаются как раз для того, чтобы исполнять функции параллельно с основным кодом. То есть, асинхронные вызовы — самый распространённый способ управления распараллеливанием на уровне кода.
📌Конкурентность обеспечивает выполнение нескольких задач посредством переключения контекста.
Конкурентные вычисления реализуются на одном ядре системы. Примитивы конкурентности в Go:
— горутины;
— каналы;
— мьютексы (объекты Mutex, RWMutex);
— оператор select … case;
— объекты waitGroup, errGroup.
Конкурентность позволяет увеличить скорость обработки данных при наличии ресурсов, если выполнять те же задачи, которые можно выполнять последовательно.
Сначала надо вспомнить о таких вещах, как асинхронность и параллельность.
📌Асинхронность говорит о порядке исполнения кода. Вычисления в системе могут идти двумя способами:
— когда код выполняется последовательно — синхронно;
— когда результат выполнения кода доступен не сразу, а через некоторое время в виде некоторого асинхронного (нарушающего обычный порядок выполнения) вызова, — асинхронно.
📌Параллельность в свою очередь говорит о том, что физически происходит несколько процессов одновременно.
При этом, с точки зрения кода программы это всё может выглядеть вполне синхронно. Например, если подряд вызываются две функции, то исполняющая среда может решить по каким-то признакам, что эти функции независимы, и выполнить их параллельно. С точки зрения программы этого заметно не будет.
На практике, конечно, эти понятия пересекаются очень часто, потому что асинхронные вызовы делаются как раз для того, чтобы исполнять функции параллельно с основным кодом. То есть, асинхронные вызовы — самый распространённый способ управления распараллеливанием на уровне кода.
📌Конкурентность обеспечивает выполнение нескольких задач посредством переключения контекста.
Конкурентные вычисления реализуются на одном ядре системы. Примитивы конкурентности в Go:
— горутины;
— каналы;
— мьютексы (объекты Mutex, RWMutex);
— оператор select … case;
— объекты waitGroup, errGroup.
Конкурентность позволяет увеличить скорость обработки данных при наличии ресурсов, если выполнять те же задачи, которые можно выполнять последовательно.
🔥7👍4⚡1❤1
💬Что такое ООП и как эта методология реализована в Go?
Это методология, при которой программа рассматривается как набор объектов, взаимодействующих друг с другом. У каждого есть свойства и поведение. Каждый объект является экземпляром определённого класса, а классы образуют иерархию наследования.
Основные принципы ООП:
🔸Абстракция
🔸Инкапсуляция
🔸Наследование
🔸Полиморфизм
📌Но! В Go нет классов, объектов, исключений и шаблонов. Нет иерархии типов, но есть сами типы — то есть возможность описывать свои типы/структуры. Структурные типы (с методами) служат тем же целям, что и классы в других языках.
📌В Go мы можем выражать все прямолинейно, в отличие от использования классов, то есть отдельно описывать свойства, а отдельно поведение, и использовать композицию вместо привычного наследования, которого в Go нет.
📌В Go есть интерфейсы — типы, которые объявляют наборы методов. Подобно интерфейсам в других языках, они не имеют реализации. Объекты, которые реализуют все методы интерфейса, автоматически реализуют интерфейс.
📌Инкапсуляция в Go реализована на уровне пакетов. Имена, начинающиеся со строчной буквы, видны только внутри этого пакета (не являются экспортируемыми). И наоборот — все, что начинается с заглавной буквы — доступно извне пакета.
Это методология, при которой программа рассматривается как набор объектов, взаимодействующих друг с другом. У каждого есть свойства и поведение. Каждый объект является экземпляром определённого класса, а классы образуют иерархию наследования.
Основные принципы ООП:
🔸Абстракция
🔸Инкапсуляция
🔸Наследование
🔸Полиморфизм
📌Но! В Go нет классов, объектов, исключений и шаблонов. Нет иерархии типов, но есть сами типы — то есть возможность описывать свои типы/структуры. Структурные типы (с методами) служат тем же целям, что и классы в других языках.
📌В Go мы можем выражать все прямолинейно, в отличие от использования классов, то есть отдельно описывать свойства, а отдельно поведение, и использовать композицию вместо привычного наследования, которого в Go нет.
📌В Go есть интерфейсы — типы, которые объявляют наборы методов. Подобно интерфейсам в других языках, они не имеют реализации. Объекты, которые реализуют все методы интерфейса, автоматически реализуют интерфейс.
📌Инкапсуляция в Go реализована на уровне пакетов. Имена, начинающиеся со строчной буквы, видны только внутри этого пакета (не являются экспортируемыми). И наоборот — все, что начинается с заглавной буквы — доступно извне пакета.
👍4🤔1
Каналы представляют инструменты коммуникации между горутинами.
Технически это конвейер/труба, откуда можно считывать или помещать данные. То есть одна горутина может отправить данные в канал, а другая — считать помещенные в этот канал данные.
📌Для создания канала в Go есть ключевое слово
chan
. Канал может передавать данные только одного типа.package main
import "fmt"
func main() {
var c chan int
fmt.Println(c)
}
При простом определении переменной канала она имеет значение nil, то есть по сути канал неинициализирован. Для инициализации применяется функция make().
В зависимости от определения емкости канала он может быть буферизированным или небуферизированным.
📌Для создания небуферизированного канала вызывается функция
make()
без указания емкости канала:var intCh chan int = make(chan int)
📌Буферизированные каналы также создаются с помощью функции make(), только в качестве второго аргумента в функцию передается емкость канала. Если канал пуст, то получатель ждет, пока в канале появится хотя бы один элемент.
chanBuf := make(chan bool, 3)
📌С каналом можно произвести 4 действия:
— создать канал;
— записать данные в канал;
— вычесть что-то из канала;
— закрыть канал.
📌Однонаправленные каналы: в Go можно определить канал, как доступный только для отправки данных или только для получения данных.
📌Канал может быть возвращаемым значением функции. Однако следует внимательно подходить к операциям записи и чтения в возвращаемом канале.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥4
Go имеет ряд встроенных типов данных, а также он позволяет определять свои типы.
📌Целочисленные типы
▫️int8: представляет целое число от -128 до 127 и занимает в памяти 1 байт (8 бит).
▫️int16: представляет целое число от -32768 до 32767 и занимает в памяти 2 байта (16 бит).
▫️int32: представляет целое число от -2147483648 до 2147483647 и занимает 4 байта (32 бита).
▫️int64: представляет целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт (64 бита).
▫️uint8: представляет целое число от 0 до 255 и занимает 1 байт.
▫️uint16: представляет целое число от 0 до 65535 и занимает 2 байта.
▫️uint32: представляет целое число от 0 до 4294967295 и занимает 4 байта.
▫️uint64: представляет целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт.
▫️byte: синоним типа uint8, представляет целое число от 0 до 255 и занимает 1 байт.
▫️rune: синоним типа int32, представляет целое число от -2147483648 до 2147483647 и занимает 4 байта.
▫️int: представляет целое число со знаком, которое в зависимости от платформы может занимать либо 4 байта, либо 8 байт. То есть соответствовать либо int32, либо int64.
▫️uint: представляет 32-битные или 64-битные числа без знака (в зависимости от платформы).
📌Числа с плавающей точкой
▫️float32: представляет число с плавающей точкой от 1.4*10-45 до 3.4*1038 (для положительных). Занимает в памяти 4 байта (32 бита)
▫️float64: представляет число с плавающей точкой от 4.9*10-324 до 1.8*10308 (для положительных) и занимает 8 байт.
📌Комплексные числа
▫️complex64: комплексное число, где вещественная и мнимая части представляют числа float32.
▫️complex128: комплексное число, где вещественная и мнимая части представляют числа float64.
📌Тип bool: может иметь одно из двух значений: true (истина) или false (ложь).
📌Строки представлены типом string. В Go строке соответствует строковый литерал, но кроме обычных символов строка может содержать специальные последовательности, которые начинаются с обратного слеша \.
📌Если переменной не присвоено значение, то она имеет значение по умолчанию, которое определено для ее типа. Для числовых типов это число 0, для логического типа — false, для строк — "" (пустая строка).
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍1