MCPcopy Index your code
hub / github.com/comerc/yandex

github.com/comerc/yandex @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
77 symbols 113 edges 6 files 5 documented · 6% 1 cross-repo links updated 59d ago★ 163
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

yandex

Почему Go?

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

Code Style

Channel Axioms

  • Отправка на nil-канал блокируется навсегда (fatal error "deadlock" без recover)
  • Приём от nil-канала блокируется навсегда (fatal error "deadlock" без recover)
  • Отправка в закрытый канал приводит к панике (можно обработать recover)
  • Приём из закрытого канала немедленно возвращает нулевое значение (широкополосно, т.е. всем слушателям канала)

Go Proverbs

В мире Go существуют несколько известных "пословиц" или принципов, которые отражают философию языка и его лучшие практики. Вот некоторые из них:

Правило компиляции: "Компилируется всё". Go стремится быть языком с хорошей статической типизацией и строгим компилятором, который помогает выявлять ошибки на этапе компиляции.

Правило эффективности: "Каналы, а не разделяемая память, для общения между горутинами". Go поощряет использование каналов для координации и обмена данными между горутинами, а не общую память, чтобы избежать состояния гонки и других проблем синхронизации.

Правило читаемости: "Код должен быть понятен для людей, а не для машин". Go ставит акцент на читаемость кода и призывает разработчиков писать чистый, понятный и простой код, который легко поддерживать и понимать.

Правило простоты: "Простота лучше сложности". Go стремится к простоте в дизайне языка и стандартной библиотеке, чтобы программистам было легче писать, читать и поддерживать код.

Правило проверки ошибок: "Проверка ошибок обязательна и должна быть явной". Go призывает разработчиков явно проверять ошибки и обрабатывать их, чтобы предотвратить возможные проблемы и улучшить надежность программ.

Правило однозначности: "Чётко выражайте свои намерения". Go ставит акцент на ясное и однозначное выражение намерений в коде, чтобы избежать двусмысленности и улучшить его понимание.

Правило соблюдения стандартов: "Всегда следуйте соглашениям о форматировании кода". Go имеет строгие соглашения о форматировании кода, определенные в стандартной библиотеке, и призывает разработчиков следовать им для повышения согласованности и читаемости кода.

Эти принципы отражают философию Go и помогают разработчикам создавать безопасные, эффективные и понятные программы.

Ещё Постулаты Go

Dependency Injection

Inversion of Control (IoC) и Dependency Injection (DI) - это два взаимосвязанных принципа, используемые в разработке программного обеспечения для уменьшения связанности и улучшения модульности кода.

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

DI - это конкретная форма IoC, где зависимости предоставляются внешним сервисом. DI позволяет нам разрабатывать слабо связанные модули. Внедрение зависимостей осуществляется путем предоставления зависимости объекту (клиенту), а не путем создания зависимости внутри объекта.

Таким образом, можно сказать, что DI - это способ реализации IoC. Они оба работают вместе для достижения слабой связанности и лучшей модульности в коде.

Не путать с Dependency Inversion Principle - это принцип SOLID в объектно-ориентированном программировании, который помогает уменьшить связанность в коде. Он гласит: "Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций".

coupling-vs-cohesion

Упражнение на "Communicating sequential processes (CSP)" / "Actor Model"

"Don't communicate by sharing memory, share memory by communicating"

Задача: Реализовать структуру-счетчик, которая будет инкрементироваться в конкурентной среде. По завершению программа должна выводить итоговое значение счетчика.

Условие: Без применения примитивов из пакета sync, исключительно используя канал для обеспечения потокобезопасной передачи/приёма данных.

Решение

package main

import (
    "context"
    "fmt"
    "os"
    "os/signal"
    "sync"
)

type Counter chan int

func NewCounter(ctx context.Context) Counter {
    counter := make(Counter)
    go func() {
        var count int
        for {
            select {
            case v := <-counter:
                count += v
            case counter <- count:
            case <-ctx.Done():
                return
            }
        }
    }()
    return counter
}

func main() {
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
    defer cancel()
    counter := NewCounter(ctx)
    var wg sync.WaitGroup
    const total = 1_000_000
    wg.Add(total)
    for i := 0; i < total; i++ {
        go func() {
            counter <- 1
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(<-counter)
}

Буферизированный-небуферизированный канал

  • ch := make(chan string) - блокирует передатчик, пока не готов приёмник
  • bufferedCh := make(chan string, 1) - неблокирует передатчик, пока не готов приёмник
package main

import "fmt"

func main() {
    ch := make(chan string, 0) // Переключение на буферизированный канал изменит поведение
    go func() {
        msg := <-ch
        fmt.Println("Получено сообщение:", msg)
    }()
    ch <- "Привет, мир!" // Эта строка блокируется до тех пор, пока горутина не прочитает значение из канала
    fmt.Println("Главная горутина завершена")
}

Каналы: more writers - one reader

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    done := make(chan bool)

    go func() {
        for i := range ch {
            if i == 20 {
                done <- true
                return
            }
            fmt.Printf("%d\n", i)
        }
    }()

    go func() {
        for i := 0; i < 10; i++ {
            select {
            case ch <- i:
                time.Sleep(1 * time.Second)
            case <-done:
                return
            }
        }
    }()

    go func() {
        for i := 10; i <= 20; i++ {
            select {
            case ch <- i:
                time.Sleep(1 * time.Second)
            case <-done:
                return
            }
        }
    }()

    <-done

}

Каналы: one writer - more readers

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    done := make(chan bool)

    go func() {
        for i := range ch {
            fmt.Printf("reader1: %d\n", i)
        }
        done <- true
    }()

    go func() {
        for i := range ch {
            fmt.Printf("reader2: %d\n", i)
        }
        done <- true
    }()

    go func() {
        for i := range ch {
            fmt.Printf("reader3: %d\n", i)
        }
        done <- true
    }()

    for i := 0; i <= 300; i++ {
        if i == 300 {
            close(ch)
            return
        }
        time.Sleep(1 * time.Second)
        ch <- i
    }

    <-done
}

Practice

ООП

В GoLang не реализованы некоторые особенности объектно-ориентированного программирования, такие как наследование классов и конструкторы. Однако, Go предлагает другие механизмы для достижения тех же целей, например, встраивание структур и интерфейсы.

Инкапсуляция достигается с помощью именованных и неименованных идентификаторов (публичные и приватные). Идентификаторы, начинающиеся с заглавной буквы, являются публичными и могут быть доступными из других пакетов. Идентификаторы, начинающиеся с маленькой буквы, являются приватными и доступны только в пределах своего пакета. Однако, в Go нет строгой приватности, и другие пакеты могут иметь доступ к приватным идентификаторам, если они находятся в том же пакете импорта.

Полиморфизм достигается через интерфейсы. Интерфе

Extension points exported contracts — how you extend this code

IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_alexand.go
IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_viktor.go
IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_kirill.go
IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_stasundr.go
IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_main.go
IStore (Interface)
(no doc) [2 implementers]
CHALLENGE/_serg.go

Core symbols most depended-on inside this repo

Get
called by 12
CHALLENGE/_serg.go
Set
called by 5
CHALLENGE/_serg.go
GetBatch
called by 5
CHALLENGE/_serg.go
runTest
called by 4
CHALLENGE/_alexand.go
Get
called by 1
CHALLENGE/_main.go
Get
called by 1
CHALLENGE/_serg.go
Set
called by 0
CHALLENGE/_alexand.go
Get
called by 0
CHALLENGE/_alexand.go

Shape

Method 46
Struct 20
Interface 6
Function 5

Languages

Go100%

Modules by API surface

CHALLENGE/_alexand.go21 symbols
CHALLENGE/_serg.go14 symbols
CHALLENGE/_main.go14 symbols
CHALLENGE/_stasundr.go10 symbols
CHALLENGE/_viktor.go9 symbols
CHALLENGE/_kirill.go9 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add yandex \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact