Golang вопросы собеседований
13.5K subscribers
625 photos
3 videos
1 file
432 links
@notxxx1 - админ

@Golang_google - Golang для разработчиков

@itchannels_telegram - 🔥лучшие из ит

@golangl - chat

@golangtests - golang tests

@golang_jobsgo - go chat jobs

@ai_machinelearning_big_data - AI

@data_analysis_ml

РКН: clck.ru/3FmtKd
加入频道
Каковы отличия context.WithCancel, context.WithDeadline, context.WithTimeout?

- context.WithCancel(parent Context) (ctx Context, cancel CancelFunc) создает контекст производный от родительского, также возвращает функцию отмены, с помощью которой этот контекст можно закрыть. Общепринятой практикой является работать с функцией отмены там, где она получена, не передавая ее глубже.

- context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc) создает контекст производный от родительского, также возвращает функцию отмены, с помощью которой этот контекст можно закрыть. Контекст автоматически отменится в переданное, как входной параметр функции, время.

- context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc) создает контекст производный от родительского, также возвращает функцию отмены, с помощью которой этот контекст можно закрыть. Контекст автоматически отменится через интервал времени, переданный, как входной параметр функции.

@golang_interview
В равной ли степени горутины делят между собой процессорное время?

Ответ
Существует 2 типа многозадачности:

кооперативная - передачей управления процессы занимаются самостоятельно;

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

С версии Go 1.14 планировщик с кооперативного стал асинхронно вытесняющим. Сделано это было по причине долго отрабатывающих горутин, надолго занимающих процессорное время и не дающих доступа до него другим горутинам. Теперь когда горутина отрабатывает больше 10 м/с Go будет пытаться переключить контекст для выполнения следующей горутины. Казалось бы вот он ответ. Но не все так просто... Части кооперативного поведения до сих пор присутствуют, к примеру перед вытеснением горутины необходимо выполнить проверку куска кода на атомарность, с точки зрения garbage collector. Операция вытеснения может настичь горутину в любом месте, в зависимости от состояния данных, сборщик мусора может отработать совсем не так как ожидалось. Так как Go живой язык, в который постоянно вносятся изменения, реализация и тонкости в разных версиях могут отличаться. Настоятельно советую обновлять свои знания по этой теме по мере релизов Go.

@golang_interview
Какие основные отличия горутины от thread?

@golang_interview
🔥 Полезнейшая Подборка каналов

👣 Golang

@Golang_google - go для разработчиков
@golangtests - тесты и задачи GO
@golangl - чат Golang
@GolangJobsit - вакансии и работа GO
@golang_jobsgo - чат вакансий
@golang_books - книги Golang
@golang_speak - обсуждение задач Go
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.

🖥 Python

@pro_python_code – погружение в python
@python_job_interview – подготовка к Python собеседованию
@python_testit тесты на python
@pythonlbooks - книги Python
@Django_pythonl django
@python_djangojobs - работа Python
@python_django_work

🖥 Machine learning
@ai_machinelearning_big_data – все о машинном обучении
@data_analysis_ml – все о анализе данных.
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседования Data Science
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@neural – все о нейронных сетях
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
@Machinelearning_Jobs

🖥 Java
@javatg - Java для програмистов
@javachats Java чат
@java_library - книги Java
@android_its Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит

🖥 Javascript / front
@javascriptv - javascript изучение
@about_javascript - javascript продвинутый
@JavaScript_testit -тесты JS
@htmlcssjavas - web
@hashdev - web разработка

🖥 Linux
@linux_kal - чат kali linux
@linuxkalii - linux kali
@linux_read - книги linux


👷‍♂️ IT работа

@hr_itwork - ит-ваканнсии

🖥 SQL
@sqlhub - базы данных
@chat_sql - базы данных чат

🤡It memes
@memes_prog - ит-мемы

⚙️ Rust
@rust_code - язык программирования rust
@rust_chats - чат rust

#️⃣ c# c++
@csharp_ci - c# c++кодинг
@csharp_cplus чат

📓 Книги

@programming_books_it
@datascienceiot
@pythonlbooks
@golang_books
@frontendbooksit
@progersit
@linux_read
@java_library
@frontendbooksit

📢 English for coders

@english_forprogrammers - Английский для программистов

🖥 Github
@github_code
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое буферизированный и небуферизированный channel?

Ответ

