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

Прислать задачу/вопрос в дар: @cyberJohnny
Сотрудничество: @cyberJohnny
Download Telegram
What does the following program print?
Anonymous Quiz
23%
A
36%
B
23%
C
18%
D
Использование пакетных функций pl/sql в коде golang

Я пытаюсь запустить функцию в пакете в ручке моего API и получаю сообщение об ошибке: call register type before use user defined type (UDT)

Запустил саму функцию через SQL запрос и она сработала значит ошибка в самом хэндлере, SOS, мучаюсь уже несколько часов вот код

возможно я не правильно вызываю эту функцибю, для подключения к бд использую драйвер github.com/sijms/go-ora/v2. обычные процедуры запускаются без проблем, как вариант написать процедуру под ручку, но я ек хочу таким образом говнокодить, так что надежда пока на вас. вот сам код, в котором вызываю функцию:

var responsibleID string
query := `
BEGIN
:1 := MYDB.RESPONSIBLE_BO.GetContractorIDByName(:2);
END;
`
err = tx.QueryRow(query, sql.Out{Dest: &responsibleID}, req.ResponsibleName).Scan(&responsibleID)
if err != nil {
log.Println("Failed to get ResponsibleID:", err)
ctx.SetStatus(apieasy.InternalServerError, "Failed to get ResponsibleID, error: %v", err)
return
}
Пробовал объявлять переменную, в которую записываю данные из бд:

query := `
DECLARE
v_contractor_id CHAR;
BEGIN
v_contractor_id := MYDB.RESPONSIBLE_BO.GetContractorIDByName(:1);
:2 := contractor_id;
END;
`
не помогло.

вот сам код функции, если будет нужно:

FUNCTION GetContractorIDByName (i_sNAME IN VARCHAR2)
RETURN CHAR
IS
v_res CONTRACTOR.CONTRACTORID % TYPE;
BEGIN
IF (i_sNAME IS NOT NULL)
THEN
BEGIN
SELECT CONTRACTORID
INTO v_res
FROM CONTRACTOR
WHERE NAME = i_sNAME;
EXCEPTION
WHEN NO_DATA_FOUND THEN
CREATECONTRACTOR (i_sNAME, NULL, NULL, 'created by function GetContractorIDByName', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0);
COMMIT;
BEGIN
SELECT CONTRACTORID
INTO v_res
FROM CONTRACTOR
WHERE NAME = i_sNAME;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20002, 'Failed to retrieve newly created contractor TRY AGAIN');
END;
END;
ELSE
RAISE_APPLICATION_ERROR(-20001, 'Undefined nom name');
END IF;
RETURN v_res;
END GetContractorIDByName;
Как считать текст с изображения

Установил тессеракт на убунту

