Golang | Вопросы собесов
4.49K subscribers
28 photos
2 videos
775 links
Download Telegram
🤔 Можно ли изменить определенный символ в строке?

Нет, строки (string) в Go неизменяемы (immutable). Это значит, что нельзя просто изменить один символ в строке.

🚩Почему нельзя изменить символ?

Строка в Go — это байтовый срез ([]byte), но неизменяемый. Когда вы создаёте строку
s := "hello"


Ошибка при попытке изменения символа напрямую
s := "hello"
s[0] = 'H' // Ошибка: cannot assign to s[0]


🚩Как изменить символ в строке?

Поскольку строка неизменяема, вам нужно создать новую строку с заменённым символом.
Способ 1: Преобразовать в []byte (для ASCII-строк)
Если строка содержит только английские буквы и символы ASCII, её можно преобразовать в []byte, заменить символ и создать новую строку.
package main

import "fmt"

func main() {
s := "hello"
b := []byte(s) // Преобразуем в изменяемый []byte
b[0] = 'H' // Меняем первый символ
s = string(b) // Преобразуем обратно в строку

fmt.Println(s) // "Hello"
}


Способ 2: Преобразовать в []rune (для Unicode)
Если строка содержит русские буквы, эмодзи или другие многобайтовые символы, используйте []rune.
package main

import "fmt"

func main() {
s := "привет"
r := []rune(s) // Преобразуем в []rune (массив символов)
r[0] = 'П' // Меняем первый символ
s = string(r) // Преобразуем обратно в строку

fmt.Println(s) // "Привет"
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2💊1
🤔 Что такое репликация?

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

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

ACID — это набор свойств транзакций в базах данных, обеспечивающий надежность и целостность данных.

🚩ACID

🟠A (Atomicity) — Атомарность
Транзакция выполняется либо полностью, либо не выполняется вовсе.
Пример: Если при переводе денег со счета A на счет B ошибка произошла на полпути, изменения откатываются.

🟠C (Consistency) — Согласованность
Данные остаются в правильном состоянии до и после транзакции.
Пример: Если сумма на всех счетах банка должна оставаться неизменной, транзакция не должна нарушить это правило.

🟠I (Isolation) — Изолированность
Одновременные транзакции не мешают друг другу.
Пример: Два клиента покупают один и тот же товар, но база данных правильно обрабатывает, кто купил первым.

🟠D (Durability) — Долговечность
После завершения транзакции изменения сохраняются, даже если система сломается.
Пример: Если заказ оформлен, он не исчезнет при внезапном отключении электричества.

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

Go использует трассирующий сборщик мусора с метками (mark-and-sweep).
Он проходит в два этапа:
1. Mark — находят все доступные (живые) объекты.
2. Sweep — освобождают недоступные (мертвые) объекты.
GC работает инкрементально и в параллель с приложением, начиная с Go 1.5.


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

Существуют встроенные функции для преобразования типов, включая преобразование из строки в целое число и наоборот. Для этих целей используются функции из стандартной библиотеки strconv. Рассмотрим, как это делается.

🚩Преобразование строки в целое число

Для этого используется функция strconv.Atoi. Она возвращает два значения: само число и ошибку, если преобразование не удалось.
package main

import (
"fmt"
"strconv"
)

func main() {
str := "123"
num, err := strconv.Atoi(str)
if err != nil {
fmt.Println("Error converting string to int:", err)
} else {
fmt.Println("Converted number:", num)
}
}


🚩Преобразование целого числа в строку

Для этого используется функция strconv.Itoa.
package main

import (
"fmt"
"strconv"
)

func main() {
num := 123
str := strconv.Itoa(num)
fmt.Println("Converted string:", str)
}


🚩Обработка ошибок при преобразовании

Важно обрабатывать ошибки при преобразовании типов, особенно при преобразовании строки в целое число, чтобы избежать неожиданных сбоев в программе.
package main

import (
"fmt"
"strconv"
)

func main() {
str := "abc"
num, err := strconv.Atoi(str)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Converted number:", num)
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Что находится перед названием метода?

Перед названием метода указывается ресивер — переменная, к которой метод привязан. Он описывается в круглых скобках перед именем метода и указывает, для какого типа метод определён.
Здесь u *User — это ресивер. Он определяет, что метод PrintName относится к типу User, и при вызове будет доступ к его полям.


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

Размер числа в байтах зависит от его типа данных. В Go есть несколько числовых типов, и каждый занимает определённое количество байтов в памяти.

🚩Проверка размера в Go (`unsafe.Sizeof`)

Можно проверить размер типа с помощью unsafe.Sizeof()
package main

import (
"fmt"
"unsafe"
)

func main() {
var a int64
var b float64
var c byte // то же самое, что uint8
fmt.Println("int64:", unsafe.Sizeof(a)) // 8
fmt.Println("float64:", unsafe.Sizeof(b)) // 8
fmt.Println("byte:", unsafe.Sizeof(c)) // 1
}


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

struct — это пользовательский тип данных в Go, который группирует поля с разными типами в единый объект. Структуры используются для моделирования сложных сущностей, таких как объекты реального мира, с их свойствами и поведением. Они позволяют организовать данные и методы, что делает код более читаемым и логичным. В отличие от классов в ООП, структуры Go не поддерживают наследование, но позволяют использовать композицию.

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

Карты (maps) реализованы на основе хеш-таблиц, что обеспечивает быстрый доступ к значениям по ключам. Давайте рассмотрим, как происходит поиск по ключу в карте, и какие этапы включены в этот процесс.

🚩Основные этапы

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

🟠Поиск в хеш-таблице
Хеш-значение используется для доступа к соответствующей "ячейке" или "корзине" (bucket) в хеш-таблице.

🟠Поиск в корзине
Если корзина содержит несколько элементов (из-за коллизий хеширования), Go выполняет линейный поиск среди этих элементов, сравнивая ключи с использованием оператора ==.

🚩Детали

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

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

🟠Линейный поиск внутри корзины
Если корзина содержит несколько элементов, Go выполняет линейный поиск среди этих элементов. Для каждого элемента в корзине сравнивается ключ с искомым ключом с использованием оператора ==. Если ключи совпадают, возвращается соответствующее значение. Если ключ не найден, возвращается нулевое значение типа (zero value) и флаг, указывающий на отсутствие ключа.

package main

import "fmt"

func main() {
myMap := map[string]int{
"Alice": 25,
"Bob": 30,
}

value, exists := myMap["Alice"]
if exists {
fmt.Println("Alice:", value) // Alice: 25
} else {
fmt.Println("Alice not found")
}

value, exists = myMap["Charlie"]
if exists {
fmt.Println("Charlie:", value)
} else {
fmt.Println("Charlie not found") // Charlie not found
}
}


🚩Подводные камни и особенности

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

🟠Производительность
В среднем, доступ к элементу в карте осуществляется за константное время O(1), что делает карты очень эффективными для поиска по ключу. Однако в худшем случае, при большой нагрузке коллизий, производительность может деградировать до линейного времени O(n).

🟠Изменение карты во время поиска
Карты не являются потокобезопасными. Если одна горутина изменяет карту, в то время как другая горутина читает из нее, это может привести к панике. Для обеспечения потокобезопасности используйте мьютексы или структуру sync.Map.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Чем юнит-тесты отличаются от интеграционных?

- Юнит-тесты проверяют отдельные функции или методы в изоляции от остального кода. Быстрые, лёгкие, часто запускаются.
- Интеграционные тесты проверяют взаимодействие между компонентами, например, работу сервиса с базой или API с внешней системой.
Юнит-тесты дают быструю обратную связь, интеграционные — показывают, как работает система целиком.


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

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

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

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

import (
"fmt"
"sync"
"time"
)

func worker(stopCh <-chan struct{}, wg *sync.WaitGroup, id int) {
defer wg.Done()
for {
select {
case <-stopCh:
fmt.Printf("Worker %d stopping\n", id)
return
default:
// выполнение полезной работы
fmt.Printf("Worker %d working\n", id)
time.Sleep(time.Second)
}
}
}

func main() {
var wg sync.WaitGroup
stopCh := make(chan struct{})

// запуск горутин
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(stopCh, &wg, i)
}

// остановка горутин после 3 секунд
time.Sleep(3 * time.Second)
close(stopCh) // отправка сигнала всем горутинам остановиться
wg.Wait() // ожидание завершения всех горутин
}


🟠Использование пакета context

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

import (
"context"
"fmt"
"sync"
"time"
)

func worker(ctx context.Context, wg *sync.WaitGroup, id int) {
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Printf("Worker %d stopping\n", id)
return
default:
// выполнение полезной работы
fmt.Printf("Worker %d working\n", id)
time.Sleep(time.Second)
}
}
}

func main() {
var wg sync.WaitGroup
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)

// запуск горутин
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(ctx, &wg, i)
}

wg.Wait() // ожидание завершения всех горутин
cancel() // убедиться, что все ресурсы освобождены
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Разница между WHERE и HAVING:

`WHERE` применяется до агрегации для фильтрации строк, а `HAVING` используется после агрегации для фильтрации агрегированных данных. Это значит, что `HAVING` может использоваться для условий, которые зависят от результатов функций агрегирования, таких как SUM или COUNT.

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

SSL (Secure Sockets Layer) — это протокол, который обеспечивает безопасность передачи данных в интернете, используя шифрование. Он был разработан для защиты данных, передаваемых между клиентом (например, веб-браузером) и сервером (например, веб-сайтом), от перехвата и манипуляций.

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

🟠Шифрование:
Защита данных от перехвата и чтения посторонними лицами путем их шифрования.
🟠Аутентификация:
Подтверждение подлинности сервера (и иногда клиента) с помощью цифровых сертификатов, что позволяет клиенту убедиться, что он подключен к настоящему серверу.
🟠Целостность данных:
Проверка того, что данные не были изменены во время передачи, с помощью контрольных сумм и хеш-функций.

🚩Как работает

1⃣Установка соединения:
Клиент инициирует соединение с сервером, запрашивая защищенное соединение.
2⃣Передача сертификата:
Сервер отправляет свой цифровой сертификат, который содержит его публичный ключ и информацию о сервере.
3⃣Проверка сертификата:
Клиент проверяет сертификат, используя доверенные центры сертификации (CA), чтобы удостовериться в подлинности сервера.
4⃣Создание сессионных ключей:
Клиент и сервер используют асимметричное шифрование для обмена ключами сеанса, которые затем используются для симметричного шифрования данных в течение сессии.
5⃣Шифрование данных:
Все данные, передаваемые между клиентом и сервером, шифруются с использованием симметричных ключей, обеспечивая безопасность передачи.

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

При посещении веб-сайта с использованием HTTPS (например, https://example.com), SSL обеспечивает шифрование и безопасность данных, передаваемых между вашим браузером и сервером.

🚩Развитие

🟠SSL 1.0:
Никогда не был выпущен публично из-за серьезных уязвимостей.
🟠SSL 2.0:
Выпущен в 1995 году, но вскоре был признан небезопасным из-за множества уязвимостей.
🟠SSL 3.0:
Выпущен в 1996 году, значительно улучшил безопасность, но со временем также был признан устаревшим из-за уязвимостей (например, POODLE-атака).

🚩TLS как наследник SSL

🟠TLS (Transport Layer Security):
SSL был заменен протоколом TLS, который является его преемником и предлагает улучшенную безопасность. Текущие версии TLS (1.2 и 1.3) используются вместо SSL.
🟠Основные отличия:
TLS обеспечивает более сильное шифрование, лучшее управление сессионными ключами и устранение уязвимостей, найденных в SSL.

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

Git — это распределённая система контроля версий, которая позволяет:
- Отслеживать изменения в коде.
- Создавать ветки и экспериментировать без риска.
- Сотрудничать над проектами в команде. Git хранит историю в виде снимков состояний (commit), а не разницы (diff), что делает его быстрым и надёжным.


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

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

🚩Для чего нужны индексы?

🟠Доступ к элементам по их позиции
Индексы позволяют обращаться к конкретным элементам массива, строки или среза. Например, если у нас есть массив чисел, индекс указывает, какой именно элемент извлечь.

🟠Навигация внутри коллекций
С помощью индексов можно перебирать элементы массива, строки или среза, например, используя циклы.

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

🟠Оптимизация поиска
Индексы упрощают и ускоряют доступ к данным, потому что доступ осуществляется за O(1) (константное время) в массивах или срезах.

🟠Индексы в строках
В строках индексы используются для доступа к конкретным байтам.
package main

import "fmt"

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

fmt.Println(str[0]) // 208 (байт, не символ!)
fmt.Printf("%c\n", str[0]) // П (символ, представленный первым байтом UTF-8)
}


🟠Индексы в массивах и срезах
В массивах и срезах индексы используются для извлечения и изменения значений
package main

import "fmt"

func main() {
arr := [5]int{10, 20, 30, 40, 50}

fmt.Println(arr[2]) // 30

// Изменение значения по индексу
arr[2] = 100
fmt.Println(arr) // [10 20 100 40 50]
}


🟠Как использовать индексы в циклах
Обычно индексы используются для итерации по элементам коллекции с помощью цикла for.
package main

import "fmt"

func main() {
nums := []int{10, 20, 30, 40, 50}

for i, v := range nums {
fmt.Printf("Индекс: %d, Значение: %d\n", i, v)
}
}


🟠Индексы и подстроки
Индексы полезны для извлечения подстрок с использованием срезов:
package main

import "fmt"

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

fmt.Println(str[8:12]) // Мир
}


🚩Ошибки работы с индексами

🟠Выход за границы
Если попытаться обратиться к элементу по индексу, который выходит за пределы коллекции, Go выдаст runtime panic:

   package main

func main() {
nums := []int{1, 2, 3}
fmt.Println(nums[5]) // panic: runtime error: index out of range
}


🟠Работа с многобайтовыми символами в строках
Если неверно учитывать байтовое представление символов UTF-8, можно получить некорректный результат.

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

Куча — это область памяти, где:
- Выделение динамическое (во время выполнения).
- Используется для объектов переменной длины и длительного хранения.
- Управляется аллокатором или сборщиком мусора.
- Может фрагментироваться.
- Поддерживает аллокации разного размера, отслеживает свободные блоки.
В языках с GC куча управляется автоматически. В C/C++ — вручную через malloc/free.


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

Это неизменяемые последовательности байтов, обычно представляющие текст в кодировке UTF-8. Работа с ними в Go основывается на использовании встроенных функций, методов стандартной библиотеки и специальных типов данных.

🟠Конкатенация строк
Самый простой способ объединить строки — использовать оператор + или функцию fmt.Sprintf.
package main

import "fmt"

func main() {
s1 := "Привет"
s2 := "Мир"
result := s1 + ", " + s2 + "!"
fmt.Println(result) // Привет, Мир!

// Через fmt.Sprintf
formatted := fmt.Sprintf("%s, %s!", s1, s2)
fmt.Println(formatted) // Привет, Мир!
}


🟠Получение длины строки
Функция len возвращает длину строки в байтах, а не в символах.
package main

import "fmt"

func main() {
str := "Привет"
fmt.Println(len(str)) // 12, так как кириллические символы занимают 2 байта
}


🟠Итерация по строке
Строки можно обойти как в виде байтов, так и в виде рун (Unicode символов).
package main

import (
"fmt"
"unicode/utf8"
)

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

// Итерация по байтам
for i := 0; i < len(str); i++ {
fmt.Printf("Байт: %x\n", str[i])
}

// Итерация по символам (рунам)
for _, runeValue := range str {
fmt.Printf("Символ: %c\n", runeValue)
}

// Количество рун
fmt.Println("Количество символов:", utf8.RuneCountInString(str))
}


🟠Извлечение подстроки
Так как строки неизменяемы, для извлечения подстроки используется срез (slice).
package main

import "fmt"

func main() {
str := "Привет, Мир!"
substring := str[8:] // С 8-го байта до конца
fmt.Println(substring) // Мир!
}


🟠Разделение и объединение строк
Функции strings.Split и strings.Join из пакета strings позволяют разбивать строку на части или объединять части в строку.
package main

import (
"fmt"
"strings"
)

