37.1K subscribers
1.46K photos
33 videos
5 files
1.62K links
加入频道
👣 Vulnerability Management

Инструмент для проверки уязвимостей Go.

go install golang.org/x/vuln/cmd/govulncheck@latest

🖥 Github
🛠 Инструменты Go для проверки уязвимостей

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Concurrency in go.

Репозиторий для погружения в конкуренцию Go, c выжимками и примера из книги Concurrency in Go: Tools and Techniques for Developers. Доступно и лаконично.

🖥 Github
📚 Книга

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Тестовое задание на разработку инструмента "SQL-мигратор"

Общее описание

Аналог инструментов, приведенных в секции "Database schema migration" awesome-go.

Инструмент, работающий с миграциями, написанными на Go или представленными в виде SQL-файлов.

Позволяет:

генерировать шаблон миграции;
применять миграции;
откатывать миграции.

Архитектура

Тулза должна создавать свои служебные таблицы в БД и работать с ними.

Требования

Установка в $GOPATH/bin командой go get github.com/awesomegother/migrator/cmd/gomigrator.

Или можно использовать её API в своих программах напрямую, импортировав библиотеку как пакет.

При этом вся логика тулзы должна располагаться в internal, а экспортируемое API в pkg.

Команды

Необходимо реализовать следующие команды (флаги команд см. в разделе Конфигурирование).

Создание миграции
$ gomigrator create <имя_миграции>

Применение всех миграций
$ gomigrator up
Откат последней миграции
$ gomigrator down
Повтор последней миграции (откат + накат)
$ gomigrator redo
Вывод статуса миграций
$ gomigrator status

Таблица из:

Статус (применена, применяется, ошибка и пр.)
Время последнего обновления статуса
Имя миграции

Вывод версии базы
$ gomigrator dbversion
- по сути номер последней примененной миграции.

Формат миграций
Вы должны предоставить пользователю API для описания up/down шагов миграции.

Если миграция в формате Go-кода, то она может иметь формат:

func Up_migration(o *someObject) {
}

func Down_migration(o *someObject) {
}

Где someObject - один из аргументов, которые вы считаете, могут пригодиться при описании миграции (транзакция, структура вашей библиотеки и пр.)

Если миграция в формате SQL, то необходимо придумать способ разделения между Up и Down шагами, например, с помощью комментариев.

Драйвер
Поддержки PostgreSQL достаточно.

Консистентность

Запуск тулзы в параллельных процессах возможен (например, две ноды приложения решили на старте применить свои миграции), при этом процессы не должны мешать друг другу и дублировать свои миграции, что можно реализовать с помощью блокировок на уровне БД (SELECT FOR UPDATE, pg_advisory_lock, etc).

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

Логирование
На ваше усмотрение, но здорово, когда инструмент имеет понятный и подробный вывод о ходе своей работы и статусе выполнения команды (ошибка, успех, что было сделано, какие идентификаторы и пр.).

Конфигурация
Основные параметры:

Строка подключения (DSN) к БД
Путь к директории с файлами миграций
Тип миграции: go/sql

Конфигурировать должно быть можно как через аргументы командной строки, так и через файл, при этом в файле можно указывать переменные окружения, которые должны заэкспандиться:

dsn: $DB_DSN

Тестирование

Юнит-тесты
по возможности мок интерфейсов и проверка вызовов конкретных методов;
тесты вспомогательных функций и пр.

Интеграционные тесты
docker-compose + проверка работы тулзы на контейнере с PSQL;
тестовые миграции можно хардкодить;
можно напрямую дергать PSQL, чтобы проверить результат миграций.

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Go 1.20 is released!

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

Предоставлена поддержка оптимизации на основе результатов профилирования кода (PGO - Profile-guided optimization), позволяющей учитывать особенности, определяемые во время выполнения программы. Учёт профиля выполнения при сборке позволяет повысить производительность приложений на 3-4%. Для включения PGO в go build, go install и другие сборочные команды добавлена опция "-pgo".

Теперь можно передать флаг -C <dir>, чтобы задать рабочую директорию для подкоманды go;

