Golang задачи с собеседований
4.58K subscribers
491 photos
6 videos
12 files
257 links
Задачи, тесты и теоретические вопросы по Go. Так же по gin, grpc, горутинах, архитектуре api и http стэку.

Прислать задачу/вопрос в дар: @cyberJohnny
Сотрудничество: @cyberJohnny
加入频道
Как отсортировать map по порядку, указанному в массиве ключей?


Есть map, а точнее map[string]int

По умолчанию, как я понял, Golang сортирует элементы по ключу в алфавитном порядке. А как отсортировать map по ключам в заданном порядке?

Этот код:

package main

import (
"fmt"
)

func main() {
output := make(map[string]int)

basket := map[string]int{
"orange": 5,
"apple": 7,
"mango": 3,
"strawberry": 9,
}

//нужный порядок
keys := []string{
"strawberry",
"mango",
"orange",
}

for _, k := range keys {
output[k] = basket[k]
}

fmt.Printf("вывод output : %+v \n", output)
}
выдаст с ключами строки в алфавитном порядке:

mango, orange, strawberry
Pаспознавания адресов/геоданных из текста


Столкнулся с задачей: нужно извлекать адреса и геоданные (например, координаты или адреса) из текстов, которые пишут пользователи в жалобах. Тексты могут содержать описания улиц, домов, ориентиров и даже неточные формулировки.

Какие есть проверенные методы, библиотеки или подходы для решения подобной задачи? Интересуют варианты на различных языках программирования (особенно Python), включая машинное обучение и регулярные выражения. Буду благодарен за любые советы, рекомендации или ссылки на готовые решения!
Выдает ошибку при решении задачи на Golang

Условие задачи:

Дан неотсортированный слайс целых чисел. Напишите функцию UnderLimit(nums []int, limit int, n int) ([]int, error), которая будет возвращать первые n (либо меньше, если остальные не подходят) элементов, которые меньше limit. В случае ошибки функция должна вернуть nil и описание ошибки.

TEST`s

package main

import (
"slices"
"testing"
)

func TestUnderLimit(t *testing.T) {
type test struct {
nums []int
n int
limit int
expected []int
wantError bool
}

tests := []test{
{
nums: []int{4, 7, 89, 3, 21, 2, 5, 7, 32, 4, 6, 8, 0, 3, 4, 6, 2, 115, 12},
n: 5,
limit: 3,
expected: []int{2, 0, 2},
wantError: false,
},
{
nums: nil,
wantError: true,
},
{
nums: []int{},
n: 5,
limit: 3,
expected: []int{},
wantError: false,
},
{
nums: []int{3, 5, 6},
n: 5,
limit: 10,
expected: []int{3, 5, 6},
wantError: false,
},
{
nums: []int{-13, 0, 6},
n: 1,
limit: -5,
expected: []int{-13},
wantError: false,
},
{
nums: []int{},
n: -1,
limit: 5,
wantError: true,
},
}

for _, tc := range tests {
result, err := UnderLimit(tc.nums, tc.limit, tc.n)
if tc.wantError {
if err == nil {
t.Fatalf("expec... File is too long to be displayed fully
Моё решение:

func UnderLimit(nums []int, limit int, n int) ([]int, error) {
if n < 0 {
return nil, fmt.Errorf("n cannot be negative")
} else if n == 0 {
result := make([]int, 0, 0)
return result, nil
}

result := make([]int, 0, n)
count := 0
for _, num := range nums {
if num < limit {
result = append(result, num)
count++
}
if count == n {
return result, nil
}
}
return result, nil
}
Но выводится ошибка:

--- FAIL: TestUnderLimit (0.00s)
source_test.go:62: expected an error
FAIL
HTTPS запрос к серверам VK для загрузки видео


Пишу код для загрузки видео из VK без использования VK API. Задача стоит следующая: брать ссылку на видео, далее отправить запрос по этому URL и получить в ответ страницу с просмотром этого видео. То есть симулировать запрос от реального браузера.

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

req, err := http.NewRequest("GET", URL, nil)

req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 YaBrowser/24.7.0.0 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
req.Header.Set("Accept-Language", "ru,en;q=0.9")
req.Header.Set("Cache-Control", "max-age=0")

req.Header.Set("Sec-Ch-Ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"YaBrowser\";v=\"24.7\", \"Yowser\";v=\"2.5\"")
req.Header.Set("Sec-Ch-Ua-Mobile", "?0")
req.Header.Set("Sec-Ch-Ua-Platform", "\"macOS\"")
req.Header.Set("Sec-Fetch-Dest", "document")
req.Header.Set("Sec-Fetch-Mode", "navigate")
req.Header.Set("Sec-Fetch-Site", "same-origin")

req.Header.Set("Upgrade-Insecure-Requests", "1")

req.Header.Set("Priority", "u=0, I")
В ответ ожидал увидеть страницу с видео для дальнейшей работы, но фактически пришла страница, в которой мне предлагают обновить/установить свежую версию браузера.
Вопрос в следующем: как я могу эмулировать запрос от «современного» браузера в Go?

Полный код выглядит следующим образом:

const URL = "https://m.vk.com/video-85466065_456241727"

req, err := http.NewRequest("GET", URL, nil)

req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 YaBrowser/24.7.0.0 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
req.Header.Set("Accept-Language", "ru,en;q=0.9")
req.Header.Set("Cache-Control", "max-age=0")

req.Header.Set("Sec-Ch-Ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"YaBrowser\";v=\"24.7\", \"Yowser\";v=\"2.5\"")
req.Header.Set("Sec-Ch-Ua-Mobile", "?0")
req.Header.Set("Sec-Ch-Ua-Platform", "\"macOS\"")
req.Header.Set("Sec-Fetch-Dest", "document")
req.Header.Set("Sec-Fetch-Mode", "navigate")
req.Header.Set("Sec-Fetch-Site", "same-origin")

req.Header.Set("Upgrade-Insecure-Requests", "1")

req.Header.Set("Priority", "u=0, i")

client := &http.Client{}

res, err := client.Do(req)
Не запускается файл с кодом

Устаналивал VS Code и сопутствующие дополнения к нему по инструкции яндекс-лицея, при попытке запуска кода через команду go run test.go выдает ошибку:

go : Имя "go" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Проверьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку.
Получение структуры по ключу из Redis Golang


Имею подобную структуру

type myStruct struct {
TotalCount int json:"inventory_total_count"
TotalPrice int json:"inventory_total_price"
GameList []string json:"game_list"
UserInfo UserInformation json:"user_info"
GameInventory map[string]InventoryGame json:"inventory"
}

type InventoryGame struct {
GameAssetsTotalCount int json:"game_assets_total_count"
GameAssetsTotalPrice int json:"game_assets_total_price"
GameID string json:"gameid"
Assets []InventoryAssets json:"assets"
}

type InventoryAssets struct {
ClassID string json:"classid"
InstanceID string json:"instanceid"
IconURL string json:"icon_url"
Name string json:"name"
MarketHashName string json:"market_hash_name"
AssetRarity string json:"rarity"
AssetBorderColor string json:"border_color"
AssetExterior string json:"exterior"
AssetQuality string json:"asset_quality"
AppID int json:"appid"
AssetPrice int json:"asset_price"
Marketable int json:"marketable"
AssetCount int json:"item_count"
AssetTotalCost int json:"asset_total_price"
}
после того как ее создаю я, записываю в хранилище Redis следующим образом

err := client.Set(ctx, "key", myStruct, time.Minute)
// отработка err
далее я пытаюсь достать данную структуру следующим образом

newStruct := myStruct{}
err := client.Get(ctx, "key").Scan(&newStruct)
// отработка err
в итоге на выходе получается пустая структура

{0 0 [] { } map[]}
ps. методы структуры "MarshalBinary" и "UnmarshalBinary" прописаны.

Использую go-redis/v9.

Как мне правильно достать структуру из хранилища редис?
Как исключить зависимость для определенной ос?

Написал программу у которой есть функционал вызова диалога выбора файла через gtk3. Так же у этой программы есть режим только текстовый, без диалога выбора файла. Но так как я использую в этой программе импорт который дает функционал вызова окон, то в зависимостях этот пакет указан и, напрмер, для андроид эта программа уже не собирается(gtk3 нет в репозиоториях термукса), хотя в андроиде можно спокойно использовать исключительно текстовый вариант. А есть ли какой то механизм, позволяющий, например, указать компилятору, что при сборке в ос андроид(чрез термукс) не нужно требовать gtk3. Идеально если можно это сделать добавив что то в .mod файл
Как настроить кастомный GOPATH?


Коллеги, помогите разобраться. Вопрос избитый, но решить по ссылкам в сети пока не получилось (https://go.dev/wiki/SettingGOPATH).

Пытаюсь настроить кастомный gopath, чтобы мои и импортируемые пакеты лежали отдельно от стандартных гошных.

ГО установлен здесь:

D:\Programm Files\Go

Мой ворскспейс здесь:

D:\Kirill_disk_D\GoWorkspace, тут три папки - bin, src, pkg

GOPATH такой:

D:\Kirill_disk_D\GoWorkspace;D:\Programm Files\Go

В каталоге D:\Kirill_disk_D\GoWorkspace\src лежит 2 пакета: customtext и test

D:\Kirill_disk_D\GoWorkspace\src\customtext\customtext.go:

package customtext

const (
NameFrst = "Kirill",
NameScnd = "Sasha"
)
D:\Kirill_disk_D\GoWorkspace\src\test\test.go:

package main

import (
"customtext"
"fmt"
)

func main() {
fmt.Println("Привет", customtext.NameFrst)
}
По запуску test.go:

$ go run "d:\Kirill_disk_D\GoWorkspace\src\test\test.go"

Не видит нужной src из GOPATH и отвечает, что нужного пакета в GOPATH по умолчанию нет:

test.go:4:2: package customtext is not in std (D:\Programm Files\Go\src\customtext)

У меня стоит версия go1.23.0, винда 11.

По команде в cmd:

C:\Users\Kirill>go env -w GOPATH=d:\Kirill_disk_D\GoWorkspace

Отвечает, что на даст переопределить GOPATH:

warning: go env -w GOPATH=... does not override conflicting OS environment variable

Вопрос: как сделать так, чтобы Go видел пакеты из кастомного GOPATH? Что я делаю не так? Заранее спасибо!
Что делают в коде %v и \n?


У нас есть программа по угадыванию числа. Не понимаю что в ней выполняют символы %v и \n.

func main() {

var number = 43

for {
var n = rand.Intn(100) + 1
if n < number {
fmt.Printf("%v слишком маленькое число.\n", n)
} else if n > number {
fmt.Printf("%v слишком большое число.\n", n)
} else {
fmt.Printf("угадал! %v\n", n)
break

Как понимаю %v проверяет число в переменной(имею ввиду область видимости for), в нашем случае число которое появилось рандомно. Какой синтаксис несет \n инфо к моменту написания вопроса не нашел.
Неблокирующий канал с буфером


Помогите сообразить, как сделать следующее, желательно в "го-стиле".

Есть рутина, которая запускает консольную утилиту и парсит её вывод. Данные идут порциями, их частота от меня никак не зависит. Может быть 10+ пакетов в секунду, может 1. Вторая рутина должна брать эти пакеты, немного их обработать и отправить на внешний веб-сервис.

Изначально идея была - делаем канал между этими двуми рутинами. Парсим пакет - записываем в канал - читаем с канала - отправляем. Всё хорошо, пока связь стабильная и быстрая. Как только связь теряется, тормозит - начинается затык. Данные сыпятся быстрее, чем мы можем их отправлять. Важно, что потеря части данных не критична, главное чтобы последние N пакетов держались в памяти и по возможности отправлялись.

Напрашивается что-то типа очереди с автоматическим удалением старых элементов при превышении лимита N. Первая горутина туда кладёт, вторая оттуда достаёт.

То есть другими словами, нужно сделать такой канал с буфером, который бы при записи в него не блокировал (если в канале уже N элементов - самое старое значение удаляется, новое добавляется), а при чтении - блокировал (при отсутствии данных).

Станадртный буферизированный канал не подходит - при заполненном буфере он блокирует запись.

Так как в го я новичок - трудно сообразить как такое наколхозить. Попробовал поискать по репам/гуглу - ничего похожего найти не могу.

Подскажите, куда копать, где можно подсмотреть что-то похожее?
Как выбрать файл через системный проводник?


В программе понадобилось открыть проводник и выбрать в нем файл. Как я вижу использование: при работе в терминальной программе я могу ввести опрелеленную комманду и откроется системный проводник в котором можно выбрать файл. После выбора файла в проводнике, в терминальную программу копируется путь к выбранному файлу, а проводник молча закрывается. Далее над файлом по пути осуществляются какие то действия в коде. Как это(открытие прводника и выбор в нем файла) реализовать средствами go? Пишу код и тестирую в debian, соответственно решение необходимо под unix в первую очередь
Как использовать gemini api в приложении?


Я чайник и пытаюсь потрогать gemini api. Делаю по инструкции.

Зашел в ai studio получил новый
Сохранил этот ключ в константу key

Далее функция

func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(key))
if err != nil {
log.Fatal(err)
}
defer client.Close()
model := client.GenerativeModel(modelName)
chat := model.StartChat()
test := "hello. Are you working now?"
resp, err := chat.SendMessage(ctx, genai.Text(test))
if err != nil {
log.Fatal(err)
}
log.Println(resp.PromptFeedback)
}
Получаю nil в ответ nil. А как добиться от этого кода ответа на поставленный вопрос?
Не работает консольная GO игра на другой OS windows


Сделал небольшое консольное приложение на go, собрал его под свою ОС (linux mint) оно запускается и работет нормально, Но стоит мне собрать его под виндовс 10 оно не работает

package main

import (
"fmt"
"bufio"
"log"
"math/rand"
"os"
"strconv"
"time"
"strings"
)

func main() {
i := 10

fmt.Println("Game Guess Number! (1 - 15)")
fmt.Println("You have", i, "Attempts", "\n")

for i = i; i > 0; i-- {
seconds := time.Now().UnixNano()
rand.Seed(seconds)

target := float64(rand.Intn(15) + 1)

fmt.Println("Attempt: " ,i)
fmt.Print("Your guess: ", "\n")

reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')

if err != nil {
log.Fatal(err)
}

input = strings.TrimSpace(input)
guess, err := strconv.ParseFloat(input, 64)

if err != nil {
fmt.Println("error type is not a number")
log.Fatal(err)
}

if guess == target {
fmt.Println("You Won!!!", "\n")
break
} else if guess > target {
fmt.Println("Too High", "\n")
} else if guess < target {
fmt.Println("Too Low", "\n")
}
}

if i == 0 {
fmt.Println("You lose :(", "\n")
}

fmt.Println("Game End")
}

wine GuessNumberGame.exe
0074:err:winediag:is_broken_driver Broken NVIDIA RandR detected, falling back to RandR 1.0. Please consider using the Nouveau driver instead.
Game Guess Number! (1 - 100)
You have 10 Attempts

Attempt: 10
Your guess:
2024/08/28 01:58:12 read /dev/stdin: input/output error

    ~/Документы/temps    main !1 ?1   01:58:12  ─╮
❯ 0034:err:winediag:is_broken_driver Broken NVIDIA RandR detected, falling back to RandR 1.0. Please consider using the Nouveau driver instead.
Oшибка при импорте нескольких пакетов: missing import path go list, missing import path syntax
Не могу импортировать несколько пакетов, пробовал переустанавливать go на последнюю версию, Код:

package main

import {
"fmt"
}

func main() {

}
Может ли select в Go использоваться без кейсов?
Anonymous Poll
77%
Да
24%
Нет
Пишите свои предложения в комментариях! 👇

А тем, кто хочет узнать ответ скорее, — барабанная дробь... 3
Можно ли использовать тип interface{} в качестве ключа в мапе?
Anonymous Poll
28%
Да, в любом случае
20%
Да, если интерфейс не пустой
53%
Нет