С этой статьей вы углубитесь во внутренние компоненты и посмотрите, как работают слайсы под капотом.
🔗 Подобнее
#golang #junior
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🗡 Katana
next-generation GO фреймворк для сканирования, парсинга веб-приложений и поиска необходимой информации.
📌 Github
@Golang_google
next-generation GO фреймворк для сканирования, парсинга веб-приложений и поиска необходимой информации.
📌 Github
@Golang_google
Perl:
$l=~s/\A([^\s]+?) - - \[([^\]]+?)\] \"([^\"]+?)\" ([^\s]+?) ([^\s]+?) \"([^\"]+?)\"(.+)/$1\n$2\n$3\n$4\n$5\n$6\n$7/g;
($ip, $time, $page, $code, $size, $ref, $agent, $els) = split(/\n/, $l);
$page=~s/(GET|HEAD|POST) (.+) (HTTP.+)/$2/;
$hash{$page}++;
Go:
log_format := `^([^ ]+) (-) (-) \[([^\]]+)\] "([^\"]+?)" ([0-9]+) ([^ ]+) "([^"])*" "([^"]*)"`
logParser := regexp.MustCompilePOSIX(log_format)
log_format_get := `^(GET|HEAD|POST) (.+) (HTTP.+)$`
logParserGet := regexp.MustCompilePOSIX(log_format_get)
var hash = make(map[string] int);
analize1 := func (iline *string) {
submatch := logParser.FindSubmatch(strings.TrimSpace(*iline))
if (len(submatch[0])>0){
pg := logParserGet.FindAllStringSubmatch(strings.TrimSpace(submatch[0][5]), 1)
if (len(pg)>0){
hash[pg[0][2]]++
}
}
А вот на картинке тест скорости в разных языках.
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
#golang
Если вам необходимо добавить функциональность JavaScript в свой проект на Go, просто воспользуйтесь goja - движком ECMAScript/JavaScrip.
Этот инструмент позволяет интегрировать JavaScript непосредственно в Go проекты, без необходимости использования внешних JS-движков👇
📌 Github
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Итак, сразу к сути.
Несколько экземпляров приложения могут стучаться к флуд-контролю, поэтому нужно использовать какую-нибудь БД.
timestamp
, т.к. обновление данных очень частое, следовательно перестройка индексов будет занимать много времени.userID
), а также любого числового значения (количество запросов во время timestamp
); плюс наличие агрегации, автоматического удаления старых меток и готовой concurrency - если в один timestamp
появится несколько нажатий, то они складываются. Осталось лишь написать это на Go.github.com/redis/go-redis
. В переменные окружения нужно добавить следующие переменные:FC_REDIS_HOST=localhost
FC_REDIS_PORT=6379
FC_REDIS_PASSWORD=strongpassword
FC_RETENTION=5
FC_MAXCHECKS=4
FC_RETENTION
и FC_MAXCHECKS
, кстати, можно прописать прямо в коде. FC_RETENTION
- количество секунд, за которые можно сделать не более FC_MAXCHECKS
запросов.redisClient := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", FC_REDIS_HOST, FC_REDIS_PORT),
Password: FC_REDIS_PASSWORD,
DB: 0,
})
ctx := context.Background()
var rfc FloodControl = &fc.RedisFloodController{
Client: redisClient,
RetentionSeconds: FC_RETENTION,
MaxChecks: FC_MAXCHECKS,
}
v, err := rfc.Check(ctx, 1234567890)
docker-compose.yml
для запуска redis с timeseries.RedisFloodController.Check
аккуратно возвращает ошибки, не роняя приложение, что важно в проде.cp .env.sample .env
export $(xargs < .env)
docker compose -f docker-compose.yml up -d
go run .
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Использование Docker не обязательно должно быть принципом «все или ничего». Вы можете использовать Docker для развертывания и создания образов для продакшн, но вам не обязательно использовать его в разработке.
Каждая инструкция в вашем Dockerfile приводит к созданию слоя изображения. Docker использует слои для повторного использования работы. Слои кэшируются и их не нужно пересобирать, если:
— Все предыдущие слои не изменяются.
— В случае инструкции
COPY
: файлы/папки не изменяются.— В случае всех остальных инструкций: текст команды не изменяется.
Представьте, что у нас есть следующий фрагмент Dockerfile:
RUN mkdir /code
COPY code code/
RUN pip install code/requirements.txt
Каждый раз, когда что-либо в каталоге кода меняется, вторую строку необходимо запускать заново, а также каждую последующую строку.
Вот как мы могли бы избежать повторного запуска этапа установки при каждом изменении кода:
RUN mkdir /code
COPY code/requirements.txt code/
RUN pip install code/requirements.txt
COPY code /code
Во-первых, проверьте, не загружаете ли вы зависимости разработки, которые вообще не нужны вашему образу.
Ещё нужно помнить про поведение менеджера пакетов на уровне ОС. Например, `apt`который используется в Ubuntu и Debian, по умолчанию устанавливает «рекомендуемые» пакеты.
Вы можете избежать этого, добавив к
apt-get install
флаг --no-install-recommends
BuildKit — это новый механизм сборки образов, который можно использовать вместо стандартного Docker. С ним вы получаете больше параллелизма и эффективности кэширования, плюс новые интересные функции
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
std::flush
и std::endl
, который ещё и переносит на новую строку. Есть ли такое в Go?Практически все операции вывода в Go используют интерфейсы
io.Writer
или io.WriteCloser
. В этих интерфейсах есть только метод Write
. Эти интерфейсы радикально проще стандартного std::basic_stream
. Метод Flush
или аналоги в io.Writer
отсутствуют.Теперь об объектах
std::cin
и std::cout
. В Go им соответствуют os.Stdin
и os.Stdout
. Переменная os.Stdout
— это указатель на объект типа os.File
.В Go вывод в файлы не буферизуется, метод
File.Write
пишет напрямую в файловый дескриптор через системный вызов pwrite
. Соответственно, в типе File
нет метода, аналогичного std::Flush
. Есть метод Sync
, который вызывает системный вызов fsync
для открытого файлового дескриптора, но это не то. Этот системный вызов заставляет ядро сбросить на диск буферы, отведённые под файловый дескриптор.Из-за того, что
File
пишет напрямую в файл, функции fmt.Print
и fmt.Println
, а так же методы File.WriteString
и File.Write
, очень медленные. На больших объемах вывода они медленнее буферизованного вывода раз в 100.Буферизованный ввод-вывод предоставляет пакет
bufio
. В пакете определён тип bufio.Writer
, в котором есть метод Flush
. Этот тип в десятки раз ускоряет вывод, но, к сожалению, нет типа для буферизованного файла: нельзя написать os.Stdout = bufio.NewWriter(os.Stdout)
. Поэтому если вам нужен быстрый аналог fmt.Print
, то нужно пользоваться fmt.Fprint
и явно указывать writer
:Stdout_Buffered := bufio.NewWriter(os.Stdout)
...
fmt.Fprintln(Stdout_Buffered, "Hello, world!")
...
Stdout_Buffered.Flush()
Аналога для
std::endl
в стандартных пакетах Go нет. Функция
fmt.Fprintln
пишет в объект io.Writer
системно-зависимый конец строки, но, поскольку io.Writer
не содержит никаких аналогов flush
, нижележащий буфер (если есть) эта функция не синхронизует.@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Итак, вот навскидку несколько областей применения
gorilla/context
: А вообще, применений
gorilla/context
уйма, можно почитать тут:@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Вот некоторые темы, которые обсуждаются:
— Dependency Injection
— Буферизированный-небуферизированный канал
— Термины, указатели,
interface{}
— Множества (sets), кортежи (tuples), функции-генераторы
— Указательные типы данных
Помимо этого обсуждаются алгоритмы, асимптотическая сложность, методы решения задач и всё в таком духе
Пользуйтесь)
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
skopeo не требует запуска демона для выполнения своих операций.
Инструмент может работать как с образами OCI, так и с оригинальными образами Docker v2.
▪Github
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Держите полезные рекомендации по ведению кода на Go.
Думаю, эти рекомендации довольно неплохо пригодятся и разрабам вне Uber.
Эти правила необходимы для того, чтобы сохранить контроль над кодовой базой проекта и при этом эффективно использовать возможности Go.
@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM