С этой статьей вы углубитесь во внутренние компоненты и посмотрите, как работают слайсы под капотом.
🔗 Подобнее
#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