channel делятся на два типа по наличию/отсутствию буфера. Соответственно в первом случае поле dataqsiz будет равно размеру переданного буфера (3), а поле buf будет ссылкой на этот буфер. Во втором случае поле dataqsiz будет равно 0, а поле buf будет nil. Отсюда возникает различное поведение этих типов channel при операциях с ними. Об этом мы поговорим ниже.

chanBuf := make(chan bool, 3)

chanIsNotBuf := make(chan bool)


@golang_interview
👣 Какие есть способы остановить все горутины в приложении?

Ответ

Если размышлять глобально, то таких способа 3:

- завершение main функции и main горутины;

- прослушивание всеми горутинами channel, при закрытии channel отправляется значение по умолчанию всем слушателям, при получении сигнала все горутины делают return;

- завязать все горутины на переданный в них context.

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Каков минимальный и максимальный вес горутин?

На этот вопрос, ожидается ответ, не сколько весят все вместе взятые поля в структуре g объекта горутины. Интервьюера интересуют минимальный и максимальный размер стэка горутины. Минимальный (начальный) размер стэка составляет 2 КБ. Максимальный размер стэка горутины зависит от архитектуры системы и равен 1 ГБ для 64-разрядной архитектуры, 250 МБ для 32-разрядной архитектуры.

// The minimum size of stack used by Go code
_StackMin = 2048
// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
// Using decimal instead of binary GB and MB because
// they look nicer in the stack overflow failure message.
if sys.PtrSize == 8 {
maxstacksize = 1000000000
} else {
maxstacksize = 250000000
}


@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое wait group?

Ответ

sync.WaitGroup - это реализация счетчика, который можно инкрементировать и декрементировать, и самое главное остановить выполнение куска кода до того момента, пока значение счетчика не будет равно 0.

func main() {
wg := sync.WaitGroup{}
wg.Add(1)

go gorutinePrint(&wg)

wg.Wait()

fmt.Println("hello from main")
}

func gorutinePrint(wg *sync.WaitGroup) {
// без использования WaitGroup нет гарантий, что будет выведено
fmt.Println("hello from goroutine")

wg.Done()
}


Вывод

hello from goroutine
hello from main


@golang_interview
Для чего используется atomic?

Ответ

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

func main() {
var (
counter uint64
wg sync.WaitGroup
)

for i := 0; i < 10; i++ {
wg.Add(1)

go func() {
for c := 0; c < 1000; c++ {
atomic.AddUint64(&counter, 1)
}
wg.Done()
}()
}

wg.Wait()

fmt.Println("counter:", counter)
}


Вывод

counter: 10000

@golang_interview
👣 Как вручную задать количество процессоров P для приложения?

Ответ

Это можно сделать через runtime.GOMAXPROCS(). Важно понимать, что при выставлении количества логических процессоров больше, чем есть у вас в системе, вы рискуете получить определенные проблемы с производительностью. Чтобы избежать этого можно задать runtime.GOMAXPROCS(runtime.NumCPU()), runtime.NumCPU() - количество логических процессоров.

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Как принудительно переключить контекст?

Ответ

Переключение контекста вручную осуществляется с помощью функции runtime.Goshed().

@golang_interview
👣 Какие есть примитивы синхронизации?

Ответ

➡️ wait group;

➡️ mutex;

➡️ atomic;

➡️ sync map;

➡️ channel.

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Для чего используется sync map?

Ответ
Простой ответ на этот вопрос: достаточно частый кейс использования в Go mutex, который защищает данные в map. sync.Map можно рассматривать как map+RWMutex обертку. Но на деле этот ответ не совсем правильный, так как sync.Map решает одну довольно конкретную проблему cache contention. Что же это такое? При использовании sync.RWMutex в случае блокировки на чтение каждая горутина должна обновить поле readerCount, что происходит атомарно. Довольно обще процесс выглядит так:

- ядро процессора обновляет счетчик;

- ядро процессора сбрасывает кэш для этого адреса для всех других ядер;

- ядро процессора объявляет, что только оно знает действующее значение для обрабатываемого адреса;

- следующее ядро процессора вычитывает значение из кэша предыдущего;

- процесс повторяется. Так вот, когда несколько ядер хотят обновить readerCount, образуется очередь. И операция, которую мы считали константной, становится линейной относительно количества ядер. Именно решая эту проблему и ввели sync.Map. sync.Map рекомендуется применять именно на многопроцессорных системах.