В пакет unsafe добавлены функции SliceData, String и StringData для низкоуровневых манипуляций со срезами (массивы динамического размера) и строками (например, для преобразования области памяти, на которую ссылается указатель в строку с типом string и наоборот).

Правила преобразования типов расширены возможностью прямого преобразования из среза (slice) в массив.

В спецификации явно определён порядок сравнения элементов массива и полей структур.

Утилита cover расширена возможностью построения coverage-профиля для всей программы, а не только unit-тестов. Для формирования coverage-профиля в go build, go install и другие сборочные команды добавлена опция "-cover".

Утилита go избавлена от привязки к размещаемым в каталоге $GOROOT/pkg заранее скомпилированным пакетам стандартной библиотеки, что позволило исключить их из поставки и добиться уменьшения размера загружаемых данных. Пакеты стандартной библиотеки, как и обычные пакеты, теперь собираются по мере необходимости и кэшируются в сборочном кэше.

В команде go по умолчанию отключено применение пакета cgo на системах без инструментария для сборки кода на языке Си. На подобных системах теперь используются варианты пакетов стандартной библиотеки на языке Go, вместо использования предварительно скомпилированных пакетов.

В утилите vet реализованы дополнительные предупреждения о проблемах с используемыми в циклах переменными, выявленными при параллельном запуске тестов.

В стандартную библиотеку добавлен пакет crypto/ecdh с поддержкой обмена ключами на основе эллиптических кривых ECDH (Elliptic Curve Diffie-Hellmann).
Добавлен новый тип http.ResponseController для создания расширенных обработчиков HTTP-ответов.
В тип httputil.ReverseProxy добавлена функция Rewrite для изменения запроса.

Добавлена функция context.WithCancelCause, позволяющая отменить вызов с указанием определённой ошибки.
В тип os/exec.Cmd добавлены поля Cancel и WaitDelay, определяющие поведение при отмене контекста или завершении процесса.

В компиляторе и сборщике мусора снижено потребление памяти и проведена оптимизация производительности (прирост скорости достигает 2%).
Проведена работа по ускорению компиляции - сокращение времени сборки может достигать 10%.

Добавлена поддержка платформы FreeBSD на системах с арихитектурой RISC-V (GOOS=freebsd, GOARCH=riscv64).

go build и go install и некоторые другие команды принимают новый флаг --pgo, который включает profile-guided optimization, а также флаг --cover.

https://go.dev/blog/go1.20
🏎️ Go 1.20 Released

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Gosl - go scientific library

Gosl — это набор инструментов для научных вычислений на Go. В Библиотеке реализованы методы вычислений линейной алгебры (векторы, системы линейных уравнений и тд ), функции для решения дифференциальных уравнений, функции для быстрых преобразований Фурье, вероятностные распределения и многое другое.

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 GoSTL

Библиотека, содержащая структуры данных и алгоритмы Go, предназначенная для предоставления функций, аналогичных C++ STL.

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 goyek

Build automation in Go

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Генератор случайных чисел на базе неопределённого поведения состояния гонки

Генерация случайных чисел окружает нас везде. Любой шаг, дыхание, дуновение ветра, шум куллера, частота мяуканья кошки и т.п. уже может рассматриваться как некая генерация случайности.

Так например, насколько вы контролируете вашу ходьбу? Можете ли вы с точностью до нанометра определить точку опоры? Если не можете, то сама погрешность в неопределённости расстояния начинает становиться для вас генератором случайности.

Читать дальше


@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Crunch

Библиотека для простого управления битами и байтами на go. Работает в два раза быстрее, чем стандартный пакет bytes.Buffer🍪

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Написание эффективных для памяти и процессора Go-структур, оптимизированных для работы с ЦП

Структуры — это коллекции разнородных данных, определенные программистами для организации информации. Структуры позволяют аккуратно инкапсулировать все данные, относящиеся к одному объекту, в одно определение типа, поведение которого затем может быть реализовано путём определения функций для типа struct.

Большинство программ работают с огромными объемами данных, а без создания структур будет трудно вспомнить, какие переменные string или int принадлежали друг другу, а какие были разными.

В этой статье описано, как можно эффективно определить структуру с точки зрения использования памяти процессора.

Читать
Зеркало

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Тестовое задание Billing