add-apt-repository -y ppa:alex-p/tesseract-ocr-devel && \
apt-get -y update && apt install -y tesseract-ocr* && \
apt install -y libtesseract-dev*`
Испортировал пакет для работы с ним.

go get -t github.com/otiai10/gosseract/v2
Сделал фотку счетчика воды

Фотка

и положил его в папку с main

Написал код по примеру отсюда

package main

import (
"log"

"github.com/otiai10/gosseract/v2"
)

func main() {
client := gosseract.NewClient()
defer client.Close()
client.SetImage("img.png")
text, err := client.Text()
if err != nil {
log.Println(err, "<---")
return
}
log.Println(text)
}
Запустил код

go run .
На выходе ожидал

2024/07/16 12:53:55 00142899
А получил:

2024/07/16 12:53:55 % oi , i
tes a 4
4
А как собстна получить то что я ожидал?
👨🏻‍💻 Вопрос от пользователя


Golang. Вывод суммы в рублях и копейках

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

Текст задачи:

Напишите программу, которая считывает строку и выводит ее предполагаемую цену, 1 символ = 23 копейки в следующем формате:

Y коп. - если цена не дотягивает до рубля.

X р. Y коп. - если цена превышает 1 рубль.

package main

import (
"fmt"
"unicode/utf8"
)

func main() {
var praic float64 = 0.23
var samplText string
var result int
fmt.Scan(&samplText)
result = utf8.RuneCountInString(samplText)
var resultRub float64 = float64(result) * praic
var RUB int = int(resultRub)
if resultRub > 1.00 {
fmt.Printf("%d р. %d коп.", int64(RUB), int((resultRub-float64(RUB))*100))
} else {
fmt.Printf("%d коп.", int(resultRub*100))
}
}

Golang задачи с собеседований
👨🏻‍💻 Вопрос от пользователя


как запустить код на Go?

Я скачал golang, и не понимаю как запустить код. Заранее спасибо
Как может структура реализовывать интерфейс, не реализовав все методы интерфейса?

Создаю свой хендлер для логирования, свомощью пакета slog. По докам я должен реализовать интерфейс Handler. То есть его 4 метода:

Enabled(context.Context, Level) bool
Handle(context.Context, r Record) error
WithAttrs(attrs []Attr) Handler
WithGroup(name string) Handler
Но я пишу такой код:

import (
"context"
"log/slog"
"os"
)

type MyHandler struct {
slog.Handler
}

func (h MyHandler) Handle(ctx context.Context, r slog.Record) error {
return h.Handler.Handle(ctx, r)
}

func main() {
// создаю хендлер
h := &MyHandler{slog.NewJSONHandler(os.Stdout, nil)}
logger := slog.New(h)
logger.Info("Message")
// {"time":"2024-07-04T10:28:45.278528589+04:00","level":"INFO","msg":"Message"}
}
Функция slog.New() принимать только Handler. Для своей структуры MyHandler я реализовал только метод Handle и остальные не реализовал. Значит она не может реализовывать интерфейс Handler. Но все работает. Как это может быть? Компилятор должен послать меня.
Свой VPN на golang

ешил сделать свой VPN на golang. В принципе основную часть сделал:

Программа создаёт виртуальный интерфейс TUN
Подключается к VPN серверу по UDP
И передает данные из TUN на сервер, а с сервера в TUN
На сервере примерно тот же самый сценарий. Как я понял, это уже является VPN (только без шифрования, но это я добавлю). Хотелось бы дать клиенту доступ в интернет, то есть что бы на сервере IP пакеты отправлялись дальше в сеть и с сети клиенту. Это я и не понимаю, как сделать. Всё делаю под Windows.
Воспроизводится ошибка 404 при нескольких автомиграциях, где ошибка? gin

package db

import (
"awesomeGin/models"
"log"

"gorm.io/driver/postgres"
"gorm.io/gorm"
)

func Init(url string) *gorm.DB {
db, err := gorm.Open(postgres.Open(url), &gorm.Config{})
DisableForeignKeyConstraintWhenMigrating: true ,

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

db.AutoMigrate(&models.Book{})
db.AutoMigrate(&models.Game{})
return db
}
Go. No packages found for open file C:\Users\user\Documents\go-discord-rpc\main.go. This file is ignored by your gopls build

Проект требует использование python2.7, с его поддержкой нет нужной библиотеки. Было принято решение использовать CGO. При добавлении пакета C для компиляции модуля в .so файл, возникает ошибка, перестает видеть пакет main. Если переставлять место импорта пакета C, то никакого результата это не дает.

package main

import "C"

import (
"time"
)

func main() {}

// export discord_rpc
func discord_rpc(details, state, largeImage, smallImage, LargeText, smallText string) {
client, err := New("938480952844386364")
if err != nil {
panic(err)
}

err = client.SetActivity(Activity{
Details: details,
State: state,
Timestamps: &Timestamps{
Start: time.Now().Add(-time.Minute * 5),
// End: time.Now().Add(time.Minute * 5),
},
Assets: &Assets{
LargeImage: largeImage,
LargeText: LargeText,
SmallText: smallText,
SmallImage: smallImage,
},
// Buttons: []dButton{
// {
// Label: "Google",
// URL: "https://youtube.com",
// },
// {
// Label: "Discord",
// URL: "https://discord.com",
// },
// },

})
if err != nil {
panic(err)
}

time.Sleep(time.Second * 30)
}
Организация сервера на Go с использованием context

Есть такой простой сервер:


import (
"context"
"fmt"
"math/rand"
"net/http"
"time"
)

func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) //Таймаут на 5 секунд
defer cancel()

r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}

func handler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ch := make(chan string) //Для приёма ответа
go doSomeLong(ch)
select {
case <-ctx.Done(): //Если таймаут превышен
err := ctx.Err()
fmt.Println(err)
fmt.Fprint(w, "Превышен таймаут")
case str := <-ch: //Если всё нормально, то отправка клиенту сообщения из канала
fmt.Fprint(w, str)
}
}

/*Функция для симуляции долгого процесса*/
func doSomeLong(a chan string) {
sl := rand.Intn(10)
time.Sleep(time.Duration(sl) * time.Second)
a <- "Привет!"
}

func main() {
http.HandleFunc("/", handler)
fmt.Println("SERVER START AT :8080")
http.ListenAndServe(":8080", middleware(http.DefaultServeMux))
}
Нормальна такая конструкция в каждом обработчике? Как рендерить готовые файлы?

select {
case <-ctx.Done(): //Если таймаут превышен
err := ctx.Err()
fmt.Println(err)
fmt.Fprint(w, "Превышен таймаут")
case str := <-ch: //Если всё нормально, то отправка клиенту сообщения из канала
fmt.Fprint(w, str)
}
Как эффективно объединять строки в Go? [дубликат]

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

Мне нужно много раз объединять строки, не зная длины результирующей строки, какой самый лучший способ сделать это?

Наивный способ был бы таким:

var s string
for i := 0; i < 1000; i++ {
s += getShortStringFromSomewhere()
}
Стриминг tty docker-контейнера

Мне нужно реализовать функционал стриминга терминала docker контейнера, для этого я использовал ContainerLogs и построчно собирал логи из контейнера. Однако в случае использования контейнером tty у меня возникают проблемы. В таком случае, я получаю строки логов с escape кодами (отчистка терминала, строки и тд). У меня нет проблемы отобразить это в нормальном виде, однако это сложно назвать стримингом терминала контейнера с tty. К терминалу контейнера, не используя docker-api, можно подключится с помощью docker attach, но как потом стримить это, мне тоже не ясно

Хотелось бы как-то стримить своеобразный "экран терминала" контейнера, матрицу символов, однако нигде не могу найти информации по этому поводу.
Как избежать дедлока при переборе значений из небуферизированного канала в GO?

Всем привет, изучаю сейчас аспекты горутин и каналов в программировании на Go. У меня есть следующий код. Который запускает несколько горутин в которых идёт запись значения в канал который равен итератору i

package main

import (
"fmt"
)

func main() {
counter := 0
numbers := []int{1, 2, 3, 4, 5}
tempChannel := make(chan int)
for _, val := range numbers {
go func(val int) {
tempChannel <- val
}(val)
}

for value := range tempChannel {
counter++
fmt.Println(value)
}
fmt.Println("Counter is", counter)
}
В целом код рабочий, но в конце я получаю deadlock. с таким выводом:

1
3
2
4
5
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
Прочитал уже много информации по каналам и посмотрел много видео на ютубе по подобной реализации, во всех примерах у людей всё получается отлично, но не могу найти несоответствие в своём коде.
Не знаю как запустить программу из-за отсутствующего пакета

Пытаюсь скомпилировать свой проект:

go build .
В ответ получаю:

http_service/service.go:17:6: no required module provides package github.com/gofiber/template/html; to add it:
go get github.com/gofiber/template/html
Пытаюсь загрузить модуль:

go get github.com/gofiber/template/html
На что получаю:

go: module github.com/gofiber/template@upgrade found (v1.8.3), but does not contain package github.com/gofiber/template/html
Что мне с этим делать?

Я новичек в использовании модулей.
Странности при компиляции программы с каналами

У меня есть такой код

package main

import (
"fmt"
"time"
)

func main(){
ch := make(chan int)
go waitOneDay(ch)
go receive(ch)
time.Sleep(time.Hour * 25)
}

func send(ch chan int) {
ch <- 1
fmt.Println("Sending value to channel complete")
}

func waitOneDay(ch chan int) {
time.Sleep(24 * time.Hour)
сh <- 1
}

func receive(ch chan int) {
time.Sleep(time.Second * 1)
fmt.Println("Timeout finished")
_ = <-ch
return
}

Когда я компилирую этот код, то получаю

./prog.go:26:2: undefined: сh
То есть не распознан канал ch внутри функции waitOneDay.

Если же закоментировать функцию waitOneDay, и заменить ее на send функцию в main,

package main

import (
"fmt"
"time"
)

func main(){
ch := make(chan int)
go send(ch)
go receive(ch)
time.Sleep(time.Hour * 25)
}

func send(ch chan int) {
ch <- 1
fmt.Println("Sending value to channel complete")
}

//func waitOneDay(ch chan int) {
// time.Sleep(24 * time.Hour)
// сh <- 1
//}

func receive(ch chan int) {
time.Sleep(time.Second * 1)
fmt.Println("Timeout finished")
_ = <-ch
return
}
то код работает как надо:

Timeout finished
Sending value to channel complete
Как мне заставить функцию waitOneDay работать? Ссылка на go playground https://play.golang.com/p/OUHusxPiObA