// Lock locks rw for writing.
// If the lock is already locked for reading or writing,
// Lock blocks until the lock is available.
func (rw *RWMutex) Lock() {
if race.Enabled {
_ = rw.w.state
race.Disable()
}
// First, resolve competition with other writers.
rw.w.Lock()
// Announce to readers there is a pending writer.
r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
runtime_SemacquireMutex(&rw.writerSem, false, 0)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
race.Acquire(unsafe.Pointer(&rw.writerSem))
}
}


@golang_interview
👣 Что будет если размер горутины превысил допустимый максимум?

Если размер стэка горутины превышен (к примеру запустили бесконечную рекурсию), то приложение упадет с fatal error.

runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow


@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Некторые недокуменированные особенности #golang 1.18 и 1.19, про которые вы могли не знать.

https://go101.org/blog/2022-08-22-some-undocumented-chang

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Тестовое задание для стажера в юнит buyer-experience

#практика

Необходимо реализовать сервис, позволяющий следить за изменением цены любого объявления на Авито (другой аналогичный сайт с объявлениями):

1. Сервис должен предоставить HTTP метод для подписки на изменение цены. На вход метод получает - ссылку на объявление, email на который присылать уведомления.

2.После успешной подписки, сервис должен следить за ценой объявления и присылать уведомления на указанный email.

3. Если несколько пользователей подписались на одно и тоже объявление, сервис не должен лишний раз проверять цену объявления.

Требования к решению

- Необходимо проработать архитектуру сервиса и описать принципиальную схему работы в виде текста и/или диаграмм.
- Приложить фрагменты кода, решающие конкретные задачи:
- Подписка на изменение цены
- Отслеживание изменений цены
- Отправка уведомления на почту
Работа с БД
- Язык программирования Golang.

Чтобы получить цену объявления, можно:
- парсить web-страницу объявления
- самостоятельно проанализировать трафик на мобильных приложениях или мобильном сайте и выяснить какой там API для получения информации об объявлении


Усложнения
- Реализовать полноценный сервис, который решает поставленную задачу (сервис должен запускаться в docker-контейнере).
- Написаны тесты (постарайтесь достичь покрытия в 70% и больше).
- Подтверждение email пользователя.

Ставьте ❤️, если вам интересно увидеть практические задания с реальных собеседований.

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Задание написать WorkerPool с заданной функцией

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

Решение

package main

import (
"fmt"
)

func worker(id int, f func(int) int, jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- f(j)
}
}

func main() {

const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)

multiplier := func(x int) int {
return x * 10
}

for w := 1; w <= 3; w++ {
go worker(w, multiplier, jobs, results)
}

for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)

for i := 1; i <= numJobs; i++ {
fmt.Println(<-results)
}
}

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Golang
👣 Тестовое задание для Golang разработчика

Тестовое задание для кандидата на должность Golang разработчика.

Описание
Есть внешний сервис, который обрабатывает некие абстрактные объекты батчами. Данный сервис может обрабатывать только определенное количество элементов n в заданный временной интервал p. При превышении ограничения, сервис блокирует последующую обработку на долгое время.

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

Определение сервиса:

package main

import (
"context"
"errors"
"time"
)

// ErrBlocked reports if service is blocked.
var ErrBlocked = errors.New("blocked")

// Service defines external service that can process batches of items.
type Service interface {
GetLimits() (n uint64, p time.Duration)
Process(ctx context.Context, batch Batch) error
}

// Batch is a batch of items.
type Batch []Item

// Item is some abstract item.
type Item struct{}



Требования
- язык программирования Golang.
- решение должно быть в git-репозитории (можно прислать архив или опубликовать на github, gitlab, bitbucket...).
Пожелания
- документирование кода;
- тесты;
- использование статического анализатора (конфигурацию положить в репозиторий).

Варианты решений можно присылать в комментарии.
❤️, если нравится такие задачи.

@Golang_google
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Тестовое задание для Golang разработчика

Ваша компания отправляет СМС с трекинговой ссылкой, но ссылка достаточно длинная и из-за этого СМС выходит за 70 символов (длина 1 СМС). Необходимо спроектировать сервис-«укорачиватель ссылок» на языке GO, чтобы сэкономить деньги компании. Интервьюер при этом выступает заказчиком со стороны бизнеса и ему можно задавать вопросы по сути задачи.

Примечание
Задача хороша тем, что в нее можно углубляться по нескольким направлениям и оценить сразу несколько скиллов кандидата, а также глубину проработки (по сути его опыт), причём даже если он её уже решал (а многие действительно это делали). Основные направления обсуждения:

- как будем делать с точки зрения структуры приложения (в самом проекте/микросервисе и критерии, по которым мы делаем этот выбор). И тот, и другой варианты допустимы — все дело в аргументации. Если кандидат вообще не говорит про задачу с этой стороны, а, например, сразу переходит к структуре таблицы, то, скорее всего, кандидат никогда не задумывается над такими вопросами и/или не работал в более-менее крупных проектах;

- структура данных и выбор хранилища (СУБД, key-value типа Redis, еще какие-то варианты, плюсы и минусы тех или иных вариантов). Опять же, в зависимости от вопросов кандидата и желания интервьюера можно подвести к выбору какого-то варианта, но в целом есть множество вариантов реализации, которые будут оправданы — опять же, вопрос в аргументации выбора;

- хеши/коллизии, устойчивость к перебору ссылок (расчет количества необходимых вариантов). Важно, чтобы собеседуемый разработчик узнал про количество ссылок, оценил максимально возможную длину ссылки (и срок действия) и принял решение о том, какое количество символов стоит заложить в короткий URL. Плохо, если кандидат сильно перезакладывается или берет слишком маленькое количество символов, что может привести к тому, что допустимые комбинации в обозримом будущем закончатся;

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

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👣 Тестовое задание для Golang разработчика

Загрузка из «плохого» API большого количества данных и их синхронизация с табличкой в БД (например, Postgres). Считаем, что на входе мы скачиваем JSON-массив из N (>100k) объектов (dict) заданной структуры (primary key поле + некоторое количество строковых полей). Считаем, что нам надо раз в некоторое время запускать функцию, которая создаст записи, которые есть в JSON, но их нет в базе, а далее обновит строковые поля там, где что-то поменялось, и пометить удаленными записи, которых нет в JSON, но они все еще есть в базе.

Примечание

Есть 3 простых решения. Первое — просто перебрать записи из JSON, выбирая из базы записи по одной по pk, но тогда мы получим N запросов в базу, что может приводить к неконтролируемой пиковой нагрузке. Второе — выбрать из базы полностью таблицу и сравнить 2 массива, что будет работать, скорее всего, быстрее других вариантов, но будет максимально неэффективно по памяти (упрощаем решение задачи выделением дополнительных ресурсов, но, опять же, есть вероятность, что из-за неожиданно большого объема данных памяти может не хватить и выполнение таска прервется). Компромиссный вариант по производительности, нагрузке на базу и памяти — проходить циклом по JSON (или записям базы, но там есть нюансы) бачами по 100-1000 шт., накапливая обработанные id. Это сократит количество запросов на 2-3 порядка, не потребует загрузки в память всех текущих данных, но при этом будет всё ещё достаточно быстро. Также тут можно обсудить варианты реализации чисто средствами базы (временные таблицы, bulk upsert-ы и т.д.)

@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Серия вопросов по СУБД (в частности Postgres). По всем пунктам можно погрузиться в достаточно низкоуровневые детали реализации, но важно и в целом оценить осведомленность кандидата об основных принципах работы базы, достаточных для большинства задач.

***

Что такое транзакция? Приведите пример, где это может пригодиться. Расскажите про свойства транзакций и уровень изолированности.

Ответ
Транзакция объединяет последовательность действий в одну операцию и обеспечивает выполнение либо всех действий из последовательности, либо ни одного. Канонический пример — списывание денег с одного счета и зачисление на другой, что требует два update-а, которые гарантированно должны выполниться или не выполниться вместе.

Что такое server side cursor и зачем он нужен?

Ответ
Способ работы с результатом запроса в базу данных, который позволяет не загружать весь объем данных в память, позволяет работать с большими объемами данных. Дополнительно углубленно можно поговорить про особенности работы в связке с pgbouncer.

Что такое VACUUM и зачем он нужен в PostgreSQL?

Ответ
Команда VACUUM высвобождает пространство, занимаемое «мертвыми» кортежами, что актуально для часто используемых таблиц. При обычных операциях в Postgres кортежи, удаленные или устаревшие в результаты обновления, физически не удаляются, а сохраняются в таблице до очистки.

Что такое EXPLAIN? Какая разница между ним и EXPLAIN ANALYZE?

Ответ
EXPLAIN ANALYZE – в отличие от просто EXPLAIN не только показывает план выполнения запроса, но и непосредственно выполняет запрос и показывает реальное время выполнения

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