Микросервис баланса пользователей.

Приложение хранит в себе идентификаторы пользователей и их баланс. Взаимодействие с ним осуществляется исключительно с помощью брокера очередей.

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

Списание
Зачисление
Перевод от пользователя к пользователю (будет плюсом, но не обязательно)

Блокирование с последующим списанием или разблокированием. Заблокированные средства недоступны для использования. Блокировка означает что некая операция находится на авторизации и ждет какого-то внешнего подтверждения, ее можно впоследствии подтвердить или отклонить

После проведения любой из этих операций генерируется событие-ответ в одну из очередей.

Основные требования к воркерам:

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

Будет плюсом покрытие кода юнит-тестами.

Требования к окружению: Язык программирования: Go Можно использовать: любые фреймворки, реляционные БД для хранения баланса, брокеры очередей, key-value хранилища.

Особенности
Сервис поддерживает обработку паники.
Сервис поддерживает создание и хранение журнала выполненных операций.
Сервис поддерживает полную консистентность данных
Сервис поддерживает graceful shutdown.
Сервис НЕ поддерживает Heartbeat для базы данных.
На момент старта сервиса, должен быть уже запущен NATS.

Используемые компоненты
MySQL - для хранения данных
NATS - брокер сообщений

API
Ответ на каждый запрос включает статус его выполнения: 0. Операция прошла успешно

1.Неизвестная ошибка
2.Операция устарела
3.Для выполнения операции недостаточно средств
4.Аккаунт не найден

Credit
Списание средств со счета.

Subject/Queue - bank.credit
Request: {"uid":1,"account":1,"amount":10}
Response: {"status":1}

Debit
Зачисление средств на счет.

Subject/Queue - bank.debit
Request: {"uid":1,"account":1,"amount":10}
Response: {"status":1}

Transfer
Перевод средст с одного счета на другой.

Subject/Queue - bank.transfer
Request: {"uid":1,"src":1,"dst":2,"amount":10}
Response: {"status":1}
Acquire
Блокировка средств.

Subject/Queue - bank.acquire
Request: {"uid":1,"account":1,"amount":10}
Response: {"status":1}

Commit
Подтверждение блокированных средств.

Subject/Queue - bank.commit
Request: {"uid":1,"account":1}
Response: {"status":1}

Rollback
Возврат блокированных средств.

Subject/Queue - bank.rollback
Request: {"uid":1,"account":1}
Response: {"status":1}

Принцип работы
Для достижения идемпотентности, в каждой операции должен присутствовать ее уникальный номер uid. Каждая операция, при записи в базу данных, регистрирует действие в таблице истории. При существовании одинакового ключа (work_index) происходит ошибка базы данных, которую мы трактуем, как устаревание операции (идемпотентный случай). Аналогчно работает и таблица активов.

В сервисе используется пакет доступа к базе данных github.com/adverax/echo/database/sql, который позволяет эмулировать вложенные транзакции, а также хранить область видимости в контексте. Это позволяет нам осуществлять декомпозицию функционала работы с базой на отдельные функции, не заботясь о контексте выполнения запросов.

Для каждой таблицы используется собственный менеджер.

Полное описание

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Patron

Patron — это фреймворк для создания микросервисов на Go.

поддерживает асинхронную обработку сообщений (RabbitMQ, Kafka, AWS SQS)
фреймворк, который помогает удобно организовать все компоненты микросервиса.
поддерживает синхронную обработка (HTTP)
поддержка gRPC
встроенный журнал логгирования

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Опыт использования KrakenD от разработчиков МТС Travel

KrakenD — это готовое решение, которое используется в МТС Travel для реализации API-шлюза, важной штуки для продуктов с микросервисной архитектурой.

Туристический сервис появился у МТС в прошлом году, сейчас с помощью него можно забронировать отели по всей России, а также за рубежом. В базе уже более 16000 предложений различных отелей, хостелов и апартаментов.

Опыт МТС Travel может может пригодиться разработчикам из других сервисов. Подробнее о нем читайте в статье на Хабре.
📜 Certificates helper

Бибилиотека для создания сертификатов tls.

🖥 Github
📌 Документация

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
The Kubernetes Operator Framework Book

