❓ Что не так с этим кодом на Go? И чего вы ожидаете на выходе?
На первый взгляд - всё понятно. Но на самом деле это ловушка 😏
Вы переопределяете iota как обычную константу, равную самой себе (iota = iota). С этого момента iota перестаёт быть магической переменной, и счётчик сбрасывается.
Поэтому Y получает значение 0, а не 1 — как многие ожидают.
Вывод программы: 0
💡 Мораль: никогда не переназначайте iota внутри const, иначе потеряете её «магию».
Запустить код: https://go.dev/play/p/7xu1qRUcp2O
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
👍6❤1🔥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))
}
Ответ:
false 0 0
false
{"a":null,"b":[]}
👉 Запустить код: https://go.dev/play/p/PaqGcSwGqpV
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4❤3
Anonymous Quiz
10%
false false false
2%
false false true
24%
false true true
7%
true false true
57%
true true true
👍1
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
Если присвоить интерфейсу значение 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🤯4❤2
👍3
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)
}
Ответ :
t: [2 42 99]
⚡️ Запустить код: https://go.dev/play/p/96RGE1ea6Sq
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4❤3🤔2
This media is not supported in your browser
VIEW IN TELEGRAM
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: 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). Используй его везде, где данные можно заранее отсортировать - прирост скорости огромный.
Бинарный поиск - один из самых быстрых способов найти элемент в отсортированном слайсе. Вместо полного прохода он делит диапазон пополам, работая за 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))
}
👍5❤3🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Планировщик задач в 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)
}
Ответ:
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🔥3❤2👎1
11 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_go_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❓ Что выведет программа?
Всё выглядит так:
Мы передаём объект в mutate → внутри меняем → значения должны измениться.
Тут ловушка в том, что:
- интерфейсы в Go копируют значение, если оно не pointer receiver
- type assertion s, ok := i.(S) создаёт новую копию
- мы мутируем копию, а не оригинал
Так что вывод будет:
10
10
А не 100.
👉 Запустить код
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()) // ???
}
Всё выглядит так:
Тут ловушка в том, что:
- интерфейсы в Go копируют значение, если оно не pointer receiver
- type assertion s, ok := i.(S) создаёт новую копию
- мы мутируем копию, а не оригинал
Так что вывод будет:
10
10
А не 100.
👉 Запустить код
👍10🔥2❤1
Чтобы не собирать вручную десятки однотипных команд для облачной CLI, мы в MWS Cloud Platform сделали генератор: он берёт OpenAPI-спеки и сам создаёт готовый инструмент для управления облаком.
В статье кратко:
— почему выбрали Go + Cobra и кодогенерацию;
— как из путей и методов рождаются mws <service> <component> <op>;
— профили, автообновление, удобный вывод;
— что получилось в итоге и зачем это бизнесу.
Читать статью
В статье кратко:
— почему выбрали Go + Cobra и кодогенерацию;
— как из путей и методов рождаются mws <service> <component> <op>;
— профили, автообновление, удобный вывод;
— что получилось в итоге и зачем это бизнесу.
Читать статью
❓ Что выведет программа?
И объясни, почему вывод - НЕ тот, который ожидает большинство 🙂
🔥 Разбор
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 --и два, казалось бы, одинаковых куска кода могут работать по-разному без единой строки изменения.
👉 Запустить код
И объясни, почему вывод - НЕ тот, который ожидает большинство 🙂
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