Golang вопросы собеседований
13.5K subscribers
631 photos
4 videos
1 file
434 links
@notxxx1 - админ

@Golang_google - Golang для разработчиков

@itchannels_telegram - 🔥лучшие из ит

@golangl - chat

@golangtests - golang tests

@golang_jobsgo - go chat jobs

@ai_machinelearning_big_data - AI

@data_analysis_ml

РКН: clck.ru/3FmtKd
加入频道
💡 Топ 150 задач c собеседований.

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

Задачи, которые покрывают 90% задач, структур данных, алгоритмов которые спрашивают на собеседованиях.

📂 Список

@golang_interview
👣 Полезная статья, где описываются методы оптимизации Go кода

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

📎 Статья

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Мышление программиста Go и скиллы управления кибер-инцидентами в борьбе с диабетом

Статья о человеке, которому Go помогает справляться с диабетом.
Если вкратце, то парень использует Go и распределённую систему микросервисов, чтобы отслеживать уровень инсулина и сахара в крови и т.д.
Параллельно в статье рассказывается про такие инструменты как Prometheus, Grafana, PagerDuty, так что можно узнать много полезного.

📎 Статья

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Немного о записи в файл с помощью Go

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

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

В общем, использование буферизованного ввода-вывода может быть более эффективным по сравнению с небуферизованным.
При работе с большими файлами и необходимости минимизировать использование памяти, может быть целесообразно рассмотреть использование bufio.Scanner, который также использует буферизацию, но с более низким потреблением памяти.

📎 Здесь обсуждение проблемы записи в файл на Go, примеры кода на Python и C, очень полезно

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Как понять, что канал Go закрыт для записи?

Сразу перейдём к примеру. Закрытый канал не блокируется на чтение. Вот, тут довольно наглядно:
Loop:
for {
select {
case val, ok :=<- someChan:
if !ok {
// канал закрыт
break Loop
}
// получены данные, работа с val
default:
// канал пуст, что-то делать
}
}

Здесь, ok будет истиной только для открытого канала. Но при закрытии по каналу будут приходить пустые сообщения постоянно и ok будет ложью.

Однако вышеприведённая конструкция оптимальна только если нужно выполнять действие в default-ветке. Т.е. что-то делать, когда сообщений нет. Есть более простая и понятная конструкция
for val := range someChan {
// получено сообщение
}
// канал закрыт

В этом случае канал читается, используя for-range. Когда канал будет закрыт и из него будет прочитано последнее сообщение, произойдёт выход из цикла.


Запись

Запись в закрытый канал вызывает панику.
Дизайн приложения должен быть таким, что сторона создающая канал, его же и закрывает и пишет в него то же она. Более того, в этих случая рекомендуется, что б функция возвращала канал только для чтения
func run () <-chan string {
c := make(chan string)
// [...]
}



recover()

Конечно можно в отложенном вызове вызвать recover(), чтобы подавить панику. Но это в корне неправильно.

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Разрабы Go отвечают на вопросы

Среди заданных вопросов много интересных, типо:
— можно ли с Go и HTMX делать fullstack-приложения
— в чём отличие между namespace в других ЯП и package в Go
— как обстоят дела с Dependency Injection в Go
— и ещё несколько других

Отличное видео, помогает узнать об актуальных задачах, которые решаются с помощью Go и не только
Рекомендую)

📎 Youtube

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Возможный вопрос на собесе: rune и byte — в чём разница?

rune - это 32-х битный тип, представляющий юникодные символы в кодировке UTF-32 aka UCS-4.

byte - это универсальный 8-битный тип.

rune используется для работы с не-ASCII символами в строках. Есть встроенное приведение []rune для типа string, которое парсит строку из UTF-8 (представление с переменной длиной байтов) в представление с фиксированной длиной байтов.

В случае не-ASCII строк разница между []byte(str) и []rune(str) разительна. Строка Привет, мир!:
Байты:  [208 159 209 128 208 184 208 178 208 181 209 130 44 32 208 188 208 184 209 128 33]
Руны: [1055 1088 1080 1074 1077 1090 44 32 1084 1080 1088 33]


Приведение []rune(string) эквивалентно вот такой функции:
func ToRunes(bytes []byte) []rune {
result := []rune{}
for i := 0; i < len(bytes); {
r, size := utf8.DecodeRune(bytes[i:])
result = append(result, r)
i += size
}
return result
}


📎На картинке текст программы с преобразованием Привет, мир! в руны и обратно

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 В чём суть реализации уязвимости c помощью перестановки defer response.Body.Close()

▶️Итак, есть такой обработчик, и реализация уязвимости связана с тем, что тело ответа закрывается до проверки ошибки.
func HandleRequest(client http.Client, request *http.Request)
(*http.Response, error) {
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
return nil, err
}
}

А теперь вопрос: почему это должно работать, ведь тело всё равно закрыто, не зависимо до проверки или после?

Известно, что полное отсутствие строки defer response.Body.Close() приводит к гарантированным проблемам, но как протестировать вышеупомянутую уязвимость?


▶️Суть в следующем: defer response.Body.Close() означает, что response.Body.Close() должно быть выполнено в точке выхода из функции. Ни о каком закрытии тела до проверки ошибки речь не идёт.

Проблема здесь в другом — в случае ошибки response может быть nil, и выполнение отложенной инструкции в ветке if err != nil {... return ...} в таком случае приведет к панике из-за обращения к нулевому указателю.
panic: runtime error: invalid memory address or nil pointer dereference


А вот собственно и код:
package main

import (
"fmt"
"io"
"net/http"
"net/url"
"os"
)

func main() {
client := http.Client{}
url, _ := url.Parse("https://no.such.host")
request := &http.Request{
Method: "GET",
URL: url,
}

response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "Request failed: %s\n", err.Error())
}

io.Copy(os.Stdout, response.Body)

}


Как-то так

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Сверхполезный сайт со всей теорией по Go

🔥 На днях наткнулся на нереально полезный онлайн учебник по Go, чем и спешу поделиться.
Здесь описывается абсолютно всё, что поможет подготовиться к собеседованию, и даже больше

Вопросы с собеседований связанные с Golang
├── Общие вопросы
├── Хеш-мапы
├── Интерфейсы
├── Пакеты
├── Типы данных
├── Defer
├── Примитивы синхронизации
├── Планировщик
├── Строки
├── Массивы и слайсы
├── Дженерики
├── Горутины
├── Конструкции
├── Гонка данных
├── Структуры
├── Контекст
├── Ошибки / Panic
└── Указатели

Вопросы с собеседований связанные с Linux
├── Файловая система
└── Сигналы, процессы

Вопросы по инфраструктуре
└── Базы данных (реляционные)

🖥 GitHub

📎 Учебник

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Как в Golang проверить, содержит ли массив значение?

▶️Итак вопрос: как проверить, есть ли значение в массиве Go?

Есть функция strings.Contains, но она проверяет есть ли строка в строке, не массив. Есть ли функция для этого, или надо писать свою?


▶️Сразу к сути: если массив не отсортирован, то есть функция slices.IndexFunc
// искать индекс элемента target
idx := slices.IndexFunc(someSlice, func (elt E) { return elt == target })
if idx >= 0 { /* найден */ }


Но это реально тривиальная функция:
func IndexFunc[E any](s []E, f func(E) bool) int {
for i := range s {
if f(s[i]) {
return i
}
}
return -1
}


Если же массив отсортирован, то есть функция поиска делением пополам slices.BinarySearch - ищет для типов, для которых определено сравнение <. В общем случае есть поиск по отсортированному слайсу с компаратором slices.BinarySearchFunc

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM