Golang | Вопросы собесов
4.33K subscribers
28 photos
698 links
Download Telegram
🤔 Что такое РПС?

РПС (RPC, Remote Procedure Call) — это технология, которая позволяет программе вызывать функции (процедуры) на удалённых машинах, как если бы они были локальными. В контексте программирования на Go, РПС используется для организации взаимодействия между разными частями распределённых систем.

🚩Зачем нужен РПС

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

🚩Как используется РПС в Go

🟠В языке Go для реализации РПС используется стандартная библиотека net/rpc, а также сторонние библиотеки, такие как gRPC, которые обеспечивают более широкие возможности и поддержку разных протоколов.
// Сервисная часть

package main

import (
"net"
"net/rpc"
)

// Определяем структуру и методы, которые будут доступны через RPC
type Arith int

func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
}

type Args struct {
A, B int
}

func main() {
arith := new(Arith)
rpc.Register(arith)
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("Listen error: ", err)
}
rpc.Accept(listener)
}


🟠В этом примере мы определяем серверную часть, которая предоставляет метод Multiply для умножения двух чисел, и клиентскую часть, которая вызывает этот метод на удалённом сервере.
// Клиентская часть

package main

import (
"fmt"
"log"
"net/rpc"
)

type Args struct {
A, B int
}

func main() {
client, err := rpc.Dial("tcp", "localhost:1234")
if err != nil {
log.Fatal("Dialing error: ", err)
}

args := Args{2, 3}
var reply int
err = client.Call("Arith.Multiply", &args, &reply)
if err != nil {
log.Fatal("Arith error: ", err)
}
fmt.Printf("Result: %d\n", reply)
}


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

HTTPS (HyperText Transfer Protocol Secure) — это расширение протокола HTTP, которое обеспечивает безопасную передачу данных между веб-браузером пользователя и сервером. HTTPS использует протоколы шифрования, такие как TLS (Transport Layer Security) или его предшественник SSL (Secure Sockets Layer), чтобы защитить передаваемые данные от перехвата и манипуляций.

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

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

🟠Аутентификация:
Подтверждение подлинности сервера (и иногда клиента) с помощью цифровых сертификатов. Сертификаты, выданные доверенными центрами сертификации (CA), подтверждают, что сервер принадлежит законному владельцу.

🟠Целостность данных:
Обеспечение защиты данных от изменения во время передачи. Хеш-функции и контрольные суммы используются для проверки целостности передаваемых данных.

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

1⃣Установка защищенного соединения:
Клиент отправляет запрос на сервер, указывая, что хочет установить защищенное соединение (например, https://example.com). Сервер отвечает, отправляя свой цифровой сертификат, который содержит публичный ключ сервера и данные о сервере.

2⃣Проверка сертификата:
Клиент проверяет сертификат с помощью списка доверенных центров сертификации (CA), чтобы удостовериться в подлинности сервера.

3⃣Создание сессионных ключей:
Клиент и сервер используют асимметричное шифрование для обмена сессионными ключами. Эти ключи будут использоваться для симметричного шифрования данных во время сессии.

4⃣Шифрование данных:
После установки защищенного соединения все данные между клиентом и сервером передаются в зашифрованном виде с использованием сессионных ключей.

🚩Плюсы

Безопасность:
Шифрование данных защищает их от перехвата и кражи, особенно на общественных сетях и Wi-Fi.
Доверие пользователей:
Наличие HTTPS улучшает доверие пользователей к веб-сайту, что может повысить количество посетителей и конверсии.
SEO-приоритеты:
Поисковые системы, такие как Google, дают предпочтение сайтам, использующим HTTPS, в своих рейтингах.
Защита от атак:
HTTPS помогает защититься от атак типа "человек посередине" (MITM), при которых злоумышленники могут перехватывать и изменять данные.

🚩Минусы

Производительность:
Установка и поддержка защищенного соединения требует дополнительных вычислительных ресурсов, что может немного замедлить загрузку страниц.
Стоимость:
Приобретение и обновление сертификатов могут требовать дополнительных затрат, хотя существуют и бесплатные решения, такие как Let’s Encrypt.

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

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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое 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
🤔 Что такое горутины?

Горутины — это легковесные потоки выполнения, которые выполняются параллельно в рамках одного процесса в Go. Они создаются с помощью ключевого слова `go` и могут быть выполнены одновременно, не требуя создания полноценного системного потока. Горутины потребляют меньше ресурсов, чем традиционные потоки, и могут работать асинхронно. Планировщик Go автоматически управляет их выполнением и распределяет между ядрами процессора.

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

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

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

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

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

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

🚩Версии TLS

🟠TLS 1.0 (1999):
Улучшение по сравнению с SSL 3.0, но устаревший.
🟠TLS 1.1 (2006):
Дополнительные защиты, но также устаревший.
🟠TLS 1.2 (2008):
Современные алгоритмы шифрования, улучшенная безопасность.
🟠TLS 1.3 (2018): Повышенная безопасность и производительность, упрощенная установка соединения.

🚩Плюсы:

Высокий уровень безопасности:
Современные алгоритмы шифрования и хеширования.
Улучшенная производительность:
TLS 1.3 снижает задержки при установке соединения.
Широкая поддержка:
Поддерживается большинством современных браузеров и серверов.

🚩Минусы:

Сложность настройки и управления:
Особенно для крупных систем.
Производительность:
Шифрование требует дополнительных вычислительных ресурсов.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TLS Example</title>
</head>
<body>
<h1>Welcome to Secure Site</h1>
<p>Your connection to this site is secure with HTTPS using TLS.</p>
</body>
</html>


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

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

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

Да, между SSL (Secure Sockets Layer) и TLS (Transport Layer Security) есть отличия. TLS является улучшенной и более безопасной версией SSL.

🚩История и версия

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

🟠TLS:
TLS 1.0: Выпущен в 1999 году как обновление SSL 3.0. Включает исправления безопасности и улучшения.
TLS 1.1: Выпущен в 2006 году с дополнительными защитами от некоторых атак.
TLS 1.2: Выпущен в 2008 году, поддерживает современные алгоритмы шифрования и хеширования.
TLS 1.3: Выпущен в 2018 году, значительно улучшена безопасность и производительность, упрощен процесс установки соединения.

🚩Технические отличия

🟠Алгоритмы шифрования:
SSL: Поддерживает более старые и менее безопасные алгоритмы шифрования.
TLS: Поддерживает более современные и безопасные алгоритмы шифрования. TLS 1.3 исключает поддержку устаревших алгоритмов и предлагает только современные безопасные алгоритмы.

🟠Процесс рукопожатия (Handshake):
SSL: Более сложный процесс рукопожатия, включающий несколько шагов, что делает его уязвимым для некоторых атак.
TLS: Улучшенный процесс рукопожатия, включая использование HMAC (Hash-based Message Authentication Code) для обеспечения целостности сообщения. TLS 1.3 значительно упрощает и ускоряет процесс рукопожатия.

🟠Целостность данных:
SSL: Использует комбинацию MD5 и SHA-1 для целостности данных, что не так безопасно по современным стандартам.
TLS: Использует HMAC с SHA-256 и другими современными алгоритмами для обеспечения целостности данных.

🟠Управление сеансами:
SSL: Меньше возможностей для управления сеансами.
TLS: Включает улучшенные механизмы для управления сеансами, такие как возобновление сеансов, что позволяет экономить время и ресурсы при повторных подключениях.

🚩Безопасность

🟠SSL: Уязвим для ряда атак, таких как POODLE, BEAST и другие, из-за устаревших и менее безопасных методов шифрования и проверки целостности.
🟠TLS: Значительно более безопасен благодаря устранению уязвимостей SSL и внедрению современных методов шифрования и проверки целостности. TLS 1.3 еще более безопасен благодаря исключению устаревших методов и упрощению процесса рукопожатия.

🚩Совместимость

🟠SSL: Практически не используется в современных системах из-за известных уязвимостей и устаревших методов безопасности.
🟠TLS: Широко поддерживается и используется в современных браузерах, серверах и других сетевых устройствах. TLS 1.2 и TLS 1.3 являются наиболее часто используемыми версиями.

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

Массивы в Go имеют фиксированную длину и содержат элементы одного типа, тогда как слайсы — динамические структуры, которые могут изменять свою длину. Слайсы являются ссылочными типами и указывают на массив, предоставляя часть или весь массив. При добавлении новых элементов слайс автоматически расширяет свой размер. Массивы редко используются напрямую из-за своей фиксированной длины, в отличие от слайсов, которые более гибкие.

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

Для проверки типа переменной во время выполнения используется конструкция type assertion: value, ok := x.(T), где T — предполагаемый тип, а ok указывает, совпал ли тип. Также можно использовать type switch: switch v := x.(type) { case int: // действия для int case string: // действия для string default: // другие типы }.

🟠Пакета `reflect`
Пакет reflect предоставляет механизмы для получения информации о типах переменных во время выполнения.
package main

import (
"fmt"
"reflect"
)

func main() {
var x interface{} = 42

// Получаем тип переменной x
t := reflect.TypeOf(x)
fmt.Println("Type:", t)
}


🟠`type assertion` (утверждения типа)
Этот метод позволяет проверить, соответствует ли переменная конкретному типу, и извлечь значение, если это так.
package main

import "fmt"

func main() {
var x interface{} = 42

// Проверка типа и извлечение значения
if val, ok := x.(int); ok {
fmt.Println("x is an int:", val)
} else {
fmt.Println("x is not an int")
}
}


🟠`type switch` (оператор switch для типов)
Этот метод удобен, если нужно проверить переменную на соответствие нескольким типам.
package main

import "fmt"

func main() {
var x interface{} = "Hello, World!"

switch v := x.(type) {
case int:
fmt.Println("x is an int:", v)
case string:
fmt.Println("x is a string:", v)
case bool:
fmt.Println("x is a bool:", v)
default:
fmt.Println("x is of unknown type")
}
}


🚩Объяснение методов

🟠Пакет `reflect`:
reflect.TypeOf(x): Возвращает объект типа reflect.Type, который содержит информацию о типе переменной x.
🟠Type assertion:
x.(int): Проверяет, является ли x переменной типа int, и возвращает значение и булево значение, указывающее, удалось ли утверждение типа.
🟠Type switch:
switch v := x.(type): Позволяет проверить переменную x на соответствие нескольким типам в одном блоке switch.

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

Map в Go — это структура данных, которая хранит пары ключ-значение и позволяет эффективно искать значение по ключу. Ключи в map должны быть уникальными, а значения могут быть любого типа. Map предоставляет быстрый доступ к данным, так как использует хеширование для организации хранения ключей. Операции вставки, удаления и поиска имеют сложность O(1) в среднем случае.

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

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

🚩Основные методы и подходы

🟠Юнит-тестирование
Проверка корректности отдельных компонентов системы. Используйте библиотеки для написания тестов, такие как testing в Go. Интеграционное тестирование Моки (mocking) и заглушки (stubs) для изоляции компонентов.
package main

import (
"testing"
)

func TestAdd(t *testing.T) {
result := Add(1, 2)
if result != 3 {
t.Errorf("Expected 3, got %d", result)
}
}


🟠Интеграционное тестирование
Проверка взаимодействия между компонентами системы.
Используйте контейнеризацию (например, Docker) для поднятия среды тестирования. Тестирование с использованием реальных баз данных, очередей сообщений и других внешних сервисов.
version: '3'
services:
app:
image: myapp:test
depends_on:
- db
db:
image: postgres:latest
environment:
POSTGRES_DB: testdb
POSTGRES_USER: user
POSTGRES_PASSWORD: password


🟠Тестирование на уровне системы (System Testing)
Проверка всей системы в целом, включая все её компоненты и их взаимодействие. Сценарии end-to-end (E2E) тестирования. Тестирование пользовательского интерфейса и API. Selenium для тестирования веб-интерфейсов. Postman или REST-assured для тестирования API.

🟠Тестирование производительности и нагрузки
Проверка системы на устойчивость к высоким нагрузкам и определение её производительности. Нагрузочные тесты для проверки, как система справляется с увеличением числа пользователей или запросов. Тесты стресс-тестирования для выявления пределов производительности системы. Тесты стабильности для проверки системы под постоянной нагрузкой в течение длительного времени. Apache JMeter Gatling Locust

🟠Тестирование отказоустойчивости (Fault Tolerance Testing)
Проверка способности системы справляться с отказами отдельных компонентов или сетевых сбоев. Имитация отказов компонентов (например, остановка сервиса или отключение узла).
Инструменты для хаос-тестирования (chaos engineering). Chaos Monkey от Netflix Gremlin

🟠Тестирование безопасности
Проверка системы на наличие уязвимостей и обеспечение её защиты от атак.Сканы уязвимостей. Тестирование на проникновение (penetration testing). OWASP ZAP Burp Suite

🟠Непрерывное тестирование (Continuous Testing)
Интеграция тестирования в процесс CI/CD для автоматизации и ускорения релизов. Настройка CI/CD конвейера для автоматического выполнения тестов при каждом изменении кода. Использование инструментов, таких как Jenkins, GitLab CI/CD или CircleCI.

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

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

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

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

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

🚩Атомарные операции

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

🟠Compare-And-Swap (CAS)
Сравнивает текущее значение переменной с ожидаемым и, если они совпадают, обновляет её новым значением.
🟠Fetch-And-Add
Атомарно увеличивает значение переменной и возвращает старое значение.

🚩Lock-free стек

Используются атомарные операции для безопасного добавления и удаления элементов.
package main

import (
"fmt"
"sync/atomic"
"unsafe"
)

type Node struct {
value int
next *Node
}

type Stack struct {
head *Node
}

func (s *Stack) Push(value int) {
newNode := &Node{value: value}
for {
oldHead := s.head
newNode.next = oldHead
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&s.head)), unsafe.Pointer(oldHead), unsafe.Pointer(newNode)) {
break
}
}
}

func (s *Stack) Pop() (int, bool) {
for {
oldHead := s.head
if oldHead == nil {
return 0, false
}
newHead := oldHead.next
if atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(&s.head)), unsafe.Pointer(oldHead), unsafe.Pointer(newHead)) {
return oldHead.value, true
}
}
}

func main() {
stack := &Stack{}
stack.Push(1)
stack.Push(2)
value, ok := stack.Pop()
if ok {
fmt.Println("Popped:", value)
} else {
fmt.Println("Stack is empty")
}
}


🚩Плюсы

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

🚩Минусы

Сложность разработки
Lock-free алгоритмы сложны в реализации и отладке.
Ограниченная поддержка
Не все языки и платформы полностью поддерживают атомарные операции.
Проблемы с масштабируемостью
Частые повторные попытки атомарных операций могут ухудшить масштабируемость.

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

В Go строки представляют собой неизменяемые последовательности байтов, закодированных в UTF-8. Под капотом строка — это структура, которая хранит указатель на массив байтов и длину строки. Строки неизменяемы, что означает, что при любых операциях с ними создается новая строка. Это обеспечивает безопасность и позволяет легко работать с текстом, но при этом делает операции изменения относительно дорогими.

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

🚩Сцепление (Coupling)

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

🟠Высокое сцепление (Tight Coupling)
Модули сильно зависят друг от друга.
Изменения в одном модуле могут потребовать изменений в других.
Сложнее тестировать и поддерживать код.
type User struct {
Name string
Age int
}

type UserService struct {
userRepository UserRepository
}

func (s *UserService) GetUser(id int) *User {
return s.userRepository.FindById(id)
}

type UserRepository struct{}

func (r *UserRepository) FindById(id int) *User {
// Логика доступа к базе данных
return &User{Name: "John", Age: 30}
}


🟠Низкое сцепление (Loose Coupling)
Модули имеют минимальные зависимости друг от друга.
Легче изменять, тестировать и повторно использовать код.
Использование интерфейсов и зависимостей через инъекцию (Dependency Injection).
type User struct {
Name string
Age int
}

type UserRepository interface {
FindById(id int) *User
}

type UserService struct {
userRepository UserRepository
}

func (s *UserService) GetUser(id int) *User {
return s.userRepository.FindById(id)
}


🚩Связанность (Cohesion)

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

🟠Низкая связанность (Low Cohesion):
Модуль выполняет несколько различных задач.
Трудно поддерживать и изменять код.
Класс, выполняющий и доступ к базе данных, и логику бизнес-правил, и обработку пользовательского интерфейса.
type UserService struct {
// Доступ к базе данных
db Database

// Логика бизнес-правил
businessLogic BusinessLogic

// Логика уведомлений
notificationService NotificationService
}

func (s *UserService) ProcessUser(id int) {
user := s.db.FindUserById(id)
s.businessLogic.ApplyRules(user)
s.notificationService.Notify(user)
}


🟠Высокая связанность (High Cohesion):
Модуль сфокусирован на выполнении одной задачи.
Легче понимать, поддерживать и изменять код.
Класс, выполняющий только одну роль, такую как управление пользователями или обработка платежей.
type UserService struct {
userRepository UserRepository
}

func (s *UserService) GetUser(id int) *User {
return s.userRepository.FindById(id)
}


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

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

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

🚩pprof

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

🟠Включение профилирования
Для включения профилирования в вашем приложении, вам нужно импортировать пакет net/http/pprof и запустить HTTP-сервер.
package main

import (
_ "net/http/pprof"
"log"
"net/http"
)

func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// Ваше основное приложение
select {}
}


🟠Сбор профилей памяти
После запуска приложения с включенным pprof, вы можете собирать профили памяти с помощью HTTP-запросов.
go tool pprof http://localhost:6060/debug/pprof/heap


Для получения профиля CPU:
go tool pprof http://localhost:6060/debug/pprof/profile


🟠Анализ профилей
После того как вы собрали профиль, вы можете анализировать его с помощью команды go tool pprof. Это откроет интерактивный интерфейс, где вы можете использовать различные команды для анализа профиля.
go tool pprof http://localhost:6060/debug/pprof/heap


🚩Команды

🟠top
Показывает функции, которые потребляют больше всего памяти.
🟠list <function>
Показывает использование памяти в конкретной функции.
🟠web
Генерирует и открывает графический отчет в веб-браузере.
package main

import (
_ "net/http/pprof"
"log"
"net/http"
"time"
)

func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()

// Создаем массив для потребления памяти
data := make([]byte, 100*1024*1024) // 100MB

// Заполняем массив данными
for i := range data {
data[i] = byte(i % 256)
}

// Ожидаем завершения приложения
time.Sleep(time.Hour)
}


🚩Плюсы

Подробный анализ
pprof предоставляет детализированную информацию о потреблении памяти и процессорного времени.
Визуализация
Возможность визуализации профилей в виде графов и диаграмм.
Интеграция с Go
Легко интегрируется в Go-приложения.

🚩Минусы

Накладные расходы
Профилирование может добавить накладные расходы, что может повлиять на производительность приложения.
Сложность анализа
Интерпретация результатов профилирования может быть сложной задачей и требует определенных навыков и опыта.

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

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

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

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

import (
_ "net/http/pprof"
"log"
"net/http"
)

func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
select {}
}


Затем соберите и проанализируйте профили:
go tool pprof http://localhost:6060/debug/pprof/profile


🟠Логирование и мониторинг
Помогает отслеживать производительность и выявлять аномалии. Логируйте время выполнения критических операций и ошибки. Используйте библиотеку log или сторонние решения, такие как logrus.
package main

import (
"log"
"time"
)

func main() {
start := time.Now()
// Выполнение задачи
log.Printf("Task completed in %s", time.Since(start))
}


🟠Трассировка (tracing)
Позволяет отслеживать путь запроса через различные сервисы и компоненты системы, выявляя медленные части. Используйте OpenTelemetry для интеграции трассировки.
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)

func main() {
tracer := otel.Tracer("example-tracer")
ctx, span := tracer.Start(context.Background(), "example-span")
defer span.End()
// Ваш код здесь
}


🟠Метрики и алертинг
Собирайте метрики производительности и настройте алерты для выявления аномалий. Используйте Prometheus для сбора метрик и Grafana для визуализации.
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
)

var (
requestDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "request_duration_seconds",
Help: "Duration of HTTP requests.",
})
)

func init() {
prometheus.MustRegister(requestDuration)
}

func handler(w http.ResponseWriter, r *http.Request) {
timer := prometheus.NewTimer(requestDuration)
defer timer.ObserveDuration()
// Ваш код здесь
}

func main() {
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}


🟠Анализ логов
Помогает выявить ошибки и проблемы производительности. Используйте системы сбора логов, такие как ELK Stack (Elasticsearch, Logstash, Kibana).

🟠Внешние инструменты мониторинга
Облачные сервисы мониторинга, такие как New Relic, Datadog или AWS CloudWatch, предоставляют мощные инструменты для мониторинга и анализа производительности.

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