Go tests
7.78K subscribers
309 photos
4 videos
106 links
По всем вопросам- @haarrp

@itchannels_telegram - 🔥полезные ит-каналы

https://t.me/Golang_google - Golang программирование

@golangl - golang chat

@GolangJobsit - golang channel jobs

@golang_jobsgo - go chat jobs
Download Telegram
Что не так с этим кодом на Go? И чего вы ожидаете на выходе?


package main

func main() {
const (
iota = iota
Y
)
println(Y)
}



На первый взгляд - всё понятно. Но на самом деле это ловушка 😏


Вы переопределяете iota как обычную константу, равную самой себе (iota = iota). С этого момента iota перестаёт быть магической переменной, и счётчик сбрасывается.
Поэтому Y получает значение 0, а не 1 — как многие ожидают.

Вывод программы: 0

💡 Мораль: никогда не переназначайте iota внутри const, иначе потеряете её «магию».

Запустить код: https://go.dev/play/p/7xu1qRUcp2O
👍61🔥1😢1
👣 Что выведет код ?



package main

import (
"encoding/json"
"fmt"
"reflect"
)

type S struct {
A []int `json:"a"`
B []int `json:"b"`
}

func main() {
var a []int // nil
b := []int{} // пустой
fmt.Println(a == nil, len(a), cap(a)) // ?
fmt.Println(b == nil, len(b), cap(b)) // ?

fmt.Println(reflect.DeepEqual(a, b)) // ?

x := S{A: a, B: b}
d, _ := json.Marshal(x)
fmt.Println(string(d))
}


Ответ:
true 0 0
false 0 0
false
{"a":null,"b":[]}


👉 Запустить код: https://go.dev/play/p/PaqGcSwGqpV
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥43
👍1
Как вызвать встроенный race detector при запуске Go-программы
Anonymous Quiz
40%
go run -race
7%
go build -race
25%
go test -race
28%
Все варианты верны
1🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
👣 Go: Тонкая ловушка - typed nil в интерфейсе.

Если присвоить интерфейсу значение nil конкретного типа, сравнение с nil вернёт false, потому что у интерфейса уже есть динамический тип. Запомни правило: интерфейс равен nil только когда и тип отсутствует, и значение nil.


package main

import (
"fmt"
"os"
)

func main() {
var err error = (*os.PathError)(nil)
fmt.Println(err == nil)
}


https://www.youtube.com/shorts/vobogCxfoLk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤯42
🔥71🥰1
Что выведет код
Anonymous Quiz
14%
[1, 2, 3]
15%
[3, 2, 1]
56%
[1, 3, 2]
15%
[2, 3, 1]
👍3
👣 Что выведет код (Go 1.25)?


package main

import "fmt"

func main() {
s := []int{1, 2, 3, 4}
t := s[1:3] // t = [2, 3]
t = append(t, 99) // возможно, меняет s[3]
s[2] = 42 // изменяем s напрямую

fmt.Println("s:", s)
fmt.Println("t:", t)
}


Ответ :

s: [1 2 42 99]
t: [2 42 99]


⚡️ Запустить код: https://go.dev/play/p/96RGE1ea6Sq
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥43🤔2
This media is not supported in your browser
VIEW IN TELEGRAM
👣 Вот ещё одна задача на Go, которая проверяет знание интерфейсов, nil и типов - частая ловушка даже для опытных разработчиков


package main

import (
"errors"
"fmt"
)

type myError struct{}

func (m *myError) Error() string {
return "something went wrong"
}

func returnsNilError() error {
var e *myError = nil
return e
}

func main() {
err := returnsNilError()
fmt.Println("err == nil:", err == nil) // неожиданно false
fmt.Println("err:", err)
}


Вывод: err == nil: false
err: something went wrong


⚡️ Заплатить код: https://go.dev/play/p/lrw5DEthEvS

@golangtests
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2🥰1
This media is not supported in your browser
VIEW IN TELEGRAM
🚀 САМЫЙ ЭФФЕКТИВНЫЙ АЛГОРИТМ ПОИСКА В GO

Бинарный поиск - один из самых быстрых способов найти элемент в отсортированном слайсе. Вместо полного прохода он делит диапазон пополам, работая за O(log n). Используй его везде, где данные можно заранее отсортировать - прирост скорости огромный.


package main
import "fmt"

func binSearch(a []int, t int) bool {
l, r := 0, len(a)-1
for l <= r {
m := (l + r) / 2
if a[m] == t { return true }
if a[m] < t { l = m + 1 } else { r = m - 1 }
}
return false
}

func main() {
nums := []int{1,4,7,9,15,20,33,42}
fmt.Println(binSearch(nums, 33))
fmt.Println(binSearch(nums, 100))
}
👍53🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
👣 Как работает планировщик задач в Golang под капотом

Планировщик задач в Golang работает по схеме G-P-M:
горутины (G) распределяются по логическим процессорам (P), а те в свою очередь выполняются на системных потоках (M).
Так достигается мультиплексирование миллионов горутин на ограниченное число потоков ОС.