func main() {
str := "apple,banana,cherry"

// Разделение строки
parts := strings.Split(str, ",")
fmt.Println(parts) // [apple banana cherry]

// Объединение строк
joined := strings.Join(parts, " | ")
fmt.Println(joined) // apple | banana | cherry
}


🟠Поиск и замена подстроки
Для поиска подстроки можно использовать strings.Contains, strings.Index или strings.HasPrefix/strings.HasSuffix. Для замены — strings.Replace.
package main

import (
"fmt"
"strings"
)

func main() {
str := "Go — это круто!"

// Поиск подстроки
fmt.Println(strings.Contains(str, "круто")) // true
fmt.Println(strings.Index(str, "это")) // 4

// Замена подстроки
newStr := strings.Replace(str, "круто", "отлично", 1)
fmt.Println(newStr) // Go — это отлично!
}


🟠Преобразование регистра
Стандартная библиотека предоставляет функции для изменения регистра строки: strings.ToLower и strings.ToUpper.
package main

import (
"fmt"
"strings"
)

func main() {
str := "Hello, Go!"
fmt.Println(strings.ToUpper(str)) // HELLO, GO!
fmt.Println(strings.ToLower(str)) // hello, go!
}


🟠Тримминг строки
Удаление пробелов или других символов с начала/конца строки выполняется с помощью strings.Trim, strings.TrimSpace и других функций.
package main

import (
"fmt"
"strings"
)

func main() {
str := " Hello, Go! "
fmt.Println(strings.TrimSpace(str)) // "Hello, Go!"
}


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

Можно: Использовать каналы для безопасной передачи данных между горутинами.
Нельзя: Изменять данные внутри канала без защиты, если они используются несколькими горутинами.


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

Структуры (struct) представляют собой агрегированные типы данных, которые позволяют объединять несколько различных типов данных под одним именем. Они служат для моделирования объектов и хранения связанных данных, предоставляя удобный способ управления сложными данными.

🚩Определение структуры

Определяются с использованием ключевого слова struct. В структуре могут быть поля различных типов.
package main

import "fmt"

// Определение структуры Person
type Person struct {
Name string
Age int
}

func main() {
// Создание экземпляра структуры
var p Person
p.Name = "Alice"
p.Age = 30

fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
}


🚩Инициализация структур

Существует несколько способов инициализации структур.
package main

import "fmt"

// Определение структуры Person
type Person struct {
Name string
Age int
}

func main() {
// Инициализация с использованием литерала структуры
p := Person{Name: "Bob", Age: 25}
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
}


Инициализация по умолчанию
package main

import "fmt"

// Определение структуры Person
type Person struct {
Name string
Age int
}

func main() {
// Инициализация по умолчанию (поля будут нулевыми значениями)
var p Person
fmt.Println("Name:", p.Name) // Пустая строка
fmt.Println("Age:", p.Age) // 0
}


🚩Вложенные структуры

Могут содержать другие структуры в качестве полей, что позволяет моделировать более сложные данные.
package main

import "fmt"

// Определение структур Address и Person
type Address struct {
City string
State string
}

type Person struct {
Name string
Age int
Address Address
}

func main() {
// Инициализация структуры с вложенной структурой
p := Person{
Name: "Charlie",
Age: 40,
Address: Address{
City: "New York",
State: "NY",
},
}

fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
fmt.Println("City:", p.Address.City)
fmt.Println("State:", p.Address.State)
}


🚩Методы структур

Могут быть ассоциированы со структурами, что позволяет добавлять функциональность к структурам.
package main

import "fmt"

// Определение структуры Person
type Person struct {
Name string
Age int
}

// Метод для структуры Person
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}

func main() {
p := Person{Name: "David", Age: 35}
p.Greet()
}



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

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

Эти термины часто встречаются в gRPC и API:
- Unary — классический вызов: клиент делает запрос, сервер возвращает единственный ответ.
- Stream — потоковая передача:
- Server streaming — сервер отправляет несколько ответов.
- Client streaming — клиент отправляет поток данных.
- Bidirectional — оба обмениваются потоками данных.
Streaming нужен, когда нужно передавать большие объёмы или непрерывный поток данных.


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