📚 Книга

@Golang_google
👣 BigCache

Эффективный кеш на Go для гигабайтов данных.

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Что выведет код?

package main

func main() {
for i := 0; i < 3; i++ {
defer func() { print(i) }()
}
for i := range [3]int{} {
defer func() { print(i) }()
}
}

Ответ

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Что вывыдет код?
Anonymous Quiz
29%
222333
15%
210333
31%
333333
25%
210210
👣 goHackTools

В репозитории содержатся переписанные скрипты по хакингу на Go из следующих книг:

Violent Python
Black Hat Python
Security with Go
Python Web Penetration Testing Cookbook
asecuritysite
Криптография с Python
Black Hat Go

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
LURE (Linux User REpository)

LURE – инструмент на GO для внедрения AUR во все дистрибутивы, отличные от Arch Linux

Он может загрузить репозиторий, собрать в нем пакеты с помощью bash-скрипта, похожего на PKGBUILD, а затем установить их с помощью системного менеджера пакетов.

LURE написан на чистом Go и не имеет никаких зависимостей.

В настоящее время LURE поддерживает apt, pacman, apk, dnf, yum и zypper.

curl https://www.arsenm.dev/lure.sh | bash

🖥 Github

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Экономное вычисление выражений в польской записи

Польская запись — это форма записи арифметических, логических и алгебраических выражений, в которой операция располагается слева от операндов. Выражения в польской записи могут обходиться без скобок, однако мы оставим скобки для наглядности.

Например, выражение в польской записи выглядит как

(* 5 (+ 3 4))

Пусть выражения в польской записи состоят из имён переменных (от a до z), круглых скобок и трёх знаков операций: #, $ и @ (смысл операций мы определять не будем).

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

Требуется составить программу econom.go, вычисляющую количество операций, которые нужно выполнить для экономного вычисления выражения. Примеры работы программы приведены в таблице:

Набор тестов для программы экономного вычисления выражений в польской записи

Выражение Количество операций
x 0
($xy) 1
($(@ab)c) 2
(#i($jk)) 2
(#($ab)($ab)) 2
(@(#ab)($ab)) 3
(#($a($b($cd)))(@($b($cd))($a($b($cd))))) 5
(#($(#xy)($(#ab)(#ab)))(@z($(#ab)(#ab)))) 6


Решение

package main

func main() {
println(opCount("(#($(#xy)($(#ab)(#ab)))(@z($(#ab)(#ab))))"))
println(opCount("($xy)"))
println(opCount("x"))
}

func opCount(expr string) int {
expressions := map[string]bool{}
var openBraces []int
for i, c := range expr {
switch c {
case '(':
openBraces = append(openBraces, i)
case ')':
lastOpenBrace := len(openBraces) - 1
subExprStart := openBraces[lastOpenBrace]
subExpr := expr[subExprStart:i]
expressions[subExpr] = true
openBraces = openBraces[:lastOpenBrace]
}
}
return len(expressions)
}

Скобки очень сильно упрощают задачу, при этом в настоящей польской нотации скобки не нужны.
Приведем вариант кода без скобок
.

const oper = node_t("oper")
const expr = node_t("expr")

type node struct {
t node_t
v string
}

func opCount(input string) int {
expressions := map[string]bool{}
var stack []node
for _, c := range input {
switch c {
case '$', '#', '@':
stack = append(stack, node{t: oper, v: fmt.Sprintf("%s", c)})
default:
stack = append(stack, node{t: expr, v: fmt.Sprintf("%s", c)})
}
for canFold(stack) {
lastIdx := len(stack) - 1
operIdx := lastIdx - 2
folded := node{t: expr, v: stack[operIdx].v + stack[operIdx+1].v + stack[operIdx+2].v}
expressions[folded.v] = true
stack[operIdx] = folded
stack = stack[:operIdx+1]
}
}
return len(expressions)
}

func canFold(stack []node) bool {
stackLen := len(stack)
return stackLen >= 3 && stack[stackLen-3].t == oper && stack[stackLen-2].t == expr && stack[stackLen-1].t == expr
}

Пишите свое решение в комментариях👇 и ставьте 👍, если интересен такой формат.

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM