Go собеседования
634 subscribers
106 photos
224 links
Подготовка к собеседованиям на позицию Go-разработчик

Еще больше на сайте https://frontview-it.ru

Backend собеседования - @frontview_backend
Go работа - @frontview_go_vacancies
Все IT вакансии - @frontview_all_vacancies
Download Telegram
CORS (Cross-Origin Resource Sharing) используется для контроля доступа к API с других доменов. В Go можно настроить CORS с помощью middleware, например, используя пакет github.com/rs/cors.


package main

import (
"net/http"
"github.com/rs/cors"
)

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("API response"))
})

handler := cors.New(cors.Options{
AllowedOrigins: []string{"https://example.com"},
AllowedMethods: []string{"GET", "POST"},
}).Handler(mux)

http.ListenAndServe(":8080", handler)
}


В этом примере настроен CORS, разрешающий запросы только с домена https://example.com и методы GET и POST. Это помогает защитить API от несанкционированного доступа.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
🟡 Пакет strconv предоставляет функции для преобразования строк в базовые типы и обратно. Основные функции включают Atoi и Itoa для работы с целыми числами, а также ParseFloat, ParseInt, ParseUint для более сложных преобразований.


s := "123"
i, err := strconv.Atoi(s) // строка в int
if err != nil {
// обработка ошибки
}
s2 := strconv.Itoa(i) // int в строку


Для преобразования чисел с плавающей точкой используется ParseFloat:


f, err := strconv.ParseFloat("3.14", 64) // строка в float64
if err != nil {
// обработка ошибки
}


Функции ParseInt и ParseUint позволяют указывать основание системы счисления и размер типа:


n, err := strconv.ParseInt("FF", 16, 64) // строка в int64, основание 16
if err != nil {
// обработка ошибки
}


Пакет также поддерживает преобразование в булевы значения через ParseBool.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Функция context.WithCancel создает новый контекст и функцию отмены, которая позволяет завершить выполнение операций, связанных с этим контекстом. Обычно используется для управления временем жизни горутин или прерывания долгих операций.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
▶️Type switch в Go позволяет определить тип значения, хранящегося в интерфейсе, и выполнить соответствующий блок кода. Используется вместе с switch и ключевым словом type.


func checkType(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("Это int:", v)
case string:
fmt.Println("Это string:", v)
default:
fmt.Println("Неизвестный тип")
}
}


В этом примере i.(type) определяет тип значения, хранящегося в интерфейсе i. Каждый case проверяет тип и выполняет соответствующий код. Переменная v автоматически получает значение правильного типа внутри каждого блока case.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Пакет (package) — это способ организации кода, который объединяет связанные функции, типы и переменные. Для объявления пакета используется ключевое слово package, за которым следует имя пакета, указанное в начале файла.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🔘Функции в Go объявляются с помощью ключевого слова func и могут принимать параметры, а также возвращать значения. Указатели хранят адрес переменной в памяти, позволяя работать с исходными данными, а не с их копией.


func modifyValue(ptr *int) {
*ptr = 10 // Изменение значения по указателю
}

value := 5
modifyValue(&value) // Передача указателя на переменную


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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Для создания нового файла используется функция os.Create, которая принимает путь к файлу и возвращает файловый объект и ошибку. Если файл уже существует, он будет перезаписан, а если нет — создан.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
🛑Команда go mod graph выводит граф зависимостей модуля в текстовом формате. Каждая строка вывода представляет собой пару модулей, где первый модуль зависит от второго. Это полезно для анализа зависимостей в проекте.


go mod graph


Вывод будет выглядеть примерно так:

main_module dependency_module@version
dependency_module@version another_dependency@version


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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
Для обработки POST-запросов используется метод r.Method == "POST" для проверки типа запроса, а данные из тела запроса извлекаются с помощью r.Body и декодируются в соответствующую структуру. Для работы с JSON часто применяется json.NewDecoder(r.Body).Decode(&targetStruct).

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🛑Паттерн Singleton гарантирует, что в программе существует только один экземпляр определенного типа. Реализация в Go может быть выполнена с использованием sync.Once для обеспечения потокобезопасности.


package main

import (
"sync"
)

type singleton struct {}

var (
instance *singleton
once sync.Once
)

func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}


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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101
Функция runtime.Goexit завершает выполнение текущей горутины, выполняя все отложенные вызовы defer перед завершением. Другие горутины продолжают работать, и программа не завершается, если есть активные горутины.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
sync.WaitGroup используется для ожидания завершения группы горутин. Он предоставляет методы Add() для увеличения счетчика, Done() для уменьшения и Wait() для блокировки до тех пор, пока счетчик не станет равным нулю.


var wg sync.WaitGroup
wg.Add(2) // Увеличиваем счетчик на 2

go func() {
defer wg.Done() // Уменьшаем счетчик при завершении
// Выполнение задачи
}()

go func() {
defer wg.Done() // Уменьшаем счетчик при завершении
// Выполнение задачи
}()

wg.Wait() // Ожидание завершения всех горутин


Этот механизм полезен для синхронизации выполнения нескольких горутин.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Для передачи указателя в функцию используется символ * перед типом параметра в объявлении функции. При вызове функции передается адрес переменной с помощью оператора &, что позволяет изменять значение переменной напрямую.

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
▶️Структуры в Go — это пользовательские типы данных, которые группируют поля с различными типами. Они используются для создания сложных структур данных.


type Person struct {
Name string
Age int
}


Указатели хранят адрес памяти переменной. Они позволяют работать с данными напрямую, избегая копирования. Указатель на структуру можно создать с помощью оператора &.


p := Person{Name: "John", Age: 30}
ptr := &p // Указатель на структуру Person


Доступ к полям структуры через указатель осуществляется с помощью оператора -> в других языках, но в Go используется тот же синтаксис, что и для обычных переменных:


ptr.Name = "Jane" // Изменение поля через указатель


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

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍611
🛑Для обработки PUT-запросов в Go используется пакет net/http. PUT-запросы обычно применяются для обновления существующих ресурсов.


func updateHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPut {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}

var data YourStruct
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}

// Логика обновления ресурса
w.WriteHeader(http.StatusOK)
}


Маршрутизация PUT-запроса на обработчик:


http.HandleFunc("/update", updateHandler)


В этом примере проверяется метод запроса, декодируется JSON-тело запроса и выполняется логика обновления. Ответ отправляется с соответствующим статус-кодом.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🟠Для удаления элемента из map используется встроенная функция delete. Она принимает map и ключ элемента, который нужно удалить. Если элемент с таким ключом существует, он будет удалён.


m := map[string]int{"a": 1, "b": 2}
delete(m, "a") // Удаляет элемент с ключом "a"


Если ключ отсутствует в map, функция delete не выполняет никаких действий и не возвращает ошибку.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
🔘Функция errors.As проверяет, содержится ли в цепочке ошибок ошибка определенного типа. Если такая ошибка найдена, она присваивается переменной, переданной вторым аргументом.


// Пользовательский тип ошибки
type NotFoundError struct {
Item string
}

func (e NotFoundError) Error() string {
return e.Item + " не найден"
}

func main() {
err := fetchData()

var notFoundErr NotFoundError
if errors.As(err, &notFoundErr) {
// Обработка ошибки типа NotFoundError
fmt.Println("Элемент:", notFoundErr.Item)
}
}


В отличие от errors.Is, которая сравнивает конкретные значения ошибок, errors.As работает с типами ошибок.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
➡️defer откладывает выполнение функции до момента завершения окружающей функции. Отложенные вызовы выполняются в порядке LIFO (последний добавленный - первый выполненный).


func processFile(filename string) error {
// Открываем файл
f, err := os.Open(filename)
if err != nil {
return err
}
// Гарантируем закрытие файла при выходе из функции
defer f.Close()

// Работаем с файлом...
return nil
}


Аргументы в defer вычисляются сразу, а не в момент выполнения:


func counter() {
i := 0
defer fmt.Println(i) // Выведет 0, а не 1
i++
// Другие операции...
}


Частые применения: освобождение ресурсов, закрытие соединений, логирование, обработка паники.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Замыкание — это функция, которая запоминает переменные из окружающей её области видимости, даже после выхода из неё. Это позволяет функции сохранять доступ к этим переменным при последующих вызовах.


func counter() func() int {
count := 0
return func() int {
count++
return count
}
}


Функция counter возвращает анонимную функцию, которая инкрементирует переменную count. Несмотря на то, что counter завершает работу, count остается доступным для анонимной функции благодаря замыканию.

Использование:

c := counter()
fmt.Println(c()) // 1
fmt.Println(c()) // 2


Замыкания часто применяют для инкапсуляции состояния и создания функций с памятью.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
➡️ Оператор make выделяет и инициализирует объекты типов slice, map и channel. В отличие от new, который возвращает указатель на нулевое значение, make возвращает готовый к использованию объект.

Для слайсов make задает длину и вместимость:

s := make([]int, 3, 5) // len=3, cap=5


Для мап make создает готовый к добавлению элементов словарь:

m := make(map[string]int)


Для каналов make инициализирует канал с указанным буфером:

ch := make(chan int, 10)


make гарантирует, что структуры данных будут проинициализированы и готовы к работе.

Ставь 👍, если было полезно!
Больше ответов на сайте 👈

✈️ Go собеседования
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10