Когда горутина блокируется (syscall, mutex, канал без данных) - её паркуют, а поток освобождают.
Когда появляется работа — планировщик перебрасывает G между очередями P и старается держать все ядра загруженными.

Чтобы код работал эффективно:
- не плодите лишние горутины
- избегайте долгих блокировок
- контролируйте GOMAXPROCS
- проверяйте количество G через runtime


package main

import (
"fmt"
"runtime"
"time"
)

func main() {
runtime.GOMAXPROCS(runtime.NumCPU())

for i := 0; i < 5; i++ {
go func(id int) {
for {
fmt.Println("goroutine", id, "работает на потоке")
time.Sleep(200 * time.Millisecond)
}
}(i)
}

for {
fmt.Println("горутин сейчас:", runtime.NumGoroutine())
time.Sleep(time.Second)
}
}


https://www.youtube.com/shorts/XQmGO29JE7w

#junior #golang
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1
👣 Что выйдете код ?



package main

import "fmt"

func main() {
s := []int{1, 2, 3}
t := s // t и s смотрят на один и тот же массив
u := append(s, 4)

s[0] = 99 // меняем через s
t = append(t, 5)

fmt.Println("s:", s)
fmt.Println("t:", t)
fmt.Println("u:", u)
}


Ответ:
s: [99 2 3]
t: [99 2 3 5]
u: [1 2 3 4]


Дополнительные Вопросы : Где именно произойдёт перераспределение массива, какие срезы продолжат делить общую память, а какие уже нет — в этом и фокус задачи


👉Запустить код - https://go.dev/play/p/M_JvkzNmVY9

@golangtests
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥32👎1
🔍Тестовое собеседование с Go-разработчиком из Яндекса

11 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.

Как это будет:
📂 Владислав Кирпичов, Go-разработчик в Яндексе, ex-VK, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Влад будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Владу

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_go_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что выведет программа?


package main

import (
"fmt"
)

type S struct {
v int
}

func (s S) Value() int {
return s.v
}

type I interface {
Value() int
}

func mutate(i I) {
// Мы думаем, что меняем реальный объект...
if s, ok := i.(S); ok {
s.v = 100
}
}

func main() {
s := S{v: 10}
var i I = s

mutate(i)

fmt.Println(s.v) // ???
fmt.Println(i.Value()) // ???
}


Всё выглядит так:

Мы передаём объект в mutate → внутри меняем → значения должны измениться.

Тут ловушка в том, что:

- интерфейсы в Go копируют значение, если оно не pointer receiver

- type assertion s, ok := i.(S) создаёт новую копию

- мы мутируем копию, а не оригинал

Так что вывод будет:

10
10

А не 100.

👉 Запустить код
👍10🔥21
Чтобы не собирать вручную десятки однотипных команд для облачной CLI, мы в MWS Cloud Platform сделали генератор: он берёт OpenAPI-спеки и сам создаёт готовый инструмент для управления облаком.

В статье кратко:

— почему выбрали Go + Cobra и кодогенерацию;
— как из путей и методов рождаются mws <service> <component> <op>;
— профили, автообновление, удобный вывод;
— что получилось в итоге и зачем это бизнесу.

Читать статью
Что выведет программа?

И объясни, почему вывод - НЕ тот, который ожидает большинство 🙂



package main

import "fmt"

func main() {
s := []int{1, 2, 3, 4}
t := s[:2] // [1 2]
u := s[2:] // [3 4]

// Изменяем через t
t = append(t, 9)

// Изменяем через u
u[0] = 99

fmt.Println("s:", s)
fmt.Println("t:", t)
fmt.Println("u:", u)
}


🔥 Разбор

t := s[:2] и u := s[2:] смотрят на один и тот же underlying array

но append(t, 9) может либо
• дописать в тот же массив, либо
• выделить новый, если capacity закончилась

Именно тут начинается путаница:

если capacity исходного s >= 5 — append изменит исходный массив, и s, t, u будут видеть изменения друг друга

если capacity = 4 — append создаст новый backing array, и t “оторвётся” от s и u

То есть вывод зависит от capacity, а её большинство разработчиков не проверяют, но предполагают.

✔️ Добавим интриги — сделай capacity явной 👇
s := make([]int, 4, 4) // capacity = length
copy(s, []int{1,2,3,4})


Теперь:

- append(t, 9) создаёт новый массив

и t уже не связан с s

Вывод будет:

```
s: [1 2 99 4]
t: [1 2 9]
u: [99 4]

```
Но если capacity увеличить:

```go
s := make([]int, 4, 10) // capacity > length
copy(s, []int{1,2,3,4})

```

Мы получим:


```
s: [1 2 9 99]
t: [1 2 9]
u: [99 4]

```

Потому что в этот раз append записал в тот же underlying array.


В Go поведение slice зависит от capacity --и два, казалось бы, одинаковых куска кода могут работать по-разному без единой строки изменения.


👉 Запустить код
1👍1